diff options
author | Steve Bennett <steveb@workware.net.au> | 2023-07-01 12:45:36 +1000 |
---|---|---|
committer | Steve Bennett <steveb@workware.net.au> | 2023-08-13 15:05:05 +1000 |
commit | ef0b05c3fa344564529db450bc2638ad45e334a4 (patch) | |
tree | 13803be775cc757928f8cbf0f183ea235520eee6 | |
parent | f976e4e01a9feb5403437bd403e43e9a118b1548 (diff) | |
download | jimtcl-ef0b05c3fa344564529db450bc2638ad45e334a4.zip jimtcl-ef0b05c3fa344564529db450bc2638ad45e334a4.tar.gz jimtcl-ef0b05c3fa344564529db450bc2638ad45e334a4.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.
Signed-off-by: Steve Bennett <steveb@workware.net.au>
-rw-r--r-- | initjimsh.tcl | 19 | ||||
-rw-r--r-- | jim-aio.c | 85 | ||||
-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 | 1032 | ||||
-rw-r--r-- | jim.h | 39 | ||||
-rw-r--r-- | jim_tcl.txt | 12 | ||||
-rw-r--r-- | tests/clock.test | 2 | ||||
-rw-r--r-- | tests/coverage.test | 2 | ||||
-rw-r--r-- | tests/debug.test | 5 | ||||
-rw-r--r-- | tests/dict2.test | 4 | ||||
-rw-r--r-- | tests/exists.test | 2 | ||||
-rw-r--r-- | tests/history.test | 5 | ||||
-rw-r--r-- | tests/jim.test | 2 | ||||
-rw-r--r-- | tests/loadtest.c | 12 |
39 files changed, 606 insertions, 927 deletions
diff --git a/initjimsh.tcl b/initjimsh.tcl index 6fa54c6..d95f4aa 100644 --- a/initjimsh.tcl +++ b/initjimsh.tcl @@ -106,8 +106,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] @@ -129,6 +129,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 } @@ -938,7 +938,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 */ @@ -978,7 +978,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); @@ -1162,7 +1162,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; @@ -1450,7 +1450,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) { @@ -1614,7 +1614,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 */ @@ -1881,7 +1881,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; } @@ -1959,7 +1959,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); @@ -2342,18 +2342,12 @@ static int JimAioOpenCommand(Jim_Interp *interp, int argc, /* filehandles created by open are not tainted by default */ int flags = AIO_NOTAINT; - if (Jim_CheckTaint(interp, JIM_TAINT_ANY)) { - Jim_SetTaintError(interp, 1, argv); - return JIM_ERR; - } - 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?"); - return JIM_ERR; + if (argc > 3 + n) { + return JIM_USAGE; } filename = Jim_String(argv[1]); @@ -2490,7 +2484,11 @@ static AioFile *JimMakeChannel(Jim_Interp *interp, int fd, Jim_Obj *filename, if (!(flags & AIO_NOTAINT)) { JimAioSetTaint(af, JIM_TAINT_STD, JIM_TAINT_STD); } - Jim_CreateCommand(interp, buf, JimAioSubCmdProc, af, JimAioDelProc); + Jim_RegisterCommand(interp, Jim_NewStringObj(interp, buf, -1), + 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 @@ -2533,10 +2531,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 @@ -2547,11 +2541,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; @@ -2608,7 +2597,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; @@ -2617,11 +2605,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 }; @@ -2654,9 +2637,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) { @@ -2676,7 +2657,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) { @@ -2691,7 +2672,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); } @@ -2706,14 +2687,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; @@ -2722,7 +2703,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; @@ -2732,7 +2713,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; @@ -2759,7 +2740,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; @@ -2768,7 +2749,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; @@ -2778,7 +2759,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 @@ -2845,11 +2826,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; @@ -2864,20 +2840,17 @@ static int JimAioLoadSSLCertsCommand(Jim_Interp *interp, int argc, Jim_Obj *cons 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 1b03935..9689aab 100644 --- a/jim-clock.c +++ b/jim-clock.c @@ -212,6 +212,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. @@ -599,8 +594,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; @@ -632,11 +626,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; } @@ -1247,10 +1236,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; } @@ -1110,19 +1110,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, @@ -1151,8 +1139,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; } @@ -281,9 +281,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; @@ -361,7 +359,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; } @@ -419,7 +417,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; @@ -122,20 +122,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 0bdb0a9..492f417 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 c0d1f9e..ae02d1f 100644 --- a/jim-package.c +++ b/jim-package.c @@ -259,6 +259,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 5715b2c..061f989 100644 --- a/jim-readline.c +++ b/jim-readline.c @@ -41,10 +41,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; @@ -55,10 +51,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; } @@ -66,7 +58,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 d7e5770..f91a6db 100644 --- a/jim-redis.c +++ b/jim-redis.c @@ -197,8 +197,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 */ @@ -225,7 +224,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))); @@ -236,6 +235,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 1486c3a..69191b4 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); @@ -371,13 +364,6 @@ int Jim_RegsubCmd(Jim_Interp *interp, int argc, Jim_Obj *const *argv) "-nocase", "-line", "-all", "-start", "--", 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]); @@ -406,7 +392,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; @@ -415,7 +401,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; } regex = SetRegexpFromAny(interp, argv[i], regcomp_flags); @@ -582,7 +568,7 @@ int Jim_RegsubCmd(Jim_Interp *interp, int argc, Jim_Obj *const *argv) 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; } @@ -157,6 +157,7 @@ static int JimSetNewVariable(Jim_HashTable *ht, Jim_Obj *nameObjPtr, Jim_VarVal static Jim_VarVal *JimFindVariable(Jim_HashTable *ht, Jim_Obj *nameObjPtr); static void JimSetErrorStack(Jim_Interp *interp); 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() */ @@ -3831,7 +3832,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); @@ -4100,30 +4101,43 @@ 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) { 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; } - 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) @@ -4244,7 +4258,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() */ @@ -4283,7 +4297,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; @@ -4504,7 +4518,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; @@ -6021,7 +6035,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; } } @@ -10690,10 +10704,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; @@ -10872,12 +10882,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); @@ -11200,7 +11214,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) { @@ -11426,46 +11440,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; + Jim_Obj *usage = Jim_DuplicateObj(interp, cmdNameObj); - for (i = 0; i < cmd->u.proc.argListLen; i++) { - Jim_AppendString(interp, argmsg, " ", 1); - - 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 @@ -11618,6 +11650,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; @@ -11893,6 +11955,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); @@ -11981,30 +12047,32 @@ 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; + } 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); } @@ -12125,10 +12193,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); @@ -12184,11 +12248,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) { @@ -12283,10 +12343,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; @@ -12357,11 +12413,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; @@ -12399,11 +12450,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; @@ -12593,11 +12639,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); @@ -12710,9 +12751,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 */ @@ -12825,11 +12865,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++) { @@ -12855,50 +12890,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; } @@ -12941,12 +12976,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]); @@ -12967,7 +12996,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 { @@ -12977,7 +13006,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; @@ -12987,7 +13016,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]; @@ -13057,10 +13086,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 @@ -13077,10 +13102,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; } @@ -13109,13 +13130,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; @@ -13146,7 +13160,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 */ @@ -13156,13 +13170,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; @@ -13177,7 +13191,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; @@ -13323,10 +13337,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 */ @@ -13354,10 +13364,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); @@ -13385,10 +13391,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; @@ -13428,11 +13430,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; @@ -13461,12 +13459,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; @@ -13513,7 +13505,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; @@ -13587,10 +13579,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) @@ -13715,79 +13703,30 @@ static int Jim_DebugCoreCommand(Jim_Interp *interp, int argc, Jim_Obj *const *ar } case OPT_OBJECTS:{ - Jim_Obj *objPtr, *listObjPtr, *subListObjPtr; + Jim_Obj *objPtr; + int freeobj = 0, liveobj = 0; + char buf[256]; int tainted; tainted = (argc == 3 && Jim_CompareStringImmediate(interp, argv[2], "-taint")); - /* Count the number of free objects. */ - objPtr = interp->freeList; - while (objPtr) { - freeobj++; - objPtr = objPtr->nextObjPtr; - } - /* Count the number of live objects. */ - objPtr = interp->liveList; - while (objPtr) { - liveobj++; - objPtr = objPtr->nextObjPtr; - } - /* Set the result string and return. */ - sprintf(buf, "free %d used %d", freeobj, liveobj); - Jim_SetResultString(interp, buf, -1); - return JIM_OK; - } - else if (option == OPT_OBJECTS) { - Jim_Obj *objPtr, *listObjPtr, *subListObjPtr; - int tainted; - - - tainted = (argc == 3 && Jim_CompareStringImmediate(interp, argv[2], "-taint")); - - /* 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); - } - Jim_SetResult(interp, listObjPtr); - return JIM_OK; - } - else if (option == OPT_INVSTR) { - Jim_Obj *objPtr; ->>>>>>> core: taint support - - /* Count the number of live objects. */ - objPtr = interp->liveList; - listObjPtr = Jim_NewListObj(interp, NULL, 0); + /* Count the number of free objects. */ + objPtr = interp->freeList; while (objPtr) { - char buf[128]; - const char *type = objPtr->typePtr ? objPtr->typePtr->name : ""; - - 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); + freeobj++; objPtr = objPtr->nextObjPtr; } - Jim_SetResult(interp, listObjPtr); + /* Count the number of live objects. */ + for (objPtr = interp->liveList; objPtr; objPtr = objPtr->nextObjPtr) { + if ((tainted && !objPtr->taint)) { + continue; + } + liveobj++; + } + /* Set the result string and return. */ + sprintf(buf, "free %d used %d", freeobj, liveobj); + Jim_SetResultString(interp, buf, -1); return JIM_OK; } - case OPT_INVSTR:{ Jim_Obj *objPtr = argv[2]; if (objPtr->typePtr != NULL) @@ -13795,7 +13734,6 @@ static int Jim_DebugCoreCommand(Jim_Interp *interp, int argc, Jim_Obj *const *ar Jim_SetEmptyResult(interp); return JIM_OK; } -<<<<<<< HEAD case OPT_SHOW:{ const char *s; @@ -13812,28 +13750,11 @@ static int Jim_DebugCoreCommand(Jim_Interp *interp, int argc, Jim_Obj *const *ar charlen = len; #endif char buf[256]; - snprintf(buf, sizeof(buf), "refcount: %d, type: %s\n" + snprintf(buf, sizeof(buf), "refcount: %d, taint: %d, type: %s\n" "chars (%d):", - argv[2]->refCount, JimObjTypeName(argv[2]), charlen); + argv[2]->refCount, argv[2]->taint, JimObjTypeName(argv[2]), charlen); Jim_SetResultFormatted(interp, "%s <<%s>>\n", buf, s); snprintf(buf, sizeof(buf), "bytes (%d):", len); -======= - s = Jim_GetString(argv[2], &len); -#ifdef JIM_UTF8 - charlen = utf8_strlen(s, len); -#else - charlen = len; -#endif - char buf[256]; - snprintf(buf, sizeof(buf), "refcount: %d, taint: %d, type: %s\n" - "chars (%d):", - argv[2]->refCount, argv[2]->taint, JimObjTypeName(argv[2]), charlen); - Jim_SetResultFormatted(interp, "%s <<%s>>\n", buf, s); - snprintf(buf, sizeof(buf), "bytes (%d):", len); - Jim_AppendString(interp, Jim_GetResult(interp), buf, -1); - while (len--) { - snprintf(buf, sizeof(buf), " %02x", (unsigned char)*s++); ->>>>>>> core: taint support Jim_AppendString(interp, Jim_GetResult(interp), buf, -1); while (len--) { snprintf(buf, sizeof(buf), " %02x", (unsigned char)*s++); @@ -13878,11 +13799,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]); } @@ -13896,46 +13812,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] */ @@ -13946,13 +13855,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); @@ -13960,20 +13863,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); @@ -14061,8 +13955,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 */ @@ -14136,18 +14029,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] */ @@ -14155,11 +14042,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); } @@ -14186,11 +14068,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; @@ -14209,11 +14086,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); @@ -14241,83 +14113,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 @@ -14404,8 +14264,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: */ @@ -14421,10 +14280,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... */ @@ -14541,7 +14396,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), @@ -14859,10 +14714,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; @@ -14891,7 +14742,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; @@ -14900,10 +14751,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; @@ -14960,10 +14807,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; @@ -14992,10 +14835,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; @@ -15048,7 +14887,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) { @@ -15062,9 +14901,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) { @@ -15107,12 +14944,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) { @@ -15144,7 +14981,7 @@ wrongargs: break; case TRY_FINALLY: if (idx + 2 != argc) { - goto wrongargs; + return JIM_USAGE; } finallyScriptObj = argv[idx + 1]; idx += 2; @@ -15253,10 +15090,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)); } @@ -15271,10 +15104,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); @@ -15286,10 +15115,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]); @@ -15302,10 +15127,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. */ @@ -15321,10 +15142,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; @@ -15367,11 +15184,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]); } @@ -15706,10 +15518,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; @@ -15762,6 +15570,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, @@ -15775,6 +15584,7 @@ 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 @@ -15789,6 +15599,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), @@ -15802,6 +15613,7 @@ static int Jim_InfoCoreCommand(Jim_Interp *interp, int argc, Jim_Obj *const *arg JIM_DEF_SUBCMD("stacktrace", NULL, 0, 0), JIM_DEF_SUBCMD("statics", "procname", 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 terminator */ } @@ -15839,7 +15651,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; } @@ -15869,8 +15681,9 @@ static int Jim_InfoCoreCommand(Jim_Interp *interp, int argc, Jim_Obj *const *arg /* mode 0 => JIM_CMDLIST_COMMANDS */ #ifdef jim_ext_namespace if (!nons) { - if (Jim_Length(interp->framePtr->nsObj) || (argc == 3 && JimIsGlobalNamespace(argv[2]))) { - return Jim_EvalPrefix(interp, "namespace info", argc - 1, argv + 1); + /* Called as 'info -nons commands|procs' so respect the current namespace */ + if (Jim_Length(interp->framePtr->nsObj) || (argc == 3 + n && JimIsGlobalNamespace(argv[2 + n]))) { + return Jim_EvalPrefix(interp, "namespace info", argc - (1 + n), argv + (1 + n)); } } #endif @@ -15970,6 +15783,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)); + } + else { + if (cmdPtr->u.native.help) { + Jim_SetResultString(interp, cmdPtr->u.native.help, -1); + } + else { + /* 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:{ @@ -15978,7 +15812,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)) { Jim_SetResultFormatted(interp, "command \"%#s\" is not a procedure", argv[2]); return JIM_ERR; } @@ -16100,8 +15934,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) { @@ -16118,11 +15951,11 @@ 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); break; case OPT_PROC: - result = cmd->isproc; + result = !!(cmd->flags & JIM_CMD_ISPROC); break; } } @@ -16140,11 +15973,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; @@ -16226,10 +16054,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 = " "; @@ -16247,10 +16071,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; @@ -16264,10 +16084,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) { @@ -16337,10 +16153,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]); @@ -16354,10 +16166,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); @@ -16371,8 +16179,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); @@ -16444,10 +16251,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) { @@ -16464,18 +16267,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; } @@ -16486,10 +16278,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); @@ -16533,10 +16321,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; @@ -16565,10 +16349,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) { @@ -16596,101 +16376,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|-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 101 +/* 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 */ @@ -502,12 +505,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 { @@ -516,6 +528,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 */ @@ -792,10 +808,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 83dd9c8..538eebc 100644 --- a/jim_tcl.txt +++ b/jim_tcl.txt @@ -1232,6 +1232,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 @@ -2888,12 +2892,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 @@ -2969,11 +2975,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..513ab3e 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 @@ -34,7 +34,8 @@ test debug-2.2 {debug objcount too many args} -body { } -returnCodes error -result {wrong # args: should be "debug objcount"} test debug-3.1 {debug objects} -body { - expr {[llength [debug objects]] > 1000} + set dict [debug objects] + expr {$dict(used) > 100} } -result {1} # does not currently check for too many args 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..05dec2a 100644 --- a/tests/exists.test +++ b/tests/exists.test @@ -82,6 +82,6 @@ test exists-1.17 {exists usage} -body { test exists-1.18 {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|-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; } |