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)
250 if (strncasecmp (ptr
->ptr
+ i
, to
, to_len
) == 0)
255 /* Reset the string to not include the ending rune */
256 ptr
->len
= line_start
;
262 /* Add a CR to the end and keep running */
263 sb_add_char (ptr
, '\n');
264 line_start
= ptr
->len
;
265 more
= get_line (ptr
);
268 /* Return 1 on success, 0 on unexpected EOF. */
272 /* Pick up a token. */
275 get_token (idx
, in
, name
)
281 && (isalpha ((unsigned char) in
->ptr
[idx
])
282 || in
->ptr
[idx
] == '_'
283 || in
->ptr
[idx
] == '$'))
285 sb_add_char (name
, in
->ptr
[idx
++]);
287 && (isalnum ((unsigned char) in
->ptr
[idx
])
288 || in
->ptr
[idx
] == '_'
289 || in
->ptr
[idx
] == '$'))
291 sb_add_char (name
, in
->ptr
[idx
++]);
294 /* Ignore trailing & */
295 if (macro_alternate
&& idx
< in
->len
&& in
->ptr
[idx
] == '&')
300 /* Pick up a string. */
303 getstring (idx
, in
, acc
)
308 idx
= sb_skip_white (idx
, in
);
311 && (in
->ptr
[idx
] == '"'
312 || (in
->ptr
[idx
] == '<' && (macro_alternate
|| macro_mri
))
313 || (in
->ptr
[idx
] == '\'' && macro_alternate
)))
315 if (in
->ptr
[idx
] == '<')
319 while ((in
->ptr
[idx
] != '>' || nest
)
322 if (in
->ptr
[idx
] == '!')
325 sb_add_char (acc
, in
->ptr
[idx
++]);
329 if (in
->ptr
[idx
] == '>')
331 if (in
->ptr
[idx
] == '<')
333 sb_add_char (acc
, in
->ptr
[idx
++]);
338 else if (in
->ptr
[idx
] == '"' || in
->ptr
[idx
] == '\'')
340 char tchar
= in
->ptr
[idx
];
342 while (idx
< in
->len
)
344 if (macro_alternate
&& in
->ptr
[idx
] == '!')
347 sb_add_char (acc
, in
->ptr
[idx
++]);
351 if (in
->ptr
[idx
] == tchar
)
354 if (idx
>= in
->len
|| in
->ptr
[idx
] != tchar
)
357 sb_add_char (acc
, in
->ptr
[idx
]);
367 /* Fetch string from the input stream,
369 'Bxyx<whitespace> -> return 'Bxyza
370 %<char> -> return string of decimal value of x
371 "<string>" -> return string
372 xyx<whitespace> -> return xyz
376 get_any_string (idx
, in
, out
, expand
, pretend_quoted
)
384 idx
= sb_skip_white (idx
, in
);
388 if (in
->len
> 2 && in
->ptr
[idx
+1] == '\'' && ISBASE (in
->ptr
[idx
]))
390 while (!ISSEP (in
->ptr
[idx
]))
391 sb_add_char (out
, in
->ptr
[idx
++]);
393 else if (in
->ptr
[idx
] == '%'
399 /* Turns the next expression into a string */
400 idx
= (*macro_expr
) (_("% operator needs absolute expression"),
404 sprintf(buf
, "%d", val
);
405 sb_add_string (out
, buf
);
407 else if (in
->ptr
[idx
] == '"'
408 || (in
->ptr
[idx
] == '<' && (macro_alternate
|| macro_mri
))
409 || (macro_alternate
&& in
->ptr
[idx
] == '\''))
415 /* Keep the quotes */
416 sb_add_char (out
, '\"');
418 idx
= getstring (idx
, in
, out
);
419 sb_add_char (out
, '\"');
423 idx
= getstring (idx
, in
, out
);
429 && (in
->ptr
[idx
] == '"'
430 || in
->ptr
[idx
] == '\''
432 || (in
->ptr
[idx
] != ' '
433 && in
->ptr
[idx
] != '\t'
434 && in
->ptr
[idx
] != ','
435 && (in
->ptr
[idx
] != '<'
436 || (! macro_alternate
&& ! macro_mri
)))))
438 if (in
->ptr
[idx
] == '"'
439 || in
->ptr
[idx
] == '\'')
441 char tchar
= in
->ptr
[idx
];
442 sb_add_char (out
, in
->ptr
[idx
++]);
444 && in
->ptr
[idx
] != tchar
)
445 sb_add_char (out
, in
->ptr
[idx
++]);
449 sb_add_char (out
, in
->ptr
[idx
++]);
457 /* Pick up the formal parameters of a macro definition. */
460 do_formals (macro
, idx
, in
)
465 formal_entry
**p
= ¯o
->formals
;
467 macro
->formal_count
= 0;
468 macro
->formal_hash
= hash_new ();
469 while (idx
< in
->len
)
471 formal_entry
*formal
;
473 formal
= (formal_entry
*) xmalloc (sizeof (formal_entry
));
475 sb_new (&formal
->name
);
476 sb_new (&formal
->def
);
477 sb_new (&formal
->actual
);
479 idx
= sb_skip_white (idx
, in
);
480 idx
= get_token (idx
, in
, &formal
->name
);
481 if (formal
->name
.len
== 0)
483 idx
= sb_skip_white (idx
, in
);
484 if (formal
->name
.len
)
486 /* This is a formal */
487 if (idx
< in
->len
&& in
->ptr
[idx
] == '=')
490 idx
= get_any_string (idx
+ 1, in
, &formal
->def
, 1, 0);
494 /* Add to macro's hash table */
495 hash_jam (macro
->formal_hash
, sb_terminate (&formal
->name
), formal
);
497 formal
->index
= macro
->formal_count
;
498 idx
= sb_skip_comma (idx
, in
);
499 macro
->formal_count
++;
507 formal_entry
*formal
;
510 /* Add a special NARG formal, which macro_expand will set to the
511 number of arguments. */
512 formal
= (formal_entry
*) xmalloc (sizeof (formal_entry
));
514 sb_new (&formal
->name
);
515 sb_new (&formal
->def
);
516 sb_new (&formal
->actual
);
518 /* The same MRI assemblers which treat '@' characters also use
519 the name $NARG. At least until we find an exception. */
525 sb_add_string (&formal
->name
, name
);
527 /* Add to macro's hash table */
528 hash_jam (macro
->formal_hash
, name
, formal
);
530 formal
->index
= NARG_INDEX
;
538 /* Define a new macro. Returns NULL on success, otherwise returns an
539 error message. If NAMEP is not NULL, *NAMEP is set to the name of
540 the macro which was defined. */
543 define_macro (idx
, in
, label
, get_line
, namep
)
547 int (*get_line
) PARAMS ((sb
*));
554 macro
= (macro_entry
*) xmalloc (sizeof (macro_entry
));
555 sb_new (¯o
->sub
);
558 macro
->formal_count
= 0;
561 idx
= sb_skip_white (idx
, in
);
562 if (! buffer_and_nest ("MACRO", "ENDM", ¯o
->sub
, get_line
))
563 return _("unexpected end of file in macro definition");
564 if (label
!= NULL
&& label
->len
!= 0)
566 sb_add_sb (&name
, label
);
567 if (idx
< in
->len
&& in
->ptr
[idx
] == '(')
569 /* It's the label: MACRO (formals,...) sort */
570 idx
= do_formals (macro
, idx
+ 1, in
);
571 if (in
->ptr
[idx
] != ')')
572 return _("missing ) after formals");
576 /* It's the label: MACRO formals,... sort */
577 idx
= do_formals (macro
, idx
, in
);
582 idx
= get_token (idx
, in
, &name
);
583 idx
= sb_skip_comma (idx
, in
);
584 idx
= do_formals (macro
, idx
, in
);
587 /* and stick it in the macro hash table */
588 for (idx
= 0; idx
< name
.len
; idx
++)
589 if (isupper ((unsigned char) name
.ptr
[idx
]))
590 name
.ptr
[idx
] = tolower (name
.ptr
[idx
]);
591 namestr
= sb_terminate (&name
);
592 hash_jam (macro_hash
, namestr
, (PTR
) macro
);
602 /* Scan a token, and then skip KIND. */
605 get_apost_token (idx
, in
, name
, kind
)
611 idx
= get_token (idx
, in
, name
);
613 && in
->ptr
[idx
] == kind
614 && (! macro_mri
|| macro_strip_at
)
615 && (! macro_strip_at
|| kind
== '@'))
620 /* Substitute the actual value for a formal parameter. */
623 sub_actual (start
, in
, t
, formal_hash
, kind
, out
, copyifnotthere
)
627 struct hash_control
*formal_hash
;
635 src
= get_apost_token (start
, in
, t
, kind
);
636 /* See if it's in the macro's hash table, unless this is
637 macro_strip_at and kind is '@' and the token did not end in '@'. */
640 && (src
== start
|| in
->ptr
[src
- 1] != '@'))
643 ptr
= (formal_entry
*) hash_find (formal_hash
, sb_terminate (t
));
648 sb_add_sb (out
, &ptr
->actual
);
652 sb_add_sb (out
, &ptr
->def
);
655 else if (kind
== '&')
657 /* Doing this permits people to use & in macro bodies. */
658 sb_add_char (out
, '&');
660 else if (copyifnotthere
)
666 sb_add_char (out
, '\\');
672 /* Expand the body of a macro. */
675 macro_expand_body (in
, out
, formals
, formal_hash
, comment_char
, locals
)
678 formal_entry
*formals
;
679 struct hash_control
*formal_hash
;
686 formal_entry
*loclist
= NULL
;
690 while (src
< in
->len
)
692 if (in
->ptr
[src
] == '&')
697 if (src
+ 1 < in
->len
&& in
->ptr
[src
+ 1] == '&')
698 src
= sub_actual (src
+ 2, in
, &t
, formal_hash
, '\'', out
, 1);
700 sb_add_char (out
, in
->ptr
[src
++]);
704 /* FIXME: Why do we do this? */
705 src
= sub_actual (src
+ 1, in
, &t
, formal_hash
, '&', out
, 0);
708 else if (in
->ptr
[src
] == '\\')
711 if (in
->ptr
[src
] == comment_char
&& comment_char
!= '\0')
713 /* This is a comment, just drop the rest of the line */
715 && in
->ptr
[src
] != '\n')
718 else if (in
->ptr
[src
] == '(')
720 /* Sub in till the next ')' literally */
722 while (src
< in
->len
&& in
->ptr
[src
] != ')')
724 sb_add_char (out
, in
->ptr
[src
++]);
726 if (in
->ptr
[src
] == ')')
729 return _("missplaced )");
731 else if (in
->ptr
[src
] == '@')
733 /* Sub in the macro invocation number */
737 sprintf (buffer
, "%05d", macro_number
);
738 sb_add_string (out
, buffer
);
740 else if (in
->ptr
[src
] == '&')
742 /* This is a preprocessor variable name, we don't do them
744 sb_add_char (out
, '\\');
745 sb_add_char (out
, '&');
749 && isalnum ((unsigned char) in
->ptr
[src
]))
754 if (isdigit ((unsigned char) in
->ptr
[src
]))
755 ind
= in
->ptr
[src
] - '0';
756 else if (isupper ((unsigned char) in
->ptr
[src
]))
757 ind
= in
->ptr
[src
] - 'A' + 10;
759 ind
= in
->ptr
[src
] - 'a' + 10;
761 for (f
= formals
; f
!= NULL
; f
= f
->next
)
763 if (f
->index
== ind
- 1)
765 if (f
->actual
.len
!= 0)
766 sb_add_sb (out
, &f
->actual
);
768 sb_add_sb (out
, &f
->def
);
776 src
= sub_actual (src
, in
, &t
, formal_hash
, '\'', out
, 0);
779 else if ((macro_alternate
|| macro_mri
)
780 && (isalpha ((unsigned char) in
->ptr
[src
])
781 || in
->ptr
[src
] == '_'
782 || in
->ptr
[src
] == '$')
785 || (src
> 0 && in
->ptr
[src
- 1] == '@')))
788 || src
+ 5 >= in
->len
789 || strncasecmp (in
->ptr
+ src
, "LOCAL", 5) != 0
790 || ! ISWHITE (in
->ptr
[src
+ 5]))
793 src
= sub_actual (src
, in
, &t
, formal_hash
,
794 (macro_strip_at
&& inquote
) ? '@' : '\'',
801 src
= sb_skip_white (src
+ 5, in
);
802 while (in
->ptr
[src
] != '\n' && in
->ptr
[src
] != comment_char
)
808 f
= (formal_entry
*) xmalloc (sizeof (formal_entry
));
812 f
->index
= LOCAL_INDEX
;
816 src
= get_token (src
, in
, &f
->name
);
818 sprintf (buf
, "LL%04x", loccnt
);
819 sb_add_string (&f
->actual
, buf
);
821 err
= hash_jam (formal_hash
, sb_terminate (&f
->name
), f
);
825 src
= sb_skip_comma (src
, in
);
829 else if (comment_char
!= '\0'
830 && in
->ptr
[src
] == comment_char
832 && in
->ptr
[src
+ 1] == comment_char
835 /* Two comment chars in a row cause the rest of the line to
837 while (src
< in
->len
&& in
->ptr
[src
] != '\n')
840 else if (in
->ptr
[src
] == '"'
841 || (macro_mri
&& in
->ptr
[src
] == '\''))
844 sb_add_char (out
, in
->ptr
[src
++]);
846 else if (in
->ptr
[src
] == '@' && macro_strip_at
)
850 && in
->ptr
[src
] == '@')
852 sb_add_char (out
, '@');
857 && in
->ptr
[src
] == '='
859 && in
->ptr
[src
+ 1] == '=')
864 src
= get_token (src
+ 2, in
, &t
);
865 ptr
= (formal_entry
*) hash_find (formal_hash
, sb_terminate (&t
));
868 /* FIXME: We should really return a warning string here,
869 but we can't, because the == might be in the MRI
870 comment field, and, since the nature of the MRI
871 comment field depends upon the exact instruction
872 being used, we don't have enough information here to
873 figure out whether it is or not. Instead, we leave
874 the == in place, which should cause a syntax error if
875 it is not in a comment. */
876 sb_add_char (out
, '=');
877 sb_add_char (out
, '=');
884 sb_add_string (out
, "-1");
888 sb_add_char (out
, '0');
894 sb_add_char (out
, in
->ptr
[src
++]);
900 while (loclist
!= NULL
)
905 /* Setting the value to NULL effectively deletes the entry. We
906 avoid calling hash_delete because it doesn't reclaim memory. */
907 hash_jam (formal_hash
, sb_terminate (&loclist
->name
), NULL
);
908 sb_kill (&loclist
->name
);
909 sb_kill (&loclist
->def
);
910 sb_kill (&loclist
->actual
);
918 /* Assign values to the formal parameters of a macro, and expand the
922 macro_expand (idx
, in
, m
, out
, comment_char
)
932 int is_positional
= 0;
939 /* Reset any old value the actuals may have */
940 for (f
= m
->formals
; f
; f
= f
->next
)
941 sb_reset (&f
->actual
);
943 while (f
!= NULL
&& f
->index
< 0)
948 /* The macro may be called with an optional qualifier, which may
949 be referred to in the macro body as \0. */
950 if (idx
< in
->len
&& in
->ptr
[idx
] == '.')
954 n
= (formal_entry
*) xmalloc (sizeof (formal_entry
));
958 n
->index
= QUAL_INDEX
;
960 n
->next
= m
->formals
;
963 idx
= get_any_string (idx
+ 1, in
, &n
->actual
, 1, 0);
967 /* Peel off the actuals and store them away in the hash tables' actuals */
968 idx
= sb_skip_white (idx
, in
);
969 while (idx
< in
->len
&& in
->ptr
[idx
] != comment_char
)
973 /* Look and see if it's a positional or keyword arg */
975 while (scan
< in
->len
976 && !ISSEP (in
->ptr
[scan
])
977 && !(macro_mri
&& in
->ptr
[scan
] == '\'')
978 && (!macro_alternate
&& in
->ptr
[scan
] != '='))
980 if (scan
< in
->len
&& !macro_alternate
&& in
->ptr
[scan
] == '=')
984 /* It's OK to go from positional to keyword. */
986 /* This is a keyword arg, fetch the formal name and
987 then the actual stuff */
989 idx
= get_token (idx
, in
, &t
);
990 if (in
->ptr
[idx
] != '=')
991 return _("confusion in formal parameters");
993 /* Lookup the formal in the macro's list */
994 ptr
= (formal_entry
*) hash_find (m
->formal_hash
, sb_terminate (&t
));
996 return _("macro formal argument does not exist");
999 /* Insert this value into the right place */
1000 sb_reset (&ptr
->actual
);
1001 idx
= get_any_string (idx
+ 1, in
, &ptr
->actual
, 0, 0);
1002 if (ptr
->actual
.len
> 0)
1008 /* This is a positional arg */
1011 return _("can't mix positional and keyword arguments");
1019 return _("too many positional arguments");
1021 f
= (formal_entry
*) xmalloc (sizeof (formal_entry
));
1024 sb_new (&f
->actual
);
1028 for (pf
= &m
->formals
; *pf
!= NULL
; pf
= &(*pf
)->next
)
1029 if ((*pf
)->index
>= c
)
1030 c
= (*pf
)->index
+ 1;
1037 sb_reset (&f
->actual
);
1038 idx
= get_any_string (idx
, in
, &f
->actual
, 1, 0);
1039 if (f
->actual
.len
> 0)
1045 while (f
!= NULL
&& f
->index
< 0);
1049 idx
= sb_skip_comma (idx
, in
);
1052 if (in
->ptr
[idx
] == ',')
1054 if (ISWHITE (in
->ptr
[idx
]))
1064 sb_add_string (&t
, macro_strip_at
? "$NARG" : "NARG");
1065 ptr
= (formal_entry
*) hash_find (m
->formal_hash
, sb_terminate (&t
));
1066 sb_reset (&ptr
->actual
);
1067 sprintf (buffer
, "%d", narg
);
1068 sb_add_string (&ptr
->actual
, buffer
);
1071 err
= macro_expand_body (&m
->sub
, out
, m
->formals
, m
->formal_hash
,
1076 /* Discard any unnamed formal arguments. */
1084 if ((*pf
)->name
.len
!= 0)
1088 sb_kill (&(*pf
)->name
);
1089 sb_kill (&(*pf
)->def
);
1090 sb_kill (&(*pf
)->actual
);
1104 /* Check for a macro. If one is found, put the expansion into
1105 *EXPAND. COMMENT_CHAR is the comment character--this is used by
1106 gasp. Return 1 if a macro is found, 0 otherwise. */
1109 check_macro (line
, expand
, comment_char
, error
)
1120 if (! isalpha ((unsigned char) *line
)
1123 && (! macro_mri
|| *line
!= '.'))
1127 while (isalnum ((unsigned char) *s
)
1132 copy
= (char *) alloca (s
- line
+ 1);
1133 memcpy (copy
, line
, s
- line
);
1134 copy
[s
- line
] = '\0';
1135 for (cs
= copy
; *cs
!= '\0'; cs
++)
1136 if (isupper ((unsigned char) *cs
))
1137 *cs
= tolower (*cs
);
1139 macro
= (macro_entry
*) hash_find (macro_hash
, copy
);
1144 /* Wrap the line up in an sb. */
1146 while (*s
!= '\0' && *s
!= '\n' && *s
!= '\r')
1147 sb_add_char (&line_sb
, *s
++);
1150 *error
= macro_expand (0, &line_sb
, macro
, expand
, comment_char
);
1157 /* Delete a macro. */
1163 hash_delete (macro_hash
, name
);
1166 /* Handle the MRI IRP and IRPC pseudo-ops. These are handled as a
1167 combined macro definition and execution. This returns NULL on
1168 success, or an error message otherwise. */
1171 expand_irp (irpc
, idx
, in
, out
, get_line
, comment_char
)
1176 int (*get_line
) PARAMS ((sb
*));
1182 struct hash_control
*h
;
1190 idx
= sb_skip_white (idx
, in
);
1193 if (! buffer_and_nest (mn
, "ENDR", &sub
, get_line
))
1194 return _("unexpected end of file in irp or irpc");
1200 idx
= get_token (idx
, in
, &f
.name
);
1201 if (f
.name
.len
== 0)
1202 return _("missing model parameter");
1205 err
= hash_jam (h
, sb_terminate (&f
.name
), &f
);
1214 idx
= sb_skip_comma (idx
, in
);
1215 if (idx
>= in
->len
|| in
->ptr
[idx
] == comment_char
)
1217 /* Expand once with a null string. */
1218 err
= macro_expand_body (&sub
, out
, &f
, h
, comment_char
, 0);
1224 if (irpc
&& in
->ptr
[idx
] == '"')
1226 while (idx
< in
->len
&& in
->ptr
[idx
] != comment_char
)
1229 idx
= get_any_string (idx
, in
, &f
.actual
, 1, 0);
1232 if (in
->ptr
[idx
] == '"')
1236 nxt
= sb_skip_white (idx
+ 1, in
);
1237 if (nxt
>= in
->len
|| in
->ptr
[nxt
] == comment_char
)
1243 sb_reset (&f
.actual
);
1244 sb_add_char (&f
.actual
, in
->ptr
[idx
]);
1247 err
= macro_expand_body (&sub
, out
, &f
, h
, comment_char
, 0);
1251 idx
= sb_skip_comma (idx
, in
);
1253 idx
= sb_skip_white (idx
, in
);