aboutsummaryrefslogtreecommitdiff
path: root/autosetup
diff options
context:
space:
mode:
authorSteve Bennett <steveb@workware.net.au>2012-02-14 10:58:56 +1000
committerSteve Bennett <steveb@workware.net.au>2012-02-14 10:58:56 +1000
commitba028faf4f740dcd364f9136399b599ea7d1f6d9 (patch)
tree86e6b24d084725eea0f001a7313dc8cdfbe5851e /autosetup
parentf7b181fa949476b1f3d3a771cfb786d9c65efac0 (diff)
downloadjimtcl-ba028faf4f740dcd364f9136399b599ea7d1f6d9.zip
jimtcl-ba028faf4f740dcd364f9136399b599ea7d1f6d9.tar.gz
jimtcl-ba028faf4f740dcd364f9136399b599ea7d1f6d9.tar.bz2
Update autosetup to 0.6.4
Signed-off-by: Steve Bennett <steveb@workware.net.au>
Diffstat (limited to 'autosetup')
-rw-r--r--autosetup/README.autosetup2
-rwxr-xr-xautosetup/autosetup2
-rwxr-xr-xautosetup/find-tclsh2
-rw-r--r--autosetup/jimsh0.c3311
4 files changed, 1966 insertions, 1351 deletions
diff --git a/autosetup/README.autosetup b/autosetup/README.autosetup
index c7f69a8..7ba1e37 100644
--- a/autosetup/README.autosetup
+++ b/autosetup/README.autosetup
@@ -1 +1 @@
-This is autosetup v0.6.3. See http://msteveb.github.com/autosetup/
+This is autosetup v0.6.4. See http://msteveb.github.com/autosetup/
diff --git a/autosetup/autosetup b/autosetup/autosetup
index b1134c8..84de0cf 100755
--- a/autosetup/autosetup
+++ b/autosetup/autosetup
@@ -5,7 +5,7 @@
# \
dir=`dirname "$0"`; exec "`$dir/find-tclsh`" "$0" "$@"
-set autosetup(version) 0.6.3
+set autosetup(version) 0.6.4
# Can be set to 1 to debug early-init problems
set autosetup(debug) 0
diff --git a/autosetup/find-tclsh b/autosetup/find-tclsh
index db30bd3..be7cf3d 100755
--- a/autosetup/find-tclsh
+++ b/autosetup/find-tclsh
@@ -3,7 +3,7 @@
# If not found, builds a bootstrap jimsh from source
d=`dirname "$0"`
{ "$d/jimsh0" "$d/test-tclsh"; } 2>/dev/null && exit 0
-PATH="$PATH:$d"
+PATH="$PATH:$d"; export PATH
for tclsh in jimsh tclsh tclsh8.5 tclsh8.6; do
{ $tclsh "$d/test-tclsh"; } 2>/dev/null && exit 0
done
diff --git a/autosetup/jimsh0.c b/autosetup/jimsh0.c
index 066b9df..3bf6947 100644
--- a/autosetup/jimsh0.c
+++ b/autosetup/jimsh0.c
@@ -57,6 +57,9 @@ int dlclose(void *handle);
void *dlsym(void *handle, const char *symbol);
char *dlerror(void);
+
+#define JIM_SPRINTF_DOUBLE_NEEDS_FIX
+
#ifdef _MSC_VER
@@ -111,7 +114,10 @@ struct dirent *readdir(DIR *dir);
#ifndef UTF8_UTIL_H
#define UTF8_UTIL_H
-int utf8_fromunicode(char *p, unsigned short uc);
+
+#define MAX_UTF8_LEN 4
+
+int utf8_fromunicode(char *p, unsigned uc);
#ifndef JIM_UTF8
#include <ctype.h>
@@ -120,6 +126,7 @@ int utf8_fromunicode(char *p, unsigned short uc);
#define utf8_strlen(S, B) ((B) < 0 ? strlen(S) : (B))
#define utf8_tounicode(S, CP) (*(CP) = (unsigned char)*(S), 1)
#define utf8_upper(C) toupper(C)
+#define utf8_title(C) toupper(C)
#define utf8_lower(C) tolower(C)
#define utf8_index(C, I) (I)
#define utf8_charlen(C) 1
@@ -191,12 +198,17 @@ extern "C" {
#define JIM_EVAL 7
-#define JIM_MAX_NESTING_DEPTH 1000
+#define JIM_MAX_CALLFRAME_DEPTH 1000
+#define JIM_MAX_EVAL_DEPTH 2000
#define JIM_NONE 0
#define JIM_ERRMSG 1
#define JIM_UNSHARED 4
+#define JIM_MUSTEXIST 8
+
+
+#define JIM_GLOBAL_ONLY 0x100
#define JIM_SUBST_NOVAR 1
@@ -236,7 +248,7 @@ typedef struct Jim_Stack {
typedef struct Jim_HashEntry {
- const void *key;
+ void *key;
union {
void *val;
int intval;
@@ -246,10 +258,10 @@ typedef struct Jim_HashEntry {
typedef struct Jim_HashTableType {
unsigned int (*hashFunction)(const void *key);
- const void *(*keyDup)(void *privdata, const void *key);
+ void *(*keyDup)(void *privdata, const void *key);
void *(*valDup)(void *privdata, const void *obj);
int (*keyCompare)(void *privdata, const void *key1, const void *key2);
- void (*keyDestructor)(void *privdata, const void *key);
+ void (*keyDestructor)(void *privdata, void *key);
void (*valDestructor)(void *privdata, void *obj);
} Jim_HashTableType;
@@ -292,7 +304,7 @@ typedef struct Jim_HashTableIterator {
if ((ht)->type->keyDup) \
entry->key = (ht)->type->keyDup((ht)->privdata, _key_); \
else \
- entry->key = (_key_); \
+ entry->key = (void *)(_key_); \
} while(0)
#define Jim_CompareHashKeys(ht, key1, key2) \
@@ -319,11 +331,7 @@ typedef struct Jim_Obj {
jim_wide wideValue;
- int hashValue;
-
- int indexValue;
-
- int returnCode;
+ int intValue;
double doubleValue;
@@ -335,12 +343,14 @@ typedef struct Jim_Obj {
} twoPtrValue;
struct {
- unsigned jim_wide callFrameId;
+ unsigned long callFrameId;
struct Jim_Var *varPtr;
+ int global;
} varValue;
struct {
- unsigned jim_wide procEpoch;
+ unsigned long procEpoch;
+ struct Jim_Obj *nsObj;
struct Jim_Cmd *cmdPtr;
} cmdValue;
@@ -356,7 +366,7 @@ typedef struct Jim_Obj {
} strValue;
struct {
- jim_wide id;
+ unsigned long id;
struct Jim_Reference *refPtr;
} refValue;
@@ -371,11 +381,6 @@ typedef struct Jim_Obj {
} dictSubstValue;
struct {
- unsigned char *data;
- size_t len;
- } binaryValue;
-
- struct {
unsigned flags;
void *compre;
} regexpValue;
@@ -436,18 +441,20 @@ typedef struct Jim_ObjType {
typedef struct Jim_CallFrame {
- unsigned jim_wide id;
+ unsigned long id;
int level;
struct Jim_HashTable vars;
struct Jim_HashTable *staticVars;
- struct Jim_CallFrame *parentCallFrame;
+ struct Jim_CallFrame *parent;
Jim_Obj *const *argv;
int argc;
Jim_Obj *procArgsObjPtr;
Jim_Obj *procBodyObjPtr;
- struct Jim_CallFrame *nextFramePtr;
+ struct Jim_CallFrame *next;
+ Jim_Obj *nsObj;
Jim_Obj *fileNameObj;
int line;
+ Jim_Stack *localCommands;
} Jim_CallFrame;
typedef struct Jim_Var {
@@ -465,6 +472,7 @@ typedef void (*Jim_DelCmdProc)(struct Jim_Interp *interp, void *privData);
typedef struct Jim_Cmd {
int inUse;
int isproc;
+ struct Jim_Cmd *prevCmd;
union {
struct {
@@ -477,7 +485,6 @@ typedef struct Jim_Cmd {
Jim_Obj *argListObjPtr;
Jim_Obj *bodyObjPtr;
Jim_HashTable *staticVars;
- struct Jim_Cmd *prevCmd;
int argListLen;
int reqArity;
int optArity;
@@ -487,6 +494,7 @@ typedef struct Jim_Cmd {
Jim_Obj *nameObjPtr;
Jim_Obj *defaultObjPtr;
} *arglist;
+ Jim_Obj *nsObj;
} proc;
} u;
} Jim_Cmd;
@@ -502,7 +510,9 @@ typedef struct Jim_Interp {
int errorLine;
Jim_Obj *errorFileNameObj;
int addStackTrace;
- int maxNestingDepth;
+ int maxCallFrameDepth;
+ int maxEvalDepth;
+ int evalDepth;
int returnCode;
int returnLevel;
int exitCode;
@@ -513,10 +523,10 @@ typedef struct Jim_Interp {
Jim_CallFrame *framePtr;
Jim_CallFrame *topFramePtr;
struct Jim_HashTable commands;
- unsigned jim_wide procEpoch; /* Incremented every time the result
+ unsigned long procEpoch; /* Incremented every time the result
of procedures names lookup caching
may no longer be valid. */
- unsigned jim_wide callFrameEpoch; /* Incremented every time a new
+ unsigned long callFrameEpoch; /* Incremented every time a new
callframe is created. This id is used for the
'ID' field contained in the Jim_CallFrame
structure. */
@@ -527,9 +537,9 @@ typedef struct Jim_Interp {
Jim_Obj *emptyObj;
Jim_Obj *trueObj;
Jim_Obj *falseObj;
- unsigned jim_wide referenceNextId;
+ unsigned long referenceNextId;
struct Jim_HashTable references;
- jim_wide lastCollectId; /* reference max Id of the last GC
+ unsigned long lastCollectId; /* reference max Id of the last GC
execution. It's set to -1 while the collection
is running as sentinel to avoid to recursive
calls via the [collect] command inside
@@ -548,7 +558,6 @@ typedef struct Jim_Interp {
struct Jim_HashTable assocData;
Jim_PrngState *prngState;
struct Jim_HashTable packages;
- Jim_Stack *localProcs;
Jim_Stack *loadHandles;
} Jim_Interp;
@@ -560,7 +569,6 @@ typedef struct Jim_Interp {
#define Jim_SetEmptyResult(i) Jim_SetResult(i, (i)->emptyObj)
#define Jim_GetResult(i) ((i)->result)
#define Jim_CmdPrivData(i) ((i)->cmdPrivData)
-#define Jim_String(o) Jim_GetString((o), NULL)
#define Jim_SetResult(i,o) do { \
Jim_Obj *_resultObjPtr_ = (o); \
@@ -616,9 +624,11 @@ JIM_EXPORT int Jim_EvalFileGlobal(Jim_Interp *interp, const char *filename);
JIM_EXPORT int Jim_EvalObj (Jim_Interp *interp, Jim_Obj *scriptObjPtr);
JIM_EXPORT int Jim_EvalObjVector (Jim_Interp *interp, int objc,
Jim_Obj *const *objv);
+JIM_EXPORT int Jim_EvalObjList(Jim_Interp *interp, Jim_Obj *listObj);
JIM_EXPORT int Jim_EvalObjPrefix(Jim_Interp *interp, Jim_Obj *prefix,
int objc, Jim_Obj *const *objv);
#define Jim_EvalPrefix(i, p, oc, ov) Jim_EvalObjPrefix((i), Jim_NewStringObj((i), (p), -1), (oc), (ov))
+JIM_EXPORT int Jim_EvalNamespace(Jim_Interp *interp, Jim_Obj *scriptObj, Jim_Obj *nsObj);
JIM_EXPORT int Jim_SubstObj (Jim_Interp *interp, Jim_Obj *substObjPtr,
Jim_Obj **resObjPtrPtr, int flags);
@@ -634,7 +644,7 @@ JIM_EXPORT void Jim_FreeStackElements(Jim_Stack *stack, void (*freeFunc)(void *p
JIM_EXPORT int Jim_InitHashTable (Jim_HashTable *ht,
const Jim_HashTableType *type, void *privdata);
-JIM_EXPORT int Jim_ExpandHashTable (Jim_HashTable *ht,
+JIM_EXPORT void Jim_ExpandHashTable (Jim_HashTable *ht,
unsigned int size);
JIM_EXPORT int Jim_AddHashEntry (Jim_HashTable *ht, const void *key,
void *val);
@@ -645,7 +655,7 @@ JIM_EXPORT int Jim_DeleteHashEntry (Jim_HashTable *ht,
JIM_EXPORT int Jim_FreeHashTable (Jim_HashTable *ht);
JIM_EXPORT Jim_HashEntry * Jim_FindHashEntry (Jim_HashTable *ht,
const void *key);
-JIM_EXPORT int Jim_ResizeHashTable (Jim_HashTable *ht);
+JIM_EXPORT void Jim_ResizeHashTable (Jim_HashTable *ht);
JIM_EXPORT Jim_HashTableIterator *Jim_GetHashTableIterator
(Jim_HashTable *ht);
JIM_EXPORT Jim_HashEntry * Jim_NextHashEntry
@@ -661,6 +671,7 @@ JIM_EXPORT Jim_Obj * Jim_DuplicateObj (Jim_Interp *interp,
Jim_Obj *objPtr);
JIM_EXPORT const char * Jim_GetString(Jim_Obj *objPtr,
int *lenPtr);
+JIM_EXPORT const char *Jim_String(Jim_Obj *objPtr);
JIM_EXPORT int Jim_Length(Jim_Obj *objPtr);
@@ -690,6 +701,8 @@ JIM_EXPORT int Jim_CompareStringImmediate (Jim_Interp *interp,
Jim_Obj *objPtr, const char *str);
JIM_EXPORT int Jim_StringCompareObj(Jim_Interp *interp, Jim_Obj *firstObjPtr,
Jim_Obj *secondObjPtr, int nocase);
+JIM_EXPORT int Jim_StringCompareLenObj(Jim_Interp *interp, Jim_Obj *firstObjPtr,
+ Jim_Obj *secondObjPtr, int nocase);
JIM_EXPORT int Jim_Utf8Length(Jim_Interp *interp, Jim_Obj *objPtr);
@@ -729,6 +742,9 @@ JIM_EXPORT int Jim_SetVariableStrWithStr (Jim_Interp *interp,
JIM_EXPORT int Jim_SetVariableLink (Jim_Interp *interp,
Jim_Obj *nameObjPtr, Jim_Obj *targetNameObjPtr,
Jim_CallFrame *targetCallFrame);
+JIM_EXPORT int Jim_CreateNamespaceVariable(Jim_Interp *interp,
+ Jim_Obj *varNameObj, Jim_Obj *targetNameObj);
+JIM_EXPORT int Jim_DiscardNamespaceVars(Jim_Interp *interp);
JIM_EXPORT Jim_Obj * Jim_GetVariable (Jim_Interp *interp,
Jim_Obj *nameObjPtr, int flags);
JIM_EXPORT Jim_Obj * Jim_GetGlobalVariable (Jim_Interp *interp,
@@ -764,11 +780,14 @@ JIM_EXPORT void Jim_ListAppendList (Jim_Interp *interp,
JIM_EXPORT int Jim_ListLength (Jim_Interp *interp, Jim_Obj *objPtr);
JIM_EXPORT int Jim_ListIndex (Jim_Interp *interp, Jim_Obj *listPrt,
int listindex, Jim_Obj **objPtrPtr, int seterr);
+JIM_EXPORT Jim_Obj *Jim_ListGetIndex(Jim_Interp *interp, Jim_Obj *listPtr, int idx);
JIM_EXPORT int Jim_SetListIndex (Jim_Interp *interp,
Jim_Obj *varNamePtr, Jim_Obj *const *indexv, int indexc,
Jim_Obj *newObjPtr);
JIM_EXPORT Jim_Obj * Jim_ConcatObj (Jim_Interp *interp, int objc,
Jim_Obj *const *objv);
+JIM_EXPORT Jim_Obj *Jim_ListJoin(Jim_Interp *interp,
+ Jim_Obj *listObjPtr, const char *joinStr, int joinStrLen);
JIM_EXPORT Jim_Obj * Jim_NewDictObj (Jim_Interp *interp,
@@ -786,6 +805,7 @@ JIM_EXPORT int Jim_DictPairs(Jim_Interp *interp,
JIM_EXPORT int Jim_DictAddElement(Jim_Interp *interp, Jim_Obj *objPtr,
Jim_Obj *keyObjPtr, Jim_Obj *valueObjPtr);
JIM_EXPORT int Jim_DictKeys(Jim_Interp *interp, Jim_Obj *objPtr, Jim_Obj *patternObj);
+JIM_EXPORT int Jim_DictValues(Jim_Interp *interp, Jim_Obj *dictObjPtr, Jim_Obj *patternObjPtr);
JIM_EXPORT int Jim_DictSize(Jim_Interp *interp, Jim_Obj *objPtr);
@@ -848,6 +868,11 @@ JIM_EXPORT void Jim_MakeErrorMessage (Jim_Interp *interp);
JIM_EXPORT int Jim_InteractivePrompt (Jim_Interp *interp);
+JIM_EXPORT void Jim_HistoryLoad(const char *filename);
+JIM_EXPORT void Jim_HistorySave(const char *filename);
+JIM_EXPORT char *Jim_HistoryGetline(const char *prompt);
+JIM_EXPORT void Jim_HistoryAdd(const char *line);
+JIM_EXPORT void Jim_HistoryShow(void);
JIM_EXPORT int Jim_InitStaticExtensions(Jim_Interp *interp);
@@ -1083,7 +1108,7 @@ int Jim_globInit(Jim_Interp *interp)
" }\n"
"\n"
"\n"
-" if {[string match {*[*?]*} $pattern]} {\n"
+" if {[string match {*[[*?]*} $pattern]} {\n"
"\n"
" set files [readdir -nocomplain $dir]\n"
" } elseif {[file isdir $dir] && [file exists $dir/$pattern]} {\n"
@@ -1113,10 +1138,10 @@ int Jim_globInit(Jim_Interp *interp)
"\n"
"\n"
" if {[set fb [string first \"\\{\" $pattern]] < 0} {\n"
-" return $pattern\n"
+" return [list $pattern]\n"
" }\n"
" if {[set nb [string first \"\\}\" $pattern $fb]] < 0} {\n"
-" return $pattern\n"
+" return [list $pattern]\n"
" }\n"
" set before [string range $pattern 0 $fb-1]\n"
" set braced [string range $pattern $fb+1 $nb-1]\n"
@@ -1188,19 +1213,8 @@ int Jim_stdlibInit(Jim_Interp *interp)
return Jim_EvalSource(interp, "stdlib.tcl", 1,
"\n"
-"\n"
-"\n"
-"proc alias {name args} {\n"
-" set prefix $args\n"
-" proc $name args prefix {\n"
-" tailcall {*}$prefix {*}$args\n"
-" }\n"
-"}\n"
-"\n"
-"\n"
"proc lambda {arglist args} {\n"
-" set name [ref {} function lambda.finalizer]\n"
-" tailcall proc $name $arglist {*}$args\n"
+" tailcall proc [ref {} function lambda.finalizer] $arglist {*}$args\n"
"}\n"
"\n"
"proc lambda.finalizer {name val} {\n"
@@ -1209,10 +1223,7 @@ int Jim_stdlibInit(Jim_Interp *interp)
"\n"
"\n"
"proc curry {args} {\n"
-" set prefix $args\n"
-" lambda args prefix {\n"
-" tailcall {*}$prefix {*}$args\n"
-" }\n"
+" alias [ref {} function lambda.finalizer] {*}$args\n"
"}\n"
"\n"
"\n"
@@ -1228,14 +1239,6 @@ int Jim_stdlibInit(Jim_Interp *interp)
"}\n"
"\n"
"\n"
-"proc lassign {list args} {\n"
-"\n"
-" lappend list {}\n"
-" uplevel 1 [list foreach $args $list break]\n"
-" lrange $list [llength $args] end-1\n"
-"}\n"
-"\n"
-"\n"
"\n"
"\n"
"proc stacktrace {} {\n"
@@ -1387,7 +1390,7 @@ int Jim_tclcompatInit(Jim_Interp *interp)
" foreach {n v} $args {\n"
" switch -glob -- $n {\n"
" -bl* {\n"
-" $f ndelay $v\n"
+" $f ndelay $(!$v)\n"
" }\n"
" -bu* {\n"
" $f buffering $v\n"
@@ -1721,13 +1724,37 @@ static void JimAioDelProc(Jim_Interp *interp, void *privData)
Jim_Free(af);
}
+static int JimCheckStreamError(Jim_Interp *interp, AioFile *af)
+{
+ if (!ferror(af->fp)) {
+ return JIM_OK;
+ }
+ clearerr(af->fp);
+
+ if (feof(af->fp) || errno == EAGAIN || errno == EINTR) {
+ return JIM_OK;
+ }
+#ifdef ECONNRESET
+ if (errno == ECONNRESET) {
+ return JIM_OK;
+ }
+#endif
+#ifdef ECONNABORTED
+ if (errno != ECONNABORTED) {
+ return JIM_OK;
+ }
+#endif
+ JimAioSetError(interp, af->filename);
+ return JIM_ERR;
+}
+
static int aio_cmd_read(Jim_Interp *interp, int argc, Jim_Obj *const *argv)
{
AioFile *af = Jim_CmdPrivData(interp);
char buf[AIO_BUF_LEN];
Jim_Obj *objPtr;
int nonewline = 0;
- int neededLen = -1;
+ jim_wide neededLen = -1;
if (argc && Jim_CompareStringImmediate(interp, argv[0], "-nonewline")) {
nonewline = 1;
@@ -1735,15 +1762,12 @@ static int aio_cmd_read(Jim_Interp *interp, int argc, Jim_Obj *const *argv)
argc--;
}
if (argc == 1) {
- jim_wide wideValue;
-
- if (Jim_GetWide(interp, argv[0], &wideValue) != JIM_OK)
+ if (Jim_GetWide(interp, argv[0], &neededLen) != JIM_OK)
return JIM_ERR;
- if (wideValue < 0) {
+ if (neededLen < 0) {
Jim_SetResultString(interp, "invalid parameter: negative len", -1);
return JIM_ERR;
}
- neededLen = (int)wideValue;
}
else if (argc) {
return -1;
@@ -1770,15 +1794,9 @@ static int aio_cmd_read(Jim_Interp *interp, int argc, Jim_Obj *const *argv)
break;
}
- if (ferror(af->fp)) {
- clearerr(af->fp);
-
- if (!feof(af->fp) && errno != EAGAIN) {
-
- Jim_FreeNewObj(interp, objPtr);
- JimAioSetError(interp, af->filename);
- return JIM_ERR;
- }
+ if (JimCheckStreamError(interp, af)) {
+ Jim_FreeNewObj(interp, objPtr);
+ return JIM_ERR;
}
if (nonewline) {
int len;
@@ -1796,8 +1814,8 @@ static int aio_cmd_read(Jim_Interp *interp, int argc, Jim_Obj *const *argv)
static int aio_cmd_copy(Jim_Interp *interp, int argc, Jim_Obj *const *argv)
{
AioFile *af = Jim_CmdPrivData(interp);
- long count = 0;
- long maxlen = LONG_MAX;
+ jim_wide count = 0;
+ jim_wide maxlen = JIM_WIDE_MAX;
FILE *outfh = Jim_AioFilehandle(interp, argv[0]);
if (outfh == NULL) {
@@ -1805,7 +1823,7 @@ static int aio_cmd_copy(Jim_Interp *interp, int argc, Jim_Obj *const *argv)
}
if (argc == 2) {
- if (Jim_GetLong(interp, argv[1], &maxlen) != JIM_OK) {
+ if (Jim_GetWide(interp, argv[1], &maxlen) != JIM_OK) {
return JIM_ERR;
}
}
@@ -1866,11 +1884,9 @@ static int aio_cmd_gets(Jim_Interp *interp, int argc, Jim_Obj *const *argv)
break;
}
}
- if (ferror(af->fp) && errno != EAGAIN && errno != EINTR) {
+ if (JimCheckStreamError(interp, af)) {
Jim_FreeNewObj(interp, objPtr);
- JimAioSetError(interp, af->filename);
- clearerr(af->fp);
return JIM_ERR;
}
@@ -2300,9 +2316,11 @@ static int JimMakeChannel(Jim_Interp *interp, FILE *fh, int fd, Jim_Obj *filenam
if (fh == NULL) {
JimAioSetError(interp, filename);
+#if !defined(JIM_ANSIC)
if (fd >= 0) {
close(fd);
}
+#endif
Jim_DecrRefCount(interp, filename);
return JIM_ERR;
}
@@ -3007,7 +3025,7 @@ static int set_array_string_value(Jim_Interp *interp, Jim_Obj *container, const
static int StoreStatData(Jim_Interp *interp, Jim_Obj *varName, const struct stat *sb)
{
if (set_array_int_value(interp, varName, "dev", sb->st_dev) != JIM_OK) {
- Jim_SetResultFormatted(interp, "can't set \"%#s(dev)\": variables isn't array", varName);
+ Jim_SetResultFormatted(interp, "can't set \"%#s(dev)\": variable isn't array", varName);
return JIM_ERR;
}
set_array_int_value(interp, varName, "ino", sb->st_ino);
@@ -3253,14 +3271,16 @@ static int mkdir_all(char *path)
while (ok--) {
- char *slash = strrchr(path, '/');
+ {
+ char *slash = strrchr(path, '/');
- if (slash && slash != path) {
- *slash = 0;
- if (mkdir_all(path) != 0) {
- return -1;
+ if (slash && slash != path) {
+ *slash = 0;
+ if (mkdir_all(path) != 0) {
+ return -1;
+ }
+ *slash = '/';
}
- *slash = '/';
}
first:
if (MKDIR_DEFAULT(path) == 0) {
@@ -3886,6 +3906,10 @@ int Jim_execInit(Jim_Interp *interp)
#define JimDupFd dup
#define JimFdOpenForRead(FD) fdopen((FD), "r")
#define JimOpenForRead(NAME) open((NAME), O_RDONLY, 0)
+
+ #ifndef HAVE_EXECVPE
+ #define execvpe(ARG0, ARGV, ENV) execvp(ARG0, ARGV)
+ #endif
#endif
static const char *JimStrError(void);
@@ -3974,8 +3998,7 @@ static char **JimBuildEnv(Jim_Interp *interp)
if (num % 2) {
num--;
}
- size = Jim_Length(objPtr);
- size++;
+ size = Jim_Length(objPtr) + 2;
envptr = Jim_Alloc(sizeof(*envptr) * (num / 2 + 1) + size);
envdata = (char *)&envptr[num / 2 + 1];
@@ -4212,6 +4235,19 @@ static void JimDetachPids(Jim_Interp *interp, int numPids, const pidtype *pidPtr
}
}
+static FILE *JimGetAioFilehandle(Jim_Interp *interp, const char *name)
+{
+ FILE *fh;
+ Jim_Obj *fhObj;
+
+ fhObj = Jim_NewStringObj(interp, name, -1);
+ Jim_IncrRefCount(fhObj);
+ fh = Jim_AioFilehandle(interp, fhObj);
+ Jim_DecrRefCount(interp, fhObj);
+
+ return fh;
+}
+
static int
JimCreatePipeline(Jim_Interp *interp, int argc, Jim_Obj *const *argv, pidtype **pidArrayPtr,
fdtype *inPipePtr, fdtype *outPipePtr, fdtype *errFilePtr)
@@ -4383,10 +4419,8 @@ badargs:
}
else if (inputFile == FILE_HANDLE) {
- Jim_Obj *fhObj = Jim_NewStringObj(interp, input, -1);
- FILE *fh = Jim_AioFilehandle(interp, fhObj);
+ FILE *fh = JimGetAioFilehandle(interp, input);
- Jim_FreeNewObj(interp, fhObj);
if (fh == NULL) {
goto error;
}
@@ -4412,10 +4446,7 @@ badargs:
if (output != NULL) {
if (outputFile == FILE_HANDLE) {
- Jim_Obj *fhObj = Jim_NewStringObj(interp, output, -1);
- FILE *fh = Jim_AioFilehandle(interp, fhObj);
-
- Jim_FreeNewObj(interp, fhObj);
+ FILE *fh = JimGetAioFilehandle(interp, output);
if (fh == NULL) {
goto error;
}
@@ -4453,10 +4484,7 @@ badargs:
}
}
if (errorId == JIM_BAD_FD) {
- Jim_Obj *fhObj = Jim_NewStringObj(interp, error, -1);
- FILE *fh = Jim_AioFilehandle(interp, fhObj);
-
- Jim_FreeNewObj(interp, fhObj);
+ FILE *fh = JimGetAioFilehandle(interp, error);
if (fh == NULL) {
goto error;
}
@@ -4544,7 +4572,7 @@ badargs:
close(i);
}
- execvp(arg_array[firstArg], &arg_array[firstArg]);
+ execvpe(arg_array[firstArg], &arg_array[firstArg], Jim_GetEnviron());
fprintf(stderr, "couldn't exec \"%s\"", arg_array[firstArg]);
@@ -5294,58 +5322,30 @@ static int array_cmd_exists(Jim_Interp *interp, int argc, Jim_Obj *const *argv)
static int array_cmd_get(Jim_Interp *interp, int argc, Jim_Obj *const *argv)
{
- int i;
- int len;
- int all = 0;
- Jim_Obj *resultObj;
Jim_Obj *objPtr = Jim_GetVariable(interp, argv[0], JIM_NONE);
- Jim_Obj *dictObj;
- Jim_Obj **dictValuesObj;
if (!objPtr) {
return JIM_OK;
}
if (argc == 1 || Jim_CompareStringImmediate(interp, argv[1], "*")) {
- all = 1;
- }
-
-
- if (all) {
- if (Jim_IsDict(objPtr) || (Jim_IsList(objPtr) && Jim_ListLength(interp, objPtr) % 2 == 0)) {
- Jim_SetResult(interp, objPtr);
- return JIM_OK;
- }
- }
-
- if (Jim_DictKeysVector(interp, objPtr, NULL, 0, &dictObj, JIM_ERRMSG) != JIM_OK) {
- return JIM_ERR;
- }
-
- if (Jim_DictPairs(interp, dictObj, &dictValuesObj, &len) != JIM_OK) {
- return JIM_ERR;
- }
-
- if (all) {
-
- Jim_SetResult(interp, dictObj);
- }
- else {
- resultObj = Jim_NewListObj(interp, NULL, 0);
-
- for (i = 0; i < len; i += 2) {
- if (Jim_StringMatchObj(interp, argv[1], dictValuesObj[i], 0)) {
- Jim_ListAppendElement(interp, resultObj, dictValuesObj[i]);
- Jim_ListAppendElement(interp, resultObj, dictValuesObj[i + 1]);
+ if (Jim_IsList(objPtr)) {
+ if (Jim_ListLength(interp, objPtr) % 2 != 0) {
+
+ return JIM_ERR;
}
}
-
- Jim_SetResult(interp, resultObj);
+ else if (Jim_DictSize(interp, objPtr) < 0) {
+
+ return JIM_ERR;
+ }
+ Jim_SetResult(interp, objPtr);
+ return JIM_OK;
}
- Jim_Free(dictValuesObj);
- return JIM_OK;
+
+ return Jim_DictValues(interp, objPtr, argv[1]);
}
static int array_cmd_names(Jim_Interp *interp, int argc, Jim_Obj *const *argv)
@@ -5365,7 +5365,6 @@ static int array_cmd_unset(Jim_Interp *interp, int argc, Jim_Obj *const *argv)
int len;
Jim_Obj *resultObj;
Jim_Obj *objPtr;
- Jim_Obj *dictObj;
Jim_Obj **dictValuesObj;
if (argc == 1 || Jim_CompareStringImmediate(interp, argv[1], "*")) {
@@ -5376,11 +5375,7 @@ static int array_cmd_unset(Jim_Interp *interp, int argc, Jim_Obj *const *argv)
objPtr = Jim_GetVariable(interp, argv[0], JIM_NONE);
- if (Jim_DictKeysVector(interp, objPtr, NULL, 0, &dictObj, JIM_ERRMSG) != JIM_OK) {
- return JIM_ERR;
- }
-
- if (Jim_DictPairs(interp, dictObj, &dictValuesObj, &len) != JIM_OK) {
+ if (Jim_DictPairs(interp, objPtr, &dictValuesObj, &len) != JIM_OK) {
return JIM_ERR;
}
@@ -5421,30 +5416,35 @@ static int array_cmd_set(Jim_Interp *interp, int argc, Jim_Obj *const *argv)
{
int i;
int len;
- int rc = JIM_OK;
Jim_Obj *listObj = argv[1];
-
- if (Jim_GetVariable(interp, argv[0], JIM_NONE) == NULL) {
-
- return Jim_SetVariable(interp, argv[0], listObj);
- }
+ Jim_Obj *dictObj;
len = Jim_ListLength(interp, listObj);
if (len % 2) {
Jim_SetResultString(interp, "list must have an even number of elements", -1);
return JIM_ERR;
}
- for (i = 0; i < len && rc == JIM_OK; i += 2) {
+
+ dictObj = Jim_GetVariable(interp, argv[0], JIM_UNSHARED);
+ if (!dictObj) {
+
+ return Jim_SetVariable(interp, argv[0], listObj);
+ }
+
+ if (Jim_IsShared(dictObj)) {
+ dictObj = Jim_DuplicateObj(interp, dictObj);
+ }
+
+ for (i = 0; i < len; i += 2) {
Jim_Obj *nameObj;
Jim_Obj *valueObj;
Jim_ListIndex(interp, listObj, i, &nameObj, JIM_NONE);
Jim_ListIndex(interp, listObj, i + 1, &valueObj, JIM_NONE);
- rc = Jim_SetDictKeysVector(interp, argv[0], &nameObj, 1, valueObj, JIM_ERRMSG);
+ Jim_DictAddElement(interp, dictObj, nameObj, valueObj);
}
-
- return rc;
+ return Jim_SetVariable(interp, argv[0], dictObj);
}
static const jim_subcmd_type array_command_table[] = {
@@ -5601,15 +5601,12 @@ static void JimChangeCallFrameId(Jim_Interp *interp, Jim_CallFrame *cf);
static void JimFreeCallFrame(Jim_Interp *interp, Jim_CallFrame *cf, int flags);
static int ListSetIndex(Jim_Interp *interp, Jim_Obj *listPtr, int listindex, Jim_Obj *newObjPtr,
int flags);
+static int JimDeleteLocalProcs(Jim_Interp *interp, Jim_Stack *localCommands);
static Jim_Obj *JimExpandDictSugar(Jim_Interp *interp, Jim_Obj *objPtr);
static void SetDictSubstFromAny(Jim_Interp *interp, Jim_Obj *objPtr);
static void JimSetFailedEnumResult(Jim_Interp *interp, const char *arg, const char *badtype,
const char *prefix, const char *const *tablePtr, const char *name);
-static void JimDeleteLocalProcs(Jim_Interp *interp);
-static int JimCallProcedure(Jim_Interp *interp, Jim_Cmd *cmd, Jim_Obj *fileNameObj, int linenr,
- int argc, Jim_Obj *const *argv);
-static int JimEvalObjVector(Jim_Interp *interp, int objc, Jim_Obj *const *objv,
- Jim_Obj *fileNameObj, int linenr);
+static int JimCallProcedure(Jim_Interp *interp, Jim_Cmd *cmd, int argc, Jim_Obj *const *argv);
static int JimGetWideNoErr(Jim_Interp *interp, Jim_Obj *objPtr, jim_wide * widePtr);
static int JimSign(jim_wide w);
static int JimValidName(Jim_Interp *interp, const char *type, Jim_Obj *nameObjPtr);
@@ -5617,8 +5614,6 @@ static void JimPrngSeed(Jim_Interp *interp, unsigned char *seed, int seedLen);
static void JimRandomBytes(Jim_Interp *interp, void *dest, unsigned int len);
-static const Jim_HashTableType JimVariablesHashTableType;
-
#define JimWideValue(objPtr) (objPtr)->internalRep.wideValue
@@ -5700,7 +5695,7 @@ first:
-static int GlobMatch(const char *pattern, const char *string, int nocase)
+static int JimGlobMatch(const char *pattern, const char *string, int nocase)
{
int c;
int pchar;
@@ -5716,7 +5711,7 @@ static int GlobMatch(const char *pattern, const char *string, int nocase)
}
while (*string) {
- if (GlobMatch(pattern, string, nocase))
+ if (JimGlobMatch(pattern, string, nocase))
return 1;
string += utf8_tounicode(string, &c);
}
@@ -5765,11 +5760,6 @@ static int GlobMatch(const char *pattern, const char *string, int nocase)
return 0;
}
-static int JimStringMatch(Jim_Interp *interp, Jim_Obj *patternObj, const char *string, int nocase)
-{
- return GlobMatch(Jim_String(patternObj), string, nocase);
-}
-
static int JimStringCompare(const char *s1, int l1, const char *s2, int l2)
{
if (l1 < l2) {
@@ -5783,12 +5773,12 @@ static int JimStringCompare(const char *s1, int l1, const char *s2, int l2)
}
}
-static int JimStringCompareNoCase(const char *s1, const char *s2, int maxchars)
+static int JimStringCompareLen(const char *s1, const char *s2, int maxchars, int nocase)
{
while (*s1 && *s2 && maxchars) {
int c1, c2;
- s1 += utf8_tounicode_case(s1, &c1, 1);
- s2 += utf8_tounicode_case(s2, &c2, 1);
+ s1 += utf8_tounicode_case(s1, &c1, nocase);
+ s2 += utf8_tounicode_case(s2, &c2, nocase);
if (c1 != c2) {
return JimSign(c1 - c2);
}
@@ -5894,31 +5884,37 @@ int Jim_StringToWide(const char *str, jim_wide * widePtr, int base)
int Jim_DoubleToString(char *buf, double doubleValue)
{
int len;
- char *buf0 = buf;
+ int i;
len = sprintf(buf, "%.12g", doubleValue);
- while (*buf) {
- if (*buf == '.' || isalpha(UCHAR(*buf))) {
-
- if (*buf == 'i' || *buf == 'n') {
- *buf = toupper(UCHAR(*buf));
- }
- if (*buf == 'I') {
+
+ for (i = 0; i < len; i++) {
+ if (buf[i] == '.' || buf[i] == 'e') {
+#if defined(JIM_SPRINTF_DOUBLE_NEEDS_FIX)
+ char *e = strchr(buf, 'e');
+ if (e && (e[1] == '-' || e[1] == '+') && e[2] == '0') {
- buf[3] = '\0';
- len = buf - buf0 + 3;
+ e += 2;
+ memmove(e, e + 1, len - (e - buf));
+ return len - 1;
}
+#endif
return len;
}
- buf++;
+
+ if (buf[i] == 'i' || buf[i] == 'I' || buf[i] == 'n' || buf[i] == 'N') {
+ buf[i] = toupper(UCHAR(buf[i]));
+ buf[i + 3] = 0;
+ return i + 3;
+ }
}
- *buf++ = '.';
- *buf++ = '0';
- *buf = '\0';
+ buf[i++] = '.';
+ buf[i++] = '0';
+ buf[i] = '\0';
- return len + 2;
+ return i;
}
int Jim_StringToDouble(const char *str, double *doublePtr)
@@ -5976,14 +5972,14 @@ void JimPanicDump(int condition, const char *fmt, ...)
}
#endif
- abort();
+ exit(1);
}
#endif
void *Jim_Alloc(int size)
{
- return malloc(size);
+ return size ? malloc(size) : NULL;
}
void Jim_Free(void *ptr)
@@ -6022,9 +6018,9 @@ static jim_wide JimClock(void)
-static int JimExpandHashTableIfNeeded(Jim_HashTable *ht);
+static void JimExpandHashTableIfNeeded(Jim_HashTable *ht);
static unsigned int JimHashTableNextPower(unsigned int size);
-static int JimInsertHashEntry(Jim_HashTable *ht, const void *key);
+static Jim_HashEntry *JimInsertHashEntry(Jim_HashTable *ht, const void *key, int replace);
@@ -6069,23 +6065,23 @@ int Jim_InitHashTable(Jim_HashTable *ht, const Jim_HashTableType *type, void *pr
return JIM_OK;
}
-int Jim_ResizeHashTable(Jim_HashTable *ht)
+void Jim_ResizeHashTable(Jim_HashTable *ht)
{
int minimal = ht->used;
if (minimal < JIM_HT_INITIAL_SIZE)
minimal = JIM_HT_INITIAL_SIZE;
- return Jim_ExpandHashTable(ht, minimal);
+ Jim_ExpandHashTable(ht, minimal);
}
-int Jim_ExpandHashTable(Jim_HashTable *ht, unsigned int size)
+void Jim_ExpandHashTable(Jim_HashTable *ht, unsigned int size)
{
Jim_HashTable n;
unsigned int realsize = JimHashTableNextPower(size), i;
- if (ht->used >= size)
- return JIM_ERR;
+ if (size <= ht->used)
+ return;
Jim_InitHashTable(&n, ht->type, ht->privdata);
n.size = realsize;
@@ -6122,43 +6118,43 @@ int Jim_ExpandHashTable(Jim_HashTable *ht, unsigned int size)
*ht = n;
- return JIM_OK;
}
int Jim_AddHashEntry(Jim_HashTable *ht, const void *key, void *val)
{
- int idx;
Jim_HashEntry *entry;
- if ((idx = JimInsertHashEntry(ht, key)) == -1)
+ entry = JimInsertHashEntry(ht, key, 0);
+ if (entry == NULL)
return JIM_ERR;
- entry = Jim_Alloc(sizeof(*entry));
- entry->next = ht->table[idx];
- ht->table[idx] = entry;
-
-
Jim_SetHashKey(ht, entry, key);
Jim_SetHashVal(ht, entry, val);
- ht->used++;
return JIM_OK;
}
int Jim_ReplaceHashEntry(Jim_HashTable *ht, const void *key, void *val)
{
+ int existed;
Jim_HashEntry *entry;
- if (Jim_AddHashEntry(ht, key, val) == JIM_OK)
- return JIM_OK;
-
- entry = Jim_FindHashEntry(ht, key);
-
- Jim_FreeEntryVal(ht, entry);
+ entry = JimInsertHashEntry(ht, key, 1);
+ if (entry->key) {
+
+ Jim_FreeEntryVal(ht, entry);
+ existed = 1;
+ }
+ else {
+
+ Jim_SetHashKey(ht, entry, key);
+ existed = 0;
+ }
Jim_SetHashVal(ht, entry, val);
- return JIM_OK;
+
+ return existed;
}
@@ -6270,13 +6266,12 @@ Jim_HashEntry *Jim_NextHashEntry(Jim_HashTableIterator *iter)
-static int JimExpandHashTableIfNeeded(Jim_HashTable *ht)
+static void JimExpandHashTableIfNeeded(Jim_HashTable *ht)
{
if (ht->size == 0)
- return Jim_ExpandHashTable(ht, JIM_HT_INITIAL_SIZE);
+ Jim_ExpandHashTable(ht, JIM_HT_INITIAL_SIZE);
if (ht->size == ht->used)
- return Jim_ExpandHashTable(ht, ht->size * 2);
- return JIM_OK;
+ Jim_ExpandHashTable(ht, ht->size * 2);
}
@@ -6293,24 +6288,32 @@ static unsigned int JimHashTableNextPower(unsigned int size)
}
}
-static int JimInsertHashEntry(Jim_HashTable *ht, const void *key)
+static Jim_HashEntry *JimInsertHashEntry(Jim_HashTable *ht, const void *key, int replace)
{
unsigned int h;
Jim_HashEntry *he;
- if (JimExpandHashTableIfNeeded(ht) == JIM_ERR)
- return -1;
+ JimExpandHashTableIfNeeded(ht);
+
h = Jim_HashKey(ht, key) & ht->sizemask;
he = ht->table[h];
while (he) {
if (Jim_CompareHashKeys(ht, key, he->key))
- return -1;
+ return replace ? he : NULL;
he = he->next;
}
- return h;
+
+
+ he = Jim_Alloc(sizeof(*he));
+ he->next = ht->table[h];
+ ht->table[h] = he;
+ ht->used++;
+ he->key = NULL;
+
+ return he;
}
@@ -6320,78 +6323,28 @@ static unsigned int JimStringCopyHTHashFunction(const void *key)
return Jim_GenHashFunction(key, strlen(key));
}
-static const void *JimStringCopyHTKeyDup(void *privdata, const void *key)
-{
- int len = strlen(key);
- char *copy = Jim_Alloc(len + 1);
-
- JIM_NOTUSED(privdata);
-
- memcpy(copy, key, len);
- copy[len] = '\0';
- return copy;
-}
-
-static void *JimStringKeyValCopyHTValDup(void *privdata, const void *val)
+static void *JimStringCopyHTDup(void *privdata, const void *key)
{
- int len = strlen(val);
- char *copy = Jim_Alloc(len + 1);
-
- JIM_NOTUSED(privdata);
-
- memcpy(copy, val, len);
- copy[len] = '\0';
- return copy;
+ return strdup(key);
}
static int JimStringCopyHTKeyCompare(void *privdata, const void *key1, const void *key2)
{
- JIM_NOTUSED(privdata);
-
return strcmp(key1, key2) == 0;
}
-static void JimStringCopyHTKeyDestructor(void *privdata, const void *key)
-{
- JIM_NOTUSED(privdata);
-
- Jim_Free((void *)key);
-}
-
-static void JimStringKeyValCopyHTValDestructor(void *privdata, void *val)
+static void JimStringCopyHTKeyDestructor(void *privdata, void *key)
{
- JIM_NOTUSED(privdata);
-
- Jim_Free((void *)val);
+ Jim_Free(key);
}
-#if 0
-static Jim_HashTableType JimStringCopyHashTableType = {
- JimStringCopyHTHashFunction,
- JimStringCopyHTKeyDup,
- NULL,
- JimStringCopyHTKeyCompare,
- JimStringCopyHTKeyDestructor,
- NULL
-};
-#endif
-
-static const Jim_HashTableType JimSharedStringsHashTableType = {
- JimStringCopyHTHashFunction,
- NULL,
- NULL,
- JimStringCopyHTKeyCompare,
- JimStringCopyHTKeyDestructor,
- NULL
-};
-
-static const Jim_HashTableType JimStringKeyValCopyHashTableType = {
- JimStringCopyHTHashFunction,
- JimStringCopyHTKeyDup,
- JimStringKeyValCopyHTValDup,
- JimStringCopyHTKeyCompare,
- JimStringCopyHTKeyDestructor,
- JimStringKeyValCopyHTValDestructor,
+static const Jim_HashTableType JimPackageHashTableType = {
+ JimStringCopyHTHashFunction,
+ JimStringCopyHTDup,
+ NULL,
+ JimStringCopyHTKeyCompare,
+ JimStringCopyHTKeyDestructor,
+ NULL
};
typedef struct AssocDataValue
@@ -6410,11 +6363,11 @@ static void JimAssocDataHashTableValueDestructor(void *privdata, void *data)
}
static const Jim_HashTableType JimAssocDataHashTableType = {
- JimStringCopyHTHashFunction,
- JimStringCopyHTKeyDup,
- NULL,
- JimStringCopyHTKeyCompare,
- JimStringCopyHTKeyDestructor,
+ JimStringCopyHTHashFunction,
+ JimStringCopyHTDup,
+ NULL,
+ JimStringCopyHTKeyCompare,
+ JimStringCopyHTKeyDestructor,
JimAssocDataHashTableValueDestructor
};
@@ -6572,57 +6525,43 @@ static int JimParseScript(struct JimParserCtx *pc)
if (*(pc->p + 1) == '\n' && pc->state == JIM_PS_DEF) {
return JimParseSep(pc);
}
- else {
- pc->comment = 0;
- return JimParseStr(pc);
- }
- break;
+ pc->comment = 0;
+ return JimParseStr(pc);
case ' ':
case '\t':
case '\r':
+ case '\f':
if (pc->state == JIM_PS_DEF)
return JimParseSep(pc);
- else {
- pc->comment = 0;
- return JimParseStr(pc);
- }
- break;
+ pc->comment = 0;
+ return JimParseStr(pc);
case '\n':
case ';':
pc->comment = 1;
if (pc->state == JIM_PS_DEF)
return JimParseEol(pc);
- else
- return JimParseStr(pc);
- break;
+ return JimParseStr(pc);
case '[':
pc->comment = 0;
return JimParseCmd(pc);
- break;
case '$':
pc->comment = 0;
if (JimParseVar(pc) == JIM_ERR) {
+
pc->tstart = pc->tend = pc->p++;
pc->len--;
- pc->tline = pc->linenr;
- pc->tt = JIM_TT_STR;
- return JIM_OK;
+ pc->tt = JIM_TT_ESC;
}
- else
- return JIM_OK;
- break;
+ return JIM_OK;
case '#':
if (pc->comment) {
JimParseComment(pc);
continue;
}
- else {
- return JimParseStr(pc);
- }
+ return JimParseStr(pc);
default:
pc->comment = 0;
return JimParseStr(pc);
- break;
}
return JIM_OK;
}
@@ -6632,8 +6571,10 @@ static int JimParseSep(struct JimParserCtx *pc)
{
pc->tstart = pc->p;
pc->tline = pc->linenr;
- while (*pc->p == ' ' || *pc->p == '\t' || *pc->p == '\r' ||
- (*pc->p == '\\' && *(pc->p + 1) == '\n')) {
+ while (isspace(UCHAR(*pc->p)) || (*pc->p == '\\' && *(pc->p + 1) == '\n')) {
+ if (*pc->p == '\n') {
+ break;
+ }
if (*pc->p == '\\') {
pc->p++;
pc->len--;
@@ -6651,7 +6592,7 @@ static int JimParseEol(struct JimParserCtx *pc)
{
pc->tstart = pc->p;
pc->tline = pc->linenr;
- while (*pc->p == ' ' || *pc->p == '\n' || *pc->p == '\t' || *pc->p == '\r' || *pc->p == ';') {
+ while (isspace(UCHAR(*pc->p)) || *pc->p == ';') {
if (*pc->p == '\n')
pc->linenr++;
pc->p++;
@@ -6878,11 +6819,13 @@ static int JimParseVar(struct JimParserCtx *pc)
while (1) {
if (pc->p[0] == ':' && pc->p[1] == ':') {
- pc->p += 2;
- pc->len -= 2;
+ while (*pc->p == ':') {
+ pc->p++;
+ pc->len--;
+ }
continue;
}
- if (isalnum(UCHAR(*pc->p)) || *pc->p == '_') {
+ if (isalnum(UCHAR(*pc->p)) || *pc->p == '_' || UCHAR(*pc->p) >= 0x80) {
pc->p++;
pc->len--;
continue;
@@ -6939,17 +6882,19 @@ static int JimParseVar(struct JimParserCtx *pc)
static int JimParseStr(struct JimParserCtx *pc)
{
- int newword = (pc->tt == JIM_TT_SEP || pc->tt == JIM_TT_EOL ||
- pc->tt == JIM_TT_NONE || pc->tt == JIM_TT_STR);
- if (newword && *pc->p == '{') {
- return JimParseBrace(pc);
- }
- else if (newword && *pc->p == '"') {
- pc->state = JIM_PS_QUOTE;
- pc->p++;
- pc->len--;
+ if (pc->tt == JIM_TT_SEP || pc->tt == JIM_TT_EOL ||
+ pc->tt == JIM_TT_NONE || pc->tt == JIM_TT_STR) {
- pc->missingline = pc->tline;
+ if (*pc->p == '{') {
+ return JimParseBrace(pc);
+ }
+ if (*pc->p == '"') {
+ pc->state = JIM_PS_QUOTE;
+ pc->p++;
+ pc->len--;
+
+ pc->missingline = pc->tline;
+ }
}
pc->tstart = pc->p;
pc->tline = pc->linenr;
@@ -7005,6 +6950,7 @@ static int JimParseStr(struct JimParserCtx *pc)
case '\t':
case '\n':
case '\r':
+ case '\f':
case ';':
if (pc->state == JIM_PS_DEF) {
pc->tend = pc->p - 1;
@@ -7105,27 +7051,54 @@ static int JimEscape(char *dest, const char *s, int slen)
i++;
break;
case 'u':
+ case 'U':
case 'x':
{
- int val = 0;
+ unsigned val = 0;
int k;
+ int maxchars = 2;
i++;
- for (k = 0; k < (s[i] == 'u' ? 4 : 2); k++) {
+ if (s[i] == 'U') {
+ maxchars = 8;
+ }
+ else if (s[i] == 'u') {
+ if (s[i + 1] == '{') {
+ maxchars = 6;
+ i++;
+ }
+ else {
+ maxchars = 4;
+ }
+ }
+
+ for (k = 0; k < maxchars; k++) {
int c = xdigitval(s[i + k + 1]);
if (c == -1) {
break;
}
val = (val << 4) | c;
}
+
+ if (s[i] == '{') {
+ if (k == 0 || val > 0x1fffff || s[i + k + 1] != '}') {
+
+ i--;
+ k = 0;
+ }
+ else {
+
+ k++;
+ }
+ }
if (k) {
- if (s[i] == 'u') {
- p += utf8_fromunicode(p, val);
+ if (s[i] == 'x') {
+ *p++ = val;
}
else {
- *p++ = val;
+ p += utf8_fromunicode(p, val);
}
i += k;
break;
@@ -7247,13 +7220,10 @@ static int JimParseListQuote(struct JimParserCtx *pc);
static int JimParseList(struct JimParserCtx *pc)
{
+ if (isspace(UCHAR(*pc->p))) {
+ return JimParseListSep(pc);
+ }
switch (*pc->p) {
- case ' ':
- case '\n':
- case '\t':
- case '\r':
- return JimParseListSep(pc);
-
case '"':
return JimParseListQuote(pc);
@@ -7278,7 +7248,7 @@ static int JimParseListSep(struct JimParserCtx *pc)
{
pc->tstart = pc->p;
pc->tline = pc->linenr;
- while (*pc->p == ' ' || *pc->p == '\t' || *pc->p == '\r' || *pc->p == '\n') {
+ while (isspace(UCHAR(*pc->p))) {
if (*pc->p == '\n') {
pc->linenr++;
}
@@ -7334,22 +7304,18 @@ static int JimParseListStr(struct JimParserCtx *pc)
pc->tt = JIM_TT_STR;
while (pc->len) {
- switch (*pc->p) {
- case '\\':
- if (--pc->len == 0) {
-
- pc->tend = pc->p;
- return JIM_OK;
- }
- pc->tt = JIM_TT_ESC;
- pc->p++;
- break;
- case ' ':
- case '\t':
- case '\n':
- case '\r':
- pc->tend = pc->p - 1;
+ if (isspace(UCHAR(*pc->p))) {
+ pc->tend = pc->p - 1;
+ return JIM_OK;
+ }
+ if (*pc->p == '\\') {
+ if (--pc->len == 0) {
+
+ pc->tend = pc->p;
return JIM_OK;
+ }
+ pc->tt = JIM_TT_ESC;
+ pc->p++;
}
pc->p++;
pc->len--;
@@ -7486,10 +7452,23 @@ const char *Jim_GetString(Jim_Obj *objPtr, int *lenPtr)
int Jim_Length(Jim_Obj *objPtr)
{
- int len;
+ if (objPtr->bytes == NULL) {
+
+ JimPanic((objPtr->typePtr->updateStringProc == NULL, "UpdateStringProc called against '%s' type.", objPtr->typePtr->name));
+ objPtr->typePtr->updateStringProc(objPtr);
+ }
+ return objPtr->length;
+}
- Jim_GetString(objPtr, &len);
- return len;
+
+const char *Jim_String(Jim_Obj *objPtr)
+{
+ if (objPtr->bytes == NULL) {
+
+ JimPanic((objPtr->typePtr->updateStringProc == NULL, "UpdateStringProc called against '%s' type.", objPtr->typePtr->name));
+ objPtr->typePtr->updateStringProc(objPtr);
+ }
+ return objPtr->bytes;
}
static void FreeDictSubstInternalRep(Jim_Interp *interp, Jim_Obj *objPtr);
@@ -7505,7 +7484,7 @@ static const Jim_ObjType dictSubstObjType = {
static void FreeInterpolatedInternalRep(Jim_Interp *interp, Jim_Obj *objPtr)
{
- Jim_DecrRefCount(interp, (Jim_Obj *)objPtr->internalRep.twoPtrValue.ptr2);
+ Jim_DecrRefCount(interp, objPtr->internalRep.dictSubstValue.indexObjPtr);
}
static const Jim_ObjType interpolatedObjType = {
@@ -7538,23 +7517,28 @@ static void DupStringInternalRep(Jim_Interp *interp, Jim_Obj *srcPtr, Jim_Obj *d
static int SetStringFromAny(Jim_Interp *interp, Jim_Obj *objPtr)
{
-
- (void)Jim_String(objPtr);
-
- Jim_FreeIntRep(interp, objPtr);
-
- objPtr->typePtr = &stringObjType;
- objPtr->internalRep.strValue.maxLength = objPtr->length;
-
- objPtr->internalRep.strValue.charLength = -1;
+ if (objPtr->typePtr != &stringObjType) {
+
+ if (objPtr->bytes == NULL) {
+
+ JimPanic((objPtr->typePtr->updateStringProc == NULL, "UpdateStringProc called against '%s' type.", objPtr->typePtr->name));
+ objPtr->typePtr->updateStringProc(objPtr);
+ }
+
+ Jim_FreeIntRep(interp, objPtr);
+
+ objPtr->typePtr = &stringObjType;
+ objPtr->internalRep.strValue.maxLength = objPtr->length;
+
+ objPtr->internalRep.strValue.charLength = -1;
+ }
return JIM_OK;
}
int Jim_Utf8Length(Jim_Interp *interp, Jim_Obj *objPtr)
{
#ifdef JIM_UTF8
- if (objPtr->typePtr != &stringObjType)
- SetStringFromAny(interp, objPtr);
+ SetStringFromAny(interp, objPtr);
if (objPtr->internalRep.strValue.charLength < 0) {
objPtr->internalRep.strValue.charLength = utf8_strlen(objPtr->bytes, objPtr->length);
@@ -7656,8 +7640,7 @@ static void StringAppendString(Jim_Obj *objPtr, const char *str, int len)
void Jim_AppendString(Jim_Interp *interp, Jim_Obj *objPtr, const char *str, int len)
{
JimPanic((Jim_IsShared(objPtr), "Jim_AppendString called with shared object"));
- if (objPtr->typePtr != &stringObjType)
- SetStringFromAny(interp, objPtr);
+ SetStringFromAny(interp, objPtr);
StringAppendString(objPtr, str, len);
}
@@ -7674,8 +7657,7 @@ void Jim_AppendStrings(Jim_Interp *interp, Jim_Obj *objPtr, ...)
{
va_list ap;
- if (objPtr->typePtr != &stringObjType)
- SetStringFromAny(interp, objPtr);
+ SetStringFromAny(interp, objPtr);
va_start(ap, objPtr);
while (1) {
char *s = va_arg(ap, char *);
@@ -7703,23 +7685,30 @@ int Jim_StringEqObj(Jim_Obj *aObjPtr, Jim_Obj *bObjPtr)
int Jim_StringMatchObj(Jim_Interp *interp, Jim_Obj *patternObjPtr, Jim_Obj *objPtr, int nocase)
{
- return JimStringMatch(interp, patternObjPtr, Jim_String(objPtr), nocase);
+ return JimGlobMatch(Jim_String(patternObjPtr), Jim_String(objPtr), nocase);
}
int Jim_StringCompareObj(Jim_Interp *interp, Jim_Obj *firstObjPtr, Jim_Obj *secondObjPtr, int nocase)
{
- const char *s1, *s2;
int l1, l2;
-
- s1 = Jim_GetString(firstObjPtr, &l1);
- s2 = Jim_GetString(secondObjPtr, &l2);
+ const char *s1 = Jim_GetString(firstObjPtr, &l1);
+ const char *s2 = Jim_GetString(secondObjPtr, &l2);
if (nocase) {
- return JimStringCompareNoCase(s1, s2, -1);
+
+ return JimStringCompareLen(s1, s2, -1, nocase);
}
return JimStringCompare(s1, l1, s2, l2);
}
+int Jim_StringCompareLenObj(Jim_Interp *interp, Jim_Obj *firstObjPtr, Jim_Obj *secondObjPtr, int nocase)
+{
+ const char *s1 = Jim_String(firstObjPtr);
+ const char *s2 = Jim_String(secondObjPtr);
+
+ return JimStringCompareLen(s1, s2, Jim_Utf8Length(interp, firstObjPtr), nocase);
+}
+
static int JimRelToAbsIndex(int len, int idx)
{
if (idx < 0)
@@ -7727,35 +7716,47 @@ static int JimRelToAbsIndex(int len, int idx)
return idx;
}
-static void JimRelToAbsRange(int len, int first, int last,
- int *firstPtr, int *lastPtr, int *rangeLenPtr)
+static void JimRelToAbsRange(int len, int *firstPtr, int *lastPtr, int *rangeLenPtr)
{
int rangeLen;
- if (first > last) {
+ if (*firstPtr > *lastPtr) {
rangeLen = 0;
}
else {
- rangeLen = last - first + 1;
+ rangeLen = *lastPtr - *firstPtr + 1;
if (rangeLen) {
- if (first < 0) {
- rangeLen += first;
- first = 0;
+ if (*firstPtr < 0) {
+ rangeLen += *firstPtr;
+ *firstPtr = 0;
}
- if (last >= len) {
- rangeLen -= (last - (len - 1));
- last = len - 1;
+ if (*lastPtr >= len) {
+ rangeLen -= (*lastPtr - (len - 1));
+ *lastPtr = len - 1;
}
}
}
if (rangeLen < 0)
rangeLen = 0;
- *firstPtr = first;
- *lastPtr = last;
*rangeLenPtr = rangeLen;
}
+static int JimStringGetRange(Jim_Interp *interp, Jim_Obj *firstObjPtr, Jim_Obj *lastObjPtr,
+ int len, int *first, int *last, int *range)
+{
+ if (Jim_GetIndex(interp, firstObjPtr, first) != JIM_OK) {
+ return JIM_ERR;
+ }
+ if (Jim_GetIndex(interp, lastObjPtr, last) != JIM_OK) {
+ return JIM_ERR;
+ }
+ *first = JimRelToAbsIndex(len, *first);
+ *last = JimRelToAbsIndex(len, *last);
+ JimRelToAbsRange(len, first, last, range);
+ return JIM_OK;
+}
+
Jim_Obj *Jim_StringByteRangeObj(Jim_Interp *interp,
Jim_Obj *strObjPtr, Jim_Obj *firstObjPtr, Jim_Obj *lastObjPtr)
{
@@ -7764,13 +7765,12 @@ Jim_Obj *Jim_StringByteRangeObj(Jim_Interp *interp,
int rangeLen;
int bytelen;
- if (Jim_GetIndex(interp, firstObjPtr, &first) != JIM_OK ||
- Jim_GetIndex(interp, lastObjPtr, &last) != JIM_OK)
- return NULL;
str = Jim_GetString(strObjPtr, &bytelen);
- first = JimRelToAbsIndex(bytelen, first);
- last = JimRelToAbsIndex(bytelen, last);
- JimRelToAbsRange(bytelen, first, last, &first, &last, &rangeLen);
+
+ if (JimStringGetRange(interp, firstObjPtr, lastObjPtr, bytelen, &first, &last, &rangeLen) != JIM_OK) {
+ return NULL;
+ }
+
if (first == 0 && rangeLen == bytelen) {
return strObjPtr;
}
@@ -7786,14 +7786,13 @@ Jim_Obj *Jim_StringRangeObj(Jim_Interp *interp,
int len, rangeLen;
int bytelen;
- if (Jim_GetIndex(interp, firstObjPtr, &first) != JIM_OK ||
- Jim_GetIndex(interp, lastObjPtr, &last) != JIM_OK)
- return NULL;
str = Jim_GetString(strObjPtr, &bytelen);
len = Jim_Utf8Length(interp, strObjPtr);
- first = JimRelToAbsIndex(len, first);
- last = JimRelToAbsIndex(len, last);
- JimRelToAbsRange(len, first, last, &first, &last, &rangeLen);
+
+ if (JimStringGetRange(interp, firstObjPtr, lastObjPtr, len, &first, &last, &rangeLen) != JIM_OK) {
+ return NULL;
+ }
+
if (first == 0 && rangeLen == len) {
return strObjPtr;
}
@@ -7807,48 +7806,110 @@ Jim_Obj *Jim_StringRangeObj(Jim_Interp *interp,
#endif
}
-static Jim_Obj *JimStringToLower(Jim_Interp *interp, Jim_Obj *strObjPtr)
+Jim_Obj *JimStringReplaceObj(Jim_Interp *interp,
+ Jim_Obj *strObjPtr, Jim_Obj *firstObjPtr, Jim_Obj *lastObjPtr, Jim_Obj *newStrObj)
{
- char *buf, *p;
- int len;
+ int first, last;
const char *str;
+ int len, rangeLen;
+ Jim_Obj *objPtr;
- if (strObjPtr->typePtr != &stringObjType) {
- SetStringFromAny(interp, strObjPtr);
+ len = Jim_Utf8Length(interp, strObjPtr);
+
+ if (JimStringGetRange(interp, firstObjPtr, lastObjPtr, len, &first, &last, &rangeLen) != JIM_OK) {
+ return NULL;
}
- str = Jim_GetString(strObjPtr, &len);
+ if (last <= first) {
+ return strObjPtr;
+ }
- buf = p = Jim_Alloc(len + 1);
+ str = Jim_String(strObjPtr);
+
+
+ objPtr = Jim_NewStringObjUtf8(interp, str, first);
+
+
+ if (newStrObj) {
+ Jim_AppendObj(interp, objPtr, newStrObj);
+ }
+
+
+ Jim_AppendString(interp, objPtr, str + utf8_index(str, last + 1), len - last - 1);
+
+ return objPtr;
+}
+
+static void JimStrCopyUpperLower(char *dest, const char *str, int uc)
+{
while (*str) {
int c;
str += utf8_tounicode(str, &c);
- p += utf8_fromunicode(p, utf8_lower(c));
+ dest += utf8_fromunicode(dest, uc ? utf8_upper(c) : utf8_lower(c));
}
- *p = 0;
- return Jim_NewStringObjNoAlloc(interp, buf, len);
+ *dest = 0;
}
-static Jim_Obj *JimStringToUpper(Jim_Interp *interp, Jim_Obj *strObjPtr)
+static Jim_Obj *JimStringToLower(Jim_Interp *interp, Jim_Obj *strObjPtr)
{
- char *buf, *p;
+ char *buf;
int len;
const char *str;
+ SetStringFromAny(interp, strObjPtr);
+
+ str = Jim_GetString(strObjPtr, &len);
+
+#ifdef JIM_UTF8
+ len *= 2;
+#endif
+ buf = Jim_Alloc(len + 1);
+ JimStrCopyUpperLower(buf, str, 0);
+ return Jim_NewStringObjNoAlloc(interp, buf, -1);
+}
+
+static Jim_Obj *JimStringToUpper(Jim_Interp *interp, Jim_Obj *strObjPtr)
+{
+ char *buf;
+ const char *str;
+ int len;
+
if (strObjPtr->typePtr != &stringObjType) {
SetStringFromAny(interp, strObjPtr);
}
str = Jim_GetString(strObjPtr, &len);
- buf = p = Jim_Alloc(len + 1);
- while (*str) {
- int c;
- str += utf8_tounicode(str, &c);
- p += utf8_fromunicode(p, utf8_upper(c));
+#ifdef JIM_UTF8
+ len *= 2;
+#endif
+ buf = Jim_Alloc(len + 1);
+ JimStrCopyUpperLower(buf, str, 1);
+ return Jim_NewStringObjNoAlloc(interp, buf, -1);
+}
+
+static Jim_Obj *JimStringToTitle(Jim_Interp *interp, Jim_Obj *strObjPtr)
+{
+ char *buf, *p;
+ int len;
+ int c;
+ const char *str;
+
+ str = Jim_GetString(strObjPtr, &len);
+ if (len == 0) {
+ return strObjPtr;
}
- *p = 0;
- return Jim_NewStringObjNoAlloc(interp, buf, len);
+#ifdef JIM_UTF8
+ len *= 2;
+#endif
+ buf = p = Jim_Alloc(len + 1);
+
+ str += utf8_tounicode(str, &c);
+ p += utf8_fromunicode(p, utf8_title(c));
+
+ JimStrCopyUpperLower(p, str, 0);
+
+ return Jim_NewStringObjNoAlloc(interp, buf, -1);
}
static const char *utf8_memchr(const char *str, int len, int c)
@@ -7941,9 +8002,8 @@ static Jim_Obj *JimStringTrimRight(Jim_Interp *interp, Jim_Obj *strObjPtr, Jim_O
trimchars = Jim_GetString(trimcharsObjPtr, &trimcharslen);
}
- if (strObjPtr->typePtr != &stringObjType) {
- SetStringFromAny(interp, strObjPtr);
- }
+ SetStringFromAny(interp, strObjPtr);
+
len = Jim_Length(strObjPtr);
nontrim = JimFindTrimRight(strObjPtr->bytes, len, trimchars, trimcharslen);
@@ -8182,7 +8242,8 @@ typedef struct ScriptObj
only used by Jim_EvalObj() as protection against
shimmering of the currently evaluated object. */
Jim_Obj *fileNameObj;
- int line;
+ int firstline;
+ int linenr;
} ScriptObj;
void FreeScriptInternalRep(Jim_Interp *interp, Jim_Obj *objPtr)
@@ -8334,7 +8395,7 @@ static void ScriptObjAddTokens(Jim_Interp *interp, struct ScriptObj *script,
count++;
}
}
- linenr = script->line = tokenlist->list[0].line;
+ linenr = script->firstline = tokenlist->list[0].line;
token = script->token = Jim_Alloc(sizeof(ScriptToken) * count);
@@ -8475,7 +8536,6 @@ static int SetScriptFromAny(Jim_Interp *interp, struct Jim_Obj *objPtr, struct J
script = Jim_Alloc(sizeof(*script));
memset(script, 0, sizeof(*script));
script->inUse = 1;
- script->line = line;
if (objPtr->typePtr == &sourceObjType) {
script->fileNameObj = objPtr->internalRep.sourceValue.fileNameObj;
}
@@ -8518,14 +8578,11 @@ static void JimDecrCmdRefCount(Jim_Interp *interp, Jim_Cmd *cmdPtr)
if (cmdPtr->isproc) {
Jim_DecrRefCount(interp, cmdPtr->u.proc.argListObjPtr);
Jim_DecrRefCount(interp, cmdPtr->u.proc.bodyObjPtr);
+ Jim_DecrRefCount(interp, cmdPtr->u.proc.nsObj);
if (cmdPtr->u.proc.staticVars) {
Jim_FreeHashTable(cmdPtr->u.proc.staticVars);
Jim_Free(cmdPtr->u.proc.staticVars);
}
- if (cmdPtr->u.proc.prevCmd) {
-
- JimDecrCmdRefCount(interp, cmdPtr->u.proc.prevCmd);
- }
}
else {
@@ -8533,37 +8590,121 @@ static void JimDecrCmdRefCount(Jim_Interp *interp, Jim_Cmd *cmdPtr)
cmdPtr->u.native.delProc(interp, cmdPtr->u.native.privData);
}
}
+ if (cmdPtr->prevCmd) {
+
+ JimDecrCmdRefCount(interp, cmdPtr->prevCmd);
+ }
Jim_Free(cmdPtr);
}
}
-static void JimCommandsHT_ValDestructor(void *interp, void *val)
+
+static void JimVariablesHTValDestructor(void *interp, void *val)
{
- JimDecrCmdRefCount(interp, val);
+ Jim_DecrRefCount(interp, ((Jim_Var *)val)->objPtr);
+ Jim_Free(val);
}
-static const Jim_HashTableType JimCommandsHashTableType = {
+static const Jim_HashTableType JimVariablesHashTableType = {
JimStringCopyHTHashFunction,
- JimStringCopyHTKeyDup,
- NULL,
+ JimStringCopyHTDup,
+ NULL,
JimStringCopyHTKeyCompare,
JimStringCopyHTKeyDestructor,
- JimCommandsHT_ValDestructor
+ JimVariablesHTValDestructor
+};
+
+static void JimCommandsHT_ValDestructor(void *interp, void *val)
+{
+ JimDecrCmdRefCount(interp, val);
+}
+
+static const Jim_HashTableType JimCommandsHashTableType = {
+ JimStringCopyHTHashFunction,
+ JimStringCopyHTDup,
+ NULL,
+ JimStringCopyHTKeyCompare,
+ JimStringCopyHTKeyDestructor,
+ JimCommandsHT_ValDestructor
};
-int Jim_CreateCommand(Jim_Interp *interp, const char *cmdName,
- Jim_CmdProc cmdProc, void *privData, Jim_DelCmdProc delProc)
+#ifdef jim_ext_namespace
+static Jim_Obj *JimQualifyNameObj(Jim_Interp *interp, Jim_Obj *nsObj)
{
- Jim_Cmd *cmdPtr;
+ const char *name = Jim_String(nsObj);
+ if (name[0] == ':' && name[1] == ':') {
+
+ while (*++name == ':') {
+ }
+ nsObj = Jim_NewStringObj(interp, name, -1);
+ }
+ else if (Jim_Length(interp->framePtr->nsObj)) {
+
+ nsObj = Jim_DuplicateObj(interp, interp->framePtr->nsObj);
+ Jim_AppendStrings(interp, nsObj, "::", name, NULL);
+ }
+ return nsObj;
+}
+
+static const char *JimQualifyName(Jim_Interp *interp, const char *name, Jim_Obj **objPtrPtr)
+{
+ Jim_Obj *objPtr = interp->emptyObj;
- if (Jim_DeleteHashEntry(&interp->commands, cmdName) != JIM_ERR) {
+ if (name[0] == ':' && name[1] == ':') {
+ while (*++name == ':') {
+ }
+ }
+ else if (Jim_Length(interp->framePtr->nsObj)) {
+
+ objPtr = Jim_DuplicateObj(interp, interp->framePtr->nsObj);
+ Jim_AppendStrings(interp, objPtr, "::", name, NULL);
+ name = Jim_String(objPtr);
+ }
+ Jim_IncrRefCount(objPtr);
+ *objPtrPtr = objPtr;
+ return name;
+}
+
+ #define JimFreeQualifiedName(INTERP, OBJ) Jim_DecrRefCount((INTERP), (OBJ))
+
+#else
+
+ #define JimQualifyName(INTERP, NAME, DUMMY) (((NAME)[0] == ':' && (NAME)[1] == ':') ? (NAME) + 2 : (NAME))
+ #define JimFreeQualifiedName(INTERP, DUMMY) (void)(DUMMY)
+#endif
+
+static int JimCreateCommand(Jim_Interp *interp, const char *name, Jim_Cmd *cmd)
+{
+ Jim_HashEntry *he = Jim_FindHashEntry(&interp->commands, name);
+ if (he) {
+
Jim_InterpIncrProcEpoch(interp);
}
- cmdPtr = Jim_Alloc(sizeof(*cmdPtr));
+ if (he && interp->local) {
+
+ cmd->prevCmd = he->u.val;
+ he->u.val = cmd;
+ }
+ else {
+ if (he) {
+
+ Jim_DeleteHashEntry(&interp->commands, name);
+ }
+
+ Jim_AddHashEntry(&interp->commands, name, cmd);
+ }
+ return JIM_OK;
+}
+
+
+int Jim_CreateCommand(Jim_Interp *interp, const char *cmdNameStr,
+ Jim_CmdProc cmdProc, void *privData, Jim_DelCmdProc delProc)
+{
+ Jim_Cmd *cmdPtr = Jim_Alloc(sizeof(*cmdPtr));
memset(cmdPtr, 0, sizeof(*cmdPtr));
@@ -8572,23 +8713,97 @@ int Jim_CreateCommand(Jim_Interp *interp, const char *cmdName,
cmdPtr->u.native.cmdProc = cmdProc;
cmdPtr->u.native.privData = privData;
- Jim_AddHashEntry(&interp->commands, cmdName, cmdPtr);
+ JimCreateCommand(interp, cmdNameStr, cmdPtr);
+
+ return JIM_OK;
+}
+
+static int JimCreateProcedureStatics(Jim_Interp *interp, Jim_Cmd *cmdPtr, Jim_Obj *staticsListObjPtr)
+{
+ int len, i;
+
+ len = Jim_ListLength(interp, staticsListObjPtr);
+ if (len == 0) {
+ return JIM_OK;
+ }
+
+ cmdPtr->u.proc.staticVars = Jim_Alloc(sizeof(Jim_HashTable));
+ Jim_InitHashTable(cmdPtr->u.proc.staticVars, &JimVariablesHashTableType, interp);
+ for (i = 0; i < len; i++) {
+ Jim_Obj *objPtr = NULL, *initObjPtr = NULL, *nameObjPtr = NULL;
+ Jim_Var *varPtr;
+ int subLen;
+
+ Jim_ListIndex(interp, staticsListObjPtr, i, &objPtr, JIM_NONE);
+
+ subLen = Jim_ListLength(interp, objPtr);
+ if (subLen == 1 || subLen == 2) {
+ Jim_ListIndex(interp, objPtr, 0, &nameObjPtr, JIM_NONE);
+ if (subLen == 1) {
+ initObjPtr = Jim_GetVariable(interp, nameObjPtr, JIM_NONE);
+ if (initObjPtr == NULL) {
+ Jim_SetResultFormatted(interp,
+ "variable for initialization of static \"%#s\" not found in the local context",
+ nameObjPtr);
+ return JIM_ERR;
+ }
+ }
+ else {
+ Jim_ListIndex(interp, objPtr, 1, &initObjPtr, JIM_NONE);
+ }
+ if (JimValidName(interp, "static variable", nameObjPtr) != JIM_OK) {
+ return JIM_ERR;
+ }
+ varPtr = Jim_Alloc(sizeof(*varPtr));
+ varPtr->objPtr = initObjPtr;
+ Jim_IncrRefCount(initObjPtr);
+ varPtr->linkFramePtr = NULL;
+ if (Jim_AddHashEntry(cmdPtr->u.proc.staticVars,
+ Jim_String(nameObjPtr), varPtr) != JIM_OK) {
+ Jim_SetResultFormatted(interp,
+ "static variable name \"%#s\" duplicated in statics list", nameObjPtr);
+ Jim_DecrRefCount(interp, initObjPtr);
+ Jim_Free(varPtr);
+ return JIM_ERR;
+ }
+ }
+ else {
+ Jim_SetResultFormatted(interp, "too many fields in static specifier \"%#s\"",
+ objPtr);
+ return JIM_ERR;
+ }
+ }
return JIM_OK;
}
-static int JimCreateProcedure(Jim_Interp *interp, Jim_Obj *cmdName,
- Jim_Obj *argListObjPtr, Jim_Obj *staticsListObjPtr, Jim_Obj *bodyObjPtr)
+static void JimUpdateProcNamespace(Jim_Interp *interp, Jim_Cmd *cmdPtr, const char *cmdname)
+{
+#ifdef jim_ext_namespace
+ if (cmdPtr->isproc) {
+
+ const char *pt = strrchr(cmdname, ':');
+ if (pt && pt != cmdname && pt[-1] == ':') {
+ Jim_DecrRefCount(interp, cmdPtr->u.proc.nsObj);
+ cmdPtr->u.proc.nsObj = Jim_NewStringObj(interp, cmdname, pt - cmdname - 1);
+ Jim_IncrRefCount(cmdPtr->u.proc.nsObj);
+
+ if (Jim_FindHashEntry(&interp->commands, pt + 1)) {
+
+ Jim_InterpIncrProcEpoch(interp);
+ }
+ }
+ }
+#endif
+}
+
+static Jim_Cmd *JimCreateProcedureCmd(Jim_Interp *interp, Jim_Obj *argListObjPtr,
+ Jim_Obj *staticsListObjPtr, Jim_Obj *bodyObjPtr, Jim_Obj *nsObj)
{
Jim_Cmd *cmdPtr;
- Jim_HashEntry *he;
int argListLen;
int i;
- if (JimValidName(interp, "procedure", cmdName) != JIM_OK) {
- return JIM_ERR;
- }
-
argListLen = Jim_ListLength(interp, argListObjPtr);
@@ -8601,63 +8816,14 @@ static int JimCreateProcedure(Jim_Interp *interp, Jim_Obj *cmdName,
cmdPtr->u.proc.bodyObjPtr = bodyObjPtr;
cmdPtr->u.proc.argsPos = -1;
cmdPtr->u.proc.arglist = (struct Jim_ProcArg *)(cmdPtr + 1);
+ cmdPtr->u.proc.nsObj = nsObj ? nsObj : interp->emptyObj;
Jim_IncrRefCount(argListObjPtr);
Jim_IncrRefCount(bodyObjPtr);
+ Jim_IncrRefCount(cmdPtr->u.proc.nsObj);
- if (staticsListObjPtr) {
- int len, i;
-
- len = Jim_ListLength(interp, staticsListObjPtr);
- if (len != 0) {
- cmdPtr->u.proc.staticVars = Jim_Alloc(sizeof(Jim_HashTable));
- Jim_InitHashTable(cmdPtr->u.proc.staticVars, &JimVariablesHashTableType, interp);
- for (i = 0; i < len; i++) {
- Jim_Obj *objPtr = 0, *initObjPtr = 0, *nameObjPtr = 0;
- Jim_Var *varPtr;
- int subLen;
-
- Jim_ListIndex(interp, staticsListObjPtr, i, &objPtr, JIM_NONE);
-
- subLen = Jim_ListLength(interp, objPtr);
- if (subLen == 1 || subLen == 2) {
- Jim_ListIndex(interp, objPtr, 0, &nameObjPtr, JIM_NONE);
- if (subLen == 1) {
- initObjPtr = Jim_GetVariable(interp, nameObjPtr, JIM_NONE);
- if (initObjPtr == NULL) {
- Jim_SetResultFormatted(interp,
- "variable for initialization of static \"%#s\" not found in the local context",
- nameObjPtr);
- goto err;
- }
- }
- else {
- Jim_ListIndex(interp, objPtr, 1, &initObjPtr, JIM_NONE);
- }
- if (JimValidName(interp, "static variable", nameObjPtr) != JIM_OK) {
- goto err;
- }
-
- varPtr = Jim_Alloc(sizeof(*varPtr));
- varPtr->objPtr = initObjPtr;
- Jim_IncrRefCount(initObjPtr);
- varPtr->linkFramePtr = NULL;
- if (Jim_AddHashEntry(cmdPtr->u.proc.staticVars,
- Jim_String(nameObjPtr), varPtr) != JIM_OK) {
- Jim_SetResultFormatted(interp,
- "static variable name \"%#s\" duplicated in statics list", nameObjPtr);
- Jim_DecrRefCount(interp, initObjPtr);
- Jim_Free(varPtr);
- goto err;
- }
- }
- else {
- Jim_SetResultFormatted(interp, "too many fields in static specifier \"%#s\"",
- objPtr);
- goto err;
- }
- }
- }
+ if (staticsListObjPtr && JimCreateProcedureStatics(interp, cmdPtr, staticsListObjPtr) != JIM_OK) {
+ goto err;
}
@@ -8667,17 +8833,18 @@ static int JimCreateProcedure(Jim_Interp *interp, Jim_Obj *cmdName,
Jim_Obj *nameObjPtr;
Jim_Obj *defaultObjPtr;
int len;
- int n = 1;
Jim_ListIndex(interp, argListObjPtr, i, &argPtr, JIM_NONE);
len = Jim_ListLength(interp, argPtr);
if (len == 0) {
- Jim_SetResultString(interp, "procedure has argument with no name", -1);
- goto err;
+ Jim_SetResultString(interp, "argument with no name", -1);
+err:
+ JimDecrCmdRefCount(interp, cmdPtr);
+ return NULL;
}
if (len > 2) {
- Jim_SetResultString(interp, "procedure has argument with too many fields", -1);
+ Jim_SetResultFormatted(interp, "too many fields in argument specifier \"%#s\"", argPtr);
goto err;
}
@@ -8695,17 +8862,17 @@ static int JimCreateProcedure(Jim_Interp *interp, Jim_Obj *cmdName,
if (Jim_CompareStringImmediate(interp, nameObjPtr, "args")) {
if (cmdPtr->u.proc.argsPos >= 0) {
- Jim_SetResultString(interp, "procedure has 'args' specified more than once", -1);
+ Jim_SetResultString(interp, "'args' specified more than once", -1);
goto err;
}
cmdPtr->u.proc.argsPos = i;
}
else {
if (len == 2) {
- cmdPtr->u.proc.optArity += n;
+ cmdPtr->u.proc.optArity++;
}
else {
- cmdPtr->u.proc.reqArity += n;
+ cmdPtr->u.proc.reqArity++;
}
}
@@ -8713,152 +8880,160 @@ static int JimCreateProcedure(Jim_Interp *interp, Jim_Obj *cmdName,
cmdPtr->u.proc.arglist[i].defaultObjPtr = defaultObjPtr;
}
-
-
- he = Jim_FindHashEntry(&interp->commands, Jim_String(cmdName));
- if (he) {
+ return cmdPtr;
+}
- Jim_InterpIncrProcEpoch(interp);
- }
+int Jim_DeleteCommand(Jim_Interp *interp, const char *name)
+{
+ int ret = JIM_OK;
+ Jim_Obj *qualifiedNameObj;
+ const char *qualname = JimQualifyName(interp, name, &qualifiedNameObj);
- if (he && interp->local) {
-
- cmdPtr->u.proc.prevCmd = he->u.val;
- he->u.val = cmdPtr;
+ if (Jim_DeleteHashEntry(&interp->commands, qualname) == JIM_ERR) {
+ Jim_SetResultFormatted(interp, "can't delete \"%s\": command doesn't exist", name);
+ ret = JIM_ERR;
}
else {
- if (he) {
-
- Jim_DeleteHashEntry(&interp->commands, Jim_String(cmdName));
- }
-
- Jim_AddHashEntry(&interp->commands, Jim_String(cmdName), cmdPtr);
+ Jim_InterpIncrProcEpoch(interp);
}
-
- Jim_SetResult(interp, cmdName);
- return JIM_OK;
-
- err:
- if (cmdPtr->u.proc.staticVars) {
- Jim_FreeHashTable(cmdPtr->u.proc.staticVars);
- }
- Jim_Free(cmdPtr->u.proc.staticVars);
- Jim_DecrRefCount(interp, argListObjPtr);
- Jim_DecrRefCount(interp, bodyObjPtr);
- Jim_Free(cmdPtr);
- return JIM_ERR;
-}
+ JimFreeQualifiedName(interp, qualifiedNameObj);
-int Jim_DeleteCommand(Jim_Interp *interp, const char *cmdName)
-{
- if (Jim_DeleteHashEntry(&interp->commands, cmdName) == JIM_ERR)
- return JIM_ERR;
- Jim_InterpIncrProcEpoch(interp);
- return JIM_OK;
+ return ret;
}
int Jim_RenameCommand(Jim_Interp *interp, const char *oldName, const char *newName)
{
+ int ret = JIM_ERR;
Jim_HashEntry *he;
+ Jim_Cmd *cmdPtr;
+ Jim_Obj *qualifiedOldNameObj;
+ Jim_Obj *qualifiedNewNameObj;
+ const char *fqold;
+ const char *fqnew;
-
- he = Jim_FindHashEntry(&interp->commands, oldName);
- if (he == NULL) {
- Jim_SetResultFormatted(interp, "can't %s \"%s\": command doesn't exist",
- newName[0] ? "rename" : "delete", oldName);
- return JIM_ERR;
+ if (newName[0] == 0) {
+ return Jim_DeleteCommand(interp, oldName);
}
- if (newName[0] == '\0')
- return Jim_DeleteCommand(interp, oldName);
+ fqold = JimQualifyName(interp, oldName, &qualifiedOldNameObj);
+ fqnew = JimQualifyName(interp, newName, &qualifiedNewNameObj);
- if (Jim_FindHashEntry(&interp->commands, newName)) {
+ he = Jim_FindHashEntry(&interp->commands, fqold);
+ if (he == NULL) {
+ Jim_SetResultFormatted(interp, "can't rename \"%s\": command doesn't exist", oldName);
+ }
+ else if (Jim_FindHashEntry(&interp->commands, fqnew)) {
Jim_SetResultFormatted(interp, "can't rename to \"%s\": command already exists", newName);
- return JIM_ERR;
}
+ else {
+
+ cmdPtr = he->u.val;
+ JimIncrCmdRefCount(cmdPtr);
+ JimUpdateProcNamespace(interp, cmdPtr, fqnew);
+ Jim_AddHashEntry(&interp->commands, fqnew, cmdPtr);
-
- JimIncrCmdRefCount(he->u.val);
- Jim_AddHashEntry(&interp->commands, newName, he->u.val);
+
+ Jim_DeleteHashEntry(&interp->commands, fqold);
-
- Jim_DeleteHashEntry(&interp->commands, oldName);
+
+ Jim_InterpIncrProcEpoch(interp);
-
- Jim_InterpIncrProcEpoch(interp);
- return JIM_OK;
+ ret = JIM_OK;
+ }
+
+ JimFreeQualifiedName(interp, qualifiedOldNameObj);
+ JimFreeQualifiedName(interp, qualifiedNewNameObj);
+
+ return ret;
}
-static int SetCommandFromAny(Jim_Interp *interp, struct Jim_Obj *objPtr);
+static void FreeCommandInternalRep(Jim_Interp *interp, Jim_Obj *objPtr)
+{
+ Jim_DecrRefCount(interp, objPtr->internalRep.cmdValue.nsObj);
+}
+
+static void DupCommandInternalRep(Jim_Interp *interp, Jim_Obj *srcPtr, Jim_Obj *dupPtr)
+{
+ dupPtr->internalRep.cmdValue = srcPtr->internalRep.cmdValue;
+ dupPtr->typePtr = srcPtr->typePtr;
+ Jim_IncrRefCount(dupPtr->internalRep.cmdValue.nsObj);
+}
static const Jim_ObjType commandObjType = {
"command",
- NULL,
- NULL,
+ FreeCommandInternalRep,
+ DupCommandInternalRep,
NULL,
JIM_TYPE_REFERENCES,
};
-int SetCommandFromAny(Jim_Interp *interp, Jim_Obj *objPtr)
+Jim_Cmd *Jim_GetCommand(Jim_Interp *interp, Jim_Obj *objPtr, int flags)
{
- Jim_HashEntry *he;
- const char *cmdName;
+ Jim_Cmd *cmd;
-
- cmdName = Jim_String(objPtr);
-
- he = Jim_FindHashEntry(&interp->commands, cmdName);
- if (he == NULL)
- return JIM_ERR;
+ if (objPtr->typePtr != &commandObjType ||
+ objPtr->internalRep.cmdValue.procEpoch != interp->procEpoch
+#ifdef jim_ext_namespace
+ || !Jim_StringEqObj(objPtr->internalRep.cmdValue.nsObj, interp->framePtr->nsObj)
+#endif
+ ) {
+
-
- Jim_FreeIntRep(interp, objPtr);
- objPtr->typePtr = &commandObjType;
- objPtr->internalRep.cmdValue.procEpoch = interp->procEpoch;
- objPtr->internalRep.cmdValue.cmdPtr = (void *)he->u.val;
- return JIM_OK;
-}
+
+ const char *name = Jim_String(objPtr);
+ Jim_HashEntry *he;
-Jim_Cmd *Jim_GetCommand(Jim_Interp *interp, Jim_Obj *objPtr, int flags)
-{
- Jim_Cmd *cmd;
+ if (name[0] == ':' && name[1] == ':') {
+ while (*++name == ':') {
+ }
+ }
+#ifdef jim_ext_namespace
+ else if (Jim_Length(interp->framePtr->nsObj)) {
+
+ Jim_Obj *nameObj = Jim_DuplicateObj(interp, interp->framePtr->nsObj);
+ Jim_AppendStrings(interp, nameObj, "::", name, NULL);
+ he = Jim_FindHashEntry(&interp->commands, Jim_String(nameObj));
+ Jim_FreeNewObj(interp, nameObj);
+ if (he) {
+ goto found;
+ }
+ }
+#endif
- if ((objPtr->typePtr != &commandObjType ||
- objPtr->internalRep.cmdValue.procEpoch != interp->procEpoch) &&
- SetCommandFromAny(interp, objPtr) == JIM_ERR) {
- if (flags & JIM_ERRMSG) {
- Jim_SetResultFormatted(interp, "invalid command name \"%#s\"", objPtr);
+
+ he = Jim_FindHashEntry(&interp->commands, name);
+ if (he == NULL) {
+ if (flags & JIM_ERRMSG) {
+ Jim_SetResultFormatted(interp, "invalid command name \"%#s\"", objPtr);
+ }
+ return NULL;
}
- return NULL;
+#ifdef jim_ext_namespace
+found:
+#endif
+ cmd = (Jim_Cmd *)he->u.val;
+
+
+ Jim_FreeIntRep(interp, objPtr);
+ objPtr->typePtr = &commandObjType;
+ objPtr->internalRep.cmdValue.procEpoch = interp->procEpoch;
+ objPtr->internalRep.cmdValue.cmdPtr = cmd;
+ objPtr->internalRep.cmdValue.nsObj = interp->framePtr->nsObj;
+ Jim_IncrRefCount(interp->framePtr->nsObj);
+ }
+ else {
+ cmd = objPtr->internalRep.cmdValue.cmdPtr;
}
- cmd = objPtr->internalRep.cmdValue.cmdPtr;
- while (cmd->isproc && cmd->u.proc.upcall) {
- cmd = cmd->u.proc.prevCmd;
+ while (cmd->u.proc.upcall) {
+ cmd = cmd->prevCmd;
}
return cmd;
}
-static void JimVariablesHTValDestructor(void *interp, void *val)
-{
- Jim_Var *varPtr = (void *)val;
-
- Jim_DecrRefCount(interp, varPtr->objPtr);
- Jim_Free(val);
-}
-
-static const Jim_HashTableType JimVariablesHashTableType = {
- JimStringCopyHTHashFunction,
- JimStringCopyHTKeyDup,
- NULL,
- JimStringCopyHTKeyCompare,
- JimStringCopyHTKeyDestructor,
- JimVariablesHTValDestructor
-};
-
#define JIM_DICT_SUGAR 100
@@ -8872,13 +9047,6 @@ static const Jim_ObjType variableObjType = {
JIM_TYPE_REFERENCES,
};
-static int JimNameIsDictSugar(const char *str, int len)
-{
- if (len && str[len - 1] == ')' && strchr(str, '(') != NULL)
- return 1;
- return 0;
-}
-
static int JimValidName(Jim_Interp *interp, const char *type, Jim_Obj *nameObjPtr)
{
@@ -8895,56 +9063,65 @@ static int JimValidName(Jim_Interp *interp, const char *type, Jim_Obj *nameObjPt
static int SetVariableFromAny(Jim_Interp *interp, struct Jim_Obj *objPtr)
{
- Jim_HashEntry *he;
const char *varName;
+ Jim_CallFrame *framePtr;
+ Jim_HashEntry *he;
+ int global;
int len;
- Jim_CallFrame *framePtr = interp->framePtr;
- if (objPtr->typePtr == &variableObjType &&
- objPtr->internalRep.varValue.callFrameId == framePtr->id) {
- return JIM_OK;
+ if (objPtr->typePtr == &variableObjType) {
+ framePtr = objPtr->internalRep.varValue.global ? interp->topFramePtr : interp->framePtr;
+ if (objPtr->internalRep.varValue.callFrameId == framePtr->id) {
+
+ return JIM_OK;
+ }
+
}
-
- if (objPtr->typePtr == &dictSubstObjType) {
+ else if (objPtr->typePtr == &dictSubstObjType) {
return JIM_DICT_SUGAR;
}
-
- if (JimValidName(interp, "variable", objPtr) != JIM_OK) {
+ else if (JimValidName(interp, "variable", objPtr) != JIM_OK) {
return JIM_ERR;
}
-
+
varName = Jim_GetString(objPtr, &len);
- if (JimNameIsDictSugar(varName, len)) {
+ if (len && varName[len - 1] == ')' && strchr(varName, '(') != NULL) {
return JIM_DICT_SUGAR;
}
if (varName[0] == ':' && varName[1] == ':') {
- framePtr = interp->topFramePtr;
- he = Jim_FindHashEntry(&framePtr->vars, varName + 2);
- if (he == NULL) {
- return JIM_ERR;
+ while (*++varName == ':') {
}
+ global = 1;
+ framePtr = interp->topFramePtr;
}
else {
-
- he = Jim_FindHashEntry(&framePtr->vars, varName);
- if (he == NULL) {
+ global = 0;
+ framePtr = interp->framePtr;
+ }
+
+
+ he = Jim_FindHashEntry(&framePtr->vars, varName);
+ if (he == NULL) {
+ if (!global && framePtr->staticVars) {
- if (framePtr->staticVars == NULL)
- return JIM_ERR;
- if (!(he = Jim_FindHashEntry(framePtr->staticVars, varName)))
- return JIM_ERR;
+ he = Jim_FindHashEntry(framePtr->staticVars, varName);
+ }
+ if (he == NULL) {
+ return JIM_ERR;
}
}
+
Jim_FreeIntRep(interp, objPtr);
objPtr->typePtr = &variableObjType;
objPtr->internalRep.varValue.callFrameId = framePtr->id;
- objPtr->internalRep.varValue.varPtr = (void *)he->u.val;
+ objPtr->internalRep.varValue.varPtr = he->u.val;
+ objPtr->internalRep.varValue.global = global;
return JIM_OK;
}
@@ -8952,63 +9129,78 @@ static int SetVariableFromAny(Jim_Interp *interp, struct Jim_Obj *objPtr)
static int JimDictSugarSet(Jim_Interp *interp, Jim_Obj *ObjPtr, Jim_Obj *valObjPtr);
static Jim_Obj *JimDictSugarGet(Jim_Interp *interp, Jim_Obj *ObjPtr, int flags);
-
-int Jim_SetVariable(Jim_Interp *interp, Jim_Obj *nameObjPtr, Jim_Obj *valObjPtr)
+static Jim_Var *JimCreateVariable(Jim_Interp *interp, Jim_Obj *nameObjPtr, Jim_Obj *valObjPtr)
{
const char *name;
- Jim_Var *var;
- int err;
-
- if ((err = SetVariableFromAny(interp, nameObjPtr)) != JIM_OK) {
- Jim_CallFrame *framePtr = interp->framePtr;
-
-
- if (err == JIM_DICT_SUGAR)
- return JimDictSugarSet(interp, nameObjPtr, valObjPtr);
+ Jim_CallFrame *framePtr;
+ int global;
- if (JimValidName(interp, "variable", nameObjPtr) != JIM_OK) {
- return JIM_ERR;
- }
+
+ Jim_Var *var = Jim_Alloc(sizeof(*var));
-
- name = Jim_String(nameObjPtr);
+ var->objPtr = valObjPtr;
+ Jim_IncrRefCount(valObjPtr);
+ var->linkFramePtr = NULL;
- var = Jim_Alloc(sizeof(*var));
- var->objPtr = valObjPtr;
- Jim_IncrRefCount(valObjPtr);
- var->linkFramePtr = NULL;
-
- if (name[0] == ':' && name[1] == ':') {
-
- framePtr = interp->topFramePtr;
- Jim_AddHashEntry(&framePtr->vars, name + 2, var);
+ name = Jim_String(nameObjPtr);
+ if (name[0] == ':' && name[1] == ':') {
+ while (*++name == ':') {
}
- else {
- Jim_AddHashEntry(&framePtr->vars, name, var);
- }
-
- Jim_FreeIntRep(interp, nameObjPtr);
- nameObjPtr->typePtr = &variableObjType;
- nameObjPtr->internalRep.varValue.callFrameId = framePtr->id;
- nameObjPtr->internalRep.varValue.varPtr = var;
+ framePtr = interp->topFramePtr;
+ global = 1;
}
else {
- var = nameObjPtr->internalRep.varValue.varPtr;
- if (var->linkFramePtr == NULL) {
- Jim_IncrRefCount(valObjPtr);
- Jim_DecrRefCount(interp, var->objPtr);
- var->objPtr = valObjPtr;
- }
- else {
- Jim_CallFrame *savedCallFrame;
+ framePtr = interp->framePtr;
+ global = 0;
+ }
- savedCallFrame = interp->framePtr;
- interp->framePtr = var->linkFramePtr;
- err = Jim_SetVariable(interp, var->objPtr, valObjPtr);
- interp->framePtr = savedCallFrame;
- if (err != JIM_OK)
- return err;
- }
+
+ Jim_AddHashEntry(&framePtr->vars, name, var);
+
+
+ Jim_FreeIntRep(interp, nameObjPtr);
+ nameObjPtr->typePtr = &variableObjType;
+ nameObjPtr->internalRep.varValue.callFrameId = framePtr->id;
+ nameObjPtr->internalRep.varValue.varPtr = var;
+ nameObjPtr->internalRep.varValue.global = global;
+
+ return var;
+}
+
+
+int Jim_SetVariable(Jim_Interp *interp, Jim_Obj *nameObjPtr, Jim_Obj *valObjPtr)
+{
+ int err;
+ Jim_Var *var;
+
+ switch (SetVariableFromAny(interp, nameObjPtr)) {
+ case JIM_DICT_SUGAR:
+ return JimDictSugarSet(interp, nameObjPtr, valObjPtr);
+
+ case JIM_ERR:
+ if (JimValidName(interp, "variable", nameObjPtr) != JIM_OK) {
+ return JIM_ERR;
+ }
+ JimCreateVariable(interp, nameObjPtr, valObjPtr);
+ break;
+
+ case JIM_OK:
+ var = nameObjPtr->internalRep.varValue.varPtr;
+ if (var->linkFramePtr == NULL) {
+ Jim_IncrRefCount(valObjPtr);
+ Jim_DecrRefCount(interp, var->objPtr);
+ var->objPtr = valObjPtr;
+ }
+ else {
+ Jim_CallFrame *savedCallFrame;
+
+ savedCallFrame = interp->framePtr;
+ interp->framePtr = var->linkFramePtr;
+ err = Jim_SetVariable(interp, var->objPtr, valObjPtr);
+ interp->framePtr = savedCallFrame;
+ if (err != JIM_OK)
+ return err;
+ }
}
return JIM_OK;
}
@@ -9056,42 +9248,70 @@ int Jim_SetVariableLink(Jim_Interp *interp, Jim_Obj *nameObjPtr,
Jim_Obj *targetNameObjPtr, Jim_CallFrame *targetCallFrame)
{
const char *varName;
- int len;
+ const char *targetName;
+ Jim_CallFrame *framePtr;
+ Jim_Var *varPtr;
- varName = Jim_GetString(nameObjPtr, &len);
+
+ switch (SetVariableFromAny(interp, nameObjPtr)) {
+ case JIM_DICT_SUGAR:
+
+ Jim_SetResultFormatted(interp, "bad variable name \"%#s\": upvar won't create a scalar variable that looks like an array element", nameObjPtr);
+ return JIM_ERR;
- if (varName[0] == ':' && varName[1] == ':') {
-
- return JIM_OK;
- }
+ case JIM_OK:
+ varPtr = nameObjPtr->internalRep.varValue.varPtr;
- if (JimNameIsDictSugar(varName, len)) {
- Jim_SetResultString(interp, "Dict key syntax invalid as link source", -1);
- return JIM_ERR;
+ if (varPtr->linkFramePtr == NULL) {
+ Jim_SetResultFormatted(interp, "variable \"%#s\" already exists", nameObjPtr);
+ return JIM_ERR;
+ }
+
+
+ varPtr->linkFramePtr = NULL;
+ break;
}
- if (SetVariableFromAny(interp, nameObjPtr) == JIM_OK) {
- Jim_Var *varPtr = nameObjPtr->internalRep.varValue.varPtr;
+
+ varName = Jim_String(nameObjPtr);
- if (varPtr->linkFramePtr == NULL) {
- Jim_SetResultFormatted(interp, "variable \"%#s\" already exists", nameObjPtr);
- return JIM_ERR;
+ if (varName[0] == ':' && varName[1] == ':') {
+ while (*++varName == ':') {
}
-
- varPtr->linkFramePtr = NULL;
+ framePtr = interp->topFramePtr;
+ }
+ else {
+ framePtr = interp->framePtr;
+ }
+
+ targetName = Jim_String(targetNameObjPtr);
+ if (targetName[0] == ':' && targetName[1] == ':') {
+ while (*++targetName == ':') {
+ }
+ targetNameObjPtr = Jim_NewStringObj(interp, targetName, -1);
+ targetCallFrame = interp->topFramePtr;
+ }
+ Jim_IncrRefCount(targetNameObjPtr);
+
+ if (framePtr->level < targetCallFrame->level) {
+ Jim_SetResultFormatted(interp,
+ "bad variable name \"%#s\": upvar won't create namespace variable that refers to procedure variable",
+ nameObjPtr);
+ Jim_DecrRefCount(interp, targetNameObjPtr);
+ return JIM_ERR;
}
- if (interp->framePtr == targetCallFrame) {
+ if (framePtr == targetCallFrame) {
Jim_Obj *objPtr = targetNameObjPtr;
- Jim_Var *varPtr;
while (1) {
- if (Jim_StringEqObj(objPtr, nameObjPtr)) {
+ if (strcmp(Jim_String(objPtr), varName) == 0) {
Jim_SetResultString(interp, "can't upvar from variable to itself", -1);
+ Jim_DecrRefCount(interp, targetNameObjPtr);
return JIM_ERR;
}
if (SetVariableFromAny(interp, objPtr) != JIM_OK)
@@ -9107,6 +9327,7 @@ int Jim_SetVariableLink(Jim_Interp *interp, Jim_Obj *nameObjPtr,
Jim_SetVariable(interp, nameObjPtr, targetNameObjPtr);
nameObjPtr->internalRep.varValue.varPtr->linkFramePtr = targetCallFrame;
+ Jim_DecrRefCount(interp, targetNameObjPtr);
return JIM_OK;
}
@@ -9185,9 +9406,9 @@ Jim_Obj *Jim_GetGlobalVariableStr(Jim_Interp *interp, const char *name, int flag
int Jim_UnsetVariable(Jim_Interp *interp, Jim_Obj *nameObjPtr, int flags)
{
- const char *name;
Jim_Var *varPtr;
int retval;
+ Jim_CallFrame *framePtr;
retval = SetVariableFromAny(interp, nameObjPtr);
if (retval == JIM_DICT_SUGAR) {
@@ -9199,21 +9420,21 @@ int Jim_UnsetVariable(Jim_Interp *interp, Jim_Obj *nameObjPtr, int flags)
if (varPtr->linkFramePtr) {
- Jim_CallFrame *savedCallFrame;
-
- savedCallFrame = interp->framePtr;
+ framePtr = interp->framePtr;
interp->framePtr = varPtr->linkFramePtr;
retval = Jim_UnsetVariable(interp, varPtr->objPtr, JIM_NONE);
- interp->framePtr = savedCallFrame;
+ interp->framePtr = framePtr;
}
else {
- Jim_CallFrame *framePtr = interp->framePtr;
-
- name = Jim_String(nameObjPtr);
- if (name[0] == ':' && name[1] == ':') {
- framePtr = interp->topFramePtr;
+ const char *name = Jim_String(nameObjPtr);
+ if (nameObjPtr->internalRep.varValue.global) {
name += 2;
+ framePtr = interp->topFramePtr;
+ }
+ else {
+ framePtr = interp->framePtr;
}
+
retval = Jim_DeleteHashEntry(&framePtr->vars, name);
if (retval == JIM_OK) {
@@ -9265,7 +9486,7 @@ static int JimDictSugarSet(Jim_Interp *interp, Jim_Obj *objPtr, Jim_Obj *valObjP
SetDictSubstFromAny(interp, objPtr);
err = Jim_SetDictKeysVector(interp, objPtr->internalRep.dictSubstValue.varNameObjPtr,
- &objPtr->internalRep.dictSubstValue.indexObjPtr, 1, valObjPtr, JIM_ERRMSG);
+ &objPtr->internalRep.dictSubstValue.indexObjPtr, 1, valObjPtr, JIM_MUSTEXIST);
if (err == JIM_OK) {
@@ -9361,10 +9582,8 @@ static void SetDictSubstFromAny(Jim_Interp *interp, Jim_Obj *objPtr)
if (objPtr->typePtr == &interpolatedObjType) {
- const ScriptToken *token = objPtr->internalRep.twoPtrValue.ptr1;
-
- varObjPtr = token[0].objPtr;
- keyObjPtr = objPtr->internalRep.twoPtrValue.ptr2;
+ varObjPtr = objPtr->internalRep.dictSubstValue.varNameObjPtr;
+ keyObjPtr = objPtr->internalRep.dictSubstValue.indexObjPtr;
Jim_IncrRefCount(varObjPtr);
Jim_IncrRefCount(keyObjPtr);
@@ -9414,13 +9633,13 @@ static Jim_Obj *JimExpandExprSugar(Jim_Interp *interp, Jim_Obj *objPtr)
}
-static Jim_CallFrame *JimCreateCallFrame(Jim_Interp *interp, Jim_CallFrame *parent)
+static Jim_CallFrame *JimCreateCallFrame(Jim_Interp *interp, Jim_CallFrame *parent, Jim_Obj *nsObj)
{
Jim_CallFrame *cf;
if (interp->freeFramesList) {
cf = interp->freeFramesList;
- interp->freeFramesList = cf->nextFramePtr;
+ interp->freeFramesList = cf->next;
}
else {
cf = Jim_Alloc(sizeof(*cf));
@@ -9428,14 +9647,18 @@ static Jim_CallFrame *JimCreateCallFrame(Jim_Interp *interp, Jim_CallFrame *pare
}
cf->id = interp->callFrameEpoch++;
- cf->parentCallFrame = parent;
+ cf->parent = parent;
cf->level = parent ? parent->level + 1 : 0;
cf->argv = NULL;
cf->argc = 0;
cf->procArgsObjPtr = NULL;
cf->procBodyObjPtr = NULL;
- cf->nextFramePtr = NULL;
+ cf->next = NULL;
cf->staticVars = NULL;
+ cf->localCommands = NULL;
+
+ cf->nsObj = nsObj;
+ Jim_IncrRefCount(nsObj);
if (cf->vars.table == NULL)
Jim_InitHashTable(&cf->vars, &JimVariablesHashTableType, interp);
return cf;
@@ -9447,6 +9670,47 @@ static void JimChangeCallFrameId(Jim_Interp *interp, Jim_CallFrame *cf)
cf->id = interp->callFrameEpoch++;
}
+static int JimDeleteLocalProcs(Jim_Interp *interp, Jim_Stack *localCommands)
+{
+
+ if (localCommands) {
+ Jim_Obj *cmdNameObj;
+
+ while ((cmdNameObj = Jim_StackPop(localCommands)) != NULL) {
+ Jim_HashEntry *he;
+ Jim_Obj *fqObjName;
+
+ const char *fqname = JimQualifyName(interp, Jim_String(cmdNameObj), &fqObjName);
+
+ he = Jim_FindHashEntry(&interp->commands, fqname);
+
+ if (he) {
+ Jim_Cmd *cmd = he->u.val;
+ if (cmd->prevCmd) {
+ Jim_Cmd *prevCmd = cmd->prevCmd;
+ cmd->prevCmd = NULL;
+
+
+ JimDecrCmdRefCount(interp, cmd);
+
+
+ he->u.val = prevCmd;
+ }
+ else {
+ Jim_DeleteHashEntry(&interp->commands, fqname);
+ Jim_InterpIncrProcEpoch(interp);
+ }
+ }
+ Jim_DecrRefCount(interp, cmdNameObj);
+ JimFreeQualifiedName(interp, fqObjName);
+ }
+ Jim_FreeStack(localCommands);
+ Jim_Free(localCommands);
+ }
+ return JIM_OK;
+}
+
+
#define JIM_FCF_NONE 0
#define JIM_FCF_NOHT 1
static void JimFreeCallFrame(Jim_Interp *interp, Jim_CallFrame *cf, int flags)
@@ -9455,6 +9719,7 @@ static void JimFreeCallFrame(Jim_Interp *interp, Jim_CallFrame *cf, int flags)
Jim_DecrRefCount(interp, cf->procArgsObjPtr);
if (cf->procBodyObjPtr)
Jim_DecrRefCount(interp, cf->procBodyObjPtr);
+ Jim_DecrRefCount(interp, cf->nsObj);
if (!(flags & JIM_FCF_NOHT))
Jim_FreeHashTable(&cf->vars);
else {
@@ -9477,10 +9742,15 @@ static void JimFreeCallFrame(Jim_Interp *interp, Jim_CallFrame *cf, int flags)
}
cf->vars.used = 0;
}
- cf->nextFramePtr = interp->freeFramesList;
+
+ JimDeleteLocalProcs(interp, cf->localCommands);
+
+ cf->next = interp->freeFramesList;
interp->freeFramesList = cf;
+
}
+
#ifdef JIM_REFERENCES
static void JimReferencesHTValDestructor(void *interp, void *val)
@@ -9497,19 +9767,19 @@ static void JimReferencesHTValDestructor(void *interp, void *val)
static unsigned int JimReferencesHTHashFunction(const void *key)
{
- const jim_wide *widePtr = key;
+ const unsigned long *widePtr = key;
unsigned int intValue = (unsigned int)*widePtr;
return Jim_IntHashFunction(intValue);
}
-static const void *JimReferencesHTKeyDup(void *privdata, const void *key)
+static void *JimReferencesHTKeyDup(void *privdata, const void *key)
{
- void *copy = Jim_Alloc(sizeof(jim_wide));
+ void *copy = Jim_Alloc(sizeof(unsigned long));
JIM_NOTUSED(privdata);
- memcpy(copy, key, sizeof(jim_wide));
+ memcpy(copy, key, sizeof(unsigned long));
return copy;
}
@@ -9517,14 +9787,14 @@ static int JimReferencesHTKeyCompare(void *privdata, const void *key1, const voi
{
JIM_NOTUSED(privdata);
- return memcmp(key1, key2, sizeof(jim_wide)) == 0;
+ return memcmp(key1, key2, sizeof(unsigned long)) == 0;
}
-static void JimReferencesHTKeyDestructor(void *privdata, const void *key)
+static void JimReferencesHTKeyDestructor(void *privdata, void *key)
{
JIM_NOTUSED(privdata);
- Jim_Free((void *)key);
+ Jim_Free(key);
}
static const Jim_HashTableType JimReferencesHashTableType = {
@@ -9540,9 +9810,9 @@ static const Jim_HashTableType JimReferencesHashTableType = {
#define JIM_REFERENCE_SPACE (35+JIM_REFERENCE_TAGLEN)
-static int JimFormatReference(char *buf, Jim_Reference *refPtr, jim_wide id)
+static int JimFormatReference(char *buf, Jim_Reference *refPtr, unsigned long id)
{
- const char *fmt = "<reference.<%s>.%020" JIM_WIDE_MODIFIER ">";
+ const char *fmt = "<reference.<%s>.%020lu>";
sprintf(buf, fmt, refPtr->tag, id);
return JIM_REFERENCE_SPACE;
@@ -9578,12 +9848,13 @@ static int isrefchar(int c)
static int SetReferenceFromAny(Jim_Interp *interp, Jim_Obj *objPtr)
{
- jim_wide wideValue;
+ unsigned long value;
int i, len;
const char *str, *start, *end;
char refId[21];
Jim_Reference *refPtr;
Jim_HashEntry *he;
+ char *endptr;
str = Jim_GetString(objPtr, &len);
@@ -9613,10 +9884,11 @@ static int SetReferenceFromAny(Jim_Interp *interp, Jim_Obj *objPtr)
memcpy(refId, start + 14 + JIM_REFERENCE_TAGLEN, 20);
refId[20] = '\0';
- if (Jim_StringToWide(refId, &wideValue, 10) != JIM_OK)
+ value = strtoul(refId, &endptr, 10);
+ if (JimCheckConversion(refId, endptr) != JIM_OK)
goto badformat;
- he = Jim_FindHashEntry(&interp->references, &wideValue);
+ he = Jim_FindHashEntry(&interp->references, &value);
if (he == NULL) {
Jim_SetResultFormatted(interp, "invalid reference id \"%#s\"", objPtr);
return JIM_ERR;
@@ -9625,7 +9897,7 @@ static int SetReferenceFromAny(Jim_Interp *interp, Jim_Obj *objPtr)
Jim_FreeIntRep(interp, objPtr);
objPtr->typePtr = &referenceObjType;
- objPtr->internalRep.refValue.id = wideValue;
+ objPtr->internalRep.refValue.id = value;
objPtr->internalRep.refValue.refPtr = refPtr;
return JIM_OK;
@@ -9637,7 +9909,7 @@ static int SetReferenceFromAny(Jim_Interp *interp, Jim_Obj *objPtr)
Jim_Obj *Jim_NewReference(Jim_Interp *interp, Jim_Obj *objPtr, Jim_Obj *tagPtr, Jim_Obj *cmdNamePtr)
{
struct Jim_Reference *refPtr;
- jim_wide wideValue = interp->referenceNextId;
+ unsigned long id;
Jim_Obj *refObjPtr;
const char *tag;
int tagLen, i;
@@ -9651,11 +9923,12 @@ Jim_Obj *Jim_NewReference(Jim_Interp *interp, Jim_Obj *objPtr, Jim_Obj *tagPtr,
refPtr->finalizerCmdNamePtr = cmdNamePtr;
if (cmdNamePtr)
Jim_IncrRefCount(cmdNamePtr);
- Jim_AddHashEntry(&interp->references, &wideValue, refPtr);
+ id = interp->referenceNextId++;
+ Jim_AddHashEntry(&interp->references, &id, refPtr);
refObjPtr = Jim_NewObj(interp);
refObjPtr->typePtr = &referenceObjType;
refObjPtr->bytes = NULL;
- refObjPtr->internalRep.refValue.id = interp->referenceNextId;
+ refObjPtr->internalRep.refValue.id = id;
refObjPtr->internalRep.refValue.refPtr = refPtr;
interp->referenceNextId++;
tag = Jim_GetString(tagPtr, &tagLen);
@@ -9724,7 +9997,7 @@ int Jim_Collect(Jim_Interp *interp)
void Jim_CollectIfNeeded(Jim_Interp *interp)
{
- jim_wide elapsedId;
+ unsigned long elapsedId;
int elapsedTime;
elapsedId = interp->referenceNextId - interp->lastCollectId;
@@ -9754,7 +10027,8 @@ Jim_Interp *Jim_CreateInterp(void)
memset(i, 0, sizeof(*i));
- i->maxNestingDepth = JIM_MAX_NESTING_DEPTH;
+ i->maxCallFrameDepth = JIM_MAX_CALLFRAME_DEPTH;
+ i->maxEvalDepth = JIM_MAX_EVAL_DEPTH;
i->lastCollectTime = time(NULL);
Jim_InitHashTable(&i->commands, &JimCommandsHashTableType, i);
@@ -9762,11 +10036,11 @@ Jim_Interp *Jim_CreateInterp(void)
Jim_InitHashTable(&i->references, &JimReferencesHashTableType, i);
#endif
Jim_InitHashTable(&i->assocData, &JimAssocDataHashTableType, i);
- Jim_InitHashTable(&i->packages, &JimStringKeyValCopyHashTableType, NULL);
- i->framePtr = i->topFramePtr = JimCreateCallFrame(i, NULL);
+ Jim_InitHashTable(&i->packages, &JimPackageHashTableType, NULL);
i->emptyObj = Jim_NewEmptyStringObj(i);
i->trueObj = Jim_NewIntObj(i, 1);
i->falseObj = Jim_NewIntObj(i, 0);
+ i->framePtr = i->topFramePtr = JimCreateCallFrame(i, NULL, i->emptyObj);
i->errorFileNameObj = i->emptyObj;
i->result = i->emptyObj;
i->stackTrace = Jim_NewListObj(i, NULL, 0);
@@ -9819,11 +10093,10 @@ void Jim_FreeInterp(Jim_Interp *i)
Jim_FreeHashTable(&i->packages);
Jim_Free(i->prngState);
Jim_FreeHashTable(&i->assocData);
- JimDeleteLocalProcs(i);
while (cf) {
- prevcf = cf->parentCallFrame;
+ prevcf = cf->parent;
JimFreeCallFrame(i, cf, JIM_FCF_NONE);
cf = prevcf;
}
@@ -9835,8 +10108,14 @@ void Jim_FreeInterp(Jim_Interp *i)
while (objPtr) {
const char *type = objPtr->typePtr ? objPtr->typePtr->name : "string";
- printf("%p (%d) %-10s: '%.20s'" JIM_NL,
- (void *)objPtr, objPtr->refCount, type, objPtr->bytes ? objPtr->bytes : "(null)");
+ if (objPtr->bytes && strlen(objPtr->bytes) > 20) {
+ printf("%p (%d) %-10s: '%.20s...'" JIM_NL,
+ (void *)objPtr, objPtr->refCount, type, objPtr->bytes);
+ }
+ else {
+ printf("%p (%d) %-10s: '%s'" JIM_NL,
+ (void *)objPtr, objPtr->refCount, type, objPtr->bytes ? objPtr->bytes : "(null)");
+ }
if (objPtr->typePtr == &sourceObjType) {
printf("FILE %s LINE %d" JIM_NL,
Jim_String(objPtr->internalRep.sourceValue.fileNameObj),
@@ -9857,7 +10136,7 @@ void Jim_FreeInterp(Jim_Interp *i)
cf = i->freeFramesList;
while (cf) {
- nextcf = cf->nextFramePtr;
+ nextcf = cf->next;
if (cf->vars.table != NULL)
Jim_Free(cf->vars.table);
Jim_Free(cf);
@@ -9907,7 +10186,7 @@ Jim_CallFrame *Jim_GetCallFrameByLevel(Jim_Interp *interp, Jim_Obj *levelObjPtr)
}
if (level > 0) {
- for (framePtr = interp->framePtr; framePtr; framePtr = framePtr->parentCallFrame) {
+ for (framePtr = interp->framePtr; framePtr; framePtr = framePtr->parent) {
if (framePtr->level == level) {
return framePtr;
}
@@ -9934,7 +10213,7 @@ static Jim_CallFrame *JimGetCallFrameByInteger(Jim_Interp *interp, Jim_Obj *leve
}
- for (framePtr = interp->framePtr; framePtr; framePtr = framePtr->parentCallFrame) {
+ for (framePtr = interp->framePtr; framePtr; framePtr = framePtr->parent) {
if (framePtr->level == level) {
return framePtr;
}
@@ -10312,8 +10591,6 @@ static int ListElementQuotingType(const char *s, int len)
if (len == 0)
return JIM_ELESTR_BRACE;
- if (s[0] == '#')
- return JIM_ELESTR_BRACE;
if (s[0] == '"' || s[0] == '{') {
trySimple = 0;
goto testbrace;
@@ -10400,11 +10677,10 @@ static int ListElementQuotingType(const char *s, int len)
return JIM_ELESTR_QUOTE;
}
-static char *BackslashQuoteString(const char *s, int len, int *qlenPtr)
+static int BackslashQuoteString(const char *s, char *q)
{
- char *q = Jim_Alloc(len * 2 + 1), *p;
+ char *p = q;
- p = q;
while (*s) {
switch (*s) {
case ' ':
@@ -10450,30 +10726,34 @@ static char *BackslashQuoteString(const char *s, int len, int *qlenPtr)
}
}
*p = '\0';
- *qlenPtr = p - q;
- return q;
+
+ return p - q;
}
-static void UpdateStringOfList(struct Jim_Obj *objPtr)
+static void JimMakeListStringRep(Jim_Obj *objPtr, Jim_Obj **objv, int objc)
{
int i, bufLen, realLength;
const char *strRep;
char *p;
int *quotingType;
- Jim_Obj **ele = objPtr->internalRep.listValue.ele;
- quotingType = Jim_Alloc(sizeof(int) * objPtr->internalRep.listValue.len + 1);
+ quotingType = Jim_Alloc(sizeof(int) * objc + 1);
bufLen = 0;
- for (i = 0; i < objPtr->internalRep.listValue.len; i++) {
+ for (i = 0; i < objc; i++) {
int len;
- strRep = Jim_GetString(ele[i], &len);
+ strRep = Jim_GetString(objv[i], &len);
quotingType[i] = ListElementQuotingType(strRep, len);
switch (quotingType[i]) {
case JIM_ELESTR_SIMPLE:
- bufLen += len;
- break;
+ if (i != 0 || strRep[0] != '#') {
+ bufLen += len;
+ break;
+ }
+
+ quotingType[i] = JIM_ELESTR_BRACE;
+
case JIM_ELESTR_BRACE:
bufLen += len + 2;
break;
@@ -10488,11 +10768,10 @@ static void UpdateStringOfList(struct Jim_Obj *objPtr)
p = objPtr->bytes = Jim_Alloc(bufLen + 1);
realLength = 0;
- for (i = 0; i < objPtr->internalRep.listValue.len; i++) {
+ for (i = 0; i < objc; i++) {
int len, qlen;
- char *q;
- strRep = Jim_GetString(ele[i], &len);
+ strRep = Jim_GetString(objv[i], &len);
switch (quotingType[i]) {
case JIM_ELESTR_SIMPLE:
@@ -10508,15 +10787,17 @@ static void UpdateStringOfList(struct Jim_Obj *objPtr)
realLength += len + 2;
break;
case JIM_ELESTR_QUOTE:
- q = BackslashQuoteString(strRep, len, &qlen);
- memcpy(p, q, qlen);
- Jim_Free(q);
+ if (i == 0 && strRep[0] == '#') {
+ *p++ = '\\';
+ realLength++;
+ }
+ qlen = BackslashQuoteString(strRep, p);
p += qlen;
realLength += qlen;
break;
}
- if (i + 1 != objPtr->internalRep.listValue.len) {
+ if (i + 1 != objc) {
*p++ = ' ';
realLength++;
}
@@ -10526,6 +10807,11 @@ static void UpdateStringOfList(struct Jim_Obj *objPtr)
Jim_Free(quotingType);
}
+static void UpdateStringOfList(struct Jim_Obj *objPtr)
+{
+ JimMakeListStringRep(objPtr, objPtr->internalRep.listValue.ele, objPtr->internalRep.listValue.len);
+}
+
static int SetListFromAny(Jim_Interp *interp, struct Jim_Obj *objPtr)
{
struct JimParserCtx parser;
@@ -10534,6 +10820,33 @@ static int SetListFromAny(Jim_Interp *interp, struct Jim_Obj *objPtr)
Jim_Obj *fileNameObj;
int linenr;
+ if (objPtr->typePtr == &listObjType) {
+ return JIM_OK;
+ }
+
+#if 0
+
+ if (Jim_IsDict(objPtr)) {
+ Jim_Obj **listObjPtrPtr;
+ int len;
+ int i;
+
+ Jim_DictPairs(interp, objPtr, &listObjPtrPtr, &len);
+ for (i = 0; i < len; i++) {
+ Jim_IncrRefCount(listObjPtrPtr[i]);
+ }
+
+
+ Jim_FreeIntRep(interp, objPtr);
+ objPtr->typePtr = &listObjType;
+ objPtr->internalRep.listValue.len = len;
+ objPtr->internalRep.listValue.maxLen = len;
+ objPtr->internalRep.listValue.ele = listObjPtrPtr;
+
+ return JIM_OK;
+ }
+#endif
+
if (objPtr->typePtr == &sourceObjType) {
fileNameObj = objPtr->internalRep.sourceValue.fileNameObj;
@@ -10693,8 +11006,7 @@ static int ListSortElements(Jim_Interp *interp, Jim_Obj *listObjPtr, struct lsor
int rc;
JimPanic((Jim_IsShared(listObjPtr), "Jim_ListSortElements called with shared object"));
- if (!Jim_IsList(listObjPtr))
- SetListFromAny(interp, listObjPtr);
+ SetListFromAny(interp, listObjPtr);
prev_info = sort_info;
@@ -10774,8 +11086,7 @@ static void ListAppendList(Jim_Obj *listPtr, Jim_Obj *appendListPtr)
void Jim_ListAppendElement(Jim_Interp *interp, Jim_Obj *listPtr, Jim_Obj *objPtr)
{
JimPanic((Jim_IsShared(listPtr), "Jim_ListAppendElement called with shared object"));
- if (!Jim_IsList(listPtr))
- SetListFromAny(interp, listPtr);
+ SetListFromAny(interp, listPtr);
Jim_InvalidateStringRep(listPtr);
ListAppendElement(listPtr, objPtr);
}
@@ -10783,16 +11094,15 @@ void Jim_ListAppendElement(Jim_Interp *interp, Jim_Obj *listPtr, Jim_Obj *objPtr
void Jim_ListAppendList(Jim_Interp *interp, Jim_Obj *listPtr, Jim_Obj *appendListPtr)
{
JimPanic((Jim_IsShared(listPtr), "Jim_ListAppendList called with shared object"));
- if (!Jim_IsList(listPtr))
- SetListFromAny(interp, listPtr);
+ SetListFromAny(interp, listPtr);
+ SetListFromAny(interp, appendListPtr);
Jim_InvalidateStringRep(listPtr);
ListAppendList(listPtr, appendListPtr);
}
int Jim_ListLength(Jim_Interp *interp, Jim_Obj *objPtr)
{
- if (!Jim_IsList(objPtr))
- SetListFromAny(interp, objPtr);
+ SetListFromAny(interp, objPtr);
return objPtr->internalRep.listValue.len;
}
@@ -10800,8 +11110,7 @@ void Jim_ListInsertElements(Jim_Interp *interp, Jim_Obj *listPtr, int idx,
int objc, Jim_Obj *const *objVec)
{
JimPanic((Jim_IsShared(listPtr), "Jim_ListInsertElement called with shared object"));
- if (!Jim_IsList(listPtr))
- SetListFromAny(interp, listPtr);
+ SetListFromAny(interp, listPtr);
if (idx >= 0 && idx > listPtr->internalRep.listValue.len)
idx = listPtr->internalRep.listValue.len;
else if (idx < 0)
@@ -10810,29 +11119,34 @@ void Jim_ListInsertElements(Jim_Interp *interp, Jim_Obj *listPtr, int idx,
ListInsertElements(listPtr, idx, objc, objVec);
}
-int Jim_ListIndex(Jim_Interp *interp, Jim_Obj *listPtr, int idx, Jim_Obj **objPtrPtr, int flags)
+Jim_Obj *Jim_ListGetIndex(Jim_Interp *interp, Jim_Obj *listPtr, int idx)
{
- if (!Jim_IsList(listPtr))
- SetListFromAny(interp, listPtr);
+ SetListFromAny(interp, listPtr);
if ((idx >= 0 && idx >= listPtr->internalRep.listValue.len) ||
(idx < 0 && (-idx - 1) >= listPtr->internalRep.listValue.len)) {
+ return NULL;
+ }
+ if (idx < 0)
+ idx = listPtr->internalRep.listValue.len + idx;
+ return listPtr->internalRep.listValue.ele[idx];
+}
+
+int Jim_ListIndex(Jim_Interp *interp, Jim_Obj *listPtr, int idx, Jim_Obj **objPtrPtr, int flags)
+{
+ *objPtrPtr = Jim_ListGetIndex(interp, listPtr, idx);
+ if (*objPtrPtr == NULL) {
if (flags & JIM_ERRMSG) {
Jim_SetResultString(interp, "list index out of range", -1);
}
- *objPtrPtr = NULL;
return JIM_ERR;
}
- if (idx < 0)
- idx = listPtr->internalRep.listValue.len + idx;
- *objPtrPtr = listPtr->internalRep.listValue.ele[idx];
return JIM_OK;
}
static int ListSetIndex(Jim_Interp *interp, Jim_Obj *listPtr, int idx,
Jim_Obj *newObjPtr, int flags)
{
- if (!Jim_IsList(listPtr))
- SetListFromAny(interp, listPtr);
+ SetListFromAny(interp, listPtr);
if ((idx >= 0 && idx >= listPtr->internalRep.listValue.len) ||
(idx < 0 && (-idx - 1) >= listPtr->internalRep.listValue.len)) {
if (flags & JIM_ERRMSG) {
@@ -10889,6 +11203,24 @@ int Jim_SetListIndex(Jim_Interp *interp, Jim_Obj *varNamePtr,
return JIM_ERR;
}
+Jim_Obj *Jim_ListJoin(Jim_Interp *interp, Jim_Obj *listObjPtr, const char *joinStr, int joinStrLen)
+{
+ int i;
+ int listLen = Jim_ListLength(interp, listObjPtr);
+ Jim_Obj *resObjPtr = Jim_NewEmptyStringObj(interp);
+
+ for (i = 0; i < listLen; ) {
+ Jim_Obj *objPtr;
+
+ Jim_ListIndex(interp, listObjPtr, i, &objPtr, JIM_NONE);
+ Jim_AppendObj(interp, resObjPtr, objPtr);
+ if (++i != listLen) {
+ Jim_AppendString(interp, resObjPtr, joinStr, joinStrLen);
+ }
+ }
+ return resObjPtr;
+}
+
Jim_Obj *Jim_ConcatObj(Jim_Interp *interp, int objc, Jim_Obj *const *objv)
{
int i;
@@ -10963,7 +11295,7 @@ Jim_Obj *Jim_ListRange(Jim_Interp *interp, Jim_Obj *listObjPtr, Jim_Obj *firstOb
len = Jim_ListLength(interp, listObjPtr);
first = JimRelToAbsIndex(len, first);
last = JimRelToAbsIndex(len, last);
- JimRelToAbsRange(len, first, last, &first, &last, &rangeLen);
+ JimRelToAbsRange(len, &first, &last, &rangeLen);
if (first == 0 && last == len) {
return listObjPtr;
}
@@ -10978,26 +11310,19 @@ static int SetDictFromAny(Jim_Interp *interp, struct Jim_Obj *objPtr);
static unsigned int JimObjectHTHashFunction(const void *key)
{
- const char *str;
- Jim_Obj *objPtr = (Jim_Obj *)key;
int len;
-
- str = Jim_GetString(objPtr, &len);
- return Jim_GenHashFunction((unsigned char *)str, len);
+ const char *str = Jim_GetString((Jim_Obj *)key, &len);
+ return Jim_GenHashFunction((const unsigned char *)str, len);
}
static int JimObjectHTKeyCompare(void *privdata, const void *key1, const void *key2)
{
- JIM_NOTUSED(privdata);
-
return Jim_StringEqObj((Jim_Obj *)key1, (Jim_Obj *)key2);
}
static void JimObjectHTKeyValDestructor(void *interp, void *val)
{
- Jim_Obj *objPtr = val;
-
- Jim_DecrRefCount(interp, objPtr);
+ Jim_DecrRefCount(interp, (Jim_Obj *)val);
}
static const Jim_HashTableType JimDictHashTableType = {
@@ -11005,8 +11330,7 @@ static const Jim_HashTableType JimDictHashTableType = {
NULL,
NULL,
JimObjectHTKeyCompare,
- (void (*)(void *, const void *))
- JimObjectHTKeyValDestructor,
+ JimObjectHTKeyValDestructor,
JimObjectHTKeyValDestructor
};
@@ -11054,90 +11378,37 @@ void DupDictInternalRep(Jim_Interp *interp, Jim_Obj *srcPtr, Jim_Obj *dupPtr)
dupPtr->typePtr = &dictObjType;
}
-void UpdateStringOfDict(struct Jim_Obj *objPtr)
+static Jim_Obj **JimDictPairs(Jim_Obj *dictPtr, int *len)
{
- int i, bufLen, realLength;
- const char *strRep;
- char *p;
- int *quotingType, objc;
Jim_HashTable *ht;
Jim_HashTableIterator *htiter;
Jim_HashEntry *he;
Jim_Obj **objv;
+ int i;
+
+ ht = dictPtr->internalRep.ptr;
- ht = objPtr->internalRep.ptr;
- objc = ht->used * 2;
- objv = Jim_Alloc(objc * sizeof(Jim_Obj *));
+ objv = Jim_Alloc((ht->used * 2) * sizeof(Jim_Obj *));
htiter = Jim_GetHashTableIterator(ht);
i = 0;
while ((he = Jim_NextHashEntry(htiter)) != NULL) {
- objv[i++] = (Jim_Obj *)he->key;
+ objv[i++] = (Jim_Obj *)he->key;
objv[i++] = he->u.val;
}
+ *len = i;
Jim_FreeHashTableIterator(htiter);
-
- quotingType = Jim_Alloc(sizeof(int) * objc);
- bufLen = 0;
- for (i = 0; i < objc; i++) {
- int len;
-
- strRep = Jim_GetString(objv[i], &len);
- quotingType[i] = ListElementQuotingType(strRep, len);
- switch (quotingType[i]) {
- case JIM_ELESTR_SIMPLE:
- bufLen += len;
- break;
- case JIM_ELESTR_BRACE:
- bufLen += len + 2;
- break;
- case JIM_ELESTR_QUOTE:
- bufLen += len * 2;
- break;
- }
- bufLen++;
- }
- bufLen++;
+ return objv;
+}
+static void UpdateStringOfDict(struct Jim_Obj *objPtr)
+{
- p = objPtr->bytes = Jim_Alloc(bufLen + 1);
- realLength = 0;
- for (i = 0; i < objc; i++) {
- int len, qlen;
- char *q;
+ int len;
+ Jim_Obj **objv = JimDictPairs(objPtr, &len);
- strRep = Jim_GetString(objv[i], &len);
+ JimMakeListStringRep(objPtr, objv, len);
- switch (quotingType[i]) {
- case JIM_ELESTR_SIMPLE:
- memcpy(p, strRep, len);
- p += len;
- realLength += len;
- break;
- case JIM_ELESTR_BRACE:
- *p++ = '{';
- memcpy(p, strRep, len);
- p += len;
- *p++ = '}';
- realLength += len + 2;
- break;
- case JIM_ELESTR_QUOTE:
- q = BackslashQuoteString(strRep, len, &qlen);
- memcpy(p, q, qlen);
- Jim_Free(q);
- p += qlen;
- realLength += qlen;
- break;
- }
-
- if (i + 1 != objc) {
- *p++ = ' ';
- realLength++;
- }
- }
- *p = '\0';
- objPtr->length = realLength;
- Jim_Free(quotingType);
Jim_Free(objv);
}
@@ -11145,13 +11416,16 @@ static int SetDictFromAny(Jim_Interp *interp, struct Jim_Obj *objPtr)
{
int listlen;
+ if (objPtr->typePtr == &dictObjType) {
+ return JIM_OK;
+ }
+
Jim_String(objPtr);
listlen = Jim_ListLength(interp, objPtr);
if (listlen % 2) {
- Jim_SetResultString(interp,
- "invalid dictionary value: must be a list with an even number of elements", -1);
+ Jim_SetResultString(interp, "missing value to go with key", -1);
return JIM_ERR;
}
else {
@@ -11203,13 +11477,9 @@ static int DictAddElement(Jim_Interp *interp, Jim_Obj *objPtr,
}
Jim_IncrRefCount(keyObjPtr);
Jim_IncrRefCount(valueObjPtr);
- if (Jim_AddHashEntry(ht, keyObjPtr, valueObjPtr) != JIM_OK) {
- Jim_HashEntry *he = Jim_FindHashEntry(ht, keyObjPtr);
-
- Jim_DecrRefCount(interp, keyObjPtr);
+ if (Jim_ReplaceHashEntry(ht, keyObjPtr, valueObjPtr)) {
- Jim_DecrRefCount(interp, (Jim_Obj *)he->u.val);
- he->u.val = valueObjPtr;
+ Jim_DecrRefCount(interp, keyObjPtr);
}
return JIM_OK;
}
@@ -11220,9 +11490,8 @@ int Jim_DictAddElement(Jim_Interp *interp, Jim_Obj *objPtr,
int retcode;
JimPanic((Jim_IsShared(objPtr), "Jim_DictAddElement called with shared object"));
- if (objPtr->typePtr != &dictObjType) {
- if (SetDictFromAny(interp, objPtr) != JIM_OK)
- return JIM_ERR;
+ if (SetDictFromAny(interp, objPtr) != JIM_OK) {
+ return JIM_ERR;
}
retcode = DictAddElement(interp, objPtr, keyObjPtr, valueObjPtr);
Jim_InvalidateStringRep(objPtr);
@@ -11252,14 +11521,13 @@ int Jim_DictKey(Jim_Interp *interp, Jim_Obj *dictPtr, Jim_Obj *keyPtr,
Jim_HashEntry *he;
Jim_HashTable *ht;
- if (dictPtr->typePtr != &dictObjType) {
- if (SetDictFromAny(interp, dictPtr) != JIM_OK)
- return -1;
+ if (SetDictFromAny(interp, dictPtr) != JIM_OK) {
+ return -1;
}
ht = dictPtr->internalRep.ptr;
if ((he = Jim_FindHashEntry(ht, keyPtr)) == NULL) {
if (flags & JIM_ERRMSG) {
- Jim_SetResultFormatted(interp, "key \"%#s\" not found in dictionary", keyPtr);
+ Jim_SetResultFormatted(interp, "key \"%#s\" not known in dictionary", keyPtr);
}
return JIM_ERR;
}
@@ -11270,29 +11538,11 @@ int Jim_DictKey(Jim_Interp *interp, Jim_Obj *dictPtr, Jim_Obj *keyPtr,
int Jim_DictPairs(Jim_Interp *interp, Jim_Obj *dictPtr, Jim_Obj ***objPtrPtr, int *len)
{
- Jim_HashTable *ht;
- Jim_HashTableIterator *htiter;
- Jim_HashEntry *he;
- Jim_Obj **objv;
- int i;
-
- if (dictPtr->typePtr != &dictObjType) {
- if (SetDictFromAny(interp, dictPtr) != JIM_OK)
- return JIM_ERR;
+ if (SetDictFromAny(interp, dictPtr) != JIM_OK) {
+ return JIM_ERR;
}
- ht = dictPtr->internalRep.ptr;
+ *objPtrPtr = JimDictPairs(dictPtr, len);
-
- objv = Jim_Alloc((ht->used * 2) * sizeof(Jim_Obj *));
- htiter = Jim_GetHashTableIterator(ht);
- i = 0;
- while ((he = Jim_NextHashEntry(htiter)) != NULL) {
- objv[i++] = (Jim_Obj *)he->key;
- objv[i++] = he->u.val;
- }
- *len = i;
- Jim_FreeHashTableIterator(htiter);
- *objPtrPtr = objv;
return JIM_OK;
}
@@ -11311,9 +11561,10 @@ int Jim_DictKeysVector(Jim_Interp *interp, Jim_Obj *dictPtr,
for (i = 0; i < keyc; i++) {
Jim_Obj *objPtr;
- if (Jim_DictKey(interp, dictPtr, keyv[i], &objPtr, flags)
- != JIM_OK)
- return JIM_ERR;
+ int rc = Jim_DictKey(interp, dictPtr, keyv[i], &objPtr, flags);
+ if (rc != JIM_OK) {
+ return rc;
+ }
dictPtr = objPtr;
}
*objPtrPtr = dictPtr;
@@ -11326,10 +11577,10 @@ int Jim_SetDictKeysVector(Jim_Interp *interp, Jim_Obj *varNamePtr,
Jim_Obj *varObjPtr, *objPtr, *dictObjPtr;
int shared, i;
- varObjPtr = objPtr =
- Jim_GetVariable(interp, varNamePtr, newObjPtr == NULL ? JIM_ERRMSG : JIM_NONE);
+ varObjPtr = objPtr = Jim_GetVariable(interp, varNamePtr, flags);
if (objPtr == NULL) {
- if (newObjPtr == NULL) {
+ if (newObjPtr == NULL && (flags & JIM_MUSTEXIST)) {
+
return JIM_ERR;
}
varObjPtr = objPtr = Jim_NewDictObj(interp, NULL, 0);
@@ -11340,15 +11591,24 @@ int Jim_SetDictKeysVector(Jim_Interp *interp, Jim_Obj *varNamePtr,
}
if ((shared = Jim_IsShared(objPtr)))
varObjPtr = objPtr = Jim_DuplicateObj(interp, objPtr);
- for (i = 0; i < keyc - 1; i++) {
+ for (i = 0; i < keyc; i++) {
dictObjPtr = objPtr;
- if (dictObjPtr->typePtr != &dictObjType) {
- if (SetDictFromAny(interp, dictObjPtr) != JIM_OK) {
- goto err;
+ if (SetDictFromAny(interp, dictObjPtr) != JIM_OK) {
+ goto err;
+ }
+
+ if (i == keyc - 1) {
+
+ if (Jim_DictAddElement(interp, objPtr, keyv[keyc - 1], newObjPtr) != JIM_OK) {
+ if (newObjPtr || (flags & JIM_MUSTEXIST)) {
+ goto err;
+ }
}
+ break;
}
+
Jim_InvalidateStringRep(dictObjPtr);
if (Jim_DictKey(interp, dictObjPtr, keyv[i], &objPtr,
@@ -11366,12 +11626,6 @@ int Jim_SetDictKeysVector(Jim_Interp *interp, Jim_Obj *varNamePtr,
DictAddElement(interp, dictObjPtr, keyv[i], objPtr);
}
}
-
- if (Jim_DictAddElement(interp, objPtr, keyv[keyc - 1], newObjPtr) != JIM_OK) {
- if (newObjPtr || (flags & JIM_ERRMSG)) {
- goto err;
- }
- }
Jim_InvalidateStringRep(objPtr);
Jim_InvalidateStringRep(varObjPtr);
if (Jim_SetVariable(interp, varNamePtr, varObjPtr) != JIM_OK) {
@@ -11402,12 +11656,12 @@ void UpdateStringOfIndex(struct Jim_Obj *objPtr)
int len;
char buf[JIM_INTEGER_SPACE + 1];
- if (objPtr->internalRep.indexValue >= 0)
- len = sprintf(buf, "%d", objPtr->internalRep.indexValue);
- else if (objPtr->internalRep.indexValue == -1)
+ if (objPtr->internalRep.intValue >= 0)
+ len = sprintf(buf, "%d", objPtr->internalRep.intValue);
+ else if (objPtr->internalRep.intValue == -1)
len = sprintf(buf, "end");
else {
- len = sprintf(buf, "end%d", objPtr->internalRep.indexValue + 1);
+ len = sprintf(buf, "end%d", objPtr->internalRep.intValue + 1);
}
objPtr->bytes = Jim_Alloc(len + 1);
memcpy(objPtr->bytes, buf, len + 1);
@@ -11430,7 +11684,7 @@ int SetIndexFromAny(Jim_Interp *interp, Jim_Obj *objPtr)
idx = 0;
}
else {
- idx = strtol(str, &endptr, 10);
+ idx = strtol(str, &endptr, 0);
if (endptr == str) {
goto badindex;
@@ -11442,7 +11696,7 @@ int SetIndexFromAny(Jim_Interp *interp, Jim_Obj *objPtr)
if (*str == '+' || *str == '-') {
int sign = (*str == '+' ? 1 : -1);
- idx += sign * strtol(++str, &endptr, 10);
+ idx += sign * strtol(++str, &endptr, 0);
if (str == endptr || *endptr) {
goto badindex;
}
@@ -11471,7 +11725,7 @@ int SetIndexFromAny(Jim_Interp *interp, Jim_Obj *objPtr)
Jim_FreeIntRep(interp, objPtr);
objPtr->typePtr = &indexObjType;
- objPtr->internalRep.indexValue = idx;
+ objPtr->internalRep.intValue = idx;
return JIM_OK;
badindex:
@@ -11493,7 +11747,7 @@ int Jim_GetIndex(Jim_Interp *interp, Jim_Obj *objPtr, int *indexPtr)
}
if (objPtr->typePtr != &indexObjType && SetIndexFromAny(interp, objPtr) == JIM_ERR)
return JIM_ERR;
- *indexPtr = objPtr->internalRep.indexValue;
+ *indexPtr = objPtr->internalRep.intValue;
return JIM_OK;
}
@@ -11548,7 +11802,7 @@ int SetReturnCodeFromAny(Jim_Interp *interp, Jim_Obj *objPtr)
Jim_FreeIntRep(interp, objPtr);
objPtr->typePtr = &returnCodeObjType;
- objPtr->internalRep.returnCode = returnCode;
+ objPtr->internalRep.intValue = returnCode;
return JIM_OK;
}
@@ -11556,7 +11810,7 @@ int Jim_GetReturnCode(Jim_Interp *interp, Jim_Obj *objPtr, int *intPtr)
{
if (objPtr->typePtr != &returnCodeObjType && SetReturnCodeFromAny(interp, objPtr) == JIM_ERR)
return JIM_ERR;
- *intPtr = objPtr->internalRep.returnCode;
+ *intPtr = objPtr->internalRep.intValue;
return JIM_OK;
}
@@ -13982,101 +14236,97 @@ static int Jim_IncrCoreCommand(Jim_Interp *interp, int argc, Jim_Obj *const *arg
#define JIM_EVAL_SINTV_LEN 8
-static int JimUnknown(Jim_Interp *interp, int argc, Jim_Obj *const *argv, Jim_Obj *fileNameObj,
- int linenr)
+static int JimUnknown(Jim_Interp *interp, int argc, Jim_Obj *const *argv)
{
- Jim_Obj **v, *sv[JIM_EVAL_SARGV_LEN];
- int retCode;
+ int retcode;
if (interp->unknown_called > 50) {
return JIM_ERR;
}
+
+
if (Jim_GetCommand(interp, interp->unknown, JIM_NONE) == NULL)
return JIM_ERR;
- if (argc + 1 <= JIM_EVAL_SARGV_LEN)
- v = sv;
- else
- v = Jim_Alloc(sizeof(Jim_Obj *) * (argc + 1));
- memcpy(v + 1, argv, sizeof(Jim_Obj *) * argc);
- v[0] = interp->unknown;
-
interp->unknown_called++;
- retCode = JimEvalObjVector(interp, argc + 1, v, fileNameObj, linenr);
+
+ retcode = Jim_EvalObjPrefix(interp, interp->unknown, argc, argv);
interp->unknown_called--;
-
- if (v != sv)
- Jim_Free(v);
- return retCode;
+ return retcode;
}
-static int JimEvalObjVector(Jim_Interp *interp, int objc, Jim_Obj *const *objv,
- Jim_Obj *fileNameObj, int linenr)
+static int JimInvokeCommand(Jim_Interp *interp, int objc, Jim_Obj *const *objv)
{
- int i, retcode;
- Jim_Cmd *cmdPtr;
+ int retcode;
+ Jim_Cmd *cmdPtr = Jim_GetCommand(interp, objv[0], JIM_ERRMSG);
-
- for (i = 0; i < objc; i++)
- Jim_IncrRefCount(objv[i]);
-
- cmdPtr = Jim_GetCommand(interp, objv[0], JIM_ERRMSG);
if (cmdPtr == NULL) {
- retcode = JimUnknown(interp, objc, objv, fileNameObj, linenr);
+ return JimUnknown(interp, objc, objv);
}
- else {
-
- JimIncrCmdRefCount(cmdPtr);
- Jim_SetEmptyResult(interp);
- if (cmdPtr->isproc) {
- retcode = JimCallProcedure(interp, cmdPtr, fileNameObj, linenr, objc, objv);
- }
- else {
- interp->cmdPrivData = cmdPtr->u.native.privData;
- retcode = cmdPtr->u.native.cmdProc(interp, objc, objv);
- }
- JimDecrCmdRefCount(interp, cmdPtr);
+ if (interp->evalDepth == interp->maxEvalDepth) {
+ Jim_SetResultString(interp, "Infinite eval recursion", -1);
+ return JIM_ERR;
}
+ interp->evalDepth++;
+
- for (i = 0; i < objc; i++)
- Jim_DecrRefCount(interp, objv[i]);
+ JimIncrCmdRefCount(cmdPtr);
+ Jim_SetEmptyResult(interp);
+ if (cmdPtr->isproc) {
+ retcode = JimCallProcedure(interp, cmdPtr, objc, objv);
+ }
+ else {
+ interp->cmdPrivData = cmdPtr->u.native.privData;
+ retcode = cmdPtr->u.native.cmdProc(interp, objc, objv);
+ }
+ JimDecrCmdRefCount(interp, cmdPtr);
+ interp->evalDepth--;
return retcode;
}
int Jim_EvalObjVector(Jim_Interp *interp, int objc, Jim_Obj *const *objv)
{
- return JimEvalObjVector(interp, objc, objv, interp->emptyObj, 1);
+ int i, retcode;
+
+
+ for (i = 0; i < objc; i++)
+ Jim_IncrRefCount(objv[i]);
+
+ retcode = JimInvokeCommand(interp, objc, objv);
+
+
+ for (i = 0; i < objc; i++)
+ Jim_DecrRefCount(interp, objv[i]);
+
+ return retcode;
}
int Jim_EvalObjPrefix(Jim_Interp *interp, Jim_Obj *prefix, int objc, Jim_Obj *const *objv)
{
- int i;
int ret;
Jim_Obj **nargv = Jim_Alloc((objc + 1) * sizeof(*nargv));
nargv[0] = prefix;
- for (i = 0; i < objc; i++) {
- nargv[i + 1] = objv[i];
- }
+ memcpy(&nargv[1], &objv[0], sizeof(nargv[0]) * objc);
ret = Jim_EvalObjVector(interp, objc + 1, nargv);
Jim_Free(nargv);
return ret;
}
-static void JimAddErrorToStack(Jim_Interp *interp, int retcode, Jim_Obj *fileNameObj, int line)
+static void JimAddErrorToStack(Jim_Interp *interp, int retcode, ScriptObj *script)
{
int rc = retcode;
if (rc == JIM_ERR && !interp->errorFlag) {
interp->errorFlag = 1;
- Jim_IncrRefCount(fileNameObj);
+ Jim_IncrRefCount(script->fileNameObj);
Jim_DecrRefCount(interp, interp->errorFileNameObj);
- interp->errorFileNameObj = fileNameObj;
- interp->errorLine = line;
+ interp->errorFileNameObj = script->fileNameObj;
+ interp->errorLine = script->linenr;
JimResetStackTrace(interp);
@@ -14087,9 +14337,9 @@ static void JimAddErrorToStack(Jim_Interp *interp, int retcode, Jim_Obj *fileNam
if (rc == JIM_ERR && interp->addStackTrace > 0) {
- JimAppendStackTrace(interp, Jim_String(interp->errorProc), fileNameObj, line);
+ JimAppendStackTrace(interp, Jim_String(interp->errorProc), script->fileNameObj, script->linenr);
- if (Jim_Length(fileNameObj)) {
+ if (Jim_Length(script->fileNameObj)) {
interp->addStackTrace = 0;
}
@@ -14105,39 +14355,6 @@ static void JimAddErrorToStack(Jim_Interp *interp, int retcode, Jim_Obj *fileNam
}
}
-
-static void JimDeleteLocalProcs(Jim_Interp *interp)
-{
- if (interp->localProcs) {
- char *procname;
-
- while ((procname = Jim_StackPop(interp->localProcs)) != NULL) {
-
- Jim_Cmd *prevCmd = NULL;
- Jim_HashEntry *he = Jim_FindHashEntry(&interp->commands, procname);
- if (he) {
- Jim_Cmd *cmd = (Jim_Cmd *)he->u.val;
- if (cmd->isproc && cmd->u.proc.prevCmd) {
- prevCmd = cmd->u.proc.prevCmd;
- cmd->u.proc.prevCmd = NULL;
- }
- }
-
-
- Jim_DeleteCommand(interp, procname);
-
- if (prevCmd) {
-
- Jim_AddHashEntry(&interp->commands, procname, prevCmd);
- }
- Jim_Free(procname);
- }
- Jim_FreeStack(interp->localProcs);
- Jim_Free(interp->localProcs);
- interp->localProcs = NULL;
- }
-}
-
static int JimSubstOneToken(Jim_Interp *interp, const ScriptToken *token, Jim_Obj **objPtrPtr)
{
Jim_Obj *objPtr;
@@ -14244,8 +14461,8 @@ static Jim_Obj *JimInterpolateTokens(Jim_Interp *interp, const ScriptToken * tok
&& token[2].type == JIM_TT_VAR) {
objPtr->typePtr = &interpolatedObjType;
- objPtr->internalRep.twoPtrValue.ptr1 = (void *)token;
- objPtr->internalRep.twoPtrValue.ptr2 = intv[2];
+ objPtr->internalRep.dictSubstValue.varNameObjPtr = token[0].objPtr;
+ objPtr->internalRep.dictSubstValue.indexObjPtr = intv[2];
Jim_IncrRefCount(intv[2]);
}
@@ -14268,22 +14485,26 @@ static Jim_Obj *JimInterpolateTokens(Jim_Interp *interp, const ScriptToken * tok
}
-static int JimEvalObjList(Jim_Interp *interp, Jim_Obj *listPtr, Jim_Obj *fileNameObj, int linenr)
+static int JimEvalObjList(Jim_Interp *interp, Jim_Obj *listPtr)
{
int retcode = JIM_OK;
- JimPanic((!Jim_IsList(listPtr), "JimEvalObjList() called without list arg"));
-
if (listPtr->internalRep.listValue.len) {
Jim_IncrRefCount(listPtr);
- retcode = JimEvalObjVector(interp,
+ retcode = JimInvokeCommand(interp,
listPtr->internalRep.listValue.len,
- listPtr->internalRep.listValue.ele, fileNameObj, linenr);
+ listPtr->internalRep.listValue.ele);
Jim_DecrRefCount(interp, listPtr);
}
return retcode;
}
+int Jim_EvalObjList(Jim_Interp *interp, Jim_Obj *listPtr)
+{
+ SetListFromAny(interp, listPtr);
+ return JimEvalObjList(interp, listPtr);
+}
+
int Jim_EvalObj(Jim_Interp *interp, Jim_Obj *scriptObjPtr)
{
int i;
@@ -14291,12 +14512,10 @@ int Jim_EvalObj(Jim_Interp *interp, Jim_Obj *scriptObjPtr)
ScriptToken *token;
int retcode = JIM_OK;
Jim_Obj *sargv[JIM_EVAL_SARGV_LEN], **argv = NULL;
- int linenr = 0;
-
- interp->errorFlag = 0;
+ Jim_Obj *prevScriptObj;
if (Jim_IsList(scriptObjPtr) && scriptObjPtr->bytes == NULL) {
- return JimEvalObjList(interp, scriptObjPtr, interp->emptyObj, 1);
+ return JimEvalObjList(interp, scriptObjPtr);
}
Jim_IncrRefCount(scriptObjPtr);
@@ -14304,18 +14523,20 @@ int Jim_EvalObj(Jim_Interp *interp, Jim_Obj *scriptObjPtr)
Jim_SetEmptyResult(interp);
+ token = script->token;
+
#ifdef JIM_OPTIMIZATION
if (script->len == 0) {
Jim_DecrRefCount(interp, scriptObjPtr);
return JIM_OK;
}
if (script->len == 3
- && script->token[1].objPtr->typePtr == &commandObjType
- && script->token[1].objPtr->internalRep.cmdValue.cmdPtr->isproc == 0
- && script->token[1].objPtr->internalRep.cmdValue.cmdPtr->u.native.cmdProc == Jim_IncrCoreCommand
- && script->token[2].objPtr->typePtr == &variableObjType) {
+ && token[1].objPtr->typePtr == &commandObjType
+ && token[1].objPtr->internalRep.cmdValue.cmdPtr->isproc == 0
+ && token[1].objPtr->internalRep.cmdValue.cmdPtr->u.native.cmdProc == Jim_IncrCoreCommand
+ && token[2].objPtr->typePtr == &variableObjType) {
- Jim_Obj *objPtr = Jim_GetVariable(interp, script->token[2].objPtr, JIM_NONE);
+ Jim_Obj *objPtr = Jim_GetVariable(interp, token[2].objPtr, JIM_NONE);
if (objPtr && !Jim_IsShared(objPtr) && objPtr->typePtr == &intObjType) {
JimWideValue(objPtr)++;
@@ -14329,17 +14550,20 @@ int Jim_EvalObj(Jim_Interp *interp, Jim_Obj *scriptObjPtr)
script->inUse++;
- token = script->token;
+
+ prevScriptObj = interp->currentScriptObj;
+ interp->currentScriptObj = scriptObjPtr;
+
+ interp->errorFlag = 0;
argv = sargv;
for (i = 0; i < script->len && retcode == JIM_OK; ) {
int argc;
int j;
- Jim_Cmd *cmd;
argc = token[i].objPtr->internalRep.scriptLineValue.argc;
- linenr = token[i].objPtr->internalRep.scriptLineValue.line;
+ script->linenr = token[i].objPtr->internalRep.scriptLineValue.line;
if (argc > JIM_EVAL_SARGV_LEN)
@@ -14439,24 +14663,7 @@ int Jim_EvalObj(Jim_Interp *interp, Jim_Obj *scriptObjPtr)
if (retcode == JIM_OK && argc) {
- cmd = Jim_GetCommand(interp, argv[0], JIM_ERRMSG);
- if (cmd != NULL) {
-
- JimIncrCmdRefCount(cmd);
- Jim_SetEmptyResult(interp);
- if (cmd->isproc) {
- retcode =
- JimCallProcedure(interp, cmd, script->fileNameObj, linenr, argc, argv);
- } else {
- interp->cmdPrivData = cmd->u.native.privData;
- retcode = cmd->u.native.cmdProc(interp, argc, argv);
- }
- JimDecrCmdRefCount(interp, cmd);
- }
- else {
-
- retcode = JimUnknown(interp, argc, argv, script->fileNameObj, linenr);
- }
+ retcode = JimInvokeCommand(interp, argc, argv);
if (interp->signal_level && interp->sigmask) {
retcode = JIM_SIGNAL;
@@ -14475,7 +14682,10 @@ int Jim_EvalObj(Jim_Interp *interp, Jim_Obj *scriptObjPtr)
}
- JimAddErrorToStack(interp, retcode, script->fileNameObj, linenr);
+ JimAddErrorToStack(interp, retcode, script);
+
+
+ interp->currentScriptObj = prevScriptObj;
Jim_FreeIntRep(interp, scriptObjPtr);
scriptObjPtr->typePtr = &scriptObjType;
@@ -14495,7 +14705,7 @@ static int JimSetProcArg(Jim_Interp *interp, Jim_Obj *argNameObj, Jim_Obj *argVa
Jim_Obj *objPtr;
Jim_CallFrame *savedCallFrame = interp->framePtr;
- interp->framePtr = interp->framePtr->parentCallFrame;
+ interp->framePtr = interp->framePtr->parent;
objPtr = Jim_GetVariable(interp, argValObj, JIM_ERRMSG);
interp->framePtr = savedCallFrame;
if (!objPtr) {
@@ -14505,7 +14715,7 @@ static int JimSetProcArg(Jim_Interp *interp, Jim_Obj *argNameObj, Jim_Obj *argVa
objPtr = Jim_NewStringObj(interp, varname + 1, -1);
Jim_IncrRefCount(objPtr);
- retcode = Jim_SetVariableLink(interp, objPtr, argValObj, interp->framePtr->parentCallFrame);
+ retcode = Jim_SetVariableLink(interp, objPtr, argValObj, interp->framePtr->parent);
Jim_DecrRefCount(interp, objPtr);
}
else {
@@ -14532,7 +14742,7 @@ static void JimSetProcWrongArgs(Jim_Interp *interp, Jim_Obj *procNameObj, Jim_Cm
}
else {
- Jim_AppendString(interp, argmsg, "?argument ...?", -1);
+ Jim_AppendString(interp, argmsg, "?arg...?", -1);
}
}
else {
@@ -14542,7 +14752,11 @@ static void JimSetProcWrongArgs(Jim_Interp *interp, Jim_Obj *procNameObj, Jim_Cm
Jim_AppendString(interp, argmsg, "?", 1);
}
else {
- Jim_AppendObj(interp, argmsg, cmd->u.proc.arglist[i].nameObjPtr);
+ const char *arg = Jim_String(cmd->u.proc.arglist[i].nameObjPtr);
+ if (*arg == '&') {
+ arg++;
+ }
+ Jim_AppendString(interp, argmsg, arg, -1);
}
}
}
@@ -14550,12 +14764,53 @@ static void JimSetProcWrongArgs(Jim_Interp *interp, Jim_Obj *procNameObj, Jim_Cm
Jim_FreeNewObj(interp, argmsg);
}
-static int JimCallProcedure(Jim_Interp *interp, Jim_Cmd *cmd, Jim_Obj *fileNameObj, int linenr, int argc,
- Jim_Obj *const *argv)
+#ifdef jim_ext_namespace
+int Jim_EvalNamespace(Jim_Interp *interp, Jim_Obj *scriptObj, Jim_Obj *nsObj)
+{
+ Jim_CallFrame *callFramePtr;
+ int retcode;
+
+
+ callFramePtr = JimCreateCallFrame(interp, interp->framePtr, nsObj);
+ callFramePtr->argv = &interp->emptyObj;
+ callFramePtr->argc = 0;
+ callFramePtr->procArgsObjPtr = NULL;
+ callFramePtr->procBodyObjPtr = scriptObj;
+ callFramePtr->staticVars = NULL;
+ callFramePtr->fileNameObj = interp->emptyObj;
+ callFramePtr->line = 0;
+ Jim_IncrRefCount(scriptObj);
+ interp->framePtr = callFramePtr;
+
+
+ if (interp->framePtr->level == interp->maxCallFrameDepth) {
+ Jim_SetResultString(interp, "Too many nested calls. Infinite recursion?", -1);
+ retcode = JIM_ERR;
+ }
+ else {
+
+ retcode = Jim_EvalObj(interp, scriptObj);
+ }
+
+
+ interp->framePtr = interp->framePtr->parent;
+ if (callFramePtr->vars.size != JIM_HT_INITIAL_SIZE) {
+ JimFreeCallFrame(interp, callFramePtr, JIM_FCF_NONE);
+ }
+ else {
+ JimFreeCallFrame(interp, callFramePtr, JIM_FCF_NOHT);
+ }
+
+ return retcode;
+}
+#endif
+
+static int JimCallProcedure(Jim_Interp *interp, Jim_Cmd *cmd, int argc, Jim_Obj *const *argv)
{
Jim_CallFrame *callFramePtr;
- Jim_Stack *prevLocalProcs;
int i, d, retcode, optargs;
+ Jim_Stack *localCommands;
+ ScriptObj *script;
if (argc - 1 < cmd->u.proc.reqArity ||
@@ -14565,29 +14820,29 @@ static int JimCallProcedure(Jim_Interp *interp, Jim_Cmd *cmd, Jim_Obj *fileNameO
}
- if (interp->framePtr->level == interp->maxNestingDepth) {
+ if (interp->framePtr->level == interp->maxCallFrameDepth) {
Jim_SetResultString(interp, "Too many nested calls. Infinite recursion?", -1);
return JIM_ERR;
}
- callFramePtr = JimCreateCallFrame(interp, interp->framePtr);
+ callFramePtr = JimCreateCallFrame(interp, interp->framePtr, cmd->u.proc.nsObj);
callFramePtr->argv = argv;
callFramePtr->argc = argc;
callFramePtr->procArgsObjPtr = cmd->u.proc.argListObjPtr;
callFramePtr->procBodyObjPtr = cmd->u.proc.bodyObjPtr;
callFramePtr->staticVars = cmd->u.proc.staticVars;
- callFramePtr->fileNameObj = fileNameObj;
- callFramePtr->line = linenr;
+
+
+ script = Jim_GetScript(interp, interp->currentScriptObj);
+ callFramePtr->fileNameObj = script->fileNameObj;
+ callFramePtr->line = script->linenr;
+
Jim_IncrRefCount(cmd->u.proc.argListObjPtr);
Jim_IncrRefCount(cmd->u.proc.bodyObjPtr);
interp->framePtr = callFramePtr;
- prevLocalProcs = interp->localProcs;
- interp->localProcs = NULL;
-
-
optargs = (argc - 1 - cmd->u.proc.reqArity);
@@ -14634,20 +14889,27 @@ static int JimCallProcedure(Jim_Interp *interp, Jim_Cmd *cmd, Jim_Obj *fileNameO
badargset:
- interp->framePtr = interp->framePtr->parentCallFrame;
+
+ localCommands = callFramePtr->localCommands;
+ callFramePtr->localCommands = NULL;
+
+ interp->framePtr = interp->framePtr->parent;
if (callFramePtr->vars.size != JIM_HT_INITIAL_SIZE) {
JimFreeCallFrame(interp, callFramePtr, JIM_FCF_NONE);
}
else {
JimFreeCallFrame(interp, callFramePtr, JIM_FCF_NOHT);
}
+
while (retcode == JIM_EVAL) {
Jim_Obj *resultScriptObjPtr = Jim_GetResult(interp);
Jim_IncrRefCount(resultScriptObjPtr);
- retcode = JimEvalObjList(interp, resultScriptObjPtr, fileNameObj, linenr);
+ JimPanic((!Jim_IsList(resultScriptObjPtr), "tailcall (JIM_EVAL) returned non-list"));
+
+ retcode = JimEvalObjList(interp, resultScriptObjPtr);
if (retcode == JIM_RETURN) {
interp->returnLevel++;
}
@@ -14669,8 +14931,7 @@ badargset:
}
- JimDeleteLocalProcs(interp);
- interp->localProcs = prevLocalProcs;
+ JimDeleteLocalProcs(interp, localCommands);
return retcode;
}
@@ -14968,70 +15229,80 @@ int Jim_SubstObj(Jim_Interp *interp, Jim_Obj *substObjPtr, Jim_Obj **resObjPtrPt
void Jim_WrongNumArgs(Jim_Interp *interp, int argc, Jim_Obj *const *argv, const char *msg)
{
- int i;
- Jim_Obj *objPtr = Jim_NewEmptyStringObj(interp);
+ Jim_Obj *objPtr;
+ Jim_Obj *listObjPtr = Jim_NewListObj(interp, argv, argc);
- Jim_AppendString(interp, objPtr, "wrong # args: should be \"", -1);
- for (i = 0; i < argc; i++) {
- Jim_AppendObj(interp, objPtr, argv[i]);
- if (!(i + 1 == argc && msg[0] == '\0'))
- Jim_AppendString(interp, objPtr, " ", 1);
+ if (*msg) {
+ Jim_ListAppendElement(interp, listObjPtr, Jim_NewStringObj(interp, msg, -1));
}
- Jim_AppendString(interp, objPtr, msg, -1);
- Jim_AppendString(interp, objPtr, "\"", 1);
- Jim_SetResult(interp, objPtr);
+ Jim_IncrRefCount(listObjPtr);
+ objPtr = Jim_ListJoin(interp, listObjPtr, " ", 1);
+ Jim_DecrRefCount(interp, listObjPtr);
+
+ Jim_IncrRefCount(objPtr);
+ Jim_SetResultFormatted(interp, "wrong # args: should be \"%#s\"", objPtr);
+ Jim_DecrRefCount(interp, objPtr);
}
-#define JimTrivialMatch(pattern) (strpbrk((pattern), "*[?\\") == NULL)
+typedef void JimHashtableIteratorCallbackType(Jim_Interp *interp, Jim_Obj *listObjPtr,
+ Jim_HashEntry *he, int type);
+#define JimTrivialMatch(pattern) (strpbrk((pattern), "*[?\\") == NULL)
-static Jim_Obj *JimCommandsList(Jim_Interp *interp, Jim_Obj *patternObjPtr, int type)
+static Jim_Obj *JimHashtablePatternMatch(Jim_Interp *interp, Jim_HashTable *ht, Jim_Obj *patternObjPtr,
+ JimHashtableIteratorCallbackType *callback, int type)
{
- Jim_HashTableIterator *htiter;
Jim_HashEntry *he;
Jim_Obj *listObjPtr = Jim_NewListObj(interp, NULL, 0);
if (patternObjPtr && JimTrivialMatch(Jim_String(patternObjPtr))) {
- Jim_Cmd *cmdPtr = Jim_GetCommand(interp, patternObjPtr, JIM_NONE);
- if (cmdPtr) {
- if (type == 1 && !cmdPtr->isproc) {
-
- }
- else if (type == 2 && !Jim_AioFilehandle(interp, patternObjPtr)) {
-
- }
- else {
- Jim_ListAppendElement(interp, listObjPtr, patternObjPtr);
+ he = Jim_FindHashEntry(ht, Jim_String(patternObjPtr));
+ if (he) {
+ callback(interp, listObjPtr, he, type);
+ }
+ }
+ else {
+ Jim_HashTableIterator *htiter = Jim_GetHashTableIterator(ht);
+ while ((he = Jim_NextHashEntry(htiter)) != NULL) {
+ if (patternObjPtr == NULL || JimGlobMatch(Jim_String(patternObjPtr), he->key, 0)) {
+ callback(interp, listObjPtr, he, type);
}
}
- return listObjPtr;
+ Jim_FreeHashTableIterator(htiter);
}
+ return listObjPtr;
+}
- htiter = Jim_GetHashTableIterator(&interp->commands);
- while ((he = Jim_NextHashEntry(htiter)) != NULL) {
- Jim_Cmd *cmdPtr = he->u.val;
- Jim_Obj *cmdNameObj;
- if (type == 1 && !cmdPtr->isproc) {
-
- continue;
- }
- if (patternObjPtr && !JimStringMatch(interp, patternObjPtr, he->key, 0))
- continue;
+#define JIM_CMDLIST_COMMANDS 0
+#define JIM_CMDLIST_PROCS 1
+#define JIM_CMDLIST_CHANNELS 2
- cmdNameObj = Jim_NewStringObj(interp, he->key, -1);
+static void JimCommandMatch(Jim_Interp *interp, Jim_Obj *listObjPtr,
+ Jim_HashEntry *he, int type)
+{
+ Jim_Cmd *cmdPtr = (Jim_Cmd *)he->u.val;
+ Jim_Obj *objPtr;
+ if (type == JIM_CMDLIST_PROCS && !cmdPtr->isproc) {
- if (type == 2 && !Jim_AioFilehandle(interp, cmdNameObj)) {
- Jim_FreeNewObj(interp, cmdNameObj);
- continue;
- }
+ return;
+ }
+
+ objPtr = Jim_NewStringObj(interp, he->key, -1);
+ Jim_IncrRefCount(objPtr);
- Jim_ListAppendElement(interp, listObjPtr, cmdNameObj);
+ if (type != JIM_CMDLIST_CHANNELS || Jim_AioFilehandle(interp, objPtr)) {
+ Jim_ListAppendElement(interp, listObjPtr, objPtr);
}
- Jim_FreeHashTableIterator(htiter);
- return listObjPtr;
+ Jim_DecrRefCount(interp, objPtr);
+}
+
+
+static Jim_Obj *JimCommandsList(Jim_Interp *interp, Jim_Obj *patternObjPtr, int type)
+{
+ return JimHashtablePatternMatch(interp, &interp->commands, patternObjPtr, JimCommandMatch, type);
}
@@ -15039,33 +15310,31 @@ static Jim_Obj *JimCommandsList(Jim_Interp *interp, Jim_Obj *patternObjPtr, int
#define JIM_VARLIST_LOCALS 1
#define JIM_VARLIST_VARS 2
-static Jim_Obj *JimVariablesList(Jim_Interp *interp, Jim_Obj *patternObjPtr, int mode)
+#define JIM_VARLIST_VALUES 0x1000
+
+static void JimVariablesMatch(Jim_Interp *interp, Jim_Obj *listObjPtr,
+ Jim_HashEntry *he, int type)
{
- Jim_HashTableIterator *htiter;
- Jim_HashEntry *he;
- Jim_Obj *listObjPtr = Jim_NewListObj(interp, NULL, 0);
+ Jim_Var *varPtr = (Jim_Var *)he->u.val;
- if (mode == JIM_VARLIST_GLOBALS) {
- htiter = Jim_GetHashTableIterator(&interp->topFramePtr->vars);
- }
- else {
- if (mode == JIM_VARLIST_LOCALS && interp->framePtr == interp->topFramePtr)
- return listObjPtr;
- htiter = Jim_GetHashTableIterator(&interp->framePtr->vars);
+ if (type != JIM_VARLIST_LOCALS || varPtr->linkFramePtr == NULL) {
+ Jim_ListAppendElement(interp, listObjPtr, Jim_NewStringObj(interp, he->key, -1));
+ if (type & JIM_VARLIST_VALUES) {
+ Jim_ListAppendElement(interp, listObjPtr, varPtr->objPtr);
+ }
}
- while ((he = Jim_NextHashEntry(htiter)) != NULL) {
- Jim_Var *varPtr = (Jim_Var *)he->u.val;
+}
- if (mode == JIM_VARLIST_LOCALS) {
- if (varPtr->linkFramePtr != NULL)
- continue;
- }
- if (patternObjPtr && !JimStringMatch(interp, patternObjPtr, he->key, 0))
- continue;
- Jim_ListAppendElement(interp, listObjPtr, Jim_NewStringObj(interp, he->key, -1));
+
+static Jim_Obj *JimVariablesList(Jim_Interp *interp, Jim_Obj *patternObjPtr, int mode)
+{
+ if (mode == JIM_VARLIST_LOCALS && interp->framePtr == interp->topFramePtr) {
+ return interp->emptyObj;
+ }
+ else {
+ Jim_CallFrame *framePtr = (mode == JIM_VARLIST_GLOBALS) ? interp->topFramePtr : interp->framePtr;
+ return JimHashtablePatternMatch(interp, &framePtr->vars, patternObjPtr, JimVariablesMatch, mode);
}
- Jim_FreeHashTableIterator(htiter);
- return listObjPtr;
}
static int JimInfoLevel(Jim_Interp *interp, Jim_Obj *levelObjPtr,
@@ -15360,7 +15629,6 @@ static int Jim_ForCoreCommand(Jim_Interp *interp, int argc, Jim_Obj *const *argv
ScriptObj *incrScript;
ExprByteCode *expr;
jim_wide stop, currentVal;
- unsigned jim_wide procEpoch;
Jim_Obj *objPtr;
int cmpOffset;
@@ -15413,7 +15681,6 @@ static int Jim_ForCoreCommand(Jim_Interp *interp, int argc, Jim_Obj *const *argv
}
- procEpoch = interp->procEpoch;
varNamePtr = expr->token[0].objPtr;
Jim_IncrRefCount(varNamePtr);
@@ -15443,9 +15710,6 @@ static int Jim_ForCoreCommand(Jim_Interp *interp, int argc, Jim_Obj *const *argv
retval = Jim_EvalObj(interp, argv[4]);
if (retval == JIM_OK || retval == JIM_CONTINUE) {
retval = JIM_OK;
- if (procEpoch != interp->procEpoch) {
- goto evalnext;
- }
objPtr = Jim_GetVariable(interp, varNamePtr, JIM_ERRMSG);
@@ -15569,100 +15833,124 @@ static int Jim_LoopCoreCommand(Jim_Interp *interp, int argc, Jim_Obj *const *arg
return retval;
}
+typedef struct {
+ Jim_Obj *objPtr;
+ int idx;
+} Jim_ListIter;
+
+static void JimListIterInit(Jim_ListIter *iter, Jim_Obj *objPtr)
+{
+ iter->objPtr = objPtr;
+ iter->idx = 0;
+}
+
+static Jim_Obj *JimListIterNext(Jim_Interp *interp, Jim_ListIter *iter)
+{
+ if (iter->idx >= Jim_ListLength(interp, iter->objPtr)) {
+ return NULL;
+ }
+ return iter->objPtr->internalRep.listValue.ele[iter->idx++];
+}
+
+static int JimListIterDone(Jim_Interp *interp, Jim_ListIter *iter)
+{
+ return iter->idx >= Jim_ListLength(interp, iter->objPtr);
+}
+
static int JimForeachMapHelper(Jim_Interp *interp, int argc, Jim_Obj *const *argv, int doMap)
{
- int result = JIM_ERR, i, nbrOfLists, *listsIdx, *listsEnd;
- int nbrOfLoops = 0;
- Jim_Obj *emptyStr, *script, *mapRes = NULL;
+ int result = JIM_ERR;
+ int i, numargs;
+ Jim_ListIter twoiters[2];
+ Jim_ListIter *iters;
+ Jim_Obj *script;
+ Jim_Obj *resultObj;
if (argc < 4 || argc % 2 != 0) {
Jim_WrongNumArgs(interp, 1, argv, "varList list ?varList list ...? script");
return JIM_ERR;
}
- if (doMap) {
- mapRes = Jim_NewListObj(interp, NULL, 0);
- Jim_IncrRefCount(mapRes);
- }
- emptyStr = Jim_NewEmptyStringObj(interp);
- Jim_IncrRefCount(emptyStr);
script = argv[argc - 1];
- nbrOfLists = (argc - 1 - 1) / 2;
- listsIdx = (int *)Jim_Alloc(nbrOfLists * sizeof(int));
- listsEnd = (int *)Jim_Alloc(nbrOfLists * 2 * sizeof(int));
-
- memset(listsIdx, 0, nbrOfLists * sizeof(int));
-
- for (i = 0; i < nbrOfLists * 2; i += 2) {
- div_t cnt;
- int count;
+ numargs = (argc - 1 - 1);
- listsEnd[i] = Jim_ListLength(interp, argv[i + 1]);
- listsEnd[i + 1] = Jim_ListLength(interp, argv[i + 2]);
- if (listsEnd[i] == 0) {
+ if (numargs == 2) {
+ iters = twoiters;
+ }
+ else {
+ iters = Jim_Alloc(numargs * sizeof(*iters));
+ }
+ for (i = 0; i < numargs; i++) {
+ JimListIterInit(&iters[i], argv[i + 1]);
+ if (i % 2 == 0 && JimListIterDone(interp, &iters[i])) {
Jim_SetResultString(interp, "foreach varlist is empty", -1);
- goto err;
+ return JIM_ERR;
}
- cnt = div(listsEnd[i + 1], listsEnd[i]);
- count = cnt.quot + (cnt.rem ? 1 : 0);
- if (count > nbrOfLoops)
- nbrOfLoops = count;
}
- for (; nbrOfLoops-- > 0;) {
- for (i = 0; i < nbrOfLists; ++i) {
- int varIdx = 0, var = i * 2;
- while (varIdx < listsEnd[var]) {
- Jim_Obj *varName, *ele;
- int lst = i * 2 + 1;
+ if (doMap) {
+ resultObj = Jim_NewListObj(interp, NULL, 0);
+ }
+ else {
+ resultObj = interp->emptyObj;
+ }
+ Jim_IncrRefCount(resultObj);
+
+ while (1) {
+
+ for (i = 0; i < numargs; i += 2) {
+ if (!JimListIterDone(interp, &iters[i + 1])) {
+ break;
+ }
+ }
+ if (i == numargs) {
+
+ break;
+ }
-
- Jim_ListIndex(interp, argv[var + 1], varIdx, &varName, JIM_NONE);
- if (listsIdx[i] < listsEnd[lst]) {
- Jim_ListIndex(interp, argv[lst + 1], listsIdx[i], &ele, JIM_NONE);
+
+ for (i = 0; i < numargs; i += 2) {
+ Jim_Obj *varName;
+
+
+ JimListIterInit(&iters[i], argv[i + 1]);
+ while ((varName = JimListIterNext(interp, &iters[i])) != NULL) {
+ Jim_Obj *valObj = JimListIterNext(interp, &iters[i + 1]);
+ if (!valObj) {
- Jim_IncrRefCount(ele);
- result = Jim_SetVariable(interp, varName, ele);
- Jim_DecrRefCount(interp, ele);
- if (result == JIM_OK) {
- ++listsIdx[i];
- ++varIdx;
- continue;
- }
+ valObj = interp->emptyObj;
}
- else if (Jim_SetVariable(interp, varName, emptyStr) == JIM_OK) {
- ++varIdx;
- continue;
+
+ Jim_IncrRefCount(valObj);
+ result = Jim_SetVariable(interp, varName, valObj);
+ Jim_DecrRefCount(interp, valObj);
+ if (result != JIM_OK) {
+ goto err;
}
- goto err;
}
}
switch (result = Jim_EvalObj(interp, script)) {
case JIM_OK:
- if (doMap)
- Jim_ListAppendElement(interp, mapRes, interp->result);
+ if (doMap) {
+ Jim_ListAppendElement(interp, resultObj, interp->result);
+ }
break;
case JIM_CONTINUE:
break;
case JIM_BREAK:
goto out;
- break;
default:
goto err;
}
}
out:
result = JIM_OK;
- if (doMap)
- Jim_SetResult(interp, mapRes);
- else
- Jim_SetEmptyResult(interp);
+ Jim_SetResult(interp, resultObj);
err:
- if (doMap)
- Jim_DecrRefCount(interp, mapRes);
- Jim_DecrRefCount(interp, emptyStr);
- Jim_Free(listsIdx);
- Jim_Free(listsEnd);
+ Jim_DecrRefCount(interp, resultObj);
+ if (numargs > 2) {
+ Jim_Free(iters);
+ }
return result;
}
@@ -15679,6 +15967,39 @@ static int Jim_LmapCoreCommand(Jim_Interp *interp, int argc, Jim_Obj *const *arg
}
+static int Jim_LassignCoreCommand(Jim_Interp *interp, int argc, Jim_Obj *const *argv)
+{
+ int result = JIM_ERR;
+ int i;
+ Jim_ListIter iter;
+ Jim_Obj *resultObj;
+
+ if (argc < 2) {
+ Jim_WrongNumArgs(interp, 1, argv, "varList list ?varName ...?");
+ return JIM_ERR;
+ }
+
+ JimListIterInit(&iter, argv[1]);
+
+ for (i = 2; i < argc; i++) {
+ Jim_Obj *valObj = JimListIterNext(interp, &iter);
+ result = Jim_SetVariable(interp, argv[i], valObj ? valObj : interp->emptyObj);
+ if (result != JIM_OK) {
+ return result;
+ }
+ }
+
+ resultObj = Jim_NewListObj(interp, NULL, 0);
+ while (!JimListIterDone(interp, &iter)) {
+ Jim_ListAppendElement(interp, resultObj, JimListIterNext(interp, &iter));
+ }
+
+ Jim_SetResult(interp, resultObj);
+
+ return JIM_OK;
+}
+
+
static int Jim_IfCoreCommand(Jim_Interp *interp, int argc, Jim_Obj *const *argv)
{
int boolean, retval, current = 1, falsebody = 0;
@@ -16004,7 +16325,7 @@ static int Jim_LsearchCoreCommand(Jim_Interp *interp, int argc, Jim_Obj *const *
Jim_ListIndex(interp, argv[0], i, &objPtr, JIM_NONE);
switch (opt_match) {
case OPT_EXACT:
- eq = Jim_StringCompareObj(interp, objPtr, argv[1], opt_nocase) == 0;
+ eq = Jim_StringCompareObj(interp, argv[1], objPtr, opt_nocase) == 0;
break;
case OPT_GLOB:
@@ -16112,8 +16433,8 @@ static int Jim_LinsertCoreCommand(Jim_Interp *interp, int argc, Jim_Obj *const *
int idx, len;
Jim_Obj *listPtr;
- if (argc < 4) {
- Jim_WrongNumArgs(interp, 1, argv, "list index element " "?element ...?");
+ if (argc < 3) {
+ Jim_WrongNumArgs(interp, 1, argv, "list index ?element ...?");
return JIM_ERR;
}
listPtr = argv[1];
@@ -16144,7 +16465,7 @@ static int Jim_LreplaceCoreCommand(Jim_Interp *interp, int argc, Jim_Obj *const
Jim_Obj *newListObj;
if (argc < 4) {
- Jim_WrongNumArgs(interp, 1, argv, "list first last ?element element ...?");
+ Jim_WrongNumArgs(interp, 1, argv, "list first last ?element ...?");
return JIM_ERR;
}
if (Jim_GetIndex(interp, argv[2], &first) != JIM_OK ||
@@ -16157,7 +16478,7 @@ static int Jim_LreplaceCoreCommand(Jim_Interp *interp, int argc, Jim_Obj *const
first = JimRelToAbsIndex(len, first);
last = JimRelToAbsIndex(len, last);
- JimRelToAbsRange(len, first, last, &first, &last, &rangeLen);
+ JimRelToAbsRange(len, &first, &last, &rangeLen);
@@ -16515,27 +16836,89 @@ static int Jim_ReturnCoreCommand(Jim_Interp *interp, int argc, Jim_Obj *const *a
static int Jim_TailcallCoreCommand(Jim_Interp *interp, int argc, Jim_Obj *const *argv)
{
- Jim_Obj *objPtr;
-
- objPtr = Jim_NewListObj(interp, argv + 1, argc - 1);
- Jim_SetResult(interp, objPtr);
+ Jim_SetResult(interp, Jim_NewListObj(interp, argv + 1, argc - 1));
return JIM_EVAL;
}
+static int JimAliasCmd(Jim_Interp *interp, int argc, Jim_Obj *const *argv)
+{
+ Jim_Obj *cmdList;
+ Jim_Obj *prefixListObj = Jim_CmdPrivData(interp);
+
+
+ cmdList = Jim_DuplicateObj(interp, prefixListObj);
+ ListInsertElements(cmdList, -1, argc - 1, argv + 1);
+
+ return JimEvalObjList(interp, cmdList);
+}
+
+static void JimAliasCmdDelete(Jim_Interp *interp, void *privData)
+{
+ Jim_Obj *prefixListObj = privData;
+ Jim_DecrRefCount(interp, prefixListObj);
+}
+
+static int Jim_AliasCoreCommand(Jim_Interp *interp, int argc, Jim_Obj *const *argv)
+{
+ Jim_Obj *prefixListObj;
+ const char *newname;
+
+ if (argc < 3) {
+ Jim_WrongNumArgs(interp, 1, argv, "newname command ?args ...?");
+ return JIM_ERR;
+ }
+
+ prefixListObj = Jim_NewListObj(interp, argv + 2, argc - 2);
+ Jim_IncrRefCount(prefixListObj);
+ newname = Jim_String(argv[1]);
+ if (newname[0] == ':' && newname[1] == ':') {
+ while (*++newname == ':') {
+ }
+ }
+
+ Jim_SetResult(interp, argv[1]);
+
+ return Jim_CreateCommand(interp, newname, JimAliasCmd, prefixListObj, JimAliasCmdDelete);
+}
+
static int Jim_ProcCoreCommand(Jim_Interp *interp, int argc, Jim_Obj *const *argv)
{
+ Jim_Cmd *cmd;
+
if (argc != 4 && argc != 5) {
Jim_WrongNumArgs(interp, 1, argv, "name arglist ?statics? body");
return JIM_ERR;
}
+ if (JimValidName(interp, "procedure", argv[1]) != JIM_OK) {
+ return JIM_ERR;
+ }
+
if (argc == 4) {
- return JimCreateProcedure(interp, argv[1], argv[2], NULL, argv[3]);
+ cmd = JimCreateProcedureCmd(interp, argv[2], NULL, argv[3], NULL);
}
else {
- return JimCreateProcedure(interp, argv[1], argv[2], argv[3], argv[4]);
+ cmd = JimCreateProcedureCmd(interp, argv[2], argv[3], argv[4], NULL);
+ }
+
+ if (cmd) {
+
+ Jim_Obj *qualifiedCmdNameObj;
+ const char *cmdname = JimQualifyName(interp, Jim_String(argv[1]), &qualifiedCmdNameObj);
+
+ JimCreateCommand(interp, cmdname, cmd);
+
+
+ JimUpdateProcNamespace(interp, cmd, cmdname);
+
+ JimFreeQualifiedName(interp, qualifiedCmdNameObj);
+
+
+ Jim_SetResult(interp, argv[1]);
+ return JIM_OK;
}
+ return JIM_ERR;
}
@@ -16551,17 +16934,17 @@ static int Jim_LocalCoreCommand(Jim_Interp *interp, int argc, Jim_Obj *const *ar
if (retcode == 0) {
- const char *procname = Jim_String(Jim_GetResult(interp));
+ Jim_Obj *cmdNameObj = Jim_GetResult(interp);
- if (Jim_FindHashEntry(&interp->commands, procname) == NULL) {
- Jim_SetResultFormatted(interp, "not a proc: \"%s\"", procname);
+ if (Jim_GetCommand(interp, cmdNameObj, JIM_ERRMSG) == NULL) {
return JIM_ERR;
}
- if (interp->localProcs == NULL) {
- interp->localProcs = Jim_Alloc(sizeof(*interp->localProcs));
- Jim_InitStack(interp->localProcs);
+ if (interp->framePtr->localCommands == NULL) {
+ interp->framePtr->localCommands = Jim_Alloc(sizeof(*interp->framePtr->localCommands));
+ Jim_InitStack(interp->framePtr->localCommands);
}
- Jim_StackPush(interp->localProcs, Jim_StrDup(procname));
+ Jim_IncrRefCount(cmdNameObj);
+ Jim_StackPush(interp->framePtr->localCommands, cmdNameObj);
}
return retcode;
@@ -16578,8 +16961,8 @@ static int Jim_UpcallCoreCommand(Jim_Interp *interp, int argc, Jim_Obj *const *a
int retcode;
Jim_Cmd *cmdPtr = Jim_GetCommand(interp, argv[1], JIM_ERRMSG);
- if (cmdPtr == NULL || !cmdPtr->isproc || !cmdPtr->u.proc.prevCmd) {
- Jim_SetResultFormatted(interp, "no previous proc: \"%#s\"", argv[1]);
+ if (cmdPtr == NULL || !cmdPtr->isproc || !cmdPtr->prevCmd) {
+ Jim_SetResultFormatted(interp, "no previous command: \"%#s\"", argv[1]);
return JIM_ERR;
}
@@ -16598,6 +16981,59 @@ static int Jim_UpcallCoreCommand(Jim_Interp *interp, int argc, Jim_Obj *const *a
}
+static int Jim_ApplyCoreCommand(Jim_Interp *interp, int argc, Jim_Obj *const *argv)
+{
+ if (argc < 2) {
+ Jim_WrongNumArgs(interp, 1, argv, "lambdaExpr ?arg ...?");
+ return JIM_ERR;
+ }
+ else {
+ int ret;
+ Jim_Cmd *cmd;
+ Jim_Obj *argListObjPtr;
+ Jim_Obj *bodyObjPtr;
+ Jim_Obj *nsObj = NULL;
+ Jim_Obj **nargv;
+
+ int len = Jim_ListLength(interp, argv[1]);
+ if (len != 2 && len != 3) {
+ Jim_SetResultFormatted(interp, "can't interpret \"%#s\" as a lambda expression", argv[1]);
+ return JIM_ERR;
+ }
+
+ if (len == 3) {
+#ifdef jim_ext_namespace
+
+ nsObj = JimQualifyNameObj(interp, Jim_ListGetIndex(interp, argv[1], 2));
+#else
+ Jim_SetResultString(interp, "namespaces not enabled", -1);
+ return JIM_ERR;
+#endif
+ }
+ argListObjPtr = Jim_ListGetIndex(interp, argv[1], 0);
+ bodyObjPtr = Jim_ListGetIndex(interp, argv[1], 1);
+
+ cmd = JimCreateProcedureCmd(interp, argListObjPtr, NULL, bodyObjPtr, nsObj);
+
+ if (cmd) {
+
+ nargv = Jim_Alloc((argc - 2 + 1) * sizeof(*nargv));
+ nargv[0] = Jim_NewStringObj(interp, "apply lambdaExpr", -1);
+ Jim_IncrRefCount(nargv[0]);
+ memcpy(&nargv[1], argv + 2, (argc - 2) * sizeof(*nargv));
+ ret = JimCallProcedure(interp, cmd, argc - 2 + 1, nargv);
+ Jim_DecrRefCount(interp, nargv[0]);
+ Jim_Free(nargv);
+
+ JimDecrCmdRefCount(interp, cmd);
+ return ret;
+ }
+ return JIM_ERR;
+ }
+}
+
+
+
static int Jim_ConcatCoreCommand(Jim_Interp *interp, int argc, Jim_Obj *const *argv)
{
Jim_SetResult(interp, Jim_ConcatObj(interp, argc - 1, argv + 1));
@@ -16650,8 +17086,12 @@ static int Jim_GlobalCoreCommand(Jim_Interp *interp, int argc, Jim_Obj *const *a
if (interp->framePtr->level == 0)
return JIM_OK;
for (i = 1; i < argc; i++) {
- if (Jim_SetVariableLink(interp, argv[i], argv[i], interp->topFramePtr) != JIM_OK)
- return JIM_ERR;
+
+ const char *name = Jim_String(argv[i]);
+ if (name[0] != ':' || name[1] != ':') {
+ if (Jim_SetVariableLink(interp, argv[i], argv[i], interp->topFramePtr) != JIM_OK)
+ return JIM_ERR;
+ }
}
return JIM_OK;
}
@@ -16687,12 +17127,7 @@ static Jim_Obj *JimStringMap(Jim_Interp *interp, Jim_Obj *mapListObjPtr,
if (strLen >= kl && kl) {
int rc;
- if (nocase) {
- rc = JimStringCompareNoCase(str, k, kl);
- }
- else {
- rc = JimStringCompare(str, kl, k, kl);
- }
+ rc = JimStringCompareLen(str, k, kl, nocase);
if (rc == 0) {
if (noMatchStart) {
Jim_AppendString(interp, resultObjPtr, noMatchStart, str - noMatchStart);
@@ -16727,15 +17162,15 @@ static int Jim_StringCoreCommand(Jim_Interp *interp, int argc, Jim_Obj *const *a
int opt_case = 1;
int option;
static const char * const options[] = {
- "bytelength", "length", "compare", "match", "equal", "is", "byterange", "range", "map",
- "repeat", "reverse", "index", "first", "last",
- "trim", "trimleft", "trimright", "tolower", "toupper", NULL
+ "bytelength", "length", "compare", "match", "equal", "is", "byterange", "range", "replace",
+ "map", "repeat", "reverse", "index", "first", "last",
+ "trim", "trimleft", "trimright", "tolower", "toupper", "totitle", NULL
};
enum
{
- OPT_BYTELENGTH, OPT_LENGTH, OPT_COMPARE, OPT_MATCH, OPT_EQUAL, OPT_IS, OPT_BYTERANGE, OPT_RANGE, OPT_MAP,
- OPT_REPEAT, OPT_REVERSE, OPT_INDEX, OPT_FIRST, OPT_LAST,
- OPT_TRIM, OPT_TRIMLEFT, OPT_TRIMRIGHT, OPT_TOLOWER, OPT_TOUPPER
+ OPT_BYTELENGTH, OPT_LENGTH, OPT_COMPARE, OPT_MATCH, OPT_EQUAL, OPT_IS, OPT_BYTERANGE, OPT_RANGE, OPT_REPLACE,
+ OPT_MAP, OPT_REPEAT, OPT_REVERSE, OPT_INDEX, OPT_FIRST, OPT_LAST,
+ OPT_TRIM, OPT_TRIMLEFT, OPT_TRIMRIGHT, OPT_TOLOWER, OPT_TOUPPER, OPT_TOTITLE
};
static const char * const nocase_options[] = {
"-nocase", NULL
@@ -16844,6 +17279,22 @@ static int Jim_StringCoreCommand(Jim_Interp *interp, int argc, Jim_Obj *const *a
return JIM_OK;
}
+ case OPT_REPLACE:{
+ Jim_Obj *objPtr;
+
+ if (argc != 5 && argc != 6) {
+ Jim_WrongNumArgs(interp, 2, argv, "string first last ?newstring?");
+ return JIM_ERR;
+ }
+ objPtr = JimStringReplaceObj(interp, argv[2], argv[3], argv[4], argc == 6 ? argv[5] : NULL);
+ if (objPtr == NULL) {
+ return JIM_ERR;
+ }
+ Jim_SetResult(interp, objPtr);
+ return JIM_OK;
+ }
+
+
case OPT_REPEAT:{
Jim_Obj *objPtr;
jim_wide count;
@@ -16982,6 +17433,7 @@ static int Jim_StringCoreCommand(Jim_Interp *interp, int argc, Jim_Obj *const *a
case OPT_TOLOWER:
case OPT_TOUPPER:
+ case OPT_TOTITLE:
if (argc != 3) {
Jim_WrongNumArgs(interp, 2, argv, "string");
return JIM_ERR;
@@ -16989,9 +17441,12 @@ static int Jim_StringCoreCommand(Jim_Interp *interp, int argc, Jim_Obj *const *a
if (option == OPT_TOLOWER) {
Jim_SetResult(interp, JimStringToLower(interp, argv[2]));
}
- else {
+ else if (option == OPT_TOUPPER) {
Jim_SetResult(interp, JimStringToUpper(interp, argv[2]));
}
+ else {
+ Jim_SetResult(interp, JimStringToTitle(interp, argv[2]));
+ }
return JIM_OK;
case OPT_IS:
@@ -17302,8 +17757,6 @@ static int JimInfoReferences(Jim_Interp *interp, int argc, Jim_Obj *const *argv)
static int Jim_RenameCoreCommand(Jim_Interp *interp, int argc, Jim_Obj *const *argv)
{
- const char *oldName, *newName;
-
if (argc != 3) {
Jim_WrongNumArgs(interp, 1, argv, "oldName newName");
return JIM_ERR;
@@ -17313,38 +17766,55 @@ static int Jim_RenameCoreCommand(Jim_Interp *interp, int argc, Jim_Obj *const *a
return JIM_ERR;
}
- oldName = Jim_String(argv[1]);
- newName = Jim_String(argv[2]);
- return Jim_RenameCommand(interp, oldName, newName);
+ return Jim_RenameCommand(interp, Jim_String(argv[1]), Jim_String(argv[2]));
}
-int Jim_DictKeys(Jim_Interp *interp, Jim_Obj *objPtr, Jim_Obj *patternObj)
-{
- int i;
- int len;
- Jim_Obj *resultObj;
- Jim_Obj *dictObj;
- Jim_Obj **dictValuesObj;
+#define JIM_DICTMATCH_VALUES 0x0001
- if (Jim_DictKeysVector(interp, objPtr, NULL, 0, &dictObj, JIM_ERRMSG) != JIM_OK) {
- return JIM_ERR;
- }
+typedef void JimDictMatchCallbackType(Jim_Interp *interp, Jim_Obj *listObjPtr, Jim_HashEntry *he, int type);
- if (Jim_DictPairs(interp, dictObj, &dictValuesObj, &len) != JIM_OK) {
- return JIM_ERR;
+static void JimDictMatchKeys(Jim_Interp *interp, Jim_Obj *listObjPtr, Jim_HashEntry *he, int type)
+{
+ Jim_ListAppendElement(interp, listObjPtr, (Jim_Obj *)he->key);
+ if (type & JIM_DICTMATCH_VALUES) {
+ Jim_ListAppendElement(interp, listObjPtr, (Jim_Obj *)he->u.val);
}
+}
-
- resultObj = Jim_NewListObj(interp, NULL, 0);
+static Jim_Obj *JimDictPatternMatch(Jim_Interp *interp, Jim_HashTable *ht, Jim_Obj *patternObjPtr,
+ JimDictMatchCallbackType *callback, int type)
+{
+ Jim_HashEntry *he;
+ Jim_Obj *listObjPtr = Jim_NewListObj(interp, NULL, 0);
- for (i = 0; i < len; i += 2) {
- if (patternObj == NULL || Jim_StringMatchObj(interp, patternObj, dictValuesObj[i], 0)) {
- Jim_ListAppendElement(interp, resultObj, dictValuesObj[i]);
+
+ Jim_HashTableIterator *htiter = Jim_GetHashTableIterator(ht);
+ while ((he = Jim_NextHashEntry(htiter)) != NULL) {
+ if (patternObjPtr == NULL || JimGlobMatch(Jim_String(patternObjPtr), Jim_String((Jim_Obj *)he->key), 0)) {
+ callback(interp, listObjPtr, he, type);
}
}
- Jim_Free(dictValuesObj);
+ Jim_FreeHashTableIterator(htiter);
- Jim_SetResult(interp, resultObj);
+ return listObjPtr;
+}
+
+
+int Jim_DictKeys(Jim_Interp *interp, Jim_Obj *objPtr, Jim_Obj *patternObjPtr)
+{
+ if (SetDictFromAny(interp, objPtr) != JIM_OK) {
+ return JIM_ERR;
+ }
+ Jim_SetResult(interp, JimDictPatternMatch(interp, objPtr->internalRep.ptr, patternObjPtr, JimDictMatchKeys, 0));
+ return JIM_OK;
+}
+
+int Jim_DictValues(Jim_Interp *interp, Jim_Obj *objPtr, Jim_Obj *patternObjPtr)
+{
+ if (SetDictFromAny(interp, objPtr) != JIM_OK) {
+ return JIM_ERR;
+ }
+ Jim_SetResult(interp, JimDictPatternMatch(interp, objPtr->internalRep.ptr, patternObjPtr, JimDictMatchKeys, JIM_DICTMATCH_VALUES));
return JIM_OK;
}
@@ -17441,7 +17911,7 @@ static int Jim_DictCoreCommand(Jim_Interp *interp, int argc, Jim_Obj *const *arg
if (argc == 2) {
return JIM_OK;
}
- else if (argv[2]->typePtr != &dictObjType && SetDictFromAny(interp, argv[2]) != JIM_OK) {
+ else if (SetDictFromAny(interp, argv[2]) != JIM_OK) {
return JIM_ERR;
}
else {
@@ -17520,24 +17990,31 @@ static int Jim_InfoCoreCommand(Jim_Interp *interp, int argc, Jim_Obj *const *arg
int cmd;
Jim_Obj *objPtr;
int mode = 0;
+ int nons = 0;
static const char * const commands[] = {
- "body", "commands", "procs", "channels", "exists", "globals", "level", "frame", "locals",
+ "body", "statics", "commands", "procs", "channels", "exists", "globals", "level", "frame", "locals",
"vars", "version", "patchlevel", "complete", "args", "hostname",
"script", "source", "stacktrace", "nameofexecutable", "returncodes",
- "references", NULL
+ "references", "alias", NULL
};
enum
- { INFO_BODY, INFO_COMMANDS, INFO_PROCS, INFO_CHANNELS, INFO_EXISTS, INFO_GLOBALS, INFO_LEVEL,
+ { INFO_BODY, INFO_STATICS, INFO_COMMANDS, INFO_PROCS, INFO_CHANNELS, INFO_EXISTS, INFO_GLOBALS, INFO_LEVEL,
INFO_FRAME, INFO_LOCALS, INFO_VARS, INFO_VERSION, INFO_PATCHLEVEL, INFO_COMPLETE, INFO_ARGS,
INFO_HOSTNAME, INFO_SCRIPT, INFO_SOURCE, INFO_STACKTRACE, INFO_NAMEOFEXECUTABLE,
- INFO_RETURNCODES, INFO_REFERENCES,
+ INFO_RETURNCODES, INFO_REFERENCES, INFO_ALIAS
};
if (argc < 2) {
Jim_WrongNumArgs(interp, 1, argv, "subcommand ?args ...?");
return JIM_ERR;
}
+ if (argc > 2 && Jim_CompareStringImmediate(interp, argv[1], "-nons")) {
+
+ argc--;
+ argv++;
+ nons = 1;
+ }
if (Jim_GetEnum(interp, argv[1], commands, &cmd, "subcommand", JIM_ERRMSG | JIM_ENUM_ABBREV)
!= JIM_OK) {
return JIM_ERR;
@@ -17545,28 +18022,54 @@ static int Jim_InfoCoreCommand(Jim_Interp *interp, int argc, Jim_Obj *const *arg
switch (cmd) {
- case INFO_EXISTS:{
- if (argc != 3) {
- Jim_WrongNumArgs(interp, 2, argv, "varName");
- return JIM_ERR;
- }
- Jim_SetResultBool(interp, Jim_GetVariable(interp, argv[2], 0) != NULL);
- break;
+ case INFO_EXISTS:
+ if (argc != 3) {
+ Jim_WrongNumArgs(interp, 2, argv, "varName");
+ return JIM_ERR;
+ }
+ Jim_SetResultBool(interp, Jim_GetVariable(interp, argv[2], 0) != NULL);
+ break;
+
+ case INFO_ALIAS:{
+ Jim_Cmd *cmdPtr;
+
+ if (argc != 3) {
+ Jim_WrongNumArgs(interp, 2, argv, "command");
+ return JIM_ERR;
+ }
+ if ((cmdPtr = Jim_GetCommand(interp, argv[2], JIM_ERRMSG)) == NULL) {
+ return JIM_ERR;
+ }
+ if (cmdPtr->isproc || cmdPtr->u.native.cmdProc != JimAliasCmd) {
+ Jim_SetResultFormatted(interp, "command \"%#s\" is not an alias", argv[2]);
+ return JIM_ERR;
}
+ Jim_SetResult(interp, (Jim_Obj *)cmdPtr->u.native.privData);
+ return JIM_OK;
+ }
case INFO_CHANNELS:
+ mode++;
#ifndef jim_ext_aio
Jim_SetResultString(interp, "aio not enabled", -1);
return JIM_ERR;
#endif
- case INFO_COMMANDS:
case INFO_PROCS:
+ mode++;
+ case INFO_COMMANDS:
+
if (argc != 2 && argc != 3) {
Jim_WrongNumArgs(interp, 2, argv, "?pattern?");
return JIM_ERR;
}
- Jim_SetResult(interp, JimCommandsList(interp, (argc == 3) ? argv[2] : NULL,
- (cmd - INFO_COMMANDS)));
+#ifdef jim_ext_namespace
+ if (!nons) {
+ if (Jim_Length(interp->framePtr->nsObj) || (argc == 3 && JimGlobMatch("::*", Jim_String(argv[2]), 0))) {
+ return Jim_EvalPrefix(interp, "namespace info", argc - 1, argv + 1);
+ }
+ }
+#endif
+ Jim_SetResult(interp, JimCommandsList(interp, (argc == 3) ? argv[2] : NULL, mode));
break;
case INFO_VARS:
@@ -17579,6 +18082,13 @@ static int Jim_InfoCoreCommand(Jim_Interp *interp, int argc, Jim_Obj *const *arg
Jim_WrongNumArgs(interp, 2, argv, "?pattern?");
return JIM_ERR;
}
+#ifdef jim_ext_namespace
+ if (!nons) {
+ if (Jim_Length(interp->framePtr->nsObj) || (argc == 3 && JimGlobMatch("::*", Jim_String(argv[2]), 0))) {
+ return Jim_EvalPrefix(interp, "namespace info", argc - 1, argv + 1);
+ }
+ }
+#endif
Jim_SetResult(interp, JimVariablesList(interp, argc == 3 ? argv[2] : NULL, mode));
break;
@@ -17606,7 +18116,7 @@ static int Jim_InfoCoreCommand(Jim_Interp *interp, int argc, Jim_Obj *const *arg
else if (argv[2]->typePtr == &scriptObjType) {
ScriptObj *script = Jim_GetScript(interp, argv[2]);
fileNameObj = script->fileNameObj;
- line = script->line;
+ line = script->firstline;
}
else {
fileNameObj = interp->emptyObj;
@@ -17644,6 +18154,7 @@ static int Jim_InfoCoreCommand(Jim_Interp *interp, int argc, Jim_Obj *const *arg
break;
case INFO_BODY:
+ case INFO_STATICS:
case INFO_ARGS:{
Jim_Cmd *cmdPtr;
@@ -17658,8 +18169,21 @@ static int Jim_InfoCoreCommand(Jim_Interp *interp, int argc, Jim_Obj *const *arg
Jim_SetResultFormatted(interp, "command \"%#s\" is not a procedure", argv[2]);
return JIM_ERR;
}
- Jim_SetResult(interp,
- cmd == INFO_BODY ? cmdPtr->u.proc.bodyObjPtr : cmdPtr->u.proc.argListObjPtr);
+ switch (cmd) {
+ case INFO_BODY:
+ Jim_SetResult(interp, cmdPtr->u.proc.bodyObjPtr);
+ break;
+ case INFO_ARGS:
+ Jim_SetResult(interp, cmdPtr->u.proc.argListObjPtr);
+ break;
+ case INFO_STATICS:
+ if (cmdPtr->u.proc.staticVars) {
+ int mode = JIM_VARLIST_LOCALS | JIM_VARLIST_VALUES;
+ Jim_SetResult(interp, JimHashtablePatternMatch(interp, cmdPtr->u.proc.staticVars,
+ NULL, JimVariablesMatch, mode));
+ }
+ break;
+ }
break;
}
@@ -17745,13 +18269,14 @@ static int Jim_InfoCoreCommand(Jim_Interp *interp, int argc, Jim_Obj *const *arg
static int Jim_ExistsCoreCommand(Jim_Interp *interp, int argc, Jim_Obj *const *argv)
{
Jim_Obj *objPtr;
+ int result = 0;
static const char * const options[] = {
- "-command", "-proc", "-var", NULL
+ "-command", "-proc", "-alias", "-var", NULL
};
enum
{
- OPT_COMMAND, OPT_PROC, OPT_VAR
+ OPT_COMMAND, OPT_PROC, OPT_ALIAS, OPT_VAR
};
int option;
@@ -17770,19 +18295,30 @@ static int Jim_ExistsCoreCommand(Jim_Interp *interp, int argc, Jim_Obj *const *a
return JIM_ERR;
}
-
- switch (option) {
- case OPT_VAR:
- Jim_SetResultBool(interp, Jim_GetVariable(interp, objPtr, 0) != NULL);
- break;
+ if (option == OPT_VAR) {
+ result = Jim_GetVariable(interp, objPtr, 0) != NULL;
+ }
+ else {
+
+ Jim_Cmd *cmd = Jim_GetCommand(interp, objPtr, JIM_NONE);
- case OPT_COMMAND:
- case OPT_PROC: {
- Jim_Cmd *cmd = Jim_GetCommand(interp, objPtr, JIM_NONE);
- Jim_SetResultBool(interp, cmd != NULL && (option == OPT_COMMAND || cmd->isproc));
- break;
+ if (cmd) {
+ switch (option) {
+ case OPT_COMMAND:
+ result = 1;
+ break;
+
+ case OPT_ALIAS:
+ result = cmd->isproc == 0 && cmd->u.native.cmdProc == JimAliasCmd;
+ break;
+
+ case OPT_PROC:
+ result = cmd->isproc;
+ break;
+ }
}
}
+ Jim_SetResultBool(interp, result);
return JIM_OK;
}
@@ -17876,8 +18412,7 @@ static int Jim_SplitCoreCommand(Jim_Interp *interp, int argc, Jim_Obj *const *ar
static int Jim_JoinCoreCommand(Jim_Interp *interp, int argc, Jim_Obj *const *argv)
{
const char *joinStr;
- int joinStrLen, i, listLen;
- Jim_Obj *resObjPtr;
+ int joinStrLen;
if (argc != 2 && argc != 3) {
Jim_WrongNumArgs(interp, 1, argv, "list ?joinString?");
@@ -17891,19 +18426,7 @@ static int Jim_JoinCoreCommand(Jim_Interp *interp, int argc, Jim_Obj *const *arg
else {
joinStr = Jim_GetString(argv[2], &joinStrLen);
}
- listLen = Jim_ListLength(interp, argv[1]);
- resObjPtr = Jim_NewStringObj(interp, NULL, 0);
-
- for (i = 0; i < listLen; i++) {
- Jim_Obj *objPtr = 0;
-
- Jim_ListIndex(interp, argv[1], i, &objPtr, JIM_NONE);
- Jim_AppendObj(interp, resObjPtr, objPtr);
- if (i + 1 != listLen) {
- Jim_AppendString(interp, resObjPtr, joinStr, joinStrLen);
- }
- }
- Jim_SetResult(interp, resObjPtr);
+ Jim_SetResult(interp, Jim_ListJoin(interp, argv[1], joinStr, joinStrLen));
return JIM_OK;
}
@@ -18256,6 +18779,7 @@ static const struct {
const char *name;
Jim_CmdProc cmdProc;
} Jim_CoreCommandsTable[] = {
+ {"alias", Jim_AliasCoreCommand},
{"set", Jim_SetCoreCommand},
{"unset", Jim_UnsetCoreCommand},
{"puts", Jim_PutsCoreCommand},
@@ -18269,6 +18793,7 @@ static const struct {
{"for", Jim_ForCoreCommand},
{"foreach", Jim_ForeachCoreCommand},
{"lmap", Jim_LmapCoreCommand},
+ {"lassign", Jim_LassignCoreCommand},
{"if", Jim_IfCoreCommand},
{"switch", Jim_SwitchCoreCommand},
{"list", Jim_ListCoreCommand},
@@ -18323,6 +18848,7 @@ static const struct {
{"tailcall", Jim_TailcallCoreCommand},
{"local", Jim_LocalCoreCommand},
{"upcall", Jim_UpcallCoreCommand},
+ {"apply", Jim_ApplyCoreCommand},
{NULL, NULL},
};
@@ -18560,7 +19086,7 @@ static void add_cmd_usage(Jim_Interp *interp, const jim_subcmd_type * ct, Jim_Ob
static void set_wrong_args(Jim_Interp *interp, const jim_subcmd_type * command_table, Jim_Obj *subcmd)
{
- Jim_SetResultString(interp, "wrong # args: must be \"", -1);
+ Jim_SetResultString(interp, "wrong # args: should be \"", -1);
add_cmd_usage(interp, command_table, subcmd);
Jim_AppendStrings(interp, Jim_GetResult(interp), "\"", NULL);
}
@@ -18657,7 +19183,7 @@ const jim_subcmd_type *Jim_ParseSubCmd(Jim_Interp *interp, const jim_subcmd_type
if (argc - 2 < ct->minargs || (ct->maxargs >= 0 && argc - 2 > ct->maxargs)) {
- Jim_SetResultString(interp, "wrong # args: must be \"", -1);
+ Jim_SetResultString(interp, "wrong # args: should be \"", -1);
add_cmd_usage(interp, ct, argv[0]);
Jim_AppendStrings(interp, Jim_GetResult(interp), "\"", NULL);
@@ -18703,7 +19229,7 @@ int Jim_SubCmdProc(Jim_Interp *interp, int argc, Jim_Obj *const *argv)
#include <assert.h>
-int utf8_fromunicode(char *p, unsigned short uc)
+int utf8_fromunicode(char *p, unsigned uc)
{
if (uc <= 0x7f) {
*p = uc;
@@ -18714,12 +19240,20 @@ int utf8_fromunicode(char *p, unsigned short uc)
*p = 0x80 | (uc & 0x3f);
return 2;
}
- else {
+ else if (uc <= 0xffff) {
*p++ = 0xe0 | ((uc & 0xf000) >> 12);
*p++ = 0x80 | ((uc & 0xfc0) >> 6);
*p = 0x80 | (uc & 0x3f);
return 3;
}
+
+ else {
+ *p++ = 0xf0 | ((uc & 0x1c0000) >> 18);
+ *p++ = 0x80 | ((uc & 0x3f000) >> 12);
+ *p++ = 0x80 | ((uc & 0xfc0) >> 6);
+ *p = 0x80 | (uc & 0x3f);
+ return 4;
+ }
}
#include <ctype.h>
@@ -19102,10 +19636,12 @@ Jim_Obj *Jim_FormatString(Jim_Interp *interp, Jim_Obj *fmtObjPtr, int objc, Jim_
#define WORDA 15
#define WORDZ 16
+#define OPENNC 19
#define OPEN 20
-#define CLOSE (OPEN+REG_MAX_PAREN)
+#define CLOSE (OPEN+REG_MAX_PAREN+1)
#define CLOSE_END (CLOSE+REG_MAX_PAREN)
+#define CLOSENC (CLOSE-1)
#define REG_MAGIC 0xFADED00D
@@ -19146,7 +19682,7 @@ static int prefix_cmp(const int *prog, int proglen, const char *string, int noca
#ifdef DEBUG
-int regnarrate = 0;
+static int regnarrate = 0;
static void regdump(regex_t *preg);
static const char *regprop( int op );
#endif
@@ -19183,13 +19719,11 @@ int regcomp(regex_t *preg, const char *exp, int cflags)
preg->program = NULL;
preg->proglen = 0;
-#if 1
preg->proglen = (strlen(exp) + 1) * 5;
preg->program = malloc(preg->proglen * sizeof(int));
if (preg->program == NULL)
FAIL(preg, REG_ERR_NOMEM);
-#endif
regc(preg, REG_MAGIC);
if (reg(preg, 0, &flags) == 0) {
@@ -19252,7 +19786,14 @@ static int reg(regex_t *preg, int paren , int *flagp )
if (paren) {
- parno = ++preg->re_nsub;
+ if (preg->regparse[0] == '?' && preg->regparse[1] == ':') {
+
+ preg->regparse += 2;
+ parno = -1;
+ }
+ else {
+ parno = ++preg->re_nsub;
+ }
ret = regnode(preg, OPEN+parno);
} else
ret = 0;
@@ -19499,10 +20040,25 @@ static int reg_decode_escape(const char *s, int *ch)
case 't': *ch = '\t'; break;
case 'v': *ch = '\v'; break;
case 'u':
- if ((n = parse_hex(s, 4, ch)) > 0) {
+ if (*s == '{') {
+
+ n = parse_hex(s + 1, 6, ch);
+ if (n > 0 && s[n + 1] == '}' && *ch >= 0 && *ch <= 0x1fffff) {
+ s += n + 2;
+ }
+ else {
+
+ *ch = 'u';
+ }
+ }
+ else if ((n = parse_hex(s, 4, ch)) > 0) {
s += n;
}
break;
+ case 'U':
+ if ((n = parse_hex(s, 8, ch)) > 0) {
+ s += n;
+ }
case 'x':
if ((n = parse_hex(s, 2, ch)) > 0) {
s += n;
@@ -19568,7 +20124,7 @@ static int regatom(regex_t *preg, int *flagp)
return 0;
}
}
- if (pattern[0] == '-' && pattern[1]) {
+ if (pattern[0] == '-' && pattern[1] && pattern[1] != ']') {
pattern += utf8_tounicode(pattern, &end);
pattern += reg_utf8_tounicode_case(pattern, &end, nocase);
@@ -19843,13 +20399,30 @@ int regexec(regex_t *preg, const char *string, size_t nmatch, regmatch_t pmat
preg->start = string;
- for (scan = OPERAND(1); scan != 0; scan = regnext(preg, scan)) {
+ for (scan = OPERAND(1); scan != 0; ) {
switch (OP(preg, scan)) {
case REP:
case REPMIN:
case REPX:
case REPXMIN:
preg->program[scan + 4] = 0;
+ scan += 5;
+ break;
+
+ case ANYOF:
+ case ANYBUT:
+ case EXACTLY:
+ scan += 2;
+ while (preg->program[scan++]) {
+ }
+ break;
+
+ case END:
+ scan = 0;
+ break;
+
+ default:
+ scan += 2;
break;
}
}
@@ -19877,8 +20450,7 @@ int regexec(regex_t *preg, const char *string, size_t nmatch, regmatch_t pmat
goto nextline;
}
while (1) {
- int ret = regtry(preg, string);
- if (ret) {
+ if (regtry(preg, string)) {
return REG_NOERROR;
}
if (*string) {
@@ -19914,7 +20486,10 @@ nextline:
if (*s == '\0') {
break;
}
- s += utf8_charlen(*s);
+ else {
+ int c;
+ s += utf8_tounicode(s, &c);
+ }
}
@@ -20223,6 +20798,14 @@ static int regmatch(regex_t *preg, int prog)
case END:
return(1);
break;
+
+ case OPENNC:
+ case CLOSENC:
+ if (regmatch(preg, next)) {
+ return 1;
+ }
+ return 0;
+
default:
if (OP(preg, scan) >= OPEN+1 && OP(preg, scan) < CLOSE_END) {
const char *save;
@@ -20493,15 +21076,19 @@ struct dirent *readdir(DIR * dir)
#include <errno.h>
#include <string.h>
+
#ifdef USE_LINENOISE
#include <unistd.h>
#include "linenoise.h"
#else
-
#define MAX_LINE_LEN 512
+#endif
-static char *linenoise(const char *prompt)
+char *Jim_HistoryGetline(const char *prompt)
{
+#ifdef USE_LINENOISE
+ return linenoise(prompt);
+#else
char *line = malloc(MAX_LINE_LEN);
fputs(prompt, stdout);
@@ -20512,8 +21099,42 @@ static char *linenoise(const char *prompt)
return NULL;
}
return line;
+#endif
}
+
+void Jim_HistoryLoad(const char *filename)
+{
+#ifdef USE_LINENOISE
+ linenoiseHistoryLoad(filename);
#endif
+}
+
+void Jim_HistoryAdd(const char *line)
+{
+#ifdef USE_LINENOISE
+ linenoiseHistoryAdd(line);
+#endif
+}
+
+void Jim_HistorySave(const char *filename)
+{
+#ifdef USE_LINENOISE
+ linenoiseHistorySave(filename);
+#endif
+}
+
+void Jim_HistoryShow(void)
+{
+#ifdef USE_LINENOISE
+
+ int i;
+ int len;
+ char **history = linenoiseHistory(&len);
+ for (i = 0; i < len; i++) {
+ printf("%4d %s\n", i + 1, history[i]);
+ }
+#endif
+}
int Jim_InteractivePrompt(Jim_Interp *interp)
{
@@ -20527,7 +21148,7 @@ int Jim_InteractivePrompt(Jim_Interp *interp)
int history_len = strlen(home) + sizeof("/.jim_history");
history_file = Jim_Alloc(history_len);
snprintf(history_file, history_len, "%s/.jim_history", home);
- linenoiseHistoryLoad(history_file);
+ Jim_HistoryLoad(history_file);
}
#endif
@@ -20564,12 +21185,13 @@ int Jim_InteractivePrompt(Jim_Interp *interp)
int len;
char *line;
- line = linenoise(prompt);
+ line = Jim_HistoryGetline(prompt);
if (line == NULL) {
if (errno == EINTR) {
continue;
}
Jim_DecrRefCount(interp, scriptObjPtr);
+ retcode = JIM_OK;
goto out;
}
if (Jim_Length(scriptObjPtr) != 0) {
@@ -20589,29 +21211,22 @@ int Jim_InteractivePrompt(Jim_Interp *interp)
#ifdef USE_LINENOISE
if (strcmp(str, "h") == 0) {
- int i;
- int len;
- char **history = linenoiseHistory(&len);
- for (i = 0; i < len; i++) {
- printf("%4d %s\n", i + 1, history[i]);
- }
+ Jim_HistoryShow();
Jim_DecrRefCount(interp, scriptObjPtr);
continue;
}
- linenoiseHistoryAdd(Jim_String(scriptObjPtr));
+ Jim_HistoryAdd(Jim_String(scriptObjPtr));
if (history_file) {
- linenoiseHistorySave(history_file);
+ Jim_HistorySave(history_file);
}
#endif
retcode = Jim_EvalObj(interp, scriptObjPtr);
Jim_DecrRefCount(interp, scriptObjPtr);
-
-
if (retcode == JIM_EXIT) {
- Jim_Free(history_file);
- return JIM_EXIT;
+ retcode = JIM_EXIT;
+ break;
}
if (retcode == JIM_ERR) {
Jim_MakeErrorMessage(interp);
@@ -20623,7 +21238,7 @@ int Jim_InteractivePrompt(Jim_Interp *interp)
}
out:
Jim_Free(history_file);
- return JIM_OK;
+ return retcode;
}
#include <stdio.h>