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