]> Git Repo - binutils.git/blame - gas/macro.c
gas/
[binutils.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 [email protected]
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 ();
057f53c1 438 idx = sb_skip_white (idx, in);
252b5132
RH
439 while (idx < in->len)
440 {
441 formal_entry *formal;
057f53c1 442 int cidx;
252b5132
RH
443
444 formal = (formal_entry *) xmalloc (sizeof (formal_entry));
445
446 sb_new (&formal->name);
447 sb_new (&formal->def);
448 sb_new (&formal->actual);
449
252b5132
RH
450 idx = get_token (idx, in, &formal->name);
451 if (formal->name.len == 0)
057f53c1
JB
452 {
453 if (macro->formal_count)
454 --idx;
455 break;
456 }
252b5132 457 idx = sb_skip_white (idx, in);
057f53c1
JB
458 /* This is a formal. */
459 if (idx < in->len && in->ptr[idx] == '=')
252b5132 460 {
057f53c1
JB
461 /* Got a default. */
462 idx = get_any_string (idx + 1, in, &formal->def, 1, 0);
463 idx = sb_skip_white (idx, in);
252b5132
RH
464 }
465
29f8404c 466 /* Add to macro's hash table. */
252b5132
RH
467 hash_jam (macro->formal_hash, sb_terminate (&formal->name), formal);
468
057f53c1
JB
469 formal->index = macro->formal_count++;
470 cidx = idx;
252b5132 471 idx = sb_skip_comma (idx, in);
057f53c1
JB
472 if (idx != cidx && idx >= in->len)
473 {
474 idx = cidx;
475 break;
476 }
252b5132
RH
477 *p = formal;
478 p = &formal->next;
479 *p = NULL;
480 }
481
482 if (macro_mri)
483 {
484 formal_entry *formal;
485 const char *name;
486
487 /* Add a special NARG formal, which macro_expand will set to the
488 number of arguments. */
489 formal = (formal_entry *) xmalloc (sizeof (formal_entry));
490
491 sb_new (&formal->name);
492 sb_new (&formal->def);
493 sb_new (&formal->actual);
494
495 /* The same MRI assemblers which treat '@' characters also use
496 the name $NARG. At least until we find an exception. */
497 if (macro_strip_at)
498 name = "$NARG";
499 else
500 name = "NARG";
501
502 sb_add_string (&formal->name, name);
503
29f8404c 504 /* Add to macro's hash table. */
252b5132
RH
505 hash_jam (macro->formal_hash, name, formal);
506
507 formal->index = NARG_INDEX;
508 *p = formal;
509 formal->next = NULL;
510 }
511
512 return idx;
513}
514
515/* Define a new macro. Returns NULL on success, otherwise returns an
516 error message. If NAMEP is not NULL, *NAMEP is set to the name of
517 the macro which was defined. */
518
519const char *
254d758c
KH
520define_macro (int idx, sb *in, sb *label,
521 int (*get_line) (sb *), const char **namep)
252b5132
RH
522{
523 macro_entry *macro;
524 sb name;
525 const char *namestr;
526
527 macro = (macro_entry *) xmalloc (sizeof (macro_entry));
528 sb_new (&macro->sub);
529 sb_new (&name);
530
531 macro->formal_count = 0;
532 macro->formals = 0;
533
534 idx = sb_skip_white (idx, in);
535 if (! buffer_and_nest ("MACRO", "ENDM", &macro->sub, get_line))
536 return _("unexpected end of file in macro definition");
537 if (label != NULL && label->len != 0)
538 {
539 sb_add_sb (&name, label);
540 if (idx < in->len && in->ptr[idx] == '(')
541 {
29f8404c 542 /* It's the label: MACRO (formals,...) sort */
252b5132 543 idx = do_formals (macro, idx + 1, in);
057f53c1 544 if (idx >= in->len || in->ptr[idx] != ')')
252b5132 545 return _("missing ) after formals");
057f53c1 546 idx = sb_skip_white (idx + 1, in);
252b5132
RH
547 }
548 else
549 {
29f8404c 550 /* It's the label: MACRO formals,... sort */
252b5132
RH
551 idx = do_formals (macro, idx, in);
552 }
553 }
554 else
555 {
057f53c1
JB
556 int cidx;
557
252b5132 558 idx = get_token (idx, in, &name);
057f53c1
JB
559 if (name.len == 0)
560 return _("Missing macro name");
561 cidx = sb_skip_white (idx, in);
562 idx = sb_skip_comma (cidx, in);
563 if (idx == cidx || idx < in->len)
564 idx = do_formals (macro, idx, in);
565 else
566 idx = cidx;
252b5132 567 }
057f53c1
JB
568 if (idx < in->len)
569 return _("Bad macro parameter list");
252b5132 570
29f8404c 571 /* And stick it in the macro hash table. */
252b5132 572 for (idx = 0; idx < name.len; idx++)
3882b010 573 name.ptr[idx] = TOLOWER (name.ptr[idx]);
252b5132 574 namestr = sb_terminate (&name);
057f53c1
JB
575 if (hash_find (macro_hash, namestr))
576 return _("Macro with this name was already defined");
252b5132
RH
577 hash_jam (macro_hash, namestr, (PTR) macro);
578
579 macro_defined = 1;
580
581 if (namep != NULL)
582 *namep = namestr;
583
584 return NULL;
585}
586
587/* Scan a token, and then skip KIND. */
588
589static int
254d758c 590get_apost_token (int idx, sb *in, sb *name, int kind)
252b5132
RH
591{
592 idx = get_token (idx, in, name);
593 if (idx < in->len
594 && in->ptr[idx] == kind
595 && (! macro_mri || macro_strip_at)
596 && (! macro_strip_at || kind == '@'))
597 idx++;
598 return idx;
599}
600
601/* Substitute the actual value for a formal parameter. */
602
603static int
254d758c
KH
604sub_actual (int start, sb *in, sb *t, struct hash_control *formal_hash,
605 int kind, sb *out, int copyifnotthere)
252b5132
RH
606{
607 int src;
608 formal_entry *ptr;
609
610 src = get_apost_token (start, in, t, kind);
611 /* See if it's in the macro's hash table, unless this is
612 macro_strip_at and kind is '@' and the token did not end in '@'. */
613 if (macro_strip_at
614 && kind == '@'
615 && (src == start || in->ptr[src - 1] != '@'))
616 ptr = NULL;
617 else
618 ptr = (formal_entry *) hash_find (formal_hash, sb_terminate (t));
619 if (ptr)
620 {
621 if (ptr->actual.len)
622 {
623 sb_add_sb (out, &ptr->actual);
624 }
625 else
626 {
627 sb_add_sb (out, &ptr->def);
628 }
629 }
630 else if (kind == '&')
631 {
632 /* Doing this permits people to use & in macro bodies. */
633 sb_add_char (out, '&');
c1ed1235 634 sb_add_sb (out, t);
252b5132
RH
635 }
636 else if (copyifnotthere)
637 {
638 sb_add_sb (out, t);
639 }
29f8404c 640 else
252b5132
RH
641 {
642 sb_add_char (out, '\\');
643 sb_add_sb (out, t);
644 }
645 return src;
646}
647
648/* Expand the body of a macro. */
649
650static const char *
254d758c
KH
651macro_expand_body (sb *in, sb *out, formal_entry *formals,
652 struct hash_control *formal_hash, int locals)
252b5132
RH
653{
654 sb t;
655 int src = 0;
656 int inquote = 0;
657 formal_entry *loclist = NULL;
658
659 sb_new (&t);
660
661 while (src < in->len)
662 {
663 if (in->ptr[src] == '&')
664 {
665 sb_reset (&t);
666 if (macro_mri)
667 {
668 if (src + 1 < in->len && in->ptr[src + 1] == '&')
669 src = sub_actual (src + 2, in, &t, formal_hash, '\'', out, 1);
670 else
671 sb_add_char (out, in->ptr[src++]);
672 }
673 else
674 {
675 /* FIXME: Why do we do this? */
676 src = sub_actual (src + 1, in, &t, formal_hash, '&', out, 0);
677 }
678 }
679 else if (in->ptr[src] == '\\')
680 {
681 src++;
fea17916 682 if (in->ptr[src] == '(')
252b5132 683 {
29f8404c 684 /* Sub in till the next ')' literally. */
252b5132
RH
685 src++;
686 while (src < in->len && in->ptr[src] != ')')
687 {
688 sb_add_char (out, in->ptr[src++]);
689 }
690 if (in->ptr[src] == ')')
691 src++;
692 else
693 return _("missplaced )");
694 }
695 else if (in->ptr[src] == '@')
696 {
29f8404c 697 /* Sub in the macro invocation number. */
252b5132
RH
698
699 char buffer[10];
700 src++;
a2984248 701 sprintf (buffer, "%d", macro_number);
252b5132
RH
702 sb_add_string (out, buffer);
703 }
704 else if (in->ptr[src] == '&')
705 {
706 /* This is a preprocessor variable name, we don't do them
29f8404c 707 here. */
252b5132
RH
708 sb_add_char (out, '\\');
709 sb_add_char (out, '&');
710 src++;
711 }
3882b010 712 else if (macro_mri && ISALNUM (in->ptr[src]))
252b5132
RH
713 {
714 int ind;
715 formal_entry *f;
716
3882b010 717 if (ISDIGIT (in->ptr[src]))
252b5132 718 ind = in->ptr[src] - '0';
3882b010 719 else if (ISUPPER (in->ptr[src]))
252b5132
RH
720 ind = in->ptr[src] - 'A' + 10;
721 else
722 ind = in->ptr[src] - 'a' + 10;
723 ++src;
724 for (f = formals; f != NULL; f = f->next)
725 {
726 if (f->index == ind - 1)
727 {
728 if (f->actual.len != 0)
729 sb_add_sb (out, &f->actual);
730 else
731 sb_add_sb (out, &f->def);
732 break;
733 }
734 }
735 }
736 else
737 {
738 sb_reset (&t);
739 src = sub_actual (src, in, &t, formal_hash, '\'', out, 0);
740 }
741 }
742 else if ((macro_alternate || macro_mri)
3882b010 743 && (ISALPHA (in->ptr[src])
252b5132
RH
744 || in->ptr[src] == '_'
745 || in->ptr[src] == '$')
746 && (! inquote
747 || ! macro_strip_at
748 || (src > 0 && in->ptr[src - 1] == '@')))
749 {
750 if (! locals
751 || src + 5 >= in->len
752 || strncasecmp (in->ptr + src, "LOCAL", 5) != 0
753 || ! ISWHITE (in->ptr[src + 5]))
754 {
755 sb_reset (&t);
756 src = sub_actual (src, in, &t, formal_hash,
757 (macro_strip_at && inquote) ? '@' : '\'',
758 out, 1);
759 }
760 else
761 {
762 formal_entry *f;
763
764 src = sb_skip_white (src + 5, in);
fea17916 765 while (in->ptr[src] != '\n')
252b5132
RH
766 {
767 static int loccnt;
768 char buf[20];
769 const char *err;
770
771 f = (formal_entry *) xmalloc (sizeof (formal_entry));
772 sb_new (&f->name);
773 sb_new (&f->def);
774 sb_new (&f->actual);
775 f->index = LOCAL_INDEX;
776 f->next = loclist;
777 loclist = f;
778
779 src = get_token (src, in, &f->name);
780 ++loccnt;
89658e52 781 sprintf (buf, IS_ELF ? ".LL%04x" : "LL%04x", loccnt);
252b5132
RH
782 sb_add_string (&f->actual, buf);
783
784 err = hash_jam (formal_hash, sb_terminate (&f->name), f);
785 if (err != NULL)
786 return err;
787
788 src = sb_skip_comma (src, in);
789 }
790 }
791 }
252b5132
RH
792 else if (in->ptr[src] == '"'
793 || (macro_mri && in->ptr[src] == '\''))
794 {
795 inquote = !inquote;
796 sb_add_char (out, in->ptr[src++]);
797 }
798 else if (in->ptr[src] == '@' && macro_strip_at)
799 {
800 ++src;
801 if (src < in->len
802 && in->ptr[src] == '@')
803 {
804 sb_add_char (out, '@');
805 ++src;
806 }
807 }
808 else if (macro_mri
809 && in->ptr[src] == '='
810 && src + 1 < in->len
811 && in->ptr[src + 1] == '=')
812 {
813 formal_entry *ptr;
814
815 sb_reset (&t);
816 src = get_token (src + 2, in, &t);
817 ptr = (formal_entry *) hash_find (formal_hash, sb_terminate (&t));
818 if (ptr == NULL)
819 {
820 /* FIXME: We should really return a warning string here,
821 but we can't, because the == might be in the MRI
822 comment field, and, since the nature of the MRI
823 comment field depends upon the exact instruction
824 being used, we don't have enough information here to
825 figure out whether it is or not. Instead, we leave
826 the == in place, which should cause a syntax error if
827 it is not in a comment. */
828 sb_add_char (out, '=');
829 sb_add_char (out, '=');
830 sb_add_sb (out, &t);
831 }
832 else
833 {
834 if (ptr->actual.len)
835 {
836 sb_add_string (out, "-1");
837 }
838 else
839 {
840 sb_add_char (out, '0');
841 }
842 }
843 }
844 else
845 {
846 sb_add_char (out, in->ptr[src++]);
847 }
848 }
849
850 sb_kill (&t);
851
852 while (loclist != NULL)
853 {
854 formal_entry *f;
855
856 f = loclist->next;
1af6dcd2
ILT
857 /* Setting the value to NULL effectively deletes the entry. We
858 avoid calling hash_delete because it doesn't reclaim memory. */
859 hash_jam (formal_hash, sb_terminate (&loclist->name), NULL);
252b5132
RH
860 sb_kill (&loclist->name);
861 sb_kill (&loclist->def);
862 sb_kill (&loclist->actual);
863 free (loclist);
864 loclist = f;
865 }
866
867 return NULL;
868}
869
870/* Assign values to the formal parameters of a macro, and expand the
871 body. */
872
873static const char *
254d758c 874macro_expand (int idx, sb *in, macro_entry *m, sb *out)
252b5132
RH
875{
876 sb t;
877 formal_entry *ptr;
878 formal_entry *f;
879 int is_positional = 0;
880 int is_keyword = 0;
881 int narg = 0;
882 const char *err;
883
884 sb_new (&t);
29f8404c
KH
885
886 /* Reset any old value the actuals may have. */
252b5132 887 for (f = m->formals; f; f = f->next)
29f8404c 888 sb_reset (&f->actual);
252b5132
RH
889 f = m->formals;
890 while (f != NULL && f->index < 0)
891 f = f->next;
892
893 if (macro_mri)
894 {
895 /* The macro may be called with an optional qualifier, which may
896 be referred to in the macro body as \0. */
897 if (idx < in->len && in->ptr[idx] == '.')
d1a6c242
KH
898 {
899 /* The Microtec assembler ignores this if followed by a white space.
900 (Macro invocation with empty extension) */
901 idx++;
902 if ( idx < in->len
903 && in->ptr[idx] != ' '
904 && in->ptr[idx] != '\t')
905 {
906 formal_entry *n;
907
908 n = (formal_entry *) xmalloc (sizeof (formal_entry));
909 sb_new (&n->name);
910 sb_new (&n->def);
911 sb_new (&n->actual);
912 n->index = QUAL_INDEX;
913
914 n->next = m->formals;
915 m->formals = n;
916
917 idx = get_any_string (idx, in, &n->actual, 1, 0);
918 }
919 }
920 }
252b5132 921
29f8404c 922 /* Peel off the actuals and store them away in the hash tables' actuals. */
252b5132 923 idx = sb_skip_white (idx, in);
fea17916 924 while (idx < in->len)
252b5132
RH
925 {
926 int scan;
927
29f8404c 928 /* Look and see if it's a positional or keyword arg. */
252b5132
RH
929 scan = idx;
930 while (scan < in->len
931 && !ISSEP (in->ptr[scan])
932 && !(macro_mri && in->ptr[scan] == '\'')
933 && (!macro_alternate && in->ptr[scan] != '='))
934 scan++;
935 if (scan < in->len && !macro_alternate && in->ptr[scan] == '=')
936 {
937 is_keyword = 1;
938
939 /* It's OK to go from positional to keyword. */
940
941 /* This is a keyword arg, fetch the formal name and
29f8404c 942 then the actual stuff. */
252b5132
RH
943 sb_reset (&t);
944 idx = get_token (idx, in, &t);
945 if (in->ptr[idx] != '=')
946 return _("confusion in formal parameters");
947
29f8404c 948 /* Lookup the formal in the macro's list. */
252b5132
RH
949 ptr = (formal_entry *) hash_find (m->formal_hash, sb_terminate (&t));
950 if (!ptr)
951 return _("macro formal argument does not exist");
952 else
953 {
29f8404c 954 /* Insert this value into the right place. */
252b5132
RH
955 sb_reset (&ptr->actual);
956 idx = get_any_string (idx + 1, in, &ptr->actual, 0, 0);
957 if (ptr->actual.len > 0)
958 ++narg;
959 }
960 }
961 else
962 {
29f8404c 963 /* This is a positional arg. */
252b5132
RH
964 is_positional = 1;
965 if (is_keyword)
966 return _("can't mix positional and keyword arguments");
967
968 if (!f)
969 {
970 formal_entry **pf;
971 int c;
972
973 if (!macro_mri)
974 return _("too many positional arguments");
975
976 f = (formal_entry *) xmalloc (sizeof (formal_entry));
977 sb_new (&f->name);
978 sb_new (&f->def);
979 sb_new (&f->actual);
980 f->next = NULL;
981
982 c = -1;
983 for (pf = &m->formals; *pf != NULL; pf = &(*pf)->next)
984 if ((*pf)->index >= c)
985 c = (*pf)->index + 1;
986 if (c == -1)
987 c = 0;
988 *pf = f;
989 f->index = c;
990 }
991
992 sb_reset (&f->actual);
993 idx = get_any_string (idx, in, &f->actual, 1, 0);
994 if (f->actual.len > 0)
995 ++narg;
996 do
997 {
998 f = f->next;
999 }
1000 while (f != NULL && f->index < 0);
1001 }
1002
1003 if (! macro_mri)
1004 idx = sb_skip_comma (idx, in);
1005 else
1006 {
1007 if (in->ptr[idx] == ',')
1008 ++idx;
1009 if (ISWHITE (in->ptr[idx]))
1010 break;
1011 }
1012 }
1013
1014 if (macro_mri)
1015 {
1016 char buffer[20];
1017
1018 sb_reset (&t);
1019 sb_add_string (&t, macro_strip_at ? "$NARG" : "NARG");
1020 ptr = (formal_entry *) hash_find (m->formal_hash, sb_terminate (&t));
1021 sb_reset (&ptr->actual);
1022 sprintf (buffer, "%d", narg);
1023 sb_add_string (&ptr->actual, buffer);
1024 }
1025
fea17916 1026 err = macro_expand_body (&m->sub, out, m->formals, m->formal_hash, 1);
252b5132
RH
1027 if (err != NULL)
1028 return err;
1029
1030 /* Discard any unnamed formal arguments. */
1031 if (macro_mri)
1032 {
1033 formal_entry **pf;
1034
1035 pf = &m->formals;
1036 while (*pf != NULL)
1037 {
1038 if ((*pf)->name.len != 0)
1039 pf = &(*pf)->next;
1040 else
1041 {
1042 sb_kill (&(*pf)->name);
1043 sb_kill (&(*pf)->def);
1044 sb_kill (&(*pf)->actual);
1045 f = (*pf)->next;
1046 free (*pf);
1047 *pf = f;
1048 }
1049 }
1050 }
1051
1052 sb_kill (&t);
1053 macro_number++;
1054
1055 return NULL;
1056}
1057
1058/* Check for a macro. If one is found, put the expansion into
fea17916 1059 *EXPAND. Return 1 if a macro is found, 0 otherwise. */
252b5132
RH
1060
1061int
254d758c
KH
1062check_macro (const char *line, sb *expand,
1063 const char **error, macro_entry **info)
252b5132
RH
1064{
1065 const char *s;
1066 char *copy, *cs;
1067 macro_entry *macro;
1068 sb line_sb;
1069
3882b010 1070 if (! ISALPHA (*line)
252b5132
RH
1071 && *line != '_'
1072 && *line != '$'
1073 && (! macro_mri || *line != '.'))
1074 return 0;
1075
1076 s = line + 1;
3882b010 1077 while (ISALNUM (*s)
252b5132
RH
1078 || *s == '_'
1079 || *s == '$')
1080 ++s;
1081
1082 copy = (char *) alloca (s - line + 1);
1083 memcpy (copy, line, s - line);
1084 copy[s - line] = '\0';
1085 for (cs = copy; *cs != '\0'; cs++)
3882b010 1086 *cs = TOLOWER (*cs);
252b5132
RH
1087
1088 macro = (macro_entry *) hash_find (macro_hash, copy);
1089
1090 if (macro == NULL)
1091 return 0;
1092
1093 /* Wrap the line up in an sb. */
1094 sb_new (&line_sb);
1095 while (*s != '\0' && *s != '\n' && *s != '\r')
1096 sb_add_char (&line_sb, *s++);
1097
1098 sb_new (expand);
fea17916 1099 *error = macro_expand (0, &line_sb, macro, expand);
252b5132
RH
1100
1101 sb_kill (&line_sb);
1102
29f8404c 1103 /* Export the macro information if requested. */
9f10757c
TW
1104 if (info)
1105 *info = macro;
1106
252b5132
RH
1107 return 1;
1108}
1109
1110/* Delete a macro. */
1111
1112void
254d758c 1113delete_macro (const char *name)
252b5132
RH
1114{
1115 hash_delete (macro_hash, name);
1116}
1117
1118/* Handle the MRI IRP and IRPC pseudo-ops. These are handled as a
1119 combined macro definition and execution. This returns NULL on
1120 success, or an error message otherwise. */
1121
1122const char *
254d758c 1123expand_irp (int irpc, int idx, sb *in, sb *out, int (*get_line) (sb *))
252b5132
RH
1124{
1125 const char *mn;
1126 sb sub;
1127 formal_entry f;
1128 struct hash_control *h;
1129 const char *err;
1130
1131 if (irpc)
1132 mn = "IRPC";
1133 else
1134 mn = "IRP";
1135
1136 idx = sb_skip_white (idx, in);
1137
1138 sb_new (&sub);
1139 if (! buffer_and_nest (mn, "ENDR", &sub, get_line))
1140 return _("unexpected end of file in irp or irpc");
29f8404c 1141
252b5132
RH
1142 sb_new (&f.name);
1143 sb_new (&f.def);
1144 sb_new (&f.actual);
1145
1146 idx = get_token (idx, in, &f.name);
1147 if (f.name.len == 0)
1148 return _("missing model parameter");
1149
1150 h = hash_new ();
1151 err = hash_jam (h, sb_terminate (&f.name), &f);
1152 if (err != NULL)
1153 return err;
1154
1155 f.index = 1;
1156 f.next = NULL;
1157
1158 sb_reset (out);
1159
1160 idx = sb_skip_comma (idx, in);
fea17916 1161 if (idx >= in->len)
252b5132
RH
1162 {
1163 /* Expand once with a null string. */
fea17916 1164 err = macro_expand_body (&sub, out, &f, h, 0);
252b5132
RH
1165 if (err != NULL)
1166 return err;
1167 }
1168 else
1169 {
1170 if (irpc && in->ptr[idx] == '"')
1171 ++idx;
fea17916 1172 while (idx < in->len)
252b5132
RH
1173 {
1174 if (!irpc)
1175 idx = get_any_string (idx, in, &f.actual, 1, 0);
1176 else
1177 {
1178 if (in->ptr[idx] == '"')
1179 {
1180 int nxt;
1181
1182 nxt = sb_skip_white (idx + 1, in);
fea17916 1183 if (nxt >= in->len)
252b5132
RH
1184 {
1185 idx = nxt;
1186 break;
1187 }
1188 }
1189 sb_reset (&f.actual);
1190 sb_add_char (&f.actual, in->ptr[idx]);
1191 ++idx;
1192 }
fea17916 1193 err = macro_expand_body (&sub, out, &f, h, 0);
252b5132
RH
1194 if (err != NULL)
1195 return err;
1196 if (!irpc)
1197 idx = sb_skip_comma (idx, in);
1198 else
1199 idx = sb_skip_white (idx, in);
1200 }
1201 }
1202
1203 hash_die (h);
1204 sb_kill (&sub);
1205
1206 return NULL;
1207}
This page took 0.606425 seconds and 4 git commands to generate.