include/
[binutils.git] / gas / macro.c
blob2df32971674223fdd48c432e9c472f3e94794141
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 alternate mode on the fly. */
137 void
138 macro_set_alternate (int alternate)
140 macro_alternate = alternate;
143 /* Switch in and out of MRI mode on the fly. */
145 void
146 macro_mri_mode (int mri)
148 macro_mri = mri;
151 /* Read input lines till we get to a TO string.
152 Increase nesting depth if we get a FROM string.
153 Put the results into sb at PTR.
154 Add a new input line to an sb using GET_LINE.
155 Return 1 on success, 0 on unexpected EOF. */
158 buffer_and_nest (const char *from, const char *to, sb *ptr,
159 int (*get_line) (sb *))
161 int from_len = strlen (from);
162 int to_len = strlen (to);
163 int depth = 1;
164 int line_start = ptr->len;
166 int more = get_line (ptr);
168 while (more)
170 /* Try and find the first pseudo op on the line. */
171 int i = line_start;
173 if (! macro_alternate && ! macro_mri)
175 /* With normal syntax we can suck what we want till we get
176 to the dot. With the alternate, labels have to start in
177 the first column, since we cant tell what's a label and
178 whats a pseudoop. */
180 /* Skip leading whitespace. */
181 while (i < ptr->len && ISWHITE (ptr->ptr[i]))
182 i++;
184 /* Skip over a label. */
185 while (i < ptr->len
186 && (ISALNUM (ptr->ptr[i])
187 || ptr->ptr[i] == '_'
188 || ptr->ptr[i] == '$'))
189 i++;
191 /* And a colon. */
192 if (i < ptr->len
193 && ptr->ptr[i] == ':')
194 i++;
197 /* Skip trailing whitespace. */
198 while (i < ptr->len && ISWHITE (ptr->ptr[i]))
199 i++;
201 if (i < ptr->len && (ptr->ptr[i] == '.'
202 || macro_alternate
203 || macro_mri))
205 if (ptr->ptr[i] == '.')
206 i++;
207 if (strncasecmp (ptr->ptr + i, from, from_len) == 0
208 && (ptr->len == (i + from_len)
209 || ! ISALNUM (ptr->ptr[i + from_len])))
210 depth++;
211 if (strncasecmp (ptr->ptr + i, to, to_len) == 0
212 && (ptr->len == (i + to_len)
213 || ! ISALNUM (ptr->ptr[i + to_len])))
215 depth--;
216 if (depth == 0)
218 /* Reset the string to not include the ending rune. */
219 ptr->len = line_start;
220 break;
225 /* Add the original end-of-line char to the end and keep running. */
226 sb_add_char (ptr, more);
227 line_start = ptr->len;
228 more = get_line (ptr);
231 /* Return 1 on success, 0 on unexpected EOF. */
232 return depth == 0;
235 /* Pick up a token. */
237 static int
238 get_token (int idx, sb *in, sb *name)
240 if (idx < in->len
241 && (ISALPHA (in->ptr[idx])
242 || in->ptr[idx] == '_'
243 || in->ptr[idx] == '$'))
245 sb_add_char (name, in->ptr[idx++]);
246 while (idx < in->len
247 && (ISALNUM (in->ptr[idx])
248 || in->ptr[idx] == '_'
249 || in->ptr[idx] == '$'))
251 sb_add_char (name, in->ptr[idx++]);
254 /* Ignore trailing &. */
255 if (macro_alternate && idx < in->len && in->ptr[idx] == '&')
256 idx++;
257 return idx;
260 /* Pick up a string. */
262 static int
263 getstring (int idx, sb *in, sb *acc)
265 idx = sb_skip_white (idx, in);
267 while (idx < in->len
268 && (in->ptr[idx] == '"'
269 || (in->ptr[idx] == '<' && (macro_alternate || macro_mri))
270 || (in->ptr[idx] == '\'' && macro_alternate)))
272 if (in->ptr[idx] == '<')
274 int nest = 0;
275 idx++;
276 while ((in->ptr[idx] != '>' || nest)
277 && idx < in->len)
279 if (in->ptr[idx] == '!')
281 idx++;
282 sb_add_char (acc, in->ptr[idx++]);
284 else
286 if (in->ptr[idx] == '>')
287 nest--;
288 if (in->ptr[idx] == '<')
289 nest++;
290 sb_add_char (acc, in->ptr[idx++]);
293 idx++;
295 else if (in->ptr[idx] == '"' || in->ptr[idx] == '\'')
297 char tchar = in->ptr[idx];
298 int escaped = 0;
300 idx++;
302 while (idx < in->len)
304 if (in->ptr[idx - 1] == '\\')
305 escaped ^= 1;
306 else
307 escaped = 0;
309 if (macro_alternate && in->ptr[idx] == '!')
311 idx ++;
313 sb_add_char (acc, in->ptr[idx]);
315 idx ++;
317 else if (escaped && in->ptr[idx] == tchar)
319 sb_add_char (acc, tchar);
320 idx ++;
322 else
324 if (in->ptr[idx] == tchar)
326 idx ++;
328 if (idx >= in->len || in->ptr[idx] != tchar)
329 break;
332 sb_add_char (acc, in->ptr[idx]);
333 idx ++;
339 return idx;
342 /* Fetch string from the input stream,
343 rules:
344 'Bxyx<whitespace> -> return 'Bxyza
345 %<char> -> return string of decimal value of x
346 "<string>" -> return string
347 xyx<whitespace> -> return xyz
350 static int
351 get_any_string (int idx, sb *in, sb *out, int expand, int pretend_quoted)
353 sb_reset (out);
354 idx = sb_skip_white (idx, in);
356 if (idx < in->len)
358 if (in->len > idx + 2 && in->ptr[idx + 1] == '\'' && ISBASE (in->ptr[idx]))
360 while (!ISSEP (in->ptr[idx]))
361 sb_add_char (out, in->ptr[idx++]);
363 else if (in->ptr[idx] == '%'
364 && macro_alternate
365 && expand)
367 int val;
368 char buf[20];
369 /* Turns the next expression into a string. */
370 /* xgettext: no-c-format */
371 idx = (*macro_expr) (_("% operator needs absolute expression"),
372 idx + 1,
374 &val);
375 sprintf (buf, "%d", val);
376 sb_add_string (out, buf);
378 else if (in->ptr[idx] == '"'
379 || (in->ptr[idx] == '<' && (macro_alternate || macro_mri))
380 || (macro_alternate && in->ptr[idx] == '\''))
382 if (macro_alternate
383 && ! macro_strip_at
384 && expand)
386 /* Keep the quotes. */
387 sb_add_char (out, '\"');
389 idx = getstring (idx, in, out);
390 sb_add_char (out, '\"');
392 else
394 idx = getstring (idx, in, out);
397 else
399 while (idx < in->len
400 && (in->ptr[idx] == '"'
401 || in->ptr[idx] == '\''
402 || pretend_quoted
403 || (in->ptr[idx] != ' '
404 && in->ptr[idx] != '\t'
405 && in->ptr[idx] != ','
406 && (in->ptr[idx] != '<'
407 || (! macro_alternate && ! macro_mri)))))
409 if (in->ptr[idx] == '"'
410 || in->ptr[idx] == '\'')
412 char tchar = in->ptr[idx];
413 sb_add_char (out, in->ptr[idx++]);
414 while (idx < in->len
415 && in->ptr[idx] != tchar)
416 sb_add_char (out, in->ptr[idx++]);
417 if (idx == in->len)
418 return idx;
420 sb_add_char (out, in->ptr[idx++]);
425 return idx;
428 /* Pick up the formal parameters of a macro definition. */
430 static int
431 do_formals (macro_entry *macro, int idx, sb *in)
433 formal_entry **p = &macro->formals;
435 macro->formal_count = 0;
436 macro->formal_hash = hash_new ();
437 while (idx < in->len)
439 formal_entry *formal;
441 formal = (formal_entry *) xmalloc (sizeof (formal_entry));
443 sb_new (&formal->name);
444 sb_new (&formal->def);
445 sb_new (&formal->actual);
447 idx = sb_skip_white (idx, in);
448 idx = get_token (idx, in, &formal->name);
449 if (formal->name.len == 0)
450 break;
451 idx = sb_skip_white (idx, in);
452 if (formal->name.len)
454 /* This is a formal. */
455 if (idx < in->len && in->ptr[idx] == '=')
457 /* Got a default. */
458 idx = get_any_string (idx + 1, in, &formal->def, 1, 0);
462 /* Add to macro's hash table. */
463 hash_jam (macro->formal_hash, sb_terminate (&formal->name), formal);
465 formal->index = macro->formal_count;
466 idx = sb_skip_comma (idx, in);
467 macro->formal_count++;
468 *p = formal;
469 p = &formal->next;
470 *p = NULL;
473 if (macro_mri)
475 formal_entry *formal;
476 const char *name;
478 /* Add a special NARG formal, which macro_expand will set to the
479 number of arguments. */
480 formal = (formal_entry *) xmalloc (sizeof (formal_entry));
482 sb_new (&formal->name);
483 sb_new (&formal->def);
484 sb_new (&formal->actual);
486 /* The same MRI assemblers which treat '@' characters also use
487 the name $NARG. At least until we find an exception. */
488 if (macro_strip_at)
489 name = "$NARG";
490 else
491 name = "NARG";
493 sb_add_string (&formal->name, name);
495 /* Add to macro's hash table. */
496 hash_jam (macro->formal_hash, name, formal);
498 formal->index = NARG_INDEX;
499 *p = formal;
500 formal->next = NULL;
503 return idx;
506 /* Define a new macro. Returns NULL on success, otherwise returns an
507 error message. If NAMEP is not NULL, *NAMEP is set to the name of
508 the macro which was defined. */
510 const char *
511 define_macro (int idx, sb *in, sb *label,
512 int (*get_line) (sb *), const char **namep)
514 macro_entry *macro;
515 sb name;
516 const char *namestr;
518 macro = (macro_entry *) xmalloc (sizeof (macro_entry));
519 sb_new (&macro->sub);
520 sb_new (&name);
522 macro->formal_count = 0;
523 macro->formals = 0;
525 idx = sb_skip_white (idx, in);
526 if (! buffer_and_nest ("MACRO", "ENDM", &macro->sub, get_line))
527 return _("unexpected end of file in macro definition");
528 if (label != NULL && label->len != 0)
530 sb_add_sb (&name, label);
531 if (idx < in->len && in->ptr[idx] == '(')
533 /* It's the label: MACRO (formals,...) sort */
534 idx = do_formals (macro, idx + 1, in);
535 if (in->ptr[idx] != ')')
536 return _("missing ) after formals");
538 else
540 /* It's the label: MACRO formals,... sort */
541 idx = do_formals (macro, idx, in);
544 else
546 idx = get_token (idx, in, &name);
547 idx = sb_skip_comma (idx, in);
548 idx = do_formals (macro, idx, in);
551 /* And stick it in the macro hash table. */
552 for (idx = 0; idx < name.len; idx++)
553 name.ptr[idx] = TOLOWER (name.ptr[idx]);
554 namestr = sb_terminate (&name);
555 hash_jam (macro_hash, namestr, (PTR) macro);
557 macro_defined = 1;
559 if (namep != NULL)
560 *namep = namestr;
562 return NULL;
565 /* Scan a token, and then skip KIND. */
567 static int
568 get_apost_token (int idx, sb *in, sb *name, int kind)
570 idx = get_token (idx, in, name);
571 if (idx < in->len
572 && in->ptr[idx] == kind
573 && (! macro_mri || macro_strip_at)
574 && (! macro_strip_at || kind == '@'))
575 idx++;
576 return idx;
579 /* Substitute the actual value for a formal parameter. */
581 static int
582 sub_actual (int start, sb *in, sb *t, struct hash_control *formal_hash,
583 int kind, sb *out, int copyifnotthere)
585 int src;
586 formal_entry *ptr;
588 src = get_apost_token (start, in, t, kind);
589 /* See if it's in the macro's hash table, unless this is
590 macro_strip_at and kind is '@' and the token did not end in '@'. */
591 if (macro_strip_at
592 && kind == '@'
593 && (src == start || in->ptr[src - 1] != '@'))
594 ptr = NULL;
595 else
596 ptr = (formal_entry *) hash_find (formal_hash, sb_terminate (t));
597 if (ptr)
599 if (ptr->actual.len)
601 sb_add_sb (out, &ptr->actual);
603 else
605 sb_add_sb (out, &ptr->def);
608 else if (kind == '&')
610 /* Doing this permits people to use & in macro bodies. */
611 sb_add_char (out, '&');
612 sb_add_sb (out, t);
614 else if (copyifnotthere)
616 sb_add_sb (out, t);
618 else
620 sb_add_char (out, '\\');
621 sb_add_sb (out, t);
623 return src;
626 /* Expand the body of a macro. */
628 static const char *
629 macro_expand_body (sb *in, sb *out, formal_entry *formals,
630 struct hash_control *formal_hash, int locals)
632 sb t;
633 int src = 0;
634 int inquote = 0;
635 formal_entry *loclist = NULL;
637 sb_new (&t);
639 while (src < in->len)
641 if (in->ptr[src] == '&')
643 sb_reset (&t);
644 if (macro_mri)
646 if (src + 1 < in->len && in->ptr[src + 1] == '&')
647 src = sub_actual (src + 2, in, &t, formal_hash, '\'', out, 1);
648 else
649 sb_add_char (out, in->ptr[src++]);
651 else
653 /* FIXME: Why do we do this? */
654 src = sub_actual (src + 1, in, &t, formal_hash, '&', out, 0);
657 else if (in->ptr[src] == '\\')
659 src++;
660 if (in->ptr[src] == '(')
662 /* Sub in till the next ')' literally. */
663 src++;
664 while (src < in->len && in->ptr[src] != ')')
666 sb_add_char (out, in->ptr[src++]);
668 if (in->ptr[src] == ')')
669 src++;
670 else
671 return _("missplaced )");
673 else if (in->ptr[src] == '@')
675 /* Sub in the macro invocation number. */
677 char buffer[10];
678 src++;
679 sprintf (buffer, "%d", macro_number);
680 sb_add_string (out, buffer);
682 else if (in->ptr[src] == '&')
684 /* This is a preprocessor variable name, we don't do them
685 here. */
686 sb_add_char (out, '\\');
687 sb_add_char (out, '&');
688 src++;
690 else if (macro_mri && ISALNUM (in->ptr[src]))
692 int ind;
693 formal_entry *f;
695 if (ISDIGIT (in->ptr[src]))
696 ind = in->ptr[src] - '0';
697 else if (ISUPPER (in->ptr[src]))
698 ind = in->ptr[src] - 'A' + 10;
699 else
700 ind = in->ptr[src] - 'a' + 10;
701 ++src;
702 for (f = formals; f != NULL; f = f->next)
704 if (f->index == ind - 1)
706 if (f->actual.len != 0)
707 sb_add_sb (out, &f->actual);
708 else
709 sb_add_sb (out, &f->def);
710 break;
714 else
716 sb_reset (&t);
717 src = sub_actual (src, in, &t, formal_hash, '\'', out, 0);
720 else if ((macro_alternate || macro_mri)
721 && (ISALPHA (in->ptr[src])
722 || in->ptr[src] == '_'
723 || in->ptr[src] == '$')
724 && (! inquote
725 || ! macro_strip_at
726 || (src > 0 && in->ptr[src - 1] == '@')))
728 if (! locals
729 || src + 5 >= in->len
730 || strncasecmp (in->ptr + src, "LOCAL", 5) != 0
731 || ! ISWHITE (in->ptr[src + 5]))
733 sb_reset (&t);
734 src = sub_actual (src, in, &t, formal_hash,
735 (macro_strip_at && inquote) ? '@' : '\'',
736 out, 1);
738 else
740 formal_entry *f;
742 src = sb_skip_white (src + 5, in);
743 while (in->ptr[src] != '\n')
745 static int loccnt;
746 char buf[20];
747 const char *err;
749 f = (formal_entry *) xmalloc (sizeof (formal_entry));
750 sb_new (&f->name);
751 sb_new (&f->def);
752 sb_new (&f->actual);
753 f->index = LOCAL_INDEX;
754 f->next = loclist;
755 loclist = f;
757 src = get_token (src, in, &f->name);
758 ++loccnt;
759 sprintf (buf, "LL%04x", loccnt);
760 sb_add_string (&f->actual, buf);
762 err = hash_jam (formal_hash, sb_terminate (&f->name), f);
763 if (err != NULL)
764 return err;
766 src = sb_skip_comma (src, in);
770 else if (in->ptr[src] == '"'
771 || (macro_mri && in->ptr[src] == '\''))
773 inquote = !inquote;
774 sb_add_char (out, in->ptr[src++]);
776 else if (in->ptr[src] == '@' && macro_strip_at)
778 ++src;
779 if (src < in->len
780 && in->ptr[src] == '@')
782 sb_add_char (out, '@');
783 ++src;
786 else if (macro_mri
787 && in->ptr[src] == '='
788 && src + 1 < in->len
789 && in->ptr[src + 1] == '=')
791 formal_entry *ptr;
793 sb_reset (&t);
794 src = get_token (src + 2, in, &t);
795 ptr = (formal_entry *) hash_find (formal_hash, sb_terminate (&t));
796 if (ptr == NULL)
798 /* FIXME: We should really return a warning string here,
799 but we can't, because the == might be in the MRI
800 comment field, and, since the nature of the MRI
801 comment field depends upon the exact instruction
802 being used, we don't have enough information here to
803 figure out whether it is or not. Instead, we leave
804 the == in place, which should cause a syntax error if
805 it is not in a comment. */
806 sb_add_char (out, '=');
807 sb_add_char (out, '=');
808 sb_add_sb (out, &t);
810 else
812 if (ptr->actual.len)
814 sb_add_string (out, "-1");
816 else
818 sb_add_char (out, '0');
822 else
824 sb_add_char (out, in->ptr[src++]);
828 sb_kill (&t);
830 while (loclist != NULL)
832 formal_entry *f;
834 f = loclist->next;
835 /* Setting the value to NULL effectively deletes the entry. We
836 avoid calling hash_delete because it doesn't reclaim memory. */
837 hash_jam (formal_hash, sb_terminate (&loclist->name), NULL);
838 sb_kill (&loclist->name);
839 sb_kill (&loclist->def);
840 sb_kill (&loclist->actual);
841 free (loclist);
842 loclist = f;
845 return NULL;
848 /* Assign values to the formal parameters of a macro, and expand the
849 body. */
851 static const char *
852 macro_expand (int idx, sb *in, macro_entry *m, sb *out)
854 sb t;
855 formal_entry *ptr;
856 formal_entry *f;
857 int is_positional = 0;
858 int is_keyword = 0;
859 int narg = 0;
860 const char *err;
862 sb_new (&t);
864 /* Reset any old value the actuals may have. */
865 for (f = m->formals; f; f = f->next)
866 sb_reset (&f->actual);
867 f = m->formals;
868 while (f != NULL && f->index < 0)
869 f = f->next;
871 if (macro_mri)
873 /* The macro may be called with an optional qualifier, which may
874 be referred to in the macro body as \0. */
875 if (idx < in->len && in->ptr[idx] == '.')
877 /* The Microtec assembler ignores this if followed by a white space.
878 (Macro invocation with empty extension) */
879 idx++;
880 if ( idx < in->len
881 && in->ptr[idx] != ' '
882 && in->ptr[idx] != '\t')
884 formal_entry *n;
886 n = (formal_entry *) xmalloc (sizeof (formal_entry));
887 sb_new (&n->name);
888 sb_new (&n->def);
889 sb_new (&n->actual);
890 n->index = QUAL_INDEX;
892 n->next = m->formals;
893 m->formals = n;
895 idx = get_any_string (idx, in, &n->actual, 1, 0);
900 /* Peel off the actuals and store them away in the hash tables' actuals. */
901 idx = sb_skip_white (idx, in);
902 while (idx < in->len)
904 int scan;
906 /* Look and see if it's a positional or keyword arg. */
907 scan = idx;
908 while (scan < in->len
909 && !ISSEP (in->ptr[scan])
910 && !(macro_mri && in->ptr[scan] == '\'')
911 && (!macro_alternate && in->ptr[scan] != '='))
912 scan++;
913 if (scan < in->len && !macro_alternate && in->ptr[scan] == '=')
915 is_keyword = 1;
917 /* It's OK to go from positional to keyword. */
919 /* This is a keyword arg, fetch the formal name and
920 then the actual stuff. */
921 sb_reset (&t);
922 idx = get_token (idx, in, &t);
923 if (in->ptr[idx] != '=')
924 return _("confusion in formal parameters");
926 /* Lookup the formal in the macro's list. */
927 ptr = (formal_entry *) hash_find (m->formal_hash, sb_terminate (&t));
928 if (!ptr)
929 return _("macro formal argument does not exist");
930 else
932 /* Insert this value into the right place. */
933 sb_reset (&ptr->actual);
934 idx = get_any_string (idx + 1, in, &ptr->actual, 0, 0);
935 if (ptr->actual.len > 0)
936 ++narg;
939 else
941 /* This is a positional arg. */
942 is_positional = 1;
943 if (is_keyword)
944 return _("can't mix positional and keyword arguments");
946 if (!f)
948 formal_entry **pf;
949 int c;
951 if (!macro_mri)
952 return _("too many positional arguments");
954 f = (formal_entry *) xmalloc (sizeof (formal_entry));
955 sb_new (&f->name);
956 sb_new (&f->def);
957 sb_new (&f->actual);
958 f->next = NULL;
960 c = -1;
961 for (pf = &m->formals; *pf != NULL; pf = &(*pf)->next)
962 if ((*pf)->index >= c)
963 c = (*pf)->index + 1;
964 if (c == -1)
965 c = 0;
966 *pf = f;
967 f->index = c;
970 sb_reset (&f->actual);
971 idx = get_any_string (idx, in, &f->actual, 1, 0);
972 if (f->actual.len > 0)
973 ++narg;
976 f = f->next;
978 while (f != NULL && f->index < 0);
981 if (! macro_mri)
982 idx = sb_skip_comma (idx, in);
983 else
985 if (in->ptr[idx] == ',')
986 ++idx;
987 if (ISWHITE (in->ptr[idx]))
988 break;
992 if (macro_mri)
994 char buffer[20];
996 sb_reset (&t);
997 sb_add_string (&t, macro_strip_at ? "$NARG" : "NARG");
998 ptr = (formal_entry *) hash_find (m->formal_hash, sb_terminate (&t));
999 sb_reset (&ptr->actual);
1000 sprintf (buffer, "%d", narg);
1001 sb_add_string (&ptr->actual, buffer);
1004 err = macro_expand_body (&m->sub, out, m->formals, m->formal_hash, 1);
1005 if (err != NULL)
1006 return err;
1008 /* Discard any unnamed formal arguments. */
1009 if (macro_mri)
1011 formal_entry **pf;
1013 pf = &m->formals;
1014 while (*pf != NULL)
1016 if ((*pf)->name.len != 0)
1017 pf = &(*pf)->next;
1018 else
1020 sb_kill (&(*pf)->name);
1021 sb_kill (&(*pf)->def);
1022 sb_kill (&(*pf)->actual);
1023 f = (*pf)->next;
1024 free (*pf);
1025 *pf = f;
1030 sb_kill (&t);
1031 macro_number++;
1033 return NULL;
1036 /* Check for a macro. If one is found, put the expansion into
1037 *EXPAND. Return 1 if a macro is found, 0 otherwise. */
1040 check_macro (const char *line, sb *expand,
1041 const char **error, macro_entry **info)
1043 const char *s;
1044 char *copy, *cs;
1045 macro_entry *macro;
1046 sb line_sb;
1048 if (! ISALPHA (*line)
1049 && *line != '_'
1050 && *line != '$'
1051 && (! macro_mri || *line != '.'))
1052 return 0;
1054 s = line + 1;
1055 while (ISALNUM (*s)
1056 || *s == '_'
1057 || *s == '$')
1058 ++s;
1060 copy = (char *) alloca (s - line + 1);
1061 memcpy (copy, line, s - line);
1062 copy[s - line] = '\0';
1063 for (cs = copy; *cs != '\0'; cs++)
1064 *cs = TOLOWER (*cs);
1066 macro = (macro_entry *) hash_find (macro_hash, copy);
1068 if (macro == NULL)
1069 return 0;
1071 /* Wrap the line up in an sb. */
1072 sb_new (&line_sb);
1073 while (*s != '\0' && *s != '\n' && *s != '\r')
1074 sb_add_char (&line_sb, *s++);
1076 sb_new (expand);
1077 *error = macro_expand (0, &line_sb, macro, expand);
1079 sb_kill (&line_sb);
1081 /* Export the macro information if requested. */
1082 if (info)
1083 *info = macro;
1085 return 1;
1088 /* Delete a macro. */
1090 void
1091 delete_macro (const char *name)
1093 hash_delete (macro_hash, name);
1096 /* Handle the MRI IRP and IRPC pseudo-ops. These are handled as a
1097 combined macro definition and execution. This returns NULL on
1098 success, or an error message otherwise. */
1100 const char *
1101 expand_irp (int irpc, int idx, sb *in, sb *out, int (*get_line) (sb *))
1103 const char *mn;
1104 sb sub;
1105 formal_entry f;
1106 struct hash_control *h;
1107 const char *err;
1109 if (irpc)
1110 mn = "IRPC";
1111 else
1112 mn = "IRP";
1114 idx = sb_skip_white (idx, in);
1116 sb_new (&sub);
1117 if (! buffer_and_nest (mn, "ENDR", &sub, get_line))
1118 return _("unexpected end of file in irp or irpc");
1120 sb_new (&f.name);
1121 sb_new (&f.def);
1122 sb_new (&f.actual);
1124 idx = get_token (idx, in, &f.name);
1125 if (f.name.len == 0)
1126 return _("missing model parameter");
1128 h = hash_new ();
1129 err = hash_jam (h, sb_terminate (&f.name), &f);
1130 if (err != NULL)
1131 return err;
1133 f.index = 1;
1134 f.next = NULL;
1136 sb_reset (out);
1138 idx = sb_skip_comma (idx, in);
1139 if (idx >= in->len)
1141 /* Expand once with a null string. */
1142 err = macro_expand_body (&sub, out, &f, h, 0);
1143 if (err != NULL)
1144 return err;
1146 else
1148 if (irpc && in->ptr[idx] == '"')
1149 ++idx;
1150 while (idx < in->len)
1152 if (!irpc)
1153 idx = get_any_string (idx, in, &f.actual, 1, 0);
1154 else
1156 if (in->ptr[idx] == '"')
1158 int nxt;
1160 nxt = sb_skip_white (idx + 1, in);
1161 if (nxt >= in->len)
1163 idx = nxt;
1164 break;
1167 sb_reset (&f.actual);
1168 sb_add_char (&f.actual, in->ptr[idx]);
1169 ++idx;
1171 err = macro_expand_body (&sub, out, &f, h, 0);
1172 if (err != NULL)
1173 return err;
1174 if (!irpc)
1175 idx = sb_skip_comma (idx, in);
1176 else
1177 idx = sb_skip_white (idx, in);
1181 hash_die (h);
1182 sb_kill (&sub);
1184 return NULL;