* elf32-sparc.c (elf32_sparc_omit_section_dynsym): New function.
[deliverable/binutils-gdb.git] / gas / macro.c
CommitLineData
fea17916 1/* macro.c - macro support for gas
89658e52 2 Copyright 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004
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
89658e52 57#include "as.h"
252b5132 58#include "libiberty.h"
3882b010 59#include "safe-ctype.h"
252b5132
RH
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.
fea17916 67 They are called by gas. */
252b5132 68
252b5132
RH
69/* Internal functions. */
70
254d758c
KH
71static int get_token (int, sb *, sb *);
72static int getstring (int, sb *, sb *);
73static int get_any_string (int, sb *, sb *, int, int);
74static int do_formals (macro_entry *, int, sb *);
75static int get_apost_token (int, sb *, sb *, int);
76static int sub_actual (int, sb *, sb *, struct hash_control *, int, sb *, int);
252b5132 77static const char *macro_expand_body
254d758c
KH
78 (sb *, sb *, formal_entry *, struct hash_control *, int);
79static const char *macro_expand (int, sb *, macro_entry *, sb *);
252b5132
RH
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
1c53c80d 96struct hash_control *macro_hash;
252b5132
RH
97
98/* Whether any macros have been defined. */
99
100int macro_defined;
101
fea17916 102/* Whether we are in alternate syntax mode. */
252b5132
RH
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
254d758c 116static int (*macro_expr) (const char *, int, sb *, int *);
252b5132
RH
117
118/* Number of macro expansions that have been done. */
119
120static int macro_number;
121
122/* Initialize macro processing. */
123
124void
254d758c
KH
125macro_init (int alternate, int mri, int strip_at,
126 int (*expr) (const char *, int, sb *, int *))
252b5132
RH
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
caa32fe5
NC
136/* Switch in and out of alternate mode on the fly. */
137
138void
2766e5e4 139macro_set_alternate (int alternate)
caa32fe5
NC
140{
141 macro_alternate = alternate;
142}
143
252b5132
RH
144/* Switch in and out of MRI mode on the fly. */
145
146void
254d758c 147macro_mri_mode (int mri)
252b5132
RH
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
158int
254d758c
KH
159buffer_and_nest (const char *from, const char *to, sb *ptr,
160 int (*get_line) (sb *))
252b5132
RH
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 {
29f8404c 171 /* Try and find the first pseudo op on the line. */
252b5132
RH
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
29f8404c 179 whats a pseudoop. */
252b5132 180
29f8404c 181 /* Skip leading whitespace. */
252b5132
RH
182 while (i < ptr->len && ISWHITE (ptr->ptr[i]))
183 i++;
184
29f8404c 185 /* Skip over a label. */
252b5132 186 while (i < ptr->len
3882b010 187 && (ISALNUM (ptr->ptr[i])
252b5132
RH
188 || ptr->ptr[i] == '_'
189 || ptr->ptr[i] == '$'))
190 i++;
191
29f8404c 192 /* And a colon. */
252b5132
RH
193 if (i < ptr->len
194 && ptr->ptr[i] == ':')
195 i++;
196
197 }
29f8404c 198 /* Skip trailing whitespace. */
252b5132
RH
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] == '.')
29f8404c 207 i++;
c1eae114 208 if (strncasecmp (ptr->ptr + i, from, from_len) == 0
29f8404c 209 && (ptr->len == (i + from_len)
3882b010 210 || ! ISALNUM (ptr->ptr[i + from_len])))
252b5132 211 depth++;
c1eae114 212 if (strncasecmp (ptr->ptr + i, to, to_len) == 0
29f8404c 213 && (ptr->len == (i + to_len)
3882b010 214 || ! ISALNUM (ptr->ptr[i + to_len])))
252b5132
RH
215 {
216 depth--;
217 if (depth == 0)
218 {
29f8404c 219 /* Reset the string to not include the ending rune. */
252b5132
RH
220 ptr->len = line_start;
221 break;
222 }
223 }
224 }
225
0822d075
NC
226 /* Add the original end-of-line char to the end and keep running. */
227 sb_add_char (ptr, more);
252b5132
RH
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
238static int
254d758c 239get_token (int idx, sb *in, sb *name)
252b5132
RH
240{
241 if (idx < in->len
3882b010 242 && (ISALPHA (in->ptr[idx])
252b5132
RH
243 || in->ptr[idx] == '_'
244 || in->ptr[idx] == '$'))
245 {
246 sb_add_char (name, in->ptr[idx++]);
247 while (idx < in->len
3882b010 248 && (ISALNUM (in->ptr[idx])
252b5132
RH
249 || in->ptr[idx] == '_'
250 || in->ptr[idx] == '$'))
251 {
252 sb_add_char (name, in->ptr[idx++]);
253 }
254 }
29f8404c 255 /* Ignore trailing &. */
252b5132
RH
256 if (macro_alternate && idx < in->len && in->ptr[idx] == '&')
257 idx++;
258 return idx;
259}
260
261/* Pick up a string. */
262
263static int
254d758c 264getstring (int idx, sb *in, sb *acc)
252b5132
RH
265{
266 idx = sb_skip_white (idx, in);
267
268 while (idx < in->len
29f8404c 269 && (in->ptr[idx] == '"'
252b5132
RH
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 {
29f8404c 282 idx++;
252b5132
RH
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];
c06ae4f2 299 int escaped = 0;
29f8404c 300
252b5132 301 idx++;
29f8404c 302
252b5132
RH
303 while (idx < in->len)
304 {
29f8404c 305 if (in->ptr[idx - 1] == '\\')
c06ae4f2
UC
306 escaped ^= 1;
307 else
308 escaped = 0;
309
252b5132
RH
310 if (macro_alternate && in->ptr[idx] == '!')
311 {
e972090a 312 idx ++;
29f8404c 313
1994a7c7
NC
314 sb_add_char (acc, in->ptr[idx]);
315
e972090a 316 idx ++;
252b5132 317 }
c06ae4f2
UC
318 else if (escaped && in->ptr[idx] == tchar)
319 {
320 sb_add_char (acc, tchar);
e972090a 321 idx ++;
c06ae4f2 322 }
252b5132
RH
323 else
324 {
325 if (in->ptr[idx] == tchar)
326 {
e972090a 327 idx ++;
29f8404c 328
252b5132
RH
329 if (idx >= in->len || in->ptr[idx] != tchar)
330 break;
331 }
29f8404c 332
252b5132 333 sb_add_char (acc, in->ptr[idx]);
e972090a 334 idx ++;
252b5132
RH
335 }
336 }
337 }
338 }
29f8404c 339
252b5132
RH
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
351static int
254d758c 352get_any_string (int idx, sb *in, sb *out, int expand, int pretend_quoted)
252b5132
RH
353{
354 sb_reset (out);
355 idx = sb_skip_white (idx, in);
356
357 if (idx < in->len)
358 {
9df59bba 359 if (in->len > idx + 2 && in->ptr[idx + 1] == '\'' && ISBASE (in->ptr[idx]))
252b5132
RH
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];
29f8404c 370 /* Turns the next expression into a string. */
06f030db 371 /* xgettext: no-c-format */
252b5132
RH
372 idx = (*macro_expr) (_("% operator needs absolute expression"),
373 idx + 1,
374 in,
375 &val);
d1a6c242 376 sprintf (buf, "%d", val);
252b5132
RH
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 {
29f8404c
KH
387 /* Keep the quotes. */
388 sb_add_char (out, '\"');
252b5132
RH
389
390 idx = getstring (idx, in, out);
29f8404c 391 sb_add_char (out, '\"');
252b5132
RH
392 }
393 else
394 {
395 idx = getstring (idx, in, out);
396 }
397 }
29f8404c 398 else
252b5132 399 {
29f8404c 400 while (idx < in->len
252b5132
RH
401 && (in->ptr[idx] == '"'
402 || in->ptr[idx] == '\''
29f8404c 403 || pretend_quoted
252b5132
RH
404 || (in->ptr[idx] != ' '
405 && in->ptr[idx] != '\t'
406 && in->ptr[idx] != ','
407 && (in->ptr[idx] != '<'
408 || (! macro_alternate && ! macro_mri)))))
409 {
29f8404c 410 if (in->ptr[idx] == '"'
252b5132
RH
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)
29f8404c 417 sb_add_char (out, in->ptr[idx++]);
252b5132 418 if (idx == in->len)
29f8404c 419 return idx;
252b5132
RH
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
431static int
254d758c 432do_formals (macro_entry *macro, int idx, sb *in)
252b5132
RH
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 {
29f8404c 455 /* This is a formal. */
252b5132
RH
456 if (idx < in->len && in->ptr[idx] == '=')
457 {
29f8404c 458 /* Got a default. */
252b5132
RH
459 idx = get_any_string (idx + 1, in, &formal->def, 1, 0);
460 }
461 }
462
29f8404c 463 /* Add to macro's hash table. */
252b5132
RH
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
29f8404c 496 /* Add to macro's hash table. */
252b5132
RH
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
511const char *
254d758c
KH
512define_macro (int idx, sb *in, sb *label,
513 int (*get_line) (sb *), const char **namep)
252b5132
RH
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 {
29f8404c 534 /* It's the label: MACRO (formals,...) sort */
252b5132
RH
535 idx = do_formals (macro, idx + 1, in);
536 if (in->ptr[idx] != ')')
537 return _("missing ) after formals");
538 }
539 else
540 {
29f8404c 541 /* It's the label: MACRO formals,... sort */
252b5132
RH
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
29f8404c 552 /* And stick it in the macro hash table. */
252b5132 553 for (idx = 0; idx < name.len; idx++)
3882b010 554 name.ptr[idx] = TOLOWER (name.ptr[idx]);
252b5132
RH
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
568static int
254d758c 569get_apost_token (int idx, sb *in, sb *name, int kind)
252b5132
RH
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
582static int
254d758c
KH
583sub_actual (int start, sb *in, sb *t, struct hash_control *formal_hash,
584 int kind, sb *out, int copyifnotthere)
252b5132
RH
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, '&');
c1ed1235 613 sb_add_sb (out, t);
252b5132
RH
614 }
615 else if (copyifnotthere)
616 {
617 sb_add_sb (out, t);
618 }
29f8404c 619 else
252b5132
RH
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
629static const char *
254d758c
KH
630macro_expand_body (sb *in, sb *out, formal_entry *formals,
631 struct hash_control *formal_hash, int locals)
252b5132
RH
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++;
fea17916 661 if (in->ptr[src] == '(')
252b5132 662 {
29f8404c 663 /* Sub in till the next ')' literally. */
252b5132
RH
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 {
29f8404c 676 /* Sub in the macro invocation number. */
252b5132
RH
677
678 char buffer[10];
679 src++;
a2984248 680 sprintf (buffer, "%d", macro_number);
252b5132
RH
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
29f8404c 686 here. */
252b5132
RH
687 sb_add_char (out, '\\');
688 sb_add_char (out, '&');
689 src++;
690 }
3882b010 691 else if (macro_mri && ISALNUM (in->ptr[src]))
252b5132
RH
692 {
693 int ind;
694 formal_entry *f;
695
3882b010 696 if (ISDIGIT (in->ptr[src]))
252b5132 697 ind = in->ptr[src] - '0';
3882b010 698 else if (ISUPPER (in->ptr[src]))
252b5132
RH
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)
3882b010 722 && (ISALPHA (in->ptr[src])
252b5132
RH
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);
fea17916 744 while (in->ptr[src] != '\n')
252b5132
RH
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;
89658e52 760 sprintf (buf, IS_ELF ? ".LL%04x" : "LL%04x", loccnt);
252b5132
RH
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 }
252b5132
RH
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;
1af6dcd2
ILT
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);
252b5132
RH
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
852static const char *
254d758c 853macro_expand (int idx, sb *in, macro_entry *m, sb *out)
252b5132
RH
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);
29f8404c
KH
864
865 /* Reset any old value the actuals may have. */
252b5132 866 for (f = m->formals; f; f = f->next)
29f8404c 867 sb_reset (&f->actual);
252b5132
RH
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] == '.')
d1a6c242
KH
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 }
252b5132 900
29f8404c 901 /* Peel off the actuals and store them away in the hash tables' actuals. */
252b5132 902 idx = sb_skip_white (idx, in);
fea17916 903 while (idx < in->len)
252b5132
RH
904 {
905 int scan;
906
29f8404c 907 /* Look and see if it's a positional or keyword arg. */
252b5132
RH
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
29f8404c 921 then the actual stuff. */
252b5132
RH
922 sb_reset (&t);
923 idx = get_token (idx, in, &t);
924 if (in->ptr[idx] != '=')
925 return _("confusion in formal parameters");
926
29f8404c 927 /* Lookup the formal in the macro's list. */
252b5132
RH
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 {
29f8404c 933 /* Insert this value into the right place. */
252b5132
RH
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 {
29f8404c 942 /* This is a positional arg. */
252b5132
RH
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
fea17916 1005 err = macro_expand_body (&m->sub, out, m->formals, m->formal_hash, 1);
252b5132
RH
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
fea17916 1038 *EXPAND. Return 1 if a macro is found, 0 otherwise. */
252b5132
RH
1039
1040int
254d758c
KH
1041check_macro (const char *line, sb *expand,
1042 const char **error, macro_entry **info)
252b5132
RH
1043{
1044 const char *s;
1045 char *copy, *cs;
1046 macro_entry *macro;
1047 sb line_sb;
1048
3882b010 1049 if (! ISALPHA (*line)
252b5132
RH
1050 && *line != '_'
1051 && *line != '$'
1052 && (! macro_mri || *line != '.'))
1053 return 0;
1054
1055 s = line + 1;
3882b010 1056 while (ISALNUM (*s)
252b5132
RH
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++)
3882b010 1065 *cs = TOLOWER (*cs);
252b5132
RH
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);
fea17916 1078 *error = macro_expand (0, &line_sb, macro, expand);
252b5132
RH
1079
1080 sb_kill (&line_sb);
1081
29f8404c 1082 /* Export the macro information if requested. */
9f10757c
TW
1083 if (info)
1084 *info = macro;
1085
252b5132
RH
1086 return 1;
1087}
1088
1089/* Delete a macro. */
1090
1091void
254d758c 1092delete_macro (const char *name)
252b5132
RH
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
1101const char *
254d758c 1102expand_irp (int irpc, int idx, sb *in, sb *out, int (*get_line) (sb *))
252b5132
RH
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");
29f8404c 1120
252b5132
RH
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);
fea17916 1140 if (idx >= in->len)
252b5132
RH
1141 {
1142 /* Expand once with a null string. */
fea17916 1143 err = macro_expand_body (&sub, out, &f, h, 0);
252b5132
RH
1144 if (err != NULL)
1145 return err;
1146 }
1147 else
1148 {
1149 if (irpc && in->ptr[idx] == '"')
1150 ++idx;
fea17916 1151 while (idx < in->len)
252b5132
RH
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);
fea17916 1162 if (nxt >= in->len)
252b5132
RH
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 }
fea17916 1172 err = macro_expand_body (&sub, out, &f, h, 0);
252b5132
RH
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}
This page took 0.277662 seconds and 4 git commands to generate.