aboutsummaryrefslogtreecommitdiff
path: root/jim-load.c
diff options
context:
space:
mode:
authorSteve Bennett <steveb@workware.net.au>2009-07-27 10:28:21 +1000
committerSteve Bennett <steveb@workware.net.au>2010-10-15 10:11:01 +1000
commit7f683b890f5575999bfae65988079c227735822d (patch)
tree4e9399f3466f1c1a38e93a984f0d42a66855b5d9 /jim-load.c
parent0423aa4420d853a8f81a0579910d7f39b720f851 (diff)
downloadjimtcl-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.c118
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 */
+