This is the mail archive of the gdb@sourceware.org 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: asynchronous MI output commands


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


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