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