Tcl Source Code

Artifact [ec381cd036]
Login

Artifact ec381cd03676df22f6af3cb0b1021ed91752c3a8:

Attachment "forgive.patch" to ticket [1162286fff] added by dgp 2005-11-17 00:56:00.
Index: generic/tclPkg.c
===================================================================
RCS file: /cvsroot/tcl/tcl/generic/tclPkg.c,v
retrieving revision 1.9.2.1
diff -u -r1.9.2.1 tclPkg.c
--- generic/tclPkg.c	8 Nov 2005 18:28:56 -0000	1.9.2.1
+++ generic/tclPkg.c	16 Nov 2005 17:38:58 -0000
@@ -331,8 +331,8 @@
 	    Tcl_Release((ClientData) script);
 	    pkgPtr = FindPackage(interp, name);
 	    if (code == TCL_OK) {
-		Tcl_ResetResult(interp);
 		if (pkgPtr->version == NULL) {
+		    Tcl_ResetResult(interp);
 		    code = TCL_ERROR;
 		    Tcl_AppendResult(interp, "attempt to provide package ",
 			    name, " ", versionToProvide,
@@ -340,11 +340,55 @@
 			    " provided", NULL);
 		} else if (0 != ComparePkgVersions(
 			pkgPtr->version, versionToProvide, NULL)) {
-		    code = TCL_ERROR;
-		    Tcl_AppendResult(interp, "attempt to provide package ",
-			    name, " ", versionToProvide, " failed: package ",
-			    name, " ", pkgPtr->version, " provided instead",
-			    NULL);
+		    /* At this point, it is clear that a prior
+		     * [package ifneeded] command lied to us.  It said
+		     * that to get a particular version of a particular
+		     * package, we needed to evaluate a particular script.
+		     * However, we evaluated that script and got a different
+		     * version than we were told.  This is an error, and we
+		     * ought to report it.
+		     *
+		     * However, we've been letting this type of error slide
+		     * for a long time, and as a result, a lot of packages
+		     * suffer from them.
+		     *
+		     * It's a bit too harsh to make a large number of
+		     * existing packages start failing by releasing a
+		     * new patch release, so we forgive this type of error
+		     * for the rest of the Tcl 8.4 series, and only report
+		     * a warning.  We limit the error reporting to only
+		     * the situation where a broken ifneeded script leads
+		     * to a failure to satisfy the requirement.
+		     */
+		    if (version) {
+			result = ComparePkgVersions(
+				pkgPtr->version, version, &satisfies);
+			if (result && (exact || !satisfies)) {
+			    Tcl_ResetResult(interp);
+			    code = TCL_ERROR;
+			    Tcl_AppendResult(interp,
+				    "attempt to provide package ", name, " ",
+				    versionToProvide, " failed: package ",
+				    name, " ", pkgPtr->version,
+				    " provided instead", NULL);
+			}
+		    }
+		    if (code == TCL_OK) {
+			/* Forgiving the error, report warning instead */
+			Tcl_Obj *msg = Tcl_NewStringObj(
+				"attempt to provide package ", -1);
+			Tcl_Obj *cmdPtr = Tcl_NewListObj(0, NULL);
+			Tcl_ListObjAppendElement(NULL, cmdPtr,
+				Tcl_NewStringObj("tclLog", -1));
+			Tcl_AppendStringsToObj(msg, name, " ", versionToProvide,
+				" failed: package ", name, " ",
+				pkgPtr->version, " provided instead", NULL);
+			Tcl_ListObjAppendElement(NULL, cmdPtr, msg);
+			Tcl_IncrRefCount(cmdPtr);
+			Tcl_GlobalEvalObj(interp, cmdPtr);
+			Tcl_DecrRefCount(cmdPtr);
+			Tcl_ResetResult(interp);
+		    }
 		}
 	    } else if (code != TCL_ERROR) {
 		Tcl_Obj *codePtr = Tcl_NewIntObj(code);
Index: tests/pkg.test
===================================================================
RCS file: /cvsroot/tcl/tcl/tests/pkg.test,v
retrieving revision 1.9.12.1
diff -u -r1.9.12.1 pkg.test
--- tests/pkg.test	8 Nov 2005 18:28:56 -0000	1.9.12.1
+++ tests/pkg.test	16 Nov 2005 17:38:58 -0000
@@ -351,7 +351,7 @@
     package require foo 1
 } -cleanup {
     package forget foo
-} -returnCodes error -match glob -result {attempt to provide package * failed:*}
+} -match glob -result 1.1 -errorOutput {attempt to provide package * failed:*}
 test pkg-2.35 {Tcl_PkgRequire: consistent return values (1162286)} -setup {
     package forget foo
 } -body {