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