cli-decode.c

来自「这个是LINUX下的GDB调度工具的源码」· C语言 代码 · 共 1,605 行 · 第 1/4 页

C
1,605
字号
    {      fprintf_filtered (stream, "\n\Type \"help%s\" followed by a class name for a list of commands in ",			cmdtype1);      wrap_here ("");      fprintf_filtered (stream, "that class.");    }  fprintf_filtered (stream, "\nType \"help%s\" followed by %scommand name ",		    cmdtype1, cmdtype2);  wrap_here ("");  fputs_filtered ("for ", stream);  wrap_here ("");  fputs_filtered ("full ", stream);  wrap_here ("");  fputs_filtered ("documentation.\n", stream);  fputs_filtered ("Command name abbreviations are allowed if unambiguous.\n",		  stream);}static voidhelp_all (struct ui_file *stream){  struct cmd_list_element *c;  extern struct cmd_list_element *cmdlist;  for (c = cmdlist; c; c = c->next)    {      if (c->abbrev_flag)        continue;      /* If this is a prefix command, print it's subcommands */      if (c->prefixlist)        help_cmd_list (*c->prefixlist, all_commands, c->prefixname, 0, stream);          /* If this is a class name, print all of the commands in the class */      else if (c->func == NULL)        help_cmd_list (cmdlist, c->class, "", 0, stream);    }}/* Print only the first line of STR on STREAM.  */voidprint_doc_line (struct ui_file *stream, char *str){  static char *line_buffer = 0;  static int line_size;  char *p;  if (!line_buffer)    {      line_size = 80;      line_buffer = (char *) xmalloc (line_size);    }  p = str;  while (*p && *p != '\n' && *p != '.' && *p != ',')    p++;  if (p - str > line_size - 1)    {      line_size = p - str + 1;      xfree (line_buffer);      line_buffer = (char *) xmalloc (line_size);    }  strncpy (line_buffer, str, p - str);  line_buffer[p - str] = '\0';  if (islower (line_buffer[0]))    line_buffer[0] = toupper (line_buffer[0]);  ui_out_text (uiout, line_buffer);}/* * Implement a help command on command list LIST. * RECURSE should be non-zero if this should be done recursively on * all sublists of LIST. * PREFIX is the prefix to print before each command name. * STREAM is the stream upon which the output should be written. * CLASS should be: *      A non-negative class number to list only commands in that * class. *      ALL_COMMANDS to list all commands in list. *      ALL_CLASSES  to list all classes in list. * *   Note that RECURSE will be active on *all* sublists, not just the * ones selected by the criteria above (ie. the selection mechanism * is at the low level, not the high-level). */voidhelp_cmd_list (struct cmd_list_element *list, enum command_class class,	       char *prefix, int recurse, struct ui_file *stream){  struct cmd_list_element *c;  for (c = list; c; c = c->next)    {      if (c->abbrev_flag == 0 &&	  (class == all_commands	   || (class == all_classes && c->func == NULL)	   || (class == c->class && c->func != NULL)))	{	  fprintf_filtered (stream, "%s%s -- ", prefix, c->name);	  print_doc_line (stream, c->doc);	  fputs_filtered ("\n", stream);	}      if (recurse	  && c->prefixlist != 0	  && c->abbrev_flag == 0)	help_cmd_list (*c->prefixlist, class, c->prefixname, 1, stream);    }}/* Search the input clist for 'command'.  Return the command if   found (or NULL if not), and return the number of commands   found in nfound */static struct cmd_list_element *find_cmd (char *command, int len, struct cmd_list_element *clist,	  int ignore_help_classes, int *nfound){  struct cmd_list_element *found, *c;  found = (struct cmd_list_element *) NULL;  *nfound = 0;  for (c = clist; c; c = c->next)    if (!strncmp (command, c->name, len)	&& (!ignore_help_classes || c->func))      {	found = c;	(*nfound)++;	if (c->name[len] == '\0')	  {	    *nfound = 1;	    break;	  }      }  return found;}/* This routine takes a line of TEXT and a CLIST in which to start the   lookup.  When it returns it will have incremented the text pointer past   the section of text it matched, set *RESULT_LIST to point to the list in   which the last word was matched, and will return a pointer to the cmd   list element which the text matches.  It will return NULL if no match at   all was possible.  It will return -1 (cast appropriately, ick) if ambigous   matches are possible; in this case *RESULT_LIST will be set to point to   the list in which there are ambiguous choices (and *TEXT will be set to   the ambiguous text string).   If the located command was an abbreviation, this routine returns the base   command of the abbreviation.   It does no error reporting whatsoever; control will always return   to the superior routine.   In the case of an ambiguous return (-1), *RESULT_LIST will be set to point   at the prefix_command (ie. the best match) *or* (special case) will be NULL   if no prefix command was ever found.  For example, in the case of "info a",   "info" matches without ambiguity, but "a" could be "args" or "address", so   *RESULT_LIST is set to the cmd_list_element for "info".  So in this case   RESULT_LIST should not be interpeted as a pointer to the beginning of a   list; it simply points to a specific command.  In the case of an ambiguous   return *TEXT is advanced past the last non-ambiguous prefix (e.g.   "info t" can be "info types" or "info target"; upon return *TEXT has been   advanced past "info ").   If RESULT_LIST is NULL, don't set *RESULT_LIST (but don't otherwise   affect the operation).   This routine does *not* modify the text pointed to by TEXT.   If IGNORE_HELP_CLASSES is nonzero, ignore any command list elements which   are actually help classes rather than commands (i.e. the function field of   the struct cmd_list_element is NULL).  */struct cmd_list_element *lookup_cmd_1 (char **text, struct cmd_list_element *clist,	      struct cmd_list_element **result_list, int ignore_help_classes){  char *p, *command;  int len, tmp, nfound;  struct cmd_list_element *found, *c;  char *line = *text;  while (**text == ' ' || **text == '\t')    (*text)++;  /* Treating underscores as part of command words is important     so that "set args_foo()" doesn't get interpreted as     "set args _foo()".  */  /* NOTE: cagney/2003-02-13 The `tui_active' was previously     `tui_version'.  */  for (p = *text;       *p && (isalnum (*p) || *p == '-' || *p == '_' ||#if defined(TUI)	      (tui_active &&	       (*p == '+' || *p == '<' || *p == '>' || *p == '$')) ||#endif	      (xdb_commands && (*p == '!' || *p == '/' || *p == '?')));       p++)    ;  /* If nothing but whitespace, return 0.  */  if (p == *text)    return 0;  len = p - *text;  /* *text and p now bracket the first command word to lookup (and     it's length is len).  We copy this into a local temporary */  command = (char *) alloca (len + 1);  for (tmp = 0; tmp < len; tmp++)    {      char x = (*text)[tmp];      command[tmp] = x;    }  command[len] = '\0';  /* Look it up.  */  found = 0;  nfound = 0;  found = find_cmd (command, len, clist, ignore_help_classes, &nfound);  /*      ** We didn't find the command in the entered case, so lower case it     ** and search again.   */  if (!found || nfound == 0)    {      for (tmp = 0; tmp < len; tmp++)	{	  char x = command[tmp];	  command[tmp] = isupper (x) ? tolower (x) : x;	}      found = find_cmd (command, len, clist, ignore_help_classes, &nfound);    }  /* If nothing matches, we have a simple failure.  */  if (nfound == 0)    return 0;  if (nfound > 1)    {      if (result_list != NULL)	/* Will be modified in calling routine	   if we know what the prefix command is.  */	*result_list = 0;      return (struct cmd_list_element *) -1;	/* Ambiguous.  */    }  /* We've matched something on this list.  Move text pointer forward. */  *text = p;  if (found->cmd_pointer)    {      /* We drop the alias (abbreviation) in favor of the command it is       pointing to.  If the alias is deprecated, though, we need to       warn the user about it before we drop it.  Note that while we       are warning about the alias, we may also warn about the command       itself and we will adjust the appropriate DEPRECATED_WARN_USER       flags */            if (found->flags & DEPRECATED_WARN_USER)      deprecated_cmd_warning (&line);      found = found->cmd_pointer;    }  /* If we found a prefix command, keep looking.  */  if (found->prefixlist)    {      c = lookup_cmd_1 (text, *found->prefixlist, result_list,			ignore_help_classes);      if (!c)	{	  /* Didn't find anything; this is as far as we got.  */	  if (result_list != NULL)	    *result_list = clist;	  return found;	}      else if (c == (struct cmd_list_element *) -1)	{	  /* We've gotten this far properly, but the next step	     is ambiguous.  We need to set the result list to the best	     we've found (if an inferior hasn't already set it).  */	  if (result_list != NULL)	    if (!*result_list)	      /* This used to say *result_list = *found->prefixlist	         If that was correct, need to modify the documentation	         at the top of this function to clarify what is supposed	         to be going on.  */	      *result_list = found;	  return c;	}      else	{	  /* We matched!  */	  return c;	}    }  else    {      if (result_list != NULL)	*result_list = clist;      return found;    }}/* All this hair to move the space to the front of cmdtype */static voidundef_cmd_error (char *cmdtype, char *q){  error ("Undefined %scommand: \"%s\".  Try \"help%s%.*s\".",	 cmdtype,	 q,	 *cmdtype ? " " : "",	 (int) strlen (cmdtype) - 1,	 cmdtype);}/* Look up the contents of *LINE as a command in the command list LIST.   LIST is a chain of struct cmd_list_element's.   If it is found, return the struct cmd_list_element for that command   and update *LINE to point after the command name, at the first argument.   If not found, call error if ALLOW_UNKNOWN is zero   otherwise (or if error returns) return zero.   Call error if specified command is ambiguous,   unless ALLOW_UNKNOWN is negative.   CMDTYPE precedes the word "command" in the error message.   If INGNORE_HELP_CLASSES is nonzero, ignore any command list   elements which are actually help classes rather than commands (i.e.   the function field of the struct cmd_list_element is 0).  */struct cmd_list_element *lookup_cmd (char **line, struct cmd_list_element *list, char *cmdtype,	    int allow_unknown, int ignore_help_classes){  struct cmd_list_element *last_list = 0;  struct cmd_list_element *c =  lookup_cmd_1 (line, list, &last_list, ignore_help_classes);  /* Note: Do not remove trailing whitespace here because this     would be wrong for complete_command.  Jim Kingdon  */  if (!c)    {      if (!allow_unknown)	{	  if (!*line)	    error ("Lack of needed %scommand", cmdtype);	  else	    {	      char *p = *line, *q;	      while (isalnum (*p) || *p == '-')		p++;	      q = (char *) alloca (p - *line + 1);	      strncpy (q, *line, p - *line);	      q[p - *line] = '\0';	      undef_cmd_error (cmdtype, q);	    }	}      else	return 0;    }  else if (c == (struct cmd_list_element *) -1)    {      /* Ambigous.  Local values should be off prefixlist or called         values.  */      int local_allow_unknown = (last_list ? last_list->allow_unknown :				 allow_unknown);      char *local_cmdtype = last_list ? last_list->prefixname : cmdtype;      struct cmd_list_element *local_list =      (last_list ? *(last_list->prefixlist) : list);      if (local_allow_unknown < 0)	{	  if (last_list)	    return last_list;	/* Found something.  */	  else	    return 0;		/* Found nothing.  */	}      else	{	  /* Report as error.  */	  int amb_len;	  char ambbuf[100];	  for (amb_len = 0;	       ((*line)[amb_len] && (*line)[amb_len] != ' '		&& (*line)[amb_len] != '\t');	       amb_len++)	    ;	  ambbuf[0] = 0;	  for (c = local_list; c; c = c->next)	    if (!strncmp (*line, c->name, amb_len))	      {

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?