xref: /netbsd-src/external/gpl3/binutils.old/dist/gas/macro.c (revision e992f068c547fd6e84b3f104dc2340adcc955732)
1 /* macro.c - macro support for gas
2    Copyright (C) 1994-2022 Free Software Foundation, Inc.
3 
4    Written by Steve and Judy Chamberlain of Cygnus Support,
5       sac@cygnus.com
6 
7    This file is part of GAS, the GNU Assembler.
8 
9    GAS is free software; you can redistribute it and/or modify
10    it under the terms of the GNU General Public License as published by
11    the Free Software Foundation; either version 3, or (at your option)
12    any later version.
13 
14    GAS is distributed in the hope that it will be useful,
15    but WITHOUT ANY WARRANTY; without even the implied warranty of
16    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17    GNU General Public License for more details.
18 
19    You should have received a copy of the GNU General Public License
20    along with GAS; see the file COPYING.  If not, write to the Free
21    Software Foundation, 51 Franklin Street - Fifth Floor, Boston, MA
22    02110-1301, USA.  */
23 
24 #include "as.h"
25 #include "safe-ctype.h"
26 #include "sb.h"
27 #include "macro.h"
28 
29 /* The routines in this file handle macro definition and expansion.
30    They are called by gas.  */
31 
32 #define ISWHITE(x) ((x) == ' ' || (x) == '\t')
33 
34 #define ISSEP(x) \
35  ((x) == ' ' || (x) == '\t' || (x) == ',' || (x) == '"' || (x) == ';' \
36   || (x) == ')' || (x) == '(' \
37   || ((macro_alternate || macro_mri) && ((x) == '<' || (x) == '>')))
38 
39 #define ISBASE(x) \
40   ((x) == 'b' || (x) == 'B' \
41    || (x) == 'q' || (x) == 'Q' \
42    || (x) == 'h' || (x) == 'H' \
43    || (x) == 'd' || (x) == 'D')
44 
45 /* The macro hash table.  */
46 
47 struct htab *macro_hash;
48 
49 /* Whether any macros have been defined.  */
50 
51 int macro_defined;
52 
53 /* Whether we are in alternate syntax mode.  */
54 
55 static int macro_alternate;
56 
57 /* Whether we are in MRI mode.  */
58 
59 static int macro_mri;
60 
61 /* Whether we should strip '@' characters.  */
62 
63 static int macro_strip_at;
64 
65 /* Function to use to parse an expression.  */
66 
67 static size_t (*macro_expr) (const char *, size_t, sb *, offsetT *);
68 
69 /* Number of macro expansions that have been done.  */
70 
71 static int macro_number;
72 
73 /* Initialize macro processing.  */
74 
75 void
macro_init(int alternate,int mri,int strip_at,size_t (* exp)(const char *,size_t,sb *,offsetT *))76 macro_init (int alternate, int mri, int strip_at,
77 	    size_t (*exp) (const char *, size_t, sb *, offsetT *))
78 {
79   macro_hash = htab_create_alloc (16, hash_macro_entry, eq_macro_entry,
80 				  NULL, xcalloc, free);
81   macro_defined = 0;
82   macro_alternate = alternate;
83   macro_mri = mri;
84   macro_strip_at = strip_at;
85   macro_expr = exp;
86 }
87 
88 /* Switch in and out of alternate mode on the fly.  */
89 
90 void
macro_set_alternate(int alternate)91 macro_set_alternate (int alternate)
92 {
93   macro_alternate = alternate;
94 }
95 
96 /* Switch in and out of MRI mode on the fly.  */
97 
98 void
macro_mri_mode(int mri)99 macro_mri_mode (int mri)
100 {
101   macro_mri = mri;
102 }
103 
104 /* Read input lines till we get to a TO string.
105    Increase nesting depth if we get a FROM string.
106    Put the results into sb at PTR.
107    FROM may be NULL (or will be ignored) if TO is "ENDR".
108    Add a new input line to an sb using GET_LINE.
109    Return 1 on success, 0 on unexpected EOF.  */
110 
111 int
buffer_and_nest(const char * from,const char * to,sb * ptr,size_t (* get_line)(sb *))112 buffer_and_nest (const char *from, const char *to, sb *ptr,
113 		 size_t (*get_line) (sb *))
114 {
115   size_t from_len;
116   size_t to_len = strlen (to);
117   int depth = 1;
118   size_t line_start = ptr->len;
119   size_t more = get_line (ptr);
120 
121   if (to_len == 4 && strcasecmp (to, "ENDR") == 0)
122     {
123       from = NULL;
124       from_len = 0;
125     }
126   else
127     from_len = strlen (from);
128 
129   /* Except for macros record the present source position, such that
130      diagnostics and debug info will be properly associated with the
131      respective original lines, rather than with the line of the ending
132      directive (TO).  */
133   if (from == NULL || strcasecmp (from, "MACRO") != 0)
134     {
135       unsigned int line;
136       char *linefile;
137 
138       as_where (&line);
139       if (!flag_m68k_mri)
140 	linefile = xasprintf ("\t.linefile %u .\n", line);
141       else
142 	linefile = xasprintf ("\tlinefile %u .\n", line);
143       sb_add_buffer (ptr, linefile, strlen (linefile));
144       xfree (linefile);
145     }
146 
147   while (more)
148     {
149       /* Try to find the first pseudo op on the line.  */
150       size_t i = line_start;
151       bool had_colon = false;
152 
153       /* With normal syntax we can suck what we want till we get
154 	 to the dot.  With the alternate, labels have to start in
155 	 the first column, since we can't tell what's a label and
156 	 what's a pseudoop.  */
157 
158       if (! LABELS_WITHOUT_COLONS)
159 	{
160 	  /* Skip leading whitespace.  */
161 	  while (i < ptr->len && ISWHITE (ptr->ptr[i]))
162 	    i++;
163 	}
164 
165       for (;;)
166 	{
167 	  /* Skip over a label, if any.  */
168 	  if (i >= ptr->len || ! is_name_beginner (ptr->ptr[i]))
169 	    break;
170 	  i++;
171 	  while (i < ptr->len && is_part_of_name (ptr->ptr[i]))
172 	    i++;
173 	  if (i < ptr->len && is_name_ender (ptr->ptr[i]))
174 	    i++;
175 	  /* Skip whitespace.  */
176 	  while (i < ptr->len && ISWHITE (ptr->ptr[i]))
177 	    i++;
178 	  /* Check for the colon.  */
179 	  if (i >= ptr->len || ptr->ptr[i] != ':')
180 	    {
181 	      /* LABELS_WITHOUT_COLONS doesn't mean we cannot have a
182 		 colon after a label.  If we do have a colon on the
183 		 first label then handle more than one label on the
184 		 line, assuming that each label has a colon.  */
185 	      if (LABELS_WITHOUT_COLONS && !had_colon)
186 		break;
187 	      i = line_start;
188 	      break;
189 	    }
190 	  i++;
191 	  line_start = i;
192 	  had_colon = true;
193 	}
194 
195       /* Skip trailing whitespace.  */
196       while (i < ptr->len && ISWHITE (ptr->ptr[i]))
197 	i++;
198 
199       if (i < ptr->len && (ptr->ptr[i] == '.'
200 			   || NO_PSEUDO_DOT
201 			   || macro_mri))
202 	{
203 	  if (! flag_m68k_mri && ptr->ptr[i] == '.')
204 	    i++;
205 	  size_t len = ptr->len - i;
206 	  if (from == NULL)
207 	    {
208 	      if (len >= 5 && strncasecmp (ptr->ptr + i, "IREPC", 5) == 0)
209 		from_len = 5;
210 	      else if (len >= 4 && strncasecmp (ptr->ptr + i, "IREP", 4) == 0)
211 		from_len = 4;
212 	      else if (len >= 4 && strncasecmp (ptr->ptr + i, "IRPC", 4) == 0)
213 		from_len = 4;
214 	      else if (len >= 4 && strncasecmp (ptr->ptr + i, "REPT", 4) == 0)
215 		from_len = 4;
216 	      else if (len >= 3 && strncasecmp (ptr->ptr + i, "IRP", 3) == 0)
217 		from_len = 3;
218 	      else if (len >= 3 && strncasecmp (ptr->ptr + i, "REP", 3) == 0)
219 		from_len = 3;
220 	      else
221 		from_len = 0;
222 	    }
223 	  if ((from != NULL
224 	       ? (len >= from_len
225 		  && strncasecmp (ptr->ptr + i, from, from_len) == 0)
226 	       : from_len > 0)
227 	      && (len == from_len
228 		  || ! (is_part_of_name (ptr->ptr[i + from_len])
229 			|| is_name_ender (ptr->ptr[i + from_len]))))
230 	    depth++;
231 	  if (len >= to_len
232 	      && strncasecmp (ptr->ptr + i, to, to_len) == 0
233 	      && (len == to_len
234 		  || ! (is_part_of_name (ptr->ptr[i + to_len])
235 			|| is_name_ender (ptr->ptr[i + to_len]))))
236 	    {
237 	      depth--;
238 	      if (depth == 0)
239 		{
240 		  /* Reset the string to not include the ending rune.  */
241 		  ptr->len = line_start;
242 		  break;
243 		}
244 	    }
245 
246 	  /* PR gas/16908
247 	     Apply and discard .linefile directives that appear within
248 	     the macro.  For long macros, one might want to report the
249 	     line number information associated with the lines within
250 	     the macro definition, but we would need more infrastructure
251 	     to make that happen correctly (e.g. resetting the line
252 	     number when expanding the macro), and since for short
253 	     macros we clearly prefer reporting the point of expansion
254 	     anyway, there's not an obviously better fix here.  */
255 	  if (from != NULL && strcasecmp (from, "MACRO") == 0
256 	      && len >= 8 && strncasecmp (ptr->ptr + i, "linefile", 8) == 0)
257 	    {
258 	      char saved_eol_char = ptr->ptr[ptr->len];
259 
260 	      ptr->ptr[ptr->len] = '\0';
261 	      temp_ilp (ptr->ptr + i + 8);
262 	      s_linefile (0);
263 	      restore_ilp ();
264 	      ptr->ptr[ptr->len] = saved_eol_char;
265 	      ptr->len = line_start;
266 	    }
267 	}
268 
269       /* Add the original end-of-line char to the end and keep running.  */
270       sb_add_char (ptr, more);
271       line_start = ptr->len;
272       more = get_line (ptr);
273     }
274 
275   /* Return 1 on success, 0 on unexpected EOF.  */
276   return depth == 0;
277 }
278 
279 /* Pick up a token.  */
280 
281 static size_t
get_token(size_t idx,sb * in,sb * name)282 get_token (size_t idx, sb *in, sb *name)
283 {
284   if (idx < in->len
285       && is_name_beginner (in->ptr[idx]))
286     {
287       sb_add_char (name, in->ptr[idx++]);
288       while (idx < in->len
289 	     && is_part_of_name (in->ptr[idx]))
290 	{
291 	  sb_add_char (name, in->ptr[idx++]);
292 	}
293       if (idx < in->len
294 	     && is_name_ender (in->ptr[idx]))
295 	{
296 	  sb_add_char (name, in->ptr[idx++]);
297 	}
298     }
299   /* Ignore trailing &.  */
300   if (macro_alternate && idx < in->len && in->ptr[idx] == '&')
301     idx++;
302   return idx;
303 }
304 
305 /* Pick up a string.  */
306 
307 static size_t
getstring(size_t idx,sb * in,sb * acc)308 getstring (size_t idx, sb *in, sb *acc)
309 {
310   while (idx < in->len
311 	 && (in->ptr[idx] == '"'
312 	     || (in->ptr[idx] == '<' && (macro_alternate || macro_mri))
313 	     || (in->ptr[idx] == '\'' && macro_alternate)))
314     {
315       if (in->ptr[idx] == '<')
316 	{
317 	  int nest = 0;
318 	  idx++;
319 	  while (idx < in->len
320 		 && (in->ptr[idx] != '>' || nest))
321 	    {
322 	      if (in->ptr[idx] == '!')
323 		{
324 		  idx++;
325 		  sb_add_char (acc, in->ptr[idx++]);
326 		}
327 	      else
328 		{
329 		  if (in->ptr[idx] == '>')
330 		    nest--;
331 		  if (in->ptr[idx] == '<')
332 		    nest++;
333 		  sb_add_char (acc, in->ptr[idx++]);
334 		}
335 	    }
336 	  idx++;
337 	}
338       else if (in->ptr[idx] == '"' || in->ptr[idx] == '\'')
339 	{
340 	  char tchar = in->ptr[idx];
341 	  int escaped = 0;
342 
343 	  idx++;
344 
345 	  while (idx < in->len)
346 	    {
347 	      if (in->ptr[idx - 1] == '\\')
348 		escaped ^= 1;
349 	      else
350 		escaped = 0;
351 
352 	      if (macro_alternate && in->ptr[idx] == '!')
353 		{
354 		  idx ++;
355 
356 		  sb_add_char (acc, in->ptr[idx]);
357 
358 		  idx ++;
359 		}
360 	      else if (escaped && in->ptr[idx] == tchar)
361 		{
362 		  sb_add_char (acc, tchar);
363 		  idx ++;
364 		}
365 	      else
366 		{
367 		  if (in->ptr[idx] == tchar)
368 		    {
369 		      idx ++;
370 
371 		      if (idx >= in->len || in->ptr[idx] != tchar)
372 			break;
373 		    }
374 
375 		  sb_add_char (acc, in->ptr[idx]);
376 		  idx ++;
377 		}
378 	    }
379 	}
380     }
381 
382   return idx;
383 }
384 
385 /* Fetch string from the input stream,
386    rules:
387     'Bxyx<whitespace>  	-> return 'Bxyza
388     %<expr>		-> return string of decimal value of <expr>
389     "string"		-> return string
390     (string)		-> return (string-including-whitespaces)
391     xyx<whitespace>     -> return xyz.  */
392 
393 static size_t
get_any_string(size_t idx,sb * in,sb * out)394 get_any_string (size_t idx, sb *in, sb *out)
395 {
396   sb_reset (out);
397   idx = sb_skip_white (idx, in);
398 
399   if (idx < in->len)
400     {
401       if (in->len > idx + 2 && in->ptr[idx + 1] == '\'' && ISBASE (in->ptr[idx]))
402 	{
403 	  while (idx < in->len && !ISSEP (in->ptr[idx]))
404 	    sb_add_char (out, in->ptr[idx++]);
405 	}
406       else if (in->ptr[idx] == '%' && macro_alternate)
407 	{
408 	  offsetT val;
409 	  char buf[64];
410 
411 	  /* Turns the next expression into a string.  */
412 	  /* xgettext: no-c-format */
413 	  idx = (*macro_expr) (_("% operator needs absolute expression"),
414 			       idx + 1,
415 			       in,
416 			       &val);
417 	  sprintf (buf, "%" BFD_VMA_FMT "d", val);
418 	  sb_add_string (out, buf);
419 	}
420       else if (in->ptr[idx] == '"'
421 	       || (in->ptr[idx] == '<' && (macro_alternate || macro_mri))
422 	       || (macro_alternate && in->ptr[idx] == '\''))
423 	{
424 	  if (macro_alternate && ! macro_strip_at && in->ptr[idx] != '<')
425 	    {
426 	      /* Keep the quotes.  */
427 	      sb_add_char (out, '"');
428 	      idx = getstring (idx, in, out);
429 	      sb_add_char (out, '"');
430 	    }
431 	  else
432 	    {
433 	      idx = getstring (idx, in, out);
434 	    }
435 	}
436       else
437 	{
438 	  char *br_buf = XNEWVEC (char, 1);
439 	  char *in_br = br_buf;
440 
441 	  *in_br = '\0';
442 	  while (idx < in->len
443 		 && (*in_br
444 		     || (in->ptr[idx] != ' '
445 			 && in->ptr[idx] != '\t'))
446 		 && in->ptr[idx] != ','
447 		 && (in->ptr[idx] != '<'
448 		     || (! macro_alternate && ! macro_mri)))
449 	    {
450 	      char tchar = in->ptr[idx];
451 
452 	      switch (tchar)
453 		{
454 		case '"':
455 		case '\'':
456 		  sb_add_char (out, in->ptr[idx++]);
457 		  while (idx < in->len
458 			 && in->ptr[idx] != tchar)
459 		    sb_add_char (out, in->ptr[idx++]);
460 		  if (idx == in->len)
461 		    {
462 		      free (br_buf);
463 		      return idx;
464 		    }
465 		  break;
466 		case '(':
467 		case '[':
468 		  if (in_br > br_buf)
469 		    --in_br;
470 		  else
471 		    {
472 		      br_buf = XNEWVEC (char, strlen (in_br) + 2);
473 		      strcpy (br_buf + 1, in_br);
474 		      free (in_br);
475 		      in_br = br_buf;
476 		    }
477 		  *in_br = tchar;
478 		  break;
479 		case ')':
480 		  if (*in_br == '(')
481 		    ++in_br;
482 		  break;
483 		case ']':
484 		  if (*in_br == '[')
485 		    ++in_br;
486 		  break;
487 		}
488 	      sb_add_char (out, tchar);
489 	      ++idx;
490 	    }
491 	  free (br_buf);
492 	}
493     }
494 
495   return idx;
496 }
497 
498 /* Allocate a new formal.  */
499 
500 static formal_entry *
new_formal(void)501 new_formal (void)
502 {
503   formal_entry *formal;
504 
505   formal = XNEW (formal_entry);
506 
507   sb_new (&formal->name);
508   sb_new (&formal->def);
509   sb_new (&formal->actual);
510   formal->next = NULL;
511   formal->type = FORMAL_OPTIONAL;
512   return formal;
513 }
514 
515 /* Free a formal.  */
516 
517 static void
del_formal(formal_entry * formal)518 del_formal (formal_entry *formal)
519 {
520   sb_kill (&formal->actual);
521   sb_kill (&formal->def);
522   sb_kill (&formal->name);
523   free (formal);
524 }
525 
526 /* Pick up the formal parameters of a macro definition.  */
527 
528 static size_t
do_formals(macro_entry * macro,size_t idx,sb * in)529 do_formals (macro_entry *macro, size_t idx, sb *in)
530 {
531   formal_entry **p = &macro->formals;
532   const char *name;
533 
534   idx = sb_skip_white (idx, in);
535   while (idx < in->len)
536     {
537       formal_entry *formal = new_formal ();
538       size_t cidx;
539       formal_hash_entry_t *elt;
540 
541       idx = get_token (idx, in, &formal->name);
542       if (formal->name.len == 0)
543 	{
544 	  if (macro->formal_count)
545 	    --idx;
546 	  del_formal (formal);	/* 'formal' goes out of scope.  */
547 	  break;
548 	}
549       idx = sb_skip_white (idx, in);
550       /* This is a formal.  */
551       name = sb_terminate (&formal->name);
552       if (! macro_mri
553 	  && idx < in->len
554 	  && in->ptr[idx] == ':'
555 	  && (! is_name_beginner (':')
556 	      || idx + 1 >= in->len
557 	      || ! is_part_of_name (in->ptr[idx + 1])))
558 	{
559 	  /* Got a qualifier.  */
560 	  sb qual;
561 
562 	  sb_new (&qual);
563 	  idx = get_token (sb_skip_white (idx + 1, in), in, &qual);
564 	  sb_terminate (&qual);
565 	  if (qual.len == 0)
566 	    as_bad_where (macro->file,
567 			  macro->line,
568 			  _("Missing parameter qualifier for `%s' in macro `%s'"),
569 			  name,
570 			  macro->name);
571 	  else if (strcmp (qual.ptr, "req") == 0)
572 	    formal->type = FORMAL_REQUIRED;
573 	  else if (strcmp (qual.ptr, "vararg") == 0)
574 	    formal->type = FORMAL_VARARG;
575 	  else
576 	    as_bad_where (macro->file,
577 			  macro->line,
578 			  _("`%s' is not a valid parameter qualifier for `%s' in macro `%s'"),
579 			  qual.ptr,
580 			  name,
581 			  macro->name);
582 	  sb_kill (&qual);
583 	  idx = sb_skip_white (idx, in);
584 	}
585       if (idx < in->len && in->ptr[idx] == '=')
586 	{
587 	  /* Got a default.  */
588 	  idx = get_any_string (idx + 1, in, &formal->def);
589 	  idx = sb_skip_white (idx, in);
590 	  if (formal->type == FORMAL_REQUIRED)
591 	    {
592 	      sb_reset (&formal->def);
593 	      as_warn_where (macro->file,
594 			    macro->line,
595 			    _("Pointless default value for required parameter `%s' in macro `%s'"),
596 			    name,
597 			    macro->name);
598 	    }
599 	}
600 
601       /* Add to macro's hash table.  */
602       elt = formal_entry_alloc (name, formal);
603       if (htab_insert (macro->formal_hash, elt, 0) != NULL)
604 	{
605 	  free (elt);
606 	  as_bad_where (macro->file, macro->line,
607 			_("A parameter named `%s' "
608 			  "already exists for macro `%s'"),
609 			name, macro->name);
610 	}
611 
612       formal->index = macro->formal_count++;
613       *p = formal;
614       p = &formal->next;
615       if (formal->type == FORMAL_VARARG)
616 	break;
617       cidx = idx;
618       idx = sb_skip_comma (idx, in);
619       if (idx != cidx && idx >= in->len)
620 	{
621 	  idx = cidx;
622 	  break;
623 	}
624     }
625 
626   if (macro_mri)
627     {
628       formal_entry *formal = new_formal ();
629       formal_hash_entry_t *elt;
630 
631       /* Add a special NARG formal, which macro_expand will set to the
632 	 number of arguments.  */
633       /* The same MRI assemblers which treat '@' characters also use
634 	 the name $NARG.  At least until we find an exception.  */
635       if (macro_strip_at)
636 	name = "$NARG";
637       else
638 	name = "NARG";
639 
640       sb_add_string (&formal->name, name);
641 
642       /* Add to macro's hash table.  */
643       elt = formal_entry_alloc (name, formal);
644       if (htab_insert (macro->formal_hash, elt, 0) != NULL)
645 	{
646 	  free (elt);
647 	  as_bad_where (macro->file, macro->line,
648 			_("Reserved word `%s' used as parameter in macro `%s'"),
649 			name, macro->name);
650 	}
651 
652       formal->index = NARG_INDEX;
653       *p = formal;
654     }
655 
656   return idx;
657 }
658 
659 /* Free the memory allocated to a macro.  */
660 
661 static void
free_macro(macro_entry * macro)662 free_macro (macro_entry *macro)
663 {
664   formal_entry *formal;
665 
666   for (formal = macro->formals; formal; )
667     {
668       formal_entry *f;
669 
670       f = formal;
671       formal = formal->next;
672       del_formal (f);
673     }
674   htab_delete (macro->formal_hash);
675   sb_kill (&macro->sub);
676   free (macro);
677 }
678 
679 /* Define a new macro.  Returns NULL on success, otherwise returns an
680    error message.  If NAMEP is not NULL, *NAMEP is set to the name of
681    the macro which was defined.  */
682 
683 const char *
define_macro(size_t idx,sb * in,sb * label,size_t (* get_line)(sb *),const char * file,unsigned int line,const char ** namep)684 define_macro (size_t idx, sb *in, sb *label,
685 	      size_t (*get_line) (sb *),
686 	      const char *file, unsigned int line,
687 	      const char **namep)
688 {
689   macro_entry *macro;
690   sb name;
691   const char *error = NULL;
692 
693   macro = XNEW (macro_entry);
694   sb_new (&macro->sub);
695   sb_new (&name);
696   macro->file = file;
697   macro->line = line;
698 
699   macro->formal_count = 0;
700   macro->formals = 0;
701   macro->formal_hash = htab_create_alloc (7, hash_formal_entry, eq_formal_entry,
702 					  NULL, xcalloc, free);
703 
704   idx = sb_skip_white (idx, in);
705   if (! buffer_and_nest ("MACRO", "ENDM", &macro->sub, get_line))
706     error = _("unexpected end of file in macro `%s' definition");
707   if (label != NULL && label->len != 0)
708     {
709       sb_add_sb (&name, label);
710       macro->name = sb_terminate (&name);
711       if (idx < in->len && in->ptr[idx] == '(')
712 	{
713 	  /* It's the label: MACRO (formals,...)  sort  */
714 	  idx = do_formals (macro, idx + 1, in);
715 	  if (idx < in->len && in->ptr[idx] == ')')
716 	    idx = sb_skip_white (idx + 1, in);
717 	  else if (!error)
718 	    error = _("missing `)' after formals in macro definition `%s'");
719 	}
720       else
721 	{
722 	  /* It's the label: MACRO formals,...  sort  */
723 	  idx = do_formals (macro, idx, in);
724 	}
725     }
726   else
727     {
728       size_t cidx;
729 
730       idx = get_token (idx, in, &name);
731       macro->name = sb_terminate (&name);
732       if (name.len == 0)
733 	error = _("Missing macro name");
734       cidx = sb_skip_white (idx, in);
735       idx = sb_skip_comma (cidx, in);
736       if (idx == cidx || idx < in->len)
737 	idx = do_formals (macro, idx, in);
738       else
739 	idx = cidx;
740     }
741   if (!error && idx < in->len)
742     error = _("Bad parameter list for macro `%s'");
743 
744   /* And stick it in the macro hash table.  */
745   for (idx = 0; idx < name.len; idx++)
746     name.ptr[idx] = TOLOWER (name.ptr[idx]);
747   if (!error)
748     {
749       macro_hash_entry_t *elt = macro_entry_alloc (macro->name, macro);
750       if (htab_insert (macro_hash, elt, 0) != NULL)
751 	{
752 	  free (elt);
753 	  error = _("Macro `%s' was already defined");
754 	}
755     }
756 
757   if (namep != NULL)
758     *namep = macro->name;
759 
760   if (!error)
761     macro_defined = 1;
762   else
763     free_macro (macro);
764 
765   return error;
766 }
767 
768 /* Scan a token, and then skip KIND.  */
769 
770 static size_t
get_apost_token(size_t idx,sb * in,sb * name,int kind)771 get_apost_token (size_t idx, sb *in, sb *name, int kind)
772 {
773   idx = get_token (idx, in, name);
774   if (idx < in->len
775       && in->ptr[idx] == kind
776       && (! macro_mri || macro_strip_at)
777       && (! macro_strip_at || kind == '@'))
778     idx++;
779   return idx;
780 }
781 
782 /* Substitute the actual value for a formal parameter.  */
783 
784 static size_t
sub_actual(size_t start,sb * in,sb * t,struct htab * formal_hash,int kind,sb * out,int copyifnotthere)785 sub_actual (size_t start, sb *in, sb *t, struct htab *formal_hash,
786 	    int kind, sb *out, int copyifnotthere)
787 {
788   size_t src;
789   formal_entry *ptr;
790 
791   src = get_apost_token (start, in, t, kind);
792   /* See if it's in the macro's hash table, unless this is
793      macro_strip_at and kind is '@' and the token did not end in '@'.  */
794   if (macro_strip_at
795       && kind == '@'
796       && (src == start || in->ptr[src - 1] != '@'))
797     ptr = NULL;
798   else
799     ptr = formal_entry_find (formal_hash, sb_terminate (t));
800   if (ptr)
801     {
802       if (ptr->actual.len)
803 	{
804 	  sb_add_sb (out, &ptr->actual);
805 	}
806       else
807 	{
808 	  sb_add_sb (out, &ptr->def);
809 	}
810     }
811   else if (kind == '&')
812     {
813       /* Doing this permits people to use & in macro bodies.  */
814       sb_add_char (out, '&');
815       sb_add_sb (out, t);
816       if (src != start && in->ptr[src - 1] == '&')
817 	sb_add_char (out, '&');
818     }
819   else if (copyifnotthere)
820     {
821       sb_add_sb (out, t);
822     }
823   else
824     {
825       sb_add_char (out, '\\');
826       sb_add_sb (out, t);
827     }
828   return src;
829 }
830 
831 /* Expand the body of a macro.  */
832 
833 static const char *
macro_expand_body(sb * in,sb * out,formal_entry * formals,struct htab * formal_hash,const macro_entry * macro)834 macro_expand_body (sb *in, sb *out, formal_entry *formals,
835 		   struct htab *formal_hash, const macro_entry *macro)
836 {
837   sb t;
838   size_t src = 0;
839   int inquote = 0, macro_line = 0;
840   formal_entry *loclist = NULL;
841   const char *err = NULL;
842 
843   sb_new (&t);
844 
845   while (src < in->len && !err)
846     {
847       if (in->ptr[src] == '&')
848 	{
849 	  sb_reset (&t);
850 	  if (macro_mri)
851 	    {
852 	      if (src + 1 < in->len && in->ptr[src + 1] == '&')
853 		src = sub_actual (src + 2, in, &t, formal_hash, '\'', out, 1);
854 	      else
855 		sb_add_char (out, in->ptr[src++]);
856 	    }
857 	  else
858 	    {
859 	      /* Permit macro parameter substitution delineated with
860 		 an '&' prefix and optional '&' suffix.  */
861 	      src = sub_actual (src + 1, in, &t, formal_hash, '&', out, 0);
862 	    }
863 	}
864       else if (in->ptr[src] == '\\')
865 	{
866 	  src++;
867 	  if (src < in->len && in->ptr[src] == '(')
868 	    {
869 	      /* Sub in till the next ')' literally.  */
870 	      src++;
871 	      while (src < in->len && in->ptr[src] != ')')
872 		{
873 		  sb_add_char (out, in->ptr[src++]);
874 		}
875 	      if (src < in->len)
876 		src++;
877 	      else if (!macro)
878 		err = _("missing `)'");
879 	      else
880 		as_bad_where (macro->file, macro->line + macro_line, _("missing `)'"));
881 	    }
882 	  else if (src < in->len && in->ptr[src] == '@')
883 	    {
884 	      /* Sub in the macro invocation number.  */
885 
886 	      char buffer[12];
887 	      src++;
888 	      sprintf (buffer, "%d", macro_number);
889 	      sb_add_string (out, buffer);
890 	    }
891 	  else if (src < in->len && in->ptr[src] == '&')
892 	    {
893 	      /* This is a preprocessor variable name, we don't do them
894 		 here.  */
895 	      sb_add_char (out, '\\');
896 	      sb_add_char (out, '&');
897 	      src++;
898 	    }
899 	  else if (macro_mri && src < in->len && ISALNUM (in->ptr[src]))
900 	    {
901 	      int ind;
902 	      formal_entry *f;
903 
904 	      if (ISDIGIT (in->ptr[src]))
905 		ind = in->ptr[src] - '0';
906 	      else if (ISUPPER (in->ptr[src]))
907 		ind = in->ptr[src] - 'A' + 10;
908 	      else
909 		ind = in->ptr[src] - 'a' + 10;
910 	      ++src;
911 	      for (f = formals; f != NULL; f = f->next)
912 		{
913 		  if (f->index == ind - 1)
914 		    {
915 		      if (f->actual.len != 0)
916 			sb_add_sb (out, &f->actual);
917 		      else
918 			sb_add_sb (out, &f->def);
919 		      break;
920 		    }
921 		}
922 	    }
923 	  else
924 	    {
925 	      sb_reset (&t);
926 	      src = sub_actual (src, in, &t, formal_hash, '\'', out, 0);
927 	    }
928 	}
929       else if ((macro_alternate || macro_mri)
930 	       && is_name_beginner (in->ptr[src])
931 	       && (! inquote
932 		   || ! macro_strip_at
933 		   || (src > 0 && in->ptr[src - 1] == '@')))
934 	{
935 	  if (! macro
936 	      || src + 5 >= in->len
937 	      || strncasecmp (in->ptr + src, "LOCAL", 5) != 0
938 	      || ! ISWHITE (in->ptr[src + 5])
939 	      /* PR 11507: Skip keyword LOCAL if it is found inside a quoted string.  */
940 	      || inquote)
941 	    {
942 	      sb_reset (&t);
943 	      src = sub_actual (src, in, &t, formal_hash,
944 				(macro_strip_at && inquote) ? '@' : '\'',
945 				out, 1);
946 	    }
947 	  else
948 	    {
949 	      src = sb_skip_white (src + 5, in);
950 	      while (in->ptr[src] != '\n')
951 		{
952 		  const char *name;
953 		  formal_entry *f = new_formal ();
954 		  formal_hash_entry_t *elt;
955 
956 		  src = get_token (src, in, &f->name);
957 		  name = sb_terminate (&f->name);
958 		  elt = formal_entry_alloc (name, f);
959 		  if (htab_insert (formal_hash, elt, 0) != NULL)
960 		    {
961 		      free (elt);
962 		      as_bad_where (macro->file, macro->line + macro_line,
963 				    _("`%s' was already used as parameter "
964 				      "(or another local) name"), name);
965 		      del_formal (f);
966 		    }
967 		  else
968 		    {
969 		      static int loccnt;
970 		      char buf[20];
971 
972 		      f->index = LOCAL_INDEX;
973 		      f->next = loclist;
974 		      loclist = f;
975 
976 		      sprintf (buf, IS_ELF ? ".LL%04x" : "LL%04x", ++loccnt);
977 		      sb_add_string (&f->actual, buf);
978 		    }
979 
980 		  src = sb_skip_comma (src, in);
981 		}
982 	    }
983 	}
984       else if (in->ptr[src] == '"'
985 	       || (macro_mri && in->ptr[src] == '\''))
986 	{
987 	  inquote = !inquote;
988 	  sb_add_char (out, in->ptr[src++]);
989 	}
990       else if (in->ptr[src] == '@' && macro_strip_at)
991 	{
992 	  ++src;
993 	  if (src < in->len
994 	      && in->ptr[src] == '@')
995 	    {
996 	      sb_add_char (out, '@');
997 	      ++src;
998 	    }
999 	}
1000       else if (macro_mri
1001 	       && in->ptr[src] == '='
1002 	       && src + 1 < in->len
1003 	       && in->ptr[src + 1] == '=')
1004 	{
1005 	  formal_entry *ptr;
1006 
1007 	  sb_reset (&t);
1008 	  src = get_token (src + 2, in, &t);
1009 	  ptr = formal_entry_find (formal_hash, sb_terminate (&t));
1010 	  if (ptr == NULL)
1011 	    {
1012 	      /* FIXME: We should really return a warning string here,
1013 		 but we can't, because the == might be in the MRI
1014 		 comment field, and, since the nature of the MRI
1015 		 comment field depends upon the exact instruction
1016 		 being used, we don't have enough information here to
1017 		 figure out whether it is or not.  Instead, we leave
1018 		 the == in place, which should cause a syntax error if
1019 		 it is not in a comment.  */
1020 	      sb_add_char (out, '=');
1021 	      sb_add_char (out, '=');
1022 	      sb_add_sb (out, &t);
1023 	    }
1024 	  else
1025 	    {
1026 	      if (ptr->actual.len)
1027 		{
1028 		  sb_add_string (out, "-1");
1029 		}
1030 	      else
1031 		{
1032 		  sb_add_char (out, '0');
1033 		}
1034 	    }
1035 	}
1036       else
1037 	{
1038 	  if (in->ptr[src] == '\n')
1039 	    ++macro_line;
1040 	  sb_add_char (out, in->ptr[src++]);
1041 	}
1042     }
1043 
1044   sb_kill (&t);
1045 
1046   while (loclist != NULL)
1047     {
1048       formal_entry *f;
1049       const char *name;
1050 
1051       f = loclist->next;
1052       name = sb_terminate (&loclist->name);
1053       formal_hash_entry_t needle = { name, NULL };
1054       htab_remove_elt (formal_hash, &needle);
1055       del_formal (loclist);
1056       loclist = f;
1057     }
1058 
1059   if (!err && (out->len == 0 || out->ptr[out->len - 1] != '\n'))
1060     sb_add_char (out, '\n');
1061   return err;
1062 }
1063 
1064 /* Assign values to the formal parameters of a macro, and expand the
1065    body.  */
1066 
1067 static const char *
macro_expand(size_t idx,sb * in,macro_entry * m,sb * out)1068 macro_expand (size_t idx, sb *in, macro_entry *m, sb *out)
1069 {
1070   sb t;
1071   formal_entry *ptr;
1072   formal_entry *f;
1073   int is_keyword = 0;
1074   int narg = 0;
1075   const char *err = NULL;
1076 
1077   sb_new (&t);
1078 
1079   /* Reset any old value the actuals may have.  */
1080   for (f = m->formals; f; f = f->next)
1081     sb_reset (&f->actual);
1082   f = m->formals;
1083   while (f != NULL && f->index < 0)
1084     f = f->next;
1085 
1086   if (macro_mri)
1087     {
1088       /* The macro may be called with an optional qualifier, which may
1089 	 be referred to in the macro body as \0.  */
1090       if (idx < in->len && in->ptr[idx] == '.')
1091 	{
1092 	  /* The Microtec assembler ignores this if followed by a white space.
1093 	     (Macro invocation with empty extension) */
1094 	  idx++;
1095 	  if (    idx < in->len
1096 		  && in->ptr[idx] != ' '
1097 		  && in->ptr[idx] != '\t')
1098 	    {
1099 	      formal_entry *n = new_formal ();
1100 
1101 	      n->index = QUAL_INDEX;
1102 
1103 	      n->next = m->formals;
1104 	      m->formals = n;
1105 
1106 	      idx = get_any_string (idx, in, &n->actual);
1107 	    }
1108 	}
1109     }
1110 
1111   /* Peel off the actuals and store them away in the hash tables' actuals.  */
1112   idx = sb_skip_white (idx, in);
1113   while (idx < in->len)
1114     {
1115       size_t scan;
1116 
1117       /* Look and see if it's a positional or keyword arg.  */
1118       scan = idx;
1119       while (scan < in->len
1120 	     && !ISSEP (in->ptr[scan])
1121 	     && !(macro_mri && in->ptr[scan] == '\'')
1122 	     && (!macro_alternate && in->ptr[scan] != '='))
1123 	scan++;
1124       if (scan < in->len && !macro_alternate && in->ptr[scan] == '=')
1125 	{
1126 	  is_keyword = 1;
1127 
1128 	  /* It's OK to go from positional to keyword.  */
1129 
1130 	  /* This is a keyword arg, fetch the formal name and
1131 	     then the actual stuff.  */
1132 	  sb_reset (&t);
1133 	  idx = get_token (idx, in, &t);
1134 	  if (in->ptr[idx] != '=')
1135 	    {
1136 	      err = _("confusion in formal parameters");
1137 	      break;
1138 	    }
1139 
1140 	  /* Lookup the formal in the macro's list.  */
1141 	  ptr = formal_entry_find (m->formal_hash, sb_terminate (&t));
1142 	  if (!ptr)
1143 	    {
1144 	      as_bad (_("Parameter named `%s' does not exist for macro `%s'"),
1145 		      t.ptr,
1146 		      m->name);
1147 	      sb_reset (&t);
1148 	      idx = get_any_string (idx + 1, in, &t);
1149 	    }
1150 	  else
1151 	    {
1152 	      /* Insert this value into the right place.  */
1153 	      if (ptr->actual.len)
1154 		{
1155 		  as_warn (_("Value for parameter `%s' of macro `%s' was already specified"),
1156 			   ptr->name.ptr,
1157 			   m->name);
1158 		  sb_reset (&ptr->actual);
1159 		}
1160 	      idx = get_any_string (idx + 1, in, &ptr->actual);
1161 	      if (ptr->actual.len > 0)
1162 		++narg;
1163 	    }
1164 	}
1165       else
1166 	{
1167 	  if (is_keyword)
1168 	    {
1169 	      err = _("can't mix positional and keyword arguments");
1170 	      break;
1171 	    }
1172 
1173 	  if (!f)
1174 	    {
1175 	      formal_entry **pf;
1176 	      int c;
1177 
1178 	      if (!macro_mri)
1179 		{
1180 		  err = _("too many positional arguments");
1181 		  break;
1182 		}
1183 
1184 	      f = new_formal ();
1185 
1186 	      c = -1;
1187 	      for (pf = &m->formals; *pf != NULL; pf = &(*pf)->next)
1188 		if ((*pf)->index >= c)
1189 		  c = (*pf)->index + 1;
1190 	      if (c == -1)
1191 		c = 0;
1192 	      *pf = f;
1193 	      f->index = c;
1194 	    }
1195 
1196 	  if (f->type != FORMAL_VARARG)
1197 	    idx = get_any_string (idx, in, &f->actual);
1198 	  else
1199 	    {
1200 	      sb_add_buffer (&f->actual, in->ptr + idx, in->len - idx);
1201 	      idx = in->len;
1202 	    }
1203 	  if (f->actual.len > 0)
1204 	    ++narg;
1205 	  do
1206 	    {
1207 	      f = f->next;
1208 	    }
1209 	  while (f != NULL && f->index < 0);
1210 	}
1211 
1212       if (! macro_mri)
1213 	idx = sb_skip_comma (idx, in);
1214       else
1215 	{
1216 	  if (in->ptr[idx] == ',')
1217 	    ++idx;
1218 	  if (ISWHITE (in->ptr[idx]))
1219 	    break;
1220 	}
1221     }
1222 
1223   if (! err)
1224     {
1225       for (ptr = m->formals; ptr; ptr = ptr->next)
1226 	{
1227 	  if (ptr->type == FORMAL_REQUIRED && ptr->actual.len == 0)
1228 	    as_bad (_("Missing value for required parameter `%s' of macro `%s'"),
1229 		    ptr->name.ptr,
1230 		    m->name);
1231 	}
1232 
1233       if (macro_mri)
1234 	{
1235 	  char buffer[20];
1236 
1237 	  sb_reset (&t);
1238 	  sb_add_string (&t, macro_strip_at ? "$NARG" : "NARG");
1239 	  ptr = formal_entry_find (m->formal_hash, sb_terminate (&t));
1240 	  sprintf (buffer, "%d", narg);
1241 	  sb_add_string (&ptr->actual, buffer);
1242 	}
1243 
1244       err = macro_expand_body (&m->sub, out, m->formals, m->formal_hash, m);
1245     }
1246 
1247   /* Discard any unnamed formal arguments.  */
1248   if (macro_mri)
1249     {
1250       formal_entry **pf;
1251 
1252       pf = &m->formals;
1253       while (*pf != NULL)
1254 	{
1255 	  if ((*pf)->name.len != 0)
1256 	    pf = &(*pf)->next;
1257 	  else
1258 	    {
1259 	      f = (*pf)->next;
1260 	      del_formal (*pf);
1261 	      *pf = f;
1262 	    }
1263 	}
1264     }
1265 
1266   sb_kill (&t);
1267   if (!err)
1268     macro_number++;
1269 
1270   return err;
1271 }
1272 
1273 /* Check for a macro.  If one is found, put the expansion into
1274    *EXPAND.  Return 1 if a macro is found, 0 otherwise.  */
1275 
1276 int
check_macro(const char * line,sb * expand,const char ** error,macro_entry ** info)1277 check_macro (const char *line, sb *expand,
1278 	     const char **error, macro_entry **info)
1279 {
1280   const char *s;
1281   char *copy, *cls;
1282   macro_entry *macro;
1283   sb line_sb;
1284 
1285   if (! is_name_beginner (*line)
1286       && (! macro_mri || *line != '.'))
1287     return 0;
1288 
1289   s = line + 1;
1290   while (is_part_of_name (*s))
1291     ++s;
1292   if (is_name_ender (*s))
1293     ++s;
1294 
1295   copy = xmemdup0 (line, s - line);
1296   for (cls = copy; *cls != '\0'; cls ++)
1297     *cls = TOLOWER (*cls);
1298 
1299   macro = macro_entry_find (macro_hash, copy);
1300   free (copy);
1301 
1302   if (macro == NULL)
1303     return 0;
1304 
1305   /* Wrap the line up in an sb.  */
1306   sb_new (&line_sb);
1307   while (*s != '\0' && *s != '\n' && *s != '\r')
1308     sb_add_char (&line_sb, *s++);
1309 
1310   sb_new (expand);
1311   *error = macro_expand (0, &line_sb, macro, expand);
1312 
1313   sb_kill (&line_sb);
1314 
1315   /* Export the macro information if requested.  */
1316   if (info)
1317     *info = macro;
1318 
1319   return 1;
1320 }
1321 
1322 /* Delete a macro.  */
1323 
1324 void
delete_macro(const char * name)1325 delete_macro (const char *name)
1326 {
1327   char *copy;
1328   size_t i, len;
1329   void **slot;
1330   macro_hash_entry_t needle;
1331 
1332   len = strlen (name);
1333   copy = XNEWVEC (char, len + 1);
1334   for (i = 0; i < len; ++i)
1335     copy[i] = TOLOWER (name[i]);
1336   copy[i] = '\0';
1337 
1338   needle.name = copy;
1339   needle.macro = NULL;
1340   slot = htab_find_slot (macro_hash, &needle, NO_INSERT);
1341   if (slot)
1342     {
1343       free_macro (((macro_hash_entry_t *) *slot)->macro);
1344       htab_clear_slot (macro_hash, slot);
1345     }
1346   else
1347     as_warn (_("Attempt to purge non-existing macro `%s'"), copy);
1348   free (copy);
1349 }
1350 
1351 /* Handle the MRI IRP and IRPC pseudo-ops.  These are handled as a
1352    combined macro definition and execution.  This returns NULL on
1353    success, or an error message otherwise.  */
1354 
1355 const char *
expand_irp(int irpc,size_t idx,sb * in,sb * out,size_t (* get_line)(sb *))1356 expand_irp (int irpc, size_t idx, sb *in, sb *out, size_t (*get_line) (sb *))
1357 {
1358   sb sub;
1359   formal_entry f;
1360   struct htab *h;
1361   const char *err = NULL;
1362 
1363   idx = sb_skip_white (idx, in);
1364 
1365   sb_new (&sub);
1366   if (! buffer_and_nest (NULL, "ENDR", &sub, get_line))
1367     return _("unexpected end of file in irp or irpc");
1368 
1369   sb_new (&f.name);
1370   sb_new (&f.def);
1371   sb_new (&f.actual);
1372 
1373   idx = get_token (idx, in, &f.name);
1374   if (f.name.len == 0)
1375     return _("missing model parameter");
1376 
1377   h = htab_create_alloc (16, hash_formal_entry, eq_formal_entry,
1378 			 NULL, xcalloc, free);
1379 
1380   htab_insert (h, formal_entry_alloc (sb_terminate (&f.name), &f), 0);
1381 
1382   f.index = 1;
1383   f.next = NULL;
1384   f.type = FORMAL_OPTIONAL;
1385 
1386   sb_reset (out);
1387 
1388   idx = sb_skip_comma (idx, in);
1389   if (idx >= in->len)
1390     {
1391       /* Expand once with a null string.  */
1392       err = macro_expand_body (&sub, out, &f, h, 0);
1393     }
1394   else
1395     {
1396       bool in_quotes = false;
1397 
1398       if (irpc && in->ptr[idx] == '"')
1399 	{
1400 	  in_quotes = true;
1401 	  ++idx;
1402 	}
1403 
1404       while (idx < in->len)
1405 	{
1406 	  if (!irpc)
1407 	    idx = get_any_string (idx, in, &f.actual);
1408 	  else
1409 	    {
1410 	      if (in->ptr[idx] == '"')
1411 		{
1412 		  size_t nxt;
1413 
1414 		  if (irpc)
1415 		    in_quotes = ! in_quotes;
1416 
1417 		  nxt = sb_skip_white (idx + 1, in);
1418 		  if (nxt >= in->len)
1419 		    {
1420 		      idx = nxt;
1421 		      break;
1422 		    }
1423 		}
1424 	      sb_reset (&f.actual);
1425 	      sb_add_char (&f.actual, in->ptr[idx]);
1426 	      ++idx;
1427 	    }
1428 
1429 	  err = macro_expand_body (&sub, out, &f, h, 0);
1430 	  if (err != NULL)
1431 	    break;
1432 	  if (!irpc)
1433 	    idx = sb_skip_comma (idx, in);
1434 	  else if (! in_quotes)
1435 	    idx = sb_skip_white (idx, in);
1436 	}
1437     }
1438 
1439   htab_delete (h);
1440   sb_kill (&f.actual);
1441   sb_kill (&f.def);
1442   sb_kill (&f.name);
1443   sb_kill (&sub);
1444 
1445   return err;
1446 }
1447