xref: /plan9/sys/src/cmd/fossil/Ccli.c (revision 5e96a66c77eb9140492ca53f857cbbf108e128ed)
1 #include "stdinc.h"
2 
3 #include "9.h"
4 
5 typedef struct {
6 	char*	argv0;
7 	int	(*cmd)(int, char*[]);
8 } Cmd;
9 
10 static struct {
11 	VtLock*	lock;
12 	Cmd*	cmd;
13 	int	ncmd;
14 	int	hi;
15 } cbox;
16 
17 enum {
18 	NCmdIncr	= 20,
19 };
20 
21 int
cliError(char * fmt,...)22 cliError(char* fmt, ...)
23 {
24 	char *p;
25 	va_list arg;
26 
27 	va_start(arg, fmt);
28 	p = vsmprint(fmt, arg);
29 	vtSetError("%s", p);
30 	free(p);
31 	va_end(arg);
32 
33 	return 0;
34 }
35 
36 int
cliExec(char * buf)37 cliExec(char* buf)
38 {
39 	int argc, i, r;
40 	char *argv[20], *p;
41 
42 	p = vtStrDup(buf);
43 	if((argc = tokenize(p, argv, nelem(argv)-1)) == 0){
44 		vtMemFree(p);
45 		return 1;
46 	}
47 	argv[argc] = 0;
48 
49 	if(argv[0][0] == '#'){
50 		vtMemFree(p);
51 		return 1;
52 	}
53 
54 	vtLock(cbox.lock);
55 	for(i = 0; i < cbox.hi; i++){
56 		if(strcmp(cbox.cmd[i].argv0, argv[0]) == 0){
57 			vtUnlock(cbox.lock);
58 			if(!(r = cbox.cmd[i].cmd(argc, argv)))
59 				consPrint("%s\n", vtGetError());
60 			vtMemFree(p);
61 			return r;
62 		}
63 	}
64 	vtUnlock(cbox.lock);
65 
66 	consPrint("%s: - eh?\n", argv[0]);
67 	vtMemFree(p);
68 
69 	return 0;
70 }
71 
72 int
cliAddCmd(char * argv0,int (* cmd)(int,char * []))73 cliAddCmd(char* argv0, int (*cmd)(int, char*[]))
74 {
75 	int i;
76 	Cmd *opt;
77 
78 	vtLock(cbox.lock);
79 	for(i = 0; i < cbox.hi; i++){
80 		if(strcmp(argv0, cbox.cmd[i].argv0) == 0){
81 			vtUnlock(cbox.lock);
82 			return 0;
83 		}
84 	}
85 	if(i >= cbox.hi){
86 		if(cbox.hi >= cbox.ncmd){
87 			cbox.cmd = vtMemRealloc(cbox.cmd,
88 					(cbox.ncmd+NCmdIncr)*sizeof(Cmd));
89 			memset(&cbox.cmd[cbox.ncmd], 0, NCmdIncr*sizeof(Cmd));
90 			cbox.ncmd += NCmdIncr;
91 		}
92 	}
93 
94 	opt = &cbox.cmd[cbox.hi];
95 	opt->argv0 = argv0;
96 	opt->cmd = cmd;
97 	cbox.hi++;
98 	vtUnlock(cbox.lock);
99 
100 	return 1;
101 }
102 
103 int
cliInit(void)104 cliInit(void)
105 {
106 	cbox.lock = vtLockAlloc();
107 	cbox.cmd = vtMemAllocZ(NCmdIncr*sizeof(Cmd));
108 	cbox.ncmd = NCmdIncr;
109 	cbox.hi = 0;
110 
111 	return 1;
112 }
113