15e96a66cSDavid du Colombier #include "stdinc.h"
25e96a66cSDavid du Colombier
35e96a66cSDavid du Colombier #include "9.h"
45e96a66cSDavid du Colombier
55e96a66cSDavid du Colombier typedef struct {
65e96a66cSDavid du Colombier char* argv0;
75e96a66cSDavid du Colombier int (*cmd)(int, char*[]);
85e96a66cSDavid du Colombier } Cmd;
95e96a66cSDavid du Colombier
105e96a66cSDavid du Colombier static struct {
11*d7aba6c3SDavid du Colombier QLock lock;
125e96a66cSDavid du Colombier Cmd* cmd;
135e96a66cSDavid du Colombier int ncmd;
145e96a66cSDavid du Colombier int hi;
155e96a66cSDavid du Colombier } cbox;
165e96a66cSDavid du Colombier
175e96a66cSDavid du Colombier enum {
185e96a66cSDavid du Colombier NCmdIncr = 20,
195e96a66cSDavid du Colombier };
205e96a66cSDavid du Colombier
215e96a66cSDavid du Colombier int
cliError(char * fmt,...)225e96a66cSDavid du Colombier cliError(char* fmt, ...)
235e96a66cSDavid du Colombier {
245e96a66cSDavid du Colombier char *p;
255e96a66cSDavid du Colombier va_list arg;
265e96a66cSDavid du Colombier
275e96a66cSDavid du Colombier va_start(arg, fmt);
285e96a66cSDavid du Colombier p = vsmprint(fmt, arg);
29*d7aba6c3SDavid du Colombier werrstr("%s", p);
305e96a66cSDavid du Colombier free(p);
315e96a66cSDavid du Colombier va_end(arg);
325e96a66cSDavid du Colombier
335e96a66cSDavid du Colombier return 0;
345e96a66cSDavid du Colombier }
355e96a66cSDavid du Colombier
365e96a66cSDavid du Colombier int
cliExec(char * buf)375e96a66cSDavid du Colombier cliExec(char* buf)
385e96a66cSDavid du Colombier {
395e96a66cSDavid du Colombier int argc, i, r;
405e96a66cSDavid du Colombier char *argv[20], *p;
415e96a66cSDavid du Colombier
42*d7aba6c3SDavid du Colombier p = vtstrdup(buf);
435e96a66cSDavid du Colombier if((argc = tokenize(p, argv, nelem(argv)-1)) == 0){
44*d7aba6c3SDavid du Colombier vtfree(p);
455e96a66cSDavid du Colombier return 1;
465e96a66cSDavid du Colombier }
475e96a66cSDavid du Colombier argv[argc] = 0;
485e96a66cSDavid du Colombier
495e96a66cSDavid du Colombier if(argv[0][0] == '#'){
50*d7aba6c3SDavid du Colombier vtfree(p);
515e96a66cSDavid du Colombier return 1;
525e96a66cSDavid du Colombier }
535e96a66cSDavid du Colombier
54*d7aba6c3SDavid du Colombier qlock(&cbox.lock);
555e96a66cSDavid du Colombier for(i = 0; i < cbox.hi; i++){
565e96a66cSDavid du Colombier if(strcmp(cbox.cmd[i].argv0, argv[0]) == 0){
57*d7aba6c3SDavid du Colombier qunlock(&cbox.lock);
585e96a66cSDavid du Colombier if(!(r = cbox.cmd[i].cmd(argc, argv)))
59*d7aba6c3SDavid du Colombier consPrint("%r\n");
60*d7aba6c3SDavid du Colombier vtfree(p);
615e96a66cSDavid du Colombier return r;
625e96a66cSDavid du Colombier }
635e96a66cSDavid du Colombier }
64*d7aba6c3SDavid du Colombier qunlock(&cbox.lock);
655e96a66cSDavid du Colombier
665e96a66cSDavid du Colombier consPrint("%s: - eh?\n", argv[0]);
67*d7aba6c3SDavid du Colombier vtfree(p);
685e96a66cSDavid du Colombier
695e96a66cSDavid du Colombier return 0;
705e96a66cSDavid du Colombier }
715e96a66cSDavid du Colombier
725e96a66cSDavid du Colombier int
cliAddCmd(char * argv0,int (* cmd)(int,char * []))735e96a66cSDavid du Colombier cliAddCmd(char* argv0, int (*cmd)(int, char*[]))
745e96a66cSDavid du Colombier {
755e96a66cSDavid du Colombier int i;
765e96a66cSDavid du Colombier Cmd *opt;
775e96a66cSDavid du Colombier
78*d7aba6c3SDavid du Colombier qlock(&cbox.lock);
795e96a66cSDavid du Colombier for(i = 0; i < cbox.hi; i++){
805e96a66cSDavid du Colombier if(strcmp(argv0, cbox.cmd[i].argv0) == 0){
81*d7aba6c3SDavid du Colombier qunlock(&cbox.lock);
825e96a66cSDavid du Colombier return 0;
835e96a66cSDavid du Colombier }
845e96a66cSDavid du Colombier }
855e96a66cSDavid du Colombier if(i >= cbox.hi){
865e96a66cSDavid du Colombier if(cbox.hi >= cbox.ncmd){
87*d7aba6c3SDavid du Colombier cbox.cmd = vtrealloc(cbox.cmd,
885e96a66cSDavid du Colombier (cbox.ncmd+NCmdIncr)*sizeof(Cmd));
895e96a66cSDavid du Colombier memset(&cbox.cmd[cbox.ncmd], 0, NCmdIncr*sizeof(Cmd));
905e96a66cSDavid du Colombier cbox.ncmd += NCmdIncr;
915e96a66cSDavid du Colombier }
925e96a66cSDavid du Colombier }
935e96a66cSDavid du Colombier
945e96a66cSDavid du Colombier opt = &cbox.cmd[cbox.hi];
955e96a66cSDavid du Colombier opt->argv0 = argv0;
965e96a66cSDavid du Colombier opt->cmd = cmd;
975e96a66cSDavid du Colombier cbox.hi++;
98*d7aba6c3SDavid du Colombier qunlock(&cbox.lock);
995e96a66cSDavid du Colombier
1005e96a66cSDavid du Colombier return 1;
1015e96a66cSDavid du Colombier }
1025e96a66cSDavid du Colombier
1035e96a66cSDavid du Colombier int
cliInit(void)1045e96a66cSDavid du Colombier cliInit(void)
1055e96a66cSDavid du Colombier {
106*d7aba6c3SDavid du Colombier cbox.cmd = vtmallocz(NCmdIncr*sizeof(Cmd));
1075e96a66cSDavid du Colombier cbox.ncmd = NCmdIncr;
1085e96a66cSDavid du Colombier cbox.hi = 0;
1095e96a66cSDavid du Colombier
1105e96a66cSDavid du Colombier return 1;
1115e96a66cSDavid du Colombier }
112