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
31 /* The routines in this file handle macro definition and expansion.
32 They are called by both gasp and gas. */
34 /* Structures used to store macros.
36 Each macro knows its name and included text. It gets built with a
37 list of formal arguments, and also keeps a hash table which points
38 into the list to speed up formal search. Each formal knows its
39 name and its default value. Each time the macro is expanded, the
40 formals get the actual values attatched to them. */
42 /* describe the formal arguments to a macro */
44 typedef struct formal_struct
46 struct formal_struct
*next
; /* next formal in list */
47 sb name
; /* name of the formal */
48 sb def
; /* the default value */
49 sb actual
; /* the actual argument (changed on each expansion) */
50 int index
; /* the index of the formal 0..formal_count-1 */
54 /* Other values found in the index field of a formal_entry. */
55 #define QUAL_INDEX (-1)
56 #define NARG_INDEX (-2)
57 #define LOCAL_INDEX (-3)
59 /* describe the macro. */
61 typedef struct macro_struct
63 sb sub
; /* substitution text. */
64 int formal_count
; /* number of formal args. */
65 formal_entry
*formals
; /* pointer to list of formal_structs */
66 struct hash_control
*formal_hash
; /* hash table of formals. */
70 /* Internal functions. */
72 static int get_token
PARAMS ((int, sb
*, sb
*));
73 static int getstring
PARAMS ((int, sb
*, sb
*));
74 static int get_any_string
PARAMS ((int, sb
*, sb
*, int, int));
75 static int do_formals
PARAMS ((macro_entry
*, int, sb
*));
76 static int get_apost_token
PARAMS ((int, sb
*, sb
*, int));
78 PARAMS ((int, sb
*, sb
*, struct hash_control
*, int, sb
*, int));
79 static const char *macro_expand_body
80 PARAMS ((sb
*, sb
*, formal_entry
*, struct hash_control
*, int, int));
81 static const char *macro_expand
PARAMS ((int, sb
*, macro_entry
*, sb
*, int));
83 #define ISWHITE(x) ((x) == ' ' || (x) == '\t')
86 ((x) == ' ' || (x) == '\t' || (x) == ',' || (x) == '"' || (x) == ';' \
87 || (x) == '<' || (x) == '>' || (x) == ')' || (x) == '(')
90 ((x) == 'b' || (x) == 'B' \
91 || (x) == 'q' || (x) == 'Q' \
92 || (x) == 'h' || (x) == 'H' \
93 || (x) == 'd' || (x) == 'D')
95 /* The macro hash table. */
97 static struct hash_control
*macro_hash
;
99 /* Whether any macros have been defined. */
103 /* Whether we are in GASP alternate mode. */
105 static int macro_alternate
;
107 /* Whether we are in MRI mode. */
109 static int macro_mri
;
111 /* Function to use to parse an expression. */
113 static int (*macro_expr
) PARAMS ((const char *, int, sb
*, int *));
115 /* Number of macro expansions that have been done. */
117 static int macro_number
;
119 /* Initialize macro processing. */
122 macro_init (alternate
, mri
, expr
)
125 int (*expr
) PARAMS ((const char *, int, sb
*, int *));
127 macro_hash
= hash_new ();
129 macro_alternate
= alternate
;
134 /* Read input lines till we get to a TO string.
135 Increase nesting depth if we get a FROM string.
136 Put the results into sb at PTR.
137 Add a new input line to an sb using GET_LINE.
138 Return 1 on success, 0 on unexpected EOF. */
141 buffer_and_nest (from
, to
, ptr
, get_line
)
145 int (*get_line
) PARAMS ((sb
*));
147 int from_len
= strlen (from
);
148 int to_len
= strlen (to
);
150 int line_start
= ptr
->len
;
152 int more
= get_line (ptr
);
156 /* Try and find the first pseudo op on the line */
159 if (! macro_alternate
&& ! macro_mri
)
161 /* With normal syntax we can suck what we want till we get
162 to the dot. With the alternate, labels have to start in
163 the first column, since we cant tell what's a label and
166 /* Skip leading whitespace */
167 while (i
< ptr
->len
&& ISWHITE (ptr
->ptr
[i
]))
170 /* Skip over a label */
172 && (isalnum ((unsigned char) ptr
->ptr
[i
])
173 || ptr
->ptr
[i
] == '_'
174 || ptr
->ptr
[i
] == '$'))
179 && ptr
->ptr
[i
] == ':')
183 /* Skip trailing whitespace */
184 while (i
< ptr
->len
&& ISWHITE (ptr
->ptr
[i
]))
187 if (i
< ptr
->len
&& (ptr
->ptr
[i
] == '.'
191 if (ptr
->ptr
[i
] == '.')
193 if (strncasecmp (ptr
->ptr
+ i
, from
, from_len
) == 0)
195 if (strncasecmp (ptr
->ptr
+ i
, to
, to_len
) == 0)
200 /* Reset the string to not include the ending rune */
201 ptr
->len
= line_start
;
207 /* Add a CR to the end and keep running */
208 sb_add_char (ptr
, '\n');
209 line_start
= ptr
->len
;
210 more
= get_line (ptr
);
213 /* Return 1 on success, 0 on unexpected EOF. */
217 /* Pick up a token. */
220 get_token (idx
, in
, name
)
226 && (isalpha ((unsigned char) in
->ptr
[idx
])
227 || in
->ptr
[idx
] == '_'
228 || in
->ptr
[idx
] == '$'))
230 sb_add_char (name
, in
->ptr
[idx
++]);
232 && (isalnum ((unsigned char) in
->ptr
[idx
])
233 || in
->ptr
[idx
] == '_'
234 || in
->ptr
[idx
] == '$'))
236 sb_add_char (name
, in
->ptr
[idx
++]);
239 /* Ignore trailing & */
240 if (macro_alternate
&& idx
< in
->len
&& in
->ptr
[idx
] == '&')
245 /* Pick up a string. */
248 getstring (idx
, in
, acc
)
253 idx
= sb_skip_white (idx
, in
);
256 && (in
->ptr
[idx
] == '"'
257 || in
->ptr
[idx
] == '<'
258 || (in
->ptr
[idx
] == '\'' && macro_alternate
)))
260 if (in
->ptr
[idx
] == '<')
262 if (macro_alternate
|| macro_mri
)
266 while ((in
->ptr
[idx
] != '>' || nest
)
269 if (in
->ptr
[idx
] == '!')
272 sb_add_char (acc
, in
->ptr
[idx
++]);
276 if (in
->ptr
[idx
] == '>')
278 if (in
->ptr
[idx
] == '<')
280 sb_add_char (acc
, in
->ptr
[idx
++]);
290 ("character code in string must be absolute expression",
292 sb_add_char (acc
, code
);
295 if (in
->ptr
[idx
] != '>')
296 ERROR ((stderr
, "Missing > for character code.\n"));
301 else if (in
->ptr
[idx
] == '"' || in
->ptr
[idx
] == '\'')
303 char tchar
= in
->ptr
[idx
];
305 while (idx
< in
->len
)
307 if (macro_alternate
&& in
->ptr
[idx
] == '!')
310 sb_add_char (acc
, in
->ptr
[idx
++]);
314 if (in
->ptr
[idx
] == tchar
)
317 if (idx
>= in
->len
|| in
->ptr
[idx
] != tchar
)
320 sb_add_char (acc
, in
->ptr
[idx
]);
330 /* Fetch string from the input stream,
332 'Bxyx<whitespace> -> return 'Bxyza
333 %<char> -> return string of decimal value of x
334 "<string>" -> return string
335 xyx<whitespace> -> return xyz
339 get_any_string (idx
, in
, out
, expand
, pretend_quoted
)
347 idx
= sb_skip_white (idx
, in
);
351 if (in
->len
> 2 && in
->ptr
[idx
+1] == '\'' && ISBASE (in
->ptr
[idx
]))
353 while (!ISSEP (in
->ptr
[idx
]))
354 sb_add_char (out
, in
->ptr
[idx
++]);
356 else if (in
->ptr
[idx
] == '%'
362 /* Turns the next expression into a string */
363 idx
= (*macro_expr
) ("% operator needs absolute expression",
367 sprintf(buf
, "%d", val
);
368 sb_add_string (out
, buf
);
370 else if (in
->ptr
[idx
] == '"'
371 || in
->ptr
[idx
] == '<'
372 || (macro_alternate
&& in
->ptr
[idx
] == '\''))
374 if (macro_alternate
&& expand
)
376 /* Keep the quotes */
377 sb_add_char (out
, '\"');
379 idx
= getstring (idx
, in
, out
);
380 sb_add_char (out
, '\"');
384 idx
= getstring (idx
, in
, out
);
390 && (in
->ptr
[idx
] == '"'
391 || in
->ptr
[idx
] == '\''
393 || (in
->ptr
[idx
] != ' '
394 && in
->ptr
[idx
] != '\t'
395 && in
->ptr
[idx
] != ','
396 && in
->ptr
[idx
] != '<')))
398 if (in
->ptr
[idx
] == '"'
399 || in
->ptr
[idx
] == '\'')
401 char tchar
= in
->ptr
[idx
];
402 sb_add_char (out
, in
->ptr
[idx
++]);
404 && in
->ptr
[idx
] != tchar
)
405 sb_add_char (out
, in
->ptr
[idx
++]);
409 sb_add_char (out
, in
->ptr
[idx
++]);
417 /* Pick up the formal parameters of a macro definition. */
420 do_formals (macro
, idx
, in
)
425 formal_entry
**p
= ¯o
->formals
;
427 macro
->formal_count
= 0;
428 macro
->formal_hash
= hash_new ();
429 while (idx
< in
->len
)
431 formal_entry
*formal
;
433 formal
= (formal_entry
*) xmalloc (sizeof (formal_entry
));
435 sb_new (&formal
->name
);
436 sb_new (&formal
->def
);
437 sb_new (&formal
->actual
);
439 idx
= sb_skip_white (idx
, in
);
440 idx
= get_token (idx
, in
, &formal
->name
);
441 if (formal
->name
.len
== 0)
443 idx
= sb_skip_white (idx
, in
);
444 if (formal
->name
.len
)
446 /* This is a formal */
447 if (idx
< in
->len
&& in
->ptr
[idx
] == '=')
450 idx
= get_any_string (idx
+ 1, in
, &formal
->def
, 1, 0);
454 /* Add to macro's hash table */
455 hash_jam (macro
->formal_hash
, sb_terminate (&formal
->name
), formal
);
457 formal
->index
= macro
->formal_count
;
458 idx
= sb_skip_comma (idx
, in
);
459 macro
->formal_count
++;
467 formal_entry
*formal
;
469 /* Add a special NARG formal, which macro_expand will set to the
470 number of arguments. */
471 formal
= (formal_entry
*) xmalloc (sizeof (formal_entry
));
473 sb_new (&formal
->name
);
474 sb_new (&formal
->def
);
475 sb_new (&formal
->actual
);
477 sb_add_string (&formal
->name
, "NARG");
479 /* Add to macro's hash table */
480 hash_jam (macro
->formal_hash
, "NARG", formal
);
482 formal
->index
= NARG_INDEX
;
490 /* Define a new macro. Returns NULL on success, otherwise returns an
494 define_macro (idx
, in
, label
, get_line
)
498 int (*get_line
) PARAMS ((sb
*));
503 macro
= (macro_entry
*) xmalloc (sizeof (macro_entry
));
504 sb_new (¯o
->sub
);
507 macro
->formal_count
= 0;
510 idx
= sb_skip_white (idx
, in
);
511 if (! buffer_and_nest ("MACRO", "ENDM", ¯o
->sub
, get_line
))
512 return "unexpected end of file in macro definition";
513 if (label
!= NULL
&& label
->len
!= 0)
515 sb_add_sb (&name
, label
);
516 if (in
->ptr
[idx
] == '(')
518 /* It's the label: MACRO (formals,...) sort */
519 idx
= do_formals (macro
, idx
+ 1, in
);
520 if (in
->ptr
[idx
] != ')')
521 return "missing ) after formals";
525 /* It's the label: MACRO formals,... sort */
526 idx
= do_formals (macro
, idx
, in
);
531 idx
= get_token (idx
, in
, &name
);
532 idx
= sb_skip_white (idx
, in
);
533 idx
= do_formals (macro
, idx
, in
);
536 /* and stick it in the macro hash table */
537 for (idx
= 0; idx
< name
.len
; idx
++)
538 if (isupper (name
.ptr
[idx
]))
539 name
.ptr
[idx
] = tolower (name
.ptr
[idx
]);
540 hash_jam (macro_hash
, sb_terminate (&name
), (PTR
) macro
);
547 /* Scan a token, and then skip KIND. */
550 get_apost_token (idx
, in
, name
, kind
)
556 idx
= get_token (idx
, in
, name
);
557 if (idx
< in
->len
&& in
->ptr
[idx
] == kind
&& ! macro_mri
)
562 /* Substitute the actual value for a formal parameter. */
565 sub_actual (src
, in
, t
, formal_hash
, kind
, out
, copyifnotthere
)
569 struct hash_control
*formal_hash
;
576 src
= get_apost_token (src
, in
, t
, kind
);
577 /* See if it's in the macro's hash table */
578 ptr
= (formal_entry
*) hash_find (formal_hash
, sb_terminate (t
));
583 sb_add_sb (out
, &ptr
->actual
);
587 sb_add_sb (out
, &ptr
->def
);
590 else if (copyifnotthere
)
596 sb_add_char (out
, '\\');
602 /* Expand the body of a macro. */
605 macro_expand_body (in
, out
, formals
, formal_hash
, comment_char
, locals
)
608 formal_entry
*formals
;
609 struct hash_control
*formal_hash
;
616 formal_entry
*loclist
= NULL
;
620 while (src
< in
->len
)
622 if (in
->ptr
[src
] == '&')
625 if (macro_mri
&& src
+ 1 < in
->len
&& in
->ptr
[src
+ 1] == '&')
627 src
= sub_actual (src
+ 2, in
, &t
, formal_hash
, '\'', out
, 1);
631 src
= sub_actual (src
+ 1, in
, &t
, formal_hash
, '&', out
, 0);
634 else if (in
->ptr
[src
] == '\\')
637 if (in
->ptr
[src
] == comment_char
&& comment_char
!= '\0')
639 /* This is a comment, just drop the rest of the line */
641 && in
->ptr
[src
] != '\n')
644 else if (in
->ptr
[src
] == '(')
646 /* Sub in till the next ')' literally */
648 while (src
< in
->len
&& in
->ptr
[src
] != ')')
650 sb_add_char (out
, in
->ptr
[src
++]);
652 if (in
->ptr
[src
] == ')')
655 return "missplaced )";
657 else if (in
->ptr
[src
] == '@')
659 /* Sub in the macro invocation number */
663 sprintf (buffer
, "%05d", macro_number
);
664 sb_add_string (out
, buffer
);
666 else if (in
->ptr
[src
] == '&')
668 /* This is a preprocessor variable name, we don't do them
670 sb_add_char (out
, '\\');
671 sb_add_char (out
, '&');
675 && isalnum ((unsigned char) in
->ptr
[src
]))
680 if (isdigit ((unsigned char) in
->ptr
[src
]))
681 ind
= in
->ptr
[src
] - '0';
682 else if (isupper ((unsigned char) in
->ptr
[src
]))
683 ind
= in
->ptr
[src
] - 'A' + 10;
685 ind
= in
->ptr
[src
] - 'a' + 10;
687 for (f
= formals
; f
!= NULL
; f
= f
->next
)
689 if (f
->index
== ind
- 1)
691 if (f
->actual
.len
!= 0)
692 sb_add_sb (out
, &f
->actual
);
694 sb_add_sb (out
, &f
->def
);
702 src
= sub_actual (src
, in
, &t
, formal_hash
, '\'', out
, 0);
705 else if ((macro_alternate
|| macro_mri
)
706 && (isalpha ((unsigned char) in
->ptr
[src
])
707 || in
->ptr
[src
] == '_'
708 || in
->ptr
[src
] == '$'))
711 || src
+ 5 >= in
->len
712 || strncasecmp (in
->ptr
+ src
, "LOCAL", 5) != 0
713 || ! ISWHITE (in
->ptr
[src
+ 5]))
716 src
= sub_actual (src
, in
, &t
, formal_hash
, '\'', out
, 1);
722 src
= sb_skip_white (src
+ 5, in
);
723 while (in
->ptr
[src
] != '\n' && in
->ptr
[src
] != comment_char
)
729 f
= (formal_entry
*) xmalloc (sizeof (formal_entry
));
733 f
->index
= LOCAL_INDEX
;
737 src
= get_token (src
, in
, &f
->name
);
739 sprintf (buf
, "LL%04x", loccnt
);
740 sb_add_string (&f
->actual
, buf
);
742 err
= hash_jam (formal_hash
, sb_terminate (&f
->name
), f
);
746 src
= sb_skip_comma (src
, in
);
750 else if (comment_char
!= '\0'
751 && in
->ptr
[src
] == comment_char
753 && in
->ptr
[src
+ 1] == comment_char
756 /* Two comment chars in a row cause the rest of the line to
758 while (src
< in
->len
&& in
->ptr
[src
] != '\n')
761 else if (in
->ptr
[src
] == '"'
762 || (macro_mri
&& in
->ptr
[src
] == '\''))
765 sb_add_char (out
, in
->ptr
[src
++]);
768 && in
->ptr
[src
] == '='
770 && in
->ptr
[src
+ 1] == '=')
775 src
= get_token (src
+ 2, in
, &t
);
776 ptr
= (formal_entry
*) hash_find (formal_hash
, sb_terminate (&t
));
778 return "macro formal argument does not exist";
783 sb_add_string (out
, "-1");
787 sb_add_char (out
, '0');
793 sb_add_char (out
, in
->ptr
[src
++]);
799 while (loclist
!= NULL
)
804 sb_kill (&loclist
->name
);
805 sb_kill (&loclist
->def
);
806 sb_kill (&loclist
->actual
);
814 /* Assign values to the formal parameters of a macro, and expand the
818 macro_expand (idx
, in
, m
, out
, comment_char
)
828 int is_positional
= 0;
835 /* Reset any old value the actuals may have */
836 for (f
= m
->formals
; f
; f
= f
->next
)
837 sb_reset (&f
->actual
);
839 while (f
!= NULL
&& f
->index
< 0)
844 /* The macro may be called with an optional qualifier, which may
845 be referred to in the macro body as \0. */
846 if (idx
< in
->len
&& in
->ptr
[idx
] == '.')
850 n
= (formal_entry
*) xmalloc (sizeof (formal_entry
));
854 n
->index
= QUAL_INDEX
;
856 n
->next
= m
->formals
;
859 idx
= get_any_string (idx
+ 1, in
, &n
->actual
, 1, 0);
863 /* Peel off the actuals and store them away in the hash tables' actuals */
864 idx
= sb_skip_white (idx
, in
);
865 while (idx
< in
->len
&& in
->ptr
[idx
] != comment_char
)
869 /* Look and see if it's a positional or keyword arg */
871 while (scan
< in
->len
872 && !ISSEP (in
->ptr
[scan
])
873 && (!macro_alternate
&& in
->ptr
[scan
] != '='))
875 if (scan
< in
->len
&& !macro_alternate
&& in
->ptr
[scan
] == '=')
879 return "can't mix positional and keyword arguments";
881 /* This is a keyword arg, fetch the formal name and
882 then the actual stuff */
884 idx
= get_token (idx
, in
, &t
);
885 if (in
->ptr
[idx
] != '=')
886 return "confusion in formal parameters";
888 /* Lookup the formal in the macro's list */
889 ptr
= (formal_entry
*) hash_find (m
->formal_hash
, sb_terminate (&t
));
891 return "macro formal argument does not exist";
894 /* Insert this value into the right place */
895 sb_reset (&ptr
->actual
);
896 idx
= get_any_string (idx
+ 1, in
, &ptr
->actual
, 0, 0);
897 if (ptr
->actual
.len
> 0)
903 /* This is a positional arg */
906 return "can't mix positional and keyword arguments";
914 return "too many positional arguments";
916 f
= (formal_entry
*) xmalloc (sizeof (formal_entry
));
923 for (pf
= &m
->formals
; *pf
!= NULL
; pf
= &(*pf
)->next
)
924 if ((*pf
)->index
>= c
)
925 c
= (*pf
)->index
+ 1;
932 sb_reset (&f
->actual
);
933 idx
= get_any_string (idx
, in
, &f
->actual
, 1, 0);
934 if (f
->actual
.len
> 0)
940 while (f
!= NULL
&& f
->index
< 0);
943 idx
= sb_skip_comma (idx
, in
);
951 sb_add_string (&t
, "NARG");
952 ptr
= (formal_entry
*) hash_find (m
->formal_hash
, sb_terminate (&t
));
953 sb_reset (&ptr
->actual
);
954 sprintf (buffer
, "%d", narg
);
955 sb_add_string (&ptr
->actual
, buffer
);
958 err
= macro_expand_body (&m
->sub
, out
, m
->formals
, m
->formal_hash
,
963 /* Discard any unnamed formal arguments. */
971 if ((*pf
)->name
.len
!= 0)
975 sb_kill (&(*pf
)->name
);
976 sb_kill (&(*pf
)->def
);
977 sb_kill (&(*pf
)->actual
);
991 /* Check for a macro. If one is found, put the expansion into
992 *EXPAND. COMMENT_CHAR is the comment character--this is used by
993 gasp. Return 1 if a macro is found, 0 otherwise. */
996 check_macro (line
, expand
, comment_char
, error
)
1007 if (! isalpha ((unsigned char) *line
)
1010 && (! macro_mri
|| *line
!= '.'))
1014 while (isalnum ((unsigned char) *s
)
1019 copy
= (char *) xmalloc (s
- line
+ 1);
1020 memcpy (copy
, line
, s
- line
);
1021 copy
[s
- line
] = '\0';
1022 for (cs
= copy
; *cs
!= '\0'; cs
++)
1024 *cs
= tolower (*cs
);
1026 macro
= (macro_entry
*) hash_find (macro_hash
, copy
);
1031 /* Wrap the line up in an sb. */
1033 while (*s
!= '\0' && *s
!= '\n' && *s
!= '\r')
1034 sb_add_char (&line_sb
, *s
++);
1037 *error
= macro_expand (0, &line_sb
, macro
, expand
, comment_char
);
1044 /* Handle the MRI IRP and IRPC pseudo-ops. These are handled as a
1045 combined macro definition and execution. This returns NULL on
1046 success, or an error message otherwise. */
1049 expand_irp (irpc
, idx
, in
, out
, get_line
, comment_char
)
1054 int (*get_line
) PARAMS ((sb
*));
1060 struct hash_control
*h
;
1068 idx
= sb_skip_white (idx
, in
);
1071 if (! buffer_and_nest (mn
, "ENDR", &sub
, get_line
))
1072 return "unexpected end of file in irp or irpc";
1078 idx
= get_token (idx
, in
, &f
.name
);
1079 if (f
.name
.len
== 0)
1080 return "missing model parameter";
1083 err
= hash_jam (h
, sb_terminate (&f
.name
), &f
);
1092 idx
= sb_skip_comma (idx
, in
);
1093 if (idx
>= in
->len
|| in
->ptr
[idx
] == comment_char
)
1095 /* Expand once with a null string. */
1096 err
= macro_expand_body (&sub
, out
, &f
, h
, comment_char
, 0);
1102 while (idx
< in
->len
&& in
->ptr
[idx
] != comment_char
)
1105 idx
= get_any_string (idx
, in
, &f
.actual
, 1, 0);
1108 sb_reset (&f
.actual
);
1109 sb_add_char (&f
.actual
, in
->ptr
[idx
]);
1112 err
= macro_expand_body (&sub
, out
, &f
, h
, comment_char
, 0);
1116 idx
= sb_skip_comma (idx
, in
);
1118 idx
= sb_skip_white (idx
, in
);
This page took 0.067503 seconds and 5 git commands to generate.