aboutsummaryrefslogtreecommitdiff
path: root/gdb/utils.c
diff options
context:
space:
mode:
Diffstat (limited to 'gdb/utils.c')
-rw-r--r--gdb/utils.c134
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;