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