summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--doc/GetIndex.35
-rw-r--r--doc/try.n2
-rw-r--r--generic/tcl.decls2
-rw-r--r--generic/tclDecls.h9
-rw-r--r--generic/tclExecute.c6
-rw-r--r--generic/tclIndexObj.c41
-rw-r--r--generic/tclStringObj.c4
-rw-r--r--generic/tclTest.c13
8 files changed, 54 insertions, 28 deletions
diff --git a/doc/GetIndex.3 b/doc/GetIndex.3
index 1af1663..fa8455a 100644
--- a/doc/GetIndex.3
+++ b/doc/GetIndex.3
@@ -55,9 +55,10 @@ Null-terminated string describing what is being looked up, such as
OR-ed combination of bits providing additional information for
operation. The only bits that are currently defined are \fBTCL_EXACT\fR
, \fBTCL_INDEX_TEMP_TABLE\fR, and \fBTCL_INDEX_NULL_OK\fR.
-.AP int *indexPtr out
+.AP enum|char|short|int|long *indexPtr out
The index of the string in \fItablePtr\fR that matches the value of
-\fIobjPtr\fR is returned here.
+\fIobjPtr\fR is returned here. The variable can be any integer type,
+signed or unsigned, char, short, long or long long. It can also be an enum.
.BE
.SH DESCRIPTION
.PP
diff --git a/doc/try.n b/doc/try.n
index eae4dc7..992dcea 100644
--- a/doc/try.n
+++ b/doc/try.n
@@ -87,7 +87,7 @@ Handle different reasons for a file to not be openable for reading:
.PP
.CS
\fBtry\fR {
- set f [open /some/file/name w]
+ set f [open /some/file/name r]
} \fBtrap\fR {POSIX EISDIR} {} {
puts "failed to open /some/file/name: it's a directory"
} \fBtrap\fR {POSIX ENOENT} {} {
diff --git a/generic/tcl.decls b/generic/tcl.decls
index bd9800a..c137a88 100644
--- a/generic/tcl.decls
+++ b/generic/tcl.decls
@@ -1092,7 +1092,7 @@ declare 303 {
declare 304 {
int Tcl_GetIndexFromObjStruct(Tcl_Interp *interp, Tcl_Obj *objPtr,
const void *tablePtr, int offset, const char *msg, int flags,
- int *indexPtr)
+ void *indexPtr)
}
declare 305 {
void *Tcl_GetThreadData(Tcl_ThreadDataKey *keyPtr, int size)
diff --git a/generic/tclDecls.h b/generic/tclDecls.h
index 6ca7633..4995f74 100644
--- a/generic/tclDecls.h
+++ b/generic/tclDecls.h
@@ -945,7 +945,7 @@ EXTERN void Tcl_GetEncodingNames(Tcl_Interp *interp);
EXTERN int Tcl_GetIndexFromObjStruct(Tcl_Interp *interp,
Tcl_Obj *objPtr, const void *tablePtr,
int offset, const char *msg, int flags,
- int *indexPtr);
+ void *indexPtr);
/* 305 */
EXTERN void * Tcl_GetThreadData(Tcl_ThreadDataKey *keyPtr,
int size);
@@ -2287,7 +2287,7 @@ typedef struct TclStubs {
Tcl_Encoding (*tcl_GetEncoding) (Tcl_Interp *interp, const char *name); /* 301 */
const char * (*tcl_GetEncodingName) (Tcl_Encoding encoding); /* 302 */
void (*tcl_GetEncodingNames) (Tcl_Interp *interp); /* 303 */
- int (*tcl_GetIndexFromObjStruct) (Tcl_Interp *interp, Tcl_Obj *objPtr, const void *tablePtr, int offset, const char *msg, int flags, int *indexPtr); /* 304 */
+ int (*tcl_GetIndexFromObjStruct) (Tcl_Interp *interp, Tcl_Obj *objPtr, const void *tablePtr, int offset, const char *msg, int flags, void *indexPtr); /* 304 */
void * (*tcl_GetThreadData) (Tcl_ThreadDataKey *keyPtr, int size); /* 305 */
Tcl_Obj * (*tcl_GetVar2Ex) (Tcl_Interp *interp, const char *part1, const char *part2, int flags); /* 306 */
ClientData (*tcl_InitNotifier) (void); /* 307 */
@@ -4209,6 +4209,7 @@ extern const TclStubs *tclStubsPtr;
#define Tcl_GetUnicode(objPtr) \
Tcl_GetUnicodeFromObj(objPtr, (int *)NULL)
#undef Tcl_GetBytesFromObj
+#undef Tcl_GetIndexFromObjStruct
#ifdef TCL_NO_DEPRECATED
#undef Tcl_GetStringFromObj
#undef Tcl_GetUnicodeFromObj
@@ -4217,6 +4218,8 @@ extern const TclStubs *tclStubsPtr;
#if defined(USE_TCL_STUBS)
#define Tcl_GetBytesFromObj(interp, objPtr, sizePtr) \
(sizeof(*sizePtr) <= sizeof(int) ? tclStubsPtr->tclGetBytesFromObj(interp, objPtr, (int *)sizePtr) : tclStubsPtr->tcl_GetBytesFromObj(interp, objPtr, (size_t *)sizePtr))
+#define Tcl_GetIndexFromObjStruct(interp, objPtr, tablePtr, offset, msg, flags, indexPtr) \
+ (tclStubsPtr->tcl_GetIndexFromObjStruct((interp), (objPtr), (tablePtr), (offset), (msg), (flags)|(int)(sizeof(*indexPtr)<<8), (indexPtr)))
#ifdef TCL_NO_DEPRECATED
#define Tcl_GetStringFromObj(objPtr, sizePtr) \
(sizeof(*sizePtr) <= sizeof(int) ? tclStubsPtr->tcl_GetStringFromObj(objPtr, (int *)sizePtr) : tclStubsPtr->tclGetStringFromObj(objPtr, (size_t *)sizePtr))
@@ -4228,6 +4231,8 @@ extern const TclStubs *tclStubsPtr;
#else
#define Tcl_GetBytesFromObj(interp, objPtr, sizePtr) \
(sizeof(*sizePtr) <= sizeof(int) ? (TclGetBytesFromObj)(interp, objPtr, (int *)sizePtr) : (Tcl_GetBytesFromObj)(interp, objPtr, (size_t *)sizePtr))
+#define Tcl_GetIndexFromObjStruct(interp, objPtr, tablePtr, offset, msg, flags, indexPtr) \
+ ((Tcl_GetIndexFromObjStruct)((interp), (objPtr), (tablePtr), (offset), (msg), (flags)|(int)(sizeof(*indexPtr)<<8), (indexPtr)))
#ifdef TCL_NO_DEPRECATED
#define Tcl_GetStringFromObj(objPtr, sizePtr) \
(sizeof(*sizePtr) <= sizeof(int) ? (Tcl_GetStringFromObj)(objPtr, (int *)sizePtr) : (TclGetStringFromObj)(objPtr, (size_t *)sizePtr))
diff --git a/generic/tclExecute.c b/generic/tclExecute.c
index 73bd0e9..bbb7dee 100644
--- a/generic/tclExecute.c
+++ b/generic/tclExecute.c
@@ -6017,10 +6017,10 @@ TEBCresume(
* Handle shifts within the native long range.
*/
- if ((size_t) shift < CHAR_BIT*sizeof(long) && (w1 != 0)
+ if (((size_t) shift < CHAR_BIT*sizeof(long))
&& !((w1>0 ? w1 : ~w1) &
- -(1L<<(CHAR_BIT*sizeof(long) - 1 - shift)))) {
- wResult = w1 << shift;
+ -(1UL<<(CHAR_BIT*sizeof(long) - 1 - shift)))) {
+ wResult = (unsigned long)w1 << shift;
goto wideResultOfArithmetic;
}
}
diff --git a/generic/tclIndexObj.c b/generic/tclIndexObj.c
index c6dd15a..cb376f3 100644
--- a/generic/tclIndexObj.c
+++ b/generic/tclIndexObj.c
@@ -73,7 +73,7 @@ typedef struct {
#define NEXT_ENTRY(table, offset) \
(&(STRING_AT(table, offset)))
#define EXPAND_OF(indexRep) \
- STRING_AT((indexRep)->tablePtr, (indexRep)->offset*(indexRep)->index)
+ (((indexRep)->index >= 0) ? STRING_AT((indexRep)->tablePtr, (indexRep)->offset*(indexRep)->index) : "")
/*
*----------------------------------------------------------------------
@@ -249,6 +249,7 @@ GetIndexFromObjList(
*----------------------------------------------------------------------
*/
+#undef Tcl_GetIndexFromObjStruct
int
Tcl_GetIndexFromObjStruct(
Tcl_Interp *interp, /* Used for error reporting if not NULL. */
@@ -262,7 +263,7 @@ Tcl_GetIndexFromObjStruct(
const char *msg, /* Identifying word to use in error
* messages. */
int flags, /* 0, TCL_EXACT, TCL_INDEX_TEMP_TABLE or TCL_INDEX_NULL_OK */
- int *indexPtr) /* Place to store resulting integer index. */
+ void *indexPtr) /* Place to store resulting index. */
{
int index, idx, numAbbrev;
const char *key, *p1;
@@ -280,16 +281,15 @@ Tcl_GetIndexFromObjStruct(
* See if there is a valid cached result from a previous lookup.
*/
- if (!objPtr && (flags & TCL_INDEX_NULL_OK)) {
- *indexPtr = -1;
- return TCL_OK;
- } else if (objPtr && !(flags & TCL_INDEX_TEMP_TABLE)) {
+ if (objPtr && !(flags & TCL_INDEX_TEMP_TABLE)) {
irPtr = TclFetchInternalRep(objPtr, &indexType);
if (irPtr) {
indexRep = (IndexRep *)irPtr->twoPtrValue.ptr1;
- if (indexRep->tablePtr==tablePtr && indexRep->offset==offset) {
- *indexPtr = indexRep->index;
- return TCL_OK;
+ if ((indexRep->tablePtr == tablePtr)
+ && (indexRep->offset == offset)
+ && (indexRep->index >= 0)) {
+ index = indexRep->index;
+ goto uncachedDone;
}
}
}
@@ -304,8 +304,7 @@ Tcl_GetIndexFromObjStruct(
numAbbrev = 0;
if (!*key && (flags & TCL_INDEX_NULL_OK)) {
- *indexPtr = -1;
- return TCL_OK;
+ goto uncachedDone;
}
/*
* Scan the table looking for one of:
@@ -351,7 +350,7 @@ Tcl_GetIndexFromObjStruct(
* operation.
*/
- if (objPtr && !(flags & TCL_INDEX_TEMP_TABLE)) {
+ if (objPtr && (index >= 0) && !(flags & TCL_INDEX_TEMP_TABLE)) {
irPtr = TclFetchInternalRep(objPtr, &indexType);
if (irPtr) {
indexRep = (IndexRep *)irPtr->twoPtrValue.ptr1;
@@ -367,7 +366,23 @@ Tcl_GetIndexFromObjStruct(
indexRep->index = index;
}
- *indexPtr = index;
+ uncachedDone:
+ if ((flags>>8) & (int)~sizeof(int)) {
+ if ((flags>>8) == sizeof(uint64_t)) {
+ *(uint64_t *)indexPtr = index;
+ return TCL_OK;
+ } else if ((flags>>8) == sizeof(uint32_t)) {
+ *(uint32_t *)indexPtr = index;
+ return TCL_OK;
+ } else if ((flags>>8) == sizeof(uint16_t)) {
+ *(uint16_t *)indexPtr = index;
+ return TCL_OK;
+ } else if ((flags>>8) == sizeof(uint8_t)) {
+ *(uint8_t *)indexPtr = index;
+ return TCL_OK;
+ }
+ }
+ *(int *)indexPtr = index;
return TCL_OK;
error:
diff --git a/generic/tclStringObj.c b/generic/tclStringObj.c
index 4735f43..428f758 100644
--- a/generic/tclStringObj.c
+++ b/generic/tclStringObj.c
@@ -1674,10 +1674,10 @@ AppendUtfToUtfRep(
objPtr->length = 0;
}
oldLength = objPtr->length;
- newLength = numBytes + oldLength;
- if (newLength < 0) {
+ if (numBytes > INT_MAX - oldLength) {
Tcl_Panic("max size for a Tcl value (%d bytes) exceeded", INT_MAX);
}
+ newLength = numBytes + oldLength;
stringPtr = GET_STRING(objPtr);
if (newLength > stringPtr->allocated) {
diff --git a/generic/tclTest.c b/generic/tclTest.c
index 0ac79a6..1c9e605 100644
--- a/generic/tclTest.c
+++ b/generic/tclTest.c
@@ -6285,7 +6285,8 @@ TestGetIndexFromObjStructObjCmd(
const char *const ary[] = {
"a", "b", "c", "d", "ee", "ff", NULL, NULL
};
- int idx,target, flags = 0;
+ int target, flags = 0;
+ signed char idx[8];
if (objc != 3 && objc != 4) {
Tcl_WrongNumArgs(interp, 1, objv, "argument targetvalue ?flags?");
@@ -6297,13 +6298,17 @@ TestGetIndexFromObjStructObjCmd(
if ((objc > 3) && (Tcl_GetIntFromObj(interp, objv[3], &flags) != TCL_OK)) {
return TCL_ERROR;
}
+ memset(idx, 85, sizeof(idx));
if (Tcl_GetIndexFromObjStruct(interp, (Tcl_GetString(objv[1])[0] ? objv[1] : NULL), ary, 2*sizeof(char *),
- "dummy", flags, &idx) != TCL_OK) {
+ "dummy", flags, &idx[0]) != TCL_OK) {
return TCL_ERROR;
}
- if (idx != target) {
+ if (idx[1] != 85) {
+ Tcl_AppendResult(interp, "Tcl_GetIndexFromObjStruct overwrites size", NULL);
+ return TCL_ERROR;
+ } else if (idx[0] != target) {
char buffer[64];
- sprintf(buffer, "%d", idx);
+ sprintf(buffer, "%d", idx[0]);
Tcl_AppendResult(interp, "index value comparison failed: got ",
buffer, NULL);
sprintf(buffer, "%d", target);