21#include "gdbsupport/gdb_obstack.h"
130 return gdb::unique_xmalloc_ptr<char> (result);
148 int new_len =
len + 1;
160 int new_len =
len + count;
165 memcpy (
text +
len, addr, count);
189 return (
'0' <= c && c <=
'9');
197 || (
'a' <= c && c <=
'z')
198 || (
'A' <= c && c <=
'Z'));
221 const char *tok_start = p;
235 error (_(
"Unterminated comment in macro expansion."));
240 const char *tok_start = p;
261 const char *tok_start = p;
286 const char *tok_start = p;
291 && strchr (
"eEpP", *p)
292 && (p[1] ==
'+' || p[1] ==
'-'))
318 const char *p,
const char *end)
324 if ((p + 1 <= end && *p ==
'\'')
326 && (p[0] ==
'L' || p[0] ==
'u' || p[0] ==
'U')
329 const char *tok_start = p;
334 else if (*p ==
'L' || *p ==
'u' || *p ==
'U')
337 gdb_assert_not_reached (
"unexpected character constant");
342 error (_(
"Unmatched single quote."));
346 error (_(
"A character constant must contain at least one "
384 && (p[0] ==
'L' || p[0] ==
'u' || p[0] ==
'U')
387 const char *tok_start = p;
391 else if (*p ==
'L' || *p ==
'u' || *p ==
'U')
394 gdb_assert_not_reached (
"unexpected string literal");
399 error (_(
"Unterminated string in expression."));
406 error (_(
"Newline characters may not appear in string "
437 static const char *
const punctuators[] = {
438 "[",
"]",
"(",
")",
"{",
"}",
"?",
";",
",",
"~",
440 "->",
"--",
"-=",
"-",
446 "%>",
"%:%:",
"%:",
"%=",
"%",
451 "<<=",
"<<",
"<=",
"<:",
"<%",
"<",
452 ">>=",
">>",
">=",
">",
461 for (i = 0; punctuators[i]; i++)
463 const char *punctuator = punctuators[i];
465 if (p[0] == punctuator[0])
467 int len = strlen (punctuator);
470 && ! memcmp (p, punctuator, len))
493 const char *p = src->
text;
494 const char *end = p + src->
len;
530 int consumed = p - src->
text + tok->
len;
532 src->
text += consumed;
533 src->
len -= consumed;
543 consumed = p - src->
text + tok->
len;
544 src->
text += consumed;
545 src->
len -= consumed;
576 int original_dest_len = dest->
len;
605 && (new_token.
text + new_token.
len
606 == dest->
text + original_dest_len))
616 dest->
len = original_dest_len;
625 && (new_token.
text + new_token.
len
626 == dest->
text + original_dest_len))
635 internal_error (_(
"unable to avoid splicing tokens during macro expansion"));
671 else if (*arg ==
'\\' || *arg ==
'"')
687gdb::unique_xmalloc_ptr<char>
690 int len = strlen (str);
724 for (; list; list = list->
next)
770 std::vector<shared_macro_buffer> *args_ptr)
773 std::vector<shared_macro_buffer> args;
783 || tok.
text[0] !=
'(')
796 args.emplace_back ();
805 error (_(
"Malformed argument list for macro `%s'."),
name);
808 if (tok.
len == 1 && tok.
text[0] ==
'(')
812 else if (tok.
len == 1 && tok.
text[0] ==
')')
820 if (nargs != -1 && args.size () == nargs - 1)
822 args.emplace_back ();
827 *args_ptr = std::move (args);
838 else if (tok.
len == 1 && tok.
text[0] ==
',' && depth == 0
839 && (nargs == -1 || args.size () < nargs))
882 int argc,
const char *
const *argv)
889 for (i = 0; i < argc; ++i)
890 if (tok->
len == strlen (argv[i])
891 && !memcmp (tok->
text, argv[i], tok->
len))
894 if (is_varargs && tok->
len == va_arg_name->
len
895 && ! memcmp (tok->
text, va_arg_name->
text, tok->
len))
909 const char **lookahead_start,
910 int *lookahead_valid,
913 if (!*lookahead_valid)
919 *start = *lookahead_start;
920 *lookahead_start = replacement_list->
text;
921 *lookahead_valid =
get_token (lookahead, replacement_list);
944 const std::vector<shared_macro_buffer> &argv,
951 const char *original_rl_start;
958 const char *lookahead_rl_start;
964 gdb_assert (dest->
len == 0);
967 original_rl_start = replacement_list.
text;
968 if (!
get_token (&tok, &replacement_list))
970 lookahead_rl_start = replacement_list.
text;
971 lookahead_valid =
get_token (&lookahead, &replacement_list);
977 unsigned vaopt_state = 0;
989 bool token_is_vaopt = (tok.
len == 10
990 && startswith (tok.
text,
"__VA_OPT__"));
995 error (_(
"__VA_OPT__ cannot appear inside __VA_OPT__"));
996 else if (tok.
len == 1 && tok.
text[0] ==
'(')
1003 else if (vaopt_state == 1)
1004 error (_(
"__VA_OPT__ must be followed by an open parenthesis"));
1005 else if (tok.
len == 1 && tok.
text[0] ==
')')
1008 if (vaopt_state == 1)
1019 if (argv.back ().len == 0)
1022 else if (token_is_vaopt)
1025 error (_(
"__VA_OPT__ is only valid in a variadic macro"));
1033 if (tok.
text > original_rl_start)
1035 dest->
appendmem (original_rl_start, tok.
text - original_rl_start);
1041 && tok.
text[0] ==
'#')
1045 if (!lookahead_valid)
1046 error (_(
"Stringification operator requires an argument."));
1051 error (_(
"Argument to stringification operator must name "
1052 "a macro parameter."));
1054 stringify (dest, argv[arg].text, argv[arg].len);
1058 lookahead_rl_start = replacement_list.
text;
1059 lookahead_valid =
get_token (&lookahead, &replacement_list);
1062 else if (tok.
len == 2
1063 && tok.
text[0] ==
'#'
1064 && tok.
text[1] ==
'#')
1065 error (_(
"Stray splicing operator"));
1067 else if (lookahead_valid
1068 && lookahead.
len == 2
1069 && lookahead.
text[0] ==
'#'
1070 && lookahead.
text[1] ==
'#')
1073 int prev_was_comma = 0;
1080 if (tok.
len == 1 && tok.
text[0] ==
',')
1088 dest->
appendmem (argv[arg].text, argv[arg].len);
1096 if (!
get_token (&tok, &replacement_list))
1097 error (_(
"Splicing operator at end of macro"));
1111 && tok.
len == va_arg_name->
len
1113 && argv.back ().len == 0))
1120 if (tok.
len == 1 && tok.
text[0] ==
',')
1128 dest->
appendmem (argv[arg].text, argv[arg].len);
1135 original_rl_start = replacement_list.
text;
1136 if (!
get_token (&tok, &replacement_list))
1143 && tok.
text[0] ==
'#'
1144 && tok.
text[1] ==
'#'))
1156 lookahead_valid = 0;
1161 lookahead_rl_start = original_rl_start;
1162 lookahead_valid = 1;
1168 int substituted = 0;
1180 scan (dest, &arg_src, no_loop, scope);
1190 if (vaopt_state > 0)
1191 error (_(
"Unterminated __VA_OPT__"));
1219 new_no_loop.
name = id;
1220 new_no_loop.
next = no_loop;
1228 scan (dest, &replacement_list, &new_no_loop, scope);
1238 if (strcmp (def->
argv[def->
argc - 1],
"...") == 0)
1242 va_arg_name.
set_shared (
"__VA_ARGS__", strlen (
"__VA_ARGS__"));
1247 int len = strlen (def->
argv[def->
argc - 1]);
1250 && strcmp (def->
argv[def->
argc - 1] + len - 3,
"...") == 0)
1261 std::vector<shared_macro_buffer> argv;
1270 if (argv.size () != def->
argc)
1272 if (is_varargs && argv.size () >= def->
argc - 1)
1279 else if (! (argv.size () == 1
1282 error (_(
"Wrong number of arguments to macro `%s' "
1283 "(expected %d, got %d)."),
1284 id, def->
argc, int (argv.size ()));
1295 argv, no_loop, scope);
1308 scan (dest, &substituted_src, &new_no_loop, scope);
1313 internal_error (_(
"bad macro definition kind"));
1335 std::string id (src_first->
text, src_first->
len);
1344 if (def &&
expand (
id.c_str (), def, dest, src_rest, no_loop, scope))
1367 const char *original_src_start = src->
text;
1375 if (tok.
text > original_src_start)
1377 dest->
appendmem (original_src_start, tok.
text - original_src_start);
1397gdb::unique_xmalloc_ptr<char>
1405 scan (&dest, &src, 0, scope);
1413gdb::unique_xmalloc_ptr<char>
1416 error (_(
"Expand-once not implemented yet."));
1419gdb::unique_xmalloc_ptr<char>
void * xrealloc(void *ptr, size_t size)
int c_parse_escape(const char **ptr, struct obstack *output)
static void keep_going(struct execution_control_state *ecs)
static int maybe_expand(growable_macro_buffer *dest, shared_macro_buffer *src_first, shared_macro_buffer *src_rest, struct macro_name_list *no_loop, const macro_scope &scope)
static int get_character_constant(shared_macro_buffer *tok, const char *p, const char *end)
gdb::unique_xmalloc_ptr< char > macro_stringify(const char *str)
static int currently_rescanning(struct macro_name_list *list, const char *name)
static int get_punctuator(shared_macro_buffer *tok, const char *p, const char *end)
int macro_is_identifier_nondigit(int c)
gdb::unique_xmalloc_ptr< char > macro_expand(const char *source, const macro_scope &scope)
int macro_is_digit(int c)
static int expand(const char *id, struct macro_definition *def, growable_macro_buffer *dest, shared_macro_buffer *src, struct macro_name_list *no_loop, const macro_scope &scope)
static int get_comment(shared_macro_buffer *tok, const char *p, const char *end)
static void scan(growable_macro_buffer *dest, shared_macro_buffer *src, struct macro_name_list *no_loop, const macro_scope &scope)
static void get_next_token_for_substitution(shared_macro_buffer *replacement_list, shared_macro_buffer *token, const char **start, shared_macro_buffer *lookahead, const char **lookahead_start, int *lookahead_valid, bool *keep_going)
static int get_pp_number(shared_macro_buffer *tok, const char *p, const char *end)
static int get_identifier(shared_macro_buffer *tok, const char *p, const char *end)
static void substitute_args(growable_macro_buffer *dest, struct macro_definition *def, int is_varargs, const shared_macro_buffer *va_arg_name, const std::vector< shared_macro_buffer > &argv, struct macro_name_list *no_loop, const macro_scope &scope)
gdb::unique_xmalloc_ptr< char > macro_expand_once(const char *source, const macro_scope &scope)
static void set_token(shared_macro_buffer *tok, const char *start, const char *end)
gdb::unique_xmalloc_ptr< char > macro_expand_next(const char **lexptr, const macro_scope &scope)
static void append_tokens_without_splicing(growable_macro_buffer *dest, shared_macro_buffer *src)
int macro_is_whitespace(int c)
static int get_token(shared_macro_buffer *tok, shared_macro_buffer *src)
static int find_parameter(const shared_macro_buffer *tok, int is_varargs, const shared_macro_buffer *va_arg_name, int argc, const char *const *argv)
static void stringify(growable_macro_buffer *dest, const char *arg, int len)
static bool gather_arguments(const char *name, shared_macro_buffer *src, int nargs, std::vector< shared_macro_buffer > *args_ptr)
static int get_string_literal(shared_macro_buffer *tok, const char *p, const char *end)
struct macro_definition * standard_macro_lookup(const char *name, const macro_scope &ms)
growable_macro_buffer(int n)
void appendmem(const char *addr, int count)
DISABLE_COPY_AND_ASSIGN(growable_macro_buffer)
gdb::unique_xmalloc_ptr< char > release()
void resize_buffer(int n)
__extension__ enum macro_kind kind
struct macro_name_list * next
shared_macro_buffer(const char *addr, int len)
void set_shared(const char *addr, int len_)