xref: /openbsd-src/gnu/usr.bin/binutils-2.17/gas/input-scrub.c (revision 4d6c937d5b552af0cbe003748c5da1c9ebdc9c20)
13d8817e4Smiod /* input_scrub.c - Break up input buffers into whole numbers of lines.
23d8817e4Smiod    Copyright 1987, 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998,
33d8817e4Smiod    2000, 2001, 2003
43d8817e4Smiod    Free Software Foundation, Inc.
53d8817e4Smiod 
63d8817e4Smiod    This file is part of GAS, the GNU Assembler.
73d8817e4Smiod 
83d8817e4Smiod    GAS is free software; you can redistribute it and/or modify
93d8817e4Smiod    it under the terms of the GNU General Public License as published by
103d8817e4Smiod    the Free Software Foundation; either version 2, or (at your option)
113d8817e4Smiod    any later version.
123d8817e4Smiod 
133d8817e4Smiod    GAS is distributed in the hope that it will be useful,
143d8817e4Smiod    but WITHOUT ANY WARRANTY; without even the implied warranty of
153d8817e4Smiod    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
163d8817e4Smiod    GNU General Public License for more details.
173d8817e4Smiod 
183d8817e4Smiod    You should have received a copy of the GNU General Public License
193d8817e4Smiod    along with GAS; see the file COPYING.  If not, write to the Free
203d8817e4Smiod    Software Foundation, 51 Franklin Street - Fifth Floor, Boston, MA
213d8817e4Smiod    02110-1301, USA.  */
223d8817e4Smiod 
233d8817e4Smiod #include <errno.h>		/* Need this to make errno declaration right */
243d8817e4Smiod #include "as.h"
253d8817e4Smiod #include "input-file.h"
263d8817e4Smiod #include "sb.h"
273d8817e4Smiod #include "listing.h"
283d8817e4Smiod 
293d8817e4Smiod /*
303d8817e4Smiod  * O/S independent module to supply buffers of sanitised source code
313d8817e4Smiod  * to rest of assembler.  We get sanitised input data of arbitrary length.
323d8817e4Smiod  * We break these buffers on line boundaries, recombine pieces that
333d8817e4Smiod  * were broken across buffers, and return a buffer of full lines to
343d8817e4Smiod  * the caller.
353d8817e4Smiod  * The last partial line begins the next buffer we build and return to caller.
363d8817e4Smiod  * The buffer returned to caller is preceded by BEFORE_STRING and followed
373d8817e4Smiod  * by AFTER_STRING, as sentinels. The last character before AFTER_STRING
383d8817e4Smiod  * is a newline.
393d8817e4Smiod  * Also looks after line numbers, for e.g. error messages.
403d8817e4Smiod  */
413d8817e4Smiod 
423d8817e4Smiod /*
433d8817e4Smiod  * We don't care how filthy our buffers are, but our callers assume
443d8817e4Smiod  * that the following sanitation has already been done.
453d8817e4Smiod  *
463d8817e4Smiod  * No comments, reduce a comment to a space.
473d8817e4Smiod  * Reduce a tab to a space unless it is 1st char of line.
483d8817e4Smiod  * All multiple tabs and spaces collapsed into 1 char. Tab only
493d8817e4Smiod  *   legal if 1st char of line.
503d8817e4Smiod  * # line file statements converted to .line x;.file y; statements.
513d8817e4Smiod  * Escaped newlines at end of line: remove them but add as many newlines
523d8817e4Smiod  *   to end of statement as you removed in the middle, to synch line numbers.
533d8817e4Smiod  */
543d8817e4Smiod 
553d8817e4Smiod #define BEFORE_STRING ("\n")
563d8817e4Smiod #define AFTER_STRING ("\0")	/* memcpy of 0 chars might choke.  */
573d8817e4Smiod #define BEFORE_SIZE (1)
583d8817e4Smiod #define AFTER_SIZE  (1)
593d8817e4Smiod 
603d8817e4Smiod static char *buffer_start;	/*->1st char of full buffer area.  */
613d8817e4Smiod static char *partial_where;	/*->after last full line in buffer.  */
623d8817e4Smiod static int partial_size;	/* >=0. Number of chars in partial line in buffer.  */
633d8817e4Smiod 
643d8817e4Smiod /* Because we need AFTER_STRING just after last full line, it clobbers
653d8817e4Smiod    1st part of partial line. So we preserve 1st part of partial line
663d8817e4Smiod    here.  */
673d8817e4Smiod static char save_source[AFTER_SIZE];
683d8817e4Smiod 
693d8817e4Smiod /* What is the largest size buffer that input_file_give_next_buffer()
703d8817e4Smiod    could return to us?  */
713d8817e4Smiod static unsigned int buffer_length;
723d8817e4Smiod 
733d8817e4Smiod /* The index into an sb structure we are reading from.  -1 if none.  */
743d8817e4Smiod static int sb_index = -1;
753d8817e4Smiod 
763d8817e4Smiod /* If we are reading from an sb structure, this is it.  */
773d8817e4Smiod static sb from_sb;
783d8817e4Smiod 
793d8817e4Smiod /* Should we do a conditional check on from_sb? */
803d8817e4Smiod static int from_sb_is_expansion = 1;
813d8817e4Smiod 
823d8817e4Smiod /* The number of nested sb structures we have included.  */
833d8817e4Smiod int macro_nest;
843d8817e4Smiod 
853d8817e4Smiod /* We can have more than one source file open at once, though the info for all
863d8817e4Smiod    but the latest one are saved off in a struct input_save.  These files remain
873d8817e4Smiod    open, so we are limited by the number of open files allowed by the
883d8817e4Smiod    underlying OS. We may also sequentially read more than one source file in an
893d8817e4Smiod    assembly.  */
903d8817e4Smiod 
913d8817e4Smiod /* We must track the physical file and line number for error messages. We also
923d8817e4Smiod    track a "logical" file and line number corresponding to (C?)  compiler
933d8817e4Smiod    source line numbers.  Whenever we open a file we must fill in
943d8817e4Smiod    physical_input_file. So if it is NULL we have not opened any files yet.  */
953d8817e4Smiod 
963d8817e4Smiod static char *physical_input_file;
973d8817e4Smiod static char *logical_input_file;
983d8817e4Smiod 
993d8817e4Smiod typedef unsigned int line_numberT;	/* 1-origin line number in a source file.  */
1003d8817e4Smiod /* A line ends in '\n' or eof.  */
1013d8817e4Smiod 
1023d8817e4Smiod static line_numberT physical_input_line;
1033d8817e4Smiod static int logical_input_line;
1043d8817e4Smiod 
1053d8817e4Smiod /* Struct used to save the state of the input handler during include files */
1063d8817e4Smiod struct input_save {
1073d8817e4Smiod   char *              buffer_start;
1083d8817e4Smiod   char *              partial_where;
1093d8817e4Smiod   int                 partial_size;
1103d8817e4Smiod   char                save_source[AFTER_SIZE];
1113d8817e4Smiod   unsigned int        buffer_length;
1123d8817e4Smiod   char *              physical_input_file;
1133d8817e4Smiod   char *              logical_input_file;
1143d8817e4Smiod   line_numberT        physical_input_line;
1153d8817e4Smiod   int                 logical_input_line;
1163d8817e4Smiod   int                 sb_index;
1173d8817e4Smiod   sb                  from_sb;
1183d8817e4Smiod   int                 from_sb_is_expansion; /* Should we do a conditional check?  */
1193d8817e4Smiod   struct input_save * next_saved_file;	/* Chain of input_saves.  */
1203d8817e4Smiod   char *              input_file_save;	/* Saved state of input routines.  */
1213d8817e4Smiod   char *              saved_position;	/* Caller's saved position in buf.  */
1223d8817e4Smiod };
1233d8817e4Smiod 
1243d8817e4Smiod static struct input_save *input_scrub_push (char *saved_position);
1253d8817e4Smiod static char *input_scrub_pop (struct input_save *arg);
1263d8817e4Smiod 
1273d8817e4Smiod /* Saved information about the file that .include'd this one.  When we hit EOF,
1283d8817e4Smiod    we automatically pop to that file.  */
1293d8817e4Smiod 
1303d8817e4Smiod static struct input_save *next_saved_file;
1313d8817e4Smiod 
1323d8817e4Smiod /* Push the state of input reading and scrubbing so that we can #include.
1333d8817e4Smiod    The return value is a 'void *' (fudged for old compilers) to a save
1343d8817e4Smiod    area, which can be restored by passing it to input_scrub_pop().  */
1353d8817e4Smiod 
1363d8817e4Smiod static struct input_save *
input_scrub_push(char * saved_position)1373d8817e4Smiod input_scrub_push (char *saved_position)
1383d8817e4Smiod {
1393d8817e4Smiod   register struct input_save *saved;
1403d8817e4Smiod 
1413d8817e4Smiod   saved = (struct input_save *) xmalloc (sizeof *saved);
1423d8817e4Smiod 
1433d8817e4Smiod   saved->saved_position = saved_position;
1443d8817e4Smiod   saved->buffer_start = buffer_start;
1453d8817e4Smiod   saved->partial_where = partial_where;
1463d8817e4Smiod   saved->partial_size = partial_size;
1473d8817e4Smiod   saved->buffer_length = buffer_length;
1483d8817e4Smiod   saved->physical_input_file = physical_input_file;
1493d8817e4Smiod   saved->logical_input_file = logical_input_file;
1503d8817e4Smiod   saved->physical_input_line = physical_input_line;
1513d8817e4Smiod   saved->logical_input_line = logical_input_line;
1523d8817e4Smiod   saved->sb_index = sb_index;
1533d8817e4Smiod   saved->from_sb = from_sb;
1543d8817e4Smiod   saved->from_sb_is_expansion = from_sb_is_expansion;
1553d8817e4Smiod   memcpy (saved->save_source, save_source, sizeof (save_source));
1563d8817e4Smiod   saved->next_saved_file = next_saved_file;
1573d8817e4Smiod   saved->input_file_save = input_file_push ();
1583d8817e4Smiod 
1593d8817e4Smiod   input_file_begin ();		/* Reinitialize! */
1603d8817e4Smiod   logical_input_line = -1;
1613d8817e4Smiod   logical_input_file = (char *) NULL;
1623d8817e4Smiod   buffer_length = input_file_buffer_size ();
1633d8817e4Smiod   sb_index = -1;
1643d8817e4Smiod 
1653d8817e4Smiod   buffer_start = xmalloc ((BEFORE_SIZE + buffer_length + buffer_length + AFTER_SIZE));
1663d8817e4Smiod   memcpy (buffer_start, BEFORE_STRING, (int) BEFORE_SIZE);
1673d8817e4Smiod 
1683d8817e4Smiod   return saved;
1693d8817e4Smiod }
1703d8817e4Smiod 
1713d8817e4Smiod static char *
input_scrub_pop(struct input_save * saved)1723d8817e4Smiod input_scrub_pop (struct input_save *saved)
1733d8817e4Smiod {
1743d8817e4Smiod   char *saved_position;
1753d8817e4Smiod 
1763d8817e4Smiod   input_scrub_end ();		/* Finish off old buffer */
1773d8817e4Smiod 
1783d8817e4Smiod   input_file_pop (saved->input_file_save);
1793d8817e4Smiod   saved_position = saved->saved_position;
1803d8817e4Smiod   buffer_start = saved->buffer_start;
1813d8817e4Smiod   buffer_length = saved->buffer_length;
1823d8817e4Smiod   physical_input_file = saved->physical_input_file;
1833d8817e4Smiod   logical_input_file = saved->logical_input_file;
1843d8817e4Smiod   physical_input_line = saved->physical_input_line;
1853d8817e4Smiod   logical_input_line = saved->logical_input_line;
1863d8817e4Smiod   sb_index = saved->sb_index;
1873d8817e4Smiod   from_sb = saved->from_sb;
1883d8817e4Smiod   from_sb_is_expansion = saved->from_sb_is_expansion;
1893d8817e4Smiod   partial_where = saved->partial_where;
1903d8817e4Smiod   partial_size = saved->partial_size;
1913d8817e4Smiod   next_saved_file = saved->next_saved_file;
1923d8817e4Smiod   memcpy (save_source, saved->save_source, sizeof (save_source));
1933d8817e4Smiod 
1943d8817e4Smiod   free (saved);
1953d8817e4Smiod   return saved_position;
1963d8817e4Smiod }
1973d8817e4Smiod 
1983d8817e4Smiod void
input_scrub_begin(void)1993d8817e4Smiod input_scrub_begin (void)
2003d8817e4Smiod {
2013d8817e4Smiod   know (strlen (BEFORE_STRING) == BEFORE_SIZE);
2023d8817e4Smiod   know (strlen (AFTER_STRING) == AFTER_SIZE
2033d8817e4Smiod 	|| (AFTER_STRING[0] == '\0' && AFTER_SIZE == 1));
2043d8817e4Smiod 
2053d8817e4Smiod   input_file_begin ();
2063d8817e4Smiod 
2073d8817e4Smiod   buffer_length = input_file_buffer_size ();
2083d8817e4Smiod 
2093d8817e4Smiod   buffer_start = xmalloc ((BEFORE_SIZE + buffer_length + buffer_length + AFTER_SIZE));
2103d8817e4Smiod   memcpy (buffer_start, BEFORE_STRING, (int) BEFORE_SIZE);
2113d8817e4Smiod 
2123d8817e4Smiod   /* Line number things.  */
2133d8817e4Smiod   logical_input_line = -1;
2143d8817e4Smiod   logical_input_file = (char *) NULL;
2153d8817e4Smiod   physical_input_file = NULL;	/* No file read yet.  */
2163d8817e4Smiod   next_saved_file = NULL;	/* At EOF, don't pop to any other file */
2173d8817e4Smiod   do_scrub_begin (flag_m68k_mri);
2183d8817e4Smiod }
2193d8817e4Smiod 
2203d8817e4Smiod void
input_scrub_end(void)2213d8817e4Smiod input_scrub_end (void)
2223d8817e4Smiod {
2233d8817e4Smiod   if (buffer_start)
2243d8817e4Smiod     {
2253d8817e4Smiod       free (buffer_start);
2263d8817e4Smiod       buffer_start = 0;
2273d8817e4Smiod       input_file_end ();
2283d8817e4Smiod     }
2293d8817e4Smiod }
2303d8817e4Smiod 
2313d8817e4Smiod /* Start reading input from a new file.
2323d8817e4Smiod    Return start of caller's part of buffer.  */
2333d8817e4Smiod 
2343d8817e4Smiod char *
input_scrub_new_file(char * filename)2353d8817e4Smiod input_scrub_new_file (char *filename)
2363d8817e4Smiod {
2373d8817e4Smiod   input_file_open (filename, !flag_no_comments);
2383d8817e4Smiod   physical_input_file = filename[0] ? filename : _("{standard input}");
2393d8817e4Smiod   physical_input_line = 0;
2403d8817e4Smiod 
2413d8817e4Smiod   partial_size = 0;
2423d8817e4Smiod   return (buffer_start + BEFORE_SIZE);
2433d8817e4Smiod }
2443d8817e4Smiod 
2453d8817e4Smiod /* Include a file from the current file.  Save our state, cause it to
2463d8817e4Smiod    be restored on EOF, and begin handling a new file.  Same result as
2473d8817e4Smiod    input_scrub_new_file.  */
2483d8817e4Smiod 
2493d8817e4Smiod char *
input_scrub_include_file(char * filename,char * position)2503d8817e4Smiod input_scrub_include_file (char *filename, char *position)
2513d8817e4Smiod {
2523d8817e4Smiod   next_saved_file = input_scrub_push (position);
2533d8817e4Smiod   return input_scrub_new_file (filename);
2543d8817e4Smiod }
2553d8817e4Smiod 
2563d8817e4Smiod /* Start getting input from an sb structure.  This is used when
2573d8817e4Smiod    expanding a macro.  */
2583d8817e4Smiod 
2593d8817e4Smiod void
input_scrub_include_sb(sb * from,char * position,int is_expansion)2603d8817e4Smiod input_scrub_include_sb (sb *from, char *position, int is_expansion)
2613d8817e4Smiod {
2623d8817e4Smiod   if (macro_nest > max_macro_nest)
2633d8817e4Smiod     as_fatal (_("macros nested too deeply"));
2643d8817e4Smiod   ++macro_nest;
2653d8817e4Smiod 
2663d8817e4Smiod #ifdef md_macro_start
2673d8817e4Smiod   if (is_expansion)
2683d8817e4Smiod     {
2693d8817e4Smiod       md_macro_start ();
2703d8817e4Smiod     }
2713d8817e4Smiod #endif
2723d8817e4Smiod 
2733d8817e4Smiod   next_saved_file = input_scrub_push (position);
2743d8817e4Smiod 
2753d8817e4Smiod   sb_new (&from_sb);
2763d8817e4Smiod   from_sb_is_expansion = is_expansion;
2773d8817e4Smiod   if (from->len >= 1 && from->ptr[0] != '\n')
2783d8817e4Smiod     {
2793d8817e4Smiod       /* Add the sentinel required by read.c.  */
2803d8817e4Smiod       sb_add_char (&from_sb, '\n');
2813d8817e4Smiod     }
2823d8817e4Smiod   sb_scrub_and_add_sb (&from_sb, from);
2833d8817e4Smiod   sb_index = 1;
2843d8817e4Smiod 
2853d8817e4Smiod   /* These variables are reset by input_scrub_push.  Restore them
2863d8817e4Smiod      since we are, after all, still at the same point in the file.  */
2873d8817e4Smiod   logical_input_line = next_saved_file->logical_input_line;
2883d8817e4Smiod   logical_input_file = next_saved_file->logical_input_file;
2893d8817e4Smiod }
2903d8817e4Smiod 
2913d8817e4Smiod void
input_scrub_close(void)2923d8817e4Smiod input_scrub_close (void)
2933d8817e4Smiod {
2943d8817e4Smiod   input_file_close ();
2953d8817e4Smiod }
2963d8817e4Smiod 
2973d8817e4Smiod char *
input_scrub_next_buffer(char ** bufp)2983d8817e4Smiod input_scrub_next_buffer (char **bufp)
2993d8817e4Smiod {
3003d8817e4Smiod   register char *limit;		/*->just after last char of buffer.  */
3013d8817e4Smiod 
3023d8817e4Smiod   if (sb_index >= 0)
3033d8817e4Smiod     {
3043d8817e4Smiod       if (sb_index >= from_sb.len)
3053d8817e4Smiod 	{
3063d8817e4Smiod 	  sb_kill (&from_sb);
3073d8817e4Smiod 	  if (from_sb_is_expansion
3083d8817e4Smiod 	      )
3093d8817e4Smiod 	    {
3103d8817e4Smiod 	      cond_finish_check (macro_nest);
3113d8817e4Smiod #ifdef md_macro_end
3123d8817e4Smiod 	      /* Allow the target to clean up per-macro expansion
3133d8817e4Smiod 	         data.  */
3143d8817e4Smiod 	      md_macro_end ();
3153d8817e4Smiod #endif
3163d8817e4Smiod 	    }
3173d8817e4Smiod 	  --macro_nest;
3183d8817e4Smiod 	  partial_where = NULL;
3193d8817e4Smiod 	  if (next_saved_file != NULL)
3203d8817e4Smiod 	    *bufp = input_scrub_pop (next_saved_file);
3213d8817e4Smiod 	  return partial_where;
3223d8817e4Smiod 	}
3233d8817e4Smiod 
3243d8817e4Smiod       partial_where = from_sb.ptr + from_sb.len;
3253d8817e4Smiod       partial_size = 0;
3263d8817e4Smiod       *bufp = from_sb.ptr + sb_index;
3273d8817e4Smiod       sb_index = from_sb.len;
3283d8817e4Smiod       return partial_where;
3293d8817e4Smiod     }
3303d8817e4Smiod 
3313d8817e4Smiod   *bufp = buffer_start + BEFORE_SIZE;
3323d8817e4Smiod 
3333d8817e4Smiod   if (partial_size)
3343d8817e4Smiod     {
335*4d6c937dSmillert       memmove (buffer_start + BEFORE_SIZE, partial_where,
3363d8817e4Smiod 	      (unsigned int) partial_size);
3373d8817e4Smiod       memcpy (buffer_start + BEFORE_SIZE, save_source, AFTER_SIZE);
3383d8817e4Smiod     }
3393d8817e4Smiod   limit = input_file_give_next_buffer (buffer_start
3403d8817e4Smiod 				       + BEFORE_SIZE
3413d8817e4Smiod 				       + partial_size);
3423d8817e4Smiod   if (limit)
3433d8817e4Smiod     {
3443d8817e4Smiod       register char *p;		/* Find last newline.  */
3453d8817e4Smiod 
3463d8817e4Smiod       for (p = limit - 1; *p != '\n'; --p)
3473d8817e4Smiod 	;
3483d8817e4Smiod       ++p;
3493d8817e4Smiod 
3503d8817e4Smiod       while (p <= buffer_start + BEFORE_SIZE)
3513d8817e4Smiod 	{
3523d8817e4Smiod 	  int limoff;
3533d8817e4Smiod 
3543d8817e4Smiod 	  limoff = limit - buffer_start;
3553d8817e4Smiod 	  buffer_length += input_file_buffer_size ();
3563d8817e4Smiod 	  buffer_start = xrealloc (buffer_start,
3573d8817e4Smiod 				   (BEFORE_SIZE
3583d8817e4Smiod 				    + 2 * buffer_length
3593d8817e4Smiod 				    + AFTER_SIZE));
3603d8817e4Smiod 	  *bufp = buffer_start + BEFORE_SIZE;
3613d8817e4Smiod 	  limit = input_file_give_next_buffer (buffer_start + limoff);
3623d8817e4Smiod 
3633d8817e4Smiod 	  if (limit == NULL)
3643d8817e4Smiod 	    {
3653d8817e4Smiod 	      as_warn (_("partial line at end of file ignored"));
3663d8817e4Smiod 	      partial_where = NULL;
3673d8817e4Smiod 	      if (next_saved_file)
3683d8817e4Smiod 		*bufp = input_scrub_pop (next_saved_file);
3693d8817e4Smiod 	      return NULL;
3703d8817e4Smiod 	    }
3713d8817e4Smiod 
3723d8817e4Smiod 	  for (p = limit - 1; *p != '\n'; --p)
3733d8817e4Smiod 	    ;
3743d8817e4Smiod 	  ++p;
3753d8817e4Smiod 	}
3763d8817e4Smiod 
3773d8817e4Smiod       partial_where = p;
3783d8817e4Smiod       partial_size = limit - p;
3793d8817e4Smiod       memcpy (save_source, partial_where, (int) AFTER_SIZE);
3803d8817e4Smiod       memcpy (partial_where, AFTER_STRING, (int) AFTER_SIZE);
3813d8817e4Smiod     }
3823d8817e4Smiod   else
3833d8817e4Smiod     {
3843d8817e4Smiod       partial_where = 0;
3853d8817e4Smiod       if (partial_size > 0)
3863d8817e4Smiod 	{
3873d8817e4Smiod 	  as_warn (_("partial line at end of file ignored"));
3883d8817e4Smiod 	}
3893d8817e4Smiod 
3903d8817e4Smiod       /* Tell the listing we've finished the file.  */
3913d8817e4Smiod       LISTING_EOF ();
3923d8817e4Smiod 
3933d8817e4Smiod       /* If we should pop to another file at EOF, do it.  */
3943d8817e4Smiod       if (next_saved_file)
3953d8817e4Smiod 	{
3963d8817e4Smiod 	  *bufp = input_scrub_pop (next_saved_file);	/* Pop state */
3973d8817e4Smiod 	  /* partial_where is now correct to return, since we popped it.  */
3983d8817e4Smiod 	}
3993d8817e4Smiod     }
4003d8817e4Smiod   return (partial_where);
4013d8817e4Smiod }
4023d8817e4Smiod 
4033d8817e4Smiod /* The remaining part of this file deals with line numbers, error
4043d8817e4Smiod    messages and so on.  Return TRUE if we opened any file.  */
4053d8817e4Smiod 
4063d8817e4Smiod int
seen_at_least_1_file(void)4073d8817e4Smiod seen_at_least_1_file (void)
4083d8817e4Smiod {
4093d8817e4Smiod   return (physical_input_file != NULL);
4103d8817e4Smiod }
4113d8817e4Smiod 
4123d8817e4Smiod void
bump_line_counters(void)4133d8817e4Smiod bump_line_counters (void)
4143d8817e4Smiod {
4153d8817e4Smiod   if (sb_index < 0)
4163d8817e4Smiod     {
4173d8817e4Smiod       ++physical_input_line;
4183d8817e4Smiod       if (logical_input_line >= 0)
4193d8817e4Smiod 	++logical_input_line;
4203d8817e4Smiod     }
4213d8817e4Smiod }
4223d8817e4Smiod 
4233d8817e4Smiod /* Tells us what the new logical line number and file are.
4243d8817e4Smiod    If the line_number is -1, we don't change the current logical line
4253d8817e4Smiod    number.  If it is -2, we decrement the logical line number (this is
4263d8817e4Smiod    to support the .appfile pseudo-op inserted into the stream by
4273d8817e4Smiod    do_scrub_chars).
4283d8817e4Smiod    If the fname is NULL, we don't change the current logical file name.
4293d8817e4Smiod    Returns nonzero if the filename actually changes.  */
4303d8817e4Smiod 
4313d8817e4Smiod int
new_logical_line(char * fname,int line_number)4323d8817e4Smiod new_logical_line (char *fname, /* DON'T destroy it!  We point to it!  */
4333d8817e4Smiod 		  int line_number)
4343d8817e4Smiod {
4353d8817e4Smiod   if (line_number >= 0)
4363d8817e4Smiod     logical_input_line = line_number;
4373d8817e4Smiod   else if (line_number == -2 && logical_input_line > 0)
4383d8817e4Smiod     --logical_input_line;
4393d8817e4Smiod 
4403d8817e4Smiod   if (fname
4413d8817e4Smiod       && (logical_input_file == NULL
4423d8817e4Smiod 	  || strcmp (logical_input_file, fname)))
4433d8817e4Smiod     {
4443d8817e4Smiod       logical_input_file = fname;
4453d8817e4Smiod       return 1;
4463d8817e4Smiod     }
4473d8817e4Smiod   else
4483d8817e4Smiod     return 0;
4493d8817e4Smiod }
4503d8817e4Smiod 
4513d8817e4Smiod /* Return the current file name and line number.
4523d8817e4Smiod    namep should be char * const *, but there are compilers which screw
4533d8817e4Smiod    up declarations like that, and it's easier to avoid it.  */
4543d8817e4Smiod 
4553d8817e4Smiod void
as_where(char ** namep,unsigned int * linep)4563d8817e4Smiod as_where (char **namep, unsigned int *linep)
4573d8817e4Smiod {
4583d8817e4Smiod   if (logical_input_file != NULL
4593d8817e4Smiod       && (linep == NULL || logical_input_line >= 0))
4603d8817e4Smiod     {
4613d8817e4Smiod       *namep = logical_input_file;
4623d8817e4Smiod       if (linep != NULL)
4633d8817e4Smiod 	*linep = logical_input_line;
4643d8817e4Smiod     }
4653d8817e4Smiod   else if (physical_input_file != NULL)
4663d8817e4Smiod     {
4673d8817e4Smiod       *namep = physical_input_file;
4683d8817e4Smiod       if (linep != NULL)
4693d8817e4Smiod 	*linep = physical_input_line;
4703d8817e4Smiod     }
4713d8817e4Smiod   else
4723d8817e4Smiod     {
4733d8817e4Smiod       *namep = 0;
4743d8817e4Smiod       if (linep != NULL)
4753d8817e4Smiod 	*linep = 0;
4763d8817e4Smiod     }
4773d8817e4Smiod }
478