Index: doc/string.n =================================================================== RCS file: /cvsroot/tcl/tcl/doc/string.n,v retrieving revision 1.45 diff -w -u -r1.45 string.n --- doc/string.n 17 Oct 2008 10:22:25 -0000 1.45 +++ doc/string.n 9 Feb 2009 14:27:21 -0000 @@ -147,6 +147,9 @@ .IP \fBascii\fR 12 Any character with a value less than \eu0080 (those that are in the 7\-bit ascii range). +.IP \fBentier\fR 12 +Any of the valid string formats for an integer value in Tcl, with optional +surrounding whitespace. .IP \fBboolean\fR 12 Any of the forms allowed to \fBTcl_GetBoolean\fR. .IP \fBcontrol\fR 12 Index: generic/tclCmdMZ.c =================================================================== RCS file: /cvsroot/tcl/tcl/generic/tclCmdMZ.c,v retrieving revision 1.179 diff -w -u -r1.179 tclCmdMZ.c --- generic/tclCmdMZ.c 5 Feb 2009 22:12:44 -0000 1.179 +++ generic/tclCmdMZ.c 9 Feb 2009 14:27:23 -0000 @@ -19,6 +19,7 @@ */ #include "tclInt.h" +#include "tommath.h" #include "tclRegexp.h" static int UniCharIsAscii(int character); @@ -1406,6 +1407,7 @@ int i, failat = 0, result = 1, strict = 0, index, length1, length2; Tcl_Obj *objPtr, *failVarObj = NULL; Tcl_WideInt w; + mp_int big; static const char *const isOptions[] = { "alnum", "alpha", "ascii", "control", @@ -1413,14 +1415,15 @@ "graph", "integer", "list", "lower", "print", "punct", "space", "true", "upper", "wideinteger", "wordchar", "xdigit", - NULL + "entier", NULL }; enum isOptions { STR_IS_ALNUM, STR_IS_ALPHA, STR_IS_ASCII, STR_IS_CONTROL, STR_IS_BOOL, STR_IS_DIGIT, STR_IS_DOUBLE, STR_IS_FALSE, STR_IS_GRAPH, STR_IS_INT, STR_IS_LIST, STR_IS_LOWER, STR_IS_PRINT, STR_IS_PUNCT, STR_IS_SPACE, STR_IS_TRUE, - STR_IS_UPPER, STR_IS_WIDE, STR_IS_WORD, STR_IS_XDIGIT + STR_IS_UPPER, STR_IS_WIDE, STR_IS_WORD, STR_IS_XDIGIT, + STR_IS_ENTIER }; if (objc < 3 || objc > 6) { @@ -1531,6 +1534,11 @@ case STR_IS_GRAPH: chcomp = Tcl_UniCharIsGraph; break; + case STR_IS_ENTIER: + if (TCL_OK == Tcl_GetBignumFromObj(NULL, objPtr, &big)) { + break; + } + goto failedIntParse; case STR_IS_INT: if (TCL_OK == TclGetIntFromObj(NULL, objPtr, &i)) { break; Index: generic/tclStringObj.c =================================================================== RCS file: /cvsroot/tcl/tcl/generic/tclStringObj.c,v retrieving revision 1.87 diff -w -u -r1.87 tclStringObj.c --- generic/tclStringObj.c 5 Feb 2009 21:27:45 -0000 1.87 +++ generic/tclStringObj.c 9 Feb 2009 14:27:25 -0000 @@ -2054,10 +2054,6 @@ } case 'u': - if (useBig) { - msg = "unsigned bignum format is invalid"; - goto errorMsg; - } case 'd': case 'o': case 'x': @@ -2075,6 +2071,10 @@ goto error; } isNegative = (mp_cmp_d(&big, 0) == MP_LT); + if (ch == 'u' && isNegative) { + msg = "unsigned bignum format is invalid for negative values"; + goto errorMsg; + } } else if (useWide) { if (Tcl_GetWideIntFromObj(NULL, segment, &w) != TCL_OK) { Tcl_Obj *objPtr; Index: tests/string.test =================================================================== RCS file: /cvsroot/tcl/tcl/tests/string.test,v retrieving revision 1.76 diff -w -u -r1.76 string.test --- tests/string.test 14 Oct 2008 18:49:47 -0000 1.76 +++ tests/string.test 9 Feb 2009 14:27:27 -0000 @@ -314,10 +314,10 @@ } {1 {wrong # args: should be "string is class ?-strict? ?-failindex var? str"}} test string-6.5 {string is, class check} { list [catch {string is bogus str} msg] $msg -} {1 {bad class "bogus": must be alnum, alpha, ascii, control, boolean, digit, double, false, graph, integer, list, lower, print, punct, space, true, upper, wideinteger, wordchar, or xdigit}} +} {1 {bad class "bogus": must be alnum, alpha, ascii, control, boolean, digit, double, false, graph, integer, list, lower, print, punct, space, true, upper, wideinteger, wordchar, xdigit, or entier}} test string-6.6 {string is, ambiguous class} { list [catch {string is al str} msg] $msg -} {1 {ambiguous class "al": must be alnum, alpha, ascii, control, boolean, digit, double, false, graph, integer, list, lower, print, punct, space, true, upper, wideinteger, wordchar, or xdigit}} +} {1 {ambiguous class "al": must be alnum, alpha, ascii, control, boolean, digit, double, false, graph, integer, list, lower, print, punct, space, true, upper, wideinteger, wordchar, xdigit, or entier}} test string-6.7 {string is alpha, all ok} { string is alpha -strict -failindex var abc } 1 @@ -676,6 +676,78 @@ test string-6.109 {string is double, Bug 1360532} { string is double 1\u00a0 } 0 +test string-6.110 {string is entier, true} { + string is entier +1234567890 +} 1 +test string-6.111 {string is entier, true on type} { + string is entier [expr wide(50.0)] +} 1 +test string-6.112 {string is entier, true} { + string is entier [list -10] +} 1 +test string-6.113 {string is entier, true as hex} { + string is entier 0xabcdef +} 1 +test string-6.114 {string is entier, true as octal} { + string is entier 0123456 +} 1 +test string-6.115 {string is entier, true with whitespace} { + string is entier " \n1234\v" +} 1 +test string-6.116 {string is entier, false} { + list [string is entier -fail var 123abc] $var +} {0 3} +test string-6.117 {string is entier, false} { + list [string is entier -fail var 123123123123123123123123123123123123123123123123123123123123123123123123123123123123abc] $var +} {0 84} +test string-6.118 {string is entier, false} { + list [string is entier -fail var [expr double(1)]] $var +} {0 1} +test string-6.119 {string is entier, false} { + list [string is entier -fail var " "] $var +} {0 0} +test string-6.120 {string is entier, false on bad octal} { + list [string is entier -fail var 0o36963] $var +} {0 4} +test string-6.121.1 {string is entier, false on bad octal} { + list [string is entier -fail var 0o36963] $var +} {0 4} +test string-6.122 {string is entier, false on bad hex} { + list [string is entier -fail var 0X345XYZ] $var +} {0 5} +test string-6.123 {string is entier, bad integers} { + # SF bug #634856 + set result "" + set numbers [list 1 +1 ++1 +-1 -+1 -1 --1 "- +1"] + foreach num $numbers { + lappend result [string is entier -strict $num] + } + set result +} {1 1 0 0 0 1 0 0} +test string-6.124 {string is entier, true} { + string is entier +1234567890123456789012345678901234567890 +} 1 +test string-6.125 {string is entier, true} { + string is entier [list -10000000000000000000000000000000000000000000000000000000000000000000000000000000000000] +} 1 +test string-6.126 {string is entier, true as hex} { + string is entier 0xabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdef +} 1 +test string-6.127 {string is entier, true as octal} { + string is entier 0123456112341234561234565623456123456123456123456123456123456123456123456123456123456 +} 1 +test string-6.128 {string is entier, true with whitespace} { + string is entier " \n12340000000000000000000000000000000000000000000000000000000000000000000000000000000000000\v" +} 1 +test string-6.129 {string is entier, false on bad octal} { + list [string is entier -fail var 0o1234561123412345612345656234561234561234561234561234561234561234561234561234561234536963] $var +} {0 87} +test string-6.130.1 {string is entier, false on bad octal} { + list [string is entier -fail var 0o1234561123412345612345656234561234561234561234561234561234561234561234561234561234536963] $var +} {0 87} +test string-6.131 {string is entier, false on bad hex} { + list [string is entier -fail var 0X12345611234123456123456562345612345612345612345612345612345612345612345612345612345345XYZ] $var +} {0 88} catch {rename largest_int {}}