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