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 + -
显示快捷键?