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