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