Coverage Report

Created: 2026-07-12 09:22

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/binutils-gdb/gas/macro.c
Line
Count
Source
1
/* macro.c - macro support for gas
2
   Copyright (C) 1994-2026 Free Software Foundation, Inc.
3
4
   Written by Steve and Judy Chamberlain of Cygnus Support,
5
      sac@cygnus.com
6
7
   This file is part of GAS, the GNU Assembler.
8
9
   GAS is free software; you can redistribute it and/or modify
10
   it under the terms of the GNU General Public License as published by
11
   the Free Software Foundation; either version 3, or (at your option)
12
   any later version.
13
14
   GAS is distributed in the hope that it will be useful,
15
   but WITHOUT ANY WARRANTY; without even the implied warranty of
16
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17
   GNU General Public License for more details.
18
19
   You should have received a copy of the GNU General Public License
20
   along with GAS; see the file COPYING.  If not, write to the Free
21
   Software Foundation, 51 Franklin Street - Fifth Floor, Boston, MA
22
   02110-1301, USA.  */
23
24
#include "as.h"
25
#include "safe-ctype.h"
26
#include "sb.h"
27
#include "macro.h"
28
29
/* The routines in this file handle macro definition and expansion.
30
   They are called by gas.  */
31
32
/* The macro hash table.  */
33
34
htab_t macro_hash;
35
36
/* Whether any macros have been defined.  */
37
38
int macro_defined;
39
40
/* Whether we should strip '@' characters.  */
41
42
28.1M
#define macro_strip_at false
43
44
/* Number of macro expansions that have been done.  */
45
46
static unsigned int macro_number;
47
48
static void free_macro (macro_entry *);
49
50
static void
51
macro_del_f (void *ent)
52
727
{
53
727
  string_tuple_t *tuple = ent;
54
727
  free_macro ((macro_entry *) tuple->value);
55
727
}
56
57
/* Initialize macro processing.  */
58
59
void
60
macro_init (void)
61
584
{
62
584
  macro_hash = htab_create_alloc (16, hash_string_tuple, eq_string_tuple,
63
584
          macro_del_f, notes_calloc, NULL);
64
584
  macro_defined = 0;
65
584
}
66
67
void
68
macro_end (void)
69
584
{
70
584
  if (ENABLE_LEAK_CHECK)
71
584
    htab_delete (macro_hash);
72
584
}
73
74
/* Read input lines till we get to a TO string.
75
   Increase nesting depth if we get a FROM string.
76
   Put the results into sb at PTR.
77
   FROM may be NULL (or will be ignored) if TO is "ENDR".
78
   Add a new input line to an sb using GET_LINE.
79
   Return 1 on success, 0 on unexpected EOF.  */
80
81
int
82
buffer_and_nest (const char *from, const char *to, sb *ptr,
83
     size_t (*get_line) (sb *))
84
2.92k
{
85
2.92k
  size_t from_len;
86
2.92k
  size_t to_len = strlen (to);
87
2.92k
  int depth = 1;
88
2.92k
  size_t line_start, more;
89
90
2.92k
  if (to_len == 4 && strcasecmp (to, "ENDR") == 0)
91
1.42k
    {
92
1.42k
      from = NULL;
93
1.42k
      from_len = 0;
94
1.42k
    }
95
1.49k
  else
96
1.49k
    from_len = strlen (from);
97
98
  /* Record the present source position, such that diagnostics and debug info
99
     can be properly associated with the respective original lines, rather
100
     than with the line of the ending directive (TO).  */
101
2.92k
  {
102
2.92k
    unsigned int line;
103
2.92k
    char *linefile;
104
105
2.92k
    const char *prefix = flag_m68k_mri ? "" : ".";
106
2.92k
    const char *file = as_where_top (&line);
107
108
2.92k
    if (*input_line_pointer == '\n')
109
1.32k
      line++;
110
2.92k
    if (file)
111
2.92k
      linefile = xasprintf ("\t%slinefile %u \"%s\"", prefix, line, file);
112
0
    else
113
0
      linefile = xasprintf ("\t%slinefile %u .", prefix, line);
114
2.92k
    sb_add_string (ptr, linefile);
115
2.92k
    xfree (linefile);
116
2.92k
  }
117
118
2.92k
  line_start = ptr->len;
119
2.92k
  more = get_line (ptr);
120
609k
  while (more)
121
609k
    {
122
      /* Try to find the first pseudo op on the line.  */
123
609k
      size_t i = line_start;
124
609k
      bool had_colon = false;
125
126
      /* With normal syntax we can suck what we want till we get
127
   to the dot.  With the alternate, labels have to start in
128
   the first column, since we can't tell what's a label and
129
   what's a pseudoop.  */
130
131
609k
      if (! LABELS_WITHOUT_COLONS)
132
609k
  {
133
    /* Skip leading whitespace.  */
134
609k
    i = sb_skip_white (i, ptr);
135
609k
  }
136
137
609k
      for (;;)
138
685k
  {
139
    /* Skip over a label, if any.  */
140
685k
    if (i >= ptr->len || ! is_name_beginner (ptr->ptr[i]))
141
225k
      break;
142
460k
    i++;
143
2.92M
    while (i < ptr->len && is_part_of_name (ptr->ptr[i]))
144
2.46M
      i++;
145
460k
    if (i < ptr->len && is_name_ender (ptr->ptr[i]))
146
0
      i++;
147
    /* Skip whitespace.  */
148
460k
    i = sb_skip_white (i, ptr);
149
    /* Check for the colon.  */
150
460k
    if (i >= ptr->len || ptr->ptr[i] != ':')
151
384k
      {
152
        /* LABELS_WITHOUT_COLONS doesn't mean we cannot have a
153
     colon after a label.  If we do have a colon on the
154
     first label then handle more than one label on the
155
     line, assuming that each label has a colon.  */
156
384k
        if (LABELS_WITHOUT_COLONS && !had_colon)
157
0
    break;
158
384k
        i = line_start;
159
384k
        break;
160
384k
      }
161
75.9k
    i++;
162
75.9k
    line_start = i;
163
75.9k
    had_colon = true;
164
75.9k
  }
165
166
      /* Skip trailing whitespace.  */
167
609k
      i = sb_skip_white (i, ptr);
168
169
609k
      if (i < ptr->len && (ptr->ptr[i] == '.'
170
263k
         || NO_PSEUDO_DOT
171
263k
         || flag_mri))
172
462k
  {
173
462k
    if (! flag_m68k_mri && ptr->ptr[i] == '.')
174
202k
      i++;
175
462k
    size_t len = ptr->len - i;
176
462k
    if (from == NULL)
177
457k
      {
178
457k
        if (len >= 5 && strncasecmp (ptr->ptr + i, "IREPC", 5) == 0)
179
0
    from_len = 5;
180
457k
        else if (len >= 4 && strncasecmp (ptr->ptr + i, "IREP", 4) == 0)
181
0
    from_len = 4;
182
457k
        else if (len >= 4 && strncasecmp (ptr->ptr + i, "IRPC", 4) == 0)
183
17
    from_len = 4;
184
457k
        else if (len >= 4 && strncasecmp (ptr->ptr + i, "REPT", 4) == 0)
185
3
    from_len = 4;
186
457k
        else if (len >= 3 && strncasecmp (ptr->ptr + i, "IRP", 3) == 0)
187
3
    from_len = 3;
188
457k
        else if (len >= 3 && strncasecmp (ptr->ptr + i, "REP", 3) == 0)
189
11
    from_len = 3;
190
457k
        else
191
457k
    from_len = 0;
192
457k
      }
193
462k
    if ((from != NULL
194
462k
         ? (len >= from_len
195
1.73k
      && strncasecmp (ptr->ptr + i, from, from_len) == 0)
196
462k
         : from_len > 0)
197
36
        && (len == from_len
198
36
      || ! (is_part_of_name (ptr->ptr[i + from_len])
199
27
      || is_name_ender (ptr->ptr[i + from_len]))))
200
27
      depth++;
201
462k
    if (len >= to_len
202
425k
        && strncasecmp (ptr->ptr + i, to, to_len) == 0
203
2.71k
        && (len == to_len
204
509
      || ! (is_part_of_name (ptr->ptr[i + to_len])
205
499
      || is_name_ender (ptr->ptr[i + to_len]))))
206
2.70k
      {
207
2.70k
        depth--;
208
2.70k
        if (depth == 0)
209
2.68k
    {
210
      /* Reset the string to not include the ending rune.  */
211
2.68k
      ptr->len = line_start;
212
213
      /* With the ending directive consumed here, announce the
214
         line for macro-expanded listings. */
215
2.68k
      if (listing & LISTING_MACEXP)
216
0
        listing_newline (NULL);
217
2.68k
      break;
218
2.68k
    }
219
2.70k
      }
220
221
    /* PR gas/16908
222
       Apply .linefile directives that appear within the macro, alongside
223
       keeping them for later expansion of the macro.  */
224
460k
    if (from != NULL && strcasecmp (from, "MACRO") == 0
225
3.73k
        && len >= 8 && strncasecmp (ptr->ptr + i, "linefile", 8) == 0)
226
650
      {
227
650
        sb_add_char (ptr, more);
228
650
        temp_ilp (sb_terminate (ptr) + i + 8);
229
650
        s_linefile (0);
230
650
        restore_ilp ();
231
650
        line_start = ptr->len;
232
650
        more = get_line (ptr);
233
650
        continue;
234
650
      }
235
460k
  }
236
237
      /* Add the original end-of-line char to the end and keep running.  */
238
606k
      sb_add_char (ptr, more);
239
606k
      line_start = ptr->len;
240
606k
      more = get_line (ptr);
241
606k
    }
242
243
  /* Return 1 on success, 0 on unexpected EOF.  */
244
2.92k
  return depth == 0;
245
2.92k
}
246
247
/* Pick up a token.  */
248
249
static size_t
250
get_token (size_t idx, sb *in, sb *name)
251
2.34M
{
252
2.34M
  if (idx < in->len
253
2.34M
      && is_name_beginner (in->ptr[idx]))
254
2.01M
    {
255
2.01M
      sb_add_char (name, in->ptr[idx++]);
256
14.3M
      while (idx < in->len
257
14.3M
       && is_part_of_name (in->ptr[idx]))
258
12.3M
  {
259
12.3M
    sb_add_char (name, in->ptr[idx++]);
260
12.3M
  }
261
2.01M
      if (idx < in->len
262
2.01M
       && is_name_ender (in->ptr[idx]))
263
0
  {
264
0
    sb_add_char (name, in->ptr[idx++]);
265
0
  }
266
2.01M
    }
267
  /* Ignore trailing &.  */
268
2.34M
  if (flag_macro_alternate && idx < in->len && in->ptr[idx] == '&')
269
0
    idx++;
270
2.34M
  return idx;
271
2.34M
}
272
273
/* Pick up a string.  */
274
275
static size_t
276
getstring (size_t idx, sb *in, sb *acc)
277
88
{
278
176
  while (idx < in->len
279
130
   && (in->ptr[idx] == '"'
280
71
       || (in->ptr[idx] == '<' && (flag_macro_alternate || flag_mri))
281
42
       || (in->ptr[idx] == '\'' && flag_macro_alternate)))
282
88
    {
283
88
      if (in->ptr[idx] == '<')
284
29
  {
285
29
    int nest = 0;
286
29
    idx++;
287
113
    while (idx < in->len)
288
112
      {
289
112
        if (in->ptr[idx] == '!' && idx + 1 < in->len)
290
0
    idx++;
291
112
        else if (in->ptr[idx] == '>')
292
28
    {
293
28
      if (nest == 0)
294
28
        {
295
28
          idx++;
296
28
          break;
297
28
        }
298
0
      nest--;
299
0
    }
300
84
        else if (in->ptr[idx] == '<')
301
0
    nest++;
302
303
84
        sb_add_char (acc, in->ptr[idx]);
304
84
        idx++;
305
84
      }
306
29
  }
307
59
      else if (in->ptr[idx] == '"' || in->ptr[idx] == '\'')
308
59
  {
309
59
    char tchar = in->ptr[idx];
310
59
    int escaped = 0;
311
312
59
    idx++;
313
356
    while (idx < in->len)
314
321
      {
315
321
        if (in->ptr[idx - 1] == '\\')
316
2
    escaped ^= 1;
317
319
        else
318
319
    escaped = 0;
319
320
321
        if (flag_macro_alternate
321
0
      && in->ptr[idx] == '!' && idx + 1 < in->len)
322
0
    {
323
0
      idx++;
324
0
    }
325
321
        else if (!escaped && in->ptr[idx] == tchar)
326
47
    {
327
47
      idx++;
328
47
      if (idx >= in->len || in->ptr[idx] != tchar)
329
24
        break;
330
47
    }
331
297
        sb_add_char (acc, in->ptr[idx]);
332
297
        idx++;
333
297
      }
334
59
  }
335
88
    }
336
337
88
  return idx;
338
88
}
339
340
/* Fetch string from the input stream,
341
   rules:
342
    %<expr>   -> return string of decimal value of <expr>
343
    "string"    -> return string
344
    (string)    -> return (string-including-whitespaces)
345
    xyx<whitespace>     -> return xyz.  */
346
347
static size_t
348
get_any_string (size_t idx, sb *in, sb *out)
349
399
{
350
399
  sb_reset (out);
351
399
  idx = sb_skip_white (idx, in);
352
353
399
  if (idx < in->len)
354
398
    {
355
398
      if (in->ptr[idx] == '%' && flag_macro_alternate)
356
0
  {
357
    /* Turn the following expression into a string.  */
358
0
    expressionS ex;
359
0
    char buf[64];
360
361
0
    sb_terminate (in);
362
363
0
    temp_ilp (in->ptr + idx + 1);
364
0
    expression_and_evaluate (&ex);
365
0
    idx = input_line_pointer - in->ptr;
366
0
    restore_ilp ();
367
368
0
    if (ex.X_op != O_constant)
369
0
      as_bad (_("%% operator needs absolute expression"));
370
371
0
    sprintf (buf, "%" PRId64, (int64_t) ex.X_add_number);
372
0
    sb_add_string (out, buf);
373
0
  }
374
398
      else if (in->ptr[idx] == '"'
375
339
         || (in->ptr[idx] == '<' && (flag_macro_alternate || flag_mri))
376
310
         || (flag_macro_alternate && in->ptr[idx] == '\''))
377
88
  {
378
88
    if (flag_macro_alternate && ! macro_strip_at && in->ptr[idx] != '<')
379
0
      {
380
        /* Keep the quotes.  */
381
0
        sb_add_char (out, '"');
382
0
        idx = getstring (idx, in, out);
383
0
        sb_add_char (out, '"');
384
0
      }
385
88
    else
386
88
      {
387
88
        idx = getstring (idx, in, out);
388
88
      }
389
88
  }
390
310
      else
391
310
  {
392
310
    char *br_buf = XNEWVEC (char, 1);
393
310
    char *in_br = br_buf;
394
395
310
    *in_br = '\0';
396
3.65k
    while (idx < in->len
397
3.59k
     && (*in_br || !is_whitespace (in->ptr[idx]))
398
3.54k
     && in->ptr[idx] != ','
399
3.37k
     && (in->ptr[idx] != '<'
400
48
         || (! flag_macro_alternate && ! flag_mri)))
401
3.34k
      {
402
3.34k
        char tchar = in->ptr[idx];
403
404
3.34k
        switch (tchar)
405
3.34k
    {
406
7
    case '"':
407
7
    case '\'':
408
7
      sb_add_char (out, in->ptr[idx++]);
409
8
      while (idx < in->len
410
2
       && in->ptr[idx] != tchar)
411
1
        sb_add_char (out, in->ptr[idx++]);
412
7
      if (idx == in->len)
413
6
        {
414
6
          free (br_buf);
415
6
          return idx;
416
6
        }
417
1
      break;
418
36
    case '(':
419
39
    case '[':
420
39
      if (in_br > br_buf)
421
0
        --in_br;
422
39
      else
423
39
        {
424
39
          br_buf = XNEWVEC (char, strlen (in_br) + 2);
425
39
          strcpy (br_buf + 1, in_br);
426
39
          free (in_br);
427
39
          in_br = br_buf;
428
39
        }
429
39
      *in_br = tchar;
430
39
      break;
431
60
    case ')':
432
60
      if (*in_br == '(')
433
28
        ++in_br;
434
60
      break;
435
60
    case ']':
436
60
      if (*in_br == '[')
437
0
        ++in_br;
438
60
      break;
439
3.34k
    }
440
3.34k
        sb_add_char (out, tchar);
441
3.34k
        ++idx;
442
3.34k
      }
443
304
    free (br_buf);
444
304
  }
445
398
    }
446
447
393
  return idx;
448
399
}
449
450
/* Allocate a new formal.  */
451
452
static formal_entry *
453
new_formal (void)
454
4.38k
{
455
4.38k
  formal_entry *formal;
456
457
4.38k
  formal = XNEW (formal_entry);
458
459
4.38k
  sb_new (&formal->name);
460
4.38k
  sb_new (&formal->def);
461
4.38k
  sb_new (&formal->actual);
462
4.38k
  formal->next = NULL;
463
4.38k
  formal->type = FORMAL_OPTIONAL;
464
4.38k
  return formal;
465
4.38k
}
466
467
/* Free a formal.  */
468
469
static void
470
del_formal (formal_entry *formal)
471
4.38k
{
472
4.38k
  sb_kill (&formal->actual);
473
4.38k
  sb_kill (&formal->def);
474
4.38k
  sb_kill (&formal->name);
475
4.38k
  free (formal);
476
4.38k
}
477
478
/* Pick up the formal parameters of a macro definition.  */
479
480
static size_t
481
do_formals (macro_entry *macro, size_t idx, sb *in)
482
1.49k
{
483
1.49k
  formal_entry **p = &macro->formals;
484
1.49k
  const char *name;
485
486
1.49k
  idx = sb_skip_white (idx, in);
487
5.01k
  while (idx < in->len)
488
3.54k
    {
489
3.54k
      formal_entry *formal = new_formal ();
490
3.54k
      size_t cidx;
491
492
3.54k
      idx = get_token (idx, in, &formal->name);
493
3.54k
      if (formal->name.len == 0)
494
28
  {
495
28
    if (macro->formal_count)
496
27
      --idx;
497
28
    del_formal (formal);  /* 'formal' goes out of scope.  */
498
28
    break;
499
28
  }
500
3.51k
      idx = sb_skip_white (idx, in);
501
      /* This is a formal.  */
502
3.51k
      name = sb_terminate (&formal->name);
503
3.51k
      if (! flag_mri
504
1.63k
    && idx < in->len
505
977
    && in->ptr[idx] == ':'
506
0
    && (! is_name_beginner (':')
507
0
        || idx + 1 >= in->len
508
0
        || ! is_part_of_name (in->ptr[idx + 1])))
509
0
  {
510
    /* Got a qualifier.  */
511
0
    sb qual;
512
513
0
    sb_new (&qual);
514
0
    idx = get_token (sb_skip_white (idx + 1, in), in, &qual);
515
0
    sb_terminate (&qual);
516
0
    if (qual.len == 0)
517
0
      as_bad_where (macro->file,
518
0
        macro->line,
519
0
        _("Missing parameter qualifier for `%s' in macro `%s'"),
520
0
        name,
521
0
        macro->name);
522
0
    else if (strcmp (qual.ptr, "req") == 0)
523
0
      formal->type = FORMAL_REQUIRED;
524
0
    else if (strcmp (qual.ptr, "vararg") == 0)
525
0
      formal->type = FORMAL_VARARG;
526
0
    else
527
0
      as_bad_where (macro->file,
528
0
        macro->line,
529
0
        _("`%s' is not a valid parameter qualifier for `%s' in macro `%s'"),
530
0
        qual.ptr,
531
0
        name,
532
0
        macro->name);
533
0
    sb_kill (&qual);
534
0
    idx = sb_skip_white (idx, in);
535
0
  }
536
3.51k
      if (idx < in->len && in->ptr[idx] == '=')
537
8
  {
538
    /* Got a default.  */
539
8
    idx = get_any_string (idx + 1, in, &formal->def);
540
8
    idx = sb_skip_white (idx, in);
541
8
    if (formal->type == FORMAL_REQUIRED)
542
0
      {
543
0
        sb_reset (&formal->def);
544
0
        as_warn_where (macro->file,
545
0
          macro->line,
546
0
          _("Pointless default value for required parameter `%s' in macro `%s'"),
547
0
          name,
548
0
          macro->name);
549
0
      }
550
8
  }
551
552
      /* Add to macro's hash table.  */
553
3.51k
      if (str_hash_insert (macro->formal_hash, name, formal, 0) != NULL)
554
1
  {
555
1
    as_bad_where (macro->file, macro->line,
556
1
      _("A parameter named `%s' "
557
1
        "already exists for macro `%s'"),
558
1
      name, macro->name);
559
1
  }
560
561
3.51k
      formal->index = macro->formal_count++;
562
3.51k
      *p = formal;
563
3.51k
      p = &formal->next;
564
3.51k
      if (formal->type == FORMAL_VARARG)
565
0
  break;
566
3.51k
      cidx = idx;
567
3.51k
      idx = sb_skip_comma (idx, in);
568
3.51k
      if (idx != cidx && idx >= in->len)
569
0
  {
570
0
    idx = cidx;
571
0
    break;
572
0
  }
573
3.51k
    }
574
575
1.49k
  if (flag_mri)
576
837
    {
577
837
      formal_entry *formal = new_formal ();
578
579
      /* Add a special NARG formal, which macro_expand will set to the
580
   number of arguments.  */
581
      /* The same MRI assemblers which treat '@' characters also use
582
   the name $NARG.  At least until we find an exception.  */
583
837
      if (macro_strip_at)
584
0
  name = "$NARG";
585
837
      else
586
837
  name = "NARG";
587
588
837
      sb_add_string (&formal->name, name);
589
590
      /* Add to macro's hash table.  */
591
837
      if (str_hash_insert (macro->formal_hash, name, formal, 0) != NULL)
592
0
  {
593
0
    as_bad_where (macro->file, macro->line,
594
0
      _("Reserved word `%s' used as parameter in macro `%s'"),
595
0
      name, macro->name);
596
0
  }
597
598
837
      formal->index = NARG_INDEX;
599
837
      *p = formal;
600
837
    }
601
602
1.49k
  return idx;
603
1.49k
}
604
605
/* Free the memory allocated to a macro.  */
606
607
static void
608
free_macro (macro_entry *macro)
609
1.49k
{
610
1.49k
  formal_entry *formal;
611
612
5.85k
  for (formal = macro->formals; formal; )
613
4.35k
    {
614
4.35k
      formal_entry *f;
615
616
4.35k
      f = formal;
617
4.35k
      formal = formal->next;
618
4.35k
      del_formal (f);
619
4.35k
    }
620
1.49k
  htab_delete (macro->formal_hash);
621
1.49k
  sb_kill (&macro->sub);
622
1.49k
  free ((char *) macro->name);
623
1.49k
  free (macro);
624
1.49k
}
625
626
/* Define a new macro.  */
627
628
macro_entry *
629
define_macro (sb *in, sb *label, size_t (*get_line) (sb *))
630
1.49k
{
631
1.49k
  macro_entry *macro;
632
1.49k
  sb name;
633
1.49k
  size_t idx;
634
1.49k
  const char *error = NULL;
635
636
1.49k
  macro = XNEW (macro_entry);
637
1.49k
  sb_new (&macro->sub);
638
1.49k
  sb_new (&name);
639
1.49k
  macro->file = as_where (&macro->line);
640
641
1.49k
  macro->formal_count = 0;
642
1.49k
  macro->formals = 0;
643
1.49k
  macro->formal_hash = str_htab_create ();
644
1.49k
  macro->count = 0;
645
646
1.49k
  idx = sb_skip_white (0, in);
647
1.49k
  if (! buffer_and_nest ("MACRO", "ENDM", &macro->sub, get_line))
648
104
    error = _("unexpected end of file in macro `%s' definition");
649
1.49k
  if (label != NULL && label->len != 0)
650
1.42k
    {
651
1.42k
      sb_add_sb (&name, label);
652
1.42k
      macro->name = sb_terminate (&name);
653
1.42k
      if (idx < in->len && in->ptr[idx] == '(')
654
61
  {
655
    /* It's the label: MACRO (formals,...)  sort  */
656
61
    idx = do_formals (macro, idx + 1, in);
657
61
    if (idx < in->len && in->ptr[idx] == ')')
658
0
      idx = sb_skip_white (idx + 1, in);
659
61
    else if (!error)
660
0
      error = _("missing `)' after formals in macro definition `%s'");
661
61
  }
662
1.36k
      else
663
1.36k
  {
664
    /* It's the label: MACRO formals,...  sort  */
665
1.36k
    idx = do_formals (macro, idx, in);
666
1.36k
  }
667
1.42k
    }
668
69
  else
669
69
    {
670
69
      size_t cidx;
671
672
69
      idx = get_token (idx, in, &name);
673
69
      macro->name = sb_terminate (&name);
674
69
      if (name.len == 0)
675
15
  error = _("Missing macro name");
676
69
      cidx = sb_skip_white (idx, in);
677
69
      idx = sb_skip_comma (cidx, in);
678
69
      if (idx == cidx || idx < in->len)
679
69
  idx = do_formals (macro, idx, in);
680
0
      else
681
0
  idx = cidx;
682
69
    }
683
1.49k
  if (!error && idx < in->len)
684
1
    error = _("Bad parameter list for macro `%s'");
685
686
  /* And stick it in the macro hash table.  */
687
19.3k
  for (idx = 0; idx < name.len; idx++)
688
17.8k
    name.ptr[idx] = TOLOWER (name.ptr[idx]);
689
1.49k
  if (!error)
690
1.39k
    {
691
1.39k
      if (str_hash_insert (macro_hash, macro->name, macro, 0) != NULL)
692
665
  error = _("Macro `%s' was already defined");
693
1.39k
    }
694
695
1.49k
  if (!error)
696
727
    macro_defined = 1;
697
770
  else
698
770
    {
699
770
      as_bad_where (macro->file, macro->line, error, macro->name);
700
770
      free_macro (macro);
701
770
      macro = NULL;
702
770
    }
703
704
1.49k
  return macro;
705
1.49k
}
706
707
/* Scan a token, and then skip KIND.  */
708
709
static size_t
710
get_apost_token (size_t idx, sb *in, sb *name, int kind)
711
2.33M
{
712
2.33M
  idx = get_token (idx, in, name);
713
2.33M
  if (idx < in->len
714
2.33M
      && in->ptr[idx] == kind
715
3.06k
      && (! flag_mri || macro_strip_at)
716
0
      && (! macro_strip_at || kind == '@'))
717
2.37k
    idx++;
718
2.33M
  return idx;
719
2.33M
}
720
721
/* Substitute the actual value for a formal parameter.  */
722
723
static size_t
724
sub_actual (size_t start, sb *in, sb *t, struct htab *formal_hash,
725
      int kind, sb *out, int copyifnotthere)
726
2.33M
{
727
2.33M
  size_t src;
728
2.33M
  formal_entry *ptr;
729
730
2.33M
  src = get_apost_token (start, in, t, kind);
731
  /* See if it's in the macro's hash table, unless this is
732
     macro_strip_at and kind is '@' and the token did not end in '@'.  */
733
2.33M
  if (macro_strip_at
734
0
      && kind == '@'
735
0
      && (src == start || in->ptr[src - 1] != '@'))
736
0
    ptr = NULL;
737
2.33M
  else
738
2.33M
    ptr = str_hash_find (formal_hash, sb_terminate (t));
739
2.33M
  if (ptr)
740
75.6k
    {
741
75.6k
      if (ptr->actual.len)
742
75.6k
  {
743
75.6k
    sb_add_sb (out, &ptr->actual);
744
75.6k
  }
745
6
      else
746
6
  {
747
6
    sb_add_sb (out, &ptr->def);
748
6
  }
749
75.6k
    }
750
2.25M
  else if (kind == '&')
751
5.48k
    {
752
      /* Doing this permits people to use & in macro bodies.  */
753
5.48k
      sb_add_char (out, '&');
754
5.48k
      sb_add_sb (out, t);
755
5.48k
      if (src != start && in->ptr[src - 1] == '&')
756
2.37k
  sb_add_char (out, '&');
757
5.48k
    }
758
2.24M
  else if (copyifnotthere)
759
1.94M
    {
760
1.94M
      sb_add_sb (out, t);
761
1.94M
    }
762
307k
  else
763
307k
    {
764
307k
      sb_add_char (out, '\\');
765
307k
      sb_add_sb (out, t);
766
307k
    }
767
2.33M
  return src;
768
2.33M
}
769
770
/* Expand the body of a macro.  */
771
772
static const char *
773
macro_expand_body (sb *in, sb *out, formal_entry *formals,
774
       struct htab *formal_hash, const macro_entry *macro,
775
       unsigned int instance)
776
72.7k
{
777
72.7k
  sb t;
778
72.7k
  size_t src = 0;
779
72.7k
  int inquote = 0, macro_line = 0;
780
72.7k
  formal_entry *loclist = NULL;
781
72.7k
  const char *err = NULL;
782
783
72.7k
  sb_new (&t);
784
785
24.2M
  while (src < in->len && !err)
786
24.1M
    {
787
24.1M
      if (in->ptr[src] == '&')
788
19.5k
  {
789
19.5k
    sb_reset (&t);
790
19.5k
    if (flag_mri)
791
14.0k
      {
792
14.0k
        if (src + 1 < in->len && in->ptr[src + 1] == '&')
793
8.24k
    src = sub_actual (src + 2, in, &t, formal_hash, '\'', out, 1);
794
5.76k
        else
795
5.76k
    sb_add_char (out, in->ptr[src++]);
796
14.0k
      }
797
5.48k
    else
798
5.48k
      {
799
        /* Permit macro parameter substitution delineated with
800
     an '&' prefix and optional '&' suffix.  */
801
5.48k
        src = sub_actual (src + 1, in, &t, formal_hash, '&', out, 0);
802
5.48k
      }
803
19.5k
  }
804
24.1M
      else if (in->ptr[src] == '\\')
805
316k
  {
806
316k
    src++;
807
316k
    if (src < in->len && in->ptr[src] == '(')
808
158
      {
809
        /* Sub in till the next ')' literally.  */
810
158
        src++;
811
12.4k
        while (src < in->len && in->ptr[src] != ')')
812
12.3k
    {
813
12.3k
      sb_add_char (out, in->ptr[src++]);
814
12.3k
    }
815
158
        if (src < in->len)
816
138
    src++;
817
20
        else if (!macro)
818
20
    err = _("missing `)'");
819
0
        else
820
0
    as_bad_where (macro->file, macro->line + macro_line, _("missing `)'"));
821
158
      }
822
316k
    else if (src < in->len && in->ptr[src] == '@')
823
319
      {
824
        /* Sub in the total macro invocation number.  */
825
826
319
        char buffer[12];
827
319
        src++;
828
319
        sprintf (buffer, "%u", macro_number);
829
319
        sb_add_string (out, buffer);
830
319
      }
831
316k
    else if (src < in->len && in->ptr[src] == '+')
832
5.21k
      {
833
        /* Sub in the current macro invocation number.  */
834
835
5.21k
        char buffer[12];
836
5.21k
        src++;
837
5.21k
        sprintf (buffer, "%d", instance);
838
5.21k
        sb_add_string (out, buffer);
839
5.21k
      }
840
311k
    else if (src < in->len && in->ptr[src] == '&')
841
4
      {
842
        /* This is a preprocessor variable name, we don't do them
843
     here.  */
844
4
        sb_add_char (out, '\\');
845
4
        sb_add_char (out, '&');
846
4
        src++;
847
4
      }
848
311k
    else if (flag_mri && src < in->len && ISALNUM (in->ptr[src]))
849
3.46k
      {
850
3.46k
        int ind;
851
3.46k
        formal_entry *f;
852
853
3.46k
        if (ISDIGIT (in->ptr[src]))
854
1.74k
    ind = in->ptr[src] - '0';
855
1.72k
        else if (ISUPPER (in->ptr[src]))
856
215
    ind = in->ptr[src] - 'A' + 10;
857
1.50k
        else
858
1.50k
    ind = in->ptr[src] - 'a' + 10;
859
3.46k
        ++src;
860
6.95k
        for (f = formals; f != NULL; f = f->next)
861
3.53k
    {
862
3.53k
      if (f->index == ind - 1)
863
36
        {
864
36
          if (f->actual.len != 0)
865
36
      sb_add_sb (out, &f->actual);
866
0
          else
867
0
      sb_add_sb (out, &f->def);
868
36
          break;
869
36
        }
870
3.53k
    }
871
3.46k
      }
872
307k
    else
873
307k
      {
874
307k
        sb_reset (&t);
875
307k
        src = sub_actual (src, in, &t, formal_hash, '\'', out, 0);
876
307k
      }
877
316k
  }
878
23.8M
      else if ((flag_macro_alternate || flag_mri)
879
7.74M
         && is_name_beginner (in->ptr[src])
880
2.00M
         && (! inquote
881
993k
       || ! macro_strip_at
882
0
       || (src > 0 && in->ptr[src - 1] == '@')))
883
2.00M
  {
884
2.00M
    if (! macro
885
3.43k
        || src + 5 >= in->len
886
3.40k
        || strncasecmp (in->ptr + src, "LOCAL", 5) != 0
887
0
        || ! is_whitespace (in->ptr[src + 5])
888
        /* PR 11507: Skip keyword LOCAL if it is found inside a quoted string.  */
889
0
        || inquote)
890
2.00M
      {
891
2.00M
        sb_reset (&t);
892
2.00M
        src = sub_actual (src, in, &t, formal_hash,
893
2.00M
        (macro_strip_at && inquote) ? '@' : '\'',
894
2.00M
        out, 1);
895
2.00M
      }
896
0
    else
897
0
      {
898
0
        src = sb_skip_white (src + 5, in);
899
0
        while (in->ptr[src] != '\n')
900
0
    {
901
0
      const char *name;
902
0
      formal_entry *f = new_formal ();
903
904
0
      src = get_token (src, in, &f->name);
905
0
      name = sb_terminate (&f->name);
906
0
      if (str_hash_insert (formal_hash, name, f, 0) != NULL)
907
0
        {
908
0
          as_bad_where (macro->file, macro->line + macro_line,
909
0
            _("`%s' was already used as parameter "
910
0
              "(or another local) name"), name);
911
0
          del_formal (f);
912
0
        }
913
0
      else
914
0
        {
915
0
          static int loccnt;
916
0
          char buf[20];
917
918
0
          f->index = LOCAL_INDEX;
919
0
          f->next = loclist;
920
0
          loclist = f;
921
922
0
          sprintf (buf, IS_ELF ? ".LL%04x" : "LL%04x", ++loccnt);
923
0
          sb_add_string (&f->actual, buf);
924
0
        }
925
926
0
      src = sb_skip_comma (src, in);
927
0
    }
928
0
      }
929
2.00M
  }
930
21.8M
      else if (in->ptr[src] == '"'
931
20.8M
         || (flag_mri && in->ptr[src] == '\''))
932
1.00M
  {
933
1.00M
    inquote = !inquote;
934
1.00M
    sb_add_char (out, in->ptr[src++]);
935
1.00M
  }
936
20.8M
      else if (in->ptr[src] == '@' && macro_strip_at)
937
0
  {
938
0
    ++src;
939
0
    if (src < in->len
940
0
        && in->ptr[src] == '@')
941
0
      {
942
0
        sb_add_char (out, '@');
943
0
        ++src;
944
0
      }
945
0
  }
946
20.8M
      else if (flag_mri
947
5.03M
         && in->ptr[src] == '='
948
126k
         && src + 1 < in->len
949
126k
         && in->ptr[src + 1] == '=')
950
9.48k
  {
951
9.48k
    formal_entry *ptr;
952
953
9.48k
    sb_reset (&t);
954
9.48k
    src = get_token (src + 2, in, &t);
955
9.48k
    ptr = str_hash_find (formal_hash, sb_terminate (&t));
956
9.48k
    if (ptr == NULL)
957
9.48k
      {
958
        /* FIXME: We should really return a warning string here,
959
     but we can't, because the == might be in the MRI
960
     comment field, and, since the nature of the MRI
961
     comment field depends upon the exact instruction
962
     being used, we don't have enough information here to
963
     figure out whether it is or not.  Instead, we leave
964
     the == in place, which should cause a syntax error if
965
     it is not in a comment.  */
966
9.48k
        sb_add_char (out, '=');
967
9.48k
        sb_add_char (out, '=');
968
9.48k
        sb_add_sb (out, &t);
969
9.48k
      }
970
0
    else
971
0
      {
972
0
        if (ptr->actual.len)
973
0
    {
974
0
      sb_add_string (out, "-1");
975
0
    }
976
0
        else
977
0
    {
978
0
      sb_add_char (out, '0');
979
0
    }
980
0
      }
981
9.48k
  }
982
20.8M
      else
983
20.8M
  {
984
20.8M
    if (in->ptr[src] == '\n')
985
1.15M
      ++macro_line;
986
20.8M
    sb_add_char (out, in->ptr[src++]);
987
20.8M
  }
988
24.1M
    }
989
990
72.7k
  sb_kill (&t);
991
992
72.7k
  while (loclist != NULL)
993
0
    {
994
0
      formal_entry *f;
995
0
      const char *name;
996
997
0
      f = loclist->next;
998
0
      name = sb_terminate (&loclist->name);
999
0
      str_hash_delete (formal_hash, name);
1000
0
      del_formal (loclist);
1001
0
      loclist = f;
1002
0
    }
1003
1004
72.7k
  if (!err && (out->len == 0 || out->ptr[out->len - 1] != '\n'))
1005
331
    sb_add_char (out, '\n');
1006
72.7k
  return err;
1007
72.7k
}
1008
1009
/* Assign values to the formal parameters of a macro, and expand the
1010
   body.  */
1011
1012
static const char *
1013
macro_expand (size_t idx, sb *in, macro_entry *m, sb *out)
1014
72
{
1015
72
  sb t;
1016
72
  formal_entry *ptr;
1017
72
  formal_entry *f;
1018
72
  int is_keyword = 0;
1019
72
  int narg = 0;
1020
72
  const char *err = NULL;
1021
1022
72
  sb_new (&t);
1023
1024
  /* Reset any old value the actuals may have.  */
1025
194
  for (f = m->formals; f; f = f->next)
1026
122
    sb_reset (&f->actual);
1027
72
  f = m->formals;
1028
73
  while (f != NULL && f->index < 0)
1029
1
    f = f->next;
1030
1031
72
  if (flag_mri)
1032
52
    {
1033
      /* The macro may be called with an optional qualifier, which may
1034
   be referred to in the macro body as \0.  */
1035
52
      if (idx < in->len && in->ptr[idx] == '.')
1036
0
  {
1037
    /* The Microtec assembler ignores this if followed by a white space.
1038
       (Macro invocation with empty extension) */
1039
0
    idx++;
1040
0
    if (idx < in->len && !is_whitespace (in->ptr[idx]))
1041
0
      {
1042
0
        formal_entry *n = new_formal ();
1043
1044
0
        n->index = QUAL_INDEX;
1045
1046
0
        n->next = m->formals;
1047
0
        m->formals = n;
1048
1049
0
        idx = get_any_string (idx, in, &n->actual);
1050
0
      }
1051
0
  }
1052
52
    }
1053
1054
  /* Peel off the actuals and store them away in the hash tables' actuals.  */
1055
72
  idx = sb_skip_white (idx, in);
1056
143
  while (idx < in->len)
1057
73
    {
1058
      /* Look and see if it's a positional or keyword arg.  */
1059
73
      size_t scan;
1060
1061
73
      sb_reset (&t);
1062
73
      scan = !flag_macro_alternate ? get_token (idx, in, &t) : idx;
1063
1064
73
      if (scan > idx && scan < in->len && in->ptr[scan] == '=')
1065
1
  {
1066
1
    is_keyword = 1;
1067
1068
    /* It's OK to go from positional to keyword.  */
1069
1070
    /* Lookup the formal in the macro's list.  */
1071
1
    ptr = str_hash_find (m->formal_hash, sb_terminate (&t));
1072
1
    if (!ptr)
1073
0
      {
1074
0
        as_bad (_("Parameter named `%s' does not exist for macro `%s'"),
1075
0
          t.ptr,
1076
0
          m->name);
1077
0
        sb_reset (&t);
1078
        /* Skip what would be the actual stuff.  */
1079
0
        idx = get_any_string (scan + 1, in, &t);
1080
0
      }
1081
1
    else
1082
1
      {
1083
        /* Insert this value into the right place.  */
1084
1
        if (ptr->actual.len)
1085
1
    {
1086
1
      as_warn (_("Value for parameter `%s' of macro `%s' was already specified"),
1087
1
         ptr->name.ptr,
1088
1
         m->name);
1089
1
      sb_reset (&ptr->actual);
1090
1
    }
1091
        /* Fetch the actual stuff.  */
1092
1
        idx = get_any_string (scan + 1, in, &ptr->actual);
1093
1
        if (ptr->actual.len > 0)
1094
0
    ++narg;
1095
1
      }
1096
1
  }
1097
72
      else
1098
72
  {
1099
72
    if (is_keyword)
1100
0
      {
1101
0
        err = _("can't mix positional and keyword arguments");
1102
0
        break;
1103
0
      }
1104
1105
72
    if (!f)
1106
10
      {
1107
10
        formal_entry **pf;
1108
10
        int c;
1109
1110
10
        if (!flag_mri)
1111
2
    {
1112
2
      err = _("too many positional arguments");
1113
2
      break;
1114
2
    }
1115
1116
8
        f = new_formal ();
1117
1118
8
        c = -1;
1119
23
        for (pf = &m->formals; *pf != NULL; pf = &(*pf)->next)
1120
15
    if ((*pf)->index >= c)
1121
8
      c = (*pf)->index + 1;
1122
8
        if (c == -1)
1123
0
    c = 0;
1124
8
        *pf = f;
1125
8
        f->index = c;
1126
8
      }
1127
1128
70
    if (f->type != FORMAL_VARARG)
1129
70
      idx = get_any_string (idx, in, &f->actual);
1130
0
    else if (idx < in->len)
1131
0
      {
1132
0
        sb_add_buffer (&f->actual, in->ptr + idx, in->len - idx);
1133
0
        idx = in->len;
1134
0
      }
1135
70
    if (f->actual.len > 0)
1136
64
      ++narg;
1137
70
    do
1138
115
      {
1139
115
        f = f->next;
1140
115
      }
1141
115
    while (f != NULL && f->index < 0);
1142
70
  }
1143
1144
71
      if (! flag_mri)
1145
13
  idx = sb_skip_comma (idx, in);
1146
58
      else
1147
58
  {
1148
58
    if (idx < in->len && in->ptr[idx] == ',')
1149
3
      ++idx;
1150
58
    if (idx < in->len && is_whitespace (in->ptr[idx]))
1151
0
      break;
1152
58
  }
1153
71
    }
1154
1155
72
  if (! err)
1156
70
    {
1157
198
      for (ptr = m->formals; ptr; ptr = ptr->next)
1158
128
  {
1159
128
    if (ptr->type == FORMAL_REQUIRED && ptr->actual.len == 0)
1160
0
      as_bad (_("Missing value for required parameter `%s' of macro `%s'"),
1161
0
        ptr->name.ptr,
1162
0
        m->name);
1163
128
  }
1164
1165
70
      if (flag_mri)
1166
52
  {
1167
52
    ptr = str_hash_find (m->formal_hash,
1168
52
             macro_strip_at ? "$NARG" : "NARG");
1169
52
    if (ptr)
1170
50
      {
1171
50
        char buffer[20];
1172
50
        sprintf (buffer, "%d", narg);
1173
50
        sb_add_string (&ptr->actual, buffer);
1174
50
      }
1175
52
  }
1176
1177
70
      err = macro_expand_body (&m->sub, out, m->formals, m->formal_hash, m,
1178
70
             m->count);
1179
70
    }
1180
1181
  /* Discard any unnamed formal arguments.  */
1182
72
  if (flag_mri)
1183
52
    {
1184
52
      formal_entry **pf;
1185
1186
52
      pf = &m->formals;
1187
168
      while (*pf != NULL)
1188
116
  {
1189
116
    if ((*pf)->name.len != 0)
1190
108
      pf = &(*pf)->next;
1191
8
    else
1192
8
      {
1193
8
        f = (*pf)->next;
1194
8
        del_formal (*pf);
1195
8
        *pf = f;
1196
8
      }
1197
116
  }
1198
52
    }
1199
1200
72
  sb_kill (&t);
1201
72
  if (!err)
1202
70
    {
1203
70
      macro_number++;
1204
70
      m->count++;
1205
70
    }
1206
1207
72
  return err;
1208
72
}
1209
1210
/* Check for a macro.  If one is found, put the expansion into
1211
   *EXPAND.  Return 1 if a macro is found, 0 otherwise.  */
1212
1213
int
1214
check_macro (const char *line, sb *expand,
1215
       const char **error, macro_entry **info)
1216
4.43k
{
1217
4.43k
  const char *s;
1218
4.43k
  char *copy, *cls;
1219
4.43k
  macro_entry *macro;
1220
4.43k
  sb line_sb;
1221
1222
4.43k
  if (! is_name_beginner (*line)
1223
34
      && (! flag_mri || *line != '.'))
1224
34
    return 0;
1225
1226
4.39k
  s = line + 1;
1227
26.0k
  while (is_part_of_name (*s))
1228
21.6k
    ++s;
1229
4.39k
  if (is_name_ender (*s))
1230
0
    ++s;
1231
1232
4.39k
  copy = xmemdup0 (line, s - line);
1233
30.4k
  for (cls = copy; *cls != '\0'; cls ++)
1234
26.0k
    *cls = TOLOWER (*cls);
1235
1236
4.39k
  macro = str_hash_find (macro_hash, copy);
1237
4.39k
  free (copy);
1238
1239
4.39k
  if (macro == NULL)
1240
4.32k
    return 0;
1241
1242
  /* Wrap the line up in an sb.  */
1243
72
  sb_new (&line_sb);
1244
581
  while (*s != '\0' && *s != '\n' && *s != '\r')
1245
509
    sb_add_char (&line_sb, *s++);
1246
1247
72
  sb_new (expand);
1248
72
  *error = macro_expand (0, &line_sb, macro, expand);
1249
1250
72
  sb_kill (&line_sb);
1251
1252
  /* Export the macro information if requested.  */
1253
72
  if (info)
1254
72
    *info = macro;
1255
1256
72
  return 1;
1257
4.39k
}
1258
1259
/* Delete a macro.  */
1260
1261
void
1262
delete_macro (const char *name)
1263
2
{
1264
2
  char *copy;
1265
2
  size_t i, len;
1266
2
  macro_entry *macro;
1267
1268
2
  len = strlen (name);
1269
2
  copy = XNEWVEC (char, len + 1);
1270
6
  for (i = 0; i < len; ++i)
1271
4
    copy[i] = TOLOWER (name[i]);
1272
2
  copy[i] = '\0';
1273
1274
2
  macro = str_hash_find (macro_hash, copy);
1275
2
  if (macro != NULL)
1276
0
    str_hash_delete (macro_hash, copy);
1277
2
  else
1278
2
    as_warn (_("Attempt to purge non-existing macro `%s'"), copy);
1279
2
  free (copy);
1280
2
}
1281
1282
/* Handle the MRI IRP and IRPC pseudo-ops.  These are handled as a
1283
   combined macro definition and execution.  This returns NULL on
1284
   success, or an error message otherwise.  */
1285
1286
const char *
1287
expand_irp (int irpc, size_t idx, sb *in, sb *out, size_t (*get_line) (sb *))
1288
1.31k
{
1289
1.31k
  sb sub;
1290
1.31k
  formal_entry f;
1291
1.31k
  struct htab *h;
1292
1.31k
  const char *err = NULL;
1293
1294
1.31k
  idx = sb_skip_white (idx, in);
1295
1296
1.31k
  sb_new (&sub);
1297
1.31k
  if (! buffer_and_nest (NULL, "ENDR", &sub, get_line))
1298
115
    {
1299
115
      err = _("unexpected end of file in irp or irpc");
1300
115
      goto out2;
1301
115
    }
1302
1303
1.20k
  sb_new (&f.name);
1304
1.20k
  sb_new (&f.def);
1305
1.20k
  sb_new (&f.actual);
1306
1307
1.20k
  idx = get_token (idx, in, &f.name);
1308
1.20k
  if (f.name.len == 0)
1309
6
    {
1310
6
      err = _("missing model parameter");
1311
6
      goto out1;
1312
6
    }
1313
1314
1.19k
  h = str_htab_create ();
1315
1316
1.19k
  str_hash_insert (h, sb_terminate (&f.name), &f, 0);
1317
1318
1.19k
  f.index = 1;
1319
1.19k
  f.next = NULL;
1320
1.19k
  f.type = FORMAL_OPTIONAL;
1321
1322
1.19k
  sb_reset (out);
1323
1324
1.19k
  idx = sb_skip_comma (idx, in);
1325
1.19k
  if (idx >= in->len)
1326
0
    {
1327
      /* Expand once with a null string.  */
1328
0
      err = macro_expand_body (&sub, out, &f, h, NULL, 0);
1329
0
    }
1330
1.19k
  else
1331
1.19k
    {
1332
1.19k
      bool in_quotes = false;
1333
1.19k
      unsigned int instance = 0;
1334
1335
74.9k
      while (idx < in->len)
1336
73.7k
  {
1337
73.7k
    if (!irpc)
1338
320
      idx = get_any_string (idx, in, &f.actual);
1339
73.4k
    else
1340
73.4k
      {
1341
73.4k
        if (in->ptr[idx] == '"')
1342
1.04k
    {
1343
1.04k
      in_quotes = ! in_quotes;
1344
1.04k
      ++idx;
1345
1346
1.04k
      if (! in_quotes)
1347
319
        {
1348
319
          idx = sb_skip_white (idx, in);
1349
319
          if (idx >= in->len)
1350
8
      break;
1351
319
        }
1352
1.03k
      continue;
1353
1.04k
    }
1354
72.4k
        sb_reset (&f.actual);
1355
72.4k
        sb_add_char (&f.actual, in->ptr[idx]);
1356
72.4k
        ++idx;
1357
72.4k
      }
1358
1359
72.7k
    err = macro_expand_body (&sub, out, &f, h, NULL, instance);
1360
72.7k
    ++instance;
1361
72.7k
    if (err != NULL)
1362
20
      break;
1363
72.7k
    if (!irpc)
1364
300
      idx = sb_skip_comma (idx, in);
1365
72.4k
    else if (! in_quotes)
1366
71.3k
      idx = sb_skip_white (idx, in);
1367
72.7k
  }
1368
1.19k
    }
1369
1370
1.19k
  htab_delete (h);
1371
1.20k
 out1:
1372
1.20k
  sb_kill (&f.actual);
1373
1.20k
  sb_kill (&f.def);
1374
1.20k
  sb_kill (&f.name);
1375
1.31k
 out2:
1376
1.31k
  sb_kill (&sub);
1377
1378
1.31k
  return err;
1379
1.20k
}