Differences From Artifact [78458f36cb89e6aa]:
- File
jim.c
-
2010-10-15 00:11:00
- part of checkin
[277d760a13]
on branch trunk
- Strip out unneeded junk from Jim
Nvp, getopt, move interactive processing to jim-interactive.c (user: steveb@workware.net.au
-
2010-10-15 00:11:00
- part of checkin
[277d760a13]
on branch trunk
- Strip out unneeded junk from Jim
To Artifact [0ffaf9426c4ddc86]:
- File
jim.c
- 2010-10-15 00:11:00 - part of checkin [3c72c7614b] on branch trunk - Split package and load out of jim.c (user: steveb@workware.net.au
7764 7764 prng->sbox[seed[i]] = t;
7765 7765 }
7766 7766 prng->i = prng->j = 0;
7767 7767 /* discard the first 256 bytes of stream. */
7768 7768 JimRandomBytes(interp, buf, 256);
7769 7769 }
7770 7770
7771 -/* -----------------------------------------------------------------------------
7772 - * Dynamic libraries support (WIN32 not supported)
7773 - * ---------------------------------------------------------------------------*/
7774 -
7775 -#ifdef JIM_DYNLIB
7776 -#ifdef WIN32
7777 -#define RTLD_LAZY 0
7778 -void * dlopen(const char *path, int mode)
7779 -{
7780 - JIM_NOTUSED(mode);
7781 -
7782 - return (void *)LoadLibraryA(path);
7783 -}
7784 -int dlclose(void *handle)
7785 -{
7786 - FreeLibrary((HANDLE)handle);
7787 - return 0;
7788 -}
7789 -void *dlsym(void *handle, const char *symbol)
7790 -{
7791 - return GetProcAddress((HMODULE)handle, symbol);
7792 -}
7793 -static char win32_dlerror_string[121];
7794 -const char *dlerror(void)
7795 -{
7796 - FormatMessageA(FORMAT_MESSAGE_FROM_SYSTEM, NULL, GetLastError(),
7797 - LANG_NEUTRAL, win32_dlerror_string, 120, NULL);
7798 - return win32_dlerror_string;
7799 -}
7800 -#endif /* WIN32 */
7801 -
7802 -int Jim_LoadLibrary(Jim_Interp *interp, const char *pathName)
7803 -{
7804 - Jim_Obj *libPathObjPtr;
7805 - int prefixc, i;
7806 - void *handle;
7807 - int (*onload)(Jim_Interp *interp);
7808 -
7809 - libPathObjPtr = Jim_GetGlobalVariableStr(interp, "jim_libpath", JIM_NONE);
7810 - if (libPathObjPtr == NULL) {
7811 - prefixc = 0;
7812 - libPathObjPtr = NULL;
7813 - } else {
7814 - Jim_IncrRefCount(libPathObjPtr);
7815 - Jim_ListLength(interp, libPathObjPtr, &prefixc);
7816 - }
7817 -
7818 - for (i = -1; i < prefixc; i++) {
7819 - if (i < 0) {
7820 - handle = dlopen(pathName, RTLD_LAZY);
7821 - } else {
7822 - FILE *fp;
7823 - char buf[JIM_PATH_LEN];
7824 - const char *prefix;
7825 - int prefixlen;
7826 - Jim_Obj *prefixObjPtr;
7827 -
7828 - buf[0] = '\0';
7829 - if (Jim_ListIndex(interp, libPathObjPtr, i,
7830 - &prefixObjPtr, JIM_NONE) != JIM_OK)
7831 - continue;
7832 - prefix = Jim_GetString(prefixObjPtr, &prefixlen);
7833 - if (prefixlen+strlen(pathName)+1 >= JIM_PATH_LEN)
7834 - continue;
7835 - if (*pathName == '/') {
7836 - strcpy(buf, pathName);
7837 - }
7838 - else if (prefixlen && prefix[prefixlen-1] == '/')
7839 - sprintf(buf, "%s%s", prefix, pathName);
7840 - else
7841 - sprintf(buf, "%s/%s", prefix, pathName);
7842 - fp = fopen(buf, "r");
7843 - if (fp == NULL)
7844 - continue;
7845 - fclose(fp);
7846 - handle = dlopen(buf, RTLD_LAZY);
7847 - }
7848 - if (handle == NULL) {
7849 - Jim_SetResult(interp, Jim_NewEmptyStringObj(interp));
7850 - Jim_AppendStrings(interp, Jim_GetResult(interp),
7851 - "error loading extension \"", pathName,
7852 - "\": ", dlerror(), NULL);
7853 - if (i < 0)
7854 - continue;
7855 - goto err;
7856 - }
7857 - if ((onload = dlsym(handle, "Jim_OnLoad")) == NULL) {
7858 - Jim_SetResultString(interp,
7859 - "No Jim_OnLoad symbol found on extension", -1);
7860 - goto err;
7861 - }
7862 - if (onload(interp) == JIM_ERR) {
7863 - dlclose(handle);
7864 - goto err;
7865 - }
7866 - Jim_SetEmptyResult(interp);
7867 - if (libPathObjPtr != NULL)
7868 - Jim_DecrRefCount(interp, libPathObjPtr);
7869 - return JIM_OK;
7870 - }
7871 -err:
7872 - if (libPathObjPtr != NULL)
7873 - Jim_DecrRefCount(interp, libPathObjPtr);
7874 - return JIM_ERR;
7875 -}
7876 -#else /* JIM_DYNLIB */
7877 -int Jim_LoadLibrary(Jim_Interp *interp, const char *pathName)
7878 -{
7879 - JIM_NOTUSED(interp);
7880 - JIM_NOTUSED(pathName);
7881 -
7882 - Jim_SetResultString(interp, "the Jim binary has no support for [load]", -1);
7883 - return JIM_ERR;
7884 -}
7885 -#endif/* JIM_DYNLIB */
7886 -
7887 -/* -----------------------------------------------------------------------------
7888 - * Packages handling
7889 - * ---------------------------------------------------------------------------*/
7890 -
7891 -#define JIM_PKG_ANY_VERSION -1
7892 -
7893 -/* Convert a string of the type "1.2" into an integer.
7894 - * MAJOR.MINOR is converted as MAJOR*100+MINOR, so "1.2" is converted
7895 - * to the integer with value 102 */
7896 -static int JimPackageVersionToInt(Jim_Interp *interp, const char *v,
7897 - int *intPtr, int flags)
7898 -{
7899 - char *copy;
7900 - jim_wide major, minor;
7901 - char *majorStr, *minorStr, *p;
7902 -
7903 - if (v[0] == '\0') {
7904 - *intPtr = JIM_PKG_ANY_VERSION;
7905 - return JIM_OK;
7906 - }
7907 -
7908 - copy = Jim_StrDup(v);
7909 - p = strchr(copy, '.');
7910 - if (p == NULL) goto badfmt;
7911 - *p = '\0';
7912 - majorStr = copy;
7913 - minorStr = p+1;
7914 -
7915 - if (Jim_StringToWide(majorStr, &major, 10) != JIM_OK ||
7916 - Jim_StringToWide(minorStr, &minor, 10) != JIM_OK)
7917 - goto badfmt;
7918 - *intPtr = (int)(major*100+minor);
7919 - Jim_Free(copy);
7920 - return JIM_OK;
7921 -
7922 -badfmt:
7923 - Jim_Free(copy);
7924 - if (flags & JIM_ERRMSG) {
7925 - Jim_SetResult(interp, Jim_NewEmptyStringObj(interp));
7926 - Jim_AppendStrings(interp, Jim_GetResult(interp),
7927 - "invalid package version '", v, "'", NULL);
7928 - }
7929 - return JIM_ERR;
7930 -}
7931 -
7932 -#define JIM_MATCHVER_EXACT (1<<JIM_PRIV_FLAG_SHIFT)
7933 -static int JimPackageMatchVersion(int needed, int actual, int flags)
7934 -{
7935 - if (needed == JIM_PKG_ANY_VERSION) return 1;
7936 - if (flags & JIM_MATCHVER_EXACT) {
7937 - return needed == actual;
7938 - } else {
7939 - return needed/100 == actual/100 && (needed <= actual);
7940 - }
7941 -}
7942 -
7943 -int Jim_PackageProvide(Jim_Interp *interp, const char *name, const char *ver,
7944 - int flags)
7945 -{
7946 - int intVersion;
7947 - /* Check if the version format is ok */
7948 - if (JimPackageVersionToInt(interp, ver, &intVersion, JIM_ERRMSG) != JIM_OK)
7949 - return JIM_ERR;
7950 - /* If the package was already provided returns an error. */
7951 - if (Jim_FindHashEntry(&interp->packages, name) != NULL) {
7952 - if (flags & JIM_ERRMSG) {
7953 - Jim_SetResult(interp, Jim_NewEmptyStringObj(interp));
7954 - Jim_AppendStrings(interp, Jim_GetResult(interp),
7955 - "package '", name, "' was already provided", NULL);
7956 - }
7957 - return JIM_ERR;
7958 - }
7959 - Jim_AddHashEntry(&interp->packages, name, (char*) ver);
7960 - return JIM_OK;
7961 -}
7962 -
7963 -#ifndef JIM_ANSIC
7964 -
7965 -#ifndef WIN32
7966 -# include <sys/types.h>
7967 -# include <dirent.h>
7968 -#else
7969 -# include <io.h>
7970 -/* Posix dirent.h compatiblity layer for WIN32.
7971 - * Copyright Kevlin Henney, 1997, 2003. All rights reserved.
7972 - * Copyright Salvatore Sanfilippo ,2005.
7973 - *
7974 - * Permission to use, copy, modify, and distribute this software and its
7975 - * documentation for any purpose is hereby granted without fee, provided
7976 - * that this copyright and permissions notice appear in all copies and
7977 - * derivatives.
7978 - *
7979 - * This software is supplied "as is" without express or implied warranty.
7980 - * This software was modified by Salvatore Sanfilippo for the Jim Interpreter.
7981 - */
7982 -
7983 -struct dirent {
7984 - char *d_name;
7985 -};
7986 -
7987 -typedef struct DIR {
7988 - long handle; /* -1 for failed rewind */
7989 - struct _finddata_t info;
7990 - struct dirent result; /* d_name null iff first time */
7991 - char *name; /* null-terminated char string */
7992 -} DIR;
7993 -
7994 -DIR *opendir(const char *name)
7995 -{
7996 - DIR *dir = 0;
7997 -
7998 - if(name && name[0]) {
7999 - size_t base_length = strlen(name);
8000 - const char *all = /* search pattern must end with suitable wildcard */
8001 - strchr("/\\", name[base_length - 1]) ? "*" : "/*";
8002 -
8003 - if((dir = (DIR *) Jim_Alloc(sizeof *dir)) != 0 &&
8004 - (dir->name = (char *) Jim_Alloc(base_length + strlen(all) + 1)) != 0)
8005 - {
8006 - strcat(strcpy(dir->name, name), all);
8007 -
8008 - if((dir->handle = (long) _findfirst(dir->name, &dir->info)) != -1)
8009 - dir->result.d_name = 0;
8010 - else { /* rollback */
8011 - Jim_Free(dir->name);
8012 - Jim_Free(dir);
8013 - dir = 0;
8014 - }
8015 - } else { /* rollback */
8016 - Jim_Free(dir);
8017 - dir = 0;
8018 - errno = ENOMEM;
8019 - }
8020 - } else {
8021 - errno = EINVAL;
8022 - }
8023 - return dir;
8024 -}
8025 -
8026 -int closedir(DIR *dir)
8027 -{
8028 - int result = -1;
8029 -
8030 - if(dir) {
8031 - if(dir->handle != -1)
8032 - result = _findclose(dir->handle);
8033 - Jim_Free(dir->name);
8034 - Jim_Free(dir);
8035 - }
8036 - if(result == -1) /* map all errors to EBADF */
8037 - errno = EBADF;
8038 - return result;
8039 -}
8040 -
8041 -struct dirent *readdir(DIR *dir)
8042 -{
8043 - struct dirent *result = 0;
8044 -
8045 - if(dir && dir->handle != -1) {
8046 - if(!dir->result.d_name || _findnext(dir->handle, &dir->info) != -1) {
8047 - result = &dir->result;
8048 - result->d_name = dir->info.name;
8049 - }
8050 - } else {
8051 - errno = EBADF;
8052 - }
8053 - return result;
8054 -}
8055 -
8056 -#endif /* WIN32 */
8057 -
8058 -static char *JimFindBestPackage(Jim_Interp *interp, char **prefixes,
8059 - int prefixc, const char *pkgName, int pkgVer, int flags)
8060 -{
8061 - int bestVer = -1, i;
8062 - int pkgNameLen = strlen(pkgName);
8063 - char *bestPackage = NULL;
8064 - struct dirent *de;
8065 -
8066 - for (i = 0; i < prefixc; i++) {
8067 - DIR *dir;
8068 - char buf[JIM_PATH_LEN];
8069 - int prefixLen;
8070 -
8071 - if (prefixes[i] == NULL) continue;
8072 - strncpy(buf, prefixes[i], JIM_PATH_LEN);
8073 - buf[JIM_PATH_LEN-1] = '\0';
8074 - prefixLen = strlen(buf);
8075 - if (prefixLen && buf[prefixLen-1] == '/')
8076 - buf[prefixLen-1] = '\0';
8077 -
8078 - if ((dir = opendir(buf)) == NULL) continue;
8079 - while ((de = readdir(dir)) != NULL) {
8080 - char *fileName = de->d_name;
8081 - int fileNameLen = strlen(fileName);
8082 -
8083 - if (strncmp(fileName, "jim-", 4) == 0 &&
8084 - strncmp(fileName+4, pkgName, pkgNameLen) == 0 &&
8085 - *(fileName+4+pkgNameLen) == '-' &&
8086 - fileNameLen > 4 && /* note that this is not really useful */
8087 - (strncmp(fileName+fileNameLen-4, ".tcl", 4) == 0 ||
8088 - strncmp(fileName+fileNameLen-4, ".dll", 4) == 0 ||
8089 - strncmp(fileName+fileNameLen-3, ".so", 3) == 0))
8090 - {
8091 - char ver[6]; /* xx.yy<nulterm> */
8092 - char *p = strrchr(fileName, '.');
8093 - int verLen, fileVer;
8094 -
8095 - verLen = p - (fileName+4+pkgNameLen+1);
8096 - if (verLen < 3 || verLen > 5) continue;
8097 - memcpy(ver, fileName+4+pkgNameLen+1, verLen);
8098 - ver[verLen] = '\0';
8099 - if (JimPackageVersionToInt(interp, ver, &fileVer, JIM_NONE)
8100 - != JIM_OK) continue;
8101 - if (JimPackageMatchVersion(pkgVer, fileVer, flags) &&
8102 - (bestVer == -1 || bestVer < fileVer))
8103 - {
8104 - bestVer = fileVer;
8105 - Jim_Free(bestPackage);
8106 - bestPackage = Jim_Alloc(strlen(buf)+strlen(fileName)+2);
8107 - sprintf(bestPackage, "%s/%s", buf, fileName);
8108 - }
8109 - }
8110 - }
8111 - closedir(dir);
8112 - }
8113 - return bestPackage;
8114 -}
8115 -
8116 -#else /* JIM_ANSIC */
8117 -
8118 -static char *JimFindBestPackage(Jim_Interp *interp, char **prefixes,
8119 - int prefixc, const char *pkgName, int pkgVer, int flags)
8120 -{
8121 - JIM_NOTUSED(interp);
8122 - JIM_NOTUSED(prefixes);
8123 - JIM_NOTUSED(prefixc);
8124 - JIM_NOTUSED(pkgName);
8125 - JIM_NOTUSED(pkgVer);
8126 - JIM_NOTUSED(flags);
8127 - return NULL;
8128 -}
8129 -
8130 -#endif /* JIM_ANSIC */
8131 -
8132 -/* Search for a suitable package under every dir specified by jim_libpath
8133 - * and load it if possible. If a suitable package was loaded with success
8134 - * JIM_OK is returned, otherwise JIM_ERR is returned. */
8135 -static int JimLoadPackage(Jim_Interp *interp, const char *name, int ver,
8136 - int flags)
8137 -{
8138 - Jim_Obj *libPathObjPtr;
8139 - char **prefixes, *best;
8140 - int prefixc, i, retCode = JIM_OK;
8141 -
8142 - libPathObjPtr = Jim_GetGlobalVariableStr(interp, "jim_libpath", JIM_NONE);
8143 - if (libPathObjPtr == NULL) {
8144 - prefixc = 0;
8145 - libPathObjPtr = NULL;
8146 - } else {
8147 - Jim_IncrRefCount(libPathObjPtr);
8148 - Jim_ListLength(interp, libPathObjPtr, &prefixc);
8149 - }
8150 -
8151 - prefixes = Jim_Alloc(sizeof(char*)*prefixc);
8152 - for (i = 0; i < prefixc; i++) {
8153 - Jim_Obj *prefixObjPtr;
8154 - if (Jim_ListIndex(interp, libPathObjPtr, i,
8155 - &prefixObjPtr, JIM_NONE) != JIM_OK)
8156 - {
8157 - prefixes[i] = NULL;
8158 - continue;
8159 - }
8160 - prefixes[i] = Jim_StrDup(Jim_GetString(prefixObjPtr, NULL));
8161 - }
8162 - /* Scan every directory to find the "best" package. */
8163 - best = JimFindBestPackage(interp, prefixes, prefixc, name, ver, flags);
8164 - if (best != NULL) {
8165 - char *p = strrchr(best, '.');
8166 - /* Try to load/source it */
8167 - if (p && strcmp(p, ".tcl") == 0) {
8168 - retCode = Jim_EvalFile(interp, best);
8169 - } else {
8170 - retCode = Jim_LoadLibrary(interp, best);
8171 - }
8172 - } else {
8173 - retCode = JIM_ERR;
8174 - }
8175 - Jim_Free(best);
8176 - for (i = 0; i < prefixc; i++)
8177 - Jim_Free(prefixes[i]);
8178 - Jim_Free(prefixes);
8179 - if (libPathObjPtr)
8180 - Jim_DecrRefCount(interp, libPathObjPtr);
8181 - return retCode;
8182 -}
8183 -
8184 -const char *Jim_PackageRequire(Jim_Interp *interp, const char *name,
8185 - const char *ver, int flags)
8186 -{
8187 - Jim_HashEntry *he;
8188 - int requiredVer;
8189 -
8190 - /* Start with an empty error string */
8191 - Jim_SetResultString(interp, "", 0);
8192 -
8193 - if (JimPackageVersionToInt(interp, ver, &requiredVer, JIM_ERRMSG) != JIM_OK)
8194 - return NULL;
8195 - he = Jim_FindHashEntry(&interp->packages, name);
8196 - if (he == NULL) {
8197 - /* Try to load the package. */
8198 - if (JimLoadPackage(interp, name, requiredVer, flags) == JIM_OK) {
8199 - he = Jim_FindHashEntry(&interp->packages, name);
8200 - if (he == NULL) {
8201 - return "?";
8202 - }
8203 - return he->val;
8204 - }
8205 - /* No way... return an error. */
8206 - if (flags & JIM_ERRMSG) {
8207 - int len;
8208 - Jim_GetString(Jim_GetResult(interp), &len);
8209 - Jim_AppendStrings(interp, Jim_GetResult(interp), len ? "\n" : "",
8210 - "Can't find package '", name, "'", NULL);
8211 - }
8212 - return NULL;
8213 - } else {
8214 - int actualVer;
8215 - if (JimPackageVersionToInt(interp, he->val, &actualVer, JIM_ERRMSG)
8216 - != JIM_OK)
8217 - {
8218 - return NULL;
8219 - }
8220 - /* Check if version matches. */
8221 - if (JimPackageMatchVersion(requiredVer, actualVer, flags) == 0) {
8222 - Jim_AppendStrings(interp, Jim_GetResult(interp),
8223 - "Package '", name, "' already loaded, but with version ",
8224 - he->val, NULL);
8225 - return NULL;
8226 - }
8227 - return he->val;
8228 - }
8229 -}
8230 -
8231 7771 /* -----------------------------------------------------------------------------
8232 7772 * Eval
8233 7773 * ---------------------------------------------------------------------------*/
8234 7774 #define JIM_EVAL_SARGV_LEN 8 /* static arguments vector length */
8235 7775 #define JIM_EVAL_SINTV_LEN 8 /* static interpolation vector length */
8236 7776
8237 7777 static int JimCallProcedure(Jim_Interp *interp, Jim_Cmd *cmd, int argc,
................................................................................
9219 8759 * ---------------------------------------------------------------------------*/
9220 8760
9221 8761 /* fake [puts] -- not the real puts, just for debugging. */
9222 8762 static int Jim_PutsCoreCommand(Jim_Interp *interp, int argc,
9223 8763 Jim_Obj *const *argv)
9224 8764 {
9225 8765 const char *str;
9226 - int len, nonewline = 0;
8766 + int nonewline = 0;
9227 8767
9228 8768 if (argc != 2 && argc != 3) {
9229 8769 Jim_WrongNumArgs(interp, 1, argv, "-nonewline string");
9230 8770 return JIM_ERR;
9231 8771 }
9232 8772 if (argc == 3) {
9233 8773 if (!Jim_CompareStringImmediate(interp, argv[1], "-nonewline"))