1 /* macro.c - macro support for gas and gasp
2 Copyright 1994, 1995, 1996, 1997, 1998, 1999, 2000
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 */
58 #include "libiberty.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 ((unsigned char) 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 ((unsigned char) in
->ptr
[idx
])
245 || in
->ptr
[idx
] == '_'
246 || in
->ptr
[idx
] == '$'))
248 sb_add_char (name
, in
->ptr
[idx
++]);
250 && (isalnum ((unsigned char) 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 if (isupper ((unsigned char) name
.ptr
[idx
]))
571 name
.ptr
[idx
] = tolower (name
.ptr
[idx
]);
572 namestr
= sb_terminate (&name
);
573 hash_jam (macro_hash
, namestr
, (PTR
) macro
);
583 /* Scan a token, and then skip KIND. */
586 get_apost_token (idx
, in
, name
, kind
)
592 idx
= get_token (idx
, in
, name
);
594 && in
->ptr
[idx
] == kind
595 && (! macro_mri
|| macro_strip_at
)
596 && (! macro_strip_at
|| kind
== '@'))
601 /* Substitute the actual value for a formal parameter. */
604 sub_actual (start
, in
, t
, formal_hash
, kind
, out
, copyifnotthere
)
608 struct hash_control
*formal_hash
;
616 src
= get_apost_token (start
, in
, t
, kind
);
617 /* See if it's in the macro's hash table, unless this is
618 macro_strip_at and kind is '@' and the token did not end in '@'. */
621 && (src
== start
|| in
->ptr
[src
- 1] != '@'))
624 ptr
= (formal_entry
*) hash_find (formal_hash
, sb_terminate (t
));
629 sb_add_sb (out
, &ptr
->actual
);
633 sb_add_sb (out
, &ptr
->def
);
636 else if (kind
== '&')
638 /* Doing this permits people to use & in macro bodies. */
639 sb_add_char (out
, '&');
641 else if (copyifnotthere
)
647 sb_add_char (out
, '\\');
653 /* Expand the body of a macro. */
656 macro_expand_body (in
, out
, formals
, formal_hash
, comment_char
, locals
)
659 formal_entry
*formals
;
660 struct hash_control
*formal_hash
;
667 formal_entry
*loclist
= NULL
;
671 while (src
< in
->len
)
673 if (in
->ptr
[src
] == '&')
678 if (src
+ 1 < in
->len
&& in
->ptr
[src
+ 1] == '&')
679 src
= sub_actual (src
+ 2, in
, &t
, formal_hash
, '\'', out
, 1);
681 sb_add_char (out
, in
->ptr
[src
++]);
685 /* FIXME: Why do we do this? */
686 src
= sub_actual (src
+ 1, in
, &t
, formal_hash
, '&', out
, 0);
689 else if (in
->ptr
[src
] == '\\')
692 if (in
->ptr
[src
] == comment_char
&& comment_char
!= '\0')
694 /* This is a comment, just drop the rest of the line. */
696 && in
->ptr
[src
] != '\n')
699 else if (in
->ptr
[src
] == '(')
701 /* Sub in till the next ')' literally. */
703 while (src
< in
->len
&& in
->ptr
[src
] != ')')
705 sb_add_char (out
, in
->ptr
[src
++]);
707 if (in
->ptr
[src
] == ')')
710 return _("missplaced )");
712 else if (in
->ptr
[src
] == '@')
714 /* Sub in the macro invocation number. */
718 sprintf (buffer
, "%d", macro_number
);
719 sb_add_string (out
, buffer
);
721 else if (in
->ptr
[src
] == '&')
723 /* This is a preprocessor variable name, we don't do them
725 sb_add_char (out
, '\\');
726 sb_add_char (out
, '&');
730 && isalnum ((unsigned char) in
->ptr
[src
]))
735 if (isdigit ((unsigned char) in
->ptr
[src
]))
736 ind
= in
->ptr
[src
] - '0';
737 else if (isupper ((unsigned char) in
->ptr
[src
]))
738 ind
= in
->ptr
[src
] - 'A' + 10;
740 ind
= in
->ptr
[src
] - 'a' + 10;
742 for (f
= formals
; f
!= NULL
; f
= f
->next
)
744 if (f
->index
== ind
- 1)
746 if (f
->actual
.len
!= 0)
747 sb_add_sb (out
, &f
->actual
);
749 sb_add_sb (out
, &f
->def
);
757 src
= sub_actual (src
, in
, &t
, formal_hash
, '\'', out
, 0);
760 else if ((macro_alternate
|| macro_mri
)
761 && (isalpha ((unsigned char) in
->ptr
[src
])
762 || in
->ptr
[src
] == '_'
763 || in
->ptr
[src
] == '$')
766 || (src
> 0 && in
->ptr
[src
- 1] == '@')))
769 || src
+ 5 >= in
->len
770 || strncasecmp (in
->ptr
+ src
, "LOCAL", 5) != 0
771 || ! ISWHITE (in
->ptr
[src
+ 5]))
774 src
= sub_actual (src
, in
, &t
, formal_hash
,
775 (macro_strip_at
&& inquote
) ? '@' : '\'',
782 src
= sb_skip_white (src
+ 5, in
);
783 while (in
->ptr
[src
] != '\n' && in
->ptr
[src
] != comment_char
)
789 f
= (formal_entry
*) xmalloc (sizeof (formal_entry
));
793 f
->index
= LOCAL_INDEX
;
797 src
= get_token (src
, in
, &f
->name
);
799 sprintf (buf
, "LL%04x", loccnt
);
800 sb_add_string (&f
->actual
, buf
);
802 err
= hash_jam (formal_hash
, sb_terminate (&f
->name
), f
);
806 src
= sb_skip_comma (src
, in
);
810 else if (comment_char
!= '\0'
811 && in
->ptr
[src
] == comment_char
813 && in
->ptr
[src
+ 1] == comment_char
816 /* Two comment chars in a row cause the rest of the line to
818 while (src
< in
->len
&& in
->ptr
[src
] != '\n')
821 else if (in
->ptr
[src
] == '"'
822 || (macro_mri
&& in
->ptr
[src
] == '\''))
825 sb_add_char (out
, in
->ptr
[src
++]);
827 else if (in
->ptr
[src
] == '@' && macro_strip_at
)
831 && in
->ptr
[src
] == '@')
833 sb_add_char (out
, '@');
838 && in
->ptr
[src
] == '='
840 && in
->ptr
[src
+ 1] == '=')
845 src
= get_token (src
+ 2, in
, &t
);
846 ptr
= (formal_entry
*) hash_find (formal_hash
, sb_terminate (&t
));
849 /* FIXME: We should really return a warning string here,
850 but we can't, because the == might be in the MRI
851 comment field, and, since the nature of the MRI
852 comment field depends upon the exact instruction
853 being used, we don't have enough information here to
854 figure out whether it is or not. Instead, we leave
855 the == in place, which should cause a syntax error if
856 it is not in a comment. */
857 sb_add_char (out
, '=');
858 sb_add_char (out
, '=');
865 sb_add_string (out
, "-1");
869 sb_add_char (out
, '0');
875 sb_add_char (out
, in
->ptr
[src
++]);
881 while (loclist
!= NULL
)
886 /* Setting the value to NULL effectively deletes the entry. We
887 avoid calling hash_delete because it doesn't reclaim memory. */
888 hash_jam (formal_hash
, sb_terminate (&loclist
->name
), NULL
);
889 sb_kill (&loclist
->name
);
890 sb_kill (&loclist
->def
);
891 sb_kill (&loclist
->actual
);
899 /* Assign values to the formal parameters of a macro, and expand the
903 macro_expand (idx
, in
, m
, out
, comment_char
)
913 int is_positional
= 0;
920 /* Reset any old value the actuals may have. */
921 for (f
= m
->formals
; f
; f
= f
->next
)
922 sb_reset (&f
->actual
);
924 while (f
!= NULL
&& f
->index
< 0)
929 /* The macro may be called with an optional qualifier, which may
930 be referred to in the macro body as \0. */
931 if (idx
< in
->len
&& in
->ptr
[idx
] == '.')
933 /* The Microtec assembler ignores this if followed by a white space.
934 (Macro invocation with empty extension) */
937 && in
->ptr
[idx
] != ' '
938 && in
->ptr
[idx
] != '\t')
942 n
= (formal_entry
*) xmalloc (sizeof (formal_entry
));
946 n
->index
= QUAL_INDEX
;
948 n
->next
= m
->formals
;
951 idx
= get_any_string (idx
, in
, &n
->actual
, 1, 0);
956 /* Peel off the actuals and store them away in the hash tables' actuals. */
957 idx
= sb_skip_white (idx
, in
);
958 while (idx
< in
->len
&& in
->ptr
[idx
] != comment_char
)
962 /* Look and see if it's a positional or keyword arg. */
964 while (scan
< in
->len
965 && !ISSEP (in
->ptr
[scan
])
966 && !(macro_mri
&& in
->ptr
[scan
] == '\'')
967 && (!macro_alternate
&& in
->ptr
[scan
] != '='))
969 if (scan
< in
->len
&& !macro_alternate
&& in
->ptr
[scan
] == '=')
973 /* It's OK to go from positional to keyword. */
975 /* This is a keyword arg, fetch the formal name and
976 then the actual stuff. */
978 idx
= get_token (idx
, in
, &t
);
979 if (in
->ptr
[idx
] != '=')
980 return _("confusion in formal parameters");
982 /* Lookup the formal in the macro's list. */
983 ptr
= (formal_entry
*) hash_find (m
->formal_hash
, sb_terminate (&t
));
985 return _("macro formal argument does not exist");
988 /* Insert this value into the right place. */
989 sb_reset (&ptr
->actual
);
990 idx
= get_any_string (idx
+ 1, in
, &ptr
->actual
, 0, 0);
991 if (ptr
->actual
.len
> 0)
997 /* This is a positional arg. */
1000 return _("can't mix positional and keyword arguments");
1008 return _("too many positional arguments");
1010 f
= (formal_entry
*) xmalloc (sizeof (formal_entry
));
1013 sb_new (&f
->actual
);
1017 for (pf
= &m
->formals
; *pf
!= NULL
; pf
= &(*pf
)->next
)
1018 if ((*pf
)->index
>= c
)
1019 c
= (*pf
)->index
+ 1;
1026 sb_reset (&f
->actual
);
1027 idx
= get_any_string (idx
, in
, &f
->actual
, 1, 0);
1028 if (f
->actual
.len
> 0)
1034 while (f
!= NULL
&& f
->index
< 0);
1038 idx
= sb_skip_comma (idx
, in
);
1041 if (in
->ptr
[idx
] == ',')
1043 if (ISWHITE (in
->ptr
[idx
]))
1053 sb_add_string (&t
, macro_strip_at
? "$NARG" : "NARG");
1054 ptr
= (formal_entry
*) hash_find (m
->formal_hash
, sb_terminate (&t
));
1055 sb_reset (&ptr
->actual
);
1056 sprintf (buffer
, "%d", narg
);
1057 sb_add_string (&ptr
->actual
, buffer
);
1060 err
= macro_expand_body (&m
->sub
, out
, m
->formals
, m
->formal_hash
,
1065 /* Discard any unnamed formal arguments. */
1073 if ((*pf
)->name
.len
!= 0)
1077 sb_kill (&(*pf
)->name
);
1078 sb_kill (&(*pf
)->def
);
1079 sb_kill (&(*pf
)->actual
);
1093 /* Check for a macro. If one is found, put the expansion into
1094 *EXPAND. COMMENT_CHAR is the comment character--this is used by
1095 gasp. Return 1 if a macro is found, 0 otherwise. */
1098 check_macro (line
, expand
, comment_char
, error
, info
)
1110 if (! isalpha ((unsigned char) *line
)
1113 && (! macro_mri
|| *line
!= '.'))
1117 while (isalnum ((unsigned char) *s
)
1122 copy
= (char *) alloca (s
- line
+ 1);
1123 memcpy (copy
, line
, s
- line
);
1124 copy
[s
- line
] = '\0';
1125 for (cs
= copy
; *cs
!= '\0'; cs
++)
1126 if (isupper ((unsigned char) *cs
))
1127 *cs
= tolower (*cs
);
1129 macro
= (macro_entry
*) hash_find (macro_hash
, copy
);
1134 /* Wrap the line up in an sb. */
1136 while (*s
!= '\0' && *s
!= '\n' && *s
!= '\r')
1137 sb_add_char (&line_sb
, *s
++);
1140 *error
= macro_expand (0, &line_sb
, macro
, expand
, comment_char
);
1144 /* Export the macro information if requested. */
1151 /* Delete a macro. */
1157 hash_delete (macro_hash
, name
);
1160 /* Handle the MRI IRP and IRPC pseudo-ops. These are handled as a
1161 combined macro definition and execution. This returns NULL on
1162 success, or an error message otherwise. */
1165 expand_irp (irpc
, idx
, in
, out
, get_line
, comment_char
)
1170 int (*get_line
) PARAMS ((sb
*));
1176 struct hash_control
*h
;
1184 idx
= sb_skip_white (idx
, in
);
1187 if (! buffer_and_nest (mn
, "ENDR", &sub
, get_line
))
1188 return _("unexpected end of file in irp or irpc");
1194 idx
= get_token (idx
, in
, &f
.name
);
1195 if (f
.name
.len
== 0)
1196 return _("missing model parameter");
1199 err
= hash_jam (h
, sb_terminate (&f
.name
), &f
);
1208 idx
= sb_skip_comma (idx
, in
);
1209 if (idx
>= in
->len
|| in
->ptr
[idx
] == comment_char
)
1211 /* Expand once with a null string. */
1212 err
= macro_expand_body (&sub
, out
, &f
, h
, comment_char
, 0);
1218 if (irpc
&& in
->ptr
[idx
] == '"')
1220 while (idx
< in
->len
&& in
->ptr
[idx
] != comment_char
)
1223 idx
= get_any_string (idx
, in
, &f
.actual
, 1, 0);
1226 if (in
->ptr
[idx
] == '"')
1230 nxt
= sb_skip_white (idx
+ 1, in
);
1231 if (nxt
>= in
->len
|| in
->ptr
[nxt
] == comment_char
)
1237 sb_reset (&f
.actual
);
1238 sb_add_char (&f
.actual
, in
->ptr
[idx
]);
1241 err
= macro_expand_body (&sub
, out
, &f
, h
, comment_char
, 0);
1245 idx
= sb_skip_comma (idx
, in
);
1247 idx
= sb_skip_white (idx
, in
);