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