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