X-Git-Url: http://drtracing.org/?a=blobdiff_plain;f=gas%2Fmacro.c;h=d7d470b764eb31355e0a3b6173848a8c7e57d69e;hb=6e29ef6d2828415f5ee2d6e1690d13bc40a8d5d4;hp=fbe266612c30036434e397a36d636bbbca3ce22a;hpb=df40eaf977e1422cfd1a8e55de7efffdd397447a;p=deliverable%2Fbinutils-gdb.git diff --git a/gas/macro.c b/gas/macro.c index fbe266612c..d7d470b764 100644 --- a/gas/macro.c +++ b/gas/macro.c @@ -1,6 +1,6 @@ /* macro.c - macro support for gas Copyright 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, - 2004, 2005 Free Software Foundation, Inc. + 2004, 2005, 2006 Free Software Foundation, Inc. Written by Steve and Judy Chamberlain of Cygnus Support, sac@cygnus.com @@ -22,47 +22,11 @@ Software Foundation, 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA. */ -#include "config.h" - -#ifndef __GNUC__ -# if HAVE_ALLOCA_H -# include -# else -# ifdef _AIX -/* Indented so that pre-ansi C compilers will ignore it, rather than - choke on it. Some versions of AIX require this to be the first - thing in the file. */ - #pragma alloca -# else -# ifndef alloca /* predefined by HP cc +Olibcalls */ -# if !defined (__STDC__) && !defined (__hpux) -extern char *alloca (); -# else -extern void *alloca (); -# endif /* __STDC__, __hpux */ -# endif /* alloca */ -# endif /* _AIX */ -# endif /* HAVE_ALLOCA_H */ -#endif /* __GNUC__ */ - -#include -#ifdef HAVE_STRING_H -#include -#else -#include -#endif -#ifdef HAVE_STDLIB_H -#include -#endif #include "as.h" -#include "libiberty.h" #include "safe-ctype.h" #include "sb.h" -#include "hash.h" #include "macro.h" -#include "asintl.h" - /* The routines in this file handle macro definition and expansion. They are called by gas. */ @@ -180,49 +144,46 @@ buffer_and_nest (const char *from, const char *to, sb *ptr, while (more) { - /* Try and find the first pseudo op on the line. */ + /* Try to find the first pseudo op on the line. */ int i = line_start; - if (! NO_PSEUDO_DOT && ! flag_m68k_mri) - { - /* With normal syntax we can suck what we want till we get - to the dot. With the alternate, labels have to start in - the first column, since we can't tell what's a label and - whats a pseudoop. */ + /* With normal syntax we can suck what we want till we get + to the dot. With the alternate, labels have to start in + the first column, since we can't tell what's a label and + what's a pseudoop. */ - if (! LABELS_WITHOUT_COLONS) - { - /* Skip leading whitespace. */ - while (i < ptr->len && ISWHITE (ptr->ptr[i])) - i++; - } + if (! LABELS_WITHOUT_COLONS) + { + /* Skip leading whitespace. */ + while (i < ptr->len && ISWHITE (ptr->ptr[i])) + i++; + } - for (;;) + for (;;) + { + /* Skip over a label, if any. */ + if (i >= ptr->len || ! is_name_beginner (ptr->ptr[i])) + break; + i++; + while (i < ptr->len && is_part_of_name (ptr->ptr[i])) + i++; + if (i < ptr->len && is_name_ender (ptr->ptr[i])) + i++; + if (LABELS_WITHOUT_COLONS) + break; + /* Skip whitespace. */ + while (i < ptr->len && ISWHITE (ptr->ptr[i])) + i++; + /* Check for the colon. */ + if (i >= ptr->len || ptr->ptr[i] != ':') { - /* Skip over a label, if any. */ - if (i >= ptr->len || ! is_name_beginner (ptr->ptr[i])) - break; - i++; - while (i < ptr->len && is_part_of_name (ptr->ptr[i])) - i++; - if (i < ptr->len && is_name_ender (ptr->ptr[i])) - i++; - if (LABELS_WITHOUT_COLONS) - break; - /* Skip whitespace. */ - while (i < ptr->len && ISWHITE (ptr->ptr[i])) - i++; - /* Check for the colon. */ - if (i >= ptr->len || ptr->ptr[i] != ':') - { - i = line_start; - break; - } - i++; - line_start = i; + i = line_start; + break; } - + i++; + line_start = i; } + /* Skip trailing whitespace. */ while (i < ptr->len && ISWHITE (ptr->ptr[i])) i++; @@ -306,19 +267,14 @@ getstring (int idx, sb *in, sb *acc) { while (idx < in->len && (in->ptr[idx] == '"' - || in->ptr[idx] == '(' || (in->ptr[idx] == '<' && (macro_alternate || macro_mri)) || (in->ptr[idx] == '\'' && macro_alternate))) { - if (in->ptr[idx] == '<' - || in->ptr[idx] == '(') + if (in->ptr[idx] == '<') { int nest = 0; - char start_char = in->ptr[idx]; - char end_char = in->ptr[idx] == '<' ? '>' : ')'; - idx++; - while ((in->ptr[idx] != end_char || nest) + while ((in->ptr[idx] != '>' || nest) && idx < in->len) { if (in->ptr[idx] == '!') @@ -328,9 +284,9 @@ getstring (int idx, sb *in, sb *acc) } else { - if (in->ptr[idx] == end_char) + if (in->ptr[idx] == '>') nest--; - if (in->ptr[idx] == start_char) + if (in->ptr[idx] == '<') nest++; sb_add_char (acc, in->ptr[idx++]); } @@ -389,7 +345,7 @@ getstring (int idx, sb *in, sb *acc) 'Bxyx -> return 'Bxyza % -> return string of decimal value of "string" -> return string - (string) -> return string + (string) -> return (string-including-whitespaces) xyx -> return xyz. */ static int @@ -420,17 +376,15 @@ get_any_string (int idx, sb *in, sb *out) sb_add_string (out, buf); } else if (in->ptr[idx] == '"' - || in->ptr[idx] == '(' || (in->ptr[idx] == '<' && (macro_alternate || macro_mri)) || (macro_alternate && in->ptr[idx] == '\'')) { - if (macro_alternate && ! macro_strip_at) + if (macro_alternate && ! macro_strip_at && in->ptr[idx] != '<') { /* Keep the quotes. */ - sb_add_char (out, '\"'); - + sb_add_char (out, '"'); idx = getstring (idx, in, out); - sb_add_char (out, '\"'); + sb_add_char (out, '"'); } else { @@ -439,27 +393,57 @@ get_any_string (int idx, sb *in, sb *out) } else { + char *br_buf = xmalloc(1); + char *in_br = br_buf; + + *in_br = '\0'; while (idx < in->len - && in->ptr[idx] != ' ' - && in->ptr[idx] != '\t' + && (*in_br + || (in->ptr[idx] != ' ' + && in->ptr[idx] != '\t')) && in->ptr[idx] != ',' && (in->ptr[idx] != '<' || (! macro_alternate && ! macro_mri))) { - if (in->ptr[idx] == '"' - || in->ptr[idx] == '\'') - { - char tchar = in->ptr[idx]; + char tchar = in->ptr[idx]; + switch (tchar) + { + case '"': + case '\'': sb_add_char (out, in->ptr[idx++]); while (idx < in->len && in->ptr[idx] != tchar) sb_add_char (out, in->ptr[idx++]); if (idx == in->len) return idx; + break; + case '(': + case '[': + if (in_br > br_buf) + --in_br; + else + { + br_buf = xmalloc(strlen(in_br) + 2); + strcpy(br_buf + 1, in_br); + free(in_br); + in_br = br_buf; + } + *in_br = tchar; + break; + case ')': + if (*in_br == '(') + ++in_br; + break; + case ']': + if (*in_br == '[') + ++in_br; + break; } - sb_add_char (out, in->ptr[idx++]); + sb_add_char (out, tchar); + ++idx; } + free(br_buf); } } @@ -1005,7 +989,6 @@ macro_expand (int idx, sb *in, macro_entry *m, sb *out) sb t; formal_entry *ptr; formal_entry *f; - int is_positional = 0; int is_keyword = 0; int narg = 0; const char *err = NULL; @@ -1096,8 +1079,6 @@ macro_expand (int idx, sb *in, macro_entry *m, sb *out) } else { - /* This is a positional arg. */ - is_positional = 1; if (is_keyword) { err = _("can't mix positional and keyword arguments"); @@ -1344,8 +1325,14 @@ expand_irp (int irpc, int idx, sb *in, sb *out, int (*get_line) (sb *)) } else { + bfd_boolean in_quotes = FALSE; + if (irpc && in->ptr[idx] == '"') - ++idx; + { + in_quotes = TRUE; + ++idx; + } + while (idx < in->len) { if (!irpc) @@ -1356,6 +1343,9 @@ expand_irp (int irpc, int idx, sb *in, sb *out, int (*get_line) (sb *)) { int nxt; + if (irpc) + in_quotes = ! in_quotes; + nxt = sb_skip_white (idx + 1, in); if (nxt >= in->len) { @@ -1367,12 +1357,13 @@ expand_irp (int irpc, int idx, sb *in, sb *out, int (*get_line) (sb *)) sb_add_char (&f.actual, in->ptr[idx]); ++idx; } + err = macro_expand_body (&sub, out, &f, h, 0); if (err != NULL) break; if (!irpc) idx = sb_skip_comma (idx, in); - else + else if (! in_quotes) idx = sb_skip_white (idx, in); } }