diff options
author | David Carlton <carlton@bactrian.org> | 2002-11-05 01:22:21 +0000 |
---|---|---|
committer | David Carlton <carlton@bactrian.org> | 2002-11-05 01:22:21 +0000 |
commit | 3257c35651c0b2a322edca9f07805c1b9dd88ff9 (patch) | |
tree | 35494622c1f79373a2067070b364781756b1a672 | |
parent | a1fb2f8295de40b83a8ee49802df5c2c78a9dce4 (diff) | |
download | gdb-3257c35651c0b2a322edca9f07805c1b9dd88ff9.tar.gz |
2002-11-04 David Carlton <carlton@math.stanford.edu>
* linespec.c (initialize_defaults): Rename from
dl1_initialize_defaults.
(set_flags): Rename from dl1_set_flags.
(decode_line_1): Set flags before decoding indirect.
(decode_indirect): Rename from dl1_indirect.
(set_flags): Miscellaneous cleanup.
(decode_indirect): Miscellaneous cleanup.
Move around some functions and declarations.
-rw-r--r-- | gdb/ChangeLog | 11 | ||||
-rw-r--r-- | gdb/linespec.c | 479 |
2 files changed, 262 insertions, 228 deletions
diff --git a/gdb/ChangeLog b/gdb/ChangeLog index b11fc6598de..2c3855b6fdc 100644 --- a/gdb/ChangeLog +++ b/gdb/ChangeLog @@ -1,3 +1,14 @@ +2002-11-04 David Carlton <carlton@math.stanford.edu> + + * linespec.c (initialize_defaults): Rename from + dl1_initialize_defaults. + (set_flags): Rename from dl1_set_flags. + (decode_line_1): Set flags before decoding indirect. + (decode_indirect): Rename from dl1_indirect. + (set_flags): Miscellaneous cleanup. + (decode_indirect): Miscellaneous cleanup. + Move around some functions and declarations. + 2002-11-01 David Carlton <carlton@math.stanford.edu> * linespec.c (dl1_set_flags): Change arguments. diff --git a/gdb/linespec.c b/gdb/linespec.c index 05a29d466a7..21fc7bdf5f6 100644 --- a/gdb/linespec.c +++ b/gdb/linespec.c @@ -40,6 +40,13 @@ extern char *operator_chars (char *, char **); /* Prototypes for local functions */ +static void initialize_defaults (struct symtab **default_symtab, + int *default_line); + +static void set_flags (char *arg, int *is_quoted, char **paren_pointer); + +static struct symtabs_and_lines decode_indirect (char **argptr); + static NORETURN void cplusplus_error (const char *name, const char *fmt, ...) ATTR_NORETURN ATTR_FORMAT (printf, 2, 3); static int total_number_of_methods (struct type *type); @@ -54,14 +61,6 @@ static char *find_toplevel_char (char *s, char c); static struct symtabs_and_lines decode_line_2 (struct symbol *[], int, int, char ***); -static void dl1_initialize_defaults (struct symtab **default_symtab, - int *default_line); - -static struct symtabs_and_lines dl1_indirect (char **argptr); - -static void dl1_set_flags (char *arg, int *is_quoted, - char **paren_pointer); - static char *dl1_locate_first_half (char **argptr, int *is_quote_enclosed); static struct symtabs_and_lines dl1_compound (char **argptr, @@ -130,6 +129,250 @@ static struct symtabs_and_lines dl1_minsym_found (int funfirstline, struct minimal_symbol *msymbol); +/* The parser of linespec itself. */ + +/* Parse a string that specifies a line number. + Pass the address of a char * variable; that variable will be + advanced over the characters actually parsed. + + The string can be: + + LINENUM -- that line number in current file. PC returned is 0. + FILE:LINENUM -- that line in that file. PC returned is 0. + FUNCTION -- line number of openbrace of that function. + PC returned is the start of the function. + VARIABLE -- line number of definition of that variable. + PC returned is 0. + FILE:FUNCTION -- likewise, but prefer functions in that file. + *EXPR -- line in which address EXPR appears. + + This may all be followed by an "if EXPR", which we ignore. + + FUNCTION may be an undebuggable function found in minimal symbol table. + + If the argument FUNFIRSTLINE is nonzero, we want the first line + of real code inside a function when a function is specified, and it is + not OK to specify a variable or type to get its line number. + + DEFAULT_SYMTAB specifies the file to use if none is specified. + It defaults to current_source_symtab. + DEFAULT_LINE specifies the line number to use for relative + line numbers (that start with signs). Defaults to current_source_line. + If CANONICAL is non-NULL, store an array of strings containing the canonical + line specs there if necessary. Currently overloaded member functions and + line numbers or static functions without a filename yield a canonical + line spec. The array and the line spec strings are allocated on the heap, + it is the callers responsibility to free them. + + Note that it is possible to return zero for the symtab + if no file is validly specified. Callers must check that. + Also, the line number returned may be invalid. */ + +/* We allow single quotes in various places. This is a hideous + kludge, which exists because the completer can't yet deal with the + lack of single quotes. FIXME: write a linespec_completer which we + can use as appropriate instead of make_symbol_completion_list. */ + +/* Everything else in this file is a helper function for + decode_line_1. */ + +/* FIXME: carlton/2002-11-04: It would be nice for ARGPTR to be a + const char **. But, alas, that can't easily be fixed right now: + for one thing, some functions actually do temporarily modify some + of the chars in question (e.g. is_quoted), and, for another thing, + GCC would seem not to be to thrilled about implicit conversions + from char ** to const char **. */ + +struct symtabs_and_lines +decode_line_1 (char **argptr, int funfirstline, struct symtab *default_symtab, + int default_line, char ***canonical) +{ + /* This is NULL if there are no parens in *ARGPTR, or a pointer to + the closing parenthesis if there are parens. */ + char *paren_pointer; + /* This says whether or not something in *ARGPTR is quoted with + completer_quotes (i.e. with single quotes). */ + int is_quoted; + /* If a file name is specified, this is its symtab. */ + struct symtab *file_symtab = NULL; + /* This function advances *ARGPTR, but, for error messages, we want + to remember what it pointed to initially. */ + char *saved_arg = *argptr; + + /* Defaults have defaults. */ + + initialize_defaults (&default_symtab, &default_line); + + /* Set various flags. + * 'paren_pointer' is important for overload checking, where + * we allow things like: + * (gdb) break c::f(int) + */ + + set_flags (*argptr, &is_quoted, &paren_pointer); + + /* See if arg is *PC */ + + if (**argptr == '*') + return decode_indirect (argptr); + + /* Check to see if it's a multipart linespec (with colons or periods). */ + { + 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_compound (argptr, funfirstline, canonical, + saved_arg, p); + + /* No, the first part is a filename; set file_symtab + accordingly. Also, move argptr past the filename. */ + + file_symtab = dl1_handle_filename (argptr, p, is_quote_enclosed); + } + } + + /* Check whether arg is all digits (and sign) */ + + 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 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 (**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. */ + + return dl1_variable (argptr, funfirstline, canonical, is_quoted, + paren_pointer, file_symtab); +} + + + +/* Now, the helper functions. */ + +/* NOTE: carlton/2002-11-04: Some of these have non-obvious side + effects. In particular, if a function is passed ARGPTR as an + argument, it probably modifies what ARGPTR points to. */ + +/* First, some functions to initialize stuff at the beggining of the + function. */ + +static void +initialize_defaults (struct symtab **default_symtab, int *default_line) +{ + if (*default_symtab == NULL) + { + /* Use whatever we have for the default source line. We don't use + get_current_or_default_symtab_and_line as it can recurse and call + us back! */ + struct symtab_and_line cursal + = get_current_source_symtab_and_line (); + + *default_symtab = cursal.symtab; + *default_line = cursal.line; + } +} + +static void +set_flags (char *arg, int *is_quoted, char **paren_pointer) +{ + char *if_index; + char *paren_start; + int has_if = 0; + + /* 'has_if' is for the syntax: + * (gdb) break foo if (a==b) + */ + if ((if_index = strstr (arg, " if ")) != NULL || + (if_index = strstr (arg, "\tif ")) != NULL || + (if_index = strstr (arg, " if\t")) != NULL || + (if_index = strstr (arg, "\tif\t")) != NULL || + (if_index = strstr (arg, " if(")) != NULL || + (if_index = strstr (arg, "\tif( ")) != NULL) + has_if = 1; + /* Temporarily zap out "if (condition)" to not + * confuse the parenthesis-checking code below. + * This is undone below. Do not change if_index!! + */ + if (has_if) + { + *if_index = '\0'; + } + + /* Set various flags. + * 'paren_pointer' is important for overload checking, where + * we allow things like: + * (gdb) break c::f(int) + */ + + /* Maybe arg is FILE : LINENUM or FILE : FUNCTION */ + + *is_quoted = (*arg && (strchr (get_gdb_completer_quote_characters (), + *arg) + != NULL)); + + paren_start = strchr (arg, '('); + + if (paren_start != NULL) + *paren_pointer = strrchr (paren_start, ')'); + else + *paren_pointer = NULL; + + /* Now that we're safely past the has_parens check, + * put back " if (condition)" so outer layers can see it + */ + if (has_if) + *if_index = ' '; +} + + + +/* Decode arg of the form *PC. */ + +static struct symtabs_and_lines +decode_indirect (char **argptr) +{ + struct symtabs_and_lines values; + CORE_ADDR pc; + + (*argptr)++; /* Skip the initial asterisk. */ + pc = parse_and_eval_address_1 (argptr); + + values.sals = xmalloc (sizeof (struct symtab_and_line)); + + values.nelts = 1; + values.sals[0] = find_pc_line (pc, 0); + values.sals[0].pc = pc; + values.sals[0].section = find_pc_overlay (pc); + + return values; +} + + /* Helper functions. */ /* Issue a helpful hint on using the command completion feature on @@ -536,226 +779,6 @@ decode_line_2 (struct symbol *sym_arr[], int nelts, int funfirstline, discard_cleanups (old_chain); return return_values; } - -/* The parser of linespec itself. */ - -/* Parse a string that specifies a line number. - Pass the address of a char * variable; that variable will be - advanced over the characters actually parsed. - - The string can be: - - LINENUM -- that line number in current file. PC returned is 0. - FILE:LINENUM -- that line in that file. PC returned is 0. - FUNCTION -- line number of openbrace of that function. - PC returned is the start of the function. - VARIABLE -- line number of definition of that variable. - PC returned is 0. - FILE:FUNCTION -- likewise, but prefer functions in that file. - *EXPR -- line in which address EXPR appears. - - This may all be followed by an "if EXPR", which we ignore. - - FUNCTION may be an undebuggable function found in minimal symbol table. - - If the argument FUNFIRSTLINE is nonzero, we want the first line - of real code inside a function when a function is specified, and it is - not OK to specify a variable or type to get its line number. - - DEFAULT_SYMTAB specifies the file to use if none is specified. - It defaults to current_source_symtab. - DEFAULT_LINE specifies the line number to use for relative - line numbers (that start with signs). Defaults to current_source_line. - If CANONICAL is non-NULL, store an array of strings containing the canonical - line specs there if necessary. Currently overloaded member functions and - line numbers or static functions without a filename yield a canonical - line spec. The array and the line spec strings are allocated on the heap, - it is the callers responsibility to free them. - - Note that it is possible to return zero for the symtab - if no file is validly specified. Callers must check that. - Also, the line number returned may be invalid. */ - -/* We allow single quotes in various places. This is a hideous - kludge, which exists because the completer can't yet deal with the - lack of single quotes. FIXME: write a linespec_completer which we - can use as appropriate instead of make_symbol_completion_list. */ - -struct symtabs_and_lines -decode_line_1 (char **argptr, int funfirstline, struct symtab *default_symtab, - int default_line, char ***canonical) -{ - /* This is NULL if there are no parens in argptr, or a pointer to - the closing parenthesis if there are parens. */ - char *paren_pointer; - /* If a file name is specified, this is its symtab. */ - struct symtab *file_symtab = NULL; - int is_quoted; - char *saved_arg = *argptr; - - /* Defaults have defaults. */ - - dl1_initialize_defaults (&default_symtab, &default_line); - - /* See if arg is *PC */ - - if (**argptr == '*') - return dl1_indirect (argptr); - - /* Set various flags. - * 'paren_pointer' is important for overload checking, where - * we allow things like: - * (gdb) break c::f(int) - */ - - dl1_set_flags (*argptr, &is_quoted, &paren_pointer); - - /* Check to see if it's a multipart linespec (with colons or periods). */ - { - 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_compound (argptr, funfirstline, canonical, - saved_arg, p); - - /* No, the first part is a filename; set file_symtab - accordingly. Also, move argptr past the filename. */ - - file_symtab = dl1_handle_filename (argptr, p, is_quote_enclosed); - } - } - - /* Check whether arg is all digits (and sign) */ - - 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 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 (**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. */ - - return dl1_variable (argptr, funfirstline, canonical, is_quoted, - paren_pointer, file_symtab); -} - -/* Now come a bunch of helper functions for decode_line_1. Warning: - most of them have the side effect of advancing argptr, and I'm not - mentioning that in the comments. */ - -/* Defaults have defaults. */ - -static void -dl1_initialize_defaults (struct symtab **default_symtab, int *default_line) -{ - if (*default_symtab == NULL) - { - /* Use whatever we have for the default source line. We don't use - get_current_or_default_symtab_and_line as it can recurse and call - us back! */ - struct symtab_and_line cursal - = get_current_source_symtab_and_line (); - - *default_symtab = cursal.symtab; - *default_line = cursal.line; - } -} - -/* See if arg is *PC */ - -static struct symtabs_and_lines -dl1_indirect (char **argptr) -{ - struct symtabs_and_lines values; - CORE_ADDR pc; - - (*argptr)++; - pc = parse_and_eval_address_1 (argptr); - - values.sals = (struct symtab_and_line *) - xmalloc (sizeof (struct symtab_and_line)); - - values.nelts = 1; - values.sals[0] = find_pc_line (pc, 0); - values.sals[0].pc = pc; - values.sals[0].section = find_pc_overlay (pc); - - return values; -} - -static void -dl1_set_flags (char *arg, int *is_quoted, char **paren_pointer) -{ - char *ii; - int has_if = 0; - - /* 'has_if' is for the syntax: - * (gdb) break foo if (a==b) - */ - 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. - * This is undone below. Do not change ii!! - */ - if (has_if) - { - *ii = '\0'; - } - - /* Set various flags. - * 'paren_pointer' is important for overload checking, where - * we allow things like: - * (gdb) break c::f(int) - */ - - /* Maybe arg is FILE : LINENUM or FILE : FUNCTION */ - - *is_quoted = (*arg - && strchr (get_gdb_completer_quote_characters (), - *arg) != NULL); - - *paren_pointer = strchr (arg, '('); - - if (*paren_pointer != NULL) - *paren_pointer = strrchr (*paren_pointer, ')'); - - /* Now that we're safely past the has_parens check, - * put back " if (condition)" so outer layers can see it - */ - if (has_if) - *ii = ' '; -} static char * dl1_locate_first_half (char **argptr, int *is_quote_enclosed) |