Jim Tcl
Diff
Not logged in

Differences From Artifact [78458f36cb89e6aa]:

To Artifact [0ffaf9426c4ddc86]:


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"))