| #include "stdinc.h" |
| |
| #include "9.h" |
| |
| typedef struct { |
| char* argv0; |
| int (*cmd)(int, char*[]); |
| } Cmd; |
| |
| static struct { |
| QLock lock; |
| Cmd* cmd; |
| int ncmd; |
| int hi; |
| } cbox; |
| |
| enum { |
| NCmdIncr = 20, |
| }; |
| |
| int |
| cliError(char* fmt, ...) |
| { |
| char *p; |
| va_list arg; |
| |
| va_start(arg, fmt); |
| p = vsmprint(fmt, arg); |
| werrstr("%s", p); |
| free(p); |
| va_end(arg); |
| |
| return 0; |
| } |
| |
| int |
| cliExec(char* buf) |
| { |
| int argc, i, r; |
| char *argv[20], *p; |
| |
| p = vtstrdup(buf); |
| if((argc = tokenize(p, argv, nelem(argv)-1)) == 0){ |
| vtfree(p); |
| return 1; |
| } |
| argv[argc] = 0; |
| |
| if(argv[0][0] == '#'){ |
| vtfree(p); |
| return 1; |
| } |
| |
| qlock(&cbox.lock); |
| for(i = 0; i < cbox.hi; i++){ |
| if(strcmp(cbox.cmd[i].argv0, argv[0]) == 0){ |
| qunlock(&cbox.lock); |
| if(!(r = cbox.cmd[i].cmd(argc, argv))) |
| consPrint("%r\n"); |
| vtfree(p); |
| return r; |
| } |
| } |
| qunlock(&cbox.lock); |
| |
| consPrint("%s: - eh?\n", argv[0]); |
| vtfree(p); |
| |
| return 0; |
| } |
| |
| int |
| cliAddCmd(char* argv0, int (*cmd)(int, char*[])) |
| { |
| int i; |
| Cmd *opt; |
| |
| qlock(&cbox.lock); |
| for(i = 0; i < cbox.hi; i++){ |
| if(strcmp(argv0, cbox.cmd[i].argv0) == 0){ |
| qunlock(&cbox.lock); |
| return 0; |
| } |
| } |
| if(i >= cbox.hi){ |
| if(cbox.hi >= cbox.ncmd){ |
| cbox.cmd = vtrealloc(cbox.cmd, |
| (cbox.ncmd+NCmdIncr)*sizeof(Cmd)); |
| memset(&cbox.cmd[cbox.ncmd], 0, NCmdIncr*sizeof(Cmd)); |
| cbox.ncmd += NCmdIncr; |
| } |
| } |
| |
| opt = &cbox.cmd[cbox.hi]; |
| opt->argv0 = argv0; |
| opt->cmd = cmd; |
| cbox.hi++; |
| qunlock(&cbox.lock); |
| |
| return 1; |
| } |
| |
| int |
| cliInit(void) |
| { |
| cbox.cmd = vtmallocz(NCmdIncr*sizeof(Cmd)); |
| cbox.ncmd = NCmdIncr; |
| cbox.hi = 0; |
| |
| return 1; |
| } |