From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 11035 invoked by alias); 18 Oct 2006 22:21:00 -0000 Received: (qmail 11024 invoked by uid 22791); 18 Oct 2006 22:20:58 -0000 X-Spam-Check-By: sourceware.org Received: from nevyn.them.org (HELO nevyn.them.org) (66.93.172.17) by sourceware.org (qpsmtpd/0.31.1) with ESMTP; Wed, 18 Oct 2006 22:20:56 +0000 Received: from drow by nevyn.them.org with local (Exim 4.54) id 1GaJmQ-0006QT-CI for gdb-patches@sourceware.org; Wed, 18 Oct 2006 18:20:54 -0400 Date: Wed, 18 Oct 2006 22:21:00 -0000 From: Daniel Jacobowitz To: gdb-patches@sourceware.org Subject: Re: [RFC] Never silently discard internal errors Message-ID: <20061018222054.GA24547@nevyn.them.org> Mail-Followup-To: gdb-patches@sourceware.org References: <20060925184223.GA15314@nevyn.them.org> <20060925200303.GA18759@nevyn.them.org> <20060926035635.GB31294@nevyn.them.org> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <20060926035635.GB31294@nevyn.them.org> User-Agent: Mutt/1.5.13 (2006-08-11) X-IsSubscribed: yes Mailing-List: contact gdb-patches-help@sourceware.org; run by ezmlm Precedence: bulk List-Subscribe: List-Archive: List-Post: List-Help: , Sender: gdb-patches-owner@sourceware.org X-SW-Source: 2006-10/txt/msg00236.txt.bz2 On Mon, Sep 25, 2006 at 11:56:35PM -0400, Daniel Jacobowitz wrote: > On Mon, Sep 25, 2006 at 02:18:38PM -0700, Jim Blandy wrote: > > > > Daniel Jacobowitz writes: > > > On Mon, Sep 25, 2006 at 12:38:40PM -0700, Jim Blandy wrote: > > >> What if we simply had 'query' itself print out the prompt, followed by > > >> "[answering 'y', since standard input is not a terminal]" (or > > >> something more tasteful)? Then you wouldn't have to go around > > >> decorating all the calls to query. > > > > > > I assume that would be wrong for "set confirm off"? > > > > I don't want to turn this into a bikeshed discussion, but here's what > > I had in mind: > > Hmm, I like this. Anyone else? > > [defaulted_query needs similar treatment.] No one else had an opinion so Jim gets to paint the bikeshed :-) I've tested and committed the attached. I took the opportunity to combine query and defaulted_query, and fix a bug I encountered during manual testing that could crash GDB if you hit a couple times at the prompt. -- Daniel Jacobowitz CodeSourcery 2006-10-18 Jim Blandy Daniel Jacobowitz * utils.c (query): Use defaulted_query. (defaulted_query): Handle having no default answer. Print out messages even if we have no terminal. Prevent memory corruption. Index: utils.c =================================================================== RCS file: /cvs/src/src/gdb/utils.c,v retrieving revision 1.169 diff -u -p -r1.169 utils.c --- utils.c 21 Sep 2006 13:50:51 -0000 1.169 +++ utils.c 18 Oct 2006 22:14:57 -0000 @@ -1127,92 +1127,13 @@ gdb_print_host_address (const void *addr fprintf_filtered (stream, "0x%lx", (unsigned long) addr); } - -/* Ask user a y-or-n question and return 1 iff answer is yes. - 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. */ - -/* VARARGS */ -int -query (const char *ctlstr, ...) -{ - va_list args; - int answer; - int ans2; - int retval; - - /* Automatically answer "yes" if input is not from the user - directly, or if the user did not want prompts. */ - if (!input_from_terminal_p () || !caution) - return 1; - - if (deprecated_query_hook) - { - va_start (args, ctlstr); - return deprecated_query_hook (ctlstr, args); - } - - while (1) - { - wrap_here (""); /* Flush any buffered output */ - gdb_flush (gdb_stdout); - - if (annotation_level > 1) - printf_filtered (("\n\032\032pre-query\n")); - - va_start (args, ctlstr); - vfprintf_filtered (gdb_stdout, ctlstr, args); - va_end (args); - printf_filtered (_("(y or n) ")); - - if (annotation_level > 1) - printf_filtered (("\n\032\032query\n")); - - wrap_here (""); - gdb_flush (gdb_stdout); - - answer = fgetc (stdin); - clearerr (stdin); /* in case of C-d */ - if (answer == EOF) /* C-d */ - { - retval = 1; - 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; - if (answer == 'Y') - { - retval = 1; - break; - } - if (answer == 'N') - { - retval = 0; - break; - } - printf_filtered (_("Please answer y or n.\n")); - } - - if (annotation_level > 1) - printf_filtered (("\n\032\032post-query\n")); - return retval; -} -/* This function supports the nquery() and yquery() functions. +/* This function supports the query, 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. + answer is yes, or default the answer to the specified default + (for yquery or nquery). DEFCHAR may be 'y' or 'n' to provide a + default answer, or '\0' for no default. 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 @@ -1226,10 +1147,18 @@ defaulted_query (const char *ctlstr, con int retval; int def_value; char def_answer, not_def_answer; - char *y_string, *n_string; + char *y_string, *n_string, *question; /* Set up according to which answer is the default. */ - if (defchar == 'y') + if (defchar == '\0') + { + def_value = 1; + def_answer = 'Y'; + not_def_answer = 'N'; + y_string = "y"; + n_string = "n"; + } + else if (defchar == 'y') { def_value = 1; def_answer = 'Y'; @@ -1246,6 +1175,27 @@ defaulted_query (const char *ctlstr, con n_string = "[n]"; } + /* Automatically answer the default value if the user did not want + prompts. */ + if (! caution) + return def_value; + + /* If input isn't coming from the user directly, just say what + question we're asking, and then answer "yes" automatically. This + way, important error messages don't get lost when talking to GDB + over a pipe. */ + if (! input_from_terminal_p ()) + { + wrap_here (""); + vfprintf_filtered (gdb_stdout, ctlstr, args); + + printf_filtered (_("(%s or %s) [answered %c; input not from terminal]\n"), + y_string, n_string, def_answer); + gdb_flush (gdb_stdout); + + return def_value; + } + /* Automatically answer the default value if input is not from the user directly, or if the user did not want prompts. */ if (!input_from_terminal_p () || !caution) @@ -1256,6 +1206,9 @@ defaulted_query (const char *ctlstr, con return deprecated_query_hook (ctlstr, args); } + /* Format the question outside of the loop, to avoid reusing args. */ + question = xstrvprintf (ctlstr, args); + while (1) { wrap_here (""); /* Flush any buffered output */ @@ -1264,7 +1217,7 @@ defaulted_query (const char *ctlstr, con if (annotation_level > 1) printf_filtered (("\n\032\032pre-query\n")); - vfprintf_filtered (gdb_stdout, ctlstr, args); + fputs_filtered (question, gdb_stdout); printf_filtered (_("(%s or %s) "), y_string, n_string); if (annotation_level > 1) @@ -1298,10 +1251,12 @@ defaulted_query (const char *ctlstr, con 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) + /* Otherwise, if a default was specified, the user may either + specify the required input or have it default by entering + nothing. */ + if (answer == def_answer + || (defchar != '\0' && + (answer == '\n' || answer == '\r' || answer == EOF))) { retval = def_value; break; @@ -1311,6 +1266,7 @@ defaulted_query (const char *ctlstr, con y_string, n_string); } + xfree (question); if (annotation_level > 1) printf_filtered (("\n\032\032post-query\n")); return retval; @@ -1349,6 +1305,21 @@ yquery (const char *ctlstr, ...) va_end (args); } +/* Ask user a y-or-n question and return 1 iff answer is yes. + 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 +query (const char *ctlstr, ...) +{ + va_list args; + + va_start (args, ctlstr); + return defaulted_query (ctlstr, '\0', 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