static struct symtab *symtab_from_filename (char **argptr,
char *p, int is_quote_enclosed);
+static struct
+symtabs_and_lines decode_all_digits (char **argptr,
+ struct symtab *default_symtab,
+ int default_line,
+ char ***canonical,
+ struct symtab *s,
+ char *q);
+
+static struct symtabs_and_lines decode_dollar (char *copy,
+ int funfirstline,
+ struct symtab *default_symtab,
+ char ***canonical,
+ struct symtab *s);
+
+static struct symtabs_and_lines decode_variable (char *copy,
+ int funfirstline,
+ char ***canonical,
+ struct symtab *s);
+
static struct
symtabs_and_lines symbol_found (int funfirstline,
char ***canonical,
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;
struct symtab *s = NULL;
- struct symbol *sym;
- /* The symtab that SYM was found in. */
- struct symtab *sym_symtab;
-
- struct minimal_symbol *msymbol;
char *copy;
/* This is NULL if there are no parens in *ARGPTR, or a pointer to
the closing parenthesis if there are parens. */
int is_quote_enclosed;
char *saved_arg = *argptr;
- init_sal (&val); /* initialize to zeroes */
-
/* Defaults have defaults. */
initialize_defaults (&default_symtab, &default_line);
q++;
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)
- {
- /* Make sure we have at least a default source file. */
- set_default_source_symtab_and_line ();
- initialize_defaults (&default_symtab, &default_line);
- }
-
- 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. */
- }
-
- 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;
- }
+ /* We found a token consisting of all digits -- at least one digit. */
+ return decode_all_digits (argptr, default_symtab, default_line,
+ canonical, s, q);
/* Arg token is not digits => try it as a variable name
Find the next token (everything up to end or next whitespace). */
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. */
- if (sym)
- return 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);
- /* Min symbol was found --> jump to minsym processing. */
- if (msymbol)
- return minsym_found (funfirstline, msymbol);
-
- /* 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;
- }
-
+ return decode_dollar (copy, funfirstline, default_symtab,
+ canonical, s);
/* 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);
-
- if (sym != NULL)
- return symbol_found (funfirstline, canonical, copy, sym, s, sym_symtab);
-
- msymbol = lookup_minimal_symbol (copy, NULL, NULL);
-
- if (msymbol != NULL)
- return 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);
- return values; /* for lint */
+ return decode_variable (copy, funfirstline, canonical, s);
}
\f
return s;
}
+\f
+
+/* This decodes a line where the argument is all digits (possibly
+ preceded by a sign). Q should point to the end of those digits;
+ the other arguments are as usual. */
+
+static struct symtabs_and_lines
+decode_all_digits (char **argptr, struct symtab *default_symtab,
+ int default_line, char ***canonical,
+ struct symtab *s, char *q)
+
+{
+ struct symtabs_and_lines values;
+ struct symtab_and_line val;
+
+ 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;
+
+ init_sal (&val);
+
+ /* 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)
+ {
+ /* Make sure we have at least a default source file. */
+ set_default_source_symtab_and_line ();
+ initialize_defaults (&default_symtab, &default_line);
+ }
+
+ 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. */
+ }
+
+ 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;
+}
+
+\f
+
+/* Decode a linespec starting with a dollar sign. */
+
+static struct symtabs_and_lines
+decode_dollar (char *copy, int funfirstline, struct symtab *default_symtab,
+ char ***canonical, struct symtab *s)
+{
+ struct value *valx;
+ int index = 0;
+ int need_canonical = 0;
+ struct symtabs_and_lines values;
+ struct symtab_and_line val;
+ char *p;
+ struct symbol *sym;
+ /* The symtab that SYM was found in. */
+ struct symtab *sym_symtab;
+ struct minimal_symbol *msymbol;
+
+ 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. */
+ if (sym)
+ return 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);
+ /* Min symbol was found --> jump to minsym processing. */
+ if (msymbol)
+ return minsym_found (funfirstline, msymbol);
+
+ /* 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.");
+ }
+
+ init_sal (&val);
+
+ /* 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;
+}
+
+\f
+
+/* Decode a linespec that's a variable. If S is non-NULL,
+ look in that symtab's static variables first. */
+
+static struct symtabs_and_lines
+decode_variable (char *copy, int funfirstline, char ***canonical,
+ struct symtab *s)
+{
+ struct symbol *sym;
+ /* The symtab that SYM was found in. */
+ struct symtab *sym_symtab;
+
+ struct minimal_symbol *msymbol;
+
+ sym = lookup_symbol (copy,
+ (s ? BLOCKVECTOR_BLOCK (BLOCKVECTOR (s), STATIC_BLOCK)
+ : get_selected_block (0)),
+ VAR_NAMESPACE, 0, &sym_symtab);
+
+ if (sym != NULL)
+ return symbol_found (funfirstline, canonical, copy, sym, s, sym_symtab);
+
+ msymbol = lookup_minimal_symbol (copy, NULL, NULL);
+
+ if (msymbol != NULL)
+ return 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);
+}
+
\f