diff options
author | Steve Bennett <steveb@workware.net.au> | 2023-07-01 12:45:36 +1000 |
---|---|---|
committer | Steve Bennett <steveb@workware.net.au> | 2025-07-16 09:34:08 +1000 |
commit | 5669e84aad22d7f82417af60c3c1c384fe9a4b66 (patch) | |
tree | 8f6b6592d9f6314dff3c9f4317993cf4b3b382ab | |
parent | 3786590cd13b33e84ba585bf8b1802c68f7d1176 (diff) | |
download | jimtcl-5669e84aad22d7f82417af60c3c1c384fe9a4b66.zip jimtcl-5669e84aad22d7f82417af60c3c1c384fe9a4b66.tar.gz jimtcl-5669e84aad22d7f82417af60c3c1c384fe9a4b66.tar.bz2 |
core: Add Jim_RegisterCommand()
and wrappers Jim_RegisterCmd, Jim_RegisterSimpleCmd and Jim_RegisterSubCmd
Allows usage, help and flags when registering commands.
Allows for JIM_CMD_ISPROC, JIM_CMD_ISALIAS, JIM_CMD_ISCHANNEL
'info usage' and (later) 'info help'
Now every command doesn't need to check min/max and print usage.
This also adds support for 'info aliases', 'info channels' and 'exists -channel'.
Signed-off-by: Steve Bennett <steveb@workware.net.au>
-rw-r--r-- | initjimsh.tcl | 19 | ||||
-rw-r--r-- | jim-aio.c | 89 | ||||
-rw-r--r-- | jim-array.c | 2 | ||||
-rw-r--r-- | jim-clock.c | 2 | ||||
-rw-r--r-- | jim-eventloop.c | 19 | ||||
-rw-r--r-- | jim-exec.c | 24 | ||||
-rw-r--r-- | jim-file.c | 20 | ||||
-rw-r--r-- | jim-history.c | 2 | ||||
-rw-r--r-- | jim-interp.c | 11 | ||||
-rw-r--r-- | jim-json.c | 8 | ||||
-rw-r--r-- | jim-load.c | 11 | ||||
-rw-r--r-- | jim-mk.cpp | 5 | ||||
-rw-r--r-- | jim-namespace.c | 9 | ||||
-rw-r--r-- | jim-pack.c | 14 | ||||
-rw-r--r-- | jim-package.c | 2 | ||||
-rw-r--r-- | jim-posix.c | 25 | ||||
-rw-r--r-- | jim-readdir.c | 5 | ||||
-rw-r--r-- | jim-readline.c | 12 | ||||
-rw-r--r-- | jim-redis.c | 7 | ||||
-rw-r--r-- | jim-regexp.c | 26 | ||||
-rw-r--r-- | jim-sdl.c | 7 | ||||
-rw-r--r-- | jim-signal.c | 37 | ||||
-rw-r--r-- | jim-sqlite3.c | 18 | ||||
-rw-r--r-- | jim-subcmd.c | 12 | ||||
-rw-r--r-- | jim-subcmd.h | 10 | ||||
-rw-r--r-- | jim-syslog.c | 11 | ||||
-rw-r--r-- | jim-tclprefix.c | 6 | ||||
-rw-r--r-- | jim-zlib.c | 7 | ||||
-rw-r--r-- | jim.c | 992 | ||||
-rw-r--r-- | jim.h | 39 | ||||
-rw-r--r-- | jim_tcl.txt | 22 | ||||
-rw-r--r-- | tests/clock.test | 2 | ||||
-rw-r--r-- | tests/coverage.test | 2 | ||||
-rw-r--r-- | tests/debug.test | 2 | ||||
-rw-r--r-- | tests/dict2.test | 4 | ||||
-rw-r--r-- | tests/exists.test | 24 | ||||
-rw-r--r-- | tests/history.test | 5 | ||||
-rw-r--r-- | tests/jim.test | 2 | ||||
-rw-r--r-- | tests/loadtest.c | 12 |
39 files changed, 655 insertions, 871 deletions
diff --git a/initjimsh.tcl b/initjimsh.tcl index e632623..2a37ec0 100644 --- a/initjimsh.tcl +++ b/initjimsh.tcl @@ -112,8 +112,8 @@ set tcl::stdhint_col $tcl::stdhint_cols(lcyan) # The default hint implementation proc tcl::stdhint {string} { set result "" + lassign $string cmd arg if {[llength $string] >= 2} { - lassign $string cmd arg if {$cmd in $::tcl::stdhint_commands || [info channel $cmd] ne ""} { catch { set help [$cmd -help $arg] @@ -135,6 +135,23 @@ proc tcl::stdhint {string} { } } } + } else { + catch { + if {[exists -alias $cmd] && [llength [info alias $cmd]] == 1} { + # Look through a simple alias. Doesn't really work for anything more complex. + # consider 'alias p stderr puts' where we can't really provide the usage + # of 'stderr puts' + set help [info usage [info alias $cmd]] + } else { + set help [info usage $cmd] + } + set hint [join [lrange $help 1 end]] + set prefix " " + if {[string match "* " $string]} { + set prefix "" + } + set result [list $prefix$hint {*}$::tcl::stdhint_col] + } } return $result } @@ -93,6 +93,7 @@ #define AIO_EOF 4 /* EOF was reached */ #define AIO_WBUF_NONE 8 /* default to buffering=none */ #define AIO_NONBLOCK 16 /* socket is non-blocking */ +#define AIO_NOTAINT 32 /* Don't set taint on the channel */ #define AIO_ONEREAD 32 /* passed to aio_read_len() to return after a single read */ @@ -961,7 +962,7 @@ static int aio_cmd_read(Jim_Interp *interp, int argc, Jim_Obj *const *argv) argv++; } if (argc) { - return -1; + return JIM_USAGE; } /* reads are nonblocking if a timeout is given */ @@ -1002,7 +1003,7 @@ int Jim_AioFilehandle(Jim_Interp *interp, Jim_Obj *command) Jim_Cmd *cmdPtr = Jim_GetCommand(interp, command, JIM_ERRMSG); /* XXX: There ought to be a supported API for this */ - if (cmdPtr && !cmdPtr->isproc && cmdPtr->u.native.cmdProc == JimAioSubCmdProc) { + if (cmdPtr && !(cmdPtr->flags & JIM_CMD_ISPROC) && cmdPtr->u.native.cmdProc == JimAioSubCmdProc) { return ((AioFile *) cmdPtr->u.native.privData)->fd; } Jim_SetResultFormatted(interp, "Not a filehandle: \"%#s\"", command); @@ -1214,7 +1215,7 @@ static int aio_cmd_puts(Jim_Interp *interp, int argc, Jim_Obj *const *argv) if (argc == 2) { if (!Jim_CompareStringImmediate(interp, argv[0], "-nonewline")) { - return -1; + return JIM_USAGE; } strObj = argv[1]; nl = 0; @@ -1511,7 +1512,7 @@ static int aio_cmd_seek(Jim_Interp *interp, int argc, Jim_Obj *const *argv) else if (Jim_CompareStringImmediate(interp, argv[1], "end")) orig = SEEK_END; else { - return -1; + return JIM_USAGE; } } if (Jim_GetWide(interp, argv[0], &offset) != JIM_OK) { @@ -1675,7 +1676,7 @@ static int aio_cmd_sockopt(Jim_Interp *interp, int argc, Jim_Obj *const *argv) return JIM_OK; } if (argc == 1) { - return -1; + return JIM_USAGE; } /* Set an option */ @@ -2004,7 +2005,7 @@ static int aio_cmd_lock(Jim_Interp *interp, int argc, Jim_Obj *const *argv) if (argc == 1) { if (!Jim_CompareStringImmediate(interp, argv[0], "-wait")) { - return -1; + return JIM_USAGE; } lockmode = F_SETLKW; } @@ -2082,7 +2083,7 @@ static int aio_cmd_tty(Jim_Interp *interp, int argc, Jim_Obj *const *argv) if (Jim_ListLength(interp, dictObjPtr) % 2) { /* Must be a valid dictionary */ Jim_DecrRefCount(interp, dictObjPtr); - return -1; + return JIM_USAGE; } ret = Jim_SetTtySettings(interp, af->fd, dictObjPtr); @@ -2536,20 +2537,21 @@ static int JimAioOpenCommand(Jim_Interp *interp, int argc, const char *filename; int fd = -1; int n = 0; - int flags = 0; + /* filehandles created by open are not tainted by default */ + int flags = AIO_NOTAINT; if (argc > 2 && Jim_CompareStringImmediate(interp, argv[2], "-noclose")) { flags = AIO_KEEPOPEN; n++; } - if (argc < 2 || argc > 3 + n) { - Jim_WrongNumArgs(interp, 1, argv, "filename ?-noclose? ?mode?"); - } if (Jim_CheckTaint(interp, JIM_TAINT_ANY)) { Jim_SetTaintError(interp, 1, argv); return JIM_ERR; } + if (argc > 3 + n) { + return JIM_USAGE; + } filename = Jim_String(argv[1]); @@ -2691,8 +2693,14 @@ static AioFile *JimMakeChannel(Jim_Interp *interp, int fd, Jim_Obj *filename, /* Don't allocate rbuf or readbuf until we need it */ /* By default, all channels are JIM_TAINT_STD for input and output. */ - JimAioSetTaint(af, JIM_TAINT_STD, JIM_TAINT_STD); - Jim_CreateCommand(interp, buf, JimAioSubCmdProc, af, JimAioDelProc); + if (!(flags & AIO_NOTAINT)) { + JimAioSetTaint(af, JIM_TAINT_STD, JIM_TAINT_STD); + } + Jim_RegisterCommand(interp, cmdname, + JimAioSubCmdProc, JimAioDelProc, + NULL, /* usage comes from -help */ + NULL, /* no help */ + 0, -1, JIM_CMD_ISCHANNEL, af); /* Note that the command must use the global namespace, even if * the current namespace is something different @@ -2743,10 +2751,6 @@ static int JimCreatePipe(Jim_Interp *interp, Jim_Obj *filenameObj, int flags) /* Note that if you want -noclose, use "socket -noclose pipe" instead */ static int JimAioPipeCommand(Jim_Interp *interp, int argc, Jim_Obj *const *argv) { - if (argc != 1) { - Jim_WrongNumArgs(interp, 1, argv, ""); - return JIM_ERR; - } return JimCreatePipe(interp, argv[0], 0); } #endif @@ -2757,11 +2761,6 @@ static int JimAioOpenPtyCommand(Jim_Interp *interp, int argc, Jim_Obj *const *ar int p[2]; char path[MAXPATHLEN]; - if (argc != 1) { - Jim_WrongNumArgs(interp, 1, argv, ""); - return JIM_ERR; - } - if (openpty(&p[0], &p[1], path, NULL, NULL) != 0) { JimAioSetError(interp, NULL); return JIM_ERR; @@ -2818,7 +2817,6 @@ static int JimAioSockCommand(Jim_Interp *interp, int argc, Jim_Obj *const *argv) int do_listen = 0; int family = PF_INET; int type = SOCK_STREAM; - Jim_Obj *argv0 = argv[0]; int ipv6 = 0; int async = 0; int flags = 0; @@ -2827,11 +2825,6 @@ static int JimAioSockCommand(Jim_Interp *interp, int argc, Jim_Obj *const *argv) return Jim_CheckShowCommands(interp, argv[1], socktypes); } - if (Jim_CheckTaint(interp, JIM_TAINT_ANY)) { - Jim_SetTaintError(interp, 1, argv); - return JIM_ERR; - } - while (argc > 1 && Jim_String(argv[1])[0] == '-') { static const char * const options[] = { "-async", "-ipv6", "-noclose", NULL }; enum { OPT_ASYNC, OPT_IPV6, OPT_NOCLOSE }; @@ -2864,9 +2857,7 @@ static int JimAioSockCommand(Jim_Interp *interp, int argc, Jim_Obj *const *argv) } if (argc < 2) { - wrongargs: - Jim_WrongNumArgs(interp, 1, &argv0, "?-async? ?-ipv6? socktype ?address?"); - return JIM_ERR; + return JIM_USAGE; } if (Jim_GetEnum(interp, argv[1], socktypes, &socktype, "socktype", JIM_ERRMSG) != JIM_OK) { @@ -2886,7 +2877,7 @@ static int JimAioSockCommand(Jim_Interp *interp, int argc, Jim_Obj *const *argv) int p[2]; if (addr || ipv6) { - goto wrongargs; + return JIM_USAGE; } if (socketpair(PF_UNIX, SOCK_STREAM, 0, p) < 0) { @@ -2901,7 +2892,7 @@ static int JimAioSockCommand(Jim_Interp *interp, int argc, Jim_Obj *const *argv) #if defined(HAVE_PIPE) if (socktype == SOCK_STREAM_PIPE) { if (addr || ipv6) { - goto wrongargs; + return JIM_USAGE; } return JimCreatePipe(interp, argv[1], flags); } @@ -2916,14 +2907,14 @@ static int JimAioSockCommand(Jim_Interp *interp, int argc, Jim_Obj *const *argv) case SOCK_STREAM_CLIENT: if (addr == NULL) { - goto wrongargs; + return JIM_USAGE; } connect_addr = addr; break; case SOCK_STREAM_SERVER: if (addr == NULL) { - goto wrongargs; + return JIM_USAGE; } bind_addr = addr; reuse = 1; @@ -2932,7 +2923,7 @@ static int JimAioSockCommand(Jim_Interp *interp, int argc, Jim_Obj *const *argv) case SOCK_DGRAM_SERVER: if (addr == NULL) { - goto wrongargs; + return JIM_USAGE; } bind_addr = addr; type = SOCK_DGRAM; @@ -2942,7 +2933,7 @@ static int JimAioSockCommand(Jim_Interp *interp, int argc, Jim_Obj *const *argv) #if UNIX_SOCKETS case SOCK_UNIX: if (addr == NULL) { - goto wrongargs; + return JIM_USAGE; } connect_addr = addr; family = PF_UNIX; @@ -2969,7 +2960,7 @@ static int JimAioSockCommand(Jim_Interp *interp, int argc, Jim_Obj *const *argv) case SOCK_UNIX_SERVER: if (addr == NULL) { - goto wrongargs; + return JIM_USAGE; } bind_addr = addr; family = PF_UNIX; @@ -2978,7 +2969,7 @@ static int JimAioSockCommand(Jim_Interp *interp, int argc, Jim_Obj *const *argv) case SOCK_UNIX_DGRAM_SERVER: if (addr == NULL) { - goto wrongargs; + return JIM_USAGE; } bind_addr = addr; type = SOCK_DGRAM; @@ -2988,7 +2979,7 @@ static int JimAioSockCommand(Jim_Interp *interp, int argc, Jim_Obj *const *argv) #ifdef HAVE_OPENPTY case SOCK_STREAM_PTY: if (addr || ipv6) { - goto wrongargs; + return JIM_USAGE; } return JimAioOpenPtyCommand(interp, 1, &argv[1]); #endif @@ -3054,11 +3045,6 @@ static int JimAioLoadSSLCertsCommand(Jim_Interp *interp, int argc, Jim_Obj *cons { SSL_CTX *ssl_ctx; - if (argc != 2) { - Jim_WrongNumArgs(interp, 1, argv, "dir"); - return JIM_ERR; - } - ssl_ctx = JimAioSslCtx(interp); if (!ssl_ctx) { return JIM_ERR; @@ -3081,20 +3067,17 @@ static void JimMakeStdioChannel(Jim_Interp *interp, FILE *fh, const char *name, int Jim_aioInit(Jim_Interp *interp) { - - if (Jim_PackageProvide(interp, "aio", "1.0", JIM_ERRMSG)) - return JIM_ERR; - + Jim_PackageProvideCheck(interp, "aio"); #if defined(JIM_SSL) - Jim_CreateCommand(interp, "load_ssl_certs", JimAioLoadSSLCertsCommand, NULL, NULL); + Jim_RegisterSimpleCmd(interp, "load_ssl_certs", "dir", 1, 1, JimAioLoadSSLCertsCommand); #endif - Jim_CreateCommand(interp, "open", JimAioOpenCommand, NULL, NULL); + Jim_RegisterCmd(interp, "open", "filename ?-noclose? ?mode?", 1, 3, JimAioOpenCommand, NULL, NULL, JIM_CMD_NOTAINT); #ifdef HAVE_SOCKETS - Jim_CreateCommand(interp, "socket", JimAioSockCommand, NULL, NULL); + Jim_RegisterCmd(interp, "socket", "?-async? ?-ipv6? socktype ?address?", 1, 4, JimAioSockCommand, NULL, NULL, JIM_CMD_NOTAINT); #endif #ifdef HAVE_PIPE - Jim_CreateCommand(interp, "pipe", JimAioPipeCommand, NULL, NULL); + Jim_RegisterSimpleCmd(interp, "pipe", "", 0, 0, JimAioPipeCommand); #endif /* Create filehandles for stdin, stdout and stderr */ diff --git a/jim-array.c b/jim-array.c index a21099d..a43d89f 100644 --- a/jim-array.c +++ b/jim-array.c @@ -260,6 +260,6 @@ static const jim_subcmd_type array_command_table[] = { int Jim_arrayInit(Jim_Interp *interp) { Jim_PackageProvideCheck(interp, "array"); - Jim_CreateCommand(interp, "array", Jim_SubCmdProc, (void *)array_command_table, NULL); + Jim_RegisterSubCmd(interp, "array", array_command_table, NULL); return JIM_OK; } diff --git a/jim-clock.c b/jim-clock.c index 866ed58..ac67996 100644 --- a/jim-clock.c +++ b/jim-clock.c @@ -213,6 +213,6 @@ static const jim_subcmd_type clock_command_table[] = { int Jim_clockInit(Jim_Interp *interp) { Jim_PackageProvideCheck(interp, "clock"); - Jim_CreateCommand(interp, "clock", Jim_SubCmdProc, (void *)clock_command_table, NULL); + Jim_RegisterSubCmd(interp, "clock", clock_command_table, NULL); return JIM_OK; } diff --git a/jim-eventloop.c b/jim-eventloop.c index 84cba71..fa5631f 100644 --- a/jim-eventloop.c +++ b/jim-eventloop.c @@ -573,8 +573,7 @@ static int JimELVwaitCommand(Jim_Interp *interp, int argc, Jim_Obj *const *argv) } if (argc - signal != 2) { - Jim_WrongNumArgs(interp, 1, argv, "?-signal? name"); - return JIM_ERR; + return JIM_USAGE; } oldValue = Jim_GetGlobalVariable(interp, argv[1 + signal], JIM_NONE); @@ -640,9 +639,8 @@ static int JimELUpdateCommand(Jim_Interp *interp, int argc, Jim_Obj *const *argv if (argc == 1) { flags = JIM_ALL_EVENTS; } - else if (argc > 2 || Jim_GetEnum(interp, argv[1], options, &option, NULL, JIM_ERRMSG | JIM_ENUM_ABBREV) != JIM_OK) { - Jim_WrongNumArgs(interp, 1, argv, "?idletasks?"); - return JIM_ERR; + else if (argc > 2 || Jim_GetEnum(interp, argv[1], options, &option, NULL, JIM_ENUM_ABBREV) != JIM_OK) { + return JIM_USAGE; } eventLoop->suppress_bgerror = 0; @@ -679,11 +677,6 @@ static int JimELAfterCommand(Jim_Interp *interp, int argc, Jim_Obj *const *argv) enum { AFTER_CANCEL, AFTER_INFO, AFTER_IDLE, AFTER_RESTART, AFTER_EXPIRE, AFTER_CREATE }; int option = AFTER_CREATE; - - if (argc < 2) { - Jim_WrongNumArgs(interp, 1, argv, "option ?arg ...?"); - return JIM_ERR; - } if (Jim_GetDouble(interp, argv[1], &ms) != JIM_OK) { if (Jim_GetEnum(interp, argv[1], options, &option, "argument", JIM_ERRMSG) != JIM_OK) { return JIM_ERR; @@ -792,9 +785,9 @@ int Jim_eventloopInit(Jim_Interp *interp) Jim_SetAssocData(interp, "eventloop", JimELAssocDataDeleProc, eventLoop); - Jim_CreateCommand(interp, "vwait", JimELVwaitCommand, eventLoop, NULL); - Jim_CreateCommand(interp, "update", JimELUpdateCommand, eventLoop, NULL); - Jim_CreateCommand(interp, "after", JimELAfterCommand, eventLoop, NULL); + Jim_RegisterCmd(interp, "vwait", "?-signal? name", 1, 2, JimELVwaitCommand, NULL, eventLoop, 0); + Jim_RegisterCmd(interp, "update", "?idletasks?", 0, 1, JimELUpdateCommand, NULL, eventLoop, 0); + Jim_RegisterCmd(interp, "after", "option ?arg ...?", 1, -1, JimELAfterCommand, NULL, eventLoop, 0); return JIM_OK; } @@ -80,7 +80,7 @@ static int Jim_ExecCmd(Jim_Interp *interp, int argc, Jim_Obj *const *argv) int Jim_execInit(Jim_Interp *interp) { Jim_PackageProvideCheck(interp, "exec"); - Jim_CreateCommand(interp, "exec", Jim_ExecCmd, NULL, NULL); + Jim_RegisterSimpleCmd(interp, "exec", "arg ?arg ...? ?&?", 1, -1, Jim_ExecCoreCmd); return JIM_OK; } #else @@ -333,7 +333,7 @@ static struct WaitInfoTable *JimAllocWaitInfoTable(void) struct WaitInfoTable *table = Jim_Alloc(sizeof(*table)); table->info = NULL; table->size = table->used = 0; - table->refcount = 1; + table->refcount = 0; return table; } @@ -374,11 +374,6 @@ static int Jim_ExecCmd(Jim_Interp *interp, int argc, Jim_Obj *const *argv) Jim_Obj *errStrObj; struct WaitInfoTable *table = Jim_CmdPrivData(interp); - if (Jim_CheckTaint(interp, JIM_TAINT_ANY)) { - Jim_SetTaintError(interp, 1, argv); - return JIM_ERR; - } - /* * See if the command is to be run in the background; if so, create * the command, detach it, and return. @@ -600,8 +595,7 @@ static int Jim_WaitCommand(Jim_Interp *interp, int argc, Jim_Obj *const *argv) nohang = 1; } if (argc != nohang + 2) { - Jim_WrongNumArgs(interp, 1, argv, "?-nohang? ?pid?"); - return JIM_ERR; + return JIM_USAGE; } if (Jim_GetLong(interp, argv[nohang + 1], &pid) != JIM_OK) { return JIM_ERR; @@ -633,11 +627,6 @@ static int Jim_WaitCommand(Jim_Interp *interp, int argc, Jim_Obj *const *argv) static int Jim_PidCommand(Jim_Interp *interp, int argc, Jim_Obj *const *argv) { - if (argc != 1) { - Jim_WrongNumArgs(interp, 1, argv, ""); - return JIM_ERR; - } - Jim_SetResultInt(interp, (jim_wide)getpid()); return JIM_OK; } @@ -1407,10 +1396,11 @@ int Jim_execInit(Jim_Interp *interp) Jim_PackageProvideCheck(interp, "exec"); waitinfo = JimAllocWaitInfoTable(); - Jim_CreateCommand(interp, "exec", Jim_ExecCmd, waitinfo, JimFreeWaitInfoTable); + Jim_RegisterCmd(interp, "exec", "arg ?arg ...? ?&?", 1, -1, Jim_ExecCmd, JimFreeWaitInfoTable, waitinfo, JIM_CMD_NOTAINT); + waitinfo->refcount++; + Jim_RegisterCmd(interp, "wait", "?-nohang? ?pid?", 0, 2, Jim_WaitCommand, JimFreeWaitInfoTable, waitinfo, 0); waitinfo->refcount++; - Jim_CreateCommand(interp, "wait", Jim_WaitCommand, waitinfo, JimFreeWaitInfoTable); - Jim_CreateCommand(interp, "pid", Jim_PidCommand, 0, 0); + Jim_RegisterSimpleCmd(interp, "pid", "", 0, 0, Jim_PidCommand); return JIM_OK; } @@ -1102,19 +1102,7 @@ static const jim_subcmd_type file_command_table[] = { static int Jim_CdCmd(Jim_Interp *interp, int argc, Jim_Obj *const *argv) { - const char *path; - - if (Jim_CheckTaint(interp, JIM_TAINT_ANY)) { - Jim_SetTaintError(interp, 1, argv); - return JIM_ERR; - } - - if (argc != 2) { - Jim_WrongNumArgs(interp, 1, argv, "dirname"); - return JIM_ERR; - } - - path = Jim_String(argv[1]); + const char *path = Jim_String(argv[1]); if (chdir(path) != 0) { Jim_SetResultFormatted(interp, "couldn't change working directory to \"%s\": %s", path, @@ -1143,8 +1131,8 @@ static int Jim_PwdCmd(Jim_Interp *interp, int argc, Jim_Obj *const *argv) int Jim_fileInit(Jim_Interp *interp) { Jim_PackageProvideCheck(interp, "file"); - Jim_CreateCommand(interp, "file", Jim_SubCmdProc, (void *)file_command_table, NULL); - Jim_CreateCommand(interp, "pwd", Jim_PwdCmd, NULL, NULL); - Jim_CreateCommand(interp, "cd", Jim_CdCmd, NULL, NULL); + Jim_RegisterSubCmd(interp, "file", file_command_table, NULL); + Jim_RegisterSimpleCmd(interp, "pwd", "", 0, 0, Jim_PwdCmd); + Jim_RegisterCmd(interp, "cd", "dirname", 1, 1, Jim_CdCmd, NULL, NULL, JIM_CMD_NOTAINT); return JIM_OK; } diff --git a/jim-history.c b/jim-history.c index 076fd0b..c43bdca 100644 --- a/jim-history.c +++ b/jim-history.c @@ -149,6 +149,6 @@ static const jim_subcmd_type history_command_table[] = { int Jim_historyInit(Jim_Interp *interp) { Jim_PackageProvideCheck(interp, "history"); - Jim_CreateCommand(interp, "history", Jim_SubCmdProc, (void *)history_command_table, NULL); + Jim_RegisterSubCmd(interp, "history", history_command_table, NULL); return JIM_OK; } diff --git a/jim-interp.c b/jim-interp.c index 8868076..c545356 100644 --- a/jim-interp.c +++ b/jim-interp.c @@ -88,7 +88,7 @@ static int interp_cmd_alias(Jim_Interp *interp, int argc, Jim_Obj *const *argv) aliasPrefixList = Jim_NewListObj(interp, argv + 1, argc - 1); Jim_IncrRefCount(aliasPrefixList); - Jim_CreateCommand(child, Jim_String(argv[0]), JimInterpAliasProc, aliasPrefixList, JimInterpDelAlias); + Jim_RegisterCmd(child, Jim_String(argv[0]), NULL, 0, -1, JimInterpAliasProc, JimInterpDelAlias, aliasPrefixList, 0); return JIM_OK; } @@ -146,11 +146,6 @@ static int JimInterpCommand(Jim_Interp *interp, int argc, Jim_Obj *const *argv) "argv", "argc", "argv0", "jim::argv0", "jim::exe", "jim::lineedit", NULL }; - if (argc != 1) { - Jim_WrongNumArgs(interp, 1, argv, ""); - return JIM_ERR; - } - /* Create the interpreter command */ child = Jim_CreateInterp(); Jim_RegisterCoreCommands(child); @@ -165,7 +160,7 @@ static int JimInterpCommand(Jim_Interp *interp, int argc, Jim_Obj *const *argv) Jim_SetAssocData(child, "interp.parent", NULL, interp); snprintf(buf, sizeof(buf), "interp.handle%ld", Jim_GetId(interp)); - Jim_CreateCommand(interp, buf, JimInterpSubCmdProc, child, JimInterpDelProc); + Jim_RegisterCmd(interp, buf, "subcommand ?arg ...?", 1, -1, JimInterpSubCmdProc, JimInterpDelProc, child, 0); Jim_SetResult(interp, Jim_MakeGlobalNamespaceName(interp, Jim_NewStringObj(interp, buf, -1))); return JIM_OK; } @@ -173,7 +168,7 @@ static int JimInterpCommand(Jim_Interp *interp, int argc, Jim_Obj *const *argv) int Jim_interpInit(Jim_Interp *interp) { Jim_PackageProvideCheck(interp, "interp"); - Jim_CreateCommand(interp, "interp", JimInterpCommand, NULL, NULL); + Jim_RegisterSimpleCmd(interp, "interp", "", 0, 0, JimInterpCommand); return JIM_OK; } @@ -289,9 +289,7 @@ static int parse_json_decode_options(Jim_Interp *interp, int argc, Jim_Obj *cons } if (i != argc - 1) { - Jim_WrongNumArgs(interp, 1, argv, - "?-index? ?-null nullvalue? ?-schema? json"); - return JIM_ERR; + return JIM_USAGE; } return JIM_OK; @@ -369,7 +367,7 @@ json_decode(Jim_Interp *interp, int argc, Jim_Obj *const argv[]) state.nullObj = Jim_NewStringObj(interp, "null", -1); Jim_IncrRefCount(state.nullObj); - if (parse_json_decode_options(interp, argc, argv, &state) != JIM_OK) { + if ((ret = parse_json_decode_options(interp, argc, argv, &state)) != JIM_OK) { goto done; } @@ -431,7 +429,7 @@ int Jim_jsonInit(Jim_Interp *interp) { Jim_PackageProvideCheck(interp, "json"); - Jim_CreateCommand(interp, "json::decode", json_decode, NULL, NULL); + Jim_RegisterSimpleCmd(interp, "json::decode", "?-index? ?-null nullvalue? ?-schema? json", 1, 5, json_decode); /* Load the Tcl implementation of the json encoder if possible */ Jim_PackageRequire(interp, "jsonencode", 0); return JIM_OK; @@ -119,20 +119,11 @@ void Jim_FreeLoadHandles(Jim_Interp *interp) /* [load] */ static int Jim_LoadCoreCommand(Jim_Interp *interp, int argc, Jim_Obj *const *argv) { - if (Jim_CheckTaint(interp, JIM_TAINT_ANY)) { - Jim_SetTaintError(interp, 1, argv); - return JIM_ERR; - } - - if (argc < 2) { - Jim_WrongNumArgs(interp, 1, argv, "libraryFile"); - return JIM_ERR; - } return Jim_LoadLibrary(interp, Jim_String(argv[1])); } int Jim_loadInit(Jim_Interp *interp) { - Jim_CreateCommand(interp, "load", Jim_LoadCoreCommand, NULL, NULL); + Jim_RegisterCmd(interp, "load", "libraryFile", 1, 1, Jim_LoadCoreCommand, NULL, NULL, JIM_CMD_NOTAINT); return JIM_OK; } @@ -2258,14 +2258,13 @@ int Jim_mkInit(Jim_Interp *interp) { char version[MK_VERSION_SPACE]; + Jim_PackageProvideCheck(interp, "mk"); + snprintf(version, MK_VERSION_SPACE, "%d.%d.%d", d4_MetakitLibraryVersion / 100, d4_MetakitLibraryVersion % 100 / 10, d4_MetakitLibraryVersion % 10); - if (Jim_PackageProvide(interp, "mk", version, JIM_ERRMSG)) - return JIM_ERR; - Jim_CreateCommand(interp, "storage", JimStorageCommand, NULL, NULL); Jim_CreateCommand(interp, "cursor", JimCursorCommand, NULL, NULL); Jim_CreateCommand(interp, "mk.view.finalizer", JimViewFinalizerProc, NULL, NULL); diff --git a/jim-namespace.c b/jim-namespace.c index d1a02f5..c6e61b0 100644 --- a/jim-namespace.c +++ b/jim-namespace.c @@ -156,10 +156,6 @@ static int JimVariableCmd(Jim_Interp *interp, int argc, Jim_Obj *const *argv) { int retcode = JIM_OK; - if (argc > 3) { - Jim_WrongNumArgs(interp, 1, argv, "name ?value?"); - return JIM_ERR; - } if (argc > 1) { Jim_Obj *targetNameObj; Jim_Obj *localNameObj; @@ -334,8 +330,7 @@ static int JimNamespaceCmd(Jim_Interp *interp, int argc, Jim_Obj *const *argv) int Jim_namespaceInit(Jim_Interp *interp) { Jim_PackageProvideCheck(interp, "namespace"); - Jim_CreateCommand(interp, "namespace", JimNamespaceCmd, NULL, NULL); - Jim_CreateCommand(interp, "variable", JimVariableCmd, NULL, NULL); + Jim_RegisterSimpleCmd(interp, "namespace", "subcommand ?arg ...?", 1, -1, JimNamespaceCmd); + Jim_RegisterSimpleCmd(interp, "variable", "name ?value?", 1, 2, JimVariableCmd); return JIM_OK; } - @@ -281,11 +281,6 @@ static int Jim_UnpackCmd(Jim_Interp *interp, int argc, Jim_Obj *const *argv) jim_wide pos; jim_wide width; - if (argc != 5) { - Jim_WrongNumArgs(interp, 1, argv, - "binvalue -intbe|-intle|-uintbe|-uintle|-floatbe|-floatle|-str bitpos bitwidth"); - return JIM_ERR; - } if (Jim_GetEnum(interp, argv[2], options, &option, NULL, JIM_ERRMSG) != JIM_OK) { return JIM_ERR; } @@ -378,11 +373,6 @@ static int Jim_PackCmd(Jim_Interp *interp, int argc, Jim_Obj *const *argv) int len; int freeobj = 0; - if (argc != 5 && argc != 6) { - Jim_WrongNumArgs(interp, 1, argv, - "varName value -intle|-intbe|-floatle|-floatbe|-str bitwidth ?bitoffset?"); - return JIM_ERR; - } if (Jim_GetEnum(interp, argv[3], options, &option, NULL, JIM_ERRMSG) != JIM_OK) { return JIM_ERR; } @@ -476,7 +466,7 @@ static int Jim_PackCmd(Jim_Interp *interp, int argc, Jim_Obj *const *argv) int Jim_packInit(Jim_Interp *interp) { Jim_PackageProvideCheck(interp, "pack"); - Jim_CreateCommand(interp, "unpack", Jim_UnpackCmd, NULL, NULL); - Jim_CreateCommand(interp, "pack", Jim_PackCmd, NULL, NULL); + Jim_RegisterSimpleCmd(interp, "pack", "varName value -intle|-intbe|-floatle|-floatbe|-str bitwidth ?bitoffset?", 4, 5, Jim_PackCmd); + Jim_RegisterSimpleCmd(interp, "unpack", "binvalue -intbe|-intle|-uintbe|-uintle|-floatbe|-floatle|-str bitpos bitwidth", 4, 4, Jim_UnpackCmd); return JIM_OK; } diff --git a/jim-package.c b/jim-package.c index 7471e80..925b9b9 100644 --- a/jim-package.c +++ b/jim-package.c @@ -277,6 +277,6 @@ static const jim_subcmd_type package_command_table[] = { int Jim_packageInit(Jim_Interp *interp) { - Jim_CreateCommand(interp, "package", Jim_SubCmdProc, (void *)package_command_table, NULL); + Jim_RegisterSubCmd(interp, "package", package_command_table, NULL); return JIM_OK; } diff --git a/jim-posix.c b/jim-posix.c index 5a6fb98..3a04fdf 100644 --- a/jim-posix.c +++ b/jim-posix.c @@ -58,10 +58,6 @@ static int Jim_PosixForkCommand(Jim_Interp *interp, int argc, Jim_Obj *const *ar JIM_NOTUSED(argv); - if (argc != 1) { - Jim_WrongNumArgs(interp, 1, argv, ""); - return JIM_ERR; - } if ((pid = fork()) == -1) { Jim_PosixSetError(interp); return JIM_ERR; @@ -76,10 +72,6 @@ static int Jim_PosixGetidsCommand(Jim_Interp *interp, int argc, Jim_Obj *const * { Jim_Obj *objv[8]; - if (argc != 1) { - Jim_WrongNumArgs(interp, 1, argv, ""); - return JIM_ERR; - } objv[0] = Jim_NewStringObj(interp, "uid", -1); objv[1] = Jim_NewIntObj(interp, getuid()); objv[2] = Jim_NewStringObj(interp, "euid", -1); @@ -98,10 +90,6 @@ static int Jim_PosixGethostnameCommand(Jim_Interp *interp, int argc, Jim_Obj *co char *buf; int rc = JIM_OK; - if (argc != 1) { - Jim_WrongNumArgs(interp, 1, argv, ""); - return JIM_ERR; - } buf = Jim_Alloc(JIM_HOST_NAME_MAX); if (gethostname(buf, JIM_HOST_NAME_MAX) == -1) { Jim_PosixSetError(interp); @@ -119,11 +107,6 @@ static int Jim_PosixUptimeCommand(Jim_Interp *interp, int argc, Jim_Obj *const * #ifdef HAVE_STRUCT_SYSINFO_UPTIME struct sysinfo info; - if (argc != 1) { - Jim_WrongNumArgs(interp, 1, argv, ""); - return JIM_ERR; - } - if (sysinfo(&info) == -1) { Jim_PosixSetError(interp); return JIM_ERR; @@ -141,12 +124,12 @@ int Jim_posixInit(Jim_Interp *interp) { Jim_PackageProvideCheck(interp, "posix"); #ifdef HAVE_FORK - Jim_CreateCommand(interp, "os.fork", Jim_PosixForkCommand, NULL, NULL); + Jim_RegisterSimpleCmd(interp, "os.fork", "", 0, 0, Jim_PosixForkCommand); #endif #if !defined(JIM_BOOTSTRAP) - Jim_CreateCommand(interp, "os.getids", Jim_PosixGetidsCommand, NULL, NULL); - Jim_CreateCommand(interp, "os.gethostname", Jim_PosixGethostnameCommand, NULL, NULL); - Jim_CreateCommand(interp, "os.uptime", Jim_PosixUptimeCommand, NULL, NULL); + Jim_RegisterSimpleCmd(interp, "os.gethostname", "", 0, 0, Jim_PosixGethostnameCommand); + Jim_RegisterSimpleCmd(interp, "os.getids", "", 0, 0, Jim_PosixGetidsCommand); + Jim_RegisterSimpleCmd(interp, "os.uptime", "", 0, 0, Jim_PosixUptimeCommand); #endif /* JIM_BOOTSTRAP */ return JIM_OK; } diff --git a/jim-readdir.c b/jim-readdir.c index 07c558e..3823fb7 100644 --- a/jim-readdir.c +++ b/jim-readdir.c @@ -77,8 +77,7 @@ int Jim_ReaddirCmd(Jim_Interp *interp, int argc, Jim_Obj *const *argv) nocomplain = 1; } if (argc != 2 && !nocomplain) { - Jim_WrongNumArgs(interp, 1, argv, "?-nocomplain? dirPath"); - return JIM_ERR; + return JIM_USAGE; } dirPath = Jim_String(argv[1 + nocomplain]); @@ -115,6 +114,6 @@ int Jim_ReaddirCmd(Jim_Interp *interp, int argc, Jim_Obj *const *argv) int Jim_readdirInit(Jim_Interp *interp) { Jim_PackageProvideCheck(interp, "readdir"); - Jim_CreateCommand(interp, "readdir", Jim_ReaddirCmd, NULL, NULL); + Jim_RegisterSimpleCmd(interp, "readdir", "?-nocomplain? dirPath", 1, 2, Jim_ReaddirCmd); return JIM_OK; } diff --git a/jim-readline.c b/jim-readline.c index c83e649..9acef8d 100644 --- a/jim-readline.c +++ b/jim-readline.c @@ -43,10 +43,6 @@ static int JimRlReadlineCommand(Jim_Interp *interp, int argc, Jim_Obj *const *ar { char *line; - if (argc != 2) { - Jim_WrongNumArgs(interp, 1, argv, "prompt"); - return JIM_ERR; - } line = readline(Jim_String(argv[1])); if (!line) { return JIM_EXIT; @@ -57,10 +53,6 @@ static int JimRlReadlineCommand(Jim_Interp *interp, int argc, Jim_Obj *const *ar static int JimRlAddHistoryCommand(Jim_Interp *interp, int argc, Jim_Obj *const *argv) { - if (argc != 2) { - Jim_WrongNumArgs(interp, 1, argv, "string"); - return JIM_ERR; - } add_history(Jim_String(argv[1])); return JIM_OK; } @@ -68,7 +60,7 @@ static int JimRlAddHistoryCommand(Jim_Interp *interp, int argc, Jim_Obj *const * int Jim_readlineInit(Jim_Interp *interp) { Jim_PackageProvideCheck(interp, "readline"); - Jim_CreateCommand(interp, "readline.readline", JimRlReadlineCommand, NULL, NULL); - Jim_CreateCommand(interp, "readline.addhistory", JimRlAddHistoryCommand, NULL, NULL); + Jim_RegisterSimpleCmd(interp, "readline.readline", "prompt", 1, 1, JimRlReadlineCommand); + Jim_RegisterSimpleCmd(interp, "readline.addhistory", "string", 1, 1, JimRlAddHistoryCommand); return JIM_OK; } diff --git a/jim-redis.c b/jim-redis.c index fb16b13..6628aa5 100644 --- a/jim-redis.c +++ b/jim-redis.c @@ -201,8 +201,7 @@ static int jim_redis_cmd(Jim_Interp *interp, int argc, Jim_Obj *const *argv) async = 1; } if (argc - async != 2) { - Jim_WrongNumArgs(interp, 1, argv, "?-async? socket-stream"); - return JIM_ERR; + return JIM_USAGE; } /* Invoke getfd to get the file descriptor */ @@ -229,7 +228,7 @@ static int jim_redis_cmd(Jim_Interp *interp, int argc, Jim_Obj *const *argv) /* Now delete the original stream */ Jim_DeleteCommand(interp, argv[1 + async]); snprintf(buf, sizeof(buf), "redis.handle%ld", Jim_GetId(interp)); - Jim_CreateCommand(interp, buf, jim_redis_subcmd, c, jim_redis_del_proc); + Jim_RegisterCmd(interp, buf, "subcommand ?arg ...?", 1, -1, jim_redis_subcmd, jim_redis_del_proc, c, 0); Jim_SetResult(interp, Jim_MakeGlobalNamespaceName(interp, Jim_NewStringObj(interp, buf, -1))); @@ -240,6 +239,6 @@ int Jim_redisInit(Jim_Interp *interp) { Jim_PackageProvideCheck(interp, "redis"); - Jim_CreateCommand(interp, "redis", jim_redis_cmd, NULL, NULL); + Jim_RegisterSimpleCmd(interp, "redis", "?-async? socket-stream", 1, 2, jim_redis_cmd); return JIM_OK; } diff --git a/jim-regexp.c b/jim-regexp.c index f370e5e..8516c80 100644 --- a/jim-regexp.c +++ b/jim-regexp.c @@ -143,13 +143,6 @@ int Jim_RegexpCmd(Jim_Interp *interp, int argc, Jim_Obj *const *argv) "-indices", "-nocase", "-line", "-all", "-inline", "-start", "--", NULL }; - if (argc < 3) { - wrongNumArgs: - Jim_WrongNumArgs(interp, 1, argv, - "?-switch ...? exp string ?matchVar? ?subMatchVar ...?"); - return JIM_ERR; - } - for (i = 1; i < argc; i++) { const char *opt = Jim_String(argv[i]); @@ -186,7 +179,7 @@ int Jim_RegexpCmd(Jim_Interp *interp, int argc, Jim_Obj *const *argv) case OPT_START: if (++i == argc) { - goto wrongNumArgs; + return JIM_USAGE; } if (Jim_GetIndex(interp, argv[i], &offset) != JIM_OK) { return JIM_ERR; @@ -195,7 +188,7 @@ int Jim_RegexpCmd(Jim_Interp *interp, int argc, Jim_Obj *const *argv) } } if (argc - i < 2) { - goto wrongNumArgs; + return JIM_USAGE; } regex = SetRegexpFromAny(interp, argv[i], regcomp_flags); @@ -374,13 +367,6 @@ int Jim_RegsubCmd(Jim_Interp *interp, int argc, Jim_Obj *const *argv) "-nocase", "-line", "-all", "-start", "-command", "--", NULL }; - if (argc < 4) { - wrongNumArgs: - Jim_WrongNumArgs(interp, 1, argv, - "?-switch ...? exp string subSpec ?varName?"); - return JIM_ERR; - } - for (i = 1; i < argc; i++) { const char *opt = Jim_String(argv[i]); @@ -409,7 +395,7 @@ int Jim_RegsubCmd(Jim_Interp *interp, int argc, Jim_Obj *const *argv) case OPT_START: if (++i == argc) { - goto wrongNumArgs; + return JIM_USAGE; } if (Jim_GetIndex(interp, argv[i], &offset) != JIM_OK) { return JIM_ERR; @@ -422,7 +408,7 @@ int Jim_RegsubCmd(Jim_Interp *interp, int argc, Jim_Obj *const *argv) } } if (argc - i != 3 && argc - i != 4) { - goto wrongNumArgs; + return JIM_USAGE; } /* Need to ensure that this is unshared, so just duplicate it always */ @@ -639,7 +625,7 @@ cmd_error: int Jim_regexpInit(Jim_Interp *interp) { Jim_PackageProvideCheck(interp, "regexp"); - Jim_CreateCommand(interp, "regexp", Jim_RegexpCmd, NULL, NULL); - Jim_CreateCommand(interp, "regsub", Jim_RegsubCmd, NULL, NULL); + Jim_RegisterSimpleCmd(interp, "regexp", "?-switch ...? exp string ?matchVar? ?subMatchVar ...?", 2, -1, Jim_RegexpCmd); + Jim_RegisterSimpleCmd(interp, "regsub", "?-switch ...? exp string subSpec ?varName?", 3, -1, Jim_RegsubCmd); return JIM_OK; } @@ -471,11 +471,6 @@ static int JimSdlSurfaceCommand(Jim_Interp *interp, int argc, Jim_Obj *const *ar long vals[2]; const char *title; - if (argc != 3 && argc != 4) { - Jim_WrongNumArgs(interp, 1, argv, "xres yres ?title?"); - return JIM_ERR; - } - if (JimSdlGetLongs(interp, 2, argv + 1, vals) != JIM_OK) { return JIM_ERR; } @@ -536,6 +531,6 @@ static int JimSdlSurfaceCommand(Jim_Interp *interp, int argc, Jim_Obj *const *ar int Jim_sdlInit(Jim_Interp *interp) { Jim_PackageProvideCheck(interp, "sdl"); - Jim_CreateCommand(interp, "sdl.screen", JimSdlSurfaceCommand, NULL, NULL); + Jim_RegisterSimpleCmd(interp, "sdl.screen", "xres yres ?title?", 2, 3, JimSdlSurfaceCommand); return JIM_OK; } diff --git a/jim-signal.c b/jim-signal.c index 328a139..88862da 100644 --- a/jim-signal.c +++ b/jim-signal.c @@ -440,11 +440,7 @@ static int Jim_AlarmCmd(Jim_Interp *interp, int argc, Jim_Obj *const *argv) { int ret; - if (argc != 2) { - Jim_WrongNumArgs(interp, 1, argv, "seconds"); - return JIM_ERR; - } - else { + { #ifdef HAVE_UALARM double t; @@ -473,21 +469,14 @@ static int Jim_AlarmCmd(Jim_Interp *interp, int argc, Jim_Obj *const *argv) static int Jim_SleepCmd(Jim_Interp *interp, int argc, Jim_Obj *const *argv) { int ret; + double t; - if (argc != 2) { - Jim_WrongNumArgs(interp, 1, argv, "seconds"); - return JIM_ERR; - } - else { - double t; - - ret = Jim_GetDouble(interp, argv[1], &t); - if (ret == JIM_OK) { + ret = Jim_GetDouble(interp, argv[1], &t); + if (ret == JIM_OK) { #ifdef HAVE_USLEEP - usleep((int)((t - (int)t) * 1e6)); + usleep((int)((t - (int)t) * 1e6)); #endif - sleep(t); - } + sleep(t); } return ret; @@ -500,11 +489,6 @@ static int Jim_KillCmd(Jim_Interp *interp, int argc, Jim_Obj *const *argv) Jim_Obj *pidObj; const char *signame; - if (argc != 2 && argc != 3) { - Jim_WrongNumArgs(interp, 1, argv, "?SIG|-0? pid"); - return JIM_ERR; - } - if (argc == 2) { sig = SIGTERM; pidObj = argv[1]; @@ -540,10 +524,10 @@ static int Jim_KillCmd(Jim_Interp *interp, int argc, Jim_Obj *const *argv) int Jim_signalInit(Jim_Interp *interp) { Jim_PackageProvideCheck(interp, "signal"); - Jim_CreateCommand(interp, "alarm", Jim_AlarmCmd, 0, 0); - Jim_CreateCommand(interp, "kill", Jim_KillCmd, 0, 0); + Jim_RegisterSimpleCmd(interp, "alarm", "seconds", 1, 1, Jim_AlarmCmd); + Jim_RegisterSimpleCmd(interp, "kill", "?SIG|-0? pid", 1, 2, Jim_KillCmd); /* Sleep is slightly dubious here */ - Jim_CreateCommand(interp, "sleep", Jim_SleepCmd, 0, 0); + Jim_RegisterSimpleCmd(interp, "sleep", "seconds", 1, 1, Jim_SleepCmd); /* Teach the jim core how to set a result from a sigmask */ interp->signal_set_result = signal_set_sigmask_result; @@ -554,8 +538,7 @@ int Jim_signalInit(Jim_Interp *interp) /* Make sure we know where to store the signals which occur */ sigloc = &interp->sigmask; - - Jim_CreateCommand(interp, "signal", Jim_SubCmdProc, (void *)signal_command_table, JimSignalCmdDelete); + Jim_RegisterSubCmd(interp, "signal", signal_command_table, JimSignalCmdDelete); } return JIM_OK; diff --git a/jim-sqlite3.c b/jim-sqlite3.c index dbb3d4f..0633ec9 100644 --- a/jim-sqlite3.c +++ b/jim-sqlite3.c @@ -148,10 +148,6 @@ static int JimSqliteHandlerCommand(Jim_Interp *interp, int argc, Jim_Obj *const enum { OPT_CLOSE, OPT_QUERY, OPT_LASTID, OPT_CHANGES }; - if (argc < 2) { - Jim_WrongNumArgs(interp, 1, argv, "method ?args ...?"); - return JIM_ERR; - } if (Jim_GetEnum(interp, argv[1], options, &option, "Sqlite method", JIM_ERRMSG) != JIM_OK) return JIM_ERR; /* CLOSE */ @@ -270,16 +266,6 @@ static int JimSqliteOpenCommand(Jim_Interp *interp, int argc, Jim_Obj *const *ar char buf[60]; int r; - if (argc != 2) { - Jim_WrongNumArgs(interp, 1, argv, "dbname"); - return JIM_ERR; - } - - if (Jim_CheckTaint(interp, JIM_TAINT_ANY)) { - Jim_SetTaintError(interp, 1, argv); - return JIM_ERR; - } - r = sqlite3_open(Jim_String(argv[1]), &db); if (r != SQLITE_OK) { Jim_SetResultString(interp, sqlite3_errmsg(db), -1); @@ -288,7 +274,7 @@ static int JimSqliteOpenCommand(Jim_Interp *interp, int argc, Jim_Obj *const *ar } /* Create the file command */ snprintf(buf, sizeof(buf), "sqlite.handle%ld", Jim_GetId(interp)); - Jim_CreateCommand(interp, buf, JimSqliteHandlerCommand, db, JimSqliteDelProc); + Jim_RegisterCmd(interp, buf, "subcommand ?arg ...?", 1, -1, JimSqliteHandlerCommand, JimSqliteDelProc, db, 0); Jim_SetResult(interp, Jim_MakeGlobalNamespaceName(interp, Jim_NewStringObj(interp, buf, -1))); @@ -298,6 +284,6 @@ static int JimSqliteOpenCommand(Jim_Interp *interp, int argc, Jim_Obj *const *ar int Jim_sqlite3Init(Jim_Interp *interp) { Jim_PackageProvideCheck(interp, "sqlite3"); - Jim_CreateCommand(interp, "sqlite3.open", JimSqliteOpenCommand, NULL, NULL); + Jim_RegisterCmd(interp, "sqlite3.open", "dbname", 1, 1, JimSqliteOpenCommand, NULL, NULL, JIM_CMD_NOTAINT); return JIM_OK; } diff --git a/jim-subcmd.c b/jim-subcmd.c index 9ca89a7..75a9168 100644 --- a/jim-subcmd.c +++ b/jim-subcmd.c @@ -259,3 +259,15 @@ int Jim_SubCmdProc(Jim_Interp *interp, int argc, Jim_Obj *const *argv) return Jim_CallSubCmd(interp, ct, argc, argv); } + +Jim_Cmd *Jim_RegisterSubCmd(Jim_Interp *interp, const char *cmdname, + const jim_subcmd_type *command_table, Jim_DelCmdProc *delProc) +{ + return Jim_RegisterCmd(interp, cmdname, + "subcommand ?arg ...?", + 1, -1, + Jim_SubCmdProc, + delProc, + (void *)command_table, + 0); +} diff --git a/jim-subcmd.h b/jim-subcmd.h index a88a2f0..4b39b17 100644 --- a/jim-subcmd.h +++ b/jim-subcmd.h @@ -62,9 +62,9 @@ Jim_ParseSubCmd(Jim_Interp *interp, const jim_subcmd_type *command_table, int ar * Parses the args against the given command table and executes the subcommand if found * or sets an appropriate error if the subcommand or arguments is invalid. * - * Can be used directly with Jim_CreateCommand() where the ClientData is the command table. + * Typically used via Jim_RegisterCmd() * - * e.g. Jim_CreateCommand(interp, "mycmd", Jim_SubCmdProc, command_table, NULL); + * e.g. Jim_RegisterSubCmd(interp, "mycmd", command_table, NULL); */ int Jim_SubCmdProc(Jim_Interp *interp, int argc, Jim_Obj *const *argv); @@ -87,6 +87,12 @@ int Jim_CallSubCmd(Jim_Interp *interp, const jim_subcmd_type *ct, int argc, Jim_ */ void Jim_SubCmdArgError(Jim_Interp *interp, const jim_subcmd_type *ct, Jim_Obj *subcmd); +/** + * Convenience wrapper around Jim_RegisterCmd() to register a subcmd command. + */ +Jim_Cmd *Jim_RegisterSubCmd(Jim_Interp *interp, const char *cmdname, + const jim_subcmd_type *command_table, Jim_DelCmdProc *delProc); + #ifdef __cplusplus } #endif diff --git a/jim-syslog.c b/jim-syslog.c index ad8af59..42c9992 100644 --- a/jim-syslog.c +++ b/jim-syslog.c @@ -79,12 +79,6 @@ int Jim_SyslogCmd(Jim_Interp *interp, int argc, Jim_Obj *const *argv) int i = 1; SyslogInfo *info = Jim_CmdPrivData(interp); - if (argc <= 1) { - wrongargs: - Jim_WrongNumArgs(interp, 1, argv, - "?-facility cron|daemon|...? ?-ident string? ?-options int? ?debug|info|...? message"); - return JIM_ERR; - } while (i < argc - 1) { if (Jim_CompareStringImmediate(interp, argv[i], "-facility")) { int entry = @@ -146,7 +140,7 @@ int Jim_SyslogCmd(Jim_Interp *interp, int argc, Jim_Obj *const *argv) } if (i != argc - 1) { - goto wrongargs; + return JIM_USAGE; } if (!info->logOpened) { if (!info->ident[0]) { @@ -181,7 +175,8 @@ int Jim_syslogInit(Jim_Interp *interp) info->facility = LOG_USER; info->ident[0] = 0; - Jim_CreateCommand(interp, "syslog", Jim_SyslogCmd, info, Jim_SyslogCmdDelete); + Jim_RegisterCmd(interp, "syslog", "?-facility cron|daemon|...? ?-ident string? ?-options int? ?debug|info|...? message", + 1, -1, Jim_SyslogCmd, Jim_SyslogCmdDelete, info, 0); return JIM_OK; } diff --git a/jim-tclprefix.c b/jim-tclprefix.c index c451119..22c6904 100644 --- a/jim-tclprefix.c +++ b/jim-tclprefix.c @@ -64,10 +64,6 @@ static int Jim_TclPrefixCoreCommand(Jim_Interp *interp, int argc, Jim_Obj *const static const char * const options[] = { "match", "all", "longest", NULL }; enum { OPT_MATCH, OPT_ALL, OPT_LONGEST }; - if (argc < 2) { - Jim_WrongNumArgs(interp, 1, argv, "subcommand ?arg ...?"); - return JIM_ERR; - } if (Jim_GetEnum(interp, argv[1], options, &option, NULL, JIM_ERRMSG | JIM_ENUM_ABBREV) != JIM_OK) return Jim_CheckShowCommands(interp, argv[1], options); @@ -215,6 +211,6 @@ static int Jim_TclPrefixCoreCommand(Jim_Interp *interp, int argc, Jim_Obj *const int Jim_tclprefixInit(Jim_Interp *interp) { Jim_PackageProvideCheck(interp, "tclprefix"); - Jim_CreateCommand(interp, "tcl::prefix", Jim_TclPrefixCoreCommand, NULL, NULL); + Jim_RegisterSimpleCmd(interp, "tcl::prefix", "subcommand ?arg ...?", 1, -1, Jim_TclPrefixCoreCommand); return JIM_OK; } @@ -302,15 +302,10 @@ static const jim_subcmd_type zlib_command_table[] = { { NULL } }; -static int JimZlibCmd(Jim_Interp *interp, int argc, Jim_Obj *const *argv) -{ - return Jim_CallSubCmd(interp, Jim_ParseSubCmd(interp, zlib_command_table, argc, argv), argc, argv); -} - int Jim_zlibInit(Jim_Interp *interp) { Jim_PackageProvideCheck(interp, "zlib"); - Jim_CreateCommand(interp, "zlib", JimZlibCmd, 0, 0); + Jim_RegisterSubCmd(interp, "zlib", zlib_command_table, NULL); return JIM_OK; } @@ -156,6 +156,7 @@ static void JimRandomBytes(Jim_Interp *interp, void *dest, unsigned int len); static int JimSetNewVariable(Jim_HashTable *ht, Jim_Obj *nameObjPtr, Jim_VarVal *vv); static Jim_VarVal *JimFindVariable(Jim_HashTable *ht, Jim_Obj *nameObjPtr); static int SetVariableFromAny(Jim_Interp *interp, struct Jim_Obj *objPtr); +static int JimCallNative(Jim_Interp *interp, Jim_Cmd *cmd, int argc, Jim_Obj *const *argv); #define JIM_DICT_SUGAR 100 /* Only returned by SetVariableFromAny() */ @@ -3836,7 +3837,7 @@ static void JimIncrCmdRefCount(Jim_Cmd *cmdPtr) static void JimDecrCmdRefCount(Jim_Interp *interp, Jim_Cmd *cmdPtr) { if (--cmdPtr->inUse == 0) { - if (cmdPtr->isproc) { + if (cmdPtr->flags & JIM_CMD_ISPROC) { Jim_DecrRefCount(interp, cmdPtr->u.proc.argListObjPtr); Jim_DecrRefCount(interp, cmdPtr->u.proc.bodyObjPtr); Jim_DecrRefCount(interp, cmdPtr->u.proc.nsObj); @@ -4105,30 +4106,48 @@ static void JimCreateCommand(Jim_Interp *interp, Jim_Obj *nameObjPtr, Jim_Cmd *c Jim_ReplaceHashEntry(&interp->commands, nameObjPtr, cmd); } -int Jim_CreateCommandObj(Jim_Interp *interp, Jim_Obj *cmdNameObj, - Jim_CmdProc *cmdProc, void *privData, Jim_DelCmdProc *delProc) +/* commands */ +Jim_Cmd *Jim_RegisterCommand(Jim_Interp *interp, Jim_Obj *cmdNameObj, + Jim_CmdProc *cmdProc, + Jim_DelCmdProc *delProc, + const char *usage, + const char *help, + short minargs, + short maxargs, + int flags, + void *privData) { + JimPanic(((flags & JIM_CMD_ISPROC), "Jim_RegisterCommand called with JIM_CMD_ISPROC flag")); Jim_Cmd *cmdPtr = Jim_Alloc(sizeof(*cmdPtr)); /* Store the new details for this command */ memset(cmdPtr, 0, sizeof(*cmdPtr)); cmdPtr->inUse = 1; + cmdPtr->flags = flags; cmdPtr->u.native.delProc = delProc; cmdPtr->u.native.cmdProc = cmdProc; + cmdPtr->u.native.usage = usage; + cmdPtr->u.native.help = help; + cmdPtr->u.native.minargs = minargs; + cmdPtr->u.native.maxargs = maxargs; cmdPtr->u.native.privData = privData; Jim_IncrRefCount(cmdNameObj); JimCreateCommand(interp, cmdNameObj, cmdPtr); Jim_DecrRefCount(interp, cmdNameObj); - return JIM_OK; + return cmdPtr; } - +/* This remains for backward compatiblity to create a command + * with no arg limitations or usage/help. + * Prefer one of the Jim_Register* variants instead. + */ int Jim_CreateCommand(Jim_Interp *interp, const char *cmdNameStr, Jim_CmdProc *cmdProc, void *privData, Jim_DelCmdProc *delProc) { - return Jim_CreateCommandObj(interp, Jim_NewStringObj(interp, cmdNameStr, -1), cmdProc, privData, delProc); + Jim_RegisterCmd(interp, cmdNameStr, NULL, 0, -1, cmdProc, delProc, privData, 0); + return JIM_OK; } static int JimCreateProcedureStatics(Jim_Interp *interp, Jim_Cmd *cmdPtr, Jim_Obj *staticsListObjPtr) @@ -4249,7 +4268,7 @@ static const char *Jim_memrchr(const char *p, int c, int len) static void JimUpdateProcNamespace(Jim_Interp *interp, Jim_Cmd *cmdPtr, Jim_Obj *nameObjPtr) { #ifdef jim_ext_namespace - if (cmdPtr->isproc) { + if (cmdPtr->flags & JIM_CMD_ISPROC) { int len; const char *cmdname = Jim_GetStringNoQualifier(nameObjPtr, &len); /* XXX: Really need JimNamespaceSplit() */ @@ -4288,7 +4307,7 @@ static Jim_Cmd *JimCreateProcedureCmd(Jim_Interp *interp, Jim_Obj *argListObjPtr assert(cmdPtr); memset(cmdPtr, 0, sizeof(*cmdPtr)); cmdPtr->inUse = 1; - cmdPtr->isproc = 1; + cmdPtr->flags = JIM_CMD_ISPROC; cmdPtr->u.proc.argListObjPtr = argListObjPtr; cmdPtr->u.proc.argListLen = argListLen; cmdPtr->u.proc.bodyObjPtr = bodyObjPtr; @@ -4509,7 +4528,7 @@ Jim_Cmd *Jim_GetCommand(Jim_Interp *interp, Jim_Obj *objPtr, int flags) Jim_IncrRefCount(interp->framePtr->nsObj); Jim_DecrRefCount(interp, qualifiedNameObj); } - while (cmd->u.proc.upcall) { + while ((cmd->flags & JIM_CMD_ISPROC) && cmd->u.proc.upcall) { cmd = cmd->prevCmd; } return cmd; @@ -6028,7 +6047,7 @@ static Jim_Obj *JimProcForEvalFrame(Jim_Interp *interp, Jim_EvalFrame *frame) if (frame == interp->evalFrame || (frame->cmd && frame->cmd->cmdNameObj)) { Jim_EvalFrame *e; for (e = frame->parent; e; e = e->parent) { - if (e->cmd && e->cmd->isproc && e->cmd->cmdNameObj) { + if (e->cmd && (e->cmd->flags & JIM_CMD_ISPROC) && e->cmd->cmdNameObj) { break; } } @@ -10763,10 +10782,6 @@ static int Jim_IncrCoreCommand(Jim_Interp *interp, int argc, Jim_Obj *const *arg jim_wide wideValue, increment = 1; Jim_Obj *intObjPtr; - if (argc != 2 && argc != 3) { - Jim_WrongNumArgs(interp, 1, argv, "varName ?increment?"); - return JIM_ERR; - } if (argc == 3) { if (Jim_GetWideExpr(interp, argv[2], &increment) != JIM_OK) return JIM_ERR; @@ -10950,12 +10965,16 @@ tailcall: /* Call it -- Make sure result is an empty object. */ Jim_SetEmptyResult(interp); interp->taint = Jim_CalcTaint(objc, objv); - if (cmdPtr->isproc) { + if (cmdPtr->flags & JIM_CMD_ISPROC) { retcode = JimCallProcedure(interp, cmdPtr, objc, objv); } + else if ((cmdPtr->flags & JIM_CMD_NOTAINT) && Jim_CheckTaint(interp, JIM_TAINT_ANY)) { + Jim_SetTaintError(interp, 1, objv); + retcode = JIM_ERR; + } else { - interp->cmdPrivData = cmdPtr->u.native.privData; - retcode = cmdPtr->u.native.cmdProc(interp, objc, objv); + retcode = JimCallNative(interp, cmdPtr, objc, objv); + /* XXX Could it return -2 for tainted? */ } if (retcode == JIM_ERR) { JimSetErrorStack(interp, NULL); @@ -11281,7 +11300,7 @@ int Jim_EvalObj(Jim_Interp *interp, Jim_Obj *scriptObjPtr) } if (script->len == 3 && token[1].objPtr->typePtr == &commandObjType - && token[1].objPtr->internalRep.cmdValue.cmdPtr->isproc == 0 + && (token[1].objPtr->internalRep.cmdValue.cmdPtr->flags & JIM_CMD_ISPROC) == 0 && token[1].objPtr->internalRep.cmdValue.cmdPtr->u.native.cmdProc == Jim_IncrCoreCommand && token[2].objPtr->typePtr == &variableObjType) { @@ -11507,46 +11526,64 @@ static int JimSetProcArg(Jim_Interp *interp, Jim_Obj *argNameObj, Jim_Obj *argVa return retcode; } -/** - * Sets the interp result to be an error message indicating the required proc args. +/* Returns a zero-ref count usage string for the command. + * If no usage is availabe, just returns "cmd ..." */ -static void JimSetProcWrongArgs(Jim_Interp *interp, Jim_Obj *procNameObj, Jim_Cmd *cmd) +static Jim_Obj *JimCmdUsage(Jim_Interp *interp, Jim_Obj *cmdNameObj, Jim_Cmd *cmd) { - /* Create a nice error message, consistent with Tcl 8.5 */ - Jim_Obj *argmsg = Jim_NewStringObj(interp, "", 0); - int i; - - for (i = 0; i < cmd->u.proc.argListLen; i++) { - Jim_AppendString(interp, argmsg, " ", 1); + Jim_Obj *usage = Jim_DuplicateObj(interp, cmdNameObj); - if (i == cmd->u.proc.argsPos) { - if (cmd->u.proc.arglist[i].defaultObjPtr) { - /* Renamed args */ - Jim_AppendString(interp, argmsg, "?", 1); - Jim_AppendObj(interp, argmsg, cmd->u.proc.arglist[i].defaultObjPtr); - Jim_AppendString(interp, argmsg, " ...?", -1); - } - else { - /* We have plain args */ - Jim_AppendString(interp, argmsg, "?arg ...?", -1); - } - } - else { - if (cmd->u.proc.arglist[i].defaultObjPtr) { - Jim_AppendString(interp, argmsg, "?", 1); - Jim_AppendObj(interp, argmsg, cmd->u.proc.arglist[i].nameObjPtr); - Jim_AppendString(interp, argmsg, "?", 1); + if (cmd->flags & JIM_CMD_ISPROC) { + int i; + for (i = 0; i < cmd->u.proc.argListLen; i++) { + Jim_AppendString(interp, usage, " ", 1); + + if (i == cmd->u.proc.argsPos) { + if (cmd->u.proc.arglist[i].defaultObjPtr) { + /* Renamed args */ + Jim_AppendString(interp, usage, "?", 1); + Jim_AppendObj(interp, usage, cmd->u.proc.arglist[i].defaultObjPtr); + Jim_AppendString(interp, usage, " ...?", -1); + } + else { + /* We have plain args */ + Jim_AppendString(interp, usage, "?arg ...?", -1); + } } else { - const char *arg = Jim_String(cmd->u.proc.arglist[i].nameObjPtr); - if (*arg == '&') { - arg++; + if (cmd->u.proc.arglist[i].defaultObjPtr) { + Jim_AppendString(interp, usage, "?", 1); + Jim_AppendObj(interp, usage, cmd->u.proc.arglist[i].nameObjPtr); + Jim_AppendString(interp, usage, "?", 1); + } + else { + const char *arg = Jim_String(cmd->u.proc.arglist[i].nameObjPtr); + if (*arg == '&') { + arg++; + } + Jim_AppendString(interp, usage, arg, -1); } - Jim_AppendString(interp, argmsg, arg, -1); } } } - Jim_SetResultFormatted(interp, "wrong # args: should be \"%#s%#s\"", procNameObj, argmsg); + else if (cmd->u.native.usage) { + if (*cmd->u.native.usage) { + Jim_AppendStrings(interp, usage, " ", cmd->u.native.usage, NULL); + } + } + else { + Jim_AppendString(interp, usage, " ...", -1); + } + + return usage; +} + +/** + * Sets the interp result to be an error message indicating the required proc args. + */ +static void JimSetProcWrongArgs(Jim_Interp *interp, Jim_Obj *procNameObj, Jim_Cmd *cmd) +{ + Jim_SetResultFormatted(interp, "wrong # args: should be \"%#s\"", JimCmdUsage(interp, procNameObj, cmd)); } #ifdef jim_ext_namespace @@ -11699,6 +11736,36 @@ badargset: return retcode; } +static int JimCallNative(Jim_Interp *interp, Jim_Cmd *cmd, int argc, Jim_Obj *const *argv) +{ + int argsok = 1; + int ret; + + /* Check arg count */ + if (argc - 1 < cmd->u.native.minargs) { + argsok = 0; + } + else if (cmd->u.native.maxargs >= 0 && argc - 1 > cmd->u.native.maxargs) { + argsok = 0; + } + else if (cmd->u.native.maxargs < -1 && (argc - 1) % -cmd->u.native.maxargs != 0) { + /* -2 means must have n * 2 args */ + argsok = 0; + } + if (argsok) { + interp->cmdPrivData = cmd->u.native.privData; + ret = cmd->u.native.cmdProc(interp, argc, argv); + if (ret >= 0) { + return ret; + } + /* This means an argument error */ + } + + //printf("Wrong args for %s, argc=%d, minargs=%d, maxargs=%d\n", Jim_String(argv[0]), argc, cmd->u.native.minargs, cmd->u.native.maxargs); + Jim_SetResultFormatted(interp, "wrong # args: should be \"%#s\"", JimCmdUsage(interp, argv[0], cmd)); + return JIM_ERR; +} + int Jim_EvalSource(Jim_Interp *interp, const char *filename, int lineno, const char *script) { int retval; @@ -11963,6 +12030,10 @@ static Jim_Obj *JimJoinCmdArgs(Jim_Interp *interp, int argc, Jim_Obj *const *arg return objPtr; } + /* This function should not be necessary for simple commands. + * Instead set minargs/maxargs and a usage string when registering the command and + * optionally return JIM_USAGE from the command proc to generate a usage message. + */ void Jim_WrongNumArgs(Jim_Interp *interp, int argc, Jim_Obj *const *argv, const char *msg) { Jim_Obj *objPtr = JimJoinCmdArgs(interp, argc, argv); @@ -12041,9 +12112,10 @@ static Jim_Obj *JimHashtablePatternMatch(Jim_Interp *interp, Jim_HashTable *ht, } /* Keep these in order */ -#define JIM_CMDLIST_COMMANDS 0 -#define JIM_CMDLIST_PROCS 1 -#define JIM_CMDLIST_CHANNELS 2 +#define JIM_CMDLIST_COMMANDS 1 +#define JIM_CMDLIST_PROCS 2 +#define JIM_CMDLIST_ALIASES 4 +#define JIM_CMDLIST_CHANNELS 8 /** * Adds matching command names (procs, channels) to the list. @@ -12052,30 +12124,36 @@ static void JimCommandMatch(Jim_Interp *interp, Jim_Obj *listObjPtr, Jim_Obj *keyObj, void *value, Jim_Obj *patternObj, int type) { Jim_Cmd *cmdPtr = (Jim_Cmd *)value; + int match = 1; - if (type == JIM_CMDLIST_PROCS && !cmdPtr->isproc) { + if (type == JIM_CMDLIST_PROCS && !(cmdPtr->flags & JIM_CMD_ISPROC)) { /* not a proc */ return; } + if (type == JIM_CMDLIST_CHANNELS && !(cmdPtr->flags & JIM_CMD_ISCHANNEL)) { + /* not a channel */ + return; + } + if ((type & JIM_CMDLIST_ALIASES) && !(cmdPtr->flags & JIM_CMD_ISALIAS)) { + /* not an alias */ + return; + } Jim_IncrRefCount(keyObj); - if (type != JIM_CMDLIST_CHANNELS || Jim_AioFilehandle(interp, keyObj) >= 0) { - int match = 1; - if (patternObj) { - int plen, slen; - const char *pattern = Jim_GetStringNoQualifier(patternObj, &plen); - const char *str = Jim_GetStringNoQualifier(keyObj, &slen); + if (patternObj) { + int plen, slen; + const char *pattern = Jim_GetStringNoQualifier(patternObj, &plen); + const char *str = Jim_GetStringNoQualifier(keyObj, &slen); #ifdef JIM_NO_INTROSPECTION - /* Only exact match supported with no introspection */ - match = (JimStringCompareUtf8(pattern, plen, str, slen, 0) == 0); + /* Only exact match supported with no introspection */ + match = (JimStringCompareUtf8(pattern, plen, str, slen, 0) == 0); #else - match = JimGlobMatch(pattern, plen, str, slen, 0); + match = JimGlobMatch(pattern, plen, str, slen, 0); #endif - } - if (match) { - Jim_ListAppendElement(interp, listObjPtr, keyObj); - } + } + if (match) { + Jim_ListAppendElement(interp, listObjPtr, keyObj); } Jim_DecrRefCount(interp, keyObj); } @@ -12196,10 +12274,6 @@ static int JimInfoFrame(Jim_Interp *interp, Jim_Obj *levelObjPtr, Jim_Obj **objP /* fake [puts] -- not the real puts, just for debugging. */ static int Jim_PutsCoreCommand(Jim_Interp *interp, int argc, Jim_Obj *const *argv) { - if (argc != 2 && argc != 3) { - Jim_WrongNumArgs(interp, 1, argv, "?-nonewline? string"); - return JIM_ERR; - } if (argc == 3) { if (!Jim_CompareStringImmediate(interp, argv[1], "-nonewline")) { Jim_SetResultString(interp, "The second argument must " "be -nonewline", -1); @@ -12255,11 +12329,7 @@ static int JimSubDivHelper(Jim_Interp *interp, int argc, Jim_Obj *const *argv, i double doubleValue, doubleRes = 0; int i = 2; - if (argc < 2) { - Jim_WrongNumArgs(interp, 1, argv, "number ?number ... number?"); - return JIM_ERR; - } - else if (argc == 2) { + if (argc == 2) { /* The arity = 2 case is different. For [- x] returns -x, * while [/ x] returns 1/x. */ if (Jim_GetWide(interp, argv[1], &wideValue) != JIM_OK) { @@ -12354,10 +12424,6 @@ static int Jim_DivCoreCommand(Jim_Interp *interp, int argc, Jim_Obj *const *argv /* [set] */ static int Jim_SetCoreCommand(Jim_Interp *interp, int argc, Jim_Obj *const *argv) { - if (argc != 2 && argc != 3) { - Jim_WrongNumArgs(interp, 1, argv, "varName ?newValue?"); - return JIM_ERR; - } if (argc == 2) { Jim_Obj *objPtr; @@ -12428,11 +12494,6 @@ static int JimCheckLoopRetcode(Jim_Interp *interp, int retval) /* [while] */ static int Jim_WhileCoreCommand(Jim_Interp *interp, int argc, Jim_Obj *const *argv) { - if (argc != 3) { - Jim_WrongNumArgs(interp, 1, argv, "condition body"); - return JIM_ERR; - } - /* The general purpose implementation of while starts here */ while (1) { int boolean = 0, retval; @@ -12470,11 +12531,6 @@ static int Jim_ForCoreCommand(Jim_Interp *interp, int argc, Jim_Obj *const *argv Jim_Obj *varNamePtr = NULL; Jim_Obj *stopVarNamePtr = NULL; - if (argc != 5) { - Jim_WrongNumArgs(interp, 1, argv, "start test next body"); - return JIM_ERR; - } - /* Do the initialisation */ if ((retval = Jim_EvalObj(interp, argv[1])) != JIM_OK) { return retval; @@ -12664,11 +12720,6 @@ static int Jim_LoopCoreCommand(Jim_Interp *interp, int argc, Jim_Obj *const *arg jim_wide incr = 1; Jim_Obj *bodyObjPtr; - if (argc < 4 || argc > 6) { - Jim_WrongNumArgs(interp, 1, argv, "var ?first? limit ?incr? body"); - return JIM_ERR; - } - retval = Jim_GetWideExpr(interp, argv[2], &i); if (argc > 4 && retval == JIM_OK) { retval = Jim_GetWideExpr(interp, argv[3], &limit); @@ -12781,9 +12832,8 @@ static int JimForeachMapHelper(Jim_Interp *interp, int argc, Jim_Obj *const *arg Jim_Obj *script; Jim_Obj *resultObj; - if (argc < 4 || argc % 2 != 0) { - Jim_WrongNumArgs(interp, 1, argv, "varList list ?varList list ...? script"); - return JIM_ERR; + if (argc % 2 != 0) { + return JIM_USAGE; } script = argv[argc - 1]; /* Last argument is a script */ numargs = (argc - 1 - 1); /* argc - 'foreach' - script */ @@ -12896,11 +12946,6 @@ static int Jim_LassignCoreCommand(Jim_Interp *interp, int argc, Jim_Obj *const * Jim_ListIter iter; Jim_Obj *resultObj; - if (argc < 2) { - Jim_WrongNumArgs(interp, 1, argv, "varList list ?varName ...?"); - return JIM_ERR; - } - JimListIterInit(&iter, argv[1]); for (i = 2; i < argc; i++) { @@ -12926,50 +12971,50 @@ static int Jim_IfCoreCommand(Jim_Interp *interp, int argc, Jim_Obj *const *argv) { int boolean, retval, current = 1, falsebody = 0; - if (argc >= 3) { - while (1) { - /* Far not enough arguments given! */ - if (current >= argc) - goto err; - if ((retval = Jim_GetBoolFromExpr(interp, argv[current++], &boolean)) - != JIM_OK) - return retval; - /* There lacks something, isn't it? */ - if (current >= argc) - goto err; - if (Jim_CompareStringImmediate(interp, argv[current], "then")) - current++; - /* Tsk tsk, no then-clause? */ - if (current >= argc) - goto err; - if (boolean) - return Jim_EvalObj(interp, argv[current]); - /* Ok: no else-clause follows */ - if (++current >= argc) { - Jim_SetResult(interp, Jim_NewEmptyStringObj(interp)); - return JIM_OK; - } - falsebody = current++; - if (Jim_CompareStringImmediate(interp, argv[falsebody], "else")) { - /* IIICKS - else-clause isn't last cmd? */ - if (current != argc - 1) - goto err; - return Jim_EvalObj(interp, argv[current]); + while (1) { + /* not enough arguments given! */ + if (current >= argc) { + return JIM_USAGE; + } + if ((retval = Jim_GetBoolFromExpr(interp, argv[current++], &boolean)) + != JIM_OK) + return retval; + /* There lacks something, isn't it? */ + if (current >= argc) { + return JIM_USAGE; + } + if (Jim_CompareStringImmediate(interp, argv[current], "then")) + current++; + /* Tsk tsk, no then-clause? */ + if (current >= argc) { + return JIM_USAGE; + } + if (boolean) + return Jim_EvalObj(interp, argv[current]); + /* Ok: no else-clause follows */ + if (++current >= argc) { + Jim_SetResult(interp, Jim_NewEmptyStringObj(interp)); + return JIM_OK; + } + falsebody = current++; + if (Jim_CompareStringImmediate(interp, argv[falsebody], "else")) { + /* IIICKS - else-clause isn't last cmd? */ + if (current != argc - 1) { + return JIM_USAGE; } - else if (Jim_CompareStringImmediate(interp, argv[falsebody], "elseif")) - /* Ok: elseif follows meaning all the stuff - * again (how boring...) */ - continue; - /* OOPS - else-clause is not last cmd? */ - else if (falsebody != argc - 1) - goto err; - return Jim_EvalObj(interp, argv[falsebody]); + return Jim_EvalObj(interp, argv[current]); } - return JIM_OK; + else if (Jim_CompareStringImmediate(interp, argv[falsebody], "elseif")) + /* Ok: elseif follows meaning all the stuff + * again (how boring...) */ + continue; + /* OOPS - else-clause is not last cmd? */ + else if (falsebody != argc - 1) { + return JIM_USAGE; + } + return Jim_EvalObj(interp, argv[falsebody]); } - err: - Jim_WrongNumArgs(interp, 1, argv, "condition ?then? trueBody ?elseif ...? ?else? falseBody"); - return JIM_ERR; + return JIM_OK; } @@ -13012,12 +13057,6 @@ static int Jim_SwitchCoreCommand(Jim_Interp *interp, int argc, Jim_Obj *const *a Jim_Obj *command = NULL, *scriptObj = NULL, *strObj; Jim_Obj **caseList; - if (argc < 3) { - wrongnumargs: - Jim_WrongNumArgs(interp, 1, argv, "?options? string " - "pattern body ... ?default body? or " "{pattern body ?pattern body ...?}"); - return JIM_ERR; - } for (opt = 1; opt < argc; ++opt) { const char *option = Jim_String(argv[opt]); @@ -13038,7 +13077,7 @@ static int Jim_SwitchCoreCommand(Jim_Interp *interp, int argc, Jim_Obj *const *a else if (strncmp(option, "-command", 2) == 0) { matchOpt = SWITCH_CMD; if ((argc - opt) < 2) - goto wrongnumargs; + return JIM_USAGE; command = argv[++opt]; } else { @@ -13048,7 +13087,7 @@ static int Jim_SwitchCoreCommand(Jim_Interp *interp, int argc, Jim_Obj *const *a return JIM_ERR; } if ((argc - opt) < 2) - goto wrongnumargs; + return JIM_USAGE; } strObj = argv[opt++]; patCount = argc - opt; @@ -13058,7 +13097,7 @@ static int Jim_SwitchCoreCommand(Jim_Interp *interp, int argc, Jim_Obj *const *a else caseList = (Jim_Obj **)&argv[opt]; if (patCount == 0 || patCount % 2 != 0) - goto wrongnumargs; + return JIM_USAGE; for (i = 0; scriptObj == NULL && i < patCount; i += 2) { Jim_Obj *patObj = caseList[i]; @@ -13128,10 +13167,6 @@ static int Jim_LindexCoreCommand(Jim_Interp *interp, int argc, Jim_Obj *const *a Jim_Obj *objPtr; int ret; - if (argc < 2) { - Jim_WrongNumArgs(interp, 1, argv, "list ?index ...?"); - return JIM_ERR; - } ret = Jim_ListIndices(interp, argv[1], argv + 2, argc - 2, &objPtr, JIM_NONE); if (ret < 0) { /* Returns an empty object if the index @@ -13148,10 +13183,6 @@ static int Jim_LindexCoreCommand(Jim_Interp *interp, int argc, Jim_Obj *const *a /* [llength] */ static int Jim_LlengthCoreCommand(Jim_Interp *interp, int argc, Jim_Obj *const *argv) { - if (argc != 2) { - Jim_WrongNumArgs(interp, 1, argv, "list"); - return JIM_ERR; - } Jim_SetResultInt(interp, Jim_ListLength(interp, argv[1])); return JIM_OK; } @@ -13180,13 +13211,6 @@ static int Jim_LsearchCoreCommand(Jim_Interp *interp, int argc, Jim_Obj *const * int match_flags = 0; long stride = 1; - if (argc < 3) { - wrongargs: - Jim_WrongNumArgs(interp, 1, argv, - "?-exact|-glob|-regexp|-command 'command'? ?-bool|-inline? ?-not? ?-nocase? ?-all? ?-stride len? ?-index val? list value"); - return JIM_ERR; - } - for (i = 1; i < argc - 2; i++) { int option; @@ -13217,7 +13241,7 @@ static int Jim_LsearchCoreCommand(Jim_Interp *interp, int argc, Jim_Obj *const * break; case OPT_COMMAND: if (i >= argc - 2) { - goto wrongargs; + return JIM_USAGE; } commandObj = argv[++i]; /* fallthru */ @@ -13227,13 +13251,13 @@ static int Jim_LsearchCoreCommand(Jim_Interp *interp, int argc, Jim_Obj *const * break; case OPT_INDEX: if (i >= argc - 2) { - goto wrongargs; + return JIM_USAGE; } indexObj = argv[++i]; break; case OPT_STRIDE: if (i >= argc - 2) { - goto wrongargs; + return JIM_USAGE; } if (Jim_GetLong(interp, argv[++i], &stride) != JIM_OK) { return JIM_ERR; @@ -13248,7 +13272,7 @@ static int Jim_LsearchCoreCommand(Jim_Interp *interp, int argc, Jim_Obj *const * argc -= i; if (argc < 2) { - goto wrongargs; + return JIM_USAGE; } argv += i; @@ -13394,10 +13418,6 @@ static int Jim_LappendCoreCommand(Jim_Interp *interp, int argc, Jim_Obj *const * int new_obj = 0; int i; - if (argc < 2) { - Jim_WrongNumArgs(interp, 1, argv, "varName ?value value ...?"); - return JIM_ERR; - } listObjPtr = Jim_GetVariable(interp, argv[1], JIM_UNSHARED); if (!listObjPtr) { /* Create the list if it does not exist */ @@ -13425,10 +13445,6 @@ static int Jim_LinsertCoreCommand(Jim_Interp *interp, int argc, Jim_Obj *const * int idx, len; Jim_Obj *listPtr; - if (argc < 3) { - Jim_WrongNumArgs(interp, 1, argv, "list index ?element ...?"); - return JIM_ERR; - } listPtr = argv[1]; if (Jim_IsShared(listPtr)) listPtr = Jim_DuplicateObj(interp, listPtr); @@ -13456,10 +13472,6 @@ static int Jim_LreplaceCoreCommand(Jim_Interp *interp, int argc, Jim_Obj *const Jim_Obj *listObj; Jim_Obj *newListObj; - if (argc < 4) { - Jim_WrongNumArgs(interp, 1, argv, "list first last ?element ...?"); - return JIM_ERR; - } if (Jim_GetIndex(interp, argv[2], &first) != JIM_OK || Jim_GetIndex(interp, argv[3], &last) != JIM_OK) { return JIM_ERR; @@ -13499,11 +13511,7 @@ static int Jim_LreplaceCoreCommand(Jim_Interp *interp, int argc, Jim_Obj *const /* [lset] */ static int Jim_LsetCoreCommand(Jim_Interp *interp, int argc, Jim_Obj *const *argv) { - if (argc < 3) { - Jim_WrongNumArgs(interp, 1, argv, "listVar ?index ...? value"); - return JIM_ERR; - } - else if (argc == 3) { + if (argc == 3) { /* With no indexes, simply implements [set] */ if (Jim_SetVariable(interp, argv[1], argv[2]) != JIM_OK) return JIM_ERR; @@ -13534,12 +13542,6 @@ static int Jim_LsortCoreCommand(Jim_Interp *interp, int argc, Jim_Obj *const arg struct lsort_info info; - if (argc < 2) { -wrongargs: - Jim_WrongNumArgs(interp, 1, argv, "?options? list"); - return JIM_ERR; - } - info.type = JIM_LSORT_ASCII; info.order = 1; info.indexc = 0; @@ -13589,7 +13591,7 @@ wrongargs: break; case OPT_STRIDE: if (i >= argc - 2) { - goto wrongargs; + return JIM_USAGE; } if (Jim_GetLong(interp, argv[++i], &stride) != JIM_OK) { return JIM_ERR; @@ -13667,10 +13669,6 @@ static int Jim_AppendCoreCommand(Jim_Interp *interp, int argc, Jim_Obj *const *a Jim_Obj *stringObjPtr; int i; - if (argc < 2) { - Jim_WrongNumArgs(interp, 1, argv, "varName ?value ...?"); - return JIM_ERR; - } if (argc == 2) { stringObjPtr = Jim_GetVariable(interp, argv[1], JIM_ERRMSG); if (!stringObjPtr) @@ -13796,8 +13794,9 @@ static int Jim_DebugCoreCommand(Jim_Interp *interp, int argc, Jim_Obj *const *ar case OPT_OBJECTS:{ Jim_Obj *objPtr, *listObjPtr, *subListObjPtr; - int tainted; + int tainted = 0; +#ifdef JIM_TAINT if (argc == 3) { if (Jim_CompareStringImmediate(interp, argv[2], "-taint")) { tainted = 1; @@ -13807,32 +13806,25 @@ static int Jim_DebugCoreCommand(Jim_Interp *interp, int argc, Jim_Obj *const *ar return JIM_ERR; } } +#endif - /* Count the number of live objects. */ - objPtr = interp->liveList; + /* Return a list of the objects */ listObjPtr = Jim_NewListObj(interp, NULL, 0); - while (objPtr) { + for (objPtr = interp->liveList; objPtr; objPtr = objPtr->nextObjPtr) { char buf[128]; const char *type = objPtr->typePtr ? objPtr->typePtr->name : ""; - /* Return a list of the objects */ - listObjPtr = Jim_NewListObj(interp, NULL, 0); - for (objPtr = interp->liveList; objPtr; objPtr = objPtr->nextObjPtr) { - char buf[128]; - const char *type = objPtr->typePtr ? objPtr->typePtr->name : ""; - - if (objPtr == listObjPtr || (tainted && !objPtr->taint)) { - continue; - } - - subListObjPtr = Jim_NewListObj(interp, NULL, 0); - sprintf(buf, "%p", objPtr); - Jim_ListAppendElement(interp, subListObjPtr, Jim_NewStringObj(interp, buf, -1)); - Jim_ListAppendElement(interp, subListObjPtr, Jim_NewStringObj(interp, type, -1)); - Jim_ListAppendElement(interp, subListObjPtr, Jim_NewIntObj(interp, objPtr->refCount)); - Jim_ListAppendElement(interp, subListObjPtr, objPtr); - Jim_ListAppendElement(interp, listObjPtr, subListObjPtr); + if (objPtr == listObjPtr || (tainted && !objPtr->taint)) { + continue; } + + subListObjPtr = Jim_NewListObj(interp, NULL, 0); + sprintf(buf, "%p", objPtr); + Jim_ListAppendElement(interp, subListObjPtr, Jim_NewStringObj(interp, buf, -1)); + Jim_ListAppendElement(interp, subListObjPtr, Jim_NewStringObj(interp, type, -1)); + Jim_ListAppendElement(interp, subListObjPtr, Jim_NewIntObj(interp, objPtr->refCount)); + Jim_ListAppendElement(interp, subListObjPtr, objPtr); + Jim_ListAppendElement(interp, listObjPtr, subListObjPtr); } Jim_SetResult(interp, listObjPtr); return JIM_OK; @@ -13910,11 +13902,6 @@ static int Jim_EvalCoreCommand(Jim_Interp *interp, int argc, Jim_Obj *const *arg { int rc; - if (argc < 2) { - Jim_WrongNumArgs(interp, 1, argv, "arg ?arg ...?"); - return JIM_ERR; - } - if (argc == 2) { rc = Jim_EvalObj(interp, argv[1]); } @@ -13928,46 +13915,39 @@ static int Jim_EvalCoreCommand(Jim_Interp *interp, int argc, Jim_Obj *const *arg /* [uplevel] */ static int Jim_UplevelCoreCommand(Jim_Interp *interp, int argc, Jim_Obj *const *argv) { - if (argc >= 2) { - int retcode; - Jim_CallFrame *savedCallFrame, *targetCallFrame; - const char *str; + int retcode; + Jim_CallFrame *savedCallFrame, *targetCallFrame; + const char *str; - /* Save the old callframe pointer */ - savedCallFrame = interp->framePtr; + /* Save the old callframe pointer */ + savedCallFrame = interp->framePtr; - /* Lookup the target frame pointer */ - str = Jim_String(argv[1]); - if ((str[0] >= '0' && str[0] <= '9') || str[0] == '#') { - targetCallFrame = Jim_GetCallFrameByLevel(interp, argv[1]); - argc--; - argv++; - } - else { - targetCallFrame = Jim_GetCallFrameByLevel(interp, NULL); - } - if (targetCallFrame == NULL) { - return JIM_ERR; - } - if (argc < 2) { - Jim_WrongNumArgs(interp, 1, argv - 1, "?level? command ?arg ...?"); - return JIM_ERR; - } - /* Eval the code in the target callframe. */ - interp->framePtr = targetCallFrame; - if (argc == 2) { - retcode = Jim_EvalObj(interp, argv[1]); - } - else { - retcode = Jim_EvalObj(interp, Jim_ConcatObj(interp, argc - 1, argv + 1)); - } - interp->framePtr = savedCallFrame; - return retcode; + /* Lookup the target frame pointer */ + str = Jim_String(argv[1]); + if ((str[0] >= '0' && str[0] <= '9') || str[0] == '#') { + targetCallFrame = Jim_GetCallFrameByLevel(interp, argv[1]); + argc--; + argv++; } else { - Jim_WrongNumArgs(interp, 1, argv, "?level? command ?arg ...?"); + targetCallFrame = Jim_GetCallFrameByLevel(interp, NULL); + } + if (targetCallFrame == NULL) { return JIM_ERR; } + if (argc < 2) { + return JIM_USAGE; + } + /* Eval the code in the target callframe. */ + interp->framePtr = targetCallFrame; + if (argc == 2) { + retcode = Jim_EvalObj(interp, argv[1]); + } + else { + retcode = Jim_EvalObj(interp, Jim_ConcatObj(interp, argc - 1, argv + 1)); + } + interp->framePtr = savedCallFrame; + return retcode; } /* [expr] */ @@ -13978,13 +13958,7 @@ static int Jim_ExprCoreCommand(Jim_Interp *interp, int argc, Jim_Obj *const *arg if (argc == 2) { retcode = Jim_EvalExpression(interp, argv[1]); } -#ifndef JIM_COMPAT else { - Jim_WrongNumArgs(interp, 1, argv, "expression"); - retcode = JIM_ERR; - } -#else - else if (argc > 2) { Jim_Obj *objPtr; objPtr = Jim_ConcatObj(interp, argc - 1, argv + 1); @@ -13992,20 +13966,11 @@ static int Jim_ExprCoreCommand(Jim_Interp *interp, int argc, Jim_Obj *const *arg retcode = Jim_EvalExpression(interp, objPtr); Jim_DecrRefCount(interp, objPtr); } - else { - Jim_WrongNumArgs(interp, 1, argv, "expression ?...?"); - return JIM_ERR; - } -#endif return retcode; } static int JimBreakContinueHelper(Jim_Interp *interp, int argc, Jim_Obj *const *argv, int retcode) { - if (argc != 1 && argc != 2) { - Jim_WrongNumArgs(interp, 1, argv, "?level?"); - return JIM_ERR; - } if (argc == 2) { long level; int ret = Jim_GetLong(interp, argv[1], &level); @@ -14093,8 +14058,7 @@ static int Jim_ReturnCoreCommand(Jim_Interp *interp, int argc, Jim_Obj *const *a } if (i != argc - 1 && i != argc) { - Jim_WrongNumArgs(interp, 1, argv, - "?-code code? ?-errorinfo stacktrace? ?-level level? ?result?"); + return JIM_USAGE; } /* If a stack trace is supplied and code is error, set the stack trace */ @@ -14168,18 +14132,12 @@ static void JimAliasCmdDelete(Jim_Interp *interp, void *privData) static int Jim_AliasCoreCommand(Jim_Interp *interp, int argc, Jim_Obj *const *argv) { - Jim_Obj *prefixListObj; - - if (argc < 3) { - Jim_WrongNumArgs(interp, 1, argv, "newname command ?args ...?"); - return JIM_ERR; - } - - prefixListObj = Jim_NewListObj(interp, argv + 2, argc - 2); + Jim_Obj *prefixListObj = Jim_NewListObj(interp, argv + 2, argc - 2); Jim_IncrRefCount(prefixListObj); Jim_SetResult(interp, argv[1]); - return Jim_CreateCommandObj(interp, argv[1], JimAliasCmd, prefixListObj, JimAliasCmdDelete); + Jim_RegisterCommand(interp, argv[1], JimAliasCmd, JimAliasCmdDelete, NULL, NULL, 0, -1, JIM_CMD_ISALIAS, prefixListObj); + return JIM_OK; } /* [proc] */ @@ -14187,11 +14145,6 @@ static int Jim_ProcCoreCommand(Jim_Interp *interp, int argc, Jim_Obj *const *arg { Jim_Cmd *cmd; - if (argc != 4 && argc != 5) { - Jim_WrongNumArgs(interp, 1, argv, "name arglist ?statics? body"); - return JIM_ERR; - } - if (argc == 4) { cmd = JimCreateProcedureCmd(interp, argv[2], NULL, argv[3], NULL); } @@ -14218,11 +14171,6 @@ static int Jim_ProcCoreCommand(Jim_Interp *interp, int argc, Jim_Obj *const *arg /* [xtrace] */ static int Jim_XtraceCoreCommand(Jim_Interp *interp, int argc, Jim_Obj *const *argv) { - if (argc != 2) { - Jim_WrongNumArgs(interp, 1, argv, "callback"); - return JIM_ERR; - } - if (interp->traceCmdObj) { Jim_DecrRefCount(interp, interp->traceCmdObj); interp->traceCmdObj = NULL; @@ -14241,11 +14189,6 @@ static int Jim_LocalCoreCommand(Jim_Interp *interp, int argc, Jim_Obj *const *ar { int retcode; - if (argc < 2) { - Jim_WrongNumArgs(interp, 1, argv, "cmd ?args ...?"); - return JIM_ERR; - } - /* Evaluate the arguments with 'local' in force */ interp->local++; retcode = Jim_EvalObjVector(interp, argc - 1, argv + 1); @@ -14273,83 +14216,71 @@ static int Jim_LocalCoreCommand(Jim_Interp *interp, int argc, Jim_Obj *const *ar /* [upcall] */ static int Jim_UpcallCoreCommand(Jim_Interp *interp, int argc, Jim_Obj *const *argv) { - if (argc < 2) { - Jim_WrongNumArgs(interp, 1, argv, "cmd ?args ...?"); + int retcode; + + Jim_Cmd *cmdPtr = Jim_GetCommand(interp, argv[1], JIM_ERRMSG); + if (cmdPtr == NULL || !(cmdPtr->flags & JIM_CMD_ISPROC) || !cmdPtr->prevCmd) { + Jim_SetResultFormatted(interp, "no previous command: \"%#s\"", argv[1]); return JIM_ERR; } - else { - int retcode; - - Jim_Cmd *cmdPtr = Jim_GetCommand(interp, argv[1], JIM_ERRMSG); - if (cmdPtr == NULL || !cmdPtr->isproc || !cmdPtr->prevCmd) { - Jim_SetResultFormatted(interp, "no previous command: \"%#s\"", argv[1]); - return JIM_ERR; - } - /* OK. Mark this command as being in an upcall */ - cmdPtr->u.proc.upcall++; - JimIncrCmdRefCount(cmdPtr); + /* OK. Mark this command as being in an upcall */ + cmdPtr->u.proc.upcall++; + JimIncrCmdRefCount(cmdPtr); - /* Invoke the command as normal */ - retcode = Jim_EvalObjVector(interp, argc - 1, argv + 1); + /* Invoke the command as normal */ + retcode = Jim_EvalObjVector(interp, argc - 1, argv + 1); - /* No longer in an upcall */ - cmdPtr->u.proc.upcall--; - JimDecrCmdRefCount(interp, cmdPtr); + /* No longer in an upcall */ + cmdPtr->u.proc.upcall--; + JimDecrCmdRefCount(interp, cmdPtr); - return retcode; - } + return retcode; } /* [apply] */ static int Jim_ApplyCoreCommand(Jim_Interp *interp, int argc, Jim_Obj *const *argv) { - if (argc < 2) { - Jim_WrongNumArgs(interp, 1, argv, "lambdaExpr ?arg ...?"); + int ret; + Jim_Cmd *cmd; + Jim_Obj *argListObjPtr; + Jim_Obj *bodyObjPtr; + Jim_Obj *nsObj = NULL; + Jim_Obj **nargv; + + int len = Jim_ListLength(interp, argv[1]); + if (len != 2 && len != 3) { + Jim_SetResultFormatted(interp, "can't interpret \"%#s\" as a lambda expression", argv[1]); return JIM_ERR; } - else { - int ret; - Jim_Cmd *cmd; - Jim_Obj *argListObjPtr; - Jim_Obj *bodyObjPtr; - Jim_Obj *nsObj = NULL; - Jim_Obj **nargv; - - int len = Jim_ListLength(interp, argv[1]); - if (len != 2 && len != 3) { - Jim_SetResultFormatted(interp, "can't interpret \"%#s\" as a lambda expression", argv[1]); - return JIM_ERR; - } - if (len == 3) { + if (len == 3) { #ifdef jim_ext_namespace - /* Note that the namespace is always treated as global */ - nsObj = Jim_ListGetIndex(interp, argv[1], 2); + /* Note that the namespace is always treated as global */ + nsObj = Jim_ListGetIndex(interp, argv[1], 2); #else - Jim_SetResultString(interp, "namespaces not enabled", -1); - return JIM_ERR; + Jim_SetResultString(interp, "namespaces not enabled", -1); + return JIM_ERR; #endif - } - argListObjPtr = Jim_ListGetIndex(interp, argv[1], 0); - bodyObjPtr = Jim_ListGetIndex(interp, argv[1], 1); + } + argListObjPtr = Jim_ListGetIndex(interp, argv[1], 0); + bodyObjPtr = Jim_ListGetIndex(interp, argv[1], 1); - cmd = JimCreateProcedureCmd(interp, argListObjPtr, NULL, bodyObjPtr, nsObj); + cmd = JimCreateProcedureCmd(interp, argListObjPtr, NULL, bodyObjPtr, nsObj); - if (cmd) { - /* Create a new argv array with a dummy argv[0], for error messages */ - nargv = Jim_Alloc((argc - 2 + 1) * sizeof(*nargv)); - nargv[0] = Jim_NewStringObj(interp, "apply lambdaExpr", -1); - Jim_IncrRefCount(nargv[0]); - memcpy(&nargv[1], argv + 2, (argc - 2) * sizeof(*nargv)); - ret = JimCallProcedure(interp, cmd, argc - 2 + 1, nargv); - Jim_DecrRefCount(interp, nargv[0]); - Jim_Free(nargv); - - JimDecrCmdRefCount(interp, cmd); - return ret; - } - return JIM_ERR; + if (cmd) { + /* Create a new argv array with a dummy argv[0], for error messages */ + nargv = Jim_Alloc((argc - 2 + 1) * sizeof(*nargv)); + nargv[0] = Jim_NewStringObj(interp, "apply lambdaExpr", -1); + Jim_IncrRefCount(nargv[0]); + memcpy(&nargv[1], argv + 2, (argc - 2) * sizeof(*nargv)); + ret = JimCallProcedure(interp, cmd, argc - 2 + 1, nargv); + Jim_DecrRefCount(interp, nargv[0]); + Jim_Free(nargv); + + JimDecrCmdRefCount(interp, cmd); + return ret; } + return JIM_ERR; } #ifdef JIM_TAINT @@ -14436,8 +14367,7 @@ static int Jim_UpvarCoreCommand(Jim_Interp *interp, int argc, Jim_Obj *const *ar /* Check for arity */ if (argc < 3) { - Jim_WrongNumArgs(interp, 1, argv, "?level? otherVar localVar ?otherVar localVar ...?"); - return JIM_ERR; + return JIM_USAGE; } /* Now... for every other/local couple: */ @@ -14453,10 +14383,6 @@ static int Jim_GlobalCoreCommand(Jim_Interp *interp, int argc, Jim_Obj *const *a { int i; - if (argc < 2) { - Jim_WrongNumArgs(interp, 1, argv, "varName ?varName ...?"); - return JIM_ERR; - } /* Link every var to the toplevel having the same name */ if (interp->framePtr->level == 0) return JIM_OK; /* global at toplevel... */ @@ -14573,7 +14499,7 @@ static int Jim_StringCoreCommand(Jim_Interp *interp, int argc, Jim_Obj *const *a static const jim_subcmd_type cmds[OPT_COUNT + 1] = { JIM_DEF_SUBCMD("bytelength", "string", 1, 1), JIM_DEF_SUBCMD("byterange", "string first last", 3, 3), - JIM_DEF_SUBCMD("cat", "?...?", 0, -1), + JIM_DEF_SUBCMD("cat", "?string ...?", 0, -1), JIM_DEF_SUBCMD("compare", "?-nocase? ?-length int? string1 string2", 2, 5), JIM_DEF_SUBCMD("equal", "?-nocase? ?-length int? string1 string2", 2, 5), JIM_DEF_SUBCMD("first", "subString string ?index?", 2, 3), @@ -14891,10 +14817,6 @@ static int Jim_TimeCoreCommand(Jim_Interp *interp, int argc, Jim_Obj *const *arg long i, count = 1; jim_wide start, elapsed; - if (argc < 2) { - Jim_WrongNumArgs(interp, 1, argv, "script ?count?"); - return JIM_ERR; - } if (argc == 3) { if (Jim_GetLong(interp, argv[2], &count) != JIM_OK) return JIM_ERR; @@ -14923,7 +14845,7 @@ static int Jim_TimeCoreCommand(Jim_Interp *interp, int argc, Jim_Obj *const *arg } /* [timerate] */ -static int Jim_TimeRateCoreCommand(Jim_Interp *interp, int argc, Jim_Obj *const *argv) +static int Jim_TimerateCoreCommand(Jim_Interp *interp, int argc, Jim_Obj *const *argv) { long us = 0; jim_wide start, delta, overhead; @@ -14932,10 +14854,6 @@ static int Jim_TimeRateCoreCommand(Jim_Interp *interp, int argc, Jim_Obj *const int count; int n; - if (argc < 2) { - Jim_WrongNumArgs(interp, 1, argv, "script ?milliseconds?"); - return JIM_ERR; - } if (argc == 3) { if (Jim_GetLong(interp, argv[2], &us) != JIM_OK) return JIM_ERR; @@ -14992,10 +14910,6 @@ static int Jim_ExitCoreCommand(Jim_Interp *interp, int argc, Jim_Obj *const *arg { long exitCode = 0; - if (argc > 2) { - Jim_WrongNumArgs(interp, 1, argv, "?exitCode?"); - return JIM_ERR; - } if (argc == 2) { if (Jim_GetLong(interp, argv[1], &exitCode) != JIM_OK) return JIM_ERR; @@ -15024,10 +14938,6 @@ static int JimMatchReturnCodes(Jim_Interp *interp, Jim_Obj *retcodeListObj, int /* Implements both [try] and [catch] */ static int JimCatchTryHelper(Jim_Interp *interp, int istry, int argc, Jim_Obj *const *argv) { - static const char * const wrongargs_catchtry[2] = { - "?-?no?code ... --? script ?resultVarName? ?optionVarName?", - "?-?no?code ... --? script ?on|trap codes vars script? ... ?finally script?" - }; int exitCode = 0; int i; int sig = 0; @@ -15080,7 +14990,7 @@ static int JimCatchTryHelper(Jim_Interp *interp, int istry, int argc, Jim_Obj *c option = Jim_FindByName(arg, jimReturnCodes, jimReturnCodesSize); } if (option < 0) { - goto wrongargs; + return JIM_USAGE; } if (ignore) { @@ -15094,9 +15004,7 @@ static int JimCatchTryHelper(Jim_Interp *interp, int istry, int argc, Jim_Obj *c idx = i; if (argc - idx < 1) { -wrongargs: - Jim_WrongNumArgs(interp, 1, argv, wrongargs_catchtry[istry]); - return JIM_ERR; + return JIM_USAGE; } if ((ignore_mask & (1 << JIM_SIGNAL)) == 0) { @@ -15139,12 +15047,12 @@ wrongargs: case TRY_ON: case TRY_TRAP: if (idx + 4 > argc) { - goto wrongargs; + return JIM_USAGE; } if (option == TRY_ON) { ret = JimMatchReturnCodes(interp, argv[idx + 1], exitCode); if (ret > JIM_OK) { - goto wrongargs; + return JIM_USAGE; } } else if (errorCodeObj) { @@ -15182,7 +15090,7 @@ wrongargs: break; case TRY_FINALLY: if (idx + 2 != argc) { - goto wrongargs; + return JIM_USAGE; } finallyScriptObj = argv[idx + 1]; idx += 2; @@ -15291,10 +15199,6 @@ static int Jim_TryCoreCommand(Jim_Interp *interp, int argc, Jim_Obj *const *argv /* [ref] */ static int Jim_RefCoreCommand(Jim_Interp *interp, int argc, Jim_Obj *const *argv) { - if (argc != 3 && argc != 4) { - Jim_WrongNumArgs(interp, 1, argv, "string tag ?finalizer?"); - return JIM_ERR; - } if (argc == 3) { Jim_SetResult(interp, Jim_NewReference(interp, argv[1], argv[2], NULL)); } @@ -15309,10 +15213,6 @@ static int Jim_GetrefCoreCommand(Jim_Interp *interp, int argc, Jim_Obj *const *a { Jim_Reference *refPtr; - if (argc != 2) { - Jim_WrongNumArgs(interp, 1, argv, "reference"); - return JIM_ERR; - } if ((refPtr = Jim_GetReference(interp, argv[1])) == NULL) return JIM_ERR; Jim_SetResult(interp, refPtr->objPtr); @@ -15324,10 +15224,6 @@ static int Jim_SetrefCoreCommand(Jim_Interp *interp, int argc, Jim_Obj *const *a { Jim_Reference *refPtr; - if (argc != 3) { - Jim_WrongNumArgs(interp, 1, argv, "reference newValue"); - return JIM_ERR; - } if ((refPtr = Jim_GetReference(interp, argv[1])) == NULL) return JIM_ERR; Jim_IncrRefCount(argv[2]); @@ -15340,10 +15236,6 @@ static int Jim_SetrefCoreCommand(Jim_Interp *interp, int argc, Jim_Obj *const *a /* [collect] */ static int Jim_CollectCoreCommand(Jim_Interp *interp, int argc, Jim_Obj *const *argv) { - if (argc != 1) { - Jim_WrongNumArgs(interp, 1, argv, ""); - return JIM_ERR; - } Jim_SetResultInt(interp, Jim_Collect(interp)); /* Free all the freed objects. */ @@ -15359,10 +15251,6 @@ static int Jim_CollectCoreCommand(Jim_Interp *interp, int argc, Jim_Obj *const * /* [finalize] reference ?newValue? */ static int Jim_FinalizeCoreCommand(Jim_Interp *interp, int argc, Jim_Obj *const *argv) { - if (argc != 2 && argc != 3) { - Jim_WrongNumArgs(interp, 1, argv, "reference ?finalizerProc?"); - return JIM_ERR; - } if (argc == 2) { Jim_Obj *cmdNamePtr; @@ -15405,11 +15293,6 @@ static int JimInfoReferences(Jim_Interp *interp, int argc, Jim_Obj *const *argv) /* [rename] */ static int Jim_RenameCoreCommand(Jim_Interp *interp, int argc, Jim_Obj *const *argv) { - if (argc != 3) { - Jim_WrongNumArgs(interp, 1, argv, "oldName newName"); - return JIM_ERR; - } - return Jim_RenameCommand(interp, argv[1], argv[2]); } @@ -15744,10 +15627,6 @@ static int Jim_SubstCoreCommand(Jim_Interp *interp, int argc, Jim_Obj *const *ar int flags = JIM_SUBST_FLAG; Jim_Obj *objPtr; - if (argc < 2) { - Jim_WrongNumArgs(interp, 1, argv, "?options? string"); - return JIM_ERR; - } for (i = 1; i < (argc - 1); i++) { int option; @@ -15792,6 +15671,7 @@ static int Jim_InfoCoreCommand(Jim_Interp *interp, int argc, Jim_Obj *const *arg /* Must be kept in order with the array below */ enum { INFO_ALIAS, + INFO_ALIASES, INFO_ARGS, INFO_BODY, INFO_CHANNELS, @@ -15800,6 +15680,7 @@ static int Jim_InfoCoreCommand(Jim_Interp *interp, int argc, Jim_Obj *const *arg INFO_EXISTS, INFO_FRAME, INFO_GLOBALS, + INFO_HELP, INFO_HOSTNAME, INFO_LEVEL, INFO_LOCALS, @@ -15813,12 +15694,14 @@ static int Jim_InfoCoreCommand(Jim_Interp *interp, int argc, Jim_Obj *const *arg INFO_STACKTRACE, INFO_STATICS, INFO_TAINTED, + INFO_USAGE, INFO_VARS, INFO_VERSION, INFO_COUNT }; static const jim_subcmd_type cmds[INFO_COUNT + 1] = { JIM_DEF_SUBCMD("alias", "command", 1, 1), + JIM_DEF_SUBCMD("aliases", "?-all? ?pattern?", 0, 2), JIM_DEF_SUBCMD("args", "procname", 1, 1), JIM_DEF_SUBCMD("body", "procname", 1, 1), JIM_DEF_SUBCMD("channels", "?pattern?", 0, 1), @@ -15827,6 +15710,7 @@ static int Jim_InfoCoreCommand(Jim_Interp *interp, int argc, Jim_Obj *const *arg JIM_DEF_SUBCMD("exists", "varName", 1, 1), JIM_DEF_SUBCMD("frame", "?levelNum?", 0, 1), JIM_DEF_SUBCMD("globals", "?pattern?", 0, 1), + JIM_DEF_SUBCMD("help", "command", 1, 1), JIM_DEF_SUBCMD("hostname", NULL, 0, 0), JIM_DEF_SUBCMD("level", "?levelNum?", 0, 1), JIM_DEF_SUBCMD("locals", "?pattern?", 0, 1), @@ -15839,7 +15723,8 @@ static int Jim_InfoCoreCommand(Jim_Interp *interp, int argc, Jim_Obj *const *arg JIM_DEF_SUBCMD("source", "source ?filename line?", 1, 3), JIM_DEF_SUBCMD("stacktrace", NULL, 0, 0), JIM_DEF_SUBCMD("statics", "procname", 1, 1), - JIM_DEF_SUBCMD("tainted", "str", 1, 1), + JIM_DEF_SUBCMD("tainted", "value", 1, 1), + JIM_DEF_SUBCMD("usage", "command", 1, 1), JIM_DEF_SUBCMD("vars", "?pattern?", 0, 1), JIM_DEF_SUBCMD("version", NULL, 0, 0), { NULL } @@ -15877,7 +15762,7 @@ static int Jim_InfoCoreCommand(Jim_Interp *interp, int argc, Jim_Obj *const *arg if ((cmdPtr = Jim_GetCommand(interp, argv[2], JIM_ERRMSG)) == NULL) { return JIM_ERR; } - if (cmdPtr->isproc || cmdPtr->u.native.cmdProc != JimAliasCmd) { + if ((cmdPtr->flags & JIM_CMD_ISALIAS) == 0) { Jim_SetResultFormatted(interp, "command \"%#s\" is not an alias", argv[2]); return JIM_ERR; } @@ -15899,6 +15784,9 @@ static int Jim_InfoCoreCommand(Jim_Interp *interp, int argc, Jim_Obj *const *arg return JIM_ERR; #endif /* fall through */ + case INFO_ALIASES: + mode <<= 1; /* JIM_CMDLIST_ALIASES */ + /* fall through */ case INFO_PROCS: mode++; /* JIM_CMDLIST_PROCS */ /* fall through */ @@ -15906,6 +15794,7 @@ static int Jim_InfoCoreCommand(Jim_Interp *interp, int argc, Jim_Obj *const *arg /* mode 0 => JIM_CMDLIST_COMMANDS */ #ifdef jim_ext_namespace if (!nons) { + /* Called as 'info -nons commands|procs' so respect the current namespace */ if (Jim_Length(interp->framePtr->nsObj) || (argc == 3 && JimIsGlobalNamespace(argv[2]))) { return Jim_EvalPrefix(interp, "namespace info", argc - 1, argv + 1); } @@ -15996,6 +15885,27 @@ static int Jim_InfoCoreCommand(Jim_Interp *interp, int argc, Jim_Obj *const *arg } return JIM_OK; + case INFO_USAGE: + case INFO_HELP:{ + Jim_Cmd *cmdPtr = Jim_GetCommand(interp, argv[2], JIM_ERRMSG); + if (!cmdPtr) { + return JIM_ERR; + } + if (option == INFO_USAGE) { + Jim_SetResult(interp, JimCmdUsage(interp, argv[2], cmdPtr)); + return JIM_OK; + } + else if ((cmdPtr->flags & JIM_CMD_ISPROC) == 0) { + if (cmdPtr->u.native.help) { + Jim_SetResultString(interp, cmdPtr->u.native.help, -1); + return JIM_OK; + } + } + /* This isn't an error */ + Jim_SetResultFormatted(interp, "No help available for command \"%#s\"", argv[2]); + return JIM_OK; + } + case INFO_BODY: case INFO_STATICS: case INFO_ARGS:{ @@ -16004,7 +15914,7 @@ static int Jim_InfoCoreCommand(Jim_Interp *interp, int argc, Jim_Obj *const *arg if ((cmdPtr = Jim_GetCommand(interp, argv[2], JIM_ERRMSG)) == NULL) { return JIM_ERR; } - if (!cmdPtr->isproc) { + if ((cmdPtr->flags & JIM_CMD_ISPROC) == 0) { Jim_SetResultFormatted(interp, "command \"%#s\" is not a procedure", argv[2]); return JIM_ERR; } @@ -16106,11 +16016,11 @@ static int Jim_ExistsCoreCommand(Jim_Interp *interp, int argc, Jim_Obj *const *a int result = 0; static const char * const options[] = { - "-command", "-proc", "-alias", "-var", NULL + "-command", "-proc", "-alias", "-channel", "-var", NULL }; enum { - OPT_COMMAND, OPT_PROC, OPT_ALIAS, OPT_VAR + OPT_COMMAND, OPT_PROC, OPT_ALIAS, OPT_CHANNEL, OPT_VAR }; int option; @@ -16125,8 +16035,7 @@ static int Jim_ExistsCoreCommand(Jim_Interp *interp, int argc, Jim_Obj *const *a objPtr = argv[2]; } else { - Jim_WrongNumArgs(interp, 1, argv, "?option? name"); - return JIM_ERR; + return JIM_USAGE; } if (option == OPT_VAR) { @@ -16143,11 +16052,15 @@ static int Jim_ExistsCoreCommand(Jim_Interp *interp, int argc, Jim_Obj *const *a break; case OPT_ALIAS: - result = cmd->isproc == 0 && cmd->u.native.cmdProc == JimAliasCmd; + result = (cmd->flags & JIM_CMD_ISALIAS) != 0; break; case OPT_PROC: - result = cmd->isproc; + result = (cmd->flags & JIM_CMD_ISPROC) != 0; + break; + + case OPT_CHANNEL: + result = (cmd->flags & JIM_CMD_ISCHANNEL) != 0; break; } } @@ -16165,11 +16078,6 @@ static int Jim_SplitCoreCommand(Jim_Interp *interp, int argc, Jim_Obj *const *ar int c; int len; - if (argc != 2 && argc != 3) { - Jim_WrongNumArgs(interp, 1, argv, "string ?splitChars?"); - return JIM_ERR; - } - str = Jim_GetString(argv[1], &len); if (len == 0) { return JIM_OK; @@ -16251,10 +16159,6 @@ static int Jim_JoinCoreCommand(Jim_Interp *interp, int argc, Jim_Obj *const *arg const char *joinStr; int joinStrLen; - if (argc != 2 && argc != 3) { - Jim_WrongNumArgs(interp, 1, argv, "list ?joinString?"); - return JIM_ERR; - } /* Init */ if (argc == 2) { joinStr = " "; @@ -16272,10 +16176,6 @@ static int Jim_FormatCoreCommand(Jim_Interp *interp, int argc, Jim_Obj *const *a { Jim_Obj *objPtr; - if (argc < 2) { - Jim_WrongNumArgs(interp, 1, argv, "formatString ?arg arg ...?"); - return JIM_ERR; - } objPtr = Jim_FormatString(interp, argv[1], argc - 2, argv + 2); if (objPtr == NULL) return JIM_ERR; @@ -16289,10 +16189,6 @@ static int Jim_ScanCoreCommand(Jim_Interp *interp, int argc, Jim_Obj *const *arg Jim_Obj *listPtr, **outVec; int outc, i; - if (argc < 3) { - Jim_WrongNumArgs(interp, 1, argv, "string format ?varName varName ...?"); - return JIM_ERR; - } if (argv[2]->typePtr != &scanFmtStringObjType) SetScanFmtFromAny(interp, argv[2]); if (FormatGetError(argv[2]) != 0) { @@ -16362,10 +16258,6 @@ static int Jim_ScanCoreCommand(Jim_Interp *interp, int argc, Jim_Obj *const *arg /* [error] */ static int Jim_ErrorCoreCommand(Jim_Interp *interp, int argc, Jim_Obj *const *argv) { - if (argc != 2 && argc != 3) { - Jim_WrongNumArgs(interp, 1, argv, "message ?stacktrace?"); - return JIM_ERR; - } Jim_SetResult(interp, argv[1]); if (argc == 3) { JimSetStackTrace(interp, argv[2]); @@ -16379,10 +16271,6 @@ static int Jim_LrangeCoreCommand(Jim_Interp *interp, int argc, Jim_Obj *const *a { Jim_Obj *objPtr; - if (argc != 4) { - Jim_WrongNumArgs(interp, 1, argv, "list first last"); - return JIM_ERR; - } if ((objPtr = Jim_ListRange(interp, argv[1], argv[2], argv[3])) == NULL) return JIM_ERR; Jim_SetResult(interp, objPtr); @@ -16396,8 +16284,7 @@ static int Jim_LrepeatCoreCommand(Jim_Interp *interp, int argc, Jim_Obj *const * jim_wide count; if (argc < 2 || Jim_GetWideExpr(interp, argv[1], &count) != JIM_OK || count < 0) { - Jim_WrongNumArgs(interp, 1, argv, "count ?value ...?"); - return JIM_ERR; + return JIM_USAGE; } if (count == 0 || argc == 2) { Jim_SetEmptyResult(interp); @@ -16472,10 +16359,6 @@ static int Jim_EnvCoreCommand(Jim_Interp *interp, int argc, Jim_Obj *const *argv return JIM_OK; } - if (argc > 3) { - Jim_WrongNumArgs(interp, 1, argv, "varName ?default?"); - return JIM_ERR; - } key = Jim_String(argv[1]); val = getenv(key); if (val == NULL) { @@ -16492,18 +16375,7 @@ static int Jim_EnvCoreCommand(Jim_Interp *interp, int argc, Jim_Obj *const *argv /* [source] */ static int Jim_SourceCoreCommand(Jim_Interp *interp, int argc, Jim_Obj *const *argv) { - int retval; - - if (Jim_CheckTaint(interp, JIM_TAINT_ANY)) { - Jim_SetTaintError(interp, 1, argv); - return JIM_ERR; - } - - if (argc != 2) { - Jim_WrongNumArgs(interp, 1, argv, "fileName"); - return JIM_ERR; - } - retval = Jim_EvalFile(interp, Jim_String(argv[1])); + int retval = Jim_EvalFile(interp, Jim_String(argv[1])); return retval == JIM_RETURN ? JIM_OK : retval; } @@ -16514,10 +16386,6 @@ static int Jim_LreverseCoreCommand(Jim_Interp *interp, int argc, Jim_Obj *const Jim_Obj *revObjPtr, **ele; int len; - if (argc != 2) { - Jim_WrongNumArgs(interp, 1, argv, "list"); - return JIM_ERR; - } JimListGetElements(interp, argv[1], &len, &ele); revObjPtr = Jim_NewListObj(interp, NULL, 0); ListEnsureLength(revObjPtr, len); @@ -16561,10 +16429,6 @@ static int Jim_RangeCoreCommand(Jim_Interp *interp, int argc, Jim_Obj *const *ar int len, i; Jim_Obj *objPtr; - if (argc < 2 || argc > 4) { - Jim_WrongNumArgs(interp, 1, argv, "?start? end ?step?"); - return JIM_ERR; - } if (argc == 2) { if (Jim_GetWideExpr(interp, argv[1], &end) != JIM_OK) return JIM_ERR; @@ -16593,10 +16457,6 @@ static int Jim_RandCoreCommand(Jim_Interp *interp, int argc, Jim_Obj *const *arg { jim_wide min = 0, max = 0, len, maxMul; - if (argc < 1 || argc > 3) { - Jim_WrongNumArgs(interp, 1, argv, "?min? max"); - return JIM_ERR; - } if (argc == 1) { max = JIM_WIDE_MAX; } else if (argc == 2) { @@ -16624,101 +16484,109 @@ static int Jim_RandCoreCommand(Jim_Interp *interp, int argc, Jim_Obj *const *arg } } -static const struct { +static const struct jim_core_cmd_def_t { const char *name; Jim_CmdProc *cmdProc; + short minargs; + short maxargs; + const char *usage; + int flags; } Jim_CoreCommandsTable[] = { - {"alias", Jim_AliasCoreCommand}, - {"set", Jim_SetCoreCommand}, - {"unset", Jim_UnsetCoreCommand}, - {"puts", Jim_PutsCoreCommand}, - {"+", Jim_AddCoreCommand}, - {"*", Jim_MulCoreCommand}, - {"-", Jim_SubCoreCommand}, - {"/", Jim_DivCoreCommand}, - {"incr", Jim_IncrCoreCommand}, - {"while", Jim_WhileCoreCommand}, - {"loop", Jim_LoopCoreCommand}, - {"for", Jim_ForCoreCommand}, - {"foreach", Jim_ForeachCoreCommand}, - {"lmap", Jim_LmapCoreCommand}, - {"lassign", Jim_LassignCoreCommand}, - {"if", Jim_IfCoreCommand}, - {"switch", Jim_SwitchCoreCommand}, - {"list", Jim_ListCoreCommand}, - {"lindex", Jim_LindexCoreCommand}, - {"lset", Jim_LsetCoreCommand}, - {"lsearch", Jim_LsearchCoreCommand}, - {"llength", Jim_LlengthCoreCommand}, - {"lappend", Jim_LappendCoreCommand}, - {"linsert", Jim_LinsertCoreCommand}, - {"lreplace", Jim_LreplaceCoreCommand}, - {"lsort", Jim_LsortCoreCommand}, - {"append", Jim_AppendCoreCommand}, + {"*", Jim_MulCoreCommand, 0, -1, "?number ...?" }, + {"+", Jim_AddCoreCommand, 0, -1, "?number ...?" }, + {"-", Jim_SubCoreCommand, 1, -1, "number ?number ...?" }, + {"/", Jim_DivCoreCommand, 1, -1, "number ?number ...?" }, + {"alias", Jim_AliasCoreCommand, 2, -1, "newname command ?args ...?" }, + {"append", Jim_AppendCoreCommand, 1, -1, "varName ?value ...?" }, + {"apply", Jim_ApplyCoreCommand, 1, -1, "lambdaExpr ?arg ...?" }, + {"break", Jim_BreakCoreCommand, 0, 1, "?level?" }, + {"catch", Jim_CatchCoreCommand, 1, -1, "?-?no?code ... --? script ?resultVarName? ?optionVarName?" }, + {"concat", Jim_ConcatCoreCommand, 0, -1, "?arg ...?" }, + {"continue", Jim_ContinueCoreCommand, 0, 1, "?level?" }, #if defined(JIM_DEBUG_COMMAND) && !defined(JIM_BOOTSTRAP) - {"debug", Jim_DebugCoreCommand}, + {"debug", Jim_DebugCoreCommand, 1, -1, "subcommand ?arg ...?" }, #endif /* JIM_DEBUG_COMMAND && !JIM_BOOTSTRAP */ - {"eval", Jim_EvalCoreCommand}, - {"uplevel", Jim_UplevelCoreCommand}, - {"expr", Jim_ExprCoreCommand}, - {"break", Jim_BreakCoreCommand}, - {"continue", Jim_ContinueCoreCommand}, - {"proc", Jim_ProcCoreCommand}, - {"xtrace", Jim_XtraceCoreCommand}, - {"concat", Jim_ConcatCoreCommand}, - {"return", Jim_ReturnCoreCommand}, - {"upvar", Jim_UpvarCoreCommand}, - {"global", Jim_GlobalCoreCommand}, - {"string", Jim_StringCoreCommand}, - {"time", Jim_TimeCoreCommand}, - {"timerate", Jim_TimeRateCoreCommand}, - {"exit", Jim_ExitCoreCommand}, - {"catch", Jim_CatchCoreCommand}, - {"try", Jim_TryCoreCommand}, + {"dict", Jim_DictCoreCommand, 1, -1, "subcommand ?arg ...?"}, + {"env", Jim_EnvCoreCommand, 0, 2, "?varName? ?default?" }, + {"error", Jim_ErrorCoreCommand, 1, 2, "message ?stacktrace?" }, + {"eval", Jim_EvalCoreCommand, 1, -1, "arg ?arg ...?" }, + {"exists", Jim_ExistsCoreCommand, 1, 2, "?-command|-proc|-alias|-channel|-var? name" }, + {"exit", Jim_ExitCoreCommand, 0, 1, "?exitCode?" }, +#ifndef JIM_COMPAT + {"expr", Jim_ExprCoreCommand, 1, -1, "expression ?...?" }, +#else + {"expr", Jim_ExprCoreCommand, 1, 1, "expression" }, +#endif + {"for", Jim_ForCoreCommand, 4, 4, "start test next body" }, + {"foreach", Jim_ForeachCoreCommand, 3, -1, "varList list ?varList list ...? script" }, + {"format", Jim_FormatCoreCommand, 1, -1, "formatString ?arg arg ...?" }, + {"global", Jim_GlobalCoreCommand, 1, -1, "varName ?varName ...?" }, + {"if", Jim_IfCoreCommand, 2, -1, "condition ?then? trueBody ?elseif ...? ?else? ?falseBody?" }, + {"incr", Jim_IncrCoreCommand, 1, 2, "varName ?increment?" }, + {"info", Jim_InfoCoreCommand, 1, -1, "subcommand ?arg ...?"}, + {"join", Jim_JoinCoreCommand, 1, 2, "list ?joinString?" }, + {"lappend", Jim_LappendCoreCommand, 1, -1, "varName ?value value ...?" }, + {"lassign", Jim_LassignCoreCommand, 2, -1, "varList list ?varName ...?" }, + {"lindex", Jim_LindexCoreCommand, 1, -1, "list ?index ...?" }, + {"linsert", Jim_LinsertCoreCommand, 2, -1, "list index ?element ...?" }, + {"list", Jim_ListCoreCommand, 0, -1, "?arg ...?" }, + {"llength", Jim_LlengthCoreCommand, 1, 1, "list" }, + {"lmap", Jim_LmapCoreCommand, 3, -1, "varList list ?varList list ...? script" }, + {"local", Jim_LocalCoreCommand, 1, -1, "cmd ?args ...?" }, + {"loop", Jim_LoopCoreCommand, 3, 5, "var ?first? limit ?incr? body" }, + {"lrange", Jim_LrangeCoreCommand, 3, 3, "list first last" }, + {"lrepeat", Jim_LrepeatCoreCommand, 1, -1, "count ?value ...?" }, + {"lreplace", Jim_LreplaceCoreCommand, 3, -1, "list first last ?element ...?" }, + {"lreverse", Jim_LreverseCoreCommand, 1, 1, "list" }, + {"lsearch", Jim_LsearchCoreCommand, 2, -1, "?-exact|-glob|-regexp|-command 'command'? ?-bool|-inline? ?-not? ?-nocase? ?-all? ?-stride len? ?-index val? list value" }, + {"lset", Jim_LsetCoreCommand, 2, -1, "listVar ?index ...? value" }, + {"lsort", Jim_LsortCoreCommand, 1, -1, "?options? list" }, + {"proc", Jim_ProcCoreCommand, 3, 4, "name arglist ?statics? body" }, + {"puts", Jim_PutsCoreCommand, 1, 2, "?-nonewline? string" }, + {"rand", Jim_RandCoreCommand, 0, 2, "?min? ?max?" }, + {"range", Jim_RangeCoreCommand, 1, 3, "?start? end ?step?" }, + {"rename", Jim_RenameCoreCommand, 2, 2, "oldName newName" }, + {"return", Jim_ReturnCoreCommand, 0, -1, "?-code code? ?-errorinfo stacktrace? ?-level level? ?result?" }, + {"scan", Jim_ScanCoreCommand, 2, -1, "string format ?varName varName ...?" }, + {"set", Jim_SetCoreCommand, 1, 2, "varName ?newValue?" }, + {"source", Jim_SourceCoreCommand, 1, 1, "fileName", JIM_CMD_NOTAINT }, + {"split", Jim_SplitCoreCommand, 1, 2, "string ?splitChars?" }, + {"stacktrace", Jim_StacktraceCoreCommand, 0, 2, "?firstlevel? ?lastlevel?" }, + {"string", Jim_StringCoreCommand, 1, -1, "subcommand ?arg ...?" }, + {"subst", Jim_SubstCoreCommand, 1, 4, "?options? string" }, + {"switch", Jim_SwitchCoreCommand, 2, -1, "?options? string pattern body ... ?default body? or pattern body ?pattern body ...?" }, + {"tailcall", Jim_TailcallCoreCommand, 0, -1, "?cmd arg ...?" }, + {"time", Jim_TimeCoreCommand, 1, 2, "script ?count?" }, + {"timerate", Jim_TimerateCoreCommand, 1, 2, "script ?milliseconds?" }, + {"try", Jim_TryCoreCommand, 1, -1, "?-?no?code ... --? script ?on|trap codes vars script? ... ?finally script?" }, + {"unset", Jim_UnsetCoreCommand, 0, -1, "?-nocomplain? ?--? ?varName ...?"}, + {"upcall", Jim_UpcallCoreCommand, 1, -1, "cmd ?args ...?" }, + {"uplevel", Jim_UplevelCoreCommand, 1, -1, "?level? command ?arg ...?" }, + {"upvar", Jim_UpvarCoreCommand, 2, -1, "?level? otherVar myVar ?otherVar myVar ...?"}, + {"while", Jim_WhileCoreCommand, 2, 2, "condition body" }, + {"xtrace", Jim_XtraceCoreCommand, 1, 1, "callback" }, #ifdef JIM_REFERENCES - {"ref", Jim_RefCoreCommand}, - {"getref", Jim_GetrefCoreCommand}, - {"setref", Jim_SetrefCoreCommand}, - {"finalize", Jim_FinalizeCoreCommand}, - {"collect", Jim_CollectCoreCommand}, + {"collect", Jim_CollectCoreCommand, 0, 0, "" }, + {"finalize", Jim_FinalizeCoreCommand, 1, 2, "reference ?finalizerProc?" }, + {"getref", Jim_GetrefCoreCommand, 1, 1, "reference" }, + {"ref", Jim_RefCoreCommand, 2, 3, "string tag ?finalizer?" }, + {"setref", Jim_SetrefCoreCommand, 2, 2, "reference newValue" }, #endif - {"rename", Jim_RenameCoreCommand}, - {"dict", Jim_DictCoreCommand}, - {"subst", Jim_SubstCoreCommand}, - {"info", Jim_InfoCoreCommand}, - {"exists", Jim_ExistsCoreCommand}, - {"split", Jim_SplitCoreCommand}, - {"join", Jim_JoinCoreCommand}, - {"format", Jim_FormatCoreCommand}, - {"scan", Jim_ScanCoreCommand}, - {"error", Jim_ErrorCoreCommand}, - {"lrange", Jim_LrangeCoreCommand}, - {"lrepeat", Jim_LrepeatCoreCommand}, - {"env", Jim_EnvCoreCommand}, - {"source", Jim_SourceCoreCommand}, - {"lreverse", Jim_LreverseCoreCommand}, - {"range", Jim_RangeCoreCommand}, - {"rand", Jim_RandCoreCommand}, - {"tailcall", Jim_TailcallCoreCommand}, - {"local", Jim_LocalCoreCommand}, - {"upcall", Jim_UpcallCoreCommand}, - {"apply", Jim_ApplyCoreCommand}, - {"stacktrace", Jim_StacktraceCoreCommand}, #ifdef JIM_TAINT - {"taint", Jim_TaintCoreCommand}, - {"untaint", Jim_UntaintCoreCommand}, + {"taint", Jim_TaintCoreCommand, 1, 1, "varname"}, + {"untaint", Jim_UntaintCoreCommand, 1, 1, "varname"}, #endif {NULL, NULL}, }; void Jim_RegisterCoreCommands(Jim_Interp *interp) { - int i = 0; + const struct jim_core_cmd_def_t *c; - while (Jim_CoreCommandsTable[i].name != NULL) { - Jim_CreateCommand(interp, - Jim_CoreCommandsTable[i].name, Jim_CoreCommandsTable[i].cmdProc, NULL, NULL); - i++; + for (c = Jim_CoreCommandsTable; c->name; c++) { + /* All core commands must have usage */ + assert(c->usage); + Jim_RegisterCmd(interp, c->name, c->usage, c->minargs, c->maxargs, c->cmdProc, NULL, NULL, c->flags); } } @@ -127,6 +127,7 @@ extern "C" { /* Increment this every time the public ABI changes */ #define JIM_ABI_VERSION 102 +/* Tcl return codes */ #define JIM_OK 0 #define JIM_ERR 1 #define JIM_RETURN 2 @@ -134,6 +135,8 @@ extern "C" { #define JIM_CONTINUE 4 #define JIM_SIGNAL 5 #define JIM_EXIT 6 +/* Special meaning */ +#define JIM_USAGE -1 /* Throw a usage error */ /* The following are internal codes and should never been seen/used */ #define JIM_EVAL 7 /* tailcall */ @@ -501,12 +504,21 @@ typedef struct Jim_Dict { unsigned int dummy; /* Number of dummy entries */ } Jim_Dict; +#define JIM_CMD_ISPROC 1 +#define JIM_CMD_ISCHANNEL 2 +#define JIM_CMD_ISALIAS 4 + +/* When a command is registered with this flag, it can't be called with + * tainted data + */ +#define JIM_CMD_NOTAINT 0x100 + /* A command is implemented in C if isproc is 0, otherwise * it is a Tcl procedure with the arglist and body represented by the * two objects referenced by arglistObjPtr and bodyObjPtr. */ typedef struct Jim_Cmd { int inUse; /* Reference count */ - int isproc; /* Is this a procedure? */ + int flags; /* JIM_CMD_XXX */ struct Jim_Cmd *prevCmd; /* Previous command defn if cmd created 'local' */ Jim_Obj *cmdNameObj; /* The fully resolved command name - just a pointer, not a reference */ union { @@ -515,6 +527,10 @@ typedef struct Jim_Cmd { Jim_CmdProc *cmdProc; /* The command implementation */ Jim_DelCmdProc *delProc; /* Called when the command is deleted if != NULL */ void *privData; /* command-private data available via Jim_CmdPrivData() */ + const char *usage; /* If not NULL, usage text - used by 'info usage' */ + const char *help; /* If not NULL, help text - used by 'info help' */ + short minargs; + short maxargs; /* -1 for unlimited */ } native; struct { /* Tcl procedure */ @@ -793,10 +809,29 @@ JIM_EXPORT const char *Jim_ReturnCode(int code); JIM_EXPORT void Jim_SetResultFormatted(Jim_Interp *interp, const char *format, ...); /* commands */ -JIM_EXPORT void Jim_RegisterCoreCommands (Jim_Interp *interp); +JIM_EXPORT Jim_Cmd *Jim_RegisterCommand(Jim_Interp *interp, Jim_Obj *cmdNameObj, + Jim_CmdProc *cmdProc, + Jim_DelCmdProc *delProc, + const char *usage, + const char *help, + short minargs, + short maxargs, + int flags, + void *privData); +/* This is a this wrapper around Jim_RegisterCommand */ JIM_EXPORT int Jim_CreateCommand (Jim_Interp *interp, const char *cmdName, Jim_CmdProc *cmdProc, void *privData, Jim_DelCmdProc *delProc); +/* Simplify creating commands that specify minargs, maxargs and usage but + * don't need delProc or privData + */ +#define Jim_RegisterSimpleCmd(interp, name, usage, minargs, maxargs, cmdproc) \ + Jim_RegisterCommand(interp, Jim_NewStringObj(interp, name, -1), cmdproc, NULL, usage, NULL, minargs, maxargs, 0, NULL) +/* And also slightly more complex where delProc, privData and flags may be needed */ +#define Jim_RegisterCmd(interp, name, usage, minargs, maxargs, cmdproc, delproc, privdata, flags) \ + Jim_RegisterCommand(interp, Jim_NewStringObj(interp, name, -1), cmdproc, delproc, usage, NULL, minargs, maxargs, flags, privdata) + +JIM_EXPORT void Jim_RegisterCoreCommands (Jim_Interp *interp); JIM_EXPORT int Jim_DeleteCommand (Jim_Interp *interp, Jim_Obj *cmdNameObj); JIM_EXPORT int Jim_RenameCommand (Jim_Interp *interp, diff --git a/jim_tcl.txt b/jim_tcl.txt index 4da4a7a..abd02ea 100644 --- a/jim_tcl.txt +++ b/jim_tcl.txt @@ -329,7 +329,7 @@ has three fields: the first, `set`, is the name of a Tcl command, and the last two, 'a' and '22', will be passed as arguments to the `set` command. The command name may refer either to a built-in Tcl command, an application-specific command bound in with the library -procedure 'Jim_CreateCommand', or a command procedure defined with the +procedure 'Jim_RegisterCommand', or a command procedure defined with the `proc` built-in command. Arguments are passed literally as text strings. Individual commands may @@ -1209,6 +1209,10 @@ defined in jim.h, and are: Indicates that the command called the `exit` command. The string contains the exit code. ++JIM_USAGE(-1)+:: + This is a special return code that is automatically translated into JIM_ERR with the command usage + (from Jim_RegisterCommand()) as the message. + Tcl programmers do not normally need to think about return codes, since +JIM_OK+ is almost always returned. If anything else is returned by a command, then the Tcl interpreter immediately stops processing @@ -2476,12 +2480,12 @@ this variable is unset, in which case the original environment is used). exists ~~~~~~ -+*exists ?-var|-proc|-command|-alias?* 'name'+ ++*exists ?-var|-proc|-command|-alias|-channel?* 'name'+ -Checks the existence of the given variable, procedure, command -or alias respectively and returns 1 if it exists or 0 if not. This command +Checks the existence of the given variable, procedure, command, +alias or channel respectively and returns 1 if it exists or 0 if not. This command provides a more simplified/convenient version of `info exists`, -`info procs` and `info commands`. +`info procs`, `info commands`, `info aliases` and `info channels`. If the type is omitted, a type of '-var' is used. The type may be abbreviated. @@ -2929,12 +2933,14 @@ The legal +'option'+'s (which may be abbreviated) are: +*info channels*+:: Returns a list of all open file handles from `open` or `socket` -+*info commands* ?'pattern'?+:: ++*info commands ?-all?* ?'pattern'?+:: If +'pattern'+ isn't specified, returns a list of names of all the Tcl commands, including both the built-in commands written in C and the command procedures defined using the `proc` command. If +'pattern'+ is specified, only those names matching +'pattern'+ (using <<_string_matching,STRING MATCHING>> rules) are returned. + Normally commands containing a space character are not returned. + If +*-all*+ is given, the result does include these commands. +*info complete* 'command' ?'missing'?+:: Returns 1 if +'command'+ is a complete Tcl command in the sense of @@ -3010,11 +3016,13 @@ The legal +'option'+'s (which may be abbreviated) are: was invoked. A full path will be returned, unless the path can't be determined, in which case the empty string will be returned. -+*info procs* ?'pattern'?+:: ++*info procs ?-all?* ?'pattern'?+:: If +'pattern'+ isn't specified, returns a list of all the names of Tcl command procedures. If +'pattern'+ is specified, only those names matching +'pattern'+ (using <<_string_matching,STRING MATCHING>> rules) are returned. + Normally commands containing a space character are not returned. + If +*-all*+ is given, the result does include these commands. +*info references*+:: Returns a list of all references which have not yet been garbage diff --git a/tests/clock.test b/tests/clock.test index 0ef7bb3..26aa17e 100644 --- a/tests/clock.test +++ b/tests/clock.test @@ -5,7 +5,7 @@ constraint cmd {clock scan} test clock-1.1 {clock usage} -body { clock -} -returnCodes error -match glob -result {wrong # args: should be "clock command ..."*} +} -returnCodes error -match glob -result {wrong # args: should be "clock subcommand ?arg ...?"} test clock-1.2 {clock usage} -body { clock blah diff --git a/tests/coverage.test b/tests/coverage.test index 95933a3..48d1a3c 100644 --- a/tests/coverage.test +++ b/tests/coverage.test @@ -175,7 +175,7 @@ test cmd-1 {standard -commands} jim { test rand-1 {rand} -constraints rand -body { rand 1 2 3 -} -returnCodes error -result {wrong # args: should be "rand ?min? max"} +} -returnCodes error -result {wrong # args: should be "rand ?min? ?max?"} test rand-2 {rand} -constraints rand -body { rand foo diff --git a/tests/debug.test b/tests/debug.test index 111cdeb..1e6a3ec 100644 --- a/tests/debug.test +++ b/tests/debug.test @@ -7,7 +7,7 @@ set x 0 test debug-0.1 {debug too few args} -body { debug -} -returnCodes error -match glob -result {wrong # args: should be "debug command ..."*} +} -returnCodes error -match glob -result {wrong # args: should be "debug subcommand ?arg ...?"} test debug-0.2 {debug bad option} -body { debug badoption diff --git a/tests/dict2.test b/tests/dict2.test index 94ba605..57cf069 100644 --- a/tests/dict2.test +++ b/tests/dict2.test @@ -22,9 +22,9 @@ proc dict-sort {dict} { return $result } -test dict-1.1 {dict command basic syntax} -returnCodes error -body { +test dict-1.1 {dict command basic syntax} -body { dict -} -match glob -result {wrong # args: should be "dict command ..."*} +} -returnCodes error -match glob -result {wrong # args: should be "dict subcommand ?arg ...?"} test dict-1.2 {dict command basic syntax} -returnCodes error -body { dict ? } -match glob -result * diff --git a/tests/exists.test b/tests/exists.test index 7531b0c..b46ec26 100644 --- a/tests/exists.test +++ b/tests/exists.test @@ -76,12 +76,28 @@ test exists-1.16 "Exists local lambda" lambda { a } 1 -test exists-1.17 {exists usage} -body { +test exists-1.17 "Exists -channel" { + exists -channel bogus +} 0 + +test exists-1.18 "Exists -channel" { + exists -channel stdout +} 1 + +test exists-1.19 "Exists -channel" { + exists -channel info +} 0 + +test exists-1.20 "Exists -channel" { + exists -channel a +} 0 + +test exists-2.1 {exists usage} -body { exists -dummy blah -} -returnCodes error -result {bad option "-dummy": must be -alias, -command, -proc, or -var} +} -returnCodes error -result {bad option "-dummy": must be -alias, -channel, -command, -proc, or -var} -test exists-1.18 {exists usage} -body { +test exists-2.2 {exists usage} -body { exists abc def ghi -} -returnCodes error -result {wrong # args: should be "exists ?option? name"} +} -returnCodes error -result {wrong # args: should be "exists ?-command|-proc|-alias|-channel|-var? name"} testreport diff --git a/tests/history.test b/tests/history.test index e0ff0e2..f0fa05a 100644 --- a/tests/history.test +++ b/tests/history.test @@ -4,9 +4,8 @@ needs cmd {history save} needs expr "jim::lineedit" {$jim::lineedit} test history-1.1 {history usage} -body { - history -} -returnCodes error -result {wrong # args: should be "history command ..." -Use "history -help ?command?" for help} + history +} -returnCodes error -result {wrong # args: should be "history subcommand ?arg ...?"} test history-1.2 {history -help} -body { history -help diff --git a/tests/jim.test b/tests/jim.test index 16e56fa..eff2c1f 100644 --- a/tests/jim.test +++ b/tests/jim.test @@ -3557,7 +3557,7 @@ catch {unset sum; unset err; unset i} ################################################################################ test env-1.1 {env} -body { env abc def ghi -} -returnCodes error -result {wrong # args: should be "env varName ?default?"} +} -returnCodes error -result {wrong # args: should be "env ?varName? ?default?"} test env-1.2 {env} -body { env DOES_NOT_EXIST abc diff --git a/tests/loadtest.c b/tests/loadtest.c index 138e403..170e056 100644 --- a/tests/loadtest.c +++ b/tests/loadtest.c @@ -17,19 +17,11 @@ static const jim_subcmd_type loadtest_command_table[] = { { NULL } }; -static int loadtest_cmd(Jim_Interp *interp, int argc, Jim_Obj *const *argv) -{ - return Jim_CallSubCmd(interp, Jim_ParseSubCmd(interp, loadtest_command_table, argc, argv), argc, argv); -} - #ifndef NO_ENTRYPOINT int Jim_loadtestInit(Jim_Interp *interp) { - if (Jim_PackageProvide(interp, "loadtest", "1.0", JIM_ERRMSG)) { - return JIM_ERR; - } - - Jim_CreateCommand(interp, "loadtest", loadtest_cmd, 0, 0); + Jim_PackageProvideCheck(interp, "loadtest"); + Jim_RegisterSubCmd(interp, "loadtest", loadtest_command_table, NULL); return JIM_OK; } |