This is the mail archive of the gdb@sources.redhat.com 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]

[RFA]: Patch for pending breakpoints and scripts


Daniel Jacobowitz wrote:
On Wed, Feb 11, 2004 at 09:31:23AM -0500, Andrew Cagney wrote:

I'd rather not reverse the question.  We could check from_tty at the
call site, and not set pending breakpoints if no tty...

Why?


Well, how would you word it?  It makes more intuitive sense to me to
answer 'y' to create something special and 'n' to do nothing, than the
other way around.

Something like:


"Discard breakpoint, rather than mark it pending?"

is a guess.


That's why I don't want to reverse the question - I find that really
unintuitive.  Perhaps it's just me.


The real problem here is with batch scripts, the change breaks existing script behavior (which is never a good thing).

How about this, we introduce:
nquery()
yquery()
where the default (batch mode, and when return is pressed is n/y respectively). We'd need the language police to look over the interface but should otherwize be ok.


Works for me.


Ok, please review the attached patches.


gdb/ChangeLog:

2004-02-19 Jeff Johnston <jjohnstn@redhat.com>

        * defs.h (nquery, yquery): New prototypes.
        * breakpoint.c (break_command_1): Use new nquery interface.
        * utils.c (defaulted_query, nquery, yquery): New functions.


gdb/testsuite/ChangeLog:


2004-02-19 Jeff Johnston <jjohnstn@redhat.com>

        * lib/gdb.exp (gdb_breakpoint): Update query string to match
        new nquery format.
        * gdb.base/pending.exp: Ditto.


Index: defs.h
===================================================================
RCS file: /cvs/src/src/gdb/defs.h,v
retrieving revision 1.142
diff -u -p -r1.142 defs.h
--- defs.h	18 Feb 2004 00:21:00 -0000	1.142
+++ defs.h	19 Feb 2004 21:51:40 -0000
@@ -405,6 +405,8 @@ extern void null_cleanup (void *);
 extern int myread (int, char *, int);
 
 extern int query (const char *, ...) ATTR_FORMAT (printf, 1, 2);
+extern int nquery (const char *, ...) ATTR_FORMAT (printf, 1, 2);
+extern int yquery (const char *, ...) ATTR_FORMAT (printf, 1, 2);
 
 extern void init_page_info (void);
 
Index: utils.c
===================================================================
RCS file: /cvs/src/src/gdb/utils.c,v
retrieving revision 1.115
diff -u -p -r1.115 utils.c
--- utils.c	10 Feb 2004 19:08:13 -0000	1.115
+++ utils.c	19 Feb 2004 21:51:40 -0000
@@ -1339,6 +1339,145 @@ query (const char *ctlstr, ...)
 }
 
 
+/* This function supports the nquery() and yquery() functions.
+   Ask user a y-or-n question and return 0 if answer is no, 1 if
+   answer is yes, or default the answer to the specified default.
+   DEFCHAR is either 'y' or 'n' and refers to the default answer.
+   CTLSTR is the control string and should end in "? ".  It should
+   not say how to answer, because we do that.
+   ARGS are the arguments passed along with the CTLSTR argument to
+   printf.  */
+
+static int
+defaulted_query (const char *ctlstr, const char defchar, va_list args)
+{
+  int answer;
+  int ans2;
+  int retval;
+  int def_value;
+  char def_answer, not_def_answer;
+  char *y_string, *n_string;
+
+  /* Set up according to which answer is the default.  */
+  if (defchar == 'y')
+    {
+      def_value = 1;
+      def_answer = 'Y';
+      not_def_answer = 'N';
+      y_string = "[y]";
+      n_string = "n";
+    }
+  else
+    {
+      def_value = 0;
+      def_answer = 'N';
+      not_def_answer = 'Y';
+      y_string = "y";
+      n_string = "[n]";
+    }
+
+  if (query_hook)
+    {
+      return query_hook (ctlstr, args);
+    }
+
+  /* Automatically answer default value if input is not from a terminal.  */
+  if (!input_from_terminal_p ())
+    return def_value;
+
+  while (1)
+    {
+      wrap_here ("");		/* Flush any buffered output */
+      gdb_flush (gdb_stdout);
+
+      if (annotation_level > 1)
+	printf_filtered ("\n\032\032pre-%cquery\n", defchar);
+
+      vfprintf_filtered (gdb_stdout, ctlstr, args);
+      printf_filtered ("(%s or %s) ", y_string, n_string);
+
+      if (annotation_level > 1)
+	printf_filtered ("\n\032\032%cquery\n", defchar);
+
+      wrap_here ("");
+      gdb_flush (gdb_stdout);
+
+      answer = fgetc (stdin);
+      clearerr (stdin);		/* in case of C-d */
+      if (answer == EOF)	/* C-d */
+	{
+	  retval = def_value;
+	  break;
+	}
+      /* Eat rest of input line, to EOF or newline */
+      if (answer != '\n')
+	do
+	  {
+	    ans2 = fgetc (stdin);
+	    clearerr (stdin);
+	  }
+	while (ans2 != EOF && ans2 != '\n' && ans2 != '\r');
+
+      if (answer >= 'a')
+	answer -= 040;
+      /* Check answer.  For the non-default, the user must specify
+         the non-default explicitly.  */
+      if (answer == not_def_answer)
+	{
+	  retval = !def_value;
+	  break;
+	}
+      /* Otherwise, for the default, the user may either specify
+         the required input or have it default by entering nothing.  */
+      if (answer == def_answer || answer == '\n' || 
+	  answer == '\r' || answer == EOF)
+	{
+	  retval = def_value;
+	  break;
+	}
+      /* Invalid entries are not defaulted and require another selection.  */
+      printf_filtered ("Please answer %s or %s.\n",
+		       y_string, n_string);
+    }
+
+  if (annotation_level > 1)
+    printf_filtered ("\n\032\032post-%cquery\n", defchar);
+  return retval;
+}
+
+
+/* Ask user a y-or-n question and return 0 if answer is no, 1 if
+   answer is yes, or 0 if answer is defaulted.
+   Takes three args which are given to printf to print the question.
+   The first, a control string, should end in "? ".
+   It should not say how to answer, because we do that.  */
+
+int
+nquery (const char *ctlstr, ...)
+{
+  va_list args;
+
+  va_start (args, ctlstr);
+  return defaulted_query (ctlstr, 'n', args);
+  va_end (args);
+}
+
+/* Ask user a y-or-n question and return 0 if answer is no, 1 if
+   answer is yes, or 1 if answer is defaulted.
+   Takes three args which are given to printf to print the question.
+   The first, a control string, should end in "? ".
+   It should not say how to answer, because we do that.  */
+
+int
+yquery (const char *ctlstr, ...)
+{
+  va_list args;
+
+  va_start (args, ctlstr);
+  return defaulted_query (ctlstr, 'y', args);
+  va_end (args);
+}
+
 /* Print an error message saying that we couldn't make sense of a
    \^mumble sequence in a string or character constant.  START and END
    indicate a substring of some larger string that contains the
Index: breakpoint.c
===================================================================
RCS file: /cvs/src/src/gdb/breakpoint.c,v
retrieving revision 1.158
diff -u -p -r1.158 breakpoint.c
--- breakpoint.c	3 Feb 2004 22:47:40 -0000	1.158
+++ breakpoint.c	19 Feb 2004 21:51:40 -0000
@@ -5103,7 +5103,7 @@ break_command_1 (char *arg, int flag, in
 
 	  error_output_message (NULL, err_msg);
 	  xfree (err_msg);
-	  if (!query ("Make breakpoint pending on future shared library load? "))
+	  if (!nquery ("Make breakpoint pending on future shared library load? "))
 	    return rc;
 	  copy_arg = xstrdup (addr_start);
 	  addr_string = &copy_arg;
Index: lib/gdb.exp
===================================================================
RCS file: /cvs/src/src/gdb/testsuite/lib/gdb.exp,v
retrieving revision 1.48
diff -u -p -r1.48 gdb.exp
--- lib/gdb.exp	10 Feb 2004 21:00:15 -0000	1.48
+++ lib/gdb.exp	19 Feb 2004 22:04:49 -0000
@@ -275,7 +275,7 @@ proc gdb_breakpoint { function } {
 	-re "Breakpoint \[0-9\]* at .*: file .*, line $decimal.\r\n$gdb_prompt $" {}
 	-re "Breakpoint \[0-9\]*: file .*, line $decimal.\r\n$gdb_prompt $" {}
 	-re "Breakpoint \[0-9\]* at .*$gdb_prompt $" {}
-	-re "Make breakpoint pending.*y or n. $" { 
+	-re "Make breakpoint pending.*y or \\\[n\\\]. $" { 
 		send_gdb "n\n"
 		exp_continue
 	}
Index: gdb.base/pending.exp
===================================================================
RCS file: /cvs/src/src/gdb/testsuite/gdb.base/pending.exp,v
retrieving revision 1.2
diff -u -p -r1.2 pending.exp
--- gdb.base/pending.exp	9 Feb 2004 10:55:24 -0000	1.2
+++ gdb.base/pending.exp	19 Feb 2004 22:04:49 -0000
@@ -111,7 +111,7 @@ if [target_info exists gdb_stub] {
 #
 
 gdb_test_multiple "break pendfunc1" "set pending breakpoint" {
-     -re ".*Make breakpoint pending.*y or n. $" {
+     -re ".*Make breakpoint pending.*y or \\\[n\\\]. $" {
 	    gdb_test "y" "Breakpoint.*pendfunc1.*pending." "set pending breakpoint"
      }
 }
@@ -142,7 +142,7 @@ gdb_test "info break" \
 # Test not setting a pending breakpoint 
 #
 gdb_test_multiple "break pendfunc2" "Don't set pending breakpoint" {
-     -re ".*Make breakpoint pending.*y or n. $" {
+     -re ".*Make breakpoint pending.*y or \\\[n\\\]. $" {
 	    gdb_test "n" "" "Don't set pending breakpoint"
      }
 }
@@ -192,7 +192,7 @@ gdb_test "info break" \
 #
 
 gdb_test_multiple "break pendshr.c:26 if x > 3" "Set pending breakpoint 2" {
-     -re ".*Make breakpoint pending.*y or n. $" {
+     -re ".*Make breakpoint pending.*y or \\\[n\\\]. $" {
 	    gdb_test "y" "Breakpoint.*pendshr.c:26.*pending." \
 		"Set pending breakpoint 2"
      }
@@ -247,7 +247,7 @@ gdb_breakpoint "main"
 # Set non-existent pending breakpoint
 #
 gdb_test_multiple "break imaginary" "set imaginary pending breakpoint" {
-     -re ".*Make breakpoint pending.*y or n. $" {
+     -re ".*Make breakpoint pending.*y or \\\[n\\\]. $" {
 	    gdb_test "y" "Breakpoint.*imaginary.*pending." \
 		"set imaginary pending breakpoint"
      }

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