home *** CD-ROM | disk | FTP | other *** search
- #include <stdio.h>
- #include <stdlib.h>
- #include <string.h>
- #include <ctype.h>
-
- #include "cmdparse.h"
- #include "cmdparse.h"
- #include "misc.h"
- #include "var.h"
-
- varlist global_vars = NULL;
-
- static char *skipspace(char *p);
- static int report(int errnum, char *info, vterm vt);
- static int helplist(cmdtab_str *tab, vterm vt);
-
- /* Skip past space (' ', '\t', '\r', '\n')
- in a string */
- static char *skipspace(char *p)
- {
- while (isspace(*p))
- p++;
- return p;
- }
-
- static int report(int errnum, char *info, vterm vt)
- {
- switch (errnum)
- {
- case CMD_OK:
- return NULL;
- case CMD_HELP:
- vterm_printf(vt, -1, "Sorry no help available on subject \"%s\"\n", info);
- break;
- case CMD_SYNTAX:
- vterm_printf(vt, -1, "Usage: %s\n", info);
- break;
- case CMD_PARSEERR:
- vterm_printf(vt, -1, "Parse error (missing quote, bad escape sequence etc) in \"%s\"\n", info);
- break;
- case CMD_FAIL:
- vterm_printf(vt, -1, "Sorry, insufficient resources\n");
- break;
- case CMD_UNKNOWN:
- vterm_printf(vt, -1, "Unrecognised command \"%s\"\n", info);
- break;
- }
- return CMD_FAIL;
- }
-
- static int helplist(cmdtab_str *tab, vterm vt)
- {
- int c, x, n;
-
- vterm_printf(vt, -1, "Commands available:\n");
-
- n = 0;
-
- for (c=0; tab[c].command!=NULL; c++)
- {
- n += ((strlen(tab[c].command)+16)&~0x0f);
- if (n>80)
- {
- vterm_printf(vt, -1, "\r\n");
- n = 0;
- }
- vterm_printf(vt, -1, "%-16s", tab[c].command);
- }
- if (n>0)
- vterm_printf(vt, -1, "\r\n");
-
- return CMD_OK;
- }
-
- /* Examine a strings for flags. The presence of flags
- is indicated by the 1st char being a '-'.
-
- If it is a flags string, for each character in the flags
- string, set a or clear a bit in the flag word according
- the the position of the char in the flags list string.
- Prefixing any flag with '!' or '~' clear the flag.
- */
-
- unsigned int command_flags(unsigned int opts, char *cmd, char *flags)
- {
- int i;
- char *n;
-
- if (*cmd=='-')
- {
- opts = 1<<31; /* Top bit set for flags present */
- while(++cmd!='\0')
- {
- i = (*cmd == '!' || *cmd=='~');
- n = strchr(flags, *cmd);
- if (n)
- {
- if (i)
- opts &= ~( 1 << (n-flags) );
- else
- opts |= ( 1 << (n-flags) );
- }
- }
- } else
- opts = 0;
- return opts;
- }
-
-
- /* Command args extraction function
- can be used in two ways:
- 1. Entered with argv==NULL to count the args only
- for eg to determin size of array needed for
- arg pointers.
- 2. Entered with argv pointing to an array of char*
- with sufficient entries for number of args present
- cmd is the command line being processed.
-
- Returns number of args present, ignoring tail comments
- or <0 if a parse error occurs (eg missing quote)
-
- No escape sequence processing is done, other than to not count
- '\"' as a '"', as may need to be handed differently according to usage
- */
- static int command_tokenise(char *line, char *argv[])
- {
- int n = 0;
- char *p = line;
-
- strterm(line); /* Remove eol from command */
-
- while (*p!='\0')
- {
- p = skipspace(p);
-
- /* Non escaped quote? (ie start of token) */
- if (*p=='\"')
- {
- ++p;
-
- if (argv!=NULL)
- argv[n] = p;
- ++n;
-
- /* scan forward for another non escaped quote */
- while ( !(*p=='\"' && *(p-1)!='\\') && *p!='\0')
- ++p;
-
- /* Test for missing closing quote,
- and return a parse error if missing
- */
- if (*p=='\0')
- return -1;
-
- if (argv!=NULL) /* Terminate arg if extracting */
- *p = '\0';
-
- ++p;
- }
- else if (*p!='\0')
- {
- /* Added to allow comments on end of script command to be ignored
- Tail comments may be either C++ style "// ..."
- or the style commonly used in scripts "# ..." and "; ..."
- */
- if (!strncmp("#", p, 1) || !strncmp(";", p, 1) || !strncmp("//", p, 2))
- break;
-
- if (argv!=NULL)
- argv[n] = p;
- ++n;
-
- while (!isspace(*p) && *p!='\0')
- ++p;
-
- if (argv!=NULL && *p!='\0') /* Terminate arg if extracting */
- *p++ = '\0';
- }
- }
- return n; /* Number of args found */
- }
-
-
- /* Parse, Tokenise and Execute a command
- * table is a list of commands (see cmdparse.h)
- * cmd is the command to be parsed
- * handle is a user suplied value to be passed back to user functions
- * Returns completion code (see cmdparse.h)
- */
- cmderr_str *command_parse(cmdtab table, char *cmd, vterm vt)
- {
- int argc;
- char **argv;
- char *s;
- cmderr_str *e;
-
- /* Count number of argc present */
- if (argc = command_tokenise(cmd, NULL), argc<=0)
- return make_report((argc<0)?CMD_PARSEERR:CMD_OK, cmd, vt);
-
- if (argv = (char**)malloc(sizeof(char*)*argc), argv==NULL)
- return make_report(CMD_FAIL, cmd, vt);
-
- /* Make a working copy of the command line */
- if (s = strdup(cmd), s==NULL)
- return make_report(CMD_FAIL, cmd, vt);
-
- /* Extract the args this time into argv[]
- no need to error check as is done at count stage
- */
- command_tokenise(s, argv);
-
- /* Lookup and execute the comand */
- e = command_process(table, argc, argv, vt);
-
- free(s);
- free(argv);
- return e; /* Completion code - see cmdparse.h */
- }
-
-
- /* Lookup and Execute a command
- * table is a list of commands (see cmdparse.h)
- * argc is number of valid args
- * argv is a list of args
- * handle is a user suplied value to be passed back to user functions
- * Returns completion code (see cmdparse.h)
- */
- cmderr_str *command_process(cmdtab table, int argc, char* argv[], vterm vt)
- {
- int i,n,help;
-
- /* no args = no action */
- if (argc==0)
- return CMD_OK;
-
- /* is whole command a comment ? ("#" and ";" are command prefixes) */
- if (*argv[0]=='#' || *argv[0]==';')
- return CMD_OK;
-
- /* Scan through a command table
- */
- if (help = ( !strcmp(argv[0], "?") || !strincmp(argv[0],"help",strlen(argv[0])) ), help)
- {
- --argc; ++argv;
- }
-
- /* help on its own yields a commads list */
- if (help && argc==0)
- return helplist(table, vt);
-
- /* Locate command in table, abbreviations allowed */
- n = strlen(argv[0]);
- for (i=0; table[i].command!=NULL && strincmp(table[i].command, argv[0], n); i++);
-
- if (table[i].command!=NULL)
- {
- /* is it a help request? */
- if (help || (argc>1 && *argv[1]=='?'))
- return report(CMD_HELP, table[i].help, vt);
-
- /* Check that sufficient args have been given,
- return syntax error if not.
- */
- if (argc<=table[i].minargs)
- return report(CMD_SYNTAX, table[i].syntax, vt);
-
- (table[i].proc)(argc, argv, handle);
- return NULL;
- }
- return report(CMD_UNKNOWN, argv[0], vt);
- }
-
- /*
- * From old cmdparse code:
- * Variable handle code
- */
- void cmdparse_init(void)
- {
- global_vars = varlist_create(NULL);
- var_init_osvars(global_vars, vart_string, "TCPIP$String$*" );
- var_init_osvars(global_vars, vart_osvar, "TCPIP$OSVar$*" );
- }
-
- int dosetvar(int argc, char **argv)
- {
- var_create_string(global_vars, argv[1], 0, argv[2]);
- return 0;
- }
-
- int dosetosvar(int argc, char **argv)
- {
- var_create_osvar(global_vars, argv[1], 0, argv[2]);
- return 0;
- }
-
- int doshowvar(int argc, char **argv)
- {
- char buf[256];
- var vp;
-
- if (argc<2)
- {
- for (vp = global_vars->head; vp!=NULL; vp = vp->link)
- {
- var_output(vp, buf, 256);
- if (vp->type==vart_osvar)
- cwprintf(NULL, " %-16s: <%s> = \"%s\"\r\n", vp->name+1, vp->value.string, buf);
- else
- cwprintf(NULL, " %-16s: \"%s\"\r\n", vp->name+1, buf);
- }
- }
- else
- {
- if (vp = var_lookup(global_vars, argv[1], 0), vp!=NULL)
- {
- var_output(vp, buf, 256);
- if (vp->type==vart_osvar)
- cwprintf(NULL, " %-16s: <%s> = \"%s\"\r\n", vp->name+1, vp->value.string, buf);
- else
- cwprintf(NULL, " %-16s: \"%s\"\r\n", vp->name+1, buf);
- }
- else
- {
- cwprintf(NULL, "Variable not known\r\n");
- return 1;
- }
- }
- return 0;
- }
-