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"
68 /* The routines in this file handle macro definition and expansion.
69 They are called by both gasp and gas. */
71 /* Structures used to store macros.
73 Each macro knows its name and included text. It gets built with a
74 list of formal arguments, and also keeps a hash table which points
75 into the list to speed up formal search. Each formal knows its
76 name and its default value. Each time the macro is expanded, the
77 formals get the actual values attatched to them. */
79 /* describe the formal arguments to a macro */
81 typedef struct formal_struct
83 struct formal_struct
*next
; /* next formal in list */
84 sb name
; /* name of the formal */
85 sb def
; /* the default value */
86 sb actual
; /* the actual argument (changed on each expansion) */
87 int index
; /* the index of the formal 0..formal_count-1 */
91 /* Other values found in the index field of a formal_entry. */
92 #define QUAL_INDEX (-1)
93 #define NARG_INDEX (-2)
94 #define LOCAL_INDEX (-3)
96 /* describe the macro. */
98 typedef struct macro_struct
100 sb sub
; /* substitution text. */
101 int formal_count
; /* number of formal args. */
102 formal_entry
*formals
; /* pointer to list of formal_structs */
103 struct hash_control
*formal_hash
; /* hash table of formals. */
107 /* Internal functions. */
109 static int get_token
PARAMS ((int, sb
*, sb
*));
110 static int getstring
PARAMS ((int, sb
*, sb
*));
111 static int get_any_string
PARAMS ((int, sb
*, sb
*, int, int));
112 static int do_formals
PARAMS ((macro_entry
*, int, sb
*));
113 static int get_apost_token
PARAMS ((int, sb
*, sb
*, int));
114 static int sub_actual
115 PARAMS ((int, sb
*, sb
*, struct hash_control
*, int, sb
*, int));
116 static const char *macro_expand_body
117 PARAMS ((sb
*, sb
*, formal_entry
*, struct hash_control
*, int, int));
118 static const char *macro_expand
PARAMS ((int, sb
*, macro_entry
*, sb
*, int));
120 #define ISWHITE(x) ((x) == ' ' || (x) == '\t')
123 ((x) == ' ' || (x) == '\t' || (x) == ',' || (x) == '"' || (x) == ';' \
124 || (x) == ')' || (x) == '(' \
125 || ((macro_alternate || macro_mri) && ((x) == '<' || (x) == '>')))
128 ((x) == 'b' || (x) == 'B' \
129 || (x) == 'q' || (x) == 'Q' \
130 || (x) == 'h' || (x) == 'H' \
131 || (x) == 'd' || (x) == 'D')
133 /* The macro hash table. */
135 static struct hash_control
*macro_hash
;
137 /* Whether any macros have been defined. */
141 /* Whether we are in GASP alternate mode. */
143 static int macro_alternate
;
145 /* Whether we are in MRI mode. */
147 static int macro_mri
;
149 /* Whether we should strip '@' characters. */
151 static int macro_strip_at
;
153 /* Function to use to parse an expression. */
155 static int (*macro_expr
) PARAMS ((const char *, int, sb
*, int *));
157 /* Number of macro expansions that have been done. */
159 static int macro_number
;
161 /* Initialize macro processing. */
164 macro_init (alternate
, mri
, strip_at
, expr
)
168 int (*expr
) PARAMS ((const char *, int, sb
*, int *));
170 macro_hash
= hash_new ();
172 macro_alternate
= alternate
;
174 macro_strip_at
= strip_at
;
178 /* Read input lines till we get to a TO string.
179 Increase nesting depth if we get a FROM string.
180 Put the results into sb at PTR.
181 Add a new input line to an sb using GET_LINE.
182 Return 1 on success, 0 on unexpected EOF. */
185 buffer_and_nest (from
, to
, ptr
, get_line
)
189 int (*get_line
) PARAMS ((sb
*));
191 int from_len
= strlen (from
);
192 int to_len
= strlen (to
);
194 int line_start
= ptr
->len
;
196 int more
= get_line (ptr
);
200 /* Try and find the first pseudo op on the line */
203 if (! macro_alternate
&& ! macro_mri
)
205 /* With normal syntax we can suck what we want till we get
206 to the dot. With the alternate, labels have to start in
207 the first column, since we cant tell what's a label and
210 /* Skip leading whitespace */
211 while (i
< ptr
->len
&& ISWHITE (ptr
->ptr
[i
]))
214 /* Skip over a label */
216 && (isalnum ((unsigned char) ptr
->ptr
[i
])
217 || ptr
->ptr
[i
] == '_'
218 || ptr
->ptr
[i
] == '$'))
223 && ptr
->ptr
[i
] == ':')
227 /* Skip trailing whitespace */
228 while (i
< ptr
->len
&& ISWHITE (ptr
->ptr
[i
]))
231 if (i
< ptr
->len
&& (ptr
->ptr
[i
] == '.'
235 if (ptr
->ptr
[i
] == '.')
237 if (strncasecmp (ptr
->ptr
+ i
, from
, from_len
) == 0)
239 if (strncasecmp (ptr
->ptr
+ i
, to
, to_len
) == 0)
244 /* Reset the string to not include the ending rune */
245 ptr
->len
= line_start
;
251 /* Add a CR to the end and keep running */
252 sb_add_char (ptr
, '\n');
253 line_start
= ptr
->len
;
254 more
= get_line (ptr
);
257 /* Return 1 on success, 0 on unexpected EOF. */
261 /* Pick up a token. */
264 get_token (idx
, in
, name
)
270 && (isalpha ((unsigned char) in
->ptr
[idx
])
271 || in
->ptr
[idx
] == '_'
272 || in
->ptr
[idx
] == '$'))
274 sb_add_char (name
, in
->ptr
[idx
++]);
276 && (isalnum ((unsigned char) in
->ptr
[idx
])
277 || in
->ptr
[idx
] == '_'
278 || in
->ptr
[idx
] == '$'))
280 sb_add_char (name
, in
->ptr
[idx
++]);
283 /* Ignore trailing & */
284 if (macro_alternate
&& idx
< in
->len
&& in
->ptr
[idx
] == '&')
289 /* Pick up a string. */
292 getstring (idx
, in
, acc
)
297 idx
= sb_skip_white (idx
, in
);
300 && (in
->ptr
[idx
] == '"'
301 || (in
->ptr
[idx
] == '<' && (macro_alternate
|| macro_mri
))
302 || (in
->ptr
[idx
] == '\'' && macro_alternate
)))
304 if (in
->ptr
[idx
] == '<')
308 while ((in
->ptr
[idx
] != '>' || nest
)
311 if (in
->ptr
[idx
] == '!')
314 sb_add_char (acc
, in
->ptr
[idx
++]);
318 if (in
->ptr
[idx
] == '>')
320 if (in
->ptr
[idx
] == '<')
322 sb_add_char (acc
, in
->ptr
[idx
++]);
327 else if (in
->ptr
[idx
] == '"' || in
->ptr
[idx
] == '\'')
329 char tchar
= in
->ptr
[idx
];
331 while (idx
< in
->len
)
333 if (macro_alternate
&& in
->ptr
[idx
] == '!')
336 sb_add_char (acc
, in
->ptr
[idx
++]);
340 if (in
->ptr
[idx
] == tchar
)
343 if (idx
>= in
->len
|| in
->ptr
[idx
] != tchar
)
346 sb_add_char (acc
, in
->ptr
[idx
]);
356 /* Fetch string from the input stream,
358 'Bxyx<whitespace> -> return 'Bxyza
359 %<char> -> return string of decimal value of x
360 "<string>" -> return string
361 xyx<whitespace> -> return xyz
365 get_any_string (idx
, in
, out
, expand
, pretend_quoted
)
373 idx
= sb_skip_white (idx
, in
);
377 if (in
->len
> 2 && in
->ptr
[idx
+1] == '\'' && ISBASE (in
->ptr
[idx
]))
379 while (!ISSEP (in
->ptr
[idx
]))
380 sb_add_char (out
, in
->ptr
[idx
++]);
382 else if (in
->ptr
[idx
] == '%'
388 /* Turns the next expression into a string */
389 idx
= (*macro_expr
) ("% operator needs absolute expression",
393 sprintf(buf
, "%d", val
);
394 sb_add_string (out
, buf
);
396 else if (in
->ptr
[idx
] == '"'
397 || (in
->ptr
[idx
] == '<' && (macro_alternate
|| macro_mri
))
398 || (macro_alternate
&& in
->ptr
[idx
] == '\''))
404 /* Keep the quotes */
405 sb_add_char (out
, '\"');
407 idx
= getstring (idx
, in
, out
);
408 sb_add_char (out
, '\"');
412 idx
= getstring (idx
, in
, out
);
418 && (in
->ptr
[idx
] == '"'
419 || in
->ptr
[idx
] == '\''
421 || (in
->ptr
[idx
] != ' '
422 && in
->ptr
[idx
] != '\t'
423 && in
->ptr
[idx
] != ','
424 && (in
->ptr
[idx
] != '<'
425 || (! macro_alternate
&& ! macro_mri
)))))
427 if (in
->ptr
[idx
] == '"'
428 || in
->ptr
[idx
] == '\'')
430 char tchar
= in
->ptr
[idx
];
431 sb_add_char (out
, in
->ptr
[idx
++]);
433 && in
->ptr
[idx
] != tchar
)
434 sb_add_char (out
, in
->ptr
[idx
++]);
438 sb_add_char (out
, in
->ptr
[idx
++]);
446 /* Pick up the formal parameters of a macro definition. */
449 do_formals (macro
, idx
, in
)
454 formal_entry
**p
= ¯o
->formals
;
456 macro
->formal_count
= 0;
457 macro
->formal_hash
= hash_new ();
458 while (idx
< in
->len
)
460 formal_entry
*formal
;
462 formal
= (formal_entry
*) xmalloc (sizeof (formal_entry
));
464 sb_new (&formal
->name
);
465 sb_new (&formal
->def
);
466 sb_new (&formal
->actual
);
468 idx
= sb_skip_white (idx
, in
);
469 idx
= get_token (idx
, in
, &formal
->name
);
470 if (formal
->name
.len
== 0)
472 idx
= sb_skip_white (idx
, in
);
473 if (formal
->name
.len
)
475 /* This is a formal */
476 if (idx
< in
->len
&& in
->ptr
[idx
] == '=')
479 idx
= get_any_string (idx
+ 1, in
, &formal
->def
, 1, 0);
483 /* Add to macro's hash table */
484 hash_jam (macro
->formal_hash
, sb_terminate (&formal
->name
), formal
);
486 formal
->index
= macro
->formal_count
;
487 idx
= sb_skip_comma (idx
, in
);
488 macro
->formal_count
++;
496 formal_entry
*formal
;
499 /* Add a special NARG formal, which macro_expand will set to the
500 number of arguments. */
501 formal
= (formal_entry
*) xmalloc (sizeof (formal_entry
));
503 sb_new (&formal
->name
);
504 sb_new (&formal
->def
);
505 sb_new (&formal
->actual
);
507 /* The same MRI assemblers which treat '@' characters also use
508 the name $NARG. At least until we find an exception. */
514 sb_add_string (&formal
->name
, name
);
516 /* Add to macro's hash table */
517 hash_jam (macro
->formal_hash
, name
, formal
);
519 formal
->index
= NARG_INDEX
;
527 /* Define a new macro. Returns NULL on success, otherwise returns an
528 error message. If NAMEP is not NULL, *NAMEP is set to the name of
529 the macro which was defined. */
532 define_macro (idx
, in
, label
, get_line
, namep
)
536 int (*get_line
) PARAMS ((sb
*));
543 macro
= (macro_entry
*) xmalloc (sizeof (macro_entry
));
544 sb_new (¯o
->sub
);
547 macro
->formal_count
= 0;
550 idx
= sb_skip_white (idx
, in
);
551 if (! buffer_and_nest ("MACRO", "ENDM", ¯o
->sub
, get_line
))
552 return "unexpected end of file in macro definition";
553 if (label
!= NULL
&& label
->len
!= 0)
555 sb_add_sb (&name
, label
);
556 if (idx
< in
->len
&& in
->ptr
[idx
] == '(')
558 /* It's the label: MACRO (formals,...) sort */
559 idx
= do_formals (macro
, idx
+ 1, in
);
560 if (in
->ptr
[idx
] != ')')
561 return "missing ) after formals";
565 /* It's the label: MACRO formals,... sort */
566 idx
= do_formals (macro
, idx
, in
);
571 idx
= get_token (idx
, in
, &name
);
572 idx
= sb_skip_comma (idx
, in
);
573 idx
= do_formals (macro
, idx
, in
);
576 /* and stick it in the macro hash table */
577 for (idx
= 0; idx
< name
.len
; idx
++)
578 if (isupper (name
.ptr
[idx
]))
579 name
.ptr
[idx
] = tolower (name
.ptr
[idx
]);
580 namestr
= sb_terminate (&name
);
581 hash_jam (macro_hash
, namestr
, (PTR
) macro
);
591 /* Scan a token, and then skip KIND. */
594 get_apost_token (idx
, in
, name
, kind
)
600 idx
= get_token (idx
, in
, name
);
602 && in
->ptr
[idx
] == kind
603 && (! macro_mri
|| macro_strip_at
)
604 && (! macro_strip_at
|| kind
== '@'))
609 /* Substitute the actual value for a formal parameter. */
612 sub_actual (start
, in
, t
, formal_hash
, kind
, out
, copyifnotthere
)
616 struct hash_control
*formal_hash
;
624 src
= get_apost_token (start
, in
, t
, kind
);
625 /* See if it's in the macro's hash table, unless this is
626 macro_strip_at and kind is '@' and the token did not end in '@'. */
629 && (src
== start
|| in
->ptr
[src
- 1] != '@'))
632 ptr
= (formal_entry
*) hash_find (formal_hash
, sb_terminate (t
));
637 sb_add_sb (out
, &ptr
->actual
);
641 sb_add_sb (out
, &ptr
->def
);
644 else if (kind
== '&')
646 /* Doing this permits people to use & in macro bodies. */
647 sb_add_char (out
, '&');
649 else if (copyifnotthere
)
655 sb_add_char (out
, '\\');
661 /* Expand the body of a macro. */
664 macro_expand_body (in
, out
, formals
, formal_hash
, comment_char
, locals
)
667 formal_entry
*formals
;
668 struct hash_control
*formal_hash
;
675 formal_entry
*loclist
= NULL
;
679 while (src
< in
->len
)
681 if (in
->ptr
[src
] == '&')
686 if (src
+ 1 < in
->len
&& in
->ptr
[src
+ 1] == '&')
687 src
= sub_actual (src
+ 2, in
, &t
, formal_hash
, '\'', out
, 1);
689 sb_add_char (out
, in
->ptr
[src
++]);
693 /* FIXME: Why do we do this? */
694 src
= sub_actual (src
+ 1, in
, &t
, formal_hash
, '&', out
, 0);
697 else if (in
->ptr
[src
] == '\\')
700 if (in
->ptr
[src
] == comment_char
&& comment_char
!= '\0')
702 /* This is a comment, just drop the rest of the line */
704 && in
->ptr
[src
] != '\n')
707 else if (in
->ptr
[src
] == '(')
709 /* Sub in till the next ')' literally */
711 while (src
< in
->len
&& in
->ptr
[src
] != ')')
713 sb_add_char (out
, in
->ptr
[src
++]);
715 if (in
->ptr
[src
] == ')')
718 return "missplaced )";
720 else if (in
->ptr
[src
] == '@')
722 /* Sub in the macro invocation number */
726 sprintf (buffer
, "%05d", macro_number
);
727 sb_add_string (out
, buffer
);
729 else if (in
->ptr
[src
] == '&')
731 /* This is a preprocessor variable name, we don't do them
733 sb_add_char (out
, '\\');
734 sb_add_char (out
, '&');
738 && isalnum ((unsigned char) in
->ptr
[src
]))
743 if (isdigit ((unsigned char) in
->ptr
[src
]))
744 ind
= in
->ptr
[src
] - '0';
745 else if (isupper ((unsigned char) in
->ptr
[src
]))
746 ind
= in
->ptr
[src
] - 'A' + 10;
748 ind
= in
->ptr
[src
] - 'a' + 10;
750 for (f
= formals
; f
!= NULL
; f
= f
->next
)
752 if (f
->index
== ind
- 1)
754 if (f
->actual
.len
!= 0)
755 sb_add_sb (out
, &f
->actual
);
757 sb_add_sb (out
, &f
->def
);
765 src
= sub_actual (src
, in
, &t
, formal_hash
, '\'', out
, 0);
768 else if ((macro_alternate
|| macro_mri
)
769 && (isalpha ((unsigned char) in
->ptr
[src
])
770 || in
->ptr
[src
] == '_'
771 || in
->ptr
[src
] == '$')
774 || (src
> 0 && in
->ptr
[src
- 1] == '@')))
777 || src
+ 5 >= in
->len
778 || strncasecmp (in
->ptr
+ src
, "LOCAL", 5) != 0
779 || ! ISWHITE (in
->ptr
[src
+ 5]))
782 src
= sub_actual (src
, in
, &t
, formal_hash
,
783 (macro_strip_at
&& inquote
) ? '@' : '\'',
790 src
= sb_skip_white (src
+ 5, in
);
791 while (in
->ptr
[src
] != '\n' && in
->ptr
[src
] != comment_char
)
797 f
= (formal_entry
*) xmalloc (sizeof (formal_entry
));
801 f
->index
= LOCAL_INDEX
;
805 src
= get_token (src
, in
, &f
->name
);
807 sprintf (buf
, "LL%04x", loccnt
);
808 sb_add_string (&f
->actual
, buf
);
810 err
= hash_jam (formal_hash
, sb_terminate (&f
->name
), f
);
814 src
= sb_skip_comma (src
, in
);
818 else if (comment_char
!= '\0'
819 && in
->ptr
[src
] == comment_char
821 && in
->ptr
[src
+ 1] == comment_char
824 /* Two comment chars in a row cause the rest of the line to
826 while (src
< in
->len
&& in
->ptr
[src
] != '\n')
829 else if (in
->ptr
[src
] == '"'
830 || (macro_mri
&& in
->ptr
[src
] == '\''))
833 sb_add_char (out
, in
->ptr
[src
++]);
835 else if (in
->ptr
[src
] == '@' && macro_strip_at
)
839 && in
->ptr
[src
] == '@')
841 sb_add_char (out
, '@');
846 && in
->ptr
[src
] == '='
848 && in
->ptr
[src
+ 1] == '=')
853 src
= get_token (src
+ 2, in
, &t
);
854 ptr
= (formal_entry
*) hash_find (formal_hash
, sb_terminate (&t
));
857 /* FIXME: We should really return a warning string here,
858 but we can't, because the == might be in the MRI
859 comment field, and, since the nature of the MRI
860 comment field depends upon the exact instruction
861 being used, we don't have enough information here to
862 figure out whether it is or not. Instead, we leave
863 the == in place, which should cause a syntax error if
864 it is not in a comment. */
865 sb_add_char (out
, '=');
866 sb_add_char (out
, '=');
873 sb_add_string (out
, "-1");
877 sb_add_char (out
, '0');
883 sb_add_char (out
, in
->ptr
[src
++]);
889 while (loclist
!= NULL
)
894 hash_delete (formal_hash
, sb_terminate (&loclist
->name
));
895 sb_kill (&loclist
->name
);
896 sb_kill (&loclist
->def
);
897 sb_kill (&loclist
->actual
);
905 /* Assign values to the formal parameters of a macro, and expand the
909 macro_expand (idx
, in
, m
, out
, comment_char
)
919 int is_positional
= 0;
926 /* Reset any old value the actuals may have */
927 for (f
= m
->formals
; f
; f
= f
->next
)
928 sb_reset (&f
->actual
);
930 while (f
!= NULL
&& f
->index
< 0)
935 /* The macro may be called with an optional qualifier, which may
936 be referred to in the macro body as \0. */
937 if (idx
< in
->len
&& in
->ptr
[idx
] == '.')
941 n
= (formal_entry
*) xmalloc (sizeof (formal_entry
));
945 n
->index
= QUAL_INDEX
;
947 n
->next
= m
->formals
;
950 idx
= get_any_string (idx
+ 1, 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
)
1107 if (! isalpha ((unsigned char) *line
)
1110 && (! macro_mri
|| *line
!= '.'))
1114 while (isalnum ((unsigned char) *s
)
1119 copy
= (char *) alloca (s
- line
+ 1);
1120 memcpy (copy
, line
, s
- line
);
1121 copy
[s
- line
] = '\0';
1122 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
);
1144 /* Delete a macro. */
1150 hash_delete (macro_hash
, name
);
1153 /* Handle the MRI IRP and IRPC pseudo-ops. These are handled as a
1154 combined macro definition and execution. This returns NULL on
1155 success, or an error message otherwise. */
1158 expand_irp (irpc
, idx
, in
, out
, get_line
, comment_char
)
1163 int (*get_line
) PARAMS ((sb
*));
1169 struct hash_control
*h
;
1177 idx
= sb_skip_white (idx
, in
);
1180 if (! buffer_and_nest (mn
, "ENDR", &sub
, get_line
))
1181 return "unexpected end of file in irp or irpc";
1187 idx
= get_token (idx
, in
, &f
.name
);
1188 if (f
.name
.len
== 0)
1189 return "missing model parameter";
1192 err
= hash_jam (h
, sb_terminate (&f
.name
), &f
);
1201 idx
= sb_skip_comma (idx
, in
);
1202 if (idx
>= in
->len
|| in
->ptr
[idx
] == comment_char
)
1204 /* Expand once with a null string. */
1205 err
= macro_expand_body (&sub
, out
, &f
, h
, comment_char
, 0);
1211 if (irpc
&& in
->ptr
[idx
] == '"')
1213 while (idx
< in
->len
&& in
->ptr
[idx
] != comment_char
)
1216 idx
= get_any_string (idx
, in
, &f
.actual
, 1, 0);
1219 if (in
->ptr
[idx
] == '"')
1223 nxt
= sb_skip_white (idx
+ 1, in
);
1224 if (nxt
>= in
->len
|| in
->ptr
[nxt
] == comment_char
)
1230 sb_reset (&f
.actual
);
1231 sb_add_char (&f
.actual
, in
->ptr
[idx
]);
1234 err
= macro_expand_body (&sub
, out
, &f
, h
, comment_char
, 0);
1238 idx
= sb_skip_comma (idx
, in
);
1240 idx
= sb_skip_white (idx
, in
);
This page took 0.079967 seconds and 4 git commands to generate.