1 /* macro.c - macro support for gas and gasp
2 Copyright (C) 1994, 95, 96, 97, 98, 1999 Free Software Foundation, Inc.
4 Written by Steve and Judy Chamberlain of Cygnus Support,
7 This file is part of GAS, the GNU Assembler.
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)
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.
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
26 /* AIX requires this to be the first thing in the file. */
30 extern void *alloca ();
32 extern char *alloca ();
42 # ifndef alloca /* predefined by HP cc +Olibcalls */
43 # if !defined (__STDC__) && !defined (__hpux)
44 extern char *alloca ();
46 extern void *alloca ();
47 # endif /* __STDC__, __hpux */
50 # endif /* HAVE_ALLOCA_H */
63 #include "libiberty.h"
70 /* The routines in this file handle macro definition and expansion.
71 They are called by both gasp and gas. */
73 /* Structures used to store macros.
75 Each macro knows its name and included text. It gets built with a
76 list of formal arguments, and also keeps a hash table which points
77 into the list to speed up formal search. Each formal knows its
78 name and its default value. Each time the macro is expanded, the
79 formals get the actual values attatched to them. */
81 /* describe the formal arguments to a macro */
83 typedef struct formal_struct
85 struct formal_struct
*next
; /* next formal in list */
86 sb name
; /* name of the formal */
87 sb def
; /* the default value */
88 sb actual
; /* the actual argument (changed on each expansion) */
89 int index
; /* the index of the formal 0..formal_count-1 */
93 /* Other values found in the index field of a formal_entry. */
94 #define QUAL_INDEX (-1)
95 #define NARG_INDEX (-2)
96 #define LOCAL_INDEX (-3)
98 /* describe the macro. */
100 typedef struct macro_struct
102 sb sub
; /* substitution text. */
103 int formal_count
; /* number of formal args. */
104 formal_entry
*formals
; /* pointer to list of formal_structs */
105 struct hash_control
*formal_hash
; /* hash table of formals. */
109 /* Internal functions. */
111 static int get_token
PARAMS ((int, sb
*, sb
*));
112 static int getstring
PARAMS ((int, sb
*, sb
*));
113 static int get_any_string
PARAMS ((int, sb
*, sb
*, int, int));
114 static int do_formals
PARAMS ((macro_entry
*, int, sb
*));
115 static int get_apost_token
PARAMS ((int, sb
*, sb
*, int));
116 static int sub_actual
117 PARAMS ((int, sb
*, sb
*, struct hash_control
*, int, sb
*, int));
118 static const char *macro_expand_body
119 PARAMS ((sb
*, sb
*, formal_entry
*, struct hash_control
*, int, int));
120 static const char *macro_expand
PARAMS ((int, sb
*, macro_entry
*, sb
*, int));
122 #define ISWHITE(x) ((x) == ' ' || (x) == '\t')
125 ((x) == ' ' || (x) == '\t' || (x) == ',' || (x) == '"' || (x) == ';' \
126 || (x) == ')' || (x) == '(' \
127 || ((macro_alternate || macro_mri) && ((x) == '<' || (x) == '>')))
130 ((x) == 'b' || (x) == 'B' \
131 || (x) == 'q' || (x) == 'Q' \
132 || (x) == 'h' || (x) == 'H' \
133 || (x) == 'd' || (x) == 'D')
135 /* The macro hash table. */
137 static struct hash_control
*macro_hash
;
139 /* Whether any macros have been defined. */
143 /* Whether we are in GASP alternate mode. */
145 static int macro_alternate
;
147 /* Whether we are in MRI mode. */
149 static int macro_mri
;
151 /* Whether we should strip '@' characters. */
153 static int macro_strip_at
;
155 /* Function to use to parse an expression. */
157 static int (*macro_expr
) PARAMS ((const char *, int, sb
*, int *));
159 /* Number of macro expansions that have been done. */
161 static int macro_number
;
163 /* Initialize macro processing. */
166 macro_init (alternate
, mri
, strip_at
, expr
)
170 int (*expr
) PARAMS ((const char *, int, sb
*, int *));
172 macro_hash
= hash_new ();
174 macro_alternate
= alternate
;
176 macro_strip_at
= strip_at
;
180 /* Switch in and out of MRI mode on the fly. */
189 /* Read input lines till we get to a TO string.
190 Increase nesting depth if we get a FROM string.
191 Put the results into sb at PTR.
192 Add a new input line to an sb using GET_LINE.
193 Return 1 on success, 0 on unexpected EOF. */
196 buffer_and_nest (from
, to
, ptr
, get_line
)
200 int (*get_line
) PARAMS ((sb
*));
202 int from_len
= strlen (from
);
203 int to_len
= strlen (to
);
205 int line_start
= ptr
->len
;
207 int more
= get_line (ptr
);
211 /* Try and find the first pseudo op on the line */
214 if (! macro_alternate
&& ! macro_mri
)
216 /* With normal syntax we can suck what we want till we get
217 to the dot. With the alternate, labels have to start in
218 the first column, since we cant tell what's a label and
221 /* Skip leading whitespace */
222 while (i
< ptr
->len
&& ISWHITE (ptr
->ptr
[i
]))
225 /* Skip over a label */
227 && (isalnum ((unsigned char) ptr
->ptr
[i
])
228 || ptr
->ptr
[i
] == '_'
229 || ptr
->ptr
[i
] == '$'))
234 && ptr
->ptr
[i
] == ':')
238 /* Skip trailing whitespace */
239 while (i
< ptr
->len
&& ISWHITE (ptr
->ptr
[i
]))
242 if (i
< ptr
->len
&& (ptr
->ptr
[i
] == '.'
246 if (ptr
->ptr
[i
] == '.')
248 if (strncasecmp (ptr
->ptr
+ i
, from
, from_len
) == 0
249 && (ptr
->len
== (i
+ from_len
) || ! isalnum (ptr
->ptr
[i
+ from_len
])))
251 if (strncasecmp (ptr
->ptr
+ i
, to
, to_len
) == 0
252 && (ptr
->len
== (i
+ to_len
) || ! isalnum (ptr
->ptr
[i
+ to_len
])))
257 /* Reset the string to not include the ending rune */
258 ptr
->len
= line_start
;
264 /* Add a CR to the end and keep running */
265 sb_add_char (ptr
, '\n');
266 line_start
= ptr
->len
;
267 more
= get_line (ptr
);
270 /* Return 1 on success, 0 on unexpected EOF. */
274 /* Pick up a token. */
277 get_token (idx
, in
, name
)
283 && (isalpha ((unsigned char) in
->ptr
[idx
])
284 || in
->ptr
[idx
] == '_'
285 || in
->ptr
[idx
] == '$'))
287 sb_add_char (name
, in
->ptr
[idx
++]);
289 && (isalnum ((unsigned char) in
->ptr
[idx
])
290 || in
->ptr
[idx
] == '_'
291 || in
->ptr
[idx
] == '$'))
293 sb_add_char (name
, in
->ptr
[idx
++]);
296 /* Ignore trailing & */
297 if (macro_alternate
&& idx
< in
->len
&& in
->ptr
[idx
] == '&')
302 /* Pick up a string. */
305 getstring (idx
, in
, acc
)
310 idx
= sb_skip_white (idx
, in
);
313 && (in
->ptr
[idx
] == '"'
314 || (in
->ptr
[idx
] == '<' && (macro_alternate
|| macro_mri
))
315 || (in
->ptr
[idx
] == '\'' && macro_alternate
)))
317 if (in
->ptr
[idx
] == '<')
321 while ((in
->ptr
[idx
] != '>' || nest
)
324 if (in
->ptr
[idx
] == '!')
327 sb_add_char (acc
, in
->ptr
[idx
++]);
331 if (in
->ptr
[idx
] == '>')
333 if (in
->ptr
[idx
] == '<')
335 sb_add_char (acc
, in
->ptr
[idx
++]);
340 else if (in
->ptr
[idx
] == '"' || in
->ptr
[idx
] == '\'')
342 char tchar
= in
->ptr
[idx
];
344 while (idx
< in
->len
)
346 if (macro_alternate
&& in
->ptr
[idx
] == '!')
349 sb_add_char (acc
, in
->ptr
[idx
++]);
353 if (in
->ptr
[idx
] == tchar
)
356 if (idx
>= in
->len
|| in
->ptr
[idx
] != tchar
)
359 sb_add_char (acc
, in
->ptr
[idx
]);
369 /* Fetch string from the input stream,
371 'Bxyx<whitespace> -> return 'Bxyza
372 %<char> -> return string of decimal value of x
373 "<string>" -> return string
374 xyx<whitespace> -> return xyz
378 get_any_string (idx
, in
, out
, expand
, pretend_quoted
)
386 idx
= sb_skip_white (idx
, in
);
390 if (in
->len
> 2 && in
->ptr
[idx
+1] == '\'' && ISBASE (in
->ptr
[idx
]))
392 while (!ISSEP (in
->ptr
[idx
]))
393 sb_add_char (out
, in
->ptr
[idx
++]);
395 else if (in
->ptr
[idx
] == '%'
401 /* Turns the next expression into a string */
402 idx
= (*macro_expr
) (_("% operator needs absolute expression"),
406 sprintf(buf
, "%d", val
);
407 sb_add_string (out
, buf
);
409 else if (in
->ptr
[idx
] == '"'
410 || (in
->ptr
[idx
] == '<' && (macro_alternate
|| macro_mri
))
411 || (macro_alternate
&& in
->ptr
[idx
] == '\''))
417 /* Keep the quotes */
418 sb_add_char (out
, '\"');
420 idx
= getstring (idx
, in
, out
);
421 sb_add_char (out
, '\"');
425 idx
= getstring (idx
, in
, out
);
431 && (in
->ptr
[idx
] == '"'
432 || in
->ptr
[idx
] == '\''
434 || (in
->ptr
[idx
] != ' '
435 && in
->ptr
[idx
] != '\t'
436 && in
->ptr
[idx
] != ','
437 && (in
->ptr
[idx
] != '<'
438 || (! macro_alternate
&& ! macro_mri
)))))
440 if (in
->ptr
[idx
] == '"'
441 || in
->ptr
[idx
] == '\'')
443 char tchar
= in
->ptr
[idx
];
444 sb_add_char (out
, in
->ptr
[idx
++]);
446 && in
->ptr
[idx
] != tchar
)
447 sb_add_char (out
, in
->ptr
[idx
++]);
451 sb_add_char (out
, in
->ptr
[idx
++]);
459 /* Pick up the formal parameters of a macro definition. */
462 do_formals (macro
, idx
, in
)
467 formal_entry
**p
= ¯o
->formals
;
469 macro
->formal_count
= 0;
470 macro
->formal_hash
= hash_new ();
471 while (idx
< in
->len
)
473 formal_entry
*formal
;
475 formal
= (formal_entry
*) xmalloc (sizeof (formal_entry
));
477 sb_new (&formal
->name
);
478 sb_new (&formal
->def
);
479 sb_new (&formal
->actual
);
481 idx
= sb_skip_white (idx
, in
);
482 idx
= get_token (idx
, in
, &formal
->name
);
483 if (formal
->name
.len
== 0)
485 idx
= sb_skip_white (idx
, in
);
486 if (formal
->name
.len
)
488 /* This is a formal */
489 if (idx
< in
->len
&& in
->ptr
[idx
] == '=')
492 idx
= get_any_string (idx
+ 1, in
, &formal
->def
, 1, 0);
496 /* Add to macro's hash table */
497 hash_jam (macro
->formal_hash
, sb_terminate (&formal
->name
), formal
);
499 formal
->index
= macro
->formal_count
;
500 idx
= sb_skip_comma (idx
, in
);
501 macro
->formal_count
++;
509 formal_entry
*formal
;
512 /* Add a special NARG formal, which macro_expand will set to the
513 number of arguments. */
514 formal
= (formal_entry
*) xmalloc (sizeof (formal_entry
));
516 sb_new (&formal
->name
);
517 sb_new (&formal
->def
);
518 sb_new (&formal
->actual
);
520 /* The same MRI assemblers which treat '@' characters also use
521 the name $NARG. At least until we find an exception. */
527 sb_add_string (&formal
->name
, name
);
529 /* Add to macro's hash table */
530 hash_jam (macro
->formal_hash
, name
, formal
);
532 formal
->index
= NARG_INDEX
;
540 /* Define a new macro. Returns NULL on success, otherwise returns an
541 error message. If NAMEP is not NULL, *NAMEP is set to the name of
542 the macro which was defined. */
545 define_macro (idx
, in
, label
, get_line
, namep
)
549 int (*get_line
) PARAMS ((sb
*));
556 macro
= (macro_entry
*) xmalloc (sizeof (macro_entry
));
557 sb_new (¯o
->sub
);
560 macro
->formal_count
= 0;
563 idx
= sb_skip_white (idx
, in
);
564 if (! buffer_and_nest ("MACRO", "ENDM", ¯o
->sub
, get_line
))
565 return _("unexpected end of file in macro definition");
566 if (label
!= NULL
&& label
->len
!= 0)
568 sb_add_sb (&name
, label
);
569 if (idx
< in
->len
&& in
->ptr
[idx
] == '(')
571 /* It's the label: MACRO (formals,...) sort */
572 idx
= do_formals (macro
, idx
+ 1, in
);
573 if (in
->ptr
[idx
] != ')')
574 return _("missing ) after formals");
578 /* It's the label: MACRO formals,... sort */
579 idx
= do_formals (macro
, idx
, in
);
584 idx
= get_token (idx
, in
, &name
);
585 idx
= sb_skip_comma (idx
, in
);
586 idx
= do_formals (macro
, idx
, in
);
589 /* and stick it in the macro hash table */
590 for (idx
= 0; idx
< name
.len
; idx
++)
591 if (isupper ((unsigned char) name
.ptr
[idx
]))
592 name
.ptr
[idx
] = tolower (name
.ptr
[idx
]);
593 namestr
= sb_terminate (&name
);
594 hash_jam (macro_hash
, namestr
, (PTR
) macro
);
604 /* Scan a token, and then skip KIND. */
607 get_apost_token (idx
, in
, name
, kind
)
613 idx
= get_token (idx
, in
, name
);
615 && in
->ptr
[idx
] == kind
616 && (! macro_mri
|| macro_strip_at
)
617 && (! macro_strip_at
|| kind
== '@'))
622 /* Substitute the actual value for a formal parameter. */
625 sub_actual (start
, in
, t
, formal_hash
, kind
, out
, copyifnotthere
)
629 struct hash_control
*formal_hash
;
637 src
= get_apost_token (start
, in
, t
, kind
);
638 /* See if it's in the macro's hash table, unless this is
639 macro_strip_at and kind is '@' and the token did not end in '@'. */
642 && (src
== start
|| in
->ptr
[src
- 1] != '@'))
645 ptr
= (formal_entry
*) hash_find (formal_hash
, sb_terminate (t
));
650 sb_add_sb (out
, &ptr
->actual
);
654 sb_add_sb (out
, &ptr
->def
);
657 else if (kind
== '&')
659 /* Doing this permits people to use & in macro bodies. */
660 sb_add_char (out
, '&');
662 else if (copyifnotthere
)
668 sb_add_char (out
, '\\');
674 /* Expand the body of a macro. */
677 macro_expand_body (in
, out
, formals
, formal_hash
, comment_char
, locals
)
680 formal_entry
*formals
;
681 struct hash_control
*formal_hash
;
688 formal_entry
*loclist
= NULL
;
692 while (src
< in
->len
)
694 if (in
->ptr
[src
] == '&')
699 if (src
+ 1 < in
->len
&& in
->ptr
[src
+ 1] == '&')
700 src
= sub_actual (src
+ 2, in
, &t
, formal_hash
, '\'', out
, 1);
702 sb_add_char (out
, in
->ptr
[src
++]);
706 /* FIXME: Why do we do this? */
707 src
= sub_actual (src
+ 1, in
, &t
, formal_hash
, '&', out
, 0);
710 else if (in
->ptr
[src
] == '\\')
713 if (in
->ptr
[src
] == comment_char
&& comment_char
!= '\0')
715 /* This is a comment, just drop the rest of the line */
717 && in
->ptr
[src
] != '\n')
720 else if (in
->ptr
[src
] == '(')
722 /* Sub in till the next ')' literally */
724 while (src
< in
->len
&& in
->ptr
[src
] != ')')
726 sb_add_char (out
, in
->ptr
[src
++]);
728 if (in
->ptr
[src
] == ')')
731 return _("missplaced )");
733 else if (in
->ptr
[src
] == '@')
735 /* Sub in the macro invocation number */
739 sprintf (buffer
, "%05d", macro_number
);
740 sb_add_string (out
, buffer
);
742 else if (in
->ptr
[src
] == '&')
744 /* This is a preprocessor variable name, we don't do them
746 sb_add_char (out
, '\\');
747 sb_add_char (out
, '&');
751 && isalnum ((unsigned char) in
->ptr
[src
]))
756 if (isdigit ((unsigned char) in
->ptr
[src
]))
757 ind
= in
->ptr
[src
] - '0';
758 else if (isupper ((unsigned char) in
->ptr
[src
]))
759 ind
= in
->ptr
[src
] - 'A' + 10;
761 ind
= in
->ptr
[src
] - 'a' + 10;
763 for (f
= formals
; f
!= NULL
; f
= f
->next
)
765 if (f
->index
== ind
- 1)
767 if (f
->actual
.len
!= 0)
768 sb_add_sb (out
, &f
->actual
);
770 sb_add_sb (out
, &f
->def
);
778 src
= sub_actual (src
, in
, &t
, formal_hash
, '\'', out
, 0);
781 else if ((macro_alternate
|| macro_mri
)
782 && (isalpha ((unsigned char) in
->ptr
[src
])
783 || in
->ptr
[src
] == '_'
784 || in
->ptr
[src
] == '$')
787 || (src
> 0 && in
->ptr
[src
- 1] == '@')))
790 || src
+ 5 >= in
->len
791 || strncasecmp (in
->ptr
+ src
, "LOCAL", 5) != 0
792 || ! ISWHITE (in
->ptr
[src
+ 5]))
795 src
= sub_actual (src
, in
, &t
, formal_hash
,
796 (macro_strip_at
&& inquote
) ? '@' : '\'',
803 src
= sb_skip_white (src
+ 5, in
);
804 while (in
->ptr
[src
] != '\n' && in
->ptr
[src
] != comment_char
)
810 f
= (formal_entry
*) xmalloc (sizeof (formal_entry
));
814 f
->index
= LOCAL_INDEX
;
818 src
= get_token (src
, in
, &f
->name
);
820 sprintf (buf
, "LL%04x", loccnt
);
821 sb_add_string (&f
->actual
, buf
);
823 err
= hash_jam (formal_hash
, sb_terminate (&f
->name
), f
);
827 src
= sb_skip_comma (src
, in
);
831 else if (comment_char
!= '\0'
832 && in
->ptr
[src
] == comment_char
834 && in
->ptr
[src
+ 1] == comment_char
837 /* Two comment chars in a row cause the rest of the line to
839 while (src
< in
->len
&& in
->ptr
[src
] != '\n')
842 else if (in
->ptr
[src
] == '"'
843 || (macro_mri
&& in
->ptr
[src
] == '\''))
846 sb_add_char (out
, in
->ptr
[src
++]);
848 else if (in
->ptr
[src
] == '@' && macro_strip_at
)
852 && in
->ptr
[src
] == '@')
854 sb_add_char (out
, '@');
859 && in
->ptr
[src
] == '='
861 && in
->ptr
[src
+ 1] == '=')
866 src
= get_token (src
+ 2, in
, &t
);
867 ptr
= (formal_entry
*) hash_find (formal_hash
, sb_terminate (&t
));
870 /* FIXME: We should really return a warning string here,
871 but we can't, because the == might be in the MRI
872 comment field, and, since the nature of the MRI
873 comment field depends upon the exact instruction
874 being used, we don't have enough information here to
875 figure out whether it is or not. Instead, we leave
876 the == in place, which should cause a syntax error if
877 it is not in a comment. */
878 sb_add_char (out
, '=');
879 sb_add_char (out
, '=');
886 sb_add_string (out
, "-1");
890 sb_add_char (out
, '0');
896 sb_add_char (out
, in
->ptr
[src
++]);
902 while (loclist
!= NULL
)
907 /* Setting the value to NULL effectively deletes the entry. We
908 avoid calling hash_delete because it doesn't reclaim memory. */
909 hash_jam (formal_hash
, sb_terminate (&loclist
->name
), NULL
);
910 sb_kill (&loclist
->name
);
911 sb_kill (&loclist
->def
);
912 sb_kill (&loclist
->actual
);
920 /* Assign values to the formal parameters of a macro, and expand the
924 macro_expand (idx
, in
, m
, out
, comment_char
)
934 int is_positional
= 0;
941 /* Reset any old value the actuals may have */
942 for (f
= m
->formals
; f
; f
= f
->next
)
943 sb_reset (&f
->actual
);
945 while (f
!= NULL
&& f
->index
< 0)
950 /* The macro may be called with an optional qualifier, which may
951 be referred to in the macro body as \0. */
952 if (idx
< in
->len
&& in
->ptr
[idx
] == '.')
956 n
= (formal_entry
*) xmalloc (sizeof (formal_entry
));
960 n
->index
= QUAL_INDEX
;
962 n
->next
= m
->formals
;
965 idx
= get_any_string (idx
+ 1, in
, &n
->actual
, 1, 0);
969 /* Peel off the actuals and store them away in the hash tables' actuals */
970 idx
= sb_skip_white (idx
, in
);
971 while (idx
< in
->len
&& in
->ptr
[idx
] != comment_char
)
975 /* Look and see if it's a positional or keyword arg */
977 while (scan
< in
->len
978 && !ISSEP (in
->ptr
[scan
])
979 && !(macro_mri
&& in
->ptr
[scan
] == '\'')
980 && (!macro_alternate
&& in
->ptr
[scan
] != '='))
982 if (scan
< in
->len
&& !macro_alternate
&& in
->ptr
[scan
] == '=')
986 /* It's OK to go from positional to keyword. */
988 /* This is a keyword arg, fetch the formal name and
989 then the actual stuff */
991 idx
= get_token (idx
, in
, &t
);
992 if (in
->ptr
[idx
] != '=')
993 return _("confusion in formal parameters");
995 /* Lookup the formal in the macro's list */
996 ptr
= (formal_entry
*) hash_find (m
->formal_hash
, sb_terminate (&t
));
998 return _("macro formal argument does not exist");
1001 /* Insert this value into the right place */
1002 sb_reset (&ptr
->actual
);
1003 idx
= get_any_string (idx
+ 1, in
, &ptr
->actual
, 0, 0);
1004 if (ptr
->actual
.len
> 0)
1010 /* This is a positional arg */
1013 return _("can't mix positional and keyword arguments");
1021 return _("too many positional arguments");
1023 f
= (formal_entry
*) xmalloc (sizeof (formal_entry
));
1026 sb_new (&f
->actual
);
1030 for (pf
= &m
->formals
; *pf
!= NULL
; pf
= &(*pf
)->next
)
1031 if ((*pf
)->index
>= c
)
1032 c
= (*pf
)->index
+ 1;
1039 sb_reset (&f
->actual
);
1040 idx
= get_any_string (idx
, in
, &f
->actual
, 1, 0);
1041 if (f
->actual
.len
> 0)
1047 while (f
!= NULL
&& f
->index
< 0);
1051 idx
= sb_skip_comma (idx
, in
);
1054 if (in
->ptr
[idx
] == ',')
1056 if (ISWHITE (in
->ptr
[idx
]))
1066 sb_add_string (&t
, macro_strip_at
? "$NARG" : "NARG");
1067 ptr
= (formal_entry
*) hash_find (m
->formal_hash
, sb_terminate (&t
));
1068 sb_reset (&ptr
->actual
);
1069 sprintf (buffer
, "%d", narg
);
1070 sb_add_string (&ptr
->actual
, buffer
);
1073 err
= macro_expand_body (&m
->sub
, out
, m
->formals
, m
->formal_hash
,
1078 /* Discard any unnamed formal arguments. */
1086 if ((*pf
)->name
.len
!= 0)
1090 sb_kill (&(*pf
)->name
);
1091 sb_kill (&(*pf
)->def
);
1092 sb_kill (&(*pf
)->actual
);
1106 /* Check for a macro. If one is found, put the expansion into
1107 *EXPAND. COMMENT_CHAR is the comment character--this is used by
1108 gasp. Return 1 if a macro is found, 0 otherwise. */
1111 check_macro (line
, expand
, comment_char
, error
)
1122 if (! isalpha ((unsigned char) *line
)
1125 && (! macro_mri
|| *line
!= '.'))
1129 while (isalnum ((unsigned char) *s
)
1134 copy
= (char *) alloca (s
- line
+ 1);
1135 memcpy (copy
, line
, s
- line
);
1136 copy
[s
- line
] = '\0';
1137 for (cs
= copy
; *cs
!= '\0'; cs
++)
1138 if (isupper ((unsigned char) *cs
))
1139 *cs
= tolower (*cs
);
1141 macro
= (macro_entry
*) hash_find (macro_hash
, copy
);
1146 /* Wrap the line up in an sb. */
1148 while (*s
!= '\0' && *s
!= '\n' && *s
!= '\r')
1149 sb_add_char (&line_sb
, *s
++);
1152 *error
= macro_expand (0, &line_sb
, macro
, expand
, comment_char
);
1159 /* Delete a macro. */
1165 hash_delete (macro_hash
, name
);
1168 /* Handle the MRI IRP and IRPC pseudo-ops. These are handled as a
1169 combined macro definition and execution. This returns NULL on
1170 success, or an error message otherwise. */
1173 expand_irp (irpc
, idx
, in
, out
, get_line
, comment_char
)
1178 int (*get_line
) PARAMS ((sb
*));
1184 struct hash_control
*h
;
1192 idx
= sb_skip_white (idx
, in
);
1195 if (! buffer_and_nest (mn
, "ENDR", &sub
, get_line
))
1196 return _("unexpected end of file in irp or irpc");
1202 idx
= get_token (idx
, in
, &f
.name
);
1203 if (f
.name
.len
== 0)
1204 return _("missing model parameter");
1207 err
= hash_jam (h
, sb_terminate (&f
.name
), &f
);
1216 idx
= sb_skip_comma (idx
, in
);
1217 if (idx
>= in
->len
|| in
->ptr
[idx
] == comment_char
)
1219 /* Expand once with a null string. */
1220 err
= macro_expand_body (&sub
, out
, &f
, h
, comment_char
, 0);
1226 if (irpc
&& in
->ptr
[idx
] == '"')
1228 while (idx
< in
->len
&& in
->ptr
[idx
] != comment_char
)
1231 idx
= get_any_string (idx
, in
, &f
.actual
, 1, 0);
1234 if (in
->ptr
[idx
] == '"')
1238 nxt
= sb_skip_white (idx
+ 1, in
);
1239 if (nxt
>= in
->len
|| in
->ptr
[nxt
] == comment_char
)
1245 sb_reset (&f
.actual
);
1246 sb_add_char (&f
.actual
, in
->ptr
[idx
]);
1249 err
= macro_expand_body (&sub
, out
, &f
, h
, comment_char
, 0);
1253 idx
= sb_skip_comma (idx
, in
);
1255 idx
= sb_skip_white (idx
, in
);