aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorantirez <antirez>2005-02-27 11:28:01 +0000
committerantirez <antirez>2005-02-27 11:28:01 +0000
commit1e36e4656b9cd5cb69ca32a7088ad147b0a67d05 (patch)
treed854f8e80d74c4f79fdcead6e83391b48f037a96
parenta52c478f7d07b44a58ef88974a06de8f3e7ed0e2 (diff)
downloadjimtcl-1e36e4656b9cd5cb69ca32a7088ad147b0a67d05.zip
jimtcl-1e36e4656b9cd5cb69ca32a7088ad147b0a67d05.tar.gz
jimtcl-1e36e4656b9cd5cb69ca32a7088ad147b0a67d05.tar.bz2
Now there is implicit subst in expr's strings like expr {"foo $i" eq $bar}.
More tests. A fix in the parsing code for line number calculation.
-rw-r--r--TODO11
-rw-r--r--jim.c78
-rw-r--r--test.tcl162
3 files changed, 221 insertions, 30 deletions
diff --git a/TODO b/TODO
index 9c65ff5..bbaa98d 100644
--- a/TODO
+++ b/TODO
@@ -37,3 +37,14 @@ IMPLEMENTATION ISSUES
- Remove SetTypeFromAny() method from the Jim_ObjType structure.
It's not useful, and it may be useful to have different prototypes
for the Set*FromAny() procedures of different types.
+
+ERROR MESSAGES
+
+- Display the procedure relative file number where the error happened.
+ Like:
+
+ In procedure 'check' line 11, called at file "test.tcl", line 1024
+
+ instead of just:
+
+ In procedure 'check' called at file "test.tcl", line 1024
diff --git a/jim.c b/jim.c
index ffafabe..51488f9 100644
--- a/jim.c
+++ b/jim.c
@@ -1065,7 +1065,10 @@ int JimParseSep(struct JimParserCtx *pc)
pc->tline = pc->linenr;
while (*pc->p == ' ' || *pc->p == '\t' || *pc->p == '\r' ||
(*pc->p == '\\' && *(pc->p+1) == '\n')) {
- if (*pc->p == '\\') pc->p++;
+ if (*pc->p == '\\') {
+ pc->p++;
+ pc->linenr++;
+ }
pc->p++;
}
pc->tend = pc->p-1;
@@ -1192,6 +1195,8 @@ int JimParseBrace(struct JimParserCtx *pc)
while (1) {
if (*pc->p == '\\' && *(pc->p+1) != '\0') {
pc->p++;
+ if (*pc->p == '\n')
+ pc->linenr++;
} else if (*pc->p == '{') {
level++;
} else if (*pc->p == '\0' || *pc->p == '}') {
@@ -2814,7 +2819,7 @@ Jim_Obj *Jim_GetVariable(Jim_Interp *interp, Jim_Obj *nameObjPtr, int flags)
if (flags & JIM_ERRMSG) {
Jim_SetResult(interp, Jim_NewEmptyStringObj(interp));
Jim_AppendStrings(interp, Jim_GetResult(interp),
- "Can't read \"", nameObjPtr->bytes,
+ "can't read \"", nameObjPtr->bytes,
"\": no such variable",
NULL);
}
@@ -2834,7 +2839,7 @@ Jim_Obj *Jim_GetVariable(Jim_Interp *interp, Jim_Obj *nameObjPtr, int flags)
if (objPtr == NULL && flags & JIM_ERRMSG) {
Jim_SetResult(interp, Jim_NewEmptyStringObj(interp));
Jim_AppendStrings(interp, Jim_GetResult(interp),
- "Can't read \"", nameObjPtr->bytes,
+ "can't read \"", nameObjPtr->bytes,
"\": no such variable",
NULL);
}
@@ -2869,7 +2874,7 @@ int Jim_UnsetVariable(Jim_Interp *interp, Jim_Obj *nameObjPtr, int flags)
return Jim_DictSugarSet(interp, nameObjPtr, NULL);
Jim_SetResult(interp, Jim_NewEmptyStringObj(interp));
Jim_AppendStrings(interp, Jim_GetResult(interp),
- "Can't unset \"", nameObjPtr->bytes,
+ "can't unset \"", nameObjPtr->bytes,
"\": no such variable",
NULL);
return JIM_ERR; /* var not found */
@@ -2888,7 +2893,7 @@ int Jim_UnsetVariable(Jim_Interp *interp, Jim_Obj *nameObjPtr, int flags)
if (retval != JIM_OK && flags & JIM_ERRMSG) {
Jim_SetResult(interp, Jim_NewEmptyStringObj(interp));
Jim_AppendStrings(interp, Jim_GetResult(interp),
- "Can't unset \"", nameObjPtr->bytes,
+ "can't unset \"", nameObjPtr->bytes,
"\": no such variable",
NULL);
}
@@ -4947,35 +4952,36 @@ typedef struct Jim_ExprOperator {
#define JIM_EXPROP_LSHIFT 9
#define JIM_EXPROP_RSHIFT 10
-#define JIM_EXPROP_ROTL 30
-#define JIM_EXPROP_ROTR 31
+#define JIM_EXPROP_ROTL 11
+#define JIM_EXPROP_ROTR 12
-#define JIM_EXPROP_LT 11
-#define JIM_EXPROP_GT 12
-#define JIM_EXPROP_LTE 13
-#define JIM_EXPROP_GTE 14
+#define JIM_EXPROP_LT 13
+#define JIM_EXPROP_GT 14
+#define JIM_EXPROP_LTE 15
+#define JIM_EXPROP_GTE 16
-#define JIM_EXPROP_NUMEQ 15
-#define JIM_EXPROP_NUMNE 16
+#define JIM_EXPROP_NUMEQ 17
+#define JIM_EXPROP_NUMNE 18
-#define JIM_EXPROP_STREQ 17
-#define JIM_EXPROP_STRNE 18
+#define JIM_EXPROP_STREQ 19
+#define JIM_EXPROP_STRNE 20
-#define JIM_EXPROP_BITAND 19
-#define JIM_EXPROP_BITXOR 20
-#define JIM_EXPROP_BITOR 21
+#define JIM_EXPROP_BITAND 21
+#define JIM_EXPROP_BITXOR 22
+#define JIM_EXPROP_BITOR 23
-#define JIM_EXPROP_LOGICAND 22
-#define JIM_EXPROP_LOGICOR 23
+#define JIM_EXPROP_LOGICAND 24
+#define JIM_EXPROP_LOGICOR 25
-#define JIM_EXPROP_TERNARY 24
+#define JIM_EXPROP_TERNARY 26
/* Operands */
-#define JIM_EXPROP_NUMBER 25
-#define JIM_EXPROP_COMMAND 26
-#define JIM_EXPROP_VARIABLE 27
-#define JIM_EXPROP_DICTSUGAR 28
-#define JIM_EXPROP_STRING 29
+#define JIM_EXPROP_NUMBER 27
+#define JIM_EXPROP_COMMAND 28
+#define JIM_EXPROP_VARIABLE 29
+#define JIM_EXPROP_DICTSUGAR 30
+#define JIM_EXPROP_SUBST 31
+#define JIM_EXPROP_STRING 32
static struct Jim_ExprOperator Jim_ExprOperators[] = {
{"!", 300, 1, JIM_EXPROP_NOT},
@@ -5205,6 +5211,7 @@ static int ExprCheckCorrectness(ExprByteCode *expr)
switch(expr->opcode[i]) {
case JIM_EXPROP_NUMBER:
case JIM_EXPROP_STRING:
+ case JIM_EXPROP_SUBST:
case JIM_EXPROP_VARIABLE:
case JIM_EXPROP_DICTSUGAR:
case JIM_EXPROP_COMMAND:
@@ -5310,9 +5317,11 @@ int SetExprFromAny(Jim_Interp *interp, struct Jim_Obj *objPtr)
}
switch(type) {
case JIM_TT_STR:
- case JIM_TT_ESC:
ExprObjAddInstr(interp, expr,
JIM_EXPROP_STRING, token, len);
+ case JIM_TT_ESC:
+ ExprObjAddInstr(interp, expr,
+ JIM_EXPROP_SUBST, token, len);
break;
case JIM_TT_VAR:
ExprObjAddInstr(interp, expr,
@@ -5501,6 +5510,17 @@ int Jim_EvalExpression(Jim_Interp *interp, Jim_Obj *exprObjPtr,
int Alen, Blen, retcode;
switch(expr->opcode[i]) {
+ case JIM_EXPROP_SUBST:
+ if ((retcode = Jim_SubstObj(interp, expr->obj[i],
+ &objPtr, JIM_NONE)) != JIM_OK)
+ {
+ error = 1;
+ errRetCode = retcode;
+ goto err;
+ }
+ stack[stacklen++] = objPtr;
+ Jim_IncrRefCount(objPtr);
+ break;
case JIM_EXPROP_NUMBER:
case JIM_EXPROP_STRING:
stack[stacklen++] = expr->obj[i];
@@ -7195,7 +7215,7 @@ int Jim_LappendCoreCommand(Jim_Interp *interp, int argc, Jim_Obj **argv)
int shared, i;
if (argc < 2) {
- Jim_WrongNumArgs(interp, 1, argv, "listVar ?element ...?");
+ Jim_WrongNumArgs(interp, 1, argv, "varName ?value value ...?");
return JIM_ERR;
}
listObjPtr = Jim_GetVariable(interp, argv[1], JIM_NONE);
@@ -7248,7 +7268,7 @@ int Jim_AppendCoreCommand(Jim_Interp *interp, int argc, Jim_Obj **argv)
int shared, i;
if (argc < 2) {
- Jim_WrongNumArgs(interp, 1, argv, "listVar ?string ...?");
+ Jim_WrongNumArgs(interp, 1, argv, "varName ?value value ...?");
return JIM_ERR;
}
if (argc == 2) {
diff --git a/test.tcl b/test.tcl
index 5e51737..ed776f0 100644
--- a/test.tcl
+++ b/test.tcl
@@ -475,7 +475,6 @@ test lset-6.8 {lset, not compiled, 1-d list basics} {
set a {x y z}
list [eval [list $lset a [list end-0] a]] $a
} {{x y a} {x y a}}
-
test lset-6.9 {lset, not compiled, 1-d list basics} {
set a {x y z}
list [eval [list $lset a end-2 a]] $a
@@ -871,3 +870,164 @@ test if-12.36 {error conditions} {
test if-12.37 {error conditions} {
list [catch {if 0 then foo elseif 0 bar else {[error "error in else clause"]}} msg] $msg
} {1 {error in else clause}}
+
+################################################################################
+# APPEND
+################################################################################
+
+catch {unset x}
+
+test append-1.1 {append command} {
+ catch {unset x}
+ list [append x 1 2 abc "long string"] $x
+} {{12abclong string} {12abclong string}}
+test append-1.2 {append command} {
+ set x ""
+ list [append x first] [append x second] [append x third] $x
+} {first firstsecond firstsecondthird firstsecondthird}
+test append-1.3 {append command} {
+ set x "abcd"
+ append x
+} abcd
+
+test append-2.1 {long appends} {
+ set x ""
+ for {set i 0} {$i < 1000} {set i [expr $i+1]} {
+ append x "foobar "
+ }
+ set y "foobar"
+ set y "$y $y $y $y $y $y $y $y $y $y"
+ set y "$y $y $y $y $y $y $y $y $y $y"
+ set y "$y $y $y $y $y $y $y $y $y $y "
+ expr {$x eq $y}
+} 1
+
+test append-3.1 {append errors} {
+ list [catch {append} msg] $msg
+} {1 {wrong # args: should be "append varName ?value value ...?"}}
+#test append-3.2 {append errors} {
+# set x ""
+# list [catch {append x(0) 44} msg] $msg
+#} {1 {can't set "x(0)": variable isn't array}}
+test append-3.3 {append errors} {
+ catch {unset x}
+ list [catch {append x} msg] $msg
+} {1 {can't read "x": no such variable}}
+
+test append-4.1 {lappend command} {
+ catch {unset x}
+ list [lappend x 1 2 abc "long string"] $x
+} {{1 2 abc {long string}} {1 2 abc {long string}}}
+test append-4.2 {lappend command} {
+ set x ""
+ list [lappend x first] [lappend x second] [lappend x third] $x
+} {first {first second} {first second third} {first second third}}
+test append-4.3 {lappend command} {
+ proc foo {} {
+ global x
+ set x old
+ unset x
+ lappend x new
+ }
+ set result [foo]
+ rename foo {}
+ set result
+} {new}
+test append-4.4 {lappend command} {
+ set x {}
+ lappend x \{\ abc
+} {\{\ abc}
+test append-4.5 {lappend command} {
+ set x {}
+ lappend x \{ abc
+} {\{ abc}
+test append-4.6 {lappend command} {
+ set x {1 2 3}
+ lappend x
+} {1 2 3}
+test append-4.7 {lappend command} {
+ set x "a\{"
+ lappend x abc
+} "a\\\{ abc"
+test append-4.8 {lappend command} {
+ set x "\\\{"
+ lappend x abc
+} "\\{ abc"
+#test append-4.9 {lappend command} {
+# set x " \{"
+# list [catch {lappend x abc} msg] $msg
+#} {1 {unmatched open brace in list}}
+#test append-4.10 {lappend command} {
+# set x " \{"
+# list [catch {lappend x abc} msg] $msg
+#} {1 {unmatched open brace in list}}
+#test append-4.11 {lappend command} {
+# set x "\{\{\{"
+# list [catch {lappend x abc} msg] $msg
+#} {1 {unmatched open brace in list}}
+#test append-4.12 {lappend command} {
+# set x "x \{\{\{"
+# list [catch {lappend x abc} msg] $msg
+#} {1 {unmatched open brace in list}}
+test append-4.13 {lappend command} {
+ set x "x\{\{\{"
+ lappend x abc
+} "x\\\{\\\{\\\{ abc"
+test append-4.14 {lappend command} {
+ set x " "
+ lappend x abc
+} "abc"
+test append-4.15 {lappend command} {
+ set x "\\ "
+ lappend x abc
+} "{ } abc"
+test append-4.16 {lappend command} {
+ set x "x "
+ lappend x abc
+} "x abc"
+test append-4.17 {lappend command} {
+ catch {unset x}
+ lappend x
+} {}
+test append-4.18 {lappend command} {
+ catch {unset x}
+ lappend x {}
+} {{}}
+test append-4.19 {lappend command} {
+ catch {unset x}
+ lappend x(0)
+} {}
+test append-4.20 {lappend command} {
+ catch {unset x}
+ lappend x(0) abc
+} {abc}
+
+proc check {var size} {
+ set l [llength $var]
+ if {$l != $size} {
+ return "length mismatch: should have been $size, was $l"
+ }
+ for {set i 0} {$i < $size} {set i [expr $i+1]} {
+ set j [lindex $var $i]
+ if {$j ne "item $i"} {
+ return "element $i should have been \"item $i\", was \"$j\""
+ }
+ }
+ return ok
+}
+test append-5.1 {long lappends} {
+ catch {unset x}
+ set x ""
+ for {set i 0} {$i < 300} {set i [expr $i+1]} {
+ lappend x "item $i"
+ }
+ check $x 300
+} ok
+
+test append-6.1 {lappend errors} {
+ list [catch {lappend} msg] $msg
+} {1 {wrong # args: should be "lappend varName ?value value ...?"}}
+#test append-6.2 {lappend errors} {
+# set x ""
+# list [catch {lappend x(0) 44} msg] $msg
+#} {1 {can't set "x(0)": variable isn't array}}