summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--ChangeLog18
-rw-r--r--generic/tclIOUtil.c44
-rw-r--r--generic/tclInt.h13
-rw-r--r--generic/tclLoadNone.c29
-rw-r--r--mac/tclMacLoad.c186
-rw-r--r--unix/tclLoadAout.c33
-rw-r--r--unix/tclLoadDl.c54
-rw-r--r--unix/tclLoadDld.c29
-rw-r--r--unix/tclLoadDyld.c69
-rw-r--r--unix/tclLoadNext.c44
-rw-r--r--unix/tclLoadOSF.c33
-rw-r--r--unix/tclLoadShl.c53
-rw-r--r--win/tclWinLoad.c48
13 files changed, 370 insertions, 283 deletions
diff --git a/ChangeLog b/ChangeLog
index 8b3b350..d2ea46b 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,21 @@
+2002-07-17 Vince Darley <vincentdarley@users.sourceforge.net>
+
+ * generic/tclInt.h:
+ * generic/tclIOUtil.c:
+ * generic/tclLoadNone.c:
+ * unix/tclLoadAout.c:
+ * unix/tclLoadDl.c:
+ * unix/tclLoadDld.c:
+ * unix/tclLoadDyld.c:
+ * unix/tclLoadNext.c:
+ * unix/tclLoadOSF.c:
+ * unix/tclLoadShl.c:
+ * mac/tclMacLoad.c:
+ * win/tclWinLoad.c: modified to move more functionality
+ to the generic code and avoid duplication. Partial replacement
+ of internal uses of clientData with opaque TclLoadHandle. A
+ little further work still needed, but significant changes are done.
+
2002-07-17 D. Richard Hipp <drh@hwaci.com>
* library/msgcat/msgcat.tcl: fix a comment that was causing
diff --git a/generic/tclIOUtil.c b/generic/tclIOUtil.c
index 5b82f7e..c875292 100644
--- a/generic/tclIOUtil.c
+++ b/generic/tclIOUtil.c
@@ -17,7 +17,7 @@
* See the file "license.terms" for information on usage and redistribution
* of this file, and for a DISCLAIMER OF ALL WARRANTIES.
*
- * RCS: @(#) $Id: tclIOUtil.c,v 1.55 2002/07/15 14:16:43 vincentdarley Exp $
+ * RCS: @(#) $Id: tclIOUtil.c,v 1.56 2002/07/17 20:00:44 vincentdarley Exp $
*/
#include "tclInt.h"
@@ -2626,6 +2626,48 @@ Tcl_FSLoadFile(interp, pathPtr, sym1, sym2, proc1Ptr, proc2Ptr,
Tcl_SetErrno(ENOENT);
return -1;
}
+/*
+ * This function used to be in the platform specific directories, but it
+ * has now been made to work cross-platform
+ */
+int
+TclpLoadFile(interp, pathPtr, sym1, sym2, proc1Ptr, proc2Ptr,
+ clientDataPtr, unloadProcPtr)
+ Tcl_Interp *interp; /* Used for error reporting. */
+ Tcl_Obj *pathPtr; /* Name of the file containing the desired
+ * code (UTF-8). */
+ CONST char *sym1, *sym2; /* Names of two procedures to look up in
+ * the file's symbol table. */
+ Tcl_PackageInitProc **proc1Ptr, **proc2Ptr;
+ /* Where to return the addresses corresponding
+ * to sym1 and sym2. */
+ ClientData *clientDataPtr; /* Filled with token for dynamically loaded
+ * file which will be passed back to
+ * (*unloadProcPtr)() to unload the file. */
+ Tcl_FSUnloadFileProc **unloadProcPtr;
+ /* Filled with address of Tcl_FSUnloadFileProc
+ * function which should be used for
+ * this file. */
+{
+ TclLoadHandle handle = NULL;
+ int res;
+
+ res = TclpDlopen(interp, pathPtr, &handle, unloadProcPtr);
+
+ if (res != TCL_OK) {
+ return res;
+ }
+
+ if (handle == NULL) {
+ return TCL_ERROR;
+ }
+
+ *clientDataPtr = (ClientData)handle;
+
+ *proc1Ptr = TclpFindSymbol(interp, handle, sym1);
+ *proc2Ptr = TclpFindSymbol(interp, handle, sym2);
+ return TCL_OK;
+}
/*
*---------------------------------------------------------------------------
diff --git a/generic/tclInt.h b/generic/tclInt.h
index 3fca93b..ba9ebc3 100644
--- a/generic/tclInt.h
+++ b/generic/tclInt.h
@@ -12,7 +12,7 @@
* See the file "license.terms" for information on usage and redistribution
* of this file, and for a DISCLAIMER OF ALL WARRANTIES.
*
- * RCS: @(#) $Id: tclInt.h,v 1.101 2002/07/17 10:36:23 msofer Exp $
+ * RCS: @(#) $Id: tclInt.h,v 1.102 2002/07/17 20:00:45 vincentdarley Exp $
*/
#ifndef _TCLINT
@@ -1563,7 +1563,8 @@ typedef struct TclFile_ *TclFile;
* Opaque names for platform specific types.
*/
-typedef struct TclpTime_t_ *TclpTime_t;
+typedef struct TclpTime_t_ *TclpTime_t;
+typedef struct TclLoadHandle_ *TclLoadHandle;
/*
* The "globParameters" argument of the function TclGlob is an
@@ -1829,8 +1830,14 @@ EXTERN void TclTransferResult _ANSI_ARGS_((Tcl_Interp *sourceInterp,
int result, Tcl_Interp *targetInterp));
EXTERN Tcl_Obj* TclpNativeToNormalized
_ANSI_ARGS_((ClientData clientData));
-EXTERN Tcl_Obj* TclpFilesystemPathType
+EXTERN Tcl_Obj* TclpFilesystemPathType
_ANSI_ARGS_((Tcl_Obj* pathObjPtr));
+EXTERN Tcl_PackageInitProc* TclpFindSymbol _ANSI_ARGS_((Tcl_Interp *interp,
+ TclLoadHandle loadHandle, CONST char *symbol));
+EXTERN int TclpDlopen _ANSI_ARGS_((Tcl_Interp *interp,
+ Tcl_Obj *pathPtr,
+ TclLoadHandle *loadHandle,
+ Tcl_FSUnloadFileProc **unloadProcPtr));
/*
*----------------------------------------------------------------
diff --git a/generic/tclLoadNone.c b/generic/tclLoadNone.c
index ee79130..9d93ba1 100644
--- a/generic/tclLoadNone.c
+++ b/generic/tclLoadNone.c
@@ -10,7 +10,7 @@
* See the file "license.terms" for information on usage and redistribution
* of this file, and for a DISCLAIMER OF ALL WARRANTIES.
*
- * RCS: @(#) $Id: tclLoadNone.c,v 1.8 2002/01/21 22:47:52 davygrvy Exp $
+ * RCS: @(#) $Id: tclLoadNone.c,v 1.9 2002/07/17 20:00:46 vincentdarley Exp $
*/
#include "tclInt.h"
@@ -35,19 +35,17 @@
*/
int
-TclpLoadFile(interp, pathPtr, sym1, sym2, proc1Ptr, proc2Ptr, clientDataPtr, unloadProcPtr)
+TclpDlopen(interp, pathPtr, loadHandle, unloadProcPtr)
Tcl_Interp *interp; /* Used for error reporting. */
Tcl_Obj *pathPtr; /* Name of the file containing the desired
- * code. */
- CONST char *sym1, *sym2; /* Names of two procedures to look up in
- * the file's symbol table. */
- Tcl_PackageInitProc **proc1Ptr, **proc2Ptr;
- /* Where to return the addresses corresponding
- * to sym1 and sym2. */
- ClientData *clientDataPtr; /* Filled with token for dynamically loaded
+ * code (UTF-8). */
+ TclLoadHandle *loadHandle; /* Filled with token for dynamically loaded
* file which will be passed back to
- * TclpUnloadFile() to unload the file. */
- Tcl_FSUnloadFileProc **unloadProcPtr;
+ * (*unloadProcPtr)() to unload the file. */
+ Tcl_FSUnloadFileProc **unloadProcPtr;
+ /* Filled with address of Tcl_FSUnloadFileProc
+ * function which should be used for
+ * this file. */
{
Tcl_SetResult(interp,
"dynamic loading is not currently available on this system",
@@ -55,6 +53,15 @@ TclpLoadFile(interp, pathPtr, sym1, sym2, proc1Ptr, proc2Ptr, clientDataPtr, unl
return TCL_ERROR;
}
+Tcl_PackageInitProc*
+TclpFindSymbol(interp, loadHandle, symbol)
+ Tcl_Interp *interp;
+ TclLoadHandle loadHandle;
+ CONST char *symbol;
+{
+ return NULL;
+}
+
/*
*----------------------------------------------------------------------
*
diff --git a/mac/tclMacLoad.c b/mac/tclMacLoad.c
index e767651..a36e151 100644
--- a/mac/tclMacLoad.c
+++ b/mac/tclMacLoad.c
@@ -10,7 +10,7 @@
* See the file "license.terms" for information on usage and redistribution
* of this file, and for a DISCLAIMER OF ALL WARRANTIES.
*
- * RCS: @(#) $Id: tclMacLoad.c,v 1.12 2002/01/27 11:09:58 das Exp $
+ * RCS: @(#) $Id: tclMacLoad.c,v 1.13 2002/07/17 20:00:46 vincentdarley Exp $
*/
#include <CodeFragments.h>
@@ -76,6 +76,16 @@ struct CfrgItem {
Str255 name; /* This is actually variable sized. */
};
typedef struct CfrgItem CfrgItem;
+
+typedef struct TclMacLoadInfo {
+ int loaded;
+ CFragConnectionID connID;
+ FSSpec fileSpec;
+} TclMacLoadInfo;
+
+static int TryToLoad(Tcl_Interp *interp, TclMacLoadInfo *loadInfo,
+ CONST char *sym /* native */)
+
/*
*----------------------------------------------------------------------
@@ -97,18 +107,11 @@ typedef struct CfrgItem CfrgItem;
*/
int
-TclpLoadFile(
- Tcl_Interp *interp, /* Used for error reporting. */
- Tcl_Obj *pathPtr, /* Name of the file containing the desired
- * code. */
- CONST char *sym1,
- CONST char *sym2, /* Names of two procedures to look up in
- * the file's symbol table. */
- Tcl_PackageInitProc **proc1Ptr,
- Tcl_PackageInitProc **proc2Ptr,
- /* Where to return the addresses corresponding
- * to sym1 and sym2. */
- ClientData *clientDataPtr, /* Filled with token for dynamically loaded
+TclpDlopen(interp, pathPtr, loadHandle, unloadProcPtr)
+ Tcl_Interp *interp; /* Used for error reporting. */
+ Tcl_Obj *pathPtr; /* Name of the file containing the desired
+ * code (UTF-8). */
+ TclLoadHandle *loadHandle; /* Filled with token for dynamically loaded
* file which will be passed back to
* (*unloadProcPtr)() to unload the file. */
Tcl_FSUnloadFileProc **unloadProcPtr)
@@ -116,19 +119,11 @@ TclpLoadFile(
* function which should be used for
* this file. */
{
- CFragConnectionID connID;
- Ptr dummy;
OSErr err;
- CFragSymbolClass symClass;
FSSpec fileSpec;
- short fragFileRef, saveFileRef;
- Handle fragResource;
- UInt32 offset = 0;
- UInt32 length = kCFragGoesToEOF;
- StringPtr fragName=NULL;
- Str255 errName, symbolName;
Tcl_DString ds;
CONST char *native;
+ TclMacLoadInfo *loadInfo;
native = Tcl_FSGetNativePath(pathPtr);
err = FSpLocationFromPath(strlen(native), native, &fileSpec);
@@ -138,15 +133,37 @@ TclpLoadFile(
return TCL_ERROR;
}
- /*
- * First thing we must do is infer the package name from the sym1
- * variable (by removing the "_Init" suffix). This is kind of dumb
- * since the caller actually knows this value, it just doesn't give
- * it to us.
- */
- native = Tcl_UtfToExternalDString(NULL, sym1, -1, &ds);
- Tcl_DStringSetLength(&ds, Tcl_DStringLength(&ds) - 5);
+ loadInfo = (TclMacLoadInfo *) ckalloc(sizeof(TclMacLoadInfo));
+ loadInfo->loaded = 0;
+ loadInfo->fileSpec = fileSpec;
+ loadInfo->connID = NULL;
+ if (TryToLoad(interp, loadInfo, NULL) != TCL_OK) {
+ ckfree(loadInfo);
+ return TCL_ERROR;
+ }
+
+ *loadHandle = (TclLoadHandle)loadInfo;
+ *unloadProcPtr = &TclpUnloadFile;
+ return TCL_OK;
+}
+static int
+TryToLoad(Tcl_Interp *interp, TclMacLoadInfo *loadInfo,
+ CONST char *sym /* native */)
+{
+ CFragConnectionID connID;
+ Ptr dummy;
+ short fragFileRef, saveFileRef;
+ Handle fragResource;
+ UInt32 offset = 0;
+ UInt32 length = kCFragGoesToEOF;
+ Str255 errName;
+ StringPtr fragName=NULL;
+
+ if (loadInfo->loaded == 1) {
+ return TCL_OK;
+ }
+
/*
* See if this fragment has a 'cfrg' resource. It will tell us where
* to look for the fragment in the file. If it doesn't exist we will
@@ -160,25 +177,27 @@ TclpLoadFile(
fragFileRef = FSpOpenResFile(&fileSpec, fsRdPerm);
SetResLoad(true);
if (fragFileRef != -1) {
- UseResFile(fragFileRef);
- fragResource = Get1Resource(kCFragResourceType, kCFragResourceID);
- HLock(fragResource);
- if (ResError() == noErr) {
- CfrgItem* srcItem;
- long itemCount, index;
- Ptr itemStart;
+ if (sym != NULL) {
+ UseResFile(fragFileRef);
+ fragResource = Get1Resource(kCFragResourceType, kCFragResourceID);
+ HLock(fragResource);
+ if (ResError() == noErr) {
+ CfrgItem* srcItem;
+ long itemCount, index;
+ Ptr itemStart;
- itemCount = (*(CfrgHeaderPtrHand)fragResource)->itemCount;
- itemStart = &(*(CfrgHeaderPtrHand)fragResource)->arrayStart;
- for (index = 0; index < itemCount;
- index++, itemStart += srcItem->itemSize) {
- srcItem = (CfrgItem*)itemStart;
- if (srcItem->archType != OUR_ARCH_TYPE) continue;
- if (!strncasecmp(native, (char *) srcItem->name + 1,
- strlen(native))) {
- offset = srcItem->codeOffset;
- length = srcItem->codeLength;
- fragName=srcItem->name;
+ itemCount = (*(CfrgHeaderPtrHand)fragResource)->itemCount;
+ itemStart = &(*(CfrgHeaderPtrHand)fragResource)->arrayStart;
+ for (index = 0; index < itemCount;
+ index++, itemStart += srcItem->itemSize) {
+ srcItem = (CfrgItem*)itemStart;
+ if (srcItem->archType != OUR_ARCH_TYPE) continue;
+ if (!strncasecmp(sym, (char *) srcItem->name + 1,
+ strlen(sym))) {
+ offset = srcItem->codeOffset;
+ length = srcItem->codeLength;
+ fragName=srcItem->name;
+ }
}
}
}
@@ -191,20 +210,21 @@ TclpLoadFile(
ReleaseResource(fragResource);
CloseResFile(fragFileRef);
UseResFile(saveFileRef);
+ if (sym == NULL) {
+ /* We just return */
+ return TCL_OK;
+ }
}
- Tcl_DStringFree(&ds);
/*
- * Now we can attempt to load the fragement using the offset & length
+ * Now we can attempt to load the fragment using the offset & length
* obtained from the resource. We don't worry about the main entry point
* as we are going to search for specific entry points passed to us.
*/
err = GetDiskFragment(&fileSpec, offset, length, fragName,
kLoadCFrag, &connID, &dummy, errName);
-
- *clientDataPtr = (ClientData) connID;
-
+
if (err != fragNoErr) {
p2cstr(errName);
Tcl_AppendResult(interp, "couldn't load file \"",
@@ -212,31 +232,53 @@ TclpLoadFile(
"\": ", errName, (char *) NULL);
return TCL_ERROR;
}
-
- *unloadProcPtr = &TclpUnloadFile;
+
+ loadInfo->connID = connID;
+ loadInfo->loaded = 1;
+
+ return TCL_OK;
+}
+
+Tcl_PackageInitProc*
+TclpFindSymbol(interp, loadHandle, symbol)
+ Tcl_Interp *interp;
+ TclLoadHandle loadHandle;
+ CONST char *symbol;
+{
+ Tcl_DString ds;
+ Tcl_PackageInitProc *proc=NULL;
+ TclMacLoadInfo *loadInfo = (TclMacLoadInfo *)loadHandle;
+ Str255 symbolName;
+ CFragSymbolClass symClass;
+ OSErr err;
- Tcl_UtfToExternalDString(NULL, sym1, -1, &ds);
+ if (loadInfo->loaded == 0) {
+ int res;
+ /*
+ * First thing we must do is infer the package name from the
+ * sym variable. We do this by removing the '_Init'.
+ */
+ Tcl_UtfToExternalDString(NULL, symbol, -1, &ds);
+ Tcl_DStringSetLength(&ds, Tcl_DStringLength(&ds) - 5);
+ res = TryToLoad(interp, loadInfo, Tcl_DStringValue(&ds));
+ Tcl_DStringFree(&ds);
+ if (res != TCL_OK) {
+ return NULL;
+ }
+ }
+
+ Tcl_UtfToExternalDString(NULL, symbol, -1, &ds);
strcpy((char *) symbolName + 1, Tcl_DStringValue(&ds));
symbolName[0] = (unsigned) Tcl_DStringLength(&ds);
- err = FindSymbol(connID, symbolName, (Ptr *) proc1Ptr, &symClass);
+ err = FindSymbol(loadInfo->connID, symbolName, (Ptr *) &proc, &symClass);
Tcl_DStringFree(&ds);
if (err != fragNoErr || symClass == kDataCFragSymbol) {
Tcl_SetResult(interp,
"could not find Initialization routine in library",
TCL_STATIC);
- return TCL_ERROR;
+ return NULL;
}
-
- Tcl_UtfToExternalDString(NULL, sym2, -1, &ds);
- strcpy((char *) symbolName + 1, Tcl_DStringValue(&ds));
- symbolName[0] = (unsigned) Tcl_DStringLength(&ds);
- err = FindSymbol(connID, symbolName, (Ptr *) proc2Ptr, &symClass);
- Tcl_DStringFree(&ds);
- if (err != fragNoErr || symClass == kDataCFragSymbol) {
- *proc2Ptr = NULL;
- }
-
- return TCL_OK;
+ return proc;
}
/*
@@ -264,7 +306,11 @@ TclpUnloadFile(clientData)
* a token that represents the loaded
* file. */
{
- CloseConnection((CFragConnectionID*) &clientData);
+ TclMacLoadInfo *loadInfo = (TclMacLoadInfo *)clientData;
+ if (loadInfo->loaded) {
+ CloseConnection((CFragConnectionID*) &(loadInfo->connID));
+ }
+ ckfree(loadInfo);
}
/*
diff --git a/unix/tclLoadAout.c b/unix/tclLoadAout.c
index afd956c..c4d6254 100644
--- a/unix/tclLoadAout.c
+++ b/unix/tclLoadAout.c
@@ -14,7 +14,7 @@
* and Design Engineering (MADE) Initiative through ARPA contract
* F33615-94-C-4400.
*
- * RCS: @(#) $Id: tclLoadAout.c,v 1.10 2002/02/15 14:28:50 dkf Exp $
+ * RCS: @(#) $Id: tclLoadAout.c,v 1.11 2002/07/17 20:00:46 vincentdarley Exp $
*/
#include "tclInt.h"
@@ -141,17 +141,11 @@ static void UnlinkSymbolTable _ANSI_ARGS_((void));
*/
int
-TclpLoadFile(interp, pathPtr, sym1, sym2, proc1Ptr, proc2Ptr,
- clientDataPtr, unloadProcPtr)
+TclpDlopen(interp, pathPtr, loadHandle, unloadProcPtr)
Tcl_Interp *interp; /* Used for error reporting. */
Tcl_Obj *pathPtr; /* Name of the file containing the desired
* code (UTF-8). */
- CONST char *sym1, *sym2; /* Names of two procedures to look up in
- * the file's symbol table. */
- Tcl_PackageInitProc **proc1Ptr, **proc2Ptr;
- /* Where to return the addresses corresponding
- * to sym1 and sym2. */
- ClientData *clientDataPtr; /* Filled with token for dynamically loaded
+ TclLoadHandle *loadHandle; /* Filled with token for dynamically loaded
* file which will be passed back to
* (*unloadProcPtr)() to unload the file. */
Tcl_FSUnloadFileProc **unloadProcPtr;
@@ -172,12 +166,9 @@ TclpLoadFile(interp, pathPtr, sym1, sym2, proc1Ptr, proc2Ptr,
struct exec relocatedHead; /* Header of the relocated text */
unsigned long relocatedSize; /* Size of the relocated text */
char * startAddress; /* Starting address of the module */
- DictFn dictionary; /* Dictionary function in the load module */
int status; /* Status return from Tcl_ calls */
char * p;
- *clientDataPtr = NULL;
-
/* Find the file that contains the symbols for the run-time link. */
if (SymbolTableFile != NULL) {
@@ -317,15 +308,21 @@ TclpLoadFile(interp, pathPtr, sym1, sym2, proc1Ptr, proc2Ptr,
SymbolTableFile = ckalloc (strlen (relocatedFileName) + 1);
strcpy (SymbolTableFile, relocatedFileName);
- /* Look up the entry points in the load module's dictionary. */
-
- dictionary = (DictFn) startAddress;
- *proc1Ptr = dictionary (sym1);
- *proc2Ptr = dictionary (sym2);
-
+ *loadHandle = startAddress;
return TCL_OK;
}
+TclpFindSymbol(interp, loadHandle, symbol)
+ Tcl_Interp *interp;
+ TclLoadHandle loadHandle;
+ CONST char *symbol;
+{
+ /* Look up the entry point in the load module's dictionary. */
+ DictFn dictionary = (DictFn) loadHandle;
+ return (Tcl_PackageInitProc*) dictionary(sym1);
+}
+
+
/*
*------------------------------------------------------------------------
*
diff --git a/unix/tclLoadDl.c b/unix/tclLoadDl.c
index 3578695..951a8cb 100644
--- a/unix/tclLoadDl.c
+++ b/unix/tclLoadDl.c
@@ -10,7 +10,7 @@
* See the file "license.terms" for information on usage and redistribution
* of this file, and for a DISCLAIMER OF ALL WARRANTIES.
*
- * RCS: @(#) $Id: tclLoadDl.c,v 1.8 2002/01/09 19:09:28 kennykb Exp $
+ * RCS: @(#) $Id: tclLoadDl.c,v 1.9 2002/07/17 20:00:46 vincentdarley Exp $
*/
#include "tclInt.h"
@@ -57,17 +57,11 @@
*/
int
-TclpLoadFile(interp, pathPtr, sym1, sym2, proc1Ptr, proc2Ptr,
- clientDataPtr, unloadProcPtr)
+TclpDlopen(interp, pathPtr, loadHandle, unloadProcPtr)
Tcl_Interp *interp; /* Used for error reporting. */
Tcl_Obj *pathPtr; /* Name of the file containing the desired
- * code. */
- CONST char *sym1, *sym2; /* Names of two procedures to look up in
- * the file's symbol table. */
- Tcl_PackageInitProc **proc1Ptr, **proc2Ptr;
- /* Where to return the addresses corresponding
- * to sym1 and sym2. */
- ClientData *clientDataPtr; /* Filled with token for dynamically loaded
+ * code (UTF-8). */
+ TclLoadHandle *loadHandle; /* Filled with token for dynamically loaded
* file which will be passed back to
* (*unloadProcPtr)() to unload the file. */
Tcl_FSUnloadFileProc **unloadProcPtr;
@@ -76,14 +70,11 @@ TclpLoadFile(interp, pathPtr, sym1, sym2, proc1Ptr, proc2Ptr,
* this file. */
{
VOID *handle;
- Tcl_DString newName, ds;
CONST char *native;
native = Tcl_FSGetNativePath(pathPtr);
handle = dlopen(native, RTLD_NOW | RTLD_GLOBAL); /* INTL: Native. */
- *clientDataPtr = (ClientData) handle;
-
if (handle == NULL) {
Tcl_AppendResult(interp, "couldn't load file \"",
Tcl_GetString(pathPtr),
@@ -92,40 +83,39 @@ TclpLoadFile(interp, pathPtr, sym1, sym2, proc1Ptr, proc2Ptr,
}
*unloadProcPtr = &TclpUnloadFile;
-
+ *loadHandle = (TclLoadHandle)handle;
+}
+
+Tcl_PackageInitProc*
+TclpFindSymbol(interp, loadHandle, symbol)
+ Tcl_Interp *interp;
+ TclLoadHandle loadHandle;
+ CONST char *symbol;
+{
+ CONST char *native;
+ Tcl_DString newName, ds;
+ VOID *handle = (VOID*)loadHandle;
+ Tcl_PackageInitProc *proc;
/*
* Some platforms still add an underscore to the beginning of symbol
* names. If we can't find a name without an underscore, try again
* with the underscore.
*/
- native = Tcl_UtfToExternalDString(NULL, sym1, -1, &ds);
- *proc1Ptr = (Tcl_PackageInitProc *) dlsym(handle, /* INTL: Native. */
+ native = Tcl_UtfToExternalDString(NULL, symbol, -1, &ds);
+ proc = (Tcl_PackageInitProc *) dlsym(handle, /* INTL: Native. */
native);
- if (*proc1Ptr == NULL) {
+ if (proc == NULL) {
Tcl_DStringInit(&newName);
Tcl_DStringAppend(&newName, "_", 1);
native = Tcl_DStringAppend(&newName, native, -1);
- *proc1Ptr = (Tcl_PackageInitProc *) dlsym(handle, /* INTL: Native. */
+ proc = (Tcl_PackageInitProc *) dlsym(handle, /* INTL: Native. */
native);
Tcl_DStringFree(&newName);
}
Tcl_DStringFree(&ds);
- native = Tcl_UtfToExternalDString(NULL, sym2, -1, &ds);
- *proc2Ptr = (Tcl_PackageInitProc *) dlsym(handle, /* INTL: Native. */
- native);
- if (*proc2Ptr == NULL) {
- Tcl_DStringInit(&newName);
- Tcl_DStringAppend(&newName, "_", 1);
- native = Tcl_DStringAppend(&newName, native, -1);
- *proc2Ptr = (Tcl_PackageInitProc *) dlsym(handle, /* INTL: Native. */
- native);
- Tcl_DStringFree(&newName);
- }
- Tcl_DStringFree(&ds);
-
- return TCL_OK;
+ return proc;
}
/*
diff --git a/unix/tclLoadDld.c b/unix/tclLoadDld.c
index f1c1589..99fee26 100644
--- a/unix/tclLoadDld.c
+++ b/unix/tclLoadDld.c
@@ -12,7 +12,7 @@
* See the file "license.terms" for information on usage and redistribution
* of this file, and for a DISCLAIMER OF ALL WARRANTIES.
*
- * RCS: @(#) $Id: tclLoadDld.c,v 1.8 2002/01/10 22:03:12 kennykb Exp $
+ * RCS: @(#) $Id: tclLoadDld.c,v 1.9 2002/07/17 20:00:46 vincentdarley Exp $
*/
#include "tclInt.h"
@@ -49,17 +49,11 @@
*/
int
-TclpLoadFile(interp, pathPtr, sym1, sym2, proc1Ptr, proc2Ptr,
- clientDataPtr, unloadProcPtr)
+TclpDlopen(interp, pathPtr, loadHandle, unloadProcPtr)
Tcl_Interp *interp; /* Used for error reporting. */
Tcl_Obj *pathPtr; /* Name of the file containing the desired
- * code. */
- CONST char *sym1, *sym2; /* Names of two procedures to look up in
- * the file's symbol table. */
- Tcl_PackageInitProc **proc1Ptr, **proc2Ptr;
- /* Where to return the addresses corresponding
- * to sym1 and sym2. */
- ClientData *clientDataPtr; /* Filled with token for dynamically loaded
+ * code (UTF-8). */
+ TclLoadHandle *loadHandle; /* Filled with token for dynamically loaded
* file which will be passed back to
* (*unloadProcPtr)() to unload the file. */
Tcl_FSUnloadFileProc **unloadProcPtr;
@@ -73,7 +67,7 @@ TclpLoadFile(interp, pathPtr, sym1, sym2, proc1Ptr, proc2Ptr,
/*
* The dld package needs to know the pathname to the tcl binary.
- * If that's not know, return an error.
+ * If that's not known, return an error.
*/
if (firstTime) {
@@ -99,14 +93,21 @@ TclpLoadFile(interp, pathPtr, sym1, sym2, proc1Ptr, proc2Ptr,
"\": ", dld_strerror(returnCode), (char *) NULL);
return TCL_ERROR;
}
- *proc1Ptr = (Tcl_PackageInitProc *) dld_get_func(sym1);
- *proc2Ptr = (Tcl_PackageInitProc *) dld_get_func(sym2);
- *clientDataPtr = strcpy(
+ *loadHandle = strcpy(
(char *) ckalloc((unsigned) (strlen(fileName) + 1)), fileName);
*unloadProcPtr = &TclpUnloadFile;
return TCL_OK;
}
+Tcl_PackageInitProc*
+TclpFindSymbol(interp, loadHandle, symbol)
+ Tcl_Interp *interp;
+ TclLoadHandle loadHandle;
+ CONST char *symbol;
+{
+ return (Tcl_PackageInitProc *) dld_get_func(symbol);
+}
+
/*
*----------------------------------------------------------------------
*
diff --git a/unix/tclLoadDyld.c b/unix/tclLoadDyld.c
index 8541416..9eefd91 100644
--- a/unix/tclLoadDyld.c
+++ b/unix/tclLoadDyld.c
@@ -11,7 +11,7 @@
* See the file "license.terms" for information on usage and redistribution
* of this file, and for a DISCLAIMER OF ALL WARRANTIES.
*
- * RCS: @(#) $Id: tclLoadDyld.c,v 1.8 2002/02/25 15:21:59 das Exp $
+ * RCS: @(#) $Id: tclLoadDyld.c,v 1.9 2002/07/17 20:00:46 vincentdarley Exp $
*/
#include "tclInt.h"
@@ -40,17 +40,11 @@
*/
int
-TclpLoadFile(interp, pathPtr, sym1, sym2, proc1Ptr, proc2Ptr,
- clientDataPtr, unloadProcPtr)
+TclpDlopen(interp, pathPtr, loadHandle, unloadProcPtr)
Tcl_Interp *interp; /* Used for error reporting. */
Tcl_Obj *pathPtr; /* Name of the file containing the desired
- * code. */
- CONST char *sym1, *sym2; /* Names of two procedures to look up in
- * the file's symbol table. */
- Tcl_PackageInitProc **proc1Ptr, **proc2Ptr;
- /* Where to return the addresses corresponding
- * to sym1 and sym2. */
- ClientData *clientDataPtr; /* Filled with token for dynamically loaded
+ * code (UTF-8). */
+ TclLoadHandle *loadHandle; /* Filled with token for dynamically loaded
* file which will be passed back to
* (*unloadProcPtr)() to unload the file. */
Tcl_FSUnloadFileProc **unloadProcPtr;
@@ -58,9 +52,7 @@ TclpLoadFile(interp, pathPtr, sym1, sym2, proc1Ptr, proc2Ptr,
* function which should be used for
* this file. */
{
- NSSymbol symbol;
const struct mach_header *dyld_lib;
- Tcl_DString newName, ds;
char *native;
native = Tcl_FSGetNativePath(pathPtr);
@@ -75,46 +67,41 @@ TclpLoadFile(interp, pathPtr, sym1, sym2, proc1Ptr, proc2Ptr,
Tcl_AppendResult(interp, msg, (char *) NULL);
return TCL_ERROR;
}
-
+ *loadHandle = (TclLoadHandle)dyld_lib;
*unloadProcPtr = &TclpUnloadFile;
-
+ return TCL_OK;
+}
+
+Tcl_PackageInitProc*
+TclpFindSymbol(interp, loadHandle, symbol)
+ Tcl_Interp *interp;
+ TclLoadHandle loadHandle;
+ CONST char *symbol;
+{
+ NSSymbol nsSymbol;
+ CONST char *native;
+ Tcl_DString newName, ds;
+ Tcl_PackageInitProc* proc = NULL;
+ const struct mach_header *dyld_lib = (mach_header *)loadHandle;
/*
* dyld adds an underscore to the beginning of symbol names.
*/
- native = Tcl_UtfToExternalDString(NULL, sym1, -1, &ds);
+ native = Tcl_UtfToExternalDString(NULL, symbol, -1, &ds);
Tcl_DStringInit(&newName);
Tcl_DStringAppend(&newName, "_", 1);
native = Tcl_DStringAppend(&newName, native, -1);
- symbol = NSLookupSymbolInImage(dyld_lib, native,
- NSLOOKUPSYMBOLINIMAGE_OPTION_BIND_NOW |
- NSLOOKUPSYMBOLINIMAGE_OPTION_RETURN_ON_ERROR);
- if(symbol) {
- *proc1Ptr = NSAddressOfSymbol(symbol);
- *clientDataPtr = NSModuleForSymbol(symbol);
- } else {
- *proc1Ptr=NULL;
- *clientDataPtr=NULL;
+ nsSymbol = NSLookupSymbolInImage(dyld_lib, native,
+ NSLOOKUPSYMBOLINIMAGE_OPTION_BIND_NOW |
+ NSLOOKUPSYMBOLINIMAGE_OPTION_RETURN_ON_ERROR);
+ if(nsSymbol) {
+ proc = NSAddressOfSymbol(nsSymbol);
+ /* *clientDataPtr = NSModuleForSymbol(nsSymbol); */
}
Tcl_DStringFree(&newName);
Tcl_DStringFree(&ds);
-
- native = Tcl_UtfToExternalDString(NULL, sym2, -1, &ds);
- Tcl_DStringInit(&newName);
- Tcl_DStringAppend(&newName, "_", 1);
- native = Tcl_DStringAppend(&newName, native, -1);
- symbol = NSLookupSymbolInImage(dyld_lib, native,
- NSLOOKUPSYMBOLINIMAGE_OPTION_BIND_NOW |
- NSLOOKUPSYMBOLINIMAGE_OPTION_RETURN_ON_ERROR);
- if(symbol) {
- *proc2Ptr = NSAddressOfSymbol(symbol);
- } else {
- *proc2Ptr=NULL;
- }
- Tcl_DStringFree(&newName);
- Tcl_DStringFree(&ds);
-
- return TCL_OK;
+
+ return proc;
}
/*
diff --git a/unix/tclLoadNext.c b/unix/tclLoadNext.c
index d19b22e..cb09d38 100644
--- a/unix/tclLoadNext.c
+++ b/unix/tclLoadNext.c
@@ -10,7 +10,7 @@
* See the file "license.terms" for information on usage and redistribution
* of this file, and for a DISCLAIMER OF ALL WARRANTIES.
*
- * RCS: @(#) $Id: tclLoadNext.c,v 1.7 2002/01/09 19:09:28 kennykb Exp $
+ * RCS: @(#) $Id: tclLoadNext.c,v 1.8 2002/07/17 20:00:46 vincentdarley Exp $
*/
#include "tclInt.h"
@@ -39,17 +39,11 @@
*/
int
-TclpLoadFile(interp, pathPtr, sym1, sym2, proc1Ptr, proc2Ptr,
- clientDataPtr, unloadProcPtr)
+TclpDlopen(interp, pathPtr, loadHandle, unloadProcPtr)
Tcl_Interp *interp; /* Used for error reporting. */
Tcl_Obj *pathPtr; /* Name of the file containing the desired
- * code. */
- CONST char *sym1, *sym2; /* Names of two procedures to look up in
- * the file's symbol table. */
- Tcl_PackageInitProc **proc1Ptr, **proc2Ptr;
- /* Where to return the addresses corresponding
- * to sym1 and sym2. */
- ClientData *clientDataPtr; /* Filled with token for dynamically loaded
+ * code (UTF-8). */
+ TclLoadHandle *loadHandle; /* Filled with token for dynamically loaded
* file which will be passed back to
* (*unloadProcPtr)() to unload the file. */
Tcl_FSUnloadFileProc **unloadProcPtr;
@@ -72,25 +66,27 @@ TclpLoadFile(interp, pathPtr, sym1, sym2, proc1Ptr, proc2Ptr,
}
NXCloseMemory(errorStream,NX_FREEBUFFER);
- *proc1Ptr=NULL;
- if(sym1) {
- char sym[strlen(sym1)+2];
- sym[0]='_'; sym[1]=0; strcat(sym,sym1);
- rld_lookup(NULL,sym,(unsigned long *)proc1Ptr);
- }
-
- *proc2Ptr=NULL;
- if(sym2) {
- char sym[strlen(sym2)+2];
- sym[0]='_'; sym[1]=0; strcat(sym,sym2);
- rld_lookup(NULL,sym,(unsigned long *)proc2Ptr);
- }
- *clientDataPtr = NULL;
+ *loadHandle = (TclLoadHandle)1; /* A dummy non-NULL value */
*unloadProcPtr = &TclpUnloadFile;
return TCL_OK;
}
+Tcl_PackageInitProc*
+TclpFindSymbol(interp, loadHandle, symbol)
+ Tcl_Interp *interp;
+ TclLoadHandle loadHandle;
+ CONST char *symbol;
+{
+ Tcl_PackageInitProc *proc=NULL;
+ if(symbol) {
+ char sym[strlen(symbol)+2];
+ sym[0]='_'; sym[1]=0; strcat(sym,symbol);
+ rld_lookup(NULL,sym,(unsigned long *)&proc);
+ }
+ return proc;
+}
+
/*
*----------------------------------------------------------------------
*
diff --git a/unix/tclLoadOSF.c b/unix/tclLoadOSF.c
index 76c0c7c..8740feb 100644
--- a/unix/tclLoadOSF.c
+++ b/unix/tclLoadOSF.c
@@ -31,7 +31,7 @@
* See the file "license.terms" for information on usage and redistribution
* of this file, and for a DISCLAIMER OF ALL WARRANTIES.
*
- * RCS: @(#) $Id: tclLoadOSF.c,v 1.7 2002/01/09 19:09:28 kennykb Exp $
+ * RCS: @(#) $Id: tclLoadOSF.c,v 1.8 2002/07/17 20:00:46 vincentdarley Exp $
*/
#include "tclInt.h"
@@ -60,17 +60,11 @@
*/
int
-TclpLoadFile(interp, pathPtr, sym1, sym2, proc1Ptr, proc2Ptr,
- clientDataPtr, unloadProcPtr)
+TclpDlopen(interp, pathPtr, loadHandle, unloadProcPtr)
Tcl_Interp *interp; /* Used for error reporting. */
Tcl_Obj *pathPtr; /* Name of the file containing the desired
- * code. */
- CONST char *sym1, *sym2; /* Names of two procedures to look up in
- * the file's symbol table. */
- Tcl_PackageInitProc **proc1Ptr, **proc2Ptr;
- /* Where to return the addresses corresponding
- * to sym1 and sym2. */
- ClientData *clientDataPtr; /* Filled with token for dynamically loaded
+ * code (UTF-8). */
+ TclLoadHandle *loadHandle; /* Filled with token for dynamically loaded
* file which will be passed back to
* (*unloadProcPtr)() to unload the file. */
Tcl_FSUnloadFileProc **unloadProcPtr;
@@ -99,16 +93,25 @@ TclpLoadFile(interp, pathPtr, sym1, sym2, proc1Ptr, proc2Ptr,
* I build loadable modules with a makefile rule like
* ld ... -export $@: -o $@ $(OBJS)
*/
- if ((pkg = strrchr(fileName, '/')) == NULL)
- pkg = fileName;
- else
+ if ((pkg = strrchr(fileName, '/')) == NULL) {
+ pkg = fileName;
+ } else {
pkg++;
- *proc1Ptr = ldr_lookup_package(pkg, sym1);
- *proc2Ptr = ldr_lookup_package(pkg, sym2);
+ }
+ *loadHandle = pkg;
*unloadProcPtr = &TclpUnloadFile;
return TCL_OK;
}
+Tcl_PackageInitProc*
+TclpFindSymbol(interp, loadHandle, symbol)
+ Tcl_Interp *interp;
+ TclLoadHandle loadHandle;
+ CONST char *symbol;
+{
+ return ldr_lookup_package((char *)loadHandle, symbol);
+}
+
/*
*----------------------------------------------------------------------
*
diff --git a/unix/tclLoadShl.c b/unix/tclLoadShl.c
index cb222bb..14e5b2d 100644
--- a/unix/tclLoadShl.c
+++ b/unix/tclLoadShl.c
@@ -10,7 +10,7 @@
* See the file "license.terms" for information on usage and redistribution
* of this file, and for a DISCLAIMER OF ALL WARRANTIES.
*
- * RCS: @(#) $Id: tclLoadShl.c,v 1.9 2002/01/09 19:09:28 kennykb Exp $
+ * RCS: @(#) $Id: tclLoadShl.c,v 1.10 2002/07/17 20:00:46 vincentdarley Exp $
*/
#include <dl.h>
@@ -47,17 +47,11 @@
*/
int
-TclpLoadFile(interp, pathPtr, sym1, sym2, proc1Ptr, proc2Ptr,
- clientDataPtr, unloadProcPtr)
+TclpDlopen(interp, pathPtr, loadHandle, unloadProcPtr)
Tcl_Interp *interp; /* Used for error reporting. */
Tcl_Obj *pathPtr; /* Name of the file containing the desired
- * code. */
- CONST char *sym1, *sym2; /* Names of two procedures to look up in
- * the file's symbol table. */
- Tcl_PackageInitProc **proc1Ptr, **proc2Ptr;
- /* Where to return the addresses corresponding
- * to sym1 and sym2. */
- ClientData *clientDataPtr; /* Filled with token for dynamically loaded
+ * code (UTF-8). */
+ TclLoadHandle *loadHandle; /* Filled with token for dynamically loaded
* file which will be passed back to
* (*unloadProcPtr)() to unload the file. */
Tcl_FSUnloadFileProc **unloadProcPtr;
@@ -66,7 +60,6 @@ TclpLoadFile(interp, pathPtr, sym1, sym2, proc1Ptr, proc2Ptr,
* this file. */
{
shl_t handle;
- Tcl_DString newName;
char *fileName = Tcl_GetString(pathPtr);
/*
@@ -87,38 +80,38 @@ TclpLoadFile(interp, pathPtr, sym1, sym2, proc1Ptr, proc2Ptr,
"\": ", Tcl_PosixError(interp), (char *) NULL);
return TCL_ERROR;
}
- *clientDataPtr = (ClientData) handle;
-
+ *loadHandle = (TclLoadHandle) handle;
+ *unloadProcPtr = &TclpUnloadFile;
+ return TCL_OK;
+}
+
+Tcl_PackageInitProc*
+TclpFindSymbol(interp, loadHandle, symbol)
+ Tcl_Interp *interp;
+ TclLoadHandle loadHandle;
+ CONST char *symbol;
+{
+ Tcl_DString newName;
+ Tcl_PackageInitProc *proc=NULL;
+ shl_t handle = (shl_t)loadHandle;
/*
* Some versions of the HP system software still use "_" at the
* beginning of exported symbols while others don't; try both
* forms of each name.
*/
- if (shl_findsym(&handle, sym1, (short) TYPE_PROCEDURE, (void *) proc1Ptr)
+ if (shl_findsym(&handle, symbol, (short) TYPE_PROCEDURE, (void *) &proc)
!= 0) {
Tcl_DStringInit(&newName);
Tcl_DStringAppend(&newName, "_", 1);
- Tcl_DStringAppend(&newName, sym1, -1);
+ Tcl_DStringAppend(&newName, symbol, -1);
if (shl_findsym(&handle, Tcl_DStringValue(&newName),
- (short) TYPE_PROCEDURE, (void *) proc1Ptr) != 0) {
- *proc1Ptr = NULL;
+ (short) TYPE_PROCEDURE, (void *) &proc) != 0) {
+ proc = NULL;
}
Tcl_DStringFree(&newName);
}
- if (shl_findsym(&handle, sym2, (short) TYPE_PROCEDURE, (void *) proc2Ptr)
- != 0) {
- Tcl_DStringInit(&newName);
- Tcl_DStringAppend(&newName, "_", 1);
- Tcl_DStringAppend(&newName, sym2, -1);
- if (shl_findsym(&handle, Tcl_DStringValue(&newName),
- (short) TYPE_PROCEDURE, (void *) proc2Ptr) != 0) {
- *proc2Ptr = NULL;
- }
- Tcl_DStringFree(&newName);
- }
- *unloadProcPtr = &TclpUnloadFile;
- return TCL_OK;
+ return proc;
}
/*
diff --git a/win/tclWinLoad.c b/win/tclWinLoad.c
index 8e23490..48a6c3b 100644
--- a/win/tclWinLoad.c
+++ b/win/tclWinLoad.c
@@ -10,7 +10,7 @@
* See the file "license.terms" for information on usage and redistribution
* of this file, and for a DISCLAIMER OF ALL WARRANTIES.
*
- * RCS: @(#) $Id: tclWinLoad.c,v 1.11 2002/01/25 21:36:10 dgp Exp $
+ * RCS: @(#) $Id: tclWinLoad.c,v 1.12 2002/07/17 20:00:46 vincentdarley Exp $
*/
#include "tclWinInt.h"
@@ -36,17 +36,11 @@
*/
int
-TclpLoadFile(interp, pathPtr, sym1, sym2, proc1Ptr, proc2Ptr,
- clientDataPtr, unloadProcPtr)
+TclpDlopen(interp, pathPtr, loadHandle, unloadProcPtr)
Tcl_Interp *interp; /* Used for error reporting. */
Tcl_Obj *pathPtr; /* Name of the file containing the desired
- * code. */
- CONST char *sym1, *sym2; /* Names of two procedures to look up in
- * the file's symbol table. */
- Tcl_PackageInitProc **proc1Ptr, **proc2Ptr;
- /* Where to return the addresses corresponding
- * to sym1 and sym2. */
- ClientData *clientDataPtr; /* Filled with token for dynamically loaded
+ * code (UTF-8). */
+ TclLoadHandle *loadHandle; /* Filled with token for dynamically loaded
* file which will be passed back to
* (*unloadProcPtr)() to unload the file. */
Tcl_FSUnloadFileProc **unloadProcPtr;
@@ -63,7 +57,7 @@ TclpLoadFile(interp, pathPtr, sym1, sym2, proc1Ptr, proc2Ptr,
handle = (*tclWinProcs->loadLibraryProc)(nativeName);
Tcl_DStringFree(&ds);
- *clientDataPtr = (ClientData) handle;
+ *loadHandle = (TclLoadHandle) handle;
if (handle == NULL) {
DWORD lastError = GetLastError();
@@ -117,27 +111,33 @@ TclpLoadFile(interp, pathPtr, sym1, sym2, proc1Ptr, proc2Ptr,
} else {
*unloadProcPtr = &TclpUnloadFile;
}
+ return TCL_OK;
+}
+
+Tcl_PackageInitProc*
+TclpFindSymbol(interp, loadHandle, symbol)
+ Tcl_Interp *interp;
+ TclLoadHandle loadHandle;
+ CONST char *symbol;
+{
+ Tcl_PackageInitProc *proc = NULL;
+ HINSTANCE handle = (HINSTANCE)loadHandle;
+
/*
* For each symbol, check for both Symbol and _Symbol, since Borland
* generates C symbols with a leading '_' by default.
*/
- *proc1Ptr = (Tcl_PackageInitProc *) GetProcAddress(handle, sym1);
- if (*proc1Ptr == NULL) {
+ proc = (Tcl_PackageInitProc *) GetProcAddress(handle, symbol);
+ if (proc == NULL) {
+ Tcl_DString ds;
+ Tcl_DStringInit(&ds);
Tcl_DStringAppend(&ds, "_", 1);
- sym1 = Tcl_DStringAppend(&ds, sym1, -1);
- *proc1Ptr = (Tcl_PackageInitProc *) GetProcAddress(handle, sym1);
+ symbol = Tcl_DStringAppend(&ds, symbol, -1);
+ proc = (Tcl_PackageInitProc *) GetProcAddress(handle, symbol);
Tcl_DStringFree(&ds);
}
-
- *proc2Ptr = (Tcl_PackageInitProc *) GetProcAddress(handle, sym2);
- if (*proc2Ptr == NULL) {
- Tcl_DStringAppend(&ds, "_", 1);
- sym2 = Tcl_DStringAppend(&ds, sym2, -1);
- *proc2Ptr = (Tcl_PackageInitProc *) GetProcAddress(handle, sym2);
- Tcl_DStringFree(&ds);
- }
- return TCL_OK;
+ return proc;
}
/*