*** empty log message ***
[deliverable/binutils-gdb.git] / gdb / linespec.c
index e85be681a1bdae517c5b7114d900415a7dba9bce..c22ffe7c6dcf3b6d15be8634639b2c1aee95d462 100644 (file)
@@ -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 ':':
@@ -829,7 +852,7 @@ add_sal_to_sals (struct linespec_state *self,
 
       self->canonical_names = xrealloc (self->canonical_names,
                                        sals->nelts * sizeof (char *));
-      if (!literal_canonical && sal->symtab && sal->symtab->filename)
+      if (!literal_canonical && sal->symtab)
        {
          char *filename = sal->symtab->filename;
 
@@ -998,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)
            {
@@ -1009,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);
                }
            }
        }
@@ -1051,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);
 
@@ -1061,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);
 
@@ -1700,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.  */
 
@@ -2013,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;
@@ -2069,24 +2095,24 @@ parse_linespec (linespec_parser *parser, char **argptr)
       cleanup = make_cleanup (xfree, var);
       PARSER_RESULT (parser)->line_offset
        = linespec_parse_variable (PARSER_STATE (parser), var);
+      do_cleanups (cleanup);
 
       /* If a line_offset wasn't found (VAR is the name of a user
         variable/function), then skip to normal symbol processing.  */
       if (PARSER_RESULT (parser)->line_offset.sign != LINE_OFFSET_UNKNOWN)
        {
-         discard_cleanups (cleanup);
-
          /* Consume this token.  */
          linespec_lexer_consume_token (parser);
 
          goto convert_to_sals;
        }
-
-      do_cleanups (cleanup);
     }
   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);
@@ -2261,7 +2287,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;
This page took 0.025656 seconds and 4 git commands to generate.