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