| plan 9 kernel history: overview | file list | diff list |
2001/0405/port/parse.c (diff list | history)
| 1999/0316/sys/src/9/port/parse.c:5,27 – 2000/0308/sys/src/9/port/parse.c:5,10 (short | long) | ||
|
Replace parsefields with new library function getfields, now that getfields is thread-safe.
rsc Fri Mar 4 12:44:25 2005 | ||
| 1999/0316 | #include "fns.h" #include "../port/error.h" | |
| 1999/0316/sys/src/9/port/parse.c:38,44 – 2000/0308/sys/src/9/port/parse.c:21,27 | ||
| 1999/0316 | if(n > 0 && cb->buf[n-1] == '\n') n--; cb->buf[n] = '\0'; | |
| 2000/0308 | cb->nf = getfields(cb->buf, cb->f, nelem(cb->f), 1, " "); | |
| 1999/0316 | return cb; } | |
| 2000/0308/sys/src/9/port/parse.c:11,23 – 2001/0331/sys/src/9/port/parse.c:11,30 (short | long) | ||
|
Bug fix: guard against error in user to kernel memmove.
rsc Fri Mar 4 12:44:25 2005 | ||
| 1999/0316 | Cmdbuf* parsecmd(char *p, int n) { | |
| 2001/0331 | Cmdbuf *volatile cb; | |
| 1999/0316 | cb = smalloc(sizeof(*cb)); if(n > sizeof(cb->buf)-1) n = sizeof(cb->buf)-1; | |
| 2001/0331 | if(waserror()){ free(cb); nexterror(); } | |
| 1999/0316 | memmove(cb->buf, p, n); | |
| 2001/0331 | poperror(); | |
| 1999/0316 | if(n > 0 && cb->buf[n-1] == '\n') n--; cb->buf[n] = '\0'; | |
| 2001/0331/sys/src/9/port/parse.c:13,29 – 2001/0405/sys/src/9/port/parse.c:13,36 (short | long) | ||
|
Bug fix: only call smalloc, waserror, poperror when running a user process.
rsc Fri Mar 4 12:44:25 2005 | ||
| 1999/0316 | { | |
| 2001/0331 | Cmdbuf *volatile cb; | |
| 1999/0316 |
| |
| 2001/0405 | if(up != nil) cb = smalloc(sizeof(*cb)); else{ cb = malloc(sizeof(*cb)); if(cb == nil) return nil; } | |
| 1999/0316 | if(n > sizeof(cb->buf)-1) n = sizeof(cb->buf)-1; | |
| 2001/0331 |
| |
| 2001/0405 | if(up != nil && waserror()){ | |
| 2001/0331 | free(cb); nexterror(); } | |
| 1999/0316 | memmove(cb->buf, p, n); | |
| 2001/0331 |
| |
| 2001/0405 | if(up != nil) poperror(); | |
| 2001/0331 | ||
| 1999/0316 | if(n > 0 && cb->buf[n-1] == '\n') n--; | |
| 2001/0405/sys/src/9/port/parse.c:35,41 – 2001/0418/sys/src/9/port/parse.c:35,41 (short | long) | ||
|
Change getfields to tokenize for quoted strings.
rsc Fri Mar 4 12:44:25 2005 | ||
| 1999/0316 | if(n > 0 && cb->buf[n-1] == '\n') n--; cb->buf[n] = '\0'; | |
| 2000/0308 |
| |
| 2001/0418 | cb->nf = tokenize(cb->buf, cb->f, nelem(cb->f)); | |
| 1999/0316 | return cb; } | |
| 2001/0418/sys/src/9/port/parse.c:13,30 – 2001/0527/sys/src/9/port/parse.c:13,24 (short | long) | ||
|
Change tokenize back to getfields to avoid quoted strings.
Format edits. Bug: call smalloc always.
rsc Fri Mar 4 12:44:25 2005 | ||
| 1999/0316 | { | |
| 2001/0331 | Cmdbuf *volatile cb; | |
| 1999/0316 | ||
| 2001/0405 |
| |
| 2001/0527 | cb = smalloc(sizeof(*cb)); | |
| 1999/0316 | if(n > sizeof(cb->buf)-1) n = sizeof(cb->buf)-1; | |
| 2001/0331 | ||
| 2001/0405 |
| |
| 2001/0527 | if(up!=nil && waserror()){ | |
| 2001/0331 | free(cb); nexterror(); } | |
| 2001/0418/sys/src/9/port/parse.c:35,41 – 2001/0527/sys/src/9/port/parse.c:29,35 | ||
| 1999/0316 | if(n > 0 && cb->buf[n-1] == '\n') n--; cb->buf[n] = '\0'; | |
| 2001/0418 |
| |
| 2001/0527 | cb->nf = getfields(cb->buf, cb->f, nelem(cb->f), 1, " "); | |
| 1999/0316 | return cb; } | |
| 2001/0527/sys/src/9/port/parse.c:12,22 – 2001/1108/sys/src/9/port/parse.c:12,27 (short | long) | ||
|
Avoid fixed field count; allocate enough for list of fields.
rsc Fri Mar 4 12:44:25 2005 | ||
| 1999/0316 | parsecmd(char *p, int n) { | |
| 2001/0331 | Cmdbuf *volatile cb; | |
| 2001/1108 | int nf; char *sp; | |
| 1999/0316 | ||
| 2001/0527 |
| |
| 1999/0316 |
| |
| 2001/1108 | /* count fields and allocate a big enough cmdbuf */ for(nf = 1, sp = p; sp != nil && *sp; nf++, sp = strchr(sp+1, ' ')) ; sp = smalloc(sizeof(*cb) + n + 1 + nf*sizeof(char*)); cb = (Cmdbuf*)sp; cb->buf = sp+sizeof(*cb); cb->f = (char**)(cb->buf + n + 1); | |
| 2001/0331 | ||
| 2001/0527 | if(up!=nil && waserror()){ | |
| 2001/0331 | free(cb); | |
| 2001/0527/sys/src/9/port/parse.c:26,35 – 2001/1108/sys/src/9/port/parse.c:31,42 | ||
| 2001/0405 | if(up != nil) poperror(); | |
| 2001/0331 | ||
| 2001/1108 | /* dump new line and null terminate */ | |
| 1999/0316 | if(n > 0 && cb->buf[n-1] == '\n') n--; cb->buf[n] = '\0'; | |
| 2001/0527 |
| |
| 2001/1108 | cb->nf = getfields(cb->buf, cb->f, nf, 1, " "); | |
| 1999/0316 | return cb; } | |
| 2001/1108/sys/src/9/port/parse.c:6,11 – 2001/1117/sys/src/9/port/parse.c:6,36 (short | long) | ||
|
Reduce estimate of field count. Change back to tokenize.
rsc Fri Mar 4 12:44:25 2005 | ||
| 1999/0316 | #include "../port/error.h" /* | |
| 2001/1117 | * 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 */ } /* | |
| 1999/0316 | * parse a command written to a device */ Cmdbuf* | |
| 2001/1108/sys/src/9/port/parse.c:15,27 – 2001/1117/sys/src/9/port/parse.c:40,52 | ||
| 2001/1108 | int nf; char *sp; | |
| 1999/0316 | ||
| 2001/1108 |
| |
| 2001/1117 | nf = ncmdfield(p, n); /* allocate Cmdbuf plus string pointers plus copy of string including \0 */ sp = smalloc(sizeof(*cb) + nf * sizeof(char*) + n + 1); | |
| 2001/1108 | cb = (Cmdbuf*)sp; | |
| 2001/1117 | cb->f = (char**)(&cb[1]); cb->buf = (char*)(&cb->f[nf]); | |
| 2001/0331 | ||
| 2001/0527 | if(up!=nil && waserror()){ | |
| 2001/0331 | free(cb); | |
| 2001/1108/sys/src/9/port/parse.c:36,42 – 2001/1117/sys/src/9/port/parse.c:61,69 | ||
| 1999/0316 | n--; cb->buf[n] = '\0'; | |
| 2001/1108 |
| |
| 2001/1117 | cb->nf = tokenize(cb->buf, cb->f, nf-1); cb->f[cb->nf] = nil; | |
| 1999/0316 | return cb; } | |
| 2001/1117/sys/src/9/port/parse.c:67,69 – 2001/1118/sys/src/9/port/parse.c:67,90 (short | long) | ||
|
Add lookupcmd.
rsc Fri Mar 4 12:44:25 2005 | ||
| 1999/0316 | return cb; } | |
| 2001/1118 | /* * Look up entry in table */ Cmdtab* lookupcmd(Cmdbuf *cb, Cmdtab *ct, int nct) { int i; if(cb->nf == 0) error(Ebadctl); for(i=0; i<nct; i++, ct++){ if(strcmp(cb->f[0], ct->cmd) != 0) continue; if(ct->narg!=0 && ct->narg!=cb->nf) error(Eargctl); return ct; } error(Ebadctl); return nil; } | |
| 2001/1118/sys/src/9/port/parse.c:68,90 – 2001/1120/sys/src/9/port/parse.c:68,114 (short | long) | ||
|
Add wildcard command. Add cmderror. Better error strings.
rsc Fri Mar 4 12:44:25 2005 | ||
| 1999/0316 | } | |
| 2001/1118 | /* | |
| 2001/1120 | * Reconstruct original message, for error diagnostic */ void cmderror(Cmdbuf *cb, char *s) { int i; char *p, *e; p = up->genbuf; e = p+ERRMAX-10; p = seprint(p, e, "%s \"", s); for(i=0; i<cb->nf; i++){ if(i > 0) p = seprint(p, e, " "); p = seprint(p, e, "%q", cb->f[i]); } strcpy(p, "\""); error(up->genbuf); } /* | |
| 2001/1118 | * Look up entry in table */ Cmdtab* | |
| 2001/1120 | lookupcmd(Cmdbuf *cb, Cmdtab *ctab, int nctab) | |
| 2001/1118 | { int i; | |
| 2001/1120 | Cmdtab *ct; | |
| 2001/1118 | if(cb->nf == 0) | |
| 2001/1120 | error("empty control message"); | |
| 2001/1118 |
| |
| 2001/1120 | for(ct = ctab, i=0; i<nctab; i++, ct++){ if(strcmp(ct->cmd, "*") !=0) /* wildcard always matches */ if(strcmp(ct->cmd, cb->f[0]) != 0) | |
| 2001/1118 | continue; | |
| 2001/1120 | if(ct->narg != 0 && ct->narg != cb->nf) cmderror(cb, Ecmdargs); | |
| 2001/1118 | return ct; } | |
| 2001/1120 | cmderror(cb, "unknown control message"); | |
| 2001/1118 | return nil; } | |