diff options
author | Steve Bennett <steveb@workware.net.au> | 2009-07-27 10:28:21 +1000 |
---|---|---|
committer | Steve Bennett <steveb@workware.net.au> | 2010-10-15 10:11:01 +1000 |
commit | 7f683b890f5575999bfae65988079c227735822d (patch) | |
tree | 4e9399f3466f1c1a38e93a984f0d42a66855b5d9 /jim-load.c | |
parent | 0423aa4420d853a8f81a0579910d7f39b720f851 (diff) | |
download | jimtcl-7f683b890f5575999bfae65988079c227735822d.zip jimtcl-7f683b890f5575999bfae65988079c227735822d.tar.gz jimtcl-7f683b890f5575999bfae65988079c227735822d.tar.bz2 |
Split package and load out of jim.c
Diffstat (limited to 'jim-load.c')
-rw-r--r-- | jim-load.c | 118 |
1 files changed, 118 insertions, 0 deletions
diff --git a/jim-load.c b/jim-load.c new file mode 100644 index 0000000..8572405 --- /dev/null +++ b/jim-load.c @@ -0,0 +1,118 @@ +#include <jim.h> + +/* ----------------------------------------------------------------------------- + * Dynamic libraries support (WIN32 not supported) + * ---------------------------------------------------------------------------*/ + +#ifdef JIM_DYNLIB +#ifdef WIN32 +#define RTLD_LAZY 0 +void * dlopen(const char *path, int mode) +{ + JIM_NOTUSED(mode); + + return (void *)LoadLibraryA(path); +} +int dlclose(void *handle) +{ + FreeLibrary((HANDLE)handle); + return 0; +} +void *dlsym(void *handle, const char *symbol) +{ + return GetProcAddress((HMODULE)handle, symbol); +} +static char win32_dlerror_string[121]; +const char *dlerror(void) +{ + FormatMessageA(FORMAT_MESSAGE_FROM_SYSTEM, NULL, GetLastError(), + LANG_NEUTRAL, win32_dlerror_string, 120, NULL); + return win32_dlerror_string; +} +#endif /* WIN32 */ + +int Jim_LoadLibrary(Jim_Interp *interp, const char *pathName) +{ + Jim_Obj *libPathObjPtr; + int prefixc, i; + void *handle; + int (*onload)(Jim_Interp *interp); + + libPathObjPtr = Jim_GetGlobalVariableStr(interp, "jim_libpath", JIM_NONE); + if (libPathObjPtr == NULL) { + prefixc = 0; + libPathObjPtr = NULL; + } else { + Jim_IncrRefCount(libPathObjPtr); + Jim_ListLength(interp, libPathObjPtr, &prefixc); + } + + for (i = -1; i < prefixc; i++) { + if (i < 0) { + handle = dlopen(pathName, RTLD_LAZY); + } else { + FILE *fp; + char buf[JIM_PATH_LEN]; + const char *prefix; + int prefixlen; + Jim_Obj *prefixObjPtr; + + buf[0] = '\0'; + if (Jim_ListIndex(interp, libPathObjPtr, i, + &prefixObjPtr, JIM_NONE) != JIM_OK) + continue; + prefix = Jim_GetString(prefixObjPtr, &prefixlen); + if (prefixlen+strlen(pathName)+1 >= JIM_PATH_LEN) + continue; + if (*pathName == '/') { + strcpy(buf, pathName); + } + else if (prefixlen && prefix[prefixlen-1] == '/') + sprintf(buf, "%s%s", prefix, pathName); + else + sprintf(buf, "%s/%s", prefix, pathName); + fp = fopen(buf, "r"); + if (fp == NULL) + continue; + fclose(fp); + handle = dlopen(buf, RTLD_LAZY); + } + if (handle == NULL) { + Jim_SetResult(interp, Jim_NewEmptyStringObj(interp)); + Jim_AppendStrings(interp, Jim_GetResult(interp), + "error loading extension \"", pathName, + "\": ", dlerror(), NULL); + if (i < 0) + continue; + goto err; + } + if ((onload = dlsym(handle, "Jim_OnLoad")) == NULL) { + Jim_SetResultString(interp, + "No Jim_OnLoad symbol found on extension", -1); + goto err; + } + if (onload(interp) == JIM_ERR) { + dlclose(handle); + goto err; + } + Jim_SetEmptyResult(interp); + if (libPathObjPtr != NULL) + Jim_DecrRefCount(interp, libPathObjPtr); + return JIM_OK; + } +err: + if (libPathObjPtr != NULL) + Jim_DecrRefCount(interp, libPathObjPtr); + return JIM_ERR; +} +#else /* JIM_DYNLIB */ +int Jim_LoadLibrary(Jim_Interp *interp, const char *pathName) +{ + JIM_NOTUSED(interp); + JIM_NOTUSED(pathName); + + Jim_SetResultString(interp, "the Jim binary has no support for [load]", -1); + return JIM_ERR; +} +#endif/* JIM_DYNLIB */ + |