summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--doc/Number.3123
-rw-r--r--generic/tcl.decls10
-rw-r--r--generic/tcl.h14
-rwxr-xr-xgeneric/tclArithSeries.c2
-rw-r--r--generic/tclBasic.c32
-rw-r--r--generic/tclCmdIL.c2
-rw-r--r--generic/tclDecls.h20
-rw-r--r--generic/tclExecute.c4
-rw-r--r--generic/tclInt.h18
-rw-r--r--generic/tclLink.c2
-rw-r--r--generic/tclObj.c40
-rw-r--r--generic/tclStubInit.c4
-rw-r--r--generic/tclUtil.c10
13 files changed, 226 insertions, 55 deletions
diff --git a/doc/Number.3 b/doc/Number.3
new file mode 100644
index 0000000..f93d75d
--- /dev/null
+++ b/doc/Number.3
@@ -0,0 +1,123 @@
+'\"
+'\" Contribution from Don Porter, NIST, 2022. (not subject to US copyright)
+'\"
+'\" See the file "license.terms" for information on usage and redistribution
+'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+'\"
+.TH Tcl_GetNumber 3 8.7 Tcl "Tcl Library Procedures"
+.so man.macros
+.BS
+.SH NAME
+Tcl_GetNumber, Tcl_GetNumberFromObj \- get numeric value from Tcl value
+.SH SYNOPSIS
+.nf
+\fB#include <tcl.h>\fR
+.sp
+\fB#include <tclTomMath.h>\fR
+.sp
+int
+\fBTcl_GetNumber\fR(\fIinterp, bytes, numBytes, clientDataPtr, typePtr\fR)
+.sp
+int
+\fBTcl_GetNumberFromObj\fR(\fIinterp, objPtr, clientDataPtr, typePtr\fR)
+.SH ARGUMENTS
+.AS Tcl_Interp clientDataPtr out
+.AP Tcl_Interp *interp out
+When non-NULL, error information is recorded here when the value is not
+in any of the numeric formats recognized by Tcl.
+.AP "const char" *bytes in
+Points to first byte of the string value to be examined.
+.AP size_t numBytes in
+The number of bytes, starting at \fIbytes\fR, that should be examined.
+If the value \fBTCL_INDEX_NONE\fR is provided, then all bytes should
+be examined until the first \fBNUL\fR byte terminates examination.
+.AP "void *" *clientDataPtr out
+Points to space where a pointer value may be written through which a numeric
+value is available to read.
+.AP int *typePtr out
+Points to space where a value may be written reporting what type of
+numeric storage is available to read.
+.AP Tcl_Obj *objPtr in
+A Tcl value to be examined.
+.BE
+.SH DESCRIPTION
+.PP
+These procedures enable callers to retrieve a numeric value from a
+Tcl value in a numeric format recognized by Tcl.
+.PP
+Tcl recognizes many values as numbers. Several examples include:
+\fB"0"\fR, \fB" +1"\fR, \fB"-2 "\fR, \fB" 3 "\fR, \fB"0xdad1"\fR, \fB"0d09"\fR,
+\fB"1_000_000"\fR, \fB"4.0"\fR, \fB"1e-7"\fR, \fB"NaN"\fR, or \fB"Inf"\fR.
+When built-in Tcl commands act on these values as numbers, they are converted
+to a numeric representation for efficient handling in C code. Tcl makes
+use of three C types to store these representations: \fBdouble\fR,
+\fBTcl_WideInt\fR, and \fBmp_int\fR. The \fBdouble\fR type is provided by the
+C language standard. The \fBTcl_WideInt\fR type is declared in the Tcl
+header file, \fBtcl.h\fR, and is equivalent to the C standard type
+\fBlong long\fR on most platforms. The \fBmp_int\fR type is declared in the
+header file \fBtclTomMath.h\fR, and implemented by the LibTomMath
+multiple-precision integer library, included with Tcl.
+.PP
+The routines \fBTcl_GetNumber\fR and \fBTcl_GetNumberFromObj\fR perform
+the same function. They differ only in how the arguments present the Tcl
+value to be examined. \fBTcl_GetNumber\fR accepts a counted string
+value in the arguments \fIbytes\fR and \fInumBytes\fR (or a
+\fBNUL\fR-terminated string value when \fInumBytes\fR is
+\fBTCL_INDEX_NONE\fR). \fBTcl_GetNumberFromObj\fR accepts the Tcl value
+in \fIobjPtr\fR.
+.PP
+Both routines examine the Tcl value and determine whether Tcl recognizes
+it as a number. If not, both routines return \fBTCL_ERROR\fR and (when
+\fIinterp\fR is not NULL) record an error message and error code
+in \fIinterp\fR.
+.PP
+If Tcl does recognize the examined value as a number, both routines return
+\fBTCL_OK\fR, and use the pointer arguments \fIclientDataPtr\fR
+and \fItypePtr\fR (which may not be NULL) to report information the
+caller can use to retrieve the numeric representation. Both routines
+write to *\fIclientDataPtr\fR a pointer to the internal storage location
+where Tcl holds the converted numeric value.
+.PP
+When the converted numeric value is stored as a \fBdouble\fR,
+a call to math library routine \fBisnan\fR determines whether that
+value is not a number (NaN). If so, both \fBTcl_GetNumber\fR and
+\fBTcl_GetNumberFromObj\fR write the value \fBTCL_NUMBER_NAN\fR
+to *\fItypePtr\fR. If not, both routines write the value
+\fBTCL_NUMBER_DOUBLE\fR to *\fItypePtr\fR. These routines report
+different type values in these cases because \fBTcl_GetDoubleFromObj\fR
+raises an error on NaN values. For both reported type values,
+the storage pointer may be cast to type \fBconst double *\fR and
+the \fBdouble\fR numeric value may be read through it.
+.PP
+When the converted numeric value is stored as a \fBTcl_WideInt\fR,
+both \fBTcl_GetNumber\fR and \fBTcl_GetNumberFromObj\fR write the
+value \fBTCL_NUMBER_INT\fR to *\fItypePtr\fR.
+The storage pointer may be cast to type \fBconst Tcl_WideInt *\fR and
+the \fBTcl_WideInt\fR numeric value may be read through it.
+.PP
+When the converted numeric value is stored as an \fBmp_int\fR,
+both \fBTcl_GetNumber\fR and \fBTcl_GetNumberFromObj\fR write the
+value \fBTCL_NUMBER_BIG\fR to *\fItypePtr\fR.
+The storage pointer may be cast to type \fBconst mp_int *\fR and
+the \fBmp_int\fR numeric value may be read through it.
+.PP
+Future releases of Tcl might expand or revise the recognition of
+values as numbers. If additional storage representations are
+adopted, these routines will add new values to be written to
+*\fItypePtr\fR to identify them. Callers should consider how
+they should react to unknown values written to *\fItypePtr\fR.
+.PP
+When callers of these routines read numeric values through the
+reported storage pointer, they are accessing memory that belongs
+to the Tcl library. The Tcl library has the power to overwrite
+or free this memory. The storage pointer reported by a call to
+\fBTcl_GetNumber\fR or \fBTcl_GetNumberFromObj\fR should not be
+used after the same thread has possibly returned control to the
+Tcl library. If longer term access to the numeric value is needed,
+it should be copied into memory controlled by the caller. Callers
+must not attempt to write through or free the storage pointer.
+.SH "SEE ALSO"
+Tcl_GetDouble, Tcl_GetDoubleFromObj, Tcl_GetWideIntFromObj
+.SH KEYWORDS
+double, double value, double type, integer, integer value, integer type,
+internal representation, value, value type, string representation
diff --git a/generic/tcl.decls b/generic/tcl.decls
index 95cecdf..268fe33 100644
--- a/generic/tcl.decls
+++ b/generic/tcl.decls
@@ -2532,7 +2532,15 @@ declare 679 {
void *clientData, size_t objc, Tcl_Obj *const objv[])
}
-# slot 680 and 681 are reserved for TIP #638
+# TIP #638.
+declare 680 {
+ int Tcl_GetNumberFromObj(Tcl_Interp *interp, Tcl_Obj *objPtr,
+ void **clientDataPtr, int *typePtr)
+}
+declare 681 {
+ int Tcl_GetNumber(Tcl_Interp *interp, const char *bytes, size_t numBytes,
+ void **clientDataPtr, int *typePtr)
+}
# TIP #220.
declare 682 {
diff --git a/generic/tcl.h b/generic/tcl.h
index 43975a3..849278b 100644
--- a/generic/tcl.h
+++ b/generic/tcl.h
@@ -976,6 +976,20 @@ typedef struct Tcl_DString {
#define TCL_INTEGER_SPACE (3*(int)sizeof(Tcl_WideInt))
/*
+ *----------------------------------------------------------------------------
+ * Type values returned by Tcl_GetNumberFromObj
+ * TCL_NUMBER_INT Representation is a Tcl_WideInt
+ * TCL_NUMBER_BIG Representation is an mp_int
+ * TCL_NUMBER_DOUBLE Representation is a double
+ * TCL_NUMBER_NAN Value is NaN.
+ */
+
+#define TCL_NUMBER_INT 2
+#define TCL_NUMBER_BIG 3
+#define TCL_NUMBER_DOUBLE 4
+#define TCL_NUMBER_NAN 5
+
+/*
* Flag values passed to Tcl_ConvertElement.
* TCL_DONT_USE_BRACES forces it not to enclose the element in braces, but to
* use backslash quoting instead.
diff --git a/generic/tclArithSeries.c b/generic/tclArithSeries.c
index 11a4254..b6f33a8 100755
--- a/generic/tclArithSeries.c
+++ b/generic/tclArithSeries.c
@@ -232,7 +232,7 @@ assignNumber(int useDoubles, Tcl_WideInt *intNumberPtr, double *dblNumberPtr, Tc
void *clientData;
int tcl_number_type;
- if (TclGetNumberFromObj(NULL, numberObj, &clientData, &tcl_number_type) != TCL_OK
+ if (Tcl_GetNumberFromObj(NULL, numberObj, &clientData, &tcl_number_type) != TCL_OK
|| tcl_number_type == TCL_NUMBER_BIG) {
return;
}
diff --git a/generic/tclBasic.c b/generic/tclBasic.c
index 73b997d..13715f8 100644
--- a/generic/tclBasic.c
+++ b/generic/tclBasic.c
@@ -4135,7 +4135,7 @@ OldMathFuncProc(
args = (Tcl_Value *)ckalloc(dataPtr->numArgs * sizeof(Tcl_Value));
for (j = 1, k = 0; j < objc; ++j, ++k) {
- /* TODO: Convert to TclGetNumberFromObj? */
+ /* TODO: Convert to Tcl_GetNumberFromObj? */
valuePtr = objv[j];
result = Tcl_GetDoubleFromObj(NULL, valuePtr, &d);
#ifdef ACCEPT_NAN
@@ -7043,7 +7043,7 @@ Tcl_ExprLongObj(
return TCL_ERROR;
}
- if (TclGetNumberFromObj(interp, resultPtr, &internalPtr, &type)!=TCL_OK) {
+ if (Tcl_GetNumberFromObj(interp, resultPtr, &internalPtr, &type)!=TCL_OK) {
return TCL_ERROR;
}
@@ -7089,7 +7089,7 @@ Tcl_ExprDoubleObj(
return TCL_ERROR;
}
- result = TclGetNumberFromObj(interp, resultPtr, &internalPtr, &type);
+ result = Tcl_GetNumberFromObj(interp, resultPtr, &internalPtr, &type);
if (result == TCL_OK) {
switch (type) {
case TCL_NUMBER_NAN:
@@ -7810,7 +7810,7 @@ ExprIsqrtFunc(
* Make sure that the arg is a number.
*/
- if (TclGetNumberFromObj(interp, objv[1], &ptr, &type) != TCL_OK) {
+ if (Tcl_GetNumberFromObj(interp, objv[1], &ptr, &type) != TCL_OK) {
return TCL_ERROR;
}
@@ -8073,7 +8073,7 @@ ExprAbsFunc(
return TCL_ERROR;
}
- if (TclGetNumberFromObj(interp, objv[1], &ptr, &type) != TCL_OK) {
+ if (Tcl_GetNumberFromObj(interp, objv[1], &ptr, &type) != TCL_OK) {
return TCL_ERROR;
}
@@ -8228,7 +8228,7 @@ ExprIntFunc(
MathFuncWrongNumArgs(interp, 2, objc, objv);
return TCL_ERROR;
}
- if (TclGetNumberFromObj(interp, objv[1], &ptr, &type) != TCL_OK) {
+ if (Tcl_GetNumberFromObj(interp, objv[1], &ptr, &type) != TCL_OK) {
return TCL_ERROR;
}
@@ -8309,7 +8309,7 @@ ExprMaxMinFunc(
}
res = objv[1];
for (i = 1; i < objc; i++) {
- if (TclGetNumberFromObj(interp, objv[i], &ptr, &type) != TCL_OK) {
+ if (Tcl_GetNumberFromObj(interp, objv[i], &ptr, &type) != TCL_OK) {
return TCL_ERROR;
}
if (type == TCL_NUMBER_NAN) {
@@ -8461,7 +8461,7 @@ ExprRoundFunc(
return TCL_ERROR;
}
- if (TclGetNumberFromObj(interp, objv[1], &ptr, &type) != TCL_OK) {
+ if (Tcl_GetNumberFromObj(interp, objv[1], &ptr, &type) != TCL_OK) {
return TCL_ERROR;
}
@@ -8729,7 +8729,7 @@ ExprIsFiniteFunc(
return TCL_ERROR;
}
- if (TclGetNumberFromObj(interp, objv[1], &ptr, &type) != TCL_OK) {
+ if (Tcl_GetNumberFromObj(interp, objv[1], &ptr, &type) != TCL_OK) {
return TCL_ERROR;
}
if (type != TCL_NUMBER_NAN) {
@@ -8760,7 +8760,7 @@ ExprIsInfinityFunc(
return TCL_ERROR;
}
- if (TclGetNumberFromObj(interp, objv[1], &ptr, &type) != TCL_OK) {
+ if (Tcl_GetNumberFromObj(interp, objv[1], &ptr, &type) != TCL_OK) {
return TCL_ERROR;
}
if (type != TCL_NUMBER_NAN) {
@@ -8790,7 +8790,7 @@ ExprIsNaNFunc(
return TCL_ERROR;
}
- if (TclGetNumberFromObj(interp, objv[1], &ptr, &type) != TCL_OK) {
+ if (Tcl_GetNumberFromObj(interp, objv[1], &ptr, &type) != TCL_OK) {
return TCL_ERROR;
}
if (type != TCL_NUMBER_NAN) {
@@ -8820,7 +8820,7 @@ ExprIsNormalFunc(
return TCL_ERROR;
}
- if (TclGetNumberFromObj(interp, objv[1], &ptr, &type) != TCL_OK) {
+ if (Tcl_GetNumberFromObj(interp, objv[1], &ptr, &type) != TCL_OK) {
return TCL_ERROR;
}
if (type != TCL_NUMBER_NAN) {
@@ -8850,7 +8850,7 @@ ExprIsSubnormalFunc(
return TCL_ERROR;
}
- if (TclGetNumberFromObj(interp, objv[1], &ptr, &type) != TCL_OK) {
+ if (Tcl_GetNumberFromObj(interp, objv[1], &ptr, &type) != TCL_OK) {
return TCL_ERROR;
}
if (type != TCL_NUMBER_NAN) {
@@ -8880,7 +8880,7 @@ ExprIsUnorderedFunc(
return TCL_ERROR;
}
- if (TclGetNumberFromObj(interp, objv[1], &ptr, &type) != TCL_OK) {
+ if (Tcl_GetNumberFromObj(interp, objv[1], &ptr, &type) != TCL_OK) {
return TCL_ERROR;
}
if (type == TCL_NUMBER_NAN) {
@@ -8890,7 +8890,7 @@ ExprIsUnorderedFunc(
result = (ClassifyDouble(d) == FP_NAN);
}
- if (TclGetNumberFromObj(interp, objv[2], &ptr, &type) != TCL_OK) {
+ if (Tcl_GetNumberFromObj(interp, objv[2], &ptr, &type) != TCL_OK) {
return TCL_ERROR;
}
if (type == TCL_NUMBER_NAN) {
@@ -8922,7 +8922,7 @@ FloatClassifyObjCmd(
return TCL_ERROR;
}
- if (TclGetNumberFromObj(interp, objv[1], &ptr, &type) != TCL_OK) {
+ if (Tcl_GetNumberFromObj(interp, objv[1], &ptr, &type) != TCL_OK) {
return TCL_ERROR;
}
if (type == TCL_NUMBER_NAN) {
diff --git a/generic/tclCmdIL.c b/generic/tclCmdIL.c
index 62ceeea..4b7bd48 100644
--- a/generic/tclCmdIL.c
+++ b/generic/tclCmdIL.c
@@ -4079,7 +4079,7 @@ SequenceIdentifyArgument(
SequenceByMode bymode;
void *clientData;
- status = TclGetNumberFromObj(NULL, argPtr, &clientData, keywordIndexPtr);
+ status = Tcl_GetNumberFromObj(NULL, argPtr, &clientData, keywordIndexPtr);
if (status == TCL_OK) {
if (numValuePtr) {
*numValuePtr = argPtr;
diff --git a/generic/tclDecls.h b/generic/tclDecls.h
index 80131e8..e54ea2c 100644
--- a/generic/tclDecls.h
+++ b/generic/tclDecls.h
@@ -2008,8 +2008,14 @@ EXTERN Tcl_Command Tcl_NRCreateCommand2(Tcl_Interp *interp,
EXTERN int Tcl_NRCallObjProc2(Tcl_Interp *interp,
Tcl_ObjCmdProc2 *objProc2, void *clientData,
size_t objc, Tcl_Obj *const objv[]);
-/* Slot 680 is reserved */
-/* Slot 681 is reserved */
+/* 680 */
+EXTERN int Tcl_GetNumberFromObj(Tcl_Interp *interp,
+ Tcl_Obj *objPtr, void **clientDataPtr,
+ int *typePtr);
+/* 681 */
+EXTERN int Tcl_GetNumber(Tcl_Interp *interp, const char *bytes,
+ size_t numBytes, void **clientDataPtr,
+ int *typePtr);
/* 682 */
EXTERN int Tcl_RemoveChannelMode(Tcl_Interp *interp,
Tcl_Channel chan, int mode);
@@ -2728,8 +2734,8 @@ typedef struct TclStubs {
Tcl_Trace (*tcl_CreateObjTrace2) (Tcl_Interp *interp, int level, int flags, Tcl_CmdObjTraceProc2 *objProc2, void *clientData, Tcl_CmdObjTraceDeleteProc *delProc); /* 677 */
Tcl_Command (*tcl_NRCreateCommand2) (Tcl_Interp *interp, const char *cmdName, Tcl_ObjCmdProc2 *proc, Tcl_ObjCmdProc2 *nreProc2, void *clientData, Tcl_CmdDeleteProc *deleteProc); /* 678 */
int (*tcl_NRCallObjProc2) (Tcl_Interp *interp, Tcl_ObjCmdProc2 *objProc2, void *clientData, size_t objc, Tcl_Obj *const objv[]); /* 679 */
- void (*reserved680)(void);
- void (*reserved681)(void);
+ int (*tcl_GetNumberFromObj) (Tcl_Interp *interp, Tcl_Obj *objPtr, void **clientDataPtr, int *typePtr); /* 680 */
+ int (*tcl_GetNumber) (Tcl_Interp *interp, const char *bytes, size_t numBytes, void **clientDataPtr, int *typePtr); /* 681 */
int (*tcl_RemoveChannelMode) (Tcl_Interp *interp, Tcl_Channel chan, int mode); /* 682 */
} TclStubs;
@@ -4121,8 +4127,10 @@ extern const TclStubs *tclStubsPtr;
(tclStubsPtr->tcl_NRCreateCommand2) /* 678 */
#define Tcl_NRCallObjProc2 \
(tclStubsPtr->tcl_NRCallObjProc2) /* 679 */
-/* Slot 680 is reserved */
-/* Slot 681 is reserved */
+#define Tcl_GetNumberFromObj \
+ (tclStubsPtr->tcl_GetNumberFromObj) /* 680 */
+#define Tcl_GetNumber \
+ (tclStubsPtr->tcl_GetNumber) /* 681 */
#define Tcl_RemoveChannelMode \
(tclStubsPtr->tcl_RemoveChannelMode) /* 682 */
diff --git a/generic/tclExecute.c b/generic/tclExecute.c
index 47cb5e6..408032b 100644
--- a/generic/tclExecute.c
+++ b/generic/tclExecute.c
@@ -503,7 +503,7 @@ VarHashCreateVar(
/*
* Macro used in this file to save a function call for common uses of
- * TclGetNumberFromObj(). The ANSI C "prototype" is:
+ * Tcl_GetNumberFromObj(). The ANSI C "prototype" is:
*
* MODULE_SCOPE int GetNumberFromObj(Tcl_Interp *interp, Tcl_Obj *objPtr,
* void **ptrPtr, int *tPtr);
@@ -522,7 +522,7 @@ VarHashCreateVar(
(&((objPtr)->internalRep.doubleValue)), TCL_OK) : \
(((objPtr)->bytes != NULL) && ((objPtr)->length == 0)) \
? TCL_ERROR : \
- TclGetNumberFromObj((interp), (objPtr), (ptrPtr), (tPtr)))
+ Tcl_GetNumberFromObj((interp), (objPtr), (ptrPtr), (tPtr)))
/*
* Macro used to make the check for type overflow more mnemonic. This works by
diff --git a/generic/tclInt.h b/generic/tclInt.h
index c15293a..0092322 100644
--- a/generic/tclInt.h
+++ b/generic/tclInt.h
@@ -2877,21 +2877,6 @@ typedef struct ProcessGlobalValue {
/* Reject underscore digit separator */
/*
- *----------------------------------------------------------------------
- * Type values TclGetNumberFromObj
- *----------------------------------------------------------------------
- */
-
-#define TCL_NUMBER_INT 2
-#if !defined(TCL_NO_DEPRECATED)
-# define TCL_NUMBER_LONG 1 /* deprecated, not used any more */
-# define TCL_NUMBER_WIDE TCL_NUMBER_INT /* deprecated */
-#endif
-#define TCL_NUMBER_BIG 3
-#define TCL_NUMBER_DOUBLE 4
-#define TCL_NUMBER_NAN 5
-
-/*
*----------------------------------------------------------------
* Variables shared among Tcl modules but not used by the outside world.
*----------------------------------------------------------------
@@ -3202,9 +3187,6 @@ MODULE_SCOPE int TclGetCompletionCodeFromObj(Tcl_Interp *interp,
Tcl_Obj *value, int *code);
MODULE_SCOPE Proc * TclGetLambdaFromObj(Tcl_Interp *interp,
Tcl_Obj *objPtr, Tcl_Obj **nsObjPtrPtr);
-MODULE_SCOPE int TclGetNumberFromObj(Tcl_Interp *interp,
- Tcl_Obj *objPtr, void **clientDataPtr,
- int *typePtr);
MODULE_SCOPE int TclGetOpenModeEx(Tcl_Interp *interp,
const char *modeString, int *seekFlagPtr,
int *binaryPtr);
diff --git a/generic/tclLink.c b/generic/tclLink.c
index 6bd65fa..0d57d44 100644
--- a/generic/tclLink.c
+++ b/generic/tclLink.c
@@ -530,7 +530,7 @@ GetUWide(
void *clientData;
int type, intValue;
- if (TclGetNumberFromObj(NULL, objPtr, &clientData, &type) == TCL_OK) {
+ if (Tcl_GetNumberFromObj(NULL, objPtr, &clientData, &type) == TCL_OK) {
if (type == TCL_NUMBER_INT) {
*widePtr = *((const Tcl_WideInt *) clientData);
return (*widePtr < 0);
diff --git a/generic/tclObj.c b/generic/tclObj.c
index 4963b22..8970ab0 100644
--- a/generic/tclObj.c
+++ b/generic/tclObj.c
@@ -3897,7 +3897,7 @@ TclSetBignumInternalRep(
/*
*----------------------------------------------------------------------
*
- * TclGetNumberFromObj --
+ * Tcl_GetNumberFromObj --
*
* Extracts a number (of any possible numeric type) from an object.
*
@@ -3915,7 +3915,7 @@ TclSetBignumInternalRep(
*/
int
-TclGetNumberFromObj(
+Tcl_GetNumberFromObj(
Tcl_Interp *interp,
Tcl_Obj *objPtr,
void **clientDataPtr,
@@ -3950,6 +3950,42 @@ TclGetNumberFromObj(
TclParseNumber(interp, objPtr, "number", NULL, -1, NULL, 0));
return TCL_ERROR;
}
+
+int
+Tcl_GetNumber(
+ Tcl_Interp *interp,
+ const char *bytes,
+ size_t numBytes,
+ ClientData *clientDataPtr,
+ int *typePtr)
+{
+ static Tcl_ThreadDataKey numberCacheKey;
+ Tcl_Obj *objPtr = (Tcl_Obj *)Tcl_GetThreadData(&numberCacheKey,
+ sizeof(Tcl_Obj));
+
+ Tcl_FreeInternalRep(objPtr);
+
+ if (bytes == NULL) {
+ bytes = &tclEmptyString;
+ numBytes = 0;
+ }
+ if (numBytes == (size_t)TCL_INDEX_NONE) {
+ numBytes = strlen(bytes);
+ }
+ if (numBytes > INT_MAX) {
+ if (interp) {
+ Tcl_SetObjResult(interp, Tcl_ObjPrintf(
+ "max size for a Tcl value (%d bytes) exceeded", INT_MAX));
+ Tcl_SetErrorCode(interp, "TCL", "MEMORY", NULL);
+ }
+ return TCL_ERROR;
+ }
+
+ objPtr->bytes = (char *) bytes;
+ objPtr->length = numBytes;
+
+ return Tcl_GetNumberFromObj(interp, objPtr, clientDataPtr, typePtr);
+}
/*
*----------------------------------------------------------------------
diff --git a/generic/tclStubInit.c b/generic/tclStubInit.c
index c7f178f..e6f6b5c 100644
--- a/generic/tclStubInit.c
+++ b/generic/tclStubInit.c
@@ -2045,8 +2045,8 @@ const TclStubs tclStubs = {
Tcl_CreateObjTrace2, /* 677 */
Tcl_NRCreateCommand2, /* 678 */
Tcl_NRCallObjProc2, /* 679 */
- 0, /* 680 */
- 0, /* 681 */
+ Tcl_GetNumberFromObj, /* 680 */
+ Tcl_GetNumber, /* 681 */
Tcl_RemoveChannelMode, /* 682 */
};
diff --git a/generic/tclUtil.c b/generic/tclUtil.c
index f10187b..ab97461 100644
--- a/generic/tclUtil.c
+++ b/generic/tclUtil.c
@@ -3648,7 +3648,7 @@ GetWideForIndex(
{
int numType;
void *cd;
- int code = TclGetNumberFromObj(NULL, objPtr, &cd, &numType);
+ int code = Tcl_GetNumberFromObj(NULL, objPtr, &cd, &numType);
if (code == TCL_OK) {
if (numType == TCL_NUMBER_INT) {
@@ -3812,7 +3812,7 @@ GetEndOffsetFromObj(
/* ... value continues with [-+] ... */
/* Save first integer as wide if possible */
- TclGetNumberFromObj(NULL, objPtr, &cd, &t1);
+ Tcl_GetNumberFromObj(NULL, objPtr, &cd, &t1);
if (t1 == TCL_NUMBER_INT) {
w1 = (*(Tcl_WideInt *)cd);
}
@@ -3822,7 +3822,7 @@ GetEndOffsetFromObj(
/* ... value concludes with second valid integer */
/* Save second integer as wide if possible */
- TclGetNumberFromObj(NULL, objPtr, &cd, &t2);
+ Tcl_GetNumberFromObj(NULL, objPtr, &cd, &t2);
if (t2 == TCL_NUMBER_INT) {
w2 = (*(Tcl_WideInt *)cd);
}
@@ -3875,7 +3875,7 @@ GetEndOffsetFromObj(
Tcl_ExprObj(compute, objPtr, &sum);
Tcl_DeleteInterp(compute);
}
- TclGetNumberFromObj(NULL, sum, &cd, &numType);
+ Tcl_GetNumberFromObj(NULL, sum, &cd, &numType);
if (numType == TCL_NUMBER_INT) {
/* sum holds an integer in the signed wide range */
@@ -3926,7 +3926,7 @@ GetEndOffsetFromObj(
}
/* Got an integer offset; pull it from where parser left it. */
- TclGetNumberFromObj(NULL, objPtr, &cd, &t);
+ Tcl_GetNumberFromObj(NULL, objPtr, &cd, &t);
if (t == TCL_NUMBER_BIG) {
/* Truncate to the signed wide range. */