Index: doc/GetIndex.3 ================================================================== --- doc/GetIndex.3 +++ doc/GetIndex.3 @@ -25,23 +25,26 @@ .AP Tcl_Interp *interp in Interpreter to use for error reporting; if NULL, then no message is provided on errors. .AP Tcl_Obj *objPtr in/out The string value of this value is used to search through \fItablePtr\fR. -The internal representation is modified to hold the index of the matching +If the \fBTCL_INDEX_TEMP_TABLE\fR flag is not specified, +the internal representation is modified to hold the index of the matching table entry. .AP "const char *const" *tablePtr in An array of null-terminated strings. The end of the array is marked by a NULL string pointer. -Note that references to the \fItablePtr\fR may be retained in the +Note that, unless the \fBTCL_INDEX_TEMP_TABLE\fR flag is specified, +references to the \fItablePtr\fR may be retained in the internal representation of \fIobjPtr\fR, so this should represent the address of a statically-allocated array. .AP "const void" *structTablePtr in An array of arbitrary type, typically some \fBstruct\fR type. The first member of the structure must be a null-terminated string. The size of the structure is given by \fIoffset\fR. -Note that references to the \fIstructTablePtr\fR may be retained in the +Note that, unless the \fBTCL_INDEX_TEMP_TABLE\fR flag is specified, +references to the \fIstructTablePtr\fR may be retained in the internal representation of \fIobjPtr\fR, so this should represent the address of a statically-allocated array of structures. .AP int offset in The offset to add to structTablePtr to get to the next entry. The end of the array is marked by a NULL string pointer. @@ -48,11 +51,12 @@ .AP "const char" *msg in Null-terminated string describing what is being looked up, such as \fBoption\fR. This string is included in error messages. .AP int flags in OR-ed combination of bits providing additional information for -operation. The only bit that is currently defined is \fBTCL_EXACT\fR. +operation. The only bits that are currently defined are \fBTCL_EXACT\fR +and \fBTCL_INDEX_TEMP_TABLE\fR. .AP int *indexPtr out The index of the string in \fItablePtr\fR that matches the value of \fIobjPtr\fR is returned here. .BE .SH DESCRIPTION @@ -74,19 +78,22 @@ result if \fIinterp\fR is not NULL. \fIMsg\fR is included in the error message to indicate what was being looked up. For example, if \fImsg\fR is \fBoption\fR the error message will have a form like .QW "\fBbad option \N'34'firt\N'34': must be first, second, or third\fR" . .PP -If \fBTcl_GetIndexFromObj\fR completes successfully it modifies the +If the \fBTCL_INDEX_TEMP_TABLE\fR was not specified, when +\fBTcl_GetIndexFromObj\fR completes successfully it modifies the internal representation of \fIobjPtr\fR to hold the address of the table and the index of the matching entry. If \fBTcl_GetIndexFromObj\fR is invoked again with the same \fIobjPtr\fR and \fItablePtr\fR arguments (e.g. during a reinvocation of a Tcl command), it returns the matching index immediately without having to redo the lookup operation. Note: \fBTcl_GetIndexFromObj\fR assumes that the entries in \fItablePtr\fR are static: they must not change between -invocations. If the value of \fIobjPtr\fR is the empty string, +invocations. This caching mechanism can be disallowed by specifying +the \fBTCL_INDEX_TEMP_TABLE\fR flag. +If the value of \fIobjPtr\fR is the empty string, \fBTcl_GetIndexFromObj\fR will treat it as a non-matching value and return \fBTCL_ERROR\fR. .PP \fBTcl_GetIndexFromObjStruct\fR works just like \fBTcl_GetIndexFromObj\fR, except that instead of treating Index: generic/tcl.h ================================================================== --- generic/tcl.h +++ generic/tcl.h @@ -971,15 +971,18 @@ #define TCL_DONT_USE_BRACES 1 #define TCL_DONT_QUOTE_HASH 8 /* - * Flag that may be passed to Tcl_GetIndexFromObj to force it to disallow - * abbreviated strings. + * Flags that may be passed to Tcl_GetIndexFromObj. + * TCL_EXACT disallows abbreviated strings. + * TCL_INDEX_TEMP_TABLE disallows caching of lookups. A possible use case is + * a table that will not live long enough to make it worthwhile. */ -#define TCL_EXACT 1 +#define TCL_EXACT 1 +#define TCL_INDEX_TEMP_TABLE 2 /* *---------------------------------------------------------------------------- * Flag values passed to Tcl_RecordAndEval, Tcl_EvalObj, Tcl_EvalObjv. * WARNING: these bit choices must not conflict with the bit choices for Index: generic/tclFCmd.c ================================================================== --- generic/tclFCmd.c +++ generic/tclFCmd.c @@ -1083,11 +1083,11 @@ Tcl_SetErrorCode(interp, "TCL","OPERATION","FATTR","NONE", NULL); goto end; } if (Tcl_GetIndexFromObj(interp, objv[0], attributeStrings, - "option", INDEX_TEMP_TABLE, &index) != TCL_OK) { + "option", TCL_INDEX_TEMP_TABLE, &index) != TCL_OK) { goto end; } if (Tcl_FSFileAttrsGet(interp, index, filePtr, &objPtr) != TCL_OK) { goto end; @@ -1108,11 +1108,11 @@ goto end; } for (i = 0; i < objc ; i += 2) { if (Tcl_GetIndexFromObj(interp, objv[i], attributeStrings, - "option", INDEX_TEMP_TABLE, &index) != TCL_OK) { + "option", TCL_INDEX_TEMP_TABLE, &index) != TCL_OK) { goto end; } if (i + 1 == objc) { Tcl_SetObjResult(interp, Tcl_ObjPrintf( "value for \"%s\" missing", TclGetString(objv[i]))); Index: generic/tclIndexObj.c ================================================================== --- generic/tclIndexObj.c +++ generic/tclIndexObj.c @@ -112,11 +112,11 @@ const char *msg, /* Identifying word to use in error * messages. */ int flags, /* 0 or TCL_EXACT */ int *indexPtr) /* Place to store resulting integer index. */ { - if (!(flags & INDEX_TEMP_TABLE)) { + if (!(flags & TCL_INDEX_TEMP_TABLE)) { /* * See if there is a valid cached result from a previous lookup (doing the * check here saves the overhead of calling Tcl_GetIndexFromObjStruct in * the common case where the result is cached). @@ -214,11 +214,11 @@ tablePtr[t] = Tcl_GetString(objv[t]); } tablePtr[objc] = NULL; result = Tcl_GetIndexFromObjStruct(interp, objPtr, tablePtr, - sizeof(char *), msg, flags | INDEX_TEMP_TABLE, indexPtr); + sizeof(char *), msg, flags | TCL_INDEX_TEMP_TABLE, indexPtr); ckfree(tablePtr); return result; } @@ -278,11 +278,11 @@ } /* * See if there is a valid cached result from a previous lookup. */ - if (!(flags & INDEX_TEMP_TABLE)) { + if (!(flags & TCL_INDEX_TEMP_TABLE)) { irPtr = TclFetchIntRep(objPtr, &indexType); if (irPtr) { indexRep = (IndexRep *)irPtr->twoPtrValue.ptr1; if (indexRep->tablePtr==tablePtr && indexRep->offset==offset) { *indexPtr = indexRep->index; @@ -342,11 +342,11 @@ * Cache the found representation. Note that we want to avoid allocating a * new internal-rep if at all possible since that is potentially a slow * operation. */ - if (!(flags & INDEX_TEMP_TABLE)) { + if (!(flags & TCL_INDEX_TEMP_TABLE)) { irPtr = TclFetchIntRep(objPtr, &indexType); if (irPtr) { indexRep = (IndexRep *)irPtr->twoPtrValue.ptr1; } else { Tcl_ObjIntRep ir; Index: generic/tclInt.h ================================================================== --- generic/tclInt.h +++ generic/tclInt.h @@ -2603,19 +2603,10 @@ typedef struct TclFileAttrProcs { TclGetFileAttrProc *getProc;/* The procedure for getting attrs. */ TclSetFileAttrProc *setProc;/* The procedure for setting attrs. */ } TclFileAttrProcs; -/* - * Private flag value which controls Tcl_GetIndexFromObj*() routines - * to instruct them not to cache lookups because the table will not - * live long enough to make it worthwhile. Must not clash with public - * flag value TCL_EXACT. - */ - -#define INDEX_TEMP_TABLE 2 - /* * Opaque handle used in pipeline routines to encapsulate platform-dependent * state. */ Index: generic/tclTestObj.c ================================================================== --- generic/tclTestObj.c +++ generic/tclTestObj.c @@ -625,11 +625,11 @@ argv[i-4] = Tcl_GetString(objv[i]); } argv[objc-4] = NULL; result = Tcl_GetIndexFromObj((setError? interp : NULL), objv[3], - argv, "token", INDEX_TEMP_TABLE|(allowAbbrev? 0 : TCL_EXACT), + argv, "token", TCL_INDEX_TEMP_TABLE|(allowAbbrev? 0 : TCL_EXACT), &index); ckfree(argv); if (result == TCL_OK) { Tcl_SetIntObj(Tcl_GetObjResult(interp), index); }