From 2277c5d7bbe1f9595fad512d8f790708473a9bf1 Mon Sep 17 00:00:00 2001 From: rsc Date: Sun, 21 Mar 2004 04:33:13 +0000 Subject: Small tweaks Lots of new code imported. --- src/lib9p/parse.c | 115 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 115 insertions(+) create mode 100644 src/lib9p/parse.c (limited to 'src/lib9p/parse.c') diff --git a/src/lib9p/parse.c b/src/lib9p/parse.c new file mode 100644 index 00000000..753ae79d --- /dev/null +++ b/src/lib9p/parse.c @@ -0,0 +1,115 @@ +#include +#include +#include +#include +#include <9p.h> + +/* + * Generous estimate of number of fields, including terminal nil pointer + */ +static int +ncmdfield(char *p, int n) +{ + int white, nwhite; + char *ep; + int nf; + + if(p == nil) + return 1; + + nf = 0; + ep = p+n; + white = 1; /* first text will start field */ + while(p < ep){ + nwhite = (strchr(" \t\r\n", *p++ & 0xFF) != 0); /* UTF is irrelevant */ + if(white && !nwhite) /* beginning of field */ + nf++; + white = nwhite; + } + return nf+1; /* +1 for nil */ +} + +/* + * parse a command written to a device + */ +Cmdbuf* +parsecmd(char *p, int n) +{ + Cmdbuf *cb; + int nf; + char *sp; + + nf = ncmdfield(p, n); + + /* allocate Cmdbuf plus string pointers plus copy of string including \0 */ + sp = emalloc9p(sizeof(*cb) + nf * sizeof(char*) + n + 1); + cb = (Cmdbuf*)sp; + cb->f = (char**)(&cb[1]); + cb->buf = (char*)(&cb->f[nf]); + + memmove(cb->buf, p, n); + + /* dump new line and null terminate */ + if(n > 0 && cb->buf[n-1] == '\n') + n--; + cb->buf[n] = '\0'; + + cb->nf = tokenize(cb->buf, cb->f, nf-1); + cb->f[cb->nf] = nil; + + return cb; +} + +/* + * Reconstruct original message, for error diagnostic + */ +void +respondcmderror(Req *r, Cmdbuf *cb, char *fmt, ...) +{ + int i; + va_list arg; + char *p, *e; + char err[ERRMAX]; + + e = err+ERRMAX-10; + va_start(arg, fmt); + p = vseprint(err, e, fmt, arg); + va_end(arg); + p = seprint(p, e, ": \""); + for(i=0; inf; i++){ + if(i > 0) + p = seprint(p, e, " "); + p = seprint(p, e, "%q", cb->f[i]); + } + strcpy(p, "\""); + respond(r, err); +} + +/* + * Look up entry in table + */ +Cmdtab* +lookupcmd(Cmdbuf *cb, Cmdtab *ctab, int nctab) +{ + int i; + Cmdtab *ct; + + if(cb->nf == 0){ + werrstr("empty control message"); + return nil; + } + + for(ct = ctab, i=0; icmd, "*") !=0) /* wildcard always matches */ + if(strcmp(ct->cmd, cb->f[0]) != 0) + continue; + if(ct->narg != 0 && ct->narg != cb->nf){ + werrstr("bad # args to command"); + return nil; + } + return ct; + } + + werrstr("unknown control message"); + return nil; +} -- cgit v1.2.3