Import japanese translation from translation project.
[binutils.git] / gas / macro.c
blob3e03c5d68f1a8e30c3d349fcd79a2415d38ffd75
1 /* macro.c - macro support for gas and gasp
2 Copyright 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001
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 both gasp and gas. */
68 /* Internal functions. */
70 static int get_token PARAMS ((int, sb *, sb *));
71 static int getstring PARAMS ((int, sb *, sb *));
72 static int get_any_string PARAMS ((int, sb *, sb *, int, int));
73 static int do_formals PARAMS ((macro_entry *, int, sb *));
74 static int get_apost_token PARAMS ((int, sb *, sb *, int));
75 static int sub_actual
76 PARAMS ((int, sb *, sb *, struct hash_control *, int, sb *, int));
77 static const char *macro_expand_body
78 PARAMS ((sb *, sb *, formal_entry *, struct hash_control *, int, int));
79 static const char *macro_expand PARAMS ((int, sb *, macro_entry *, sb *, int));
81 #define ISWHITE(x) ((x) == ' ' || (x) == '\t')
83 #define ISSEP(x) \
84 ((x) == ' ' || (x) == '\t' || (x) == ',' || (x) == '"' || (x) == ';' \
85 || (x) == ')' || (x) == '(' \
86 || ((macro_alternate || macro_mri) && ((x) == '<' || (x) == '>')))
88 #define ISBASE(x) \
89 ((x) == 'b' || (x) == 'B' \
90 || (x) == 'q' || (x) == 'Q' \
91 || (x) == 'h' || (x) == 'H' \
92 || (x) == 'd' || (x) == 'D')
94 /* The macro hash table. */
96 static struct hash_control *macro_hash;
98 /* Whether any macros have been defined. */
100 int macro_defined;
102 /* Whether we are in GASP alternate mode. */
104 static int macro_alternate;
106 /* Whether we are in MRI mode. */
108 static int macro_mri;
110 /* Whether we should strip '@' characters. */
112 static int macro_strip_at;
114 /* Function to use to parse an expression. */
116 static int (*macro_expr) PARAMS ((const char *, int, sb *, int *));
118 /* Number of macro expansions that have been done. */
120 static int macro_number;
122 /* Initialize macro processing. */
124 void
125 macro_init (alternate, mri, strip_at, expr)
126 int alternate;
127 int mri;
128 int strip_at;
129 int (*expr) PARAMS ((const char *, int, sb *, int *));
131 macro_hash = hash_new ();
132 macro_defined = 0;
133 macro_alternate = alternate;
134 macro_mri = mri;
135 macro_strip_at = strip_at;
136 macro_expr = expr;
139 /* Switch in and out of MRI mode on the fly. */
141 void
142 macro_mri_mode (mri)
143 int mri;
145 macro_mri = mri;
148 /* Read input lines till we get to a TO string.
149 Increase nesting depth if we get a FROM string.
150 Put the results into sb at PTR.
151 Add a new input line to an sb using GET_LINE.
152 Return 1 on success, 0 on unexpected EOF. */
155 buffer_and_nest (from, to, ptr, get_line)
156 const char *from;
157 const char *to;
158 sb *ptr;
159 int (*get_line) PARAMS ((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 a CR to the end and keep running. */
226 sb_add_char (ptr, '\n');
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 (idx, in, name)
239 int idx;
240 sb *in;
241 sb *name;
243 if (idx < in->len
244 && (ISALPHA (in->ptr[idx])
245 || in->ptr[idx] == '_'
246 || in->ptr[idx] == '$'))
248 sb_add_char (name, in->ptr[idx++]);
249 while (idx < in->len
250 && (ISALNUM (in->ptr[idx])
251 || in->ptr[idx] == '_'
252 || in->ptr[idx] == '$'))
254 sb_add_char (name, in->ptr[idx++]);
257 /* Ignore trailing &. */
258 if (macro_alternate && idx < in->len && in->ptr[idx] == '&')
259 idx++;
260 return idx;
263 /* Pick up a string. */
265 static int
266 getstring (idx, in, acc)
267 int idx;
268 sb *in;
269 sb *acc;
271 idx = sb_skip_white (idx, in);
273 while (idx < in->len
274 && (in->ptr[idx] == '"'
275 || (in->ptr[idx] == '<' && (macro_alternate || macro_mri))
276 || (in->ptr[idx] == '\'' && macro_alternate)))
278 if (in->ptr[idx] == '<')
280 int nest = 0;
281 idx++;
282 while ((in->ptr[idx] != '>' || nest)
283 && idx < in->len)
285 if (in->ptr[idx] == '!')
287 idx++;
288 sb_add_char (acc, in->ptr[idx++]);
290 else
292 if (in->ptr[idx] == '>')
293 nest--;
294 if (in->ptr[idx] == '<')
295 nest++;
296 sb_add_char (acc, in->ptr[idx++]);
299 idx++;
301 else if (in->ptr[idx] == '"' || in->ptr[idx] == '\'')
303 char tchar = in->ptr[idx];
304 int escaped = 0;
306 idx++;
308 while (idx < in->len)
310 if (in->ptr[idx - 1] == '\\')
311 escaped ^= 1;
312 else
313 escaped = 0;
315 if (macro_alternate && in->ptr[idx] == '!')
317 idx ++;
319 sb_add_char (acc, in->ptr[idx]);
321 idx ++;
323 else if (escaped && in->ptr[idx] == tchar)
325 sb_add_char (acc, tchar);
326 idx ++;
328 else
330 if (in->ptr[idx] == tchar)
332 idx ++;
334 if (idx >= in->len || in->ptr[idx] != tchar)
335 break;
338 sb_add_char (acc, in->ptr[idx]);
339 idx ++;
345 return idx;
348 /* Fetch string from the input stream,
349 rules:
350 'Bxyx<whitespace> -> return 'Bxyza
351 %<char> -> return string of decimal value of x
352 "<string>" -> return string
353 xyx<whitespace> -> return xyz
356 static int
357 get_any_string (idx, in, out, expand, pretend_quoted)
358 int idx;
359 sb *in;
360 sb *out;
361 int expand;
362 int pretend_quoted;
364 sb_reset (out);
365 idx = sb_skip_white (idx, in);
367 if (idx < in->len)
369 if (in->len > 2 && in->ptr[idx + 1] == '\'' && ISBASE (in->ptr[idx]))
371 while (!ISSEP (in->ptr[idx]))
372 sb_add_char (out, in->ptr[idx++]);
374 else if (in->ptr[idx] == '%'
375 && macro_alternate
376 && expand)
378 int val;
379 char buf[20];
380 /* Turns the next expression into a string. */
381 idx = (*macro_expr) (_("% operator needs absolute expression"),
382 idx + 1,
384 &val);
385 sprintf(buf, "%d", val);
386 sb_add_string (out, buf);
388 else if (in->ptr[idx] == '"'
389 || (in->ptr[idx] == '<' && (macro_alternate || macro_mri))
390 || (macro_alternate && in->ptr[idx] == '\''))
392 if (macro_alternate
393 && ! macro_strip_at
394 && expand)
396 /* Keep the quotes. */
397 sb_add_char (out, '\"');
399 idx = getstring (idx, in, out);
400 sb_add_char (out, '\"');
402 else
404 idx = getstring (idx, in, out);
407 else
409 while (idx < in->len
410 && (in->ptr[idx] == '"'
411 || in->ptr[idx] == '\''
412 || pretend_quoted
413 || (in->ptr[idx] != ' '
414 && in->ptr[idx] != '\t'
415 && in->ptr[idx] != ','
416 && (in->ptr[idx] != '<'
417 || (! macro_alternate && ! macro_mri)))))
419 if (in->ptr[idx] == '"'
420 || in->ptr[idx] == '\'')
422 char tchar = in->ptr[idx];
423 sb_add_char (out, in->ptr[idx++]);
424 while (idx < in->len
425 && in->ptr[idx] != tchar)
426 sb_add_char (out, in->ptr[idx++]);
427 if (idx == in->len)
428 return idx;
430 sb_add_char (out, in->ptr[idx++]);
435 return idx;
438 /* Pick up the formal parameters of a macro definition. */
440 static int
441 do_formals (macro, idx, in)
442 macro_entry *macro;
443 int idx;
444 sb *in;
446 formal_entry **p = &macro->formals;
448 macro->formal_count = 0;
449 macro->formal_hash = hash_new ();
450 while (idx < in->len)
452 formal_entry *formal;
454 formal = (formal_entry *) xmalloc (sizeof (formal_entry));
456 sb_new (&formal->name);
457 sb_new (&formal->def);
458 sb_new (&formal->actual);
460 idx = sb_skip_white (idx, in);
461 idx = get_token (idx, in, &formal->name);
462 if (formal->name.len == 0)
463 break;
464 idx = sb_skip_white (idx, in);
465 if (formal->name.len)
467 /* This is a formal. */
468 if (idx < in->len && in->ptr[idx] == '=')
470 /* Got a default. */
471 idx = get_any_string (idx + 1, in, &formal->def, 1, 0);
475 /* Add to macro's hash table. */
476 hash_jam (macro->formal_hash, sb_terminate (&formal->name), formal);
478 formal->index = macro->formal_count;
479 idx = sb_skip_comma (idx, in);
480 macro->formal_count++;
481 *p = formal;
482 p = &formal->next;
483 *p = NULL;
486 if (macro_mri)
488 formal_entry *formal;
489 const char *name;
491 /* Add a special NARG formal, which macro_expand will set to the
492 number of arguments. */
493 formal = (formal_entry *) xmalloc (sizeof (formal_entry));
495 sb_new (&formal->name);
496 sb_new (&formal->def);
497 sb_new (&formal->actual);
499 /* The same MRI assemblers which treat '@' characters also use
500 the name $NARG. At least until we find an exception. */
501 if (macro_strip_at)
502 name = "$NARG";
503 else
504 name = "NARG";
506 sb_add_string (&formal->name, name);
508 /* Add to macro's hash table. */
509 hash_jam (macro->formal_hash, name, formal);
511 formal->index = NARG_INDEX;
512 *p = formal;
513 formal->next = NULL;
516 return idx;
519 /* Define a new macro. Returns NULL on success, otherwise returns an
520 error message. If NAMEP is not NULL, *NAMEP is set to the name of
521 the macro which was defined. */
523 const char *
524 define_macro (idx, in, label, get_line, namep)
525 int idx;
526 sb *in;
527 sb *label;
528 int (*get_line) PARAMS ((sb *));
529 const char **namep;
531 macro_entry *macro;
532 sb name;
533 const char *namestr;
535 macro = (macro_entry *) xmalloc (sizeof (macro_entry));
536 sb_new (&macro->sub);
537 sb_new (&name);
539 macro->formal_count = 0;
540 macro->formals = 0;
542 idx = sb_skip_white (idx, in);
543 if (! buffer_and_nest ("MACRO", "ENDM", &macro->sub, get_line))
544 return _("unexpected end of file in macro definition");
545 if (label != NULL && label->len != 0)
547 sb_add_sb (&name, label);
548 if (idx < in->len && in->ptr[idx] == '(')
550 /* It's the label: MACRO (formals,...) sort */
551 idx = do_formals (macro, idx + 1, in);
552 if (in->ptr[idx] != ')')
553 return _("missing ) after formals");
555 else
557 /* It's the label: MACRO formals,... sort */
558 idx = do_formals (macro, idx, in);
561 else
563 idx = get_token (idx, in, &name);
564 idx = sb_skip_comma (idx, in);
565 idx = do_formals (macro, idx, in);
568 /* And stick it in the macro hash table. */
569 for (idx = 0; idx < name.len; idx++)
570 name.ptr[idx] = TOLOWER (name.ptr[idx]);
571 namestr = sb_terminate (&name);
572 hash_jam (macro_hash, namestr, (PTR) macro);
574 macro_defined = 1;
576 if (namep != NULL)
577 *namep = namestr;
579 return NULL;
582 /* Scan a token, and then skip KIND. */
584 static int
585 get_apost_token (idx, in, name, kind)
586 int idx;
587 sb *in;
588 sb *name;
589 int kind;
591 idx = get_token (idx, in, name);
592 if (idx < in->len
593 && in->ptr[idx] == kind
594 && (! macro_mri || macro_strip_at)
595 && (! macro_strip_at || kind == '@'))
596 idx++;
597 return idx;
600 /* Substitute the actual value for a formal parameter. */
602 static int
603 sub_actual (start, in, t, formal_hash, kind, out, copyifnotthere)
604 int start;
605 sb *in;
606 sb *t;
607 struct hash_control *formal_hash;
608 int kind;
609 sb *out;
610 int copyifnotthere;
612 int src;
613 formal_entry *ptr;
615 src = get_apost_token (start, in, t, kind);
616 /* See if it's in the macro's hash table, unless this is
617 macro_strip_at and kind is '@' and the token did not end in '@'. */
618 if (macro_strip_at
619 && kind == '@'
620 && (src == start || in->ptr[src - 1] != '@'))
621 ptr = NULL;
622 else
623 ptr = (formal_entry *) hash_find (formal_hash, sb_terminate (t));
624 if (ptr)
626 if (ptr->actual.len)
628 sb_add_sb (out, &ptr->actual);
630 else
632 sb_add_sb (out, &ptr->def);
635 else if (kind == '&')
637 /* Doing this permits people to use & in macro bodies. */
638 sb_add_char (out, '&');
640 else if (copyifnotthere)
642 sb_add_sb (out, t);
644 else
646 sb_add_char (out, '\\');
647 sb_add_sb (out, t);
649 return src;
652 /* Expand the body of a macro. */
654 static const char *
655 macro_expand_body (in, out, formals, formal_hash, comment_char, locals)
656 sb *in;
657 sb *out;
658 formal_entry *formals;
659 struct hash_control *formal_hash;
660 int comment_char;
661 int locals;
663 sb t;
664 int src = 0;
665 int inquote = 0;
666 formal_entry *loclist = NULL;
668 sb_new (&t);
670 while (src < in->len)
672 if (in->ptr[src] == '&')
674 sb_reset (&t);
675 if (macro_mri)
677 if (src + 1 < in->len && in->ptr[src + 1] == '&')
678 src = sub_actual (src + 2, in, &t, formal_hash, '\'', out, 1);
679 else
680 sb_add_char (out, in->ptr[src++]);
682 else
684 /* FIXME: Why do we do this? */
685 src = sub_actual (src + 1, in, &t, formal_hash, '&', out, 0);
688 else if (in->ptr[src] == '\\')
690 src++;
691 if (in->ptr[src] == comment_char && comment_char != '\0')
693 /* This is a comment, just drop the rest of the line. */
694 while (src < in->len
695 && in->ptr[src] != '\n')
696 src++;
698 else if (in->ptr[src] == '(')
700 /* Sub in till the next ')' literally. */
701 src++;
702 while (src < in->len && in->ptr[src] != ')')
704 sb_add_char (out, in->ptr[src++]);
706 if (in->ptr[src] == ')')
707 src++;
708 else
709 return _("missplaced )");
711 else if (in->ptr[src] == '@')
713 /* Sub in the macro invocation number. */
715 char buffer[10];
716 src++;
717 sprintf (buffer, "%d", macro_number);
718 sb_add_string (out, buffer);
720 else if (in->ptr[src] == '&')
722 /* This is a preprocessor variable name, we don't do them
723 here. */
724 sb_add_char (out, '\\');
725 sb_add_char (out, '&');
726 src++;
728 else if (macro_mri && ISALNUM (in->ptr[src]))
730 int ind;
731 formal_entry *f;
733 if (ISDIGIT (in->ptr[src]))
734 ind = in->ptr[src] - '0';
735 else if (ISUPPER (in->ptr[src]))
736 ind = in->ptr[src] - 'A' + 10;
737 else
738 ind = in->ptr[src] - 'a' + 10;
739 ++src;
740 for (f = formals; f != NULL; f = f->next)
742 if (f->index == ind - 1)
744 if (f->actual.len != 0)
745 sb_add_sb (out, &f->actual);
746 else
747 sb_add_sb (out, &f->def);
748 break;
752 else
754 sb_reset (&t);
755 src = sub_actual (src, in, &t, formal_hash, '\'', out, 0);
758 else if ((macro_alternate || macro_mri)
759 && (ISALPHA (in->ptr[src])
760 || in->ptr[src] == '_'
761 || in->ptr[src] == '$')
762 && (! inquote
763 || ! macro_strip_at
764 || (src > 0 && in->ptr[src - 1] == '@')))
766 if (! locals
767 || src + 5 >= in->len
768 || strncasecmp (in->ptr + src, "LOCAL", 5) != 0
769 || ! ISWHITE (in->ptr[src + 5]))
771 sb_reset (&t);
772 src = sub_actual (src, in, &t, formal_hash,
773 (macro_strip_at && inquote) ? '@' : '\'',
774 out, 1);
776 else
778 formal_entry *f;
780 src = sb_skip_white (src + 5, in);
781 while (in->ptr[src] != '\n' && in->ptr[src] != comment_char)
783 static int loccnt;
784 char buf[20];
785 const char *err;
787 f = (formal_entry *) xmalloc (sizeof (formal_entry));
788 sb_new (&f->name);
789 sb_new (&f->def);
790 sb_new (&f->actual);
791 f->index = LOCAL_INDEX;
792 f->next = loclist;
793 loclist = f;
795 src = get_token (src, in, &f->name);
796 ++loccnt;
797 sprintf (buf, "LL%04x", loccnt);
798 sb_add_string (&f->actual, buf);
800 err = hash_jam (formal_hash, sb_terminate (&f->name), f);
801 if (err != NULL)
802 return err;
804 src = sb_skip_comma (src, in);
808 else if (comment_char != '\0'
809 && in->ptr[src] == comment_char
810 && src + 1 < in->len
811 && in->ptr[src + 1] == comment_char
812 && !inquote)
814 /* Two comment chars in a row cause the rest of the line to
815 be dropped. */
816 while (src < in->len && in->ptr[src] != '\n')
817 src++;
819 else if (in->ptr[src] == '"'
820 || (macro_mri && in->ptr[src] == '\''))
822 inquote = !inquote;
823 sb_add_char (out, in->ptr[src++]);
825 else if (in->ptr[src] == '@' && macro_strip_at)
827 ++src;
828 if (src < in->len
829 && in->ptr[src] == '@')
831 sb_add_char (out, '@');
832 ++src;
835 else if (macro_mri
836 && in->ptr[src] == '='
837 && src + 1 < in->len
838 && in->ptr[src + 1] == '=')
840 formal_entry *ptr;
842 sb_reset (&t);
843 src = get_token (src + 2, in, &t);
844 ptr = (formal_entry *) hash_find (formal_hash, sb_terminate (&t));
845 if (ptr == NULL)
847 /* FIXME: We should really return a warning string here,
848 but we can't, because the == might be in the MRI
849 comment field, and, since the nature of the MRI
850 comment field depends upon the exact instruction
851 being used, we don't have enough information here to
852 figure out whether it is or not. Instead, we leave
853 the == in place, which should cause a syntax error if
854 it is not in a comment. */
855 sb_add_char (out, '=');
856 sb_add_char (out, '=');
857 sb_add_sb (out, &t);
859 else
861 if (ptr->actual.len)
863 sb_add_string (out, "-1");
865 else
867 sb_add_char (out, '0');
871 else
873 sb_add_char (out, in->ptr[src++]);
877 sb_kill (&t);
879 while (loclist != NULL)
881 formal_entry *f;
883 f = loclist->next;
884 /* Setting the value to NULL effectively deletes the entry. We
885 avoid calling hash_delete because it doesn't reclaim memory. */
886 hash_jam (formal_hash, sb_terminate (&loclist->name), NULL);
887 sb_kill (&loclist->name);
888 sb_kill (&loclist->def);
889 sb_kill (&loclist->actual);
890 free (loclist);
891 loclist = f;
894 return NULL;
897 /* Assign values to the formal parameters of a macro, and expand the
898 body. */
900 static const char *
901 macro_expand (idx, in, m, out, comment_char)
902 int idx;
903 sb *in;
904 macro_entry *m;
905 sb *out;
906 int comment_char;
908 sb t;
909 formal_entry *ptr;
910 formal_entry *f;
911 int is_positional = 0;
912 int is_keyword = 0;
913 int narg = 0;
914 const char *err;
916 sb_new (&t);
918 /* Reset any old value the actuals may have. */
919 for (f = m->formals; f; f = f->next)
920 sb_reset (&f->actual);
921 f = m->formals;
922 while (f != NULL && f->index < 0)
923 f = f->next;
925 if (macro_mri)
927 /* The macro may be called with an optional qualifier, which may
928 be referred to in the macro body as \0. */
929 if (idx < in->len && in->ptr[idx] == '.')
931 /* The Microtec assembler ignores this if followed by a white space.
932 (Macro invocation with empty extension) */
933 idx++;
934 if ( idx < in->len
935 && in->ptr[idx] != ' '
936 && in->ptr[idx] != '\t')
938 formal_entry *n;
940 n = (formal_entry *) xmalloc (sizeof (formal_entry));
941 sb_new (&n->name);
942 sb_new (&n->def);
943 sb_new (&n->actual);
944 n->index = QUAL_INDEX;
946 n->next = m->formals;
947 m->formals = n;
949 idx = get_any_string (idx, in, &n->actual, 1, 0);
954 /* Peel off the actuals and store them away in the hash tables' actuals. */
955 idx = sb_skip_white (idx, in);
956 while (idx < in->len && in->ptr[idx] != comment_char)
958 int scan;
960 /* Look and see if it's a positional or keyword arg. */
961 scan = idx;
962 while (scan < in->len
963 && !ISSEP (in->ptr[scan])
964 && !(macro_mri && in->ptr[scan] == '\'')
965 && (!macro_alternate && in->ptr[scan] != '='))
966 scan++;
967 if (scan < in->len && !macro_alternate && in->ptr[scan] == '=')
969 is_keyword = 1;
971 /* It's OK to go from positional to keyword. */
973 /* This is a keyword arg, fetch the formal name and
974 then the actual stuff. */
975 sb_reset (&t);
976 idx = get_token (idx, in, &t);
977 if (in->ptr[idx] != '=')
978 return _("confusion in formal parameters");
980 /* Lookup the formal in the macro's list. */
981 ptr = (formal_entry *) hash_find (m->formal_hash, sb_terminate (&t));
982 if (!ptr)
983 return _("macro formal argument does not exist");
984 else
986 /* Insert this value into the right place. */
987 sb_reset (&ptr->actual);
988 idx = get_any_string (idx + 1, in, &ptr->actual, 0, 0);
989 if (ptr->actual.len > 0)
990 ++narg;
993 else
995 /* This is a positional arg. */
996 is_positional = 1;
997 if (is_keyword)
998 return _("can't mix positional and keyword arguments");
1000 if (!f)
1002 formal_entry **pf;
1003 int c;
1005 if (!macro_mri)
1006 return _("too many positional arguments");
1008 f = (formal_entry *) xmalloc (sizeof (formal_entry));
1009 sb_new (&f->name);
1010 sb_new (&f->def);
1011 sb_new (&f->actual);
1012 f->next = NULL;
1014 c = -1;
1015 for (pf = &m->formals; *pf != NULL; pf = &(*pf)->next)
1016 if ((*pf)->index >= c)
1017 c = (*pf)->index + 1;
1018 if (c == -1)
1019 c = 0;
1020 *pf = f;
1021 f->index = c;
1024 sb_reset (&f->actual);
1025 idx = get_any_string (idx, in, &f->actual, 1, 0);
1026 if (f->actual.len > 0)
1027 ++narg;
1030 f = f->next;
1032 while (f != NULL && f->index < 0);
1035 if (! macro_mri)
1036 idx = sb_skip_comma (idx, in);
1037 else
1039 if (in->ptr[idx] == ',')
1040 ++idx;
1041 if (ISWHITE (in->ptr[idx]))
1042 break;
1046 if (macro_mri)
1048 char buffer[20];
1050 sb_reset (&t);
1051 sb_add_string (&t, macro_strip_at ? "$NARG" : "NARG");
1052 ptr = (formal_entry *) hash_find (m->formal_hash, sb_terminate (&t));
1053 sb_reset (&ptr->actual);
1054 sprintf (buffer, "%d", narg);
1055 sb_add_string (&ptr->actual, buffer);
1058 err = macro_expand_body (&m->sub, out, m->formals, m->formal_hash,
1059 comment_char, 1);
1060 if (err != NULL)
1061 return err;
1063 /* Discard any unnamed formal arguments. */
1064 if (macro_mri)
1066 formal_entry **pf;
1068 pf = &m->formals;
1069 while (*pf != NULL)
1071 if ((*pf)->name.len != 0)
1072 pf = &(*pf)->next;
1073 else
1075 sb_kill (&(*pf)->name);
1076 sb_kill (&(*pf)->def);
1077 sb_kill (&(*pf)->actual);
1078 f = (*pf)->next;
1079 free (*pf);
1080 *pf = f;
1085 sb_kill (&t);
1086 macro_number++;
1088 return NULL;
1091 /* Check for a macro. If one is found, put the expansion into
1092 *EXPAND. COMMENT_CHAR is the comment character--this is used by
1093 gasp. Return 1 if a macro is found, 0 otherwise. */
1096 check_macro (line, expand, comment_char, error, info)
1097 const char *line;
1098 sb *expand;
1099 int comment_char;
1100 const char **error;
1101 macro_entry **info;
1103 const char *s;
1104 char *copy, *cs;
1105 macro_entry *macro;
1106 sb line_sb;
1108 if (! ISALPHA (*line)
1109 && *line != '_'
1110 && *line != '$'
1111 && (! macro_mri || *line != '.'))
1112 return 0;
1114 s = line + 1;
1115 while (ISALNUM (*s)
1116 || *s == '_'
1117 || *s == '$')
1118 ++s;
1120 copy = (char *) alloca (s - line + 1);
1121 memcpy (copy, line, s - line);
1122 copy[s - line] = '\0';
1123 for (cs = copy; *cs != '\0'; cs++)
1124 *cs = TOLOWER (*cs);
1126 macro = (macro_entry *) hash_find (macro_hash, copy);
1128 if (macro == NULL)
1129 return 0;
1131 /* Wrap the line up in an sb. */
1132 sb_new (&line_sb);
1133 while (*s != '\0' && *s != '\n' && *s != '\r')
1134 sb_add_char (&line_sb, *s++);
1136 sb_new (expand);
1137 *error = macro_expand (0, &line_sb, macro, expand, comment_char);
1139 sb_kill (&line_sb);
1141 /* Export the macro information if requested. */
1142 if (info)
1143 *info = macro;
1145 return 1;
1148 /* Delete a macro. */
1150 void
1151 delete_macro (name)
1152 const char *name;
1154 hash_delete (macro_hash, name);
1157 /* Handle the MRI IRP and IRPC pseudo-ops. These are handled as a
1158 combined macro definition and execution. This returns NULL on
1159 success, or an error message otherwise. */
1161 const char *
1162 expand_irp (irpc, idx, in, out, get_line, comment_char)
1163 int irpc;
1164 int idx;
1165 sb *in;
1166 sb *out;
1167 int (*get_line) PARAMS ((sb *));
1168 int comment_char;
1170 const char *mn;
1171 sb sub;
1172 formal_entry f;
1173 struct hash_control *h;
1174 const char *err;
1176 if (irpc)
1177 mn = "IRPC";
1178 else
1179 mn = "IRP";
1181 idx = sb_skip_white (idx, in);
1183 sb_new (&sub);
1184 if (! buffer_and_nest (mn, "ENDR", &sub, get_line))
1185 return _("unexpected end of file in irp or irpc");
1187 sb_new (&f.name);
1188 sb_new (&f.def);
1189 sb_new (&f.actual);
1191 idx = get_token (idx, in, &f.name);
1192 if (f.name.len == 0)
1193 return _("missing model parameter");
1195 h = hash_new ();
1196 err = hash_jam (h, sb_terminate (&f.name), &f);
1197 if (err != NULL)
1198 return err;
1200 f.index = 1;
1201 f.next = NULL;
1203 sb_reset (out);
1205 idx = sb_skip_comma (idx, in);
1206 if (idx >= in->len || in->ptr[idx] == comment_char)
1208 /* Expand once with a null string. */
1209 err = macro_expand_body (&sub, out, &f, h, comment_char, 0);
1210 if (err != NULL)
1211 return err;
1213 else
1215 if (irpc && in->ptr[idx] == '"')
1216 ++idx;
1217 while (idx < in->len && in->ptr[idx] != comment_char)
1219 if (!irpc)
1220 idx = get_any_string (idx, in, &f.actual, 1, 0);
1221 else
1223 if (in->ptr[idx] == '"')
1225 int nxt;
1227 nxt = sb_skip_white (idx + 1, in);
1228 if (nxt >= in->len || in->ptr[nxt] == comment_char)
1230 idx = nxt;
1231 break;
1234 sb_reset (&f.actual);
1235 sb_add_char (&f.actual, in->ptr[idx]);
1236 ++idx;
1238 err = macro_expand_body (&sub, out, &f, h, comment_char, 0);
1239 if (err != NULL)
1240 return err;
1241 if (!irpc)
1242 idx = sb_skip_comma (idx, in);
1243 else
1244 idx = sb_skip_white (idx, in);
1248 hash_die (h);
1249 sb_kill (&sub);
1251 return NULL;