2004-02-02 Jeff Johnston <jjohnstn@redhat.com>
[binutils.git] / gas / macro.c
blob09917443a1d5695e36972e7f96ba20185369dc8d
1 /* macro.c - macro support for gas
2 Copyright 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003
3 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 "libiberty.h"
58 #include "safe-ctype.h"
59 #include "sb.h"
60 #include "hash.h"
61 #include "macro.h"
63 #include "asintl.h"
65 /* The routines in this file handle macro definition and expansion.
66 They are called by gas. */
68 /* Internal functions. */
70 static int get_token (int, sb *, sb *);
71 static int getstring (int, sb *, sb *);
72 static int get_any_string (int, sb *, sb *, int, int);
73 static int do_formals (macro_entry *, int, sb *);
74 static int get_apost_token (int, sb *, sb *, int);
75 static int sub_actual (int, sb *, sb *, struct hash_control *, int, sb *, int);
76 static const char *macro_expand_body
77 (sb *, sb *, formal_entry *, struct hash_control *, int);
78 static const char *macro_expand (int, sb *, macro_entry *, sb *);
80 #define ISWHITE(x) ((x) == ' ' || (x) == '\t')
82 #define ISSEP(x) \
83 ((x) == ' ' || (x) == '\t' || (x) == ',' || (x) == '"' || (x) == ';' \
84 || (x) == ')' || (x) == '(' \
85 || ((macro_alternate || macro_mri) && ((x) == '<' || (x) == '>')))
87 #define ISBASE(x) \
88 ((x) == 'b' || (x) == 'B' \
89 || (x) == 'q' || (x) == 'Q' \
90 || (x) == 'h' || (x) == 'H' \
91 || (x) == 'd' || (x) == 'D')
93 /* The macro hash table. */
95 struct hash_control *macro_hash;
97 /* Whether any macros have been defined. */
99 int macro_defined;
101 /* Whether we are in alternate syntax mode. */
103 static int macro_alternate;
105 /* Whether we are in MRI mode. */
107 static int macro_mri;
109 /* Whether we should strip '@' characters. */
111 static int macro_strip_at;
113 /* Function to use to parse an expression. */
115 static int (*macro_expr) (const char *, int, sb *, int *);
117 /* Number of macro expansions that have been done. */
119 static int macro_number;
121 /* Initialize macro processing. */
123 void
124 macro_init (int alternate, int mri, int strip_at,
125 int (*expr) (const char *, int, sb *, int *))
127 macro_hash = hash_new ();
128 macro_defined = 0;
129 macro_alternate = alternate;
130 macro_mri = mri;
131 macro_strip_at = strip_at;
132 macro_expr = expr;
135 /* Switch in and out of MRI mode on the fly. */
137 void
138 macro_mri_mode (int mri)
140 macro_mri = mri;
143 /* Read input lines till we get to a TO string.
144 Increase nesting depth if we get a FROM string.
145 Put the results into sb at PTR.
146 Add a new input line to an sb using GET_LINE.
147 Return 1 on success, 0 on unexpected EOF. */
150 buffer_and_nest (const char *from, const char *to, sb *ptr,
151 int (*get_line) (sb *))
153 int from_len = strlen (from);
154 int to_len = strlen (to);
155 int depth = 1;
156 int line_start = ptr->len;
158 int more = get_line (ptr);
160 while (more)
162 /* Try and find the first pseudo op on the line. */
163 int i = line_start;
165 if (! macro_alternate && ! macro_mri)
167 /* With normal syntax we can suck what we want till we get
168 to the dot. With the alternate, labels have to start in
169 the first column, since we cant tell what's a label and
170 whats a pseudoop. */
172 /* Skip leading whitespace. */
173 while (i < ptr->len && ISWHITE (ptr->ptr[i]))
174 i++;
176 /* Skip over a label. */
177 while (i < ptr->len
178 && (ISALNUM (ptr->ptr[i])
179 || ptr->ptr[i] == '_'
180 || ptr->ptr[i] == '$'))
181 i++;
183 /* And a colon. */
184 if (i < ptr->len
185 && ptr->ptr[i] == ':')
186 i++;
189 /* Skip trailing whitespace. */
190 while (i < ptr->len && ISWHITE (ptr->ptr[i]))
191 i++;
193 if (i < ptr->len && (ptr->ptr[i] == '.'
194 || macro_alternate
195 || macro_mri))
197 if (ptr->ptr[i] == '.')
198 i++;
199 if (strncasecmp (ptr->ptr + i, from, from_len) == 0
200 && (ptr->len == (i + from_len)
201 || ! ISALNUM (ptr->ptr[i + from_len])))
202 depth++;
203 if (strncasecmp (ptr->ptr + i, to, to_len) == 0
204 && (ptr->len == (i + to_len)
205 || ! ISALNUM (ptr->ptr[i + to_len])))
207 depth--;
208 if (depth == 0)
210 /* Reset the string to not include the ending rune. */
211 ptr->len = line_start;
212 break;
217 /* Add the original end-of-line char to the end and keep running. */
218 sb_add_char (ptr, more);
219 line_start = ptr->len;
220 more = get_line (ptr);
223 /* Return 1 on success, 0 on unexpected EOF. */
224 return depth == 0;
227 /* Pick up a token. */
229 static int
230 get_token (int idx, sb *in, sb *name)
232 if (idx < in->len
233 && (ISALPHA (in->ptr[idx])
234 || in->ptr[idx] == '_'
235 || in->ptr[idx] == '$'))
237 sb_add_char (name, in->ptr[idx++]);
238 while (idx < in->len
239 && (ISALNUM (in->ptr[idx])
240 || in->ptr[idx] == '_'
241 || in->ptr[idx] == '$'))
243 sb_add_char (name, in->ptr[idx++]);
246 /* Ignore trailing &. */
247 if (macro_alternate && idx < in->len && in->ptr[idx] == '&')
248 idx++;
249 return idx;
252 /* Pick up a string. */
254 static int
255 getstring (int idx, sb *in, sb *acc)
257 idx = sb_skip_white (idx, in);
259 while (idx < in->len
260 && (in->ptr[idx] == '"'
261 || (in->ptr[idx] == '<' && (macro_alternate || macro_mri))
262 || (in->ptr[idx] == '\'' && macro_alternate)))
264 if (in->ptr[idx] == '<')
266 int nest = 0;
267 idx++;
268 while ((in->ptr[idx] != '>' || nest)
269 && idx < in->len)
271 if (in->ptr[idx] == '!')
273 idx++;
274 sb_add_char (acc, in->ptr[idx++]);
276 else
278 if (in->ptr[idx] == '>')
279 nest--;
280 if (in->ptr[idx] == '<')
281 nest++;
282 sb_add_char (acc, in->ptr[idx++]);
285 idx++;
287 else if (in->ptr[idx] == '"' || in->ptr[idx] == '\'')
289 char tchar = in->ptr[idx];
290 int escaped = 0;
292 idx++;
294 while (idx < in->len)
296 if (in->ptr[idx - 1] == '\\')
297 escaped ^= 1;
298 else
299 escaped = 0;
301 if (macro_alternate && in->ptr[idx] == '!')
303 idx ++;
305 sb_add_char (acc, in->ptr[idx]);
307 idx ++;
309 else if (escaped && in->ptr[idx] == tchar)
311 sb_add_char (acc, tchar);
312 idx ++;
314 else
316 if (in->ptr[idx] == tchar)
318 idx ++;
320 if (idx >= in->len || in->ptr[idx] != tchar)
321 break;
324 sb_add_char (acc, in->ptr[idx]);
325 idx ++;
331 return idx;
334 /* Fetch string from the input stream,
335 rules:
336 'Bxyx<whitespace> -> return 'Bxyza
337 %<char> -> return string of decimal value of x
338 "<string>" -> return string
339 xyx<whitespace> -> return xyz
342 static int
343 get_any_string (int idx, sb *in, sb *out, int expand, int pretend_quoted)
345 sb_reset (out);
346 idx = sb_skip_white (idx, in);
348 if (idx < in->len)
350 if (in->len > idx + 2 && in->ptr[idx + 1] == '\'' && ISBASE (in->ptr[idx]))
352 while (!ISSEP (in->ptr[idx]))
353 sb_add_char (out, in->ptr[idx++]);
355 else if (in->ptr[idx] == '%'
356 && macro_alternate
357 && expand)
359 int val;
360 char buf[20];
361 /* Turns the next expression into a string. */
362 /* xgettext: no-c-format */
363 idx = (*macro_expr) (_("% operator needs absolute expression"),
364 idx + 1,
366 &val);
367 sprintf (buf, "%d", val);
368 sb_add_string (out, buf);
370 else if (in->ptr[idx] == '"'
371 || (in->ptr[idx] == '<' && (macro_alternate || macro_mri))
372 || (macro_alternate && in->ptr[idx] == '\''))
374 if (macro_alternate
375 && ! macro_strip_at
376 && expand)
378 /* Keep the quotes. */
379 sb_add_char (out, '\"');
381 idx = getstring (idx, in, out);
382 sb_add_char (out, '\"');
384 else
386 idx = getstring (idx, in, out);
389 else
391 while (idx < in->len
392 && (in->ptr[idx] == '"'
393 || in->ptr[idx] == '\''
394 || pretend_quoted
395 || (in->ptr[idx] != ' '
396 && in->ptr[idx] != '\t'
397 && in->ptr[idx] != ','
398 && (in->ptr[idx] != '<'
399 || (! macro_alternate && ! macro_mri)))))
401 if (in->ptr[idx] == '"'
402 || in->ptr[idx] == '\'')
404 char tchar = in->ptr[idx];
405 sb_add_char (out, in->ptr[idx++]);
406 while (idx < in->len
407 && in->ptr[idx] != tchar)
408 sb_add_char (out, in->ptr[idx++]);
409 if (idx == in->len)
410 return idx;
412 sb_add_char (out, in->ptr[idx++]);
417 return idx;
420 /* Pick up the formal parameters of a macro definition. */
422 static int
423 do_formals (macro_entry *macro, int idx, sb *in)
425 formal_entry **p = &macro->formals;
427 macro->formal_count = 0;
428 macro->formal_hash = hash_new ();
429 while (idx < in->len)
431 formal_entry *formal;
433 formal = (formal_entry *) xmalloc (sizeof (formal_entry));
435 sb_new (&formal->name);
436 sb_new (&formal->def);
437 sb_new (&formal->actual);
439 idx = sb_skip_white (idx, in);
440 idx = get_token (idx, in, &formal->name);
441 if (formal->name.len == 0)
442 break;
443 idx = sb_skip_white (idx, in);
444 if (formal->name.len)
446 /* This is a formal. */
447 if (idx < in->len && in->ptr[idx] == '=')
449 /* Got a default. */
450 idx = get_any_string (idx + 1, in, &formal->def, 1, 0);
454 /* Add to macro's hash table. */
455 hash_jam (macro->formal_hash, sb_terminate (&formal->name), formal);
457 formal->index = macro->formal_count;
458 idx = sb_skip_comma (idx, in);
459 macro->formal_count++;
460 *p = formal;
461 p = &formal->next;
462 *p = NULL;
465 if (macro_mri)
467 formal_entry *formal;
468 const char *name;
470 /* Add a special NARG formal, which macro_expand will set to the
471 number of arguments. */
472 formal = (formal_entry *) xmalloc (sizeof (formal_entry));
474 sb_new (&formal->name);
475 sb_new (&formal->def);
476 sb_new (&formal->actual);
478 /* The same MRI assemblers which treat '@' characters also use
479 the name $NARG. At least until we find an exception. */
480 if (macro_strip_at)
481 name = "$NARG";
482 else
483 name = "NARG";
485 sb_add_string (&formal->name, name);
487 /* Add to macro's hash table. */
488 hash_jam (macro->formal_hash, name, formal);
490 formal->index = NARG_INDEX;
491 *p = formal;
492 formal->next = NULL;
495 return idx;
498 /* Define a new macro. Returns NULL on success, otherwise returns an
499 error message. If NAMEP is not NULL, *NAMEP is set to the name of
500 the macro which was defined. */
502 const char *
503 define_macro (int idx, sb *in, sb *label,
504 int (*get_line) (sb *), const char **namep)
506 macro_entry *macro;
507 sb name;
508 const char *namestr;
510 macro = (macro_entry *) xmalloc (sizeof (macro_entry));
511 sb_new (&macro->sub);
512 sb_new (&name);
514 macro->formal_count = 0;
515 macro->formals = 0;
517 idx = sb_skip_white (idx, in);
518 if (! buffer_and_nest ("MACRO", "ENDM", &macro->sub, get_line))
519 return _("unexpected end of file in macro definition");
520 if (label != NULL && label->len != 0)
522 sb_add_sb (&name, label);
523 if (idx < in->len && in->ptr[idx] == '(')
525 /* It's the label: MACRO (formals,...) sort */
526 idx = do_formals (macro, idx + 1, in);
527 if (in->ptr[idx] != ')')
528 return _("missing ) after formals");
530 else
532 /* It's the label: MACRO formals,... sort */
533 idx = do_formals (macro, idx, in);
536 else
538 idx = get_token (idx, in, &name);
539 idx = sb_skip_comma (idx, in);
540 idx = do_formals (macro, idx, in);
543 /* And stick it in the macro hash table. */
544 for (idx = 0; idx < name.len; idx++)
545 name.ptr[idx] = TOLOWER (name.ptr[idx]);
546 namestr = sb_terminate (&name);
547 hash_jam (macro_hash, namestr, (PTR) macro);
549 macro_defined = 1;
551 if (namep != NULL)
552 *namep = namestr;
554 return NULL;
557 /* Scan a token, and then skip KIND. */
559 static int
560 get_apost_token (int idx, sb *in, sb *name, int kind)
562 idx = get_token (idx, in, name);
563 if (idx < in->len
564 && in->ptr[idx] == kind
565 && (! macro_mri || macro_strip_at)
566 && (! macro_strip_at || kind == '@'))
567 idx++;
568 return idx;
571 /* Substitute the actual value for a formal parameter. */
573 static int
574 sub_actual (int start, sb *in, sb *t, struct hash_control *formal_hash,
575 int kind, sb *out, int copyifnotthere)
577 int src;
578 formal_entry *ptr;
580 src = get_apost_token (start, in, t, kind);
581 /* See if it's in the macro's hash table, unless this is
582 macro_strip_at and kind is '@' and the token did not end in '@'. */
583 if (macro_strip_at
584 && kind == '@'
585 && (src == start || in->ptr[src - 1] != '@'))
586 ptr = NULL;
587 else
588 ptr = (formal_entry *) hash_find (formal_hash, sb_terminate (t));
589 if (ptr)
591 if (ptr->actual.len)
593 sb_add_sb (out, &ptr->actual);
595 else
597 sb_add_sb (out, &ptr->def);
600 else if (kind == '&')
602 /* Doing this permits people to use & in macro bodies. */
603 sb_add_char (out, '&');
604 sb_add_sb (out, t);
606 else if (copyifnotthere)
608 sb_add_sb (out, t);
610 else
612 sb_add_char (out, '\\');
613 sb_add_sb (out, t);
615 return src;
618 /* Expand the body of a macro. */
620 static const char *
621 macro_expand_body (sb *in, sb *out, formal_entry *formals,
622 struct hash_control *formal_hash, int locals)
624 sb t;
625 int src = 0;
626 int inquote = 0;
627 formal_entry *loclist = NULL;
629 sb_new (&t);
631 while (src < in->len)
633 if (in->ptr[src] == '&')
635 sb_reset (&t);
636 if (macro_mri)
638 if (src + 1 < in->len && in->ptr[src + 1] == '&')
639 src = sub_actual (src + 2, in, &t, formal_hash, '\'', out, 1);
640 else
641 sb_add_char (out, in->ptr[src++]);
643 else
645 /* FIXME: Why do we do this? */
646 src = sub_actual (src + 1, in, &t, formal_hash, '&', out, 0);
649 else if (in->ptr[src] == '\\')
651 src++;
652 if (in->ptr[src] == '(')
654 /* Sub in till the next ')' literally. */
655 src++;
656 while (src < in->len && in->ptr[src] != ')')
658 sb_add_char (out, in->ptr[src++]);
660 if (in->ptr[src] == ')')
661 src++;
662 else
663 return _("missplaced )");
665 else if (in->ptr[src] == '@')
667 /* Sub in the macro invocation number. */
669 char buffer[10];
670 src++;
671 sprintf (buffer, "%d", macro_number);
672 sb_add_string (out, buffer);
674 else if (in->ptr[src] == '&')
676 /* This is a preprocessor variable name, we don't do them
677 here. */
678 sb_add_char (out, '\\');
679 sb_add_char (out, '&');
680 src++;
682 else if (macro_mri && ISALNUM (in->ptr[src]))
684 int ind;
685 formal_entry *f;
687 if (ISDIGIT (in->ptr[src]))
688 ind = in->ptr[src] - '0';
689 else if (ISUPPER (in->ptr[src]))
690 ind = in->ptr[src] - 'A' + 10;
691 else
692 ind = in->ptr[src] - 'a' + 10;
693 ++src;
694 for (f = formals; f != NULL; f = f->next)
696 if (f->index == ind - 1)
698 if (f->actual.len != 0)
699 sb_add_sb (out, &f->actual);
700 else
701 sb_add_sb (out, &f->def);
702 break;
706 else
708 sb_reset (&t);
709 src = sub_actual (src, in, &t, formal_hash, '\'', out, 0);
712 else if ((macro_alternate || macro_mri)
713 && (ISALPHA (in->ptr[src])
714 || in->ptr[src] == '_'
715 || in->ptr[src] == '$')
716 && (! inquote
717 || ! macro_strip_at
718 || (src > 0 && in->ptr[src - 1] == '@')))
720 if (! locals
721 || src + 5 >= in->len
722 || strncasecmp (in->ptr + src, "LOCAL", 5) != 0
723 || ! ISWHITE (in->ptr[src + 5]))
725 sb_reset (&t);
726 src = sub_actual (src, in, &t, formal_hash,
727 (macro_strip_at && inquote) ? '@' : '\'',
728 out, 1);
730 else
732 formal_entry *f;
734 src = sb_skip_white (src + 5, in);
735 while (in->ptr[src] != '\n')
737 static int loccnt;
738 char buf[20];
739 const char *err;
741 f = (formal_entry *) xmalloc (sizeof (formal_entry));
742 sb_new (&f->name);
743 sb_new (&f->def);
744 sb_new (&f->actual);
745 f->index = LOCAL_INDEX;
746 f->next = loclist;
747 loclist = f;
749 src = get_token (src, in, &f->name);
750 ++loccnt;
751 sprintf (buf, "LL%04x", loccnt);
752 sb_add_string (&f->actual, buf);
754 err = hash_jam (formal_hash, sb_terminate (&f->name), f);
755 if (err != NULL)
756 return err;
758 src = sb_skip_comma (src, in);
762 else if (in->ptr[src] == '"'
763 || (macro_mri && in->ptr[src] == '\''))
765 inquote = !inquote;
766 sb_add_char (out, in->ptr[src++]);
768 else if (in->ptr[src] == '@' && macro_strip_at)
770 ++src;
771 if (src < in->len
772 && in->ptr[src] == '@')
774 sb_add_char (out, '@');
775 ++src;
778 else if (macro_mri
779 && in->ptr[src] == '='
780 && src + 1 < in->len
781 && in->ptr[src + 1] == '=')
783 formal_entry *ptr;
785 sb_reset (&t);
786 src = get_token (src + 2, in, &t);
787 ptr = (formal_entry *) hash_find (formal_hash, sb_terminate (&t));
788 if (ptr == NULL)
790 /* FIXME: We should really return a warning string here,
791 but we can't, because the == might be in the MRI
792 comment field, and, since the nature of the MRI
793 comment field depends upon the exact instruction
794 being used, we don't have enough information here to
795 figure out whether it is or not. Instead, we leave
796 the == in place, which should cause a syntax error if
797 it is not in a comment. */
798 sb_add_char (out, '=');
799 sb_add_char (out, '=');
800 sb_add_sb (out, &t);
802 else
804 if (ptr->actual.len)
806 sb_add_string (out, "-1");
808 else
810 sb_add_char (out, '0');
814 else
816 sb_add_char (out, in->ptr[src++]);
820 sb_kill (&t);
822 while (loclist != NULL)
824 formal_entry *f;
826 f = loclist->next;
827 /* Setting the value to NULL effectively deletes the entry. We
828 avoid calling hash_delete because it doesn't reclaim memory. */
829 hash_jam (formal_hash, sb_terminate (&loclist->name), NULL);
830 sb_kill (&loclist->name);
831 sb_kill (&loclist->def);
832 sb_kill (&loclist->actual);
833 free (loclist);
834 loclist = f;
837 return NULL;
840 /* Assign values to the formal parameters of a macro, and expand the
841 body. */
843 static const char *
844 macro_expand (int idx, sb *in, macro_entry *m, sb *out)
846 sb t;
847 formal_entry *ptr;
848 formal_entry *f;
849 int is_positional = 0;
850 int is_keyword = 0;
851 int narg = 0;
852 const char *err;
854 sb_new (&t);
856 /* Reset any old value the actuals may have. */
857 for (f = m->formals; f; f = f->next)
858 sb_reset (&f->actual);
859 f = m->formals;
860 while (f != NULL && f->index < 0)
861 f = f->next;
863 if (macro_mri)
865 /* The macro may be called with an optional qualifier, which may
866 be referred to in the macro body as \0. */
867 if (idx < in->len && in->ptr[idx] == '.')
869 /* The Microtec assembler ignores this if followed by a white space.
870 (Macro invocation with empty extension) */
871 idx++;
872 if ( idx < in->len
873 && in->ptr[idx] != ' '
874 && in->ptr[idx] != '\t')
876 formal_entry *n;
878 n = (formal_entry *) xmalloc (sizeof (formal_entry));
879 sb_new (&n->name);
880 sb_new (&n->def);
881 sb_new (&n->actual);
882 n->index = QUAL_INDEX;
884 n->next = m->formals;
885 m->formals = n;
887 idx = get_any_string (idx, in, &n->actual, 1, 0);
892 /* Peel off the actuals and store them away in the hash tables' actuals. */
893 idx = sb_skip_white (idx, in);
894 while (idx < in->len)
896 int scan;
898 /* Look and see if it's a positional or keyword arg. */
899 scan = idx;
900 while (scan < in->len
901 && !ISSEP (in->ptr[scan])
902 && !(macro_mri && in->ptr[scan] == '\'')
903 && (!macro_alternate && in->ptr[scan] != '='))
904 scan++;
905 if (scan < in->len && !macro_alternate && in->ptr[scan] == '=')
907 is_keyword = 1;
909 /* It's OK to go from positional to keyword. */
911 /* This is a keyword arg, fetch the formal name and
912 then the actual stuff. */
913 sb_reset (&t);
914 idx = get_token (idx, in, &t);
915 if (in->ptr[idx] != '=')
916 return _("confusion in formal parameters");
918 /* Lookup the formal in the macro's list. */
919 ptr = (formal_entry *) hash_find (m->formal_hash, sb_terminate (&t));
920 if (!ptr)
921 return _("macro formal argument does not exist");
922 else
924 /* Insert this value into the right place. */
925 sb_reset (&ptr->actual);
926 idx = get_any_string (idx + 1, in, &ptr->actual, 0, 0);
927 if (ptr->actual.len > 0)
928 ++narg;
931 else
933 /* This is a positional arg. */
934 is_positional = 1;
935 if (is_keyword)
936 return _("can't mix positional and keyword arguments");
938 if (!f)
940 formal_entry **pf;
941 int c;
943 if (!macro_mri)
944 return _("too many positional arguments");
946 f = (formal_entry *) xmalloc (sizeof (formal_entry));
947 sb_new (&f->name);
948 sb_new (&f->def);
949 sb_new (&f->actual);
950 f->next = NULL;
952 c = -1;
953 for (pf = &m->formals; *pf != NULL; pf = &(*pf)->next)
954 if ((*pf)->index >= c)
955 c = (*pf)->index + 1;
956 if (c == -1)
957 c = 0;
958 *pf = f;
959 f->index = c;
962 sb_reset (&f->actual);
963 idx = get_any_string (idx, in, &f->actual, 1, 0);
964 if (f->actual.len > 0)
965 ++narg;
968 f = f->next;
970 while (f != NULL && f->index < 0);
973 if (! macro_mri)
974 idx = sb_skip_comma (idx, in);
975 else
977 if (in->ptr[idx] == ',')
978 ++idx;
979 if (ISWHITE (in->ptr[idx]))
980 break;
984 if (macro_mri)
986 char buffer[20];
988 sb_reset (&t);
989 sb_add_string (&t, macro_strip_at ? "$NARG" : "NARG");
990 ptr = (formal_entry *) hash_find (m->formal_hash, sb_terminate (&t));
991 sb_reset (&ptr->actual);
992 sprintf (buffer, "%d", narg);
993 sb_add_string (&ptr->actual, buffer);
996 err = macro_expand_body (&m->sub, out, m->formals, m->formal_hash, 1);
997 if (err != NULL)
998 return err;
1000 /* Discard any unnamed formal arguments. */
1001 if (macro_mri)
1003 formal_entry **pf;
1005 pf = &m->formals;
1006 while (*pf != NULL)
1008 if ((*pf)->name.len != 0)
1009 pf = &(*pf)->next;
1010 else
1012 sb_kill (&(*pf)->name);
1013 sb_kill (&(*pf)->def);
1014 sb_kill (&(*pf)->actual);
1015 f = (*pf)->next;
1016 free (*pf);
1017 *pf = f;
1022 sb_kill (&t);
1023 macro_number++;
1025 return NULL;
1028 /* Check for a macro. If one is found, put the expansion into
1029 *EXPAND. Return 1 if a macro is found, 0 otherwise. */
1032 check_macro (const char *line, sb *expand,
1033 const char **error, macro_entry **info)
1035 const char *s;
1036 char *copy, *cs;
1037 macro_entry *macro;
1038 sb line_sb;
1040 if (! ISALPHA (*line)
1041 && *line != '_'
1042 && *line != '$'
1043 && (! macro_mri || *line != '.'))
1044 return 0;
1046 s = line + 1;
1047 while (ISALNUM (*s)
1048 || *s == '_'
1049 || *s == '$')
1050 ++s;
1052 copy = (char *) alloca (s - line + 1);
1053 memcpy (copy, line, s - line);
1054 copy[s - line] = '\0';
1055 for (cs = copy; *cs != '\0'; cs++)
1056 *cs = TOLOWER (*cs);
1058 macro = (macro_entry *) hash_find (macro_hash, copy);
1060 if (macro == NULL)
1061 return 0;
1063 /* Wrap the line up in an sb. */
1064 sb_new (&line_sb);
1065 while (*s != '\0' && *s != '\n' && *s != '\r')
1066 sb_add_char (&line_sb, *s++);
1068 sb_new (expand);
1069 *error = macro_expand (0, &line_sb, macro, expand);
1071 sb_kill (&line_sb);
1073 /* Export the macro information if requested. */
1074 if (info)
1075 *info = macro;
1077 return 1;
1080 /* Delete a macro. */
1082 void
1083 delete_macro (const char *name)
1085 hash_delete (macro_hash, name);
1088 /* Handle the MRI IRP and IRPC pseudo-ops. These are handled as a
1089 combined macro definition and execution. This returns NULL on
1090 success, or an error message otherwise. */
1092 const char *
1093 expand_irp (int irpc, int idx, sb *in, sb *out, int (*get_line) (sb *))
1095 const char *mn;
1096 sb sub;
1097 formal_entry f;
1098 struct hash_control *h;
1099 const char *err;
1101 if (irpc)
1102 mn = "IRPC";
1103 else
1104 mn = "IRP";
1106 idx = sb_skip_white (idx, in);
1108 sb_new (&sub);
1109 if (! buffer_and_nest (mn, "ENDR", &sub, get_line))
1110 return _("unexpected end of file in irp or irpc");
1112 sb_new (&f.name);
1113 sb_new (&f.def);
1114 sb_new (&f.actual);
1116 idx = get_token (idx, in, &f.name);
1117 if (f.name.len == 0)
1118 return _("missing model parameter");
1120 h = hash_new ();
1121 err = hash_jam (h, sb_terminate (&f.name), &f);
1122 if (err != NULL)
1123 return err;
1125 f.index = 1;
1126 f.next = NULL;
1128 sb_reset (out);
1130 idx = sb_skip_comma (idx, in);
1131 if (idx >= in->len)
1133 /* Expand once with a null string. */
1134 err = macro_expand_body (&sub, out, &f, h, 0);
1135 if (err != NULL)
1136 return err;
1138 else
1140 if (irpc && in->ptr[idx] == '"')
1141 ++idx;
1142 while (idx < in->len)
1144 if (!irpc)
1145 idx = get_any_string (idx, in, &f.actual, 1, 0);
1146 else
1148 if (in->ptr[idx] == '"')
1150 int nxt;
1152 nxt = sb_skip_white (idx + 1, in);
1153 if (nxt >= in->len)
1155 idx = nxt;
1156 break;
1159 sb_reset (&f.actual);
1160 sb_add_char (&f.actual, in->ptr[idx]);
1161 ++idx;
1163 err = macro_expand_body (&sub, out, &f, h, 0);
1164 if (err != NULL)
1165 return err;
1166 if (!irpc)
1167 idx = sb_skip_comma (idx, in);
1168 else
1169 idx = sb_skip_white (idx, in);
1173 hash_die (h);
1174 sb_kill (&sub);
1176 return NULL;