]> git.ipfire.org Git - thirdparty/binutils-gdb.git/blame - gas/macro.c
Convert to ISO C90 formatting
[thirdparty/binutils-gdb.git] / gas / macro.c
CommitLineData
fea17916 1/* macro.c - macro support for gas
2da5c037
AM
2 Copyright 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003,
3 2004, 2005 Free Software Foundation, Inc.
252b5132
RH
4
5 Written by Steve and Judy Chamberlain of Cygnus Support,
6 sac@cygnus.com
7
8 This file is part of GAS, the GNU Assembler.
9
10 GAS is free software; you can redistribute it and/or modify
11 it under the terms of the GNU General Public License as published by
12 the Free Software Foundation; either version 2, or (at your option)
13 any later version.
14
15 GAS is distributed in the hope that it will be useful,
16 but WITHOUT ANY WARRANTY; without even the implied warranty of
17 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 GNU General Public License for more details.
19
20 You should have received a copy of the GNU General Public License
21 along with GAS; see the file COPYING. If not, write to the Free
22 Software Foundation, 59 Temple Place - Suite 330, Boston, MA
29f8404c 23 02111-1307, USA. */
252b5132
RH
24
25#include "config.h"
26
fa6e9318 27#ifndef __GNUC__
252b5132
RH
28# if HAVE_ALLOCA_H
29# include <alloca.h>
30# else
31# ifdef _AIX
fa6e9318
AM
32/* Indented so that pre-ansi C compilers will ignore it, rather than
33 choke on it. Some versions of AIX require this to be the first
34 thing in the file. */
252b5132
RH
35 #pragma alloca
36# else
37# ifndef alloca /* predefined by HP cc +Olibcalls */
38# if !defined (__STDC__) && !defined (__hpux)
39extern char *alloca ();
40# else
41extern void *alloca ();
42# endif /* __STDC__, __hpux */
43# endif /* alloca */
44# endif /* _AIX */
45# endif /* HAVE_ALLOCA_H */
fa6e9318 46#endif /* __GNUC__ */
252b5132
RH
47
48#include <stdio.h>
49#ifdef HAVE_STRING_H
50#include <string.h>
51#else
52#include <strings.h>
53#endif
252b5132
RH
54#ifdef HAVE_STDLIB_H
55#include <stdlib.h>
56#endif
89658e52 57#include "as.h"
252b5132 58#include "libiberty.h"
3882b010 59#include "safe-ctype.h"
252b5132
RH
60#include "sb.h"
61#include "hash.h"
62#include "macro.h"
63
64#include "asintl.h"
65
66/* The routines in this file handle macro definition and expansion.
fea17916 67 They are called by gas. */
252b5132 68
252b5132
RH
69/* Internal functions. */
70
254d758c
KH
71static int get_token (int, sb *, sb *);
72static int getstring (int, sb *, sb *);
73static int get_any_string (int, sb *, sb *, int, int);
74static int do_formals (macro_entry *, int, sb *);
75static int get_apost_token (int, sb *, sb *, int);
76static int sub_actual (int, sb *, sb *, struct hash_control *, int, sb *, int);
252b5132 77static const char *macro_expand_body
254d758c
KH
78 (sb *, sb *, formal_entry *, struct hash_control *, int);
79static const char *macro_expand (int, sb *, macro_entry *, sb *);
252b5132
RH
80
81#define ISWHITE(x) ((x) == ' ' || (x) == '\t')
82
83#define ISSEP(x) \
84 ((x) == ' ' || (x) == '\t' || (x) == ',' || (x) == '"' || (x) == ';' \
85 || (x) == ')' || (x) == '(' \
86 || ((macro_alternate || macro_mri) && ((x) == '<' || (x) == '>')))
87
88#define ISBASE(x) \
89 ((x) == 'b' || (x) == 'B' \
90 || (x) == 'q' || (x) == 'Q' \
91 || (x) == 'h' || (x) == 'H' \
92 || (x) == 'd' || (x) == 'D')
93
94/* The macro hash table. */
95
1c53c80d 96struct hash_control *macro_hash;
252b5132
RH
97
98/* Whether any macros have been defined. */
99
100int macro_defined;
101
fea17916 102/* Whether we are in alternate syntax mode. */
252b5132
RH
103
104static int macro_alternate;
105
106/* Whether we are in MRI mode. */
107
108static int macro_mri;
109
110/* Whether we should strip '@' characters. */
111
112static int macro_strip_at;
113
114/* Function to use to parse an expression. */
115
254d758c 116static int (*macro_expr) (const char *, int, sb *, int *);
252b5132
RH
117
118/* Number of macro expansions that have been done. */
119
120static int macro_number;
121
122/* Initialize macro processing. */
123
124void
254d758c
KH
125macro_init (int alternate, int mri, int strip_at,
126 int (*expr) (const char *, int, sb *, int *))
252b5132
RH
127{
128 macro_hash = hash_new ();
129 macro_defined = 0;
130 macro_alternate = alternate;
131 macro_mri = mri;
132 macro_strip_at = strip_at;
133 macro_expr = expr;
134}
135
caa32fe5
NC
136/* Switch in and out of alternate mode on the fly. */
137
138void
2766e5e4 139macro_set_alternate (int alternate)
caa32fe5
NC
140{
141 macro_alternate = alternate;
142}
143
252b5132
RH
144/* Switch in and out of MRI mode on the fly. */
145
146void
254d758c 147macro_mri_mode (int mri)
252b5132
RH
148{
149 macro_mri = mri;
150}
151
152/* Read input lines till we get to a TO string.
153 Increase nesting depth if we get a FROM string.
154 Put the results into sb at PTR.
ca3bc58f 155 FROM may be NULL (or will be ignored) if TO is "ENDR".
252b5132
RH
156 Add a new input line to an sb using GET_LINE.
157 Return 1 on success, 0 on unexpected EOF. */
158
159int
254d758c
KH
160buffer_and_nest (const char *from, const char *to, sb *ptr,
161 int (*get_line) (sb *))
252b5132 162{
ca3bc58f 163 int from_len;
252b5132
RH
164 int to_len = strlen (to);
165 int depth = 1;
166 int line_start = ptr->len;
167
168 int more = get_line (ptr);
169
ca3bc58f
JB
170 if (to_len == 4 && strcasecmp(to, "ENDR") == 0)
171 {
172 from = NULL;
173 from_len = 0;
174 }
175 else
176 from_len = strlen (from);
177
252b5132
RH
178 while (more)
179 {
29f8404c 180 /* Try and find the first pseudo op on the line. */
252b5132
RH
181 int i = line_start;
182
ca3bc58f 183 if (! NO_PSEUDO_DOT && ! flag_m68k_mri)
252b5132
RH
184 {
185 /* With normal syntax we can suck what we want till we get
186 to the dot. With the alternate, labels have to start in
ca3bc58f 187 the first column, since we can't tell what's a label and
29f8404c 188 whats a pseudoop. */
252b5132 189
29f8404c 190 /* Skip leading whitespace. */
252b5132
RH
191 while (i < ptr->len && ISWHITE (ptr->ptr[i]))
192 i++;
193
29f8404c 194 /* Skip over a label. */
252b5132 195 while (i < ptr->len
3882b010 196 && (ISALNUM (ptr->ptr[i])
252b5132
RH
197 || ptr->ptr[i] == '_'
198 || ptr->ptr[i] == '$'))
199 i++;
200
29f8404c 201 /* And a colon. */
252b5132
RH
202 if (i < ptr->len
203 && ptr->ptr[i] == ':')
204 i++;
205
206 }
29f8404c 207 /* Skip trailing whitespace. */
252b5132
RH
208 while (i < ptr->len && ISWHITE (ptr->ptr[i]))
209 i++;
210
211 if (i < ptr->len && (ptr->ptr[i] == '.'
ca3bc58f 212 || NO_PSEUDO_DOT
252b5132
RH
213 || macro_mri))
214 {
ca3bc58f 215 if (! flag_m68k_mri && ptr->ptr[i] == '.')
29f8404c 216 i++;
ca3bc58f
JB
217 if (from == NULL
218 && strncasecmp (ptr->ptr + i, "IRPC", from_len = 4) != 0
219 && strncasecmp (ptr->ptr + i, "IRP", from_len = 3) != 0
220 && strncasecmp (ptr->ptr + i, "IREPC", from_len = 5) != 0
221 && strncasecmp (ptr->ptr + i, "IREP", from_len = 4) != 0
222 && strncasecmp (ptr->ptr + i, "REPT", from_len = 4) != 0
223 && strncasecmp (ptr->ptr + i, "REP", from_len = 3) != 0)
224 from_len = 0;
225 if ((from != NULL
226 ? strncasecmp (ptr->ptr + i, from, from_len) == 0
227 : from_len > 0)
29f8404c 228 && (ptr->len == (i + from_len)
3882b010 229 || ! ISALNUM (ptr->ptr[i + from_len])))
252b5132 230 depth++;
c1eae114 231 if (strncasecmp (ptr->ptr + i, to, to_len) == 0
29f8404c 232 && (ptr->len == (i + to_len)
3882b010 233 || ! ISALNUM (ptr->ptr[i + to_len])))
252b5132
RH
234 {
235 depth--;
236 if (depth == 0)
237 {
29f8404c 238 /* Reset the string to not include the ending rune. */
252b5132
RH
239 ptr->len = line_start;
240 break;
241 }
242 }
243 }
244
0822d075
NC
245 /* Add the original end-of-line char to the end and keep running. */
246 sb_add_char (ptr, more);
252b5132
RH
247 line_start = ptr->len;
248 more = get_line (ptr);
249 }
250
251 /* Return 1 on success, 0 on unexpected EOF. */
252 return depth == 0;
253}
254
255/* Pick up a token. */
256
257static int
254d758c 258get_token (int idx, sb *in, sb *name)
252b5132
RH
259{
260 if (idx < in->len
3882b010 261 && (ISALPHA (in->ptr[idx])
252b5132
RH
262 || in->ptr[idx] == '_'
263 || in->ptr[idx] == '$'))
264 {
265 sb_add_char (name, in->ptr[idx++]);
266 while (idx < in->len
3882b010 267 && (ISALNUM (in->ptr[idx])
252b5132
RH
268 || in->ptr[idx] == '_'
269 || in->ptr[idx] == '$'))
270 {
271 sb_add_char (name, in->ptr[idx++]);
272 }
273 }
29f8404c 274 /* Ignore trailing &. */
252b5132
RH
275 if (macro_alternate && idx < in->len && in->ptr[idx] == '&')
276 idx++;
277 return idx;
278}
279
280/* Pick up a string. */
281
282static int
254d758c 283getstring (int idx, sb *in, sb *acc)
252b5132
RH
284{
285 idx = sb_skip_white (idx, in);
286
287 while (idx < in->len
29f8404c 288 && (in->ptr[idx] == '"'
252b5132
RH
289 || (in->ptr[idx] == '<' && (macro_alternate || macro_mri))
290 || (in->ptr[idx] == '\'' && macro_alternate)))
291 {
292 if (in->ptr[idx] == '<')
293 {
294 int nest = 0;
295 idx++;
296 while ((in->ptr[idx] != '>' || nest)
297 && idx < in->len)
298 {
299 if (in->ptr[idx] == '!')
300 {
29f8404c 301 idx++;
252b5132
RH
302 sb_add_char (acc, in->ptr[idx++]);
303 }
304 else
305 {
306 if (in->ptr[idx] == '>')
307 nest--;
308 if (in->ptr[idx] == '<')
309 nest++;
310 sb_add_char (acc, in->ptr[idx++]);
311 }
312 }
313 idx++;
314 }
315 else if (in->ptr[idx] == '"' || in->ptr[idx] == '\'')
316 {
317 char tchar = in->ptr[idx];
c06ae4f2 318 int escaped = 0;
29f8404c 319
252b5132 320 idx++;
29f8404c 321
252b5132
RH
322 while (idx < in->len)
323 {
29f8404c 324 if (in->ptr[idx - 1] == '\\')
c06ae4f2
UC
325 escaped ^= 1;
326 else
327 escaped = 0;
328
252b5132
RH
329 if (macro_alternate && in->ptr[idx] == '!')
330 {
e972090a 331 idx ++;
29f8404c 332
1994a7c7
NC
333 sb_add_char (acc, in->ptr[idx]);
334
e972090a 335 idx ++;
252b5132 336 }
c06ae4f2
UC
337 else if (escaped && in->ptr[idx] == tchar)
338 {
339 sb_add_char (acc, tchar);
e972090a 340 idx ++;
c06ae4f2 341 }
252b5132
RH
342 else
343 {
344 if (in->ptr[idx] == tchar)
345 {
e972090a 346 idx ++;
29f8404c 347
252b5132
RH
348 if (idx >= in->len || in->ptr[idx] != tchar)
349 break;
350 }
29f8404c 351
252b5132 352 sb_add_char (acc, in->ptr[idx]);
e972090a 353 idx ++;
252b5132
RH
354 }
355 }
356 }
357 }
29f8404c 358
252b5132
RH
359 return idx;
360}
361
362/* Fetch string from the input stream,
363 rules:
364 'Bxyx<whitespace> -> return 'Bxyza
365 %<char> -> return string of decimal value of x
366 "<string>" -> return string
367 xyx<whitespace> -> return xyz
368*/
369
370static int
254d758c 371get_any_string (int idx, sb *in, sb *out, int expand, int pretend_quoted)
252b5132
RH
372{
373 sb_reset (out);
374 idx = sb_skip_white (idx, in);
375
376 if (idx < in->len)
377 {
9df59bba 378 if (in->len > idx + 2 && in->ptr[idx + 1] == '\'' && ISBASE (in->ptr[idx]))
252b5132
RH
379 {
380 while (!ISSEP (in->ptr[idx]))
381 sb_add_char (out, in->ptr[idx++]);
382 }
383 else if (in->ptr[idx] == '%'
384 && macro_alternate
385 && expand)
386 {
387 int val;
388 char buf[20];
29f8404c 389 /* Turns the next expression into a string. */
06f030db 390 /* xgettext: no-c-format */
252b5132
RH
391 idx = (*macro_expr) (_("% operator needs absolute expression"),
392 idx + 1,
393 in,
394 &val);
d1a6c242 395 sprintf (buf, "%d", val);
252b5132
RH
396 sb_add_string (out, buf);
397 }
398 else if (in->ptr[idx] == '"'
399 || (in->ptr[idx] == '<' && (macro_alternate || macro_mri))
400 || (macro_alternate && in->ptr[idx] == '\''))
401 {
402 if (macro_alternate
403 && ! macro_strip_at
404 && expand)
405 {
29f8404c
KH
406 /* Keep the quotes. */
407 sb_add_char (out, '\"');
252b5132
RH
408
409 idx = getstring (idx, in, out);
29f8404c 410 sb_add_char (out, '\"');
252b5132
RH
411 }
412 else
413 {
414 idx = getstring (idx, in, out);
415 }
416 }
29f8404c 417 else
252b5132 418 {
29f8404c 419 while (idx < in->len
252b5132
RH
420 && (in->ptr[idx] == '"'
421 || in->ptr[idx] == '\''
29f8404c 422 || pretend_quoted
252b5132
RH
423 || (in->ptr[idx] != ' '
424 && in->ptr[idx] != '\t'
425 && in->ptr[idx] != ','
426 && (in->ptr[idx] != '<'
427 || (! macro_alternate && ! macro_mri)))))
428 {
29f8404c 429 if (in->ptr[idx] == '"'
252b5132
RH
430 || in->ptr[idx] == '\'')
431 {
432 char tchar = in->ptr[idx];
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)
29f8404c 438 return idx;
252b5132
RH
439 }
440 sb_add_char (out, in->ptr[idx++]);
441 }
442 }
443 }
444
445 return idx;
446}
447
448/* Pick up the formal parameters of a macro definition. */
449
450static int
254d758c 451do_formals (macro_entry *macro, int idx, sb *in)
252b5132
RH
452{
453 formal_entry **p = &macro->formals;
454
455 macro->formal_count = 0;
456 macro->formal_hash = hash_new ();
057f53c1 457 idx = sb_skip_white (idx, in);
252b5132
RH
458 while (idx < in->len)
459 {
460 formal_entry *formal;
057f53c1 461 int cidx;
252b5132
RH
462
463 formal = (formal_entry *) xmalloc (sizeof (formal_entry));
464
465 sb_new (&formal->name);
466 sb_new (&formal->def);
467 sb_new (&formal->actual);
468
252b5132
RH
469 idx = get_token (idx, in, &formal->name);
470 if (formal->name.len == 0)
057f53c1
JB
471 {
472 if (macro->formal_count)
473 --idx;
474 break;
475 }
252b5132 476 idx = sb_skip_white (idx, in);
057f53c1
JB
477 /* This is a formal. */
478 if (idx < in->len && in->ptr[idx] == '=')
252b5132 479 {
057f53c1
JB
480 /* Got a default. */
481 idx = get_any_string (idx + 1, in, &formal->def, 1, 0);
482 idx = sb_skip_white (idx, in);
252b5132
RH
483 }
484
29f8404c 485 /* Add to macro's hash table. */
252b5132
RH
486 hash_jam (macro->formal_hash, sb_terminate (&formal->name), formal);
487
057f53c1
JB
488 formal->index = macro->formal_count++;
489 cidx = idx;
252b5132 490 idx = sb_skip_comma (idx, in);
057f53c1
JB
491 if (idx != cidx && idx >= in->len)
492 {
493 idx = cidx;
494 break;
495 }
252b5132
RH
496 *p = formal;
497 p = &formal->next;
498 *p = NULL;
499 }
500
501 if (macro_mri)
502 {
503 formal_entry *formal;
504 const char *name;
505
506 /* Add a special NARG formal, which macro_expand will set to the
507 number of arguments. */
508 formal = (formal_entry *) xmalloc (sizeof (formal_entry));
509
510 sb_new (&formal->name);
511 sb_new (&formal->def);
512 sb_new (&formal->actual);
513
514 /* The same MRI assemblers which treat '@' characters also use
515 the name $NARG. At least until we find an exception. */
516 if (macro_strip_at)
517 name = "$NARG";
518 else
519 name = "NARG";
520
521 sb_add_string (&formal->name, name);
522
29f8404c 523 /* Add to macro's hash table. */
252b5132
RH
524 hash_jam (macro->formal_hash, name, formal);
525
526 formal->index = NARG_INDEX;
527 *p = formal;
528 formal->next = NULL;
529 }
530
531 return idx;
532}
533
534/* Define a new macro. Returns NULL on success, otherwise returns an
535 error message. If NAMEP is not NULL, *NAMEP is set to the name of
536 the macro which was defined. */
537
538const char *
254d758c
KH
539define_macro (int idx, sb *in, sb *label,
540 int (*get_line) (sb *), const char **namep)
252b5132
RH
541{
542 macro_entry *macro;
543 sb name;
544 const char *namestr;
545
546 macro = (macro_entry *) xmalloc (sizeof (macro_entry));
547 sb_new (&macro->sub);
548 sb_new (&name);
549
550 macro->formal_count = 0;
551 macro->formals = 0;
552
553 idx = sb_skip_white (idx, in);
554 if (! buffer_and_nest ("MACRO", "ENDM", &macro->sub, get_line))
555 return _("unexpected end of file in macro definition");
556 if (label != NULL && label->len != 0)
557 {
558 sb_add_sb (&name, label);
559 if (idx < in->len && in->ptr[idx] == '(')
560 {
29f8404c 561 /* It's the label: MACRO (formals,...) sort */
252b5132 562 idx = do_formals (macro, idx + 1, in);
057f53c1 563 if (idx >= in->len || in->ptr[idx] != ')')
252b5132 564 return _("missing ) after formals");
057f53c1 565 idx = sb_skip_white (idx + 1, in);
252b5132
RH
566 }
567 else
568 {
29f8404c 569 /* It's the label: MACRO formals,... sort */
252b5132
RH
570 idx = do_formals (macro, idx, in);
571 }
572 }
573 else
574 {
057f53c1
JB
575 int cidx;
576
252b5132 577 idx = get_token (idx, in, &name);
057f53c1
JB
578 if (name.len == 0)
579 return _("Missing macro name");
580 cidx = sb_skip_white (idx, in);
581 idx = sb_skip_comma (cidx, in);
582 if (idx == cidx || idx < in->len)
583 idx = do_formals (macro, idx, in);
584 else
585 idx = cidx;
252b5132 586 }
057f53c1
JB
587 if (idx < in->len)
588 return _("Bad macro parameter list");
252b5132 589
29f8404c 590 /* And stick it in the macro hash table. */
252b5132 591 for (idx = 0; idx < name.len; idx++)
3882b010 592 name.ptr[idx] = TOLOWER (name.ptr[idx]);
252b5132 593 namestr = sb_terminate (&name);
057f53c1
JB
594 if (hash_find (macro_hash, namestr))
595 return _("Macro with this name was already defined");
252b5132
RH
596 hash_jam (macro_hash, namestr, (PTR) macro);
597
598 macro_defined = 1;
599
600 if (namep != NULL)
601 *namep = namestr;
602
603 return NULL;
604}
605
606/* Scan a token, and then skip KIND. */
607
608static int
254d758c 609get_apost_token (int idx, sb *in, sb *name, int kind)
252b5132
RH
610{
611 idx = get_token (idx, in, name);
612 if (idx < in->len
613 && in->ptr[idx] == kind
614 && (! macro_mri || macro_strip_at)
615 && (! macro_strip_at || kind == '@'))
616 idx++;
617 return idx;
618}
619
620/* Substitute the actual value for a formal parameter. */
621
622static int
254d758c
KH
623sub_actual (int start, sb *in, sb *t, struct hash_control *formal_hash,
624 int kind, sb *out, int copyifnotthere)
252b5132
RH
625{
626 int src;
627 formal_entry *ptr;
628
629 src = get_apost_token (start, in, t, kind);
630 /* See if it's in the macro's hash table, unless this is
631 macro_strip_at and kind is '@' and the token did not end in '@'. */
632 if (macro_strip_at
633 && kind == '@'
634 && (src == start || in->ptr[src - 1] != '@'))
635 ptr = NULL;
636 else
637 ptr = (formal_entry *) hash_find (formal_hash, sb_terminate (t));
638 if (ptr)
639 {
640 if (ptr->actual.len)
641 {
642 sb_add_sb (out, &ptr->actual);
643 }
644 else
645 {
646 sb_add_sb (out, &ptr->def);
647 }
648 }
649 else if (kind == '&')
650 {
651 /* Doing this permits people to use & in macro bodies. */
652 sb_add_char (out, '&');
c1ed1235 653 sb_add_sb (out, t);
252b5132
RH
654 }
655 else if (copyifnotthere)
656 {
657 sb_add_sb (out, t);
658 }
29f8404c 659 else
252b5132
RH
660 {
661 sb_add_char (out, '\\');
662 sb_add_sb (out, t);
663 }
664 return src;
665}
666
667/* Expand the body of a macro. */
668
669static const char *
254d758c
KH
670macro_expand_body (sb *in, sb *out, formal_entry *formals,
671 struct hash_control *formal_hash, int locals)
252b5132
RH
672{
673 sb t;
674 int src = 0;
675 int inquote = 0;
676 formal_entry *loclist = NULL;
677
678 sb_new (&t);
679
680 while (src < in->len)
681 {
682 if (in->ptr[src] == '&')
683 {
684 sb_reset (&t);
685 if (macro_mri)
686 {
687 if (src + 1 < in->len && in->ptr[src + 1] == '&')
688 src = sub_actual (src + 2, in, &t, formal_hash, '\'', out, 1);
689 else
690 sb_add_char (out, in->ptr[src++]);
691 }
692 else
693 {
694 /* FIXME: Why do we do this? */
695 src = sub_actual (src + 1, in, &t, formal_hash, '&', out, 0);
696 }
697 }
698 else if (in->ptr[src] == '\\')
699 {
700 src++;
fea17916 701 if (in->ptr[src] == '(')
252b5132 702 {
29f8404c 703 /* Sub in till the next ')' literally. */
252b5132
RH
704 src++;
705 while (src < in->len && in->ptr[src] != ')')
706 {
707 sb_add_char (out, in->ptr[src++]);
708 }
709 if (in->ptr[src] == ')')
710 src++;
711 else
712 return _("missplaced )");
713 }
714 else if (in->ptr[src] == '@')
715 {
29f8404c 716 /* Sub in the macro invocation number. */
252b5132
RH
717
718 char buffer[10];
719 src++;
a2984248 720 sprintf (buffer, "%d", macro_number);
252b5132
RH
721 sb_add_string (out, buffer);
722 }
723 else if (in->ptr[src] == '&')
724 {
725 /* This is a preprocessor variable name, we don't do them
29f8404c 726 here. */
252b5132
RH
727 sb_add_char (out, '\\');
728 sb_add_char (out, '&');
729 src++;
730 }
3882b010 731 else if (macro_mri && ISALNUM (in->ptr[src]))
252b5132
RH
732 {
733 int ind;
734 formal_entry *f;
735
3882b010 736 if (ISDIGIT (in->ptr[src]))
252b5132 737 ind = in->ptr[src] - '0';
3882b010 738 else if (ISUPPER (in->ptr[src]))
252b5132
RH
739 ind = in->ptr[src] - 'A' + 10;
740 else
741 ind = in->ptr[src] - 'a' + 10;
742 ++src;
743 for (f = formals; f != NULL; f = f->next)
744 {
745 if (f->index == ind - 1)
746 {
747 if (f->actual.len != 0)
748 sb_add_sb (out, &f->actual);
749 else
750 sb_add_sb (out, &f->def);
751 break;
752 }
753 }
754 }
755 else
756 {
757 sb_reset (&t);
758 src = sub_actual (src, in, &t, formal_hash, '\'', out, 0);
759 }
760 }
761 else if ((macro_alternate || macro_mri)
3882b010 762 && (ISALPHA (in->ptr[src])
252b5132
RH
763 || in->ptr[src] == '_'
764 || in->ptr[src] == '$')
765 && (! inquote
766 || ! macro_strip_at
767 || (src > 0 && in->ptr[src - 1] == '@')))
768 {
769 if (! locals
770 || src + 5 >= in->len
771 || strncasecmp (in->ptr + src, "LOCAL", 5) != 0
772 || ! ISWHITE (in->ptr[src + 5]))
773 {
774 sb_reset (&t);
775 src = sub_actual (src, in, &t, formal_hash,
776 (macro_strip_at && inquote) ? '@' : '\'',
777 out, 1);
778 }
779 else
780 {
781 formal_entry *f;
782
783 src = sb_skip_white (src + 5, in);
fea17916 784 while (in->ptr[src] != '\n')
252b5132
RH
785 {
786 static int loccnt;
787 char buf[20];
788 const char *err;
789
790 f = (formal_entry *) xmalloc (sizeof (formal_entry));
791 sb_new (&f->name);
792 sb_new (&f->def);
793 sb_new (&f->actual);
794 f->index = LOCAL_INDEX;
795 f->next = loclist;
796 loclist = f;
797
798 src = get_token (src, in, &f->name);
799 ++loccnt;
89658e52 800 sprintf (buf, IS_ELF ? ".LL%04x" : "LL%04x", loccnt);
252b5132
RH
801 sb_add_string (&f->actual, buf);
802
803 err = hash_jam (formal_hash, sb_terminate (&f->name), f);
804 if (err != NULL)
805 return err;
806
807 src = sb_skip_comma (src, in);
808 }
809 }
810 }
252b5132
RH
811 else if (in->ptr[src] == '"'
812 || (macro_mri && in->ptr[src] == '\''))
813 {
814 inquote = !inquote;
815 sb_add_char (out, in->ptr[src++]);
816 }
817 else if (in->ptr[src] == '@' && macro_strip_at)
818 {
819 ++src;
820 if (src < in->len
821 && in->ptr[src] == '@')
822 {
823 sb_add_char (out, '@');
824 ++src;
825 }
826 }
827 else if (macro_mri
828 && in->ptr[src] == '='
829 && src + 1 < in->len
830 && in->ptr[src + 1] == '=')
831 {
832 formal_entry *ptr;
833
834 sb_reset (&t);
835 src = get_token (src + 2, in, &t);
836 ptr = (formal_entry *) hash_find (formal_hash, sb_terminate (&t));
837 if (ptr == NULL)
838 {
839 /* FIXME: We should really return a warning string here,
840 but we can't, because the == might be in the MRI
841 comment field, and, since the nature of the MRI
842 comment field depends upon the exact instruction
843 being used, we don't have enough information here to
844 figure out whether it is or not. Instead, we leave
845 the == in place, which should cause a syntax error if
846 it is not in a comment. */
847 sb_add_char (out, '=');
848 sb_add_char (out, '=');
849 sb_add_sb (out, &t);
850 }
851 else
852 {
853 if (ptr->actual.len)
854 {
855 sb_add_string (out, "-1");
856 }
857 else
858 {
859 sb_add_char (out, '0');
860 }
861 }
862 }
863 else
864 {
865 sb_add_char (out, in->ptr[src++]);
866 }
867 }
868
869 sb_kill (&t);
870
871 while (loclist != NULL)
872 {
873 formal_entry *f;
874
875 f = loclist->next;
1af6dcd2
ILT
876 /* Setting the value to NULL effectively deletes the entry. We
877 avoid calling hash_delete because it doesn't reclaim memory. */
878 hash_jam (formal_hash, sb_terminate (&loclist->name), NULL);
252b5132
RH
879 sb_kill (&loclist->name);
880 sb_kill (&loclist->def);
881 sb_kill (&loclist->actual);
882 free (loclist);
883 loclist = f;
884 }
885
886 return NULL;
887}
888
889/* Assign values to the formal parameters of a macro, and expand the
890 body. */
891
892static const char *
254d758c 893macro_expand (int idx, sb *in, macro_entry *m, sb *out)
252b5132
RH
894{
895 sb t;
896 formal_entry *ptr;
897 formal_entry *f;
898 int is_positional = 0;
899 int is_keyword = 0;
900 int narg = 0;
901 const char *err;
902
903 sb_new (&t);
29f8404c
KH
904
905 /* Reset any old value the actuals may have. */
252b5132 906 for (f = m->formals; f; f = f->next)
29f8404c 907 sb_reset (&f->actual);
252b5132
RH
908 f = m->formals;
909 while (f != NULL && f->index < 0)
910 f = f->next;
911
912 if (macro_mri)
913 {
914 /* The macro may be called with an optional qualifier, which may
915 be referred to in the macro body as \0. */
916 if (idx < in->len && in->ptr[idx] == '.')
d1a6c242
KH
917 {
918 /* The Microtec assembler ignores this if followed by a white space.
919 (Macro invocation with empty extension) */
920 idx++;
921 if ( idx < in->len
922 && in->ptr[idx] != ' '
923 && in->ptr[idx] != '\t')
924 {
925 formal_entry *n;
926
927 n = (formal_entry *) xmalloc (sizeof (formal_entry));
928 sb_new (&n->name);
929 sb_new (&n->def);
930 sb_new (&n->actual);
931 n->index = QUAL_INDEX;
932
933 n->next = m->formals;
934 m->formals = n;
935
936 idx = get_any_string (idx, in, &n->actual, 1, 0);
937 }
938 }
939 }
252b5132 940
29f8404c 941 /* Peel off the actuals and store them away in the hash tables' actuals. */
252b5132 942 idx = sb_skip_white (idx, in);
fea17916 943 while (idx < in->len)
252b5132
RH
944 {
945 int scan;
946
29f8404c 947 /* Look and see if it's a positional or keyword arg. */
252b5132
RH
948 scan = idx;
949 while (scan < in->len
950 && !ISSEP (in->ptr[scan])
951 && !(macro_mri && in->ptr[scan] == '\'')
952 && (!macro_alternate && in->ptr[scan] != '='))
953 scan++;
954 if (scan < in->len && !macro_alternate && in->ptr[scan] == '=')
955 {
956 is_keyword = 1;
957
958 /* It's OK to go from positional to keyword. */
959
960 /* This is a keyword arg, fetch the formal name and
29f8404c 961 then the actual stuff. */
252b5132
RH
962 sb_reset (&t);
963 idx = get_token (idx, in, &t);
964 if (in->ptr[idx] != '=')
965 return _("confusion in formal parameters");
966
29f8404c 967 /* Lookup the formal in the macro's list. */
252b5132
RH
968 ptr = (formal_entry *) hash_find (m->formal_hash, sb_terminate (&t));
969 if (!ptr)
970 return _("macro formal argument does not exist");
971 else
972 {
29f8404c 973 /* Insert this value into the right place. */
252b5132
RH
974 sb_reset (&ptr->actual);
975 idx = get_any_string (idx + 1, in, &ptr->actual, 0, 0);
976 if (ptr->actual.len > 0)
977 ++narg;
978 }
979 }
980 else
981 {
29f8404c 982 /* This is a positional arg. */
252b5132
RH
983 is_positional = 1;
984 if (is_keyword)
985 return _("can't mix positional and keyword arguments");
986
987 if (!f)
988 {
989 formal_entry **pf;
990 int c;
991
992 if (!macro_mri)
993 return _("too many positional arguments");
994
995 f = (formal_entry *) xmalloc (sizeof (formal_entry));
996 sb_new (&f->name);
997 sb_new (&f->def);
998 sb_new (&f->actual);
999 f->next = NULL;
1000
1001 c = -1;
1002 for (pf = &m->formals; *pf != NULL; pf = &(*pf)->next)
1003 if ((*pf)->index >= c)
1004 c = (*pf)->index + 1;
1005 if (c == -1)
1006 c = 0;
1007 *pf = f;
1008 f->index = c;
1009 }
1010
1011 sb_reset (&f->actual);
1012 idx = get_any_string (idx, in, &f->actual, 1, 0);
1013 if (f->actual.len > 0)
1014 ++narg;
1015 do
1016 {
1017 f = f->next;
1018 }
1019 while (f != NULL && f->index < 0);
1020 }
1021
1022 if (! macro_mri)
1023 idx = sb_skip_comma (idx, in);
1024 else
1025 {
1026 if (in->ptr[idx] == ',')
1027 ++idx;
1028 if (ISWHITE (in->ptr[idx]))
1029 break;
1030 }
1031 }
1032
1033 if (macro_mri)
1034 {
1035 char buffer[20];
1036
1037 sb_reset (&t);
1038 sb_add_string (&t, macro_strip_at ? "$NARG" : "NARG");
1039 ptr = (formal_entry *) hash_find (m->formal_hash, sb_terminate (&t));
1040 sb_reset (&ptr->actual);
1041 sprintf (buffer, "%d", narg);
1042 sb_add_string (&ptr->actual, buffer);
1043 }
1044
fea17916 1045 err = macro_expand_body (&m->sub, out, m->formals, m->formal_hash, 1);
252b5132
RH
1046 if (err != NULL)
1047 return err;
1048
1049 /* Discard any unnamed formal arguments. */
1050 if (macro_mri)
1051 {
1052 formal_entry **pf;
1053
1054 pf = &m->formals;
1055 while (*pf != NULL)
1056 {
1057 if ((*pf)->name.len != 0)
1058 pf = &(*pf)->next;
1059 else
1060 {
1061 sb_kill (&(*pf)->name);
1062 sb_kill (&(*pf)->def);
1063 sb_kill (&(*pf)->actual);
1064 f = (*pf)->next;
1065 free (*pf);
1066 *pf = f;
1067 }
1068 }
1069 }
1070
1071 sb_kill (&t);
1072 macro_number++;
1073
1074 return NULL;
1075}
1076
1077/* Check for a macro. If one is found, put the expansion into
fea17916 1078 *EXPAND. Return 1 if a macro is found, 0 otherwise. */
252b5132
RH
1079
1080int
254d758c
KH
1081check_macro (const char *line, sb *expand,
1082 const char **error, macro_entry **info)
252b5132
RH
1083{
1084 const char *s;
1085 char *copy, *cs;
1086 macro_entry *macro;
1087 sb line_sb;
1088
3882b010 1089 if (! ISALPHA (*line)
252b5132
RH
1090 && *line != '_'
1091 && *line != '$'
1092 && (! macro_mri || *line != '.'))
1093 return 0;
1094
1095 s = line + 1;
3882b010 1096 while (ISALNUM (*s)
252b5132
RH
1097 || *s == '_'
1098 || *s == '$')
1099 ++s;
1100
1101 copy = (char *) alloca (s - line + 1);
1102 memcpy (copy, line, s - line);
1103 copy[s - line] = '\0';
1104 for (cs = copy; *cs != '\0'; cs++)
3882b010 1105 *cs = TOLOWER (*cs);
252b5132
RH
1106
1107 macro = (macro_entry *) hash_find (macro_hash, copy);
1108
1109 if (macro == NULL)
1110 return 0;
1111
1112 /* Wrap the line up in an sb. */
1113 sb_new (&line_sb);
1114 while (*s != '\0' && *s != '\n' && *s != '\r')
1115 sb_add_char (&line_sb, *s++);
1116
1117 sb_new (expand);
fea17916 1118 *error = macro_expand (0, &line_sb, macro, expand);
252b5132
RH
1119
1120 sb_kill (&line_sb);
1121
29f8404c 1122 /* Export the macro information if requested. */
9f10757c
TW
1123 if (info)
1124 *info = macro;
1125
252b5132
RH
1126 return 1;
1127}
1128
1129/* Delete a macro. */
1130
1131void
254d758c 1132delete_macro (const char *name)
252b5132
RH
1133{
1134 hash_delete (macro_hash, name);
1135}
1136
1137/* Handle the MRI IRP and IRPC pseudo-ops. These are handled as a
1138 combined macro definition and execution. This returns NULL on
1139 success, or an error message otherwise. */
1140
1141const char *
254d758c 1142expand_irp (int irpc, int idx, sb *in, sb *out, int (*get_line) (sb *))
252b5132 1143{
252b5132
RH
1144 sb sub;
1145 formal_entry f;
1146 struct hash_control *h;
1147 const char *err;
1148
252b5132
RH
1149 idx = sb_skip_white (idx, in);
1150
1151 sb_new (&sub);
ca3bc58f 1152 if (! buffer_and_nest (NULL, "ENDR", &sub, get_line))
252b5132 1153 return _("unexpected end of file in irp or irpc");
29f8404c 1154
252b5132
RH
1155 sb_new (&f.name);
1156 sb_new (&f.def);
1157 sb_new (&f.actual);
1158
1159 idx = get_token (idx, in, &f.name);
1160 if (f.name.len == 0)
1161 return _("missing model parameter");
1162
1163 h = hash_new ();
1164 err = hash_jam (h, sb_terminate (&f.name), &f);
1165 if (err != NULL)
1166 return err;
1167
1168 f.index = 1;
1169 f.next = NULL;
1170
1171 sb_reset (out);
1172
1173 idx = sb_skip_comma (idx, in);
fea17916 1174 if (idx >= in->len)
252b5132
RH
1175 {
1176 /* Expand once with a null string. */
fea17916 1177 err = macro_expand_body (&sub, out, &f, h, 0);
252b5132
RH
1178 if (err != NULL)
1179 return err;
1180 }
1181 else
1182 {
1183 if (irpc && in->ptr[idx] == '"')
1184 ++idx;
fea17916 1185 while (idx < in->len)
252b5132
RH
1186 {
1187 if (!irpc)
1188 idx = get_any_string (idx, in, &f.actual, 1, 0);
1189 else
1190 {
1191 if (in->ptr[idx] == '"')
1192 {
1193 int nxt;
1194
1195 nxt = sb_skip_white (idx + 1, in);
fea17916 1196 if (nxt >= in->len)
252b5132
RH
1197 {
1198 idx = nxt;
1199 break;
1200 }
1201 }
1202 sb_reset (&f.actual);
1203 sb_add_char (&f.actual, in->ptr[idx]);
1204 ++idx;
1205 }
fea17916 1206 err = macro_expand_body (&sub, out, &f, h, 0);
252b5132
RH
1207 if (err != NULL)
1208 return err;
1209 if (!irpc)
1210 idx = sb_skip_comma (idx, in);
1211 else
1212 idx = sb_skip_white (idx, in);
1213 }
1214 }
1215
1216 hash_die (h);
1217 sb_kill (&sub);
1218
1219 return NULL;
1220}