Main Page | Data Structures | File List | Data Fields | Globals | Related Pages

cmdhandler.c

Go to the documentation of this file.
00001 #include <string.h>
00002 #include <stdlib.h>
00003 #include <assert.h>
00004 #include <neuro/stringtable.h>
00005 #include <neuro/cmdhandler.h>
00006 #include "nsutil.h"
00007 #include "nsnet.h"
00008 #include "nsd.h"
00009 
00010 #define MAXTOKENS 256
00011 
00012 struct CommandHandler {
00013   struct StringTable *cmds, *clients;
00014   struct ClientState *curClient;
00015 };
00016 
00017 struct CommandEntry {
00018         void (*func)(struct CommandHandler *ch, int cliInd);
00019 };
00020 
00021 struct ClientState {
00022   char *curline;
00023   int tokenCount;
00024   char *tokens[MAXTOKENS];
00025 };
00026 
00027 struct CommandHandler *newCommandHandler(void)
00028 {
00029   struct CommandHandler *ch;
00030   ch = calloc(sizeof(struct CommandHandler), 1);
00031   ch->cmds = newStringTable();
00032   ch->clients = newStringTable();
00033   return ch;
00034 }
00035 
00036 void freeValues(struct StringTable *st, const char *key, void *val, void *udata)
00037 {
00038   free(val);
00039 }
00040 
00041 void freeCS(struct StringTable *st, const char *key, void *val, void *udata)
00042 {
00043   struct ClientState *cs = (struct ClientState *) val;
00044   if (cs->curline != NULL) {
00045     free(cs->curline);
00046     cs->curline = NULL;
00047   }
00048 }
00049 
00050 void freeCommandHandler(struct CommandHandler *ch)
00051 {
00052   allStrings(ch->cmds, freeValues, NULL);
00053   allStrings(ch->clients, freeCS, NULL);
00054   allStrings(ch->clients, freeValues, NULL);
00055   freeStringTable(ch->cmds);
00056   freeStringTable(ch->clients);
00057   ch->cmds = ch->clients = NULL;
00058   free(ch);
00059 }
00060 
00061 static const char *indexToStr(int cliIndex)
00062 {
00063   static char buf[80];
00064   sprintf(buf, "%d", cliIndex);
00065   return buf;
00066 }
00067 
00068 /* Call this when you accept a new client */
00069 void newClientStarted(struct CommandHandler *ch, int cliIndex)
00070 {
00071   struct ClientState *cs;
00072   cs = calloc(sizeof(struct ClientState), 1);
00073   putString(ch->clients, indexToStr(cliIndex), cs);
00074 }
00075 
00076 /* Pass in command string and function pointer */
00077 void enregisterCommand(struct CommandHandler *ch, const char *cmd, void (*func)(struct CommandHandler *ch, int))
00078 {
00079   struct CommandEntry *ce;
00080   ce = calloc(sizeof(struct CommandEntry), 1);
00081   ce->func = func;
00082   putString(ch->cmds, cmd, ce);
00083 }
00084 
00085 static void replaceCurline(struct ClientState *cs, const char *line)
00086 {
00087   int linelen = strlen(line);
00088   if (cs->curline)
00089     free(cs->curline);
00090   cs->curline = calloc(strlen(line)+2, 1);
00091   memcpy(cs->curline, line, linelen);
00092   cs->curline[linelen] = ' ';
00093   cs->curline[linelen+1] = 0;
00094 }
00095 
00096 static void addToken(struct ClientState *cs, char *tok)
00097 {
00098   int i, j=0;
00099   assert(cs->tokenCount < MAXTOKENS);
00100   for (i = 0; tok[i]; i += 1) {
00101     if (tok[i] == '\\' && tok[i+1])
00102       i += 1;
00103     tok[j] = tok[i];
00104     j += 1;
00105   }
00106   tok[j] = 0;
00107   cs->tokens[cs->tokenCount] = tok;
00108   cs->tokenCount += 1;
00109 }
00110 
00111 static void tokenizeLine(struct ClientState *cs)
00112 {
00113   int i;
00114   int inQuote=0;
00115   int inBackslash=0;
00116   int inSpace=1;
00117   int startPos = 0;
00118   memset(cs->tokens, 0, sizeof(cs->tokens));
00119   cs->tokenCount = 0;
00120   for (i = 0; cs->curline[i]; i += 1) {
00121     char c = cs->curline[i];
00122     if (inBackslash) {
00123       inBackslash = 0;
00124       continue;
00125     }
00126     if (c == '\\') {
00127       if (inSpace) {
00128         inSpace = 0;
00129         startPos = i;
00130       }
00131       inBackslash = 1;
00132       continue;
00133     }
00134     if (c == '"') {
00135       if (inQuote) {
00136         inQuote = 0;
00137         inSpace = 1;
00138         cs->curline[i] = 0;
00139         addToken(cs, cs->curline+startPos);
00140         continue;
00141       } else {
00142         if (cs->curline[i+1]) {
00143           startPos = i+1;
00144           inSpace = 0;
00145           inQuote = 1;
00146         }
00147         continue;
00148       }
00149     }
00150     if (c == '\r' || c == '\n' || c == '\t' || c == ' '
00151                   || cs->curline[i+1] == 0) {
00152       if (inQuote) continue;
00153       if (inSpace) continue;
00154       if (c == '\r' || c == '\n' || c == '\t' || c == ' ')
00155         cs->curline[i] = 0;
00156       addToken(cs, cs->curline+startPos);
00157       inSpace = 1;
00158       continue;
00159     }
00160     if (inSpace) {
00161       startPos = i;
00162       inSpace = 0;
00163       continue;
00164     }
00165   }
00166 }
00167 
00168 void handleLine(struct CommandHandler *ch, const char *line, int cliIndex)
00169 {
00170   struct ClientState *cs;
00171   struct CommandEntry *ce;
00172   cs = findString(ch->clients, indexToStr(cliIndex));
00173   assert(cs != NULL);
00174   replaceCurline(cs, line);
00175   tokenizeLine(cs);
00176   if (0)
00177   { int i;
00178     for (i = 0; i < cs->tokenCount; ++i)
00179       printf("%d: <%s>\n", i, cs->tokens[i]);
00180   }
00181   ce = findString(ch->cmds, cs->tokens[0]);
00182   if (ce == NULL)
00183     ce = findString(ch->cmds, "unknown");
00184   if (ce) {
00185     ch->curClient = cs;
00186     ce->func(ch, cliIndex);
00187     ch->curClient = NULL;
00188   }
00189 }
00190 
00191 /* TODO: fix me, redefine / refactor */
00192 int fetchIntParameters(struct CommandHandler *ch, int *vals, int num)
00193 {
00194   int i;
00195   for (i = 0; i < num; ++i)
00196     vals[i] = atoi(ch->curClient->tokens[i+1]);
00197   return 0;
00198 }
00199 
00200 const char *fetchCommandName(struct CommandHandler *ch)
00201 {
00202   return ch->curClient->tokens[0];
00203 }
00204 
00205 const char *fetchStringParameter(struct CommandHandler *ch, int which)
00206 {
00207   return ch->curClient->tokens[which+1];
00208 }
00209 

Generated on Tue Feb 8 00:05:15 2005 for Neuroserver by doxygen 1.3.3