| ︙ | | | ︙ | |
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);
static int
IsStatic(
LoadedLibrary *libraryPtr)
{
return (libraryPtr->fileName[0] == '\0');
}
|
|
|
|
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, 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
|
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;
Tcl_Size offset;
Tcl_LibraryInitProc *initProc;
const char *fullFileName, *prefix;
Tcl_LoadHandle loadHandle;
Tcl_UniChar ch = 0;
size_t len;
int flags = 0;
|
|
|
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;
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
|
*/
Tcl_MutexLock(&libraryMutex);
defaultPtr = NULL;
for (libraryPtr = firstLibraryPtr; libraryPtr != NULL;
libraryPtr = libraryPtr->nextPtr) {
if (prefix == NULL) {
namesMatch = 0;
} 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 = 1;
} else {
namesMatch = 0;
}
}
TclDStringClear(&pfx);
filesMatch = (strcmp(libraryPtr->fileName, fullFileName) == 0);
if (filesMatch && (namesMatch || (prefix == NULL))) {
break;
}
|
>
|
|
|
<
<
<
<
|
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 = false;
} else {
TclDStringClear(&pfx);
Tcl_DStringAppend(&pfx, prefix, -1);
TclDStringClear(&tmp);
Tcl_DStringAppend(&tmp, libraryPtr->prefix, -1);
namesMatch = (strcmp(Tcl_DStringValue(&tmp),
Tcl_DStringValue(&pfx)) == 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
|
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;
const char *fullFileName = "";
const char *prefix;
static const char *const options[] = {
"-nocomplain", "-keeplibrary", "--", NULL
};
enum unloadOptionsEnum {
UNLOAD_NOCOMPLAIN, UNLOAD_KEEPLIB, UNLOAD_LAST
|
|
>
|
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;
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
|
Tcl_ResetResult(interp);
break;
}
}
switch (index) {
case UNLOAD_NOCOMPLAIN: /* -nocomplain */
complain = 0;
break;
case UNLOAD_KEEPLIB: /* -keeplibrary */
keepLibrary = 1;
break;
case UNLOAD_LAST: /* -- */
i++;
goto endOfForLoop;
default:
TCL_UNREACHABLE();
}
|
|
|
|
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 = false;
break;
case UNLOAD_KEEPLIB: /* -keeplibrary */
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
|
* - 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;
if (prefix == NULL) {
namesMatch = 0;
} 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 = 1;
} else {
namesMatch = 0;
}
}
TclDStringClear(&pfx);
filesMatch = (strcmp(libraryPtr->fileName, fullFileName) == 0);
if (filesMatch && (namesMatch || (prefix == NULL))) {
break;
}
|
|
|
|
|
<
<
<
<
|
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) {
bool namesMatch, filesMatch;
if (prefix == NULL) {
namesMatch = false;
} else {
TclDStringClear(&pfx);
Tcl_DStringAppend(&pfx, prefix, -1);
TclDStringClear(&tmp);
Tcl_DStringAppend(&tmp, libraryPtr->prefix, -1);
namesMatch = (strcmp(Tcl_DStringValue(&tmp),
Tcl_DStringValue(&pfx)) == 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
|
"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);
done:
Tcl_DStringFree(&pfx);
Tcl_DStringFree(&tmp);
if (!complain && (code != TCL_OK)) {
code = TCL_OK;
Tcl_ResetResult(interp);
|
|
>
|
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,
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
|
*----------------------------------------------------------------------
*/
static int
UnloadLibrary(
Tcl_Interp *interp,
Tcl_Interp *target,
LoadedLibrary *libraryPtr,
int keepLibrary,
const char *fullFileName,
int interpExiting)
{
int code;
InterpLibrary *ipFirstPtr, *ipPtr;
LoadedLibrary *iterLibraryPtr;
int trustedRefCount = -1, safeRefCount = -1;
Tcl_LibraryUnloadProc *unloadProc = NULL;
|
|
|
|
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,
bool keepLibrary,
const char *fullFileName,
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
|
Tcl_Interp *interp)
{
InterpLibrary *ipPtr = (InterpLibrary *)clientData, *nextPtr;
LoadedLibrary *libraryPtr;
while (ipPtr) {
libraryPtr = ipPtr->libraryPtr;
UnloadLibrary(interp, interp, libraryPtr, 0, "", 1);
/* UnloadLibrary doesn't free it by interp delete, so do it here and
* repeat for next. */
nextPtr = ipPtr->nextPtr;
Tcl_Free(ipPtr);
ipPtr = nextPtr;
}
}
|
|
|
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, 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;
}
}
|
| ︙ | | | ︙ | |