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