Coverage Report

Created: 2026-10-02 09:53

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