X-Git-Url: http://drtracing.org/?a=blobdiff_plain;f=gdb%2Fmacroexp.c;h=0faa07fe61635f654347cb3b305763c81a64bb88;hb=0ea5cda8612bd2233f7a2f9d1eba0b62c2e6c015;hp=dda3592db317db70ecf368cd4d9008d305b3de61;hpb=17c8aaf5078f15d4cd621a5428a82080a7f4c516;p=deliverable%2Fbinutils-gdb.git diff --git a/gdb/macroexp.c b/gdb/macroexp.c index dda3592db3..0faa07fe61 100644 --- a/gdb/macroexp.c +++ b/gdb/macroexp.c @@ -1,5 +1,5 @@ /* C preprocessor macro expansion for GDB. - Copyright (C) 2002, 2007, 2008 Free Software Foundation, Inc. + Copyright (C) 2002-2014 Free Software Foundation, Inc. Contributed by Red Hat, Inc. This file is part of GDB. @@ -22,7 +22,7 @@ #include "bcache.h" #include "macrotab.h" #include "macroexp.h" -#include "gdb_assert.h" +#include "c-lang.h" @@ -112,6 +112,17 @@ free_buffer (struct macro_buffer *b) xfree (b->text); } +/* Like free_buffer, but return the text as an xstrdup()d string. + This only exists to try to make the API relatively clean. */ + +static char * +free_buffer_return_text (struct macro_buffer *b) +{ + gdb_assert (! b->shared); + gdb_assert (b->size); + /* Nothing to do. */ + return b->text; +} /* A cleanup function for macro buffers. */ static void @@ -204,7 +215,7 @@ set_token (struct macro_buffer *tok, char *start, char *end) init_shared_buffer (tok, start, end - start); tok->last_token = 0; - /* Presumed; get_identifier may overwrite this. */ + /* Presumed; get_identifier may overwrite this. */ tok->is_identifier = 0; } @@ -320,26 +331,27 @@ get_character_constant (struct macro_buffer *tok, char *p, char *end) way GDB's C/C++ lexer does. So we call parse_escape in utils.c to handle escape sequences. */ if ((p + 1 <= end && *p == '\'') - || (p + 2 <= end && p[0] == 'L' && p[1] == '\'')) + || (p + 2 <= end + && (p[0] == 'L' || p[0] == 'u' || p[0] == 'U') + && p[1] == '\'')) { char *tok_start = p; - char *body_start; + int char_count = 0; if (*p == '\'') p++; - else if (*p == 'L') + else if (*p == 'L' || *p == 'u' || *p == 'U') p += 2; else - gdb_assert (0); + gdb_assert_not_reached ("unexpected character constant"); - body_start = p; for (;;) { if (p >= end) error (_("Unmatched single quote.")); else if (*p == '\'') { - if (p == body_start) + if (!char_count) error (_("A character constant must contain at least one " "character.")); p++; @@ -347,11 +359,17 @@ get_character_constant (struct macro_buffer *tok, char *p, char *end) } else if (*p == '\\') { - p++; - parse_escape (&p); + const char *s, *o; + + s = o = ++p; + char_count += c_parse_escape (&s, NULL); + p += s - o; } else - p++; + { + p++; + char_count++; + } } set_token (tok, tok_start, p); @@ -370,25 +388,25 @@ static int get_string_literal (struct macro_buffer *tok, char *p, char *end) { if ((p + 1 <= end - && *p == '\"') + && *p == '"') || (p + 2 <= end - && p[0] == 'L' - && p[1] == '\"')) + && (p[0] == 'L' || p[0] == 'u' || p[0] == 'U') + && p[1] == '"')) { char *tok_start = p; - if (*p == '\"') + if (*p == '"') p++; - else if (*p == 'L') + else if (*p == 'L' || *p == 'u' || *p == 'U') p += 2; else - gdb_assert (0); + gdb_assert_not_reached ("unexpected string literal"); for (;;) { if (p >= end) error (_("Unterminated string in expression.")); - else if (*p == '\"') + else if (*p == '"') { p++; break; @@ -398,8 +416,11 @@ get_string_literal (struct macro_buffer *tok, char *p, char *end) "constants.")); else if (*p == '\\') { - p++; - parse_escape (&p); + const char *s, *o; + + s = o = ++p; + c_parse_escape (&s, NULL); + p += s - o; } else p++; @@ -518,6 +539,7 @@ get_token (struct macro_buffer *tok, { /* How many characters did we consume, including whitespace? */ int consumed = p - src->text + tok->len; + src->text += consumed; src->len -= consumed; return 1; @@ -631,7 +653,7 @@ append_tokens_without_splicing (struct macro_buffer *dest, stringify; it is LEN bytes long. */ static void -stringify (struct macro_buffer *dest, char *arg, int len) +stringify (struct macro_buffer *dest, const char *arg, int len) { /* Trim initial whitespace from ARG. */ while (len > 0 && macro_is_whitespace (*arg)) @@ -674,6 +696,21 @@ stringify (struct macro_buffer *dest, char *arg, int len) dest->last_token = dest->len; } +/* See macroexp.h. */ + +char * +macro_stringify (const char *str) +{ + struct macro_buffer buffer; + int len = strlen (str); + + init_buffer (&buffer, len); + stringify (&buffer, str, len); + appendc (&buffer, '\0'); + + return free_buffer_return_text (&buffer); +} + /* Expanding macros! */ @@ -695,7 +732,7 @@ struct macro_name_list { particular macro, and otherwise delegates the decision to another function/baton pair. But that makes the linked list of excluded macros chained through untyped baton pointers, which will make it - harder to debug. :( */ + harder to debug. :( */ static int currently_rescanning (struct macro_name_list *list, const char *name) { @@ -760,6 +797,7 @@ gather_arguments (const char *name, struct macro_buffer *src, paren. */ { struct macro_buffer temp; + init_shared_buffer (&temp, src->text, src->len); if (! get_token (&tok, &temp) @@ -798,8 +836,6 @@ gather_arguments (const char *name, struct macro_buffer *src, depth = 0; for (;;) { - char *start = src->text; - if (! get_token (&tok, src)) error (_("Malformed argument list for macro `%s'."), name); @@ -894,7 +930,8 @@ find_parameter (const struct macro_buffer *tok, return -1; for (i = 0; i < argc; ++i) - if (tok->len == strlen (argv[i]) && ! memcmp (tok->text, argv[i], tok->len)) + if (tok->len == strlen (argv[i]) + && !memcmp (tok->text, argv[i], tok->len)) return i; if (is_varargs && tok->len == va_arg_name->len @@ -997,7 +1034,7 @@ substitute_args (struct macro_buffer *dest, && lookahead.text[0] == '#' && lookahead.text[1] == '#') { - int arg, finished = 0; + int finished = 0; int prev_was_comma = 0; /* Note that GCC warns if the result of splicing is not a @@ -1011,6 +1048,7 @@ substitute_args (struct macro_buffer *dest, { int arg = find_parameter (&tok, is_varargs, va_arg_name, def->argc, def->argv); + if (arg != -1) appendmem (dest, argv[arg].text, argv[arg].len); else @@ -1050,6 +1088,7 @@ substitute_args (struct macro_buffer *dest, { int arg = find_parameter (&tok, is_varargs, va_arg_name, def->argc, def->argv); + if (arg != -1) appendmem (dest, argv[arg].text, argv[arg].len); else @@ -1130,7 +1169,7 @@ substitute_args (struct macro_buffer *dest, its expansion to DEST. SRC is the input text following the ID token. We are currently rescanning the expansions of the macros named in NO_LOOP; don't re-expand them. Use LOOKUP_FUNC and - LOOKUP_BATON to find definitions for any nested macro references. + LOOKUP_BATON to find definitions for any nested macro references. Return 1 if we decided to expand it, zero otherwise. (If it's a function-like macro name that isn't followed by an argument list, @@ -1172,7 +1211,7 @@ expand (const char *id, struct macro_buffer *argv = NULL; struct macro_buffer substituted; struct macro_buffer substituted_src; - struct macro_buffer va_arg_name; + struct macro_buffer va_arg_name = {0}; int is_varargs = 0; if (def->argc >= 1) @@ -1188,6 +1227,7 @@ expand (const char *id, else { int len = strlen (def->argv[def->argc - 1]); + if (len > 3 && strcmp (def->argv[def->argc - 1] + len - 3, "...") == 0) { @@ -1292,6 +1332,7 @@ maybe_expand (struct macro_buffer *dest, lookup function expects. */ char *id = xmalloc (src_first->len + 1); struct cleanup *back_to = make_cleanup (xfree, id); + memcpy (id, src_first->text, src_first->len); id[src_first->len] = 0; @@ -1398,7 +1439,7 @@ macro_expand_once (const char *source, char * -macro_expand_next (char **lexptr, +macro_expand_next (const char **lexptr, macro_lookup_ftype *lookup_func, void *lookup_baton) { @@ -1406,7 +1447,7 @@ macro_expand_next (char **lexptr, struct cleanup *back_to; /* Set up SRC to refer to the input text, pointed to by *lexptr. */ - init_shared_buffer (&src, *lexptr, strlen (*lexptr)); + init_shared_buffer (&src, (char *) *lexptr, strlen (*lexptr)); /* Set up DEST to receive the expansion, if there is one. */ init_buffer (&dest, 0);