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 || ((flag_macro_alternate || flag_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 should strip '@' characters. */
55 #define macro_strip_at false
57 /* Number of macro expansions that have been done. */
59 static int macro_number
;
61 static void free_macro (macro_entry
*);
64 macro_del_f (void *ent
)
66 string_tuple_t
*tuple
= ent
;
67 free_macro ((macro_entry
*) tuple
->value
);
70 /* Initialize macro processing. */
75 macro_hash
= htab_create_alloc (16, hash_string_tuple
, eq_string_tuple
,
76 macro_del_f
, notes_calloc
, NULL
);
83 htab_delete (macro_hash
);
86 /* Read input lines till we get to a TO string.
87 Increase nesting depth if we get a FROM string.
88 Put the results into sb at PTR.
89 FROM may be NULL (or will be ignored) if TO is "ENDR".
90 Add a new input line to an sb using GET_LINE.
91 Return 1 on success, 0 on unexpected EOF. */
94 buffer_and_nest (const char *from
, const char *to
, sb
*ptr
,
95 size_t (*get_line
) (sb
*))
98 size_t to_len
= strlen (to
);
100 size_t line_start
, more
;
102 if (to_len
== 4 && strcasecmp (to
, "ENDR") == 0)
108 from_len
= strlen (from
);
110 /* Record the present source position, such that diagnostics and debug info
111 can be properly associated with the respective original lines, rather
112 than with the line of the ending directive (TO). */
117 as_where_top (&line
);
119 linefile
= xasprintf ("\t.linefile %u .", line
+ 1);
121 linefile
= xasprintf ("\tlinefile %u .", line
+ 1);
122 sb_add_string (ptr
, linefile
);
126 line_start
= ptr
->len
;
127 more
= get_line (ptr
);
130 /* Try to find the first pseudo op on the line. */
131 size_t i
= line_start
;
132 bool had_colon
= false;
134 /* With normal syntax we can suck what we want till we get
135 to the dot. With the alternate, labels have to start in
136 the first column, since we can't tell what's a label and
137 what's a pseudoop. */
139 if (! LABELS_WITHOUT_COLONS
)
141 /* Skip leading whitespace. */
142 while (i
< ptr
->len
&& ISWHITE (ptr
->ptr
[i
]))
148 /* Skip over a label, if any. */
149 if (i
>= ptr
->len
|| ! is_name_beginner (ptr
->ptr
[i
]))
152 while (i
< ptr
->len
&& is_part_of_name (ptr
->ptr
[i
]))
154 if (i
< ptr
->len
&& is_name_ender (ptr
->ptr
[i
]))
156 /* Skip whitespace. */
157 while (i
< ptr
->len
&& ISWHITE (ptr
->ptr
[i
]))
159 /* Check for the colon. */
160 if (i
>= ptr
->len
|| ptr
->ptr
[i
] != ':')
162 /* LABELS_WITHOUT_COLONS doesn't mean we cannot have a
163 colon after a label. If we do have a colon on the
164 first label then handle more than one label on the
165 line, assuming that each label has a colon. */
166 if (LABELS_WITHOUT_COLONS
&& !had_colon
)
176 /* Skip trailing whitespace. */
177 while (i
< ptr
->len
&& ISWHITE (ptr
->ptr
[i
]))
180 if (i
< ptr
->len
&& (ptr
->ptr
[i
] == '.'
184 if (! flag_m68k_mri
&& ptr
->ptr
[i
] == '.')
186 size_t len
= ptr
->len
- i
;
189 if (len
>= 5 && strncasecmp (ptr
->ptr
+ i
, "IREPC", 5) == 0)
191 else if (len
>= 4 && strncasecmp (ptr
->ptr
+ i
, "IREP", 4) == 0)
193 else if (len
>= 4 && strncasecmp (ptr
->ptr
+ i
, "IRPC", 4) == 0)
195 else if (len
>= 4 && strncasecmp (ptr
->ptr
+ i
, "REPT", 4) == 0)
197 else if (len
>= 3 && strncasecmp (ptr
->ptr
+ i
, "IRP", 3) == 0)
199 else if (len
>= 3 && strncasecmp (ptr
->ptr
+ i
, "REP", 3) == 0)
206 && strncasecmp (ptr
->ptr
+ i
, from
, from_len
) == 0)
209 || ! (is_part_of_name (ptr
->ptr
[i
+ from_len
])
210 || is_name_ender (ptr
->ptr
[i
+ from_len
]))))
213 && strncasecmp (ptr
->ptr
+ i
, to
, to_len
) == 0
215 || ! (is_part_of_name (ptr
->ptr
[i
+ to_len
])
216 || is_name_ender (ptr
->ptr
[i
+ to_len
]))))
221 /* Reset the string to not include the ending rune. */
222 ptr
->len
= line_start
;
228 Apply .linefile directives that appear within the macro, alongside
229 keeping them for later expansion of the macro. */
230 if (from
!= NULL
&& strcasecmp (from
, "MACRO") == 0
231 && len
>= 8 && strncasecmp (ptr
->ptr
+ i
, "linefile", 8) == 0)
233 sb_add_char (ptr
, more
);
234 temp_ilp (sb_terminate (ptr
) + i
+ 8);
237 line_start
= ptr
->len
;
238 more
= get_line (ptr
);
243 /* Add the original end-of-line char to the end and keep running. */
244 sb_add_char (ptr
, more
);
245 line_start
= ptr
->len
;
246 more
= get_line (ptr
);
249 /* Return 1 on success, 0 on unexpected EOF. */
253 /* Pick up a token. */
256 get_token (size_t idx
, sb
*in
, sb
*name
)
259 && is_name_beginner (in
->ptr
[idx
]))
261 sb_add_char (name
, in
->ptr
[idx
++]);
263 && is_part_of_name (in
->ptr
[idx
]))
265 sb_add_char (name
, in
->ptr
[idx
++]);
268 && is_name_ender (in
->ptr
[idx
]))
270 sb_add_char (name
, in
->ptr
[idx
++]);
273 /* Ignore trailing &. */
274 if (flag_macro_alternate
&& idx
< in
->len
&& in
->ptr
[idx
] == '&')
279 /* Pick up a string. */
282 getstring (size_t idx
, sb
*in
, sb
*acc
)
285 && (in
->ptr
[idx
] == '"'
286 || (in
->ptr
[idx
] == '<' && (flag_macro_alternate
|| flag_mri
))
287 || (in
->ptr
[idx
] == '\'' && flag_macro_alternate
)))
289 if (in
->ptr
[idx
] == '<')
294 && (in
->ptr
[idx
] != '>' || nest
))
296 if (in
->ptr
[idx
] == '!')
299 sb_add_char (acc
, in
->ptr
[idx
++]);
303 if (in
->ptr
[idx
] == '>')
305 if (in
->ptr
[idx
] == '<')
307 sb_add_char (acc
, in
->ptr
[idx
++]);
312 else if (in
->ptr
[idx
] == '"' || in
->ptr
[idx
] == '\'')
314 char tchar
= in
->ptr
[idx
];
319 while (idx
< in
->len
)
321 if (in
->ptr
[idx
- 1] == '\\')
326 if (flag_macro_alternate
&& in
->ptr
[idx
] == '!')
330 sb_add_char (acc
, in
->ptr
[idx
]);
334 else if (escaped
&& in
->ptr
[idx
] == tchar
)
336 sb_add_char (acc
, tchar
);
341 if (in
->ptr
[idx
] == tchar
)
345 if (idx
>= in
->len
|| in
->ptr
[idx
] != tchar
)
349 sb_add_char (acc
, in
->ptr
[idx
]);
359 /* Fetch string from the input stream,
361 'Bxyx<whitespace> -> return 'Bxyza
362 %<expr> -> return string of decimal value of <expr>
363 "string" -> return string
364 (string) -> return (string-including-whitespaces)
365 xyx<whitespace> -> return xyz. */
368 get_any_string (size_t idx
, sb
*in
, sb
*out
)
371 idx
= sb_skip_white (idx
, in
);
375 if (in
->len
> idx
+ 2 && in
->ptr
[idx
+ 1] == '\'' && ISBASE (in
->ptr
[idx
]))
377 while (idx
< in
->len
&& !ISSEP (in
->ptr
[idx
]))
378 sb_add_char (out
, in
->ptr
[idx
++]);
380 else if (in
->ptr
[idx
] == '%' && flag_macro_alternate
)
382 /* Turn the following expression into a string. */
388 temp_ilp (in
->ptr
+ idx
+ 1);
389 expression_and_evaluate (&ex
);
390 idx
= input_line_pointer
- in
->ptr
;
393 if (ex
.X_op
!= O_constant
)
394 as_bad (_("%% operator needs absolute expression"));
396 sprintf (buf
, "%" PRId64
, (int64_t) ex
.X_add_number
);
397 sb_add_string (out
, buf
);
399 else if (in
->ptr
[idx
] == '"'
400 || (in
->ptr
[idx
] == '<' && (flag_macro_alternate
|| flag_mri
))
401 || (flag_macro_alternate
&& in
->ptr
[idx
] == '\''))
403 if (flag_macro_alternate
&& ! macro_strip_at
&& in
->ptr
[idx
] != '<')
405 /* Keep the quotes. */
406 sb_add_char (out
, '"');
407 idx
= getstring (idx
, in
, out
);
408 sb_add_char (out
, '"');
412 idx
= getstring (idx
, in
, out
);
417 char *br_buf
= XNEWVEC (char, 1);
418 char *in_br
= br_buf
;
423 || (in
->ptr
[idx
] != ' '
424 && in
->ptr
[idx
] != '\t'))
425 && in
->ptr
[idx
] != ','
426 && (in
->ptr
[idx
] != '<'
427 || (! flag_macro_alternate
&& ! flag_mri
)))
429 char tchar
= in
->ptr
[idx
];
435 sb_add_char (out
, in
->ptr
[idx
++]);
437 && in
->ptr
[idx
] != tchar
)
438 sb_add_char (out
, in
->ptr
[idx
++]);
451 br_buf
= XNEWVEC (char, strlen (in_br
) + 2);
452 strcpy (br_buf
+ 1, in_br
);
467 sb_add_char (out
, tchar
);
477 /* Allocate a new formal. */
479 static formal_entry
*
482 formal_entry
*formal
;
484 formal
= XNEW (formal_entry
);
486 sb_new (&formal
->name
);
487 sb_new (&formal
->def
);
488 sb_new (&formal
->actual
);
490 formal
->type
= FORMAL_OPTIONAL
;
497 del_formal (formal_entry
*formal
)
499 sb_kill (&formal
->actual
);
500 sb_kill (&formal
->def
);
501 sb_kill (&formal
->name
);
505 /* Pick up the formal parameters of a macro definition. */
508 do_formals (macro_entry
*macro
, size_t idx
, sb
*in
)
510 formal_entry
**p
= ¯o
->formals
;
513 idx
= sb_skip_white (idx
, in
);
514 while (idx
< in
->len
)
516 formal_entry
*formal
= new_formal ();
519 idx
= get_token (idx
, in
, &formal
->name
);
520 if (formal
->name
.len
== 0)
522 if (macro
->formal_count
)
524 del_formal (formal
); /* 'formal' goes out of scope. */
527 idx
= sb_skip_white (idx
, in
);
528 /* This is a formal. */
529 name
= sb_terminate (&formal
->name
);
532 && in
->ptr
[idx
] == ':'
533 && (! is_name_beginner (':')
534 || idx
+ 1 >= in
->len
535 || ! is_part_of_name (in
->ptr
[idx
+ 1])))
537 /* Got a qualifier. */
541 idx
= get_token (sb_skip_white (idx
+ 1, in
), in
, &qual
);
542 sb_terminate (&qual
);
544 as_bad_where (macro
->file
,
546 _("Missing parameter qualifier for `%s' in macro `%s'"),
549 else if (strcmp (qual
.ptr
, "req") == 0)
550 formal
->type
= FORMAL_REQUIRED
;
551 else if (strcmp (qual
.ptr
, "vararg") == 0)
552 formal
->type
= FORMAL_VARARG
;
554 as_bad_where (macro
->file
,
556 _("`%s' is not a valid parameter qualifier for `%s' in macro `%s'"),
561 idx
= sb_skip_white (idx
, in
);
563 if (idx
< in
->len
&& in
->ptr
[idx
] == '=')
566 idx
= get_any_string (idx
+ 1, in
, &formal
->def
);
567 idx
= sb_skip_white (idx
, in
);
568 if (formal
->type
== FORMAL_REQUIRED
)
570 sb_reset (&formal
->def
);
571 as_warn_where (macro
->file
,
573 _("Pointless default value for required parameter `%s' in macro `%s'"),
579 /* Add to macro's hash table. */
580 if (str_hash_insert (macro
->formal_hash
, name
, formal
, 0) != NULL
)
582 as_bad_where (macro
->file
, macro
->line
,
583 _("A parameter named `%s' "
584 "already exists for macro `%s'"),
588 formal
->index
= macro
->formal_count
++;
591 if (formal
->type
== FORMAL_VARARG
)
594 idx
= sb_skip_comma (idx
, in
);
595 if (idx
!= cidx
&& idx
>= in
->len
)
604 formal_entry
*formal
= new_formal ();
606 /* Add a special NARG formal, which macro_expand will set to the
607 number of arguments. */
608 /* The same MRI assemblers which treat '@' characters also use
609 the name $NARG. At least until we find an exception. */
615 sb_add_string (&formal
->name
, name
);
617 /* Add to macro's hash table. */
618 if (str_hash_insert (macro
->formal_hash
, name
, formal
, 0) != NULL
)
620 as_bad_where (macro
->file
, macro
->line
,
621 _("Reserved word `%s' used as parameter in macro `%s'"),
625 formal
->index
= NARG_INDEX
;
632 /* Free the memory allocated to a macro. */
635 free_macro (macro_entry
*macro
)
637 formal_entry
*formal
;
639 for (formal
= macro
->formals
; formal
; )
644 formal
= formal
->next
;
647 htab_delete (macro
->formal_hash
);
648 sb_kill (¯o
->sub
);
649 free ((char *) macro
->name
);
653 /* Define a new macro. */
656 define_macro (sb
*in
, sb
*label
, size_t (*get_line
) (sb
*))
661 const char *error
= NULL
;
663 macro
= XNEW (macro_entry
);
664 sb_new (¯o
->sub
);
666 macro
->file
= as_where (¯o
->line
);
668 macro
->formal_count
= 0;
670 macro
->formal_hash
= str_htab_create ();
672 idx
= sb_skip_white (0, in
);
673 if (! buffer_and_nest ("MACRO", "ENDM", ¯o
->sub
, get_line
))
674 error
= _("unexpected end of file in macro `%s' definition");
675 if (label
!= NULL
&& label
->len
!= 0)
677 sb_add_sb (&name
, label
);
678 macro
->name
= sb_terminate (&name
);
679 if (idx
< in
->len
&& in
->ptr
[idx
] == '(')
681 /* It's the label: MACRO (formals,...) sort */
682 idx
= do_formals (macro
, idx
+ 1, in
);
683 if (idx
< in
->len
&& in
->ptr
[idx
] == ')')
684 idx
= sb_skip_white (idx
+ 1, in
);
686 error
= _("missing `)' after formals in macro definition `%s'");
690 /* It's the label: MACRO formals,... sort */
691 idx
= do_formals (macro
, idx
, in
);
698 idx
= get_token (idx
, in
, &name
);
699 macro
->name
= sb_terminate (&name
);
701 error
= _("Missing macro name");
702 cidx
= sb_skip_white (idx
, in
);
703 idx
= sb_skip_comma (cidx
, in
);
704 if (idx
== cidx
|| idx
< in
->len
)
705 idx
= do_formals (macro
, idx
, in
);
709 if (!error
&& idx
< in
->len
)
710 error
= _("Bad parameter list for macro `%s'");
712 /* And stick it in the macro hash table. */
713 for (idx
= 0; idx
< name
.len
; idx
++)
714 name
.ptr
[idx
] = TOLOWER (name
.ptr
[idx
]);
717 if (str_hash_insert (macro_hash
, macro
->name
, macro
, 0) != NULL
)
718 error
= _("Macro `%s' was already defined");
725 as_bad_where (macro
->file
, macro
->line
, error
, macro
->name
);
733 /* Scan a token, and then skip KIND. */
736 get_apost_token (size_t idx
, sb
*in
, sb
*name
, int kind
)
738 idx
= get_token (idx
, in
, name
);
740 && in
->ptr
[idx
] == kind
741 && (! flag_mri
|| macro_strip_at
)
742 && (! macro_strip_at
|| kind
== '@'))
747 /* Substitute the actual value for a formal parameter. */
750 sub_actual (size_t start
, sb
*in
, sb
*t
, struct htab
*formal_hash
,
751 int kind
, sb
*out
, int copyifnotthere
)
756 src
= get_apost_token (start
, in
, t
, kind
);
757 /* See if it's in the macro's hash table, unless this is
758 macro_strip_at and kind is '@' and the token did not end in '@'. */
761 && (src
== start
|| in
->ptr
[src
- 1] != '@'))
764 ptr
= str_hash_find (formal_hash
, sb_terminate (t
));
769 sb_add_sb (out
, &ptr
->actual
);
773 sb_add_sb (out
, &ptr
->def
);
776 else if (kind
== '&')
778 /* Doing this permits people to use & in macro bodies. */
779 sb_add_char (out
, '&');
781 if (src
!= start
&& in
->ptr
[src
- 1] == '&')
782 sb_add_char (out
, '&');
784 else if (copyifnotthere
)
790 sb_add_char (out
, '\\');
796 /* Expand the body of a macro. */
799 macro_expand_body (sb
*in
, sb
*out
, formal_entry
*formals
,
800 struct htab
*formal_hash
, const macro_entry
*macro
)
804 int inquote
= 0, macro_line
= 0;
805 formal_entry
*loclist
= NULL
;
806 const char *err
= NULL
;
810 while (src
< in
->len
&& !err
)
812 if (in
->ptr
[src
] == '&')
817 if (src
+ 1 < in
->len
&& in
->ptr
[src
+ 1] == '&')
818 src
= sub_actual (src
+ 2, in
, &t
, formal_hash
, '\'', out
, 1);
820 sb_add_char (out
, in
->ptr
[src
++]);
824 /* Permit macro parameter substitution delineated with
825 an '&' prefix and optional '&' suffix. */
826 src
= sub_actual (src
+ 1, in
, &t
, formal_hash
, '&', out
, 0);
829 else if (in
->ptr
[src
] == '\\')
832 if (src
< in
->len
&& in
->ptr
[src
] == '(')
834 /* Sub in till the next ')' literally. */
836 while (src
< in
->len
&& in
->ptr
[src
] != ')')
838 sb_add_char (out
, in
->ptr
[src
++]);
843 err
= _("missing `)'");
845 as_bad_where (macro
->file
, macro
->line
+ macro_line
, _("missing `)'"));
847 else if (src
< in
->len
&& in
->ptr
[src
] == '@')
849 /* Sub in the macro invocation number. */
853 sprintf (buffer
, "%d", macro_number
);
854 sb_add_string (out
, buffer
);
856 else if (src
< in
->len
&& in
->ptr
[src
] == '&')
858 /* This is a preprocessor variable name, we don't do them
860 sb_add_char (out
, '\\');
861 sb_add_char (out
, '&');
864 else if (flag_mri
&& src
< in
->len
&& ISALNUM (in
->ptr
[src
]))
869 if (ISDIGIT (in
->ptr
[src
]))
870 ind
= in
->ptr
[src
] - '0';
871 else if (ISUPPER (in
->ptr
[src
]))
872 ind
= in
->ptr
[src
] - 'A' + 10;
874 ind
= in
->ptr
[src
] - 'a' + 10;
876 for (f
= formals
; f
!= NULL
; f
= f
->next
)
878 if (f
->index
== ind
- 1)
880 if (f
->actual
.len
!= 0)
881 sb_add_sb (out
, &f
->actual
);
883 sb_add_sb (out
, &f
->def
);
891 src
= sub_actual (src
, in
, &t
, formal_hash
, '\'', out
, 0);
894 else if ((flag_macro_alternate
|| flag_mri
)
895 && is_name_beginner (in
->ptr
[src
])
898 || (src
> 0 && in
->ptr
[src
- 1] == '@')))
901 || src
+ 5 >= in
->len
902 || strncasecmp (in
->ptr
+ src
, "LOCAL", 5) != 0
903 || ! ISWHITE (in
->ptr
[src
+ 5])
904 /* PR 11507: Skip keyword LOCAL if it is found inside a quoted string. */
908 src
= sub_actual (src
, in
, &t
, formal_hash
,
909 (macro_strip_at
&& inquote
) ? '@' : '\'',
914 src
= sb_skip_white (src
+ 5, in
);
915 while (in
->ptr
[src
] != '\n')
918 formal_entry
*f
= new_formal ();
920 src
= get_token (src
, in
, &f
->name
);
921 name
= sb_terminate (&f
->name
);
922 if (str_hash_insert (formal_hash
, name
, f
, 0) != NULL
)
924 as_bad_where (macro
->file
, macro
->line
+ macro_line
,
925 _("`%s' was already used as parameter "
926 "(or another local) name"), name
);
934 f
->index
= LOCAL_INDEX
;
938 sprintf (buf
, IS_ELF
? ".LL%04x" : "LL%04x", ++loccnt
);
939 sb_add_string (&f
->actual
, buf
);
942 src
= sb_skip_comma (src
, in
);
946 else if (in
->ptr
[src
] == '"'
947 || (flag_mri
&& in
->ptr
[src
] == '\''))
950 sb_add_char (out
, in
->ptr
[src
++]);
952 else if (in
->ptr
[src
] == '@' && macro_strip_at
)
956 && in
->ptr
[src
] == '@')
958 sb_add_char (out
, '@');
963 && in
->ptr
[src
] == '='
965 && in
->ptr
[src
+ 1] == '=')
970 src
= get_token (src
+ 2, in
, &t
);
971 ptr
= str_hash_find (formal_hash
, sb_terminate (&t
));
974 /* FIXME: We should really return a warning string here,
975 but we can't, because the == might be in the MRI
976 comment field, and, since the nature of the MRI
977 comment field depends upon the exact instruction
978 being used, we don't have enough information here to
979 figure out whether it is or not. Instead, we leave
980 the == in place, which should cause a syntax error if
981 it is not in a comment. */
982 sb_add_char (out
, '=');
983 sb_add_char (out
, '=');
990 sb_add_string (out
, "-1");
994 sb_add_char (out
, '0');
1000 if (in
->ptr
[src
] == '\n')
1002 sb_add_char (out
, in
->ptr
[src
++]);
1008 while (loclist
!= NULL
)
1014 name
= sb_terminate (&loclist
->name
);
1015 str_hash_delete (formal_hash
, name
);
1016 del_formal (loclist
);
1020 if (!err
&& (out
->len
== 0 || out
->ptr
[out
->len
- 1] != '\n'))
1021 sb_add_char (out
, '\n');
1025 /* Assign values to the formal parameters of a macro, and expand the
1029 macro_expand (size_t idx
, sb
*in
, macro_entry
*m
, sb
*out
)
1036 const char *err
= NULL
;
1040 /* Reset any old value the actuals may have. */
1041 for (f
= m
->formals
; f
; f
= f
->next
)
1042 sb_reset (&f
->actual
);
1044 while (f
!= NULL
&& f
->index
< 0)
1049 /* The macro may be called with an optional qualifier, which may
1050 be referred to in the macro body as \0. */
1051 if (idx
< in
->len
&& in
->ptr
[idx
] == '.')
1053 /* The Microtec assembler ignores this if followed by a white space.
1054 (Macro invocation with empty extension) */
1057 && in
->ptr
[idx
] != ' '
1058 && in
->ptr
[idx
] != '\t')
1060 formal_entry
*n
= new_formal ();
1062 n
->index
= QUAL_INDEX
;
1064 n
->next
= m
->formals
;
1067 idx
= get_any_string (idx
, in
, &n
->actual
);
1072 /* Peel off the actuals and store them away in the hash tables' actuals. */
1073 idx
= sb_skip_white (idx
, in
);
1074 while (idx
< in
->len
)
1078 /* Look and see if it's a positional or keyword arg. */
1080 while (scan
< in
->len
1081 && !ISSEP (in
->ptr
[scan
])
1082 && !(flag_mri
&& in
->ptr
[scan
] == '\'')
1083 && (!flag_macro_alternate
&& in
->ptr
[scan
] != '='))
1085 if (scan
< in
->len
&& !flag_macro_alternate
&& in
->ptr
[scan
] == '=')
1089 /* It's OK to go from positional to keyword. */
1091 /* This is a keyword arg, fetch the formal name and
1092 then the actual stuff. */
1094 idx
= get_token (idx
, in
, &t
);
1095 if (idx
>= in
->len
|| in
->ptr
[idx
] != '=')
1097 err
= _("confusion in formal parameters");
1101 /* Lookup the formal in the macro's list. */
1102 ptr
= str_hash_find (m
->formal_hash
, sb_terminate (&t
));
1105 as_bad (_("Parameter named `%s' does not exist for macro `%s'"),
1109 idx
= get_any_string (idx
+ 1, in
, &t
);
1113 /* Insert this value into the right place. */
1114 if (ptr
->actual
.len
)
1116 as_warn (_("Value for parameter `%s' of macro `%s' was already specified"),
1119 sb_reset (&ptr
->actual
);
1121 idx
= get_any_string (idx
+ 1, in
, &ptr
->actual
);
1122 if (ptr
->actual
.len
> 0)
1130 err
= _("can't mix positional and keyword arguments");
1141 err
= _("too many positional arguments");
1148 for (pf
= &m
->formals
; *pf
!= NULL
; pf
= &(*pf
)->next
)
1149 if ((*pf
)->index
>= c
)
1150 c
= (*pf
)->index
+ 1;
1157 if (f
->type
!= FORMAL_VARARG
)
1158 idx
= get_any_string (idx
, in
, &f
->actual
);
1159 else if (idx
< in
->len
)
1161 sb_add_buffer (&f
->actual
, in
->ptr
+ idx
, in
->len
- idx
);
1164 if (f
->actual
.len
> 0)
1170 while (f
!= NULL
&& f
->index
< 0);
1174 idx
= sb_skip_comma (idx
, in
);
1177 if (idx
< in
->len
&& in
->ptr
[idx
] == ',')
1179 if (idx
< in
->len
&& ISWHITE (in
->ptr
[idx
]))
1186 for (ptr
= m
->formals
; ptr
; ptr
= ptr
->next
)
1188 if (ptr
->type
== FORMAL_REQUIRED
&& ptr
->actual
.len
== 0)
1189 as_bad (_("Missing value for required parameter `%s' of macro `%s'"),
1196 ptr
= str_hash_find (m
->formal_hash
,
1197 macro_strip_at
? "$NARG" : "NARG");
1201 sprintf (buffer
, "%d", narg
);
1202 sb_add_string (&ptr
->actual
, buffer
);
1206 err
= macro_expand_body (&m
->sub
, out
, m
->formals
, m
->formal_hash
, m
);
1209 /* Discard any unnamed formal arguments. */
1217 if ((*pf
)->name
.len
!= 0)
1235 /* Check for a macro. If one is found, put the expansion into
1236 *EXPAND. Return 1 if a macro is found, 0 otherwise. */
1239 check_macro (const char *line
, sb
*expand
,
1240 const char **error
, macro_entry
**info
)
1247 if (! is_name_beginner (*line
)
1248 && (! flag_mri
|| *line
!= '.'))
1252 while (is_part_of_name (*s
))
1254 if (is_name_ender (*s
))
1257 copy
= xmemdup0 (line
, s
- line
);
1258 for (cls
= copy
; *cls
!= '\0'; cls
++)
1259 *cls
= TOLOWER (*cls
);
1261 macro
= str_hash_find (macro_hash
, copy
);
1267 /* Wrap the line up in an sb. */
1269 while (*s
!= '\0' && *s
!= '\n' && *s
!= '\r')
1270 sb_add_char (&line_sb
, *s
++);
1273 *error
= macro_expand (0, &line_sb
, macro
, expand
);
1277 /* Export the macro information if requested. */
1284 /* Delete a macro. */
1287 delete_macro (const char *name
)
1293 len
= strlen (name
);
1294 copy
= XNEWVEC (char, len
+ 1);
1295 for (i
= 0; i
< len
; ++i
)
1296 copy
[i
] = TOLOWER (name
[i
]);
1299 macro
= str_hash_find (macro_hash
, copy
);
1301 str_hash_delete (macro_hash
, copy
);
1303 as_warn (_("Attempt to purge non-existing macro `%s'"), copy
);
1307 /* Handle the MRI IRP and IRPC pseudo-ops. These are handled as a
1308 combined macro definition and execution. This returns NULL on
1309 success, or an error message otherwise. */
1312 expand_irp (int irpc
, size_t idx
, sb
*in
, sb
*out
, size_t (*get_line
) (sb
*))
1317 const char *err
= NULL
;
1319 idx
= sb_skip_white (idx
, in
);
1322 if (! buffer_and_nest (NULL
, "ENDR", &sub
, get_line
))
1324 err
= _("unexpected end of file in irp or irpc");
1332 idx
= get_token (idx
, in
, &f
.name
);
1333 if (f
.name
.len
== 0)
1335 err
= _("missing model parameter");
1339 h
= str_htab_create ();
1341 str_hash_insert (h
, sb_terminate (&f
.name
), &f
, 0);
1345 f
.type
= FORMAL_OPTIONAL
;
1349 idx
= sb_skip_comma (idx
, in
);
1352 /* Expand once with a null string. */
1353 err
= macro_expand_body (&sub
, out
, &f
, h
, 0);
1357 bool in_quotes
= false;
1359 if (irpc
&& in
->ptr
[idx
] == '"')
1365 while (idx
< in
->len
)
1368 idx
= get_any_string (idx
, in
, &f
.actual
);
1371 if (in
->ptr
[idx
] == '"')
1376 in_quotes
= ! in_quotes
;
1378 nxt
= sb_skip_white (idx
+ 1, in
);
1385 sb_reset (&f
.actual
);
1386 sb_add_char (&f
.actual
, in
->ptr
[idx
]);
1390 err
= macro_expand_body (&sub
, out
, &f
, h
, 0);
1394 idx
= sb_skip_comma (idx
, in
);
1395 else if (! in_quotes
)
1396 idx
= sb_skip_white (idx
, in
);
1402 sb_kill (&f
.actual
);