From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 8958 invoked by alias); 5 Nov 2004 16:39:38 -0000 Mailing-List: contact gdb-patches-help@sources.redhat.com; run by ezmlm Precedence: bulk List-Subscribe: List-Archive: List-Post: List-Help: , Sender: gdb-patches-owner@sources.redhat.com Received: (qmail 8789 invoked from network); 5 Nov 2004 16:39:34 -0000 Received: from unknown (HELO lakermmtao11.cox.net) (68.230.240.28) by sourceware.org with SMTP; 5 Nov 2004 16:39:34 -0000 Received: from white ([68.9.64.121]) by lakermmtao11.cox.net (InterMail vM.6.01.04.00 201-2131-117-20041022) with ESMTP id <20041105163933.JFEW1734.lakermmtao11.cox.net@white>; Fri, 5 Nov 2004 11:39:33 -0500 Received: from bob by white with local (Exim 3.35 #1 (Debian)) id 1CQ77d-0002ED-00; Fri, 05 Nov 2004 11:39:33 -0500 Date: Fri, 05 Nov 2004 16:39:00 -0000 From: Bob Rossi To: Eli Zaretskii Cc: gdb-patches@sources.redhat.com Subject: Re: MI handshaking Message-ID: <20041105163933.GB8318@white> Mail-Followup-To: Eli Zaretskii , gdb-patches@sources.redhat.com References: <20041104195701.GA7296@white> <01c4c2b4$Blat.v2.2.2$a21985e0@zahav.net.il> Mime-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <01c4c2b4$Blat.v2.2.2$a21985e0@zahav.net.il> User-Agent: Mutt/1.3.28i X-SW-Source: 2004-11/txt/msg00079.txt.bz2 On Thu, Nov 04, 2004 at 11:23:11PM +0200, Eli Zaretskii wrote: > > Date: Thu, 4 Nov 2004 14:57:01 -0500 > > From: Bob Rossi > > > > The one question I have is, should the documentation for this be in the > > MI output syntax? or should there me a new field called > > MI handshaking syntax? > > I'd prefer a new subsection right at the beginning of the GDB/MI > description in the manual. That way, someone who designs a front end > will see this stuff when she begins reading the docs. Here is the new patch, with the doco sections. Does anyone care if the output of the handshaking starts with a special char like '~' or something? Or should I leave it the way it is below? $ ./gdb/gdb -i=mi handshake={stable_protocols={mi2}} ~"GNU gdb 6.3.50_2004-11-05-cvs\n" ~"Copyright 2004 Free Software Foundation, Inc.\n" Any suggestions? Thanks, Bob Rossi Index: gdb/interps.c =================================================================== RCS file: /cvs/src/src/gdb/interps.c,v retrieving revision 1.8 diff -w -u -r1.8 interps.c --- gdb/interps.c 13 Sep 2004 18:26:30 -0000 1.8 +++ gdb/interps.c 5 Nov 2004 16:36:28 -0000 @@ -68,6 +68,8 @@ const struct interp_procs *procs; int quiet_p; + + interp_handshake_ftype *handshake; }; /* Functions local to this file. */ @@ -90,7 +92,7 @@ interpreter. */ struct interp * interp_new (const char *name, void *data, struct ui_out *uiout, - const struct interp_procs *procs) + const struct interp_procs *procs, interp_handshake_ftype *handshake) { struct interp *new_interp; @@ -102,6 +104,7 @@ new_interp->quiet_p = 0; new_interp->procs = procs; new_interp->inited = 0; + new_interp->handshake = handshake; return new_interp; } @@ -239,6 +242,22 @@ return current_interpreter->interpreter_out; } +int +interp_can_handshake (struct interp *interp) +{ + if (interp != NULL) + if (interp->handshake) + return 1; + + return 0; +} + +struct interp * +interp_handshake (struct interp *interp) +{ + return interp_lookup (interp->handshake (gdb_stdout, gdb_stdin)); +} + /* Returns true if the current interp is the passed in name. */ int current_interp_named_p (const char *interp_name) Index: gdb/interps.h =================================================================== RCS file: /cvs/src/src/gdb/interps.h,v retrieving revision 1.6 diff -w -u -r1.6 interps.h --- gdb/interps.h 18 Feb 2004 19:01:36 -0000 1.6 +++ gdb/interps.h 5 Nov 2004 16:36:28 -0000 @@ -40,6 +40,7 @@ typedef int (interp_prompt_p_ftype) (void *data); typedef int (interp_exec_ftype) (void *data, const char *command); typedef void (interp_command_loop_ftype) (void *data); +typedef const char *(interp_handshake_ftype) (struct ui_file *gdb_stdout, struct ui_file *gdb_stdin); struct interp_procs { @@ -53,11 +54,14 @@ extern struct interp *interp_new (const char *name, void *data, struct ui_out *uiout, - const struct interp_procs *procs); + const struct interp_procs *procs, + interp_handshake_ftype *handshake); extern void interp_add (struct interp *interp); extern int interp_set (struct interp *interp); extern struct interp *interp_lookup (const char *name); extern struct ui_out *interp_ui_out (struct interp *interp); +extern int interp_can_handshake (struct interp *interp); +extern struct interp *interp_handshake (struct interp *interp); extern int current_interp_named_p (const char *name); extern int current_interp_display_prompt_p (void); Index: gdb/main.c =================================================================== RCS file: /cvs/src/src/gdb/main.c,v retrieving revision 1.44 diff -w -u -r1.44 main.c --- gdb/main.c 10 Aug 2004 22:36:39 -0000 1.44 +++ gdb/main.c 5 Nov 2004 16:36:28 -0000 @@ -561,8 +561,13 @@ { /* Find it. */ struct interp *interp = interp_lookup (interpreter_p); + + if (interp && interp_can_handshake (interp)) + interp = interp_handshake (interp); + if (interp == NULL) error ("Interpreter `%s' unrecognized", interpreter_p); + /* Install it. */ if (!interp_set (interp)) { Index: gdb/cli/cli-interp.c =================================================================== RCS file: /cvs/src/src/gdb/cli/cli-interp.c,v retrieving revision 1.4 diff -w -u -r1.4 cli-interp.c --- gdb/cli/cli-interp.c 3 Jul 2003 14:49:26 -0000 1.4 +++ gdb/cli/cli-interp.c 5 Nov 2004 16:36:29 -0000 @@ -151,7 +151,7 @@ /* Create a default uiout builder for the CLI. */ cli_uiout = cli_out_new (gdb_stdout); - cli_interp = interp_new (INTERP_CONSOLE, NULL, cli_uiout, &procs); + cli_interp = interp_new (INTERP_CONSOLE, NULL, cli_uiout, &procs, NULL); interp_add (cli_interp); } Index: gdb/doc/gdb.texinfo =================================================================== RCS file: /cvs/src/src/gdb/doc/gdb.texinfo,v retrieving revision 1.222 diff -w -u -r1.222 gdb.texinfo --- gdb/doc/gdb.texinfo 23 Oct 2004 15:05:29 -0000 1.222 +++ gdb/doc/gdb.texinfo 5 Nov 2004 16:36:41 -0000 @@ -14997,6 +14997,7 @@ @menu * GDB/MI Command Syntax:: * GDB/MI Compatibility with CLI:: +* GDB/MI Handshaking Interface:: * GDB/MI Output Records:: * GDB/MI Command Description Format:: * GDB/MI Breakpoint Table Commands:: @@ -15021,11 +15022,50 @@ @section @sc{gdb/mi} Command Syntax @menu +* GDB/MI Handshaking Syntax:: * GDB/MI Input Syntax:: * GDB/MI Output Syntax:: * GDB/MI Simple Examples:: @end menu +@node GDB/MI Handshaking Syntax +@subsection @sc{gdb/mi} Handshaking Syntax + +@cindex handshaking syntax for @sc{gdb/mi} +@cindex @sc{gdb/mi}, handshaking syntax +@table @code +@item @var{handshake_output} @expansion{} +@code{"handshake=@{stable_protocols=@{" @var{mi-protocol-list} +"@}" @var{nl}} + +@item @var{mi-protocol-list} @expansion{} +@code{ epsilon | @var{mi-protocol} | @var{mi-protocol-list} "," @var{mi-protocol} } + +@item @var{mi-protocol} @expansion{} +@code{ "mi" @var{token} } + +@item @var{token} @expansion{} +"any sequence of digits" + +@item @var{nl} @expansion{} +@code{CR | CR-LF} +@end table + +@noindent +Notes: + +@itemize @bullet +@item +If only one stable @sc{mi} protocol is supported by a particular release of +@value{GDBN}, then that release is used and the caller does not have to +do anything. + +@item +If there is more than one stable @sc{mi} protocol supported by a particular +release of @value{GDBN}, then the caller has to specify which version of the +@sc{mi} protocol it wants @value{GDBN} to communicate with. +@end itemize + @node GDB/MI Input Syntax @subsection @sc{gdb/mi} Input Syntax @@ -15111,6 +15151,9 @@ @var{token}. @table @code +@item @var{output-list} @expansion{} +@code{@var{output} | @var{output-list} @var{output}} + @item @var{output} @expansion{} @code{( @var{out-of-band-record} )* [ @var{result-record} ] "(@value{GDBP})" @var{nl}} @@ -15314,6 +15357,38 @@ an un-supported hybrid of @sc{gdb/mi} and CLI output. @c %%%%%%%%%%%%%%%%%%%%%%%%%%%% SECTION %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +@node GDB/MI Handshaking Interface +@section @sc{gdb/mi} Handshaking Interface + +@cindex @sc{gdb/mi}, handshaking interface +@value{GDBN} is capable of speaking several MI protocols at a time. This +interface is intended to help developers understand what version of the MI +protocol that a particular @value{GDBN} is going to communicate with. + +It is possible to start the @sc{gdb/mi} interpreter using -i=mi1, -i=mi2, or +simply with -i=mi. If a front end starts @value{GDBN} with -i=miN it will +bypass the handshaking mode and will go directly into the version of the MI +that it requested. However, if @value{GDBN} is started with the -i=mi flag, +then this tells @value{GDBN} to go into it's handshaking mode with the +client to determine the correct MI protocol to communicate with. + +@value{GDBN} will output all of the stable versions of the MI protocol that +it supports. The term "stable MI protocol" simply means that the protocol +was tested when this particular release was made. Protocols that are no longer +tested in the @value{GDBN} testsuite will not be considered a stable release. +If the caller still wishes to communicate with @value{GDBN} using one of these +untested protocols, they could simply try to invoke @value{GDBN} with -i=miN, +where N is version they wish to communicate with. + +@value{GDBN} will output all of the stable MI versions that it supports. +If a specific version of @value{GDBN} speaks only one stable MI protocol than +it will begin communicating with that version of the protocol. The front end +has no way to change this version. However, if @value{GDBN} speaks several +versions of the MI protocol, than it will output a list of these protocols +and the front end then has to choose the version that it wants @value{GDBN} +to communicate with. + +@c %%%%%%%%%%%%%%%%%%%%%%%%%%%% SECTION %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% @node GDB/MI Output Records @section @sc{gdb/mi} Output Records Index: gdb/mi/mi-interp.c =================================================================== RCS file: /cvs/src/src/gdb/mi/mi-interp.c,v retrieving revision 1.11 diff -w -u -r1.11 mi-interp.c --- gdb/mi/mi-interp.c 13 Sep 2004 18:26:31 -0000 1.11 +++ gdb/mi/mi-interp.c 5 Nov 2004 16:36:42 -0000 @@ -364,6 +364,66 @@ start_event_loop (); } +/* The latest stable mi version that is being tested. + There could potentially be several versions of MI that are stable + at a time. */ +static const int stable_mi_versions[] = +{ + 2, + 0 +}; + +/* Allows MI and the front end to agree on an MI protocol. + + All of the stable MI versions are currently printed. If there is more + than one stable MI version, than it is expected the user will write + back the version they want to communicate with. + + Returns the MI version string the user requested, or if there is only + one version, that string is returned. */ +static const char *mi_handshake (struct ui_file *gdb_stdout, + struct ui_file *gdb_stdin) +{ + static char mi_buf[32]; + int i; + + if (!gdb_stdout || !gdb_stdin) + return NULL; + + /* Output the header, can't use mi_out stuff because no mi has + been chosen and initialized yet. */ + fprintf_unfiltered ( gdb_stdout, "handshake={stable_protocols={" ); + + /* Output all the stable versions */ + for (i = 0; stable_mi_versions[i] != 0; ++i ) + { + if (i > 0) + fprintf_unfiltered (gdb_stdout, ","); + + fprintf_unfiltered (gdb_stdout, "mi%d", stable_mi_versions[i] ); + } + + fprintf_unfiltered ( gdb_stdout, "}}\n" ); + + /* If there was more than one stable version outputted, ask the front + end which one it should use */ + if ( i > 1 ) + { + int size; + size = ui_file_read ( gdb_stdin, mi_buf, 31 ); + mi_buf[size--] = 0; /* null terminate, and remove new line */ + while ( size >= 0 && (mi_buf[size] == '\n' || mi_buf[size] == '\r') ) + mi_buf[size--] = 0; + + /* The mi option is not valid in this mode. */ + if ( strcmp ( mi_buf, "mi" ) == 0 ) + return NULL; + } else + sprintf ( mi_buf, "mi%d", stable_mi_versions[0] ); + + return mi_buf; +} + extern initialize_file_ftype _initialize_mi_interp; /* -Wmissing-prototypes */ void @@ -379,11 +439,11 @@ }; /* The various interpreter levels. */ - interp_add (interp_new (INTERP_MI1, NULL, mi_out_new (1), &procs)); - interp_add (interp_new (INTERP_MI2, NULL, mi_out_new (2), &procs)); - interp_add (interp_new (INTERP_MI3, NULL, mi_out_new (3), &procs)); + interp_add (interp_new (INTERP_MI1, NULL, mi_out_new (1), &procs, NULL)); + interp_add (interp_new (INTERP_MI2, NULL, mi_out_new (2), &procs, NULL)); + interp_add (interp_new (INTERP_MI3, NULL, mi_out_new (3), &procs, NULL)); /* "mi" selects the most recent released version. "mi2" was released as part of GDB 6.0. */ - interp_add (interp_new (INTERP_MI, NULL, mi_out_new (2), &procs)); + interp_add (interp_new (INTERP_MI, NULL, mi_out_new (stable_mi_versions[0]), &procs, mi_handshake)); } Index: gdb/tui/tui-interp.c =================================================================== RCS file: /cvs/src/src/gdb/tui/tui-interp.c,v retrieving revision 1.5 diff -w -u -r1.5 tui-interp.c --- gdb/tui/tui-interp.c 7 Feb 2004 04:40:36 -0000 1.5 +++ gdb/tui/tui-interp.c 5 Nov 2004 16:36:43 -0000 @@ -198,7 +198,7 @@ /* Create a default uiout builder for the TUI. */ tui_out = tui_out_new (gdb_stdout); - interp_add (interp_new ("tui", NULL, tui_out, &procs)); + interp_add (interp_new ("tui", NULL, tui_out, &procs, NULL)); if (interpreter_p && strcmp (interpreter_p, "tui") == 0) tui_start_enabled = 1;