Coverage Report

Created: 2023-08-28 06:31

/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
1.93M
#define ISWHITE(x) ((x) == ' ' || (x) == '\t')
33
34
#define ISSEP(x) \
35
243k
 ((x) == ' ' || (x) == '\t' || (x) == ',' || (x) == '"' || (x) == ';' \
36
118k
  || (x) == ')' || (x) == '(' \
37
243k
  || ((flag_macro_alternate || flag_mri) && ((x) == '<' || (x) == '>')))
38
39
#define ISBASE(x) \
40
12
  ((x) == 'b' || (x) == 'B' \
41
12
   || (x) == 'q' || (x) == 'Q' \
42
12
   || (x) == 'h' || (x) == 'H' \
43
12
   || (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.28M
#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
713
{
66
713
  string_tuple_t *tuple = ent;
67
713
  free_macro ((macro_entry *) tuple->value);
68
713
}
69
70
/* Initialize macro processing.  */
71
72
void
73
macro_init (void)
74
1.15k
{
75
1.15k
  macro_hash = htab_create_alloc (16, hash_string_tuple, eq_string_tuple,
76
1.15k
          macro_del_f, notes_calloc, NULL);
77
1.15k
  macro_defined = 0;
78
1.15k
}
79
80
void
81
macro_end (void)
82
1.15k
{
83
1.15k
  htab_delete (macro_hash);
84
1.15k
}
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
118k
{
97
118k
  size_t from_len;
98
118k
  size_t to_len = strlen (to);
99
118k
  int depth = 1;
100
118k
  size_t line_start, more;
101
102
118k
  if (to_len == 4 && strcasecmp (to, "ENDR") == 0)
103
67.9k
    {
104
67.9k
      from = NULL;
105
67.9k
      from_len = 0;
106
67.9k
    }
107
50.5k
  else
108
50.5k
    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
118k
  {
114
118k
    unsigned int line;
115
118k
    char *linefile;
116
117
118k
    as_where_top (&line);
118
118k
    if (!flag_m68k_mri)
119
118k
      linefile = xasprintf ("\t.linefile %u .", line + 1);
120
0
    else
121
0
      linefile = xasprintf ("\tlinefile %u .", line + 1);
122
118k
    sb_add_string (ptr, linefile);
123
118k
    xfree (linefile);
124
118k
  }
125
126
118k
  line_start = ptr->len;
127
118k
  more = get_line (ptr);
128
670k
  while (more)
129
641k
    {
130
      /* Try to find the first pseudo op on the line.  */
131
641k
      size_t i = line_start;
132
641k
      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
641k
      if (! LABELS_WITHOUT_COLONS)
140
641k
  {
141
    /* Skip leading whitespace.  */
142
854k
    while (i < ptr->len && ISWHITE (ptr->ptr[i]))
143
213k
      i++;
144
641k
  }
145
146
641k
      for (;;)
147
649k
  {
148
    /* Skip over a label, if any.  */
149
649k
    if (i >= ptr->len || ! is_name_beginner (ptr->ptr[i]))
150
211k
      break;
151
437k
    i++;
152
2.23M
    while (i < ptr->len && is_part_of_name (ptr->ptr[i]))
153
1.80M
      i++;
154
437k
    if (i < ptr->len && is_name_ender (ptr->ptr[i]))
155
0
      i++;
156
    /* Skip whitespace.  */
157
536k
    while (i < ptr->len && ISWHITE (ptr->ptr[i]))
158
98.1k
      i++;
159
    /* Check for the colon.  */
160
437k
    if (i >= ptr->len || ptr->ptr[i] != ':')
161
429k
      {
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
429k
        if (LABELS_WITHOUT_COLONS && !had_colon)
167
0
    break;
168
429k
        i = line_start;
169
429k
        break;
170
429k
      }
171
8.30k
    i++;
172
8.30k
    line_start = i;
173
8.30k
    had_colon = true;
174
8.30k
  }
175
176
      /* Skip trailing whitespace.  */
177
840k
      while (i < ptr->len && ISWHITE (ptr->ptr[i]))
178
199k
  i++;
179
180
641k
      if (i < ptr->len && (ptr->ptr[i] == '.'
181
459k
         || NO_PSEUDO_DOT
182
459k
         || flag_mri))
183
422k
  {
184
422k
    if (! flag_m68k_mri && ptr->ptr[i] == '.')
185
381k
      i++;
186
422k
    size_t len = ptr->len - i;
187
422k
    if (from == NULL)
188
255k
      {
189
255k
        if (len >= 5 && strncasecmp (ptr->ptr + i, "IREPC", 5) == 0)
190
272
    from_len = 5;
191
255k
        else if (len >= 4 && strncasecmp (ptr->ptr + i, "IREP", 4) == 0)
192
2
    from_len = 4;
193
255k
        else if (len >= 4 && strncasecmp (ptr->ptr + i, "IRPC", 4) == 0)
194
223
    from_len = 4;
195
254k
        else if (len >= 4 && strncasecmp (ptr->ptr + i, "REPT", 4) == 0)
196
601
    from_len = 4;
197
254k
        else if (len >= 3 && strncasecmp (ptr->ptr + i, "IRP", 3) == 0)
198
28.0k
    from_len = 3;
199
226k
        else if (len >= 3 && strncasecmp (ptr->ptr + i, "REP", 3) == 0)
200
857
    from_len = 3;
201
225k
        else
202
225k
    from_len = 0;
203
255k
      }
204
422k
    if ((from != NULL
205
422k
         ? (len >= from_len
206
166k
      && strncasecmp (ptr->ptr + i, from, from_len) == 0)
207
422k
         : from_len > 0)
208
422k
        && (len == from_len
209
48.4k
      || ! (is_part_of_name (ptr->ptr[i + from_len])
210
47.1k
      || is_name_ender (ptr->ptr[i + from_len]))))
211
43.4k
      depth++;
212
422k
    if (len >= to_len
213
422k
        && strncasecmp (ptr->ptr + i, to, to_len) == 0
214
422k
        && (len == to_len
215
131k
      || ! (is_part_of_name (ptr->ptr[i + to_len])
216
28.4k
      || is_name_ender (ptr->ptr[i + to_len]))))
217
129k
      {
218
129k
        depth--;
219
129k
        if (depth == 0)
220
89.0k
    {
221
      /* Reset the string to not include the ending rune.  */
222
89.0k
      ptr->len = line_start;
223
89.0k
      break;
224
89.0k
    }
225
129k
      }
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
332k
    if (from != NULL && strcasecmp (from, "MACRO") == 0
231
332k
        && len >= 8 && strncasecmp (ptr->ptr + i, "linefile", 8) == 0)
232
4.94k
      {
233
4.94k
        sb_add_char (ptr, more);
234
4.94k
        temp_ilp (sb_terminate (ptr) + i + 8);
235
4.94k
        s_linefile (0);
236
4.94k
        restore_ilp ();
237
4.94k
        line_start = ptr->len;
238
4.94k
        more = get_line (ptr);
239
4.94k
        continue;
240
4.94k
      }
241
332k
  }
242
243
      /* Add the original end-of-line char to the end and keep running.  */
244
547k
      sb_add_char (ptr, more);
245
547k
      line_start = ptr->len;
246
547k
      more = get_line (ptr);
247
547k
    }
248
249
  /* Return 1 on success, 0 on unexpected EOF.  */
250
118k
  return depth == 0;
251
118k
}
252
253
/* Pick up a token.  */
254
255
static size_t
256
get_token (size_t idx, sb *in, sb *name)
257
458k
{
258
458k
  if (idx < in->len
259
458k
      && is_name_beginner (in->ptr[idx]))
260
421k
    {
261
421k
      sb_add_char (name, in->ptr[idx++]);
262
2.02M
      while (idx < in->len
263
2.02M
       && is_part_of_name (in->ptr[idx]))
264
1.59M
  {
265
1.59M
    sb_add_char (name, in->ptr[idx++]);
266
1.59M
  }
267
421k
      if (idx < in->len
268
421k
       && is_name_ender (in->ptr[idx]))
269
0
  {
270
0
    sb_add_char (name, in->ptr[idx++]);
271
0
  }
272
421k
    }
273
  /* Ignore trailing &.  */
274
458k
  if (flag_macro_alternate && idx < in->len && in->ptr[idx] == '&')
275
0
    idx++;
276
458k
  return idx;
277
458k
}
278
279
/* Pick up a string.  */
280
281
static size_t
282
getstring (size_t idx, sb *in, sb *acc)
283
401
{
284
802
  while (idx < in->len
285
802
   && (in->ptr[idx] == '"'
286
402
       || (in->ptr[idx] == '<' && (flag_macro_alternate || flag_mri))
287
402
       || (in->ptr[idx] == '\'' && flag_macro_alternate)))
288
401
    {
289
401
      if (in->ptr[idx] == '<')
290
140
  {
291
140
    int nest = 0;
292
140
    idx++;
293
5.14k
    while (idx < in->len
294
5.14k
     && (in->ptr[idx] != '>' || nest))
295
5.00k
      {
296
5.00k
        if (in->ptr[idx] == '!')
297
2
    {
298
2
      idx++;
299
2
      sb_add_char (acc, in->ptr[idx++]);
300
2
    }
301
5.00k
        else
302
5.00k
    {
303
5.00k
      if (in->ptr[idx] == '>')
304
0
        nest--;
305
5.00k
      if (in->ptr[idx] == '<')
306
12
        nest++;
307
5.00k
      sb_add_char (acc, in->ptr[idx++]);
308
5.00k
    }
309
5.00k
      }
310
140
    idx++;
311
140
  }
312
261
      else if (in->ptr[idx] == '"' || in->ptr[idx] == '\'')
313
261
  {
314
261
    char tchar = in->ptr[idx];
315
261
    int escaped = 0;
316
317
261
    idx++;
318
319
1.52k
    while (idx < in->len)
320
1.26k
      {
321
1.26k
        if (in->ptr[idx - 1] == '\\')
322
10
    escaped ^= 1;
323
1.25k
        else
324
1.25k
    escaped = 0;
325
326
1.26k
        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
1.26k
        else if (escaped && in->ptr[idx] == tchar)
335
0
    {
336
0
      sb_add_char (acc, tchar);
337
0
      idx ++;
338
0
    }
339
1.26k
        else
340
1.26k
    {
341
1.26k
      if (in->ptr[idx] == tchar)
342
1
        {
343
1
          idx ++;
344
345
1
          if (idx >= in->len || in->ptr[idx] != tchar)
346
1
      break;
347
1
        }
348
349
1.25k
      sb_add_char (acc, in->ptr[idx]);
350
1.25k
      idx ++;
351
1.25k
    }
352
1.26k
      }
353
261
  }
354
401
    }
355
356
401
  return idx;
357
401
}
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
48.2k
{
370
48.2k
  sb_reset (out);
371
48.2k
  idx = sb_skip_white (idx, in);
372
373
48.2k
  if (idx < in->len)
374
48.2k
    {
375
48.2k
      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
48.2k
      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
48.2k
      else if (in->ptr[idx] == '"'
400
48.2k
         || (in->ptr[idx] == '<' && (flag_macro_alternate || flag_mri))
401
48.2k
         || (flag_macro_alternate && in->ptr[idx] == '\''))
402
401
  {
403
401
    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
401
    else
411
401
      {
412
401
        idx = getstring (idx, in, out);
413
401
      }
414
401
  }
415
47.8k
      else
416
47.8k
  {
417
47.8k
    char *br_buf = XNEWVEC (char, 1);
418
47.8k
    char *in_br = br_buf;
419
420
47.8k
    *in_br = '\0';
421
245k
    while (idx < in->len
422
245k
     && (*in_br
423
239k
         || (in->ptr[idx] != ' '
424
227k
       && in->ptr[idx] != '\t'))
425
245k
     && in->ptr[idx] != ','
426
245k
     && (in->ptr[idx] != '<'
427
197k
         || (! flag_macro_alternate && ! flag_mri)))
428
197k
      {
429
197k
        char tchar = in->ptr[idx];
430
431
197k
        switch (tchar)
432
197k
    {
433
199
    case '"':
434
371
    case '\'':
435
371
      sb_add_char (out, in->ptr[idx++]);
436
6.19k
      while (idx < in->len
437
6.19k
       && in->ptr[idx] != tchar)
438
5.82k
        sb_add_char (out, in->ptr[idx++]);
439
371
      if (idx == in->len)
440
269
        {
441
269
          free (br_buf);
442
269
          return idx;
443
269
        }
444
102
      break;
445
1.35k
    case '(':
446
2.50k
    case '[':
447
2.50k
      if (in_br > br_buf)
448
0
        --in_br;
449
2.50k
      else
450
2.50k
        {
451
2.50k
          br_buf = XNEWVEC (char, strlen (in_br) + 2);
452
2.50k
          strcpy (br_buf + 1, in_br);
453
2.50k
          free (in_br);
454
2.50k
          in_br = br_buf;
455
2.50k
        }
456
2.50k
      *in_br = tchar;
457
2.50k
      break;
458
1.83k
    case ')':
459
1.83k
      if (*in_br == '(')
460
26
        ++in_br;
461
1.83k
      break;
462
14
    case ']':
463
14
      if (*in_br == '[')
464
0
        ++in_br;
465
14
      break;
466
197k
    }
467
197k
        sb_add_char (out, tchar);
468
197k
        ++idx;
469
197k
      }
470
47.5k
    free (br_buf);
471
47.5k
  }
472
48.2k
    }
473
474
48.0k
  return idx;
475
48.2k
}
476
477
/* Allocate a new formal.  */
478
479
static formal_entry *
480
new_formal (void)
481
75.3k
{
482
75.3k
  formal_entry *formal;
483
484
75.3k
  formal = XNEW (formal_entry);
485
486
75.3k
  sb_new (&formal->name);
487
75.3k
  sb_new (&formal->def);
488
75.3k
  sb_new (&formal->actual);
489
75.3k
  formal->next = NULL;
490
75.3k
  formal->type = FORMAL_OPTIONAL;
491
75.3k
  return formal;
492
75.3k
}
493
494
/* Free a formal.  */
495
496
static void
497
del_formal (formal_entry *formal)
498
75.3k
{
499
75.3k
  sb_kill (&formal->actual);
500
75.3k
  sb_kill (&formal->def);
501
75.3k
  sb_kill (&formal->name);
502
75.3k
  free (formal);
503
75.3k
}
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
35.0k
{
510
35.0k
  formal_entry **p = &macro->formals;
511
35.0k
  const char *name;
512
513
35.0k
  idx = sb_skip_white (idx, in);
514
59.2k
  while (idx < in->len)
515
43.8k
    {
516
43.8k
      formal_entry *formal = new_formal ();
517
43.8k
      size_t cidx;
518
519
43.8k
      idx = get_token (idx, in, &formal->name);
520
43.8k
      if (formal->name.len == 0)
521
4.22k
  {
522
4.22k
    if (macro->formal_count)
523
2.73k
      --idx;
524
4.22k
    del_formal (formal);  /* 'formal' goes out of scope.  */
525
4.22k
    break;
526
4.22k
  }
527
39.5k
      idx = sb_skip_white (idx, in);
528
      /* This is a formal.  */
529
39.5k
      name = sb_terminate (&formal->name);
530
39.5k
      if (! flag_mri
531
39.5k
    && idx < in->len
532
39.5k
    && in->ptr[idx] == ':'
533
39.5k
    && (! 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
39.5k
      if (idx < in->len && in->ptr[idx] == '=')
564
367
  {
565
    /* Got a default.  */
566
367
    idx = get_any_string (idx + 1, in, &formal->def);
567
367
    idx = sb_skip_white (idx, in);
568
367
    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
367
  }
578
579
      /* Add to macro's hash table.  */
580
39.5k
      if (str_hash_insert (macro->formal_hash, name, formal, 0) != NULL)
581
3.93k
  {
582
3.93k
    as_bad_where (macro->file, macro->line,
583
3.93k
      _("A parameter named `%s' "
584
3.93k
        "already exists for macro `%s'"),
585
3.93k
      name, macro->name);
586
3.93k
  }
587
588
39.5k
      formal->index = macro->formal_count++;
589
39.5k
      *p = formal;
590
39.5k
      p = &formal->next;
591
39.5k
      if (formal->type == FORMAL_VARARG)
592
0
  break;
593
39.5k
      cidx = idx;
594
39.5k
      idx = sb_skip_comma (idx, in);
595
39.5k
      if (idx != cidx && idx >= in->len)
596
15.4k
  {
597
15.4k
    idx = cidx;
598
15.4k
    break;
599
15.4k
  }
600
39.5k
    }
601
602
35.0k
  if (flag_mri)
603
22.6k
    {
604
22.6k
      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
22.6k
      if (macro_strip_at)
611
0
  name = "$NARG";
612
22.6k
      else
613
22.6k
  name = "NARG";
614
615
22.6k
      sb_add_string (&formal->name, name);
616
617
      /* Add to macro's hash table.  */
618
22.6k
      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
22.6k
      formal->index = NARG_INDEX;
626
22.6k
      *p = formal;
627
22.6k
    }
628
629
35.0k
  return idx;
630
35.0k
}
631
632
/* Free the memory allocated to a macro.  */
633
634
static void
635
free_macro (macro_entry *macro)
636
50.5k
{
637
50.5k
  formal_entry *formal;
638
639
112k
  for (formal = macro->formals; formal; )
640
62.2k
    {
641
62.2k
      formal_entry *f;
642
643
62.2k
      f = formal;
644
62.2k
      formal = formal->next;
645
62.2k
      del_formal (f);
646
62.2k
    }
647
50.5k
  htab_delete (macro->formal_hash);
648
50.5k
  sb_kill (&macro->sub);
649
50.5k
  free ((char *) macro->name);
650
50.5k
  free (macro);
651
50.5k
}
652
653
/* Define a new macro.  */
654
655
macro_entry *
656
define_macro (sb *in, sb *label, size_t (*get_line) (sb *))
657
50.5k
{
658
50.5k
  macro_entry *macro;
659
50.5k
  sb name;
660
50.5k
  size_t idx;
661
50.5k
  const char *error = NULL;
662
663
50.5k
  macro = XNEW (macro_entry);
664
50.5k
  sb_new (&macro->sub);
665
50.5k
  sb_new (&name);
666
50.5k
  macro->file = as_where (&macro->line);
667
668
50.5k
  macro->formal_count = 0;
669
50.5k
  macro->formals = 0;
670
50.5k
  macro->formal_hash = str_htab_create ();
671
672
50.5k
  idx = sb_skip_white (0, in);
673
50.5k
  if (! buffer_and_nest ("MACRO", "ENDM", &macro->sub, get_line))
674
12.7k
    error = _("unexpected end of file in macro `%s' definition");
675
50.5k
  if (label != NULL && label->len != 0)
676
1.47k
    {
677
1.47k
      sb_add_sb (&name, label);
678
1.47k
      macro->name = sb_terminate (&name);
679
1.47k
      if (idx < in->len && in->ptr[idx] == '(')
680
1.46k
  {
681
    /* It's the label: MACRO (formals,...)  sort  */
682
1.46k
    idx = do_formals (macro, idx + 1, in);
683
1.46k
    if (idx < in->len && in->ptr[idx] == ')')
684
0
      idx = sb_skip_white (idx + 1, in);
685
1.46k
    else if (!error)
686
140
      error = _("missing `)' after formals in macro definition `%s'");
687
1.46k
  }
688
10
      else
689
10
  {
690
    /* It's the label: MACRO formals,...  sort  */
691
10
    idx = do_formals (macro, idx, in);
692
10
  }
693
1.47k
    }
694
49.0k
  else
695
49.0k
    {
696
49.0k
      size_t cidx;
697
698
49.0k
      idx = get_token (idx, in, &name);
699
49.0k
      macro->name = sb_terminate (&name);
700
49.0k
      if (name.len == 0)
701
5.23k
  error = _("Missing macro name");
702
49.0k
      cidx = sb_skip_white (idx, in);
703
49.0k
      idx = sb_skip_comma (cidx, in);
704
49.0k
      if (idx == cidx || idx < in->len)
705
33.6k
  idx = do_formals (macro, idx, in);
706
15.4k
      else
707
15.4k
  idx = cidx;
708
49.0k
    }
709
50.5k
  if (!error && idx < in->len)
710
29.3k
    error = _("Bad parameter list for macro `%s'");
711
712
  /* And stick it in the macro hash table.  */
713
113k
  for (idx = 0; idx < name.len; idx++)
714
63.4k
    name.ptr[idx] = TOLOWER (name.ptr[idx]);
715
50.5k
  if (!error)
716
8.04k
    {
717
8.04k
      if (str_hash_insert (macro_hash, macro->name, macro, 0) != NULL)
718
7.32k
  error = _("Macro `%s' was already defined");
719
8.04k
    }
720
721
50.5k
  if (!error)
722
713
    macro_defined = 1;
723
49.8k
  else
724
49.8k
    {
725
49.8k
      as_bad_where (macro->file, macro->line, error, macro->name);
726
49.8k
      free_macro (macro);
727
49.8k
      macro = NULL;
728
49.8k
    }
729
730
50.5k
  return macro;
731
50.5k
}
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
317k
{
738
317k
  idx = get_token (idx, in, name);
739
317k
  if (idx < in->len
740
317k
      && in->ptr[idx] == kind
741
317k
      && (! flag_mri || macro_strip_at)
742
317k
      && (! macro_strip_at || kind == '@'))
743
38
    idx++;
744
317k
  return idx;
745
317k
}
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
317k
{
753
317k
  size_t src;
754
317k
  formal_entry *ptr;
755
756
317k
  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
317k
  if (macro_strip_at
760
317k
      && kind == '@'
761
317k
      && (src == start || in->ptr[src - 1] != '@'))
762
0
    ptr = NULL;
763
317k
  else
764
317k
    ptr = str_hash_find (formal_hash, sb_terminate (t));
765
317k
  if (ptr)
766
14.9k
    {
767
14.9k
      if (ptr->actual.len)
768
1.34k
  {
769
1.34k
    sb_add_sb (out, &ptr->actual);
770
1.34k
  }
771
13.6k
      else
772
13.6k
  {
773
13.6k
    sb_add_sb (out, &ptr->def);
774
13.6k
  }
775
14.9k
    }
776
302k
  else if (kind == '&')
777
1.77k
    {
778
      /* Doing this permits people to use & in macro bodies.  */
779
1.77k
      sb_add_char (out, '&');
780
1.77k
      sb_add_sb (out, t);
781
1.77k
      if (src != start && in->ptr[src - 1] == '&')
782
38
  sb_add_char (out, '&');
783
1.77k
    }
784
300k
  else if (copyifnotthere)
785
283k
    {
786
283k
      sb_add_sb (out, t);
787
283k
    }
788
17.1k
  else
789
17.1k
    {
790
17.1k
      sb_add_char (out, '\\');
791
17.1k
      sb_add_sb (out, t);
792
17.1k
    }
793
317k
  return src;
794
317k
}
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
78.7k
{
802
78.7k
  sb t;
803
78.7k
  size_t src = 0;
804
78.7k
  int inquote = 0, macro_line = 0;
805
78.7k
  formal_entry *loclist = NULL;
806
78.7k
  const char *err = NULL;
807
808
78.7k
  sb_new (&t);
809
810
4.74M
  while (src < in->len && !err)
811
4.66M
    {
812
4.66M
      if (in->ptr[src] == '&')
813
4.67k
  {
814
4.67k
    sb_reset (&t);
815
4.67k
    if (flag_mri)
816
2.90k
      {
817
2.90k
        if (src + 1 < in->len && in->ptr[src + 1] == '&')
818
66
    src = sub_actual (src + 2, in, &t, formal_hash, '\'', out, 1);
819
2.83k
        else
820
2.83k
    sb_add_char (out, in->ptr[src++]);
821
2.90k
      }
822
1.77k
    else
823
1.77k
      {
824
        /* Permit macro parameter substitution delineated with
825
     an '&' prefix and optional '&' suffix.  */
826
1.77k
        src = sub_actual (src + 1, in, &t, formal_hash, '&', out, 0);
827
1.77k
      }
828
4.67k
  }
829
4.65M
      else if (in->ptr[src] == '\\')
830
21.4k
  {
831
21.4k
    src++;
832
21.4k
    if (src < in->len && in->ptr[src] == '(')
833
22
      {
834
        /* Sub in till the next ')' literally.  */
835
22
        src++;
836
3.81k
        while (src < in->len && in->ptr[src] != ')')
837
3.79k
    {
838
3.79k
      sb_add_char (out, in->ptr[src++]);
839
3.79k
    }
840
22
        if (src < in->len)
841
0
    src++;
842
22
        else if (!macro)
843
0
    err = _("missing `)'");
844
22
        else
845
22
    as_bad_where (macro->file, macro->line + macro_line, _("missing `)'"));
846
22
      }
847
21.4k
    else if (src < in->len && in->ptr[src] == '@')
848
0
      {
849
        /* Sub in the macro invocation number.  */
850
851
0
        char buffer[12];
852
0
        src++;
853
0
        sprintf (buffer, "%d", macro_number);
854
0
        sb_add_string (out, buffer);
855
0
      }
856
21.4k
    else if (src < in->len && in->ptr[src] == '&')
857
260
      {
858
        /* This is a preprocessor variable name, we don't do them
859
     here.  */
860
260
        sb_add_char (out, '\\');
861
260
        sb_add_char (out, '&');
862
260
        src++;
863
260
      }
864
21.1k
    else if (flag_mri && src < in->len && ISALNUM (in->ptr[src]))
865
4.03k
      {
866
4.03k
        int ind;
867
4.03k
        formal_entry *f;
868
869
4.03k
        if (ISDIGIT (in->ptr[src]))
870
3.82k
    ind = in->ptr[src] - '0';
871
209
        else if (ISUPPER (in->ptr[src]))
872
161
    ind = in->ptr[src] - 'A' + 10;
873
48
        else
874
48
    ind = in->ptr[src] - 'a' + 10;
875
4.03k
        ++src;
876
8.13k
        for (f = formals; f != NULL; f = f->next)
877
4.10k
    {
878
4.10k
      if (f->index == ind - 1)
879
8
        {
880
8
          if (f->actual.len != 0)
881
8
      sb_add_sb (out, &f->actual);
882
0
          else
883
0
      sb_add_sb (out, &f->def);
884
8
          break;
885
8
        }
886
4.10k
    }
887
4.03k
      }
888
17.1k
    else
889
17.1k
      {
890
17.1k
        sb_reset (&t);
891
17.1k
        src = sub_actual (src, in, &t, formal_hash, '\'', out, 0);
892
17.1k
      }
893
21.4k
  }
894
4.63M
      else if ((flag_macro_alternate || flag_mri)
895
4.63M
         && is_name_beginner (in->ptr[src])
896
4.63M
         && (! inquote
897
298k
       || ! macro_strip_at
898
298k
       || (src > 0 && in->ptr[src - 1] == '@')))
899
298k
  {
900
298k
    if (! macro
901
298k
        || src + 5 >= in->len
902
298k
        || strncasecmp (in->ptr + src, "LOCAL", 5) != 0
903
298k
        || ! ISWHITE (in->ptr[src + 5])
904
        /* PR 11507: Skip keyword LOCAL if it is found inside a quoted string.  */
905
298k
        || inquote)
906
298k
      {
907
298k
        sb_reset (&t);
908
298k
        src = sub_actual (src, in, &t, formal_hash,
909
298k
        (macro_strip_at && inquote) ? '@' : '\'',
910
298k
        out, 1);
911
298k
      }
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
298k
  }
946
4.33M
      else if (in->ptr[src] == '"'
947
4.33M
         || (flag_mri && in->ptr[src] == '\''))
948
11.0k
  {
949
11.0k
    inquote = !inquote;
950
11.0k
    sb_add_char (out, in->ptr[src++]);
951
11.0k
  }
952
4.32M
      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
4.32M
      else if (flag_mri
963
4.32M
         && in->ptr[src] == '='
964
4.32M
         && src + 1 < in->len
965
4.32M
         && in->ptr[src + 1] == '=')
966
595
  {
967
595
    formal_entry *ptr;
968
969
595
    sb_reset (&t);
970
595
    src = get_token (src + 2, in, &t);
971
595
    ptr = str_hash_find (formal_hash, sb_terminate (&t));
972
595
    if (ptr == NULL)
973
595
      {
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
595
        sb_add_char (out, '=');
983
595
        sb_add_char (out, '=');
984
595
        sb_add_sb (out, &t);
985
595
      }
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
595
  }
998
4.32M
      else
999
4.32M
  {
1000
4.32M
    if (in->ptr[src] == '\n')
1001
158k
      ++macro_line;
1002
4.32M
    sb_add_char (out, in->ptr[src++]);
1003
4.32M
  }
1004
4.66M
    }
1005
1006
78.7k
  sb_kill (&t);
1007
1008
78.7k
  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
78.7k
  if (!err && (out->len == 0 || out->ptr[out->len - 1] != '\n'))
1021
49.3k
    sb_add_char (out, '\n');
1022
78.7k
  return err;
1023
78.7k
}
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
29.0k
{
1031
29.0k
  sb t;
1032
29.0k
  formal_entry *ptr;
1033
29.0k
  formal_entry *f;
1034
29.0k
  int is_keyword = 0;
1035
29.0k
  int narg = 0;
1036
29.0k
  const char *err = NULL;
1037
1038
29.0k
  sb_new (&t);
1039
1040
  /* Reset any old value the actuals may have.  */
1041
59.2k
  for (f = m->formals; f; f = f->next)
1042
30.2k
    sb_reset (&f->actual);
1043
29.0k
  f = m->formals;
1044
39.0k
  while (f != NULL && f->index < 0)
1045
9.99k
    f = f->next;
1046
1047
29.0k
  if (flag_mri)
1048
15.3k
    {
1049
      /* The macro may be called with an optional qualifier, which may
1050
   be referred to in the macro body as \0.  */
1051
15.3k
      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
15.3k
    }
1071
1072
  /* Peel off the actuals and store them away in the hash tables' actuals.  */
1073
29.0k
  idx = sb_skip_white (idx, in);
1074
42.7k
  while (idx < in->len)
1075
31.0k
    {
1076
31.0k
      size_t scan;
1077
1078
      /* Look and see if it's a positional or keyword arg.  */
1079
31.0k
      scan = idx;
1080
124k
      while (scan < in->len
1081
124k
       && !ISSEP (in->ptr[scan])
1082
124k
       && !(flag_mri && in->ptr[scan] == '\'')
1083
124k
       && (!flag_macro_alternate && in->ptr[scan] != '='))
1084
93.1k
  scan++;
1085
31.0k
      if (scan < in->len && !flag_macro_alternate && in->ptr[scan] == '=')
1086
1.70k
  {
1087
1.70k
    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
1.70k
    sb_reset (&t);
1094
1.70k
    idx = get_token (idx, in, &t);
1095
1.70k
    if (idx >= in->len || in->ptr[idx] != '=')
1096
186
      {
1097
186
        err = _("confusion in formal parameters");
1098
186
        break;
1099
186
      }
1100
1101
    /* Lookup the formal in the macro's list.  */
1102
1.51k
    ptr = str_hash_find (m->formal_hash, sb_terminate (&t));
1103
1.51k
    if (!ptr)
1104
187
      {
1105
187
        as_bad (_("Parameter named `%s' does not exist for macro `%s'"),
1106
187
          t.ptr,
1107
187
          m->name);
1108
187
        sb_reset (&t);
1109
187
        idx = get_any_string (idx + 1, in, &t);
1110
187
      }
1111
1.33k
    else
1112
1.33k
      {
1113
        /* Insert this value into the right place.  */
1114
1.33k
        if (ptr->actual.len)
1115
145
    {
1116
145
      as_warn (_("Value for parameter `%s' of macro `%s' was already specified"),
1117
145
         ptr->name.ptr,
1118
145
         m->name);
1119
145
      sb_reset (&ptr->actual);
1120
145
    }
1121
1.33k
        idx = get_any_string (idx + 1, in, &ptr->actual);
1122
1.33k
        if (ptr->actual.len > 0)
1123
1.31k
    ++narg;
1124
1.33k
      }
1125
1.51k
  }
1126
29.3k
      else
1127
29.3k
  {
1128
29.3k
    if (is_keyword)
1129
1.17k
      {
1130
1.17k
        err = _("can't mix positional and keyword arguments");
1131
1.17k
        break;
1132
1.17k
      }
1133
1134
28.1k
    if (!f)
1135
18.9k
      {
1136
18.9k
        formal_entry **pf;
1137
18.9k
        int c;
1138
1139
18.9k
        if (!flag_mri)
1140
10.0k
    {
1141
10.0k
      err = _("too many positional arguments");
1142
10.0k
      break;
1143
10.0k
    }
1144
1145
8.88k
        f = new_formal ();
1146
1147
8.88k
        c = -1;
1148
19.5k
        for (pf = &m->formals; *pf != NULL; pf = &(*pf)->next)
1149
10.6k
    if ((*pf)->index >= c)
1150
2.69k
      c = (*pf)->index + 1;
1151
8.88k
        if (c == -1)
1152
8.24k
    c = 0;
1153
8.88k
        *pf = f;
1154
8.88k
        f->index = c;
1155
8.88k
      }
1156
1157
18.0k
    if (f->type != FORMAL_VARARG)
1158
18.0k
      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
18.0k
    if (f->actual.len > 0)
1165
15.9k
      ++narg;
1166
18.0k
    do
1167
21.1k
      {
1168
21.1k
        f = f->next;
1169
21.1k
      }
1170
21.1k
    while (f != NULL && f->index < 0);
1171
18.0k
  }
1172
1173
19.6k
      if (! flag_mri)
1174
5.28k
  idx = sb_skip_comma (idx, in);
1175
14.3k
      else
1176
14.3k
  {
1177
14.3k
    if (idx < in->len && in->ptr[idx] == ',')
1178
4.24k
      ++idx;
1179
14.3k
    if (idx < in->len && ISWHITE (in->ptr[idx]))
1180
5.91k
      break;
1181
14.3k
  }
1182
19.6k
    }
1183
1184
29.0k
  if (! err)
1185
17.6k
    {
1186
50.2k
      for (ptr = m->formals; ptr; ptr = ptr->next)
1187
32.6k
  {
1188
32.6k
    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
32.6k
  }
1193
1194
17.6k
      if (flag_mri)
1195
14.7k
  {
1196
14.7k
    ptr = str_hash_find (m->formal_hash,
1197
14.7k
             macro_strip_at ? "$NARG" : "NARG");
1198
14.7k
    if (ptr)
1199
13.4k
      {
1200
13.4k
        char buffer[20];
1201
13.4k
        sprintf (buffer, "%d", narg);
1202
13.4k
        sb_add_string (&ptr->actual, buffer);
1203
13.4k
      }
1204
14.7k
  }
1205
1206
17.6k
      err = macro_expand_body (&m->sub, out, m->formals, m->formal_hash, m);
1207
17.6k
    }
1208
1209
  /* Discard any unnamed formal arguments.  */
1210
29.0k
  if (flag_mri)
1211
15.3k
    {
1212
15.3k
      formal_entry **pf;
1213
1214
15.3k
      pf = &m->formals;
1215
46.3k
      while (*pf != NULL)
1216
30.9k
  {
1217
30.9k
    if ((*pf)->name.len != 0)
1218
22.0k
      pf = &(*pf)->next;
1219
8.88k
    else
1220
8.88k
      {
1221
8.88k
        f = (*pf)->next;
1222
8.88k
        del_formal (*pf);
1223
8.88k
        *pf = f;
1224
8.88k
      }
1225
30.9k
  }
1226
15.3k
    }
1227
1228
29.0k
  sb_kill (&t);
1229
29.0k
  if (!err)
1230
17.6k
    macro_number++;
1231
1232
29.0k
  return err;
1233
29.0k
}
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
767k
{
1242
767k
  const char *s;
1243
767k
  char *copy, *cls;
1244
767k
  macro_entry *macro;
1245
767k
  sb line_sb;
1246
1247
767k
  if (! is_name_beginner (*line)
1248
767k
      && (! flag_mri || *line != '.'))
1249
4.77k
    return 0;
1250
1251
762k
  s = line + 1;
1252
3.27M
  while (is_part_of_name (*s))
1253
2.51M
    ++s;
1254
762k
  if (is_name_ender (*s))
1255
0
    ++s;
1256
1257
762k
  copy = xmemdup0 (line, s - line);
1258
4.03M
  for (cls = copy; *cls != '\0'; cls ++)
1259
3.27M
    *cls = TOLOWER (*cls);
1260
1261
762k
  macro = str_hash_find (macro_hash, copy);
1262
762k
  free (copy);
1263
1264
762k
  if (macro == NULL)
1265
733k
    return 0;
1266
1267
  /* Wrap the line up in an sb.  */
1268
29.0k
  sb_new (&line_sb);
1269
428k
  while (*s != '\0' && *s != '\n' && *s != '\r')
1270
399k
    sb_add_char (&line_sb, *s++);
1271
1272
29.0k
  sb_new (expand);
1273
29.0k
  *error = macro_expand (0, &line_sb, macro, expand);
1274
1275
29.0k
  sb_kill (&line_sb);
1276
1277
  /* Export the macro information if requested.  */
1278
29.0k
  if (info)
1279
29.0k
    *info = macro;
1280
1281
29.0k
  return 1;
1282
762k
}
1283
1284
/* Delete a macro.  */
1285
1286
void
1287
delete_macro (const char *name)
1288
3.39k
{
1289
3.39k
  char *copy;
1290
3.39k
  size_t i, len;
1291
3.39k
  macro_entry *macro;
1292
1293
3.39k
  len = strlen (name);
1294
3.39k
  copy = XNEWVEC (char, len + 1);
1295
8.08k
  for (i = 0; i < len; ++i)
1296
4.68k
    copy[i] = TOLOWER (name[i]);
1297
3.39k
  copy[i] = '\0';
1298
1299
3.39k
  macro = str_hash_find (macro_hash, copy);
1300
3.39k
  if (macro != NULL)
1301
1
    str_hash_delete (macro_hash, copy);
1302
3.39k
  else
1303
3.39k
    as_warn (_("Attempt to purge non-existing macro `%s'"), copy);
1304
3.39k
  free (copy);
1305
3.39k
}
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
54.3k
{
1314
54.3k
  sb sub;
1315
54.3k
  formal_entry f;
1316
54.3k
  struct htab *h;
1317
54.3k
  const char *err = NULL;
1318
1319
54.3k
  idx = sb_skip_white (idx, in);
1320
1321
54.3k
  sb_new (&sub);
1322
54.3k
  if (! buffer_and_nest (NULL, "ENDR", &sub, get_line))
1323
8.62k
    {
1324
8.62k
      err = _("unexpected end of file in irp or irpc");
1325
8.62k
      goto out2;
1326
8.62k
    }
1327
1328
45.7k
  sb_new (&f.name);
1329
45.7k
  sb_new (&f.def);
1330
45.7k
  sb_new (&f.actual);
1331
1332
45.7k
  idx = get_token (idx, in, &f.name);
1333
45.7k
  if (f.name.len == 0)
1334
11.5k
    {
1335
11.5k
      err = _("missing model parameter");
1336
11.5k
      goto out1;
1337
11.5k
    }
1338
1339
34.2k
  h = str_htab_create ();
1340
1341
34.2k
  str_hash_insert (h, sb_terminate (&f.name), &f, 0);
1342
1343
34.2k
  f.index = 1;
1344
34.2k
  f.next = NULL;
1345
34.2k
  f.type = FORMAL_OPTIONAL;
1346
1347
34.2k
  sb_reset (out);
1348
1349
34.2k
  idx = sb_skip_comma (idx, in);
1350
34.2k
  if (idx >= in->len)
1351
31.7k
    {
1352
      /* Expand once with a null string.  */
1353
31.7k
      err = macro_expand_body (&sub, out, &f, h, 0);
1354
31.7k
    }
1355
2.51k
  else
1356
2.51k
    {
1357
2.51k
      bool in_quotes = false;
1358
1359
2.51k
      if (irpc && in->ptr[idx] == '"')
1360
0
  {
1361
0
    in_quotes = true;
1362
0
    ++idx;
1363
0
  }
1364
1365
31.9k
      while (idx < in->len)
1366
29.4k
  {
1367
29.4k
    if (!irpc)
1368
28.3k
      idx = get_any_string (idx, in, &f.actual);
1369
1.15k
    else
1370
1.15k
      {
1371
1.15k
        if (in->ptr[idx] == '"')
1372
6
    {
1373
6
      size_t nxt;
1374
1375
6
      if (irpc)
1376
6
        in_quotes = ! in_quotes;
1377
1378
6
      nxt = sb_skip_white (idx + 1, in);
1379
6
      if (nxt >= in->len)
1380
0
        {
1381
0
          idx = nxt;
1382
0
          break;
1383
0
        }
1384
6
    }
1385
1.15k
        sb_reset (&f.actual);
1386
1.15k
        sb_add_char (&f.actual, in->ptr[idx]);
1387
1.15k
        ++idx;
1388
1.15k
      }
1389
1390
29.4k
    err = macro_expand_body (&sub, out, &f, h, 0);
1391
29.4k
    if (err != NULL)
1392
0
      break;
1393
29.4k
    if (!irpc)
1394
28.3k
      idx = sb_skip_comma (idx, in);
1395
1.15k
    else if (! in_quotes)
1396
687
      idx = sb_skip_white (idx, in);
1397
29.4k
  }
1398
2.51k
    }
1399
1400
34.2k
  htab_delete (h);
1401
45.7k
 out1:
1402
45.7k
  sb_kill (&f.actual);
1403
45.7k
  sb_kill (&f.def);
1404
45.7k
  sb_kill (&f.name);
1405
54.3k
 out2:
1406
54.3k
  sb_kill (&sub);
1407
1408
54.3k
  return err;
1409
45.7k
}