1 /* macro.c - macro support for gas and gasp
2 Copyright 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001
3 Free Software Foundation, Inc.
5 Written by Steve and Judy Chamberlain of Cygnus Support,
8 This file is part of GAS, the GNU Assembler.
10 GAS is free software; you can redistribute it and/or modify
11 it under the terms of the GNU General Public License as published by
12 the Free Software Foundation; either version 2, or (at your option)
15 GAS is distributed in the hope that it will be useful,
16 but WITHOUT ANY WARRANTY; without even the implied warranty of
17 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 GNU General Public License for more details.
20 You should have received a copy of the GNU General Public License
21 along with GAS; see the file COPYING. If not, write to the Free
22 Software Foundation, 59 Temple Place - Suite 330, Boston, MA
32 /* Indented so that pre-ansi C compilers will ignore it, rather than
33 choke on it. Some versions of AIX require this to be the first
37 # ifndef alloca /* predefined by HP cc +Olibcalls */
38 # if !defined (__STDC__) && !defined (__hpux)
39 extern char *alloca ();
41 extern void *alloca ();
42 # endif /* __STDC__, __hpux */
45 # endif /* HAVE_ALLOCA_H */
57 #include "libiberty.h"
58 #include "safe-ctype.h"
65 /* The routines in this file handle macro definition and expansion.
66 They are called by both gasp and gas. */
68 /* Internal functions. */
70 static int get_token
PARAMS ((int, sb
*, sb
*));
71 static int getstring
PARAMS ((int, sb
*, sb
*));
72 static int get_any_string
PARAMS ((int, sb
*, sb
*, int, int));
73 static int do_formals
PARAMS ((macro_entry
*, int, sb
*));
74 static int get_apost_token
PARAMS ((int, sb
*, sb
*, int));
76 PARAMS ((int, sb
*, sb
*, struct hash_control
*, int, sb
*, int));
77 static const char *macro_expand_body
78 PARAMS ((sb
*, sb
*, formal_entry
*, struct hash_control
*, int, int));
79 static const char *macro_expand
PARAMS ((int, sb
*, macro_entry
*, sb
*, int));
81 #define ISWHITE(x) ((x) == ' ' || (x) == '\t')
84 ((x) == ' ' || (x) == '\t' || (x) == ',' || (x) == '"' || (x) == ';' \
85 || (x) == ')' || (x) == '(' \
86 || ((macro_alternate || macro_mri) && ((x) == '<' || (x) == '>')))
89 ((x) == 'b' || (x) == 'B' \
90 || (x) == 'q' || (x) == 'Q' \
91 || (x) == 'h' || (x) == 'H' \
92 || (x) == 'd' || (x) == 'D')
94 /* The macro hash table. */
96 static struct hash_control
*macro_hash
;
98 /* Whether any macros have been defined. */
102 /* Whether we are in GASP alternate mode. */
104 static int macro_alternate
;
106 /* Whether we are in MRI mode. */
108 static int macro_mri
;
110 /* Whether we should strip '@' characters. */
112 static int macro_strip_at
;
114 /* Function to use to parse an expression. */
116 static int (*macro_expr
) PARAMS ((const char *, int, sb
*, int *));
118 /* Number of macro expansions that have been done. */
120 static int macro_number
;
122 /* Initialize macro processing. */
125 macro_init (alternate
, mri
, strip_at
, expr
)
129 int (*expr
) PARAMS ((const char *, int, sb
*, int *));
131 macro_hash
= hash_new ();
133 macro_alternate
= alternate
;
135 macro_strip_at
= strip_at
;
139 /* Switch in and out of MRI mode on the fly. */
148 /* Read input lines till we get to a TO string.
149 Increase nesting depth if we get a FROM string.
150 Put the results into sb at PTR.
151 Add a new input line to an sb using GET_LINE.
152 Return 1 on success, 0 on unexpected EOF. */
155 buffer_and_nest (from
, to
, ptr
, get_line
)
159 int (*get_line
) PARAMS ((sb
*));
161 int from_len
= strlen (from
);
162 int to_len
= strlen (to
);
164 int line_start
= ptr
->len
;
166 int more
= get_line (ptr
);
170 /* Try and find the first pseudo op on the line. */
173 if (! macro_alternate
&& ! macro_mri
)
175 /* With normal syntax we can suck what we want till we get
176 to the dot. With the alternate, labels have to start in
177 the first column, since we cant tell what's a label and
180 /* Skip leading whitespace. */
181 while (i
< ptr
->len
&& ISWHITE (ptr
->ptr
[i
]))
184 /* Skip over a label. */
186 && (ISALNUM (ptr
->ptr
[i
])
187 || ptr
->ptr
[i
] == '_'
188 || ptr
->ptr
[i
] == '$'))
193 && ptr
->ptr
[i
] == ':')
197 /* Skip trailing whitespace. */
198 while (i
< ptr
->len
&& ISWHITE (ptr
->ptr
[i
]))
201 if (i
< ptr
->len
&& (ptr
->ptr
[i
] == '.'
205 if (ptr
->ptr
[i
] == '.')
207 if (strncasecmp (ptr
->ptr
+ i
, from
, from_len
) == 0
208 && (ptr
->len
== (i
+ from_len
)
209 || ! ISALNUM (ptr
->ptr
[i
+ from_len
])))
211 if (strncasecmp (ptr
->ptr
+ i
, to
, to_len
) == 0
212 && (ptr
->len
== (i
+ to_len
)
213 || ! ISALNUM (ptr
->ptr
[i
+ to_len
])))
218 /* Reset the string to not include the ending rune. */
219 ptr
->len
= line_start
;
225 /* Add a CR to the end and keep running. */
226 sb_add_char (ptr
, '\n');
227 line_start
= ptr
->len
;
228 more
= get_line (ptr
);
231 /* Return 1 on success, 0 on unexpected EOF. */
235 /* Pick up a token. */
238 get_token (idx
, in
, name
)
244 && (ISALPHA (in
->ptr
[idx
])
245 || in
->ptr
[idx
] == '_'
246 || in
->ptr
[idx
] == '$'))
248 sb_add_char (name
, in
->ptr
[idx
++]);
250 && (ISALNUM (in
->ptr
[idx
])
251 || in
->ptr
[idx
] == '_'
252 || in
->ptr
[idx
] == '$'))
254 sb_add_char (name
, in
->ptr
[idx
++]);
257 /* Ignore trailing &. */
258 if (macro_alternate
&& idx
< in
->len
&& in
->ptr
[idx
] == '&')
263 /* Pick up a string. */
266 getstring (idx
, in
, acc
)
271 idx
= sb_skip_white (idx
, in
);
274 && (in
->ptr
[idx
] == '"'
275 || (in
->ptr
[idx
] == '<' && (macro_alternate
|| macro_mri
))
276 || (in
->ptr
[idx
] == '\'' && macro_alternate
)))
278 if (in
->ptr
[idx
] == '<')
282 while ((in
->ptr
[idx
] != '>' || nest
)
285 if (in
->ptr
[idx
] == '!')
288 sb_add_char (acc
, in
->ptr
[idx
++]);
292 if (in
->ptr
[idx
] == '>')
294 if (in
->ptr
[idx
] == '<')
296 sb_add_char (acc
, in
->ptr
[idx
++]);
301 else if (in
->ptr
[idx
] == '"' || in
->ptr
[idx
] == '\'')
303 char tchar
= in
->ptr
[idx
];
308 while (idx
< in
->len
)
310 if (in
->ptr
[idx
- 1] == '\\')
315 if (macro_alternate
&& in
->ptr
[idx
] == '!')
319 sb_add_char (acc
, in
->ptr
[idx
]);
323 else if (escaped
&& in
->ptr
[idx
] == tchar
)
325 sb_add_char (acc
, tchar
);
330 if (in
->ptr
[idx
] == tchar
)
334 if (idx
>= in
->len
|| in
->ptr
[idx
] != tchar
)
338 sb_add_char (acc
, in
->ptr
[idx
]);
348 /* Fetch string from the input stream,
350 'Bxyx<whitespace> -> return 'Bxyza
351 %<char> -> return string of decimal value of x
352 "<string>" -> return string
353 xyx<whitespace> -> return xyz
357 get_any_string (idx
, in
, out
, expand
, pretend_quoted
)
365 idx
= sb_skip_white (idx
, in
);
369 if (in
->len
> 2 && in
->ptr
[idx
+ 1] == '\'' && ISBASE (in
->ptr
[idx
]))
371 while (!ISSEP (in
->ptr
[idx
]))
372 sb_add_char (out
, in
->ptr
[idx
++]);
374 else if (in
->ptr
[idx
] == '%'
380 /* Turns the next expression into a string. */
381 idx
= (*macro_expr
) (_("% operator needs absolute expression"),
385 sprintf(buf
, "%d", val
);
386 sb_add_string (out
, buf
);
388 else if (in
->ptr
[idx
] == '"'
389 || (in
->ptr
[idx
] == '<' && (macro_alternate
|| macro_mri
))
390 || (macro_alternate
&& in
->ptr
[idx
] == '\''))
396 /* Keep the quotes. */
397 sb_add_char (out
, '\"');
399 idx
= getstring (idx
, in
, out
);
400 sb_add_char (out
, '\"');
404 idx
= getstring (idx
, in
, out
);
410 && (in
->ptr
[idx
] == '"'
411 || in
->ptr
[idx
] == '\''
413 || (in
->ptr
[idx
] != ' '
414 && in
->ptr
[idx
] != '\t'
415 && in
->ptr
[idx
] != ','
416 && (in
->ptr
[idx
] != '<'
417 || (! macro_alternate
&& ! macro_mri
)))))
419 if (in
->ptr
[idx
] == '"'
420 || in
->ptr
[idx
] == '\'')
422 char tchar
= in
->ptr
[idx
];
423 sb_add_char (out
, in
->ptr
[idx
++]);
425 && in
->ptr
[idx
] != tchar
)
426 sb_add_char (out
, in
->ptr
[idx
++]);
430 sb_add_char (out
, in
->ptr
[idx
++]);
438 /* Pick up the formal parameters of a macro definition. */
441 do_formals (macro
, idx
, in
)
446 formal_entry
**p
= ¯o
->formals
;
448 macro
->formal_count
= 0;
449 macro
->formal_hash
= hash_new ();
450 while (idx
< in
->len
)
452 formal_entry
*formal
;
454 formal
= (formal_entry
*) xmalloc (sizeof (formal_entry
));
456 sb_new (&formal
->name
);
457 sb_new (&formal
->def
);
458 sb_new (&formal
->actual
);
460 idx
= sb_skip_white (idx
, in
);
461 idx
= get_token (idx
, in
, &formal
->name
);
462 if (formal
->name
.len
== 0)
464 idx
= sb_skip_white (idx
, in
);
465 if (formal
->name
.len
)
467 /* This is a formal. */
468 if (idx
< in
->len
&& in
->ptr
[idx
] == '=')
471 idx
= get_any_string (idx
+ 1, in
, &formal
->def
, 1, 0);
475 /* Add to macro's hash table. */
476 hash_jam (macro
->formal_hash
, sb_terminate (&formal
->name
), formal
);
478 formal
->index
= macro
->formal_count
;
479 idx
= sb_skip_comma (idx
, in
);
480 macro
->formal_count
++;
488 formal_entry
*formal
;
491 /* Add a special NARG formal, which macro_expand will set to the
492 number of arguments. */
493 formal
= (formal_entry
*) xmalloc (sizeof (formal_entry
));
495 sb_new (&formal
->name
);
496 sb_new (&formal
->def
);
497 sb_new (&formal
->actual
);
499 /* The same MRI assemblers which treat '@' characters also use
500 the name $NARG. At least until we find an exception. */
506 sb_add_string (&formal
->name
, name
);
508 /* Add to macro's hash table. */
509 hash_jam (macro
->formal_hash
, name
, formal
);
511 formal
->index
= NARG_INDEX
;
519 /* Define a new macro. Returns NULL on success, otherwise returns an
520 error message. If NAMEP is not NULL, *NAMEP is set to the name of
521 the macro which was defined. */
524 define_macro (idx
, in
, label
, get_line
, namep
)
528 int (*get_line
) PARAMS ((sb
*));
535 macro
= (macro_entry
*) xmalloc (sizeof (macro_entry
));
536 sb_new (¯o
->sub
);
539 macro
->formal_count
= 0;
542 idx
= sb_skip_white (idx
, in
);
543 if (! buffer_and_nest ("MACRO", "ENDM", ¯o
->sub
, get_line
))
544 return _("unexpected end of file in macro definition");
545 if (label
!= NULL
&& label
->len
!= 0)
547 sb_add_sb (&name
, label
);
548 if (idx
< in
->len
&& in
->ptr
[idx
] == '(')
550 /* It's the label: MACRO (formals,...) sort */
551 idx
= do_formals (macro
, idx
+ 1, in
);
552 if (in
->ptr
[idx
] != ')')
553 return _("missing ) after formals");
557 /* It's the label: MACRO formals,... sort */
558 idx
= do_formals (macro
, idx
, in
);
563 idx
= get_token (idx
, in
, &name
);
564 idx
= sb_skip_comma (idx
, in
);
565 idx
= do_formals (macro
, idx
, in
);
568 /* And stick it in the macro hash table. */
569 for (idx
= 0; idx
< name
.len
; idx
++)
570 name
.ptr
[idx
] = TOLOWER (name
.ptr
[idx
]);
571 namestr
= sb_terminate (&name
);
572 hash_jam (macro_hash
, namestr
, (PTR
) macro
);
582 /* Scan a token, and then skip KIND. */
585 get_apost_token (idx
, in
, name
, kind
)
591 idx
= get_token (idx
, in
, name
);
593 && in
->ptr
[idx
] == kind
594 && (! macro_mri
|| macro_strip_at
)
595 && (! macro_strip_at
|| kind
== '@'))
600 /* Substitute the actual value for a formal parameter. */
603 sub_actual (start
, in
, t
, formal_hash
, kind
, out
, copyifnotthere
)
607 struct hash_control
*formal_hash
;
615 src
= get_apost_token (start
, in
, t
, kind
);
616 /* See if it's in the macro's hash table, unless this is
617 macro_strip_at and kind is '@' and the token did not end in '@'. */
620 && (src
== start
|| in
->ptr
[src
- 1] != '@'))
623 ptr
= (formal_entry
*) hash_find (formal_hash
, sb_terminate (t
));
628 sb_add_sb (out
, &ptr
->actual
);
632 sb_add_sb (out
, &ptr
->def
);
635 else if (kind
== '&')
637 /* Doing this permits people to use & in macro bodies. */
638 sb_add_char (out
, '&');
640 else if (copyifnotthere
)
646 sb_add_char (out
, '\\');
652 /* Expand the body of a macro. */
655 macro_expand_body (in
, out
, formals
, formal_hash
, comment_char
, locals
)
658 formal_entry
*formals
;
659 struct hash_control
*formal_hash
;
666 formal_entry
*loclist
= NULL
;
670 while (src
< in
->len
)
672 if (in
->ptr
[src
] == '&')
677 if (src
+ 1 < in
->len
&& in
->ptr
[src
+ 1] == '&')
678 src
= sub_actual (src
+ 2, in
, &t
, formal_hash
, '\'', out
, 1);
680 sb_add_char (out
, in
->ptr
[src
++]);
684 /* FIXME: Why do we do this? */
685 src
= sub_actual (src
+ 1, in
, &t
, formal_hash
, '&', out
, 0);
688 else if (in
->ptr
[src
] == '\\')
691 if (in
->ptr
[src
] == comment_char
&& comment_char
!= '\0')
693 /* This is a comment, just drop the rest of the line. */
695 && in
->ptr
[src
] != '\n')
698 else if (in
->ptr
[src
] == '(')
700 /* Sub in till the next ')' literally. */
702 while (src
< in
->len
&& in
->ptr
[src
] != ')')
704 sb_add_char (out
, in
->ptr
[src
++]);
706 if (in
->ptr
[src
] == ')')
709 return _("missplaced )");
711 else if (in
->ptr
[src
] == '@')
713 /* Sub in the macro invocation number. */
717 sprintf (buffer
, "%d", macro_number
);
718 sb_add_string (out
, buffer
);
720 else if (in
->ptr
[src
] == '&')
722 /* This is a preprocessor variable name, we don't do them
724 sb_add_char (out
, '\\');
725 sb_add_char (out
, '&');
728 else if (macro_mri
&& ISALNUM (in
->ptr
[src
]))
733 if (ISDIGIT (in
->ptr
[src
]))
734 ind
= in
->ptr
[src
] - '0';
735 else if (ISUPPER (in
->ptr
[src
]))
736 ind
= in
->ptr
[src
] - 'A' + 10;
738 ind
= in
->ptr
[src
] - 'a' + 10;
740 for (f
= formals
; f
!= NULL
; f
= f
->next
)
742 if (f
->index
== ind
- 1)
744 if (f
->actual
.len
!= 0)
745 sb_add_sb (out
, &f
->actual
);
747 sb_add_sb (out
, &f
->def
);
755 src
= sub_actual (src
, in
, &t
, formal_hash
, '\'', out
, 0);
758 else if ((macro_alternate
|| macro_mri
)
759 && (ISALPHA (in
->ptr
[src
])
760 || in
->ptr
[src
] == '_'
761 || in
->ptr
[src
] == '$')
764 || (src
> 0 && in
->ptr
[src
- 1] == '@')))
767 || src
+ 5 >= in
->len
768 || strncasecmp (in
->ptr
+ src
, "LOCAL", 5) != 0
769 || ! ISWHITE (in
->ptr
[src
+ 5]))
772 src
= sub_actual (src
, in
, &t
, formal_hash
,
773 (macro_strip_at
&& inquote
) ? '@' : '\'',
780 src
= sb_skip_white (src
+ 5, in
);
781 while (in
->ptr
[src
] != '\n' && in
->ptr
[src
] != comment_char
)
787 f
= (formal_entry
*) xmalloc (sizeof (formal_entry
));
791 f
->index
= LOCAL_INDEX
;
795 src
= get_token (src
, in
, &f
->name
);
797 sprintf (buf
, "LL%04x", loccnt
);
798 sb_add_string (&f
->actual
, buf
);
800 err
= hash_jam (formal_hash
, sb_terminate (&f
->name
), f
);
804 src
= sb_skip_comma (src
, in
);
808 else if (comment_char
!= '\0'
809 && in
->ptr
[src
] == comment_char
811 && in
->ptr
[src
+ 1] == comment_char
814 /* Two comment chars in a row cause the rest of the line to
816 while (src
< in
->len
&& in
->ptr
[src
] != '\n')
819 else if (in
->ptr
[src
] == '"'
820 || (macro_mri
&& in
->ptr
[src
] == '\''))
823 sb_add_char (out
, in
->ptr
[src
++]);
825 else if (in
->ptr
[src
] == '@' && macro_strip_at
)
829 && in
->ptr
[src
] == '@')
831 sb_add_char (out
, '@');
836 && in
->ptr
[src
] == '='
838 && in
->ptr
[src
+ 1] == '=')
843 src
= get_token (src
+ 2, in
, &t
);
844 ptr
= (formal_entry
*) hash_find (formal_hash
, sb_terminate (&t
));
847 /* FIXME: We should really return a warning string here,
848 but we can't, because the == might be in the MRI
849 comment field, and, since the nature of the MRI
850 comment field depends upon the exact instruction
851 being used, we don't have enough information here to
852 figure out whether it is or not. Instead, we leave
853 the == in place, which should cause a syntax error if
854 it is not in a comment. */
855 sb_add_char (out
, '=');
856 sb_add_char (out
, '=');
863 sb_add_string (out
, "-1");
867 sb_add_char (out
, '0');
873 sb_add_char (out
, in
->ptr
[src
++]);
879 while (loclist
!= NULL
)
884 /* Setting the value to NULL effectively deletes the entry. We
885 avoid calling hash_delete because it doesn't reclaim memory. */
886 hash_jam (formal_hash
, sb_terminate (&loclist
->name
), NULL
);
887 sb_kill (&loclist
->name
);
888 sb_kill (&loclist
->def
);
889 sb_kill (&loclist
->actual
);
897 /* Assign values to the formal parameters of a macro, and expand the
901 macro_expand (idx
, in
, m
, out
, comment_char
)
911 int is_positional
= 0;
918 /* Reset any old value the actuals may have. */
919 for (f
= m
->formals
; f
; f
= f
->next
)
920 sb_reset (&f
->actual
);
922 while (f
!= NULL
&& f
->index
< 0)
927 /* The macro may be called with an optional qualifier, which may
928 be referred to in the macro body as \0. */
929 if (idx
< in
->len
&& in
->ptr
[idx
] == '.')
931 /* The Microtec assembler ignores this if followed by a white space.
932 (Macro invocation with empty extension) */
935 && in
->ptr
[idx
] != ' '
936 && in
->ptr
[idx
] != '\t')
940 n
= (formal_entry
*) xmalloc (sizeof (formal_entry
));
944 n
->index
= QUAL_INDEX
;
946 n
->next
= m
->formals
;
949 idx
= get_any_string (idx
, in
, &n
->actual
, 1, 0);
954 /* Peel off the actuals and store them away in the hash tables' actuals. */
955 idx
= sb_skip_white (idx
, in
);
956 while (idx
< in
->len
&& in
->ptr
[idx
] != comment_char
)
960 /* Look and see if it's a positional or keyword arg. */
962 while (scan
< in
->len
963 && !ISSEP (in
->ptr
[scan
])
964 && !(macro_mri
&& in
->ptr
[scan
] == '\'')
965 && (!macro_alternate
&& in
->ptr
[scan
] != '='))
967 if (scan
< in
->len
&& !macro_alternate
&& in
->ptr
[scan
] == '=')
971 /* It's OK to go from positional to keyword. */
973 /* This is a keyword arg, fetch the formal name and
974 then the actual stuff. */
976 idx
= get_token (idx
, in
, &t
);
977 if (in
->ptr
[idx
] != '=')
978 return _("confusion in formal parameters");
980 /* Lookup the formal in the macro's list. */
981 ptr
= (formal_entry
*) hash_find (m
->formal_hash
, sb_terminate (&t
));
983 return _("macro formal argument does not exist");
986 /* Insert this value into the right place. */
987 sb_reset (&ptr
->actual
);
988 idx
= get_any_string (idx
+ 1, in
, &ptr
->actual
, 0, 0);
989 if (ptr
->actual
.len
> 0)
995 /* This is a positional arg. */
998 return _("can't mix positional and keyword arguments");
1006 return _("too many positional arguments");
1008 f
= (formal_entry
*) xmalloc (sizeof (formal_entry
));
1011 sb_new (&f
->actual
);
1015 for (pf
= &m
->formals
; *pf
!= NULL
; pf
= &(*pf
)->next
)
1016 if ((*pf
)->index
>= c
)
1017 c
= (*pf
)->index
+ 1;
1024 sb_reset (&f
->actual
);
1025 idx
= get_any_string (idx
, in
, &f
->actual
, 1, 0);
1026 if (f
->actual
.len
> 0)
1032 while (f
!= NULL
&& f
->index
< 0);
1036 idx
= sb_skip_comma (idx
, in
);
1039 if (in
->ptr
[idx
] == ',')
1041 if (ISWHITE (in
->ptr
[idx
]))
1051 sb_add_string (&t
, macro_strip_at
? "$NARG" : "NARG");
1052 ptr
= (formal_entry
*) hash_find (m
->formal_hash
, sb_terminate (&t
));
1053 sb_reset (&ptr
->actual
);
1054 sprintf (buffer
, "%d", narg
);
1055 sb_add_string (&ptr
->actual
, buffer
);
1058 err
= macro_expand_body (&m
->sub
, out
, m
->formals
, m
->formal_hash
,
1063 /* Discard any unnamed formal arguments. */
1071 if ((*pf
)->name
.len
!= 0)
1075 sb_kill (&(*pf
)->name
);
1076 sb_kill (&(*pf
)->def
);
1077 sb_kill (&(*pf
)->actual
);
1091 /* Check for a macro. If one is found, put the expansion into
1092 *EXPAND. COMMENT_CHAR is the comment character--this is used by
1093 gasp. Return 1 if a macro is found, 0 otherwise. */
1096 check_macro (line
, expand
, comment_char
, error
, info
)
1108 if (! ISALPHA (*line
)
1111 && (! macro_mri
|| *line
!= '.'))
1120 copy
= (char *) alloca (s
- line
+ 1);
1121 memcpy (copy
, line
, s
- line
);
1122 copy
[s
- line
] = '\0';
1123 for (cs
= copy
; *cs
!= '\0'; cs
++)
1124 *cs
= TOLOWER (*cs
);
1126 macro
= (macro_entry
*) hash_find (macro_hash
, copy
);
1131 /* Wrap the line up in an sb. */
1133 while (*s
!= '\0' && *s
!= '\n' && *s
!= '\r')
1134 sb_add_char (&line_sb
, *s
++);
1137 *error
= macro_expand (0, &line_sb
, macro
, expand
, comment_char
);
1141 /* Export the macro information if requested. */
1148 /* Delete a macro. */
1154 hash_delete (macro_hash
, name
);
1157 /* Handle the MRI IRP and IRPC pseudo-ops. These are handled as a
1158 combined macro definition and execution. This returns NULL on
1159 success, or an error message otherwise. */
1162 expand_irp (irpc
, idx
, in
, out
, get_line
, comment_char
)
1167 int (*get_line
) PARAMS ((sb
*));
1173 struct hash_control
*h
;
1181 idx
= sb_skip_white (idx
, in
);
1184 if (! buffer_and_nest (mn
, "ENDR", &sub
, get_line
))
1185 return _("unexpected end of file in irp or irpc");
1191 idx
= get_token (idx
, in
, &f
.name
);
1192 if (f
.name
.len
== 0)
1193 return _("missing model parameter");
1196 err
= hash_jam (h
, sb_terminate (&f
.name
), &f
);
1205 idx
= sb_skip_comma (idx
, in
);
1206 if (idx
>= in
->len
|| in
->ptr
[idx
] == comment_char
)
1208 /* Expand once with a null string. */
1209 err
= macro_expand_body (&sub
, out
, &f
, h
, comment_char
, 0);
1215 if (irpc
&& in
->ptr
[idx
] == '"')
1217 while (idx
< in
->len
&& in
->ptr
[idx
] != comment_char
)
1220 idx
= get_any_string (idx
, in
, &f
.actual
, 1, 0);
1223 if (in
->ptr
[idx
] == '"')
1227 nxt
= sb_skip_white (idx
+ 1, in
);
1228 if (nxt
>= in
->len
|| in
->ptr
[nxt
] == comment_char
)
1234 sb_reset (&f
.actual
);
1235 sb_add_char (&f
.actual
, in
->ptr
[idx
]);
1238 err
= macro_expand_body (&sub
, out
, &f
, h
, comment_char
, 0);
1242 idx
= sb_skip_comma (idx
, in
);
1244 idx
= sb_skip_white (idx
, in
);