diff options
author | Steve Bennett <steveb@workware.net.au> | 2009-07-27 11:01:21 +1000 |
---|---|---|
committer | Steve Bennett <steveb@workware.net.au> | 2010-10-15 10:11:01 +1000 |
commit | 050dc9d1556f69ddaaa156682715ee06ea1ff6fa (patch) | |
tree | 4d4e00de49f40daffc23547777b6a1e9a853a097 /jim-package.c | |
parent | 63011a2556161f26605f125eac5b9f25676112a7 (diff) | |
download | jimtcl-050dc9d1556f69ddaaa156682715ee06ea1ff6fa.zip jimtcl-050dc9d1556f69ddaaa156682715ee06ea1ff6fa.tar.gz jimtcl-050dc9d1556f69ddaaa156682715ee06ea1ff6fa.tar.bz2 |
Simplify package command to ignore versions
Also remove win32 support
Diffstat (limited to 'jim-package.c')
-rw-r--r-- | jim-package.c | 262 |
1 files changed, 25 insertions, 237 deletions
diff --git a/jim-package.c b/jim-package.c index 3b5fca8..48976c0 100644 --- a/jim-package.c +++ b/jim-package.c @@ -1,102 +1,10 @@ +#include <unistd.h> #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 @@ -104,63 +12,9 @@ struct dirent *readdir(DIR *dir) #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) { @@ -174,88 +28,35 @@ int Jim_PackageProvide(Jim_Interp *interp, const char *name, const char *ver, return JIM_OK; } -static char *JimFindBestPackage(Jim_Interp *interp, char **prefixes, - int prefixc, const char *pkgName, int pkgVer, int flags) +static char *JimFindPackage(Jim_Interp *interp, char **prefixes, + int prefixc, const char *pkgName) { - int bestVer = -1, i; - int pkgNameLen = strlen(pkgName); - char *bestPackage = NULL; - struct dirent *de; + int i; 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); - } - } + snprintf(buf, sizeof(buf), "%s/%s.tcl", prefixes[i], pkgName); + if (access(buf, R_OK) == 0) { + return Jim_StrDup(buf); + } + snprintf(buf, sizeof(buf), "%s/%s.so", prefixes[i], pkgName); + if (access(buf, R_OK) == 0) { + return Jim_StrDup(buf); } - 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) +static int JimLoadPackage(Jim_Interp *interp, const char *name, int flags) { Jim_Obj *libPathObjPtr; - char **prefixes, *best; + char **prefixes, *path; int prefixc, i, retCode = JIM_OK; libPathObjPtr = Jim_GetGlobalVariableStr(interp, "jim_libpath", JIM_NONE); @@ -278,20 +79,21 @@ static int JimLoadPackage(Jim_Interp *interp, const char *name, int ver, } 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, '.'); + + /* Scan every directory for the the first match */ + path = JimFindPackage(interp, prefixes, prefixc, name); + if (path != NULL) { + char *p = strrchr(path, '.'); /* Try to load/source it */ if (p && strcmp(p, ".tcl") == 0) { - retCode = Jim_EvalFile(interp, best); + retCode = Jim_EvalFile(interp, path); } else { - retCode = Jim_LoadLibrary(interp, best); + retCode = Jim_LoadLibrary(interp, path); } } else { retCode = JIM_ERR; } - Jim_Free(best); + Jim_Free(path); for (i = 0; i < prefixc; i++) Jim_Free(prefixes[i]); Jim_Free(prefixes); @@ -304,20 +106,19 @@ 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) { + if (JimLoadPackage(interp, name, flags) == JIM_OK) { he = Jim_FindHashEntry(&interp->packages, name); if (he == NULL) { - return "?"; + /* Did not call package provide, so we do it for them */ + Jim_PackageProvide(interp, name, "1.0", 0); + return "1.0"; } return he->val; } @@ -330,19 +131,6 @@ const char *Jim_PackageRequire(Jim_Interp *interp, const char *name, } 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; } } |