Coverage Report

Created: 2023-06-29 07:09

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