* app.c (do_scrub_chars): Revert 2003-04-23 and 2003-04-22.
[external/binutils.git] / gas / app.c
1 /* This is the Assembler Pre-Processor
2    Copyright 1987, 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998,
3    1999, 2000, 2002, 2003
4    Free Software Foundation, Inc.
5
6    This file is part of GAS, the GNU Assembler.
7
8    GAS is free software; you can redistribute it and/or modify
9    it under the terms of the GNU General Public License as published by
10    the Free Software Foundation; either version 2, or (at your option)
11    any later version.
12
13    GAS is distributed in the hope that it will be useful,
14    but WITHOUT ANY WARRANTY; without even the implied warranty of
15    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16    GNU General Public License for more details.
17
18    You should have received a copy of the GNU General Public License
19    along with GAS; see the file COPYING.  If not, write to the Free
20    Software Foundation, 59 Temple Place - Suite 330, Boston, MA
21    02111-1307, USA.  */
22
23 /* Modified by Allen Wirfs-Brock, Instantiations Inc 2/90.  */
24 /* App, the assembler pre-processor.  This pre-processor strips out excess
25    spaces, turns single-quoted characters into a decimal constant, and turns
26    # <number> <filename> <garbage> into a .line <number>\n.file <filename>
27    pair.  This needs better error-handling.  */
28
29 #include <stdio.h>
30 #include "as.h"                 /* For BAD_CASE() only.  */
31
32 #if (__STDC__ != 1)
33 #ifndef const
34 #define const  /* empty */
35 #endif
36 #endif
37
38 #ifdef TC_M68K
39 /* Whether we are scrubbing in m68k MRI mode.  This is different from
40    flag_m68k_mri, because the two flags will be affected by the .mri
41    pseudo-op at different times.  */
42 static int scrub_m68k_mri;
43
44 /* The pseudo-op which switches in and out of MRI mode.  See the
45    comment in do_scrub_chars.  */
46 static const char mri_pseudo[] = ".mri 0";
47 #else
48 #define scrub_m68k_mri 0
49 #endif
50
51 #if defined TC_ARM && defined OBJ_ELF
52 /* The pseudo-op for which we need to special-case `@' characters.
53    See the comment in do_scrub_chars.  */
54 static const char   symver_pseudo[] = ".symver";
55 static const char * symver_state;
56 #endif
57
58 static char lex[256];
59 static const char symbol_chars[] =
60 "$._ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
61
62 #define LEX_IS_SYMBOL_COMPONENT         1
63 #define LEX_IS_WHITESPACE               2
64 #define LEX_IS_LINE_SEPARATOR           3
65 #define LEX_IS_COMMENT_START            4
66 #define LEX_IS_LINE_COMMENT_START       5
67 #define LEX_IS_TWOCHAR_COMMENT_1ST      6
68 #define LEX_IS_STRINGQUOTE              8
69 #define LEX_IS_COLON                    9
70 #define LEX_IS_NEWLINE                  10
71 #define LEX_IS_ONECHAR_QUOTE            11
72 #ifdef TC_V850
73 #define LEX_IS_DOUBLEDASH_1ST           12
74 #endif
75 #ifdef TC_M32R
76 #define DOUBLEBAR_PARALLEL
77 #endif
78 #ifdef DOUBLEBAR_PARALLEL
79 #define LEX_IS_DOUBLEBAR_1ST            13
80 #endif
81 #define LEX_IS_PARALLEL_SEPARATOR       14
82 #define IS_SYMBOL_COMPONENT(c)          (lex[c] == LEX_IS_SYMBOL_COMPONENT)
83 #define IS_WHITESPACE(c)                (lex[c] == LEX_IS_WHITESPACE)
84 #define IS_LINE_SEPARATOR(c)            (lex[c] == LEX_IS_LINE_SEPARATOR)
85 #define IS_PARALLEL_SEPARATOR(c)        (lex[c] == LEX_IS_PARALLEL_SEPARATOR)
86 #define IS_COMMENT(c)                   (lex[c] == LEX_IS_COMMENT_START)
87 #define IS_LINE_COMMENT(c)              (lex[c] == LEX_IS_LINE_COMMENT_START)
88 #define IS_NEWLINE(c)                   (lex[c] == LEX_IS_NEWLINE)
89
90 static int process_escape (int);
91
92 /* FIXME-soon: The entire lexer/parser thingy should be
93    built statically at compile time rather than dynamically
94    each and every time the assembler is run.  xoxorich.  */
95
96 void
97 do_scrub_begin (int m68k_mri ATTRIBUTE_UNUSED)
98 {
99   const char *p;
100   int c;
101
102   lex[' '] = LEX_IS_WHITESPACE;
103   lex['\t'] = LEX_IS_WHITESPACE;
104   lex['\r'] = LEX_IS_WHITESPACE;
105   lex['\n'] = LEX_IS_NEWLINE;
106   lex[':'] = LEX_IS_COLON;
107
108 #ifdef TC_M68K
109   scrub_m68k_mri = m68k_mri;
110
111   if (! m68k_mri)
112 #endif
113     {
114       lex['"'] = LEX_IS_STRINGQUOTE;
115
116 #if ! defined (TC_HPPA) && ! defined (TC_I370)
117       /* I370 uses single-quotes to delimit integer, float constants.  */
118       lex['\''] = LEX_IS_ONECHAR_QUOTE;
119 #endif
120
121 #ifdef SINGLE_QUOTE_STRINGS
122       lex['\''] = LEX_IS_STRINGQUOTE;
123 #endif
124     }
125
126   /* Note: if any other character can be LEX_IS_STRINGQUOTE, the loop
127      in state 5 of do_scrub_chars must be changed.  */
128
129   /* Note that these override the previous defaults, e.g. if ';' is a
130      comment char, then it isn't a line separator.  */
131   for (p = symbol_chars; *p; ++p)
132     lex[(unsigned char) *p] = LEX_IS_SYMBOL_COMPONENT;
133
134   for (c = 128; c < 256; ++c)
135     lex[c] = LEX_IS_SYMBOL_COMPONENT;
136
137 #ifdef tc_symbol_chars
138   /* This macro permits the processor to specify all characters which
139      may appears in an operand.  This will prevent the scrubber from
140      discarding meaningful whitespace in certain cases.  The i386
141      backend uses this to support prefixes, which can confuse the
142      scrubber as to whether it is parsing operands or opcodes.  */
143   for (p = tc_symbol_chars; *p; ++p)
144     lex[(unsigned char) *p] = LEX_IS_SYMBOL_COMPONENT;
145 #endif
146
147   /* The m68k backend wants to be able to change comment_chars.  */
148 #ifndef tc_comment_chars
149 #define tc_comment_chars comment_chars
150 #endif
151   for (p = tc_comment_chars; *p; p++)
152     lex[(unsigned char) *p] = LEX_IS_COMMENT_START;
153
154   for (p = line_comment_chars; *p; p++)
155     lex[(unsigned char) *p] = LEX_IS_LINE_COMMENT_START;
156
157   for (p = line_separator_chars; *p; p++)
158     lex[(unsigned char) *p] = LEX_IS_LINE_SEPARATOR;
159
160 #ifdef tc_parallel_separator_chars
161   /* This macro permits the processor to specify all characters which
162      separate parallel insns on the same line.  */
163   for (p = tc_parallel_separator_chars; *p; p++)
164     lex[(unsigned char) *p] = LEX_IS_PARALLEL_SEPARATOR;
165 #endif
166
167   /* Only allow slash-star comments if slash is not in use.
168      FIXME: This isn't right.  We should always permit them.  */
169   if (lex['/'] == 0)
170     lex['/'] = LEX_IS_TWOCHAR_COMMENT_1ST;
171
172 #ifdef TC_M68K
173   if (m68k_mri)
174     {
175       lex['\''] = LEX_IS_STRINGQUOTE;
176       lex[';'] = LEX_IS_COMMENT_START;
177       lex['*'] = LEX_IS_LINE_COMMENT_START;
178       /* The MRI documentation says '!' is LEX_IS_COMMENT_START, but
179          then it can't be used in an expression.  */
180       lex['!'] = LEX_IS_LINE_COMMENT_START;
181     }
182 #endif
183
184 #ifdef TC_V850
185   lex['-'] = LEX_IS_DOUBLEDASH_1ST;
186 #endif
187 #ifdef DOUBLEBAR_PARALLEL
188   lex['|'] = LEX_IS_DOUBLEBAR_1ST;
189 #endif
190 #ifdef TC_D30V
191   /* Must do this is we want VLIW instruction with "->" or "<-".  */
192   lex['-'] = LEX_IS_SYMBOL_COMPONENT;
193 #endif
194 }
195
196 /* Saved state of the scrubber.  */
197 static int state;
198 static int old_state;
199 static char *out_string;
200 static char out_buf[20];
201 static int add_newlines;
202 static char *saved_input;
203 static int saved_input_len;
204 static char input_buffer[32 * 1024];
205 static const char *mri_state;
206 static char mri_last_ch;
207
208 /* Data structure for saving the state of app across #include's.  Note that
209    app is called asynchronously to the parsing of the .include's, so our
210    state at the time .include is interpreted is completely unrelated.
211    That's why we have to save it all.  */
212
213 struct app_save
214 {
215   int          state;
216   int          old_state;
217   char *       out_string;
218   char         out_buf[sizeof (out_buf)];
219   int          add_newlines;
220   char *       saved_input;
221   int          saved_input_len;
222 #ifdef TC_M68K
223   int          scrub_m68k_mri;
224 #endif
225   const char * mri_state;
226   char         mri_last_ch;
227 #if defined TC_ARM && defined OBJ_ELF
228   const char * symver_state;
229 #endif
230 };
231
232 char *
233 app_push (void)
234 {
235   register struct app_save *saved;
236
237   saved = (struct app_save *) xmalloc (sizeof (*saved));
238   saved->state = state;
239   saved->old_state = old_state;
240   saved->out_string = out_string;
241   memcpy (saved->out_buf, out_buf, sizeof (out_buf));
242   saved->add_newlines = add_newlines;
243   if (saved_input == NULL)
244     saved->saved_input = NULL;
245   else
246     {
247       saved->saved_input = xmalloc (saved_input_len);
248       memcpy (saved->saved_input, saved_input, saved_input_len);
249       saved->saved_input_len = saved_input_len;
250     }
251 #ifdef TC_M68K
252   saved->scrub_m68k_mri = scrub_m68k_mri;
253 #endif
254   saved->mri_state = mri_state;
255   saved->mri_last_ch = mri_last_ch;
256 #if defined TC_ARM && defined OBJ_ELF
257   saved->symver_state = symver_state;
258 #endif
259
260   /* do_scrub_begin() is not useful, just wastes time.  */
261
262   state = 0;
263   saved_input = NULL;
264
265   return (char *) saved;
266 }
267
268 void
269 app_pop (char *arg)
270 {
271   register struct app_save *saved = (struct app_save *) arg;
272
273   /* There is no do_scrub_end ().  */
274   state = saved->state;
275   old_state = saved->old_state;
276   out_string = saved->out_string;
277   memcpy (out_buf, saved->out_buf, sizeof (out_buf));
278   add_newlines = saved->add_newlines;
279   if (saved->saved_input == NULL)
280     saved_input = NULL;
281   else
282     {
283       assert (saved->saved_input_len <= (int) (sizeof input_buffer));
284       memcpy (input_buffer, saved->saved_input, saved->saved_input_len);
285       saved_input = input_buffer;
286       saved_input_len = saved->saved_input_len;
287       free (saved->saved_input);
288     }
289 #ifdef TC_M68K
290   scrub_m68k_mri = saved->scrub_m68k_mri;
291 #endif
292   mri_state = saved->mri_state;
293   mri_last_ch = saved->mri_last_ch;
294 #if defined TC_ARM && defined OBJ_ELF
295   symver_state = saved->symver_state;
296 #endif
297
298   free (arg);
299 }
300
301 /* @@ This assumes that \n &c are the same on host and target.  This is not
302    necessarily true.  */
303
304 static int
305 process_escape (int ch)
306 {
307   switch (ch)
308     {
309     case 'b':
310       return '\b';
311     case 'f':
312       return '\f';
313     case 'n':
314       return '\n';
315     case 'r':
316       return '\r';
317     case 't':
318       return '\t';
319     case '\'':
320       return '\'';
321     case '"':
322       return '\"';
323     default:
324       return ch;
325     }
326 }
327
328 /* This function is called to process input characters.  The GET
329    parameter is used to retrieve more input characters.  GET should
330    set its parameter to point to a buffer, and return the length of
331    the buffer; it should return 0 at end of file.  The scrubbed output
332    characters are put into the buffer starting at TOSTART; the TOSTART
333    buffer is TOLEN bytes in length.  The function returns the number
334    of scrubbed characters put into TOSTART.  This will be TOLEN unless
335    end of file was seen.  This function is arranged as a state
336    machine, and saves its state so that it may return at any point.
337    This is the way the old code used to work.  */
338
339 int
340 do_scrub_chars (int (*get) (char *, int), char *tostart, int tolen)
341 {
342   char *to = tostart;
343   char *toend = tostart + tolen;
344   char *from;
345   char *fromend;
346   int fromlen;
347   register int ch, ch2 = 0;
348
349   /*State 0: beginning of normal line
350           1: After first whitespace on line (flush more white)
351           2: After first non-white (opcode) on line (keep 1white)
352           3: after second white on line (into operands) (flush white)
353           4: after putting out a .line, put out digits
354           5: parsing a string, then go to old-state
355           6: putting out \ escape in a "d string.
356           7: After putting out a .appfile, put out string.
357           8: After putting out a .appfile string, flush until newline.
358           9: After seeing symbol char in state 3 (keep 1white after symchar)
359          10: After seeing whitespace in state 9 (keep white before symchar)
360          11: After seeing a symbol character in state 0 (eg a label definition)
361          -1: output string in out_string and go to the state in old_state
362          -2: flush text until a '*' '/' is seen, then go to state old_state
363 #ifdef TC_V850
364          12: After seeing a dash, looking for a second dash as a start
365              of comment.
366 #endif
367 #ifdef DOUBLEBAR_PARALLEL
368          13: After seeing a vertical bar, looking for a second
369              vertical bar as a parallel expression separator.
370 #endif
371 #ifdef TC_IA64
372          14: After seeing a `(' at state 0, looking for a `)' as
373              predicate.
374          15: After seeing a `(' at state 1, looking for a `)' as
375              predicate.
376 #endif
377           */
378
379   /* I added states 9 and 10 because the MIPS ECOFF assembler uses
380      constructs like ``.loc 1 20''.  This was turning into ``.loc
381      120''.  States 9 and 10 ensure that a space is never dropped in
382      between characters which could appear in an identifier.  Ian
383      Taylor, ian@cygnus.com.
384
385      I added state 11 so that something like "Lfoo add %r25,%r26,%r27" works
386      correctly on the PA (and any other target where colons are optional).
387      Jeff Law, law@cs.utah.edu.
388
389      I added state 13 so that something like "cmp r1, r2 || trap #1" does not
390      get squashed into "cmp r1,r2||trap#1", with the all important space
391      between the 'trap' and the '#1' being eliminated.  nickc@cygnus.com  */
392
393   /* This macro gets the next input character.  */
394
395 #define GET()                                                   \
396   (from < fromend                                               \
397    ? * (unsigned char *) (from++)                               \
398    : (saved_input = NULL,                                       \
399       fromlen = (*get) (input_buffer, sizeof input_buffer),     \
400       from = input_buffer,                                      \
401       fromend = from + fromlen,                                 \
402       (fromlen == 0                                             \
403        ? EOF                                                    \
404        : * (unsigned char *) (from++))))
405
406   /* This macro pushes a character back on the input stream.  */
407
408 #define UNGET(uch) (*--from = (uch))
409
410   /* This macro puts a character into the output buffer.  If this
411      character fills the output buffer, this macro jumps to the label
412      TOFULL.  We use this rather ugly approach because we need to
413      handle two different termination conditions: EOF on the input
414      stream, and a full output buffer.  It would be simpler if we
415      always read in the entire input stream before processing it, but
416      I don't want to make such a significant change to the assembler's
417      memory usage.  */
418
419 #define PUT(pch)                                \
420   do                                            \
421     {                                           \
422       *to++ = (pch);                            \
423       if (to >= toend)                          \
424         goto tofull;                            \
425     }                                           \
426   while (0)
427
428   if (saved_input != NULL)
429     {
430       from = saved_input;
431       fromend = from + saved_input_len;
432     }
433   else
434     {
435       fromlen = (*get) (input_buffer, sizeof input_buffer);
436       if (fromlen == 0)
437         return 0;
438       from = input_buffer;
439       fromend = from + fromlen;
440     }
441
442   while (1)
443     {
444       /* The cases in this switch end with continue, in order to
445          branch back to the top of this while loop and generate the
446          next output character in the appropriate state.  */
447       switch (state)
448         {
449         case -1:
450           ch = *out_string++;
451           if (*out_string == '\0')
452             {
453               state = old_state;
454               old_state = 3;
455             }
456           PUT (ch);
457           continue;
458
459         case -2:
460           for (;;)
461             {
462               do
463                 {
464                   ch = GET ();
465
466                   if (ch == EOF)
467                     {
468                       as_warn (_("end of file in comment"));
469                       goto fromeof;
470                     }
471
472                   if (ch == '\n')
473                     PUT ('\n');
474                 }
475               while (ch != '*');
476
477               while ((ch = GET ()) == '*')
478                 ;
479
480               if (ch == EOF)
481                 {
482                   as_warn (_("end of file in comment"));
483                   goto fromeof;
484                 }
485
486               if (ch == '/')
487                 break;
488
489               UNGET (ch);
490             }
491
492           state = old_state;
493           UNGET (' ');
494           continue;
495
496         case 4:
497           ch = GET ();
498           if (ch == EOF)
499             goto fromeof;
500           else if (ch >= '0' && ch <= '9')
501             PUT (ch);
502           else
503             {
504               while (ch != EOF && IS_WHITESPACE (ch))
505                 ch = GET ();
506               if (ch == '"')
507                 {
508                   UNGET (ch);
509                   if (scrub_m68k_mri)
510                     out_string = "\n\tappfile ";
511                   else
512                     out_string = "\n\t.appfile ";
513                   old_state = 7;
514                   state = -1;
515                   PUT (*out_string++);
516                 }
517               else
518                 {
519                   while (ch != EOF && ch != '\n')
520                     ch = GET ();
521                   state = 0;
522                   PUT (ch);
523                 }
524             }
525           continue;
526
527         case 5:
528           /* We are going to copy everything up to a quote character,
529              with special handling for a backslash.  We try to
530              optimize the copying in the simple case without using the
531              GET and PUT macros.  */
532           {
533             char *s;
534             int len;
535
536             for (s = from; s < fromend; s++)
537               {
538                 ch = *s;
539                 /* This condition must be changed if the type of any
540                    other character can be LEX_IS_STRINGQUOTE.  */
541                 if (ch == '\\'
542                     || ch == '"'
543                     || ch == '\''
544                     || ch == '\n')
545                   break;
546               }
547             len = s - from;
548             if (len > toend - to)
549               len = toend - to;
550             if (len > 0)
551               {
552                 memcpy (to, from, len);
553                 to += len;
554                 from += len;
555               }
556           }
557
558           ch = GET ();
559           if (ch == EOF)
560             {
561               as_warn (_("end of file in string; inserted '\"'"));
562               state = old_state;
563               UNGET ('\n');
564               PUT ('"');
565             }
566           else if (lex[ch] == LEX_IS_STRINGQUOTE)
567             {
568               state = old_state;
569               PUT (ch);
570             }
571 #ifndef NO_STRING_ESCAPES
572           else if (ch == '\\')
573             {
574               state = 6;
575               PUT (ch);
576             }
577 #endif
578           else if (scrub_m68k_mri && ch == '\n')
579             {
580               /* Just quietly terminate the string.  This permits lines like
581                    bne  label   loop if we haven't reach end yet.  */
582               state = old_state;
583               UNGET (ch);
584               PUT ('\'');
585             }
586           else
587             {
588               PUT (ch);
589             }
590           continue;
591
592         case 6:
593           state = 5;
594           ch = GET ();
595           switch (ch)
596             {
597               /* Handle strings broken across lines, by turning '\n' into
598                  '\\' and 'n'.  */
599             case '\n':
600               UNGET ('n');
601               add_newlines++;
602               PUT ('\\');
603               continue;
604
605             case EOF:
606               as_warn (_("end of file in string; '\"' inserted"));
607               PUT ('"');
608               continue;
609
610             case '"':
611             case '\\':
612             case 'b':
613             case 'f':
614             case 'n':
615             case 'r':
616             case 't':
617             case 'v':
618             case 'x':
619             case 'X':
620             case '0':
621             case '1':
622             case '2':
623             case '3':
624             case '4':
625             case '5':
626             case '6':
627             case '7':
628               break;
629
630             default:
631 #ifdef ONLY_STANDARD_ESCAPES
632               as_warn (_("unknown escape '\\%c' in string; ignored"), ch);
633 #endif
634               break;
635             }
636           PUT (ch);
637           continue;
638
639         case 7:
640           ch = GET ();
641           state = 5;
642           old_state = 8;
643           if (ch == EOF)
644             goto fromeof;
645           PUT (ch);
646           continue;
647
648         case 8:
649           do
650             ch = GET ();
651           while (ch != '\n' && ch != EOF);
652           if (ch == EOF)
653             goto fromeof;
654           state = 0;
655           PUT (ch);
656           continue;
657
658 #ifdef DOUBLEBAR_PARALLEL
659         case 13:
660           ch = GET ();
661           if (ch != '|')
662             abort ();
663
664           /* Reset back to state 1 and pretend that we are parsing a
665              line from just after the first white space.  */
666           state = 1;
667           PUT ('|');
668           continue;
669 #endif
670         }
671
672       /* OK, we are somewhere in states 0 through 4 or 9 through 11.  */
673
674       /* flushchar: */
675       ch = GET ();
676
677 #ifdef TC_IA64
678       if (ch == '(' && (state == 0 || state == 1))
679         {
680           state += 14;
681           PUT (ch);
682           continue;
683         }
684       else if (state == 14 || state == 15)
685         {
686           if (ch == ')')
687             state -= 14;
688           else
689             {
690               PUT (ch);
691               continue;
692             }
693         }
694 #endif
695
696     recycle:
697
698 #if defined TC_ARM && defined OBJ_ELF
699       /* We need to watch out for .symver directives.  See the comment later
700          in this function.  */
701       if (symver_state == NULL)
702         {
703           if ((state == 0 || state == 1) && ch == symver_pseudo[0])
704             symver_state = symver_pseudo + 1;
705         }
706       else
707         {
708           /* We advance to the next state if we find the right
709              character.  */
710           if (ch != '\0' && (*symver_state == ch))
711             ++symver_state;
712           else if (*symver_state != '\0')
713             /* We did not get the expected character, or we didn't
714                get a valid terminating character after seeing the
715                entire pseudo-op, so we must go back to the beginning.  */
716             symver_state = NULL;
717           else
718             {
719               /* We've read the entire pseudo-op.  If this is the end
720                  of the line, go back to the beginning.  */
721               if (IS_NEWLINE (ch))
722                 symver_state = NULL;
723             }
724         }
725 #endif /* TC_ARM && OBJ_ELF */
726
727 #ifdef TC_M68K
728       /* We want to have pseudo-ops which control whether we are in
729          MRI mode or not.  Unfortunately, since m68k MRI mode affects
730          the scrubber, that means that we need a special purpose
731          recognizer here.  */
732       if (mri_state == NULL)
733         {
734           if ((state == 0 || state == 1)
735               && ch == mri_pseudo[0])
736             mri_state = mri_pseudo + 1;
737         }
738       else
739         {
740           /* We advance to the next state if we find the right
741              character, or if we need a space character and we get any
742              whitespace character, or if we need a '0' and we get a
743              '1' (this is so that we only need one state to handle
744              ``.mri 0'' and ``.mri 1'').  */
745           if (ch != '\0'
746               && (*mri_state == ch
747                   || (*mri_state == ' '
748                       && lex[ch] == LEX_IS_WHITESPACE)
749                   || (*mri_state == '0'
750                       && ch == '1')))
751             {
752               mri_last_ch = ch;
753               ++mri_state;
754             }
755           else if (*mri_state != '\0'
756                    || (lex[ch] != LEX_IS_WHITESPACE
757                        && lex[ch] != LEX_IS_NEWLINE))
758             {
759               /* We did not get the expected character, or we didn't
760                  get a valid terminating character after seeing the
761                  entire pseudo-op, so we must go back to the
762                  beginning.  */
763               mri_state = NULL;
764             }
765           else
766             {
767               /* We've read the entire pseudo-op.  mips_last_ch is
768                  either '0' or '1' indicating whether to enter or
769                  leave MRI mode.  */
770               do_scrub_begin (mri_last_ch == '1');
771               mri_state = NULL;
772
773               /* We continue handling the character as usual.  The
774                  main gas reader must also handle the .mri pseudo-op
775                  to control expression parsing and the like.  */
776             }
777         }
778 #endif
779
780       if (ch == EOF)
781         {
782           if (state != 0)
783             {
784               as_warn (_("end of file not at end of a line; newline inserted"));
785               state = 0;
786               PUT ('\n');
787             }
788           goto fromeof;
789         }
790
791       switch (lex[ch])
792         {
793         case LEX_IS_WHITESPACE:
794           do
795             {
796               ch = GET ();
797             }
798           while (ch != EOF && IS_WHITESPACE (ch));
799           if (ch == EOF)
800             goto fromeof;
801
802           if (state == 0)
803             {
804               /* Preserve a single whitespace character at the
805                  beginning of a line.  */
806               state = 1;
807               UNGET (ch);
808               PUT (' ');
809               break;
810             }
811
812 #ifdef KEEP_WHITE_AROUND_COLON
813           if (lex[ch] == LEX_IS_COLON)
814             {
815               /* Only keep this white if there's no white *after* the
816                  colon.  */
817               ch2 = GET ();
818               UNGET (ch2);
819               if (!IS_WHITESPACE (ch2))
820                 {
821                   state = 9;
822                   UNGET (ch);
823                   PUT (' ');
824                   break;
825                 }
826             }
827 #endif
828           if (IS_COMMENT (ch)
829               || ch == '/'
830               || IS_LINE_SEPARATOR (ch)
831               || IS_PARALLEL_SEPARATOR (ch))
832             {
833               if (scrub_m68k_mri)
834                 {
835                   /* In MRI mode, we keep these spaces.  */
836                   UNGET (ch);
837                   PUT (' ');
838                   break;
839                 }
840               goto recycle;
841             }
842
843           /* If we're in state 2 or 11, we've seen a non-white
844              character followed by whitespace.  If the next character
845              is ':', this is whitespace after a label name which we
846              normally must ignore.  In MRI mode, though, spaces are
847              not permitted between the label and the colon.  */
848           if ((state == 2 || state == 11)
849               && lex[ch] == LEX_IS_COLON
850               && ! scrub_m68k_mri)
851             {
852               state = 1;
853               PUT (ch);
854               break;
855             }
856
857           switch (state)
858             {
859             case 0:
860               state++;
861               goto recycle;     /* Punted leading sp */
862             case 1:
863               /* We can arrive here if we leave a leading whitespace
864                  character at the beginning of a line.  */
865               goto recycle;
866             case 2:
867               state = 3;
868               if (to + 1 < toend)
869                 {
870                   /* Optimize common case by skipping UNGET/GET.  */
871                   PUT (' ');    /* Sp after opco */
872                   goto recycle;
873                 }
874               UNGET (ch);
875               PUT (' ');
876               break;
877             case 3:
878               if (scrub_m68k_mri)
879                 {
880                   /* In MRI mode, we keep these spaces.  */
881                   UNGET (ch);
882                   PUT (' ');
883                   break;
884                 }
885               goto recycle;     /* Sp in operands */
886             case 9:
887             case 10:
888               if (scrub_m68k_mri)
889                 {
890                   /* In MRI mode, we keep these spaces.  */
891                   state = 3;
892                   UNGET (ch);
893                   PUT (' ');
894                   break;
895                 }
896               state = 10;       /* Sp after symbol char */
897               goto recycle;
898             case 11:
899               if (LABELS_WITHOUT_COLONS || flag_m68k_mri)
900                 state = 1;
901               else
902                 {
903                   /* We know that ch is not ':', since we tested that
904                      case above.  Therefore this is not a label, so it
905                      must be the opcode, and we've just seen the
906                      whitespace after it.  */
907                   state = 3;
908                 }
909               UNGET (ch);
910               PUT (' ');        /* Sp after label definition.  */
911               break;
912             default:
913               BAD_CASE (state);
914             }
915           break;
916
917         case LEX_IS_TWOCHAR_COMMENT_1ST:
918           ch2 = GET ();
919           if (ch2 == '*')
920             {
921               for (;;)
922                 {
923                   do
924                     {
925                       ch2 = GET ();
926                       if (ch2 != EOF && IS_NEWLINE (ch2))
927                         add_newlines++;
928                     }
929                   while (ch2 != EOF && ch2 != '*');
930
931                   while (ch2 == '*')
932                     ch2 = GET ();
933
934                   if (ch2 == EOF || ch2 == '/')
935                     break;
936
937                   /* This UNGET will ensure that we count newlines
938                      correctly.  */
939                   UNGET (ch2);
940                 }
941
942               if (ch2 == EOF)
943                 as_warn (_("end of file in multiline comment"));
944
945               ch = ' ';
946               goto recycle;
947             }
948 #ifdef DOUBLESLASH_LINE_COMMENTS
949           else if (ch2 == '/')
950             {
951               do
952                 {
953                   ch = GET ();
954                 }
955               while (ch != EOF && !IS_NEWLINE (ch));
956               if (ch == EOF)
957                 as_warn ("end of file in comment; newline inserted");
958               state = 0;
959               PUT ('\n');
960               break;
961             }
962 #endif
963           else
964             {
965               if (ch2 != EOF)
966                 UNGET (ch2);
967               if (state == 9 || state == 10)
968                 state = 3;
969               PUT (ch);
970             }
971           break;
972
973         case LEX_IS_STRINGQUOTE:
974           if (state == 10)
975             {
976               /* Preserve the whitespace in foo "bar".  */
977               UNGET (ch);
978               state = 3;
979               PUT (' ');
980
981               /* PUT didn't jump out.  We could just break, but we
982                  know what will happen, so optimize a bit.  */
983               ch = GET ();
984               old_state = 3;
985             }
986           else if (state == 9)
987             old_state = 3;
988           else
989             old_state = state;
990           state = 5;
991           PUT (ch);
992           break;
993
994 #ifndef IEEE_STYLE
995         case LEX_IS_ONECHAR_QUOTE:
996           if (state == 10)
997             {
998               /* Preserve the whitespace in foo 'b'.  */
999               UNGET (ch);
1000               state = 3;
1001               PUT (' ');
1002               break;
1003             }
1004           ch = GET ();
1005           if (ch == EOF)
1006             {
1007               as_warn (_("end of file after a one-character quote; \\0 inserted"));
1008               ch = 0;
1009             }
1010           if (ch == '\\')
1011             {
1012               ch = GET ();
1013               if (ch == EOF)
1014                 {
1015                   as_warn (_("end of file in escape character"));
1016                   ch = '\\';
1017                 }
1018               else
1019                 ch = process_escape (ch);
1020             }
1021           sprintf (out_buf, "%d", (int) (unsigned char) ch);
1022
1023           /* None of these 'x constants for us.  We want 'x'.  */
1024           if ((ch = GET ()) != '\'')
1025             {
1026 #ifdef REQUIRE_CHAR_CLOSE_QUOTE
1027               as_warn (_("missing close quote; (assumed)"));
1028 #else
1029               if (ch != EOF)
1030                 UNGET (ch);
1031 #endif
1032             }
1033           if (strlen (out_buf) == 1)
1034             {
1035               PUT (out_buf[0]);
1036               break;
1037             }
1038           if (state == 9)
1039             old_state = 3;
1040           else
1041             old_state = state;
1042           state = -1;
1043           out_string = out_buf;
1044           PUT (*out_string++);
1045           break;
1046 #endif
1047
1048         case LEX_IS_COLON:
1049 #ifdef KEEP_WHITE_AROUND_COLON
1050           state = 9;
1051 #else
1052           if (state == 9 || state == 10)
1053             state = 3;
1054           else if (state != 3)
1055             state = 1;
1056 #endif
1057           PUT (ch);
1058           break;
1059
1060         case LEX_IS_NEWLINE:
1061           /* Roll out a bunch of newlines from inside comments, etc.  */
1062           if (add_newlines)
1063             {
1064               --add_newlines;
1065               UNGET (ch);
1066             }
1067           /* Fall through.  */
1068
1069         case LEX_IS_LINE_SEPARATOR:
1070           state = 0;
1071           PUT (ch);
1072           break;
1073
1074         case LEX_IS_PARALLEL_SEPARATOR:
1075           state = 1;
1076           PUT (ch);
1077           break;
1078
1079 #ifdef TC_V850
1080         case LEX_IS_DOUBLEDASH_1ST:
1081           ch2 = GET ();
1082           if (ch2 != '-')
1083             {
1084               UNGET (ch2);
1085               goto de_fault;
1086             }
1087           /* Read and skip to end of line.  */
1088           do
1089             {
1090               ch = GET ();
1091             }
1092           while (ch != EOF && ch != '\n');
1093
1094           if (ch == EOF)
1095             as_warn (_("end of file in comment; newline inserted"));
1096
1097           state = 0;
1098           PUT ('\n');
1099           break;
1100 #endif
1101 #ifdef DOUBLEBAR_PARALLEL
1102         case LEX_IS_DOUBLEBAR_1ST:
1103           ch2 = GET ();
1104           UNGET (ch2);
1105           if (ch2 != '|')
1106             goto de_fault;
1107
1108           /* Handle '||' in two states as invoking PUT twice might
1109              result in the first one jumping out of this loop.  We'd
1110              then lose track of the state and one '|' char.  */
1111           state = 13;
1112           PUT ('|');
1113           break;
1114 #endif
1115         case LEX_IS_LINE_COMMENT_START:
1116           /* FIXME-someday: The two character comment stuff was badly
1117              thought out.  On i386, we want '/' as line comment start
1118              AND we want C style comments.  hence this hack.  The
1119              whole lexical process should be reworked.  xoxorich.  */
1120           if (ch == '/')
1121             {
1122               ch2 = GET ();
1123               if (ch2 == '*')
1124                 {
1125                   old_state = 3;
1126                   state = -2;
1127                   break;
1128                 }
1129               else
1130                 {
1131                   UNGET (ch2);
1132                 }
1133             }
1134
1135           if (state == 0 || state == 1) /* Only comment at start of line.  */
1136             {
1137               int startch;
1138
1139               startch = ch;
1140
1141               do
1142                 {
1143                   ch = GET ();
1144                 }
1145               while (ch != EOF && IS_WHITESPACE (ch));
1146
1147               if (ch == EOF)
1148                 {
1149                   as_warn (_("end of file in comment; newline inserted"));
1150                   PUT ('\n');
1151                   break;
1152                 }
1153
1154               if (ch < '0' || ch > '9' || state != 0 || startch != '#')
1155                 {
1156                   /* Not a cpp line.  */
1157                   while (ch != EOF && !IS_NEWLINE (ch))
1158                     ch = GET ();
1159                   if (ch == EOF)
1160                     as_warn (_("end of file in comment; newline inserted"));
1161                   state = 0;
1162                   PUT ('\n');
1163                   break;
1164                 }
1165               /* Looks like `# 123 "filename"' from cpp.  */
1166               UNGET (ch);
1167               old_state = 4;
1168               state = -1;
1169               if (scrub_m68k_mri)
1170                 out_string = "\tappline ";
1171               else
1172                 out_string = "\t.appline ";
1173               PUT (*out_string++);
1174               break;
1175             }
1176
1177 #ifdef TC_D10V
1178           /* All insns end in a char for which LEX_IS_SYMBOL_COMPONENT is true.
1179              Trap is the only short insn that has a first operand that is
1180              neither register nor label.
1181              We must prevent exef0f ||trap #1 to degenerate to exef0f ||trap#1 .
1182              We can't make '#' LEX_IS_SYMBOL_COMPONENT because it is
1183              already LEX_IS_LINE_COMMENT_START.  However, it is the
1184              only character in line_comment_chars for d10v, hence we
1185              can recognize it as such.  */
1186           /* An alternative approach would be to reset the state to 1 when
1187              we see '||', '<'- or '->', but that seems to be overkill.  */
1188           if (state == 10)
1189             PUT (' ');
1190 #endif
1191           /* We have a line comment character which is not at the
1192              start of a line.  If this is also a normal comment
1193              character, fall through.  Otherwise treat it as a default
1194              character.  */
1195           if (strchr (tc_comment_chars, ch) == NULL
1196               && (! scrub_m68k_mri
1197                   || (ch != '!' && ch != '*')))
1198             goto de_fault;
1199           if (scrub_m68k_mri
1200               && (ch == '!' || ch == '*' || ch == '#')
1201               && state != 1
1202               && state != 10)
1203             goto de_fault;
1204           /* Fall through.  */
1205         case LEX_IS_COMMENT_START:
1206 #if defined TC_ARM && defined OBJ_ELF
1207           /* On the ARM, `@' is the comment character.
1208              Unfortunately this is also a special character in ELF .symver
1209              directives (and .type, though we deal with those another way).
1210              So we check if this line is such a directive, and treat
1211              the character as default if so.  This is a hack.  */
1212           if ((symver_state != NULL) && (*symver_state == 0))
1213             goto de_fault;
1214 #endif
1215 #ifdef WARN_COMMENTS
1216           if (!found_comment)
1217             as_where (&found_comment_file, &found_comment);
1218 #endif
1219           do
1220             {
1221               ch = GET ();
1222             }
1223           while (ch != EOF && !IS_NEWLINE (ch));
1224           if (ch == EOF)
1225             as_warn (_("end of file in comment; newline inserted"));
1226           state = 0;
1227           PUT ('\n');
1228           break;
1229
1230         case LEX_IS_SYMBOL_COMPONENT:
1231           if (state == 10)
1232             {
1233               /* This is a symbol character following another symbol
1234                  character, with whitespace in between.  We skipped
1235                  the whitespace earlier, so output it now.  */
1236               UNGET (ch);
1237               state = 3;
1238               PUT (' ');
1239               break;
1240             }
1241
1242           if (state == 3)
1243             state = 9;
1244
1245           /* This is a common case.  Quickly copy CH and all the
1246              following symbol component or normal characters.  */
1247           if (to + 1 < toend
1248               && mri_state == NULL
1249 #if defined TC_ARM && defined OBJ_ELF
1250               && symver_state == NULL
1251 #endif
1252               )
1253             {
1254               char *s;
1255               int len;
1256
1257               for (s = from; s < fromend; s++)
1258                 {
1259                   int type;
1260
1261                   ch2 = *(unsigned char *) s;
1262                   type = lex[ch2];
1263                   if (type != 0
1264                       && type != LEX_IS_SYMBOL_COMPONENT)
1265                     break;
1266                 }
1267
1268               if (s > from)
1269                 /* Handle the last character normally, for
1270                    simplicity.  */
1271                 --s;
1272
1273               len = s - from;
1274
1275               if (len > (toend - to) - 1)
1276                 len = (toend - to) - 1;
1277
1278               if (len > 0)
1279                 {
1280                   PUT (ch);
1281                   if (len > 8)
1282                     {
1283                       memcpy (to, from, len);
1284                       to += len;
1285                       from += len;
1286                     }
1287                   else
1288                     {
1289                       switch (len)
1290                         {
1291                         case 8: *to++ = *from++;
1292                         case 7: *to++ = *from++;
1293                         case 6: *to++ = *from++;
1294                         case 5: *to++ = *from++;
1295                         case 4: *to++ = *from++;
1296                         case 3: *to++ = *from++;
1297                         case 2: *to++ = *from++;
1298                         case 1: *to++ = *from++;
1299                         }
1300                     }
1301                   ch = GET ();
1302                 }
1303             }
1304
1305           /* Fall through.  */
1306         default:
1307         de_fault:
1308           /* Some relatively `normal' character.  */
1309           if (state == 0)
1310             {
1311               state = 11;       /* Now seeing label definition.  */
1312             }
1313           else if (state == 1)
1314             {
1315               state = 2;        /* Ditto.  */
1316             }
1317           else if (state == 9)
1318             {
1319               if (!IS_SYMBOL_COMPONENT (ch))
1320                 state = 3;
1321             }
1322           else if (state == 10)
1323             {
1324               if (ch == '\\')
1325                 {
1326                   /* Special handling for backslash: a backslash may
1327                      be the beginning of a formal parameter (of a
1328                      macro) following another symbol character, with
1329                      whitespace in between.  If that is the case, we
1330                      output a space before the parameter.  Strictly
1331                      speaking, correct handling depends upon what the
1332                      macro parameter expands into; if the parameter
1333                      expands into something which does not start with
1334                      an operand character, then we don't want to keep
1335                      the space.  We don't have enough information to
1336                      make the right choice, so here we are making the
1337                      choice which is more likely to be correct.  */
1338                   PUT (' ');
1339                 }
1340
1341               state = 3;
1342             }
1343           PUT (ch);
1344           break;
1345         }
1346     }
1347
1348   /*NOTREACHED*/
1349
1350  fromeof:
1351   /* We have reached the end of the input.  */
1352   return to - tostart;
1353
1354  tofull:
1355   /* The output buffer is full.  Save any input we have not yet
1356      processed.  */
1357   if (fromend > from)
1358     {
1359       saved_input = from;
1360       saved_input_len = fromend - from;
1361     }
1362   else
1363     saved_input = NULL;
1364
1365   return to - tostart;
1366 }
1367