2000-02-27 Thomas de Lellis <tdel@windriver.com>
[binutils.git] / gas / macro.c
blob7407f1d11495a3a57895408571ab11a14a630432
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,
5 sac@cygnus.com
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)
12 any later version.
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
22 02111-1307, USA. */
24 #include "config.h"
26 /* AIX requires this to be the first thing in the file. */
27 #ifdef __GNUC__
28 # ifndef alloca
29 # ifdef __STDC__
30 extern void *alloca ();
31 # else
32 extern char *alloca ();
33 # endif
34 # endif
35 #else
36 # if HAVE_ALLOCA_H
37 # include <alloca.h>
38 # else
39 # ifdef _AIX
40 #pragma alloca
41 # else
42 # ifndef alloca /* predefined by HP cc +Olibcalls */
43 # if !defined (__STDC__) && !defined (__hpux)
44 extern char *alloca ();
45 # else
46 extern void *alloca ();
47 # endif /* __STDC__, __hpux */
48 # endif /* alloca */
49 # endif /* _AIX */
50 # endif /* HAVE_ALLOCA_H */
51 #endif
53 #include <stdio.h>
54 #ifdef HAVE_STRING_H
55 #include <string.h>
56 #else
57 #include <strings.h>
58 #endif
59 #include <ctype.h>
60 #ifdef HAVE_STDLIB_H
61 #include <stdlib.h>
62 #endif
63 #include "libiberty.h"
64 #include "sb.h"
65 #include "hash.h"
66 #include "macro.h"
68 #include "asintl.h"
70 /* The routines in this file handle macro definition and expansion.
71 They are called by both gasp and gas. */
73 /* Structures used to store macros.
75 Each macro knows its name and included text. It gets built with a
76 list of formal arguments, and also keeps a hash table which points
77 into the list to speed up formal search. Each formal knows its
78 name and its default value. Each time the macro is expanded, the
79 formals get the actual values attatched to them. */
81 /* describe the formal arguments to a macro */
83 typedef struct formal_struct
85 struct formal_struct *next; /* next formal in list */
86 sb name; /* name of the formal */
87 sb def; /* the default value */
88 sb actual; /* the actual argument (changed on each expansion) */
89 int index; /* the index of the formal 0..formal_count-1 */
91 formal_entry;
93 /* Other values found in the index field of a formal_entry. */
94 #define QUAL_INDEX (-1)
95 #define NARG_INDEX (-2)
96 #define LOCAL_INDEX (-3)
98 /* describe the macro. */
100 typedef struct macro_struct
102 sb sub; /* substitution text. */
103 int formal_count; /* number of formal args. */
104 formal_entry *formals; /* pointer to list of formal_structs */
105 struct hash_control *formal_hash; /* hash table of formals. */
107 macro_entry;
109 /* Internal functions. */
111 static int get_token PARAMS ((int, sb *, sb *));
112 static int getstring PARAMS ((int, sb *, sb *));
113 static int get_any_string PARAMS ((int, sb *, sb *, int, int));
114 static int do_formals PARAMS ((macro_entry *, int, sb *));
115 static int get_apost_token PARAMS ((int, sb *, sb *, int));
116 static int sub_actual
117 PARAMS ((int, sb *, sb *, struct hash_control *, int, sb *, int));
118 static const char *macro_expand_body
119 PARAMS ((sb *, sb *, formal_entry *, struct hash_control *, int, int));
120 static const char *macro_expand PARAMS ((int, sb *, macro_entry *, sb *, int));
122 #define ISWHITE(x) ((x) == ' ' || (x) == '\t')
124 #define ISSEP(x) \
125 ((x) == ' ' || (x) == '\t' || (x) == ',' || (x) == '"' || (x) == ';' \
126 || (x) == ')' || (x) == '(' \
127 || ((macro_alternate || macro_mri) && ((x) == '<' || (x) == '>')))
129 #define ISBASE(x) \
130 ((x) == 'b' || (x) == 'B' \
131 || (x) == 'q' || (x) == 'Q' \
132 || (x) == 'h' || (x) == 'H' \
133 || (x) == 'd' || (x) == 'D')
135 /* The macro hash table. */
137 static struct hash_control *macro_hash;
139 /* Whether any macros have been defined. */
141 int macro_defined;
143 /* Whether we are in GASP alternate mode. */
145 static int macro_alternate;
147 /* Whether we are in MRI mode. */
149 static int macro_mri;
151 /* Whether we should strip '@' characters. */
153 static int macro_strip_at;
155 /* Function to use to parse an expression. */
157 static int (*macro_expr) PARAMS ((const char *, int, sb *, int *));
159 /* Number of macro expansions that have been done. */
161 static int macro_number;
163 /* Initialize macro processing. */
165 void
166 macro_init (alternate, mri, strip_at, expr)
167 int alternate;
168 int mri;
169 int strip_at;
170 int (*expr) PARAMS ((const char *, int, sb *, int *));
172 macro_hash = hash_new ();
173 macro_defined = 0;
174 macro_alternate = alternate;
175 macro_mri = mri;
176 macro_strip_at = strip_at;
177 macro_expr = expr;
180 /* Switch in and out of MRI mode on the fly. */
182 void
183 macro_mri_mode (mri)
184 int mri;
186 macro_mri = mri;
189 /* Read input lines till we get to a TO string.
190 Increase nesting depth if we get a FROM string.
191 Put the results into sb at PTR.
192 Add a new input line to an sb using GET_LINE.
193 Return 1 on success, 0 on unexpected EOF. */
196 buffer_and_nest (from, to, ptr, get_line)
197 const char *from;
198 const char *to;
199 sb *ptr;
200 int (*get_line) PARAMS ((sb *));
202 int from_len = strlen (from);
203 int to_len = strlen (to);
204 int depth = 1;
205 int line_start = ptr->len;
207 int more = get_line (ptr);
209 while (more)
211 /* Try and find the first pseudo op on the line */
212 int i = line_start;
214 if (! macro_alternate && ! macro_mri)
216 /* With normal syntax we can suck what we want till we get
217 to the dot. With the alternate, labels have to start in
218 the first column, since we cant tell what's a label and
219 whats a pseudoop */
221 /* Skip leading whitespace */
222 while (i < ptr->len && ISWHITE (ptr->ptr[i]))
223 i++;
225 /* Skip over a label */
226 while (i < ptr->len
227 && (isalnum ((unsigned char) ptr->ptr[i])
228 || ptr->ptr[i] == '_'
229 || ptr->ptr[i] == '$'))
230 i++;
232 /* And a colon */
233 if (i < ptr->len
234 && ptr->ptr[i] == ':')
235 i++;
238 /* Skip trailing whitespace */
239 while (i < ptr->len && ISWHITE (ptr->ptr[i]))
240 i++;
242 if (i < ptr->len && (ptr->ptr[i] == '.'
243 || macro_alternate
244 || macro_mri))
246 if (ptr->ptr[i] == '.')
247 i++;
248 if (strncasecmp (ptr->ptr + i, from, from_len) == 0
249 && (ptr->len == (i + from_len) || ! isalnum (ptr->ptr[i + from_len])))
250 depth++;
251 if (strncasecmp (ptr->ptr + i, to, to_len) == 0
252 && (ptr->len == (i + to_len) || ! isalnum (ptr->ptr[i + to_len])))
254 depth--;
255 if (depth == 0)
257 /* Reset the string to not include the ending rune */
258 ptr->len = line_start;
259 break;
264 /* Add a CR to the end and keep running */
265 sb_add_char (ptr, '\n');
266 line_start = ptr->len;
267 more = get_line (ptr);
270 /* Return 1 on success, 0 on unexpected EOF. */
271 return depth == 0;
274 /* Pick up a token. */
276 static int
277 get_token (idx, in, name)
278 int idx;
279 sb *in;
280 sb *name;
282 if (idx < in->len
283 && (isalpha ((unsigned char) in->ptr[idx])
284 || in->ptr[idx] == '_'
285 || in->ptr[idx] == '$'))
287 sb_add_char (name, in->ptr[idx++]);
288 while (idx < in->len
289 && (isalnum ((unsigned char) in->ptr[idx])
290 || in->ptr[idx] == '_'
291 || in->ptr[idx] == '$'))
293 sb_add_char (name, in->ptr[idx++]);
296 /* Ignore trailing & */
297 if (macro_alternate && idx < in->len && in->ptr[idx] == '&')
298 idx++;
299 return idx;
302 /* Pick up a string. */
304 static int
305 getstring (idx, in, acc)
306 int idx;
307 sb *in;
308 sb *acc;
310 idx = sb_skip_white (idx, in);
312 while (idx < in->len
313 && (in->ptr[idx] == '"'
314 || (in->ptr[idx] == '<' && (macro_alternate || macro_mri))
315 || (in->ptr[idx] == '\'' && macro_alternate)))
317 if (in->ptr[idx] == '<')
319 int nest = 0;
320 idx++;
321 while ((in->ptr[idx] != '>' || nest)
322 && idx < in->len)
324 if (in->ptr[idx] == '!')
326 idx++ ;
327 sb_add_char (acc, in->ptr[idx++]);
329 else
331 if (in->ptr[idx] == '>')
332 nest--;
333 if (in->ptr[idx] == '<')
334 nest++;
335 sb_add_char (acc, in->ptr[idx++]);
338 idx++;
340 else if (in->ptr[idx] == '"' || in->ptr[idx] == '\'')
342 char tchar = in->ptr[idx];
343 idx++;
344 while (idx < in->len)
346 if (macro_alternate && in->ptr[idx] == '!')
348 idx++ ;
349 sb_add_char (acc, in->ptr[idx++]);
351 else
353 if (in->ptr[idx] == tchar)
355 idx++;
356 if (idx >= in->len || in->ptr[idx] != tchar)
357 break;
359 sb_add_char (acc, in->ptr[idx]);
360 idx++;
366 return idx;
369 /* Fetch string from the input stream,
370 rules:
371 'Bxyx<whitespace> -> return 'Bxyza
372 %<char> -> return string of decimal value of x
373 "<string>" -> return string
374 xyx<whitespace> -> return xyz
377 static int
378 get_any_string (idx, in, out, expand, pretend_quoted)
379 int idx;
380 sb *in;
381 sb *out;
382 int expand;
383 int pretend_quoted;
385 sb_reset (out);
386 idx = sb_skip_white (idx, in);
388 if (idx < in->len)
390 if (in->len > 2 && in->ptr[idx+1] == '\'' && ISBASE (in->ptr[idx]))
392 while (!ISSEP (in->ptr[idx]))
393 sb_add_char (out, in->ptr[idx++]);
395 else if (in->ptr[idx] == '%'
396 && macro_alternate
397 && expand)
399 int val;
400 char buf[20];
401 /* Turns the next expression into a string */
402 idx = (*macro_expr) (_("% operator needs absolute expression"),
403 idx + 1,
405 &val);
406 sprintf(buf, "%d", val);
407 sb_add_string (out, buf);
409 else if (in->ptr[idx] == '"'
410 || (in->ptr[idx] == '<' && (macro_alternate || macro_mri))
411 || (macro_alternate && in->ptr[idx] == '\''))
413 if (macro_alternate
414 && ! macro_strip_at
415 && expand)
417 /* Keep the quotes */
418 sb_add_char (out, '\"');
420 idx = getstring (idx, in, out);
421 sb_add_char (out, '\"');
423 else
425 idx = getstring (idx, in, out);
428 else
430 while (idx < in->len
431 && (in->ptr[idx] == '"'
432 || in->ptr[idx] == '\''
433 || pretend_quoted
434 || (in->ptr[idx] != ' '
435 && in->ptr[idx] != '\t'
436 && in->ptr[idx] != ','
437 && (in->ptr[idx] != '<'
438 || (! macro_alternate && ! macro_mri)))))
440 if (in->ptr[idx] == '"'
441 || in->ptr[idx] == '\'')
443 char tchar = in->ptr[idx];
444 sb_add_char (out, in->ptr[idx++]);
445 while (idx < in->len
446 && in->ptr[idx] != tchar)
447 sb_add_char (out, in->ptr[idx++]);
448 if (idx == in->len)
449 return idx;
451 sb_add_char (out, in->ptr[idx++]);
456 return idx;
459 /* Pick up the formal parameters of a macro definition. */
461 static int
462 do_formals (macro, idx, in)
463 macro_entry *macro;
464 int idx;
465 sb *in;
467 formal_entry **p = &macro->formals;
469 macro->formal_count = 0;
470 macro->formal_hash = hash_new ();
471 while (idx < in->len)
473 formal_entry *formal;
475 formal = (formal_entry *) xmalloc (sizeof (formal_entry));
477 sb_new (&formal->name);
478 sb_new (&formal->def);
479 sb_new (&formal->actual);
481 idx = sb_skip_white (idx, in);
482 idx = get_token (idx, in, &formal->name);
483 if (formal->name.len == 0)
484 break;
485 idx = sb_skip_white (idx, in);
486 if (formal->name.len)
488 /* This is a formal */
489 if (idx < in->len && in->ptr[idx] == '=')
491 /* Got a default */
492 idx = get_any_string (idx + 1, in, &formal->def, 1, 0);
496 /* Add to macro's hash table */
497 hash_jam (macro->formal_hash, sb_terminate (&formal->name), formal);
499 formal->index = macro->formal_count;
500 idx = sb_skip_comma (idx, in);
501 macro->formal_count++;
502 *p = formal;
503 p = &formal->next;
504 *p = NULL;
507 if (macro_mri)
509 formal_entry *formal;
510 const char *name;
512 /* Add a special NARG formal, which macro_expand will set to the
513 number of arguments. */
514 formal = (formal_entry *) xmalloc (sizeof (formal_entry));
516 sb_new (&formal->name);
517 sb_new (&formal->def);
518 sb_new (&formal->actual);
520 /* The same MRI assemblers which treat '@' characters also use
521 the name $NARG. At least until we find an exception. */
522 if (macro_strip_at)
523 name = "$NARG";
524 else
525 name = "NARG";
527 sb_add_string (&formal->name, name);
529 /* Add to macro's hash table */
530 hash_jam (macro->formal_hash, name, formal);
532 formal->index = NARG_INDEX;
533 *p = formal;
534 formal->next = NULL;
537 return idx;
540 /* Define a new macro. Returns NULL on success, otherwise returns an
541 error message. If NAMEP is not NULL, *NAMEP is set to the name of
542 the macro which was defined. */
544 const char *
545 define_macro (idx, in, label, get_line, namep)
546 int idx;
547 sb *in;
548 sb *label;
549 int (*get_line) PARAMS ((sb *));
550 const char **namep;
552 macro_entry *macro;
553 sb name;
554 const char *namestr;
556 macro = (macro_entry *) xmalloc (sizeof (macro_entry));
557 sb_new (&macro->sub);
558 sb_new (&name);
560 macro->formal_count = 0;
561 macro->formals = 0;
563 idx = sb_skip_white (idx, in);
564 if (! buffer_and_nest ("MACRO", "ENDM", &macro->sub, get_line))
565 return _("unexpected end of file in macro definition");
566 if (label != NULL && label->len != 0)
568 sb_add_sb (&name, label);
569 if (idx < in->len && in->ptr[idx] == '(')
571 /* It's the label: MACRO (formals,...) sort */
572 idx = do_formals (macro, idx + 1, in);
573 if (in->ptr[idx] != ')')
574 return _("missing ) after formals");
576 else
578 /* It's the label: MACRO formals,... sort */
579 idx = do_formals (macro, idx, in);
582 else
584 idx = get_token (idx, in, &name);
585 idx = sb_skip_comma (idx, in);
586 idx = do_formals (macro, idx, in);
589 /* and stick it in the macro hash table */
590 for (idx = 0; idx < name.len; idx++)
591 if (isupper ((unsigned char) name.ptr[idx]))
592 name.ptr[idx] = tolower (name.ptr[idx]);
593 namestr = sb_terminate (&name);
594 hash_jam (macro_hash, namestr, (PTR) macro);
596 macro_defined = 1;
598 if (namep != NULL)
599 *namep = namestr;
601 return NULL;
604 /* Scan a token, and then skip KIND. */
606 static int
607 get_apost_token (idx, in, name, kind)
608 int idx;
609 sb *in;
610 sb *name;
611 int kind;
613 idx = get_token (idx, in, name);
614 if (idx < in->len
615 && in->ptr[idx] == kind
616 && (! macro_mri || macro_strip_at)
617 && (! macro_strip_at || kind == '@'))
618 idx++;
619 return idx;
622 /* Substitute the actual value for a formal parameter. */
624 static int
625 sub_actual (start, in, t, formal_hash, kind, out, copyifnotthere)
626 int start;
627 sb *in;
628 sb *t;
629 struct hash_control *formal_hash;
630 int kind;
631 sb *out;
632 int copyifnotthere;
634 int src;
635 formal_entry *ptr;
637 src = get_apost_token (start, in, t, kind);
638 /* See if it's in the macro's hash table, unless this is
639 macro_strip_at and kind is '@' and the token did not end in '@'. */
640 if (macro_strip_at
641 && kind == '@'
642 && (src == start || in->ptr[src - 1] != '@'))
643 ptr = NULL;
644 else
645 ptr = (formal_entry *) hash_find (formal_hash, sb_terminate (t));
646 if (ptr)
648 if (ptr->actual.len)
650 sb_add_sb (out, &ptr->actual);
652 else
654 sb_add_sb (out, &ptr->def);
657 else if (kind == '&')
659 /* Doing this permits people to use & in macro bodies. */
660 sb_add_char (out, '&');
662 else if (copyifnotthere)
664 sb_add_sb (out, t);
666 else
668 sb_add_char (out, '\\');
669 sb_add_sb (out, t);
671 return src;
674 /* Expand the body of a macro. */
676 static const char *
677 macro_expand_body (in, out, formals, formal_hash, comment_char, locals)
678 sb *in;
679 sb *out;
680 formal_entry *formals;
681 struct hash_control *formal_hash;
682 int comment_char;
683 int locals;
685 sb t;
686 int src = 0;
687 int inquote = 0;
688 formal_entry *loclist = NULL;
690 sb_new (&t);
692 while (src < in->len)
694 if (in->ptr[src] == '&')
696 sb_reset (&t);
697 if (macro_mri)
699 if (src + 1 < in->len && in->ptr[src + 1] == '&')
700 src = sub_actual (src + 2, in, &t, formal_hash, '\'', out, 1);
701 else
702 sb_add_char (out, in->ptr[src++]);
704 else
706 /* FIXME: Why do we do this? */
707 src = sub_actual (src + 1, in, &t, formal_hash, '&', out, 0);
710 else if (in->ptr[src] == '\\')
712 src++;
713 if (in->ptr[src] == comment_char && comment_char != '\0')
715 /* This is a comment, just drop the rest of the line */
716 while (src < in->len
717 && in->ptr[src] != '\n')
718 src++;
720 else if (in->ptr[src] == '(')
722 /* Sub in till the next ')' literally */
723 src++;
724 while (src < in->len && in->ptr[src] != ')')
726 sb_add_char (out, in->ptr[src++]);
728 if (in->ptr[src] == ')')
729 src++;
730 else
731 return _("missplaced )");
733 else if (in->ptr[src] == '@')
735 /* Sub in the macro invocation number */
737 char buffer[10];
738 src++;
739 sprintf (buffer, "%05d", macro_number);
740 sb_add_string (out, buffer);
742 else if (in->ptr[src] == '&')
744 /* This is a preprocessor variable name, we don't do them
745 here */
746 sb_add_char (out, '\\');
747 sb_add_char (out, '&');
748 src++;
750 else if (macro_mri
751 && isalnum ((unsigned char) in->ptr[src]))
753 int ind;
754 formal_entry *f;
756 if (isdigit ((unsigned char) in->ptr[src]))
757 ind = in->ptr[src] - '0';
758 else if (isupper ((unsigned char) in->ptr[src]))
759 ind = in->ptr[src] - 'A' + 10;
760 else
761 ind = in->ptr[src] - 'a' + 10;
762 ++src;
763 for (f = formals; f != NULL; f = f->next)
765 if (f->index == ind - 1)
767 if (f->actual.len != 0)
768 sb_add_sb (out, &f->actual);
769 else
770 sb_add_sb (out, &f->def);
771 break;
775 else
777 sb_reset (&t);
778 src = sub_actual (src, in, &t, formal_hash, '\'', out, 0);
781 else if ((macro_alternate || macro_mri)
782 && (isalpha ((unsigned char) in->ptr[src])
783 || in->ptr[src] == '_'
784 || in->ptr[src] == '$')
785 && (! inquote
786 || ! macro_strip_at
787 || (src > 0 && in->ptr[src - 1] == '@')))
789 if (! locals
790 || src + 5 >= in->len
791 || strncasecmp (in->ptr + src, "LOCAL", 5) != 0
792 || ! ISWHITE (in->ptr[src + 5]))
794 sb_reset (&t);
795 src = sub_actual (src, in, &t, formal_hash,
796 (macro_strip_at && inquote) ? '@' : '\'',
797 out, 1);
799 else
801 formal_entry *f;
803 src = sb_skip_white (src + 5, in);
804 while (in->ptr[src] != '\n' && in->ptr[src] != comment_char)
806 static int loccnt;
807 char buf[20];
808 const char *err;
810 f = (formal_entry *) xmalloc (sizeof (formal_entry));
811 sb_new (&f->name);
812 sb_new (&f->def);
813 sb_new (&f->actual);
814 f->index = LOCAL_INDEX;
815 f->next = loclist;
816 loclist = f;
818 src = get_token (src, in, &f->name);
819 ++loccnt;
820 sprintf (buf, "LL%04x", loccnt);
821 sb_add_string (&f->actual, buf);
823 err = hash_jam (formal_hash, sb_terminate (&f->name), f);
824 if (err != NULL)
825 return err;
827 src = sb_skip_comma (src, in);
831 else if (comment_char != '\0'
832 && in->ptr[src] == comment_char
833 && src + 1 < in->len
834 && in->ptr[src + 1] == comment_char
835 && !inquote)
837 /* Two comment chars in a row cause the rest of the line to
838 be dropped. */
839 while (src < in->len && in->ptr[src] != '\n')
840 src++;
842 else if (in->ptr[src] == '"'
843 || (macro_mri && in->ptr[src] == '\''))
845 inquote = !inquote;
846 sb_add_char (out, in->ptr[src++]);
848 else if (in->ptr[src] == '@' && macro_strip_at)
850 ++src;
851 if (src < in->len
852 && in->ptr[src] == '@')
854 sb_add_char (out, '@');
855 ++src;
858 else if (macro_mri
859 && in->ptr[src] == '='
860 && src + 1 < in->len
861 && in->ptr[src + 1] == '=')
863 formal_entry *ptr;
865 sb_reset (&t);
866 src = get_token (src + 2, in, &t);
867 ptr = (formal_entry *) hash_find (formal_hash, sb_terminate (&t));
868 if (ptr == NULL)
870 /* FIXME: We should really return a warning string here,
871 but we can't, because the == might be in the MRI
872 comment field, and, since the nature of the MRI
873 comment field depends upon the exact instruction
874 being used, we don't have enough information here to
875 figure out whether it is or not. Instead, we leave
876 the == in place, which should cause a syntax error if
877 it is not in a comment. */
878 sb_add_char (out, '=');
879 sb_add_char (out, '=');
880 sb_add_sb (out, &t);
882 else
884 if (ptr->actual.len)
886 sb_add_string (out, "-1");
888 else
890 sb_add_char (out, '0');
894 else
896 sb_add_char (out, in->ptr[src++]);
900 sb_kill (&t);
902 while (loclist != NULL)
904 formal_entry *f;
906 f = loclist->next;
907 /* Setting the value to NULL effectively deletes the entry. We
908 avoid calling hash_delete because it doesn't reclaim memory. */
909 hash_jam (formal_hash, sb_terminate (&loclist->name), NULL);
910 sb_kill (&loclist->name);
911 sb_kill (&loclist->def);
912 sb_kill (&loclist->actual);
913 free (loclist);
914 loclist = f;
917 return NULL;
920 /* Assign values to the formal parameters of a macro, and expand the
921 body. */
923 static const char *
924 macro_expand (idx, in, m, out, comment_char)
925 int idx;
926 sb *in;
927 macro_entry *m;
928 sb *out;
929 int comment_char;
931 sb t;
932 formal_entry *ptr;
933 formal_entry *f;
934 int is_positional = 0;
935 int is_keyword = 0;
936 int narg = 0;
937 const char *err;
939 sb_new (&t);
941 /* Reset any old value the actuals may have */
942 for (f = m->formals; f; f = f->next)
943 sb_reset (&f->actual);
944 f = m->formals;
945 while (f != NULL && f->index < 0)
946 f = f->next;
948 if (macro_mri)
950 /* The macro may be called with an optional qualifier, which may
951 be referred to in the macro body as \0. */
952 if (idx < in->len && in->ptr[idx] == '.')
954 formal_entry *n;
956 n = (formal_entry *) xmalloc (sizeof (formal_entry));
957 sb_new (&n->name);
958 sb_new (&n->def);
959 sb_new (&n->actual);
960 n->index = QUAL_INDEX;
962 n->next = m->formals;
963 m->formals = n;
965 idx = get_any_string (idx + 1, in, &n->actual, 1, 0);
969 /* Peel off the actuals and store them away in the hash tables' actuals */
970 idx = sb_skip_white (idx, in);
971 while (idx < in->len && in->ptr[idx] != comment_char)
973 int scan;
975 /* Look and see if it's a positional or keyword arg */
976 scan = idx;
977 while (scan < in->len
978 && !ISSEP (in->ptr[scan])
979 && !(macro_mri && in->ptr[scan] == '\'')
980 && (!macro_alternate && in->ptr[scan] != '='))
981 scan++;
982 if (scan < in->len && !macro_alternate && in->ptr[scan] == '=')
984 is_keyword = 1;
986 /* It's OK to go from positional to keyword. */
988 /* This is a keyword arg, fetch the formal name and
989 then the actual stuff */
990 sb_reset (&t);
991 idx = get_token (idx, in, &t);
992 if (in->ptr[idx] != '=')
993 return _("confusion in formal parameters");
995 /* Lookup the formal in the macro's list */
996 ptr = (formal_entry *) hash_find (m->formal_hash, sb_terminate (&t));
997 if (!ptr)
998 return _("macro formal argument does not exist");
999 else
1001 /* Insert this value into the right place */
1002 sb_reset (&ptr->actual);
1003 idx = get_any_string (idx + 1, in, &ptr->actual, 0, 0);
1004 if (ptr->actual.len > 0)
1005 ++narg;
1008 else
1010 /* This is a positional arg */
1011 is_positional = 1;
1012 if (is_keyword)
1013 return _("can't mix positional and keyword arguments");
1015 if (!f)
1017 formal_entry **pf;
1018 int c;
1020 if (!macro_mri)
1021 return _("too many positional arguments");
1023 f = (formal_entry *) xmalloc (sizeof (formal_entry));
1024 sb_new (&f->name);
1025 sb_new (&f->def);
1026 sb_new (&f->actual);
1027 f->next = NULL;
1029 c = -1;
1030 for (pf = &m->formals; *pf != NULL; pf = &(*pf)->next)
1031 if ((*pf)->index >= c)
1032 c = (*pf)->index + 1;
1033 if (c == -1)
1034 c = 0;
1035 *pf = f;
1036 f->index = c;
1039 sb_reset (&f->actual);
1040 idx = get_any_string (idx, in, &f->actual, 1, 0);
1041 if (f->actual.len > 0)
1042 ++narg;
1045 f = f->next;
1047 while (f != NULL && f->index < 0);
1050 if (! macro_mri)
1051 idx = sb_skip_comma (idx, in);
1052 else
1054 if (in->ptr[idx] == ',')
1055 ++idx;
1056 if (ISWHITE (in->ptr[idx]))
1057 break;
1061 if (macro_mri)
1063 char buffer[20];
1065 sb_reset (&t);
1066 sb_add_string (&t, macro_strip_at ? "$NARG" : "NARG");
1067 ptr = (formal_entry *) hash_find (m->formal_hash, sb_terminate (&t));
1068 sb_reset (&ptr->actual);
1069 sprintf (buffer, "%d", narg);
1070 sb_add_string (&ptr->actual, buffer);
1073 err = macro_expand_body (&m->sub, out, m->formals, m->formal_hash,
1074 comment_char, 1);
1075 if (err != NULL)
1076 return err;
1078 /* Discard any unnamed formal arguments. */
1079 if (macro_mri)
1081 formal_entry **pf;
1083 pf = &m->formals;
1084 while (*pf != NULL)
1086 if ((*pf)->name.len != 0)
1087 pf = &(*pf)->next;
1088 else
1090 sb_kill (&(*pf)->name);
1091 sb_kill (&(*pf)->def);
1092 sb_kill (&(*pf)->actual);
1093 f = (*pf)->next;
1094 free (*pf);
1095 *pf = f;
1100 sb_kill (&t);
1101 macro_number++;
1103 return NULL;
1106 /* Check for a macro. If one is found, put the expansion into
1107 *EXPAND. COMMENT_CHAR is the comment character--this is used by
1108 gasp. Return 1 if a macro is found, 0 otherwise. */
1111 check_macro (line, expand, comment_char, error)
1112 const char *line;
1113 sb *expand;
1114 int comment_char;
1115 const char **error;
1117 const char *s;
1118 char *copy, *cs;
1119 macro_entry *macro;
1120 sb line_sb;
1122 if (! isalpha ((unsigned char) *line)
1123 && *line != '_'
1124 && *line != '$'
1125 && (! macro_mri || *line != '.'))
1126 return 0;
1128 s = line + 1;
1129 while (isalnum ((unsigned char) *s)
1130 || *s == '_'
1131 || *s == '$')
1132 ++s;
1134 copy = (char *) alloca (s - line + 1);
1135 memcpy (copy, line, s - line);
1136 copy[s - line] = '\0';
1137 for (cs = copy; *cs != '\0'; cs++)
1138 if (isupper ((unsigned char) *cs))
1139 *cs = tolower (*cs);
1141 macro = (macro_entry *) hash_find (macro_hash, copy);
1143 if (macro == NULL)
1144 return 0;
1146 /* Wrap the line up in an sb. */
1147 sb_new (&line_sb);
1148 while (*s != '\0' && *s != '\n' && *s != '\r')
1149 sb_add_char (&line_sb, *s++);
1151 sb_new (expand);
1152 *error = macro_expand (0, &line_sb, macro, expand, comment_char);
1154 sb_kill (&line_sb);
1156 return 1;
1159 /* Delete a macro. */
1161 void
1162 delete_macro (name)
1163 const char *name;
1165 hash_delete (macro_hash, name);
1168 /* Handle the MRI IRP and IRPC pseudo-ops. These are handled as a
1169 combined macro definition and execution. This returns NULL on
1170 success, or an error message otherwise. */
1172 const char *
1173 expand_irp (irpc, idx, in, out, get_line, comment_char)
1174 int irpc;
1175 int idx;
1176 sb *in;
1177 sb *out;
1178 int (*get_line) PARAMS ((sb *));
1179 int comment_char;
1181 const char *mn;
1182 sb sub;
1183 formal_entry f;
1184 struct hash_control *h;
1185 const char *err;
1187 if (irpc)
1188 mn = "IRPC";
1189 else
1190 mn = "IRP";
1192 idx = sb_skip_white (idx, in);
1194 sb_new (&sub);
1195 if (! buffer_and_nest (mn, "ENDR", &sub, get_line))
1196 return _("unexpected end of file in irp or irpc");
1198 sb_new (&f.name);
1199 sb_new (&f.def);
1200 sb_new (&f.actual);
1202 idx = get_token (idx, in, &f.name);
1203 if (f.name.len == 0)
1204 return _("missing model parameter");
1206 h = hash_new ();
1207 err = hash_jam (h, sb_terminate (&f.name), &f);
1208 if (err != NULL)
1209 return err;
1211 f.index = 1;
1212 f.next = NULL;
1214 sb_reset (out);
1216 idx = sb_skip_comma (idx, in);
1217 if (idx >= in->len || in->ptr[idx] == comment_char)
1219 /* Expand once with a null string. */
1220 err = macro_expand_body (&sub, out, &f, h, comment_char, 0);
1221 if (err != NULL)
1222 return err;
1224 else
1226 if (irpc && in->ptr[idx] == '"')
1227 ++idx;
1228 while (idx < in->len && in->ptr[idx] != comment_char)
1230 if (!irpc)
1231 idx = get_any_string (idx, in, &f.actual, 1, 0);
1232 else
1234 if (in->ptr[idx] == '"')
1236 int nxt;
1238 nxt = sb_skip_white (idx + 1, in);
1239 if (nxt >= in->len || in->ptr[nxt] == comment_char)
1241 idx = nxt;
1242 break;
1245 sb_reset (&f.actual);
1246 sb_add_char (&f.actual, in->ptr[idx]);
1247 ++idx;
1249 err = macro_expand_body (&sub, out, &f, h, comment_char, 0);
1250 if (err != NULL)
1251 return err;
1252 if (!irpc)
1253 idx = sb_skip_comma (idx, in);
1254 else
1255 idx = sb_skip_white (idx, in);
1259 hash_die (h);
1260 sb_kill (&sub);
1262 return NULL;