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