diff options
author | Steve Bennett <steveb@workware.net.au> | 2009-07-27 10:28:21 +1000 |
---|---|---|
committer | Steve Bennett <steveb@workware.net.au> | 2010-10-15 10:11:01 +1000 |
commit | 7f683b890f5575999bfae65988079c227735822d (patch) | |
tree | 4e9399f3466f1c1a38e93a984f0d42a66855b5d9 | |
parent | 0423aa4420d853a8f81a0579910d7f39b720f851 (diff) | |
download | jimtcl-7f683b890f5575999bfae65988079c227735822d.zip jimtcl-7f683b890f5575999bfae65988079c227735822d.tar.gz jimtcl-7f683b890f5575999bfae65988079c227735822d.tar.bz2 |
Split package and load out of jim.c
-rw-r--r-- | jim-load.c | 118 | ||||
-rw-r--r-- | jim-package.c | 349 | ||||
-rw-r--r-- | jim.c | 462 | ||||
-rw-r--r-- | jim.h | 2 | ||||
-rw-r--r-- | jimsh.c | 6 |
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; + } +} + @@ -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"); @@ -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, ... ); @@ -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; |