Diff
Not logged in

Differences From Artifact [bcd13fd890]:

To Artifact [45d6850c18]:


95
96
97
98
99
100
101
102
103


104
105
106
107
108
109
110
95
96
97
98
99
100
101


102
103
104
105
106
107
108
109
110







-
-
+
+







 * Prototypes for functions that are private to this file:
 */

static void	LoadCleanupProc(void *clientData,
		    Tcl_Interp *interp);
static int	IsStatic(LoadedLibrary *libraryPtr);
static int	UnloadLibrary(Tcl_Interp *interp, Tcl_Interp *target,
		    LoadedLibrary *library, int keepLibrary,
		    const char *fullFileName, int interpExiting);
		    LoadedLibrary *library, bool keepLibrary,
		    const char *fullFileName, bool interpExiting);

static int
IsStatic(
    LoadedLibrary *libraryPtr)
{
    return (libraryPtr->fileName[0] == '\0');
}
133
134
135
136
137
138
139
140

141
142
143
144
145
146
147
133
134
135
136
137
138
139

140
141
142
143
144
145
146
147







-
+







    int objc,			/* Number of arguments. */
    Tcl_Obj *const objv[])	/* Argument objects. */
{
    Tcl_Interp *target;
    LoadedLibrary *libraryPtr, *defaultPtr;
    Tcl_DString pfx, tmp, initName, safeInitName;
    Tcl_DString unloadName, safeUnloadName;
    int code, namesMatch, filesMatch;
    int code;
    Tcl_Size offset;
    Tcl_LibraryInitProc *initProc;
    const char *fullFileName, *prefix;
    Tcl_LoadHandle loadHandle;
    Tcl_UniChar ch = 0;
    size_t len;
    int flags = 0;
228
229
230
231
232
233
234

235
236

237
238
239
240
241
242
243


244
245
246
247
248
249
250
251
252
253
254
228
229
230
231
232
233
234
235
236

237
238
239
240
241
242


243
244




245
246
247
248
249
250
251







+

-
+





-
-
+
+
-
-
-
-







     */

    Tcl_MutexLock(&libraryMutex);

    defaultPtr = NULL;
    for (libraryPtr = firstLibraryPtr; libraryPtr != NULL;
	    libraryPtr = libraryPtr->nextPtr) {
	bool namesMatch, filesMatch;
	if (prefix == NULL) {
	    namesMatch = 0;
	    namesMatch = false;
	} else {
	    TclDStringClear(&pfx);
	    Tcl_DStringAppend(&pfx, prefix, -1);
	    TclDStringClear(&tmp);
	    Tcl_DStringAppend(&tmp, libraryPtr->prefix, -1);
	    if (strcmp(Tcl_DStringValue(&tmp),
		    Tcl_DStringValue(&pfx)) == 0) {
	    namesMatch = (strcmp(Tcl_DStringValue(&tmp),
		    Tcl_DStringValue(&pfx)) == 0);
		namesMatch = 1;
	    } else {
		namesMatch = 0;
	    }
	}
	TclDStringClear(&pfx);

	filesMatch = (strcmp(libraryPtr->fileName, fullFileName) == 0);
	if (filesMatch && (namesMatch || (prefix == NULL))) {
	    break;
	}
555
556
557
558
559
560
561
562


563
564
565
566
567
568
569
552
553
554
555
556
557
558

559
560
561
562
563
564
565
566
567







-
+
+







    int objc,			/* Number of arguments. */
    Tcl_Obj *const objv[])	/* Argument objects. */
{
    Tcl_Interp *target;		/* Which interpreter to unload from. */
    LoadedLibrary *libraryPtr;
    Tcl_DString pfx, tmp;
    InterpLibrary *ipFirstPtr, *ipPtr;
    int i, code, complain = 1, keepLibrary = 0;
    int i, code;
    bool complain = true, keepLibrary = false;
    const char *fullFileName = "";
    const char *prefix;
    static const char *const options[] = {
	"-nocomplain", "-keeplibrary", "--", NULL
    };
    enum unloadOptionsEnum {
	UNLOAD_NOCOMPLAIN, UNLOAD_KEEPLIB, UNLOAD_LAST
588
589
590
591
592
593
594
595

596
597
598

599
600
601
602
603
604
605
586
587
588
589
590
591
592

593
594
595

596
597
598
599
600
601
602
603







-
+


-
+








		Tcl_ResetResult(interp);
		break;
	    }
	}
	switch (index) {
	case UNLOAD_NOCOMPLAIN:		/* -nocomplain */
	    complain = 0;
	    complain = false;
	    break;
	case UNLOAD_KEEPLIB:		/* -keeplibrary */
	    keepLibrary = 1;
	    keepLibrary = true;
	    break;
	case UNLOAD_LAST:		/* -- */
	    i++;
	    goto endOfForLoop;
	default:
	    TCL_UNREACHABLE();
	}
655
656
657
658
659
660
661
662

663
664
665

666
667
668
669
670
671
672


673
674
675
676
677
678
679
680
681
682
683
653
654
655
656
657
658
659

660
661
662

663
664
665
666
667
668


669
670




671
672
673
674
675
676
677







-
+


-
+





-
-
+
+
-
-
-
-







     *  - Its prefix matches, the file name was specified as empty, and there is
     *	  no statically loaded library with the same prefix.
     */

    Tcl_MutexLock(&libraryMutex);

    for (libraryPtr = firstLibraryPtr; libraryPtr != NULL; libraryPtr = libraryPtr->nextPtr) {
	int namesMatch, filesMatch;
	bool namesMatch, filesMatch;

	if (prefix == NULL) {
	    namesMatch = 0;
	    namesMatch = false;
	} else {
	    TclDStringClear(&pfx);
	    Tcl_DStringAppend(&pfx, prefix, -1);
	    TclDStringClear(&tmp);
	    Tcl_DStringAppend(&tmp, libraryPtr->prefix, -1);
	    if (strcmp(Tcl_DStringValue(&tmp),
		    Tcl_DStringValue(&pfx)) == 0) {
	    namesMatch = (strcmp(Tcl_DStringValue(&tmp),
		    Tcl_DStringValue(&pfx)) == 0);
		namesMatch = 1;
	    } else {
		namesMatch = 0;
	    }
	}
	TclDStringClear(&pfx);

	filesMatch = (strcmp(libraryPtr->fileName, fullFileName) == 0);
	if (filesMatch && (namesMatch || (prefix == NULL))) {
	    break;
	}
735
736
737
738
739
740
741
742


743
744
745
746
747
748
749
729
730
731
732
733
734
735

736
737
738
739
740
741
742
743
744







-
+
+







		"file \"%s\" has never been loaded in this interpreter",
		fullFileName);
	TclSetErrorCode(interp, "TCL", "OPERATION", "UNLOAD", "NEVERLOADED");
	code = TCL_ERROR;
	goto done;
    }

    code = UnloadLibrary(interp, target, libraryPtr, keepLibrary, fullFileName, 0);
    code = UnloadLibrary(interp, target, libraryPtr, keepLibrary, fullFileName,
	    false);

  done:
    Tcl_DStringFree(&pfx);
    Tcl_DStringFree(&tmp);
    if (!complain && (code != TCL_OK)) {
	code = TCL_OK;
	Tcl_ResetResult(interp);
768
769
770
771
772
773
774
775

776
777

778
779
780
781
782
783
784
763
764
765
766
767
768
769

770
771

772
773
774
775
776
777
778
779







-
+

-
+







 *----------------------------------------------------------------------
 */
static int
UnloadLibrary(
    Tcl_Interp *interp,
    Tcl_Interp *target,
    LoadedLibrary *libraryPtr,
    int keepLibrary,
    bool keepLibrary,
    const char *fullFileName,
    int interpExiting)
    bool interpExiting)
{
    int code;
    InterpLibrary *ipFirstPtr, *ipPtr;
    LoadedLibrary *iterLibraryPtr;
    int trustedRefCount = -1, safeRefCount = -1;
    Tcl_LibraryUnloadProc *unloadProc = NULL;

1193
1194
1195
1196
1197
1198
1199
1200

1201
1202
1203
1204
1205
1206
1207
1188
1189
1190
1191
1192
1193
1194

1195
1196
1197
1198
1199
1200
1201
1202







-
+







    Tcl_Interp *interp)
{
    InterpLibrary *ipPtr = (InterpLibrary *)clientData, *nextPtr;
    LoadedLibrary *libraryPtr;

    while (ipPtr) {
	libraryPtr = ipPtr->libraryPtr;
	UnloadLibrary(interp, interp, libraryPtr, 0, "", 1);
	UnloadLibrary(interp, interp, libraryPtr, false, "", true);
	/* UnloadLibrary doesn't free it by interp delete, so do it here and
	 * repeat for next. */
	nextPtr = ipPtr->nextPtr;
	Tcl_Free(ipPtr);
	ipPtr = nextPtr;
    }
}