From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 20983 invoked by alias); 4 Nov 2004 19:57:05 -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 20971 invoked from network); 4 Nov 2004 19:57:02 -0000 Received: from unknown (HELO lakermmtao01.cox.net) (68.230.240.38) by sourceware.org with SMTP; 4 Nov 2004 19:57:02 -0000 Received: from white ([68.9.64.121]) by lakermmtao01.cox.net (InterMail vM.6.01.04.00 201-2131-117-20041022) with ESMTP id <20041104195700.NCLC10850.lakermmtao01.cox.net@white> for ; Thu, 4 Nov 2004 14:57:00 -0500 Received: from bob by white with local (Exim 3.35 #1 (Debian)) id 1CPnjB-0001vU-00 for ; Thu, 04 Nov 2004 14:57:01 -0500 Date: Thu, 04 Nov 2004 19:57:00 -0000 From: Bob Rossi To: gdb-patches@sources.redhat.com Subject: MI handshaking Message-ID: <20041104195701.GA7296@white> Mail-Followup-To: gdb-patches@sources.redhat.com Mime-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline User-Agent: Mutt/1.3.28i X-SW-Source: 2004-11/txt/msg00067.txt.bz2 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;