app.c revision 89857
1187938Semax/* This is the Assembler Pre-Processor
2187938Semax   Copyright 1987, 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998,
3187938Semax   1999, 2000
4187938Semax   Free Software Foundation, Inc.
5187938Semax
6187938Semax   This file is part of GAS, the GNU Assembler.
7187938Semax
8187938Semax   GAS is free software; you can redistribute it and/or modify
9187938Semax   it under the terms of the GNU General Public License as published by
10187938Semax   the Free Software Foundation; either version 2, or (at your option)
11187938Semax   any later version.
12187938Semax
13187938Semax   GAS is distributed in the hope that it will be useful,
14187938Semax   but WITHOUT ANY WARRANTY; without even the implied warranty of
15187938Semax   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16187938Semax   GNU General Public License for more details.
17187938Semax
18187938Semax   You should have received a copy of the GNU General Public License
19187938Semax   along with GAS; see the file COPYING.  If not, write to the Free
20187938Semax   Software Foundation, 59 Temple Place - Suite 330, Boston, MA
21187938Semax   02111-1307, USA.  */
22187938Semax
23187938Semax/* Modified by Allen Wirfs-Brock, Instantiations Inc 2/90 */
24187938Semax/* App, the assembler pre-processor.  This pre-processor strips out excess
25187938Semax   spaces, turns single-quoted characters into a decimal constant, and turns
26187938Semax   # <number> <filename> <garbage> into a .line <number>\n.file <filename>
27187938Semax   pair.  This needs better error-handling.  */
28187938Semax
29187938Semax#include <stdio.h>
30187938Semax#include "as.h"			/* For BAD_CASE() only */
31187938Semax
32187938Semax#if (__STDC__ != 1)
33187938Semax#ifndef const
34187938Semax#define const  /* empty */
35187938Semax#endif
36187938Semax#endif
37187938Semax
38187938Semax#ifdef TC_M68K
39187938Semax/* Whether we are scrubbing in m68k MRI mode.  This is different from
40187938Semax   flag_m68k_mri, because the two flags will be affected by the .mri
41187938Semax   pseudo-op at different times.  */
42187938Semaxstatic int scrub_m68k_mri;
43187938Semax#else
44187938Semax#define scrub_m68k_mri 0
45187938Semax#endif
46187938Semax
47187938Semax/* The pseudo-op which switches in and out of MRI mode.  See the
48187938Semax   comment in do_scrub_chars.  */
49187938Semaxstatic const char mri_pseudo[] = ".mri 0";
50187938Semax
51187938Semax#if defined TC_ARM && defined OBJ_ELF
52187938Semax/* The pseudo-op for which we need to special-case `@' characters.
53187938Semax   See the comment in do_scrub_chars.  */
54187938Semaxstatic const char   symver_pseudo[] = ".symver";
55187938Semaxstatic const char * symver_state;
56187938Semax#endif
57187938Semax
58187938Semaxstatic char lex[256];
59187938Semaxstatic const char symbol_chars[] =
60187938Semax"$._ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
61187938Semax
62187938Semax#define LEX_IS_SYMBOL_COMPONENT		1
63187938Semax#define LEX_IS_WHITESPACE		2
64187938Semax#define LEX_IS_LINE_SEPARATOR		3
65187938Semax#define LEX_IS_COMMENT_START		4
66187938Semax#define LEX_IS_LINE_COMMENT_START	5
67187938Semax#define	LEX_IS_TWOCHAR_COMMENT_1ST	6
68187938Semax#define	LEX_IS_STRINGQUOTE		8
69187938Semax#define	LEX_IS_COLON			9
70187938Semax#define	LEX_IS_NEWLINE			10
71187938Semax#define	LEX_IS_ONECHAR_QUOTE		11
72187938Semax#ifdef TC_V850
73187938Semax#define LEX_IS_DOUBLEDASH_1ST		12
74187938Semax#endif
75187938Semax#ifdef TC_M32R
76187938Semax#define DOUBLEBAR_PARALLEL
77187938Semax#endif
78187938Semax#ifdef DOUBLEBAR_PARALLEL
79187938Semax#define LEX_IS_DOUBLEBAR_1ST		13
80187938Semax#endif
81187938Semax#define LEX_IS_PARALLEL_SEPARATOR	14
82187938Semax#define IS_SYMBOL_COMPONENT(c)		(lex[c] == LEX_IS_SYMBOL_COMPONENT)
83187938Semax#define IS_WHITESPACE(c)		(lex[c] == LEX_IS_WHITESPACE)
84187938Semax#define IS_LINE_SEPARATOR(c)		(lex[c] == LEX_IS_LINE_SEPARATOR)
85187938Semax#define IS_PARALLEL_SEPARATOR(c)	(lex[c] == LEX_IS_PARALLEL_SEPARATOR)
86187938Semax#define IS_COMMENT(c)			(lex[c] == LEX_IS_COMMENT_START)
87187938Semax#define IS_LINE_COMMENT(c)		(lex[c] == LEX_IS_LINE_COMMENT_START)
88187938Semax#define	IS_NEWLINE(c)			(lex[c] == LEX_IS_NEWLINE)
89187938Semax
90187938Semaxstatic int process_escape PARAMS ((int));
91187938Semax
92187938Semax/* FIXME-soon: The entire lexer/parser thingy should be
93187938Semax   built statically at compile time rather than dynamically
94187938Semax   each and every time the assembler is run.  xoxorich.  */
95187938Semax
96187938Semaxvoid
97187938Semaxdo_scrub_begin (m68k_mri)
98187938Semax     int m68k_mri ATTRIBUTE_UNUSED;
99187938Semax{
100187938Semax  const char *p;
101187938Semax  int c;
102187938Semax
103187938Semax  lex[' '] = LEX_IS_WHITESPACE;
104187938Semax  lex['\t'] = LEX_IS_WHITESPACE;
105187938Semax  lex['\r'] = LEX_IS_WHITESPACE;
106187938Semax  lex['\n'] = LEX_IS_NEWLINE;
107187938Semax  lex[':'] = LEX_IS_COLON;
108187938Semax
109187938Semax#ifdef TC_M68K
110187938Semax  scrub_m68k_mri = m68k_mri;
111187938Semax
112187938Semax  if (! m68k_mri)
113187938Semax#endif
114187938Semax    {
115187938Semax      lex['"'] = LEX_IS_STRINGQUOTE;
116187938Semax
117187938Semax#if ! defined (TC_HPPA) && ! defined (TC_I370)
118187938Semax      /* I370 uses single-quotes to delimit integer, float constants */
119187938Semax      lex['\''] = LEX_IS_ONECHAR_QUOTE;
120187938Semax#endif
121187938Semax
122187938Semax#ifdef SINGLE_QUOTE_STRINGS
123187938Semax      lex['\''] = LEX_IS_STRINGQUOTE;
124187938Semax#endif
125187938Semax    }
126187938Semax
127187938Semax  /* Note: if any other character can be LEX_IS_STRINGQUOTE, the loop
128187938Semax     in state 5 of do_scrub_chars must be changed.  */
129187938Semax
130187938Semax  /* Note that these override the previous defaults, e.g. if ';' is a
131187938Semax     comment char, then it isn't a line separator.  */
132187938Semax  for (p = symbol_chars; *p; ++p)
133187938Semax    {
134187938Semax      lex[(unsigned char) *p] = LEX_IS_SYMBOL_COMPONENT;
135187938Semax    }				/* declare symbol characters */
136187938Semax
137187938Semax  for (c = 128; c < 256; ++c)
138187938Semax    lex[c] = LEX_IS_SYMBOL_COMPONENT;
139187938Semax
140187938Semax#ifdef tc_symbol_chars
141187938Semax  /* This macro permits the processor to specify all characters which
142187938Semax     may appears in an operand.  This will prevent the scrubber from
143187938Semax     discarding meaningful whitespace in certain cases.  The i386
144187938Semax     backend uses this to support prefixes, which can confuse the
145187938Semax     scrubber as to whether it is parsing operands or opcodes.  */
146187938Semax  for (p = tc_symbol_chars; *p; ++p)
147187938Semax    lex[(unsigned char) *p] = LEX_IS_SYMBOL_COMPONENT;
148187938Semax#endif
149187938Semax
150187938Semax  /* The m68k backend wants to be able to change comment_chars.  */
151187938Semax#ifndef tc_comment_chars
152187938Semax#define tc_comment_chars comment_chars
153187938Semax#endif
154187938Semax  for (p = tc_comment_chars; *p; p++)
155187938Semax    {
156187938Semax      lex[(unsigned char) *p] = LEX_IS_COMMENT_START;
157187938Semax    }				/* declare comment chars */
158187938Semax
159187938Semax  for (p = line_comment_chars; *p; p++)
160187938Semax    {
161187938Semax      lex[(unsigned char) *p] = LEX_IS_LINE_COMMENT_START;
162187938Semax    }				/* declare line comment chars */
163187938Semax
164187938Semax  for (p = line_separator_chars; *p; p++)
165187938Semax    {
166187938Semax      lex[(unsigned char) *p] = LEX_IS_LINE_SEPARATOR;
167187938Semax    }				/* declare line separators */
168187938Semax
169187938Semax#ifdef tc_parallel_separator_chars
170187938Semax  /* This macro permits the processor to specify all characters which
171187938Semax     separate parallel insns on the same line.  */
172187938Semax  for (p = tc_parallel_separator_chars; *p; p++)
173187938Semax    {
174187938Semax      lex[(unsigned char) *p] = LEX_IS_PARALLEL_SEPARATOR;
175187938Semax    }				/* declare parallel separators */
176187938Semax#endif
177187938Semax
178187938Semax  /* Only allow slash-star comments if slash is not in use.
179187938Semax     FIXME: This isn't right.  We should always permit them.  */
180187938Semax  if (lex['/'] == 0)
181187938Semax    {
182187938Semax      lex['/'] = LEX_IS_TWOCHAR_COMMENT_1ST;
183187938Semax    }
184187938Semax
185187938Semax#ifdef TC_M68K
186187938Semax  if (m68k_mri)
187187938Semax    {
188187938Semax      lex['\''] = LEX_IS_STRINGQUOTE;
189187938Semax      lex[';'] = LEX_IS_COMMENT_START;
190187938Semax      lex['*'] = LEX_IS_LINE_COMMENT_START;
191187938Semax      /* The MRI documentation says '!' is LEX_IS_COMMENT_START, but
192187938Semax         then it can't be used in an expression.  */
193187938Semax      lex['!'] = LEX_IS_LINE_COMMENT_START;
194187938Semax    }
195187938Semax#endif
196187938Semax
197187938Semax#ifdef TC_V850
198187938Semax  lex['-'] = LEX_IS_DOUBLEDASH_1ST;
199187938Semax#endif
200187938Semax#ifdef DOUBLEBAR_PARALLEL
201187938Semax  lex['|'] = LEX_IS_DOUBLEBAR_1ST;
202187938Semax#endif
203187938Semax#ifdef TC_D30V
204187938Semax  /* must do this is we want VLIW instruction with "->" or "<-" */
205187938Semax  lex['-'] = LEX_IS_SYMBOL_COMPONENT;
206187938Semax#endif
207187938Semax}				/* do_scrub_begin() */
208187938Semax
209187938Semax/* Saved state of the scrubber */
210187938Semaxstatic int state;
211187938Semaxstatic int old_state;
212187938Semaxstatic char *out_string;
213187938Semaxstatic char out_buf[20];
214187938Semaxstatic int add_newlines;
215187938Semaxstatic char *saved_input;
216187938Semaxstatic int saved_input_len;
217187938Semaxstatic char input_buffer[32 * 1024];
218187938Semaxstatic const char *mri_state;
219187938Semaxstatic char mri_last_ch;
220187938Semax
221187938Semax/* Data structure for saving the state of app across #include's.  Note that
222187938Semax   app is called asynchronously to the parsing of the .include's, so our
223187938Semax   state at the time .include is interpreted is completely unrelated.
224187938Semax   That's why we have to save it all.  */
225187938Semax
226187938Semaxstruct app_save {
227187938Semax  int          state;
228187938Semax  int          old_state;
229187938Semax  char *       out_string;
230187938Semax  char         out_buf[sizeof (out_buf)];
231187938Semax  int          add_newlines;
232187938Semax  char *       saved_input;
233187938Semax  int          saved_input_len;
234187938Semax#ifdef TC_M68K
235187938Semax  int          scrub_m68k_mri;
236187938Semax#endif
237187938Semax  const char * mri_state;
238187938Semax  char         mri_last_ch;
239187938Semax#if defined TC_ARM && defined OBJ_ELF
240187938Semax  const char * symver_state;
241187938Semax#endif
242187938Semax};
243187938Semax
244187938Semaxchar *
245187938Semaxapp_push ()
246187938Semax{
247187938Semax  register struct app_save *saved;
248187938Semax
249187938Semax  saved = (struct app_save *) xmalloc (sizeof (*saved));
250187938Semax  saved->state = state;
251187938Semax  saved->old_state = old_state;
252187938Semax  saved->out_string = out_string;
253187938Semax  memcpy (saved->out_buf, out_buf, sizeof (out_buf));
254187938Semax  saved->add_newlines = add_newlines;
255187938Semax  if (saved_input == NULL)
256187938Semax    saved->saved_input = NULL;
257187938Semax  else
258187938Semax    {
259187938Semax      saved->saved_input = xmalloc (saved_input_len);
260187938Semax      memcpy (saved->saved_input, saved_input, saved_input_len);
261187938Semax      saved->saved_input_len = saved_input_len;
262187938Semax    }
263187938Semax#ifdef TC_M68K
264187938Semax  saved->scrub_m68k_mri = scrub_m68k_mri;
265187938Semax#endif
266187938Semax  saved->mri_state = mri_state;
267187938Semax  saved->mri_last_ch = mri_last_ch;
268187938Semax#if defined TC_ARM && defined OBJ_ELF
269187938Semax  saved->symver_state = symver_state;
270187938Semax#endif
271187938Semax
272187938Semax  /* do_scrub_begin() is not useful, just wastes time.  */
273187938Semax
274187938Semax  state = 0;
275187938Semax  saved_input = NULL;
276187938Semax
277187938Semax  return (char *) saved;
278187938Semax}
279187938Semax
280187938Semaxvoid
281187938Semaxapp_pop (arg)
282187938Semax     char *arg;
283187938Semax{
284187938Semax  register struct app_save *saved = (struct app_save *) arg;
285187938Semax
286187938Semax  /* There is no do_scrub_end ().  */
287187938Semax  state = saved->state;
288187938Semax  old_state = saved->old_state;
289187938Semax  out_string = saved->out_string;
290187938Semax  memcpy (out_buf, saved->out_buf, sizeof (out_buf));
291187938Semax  add_newlines = saved->add_newlines;
292187938Semax  if (saved->saved_input == NULL)
293187938Semax    saved_input = NULL;
294187938Semax  else
295187938Semax    {
296187938Semax      assert (saved->saved_input_len <= (int) (sizeof input_buffer));
297187938Semax      memcpy (input_buffer, saved->saved_input, saved->saved_input_len);
298187938Semax      saved_input = input_buffer;
299187938Semax      saved_input_len = saved->saved_input_len;
300187938Semax      free (saved->saved_input);
301187938Semax    }
302187938Semax#ifdef TC_M68K
303187938Semax  scrub_m68k_mri = saved->scrub_m68k_mri;
304187938Semax#endif
305187938Semax  mri_state = saved->mri_state;
306187938Semax  mri_last_ch = saved->mri_last_ch;
307187938Semax#if defined TC_ARM && defined OBJ_ELF
308187938Semax  symver_state = saved->symver_state;
309187938Semax#endif
310187938Semax
311187938Semax  free (arg);
312187938Semax}				/* app_pop() */
313187938Semax
314187938Semax/* @@ This assumes that \n &c are the same on host and target.  This is not
315187938Semax   necessarily true.  */
316187938Semaxstatic int
317187938Semaxprocess_escape (ch)
318187938Semax     int ch;
319187938Semax{
320187938Semax  switch (ch)
321187938Semax    {
322187938Semax    case 'b':
323187938Semax      return '\b';
324187938Semax    case 'f':
325187938Semax      return '\f';
326187938Semax    case 'n':
327187938Semax      return '\n';
328187938Semax    case 'r':
329187938Semax      return '\r';
330187938Semax    case 't':
331187938Semax      return '\t';
332187938Semax    case '\'':
333187938Semax      return '\'';
334187938Semax    case '"':
335187938Semax      return '\"';
336187938Semax    default:
337187938Semax      return ch;
338187938Semax    }
339187938Semax}
340187938Semax
341187938Semax/* This function is called to process input characters.  The GET
342187938Semax   parameter is used to retrieve more input characters.  GET should
343187938Semax   set its parameter to point to a buffer, and return the length of
344187938Semax   the buffer; it should return 0 at end of file.  The scrubbed output
345187938Semax   characters are put into the buffer starting at TOSTART; the TOSTART
346187938Semax   buffer is TOLEN bytes in length.  The function returns the number
347187938Semax   of scrubbed characters put into TOSTART.  This will be TOLEN unless
348187938Semax   end of file was seen.  This function is arranged as a state
349187938Semax   machine, and saves its state so that it may return at any point.
350187938Semax   This is the way the old code used to work.  */
351187938Semax
352187938Semaxint
353187938Semaxdo_scrub_chars (get, tostart, tolen)
354187938Semax     int (*get) PARAMS ((char *, int));
355187938Semax     char *tostart;
356187938Semax     int tolen;
357187938Semax{
358187938Semax  char *to = tostart;
359187938Semax  char *toend = tostart + tolen;
360187938Semax  char *from;
361187938Semax  char *fromend;
362187938Semax  int fromlen;
363187938Semax  register int ch, ch2 = 0;
364187938Semax
365187938Semax  /*State 0: beginning of normal line
366187938Semax	  1: After first whitespace on line (flush more white)
367187938Semax	  2: After first non-white (opcode) on line (keep 1white)
368187938Semax	  3: after second white on line (into operands) (flush white)
369187938Semax	  4: after putting out a .line, put out digits
370187938Semax	  5: parsing a string, then go to old-state
371187938Semax	  6: putting out \ escape in a "d string.
372187938Semax	  7: After putting out a .appfile, put out string.
373187938Semax	  8: After putting out a .appfile string, flush until newline.
374187938Semax	  9: After seeing symbol char in state 3 (keep 1white after symchar)
375187938Semax	 10: After seeing whitespace in state 9 (keep white before symchar)
376187938Semax	 11: After seeing a symbol character in state 0 (eg a label definition)
377187938Semax	 -1: output string in out_string and go to the state in old_state
378187938Semax	 -2: flush text until a '*' '/' is seen, then go to state old_state
379187938Semax#ifdef TC_V850
380187938Semax         12: After seeing a dash, looking for a second dash as a start of comment.
381187938Semax#endif
382187938Semax#ifdef DOUBLEBAR_PARALLEL
383187938Semax	 13: After seeing a vertical bar, looking for a second vertical bar as a parallel expression seperator.
384187938Semax#endif
385187938Semax	  */
386187938Semax
387187938Semax  /* I added states 9 and 10 because the MIPS ECOFF assembler uses
388187938Semax     constructs like ``.loc 1 20''.  This was turning into ``.loc
389187938Semax     120''.  States 9 and 10 ensure that a space is never dropped in
390187938Semax     between characters which could appear in an identifier.  Ian
391187938Semax     Taylor, ian@cygnus.com.
392187938Semax
393187938Semax     I added state 11 so that something like "Lfoo add %r25,%r26,%r27" works
394187938Semax     correctly on the PA (and any other target where colons are optional).
395187938Semax     Jeff Law, law@cs.utah.edu.
396187938Semax
397187938Semax     I added state 13 so that something like "cmp r1, r2 || trap #1" does not
398187938Semax     get squashed into "cmp r1,r2||trap#1", with the all important space
399187938Semax     between the 'trap' and the '#1' being eliminated.  nickc@cygnus.com  */
400187938Semax
401187938Semax  /* This macro gets the next input character.  */
402187938Semax
403187938Semax#define GET()							\
404187938Semax  (from < fromend						\
405187938Semax   ? * (unsigned char *) (from++)				\
406187938Semax   : (saved_input = NULL,					\
407187938Semax      fromlen = (*get) (input_buffer, sizeof input_buffer),	\
408187938Semax      from = input_buffer,					\
409187938Semax      fromend = from + fromlen,					\
410187938Semax      (fromlen == 0						\
411187938Semax       ? EOF							\
412187938Semax       : * (unsigned char *) (from++))))
413187938Semax
414187938Semax  /* This macro pushes a character back on the input stream.  */
415187938Semax
416187938Semax#define UNGET(uch) (*--from = (uch))
417187938Semax
418187938Semax  /* This macro puts a character into the output buffer.  If this
419187938Semax     character fills the output buffer, this macro jumps to the label
420187938Semax     TOFULL.  We use this rather ugly approach because we need to
421187938Semax     handle two different termination conditions: EOF on the input
422187938Semax     stream, and a full output buffer.  It would be simpler if we
423187938Semax     always read in the entire input stream before processing it, but
424187938Semax     I don't want to make such a significant change to the assembler's
425187938Semax     memory usage.  */
426187938Semax
427187938Semax#define PUT(pch)			\
428187938Semax  do					\
429187938Semax    {					\
430187938Semax      *to++ = (pch);			\
431187938Semax      if (to >= toend)			\
432187938Semax        goto tofull;			\
433187938Semax    }					\
434187938Semax  while (0)
435187938Semax
436187938Semax  if (saved_input != NULL)
437187938Semax    {
438187938Semax      from = saved_input;
439187938Semax      fromend = from + saved_input_len;
440187938Semax    }
441187938Semax  else
442187938Semax    {
443187938Semax      fromlen = (*get) (input_buffer, sizeof input_buffer);
444187938Semax      if (fromlen == 0)
445187938Semax	return 0;
446187938Semax      from = input_buffer;
447187938Semax      fromend = from + fromlen;
448187938Semax    }
449187938Semax
450187938Semax  while (1)
451187938Semax    {
452187938Semax      /* The cases in this switch end with continue, in order to
453187938Semax         branch back to the top of this while loop and generate the
454187938Semax         next output character in the appropriate state.  */
455187938Semax      switch (state)
456187938Semax	{
457187938Semax	case -1:
458187938Semax	  ch = *out_string++;
459187938Semax	  if (*out_string == '\0')
460187938Semax	    {
461187938Semax	      state = old_state;
462187938Semax	      old_state = 3;
463187938Semax	    }
464187938Semax	  PUT (ch);
465187938Semax	  continue;
466187938Semax
467187938Semax	case -2:
468187938Semax	  for (;;)
469187938Semax	    {
470187938Semax	      do
471187938Semax		{
472187938Semax		  ch = GET ();
473187938Semax
474187938Semax		  if (ch == EOF)
475187938Semax		    {
476187938Semax		      as_warn (_("end of file in comment"));
477187938Semax		      goto fromeof;
478187938Semax		    }
479187938Semax
480187938Semax		  if (ch == '\n')
481187938Semax		    PUT ('\n');
482187938Semax		}
483187938Semax	      while (ch != '*');
484187938Semax
485187938Semax	      while ((ch = GET ()) == '*')
486187938Semax		;
487187938Semax
488187938Semax	      if (ch == EOF)
489187938Semax		{
490187938Semax		  as_warn (_("end of file in comment"));
491187938Semax		  goto fromeof;
492187938Semax		}
493187938Semax
494187938Semax	      if (ch == '/')
495187938Semax		break;
496187938Semax
497187938Semax	      UNGET (ch);
498187938Semax	    }
499187938Semax
500187938Semax	  state = old_state;
501187938Semax	  UNGET (' ');
502187938Semax	  continue;
503187938Semax
504187938Semax	case 4:
505187938Semax	  ch = GET ();
506187938Semax	  if (ch == EOF)
507187938Semax	    goto fromeof;
508187938Semax	  else if (ch >= '0' && ch <= '9')
509187938Semax	    PUT (ch);
510187938Semax	  else
511187938Semax	    {
512187938Semax	      while (ch != EOF && IS_WHITESPACE (ch))
513187938Semax		ch = GET ();
514187938Semax	      if (ch == '"')
515187938Semax		{
516187938Semax		  UNGET (ch);
517187938Semax		  if (scrub_m68k_mri)
518187938Semax		    out_string = "\n\tappfile ";
519187938Semax		  else
520187938Semax		    out_string = "\n\t.appfile ";
521187938Semax		  old_state = 7;
522187938Semax		  state = -1;
523187938Semax		  PUT (*out_string++);
524187938Semax		}
525187938Semax	      else
526187938Semax		{
527187938Semax		  while (ch != EOF && ch != '\n')
528187938Semax		    ch = GET ();
529187938Semax		  state = 0;
530187938Semax		  PUT (ch);
531187938Semax		}
532187938Semax	    }
533187938Semax	  continue;
534187938Semax
535187938Semax	case 5:
536187938Semax	  /* We are going to copy everything up to a quote character,
537187938Semax             with special handling for a backslash.  We try to
538187938Semax             optimize the copying in the simple case without using the
539187938Semax             GET and PUT macros.  */
540187938Semax	  {
541187938Semax	    char *s;
542187938Semax	    int len;
543187938Semax
544187938Semax	    for (s = from; s < fromend; s++)
545187938Semax	      {
546187938Semax		ch = *s;
547187938Semax		/* This condition must be changed if the type of any
548187938Semax                   other character can be LEX_IS_STRINGQUOTE.  */
549187938Semax		if (ch == '\\'
550187938Semax		    || ch == '"'
551187938Semax		    || ch == '\''
552187938Semax		    || ch == '\n')
553187938Semax		  break;
554187938Semax	      }
555187938Semax	    len = s - from;
556187938Semax	    if (len > toend - to)
557187938Semax	      len = toend - to;
558187938Semax	    if (len > 0)
559187938Semax	      {
560187938Semax		memcpy (to, from, len);
561187938Semax		to += len;
562187938Semax		from += len;
563187938Semax	      }
564187938Semax	  }
565187938Semax
566187938Semax	  ch = GET ();
567187938Semax	  if (ch == EOF)
568187938Semax	    {
569187938Semax	      as_warn (_("end of file in string; inserted '\"'"));
570187938Semax	      state = old_state;
571187938Semax	      UNGET ('\n');
572187938Semax	      PUT ('"');
573187938Semax	    }
574187938Semax	  else if (lex[ch] == LEX_IS_STRINGQUOTE)
575187938Semax	    {
576305287Sdim	      state = old_state;
577187938Semax	      PUT (ch);
578187938Semax	    }
579187938Semax#ifndef NO_STRING_ESCAPES
580187938Semax	  else if (ch == '\\')
581187938Semax	    {
582187938Semax	      state = 6;
583187938Semax	      PUT (ch);
584187938Semax	    }
585187938Semax#endif
586187938Semax	  else if (scrub_m68k_mri && ch == '\n')
587187938Semax	    {
588187938Semax	      /* Just quietly terminate the string.  This permits lines like
589187938Semax		   bne	label	loop if we haven't reach end yet
590187938Semax		 */
591187938Semax	      state = old_state;
592305287Sdim	      UNGET (ch);
593187938Semax	      PUT ('\'');
594187938Semax	    }
595187938Semax	  else
596187938Semax	    {
597187938Semax	      PUT (ch);
598187938Semax	    }
599187938Semax	  continue;
600187938Semax
601187938Semax	case 6:
602187938Semax	  state = 5;
603187938Semax	  ch = GET ();
604187938Semax	  switch (ch)
605187938Semax	    {
606187938Semax	      /* Handle strings broken across lines, by turning '\n' into
607187938Semax		 '\\' and 'n'.  */
608187938Semax	    case '\n':
609187938Semax	      UNGET ('n');
610187938Semax	      add_newlines++;
611187938Semax	      PUT ('\\');
612187938Semax	      continue;
613187938Semax
614187938Semax	    case '"':
615187938Semax	    case '\\':
616187938Semax	    case 'b':
617187938Semax	    case 'f':
618187938Semax	    case 'n':
619187938Semax	    case 'r':
620187938Semax	    case 't':
621187938Semax	    case 'v':
622187938Semax	    case 'x':
623187938Semax	    case 'X':
624187938Semax	    case '0':
625187938Semax	    case '1':
626187938Semax	    case '2':
627187938Semax	    case '3':
628187938Semax	    case '4':
629187938Semax	    case '5':
630187938Semax	    case '6':
631187938Semax	    case '7':
632187938Semax	      break;
633187938Semax#if defined(IGNORE_NONSTANDARD_ESCAPES) | defined(ONLY_STANDARD_ESCAPES)
634187938Semax	    default:
635187938Semax	      as_warn (_("unknown escape '\\%c' in string; ignored"), ch);
636187938Semax	      break;
637187938Semax#else  /* ONLY_STANDARD_ESCAPES */
638187938Semax	    default:
639187938Semax	      /* Accept \x as x for any x */
640187938Semax	      break;
641187938Semax#endif /* ONLY_STANDARD_ESCAPES */
642187938Semax
643187938Semax	    case EOF:
644187938Semax	      as_warn (_("end of file in string; '\"' inserted"));
645187938Semax	      PUT ('"');
646187938Semax	      continue;
647187938Semax	    }
648187938Semax	  PUT (ch);
649187938Semax	  continue;
650187938Semax
651187938Semax	case 7:
652187938Semax	  ch = GET ();
653187938Semax	  state = 5;
654187938Semax	  old_state = 8;
655187938Semax	  if (ch == EOF)
656187938Semax	    goto fromeof;
657187938Semax	  PUT (ch);
658187938Semax	  continue;
659187938Semax
660187938Semax	case 8:
661187938Semax	  do
662187938Semax	    ch = GET ();
663187938Semax	  while (ch != '\n' && ch != EOF);
664187938Semax	  if (ch == EOF)
665187938Semax	    goto fromeof;
666187938Semax	  state = 0;
667187938Semax	  PUT (ch);
668187938Semax	  continue;
669187938Semax	}
670187938Semax
671187938Semax      /* OK, we are somewhere in states 0 through 4 or 9 through 11 */
672187938Semax
673187938Semax      /* flushchar: */
674187938Semax      ch = GET ();
675187938Semax
676187938Semax    recycle:
677187938Semax
678187938Semax#if defined TC_ARM && defined OBJ_ELF
679187938Semax      /* We need to watch out for .symver directives.  See the comment later
680187938Semax	 in this function.  */
681187938Semax      if (symver_state == NULL)
682187938Semax	{
683187938Semax	  if ((state == 0 || state == 1) && ch == symver_pseudo[0])
684187938Semax	    symver_state = symver_pseudo + 1;
685187938Semax	}
686187938Semax      else
687187938Semax	{
688187938Semax	  /* We advance to the next state if we find the right
689187938Semax	     character.  */
690187938Semax	  if (ch != '\0' && (*symver_state == ch))
691187938Semax	    ++symver_state;
692187938Semax	  else if (*symver_state != '\0')
693187938Semax	    /* We did not get the expected character, or we didn't
694187938Semax	       get a valid terminating character after seeing the
695187938Semax	       entire pseudo-op, so we must go back to the beginning.  */
696187938Semax	    symver_state = NULL;
697187938Semax	  else
698187938Semax	    {
699187938Semax	      /* We've read the entire pseudo-op.  If this is the end
700187938Semax		 of the line, go back to the beginning.  */
701187938Semax	      if (IS_NEWLINE (ch))
702187938Semax		symver_state = NULL;
703187938Semax	    }
704187938Semax	}
705187938Semax#endif /* TC_ARM && OBJ_ELF */
706187938Semax
707187938Semax#ifdef TC_M68K
708187938Semax      /* We want to have pseudo-ops which control whether we are in
709187938Semax         MRI mode or not.  Unfortunately, since m68k MRI mode affects
710187938Semax         the scrubber, that means that we need a special purpose
711187938Semax         recognizer here.  */
712187938Semax      if (mri_state == NULL)
713187938Semax	{
714187938Semax	  if ((state == 0 || state == 1)
715187938Semax	      && ch == mri_pseudo[0])
716187938Semax	    mri_state = mri_pseudo + 1;
717187938Semax	}
718187938Semax      else
719187938Semax	{
720187938Semax	  /* We advance to the next state if we find the right
721187938Semax	     character, or if we need a space character and we get any
722187938Semax	     whitespace character, or if we need a '0' and we get a
723187938Semax	     '1' (this is so that we only need one state to handle
724187938Semax	     ``.mri 0'' and ``.mri 1'').  */
725187938Semax	  if (ch != '\0'
726187938Semax	      && (*mri_state == ch
727187938Semax		  || (*mri_state == ' '
728187938Semax		      && lex[ch] == LEX_IS_WHITESPACE)
729187938Semax		  || (*mri_state == '0'
730187938Semax		      && ch == '1')))
731187938Semax	    {
732187938Semax	      mri_last_ch = ch;
733187938Semax	      ++mri_state;
734187938Semax	    }
735187938Semax	  else if (*mri_state != '\0'
736187938Semax		   || (lex[ch] != LEX_IS_WHITESPACE
737187938Semax		       && lex[ch] != LEX_IS_NEWLINE))
738187938Semax	    {
739187938Semax	      /* We did not get the expected character, or we didn't
740187938Semax		 get a valid terminating character after seeing the
741187938Semax		 entire pseudo-op, so we must go back to the
742187938Semax		 beginning.  */
743187938Semax	      mri_state = NULL;
744187938Semax	    }
745187938Semax	  else
746187938Semax	    {
747187938Semax	      /* We've read the entire pseudo-op.  mips_last_ch is
748187938Semax                 either '0' or '1' indicating whether to enter or
749187938Semax                 leave MRI mode.  */
750187938Semax	      do_scrub_begin (mri_last_ch == '1');
751187938Semax	      mri_state = NULL;
752187938Semax
753187938Semax	      /* We continue handling the character as usual.  The
754187938Semax                 main gas reader must also handle the .mri pseudo-op
755187938Semax                 to control expression parsing and the like.  */
756	    }
757	}
758#endif
759
760      if (ch == EOF)
761	{
762	  if (state != 0)
763	    {
764	      as_warn (_("end of file not at end of a line; newline inserted"));
765	      state = 0;
766	      PUT ('\n');
767	    }
768	  goto fromeof;
769	}
770
771      switch (lex[ch])
772	{
773	case LEX_IS_WHITESPACE:
774	  do
775	    {
776	      ch = GET ();
777	    }
778	  while (ch != EOF && IS_WHITESPACE (ch));
779	  if (ch == EOF)
780	    goto fromeof;
781
782	  if (state == 0)
783	    {
784	      /* Preserve a single whitespace character at the
785		 beginning of a line.  */
786	      state = 1;
787	      UNGET (ch);
788	      PUT (' ');
789	      break;
790	    }
791
792#ifdef KEEP_WHITE_AROUND_COLON
793	  if (lex[ch] == LEX_IS_COLON)
794	    {
795	      /* Only keep this white if there's no white *after* the
796                 colon.  */
797	      ch2 = GET ();
798	      UNGET (ch2);
799	      if (!IS_WHITESPACE (ch2))
800		{
801		  state = 9;
802		  UNGET (ch);
803		  PUT (' ');
804		  break;
805		}
806	    }
807#endif
808	  if (IS_COMMENT (ch)
809	      || ch == '/'
810	      || IS_LINE_SEPARATOR (ch)
811	      || IS_PARALLEL_SEPARATOR (ch))
812	    {
813	      if (scrub_m68k_mri)
814		{
815		  /* In MRI mode, we keep these spaces.  */
816		  UNGET (ch);
817		  PUT (' ');
818		  break;
819		}
820	      goto recycle;
821	    }
822
823	  /* If we're in state 2 or 11, we've seen a non-white
824	     character followed by whitespace.  If the next character
825	     is ':', this is whitespace after a label name which we
826	     normally must ignore.  In MRI mode, though, spaces are
827	     not permitted between the label and the colon.  */
828	  if ((state == 2 || state == 11)
829	      && lex[ch] == LEX_IS_COLON
830	      && ! scrub_m68k_mri)
831	    {
832	      state = 1;
833	      PUT (ch);
834	      break;
835	    }
836
837	  switch (state)
838	    {
839	    case 0:
840	      state++;
841	      goto recycle;	/* Punted leading sp */
842	    case 1:
843	      /* We can arrive here if we leave a leading whitespace
844		 character at the beginning of a line.  */
845	      goto recycle;
846	    case 2:
847	      state = 3;
848	      if (to + 1 < toend)
849		{
850		  /* Optimize common case by skipping UNGET/GET.  */
851		  PUT (' ');	/* Sp after opco */
852		  goto recycle;
853		}
854	      UNGET (ch);
855	      PUT (' ');
856	      break;
857	    case 3:
858	      if (scrub_m68k_mri)
859		{
860		  /* In MRI mode, we keep these spaces.  */
861		  UNGET (ch);
862		  PUT (' ');
863		  break;
864		}
865	      goto recycle;	/* Sp in operands */
866	    case 9:
867	    case 10:
868	      if (scrub_m68k_mri)
869		{
870		  /* In MRI mode, we keep these spaces.  */
871		  state = 3;
872		  UNGET (ch);
873		  PUT (' ');
874		  break;
875		}
876	      state = 10;	/* Sp after symbol char */
877	      goto recycle;
878	    case 11:
879	      if (LABELS_WITHOUT_COLONS || flag_m68k_mri)
880		state = 1;
881	      else
882		{
883		  /* We know that ch is not ':', since we tested that
884                     case above.  Therefore this is not a label, so it
885                     must be the opcode, and we've just seen the
886                     whitespace after it.  */
887		  state = 3;
888		}
889	      UNGET (ch);
890	      PUT (' ');	/* Sp after label definition.  */
891	      break;
892	    default:
893	      BAD_CASE (state);
894	    }
895	  break;
896
897	case LEX_IS_TWOCHAR_COMMENT_1ST:
898	  ch2 = GET ();
899	  if (ch2 == '*')
900	    {
901	      for (;;)
902		{
903		  do
904		    {
905		      ch2 = GET ();
906		      if (ch2 != EOF && IS_NEWLINE (ch2))
907			add_newlines++;
908		    }
909		  while (ch2 != EOF && ch2 != '*');
910
911		  while (ch2 == '*')
912		    ch2 = GET ();
913
914		  if (ch2 == EOF || ch2 == '/')
915		    break;
916
917		  /* This UNGET will ensure that we count newlines
918                     correctly.  */
919		  UNGET (ch2);
920		}
921
922	      if (ch2 == EOF)
923		as_warn (_("end of file in multiline comment"));
924
925	      ch = ' ';
926	      goto recycle;
927	    }
928#ifdef DOUBLESLASH_LINE_COMMENTS
929	  else if (ch2 == '/')
930	    {
931	      do
932		{
933		  ch = GET ();
934		}
935	      while (ch != EOF && !IS_NEWLINE (ch));
936	      if (ch == EOF)
937		as_warn ("end of file in comment; newline inserted");
938	      state = 0;
939	      PUT ('\n');
940	      break;
941	    }
942#endif
943	  else
944	    {
945	      if (ch2 != EOF)
946		UNGET (ch2);
947	      if (state == 9 || state == 10)
948		state = 3;
949	      PUT (ch);
950	    }
951	  break;
952
953	case LEX_IS_STRINGQUOTE:
954	  if (state == 10)
955	    {
956	      /* Preserve the whitespace in foo "bar" */
957	      UNGET (ch);
958	      state = 3;
959	      PUT (' ');
960
961	      /* PUT didn't jump out.  We could just break, but we
962                 know what will happen, so optimize a bit.  */
963	      ch = GET ();
964	      old_state = 3;
965	    }
966	  else if (state == 9)
967	    old_state = 3;
968	  else
969	    old_state = state;
970	  state = 5;
971	  PUT (ch);
972	  break;
973
974#ifndef IEEE_STYLE
975	case LEX_IS_ONECHAR_QUOTE:
976	  if (state == 10)
977	    {
978	      /* Preserve the whitespace in foo 'b' */
979	      UNGET (ch);
980	      state = 3;
981	      PUT (' ');
982	      break;
983	    }
984	  ch = GET ();
985	  if (ch == EOF)
986	    {
987	      as_warn (_("end of file after a one-character quote; \\0 inserted"));
988	      ch = 0;
989	    }
990	  if (ch == '\\')
991	    {
992	      ch = GET ();
993	      if (ch == EOF)
994		{
995		  as_warn (_("end of file in escape character"));
996		  ch = '\\';
997		}
998	      else
999		ch = process_escape (ch);
1000	    }
1001	  sprintf (out_buf, "%d", (int) (unsigned char) ch);
1002
1003	  /* None of these 'x constants for us.  We want 'x'.  */
1004	  if ((ch = GET ()) != '\'')
1005	    {
1006#ifdef REQUIRE_CHAR_CLOSE_QUOTE
1007	      as_warn (_("missing close quote; (assumed)"));
1008#else
1009	      if (ch != EOF)
1010		UNGET (ch);
1011#endif
1012	    }
1013	  if (strlen (out_buf) == 1)
1014	    {
1015	      PUT (out_buf[0]);
1016	      break;
1017	    }
1018	  if (state == 9)
1019	    old_state = 3;
1020	  else
1021	    old_state = state;
1022	  state = -1;
1023	  out_string = out_buf;
1024	  PUT (*out_string++);
1025	  break;
1026#endif
1027
1028	case LEX_IS_COLON:
1029#ifdef KEEP_WHITE_AROUND_COLON
1030	  state = 9;
1031#else
1032	  if (state == 9 || state == 10)
1033	    state = 3;
1034	  else if (state != 3)
1035	    state = 1;
1036#endif
1037	  PUT (ch);
1038	  break;
1039
1040	case LEX_IS_NEWLINE:
1041	  /* Roll out a bunch of newlines from inside comments, etc.  */
1042	  if (add_newlines)
1043	    {
1044	      --add_newlines;
1045	      UNGET (ch);
1046	    }
1047	  /* Fall through.  */
1048
1049	case LEX_IS_LINE_SEPARATOR:
1050	  state = 0;
1051	  PUT (ch);
1052	  break;
1053
1054	case LEX_IS_PARALLEL_SEPARATOR:
1055	  state = 1;
1056	  PUT (ch);
1057	  break;
1058
1059#ifdef TC_V850
1060	case LEX_IS_DOUBLEDASH_1ST:
1061	  ch2 = GET ();
1062	  if (ch2 != '-')
1063	    {
1064	      UNGET (ch2);
1065	      goto de_fault;
1066	    }
1067	  /* Read and skip to end of line.  */
1068	  do
1069	    {
1070	      ch = GET ();
1071	    }
1072	  while (ch != EOF && ch != '\n');
1073	  if (ch == EOF)
1074	    {
1075	      as_warn (_("end of file in comment; newline inserted"));
1076	    }
1077	  state = 0;
1078	  PUT ('\n');
1079	  break;
1080#endif
1081#ifdef DOUBLEBAR_PARALLEL
1082	case LEX_IS_DOUBLEBAR_1ST:
1083	  ch2 = GET ();
1084	  if (ch2 != '|')
1085	    {
1086	      UNGET (ch2);
1087	      goto de_fault;
1088	    }
1089	  /* Reset back to state 1 and pretend that we are parsing a line from
1090	     just after the first white space.  */
1091	  state = 1;
1092	  PUT ('|');
1093	  PUT ('|');
1094	  break;
1095#endif
1096	case LEX_IS_LINE_COMMENT_START:
1097	  /* FIXME-someday: The two character comment stuff was badly
1098	     thought out.  On i386, we want '/' as line comment start
1099	     AND we want C style comments.  hence this hack.  The
1100	     whole lexical process should be reworked.  xoxorich.  */
1101	  if (ch == '/')
1102	    {
1103	      ch2 = GET ();
1104	      if (ch2 == '*')
1105		{
1106		  old_state = 3;
1107		  state = -2;
1108		  break;
1109		}
1110	      else
1111		{
1112		  UNGET (ch2);
1113		}
1114	    } /* bad hack */
1115
1116	  if (state == 0 || state == 1)	/* Only comment at start of line.  */
1117	    {
1118	      int startch;
1119
1120	      startch = ch;
1121
1122	      do
1123		{
1124		  ch = GET ();
1125		}
1126	      while (ch != EOF && IS_WHITESPACE (ch));
1127	      if (ch == EOF)
1128		{
1129		  as_warn (_("end of file in comment; newline inserted"));
1130		  PUT ('\n');
1131		  break;
1132		}
1133	      if (ch < '0' || ch > '9' || state != 0 || startch != '#')
1134		{
1135		  /* Not a cpp line.  */
1136		  while (ch != EOF && !IS_NEWLINE (ch))
1137		    ch = GET ();
1138		  if (ch == EOF)
1139		    as_warn (_("end of file in comment; newline inserted"));
1140		  state = 0;
1141		  PUT ('\n');
1142		  break;
1143		}
1144	      /* Looks like `# 123 "filename"' from cpp.  */
1145	      UNGET (ch);
1146	      old_state = 4;
1147	      state = -1;
1148	      if (scrub_m68k_mri)
1149		out_string = "\tappline ";
1150	      else
1151		out_string = "\t.appline ";
1152	      PUT (*out_string++);
1153	      break;
1154	    }
1155
1156#ifdef TC_D10V
1157	  /* All insns end in a char for which LEX_IS_SYMBOL_COMPONENT is true.
1158	     Trap is the only short insn that has a first operand that is
1159	     neither register nor label.
1160	     We must prevent exef0f ||trap #1 to degenerate to exef0f ||trap#1 .
1161	     We can't make '#' LEX_IS_SYMBOL_COMPONENT because it is
1162	     already LEX_IS_LINE_COMMENT_START.  However, it is the
1163	     only character in line_comment_chars for d10v, hence we
1164	     can recognize it as such.  */
1165	  /* An alternative approach would be to reset the state to 1 when
1166	     we see '||', '<'- or '->', but that seems to be overkill.  */
1167	  if (state == 10)
1168	    PUT (' ');
1169#endif
1170	  /* We have a line comment character which is not at the
1171	     start of a line.  If this is also a normal comment
1172	     character, fall through.  Otherwise treat it as a default
1173	     character.  */
1174	  if (strchr (tc_comment_chars, ch) == NULL
1175	      && (! scrub_m68k_mri
1176		  || (ch != '!' && ch != '*')))
1177	    goto de_fault;
1178	  if (scrub_m68k_mri
1179	      && (ch == '!' || ch == '*' || ch == '#')
1180	      && state != 1
1181	      && state != 10)
1182	    goto de_fault;
1183	  /* Fall through.  */
1184	case LEX_IS_COMMENT_START:
1185#if defined TC_ARM && defined OBJ_ELF
1186	  /* On the ARM, `@' is the comment character.
1187	     Unfortunately this is also a special character in ELF .symver
1188	     directives (and .type, though we deal with those another way).
1189	     So we check if this line is such a directive, and treat
1190	     the character as default if so.  This is a hack.  */
1191	  if ((symver_state != NULL) && (*symver_state == 0))
1192	    goto de_fault;
1193#endif
1194#ifdef WARN_COMMENTS
1195	  if (!found_comment)
1196	    as_where (&found_comment_file, &found_comment);
1197#endif
1198	  do
1199	    {
1200	      ch = GET ();
1201	    }
1202	  while (ch != EOF && !IS_NEWLINE (ch));
1203	  if (ch == EOF)
1204	    as_warn (_("end of file in comment; newline inserted"));
1205	  state = 0;
1206	  PUT ('\n');
1207	  break;
1208
1209	case LEX_IS_SYMBOL_COMPONENT:
1210	  if (state == 10)
1211	    {
1212	      /* This is a symbol character following another symbol
1213		 character, with whitespace in between.  We skipped
1214		 the whitespace earlier, so output it now.  */
1215	      UNGET (ch);
1216	      state = 3;
1217	      PUT (' ');
1218	      break;
1219	    }
1220
1221	  if (state == 3)
1222	    state = 9;
1223
1224	  /* This is a common case.  Quickly copy CH and all the
1225             following symbol component or normal characters.  */
1226	  if (to + 1 < toend
1227	      && mri_state == NULL
1228#if defined TC_ARM && defined OBJ_ELF
1229	      && symver_state == NULL
1230#endif
1231	      )
1232	    {
1233	      char *s;
1234	      int len;
1235
1236	      for (s = from; s < fromend; s++)
1237		{
1238		  int type;
1239
1240		  ch2 = *(unsigned char *) s;
1241		  type = lex[ch2];
1242		  if (type != 0
1243		      && type != LEX_IS_SYMBOL_COMPONENT)
1244		    break;
1245		}
1246	      if (s > from)
1247		{
1248		  /* Handle the last character normally, for
1249                     simplicity.  */
1250		  --s;
1251		}
1252	      len = s - from;
1253	      if (len > (toend - to) - 1)
1254		len = (toend - to) - 1;
1255	      if (len > 0)
1256		{
1257		  PUT (ch);
1258		  if (len > 8)
1259		    {
1260		      memcpy (to, from, len);
1261		      to += len;
1262		      from += len;
1263		    }
1264		  else
1265		    {
1266		      switch (len)
1267			{
1268			case 8: *to++ = *from++;
1269			case 7: *to++ = *from++;
1270			case 6: *to++ = *from++;
1271			case 5: *to++ = *from++;
1272			case 4: *to++ = *from++;
1273			case 3: *to++ = *from++;
1274			case 2: *to++ = *from++;
1275			case 1: *to++ = *from++;
1276			}
1277		    }
1278		  ch = GET ();
1279		}
1280	    }
1281
1282	  /* Fall through.  */
1283	default:
1284	de_fault:
1285	  /* Some relatively `normal' character.  */
1286	  if (state == 0)
1287	    {
1288	      state = 11;	/* Now seeing label definition */
1289	    }
1290	  else if (state == 1)
1291	    {
1292	      state = 2;	/* Ditto */
1293	    }
1294	  else if (state == 9)
1295	    {
1296	      if (lex[ch] != LEX_IS_SYMBOL_COMPONENT)
1297		state = 3;
1298	    }
1299	  else if (state == 10)
1300	    {
1301	      if (ch == '\\')
1302		{
1303		  /* Special handling for backslash: a backslash may
1304		     be the beginning of a formal parameter (of a
1305		     macro) following another symbol character, with
1306		     whitespace in between.  If that is the case, we
1307		     output a space before the parameter.  Strictly
1308		     speaking, correct handling depends upon what the
1309		     macro parameter expands into; if the parameter
1310		     expands into something which does not start with
1311		     an operand character, then we don't want to keep
1312		     the space.  We don't have enough information to
1313		     make the right choice, so here we are making the
1314		     choice which is more likely to be correct.  */
1315		  PUT (' ');
1316		}
1317
1318	      state = 3;
1319	    }
1320	  PUT (ch);
1321	  break;
1322	}
1323    }
1324
1325  /*NOTREACHED*/
1326
1327 fromeof:
1328  /* We have reached the end of the input.  */
1329  return to - tostart;
1330
1331 tofull:
1332  /* The output buffer is full.  Save any input we have not yet
1333     processed.  */
1334  if (fromend > from)
1335    {
1336      saved_input = from;
1337      saved_input_len = fromend - from;
1338    }
1339  else
1340    saved_input = NULL;
1341
1342  return to - tostart;
1343}
1344
1345/* end of app.c */
1346