input-scrub.c revision 78828
133965Sjdp/* input_scrub.c - Break up input buffers into whole numbers of lines.
278828Sobrien   Copyright 1987, 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998,
378828Sobrien   2000
433965Sjdp   Free Software Foundation, Inc.
533965Sjdp
633965Sjdp   This file is part of GAS, the GNU Assembler.
733965Sjdp
833965Sjdp   GAS is free software; you can redistribute it and/or modify
933965Sjdp   it under the terms of the GNU General Public License as published by
1033965Sjdp   the Free Software Foundation; either version 2, or (at your option)
1133965Sjdp   any later version.
1233965Sjdp
1333965Sjdp   GAS is distributed in the hope that it will be useful,
1433965Sjdp   but WITHOUT ANY WARRANTY; without even the implied warranty of
1533965Sjdp   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
1633965Sjdp   GNU General Public License for more details.
1733965Sjdp
1833965Sjdp   You should have received a copy of the GNU General Public License
1933965Sjdp   along with GAS; see the file COPYING.  If not, write to the Free
2033965Sjdp   Software Foundation, 59 Temple Place - Suite 330, Boston, MA
2177298Sobrien   02111-1307, USA.  */
2233965Sjdp
2333965Sjdp#include <errno.h>		/* Need this to make errno declaration right */
2433965Sjdp#include "as.h"
2533965Sjdp#include "input-file.h"
2633965Sjdp#include "sb.h"
2760484Sobrien#include "listing.h"
2833965Sjdp
2933965Sjdp/*
3033965Sjdp * O/S independent module to supply buffers of sanitised source code
3133965Sjdp * to rest of assembler.  We get sanitised input data of arbitrary length.
3233965Sjdp * We break these buffers on line boundaries, recombine pieces that
3333965Sjdp * were broken across buffers, and return a buffer of full lines to
3433965Sjdp * the caller.
3533965Sjdp * The last partial line begins the next buffer we build and return to caller.
3633965Sjdp * The buffer returned to caller is preceeded by BEFORE_STRING and followed
3733965Sjdp * by AFTER_STRING, as sentinels. The last character before AFTER_STRING
3833965Sjdp * is a newline.
3933965Sjdp * Also looks after line numbers, for e.g. error messages.
4033965Sjdp */
4133965Sjdp
4233965Sjdp/*
4333965Sjdp * We don't care how filthy our buffers are, but our callers assume
4433965Sjdp * that the following sanitation has already been done.
4533965Sjdp *
4633965Sjdp * No comments, reduce a comment to a space.
4733965Sjdp * Reduce a tab to a space unless it is 1st char of line.
4833965Sjdp * All multiple tabs and spaces collapsed into 1 char. Tab only
4933965Sjdp *   legal if 1st char of line.
5033965Sjdp * # line file statements converted to .line x;.file y; statements.
5133965Sjdp * Escaped newlines at end of line: remove them but add as many newlines
5233965Sjdp *   to end of statement as you removed in the middle, to synch line numbers.
5333965Sjdp */
5433965Sjdp
5533965Sjdp#define BEFORE_STRING ("\n")
5677298Sobrien#define AFTER_STRING ("\0")	/* memcpy of 0 chars might choke.  */
5733965Sjdp#define BEFORE_SIZE (1)
5833965Sjdp#define AFTER_SIZE  (1)
5933965Sjdp
6077298Sobrienstatic char *buffer_start;	/*->1st char of full buffer area.  */
6177298Sobrienstatic char *partial_where;	/*->after last full line in buffer.  */
6277298Sobrienstatic int partial_size;	/* >=0. Number of chars in partial line in buffer.  */
6377298Sobrien
6477298Sobrien/* Because we need AFTER_STRING just after last full line, it clobbers
6577298Sobrien   1st part of partial line. So we preserve 1st part of partial line
6677298Sobrien   here.  */
6733965Sjdpstatic char save_source[AFTER_SIZE];
6833965Sjdp
6977298Sobrien/* What is the largest size buffer that input_file_give_next_buffer()
7077298Sobrien   could return to us?  */
7177298Sobrienstatic unsigned int buffer_length;
7277298Sobrien
7333965Sjdp/* The index into an sb structure we are reading from.  -1 if none.  */
7433965Sjdpstatic int sb_index = -1;
7533965Sjdp
7633965Sjdp/* If we are reading from an sb structure, this is it.  */
7733965Sjdpstatic sb from_sb;
7833965Sjdp
7960484Sobrien/* Should we do a conditional check on from_sb? */
8060484Sobrienstatic int from_sb_is_expansion = 1;
8160484Sobrien
8233965Sjdp/* The number of nested sb structures we have included.  */
8333965Sjdpint macro_nest;
8433965Sjdp
8533965Sjdp/* We can have more than one source file open at once, though the info for all
8633965Sjdp   but the latest one are saved off in a struct input_save.  These files remain
8733965Sjdp   open, so we are limited by the number of open files allowed by the
8833965Sjdp   underlying OS. We may also sequentially read more than one source file in an
8977298Sobrien   assembly.  */
9033965Sjdp
9133965Sjdp/* We must track the physical file and line number for error messages. We also
9233965Sjdp   track a "logical" file and line number corresponding to (C?)  compiler
9333965Sjdp   source line numbers.  Whenever we open a file we must fill in
9477298Sobrien   physical_input_file. So if it is NULL we have not opened any files yet.  */
9533965Sjdp
9633965Sjdpstatic char *physical_input_file;
9733965Sjdpstatic char *logical_input_file;
9833965Sjdp
9977298Sobrientypedef unsigned int line_numberT;	/* 1-origin line number in a source file.  */
10077298Sobrien/* A line ends in '\n' or eof.  */
10133965Sjdp
10233965Sjdpstatic line_numberT physical_input_line;
10333965Sjdpstatic int logical_input_line;
10433965Sjdp
10533965Sjdp/* Struct used to save the state of the input handler during include files */
10677298Sobrienstruct input_save {
10777298Sobrien  char *              buffer_start;
10877298Sobrien  char *              partial_where;
10977298Sobrien  int                 partial_size;
11077298Sobrien  char                save_source[AFTER_SIZE];
11177298Sobrien  unsigned int        buffer_length;
11277298Sobrien  char *              physical_input_file;
11377298Sobrien  char *              logical_input_file;
11477298Sobrien  line_numberT        physical_input_line;
11577298Sobrien  int                 logical_input_line;
11677298Sobrien  int                 sb_index;
11777298Sobrien  sb                  from_sb;
11877298Sobrien  int                 from_sb_is_expansion; /* Should we do a conditional check?  */
11977298Sobrien  struct input_save * next_saved_file;	/* Chain of input_saves.  */
12077298Sobrien  char *              input_file_save;	/* Saved state of input routines.  */
12177298Sobrien  char *              saved_position;	/* Caller's saved position in buf.  */
12277298Sobrien};
12333965Sjdp
12433965Sjdpstatic struct input_save *input_scrub_push PARAMS ((char *saved_position));
12533965Sjdpstatic char *input_scrub_pop PARAMS ((struct input_save *arg));
12633965Sjdpstatic void as_1_char PARAMS ((unsigned int c, FILE * stream));
12733965Sjdp
12833965Sjdp/* Saved information about the file that .include'd this one.  When we hit EOF,
12977298Sobrien   we automatically pop to that file.  */
13033965Sjdp
13133965Sjdpstatic struct input_save *next_saved_file;
13233965Sjdp
13333965Sjdp/* Push the state of input reading and scrubbing so that we can #include.
13433965Sjdp   The return value is a 'void *' (fudged for old compilers) to a save
13577298Sobrien   area, which can be restored by passing it to input_scrub_pop().  */
13677298Sobrien
13733965Sjdpstatic struct input_save *
13833965Sjdpinput_scrub_push (saved_position)
13933965Sjdp     char *saved_position;
14033965Sjdp{
14133965Sjdp  register struct input_save *saved;
14233965Sjdp
14333965Sjdp  saved = (struct input_save *) xmalloc (sizeof *saved);
14433965Sjdp
14533965Sjdp  saved->saved_position = saved_position;
14633965Sjdp  saved->buffer_start = buffer_start;
14733965Sjdp  saved->partial_where = partial_where;
14833965Sjdp  saved->partial_size = partial_size;
14933965Sjdp  saved->buffer_length = buffer_length;
15033965Sjdp  saved->physical_input_file = physical_input_file;
15133965Sjdp  saved->logical_input_file = logical_input_file;
15233965Sjdp  saved->physical_input_line = physical_input_line;
15333965Sjdp  saved->logical_input_line = logical_input_line;
15433965Sjdp  saved->sb_index = sb_index;
15533965Sjdp  saved->from_sb = from_sb;
15660484Sobrien  saved->from_sb_is_expansion = from_sb_is_expansion;
15733965Sjdp  memcpy (saved->save_source, save_source, sizeof (save_source));
15833965Sjdp  saved->next_saved_file = next_saved_file;
15933965Sjdp  saved->input_file_save = input_file_push ();
16033965Sjdp
16133965Sjdp  input_file_begin ();		/* Reinitialize! */
16233965Sjdp  logical_input_line = -1;
16333965Sjdp  logical_input_file = (char *) NULL;
16433965Sjdp  buffer_length = input_file_buffer_size ();
16533965Sjdp  sb_index = -1;
16633965Sjdp
16733965Sjdp  buffer_start = xmalloc ((BEFORE_SIZE + buffer_length + buffer_length + AFTER_SIZE));
16833965Sjdp  memcpy (buffer_start, BEFORE_STRING, (int) BEFORE_SIZE);
16933965Sjdp
17033965Sjdp  return saved;
17177298Sobrien}
17233965Sjdp
17333965Sjdpstatic char *
17433965Sjdpinput_scrub_pop (saved)
17533965Sjdp     struct input_save *saved;
17633965Sjdp{
17733965Sjdp  char *saved_position;
17833965Sjdp
17933965Sjdp  input_scrub_end ();		/* Finish off old buffer */
18033965Sjdp
18133965Sjdp  input_file_pop (saved->input_file_save);
18233965Sjdp  saved_position = saved->saved_position;
18333965Sjdp  buffer_start = saved->buffer_start;
18433965Sjdp  buffer_length = saved->buffer_length;
18533965Sjdp  physical_input_file = saved->physical_input_file;
18633965Sjdp  logical_input_file = saved->logical_input_file;
18733965Sjdp  physical_input_line = saved->physical_input_line;
18833965Sjdp  logical_input_line = saved->logical_input_line;
18933965Sjdp  sb_index = saved->sb_index;
19033965Sjdp  from_sb = saved->from_sb;
19160484Sobrien  from_sb_is_expansion = saved->from_sb_is_expansion;
19233965Sjdp  partial_where = saved->partial_where;
19333965Sjdp  partial_size = saved->partial_size;
19433965Sjdp  next_saved_file = saved->next_saved_file;
19533965Sjdp  memcpy (save_source, saved->save_source, sizeof (save_source));
19633965Sjdp
19733965Sjdp  free (saved);
19833965Sjdp  return saved_position;
19933965Sjdp}
20033965Sjdp
20133965Sjdpvoid
20233965Sjdpinput_scrub_begin ()
20333965Sjdp{
20433965Sjdp  know (strlen (BEFORE_STRING) == BEFORE_SIZE);
20577298Sobrien  know (strlen (AFTER_STRING) == AFTER_SIZE
20677298Sobrien	|| (AFTER_STRING[0] == '\0' && AFTER_SIZE == 1));
20733965Sjdp
20833965Sjdp  input_file_begin ();
20933965Sjdp
21033965Sjdp  buffer_length = input_file_buffer_size ();
21133965Sjdp
21233965Sjdp  buffer_start = xmalloc ((BEFORE_SIZE + buffer_length + buffer_length + AFTER_SIZE));
21333965Sjdp  memcpy (buffer_start, BEFORE_STRING, (int) BEFORE_SIZE);
21433965Sjdp
21577298Sobrien  /* Line number things.  */
21633965Sjdp  logical_input_line = -1;
21733965Sjdp  logical_input_file = (char *) NULL;
21877298Sobrien  physical_input_file = NULL;	/* No file read yet.  */
21933965Sjdp  next_saved_file = NULL;	/* At EOF, don't pop to any other file */
22033965Sjdp  do_scrub_begin (flag_m68k_mri);
22133965Sjdp}
22233965Sjdp
22333965Sjdpvoid
22433965Sjdpinput_scrub_end ()
22533965Sjdp{
22633965Sjdp  if (buffer_start)
22733965Sjdp    {
22833965Sjdp      free (buffer_start);
22933965Sjdp      buffer_start = 0;
23033965Sjdp      input_file_end ();
23133965Sjdp    }
23233965Sjdp}
23333965Sjdp
23477298Sobrien/* Start reading input from a new file.
23577298Sobrien   Return start of caller's part of buffer.  */
23633965Sjdp
23777298Sobrienchar *
23833965Sjdpinput_scrub_new_file (filename)
23933965Sjdp     char *filename;
24033965Sjdp{
24133965Sjdp  input_file_open (filename, !flag_no_comments);
24260484Sobrien  physical_input_file = filename[0] ? filename : _("{standard input}");
24333965Sjdp  physical_input_line = 0;
24433965Sjdp
24533965Sjdp  partial_size = 0;
24633965Sjdp  return (buffer_start + BEFORE_SIZE);
24733965Sjdp}
24833965Sjdp
24933965Sjdp/* Include a file from the current file.  Save our state, cause it to
25033965Sjdp   be restored on EOF, and begin handling a new file.  Same result as
25177298Sobrien   input_scrub_new_file.  */
25233965Sjdp
25333965Sjdpchar *
25433965Sjdpinput_scrub_include_file (filename, position)
25533965Sjdp     char *filename;
25633965Sjdp     char *position;
25733965Sjdp{
25833965Sjdp  next_saved_file = input_scrub_push (position);
25933965Sjdp  return input_scrub_new_file (filename);
26033965Sjdp}
26133965Sjdp
26233965Sjdp/* Start getting input from an sb structure.  This is used when
26333965Sjdp   expanding a macro.  */
26433965Sjdp
26533965Sjdpvoid
26660484Sobrieninput_scrub_include_sb (from, position, is_expansion)
26733965Sjdp     sb *from;
26833965Sjdp     char *position;
26960484Sobrien     int is_expansion;
27033965Sjdp{
27133965Sjdp  if (macro_nest > max_macro_nest)
27277298Sobrien    as_fatal (_("macros nested too deeply"));
27333965Sjdp  ++macro_nest;
27433965Sjdp
27560484Sobrien#ifdef md_macro_start
27660484Sobrien  if (is_expansion)
27760484Sobrien    {
27860484Sobrien      md_macro_start ();
27960484Sobrien    }
28060484Sobrien#endif
28160484Sobrien
28233965Sjdp  next_saved_file = input_scrub_push (position);
28333965Sjdp
28433965Sjdp  sb_new (&from_sb);
28560484Sobrien  from_sb_is_expansion = is_expansion;
28638889Sjdp  if (from->len >= 1 && from->ptr[0] != '\n')
28738889Sjdp    {
28838889Sjdp      /* Add the sentinel required by read.c.  */
28938889Sjdp      sb_add_char (&from_sb, '\n');
29038889Sjdp    }
29133965Sjdp  sb_add_sb (&from_sb, from);
29233965Sjdp  sb_index = 1;
29333965Sjdp
29433965Sjdp  /* These variables are reset by input_scrub_push.  Restore them
29533965Sjdp     since we are, after all, still at the same point in the file.  */
29633965Sjdp  logical_input_line = next_saved_file->logical_input_line;
29733965Sjdp  logical_input_file = next_saved_file->logical_input_file;
29833965Sjdp}
29933965Sjdp
30033965Sjdpvoid
30133965Sjdpinput_scrub_close ()
30233965Sjdp{
30333965Sjdp  input_file_close ();
30433965Sjdp}
30533965Sjdp
30633965Sjdpchar *
30733965Sjdpinput_scrub_next_buffer (bufp)
30833965Sjdp     char **bufp;
30933965Sjdp{
31077298Sobrien  register char *limit;		/*->just after last char of buffer.  */
31133965Sjdp
31233965Sjdp  if (sb_index >= 0)
31333965Sjdp    {
31433965Sjdp      if (sb_index >= from_sb.len)
31533965Sjdp	{
31633965Sjdp	  sb_kill (&from_sb);
31777298Sobrien	  if (from_sb_is_expansion
31877298Sobrien	      )
31977298Sobrien	    {
32077298Sobrien	      cond_finish_check (macro_nest);
32160484Sobrien#ifdef md_macro_end
32277298Sobrien	      /* Allow the target to clean up per-macro expansion
32377298Sobrien	         data.  */
32477298Sobrien	      md_macro_end ();
32560484Sobrien#endif
32677298Sobrien	    }
32777298Sobrien	  --macro_nest;
32833965Sjdp	  partial_where = NULL;
32933965Sjdp	  if (next_saved_file != NULL)
33033965Sjdp	    *bufp = input_scrub_pop (next_saved_file);
33133965Sjdp	  return partial_where;
33233965Sjdp	}
33333965Sjdp
33433965Sjdp      partial_where = from_sb.ptr + from_sb.len;
33533965Sjdp      partial_size = 0;
33633965Sjdp      *bufp = from_sb.ptr + sb_index;
33733965Sjdp      sb_index = from_sb.len;
33833965Sjdp      return partial_where;
33933965Sjdp    }
34033965Sjdp
34133965Sjdp  *bufp = buffer_start + BEFORE_SIZE;
34233965Sjdp
34333965Sjdp  if (partial_size)
34433965Sjdp    {
34533965Sjdp      memcpy (buffer_start + BEFORE_SIZE, partial_where,
34633965Sjdp	      (unsigned int) partial_size);
34733965Sjdp      memcpy (buffer_start + BEFORE_SIZE, save_source, AFTER_SIZE);
34833965Sjdp    }
34933965Sjdp  limit = input_file_give_next_buffer (buffer_start
35033965Sjdp				       + BEFORE_SIZE
35133965Sjdp				       + partial_size);
35233965Sjdp  if (limit)
35333965Sjdp    {
35477298Sobrien      register char *p;		/* Find last newline.  */
35533965Sjdp
35633965Sjdp      for (p = limit - 1; *p != '\n'; --p)
35733965Sjdp	;
35833965Sjdp      ++p;
35933965Sjdp
36033965Sjdp      while (p <= buffer_start + BEFORE_SIZE)
36133965Sjdp	{
36233965Sjdp	  int limoff;
36333965Sjdp
36433965Sjdp	  limoff = limit - buffer_start;
36533965Sjdp	  buffer_length += input_file_buffer_size ();
36633965Sjdp	  buffer_start = xrealloc (buffer_start,
36733965Sjdp				   (BEFORE_SIZE
36833965Sjdp				    + 2 * buffer_length
36933965Sjdp				    + AFTER_SIZE));
37033965Sjdp	  *bufp = buffer_start + BEFORE_SIZE;
37133965Sjdp	  limit = input_file_give_next_buffer (buffer_start + limoff);
37233965Sjdp
37333965Sjdp	  if (limit == NULL)
37433965Sjdp	    {
37560484Sobrien	      as_warn (_("partial line at end of file ignored"));
37633965Sjdp	      partial_where = NULL;
37733965Sjdp	      if (next_saved_file)
37833965Sjdp		*bufp = input_scrub_pop (next_saved_file);
37933965Sjdp	      return NULL;
38033965Sjdp	    }
38133965Sjdp
38233965Sjdp	  for (p = limit - 1; *p != '\n'; --p)
38333965Sjdp	    ;
38433965Sjdp	  ++p;
38533965Sjdp	}
38633965Sjdp
38733965Sjdp      partial_where = p;
38833965Sjdp      partial_size = limit - p;
38933965Sjdp      memcpy (save_source, partial_where, (int) AFTER_SIZE);
39033965Sjdp      memcpy (partial_where, AFTER_STRING, (int) AFTER_SIZE);
39133965Sjdp    }
39233965Sjdp  else
39333965Sjdp    {
39433965Sjdp      partial_where = 0;
39533965Sjdp      if (partial_size > 0)
39633965Sjdp	{
39760484Sobrien	  as_warn (_("Partial line at end of file ignored"));
39833965Sjdp	}
39960484Sobrien
40060484Sobrien      /* Tell the listing we've finished the file.  */
40160484Sobrien      LISTING_EOF ();
40260484Sobrien
40377298Sobrien      /* If we should pop to another file at EOF, do it.  */
40433965Sjdp      if (next_saved_file)
40533965Sjdp	{
40633965Sjdp	  *bufp = input_scrub_pop (next_saved_file);	/* Pop state */
40777298Sobrien	  /* partial_where is now correct to return, since we popped it.  */
40833965Sjdp	}
40933965Sjdp    }
41033965Sjdp  return (partial_where);
41177298Sobrien}
41233965Sjdp
41377298Sobrien/* The remaining part of this file deals with line numbers, error
41477298Sobrien   messages and so on.  Return TRUE if we opened any file.  */
41533965Sjdp
41633965Sjdpint
41777298Sobrienseen_at_least_1_file ()
41833965Sjdp{
41933965Sjdp  return (physical_input_file != NULL);
42033965Sjdp}
42133965Sjdp
42233965Sjdpvoid
42333965Sjdpbump_line_counters ()
42433965Sjdp{
42533965Sjdp  if (sb_index < 0)
42633965Sjdp    {
42733965Sjdp      ++physical_input_line;
42833965Sjdp      if (logical_input_line >= 0)
42933965Sjdp	++logical_input_line;
43033965Sjdp    }
43133965Sjdp}
43233965Sjdp
43377298Sobrien/* Tells us what the new logical line number and file are.
43477298Sobrien   If the line_number is -1, we don't change the current logical line
43577298Sobrien   number.  If it is -2, we decrement the logical line number (this is
43677298Sobrien   to support the .appfile pseudo-op inserted into the stream by
43777298Sobrien   do_scrub_chars).
43877298Sobrien   If the fname is NULL, we don't change the current logical file name.
43977298Sobrien   Returns nonzero if the filename actually changes.  */
44077298Sobrien
44138889Sjdpint
44233965Sjdpnew_logical_line (fname, line_number)
44377298Sobrien     char *fname;		/* DON'T destroy it!  We point to it!  */
44433965Sjdp     int line_number;
44533965Sjdp{
44633965Sjdp  if (line_number >= 0)
44733965Sjdp    logical_input_line = line_number;
44833965Sjdp  else if (line_number == -2 && logical_input_line > 0)
44933965Sjdp    --logical_input_line;
45038889Sjdp
45138889Sjdp  if (fname
45238889Sjdp      && (logical_input_file == NULL
45338889Sjdp	  || strcmp (logical_input_file, fname)))
45438889Sjdp    {
45538889Sjdp      logical_input_file = fname;
45638889Sjdp      return 1;
45738889Sjdp    }
45838889Sjdp  else
45938889Sjdp    return 0;
46077298Sobrien}
46133965Sjdp
46277298Sobrien/* Return the current file name and line number.
46377298Sobrien   namep should be char * const *, but there are compilers which screw
46477298Sobrien   up declarations like that, and it's easier to avoid it.  */
46577298Sobrien
46677298Sobrienvoid
46733965Sjdpas_where (namep, linep)
46833965Sjdp     char **namep;
46933965Sjdp     unsigned int *linep;
47033965Sjdp{
47133965Sjdp  if (logical_input_file != NULL
47233965Sjdp      && (linep == NULL || logical_input_line >= 0))
47333965Sjdp    {
47433965Sjdp      *namep = logical_input_file;
47533965Sjdp      if (linep != NULL)
47633965Sjdp	*linep = logical_input_line;
47733965Sjdp    }
47833965Sjdp  else if (physical_input_file != NULL)
47933965Sjdp    {
48033965Sjdp      *namep = physical_input_file;
48133965Sjdp      if (linep != NULL)
48233965Sjdp	*linep = physical_input_line;
48333965Sjdp    }
48433965Sjdp  else
48533965Sjdp    {
48633965Sjdp      *namep = 0;
48733965Sjdp      if (linep != NULL)
48833965Sjdp	*linep = 0;
48933965Sjdp    }
49077298Sobrien}
49133965Sjdp
49277298Sobrien/* Output to given stream how much of line we have scanned so far.
49377298Sobrien   Assumes we have scanned up to and including input_line_pointer.
49477298Sobrien   No free '\n' at end of line.  */
49533965Sjdp
49633965Sjdpvoid
49733965Sjdpas_howmuch (stream)
49877298Sobrien     FILE *stream;		/* Opened for write please.  */
49933965Sjdp{
50077298Sobrien  register char *p;		/* Scan input line.  */
50133965Sjdp
50233965Sjdp  for (p = input_line_pointer - 1; *p != '\n'; --p)
50333965Sjdp    {
50433965Sjdp    }
50577298Sobrien  ++p;				/* p->1st char of line.  */
50633965Sjdp  for (; p <= input_line_pointer; p++)
50733965Sjdp    {
50877298Sobrien      /* Assume ASCII. EBCDIC & other micro-computer char sets ignored.  */
50933965Sjdp      as_1_char ((unsigned char) *p, stream);
51033965Sjdp    }
51133965Sjdp}
51233965Sjdp
51377298Sobrienstatic void
51433965Sjdpas_1_char (c, stream)
51533965Sjdp     unsigned int c;
51633965Sjdp     FILE *stream;
51733965Sjdp{
51833965Sjdp  if (c > 127)
51933965Sjdp    {
52033965Sjdp      (void) putc ('%', stream);
52133965Sjdp      c -= 128;
52233965Sjdp    }
52333965Sjdp  if (c < 32)
52433965Sjdp    {
52533965Sjdp      (void) putc ('^', stream);
52633965Sjdp      c += '@';
52733965Sjdp    }
52833965Sjdp  (void) putc (c, stream);
52933965Sjdp}
530