This is the mail archive of the gdb-patches@sources.redhat.com mailing list for the GDB project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: MI handshaking


On Sat, Nov 06, 2004 at 12:07:07PM +0200, Eli Zaretskii wrote:
> > Date: Fri, 5 Nov 2004 17:12:22 -0500
> > From: Bob Rossi <bob@brasko.net>
> > Cc: gdb-patches@sources.redhat.com
> > 
> > I really am not good at editing info files but am trying to do my
> > best to help out.
> 
> You are doing a good job, although I have a few more minor comments,
> see below.
> 

OK, all the issues should be resolved. Here is a final patch with the
doco changes. Thanks for the speedy reply Eli.

Does anyone want to approve the code part of this patch? Any suggestions
on how to make it better?

Again the output looks like this,

$ gdb -i=mi
handshake={stable_protocols={mi2}}
~"GNU gdb 6.3.50_2004-11-08-cvs\n"

Would it be better to have a special char at the beggining? and put the
whole thing in quotes? 

I think it's good the way it is, because it's not actually in MI mode.

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

+    * gdb.texinfo (MI menu): Add 'GDB/MI Handshaking Interface'
+	(GDB/MI Command Syntax menu): Add 'GDB/MI Handshaking Syntax'
+	(GDB/MI Handshaking Syntax): Add new node
+	(GDB/MI Handshaking Interface): Add new node

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	8 Nov 2004 14:43:07 -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	8 Nov 2004 14:43:07 -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	8 Nov 2004 14:43:07 -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	8 Nov 2004 14:43:08 -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	8 Nov 2004 14:43:22 -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,53 @@
 @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
+
+For more information on handshaking see @ref{GDB/MI Handshaking Interface}.
+
 @node GDB/MI Input Syntax
 @subsection @sc{gdb/mi} Input Syntax
 
@@ -15314,6 +15357,51 @@
 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 @samp{-i=mi@var{n}}, 
+where @var{n} is the MI protocol version (@pxref{Interpreters}).  When invoked 
+with a specific version of the MI interpreter, @value{GDBN} will bypass the 
+handshaking mode and go directly into the version of the MI that it requested.  
+However, if @value{GDBN} is started with the @samp{-i=mi} flag, then this tells 
+@value{GDBN} to go into its 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 @dfn{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 
+@samp{-i=mi@var{n}}, where @var{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 then
+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, then 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.
+
+@cindex stable MI protocol
+You could have a @value{GDBN} version that is capable of communicating with
+several versions of the @sc{mi} protocol.  In general, an official release or
+a CVS snapshot will have deprecated @sc{mi} protocols, stable @sc{mi} 
+protocols and development @sc{mi} protocols.  The deprecated @sc{mi} protocols
+are kept around in @value{GDBN} for some period of time and then will 
+eventually get removed.  The stable MI protocols are considered stable
+because they were tested when the particular @value{GDBN} program you have was
+created.  The development @sc{mi} protocols are not ready to be used since
+there is a good change there will be incompatible changes made to it before it
+can become a stable protocol.
+
+@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	8 Nov 2004 14:43:22 -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	8 Nov 2004 14:43:23 -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;
 


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]