diff options
author | antirez <antirez> | 2005-02-27 11:28:01 +0000 |
---|---|---|
committer | antirez <antirez> | 2005-02-27 11:28:01 +0000 |
commit | 1e36e4656b9cd5cb69ca32a7088ad147b0a67d05 (patch) | |
tree | d854f8e80d74c4f79fdcead6e83391b48f037a96 | |
parent | a52c478f7d07b44a58ef88974a06de8f3e7ed0e2 (diff) | |
download | jimtcl-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-- | TODO | 11 | ||||
-rw-r--r-- | jim.c | 78 | ||||
-rw-r--r-- | test.tcl | 162 |
3 files changed, 221 insertions, 30 deletions
@@ -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 @@ -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) { @@ -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}} |