Tcl Source Code

Artifact [4dd74958e4]
Login

Artifact 4dd74958e43e9aa771342b8ddaefa6e3d2ebe393:

Attachment "tip347_long_alt.patch" to ticket [2581150fff] added by nijtmans 2011-05-06 15:11:58.
Index: doc/string.n
===================================================================
--- doc/string.n
+++ doc/string.n
@@ -108,10 +108,13 @@
 .IP \fBalpha\fR 12
 Any Unicode alphabet character.
 .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
 Any Unicode control character.
 .IP \fBdigit\fR 12
@@ -125,13 +128,13 @@
 Any of the forms allowed to \fBTcl_GetBoolean\fR where the value is
 false.
 .IP \fBgraph\fR 12
 Any Unicode printing character, except space.
 .IP \fBinteger\fR 12
-Any of the valid string formats for a 32-bit integer value in Tcl,
-with optional surrounding whitespace.  In case of under/overflow in
-the value, 0 is returned and the \fIvarname\fR will contain \-1.
+Any of the forms allowed to \fBTcl_GetLongFromObj\fR. In case of
+under/overflow in the value, 0 is returned and the \fIvarname\fR will
+contain \-1.
 .IP \fBlist\fR 12
 Any proper list structure, with optional surrounding whitespace. In
 case of improper list structure, 0 is returned and the \fIvarname\fR
 will contain the index of the
 .QW element

Index: generic/tclCmdMZ.c
===================================================================
--- generic/tclCmdMZ.c
+++ generic/tclCmdMZ.c
@@ -15,10 +15,11 @@
  * See the file "license.terms" for information on usage and redistribution of
  * this file, and for a DISCLAIMER OF ALL WARRANTIES.
  */
 
 #include "tclInt.h"
+#include "tommath.h"
 #include "tclRegexp.h"
 
 static inline Tcl_Obj *	During(Tcl_Interp *interp, int resultCode,
 			    Tcl_Obj *oldOptions, Tcl_Obj *errorInfo);
 static int		SwitchPostProc(ClientData data[], Tcl_Interp *interp,
@@ -1428,22 +1429,24 @@
     Tcl_UniChar ch;
     int (*chcomp)(int) = NULL;	/* The UniChar comparison function. */
     int i, failat = 0, result = 1, strict = 0, index, length1, length2;
     Tcl_Obj *objPtr, *failVarObj = NULL;
     Tcl_WideInt w;
+    long lng;
+    mp_int big;
 
     static const char *const isClasses[] = {
 	"alnum",	"alpha",	"ascii",	"control",
-	"boolean",	"digit",	"double",	"false",
+	"boolean",	"digit",	"double",	"entier",	"false",
 	"graph",	"integer",	"list",		"lower",
 	"print",	"punct",	"space",	"true",
 	"upper",	"wideinteger",	"wordchar",	"xdigit",
 	NULL
     };
     enum isClasses {
 	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_BOOL,  STR_IS_DIGIT,	STR_IS_DOUBLE,STR_IS_ENTIER, 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
     };
     static const char *const isOptions[] = {
@@ -1565,12 +1568,17 @@
 	break;
     }
     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)) {
+	if (TCL_OK == TclGetLongFromObj(NULL, objPtr, &lng)) {
 	    break;
 	}
 	goto failedIntParse;
     case STR_IS_WIDE:
 	if (TCL_OK == Tcl_GetWideIntFromObj(NULL, objPtr, &w)) {

Index: generic/tclStringObj.c
===================================================================
--- generic/tclStringObj.c
+++ generic/tclStringObj.c
@@ -1967,15 +1967,10 @@
 	    allocSegment = 1;
 	    break;
 	}
 
 	case 'u':
-	    if (useBig) {
-		msg = "unsigned bignum format is invalid";
-		errCode = "BADUNSIGNED";
-		goto errorMsg;
-	    }
 	case 'd':
 	case 'o':
 	case 'x':
 	case 'X':
 	case 'b': {
@@ -1989,10 +1984,15 @@
 	    if (useBig) {
 		if (Tcl_GetBignumFromObj(interp, segment, &big) != TCL_OK) {
 		    goto error;
 		}
 		isNegative = (mp_cmp_d(&big, 0) == MP_LT);
+		if (ch == 'u' && isNegative) {
+		    msg = "unsigned bignum format is invalid for negative values";
+		    errCode = "BADUNSIGNED";
+		    goto errorMsg;
+		}
 	    } else if (useWide) {
 		if (Tcl_GetWideIntFromObj(NULL, segment, &w) != TCL_OK) {
 		    Tcl_Obj *objPtr;
 
 		    if (Tcl_GetBignumFromObj(interp,segment,&big) != TCL_OK) {

Index: tests/string.test
===================================================================
--- tests/string.test
+++ tests/string.test
@@ -310,14 +310,14 @@
 test string-6.4 {string is, too many args} {
     list [catch {string is alpha -failin var -strict str more} msg] $msg
 } {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, entier, false, graph, integer, list, lower, print, punct, space, true, upper, wideinteger, wordchar, or xdigit}}
 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, entier, false, graph, integer, list, lower, print, punct, space, true, upper, wideinteger, wordchar, or xdigit}}
 test string-6.7 {string is alpha, all ok} {
     string is alpha -strict -failindex var abc
 } 1
 test string-6.8 {string is, error in var} {
     list [string is alpha -failindex var abc5def] $var
@@ -600,24 +600,24 @@
     foreach num $numbers {
 	lappend result [string is double -strict $num]
     }
     set result
 } {1 1 0 0 0 1 0 0}
-test string-6.92 {string is integer, 32-bit overflow} {
+test string-6.92 {string is integer, overflow} {
     # Bug 718878
-    set x 0x100000000
+    set x 0x10000000000000000
     list [string is integer -failindex var $x] $var
 } {0 -1}
-test string-6.93 {string is integer, 32-bit overflow} {
+test string-6.93 {string is integer, overflow} {
     # Bug 718878
-    set x 0x100000000
+    set x 0x10000000000000000
     append x ""
     list [string is integer -failindex var $x] $var
 } {0 -1}
-test string-6.94 {string is integer, 32-bit overflow} {
+test string-6.94 {string is integer, overflow} {
     # Bug 718878
-    set x 0x100000000
+    set x 0x10000000000000000
     list [string is integer -failindex var [expr {$x}]] $var
 } {0 -1}
 test string-6.95 {string is wideinteger, true} {
     string is wideinteger +1234567890
 } 1
@@ -672,10 +672,82 @@
     string is double $x
 } 0
 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 {}}
 
 test string-7.1 {string last, too few args} {
     list [catch {string last a} msg] $msg