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