summaryrefslogtreecommitdiffstats
path: root/generic/tclUtil.c
diff options
context:
space:
mode:
Diffstat (limited to 'generic/tclUtil.c')
-rw-r--r--generic/tclUtil.c79
1 files changed, 26 insertions, 53 deletions
diff --git a/generic/tclUtil.c b/generic/tclUtil.c
index 15018de..6c4e23c 100644
--- a/generic/tclUtil.c
+++ b/generic/tclUtil.c
@@ -110,7 +110,6 @@ static void FreeThreadHash(ClientData clientData);
static Tcl_HashTable * GetThreadHash(Tcl_ThreadDataKey *keyPtr);
static int SetEndOffsetFromAny(Tcl_Interp *interp,
Tcl_Obj *objPtr);
-static void UpdateStringOfEndOffset(Tcl_Obj *objPtr);
static int FindElement(Tcl_Interp *interp, const char *string,
int stringLength, const char *typeStr,
const char *typeCode, const char **elementPtr,
@@ -119,15 +118,18 @@ static int FindElement(Tcl_Interp *interp, const char *string,
/*
* The following is the Tcl object type definition for an object that
* represents a list index in the form, "end-offset". It is used as a
- * performance optimization in TclGetIntForIndex. The internal rep is an
- * integer, so no memory management is required for it.
+ * performance optimization in TclGetIntForIndex. The internal rep is
+ * stored directly in the wideValue, so no memory management is required
+ * for it. This is a caching intrep, keeping the result of a parse
+ * around. This type is only created from a pre-existing string, so an
+ * updateStringProc will never be called and need not exist.
*/
-const Tcl_ObjType tclEndOffsetType = {
+static const Tcl_ObjType endOffsetType = {
"end-offset", /* name */
NULL, /* freeIntRepProc */
NULL, /* dupIntRepProc */
- UpdateStringOfEndOffset, /* updateStringProc */
+ NULL, /* updateStringProc */
SetEndOffsetFromAny
};
@@ -1604,6 +1606,7 @@ Tcl_Merge(
return result;
}
+#if !defined(TCL_NO_DEPRECATED) && TCL_MAJOR_VERSION < 9
/*
*----------------------------------------------------------------------
*
@@ -1637,6 +1640,7 @@ Tcl_Backslash(
TclUtfToUniChar(buf, &ch);
return (char) ch;
}
+#endif /* !TCL_NO_DEPRECATED */
/*
*----------------------------------------------------------------------
@@ -2528,7 +2532,8 @@ TclStringMatchObj(
udata = Tcl_GetUnicodeFromObj(strObj, &length);
uptn = Tcl_GetUnicodeFromObj(ptnObj, &plen);
match = TclUniCharMatch(udata, length, uptn, plen, flags);
- } else if (TclIsPureByteArray(strObj) && !flags) {
+ } else if (TclIsPureByteArray(strObj) && TclIsPureByteArray(ptnObj)
+ && !flags) {
unsigned char *data, *ptn;
data = Tcl_GetByteArrayFromObj(strObj, &length);
@@ -3474,9 +3479,9 @@ int
TclFormatInt(
char *buffer, /* Points to the storage into which the
* formatted characters are written. */
- long n) /* The integer to format. */
+ Tcl_WideInt n) /* The integer to format. */
{
- long intVal;
+ Tcl_WideInt intVal;
int i;
int numFormatted, j;
const char *digits = "0123456789";
@@ -3499,7 +3504,7 @@ TclFormatInt(
intVal = -n; /* [Bug 3390638] Workaround for*/
if (n == -n || intVal == n) { /* broken compiler optimizers. */
- return sprintf(buffer, "%ld", n);
+ return sprintf(buffer, "%" TCL_LL_MODIFIER "d", n);
}
/*
@@ -3583,7 +3588,7 @@ TclGetIntForIndex(
* be converted to one, use it.
*/
- *indexPtr = endValue + objPtr->internalRep.longValue;
+ *indexPtr = endValue + (int)objPtr->internalRep.wideValue;
return TCL_OK;
}
@@ -3650,43 +3655,6 @@ TclGetIntForIndex(
/*
*----------------------------------------------------------------------
*
- * UpdateStringOfEndOffset --
- *
- * Update the string rep of a Tcl object holding an "end-offset"
- * expression.
- *
- * Results:
- * None.
- *
- * Side effects:
- * Stores a valid string in the object's string rep.
- *
- * This function does NOT free any earlier string rep. If it is called on an
- * object that already has a valid string rep, it will leak memory.
- *
- *----------------------------------------------------------------------
- */
-
-static void
-UpdateStringOfEndOffset(
- register Tcl_Obj *objPtr)
-{
- char buffer[TCL_INTEGER_SPACE + 5];
- register int len = 3;
-
- memcpy(buffer, "end", 4);
- if (objPtr->internalRep.longValue != 0) {
- buffer[len++] = '-';
- len += TclFormatInt(buffer+len, -(objPtr->internalRep.longValue));
- }
- objPtr->bytes = ckalloc((unsigned) len+1);
- memcpy(objPtr->bytes, buffer, (unsigned) len+1);
- objPtr->length = len;
-}
-
-/*
- *----------------------------------------------------------------------
- *
* SetEndOffsetFromAny --
*
* Look for a string of the form "end[+-]offset" and convert it to an
@@ -3707,7 +3675,7 @@ SetEndOffsetFromAny(
Tcl_Interp *interp, /* Tcl interpreter or NULL */
Tcl_Obj *objPtr) /* Pointer to the object to parse */
{
- int offset; /* Offset in the "end-offset" expression */
+ Tcl_WideInt offset; /* Offset in the "end-offset" expression */
register const char *bytes; /* String rep of the object */
int length; /* Length of the object's string rep */
@@ -3715,7 +3683,7 @@ SetEndOffsetFromAny(
* If it's already the right type, we're fine.
*/
- if (objPtr->typePtr == &tclEndOffsetType) {
+ if (objPtr->typePtr == &endOffsetType) {
return TCL_OK;
}
@@ -3743,15 +3711,20 @@ SetEndOffsetFromAny(
} else if ((length > 4) && ((bytes[3] == '-') || (bytes[3] == '+'))) {
/*
* This is our limited string expression evaluator. Pass everything
- * after "end-" to Tcl_GetInt, then reverse for offset.
+ * after "end-" to TclParseNumber.
*/
if (TclIsSpaceProc(bytes[4])) {
goto badIndexFormat;
}
- if (Tcl_GetInt(interp, bytes+4, &offset) != TCL_OK) {
+ if (TclParseNumber(NULL, objPtr, NULL, bytes+4, length-4, NULL,
+ TCL_PARSE_INTEGER_ONLY) != TCL_OK) {
return TCL_ERROR;
}
+ if (objPtr->typePtr != &tclIntType) {
+ goto badIndexFormat;
+ }
+ offset = objPtr->internalRep.wideValue;
if (bytes[3] == '-') {
offset = -offset;
}
@@ -3775,8 +3748,8 @@ SetEndOffsetFromAny(
*/
TclFreeIntRep(objPtr);
- objPtr->internalRep.longValue = offset;
- objPtr->typePtr = &tclEndOffsetType;
+ objPtr->internalRep.wideValue = offset;
+ objPtr->typePtr = &endOffsetType;
return TCL_OK;
}