aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDavid Carlton <carlton@bactrian.org>2002-11-02 01:37:03 +0000
committerDavid Carlton <carlton@bactrian.org>2002-11-02 01:37:03 +0000
commit5a4200a2fcf25cf312886b34a7c6cfee4ef1fc76 (patch)
tree74065eae9ba9f121601e7b0ce2c80a9aedf00b1a
parenta7b76e0b12c9172d953edb0e3e61e3ddb51d07cf (diff)
downloadgdb-5a4200a2fcf25cf312886b34a7c6cfee4ef1fc76.zip
gdb-5a4200a2fcf25cf312886b34a7c6cfee4ef1fc76.tar.gz
gdb-5a4200a2fcf25cf312886b34a7c6cfee4ef1fc76.tar.bz2
2002-11-01 David Carlton <carlton@math.stanford.edu>
* linespec.c (dl1_set_flags): Change arguments. (dl1_compound): Rename from dl1_multipart_compound, and shuffle components. (dl1_examine_compound_token): Change call structure. (dl1_find_method): Ditto. (dl1_handle_filename): Ditto. (dl1_is_all_digits): New function. (dl1_all_digits): Ditto. (dl1_skip_digits): Ditto. (dl1_dollar): Ditto. (dl1_variable): Ditto. (dl1_symbol_found): Ditto. (dl1_minsym_found): Ditto. (decode_line_1): Slim down dramatically.
-rw-r--r--gdb/ChangeLog17
-rw-r--r--gdb/linespec.c920
2 files changed, 485 insertions, 452 deletions
diff --git a/gdb/ChangeLog b/gdb/ChangeLog
index 6881a77..b11fc65 100644
--- a/gdb/ChangeLog
+++ b/gdb/ChangeLog
@@ -1,3 +1,20 @@
+2002-11-01 David Carlton <carlton@math.stanford.edu>
+
+ * linespec.c (dl1_set_flags): Change arguments.
+ (dl1_compound): Rename from dl1_multipart_compound, and shuffle
+ components.
+ (dl1_examine_compound_token): Change call structure.
+ (dl1_find_method): Ditto.
+ (dl1_handle_filename): Ditto.
+ (dl1_is_all_digits): New function.
+ (dl1_all_digits): Ditto.
+ (dl1_skip_digits): Ditto.
+ (dl1_dollar): Ditto.
+ (dl1_variable): Ditto.
+ (dl1_symbol_found): Ditto.
+ (dl1_minsym_found): Ditto.
+ (decode_line_1): Slim down dramatically.
+
2002-10-31 David Carlton <carlton@math.stanford.edu>
* linespec.c (dl1_handle_multipart): New function.
diff --git a/gdb/linespec.c b/gdb/linespec.c
index 3a2aa86..05a29d4 100644
--- a/gdb/linespec.c
+++ b/gdb/linespec.c
@@ -59,63 +59,76 @@ static void dl1_initialize_defaults (struct symtab **default_symtab,
static struct symtabs_and_lines dl1_indirect (char **argptr);
-static void dl1_set_flags (char **argptr, int *is_quoted,
+static void dl1_set_flags (char *arg, int *is_quoted,
char **paren_pointer);
-enum dl1_control_flow { DO_NOTHING, DO_RETURN, DO_SYMBOL_FOUND };
+static char *dl1_locate_first_half (char **argptr, int *is_quote_enclosed);
+
+static struct symtabs_and_lines dl1_compound (char **argptr,
+ int funfirstline,
+ char ***canonical,
+ char *saved_arg,
+ char *p);
-static enum
-dl1_control_flow dl1_handle_multipart (char **argptr,
+static int dl1_examine_compound_token (char **argptr,
int funfirstline,
char ***canonical,
char *saved_arg,
- int is_quoted,
- char *paren_pointer,
- char **temp_copy,
- struct symbol **sym,
- struct symtab **sym_symtab,
- struct symtab **s,
+ char *p,
struct symtabs_and_lines *values);
-static char *dl1_locate_first_half (char **argptr, int *is_quote_enclosed);
-
-static enum
-dl1_control_flow dl1_multipart_compound (char **argptr,
- int funfirstline,
- char ***canonical,
- char *saved_arg,
- char *p,
- char **temp_copy,
- struct symbol **sym,
- struct symtab **sym_symtab,
- struct symtab **s,
- struct symtabs_and_lines *values);
-
-static enum
-dl1_control_flow dl1_examine_compound_token (char **argptr,
- int funfirstline,
- char ***canonical,
- char *saved_arg,
- char *p,
- struct symtabs_and_lines *values);
-
static struct symbol *dl1_locate_class_sym (char **argptr, char *p);
static char *dl1_find_next_token (char **argptr);
-static void dl1_find_method (int funfirstline, char ***canonical,
- char *saved_arg, char *copy,
- struct type *t,
- struct symbol *sym_class,
- struct symbol **sym_arr,
- struct symtabs_and_lines *values);
+static struct symtabs_and_lines dl1_find_method (int funfirstline,
+ char ***canonical,
+ char *saved_arg,
+ char *copy,
+ struct type *t,
+ struct symbol *sym_class,
+ struct symbol **sym_arr);
static int dl1_count_methods (char *copy, struct type *t,
struct symbol **sym_arr);
-static void dl1_handle_filename (char **argptr, char *p,
- int is_quote_enclosed,
- struct symtab **s);
+static struct symtab *dl1_handle_filename (char **argptr, char *p,
+ int is_quote_enclosed);
+
+static int dl1_is_all_digits (char *arg);
+
+static struct symtabs_and_lines dl1_all_digits (char **argptr,
+ struct symtab *default_symtab,
+ int default_line,
+ char ***canonical,
+ struct symtab *file_symtab);
+
+static char *dl1_skip_digits (char *arg);
+
+static struct symtabs_and_lines dl1_dollar (char **argptr,
+ int funfirstline,
+ struct symtab *default_symtab,
+ char ***canonical,
+ struct symtab *file_symtab);
+
+static struct symtabs_and_lines dl1_variable (char **argptr,
+ int funfirstline,
+ char ***canonical,
+ int is_quoted,
+ char *paren_pointer,
+ struct symtab *file_symtab);
+
+static struct
+symtabs_and_lines dl1_symbol_found (int funfirstline,
+ char ***canonical,
+ char *copy,
+ struct symbol *sym,
+ struct symtab *file_symtab,
+ struct symtab *sym_symtab);
+
+static struct
+symtabs_and_lines dl1_minsym_found (int funfirstline,
+ struct minimal_symbol *msymbol);
/* Helper functions. */
@@ -572,27 +585,14 @@ struct symtabs_and_lines
decode_line_1 (char **argptr, int funfirstline, struct symtab *default_symtab,
int default_line, char ***canonical)
{
- struct symtabs_and_lines values;
- struct symtab_and_line val;
- char *p;
- char *q, *ii;
/* This is NULL if there are no parens in argptr, or a pointer to
the closing parenthesis if there are parens. */
char *paren_pointer;
- struct symtab *s = NULL;
-
- struct symbol *sym;
- /* The symtab that SYM was found in. */
- struct symtab *sym_symtab;
-
- struct minimal_symbol *msymbol;
- char *copy;
+ /* If a file name is specified, this is its symtab. */
+ struct symtab *file_symtab = NULL;
int is_quoted;
- int is_quote_enclosed;
char *saved_arg = *argptr;
- init_sal (&val); /* initialize to zeroes */
-
/* Defaults have defaults. */
dl1_initialize_defaults (&default_symtab, &default_line);
@@ -608,317 +608,60 @@ decode_line_1 (char **argptr, int funfirstline, struct symtab *default_symtab,
* (gdb) break c::f(int)
*/
- dl1_set_flags (argptr, &is_quoted, &paren_pointer);
+ dl1_set_flags (*argptr, &is_quoted, &paren_pointer);
- /* Handle multipart linespecs (with colons or periods). */
+ /* Check to see if it's a multipart linespec (with colons or periods). */
{
- /* The code after symbol_found depends on having access to a
- string 'copy' which is allocated via alloca. But we can't
- allocate via alloca within dl1_handle_multipart and still
- expect it to be valid after we exit. temp_copy will help us
- get around that. */
- char *temp_copy;
-
- switch (dl1_handle_multipart (argptr, funfirstline, canonical,
- saved_arg, is_quoted, paren_pointer,
- &temp_copy, &sym, &sym_symtab,
- &s, &values))
- {
- case DO_RETURN:
- return values;
- case DO_SYMBOL_FOUND:
- {
- int temp_copy_len = strlen (temp_copy);
- copy = (char *) alloca (temp_copy_len + 1);
- memcpy (copy, temp_copy, temp_copy_len + 1);
- xfree (temp_copy);
- goto symbol_found;
- }
- default:
- /* Do nothing. */
- ;
- }
- }
+ char *p;
+ int is_quote_enclosed;
+
+ /* Locate the first half of the linespec, ending in a colon, period,
+ or whitespace. (More or less.) */
- /* S is specified file's symtab, or 0 if no file specified.
- arg no longer contains the file name. */
+ p = dl1_locate_first_half (argptr, &is_quote_enclosed);
- /* Check whether arg is all digits (and sign) */
-
- q = *argptr;
- if (*q == '-' || *q == '+')
- q++;
- while (*q >= '0' && *q <= '9')
- q++;
+ /* Does it look like there actually were two parts? */
- if (q != *argptr && (*q == 0 || *q == ' ' || *q == '\t' || *q == ','))
- {
- /* We found a token consisting of all digits -- at least one digit. */
- enum sign
- {
- none, plus, minus
- }
- sign = none;
-
- /* We might need a canonical line spec if no file was specified. */
- int need_canonical = (s == 0) ? 1 : 0;
-
- /* This is where we need to make sure that we have good defaults.
- We must guarantee that this section of code is never executed
- when we are called with just a function name, since
- set_default_source_symtab_and_line uses
- select_source_symtab that calls us with such an argument */
-
- if (s == 0 && default_symtab == 0)
- {
- struct symtab_and_line cursal;
+ if ((p[0] == ':' || p[0] == '.') && paren_pointer == NULL)
+ {
+ if (is_quoted)
+ *argptr = *argptr + 1;
+
+ /* Is it a C++ or Java compound data structure? */
+
+ if (p[0] == '.' || p[1] == ':')
+ return dl1_compound (argptr, funfirstline, canonical,
+ saved_arg, p);
- /* Make sure we have at least a default source file. */
- set_default_source_symtab_and_line ();
- cursal = get_current_source_symtab_and_line ();
+ /* No, the first part is a filename; set file_symtab
+ accordingly. Also, move argptr past the filename. */
- default_symtab = cursal.symtab;
- default_line = cursal.line;
- }
+ file_symtab = dl1_handle_filename (argptr, p, is_quote_enclosed);
+ }
+ }
- if (**argptr == '+')
- sign = plus, (*argptr)++;
- else if (**argptr == '-')
- sign = minus, (*argptr)++;
- val.line = atoi (*argptr);
- switch (sign)
- {
- case plus:
- if (q == *argptr)
- val.line = 5;
- if (s == 0)
- val.line = default_line + val.line;
- break;
- case minus:
- if (q == *argptr)
- val.line = 15;
- if (s == 0)
- val.line = default_line - val.line;
- else
- val.line = 1;
- break;
- case none:
- break; /* No need to adjust val.line. */
- }
+ /* Check whether arg is all digits (and sign) */
- while (*q == ' ' || *q == '\t')
- q++;
- *argptr = q;
- if (s == 0)
- s = default_symtab;
-
- /* It is possible that this source file has more than one symtab,
- and that the new line number specification has moved us from the
- default (in s) to a new one. */
- val.symtab = find_line_symtab (s, val.line, NULL, NULL);
- if (val.symtab == 0)
- val.symtab = s;
-
- val.pc = 0;
- values.sals = (struct symtab_and_line *)
- xmalloc (sizeof (struct symtab_and_line));
- values.sals[0] = val;
- values.nelts = 1;
- if (need_canonical)
- build_canonical_line_spec (values.sals, NULL, canonical);
- return values;
- }
+ if (dl1_is_all_digits (*argptr))
+ return dl1_all_digits (argptr, default_symtab, default_line,
+ canonical, file_symtab);
/* Arg token is not digits => try it as a variable name
Find the next token (everything up to end or next whitespace). */
- if (**argptr == '$') /* May be a convenience variable */
- p = skip_quoted (*argptr + (((*argptr)[1] == '$') ? 2 : 1)); /* One or two $ chars possible */
- else if (is_quoted)
- {
- p = skip_quoted (*argptr);
- if (p[-1] != '\'')
- error ("Unmatched single quote.");
- }
- else if (paren_pointer != NULL)
- {
- p = paren_pointer + 1;
- }
- else
- {
- p = skip_quoted (*argptr);
- }
-
- copy = (char *) alloca (p - *argptr + 1);
- memcpy (copy, *argptr, p - *argptr);
- copy[p - *argptr] = '\0';
- if (p != *argptr
- && copy[0]
- && copy[0] == copy[p - *argptr - 1]
- && strchr (get_gdb_completer_quote_characters (), copy[0]) != NULL)
- {
- copy[p - *argptr - 1] = '\0';
- copy++;
- }
- while (*p == ' ' || *p == '\t')
- p++;
- *argptr = p;
-
/* If it starts with $: may be a legitimate variable or routine name
(e.g. HP-UX millicode routines such as $$dyncall), or it may
be history value, or it may be a convenience variable */
-
- if (*copy == '$')
- {
- struct value *valx;
- int index = 0;
- int need_canonical = 0;
-
- p = (copy[1] == '$') ? copy + 2 : copy + 1;
- while (*p >= '0' && *p <= '9')
- p++;
- if (!*p) /* reached end of token without hitting non-digit */
- {
- /* We have a value history reference */
- sscanf ((copy[1] == '$') ? copy + 2 : copy + 1, "%d", &index);
- valx = access_value_history ((copy[1] == '$') ? -index : index);
- if (TYPE_CODE (VALUE_TYPE (valx)) != TYPE_CODE_INT)
- error ("History values used in line specs must have integer values.");
- }
- else
- {
- /* Not all digits -- may be user variable/function or a
- convenience variable */
-
- /* Look up entire name as a symbol first */
- sym = lookup_symbol (copy, 0, VAR_NAMESPACE, 0, &sym_symtab);
- s = (struct symtab *) 0;
- need_canonical = 1;
- /* Symbol was found --> jump to normal symbol processing.
- Code following "symbol_found" expects "copy" to have the
- symbol name, "sym" to have the symbol pointer, "s" to be
- a specified file's symtab, and sym_symtab to be the symbol's
- symtab. */
- if (sym)
- goto symbol_found;
-
- /* If symbol was not found, look in minimal symbol tables */
- msymbol = lookup_minimal_symbol (copy, NULL, NULL);
- /* Min symbol was found --> jump to minsym processing. */
- if (msymbol)
- goto minimal_symbol_found;
-
- /* Not a user variable or function -- must be convenience variable */
- need_canonical = (s == 0) ? 1 : 0;
- valx = value_of_internalvar (lookup_internalvar (copy + 1));
- if (TYPE_CODE (VALUE_TYPE (valx)) != TYPE_CODE_INT)
- error ("Convenience variables used in line specs must have integer values.");
- }
-
- /* Either history value or convenience value from above, in valx */
- val.symtab = s ? s : default_symtab;
- val.line = value_as_long (valx);
- val.pc = 0;
-
- values.sals = (struct symtab_and_line *) xmalloc (sizeof val);
- values.sals[0] = val;
- values.nelts = 1;
-
- if (need_canonical)
- build_canonical_line_spec (values.sals, NULL, canonical);
-
- return values;
- }
-
-
+
+ if (**argptr == '$')
+ return dl1_dollar (argptr, funfirstline, default_symtab, canonical,
+ file_symtab);
+
/* Look up that token as a variable.
If file specified, use that file's per-file block to start with. */
- sym = lookup_symbol (copy,
- (s ? BLOCKVECTOR_BLOCK (BLOCKVECTOR (s), STATIC_BLOCK)
- : get_selected_block (0)),
- VAR_NAMESPACE, 0, &sym_symtab);
-
-symbol_found: /* We also jump here from inside the C++ class/namespace
- code on finding a symbol of the form "A::B::C" */
-
- if (sym != NULL)
- {
- if (SYMBOL_CLASS (sym) == LOC_BLOCK)
- {
- /* Arg is the name of a function */
- values.sals = (struct symtab_and_line *)
- xmalloc (sizeof (struct symtab_and_line));
- values.sals[0] = find_function_start_sal (sym, funfirstline);
- values.nelts = 1;
-
- /* Don't use the SYMBOL_LINE; if used at all it points to
- the line containing the parameters or thereabouts, not
- the first line of code. */
-
- /* We might need a canonical line spec if it is a static
- function. */
- if (s == 0)
- {
- struct blockvector *bv = BLOCKVECTOR (sym_symtab);
- struct block *b = BLOCKVECTOR_BLOCK (bv, STATIC_BLOCK);
- if (lookup_block_symbol (b, copy, NULL, VAR_NAMESPACE) != NULL)
- build_canonical_line_spec (values.sals, copy, canonical);
- }
- return values;
- }
- else
- {
- if (funfirstline)
- error ("\"%s\" is not a function", copy);
- else if (SYMBOL_LINE (sym) != 0)
- {
- /* We know its line number. */
- values.sals = (struct symtab_and_line *)
- xmalloc (sizeof (struct symtab_and_line));
- values.nelts = 1;
- memset (&values.sals[0], 0, sizeof (values.sals[0]));
- values.sals[0].symtab = sym_symtab;
- values.sals[0].line = SYMBOL_LINE (sym);
- return values;
- }
- else
- /* This can happen if it is compiled with a compiler which doesn't
- put out line numbers for variables. */
- /* FIXME: Shouldn't we just set .line and .symtab to zero
- and return? For example, "info line foo" could print
- the address. */
- error ("Line number not known for symbol \"%s\"", copy);
- }
- }
-
- msymbol = lookup_minimal_symbol (copy, NULL, NULL);
-
-minimal_symbol_found: /* We also jump here from the case for variables
- that begin with '$' */
-
- if (msymbol != NULL)
- {
- values.sals = (struct symtab_and_line *)
- xmalloc (sizeof (struct symtab_and_line));
- values.sals[0] = find_pc_sect_line (SYMBOL_VALUE_ADDRESS (msymbol),
- (struct sec *) 0, 0);
- values.sals[0].section = SYMBOL_BFD_SECTION (msymbol);
- if (funfirstline)
- {
- values.sals[0].pc += FUNCTION_START_OFFSET;
- values.sals[0].pc = SKIP_PROLOGUE (values.sals[0].pc);
- }
- values.nelts = 1;
- return values;
- }
-
- if (!have_full_symbols () &&
- !have_partial_symbols () && !have_minimal_symbols ())
- error ("No symbol table is loaded. Use the \"file\" command.");
-
- error ("Function \"%s\" not defined.", copy);
- return values; /* for lint */
+ return dl1_variable (argptr, funfirstline, canonical, is_quoted,
+ paren_pointer, file_symtab);
}
/* Now come a bunch of helper functions for decode_line_1. Warning:
@@ -966,7 +709,7 @@ dl1_indirect (char **argptr)
}
static void
-dl1_set_flags (char **argptr, int *is_quoted, char **paren_pointer)
+dl1_set_flags (char *arg, int *is_quoted, char **paren_pointer)
{
char *ii;
int has_if = 0;
@@ -974,12 +717,12 @@ dl1_set_flags (char **argptr, int *is_quoted, char **paren_pointer)
/* 'has_if' is for the syntax:
* (gdb) break foo if (a==b)
*/
- if ((ii = strstr (*argptr, " if ")) != NULL ||
- (ii = strstr (*argptr, "\tif ")) != NULL ||
- (ii = strstr (*argptr, " if\t")) != NULL ||
- (ii = strstr (*argptr, "\tif\t")) != NULL ||
- (ii = strstr (*argptr, " if(")) != NULL ||
- (ii = strstr (*argptr, "\tif( ")) != NULL)
+ if ((ii = strstr (arg, " if ")) != NULL ||
+ (ii = strstr (arg, "\tif ")) != NULL ||
+ (ii = strstr (arg, " if\t")) != NULL ||
+ (ii = strstr (arg, "\tif\t")) != NULL ||
+ (ii = strstr (arg, " if(")) != NULL ||
+ (ii = strstr (arg, "\tif( ")) != NULL)
has_if = 1;
/* Temporarily zap out "if (condition)" to not
* confuse the parenthesis-checking code below.
@@ -998,11 +741,11 @@ dl1_set_flags (char **argptr, int *is_quoted, char **paren_pointer)
/* Maybe arg is FILE : LINENUM or FILE : FUNCTION */
- *is_quoted = (**argptr
+ *is_quoted = (*arg
&& strchr (get_gdb_completer_quote_characters (),
- **argptr) != NULL);
+ *arg) != NULL);
- *paren_pointer = strchr (*argptr, '(');
+ *paren_pointer = strchr (arg, '(');
if (*paren_pointer != NULL)
*paren_pointer = strrchr (*paren_pointer, ')');
@@ -1014,47 +757,6 @@ dl1_set_flags (char **argptr, int *is_quoted, char **paren_pointer)
*ii = ' ';
}
-static enum dl1_control_flow
-dl1_handle_multipart (char **argptr, int funfirstline, char ***canonical,
- char *saved_arg, int is_quoted, char *paren_pointer,
- char **temp_copy,
- struct symbol **sym, struct symtab **sym_symtab,
- struct symtab **s,
- struct symtabs_and_lines *values)
-{
- char *p;
- int is_quote_enclosed;
-
- /* Locate the first half of the linespec, ending in a colon, period,
- or whitespace. (More or less.) */
-
- p = dl1_locate_first_half (argptr, &is_quote_enclosed);
-
- /* Does it look like there actually were two parts? */
-
- if ((p[0] == ':' || p[0] == '.') && paren_pointer == NULL)
- {
- if (is_quoted)
- *argptr = *argptr + 1;
-
- /* Is it a C++ or Java compound data structure? */
-
- if (p[0] == '.' || p[1] == ':')
- {
- return dl1_multipart_compound (argptr, funfirstline, canonical,
- saved_arg, p, temp_copy, sym,
- sym_symtab, s, values);
- }
-
- /* No, the first part is a filename; update argptr and s
- accordingly. */
-
- dl1_handle_filename (argptr, p, is_quote_enclosed, s);
- }
-
- return DO_NOTHING;
-}
-
static char *
dl1_locate_first_half (char **argptr, int *is_quote_enclosed)
{
@@ -1145,17 +847,16 @@ dl1_locate_first_half (char **argptr, int *is_quote_enclosed)
return p;
}
-static enum dl1_control_flow
-dl1_multipart_compound (char **argptr, int funfirstline, char ***canonical,
- char *saved_arg, char *p,
- char **temp_copy, struct symbol **sym,
- struct symtab **sym_symtab,
- struct symtab **s,
- struct symtabs_and_lines *values)
+static struct symtabs_and_lines
+dl1_compound (char **argptr, int funfirstline, char ***canonical,
+ char *saved_arg, char *p)
{
char *saved_arg2 = *argptr;
char *temp_end;
char *p2;
+ char *copy;
+ struct symtab *sym_symtab;
+ struct symbol *sym;
/* First check for "global" namespace specification,
of the form "::foo". If found, skip over the colons
@@ -1187,12 +888,11 @@ dl1_multipart_compound (char **argptr, int funfirstline, char ***canonical,
p2 = p; /* save for restart */
while (1)
{
- enum dl1_control_flow do_next
- = dl1_examine_compound_token (argptr, funfirstline, canonical,
- saved_arg, p, values);
-
- if (do_next != DO_NOTHING)
- return do_next;
+ struct symtabs_and_lines values;
+
+ if (dl1_examine_compound_token (argptr, funfirstline, canonical,
+ saved_arg, p, &values))
+ return values;
/* Move pointer up to next possible class/namespace token */
p = p2 + 1; /* restart with old value +1 */
@@ -1213,45 +913,34 @@ dl1_multipart_compound (char **argptr, int funfirstline, char ***canonical,
}
if (*p != ':')
- break; /* out of the while (1) */
+ break;
p2 = p; /* save restart for next time around */
*argptr = saved_arg2; /* restore argptr */
- } /* while (1) */
+ }
/* Last chance attempt -- check entire name as a symbol */
- /* Use "temp_copy" in preparation for jumping out of the block
- after we make it back to decode_line_1. */
- *temp_copy = xmalloc (p - saved_arg2 + 1);
- memcpy (*temp_copy, saved_arg2, p - saved_arg2);
+ copy = alloca (p - saved_arg2 + 1);
+ memcpy (copy, saved_arg2, p - saved_arg2);
/* Note: if is_quoted should be true, we snuff out quote here anyway */
- (*temp_copy)[p - saved_arg2] = '\000';
+ copy[p - saved_arg2] = '\0';
/* Set argptr to skip over the name */
*argptr = (*p == '\'') ? p + 1 : p;
/* Look up entire name */
- *sym = lookup_symbol (*temp_copy, 0, VAR_NAMESPACE, 0, sym_symtab);
- *s = (struct symtab *) 0;
- /* Prepare to jump: restore the " if (condition)" so outer layers see it */
- /* Symbol was found --> jump to normal symbol processing.
- Code following "symbol_found" expects "copy" to have the
- symbol name, "sym" to have the symbol pointer, "s" to be
- a specified file's symtab, and sym_symtab to be the symbol's
- symtab. */
- /* By jumping there we avoid falling through the FILE:LINE and
- FILE:FUNC processing stuff below */
- if (*sym)
- return DO_SYMBOL_FOUND;
+ sym = lookup_symbol (copy, 0, VAR_NAMESPACE, 0, &sym_symtab);
+
+ if (sym != NULL)
+ return dl1_symbol_found (funfirstline, canonical, copy,
+ sym, NULL, sym_symtab);
/* Couldn't find any interpretation as classes/namespaces, so give up */
- /* FIXME: carlton/2002-10-31: I should arrange for *temp_copy to be
- xfree'd. */
/* The quotes are important if copy is empty. */
cplusplus_error (saved_arg,
"Can't find member of namespace, class, struct, or union named \"%s\"\n",
- *temp_copy);
+ copy);
}
-static enum dl1_control_flow
+static int
dl1_examine_compound_token (char **argptr, int funfirstline,
char ***canonical,
char *saved_arg, char *p,
@@ -1295,14 +984,14 @@ dl1_examine_compound_token (char **argptr, int funfirstline,
sym_arr = (struct symbol **) alloca (total_number_of_methods (t)
* sizeof (struct symbol *));
- dl1_find_method (funfirstline, canonical, saved_arg, copy, t,
- sym_class, sym_arr, values);
+ *values = dl1_find_method (funfirstline, canonical, saved_arg, copy,
+ t, sym_class, sym_arr);
- return DO_RETURN;
+ return 1;
}
else
{
- return DO_NOTHING;
+ return 0;
}
}
@@ -1351,12 +1040,12 @@ dl1_find_next_token (char **argptr)
return p;
}
-static void
+static struct symtabs_and_lines
dl1_find_method (int funfirstline, char ***canonical, char *saved_arg,
char *copy, struct type *t, struct symbol *sym_class,
- struct symbol **sym_arr,
- struct symtabs_and_lines *values)
+ struct symbol **sym_arr)
{
+ struct symtabs_and_lines values;
int i1 = dl1_count_methods (copy, t, sym_arr);
if (i1 == 1)
@@ -1366,20 +1055,20 @@ dl1_find_method (int funfirstline, char ***canonical, char *saved_arg,
if (sym && SYMBOL_CLASS (sym) == LOC_BLOCK)
{
- values->sals = xmalloc (sizeof (struct symtab_and_line));
- values->nelts = 1;
- values->sals[0] = find_function_start_sal (sym, funfirstline);
+ values.sals = xmalloc (sizeof (struct symtab_and_line));
+ values.nelts = 1;
+ values.sals[0] = find_function_start_sal (sym, funfirstline);
}
else
{
- values->nelts = 0;
+ values.nelts = 0;
}
}
else if (i1 > 0)
{
/* There is more than one field with that name
(overloaded). Ask the user which one to use. */
- *values = decode_line_2 (sym_arr, i1, funfirstline, canonical);
+ values = decode_line_2 (sym_arr, i1, funfirstline, canonical);
}
else
{
@@ -1402,6 +1091,8 @@ dl1_find_method (int funfirstline, char ***canonical, char *saved_arg,
"the class %s does not have any method named %s\n",
SYMBOL_SOURCE_NAME (sym_class), tmp);
}
+
+ return values;
}
static int
@@ -1432,12 +1123,12 @@ dl1_count_methods (char *copy, struct type *t, struct symbol **sym_arr)
return i1;
}
-static void
-dl1_handle_filename (char **argptr, char *p, int is_quote_enclosed,
- struct symtab **s)
+static struct symtab *
+dl1_handle_filename (char **argptr, char *p, int is_quote_enclosed)
{
char *p1;
char *copy;
+ struct symtab *s;
/* Extract the file name. */
p1 = p;
@@ -1454,8 +1145,8 @@ dl1_handle_filename (char **argptr, char *p, int is_quote_enclosed,
copy[p - *argptr] = 0;
/* Find that file's data. */
- *s = lookup_symtab (copy);
- if (*s == 0)
+ s = lookup_symtab (copy);
+ if (s == NULL)
{
if (!have_full_symbols () && !have_partial_symbols ())
error ("No symbol table is loaded. Use the \"file\" command.");
@@ -1467,4 +1158,329 @@ dl1_handle_filename (char **argptr, char *p, int is_quote_enclosed,
while (*p == ' ' || *p == '\t')
p++;
*argptr = p;
+
+ return s;
+}
+
+static int
+dl1_is_all_digits (char *arg)
+{
+ char *q = dl1_skip_digits (arg);
+
+ return q != arg && (*q == 0 || *q == ' ' || *q == '\t' || *q == ',');
+}
+
+static struct symtabs_and_lines
+dl1_all_digits (char **argptr, struct symtab *default_symtab,
+ int default_line, char ***canonical,
+ struct symtab *file_symtab)
+{
+ struct symtabs_and_lines values;
+ struct symtab_and_line val;
+ char *end_of_digits = dl1_skip_digits (*argptr);
+
+ enum sign
+ {
+ none, plus, minus
+ }
+ sign = none;
+
+ init_sal (&val);
+
+ /* We might need a canonical line spec if no file was specified. */
+ int need_canonical = (file_symtab == NULL) ? 1 : 0;
+
+ /* This is where we need to make sure that we have good defaults.
+ We must guarantee that this section of code is never executed
+ when we are called with just a function name, since
+ set_default_source_symtab_and_line uses
+ select_source_symtab that calls us with such an argument */
+
+ if (file_symtab == NULL && default_symtab == NULL)
+ {
+ struct symtab_and_line cursal;
+
+ /* Make sure we have at least a default source file. */
+ set_default_source_symtab_and_line ();
+ cursal = get_current_source_symtab_and_line ();
+
+ default_symtab = cursal.symtab;
+ default_line = cursal.line;
+ }
+
+ if (**argptr == '+')
+ sign = plus, (*argptr)++;
+ else if (**argptr == '-')
+ sign = minus, (*argptr)++;
+ val.line = atoi (*argptr);
+ switch (sign)
+ {
+ case plus:
+ if (end_of_digits == *argptr)
+ val.line = 5;
+ if (file_symtab == NULL)
+ val.line = default_line + val.line;
+ break;
+ case minus:
+ if (end_of_digits == *argptr)
+ val.line = 15;
+ if (file_symtab == NULL)
+ val.line = default_line - val.line;
+ else
+ val.line = 1;
+ break;
+ case none:
+ break; /* No need to adjust val.line. */
+ }
+
+ while (*end_of_digits == ' ' || *end_of_digits == '\t')
+ end_of_digits++;
+ *argptr = end_of_digits;
+ if (file_symtab == 0)
+ file_symtab = default_symtab;
+
+ /* It is possible that this source file has more than one symtab,
+ and that the new line number specification has moved us from the
+ default (in file_symtab) to a new one. */
+ val.symtab = find_line_symtab (file_symtab, val.line, NULL, NULL);
+ if (val.symtab == 0)
+ val.symtab = file_symtab;
+
+ val.pc = 0;
+ values.sals = xmalloc (sizeof (struct symtab_and_line));
+ values.sals[0] = val;
+ values.nelts = 1;
+ if (need_canonical)
+ build_canonical_line_spec (values.sals, NULL, canonical);
+ return values;
+}
+
+static char *
+dl1_skip_digits (char *arg)
+{
+ if (*arg == '-' || *arg == '+')
+ arg++;
+ while (*arg >= '0' && *arg <= '9')
+ arg++;
+
+ return arg;
+}
+
+static struct symtabs_and_lines
+dl1_dollar (char **argptr, int funfirstline, struct symtab *default_symtab,
+ char ***canonical, struct symtab *file_symtab)
+{
+ struct value *valx;
+ int index = 0;
+ int need_canonical = 0;
+ char *p;
+ struct symtabs_and_lines values;
+ char *copy;
+
+ /* One or two $ chars possible */
+ p = skip_quoted (*argptr + (((*argptr)[1] == '$') ? 2 : 1));
+
+ copy = (char *) alloca (p - *argptr + 1);
+ memcpy (copy, *argptr, p - *argptr);
+ copy[p - *argptr] = '\0';
+
+ while (*p == ' ' || *p == '\t')
+ p++;
+ *argptr = p;
+
+ p = (copy[1] == '$') ? copy + 2 : copy + 1;
+ while (*p >= '0' && *p <= '9')
+ p++;
+ if (!*p) /* reached end of token without hitting non-digit */
+ {
+ /* We have a value history reference */
+ sscanf ((copy[1] == '$') ? copy + 2 : copy + 1, "%d", &index);
+ valx = access_value_history ((copy[1] == '$') ? -index : index);
+ if (TYPE_CODE (VALUE_TYPE (valx)) != TYPE_CODE_INT)
+ error ("History values used in line specs must have integer values.");
+ }
+ else
+ {
+ /* Not all digits -- may be user variable/function or a
+ convenience variable */
+
+ struct symbol *sym;
+ struct symtab *sym_symtab;
+ struct minimal_symbol *msymbol;
+
+ /* Look up entire name as a symbol first */
+ sym = lookup_symbol (copy, 0, VAR_NAMESPACE, 0, &sym_symtab);
+ if (sym != NULL)
+ return dl1_symbol_found (funfirstline, canonical, copy,
+ sym, NULL, sym_symtab);
+
+ /* If symbol was not found, look in minimal symbol tables */
+ msymbol = lookup_minimal_symbol (copy, NULL, NULL);
+ if (msymbol != NULL)
+ return dl1_minsym_found (funfirstline, msymbol);
+
+ /* Not a user variable or function -- must be convenience variable */
+ file_symtab = NULL;
+ need_canonical = 1;
+ valx = value_of_internalvar (lookup_internalvar (copy + 1));
+ if (TYPE_CODE (VALUE_TYPE (valx)) != TYPE_CODE_INT)
+ error ("Convenience variables used in line specs must have integer values.");
+ }
+
+ /* Either history value or convenience value from above, in valx */
+ values.sals = xmalloc (sizeof (struct symtab_and_line));
+ init_sal (values.sals);
+ values.sals[0].symtab = file_symtab != NULL ? file_symtab : default_symtab;
+ values.sals[0].line = value_as_long (valx);
+ values.sals[0].pc = 0;
+ values.nelts = 1;
+
+ if (need_canonical)
+ build_canonical_line_spec (values.sals, NULL, canonical);
+
+ return values;
+}
+
+static struct symtabs_and_lines
+dl1_variable (char **argptr, int funfirstline, char ***canonical,
+ int is_quoted, char *paren_pointer,
+ struct symtab *file_symtab)
+{
+ char *p;
+ char *copy;
+ struct symbol *sym;
+ struct symtab *sym_symtab;
+ struct minimal_symbol *msymbol;
+
+ if (is_quoted)
+ {
+ p = skip_quoted (*argptr);
+ if (p[-1] != '\'')
+ error ("Unmatched single quote.");
+ }
+ else if (paren_pointer != NULL)
+ {
+ p = paren_pointer + 1;
+ }
+ else
+ {
+ p = skip_quoted (*argptr);
+ }
+
+ copy = (char *) alloca (p - *argptr + 1);
+ memcpy (copy, *argptr, p - *argptr);
+ copy[p - *argptr] = '\0';
+
+ /* If it's completer-quoted, get rid of the quotes. */
+
+ if (p != *argptr
+ && copy[0]
+ && copy[0] == copy[p - *argptr - 1]
+ && strchr (get_gdb_completer_quote_characters (), copy[0]) != NULL)
+ {
+ copy[p - *argptr - 1] = '\0';
+ copy++;
+ }
+
+ while (*p == ' ' || *p == '\t')
+ p++;
+ *argptr = p;
+
+ /* Look up that token as a variable.
+ If file specified, use that file's per-file block to start with. */
+
+ sym = lookup_symbol (copy,
+ (file_symtab != NULL
+ ? BLOCKVECTOR_BLOCK (BLOCKVECTOR (file_symtab),
+ STATIC_BLOCK)
+ : get_selected_block (0)),
+ VAR_NAMESPACE, 0, &sym_symtab);
+
+ if (sym != NULL)
+ {
+ return dl1_symbol_found (funfirstline, canonical, copy,
+ sym, file_symtab, sym_symtab);
+ }
+
+ msymbol = lookup_minimal_symbol (copy, NULL, NULL);
+
+ if (msymbol != NULL)
+ return dl1_minsym_found (funfirstline, msymbol);
+
+ if (!have_full_symbols () &&
+ !have_partial_symbols () && !have_minimal_symbols ())
+ error ("No symbol table is loaded. Use the \"file\" command.");
+
+ error ("Function \"%s\" not defined.", copy);
+}
+
+static struct symtabs_and_lines
+dl1_symbol_found (int funfirstline, char ***canonical, char *copy,
+ struct symbol *sym, struct symtab *file_symtab,
+ struct symtab *sym_symtab)
+{
+ struct symtabs_and_lines values;
+
+ if (SYMBOL_CLASS (sym) == LOC_BLOCK)
+ {
+ /* Arg is the name of a function */
+ values.sals = xmalloc (sizeof (struct symtab_and_line));
+ values.sals[0] = find_function_start_sal (sym, funfirstline);
+ values.nelts = 1;
+
+ /* Don't use the SYMBOL_LINE; if used at all it points to
+ the line containing the parameters or thereabouts, not
+ the first line of code. */
+
+ /* We might need a canonical line spec if it is a static
+ function. */
+ if (file_symtab == NULL)
+ {
+ struct blockvector *bv = BLOCKVECTOR (sym_symtab);
+ struct block *b = BLOCKVECTOR_BLOCK (bv, STATIC_BLOCK);
+ if (lookup_block_symbol (b, copy, NULL, VAR_NAMESPACE) != NULL)
+ build_canonical_line_spec (values.sals, copy, canonical);
+ }
+ return values;
+ }
+ else
+ {
+ if (funfirstline)
+ error ("\"%s\" is not a function", copy);
+ else if (SYMBOL_LINE (sym) != 0)
+ {
+ /* We know its line number. */
+ values.sals = xmalloc (sizeof (struct symtab_and_line));
+ values.nelts = 1;
+ memset (&values.sals[0], 0, sizeof (values.sals[0]));
+ values.sals[0].symtab = sym_symtab;
+ values.sals[0].line = SYMBOL_LINE (sym);
+ return values;
+ }
+ else
+ /* This can happen if it is compiled with a compiler which doesn't
+ put out line numbers for variables. */
+ /* FIXME: Shouldn't we just set .line and .symtab to zero
+ and return? For example, "info line foo" could print
+ the address. */
+ error ("Line number not known for symbol \"%s\"", copy);
+ }
+}
+
+static struct symtabs_and_lines
+dl1_minsym_found (int funfirstline, struct minimal_symbol *msymbol)
+{
+ struct symtabs_and_lines values;
+
+ values.sals = xmalloc (sizeof (struct symtab_and_line));
+ values.sals[0] = find_pc_sect_line (SYMBOL_VALUE_ADDRESS (msymbol),
+ (struct sec *) 0, 0);
+ values.sals[0].section = SYMBOL_BFD_SECTION (msymbol);
+ if (funfirstline)
+ {
+ values.sals[0].pc += FUNCTION_START_OFFSET;
+ values.sals[0].pc = SKIP_PROLOGUE (values.sals[0].pc);
+ }
+ values.nelts = 1;
+ return values;
}