Coverage Report

Created: 2026-10-02 09:53

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/binutils-gdb/gas/app.c
Line
Count
Source
1
/* This is the Assembler Pre-Processor
2
   Copyright (C) 1987-2026 Free Software Foundation, Inc.
3
4
   This file is part of GAS, the GNU Assembler.
5
6
   GAS is free software; you can redistribute it and/or modify
7
   it under the terms of the GNU General Public License as published by
8
   the Free Software Foundation; either version 3, or (at your option)
9
   any later version.
10
11
   GAS is distributed in the hope that it will be useful, but WITHOUT
12
   ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
13
   or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public
14
   License for more details.
15
16
   You should have received a copy of the GNU General Public License
17
   along with GAS; see the file COPYING.  If not, write to the Free
18
   Software Foundation, 51 Franklin Street - Fifth Floor, Boston, MA
19
   02110-1301, USA.  */
20
21
/* Modified by Allen Wirfs-Brock, Instantiations Inc 2/90.  */
22
/* App, the assembler pre-processor.  This pre-processor strips out
23
   excess spaces, turns single-quoted characters into a decimal
24
   constant, and turns the # in # <number> <filename> <garbage> into a
25
   .linefile.  This needs better error-handling.  */
26
27
#include "as.h"
28
29
#if (__STDC__ != 1)
30
#ifndef const
31
#define const  /* empty */
32
#endif
33
#endif
34
35
#ifdef H_TICK_HEX
36
int enable_h_tick_hex = 0;
37
#endif
38
39
#ifdef TC_M68K
40
/* Whether we are scrubbing in m68k MRI mode.  This is different from
41
   flag_m68k_mri, because the two flags will be affected by the .mri
42
   pseudo-op at different times.  */
43
static int scrub_m68k_mri;
44
45
/* The pseudo-op which switches in and out of MRI mode.  See the
46
   comment in do_scrub_chars.  */
47
static const char mri_pseudo[] = ".mri 0";
48
static const char *mri_state;
49
static char mri_last_ch;
50
#else
51
242k
#define scrub_m68k_mri 0
52
#endif
53
54
#if defined TC_ARM && defined OBJ_ELF
55
/* The pseudo-op for which we need to special-case `@' characters.
56
   See the comment in do_scrub_chars.  */
57
static const char   symver_pseudo[] = ".symver";
58
static const char * symver_state;
59
#endif
60
61
/* The pseudo-op (without leading dot) at which we want to (perhaps just
62
   temporarily) stop processing.  See the comments in do_scrub_chars().  */
63
static const char   end_pseudo[] = "end ";
64
static const char * end_state;
65
66
/* Whether, considering the state at start of assembly, NO_PSEUDO_DOT is
67
   active.  */
68
static bool no_pseudo_dot;
69
70
static char last_char;
71
72
4.91M
#define LEX_IS_SYMBOL_COMPONENT   1
73
522k
#define LEX_IS_WHITESPACE   2
74
425k
#define LEX_IS_LINE_SEPARATOR   3
75
201k
#define LEX_IS_COMMENT_START    4
76
241k
#define LEX_IS_LINE_COMMENT_START 5
77
0
#define LEX_IS_TWOCHAR_COMMENT_1ST  6
78
95.4k
#define LEX_IS_STRINGQUOTE    8
79
329k
#define LEX_IS_COLON      9
80
596k
#define LEX_IS_NEWLINE      10
81
44.0k
#define LEX_IS_ONECHAR_QUOTE    11
82
#ifdef TC_V850
83
#define LEX_IS_DOUBLEDASH_1ST   12
84
#endif
85
#ifdef DOUBLEBAR_PARALLEL
86
#define LEX_IS_DOUBLEBAR_1ST    13
87
#endif
88
198k
#define LEX_IS_PARALLEL_SEPARATOR 14
89
#ifdef H_TICK_HEX
90
#define LEX_IS_H      15
91
#endif
92
254k
#define IS_SYMBOL_COMPONENT(c)    (lex[c] == LEX_IS_SYMBOL_COMPONENT)
93
272k
#define IS_WHITESPACE(c)    (lex[c] == LEX_IS_WHITESPACE)
94
417k
#define IS_LINE_SEPARATOR(c)    (lex[c] == LEX_IS_LINE_SEPARATOR)
95
198k
#define IS_PARALLEL_SEPARATOR(c)  (lex[c] == LEX_IS_PARALLEL_SEPARATOR)
96
400k
#define IS_COMMENT(c)     (lex[c] == LEX_IS_COMMENT_START)
97
400k
#define IS_LINE_COMMENT(c)    (lex[c] == LEX_IS_LINE_COMMENT_START)
98
#define IS_TWOCHAR_COMMENT_1ST(c) (lex[c] == LEX_IS_TWOCHAR_COMMENT_1ST)
99
643k
#define IS_NEWLINE(c)     (lex[c] == LEX_IS_NEWLINE)
100
101
static char lex[256] = {
102
  [' ']  = LEX_IS_WHITESPACE,
103
  ['\t'] = LEX_IS_WHITESPACE,
104
#ifdef CR_EOL
105
  ['\r'] = LEX_IS_LINE_SEPARATOR,
106
#else
107
  ['\r'] = LEX_IS_WHITESPACE,
108
#endif
109
  ['\n'] = LEX_IS_NEWLINE,
110
  [':'] = LEX_IS_COLON,
111
  ['$'] = LEX_IS_SYMBOL_COMPONENT,
112
  ['.'] = LEX_IS_SYMBOL_COMPONENT,
113
  ['_'] = LEX_IS_SYMBOL_COMPONENT,
114
  ['A'] = LEX_IS_SYMBOL_COMPONENT, ['a'] = LEX_IS_SYMBOL_COMPONENT,
115
  ['B'] = LEX_IS_SYMBOL_COMPONENT, ['b'] = LEX_IS_SYMBOL_COMPONENT,
116
  ['C'] = LEX_IS_SYMBOL_COMPONENT, ['c'] = LEX_IS_SYMBOL_COMPONENT,
117
  ['D'] = LEX_IS_SYMBOL_COMPONENT, ['d'] = LEX_IS_SYMBOL_COMPONENT,
118
  ['E'] = LEX_IS_SYMBOL_COMPONENT, ['e'] = LEX_IS_SYMBOL_COMPONENT,
119
  ['F'] = LEX_IS_SYMBOL_COMPONENT, ['f'] = LEX_IS_SYMBOL_COMPONENT,
120
  ['G'] = LEX_IS_SYMBOL_COMPONENT, ['g'] = LEX_IS_SYMBOL_COMPONENT,
121
  ['H'] = LEX_IS_SYMBOL_COMPONENT, ['h'] = LEX_IS_SYMBOL_COMPONENT,
122
  ['I'] = LEX_IS_SYMBOL_COMPONENT, ['i'] = LEX_IS_SYMBOL_COMPONENT,
123
  ['J'] = LEX_IS_SYMBOL_COMPONENT, ['j'] = LEX_IS_SYMBOL_COMPONENT,
124
  ['K'] = LEX_IS_SYMBOL_COMPONENT, ['k'] = LEX_IS_SYMBOL_COMPONENT,
125
  ['L'] = LEX_IS_SYMBOL_COMPONENT, ['l'] = LEX_IS_SYMBOL_COMPONENT,
126
  ['M'] = LEX_IS_SYMBOL_COMPONENT, ['m'] = LEX_IS_SYMBOL_COMPONENT,
127
  ['N'] = LEX_IS_SYMBOL_COMPONENT, ['n'] = LEX_IS_SYMBOL_COMPONENT,
128
  ['O'] = LEX_IS_SYMBOL_COMPONENT, ['o'] = LEX_IS_SYMBOL_COMPONENT,
129
  ['P'] = LEX_IS_SYMBOL_COMPONENT, ['p'] = LEX_IS_SYMBOL_COMPONENT,
130
  ['Q'] = LEX_IS_SYMBOL_COMPONENT, ['q'] = LEX_IS_SYMBOL_COMPONENT,
131
  ['R'] = LEX_IS_SYMBOL_COMPONENT, ['r'] = LEX_IS_SYMBOL_COMPONENT,
132
  ['S'] = LEX_IS_SYMBOL_COMPONENT, ['s'] = LEX_IS_SYMBOL_COMPONENT,
133
  ['T'] = LEX_IS_SYMBOL_COMPONENT, ['t'] = LEX_IS_SYMBOL_COMPONENT,
134
  ['U'] = LEX_IS_SYMBOL_COMPONENT, ['u'] = LEX_IS_SYMBOL_COMPONENT,
135
  ['V'] = LEX_IS_SYMBOL_COMPONENT, ['v'] = LEX_IS_SYMBOL_COMPONENT,
136
  ['W'] = LEX_IS_SYMBOL_COMPONENT, ['w'] = LEX_IS_SYMBOL_COMPONENT,
137
  ['X'] = LEX_IS_SYMBOL_COMPONENT, ['x'] = LEX_IS_SYMBOL_COMPONENT,
138
  ['Y'] = LEX_IS_SYMBOL_COMPONENT, ['y'] = LEX_IS_SYMBOL_COMPONENT,
139
  ['Z'] = LEX_IS_SYMBOL_COMPONENT, ['z'] = LEX_IS_SYMBOL_COMPONENT,
140
  ['0'] = LEX_IS_SYMBOL_COMPONENT,
141
  ['1'] = LEX_IS_SYMBOL_COMPONENT,
142
  ['2'] = LEX_IS_SYMBOL_COMPONENT,
143
  ['3'] = LEX_IS_SYMBOL_COMPONENT,
144
  ['4'] = LEX_IS_SYMBOL_COMPONENT,
145
  ['5'] = LEX_IS_SYMBOL_COMPONENT,
146
  ['6'] = LEX_IS_SYMBOL_COMPONENT,
147
  ['7'] = LEX_IS_SYMBOL_COMPONENT,
148
  ['8'] = LEX_IS_SYMBOL_COMPONENT,
149
  ['9'] = LEX_IS_SYMBOL_COMPONENT,
150
#define INIT2(n) [n] = LEX_IS_SYMBOL_COMPONENT, \
151
     [(n) + 1] = LEX_IS_SYMBOL_COMPONENT
152
#define INIT4(n)    INIT2 (n),  INIT2 ((n) +  2)
153
#define INIT8(n)    INIT4 (n),  INIT4 ((n) +  4)
154
#define INIT16(n)   INIT8 (n),  INIT8 ((n) +  8)
155
#define INIT32(n)  INIT16 (n), INIT16 ((n) + 16)
156
#define INIT64(n)  INIT32 (n), INIT32 ((n) + 32)
157
#define INIT128(n) INIT64 (n), INIT64 ((n) + 64)
158
  INIT128 (128),
159
#undef INIT128
160
#undef INIT64
161
#undef INIT32
162
#undef INIT16
163
#undef INIT8
164
#undef INIT4
165
#undef INIT2
166
};
167
168
void
169
do_scrub_begin (int m68k_mri ATTRIBUTE_UNUSED)
170
281
{
171
281
  const char *p;
172
173
  /* Latch this once at start.  xtensa uses a hook function, yet context isn't
174
     meaningful for scrubbing (or else we'd need to sync scrubber behavior as
175
     state changes).  */
176
281
  if (lex['/'] == 0)
177
1
    no_pseudo_dot = NO_PSEUDO_DOT;
178
179
#ifdef TC_M68K
180
  scrub_m68k_mri = m68k_mri;
181
182
  if (! m68k_mri)
183
#endif
184
281
    {
185
281
      lex['"'] = LEX_IS_STRINGQUOTE;
186
187
281
#if ! defined (TC_HPPA)
188
281
      lex['\''] = LEX_IS_ONECHAR_QUOTE;
189
281
#endif
190
191
#ifdef SINGLE_QUOTE_STRINGS
192
      lex['\''] = LEX_IS_STRINGQUOTE;
193
#endif
194
281
    }
195
196
  /* Note: if any other character can be LEX_IS_STRINGQUOTE, the loop
197
     in state 5 of do_scrub_chars must be changed.  */
198
199
  /* Note that these override the previous defaults, e.g. if ';' is a
200
     comment char, then it isn't a line separator.  */
201
202
281
#ifdef tc_symbol_chars
203
  /* This macro permits the processor to specify all characters which
204
     may appears in an operand.  This will prevent the scrubber from
205
     discarding meaningful whitespace in certain cases.  The i386
206
     backend uses this to support prefixes, which can confuse the
207
     scrubber as to whether it is parsing operands or opcodes.  */
208
1.68k
  for (p = tc_symbol_chars; *p; ++p)
209
1.40k
    lex[(unsigned char) *p] = LEX_IS_SYMBOL_COMPONENT;
210
281
#endif
211
212
  /* The m68k backend wants to be able to change comment_chars.  */
213
#ifndef tc_comment_chars
214
#define tc_comment_chars comment_chars
215
#endif
216
562
  for (p = tc_comment_chars; *p; p++)
217
281
    lex[(unsigned char) *p] = LEX_IS_COMMENT_START;
218
219
  /* While counter intuitive to have more special purpose line comment chars
220
     override more general purpose ordinary ones, logic in do_scrub_chars()
221
     depends on this ordering.   */
222
843
  for (p = line_comment_chars; *p; p++)
223
562
    lex[(unsigned char) *p] = LEX_IS_LINE_COMMENT_START;
224
225
281
#ifndef tc_line_separator_chars
226
281
#define tc_line_separator_chars line_separator_chars
227
281
#endif
228
562
  for (p = tc_line_separator_chars; *p; p++)
229
281
    lex[(unsigned char) *p] = LEX_IS_LINE_SEPARATOR;
230
231
#ifdef tc_parallel_separator_chars
232
  /* This macro permits the processor to specify all characters which
233
     separate parallel insns on the same line.  */
234
  for (p = tc_parallel_separator_chars; *p; p++)
235
    lex[(unsigned char) *p] = LEX_IS_PARALLEL_SEPARATOR;
236
#endif
237
238
  /* Only allow slash-star comments if slash is not in use.  Certain
239
     other cases are dealt with in LEX_IS_LINE_COMMENT_START handling.
240
     FIXME: This isn't right.  We should always permit them.  */
241
281
  if (lex['/'] == 0)
242
0
    lex['/'] = LEX_IS_TWOCHAR_COMMENT_1ST;
243
244
#ifdef TC_M68K
245
  if (m68k_mri)
246
    {
247
      lex['\''] = LEX_IS_STRINGQUOTE;
248
      lex[';'] = LEX_IS_COMMENT_START;
249
      lex['*'] = LEX_IS_LINE_COMMENT_START;
250
      /* The MRI documentation says '!' is LEX_IS_COMMENT_START, but
251
   then it can't be used in an expression.  */
252
      lex['!'] = LEX_IS_LINE_COMMENT_START;
253
    }
254
#endif
255
256
#ifdef TC_V850
257
  lex['-'] = LEX_IS_DOUBLEDASH_1ST;
258
#endif
259
#ifdef DOUBLEBAR_PARALLEL
260
  lex['|'] = LEX_IS_DOUBLEBAR_1ST;
261
#endif
262
263
#ifdef H_TICK_HEX
264
  if (enable_h_tick_hex)
265
    {
266
      lex['h'] = LEX_IS_H;
267
      lex['H'] = LEX_IS_H;
268
    }
269
#endif
270
281
}
271
272
/* Saved state of the scrubber.  */
273
static int state;
274
static int old_state;
275
static const char *out_string;
276
static char out_buf[20];
277
static int add_newlines;
278
static char *saved_input;
279
static size_t saved_input_len;
280
static char input_buffer[32 * 1024];
281
282
/* Data structure for saving the state of app across #include's.  Note that
283
   app is called asynchronously to the parsing of the .include's, so our
284
   state at the time .include is interpreted is completely unrelated.
285
   That's why we have to save it all.  */
286
287
struct app_save
288
{
289
  int          state;
290
  int          old_state;
291
  const char * out_string;
292
  char         out_buf[sizeof (out_buf)];
293
  int          add_newlines;
294
  char *       saved_input;
295
  size_t       saved_input_len;
296
  const char * end_state;
297
#ifdef TC_M68K
298
  int          scrub_m68k_mri;
299
  const char * mri_state;
300
  char         mri_last_ch;
301
#endif
302
#if defined TC_ARM && defined OBJ_ELF
303
  const char * symver_state;
304
#endif
305
  char         last_char;
306
};
307
308
char *
309
app_push (void)
310
821
{
311
821
  struct app_save *saved;
312
313
821
  saved = XNEW (struct app_save);
314
821
  saved->state = state;
315
821
  saved->old_state = old_state;
316
821
  saved->out_string = out_string;
317
821
  memcpy (saved->out_buf, out_buf, sizeof (out_buf));
318
821
  saved->add_newlines = add_newlines;
319
821
  if (saved_input == NULL)
320
819
    saved->saved_input = NULL;
321
2
  else
322
2
    {
323
2
      saved->saved_input = XNEWVEC (char, saved_input_len);
324
2
      memcpy (saved->saved_input, saved_input, saved_input_len);
325
2
      saved->saved_input_len = saved_input_len;
326
2
    }
327
821
  saved->end_state = end_state;
328
#ifdef TC_M68K
329
  saved->scrub_m68k_mri = scrub_m68k_mri;
330
  saved->mri_state = mri_state;
331
  saved->mri_last_ch = mri_last_ch;
332
#endif
333
#if defined TC_ARM && defined OBJ_ELF
334
  saved->symver_state = symver_state;
335
#endif
336
821
  saved->last_char = last_char;
337
338
  /* do_scrub_begin() is not useful, just wastes time.  */
339
340
821
  state = 0;
341
821
  saved_input = NULL;
342
821
  add_newlines = 0;
343
344
821
  return (char *) saved;
345
821
}
346
347
void
348
app_pop (char *arg)
349
821
{
350
821
  struct app_save *saved = (struct app_save *) arg;
351
352
  /* There is no do_scrub_end ().  */
353
821
  state = saved->state;
354
821
  old_state = saved->old_state;
355
821
  out_string = saved->out_string;
356
821
  memcpy (out_buf, saved->out_buf, sizeof (out_buf));
357
821
  add_newlines = saved->add_newlines;
358
821
  if (saved->saved_input == NULL)
359
819
    saved_input = NULL;
360
2
  else
361
2
    {
362
2
      gas_assert (saved->saved_input_len <= sizeof (input_buffer));
363
2
      memcpy (input_buffer, saved->saved_input, saved->saved_input_len);
364
2
      saved_input = input_buffer;
365
2
      saved_input_len = saved->saved_input_len;
366
2
      free (saved->saved_input);
367
2
    }
368
821
  end_state = saved->end_state;
369
#ifdef TC_M68K
370
  scrub_m68k_mri = saved->scrub_m68k_mri;
371
  mri_state = saved->mri_state;
372
  mri_last_ch = saved->mri_last_ch;
373
#endif
374
#if defined TC_ARM && defined OBJ_ELF
375
  symver_state = saved->symver_state;
376
#endif
377
821
  last_char = saved->last_char;
378
379
821
  free (arg);
380
821
}
381
382
/* @@ This assumes that \n &c are the same on host and target.  This is not
383
   necessarily true.  */
384
385
static int
386
process_escape (int ch)
387
1.42k
{
388
1.42k
  switch (ch)
389
1.42k
    {
390
0
    case 'b':
391
0
      return '\b';
392
0
    case 'f':
393
0
      return '\f';
394
0
    case 'n':
395
0
      return '\n';
396
0
    case 'r':
397
0
      return '\r';
398
0
    case 't':
399
0
      return '\t';
400
0
    case '\'':
401
0
      return '\'';
402
1
    case '"':
403
1
      return '\"';
404
1.42k
    default:
405
1.42k
      return ch;
406
1.42k
    }
407
1.42k
}
408
409
0
#define MULTIBYTE_WARN_COUNT_LIMIT 10
410
static unsigned int multibyte_warn_count = 0;
411
412
bool
413
scan_for_multibyte_characters (const unsigned char *  start,
414
             const unsigned char *  end,
415
             bool                   warn)
416
0
{
417
0
  if (end <= start)
418
0
    return false;
419
420
0
  if (warn && multibyte_warn_count > MULTIBYTE_WARN_COUNT_LIMIT)
421
0
    return false;
422
423
0
  bool found = false;
424
425
0
  while (start < end)
426
0
    {
427
0
      unsigned char c;
428
429
0
      if ((c = * start++) <= 0x7f)
430
0
  continue;
431
432
0
      if (!warn)
433
0
  return true;
434
435
0
      found = true;
436
437
0
      const char * filename;
438
0
      unsigned int lineno;
439
440
0
      filename = as_where (& lineno);
441
0
      if (filename == NULL)
442
0
  as_warn (_("multibyte character (%#x) encountered in input"), c);
443
0
      else if (lineno == 0)
444
0
  as_warn (_("multibyte character (%#x) encountered in %s"), c, filename);
445
0
      else
446
0
  as_warn (_("multibyte character (%#x) encountered in %s at or near line %u"), c, filename, lineno);
447
448
0
      if (++ multibyte_warn_count == MULTIBYTE_WARN_COUNT_LIMIT)
449
0
  {
450
0
    as_warn (_("further multibyte character warnings suppressed"));
451
0
    break;
452
0
  }
453
0
    }
454
455
0
  return found;
456
0
}
457
458
/* This function is called to process input characters.  The GET
459
   parameter is used to retrieve more input characters.  GET should
460
   set its parameter to point to a buffer, and return the length of
461
   the buffer; it should return 0 at end of file.  The scrubbed output
462
   characters are put into the buffer starting at TOSTART; the TOSTART
463
   buffer is TOLEN bytes in length.  The function returns the number
464
   of scrubbed characters put into TOSTART.  This will be TOLEN unless
465
   end of file was seen.  This function is arranged as a state
466
   machine, and saves its state so that it may return at any point.
467
   This is the way the old code used to work.  */
468
469
size_t
470
do_scrub_chars (size_t (*get) (char *, size_t), char *tostart, size_t tolen,
471
    bool check_multibyte)
472
1.92k
{
473
1.92k
  char *to = tostart;
474
1.92k
  char *toend = tostart + tolen;
475
1.92k
  char *from;
476
1.92k
  char *fromend;
477
1.92k
  size_t fromlen;
478
1.92k
  int ch, ch2 = 0;
479
  /* Character that started the string we're working on.  */
480
1.92k
  static char quotechar;
481
482
  /*State 0: beginning of normal line
483
    1: After first whitespace on line (flush more white)
484
    2: After first non-white (opcode) on line (keep 1white)
485
    3: after second white on line (into operands) (flush white)
486
    4: after putting out a .linefile, put out digits
487
    5: parsing a string, then go to old-state
488
    6: putting out \ escape in a "d string.
489
    7: no longer used
490
    8: no longer used
491
    9: After seeing symbol char in state 3 (keep 1white after symchar)
492
   10: After seeing whitespace in state 9 (keep white before symchar)
493
   11: After seeing a symbol character in state 0 (eg a label definition)
494
   -1: output string in out_string and go to the state in old_state
495
   12: no longer used
496
#ifdef DOUBLEBAR_PARALLEL
497
   13: After seeing a vertical bar, looking for a second
498
       vertical bar as a parallel expression separator.
499
#endif
500
#ifdef TC_PREDICATE_START_CHAR
501
   14: After seeing a predicate start character at state 0, looking
502
       for a predicate end character as predicate.
503
   15: After seeing a predicate start character at state 1, looking
504
       for a predicate end character as predicate.
505
#endif
506
#ifdef TC_Z80
507
   16: After seeing an 'a' or an 'A' at the start of a symbol
508
   17: After seeing an 'f' or an 'F' in state 16
509
#endif
510
    */
511
512
  /* I added states 9 and 10 because the MIPS ECOFF assembler uses
513
     constructs like ``.loc 1 20''.  This was turning into ``.loc
514
     120''.  States 9 and 10 ensure that a space is never dropped in
515
     between characters which could appear in an identifier.  Ian
516
     Taylor, ian@cygnus.com.
517
518
     I added state 11 so that something like "Lfoo add %r25,%r26,%r27" works
519
     correctly on the PA (and any other target where colons are optional).
520
     Jeff Law, law@cs.utah.edu.
521
522
     I added state 13 so that something like "cmp r1, r2 || trap #1" does not
523
     get squashed into "cmp r1,r2||trap#1", with the all important space
524
     between the 'trap' and the '#1' being eliminated.  nickc@cygnus.com  */
525
526
  /* This macro gets the next input character.  */
527
528
1.92k
#define GET()             \
529
2.45M
  (from < fromend            \
530
2.45M
   ? * (unsigned char *) (from++)        \
531
2.45M
   : (saved_input = NULL,          \
532
1.40k
      fromlen = (*get) (input_buffer, sizeof input_buffer), \
533
1.40k
      from = input_buffer,          \
534
1.40k
      fromend = from + fromlen,         \
535
1.40k
      (fromlen == 0            \
536
1.40k
       ? EOF              \
537
1.40k
       : * (unsigned char *) (from++))))
538
539
  /* This macro pushes a character back on the input stream.  */
540
541
253k
#define UNGET(uch) (*--from = (uch))
542
543
  /* This macro puts a character into the output buffer.  If this
544
     character fills the output buffer, this macro jumps to the label
545
     TOFULL.  We use this rather ugly approach because we need to
546
     handle two different termination conditions: EOF on the input
547
     stream, and a full output buffer.  It would be simpler if we
548
     always read in the entire input stream before processing it, but
549
     I don't want to make such a significant change to the assembler's
550
     memory usage.  */
551
552
1.92k
#define PUT(pch)        \
553
1.96M
  do            \
554
1.96M
    {           \
555
1.96M
      *to++ = (pch);        \
556
1.96M
      if (to >= toend)       \
557
1.96M
  goto tofull;       \
558
1.96M
    }           \
559
1.96M
  while (0)
560
561
1.92k
  if (saved_input != NULL)
562
649
    {
563
649
      from = saved_input;
564
649
      fromend = from + saved_input_len;
565
649
    }
566
1.27k
  else
567
1.27k
    {
568
1.27k
      fromlen = (*get) (input_buffer, sizeof input_buffer);
569
1.27k
      if (fromlen == 0)
570
281
  return 0;
571
992
      from = input_buffer;
572
992
      fromend = from + fromlen;
573
574
992
      if (check_multibyte)
575
0
  (void) scan_for_multibyte_characters ((const unsigned char *) from,
576
0
                (const unsigned char *) fromend,
577
0
                true /* Generate warnings.  */);
578
992
    }
579
580
1.52M
  while (1)
581
1.52M
    {
582
      /* The cases in this switch end with continue, in order to
583
   branch back to the top of this while loop and generate the
584
   next output character in the appropriate state.  */
585
1.52M
      switch (state)
586
1.52M
  {
587
68.9k
  case -1:
588
68.9k
    ch = *out_string++;
589
68.9k
    if (*out_string == '\0')
590
42.2k
      {
591
42.2k
        state = old_state;
592
42.2k
        old_state = 3;
593
42.2k
      }
594
68.9k
    PUT (ch);
595
68.9k
    continue;
596
597
68.9k
  case 4:
598
1.62k
    ch = GET ();
599
1.62k
    if (ch == EOF)
600
0
      goto fromeof;
601
1.62k
    else if (ch >= '0' && ch <= '9')
602
818
      PUT (ch);
603
803
    else
604
803
      {
605
803
        while (ch != EOF && IS_WHITESPACE (ch))
606
0
    ch = GET ();
607
803
        if (ch == '"')
608
797
    {
609
797
      quotechar = ch;
610
797
      state = 5;
611
797
      old_state = 3;
612
797
      PUT (ch);
613
797
    }
614
6
        else
615
6
    {
616
247
      while (ch != EOF && ch != '\n')
617
241
        ch = GET ();
618
6
      state = 0;
619
6
      PUT (ch);
620
6
    }
621
803
      }
622
1.62k
    continue;
623
624
181k
  case 5:
625
    /* We are going to copy everything up to a quote character,
626
       with special handling for a backslash.  We try to
627
       optimize the copying in the simple case without using the
628
       GET and PUT macros.  */
629
181k
    {
630
181k
      char *s;
631
181k
      ptrdiff_t len;
632
633
3.13M
      for (s = from; s < fromend; s++)
634
3.13M
        {
635
3.13M
    ch = *s;
636
3.13M
    if (ch == '\\'
637
3.12M
        || ch == quotechar
638
3.03M
        || ch == '\n')
639
181k
      break;
640
3.13M
        }
641
181k
      len = s - from;
642
181k
      if (len > toend - to)
643
0
        len = toend - to;
644
181k
      if (len > 0)
645
162k
        {
646
162k
    memcpy (to, from, len);
647
162k
    to += len;
648
162k
    from += len;
649
162k
    if (to >= toend)
650
0
      goto tofull;
651
162k
        }
652
181k
    }
653
654
181k
    ch = GET ();
655
181k
    if (ch == EOF)
656
293
      {
657
        /* This buffer is here specifically so
658
     that the UNGET below will work.  */
659
293
        static char one_char_buf[1];
660
661
293
        as_warn (_("end of file in string; '%c' inserted"), quotechar);
662
293
        state = old_state;
663
293
        from = fromend = one_char_buf + 1;
664
293
        fromlen = 1;
665
293
        UNGET ('\n');
666
293
        PUT (quotechar);
667
293
      }
668
181k
    else if (ch == quotechar)
669
95.7k
      {
670
95.7k
        state = old_state;
671
95.7k
        PUT (ch);
672
95.7k
      }
673
85.6k
    else if (TC_STRING_ESCAPES && ch == '\\')
674
6.27k
      {
675
6.27k
        state = 6;
676
6.27k
        PUT (ch);
677
6.27k
      }
678
79.4k
    else if (scrub_m68k_mri && ch == '\n')
679
0
      {
680
        /* Just quietly terminate the string.  This permits lines like
681
       bne  label loop if we haven't reach end yet.  */
682
0
        state = old_state;
683
0
        UNGET (ch);
684
0
        PUT ('\'');
685
0
      }
686
79.4k
    else
687
79.4k
      {
688
79.4k
        PUT (ch);
689
79.4k
      }
690
181k
    continue;
691
692
181k
  case 6:
693
6.27k
    state = 5;
694
6.27k
    ch = GET ();
695
6.27k
    switch (ch)
696
6.27k
      {
697
        /* Handle strings broken across lines, by turning '\\' followed
698
     by '\n' into '\\' (already emitted when state moved to 6) and
699
     'n'.  */
700
33
      case '\n':
701
33
        add_newlines++;
702
33
        PUT ('n');
703
33
        continue;
704
705
33
      case EOF:
706
0
        as_warn (_("end of file in string; '%c' inserted"), quotechar);
707
0
        PUT (quotechar);
708
0
        continue;
709
710
6.24k
      default:
711
6.24k
        break;
712
6.27k
      }
713
6.24k
    PUT (ch);
714
6.24k
    continue;
715
716
#ifdef DOUBLEBAR_PARALLEL
717
  case 13:
718
    ch = GET ();
719
    if (ch != '|')
720
      abort ();
721
722
    /* Reset back to state 1 and pretend that we are parsing a
723
       line from just after the first white space.  */
724
    state = 1;
725
    PUT ('|');
726
    continue;
727
#endif
728
#ifdef TC_Z80
729
  case 16:
730
    /* We have seen an 'a' at the start of a symbol, look for an 'f'.  */
731
    ch = GET ();
732
    if (ch == 'f' || ch == 'F')
733
      {
734
        state = 17;
735
        PUT (ch);
736
      }
737
    else
738
      {
739
        if (ch != EOF)
740
    UNGET (ch);
741
        state = 9;
742
        break;
743
      }
744
    /* Fall through.  */
745
  case 17:
746
    /* We have seen "af" at the start of a symbol,
747
       a ' here is a part of that symbol.  */
748
    ch = GET ();
749
    state = 9;
750
    if (ch == '\'')
751
      /* Change to avoid warning about unclosed string.  */
752
      PUT ('`');
753
    else if (ch != EOF)
754
      UNGET (ch);
755
    break;
756
#endif
757
1.52M
  }
758
759
      /* OK, we are somewhere in states 0 through 4 or 9 through 11.  */
760
761
      /* flushchar: */
762
1.27M
      ch = GET ();
763
764
#ifdef TC_PREDICATE_START_CHAR
765
      if (ch == TC_PREDICATE_START_CHAR && (state == 0 || state == 1))
766
  {
767
    state += 14;
768
    PUT (ch);
769
    continue;
770
  }
771
      else if (state == 14 || state == 15)
772
  {
773
    if (ch == TC_PREDICATE_END_CHAR)
774
      {
775
        state -= 14;
776
        PUT (ch);
777
        ch = GET ();
778
      }
779
    else
780
      {
781
        PUT (ch);
782
        continue;
783
      }
784
  }
785
#endif
786
787
1.39M
    recycle:
788
789
      /* We need to watch out for .end directives: We should in particular not
790
   issue diagnostics for anything after an active one.  */
791
1.39M
      if (ch == EOF)
792
971
  end_state = NULL;
793
1.39M
      else if (end_state == NULL)
794
1.25M
  {
795
1.25M
    if ((state == 0 || state == 1)
796
276k
        && (ch == '.'
797
150k
      || (no_pseudo_dot && ch == end_pseudo[0])))
798
125k
      end_state = end_pseudo + (ch != '.');
799
1.25M
  }
800
143k
      else if (ch != '\0'
801
143k
         && (*end_state == ch
802
       /* Avoid triggering on directives like .endif or .endr.  */
803
137k
       || (*end_state == ' ' && !IS_SYMBOL_COMPONENT (ch))))
804
7.11k
  {
805
7.11k
    if (IS_NEWLINE (ch) || IS_LINE_SEPARATOR (ch))
806
18
      goto end_end;
807
7.09k
    ++end_state;
808
7.09k
  }
809
136k
      else if (*end_state != '\0')
810
  /* We did not get the expected character, or we didn't
811
     get a valid terminating character after seeing the
812
     entire pseudo-op, so we must go back to the beginning.  */
813
125k
  end_state = NULL;
814
11.3k
      else if (IS_NEWLINE (ch) || IS_LINE_SEPARATOR (ch))
815
474
  {
816
492
  end_end:
817
    /* We've read the entire pseudo-op.  If this is the end of the line,
818
       bail out now by (ab)using the output-full path.  This allows the
819
       caller to process input up to here and terminate processing if this
820
       directive is actually active (not on the false branch of a
821
       conditional and not in a macro definition).  */
822
492
    end_state = NULL;
823
492
    state = 0;
824
492
    PUT (ch);
825
492
    goto tofull;
826
492
  }
827
828
#if defined TC_ARM && defined OBJ_ELF
829
      /* We need to watch out for .symver directives.  See the comment later
830
   in this function.  */
831
      if (ch == EOF)
832
  symver_state = NULL;
833
      else if (symver_state == NULL)
834
  {
835
    if ((state == 0 || state == 1)
836
        && strchr (tc_comment_chars, '@') != NULL
837
        && ch == symver_pseudo[0])
838
      symver_state = symver_pseudo + 1;
839
  }
840
      else
841
  {
842
    /* We advance to the next state if we find the right
843
       character.  */
844
    if (ch != '\0' && (*symver_state == ch))
845
      ++symver_state;
846
    else if (*symver_state != '\0')
847
      /* We did not get the expected character, or we didn't
848
         get a valid terminating character after seeing the
849
         entire pseudo-op, so we must go back to the beginning.  */
850
      symver_state = NULL;
851
    else
852
      {
853
        /* We've read the entire pseudo-op.  If this is the end
854
     of the line, go back to the beginning.  */
855
        if (IS_NEWLINE (ch) || IS_LINE_SEPARATOR (ch))
856
    symver_state = NULL;
857
      }
858
  }
859
#endif /* TC_ARM && OBJ_ELF */
860
861
#ifdef TC_M68K
862
      /* We want to have pseudo-ops which control whether we are in
863
   MRI mode or not.  Unfortunately, since m68k MRI mode affects
864
   the scrubber, that means that we need a special purpose
865
   recognizer here.  */
866
      if (ch == EOF)
867
  mri_state = NULL;
868
      else if (mri_state == NULL)
869
  {
870
    if ((state == 0 || state == 1)
871
        && ch == mri_pseudo[0])
872
      mri_state = mri_pseudo + 1;
873
  }
874
      else
875
  {
876
    /* We advance to the next state if we find the right
877
       character, or if we need a space character and we get any
878
       whitespace character, or if we need a '0' and we get a
879
       '1' (this is so that we only need one state to handle
880
       ``.mri 0'' and ``.mri 1'').  */
881
    if (ch != '\0'
882
        && (*mri_state == ch
883
      || (*mri_state == ' '
884
          && IS_WHITESPACE (ch))
885
      || (*mri_state == '0'
886
          && ch == '1')))
887
      {
888
        mri_last_ch = ch;
889
        ++mri_state;
890
      }
891
    else if (*mri_state != '\0'
892
       || (!IS_WHITESPACE (ch)
893
           && !IS_LINE_SEPARATOR (ch)
894
           && !IS_NEWLINE (ch)))
895
      {
896
        /* We did not get the expected character, or we didn't
897
     get a valid terminating character after seeing the
898
     entire pseudo-op, so we must go back to the
899
     beginning.  */
900
        mri_state = NULL;
901
      }
902
    else
903
      {
904
        /* We've read the entire pseudo-op.  mri_last_ch is
905
     either '0' or '1' indicating whether to enter or
906
     leave MRI mode.  */
907
        do_scrub_begin (mri_last_ch == '1');
908
        mri_state = NULL;
909
910
        /* We continue handling the character as usual.  The
911
     main gas reader must also handle the .mri pseudo-op
912
     to control expression parsing and the like.  */
913
      }
914
  }
915
#endif
916
917
1.39M
      if (ch == EOF)
918
971
  {
919
971
    if (state != 0)
920
144
      {
921
144
        as_warn (_("end of file not at end of a line; newline inserted"));
922
144
        state = 0;
923
144
        PUT ('\n');
924
144
      }
925
971
    goto fromeof;
926
971
  }
927
928
1.39M
      switch (lex[ch])
929
1.39M
  {
930
249k
  case LEX_IS_WHITESPACE:
931
249k
    do
932
270k
      {
933
270k
        ch = GET ();
934
270k
      }
935
270k
    while (ch != EOF && IS_WHITESPACE (ch));
936
249k
    if (ch == EOF)
937
21
      goto fromeof;
938
939
249k
    if (state == 0)
940
49.2k
      {
941
        /* Preserve a single whitespace character at the
942
     beginning of a line.  */
943
49.2k
        state = 1;
944
49.2k
        UNGET (ch);
945
49.2k
        PUT (' ');
946
49.2k
        break;
947
49.2k
      }
948
949
#ifdef KEEP_WHITE_AROUND_COLON
950
    if (lex[ch] == LEX_IS_COLON)
951
      {
952
        /* Only keep this white if there's no white *after* the
953
     colon.  */
954
        ch2 = GET ();
955
        if (ch2 != EOF)
956
    UNGET (ch2);
957
        if (!IS_WHITESPACE (ch2))
958
    {
959
      state = 9;
960
      UNGET (ch);
961
      PUT (' ');
962
      break;
963
    }
964
      }
965
#endif
966
967
    /* Prune trailing whitespace.  */
968
200k
    if (IS_COMMENT (ch)
969
200k
        || (IS_LINE_COMMENT (ch)
970
2.67k
            && (state < 1 || strchr (tc_comment_chars, ch)))
971
200k
        || IS_NEWLINE (ch)
972
199k
        || IS_LINE_SEPARATOR (ch)
973
198k
        || IS_PARALLEL_SEPARATOR (ch))
974
1.94k
      {
975
1.94k
        if (scrub_m68k_mri)
976
0
    {
977
      /* In MRI mode, we keep these spaces.  */
978
0
      UNGET (ch);
979
0
      PUT (' ');
980
0
      break;
981
0
    }
982
1.94k
        goto recycle;
983
1.94k
      }
984
#ifdef DOUBLESLASH_LINE_COMMENTS
985
    if (IS_TWOCHAR_COMMENT_1ST (ch))
986
      {
987
        ch2 = GET ();
988
        if (ch2 != EOF)
989
          UNGET (ch2);
990
        if (ch2 == '/')
991
    goto recycle;
992
      }
993
#endif
994
995
    /* If we're in state 2 or 11, we've seen a non-white
996
       character followed by whitespace.  If the next character
997
       is ':', this is whitespace after a label name which we
998
       normally must ignore.  In MRI mode, though, spaces are
999
       not permitted between the label and the colon.  */
1000
198k
    if ((state == 2 || state == 11)
1001
118k
        && lex[ch] == LEX_IS_COLON
1002
0
        && ! scrub_m68k_mri)
1003
5.21k
      {
1004
5.21k
        state = 1;
1005
5.21k
        PUT (ch);
1006
5.21k
        break;
1007
5.21k
      }
1008
1009
193k
    switch (state)
1010
193k
      {
1011
1.15k
      case 1:
1012
        /* We can arrive here if we leave a leading whitespace
1013
     character at the beginning of a line.  */
1014
1.15k
        goto recycle;
1015
46.9k
      case 2:
1016
46.9k
        state = 3;
1017
46.9k
        if (to + 1 < toend)
1018
46.9k
    {
1019
      /* Optimize common case by skipping UNGET/GET.  */
1020
46.9k
      PUT (' '); /* Sp after opco */
1021
46.9k
      goto recycle;
1022
46.9k
    }
1023
0
        UNGET (ch);
1024
0
        PUT (' ');
1025
0
        break;
1026
8.80k
      case 3:
1027
8.80k
#ifndef TC_KEEP_OPERAND_SPACES
1028
        /* For TI C6X, we keep these spaces as they may separate
1029
     functional unit specifiers from operands.  */
1030
8.80k
        if (scrub_m68k_mri)
1031
0
#endif
1032
0
    {
1033
      /* In MRI mode, we keep these spaces.  */
1034
0
      UNGET (ch);
1035
0
      PUT (' ');
1036
0
      break;
1037
0
    }
1038
8.80k
        goto recycle; /* Sp in operands */
1039
70.0k
      case 9:
1040
70.0k
      case 10:
1041
70.0k
#ifndef TC_KEEP_OPERAND_SPACES
1042
70.0k
        if (scrub_m68k_mri)
1043
0
#endif
1044
0
    {
1045
      /* In MRI mode, we keep these spaces.  */
1046
0
      state = 3;
1047
0
      UNGET (ch);
1048
0
      PUT (' ');
1049
0
      break;
1050
0
    }
1051
70.0k
        state = 10; /* Sp after symbol char */
1052
70.0k
        goto recycle;
1053
66.1k
      case 11:
1054
66.1k
        if (LABELS_WITHOUT_COLONS || flag_m68k_mri)
1055
0
    state = 1;
1056
66.1k
        else
1057
66.1k
    {
1058
      /* We know that ch is not ':', since we tested that
1059
         case above.  Therefore this is not a label, so it
1060
         must be the opcode, and we've just seen the
1061
         whitespace after it.  */
1062
66.1k
      state = 3;
1063
66.1k
    }
1064
66.1k
        UNGET (ch);
1065
66.1k
        PUT (' '); /* Sp after label definition.  */
1066
66.1k
        break;
1067
66.1k
      default:
1068
0
        BAD_CASE (state);
1069
193k
      }
1070
66.1k
    break;
1071
1072
66.1k
  case LEX_IS_TWOCHAR_COMMENT_1ST:
1073
0
    ch2 = GET ();
1074
0
    if (ch2 == '*')
1075
0
      {
1076
25
  twochar_comment:
1077
25
        for (;;)
1078
641
    {
1079
641
      do
1080
165k
        {
1081
165k
          ch2 = GET ();
1082
165k
          if (ch2 != EOF && IS_NEWLINE (ch2))
1083
6.22k
      add_newlines++;
1084
165k
        }
1085
165k
      while (ch2 != EOF && ch2 != '*');
1086
1087
1.92k
      while (ch2 == '*')
1088
1.28k
        ch2 = GET ();
1089
1090
641
      if (ch2 == EOF || ch2 == '/')
1091
25
        break;
1092
1093
      /* This UNGET will ensure that we count newlines
1094
         correctly.  */
1095
616
      UNGET (ch2);
1096
616
    }
1097
1098
25
        if (ch2 == EOF)
1099
9
    as_warn (_("end of file in multiline comment"));
1100
1101
25
        ch = ' ';
1102
25
        goto recycle;
1103
0
      }
1104
#ifdef DOUBLESLASH_LINE_COMMENTS
1105
    else if (ch2 == '/')
1106
      {
1107
        do
1108
    {
1109
      ch = GET ();
1110
    }
1111
        while (ch != EOF && !IS_NEWLINE (ch));
1112
        if (ch == EOF)
1113
    as_warn ("end of file in comment; newline inserted");
1114
        state = 0;
1115
        PUT ('\n');
1116
        break;
1117
      }
1118
#endif
1119
0
    else
1120
0
      {
1121
0
        if (ch2 != EOF)
1122
0
    UNGET (ch2);
1123
0
        if (state == 9 || state == 10)
1124
0
    state = 3;
1125
0
        PUT (ch);
1126
0
      }
1127
0
    break;
1128
1129
95.2k
  case LEX_IS_STRINGQUOTE:
1130
95.2k
    quotechar = ch;
1131
95.2k
    if (state == 10)
1132
28.3k
      {
1133
        /* Preserve the whitespace in foo "bar".  */
1134
28.3k
        UNGET (ch);
1135
28.3k
        state = 3;
1136
28.3k
        PUT (' ');
1137
1138
        /* PUT didn't jump out.  We could just break, but we
1139
     know what will happen, so optimize a bit.  */
1140
28.3k
        ch = GET ();
1141
28.3k
        old_state = 9;
1142
28.3k
      }
1143
66.8k
    else if (state == 3)
1144
32.5k
      old_state = 9;
1145
34.2k
    else if (state == 0)
1146
1.24k
      old_state = 11; /* Now seeing label definition.  */
1147
33.0k
    else
1148
33.0k
      old_state = state;
1149
95.2k
    state = 5;
1150
95.2k
    PUT (ch);
1151
95.1k
    break;
1152
1153
95.1k
  case LEX_IS_ONECHAR_QUOTE:
1154
#ifdef H_TICK_HEX
1155
    if (state == 9 && enable_h_tick_hex)
1156
      {
1157
        char c;
1158
1159
        c = GET ();
1160
        as_warn ("'%c found after symbol", c);
1161
        UNGET (c);
1162
      }
1163
#endif
1164
43.8k
    if (state == 10)
1165
475
      {
1166
        /* Preserve the whitespace in foo 'b'.  */
1167
475
        UNGET (ch);
1168
475
        state = 3;
1169
475
        PUT (' ');
1170
475
        break;
1171
475
      }
1172
43.3k
    ch = GET ();
1173
43.3k
    if (ch == EOF)
1174
0
      {
1175
0
        as_warn (_("end of file after a one-character quote; \\0 inserted"));
1176
0
        ch = 0;
1177
0
      }
1178
43.3k
    if (ch == '\\')
1179
1.42k
      {
1180
1.42k
        ch = GET ();
1181
1.42k
        if (ch == EOF)
1182
0
    {
1183
0
      as_warn (_("end of file in escape character"));
1184
0
      ch = '\\';
1185
0
    }
1186
1.42k
        else
1187
1.42k
    ch = process_escape (ch);
1188
1.42k
      }
1189
43.3k
    sprintf (out_buf, "%d", ch & 0xff);
1190
1191
    /* None of these 'x constants for us.  We want 'x'.  */
1192
43.3k
    if ((ch = GET ()) != '\'')
1193
30.2k
      {
1194
#ifdef REQUIRE_CHAR_CLOSE_QUOTE
1195
        as_warn (_("missing close quote; (assumed)"));
1196
#else
1197
30.2k
        if (ch != EOF)
1198
30.2k
    UNGET (ch);
1199
30.2k
#endif
1200
30.2k
      }
1201
43.3k
    if (strlen (out_buf) == 1)
1202
1.92k
      {
1203
1.92k
        PUT (out_buf[0]);
1204
1.92k
        break;
1205
1.92k
      }
1206
41.4k
    if (state == 9)
1207
20.1k
      old_state = 3;
1208
21.2k
    else
1209
21.2k
      old_state = state;
1210
41.4k
    state = -1;
1211
41.4k
    out_string = out_buf;
1212
41.4k
    PUT (*out_string++);
1213
41.4k
    break;
1214
1215
41.4k
  case LEX_IS_COLON:
1216
#ifdef KEEP_WHITE_AROUND_COLON
1217
    state = 9;
1218
#else
1219
13.3k
    if (state == 9 || state == 10)
1220
2.03k
      state = 3;
1221
11.2k
    else if (state != 3)
1222
11.0k
      state = 1;
1223
13.3k
#endif
1224
13.3k
    PUT (ch);
1225
13.3k
    break;
1226
1227
171k
  case LEX_IS_NEWLINE:
1228
    /* Roll out a bunch of newlines from inside comments, etc.  */
1229
171k
    if (add_newlines)
1230
415
      {
1231
415
        --add_newlines;
1232
415
        UNGET (ch);
1233
415
      }
1234
    /* Fall through.  */
1235
1236
207k
  case LEX_IS_LINE_SEPARATOR:
1237
207k
    state = 0;
1238
207k
    PUT (ch);
1239
207k
    break;
1240
1241
207k
  case LEX_IS_PARALLEL_SEPARATOR:
1242
0
    state = 1;
1243
0
    PUT (ch);
1244
0
    break;
1245
1246
#ifdef TC_V850
1247
  case LEX_IS_DOUBLEDASH_1ST:
1248
    ch2 = GET ();
1249
    if (ch2 != '-')
1250
      {
1251
        if (ch2 != EOF)
1252
    UNGET (ch2);
1253
        goto de_fault;
1254
      }
1255
    /* Read and skip to end of line.  */
1256
    do
1257
      {
1258
        ch = GET ();
1259
      }
1260
    while (ch != EOF && ch != '\n');
1261
1262
    if (ch == EOF)
1263
      as_warn (_("end of file in comment; newline inserted"));
1264
1265
    state = 0;
1266
    PUT ('\n');
1267
    break;
1268
#endif
1269
#ifdef DOUBLEBAR_PARALLEL
1270
  case LEX_IS_DOUBLEBAR_1ST:
1271
    ch2 = GET ();
1272
    if (ch2 != EOF)
1273
      UNGET (ch2);
1274
    if (ch2 != '|')
1275
      goto de_fault;
1276
1277
    /* Handle '||' in two states as invoking PUT twice might
1278
       result in the first one jumping out of this loop.  We'd
1279
       then lose track of the state and one '|' char.  */
1280
    state = 13;
1281
    PUT ('|');
1282
    break;
1283
#endif
1284
40.2k
  case LEX_IS_LINE_COMMENT_START:
1285
    /* FIXME-someday: The two character comment stuff was badly
1286
       thought out.  On i386, we want '/' as line comment start
1287
       AND we want C style comments.  hence this hack.  The
1288
       whole lexical process should be reworked.  xoxorich.  */
1289
40.2k
    if (ch == '/')
1290
38.0k
      {
1291
38.0k
        ch2 = GET ();
1292
38.0k
        if (ch2 == '*')
1293
25
    goto twochar_comment;
1294
38.0k
        if (ch2 != EOF)
1295
38.0k
    UNGET (ch2);
1296
38.0k
      }
1297
1298
40.1k
    if (state == 0 || state == 1)  /* Only comment at start of line.  */
1299
1.09k
      {
1300
1.09k
        int startch;
1301
1302
1.09k
        startch = ch;
1303
1304
1.09k
        do
1305
1.09k
    {
1306
1.09k
      ch = GET ();
1307
1.09k
    }
1308
1.09k
        while (ch != EOF && IS_WHITESPACE (ch));
1309
1310
1.09k
        if (ch == EOF)
1311
0
    {
1312
0
      as_warn (_("end of file in comment; newline inserted"));
1313
0
      PUT ('\n');
1314
0
      break;
1315
0
    }
1316
1317
1.09k
        if (ch < '0' || ch > '9' || state != 0 || startch != '#')
1318
288
    {
1319
      /* Not a cpp line.  */
1320
5.78k
      while (ch != EOF && !IS_NEWLINE (ch))
1321
5.50k
        ch = GET ();
1322
288
      if (ch == EOF)
1323
1
        {
1324
1
          as_warn (_("end of file in comment; newline inserted"));
1325
1
          PUT ('\n');
1326
1
        }
1327
287
      else /* IS_NEWLINE (ch) */
1328
287
        {
1329
          /* To process non-zero add_newlines.  */
1330
287
          UNGET (ch);
1331
287
        }
1332
288
      state = 0;
1333
288
      break;
1334
288
    }
1335
        /* Looks like `# 123 "filename"' from cpp.  */
1336
803
        UNGET (ch);
1337
803
        old_state = 4;
1338
803
        state = -1;
1339
803
        if (scrub_m68k_mri)
1340
0
    out_string = "\tlinefile ";
1341
803
        else
1342
803
    out_string = "\t.linefile ";
1343
803
        PUT (*out_string++);
1344
803
        break;
1345
803
      }
1346
1347
#ifdef TC_D10V
1348
    /* All insns end in a char for which LEX_IS_SYMBOL_COMPONENT is true.
1349
       Trap is the only short insn that has a first operand that is
1350
       neither register nor label.
1351
       We must prevent exef0f ||trap #1 to degenerate to exef0f ||trap#1 .
1352
       We can't make '#' LEX_IS_SYMBOL_COMPONENT because it is
1353
       already LEX_IS_LINE_COMMENT_START.  However, it is the
1354
       only character in line_comment_chars for d10v, hence we
1355
       can recognize it as such.  */
1356
    /* An alternative approach would be to reset the state to 1 when
1357
       we see '||', '<'- or '->', but that seems to be overkill.  */
1358
    if (state == 10)
1359
      PUT (' ');
1360
#endif
1361
    /* We have a line comment character which is not at the
1362
       start of a line.  If this is also a normal comment
1363
       character, fall through.  Otherwise treat it as a default
1364
       character.  */
1365
39.0k
    if (strchr (tc_comment_chars, ch) == NULL)
1366
37.9k
      goto de_fault;
1367
1.11k
    if (scrub_m68k_mri
1368
0
        && (ch == '!' || ch == '*' || ch == '#'))
1369
0
      goto de_fault;
1370
    /* Fall through.  */
1371
1.11k
  case LEX_IS_COMMENT_START:
1372
#if defined TC_ARM && defined OBJ_ELF
1373
    /* On the ARM, `@' is the comment character.
1374
       Unfortunately this is also a special character in ELF .symver
1375
       directives (and .type, though we deal with those another way).
1376
       So we check if this line is such a directive, and treat
1377
       the character as default if so.  This is a hack.  */
1378
    if ((symver_state != NULL) && (*symver_state == 0))
1379
      goto de_fault;
1380
#endif
1381
1382
    /* Care is needed not to damage occurrences of \<comment-char>
1383
       by stripping the <comment-char> onwards.  Yuck.  */
1384
1.11k
    if ((to > tostart ? to[-1] : last_char) == '\\')
1385
      /* Do not treat the <comment-char> as a start-of-comment.  */
1386
0
      goto de_fault;
1387
1388
#ifdef WARN_COMMENTS
1389
    if (!found_comment)
1390
      found_comment_file = as_where (&found_comment);
1391
#endif
1392
1.11k
    do
1393
35.0k
      {
1394
35.0k
        ch = GET ();
1395
35.0k
      }
1396
35.0k
    while (ch != EOF && !IS_NEWLINE (ch));
1397
1.11k
    if (ch == EOF)
1398
8
      as_warn (_("end of file in comment; newline inserted"));
1399
1.11k
    state = 0;
1400
1.11k
    PUT ('\n');
1401
1.11k
    break;
1402
1403
#ifdef H_TICK_HEX
1404
  case LEX_IS_H:
1405
    /* Look for strings like H'[0-9A-Fa-f] and if found, replace
1406
       the H' with 0x to make them gas-style hex characters.  */
1407
    if (enable_h_tick_hex)
1408
      {
1409
        char quot;
1410
1411
        quot = GET ();
1412
        if (quot == '\'')
1413
    {
1414
      UNGET ('x');
1415
      ch = '0';
1416
    }
1417
        else
1418
    UNGET (quot);
1419
      }
1420
#endif
1421
    /* Fall through.  */
1422
1423
659k
  case LEX_IS_SYMBOL_COMPONENT:
1424
659k
    if (state == 10)
1425
38.5k
      {
1426
        /* This is a symbol character following another symbol
1427
     character, with whitespace in between.  We skipped
1428
     the whitespace earlier, so output it now.  */
1429
38.5k
        UNGET (ch);
1430
38.5k
        state = 3;
1431
38.5k
        PUT (' ');
1432
38.5k
        break;
1433
38.5k
      }
1434
1435
#ifdef TC_Z80
1436
    /* "af'" is a symbol containing '\''.  */
1437
    if (state == 3 && (ch == 'a' || ch == 'A'))
1438
      {
1439
        state = 16;
1440
        PUT (ch);
1441
        ch = GET ();
1442
        if (ch == 'f' || ch == 'F')
1443
    {
1444
      state = 17;
1445
      PUT (ch);
1446
      break;
1447
    }
1448
        else
1449
    {
1450
      state = 9;
1451
      if (ch == EOF || !IS_SYMBOL_COMPONENT (ch))
1452
        {
1453
          if (ch != EOF)
1454
      UNGET (ch);
1455
          break;
1456
        }
1457
    }
1458
      }
1459
#endif
1460
621k
    if (state == 3)
1461
188k
      state = 9;
1462
1463
    /* This is a common case.  Quickly copy CH and all the
1464
       following symbol component or normal characters.  */
1465
621k
    if (to + 1 < toend
1466
#ifdef TC_M68K
1467
        && mri_state == NULL
1468
#endif
1469
#if defined TC_ARM && defined OBJ_ELF
1470
        && symver_state == NULL
1471
#endif
1472
621k
        && end_state == NULL)
1473
479k
      {
1474
479k
        char *s;
1475
479k
        ptrdiff_t len;
1476
1477
4.54M
        for (s = from; s < fromend; s++)
1478
4.54M
    {
1479
4.54M
      int type;
1480
1481
4.54M
      ch2 = *(unsigned char *) s;
1482
4.54M
      type = lex[ch2];
1483
4.54M
      if (type != 0
1484
3.99M
          && type != LEX_IS_SYMBOL_COMPONENT)
1485
479k
        break;
1486
4.54M
    }
1487
1488
479k
        if (s > from)
1489
    /* Handle the last character normally, for
1490
       simplicity.  */
1491
394k
    --s;
1492
1493
479k
        len = s - from;
1494
1495
479k
        if (len > (toend - to) - 1)
1496
0
    len = (toend - to) - 1;
1497
1498
479k
        if (len > 0)
1499
360k
    {
1500
360k
      PUT (ch);
1501
360k
      memcpy (to, from, len);
1502
360k
      to += len;
1503
360k
      from += len;
1504
360k
      if (to >= toend)
1505
0
        goto tofull;
1506
360k
      ch = GET ();
1507
360k
    }
1508
479k
      }
1509
1510
    /* Fall through.  */
1511
710k
  default:
1512
748k
  de_fault:
1513
    /* Some relatively `normal' character.  */
1514
748k
    if (state == 0)
1515
121k
      {
1516
121k
        state = 11; /* Now seeing label definition.  */
1517
121k
      }
1518
626k
    else if (state == 1)
1519
64.3k
      {
1520
64.3k
        state = 2;  /* Ditto.  */
1521
64.3k
      }
1522
562k
    else if (state == 9)
1523
252k
      {
1524
252k
        if (!IS_SYMBOL_COMPONENT (ch))
1525
65.9k
    state = 3;
1526
252k
      }
1527
309k
    else if (state == 10)
1528
2.64k
      {
1529
2.64k
        if (ch == '\\')
1530
0
    {
1531
      /* Special handling for backslash: a backslash may
1532
         be the beginning of a formal parameter (of a
1533
         macro) following another symbol character, with
1534
         whitespace in between.  If that is the case, we
1535
         output a space before the parameter.  Strictly
1536
         speaking, correct handling depends upon what the
1537
         macro parameter expands into; if the parameter
1538
         expands into something which does not start with
1539
         an operand character, then we don't want to keep
1540
         the space.  We don't have enough information to
1541
         make the right choice, so here we are making the
1542
         choice which is more likely to be correct.  */
1543
0
      if (to + 1 >= toend)
1544
0
        {
1545
          /* If we're near the end of the buffer, save the
1546
             character for the next time round.  Otherwise
1547
             we'll lose our state.  */
1548
0
          UNGET (ch);
1549
0
          goto tofull;
1550
0
        }
1551
0
      *to++ = ' ';
1552
0
    }
1553
1554
2.64k
        state = 3;
1555
2.64k
      }
1556
748k
    PUT (ch);
1557
748k
    break;
1558
1.39M
  }
1559
1.39M
    }
1560
1561
  /*NOTREACHED*/
1562
1563
992
 fromeof:
1564
  /* We have reached the end of the input.  */
1565
992
  if (to > tostart)
1566
992
    last_char = to[-1];
1567
992
  return to - tostart;
1568
1569
649
 tofull:
1570
  /* The output buffer is full.  Save any input we have not yet
1571
     processed.  */
1572
649
  if (fromend > from)
1573
649
    {
1574
649
      saved_input = from;
1575
649
      saved_input_len = fromend - from;
1576
649
    }
1577
0
  else
1578
0
    saved_input = NULL;
1579
1580
649
  if (to > tostart)
1581
649
    last_char = to[-1];
1582
649
  return to - tostart;
1583
1.64k
}
1584
1585
/* Return amount of pending input.  */
1586
1587
size_t
1588
do_scrub_pending (void)
1589
2.10k
{
1590
2.10k
  size_t len = 0;
1591
2.10k
  if (saved_input)
1592
640
    len += saved_input_len;
1593
2.10k
  if (state == -1)
1594
0
    len += strlen (out_string);
1595
2.10k
  return len;
1596
2.10k
}