aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--jim.c88
-rw-r--r--stdlib.tcl10
-rw-r--r--tests/alias.test7
-rw-r--r--tests/tailcall.test8
4 files changed, 80 insertions, 33 deletions
diff --git a/jim.c b/jim.c
index d5bdef8..dd059e2 100644
--- a/jim.c
+++ b/jim.c
@@ -10217,6 +10217,10 @@ static void JimSetProcWrongArgs(Jim_Interp *interp, Jim_Obj *procNameObj, Jim_Cm
Jim_Obj *argmsg = Jim_NewStringObj(interp, "", 0);
int i;
+ if (interp->rewriteNameObj) {
+ procNameObj = interp->rewriteNameObj;
+ }
+
for (i = 0; i < cmd->u.proc.argListLen; i++) {
Jim_AppendString(interp, argmsg, " ", 1);
@@ -10695,18 +10699,28 @@ int Jim_SubstObj(Jim_Interp *interp, Jim_Obj *substObjPtr, Jim_Obj **resObjPtrPt
* ---------------------------------------------------------------------------*/
void Jim_WrongNumArgs(Jim_Interp *interp, int argc, Jim_Obj *const *argv, const char *msg)
{
- int i;
- Jim_Obj *objPtr = Jim_NewEmptyStringObj(interp);
+ Jim_Obj *objPtr;
+ Jim_Obj *listObjPtr;
- Jim_AppendString(interp, objPtr, "wrong # args: should be \"", -1);
- for (i = 0; i < argc; i++) {
- Jim_AppendObj(interp, objPtr, argv[i]);
- if (!(i + 1 == argc && msg[0] == '\0'))
- Jim_AppendString(interp, objPtr, " ", 1);
+ if (interp->rewriteNameObj) {
+ argc -= interp->rewriteNameCount;
+ argv += interp->rewriteNameCount;
+ listObjPtr = Jim_NewListObj(interp, &interp->rewriteNameObj, 1);
+ ListInsertElements(listObjPtr, -1, argc, argv);
}
- Jim_AppendString(interp, objPtr, msg, -1);
- Jim_AppendString(interp, objPtr, "\"", 1);
- Jim_SetResult(interp, objPtr);
+ else {
+ listObjPtr = Jim_NewListObj(interp, argv, argc);
+ }
+ if (*msg) {
+ Jim_ListAppendElement(interp, listObjPtr, Jim_NewStringObj(interp, msg, -1));
+ }
+ Jim_IncrRefCount(listObjPtr);
+ objPtr = Jim_ListJoin(interp, listObjPtr, " ", 1);
+ Jim_DecrRefCount(interp, listObjPtr);
+
+ Jim_IncrRefCount(objPtr);
+ Jim_SetResultFormatted(interp, "wrong # args: should be \"%#s\"", objPtr);
+ Jim_DecrRefCount(interp, objPtr);
}
/**
@@ -12504,13 +12518,58 @@ static int Jim_ReturnCoreCommand(Jim_Interp *interp, int argc, Jim_Obj *const *a
/* [tailcall] */
static int Jim_TailcallCoreCommand(Jim_Interp *interp, int argc, Jim_Obj *const *argv)
{
- Jim_Obj *objPtr;
-
- objPtr = Jim_NewListObj(interp, argv + 1, argc - 1);
- Jim_SetResult(interp, objPtr);
+ Jim_SetResult(interp, Jim_NewListObj(interp, argv + 1, argc - 1));
return JIM_EVAL;
}
+static int JimAliasCmd(Jim_Interp *interp, int argc, Jim_Obj *const *argv)
+{
+ int retcode;
+ Jim_Obj *prefixObj = Jim_CmdPrivData(interp);
+ Jim_Obj *saveRewriteNameObj = interp->rewriteNameObj;
+ interp->rewriteNameObj = argv[0];
+ interp->rewriteNameCount = Jim_ListLength(interp, prefixObj);
+
+ Jim_Obj *cmdList = Jim_DuplicateObj(interp, prefixObj);
+ ListInsertElements(cmdList, -1, argc - 1, argv + 1);
+ Jim_IncrRefCount(cmdList);
+
+ retcode = JimEvalObjList(interp, cmdList, interp->emptyObj, 1);
+
+ Jim_DecrRefCount(interp, cmdList);
+ interp->rewriteNameObj = saveRewriteNameObj;
+
+ return retcode;
+}
+
+static void JimAliasCmdDelete(Jim_Interp *interp, void *privData)
+{
+ Jim_Obj *prefixObj = privData;
+ Jim_DecrRefCount(interp, prefixObj);
+}
+
+static int Jim_AliasCoreCommand(Jim_Interp *interp, int argc, Jim_Obj *const *argv)
+{
+ Jim_Obj *prefixObj;
+ const char *newname;
+
+ if (argc < 3) {
+ Jim_WrongNumArgs(interp, 1, argv, "newname command ?args ...?");
+ return JIM_ERR;
+ }
+
+ prefixObj = Jim_NewListObj(interp, argv + 2, argc - 2);
+ Jim_IncrRefCount(prefixObj);
+ newname = Jim_String(argv[1]);
+ if (newname[0] == ':' && newname[1] == ':') {
+ newname += 2;
+ }
+
+ Jim_SetResult(interp, argv[1]);
+
+ return Jim_CreateCommand(interp, newname, JimAliasCmd, prefixObj, JimAliasCmdDelete);
+}
+
/* [proc] */
static int Jim_ProcCoreCommand(Jim_Interp *interp, int argc, Jim_Obj *const *argv)
{
@@ -14307,6 +14366,7 @@ static const struct {
const char *name;
Jim_CmdProc cmdProc;
} Jim_CoreCommandsTable[] = {
+ {"alias", Jim_AliasCoreCommand},
{"set", Jim_SetCoreCommand},
{"unset", Jim_UnsetCoreCommand},
{"puts", Jim_PutsCoreCommand},
diff --git a/stdlib.tcl b/stdlib.tcl
index caacc00..e05f93c 100644
--- a/stdlib.tcl
+++ b/stdlib.tcl
@@ -1,13 +1,3 @@
-# Create a single word alias (proc) for one or more words
-# e.g. alias x info exists
-# if {[x var]} ...
-proc alias {name args} {
- set prefix $args
- proc $name args prefix {
- tailcall {*}$prefix {*}$args
- }
-}
-
# Creates an anonymous procedure
proc lambda {arglist args} {
set name [ref {} function lambda.finalizer]
diff --git a/tests/alias.test b/tests/alias.test
index c193a42..8b4d857 100644
--- a/tests/alias.test
+++ b/tests/alias.test
@@ -37,6 +37,11 @@ test alias-1.8 "Replace proc with alias" {
infoexists any
} {0}
+test alias-1.9 "error message from alias" -body {
+ alias newstring string
+ newstring match
+} -returnCodes error -result {wrong # args: should be "newstring match ?-nocase? pattern string"}
+
test curry-1.1 "One word curry" {
set x 2
set one [curry incr]
@@ -80,7 +85,7 @@ test local-1.3 "local alias in proc" {
list [p x] [p y]
}
lassign [a] exists_x exists_y
- list [info procs p] $exists_x $exists_y
+ list [info commands p] $exists_x $exists_y
} {{} 1 0}
test local-1.5 "local proc in proc" {
diff --git a/tests/tailcall.test b/tests/tailcall.test
index 027dfe8..35ae91c 100644
--- a/tests/tailcall.test
+++ b/tests/tailcall.test
@@ -31,14 +31,6 @@ test tailcall-1.3 {Tailcall does return} {
set x
} {5}
-# Note that Tcl can't do tailcall in uplevel
-test tailcall-1.4 {uplevel tailcall} jim {
- proc a {} { set ::y [info level] }
- proc b {} { set ::x [info level]; uplevel 1 tailcall a}
- b
- list $x $y
-} {1 1}
-
test tailcall-1.5 {interaction of uplevel and tailcall} {
proc a {cmd} {
tailcall $cmd