aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Tcl_shipped.html21
-rw-r--r--jim-load.c125
-rw-r--r--jim_tcl.txt22
3 files changed, 76 insertions, 92 deletions
diff --git a/Tcl_shipped.html b/Tcl_shipped.html
index 158111a..05dcc0f 100644
--- a/Tcl_shipped.html
+++ b/Tcl_shipped.html
@@ -4151,6 +4151,15 @@ jim> lmap a {1 2 3} b {A B C} {list $a $b}
If the body invokes <em>break</em>, the loop ends and no more values are added.</p></div>
</div>
<div class="sect2">
+<h3 id="_load">load</h3>
+<div class="paragraph"><p><tt><strong>load</strong> <em>filename</em></tt></p></div>
+<div class="paragraph"><p>Loads the dynamic extension, <strong>filename</strong>. Generally the filename should have
+the extension <em>.so</em>. The initialisation function for the module must be based
+on the name of the file. For example loading <tt>dir/hwaccess.so</tt> will invoke
+the initialisation function, <tt>Jim_hwaccessInit</tt>. Normally the <em>load</em> command
+should not be used directly. Instead it is invoked automatically by <em>package require</em>.</p></div>
+</div>
+<div class="sect2">
<h3 id="_lrange">lrange</h3>
<div class="paragraph"><p><tt><strong>lrange</strong> <em>list first last</em></tt></p></div>
<div class="paragraph"><p><strong>List</strong> must be a valid Tcl list. This command will return a new
@@ -4404,8 +4413,14 @@ If no version is specified, <em>1.0</em> is used.</p></div>
as the first statement, although it is not required.</p></div>
<div class="paragraph"><p><tt><strong>package require</strong> <em>name ?version?</em>*</tt></p></div>
<div class="paragraph"><p>Searches for the package with the given <strong>name</strong> by examining each path
-in <em>$::auto_path</em> and trying to load <em>$path/$name.tcl</em>.</p></div>
-<div class="paragraph"><p>If either file exists, it is loaded with <em>source</em>.</p></div>
+in <em>$::auto_path</em> and trying to load <em>$path/$name.so</em> as a dynamic extension,
+or <em>$path/$name.tcl</em> as a script package.</p></div>
+<div class="paragraph"><p>The first such file which is found is considered to provide the the package.
+(The version number is ignored).</p></div>
+<div class="paragraph"><p>If <em>$name.so</em> exists, it is loaded with the <em>load</em> command,
+otherwise if <em>$name.tcl</em> exists it is loaded with the <em>source</em> command.</p></div>
+<div class="paragraph"><p>If <em>load</em> or <em>source</em> fails, <em>package require</em> will fail immediately.
+No further attempt will be made to locate the file.</p></div>
<div class="paragraph"><p>Typically <em>$::auto_path</em> contains the paths <em>.</em> and <em>/lib/jim</em>.</p></div>
</div>
<div class="sect2">
@@ -6443,7 +6458,7 @@ official policies, either expressed or implied, of the Jim Tcl Project.</tt></pr
<div id="footnotes"><hr /></div>
<div id="footer">
<div id="footer-text">
-Last updated 2010-10-30 18:17:58 EST
+Last updated 2010-11-03 16:14:30 EST
</div>
</div>
</body>
diff --git a/jim-load.c b/jim-load.c
index 772ddce..8d4e6c2 100644
--- a/jim-load.c
+++ b/jim-load.c
@@ -11,106 +11,57 @@
#include <dlfcn.h>
#endif
+/**
+ * Note that Jim_LoadLibrary() requires a path to an existing file.
+ *
+ * If it is necessary to search JIM_LIBPATH, use Jim_PackageRequire() instead.
+ */
int Jim_LoadLibrary(Jim_Interp *interp, const char *pathName)
{
- Jim_Obj *libPathObjPtr;
- int prefixc, i;
- void *handle;
- int (*onload) (Jim_Interp *);
-
- libPathObjPtr = Jim_GetGlobalVariableStr(interp, JIM_LIBPATH, JIM_NONE);
- if (libPathObjPtr == NULL) {
- prefixc = 0;
- libPathObjPtr = NULL;
+ void *handle = dlopen(pathName, RTLD_LAZY);
+ if (handle == NULL) {
+ Jim_SetResultFormatted(interp, "error loading extension \"%s\": %s", pathName,
+ dlerror());
}
else {
- Jim_IncrRefCount(libPathObjPtr);
- prefixc = Jim_ListLength(interp, libPathObjPtr);
- }
+ /* We use a unique init symbol depending on the extension name.
+ * This is done for compatibility between static and dynamic extensions.
+ * For extension readline.so, the init symbol is "Jim_readlineInit"
+ */
+ const char *pt;
+ const char *pkgname;
+ int pkgnamelen;
+ char initsym[40];
+ int (*onload) (Jim_Interp *);
- for (i = -1; i < prefixc; i++) {
- if (i < 0) {
- handle = dlopen(pathName, RTLD_LAZY);
+ pt = strrchr(pathName, '/');
+ if (pt) {
+ pkgname = pt + 1;
}
else {
- FILE *fp;
- /* XXX: Move off stack */
- 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);
+ pkgname = pathName;
}
- if (handle == NULL) {
- Jim_SetResultFormatted(interp, "error loading extension \"%s\": %s", pathName,
- dlerror());
- if (i < 0)
- continue;
- goto err;
+ pt = strchr(pkgname, '.');
+ if (pt) {
+ pkgnamelen = pt - pkgname;
}
+ else {
+ pkgnamelen = strlen(pkgname);
+ }
+ snprintf(initsym, sizeof(initsym), "Jim_%.*sInit", pkgnamelen, pkgname);
- /* Now, we use a unique init symbol depending on the extension name.
- * This is done for compatibility between static and dynamic extensions.
- * For extension readline.so, the init symbol is "Jim_readlineInit"
- */
- {
- const char *pt;
- const char *pkgname;
- int pkgnamelen;
- char initsym[50];
-
- pt = strrchr(pathName, '/');
- if (pt) {
- pkgname = pt + 1;
- }
- else {
- pkgname = pathName;
- }
- pt = strchr(pkgname, '.');
- if (pt) {
- pkgnamelen = pt - pkgname;
- }
- else {
- pkgnamelen = strlen(pkgname);
- }
- snprintf(initsym, sizeof(initsym), "Jim_%.*sInit", pkgnamelen, pkgname);
-
- if ((onload = dlsym(handle, initsym)) == NULL) {
- Jim_SetResultFormatted(interp,
- "No %s symbol found in extension %s", initsym, pathName);
- goto err;
- }
+ if ((onload = dlsym(handle, initsym)) == NULL) {
+ Jim_SetResultFormatted(interp,
+ "No %s symbol found in extension %s", initsym, pathName);
}
- if (onload(interp) == JIM_ERR) {
- dlclose(handle);
- goto err;
+ else if (onload(interp) != JIM_ERR) {
+ Jim_SetEmptyResult(interp);
+ return JIM_OK;
}
- Jim_SetEmptyResult(interp);
- if (libPathObjPtr != NULL)
- Jim_DecrRefCount(interp, libPathObjPtr);
- return JIM_OK;
}
- err:
- if (libPathObjPtr != NULL)
- Jim_DecrRefCount(interp, libPathObjPtr);
+ if (handle) {
+ dlclose(handle);
+ }
return JIM_ERR;
}
#else /* JIM_DYNLIB */
diff --git a/jim_tcl.txt b/jim_tcl.txt
index cd993f4..dfe6b4c 100644
--- a/jim_tcl.txt
+++ b/jim_tcl.txt
@@ -2697,6 +2697,16 @@ For example:
If the body invokes 'continue', no value is added for this iteration.
If the body invokes 'break', the loop ends and no more values are added.
+load
+~~~~
++*load* 'filename'+
+
+Loads the dynamic extension, *filename*. Generally the filename should have
+the extension '.so'. The initialisation function for the module must be based
+on the name of the file. For example loading +dir/hwaccess.so+ will invoke
+the initialisation function, +Jim_hwaccessInit+. Normally the 'load' command
+should not be used directly. Instead it is invoked automatically by 'package require'.
+
lrange
~~~~~~
+*lrange* 'list first last'+
@@ -2908,9 +2918,17 @@ as the first statement, although it is not required.
+*package require* 'name ?version?'*+
Searches for the package with the given *name* by examining each path
-in '$::auto_path' and trying to load '$path/$name.tcl'.
+in '$::auto_path' and trying to load '$path/$name.so' as a dynamic extension,
+or '$path/$name.tcl' as a script package.
+
+The first such file which is found is considered to provide the the package.
+(The version number is ignored).
+
+If '$name.so' exists, it is loaded with the 'load' command,
+otherwise if '$name.tcl' exists it is loaded with the 'source' command.
-If either file exists, it is loaded with 'source'.
+If 'load' or 'source' fails, 'package require' will fail immediately.
+No further attempt will be made to locate the file.
Typically '$::auto_path' contains the paths '.' and '/lib/jim'.