Esempio n. 1
0
struct mi_parse *
mi_parse (char *cmd)
{
  char *chp;
  struct mi_parse *parse = XMALLOC (struct mi_parse);
  memset (parse, 0, sizeof (*parse));

  /* Before starting, skip leading white space. */
  while (isspace (*cmd))
    cmd++;

  /* Find/skip any token and then extract it. */
  for (chp = cmd; *chp >= '0' && *chp <= '9'; chp++)
    ;
  parse->token = xmalloc ((chp - cmd + 1) * sizeof (char *));
  memcpy (parse->token, cmd, (chp - cmd));
  parse->token[chp - cmd] = '\0';

  /* This wasn't a real MI command.  Return it as a CLI_COMMAND. */
  if (*chp != '-')
    {
      while (isspace (*chp))
	chp++;
      parse->command = xstrdup (chp);
      parse->op = CLI_COMMAND;
      return parse;
    }

  /* Extract the command. */
  {
    char *tmp = chp + 1;	/* discard ``-'' */
    for (; *chp && !isspace (*chp); chp++)
      ;
    parse->command = xmalloc ((chp - tmp + 1) * sizeof (char *));
    memcpy (parse->command, tmp, chp - tmp);
    parse->command[chp - tmp] = '\0';
  }

  /* Find the command in the MI table. */
  parse->cmd = mi_lookup (parse->command);
  if (parse->cmd == NULL)
    {
      /* FIXME: This should be a function call. */
      fprintf_unfiltered
	(raw_stdout,
	 "%s^error,msg=\"Undefined MI command: %s\"\n",
	 parse->token, parse->command);
      mi_parse_free (parse);
      return NULL;
    }

  /* Skip white space following the command. */
  while (isspace (*chp))
    chp++;

  /* For new argv commands, attempt to return the parsed argument
     list. */
  if (parse->cmd->argv_func != NULL)
    {
      mi_parse_argv (chp, parse);
      if (parse->argv == NULL)
	{
	  /* FIXME: This should be a function call. */
	  fprintf_unfiltered
	    (raw_stdout,
	     "%s^error,msg=\"Problem parsing arguments: %s %s\"\n",
	     parse->token, parse->command, chp);
	  mi_parse_free (parse);
	  return NULL;
	}
    }

  /* FIXME: DELETE THIS */
  /* For CLI and old ARGS commands, also return the remainder of the
     command line as a single string. */
  if (parse->cmd->args_func != NULL
      || parse->cmd->cli.cmd != NULL)
    {
      parse->args = xstrdup (chp);
    }

  /* Fully parsed. */
  parse->op = MI_COMMAND;
  return parse;
}
struct mi_parse *
mi_parse (char *cmd)
{
  char *chp;
  struct mi_parse *parse = XMALLOC (struct mi_parse);

  memset (parse, 0, sizeof (*parse));
  parse->all = 0;
  parse->thread_group = -1;
  parse->thread = -1;
  parse->frame = -1;

  /* Before starting, skip leading white space. */
  while (isspace (*cmd))
    cmd++;

  /* Find/skip any token and then extract it. */
  for (chp = cmd; *chp >= '0' && *chp <= '9'; chp++)
    ;
  parse->token = xmalloc ((chp - cmd + 1) * sizeof (char *));
  memcpy (parse->token, cmd, (chp - cmd));
  parse->token[chp - cmd] = '\0';

  /* This wasn't a real MI command.  Return it as a CLI_COMMAND. */
  if (*chp != '-')
    {
      while (isspace (*chp))
	chp++;
      parse->command = xstrdup (chp);
      parse->op = CLI_COMMAND;
      return parse;
    }

  /* Extract the command. */
  {
    char *tmp = chp + 1;	/* discard ``-'' */

    for (; *chp && !isspace (*chp); chp++)
      ;
    parse->command = xmalloc ((chp - tmp + 1) * sizeof (char *));
    memcpy (parse->command, tmp, chp - tmp);
    parse->command[chp - tmp] = '\0';
  }

  /* Find the command in the MI table. */
  parse->cmd = mi_lookup (parse->command);
  if (parse->cmd == NULL)
    {
      /* FIXME: This should be a function call. */
      fprintf_unfiltered
	(raw_stdout,
	 "%s^error,msg=\"Undefined MI command: %s\"\n",
	 parse->token, parse->command);
      mi_parse_free (parse);
      return NULL;
    }

  /* Skip white space following the command. */
  while (isspace (*chp))
    chp++;

  /* Parse the --thread and --frame options, if present.  At present,
     some important commands, like '-break-*' are implemented by forwarding
     to the CLI layer directly.  We want to parse --thread and --frame
     here, so as not to leave those option in the string that will be passed
     to CLI.  */
  for (;;)
    {
      char *start = chp;
      size_t as = sizeof ("--all ") - 1;
      size_t tgs = sizeof ("--thread-group ") - 1;
      size_t ts = sizeof ("--thread ") - 1;
      size_t fs = sizeof ("--frame ") - 1;

      if (strncmp (chp, "--all ", as) == 0)
	{
	  parse->all = 1;
	  chp += as;
	}
      /* See if --all is the last token in the input.  */
      if (strcmp (chp, "--all") == 0)
	{
          parse->all = 1;
          chp += strlen (chp);
        }
      if (strncmp (chp, "--thread-group ", tgs) == 0)
	{
	  if (parse->thread_group != -1)
	    error (_("Duplicate '--thread-group' option"));
	  chp += tgs;
	  if (*chp != 'i')
	    error (_("Invalid thread group id"));
	  chp += 1;
	  parse->thread_group = strtol (chp, &chp, 10);
	}
      if (strncmp (chp, "--thread ", ts) == 0)
	{
	  if (parse->thread != -1)
	    error (_("Duplicate '--thread' option"));
	  chp += ts;
	  parse->thread = strtol (chp, &chp, 10);
	}
      else if (strncmp (chp, "--frame ", fs) == 0)
	{
	  if (parse->frame != -1)
	    error (_("Duplicate '--frame' option"));
	  chp += fs;
	  parse->frame = strtol (chp, &chp, 10);
	}
      else
	break;

      if (*chp != '\0' && !isspace (*chp))
	error (_("Invalid value for the '%s' option"),
	       start[2] == 't' ? "--thread" : "--frame");
      while (isspace (*chp))
	chp++;
    }

  /* For new argv commands, attempt to return the parsed argument
     list. */
  if (parse->cmd->argv_func != NULL)
    {
      mi_parse_argv (chp, parse);
      if (parse->argv == NULL)
	{
	  /* FIXME: This should be a function call. */
	  fprintf_unfiltered
	    (raw_stdout,
	     "%s^error,msg=\"Problem parsing arguments: %s %s\"\n",
	     parse->token, parse->command, chp);
	  mi_parse_free (parse);
	  return NULL;
	}
    }

  /* FIXME: DELETE THIS */
  /* For CLI commands, also return the remainder of the
     command line as a single string. */
  if (parse->cmd->cli.cmd != NULL)
    parse->args = xstrdup (chp);

  /* Fully parsed. */
  parse->op = MI_COMMAND;
  return parse;
}