Add basic support for [format %b]
[jimtcl.git] / jim-load.c
blobf9255dce73cd3111ff7b0fb0f2cddabaad2b8663
1 #include <string.h>
3 #include "jimautoconf.h"
4 #include <jim.h>
6 /* -----------------------------------------------------------------------------
7 * Dynamic libraries support (WIN32 not supported)
8 * ---------------------------------------------------------------------------*/
10 #if defined(HAVE_DLOPEN) || defined(HAVE_DLOPEN_COMPAT)
12 #ifdef HAVE_DLFCN_H
13 #include <dlfcn.h>
14 #endif
16 #ifndef RTLD_NOW
17 #define RTLD_NOW 0
18 #endif
19 #ifndef RTLD_LOCAL
20 #define RTLD_LOCAL 0
21 #endif
23 /**
24 * Note that Jim_LoadLibrary() requires a path to an existing file.
26 * If it is necessary to search JIM_LIBPATH, use Jim_PackageRequire() instead.
28 int Jim_LoadLibrary(Jim_Interp *interp, const char *pathName)
30 void *handle = dlopen(pathName, RTLD_NOW | RTLD_LOCAL);
31 if (handle == NULL) {
32 Jim_SetResultFormatted(interp, "error loading extension \"%s\": %s", pathName,
33 dlerror());
35 else {
36 /* We use a unique init symbol depending on the extension name.
37 * This is done for compatibility between static and dynamic extensions.
38 * For extension readline.so, the init symbol is "Jim_readlineInit"
40 const char *pt;
41 const char *pkgname;
42 int pkgnamelen;
43 char initsym[40];
44 typedef int jim_module_init_func_type(Jim_Interp *);
45 jim_module_init_func_type *onload;
47 pt = strrchr(pathName, '/');
48 if (pt) {
49 pkgname = pt + 1;
51 else {
52 pkgname = pathName;
54 pt = strchr(pkgname, '.');
55 if (pt) {
56 pkgnamelen = pt - pkgname;
58 else {
59 pkgnamelen = strlen(pkgname);
61 snprintf(initsym, sizeof(initsym), "Jim_%.*sInit", pkgnamelen, pkgname);
63 if ((onload = (jim_module_init_func_type *)dlsym(handle, initsym)) == NULL) {
64 Jim_SetResultFormatted(interp,
65 "No %s symbol found in extension %s", initsym, pathName);
67 else if (onload(interp) != JIM_ERR) {
68 /* Add this handle to the stack of handles to be freed */
69 if (!interp->loadHandles) {
70 interp->loadHandles = Jim_Alloc(sizeof(*interp->loadHandles));
71 Jim_InitStack(interp->loadHandles);
73 Jim_StackPush(interp->loadHandles, handle);
75 Jim_SetEmptyResult(interp);
77 return JIM_OK;
80 if (handle) {
81 dlclose(handle);
83 return JIM_ERR;
86 static void JimFreeOneLoadHandle(void *handle)
88 dlclose(handle);
91 void Jim_FreeLoadHandles(Jim_Interp *interp)
93 if (interp->loadHandles) {
94 Jim_FreeStackElements(interp->loadHandles, JimFreeOneLoadHandle);
95 Jim_Free(interp->loadHandles);
99 #else /* JIM_DYNLIB */
100 int Jim_LoadLibrary(Jim_Interp *interp, const char *pathName)
102 JIM_NOTUSED(interp);
103 JIM_NOTUSED(pathName);
105 Jim_SetResultString(interp, "the Jim binary has no support for [load]", -1);
106 return JIM_ERR;
109 void Jim_FreeLoadHandles(Jim_Interp *interp)
112 #endif /* JIM_DYNLIB */
114 /* [load] */
115 static int Jim_LoadCoreCommand(Jim_Interp *interp, int argc, Jim_Obj *const *argv)
117 if (argc < 2) {
118 Jim_WrongNumArgs(interp, 1, argv, "libaryFile");
119 return JIM_ERR;
121 return Jim_LoadLibrary(interp, Jim_String(argv[1]));
124 int Jim_loadInit(Jim_Interp *interp)
126 Jim_CreateCommand(interp, "load", Jim_LoadCoreCommand, NULL, NULL);
127 return JIM_OK;