summaryrefslogtreecommitdiffstats
path: root/generic/tclCmdMZ.c
diff options
context:
space:
mode:
authorjan.nijtmans <nijtmans@users.sourceforge.net>2012-03-29 08:38:01 (GMT)
committerjan.nijtmans <nijtmans@users.sourceforge.net>2012-03-29 08:38:01 (GMT)
commit75c11d54923f588e856aa05c9d3b7874c7e0ad38 (patch)
treedad9366c016bd7b654240195f15496f3383abec0 /generic/tclCmdMZ.c
parent1251bcbcc6272da5c31c077c03ce238cfde19844 (diff)
parent740cd597bdeb4e570412f8fa30a97e39bdf56e99 (diff)
downloadtcl-75c11d54923f588e856aa05c9d3b7874c7e0ad38.zip
tcl-75c11d54923f588e856aa05c9d3b7874c7e0ad38.tar.gz
tcl-75c11d54923f588e856aa05c9d3b7874c7e0ad38.tar.bz2
faster memleak-free implementation of [string is entier]
Diffstat (limited to 'generic/tclCmdMZ.c')
-rw-r--r--generic/tclCmdMZ.c46
1 files changed, 42 insertions, 4 deletions
diff --git a/generic/tclCmdMZ.c b/generic/tclCmdMZ.c
index ff300b0..c5bb72d 100644
--- a/generic/tclCmdMZ.c
+++ b/generic/tclCmdMZ.c
@@ -18,7 +18,6 @@
#include "tclInt.h"
#include "tclRegexp.h"
-#include "tommath.h"
static inline Tcl_Obj * During(Tcl_Interp *interp, int resultCode,
Tcl_Obj *oldOptions, Tcl_Obj *errorInfo);
@@ -1434,7 +1433,6 @@ StringIsCmd(
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 isClasses[] = {
"alnum", "alpha", "ascii", "control",
@@ -1579,10 +1577,50 @@ StringIsCmd(
}
goto failedIntParse;
case STR_IS_ENTIER:
- if (TCL_OK == Tcl_GetBignumFromObj(NULL, objPtr, &big)) {
+ if ((objPtr->typePtr == &tclIntType) ||
+#ifndef NO_WIDE_TYPE
+ (objPtr->typePtr == &tclWideIntType) ||
+#endif
+ (objPtr->typePtr == &tclBignumType)) {
break;
}
- goto failedIntParse;
+ string1 = TclGetStringFromObj(objPtr, &length1);
+ if (length1 == 0) {
+ if (strict) {
+ result = 0;
+ }
+ goto str_is_done;
+ }
+ end = string1 + length1;
+ if (TclParseNumber(NULL, objPtr, NULL, NULL, -1,
+ (const char **) &stop, TCL_PARSE_INTEGER_ONLY) == TCL_OK) {
+ if (stop == end) {
+ /*
+ * Entire string parses as an integer.
+ */
+
+ break;
+ } else {
+ /*
+ * Some prefix parsed as an integer, but not the whole string,
+ * so return failure index as the point where parsing stopped.
+ * Clear out the internal rep, since keeping it would leave
+ * *objPtr in an inconsistent state.
+ */
+
+ result = 0;
+ failat = stop - string1;
+ TclFreeIntRep(objPtr);
+ }
+ } else {
+ /*
+ * No prefix is a valid integer. Fail at beginning.
+ */
+
+ result = 0;
+ failat = 0;
+ }
+ break;
case STR_IS_WIDE:
if (TCL_OK == Tcl_GetWideIntFromObj(NULL, objPtr, &w)) {
break;