1 /* macro.c - macro support for gas and gasp
2 Copyright (C) 1994, 95, 96, 97, 1998 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 hash_delete (formal_hash
, sb_terminate (&loclist
->name
));
906 sb_kill (&loclist
->name
);
907 sb_kill (&loclist
->def
);
908 sb_kill (&loclist
->actual
);
916 /* Assign values to the formal parameters of a macro, and expand the
920 macro_expand (idx
, in
, m
, out
, comment_char
)
930 int is_positional
= 0;
937 /* Reset any old value the actuals may have */
938 for (f
= m
->formals
; f
; f
= f
->next
)
939 sb_reset (&f
->actual
);
941 while (f
!= NULL
&& f
->index
< 0)
946 /* The macro may be called with an optional qualifier, which may
947 be referred to in the macro body as \0. */
948 if (idx
< in
->len
&& in
->ptr
[idx
] == '.')
952 n
= (formal_entry
*) xmalloc (sizeof (formal_entry
));
956 n
->index
= QUAL_INDEX
;
958 n
->next
= m
->formals
;
961 idx
= get_any_string (idx
+ 1, in
, &n
->actual
, 1, 0);
965 /* Peel off the actuals and store them away in the hash tables' actuals */
966 idx
= sb_skip_white (idx
, in
);
967 while (idx
< in
->len
&& in
->ptr
[idx
] != comment_char
)
971 /* Look and see if it's a positional or keyword arg */
973 while (scan
< in
->len
974 && !ISSEP (in
->ptr
[scan
])
975 && !(macro_mri
&& in
->ptr
[scan
] == '\'')
976 && (!macro_alternate
&& in
->ptr
[scan
] != '='))
978 if (scan
< in
->len
&& !macro_alternate
&& in
->ptr
[scan
] == '=')
982 /* It's OK to go from positional to keyword. */
984 /* This is a keyword arg, fetch the formal name and
985 then the actual stuff */
987 idx
= get_token (idx
, in
, &t
);
988 if (in
->ptr
[idx
] != '=')
989 return _("confusion in formal parameters");
991 /* Lookup the formal in the macro's list */
992 ptr
= (formal_entry
*) hash_find (m
->formal_hash
, sb_terminate (&t
));
994 return _("macro formal argument does not exist");
997 /* Insert this value into the right place */
998 sb_reset (&ptr
->actual
);
999 idx
= get_any_string (idx
+ 1, in
, &ptr
->actual
, 0, 0);
1000 if (ptr
->actual
.len
> 0)
1006 /* This is a positional arg */
1009 return _("can't mix positional and keyword arguments");
1017 return _("too many positional arguments");
1019 f
= (formal_entry
*) xmalloc (sizeof (formal_entry
));
1022 sb_new (&f
->actual
);
1026 for (pf
= &m
->formals
; *pf
!= NULL
; pf
= &(*pf
)->next
)
1027 if ((*pf
)->index
>= c
)
1028 c
= (*pf
)->index
+ 1;
1035 sb_reset (&f
->actual
);
1036 idx
= get_any_string (idx
, in
, &f
->actual
, 1, 0);
1037 if (f
->actual
.len
> 0)
1043 while (f
!= NULL
&& f
->index
< 0);
1047 idx
= sb_skip_comma (idx
, in
);
1050 if (in
->ptr
[idx
] == ',')
1052 if (ISWHITE (in
->ptr
[idx
]))
1062 sb_add_string (&t
, macro_strip_at
? "$NARG" : "NARG");
1063 ptr
= (formal_entry
*) hash_find (m
->formal_hash
, sb_terminate (&t
));
1064 sb_reset (&ptr
->actual
);
1065 sprintf (buffer
, "%d", narg
);
1066 sb_add_string (&ptr
->actual
, buffer
);
1069 err
= macro_expand_body (&m
->sub
, out
, m
->formals
, m
->formal_hash
,
1074 /* Discard any unnamed formal arguments. */
1082 if ((*pf
)->name
.len
!= 0)
1086 sb_kill (&(*pf
)->name
);
1087 sb_kill (&(*pf
)->def
);
1088 sb_kill (&(*pf
)->actual
);
1102 /* Check for a macro. If one is found, put the expansion into
1103 *EXPAND. COMMENT_CHAR is the comment character--this is used by
1104 gasp. Return 1 if a macro is found, 0 otherwise. */
1107 check_macro (line
, expand
, comment_char
, error
)
1118 if (! isalpha ((unsigned char) *line
)
1121 && (! macro_mri
|| *line
!= '.'))
1125 while (isalnum ((unsigned char) *s
)
1130 copy
= (char *) alloca (s
- line
+ 1);
1131 memcpy (copy
, line
, s
- line
);
1132 copy
[s
- line
] = '\0';
1133 for (cs
= copy
; *cs
!= '\0'; cs
++)
1134 if (isupper ((unsigned char) *cs
))
1135 *cs
= tolower (*cs
);
1137 macro
= (macro_entry
*) hash_find (macro_hash
, copy
);
1142 /* Wrap the line up in an sb. */
1144 while (*s
!= '\0' && *s
!= '\n' && *s
!= '\r')
1145 sb_add_char (&line_sb
, *s
++);
1148 *error
= macro_expand (0, &line_sb
, macro
, expand
, comment_char
);
1155 /* Delete a macro. */
1161 hash_delete (macro_hash
, name
);
1164 /* Handle the MRI IRP and IRPC pseudo-ops. These are handled as a
1165 combined macro definition and execution. This returns NULL on
1166 success, or an error message otherwise. */
1169 expand_irp (irpc
, idx
, in
, out
, get_line
, comment_char
)
1174 int (*get_line
) PARAMS ((sb
*));
1180 struct hash_control
*h
;
1188 idx
= sb_skip_white (idx
, in
);
1191 if (! buffer_and_nest (mn
, "ENDR", &sub
, get_line
))
1192 return _("unexpected end of file in irp or irpc");
1198 idx
= get_token (idx
, in
, &f
.name
);
1199 if (f
.name
.len
== 0)
1200 return _("missing model parameter");
1203 err
= hash_jam (h
, sb_terminate (&f
.name
), &f
);
1212 idx
= sb_skip_comma (idx
, in
);
1213 if (idx
>= in
->len
|| in
->ptr
[idx
] == comment_char
)
1215 /* Expand once with a null string. */
1216 err
= macro_expand_body (&sub
, out
, &f
, h
, comment_char
, 0);
1222 if (irpc
&& in
->ptr
[idx
] == '"')
1224 while (idx
< in
->len
&& in
->ptr
[idx
] != comment_char
)
1227 idx
= get_any_string (idx
, in
, &f
.actual
, 1, 0);
1230 if (in
->ptr
[idx
] == '"')
1234 nxt
= sb_skip_white (idx
+ 1, in
);
1235 if (nxt
>= in
->len
|| in
->ptr
[nxt
] == comment_char
)
1241 sb_reset (&f
.actual
);
1242 sb_add_char (&f
.actual
, in
->ptr
[idx
]);
1245 err
= macro_expand_body (&sub
, out
, &f
, h
, comment_char
, 0);
1249 idx
= sb_skip_comma (idx
, in
);
1251 idx
= sb_skip_white (idx
, in
);