diff options
-rw-r--r-- | ChangeLog | 7 | ||||
-rw-r--r-- | generic/tclCompExpr.c | 33 | ||||
-rw-r--r-- | tests/parseExpr.test | 93 |
3 files changed, 126 insertions, 7 deletions
@@ -1,3 +1,10 @@ +2007-07-15 Don Porter <dgp@users.sourceforge.net> + + * generic/tclCompExpr.c: More commentary. + * tests/parseExpr.test: Several tests of syntax error messages + to check that when expression substrings are truncated they leave + visible the context relevant to the reported error. + 2007-07-12 Don Porter <dgp@users.sourceforge.net> * generic/tclCompExpr.c: Factored out, corrected, and commented diff --git a/generic/tclCompExpr.c b/generic/tclCompExpr.c index da9007f..bab56f5 100644 --- a/generic/tclCompExpr.c +++ b/generic/tclCompExpr.c @@ -12,7 +12,7 @@ * See the file "license.terms" for information on usage and redistribution of * this file, and for a DISCLAIMER OF ALL WARRANTIES. * - * RCS: @(#) $Id: tclCompExpr.c,v 1.68 2007/07/12 22:13:12 dgp Exp $ + * RCS: @(#) $Id: tclCompExpr.c,v 1.69 2007/07/16 19:50:46 dgp Exp $ */ #include "tclInt.h" @@ -514,6 +514,7 @@ ParseExpr( nodes->precedence = prec[lexeme]; nodes->left = OT_NONE; nodes->right = OT_NONE; + /* TODO: explain. */ nodes->parent = -1; nodesUsed++; } @@ -849,19 +850,32 @@ ParseExpr( } /* case LEAF */ case UNARY: + /* + * A unary operator appearing just after something that's not an + * operator is a syntax error -- something trying to be the left + * operand of an operator that doesn't take one. + */ if (NotOperator(lastParsed)) { msg = Tcl_ObjPrintf("missing operator at %s", mark); scanned = 0; insertMark = 1; code = TCL_ERROR; + /* Escape the parse loop to report the syntax error. */ continue; } - lastParsed = nodesUsed; - nodePtr->lexeme = lexeme; - nodePtr->precedence = prec[lexeme]; - nodePtr->left = OT_NONE; - nodePtr->right = OT_NONE; + /* Create an OpNode for the unary operator */ + nodePtr->lexeme = lexeme; /* Remember the operator... */ + nodePtr->precedence = prec[lexeme]; /* ... and its precedence. */ + nodePtr->left = OT_NONE; /* No left operand */ + nodePtr->right = OT_NONE; /* Right operand not + * yet known. */ + /* TODO: explain */ nodePtr->parent = nodePtr - nodes - 1; + /* + * Remember this unary operator as the last thing parsed for + * the next pass through the loop. + */ + lastParsed = nodesUsed; nodesUsed++; break; @@ -869,6 +883,11 @@ ParseExpr( OpNode *otherPtr = NULL; unsigned char precedence = prec[lexeme]; + /* + * A binary operand appearing just after another operator is a + * syntax error -- one of the two operators is missing an operand. + */ + if (IsOperator(lastParsed)) { if ((lexeme == CLOSE_PAREN) && (nodePtr[-1].lexeme == OPEN_PAREN)) { @@ -879,6 +898,7 @@ ParseExpr( */ scanned = 0; + /* TODO: explain */ lastParsed = OT_EMPTY; nodePtr[-1].left--; break; @@ -923,6 +943,7 @@ ParseExpr( continue; } + /* TODO: explain */ if (lastParsed == OT_NONE) { otherPtr = nodes + lastOpen - 1; lastParsed = lastOpen; diff --git a/tests/parseExpr.test b/tests/parseExpr.test index d2261bf..f89727d 100644 --- a/tests/parseExpr.test +++ b/tests/parseExpr.test @@ -8,7 +8,7 @@ # See the file "license.terms" for information on usage and redistribution # of this file, and for a DISCLAIMER OF ALL WARRANTIES. # -# RCS: @(#) $Id: parseExpr.test,v 1.25 2006/08/23 21:31:55 dgp Exp $ +# RCS: @(#) $Id: parseExpr.test,v 1.26 2007/07/16 19:50:46 dgp Exp $ if {[lsearch [namespace children] ::tcltest] == -1} { package require tcltest 2 @@ -911,6 +911,97 @@ in expression "...%s" @ 0" (parsing expression ""%s...") invoked from within "expr [format {"%%s" @ 0} [string repeat \u00a7 25]]"} [string repeat \u00a7 10] [string repeat \u00a7 10]] +test parseExpr-21.42 {error message} -body { + expr {123456789012345678901234567890*"abcdefghijklmnopqrstuvwxyz} +} -returnCodes error -result {missing " +in expression "...012345678901234567890*"abcdefghijklmnopqrstuv..."} +test parseExpr-21.43 {error message} -body { + expr "123456789012345678901234567890*\"foobar\$\{abcdefghijklmnopqrstuvwxyz\"" +} -returnCodes error -result "missing close-brace for variable name +in expression \"...8901234567890*\"foobar\$\{abcdefghijklmnopqrstuv...\"" +test parseExpr-21.44 {error message} -body { + expr {123456789012345678901234567890*"foo$bar(abcdefghijklmnopqrstuvwxyz"} +} -returnCodes error -result {missing ) +in expression "...8901234567890*"foo$bar(abcdefghijklmnopqrstuv..."} +test parseExpr-21.45 {error message} -body { + expr {123456789012345678901234567890*"foo$bar([{}abcdefghijklmnopqrstuvwxyz])"} +} -returnCodes error -result {extra characters after close-brace +in expression "...234567890*"foo$bar([{}abcdefghijklmnopqrstuv..."} +test parseExpr-21.46 {error message} -body { + expr {123456789012345678901234567890*"foo$bar([""abcdefghijklmnopqrstuvwxyz])"} +} -returnCodes error -result {extra characters after close-quote +in expression "...234567890*"foo$bar([""abcdefghijklmnopqrstuv..."} +test parseExpr-21.47 {error message} -body { + expr {123456789012345678901234567890*"foo$bar([abcdefghijklmnopqrstuvwxyz)"} +} -returnCodes error -result {missing close-bracket +in expression "...901234567890*"foo$bar([abcdefghijklmnopqrstuv..."} +test parseExpr-21.48 {error message} -body { + expr "123456789012345678901234567890*\"foo\$bar(\[\{abcdefghijklmnopqrstuvwxyz])\"" +} -returnCodes error -result "missing close-brace +in expression \"...01234567890*\"foo\$bar(\[\{abcdefghijklmnopqrstuv...\"" + +test parseExpr-21.49 {error message} -body { + expr "123456789012345678901234567890*\{abcdefghijklmnopqrstuvwxyz" +} -returnCodes error -result "missing close-brace +in expression \"...012345678901234567890*\{abcdefghijklmnopqrstuv...\"" + +test parseExpr-21.50 {error message} -body { + expr {123456789012345678901234567890*$foo(["abcdefghijklmnopqrstuvwxyz])} +} -returnCodes error -result {missing " +in expression "...678901234567890*$foo(["abcdefghijklmnopqrstuv..."} +test parseExpr-21.51 {error message} -body { + expr "123456789012345678901234567890*\$\{abcdefghijklmnopqrstuvwxyz" +} -returnCodes error -result "missing close-brace for variable name +in expression \"...12345678901234567890*\$\{abcdefghijklmnopqrstuv...\"" +test parseExpr-21.52 {error message} -body { + expr {123456789012345678901234567890*$bar(abcdefghijklmnopqrstuvwxyz} +} -returnCodes error -result {missing ) +in expression "...45678901234567890*$bar(abcdefghijklmnopqrstuv..."} +test parseExpr-21.53 {error message} -body { + expr {123456789012345678901234567890*$bar([{}abcdefghijklmnopqrstuvwxyz])"} +} -returnCodes error -result {extra characters after close-brace +in expression "...8901234567890*$bar([{}abcdefghijklmnopqrstuv..."} +test parseExpr-21.54 {error message} -body { + expr {123456789012345678901234567890*$bar([""abcdefghijklmnopqrstuvwxyz])"} +} -returnCodes error -result {extra characters after close-quote +in expression "...8901234567890*$bar([""abcdefghijklmnopqrstuv..."} +test parseExpr-21.55 {error message} -body { + expr {123456789012345678901234567890*$bar([abcdefghijklmnopqrstuvwxyz)"} +} -returnCodes error -result {missing close-bracket +in expression "...5678901234567890*$bar([abcdefghijklmnopqrstuv..."} +test parseExpr-21.56 {error message} -body { + expr "123456789012345678901234567890*\$bar(\[\{abcdefghijklmnopqrstuvwxyz])" +} -returnCodes error -result "missing close-brace +in expression \"...678901234567890*\$bar(\[\{abcdefghijklmnopqrstuv...\"" + +test parseExpr-21.57 {error message} -body { + expr {123456789012345678901234567890*["abcdefghijklmnopqrstuvwxyz]} +} -returnCodes error -result {missing " +in expression "...12345678901234567890*["abcdefghijklmnopqrstuv..."} +test parseExpr-21.58 {error message} -body { + expr "123456789012345678901234567890*\[\$\{abcdefghijklmnopqrstuvwxyz]" +} -returnCodes error -result "missing close-brace for variable name +in expression \"...2345678901234567890*\[\$\{abcdefghijklmnopqrstuv...\"" +test parseExpr-21.59 {error message} -body { + expr {123456789012345678901234567890*[$bar(abcdefghijklmnopqrstuvwxyz]} +} -returnCodes error -result {missing ) +in expression "...5678901234567890*[$bar(abcdefghijklmnopqrstuv..."} +test parseExpr-21.60 {error message} -body { + expr {123456789012345678901234567890*[{}abcdefghijklmnopqrstuvwxyz]"} +} -returnCodes error -result {extra characters after close-brace +in expression "...345678901234567890*[{}abcdefghijklmnopqrstuv..."} +test parseExpr-21.61 {error message} -body { + expr {123456789012345678901234567890*[""abcdefghijklmnopqrstuvwxyz]"} +} -returnCodes error -result {extra characters after close-quote +in expression "...345678901234567890*[""abcdefghijklmnopqrstuv..."} +test parseExpr-21.62 {error message} -body { + expr {123456789012345678901234567890*[abcdefghijklmnopqrstuvwxyz"} +} -returnCodes error -result {missing close-bracket +in expression "...012345678901234567890*[abcdefghijklmnopqrstuv..."} +test parseExpr-21.63 {error message} -body { + expr "123456789012345678901234567890*\[\{abcdefghijklmnopqrstuvwxyz]" +} -returnCodes error -result "missing close-brace +in expression \"...12345678901234567890*\[\{abcdefghijklmnopqrstuv...\"" # cleanup ::tcltest::cleanupTests |