/* 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 #include #include #include #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;fusage,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 */