summaryrefslogtreecommitdiff
path: root/jim-subcmd.c
diff options
context:
space:
mode:
Diffstat (limited to 'jim-subcmd.c')
-rw-r--r--jim-subcmd.c44
1 files changed, 31 insertions, 13 deletions
diff --git a/jim-subcmd.c b/jim-subcmd.c
index c522830..1a090d5 100644
--- a/jim-subcmd.c
+++ b/jim-subcmd.c
@@ -41,18 +41,14 @@ static void add_commands(Jim_Interp *interp, const jim_subcmd_type * ct, const c
static void bad_subcmd(Jim_Interp *interp, const jim_subcmd_type * command_table, const char *type,
Jim_Obj *cmd, Jim_Obj *subcmd)
{
- Jim_SetResult(interp, Jim_NewEmptyStringObj(interp));
- Jim_AppendStrings(interp, Jim_GetResult(interp), Jim_String(cmd), ", ", type,
- " command \"", Jim_String(subcmd), "\": should be ", NULL);
+ Jim_SetResultFormatted(interp, "%#s, %s command \"%#s\": should be ", cmd, type, subcmd);
add_commands(interp, command_table, ", ");
}
static void show_cmd_usage(Jim_Interp *interp, const jim_subcmd_type * command_table, int argc,
Jim_Obj *const *argv)
{
- Jim_SetResult(interp, Jim_NewEmptyStringObj(interp));
- Jim_AppendStrings(interp, Jim_GetResult(interp), "Usage: \"", Jim_String(argv[0]),
- " command ... \", where command is one of: ", NULL);
+ Jim_SetResultFormatted(interp, "Usage: \"%#s command ... \", where command is one of: ", argv[0]);
add_commands(interp, command_table, ", ");
}
@@ -74,6 +70,18 @@ static void set_wrong_args(Jim_Interp *interp, const jim_subcmd_type * command_t
Jim_AppendStrings(interp, Jim_GetResult(interp), "\"", NULL);
}
+/* internal rep is stored in ptrIntvalue
+ * ptr = command_table
+ * int1 = index
+ */
+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)
{
@@ -82,21 +90,24 @@ const jim_subcmd_type *Jim_ParseSubCmd(Jim_Interp *interp, const jim_subcmd_type
int cmdlen;
Jim_Obj *cmd;
const char *cmdstr;
- const char *cmdname;
int help = 0;
- cmdname = Jim_String(argv[0]);
-
if (argc < 2) {
- Jim_SetResult(interp, Jim_NewEmptyStringObj(interp));
- Jim_AppendStrings(interp, Jim_GetResult(interp), "wrong # args: should be \"", cmdname,
- " command ...\"\n", NULL);
- Jim_AppendStrings(interp, Jim_GetResult(interp), "Use \"", cmdname, " -help ?command?\" for help", NULL);
+ Jim_SetResultFormatted(interp, "wrong # args: should be \"%#s command ...\"\n"
+ "Use \"%#s -help ?command?\" for help", argv[0], argv[0]);
return 0;
}
cmd = argv[1];
+ /* Use cached lookup if possible */
+ if (cmd->typePtr == &subcmdLookupObjType) {
+ if (cmd->internalRep.ptrIntValue.ptr == command_table) {
+ ct = command_table + cmd->internalRep.ptrIntValue.int1;
+ goto found;
+ }
+ }
+
/* Check for the help command */
if (Jim_CompareStringImmediate(interp, cmd, "-help")) {
if (argc == 2) {
@@ -164,6 +175,13 @@ const jim_subcmd_type *Jim_ParseSubCmd(Jim_Interp *interp, const jim_subcmd_type
return &dummy_subcmd;
}
+ /* Cache the result for a successful non-help lookup */
+ Jim_FreeIntRep(interp, cmd);
+ cmd->typePtr = &subcmdLookupObjType;
+ cmd->internalRep.ptrIntValue.ptr = (void *)command_table;
+ cmd->internalRep.ptrIntValue.int1 = ct - command_table;
+
+found:
/* Check the number of args */
if (argc - 2 < ct->minargs || (ct->maxargs >= 0 && argc - 2 > ct->maxargs)) {
Jim_SetResultString(interp, "wrong # args: should be \"", -1);