* breakpoint.c (condition_completer): New function.
authorTom Tromey <tromey@redhat.com>
Wed, 13 Jun 2012 15:50:22 +0000 (15:50 +0000)
committerTom Tromey <tromey@redhat.com>
Wed, 13 Jun 2012 15:50:22 +0000 (15:50 +0000)
(_initialize_breakpoint): Use it.
* value.c (complete_internalvar): New function.
* value.h (complete_internalvar): Declare.
testsuite
* gdb.base/condbreak.exp: Add tests for "condition" completion.

gdb/ChangeLog
gdb/breakpoint.c
gdb/testsuite/ChangeLog
gdb/testsuite/gdb.base/condbreak.exp
gdb/value.c
gdb/value.h

index 81bd9a9..304adc6 100644 (file)
@@ -1,5 +1,12 @@
 2012-06-13  Tom Tromey  <tromey@redhat.com>
 
+       * breakpoint.c (condition_completer): New function.
+       (_initialize_breakpoint): Use it.
+       * value.c (complete_internalvar): New function.
+       * value.h (complete_internalvar): Declare.
+
+2012-06-13  Tom Tromey  <tromey@redhat.com>
+
        * ada-lang.c (ada_make_symbol_completion_list): Return a VEC.
        * breakpoint.c (catch_syscall_completer): Return a VEC.
        * cli/cli-cmds.c (complete_command): Update.
index d76065d..82265cc 100644 (file)
@@ -947,6 +947,62 @@ set_breakpoint_condition (struct breakpoint *b, char *exp,
   observer_notify_breakpoint_modified (b);
 }
 
+/* Completion for the "condition" command.  */
+
+static VEC (char_ptr) *
+condition_completer (struct cmd_list_element *cmd, char *text, char *word)
+{
+  char *space;
+
+  text = skip_spaces (text);
+  space = skip_to_space (text);
+  if (*space == '\0')
+    {
+      int len;
+      struct breakpoint *b;
+      VEC (char_ptr) *result = NULL;
+
+      if (text[0] == '$')
+       {
+         /* We don't support completion of history indices.  */
+         if (isdigit (text[1]))
+           return NULL;
+         return complete_internalvar (&text[1]);
+       }
+
+      /* We're completing the breakpoint number.  */
+      len = strlen (text);
+
+      ALL_BREAKPOINTS (b)
+      {
+       int single = b->loc->next == NULL;
+       struct bp_location *loc;
+       int count = 1;
+
+       for (loc = b->loc; loc; loc = loc->next)
+         {
+           char location[50];
+
+           if (single)
+             sprintf (location, "%d", b->number);
+           else
+             sprintf (location, "%d.%d", b->number, count);
+
+           if (strncmp (location, text, len) == 0)
+             VEC_safe_push (char_ptr, result, xstrdup (location));
+
+           ++count;
+         }
+      }
+
+      return result;
+    }
+
+  /* We're completing the expression part.  */
+  text = skip_spaces (space);
+  return expression_completer (cmd, text, word);
+}
+
 /* condition N EXP -- set break condition of breakpoint N to EXP.  */
 
 static void
@@ -15528,10 +15584,11 @@ Type a line containing \"end\" to indicate the end of them.\n\
 Give \"silent\" as the first line to make the breakpoint silent;\n\
 then no output is printed when it is hit, except what the commands print."));
 
-  add_com ("condition", class_breakpoint, condition_command, _("\
+  c = add_com ("condition", class_breakpoint, condition_command, _("\
 Specify breakpoint number N to break only if COND is true.\n\
 Usage is `condition N COND', where N is an integer and COND is an\n\
 expression to be evaluated whenever breakpoint N is reached."));
+  set_cmd_completer (c, condition_completer);
 
   c = add_com ("tbreak", class_breakpoint, tbreak_command, _("\
 Set a temporary breakpoint.\n\
index dfc7753..d369a2a 100644 (file)
@@ -1,3 +1,7 @@
+2012-06-13  Tom Tromey  <tromey@redhat.com>
+
+       * gdb.base/condbreak.exp: Add tests for "condition" completion.
+
 2012-06-11  Jan Kratochvil  <jan.kratochvil@redhat.com>
 
        Fix regression by the "ambiguous linespec" series.
index fb82e56..4d0b4ba 100644 (file)
@@ -261,3 +261,8 @@ gdb_test_multiple "continue" $test {
        xfail $test
     }
 }
+
+gdb_test "complete cond 1" "cond 1"
+gdb_test "set variable \$var = 1"
+gdb_test "complete cond \$v" "cond \\\$var"
+gdb_test "complete cond 1 values\[0\].a" "cond 1 values.0..a_field"
index c64e55b..a6bb718 100644 (file)
@@ -1714,6 +1714,29 @@ lookup_only_internalvar (const char *name)
   return NULL;
 }
 
+/* Complete NAME by comparing it to the names of internal variables.
+   Returns a vector of newly allocated strings, or NULL if no matches
+   were found.  */
+
+VEC (char_ptr) *
+complete_internalvar (const char *name)
+{
+  VEC (char_ptr) *result = NULL;
+  struct internalvar *var;
+  int len;
+
+  len = strlen (name);
+
+  for (var = internalvars; var; var = var->next)
+    if (strncmp (var->name, name, len) == 0)
+      {
+       char *r = xstrdup (var->name);
+
+       VEC_safe_push (char_ptr, result, r);
+      }
+
+  return result;
+}
 
 /* Create an internal variable with name NAME and with a void value.
    NAME should not normally include a dollar sign.  */
index b630fc7..242cae3 100644 (file)
@@ -765,6 +765,8 @@ extern struct internalvar *lookup_only_internalvar (const char *name);
 
 extern struct internalvar *create_internalvar (const char *name);
 
+extern VEC (char_ptr) *complete_internalvar (const char *name);
+
 /* An internalvar can be dynamically computed by supplying a vector of
    function pointers to perform various operations.  */