Coverage Report

Created: 2026-09-14 08:07

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