From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 6149 invoked by alias); 11 May 2006 10:54:56 -0000 Received: (qmail 6141 invoked by uid 22791); 11 May 2006 10:54:55 -0000 X-Spam-Check-By: sourceware.org Received: from eastrmmtao04.cox.net (HELO eastrmmtao04.cox.net) (68.230.240.35) by sourceware.org (qpsmtpd/0.31) with ESMTP; Thu, 11 May 2006 10:54:53 +0000 Received: from localhost.localdomain ([68.9.66.48]) by eastrmmtao04.cox.net (InterMail vM.6.01.06.01 201-2131-130-101-20060113) with ESMTP id <20060511105451.UTDX9931.eastrmmtao04.cox.net@localhost.localdomain>; Thu, 11 May 2006 06:54:51 -0400 Received: from bob by localhost.localdomain with local (Exim 4.52) id 1Fe8pP-00080t-4H; Thu, 11 May 2006 06:55:31 -0400 Date: Thu, 11 May 2006 11:14:00 -0000 From: Bob Rossi To: Vladimir Prus Cc: Alain Magloire , gdb@sources.redhat.com Subject: Re: asynchronous MI output commands Message-ID: <20060511105531.GG3727@brasko.net> Mail-Followup-To: Vladimir Prus , Alain Magloire , gdb@sources.redhat.com References: <3518719F06577C4F85DA618E3C37AB9105359CCA@nimbus.ott.qnx.com> <200605111008.15930.ghost@cs.msu.su> <20060511104034.GE3727@brasko.net> <200605111447.37126.ghost@cs.msu.su> Mime-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <200605111447.37126.ghost@cs.msu.su> User-Agent: Mutt/1.5.9i X-IsSubscribed: yes Mailing-List: contact gdb-help@sourceware.org; run by ezmlm Precedence: bulk List-Subscribe: List-Archive: List-Post: List-Help: , Sender: gdb-owner@sourceware.org X-SW-Source: 2006-05/txt/msg00133.txt.bz2 > > > > > Maybe I'm mistaken but I have the impression, looking at the thread, > > > > > some folks are confusing OOB and synchronous response that comes > > > > > after issuing a command. > > > > > > > > I'm hopefull not confusing them, but maybe. For synchronous commands, I > > > > just think it's a little ugly that you need the MI input command to > > > > determine what an MI output command is. > > > > > > What do you mean by "determine what an MI output command is"? You > > > certainly can parse the response into DOM-like tree without knowing the > > > output command. If you want to create C data structures for each > > > response, then yes, you'd need to know the exact type of the last > > > command. But then, I'm not sure why you want to use C data structures. In > > > KDevelop, the DOM is fully dynamic and that works just fine, for example: > > > > > > const GDBMI::Value& children = r["children"]; > > > > > > for (unsigned i = 0; i < children.size(); ++i) > > > { > > > QString exp = children[i]["exp"].literal(); > > > > > > > > > If you have specific structures for each response this won't be very much > > > simpler. > > > > Sorry, I've described this before, but apparently not good enough. I > > definatly can create the abstract parse tree with out knowing the input > > command. However, then I want to create C data structures for each > > MI output. > > Why? With C data structures, the above frontend code will be only marginally > simpler. I don't believe that to be the case at all. Look at the C data structure code I have for the -break-list data structure. If a GUI had to use this I think they would be happy. enum breakpoint_type { GDBMI_BREAKPOINT, GDBMI_WATCHPOINT }; enum breakpoint_disposition { GDBMI_KEEP, GDBMI_NOKEEP }; struct gdbmi_oc_breakpoint; typedef struct gdbmi_oc_breakpoint *gdbmi_oc_breakpoint_ptr; struct gdbmi_oc_breakpoint { int number; enum breakpoint_type type; enum breakpoint_disposition disposition; /* 1 if enabled, otherwise 0 */ int enabled; char *address; char *func; char *file; char *fullname; int line; int times; gdbmi_oc_breakpoint_ptr next; }; Look at what I had to do to get the breakpoint structure populated. I don't consider this even close to the same complexity as above. I do know that I have some code duplicated that could be in a function, and some other cleanups, but I still think it's far more difficult. *Also*, if the MI output changes in some wierd way, the GUI will have to code both of these possibilies, instead of just the piece that parses the MI and stores them into a C data structure. For instance, when MI3 comes out and is potentially not backwards compatible. gdbmi_result_ptr result_ptr = output_ptr->result_record->result; if (strcmp (result_ptr->variable, "BreakpointTable") == 0) { if (result_ptr->value->value_choice == GDBMI_TUPLE) { result_ptr = result_ptr->value->option.tuple->result; while (result_ptr) { if (strcmp (result_ptr->variable, "body") == 0) { if (result_ptr->value->value_choice == GDBMI_LIST) { gdbmi_list_ptr list_ptr = result_ptr->value->option.list; if (list_ptr && list_ptr->list_choice == GDBMI_RESULT) { gdbmi_result_ptr result_ptr = list_ptr->option.result; while (result_ptr) { if (strcmp (result_ptr->variable, "bkpt") == 0) { gdbmi_oc_breakpoint_ptr ptr = create_gdbmi_breakpoint (); gdbmi_value_ptr value_ptr = result_ptr->value; if (value_ptr->value_choice == GDBMI_TUPLE) { gdbmi_result_ptr result_ptr = value_ptr->option.tuple->result; while (result_ptr) { if (strcmp (result_ptr->variable, "number") == 0) { if (result_ptr->value->value_choice == GDBMI_CSTRING) { char *nstr; if (convert_cstring (result_ptr->value->option.cstring, &nstr) == -1) { fprintf (stderr, "%s:%d\n", __FILE__, __LINE__); return -1; } ptr->number = atoi (nstr); free (nstr); nstr = NULL; } } else if (strcmp (result_ptr->variable, "type") == 0) { if (result_ptr->value->value_choice == GDBMI_CSTRING) { if (strcmp (result_ptr->value->option.cstring, "\"breakpoint\"") == 0) ptr->type = GDBMI_BREAKPOINT; else if (strcmp (result_ptr->value->option.cstring, "\"watchpoint\"") == 0) ptr->type = GDBMI_WATCHPOINT; } } else if (strcmp (result_ptr->variable, "disp") == 0) { if (result_ptr->value->value_choice == GDBMI_CSTRING) { if (strcmp (result_ptr->value->option.cstring, "\"keep\"") == 0) ptr->disposition = GDBMI_KEEP; else if (strcmp (result_ptr->value->option.cstring, "\"nokeep\"") == 0) ptr->disposition = GDBMI_NOKEEP; } } else if (strcmp (result_ptr->variable, "enabled") == 0) { if (result_ptr->value->value_choice == GDBMI_CSTRING) { if (strcmp (result_ptr->value->option.cstring, "\"y\"") == 0) ptr->enabled = 1; else ptr->enabled = 0; } } else if (strcmp (result_ptr->variable, "addr") == 0) { if (result_ptr->value->value_choice == GDBMI_CSTRING) { if (convert_cstring (result_ptr->value->option.cstring, &ptr->address) == -1) { fprintf (stderr, "%s:%d\n", __FILE__, __LINE__); return -1; } } } else if (strcmp (result_ptr->variable, "func") == 0) { if (result_ptr->value->value_choice == GDBMI_CSTRING) { if (convert_cstring (result_ptr->value->option.cstring, &ptr->func) == -1) { fprintf (stderr, "%s:%d\n", __FILE__, __LINE__); return -1; } } } else if (strcmp (result_ptr->variable, "file") == 0) { if (result_ptr->value->value_choice == GDBMI_CSTRING) { if (convert_cstring (result_ptr->value->option.cstring, &ptr->file) == -1) { fprintf (stderr, "%s:%d\n", __FILE__, __LINE__); return -1; } } } else if (strcmp (result_ptr->variable, "fullname") == 0) { if (result_ptr->value->value_choice == GDBMI_CSTRING) { if (convert_cstring (result_ptr->value->option.cstring, &ptr->fullname) == -1) { fprintf (stderr, "%s:%d\n", __FILE__, __LINE__); return -1; } } } else if (strcmp (result_ptr->variable, "line") == 0) { if (result_ptr->value->value_choice == GDBMI_CSTRING) { char *nstr; if (convert_cstring (result_ptr->value->option.cstring, &nstr) == -1) { fprintf (stderr, "%s:%d\n", __FILE__, __LINE__); return -1; } ptr->line = atoi (nstr); free (nstr); nstr = NULL; } } else if (strcmp (result_ptr->variable, "times") == 0) { if (result_ptr->value->value_choice == GDBMI_CSTRING) { char *nstr; if (convert_cstring (result_ptr->value->option.cstring, &nstr) == -1) { fprintf (stderr, "%s:%d\n", __FILE__, __LINE__); return -1; } ptr->times = atoi (nstr); free (nstr); nstr = NULL; } } result_ptr = result_ptr->next; } } oc_ptr->input_commands.break_list.breakpoint_ptr = append_gdbmi_breakpoint (oc_ptr->input_commands.break_list.breakpoint_ptr, ptr); } result_ptr = result_ptr->next; } } } } result_ptr = result_ptr->next; } } } Thanks, Bob Rossi