* gdb.threads/gcore-thread.exp: Use gdb_gcore_cmd.
[deliverable/binutils-gdb.git] / gdb / linespec.c
index e5c1f9f7d2422238bc79812feb6c6a2af40ab425..06634d28394c333ef2b6dadfd7f2f4dc19e80adf 100644 (file)
@@ -110,7 +110,7 @@ struct linespec
      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;
@@ -118,7 +118,7 @@ struct linespec
   /* 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),
@@ -130,7 +130,7 @@ struct linespec
 
   /* 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.  */
@@ -140,7 +140,7 @@ struct linespec
   /* 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
@@ -286,6 +286,11 @@ struct ls_parser
   /* Is the entire linespec quote-enclosed?  */
   int is_quote_enclosed;
 
+  /* Is a keyword syntactically valid at this point?
+     In, e.g., "break thread thread 1", the leading "keyword" must not
+     be interpreted as such.  */
+  int keyword_ok;
+
   /* The state of the parse.  */
   struct linespec_state state;
 #define PARSER_STATE(PPTR) (&(PPTR)->state)
@@ -366,31 +371,42 @@ static const char *const linespec_quote_characters = "\"\'";
 /* 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
@@ -596,6 +612,10 @@ linespec_lexer_lex_string (linespec_parser *parser)
          if (isspace (*PARSER_STREAM (parser)))
            {
              p = skip_spaces (PARSER_STREAM (parser));
+             /* When we get here we know we've found something followed by
+                a space (we skip over parens and templates below).
+                So if we find a keyword now, we know it is a keyword and not,
+                say, a function name.  */
              if (linespec_lexer_lex_keyword (p) != NULL)
                {
                  LS_TOKEN_STOKEN (token).ptr = start;
@@ -705,8 +725,10 @@ linespec_lexer_lex_one (linespec_parser *parser)
       /* Skip any whitespace.  */
       PARSER_STREAM (parser) = skip_spaces (PARSER_STREAM (parser));
 
-      /* Check for a keyword.  */
-      keyword = linespec_lexer_lex_keyword (PARSER_STREAM (parser));
+      /* Check for a keyword, they end the linespec.  */
+      keyword = NULL;
+      if (parser->keyword_ok)
+       keyword = linespec_lexer_lex_keyword (PARSER_STREAM (parser));
       if (keyword != NULL)
        {
          parser->lexer.current.type = LSTOKEN_KEYWORD;
@@ -724,7 +746,8 @@ linespec_lexer_lex_one (linespec_parser *parser)
        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 ':':
@@ -810,13 +833,16 @@ add_sal_to_sals_basic (struct symtabs_and_lines *sals,
 
 /* 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);
 
@@ -826,7 +852,7 @@ add_sal_to_sals (struct linespec_state *self,
 
       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;
 
@@ -842,6 +868,8 @@ add_sal_to_sals (struct linespec_state *self,
          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;
     }
@@ -993,7 +1021,8 @@ iterate_over_all_matching_symtabs (struct linespec_state *state,
          struct block *block;
 
          block = BLOCKVECTOR_BLOCK (BLOCKVECTOR (symtab), STATIC_BLOCK);
-         LA_ITERATE_OVER_SYMBOLS (block, name, domain, callback, data);
+         state->language->la_iterate_over_symbols (block, name, domain,
+                                                   callback, data);
 
          if (include_inline)
            {
@@ -1004,8 +1033,8 @@ iterate_over_all_matching_symtabs (struct linespec_state *state,
                   i < BLOCKVECTOR_NBLOCKS (BLOCKVECTOR (symtab)); i++)
                {
                  block = BLOCKVECTOR_BLOCK (BLOCKVECTOR (symtab), i);
-                 LA_ITERATE_OVER_SYMBOLS (block, name, domain,
-                                          iterate_inline_only, &cad);
+                 state->language->la_iterate_over_symbols
+                   (block, name, domain, iterate_inline_only, &cad);
                }
            }
        }
@@ -1046,7 +1075,6 @@ find_methods (struct type *t, const char *name,
              VEC (const_char_ptr) **result_names,
              VEC (typep) **superclasses)
 {
-  int i1 = 0;
   int ibase;
   const char *class_name = type_name_no_tag (t);
 
@@ -1056,7 +1084,6 @@ find_methods (struct type *t, const char *name,
   if (class_name)
     {
       int method_counter;
-      int name_len = strlen (name);
 
       CHECK_TYPEDEF (t);
 
@@ -1347,7 +1374,7 @@ decode_line_2 (struct linespec_state *self,
    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 = "";
@@ -1695,7 +1722,7 @@ create_sals_line_offset (struct linespec_state *self,
 
   /* This is where we need to make sure we have good defaults.
      We must guarantee that this section of code is never executed
-     when we are called with just a function anme, since
+     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.  */
 
@@ -1809,7 +1836,7 @@ create_sals_line_offset (struct linespec_state *self,
               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);
@@ -1837,13 +1864,14 @@ convert_linespec_to_sals (struct linespec_state *state, linespec_p ls)
 
   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)
     {
@@ -1854,9 +1882,9 @@ convert_linespec_to_sals (struct linespec_state *state, linespec_p ls)
 
       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)
@@ -1880,9 +1908,10 @@ convert_linespec_to_sals (struct linespec_state *state, linespec_p ls)
            {
              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);
            }
        }
 
@@ -2006,6 +2035,10 @@ parse_linespec (linespec_parser *parser, char **argptr)
        }
     }
 
+  /* A keyword at the start cannot be interpreted as such.
+     Consider "b thread thread 42".  */
+  parser->keyword_ok = 0;
+
   parser->lexer.saved_arg = *argptr;
   parser->lexer.stream = argptr;
   file_exception.reason = 0;
@@ -2080,6 +2113,9 @@ parse_linespec (linespec_parser *parser, char **argptr)
   else if (token.type != LSTOKEN_STRING && token.type != LSTOKEN_NUMBER)
     unexpected_linespec_error (parser);
 
+  /* Now we can recognize keywords.  */
+  parser->keyword_ok = 1;
+
   /* Shortcut: If the next token is not LSTOKEN_COLON, we know that
      this token cannot represent a filename.  */
   token = linespec_lexer_peek_token (parser);
@@ -2220,14 +2256,10 @@ linespec_parser_delete (void *arg)
 {
   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);
@@ -2258,7 +2290,6 @@ decode_line_full (char **argptr, int flags,
 {
   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;
@@ -2284,19 +2315,15 @@ decode_line_full (char **argptr, int flags,
   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]);
        }
     }
@@ -2478,6 +2505,7 @@ decode_objc (struct linespec_state *self, linespec_p ls, char **argptr)
       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);
@@ -3110,7 +3138,7 @@ decode_digits_list_mode (struct linespec_state *self,
       val.pc = 0;
       val.explicit_line = 1;
 
-      add_sal_to_sals (self, values, &val, NULL);
+      add_sal_to_sals (self, values, &val, NULL, 0);
     }
 }
 
@@ -3254,7 +3282,7 @@ minsym_found (struct linespec_state *self, struct objfile *objfile,
     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
This page took 0.029055 seconds and 4 git commands to generate.