⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 command.c

📁 早期freebsd实现
💻 C
📖 第 1 页 / 共 3 页
字号:
    }  p = str;  while (*p && *p != '\n' && *p != '.' && *p != ',')    p++;  if (p - str > line_size - 1)    {      line_size = p - str + 1;      free ((PTR)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]);  fputs_filtered (line_buffer, stream);}/* * 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 (list, class, prefix, recurse, stream)     struct cmd_list_element *list;     enum command_class class;     char *prefix;     int recurse;     FILE *stream;{  register struct cmd_list_element *c;  for (c = list; c; c = c->next)    {      if (c->abbrev_flag == 0 &&	  (class == all_commands	  || (class == all_classes && c->function.cfunc == NULL)	  || (class == c->class && c->function.cfunc != 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);    }}/* 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.   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 (text, clist, result_list, ignore_help_classes)     char **text;     struct cmd_list_element *clist, **result_list;     int ignore_help_classes;{  char *p, *command;  int len, tmp, nfound;  struct cmd_list_element *found, *c;  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()".  */  for (p = *text;       *p && (isalnum(*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,     converting to lower case as we go.  */  command = (char *) alloca (len + 1);  for (tmp = 0; tmp < len; tmp++)    {      char x = (*text)[tmp];      command[tmp] = isupper(x) ? tolower(x) : x;    }  command[len] = '\0';  /* Look it up.  */  found = 0;  nfound = 0;  for (c = clist; c; c = c->next)    if (!strncmp (command, c->name, len)	&& (!ignore_help_classes || c->function.cfunc))      {	found = c;	nfound++;	if (c->name[len] == '\0')	  {	    nfound = 1;	    break;	  }      }  /* 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 this was an abbreviation, use the base command instead.  */  if (found->cmd_pointer)    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 properley, 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 (cmdtype, q)     char *cmdtype, *q;{  error ("Undefined %scommand: \"%s\".  Try \"help%s%.*s\".",    cmdtype,    q,    *cmdtype? " ": "",    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 (line, list, cmdtype, allow_unknown, ignore_help_classes)     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);  char *ptr = (*line) + strlen (*line) - 1;  /* Clear off trailing whitespace.  */  while (ptr >= *line && (*ptr == ' ' || *ptr == '\t'))    ptr--;  *(ptr + 1) = '\0';    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))	      {		if (strlen (ambbuf) + strlen (c->name) + 6 < (int)sizeof ambbuf)		  {		    if (strlen (ambbuf))		      strcat (ambbuf, ", ");		    strcat (ambbuf, c->name);		  }		else		  {		    strcat (ambbuf, "..");		    break;		  }	      }	  error ("Ambiguous %scommand \"%s\": %s.", local_cmdtype,		 *line, ambbuf);	  return 0;		/* lint */	}    }  else    {      /* We've got something.  It may still not be what the caller         wants (if this command *needs* a subcommand).  */      while (**line == ' ' || **line == '\t')	(*line)++;      if (c->prefixlist && **line && !c->allow_unknown)	undef_cmd_error (c->prefixname, *line);      /* Seems to be what he wants.  Return it.  */      return c;    }  return 0;}	#if 0/* 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.  */struct cmd_list_element *lookup_cmd (line, list, cmdtype, allow_unknown)     char **line;     struct cmd_list_element *list;     char *cmdtype;     int allow_unknown;{  register char *p;  register struct cmd_list_element *c, *found;  int nfound;  char ambbuf[100];  char *processed_cmd;  int i, cmd_len;  /* Skip leading whitespace.  */  while (**line == ' ' || **line == '\t')    (*line)++;  /* Clear out trailing whitespace.  */  p = *line + strlen (*line);  while (p != *line && (p[-1] == ' ' || p[-1] == '\t'))    p--;  *p = 0;  /* Find end of command name.  */  p = *line;  while (*p == '-' || isalnum(*p))    p++;  /* Look up the command name.     If exact match, keep that.     Otherwise, take command abbreviated, if unique.  Note that (in my     opinion) a null string does *not* indicate ambiguity; simply the     end of the argument.  */  if (p == *line)    {      if (!allow_unknown)	error ("Lack of needed %scommand", cmdtype);      return 0;    }    /* Copy over to a local buffer, converting to lowercase on the way.     This is in case the command being parsed is a subcommand which     doesn't match anything, and that's ok.  We want the original     untouched for the routine of the original command.  */    processed_cmd = (char *) alloca (p - *line + 1);  for (cmd_len = 0; cmd_len < p - *line; cmd_len++)    {      char x = (*line)[cmd_len];      if (isupper(x))	processed_cmd[cmd_len] = tolower(x);      else	processed_cmd[cmd_len] = x;    }  processed_cmd[cmd_len] = '\0';

⌨️ 快捷键说明

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