Coverage Report

Created: 2026-07-25 10:20

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
786k
#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
14.1M
#define LEX_IS_SYMBOL_COMPONENT   1
73
1.21M
#define LEX_IS_WHITESPACE   2
74
1.14M
#define LEX_IS_LINE_SEPARATOR   3
75
465k
#define LEX_IS_COMMENT_START    4
76
559k
#define LEX_IS_LINE_COMMENT_START 5
77
0
#define LEX_IS_TWOCHAR_COMMENT_1ST  6
78
227k
#define LEX_IS_STRINGQUOTE    8
79
787k
#define LEX_IS_COLON      9
80
1.47M
#define LEX_IS_NEWLINE      10
81
31.4k
#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
441k
#define LEX_IS_PARALLEL_SEPARATOR 14
89
#ifdef H_TICK_HEX
90
#define LEX_IS_H      15
91
#endif
92
585k
#define IS_SYMBOL_COMPONENT(c)    (lex[c] == LEX_IS_SYMBOL_COMPONENT)
93
619k
#define IS_WHITESPACE(c)    (lex[c] == LEX_IS_WHITESPACE)
94
1.00M
#define IS_LINE_SEPARATOR(c)    (lex[c] == LEX_IS_LINE_SEPARATOR)
95
441k
#define IS_PARALLEL_SEPARATOR(c)  (lex[c] == LEX_IS_PARALLEL_SEPARATOR)
96
888k
#define IS_COMMENT(c)     (lex[c] == LEX_IS_COMMENT_START)
97
888k
#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
1.57M
#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
535
{
171
535
  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
535
  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
535
    {
185
535
      lex['"'] = LEX_IS_STRINGQUOTE;
186
187
535
#if ! defined (TC_HPPA)
188
535
      lex['\''] = LEX_IS_ONECHAR_QUOTE;
189
535
#endif
190
191
#ifdef SINGLE_QUOTE_STRINGS
192
      lex['\''] = LEX_IS_STRINGQUOTE;
193
#endif
194
535
    }
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
535
#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
3.21k
  for (p = tc_symbol_chars; *p; ++p)
209
2.67k
    lex[(unsigned char) *p] = LEX_IS_SYMBOL_COMPONENT;
210
535
#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
1.07k
  for (p = tc_comment_chars; *p; p++)
217
535
    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
1.60k
  for (p = line_comment_chars; *p; p++)
223
1.07k
    lex[(unsigned char) *p] = LEX_IS_LINE_COMMENT_START;
224
225
535
#ifndef tc_line_separator_chars
226
535
#define tc_line_separator_chars line_separator_chars
227
535
#endif
228
1.07k
  for (p = tc_line_separator_chars; *p; p++)
229
535
    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
535
  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
535
}
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
1.42k
{
311
1.42k
  struct app_save *saved;
312
313
1.42k
  saved = XNEW (struct app_save);
314
1.42k
  saved->state = state;
315
1.42k
  saved->old_state = old_state;
316
1.42k
  saved->out_string = out_string;
317
1.42k
  memcpy (saved->out_buf, out_buf, sizeof (out_buf));
318
1.42k
  saved->add_newlines = add_newlines;
319
1.42k
  if (saved_input == NULL)
320
1.42k
    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
1.42k
  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
1.42k
  saved->last_char = last_char;
337
338
  /* do_scrub_begin() is not useful, just wastes time.  */
339
340
1.42k
  state = 0;
341
1.42k
  saved_input = NULL;
342
1.42k
  add_newlines = 0;
343
344
1.42k
  return (char *) saved;
345
1.42k
}
346
347
void
348
app_pop (char *arg)
349
1.42k
{
350
1.42k
  struct app_save *saved = (struct app_save *) arg;
351
352
  /* There is no do_scrub_end ().  */
353
1.42k
  state = saved->state;
354
1.42k
  old_state = saved->old_state;
355
1.42k
  out_string = saved->out_string;
356
1.42k
  memcpy (out_buf, saved->out_buf, sizeof (out_buf));
357
1.42k
  add_newlines = saved->add_newlines;
358
1.42k
  if (saved->saved_input == NULL)
359
1.42k
    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
1.42k
  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
1.42k
  last_char = saved->last_char;
378
379
1.42k
  free (arg);
380
1.42k
}
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
7
{
388
7
  switch (ch)
389
7
    {
390
5
    case 'b':
391
5
      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
0
    case '"':
403
0
      return '\"';
404
2
    default:
405
2
      return ch;
406
7
    }
407
7
}
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
2.96k
{
473
2.96k
  char *to = tostart;
474
2.96k
  char *toend = tostart + tolen;
475
2.96k
  char *from;
476
2.96k
  char *fromend;
477
2.96k
  size_t fromlen;
478
2.96k
  int ch, ch2 = 0;
479
  /* Character that started the string we're working on.  */
480
2.96k
  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
2.96k
#define GET()             \
529
6.00M
  (from < fromend            \
530
6.00M
   ? * (unsigned char *) (from++)        \
531
6.00M
   : (saved_input = NULL,          \
532
2.90k
      fromlen = (*get) (input_buffer, sizeof input_buffer), \
533
2.90k
      from = input_buffer,          \
534
2.90k
      fromend = from + fromlen,         \
535
2.90k
      (fromlen == 0            \
536
2.90k
       ? EOF              \
537
2.90k
       : * (unsigned char *) (from++))))
538
539
  /* This macro pushes a character back on the input stream.  */
540
541
578k
#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
2.96k
#define PUT(pch)        \
553
5.02M
  do            \
554
5.02M
    {           \
555
5.02M
      *to++ = (pch);        \
556
5.02M
      if (to >= toend)       \
557
5.02M
  goto tofull;       \
558
5.02M
    }           \
559
5.02M
  while (0)
560
561
2.96k
  if (saved_input != NULL)
562
625
    {
563
625
      from = saved_input;
564
625
      fromend = from + saved_input_len;
565
625
    }
566
2.34k
  else
567
2.34k
    {
568
2.34k
      fromlen = (*get) (input_buffer, sizeof input_buffer);
569
2.34k
      if (fromlen == 0)
570
531
  return 0;
571
1.81k
      from = input_buffer;
572
1.81k
      fromend = from + fromlen;
573
574
1.81k
      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
1.81k
    }
579
580
3.82M
  while (1)
581
3.82M
    {
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
3.82M
      switch (state)
586
3.82M
  {
587
94.2k
  case -1:
588
94.2k
    ch = *out_string++;
589
94.2k
    if (*out_string == '\0')
590
34.2k
      {
591
34.2k
        state = old_state;
592
34.2k
        old_state = 3;
593
34.2k
      }
594
94.2k
    PUT (ch);
595
94.2k
    continue;
596
597
94.2k
  case 4:
598
7.07k
    ch = GET ();
599
7.07k
    if (ch == EOF)
600
0
      goto fromeof;
601
7.07k
    else if (ch >= '0' && ch <= '9')
602
3.69k
      PUT (ch);
603
3.38k
    else
604
3.38k
      {
605
3.39k
        while (ch != EOF && IS_WHITESPACE (ch))
606
8
    ch = GET ();
607
3.38k
        if (ch == '"')
608
3.11k
    {
609
3.11k
      quotechar = ch;
610
3.11k
      state = 5;
611
3.11k
      old_state = 3;
612
3.11k
      PUT (ch);
613
3.11k
    }
614
273
        else
615
273
    {
616
2.20k
      while (ch != EOF && ch != '\n')
617
1.92k
        ch = GET ();
618
273
      state = 0;
619
273
      PUT (ch);
620
273
    }
621
3.38k
      }
622
7.07k
    continue;
623
624
541k
  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
541k
    {
630
541k
      char *s;
631
541k
      ptrdiff_t len;
632
633
11.1M
      for (s = from; s < fromend; s++)
634
11.1M
        {
635
11.1M
    ch = *s;
636
11.1M
    if (ch == '\\'
637
11.1M
        || ch == quotechar
638
10.9M
        || ch == '\n')
639
540k
      break;
640
11.1M
        }
641
541k
      len = s - from;
642
541k
      if (len > toend - to)
643
1
        len = toend - to;
644
541k
      if (len > 0)
645
488k
        {
646
488k
    memcpy (to, from, len);
647
488k
    to += len;
648
488k
    from += len;
649
488k
    if (to >= toend)
650
1
      goto tofull;
651
488k
        }
652
541k
    }
653
654
541k
    ch = GET ();
655
541k
    if (ch == EOF)
656
507
      {
657
        /* This buffer is here specifically so
658
     that the UNGET below will work.  */
659
507
        static char one_char_buf[1];
660
661
507
        as_warn (_("end of file in string; '%c' inserted"), quotechar);
662
507
        state = old_state;
663
507
        from = fromend = one_char_buf + 1;
664
507
        fromlen = 1;
665
507
        UNGET ('\n');
666
507
        PUT (quotechar);
667
507
      }
668
541k
    else if (ch == quotechar)
669
229k
      {
670
229k
        state = old_state;
671
229k
        PUT (ch);
672
229k
      }
673
311k
    else if (TC_STRING_ESCAPES && ch == '\\')
674
2.98k
      {
675
2.98k
        state = 6;
676
2.98k
        PUT (ch);
677
2.98k
      }
678
308k
    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
308k
    else
687
308k
      {
688
308k
        PUT (ch);
689
308k
      }
690
541k
    continue;
691
692
541k
  case 6:
693
2.98k
    state = 5;
694
2.98k
    ch = GET ();
695
2.98k
    switch (ch)
696
2.98k
      {
697
        /* Handle strings broken across lines, by turning '\\' followed
698
     by '\n' into '\\' (already emitted when state moved to 6) and
699
     'n'.  */
700
3
      case '\n':
701
3
        add_newlines++;
702
3
        PUT ('n');
703
3
        continue;
704
705
3
      case EOF:
706
0
        as_warn (_("end of file in string; '%c' inserted"), quotechar);
707
0
        PUT (quotechar);
708
0
        continue;
709
710
2.98k
      default:
711
2.98k
        break;
712
2.98k
      }
713
2.98k
    PUT (ch);
714
2.98k
    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
3.82M
  }
758
759
      /* OK, we are somewhere in states 0 through 4 or 9 through 11.  */
760
761
      /* flushchar: */
762
3.17M
      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
3.43M
    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
3.43M
      if (ch == EOF)
792
1.79k
  end_state = NULL;
793
3.43M
      else if (end_state == NULL)
794
2.97M
  {
795
2.97M
    if ((state == 0 || state == 1)
796
769k
        && (ch == '.'
797
431k
      || (no_pseudo_dot && ch == end_pseudo[0])))
798
337k
      end_state = end_pseudo + (ch != '.');
799
2.97M
  }
800
456k
      else if (ch != '\0'
801
456k
         && (*end_state == ch
802
       /* Avoid triggering on directives like .endif or .endr.  */
803
337k
       || (*end_state == ' ' && !IS_SYMBOL_COMPONENT (ch))))
804
118k
  {
805
118k
    if (IS_NEWLINE (ch) || IS_LINE_SEPARATOR (ch))
806
0
      goto end_end;
807
118k
    ++end_state;
808
118k
  }
809
337k
      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
337k
  end_state = NULL;
814
64
      else if (IS_NEWLINE (ch) || IS_LINE_SEPARATOR (ch))
815
53
  {
816
53
  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
53
    end_state = NULL;
823
53
    state = 0;
824
53
    PUT (ch);
825
53
    goto tofull;
826
53
  }
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
3.43M
      if (ch == EOF)
918
1.79k
  {
919
1.79k
    if (state != 0)
920
264
      {
921
264
        as_warn (_("end of file not at end of a line; newline inserted"));
922
264
        state = 0;
923
264
        PUT ('\n');
924
264
      }
925
1.79k
    goto fromeof;
926
1.79k
  }
927
928
3.43M
      switch (lex[ch])
929
3.43M
  {
930
598k
  case LEX_IS_WHITESPACE:
931
598k
    do
932
611k
      {
933
611k
        ch = GET ();
934
611k
      }
935
611k
    while (ch != EOF && IS_WHITESPACE (ch));
936
598k
    if (ch == EOF)
937
15
      goto fromeof;
938
939
598k
    if (state == 0)
940
153k
      {
941
        /* Preserve a single whitespace character at the
942
     beginning of a line.  */
943
153k
        state = 1;
944
153k
        UNGET (ch);
945
153k
        PUT (' ');
946
153k
        break;
947
153k
      }
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
444k
    if (IS_COMMENT (ch)
969
444k
        || (IS_LINE_COMMENT (ch)
970
152
            && (state < 1 || strchr (tc_comment_chars, ch)))
971
444k
        || IS_NEWLINE (ch)
972
441k
        || IS_LINE_SEPARATOR (ch)
973
441k
        || IS_PARALLEL_SEPARATOR (ch))
974
3.29k
      {
975
3.29k
        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
3.29k
        goto recycle;
983
3.29k
      }
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
441k
    if ((state == 2 || state == 11)
1001
319k
        && lex[ch] == LEX_IS_COLON
1002
0
        && ! scrub_m68k_mri)
1003
8
      {
1004
8
        state = 1;
1005
8
        PUT (ch);
1006
8
        break;
1007
8
      }
1008
1009
441k
    switch (state)
1010
441k
      {
1011
157
      case 1:
1012
        /* We can arrive here if we leave a leading whitespace
1013
     character at the beginning of a line.  */
1014
157
        goto recycle;
1015
134k
      case 2:
1016
134k
        state = 3;
1017
134k
        if (to + 1 < toend)
1018
134k
    {
1019
      /* Optimize common case by skipping UNGET/GET.  */
1020
134k
      PUT (' '); /* Sp after opco */
1021
134k
      goto recycle;
1022
134k
    }
1023
0
        UNGET (ch);
1024
0
        PUT (' ');
1025
0
        break;
1026
4.21k
      case 3:
1027
4.21k
#ifndef TC_KEEP_OPERAND_SPACES
1028
        /* For TI C6X, we keep these spaces as they may separate
1029
     functional unit specifiers from operands.  */
1030
4.21k
        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
4.21k
        goto recycle; /* Sp in operands */
1039
117k
      case 9:
1040
117k
      case 10:
1041
117k
#ifndef TC_KEEP_OPERAND_SPACES
1042
117k
        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
117k
        state = 10; /* Sp after symbol char */
1052
117k
        goto recycle;
1053
185k
      case 11:
1054
185k
        if (LABELS_WITHOUT_COLONS || flag_m68k_mri)
1055
0
    state = 1;
1056
185k
        else
1057
185k
    {
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
185k
      state = 3;
1063
185k
    }
1064
185k
        UNGET (ch);
1065
185k
        PUT (' '); /* Sp after label definition.  */
1066
184k
        break;
1067
184k
      default:
1068
0
        BAD_CASE (state);
1069
441k
      }
1070
184k
    break;
1071
1072
184k
  case LEX_IS_TWOCHAR_COMMENT_1ST:
1073
0
    ch2 = GET ();
1074
0
    if (ch2 == '*')
1075
0
      {
1076
3
  twochar_comment:
1077
3
        for (;;)
1078
8
    {
1079
8
      do
1080
272
        {
1081
272
          ch2 = GET ();
1082
272
          if (ch2 != EOF && IS_NEWLINE (ch2))
1083
38
      add_newlines++;
1084
272
        }
1085
272
      while (ch2 != EOF && ch2 != '*');
1086
1087
15
      while (ch2 == '*')
1088
7
        ch2 = GET ();
1089
1090
8
      if (ch2 == EOF || ch2 == '/')
1091
3
        break;
1092
1093
      /* This UNGET will ensure that we count newlines
1094
         correctly.  */
1095
5
      UNGET (ch2);
1096
5
    }
1097
1098
3
        if (ch2 == EOF)
1099
3
    as_warn (_("end of file in multiline comment"));
1100
1101
3
        ch = ' ';
1102
3
        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
227k
  case LEX_IS_STRINGQUOTE:
1130
227k
    quotechar = ch;
1131
227k
    if (state == 10)
1132
58.4k
      {
1133
        /* Preserve the whitespace in foo "bar".  */
1134
58.4k
        UNGET (ch);
1135
58.4k
        state = 3;
1136
58.4k
        PUT (' ');
1137
1138
        /* PUT didn't jump out.  We could just break, but we
1139
     know what will happen, so optimize a bit.  */
1140
58.4k
        ch = GET ();
1141
58.4k
        old_state = 9;
1142
58.4k
      }
1143
168k
    else if (state == 3)
1144
81.1k
      old_state = 9;
1145
87.7k
    else if (state == 0)
1146
773
      old_state = 11; /* Now seeing label definition.  */
1147
86.9k
    else
1148
86.9k
      old_state = state;
1149
227k
    state = 5;
1150
227k
    PUT (ch);
1151
227k
    break;
1152
1153
227k
  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
30.9k
    if (state == 10)
1165
1
      {
1166
        /* Preserve the whitespace in foo 'b'.  */
1167
1
        UNGET (ch);
1168
1
        state = 3;
1169
1
        PUT (' ');
1170
1
        break;
1171
1
      }
1172
30.9k
    ch = GET ();
1173
30.9k
    if (ch == EOF)
1174
2
      {
1175
2
        as_warn (_("end of file after a one-character quote; \\0 inserted"));
1176
2
        ch = 0;
1177
2
      }
1178
30.9k
    if (ch == '\\')
1179
7
      {
1180
7
        ch = GET ();
1181
7
        if (ch == EOF)
1182
0
    {
1183
0
      as_warn (_("end of file in escape character"));
1184
0
      ch = '\\';
1185
0
    }
1186
7
        else
1187
7
    ch = process_escape (ch);
1188
7
      }
1189
30.9k
    sprintf (out_buf, "%d", ch & 0xff);
1190
1191
    /* None of these 'x constants for us.  We want 'x'.  */
1192
30.9k
    if ((ch = GET ()) != '\'')
1193
30.7k
      {
1194
#ifdef REQUIRE_CHAR_CLOSE_QUOTE
1195
        as_warn (_("missing close quote; (assumed)"));
1196
#else
1197
30.7k
        if (ch != EOF)
1198
30.7k
    UNGET (ch);
1199
30.7k
#endif
1200
30.7k
      }
1201
30.9k
    if (strlen (out_buf) == 1)
1202
77
      {
1203
77
        PUT (out_buf[0]);
1204
77
        break;
1205
77
      }
1206
30.8k
    if (state == 9)
1207
29.7k
      old_state = 3;
1208
1.05k
    else
1209
1.05k
      old_state = state;
1210
30.8k
    state = -1;
1211
30.8k
    out_string = out_buf;
1212
30.8k
    PUT (*out_string++);
1213
30.6k
    break;
1214
1215
30.6k
  case LEX_IS_COLON:
1216
#ifdef KEEP_WHITE_AROUND_COLON
1217
    state = 9;
1218
#else
1219
26.9k
    if (state == 9 || state == 10)
1220
5.33k
      state = 3;
1221
21.6k
    else if (state != 3)
1222
8.33k
      state = 1;
1223
26.9k
#endif
1224
26.9k
    PUT (ch);
1225
26.9k
    break;
1226
1227
462k
  case LEX_IS_NEWLINE:
1228
    /* Roll out a bunch of newlines from inside comments, etc.  */
1229
462k
    if (add_newlines)
1230
41
      {
1231
41
        --add_newlines;
1232
41
        UNGET (ch);
1233
41
      }
1234
    /* Fall through.  */
1235
1236
583k
  case LEX_IS_LINE_SEPARATOR:
1237
583k
    state = 0;
1238
583k
    PUT (ch);
1239
583k
    break;
1240
1241
583k
  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
113k
  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
113k
    if (ch == '/')
1290
87.7k
      {
1291
87.7k
        ch2 = GET ();
1292
87.7k
        if (ch2 == '*')
1293
3
    goto twochar_comment;
1294
87.7k
        if (ch2 != EOF)
1295
87.7k
    UNGET (ch2);
1296
87.7k
      }
1297
1298
113k
    if (state == 0 || state == 1)  /* Only comment at start of line.  */
1299
4.96k
      {
1300
4.96k
        int startch;
1301
1302
4.96k
        startch = ch;
1303
1304
4.96k
        do
1305
4.97k
    {
1306
4.97k
      ch = GET ();
1307
4.97k
    }
1308
4.97k
        while (ch != EOF && IS_WHITESPACE (ch));
1309
1310
4.96k
        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
4.96k
        if (ch < '0' || ch > '9' || state != 0 || startch != '#')
1318
1.57k
    {
1319
      /* Not a cpp line.  */
1320
29.5k
      while (ch != EOF && !IS_NEWLINE (ch))
1321
27.9k
        ch = GET ();
1322
1.57k
      if (ch == EOF)
1323
3
        {
1324
3
          as_warn (_("end of file in comment; newline inserted"));
1325
3
          PUT ('\n');
1326
3
        }
1327
1.57k
      else /* IS_NEWLINE (ch) */
1328
1.57k
        {
1329
          /* To process non-zero add_newlines.  */
1330
1.57k
          UNGET (ch);
1331
1.57k
        }
1332
1.57k
      state = 0;
1333
1.57k
      break;
1334
1.57k
    }
1335
        /* Looks like `# 123 "filename"' from cpp.  */
1336
3.38k
        UNGET (ch);
1337
3.38k
        old_state = 4;
1338
3.38k
        state = -1;
1339
3.38k
        if (scrub_m68k_mri)
1340
0
    out_string = "\tlinefile ";
1341
3.38k
        else
1342
3.38k
    out_string = "\t.linefile ";
1343
3.38k
        PUT (*out_string++);
1344
3.38k
        break;
1345
3.38k
      }
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
108k
    if (strchr (tc_comment_chars, ch) == NULL)
1366
87.5k
      goto de_fault;
1367
21.0k
    if (scrub_m68k_mri
1368
0
        && (ch == '!' || ch == '*' || ch == '#'))
1369
0
      goto de_fault;
1370
    /* Fall through.  */
1371
21.0k
  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
21.0k
    if ((to > tostart ? to[-1] : last_char) == '\\')
1385
      /* Do not treat the <comment-char> as a start-of-comment.  */
1386
4
      goto de_fault;
1387
1388
#ifdef WARN_COMMENTS
1389
    if (!found_comment)
1390
      found_comment_file = as_where (&found_comment);
1391
#endif
1392
21.0k
    do
1393
417k
      {
1394
417k
        ch = GET ();
1395
417k
      }
1396
417k
    while (ch != EOF && !IS_NEWLINE (ch));
1397
21.0k
    if (ch == EOF)
1398
18
      as_warn (_("end of file in comment; newline inserted"));
1399
21.0k
    state = 0;
1400
21.0k
    PUT ('\n');
1401
21.0k
    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
1.75M
  case LEX_IS_SYMBOL_COMPONENT:
1424
1.75M
    if (state == 10)
1425
57.3k
      {
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
57.3k
        UNGET (ch);
1430
57.3k
        state = 3;
1431
57.3k
        PUT (' ');
1432
57.3k
        break;
1433
57.3k
      }
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
1.69M
    if (state == 3)
1461
437k
      state = 9;
1462
1463
    /* This is a common case.  Quickly copy CH and all the
1464
       following symbol component or normal characters.  */
1465
1.69M
    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
1.69M
        && end_state == NULL)
1473
1.24M
      {
1474
1.24M
        char *s;
1475
1.24M
        ptrdiff_t len;
1476
1477
14.0M
        for (s = from; s < fromend; s++)
1478
14.0M
    {
1479
14.0M
      int type;
1480
1481
14.0M
      ch2 = *(unsigned char *) s;
1482
14.0M
      type = lex[ch2];
1483
14.0M
      if (type != 0
1484
11.7M
          && type != LEX_IS_SYMBOL_COMPONENT)
1485
1.23M
        break;
1486
14.0M
    }
1487
1488
1.24M
        if (s > from)
1489
    /* Handle the last character normally, for
1490
       simplicity.  */
1491
1.08M
    --s;
1492
1493
1.24M
        len = s - from;
1494
1495
1.24M
        if (len > (toend - to) - 1)
1496
0
    len = (toend - to) - 1;
1497
1498
1.24M
        if (len > 0)
1499
1.01M
    {
1500
1.01M
      PUT (ch);
1501
1.01M
      memcpy (to, from, len);
1502
1.01M
      to += len;
1503
1.01M
      from += len;
1504
1.01M
      if (to >= toend)
1505
0
        goto tofull;
1506
1.01M
      ch = GET ();
1507
1.01M
    }
1508
1.24M
      }
1509
1510
    /* Fall through.  */
1511
1.79M
  default:
1512
1.88M
  de_fault:
1513
    /* Some relatively `normal' character.  */
1514
1.88M
    if (state == 0)
1515
398k
      {
1516
398k
        state = 11; /* Now seeing label definition.  */
1517
398k
      }
1518
1.48M
    else if (state == 1)
1519
159k
      {
1520
159k
        state = 2;  /* Ditto.  */
1521
159k
      }
1522
1.32M
    else if (state == 9)
1523
559k
      {
1524
559k
        if (!IS_SYMBOL_COMPONENT (ch))
1525
223k
    state = 3;
1526
559k
      }
1527
763k
    else if (state == 10)
1528
1.36k
      {
1529
1.36k
        if (ch == '\\')
1530
15
    {
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
15
      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
15
      *to++ = ' ';
1552
15
    }
1553
1554
1.36k
        state = 3;
1555
1.36k
      }
1556
1.88M
    PUT (ch);
1557
1.88M
    break;
1558
3.43M
  }
1559
3.43M
    }
1560
1561
  /*NOTREACHED*/
1562
1563
1.81k
 fromeof:
1564
  /* We have reached the end of the input.  */
1565
1.81k
  if (to > tostart)
1566
1.81k
    last_char = to[-1];
1567
1.81k
  return to - tostart;
1568
1569
625
 tofull:
1570
  /* The output buffer is full.  Save any input we have not yet
1571
     processed.  */
1572
625
  if (fromend > from)
1573
625
    {
1574
625
      saved_input = from;
1575
625
      saved_input_len = fromend - from;
1576
625
    }
1577
0
  else
1578
0
    saved_input = NULL;
1579
1580
625
  if (to > tostart)
1581
625
    last_char = to[-1];
1582
625
  return to - tostart;
1583
2.43k
}
1584
1585
/* Return amount of pending input.  */
1586
1587
size_t
1588
do_scrub_pending (void)
1589
3.25k
{
1590
3.25k
  size_t len = 0;
1591
3.25k
  if (saved_input)
1592
584
    len += saved_input_len;
1593
3.25k
  if (state == -1)
1594
144
    len += strlen (out_string);
1595
3.25k
  return len;
1596
3.25k
}