MI handshaking

Andrew Cagney cagney@gnu.org
Thu Nov 11 20:30:00 GMT 2004


(as is obvious, 6.3 is effectively out, I'm draining the queue)

Bob Rossi wrote:
> 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?

Hmm, it's async (or unprompted), has the hypothetical potential for 
multiple values, and leaves us wondering which of those values it choose:

*mi-handshake={version=mi2,stable=[mi2]}

it should also appear after the copyright.

Oh and testing ;-)

Nick, Alain, comments?

Andrew

PS: I'd clean up the ChangeLogS a little, for instance:

      * interps.c (struct interp): add field, handshake

did you mean:

      * interps.c (struct interp): Add field "handshake".

?

> 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;
>> 
> 
> 



More information about the Gdb-patches mailing list