1 /* macro.c - macro support for gas
2 Copyright (C) 1994-2023 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 3, 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, 51 Franklin Street - Fifth Floor, Boston, MA
25 #include "safe-ctype.h"
29 /* The routines in this file handle macro definition and expansion.
30 They are called by gas. */
32 #define ISWHITE(x) ((x) == ' ' || (x) == '\t')
35 ((x) == ' ' || (x) == '\t' || (x) == ',' || (x) == '"' || (x) == ';' \
36 || (x) == ')' || (x) == '(' \
37 || ((macro_alternate || macro_mri) && ((x) == '<' || (x) == '>')))
40 ((x) == 'b' || (x) == 'B' \
41 || (x) == 'q' || (x) == 'Q' \
42 || (x) == 'h' || (x) == 'H' \
43 || (x) == 'd' || (x) == 'D')
45 /* The macro hash table. */
49 /* Whether any macros have been defined. */
53 /* Whether we are in alternate syntax mode. */
55 static int macro_alternate
;
57 /* Whether we are in MRI mode. */
61 /* Whether we should strip '@' characters. */
63 static int macro_strip_at
;
65 /* Function to use to parse an expression. */
67 static size_t (*macro_expr
) (const char *, size_t, sb
*, offsetT
*);
69 /* Number of macro expansions that have been done. */
71 static int macro_number
;
73 static void free_macro (macro_entry
*);
76 macro_del_f (void *ent
)
78 string_tuple_t
*tuple
= ent
;
79 free_macro ((macro_entry
*) tuple
->value
);
82 /* Initialize macro processing. */
85 macro_init (int alternate
, int mri
, int strip_at
,
86 size_t (*exp
) (const char *, size_t, sb
*, offsetT
*))
88 macro_hash
= htab_create_alloc (16, hash_string_tuple
, eq_string_tuple
,
89 macro_del_f
, notes_calloc
, NULL
);
91 macro_alternate
= alternate
;
93 macro_strip_at
= strip_at
;
100 htab_delete (macro_hash
);
103 /* Switch in and out of alternate mode on the fly. */
106 macro_set_alternate (int alternate
)
108 macro_alternate
= alternate
;
111 /* Switch in and out of MRI mode on the fly. */
114 macro_mri_mode (int mri
)
119 /* Read input lines till we get to a TO string.
120 Increase nesting depth if we get a FROM string.
121 Put the results into sb at PTR.
122 FROM may be NULL (or will be ignored) if TO is "ENDR".
123 Add a new input line to an sb using GET_LINE.
124 Return 1 on success, 0 on unexpected EOF. */
127 buffer_and_nest (const char *from
, const char *to
, sb
*ptr
,
128 size_t (*get_line
) (sb
*))
131 size_t to_len
= strlen (to
);
133 size_t line_start
, more
;
135 if (to_len
== 4 && strcasecmp (to
, "ENDR") == 0)
141 from_len
= strlen (from
);
143 /* Record the present source position, such that diagnostics and debug info
144 can be properly associated with the respective original lines, rather
145 than with the line of the ending directive (TO). */
150 as_where_top (&line
);
152 linefile
= xasprintf ("\t.linefile %u .", line
+ 1);
154 linefile
= xasprintf ("\tlinefile %u .", line
+ 1);
155 sb_add_string (ptr
, linefile
);
159 line_start
= ptr
->len
;
160 more
= get_line (ptr
);
163 /* Try to find the first pseudo op on the line. */
164 size_t i
= line_start
;
165 bool had_colon
= false;
167 /* With normal syntax we can suck what we want till we get
168 to the dot. With the alternate, labels have to start in
169 the first column, since we can't tell what's a label and
170 what's a pseudoop. */
172 if (! LABELS_WITHOUT_COLONS
)
174 /* Skip leading whitespace. */
175 while (i
< ptr
->len
&& ISWHITE (ptr
->ptr
[i
]))
181 /* Skip over a label, if any. */
182 if (i
>= ptr
->len
|| ! is_name_beginner (ptr
->ptr
[i
]))
185 while (i
< ptr
->len
&& is_part_of_name (ptr
->ptr
[i
]))
187 if (i
< ptr
->len
&& is_name_ender (ptr
->ptr
[i
]))
189 /* Skip whitespace. */
190 while (i
< ptr
->len
&& ISWHITE (ptr
->ptr
[i
]))
192 /* Check for the colon. */
193 if (i
>= ptr
->len
|| ptr
->ptr
[i
] != ':')
195 /* LABELS_WITHOUT_COLONS doesn't mean we cannot have a
196 colon after a label. If we do have a colon on the
197 first label then handle more than one label on the
198 line, assuming that each label has a colon. */
199 if (LABELS_WITHOUT_COLONS
&& !had_colon
)
209 /* Skip trailing whitespace. */
210 while (i
< ptr
->len
&& ISWHITE (ptr
->ptr
[i
]))
213 if (i
< ptr
->len
&& (ptr
->ptr
[i
] == '.'
217 if (! flag_m68k_mri
&& ptr
->ptr
[i
] == '.')
219 size_t len
= ptr
->len
- i
;
222 if (len
>= 5 && strncasecmp (ptr
->ptr
+ i
, "IREPC", 5) == 0)
224 else if (len
>= 4 && strncasecmp (ptr
->ptr
+ i
, "IREP", 4) == 0)
226 else if (len
>= 4 && strncasecmp (ptr
->ptr
+ i
, "IRPC", 4) == 0)
228 else if (len
>= 4 && strncasecmp (ptr
->ptr
+ i
, "REPT", 4) == 0)
230 else if (len
>= 3 && strncasecmp (ptr
->ptr
+ i
, "IRP", 3) == 0)
232 else if (len
>= 3 && strncasecmp (ptr
->ptr
+ i
, "REP", 3) == 0)
239 && strncasecmp (ptr
->ptr
+ i
, from
, from_len
) == 0)
242 || ! (is_part_of_name (ptr
->ptr
[i
+ from_len
])
243 || is_name_ender (ptr
->ptr
[i
+ from_len
]))))
246 && strncasecmp (ptr
->ptr
+ i
, to
, to_len
) == 0
248 || ! (is_part_of_name (ptr
->ptr
[i
+ to_len
])
249 || is_name_ender (ptr
->ptr
[i
+ to_len
]))))
254 /* Reset the string to not include the ending rune. */
255 ptr
->len
= line_start
;
261 Apply .linefile directives that appear within the macro, alongside
262 keeping them for later expansion of the macro. */
263 if (from
!= NULL
&& strcasecmp (from
, "MACRO") == 0
264 && len
>= 8 && strncasecmp (ptr
->ptr
+ i
, "linefile", 8) == 0)
266 sb_add_char (ptr
, more
);
267 temp_ilp (sb_terminate (ptr
) + i
+ 8);
270 line_start
= ptr
->len
;
271 more
= get_line (ptr
);
276 /* Add the original end-of-line char to the end and keep running. */
277 sb_add_char (ptr
, more
);
278 line_start
= ptr
->len
;
279 more
= get_line (ptr
);
282 /* Return 1 on success, 0 on unexpected EOF. */
286 /* Pick up a token. */
289 get_token (size_t idx
, sb
*in
, sb
*name
)
292 && is_name_beginner (in
->ptr
[idx
]))
294 sb_add_char (name
, in
->ptr
[idx
++]);
296 && is_part_of_name (in
->ptr
[idx
]))
298 sb_add_char (name
, in
->ptr
[idx
++]);
301 && is_name_ender (in
->ptr
[idx
]))
303 sb_add_char (name
, in
->ptr
[idx
++]);
306 /* Ignore trailing &. */
307 if (macro_alternate
&& idx
< in
->len
&& in
->ptr
[idx
] == '&')
312 /* Pick up a string. */
315 getstring (size_t idx
, sb
*in
, sb
*acc
)
318 && (in
->ptr
[idx
] == '"'
319 || (in
->ptr
[idx
] == '<' && (macro_alternate
|| macro_mri
))
320 || (in
->ptr
[idx
] == '\'' && macro_alternate
)))
322 if (in
->ptr
[idx
] == '<')
327 && (in
->ptr
[idx
] != '>' || nest
))
329 if (in
->ptr
[idx
] == '!')
332 sb_add_char (acc
, in
->ptr
[idx
++]);
336 if (in
->ptr
[idx
] == '>')
338 if (in
->ptr
[idx
] == '<')
340 sb_add_char (acc
, in
->ptr
[idx
++]);
345 else if (in
->ptr
[idx
] == '"' || in
->ptr
[idx
] == '\'')
347 char tchar
= in
->ptr
[idx
];
352 while (idx
< in
->len
)
354 if (in
->ptr
[idx
- 1] == '\\')
359 if (macro_alternate
&& in
->ptr
[idx
] == '!')
363 sb_add_char (acc
, in
->ptr
[idx
]);
367 else if (escaped
&& in
->ptr
[idx
] == tchar
)
369 sb_add_char (acc
, tchar
);
374 if (in
->ptr
[idx
] == tchar
)
378 if (idx
>= in
->len
|| in
->ptr
[idx
] != tchar
)
382 sb_add_char (acc
, in
->ptr
[idx
]);
392 /* Fetch string from the input stream,
394 'Bxyx<whitespace> -> return 'Bxyza
395 %<expr> -> return string of decimal value of <expr>
396 "string" -> return string
397 (string) -> return (string-including-whitespaces)
398 xyx<whitespace> -> return xyz. */
401 get_any_string (size_t idx
, sb
*in
, sb
*out
)
404 idx
= sb_skip_white (idx
, in
);
408 if (in
->len
> idx
+ 2 && in
->ptr
[idx
+ 1] == '\'' && ISBASE (in
->ptr
[idx
]))
410 while (idx
< in
->len
&& !ISSEP (in
->ptr
[idx
]))
411 sb_add_char (out
, in
->ptr
[idx
++]);
413 else if (in
->ptr
[idx
] == '%' && macro_alternate
)
418 /* Turns the next expression into a string. */
419 /* xgettext: no-c-format */
420 idx
= (*macro_expr
) (_("% operator needs absolute expression"),
424 sprintf (buf
, "%" PRId64
, (int64_t) val
);
425 sb_add_string (out
, buf
);
427 else if (in
->ptr
[idx
] == '"'
428 || (in
->ptr
[idx
] == '<' && (macro_alternate
|| macro_mri
))
429 || (macro_alternate
&& in
->ptr
[idx
] == '\''))
431 if (macro_alternate
&& ! macro_strip_at
&& in
->ptr
[idx
] != '<')
433 /* Keep the quotes. */
434 sb_add_char (out
, '"');
435 idx
= getstring (idx
, in
, out
);
436 sb_add_char (out
, '"');
440 idx
= getstring (idx
, in
, out
);
445 char *br_buf
= XNEWVEC (char, 1);
446 char *in_br
= br_buf
;
451 || (in
->ptr
[idx
] != ' '
452 && in
->ptr
[idx
] != '\t'))
453 && in
->ptr
[idx
] != ','
454 && (in
->ptr
[idx
] != '<'
455 || (! macro_alternate
&& ! macro_mri
)))
457 char tchar
= in
->ptr
[idx
];
463 sb_add_char (out
, in
->ptr
[idx
++]);
465 && in
->ptr
[idx
] != tchar
)
466 sb_add_char (out
, in
->ptr
[idx
++]);
479 br_buf
= XNEWVEC (char, strlen (in_br
) + 2);
480 strcpy (br_buf
+ 1, in_br
);
495 sb_add_char (out
, tchar
);
505 /* Allocate a new formal. */
507 static formal_entry
*
510 formal_entry
*formal
;
512 formal
= XNEW (formal_entry
);
514 sb_new (&formal
->name
);
515 sb_new (&formal
->def
);
516 sb_new (&formal
->actual
);
518 formal
->type
= FORMAL_OPTIONAL
;
525 del_formal (formal_entry
*formal
)
527 sb_kill (&formal
->actual
);
528 sb_kill (&formal
->def
);
529 sb_kill (&formal
->name
);
533 /* Pick up the formal parameters of a macro definition. */
536 do_formals (macro_entry
*macro
, size_t idx
, sb
*in
)
538 formal_entry
**p
= ¯o
->formals
;
541 idx
= sb_skip_white (idx
, in
);
542 while (idx
< in
->len
)
544 formal_entry
*formal
= new_formal ();
547 idx
= get_token (idx
, in
, &formal
->name
);
548 if (formal
->name
.len
== 0)
550 if (macro
->formal_count
)
552 del_formal (formal
); /* 'formal' goes out of scope. */
555 idx
= sb_skip_white (idx
, in
);
556 /* This is a formal. */
557 name
= sb_terminate (&formal
->name
);
560 && in
->ptr
[idx
] == ':'
561 && (! is_name_beginner (':')
562 || idx
+ 1 >= in
->len
563 || ! is_part_of_name (in
->ptr
[idx
+ 1])))
565 /* Got a qualifier. */
569 idx
= get_token (sb_skip_white (idx
+ 1, in
), in
, &qual
);
570 sb_terminate (&qual
);
572 as_bad_where (macro
->file
,
574 _("Missing parameter qualifier for `%s' in macro `%s'"),
577 else if (strcmp (qual
.ptr
, "req") == 0)
578 formal
->type
= FORMAL_REQUIRED
;
579 else if (strcmp (qual
.ptr
, "vararg") == 0)
580 formal
->type
= FORMAL_VARARG
;
582 as_bad_where (macro
->file
,
584 _("`%s' is not a valid parameter qualifier for `%s' in macro `%s'"),
589 idx
= sb_skip_white (idx
, in
);
591 if (idx
< in
->len
&& in
->ptr
[idx
] == '=')
594 idx
= get_any_string (idx
+ 1, in
, &formal
->def
);
595 idx
= sb_skip_white (idx
, in
);
596 if (formal
->type
== FORMAL_REQUIRED
)
598 sb_reset (&formal
->def
);
599 as_warn_where (macro
->file
,
601 _("Pointless default value for required parameter `%s' in macro `%s'"),
607 /* Add to macro's hash table. */
608 if (str_hash_insert (macro
->formal_hash
, name
, formal
, 0) != NULL
)
610 as_bad_where (macro
->file
, macro
->line
,
611 _("A parameter named `%s' "
612 "already exists for macro `%s'"),
616 formal
->index
= macro
->formal_count
++;
619 if (formal
->type
== FORMAL_VARARG
)
622 idx
= sb_skip_comma (idx
, in
);
623 if (idx
!= cidx
&& idx
>= in
->len
)
632 formal_entry
*formal
= new_formal ();
634 /* Add a special NARG formal, which macro_expand will set to the
635 number of arguments. */
636 /* The same MRI assemblers which treat '@' characters also use
637 the name $NARG. At least until we find an exception. */
643 sb_add_string (&formal
->name
, name
);
645 /* Add to macro's hash table. */
646 if (str_hash_insert (macro
->formal_hash
, name
, formal
, 0) != NULL
)
648 as_bad_where (macro
->file
, macro
->line
,
649 _("Reserved word `%s' used as parameter in macro `%s'"),
653 formal
->index
= NARG_INDEX
;
660 /* Free the memory allocated to a macro. */
663 free_macro (macro_entry
*macro
)
665 formal_entry
*formal
;
667 for (formal
= macro
->formals
; formal
; )
672 formal
= formal
->next
;
675 htab_delete (macro
->formal_hash
);
676 sb_kill (¯o
->sub
);
677 free ((char *) macro
->name
);
681 /* Define a new macro. */
684 define_macro (sb
*in
, sb
*label
, size_t (*get_line
) (sb
*))
689 const char *error
= NULL
;
691 macro
= XNEW (macro_entry
);
692 sb_new (¯o
->sub
);
694 macro
->file
= as_where (¯o
->line
);
696 macro
->formal_count
= 0;
698 macro
->formal_hash
= str_htab_create ();
700 idx
= sb_skip_white (0, in
);
701 if (! buffer_and_nest ("MACRO", "ENDM", ¯o
->sub
, get_line
))
702 error
= _("unexpected end of file in macro `%s' definition");
703 if (label
!= NULL
&& label
->len
!= 0)
705 sb_add_sb (&name
, label
);
706 macro
->name
= sb_terminate (&name
);
707 if (idx
< in
->len
&& in
->ptr
[idx
] == '(')
709 /* It's the label: MACRO (formals,...) sort */
710 idx
= do_formals (macro
, idx
+ 1, in
);
711 if (idx
< in
->len
&& in
->ptr
[idx
] == ')')
712 idx
= sb_skip_white (idx
+ 1, in
);
714 error
= _("missing `)' after formals in macro definition `%s'");
718 /* It's the label: MACRO formals,... sort */
719 idx
= do_formals (macro
, idx
, in
);
726 idx
= get_token (idx
, in
, &name
);
727 macro
->name
= sb_terminate (&name
);
729 error
= _("Missing macro name");
730 cidx
= sb_skip_white (idx
, in
);
731 idx
= sb_skip_comma (cidx
, in
);
732 if (idx
== cidx
|| idx
< in
->len
)
733 idx
= do_formals (macro
, idx
, in
);
737 if (!error
&& idx
< in
->len
)
738 error
= _("Bad parameter list for macro `%s'");
740 /* And stick it in the macro hash table. */
741 for (idx
= 0; idx
< name
.len
; idx
++)
742 name
.ptr
[idx
] = TOLOWER (name
.ptr
[idx
]);
745 if (str_hash_insert (macro_hash
, macro
->name
, macro
, 0) != NULL
)
746 error
= _("Macro `%s' was already defined");
753 as_bad_where (macro
->file
, macro
->line
, error
, macro
->name
);
761 /* Scan a token, and then skip KIND. */
764 get_apost_token (size_t idx
, sb
*in
, sb
*name
, int kind
)
766 idx
= get_token (idx
, in
, name
);
768 && in
->ptr
[idx
] == kind
769 && (! macro_mri
|| macro_strip_at
)
770 && (! macro_strip_at
|| kind
== '@'))
775 /* Substitute the actual value for a formal parameter. */
778 sub_actual (size_t start
, sb
*in
, sb
*t
, struct htab
*formal_hash
,
779 int kind
, sb
*out
, int copyifnotthere
)
784 src
= get_apost_token (start
, in
, t
, kind
);
785 /* See if it's in the macro's hash table, unless this is
786 macro_strip_at and kind is '@' and the token did not end in '@'. */
789 && (src
== start
|| in
->ptr
[src
- 1] != '@'))
792 ptr
= str_hash_find (formal_hash
, sb_terminate (t
));
797 sb_add_sb (out
, &ptr
->actual
);
801 sb_add_sb (out
, &ptr
->def
);
804 else if (kind
== '&')
806 /* Doing this permits people to use & in macro bodies. */
807 sb_add_char (out
, '&');
809 if (src
!= start
&& in
->ptr
[src
- 1] == '&')
810 sb_add_char (out
, '&');
812 else if (copyifnotthere
)
818 sb_add_char (out
, '\\');
824 /* Expand the body of a macro. */
827 macro_expand_body (sb
*in
, sb
*out
, formal_entry
*formals
,
828 struct htab
*formal_hash
, const macro_entry
*macro
)
832 int inquote
= 0, macro_line
= 0;
833 formal_entry
*loclist
= NULL
;
834 const char *err
= NULL
;
838 while (src
< in
->len
&& !err
)
840 if (in
->ptr
[src
] == '&')
845 if (src
+ 1 < in
->len
&& in
->ptr
[src
+ 1] == '&')
846 src
= sub_actual (src
+ 2, in
, &t
, formal_hash
, '\'', out
, 1);
848 sb_add_char (out
, in
->ptr
[src
++]);
852 /* Permit macro parameter substitution delineated with
853 an '&' prefix and optional '&' suffix. */
854 src
= sub_actual (src
+ 1, in
, &t
, formal_hash
, '&', out
, 0);
857 else if (in
->ptr
[src
] == '\\')
860 if (src
< in
->len
&& in
->ptr
[src
] == '(')
862 /* Sub in till the next ')' literally. */
864 while (src
< in
->len
&& in
->ptr
[src
] != ')')
866 sb_add_char (out
, in
->ptr
[src
++]);
871 err
= _("missing `)'");
873 as_bad_where (macro
->file
, macro
->line
+ macro_line
, _("missing `)'"));
875 else if (src
< in
->len
&& in
->ptr
[src
] == '@')
877 /* Sub in the macro invocation number. */
881 sprintf (buffer
, "%d", macro_number
);
882 sb_add_string (out
, buffer
);
884 else if (src
< in
->len
&& in
->ptr
[src
] == '&')
886 /* This is a preprocessor variable name, we don't do them
888 sb_add_char (out
, '\\');
889 sb_add_char (out
, '&');
892 else if (macro_mri
&& src
< in
->len
&& ISALNUM (in
->ptr
[src
]))
897 if (ISDIGIT (in
->ptr
[src
]))
898 ind
= in
->ptr
[src
] - '0';
899 else if (ISUPPER (in
->ptr
[src
]))
900 ind
= in
->ptr
[src
] - 'A' + 10;
902 ind
= in
->ptr
[src
] - 'a' + 10;
904 for (f
= formals
; f
!= NULL
; f
= f
->next
)
906 if (f
->index
== ind
- 1)
908 if (f
->actual
.len
!= 0)
909 sb_add_sb (out
, &f
->actual
);
911 sb_add_sb (out
, &f
->def
);
919 src
= sub_actual (src
, in
, &t
, formal_hash
, '\'', out
, 0);
922 else if ((macro_alternate
|| macro_mri
)
923 && is_name_beginner (in
->ptr
[src
])
926 || (src
> 0 && in
->ptr
[src
- 1] == '@')))
929 || src
+ 5 >= in
->len
930 || strncasecmp (in
->ptr
+ src
, "LOCAL", 5) != 0
931 || ! ISWHITE (in
->ptr
[src
+ 5])
932 /* PR 11507: Skip keyword LOCAL if it is found inside a quoted string. */
936 src
= sub_actual (src
, in
, &t
, formal_hash
,
937 (macro_strip_at
&& inquote
) ? '@' : '\'',
942 src
= sb_skip_white (src
+ 5, in
);
943 while (in
->ptr
[src
] != '\n')
946 formal_entry
*f
= new_formal ();
948 src
= get_token (src
, in
, &f
->name
);
949 name
= sb_terminate (&f
->name
);
950 if (str_hash_insert (formal_hash
, name
, f
, 0) != NULL
)
952 as_bad_where (macro
->file
, macro
->line
+ macro_line
,
953 _("`%s' was already used as parameter "
954 "(or another local) name"), name
);
962 f
->index
= LOCAL_INDEX
;
966 sprintf (buf
, IS_ELF
? ".LL%04x" : "LL%04x", ++loccnt
);
967 sb_add_string (&f
->actual
, buf
);
970 src
= sb_skip_comma (src
, in
);
974 else if (in
->ptr
[src
] == '"'
975 || (macro_mri
&& in
->ptr
[src
] == '\''))
978 sb_add_char (out
, in
->ptr
[src
++]);
980 else if (in
->ptr
[src
] == '@' && macro_strip_at
)
984 && in
->ptr
[src
] == '@')
986 sb_add_char (out
, '@');
991 && in
->ptr
[src
] == '='
993 && in
->ptr
[src
+ 1] == '=')
998 src
= get_token (src
+ 2, in
, &t
);
999 ptr
= str_hash_find (formal_hash
, sb_terminate (&t
));
1002 /* FIXME: We should really return a warning string here,
1003 but we can't, because the == might be in the MRI
1004 comment field, and, since the nature of the MRI
1005 comment field depends upon the exact instruction
1006 being used, we don't have enough information here to
1007 figure out whether it is or not. Instead, we leave
1008 the == in place, which should cause a syntax error if
1009 it is not in a comment. */
1010 sb_add_char (out
, '=');
1011 sb_add_char (out
, '=');
1012 sb_add_sb (out
, &t
);
1016 if (ptr
->actual
.len
)
1018 sb_add_string (out
, "-1");
1022 sb_add_char (out
, '0');
1028 if (in
->ptr
[src
] == '\n')
1030 sb_add_char (out
, in
->ptr
[src
++]);
1036 while (loclist
!= NULL
)
1042 name
= sb_terminate (&loclist
->name
);
1043 str_hash_delete (formal_hash
, name
);
1044 del_formal (loclist
);
1048 if (!err
&& (out
->len
== 0 || out
->ptr
[out
->len
- 1] != '\n'))
1049 sb_add_char (out
, '\n');
1053 /* Assign values to the formal parameters of a macro, and expand the
1057 macro_expand (size_t idx
, sb
*in
, macro_entry
*m
, sb
*out
)
1064 const char *err
= NULL
;
1068 /* Reset any old value the actuals may have. */
1069 for (f
= m
->formals
; f
; f
= f
->next
)
1070 sb_reset (&f
->actual
);
1072 while (f
!= NULL
&& f
->index
< 0)
1077 /* The macro may be called with an optional qualifier, which may
1078 be referred to in the macro body as \0. */
1079 if (idx
< in
->len
&& in
->ptr
[idx
] == '.')
1081 /* The Microtec assembler ignores this if followed by a white space.
1082 (Macro invocation with empty extension) */
1085 && in
->ptr
[idx
] != ' '
1086 && in
->ptr
[idx
] != '\t')
1088 formal_entry
*n
= new_formal ();
1090 n
->index
= QUAL_INDEX
;
1092 n
->next
= m
->formals
;
1095 idx
= get_any_string (idx
, in
, &n
->actual
);
1100 /* Peel off the actuals and store them away in the hash tables' actuals. */
1101 idx
= sb_skip_white (idx
, in
);
1102 while (idx
< in
->len
)
1106 /* Look and see if it's a positional or keyword arg. */
1108 while (scan
< in
->len
1109 && !ISSEP (in
->ptr
[scan
])
1110 && !(macro_mri
&& in
->ptr
[scan
] == '\'')
1111 && (!macro_alternate
&& in
->ptr
[scan
] != '='))
1113 if (scan
< in
->len
&& !macro_alternate
&& in
->ptr
[scan
] == '=')
1117 /* It's OK to go from positional to keyword. */
1119 /* This is a keyword arg, fetch the formal name and
1120 then the actual stuff. */
1122 idx
= get_token (idx
, in
, &t
);
1123 if (idx
>= in
->len
|| in
->ptr
[idx
] != '=')
1125 err
= _("confusion in formal parameters");
1129 /* Lookup the formal in the macro's list. */
1130 ptr
= str_hash_find (m
->formal_hash
, sb_terminate (&t
));
1133 as_bad (_("Parameter named `%s' does not exist for macro `%s'"),
1137 idx
= get_any_string (idx
+ 1, in
, &t
);
1141 /* Insert this value into the right place. */
1142 if (ptr
->actual
.len
)
1144 as_warn (_("Value for parameter `%s' of macro `%s' was already specified"),
1147 sb_reset (&ptr
->actual
);
1149 idx
= get_any_string (idx
+ 1, in
, &ptr
->actual
);
1150 if (ptr
->actual
.len
> 0)
1158 err
= _("can't mix positional and keyword arguments");
1169 err
= _("too many positional arguments");
1176 for (pf
= &m
->formals
; *pf
!= NULL
; pf
= &(*pf
)->next
)
1177 if ((*pf
)->index
>= c
)
1178 c
= (*pf
)->index
+ 1;
1185 if (f
->type
!= FORMAL_VARARG
)
1186 idx
= get_any_string (idx
, in
, &f
->actual
);
1187 else if (idx
< in
->len
)
1189 sb_add_buffer (&f
->actual
, in
->ptr
+ idx
, in
->len
- idx
);
1192 if (f
->actual
.len
> 0)
1198 while (f
!= NULL
&& f
->index
< 0);
1202 idx
= sb_skip_comma (idx
, in
);
1205 if (idx
< in
->len
&& in
->ptr
[idx
] == ',')
1207 if (idx
< in
->len
&& ISWHITE (in
->ptr
[idx
]))
1214 for (ptr
= m
->formals
; ptr
; ptr
= ptr
->next
)
1216 if (ptr
->type
== FORMAL_REQUIRED
&& ptr
->actual
.len
== 0)
1217 as_bad (_("Missing value for required parameter `%s' of macro `%s'"),
1224 ptr
= str_hash_find (m
->formal_hash
,
1225 macro_strip_at
? "$NARG" : "NARG");
1229 sprintf (buffer
, "%d", narg
);
1230 sb_add_string (&ptr
->actual
, buffer
);
1234 err
= macro_expand_body (&m
->sub
, out
, m
->formals
, m
->formal_hash
, m
);
1237 /* Discard any unnamed formal arguments. */
1245 if ((*pf
)->name
.len
!= 0)
1263 /* Check for a macro. If one is found, put the expansion into
1264 *EXPAND. Return 1 if a macro is found, 0 otherwise. */
1267 check_macro (const char *line
, sb
*expand
,
1268 const char **error
, macro_entry
**info
)
1275 if (! is_name_beginner (*line
)
1276 && (! macro_mri
|| *line
!= '.'))
1280 while (is_part_of_name (*s
))
1282 if (is_name_ender (*s
))
1285 copy
= xmemdup0 (line
, s
- line
);
1286 for (cls
= copy
; *cls
!= '\0'; cls
++)
1287 *cls
= TOLOWER (*cls
);
1289 macro
= str_hash_find (macro_hash
, copy
);
1295 /* Wrap the line up in an sb. */
1297 while (*s
!= '\0' && *s
!= '\n' && *s
!= '\r')
1298 sb_add_char (&line_sb
, *s
++);
1301 *error
= macro_expand (0, &line_sb
, macro
, expand
);
1305 /* Export the macro information if requested. */
1312 /* Delete a macro. */
1315 delete_macro (const char *name
)
1321 len
= strlen (name
);
1322 copy
= XNEWVEC (char, len
+ 1);
1323 for (i
= 0; i
< len
; ++i
)
1324 copy
[i
] = TOLOWER (name
[i
]);
1327 macro
= str_hash_find (macro_hash
, copy
);
1329 str_hash_delete (macro_hash
, copy
);
1331 as_warn (_("Attempt to purge non-existing macro `%s'"), copy
);
1335 /* Handle the MRI IRP and IRPC pseudo-ops. These are handled as a
1336 combined macro definition and execution. This returns NULL on
1337 success, or an error message otherwise. */
1340 expand_irp (int irpc
, size_t idx
, sb
*in
, sb
*out
, size_t (*get_line
) (sb
*))
1345 const char *err
= NULL
;
1347 idx
= sb_skip_white (idx
, in
);
1350 if (! buffer_and_nest (NULL
, "ENDR", &sub
, get_line
))
1351 return _("unexpected end of file in irp or irpc");
1357 idx
= get_token (idx
, in
, &f
.name
);
1358 if (f
.name
.len
== 0)
1359 return _("missing model parameter");
1361 h
= str_htab_create ();
1363 str_hash_insert (h
, sb_terminate (&f
.name
), &f
, 0);
1367 f
.type
= FORMAL_OPTIONAL
;
1371 idx
= sb_skip_comma (idx
, in
);
1374 /* Expand once with a null string. */
1375 err
= macro_expand_body (&sub
, out
, &f
, h
, 0);
1379 bool in_quotes
= false;
1381 if (irpc
&& in
->ptr
[idx
] == '"')
1387 while (idx
< in
->len
)
1390 idx
= get_any_string (idx
, in
, &f
.actual
);
1393 if (in
->ptr
[idx
] == '"')
1398 in_quotes
= ! in_quotes
;
1400 nxt
= sb_skip_white (idx
+ 1, in
);
1407 sb_reset (&f
.actual
);
1408 sb_add_char (&f
.actual
, in
->ptr
[idx
]);
1412 err
= macro_expand_body (&sub
, out
, &f
, h
, 0);
1416 idx
= sb_skip_comma (idx
, in
);
1417 else if (! in_quotes
)
1418 idx
= sb_skip_white (idx
, in
);
1423 sb_kill (&f
.actual
);