1 /* macro.c - macro support for gas and gasp
2 Copyright (C) 1994, 95, 96, 97, 98, 1999 Free Software Foundation, Inc.
4 Written by Steve and Judy Chamberlain of Cygnus Support,
7 This file is part of GAS, the GNU Assembler.
9 GAS is free software; you can redistribute it and/or modify
10 it under the terms of the GNU General Public License as published by
11 the Free Software Foundation; either version 2, or (at your option)
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.
19 You should have received a copy of the GNU General Public License
20 along with GAS; see the file COPYING. If not, write to the Free
21 Software Foundation, 59 Temple Place - Suite 330, Boston, MA
26 /* AIX requires this to be the first thing in the file. */
30 extern void *alloca ();
32 extern char *alloca ();
42 # ifndef alloca /* predefined by HP cc +Olibcalls */
43 # if !defined (__STDC__) && !defined (__hpux)
44 extern char *alloca ();
46 extern void *alloca ();
47 # endif /* __STDC__, __hpux */
50 # endif /* HAVE_ALLOCA_H */
63 #include "libiberty.h"
70 /* The routines in this file handle macro definition and expansion.
71 They are called by both gasp and gas. */
73 /* Internal functions. */
75 static int get_token PARAMS ((int, sb *, sb *));
76 static int getstring PARAMS ((int, sb *, sb *));
77 static int get_any_string PARAMS ((int, sb *, sb *, int, int));
78 static int do_formals PARAMS ((macro_entry *, int, sb *));
79 static int get_apost_token PARAMS ((int, sb *, sb *, int));
81 PARAMS ((int, sb *, sb *, struct hash_control *, int, sb *, int));
82 static const char *macro_expand_body
83 PARAMS ((sb *, sb *, formal_entry *, struct hash_control *, int, int));
84 static const char *macro_expand PARAMS ((int, sb *, macro_entry *, sb *, int));
86 #define ISWHITE(x) ((x) == ' ' || (x) == '\t')
89 ((x) == ' ' || (x) == '\t' || (x) == ',' || (x) == '"' || (x) == ';' \
90 || (x) == ')' || (x) == '(' \
91 || ((macro_alternate || macro_mri) && ((x) == '<' || (x) == '>')))
94 ((x) == 'b' || (x) == 'B' \
95 || (x) == 'q' || (x) == 'Q' \
96 || (x) == 'h' || (x) == 'H' \
97 || (x) == 'd' || (x) == 'D')
99 /* The macro hash table. */
101 static struct hash_control *macro_hash;
103 /* Whether any macros have been defined. */
107 /* Whether we are in GASP alternate mode. */
109 static int macro_alternate;
111 /* Whether we are in MRI mode. */
113 static int macro_mri;
115 /* Whether we should strip '@' characters. */
117 static int macro_strip_at;
119 /* Function to use to parse an expression. */
121 static int (*macro_expr) PARAMS ((const char *, int, sb *, int *));
123 /* Number of macro expansions that have been done. */
125 static int macro_number;
127 /* Initialize macro processing. */
130 macro_init (alternate, mri, strip_at, expr)
134 int (*expr) PARAMS ((const char *, int, sb *, int *));
136 macro_hash = hash_new ();
138 macro_alternate = alternate;
140 macro_strip_at = strip_at;
144 /* Switch in and out of MRI mode on the fly. */
153 /* Read input lines till we get to a TO string.
154 Increase nesting depth if we get a FROM string.
155 Put the results into sb at PTR.
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 (from, to, ptr, get_line)
164 int (*get_line) PARAMS ((sb *));
166 int from_len = strlen (from);
167 int to_len = strlen (to);
169 int line_start = ptr->len;
171 int more = get_line (ptr);
175 /* Try and find the first pseudo op on the line */
178 if (! macro_alternate && ! macro_mri)
180 /* With normal syntax we can suck what we want till we get
181 to the dot. With the alternate, labels have to start in
182 the first column, since we cant tell what's a label and
185 /* Skip leading whitespace */
186 while (i < ptr->len && ISWHITE (ptr->ptr[i]))
189 /* Skip over a label */
191 && (isalnum ((unsigned char) ptr->ptr[i])
192 || ptr->ptr[i] == '_'
193 || ptr->ptr[i] == '$'))
198 && ptr->ptr[i] == ':')
202 /* Skip trailing whitespace */
203 while (i < ptr->len && ISWHITE (ptr->ptr[i]))
206 if (i < ptr->len && (ptr->ptr[i] == '.'
210 if (ptr->ptr[i] == '.')
212 if (strncasecmp (ptr->ptr + i, from, from_len) == 0
213 && (ptr->len == (i + from_len) || ! isalnum (ptr->ptr[i + from_len])))
215 if (strncasecmp (ptr->ptr + i, to, to_len) == 0
216 && (ptr->len == (i + to_len) || ! isalnum (ptr->ptr[i + to_len])))
221 /* Reset the string to not include the ending rune */
222 ptr->len = line_start;
228 /* Add a CR to the end and keep running */
229 sb_add_char (ptr, '\n');
230 line_start = ptr->len;
231 more = get_line (ptr);
234 /* Return 1 on success, 0 on unexpected EOF. */
238 /* Pick up a token. */
241 get_token (idx, in, name)
247 && (isalpha ((unsigned char) in->ptr[idx])
248 || in->ptr[idx] == '_'
249 || in->ptr[idx] == '$'))
251 sb_add_char (name, in->ptr[idx++]);
253 && (isalnum ((unsigned char) in->ptr[idx])
254 || in->ptr[idx] == '_'
255 || in->ptr[idx] == '$'))
257 sb_add_char (name, in->ptr[idx++]);
260 /* Ignore trailing & */
261 if (macro_alternate && idx < in->len && in->ptr[idx] == '&')
266 /* Pick up a string. */
269 getstring (idx, in, acc)
274 idx = sb_skip_white (idx, in);
277 && (in->ptr[idx] == '"'
278 || (in->ptr[idx] == '<' && (macro_alternate || macro_mri))
279 || (in->ptr[idx] == '\'' && macro_alternate)))
281 if (in->ptr[idx] == '<')
285 while ((in->ptr[idx] != '>' || nest)
288 if (in->ptr[idx] == '!')
291 sb_add_char (acc, in->ptr[idx++]);
295 if (in->ptr[idx] == '>')
297 if (in->ptr[idx] == '<')
299 sb_add_char (acc, in->ptr[idx++]);
304 else if (in->ptr[idx] == '"' || in->ptr[idx] == '\'')
306 char tchar = in->ptr[idx];
309 while (idx < in->len)
311 if (in->ptr[idx-1] == '\\')
316 if (macro_alternate && in->ptr[idx] == '!')
319 sb_add_char (acc, in->ptr[idx++]);
321 else if (escaped && in->ptr[idx] == tchar)
323 sb_add_char (acc, tchar);
328 if (in->ptr[idx] == tchar)
331 if (idx >= in->len || in->ptr[idx] != tchar)
334 sb_add_char (acc, in->ptr[idx]);
344 /* Fetch string from the input stream,
346 'Bxyx<whitespace> -> return 'Bxyza
347 %<char> -> return string of decimal value of x
348 "<string>" -> return string
349 xyx<whitespace> -> return xyz
353 get_any_string (idx, in, out, expand, pretend_quoted)
361 idx = sb_skip_white (idx, in);
365 if (in->len > 2 && in->ptr[idx+1] == '\'' && ISBASE (in->ptr[idx]))
367 while (!ISSEP (in->ptr[idx]))
368 sb_add_char (out, in->ptr[idx++]);
370 else if (in->ptr[idx] == '%'
376 /* Turns the next expression into a string */
377 idx = (*macro_expr) (_("% operator needs absolute expression"),
381 sprintf(buf, "%d", val);
382 sb_add_string (out, buf);
384 else if (in->ptr[idx] == '"'
385 || (in->ptr[idx] == '<' && (macro_alternate || macro_mri))
386 || (macro_alternate && in->ptr[idx] == '\''))
392 /* Keep the quotes */
393 sb_add_char (out, '\"');
395 idx = getstring (idx, in, out);
396 sb_add_char (out, '\"');
400 idx = getstring (idx, in, out);
406 && (in->ptr[idx] == '"'
407 || in->ptr[idx] == '\''
409 || (in->ptr[idx] != ' '
410 && in->ptr[idx] != '\t'
411 && in->ptr[idx] != ','
412 && (in->ptr[idx] != '<'
413 || (! macro_alternate && ! macro_mri)))))
415 if (in->ptr[idx] == '"'
416 || in->ptr[idx] == '\'')
418 char tchar = in->ptr[idx];
419 sb_add_char (out, in->ptr[idx++]);
421 && in->ptr[idx] != tchar)
422 sb_add_char (out, in->ptr[idx++]);
426 sb_add_char (out, in->ptr[idx++]);
434 /* Pick up the formal parameters of a macro definition. */
437 do_formals (macro, idx, in)
442 formal_entry **p = ¯o->formals;
444 macro->formal_count = 0;
445 macro->formal_hash = hash_new ();
446 while (idx < in->len)
448 formal_entry *formal;
450 formal = (formal_entry *) xmalloc (sizeof (formal_entry));
452 sb_new (&formal->name);
453 sb_new (&formal->def);
454 sb_new (&formal->actual);
456 idx = sb_skip_white (idx, in);
457 idx = get_token (idx, in, &formal->name);
458 if (formal->name.len == 0)
460 idx = sb_skip_white (idx, in);
461 if (formal->name.len)
463 /* This is a formal */
464 if (idx < in->len && in->ptr[idx] == '=')
467 idx = get_any_string (idx + 1, in, &formal->def, 1, 0);
471 /* Add to macro's hash table */
472 hash_jam (macro->formal_hash, sb_terminate (&formal->name), formal);
474 formal->index = macro->formal_count;
475 idx = sb_skip_comma (idx, in);
476 macro->formal_count++;
484 formal_entry *formal;
487 /* Add a special NARG formal, which macro_expand will set to the
488 number of arguments. */
489 formal = (formal_entry *) xmalloc (sizeof (formal_entry));
491 sb_new (&formal->name);
492 sb_new (&formal->def);
493 sb_new (&formal->actual);
495 /* The same MRI assemblers which treat '@' characters also use
496 the name $NARG. At least until we find an exception. */
502 sb_add_string (&formal->name, name);
504 /* Add to macro's hash table */
505 hash_jam (macro->formal_hash, name, formal);
507 formal->index = NARG_INDEX;
515 /* Define a new macro. Returns NULL on success, otherwise returns an
516 error message. If NAMEP is not NULL, *NAMEP is set to the name of
517 the macro which was defined. */
520 define_macro (idx, in, label, get_line, namep)
524 int (*get_line) PARAMS ((sb *));
531 macro = (macro_entry *) xmalloc (sizeof (macro_entry));
532 sb_new (¯o->sub);
535 macro->formal_count = 0;
538 idx = sb_skip_white (idx, in);
539 if (! buffer_and_nest ("MACRO", "ENDM", ¯o->sub, get_line))
540 return _("unexpected end of file in macro definition");
541 if (label != NULL && label->len != 0)
543 sb_add_sb (&name, label);
544 if (idx < in->len && in->ptr[idx] == '(')
546 /* It's the label: MACRO (formals,...) sort */
547 idx = do_formals (macro, idx + 1, in);
548 if (in->ptr[idx] != ')')
549 return _("missing ) after formals");
553 /* It's the label: MACRO formals,... sort */
554 idx = do_formals (macro, idx, in);
559 idx = get_token (idx, in, &name);
560 idx = sb_skip_comma (idx, in);
561 idx = do_formals (macro, idx, in);
564 /* and stick it in the macro hash table */
565 for (idx = 0; idx < name.len; idx++)
566 if (isupper ((unsigned char) name.ptr[idx]))
567 name.ptr[idx] = tolower (name.ptr[idx]);
568 namestr = sb_terminate (&name);
569 hash_jam (macro_hash, namestr, (PTR) macro);
579 /* Scan a token, and then skip KIND. */
582 get_apost_token (idx, in, name, kind)
588 idx = get_token (idx, in, name);
590 && in->ptr[idx] == kind
591 && (! macro_mri || macro_strip_at)
592 && (! macro_strip_at || kind == '@'))
597 /* Substitute the actual value for a formal parameter. */
600 sub_actual (start, in, t, formal_hash, kind, out, copyifnotthere)
604 struct hash_control *formal_hash;
612 src = get_apost_token (start, in, t, kind);
613 /* See if it's in the macro's hash table, unless this is
614 macro_strip_at and kind is '@' and the token did not end in '@'. */
617 && (src == start || in->ptr[src - 1] != '@'))
620 ptr = (formal_entry *) hash_find (formal_hash, sb_terminate (t));
625 sb_add_sb (out, &ptr->actual);
629 sb_add_sb (out, &ptr->def);
632 else if (kind == '&')
634 /* Doing this permits people to use & in macro bodies. */
635 sb_add_char (out, '&');
637 else if (copyifnotthere)
643 sb_add_char (out, '\\');
649 /* Expand the body of a macro. */
652 macro_expand_body (in, out, formals, formal_hash, comment_char, locals)
655 formal_entry *formals;
656 struct hash_control *formal_hash;
663 formal_entry *loclist = NULL;
667 while (src < in->len)
669 if (in->ptr[src] == '&')
674 if (src + 1 < in->len && in->ptr[src + 1] == '&')
675 src = sub_actual (src + 2, in, &t, formal_hash, '\'', out, 1);
677 sb_add_char (out, in->ptr[src++]);
681 /* FIXME: Why do we do this? */
682 src = sub_actual (src + 1, in, &t, formal_hash, '&', out, 0);
685 else if (in->ptr[src] == '\\')
688 if (in->ptr[src] == comment_char && comment_char != '\0')
690 /* This is a comment, just drop the rest of the line */
692 && in->ptr[src] != '\n')
695 else if (in->ptr[src] == '(')
697 /* Sub in till the next ')' literally */
699 while (src < in->len && in->ptr[src] != ')')
701 sb_add_char (out, in->ptr[src++]);
703 if (in->ptr[src] == ')')
706 return _("missplaced )");
708 else if (in->ptr[src] == '@')
710 /* Sub in the macro invocation number */
714 sprintf (buffer, "%d", macro_number);
715 sb_add_string (out, buffer);
717 else if (in->ptr[src] == '&')
719 /* This is a preprocessor variable name, we don't do them
721 sb_add_char (out, '\\');
722 sb_add_char (out, '&');
726 && isalnum ((unsigned char) in->ptr[src]))
731 if (isdigit ((unsigned char) in->ptr[src]))
732 ind = in->ptr[src] - '0';
733 else if (isupper ((unsigned char) in->ptr[src]))
734 ind = in->ptr[src] - 'A' + 10;
736 ind = in->ptr[src] - 'a' + 10;
738 for (f = formals; f != NULL; f = f->next)
740 if (f->index == ind - 1)
742 if (f->actual.len != 0)
743 sb_add_sb (out, &f->actual);
745 sb_add_sb (out, &f->def);
753 src = sub_actual (src, in, &t, formal_hash, '\'', out, 0);
756 else if ((macro_alternate || macro_mri)
757 && (isalpha ((unsigned char) in->ptr[src])
758 || in->ptr[src] == '_'
759 || in->ptr[src] == '$')
762 || (src > 0 && in->ptr[src - 1] == '@')))
765 || src + 5 >= in->len
766 || strncasecmp (in->ptr + src, "LOCAL", 5) != 0
767 || ! ISWHITE (in->ptr[src + 5]))
770 src = sub_actual (src, in, &t, formal_hash,
771 (macro_strip_at && inquote) ? '@' : '\'',
778 src = sb_skip_white (src + 5, in);
779 while (in->ptr[src] != '\n' && in->ptr[src] != comment_char)
785 f = (formal_entry *) xmalloc (sizeof (formal_entry));
789 f->index = LOCAL_INDEX;
793 src = get_token (src, in, &f->name);
795 sprintf (buf, "LL%04x", loccnt);
796 sb_add_string (&f->actual, buf);
798 err = hash_jam (formal_hash, sb_terminate (&f->name), f);
802 src = sb_skip_comma (src, in);
806 else if (comment_char != '\0'
807 && in->ptr[src] == comment_char
809 && in->ptr[src + 1] == comment_char
812 /* Two comment chars in a row cause the rest of the line to
814 while (src < in->len && in->ptr[src] != '\n')
817 else if (in->ptr[src] == '"'
818 || (macro_mri && in->ptr[src] == '\''))
821 sb_add_char (out, in->ptr[src++]);
823 else if (in->ptr[src] == '@' && macro_strip_at)
827 && in->ptr[src] == '@')
829 sb_add_char (out, '@');
834 && in->ptr[src] == '='
836 && in->ptr[src + 1] == '=')
841 src = get_token (src + 2, in, &t);
842 ptr = (formal_entry *) hash_find (formal_hash, sb_terminate (&t));
845 /* FIXME: We should really return a warning string here,
846 but we can't, because the == might be in the MRI
847 comment field, and, since the nature of the MRI
848 comment field depends upon the exact instruction
849 being used, we don't have enough information here to
850 figure out whether it is or not. Instead, we leave
851 the == in place, which should cause a syntax error if
852 it is not in a comment. */
853 sb_add_char (out, '=');
854 sb_add_char (out, '=');
861 sb_add_string (out, "-1");
865 sb_add_char (out, '0');
871 sb_add_char (out, in->ptr[src++]);
877 while (loclist != NULL)
882 /* Setting the value to NULL effectively deletes the entry. We
883 avoid calling hash_delete because it doesn't reclaim memory. */
884 hash_jam (formal_hash, sb_terminate (&loclist->name), NULL);
885 sb_kill (&loclist->name);
886 sb_kill (&loclist->def);
887 sb_kill (&loclist->actual);
895 /* Assign values to the formal parameters of a macro, and expand the
899 macro_expand (idx, in, m, out, comment_char)
909 int is_positional = 0;
916 /* Reset any old value the actuals may have */
917 for (f = m->formals; f; f = f->next)
918 sb_reset (&f->actual);
920 while (f != NULL && f->index < 0)
925 /* The macro may be called with an optional qualifier, which may
926 be referred to in the macro body as \0. */
927 if (idx < in->len && in->ptr[idx] == '.')
931 n = (formal_entry *) xmalloc (sizeof (formal_entry));
935 n->index = QUAL_INDEX;
937 n->next = m->formals;
940 idx = get_any_string (idx + 1, in, &n->actual, 1, 0);
944 /* Peel off the actuals and store them away in the hash tables' actuals */
945 idx = sb_skip_white (idx, in);
946 while (idx < in->len && in->ptr[idx] != comment_char)
950 /* Look and see if it's a positional or keyword arg */
952 while (scan < in->len
953 && !ISSEP (in->ptr[scan])
954 && !(macro_mri && in->ptr[scan] == '\'')
955 && (!macro_alternate && in->ptr[scan] != '='))
957 if (scan < in->len && !macro_alternate && in->ptr[scan] == '=')
961 /* It's OK to go from positional to keyword. */
963 /* This is a keyword arg, fetch the formal name and
964 then the actual stuff */
966 idx = get_token (idx, in, &t);
967 if (in->ptr[idx] != '=')
968 return _("confusion in formal parameters");
970 /* Lookup the formal in the macro's list */
971 ptr = (formal_entry *) hash_find (m->formal_hash, sb_terminate (&t));
973 return _("macro formal argument does not exist");
976 /* Insert this value into the right place */
977 sb_reset (&ptr->actual);
978 idx = get_any_string (idx + 1, in, &ptr->actual, 0, 0);
979 if (ptr->actual.len > 0)
985 /* This is a positional arg */
988 return _("can't mix positional and keyword arguments");
996 return _("too many positional arguments");
998 f = (formal_entry *) xmalloc (sizeof (formal_entry));
1001 sb_new (&f->actual);
1005 for (pf = &m->formals; *pf != NULL; pf = &(*pf)->next)
1006 if ((*pf)->index >= c)
1007 c = (*pf)->index + 1;
1014 sb_reset (&f->actual);
1015 idx = get_any_string (idx, in, &f->actual, 1, 0);
1016 if (f->actual.len > 0)
1022 while (f != NULL && f->index < 0);
1026 idx = sb_skip_comma (idx, in);
1029 if (in->ptr[idx] == ',')
1031 if (ISWHITE (in->ptr[idx]))
1041 sb_add_string (&t, macro_strip_at ? "$NARG" : "NARG");
1042 ptr = (formal_entry *) hash_find (m->formal_hash, sb_terminate (&t));
1043 sb_reset (&ptr->actual);
1044 sprintf (buffer, "%d", narg);
1045 sb_add_string (&ptr->actual, buffer);
1048 err = macro_expand_body (&m->sub, out, m->formals, m->formal_hash,
1053 /* Discard any unnamed formal arguments. */
1061 if ((*pf)->name.len != 0)
1065 sb_kill (&(*pf)->name);
1066 sb_kill (&(*pf)->def);
1067 sb_kill (&(*pf)->actual);
1081 /* Check for a macro. If one is found, put the expansion into
1082 *EXPAND. COMMENT_CHAR is the comment character--this is used by
1083 gasp. Return 1 if a macro is found, 0 otherwise. */
1086 check_macro (line, expand, comment_char, error, info)
1098 if (! isalpha ((unsigned char) *line)
1101 && (! macro_mri || *line != '.'))
1105 while (isalnum ((unsigned char) *s)
1110 copy = (char *) alloca (s - line + 1);
1111 memcpy (copy, line, s - line);
1112 copy[s - line] = '\0';
1113 for (cs = copy; *cs != '\0'; cs++)
1114 if (isupper ((unsigned char) *cs))
1115 *cs = tolower (*cs);
1117 macro = (macro_entry *) hash_find (macro_hash, copy);
1122 /* Wrap the line up in an sb. */
1124 while (*s != '\0' && *s != '\n' && *s != '\r')
1125 sb_add_char (&line_sb, *s++);
1128 *error = macro_expand (0, &line_sb, macro, expand, comment_char);
1132 /* export the macro information if requested */
1139 /* Delete a macro. */
1145 hash_delete (macro_hash, name);
1148 /* Handle the MRI IRP and IRPC pseudo-ops. These are handled as a
1149 combined macro definition and execution. This returns NULL on
1150 success, or an error message otherwise. */
1153 expand_irp (irpc, idx, in, out, get_line, comment_char)
1158 int (*get_line) PARAMS ((sb *));
1164 struct hash_control *h;
1172 idx = sb_skip_white (idx, in);
1175 if (! buffer_and_nest (mn, "ENDR", &sub, get_line))
1176 return _("unexpected end of file in irp or irpc");
1182 idx = get_token (idx, in, &f.name);
1183 if (f.name.len == 0)
1184 return _("missing model parameter");
1187 err = hash_jam (h, sb_terminate (&f.name), &f);
1196 idx = sb_skip_comma (idx, in);
1197 if (idx >= in->len || in->ptr[idx] == comment_char)
1199 /* Expand once with a null string. */
1200 err = macro_expand_body (&sub, out, &f, h, comment_char, 0);
1206 if (irpc && in->ptr[idx] == '"')
1208 while (idx < in->len && in->ptr[idx] != comment_char)
1211 idx = get_any_string (idx, in, &f.actual, 1, 0);
1214 if (in->ptr[idx] == '"')
1218 nxt = sb_skip_white (idx + 1, in);
1219 if (nxt >= in->len || in->ptr[nxt] == comment_char)
1225 sb_reset (&f.actual);
1226 sb_add_char (&f.actual, in->ptr[idx]);
1229 err = macro_expand_body (&sub, out, &f, h, comment_char, 0);
1233 idx = sb_skip_comma (idx, in);
1235 idx = sb_skip_white (idx, in);