From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 15510 invoked by alias); 14 Nov 2013 19:03:04 -0000 Mailing-List: contact gdb-patches-help@sourceware.org; run by ezmlm Precedence: bulk List-Id: List-Subscribe: List-Archive: List-Post: List-Help: , Sender: gdb-patches-owner@sourceware.org Received: (qmail 15488 invoked by uid 89); 14 Nov 2013 19:03:03 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-1.4 required=5.0 tests=AWL,BAYES_00,RDNS_NONE,SPF_HELO_PASS,SPF_PASS autolearn=no version=3.3.2 X-HELO: mx1.redhat.com Received: from Unknown (HELO mx1.redhat.com) (209.132.183.28) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with ESMTP; Thu, 14 Nov 2013 19:03:01 +0000 Received: from int-mx11.intmail.prod.int.phx2.redhat.com (int-mx11.intmail.prod.int.phx2.redhat.com [10.5.11.24]) by mx1.redhat.com (8.14.4/8.14.4) with ESMTP id rAEJ2olS002067 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=OK); Thu, 14 Nov 2013 14:02:50 -0500 Received: from [127.0.0.1] (ovpn01.gateway.prod.ext.ams2.redhat.com [10.39.146.11]) by int-mx11.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id rAEJ2mwG017672; Thu, 14 Nov 2013 14:02:48 -0500 Message-ID: <52851E57.30103@redhat.com> Date: Thu, 14 Nov 2013 19:37:00 -0000 From: Pedro Alves User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:17.0) Gecko/20130625 Thunderbird/17.0.7 MIME-Version: 1.0 To: Joel Brobecker CC: =?ISO-8859-1?Q?Andr=E9_P=F6nitz?= , Tom Tromey , gdb-patches@sourceware.org Subject: Re: [RFC] New GDB/MI command "-info-gdb-mi-command" References: <8761rzknb4.fsf@fleche.redhat.com> <1384255504-28444-1-git-send-email-brobecker@adacore.com> <20131112205229.GA7068@klara.mpi.htwm.de> <20131113021514.GG3481@adacore.com> <52851A04.6040004@redhat.com> In-Reply-To: <52851A04.6040004@redhat.com> Content-Type: text/plain; charset=ISO-8859-1 Content-Transfer-Encoding: 7bit X-SW-Source: 2013-11/txt/msg00384.txt.bz2 On 11/14/2013 06:44 PM, Pedro Alves wrote: > Yeah. I think that points out that errors like "Undefined MI command:" and > "Usage:" errors are in a different class of errors from errors caused > by user input though. The former should never ever be seen by the user. > They're "internal" gdb<->frontend errors. We could/should tag these > differently somehow, so that the frontend doesn't have to parse a > free form string. Like: > > "^error,msg="..." > "^error,msg="...",code="unknown-command" > "^error,msg="...",code="usage" > > or some such. > > This does not invalidate listing features in -list-features, as > it's often useful to know upfront whether some feature is supported, > so the frontend can disable parts of the GUI that won't make sense > for the current target/session. > Something like this: -whatever ^error,msg="Undefined MI command: whatever",error="unknown-command" (gdb) -list-thread-groups --frame 1 --frame 1 ^error,msg="Duplicate '--frame' option",error="command-usage" (gdb) Frontends must ignore unknown attributes, so it's backwards compatible. Just a POC. Of course, we'd have to go audit all MI "error" calls. --- gdb/exceptions.h | 6 ++++++ gdb/mi/mi-main.c | 13 ++++++++++++- gdb/mi/mi-parse.c | 20 +++++++++++++------- 3 files changed, 31 insertions(+), 8 deletions(-) diff --git a/gdb/exceptions.h b/gdb/exceptions.h index 129d29a..07599ae 100644 --- a/gdb/exceptions.h +++ b/gdb/exceptions.h @@ -93,6 +93,12 @@ enum errors { aborted as the inferior state is no longer valid. */ TARGET_CLOSE_ERROR, + /* An unknown command was executed. */ + UNKNOWN_COMMAND_ERROR, + + /* Wrong command usage. */ + COMMAND_USAGE_ERROR, + /* Add more errors here. */ NR_ERRORS }; diff --git a/gdb/mi/mi-main.c b/gdb/mi/mi-main.c index bbf944a..c2a3988 100644 --- a/gdb/mi/mi-main.c +++ b/gdb/mi/mi-main.c @@ -2021,7 +2021,18 @@ mi_print_exception (const char *token, struct gdb_exception exception) fputs_unfiltered ("unknown error", raw_stdout); else fputstr_unfiltered (exception.message, '"', raw_stdout); - fputs_unfiltered ("\"\n", raw_stdout); + fputs_unfiltered ("\"", raw_stdout); + + switch (exception.error) + { + case UNKNOWN_COMMAND_ERROR: + fputs_unfiltered (",error=\"unknown-command\"", raw_stdout); + break; + case COMMAND_USAGE_ERROR: + fputs_unfiltered (",error=\"command-usage\"", raw_stdout); + break; + } + fputs_unfiltered ("\n", raw_stdout); } void diff --git a/gdb/mi/mi-parse.c b/gdb/mi/mi-parse.c index 9994307..2c9d267 100644 --- a/gdb/mi/mi-parse.c +++ b/gdb/mi/mi-parse.c @@ -285,7 +285,8 @@ mi_parse (const char *cmd, char **token) /* Find the command in the MI table. */ parse->cmd = mi_lookup (parse->command); if (parse->cmd == NULL) - error (_("Undefined MI command: %s"), parse->command); + throw_error (UNKNOWN_COMMAND_ERROR, + _("Undefined MI command: %s"), parse->command); /* Skip white space following the command. */ chp = skip_spaces_const (chp); @@ -324,7 +325,8 @@ mi_parse (const char *cmd, char **token) option = "--thread-group"; if (parse->thread_group != -1) - error (_("Duplicate '--thread-group' option")); + throw_error (COMMAND_USAGE_ERROR, + _("Duplicate '--thread-group' option")); chp += tgs; if (*chp != 'i') error (_("Invalid thread group id")); @@ -338,7 +340,8 @@ mi_parse (const char *cmd, char **token) option = "--thread"; if (parse->thread != -1) - error (_("Duplicate '--thread' option")); + throw_error (COMMAND_USAGE_ERROR, + _("Duplicate '--thread' option")); chp += ts; parse->thread = strtol (chp, &endp, 10); chp = endp; @@ -349,7 +352,8 @@ mi_parse (const char *cmd, char **token) option = "--frame"; if (parse->frame != -1) - error (_("Duplicate '--frame' option")); + throw_error (COMMAND_USAGE_ERROR, + _("Duplicate '--frame' option")); chp += fs; parse->frame = strtol (chp, &endp, 10); chp = endp; @@ -367,7 +371,8 @@ mi_parse (const char *cmd, char **token) parse->language = language_enum (lang_name); if (parse->language == language_unknown || parse->language == language_auto) - error (_("Invalid --language argument: %s"), lang_name); + throw_error (COMMAND_USAGE_ERROR, + _("Invalid --language argument: %s"), lang_name); do_cleanups (old_chain); } @@ -414,7 +419,8 @@ mi_parse_print_values (const char *name) || strcmp (name, mi_simple_values) == 0) return PRINT_SIMPLE_VALUES; else - error (_("Unknown value for PRINT_VALUES: must be: \ + throw_error (COMMAND_USAGE_ERROR, + _("Unknown value for PRINT_VALUES: must be: \ 0 or \"%s\", 1 or \"%s\", 2 or \"%s\""), - mi_no_values, mi_all_values, mi_simple_values); + mi_no_values, mi_all_values, mi_simple_values); }