Change wording of error message to "percent-operand" from "%operand" as the
[binutils.git] / gas / macro.c
blob131838efc1eeb0723eb7ea329afa4368767ec08f
1 /* macro.c - macro support for gas
2 Copyright 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003,
3 2004, 2005 Free Software Foundation, Inc.
5 Written by Steve and Judy Chamberlain of Cygnus Support,
6 sac@cygnus.com
8 This file is part of GAS, the GNU Assembler.
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.
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.
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
23 02111-1307, USA. */
25 #include "config.h"
27 #ifndef __GNUC__
28 # if HAVE_ALLOCA_H
29 # include <alloca.h>
30 # else
31 # ifdef _AIX
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. */
35 #pragma alloca
36 # else
37 # ifndef alloca /* predefined by HP cc +Olibcalls */
38 # if !defined (__STDC__) && !defined (__hpux)
39 extern char *alloca ();
40 # else
41 extern void *alloca ();
42 # endif /* __STDC__, __hpux */
43 # endif /* alloca */
44 # endif /* _AIX */
45 # endif /* HAVE_ALLOCA_H */
46 #endif /* __GNUC__ */
48 #include <stdio.h>
49 #ifdef HAVE_STRING_H
50 #include <string.h>
51 #else
52 #include <strings.h>
53 #endif
54 #ifdef HAVE_STDLIB_H
55 #include <stdlib.h>
56 #endif
57 #include "as.h"
58 #include "libiberty.h"
59 #include "safe-ctype.h"
60 #include "sb.h"
61 #include "hash.h"
62 #include "macro.h"
64 #include "asintl.h"
66 /* The routines in this file handle macro definition and expansion.
67 They are called by gas. */
69 /* Internal functions. */
71 static int get_token (int, sb *, sb *);
72 static int getstring (int, sb *, sb *);
73 static int get_any_string (int, sb *, sb *, int, int);
74 static int do_formals (macro_entry *, int, sb *);
75 static int get_apost_token (int, sb *, sb *, int);
76 static int sub_actual (int, sb *, sb *, struct hash_control *, int, sb *, int);
77 static const char *macro_expand_body
78 (sb *, sb *, formal_entry *, struct hash_control *, int);
79 static const char *macro_expand (int, sb *, macro_entry *, sb *);
81 #define ISWHITE(x) ((x) == ' ' || (x) == '\t')
83 #define ISSEP(x) \
84 ((x) == ' ' || (x) == '\t' || (x) == ',' || (x) == '"' || (x) == ';' \
85 || (x) == ')' || (x) == '(' \
86 || ((macro_alternate || macro_mri) && ((x) == '<' || (x) == '>')))
88 #define ISBASE(x) \
89 ((x) == 'b' || (x) == 'B' \
90 || (x) == 'q' || (x) == 'Q' \
91 || (x) == 'h' || (x) == 'H' \
92 || (x) == 'd' || (x) == 'D')
94 /* The macro hash table. */
96 struct hash_control *macro_hash;
98 /* Whether any macros have been defined. */
100 int macro_defined;
102 /* Whether we are in alternate syntax mode. */
104 static int macro_alternate;
106 /* Whether we are in MRI mode. */
108 static int macro_mri;
110 /* Whether we should strip '@' characters. */
112 static int macro_strip_at;
114 /* Function to use to parse an expression. */
116 static int (*macro_expr) (const char *, int, sb *, int *);
118 /* Number of macro expansions that have been done. */
120 static int macro_number;
122 /* Initialize macro processing. */
124 void
125 macro_init (int alternate, int mri, int strip_at,
126 int (*expr) (const char *, int, sb *, int *))
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;
136 /* Switch in and out of alternate mode on the fly. */
138 void
139 macro_set_alternate (int alternate)
141 macro_alternate = alternate;
144 /* Switch in and out of MRI mode on the fly. */
146 void
147 macro_mri_mode (int mri)
149 macro_mri = mri;
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.
155 FROM may be NULL (or will be ignored) if TO is "ENDR".
156 Add a new input line to an sb using GET_LINE.
157 Return 1 on success, 0 on unexpected EOF. */
160 buffer_and_nest (const char *from, const char *to, sb *ptr,
161 int (*get_line) (sb *))
163 int from_len;
164 int to_len = strlen (to);
165 int depth = 1;
166 int line_start = ptr->len;
168 int more = get_line (ptr);
170 if (to_len == 4 && strcasecmp(to, "ENDR") == 0)
172 from = NULL;
173 from_len = 0;
175 else
176 from_len = strlen (from);
178 while (more)
180 /* Try and find the first pseudo op on the line. */
181 int i = line_start;
183 if (! NO_PSEUDO_DOT && ! flag_m68k_mri)
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
187 the first column, since we can't tell what's a label and
188 whats a pseudoop. */
190 /* Skip leading whitespace. */
191 while (i < ptr->len && ISWHITE (ptr->ptr[i]))
192 i++;
194 /* Skip over a label. */
195 while (i < ptr->len
196 && (ISALNUM (ptr->ptr[i])
197 || ptr->ptr[i] == '_'
198 || ptr->ptr[i] == '$'))
199 i++;
201 /* And a colon. */
202 if (i < ptr->len
203 && ptr->ptr[i] == ':')
204 i++;
207 /* Skip trailing whitespace. */
208 while (i < ptr->len && ISWHITE (ptr->ptr[i]))
209 i++;
211 if (i < ptr->len && (ptr->ptr[i] == '.'
212 || NO_PSEUDO_DOT
213 || macro_mri))
215 if (! flag_m68k_mri && ptr->ptr[i] == '.')
216 i++;
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)
228 && (ptr->len == (i + from_len)
229 || ! ISALNUM (ptr->ptr[i + from_len])))
230 depth++;
231 if (strncasecmp (ptr->ptr + i, to, to_len) == 0
232 && (ptr->len == (i + to_len)
233 || ! ISALNUM (ptr->ptr[i + to_len])))
235 depth--;
236 if (depth == 0)
238 /* Reset the string to not include the ending rune. */
239 ptr->len = line_start;
240 break;
245 /* Add the original end-of-line char to the end and keep running. */
246 sb_add_char (ptr, more);
247 line_start = ptr->len;
248 more = get_line (ptr);
251 /* Return 1 on success, 0 on unexpected EOF. */
252 return depth == 0;
255 /* Pick up a token. */
257 static int
258 get_token (int idx, sb *in, sb *name)
260 if (idx < in->len
261 && (ISALPHA (in->ptr[idx])
262 || in->ptr[idx] == '_'
263 || in->ptr[idx] == '$'))
265 sb_add_char (name, in->ptr[idx++]);
266 while (idx < in->len
267 && (ISALNUM (in->ptr[idx])
268 || in->ptr[idx] == '_'
269 || in->ptr[idx] == '$'))
271 sb_add_char (name, in->ptr[idx++]);
274 /* Ignore trailing &. */
275 if (macro_alternate && idx < in->len && in->ptr[idx] == '&')
276 idx++;
277 return idx;
280 /* Pick up a string. */
282 static int
283 getstring (int idx, sb *in, sb *acc)
285 idx = sb_skip_white (idx, in);
287 while (idx < in->len
288 && (in->ptr[idx] == '"'
289 || (in->ptr[idx] == '<' && (macro_alternate || macro_mri))
290 || (in->ptr[idx] == '\'' && macro_alternate)))
292 if (in->ptr[idx] == '<')
294 int nest = 0;
295 idx++;
296 while ((in->ptr[idx] != '>' || nest)
297 && idx < in->len)
299 if (in->ptr[idx] == '!')
301 idx++;
302 sb_add_char (acc, in->ptr[idx++]);
304 else
306 if (in->ptr[idx] == '>')
307 nest--;
308 if (in->ptr[idx] == '<')
309 nest++;
310 sb_add_char (acc, in->ptr[idx++]);
313 idx++;
315 else if (in->ptr[idx] == '"' || in->ptr[idx] == '\'')
317 char tchar = in->ptr[idx];
318 int escaped = 0;
320 idx++;
322 while (idx < in->len)
324 if (in->ptr[idx - 1] == '\\')
325 escaped ^= 1;
326 else
327 escaped = 0;
329 if (macro_alternate && in->ptr[idx] == '!')
331 idx ++;
333 sb_add_char (acc, in->ptr[idx]);
335 idx ++;
337 else if (escaped && in->ptr[idx] == tchar)
339 sb_add_char (acc, tchar);
340 idx ++;
342 else
344 if (in->ptr[idx] == tchar)
346 idx ++;
348 if (idx >= in->len || in->ptr[idx] != tchar)
349 break;
352 sb_add_char (acc, in->ptr[idx]);
353 idx ++;
359 return idx;
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
370 static int
371 get_any_string (int idx, sb *in, sb *out, int expand, int pretend_quoted)
373 sb_reset (out);
374 idx = sb_skip_white (idx, in);
376 if (idx < in->len)
378 if (in->len > idx + 2 && in->ptr[idx + 1] == '\'' && ISBASE (in->ptr[idx]))
380 while (!ISSEP (in->ptr[idx]))
381 sb_add_char (out, in->ptr[idx++]);
383 else if (in->ptr[idx] == '%'
384 && macro_alternate
385 && expand)
387 int val;
388 char buf[20];
389 /* Turns the next expression into a string. */
390 /* xgettext: no-c-format */
391 idx = (*macro_expr) (_("% operator needs absolute expression"),
392 idx + 1,
394 &val);
395 sprintf (buf, "%d", val);
396 sb_add_string (out, buf);
398 else if (in->ptr[idx] == '"'
399 || (in->ptr[idx] == '<' && (macro_alternate || macro_mri))
400 || (macro_alternate && in->ptr[idx] == '\''))
402 if (macro_alternate
403 && ! macro_strip_at
404 && expand)
406 /* Keep the quotes. */
407 sb_add_char (out, '\"');
409 idx = getstring (idx, in, out);
410 sb_add_char (out, '\"');
412 else
414 idx = getstring (idx, in, out);
417 else
419 while (idx < in->len
420 && (in->ptr[idx] == '"'
421 || in->ptr[idx] == '\''
422 || pretend_quoted
423 || (in->ptr[idx] != ' '
424 && in->ptr[idx] != '\t'
425 && in->ptr[idx] != ','
426 && (in->ptr[idx] != '<'
427 || (! macro_alternate && ! macro_mri)))))
429 if (in->ptr[idx] == '"'
430 || in->ptr[idx] == '\'')
432 char tchar = in->ptr[idx];
433 sb_add_char (out, in->ptr[idx++]);
434 while (idx < in->len
435 && in->ptr[idx] != tchar)
436 sb_add_char (out, in->ptr[idx++]);
437 if (idx == in->len)
438 return idx;
440 sb_add_char (out, in->ptr[idx++]);
445 return idx;
448 /* Pick up the formal parameters of a macro definition. */
450 static int
451 do_formals (macro_entry *macro, int idx, sb *in)
453 formal_entry **p = &macro->formals;
455 macro->formal_count = 0;
456 macro->formal_hash = hash_new ();
457 idx = sb_skip_white (idx, in);
458 while (idx < in->len)
460 formal_entry *formal;
461 int cidx;
463 formal = (formal_entry *) xmalloc (sizeof (formal_entry));
465 sb_new (&formal->name);
466 sb_new (&formal->def);
467 sb_new (&formal->actual);
469 idx = get_token (idx, in, &formal->name);
470 if (formal->name.len == 0)
472 if (macro->formal_count)
473 --idx;
474 break;
476 idx = sb_skip_white (idx, in);
477 /* This is a formal. */
478 if (idx < in->len && in->ptr[idx] == '=')
480 /* Got a default. */
481 idx = get_any_string (idx + 1, in, &formal->def, 1, 0);
482 idx = sb_skip_white (idx, in);
485 /* Add to macro's hash table. */
486 hash_jam (macro->formal_hash, sb_terminate (&formal->name), formal);
488 formal->index = macro->formal_count++;
489 cidx = idx;
490 idx = sb_skip_comma (idx, in);
491 if (idx != cidx && idx >= in->len)
493 idx = cidx;
494 break;
496 *p = formal;
497 p = &formal->next;
498 *p = NULL;
501 if (macro_mri)
503 formal_entry *formal;
504 const char *name;
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));
510 sb_new (&formal->name);
511 sb_new (&formal->def);
512 sb_new (&formal->actual);
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";
521 sb_add_string (&formal->name, name);
523 /* Add to macro's hash table. */
524 hash_jam (macro->formal_hash, name, formal);
526 formal->index = NARG_INDEX;
527 *p = formal;
528 formal->next = NULL;
531 return idx;
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. */
538 const char *
539 define_macro (int idx, sb *in, sb *label,
540 int (*get_line) (sb *), const char **namep)
542 macro_entry *macro;
543 sb name;
544 const char *namestr;
546 macro = (macro_entry *) xmalloc (sizeof (macro_entry));
547 sb_new (&macro->sub);
548 sb_new (&name);
550 macro->formal_count = 0;
551 macro->formals = 0;
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)
558 sb_add_sb (&name, label);
559 if (idx < in->len && in->ptr[idx] == '(')
561 /* It's the label: MACRO (formals,...) sort */
562 idx = do_formals (macro, idx + 1, in);
563 if (idx >= in->len || in->ptr[idx] != ')')
564 return _("missing ) after formals");
565 idx = sb_skip_white (idx + 1, in);
567 else
569 /* It's the label: MACRO formals,... sort */
570 idx = do_formals (macro, idx, in);
573 else
575 int cidx;
577 idx = get_token (idx, in, &name);
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;
587 if (idx < in->len)
588 return _("Bad macro parameter list");
590 /* And stick it in the macro hash table. */
591 for (idx = 0; idx < name.len; idx++)
592 name.ptr[idx] = TOLOWER (name.ptr[idx]);
593 namestr = sb_terminate (&name);
594 if (hash_find (macro_hash, namestr))
595 return _("Macro with this name was already defined");
596 hash_jam (macro_hash, namestr, (PTR) macro);
598 macro_defined = 1;
600 if (namep != NULL)
601 *namep = namestr;
603 return NULL;
606 /* Scan a token, and then skip KIND. */
608 static int
609 get_apost_token (int idx, sb *in, sb *name, int kind)
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;
620 /* Substitute the actual value for a formal parameter. */
622 static int
623 sub_actual (int start, sb *in, sb *t, struct hash_control *formal_hash,
624 int kind, sb *out, int copyifnotthere)
626 int src;
627 formal_entry *ptr;
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)
640 if (ptr->actual.len)
642 sb_add_sb (out, &ptr->actual);
644 else
646 sb_add_sb (out, &ptr->def);
649 else if (kind == '&')
651 /* Doing this permits people to use & in macro bodies. */
652 sb_add_char (out, '&');
653 sb_add_sb (out, t);
655 else if (copyifnotthere)
657 sb_add_sb (out, t);
659 else
661 sb_add_char (out, '\\');
662 sb_add_sb (out, t);
664 return src;
667 /* Expand the body of a macro. */
669 static const char *
670 macro_expand_body (sb *in, sb *out, formal_entry *formals,
671 struct hash_control *formal_hash, int locals)
673 sb t;
674 int src = 0;
675 int inquote = 0;
676 formal_entry *loclist = NULL;
678 sb_new (&t);
680 while (src < in->len)
682 if (in->ptr[src] == '&')
684 sb_reset (&t);
685 if (macro_mri)
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++]);
692 else
694 /* FIXME: Why do we do this? */
695 src = sub_actual (src + 1, in, &t, formal_hash, '&', out, 0);
698 else if (in->ptr[src] == '\\')
700 src++;
701 if (in->ptr[src] == '(')
703 /* Sub in till the next ')' literally. */
704 src++;
705 while (src < in->len && in->ptr[src] != ')')
707 sb_add_char (out, in->ptr[src++]);
709 if (in->ptr[src] == ')')
710 src++;
711 else
712 return _("missplaced )");
714 else if (in->ptr[src] == '@')
716 /* Sub in the macro invocation number. */
718 char buffer[10];
719 src++;
720 sprintf (buffer, "%d", macro_number);
721 sb_add_string (out, buffer);
723 else if (in->ptr[src] == '&')
725 /* This is a preprocessor variable name, we don't do them
726 here. */
727 sb_add_char (out, '\\');
728 sb_add_char (out, '&');
729 src++;
731 else if (macro_mri && ISALNUM (in->ptr[src]))
733 int ind;
734 formal_entry *f;
736 if (ISDIGIT (in->ptr[src]))
737 ind = in->ptr[src] - '0';
738 else if (ISUPPER (in->ptr[src]))
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)
745 if (f->index == ind - 1)
747 if (f->actual.len != 0)
748 sb_add_sb (out, &f->actual);
749 else
750 sb_add_sb (out, &f->def);
751 break;
755 else
757 sb_reset (&t);
758 src = sub_actual (src, in, &t, formal_hash, '\'', out, 0);
761 else if ((macro_alternate || macro_mri)
762 && (ISALPHA (in->ptr[src])
763 || in->ptr[src] == '_'
764 || in->ptr[src] == '$')
765 && (! inquote
766 || ! macro_strip_at
767 || (src > 0 && in->ptr[src - 1] == '@')))
769 if (! locals
770 || src + 5 >= in->len
771 || strncasecmp (in->ptr + src, "LOCAL", 5) != 0
772 || ! ISWHITE (in->ptr[src + 5]))
774 sb_reset (&t);
775 src = sub_actual (src, in, &t, formal_hash,
776 (macro_strip_at && inquote) ? '@' : '\'',
777 out, 1);
779 else
781 formal_entry *f;
783 src = sb_skip_white (src + 5, in);
784 while (in->ptr[src] != '\n')
786 static int loccnt;
787 char buf[20];
788 const char *err;
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;
798 src = get_token (src, in, &f->name);
799 ++loccnt;
800 sprintf (buf, IS_ELF ? ".LL%04x" : "LL%04x", loccnt);
801 sb_add_string (&f->actual, buf);
803 err = hash_jam (formal_hash, sb_terminate (&f->name), f);
804 if (err != NULL)
805 return err;
807 src = sb_skip_comma (src, in);
811 else if (in->ptr[src] == '"'
812 || (macro_mri && in->ptr[src] == '\''))
814 inquote = !inquote;
815 sb_add_char (out, in->ptr[src++]);
817 else if (in->ptr[src] == '@' && macro_strip_at)
819 ++src;
820 if (src < in->len
821 && in->ptr[src] == '@')
823 sb_add_char (out, '@');
824 ++src;
827 else if (macro_mri
828 && in->ptr[src] == '='
829 && src + 1 < in->len
830 && in->ptr[src + 1] == '=')
832 formal_entry *ptr;
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)
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);
851 else
853 if (ptr->actual.len)
855 sb_add_string (out, "-1");
857 else
859 sb_add_char (out, '0');
863 else
865 sb_add_char (out, in->ptr[src++]);
869 sb_kill (&t);
871 while (loclist != NULL)
873 formal_entry *f;
875 f = loclist->next;
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);
879 sb_kill (&loclist->name);
880 sb_kill (&loclist->def);
881 sb_kill (&loclist->actual);
882 free (loclist);
883 loclist = f;
886 return NULL;
889 /* Assign values to the formal parameters of a macro, and expand the
890 body. */
892 static const char *
893 macro_expand (int idx, sb *in, macro_entry *m, sb *out)
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;
903 sb_new (&t);
905 /* Reset any old value the actuals may have. */
906 for (f = m->formals; f; f = f->next)
907 sb_reset (&f->actual);
908 f = m->formals;
909 while (f != NULL && f->index < 0)
910 f = f->next;
912 if (macro_mri)
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] == '.')
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')
925 formal_entry *n;
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;
933 n->next = m->formals;
934 m->formals = n;
936 idx = get_any_string (idx, in, &n->actual, 1, 0);
941 /* Peel off the actuals and store them away in the hash tables' actuals. */
942 idx = sb_skip_white (idx, in);
943 while (idx < in->len)
945 int scan;
947 /* Look and see if it's a positional or keyword arg. */
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] == '=')
956 is_keyword = 1;
958 /* It's OK to go from positional to keyword. */
960 /* This is a keyword arg, fetch the formal name and
961 then the actual stuff. */
962 sb_reset (&t);
963 idx = get_token (idx, in, &t);
964 if (in->ptr[idx] != '=')
965 return _("confusion in formal parameters");
967 /* Lookup the formal in the macro's list. */
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
973 /* Insert this value into the right place. */
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;
980 else
982 /* This is a positional arg. */
983 is_positional = 1;
984 if (is_keyword)
985 return _("can't mix positional and keyword arguments");
987 if (!f)
989 formal_entry **pf;
990 int c;
992 if (!macro_mri)
993 return _("too many positional arguments");
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;
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;
1011 sb_reset (&f->actual);
1012 idx = get_any_string (idx, in, &f->actual, 1, 0);
1013 if (f->actual.len > 0)
1014 ++narg;
1017 f = f->next;
1019 while (f != NULL && f->index < 0);
1022 if (! macro_mri)
1023 idx = sb_skip_comma (idx, in);
1024 else
1026 if (in->ptr[idx] == ',')
1027 ++idx;
1028 if (ISWHITE (in->ptr[idx]))
1029 break;
1033 if (macro_mri)
1035 char buffer[20];
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);
1045 err = macro_expand_body (&m->sub, out, m->formals, m->formal_hash, 1);
1046 if (err != NULL)
1047 return err;
1049 /* Discard any unnamed formal arguments. */
1050 if (macro_mri)
1052 formal_entry **pf;
1054 pf = &m->formals;
1055 while (*pf != NULL)
1057 if ((*pf)->name.len != 0)
1058 pf = &(*pf)->next;
1059 else
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;
1071 sb_kill (&t);
1072 macro_number++;
1074 return NULL;
1077 /* Check for a macro. If one is found, put the expansion into
1078 *EXPAND. Return 1 if a macro is found, 0 otherwise. */
1081 check_macro (const char *line, sb *expand,
1082 const char **error, macro_entry **info)
1084 const char *s;
1085 char *copy, *cs;
1086 macro_entry *macro;
1087 sb line_sb;
1089 if (! ISALPHA (*line)
1090 && *line != '_'
1091 && *line != '$'
1092 && (! macro_mri || *line != '.'))
1093 return 0;
1095 s = line + 1;
1096 while (ISALNUM (*s)
1097 || *s == '_'
1098 || *s == '$')
1099 ++s;
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++)
1105 *cs = TOLOWER (*cs);
1107 macro = (macro_entry *) hash_find (macro_hash, copy);
1109 if (macro == NULL)
1110 return 0;
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++);
1117 sb_new (expand);
1118 *error = macro_expand (0, &line_sb, macro, expand);
1120 sb_kill (&line_sb);
1122 /* Export the macro information if requested. */
1123 if (info)
1124 *info = macro;
1126 return 1;
1129 /* Delete a macro. */
1131 void
1132 delete_macro (const char *name)
1134 hash_delete (macro_hash, name);
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. */
1141 const char *
1142 expand_irp (int irpc, int idx, sb *in, sb *out, int (*get_line) (sb *))
1144 sb sub;
1145 formal_entry f;
1146 struct hash_control *h;
1147 const char *err;
1149 idx = sb_skip_white (idx, in);
1151 sb_new (&sub);
1152 if (! buffer_and_nest (NULL, "ENDR", &sub, get_line))
1153 return _("unexpected end of file in irp or irpc");
1155 sb_new (&f.name);
1156 sb_new (&f.def);
1157 sb_new (&f.actual);
1159 idx = get_token (idx, in, &f.name);
1160 if (f.name.len == 0)
1161 return _("missing model parameter");
1163 h = hash_new ();
1164 err = hash_jam (h, sb_terminate (&f.name), &f);
1165 if (err != NULL)
1166 return err;
1168 f.index = 1;
1169 f.next = NULL;
1171 sb_reset (out);
1173 idx = sb_skip_comma (idx, in);
1174 if (idx >= in->len)
1176 /* Expand once with a null string. */
1177 err = macro_expand_body (&sub, out, &f, h, 0);
1178 if (err != NULL)
1179 return err;
1181 else
1183 if (irpc && in->ptr[idx] == '"')
1184 ++idx;
1185 while (idx < in->len)
1187 if (!irpc)
1188 idx = get_any_string (idx, in, &f.actual, 1, 0);
1189 else
1191 if (in->ptr[idx] == '"')
1193 int nxt;
1195 nxt = sb_skip_white (idx + 1, in);
1196 if (nxt >= in->len)
1198 idx = nxt;
1199 break;
1202 sb_reset (&f.actual);
1203 sb_add_char (&f.actual, in->ptr[idx]);
1204 ++idx;
1206 err = macro_expand_body (&sub, out, &f, h, 0);
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);
1216 hash_die (h);
1217 sb_kill (&sub);
1219 return NULL;