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