From: Keith Seitz Date: Fri, 23 Feb 2018 18:07:29 +0000 (-0800) Subject: Move find_toplevel_char to utils.[ch] X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=a1c8ba9846b181bf46ada899b0d8a2c7737f8f39;p=thirdparty%2Fbinutils-gdb.git Move find_toplevel_char to utils.[ch] find_toplevel_char is being used more and more outside of linespec.c, so this patch moves it into utils.[ch]. gdb/ChangeLog: * linespec.c (find_toplevel_char): Moved to ... * utils.c (find_toplevel_char): ... here. * linespec.h (find_toplevel_char): Moved to ... * utils.h (find_toplevel_char): ... here. --- diff --git a/gdb/linespec.c b/gdb/linespec.c index 1236b3f4754..247b285b994 100644 --- a/gdb/linespec.c +++ b/gdb/linespec.c @@ -1277,83 +1277,6 @@ find_methods (struct type *t, enum language t_lang, const char *name, VEC_safe_push (typep, *superclasses, TYPE_BASECLASS (t, ibase)); } -/* Find an instance of the character C in the string S that is outside - of all parenthesis pairs, single-quoted strings, and double-quoted - strings. Also, ignore the char within a template name, like a ',' - within foo, while considering C++ operator') && depth > 0) - depth--; - else if (*scan == 'o' && !quoted && depth == 0) - { - /* Handle C++ operator names. */ - if (strncmp (scan, CP_OPERATOR_STR, CP_OPERATOR_LEN) == 0) - { - scan += CP_OPERATOR_LEN; - if (*scan == c) - return scan; - while (isspace (*scan)) - { - ++scan; - if (*scan == c) - return scan; - } - if (*scan == '\0') - break; - - switch (*scan) - { - /* Skip over one less than the appropriate number of - characters: the for loop will skip over the last - one. */ - case '<': - if (scan[1] == '<') - { - scan++; - if (*scan == c) - return scan; - } - break; - case '>': - if (scan[1] == '>') - { - scan++; - if (*scan == c) - return scan; - } - break; - } - } - } - } - - return 0; -} - /* The string equivalent of find_toplevel_char. Returns a pointer to the location of NEEDLE in HAYSTACK, ignoring any occurrences inside "()" and "<>". Returns NULL if NEEDLE was not found. */ diff --git a/gdb/linespec.h b/gdb/linespec.h index eced085e3ea..2649af9e4f8 100644 --- a/gdb/linespec.h +++ b/gdb/linespec.h @@ -163,13 +163,6 @@ extern const char *get_gdb_linespec_parser_quote_characters (void); extern int is_ada_operator (const char *string); -/* Find an instance of the character C in the string S that is outside - of all parenthesis pairs, single-quoted strings, and double-quoted - strings. Also, ignore the char within a template name, like a ',' - within foo. */ - -extern const char *find_toplevel_char (const char *s, char c); - /* Find the end of the (first) linespec pointed to by *STRINGP. STRINGP will be advanced to this point. */ diff --git a/gdb/utils.c b/gdb/utils.c index c531748fe46..0a072fee6b7 100644 --- a/gdb/utils.c +++ b/gdb/utils.c @@ -3431,6 +3431,80 @@ strip_leading_path_elements (const char *path, int n) return p; } +/* See description in utils.h. */ + +const char * +find_toplevel_char (const char *s, char c) +{ + int quoted = 0; /* zero if we're not in quotes; + '"' if we're in a double-quoted string; + '\'' if we're in a single-quoted string. */ + int depth = 0; /* Number of unclosed parens we've seen. */ + const char *scan; + + for (scan = s; *scan; scan++) + { + if (quoted) + { + if (*scan == quoted) + quoted = 0; + else if (*scan == '\\' && *(scan + 1)) + scan++; + } + else if (*scan == c && ! quoted && depth == 0) + return scan; + else if (*scan == '"' || *scan == '\'') + quoted = *scan; + else if (*scan == '(' || *scan == '<') + depth++; + else if ((*scan == ')' || *scan == '>') && depth > 0) + depth--; + else if (*scan == 'o' && !quoted && depth == 0) + { + /* Handle C++ operator names. */ + if (strncmp (scan, CP_OPERATOR_STR, CP_OPERATOR_LEN) == 0) + { + scan += CP_OPERATOR_LEN; + if (*scan == c) + return scan; + while (isspace (*scan)) + { + ++scan; + if (*scan == c) + return scan; + } + if (*scan == '\0') + break; + + switch (*scan) + { + /* Skip over one less than the appropriate number of + characters: the for loop will skip over the last + one. */ + case '<': + if (scan[1] == '<') + { + scan++; + if (*scan == c) + return scan; + } + break; + case '>': + if (scan[1] == '>') + { + scan++; + if (*scan == c) + return scan; + } + break; + } + } + } + } + + return 0; +} + void _initialize_utils (void) { diff --git a/gdb/utils.h b/gdb/utils.h index b2347629296..c1195f65b50 100644 --- a/gdb/utils.h +++ b/gdb/utils.h @@ -559,4 +559,11 @@ extern void dump_core (void); extern char *make_hex_string (const gdb_byte *data, size_t length); +/* Find an instance of the character C in the string S that is outside + of all parenthesis pairs, single-quoted strings, and double-quoted + strings. Also, ignore the char within a template name, like a ',' + within foo. */ + +extern const char *find_toplevel_char (const char *s, char c); + #endif /* UTILS_H */