This is the mail archive of the
gdb-patches@sources.redhat.com
mailing list for the GDB project.
Re: MI handshaking
- From: Bob Rossi <bob at brasko dot net>
- To: gdb-patches at sources dot redhat dot com
- Date: Thu, 4 Nov 2004 14:59:33 -0500
- Subject: Re: MI handshaking
- References: <20041104195701.GA7296@white>
BTW, here is an example of how it looks,
$ ../../objdir3/gdb/gdb -i=mi
mi_handshake={stable=mi2}
~"GNU gdb 6.3.50_2004-11-04-cvs\n"
~"Copyright 2004 Free Software Foundation, Inc.\n"
~"GDB is free software, covered by the GNU General Public License, and you are\n"
~"welcome to change it and/or distribute copies of it under certain conditions.\n"
~"Type \"show copying\" to see the conditions.\n"
~"There is absolutely no warranty for GDB. Type \"show warranty\" for details.\n"
~"This GDB was configured as \"i686-pc-linux-gnu\"."
~"\n"
(gdb)
I can obviously change the syntax of the output if it is desired.
There should probably be a '~' or something like that, any suggestions?
Bob Rossi
On Thu, Nov 04, 2004 at 02:57:01PM -0500, Bob Rossi wrote:
> Hi,
>
> Here is a simple patch that I think will make everyone happy. It allows
> the MI to handshake with the front end.
>
> * It prints all the stable MI versions ( currently only 1 )
> * If there is more than one stable version ( which there isn't ) it
> let's the front end select the protocol to use.
>
> This happens only when the front end selects -i=mi, anything like -i=mi2
> will go directly to mi2 without the output.
>
> 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?
>
> Thanks,
> Bob Rossi
>
> * interps.c (struct interp): add field, handshake
> (interp_new): Add parameter, handshake
> (interp_can_handshake,interp_handshake): add function definitions
> * interps.h (interp_handshake_ftype): add typedef
> (interp_new): Add parameter, handshake
> (interp_can_handshake,interp_handshake): add function prototype
> * main.c (captured_main): Add the handshaking code
> * cli/cli-interp.c (_initialize_cli_interp): changed interface to
> interp_new
> * mi/mi-interp.c (stable_mi_versions): add table of stable MI versions
> (mi_handshake): Add function to do handshaking
> (_initialize_mi_interp): changed interface to interp_new
> * tui/tui-interp.c (_initialize_tui_interp): changed interface to
> interp_new
>
> Index: interps.c
> ===================================================================
> RCS file: /cvs/src/src/gdb/interps.c,v
> retrieving revision 1.8
> diff -w -u -r1.8 interps.c
> --- interps.c 13 Sep 2004 18:26:30 -0000 1.8
> +++ interps.c 4 Nov 2004 19:05:33 -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: interps.h
> ===================================================================
> RCS file: /cvs/src/src/gdb/interps.h,v
> retrieving revision 1.6
> diff -w -u -r1.6 interps.h
> --- interps.h 18 Feb 2004 19:01:36 -0000 1.6
> +++ interps.h 4 Nov 2004 19:05:33 -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: main.c
> ===================================================================
> RCS file: /cvs/src/src/gdb/main.c,v
> retrieving revision 1.44
> diff -w -u -r1.44 main.c
> --- main.c 10 Aug 2004 22:36:39 -0000 1.44
> +++ main.c 4 Nov 2004 19:05:34 -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: 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
> --- cli/cli-interp.c 3 Jul 2003 14:49:26 -0000 1.4
> +++ cli/cli-interp.c 4 Nov 2004 19:05:34 -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: 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
> --- mi/mi-interp.c 13 Sep 2004 18:26:31 -0000 1.11
> +++ mi/mi-interp.c 4 Nov 2004 19:05:34 -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, "mi_handshake={" );
> +
> + /* 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, "stable=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: 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
> --- tui/tui-interp.c 7 Feb 2004 04:40:36 -0000 1.5
> +++ tui/tui-interp.c 4 Nov 2004 19:05:35 -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;
>