* config/tc-i370.c (i370_ebcdic <unused>): Add ATTRIBUTE_UNUSED.
[external/binutils.git] / gas / macro.c
1 /* macro.c - macro support for gas
2    Copyright 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002
3    Free Software Foundation, Inc.
4
5    Written by Steve and Judy Chamberlain of Cygnus Support,
6       sac@cygnus.com
7
8    This file is part of GAS, the GNU Assembler.
9
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.
14
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.
19
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.  */
24
25 #include "config.h"
26
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__ */
47
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"
62
63 #include "asintl.h"
64
65 /* The routines in this file handle macro definition and expansion.
66    They are called by gas.  */
67
68 /* Internal functions.  */
69
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));
79 static const char *macro_expand PARAMS ((int, sb *, macro_entry *, sb *));
80
81 #define ISWHITE(x) ((x) == ' ' || (x) == '\t')
82
83 #define ISSEP(x) \
84  ((x) == ' ' || (x) == '\t' || (x) == ',' || (x) == '"' || (x) == ';' \
85   || (x) == ')' || (x) == '(' \
86   || ((macro_alternate || macro_mri) && ((x) == '<' || (x) == '>')))
87
88 #define ISBASE(x) \
89   ((x) == 'b' || (x) == 'B' \
90    || (x) == 'q' || (x) == 'Q' \
91    || (x) == 'h' || (x) == 'H' \
92    || (x) == 'd' || (x) == 'D')
93
94 /* The macro hash table.  */
95
96 static struct hash_control *macro_hash;
97
98 /* Whether any macros have been defined.  */
99
100 int macro_defined;
101
102 /* Whether we are in alternate syntax mode.  */
103
104 static int macro_alternate;
105
106 /* Whether we are in MRI mode.  */
107
108 static int macro_mri;
109
110 /* Whether we should strip '@' characters.  */
111
112 static int macro_strip_at;
113
114 /* Function to use to parse an expression.  */
115
116 static int (*macro_expr) PARAMS ((const char *, int, sb *, int *));
117
118 /* Number of macro expansions that have been done.  */
119
120 static int macro_number;
121
122 /* Initialize macro processing.  */
123
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 *));
130 {
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;
137 }
138
139 /* Switch in and out of MRI mode on the fly.  */
140
141 void
142 macro_mri_mode (mri)
143      int mri;
144 {
145   macro_mri = mri;
146 }
147
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.  */
153
154 int
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 *));
160 {
161   int from_len = strlen (from);
162   int to_len = strlen (to);
163   int depth = 1;
164   int line_start = ptr->len;
165
166   int more = get_line (ptr);
167
168   while (more)
169     {
170       /* Try and find the first pseudo op on the line.  */
171       int i = line_start;
172
173       if (! macro_alternate && ! macro_mri)
174         {
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.  */
179
180           /* Skip leading whitespace.  */
181           while (i < ptr->len && ISWHITE (ptr->ptr[i]))
182             i++;
183
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++;
190
191           /* And a colon.  */
192           if (i < ptr->len
193               && ptr->ptr[i] == ':')
194             i++;
195
196         }
197       /* Skip trailing whitespace.  */
198       while (i < ptr->len && ISWHITE (ptr->ptr[i]))
199         i++;
200
201       if (i < ptr->len && (ptr->ptr[i] == '.'
202                            || macro_alternate
203                            || macro_mri))
204         {
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])))
214             {
215               depth--;
216               if (depth == 0)
217                 {
218                   /* Reset the string to not include the ending rune.  */
219                   ptr->len = line_start;
220                   break;
221                 }
222             }
223         }
224
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);
229     }
230
231   /* Return 1 on success, 0 on unexpected EOF.  */
232   return depth == 0;
233 }
234
235 /* Pick up a token.  */
236
237 static int
238 get_token (idx, in, name)
239      int idx;
240      sb *in;
241      sb *name;
242 {
243   if (idx < in->len
244       && (ISALPHA (in->ptr[idx])
245           || in->ptr[idx] == '_'
246           || in->ptr[idx] == '$'))
247     {
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] == '$'))
253         {
254           sb_add_char (name, in->ptr[idx++]);
255         }
256     }
257   /* Ignore trailing &.  */
258   if (macro_alternate && idx < in->len && in->ptr[idx] == '&')
259     idx++;
260   return idx;
261 }
262
263 /* Pick up a string.  */
264
265 static int
266 getstring (idx, in, acc)
267      int idx;
268      sb *in;
269      sb *acc;
270 {
271   idx = sb_skip_white (idx, in);
272
273   while (idx < in->len
274          && (in->ptr[idx] == '"'
275              || (in->ptr[idx] == '<' && (macro_alternate || macro_mri))
276              || (in->ptr[idx] == '\'' && macro_alternate)))
277     {
278       if (in->ptr[idx] == '<')
279         {
280           int nest = 0;
281           idx++;
282           while ((in->ptr[idx] != '>' || nest)
283                  && idx < in->len)
284             {
285               if (in->ptr[idx] == '!')
286                 {
287                   idx++;
288                   sb_add_char (acc, in->ptr[idx++]);
289                 }
290               else
291                 {
292                   if (in->ptr[idx] == '>')
293                     nest--;
294                   if (in->ptr[idx] == '<')
295                     nest++;
296                   sb_add_char (acc, in->ptr[idx++]);
297                 }
298             }
299           idx++;
300         }
301       else if (in->ptr[idx] == '"' || in->ptr[idx] == '\'')
302         {
303           char tchar = in->ptr[idx];
304           int escaped = 0;
305
306           idx++;
307
308           while (idx < in->len)
309             {
310               if (in->ptr[idx - 1] == '\\')
311                 escaped ^= 1;
312               else
313                 escaped = 0;
314
315               if (macro_alternate && in->ptr[idx] == '!')
316                 {
317                   idx ++;
318
319                   sb_add_char (acc, in->ptr[idx]);
320
321                   idx ++;
322                 }
323               else if (escaped && in->ptr[idx] == tchar)
324                 {
325                   sb_add_char (acc, tchar);
326                   idx ++;
327                 }
328               else
329                 {
330                   if (in->ptr[idx] == tchar)
331                     {
332                       idx ++;
333
334                       if (idx >= in->len || in->ptr[idx] != tchar)
335                         break;
336                     }
337
338                   sb_add_char (acc, in->ptr[idx]);
339                   idx ++;
340                 }
341             }
342         }
343     }
344
345   return idx;
346 }
347
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
354 */
355
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;
363 {
364   sb_reset (out);
365   idx = sb_skip_white (idx, in);
366
367   if (idx < in->len)
368     {
369       if (in->len > idx + 2 && in->ptr[idx + 1] == '\'' && ISBASE (in->ptr[idx]))
370         {
371           while (!ISSEP (in->ptr[idx]))
372             sb_add_char (out, in->ptr[idx++]);
373         }
374       else if (in->ptr[idx] == '%'
375                && macro_alternate
376                && expand)
377         {
378           int val;
379           char buf[20];
380           /* Turns the next expression into a string.  */
381           /* xgettext: no-c-format */
382           idx = (*macro_expr) (_("% operator needs absolute expression"),
383                                idx + 1,
384                                in,
385                                &val);
386           sprintf (buf, "%d", val);
387           sb_add_string (out, buf);
388         }
389       else if (in->ptr[idx] == '"'
390                || (in->ptr[idx] == '<' && (macro_alternate || macro_mri))
391                || (macro_alternate && in->ptr[idx] == '\''))
392         {
393           if (macro_alternate
394               && ! macro_strip_at
395               && expand)
396             {
397               /* Keep the quotes.  */
398               sb_add_char (out, '\"');
399
400               idx = getstring (idx, in, out);
401               sb_add_char (out, '\"');
402             }
403           else
404             {
405               idx = getstring (idx, in, out);
406             }
407         }
408       else
409         {
410           while (idx < in->len
411                  && (in->ptr[idx] == '"'
412                      || in->ptr[idx] == '\''
413                      || pretend_quoted
414                      || (in->ptr[idx] != ' '
415                          && in->ptr[idx] != '\t'
416                          && in->ptr[idx] != ','
417                          && (in->ptr[idx] != '<'
418                              || (! macro_alternate && ! macro_mri)))))
419             {
420               if (in->ptr[idx] == '"'
421                   || in->ptr[idx] == '\'')
422                 {
423                   char tchar = in->ptr[idx];
424                   sb_add_char (out, in->ptr[idx++]);
425                   while (idx < in->len
426                          && in->ptr[idx] != tchar)
427                     sb_add_char (out, in->ptr[idx++]);
428                   if (idx == in->len)
429                     return idx;
430                 }
431               sb_add_char (out, in->ptr[idx++]);
432             }
433         }
434     }
435
436   return idx;
437 }
438
439 /* Pick up the formal parameters of a macro definition.  */
440
441 static int
442 do_formals (macro, idx, in)
443      macro_entry *macro;
444      int idx;
445      sb *in;
446 {
447   formal_entry **p = &macro->formals;
448
449   macro->formal_count = 0;
450   macro->formal_hash = hash_new ();
451   while (idx < in->len)
452     {
453       formal_entry *formal;
454
455       formal = (formal_entry *) xmalloc (sizeof (formal_entry));
456
457       sb_new (&formal->name);
458       sb_new (&formal->def);
459       sb_new (&formal->actual);
460
461       idx = sb_skip_white (idx, in);
462       idx = get_token (idx, in, &formal->name);
463       if (formal->name.len == 0)
464         break;
465       idx = sb_skip_white (idx, in);
466       if (formal->name.len)
467         {
468           /* This is a formal.  */
469           if (idx < in->len && in->ptr[idx] == '=')
470             {
471               /* Got a default.  */
472               idx = get_any_string (idx + 1, in, &formal->def, 1, 0);
473             }
474         }
475
476       /* Add to macro's hash table.  */
477       hash_jam (macro->formal_hash, sb_terminate (&formal->name), formal);
478
479       formal->index = macro->formal_count;
480       idx = sb_skip_comma (idx, in);
481       macro->formal_count++;
482       *p = formal;
483       p = &formal->next;
484       *p = NULL;
485     }
486
487   if (macro_mri)
488     {
489       formal_entry *formal;
490       const char *name;
491
492       /* Add a special NARG formal, which macro_expand will set to the
493          number of arguments.  */
494       formal = (formal_entry *) xmalloc (sizeof (formal_entry));
495
496       sb_new (&formal->name);
497       sb_new (&formal->def);
498       sb_new (&formal->actual);
499
500       /* The same MRI assemblers which treat '@' characters also use
501          the name $NARG.  At least until we find an exception.  */
502       if (macro_strip_at)
503         name = "$NARG";
504       else
505         name = "NARG";
506
507       sb_add_string (&formal->name, name);
508
509       /* Add to macro's hash table.  */
510       hash_jam (macro->formal_hash, name, formal);
511
512       formal->index = NARG_INDEX;
513       *p = formal;
514       formal->next = NULL;
515     }
516
517   return idx;
518 }
519
520 /* Define a new macro.  Returns NULL on success, otherwise returns an
521    error message.  If NAMEP is not NULL, *NAMEP is set to the name of
522    the macro which was defined.  */
523
524 const char *
525 define_macro (idx, in, label, get_line, namep)
526      int idx;
527      sb *in;
528      sb *label;
529      int (*get_line) PARAMS ((sb *));
530      const char **namep;
531 {
532   macro_entry *macro;
533   sb name;
534   const char *namestr;
535
536   macro = (macro_entry *) xmalloc (sizeof (macro_entry));
537   sb_new (&macro->sub);
538   sb_new (&name);
539
540   macro->formal_count = 0;
541   macro->formals = 0;
542
543   idx = sb_skip_white (idx, in);
544   if (! buffer_and_nest ("MACRO", "ENDM", &macro->sub, get_line))
545     return _("unexpected end of file in macro definition");
546   if (label != NULL && label->len != 0)
547     {
548       sb_add_sb (&name, label);
549       if (idx < in->len && in->ptr[idx] == '(')
550         {
551           /* It's the label: MACRO (formals,...)  sort  */
552           idx = do_formals (macro, idx + 1, in);
553           if (in->ptr[idx] != ')')
554             return _("missing ) after formals");
555         }
556       else
557         {
558           /* It's the label: MACRO formals,...  sort  */
559           idx = do_formals (macro, idx, in);
560         }
561     }
562   else
563     {
564       idx = get_token (idx, in, &name);
565       idx = sb_skip_comma (idx, in);
566       idx = do_formals (macro, idx, in);
567     }
568
569   /* And stick it in the macro hash table.  */
570   for (idx = 0; idx < name.len; idx++)
571     name.ptr[idx] = TOLOWER (name.ptr[idx]);
572   namestr = sb_terminate (&name);
573   hash_jam (macro_hash, namestr, (PTR) macro);
574
575   macro_defined = 1;
576
577   if (namep != NULL)
578     *namep = namestr;
579
580   return NULL;
581 }
582
583 /* Scan a token, and then skip KIND.  */
584
585 static int
586 get_apost_token (idx, in, name, kind)
587      int idx;
588      sb *in;
589      sb *name;
590      int kind;
591 {
592   idx = get_token (idx, in, name);
593   if (idx < in->len
594       && in->ptr[idx] == kind
595       && (! macro_mri || macro_strip_at)
596       && (! macro_strip_at || kind == '@'))
597     idx++;
598   return idx;
599 }
600
601 /* Substitute the actual value for a formal parameter.  */
602
603 static int
604 sub_actual (start, in, t, formal_hash, kind, out, copyifnotthere)
605      int start;
606      sb *in;
607      sb *t;
608      struct hash_control *formal_hash;
609      int kind;
610      sb *out;
611      int copyifnotthere;
612 {
613   int src;
614   formal_entry *ptr;
615
616   src = get_apost_token (start, in, t, kind);
617   /* See if it's in the macro's hash table, unless this is
618      macro_strip_at and kind is '@' and the token did not end in '@'.  */
619   if (macro_strip_at
620       && kind == '@'
621       && (src == start || in->ptr[src - 1] != '@'))
622     ptr = NULL;
623   else
624     ptr = (formal_entry *) hash_find (formal_hash, sb_terminate (t));
625   if (ptr)
626     {
627       if (ptr->actual.len)
628         {
629           sb_add_sb (out, &ptr->actual);
630         }
631       else
632         {
633           sb_add_sb (out, &ptr->def);
634         }
635     }
636   else if (kind == '&')
637     {
638       /* Doing this permits people to use & in macro bodies.  */
639       sb_add_char (out, '&');
640     }
641   else if (copyifnotthere)
642     {
643       sb_add_sb (out, t);
644     }
645   else
646     {
647       sb_add_char (out, '\\');
648       sb_add_sb (out, t);
649     }
650   return src;
651 }
652
653 /* Expand the body of a macro.  */
654
655 static const char *
656 macro_expand_body (in, out, formals, formal_hash, locals)
657      sb *in;
658      sb *out;
659      formal_entry *formals;
660      struct hash_control *formal_hash;
661      int locals;
662 {
663   sb t;
664   int src = 0;
665   int inquote = 0;
666   formal_entry *loclist = NULL;
667
668   sb_new (&t);
669
670   while (src < in->len)
671     {
672       if (in->ptr[src] == '&')
673         {
674           sb_reset (&t);
675           if (macro_mri)
676             {
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++]);
681             }
682           else
683             {
684               /* FIXME: Why do we do this?  */
685               src = sub_actual (src + 1, in, &t, formal_hash, '&', out, 0);
686             }
687         }
688       else if (in->ptr[src] == '\\')
689         {
690           src++;
691           if (in->ptr[src] == '(')
692             {
693               /* Sub in till the next ')' literally.  */
694               src++;
695               while (src < in->len && in->ptr[src] != ')')
696                 {
697                   sb_add_char (out, in->ptr[src++]);
698                 }
699               if (in->ptr[src] == ')')
700                 src++;
701               else
702                 return _("missplaced )");
703             }
704           else if (in->ptr[src] == '@')
705             {
706               /* Sub in the macro invocation number.  */
707
708               char buffer[10];
709               src++;
710               sprintf (buffer, "%d", macro_number);
711               sb_add_string (out, buffer);
712             }
713           else if (in->ptr[src] == '&')
714             {
715               /* This is a preprocessor variable name, we don't do them
716                  here.  */
717               sb_add_char (out, '\\');
718               sb_add_char (out, '&');
719               src++;
720             }
721           else if (macro_mri && ISALNUM (in->ptr[src]))
722             {
723               int ind;
724               formal_entry *f;
725
726               if (ISDIGIT (in->ptr[src]))
727                 ind = in->ptr[src] - '0';
728               else if (ISUPPER (in->ptr[src]))
729                 ind = in->ptr[src] - 'A' + 10;
730               else
731                 ind = in->ptr[src] - 'a' + 10;
732               ++src;
733               for (f = formals; f != NULL; f = f->next)
734                 {
735                   if (f->index == ind - 1)
736                     {
737                       if (f->actual.len != 0)
738                         sb_add_sb (out, &f->actual);
739                       else
740                         sb_add_sb (out, &f->def);
741                       break;
742                     }
743                 }
744             }
745           else
746             {
747               sb_reset (&t);
748               src = sub_actual (src, in, &t, formal_hash, '\'', out, 0);
749             }
750         }
751       else if ((macro_alternate || macro_mri)
752                && (ISALPHA (in->ptr[src])
753                    || in->ptr[src] == '_'
754                    || in->ptr[src] == '$')
755                && (! inquote
756                    || ! macro_strip_at
757                    || (src > 0 && in->ptr[src - 1] == '@')))
758         {
759           if (! locals
760               || src + 5 >= in->len
761               || strncasecmp (in->ptr + src, "LOCAL", 5) != 0
762               || ! ISWHITE (in->ptr[src + 5]))
763             {
764               sb_reset (&t);
765               src = sub_actual (src, in, &t, formal_hash,
766                                 (macro_strip_at && inquote) ? '@' : '\'',
767                                 out, 1);
768             }
769           else
770             {
771               formal_entry *f;
772
773               src = sb_skip_white (src + 5, in);
774               while (in->ptr[src] != '\n')
775                 {
776                   static int loccnt;
777                   char buf[20];
778                   const char *err;
779
780                   f = (formal_entry *) xmalloc (sizeof (formal_entry));
781                   sb_new (&f->name);
782                   sb_new (&f->def);
783                   sb_new (&f->actual);
784                   f->index = LOCAL_INDEX;
785                   f->next = loclist;
786                   loclist = f;
787
788                   src = get_token (src, in, &f->name);
789                   ++loccnt;
790                   sprintf (buf, "LL%04x", loccnt);
791                   sb_add_string (&f->actual, buf);
792
793                   err = hash_jam (formal_hash, sb_terminate (&f->name), f);
794                   if (err != NULL)
795                     return err;
796
797                   src = sb_skip_comma (src, in);
798                 }
799             }
800         }
801       else if (in->ptr[src] == '"'
802                || (macro_mri && in->ptr[src] == '\''))
803         {
804           inquote = !inquote;
805           sb_add_char (out, in->ptr[src++]);
806         }
807       else if (in->ptr[src] == '@' && macro_strip_at)
808         {
809           ++src;
810           if (src < in->len
811               && in->ptr[src] == '@')
812             {
813               sb_add_char (out, '@');
814               ++src;
815             }
816         }
817       else if (macro_mri
818                && in->ptr[src] == '='
819                && src + 1 < in->len
820                && in->ptr[src + 1] == '=')
821         {
822           formal_entry *ptr;
823
824           sb_reset (&t);
825           src = get_token (src + 2, in, &t);
826           ptr = (formal_entry *) hash_find (formal_hash, sb_terminate (&t));
827           if (ptr == NULL)
828             {
829               /* FIXME: We should really return a warning string here,
830                  but we can't, because the == might be in the MRI
831                  comment field, and, since the nature of the MRI
832                  comment field depends upon the exact instruction
833                  being used, we don't have enough information here to
834                  figure out whether it is or not.  Instead, we leave
835                  the == in place, which should cause a syntax error if
836                  it is not in a comment.  */
837               sb_add_char (out, '=');
838               sb_add_char (out, '=');
839               sb_add_sb (out, &t);
840             }
841           else
842             {
843               if (ptr->actual.len)
844                 {
845                   sb_add_string (out, "-1");
846                 }
847               else
848                 {
849                   sb_add_char (out, '0');
850                 }
851             }
852         }
853       else
854         {
855           sb_add_char (out, in->ptr[src++]);
856         }
857     }
858
859   sb_kill (&t);
860
861   while (loclist != NULL)
862     {
863       formal_entry *f;
864
865       f = loclist->next;
866       /* Setting the value to NULL effectively deletes the entry.  We
867          avoid calling hash_delete because it doesn't reclaim memory.  */
868       hash_jam (formal_hash, sb_terminate (&loclist->name), NULL);
869       sb_kill (&loclist->name);
870       sb_kill (&loclist->def);
871       sb_kill (&loclist->actual);
872       free (loclist);
873       loclist = f;
874     }
875
876   return NULL;
877 }
878
879 /* Assign values to the formal parameters of a macro, and expand the
880    body.  */
881
882 static const char *
883 macro_expand (idx, in, m, out)
884      int idx;
885      sb *in;
886      macro_entry *m;
887      sb *out;
888 {
889   sb t;
890   formal_entry *ptr;
891   formal_entry *f;
892   int is_positional = 0;
893   int is_keyword = 0;
894   int narg = 0;
895   const char *err;
896
897   sb_new (&t);
898
899   /* Reset any old value the actuals may have.  */
900   for (f = m->formals; f; f = f->next)
901     sb_reset (&f->actual);
902   f = m->formals;
903   while (f != NULL && f->index < 0)
904     f = f->next;
905
906   if (macro_mri)
907     {
908       /* The macro may be called with an optional qualifier, which may
909          be referred to in the macro body as \0.  */
910       if (idx < in->len && in->ptr[idx] == '.')
911         {
912           /* The Microtec assembler ignores this if followed by a white space.
913              (Macro invocation with empty extension) */
914           idx++;
915           if (    idx < in->len
916                   && in->ptr[idx] != ' '
917                   && in->ptr[idx] != '\t')
918             {
919               formal_entry *n;
920
921               n = (formal_entry *) xmalloc (sizeof (formal_entry));
922               sb_new (&n->name);
923               sb_new (&n->def);
924               sb_new (&n->actual);
925               n->index = QUAL_INDEX;
926
927               n->next = m->formals;
928               m->formals = n;
929
930               idx = get_any_string (idx, in, &n->actual, 1, 0);
931             }
932         }
933     }
934
935   /* Peel off the actuals and store them away in the hash tables' actuals.  */
936   idx = sb_skip_white (idx, in);
937   while (idx < in->len)
938     {
939       int scan;
940
941       /* Look and see if it's a positional or keyword arg.  */
942       scan = idx;
943       while (scan < in->len
944              && !ISSEP (in->ptr[scan])
945              && !(macro_mri && in->ptr[scan] == '\'')
946              && (!macro_alternate && in->ptr[scan] != '='))
947         scan++;
948       if (scan < in->len && !macro_alternate && in->ptr[scan] == '=')
949         {
950           is_keyword = 1;
951
952           /* It's OK to go from positional to keyword.  */
953
954           /* This is a keyword arg, fetch the formal name and
955              then the actual stuff.  */
956           sb_reset (&t);
957           idx = get_token (idx, in, &t);
958           if (in->ptr[idx] != '=')
959             return _("confusion in formal parameters");
960
961           /* Lookup the formal in the macro's list.  */
962           ptr = (formal_entry *) hash_find (m->formal_hash, sb_terminate (&t));
963           if (!ptr)
964             return _("macro formal argument does not exist");
965           else
966             {
967               /* Insert this value into the right place.  */
968               sb_reset (&ptr->actual);
969               idx = get_any_string (idx + 1, in, &ptr->actual, 0, 0);
970               if (ptr->actual.len > 0)
971                 ++narg;
972             }
973         }
974       else
975         {
976           /* This is a positional arg.  */
977           is_positional = 1;
978           if (is_keyword)
979             return _("can't mix positional and keyword arguments");
980
981           if (!f)
982             {
983               formal_entry **pf;
984               int c;
985
986               if (!macro_mri)
987                 return _("too many positional arguments");
988
989               f = (formal_entry *) xmalloc (sizeof (formal_entry));
990               sb_new (&f->name);
991               sb_new (&f->def);
992               sb_new (&f->actual);
993               f->next = NULL;
994
995               c = -1;
996               for (pf = &m->formals; *pf != NULL; pf = &(*pf)->next)
997                 if ((*pf)->index >= c)
998                   c = (*pf)->index + 1;
999               if (c == -1)
1000                 c = 0;
1001               *pf = f;
1002               f->index = c;
1003             }
1004
1005           sb_reset (&f->actual);
1006           idx = get_any_string (idx, in, &f->actual, 1, 0);
1007           if (f->actual.len > 0)
1008             ++narg;
1009           do
1010             {
1011               f = f->next;
1012             }
1013           while (f != NULL && f->index < 0);
1014         }
1015
1016       if (! macro_mri)
1017         idx = sb_skip_comma (idx, in);
1018       else
1019         {
1020           if (in->ptr[idx] == ',')
1021             ++idx;
1022           if (ISWHITE (in->ptr[idx]))
1023             break;
1024         }
1025     }
1026
1027   if (macro_mri)
1028     {
1029       char buffer[20];
1030
1031       sb_reset (&t);
1032       sb_add_string (&t, macro_strip_at ? "$NARG" : "NARG");
1033       ptr = (formal_entry *) hash_find (m->formal_hash, sb_terminate (&t));
1034       sb_reset (&ptr->actual);
1035       sprintf (buffer, "%d", narg);
1036       sb_add_string (&ptr->actual, buffer);
1037     }
1038
1039   err = macro_expand_body (&m->sub, out, m->formals, m->formal_hash, 1);
1040   if (err != NULL)
1041     return err;
1042
1043   /* Discard any unnamed formal arguments.  */
1044   if (macro_mri)
1045     {
1046       formal_entry **pf;
1047
1048       pf = &m->formals;
1049       while (*pf != NULL)
1050         {
1051           if ((*pf)->name.len != 0)
1052             pf = &(*pf)->next;
1053           else
1054             {
1055               sb_kill (&(*pf)->name);
1056               sb_kill (&(*pf)->def);
1057               sb_kill (&(*pf)->actual);
1058               f = (*pf)->next;
1059               free (*pf);
1060               *pf = f;
1061             }
1062         }
1063     }
1064
1065   sb_kill (&t);
1066   macro_number++;
1067
1068   return NULL;
1069 }
1070
1071 /* Check for a macro.  If one is found, put the expansion into
1072    *EXPAND.  Return 1 if a macro is found, 0 otherwise.  */
1073
1074 int
1075 check_macro (line, expand, error, info)
1076      const char *line;
1077      sb *expand;
1078      const char **error;
1079      macro_entry **info;
1080 {
1081   const char *s;
1082   char *copy, *cs;
1083   macro_entry *macro;
1084   sb line_sb;
1085
1086   if (! ISALPHA (*line)
1087       && *line != '_'
1088       && *line != '$'
1089       && (! macro_mri || *line != '.'))
1090     return 0;
1091
1092   s = line + 1;
1093   while (ISALNUM (*s)
1094          || *s == '_'
1095          || *s == '$')
1096     ++s;
1097
1098   copy = (char *) alloca (s - line + 1);
1099   memcpy (copy, line, s - line);
1100   copy[s - line] = '\0';
1101   for (cs = copy; *cs != '\0'; cs++)
1102     *cs = TOLOWER (*cs);
1103
1104   macro = (macro_entry *) hash_find (macro_hash, copy);
1105
1106   if (macro == NULL)
1107     return 0;
1108
1109   /* Wrap the line up in an sb.  */
1110   sb_new (&line_sb);
1111   while (*s != '\0' && *s != '\n' && *s != '\r')
1112     sb_add_char (&line_sb, *s++);
1113
1114   sb_new (expand);
1115   *error = macro_expand (0, &line_sb, macro, expand);
1116
1117   sb_kill (&line_sb);
1118
1119   /* Export the macro information if requested.  */
1120   if (info)
1121     *info = macro;
1122
1123   return 1;
1124 }
1125
1126 /* Delete a macro.  */
1127
1128 void
1129 delete_macro (name)
1130      const char *name;
1131 {
1132   hash_delete (macro_hash, name);
1133 }
1134
1135 /* Handle the MRI IRP and IRPC pseudo-ops.  These are handled as a
1136    combined macro definition and execution.  This returns NULL on
1137    success, or an error message otherwise.  */
1138
1139 const char *
1140 expand_irp (irpc, idx, in, out, get_line)
1141      int irpc;
1142      int idx;
1143      sb *in;
1144      sb *out;
1145      int (*get_line) PARAMS ((sb *));
1146 {
1147   const char *mn;
1148   sb sub;
1149   formal_entry f;
1150   struct hash_control *h;
1151   const char *err;
1152
1153   if (irpc)
1154     mn = "IRPC";
1155   else
1156     mn = "IRP";
1157
1158   idx = sb_skip_white (idx, in);
1159
1160   sb_new (&sub);
1161   if (! buffer_and_nest (mn, "ENDR", &sub, get_line))
1162     return _("unexpected end of file in irp or irpc");
1163
1164   sb_new (&f.name);
1165   sb_new (&f.def);
1166   sb_new (&f.actual);
1167
1168   idx = get_token (idx, in, &f.name);
1169   if (f.name.len == 0)
1170     return _("missing model parameter");
1171
1172   h = hash_new ();
1173   err = hash_jam (h, sb_terminate (&f.name), &f);
1174   if (err != NULL)
1175     return err;
1176
1177   f.index = 1;
1178   f.next = NULL;
1179
1180   sb_reset (out);
1181
1182   idx = sb_skip_comma (idx, in);
1183   if (idx >= in->len)
1184     {
1185       /* Expand once with a null string.  */
1186       err = macro_expand_body (&sub, out, &f, h, 0);
1187       if (err != NULL)
1188         return err;
1189     }
1190   else
1191     {
1192       if (irpc && in->ptr[idx] == '"')
1193         ++idx;
1194       while (idx < in->len)
1195         {
1196           if (!irpc)
1197             idx = get_any_string (idx, in, &f.actual, 1, 0);
1198           else
1199             {
1200               if (in->ptr[idx] == '"')
1201                 {
1202                   int nxt;
1203
1204                   nxt = sb_skip_white (idx + 1, in);
1205                   if (nxt >= in->len)
1206                     {
1207                       idx = nxt;
1208                       break;
1209                     }
1210                 }
1211               sb_reset (&f.actual);
1212               sb_add_char (&f.actual, in->ptr[idx]);
1213               ++idx;
1214             }
1215           err = macro_expand_body (&sub, out, &f, h, 0);
1216           if (err != NULL)
1217             return err;
1218           if (!irpc)
1219             idx = sb_skip_comma (idx, in);
1220           else
1221             idx = sb_skip_white (idx, in);
1222         }
1223     }
1224
1225   hash_die (h);
1226   sb_kill (&sub);
1227
1228   return NULL;
1229 }