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