This is the mail archive of the gdb-patches@sourceware.org mailing list for the GDB project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

WIP: make "set foo-integer-command unlimited" work too


There are commands that take -1 as unlimited, and others take 0.
For the latter, 0 often aren't very intuitive.

I was working on a patch this week to make these commands
accept the literal "unlimited", so that the user is excused of
needing to memorize -1/0.  The magic number still works the same.
Works like:

  (gdb) set listsize unlimited
  (gdb) show listsize
  Number of source lines gdb will list by default is unlimited.
  (gdb) set listsize 10
  (gdb) show listsize
  Number of source lines gdb will list by default is 10.
  (gdb) set listsize -1
  (gdb) show listsize
  Number of source lines gdb will list by default is unlimited.

To make this really useful, we need a completer for "unlimited".  At
this point, I noticed that these commands accept any kind of symbol as
argument, as they use "parse_" functions.  Well, since the command accepts those,
then I thought of completing on symbols/expressions too.  What could
go wrong, right?  While trying this against GDB, I immediately noticed
that GDB has a lot of symbols starting with "u", which makes the "unlimited"
completion useless.  Then I though of the variant below, which just completes
symbols if it doesn't look like "unlimited" is being written.

Taking a step back, I'm considering simplifying and not completing on
symbols at all...  Maybe at some point we'll even stop accepting random
symbols in these integer commands, like we did to "info breakpoints" and
others.

Comments?

I'll probably finish/simplify this next week.

 gdb/cli/cli-decode.c  |   50 +++++++++++++++++++++++++++++++++++++++++++++++--
 gdb/cli/cli-setshow.c |   36 +++++++++++++++++++++++++++++++----
 gdb/tracepoint.c      |    4 ++--
 3 files changed, 82 insertions(+), 8 deletions(-)

diff --git a/gdb/cli/cli-decode.c b/gdb/cli/cli-decode.c
index 61a7b5a..f92e3ad 100644
--- a/gdb/cli/cli-decode.c
+++ b/gdb/cli/cli-decode.c
@@ -170,6 +170,44 @@ set_cmd_completer (struct cmd_list_element *cmd, completer_ftype *completer)
   cmd->completer = completer; /* Ok.  */
 }

+/* Completer for var_integer/var_zuinteger_unlimited.  Completes
+   either on literal "unlimited" or on expressions.  */
+
+static VEC (char_ptr) *
+literal_unlimited_or_expression_completer (struct cmd_list_element *ignore,
+					   const char *text, const char *word)
+{
+  VEC (char_ptr) *vec_keywords;
+  static const char * const keywords[] =
+    {
+      "unlimited",
+      NULL,
+    };
+
+  /* Don't fallback to the expression completer if we already have
+     literal "unlimited".  IOW, don't suggest things like
+       (gdb) set foo unlimited <tab>
+	 symbol1
+	 symbol2
+	 symbol3
+       set foo unlimited symbol1
+  */
+  if (strncmp (text, "unlimited ", sizeof ("unlimited ") - 1) == 0)
+    return NULL;
+
+  vec_keywords = complete_on_enum (keywords, text, word);
+
+  /* Don't offer to complete on expressions if "unlimited" worked.
+     This hides symbols that start with any prefix of "unlimited", but
+     otherwise if the program has many symbols that start with "u"
+     (GDB does, for example), we mask out "unlimited" from u<tab>,
+     which is much less useful.  */
+  if (!VEC_empty (char_ptr, vec_keywords))
+    return vec_keywords;
+
+  return expression_completer (ignore, text, word);
+}
+
 /* Add element named NAME.
    Space for NAME and DOC must be allocated by the caller.
    CLASS is the top level category into which commands are broken down
@@ -653,11 +691,15 @@ add_setshow_integer_cmd (const char *name, enum command_class class,
 			 struct cmd_list_element **set_list,
 			 struct cmd_list_element **show_list)
 {
+  struct cmd_list_element *set;
+
   add_setshow_cmd_full (name, class, var_integer, var,
 			set_doc, show_doc, help_doc,
 			set_func, show_func,
 			set_list, show_list,
-			NULL, NULL);
+			&set, NULL);
+
+  set_cmd_completer (set, literal_unlimited_or_expression_completer);
 }

 /* Add element named NAME to both the set and show command LISTs (the
@@ -714,11 +756,15 @@ add_setshow_zuinteger_unlimited_cmd (const char *name,
 				     struct cmd_list_element **set_list,
 				     struct cmd_list_element **show_list)
 {
+  struct cmd_list_element *set;
+
   add_setshow_cmd_full (name, class, var_zuinteger_unlimited, var,
 			set_doc, show_doc, help_doc,
 			set_func, show_func,
 			set_list, show_list,
-			NULL, NULL);
+			&set, NULL);
+
+  set_cmd_completer (set, literal_unlimited_or_expression_completer);
 }

 /* Add element named NAME to both the set and show command LISTs (the
diff --git a/gdb/cli/cli-setshow.c b/gdb/cli/cli-setshow.c
index f612369..6c5af71 100644
--- a/gdb/cli/cli-setshow.c
+++ b/gdb/cli/cli-setshow.c
@@ -28,6 +28,7 @@
 #include "cli/cli-decode.h"
 #include "cli/cli-cmds.h"
 #include "cli/cli-setshow.h"
+#include "cli/cli-utils.h"

 /* Return true if the change of command parameter should be notified.  */

@@ -127,6 +128,20 @@ deprecated_show_value_hack (struct ui_file *ignore_file,
     }
 }

+/* Returns true of ARG is "unlimited".  */
+
+static int
+is_unlimited_literal (const char *arg)
+{
+  size_t len = sizeof ("unlimited") - 1;
+
+  arg = skip_spaces_const (arg);
+
+  return (strncmp (arg, "unlimited", len) == 0
+	  && (isspace (arg[len]) || arg[len] == '\0'));
+}
+
+
 /* Do a "set" command.  ARG is NULL if no argument, or the
    text of the argument, and FROM_TTY is nonzero if this command is
    being entered directly by the user (i.e. these are just like any
@@ -300,8 +315,17 @@ do_set_command (char *arg, int from_tty, struct cmd_list_element *c)
 	LONGEST val;

 	if (arg == NULL)
-	  error_no_arg (_("integer to set it to."));
-	val = parse_and_eval_long (arg);
+	  {
+	    if (c->var_type == var_integer)
+	      error_no_arg (_("integer to set it to, or \"unlimited\"."));
+	    else
+	      error_no_arg (_("integer to set it to."));
+	  }
+
+	if (c->var_type == var_integer && is_unlimited_literal (arg))
+	  val = 0;
+	else
+	  val = parse_and_eval_long (arg);

 	if (val == 0 && c->var_type == var_integer)
 	  val = INT_MAX;
@@ -396,8 +420,12 @@ do_set_command (char *arg, int from_tty, struct cmd_list_element *c)
 	LONGEST val;

 	if (arg == NULL)
-	  error_no_arg (_("integer to set it to."));
-	val = parse_and_eval_long (arg);
+	  error_no_arg (_("integer to set it to, or \"unlimited\"."));
+
+	if (is_unlimited_literal (arg))
+	  val = -1;
+	else
+	  val = parse_and_eval_long (arg);

 	if (val > INT_MAX)
 	  error (_("integer %s out of range"), plongest (val));
diff --git a/gdb/tracepoint.c b/gdb/tracepoint.c
index 9a2425b..847ebec 100644
--- a/gdb/tracepoint.c
+++ b/gdb/tracepoint.c
@@ -5876,8 +5876,8 @@ up and stopping the trace run."),
 Set requested size of trace buffer."), _("\
 Show requested size of trace buffer."), _("\
 Use this to choose a size for the trace buffer.  Some targets\n\
-may have fixed or limited buffer sizes.  A value of -1 disables\n\
-any attempt to set the buffer size and lets the target choose."),
+may have fixed or limited buffer sizes.  A value of -1 or \"unlimited\"\n\
+disables any attempt to set the buffer size and lets the target choose."),
 				       set_trace_buffer_size, NULL,
 				       &setlist, &showlist);


-- 
Pedro Alves


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]