summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--ChangeLog8
-rw-r--r--generic/tclInt.decls10
-rw-r--r--generic/tclInt.h13
-rw-r--r--generic/tclIntDecls.h15
-rw-r--r--generic/tclStubInit.c4
-rw-r--r--generic/tclUtil.c88
6 files changed, 114 insertions, 24 deletions
diff --git a/ChangeLog b/ChangeLog
index f13d8eb..4c4fd59 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,11 @@
+2010-11-30 Jeff Hobbs <jeffh@ActiveState.com>
+
+ * generic/tclInt.decls, generic/tclInt.h, generic/tclIntDecls.h:
+ * generic/tclStubInit.c: TclFormatInt restored at slot 24
+ * generic/tclUtil.c (TclFormatInt): restore TclFormatInt func from
+ 2005-07-05 macro-ization. Benchmarks indicate it is faster, as a
+ key int->string routine (e.g. int-indexed arrays).
+
2010-11-23 Andreas Kupries <andreask@activestate.com>
* generic/tclVar.c (VarHashInvalidateEntry): Removed obsolete
diff --git a/generic/tclInt.decls b/generic/tclInt.decls
index ad35bf8..235e784 100644
--- a/generic/tclInt.decls
+++ b/generic/tclInt.decls
@@ -13,7 +13,7 @@
# See the file "license.terms" for information on usage and redistribution
# of this file, and for a DISCLAIMER OF ALL WARRANTIES.
#
-# RCS: @(#) $Id: tclInt.decls,v 1.121.2.5 2010/10/02 00:29:42 hobbs Exp $
+# RCS: @(#) $Id: tclInt.decls,v 1.121.2.6 2010/11/30 18:16:02 hobbs Exp $
library tcl
@@ -115,10 +115,10 @@ declare 22 generic {
declare 23 generic {
Proc *TclFindProc(Interp *iPtr, CONST char *procName)
}
-# Replaced with macro (see tclInt.h) in Tcl 8.5
-#declare 24 generic {
-# int TclFormatInt(char *buffer, long n)
-#}
+# Replaced with macro (see tclInt.h) in Tcl 8.5.0, restored in 8.5.10
+declare 24 generic {
+ int TclFormatInt(char *buffer, long n)
+}
declare 25 generic {
void TclFreePackageInfo(Interp *iPtr)
}
diff --git a/generic/tclInt.h b/generic/tclInt.h
index 31c9628..75e32bf 100644
--- a/generic/tclInt.h
+++ b/generic/tclInt.h
@@ -13,7 +13,7 @@
* See the file "license.terms" for information on usage and redistribution of
* this file, and for a DISCLAIMER OF ALL WARRANTIES.
*
- * RCS: @(#) $Id: tclInt.h,v 1.362.2.15 2010/11/15 21:32:32 andreas_kupries Exp $
+ * RCS: @(#) $Id: tclInt.h,v 1.362.2.16 2010/11/30 18:16:02 hobbs Exp $
*/
#ifndef _TCLINT
@@ -3738,17 +3738,6 @@ MODULE_SCOPE void TclBNInitBignumFromWideUInt(mp_int *bignum,
/*
*----------------------------------------------------------------
- * Macro used by the Tcl core to write the string rep of a long integer to a
- * character buffer. The ANSI C "prototype" for this macro is:
- *
- * MODULE_SCOPE int TclFormatInt(char *buf, long n);
- *----------------------------------------------------------------
- */
-
-#define TclFormatInt(buf, n) sprintf((buf), "%ld", (long)(n))
-
-/*
- *----------------------------------------------------------------
* Macros used by the Tcl core to set a Tcl_Obj's numeric representation
* avoiding the corresponding function calls in time critical parts of the
* core. They should only be called on unshared objects. The ANSI C
diff --git a/generic/tclIntDecls.h b/generic/tclIntDecls.h
index 5596952..a7d2fd9 100644
--- a/generic/tclIntDecls.h
+++ b/generic/tclIntDecls.h
@@ -11,7 +11,7 @@
* See the file "license.terms" for information on usage and redistribution
* of this file, and for a DISCLAIMER OF ALL WARRANTIES.
*
- * RCS: @(#) $Id: tclIntDecls.h,v 1.112.2.4 2010/10/02 00:29:42 hobbs Exp $
+ * RCS: @(#) $Id: tclIntDecls.h,v 1.112.2.5 2010/11/30 18:16:02 hobbs Exp $
*/
#ifndef _TCLINTDECLS
@@ -148,7 +148,11 @@ EXTERN int TclFindElement(Tcl_Interp *interp,
/* 23 */
EXTERN Proc * TclFindProc(Interp *iPtr, CONST char *procName);
#endif
-/* Slot 24 is reserved */
+#ifndef TclFormatInt_TCL_DECLARED
+#define TclFormatInt_TCL_DECLARED
+/* 24 */
+EXTERN int TclFormatInt(char *buffer, long n);
+#endif
#ifndef TclFreePackageInfo_TCL_DECLARED
#define TclFreePackageInfo_TCL_DECLARED
/* 25 */
@@ -1065,7 +1069,7 @@ typedef struct TclIntStubs {
void *reserved21;
int (*tclFindElement) (Tcl_Interp *interp, CONST char *listStr, int listLength, CONST char **elementPtr, CONST char **nextPtr, int *sizePtr, int *bracePtr); /* 22 */
Proc * (*tclFindProc) (Interp *iPtr, CONST char *procName); /* 23 */
- void *reserved24;
+ int (*tclFormatInt) (char *buffer, long n); /* 24 */
void (*tclFreePackageInfo) (Interp *iPtr); /* 25 */
void *reserved26;
void *reserved27;
@@ -1364,7 +1368,10 @@ extern TclIntStubs *tclIntStubsPtr;
#define TclFindProc \
(tclIntStubsPtr->tclFindProc) /* 23 */
#endif
-/* Slot 24 is reserved */
+#ifndef TclFormatInt
+#define TclFormatInt \
+ (tclIntStubsPtr->tclFormatInt) /* 24 */
+#endif
#ifndef TclFreePackageInfo
#define TclFreePackageInfo \
(tclIntStubsPtr->tclFreePackageInfo) /* 25 */
diff --git a/generic/tclStubInit.c b/generic/tclStubInit.c
index 3a9fc31..a8ed3bd 100644
--- a/generic/tclStubInit.c
+++ b/generic/tclStubInit.c
@@ -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: tclStubInit.c,v 1.150.2.3 2010/02/07 22:16:54 nijtmans Exp $
+ * RCS: @(#) $Id: tclStubInit.c,v 1.150.2.4 2010/11/30 18:16:02 hobbs Exp $
*/
#include "tclInt.h"
@@ -98,7 +98,7 @@ TclIntStubs tclIntStubs = {
NULL, /* 21 */
TclFindElement, /* 22 */
TclFindProc, /* 23 */
- NULL, /* 24 */
+ TclFormatInt, /* 24 */
TclFreePackageInfo, /* 25 */
NULL, /* 26 */
NULL, /* 27 */
diff --git a/generic/tclUtil.c b/generic/tclUtil.c
index 64d36f4..e4083fc 100644
--- a/generic/tclUtil.c
+++ b/generic/tclUtil.c
@@ -11,7 +11,7 @@
* See the file "license.terms" for information on usage and redistribution of
* this file, and for a DISCLAIMER OF ALL WARRANTIES.
*
- * RCS: @(#) $Id: tclUtil.c,v 1.97.2.6 2010/08/10 20:48:21 hobbs Exp $
+ * RCS: @(#) $Id: tclUtil.c,v 1.97.2.7 2010/11/30 18:16:02 hobbs Exp $
*/
#include "tclInt.h"
@@ -2522,6 +2522,92 @@ TclNeedSpace(
/*
*----------------------------------------------------------------------
*
+ * TclFormatInt --
+ *
+ * This procedure formats an integer into a sequence of decimal digit
+ * characters in a buffer. If the integer is negative, a minus sign is
+ * inserted at the start of the buffer. A null character is inserted at
+ * the end of the formatted characters. It is the caller's
+ * responsibility to ensure that enough storage is available. This
+ * procedure has the effect of sprintf(buffer, "%ld", n) but is faster
+ * as proven in benchmarks. This is key to UpdateStringOfInt, which
+ * is a common path for a lot of code (e.g. int-indexed arrays).
+ *
+ * Results:
+ * An integer representing the number of characters formatted, not
+ * including the terminating \0.
+ *
+ * Side effects:
+ * The formatted characters are written into the storage pointer to
+ * by the "buffer" argument.
+ *
+ *----------------------------------------------------------------------
+ */
+
+int
+TclFormatInt(buffer, n)
+ char *buffer; /* Points to the storage into which the
+ * formatted characters are written. */
+ long n; /* The integer to format. */
+{
+ long intVal;
+ int i;
+ int numFormatted, j;
+ char *digits = "0123456789";
+
+ /*
+ * Check first whether "n" is zero.
+ */
+
+ if (n == 0) {
+ buffer[0] = '0';
+ buffer[1] = 0;
+ return 1;
+ }
+
+ /*
+ * Check whether "n" is the maximum negative value. This is
+ * -2^(m-1) for an m-bit word, and has no positive equivalent;
+ * negating it produces the same value.
+ */
+
+ if (n == -n) {
+ return sprintf(buffer, "%ld", n);
+ }
+
+ /*
+ * Generate the characters of the result backwards in the buffer.
+ */
+
+ intVal = (n < 0? -n : n);
+ i = 0;
+ buffer[0] = '\0';
+ do {
+ i++;
+ buffer[i] = digits[intVal % 10];
+ intVal = intVal/10;
+ } while (intVal > 0);
+ if (n < 0) {
+ i++;
+ buffer[i] = '-';
+ }
+ numFormatted = i;
+
+ /*
+ * Now reverse the characters.
+ */
+
+ for (j = 0; j < i; j++, i--) {
+ char tmp = buffer[i];
+ buffer[i] = buffer[j];
+ buffer[j] = tmp;
+ }
+ return numFormatted;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
* TclGetIntForIndex --
*
* This function returns an integer corresponding to the list index held