xref: /plan9-contrib/sys/src/cmd/fossil/Ccli.c (revision d7aba6c3b511bc618cf0c53345848188fc02611a)
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