diff options
Diffstat (limited to 'gdb/utils.c')
-rw-r--r-- | gdb/utils.c | 134 |
1 files changed, 134 insertions, 0 deletions
diff --git a/gdb/utils.c b/gdb/utils.c index 96ae709..c00bfd4 100644 --- a/gdb/utils.c +++ b/gdb/utils.c @@ -66,6 +66,7 @@ #include "interps.h" #include "gdb_regex.h" #include "job-control.h" +#include "cp-support.h" #if !HAVE_DECL_MALLOC extern PTR malloc (); /* ARI: PTR */ @@ -3277,6 +3278,139 @@ 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; +} + +/* See description in utils.h. */ + +const char * +find_toplevel_char_r (const char *s, size_t len, char c) +{ + int quoted = 0; + int depth = 0; + const char *scan; + + for (scan = s + len; scan >= s; --scan) + { + if (quoted) + { + if (*scan == quoted) + quoted = 0; + } + else if (*scan == ')' || *scan == '>') + ++depth; + else if ((*scan == '(' || *scan == '<') && depth > 0) + --depth; + + if (*scan == c && !quoted && depth == 0) + return scan; + else if ((*scan == '"' || *scan == '\'') + && scan > s && *(scan - 1) != '\\') + quoted = *scan; + } + + return NULL; +} + +/* See description in utils.h. */ + +const char * +find_toplevel_string (const char *haystack, const char *needle) +{ + const char *s = haystack; + + do + { + s = find_toplevel_char (s, *needle); + + if (s != NULL) + { + /* Found first char in HAYSTACK; check rest of string. */ + if (startswith (s, needle)) + return s; + + /* Didn't find it; loop over HAYSTACK, looking for the next + instance of the first character of NEEDLE. */ + ++s; + } + } + while (s != NULL && *s != '\0'); + + /* NEEDLE was not found in HAYSTACK. */ + return NULL; +} + /* Provide a prototype to silence -Wmissing-prototypes. */ extern initialize_file_ftype _initialize_utils; |