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