1 /* macro.c - macro support for gas and gasp
2 Copyright (C) 1994, 1995 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
30 #include "libiberty.h"
35 /* The routines in this file handle macro definition and expansion.
36 They are called by both gasp and gas. */
38 /* Structures used to store macros.
40 Each macro knows its name and included text. It gets built with a
41 list of formal arguments, and also keeps a hash table which points
42 into the list to speed up formal search. Each formal knows its
43 name and its default value. Each time the macro is expanded, the
44 formals get the actual values attatched to them. */
46 /* describe the formal arguments to a macro */
48 typedef struct formal_struct
50 struct formal_struct
*next
; /* next formal in list */
51 sb name
; /* name of the formal */
52 sb def
; /* the default value */
53 sb actual
; /* the actual argument (changed on each expansion) */
54 int index
; /* the index of the formal 0..formal_count-1 */
58 /* Other values found in the index field of a formal_entry. */
59 #define QUAL_INDEX (-1)
60 #define NARG_INDEX (-2)
61 #define LOCAL_INDEX (-3)
63 /* describe the macro. */
65 typedef struct macro_struct
67 sb sub
; /* substitution text. */
68 int formal_count
; /* number of formal args. */
69 formal_entry
*formals
; /* pointer to list of formal_structs */
70 struct hash_control
*formal_hash
; /* hash table of formals. */
74 /* Internal functions. */
76 static int get_token
PARAMS ((int, sb
*, sb
*));
77 static int getstring
PARAMS ((int, sb
*, sb
*));
78 static int get_any_string
PARAMS ((int, sb
*, sb
*, int, int));
79 static int do_formals
PARAMS ((macro_entry
*, int, sb
*));
80 static int get_apost_token
PARAMS ((int, sb
*, sb
*, int));
82 PARAMS ((int, sb
*, sb
*, struct hash_control
*, int, sb
*, int));
83 static const char *macro_expand_body
84 PARAMS ((sb
*, sb
*, formal_entry
*, struct hash_control
*, int, int));
85 static const char *macro_expand
PARAMS ((int, sb
*, macro_entry
*, sb
*, int));
87 #define ISWHITE(x) ((x) == ' ' || (x) == '\t')
90 ((x) == ' ' || (x) == '\t' || (x) == ',' || (x) == '"' || (x) == ';' \
91 || (x) == '<' || (x) == '>' || (x) == ')' || (x) == '(')
94 ((x) == 'b' || (x) == 'B' \
95 || (x) == 'q' || (x) == 'Q' \
96 || (x) == 'h' || (x) == 'H' \
97 || (x) == 'd' || (x) == 'D')
99 /* The macro hash table. */
101 static struct hash_control
*macro_hash
;
103 /* Whether any macros have been defined. */
107 /* Whether we are in GASP alternate mode. */
109 static int macro_alternate
;
111 /* Whether we are in MRI mode. */
113 static int macro_mri
;
115 /* Function to use to parse an expression. */
117 static int (*macro_expr
) PARAMS ((const char *, int, sb
*, int *));
119 /* Number of macro expansions that have been done. */
121 static int macro_number
;
123 /* Initialize macro processing. */
126 macro_init (alternate
, mri
, expr
)
129 int (*expr
) PARAMS ((const char *, int, sb
*, int *));
131 macro_hash
= hash_new ();
133 macro_alternate
= alternate
;
138 /* Read input lines till we get to a TO string.
139 Increase nesting depth if we get a FROM string.
140 Put the results into sb at PTR.
141 Add a new input line to an sb using GET_LINE.
142 Return 1 on success, 0 on unexpected EOF. */
145 buffer_and_nest (from
, to
, ptr
, get_line
)
149 int (*get_line
) PARAMS ((sb
*));
151 int from_len
= strlen (from
);
152 int to_len
= strlen (to
);
154 int line_start
= ptr
->len
;
156 int more
= get_line (ptr
);
160 /* Try and find the first pseudo op on the line */
163 if (! macro_alternate
&& ! macro_mri
)
165 /* With normal syntax we can suck what we want till we get
166 to the dot. With the alternate, labels have to start in
167 the first column, since we cant tell what's a label and
170 /* Skip leading whitespace */
171 while (i
< ptr
->len
&& ISWHITE (ptr
->ptr
[i
]))
174 /* Skip over a label */
176 && (isalnum ((unsigned char) ptr
->ptr
[i
])
177 || ptr
->ptr
[i
] == '_'
178 || ptr
->ptr
[i
] == '$'))
183 && ptr
->ptr
[i
] == ':')
187 /* Skip trailing whitespace */
188 while (i
< ptr
->len
&& ISWHITE (ptr
->ptr
[i
]))
191 if (i
< ptr
->len
&& (ptr
->ptr
[i
] == '.'
195 if (ptr
->ptr
[i
] == '.')
197 if (strncasecmp (ptr
->ptr
+ i
, from
, from_len
) == 0)
199 if (strncasecmp (ptr
->ptr
+ i
, to
, to_len
) == 0)
204 /* Reset the string to not include the ending rune */
205 ptr
->len
= line_start
;
211 /* Add a CR to the end and keep running */
212 sb_add_char (ptr
, '\n');
213 line_start
= ptr
->len
;
214 more
= get_line (ptr
);
217 /* Return 1 on success, 0 on unexpected EOF. */
221 /* Pick up a token. */
224 get_token (idx
, in
, name
)
230 && (isalpha ((unsigned char) in
->ptr
[idx
])
231 || in
->ptr
[idx
] == '_'
232 || in
->ptr
[idx
] == '$'))
234 sb_add_char (name
, in
->ptr
[idx
++]);
236 && (isalnum ((unsigned char) in
->ptr
[idx
])
237 || in
->ptr
[idx
] == '_'
238 || in
->ptr
[idx
] == '$'))
240 sb_add_char (name
, in
->ptr
[idx
++]);
243 /* Ignore trailing & */
244 if (macro_alternate
&& idx
< in
->len
&& in
->ptr
[idx
] == '&')
249 /* Pick up a string. */
252 getstring (idx
, in
, acc
)
257 idx
= sb_skip_white (idx
, in
);
260 && (in
->ptr
[idx
] == '"'
261 || in
->ptr
[idx
] == '<'
262 || (in
->ptr
[idx
] == '\'' && macro_alternate
)))
264 if (in
->ptr
[idx
] == '<')
266 if (macro_alternate
|| macro_mri
)
270 while ((in
->ptr
[idx
] != '>' || nest
)
273 if (in
->ptr
[idx
] == '!')
276 sb_add_char (acc
, in
->ptr
[idx
++]);
280 if (in
->ptr
[idx
] == '>')
282 if (in
->ptr
[idx
] == '<')
284 sb_add_char (acc
, in
->ptr
[idx
++]);
294 ("character code in string must be absolute expression",
296 sb_add_char (acc
, code
);
299 if (in
->ptr
[idx
] != '>')
300 ERROR ((stderr
, "Missing > for character code.\n"));
305 else if (in
->ptr
[idx
] == '"' || in
->ptr
[idx
] == '\'')
307 char tchar
= in
->ptr
[idx
];
309 while (idx
< in
->len
)
311 if (macro_alternate
&& in
->ptr
[idx
] == '!')
314 sb_add_char (acc
, in
->ptr
[idx
++]);
318 if (in
->ptr
[idx
] == tchar
)
321 if (idx
>= in
->len
|| in
->ptr
[idx
] != tchar
)
324 sb_add_char (acc
, in
->ptr
[idx
]);
334 /* Fetch string from the input stream,
336 'Bxyx<whitespace> -> return 'Bxyza
337 %<char> -> return string of decimal value of x
338 "<string>" -> return string
339 xyx<whitespace> -> return xyz
343 get_any_string (idx
, in
, out
, expand
, pretend_quoted
)
351 idx
= sb_skip_white (idx
, in
);
355 if (in
->len
> 2 && in
->ptr
[idx
+1] == '\'' && ISBASE (in
->ptr
[idx
]))
357 while (!ISSEP (in
->ptr
[idx
]))
358 sb_add_char (out
, in
->ptr
[idx
++]);
360 else if (in
->ptr
[idx
] == '%'
366 /* Turns the next expression into a string */
367 idx
= (*macro_expr
) ("% operator needs absolute expression",
371 sprintf(buf
, "%d", val
);
372 sb_add_string (out
, buf
);
374 else if (in
->ptr
[idx
] == '"'
375 || in
->ptr
[idx
] == '<'
376 || (macro_alternate
&& in
->ptr
[idx
] == '\''))
378 if (macro_alternate
&& expand
)
380 /* Keep the quotes */
381 sb_add_char (out
, '\"');
383 idx
= getstring (idx
, in
, out
);
384 sb_add_char (out
, '\"');
388 idx
= getstring (idx
, in
, out
);
394 && (in
->ptr
[idx
] == '"'
395 || in
->ptr
[idx
] == '\''
397 || (in
->ptr
[idx
] != ' '
398 && in
->ptr
[idx
] != '\t'
399 && in
->ptr
[idx
] != ','
400 && in
->ptr
[idx
] != '<')))
402 if (in
->ptr
[idx
] == '"'
403 || in
->ptr
[idx
] == '\'')
405 char tchar
= in
->ptr
[idx
];
406 sb_add_char (out
, in
->ptr
[idx
++]);
408 && in
->ptr
[idx
] != tchar
)
409 sb_add_char (out
, in
->ptr
[idx
++]);
413 sb_add_char (out
, in
->ptr
[idx
++]);
421 /* Pick up the formal parameters of a macro definition. */
424 do_formals (macro
, idx
, in
)
429 formal_entry
**p
= ¯o
->formals
;
431 macro
->formal_count
= 0;
432 macro
->formal_hash
= hash_new ();
433 while (idx
< in
->len
)
435 formal_entry
*formal
;
437 formal
= (formal_entry
*) xmalloc (sizeof (formal_entry
));
439 sb_new (&formal
->name
);
440 sb_new (&formal
->def
);
441 sb_new (&formal
->actual
);
443 idx
= sb_skip_white (idx
, in
);
444 idx
= get_token (idx
, in
, &formal
->name
);
445 if (formal
->name
.len
== 0)
447 idx
= sb_skip_white (idx
, in
);
448 if (formal
->name
.len
)
450 /* This is a formal */
451 if (idx
< in
->len
&& in
->ptr
[idx
] == '=')
454 idx
= get_any_string (idx
+ 1, in
, &formal
->def
, 1, 0);
458 /* Add to macro's hash table */
459 hash_jam (macro
->formal_hash
, sb_terminate (&formal
->name
), formal
);
461 formal
->index
= macro
->formal_count
;
462 idx
= sb_skip_comma (idx
, in
);
463 macro
->formal_count
++;
471 formal_entry
*formal
;
473 /* Add a special NARG formal, which macro_expand will set to the
474 number of arguments. */
475 formal
= (formal_entry
*) xmalloc (sizeof (formal_entry
));
477 sb_new (&formal
->name
);
478 sb_new (&formal
->def
);
479 sb_new (&formal
->actual
);
481 sb_add_string (&formal
->name
, "NARG");
483 /* Add to macro's hash table */
484 hash_jam (macro
->formal_hash
, "NARG", formal
);
486 formal
->index
= NARG_INDEX
;
494 /* Define a new macro. Returns NULL on success, otherwise returns an
498 define_macro (idx
, in
, label
, get_line
)
502 int (*get_line
) PARAMS ((sb
*));
507 macro
= (macro_entry
*) xmalloc (sizeof (macro_entry
));
508 sb_new (¯o
->sub
);
511 macro
->formal_count
= 0;
514 idx
= sb_skip_white (idx
, in
);
515 if (! buffer_and_nest ("MACRO", "ENDM", ¯o
->sub
, get_line
))
516 return "unexpected end of file in macro definition";
517 if (label
!= NULL
&& label
->len
!= 0)
519 sb_add_sb (&name
, label
);
520 if (in
->ptr
[idx
] == '(')
522 /* It's the label: MACRO (formals,...) sort */
523 idx
= do_formals (macro
, idx
+ 1, in
);
524 if (in
->ptr
[idx
] != ')')
525 return "missing ) after formals";
529 /* It's the label: MACRO formals,... sort */
530 idx
= do_formals (macro
, idx
, in
);
535 idx
= get_token (idx
, in
, &name
);
536 idx
= sb_skip_white (idx
, in
);
537 idx
= do_formals (macro
, idx
, in
);
540 /* and stick it in the macro hash table */
541 for (idx
= 0; idx
< name
.len
; idx
++)
542 if (isupper (name
.ptr
[idx
]))
543 name
.ptr
[idx
] = tolower (name
.ptr
[idx
]);
544 hash_jam (macro_hash
, sb_terminate (&name
), (PTR
) macro
);
551 /* Scan a token, and then skip KIND. */
554 get_apost_token (idx
, in
, name
, kind
)
560 idx
= get_token (idx
, in
, name
);
561 if (idx
< in
->len
&& in
->ptr
[idx
] == kind
&& ! macro_mri
)
566 /* Substitute the actual value for a formal parameter. */
569 sub_actual (src
, in
, t
, formal_hash
, kind
, out
, copyifnotthere
)
573 struct hash_control
*formal_hash
;
580 src
= get_apost_token (src
, in
, t
, kind
);
581 /* See if it's in the macro's hash table */
582 ptr
= (formal_entry
*) hash_find (formal_hash
, sb_terminate (t
));
587 sb_add_sb (out
, &ptr
->actual
);
591 sb_add_sb (out
, &ptr
->def
);
594 else if (copyifnotthere
)
600 sb_add_char (out
, '\\');
606 /* Expand the body of a macro. */
609 macro_expand_body (in
, out
, formals
, formal_hash
, comment_char
, locals
)
612 formal_entry
*formals
;
613 struct hash_control
*formal_hash
;
620 formal_entry
*loclist
= NULL
;
624 while (src
< in
->len
)
626 if (in
->ptr
[src
] == '&')
629 if (macro_mri
&& src
+ 1 < in
->len
&& in
->ptr
[src
+ 1] == '&')
631 src
= sub_actual (src
+ 2, in
, &t
, formal_hash
, '\'', out
, 1);
635 src
= sub_actual (src
+ 1, in
, &t
, formal_hash
, '&', out
, 0);
638 else if (in
->ptr
[src
] == '\\')
641 if (in
->ptr
[src
] == comment_char
&& comment_char
!= '\0')
643 /* This is a comment, just drop the rest of the line */
645 && in
->ptr
[src
] != '\n')
648 else if (in
->ptr
[src
] == '(')
650 /* Sub in till the next ')' literally */
652 while (src
< in
->len
&& in
->ptr
[src
] != ')')
654 sb_add_char (out
, in
->ptr
[src
++]);
656 if (in
->ptr
[src
] == ')')
659 return "missplaced )";
661 else if (in
->ptr
[src
] == '@')
663 /* Sub in the macro invocation number */
667 sprintf (buffer
, "%05d", macro_number
);
668 sb_add_string (out
, buffer
);
670 else if (in
->ptr
[src
] == '&')
672 /* This is a preprocessor variable name, we don't do them
674 sb_add_char (out
, '\\');
675 sb_add_char (out
, '&');
679 && isalnum ((unsigned char) in
->ptr
[src
]))
684 if (isdigit ((unsigned char) in
->ptr
[src
]))
685 ind
= in
->ptr
[src
] - '0';
686 else if (isupper ((unsigned char) in
->ptr
[src
]))
687 ind
= in
->ptr
[src
] - 'A' + 10;
689 ind
= in
->ptr
[src
] - 'a' + 10;
691 for (f
= formals
; f
!= NULL
; f
= f
->next
)
693 if (f
->index
== ind
- 1)
695 if (f
->actual
.len
!= 0)
696 sb_add_sb (out
, &f
->actual
);
698 sb_add_sb (out
, &f
->def
);
706 src
= sub_actual (src
, in
, &t
, formal_hash
, '\'', out
, 0);
709 else if ((macro_alternate
|| macro_mri
)
710 && (isalpha ((unsigned char) in
->ptr
[src
])
711 || in
->ptr
[src
] == '_'
712 || in
->ptr
[src
] == '$'))
715 || src
+ 5 >= in
->len
716 || strncasecmp (in
->ptr
+ src
, "LOCAL", 5) != 0
717 || ! ISWHITE (in
->ptr
[src
+ 5]))
720 src
= sub_actual (src
, in
, &t
, formal_hash
, '\'', out
, 1);
726 src
= sb_skip_white (src
+ 5, in
);
727 while (in
->ptr
[src
] != '\n' && in
->ptr
[src
] != comment_char
)
733 f
= (formal_entry
*) xmalloc (sizeof (formal_entry
));
737 f
->index
= LOCAL_INDEX
;
741 src
= get_token (src
, in
, &f
->name
);
743 sprintf (buf
, "LL%04x", loccnt
);
744 sb_add_string (&f
->actual
, buf
);
746 err
= hash_jam (formal_hash
, sb_terminate (&f
->name
), f
);
750 src
= sb_skip_comma (src
, in
);
754 else if (comment_char
!= '\0'
755 && in
->ptr
[src
] == comment_char
757 && in
->ptr
[src
+ 1] == comment_char
760 /* Two comment chars in a row cause the rest of the line to
762 while (src
< in
->len
&& in
->ptr
[src
] != '\n')
765 else if (in
->ptr
[src
] == '"'
766 || (macro_mri
&& in
->ptr
[src
] == '\''))
769 sb_add_char (out
, in
->ptr
[src
++]);
772 && in
->ptr
[src
] == '='
774 && in
->ptr
[src
+ 1] == '=')
779 src
= get_token (src
+ 2, in
, &t
);
780 ptr
= (formal_entry
*) hash_find (formal_hash
, sb_terminate (&t
));
782 return "macro formal argument does not exist";
787 sb_add_string (out
, "-1");
791 sb_add_char (out
, '0');
797 sb_add_char (out
, in
->ptr
[src
++]);
803 while (loclist
!= NULL
)
808 sb_kill (&loclist
->name
);
809 sb_kill (&loclist
->def
);
810 sb_kill (&loclist
->actual
);
818 /* Assign values to the formal parameters of a macro, and expand the
822 macro_expand (idx
, in
, m
, out
, comment_char
)
832 int is_positional
= 0;
839 /* Reset any old value the actuals may have */
840 for (f
= m
->formals
; f
; f
= f
->next
)
841 sb_reset (&f
->actual
);
843 while (f
!= NULL
&& f
->index
< 0)
848 /* The macro may be called with an optional qualifier, which may
849 be referred to in the macro body as \0. */
850 if (idx
< in
->len
&& in
->ptr
[idx
] == '.')
854 n
= (formal_entry
*) xmalloc (sizeof (formal_entry
));
858 n
->index
= QUAL_INDEX
;
860 n
->next
= m
->formals
;
863 idx
= get_any_string (idx
+ 1, in
, &n
->actual
, 1, 0);
867 /* Peel off the actuals and store them away in the hash tables' actuals */
868 idx
= sb_skip_white (idx
, in
);
869 while (idx
< in
->len
&& in
->ptr
[idx
] != comment_char
)
873 /* Look and see if it's a positional or keyword arg */
875 while (scan
< in
->len
876 && !ISSEP (in
->ptr
[scan
])
877 && (!macro_alternate
&& in
->ptr
[scan
] != '='))
879 if (scan
< in
->len
&& !macro_alternate
&& in
->ptr
[scan
] == '=')
883 return "can't mix positional and keyword arguments";
885 /* This is a keyword arg, fetch the formal name and
886 then the actual stuff */
888 idx
= get_token (idx
, in
, &t
);
889 if (in
->ptr
[idx
] != '=')
890 return "confusion in formal parameters";
892 /* Lookup the formal in the macro's list */
893 ptr
= (formal_entry
*) hash_find (m
->formal_hash
, sb_terminate (&t
));
895 return "macro formal argument does not exist";
898 /* Insert this value into the right place */
899 sb_reset (&ptr
->actual
);
900 idx
= get_any_string (idx
+ 1, in
, &ptr
->actual
, 0, 0);
901 if (ptr
->actual
.len
> 0)
907 /* This is a positional arg */
910 return "can't mix positional and keyword arguments";
918 return "too many positional arguments";
920 f
= (formal_entry
*) xmalloc (sizeof (formal_entry
));
927 for (pf
= &m
->formals
; *pf
!= NULL
; pf
= &(*pf
)->next
)
928 if ((*pf
)->index
>= c
)
929 c
= (*pf
)->index
+ 1;
936 sb_reset (&f
->actual
);
937 idx
= get_any_string (idx
, in
, &f
->actual
, 1, 0);
938 if (f
->actual
.len
> 0)
944 while (f
!= NULL
&& f
->index
< 0);
947 idx
= sb_skip_comma (idx
, in
);
955 sb_add_string (&t
, "NARG");
956 ptr
= (formal_entry
*) hash_find (m
->formal_hash
, sb_terminate (&t
));
957 sb_reset (&ptr
->actual
);
958 sprintf (buffer
, "%d", narg
);
959 sb_add_string (&ptr
->actual
, buffer
);
962 err
= macro_expand_body (&m
->sub
, out
, m
->formals
, m
->formal_hash
,
967 /* Discard any unnamed formal arguments. */
975 if ((*pf
)->name
.len
!= 0)
979 sb_kill (&(*pf
)->name
);
980 sb_kill (&(*pf
)->def
);
981 sb_kill (&(*pf
)->actual
);
995 /* Check for a macro. If one is found, put the expansion into
996 *EXPAND. COMMENT_CHAR is the comment character--this is used by
997 gasp. Return 1 if a macro is found, 0 otherwise. */
1000 check_macro (line
, expand
, comment_char
, error
)
1011 if (! isalpha ((unsigned char) *line
)
1014 && (! macro_mri
|| *line
!= '.'))
1018 while (isalnum ((unsigned char) *s
)
1023 copy
= (char *) xmalloc (s
- line
+ 1);
1024 memcpy (copy
, line
, s
- line
);
1025 copy
[s
- line
] = '\0';
1026 for (cs
= copy
; *cs
!= '\0'; cs
++)
1028 *cs
= tolower (*cs
);
1030 macro
= (macro_entry
*) hash_find (macro_hash
, copy
);
1035 /* Wrap the line up in an sb. */
1037 while (*s
!= '\0' && *s
!= '\n' && *s
!= '\r')
1038 sb_add_char (&line_sb
, *s
++);
1041 *error
= macro_expand (0, &line_sb
, macro
, expand
, comment_char
);
1048 /* Handle the MRI IRP and IRPC pseudo-ops. These are handled as a
1049 combined macro definition and execution. This returns NULL on
1050 success, or an error message otherwise. */
1053 expand_irp (irpc
, idx
, in
, out
, get_line
, comment_char
)
1058 int (*get_line
) PARAMS ((sb
*));
1064 struct hash_control
*h
;
1072 idx
= sb_skip_white (idx
, in
);
1075 if (! buffer_and_nest (mn
, "ENDR", &sub
, get_line
))
1076 return "unexpected end of file in irp or irpc";
1082 idx
= get_token (idx
, in
, &f
.name
);
1083 if (f
.name
.len
== 0)
1084 return "missing model parameter";
1087 err
= hash_jam (h
, sb_terminate (&f
.name
), &f
);
1096 idx
= sb_skip_comma (idx
, in
);
1097 if (idx
>= in
->len
|| in
->ptr
[idx
] == comment_char
)
1099 /* Expand once with a null string. */
1100 err
= macro_expand_body (&sub
, out
, &f
, h
, comment_char
, 0);
1106 while (idx
< in
->len
&& in
->ptr
[idx
] != comment_char
)
1109 idx
= get_any_string (idx
, in
, &f
.actual
, 1, 0);
1112 sb_reset (&f
.actual
);
1113 sb_add_char (&f
.actual
, in
->ptr
[idx
]);
1116 err
= macro_expand_body (&sub
, out
, &f
, h
, comment_char
, 0);
1120 idx
= sb_skip_comma (idx
, in
);
1122 idx
= sb_skip_white (idx
, in
);