summaryrefslogtreecommitdiffstats
path: root/generic/tclIndexObj.c
diff options
context:
space:
mode:
authorjan.nijtmans <nijtmans@users.sourceforge.net>2022-04-26 07:29:02 (GMT)
committerjan.nijtmans <nijtmans@users.sourceforge.net>2022-04-26 07:29:02 (GMT)
commita4c35fb82f99d990ca1ef877cb9917c7f55151ff (patch)
treecdd02327448cf2c0393cbf3cea4fd48bb17e52c4 /generic/tclIndexObj.c
parent81a213ed4ce77b15fbc6d5d97cc1235b689ad482 (diff)
parente12b1646c6f675cf09d5f1a72d4ecdffa5da7396 (diff)
downloadtcl-a4c35fb82f99d990ca1ef877cb9917c7f55151ff.zip
tcl-a4c35fb82f99d990ca1ef877cb9917c7f55151ff.tar.gz
tcl-a4c35fb82f99d990ca1ef877cb9917c7f55151ff.tar.bz2
Merge 8.7
Diffstat (limited to 'generic/tclIndexObj.c')
-rw-r--r--generic/tclIndexObj.c92
1 files changed, 60 insertions, 32 deletions
diff --git a/generic/tclIndexObj.c b/generic/tclIndexObj.c
index c2812ea..1f600c5 100644
--- a/generic/tclIndexObj.c
+++ b/generic/tclIndexObj.c
@@ -25,13 +25,13 @@ static int GetIndexFromObjList(Tcl_Interp *interp,
static void UpdateStringOfIndex(Tcl_Obj *objPtr);
static void DupIndex(Tcl_Obj *srcPtr, Tcl_Obj *dupPtr);
static void FreeIndex(Tcl_Obj *objPtr);
-static int PrefixAllObjCmd(ClientData clientData,
+static int PrefixAllObjCmd(void *clientData,
Tcl_Interp *interp, int objc,
Tcl_Obj *const objv[]);
-static int PrefixLongestObjCmd(ClientData clientData,
+static int PrefixLongestObjCmd(void *clientData,
Tcl_Interp *interp, int objc,
Tcl_Obj *const objv[]);
-static int PrefixMatchObjCmd(ClientData clientData,
+static int PrefixMatchObjCmd(void *clientData,
Tcl_Interp *interp, int objc,
Tcl_Obj *const objv[]);
static void PrintUsage(Tcl_Interp *interp,
@@ -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) : "")
/*
*----------------------------------------------------------------------
@@ -106,7 +106,7 @@ int
Tcl_GetIndexFromObj(
Tcl_Interp *interp, /* Used for error reporting if not NULL. */
Tcl_Obj *objPtr, /* Object containing the string to lookup. */
- const char *const*tablePtr, /* Array of strings to compare against the
+ const char *const *tablePtr, /* Array of strings to compare against the
* value of objPtr; last entry must be NULL
* and there must not be duplicate entries. */
const char *msg, /* Identifying word to use in error
@@ -132,7 +132,7 @@ Tcl_GetIndexFromObj(
* on odd platforms like a Cray PVP...
*/
- if (indexRep->tablePtr == (void *) tablePtr
+ if (indexRep->tablePtr == (void *)tablePtr
&& indexRep->offset == sizeof(char *)) {
*indexPtr = indexRep->index;
return TCL_OK;
@@ -190,7 +190,7 @@ GetIndexFromObjList(
* of the code there. This is a bit ineffiecient but simpler.
*/
- result = Tcl_ListObjGetElements(interp, tableObjPtr, &objc, &objv);
+ result = TclListObjGetElements(interp, tableObjPtr, &objc, &objv);
if (result != TCL_OK) {
return result;
}
@@ -235,11 +235,12 @@ GetIndexFromObjList(
* Results:
* If the value of objPtr is identical to or a unique abbreviation for
* one of the entries in tablePtr, then the return value is TCL_OK and
- * the index of the matching entry is stored at *indexPtr. If there isn't
- * a proper match, then TCL_ERROR is returned and an error message is
- * left in interp's result (unless interp is NULL). The msg argument is
- * used in the error message; for example, if msg has the value "option"
- * then the error message will say something like 'bad option "foo": must
+ * the index of the matching entry is stored at *indexPtr
+ * (unless indexPtr is NULL). If there isn't a proper match, then
+ * TCL_ERROR is returned and an error message is left in interp's
+ * result (unless interp is NULL). The msg argument is used in the
+ * error message; for example, if msg has the value "option" then
+ * the error message will say something like 'bad option "foo": must
* be ...'
*
* Side effects:
@@ -249,6 +250,7 @@ GetIndexFromObjList(
*----------------------------------------------------------------------
*/
+#undef Tcl_GetIndexFromObjStruct
int
Tcl_GetIndexFromObjStruct(
Tcl_Interp *interp, /* Used for error reporting if not NULL. */
@@ -261,8 +263,8 @@ Tcl_GetIndexFromObjStruct(
int offset, /* The number of bytes between entries */
const char *msg, /* Identifying word to use in error
* messages. */
- int flags, /* 0 or TCL_EXACT */
- int *indexPtr) /* Place to store resulting integer index. */
+ int flags, /* 0, TCL_EXACT, TCL_INDEX_TEMP_TABLE or TCL_INDEX_NULL_OK */
+ void *indexPtr) /* Place to store resulting index. */
{
int index, idx, numAbbrev;
const char *key, *p1;
@@ -280,13 +282,15 @@ Tcl_GetIndexFromObjStruct(
* See if there is a valid cached result from a previous lookup.
*/
- if (!(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;
}
}
}
@@ -296,10 +300,13 @@ Tcl_GetIndexFromObjStruct(
* abbreviations unless TCL_EXACT is set in flags.
*/
- key = TclGetString(objPtr);
+ key = objPtr ? TclGetString(objPtr) : "";
index = -1;
numAbbrev = 0;
+ if (!*key && (flags & TCL_INDEX_NULL_OK)) {
+ goto uncachedDone;
+ }
/*
* Scan the table looking for one of:
* - An exact match (always preferred)
@@ -307,7 +314,7 @@ Tcl_GetIndexFromObjStruct(
* - Several abbreviations (never allowed, but overridden by exact match)
*/
- for (entryPtr = (const char* const*)tablePtr, idx = 0; *entryPtr != NULL;
+ for (entryPtr = (const char *const *)tablePtr, idx = 0; *entryPtr != NULL;
entryPtr = NEXT_ENTRY(entryPtr, offset), idx++) {
for (p1 = key, p2 = *entryPtr; *p1 == *p2; p1++, p2++) {
if (*p1 == '\0') {
@@ -344,7 +351,7 @@ Tcl_GetIndexFromObjStruct(
* operation.
*/
- if (!(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;
@@ -360,7 +367,25 @@ Tcl_GetIndexFromObjStruct(
indexRep->index = index;
}
- *indexPtr = index;
+ uncachedDone:
+ if (indexPtr != NULL) {
+ 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:
@@ -372,7 +397,7 @@ Tcl_GetIndexFromObjStruct(
int count = 0;
TclNewObj(resultPtr);
- entryPtr = (const char* const *)tablePtr;
+ entryPtr = (const char *const *)tablePtr;
while ((*entryPtr != NULL) && !**entryPtr) {
entryPtr = NEXT_ENTRY(entryPtr, offset);
}
@@ -386,7 +411,7 @@ Tcl_GetIndexFromObjStruct(
*entryPtr, NULL);
entryPtr = NEXT_ENTRY(entryPtr, offset);
while (*entryPtr != NULL) {
- if (*NEXT_ENTRY(entryPtr, offset) == NULL) {
+ if ((*NEXT_ENTRY(entryPtr, offset) == NULL) && !(flags & TCL_INDEX_NULL_OK)) {
Tcl_AppendStringsToObj(resultPtr, (count > 0 ? "," : ""),
" or ", *entryPtr, NULL);
} else if (**entryPtr) {
@@ -395,6 +420,9 @@ Tcl_GetIndexFromObjStruct(
}
entryPtr = NEXT_ENTRY(entryPtr, offset);
}
+ if ((flags & TCL_INDEX_NULL_OK)) {
+ Tcl_AppendStringsToObj(resultPtr, ", or \"\"", NULL);
+ }
}
Tcl_SetObjResult(interp, resultPtr);
Tcl_SetErrorCode(interp, "TCL", "LOOKUP", "INDEX", msg, key, NULL);
@@ -540,7 +568,7 @@ TclInitPrefixCmd(
static int
PrefixMatchObjCmd(
- TCL_UNUSED(ClientData),
+ TCL_UNUSED(void *),
Tcl_Interp *interp, /* Current interpreter. */
int objc, /* Number of arguments. */
Tcl_Obj *const objv[]) /* Argument objects. */
@@ -589,7 +617,7 @@ PrefixMatchObjCmd(
return TCL_ERROR;
}
i++;
- result = Tcl_ListObjLength(interp, objv[i], &errorLength);
+ result = TclListObjLength(interp, objv[i], &errorLength);
if (result != TCL_OK) {
return TCL_ERROR;
}
@@ -613,7 +641,7 @@ PrefixMatchObjCmd(
* error case regardless of level.
*/
- result = Tcl_ListObjLength(interp, tablePtr, &dummyLength);
+ result = TclListObjLength(interp, tablePtr, &dummyLength);
if (result != TCL_OK) {
return result;
}
@@ -664,7 +692,7 @@ PrefixMatchObjCmd(
static int
PrefixAllObjCmd(
- TCL_UNUSED(ClientData),
+ TCL_UNUSED(void *),
Tcl_Interp *interp, /* Current interpreter. */
int objc, /* Number of arguments. */
Tcl_Obj *const objv[]) /* Argument objects. */
@@ -678,7 +706,7 @@ PrefixAllObjCmd(
return TCL_ERROR;
}
- result = Tcl_ListObjGetElements(interp, objv[1], &tableObjc, &tableObjv);
+ result = TclListObjGetElements(interp, objv[1], &tableObjc, &tableObjv);
if (result != TCL_OK) {
return result;
}
@@ -721,7 +749,7 @@ PrefixAllObjCmd(
static int
PrefixLongestObjCmd(
- TCL_UNUSED(ClientData),
+ TCL_UNUSED(void *),
Tcl_Interp *interp, /* Current interpreter. */
int objc, /* Number of arguments. */
Tcl_Obj *const objv[]) /* Argument objects. */
@@ -735,7 +763,7 @@ PrefixLongestObjCmd(
return TCL_ERROR;
}
- result = Tcl_ListObjGetElements(interp, objv[1], &tableObjc, &tableObjv);
+ result = TclListObjGetElements(interp, objv[1], &tableObjc, &tableObjv);
if (result != TCL_OK) {
return result;
}
@@ -851,7 +879,7 @@ Tcl_WrongNumArgs(
Tcl_Obj *objPtr;
int i, len, elemLen;
char flags;
- Interp *iPtr = (Interp *) interp;
+ Interp *iPtr = (Interp *)interp;
const char *elementStr;
/*