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