#include "cli/cli-utils.h"
#include "filenames.h"
#include "ada-lang.h"
+#include "stack.h"
typedef struct symtab *symtab_p;
DEF_VEC_P (symtab_p);
currently precludes the use of other members. */
/* The expression entered by the user. */
- char *expression;
+ const char *expression;
/* The resulting PC expression derived from evaluating EXPRESSION. */
CORE_ADDR expr_pc;
/* Any specified file symtabs. */
/* The user-supplied source filename or NULL if none was specified. */
- char *source_filename;
+ const char *source_filename;
/* The list of symtabs to search to which to limit the search. May not
be NULL. If SOURCE_FILENAME is NULL (no user-specified filename),
/* The user-specified function name. If no function name was
supplied, this may be NULL. */
- char *function_name;
+ const char *function_name;
/* A list of matching function symbols and minimal symbols. Both lists
may be NULL if no matching symbols were found. */
/* The name of a label and matching symbols. */
/* The user-specified label name. */
- char *label_name;
+ const char *label_name;
/* A structure of matching label symbols and the corresponding
function symbol in which the label was found. Both may be NULL
/* Lexer functions. */
/* Lex a number from the input in PARSER. This only supports
- decimal numbers. */
+ decimal numbers.
-static linespec_token
-linespec_lexer_lex_number (linespec_parser *parser)
-{
- linespec_token token;
+ Return true if input is decimal numbers. Return false if not. */
- token.type = LSTOKEN_NUMBER;
- LS_TOKEN_STOKEN (token).length = 0;
- LS_TOKEN_STOKEN (token).ptr = PARSER_STREAM (parser);
+static int
+linespec_lexer_lex_number (linespec_parser *parser, linespec_token *tokenp)
+{
+ tokenp->type = LSTOKEN_NUMBER;
+ LS_TOKEN_STOKEN (*tokenp).length = 0;
+ LS_TOKEN_STOKEN (*tokenp).ptr = PARSER_STREAM (parser);
/* Keep any sign at the start of the stream. */
if (*PARSER_STREAM (parser) == '+' || *PARSER_STREAM (parser) == '-')
{
- ++LS_TOKEN_STOKEN (token).length;
+ ++LS_TOKEN_STOKEN (*tokenp).length;
++(PARSER_STREAM (parser));
}
while (isdigit (*PARSER_STREAM (parser)))
{
- ++LS_TOKEN_STOKEN (token).length;
+ ++LS_TOKEN_STOKEN (*tokenp).length;
++(PARSER_STREAM (parser));
}
- return token;
+ /* If the next character in the input buffer is not a space, comma,
+ quote, or colon, this input does not represent a number. */
+ if (*PARSER_STREAM (parser) != '\0'
+ && !isspace (*PARSER_STREAM (parser)) && *PARSER_STREAM (parser) != ','
+ && *PARSER_STREAM (parser) != ':'
+ && !strchr (linespec_quote_characters, *PARSER_STREAM (parser)))
+ {
+ PARSER_STREAM (parser) = LS_TOKEN_STOKEN (*tokenp).ptr;
+ return 0;
+ }
+
+ return 1;
}
/* Does P represent one of the keywords? If so, return
case '+': case '-':
case '0': case '1': case '2': case '3': case '4':
case '5': case '6': case '7': case '8': case '9':
- parser->lexer.current = linespec_lexer_lex_number (parser);
+ if (!linespec_lexer_lex_number (parser, &(parser->lexer.current)))
+ parser->lexer.current = linespec_lexer_lex_string (parser);
break;
case ':':
/* Add SAL to SALS, and also update SELF->CANONICAL_NAMES to reflect
the new sal, if needed. If not NULL, SYMNAME is the name of the
- symbol to use when constructing the new canonical name. */
+ symbol to use when constructing the new canonical name.
+
+ If LITERAL_CANONICAL is non-zero, SYMNAME will be used as the
+ canonical name for the SAL. */
static void
add_sal_to_sals (struct linespec_state *self,
struct symtabs_and_lines *sals,
struct symtab_and_line *sal,
- const char *symname)
+ const char *symname, int literal_canonical)
{
add_sal_to_sals_basic (sals, sal);
self->canonical_names = xrealloc (self->canonical_names,
sals->nelts * sizeof (char *));
- if (sal->symtab && sal->symtab->filename)
+ if (!literal_canonical && sal->symtab && sal->symtab->filename)
{
char *filename = sal->symtab->filename;
else
canonical_name = xstrprintf ("%s:%d", filename, sal->line);
}
+ else if (symname != NULL)
+ canonical_name = xstrdup (symname);
self->canonical_names[sals->nelts - 1] = canonical_name;
}
VEC (const_char_ptr) **result_names,
VEC (typep) **superclasses)
{
- int i1 = 0;
int ibase;
const char *class_name = type_name_no_tag (t);
if (class_name)
{
int method_counter;
- int name_len = strlen (name);
CHECK_TYPEDEF (t);
FILENAME). */
static void ATTRIBUTE_NORETURN
-symbol_not_found_error (char *symbol, char *filename)
+symbol_not_found_error (const char *symbol, const char *filename)
{
if (symbol == NULL)
symbol = "";
/* Parse and return a line offset in STRING. */
static struct line_offset
-linespec_parse_line_offset (char *string)
+linespec_parse_line_offset (const char *string)
{
struct line_offset line_offset = {0, LINE_OFFSET_NONE};
found. */
intermediate_results.sals[i].line = val.line;
add_sal_to_sals (self, &values, &intermediate_results.sals[i],
- sym ? SYMBOL_NATURAL_NAME (sym) : NULL);
+ sym ? SYMBOL_NATURAL_NAME (sym) : NULL, 0);
}
do_cleanups (cleanup);
if (ls->expression != NULL)
{
+ struct symtab_and_line sal;
+
/* We have an expression. No other attribute is allowed. */
- sals.sals = XMALLOC (struct symtab_and_line);
- sals.nelts = 1;
- sals.sals[0] = find_pc_line (ls->expr_pc, 0);
- sals.sals[0].pc = ls->expr_pc;
- sals.sals[0].section = find_pc_overlay (ls->expr_pc);
- sals.sals[0].explicit_pc = 1;
+ sal = find_pc_line (ls->expr_pc, 0);
+ sal.pc = ls->expr_pc;
+ sal.section = find_pc_overlay (ls->expr_pc);
+ sal.explicit_pc = 1;
+ add_sal_to_sals (state, &sals, &sal, ls->expression, 1);
}
else if (ls->labels.label_symbols != NULL)
{
for (i = 0; VEC_iterate (symbolp, ls->labels.label_symbols, i, sym); ++i)
{
- symbol_to_sal (&sal, state->funfirstline, sym);
- add_sal_to_sals (state, &sals, &sal,
- SYMBOL_NATURAL_NAME (sym));
+ if (symbol_to_sal (&sal, state->funfirstline, sym))
+ add_sal_to_sals (state, &sals, &sal,
+ SYMBOL_NATURAL_NAME (sym), 0);
}
}
else if (ls->function_symbols != NULL || ls->minimal_symbols != NULL)
{
pspace = SYMTAB_PSPACE (SYMBOL_SYMTAB (sym));
set_current_program_space (pspace);
- symbol_to_sal (&sal, state->funfirstline, sym);
- if (maybe_add_address (state->addr_set, pspace, sal.pc))
- add_sal_to_sals (state, &sals, &sal, SYMBOL_NATURAL_NAME (sym));
+ if (symbol_to_sal (&sal, state->funfirstline, sym)
+ && maybe_add_address (state->addr_set, pspace, sal.pc))
+ add_sal_to_sals (state, &sals, &sal,
+ SYMBOL_NATURAL_NAME (sym), 0);
}
}
{
linespec_parser *parser = (linespec_parser *) arg;
- if (PARSER_RESULT (parser)->expression)
- xfree (PARSER_RESULT (parser)->expression);
- if (PARSER_RESULT (parser)->source_filename)
- xfree (PARSER_RESULT (parser)->source_filename);
- if (PARSER_RESULT (parser)->label_name)
- xfree (PARSER_RESULT (parser)->label_name);
- if (PARSER_RESULT (parser)->function_name)
- xfree (PARSER_RESULT (parser)->function_name);
+ xfree ((char *) PARSER_RESULT (parser)->expression);
+ xfree ((char *) PARSER_RESULT (parser)->source_filename);
+ xfree ((char *) PARSER_RESULT (parser)->label_name);
+ xfree ((char *) PARSER_RESULT (parser)->function_name);
if (PARSER_RESULT (parser)->file_symtabs != NULL)
VEC_free (symtab_p, PARSER_RESULT (parser)->file_symtabs);
{
struct symtabs_and_lines result;
struct cleanup *cleanups;
- char *arg_start = *argptr;
VEC (const_char_ptr) *filters = NULL;
linespec_parser parser;
struct linespec_state *state;
gdb_assert (canonical->addr_string != NULL);
canonical->pre_expanded = 1;
- /* Fill in the missing canonical names. */
+ /* Arrange for allocated canonical names to be freed. */
if (result.nelts > 0)
{
int i;
- if (state->canonical_names == NULL)
- state->canonical_names = xcalloc (result.nelts, sizeof (char *));
make_cleanup (xfree, state->canonical_names);
for (i = 0; i < result.nelts; ++i)
{
- if (state->canonical_names[i] == NULL)
- state->canonical_names[i] = savestring (arg_start,
- *argptr - arg_start);
+ gdb_assert (state->canonical_names[i] != NULL);
make_cleanup (xfree, state->canonical_names[i]);
}
}
do_cleanups (cleanups);
}
+/* See linespec.h. */
+
struct symtabs_and_lines
decode_line_1 (char **argptr, int flags,
struct symtab *default_symtab,
return result;
}
+/* See linespec.h. */
+
+struct symtabs_and_lines
+decode_line_with_current_source (char *string, int flags)
+{
+ struct symtabs_and_lines sals;
+ struct symtab_and_line cursal;
+
+ if (string == 0)
+ error (_("Empty line specification."));
+
+ /* We use whatever is set as the current source line. We do not try
+ and get a default source symtab+line or it will recursively call us! */
+ cursal = get_current_source_symtab_and_line ();
+
+ sals = decode_line_1 (&string, flags,
+ cursal.symtab, cursal.line);
+
+ if (*string)
+ error (_("Junk at end of line specification: %s"), string);
+ return sals;
+}
+
+/* See linespec.h. */
+
+struct symtabs_and_lines
+decode_line_with_last_displayed (char *string, int flags)
+{
+ struct symtabs_and_lines sals;
+
+ if (string == 0)
+ error (_("Empty line specification."));
+
+ if (last_displayed_sal_is_valid ())
+ sals = decode_line_1 (&string, flags,
+ get_last_displayed_symtab (),
+ get_last_displayed_line ());
+ else
+ sals = decode_line_1 (&string, flags, (struct symtab *) NULL, 0);
+
+ if (*string)
+ error (_("Junk at end of line specification: %s"), string);
+ return sals;
+}
+
\f
/* First, some functions to initialize stuff at the beggining of the
memcpy (saved_arg, *argptr, new_argptr - *argptr);
saved_arg[new_argptr - *argptr] = '\0';
+ ls->function_name = xstrdup (saved_arg);
ls->function_symbols = info.result.symbols;
ls->minimal_symbols = info.result.minimal_symbols;
values = convert_linespec_to_sals (self, ls);
val.pc = 0;
val.explicit_line = 1;
- add_sal_to_sals (self, values, &val, NULL);
+ add_sal_to_sals (self, values, &val, NULL, 0);
}
}
skip_prologue_sal (&sal);
if (maybe_add_address (self->addr_set, objfile->pspace, sal.pc))
- add_sal_to_sals (self, result, &sal, SYMBOL_NATURAL_NAME (msymbol));
+ add_sal_to_sals (self, result, &sal, SYMBOL_NATURAL_NAME (msymbol), 0);
}
/* A helper struct to pass some data through