1 /* macro.c - macro support for gas
2 Copyright 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003,
3 2004, 2005 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"
59 #include "safe-ctype.h"
66 /* The routines in this file handle macro definition and expansion.
67 They are called by gas. */
69 /* Internal functions. */
71 static int get_token (int, sb
*, sb
*);
72 static int getstring (int, sb
*, sb
*);
73 static int get_any_string (int, sb
*, sb
*, int, int);
74 static int do_formals (macro_entry
*, int, sb
*);
75 static int get_apost_token (int, sb
*, sb
*, int);
76 static int sub_actual (int, sb
*, sb
*, struct hash_control
*, int, sb
*, int);
77 static const char *macro_expand_body
78 (sb
*, sb
*, formal_entry
*, struct hash_control
*, int);
79 static const char *macro_expand (int, sb
*, macro_entry
*, sb
*);
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 struct hash_control
*macro_hash
;
98 /* Whether any macros have been defined. */
102 /* Whether we are in alternate syntax 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
) (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 (int alternate
, int mri
, int strip_at
,
126 int (*expr
) (const char *, int, sb
*, int *))
128 macro_hash
= hash_new ();
130 macro_alternate
= alternate
;
132 macro_strip_at
= strip_at
;
136 /* Switch in and out of alternate mode on the fly. */
139 macro_set_alternate (int alternate
)
141 macro_alternate
= alternate
;
144 /* Switch in and out of MRI mode on the fly. */
147 macro_mri_mode (int mri
)
152 /* Read input lines till we get to a TO string.
153 Increase nesting depth if we get a FROM string.
154 Put the results into sb at PTR.
155 FROM may be NULL (or will be ignored) if TO is "ENDR".
156 Add a new input line to an sb using GET_LINE.
157 Return 1 on success, 0 on unexpected EOF. */
160 buffer_and_nest (const char *from
, const char *to
, sb
*ptr
,
161 int (*get_line
) (sb
*))
164 int to_len
= strlen (to
);
166 int line_start
= ptr
->len
;
168 int more
= get_line (ptr
);
170 if (to_len
== 4 && strcasecmp(to
, "ENDR") == 0)
176 from_len
= strlen (from
);
180 /* Try and find the first pseudo op on the line. */
183 if (! NO_PSEUDO_DOT
&& ! flag_m68k_mri
)
185 /* With normal syntax we can suck what we want till we get
186 to the dot. With the alternate, labels have to start in
187 the first column, since we can't tell what's a label and
190 if (! LABELS_WITHOUT_COLONS
)
192 /* Skip leading whitespace. */
193 while (i
< ptr
->len
&& ISWHITE (ptr
->ptr
[i
]))
199 /* Skip over a label, if any. */
200 if (i
>= ptr
->len
|| ! is_name_beginner (ptr
->ptr
[i
]))
203 while (i
< ptr
->len
&& is_part_of_name (ptr
->ptr
[i
]))
205 if (i
< ptr
->len
&& is_name_ender (ptr
->ptr
[i
]))
207 if (LABELS_WITHOUT_COLONS
)
209 /* Skip whitespace. */
210 while (i
< ptr
->len
&& ISWHITE (ptr
->ptr
[i
]))
212 /* Check for the colon. */
213 if (i
>= ptr
->len
|| ptr
->ptr
[i
] != ':')
223 /* Skip trailing whitespace. */
224 while (i
< ptr
->len
&& ISWHITE (ptr
->ptr
[i
]))
227 if (i
< ptr
->len
&& (ptr
->ptr
[i
] == '.'
231 if (! flag_m68k_mri
&& ptr
->ptr
[i
] == '.')
234 && strncasecmp (ptr
->ptr
+ i
, "IRPC", from_len
= 4) != 0
235 && strncasecmp (ptr
->ptr
+ i
, "IRP", from_len
= 3) != 0
236 && strncasecmp (ptr
->ptr
+ i
, "IREPC", from_len
= 5) != 0
237 && strncasecmp (ptr
->ptr
+ i
, "IREP", from_len
= 4) != 0
238 && strncasecmp (ptr
->ptr
+ i
, "REPT", from_len
= 4) != 0
239 && strncasecmp (ptr
->ptr
+ i
, "REP", from_len
= 3) != 0)
242 ? strncasecmp (ptr
->ptr
+ i
, from
, from_len
) == 0
244 && (ptr
->len
== (i
+ from_len
)
245 || ! (is_part_of_name (ptr
->ptr
[i
+ from_len
])
246 || is_name_ender (ptr
->ptr
[i
+ from_len
]))))
248 if (strncasecmp (ptr
->ptr
+ i
, to
, to_len
) == 0
249 && (ptr
->len
== (i
+ to_len
)
250 || ! (is_part_of_name (ptr
->ptr
[i
+ to_len
])
251 || is_name_ender (ptr
->ptr
[i
+ to_len
]))))
256 /* Reset the string to not include the ending rune. */
257 ptr
->len
= line_start
;
263 /* Add the original end-of-line char to the end and keep running. */
264 sb_add_char (ptr
, more
);
265 line_start
= ptr
->len
;
266 more
= get_line (ptr
);
269 /* Return 1 on success, 0 on unexpected EOF. */
273 /* Pick up a token. */
276 get_token (int idx
, sb
*in
, sb
*name
)
279 && is_name_beginner (in
->ptr
[idx
]))
281 sb_add_char (name
, in
->ptr
[idx
++]);
283 && is_part_of_name (in
->ptr
[idx
]))
285 sb_add_char (name
, in
->ptr
[idx
++]);
288 && is_name_ender (in
->ptr
[idx
]))
290 sb_add_char (name
, in
->ptr
[idx
++]);
293 /* Ignore trailing &. */
294 if (macro_alternate
&& idx
< in
->len
&& in
->ptr
[idx
] == '&')
299 /* Pick up a string. */
302 getstring (int idx
, sb
*in
, sb
*acc
)
304 idx
= sb_skip_white (idx
, in
);
307 && (in
->ptr
[idx
] == '"'
308 || (in
->ptr
[idx
] == '<' && (macro_alternate
|| macro_mri
))
309 || (in
->ptr
[idx
] == '\'' && macro_alternate
)))
311 if (in
->ptr
[idx
] == '<')
315 while ((in
->ptr
[idx
] != '>' || nest
)
318 if (in
->ptr
[idx
] == '!')
321 sb_add_char (acc
, in
->ptr
[idx
++]);
325 if (in
->ptr
[idx
] == '>')
327 if (in
->ptr
[idx
] == '<')
329 sb_add_char (acc
, in
->ptr
[idx
++]);
334 else if (in
->ptr
[idx
] == '"' || in
->ptr
[idx
] == '\'')
336 char tchar
= in
->ptr
[idx
];
341 while (idx
< in
->len
)
343 if (in
->ptr
[idx
- 1] == '\\')
348 if (macro_alternate
&& in
->ptr
[idx
] == '!')
352 sb_add_char (acc
, in
->ptr
[idx
]);
356 else if (escaped
&& in
->ptr
[idx
] == tchar
)
358 sb_add_char (acc
, tchar
);
363 if (in
->ptr
[idx
] == tchar
)
367 if (idx
>= in
->len
|| in
->ptr
[idx
] != tchar
)
371 sb_add_char (acc
, in
->ptr
[idx
]);
381 /* Fetch string from the input stream,
383 'Bxyx<whitespace> -> return 'Bxyza
384 %<char> -> return string of decimal value of x
385 "<string>" -> return string
386 xyx<whitespace> -> return xyz
390 get_any_string (int idx
, sb
*in
, sb
*out
, int expand
, int pretend_quoted
)
393 idx
= sb_skip_white (idx
, in
);
397 if (in
->len
> idx
+ 2 && in
->ptr
[idx
+ 1] == '\'' && ISBASE (in
->ptr
[idx
]))
399 while (!ISSEP (in
->ptr
[idx
]))
400 sb_add_char (out
, in
->ptr
[idx
++]);
402 else if (in
->ptr
[idx
] == '%'
408 /* Turns the next expression into a string. */
409 /* xgettext: no-c-format */
410 idx
= (*macro_expr
) (_("% operator needs absolute expression"),
414 sprintf (buf
, "%d", val
);
415 sb_add_string (out
, buf
);
417 else if (in
->ptr
[idx
] == '"'
418 || (in
->ptr
[idx
] == '<' && (macro_alternate
|| macro_mri
))
419 || (macro_alternate
&& in
->ptr
[idx
] == '\''))
425 /* Keep the quotes. */
426 sb_add_char (out
, '\"');
428 idx
= getstring (idx
, in
, out
);
429 sb_add_char (out
, '\"');
433 idx
= getstring (idx
, in
, out
);
439 && (in
->ptr
[idx
] == '"'
440 || in
->ptr
[idx
] == '\''
442 || (in
->ptr
[idx
] != ' '
443 && in
->ptr
[idx
] != '\t'
444 && in
->ptr
[idx
] != ','
445 && (in
->ptr
[idx
] != '<'
446 || (! macro_alternate
&& ! macro_mri
)))))
448 if (in
->ptr
[idx
] == '"'
449 || in
->ptr
[idx
] == '\'')
451 char tchar
= in
->ptr
[idx
];
452 sb_add_char (out
, in
->ptr
[idx
++]);
454 && in
->ptr
[idx
] != tchar
)
455 sb_add_char (out
, in
->ptr
[idx
++]);
459 sb_add_char (out
, in
->ptr
[idx
++]);
467 /* Pick up the formal parameters of a macro definition. */
470 do_formals (macro_entry
*macro
, int idx
, sb
*in
)
472 formal_entry
**p
= ¯o
->formals
;
474 macro
->formal_count
= 0;
475 macro
->formal_hash
= hash_new ();
476 idx
= sb_skip_white (idx
, in
);
477 while (idx
< in
->len
)
479 formal_entry
*formal
;
482 formal
= (formal_entry
*) xmalloc (sizeof (formal_entry
));
484 sb_new (&formal
->name
);
485 sb_new (&formal
->def
);
486 sb_new (&formal
->actual
);
488 idx
= get_token (idx
, in
, &formal
->name
);
489 if (formal
->name
.len
== 0)
491 if (macro
->formal_count
)
495 idx
= sb_skip_white (idx
, in
);
496 /* This is a formal. */
497 if (idx
< in
->len
&& in
->ptr
[idx
] == '=')
500 idx
= get_any_string (idx
+ 1, in
, &formal
->def
, 1, 0);
501 idx
= sb_skip_white (idx
, in
);
504 /* Add to macro's hash table. */
505 hash_jam (macro
->formal_hash
, sb_terminate (&formal
->name
), formal
);
507 formal
->index
= macro
->formal_count
++;
509 idx
= sb_skip_comma (idx
, in
);
510 if (idx
!= cidx
&& idx
>= in
->len
)
522 formal_entry
*formal
;
525 /* Add a special NARG formal, which macro_expand will set to the
526 number of arguments. */
527 formal
= (formal_entry
*) xmalloc (sizeof (formal_entry
));
529 sb_new (&formal
->name
);
530 sb_new (&formal
->def
);
531 sb_new (&formal
->actual
);
533 /* The same MRI assemblers which treat '@' characters also use
534 the name $NARG. At least until we find an exception. */
540 sb_add_string (&formal
->name
, name
);
542 /* Add to macro's hash table. */
543 hash_jam (macro
->formal_hash
, name
, formal
);
545 formal
->index
= NARG_INDEX
;
553 /* Define a new macro. Returns NULL on success, otherwise returns an
554 error message. If NAMEP is not NULL, *NAMEP is set to the name of
555 the macro which was defined. */
558 define_macro (int idx
, sb
*in
, sb
*label
,
559 int (*get_line
) (sb
*), const char **namep
)
565 macro
= (macro_entry
*) xmalloc (sizeof (macro_entry
));
566 sb_new (¯o
->sub
);
569 macro
->formal_count
= 0;
572 idx
= sb_skip_white (idx
, in
);
573 if (! buffer_and_nest ("MACRO", "ENDM", ¯o
->sub
, get_line
))
574 return _("unexpected end of file in macro definition");
575 if (label
!= NULL
&& label
->len
!= 0)
577 sb_add_sb (&name
, label
);
578 if (idx
< in
->len
&& in
->ptr
[idx
] == '(')
580 /* It's the label: MACRO (formals,...) sort */
581 idx
= do_formals (macro
, idx
+ 1, in
);
582 if (idx
>= in
->len
|| in
->ptr
[idx
] != ')')
583 return _("missing ) after formals");
584 idx
= sb_skip_white (idx
+ 1, in
);
588 /* It's the label: MACRO formals,... sort */
589 idx
= do_formals (macro
, idx
, in
);
596 idx
= get_token (idx
, in
, &name
);
598 return _("Missing macro name");
599 cidx
= sb_skip_white (idx
, in
);
600 idx
= sb_skip_comma (cidx
, in
);
601 if (idx
== cidx
|| idx
< in
->len
)
602 idx
= do_formals (macro
, idx
, in
);
607 return _("Bad macro parameter list");
609 /* And stick it in the macro hash table. */
610 for (idx
= 0; idx
< name
.len
; idx
++)
611 name
.ptr
[idx
] = TOLOWER (name
.ptr
[idx
]);
612 namestr
= sb_terminate (&name
);
613 if (hash_find (macro_hash
, namestr
))
614 return _("Macro with this name was already defined");
615 hash_jam (macro_hash
, namestr
, (PTR
) macro
);
625 /* Scan a token, and then skip KIND. */
628 get_apost_token (int idx
, sb
*in
, sb
*name
, int kind
)
630 idx
= get_token (idx
, in
, name
);
632 && in
->ptr
[idx
] == kind
633 && (! macro_mri
|| macro_strip_at
)
634 && (! macro_strip_at
|| kind
== '@'))
639 /* Substitute the actual value for a formal parameter. */
642 sub_actual (int start
, sb
*in
, sb
*t
, struct hash_control
*formal_hash
,
643 int kind
, sb
*out
, int copyifnotthere
)
648 src
= get_apost_token (start
, in
, t
, kind
);
649 /* See if it's in the macro's hash table, unless this is
650 macro_strip_at and kind is '@' and the token did not end in '@'. */
653 && (src
== start
|| in
->ptr
[src
- 1] != '@'))
656 ptr
= (formal_entry
*) hash_find (formal_hash
, sb_terminate (t
));
661 sb_add_sb (out
, &ptr
->actual
);
665 sb_add_sb (out
, &ptr
->def
);
668 else if (kind
== '&')
670 /* Doing this permits people to use & in macro bodies. */
671 sb_add_char (out
, '&');
674 else if (copyifnotthere
)
680 sb_add_char (out
, '\\');
686 /* Expand the body of a macro. */
689 macro_expand_body (sb
*in
, sb
*out
, formal_entry
*formals
,
690 struct hash_control
*formal_hash
, int locals
)
695 formal_entry
*loclist
= NULL
;
699 while (src
< in
->len
)
701 if (in
->ptr
[src
] == '&')
706 if (src
+ 1 < in
->len
&& in
->ptr
[src
+ 1] == '&')
707 src
= sub_actual (src
+ 2, in
, &t
, formal_hash
, '\'', out
, 1);
709 sb_add_char (out
, in
->ptr
[src
++]);
713 /* FIXME: Why do we do this? */
714 /* At least in alternate mode this seems correct. */
715 src
= sub_actual (src
+ 1, in
, &t
, formal_hash
, '&', out
, 0);
718 else if (in
->ptr
[src
] == '\\')
721 if (src
< in
->len
&& in
->ptr
[src
] == '(')
723 /* Sub in till the next ')' literally. */
725 while (src
< in
->len
&& in
->ptr
[src
] != ')')
727 sb_add_char (out
, in
->ptr
[src
++]);
729 if (in
->ptr
[src
] == ')')
732 return _("misplaced `)'");
734 else if (src
< in
->len
&& in
->ptr
[src
] == '@')
736 /* Sub in the macro invocation number. */
740 sprintf (buffer
, "%d", macro_number
);
741 sb_add_string (out
, buffer
);
743 else if (src
< in
->len
&& in
->ptr
[src
] == '&')
745 /* This is a preprocessor variable name, we don't do them
747 sb_add_char (out
, '\\');
748 sb_add_char (out
, '&');
751 else if (macro_mri
&& src
< in
->len
&& ISALNUM (in
->ptr
[src
]))
756 if (ISDIGIT (in
->ptr
[src
]))
757 ind
= in
->ptr
[src
] - '0';
758 else if (ISUPPER (in
->ptr
[src
]))
759 ind
= in
->ptr
[src
] - 'A' + 10;
761 ind
= in
->ptr
[src
] - 'a' + 10;
763 for (f
= formals
; f
!= NULL
; f
= f
->next
)
765 if (f
->index
== ind
- 1)
767 if (f
->actual
.len
!= 0)
768 sb_add_sb (out
, &f
->actual
);
770 sb_add_sb (out
, &f
->def
);
778 src
= sub_actual (src
, in
, &t
, formal_hash
, '\'', out
, 0);
781 else if ((macro_alternate
|| macro_mri
)
782 && is_name_beginner (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')
808 f
= (formal_entry
*) xmalloc (sizeof (formal_entry
));
812 f
->index
= LOCAL_INDEX
;
816 src
= get_token (src
, in
, &f
->name
);
818 sprintf (buf
, IS_ELF
? ".LL%04x" : "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 (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 /* Setting the value to NULL effectively deletes the entry. We
895 avoid calling hash_delete because it doesn't reclaim memory. */
896 hash_jam (formal_hash
, sb_terminate (&loclist
->name
), NULL
);
897 sb_kill (&loclist
->name
);
898 sb_kill (&loclist
->def
);
899 sb_kill (&loclist
->actual
);
907 /* Assign values to the formal parameters of a macro, and expand the
911 macro_expand (int idx
, sb
*in
, macro_entry
*m
, sb
*out
)
916 int is_positional
= 0;
923 /* Reset any old value the actuals may have. */
924 for (f
= m
->formals
; f
; f
= f
->next
)
925 sb_reset (&f
->actual
);
927 while (f
!= NULL
&& f
->index
< 0)
932 /* The macro may be called with an optional qualifier, which may
933 be referred to in the macro body as \0. */
934 if (idx
< in
->len
&& in
->ptr
[idx
] == '.')
936 /* The Microtec assembler ignores this if followed by a white space.
937 (Macro invocation with empty extension) */
940 && in
->ptr
[idx
] != ' '
941 && in
->ptr
[idx
] != '\t')
945 n
= (formal_entry
*) xmalloc (sizeof (formal_entry
));
949 n
->index
= QUAL_INDEX
;
951 n
->next
= m
->formals
;
954 idx
= get_any_string (idx
, in
, &n
->actual
, 1, 0);
959 /* Peel off the actuals and store them away in the hash tables' actuals. */
960 idx
= sb_skip_white (idx
, in
);
961 while (idx
< in
->len
)
965 /* Look and see if it's a positional or keyword arg. */
967 while (scan
< in
->len
968 && !ISSEP (in
->ptr
[scan
])
969 && !(macro_mri
&& in
->ptr
[scan
] == '\'')
970 && (!macro_alternate
&& in
->ptr
[scan
] != '='))
972 if (scan
< in
->len
&& !macro_alternate
&& in
->ptr
[scan
] == '=')
976 /* It's OK to go from positional to keyword. */
978 /* This is a keyword arg, fetch the formal name and
979 then the actual stuff. */
981 idx
= get_token (idx
, in
, &t
);
982 if (in
->ptr
[idx
] != '=')
983 return _("confusion in formal parameters");
985 /* Lookup the formal in the macro's list. */
986 ptr
= (formal_entry
*) hash_find (m
->formal_hash
, sb_terminate (&t
));
988 return _("macro formal argument does not exist");
991 /* Insert this value into the right place. */
992 sb_reset (&ptr
->actual
);
993 idx
= get_any_string (idx
+ 1, in
, &ptr
->actual
, 0, 0);
994 if (ptr
->actual
.len
> 0)
1000 /* This is a positional arg. */
1003 return _("can't mix positional and keyword arguments");
1011 return _("too many positional arguments");
1013 f
= (formal_entry
*) xmalloc (sizeof (formal_entry
));
1016 sb_new (&f
->actual
);
1020 for (pf
= &m
->formals
; *pf
!= NULL
; pf
= &(*pf
)->next
)
1021 if ((*pf
)->index
>= c
)
1022 c
= (*pf
)->index
+ 1;
1029 sb_reset (&f
->actual
);
1030 idx
= get_any_string (idx
, in
, &f
->actual
, 1, 0);
1031 if (f
->actual
.len
> 0)
1037 while (f
!= NULL
&& f
->index
< 0);
1041 idx
= sb_skip_comma (idx
, in
);
1044 if (in
->ptr
[idx
] == ',')
1046 if (ISWHITE (in
->ptr
[idx
]))
1056 sb_add_string (&t
, macro_strip_at
? "$NARG" : "NARG");
1057 ptr
= (formal_entry
*) hash_find (m
->formal_hash
, sb_terminate (&t
));
1058 sb_reset (&ptr
->actual
);
1059 sprintf (buffer
, "%d", narg
);
1060 sb_add_string (&ptr
->actual
, buffer
);
1063 err
= macro_expand_body (&m
->sub
, out
, m
->formals
, m
->formal_hash
, 1);
1067 /* Discard any unnamed formal arguments. */
1075 if ((*pf
)->name
.len
!= 0)
1079 sb_kill (&(*pf
)->name
);
1080 sb_kill (&(*pf
)->def
);
1081 sb_kill (&(*pf
)->actual
);
1095 /* Check for a macro. If one is found, put the expansion into
1096 *EXPAND. Return 1 if a macro is found, 0 otherwise. */
1099 check_macro (const char *line
, sb
*expand
,
1100 const char **error
, macro_entry
**info
)
1107 if (! is_name_beginner (*line
)
1108 && (! macro_mri
|| *line
!= '.'))
1112 while (is_part_of_name (*s
))
1114 if (is_name_ender (*s
))
1117 copy
= (char *) alloca (s
- line
+ 1);
1118 memcpy (copy
, line
, s
- line
);
1119 copy
[s
- line
] = '\0';
1120 for (cs
= copy
; *cs
!= '\0'; cs
++)
1121 *cs
= TOLOWER (*cs
);
1123 macro
= (macro_entry
*) hash_find (macro_hash
, copy
);
1128 /* Wrap the line up in an sb. */
1130 while (*s
!= '\0' && *s
!= '\n' && *s
!= '\r')
1131 sb_add_char (&line_sb
, *s
++);
1134 *error
= macro_expand (0, &line_sb
, macro
, expand
);
1138 /* Export the macro information if requested. */
1145 /* Delete a macro. */
1148 delete_macro (const char *name
)
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 (int irpc
, int idx
, sb
*in
, sb
*out
, int (*get_line
) (sb
*))
1162 struct hash_control
*h
;
1165 idx
= sb_skip_white (idx
, in
);
1168 if (! buffer_and_nest (NULL
, "ENDR", &sub
, get_line
))
1169 return _("unexpected end of file in irp or irpc");
1175 idx
= get_token (idx
, in
, &f
.name
);
1176 if (f
.name
.len
== 0)
1177 return _("missing model parameter");
1180 err
= hash_jam (h
, sb_terminate (&f
.name
), &f
);
1189 idx
= sb_skip_comma (idx
, in
);
1192 /* Expand once with a null string. */
1193 err
= macro_expand_body (&sub
, out
, &f
, h
, 0);
1199 if (irpc
&& in
->ptr
[idx
] == '"')
1201 while (idx
< in
->len
)
1204 idx
= get_any_string (idx
, in
, &f
.actual
, 1, 0);
1207 if (in
->ptr
[idx
] == '"')
1211 nxt
= sb_skip_white (idx
+ 1, in
);
1218 sb_reset (&f
.actual
);
1219 sb_add_char (&f
.actual
, in
->ptr
[idx
]);
1222 err
= macro_expand_body (&sub
, out
, &f
, h
, 0);
1226 idx
= sb_skip_comma (idx
, in
);
1228 idx
= sb_skip_white (idx
, in
);
This page took 0.057264 seconds and 4 git commands to generate.