diff options
Diffstat (limited to 'jim-subcmd.c')
-rw-r--r-- | jim-subcmd.c | 44 |
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); |