1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
|
#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;
}
|