Tcl Source Code

Artifact [7ce1a51bec]
Login

Artifact 7ce1a51bec5f5fab0e0a65cbcaae420df4f13362:

Attachment "triv.patch" to ticket [1076088fff] added by dgp 2005-03-29 05:40:31.
Index: generic/tclBasic.c
===================================================================
RCS file: /cvsroot/tcl/tcl/generic/tclBasic.c,v
retrieving revision 1.142
diff -u -r1.142 tclBasic.c
--- generic/tclBasic.c	18 Mar 2005 15:50:59 -0000	1.142
+++ generic/tclBasic.c	28 Mar 2005 22:36:20 -0000
@@ -2819,6 +2819,14 @@
     Tcl_HashSearch hSearch;
     CONST char *name;
 
+    if ((pattern != NULL) && TclMatchIsTrivial(pattern)) {
+	if ((Tcl_FindHashEntry(&iPtr->mathFuncTable, pattern) != NULL)
+		&& (Tcl_ListObjAppendElement(interp, resultList,
+		Tcl_NewStringObj(pattern,-1)) != TCL_OK)) {
+	    goto error;
+	}
+	return resultList;
+    }
     for (hPtr = Tcl_FirstHashEntry(&iPtr->mathFuncTable, &hSearch);
 	 hPtr != NULL; hPtr = Tcl_NextHashEntry(&hSearch)) {
         name = Tcl_GetHashKey(&iPtr->mathFuncTable, hPtr);
@@ -2826,6 +2834,7 @@
 	    /* I don't expect this to fail, but... */
 	    Tcl_ListObjAppendElement(interp, resultList,
 				     Tcl_NewStringObj(name,-1)) != TCL_OK) {
+error:
 	    Tcl_DecrRefCount(resultList);
 	    return NULL;
 	}
Index: generic/tclCmdIL.c
===================================================================
RCS file: /cvsroot/tcl/tcl/generic/tclCmdIL.c,v
retrieving revision 1.71
diff -u -r1.71 tclCmdIL.c
--- generic/tclCmdIL.c	14 Dec 2004 21:11:45 -0000	1.71
+++ generic/tclCmdIL.c	28 Mar 2005 22:36:20 -0000
@@ -1455,6 +1455,13 @@
     }
 
     if (localVarTablePtr != NULL) {
+	if ((pattern != NULL) && TclMatchIsTrivial(pattern)) {
+	    if (Tcl_FindHashEntry(localVarTablePtr, pattern)) {
+		Tcl_ListObjAppendElement(interp, listPtr,
+			Tcl_NewStringObj(pattern,-1));
+	    }
+	    return;
+	}
 	for (entryPtr = Tcl_FirstHashEntry(localVarTablePtr, &search);
 		entryPtr != NULL;
 		entryPtr = Tcl_NextHashEntry(&search)) {
Index: generic/tclDictObj.c
===================================================================
RCS file: /cvsroot/tcl/tcl/generic/tclDictObj.c,v
retrieving revision 1.27
diff -u -r1.27 tclDictObj.c
--- generic/tclDictObj.c	13 Nov 2004 00:19:09 -0000	1.27
+++ generic/tclDictObj.c	28 Mar 2005 22:36:21 -0000
@@ -1671,6 +1671,14 @@
 	pattern = TclGetString(objv[3]);
     }
     listPtr = Tcl_NewListObj(0, NULL);
+    if ((pattern != NULL) && TclMatchIsTrivial(pattern)) {
+	Tcl_Obj *valuePtr = NULL;
+	Tcl_DictObjGet(interp, objv[2], objv[3], &valuePtr);
+	if (valuePtr != NULL) {
+	    Tcl_ListObjAppendElement(interp, listPtr, objv[3]);
+	}
+	goto searchDone;
+    }
     for (; !done ; Tcl_DictObjNext(&search, &keyPtr, NULL, &done)) {
 	if (pattern==NULL || Tcl_StringMatch(TclGetString(keyPtr), pattern)) {
 	    /*
@@ -1679,6 +1687,7 @@
 	    Tcl_ListObjAppendElement(interp, listPtr, keyPtr);
 	}
     }
+searchDone:
     Tcl_SetObjResult(interp, listPtr);
     return TCL_OK;
 }
@@ -2531,11 +2540,18 @@
 	}
 	pattern = TclGetString(objv[4]);
 	resultObj = Tcl_NewDictObj();
-	while (!done) {
-	    if (Tcl_StringMatch(TclGetString(keyObj), pattern)) {
-		Tcl_DictObjPut(interp, resultObj, keyObj, valueObj);
+	if (TclMatchIsTrivial(pattern)) {
+	    Tcl_DictObjGet(interp, objv[2], objv[4], &valueObj);
+	    if (valueObj != NULL) {
+		Tcl_DictObjPut(interp, resultObj, objv[4], valueObj);
+	    }
+	} else {
+	    while (!done) {
+		if (Tcl_StringMatch(TclGetString(keyObj), pattern)) {
+		    Tcl_DictObjPut(interp, resultObj, keyObj, valueObj);
+		}
+		Tcl_DictObjNext(&search, &keyObj, &valueObj, &done);
 	    }
-	    Tcl_DictObjNext(&search, &keyObj, &valueObj, &done);
 	}
 	Tcl_SetObjResult(interp, resultObj);
 	return TCL_OK;
Index: generic/tclIO.c
===================================================================
RCS file: /cvsroot/tcl/tcl/generic/tclIO.c,v
retrieving revision 1.82
diff -u -r1.82 tclIO.c
--- generic/tclIO.c	27 Jan 2005 00:23:23 -0000	1.82
+++ generic/tclIO.c	28 Mar 2005 22:36:22 -0000
@@ -8759,7 +8759,16 @@
 
     hTblPtr = GetChannelTable(interp);
     TclNewObj(resultPtr);
-
+    if ((pattern != NULL) && TclMatchIsTrivial(pattern)
+	    && !((pattern[0] == 's') && (pattern[1] == 't')
+	    && (pattern[2] == 'd'))) {
+	if ((Tcl_FindHashEntry(hTblPtr, pattern) != NULL)
+		&& (Tcl_ListObjAppendElement(interp, resultPtr,
+		Tcl_NewStringObj(pattern, -1)) != TCL_OK)) {
+	    goto error;
+	}
+	goto done;
+    }
     for (hPtr = Tcl_FirstHashEntry(hTblPtr, &hSearch);
 	    hPtr != (Tcl_HashEntry *) NULL;
 	    hPtr = Tcl_NextHashEntry(&hSearch)) {
@@ -8783,10 +8792,12 @@
 	if (((pattern == NULL) || Tcl_StringMatch(name, pattern)) &&
 		(Tcl_ListObjAppendElement(interp, resultPtr,
 			Tcl_NewStringObj(name, -1)) != TCL_OK)) {
+error:
 	    TclDecrRefCount(resultPtr);
 	    return TCL_ERROR;
 	}
     }
+done:
     Tcl_SetObjResult(interp, resultPtr);
     return TCL_OK;
 }
Index: generic/tclNamesp.c
===================================================================
RCS file: /cvsroot/tcl/tcl/generic/tclNamesp.c,v
retrieving revision 1.72
diff -u -r1.72 tclNamesp.c
--- generic/tclNamesp.c	9 Mar 2005 10:20:37 -0000	1.72
+++ generic/tclNamesp.c	28 Mar 2005 22:36:22 -0000
@@ -180,6 +180,10 @@
  */
 
 static void		DeleteImportedCmd _ANSI_ARGS_((ClientData clientData));
+static int		DoImport _ANSI_ARGS_((Tcl_Interp *interp,
+			    Namespace *nsPtr, Tcl_HashEntry *hPtr,
+			    CONST char *cmdName, CONST char *pattern,
+			    Namespace *importNsPtr, int allowOverwrite));
 static void		DupNsNameInternalRep _ANSI_ARGS_((Tcl_Obj *objPtr,
 			    Tcl_Obj *copyPtr));
 static char *		ErrorCodeRead _ANSI_ARGS_(( ClientData clientData,
@@ -1490,107 +1494,129 @@
      * commands redirect their invocations to the "real" command.
      */
 
+    if ((simplePattern != NULL) && TclMatchIsTrivial(simplePattern)) {
+	hPtr = Tcl_FindHashEntry(&importNsPtr->cmdTable, simplePattern);
+	if (hPtr == NULL) {
+	    return TCL_OK;
+	}
+	return DoImport(interp, nsPtr, hPtr, simplePattern, pattern,
+		importNsPtr, allowOverwrite);
+    }
     for (hPtr = Tcl_FirstHashEntry(&importNsPtr->cmdTable, &search);
 	    (hPtr != NULL); hPtr = Tcl_NextHashEntry(&search)) {
 	char *cmdName = Tcl_GetHashKey(&importNsPtr->cmdTable, hPtr);
-	if (Tcl_StringMatch(cmdName, simplePattern)) {
-	    /*
-	     * The command cmdName in the source namespace matches the
-	     * pattern. Check whether it was exported. If it wasn't,
-	     * we ignore it.
-	     */
-	    Tcl_HashEntry *found;
-	    int wasExported = 0, i;
+	if (Tcl_StringMatch(cmdName, simplePattern)
+		&& (TCL_ERROR == DoImport( interp, nsPtr, hPtr, cmdName,
+		pattern, importNsPtr, allowOverwrite))) {
+	    return TCL_ERROR;
+	}
+    }
+    return TCL_OK;
+}
 
-	    for (i = 0;  i < importNsPtr->numExportPatterns;  i++) {
-		if (Tcl_StringMatch(cmdName, importNsPtr->exportArrayPtr[i])) {
-		    wasExported = 1;
-		    break;
-		}
-	    }
-	    if (!wasExported) {
-		continue;
-	    }
+static int
+DoImport(interp, nsPtr, hPtr, cmdName, pattern, importNsPtr, allowOverwrite)
+    Tcl_Interp *interp;
+    Namespace *nsPtr;
+    Tcl_HashEntry *hPtr;
+    CONST char *cmdName;
+    CONST char *pattern;
+    Namespace *importNsPtr;
+    int allowOverwrite;
+{
+    int i = 0, exported = 0;
+    Tcl_HashEntry *found;
 
-	    /*
-	     * Unless there is a name clash, create an imported command
-	     * in the current namespace that refers to cmdPtr.
-	     */
+    /*
+     * The command cmdName in the source namespace matches the
+     * pattern. Check whether it was exported. If it wasn't,
+     * we ignore it.
+     */
 
-	    found = Tcl_FindHashEntry(&nsPtr->cmdTable, cmdName);
-	    if ((found == NULL) || allowOverwrite) {
-		/*
-		 * Create the imported command and its client data.
-		 * To create the new command in the current namespace, 
-		 * generate a fully qualified name for it.
-		 */
+    while (!exported && (i < importNsPtr->numExportPatterns)) {
+	exported |= Tcl_StringMatch(cmdName, importNsPtr->exportArrayPtr[i++]);
+    }
+    if (!exported) {
+	return TCL_OK;
+    }
 
-		Tcl_DString ds;
-		Tcl_Command importedCmd;
-		ImportedCmdData *dataPtr;
-		Command *cmdPtr;
-		ImportRef *refPtr;
+    /*
+     * Unless there is a name clash, create an imported command
+     * in the current namespace that refers to cmdPtr.
+     */
 
-		Tcl_DStringInit(&ds);
-		Tcl_DStringAppend(&ds, nsPtr->fullName, -1);
-		if (nsPtr != ((Interp *) interp)->globalNsPtr) {
-		    Tcl_DStringAppend(&ds, "::", 2);
-		}
-		Tcl_DStringAppend(&ds, cmdName, -1);
+    found = Tcl_FindHashEntry(&nsPtr->cmdTable, cmdName);
+    if ((found == NULL) || allowOverwrite) {
+	/*
+	 * Create the imported command and its client data.
+	 * To create the new command in the current namespace, 
+	 * generate a fully qualified name for it.
+	 */
 
-		/*
-		 * Check whether creating the new imported command in the
-		 * current namespace would create a cycle of imported
-		 * command references.
-		 */
+	Tcl_DString ds;
+	Tcl_Command importedCmd;
+	ImportedCmdData *dataPtr;
+	Command *cmdPtr;
+	ImportRef *refPtr;
+
+	Tcl_DStringInit(&ds);
+	Tcl_DStringAppend(&ds, nsPtr->fullName, -1);
+	if (nsPtr != ((Interp *) interp)->globalNsPtr) {
+	    Tcl_DStringAppend(&ds, "::", 2);
+	}
+	Tcl_DStringAppend(&ds, cmdName, -1);
 
-		cmdPtr = (Command *) Tcl_GetHashValue(hPtr);
-		if (found != NULL && cmdPtr->deleteProc == DeleteImportedCmd) {
-		    Command *overwrite = (Command *) Tcl_GetHashValue(found);
-		    Command *link = cmdPtr;
-
-		    while (link->deleteProc == DeleteImportedCmd) {
-			ImportedCmdData *dataPtr;
-
-			dataPtr = (ImportedCmdData *) link->objClientData;
-			link = dataPtr->realCmdPtr;
-			if (overwrite == link) {
-			    Tcl_AppendResult(interp, "import pattern \"",
-				    pattern,
-				    "\" would create a loop containing ",
-				    "command \"", Tcl_DStringValue(&ds),
-				    "\"", (char *) NULL);
-			    Tcl_DStringFree(&ds);
-			    return TCL_ERROR;
-			}
-		    }
-		}
+	/*
+	 * Check whether creating the new imported command in the
+	 * current namespace would create a cycle of imported
+	 * command references.
+	 */
 
-		dataPtr = (ImportedCmdData *) ckalloc(sizeof(ImportedCmdData));
-		importedCmd = Tcl_CreateObjCommand(interp, 
-			Tcl_DStringValue(&ds), InvokeImportedCmd,
-			(ClientData) dataPtr, DeleteImportedCmd);
-		dataPtr->realCmdPtr = cmdPtr;
-		dataPtr->selfPtr = (Command *) importedCmd;
-		dataPtr->selfPtr->compileProc = cmdPtr->compileProc;
-		Tcl_DStringFree(&ds);
+	cmdPtr = (Command *) Tcl_GetHashValue(hPtr);
+	if (found != NULL && cmdPtr->deleteProc == DeleteImportedCmd) {
+	    Command *overwrite = (Command *) Tcl_GetHashValue(found);
+	    Command *link = cmdPtr;
 
-		/*
-		 * Create an ImportRef structure describing this new import
-		 * command and add it to the import ref list in the "real"
-		 * command.
-		 */
+	    while (link->deleteProc == DeleteImportedCmd) {
+		ImportedCmdData *dataPtr;
 
-		refPtr = (ImportRef *) ckalloc(sizeof(ImportRef));
-		refPtr->importedCmdPtr = (Command *) importedCmd;
-		refPtr->nextPtr = cmdPtr->importRefPtr;
-		cmdPtr->importRefPtr = refPtr;
-	    } else {
-		Tcl_AppendResult(interp, "can't import command \"", cmdName,
-			"\": already exists", (char *) NULL);
-		return TCL_ERROR;
+		dataPtr = (ImportedCmdData *) link->objClientData;
+		link = dataPtr->realCmdPtr;
+		if (overwrite == link) {
+		    Tcl_AppendResult(interp, "import pattern \"",
+			    pattern,
+			    "\" would create a loop containing ",
+			    "command \"", Tcl_DStringValue(&ds),
+			    "\"", (char *) NULL);
+		    Tcl_DStringFree(&ds);
+		    return TCL_ERROR;
+		}
 	    }
 	}
+
+	dataPtr = (ImportedCmdData *) ckalloc(sizeof(ImportedCmdData));
+	importedCmd = Tcl_CreateObjCommand(interp, 
+		Tcl_DStringValue(&ds), InvokeImportedCmd,
+		(ClientData) dataPtr, DeleteImportedCmd);
+	dataPtr->realCmdPtr = cmdPtr;
+	dataPtr->selfPtr = (Command *) importedCmd;
+	dataPtr->selfPtr->compileProc = cmdPtr->compileProc;
+	Tcl_DStringFree(&ds);
+
+	/*
+	 * Create an ImportRef structure describing this new import
+	 * command and add it to the import ref list in the "real"
+	 * command.
+	 */
+
+	refPtr = (ImportRef *) ckalloc(sizeof(ImportRef));
+	refPtr->importedCmdPtr = (Command *) importedCmd;
+	refPtr->nextPtr = cmdPtr->importRefPtr;
+	cmdPtr->importRefPtr = refPtr;
+    } else {
+	Tcl_AppendResult(interp, "can't import command \"", cmdName,
+		"\": already exists", (char *) NULL);
+	return TCL_ERROR;
     }
     return TCL_OK;
 }
@@ -1670,6 +1696,15 @@
 	 * Delete any imported commands that match it.
 	 */
 
+	if (TclMatchIsTrivial(simplePattern)) {
+	    Command *cmdPtr;
+	    hPtr = Tcl_FindHashEntry(&nsPtr->cmdTable, simplePattern);
+	    (hPtr != NULL)
+		    && (cmdPtr = (Command *) Tcl_GetHashValue(hPtr))
+		    && (cmdPtr->deleteProc == DeleteImportedCmd)
+		    && Tcl_DeleteCommandFromToken(interp, (Tcl_Command) cmdPtr);
+	    return TCL_OK;
+	}
 	for (hPtr = Tcl_FirstHashEntry(&nsPtr->cmdTable, &search);
 		(hPtr != NULL);
 		hPtr = Tcl_NextHashEntry(&search)) {
@@ -2959,6 +2994,13 @@
      */
 
     listPtr = Tcl_NewListObj(0, (Tcl_Obj **) NULL);
+    if ((pattern != NULL) && TclMatchIsTrivial(pattern)) {
+	if (Tcl_FindHashEntry(&nsPtr->childTable, pattern) != NULL) {
+	    Tcl_ListObjAppendElement(interp, listPtr,
+		    Tcl_NewStringObj(pattern, -1));
+	}
+	goto searchDone;
+    }
     entryPtr = Tcl_FirstHashEntry(&nsPtr->childTable, &search);
     while (entryPtr != NULL) {
 	childNsPtr = (Namespace *) Tcl_GetHashValue(entryPtr);
@@ -2970,6 +3012,7 @@
 	entryPtr = Tcl_NextHashEntry(&search);
     }
 
+searchDone:
     Tcl_SetObjResult(interp, listPtr);
     Tcl_DStringFree(&buffer);
     return TCL_OK;
Index: generic/tclVar.c
===================================================================
RCS file: /cvsroot/tcl/tcl/generic/tclVar.c,v
retrieving revision 1.101
diff -u -r1.101 tclVar.c
--- generic/tclVar.c	14 Dec 2004 21:11:47 -0000	1.101
+++ generic/tclVar.c	28 Mar 2005 22:36:23 -0000
@@ -2813,7 +2813,23 @@
 
 	    nameLstPtr = Tcl_NewObj();
 	    Tcl_IncrRefCount(nameLstPtr);
-
+	    if ((pattern != NULL) && TclMatchIsTrivial(pattern)) {
+		hPtr = Tcl_FindHashEntry(varPtr->value.tablePtr, pattern);
+		if (hPtr == NULL) {
+		    goto searchDone;
+		}
+	        varPtr2 = (Var *) Tcl_GetHashValue(hPtr);
+		if (TclIsVarUndefined(varPtr2)) {
+		    goto searchDone;
+		}
+		result = Tcl_ListObjAppendElement(interp, nameLstPtr,
+		        Tcl_NewStringObj(pattern, -1));
+		if (result != TCL_OK) {
+		    Tcl_DecrRefCount(nameLstPtr);
+		    return result;
+		}
+		goto searchDone;
+	    }
 	    for (hPtr = Tcl_FirstHashEntry(varPtr->value.tablePtr, &search);
 		 hPtr != NULL;  hPtr = Tcl_NextHashEntry(&search)) {
 	        varPtr2 = (Var *) Tcl_GetHashValue(hPtr);
@@ -2834,6 +2850,7 @@
 		    return result;
 		}
 	    }
+searchDone:
 
 	    /*
 	     * Make sure the Var structure of the array is not removed by
@@ -2923,6 +2940,19 @@
 		}
 	    }       		
 	    resultPtr = Tcl_NewObj();
+	    if ((((enum options) mode) == OPT_GLOB) && (pattern != NULL)
+		    && TclMatchIsTrivial(pattern)) {
+		hPtr = Tcl_FindHashEntry(varPtr->value.tablePtr, pattern);
+		if ((hPtr != NULL)
+			&& !TclIsVarUndefined((Var *) Tcl_GetHashValue(hPtr))
+			&& (result = Tcl_ListObjAppendElement(interp,
+			resultPtr, Tcl_NewStringObj(pattern, -1))) != TCL_OK) {
+		    Tcl_DecrRefCount(resultPtr);
+		    return result;
+		}
+		Tcl_SetObjResult(interp, resultPtr);
+		return TCL_OK;
+	    }
 	    for (hPtr = Tcl_FirstHashEntry(varPtr->value.tablePtr, &search);
 		 hPtr != NULL; hPtr = Tcl_NextHashEntry(&search)) {
 	        varPtr2 = (Var *) Tcl_GetHashValue(hPtr);
@@ -3101,6 +3131,15 @@
 		}
 	    } else {
 		pattern = TclGetString(objv[3]);
+		if (TclMatchIsTrivial(pattern)) {
+		    hPtr = Tcl_FindHashEntry(varPtr->value.tablePtr, pattern);
+		    result = TCL_OK;
+		    (hPtr != NULL)
+			&& !TclIsVarUndefined((Var *) Tcl_GetHashValue(hPtr))
+			&& (result 
+			= TclObjUnsetVar2(interp, varNamePtr, pattern, 0));
+		    return result;
+		}
 		for (hPtr = Tcl_FirstHashEntry(varPtr->value.tablePtr,
 			&search);
 		     hPtr != NULL; hPtr = Tcl_NextHashEntry(&search)) {