* sb.c: Include "libiberty.h".
[platform/upstream/binutils.git] / gas / macro.c
1 /* macro.c - macro support for gas and gasp
2    Copyright (C) 1994, 1995 Free Software Foundation, Inc.
3
4    Written by Steve and Judy Chamberlain of Cygnus Support,
5       sac@cygnus.com
6
7    This file is part of GAS, the GNU Assembler.
8
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.
13
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.
18
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. */
23
24 #include "config.h"
25 #include <stdio.h>
26 #include <ctype.h>
27 #ifdef HAVE_STDLIB_H
28 #include <stdlib.h>
29 #endif
30 #include "libiberty.h"
31 #include "sb.h"
32 #include "hash.h"
33 #include "macro.h"
34
35 /* The routines in this file handle macro definition and expansion.
36    They are called by both gasp and gas.  */
37
38 /* Structures used to store macros. 
39
40    Each macro knows its name and included text.  It gets built with a
41    list of formal arguments, and also keeps a hash table which points
42    into the list to speed up formal search.  Each formal knows its
43    name and its default value.  Each time the macro is expanded, the
44    formals get the actual values attatched to them. */
45
46 /* describe the formal arguments to a macro */
47
48 typedef struct formal_struct
49   {
50     struct formal_struct *next; /* next formal in list */
51     sb name;                    /* name of the formal */
52     sb def;                     /* the default value */
53     sb actual;                  /* the actual argument (changed on each expansion) */
54     int index;                  /* the index of the formal 0..formal_count-1 */
55   }
56 formal_entry;
57
58 /* Other values found in the index field of a formal_entry.  */
59 #define QUAL_INDEX (-1)
60 #define NARG_INDEX (-2)
61 #define LOCAL_INDEX (-3)
62
63 /* describe the macro. */
64
65 typedef struct macro_struct
66   {
67     sb sub;                     /* substitution text. */
68     int formal_count;           /* number of formal args. */
69     formal_entry *formals;      /* pointer to list of formal_structs */
70     struct hash_control *formal_hash; /* hash table of formals. */
71   }
72 macro_entry;
73
74 /* Internal functions.  */
75
76 static int get_token PARAMS ((int, sb *, sb *));
77 static int getstring PARAMS ((int, sb *, sb *));
78 static int get_any_string PARAMS ((int, sb *, sb *, int, int));
79 static int do_formals PARAMS ((macro_entry *, int, sb *));
80 static int get_apost_token PARAMS ((int, sb *, sb *, int));
81 static int sub_actual
82   PARAMS ((int, sb *, sb *, struct hash_control *, int, sb *, int));
83 static const char *macro_expand_body
84   PARAMS ((sb *, sb *, formal_entry *, struct hash_control *, int, int));
85 static const char *macro_expand PARAMS ((int, sb *, macro_entry *, sb *, int));
86
87 #define ISWHITE(x) ((x) == ' ' || (x) == '\t')
88
89 #define ISSEP(x) \
90  ((x) == ' ' || (x) == '\t' || (x) == ',' || (x) == '"' || (x) == ';' \
91   || (x) == '<' || (x) == '>' || (x) == ')' || (x) == '(')
92
93 #define ISBASE(x) \
94   ((x) == 'b' || (x) == 'B' \
95    || (x) == 'q' || (x) == 'Q' \
96    || (x) == 'h' || (x) == 'H' \
97    || (x) == 'd' || (x) == 'D')
98
99 /* The macro hash table.  */
100
101 static struct hash_control *macro_hash;
102
103 /* Whether any macros have been defined.  */
104
105 int macro_defined;
106
107 /* Whether we are in GASP alternate mode.  */
108
109 static int macro_alternate;
110
111 /* Whether we are in MRI mode.  */
112
113 static int macro_mri;
114
115 /* Function to use to parse an expression.  */
116
117 static int (*macro_expr) PARAMS ((const char *, int, sb *, int *));
118
119 /* Number of macro expansions that have been done.  */
120
121 static int macro_number;
122
123 /* Initialize macro processing.  */
124
125 void
126 macro_init (alternate, mri, expr)
127      int alternate;
128      int mri;
129      int (*expr) PARAMS ((const char *, int, sb *, int *));
130 {
131   macro_hash = hash_new ();
132   macro_defined = 0;
133   macro_alternate = alternate;
134   macro_mri = mri;
135   macro_expr = expr;
136 }
137
138 /* Read input lines till we get to a TO string.
139    Increase nesting depth if we get a FROM string.
140    Put the results into sb at PTR.
141    Add a new input line to an sb using GET_LINE.
142    Return 1 on success, 0 on unexpected EOF.  */
143
144 int
145 buffer_and_nest (from, to, ptr, get_line)
146      const char *from;
147      const char *to;
148      sb *ptr;
149      int (*get_line) PARAMS ((sb *));
150 {
151   int from_len = strlen (from);
152   int to_len = strlen (to);
153   int depth = 1;
154   int line_start = ptr->len;
155
156   int more = get_line (ptr);
157
158   while (more)
159     {
160       /* Try and find the first pseudo op on the line */
161       int i = line_start;
162
163       if (! macro_alternate && ! macro_mri)
164         {
165           /* With normal syntax we can suck what we want till we get
166              to the dot.  With the alternate, labels have to start in
167              the first column, since we cant tell what's a label and
168              whats a pseudoop */
169
170           /* Skip leading whitespace */
171           while (i < ptr->len && ISWHITE (ptr->ptr[i]))
172             i++;
173
174           /* Skip over a label */
175           while (i < ptr->len
176                  && (isalnum ((unsigned char) ptr->ptr[i])
177                      || ptr->ptr[i] == '_'
178                      || ptr->ptr[i] == '$'))
179             i++;
180
181           /* And a colon */
182           if (i < ptr->len
183               && ptr->ptr[i] == ':')
184             i++;
185
186         }
187       /* Skip trailing whitespace */
188       while (i < ptr->len && ISWHITE (ptr->ptr[i]))
189         i++;
190
191       if (i < ptr->len && (ptr->ptr[i] == '.'
192                            || macro_alternate
193                            || macro_mri))
194         {
195           if (ptr->ptr[i] == '.')
196               i++;
197           if (strncasecmp (ptr->ptr + i, from, from_len) == 0)
198             depth++;
199           if (strncasecmp (ptr->ptr + i, to, to_len) == 0)
200             {
201               depth--;
202               if (depth == 0)
203                 {
204                   /* Reset the string to not include the ending rune */
205                   ptr->len = line_start;
206                   break;
207                 }
208             }
209         }
210
211       /* Add a CR to the end and keep running */
212       sb_add_char (ptr, '\n');
213       line_start = ptr->len;
214       more = get_line (ptr);
215     }
216
217   /* Return 1 on success, 0 on unexpected EOF.  */
218   return depth == 0;
219 }
220
221 /* Pick up a token.  */
222
223 static int
224 get_token (idx, in, name)
225      int idx;
226      sb *in;
227      sb *name;
228 {
229   if (idx < in->len
230       && (isalpha ((unsigned char) in->ptr[idx])
231           || in->ptr[idx] == '_'
232           || in->ptr[idx] == '$'))
233     {
234       sb_add_char (name, in->ptr[idx++]);
235       while (idx < in->len
236              && (isalnum ((unsigned char) in->ptr[idx])
237                  || in->ptr[idx] == '_'
238                  || in->ptr[idx] == '$'))
239         {
240           sb_add_char (name, in->ptr[idx++]);
241         }
242     }
243   /* Ignore trailing & */
244   if (macro_alternate && idx < in->len && in->ptr[idx] == '&')
245     idx++;
246   return idx;
247 }
248
249 /* Pick up a string.  */
250
251 static int
252 getstring (idx, in, acc)
253      int idx;
254      sb *in;
255      sb *acc;
256 {
257   idx = sb_skip_white (idx, in);
258
259   while (idx < in->len
260          && (in->ptr[idx] == '"' 
261              || in->ptr[idx] == '<' 
262              || (in->ptr[idx] == '\'' && macro_alternate)))
263     {
264       if (in->ptr[idx] == '<')
265         {
266           if (macro_alternate || macro_mri)
267             {
268               int nest = 0;
269               idx++;
270               while ((in->ptr[idx] != '>' || nest)
271                      && idx < in->len)
272                 {
273                   if (in->ptr[idx] == '!')
274                     {
275                       idx++  ;
276                       sb_add_char (acc, in->ptr[idx++]);
277                     }
278                   else
279                     {
280                       if (in->ptr[idx] == '>')
281                         nest--;
282                       if (in->ptr[idx] == '<')
283                         nest++;
284                       sb_add_char (acc, in->ptr[idx++]);
285                     }
286                 }
287               idx++;
288             }
289           else
290             {
291               int code;
292               idx++;
293               idx = ((*macro_expr)
294                      ("character code in string must be absolute expression",
295                       idx, in, &code));
296               sb_add_char (acc, code);
297
298 #if 0
299               if (in->ptr[idx] != '>')
300                 ERROR ((stderr, "Missing > for character code.\n"));
301 #endif
302               idx++;
303             }
304         }
305       else if (in->ptr[idx] == '"' || in->ptr[idx] == '\'')
306         {
307           char tchar = in->ptr[idx];
308           idx++;
309           while (idx < in->len)
310             {
311               if (macro_alternate && in->ptr[idx] == '!')
312                 {
313                   idx++  ;
314                   sb_add_char (acc, in->ptr[idx++]);
315                 }
316               else
317                 {
318                   if (in->ptr[idx] == tchar)
319                     {
320                       idx++;
321                       if (idx >= in->len || in->ptr[idx] != tchar)
322                         break;
323                     }
324                   sb_add_char (acc, in->ptr[idx]);
325                   idx++;
326                 }
327             }
328         }
329     }
330   
331   return idx;
332 }
333
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
340 */
341
342 static int
343 get_any_string (idx, in, out, expand, pretend_quoted)
344      int idx;
345      sb *in;
346      sb *out;
347      int expand;
348      int pretend_quoted;
349 {
350   sb_reset (out);
351   idx = sb_skip_white (idx, in);
352
353   if (idx < in->len)
354     {
355       if (in->len > 2 && in->ptr[idx+1] == '\'' && ISBASE (in->ptr[idx]))
356         {
357           while (!ISSEP (in->ptr[idx]))
358             sb_add_char (out, in->ptr[idx++]);
359         }
360       else if (in->ptr[idx] == '%'
361                && macro_alternate
362                && expand)
363         {
364           int val;
365           char buf[20];
366           /* Turns the next expression into a string */
367           idx = (*macro_expr) ("% operator needs absolute expression",
368                                idx + 1,
369                                in,
370                                &val);
371           sprintf(buf, "%d", val);
372           sb_add_string (out, buf);
373         }
374       else if (in->ptr[idx] == '"'
375                || in->ptr[idx] == '<'
376                || (macro_alternate && in->ptr[idx] == '\''))
377         {
378           if (macro_alternate && expand)
379             {
380               /* Keep the quotes */
381               sb_add_char (out,  '\"');
382
383               idx = getstring (idx, in, out);
384               sb_add_char (out,  '\"');
385             }
386           else
387             {
388               idx = getstring (idx, in, out);
389             }
390         }
391       else 
392         {
393           while (idx < in->len 
394                  && (in->ptr[idx] == '"'
395                      || in->ptr[idx] == '\''
396                      || pretend_quoted 
397                      || (in->ptr[idx] != ' '
398                          && in->ptr[idx] != '\t'
399                          && in->ptr[idx] != ','
400                          && in->ptr[idx] != '<')))
401             {
402               if (in->ptr[idx] == '"' 
403                   || in->ptr[idx] == '\'')
404                 {
405                   char tchar = in->ptr[idx];
406                   sb_add_char (out, in->ptr[idx++]);
407                   while (idx < in->len
408                          && in->ptr[idx] != tchar)
409                     sb_add_char (out, in->ptr[idx++]);              
410                   if (idx == in->len)
411                     return idx;       
412                 }
413               sb_add_char (out, in->ptr[idx++]);
414             }
415         }
416     }
417
418   return idx;
419 }
420
421 /* Pick up the formal parameters of a macro definition.  */
422
423 static int
424 do_formals (macro, idx, in)
425      macro_entry *macro;
426      int idx;
427      sb *in;
428 {
429   formal_entry **p = &macro->formals;
430
431   macro->formal_count = 0;
432   macro->formal_hash = hash_new ();
433   while (idx < in->len)
434     {
435       formal_entry *formal;
436
437       formal = (formal_entry *) xmalloc (sizeof (formal_entry));
438
439       sb_new (&formal->name);
440       sb_new (&formal->def);
441       sb_new (&formal->actual);
442
443       idx = sb_skip_white (idx, in);
444       idx = get_token (idx, in, &formal->name);
445       if (formal->name.len == 0)
446         break;
447       idx = sb_skip_white (idx, in);
448       if (formal->name.len)
449         {
450           /* This is a formal */
451           if (idx < in->len && in->ptr[idx] == '=')
452             {
453               /* Got a default */
454               idx = get_any_string (idx + 1, in, &formal->def, 1, 0);
455             }
456         }
457
458       /* Add to macro's hash table */
459       hash_jam (macro->formal_hash, sb_terminate (&formal->name), formal);
460
461       formal->index = macro->formal_count;
462       idx = sb_skip_comma (idx, in);
463       macro->formal_count++;
464       *p = formal;
465       p = &formal->next;
466       *p = NULL;
467     }
468
469   if (macro_mri)
470     {
471       formal_entry *formal;
472
473       /* Add a special NARG formal, which macro_expand will set to the
474          number of arguments.  */
475       formal = (formal_entry *) xmalloc (sizeof (formal_entry));
476
477       sb_new (&formal->name);
478       sb_new (&formal->def);
479       sb_new (&formal->actual);
480
481       sb_add_string (&formal->name, "NARG");
482
483       /* Add to macro's hash table */
484       hash_jam (macro->formal_hash, "NARG", formal);
485
486       formal->index = NARG_INDEX;
487       *p = formal;
488       formal->next = NULL;
489     }
490
491   return idx;
492 }
493
494 /* Define a new macro.  Returns NULL on success, otherwise returns an
495    error message.  */
496
497 const char *
498 define_macro (idx, in, label, get_line)
499      int idx;
500      sb *in;
501      sb *label;
502      int (*get_line) PARAMS ((sb *));
503 {
504   macro_entry *macro;
505   sb name;
506
507   macro = (macro_entry *) xmalloc (sizeof (macro_entry));
508   sb_new (&macro->sub);
509   sb_new (&name);
510
511   macro->formal_count = 0;
512   macro->formals = 0;
513
514   idx = sb_skip_white (idx, in);
515   if (! buffer_and_nest ("MACRO", "ENDM", &macro->sub, get_line))
516     return "unexpected end of file in macro definition";
517   if (label != NULL && label->len != 0)
518     {
519       sb_add_sb (&name, label);
520       if (in->ptr[idx] == '(')
521         {
522           /* It's the label: MACRO (formals,...)  sort */
523           idx = do_formals (macro, idx + 1, in);
524           if (in->ptr[idx] != ')')
525             return "missing ) after formals";
526         }
527       else
528         {
529           /* It's the label: MACRO formals,...  sort */
530           idx = do_formals (macro, idx, in);
531         }
532     }
533   else
534     {
535       idx = get_token (idx, in, &name);
536       idx = sb_skip_white (idx, in);
537       idx = do_formals (macro, idx, in);
538     }
539
540   /* and stick it in the macro hash table */
541   for (idx = 0; idx < name.len; idx++)
542     if (isupper (name.ptr[idx]))
543       name.ptr[idx] = tolower (name.ptr[idx]);
544   hash_jam (macro_hash, sb_terminate (&name), (PTR) macro);
545
546   macro_defined = 1;
547
548   return NULL;
549 }
550
551 /* Scan a token, and then skip KIND.  */
552
553 static int
554 get_apost_token (idx, in, name, kind)
555      int idx;
556      sb *in;
557      sb *name;
558      int kind;
559 {
560   idx = get_token (idx, in, name);
561   if (idx < in->len && in->ptr[idx] == kind && ! macro_mri)
562     idx++;
563   return idx;
564 }
565
566 /* Substitute the actual value for a formal parameter.  */
567
568 static int
569 sub_actual (src, in, t, formal_hash, kind, out, copyifnotthere)
570      int src;
571      sb *in;
572      sb *t;
573      struct hash_control *formal_hash;
574      int kind;
575      sb *out;
576      int copyifnotthere;
577 {
578   formal_entry *ptr;
579
580   src = get_apost_token (src, in, t, kind);
581   /* See if it's in the macro's hash table */
582   ptr = (formal_entry *) hash_find (formal_hash, sb_terminate (t));
583   if (ptr)
584     {
585       if (ptr->actual.len)
586         {
587           sb_add_sb (out, &ptr->actual);
588         }
589       else
590         {
591           sb_add_sb (out, &ptr->def);
592         }
593     }
594   else if (copyifnotthere)
595     {
596       sb_add_sb (out, t);
597     }
598   else 
599     {
600       sb_add_char (out, '\\');
601       sb_add_sb (out, t);
602     }
603   return src;
604 }
605
606 /* Expand the body of a macro.  */
607
608 static const char *
609 macro_expand_body (in, out, formals, formal_hash, comment_char, locals)
610      sb *in;
611      sb *out;
612      formal_entry *formals;
613      struct hash_control *formal_hash;
614      int comment_char;
615      int locals;
616 {
617   sb t;
618   int src = 0;
619   int inquote = 0;
620   formal_entry *loclist = NULL;
621
622   sb_new (&t);
623
624   while (src < in->len)
625     {
626       if (in->ptr[src] == '&')
627         {
628           sb_reset (&t);
629           if (macro_mri && src + 1 < in->len && in->ptr[src + 1] == '&')
630             {
631               src = sub_actual (src + 2, in, &t, formal_hash, '\'', out, 1);
632             }
633           else
634             {
635               src = sub_actual (src + 1, in, &t, formal_hash, '&', out, 0);
636             }
637         }
638       else if (in->ptr[src] == '\\')
639         {
640           src++;
641           if (in->ptr[src] == comment_char && comment_char != '\0')
642             {
643               /* This is a comment, just drop the rest of the line */
644               while (src < in->len
645                      && in->ptr[src] != '\n')
646                 src++;
647             }
648           else if (in->ptr[src] == '(')
649             {
650               /* Sub in till the next ')' literally */
651               src++;
652               while (src < in->len && in->ptr[src] != ')')
653                 {
654                   sb_add_char (out, in->ptr[src++]);
655                 }
656               if (in->ptr[src] == ')')
657                 src++;
658               else
659                 return "missplaced )";
660             }
661           else if (in->ptr[src] == '@')
662             {
663               /* Sub in the macro invocation number */
664
665               char buffer[6];
666               src++;
667               sprintf (buffer, "%05d", macro_number);
668               sb_add_string (out, buffer);
669             }
670           else if (in->ptr[src] == '&')
671             {
672               /* This is a preprocessor variable name, we don't do them
673                  here */
674               sb_add_char (out, '\\');
675               sb_add_char (out, '&');
676               src++;
677             }
678           else if (macro_mri
679                    && isalnum ((unsigned char) in->ptr[src]))
680             {
681               int ind;
682               formal_entry *f;
683
684               if (isdigit ((unsigned char) in->ptr[src]))
685                 ind = in->ptr[src] - '0';
686               else if (isupper ((unsigned char) in->ptr[src]))
687                 ind = in->ptr[src] - 'A' + 10;
688               else
689                 ind = in->ptr[src] - 'a' + 10;
690               ++src;
691               for (f = formals; f != NULL; f = f->next)
692                 {
693                   if (f->index == ind - 1)
694                     {
695                       if (f->actual.len != 0)
696                         sb_add_sb (out, &f->actual);
697                       else
698                         sb_add_sb (out, &f->def);
699                       break;
700                     }
701                 }
702             }
703           else
704             {
705               sb_reset (&t);
706               src = sub_actual (src, in, &t, formal_hash, '\'', out, 0);
707             }
708         }
709       else if ((macro_alternate || macro_mri)
710                && (isalpha ((unsigned char) in->ptr[src])
711                    || in->ptr[src] == '_'
712                    || in->ptr[src] == '$'))
713         {
714           if (! locals
715               || src + 5 >= in->len
716               || strncasecmp (in->ptr + src, "LOCAL", 5) != 0
717               || ! ISWHITE (in->ptr[src + 5]))
718             {
719               sb_reset (&t);
720               src = sub_actual (src, in, &t, formal_hash, '\'', out, 1);
721             }
722           else
723             {
724               formal_entry *f;
725
726               src = sb_skip_white (src + 5, in);
727               while (in->ptr[src] != '\n' && in->ptr[src] != comment_char)
728                 {
729                   static int loccnt;
730                   char buf[20];
731                   const char *err;
732
733                   f = (formal_entry *) xmalloc (sizeof (formal_entry));
734                   sb_new (&f->name);
735                   sb_new (&f->def);
736                   sb_new (&f->actual);
737                   f->index = LOCAL_INDEX;
738                   f->next = loclist;
739                   loclist = f;
740
741                   src = get_token (src, in, &f->name);
742                   ++loccnt;
743                   sprintf (buf, "LL%04x", loccnt);
744                   sb_add_string (&f->actual, buf);
745
746                   err = hash_jam (formal_hash, sb_terminate (&f->name), f);
747                   if (err != NULL)
748                     return err;
749
750                   src = sb_skip_comma (src, in);
751                 }
752             }
753         }
754       else if (comment_char != '\0'
755                && in->ptr[src] == comment_char
756                && src + 1 < in->len
757                && in->ptr[src + 1] == comment_char
758                && !inquote)
759         {
760           /* Two comment chars in a row cause the rest of the line to
761              be dropped.  */
762           while (src < in->len && in->ptr[src] != '\n')
763             src++;
764         }
765       else if (in->ptr[src] == '"'
766                || (macro_mri && in->ptr[src] == '\''))
767         {
768           inquote = !inquote;
769           sb_add_char (out, in->ptr[src++]);
770         }
771       else if (macro_mri
772                && in->ptr[src] == '='
773                && src + 1 < in->len
774                && in->ptr[src + 1] == '=')
775         {
776           formal_entry *ptr;
777
778           sb_reset (&t);
779           src = get_token (src + 2, in, &t);
780           ptr = (formal_entry *) hash_find (formal_hash, sb_terminate (&t));
781           if (ptr == NULL)
782             return "macro formal argument does not exist";
783           else
784             {
785               if (ptr->actual.len)
786                 {
787                   sb_add_string (out, "-1");
788                 }
789               else
790                 {
791                   sb_add_char (out, '0');
792                 }
793             }
794         }
795       else
796         {
797           sb_add_char (out, in->ptr[src++]);
798         }
799     }
800
801   sb_kill (&t);
802
803   while (loclist != NULL)
804     {
805       formal_entry *f;
806
807       f = loclist->next;
808       sb_kill (&loclist->name);
809       sb_kill (&loclist->def);
810       sb_kill (&loclist->actual);
811       free (loclist);
812       loclist = f;
813     }
814
815   return NULL;
816 }
817
818 /* Assign values to the formal parameters of a macro, and expand the
819    body.  */
820
821 static const char *
822 macro_expand (idx, in, m, out, comment_char)
823      int idx;
824      sb *in;
825      macro_entry *m;
826      sb *out;
827      int comment_char;
828 {
829   sb t;
830   formal_entry *ptr;
831   formal_entry *f;
832   int is_positional = 0;
833   int is_keyword = 0;
834   int narg = 0;
835   const char *err;
836
837   sb_new (&t);
838   
839   /* Reset any old value the actuals may have */
840   for (f = m->formals; f; f = f->next)
841       sb_reset (&f->actual);
842   f = m->formals;
843   while (f != NULL && f->index < 0)
844     f = f->next;
845
846   if (macro_mri)
847     {
848       /* The macro may be called with an optional qualifier, which may
849          be referred to in the macro body as \0.  */
850       if (idx < in->len && in->ptr[idx] == '.')
851         {
852           formal_entry *n;
853
854           n = (formal_entry *) xmalloc (sizeof (formal_entry));
855           sb_new (&n->name);
856           sb_new (&n->def);
857           sb_new (&n->actual);
858           n->index = QUAL_INDEX;
859
860           n->next = m->formals;
861           m->formals = n;
862
863           idx = get_any_string (idx + 1, in, &n->actual, 1, 0);
864         }
865     }
866
867   /* Peel off the actuals and store them away in the hash tables' actuals */
868   idx = sb_skip_white (idx, in);
869   while (idx < in->len && in->ptr[idx] != comment_char)
870     {
871       int scan;
872
873       /* Look and see if it's a positional or keyword arg */
874       scan = idx;
875       while (scan < in->len
876              && !ISSEP (in->ptr[scan])
877              && (!macro_alternate && in->ptr[scan] != '='))
878         scan++;
879       if (scan < in->len && !macro_alternate && in->ptr[scan] == '=')
880         {
881           is_keyword = 1;
882           if (is_positional)
883             return "can't mix positional and keyword arguments";
884
885           /* This is a keyword arg, fetch the formal name and
886              then the actual stuff */
887           sb_reset (&t);
888           idx = get_token (idx, in, &t);
889           if (in->ptr[idx] != '=')
890             return "confusion in formal parameters";
891
892           /* Lookup the formal in the macro's list */
893           ptr = (formal_entry *) hash_find (m->formal_hash, sb_terminate (&t));
894           if (!ptr)
895             return "macro formal argument does not exist";
896           else
897             {
898               /* Insert this value into the right place */
899               sb_reset (&ptr->actual);
900               idx = get_any_string (idx + 1, in, &ptr->actual, 0, 0);
901               if (ptr->actual.len > 0)
902                 ++narg;
903             }
904         }
905       else
906         {
907           /* This is a positional arg */
908           is_positional = 1;
909           if (is_keyword)
910             return "can't mix positional and keyword arguments";
911
912           if (!f)
913             {
914               formal_entry **pf;
915               int c;
916
917               if (!macro_mri)
918                 return "too many positional arguments";
919
920               f = (formal_entry *) xmalloc (sizeof (formal_entry));
921               sb_new (&f->name);
922               sb_new (&f->def);
923               sb_new (&f->actual);
924               f->next = NULL;
925
926               c = -1;
927               for (pf = &m->formals; *pf != NULL; pf = &(*pf)->next)
928                 if ((*pf)->index >= c)
929                   c = (*pf)->index + 1;
930               if (c == -1)
931                 c = 0;
932               *pf = f;
933               f->index = c;
934             }
935
936           sb_reset (&f->actual);
937           idx = get_any_string (idx, in, &f->actual, 1, 0);
938           if (f->actual.len > 0)
939             ++narg;
940           do
941             {
942               f = f->next;
943             }
944           while (f != NULL && f->index < 0);
945         }
946
947       idx = sb_skip_comma (idx, in);
948     }
949
950   if (macro_mri)
951     {
952       char buffer[20];
953
954       sb_reset (&t);
955       sb_add_string (&t, "NARG");
956       ptr = (formal_entry *) hash_find (m->formal_hash, sb_terminate (&t));
957       sb_reset (&ptr->actual);
958       sprintf (buffer, "%d", narg);
959       sb_add_string (&ptr->actual, buffer);
960     }
961
962   err = macro_expand_body (&m->sub, out, m->formals, m->formal_hash,
963                            comment_char, 1);
964   if (err != NULL)
965     return err;
966
967   /* Discard any unnamed formal arguments.  */
968   if (macro_mri)
969     {
970       formal_entry **pf;
971
972       pf = &m->formals;
973       while (*pf != NULL)
974         {
975           if ((*pf)->name.len != 0)
976             pf = &(*pf)->next;
977           else
978             {
979               sb_kill (&(*pf)->name);
980               sb_kill (&(*pf)->def);
981               sb_kill (&(*pf)->actual);
982               f = (*pf)->next;
983               free (*pf);
984               *pf = f;
985             }
986         }
987     }
988
989   sb_kill (&t);
990   macro_number++;
991
992   return NULL;
993 }
994
995 /* Check for a macro.  If one is found, put the expansion into
996    *EXPAND.  COMMENT_CHAR is the comment character--this is used by
997    gasp.  Return 1 if a macro is found, 0 otherwise.  */
998
999 int
1000 check_macro (line, expand, comment_char, error)
1001      const char *line;
1002      sb *expand;
1003      int comment_char;
1004      const char **error;
1005 {
1006   const char *s;
1007   char *copy, *cs;
1008   macro_entry *macro;
1009   sb line_sb;
1010
1011   if (! isalpha ((unsigned char) *line)
1012       && *line != '_'
1013       && *line != '$'
1014       && (! macro_mri || *line != '.'))
1015     return 0;
1016
1017   s = line + 1;
1018   while (isalnum ((unsigned char) *s)
1019          || *s == '_'
1020          || *s == '$')
1021     ++s;
1022
1023   copy = (char *) xmalloc (s - line + 1);
1024   memcpy (copy, line, s - line);
1025   copy[s - line] = '\0';
1026   for (cs = copy; *cs != '\0'; cs++)
1027     if (isupper (*cs))
1028       *cs = tolower (*cs);
1029
1030   macro = (macro_entry *) hash_find (macro_hash, copy);
1031
1032   if (macro == NULL)
1033     return 0;
1034
1035   /* Wrap the line up in an sb.  */
1036   sb_new (&line_sb);
1037   while (*s != '\0' && *s != '\n' && *s != '\r')
1038     sb_add_char (&line_sb, *s++);
1039
1040   sb_new (expand);
1041   *error = macro_expand (0, &line_sb, macro, expand, comment_char);
1042
1043   sb_kill (&line_sb);
1044
1045   return 1;
1046 }
1047
1048 /* Handle the MRI IRP and IRPC pseudo-ops.  These are handled as a
1049    combined macro definition and execution.  This returns NULL on
1050    success, or an error message otherwise.  */
1051
1052 const char *
1053 expand_irp (irpc, idx, in, out, get_line, comment_char)
1054      int irpc;
1055      int idx;
1056      sb *in;
1057      sb *out;
1058      int (*get_line) PARAMS ((sb *));
1059      int comment_char;
1060 {
1061   const char *mn;
1062   sb sub;
1063   formal_entry f;
1064   struct hash_control *h;
1065   const char *err;
1066
1067   if (irpc)
1068     mn = "IRPC";
1069   else
1070     mn = "IRP";
1071
1072   idx = sb_skip_white (idx, in);
1073
1074   sb_new (&sub);
1075   if (! buffer_and_nest (mn, "ENDR", &sub, get_line))
1076     return "unexpected end of file in irp or irpc";
1077   
1078   sb_new (&f.name);
1079   sb_new (&f.def);
1080   sb_new (&f.actual);
1081
1082   idx = get_token (idx, in, &f.name);
1083   if (f.name.len == 0)
1084     return "missing model parameter";
1085
1086   h = hash_new ();
1087   err = hash_jam (h, sb_terminate (&f.name), &f);
1088   if (err != NULL)
1089     return err;
1090
1091   f.index = 1;
1092   f.next = NULL;
1093
1094   sb_reset (out);
1095
1096   idx = sb_skip_comma (idx, in);
1097   if (idx >= in->len || in->ptr[idx] == comment_char)
1098     {
1099       /* Expand once with a null string.  */
1100       err = macro_expand_body (&sub, out, &f, h, comment_char, 0);
1101       if (err != NULL)
1102         return err;
1103     }
1104   else
1105     {
1106       while (idx < in->len && in->ptr[idx] != comment_char)
1107         {
1108           if (!irpc)
1109             idx = get_any_string (idx, in, &f.actual, 1, 0);
1110           else
1111             {
1112               sb_reset (&f.actual);
1113               sb_add_char (&f.actual, in->ptr[idx]);
1114               ++idx;
1115             }
1116           err = macro_expand_body (&sub, out, &f, h, comment_char, 0);
1117           if (err != NULL)
1118             return err;
1119           if (!irpc)
1120             idx = sb_skip_comma (idx, in);
1121           else
1122             idx = sb_skip_white (idx, in);
1123         }
1124     }
1125
1126   hash_die (h);
1127   sb_kill (&sub);
1128
1129   return NULL;
1130 }