aboutsummaryrefslogtreecommitdiff
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
parent0423aa4420d853a8f81a0579910d7f39b720f851 (diff)
downloadjimtcl-7f683b890f5575999bfae65988079c227735822d.zip
jimtcl-7f683b890f5575999bfae65988079c227735822d.tar.gz
jimtcl-7f683b890f5575999bfae65988079c227735822d.tar.bz2
Split package and load out of jim.c
-rw-r--r--jim-load.c118
-rw-r--r--jim-package.c349
-rw-r--r--jim.c462
-rw-r--r--jim.h2
-rw-r--r--jimsh.c6
5 files changed, 476 insertions, 461 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 */
+
diff --git a/jim-package.c b/jim-package.c
new file mode 100644
index 0000000..3b5fca8
--- /dev/null
+++ b/jim-package.c
@@ -0,0 +1,349 @@
+#include <string.h>
+
+#include <jim.h>
+
+
+#ifndef JIM_ANSIC
+
+#ifndef WIN32
+# include <sys/types.h>
+# include <dirent.h>
+#else
+# include <io.h>
+/* Posix dirent.h compatiblity layer for WIN32.
+ * Copyright Kevlin Henney, 1997, 2003. All rights reserved.
+ * Copyright Salvatore Sanfilippo ,2005.
+ *
+ * Permission to use, copy, modify, and distribute this software and its
+ * documentation for any purpose is hereby granted without fee, provided
+ * that this copyright and permissions notice appear in all copies and
+ * derivatives.
+ *
+ * This software is supplied "as is" without express or implied warranty.
+ * This software was modified by Salvatore Sanfilippo for the Jim Interpreter.
+ */
+
+struct dirent {
+ char *d_name;
+};
+
+typedef struct DIR {
+ long handle; /* -1 for failed rewind */
+ struct _finddata_t info;
+ struct dirent result; /* d_name null iff first time */
+ char *name; /* null-terminated char string */
+} DIR;
+
+DIR *opendir(const char *name)
+{
+ DIR *dir = 0;
+
+ if(name && name[0]) {
+ size_t base_length = strlen(name);
+ const char *all = /* search pattern must end with suitable wildcard */
+ strchr("/\\", name[base_length - 1]) ? "*" : "/*";
+
+ if((dir = (DIR *) Jim_Alloc(sizeof *dir)) != 0 &&
+ (dir->name = (char *) Jim_Alloc(base_length + strlen(all) + 1)) != 0)
+ {
+ strcat(strcpy(dir->name, name), all);
+
+ if((dir->handle = (long) _findfirst(dir->name, &dir->info)) != -1)
+ dir->result.d_name = 0;
+ else { /* rollback */
+ Jim_Free(dir->name);
+ Jim_Free(dir);
+ dir = 0;
+ }
+ } else { /* rollback */
+ Jim_Free(dir);
+ dir = 0;
+ errno = ENOMEM;
+ }
+ } else {
+ errno = EINVAL;
+ }
+ return dir;
+}
+
+int closedir(DIR *dir)
+{
+ int result = -1;
+
+ if(dir) {
+ if(dir->handle != -1)
+ result = _findclose(dir->handle);
+ Jim_Free(dir->name);
+ Jim_Free(dir);
+ }
+ if(result == -1) /* map all errors to EBADF */
+ errno = EBADF;
+ return result;
+}
+
+struct dirent *readdir(DIR *dir)
+{
+ struct dirent *result = 0;
+
+ if(dir && dir->handle != -1) {
+ if(!dir->result.d_name || _findnext(dir->handle, &dir->info) != -1) {
+ result = &dir->result;
+ result->d_name = dir->info.name;
+ }
+ } else {
+ errno = EBADF;
+ }
+ return result;
+}
+
+#endif /* WIN32 */
+
+/* -----------------------------------------------------------------------------
+ * Packages handling
+ * ---------------------------------------------------------------------------*/
+
+#define JIM_PKG_ANY_VERSION -1
+
+/* Convert a string of the type "1.2" into an integer.
+ * MAJOR.MINOR is converted as MAJOR*100+MINOR, so "1.2" is converted
+ * to the integer with value 102 */
+static int JimPackageVersionToInt(Jim_Interp *interp, const char *v,
+ int *intPtr, int flags)
+{
+ char *copy;
+ jim_wide major, minor;
+ char *majorStr, *minorStr, *p;
+
+ if (v[0] == '\0') {
+ *intPtr = JIM_PKG_ANY_VERSION;
+ return JIM_OK;
+ }
+
+ copy = Jim_StrDup(v);
+ p = strchr(copy, '.');
+ if (p == NULL) goto badfmt;
+ *p = '\0';
+ majorStr = copy;
+ minorStr = p+1;
+
+ if (Jim_StringToWide(majorStr, &major, 10) != JIM_OK ||
+ Jim_StringToWide(minorStr, &minor, 10) != JIM_OK)
+ goto badfmt;
+ *intPtr = (int)(major*100+minor);
+ Jim_Free(copy);
+ return JIM_OK;
+
+badfmt:
+ Jim_Free(copy);
+ if (flags & JIM_ERRMSG) {
+ Jim_SetResult(interp, Jim_NewEmptyStringObj(interp));
+ Jim_AppendStrings(interp, Jim_GetResult(interp),
+ "invalid package version '", v, "'", NULL);
+ }
+ return JIM_ERR;
+}
+
+#define JIM_MATCHVER_EXACT (1<<JIM_PRIV_FLAG_SHIFT)
+static int JimPackageMatchVersion(int needed, int actual, int flags)
+{
+ if (needed == JIM_PKG_ANY_VERSION) return 1;
+ if (flags & JIM_MATCHVER_EXACT) {
+ return needed == actual;
+ } else {
+ return needed/100 == actual/100 && (needed <= actual);
+ }
+}
+
+int Jim_PackageProvide(Jim_Interp *interp, const char *name, const char *ver,
+ int flags)
+{
+ int intVersion;
+ /* Check if the version format is ok */
+ if (JimPackageVersionToInt(interp, ver, &intVersion, JIM_ERRMSG) != JIM_OK)
+ return JIM_ERR;
+ /* If the package was already provided returns an error. */
+ if (Jim_FindHashEntry(&interp->packages, name) != NULL) {
+ if (flags & JIM_ERRMSG) {
+ Jim_SetResult(interp, Jim_NewEmptyStringObj(interp));
+ Jim_AppendStrings(interp, Jim_GetResult(interp),
+ "package '", name, "' was already provided", NULL);
+ }
+ return JIM_ERR;
+ }
+ Jim_AddHashEntry(&interp->packages, name, (char*) ver);
+ return JIM_OK;
+}
+
+static char *JimFindBestPackage(Jim_Interp *interp, char **prefixes,
+ int prefixc, const char *pkgName, int pkgVer, int flags)
+{
+ int bestVer = -1, i;
+ int pkgNameLen = strlen(pkgName);
+ char *bestPackage = NULL;
+ struct dirent *de;
+
+ for (i = 0; i < prefixc; i++) {
+ DIR *dir;
+ char buf[JIM_PATH_LEN];
+ int prefixLen;
+
+ if (prefixes[i] == NULL) continue;
+ strncpy(buf, prefixes[i], JIM_PATH_LEN);
+ buf[JIM_PATH_LEN-1] = '\0';
+ prefixLen = strlen(buf);
+ if (prefixLen && buf[prefixLen-1] == '/')
+ buf[prefixLen-1] = '\0';
+
+ if ((dir = opendir(buf)) == NULL) continue;
+ while ((de = readdir(dir)) != NULL) {
+ char *fileName = de->d_name;
+ int fileNameLen = strlen(fileName);
+
+ if (strncmp(fileName, "jim-", 4) == 0 &&
+ strncmp(fileName+4, pkgName, pkgNameLen) == 0 &&
+ *(fileName+4+pkgNameLen) == '-' &&
+ fileNameLen > 4 && /* note that this is not really useful */
+ (strncmp(fileName+fileNameLen-4, ".tcl", 4) == 0 ||
+ strncmp(fileName+fileNameLen-4, ".dll", 4) == 0 ||
+ strncmp(fileName+fileNameLen-3, ".so", 3) == 0))
+ {
+ char ver[6]; /* xx.yy<nulterm> */
+ char *p = strrchr(fileName, '.');
+ int verLen, fileVer;
+
+ verLen = p - (fileName+4+pkgNameLen+1);
+ if (verLen < 3 || verLen > 5) continue;
+ memcpy(ver, fileName+4+pkgNameLen+1, verLen);
+ ver[verLen] = '\0';
+ if (JimPackageVersionToInt(interp, ver, &fileVer, JIM_NONE)
+ != JIM_OK) continue;
+ if (JimPackageMatchVersion(pkgVer, fileVer, flags) &&
+ (bestVer == -1 || bestVer < fileVer))
+ {
+ bestVer = fileVer;
+ Jim_Free(bestPackage);
+ bestPackage = Jim_Alloc(strlen(buf)+strlen(fileName)+2);
+ sprintf(bestPackage, "%s/%s", buf, fileName);
+ }
+ }
+ }
+ closedir(dir);
+ }
+ return bestPackage;
+}
+
+#else /* JIM_ANSIC */
+
+static char *JimFindBestPackage(Jim_Interp *interp, char **prefixes,
+ int prefixc, const char *pkgName, int pkgVer, int flags)
+{
+ JIM_NOTUSED(interp);
+ JIM_NOTUSED(prefixes);
+ JIM_NOTUSED(prefixc);
+ JIM_NOTUSED(pkgName);
+ JIM_NOTUSED(pkgVer);
+ JIM_NOTUSED(flags);
+ return NULL;
+}
+
+#endif /* JIM_ANSIC */
+
+/* Search for a suitable package under every dir specified by jim_libpath
+ * and load it if possible. If a suitable package was loaded with success
+ * JIM_OK is returned, otherwise JIM_ERR is returned. */
+static int JimLoadPackage(Jim_Interp *interp, const char *name, int ver,
+ int flags)
+{
+ Jim_Obj *libPathObjPtr;
+ char **prefixes, *best;
+ int prefixc, i, retCode = JIM_OK;
+
+ libPathObjPtr = Jim_GetGlobalVariableStr(interp, "jim_libpath", JIM_NONE);
+ if (libPathObjPtr == NULL) {
+ prefixc = 0;
+ libPathObjPtr = NULL;
+ } else {
+ Jim_IncrRefCount(libPathObjPtr);
+ Jim_ListLength(interp, libPathObjPtr, &prefixc);
+ }
+
+ 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_GetString(prefixObjPtr, NULL));
+ }
+ /* Scan every directory to find the "best" package. */
+ best = JimFindBestPackage(interp, prefixes, prefixc, name, ver, flags);
+ if (best != NULL) {
+ char *p = strrchr(best, '.');
+ /* Try to load/source it */
+ if (p && strcmp(p, ".tcl") == 0) {
+ retCode = Jim_EvalFile(interp, best);
+ } else {
+ retCode = Jim_LoadLibrary(interp, best);
+ }
+ } else {
+ retCode = JIM_ERR;
+ }
+ Jim_Free(best);
+ for (i = 0; i < prefixc; i++)
+ Jim_Free(prefixes[i]);
+ Jim_Free(prefixes);
+ if (libPathObjPtr)
+ Jim_DecrRefCount(interp, libPathObjPtr);
+ return retCode;
+}
+
+const char *Jim_PackageRequire(Jim_Interp *interp, const char *name,
+ const char *ver, int flags)
+{
+ Jim_HashEntry *he;
+ int requiredVer;
+
+ /* Start with an empty error string */
+ Jim_SetResultString(interp, "", 0);
+
+ if (JimPackageVersionToInt(interp, ver, &requiredVer, JIM_ERRMSG) != JIM_OK)
+ return NULL;
+ he = Jim_FindHashEntry(&interp->packages, name);
+ if (he == NULL) {
+ /* Try to load the package. */
+ if (JimLoadPackage(interp, name, requiredVer, flags) == JIM_OK) {
+ he = Jim_FindHashEntry(&interp->packages, name);
+ if (he == NULL) {
+ return "?";
+ }
+ return he->val;
+ }
+ /* No way... return an error. */
+ if (flags & JIM_ERRMSG) {
+ int len;
+ Jim_GetString(Jim_GetResult(interp), &len);
+ Jim_AppendStrings(interp, Jim_GetResult(interp), len ? "\n" : "",
+ "Can't find package '", name, "'", NULL);
+ }
+ return NULL;
+ } else {
+ int actualVer;
+ if (JimPackageVersionToInt(interp, he->val, &actualVer, JIM_ERRMSG)
+ != JIM_OK)
+ {
+ return NULL;
+ }
+ /* Check if version matches. */
+ if (JimPackageMatchVersion(requiredVer, actualVer, flags) == 0) {
+ Jim_AppendStrings(interp, Jim_GetResult(interp),
+ "Package '", name, "' already loaded, but with version ",
+ he->val, NULL);
+ return NULL;
+ }
+ return he->val;
+ }
+}
+
diff --git a/jim.c b/jim.c
index 54d6e17..db51190 100644
--- a/jim.c
+++ b/jim.c
@@ -7769,466 +7769,6 @@ static void JimPrngSeed(Jim_Interp *interp, const unsigned char *seed,
}
/* -----------------------------------------------------------------------------
- * 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 */
-
-/* -----------------------------------------------------------------------------
- * Packages handling
- * ---------------------------------------------------------------------------*/
-
-#define JIM_PKG_ANY_VERSION -1
-
-/* Convert a string of the type "1.2" into an integer.
- * MAJOR.MINOR is converted as MAJOR*100+MINOR, so "1.2" is converted
- * to the integer with value 102 */
-static int JimPackageVersionToInt(Jim_Interp *interp, const char *v,
- int *intPtr, int flags)
-{
- char *copy;
- jim_wide major, minor;
- char *majorStr, *minorStr, *p;
-
- if (v[0] == '\0') {
- *intPtr = JIM_PKG_ANY_VERSION;
- return JIM_OK;
- }
-
- copy = Jim_StrDup(v);
- p = strchr(copy, '.');
- if (p == NULL) goto badfmt;
- *p = '\0';
- majorStr = copy;
- minorStr = p+1;
-
- if (Jim_StringToWide(majorStr, &major, 10) != JIM_OK ||
- Jim_StringToWide(minorStr, &minor, 10) != JIM_OK)
- goto badfmt;
- *intPtr = (int)(major*100+minor);
- Jim_Free(copy);
- return JIM_OK;
-
-badfmt:
- Jim_Free(copy);
- if (flags & JIM_ERRMSG) {
- Jim_SetResult(interp, Jim_NewEmptyStringObj(interp));
- Jim_AppendStrings(interp, Jim_GetResult(interp),
- "invalid package version '", v, "'", NULL);
- }
- return JIM_ERR;
-}
-
-#define JIM_MATCHVER_EXACT (1<<JIM_PRIV_FLAG_SHIFT)
-static int JimPackageMatchVersion(int needed, int actual, int flags)
-{
- if (needed == JIM_PKG_ANY_VERSION) return 1;
- if (flags & JIM_MATCHVER_EXACT) {
- return needed == actual;
- } else {
- return needed/100 == actual/100 && (needed <= actual);
- }
-}
-
-int Jim_PackageProvide(Jim_Interp *interp, const char *name, const char *ver,
- int flags)
-{
- int intVersion;
- /* Check if the version format is ok */
- if (JimPackageVersionToInt(interp, ver, &intVersion, JIM_ERRMSG) != JIM_OK)
- return JIM_ERR;
- /* If the package was already provided returns an error. */
- if (Jim_FindHashEntry(&interp->packages, name) != NULL) {
- if (flags & JIM_ERRMSG) {
- Jim_SetResult(interp, Jim_NewEmptyStringObj(interp));
- Jim_AppendStrings(interp, Jim_GetResult(interp),
- "package '", name, "' was already provided", NULL);
- }
- return JIM_ERR;
- }
- Jim_AddHashEntry(&interp->packages, name, (char*) ver);
- return JIM_OK;
-}
-
-#ifndef JIM_ANSIC
-
-#ifndef WIN32
-# include <sys/types.h>
-# include <dirent.h>
-#else
-# include <io.h>
-/* Posix dirent.h compatiblity layer for WIN32.
- * Copyright Kevlin Henney, 1997, 2003. All rights reserved.
- * Copyright Salvatore Sanfilippo ,2005.
- *
- * Permission to use, copy, modify, and distribute this software and its
- * documentation for any purpose is hereby granted without fee, provided
- * that this copyright and permissions notice appear in all copies and
- * derivatives.
- *
- * This software is supplied "as is" without express or implied warranty.
- * This software was modified by Salvatore Sanfilippo for the Jim Interpreter.
- */
-
-struct dirent {
- char *d_name;
-};
-
-typedef struct DIR {
- long handle; /* -1 for failed rewind */
- struct _finddata_t info;
- struct dirent result; /* d_name null iff first time */
- char *name; /* null-terminated char string */
-} DIR;
-
-DIR *opendir(const char *name)
-{
- DIR *dir = 0;
-
- if(name && name[0]) {
- size_t base_length = strlen(name);
- const char *all = /* search pattern must end with suitable wildcard */
- strchr("/\\", name[base_length - 1]) ? "*" : "/*";
-
- if((dir = (DIR *) Jim_Alloc(sizeof *dir)) != 0 &&
- (dir->name = (char *) Jim_Alloc(base_length + strlen(all) + 1)) != 0)
- {
- strcat(strcpy(dir->name, name), all);
-
- if((dir->handle = (long) _findfirst(dir->name, &dir->info)) != -1)
- dir->result.d_name = 0;
- else { /* rollback */
- Jim_Free(dir->name);
- Jim_Free(dir);
- dir = 0;
- }
- } else { /* rollback */
- Jim_Free(dir);
- dir = 0;
- errno = ENOMEM;
- }
- } else {
- errno = EINVAL;
- }
- return dir;
-}
-
-int closedir(DIR *dir)
-{
- int result = -1;
-
- if(dir) {
- if(dir->handle != -1)
- result = _findclose(dir->handle);
- Jim_Free(dir->name);
- Jim_Free(dir);
- }
- if(result == -1) /* map all errors to EBADF */
- errno = EBADF;
- return result;
-}
-
-struct dirent *readdir(DIR *dir)
-{
- struct dirent *result = 0;
-
- if(dir && dir->handle != -1) {
- if(!dir->result.d_name || _findnext(dir->handle, &dir->info) != -1) {
- result = &dir->result;
- result->d_name = dir->info.name;
- }
- } else {
- errno = EBADF;
- }
- return result;
-}
-
-#endif /* WIN32 */
-
-static char *JimFindBestPackage(Jim_Interp *interp, char **prefixes,
- int prefixc, const char *pkgName, int pkgVer, int flags)
-{
- int bestVer = -1, i;
- int pkgNameLen = strlen(pkgName);
- char *bestPackage = NULL;
- struct dirent *de;
-
- for (i = 0; i < prefixc; i++) {
- DIR *dir;
- char buf[JIM_PATH_LEN];
- int prefixLen;
-
- if (prefixes[i] == NULL) continue;
- strncpy(buf, prefixes[i], JIM_PATH_LEN);
- buf[JIM_PATH_LEN-1] = '\0';
- prefixLen = strlen(buf);
- if (prefixLen && buf[prefixLen-1] == '/')
- buf[prefixLen-1] = '\0';
-
- if ((dir = opendir(buf)) == NULL) continue;
- while ((de = readdir(dir)) != NULL) {
- char *fileName = de->d_name;
- int fileNameLen = strlen(fileName);
-
- if (strncmp(fileName, "jim-", 4) == 0 &&
- strncmp(fileName+4, pkgName, pkgNameLen) == 0 &&
- *(fileName+4+pkgNameLen) == '-' &&
- fileNameLen > 4 && /* note that this is not really useful */
- (strncmp(fileName+fileNameLen-4, ".tcl", 4) == 0 ||
- strncmp(fileName+fileNameLen-4, ".dll", 4) == 0 ||
- strncmp(fileName+fileNameLen-3, ".so", 3) == 0))
- {
- char ver[6]; /* xx.yy<nulterm> */
- char *p = strrchr(fileName, '.');
- int verLen, fileVer;
-
- verLen = p - (fileName+4+pkgNameLen+1);
- if (verLen < 3 || verLen > 5) continue;
- memcpy(ver, fileName+4+pkgNameLen+1, verLen);
- ver[verLen] = '\0';
- if (JimPackageVersionToInt(interp, ver, &fileVer, JIM_NONE)
- != JIM_OK) continue;
- if (JimPackageMatchVersion(pkgVer, fileVer, flags) &&
- (bestVer == -1 || bestVer < fileVer))
- {
- bestVer = fileVer;
- Jim_Free(bestPackage);
- bestPackage = Jim_Alloc(strlen(buf)+strlen(fileName)+2);
- sprintf(bestPackage, "%s/%s", buf, fileName);
- }
- }
- }
- closedir(dir);
- }
- return bestPackage;
-}
-
-#else /* JIM_ANSIC */
-
-static char *JimFindBestPackage(Jim_Interp *interp, char **prefixes,
- int prefixc, const char *pkgName, int pkgVer, int flags)
-{
- JIM_NOTUSED(interp);
- JIM_NOTUSED(prefixes);
- JIM_NOTUSED(prefixc);
- JIM_NOTUSED(pkgName);
- JIM_NOTUSED(pkgVer);
- JIM_NOTUSED(flags);
- return NULL;
-}
-
-#endif /* JIM_ANSIC */
-
-/* Search for a suitable package under every dir specified by jim_libpath
- * and load it if possible. If a suitable package was loaded with success
- * JIM_OK is returned, otherwise JIM_ERR is returned. */
-static int JimLoadPackage(Jim_Interp *interp, const char *name, int ver,
- int flags)
-{
- Jim_Obj *libPathObjPtr;
- char **prefixes, *best;
- int prefixc, i, retCode = JIM_OK;
-
- libPathObjPtr = Jim_GetGlobalVariableStr(interp, "jim_libpath", JIM_NONE);
- if (libPathObjPtr == NULL) {
- prefixc = 0;
- libPathObjPtr = NULL;
- } else {
- Jim_IncrRefCount(libPathObjPtr);
- Jim_ListLength(interp, libPathObjPtr, &prefixc);
- }
-
- 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_GetString(prefixObjPtr, NULL));
- }
- /* Scan every directory to find the "best" package. */
- best = JimFindBestPackage(interp, prefixes, prefixc, name, ver, flags);
- if (best != NULL) {
- char *p = strrchr(best, '.');
- /* Try to load/source it */
- if (p && strcmp(p, ".tcl") == 0) {
- retCode = Jim_EvalFile(interp, best);
- } else {
- retCode = Jim_LoadLibrary(interp, best);
- }
- } else {
- retCode = JIM_ERR;
- }
- Jim_Free(best);
- for (i = 0; i < prefixc; i++)
- Jim_Free(prefixes[i]);
- Jim_Free(prefixes);
- if (libPathObjPtr)
- Jim_DecrRefCount(interp, libPathObjPtr);
- return retCode;
-}
-
-const char *Jim_PackageRequire(Jim_Interp *interp, const char *name,
- const char *ver, int flags)
-{
- Jim_HashEntry *he;
- int requiredVer;
-
- /* Start with an empty error string */
- Jim_SetResultString(interp, "", 0);
-
- if (JimPackageVersionToInt(interp, ver, &requiredVer, JIM_ERRMSG) != JIM_OK)
- return NULL;
- he = Jim_FindHashEntry(&interp->packages, name);
- if (he == NULL) {
- /* Try to load the package. */
- if (JimLoadPackage(interp, name, requiredVer, flags) == JIM_OK) {
- he = Jim_FindHashEntry(&interp->packages, name);
- if (he == NULL) {
- return "?";
- }
- return he->val;
- }
- /* No way... return an error. */
- if (flags & JIM_ERRMSG) {
- int len;
- Jim_GetString(Jim_GetResult(interp), &len);
- Jim_AppendStrings(interp, Jim_GetResult(interp), len ? "\n" : "",
- "Can't find package '", name, "'", NULL);
- }
- return NULL;
- } else {
- int actualVer;
- if (JimPackageVersionToInt(interp, he->val, &actualVer, JIM_ERRMSG)
- != JIM_OK)
- {
- return NULL;
- }
- /* Check if version matches. */
- if (JimPackageMatchVersion(requiredVer, actualVer, flags) == 0) {
- Jim_AppendStrings(interp, Jim_GetResult(interp),
- "Package '", name, "' already loaded, but with version ",
- he->val, NULL);
- return NULL;
- }
- return he->val;
- }
-}
-
-/* -----------------------------------------------------------------------------
* Eval
* ---------------------------------------------------------------------------*/
#define JIM_EVAL_SARGV_LEN 8 /* static arguments vector length */
@@ -9223,7 +8763,7 @@ static int Jim_PutsCoreCommand(Jim_Interp *interp, int argc,
Jim_Obj *const *argv)
{
const char *str;
- int len, nonewline = 0;
+ int nonewline = 0;
if (argc != 2 && argc != 3) {
Jim_WrongNumArgs(interp, 1, argv, "-nonewline string");
diff --git a/jim.h b/jim.h
index 4ccf8d2..c10887e 100644
--- a/jim.h
+++ b/jim.h
@@ -857,6 +857,8 @@ JIM_EXPORT int JIM_API(Jim_InteractivePrompt) (Jim_Interp *interp);
/* Misc */
JIM_EXPORT void JIM_API(Jim_Panic) (Jim_Interp *interp, const char *fmt, ...);
+int Jim_StringToWide(const char *str, jim_wide *widePtr, int base);
+int Jim_LoadLibrary(Jim_Interp *interp, const char *pathName);
/* Jim's STDIO */
JIM_EXPORT int JIM_API( Jim_fprintf )( Jim_Interp *interp, void *cookie, const char *fmt, ... );
diff --git a/jimsh.c b/jimsh.c
index ef84970..838cbb2 100644
--- a/jimsh.c
+++ b/jimsh.c
@@ -119,6 +119,12 @@ static void JimLoadJimRc(Jim_Interp *interp)
}
}
+
+extern void Jim_AioInit(Jim_Interp *interp);
+extern void Jim_EventloopInit(Jim_Interp *interp);
+extern void Jim_RegexpInit(Jim_Interp *interp);
+extern void Jim_ReaddirInit(Jim_Interp *interp);
+
int main(int argc, char *const argv[])
{
int retcode, n;