diff options
-rw-r--r-- | Tcl_shipped.html | 21 | ||||
-rw-r--r-- | jim-load.c | 125 | ||||
-rw-r--r-- | jim_tcl.txt | 22 |
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>
@@ -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'. |