input-scrub.c revision 77298
1160452Scognet/* input_scrub.c - Break up input buffers into whole numbers of lines.
2160370Simp   Copyright (C) 1987, 90, 91, 92, 93, 94, 95, 96, 97, 2000
3160370Simp   Free Software Foundation, Inc.
4160370Simp
5160370Simp   This file is part of GAS, the GNU Assembler.
6160370Simp
7160370Simp   GAS is free software; you can redistribute it and/or modify
8160370Simp   it under the terms of the GNU General Public License as published by
9160370Simp   the Free Software Foundation; either version 2, or (at your option)
10160370Simp   any later version.
11160370Simp
12160370Simp   GAS is distributed in the hope that it will be useful,
13160370Simp   but WITHOUT ANY WARRANTY; without even the implied warranty of
14160370Simp   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15160370Simp   GNU General Public License for more details.
16160370Simp
17160370Simp   You should have received a copy of the GNU General Public License
18160370Simp   along with GAS; see the file COPYING.  If not, write to the Free
19160370Simp   Software Foundation, 59 Temple Place - Suite 330, Boston, MA
20160370Simp   02111-1307, USA.  */
21228471Sed
22160370Simp#include <errno.h>		/* Need this to make errno declaration right */
23160370Simp#include "as.h"
24160370Simp#include "input-file.h"
25160370Simp#include "sb.h"
26160370Simp#include "listing.h"
27160370Simp
28160370Simp/*
29 * O/S independent module to supply buffers of sanitised source code
30 * to rest of assembler.  We get sanitised input data of arbitrary length.
31 * We break these buffers on line boundaries, recombine pieces that
32 * were broken across buffers, and return a buffer of full lines to
33 * the caller.
34 * The last partial line begins the next buffer we build and return to caller.
35 * The buffer returned to caller is preceeded by BEFORE_STRING and followed
36 * by AFTER_STRING, as sentinels. The last character before AFTER_STRING
37 * is a newline.
38 * Also looks after line numbers, for e.g. error messages.
39 */
40
41/*
42 * We don't care how filthy our buffers are, but our callers assume
43 * that the following sanitation has already been done.
44 *
45 * No comments, reduce a comment to a space.
46 * Reduce a tab to a space unless it is 1st char of line.
47 * All multiple tabs and spaces collapsed into 1 char. Tab only
48 *   legal if 1st char of line.
49 * # line file statements converted to .line x;.file y; statements.
50 * Escaped newlines at end of line: remove them but add as many newlines
51 *   to end of statement as you removed in the middle, to synch line numbers.
52 */
53
54#define BEFORE_STRING ("\n")
55#define AFTER_STRING ("\0")	/* memcpy of 0 chars might choke.  */
56#define BEFORE_SIZE (1)
57#define AFTER_SIZE  (1)
58
59static char *buffer_start;	/*->1st char of full buffer area.  */
60static char *partial_where;	/*->after last full line in buffer.  */
61static int partial_size;	/* >=0. Number of chars in partial line in buffer.  */
62
63/* Because we need AFTER_STRING just after last full line, it clobbers
64   1st part of partial line. So we preserve 1st part of partial line
65   here.  */
66static char save_source[AFTER_SIZE];
67
68/* What is the largest size buffer that input_file_give_next_buffer()
69   could return to us?  */
70static unsigned int buffer_length;
71
72/* The index into an sb structure we are reading from.  -1 if none.  */
73static int sb_index = -1;
74
75/* If we are reading from an sb structure, this is it.  */
76static sb from_sb;
77
78/* Should we do a conditional check on from_sb? */
79static int from_sb_is_expansion = 1;
80
81/* The number of nested sb structures we have included.  */
82int macro_nest;
83
84/* We can have more than one source file open at once, though the info for all
85   but the latest one are saved off in a struct input_save.  These files remain
86   open, so we are limited by the number of open files allowed by the
87   underlying OS. We may also sequentially read more than one source file in an
88   assembly.  */
89
90/* We must track the physical file and line number for error messages. We also
91   track a "logical" file and line number corresponding to (C?)  compiler
92   source line numbers.  Whenever we open a file we must fill in
93   physical_input_file. So if it is NULL we have not opened any files yet.  */
94
95static char *physical_input_file;
96static char *logical_input_file;
97
98typedef unsigned int line_numberT;	/* 1-origin line number in a source file.  */
99/* A line ends in '\n' or eof.  */
100
101static line_numberT physical_input_line;
102static int logical_input_line;
103
104/* Struct used to save the state of the input handler during include files */
105struct input_save {
106  char *              buffer_start;
107  char *              partial_where;
108  int                 partial_size;
109  char                save_source[AFTER_SIZE];
110  unsigned int        buffer_length;
111  char *              physical_input_file;
112  char *              logical_input_file;
113  line_numberT        physical_input_line;
114  int                 logical_input_line;
115  int                 sb_index;
116  sb                  from_sb;
117  int                 from_sb_is_expansion; /* Should we do a conditional check?  */
118  struct input_save * next_saved_file;	/* Chain of input_saves.  */
119  char *              input_file_save;	/* Saved state of input routines.  */
120  char *              saved_position;	/* Caller's saved position in buf.  */
121};
122
123static struct input_save *input_scrub_push PARAMS ((char *saved_position));
124static char *input_scrub_pop PARAMS ((struct input_save *arg));
125static void as_1_char PARAMS ((unsigned int c, FILE * stream));
126
127/* Saved information about the file that .include'd this one.  When we hit EOF,
128   we automatically pop to that file.  */
129
130static struct input_save *next_saved_file;
131
132/* Push the state of input reading and scrubbing so that we can #include.
133   The return value is a 'void *' (fudged for old compilers) to a save
134   area, which can be restored by passing it to input_scrub_pop().  */
135
136static struct input_save *
137input_scrub_push (saved_position)
138     char *saved_position;
139{
140  register struct input_save *saved;
141
142  saved = (struct input_save *) xmalloc (sizeof *saved);
143
144  saved->saved_position = saved_position;
145  saved->buffer_start = buffer_start;
146  saved->partial_where = partial_where;
147  saved->partial_size = partial_size;
148  saved->buffer_length = buffer_length;
149  saved->physical_input_file = physical_input_file;
150  saved->logical_input_file = logical_input_file;
151  saved->physical_input_line = physical_input_line;
152  saved->logical_input_line = logical_input_line;
153  saved->sb_index = sb_index;
154  saved->from_sb = from_sb;
155  saved->from_sb_is_expansion = from_sb_is_expansion;
156  memcpy (saved->save_source, save_source, sizeof (save_source));
157  saved->next_saved_file = next_saved_file;
158  saved->input_file_save = input_file_push ();
159
160  input_file_begin ();		/* Reinitialize! */
161  logical_input_line = -1;
162  logical_input_file = (char *) NULL;
163  buffer_length = input_file_buffer_size ();
164  sb_index = -1;
165
166  buffer_start = xmalloc ((BEFORE_SIZE + buffer_length + buffer_length + AFTER_SIZE));
167  memcpy (buffer_start, BEFORE_STRING, (int) BEFORE_SIZE);
168
169  return saved;
170}
171
172static char *
173input_scrub_pop (saved)
174     struct input_save *saved;
175{
176  char *saved_position;
177
178  input_scrub_end ();		/* Finish off old buffer */
179
180  input_file_pop (saved->input_file_save);
181  saved_position = saved->saved_position;
182  buffer_start = saved->buffer_start;
183  buffer_length = saved->buffer_length;
184  physical_input_file = saved->physical_input_file;
185  logical_input_file = saved->logical_input_file;
186  physical_input_line = saved->physical_input_line;
187  logical_input_line = saved->logical_input_line;
188  sb_index = saved->sb_index;
189  from_sb = saved->from_sb;
190  from_sb_is_expansion = saved->from_sb_is_expansion;
191  partial_where = saved->partial_where;
192  partial_size = saved->partial_size;
193  next_saved_file = saved->next_saved_file;
194  memcpy (save_source, saved->save_source, sizeof (save_source));
195
196  free (saved);
197  return saved_position;
198}
199
200void
201input_scrub_begin ()
202{
203  know (strlen (BEFORE_STRING) == BEFORE_SIZE);
204  know (strlen (AFTER_STRING) == AFTER_SIZE
205	|| (AFTER_STRING[0] == '\0' && AFTER_SIZE == 1));
206
207  input_file_begin ();
208
209  buffer_length = input_file_buffer_size ();
210
211  buffer_start = xmalloc ((BEFORE_SIZE + buffer_length + buffer_length + AFTER_SIZE));
212  memcpy (buffer_start, BEFORE_STRING, (int) BEFORE_SIZE);
213
214  /* Line number things.  */
215  logical_input_line = -1;
216  logical_input_file = (char *) NULL;
217  physical_input_file = NULL;	/* No file read yet.  */
218  next_saved_file = NULL;	/* At EOF, don't pop to any other file */
219  do_scrub_begin (flag_m68k_mri);
220}
221
222void
223input_scrub_end ()
224{
225  if (buffer_start)
226    {
227      free (buffer_start);
228      buffer_start = 0;
229      input_file_end ();
230    }
231}
232
233/* Start reading input from a new file.
234   Return start of caller's part of buffer.  */
235
236char *
237input_scrub_new_file (filename)
238     char *filename;
239{
240  input_file_open (filename, !flag_no_comments);
241  physical_input_file = filename[0] ? filename : _("{standard input}");
242  physical_input_line = 0;
243
244  partial_size = 0;
245  return (buffer_start + BEFORE_SIZE);
246}
247
248/* Include a file from the current file.  Save our state, cause it to
249   be restored on EOF, and begin handling a new file.  Same result as
250   input_scrub_new_file.  */
251
252char *
253input_scrub_include_file (filename, position)
254     char *filename;
255     char *position;
256{
257  next_saved_file = input_scrub_push (position);
258  return input_scrub_new_file (filename);
259}
260
261/* Start getting input from an sb structure.  This is used when
262   expanding a macro.  */
263
264void
265input_scrub_include_sb (from, position, is_expansion)
266     sb *from;
267     char *position;
268     int is_expansion;
269{
270  if (macro_nest > max_macro_nest)
271    as_fatal (_("macros nested too deeply"));
272  ++macro_nest;
273
274#ifdef md_macro_start
275  if (is_expansion)
276    {
277      md_macro_start ();
278    }
279#endif
280
281  next_saved_file = input_scrub_push (position);
282
283  sb_new (&from_sb);
284  from_sb_is_expansion = is_expansion;
285  if (from->len >= 1 && from->ptr[0] != '\n')
286    {
287      /* Add the sentinel required by read.c.  */
288      sb_add_char (&from_sb, '\n');
289    }
290  sb_add_sb (&from_sb, from);
291  sb_index = 1;
292
293  /* These variables are reset by input_scrub_push.  Restore them
294     since we are, after all, still at the same point in the file.  */
295  logical_input_line = next_saved_file->logical_input_line;
296  logical_input_file = next_saved_file->logical_input_file;
297}
298
299void
300input_scrub_close ()
301{
302  input_file_close ();
303}
304
305char *
306input_scrub_next_buffer (bufp)
307     char **bufp;
308{
309  register char *limit;		/*->just after last char of buffer.  */
310
311  if (sb_index >= 0)
312    {
313      if (sb_index >= from_sb.len)
314	{
315	  sb_kill (&from_sb);
316	  if (from_sb_is_expansion
317	      )
318	    {
319	      cond_finish_check (macro_nest);
320#ifdef md_macro_end
321	      /* Allow the target to clean up per-macro expansion
322	         data.  */
323	      md_macro_end ();
324#endif
325	    }
326	  --macro_nest;
327	  partial_where = NULL;
328	  if (next_saved_file != NULL)
329	    *bufp = input_scrub_pop (next_saved_file);
330	  return partial_where;
331	}
332
333      partial_where = from_sb.ptr + from_sb.len;
334      partial_size = 0;
335      *bufp = from_sb.ptr + sb_index;
336      sb_index = from_sb.len;
337      return partial_where;
338    }
339
340  *bufp = buffer_start + BEFORE_SIZE;
341
342  if (partial_size)
343    {
344      memcpy (buffer_start + BEFORE_SIZE, partial_where,
345	      (unsigned int) partial_size);
346      memcpy (buffer_start + BEFORE_SIZE, save_source, AFTER_SIZE);
347    }
348  limit = input_file_give_next_buffer (buffer_start
349				       + BEFORE_SIZE
350				       + partial_size);
351  if (limit)
352    {
353      register char *p;		/* Find last newline.  */
354
355      for (p = limit - 1; *p != '\n'; --p)
356	;
357      ++p;
358
359      while (p <= buffer_start + BEFORE_SIZE)
360	{
361	  int limoff;
362
363	  limoff = limit - buffer_start;
364	  buffer_length += input_file_buffer_size ();
365	  buffer_start = xrealloc (buffer_start,
366				   (BEFORE_SIZE
367				    + 2 * buffer_length
368				    + AFTER_SIZE));
369	  *bufp = buffer_start + BEFORE_SIZE;
370	  limit = input_file_give_next_buffer (buffer_start + limoff);
371
372	  if (limit == NULL)
373	    {
374	      as_warn (_("partial line at end of file ignored"));
375	      partial_where = NULL;
376	      if (next_saved_file)
377		*bufp = input_scrub_pop (next_saved_file);
378	      return NULL;
379	    }
380
381	  for (p = limit - 1; *p != '\n'; --p)
382	    ;
383	  ++p;
384	}
385
386      partial_where = p;
387      partial_size = limit - p;
388      memcpy (save_source, partial_where, (int) AFTER_SIZE);
389      memcpy (partial_where, AFTER_STRING, (int) AFTER_SIZE);
390    }
391  else
392    {
393      partial_where = 0;
394      if (partial_size > 0)
395	{
396	  as_warn (_("Partial line at end of file ignored"));
397	}
398
399      /* Tell the listing we've finished the file.  */
400      LISTING_EOF ();
401
402      /* If we should pop to another file at EOF, do it.  */
403      if (next_saved_file)
404	{
405	  *bufp = input_scrub_pop (next_saved_file);	/* Pop state */
406	  /* partial_where is now correct to return, since we popped it.  */
407	}
408    }
409  return (partial_where);
410}
411
412/* The remaining part of this file deals with line numbers, error
413   messages and so on.  Return TRUE if we opened any file.  */
414
415int
416seen_at_least_1_file ()
417{
418  return (physical_input_file != NULL);
419}
420
421void
422bump_line_counters ()
423{
424  if (sb_index < 0)
425    {
426      ++physical_input_line;
427      if (logical_input_line >= 0)
428	++logical_input_line;
429    }
430}
431
432/* Tells us what the new logical line number and file are.
433   If the line_number is -1, we don't change the current logical line
434   number.  If it is -2, we decrement the logical line number (this is
435   to support the .appfile pseudo-op inserted into the stream by
436   do_scrub_chars).
437   If the fname is NULL, we don't change the current logical file name.
438   Returns nonzero if the filename actually changes.  */
439
440int
441new_logical_line (fname, line_number)
442     char *fname;		/* DON'T destroy it!  We point to it!  */
443     int line_number;
444{
445  if (line_number >= 0)
446    logical_input_line = line_number;
447  else if (line_number == -2 && logical_input_line > 0)
448    --logical_input_line;
449
450  if (fname
451      && (logical_input_file == NULL
452	  || strcmp (logical_input_file, fname)))
453    {
454      logical_input_file = fname;
455      return 1;
456    }
457  else
458    return 0;
459}
460
461/* Return the current file name and line number.
462   namep should be char * const *, but there are compilers which screw
463   up declarations like that, and it's easier to avoid it.  */
464
465void
466as_where (namep, linep)
467     char **namep;
468     unsigned int *linep;
469{
470  if (logical_input_file != NULL
471      && (linep == NULL || logical_input_line >= 0))
472    {
473      *namep = logical_input_file;
474      if (linep != NULL)
475	*linep = logical_input_line;
476    }
477  else if (physical_input_file != NULL)
478    {
479      *namep = physical_input_file;
480      if (linep != NULL)
481	*linep = physical_input_line;
482    }
483  else
484    {
485      *namep = 0;
486      if (linep != NULL)
487	*linep = 0;
488    }
489}
490
491/* Output to given stream how much of line we have scanned so far.
492   Assumes we have scanned up to and including input_line_pointer.
493   No free '\n' at end of line.  */
494
495void
496as_howmuch (stream)
497     FILE *stream;		/* Opened for write please.  */
498{
499  register char *p;		/* Scan input line.  */
500
501  for (p = input_line_pointer - 1; *p != '\n'; --p)
502    {
503    }
504  ++p;				/* p->1st char of line.  */
505  for (; p <= input_line_pointer; p++)
506    {
507      /* Assume ASCII. EBCDIC & other micro-computer char sets ignored.  */
508      as_1_char ((unsigned char) *p, stream);
509    }
510}
511
512static void
513as_1_char (c, stream)
514     unsigned int c;
515     FILE *stream;
516{
517  if (c > 127)
518    {
519      (void) putc ('%', stream);
520      c -= 128;
521    }
522  if (c < 32)
523    {
524      (void) putc ('^', stream);
525      c += '@';
526    }
527  (void) putc (c, stream);
528}
529