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 /* Internal functions. */
75 static int get_token
PARAMS ((int, sb
*, sb
*));
76 static int getstring
PARAMS ((int, sb
*, sb
*));
77 static int get_any_string
PARAMS ((int, sb
*, sb
*, int, int));
78 static int do_formals
PARAMS ((macro_entry
*, int, sb
*));
79 static int get_apost_token
PARAMS ((int, sb
*, sb
*, int));
81 PARAMS ((int, sb
*, sb
*, struct hash_control
*, int, sb
*, int));
82 static const char *macro_expand_body
83 PARAMS ((sb
*, sb
*, formal_entry
*, struct hash_control
*, int, int));
84 static const char *macro_expand
PARAMS ((int, sb
*, macro_entry
*, sb
*, int));
86 #define ISWHITE(x) ((x) == ' ' || (x) == '\t')
89 ((x) == ' ' || (x) == '\t' || (x) == ',' || (x) == '"' || (x) == ';' \
90 || (x) == ')' || (x) == '(' \
91 || ((macro_alternate || macro_mri) && ((x) == '<' || (x) == '>')))
94 ((x) == 'b' || (x) == 'B' \
95 || (x) == 'q' || (x) == 'Q' \
96 || (x) == 'h' || (x) == 'H' \
97 || (x) == 'd' || (x) == 'D')
99 /* The macro hash table. */
101 static struct hash_control
*macro_hash
;
103 /* Whether any macros have been defined. */
107 /* Whether we are in GASP alternate mode. */
109 static int macro_alternate
;
111 /* Whether we are in MRI mode. */
113 static int macro_mri
;
115 /* Whether we should strip '@' characters. */
117 static int macro_strip_at
;
119 /* Function to use to parse an expression. */
121 static int (*macro_expr
) PARAMS ((const char *, int, sb
*, int *));
123 /* Number of macro expansions that have been done. */
125 static int macro_number
;
127 /* Initialize macro processing. */
130 macro_init (alternate
, mri
, strip_at
, expr
)
134 int (*expr
) PARAMS ((const char *, int, sb
*, int *));
136 macro_hash
= hash_new ();
138 macro_alternate
= alternate
;
140 macro_strip_at
= strip_at
;
144 /* Switch in and out of MRI mode on the fly. */
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. */
160 buffer_and_nest (from
, to
, ptr
, get_line
)
164 int (*get_line
) PARAMS ((sb
*));
166 int from_len
= strlen (from
);
167 int to_len
= strlen (to
);
169 int line_start
= ptr
->len
;
171 int more
= get_line (ptr
);
175 /* Try and find the first pseudo op on the line */
178 if (! macro_alternate
&& ! macro_mri
)
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
185 /* Skip leading whitespace */
186 while (i
< ptr
->len
&& ISWHITE (ptr
->ptr
[i
]))
189 /* Skip over a label */
191 && (isalnum ((unsigned char) ptr
->ptr
[i
])
192 || ptr
->ptr
[i
] == '_'
193 || ptr
->ptr
[i
] == '$'))
198 && ptr
->ptr
[i
] == ':')
202 /* Skip trailing whitespace */
203 while (i
< ptr
->len
&& ISWHITE (ptr
->ptr
[i
]))
206 if (i
< ptr
->len
&& (ptr
->ptr
[i
] == '.'
210 if (ptr
->ptr
[i
] == '.')
212 if (strncasecmp (ptr
->ptr
+ i
, from
, from_len
) == 0
213 && (ptr
->len
== (i
+ from_len
) || ! isalnum (ptr
->ptr
[i
+ from_len
])))
215 if (strncasecmp (ptr
->ptr
+ i
, to
, to_len
) == 0
216 && (ptr
->len
== (i
+ to_len
) || ! isalnum (ptr
->ptr
[i
+ to_len
])))
221 /* Reset the string to not include the ending rune */
222 ptr
->len
= line_start
;
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
);
234 /* Return 1 on success, 0 on unexpected EOF. */
238 /* Pick up a token. */
241 get_token (idx
, in
, name
)
247 && (isalpha ((unsigned char) in
->ptr
[idx
])
248 || in
->ptr
[idx
] == '_'
249 || in
->ptr
[idx
] == '$'))
251 sb_add_char (name
, in
->ptr
[idx
++]);
253 && (isalnum ((unsigned char) in
->ptr
[idx
])
254 || in
->ptr
[idx
] == '_'
255 || in
->ptr
[idx
] == '$'))
257 sb_add_char (name
, in
->ptr
[idx
++]);
260 /* Ignore trailing & */
261 if (macro_alternate
&& idx
< in
->len
&& in
->ptr
[idx
] == '&')
266 /* Pick up a string. */
269 getstring (idx
, in
, acc
)
274 idx
= sb_skip_white (idx
, in
);
277 && (in
->ptr
[idx
] == '"'
278 || (in
->ptr
[idx
] == '<' && (macro_alternate
|| macro_mri
))
279 || (in
->ptr
[idx
] == '\'' && macro_alternate
)))
281 if (in
->ptr
[idx
] == '<')
285 while ((in
->ptr
[idx
] != '>' || nest
)
288 if (in
->ptr
[idx
] == '!')
291 sb_add_char (acc
, in
->ptr
[idx
++]);
295 if (in
->ptr
[idx
] == '>')
297 if (in
->ptr
[idx
] == '<')
299 sb_add_char (acc
, in
->ptr
[idx
++]);
304 else if (in
->ptr
[idx
] == '"' || in
->ptr
[idx
] == '\'')
306 char tchar
= in
->ptr
[idx
];
311 while (idx
< in
->len
)
313 if (in
->ptr
[idx
-1] == '\\')
318 if (macro_alternate
&& in
->ptr
[idx
] == '!')
322 sb_add_char (acc
, in
->ptr
[idx
]);
326 else if (escaped
&& in
->ptr
[idx
] == tchar
)
328 sb_add_char (acc
, tchar
);
333 if (in
->ptr
[idx
] == tchar
)
337 if (idx
>= in
->len
|| in
->ptr
[idx
] != tchar
)
341 sb_add_char (acc
, in
->ptr
[idx
]);
351 /* Fetch string from the input stream,
353 'Bxyx<whitespace> -> return 'Bxyza
354 %<char> -> return string of decimal value of x
355 "<string>" -> return string
356 xyx<whitespace> -> return xyz
360 get_any_string (idx
, in
, out
, expand
, pretend_quoted
)
368 idx
= sb_skip_white (idx
, in
);
372 if (in
->len
> 2 && in
->ptr
[idx
+1] == '\'' && ISBASE (in
->ptr
[idx
]))
374 while (!ISSEP (in
->ptr
[idx
]))
375 sb_add_char (out
, in
->ptr
[idx
++]);
377 else if (in
->ptr
[idx
] == '%'
383 /* Turns the next expression into a string */
384 idx
= (*macro_expr
) (_("% operator needs absolute expression"),
388 sprintf(buf
, "%d", val
);
389 sb_add_string (out
, buf
);
391 else if (in
->ptr
[idx
] == '"'
392 || (in
->ptr
[idx
] == '<' && (macro_alternate
|| macro_mri
))
393 || (macro_alternate
&& in
->ptr
[idx
] == '\''))
399 /* Keep the quotes */
400 sb_add_char (out
, '\"');
402 idx
= getstring (idx
, in
, out
);
403 sb_add_char (out
, '\"');
407 idx
= getstring (idx
, in
, out
);
413 && (in
->ptr
[idx
] == '"'
414 || in
->ptr
[idx
] == '\''
416 || (in
->ptr
[idx
] != ' '
417 && in
->ptr
[idx
] != '\t'
418 && in
->ptr
[idx
] != ','
419 && (in
->ptr
[idx
] != '<'
420 || (! macro_alternate
&& ! macro_mri
)))))
422 if (in
->ptr
[idx
] == '"'
423 || in
->ptr
[idx
] == '\'')
425 char tchar
= in
->ptr
[idx
];
426 sb_add_char (out
, in
->ptr
[idx
++]);
428 && in
->ptr
[idx
] != tchar
)
429 sb_add_char (out
, in
->ptr
[idx
++]);
433 sb_add_char (out
, in
->ptr
[idx
++]);
441 /* Pick up the formal parameters of a macro definition. */
444 do_formals (macro
, idx
, in
)
449 formal_entry
**p
= ¯o
->formals
;
451 macro
->formal_count
= 0;
452 macro
->formal_hash
= hash_new ();
453 while (idx
< in
->len
)
455 formal_entry
*formal
;
457 formal
= (formal_entry
*) xmalloc (sizeof (formal_entry
));
459 sb_new (&formal
->name
);
460 sb_new (&formal
->def
);
461 sb_new (&formal
->actual
);
463 idx
= sb_skip_white (idx
, in
);
464 idx
= get_token (idx
, in
, &formal
->name
);
465 if (formal
->name
.len
== 0)
467 idx
= sb_skip_white (idx
, in
);
468 if (formal
->name
.len
)
470 /* This is a formal */
471 if (idx
< in
->len
&& in
->ptr
[idx
] == '=')
474 idx
= get_any_string (idx
+ 1, in
, &formal
->def
, 1, 0);
478 /* Add to macro's hash table */
479 hash_jam (macro
->formal_hash
, sb_terminate (&formal
->name
), formal
);
481 formal
->index
= macro
->formal_count
;
482 idx
= sb_skip_comma (idx
, in
);
483 macro
->formal_count
++;
491 formal_entry
*formal
;
494 /* Add a special NARG formal, which macro_expand will set to the
495 number of arguments. */
496 formal
= (formal_entry
*) xmalloc (sizeof (formal_entry
));
498 sb_new (&formal
->name
);
499 sb_new (&formal
->def
);
500 sb_new (&formal
->actual
);
502 /* The same MRI assemblers which treat '@' characters also use
503 the name $NARG. At least until we find an exception. */
509 sb_add_string (&formal
->name
, name
);
511 /* Add to macro's hash table */
512 hash_jam (macro
->formal_hash
, name
, formal
);
514 formal
->index
= NARG_INDEX
;
522 /* Define a new macro. Returns NULL on success, otherwise returns an
523 error message. If NAMEP is not NULL, *NAMEP is set to the name of
524 the macro which was defined. */
527 define_macro (idx
, in
, label
, get_line
, namep
)
531 int (*get_line
) PARAMS ((sb
*));
538 macro
= (macro_entry
*) xmalloc (sizeof (macro_entry
));
539 sb_new (¯o
->sub
);
542 macro
->formal_count
= 0;
545 idx
= sb_skip_white (idx
, in
);
546 if (! buffer_and_nest ("MACRO", "ENDM", ¯o
->sub
, get_line
))
547 return _("unexpected end of file in macro definition");
548 if (label
!= NULL
&& label
->len
!= 0)
550 sb_add_sb (&name
, label
);
551 if (idx
< in
->len
&& in
->ptr
[idx
] == '(')
553 /* It's the label: MACRO (formals,...) sort */
554 idx
= do_formals (macro
, idx
+ 1, in
);
555 if (in
->ptr
[idx
] != ')')
556 return _("missing ) after formals");
560 /* It's the label: MACRO formals,... sort */
561 idx
= do_formals (macro
, idx
, in
);
566 idx
= get_token (idx
, in
, &name
);
567 idx
= sb_skip_comma (idx
, in
);
568 idx
= do_formals (macro
, idx
, in
);
571 /* and stick it in the macro hash table */
572 for (idx
= 0; idx
< name
.len
; idx
++)
573 if (isupper ((unsigned char) name
.ptr
[idx
]))
574 name
.ptr
[idx
] = tolower (name
.ptr
[idx
]);
575 namestr
= sb_terminate (&name
);
576 hash_jam (macro_hash
, namestr
, (PTR
) macro
);
586 /* Scan a token, and then skip KIND. */
589 get_apost_token (idx
, in
, name
, kind
)
595 idx
= get_token (idx
, in
, name
);
597 && in
->ptr
[idx
] == kind
598 && (! macro_mri
|| macro_strip_at
)
599 && (! macro_strip_at
|| kind
== '@'))
604 /* Substitute the actual value for a formal parameter. */
607 sub_actual (start
, in
, t
, formal_hash
, kind
, out
, copyifnotthere
)
611 struct hash_control
*formal_hash
;
619 src
= get_apost_token (start
, in
, t
, kind
);
620 /* See if it's in the macro's hash table, unless this is
621 macro_strip_at and kind is '@' and the token did not end in '@'. */
624 && (src
== start
|| in
->ptr
[src
- 1] != '@'))
627 ptr
= (formal_entry
*) hash_find (formal_hash
, sb_terminate (t
));
632 sb_add_sb (out
, &ptr
->actual
);
636 sb_add_sb (out
, &ptr
->def
);
639 else if (kind
== '&')
641 /* Doing this permits people to use & in macro bodies. */
642 sb_add_char (out
, '&');
644 else if (copyifnotthere
)
650 sb_add_char (out
, '\\');
656 /* Expand the body of a macro. */
659 macro_expand_body (in
, out
, formals
, formal_hash
, comment_char
, locals
)
662 formal_entry
*formals
;
663 struct hash_control
*formal_hash
;
670 formal_entry
*loclist
= NULL
;
674 while (src
< in
->len
)
676 if (in
->ptr
[src
] == '&')
681 if (src
+ 1 < in
->len
&& in
->ptr
[src
+ 1] == '&')
682 src
= sub_actual (src
+ 2, in
, &t
, formal_hash
, '\'', out
, 1);
684 sb_add_char (out
, in
->ptr
[src
++]);
688 /* FIXME: Why do we do this? */
689 src
= sub_actual (src
+ 1, in
, &t
, formal_hash
, '&', out
, 0);
692 else if (in
->ptr
[src
] == '\\')
695 if (in
->ptr
[src
] == comment_char
&& comment_char
!= '\0')
697 /* This is a comment, just drop the rest of the line */
699 && in
->ptr
[src
] != '\n')
702 else if (in
->ptr
[src
] == '(')
704 /* Sub in till the next ')' literally */
706 while (src
< in
->len
&& in
->ptr
[src
] != ')')
708 sb_add_char (out
, in
->ptr
[src
++]);
710 if (in
->ptr
[src
] == ')')
713 return _("missplaced )");
715 else if (in
->ptr
[src
] == '@')
717 /* Sub in the macro invocation number */
721 sprintf (buffer
, "%d", macro_number
);
722 sb_add_string (out
, buffer
);
724 else if (in
->ptr
[src
] == '&')
726 /* This is a preprocessor variable name, we don't do them
728 sb_add_char (out
, '\\');
729 sb_add_char (out
, '&');
733 && isalnum ((unsigned char) in
->ptr
[src
]))
738 if (isdigit ((unsigned char) in
->ptr
[src
]))
739 ind
= in
->ptr
[src
] - '0';
740 else if (isupper ((unsigned char) in
->ptr
[src
]))
741 ind
= in
->ptr
[src
] - 'A' + 10;
743 ind
= in
->ptr
[src
] - 'a' + 10;
745 for (f
= formals
; f
!= NULL
; f
= f
->next
)
747 if (f
->index
== ind
- 1)
749 if (f
->actual
.len
!= 0)
750 sb_add_sb (out
, &f
->actual
);
752 sb_add_sb (out
, &f
->def
);
760 src
= sub_actual (src
, in
, &t
, formal_hash
, '\'', out
, 0);
763 else if ((macro_alternate
|| macro_mri
)
764 && (isalpha ((unsigned char) in
->ptr
[src
])
765 || in
->ptr
[src
] == '_'
766 || in
->ptr
[src
] == '$')
769 || (src
> 0 && in
->ptr
[src
- 1] == '@')))
772 || src
+ 5 >= in
->len
773 || strncasecmp (in
->ptr
+ src
, "LOCAL", 5) != 0
774 || ! ISWHITE (in
->ptr
[src
+ 5]))
777 src
= sub_actual (src
, in
, &t
, formal_hash
,
778 (macro_strip_at
&& inquote
) ? '@' : '\'',
785 src
= sb_skip_white (src
+ 5, in
);
786 while (in
->ptr
[src
] != '\n' && in
->ptr
[src
] != comment_char
)
792 f
= (formal_entry
*) xmalloc (sizeof (formal_entry
));
796 f
->index
= LOCAL_INDEX
;
800 src
= get_token (src
, in
, &f
->name
);
802 sprintf (buf
, "LL%04x", loccnt
);
803 sb_add_string (&f
->actual
, buf
);
805 err
= hash_jam (formal_hash
, sb_terminate (&f
->name
), f
);
809 src
= sb_skip_comma (src
, in
);
813 else if (comment_char
!= '\0'
814 && in
->ptr
[src
] == comment_char
816 && in
->ptr
[src
+ 1] == comment_char
819 /* Two comment chars in a row cause the rest of the line to
821 while (src
< in
->len
&& in
->ptr
[src
] != '\n')
824 else if (in
->ptr
[src
] == '"'
825 || (macro_mri
&& in
->ptr
[src
] == '\''))
828 sb_add_char (out
, in
->ptr
[src
++]);
830 else if (in
->ptr
[src
] == '@' && macro_strip_at
)
834 && in
->ptr
[src
] == '@')
836 sb_add_char (out
, '@');
841 && in
->ptr
[src
] == '='
843 && in
->ptr
[src
+ 1] == '=')
848 src
= get_token (src
+ 2, in
, &t
);
849 ptr
= (formal_entry
*) hash_find (formal_hash
, sb_terminate (&t
));
852 /* FIXME: We should really return a warning string here,
853 but we can't, because the == might be in the MRI
854 comment field, and, since the nature of the MRI
855 comment field depends upon the exact instruction
856 being used, we don't have enough information here to
857 figure out whether it is or not. Instead, we leave
858 the == in place, which should cause a syntax error if
859 it is not in a comment. */
860 sb_add_char (out
, '=');
861 sb_add_char (out
, '=');
868 sb_add_string (out
, "-1");
872 sb_add_char (out
, '0');
878 sb_add_char (out
, in
->ptr
[src
++]);
884 while (loclist
!= NULL
)
889 /* Setting the value to NULL effectively deletes the entry. We
890 avoid calling hash_delete because it doesn't reclaim memory. */
891 hash_jam (formal_hash
, sb_terminate (&loclist
->name
), NULL
);
892 sb_kill (&loclist
->name
);
893 sb_kill (&loclist
->def
);
894 sb_kill (&loclist
->actual
);
902 /* Assign values to the formal parameters of a macro, and expand the
906 macro_expand (idx
, in
, m
, out
, comment_char
)
916 int is_positional
= 0;
923 /* Reset any old value the actuals may have */
924 for (f
= m
->formals
; f
; f
= f
->next
)
925 sb_reset (&f
->actual
);
927 while (f
!= NULL
&& f
->index
< 0)
932 /* The macro may be called with an optional qualifier, which may
933 be referred to in the macro body as \0. */
934 if (idx
< in
->len
&& in
->ptr
[idx
] == '.')
938 n
= (formal_entry
*) xmalloc (sizeof (formal_entry
));
942 n
->index
= QUAL_INDEX
;
944 n
->next
= m
->formals
;
947 idx
= get_any_string (idx
+ 1, in
, &n
->actual
, 1, 0);
951 /* Peel off the actuals and store them away in the hash tables' actuals */
952 idx
= sb_skip_white (idx
, in
);
953 while (idx
< in
->len
&& in
->ptr
[idx
] != comment_char
)
957 /* Look and see if it's a positional or keyword arg */
959 while (scan
< in
->len
960 && !ISSEP (in
->ptr
[scan
])
961 && !(macro_mri
&& in
->ptr
[scan
] == '\'')
962 && (!macro_alternate
&& in
->ptr
[scan
] != '='))
964 if (scan
< in
->len
&& !macro_alternate
&& in
->ptr
[scan
] == '=')
968 /* It's OK to go from positional to keyword. */
970 /* This is a keyword arg, fetch the formal name and
971 then the actual stuff */
973 idx
= get_token (idx
, in
, &t
);
974 if (in
->ptr
[idx
] != '=')
975 return _("confusion in formal parameters");
977 /* Lookup the formal in the macro's list */
978 ptr
= (formal_entry
*) hash_find (m
->formal_hash
, sb_terminate (&t
));
980 return _("macro formal argument does not exist");
983 /* Insert this value into the right place */
984 sb_reset (&ptr
->actual
);
985 idx
= get_any_string (idx
+ 1, in
, &ptr
->actual
, 0, 0);
986 if (ptr
->actual
.len
> 0)
992 /* This is a positional arg */
995 return _("can't mix positional and keyword arguments");
1003 return _("too many positional arguments");
1005 f
= (formal_entry
*) xmalloc (sizeof (formal_entry
));
1008 sb_new (&f
->actual
);
1012 for (pf
= &m
->formals
; *pf
!= NULL
; pf
= &(*pf
)->next
)
1013 if ((*pf
)->index
>= c
)
1014 c
= (*pf
)->index
+ 1;
1021 sb_reset (&f
->actual
);
1022 idx
= get_any_string (idx
, in
, &f
->actual
, 1, 0);
1023 if (f
->actual
.len
> 0)
1029 while (f
!= NULL
&& f
->index
< 0);
1033 idx
= sb_skip_comma (idx
, in
);
1036 if (in
->ptr
[idx
] == ',')
1038 if (ISWHITE (in
->ptr
[idx
]))
1048 sb_add_string (&t
, macro_strip_at
? "$NARG" : "NARG");
1049 ptr
= (formal_entry
*) hash_find (m
->formal_hash
, sb_terminate (&t
));
1050 sb_reset (&ptr
->actual
);
1051 sprintf (buffer
, "%d", narg
);
1052 sb_add_string (&ptr
->actual
, buffer
);
1055 err
= macro_expand_body (&m
->sub
, out
, m
->formals
, m
->formal_hash
,
1060 /* Discard any unnamed formal arguments. */
1068 if ((*pf
)->name
.len
!= 0)
1072 sb_kill (&(*pf
)->name
);
1073 sb_kill (&(*pf
)->def
);
1074 sb_kill (&(*pf
)->actual
);
1088 /* Check for a macro. If one is found, put the expansion into
1089 *EXPAND. COMMENT_CHAR is the comment character--this is used by
1090 gasp. Return 1 if a macro is found, 0 otherwise. */
1093 check_macro (line
, expand
, comment_char
, error
, info
)
1105 if (! isalpha ((unsigned char) *line
)
1108 && (! macro_mri
|| *line
!= '.'))
1112 while (isalnum ((unsigned char) *s
)
1117 copy
= (char *) alloca (s
- line
+ 1);
1118 memcpy (copy
, line
, s
- line
);
1119 copy
[s
- line
] = '\0';
1120 for (cs
= copy
; *cs
!= '\0'; cs
++)
1121 if (isupper ((unsigned char) *cs
))
1122 *cs
= tolower (*cs
);
1124 macro
= (macro_entry
*) hash_find (macro_hash
, copy
);
1129 /* Wrap the line up in an sb. */
1131 while (*s
!= '\0' && *s
!= '\n' && *s
!= '\r')
1132 sb_add_char (&line_sb
, *s
++);
1135 *error
= macro_expand (0, &line_sb
, macro
, expand
, comment_char
);
1139 /* export the macro information if requested */
1146 /* Delete a macro. */
1152 hash_delete (macro_hash
, name
);
1155 /* Handle the MRI IRP and IRPC pseudo-ops. These are handled as a
1156 combined macro definition and execution. This returns NULL on
1157 success, or an error message otherwise. */
1160 expand_irp (irpc
, idx
, in
, out
, get_line
, comment_char
)
1165 int (*get_line
) PARAMS ((sb
*));
1171 struct hash_control
*h
;
1179 idx
= sb_skip_white (idx
, in
);
1182 if (! buffer_and_nest (mn
, "ENDR", &sub
, get_line
))
1183 return _("unexpected end of file in irp or irpc");
1189 idx
= get_token (idx
, in
, &f
.name
);
1190 if (f
.name
.len
== 0)
1191 return _("missing model parameter");
1194 err
= hash_jam (h
, sb_terminate (&f
.name
), &f
);
1203 idx
= sb_skip_comma (idx
, in
);
1204 if (idx
>= in
->len
|| in
->ptr
[idx
] == comment_char
)
1206 /* Expand once with a null string. */
1207 err
= macro_expand_body (&sub
, out
, &f
, h
, comment_char
, 0);
1213 if (irpc
&& in
->ptr
[idx
] == '"')
1215 while (idx
< in
->len
&& in
->ptr
[idx
] != comment_char
)
1218 idx
= get_any_string (idx
, in
, &f
.actual
, 1, 0);
1221 if (in
->ptr
[idx
] == '"')
1225 nxt
= sb_skip_white (idx
+ 1, in
);
1226 if (nxt
>= in
->len
|| in
->ptr
[nxt
] == comment_char
)
1232 sb_reset (&f
.actual
);
1233 sb_add_char (&f
.actual
, in
->ptr
[idx
]);
1236 err
= macro_expand_body (&sub
, out
, &f
, h
, comment_char
, 0);
1240 idx
= sb_skip_comma (idx
, in
);
1242 idx
= sb_skip_white (idx
, in
);