aboutsummaryrefslogtreecommitdiff
path: root/gdb
diff options
context:
space:
mode:
Diffstat (limited to 'gdb')
-rw-r--r--gdb/ChangeLog7
-rw-r--r--gdb/breakpoint.c59
-rw-r--r--gdb/testsuite/ChangeLog4
-rw-r--r--gdb/testsuite/gdb.base/condbreak.exp5
-rw-r--r--gdb/value.c23
-rw-r--r--gdb/value.h2
6 files changed, 99 insertions, 1 deletions
diff --git a/gdb/ChangeLog b/gdb/ChangeLog
index 81bd9a9..304adc6 100644
--- a/gdb/ChangeLog
+++ b/gdb/ChangeLog
@@ -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.
diff --git a/gdb/breakpoint.c b/gdb/breakpoint.c
index d76065d..82265cc 100644
--- a/gdb/breakpoint.c
+++ b/gdb/breakpoint.c
@@ -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\
diff --git a/gdb/testsuite/ChangeLog b/gdb/testsuite/ChangeLog
index dfc7753..d369a2a 100644
--- a/gdb/testsuite/ChangeLog
+++ b/gdb/testsuite/ChangeLog
@@ -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.
diff --git a/gdb/testsuite/gdb.base/condbreak.exp b/gdb/testsuite/gdb.base/condbreak.exp
index fb82e56..4d0b4ba 100644
--- a/gdb/testsuite/gdb.base/condbreak.exp
+++ b/gdb/testsuite/gdb.base/condbreak.exp
@@ -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"
diff --git a/gdb/value.c b/gdb/value.c
index c64e55b..a6bb718 100644
--- a/gdb/value.c
+++ b/gdb/value.c
@@ -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. */
diff --git a/gdb/value.h b/gdb/value.h
index b630fc7..242cae3 100644
--- a/gdb/value.h
+++ b/gdb/value.h
@@ -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. */