diff options
| author | 2000-09-11 14:40:26 +0000 | |
|---|---|---|
| committer | 2000-09-11 14:40:26 +0000 | |
| commit | 2caf32899aba1af6b57e8ce1e682a74cda4f7160 (patch) | |
| tree | e4f7aefca7feb82ab6a6b4488de1458b9b0f59f9 /usr.sbin/afs/src/lib/cmd/cmd.c | |
| parent | New xfs from Arla between 0.34.2 and current in arla cvs. (diff) | |
| download | wireguard-openbsd-2caf32899aba1af6b57e8ce1e682a74cda4f7160.tar.xz wireguard-openbsd-2caf32899aba1af6b57e8ce1e682a74cda4f7160.zip | |
New Arla userland from Arla between 0.34.2 and current in arla cvs.
Too many new features and fixes to mention here.
Diffstat (limited to 'usr.sbin/afs/src/lib/cmd/cmd.c')
| -rw-r--r-- | usr.sbin/afs/src/lib/cmd/cmd.c | 1016 |
1 files changed, 1016 insertions, 0 deletions
diff --git a/usr.sbin/afs/src/lib/cmd/cmd.c b/usr.sbin/afs/src/lib/cmd/cmd.c new file mode 100644 index 00000000000..41da62309d9 --- /dev/null +++ b/usr.sbin/afs/src/lib/cmd/cmd.c @@ -0,0 +1,1016 @@ +/* + * Copyright (c) 2000 Kungliga Tekniska Högskolan + * (Royal Institute of Technology, Stockholm, Sweden). + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * 3. Neither the name of the Institute nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#ifdef HAVE_CONFIG_H +#include <config.h> +#endif + +#include <sys/types.h> +#include <stdio.h> +#include <stdlib.h> +#include <time.h> +#include <strings.h> +#include <assert.h> +#include <ctype.h> +#include <err.h> + +#include <cmd.h> + +#ifdef RCSID +RCSID("$Id: cmd.c,v 1.1 2000/09/11 14:40:55 art Exp $"); +#endif + +static struct cmd_syndesc *cmd_cmds = NULL; +static struct cmd_syndesc **cmd_lastcmd = &cmd_cmds; +static int _cmd_init = 0; + +static int (*before_proc) (void *rock) = NULL; +static void *before_rock = NULL; +static int (*after_proc) (void *rock) = NULL; +static void *after_rock = NULL; + +static void +cmd_PrintSyntaxManDoc (const char *commandname); + + +static struct cmd_syndesc * +new_cmd (const char *name, const char *help_str, struct cmd_syndesc *alias) +{ + struct cmd_syndesc *ts; + + ts = malloc (sizeof(*ts)); + if (ts == NULL) + return NULL; + memset (ts, 0, sizeof (*ts)); + + if (name) { + ts->name = strdup (name); + if (ts->name == NULL) { + free (ts); + return NULL; + } + } + if (help_str) { + ts->help = strdup (help_str); + if (ts->help == NULL) { + free (ts->name); + free (ts); + return NULL; + } + } + if (alias) { + ts->aliasOf = alias; + ts->nextAlias = alias->nextAlias; + alias->nextAlias = ts; + ts->flags |= CMD_ALIAS; + } + if (ts->name == NULL) { + assert (cmd_cmds == NULL || cmd_cmds->name != NULL); + ts->next = cmd_cmds; + if (&cmd_cmds == cmd_lastcmd) + cmd_lastcmd = &ts->next; + cmd_cmds = ts; + } else { + *cmd_lastcmd = ts; + cmd_lastcmd = &ts->next; + } + return ts; +} + +/* + * + */ + +static int +find_command (struct cmd_syndesc *cmd_cmds, const char *func, + struct cmd_syndesc **ret) +{ + struct cmd_syndesc *partial_match = NULL; + struct cmd_syndesc *ts; + int partial_len = strlen (func); + + for (ts = cmd_cmds; ts; ts = ts->next) { + if (ts->name == NULL) + continue; + if (strcasecmp (ts->name, func) == 0) { + if (ts->aliasOf) + ts = ts->aliasOf; + *ret = ts; + return 0; + } + if (strncasecmp (ts->name, func, partial_len) == 0) { + if (partial_match) + return CMD_AMBIG; + partial_match = ts; + } + } + if (partial_match) { + if (partial_match->aliasOf) + partial_match = partial_match->aliasOf; + *ret = partial_match; + return 0; + } + return CMD_UNKNOWNCMD; +} + +/* + * + */ + +static void +print_usage (const char *name, struct cmd_syndesc *ts) +{ + int i; + + if (getenv ("CMD_MANDOC") != NULL) { + cmd_PrintSyntaxManDoc(__progname); /* XXX */ + return; + } + + printf ("%s", name); + if (ts->name) + printf (" %s", ts->name); + + for (i = 0; i < CMD_MAXPARMS ; i++) { + char *help = ts->parms[i].help; + char *name = ts->parms[i].name; + if (help == NULL) + help = "arg"; + if ((ts->parms[i].flags & CMD_HIDE) == CMD_HIDE || name == NULL) + continue; + printf (" "); + if ((ts->parms[i].flags & CMD_OPTIONAL) == CMD_OPTIONAL) + printf ("["); + switch (ts->parms[i].type) { + case CMD_FLAG: + printf ("%s", name); + break; + case CMD_SINGLE: + printf ("%s <%s>", name, help); + break; + case CMD_LIST: + printf ("%s <%s>+", name, help); + break; + default: + abort(); + } + if ((ts->parms[i].flags & CMD_OPTIONAL) == CMD_OPTIONAL) + printf ("]"); + } + if (ts->name == NULL) + printf (" command"); + printf ("\n"); +} + +/* + * + */ + +static int +cmd_internal_help (struct cmd_syndesc *t, void *ptr) +{ + struct cmd_syndesc *ts; + char *help; + + if (getenv ("CMD_MANDOC") != NULL) { + cmd_PrintSyntaxManDoc(__progname); /* XXX */ + return 0; + } + + if (t->parms[0].items == NULL) { + + for (ts = cmd_cmds; ts; ts = ts->next) { + if (ts->name == NULL && cmd_cmds == ts) + continue; + if ((ts->flags & CMD_HIDDEN) == CMD_HIDDEN) + continue; + if (ts->aliasOf) + continue; + if (ts->help) + help = ts->help; + else + help = ""; + + printf ("%-10s %s\n", ts->name, help); + } + } else { + char *cmd = t->parms[0].items->data; + struct cmd_syndesc *ts; + int ret; + + ret = find_command (cmd_cmds, cmd, &ts); + if (ret) + return ret; + print_usage (__progname, ts); /* XXX */ + } + return 0; +} + +/* + * + */ + +static int +cmd_internal_apropos (struct cmd_syndesc *t, void *ptr) +{ + struct cmd_syndesc *ts; + char *cmd, *help; + + cmd = t->parms[0].items->data; + + for (ts = cmd_cmds; ts; ts = ts->next) { + if (ts->name == NULL && cmd_cmds == ts) + continue; + if (ts->help) + help = ts->help; + else + help = ""; + if (strstr(ts->name, cmd)) + printf ("%-10s %s\n", ts->name, help); + } + return 0; +} + +/* + * Create a new command with `name' that will run the function `main' + * with the `rock'. When help is choose `help_str' will be displayed. + */ + +struct cmd_syndesc * +cmd_CreateSyntax (const char *name, cmd_proc main, void *rock, + const char *help_str) +{ + struct cmd_syndesc *ts; + + ts = new_cmd (name, help_str, NULL); + + ts->proc = main; + ts->rock = rock; + + cmd_Seek (ts, CMD_HELPPARM); + cmd_AddParm (ts, "-help", CMD_FLAG, CMD_OPTIONAL, "get detailed help"); + cmd_Seek (ts, 0); + + return ts; +} + +/* + * + */ + +int +cmd_SetBeforeProc (int (*proc) (void *), void *rock) +{ + before_proc = proc; + before_rock = rock; + return 0; +} + +/* + * + */ + +int +cmd_SetAfterProc (int (*proc) (void *rock), void *rock) +{ + after_proc = proc; + after_rock = rock; + return 0; +} + +/* + * Allocate a new parameter to `ts' with name `cmd' of `type' and with + * `flags'. When help is needed show `help_str'. + */ + +void +cmd_AddParm (struct cmd_syndesc *ts, const char *name, + cmd_parmdesc_type type, cmd_parmdesc_flags flags, + const char *help_str) +{ + struct cmd_parmdesc *p = &ts->parms[ts->nParams];; + + memset (p, 0, sizeof(*p)); + + if (ts->nParams > CMD_HELPPARM) + abort(); + + p->name = strdup (name); + if (p->name == NULL) + return; + p->help = strdup(help_str); + if (p->help == NULL) { + free (p->name); + return; + } + ts->nParams++; + + p->type = type; + p->flags = flags; +} + +/* + * + */ + +int +cmd_CreateAlias (struct cmd_syndesc *orignal, const char *name) +{ + struct cmd_syndesc *ts; + ts = new_cmd (name, NULL, orignal); + if (ts == NULL) + return CMD_INTERALERROR; + return 0; +} + +/* + * + */ + +int +cmd_Seek (struct cmd_syndesc *ts, int pos) +{ + if (pos > CMD_HELPPARM || pos < 0) + return CMD_EXCESSPARMS; + ts->nParams = pos; + return 0; +} + +/* + * + */ + +void +cmd_FreeArgv (char **argv) +{ + return; +} + +/* + * + */ + +#define CMD_IS_CMD(str) (str[0] == '-' && !isdigit(str[1])) + +/* + * + */ + +static struct cmd_parmdesc * +find_next_param (struct cmd_syndesc *ts, int *curval) +{ + int i; + for (i = *curval; i < CMD_MAXPARMS ; i++) { + if ((ts->parms[i].flags & CMD_EXPANDS) == CMD_EXPANDS) + break; + if (ts->parms[i].name == NULL) + continue; + if (ts->parms[i].items != NULL) + continue; + break; + } + if (i >= CMD_MAXPARMS) + return NULL; + *curval = i; + return &ts->parms[i]; +} + +/* + * + */ + +static int +find_next_name (struct cmd_syndesc *ts, const char *name, + struct cmd_parmdesc **ret) +{ + struct cmd_parmdesc *partial_match = NULL; + int i, partial_len = strlen(name); + + for (i = 0; i < CMD_MAXPARMS; i++) { + if (ts->parms[i].name == NULL) + continue; + if (strcasecmp (name, ts->parms[i].name) == 0) { + *ret = &ts->parms[i]; + return 0; + } + if (strncasecmp (name, ts->parms[i].name, partial_len) == 0) { + if (partial_match) + return CMD_AMBIG; + partial_match = &ts->parms[i]; + } + } + if (partial_match) { + *ret = partial_match; + return 0; + } + return CMD_UNKNOWNSWITCH; +} + +/* + * + */ + +static struct cmd_item * +new_items (struct cmd_parmdesc *p) +{ + struct cmd_item *i; + i = malloc (sizeof (*i)); + if (i == NULL) + err (1, "new_items"); + i->next = p->items; + p->items = i; + return i; +} + +/* + * + */ + +static int +parse_options (int argc, char **argv, int *optind, struct cmd_syndesc *ts, + int failp) +{ + struct cmd_parmdesc *p; + int i, ret; + + for (i = 0; i < CMD_MAXPARMS; i++) { + if (ts->parms[i].name) + break; + } + if (i == CMD_MAXPARMS) + return 0; + + + for (i = 0; i < argc; i++) { + ret = find_next_name (ts, argv[i], &p); + if (ret) { + if (failp) + return ret; + break; + } + switch (p->type) { + case CMD_FLAG: + assert (p->items == NULL); + p->items = new_items (p); + p->items->data = p; + break; + case CMD_SINGLE: + assert (p->items == NULL); + if (i == argc - 1) + return CMD_TOOFEW; + i++; + p->items = new_items (p); + p->items->data = argv[i]; + break; + case CMD_LIST: + if (i == argc - 1) + return CMD_TOOFEW; + i++; + while (i < argc) { + p->items = new_items (p); + p->items->data = argv[i]; + if (i >= argc - 1 || CMD_IS_CMD(argv[i+1])) + break; + i++; + } + break; + default: + abort(); + } + } + if (argc < i) + i = argc; + *optind = i; + return 0; +} + +/* + * + */ + +static int +parse_magic_options (int argc, char **argv, int *optind, + struct cmd_syndesc *ts) +{ + struct cmd_parmdesc *p; + int i, curval = 0; + + for (i = 0; i < argc; i++) { + if (CMD_IS_CMD(argv[i])) + break; + p = find_next_param (ts, &curval); + if (p == NULL) + break; + if (p->type == CMD_FLAG) { +#if 0 + assert (p->items == NULL); + p->items = new_items (p); + p->items->data = p; +#else + break; +#endif + } else if (p->type == CMD_SINGLE) { + assert (p->items == NULL); + p->items = new_items (p); + p->items->data = argv[i]; + } else if (p->type == CMD_LIST) { + while (i < argc) { + p->items = new_items (p); + p->items->data = argv[i]; + if ((i >= argc - 1 || CMD_IS_CMD(argv[i+1])) + || (p->flags & CMD_EXPANDS) == 0) + break; + i++; + } + } else { +#if 0 + abort(); +#else + break; +#endif + } + } + if (argc < i) + i = argc; + *optind = i; + return 0; +} + +/* + * + */ + +static struct cmd_parmdesc * +req_argumentp (struct cmd_syndesc *ts) +{ + int i; + + for (i = 0; i < CMD_MAXPARMS; i++) { + if (ts->parms[i].name == NULL) + continue; + if ((ts->parms[i].flags & CMD_OPTIONAL) == 0 + && ts->parms[i].items == NULL) + return &ts->parms[i]; + } + return NULL; +} + +/* + * + */ + +int +cmd_ParseLine (const char *line, char **argv, int *n, int maxn) +{ + return 0; +} + +/* + * + */ + +static int +call_proc (const char *programname, struct cmd_syndesc *ts) +{ + struct cmd_parmdesc *p; + int ret; + + if (ts->parms[CMD_HELPPARM].items) { + print_usage (programname, ts); + return 0; + } + + p = req_argumentp (ts); + if (p) { + print_usage (programname, ts); + fprintf (stderr, "missing argument: %s\n", &p->name[1]); + return CMD_USAGE; + } + + if (before_proc) + (*before_proc) (before_rock); + + ret = (*ts->proc) (ts, ts->rock); + + if (after_proc) + (*after_proc) (before_rock); + return ret; +} + +/* + * + */ + +int +cmd_Dispatch (int argc, char **argv) +{ + struct cmd_syndesc *ts; + int optind = 0; + int ret; + char *programname = argv[0]; + + argc -= 1; + argv += 1; + + if (!_cmd_init) { + if (cmd_cmds->next != NULL || cmd_cmds->proc == NULL) { + ts = cmd_CreateSyntax ("help", cmd_internal_help, NULL, "help"); + cmd_AddParm (ts, "-cmd", CMD_SINGLE, CMD_OPTIONAL, "command"); + ts = cmd_CreateSyntax ("apropos", cmd_internal_apropos, + NULL, "apropos"); + cmd_AddParm (ts, "-cmd", CMD_SINGLE, CMD_REQUIRED, "command"); + } + if (cmd_cmds->name) + ts = cmd_CreateSyntax ("main", NULL, NULL, NULL); + _cmd_init = 1; + } + + if (cmd_cmds->next == NULL && cmd_cmds->proc) { + ret = parse_magic_options (argc, argv, &optind, ts); + if (ret) + return ret; + + argv += optind; + argc -= optind; + optind = 0; + } + ret = parse_options (argc, argv, &optind, cmd_cmds, 0); + if (ret) + errx (1, "main parse failed"); + if (cmd_cmds->next == NULL && cmd_cmds->proc) { + return call_proc (programname, cmd_cmds); + } else { + struct cmd_parmdesc *p; + + if (cmd_cmds->parms[CMD_HELPPARM].items) { + print_usage (programname, cmd_cmds); + return 0; + } + + p = req_argumentp (cmd_cmds); + if (p) { + fprintf (stderr, "missing argument: %s\n", &p->name[1]); + return CMD_USAGE; + } + } + + argv += optind; + argc -= optind; + + if (argc <= 0) { + print_usage (programname, ts); + return CMD_USAGE; + } + + ret = find_command (cmd_cmds, argv[0], &ts); + if (ret) + return ret; + + argv += 1; + argc -= 1; + optind = 0; + + ret = parse_magic_options (argc, argv, &optind, ts); + if (ret) + return ret; + + argv += optind; + argc -= optind; + optind = 0; + + ret = parse_options (argc, argv, &optind, ts, 1); + if (ret) + return ret; + + argv += optind; + argc -= optind; + + if (argc != 0) { + print_usage (programname, ts); + return CMD_USAGE; + } + + return call_proc (programname, ts); +} + + +static void +cmd_PrintParams (struct cmd_syndesc *ts) +{ + int i; + + for (i = 0; i < CMD_MAXPARMS ; i++) { + char *help = ts->parms[i].help; + if (ts->parms[i].name == NULL) + continue; + if (help == NULL) + help = "arg"; + if ((ts->parms[i].flags & CMD_HIDE) == CMD_HIDE) + continue; + if ((ts->parms[i].flags & CMD_OPTIONAL) == CMD_OPTIONAL) + printf (".Op "); + else + printf ("."); + switch (ts->parms[i].type) { + case CMD_FLAG: + printf ("Cm %s\n", ts->parms[i].name); + break; + case CMD_SINGLE: + printf ("Cm %s Ar %s\n", ts->parms[i].name, help); + break; + case CMD_LIST: + printf ("Cm %s Ar %s ...\n", ts->parms[i].name, help); + break; + default: abort(); break; + } + } +#if 0 + for (i = 0; i < CMD_MAXPARMS ; i++) { + if (ts->parms[i].name == NULL) + continue; + printf ("\tflag: %s\n", ts->parms[i].name); + printf ("\t\thelp: %s\n", ts->parms[i].help); + printf ("\t\tflags: "); + if ((ts->parms[i].flags & CMD_REQUIRED) == CMD_REQUIRED) + printf ("required"); + if ((ts->parms[i].flags & CMD_EXPANDS) == CMD_EXPANDS) + printf ("expands"); + if ((ts->parms[i].flags & CMD_PROCESSED) == CMD_PROCESSED) + printf ("processed"); + printf ("\n"); + } +#endif +} + +/* + * + */ + +static int +cmd_ExtraText (const char *cmd, const char *sectionname, + const char *class, const char *name, int withcr) +{ + char *fn, *section; + char buf[1024]; + FILE *f; + int len, searching = 1; + + asprintf (&fn, "%s.ctx", cmd); + f = fopen (fn, "r"); + if (f == NULL) { + free (fn); + if (getenv ("srcdir")) { + asprintf (&fn, "%s/%s.ctx", getenv("srcdir"), cmd); + f = fopen (fn, "r"); + } + if (f == NULL) + return 0; + } + len = asprintf (§ion, "%%%s %s", class, name); + + while (fgets (buf, sizeof(buf), f) != NULL) { + buf[strlen(buf)-1] = '\0'; + + if (buf[0] == '#') + continue; + + if (searching) { + if (strncasecmp (buf, section, len) == 0) { + searching = 0; + if (sectionname) + printf ("%s", sectionname); + } + } else { + char *p = buf; + if (buf[0] == '%') { + break; + } + while (isspace (*p)) p++; + if (*p == '\0') + continue; + printf ("%s%s", p, withcr ? "\n" : ""); + } + } + fclose (f); + return searching; +} + +static void +cmd_PrintSyntaxManDoc (const char *commandname) +{ + char timestr[64], cmd[64]; + time_t t; + struct cmd_syndesc *ts; + + printf(".\\\" Things to fix:\n"); + printf(".\\\" * use better macros for arguments (like .Pa for files)\n"); + printf(".\\\"\n"); + + t = time(NULL); + strftime(timestr, sizeof(timestr), "%B %e, %Y", localtime(&t)); + strlcpy(cmd, commandname, sizeof(cmd)); + cmd[sizeof(cmd)-1] = '\0'; +/* XXX-libroken strupr(cmd);*/ + + printf(".Dd %s\n", timestr); + printf(".Dt %s ", cmd); + if (cmd_ExtraText (commandname, NULL, "name", "section", 0)) + printf("SECTION"); + printf ("\n"); + if (cmd_ExtraText (commandname, ".Os ", "name", "OS", 0)) + printf(".Os OPERATING_SYSTEM"); + printf ("\n"); + printf(".Sh NAME\n"); + printf(".Nm %s\n", commandname); + if (cmd_ExtraText (commandname, ".Nd ", "name", "description", 1)) + printf(".Nd in search of a description\n"); + printf(".Sh SYNOPSIS\n"); + printf(".Nm\n"); + if (cmd_cmds->name == NULL) + cmd_PrintParams (cmd_cmds); + if (cmd_cmds->next) + printf (".Cm command\n.Op ..."); + printf ("\n"); + printf(".Sh DESCRIPTION\n"); + + cmd_ExtraText (commandname, NULL, "section", "description", 1); + + if (cmd_cmds->name == NULL && cmd_cmds->next == NULL) { + printf (".Pp\n"); + if (cmd_ExtraText (commandname, NULL, "command", "_main", 1)) + printf ("Tell someone to add some helptext " + "here to the .ctx file\n"); + } else { + printf (".Bl -tag -width Ds\n"); + + for (ts = cmd_cmds; ts; ts = ts->next) { + struct cmd_syndesc *t = ts->nextAlias; + + if (ts->name == NULL && cmd_cmds == ts) + continue; + if ((ts->flags & CMD_HIDDEN) == CMD_HIDDEN) + continue; + if (ts->aliasOf) + continue; + + printf (".It %s", ts->name); + + if (t) { + while (t) { + printf (", %s", t->name); + t = t->nextAlias; + } + } + printf ("\n.Pp\n"); + printf (".Nm \"%s %s\"\n", commandname, ts->name); + cmd_PrintParams (ts); + printf (".Pp\n"); + if (strcmp (ts->name, "help") == 0) { + printf ("List all commands, or if\n" + ".Ar command\n" + "is given as an argument, help for that command.\n"); + } else if (strcmp (ts->name, "apropos") == 0) { + printf ("List all command that have the argument\n.Ar command\n" + "as a subtring in themself."); + } else { + if (cmd_ExtraText (commandname, NULL, "command", ts->name, 1)) + printf ("Tell someone to add some helptext " + "here to the .ctx file\n"); + } + } + printf(".El\n"); + } + + cmd_ExtraText (commandname, ".Sh ERRORS\n", "section", "errors", 1); + cmd_ExtraText (commandname, ".Sh SEE ALSO\n", "section", "see also", 1); + cmd_ExtraText (commandname, ".Sh HISTORY\n", "section", "history", 1); + cmd_ExtraText (commandname, ".Sh AUTHORS\n", "section", "authors", 1); + cmd_ExtraText (commandname, ".Sh BUGS\n", "section", "bugs", 1); +} + +/* + * + */ + +void +cmd_PrintSyntax (const char *commandname) +{ + const char *name; + struct cmd_syndesc *ts; + int i; + + name = strrchr (commandname, '/'); + if (name == NULL) + name = commandname; + else + name++; + + if (getenv ("CMD_MANDOC") != NULL) { + cmd_PrintSyntaxManDoc(name); + return; + } + + for (ts = cmd_cmds; ts; ts = ts->next) { + struct cmd_syndesc *t = ts->nextAlias; + + if (ts->name == NULL && cmd_cmds == ts) + printf ("exec-file: %s\n", name); + else + printf ("command: %s - %s\n", ts->name, ts->help); + printf ("\tflags: "); + if ((ts->flags & CMD_ALIAS) == CMD_ALIAS) + printf (" alias"); + if ((ts->flags & CMD_HIDDEN) == CMD_HIDDEN) + printf (" hidden"); + printf ("\n"); + if (ts->aliasOf) + continue; + if (t) { + printf ("\taliases:"); + while (t) { + printf (" %s", t->name); + t = t->nextAlias; + } + printf ("\n"); + } + for (i = 0; i < CMD_MAXPARMS ; i++) { + if (ts->parms[i].name == NULL) + continue; + printf ("\tflag: %s\n", ts->parms[i].name); + switch (ts->parms[i].type) { + case CMD_FLAG: printf ("\t\ttype: flag\n"); break; + case CMD_SINGLE: printf ("\t\ttype: single\n"); break; + case CMD_LIST: printf ("\t\ttype: list\n"); break; + default: abort(); break; + } + printf ("\t\thelp: %s\n", ts->parms[i].help); + printf ("\t\tflags: "); + if ((ts->parms[i].flags & CMD_REQUIRED) == CMD_REQUIRED) + printf ("required"); + if ((ts->parms[i].flags & CMD_OPTIONAL) == CMD_OPTIONAL) + printf ("optional"); + if ((ts->parms[i].flags & CMD_EXPANDS) == CMD_EXPANDS) + printf ("expands"); + if ((ts->parms[i].flags & CMD_HIDE) == CMD_HIDE) + printf ("hide"); + if ((ts->parms[i].flags & CMD_PROCESSED) == CMD_PROCESSED) + printf ("processed"); + printf ("\n"); + } + } +} + +/* + * + */ + +static const char *cmd_errors[] = { + "cmd - Excess parameters", + "cmd - Internal error", + "cmd - Notlist", + "cmd - Too many", + "cmd - Usage", + "cmd - Unknown command", + "cmd - Unknown switch", + "cmd - Ambigous", + "cmd - Too few arguments", + "cmd - Too many arguments" +}; + +const char * +cmd_number2str(int error) +{ + if (error < CMD_EXCESSPARMS || error > CMD_TOOBIG) + return NULL; + return cmd_errors[error - CMD_EXCESSPARMS]; +} |
