diff options
Diffstat (limited to 'src/token.c')
-rw-r--r-- | src/token.c | 257 |
1 files changed, 257 insertions, 0 deletions
diff --git a/src/token.c b/src/token.c new file mode 100644 index 0000000..b71a6cb --- /dev/null +++ b/src/token.c @@ -0,0 +1,257 @@ +/* + + atarisio - A UNIX backend for an Atari SIO2PC lead. + + Copyright (C) 2004 Ian Cowburn (ianc@noddybox.demon.co.uk) + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + + ------------------------------------------------------------------------- + + Command parsing and execution + +*/ +static const char ident[]="$Id$"; + +#include <stdlib.h> +#include <stdio.h> +#include <string.h> +#include <ctype.h> + +#include "token.h" + +static const char ident_h[]=ATARIOSIO_TOKEN_H; + +#ifndef TRUE +#define TRUE 1 +#endif + +#ifndef FALSE +#define FALSE 0 +#endif + +#define MAX_ARGS 128 + + +/* ---------------------------------------- STATICS +*/ + +static int no_cmds=0; +static Command *cmd_table=NULL; + + +/* ---------------------------------------- PRIVATE FUNCTIONS +*/ +static int QCompare(const void *a, const void *b) +{ + const Command *ca; + const Command *cb; + + ca=a; + cb=b; + + return strcmp(ca->cmd,cb->cmd); +} + + +static int BCompare(const void *a, const void *b) +{ + const Command *cb; + + cb=b; + + return strcmp(a,cb->cmd); +} + + +static char *GetToken(char **ptr) +{ + char qu=0; + char *tok; + char *p; + + p=*ptr; + + while(*p && isspace(*p)) + p++; + + if (!*p) + return NULL; + + if (*p=='\'' || *p=='"') + qu=*p++; + + tok=p; + + if (qu) + { + while(*p && *p!=qu) + p++; + + if (*p) + *p++=0; + else + printf("Warning: unterminated quotes\n"); + } + else + { + while(*p && !isspace(*p)) + p++; + + if (*p) + *p++=0; + } + + *ptr=p; + + return tok; +} + +static int Split(char *p, char **argv) +{ + int argc=0; + + while((argv[argc]=GetToken(&p))) + { + if (argc==MAX_ARGS) + { + argv[argc]=0; + return argc; + } + + argc++; + } + + return argc; +} + + +static void ShowHelp(const char *usage, const char *help) +{ + int l; + + printf("%s ",usage); + + for(l=strlen(usage);l<35;l++) + putchar('.'); + + printf(" %s\n",help); +} + + +static void HelpCommand(int argc, char *argv[]) +{ + if (argc==1) + { + int f; + + for(f=0;f<no_cmds;f++) + ShowHelp(cmd_table[f].usage,cmd_table[f].help); + } + else + { + Command *cmd; + + cmd=bsearch(argv[1],cmd_table,no_cmds,sizeof *cmd_table,BCompare); + + if (!cmd) + printf("Unknown command: %s\n",argv[1]); + else + ShowHelp(cmd->usage,cmd->help); + } +} + + +static void Init(void) +{ + static Command cmd[]= + { + {"help",1,2,"help [command]","Get help on commands",HelpCommand} + }; + + static int init=FALSE; + + if (!init) + { + init=TRUE; + TokenRegister(sizeof cmd/sizeof cmd[0],cmd); + } +} + + +/* ---------------------------------------- EXPORTED INTERFACES +*/ +void TokenRegister(int no, const Command *cmds) +{ + Init(); + + cmd_table=Realloc(cmd_table,sizeof(*cmds)*(no+no_cmds)); + memcpy(cmd_table+no_cmds,cmds,sizeof(*cmds)*no); + no_cmds+=no; + qsort(cmd_table,no_cmds,sizeof *cmd_table,QCompare); +} + + +int TokenRun(const char *line) +{ + char *p; + char *argv[MAX_ARGS]; + int argc; + int res; + int l; + + if (!(l=strlen(line))) + return FALSE; + + res=FALSE; + + p=StrCopy(line); + + if (p[l-1]=='\n') + p[--l]=0; + + argc=Split(p,argv); + + if (argc) + { + Command *cmd; + + cmd=bsearch(argv[0],cmd_table,no_cmds,sizeof *cmd_table,BCompare); + + if (cmd) + { + if (argc>=cmd->min_args && argc<=cmd->max_args) + { + res=TRUE; + cmd->func(argc,argv); + } + else + { + printf("usage: %s\n",cmd->usage); + } + } + else + { + printf("Unrecognised command %s\n",argv[0]); + } + } + + free(p); + + return res; +} + + +/* END OF FILE */ |