From 881d5025bf794494317b6490233cde4438ed8d5e Mon Sep 17 00:00:00 2001 From: hobbs Date: Tue, 30 Nov 2010 18:16:01 +0000 Subject: * 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). --- ChangeLog | 8 +++++ generic/tclInt.decls | 10 +++--- generic/tclInt.h | 13 +------- generic/tclIntDecls.h | 15 ++++++--- generic/tclStubInit.c | 4 +-- generic/tclUtil.c | 88 ++++++++++++++++++++++++++++++++++++++++++++++++++- 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 + + * 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 * 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 -- cgit v0.12