]> git.ipfire.org Git - thirdparty/binutils-gdb.git/blob - gas/macro.c
gas/
[thirdparty/binutils-gdb.git] / gas / macro.c
1 /* macro.c - macro support for gas
2 Copyright 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004
3 Free Software Foundation, Inc.
4
5 Written by Steve and Judy Chamberlain of Cygnus Support,
6 sac@cygnus.com
7
8 This file is part of GAS, the GNU Assembler.
9
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)
13 any later version.
14
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.
19
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
23 02111-1307, USA. */
24
25 #include "config.h"
26
27 #ifndef __GNUC__
28 # if HAVE_ALLOCA_H
29 # include <alloca.h>
30 # else
31 # ifdef _AIX
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
34 thing in the file. */
35 #pragma alloca
36 # else
37 # ifndef alloca /* predefined by HP cc +Olibcalls */
38 # if !defined (__STDC__) && !defined (__hpux)
39 extern char *alloca ();
40 # else
41 extern void *alloca ();
42 # endif /* __STDC__, __hpux */
43 # endif /* alloca */
44 # endif /* _AIX */
45 # endif /* HAVE_ALLOCA_H */
46 #endif /* __GNUC__ */
47
48 #include <stdio.h>
49 #ifdef HAVE_STRING_H
50 #include <string.h>
51 #else
52 #include <strings.h>
53 #endif
54 #ifdef HAVE_STDLIB_H
55 #include <stdlib.h>
56 #endif
57 #include "as.h"
58 #include "libiberty.h"
59 #include "safe-ctype.h"
60 #include "sb.h"
61 #include "hash.h"
62 #include "macro.h"
63
64 #include "asintl.h"
65
66 /* The routines in this file handle macro definition and expansion.
67 They are called by gas. */
68
69 /* Internal functions. */
70
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 *);
80
81 #define ISWHITE(x) ((x) == ' ' || (x) == '\t')
82
83 #define ISSEP(x) \
84 ((x) == ' ' || (x) == '\t' || (x) == ',' || (x) == '"' || (x) == ';' \
85 || (x) == ')' || (x) == '(' \
86 || ((macro_alternate || macro_mri) && ((x) == '<' || (x) == '>')))
87
88 #define ISBASE(x) \
89 ((x) == 'b' || (x) == 'B' \
90 || (x) == 'q' || (x) == 'Q' \
91 || (x) == 'h' || (x) == 'H' \
92 || (x) == 'd' || (x) == 'D')
93
94 /* The macro hash table. */
95
96 struct hash_control *macro_hash;
97
98 /* Whether any macros have been defined. */
99
100 int macro_defined;
101
102 /* Whether we are in alternate syntax mode. */
103
104 static int macro_alternate;
105
106 /* Whether we are in MRI mode. */
107
108 static int macro_mri;
109
110 /* Whether we should strip '@' characters. */
111
112 static int macro_strip_at;
113
114 /* Function to use to parse an expression. */
115
116 static int (*macro_expr) (const char *, int, sb *, int *);
117
118 /* Number of macro expansions that have been done. */
119
120 static int macro_number;
121
122 /* Initialize macro processing. */
123
124 void
125 macro_init (int alternate, int mri, int strip_at,
126 int (*expr) (const char *, int, sb *, int *))
127 {
128 macro_hash = hash_new ();
129 macro_defined = 0;
130 macro_alternate = alternate;
131 macro_mri = mri;
132 macro_strip_at = strip_at;
133 macro_expr = expr;
134 }
135
136 /* Switch in and out of alternate mode on the fly. */
137
138 void
139 macro_set_alternate (int alternate)
140 {
141 macro_alternate = alternate;
142 }
143
144 /* Switch in and out of MRI mode on the fly. */
145
146 void
147 macro_mri_mode (int mri)
148 {
149 macro_mri = mri;
150 }
151
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. */
158
159 int
160 buffer_and_nest (const char *from, const char *to, sb *ptr,
161 int (*get_line) (sb *))
162 {
163 int from_len;
164 int to_len = strlen (to);
165 int depth = 1;
166 int line_start = ptr->len;
167
168 int more = get_line (ptr);
169
170 if (to_len == 4 && strcasecmp(to, "ENDR") == 0)
171 {
172 from = NULL;
173 from_len = 0;
174 }
175 else
176 from_len = strlen (from);
177
178 while (more)
179 {
180 /* Try and find the first pseudo op on the line. */
181 int i = line_start;
182
183 if (! NO_PSEUDO_DOT && ! flag_m68k_mri)
184 {
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
188 whats a pseudoop. */
189
190 /* Skip leading whitespace. */
191 while (i < ptr->len && ISWHITE (ptr->ptr[i]))
192 i++;
193
194 /* Skip over a label. */
195 while (i < ptr->len
196 && (ISALNUM (ptr->ptr[i])
197 || ptr->ptr[i] == '_'
198 || ptr->ptr[i] == '$'))
199 i++;
200
201 /* And a colon. */
202 if (i < ptr->len
203 && ptr->ptr[i] == ':')
204 i++;
205
206 }
207 /* Skip trailing whitespace. */
208 while (i < ptr->len && ISWHITE (ptr->ptr[i]))
209 i++;
210
211 if (i < ptr->len && (ptr->ptr[i] == '.'
212 || NO_PSEUDO_DOT
213 || macro_mri))
214 {
215 if (! flag_m68k_mri && ptr->ptr[i] == '.')
216 i++;
217 if (from == NULL
218 && strncasecmp (ptr->ptr + i, "IRPC", from_len = 4) != 0
219 && strncasecmp (ptr->ptr + i, "IRP", from_len = 3) != 0
220 && strncasecmp (ptr->ptr + i, "IREPC", from_len = 5) != 0
221 && strncasecmp (ptr->ptr + i, "IREP", from_len = 4) != 0
222 && strncasecmp (ptr->ptr + i, "REPT", from_len = 4) != 0
223 && strncasecmp (ptr->ptr + i, "REP", from_len = 3) != 0)
224 from_len = 0;
225 if ((from != NULL
226 ? strncasecmp (ptr->ptr + i, from, from_len) == 0
227 : from_len > 0)
228 && (ptr->len == (i + from_len)
229 || ! ISALNUM (ptr->ptr[i + from_len])))
230 depth++;
231 if (strncasecmp (ptr->ptr + i, to, to_len) == 0
232 && (ptr->len == (i + to_len)
233 || ! ISALNUM (ptr->ptr[i + to_len])))
234 {
235 depth--;
236 if (depth == 0)
237 {
238 /* Reset the string to not include the ending rune. */
239 ptr->len = line_start;
240 break;
241 }
242 }
243 }
244
245 /* Add the original end-of-line char to the end and keep running. */
246 sb_add_char (ptr, more);
247 line_start = ptr->len;
248 more = get_line (ptr);
249 }
250
251 /* Return 1 on success, 0 on unexpected EOF. */
252 return depth == 0;
253 }
254
255 /* Pick up a token. */
256
257 static int
258 get_token (int idx, sb *in, sb *name)
259 {
260 if (idx < in->len
261 && (ISALPHA (in->ptr[idx])
262 || in->ptr[idx] == '_'
263 || in->ptr[idx] == '$'))
264 {
265 sb_add_char (name, in->ptr[idx++]);
266 while (idx < in->len
267 && (ISALNUM (in->ptr[idx])
268 || in->ptr[idx] == '_'
269 || in->ptr[idx] == '$'))
270 {
271 sb_add_char (name, in->ptr[idx++]);
272 }
273 }
274 /* Ignore trailing &. */
275 if (macro_alternate && idx < in->len && in->ptr[idx] == '&')
276 idx++;
277 return idx;
278 }
279
280 /* Pick up a string. */
281
282 static int
283 getstring (int idx, sb *in, sb *acc)
284 {
285 idx = sb_skip_white (idx, in);
286
287 while (idx < in->len
288 && (in->ptr[idx] == '"'
289 || (in->ptr[idx] == '<' && (macro_alternate || macro_mri))
290 || (in->ptr[idx] == '\'' && macro_alternate)))
291 {
292 if (in->ptr[idx] == '<')
293 {
294 int nest = 0;
295 idx++;
296 while ((in->ptr[idx] != '>' || nest)
297 && idx < in->len)
298 {
299 if (in->ptr[idx] == '!')
300 {
301 idx++;
302 sb_add_char (acc, in->ptr[idx++]);
303 }
304 else
305 {
306 if (in->ptr[idx] == '>')
307 nest--;
308 if (in->ptr[idx] == '<')
309 nest++;
310 sb_add_char (acc, in->ptr[idx++]);
311 }
312 }
313 idx++;
314 }
315 else if (in->ptr[idx] == '"' || in->ptr[idx] == '\'')
316 {
317 char tchar = in->ptr[idx];
318 int escaped = 0;
319
320 idx++;
321
322 while (idx < in->len)
323 {
324 if (in->ptr[idx - 1] == '\\')
325 escaped ^= 1;
326 else
327 escaped = 0;
328
329 if (macro_alternate && in->ptr[idx] == '!')
330 {
331 idx ++;
332
333 sb_add_char (acc, in->ptr[idx]);
334
335 idx ++;
336 }
337 else if (escaped && in->ptr[idx] == tchar)
338 {
339 sb_add_char (acc, tchar);
340 idx ++;
341 }
342 else
343 {
344 if (in->ptr[idx] == tchar)
345 {
346 idx ++;
347
348 if (idx >= in->len || in->ptr[idx] != tchar)
349 break;
350 }
351
352 sb_add_char (acc, in->ptr[idx]);
353 idx ++;
354 }
355 }
356 }
357 }
358
359 return idx;
360 }
361
362 /* Fetch string from the input stream,
363 rules:
364 'Bxyx<whitespace> -> return 'Bxyza
365 %<char> -> return string of decimal value of x
366 "<string>" -> return string
367 xyx<whitespace> -> return xyz
368 */
369
370 static int
371 get_any_string (int idx, sb *in, sb *out, int expand, int pretend_quoted)
372 {
373 sb_reset (out);
374 idx = sb_skip_white (idx, in);
375
376 if (idx < in->len)
377 {
378 if (in->len > idx + 2 && in->ptr[idx + 1] == '\'' && ISBASE (in->ptr[idx]))
379 {
380 while (!ISSEP (in->ptr[idx]))
381 sb_add_char (out, in->ptr[idx++]);
382 }
383 else if (in->ptr[idx] == '%'
384 && macro_alternate
385 && expand)
386 {
387 int val;
388 char buf[20];
389 /* Turns the next expression into a string. */
390 /* xgettext: no-c-format */
391 idx = (*macro_expr) (_("% operator needs absolute expression"),
392 idx + 1,
393 in,
394 &val);
395 sprintf (buf, "%d", val);
396 sb_add_string (out, buf);
397 }
398 else if (in->ptr[idx] == '"'
399 || (in->ptr[idx] == '<' && (macro_alternate || macro_mri))
400 || (macro_alternate && in->ptr[idx] == '\''))
401 {
402 if (macro_alternate
403 && ! macro_strip_at
404 && expand)
405 {
406 /* Keep the quotes. */
407 sb_add_char (out, '\"');
408
409 idx = getstring (idx, in, out);
410 sb_add_char (out, '\"');
411 }
412 else
413 {
414 idx = getstring (idx, in, out);
415 }
416 }
417 else
418 {
419 while (idx < in->len
420 && (in->ptr[idx] == '"'
421 || in->ptr[idx] == '\''
422 || pretend_quoted
423 || (in->ptr[idx] != ' '
424 && in->ptr[idx] != '\t'
425 && in->ptr[idx] != ','
426 && (in->ptr[idx] != '<'
427 || (! macro_alternate && ! macro_mri)))))
428 {
429 if (in->ptr[idx] == '"'
430 || in->ptr[idx] == '\'')
431 {
432 char tchar = in->ptr[idx];
433 sb_add_char (out, in->ptr[idx++]);
434 while (idx < in->len
435 && in->ptr[idx] != tchar)
436 sb_add_char (out, in->ptr[idx++]);
437 if (idx == in->len)
438 return idx;
439 }
440 sb_add_char (out, in->ptr[idx++]);
441 }
442 }
443 }
444
445 return idx;
446 }
447
448 /* Pick up the formal parameters of a macro definition. */
449
450 static int
451 do_formals (macro_entry *macro, int idx, sb *in)
452 {
453 formal_entry **p = &macro->formals;
454
455 macro->formal_count = 0;
456 macro->formal_hash = hash_new ();
457 idx = sb_skip_white (idx, in);
458 while (idx < in->len)
459 {
460 formal_entry *formal;
461 int cidx;
462
463 formal = (formal_entry *) xmalloc (sizeof (formal_entry));
464
465 sb_new (&formal->name);
466 sb_new (&formal->def);
467 sb_new (&formal->actual);
468
469 idx = get_token (idx, in, &formal->name);
470 if (formal->name.len == 0)
471 {
472 if (macro->formal_count)
473 --idx;
474 break;
475 }
476 idx = sb_skip_white (idx, in);
477 /* This is a formal. */
478 if (idx < in->len && in->ptr[idx] == '=')
479 {
480 /* Got a default. */
481 idx = get_any_string (idx + 1, in, &formal->def, 1, 0);
482 idx = sb_skip_white (idx, in);
483 }
484
485 /* Add to macro's hash table. */
486 hash_jam (macro->formal_hash, sb_terminate (&formal->name), formal);
487
488 formal->index = macro->formal_count++;
489 cidx = idx;
490 idx = sb_skip_comma (idx, in);
491 if (idx != cidx && idx >= in->len)
492 {
493 idx = cidx;
494 break;
495 }
496 *p = formal;
497 p = &formal->next;
498 *p = NULL;
499 }
500
501 if (macro_mri)
502 {
503 formal_entry *formal;
504 const char *name;
505
506 /* Add a special NARG formal, which macro_expand will set to the
507 number of arguments. */
508 formal = (formal_entry *) xmalloc (sizeof (formal_entry));
509
510 sb_new (&formal->name);
511 sb_new (&formal->def);
512 sb_new (&formal->actual);
513
514 /* The same MRI assemblers which treat '@' characters also use
515 the name $NARG. At least until we find an exception. */
516 if (macro_strip_at)
517 name = "$NARG";
518 else
519 name = "NARG";
520
521 sb_add_string (&formal->name, name);
522
523 /* Add to macro's hash table. */
524 hash_jam (macro->formal_hash, name, formal);
525
526 formal->index = NARG_INDEX;
527 *p = formal;
528 formal->next = NULL;
529 }
530
531 return idx;
532 }
533
534 /* Define a new macro. Returns NULL on success, otherwise returns an
535 error message. If NAMEP is not NULL, *NAMEP is set to the name of
536 the macro which was defined. */
537
538 const char *
539 define_macro (int idx, sb *in, sb *label,
540 int (*get_line) (sb *), const char **namep)
541 {
542 macro_entry *macro;
543 sb name;
544 const char *namestr;
545
546 macro = (macro_entry *) xmalloc (sizeof (macro_entry));
547 sb_new (&macro->sub);
548 sb_new (&name);
549
550 macro->formal_count = 0;
551 macro->formals = 0;
552
553 idx = sb_skip_white (idx, in);
554 if (! buffer_and_nest ("MACRO", "ENDM", &macro->sub, get_line))
555 return _("unexpected end of file in macro definition");
556 if (label != NULL && label->len != 0)
557 {
558 sb_add_sb (&name, label);
559 if (idx < in->len && in->ptr[idx] == '(')
560 {
561 /* It's the label: MACRO (formals,...) sort */
562 idx = do_formals (macro, idx + 1, in);
563 if (idx >= in->len || in->ptr[idx] != ')')
564 return _("missing ) after formals");
565 idx = sb_skip_white (idx + 1, in);
566 }
567 else
568 {
569 /* It's the label: MACRO formals,... sort */
570 idx = do_formals (macro, idx, in);
571 }
572 }
573 else
574 {
575 int cidx;
576
577 idx = get_token (idx, in, &name);
578 if (name.len == 0)
579 return _("Missing macro name");
580 cidx = sb_skip_white (idx, in);
581 idx = sb_skip_comma (cidx, in);
582 if (idx == cidx || idx < in->len)
583 idx = do_formals (macro, idx, in);
584 else
585 idx = cidx;
586 }
587 if (idx < in->len)
588 return _("Bad macro parameter list");
589
590 /* And stick it in the macro hash table. */
591 for (idx = 0; idx < name.len; idx++)
592 name.ptr[idx] = TOLOWER (name.ptr[idx]);
593 namestr = sb_terminate (&name);
594 if (hash_find (macro_hash, namestr))
595 return _("Macro with this name was already defined");
596 hash_jam (macro_hash, namestr, (PTR) macro);
597
598 macro_defined = 1;
599
600 if (namep != NULL)
601 *namep = namestr;
602
603 return NULL;
604 }
605
606 /* Scan a token, and then skip KIND. */
607
608 static int
609 get_apost_token (int idx, sb *in, sb *name, int kind)
610 {
611 idx = get_token (idx, in, name);
612 if (idx < in->len
613 && in->ptr[idx] == kind
614 && (! macro_mri || macro_strip_at)
615 && (! macro_strip_at || kind == '@'))
616 idx++;
617 return idx;
618 }
619
620 /* Substitute the actual value for a formal parameter. */
621
622 static int
623 sub_actual (int start, sb *in, sb *t, struct hash_control *formal_hash,
624 int kind, sb *out, int copyifnotthere)
625 {
626 int src;
627 formal_entry *ptr;
628
629 src = get_apost_token (start, in, t, kind);
630 /* See if it's in the macro's hash table, unless this is
631 macro_strip_at and kind is '@' and the token did not end in '@'. */
632 if (macro_strip_at
633 && kind == '@'
634 && (src == start || in->ptr[src - 1] != '@'))
635 ptr = NULL;
636 else
637 ptr = (formal_entry *) hash_find (formal_hash, sb_terminate (t));
638 if (ptr)
639 {
640 if (ptr->actual.len)
641 {
642 sb_add_sb (out, &ptr->actual);
643 }
644 else
645 {
646 sb_add_sb (out, &ptr->def);
647 }
648 }
649 else if (kind == '&')
650 {
651 /* Doing this permits people to use & in macro bodies. */
652 sb_add_char (out, '&');
653 sb_add_sb (out, t);
654 }
655 else if (copyifnotthere)
656 {
657 sb_add_sb (out, t);
658 }
659 else
660 {
661 sb_add_char (out, '\\');
662 sb_add_sb (out, t);
663 }
664 return src;
665 }
666
667 /* Expand the body of a macro. */
668
669 static const char *
670 macro_expand_body (sb *in, sb *out, formal_entry *formals,
671 struct hash_control *formal_hash, int locals)
672 {
673 sb t;
674 int src = 0;
675 int inquote = 0;
676 formal_entry *loclist = NULL;
677
678 sb_new (&t);
679
680 while (src < in->len)
681 {
682 if (in->ptr[src] == '&')
683 {
684 sb_reset (&t);
685 if (macro_mri)
686 {
687 if (src + 1 < in->len && in->ptr[src + 1] == '&')
688 src = sub_actual (src + 2, in, &t, formal_hash, '\'', out, 1);
689 else
690 sb_add_char (out, in->ptr[src++]);
691 }
692 else
693 {
694 /* FIXME: Why do we do this? */
695 src = sub_actual (src + 1, in, &t, formal_hash, '&', out, 0);
696 }
697 }
698 else if (in->ptr[src] == '\\')
699 {
700 src++;
701 if (in->ptr[src] == '(')
702 {
703 /* Sub in till the next ')' literally. */
704 src++;
705 while (src < in->len && in->ptr[src] != ')')
706 {
707 sb_add_char (out, in->ptr[src++]);
708 }
709 if (in->ptr[src] == ')')
710 src++;
711 else
712 return _("missplaced )");
713 }
714 else if (in->ptr[src] == '@')
715 {
716 /* Sub in the macro invocation number. */
717
718 char buffer[10];
719 src++;
720 sprintf (buffer, "%d", macro_number);
721 sb_add_string (out, buffer);
722 }
723 else if (in->ptr[src] == '&')
724 {
725 /* This is a preprocessor variable name, we don't do them
726 here. */
727 sb_add_char (out, '\\');
728 sb_add_char (out, '&');
729 src++;
730 }
731 else if (macro_mri && ISALNUM (in->ptr[src]))
732 {
733 int ind;
734 formal_entry *f;
735
736 if (ISDIGIT (in->ptr[src]))
737 ind = in->ptr[src] - '0';
738 else if (ISUPPER (in->ptr[src]))
739 ind = in->ptr[src] - 'A' + 10;
740 else
741 ind = in->ptr[src] - 'a' + 10;
742 ++src;
743 for (f = formals; f != NULL; f = f->next)
744 {
745 if (f->index == ind - 1)
746 {
747 if (f->actual.len != 0)
748 sb_add_sb (out, &f->actual);
749 else
750 sb_add_sb (out, &f->def);
751 break;
752 }
753 }
754 }
755 else
756 {
757 sb_reset (&t);
758 src = sub_actual (src, in, &t, formal_hash, '\'', out, 0);
759 }
760 }
761 else if ((macro_alternate || macro_mri)
762 && (ISALPHA (in->ptr[src])
763 || in->ptr[src] == '_'
764 || in->ptr[src] == '$')
765 && (! inquote
766 || ! macro_strip_at
767 || (src > 0 && in->ptr[src - 1] == '@')))
768 {
769 if (! locals
770 || src + 5 >= in->len
771 || strncasecmp (in->ptr + src, "LOCAL", 5) != 0
772 || ! ISWHITE (in->ptr[src + 5]))
773 {
774 sb_reset (&t);
775 src = sub_actual (src, in, &t, formal_hash,
776 (macro_strip_at && inquote) ? '@' : '\'',
777 out, 1);
778 }
779 else
780 {
781 formal_entry *f;
782
783 src = sb_skip_white (src + 5, in);
784 while (in->ptr[src] != '\n')
785 {
786 static int loccnt;
787 char buf[20];
788 const char *err;
789
790 f = (formal_entry *) xmalloc (sizeof (formal_entry));
791 sb_new (&f->name);
792 sb_new (&f->def);
793 sb_new (&f->actual);
794 f->index = LOCAL_INDEX;
795 f->next = loclist;
796 loclist = f;
797
798 src = get_token (src, in, &f->name);
799 ++loccnt;
800 sprintf (buf, IS_ELF ? ".LL%04x" : "LL%04x", loccnt);
801 sb_add_string (&f->actual, buf);
802
803 err = hash_jam (formal_hash, sb_terminate (&f->name), f);
804 if (err != NULL)
805 return err;
806
807 src = sb_skip_comma (src, in);
808 }
809 }
810 }
811 else if (in->ptr[src] == '"'
812 || (macro_mri && in->ptr[src] == '\''))
813 {
814 inquote = !inquote;
815 sb_add_char (out, in->ptr[src++]);
816 }
817 else if (in->ptr[src] == '@' && macro_strip_at)
818 {
819 ++src;
820 if (src < in->len
821 && in->ptr[src] == '@')
822 {
823 sb_add_char (out, '@');
824 ++src;
825 }
826 }
827 else if (macro_mri
828 && in->ptr[src] == '='
829 && src + 1 < in->len
830 && in->ptr[src + 1] == '=')
831 {
832 formal_entry *ptr;
833
834 sb_reset (&t);
835 src = get_token (src + 2, in, &t);
836 ptr = (formal_entry *) hash_find (formal_hash, sb_terminate (&t));
837 if (ptr == NULL)
838 {
839 /* FIXME: We should really return a warning string here,
840 but we can't, because the == might be in the MRI
841 comment field, and, since the nature of the MRI
842 comment field depends upon the exact instruction
843 being used, we don't have enough information here to
844 figure out whether it is or not. Instead, we leave
845 the == in place, which should cause a syntax error if
846 it is not in a comment. */
847 sb_add_char (out, '=');
848 sb_add_char (out, '=');
849 sb_add_sb (out, &t);
850 }
851 else
852 {
853 if (ptr->actual.len)
854 {
855 sb_add_string (out, "-1");
856 }
857 else
858 {
859 sb_add_char (out, '0');
860 }
861 }
862 }
863 else
864 {
865 sb_add_char (out, in->ptr[src++]);
866 }
867 }
868
869 sb_kill (&t);
870
871 while (loclist != NULL)
872 {
873 formal_entry *f;
874
875 f = loclist->next;
876 /* Setting the value to NULL effectively deletes the entry. We
877 avoid calling hash_delete because it doesn't reclaim memory. */
878 hash_jam (formal_hash, sb_terminate (&loclist->name), NULL);
879 sb_kill (&loclist->name);
880 sb_kill (&loclist->def);
881 sb_kill (&loclist->actual);
882 free (loclist);
883 loclist = f;
884 }
885
886 return NULL;
887 }
888
889 /* Assign values to the formal parameters of a macro, and expand the
890 body. */
891
892 static const char *
893 macro_expand (int idx, sb *in, macro_entry *m, sb *out)
894 {
895 sb t;
896 formal_entry *ptr;
897 formal_entry *f;
898 int is_positional = 0;
899 int is_keyword = 0;
900 int narg = 0;
901 const char *err;
902
903 sb_new (&t);
904
905 /* Reset any old value the actuals may have. */
906 for (f = m->formals; f; f = f->next)
907 sb_reset (&f->actual);
908 f = m->formals;
909 while (f != NULL && f->index < 0)
910 f = f->next;
911
912 if (macro_mri)
913 {
914 /* The macro may be called with an optional qualifier, which may
915 be referred to in the macro body as \0. */
916 if (idx < in->len && in->ptr[idx] == '.')
917 {
918 /* The Microtec assembler ignores this if followed by a white space.
919 (Macro invocation with empty extension) */
920 idx++;
921 if ( idx < in->len
922 && in->ptr[idx] != ' '
923 && in->ptr[idx] != '\t')
924 {
925 formal_entry *n;
926
927 n = (formal_entry *) xmalloc (sizeof (formal_entry));
928 sb_new (&n->name);
929 sb_new (&n->def);
930 sb_new (&n->actual);
931 n->index = QUAL_INDEX;
932
933 n->next = m->formals;
934 m->formals = n;
935
936 idx = get_any_string (idx, in, &n->actual, 1, 0);
937 }
938 }
939 }
940
941 /* Peel off the actuals and store them away in the hash tables' actuals. */
942 idx = sb_skip_white (idx, in);
943 while (idx < in->len)
944 {
945 int scan;
946
947 /* Look and see if it's a positional or keyword arg. */
948 scan = idx;
949 while (scan < in->len
950 && !ISSEP (in->ptr[scan])
951 && !(macro_mri && in->ptr[scan] == '\'')
952 && (!macro_alternate && in->ptr[scan] != '='))
953 scan++;
954 if (scan < in->len && !macro_alternate && in->ptr[scan] == '=')
955 {
956 is_keyword = 1;
957
958 /* It's OK to go from positional to keyword. */
959
960 /* This is a keyword arg, fetch the formal name and
961 then the actual stuff. */
962 sb_reset (&t);
963 idx = get_token (idx, in, &t);
964 if (in->ptr[idx] != '=')
965 return _("confusion in formal parameters");
966
967 /* Lookup the formal in the macro's list. */
968 ptr = (formal_entry *) hash_find (m->formal_hash, sb_terminate (&t));
969 if (!ptr)
970 return _("macro formal argument does not exist");
971 else
972 {
973 /* Insert this value into the right place. */
974 sb_reset (&ptr->actual);
975 idx = get_any_string (idx + 1, in, &ptr->actual, 0, 0);
976 if (ptr->actual.len > 0)
977 ++narg;
978 }
979 }
980 else
981 {
982 /* This is a positional arg. */
983 is_positional = 1;
984 if (is_keyword)
985 return _("can't mix positional and keyword arguments");
986
987 if (!f)
988 {
989 formal_entry **pf;
990 int c;
991
992 if (!macro_mri)
993 return _("too many positional arguments");
994
995 f = (formal_entry *) xmalloc (sizeof (formal_entry));
996 sb_new (&f->name);
997 sb_new (&f->def);
998 sb_new (&f->actual);
999 f->next = NULL;
1000
1001 c = -1;
1002 for (pf = &m->formals; *pf != NULL; pf = &(*pf)->next)
1003 if ((*pf)->index >= c)
1004 c = (*pf)->index + 1;
1005 if (c == -1)
1006 c = 0;
1007 *pf = f;
1008 f->index = c;
1009 }
1010
1011 sb_reset (&f->actual);
1012 idx = get_any_string (idx, in, &f->actual, 1, 0);
1013 if (f->actual.len > 0)
1014 ++narg;
1015 do
1016 {
1017 f = f->next;
1018 }
1019 while (f != NULL && f->index < 0);
1020 }
1021
1022 if (! macro_mri)
1023 idx = sb_skip_comma (idx, in);
1024 else
1025 {
1026 if (in->ptr[idx] == ',')
1027 ++idx;
1028 if (ISWHITE (in->ptr[idx]))
1029 break;
1030 }
1031 }
1032
1033 if (macro_mri)
1034 {
1035 char buffer[20];
1036
1037 sb_reset (&t);
1038 sb_add_string (&t, macro_strip_at ? "$NARG" : "NARG");
1039 ptr = (formal_entry *) hash_find (m->formal_hash, sb_terminate (&t));
1040 sb_reset (&ptr->actual);
1041 sprintf (buffer, "%d", narg);
1042 sb_add_string (&ptr->actual, buffer);
1043 }
1044
1045 err = macro_expand_body (&m->sub, out, m->formals, m->formal_hash, 1);
1046 if (err != NULL)
1047 return err;
1048
1049 /* Discard any unnamed formal arguments. */
1050 if (macro_mri)
1051 {
1052 formal_entry **pf;
1053
1054 pf = &m->formals;
1055 while (*pf != NULL)
1056 {
1057 if ((*pf)->name.len != 0)
1058 pf = &(*pf)->next;
1059 else
1060 {
1061 sb_kill (&(*pf)->name);
1062 sb_kill (&(*pf)->def);
1063 sb_kill (&(*pf)->actual);
1064 f = (*pf)->next;
1065 free (*pf);
1066 *pf = f;
1067 }
1068 }
1069 }
1070
1071 sb_kill (&t);
1072 macro_number++;
1073
1074 return NULL;
1075 }
1076
1077 /* Check for a macro. If one is found, put the expansion into
1078 *EXPAND. Return 1 if a macro is found, 0 otherwise. */
1079
1080 int
1081 check_macro (const char *line, sb *expand,
1082 const char **error, macro_entry **info)
1083 {
1084 const char *s;
1085 char *copy, *cs;
1086 macro_entry *macro;
1087 sb line_sb;
1088
1089 if (! ISALPHA (*line)
1090 && *line != '_'
1091 && *line != '$'
1092 && (! macro_mri || *line != '.'))
1093 return 0;
1094
1095 s = line + 1;
1096 while (ISALNUM (*s)
1097 || *s == '_'
1098 || *s == '$')
1099 ++s;
1100
1101 copy = (char *) alloca (s - line + 1);
1102 memcpy (copy, line, s - line);
1103 copy[s - line] = '\0';
1104 for (cs = copy; *cs != '\0'; cs++)
1105 *cs = TOLOWER (*cs);
1106
1107 macro = (macro_entry *) hash_find (macro_hash, copy);
1108
1109 if (macro == NULL)
1110 return 0;
1111
1112 /* Wrap the line up in an sb. */
1113 sb_new (&line_sb);
1114 while (*s != '\0' && *s != '\n' && *s != '\r')
1115 sb_add_char (&line_sb, *s++);
1116
1117 sb_new (expand);
1118 *error = macro_expand (0, &line_sb, macro, expand);
1119
1120 sb_kill (&line_sb);
1121
1122 /* Export the macro information if requested. */
1123 if (info)
1124 *info = macro;
1125
1126 return 1;
1127 }
1128
1129 /* Delete a macro. */
1130
1131 void
1132 delete_macro (const char *name)
1133 {
1134 hash_delete (macro_hash, name);
1135 }
1136
1137 /* Handle the MRI IRP and IRPC pseudo-ops. These are handled as a
1138 combined macro definition and execution. This returns NULL on
1139 success, or an error message otherwise. */
1140
1141 const char *
1142 expand_irp (int irpc, int idx, sb *in, sb *out, int (*get_line) (sb *))
1143 {
1144 sb sub;
1145 formal_entry f;
1146 struct hash_control *h;
1147 const char *err;
1148
1149 idx = sb_skip_white (idx, in);
1150
1151 sb_new (&sub);
1152 if (! buffer_and_nest (NULL, "ENDR", &sub, get_line))
1153 return _("unexpected end of file in irp or irpc");
1154
1155 sb_new (&f.name);
1156 sb_new (&f.def);
1157 sb_new (&f.actual);
1158
1159 idx = get_token (idx, in, &f.name);
1160 if (f.name.len == 0)
1161 return _("missing model parameter");
1162
1163 h = hash_new ();
1164 err = hash_jam (h, sb_terminate (&f.name), &f);
1165 if (err != NULL)
1166 return err;
1167
1168 f.index = 1;
1169 f.next = NULL;
1170
1171 sb_reset (out);
1172
1173 idx = sb_skip_comma (idx, in);
1174 if (idx >= in->len)
1175 {
1176 /* Expand once with a null string. */
1177 err = macro_expand_body (&sub, out, &f, h, 0);
1178 if (err != NULL)
1179 return err;
1180 }
1181 else
1182 {
1183 if (irpc && in->ptr[idx] == '"')
1184 ++idx;
1185 while (idx < in->len)
1186 {
1187 if (!irpc)
1188 idx = get_any_string (idx, in, &f.actual, 1, 0);
1189 else
1190 {
1191 if (in->ptr[idx] == '"')
1192 {
1193 int nxt;
1194
1195 nxt = sb_skip_white (idx + 1, in);
1196 if (nxt >= in->len)
1197 {
1198 idx = nxt;
1199 break;
1200 }
1201 }
1202 sb_reset (&f.actual);
1203 sb_add_char (&f.actual, in->ptr[idx]);
1204 ++idx;
1205 }
1206 err = macro_expand_body (&sub, out, &f, h, 0);
1207 if (err != NULL)
1208 return err;
1209 if (!irpc)
1210 idx = sb_skip_comma (idx, in);
1211 else
1212 idx = sb_skip_white (idx, in);
1213 }
1214 }
1215
1216 hash_die (h);
1217 sb_kill (&sub);
1218
1219 return NULL;
1220 }