Coverage Report

Created: 2026-05-11 07:54

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
1.11M
#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
354
{
53
354
  string_tuple_t *tuple = ent;
54
354
  free_macro ((macro_entry *) tuple->value);
55
354
}
56
57
/* Initialize macro processing.  */
58
59
void
60
macro_init (void)
61
478
{
62
478
  macro_hash = htab_create_alloc (16, hash_string_tuple, eq_string_tuple,
63
478
          macro_del_f, notes_calloc, NULL);
64
478
  macro_defined = 0;
65
478
}
66
67
void
68
macro_end (void)
69
478
{
70
478
  if (ENABLE_LEAK_CHECK)
71
478
    htab_delete (macro_hash);
72
478
}
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
1.88k
{
85
1.88k
  size_t from_len;
86
1.88k
  size_t to_len = strlen (to);
87
1.88k
  int depth = 1;
88
1.88k
  size_t line_start, more;
89
90
1.88k
  if (to_len == 4 && strcasecmp (to, "ENDR") == 0)
91
1.17k
    {
92
1.17k
      from = NULL;
93
1.17k
      from_len = 0;
94
1.17k
    }
95
710
  else
96
710
    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
1.88k
  {
102
1.88k
    unsigned int line;
103
1.88k
    char *linefile;
104
105
1.88k
    const char *prefix = flag_m68k_mri ? "" : ".";
106
1.88k
    const char *file = as_where_top (&line);
107
108
1.88k
    if (*input_line_pointer == '\n')
109
1.08k
      line++;
110
1.88k
    if (file)
111
1.88k
      linefile = xasprintf ("\t%slinefile %u \"%s\"", prefix, line, file);
112
0
    else
113
0
      linefile = xasprintf ("\t%slinefile %u .", prefix, line);
114
1.88k
    sb_add_string (ptr, linefile);
115
1.88k
    xfree (linefile);
116
1.88k
  }
117
118
1.88k
  line_start = ptr->len;
119
1.88k
  more = get_line (ptr);
120
13.2k
  while (more)
121
13.0k
    {
122
      /* Try to find the first pseudo op on the line.  */
123
13.0k
      size_t i = line_start;
124
13.0k
      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
13.0k
      if (! LABELS_WITHOUT_COLONS)
132
13.0k
  {
133
    /* Skip leading whitespace.  */
134
13.0k
    i = sb_skip_white (i, ptr);
135
13.0k
  }
136
137
13.0k
      for (;;)
138
13.2k
  {
139
    /* Skip over a label, if any.  */
140
13.2k
    if (i >= ptr->len || ! is_name_beginner (ptr->ptr[i]))
141
4.21k
      break;
142
9.00k
    i++;
143
52.6k
    while (i < ptr->len && is_part_of_name (ptr->ptr[i]))
144
43.6k
      i++;
145
9.00k
    if (i < ptr->len && is_name_ender (ptr->ptr[i]))
146
0
      i++;
147
    /* Skip whitespace.  */
148
9.00k
    i = sb_skip_white (i, ptr);
149
    /* Check for the colon.  */
150
9.00k
    if (i >= ptr->len || ptr->ptr[i] != ':')
151
8.87k
      {
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
8.87k
        if (LABELS_WITHOUT_COLONS && !had_colon)
157
0
    break;
158
8.87k
        i = line_start;
159
8.87k
        break;
160
8.87k
      }
161
135
    i++;
162
135
    line_start = i;
163
135
    had_colon = true;
164
135
  }
165
166
      /* Skip trailing whitespace.  */
167
13.0k
      i = sb_skip_white (i, ptr);
168
169
13.0k
      if (i < ptr->len && (ptr->ptr[i] == '.'
170
4.91k
         || NO_PSEUDO_DOT
171
4.91k
         || flag_mri))
172
7.56k
  {
173
7.56k
    if (! flag_m68k_mri && ptr->ptr[i] == '.')
174
5.41k
      i++;
175
7.56k
    size_t len = ptr->len - i;
176
7.56k
    if (from == NULL)
177
4.75k
      {
178
4.75k
        if (len >= 5 && strncasecmp (ptr->ptr + i, "IREPC", 5) == 0)
179
0
    from_len = 5;
180
4.75k
        else if (len >= 4 && strncasecmp (ptr->ptr + i, "IREP", 4) == 0)
181
1
    from_len = 4;
182
4.75k
        else if (len >= 4 && strncasecmp (ptr->ptr + i, "IRPC", 4) == 0)
183
3
    from_len = 4;
184
4.74k
        else if (len >= 4 && strncasecmp (ptr->ptr + i, "REPT", 4) == 0)
185
0
    from_len = 4;
186
4.74k
        else if (len >= 3 && strncasecmp (ptr->ptr + i, "IRP", 3) == 0)
187
9
    from_len = 3;
188
4.73k
        else if (len >= 3 && strncasecmp (ptr->ptr + i, "REP", 3) == 0)
189
40
    from_len = 3;
190
4.69k
        else
191
4.69k
    from_len = 0;
192
4.75k
      }
193
7.56k
    if ((from != NULL
194
7.56k
         ? (len >= from_len
195
1.09k
      && strncasecmp (ptr->ptr + i, from, from_len) == 0)
196
7.56k
         : from_len > 0)
197
55
        && (len == from_len
198
54
      || ! (is_part_of_name (ptr->ptr[i + from_len])
199
53
      || is_name_ender (ptr->ptr[i + from_len]))))
200
54
      depth++;
201
7.56k
    if (len >= to_len
202
6.12k
        && strncasecmp (ptr->ptr + i, to, to_len) == 0
203
1.82k
        && (len == to_len
204
62
      || ! (is_part_of_name (ptr->ptr[i + to_len])
205
47
      || is_name_ender (ptr->ptr[i + to_len]))))
206
1.80k
      {
207
1.80k
        depth--;
208
1.80k
        if (depth == 0)
209
1.75k
    {
210
      /* Reset the string to not include the ending rune.  */
211
1.75k
      ptr->len = line_start;
212
213
      /* With the ending directive consumed here, announce the
214
         line for macro-expanded listings. */
215
1.75k
      if (listing & LISTING_MACEXP)
216
0
        listing_newline (NULL);
217
1.75k
      break;
218
1.75k
    }
219
1.80k
      }
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
5.81k
    if (from != NULL && strcasecmp (from, "MACRO") == 0
225
2.12k
        && len >= 8 && strncasecmp (ptr->ptr + i, "linefile", 8) == 0)
226
321
      {
227
321
        sb_add_char (ptr, more);
228
321
        temp_ilp (sb_terminate (ptr) + i + 8);
229
321
        s_linefile (0);
230
321
        restore_ilp ();
231
321
        line_start = ptr->len;
232
321
        more = get_line (ptr);
233
321
        continue;
234
321
      }
235
5.81k
  }
236
237
      /* Add the original end-of-line char to the end and keep running.  */
238
11.0k
      sb_add_char (ptr, more);
239
11.0k
      line_start = ptr->len;
240
11.0k
      more = get_line (ptr);
241
11.0k
    }
242
243
  /* Return 1 on success, 0 on unexpected EOF.  */
244
1.88k
  return depth == 0;
245
1.88k
}
246
247
/* Pick up a token.  */
248
249
static size_t
250
get_token (size_t idx, sb *in, sb *name)
251
45.2k
{
252
45.2k
  if (idx < in->len
253
45.2k
      && is_name_beginner (in->ptr[idx]))
254
40.1k
    {
255
40.1k
      sb_add_char (name, in->ptr[idx++]);
256
251k
      while (idx < in->len
257
250k
       && is_part_of_name (in->ptr[idx]))
258
211k
  {
259
211k
    sb_add_char (name, in->ptr[idx++]);
260
211k
  }
261
40.1k
      if (idx < in->len
262
39.4k
       && is_name_ender (in->ptr[idx]))
263
0
  {
264
0
    sb_add_char (name, in->ptr[idx++]);
265
0
  }
266
40.1k
    }
267
  /* Ignore trailing &.  */
268
45.2k
  if (flag_macro_alternate && idx < in->len && in->ptr[idx] == '&')
269
0
    idx++;
270
45.2k
  return idx;
271
45.2k
}
272
273
/* Pick up a string.  */
274
275
static size_t
276
getstring (size_t idx, sb *in, sb *acc)
277
25
{
278
50
  while (idx < in->len
279
34
   && (in->ptr[idx] == '"'
280
10
       || (in->ptr[idx] == '<' && (flag_macro_alternate || flag_mri))
281
9
       || (in->ptr[idx] == '\'' && flag_macro_alternate)))
282
25
    {
283
25
      if (in->ptr[idx] == '<')
284
1
  {
285
1
    int nest = 0;
286
1
    idx++;
287
25
    while (idx < in->len)
288
24
      {
289
24
        if (in->ptr[idx] == '!' && idx + 1 < in->len)
290
2
    idx++;
291
22
        else if (in->ptr[idx] == '>')
292
0
    {
293
0
      if (nest == 0)
294
0
        {
295
0
          idx++;
296
0
          break;
297
0
        }
298
0
      nest--;
299
0
    }
300
22
        else if (in->ptr[idx] == '<')
301
0
    nest++;
302
303
24
        sb_add_char (acc, in->ptr[idx]);
304
24
        idx++;
305
24
      }
306
1
  }
307
24
      else if (in->ptr[idx] == '"' || in->ptr[idx] == '\'')
308
24
  {
309
24
    char tchar = in->ptr[idx];
310
24
    int escaped = 0;
311
312
24
    idx++;
313
228
    while (idx < in->len)
314
217
      {
315
217
        if (in->ptr[idx - 1] == '\\')
316
72
    escaped ^= 1;
317
145
        else
318
145
    escaped = 0;
319
320
217
        if (flag_macro_alternate
321
0
      && in->ptr[idx] == '!' && idx + 1 < in->len)
322
0
    {
323
0
      idx++;
324
0
    }
325
217
        else if (!escaped && in->ptr[idx] == tchar)
326
31
    {
327
31
      idx++;
328
31
      if (idx >= in->len || in->ptr[idx] != tchar)
329
13
        break;
330
31
    }
331
204
        sb_add_char (acc, in->ptr[idx]);
332
204
        idx++;
333
204
      }
334
24
  }
335
25
    }
336
337
25
  return idx;
338
25
}
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
317
{
350
317
  sb_reset (out);
351
317
  idx = sb_skip_white (idx, in);
352
353
317
  if (idx < in->len)
354
317
    {
355
317
      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
317
      else if (in->ptr[idx] == '"'
375
293
         || (in->ptr[idx] == '<' && (flag_macro_alternate || flag_mri))
376
292
         || (flag_macro_alternate && in->ptr[idx] == '\''))
377
25
  {
378
25
    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
25
    else
386
25
      {
387
25
        idx = getstring (idx, in, out);
388
25
      }
389
25
  }
390
292
      else
391
292
  {
392
292
    char *br_buf = XNEWVEC (char, 1);
393
292
    char *in_br = br_buf;
394
395
292
    *in_br = '\0';
396
3.49k
    while (idx < in->len
397
3.45k
     && (*in_br || !is_whitespace (in->ptr[idx]))
398
3.42k
     && in->ptr[idx] != ','
399
3.21k
     && (in->ptr[idx] != '<'
400
30
         || (! flag_macro_alternate && ! flag_mri)))
401
3.21k
      {
402
3.21k
        char tchar = in->ptr[idx];
403
404
3.21k
        switch (tchar)
405
3.21k
    {
406
26
    case '"':
407
26
    case '\'':
408
26
      sb_add_char (out, in->ptr[idx++]);
409
55
      while (idx < in->len
410
47
       && in->ptr[idx] != tchar)
411
29
        sb_add_char (out, in->ptr[idx++]);
412
26
      if (idx == in->len)
413
8
        {
414
8
          free (br_buf);
415
8
          return idx;
416
8
        }
417
18
      break;
418
30
    case '(':
419
31
    case '[':
420
31
      if (in_br > br_buf)
421
0
        --in_br;
422
31
      else
423
31
        {
424
31
          br_buf = XNEWVEC (char, strlen (in_br) + 2);
425
31
          strcpy (br_buf + 1, in_br);
426
31
          free (in_br);
427
31
          in_br = br_buf;
428
31
        }
429
31
      *in_br = tchar;
430
31
      break;
431
56
    case ')':
432
56
      if (*in_br == '(')
433
28
        ++in_br;
434
56
      break;
435
2
    case ']':
436
2
      if (*in_br == '[')
437
0
        ++in_br;
438
2
      break;
439
3.21k
    }
440
3.20k
        sb_add_char (out, tchar);
441
3.20k
        ++idx;
442
3.20k
      }
443
284
    free (br_buf);
444
284
  }
445
317
    }
446
447
309
  return idx;
448
317
}
449
450
/* Allocate a new formal.  */
451
452
static formal_entry *
453
new_formal (void)
454
2.41k
{
455
2.41k
  formal_entry *formal;
456
457
2.41k
  formal = XNEW (formal_entry);
458
459
2.41k
  sb_new (&formal->name);
460
2.41k
  sb_new (&formal->def);
461
2.41k
  sb_new (&formal->actual);
462
2.41k
  formal->next = NULL;
463
2.41k
  formal->type = FORMAL_OPTIONAL;
464
2.41k
  return formal;
465
2.41k
}
466
467
/* Free a formal.  */
468
469
static void
470
del_formal (formal_entry *formal)
471
2.41k
{
472
2.41k
  sb_kill (&formal->actual);
473
2.41k
  sb_kill (&formal->def);
474
2.41k
  sb_kill (&formal->name);
475
2.41k
  free (formal);
476
2.41k
}
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
710
{
483
710
  formal_entry **p = &macro->formals;
484
710
  const char *name;
485
486
710
  idx = sb_skip_white (idx, in);
487
2.41k
  while (idx < in->len)
488
1.71k
    {
489
1.71k
      formal_entry *formal = new_formal ();
490
1.71k
      size_t cidx;
491
492
1.71k
      idx = get_token (idx, in, &formal->name);
493
1.71k
      if (formal->name.len == 0)
494
5
  {
495
5
    if (macro->formal_count)
496
1
      --idx;
497
5
    del_formal (formal);  /* 'formal' goes out of scope.  */
498
5
    break;
499
5
  }
500
1.70k
      idx = sb_skip_white (idx, in);
501
      /* This is a formal.  */
502
1.70k
      name = sb_terminate (&formal->name);
503
1.70k
      if (! flag_mri
504
5
    && idx < in->len
505
0
    && 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
1.70k
      if (idx < in->len && in->ptr[idx] == '=')
537
0
  {
538
    /* Got a default.  */
539
0
    idx = get_any_string (idx + 1, in, &formal->def);
540
0
    idx = sb_skip_white (idx, in);
541
0
    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
0
  }
551
552
      /* Add to macro's hash table.  */
553
1.70k
      if (str_hash_insert (macro->formal_hash, name, formal, 0) != NULL)
554
0
  {
555
0
    as_bad_where (macro->file, macro->line,
556
0
      _("A parameter named `%s' "
557
0
        "already exists for macro `%s'"),
558
0
      name, macro->name);
559
0
  }
560
561
1.70k
      formal->index = macro->formal_count++;
562
1.70k
      *p = formal;
563
1.70k
      p = &formal->next;
564
1.70k
      if (formal->type == FORMAL_VARARG)
565
0
  break;
566
1.70k
      cidx = idx;
567
1.70k
      idx = sb_skip_comma (idx, in);
568
1.70k
      if (idx != cidx && idx >= in->len)
569
2
  {
570
2
    idx = cidx;
571
2
    break;
572
2
  }
573
1.70k
    }
574
575
710
  if (flag_mri)
576
698
    {
577
698
      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
698
      if (macro_strip_at)
584
0
  name = "$NARG";
585
698
      else
586
698
  name = "NARG";
587
588
698
      sb_add_string (&formal->name, name);
589
590
      /* Add to macro's hash table.  */
591
698
      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
698
      formal->index = NARG_INDEX;
599
698
      *p = formal;
600
698
    }
601
602
710
  return idx;
603
710
}
604
605
/* Free the memory allocated to a macro.  */
606
607
static void
608
free_macro (macro_entry *macro)
609
710
{
610
710
  formal_entry *formal;
611
612
3.11k
  for (formal = macro->formals; formal; )
613
2.40k
    {
614
2.40k
      formal_entry *f;
615
616
2.40k
      f = formal;
617
2.40k
      formal = formal->next;
618
2.40k
      del_formal (f);
619
2.40k
    }
620
710
  htab_delete (macro->formal_hash);
621
710
  sb_kill (&macro->sub);
622
710
  free ((char *) macro->name);
623
710
  free (macro);
624
710
}
625
626
/* Define a new macro.  */
627
628
macro_entry *
629
define_macro (sb *in, sb *label, size_t (*get_line) (sb *))
630
710
{
631
710
  macro_entry *macro;
632
710
  sb name;
633
710
  size_t idx;
634
710
  const char *error = NULL;
635
636
710
  macro = XNEW (macro_entry);
637
710
  sb_new (&macro->sub);
638
710
  sb_new (&name);
639
710
  macro->file = as_where (&macro->line);
640
641
710
  macro->formal_count = 0;
642
710
  macro->formals = 0;
643
710
  macro->formal_hash = str_htab_create ();
644
710
  macro->count = 0;
645
646
710
  idx = sb_skip_white (0, in);
647
710
  if (! buffer_and_nest ("MACRO", "ENDM", &macro->sub, get_line))
648
14
    error = _("unexpected end of file in macro `%s' definition");
649
710
  if (label != NULL && label->len != 0)
650
689
    {
651
689
      sb_add_sb (&name, label);
652
689
      macro->name = sb_terminate (&name);
653
689
      if (idx < in->len && in->ptr[idx] == '(')
654
0
  {
655
    /* It's the label: MACRO (formals,...)  sort  */
656
0
    idx = do_formals (macro, idx + 1, in);
657
0
    if (idx < in->len && in->ptr[idx] == ')')
658
0
      idx = sb_skip_white (idx + 1, in);
659
0
    else if (!error)
660
0
      error = _("missing `)' after formals in macro definition `%s'");
661
0
  }
662
689
      else
663
689
  {
664
    /* It's the label: MACRO formals,...  sort  */
665
689
    idx = do_formals (macro, idx, in);
666
689
  }
667
689
    }
668
21
  else
669
21
    {
670
21
      size_t cidx;
671
672
21
      idx = get_token (idx, in, &name);
673
21
      macro->name = sb_terminate (&name);
674
21
      if (name.len == 0)
675
3
  error = _("Missing macro name");
676
21
      cidx = sb_skip_white (idx, in);
677
21
      idx = sb_skip_comma (cidx, in);
678
21
      if (idx == cidx || idx < in->len)
679
21
  idx = do_formals (macro, idx, in);
680
0
      else
681
0
  idx = cidx;
682
21
    }
683
710
  if (!error && idx < in->len)
684
0
    error = _("Bad parameter list for macro `%s'");
685
686
  /* And stick it in the macro hash table.  */
687
9.67k
  for (idx = 0; idx < name.len; idx++)
688
8.96k
    name.ptr[idx] = TOLOWER (name.ptr[idx]);
689
710
  if (!error)
690
696
    {
691
696
      if (str_hash_insert (macro_hash, macro->name, macro, 0) != NULL)
692
342
  error = _("Macro `%s' was already defined");
693
696
    }
694
695
710
  if (!error)
696
354
    macro_defined = 1;
697
356
  else
698
356
    {
699
356
      as_bad_where (macro->file, macro->line, error, macro->name);
700
356
      free_macro (macro);
701
356
      macro = NULL;
702
356
    }
703
704
710
  return macro;
705
710
}
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
42.6k
{
712
42.6k
  idx = get_token (idx, in, name);
713
42.6k
  if (idx < in->len
714
42.6k
      && in->ptr[idx] == kind
715
1.37k
      && (! flag_mri || macro_strip_at)
716
0
      && (! macro_strip_at || kind == '@'))
717
1.12k
    idx++;
718
42.6k
  return idx;
719
42.6k
}
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
42.6k
{
727
42.6k
  size_t src;
728
42.6k
  formal_entry *ptr;
729
730
42.6k
  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
42.6k
  if (macro_strip_at
734
0
      && kind == '@'
735
0
      && (src == start || in->ptr[src - 1] != '@'))
736
0
    ptr = NULL;
737
42.6k
  else
738
42.6k
    ptr = str_hash_find (formal_hash, sb_terminate (t));
739
42.6k
  if (ptr)
740
139
    {
741
139
      if (ptr->actual.len)
742
139
  {
743
139
    sb_add_sb (out, &ptr->actual);
744
139
  }
745
0
      else
746
0
  {
747
0
    sb_add_sb (out, &ptr->def);
748
0
  }
749
139
    }
750
42.5k
  else if (kind == '&')
751
1.61k
    {
752
      /* Doing this permits people to use & in macro bodies.  */
753
1.61k
      sb_add_char (out, '&');
754
1.61k
      sb_add_sb (out, t);
755
1.61k
      if (src != start && in->ptr[src - 1] == '&')
756
1.12k
  sb_add_char (out, '&');
757
1.61k
    }
758
40.8k
  else if (copyifnotthere)
759
38.8k
    {
760
38.8k
      sb_add_sb (out, t);
761
38.8k
    }
762
2.00k
  else
763
2.00k
    {
764
2.00k
      sb_add_char (out, '\\');
765
2.00k
      sb_add_sb (out, t);
766
2.00k
    }
767
42.6k
  return src;
768
42.6k
}
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
2.89k
{
777
2.89k
  sb t;
778
2.89k
  size_t src = 0;
779
2.89k
  int inquote = 0, macro_line = 0;
780
2.89k
  formal_entry *loclist = NULL;
781
2.89k
  const char *err = NULL;
782
783
2.89k
  sb_new (&t);
784
785
1.03M
  while (src < in->len && !err)
786
1.03M
    {
787
1.03M
      if (in->ptr[src] == '&')
788
4.24k
  {
789
4.24k
    sb_reset (&t);
790
4.24k
    if (flag_mri)
791
2.62k
      {
792
2.62k
        if (src + 1 < in->len && in->ptr[src + 1] == '&')
793
1.97k
    src = sub_actual (src + 2, in, &t, formal_hash, '\'', out, 1);
794
652
        else
795
652
    sb_add_char (out, in->ptr[src++]);
796
2.62k
      }
797
1.61k
    else
798
1.61k
      {
799
        /* Permit macro parameter substitution delineated with
800
     an '&' prefix and optional '&' suffix.  */
801
1.61k
        src = sub_actual (src + 1, in, &t, formal_hash, '&', out, 0);
802
1.61k
      }
803
4.24k
  }
804
1.03M
      else if (in->ptr[src] == '\\')
805
2.19k
  {
806
2.19k
    src++;
807
2.19k
    if (src < in->len && in->ptr[src] == '(')
808
19
      {
809
        /* Sub in till the next ')' literally.  */
810
19
        src++;
811
2.43k
        while (src < in->len && in->ptr[src] != ')')
812
2.41k
    {
813
2.41k
      sb_add_char (out, in->ptr[src++]);
814
2.41k
    }
815
19
        if (src < in->len)
816
12
    src++;
817
7
        else if (!macro)
818
7
    err = _("missing `)'");
819
0
        else
820
0
    as_bad_where (macro->file, macro->line + macro_line, _("missing `)'"));
821
19
      }
822
2.17k
    else if (src < in->len && in->ptr[src] == '@')
823
9
      {
824
        /* Sub in the total macro invocation number.  */
825
826
9
        char buffer[12];
827
9
        src++;
828
9
        sprintf (buffer, "%u", macro_number);
829
9
        sb_add_string (out, buffer);
830
9
      }
831
2.16k
    else if (src < in->len && in->ptr[src] == '+')
832
0
      {
833
        /* Sub in the current macro invocation number.  */
834
835
0
        char buffer[12];
836
0
        src++;
837
0
        sprintf (buffer, "%d", instance);
838
0
        sb_add_string (out, buffer);
839
0
      }
840
2.16k
    else if (src < in->len && in->ptr[src] == '&')
841
0
      {
842
        /* This is a preprocessor variable name, we don't do them
843
     here.  */
844
0
        sb_add_char (out, '\\');
845
0
        sb_add_char (out, '&');
846
0
        src++;
847
0
      }
848
2.16k
    else if (flag_mri && src < in->len && ISALNUM (in->ptr[src]))
849
163
      {
850
163
        int ind;
851
163
        formal_entry *f;
852
853
163
        if (ISDIGIT (in->ptr[src]))
854
49
    ind = in->ptr[src] - '0';
855
114
        else if (ISUPPER (in->ptr[src]))
856
90
    ind = in->ptr[src] - 'A' + 10;
857
24
        else
858
24
    ind = in->ptr[src] - 'a' + 10;
859
163
        ++src;
860
302
        for (f = formals; f != NULL; f = f->next)
861
163
    {
862
163
      if (f->index == ind - 1)
863
24
        {
864
24
          if (f->actual.len != 0)
865
14
      sb_add_sb (out, &f->actual);
866
10
          else
867
10
      sb_add_sb (out, &f->def);
868
24
          break;
869
24
        }
870
163
    }
871
163
      }
872
2.00k
    else
873
2.00k
      {
874
2.00k
        sb_reset (&t);
875
2.00k
        src = sub_actual (src, in, &t, formal_hash, '\'', out, 0);
876
2.00k
      }
877
2.19k
  }
878
1.03M
      else if ((flag_macro_alternate || flag_mri)
879
195k
         && is_name_beginner (in->ptr[src])
880
37.0k
         && (! inquote
881
17.8k
       || ! macro_strip_at
882
0
       || (src > 0 && in->ptr[src - 1] == '@')))
883
37.0k
  {
884
37.0k
    if (! macro
885
254
        || src + 5 >= in->len
886
235
        || 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
37.0k
      {
891
37.0k
        sb_reset (&t);
892
37.0k
        src = sub_actual (src, in, &t, formal_hash,
893
37.0k
        (macro_strip_at && inquote) ? '@' : '\'',
894
37.0k
        out, 1);
895
37.0k
      }
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
37.0k
  }
930
993k
      else if (in->ptr[src] == '"'
931
974k
         || (flag_mri && in->ptr[src] == '\''))
932
19.8k
  {
933
19.8k
    inquote = !inquote;
934
19.8k
    sb_add_char (out, in->ptr[src++]);
935
19.8k
  }
936
973k
      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
973k
      else if (flag_mri
947
149k
         && in->ptr[src] == '='
948
1.28k
         && src + 1 < in->len
949
1.28k
         && in->ptr[src + 1] == '=')
950
782
  {
951
782
    formal_entry *ptr;
952
953
782
    sb_reset (&t);
954
782
    src = get_token (src + 2, in, &t);
955
782
    ptr = str_hash_find (formal_hash, sb_terminate (&t));
956
782
    if (ptr == NULL)
957
782
      {
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
782
        sb_add_char (out, '=');
967
782
        sb_add_char (out, '=');
968
782
        sb_add_sb (out, &t);
969
782
      }
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
782
  }
982
972k
      else
983
972k
  {
984
972k
    if (in->ptr[src] == '\n')
985
38.8k
      ++macro_line;
986
972k
    sb_add_char (out, in->ptr[src++]);
987
972k
  }
988
1.03M
    }
989
990
2.89k
  sb_kill (&t);
991
992
2.89k
  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
2.89k
  if (!err && (out->len == 0 || out->ptr[out->len - 1] != '\n'))
1005
117
    sb_add_char (out, '\n');
1006
2.89k
  return err;
1007
2.89k
}
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
32
{
1015
32
  sb t;
1016
32
  formal_entry *ptr;
1017
32
  formal_entry *f;
1018
32
  int is_keyword = 0;
1019
32
  int narg = 0;
1020
32
  const char *err = NULL;
1021
1022
32
  sb_new (&t);
1023
1024
  /* Reset any old value the actuals may have.  */
1025
64
  for (f = m->formals; f; f = f->next)
1026
32
    sb_reset (&f->actual);
1027
32
  f = m->formals;
1028
52
  while (f != NULL && f->index < 0)
1029
20
    f = f->next;
1030
1031
32
  if (flag_mri)
1032
21
    {
1033
      /* The macro may be called with an optional qualifier, which may
1034
   be referred to in the macro body as \0.  */
1035
21
      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
21
    }
1053
1054
  /* Peel off the actuals and store them away in the hash tables' actuals.  */
1055
32
  idx = sb_skip_white (idx, in);
1056
47
  while (idx < in->len)
1057
16
    {
1058
      /* Look and see if it's a positional or keyword arg.  */
1059
16
      size_t scan;
1060
1061
16
      sb_reset (&t);
1062
16
      scan = !flag_macro_alternate ? get_token (idx, in, &t) : idx;
1063
1064
16
      if (scan > idx && scan < in->len && in->ptr[scan] == '=')
1065
0
  {
1066
0
    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
0
    ptr = str_hash_find (m->formal_hash, sb_terminate (&t));
1072
0
    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
0
    else
1082
0
      {
1083
        /* Insert this value into the right place.  */
1084
0
        if (ptr->actual.len)
1085
0
    {
1086
0
      as_warn (_("Value for parameter `%s' of macro `%s' was already specified"),
1087
0
         ptr->name.ptr,
1088
0
         m->name);
1089
0
      sb_reset (&ptr->actual);
1090
0
    }
1091
        /* Fetch the actual stuff.  */
1092
0
        idx = get_any_string (scan + 1, in, &ptr->actual);
1093
0
        if (ptr->actual.len > 0)
1094
0
    ++narg;
1095
0
      }
1096
0
  }
1097
16
      else
1098
16
  {
1099
16
    if (is_keyword)
1100
0
      {
1101
0
        err = _("can't mix positional and keyword arguments");
1102
0
        break;
1103
0
      }
1104
1105
16
    if (!f)
1106
6
      {
1107
6
        formal_entry **pf;
1108
6
        int c;
1109
1110
6
        if (!flag_mri)
1111
1
    {
1112
1
      err = _("too many positional arguments");
1113
1
      break;
1114
1
    }
1115
1116
5
        f = new_formal ();
1117
1118
5
        c = -1;
1119
12
        for (pf = &m->formals; *pf != NULL; pf = &(*pf)->next)
1120
7
    if ((*pf)->index >= c)
1121
2
      c = (*pf)->index + 1;
1122
5
        if (c == -1)
1123
3
    c = 0;
1124
5
        *pf = f;
1125
5
        f->index = c;
1126
5
      }
1127
1128
15
    if (f->type != FORMAL_VARARG)
1129
15
      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
15
    if (f->actual.len > 0)
1136
15
      ++narg;
1137
15
    do
1138
17
      {
1139
17
        f = f->next;
1140
17
      }
1141
17
    while (f != NULL && f->index < 0);
1142
15
  }
1143
1144
15
      if (! flag_mri)
1145
8
  idx = sb_skip_comma (idx, in);
1146
7
      else
1147
7
  {
1148
7
    if (idx < in->len && in->ptr[idx] == ',')
1149
0
      ++idx;
1150
7
    if (idx < in->len && is_whitespace (in->ptr[idx]))
1151
0
      break;
1152
7
  }
1153
15
    }
1154
1155
32
  if (! err)
1156
31
    {
1157
67
      for (ptr = m->formals; ptr; ptr = ptr->next)
1158
36
  {
1159
36
    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
36
  }
1164
1165
31
      if (flag_mri)
1166
21
  {
1167
21
    ptr = str_hash_find (m->formal_hash,
1168
21
             macro_strip_at ? "$NARG" : "NARG");
1169
21
    if (ptr)
1170
21
      {
1171
21
        char buffer[20];
1172
21
        sprintf (buffer, "%d", narg);
1173
21
        sb_add_string (&ptr->actual, buffer);
1174
21
      }
1175
21
  }
1176
1177
31
      err = macro_expand_body (&m->sub, out, m->formals, m->formal_hash, m,
1178
31
             m->count);
1179
31
    }
1180
1181
  /* Discard any unnamed formal arguments.  */
1182
32
  if (flag_mri)
1183
21
    {
1184
21
      formal_entry **pf;
1185
1186
21
      pf = &m->formals;
1187
49
      while (*pf != NULL)
1188
28
  {
1189
28
    if ((*pf)->name.len != 0)
1190
23
      pf = &(*pf)->next;
1191
5
    else
1192
5
      {
1193
5
        f = (*pf)->next;
1194
5
        del_formal (*pf);
1195
5
        *pf = f;
1196
5
      }
1197
28
  }
1198
21
    }
1199
1200
32
  sb_kill (&t);
1201
32
  if (!err)
1202
31
    {
1203
31
      macro_number++;
1204
31
      m->count++;
1205
31
    }
1206
1207
32
  return err;
1208
32
}
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
1.97k
{
1217
1.97k
  const char *s;
1218
1.97k
  char *copy, *cls;
1219
1.97k
  macro_entry *macro;
1220
1.97k
  sb line_sb;
1221
1222
1.97k
  if (! is_name_beginner (*line)
1223
2
      && (! flag_mri || *line != '.'))
1224
2
    return 0;
1225
1226
1.96k
  s = line + 1;
1227
11.1k
  while (is_part_of_name (*s))
1228
9.18k
    ++s;
1229
1.96k
  if (is_name_ender (*s))
1230
0
    ++s;
1231
1232
1.96k
  copy = xmemdup0 (line, s - line);
1233
13.1k
  for (cls = copy; *cls != '\0'; cls ++)
1234
11.1k
    *cls = TOLOWER (*cls);
1235
1236
1.96k
  macro = str_hash_find (macro_hash, copy);
1237
1.96k
  free (copy);
1238
1239
1.96k
  if (macro == NULL)
1240
1.93k
    return 0;
1241
1242
  /* Wrap the line up in an sb.  */
1243
32
  sb_new (&line_sb);
1244
203
  while (*s != '\0' && *s != '\n' && *s != '\r')
1245
171
    sb_add_char (&line_sb, *s++);
1246
1247
32
  sb_new (expand);
1248
32
  *error = macro_expand (0, &line_sb, macro, expand);
1249
1250
32
  sb_kill (&line_sb);
1251
1252
  /* Export the macro information if requested.  */
1253
32
  if (info)
1254
32
    *info = macro;
1255
1256
32
  return 1;
1257
1.96k
}
1258
1259
/* Delete a macro.  */
1260
1261
void
1262
delete_macro (const char *name)
1263
6
{
1264
6
  char *copy;
1265
6
  size_t i, len;
1266
6
  macro_entry *macro;
1267
1268
6
  len = strlen (name);
1269
6
  copy = XNEWVEC (char, len + 1);
1270
59
  for (i = 0; i < len; ++i)
1271
53
    copy[i] = TOLOWER (name[i]);
1272
6
  copy[i] = '\0';
1273
1274
6
  macro = str_hash_find (macro_hash, copy);
1275
6
  if (macro != NULL)
1276
0
    str_hash_delete (macro_hash, copy);
1277
6
  else
1278
6
    as_warn (_("Attempt to purge non-existing macro `%s'"), copy);
1279
6
  free (copy);
1280
6
}
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
159
{
1289
159
  sb sub;
1290
159
  formal_entry f;
1291
159
  struct htab *h;
1292
159
  const char *err = NULL;
1293
1294
159
  idx = sb_skip_white (idx, in);
1295
1296
159
  sb_new (&sub);
1297
159
  if (! buffer_and_nest (NULL, "ENDR", &sub, get_line))
1298
62
    {
1299
62
      err = _("unexpected end of file in irp or irpc");
1300
62
      goto out2;
1301
62
    }
1302
1303
97
  sb_new (&f.name);
1304
97
  sb_new (&f.def);
1305
97
  sb_new (&f.actual);
1306
1307
97
  idx = get_token (idx, in, &f.name);
1308
97
  if (f.name.len == 0)
1309
5
    {
1310
5
      err = _("missing model parameter");
1311
5
      goto out1;
1312
5
    }
1313
1314
92
  h = str_htab_create ();
1315
1316
92
  str_hash_insert (h, sb_terminate (&f.name), &f, 0);
1317
1318
92
  f.index = 1;
1319
92
  f.next = NULL;
1320
92
  f.type = FORMAL_OPTIONAL;
1321
1322
92
  sb_reset (out);
1323
1324
92
  idx = sb_skip_comma (idx, in);
1325
92
  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
92
  else
1331
92
    {
1332
92
      bool in_quotes = false;
1333
92
      unsigned int instance = 0;
1334
1335
2.96k
      while (idx < in->len)
1336
2.88k
  {
1337
2.88k
    if (!irpc)
1338
302
      idx = get_any_string (idx, in, &f.actual);
1339
2.58k
    else
1340
2.58k
      {
1341
2.58k
        if (in->ptr[idx] == '"')
1342
19
    {
1343
19
      in_quotes = ! in_quotes;
1344
19
      ++idx;
1345
1346
19
      if (! in_quotes)
1347
7
        {
1348
7
          idx = sb_skip_white (idx, in);
1349
7
          if (idx >= in->len)
1350
5
      break;
1351
7
        }
1352
14
      continue;
1353
19
    }
1354
2.56k
        sb_reset (&f.actual);
1355
2.56k
        sb_add_char (&f.actual, in->ptr[idx]);
1356
2.56k
        ++idx;
1357
2.56k
      }
1358
1359
2.86k
    err = macro_expand_body (&sub, out, &f, h, NULL, instance);
1360
2.86k
    ++instance;
1361
2.86k
    if (err != NULL)
1362
7
      break;
1363
2.86k
    if (!irpc)
1364
295
      idx = sb_skip_comma (idx, in);
1365
2.56k
    else if (! in_quotes)
1366
2.14k
      idx = sb_skip_white (idx, in);
1367
2.86k
  }
1368
92
    }
1369
1370
92
  htab_delete (h);
1371
97
 out1:
1372
97
  sb_kill (&f.actual);
1373
97
  sb_kill (&f.def);
1374
97
  sb_kill (&f.name);
1375
159
 out2:
1376
159
  sb_kill (&sub);
1377
1378
159
  return err;
1379
97
}