1
8
9
10
11
12
13
16
21
22
25
28
29
37
38
39
40
41
42
43
48
49
50
51
52
53
56
57
58
59
60
61
66
67
68
73
74
84
85
91
92
96
103
104
105
106
107
108
109
110
111
112
113
114
119
120
121
122
123
129
130
131
142
143
144
148
149
150
151
171
172
173
176
177
187
188
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
234
235
/* ... */
#include <stdio.h>
#include <string.h>
#include <jim-subcmd.h>
/* ... */
static int subcmd_null(Jim_Interp *interp, int argc, Jim_Obj *const *argv)
{
return JIM_OK;
}{ ... }
/* ... */
static const jim_subcmd_type dummy_subcmd = {
"dummy", NULL, subcmd_null, 0, 0, JIM_MODFLAG_HIDDEN
...};
/* ... */
static Jim_Obj *subcmd_cmd_list(Jim_Interp *interp, const jim_subcmd_type * ct, const char *sep)
{
Jim_Obj *listObj = Jim_NewListObj(interp, NULL, 0);
Jim_Obj *sortCmd[2];
for (; ct->cmd; ct++) {
if (!(ct->flags & JIM_MODFLAG_HIDDEN)) {
Jim_ListAppendElement(interp, listObj, Jim_NewStringObj(interp, ct->cmd, -1));
}if (!(ct->flags & JIM_MODFLAG_HIDDEN)) { ... }
}for (; ct->cmd; ct++) { ... }
sortCmd[0] = Jim_NewStringObj(interp, "lsort", -1);
sortCmd[1] = listObj;
if (Jim_EvalObjVector(interp, 2, sortCmd) == JIM_OK) {
return Jim_ListJoin(interp, Jim_GetResult(interp), sep, strlen(sep));
}if (Jim_EvalObjVector(interp, 2, sortCmd) == JIM_OK) { ... }
return Jim_GetResult(interp);
}{ ... }
static void bad_subcmd(Jim_Interp *interp, const jim_subcmd_type * command_table, const char *type,
Jim_Obj *cmd, Jim_Obj *subcmd)
{
Jim_SetResultFormatted(interp, "%#s, %s command \"%#s\": should be %#s", cmd, type,
subcmd, subcmd_cmd_list(interp, command_table, ", "));
}{ ... }
static void show_cmd_usage(Jim_Interp *interp, const jim_subcmd_type * command_table, int argc,
Jim_Obj *const *argv)
{
Jim_SetResultFormatted(interp, "Usage: \"%#s command ... \", where command is one of: %#s",
argv[0], subcmd_cmd_list(interp, command_table, ", "));
}{ ... }
static void add_cmd_usage(Jim_Interp *interp, const jim_subcmd_type * ct, Jim_Obj *cmd)
{
if (cmd) {
Jim_AppendStrings(interp, Jim_GetResult(interp), Jim_String(cmd), " ", NULL);
}if (cmd) { ... }
Jim_AppendStrings(interp, Jim_GetResult(interp), ct->cmd, NULL);
if (ct->args && *ct->args) {
Jim_AppendStrings(interp, Jim_GetResult(interp), " ", ct->args, NULL);
}if (ct->args && *ct->args) { ... }
}{ ... }
static void set_wrong_args(Jim_Interp *interp, const jim_subcmd_type * command_table, Jim_Obj *subcmd)
{
Jim_SetResultString(interp, "wrong # args: should be \"", -1);
add_cmd_usage(interp, command_table, subcmd);
Jim_AppendStrings(interp, Jim_GetResult(interp), "\"", NULL);
}{ ... }
/* ... */
static const Jim_ObjType subcmdLookupObjType = {
"subcmd-lookup",
NULL,
NULL,
NULL,
JIM_TYPE_REFERENCES
...};
const jim_subcmd_type *Jim_ParseSubCmd(Jim_Interp *interp, const jim_subcmd_type * command_table,
int argc, Jim_Obj *const *argv)
{
const jim_subcmd_type *ct;
const jim_subcmd_type *partial = 0;
int cmdlen;
Jim_Obj *cmd;
const char *cmdstr;
int help = 0;
if (argc < 2) {
Jim_SetResultFormatted(interp, "wrong # args: should be \"%#s command ...\"\n"
"Use \"%#s -help ?command?\" for help", argv[0], argv[0]);
return 0;
}if (argc < 2) { ... }
cmd = argv[1];
if (cmd->typePtr == &subcmdLookupObjType) {
if (cmd->internalRep.ptrIntValue.ptr == command_table) {
ct = command_table + cmd->internalRep.ptrIntValue.int1;
goto found;
}if (cmd->internalRep.ptrIntValue.ptr == command_table) { ... }
}if (cmd->typePtr == &subcmdLookupObjType) { ... }
if (Jim_CompareStringImmediate(interp, cmd, "-help")) {
if (argc == 2) {
show_cmd_usage(interp, command_table, argc, argv);
return &dummy_subcmd;
}if (argc == 2) { ... }
help = 1;
cmd = argv[2];
}if (Jim_CompareStringImmediate(interp, cmd, "-help")) { ... }
if (Jim_CompareStringImmediate(interp, cmd, "-commands")) {
Jim_SetResult(interp, subcmd_cmd_list(interp, command_table, " "));
return &dummy_subcmd;
}if (Jim_CompareStringImmediate(interp, cmd, "-commands")) { ... }
cmdstr = Jim_GetString(cmd, &cmdlen);
for (ct = command_table; ct->cmd; ct++) {
if (Jim_CompareStringImmediate(interp, cmd, ct->cmd)) {
break;
}if (Jim_CompareStringImmediate(interp, cmd, ct->cmd)) { ... }
if (strncmp(cmdstr, ct->cmd, cmdlen) == 0) {
if (partial) {
if (help) {
show_cmd_usage(interp, command_table, argc, argv);
return &dummy_subcmd;
}if (help) { ... }
bad_subcmd(interp, command_table, "ambiguous", argv[0], argv[1 + help]);
return 0;
}if (partial) { ... }
partial = ct;
}if (strncmp(cmdstr, ct->cmd, cmdlen) == 0) { ... }
continue;
}for (ct = command_table; ct->cmd; ct++) { ... }
if (partial && !ct->cmd) {
ct = partial;
}if (partial && !ct->cmd) { ... }
if (!ct->cmd) {
if (help) {
show_cmd_usage(interp, command_table, argc, argv);
return &dummy_subcmd;
}if (help) { ... }
bad_subcmd(interp, command_table, "unknown", argv[0], argv[1 + help]);
return 0;
}if (!ct->cmd) { ... }
if (help) {
Jim_SetResultString(interp, "Usage: ", -1);
add_cmd_usage(interp, ct, argv[0]);
return &dummy_subcmd;
}if (help) { ... }
Jim_FreeIntRep(interp, cmd);
cmd->typePtr = &subcmdLookupObjType;
cmd->internalRep.ptrIntValue.ptr = (void *)command_table;
cmd->internalRep.ptrIntValue.int1 = ct - command_table;
found:
if (argc - 2 < ct->minargs || (ct->maxargs >= 0 && argc - 2 > ct->maxargs)) {
Jim_SetResultString(interp, "wrong # args: should be \"", -1);
add_cmd_usage(interp, ct, argv[0]);
Jim_AppendStrings(interp, Jim_GetResult(interp), "\"", NULL);
return 0;
}if (argc - 2 < ct->minargs || (ct->maxargs >= 0 && argc - 2 > ct->maxargs)) { ... }
return ct;
}{ ... }
int Jim_CallSubCmd(Jim_Interp *interp, const jim_subcmd_type * ct, int argc, Jim_Obj *const *argv)
{
int ret = JIM_ERR;
if (ct) {
if (ct->flags & JIM_MODFLAG_FULLARGV) {
ret = ct->function(interp, argc, argv);
}if (ct->flags & JIM_MODFLAG_FULLARGV) { ... }
else {
ret = ct->function(interp, argc - 2, argv + 2);
}else { ... }
if (ret < 0) {
set_wrong_args(interp, ct, argv[0]);
ret = JIM_ERR;
}if (ret < 0) { ... }
}if (ct) { ... }
return ret;
}{ ... }
int Jim_SubCmdProc(Jim_Interp *interp, int argc, Jim_Obj *const *argv)
{
const jim_subcmd_type *ct =
Jim_ParseSubCmd(interp, (const jim_subcmd_type *)Jim_CmdPrivData(interp), argc, argv);
return Jim_CallSubCmd(interp, ct, argc, argv);
}{ ... }