aboutsummaryrefslogtreecommitdiff
path: root/jim-package.c
diff options
context:
space:
mode:
authorSteve Bennett <steveb@workware.net.au>2014-01-06 23:26:56 +1000
committerSteve Bennett <steveb@workware.net.au>2014-01-15 07:46:33 +1000
commit5f31686cb40c5b84638dbb5ffe1ad327440e1903 (patch)
tree2f23c8d65e0044fdbb46b6362f95d35a924310e0 /jim-package.c
parent6ed588b21d8e644c21bb6e7fce602cd90dae7343 (diff)
downloadjimtcl-5f31686cb40c5b84638dbb5ffe1ad327440e1903.zip
jimtcl-5f31686cb40c5b84638dbb5ffe1ad327440e1903.tar.gz
jimtcl-5f31686cb40c5b84638dbb5ffe1ad327440e1903.tar.bz2
package: simplification/code cleanup
Also, packages can once again set a version != "1.0", but the version is ignored for "package require" Signed-off-by: Steve Bennett <steveb@workware.net.au>
Diffstat (limited to 'jim-package.c')
-rw-r--r--jim-package.c129
1 files changed, 57 insertions, 72 deletions
diff --git a/jim-package.c b/jim-package.c
index d9f50a9..3dc9d54 100644
--- a/jim-package.c
+++ b/jim-package.c
@@ -9,7 +9,7 @@
#define R_OK 4
#endif
-/* All packages have a fixed, dummy version */
+/* All Tcl packages have a fixed, dummy version */
static const char *package_version_1 = "1.0";
/* -----------------------------------------------------------------------------
@@ -28,34 +28,38 @@ int Jim_PackageProvide(Jim_Interp *interp, const char *name, const char *ver, in
}
return JIM_ERR;
}
- if (he) {
- Jim_DeleteHashEntry(&interp->packages, name);
- }
- Jim_AddHashEntry(&interp->packages, name, (char *)ver);
+ Jim_ReplaceHashEntry(&interp->packages, name, (char *)ver);
return JIM_OK;
}
-static char *JimFindPackage(Jim_Interp *interp, char **prefixes, int prefixc, const char *pkgName)
+/**
+ * Searches along a of paths for the given package.
+ *
+ * Returns the allocated path to the package file if found,
+ * or NULL if not found.
+ */
+static char *JimFindPackage(Jim_Interp *interp, Jim_Obj *prefixListObj, const char *pkgName)
{
int i;
char *buf = Jim_Alloc(JIM_PATH_LEN);
+ int prefixc = Jim_ListLength(interp, prefixListObj);
for (i = 0; i < prefixc; i++) {
- if (prefixes[i] == NULL)
- continue;
+ Jim_Obj *prefixObjPtr = Jim_ListGetIndex(interp, prefixListObj, i);
+ const char *prefix = Jim_String(prefixObjPtr);
/* Loadable modules are tried first */
#ifdef jim_ext_load
- snprintf(buf, JIM_PATH_LEN, "%s/%s.so", prefixes[i], pkgName);
+ snprintf(buf, JIM_PATH_LEN, "%s/%s.so", prefix, pkgName);
if (access(buf, R_OK) == 0) {
return buf;
}
#endif
- if (strcmp(prefixes[i], ".") == 0) {
+ if (strcmp(prefix, ".") == 0) {
snprintf(buf, JIM_PATH_LEN, "%s.tcl", pkgName);
}
else {
- snprintf(buf, JIM_PATH_LEN, "%s/%s.tcl", prefixes[i], pkgName);
+ snprintf(buf, JIM_PATH_LEN, "%s/%s.tcl", prefix, pkgName);
}
if (access(buf, R_OK) == 0) {
@@ -71,63 +75,45 @@ static char *JimFindPackage(Jim_Interp *interp, char **prefixes, int prefixc, co
* JIM_OK is returned, otherwise JIM_ERR is returned. */
static int JimLoadPackage(Jim_Interp *interp, const char *name, int flags)
{
- Jim_Obj *libPathObjPtr;
- char **prefixes, *path;
- int prefixc, i, retCode = JIM_ERR;
-
- libPathObjPtr = Jim_GetGlobalVariableStr(interp, JIM_LIBPATH, JIM_NONE);
- if (libPathObjPtr == NULL) {
- prefixc = 0;
- libPathObjPtr = NULL;
- }
- else {
- Jim_IncrRefCount(libPathObjPtr);
- prefixc = Jim_ListLength(interp, libPathObjPtr);
- }
-
- prefixes = Jim_Alloc(sizeof(char *) * prefixc);
- for (i = 0; i < prefixc; i++) {
- Jim_Obj *prefixObjPtr;
-
- if (Jim_ListIndex(interp, libPathObjPtr, i, &prefixObjPtr, JIM_NONE) != JIM_OK) {
- prefixes[i] = NULL;
- continue;
- }
- prefixes[i] = Jim_StrDup(Jim_String(prefixObjPtr));
- }
-
- /* Scan every directory for the the first match */
- path = JimFindPackage(interp, prefixes, prefixc, name);
- if (path != NULL) {
- char *p = strrchr(path, '.');
-
- /* Note: Even if the file fails to load, we consider the package loaded.
- * This prevents issues with recursion.
- * Use a dummy version of "" to signify this case.
- */
- Jim_PackageProvide(interp, name, "", 0);
-
- /* Try to load/source it */
- if (p && strcmp(p, ".tcl") == 0) {
- retCode = Jim_EvalFileGlobal(interp, path);
- }
+ int retCode = JIM_ERR;
+ Jim_Obj *libPathObjPtr = Jim_GetGlobalVariableStr(interp, JIM_LIBPATH, JIM_NONE);
+ if (libPathObjPtr) {
+ char *path;
+
+ /* Scan every directory for the the first match */
+ path = JimFindPackage(interp, libPathObjPtr, name);
+ if (path) {
+ const char *p;
+
+ /* Note: Even if the file fails to load, we consider the package loaded.
+ * This prevents issues with recursion.
+ * Use a dummy version of "" to signify this case.
+ */
+ Jim_PackageProvide(interp, name, "", 0);
+
+ /* Try to load/source it */
+ p = strrchr(path, '.');
+
+ if (p && strcmp(p, ".tcl") == 0) {
+ Jim_IncrRefCount(libPathObjPtr);
+ retCode = Jim_EvalFileGlobal(interp, path);
+ Jim_DecrRefCount(interp, libPathObjPtr);
+ }
#ifdef jim_ext_load
- else {
- retCode = Jim_LoadLibrary(interp, path);
- }
+ else {
+ retCode = Jim_LoadLibrary(interp, path);
+ }
#endif
- if (retCode != JIM_OK) {
- /* Upon failure, remove the dummy entry */
- Jim_DeleteHashEntry(&interp->packages, name);
+ if (retCode != JIM_OK) {
+ /* Upon failure, remove the dummy entry */
+ Jim_DeleteHashEntry(&interp->packages, name);
+ }
+ Jim_Free(path);
}
- Jim_Free(path);
+
+ return retCode;
}
- for (i = 0; i < prefixc; i++)
- Jim_Free(prefixes[i]);
- Jim_Free(prefixes);
- if (libPathObjPtr)
- Jim_DecrRefCount(interp, libPathObjPtr);
- return retCode;
+ return JIM_ERR;
}
int Jim_PackageRequire(Jim_Interp *interp, const char *name, int flags)
@@ -135,7 +121,7 @@ int Jim_PackageRequire(Jim_Interp *interp, const char *name, int flags)
Jim_HashEntry *he;
/* Start with an empty error string */
- Jim_SetResultString(interp, "", 0);
+ Jim_SetEmptyResult(interp);
he = Jim_FindHashEntry(&interp->packages, name);
if (he == NULL) {
@@ -143,17 +129,15 @@ int Jim_PackageRequire(Jim_Interp *interp, const char *name, int flags)
int retcode = JimLoadPackage(interp, name, flags);
if (retcode != JIM_OK) {
if (flags & JIM_ERRMSG) {
- int len;
-
- Jim_GetString(Jim_GetResult(interp), &len);
+ int len = Jim_Length(Jim_GetResult(interp));
Jim_SetResultFormatted(interp, "%#s%sCan't load package %s",
Jim_GetResult(interp), len ? "\n" : "", name);
}
return retcode;
}
- /* In case the package did no 'package provide' */
- Jim_PackageProvide(interp, name, "1.0", 0);
+ /* In case the package did not 'package provide' */
+ Jim_PackageProvide(interp, name, package_version_1, 0);
/* Now it must exist */
he = Jim_FindHashEntry(&interp->packages, name);
@@ -173,13 +157,14 @@ int Jim_PackageRequire(Jim_Interp *interp, const char *name, int flags)
* The package must not already be provided in the interpreter.
*
* Results:
- * Returns JIM_OK and sets results as "1.0" (the given version is ignored)
+ * Returns JIM_OK and sets the results to the version (defaults to "1.0")
*
*----------------------------------------------------------------------
*/
static int package_cmd_provide(Jim_Interp *interp, int argc, Jim_Obj *const *argv)
{
- return Jim_PackageProvide(interp, Jim_String(argv[0]), package_version_1, JIM_ERRMSG);
+ return Jim_PackageProvide(interp, Jim_String(argv[0]),
+ argc > 1 ? Jim_String(argv[1]) : package_version_1, JIM_ERRMSG);
}
/*