1 /* input_scrub.c - Break up input buffers into whole numbers of lines.
2 Copyright (C) 1987, 90, 91, 92, 93, 94, 95, 96, 1997
3 Free Software Foundation, Inc.
5 This file is part of GAS, the GNU Assembler.
7 GAS is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2, or (at your option)
12 GAS is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with GAS; see the file COPYING. If not, write to the Free
19 Software Foundation, 59 Temple Place - Suite 330, Boston, MA
22 #include <errno.h> /* Need this to make errno declaration right */
24 #include "input-file.h"
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
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
38 * Also looks after line numbers, for e.g. error messages.
42 * We don't care how filthy our buffers are, but our callers assume
43 * that the following sanitation has already been done.
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.
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)
59 static char *buffer_start
; /*->1st char of full buffer area. */
60 static char *partial_where
; /*->after last full line in buffer. */
61 static int partial_size
; /* >=0. Number of chars in partial line in buffer. */
62 static char save_source
[AFTER_SIZE
];
63 /* Because we need AFTER_STRING just after last */
64 /* full line, it clobbers 1st part of partial */
65 /* line. So we preserve 1st part of partial */
67 static unsigned int buffer_length
; /* What is the largest size buffer that */
68 /* input_file_give_next_buffer() could */
71 /* The index into an sb structure we are reading from. -1 if none. */
72 static int sb_index
= -1;
74 /* If we are reading from an sb structure, this is it. */
77 /* The number of nested sb structures we have included. */
80 /* We can have more than one source file open at once, though the info for all
81 but the latest one are saved off in a struct input_save. These files remain
82 open, so we are limited by the number of open files allowed by the
83 underlying OS. We may also sequentially read more than one source file in an
86 /* We must track the physical file and line number for error messages. We also
87 track a "logical" file and line number corresponding to (C?) compiler
88 source line numbers. Whenever we open a file we must fill in
89 physical_input_file. So if it is NULL we have not opened any files yet. */
91 static char *physical_input_file
;
92 static char *logical_input_file
;
94 typedef unsigned int line_numberT
; /* 1-origin line number in a source file. */
95 /* A line ends in '\n' or eof. */
97 static line_numberT physical_input_line
;
98 static int logical_input_line
;
100 /* Struct used to save the state of the input handler during include files */
106 char save_source
[AFTER_SIZE
];
107 unsigned int buffer_length
;
108 char *physical_input_file
;
109 char *logical_input_file
;
110 line_numberT physical_input_line
;
111 int logical_input_line
;
114 struct input_save
*next_saved_file
; /* Chain of input_saves */
115 char *input_file_save
; /* Saved state of input routines */
116 char *saved_position
; /* Caller's saved position in buf */
119 static struct input_save
*input_scrub_push
PARAMS ((char *saved_position
));
120 static char *input_scrub_pop
PARAMS ((struct input_save
*arg
));
121 static void as_1_char
PARAMS ((unsigned int c
, FILE * stream
));
123 /* Saved information about the file that .include'd this one. When we hit EOF,
124 we automatically pop to that file. */
126 static struct input_save
*next_saved_file
;
128 /* Push the state of input reading and scrubbing so that we can #include.
129 The return value is a 'void *' (fudged for old compilers) to a save
130 area, which can be restored by passing it to input_scrub_pop(). */
131 static struct input_save
*
132 input_scrub_push (saved_position
)
133 char *saved_position
;
135 register struct input_save
*saved
;
137 saved
= (struct input_save
*) xmalloc (sizeof *saved
);
139 saved
->saved_position
= saved_position
;
140 saved
->buffer_start
= buffer_start
;
141 saved
->partial_where
= partial_where
;
142 saved
->partial_size
= partial_size
;
143 saved
->buffer_length
= buffer_length
;
144 saved
->physical_input_file
= physical_input_file
;
145 saved
->logical_input_file
= logical_input_file
;
146 saved
->physical_input_line
= physical_input_line
;
147 saved
->logical_input_line
= logical_input_line
;
148 saved
->sb_index
= sb_index
;
149 saved
->from_sb
= from_sb
;
150 memcpy (saved
->save_source
, save_source
, sizeof (save_source
));
151 saved
->next_saved_file
= next_saved_file
;
152 saved
->input_file_save
= input_file_push ();
154 input_file_begin (); /* Reinitialize! */
155 logical_input_line
= -1;
156 logical_input_file
= (char *) NULL
;
157 buffer_length
= input_file_buffer_size ();
160 buffer_start
= xmalloc ((BEFORE_SIZE
+ buffer_length
+ buffer_length
+ AFTER_SIZE
));
161 memcpy (buffer_start
, BEFORE_STRING
, (int) BEFORE_SIZE
);
164 } /* input_scrub_push() */
167 input_scrub_pop (saved
)
168 struct input_save
*saved
;
170 char *saved_position
;
172 input_scrub_end (); /* Finish off old buffer */
174 input_file_pop (saved
->input_file_save
);
175 saved_position
= saved
->saved_position
;
176 buffer_start
= saved
->buffer_start
;
177 buffer_length
= saved
->buffer_length
;
178 physical_input_file
= saved
->physical_input_file
;
179 logical_input_file
= saved
->logical_input_file
;
180 physical_input_line
= saved
->physical_input_line
;
181 logical_input_line
= saved
->logical_input_line
;
182 sb_index
= saved
->sb_index
;
183 from_sb
= saved
->from_sb
;
184 partial_where
= saved
->partial_where
;
185 partial_size
= saved
->partial_size
;
186 next_saved_file
= saved
->next_saved_file
;
187 memcpy (save_source
, saved
->save_source
, sizeof (save_source
));
190 return saved_position
;
197 know (strlen (BEFORE_STRING
) == BEFORE_SIZE
);
198 know (strlen (AFTER_STRING
) == AFTER_SIZE
|| (AFTER_STRING
[0] == '\0' && AFTER_SIZE
== 1));
202 buffer_length
= input_file_buffer_size ();
204 buffer_start
= xmalloc ((BEFORE_SIZE
+ buffer_length
+ buffer_length
+ AFTER_SIZE
));
205 memcpy (buffer_start
, BEFORE_STRING
, (int) BEFORE_SIZE
);
207 /* Line number things. */
208 logical_input_line
= -1;
209 logical_input_file
= (char *) NULL
;
210 physical_input_file
= NULL
; /* No file read yet. */
211 next_saved_file
= NULL
; /* At EOF, don't pop to any other file */
212 do_scrub_begin (flag_m68k_mri
);
226 /* Start reading input from a new file. */
228 char * /* Return start of caller's part of buffer. */
229 input_scrub_new_file (filename
)
232 input_file_open (filename
, !flag_no_comments
);
233 physical_input_file
= filename
[0] ? filename
: _("{standard input}");
234 physical_input_line
= 0;
237 return (buffer_start
+ BEFORE_SIZE
);
241 /* Include a file from the current file. Save our state, cause it to
242 be restored on EOF, and begin handling a new file. Same result as
243 input_scrub_new_file. */
246 input_scrub_include_file (filename
, position
)
250 next_saved_file
= input_scrub_push (position
);
251 return input_scrub_new_file (filename
);
254 /* Start getting input from an sb structure. This is used when
255 expanding a macro. */
258 input_scrub_include_sb (from
, position
)
262 if (macro_nest
> max_macro_nest
)
263 as_fatal (_("macros nested too deeply"));
266 next_saved_file
= input_scrub_push (position
);
269 if (from
->len
>= 1 && from
->ptr
[0] != '\n')
271 /* Add the sentinel required by read.c. */
272 sb_add_char (&from_sb
, '\n');
274 sb_add_sb (&from_sb
, from
);
277 /* These variables are reset by input_scrub_push. Restore them
278 since we are, after all, still at the same point in the file. */
279 logical_input_line
= next_saved_file
->logical_input_line
;
280 logical_input_file
= next_saved_file
->logical_input_file
;
290 input_scrub_next_buffer (bufp
)
293 register char *limit
; /*->just after last char of buffer. */
297 if (sb_index
>= from_sb
.len
)
300 cond_finish_check (macro_nest
);
302 partial_where
= NULL
;
303 if (next_saved_file
!= NULL
)
304 *bufp
= input_scrub_pop (next_saved_file
);
305 return partial_where
;
308 partial_where
= from_sb
.ptr
+ from_sb
.len
;
310 *bufp
= from_sb
.ptr
+ sb_index
;
311 sb_index
= from_sb
.len
;
312 return partial_where
;
315 *bufp
= buffer_start
+ BEFORE_SIZE
;
319 memcpy (buffer_start
+ BEFORE_SIZE
, partial_where
,
320 (unsigned int) partial_size
);
321 memcpy (buffer_start
+ BEFORE_SIZE
, save_source
, AFTER_SIZE
);
323 limit
= input_file_give_next_buffer (buffer_start
328 register char *p
; /* Find last newline. */
330 for (p
= limit
- 1; *p
!= '\n'; --p
)
334 while (p
<= buffer_start
+ BEFORE_SIZE
)
338 limoff
= limit
- buffer_start
;
339 buffer_length
+= input_file_buffer_size ();
340 buffer_start
= xrealloc (buffer_start
,
344 *bufp
= buffer_start
+ BEFORE_SIZE
;
345 limit
= input_file_give_next_buffer (buffer_start
+ limoff
);
349 as_warn (_("partial line at end of file ignored"));
350 partial_where
= NULL
;
352 *bufp
= input_scrub_pop (next_saved_file
);
356 for (p
= limit
- 1; *p
!= '\n'; --p
)
362 partial_size
= limit
- p
;
363 memcpy (save_source
, partial_where
, (int) AFTER_SIZE
);
364 memcpy (partial_where
, AFTER_STRING
, (int) AFTER_SIZE
);
369 if (partial_size
> 0)
371 as_warn (_("Partial line at end of file ignored"));
374 /* Tell the listing we've finished the file. */
377 /* If we should pop to another file at EOF, do it. */
380 *bufp
= input_scrub_pop (next_saved_file
); /* Pop state */
381 /* partial_where is now correct to return, since we popped it. */
384 return (partial_where
);
385 } /* input_scrub_next_buffer() */
388 * The remaining part of this file deals with line numbers, error
389 * messages and so on.
394 seen_at_least_1_file () /* TRUE if we opened any file. */
396 return (physical_input_file
!= NULL
);
400 bump_line_counters ()
404 ++physical_input_line
;
405 if (logical_input_line
>= 0)
406 ++logical_input_line
;
413 * Tells us what the new logical line number and file are.
414 * If the line_number is -1, we don't change the current logical line
415 * number. If it is -2, we decrement the logical line number (this is
416 * to support the .appfile pseudo-op inserted into the stream by
418 * If the fname is NULL, we don't change the current logical file name.
419 * Returns nonzero if the filename actually changes.
422 new_logical_line (fname
, line_number
)
423 char *fname
; /* DON'T destroy it! We point to it! */
426 if (line_number
>= 0)
427 logical_input_line
= line_number
;
428 else if (line_number
== -2 && logical_input_line
> 0)
429 --logical_input_line
;
432 && (logical_input_file
== NULL
433 || strcmp (logical_input_file
, fname
)))
435 logical_input_file
= fname
;
440 } /* new_logical_line() */
445 * Return the current file name and line number.
446 * namep should be char * const *, but there are compilers which screw
447 * up declarations like that, and it's easier to avoid it.
450 as_where (namep
, linep
)
454 if (logical_input_file
!= NULL
455 && (linep
== NULL
|| logical_input_line
>= 0))
457 *namep
= logical_input_file
;
459 *linep
= logical_input_line
;
461 else if (physical_input_file
!= NULL
)
463 *namep
= physical_input_file
;
465 *linep
= physical_input_line
;
479 * a s _ h o w m u c h ()
481 * Output to given stream how much of line we have scanned so far.
482 * Assumes we have scanned up to and including input_line_pointer.
483 * No free '\n' at end of line.
487 FILE *stream
; /* Opened for write please. */
489 register char *p
; /* Scan input line. */
490 /* register char c; JF unused */
492 for (p
= input_line_pointer
- 1; *p
!= '\n'; --p
)
495 ++p
; /* p->1st char of line. */
496 for (; p
<= input_line_pointer
; p
++)
498 /* Assume ASCII. EBCDIC & other micro-computer char sets ignored. */
499 as_1_char ((unsigned char) *p
, stream
);
504 as_1_char (c
, stream
)
510 (void) putc ('%', stream
);
515 (void) putc ('^', stream
);
518 (void) putc (c
, stream
);
521 /* end of input_scrub.c */