sync up to latest jim tcl
authoroharboe <oharboe@b42882b7-edfa-0310-969c-e2dbd0fdcd60>
Tue, 16 Dec 2008 21:10:06 +0000 (21:10 +0000)
committeroharboe <oharboe@b42882b7-edfa-0310-969c-e2dbd0fdcd60>
Tue, 16 Dec 2008 21:10:06 +0000 (21:10 +0000)
git-svn-id: svn://svn.berlios.de/openocd/trunk@1250 b42882b7-edfa-0310-969c-e2dbd0fdcd60

src/helper/jim.c
src/helper/jim.h

index 75e7e6c..800db23 100644 (file)
@@ -7,6 +7,7 @@
  * Copyright 2008 Andrew Lunn <andrew@lunn.ch>
  * Copyright 2008 Duane Ellis <openocd@duaneellis.com>
  * Copyright 2008 Uwe Klein <uklein@klein-messgeraete.de>
+ * Copyright 2008 Steve Bennett <steveb@workware.net.au>
  * 
  * The FreeBSD license
  * 
 #endif /* WIN32 */
 #endif /* JIM_DYNLIB */
 
+#ifndef WIN32
+#include <unistd.h>
+#endif
+
 #ifdef __ECOS
 #include <cyg/jimtcl/jim.h>
 #else
@@ -1325,19 +1330,21 @@ int JimParseVar(struct JimParserCtx *pc)
     if (brace) {
         while (!stop) {
             if (*pc->p == '}' || pc->len == 0) {
+                pc->tend = pc->p-1;
                 stop = 1;
                 if (pc->len == 0)
-                    continue;
+                    break;
             }
             else if (*pc->p == '\n')
                 pc->linenr++;
             pc->p++; pc->len--;
         }
-        if (pc->len == 0)
-            pc->tend = pc->p-1;
-        else
-            pc->tend = pc->p-2;
     } else {
+        /* Include leading colons */
+        while (*pc->p == ':') {
+            pc->p++;
+            pc->len--;
+        }
         while (!stop) {
             if (!((*pc->p >= 'a' && *pc->p <= 'z') ||
                 (*pc->p >= 'A' && *pc->p <= 'Z') ||
@@ -2197,8 +2204,13 @@ Jim_Obj *Jim_StringRangeObj(Jim_Interp *interp,
 
 static Jim_Obj *JimStringToLower(Jim_Interp *interp, Jim_Obj *strObjPtr)
 {
-    char *buf = Jim_Alloc(strObjPtr->length+1);
+    char *buf;
     int i;
+    if (strObjPtr->typePtr != &stringObjType) {
+        SetStringFromAny(interp, strObjPtr);
+    }
+
+    buf = Jim_Alloc(strObjPtr->length+1);
 
     memcpy(buf, strObjPtr->bytes, strObjPtr->length+1);
     for (i = 0; i < strObjPtr->length; i++)
@@ -2208,8 +2220,13 @@ static Jim_Obj *JimStringToLower(Jim_Interp *interp, Jim_Obj *strObjPtr)
 
 static Jim_Obj *JimStringToUpper(Jim_Interp *interp, Jim_Obj *strObjPtr)
 {
-    char *buf = Jim_Alloc(strObjPtr->length+1);
+    char *buf;
     int i;
+    if (strObjPtr->typePtr != &stringObjType) {
+        SetStringFromAny(interp, strObjPtr);
+    }
+
+    buf = Jim_Alloc(strObjPtr->length+1);
 
     memcpy(buf, strObjPtr->bytes, strObjPtr->length+1);
     for (i = 0; i < strObjPtr->length; i++)
@@ -2289,32 +2306,32 @@ static Jim_Obj *Jim_FormatString_Inner(Jim_Interp *interp, Jim_Obj *fmtObjPtr,
                        /* non-terminals */
                case '0': /* zero pad */
                        zpad = 1;
-                       *fmt++;  fmtLen--;
+                       fmt++;  fmtLen--;
                        goto next_fmt;
                        break;
                case '+':
                        forceplus = 1;
-                       *fmt++;  fmtLen--;
+                       fmt++;  fmtLen--;
                        goto next_fmt;
                        break;
                case ' ': /* sign space */
                        spad = 1;
-                       *fmt++;  fmtLen--;
+                       fmt++;  fmtLen--;
                        goto next_fmt;
                        break;
                case '-':
                        ljust = 1;
-                       *fmt++;  fmtLen--;
+                       fmt++;  fmtLen--;
                        goto next_fmt;
                        break;
                case '#':
                        altfm = 1;
-                       *fmt++; fmtLen--;
+                       fmt++; fmtLen--;
                        goto next_fmt;
-
+                       
                case '.':
                        inprec = 1;
-                       *fmt++; fmtLen--;
+                       fmt++; fmtLen--;
                        goto next_fmt;
                        break;
                case '1':
@@ -2340,7 +2357,7 @@ static Jim_Obj *Jim_FormatString_Inner(Jim_Interp *interp, Jim_Obj *fmtObjPtr,
                        goto next_fmt;
                case '*':
                        /* suck up the next item as an integer */
-                       *fmt++;  fmtLen--;
+                       fmt++;  fmtLen--;
                        objc--;
                        if( objc <= 0 ){
                                goto not_enough_args;
@@ -2358,11 +2375,11 @@ static Jim_Obj *Jim_FormatString_Inner(Jim_Interp *interp, Jim_Obj *fmtObjPtr,
                                        prec = 0;
                                }
                        } else {
-                               width = wideValue;
-                               if( width < 0 ){
-                                       ljust = 1;
-                                       width = -width;
-                               }
+                       width = wideValue;
+                       if( width < 0 ){
+                               ljust = 1;
+                               width = -width;
+                       }
                        }
                        objv++;
                        goto next_fmt;
@@ -2455,6 +2472,7 @@ static Jim_Obj *Jim_FormatString_Inner(Jim_Interp *interp, Jim_Obj *fmtObjPtr,
                        break;
         case 'b':
         case 'd':
+        case 'o':
                case 'i':
                case 'u':
                case 'x':
@@ -3009,7 +3027,7 @@ int SetScriptFromAny(Jim_Interp *interp, struct Jim_Obj *objPtr)
         initialLineNumber = objPtr->internalRep.sourceValue.lineNumber;
         propagateSourceInfo = 1;
     } else {
-        script->fileName = Jim_StrDup("?");
+        script->fileName = Jim_StrDup("");
         initialLineNumber = 1;
     }
 
@@ -3161,9 +3179,6 @@ int Jim_CreateCommand(Jim_Interp *interp, const char *cmdName,
     he = Jim_FindHashEntry(&interp->commands, cmdName);
     if (he == NULL) { /* New command to create */
         cmdPtr = Jim_Alloc(sizeof(*cmdPtr));
-        cmdPtr->cmdProc = cmdProc;
-        cmdPtr->privData = privData;
-        cmdPtr->delProc = delProc;
         Jim_AddHashEntry(&interp->commands, cmdName, cmdPtr);
     } else {
         Jim_InterpIncrProcEpoch(interp);
@@ -3181,9 +3196,13 @@ int Jim_CreateCommand(Jim_Interp *interp, const char *cmdName,
             /* If it was a C coded command, call the delProc if any */
             cmdPtr->delProc(interp, cmdPtr->privData);
         }
-        cmdPtr->cmdProc = cmdProc;
-        cmdPtr->privData = privData;
     }
+
+    /* Store the new details for this proc */
+    cmdPtr->delProc = delProc;
+    cmdPtr->cmdProc = cmdProc;
+    cmdPtr->privData = privData;
+
     /* There is no need to increment the 'proc epoch' because
      * creation of a new procedure can never affect existing
      * cached commands. We don't do negative caching. */
@@ -3463,14 +3482,22 @@ int SetVariableFromAny(Jim_Interp *interp, struct Jim_Obj *objPtr)
     /* Make sure it's not syntax glue to get/set dict. */
     if (Jim_NameIsDictSugar(varName, len))
             return JIM_DICT_SUGAR;
-    /* Lookup this name into the variables hash table */
-    he = Jim_FindHashEntry(&interp->framePtr->vars, varName);
-    if (he == NULL) {
-        /* Try with static vars. */
-        if (interp->framePtr->staticVars == NULL)
-            return JIM_ERR;
-        if (!(he = Jim_FindHashEntry(interp->framePtr->staticVars, varName)))
+    if (varName[0] == ':' && varName[1] == ':') {
+        he = Jim_FindHashEntry(&interp->topFramePtr->vars, varName + 2);
+        if (he == NULL) {
             return JIM_ERR;
+        }
+    }
+    else {
+        /* Lookup this name into the variables hash table */
+        he = Jim_FindHashEntry(&interp->framePtr->vars, varName);
+        if (he == NULL) {
+            /* Try with static vars. */
+            if (interp->framePtr->staticVars == NULL)
+                return JIM_ERR;
+            if (!(he = Jim_FindHashEntry(interp->framePtr->staticVars, varName)))
+                return JIM_ERR;
+        }
     }
     /* Free the old internal repr and set the new one. */
     Jim_FreeIntRep(interp, objPtr);
@@ -3509,7 +3536,13 @@ int Jim_SetVariable(Jim_Interp *interp, Jim_Obj *nameObjPtr, Jim_Obj *valObjPtr)
         Jim_IncrRefCount(valObjPtr);
         var->linkFramePtr = NULL;
         /* Insert the new variable */
-        Jim_AddHashEntry(&interp->framePtr->vars, name, var);
+        if (name[0] == ':' && name[1] == ':') {
+            /* Into to the top evel frame */
+            Jim_AddHashEntry(&interp->topFramePtr->vars, name + 2, var);
+        }
+        else {
+            Jim_AddHashEntry(&interp->framePtr->vars, name, var);
+        }
         /* Make the object int rep a variable */
         Jim_FreeIntRep(interp, nameObjPtr);
         nameObjPtr->typePtr = &variableObjType;
@@ -4410,6 +4443,7 @@ Jim_Interp *Jim_CreateInterp(void)
     i->result = i->emptyObj;
     i->stackTrace = Jim_NewListObj(i, NULL, 0);
     i->unknown = Jim_NewStringObj(i, "unknown", -1);
+    i->unknown_called = 0;
     Jim_IncrRefCount(i->emptyObj);
     Jim_IncrRefCount(i->result);
     Jim_IncrRefCount(i->stackTrace);
@@ -4624,6 +4658,11 @@ static void JimResetStackTrace(Jim_Interp *interp)
 static void JimAppendStackTrace(Jim_Interp *interp, const char *procname,
         const char *filename, int linenr)
 {
+    /* No need to add this dummy entry to the stack trace */
+    if (strcmp(procname, "unknown") == 0) {
+        return;
+    }
+
     if (Jim_IsShared(interp->stackTrace)) {
         interp->stackTrace =
             Jim_DuplicateObj(interp, interp->stackTrace);
@@ -6592,7 +6631,7 @@ static void ExprMakeLazy(Jim_Interp *interp, ExprByteCode *expr)
             case JIM_EXPROP_STRING:
                 break;
             default:
-                op = JimExprOperatorInfoByOpcode(expr->opcode[i]);
+                op = JimExprOperatorInfoByOpcode(expr->opcode[leftindex]);
                 if (op == NULL) {
                     Jim_Panic(interp,"Default reached in ExprMakeLazy()");
                 }
@@ -6982,6 +7021,16 @@ trydouble:
             /* --- Double --- */
             if (Jim_GetDouble(interp, A, &dA) != JIM_OK ||
                 Jim_GetDouble(interp, B, &dB) != JIM_OK) {
+
+                /* Hmmm! For compatibility, maybe convert != and == into ne and eq */
+                if (expr->opcode[i] == JIM_EXPROP_NUMNE) {
+                    opcode = JIM_EXPROP_STRNE;
+                    goto retry_as_string;
+                }
+                else if (expr->opcode[i] == JIM_EXPROP_NUMEQ) {
+                    opcode = JIM_EXPROP_STREQ;
+                    goto retry_as_string;
+                }
                 Jim_DecrRefCount(interp, A);
                 Jim_DecrRefCount(interp, B);
                 error = 1;
@@ -7043,9 +7092,10 @@ trydouble:
         } else if (opcode == JIM_EXPROP_STREQ || opcode == JIM_EXPROP_STRNE) {
             B = stack[--stacklen];
             A = stack[--stacklen];
+retry_as_string:
             sA = Jim_GetString(A, &Alen);
             sB = Jim_GetString(B, &Blen);
-            switch(expr->opcode[i]) {
+            switch(opcode) {
             case JIM_EXPROP_STREQ:
                 if (Alen == Blen && memcmp(sA, sB, Alen) ==0)
                     wC = 1;
@@ -7877,21 +7927,21 @@ int Jim_LoadLibrary(Jim_Interp *interp, const char *pathName)
             if (Jim_ListIndex(interp, libPathObjPtr, i,
                     &prefixObjPtr, JIM_NONE) != JIM_OK)
                 continue;
-            prefix = Jim_GetString(prefixObjPtr, NULL);
-            prefixlen = strlen(prefix);
+            prefix = Jim_GetString(prefixObjPtr, &prefixlen);
             if (prefixlen+strlen(pathName)+1 >= JIM_PATH_LEN)
                 continue;
-            if (prefixlen && prefix[prefixlen-1] == '/')
+            if (*pathName == '/') {
+                strcpy(buf, pathName);
+            }    
+            else if (prefixlen && prefix[prefixlen-1] == '/')
                 sprintf(buf, "%s%s", prefix, pathName);
             else
                 sprintf(buf, "%s/%s", prefix, pathName);
-            printf("opening '%s'\n", buf);
             fp = fopen(buf, "r");
             if (fp == NULL)
                 continue;
             fclose(fp);
             handle = dlopen(buf, RTLD_LAZY);
-            printf("got handle %p\n", handle);
         }
         if (handle == NULL) {
             Jim_SetResult(interp, Jim_NewEmptyStringObj(interp));
@@ -8235,6 +8285,9 @@ const char *Jim_PackageRequire(Jim_Interp *interp, const char *name,
     Jim_HashEntry *he;
     int requiredVer;
 
+    /* Start with an empty error string */
+    Jim_SetResultString(interp, "", 0);
+
     if (JimPackageVersionToInt(interp, ver, &requiredVer, JIM_ERRMSG) != JIM_OK)
         return NULL;
     he = Jim_FindHashEntry(&interp->packages, name);
@@ -8249,8 +8302,9 @@ const char *Jim_PackageRequire(Jim_Interp *interp, const char *name,
         }
         /* No way... return an error. */
         if (flags & JIM_ERRMSG) {
-            Jim_SetResult(interp, Jim_NewEmptyStringObj(interp));
-            Jim_AppendStrings(interp, Jim_GetResult(interp),
+            int len;
+            Jim_GetString(Jim_GetResult(interp), &len);
+            Jim_AppendStrings(interp, Jim_GetResult(interp), len ? "\n" : "",
                     "Can't find package '", name, "'", NULL);
         }
         return NULL;
@@ -8263,7 +8317,6 @@ const char *Jim_PackageRequire(Jim_Interp *interp, const char *name,
         }
         /* Check if version matches. */
         if (JimPackageMatchVersion(requiredVer, actualVer, flags) == 0) {
-            Jim_SetResult(interp, Jim_NewEmptyStringObj(interp));
             Jim_AppendStrings(interp, Jim_GetResult(interp),
                     "Package '", name, "' already loaded, but with version ",
                     he->val, NULL);
@@ -8288,6 +8341,13 @@ static int JimUnknown(Jim_Interp *interp, int argc, Jim_Obj *const *argv)
     Jim_Obj **v, *sv[JIM_EVAL_SARGV_LEN];
     int retCode;
 
+    /* If JimUnknown() is recursively called (e.g. error in the unknown proc,
+     * done here
+     */
+    if (interp->unknown_called) {
+        return JIM_ERR;
+    }
+
     /* If the [unknown] command does not exists returns
      * just now */
     if (Jim_GetCommand(interp, interp->unknown, JIM_NONE) == NULL)
@@ -8308,7 +8368,10 @@ static int JimUnknown(Jim_Interp *interp, int argc, Jim_Obj *const *argv)
     memcpy(v+1, argv, sizeof(Jim_Obj*)*argc);
     v[0] = interp->unknown;
     /* Call it */
+    interp->unknown_called++;
     retCode = Jim_EvalObjVector(interp, argc+1, v);
+    interp->unknown_called--;
+
     /* Clean up */
     if (v != sv)
         Jim_Free(v);
@@ -8342,12 +8405,16 @@ int Jim_EvalObjVector(Jim_Interp *interp, int objc, Jim_Obj *const *objv)
         if (cmdPtr->cmdProc) {
             interp->cmdPrivData = cmdPtr->privData;
             retcode = cmdPtr->cmdProc(interp, objc, objv);
+            if (retcode == JIM_ERR_ADDSTACK) {
+                //JimAppendStackTrace(interp, "", script->fileName, token[i-argc*2].linenr);
+                retcode = JIM_ERR;
+            }
         } else {
             retcode = JimCallProcedure(interp, cmdPtr, objc, objv);
-    if (retcode == JIM_ERR) {
-        JimAppendStackTrace(interp,
-            Jim_GetString(objv[0], NULL), "?", 1);
-    }
+            if (retcode == JIM_ERR) {
+                JimAppendStackTrace(interp,
+                    Jim_GetString(objv[0], NULL), "", 1);
+            }
         }
     }
     /* Decr refcount of arguments and return the retcode */
@@ -8628,6 +8695,10 @@ int Jim_EvalObj(Jim_Interp *interp, Jim_Obj *scriptObjPtr)
             if (cmd->cmdProc) {
                 interp->cmdPrivData = cmd->privData;
                 retcode = cmd->cmdProc(interp, argc, argv);
+                if (retcode == JIM_ERR_ADDSTACK) {
+                    JimAppendStackTrace(interp, "", script->fileName, token[i-argc*2].linenr);
+                    retcode = JIM_ERR;
+                }
             } else {
                 retcode = JimCallProcedure(interp, cmd, argc, argv);
                 if (retcode == JIM_ERR) {
@@ -8641,7 +8712,7 @@ int Jim_EvalObj(Jim_Interp *interp, Jim_Obj *scriptObjPtr)
             retcode = JimUnknown(interp, argc, argv);
             if (retcode == JIM_ERR) {
                 JimAppendStackTrace(interp,
-                    Jim_GetString(argv[0], NULL), script->fileName,
+                    "", script->fileName,
                     token[i-argc*2].linenr);
             }
         }
@@ -8697,6 +8768,7 @@ int JimCallProcedure(Jim_Interp *interp, Jim_Cmd *cmd, int argc,
 {
     int i, retcode;
     Jim_CallFrame *callFramePtr;
+    int num_args;
 
     /* Check arity */
     if (argc < cmd->arityMin || (cmd->arityMax != -1 &&
@@ -8727,19 +8799,47 @@ int JimCallProcedure(Jim_Interp *interp, Jim_Cmd *cmd, int argc,
     Jim_IncrRefCount(cmd->bodyObjPtr);
     interp->framePtr = callFramePtr;
     interp->numLevels ++;
+
     /* Set arguments */
-    for (i = 0; i < cmd->arityMin-1; i++) {
-        Jim_Obj *objPtr;
+    Jim_ListLength(interp, cmd->argListObjPtr, &num_args);
+
+    /* If last argument is 'args', don't set it here */
+    if (cmd->arityMax == -1) {
+        num_args--;
+    }
+
+    for (i = 0; i < num_args; i++) {
+        Jim_Obj *argObjPtr;
+        Jim_Obj *nameObjPtr;
+        Jim_Obj *valueObjPtr;
+
+        Jim_ListIndex(interp, cmd->argListObjPtr, i, &argObjPtr, JIM_NONE);
+        if (i + 1 >= cmd->arityMin) {
+            /* The name is the first element of the list */
+            Jim_ListIndex(interp, argObjPtr, 0, &nameObjPtr, JIM_NONE);
+        }
+        else {
+            /* The element arg is the name */
+            nameObjPtr = argObjPtr;
+        }
 
-        Jim_ListIndex(interp, cmd->argListObjPtr, i, &objPtr, JIM_NONE);
-        Jim_SetVariable(interp, objPtr, argv[i+1]);
+        if (i + 1 >= argc) {
+            /* No more values, so use default */
+            /* The value is the second element of the list */
+            Jim_ListIndex(interp, argObjPtr, 1, &valueObjPtr, JIM_NONE);
+        }
+        else {
+            valueObjPtr = argv[i+1];
+        }
+        Jim_SetVariable(interp, nameObjPtr, valueObjPtr);
     }
+    /* Set optional arguments */
     if (cmd->arityMax == -1) {
         Jim_Obj *listObjPtr, *objPtr;
 
-        listObjPtr = Jim_NewListObj(interp, argv+cmd->arityMin,
-                argc-cmd->arityMin);
-        Jim_ListIndex(interp, cmd->argListObjPtr, i, &objPtr, JIM_NONE);
+        i++;
+        listObjPtr = Jim_NewListObj(interp, argv+i, argc-i);
+        Jim_ListIndex(interp, cmd->argListObjPtr, num_args, &objPtr, JIM_NONE);
         Jim_SetVariable(interp, objPtr, listObjPtr);
     }
     /* Eval the body */
@@ -10895,17 +10995,31 @@ static int Jim_ProcCoreCommand(Jim_Interp *interp, int argc,
     }
     Jim_ListLength(interp, argv[2], &argListLen);
     arityMin = arityMax = argListLen+1;
+
     if (argListLen) {
         const char *str;
         int len;
-        Jim_Obj *lastArgPtr;
+        Jim_Obj *argPtr;
         
-        Jim_ListIndex(interp, argv[2], argListLen-1, &lastArgPtr, JIM_NONE);
-        str = Jim_GetString(lastArgPtr, &len);
+        /* Check for 'args' and adjust arityMin and arityMax if necessary */
+        Jim_ListIndex(interp, argv[2], argListLen-1, &argPtr, JIM_NONE);
+        str = Jim_GetString(argPtr, &len);
         if (len == 4 && memcmp(str, "args", 4) == 0) {
             arityMin--;
             arityMax = -1;
         }
+
+        /* Check for default arguments and reduce arityMin if necessary */
+        while (arityMin > 1) {
+            int len;
+            Jim_ListIndex(interp, argv[2], arityMin - 2, &argPtr, JIM_NONE);
+            Jim_ListLength(interp, argPtr, &len);
+            if (len != 2) {
+                /* No default argument */
+                break;
+            }
+            arityMin--;
+        }
     }
     if (argc == 4) {
         return Jim_CreateProcedure(interp, Jim_GetString(argv[1], NULL),
@@ -11537,10 +11651,10 @@ static int Jim_InfoCoreCommand(Jim_Interp *interp, int argc,
     int cmd, result = JIM_OK;
     static const char *commands[] = {
         "body", "commands", "exists", "globals", "level", "locals",
-        "vars", "version", "complete", "args", NULL
+        "vars", "version", "complete", "args", "hostname", NULL
     };
     enum {INFO_BODY, INFO_COMMANDS, INFO_EXISTS, INFO_GLOBALS, INFO_LEVEL,
-          INFO_LOCALS, INFO_VARS, INFO_VERSION, INFO_COMPLETE, INFO_ARGS};
+          INFO_LOCALS, INFO_VARS, INFO_VERSION, INFO_COMPLETE, INFO_ARGS, INFO_HOSTNAME};
     
     if (argc < 2) {
         Jim_WrongNumArgs(interp, 1, argv, "command ?args ...?");
@@ -11636,6 +11750,10 @@ static int Jim_InfoCoreCommand(Jim_Interp *interp, int argc,
         s = Jim_GetString(argv[2], &len);
         Jim_SetResult(interp,
                 Jim_NewIntObj(interp, Jim_ScriptIsComplete(s, len, NULL)));
+    } else if (cmd == INFO_HOSTNAME) {
+        /* Redirect to os.hostname if it exists */
+        Jim_Obj *command = Jim_NewStringObj(interp, "os.gethostname", -1);
+        result = Jim_EvalObjVector(interp, 1, &command);
     }
     return result;
 }
@@ -11854,6 +11972,24 @@ static int Jim_EnvCoreCommand(Jim_Interp *interp, int argc,
     const char *key;
     char *val;
 
+    if (argc == 1) {
+        extern char **environ;
+
+        int i;
+        Jim_Obj *listObjPtr = Jim_NewListObj(interp, NULL, 0);
+
+        for (i = 0; environ[i]; i++) {
+            const char *equals = strchr(environ[i], '=');
+            if (equals) {
+                Jim_ListAppendElement(interp, listObjPtr, Jim_NewStringObj(interp, environ[i], equals - environ[i]));
+                Jim_ListAppendElement(interp, listObjPtr, Jim_NewStringObj(interp, equals + 1, -1));
+            }
+        }
+
+        Jim_SetResult(interp, listObjPtr);
+        return JIM_OK;
+    }
+
     if (argc != 2) {
         Jim_WrongNumArgs(interp, 1, argv, "varName");
         return JIM_ERR;
@@ -11882,6 +12018,9 @@ static int Jim_SourceCoreCommand(Jim_Interp *interp, int argc,
         return JIM_ERR;
     }
     retval = Jim_EvalFile(interp, Jim_GetString(argv[1], NULL));
+    if (retval == JIM_ERR) {
+        return JIM_ERR_ADDSTACK;
+    }
     if (retval == JIM_RETURN)
         return JIM_OK;
     return retval;
@@ -12031,7 +12170,7 @@ static int Jim_PackageCoreCommand(Jim_Interp *interp, int argc,
                 argc == 4 ? Jim_GetString(argv[3], NULL) : "",
                 JIM_ERRMSG);
         if (ver == NULL)
-            return JIM_ERR;
+            return JIM_ERR_ADDSTACK;
         Jim_SetResultString(interp, ver, -1);
     } else if (option == OPT_PROVIDE) {
         if (argc != 4) {
@@ -12044,108 +12183,6 @@ static int Jim_PackageCoreCommand(Jim_Interp *interp, int argc,
     return JIM_OK;
 }
 
-
-static void
-jim_get_s_us( jim_wide *s, jim_wide *us )
-{
-#if defined(WIN32)
-       /* 
-        * Sorry - I do not have, or use Win32.
-        * This concept is from 
-        * 
-        * Method is from: 
-        *    http://www.openasthra.com/c-tidbits/gettimeofday-function-for-windows/
-        *
-        * I have no method to test/verify.
-        *  - Duane 6-sep-2008.
-        * (once verified, please somebody remove this comment)
-        */
-#if defined(_MSC_VER) || defined(_MSC_EXTENSIONS)
-  #define DELTA_EPOCH_IN_MICROSECS  11644473600000000Ui64
-#else
-  #define DELTA_EPOCH_IN_MICROSECS  11644473600000000ULL
-#endif
-
-       FILETIME ft;
-       unsigned __int64 tmpres;
-       tmpres = 0;
-       GetSystemTimeAsFileTime( &ft );
-
-       tmpres |= ft.dwHighDateTime;
-       tmpres <<= 32;
-       tmpres |= ft.dwLowDateTime;
-       /* convert to unix representation */
-       tmpres /= 10;
-       tmpres -= DELTA_EPOCH_IN_MICROSECS;
-       
-       *s  = (tmpres / 1000000ULL);
-       *us = (tmpres % 1000000ULL);
-       
-#undef DELTA_EPOCH_IN_MICROSECS
-
-#else
-       /* LINUX/CYGWIN */
-       struct timeval tv;
-       struct timezone tz;
-       gettimeofday( &tv, &tz );
-       *s  = tv.tv_sec;
-       *us = tv.tv_usec;
-#endif
-}
-
-
-/* [clock] */
-static int Jim_ClockCoreCommand( Jim_Interp *interp, int argc,
-                                                                  Jim_Obj *const *argv)
-{
-       /*
-        *  See: TCL man page for 'clock'
-        *  we do not impliment all features.
-        */
-       jim_wide r,s,us;
-       int option;
-       const char *options[] = {
-               "clicks",
-               "microseconds",
-               "milliseconds",
-               "seconds",
-               NULL 
-       };
-       enum { OPT_CLICKS, OPT_USEC, OPT_MSEC, OPT_SEC };
-
-       if( argc < 2 ){
-               Jim_WrongNumArgs( interp, 1, argv, "option ?arguments ...?");
-               return JIM_ERR;
-       }
-
-       if( Jim_GetEnum(interp, argv[1], options, &option, "option",
-                                       JIM_ERRMSG) != JIM_OK ){
-               return JIM_ERR;
-       }
-
-       // platform independent get time.
-       jim_get_s_us( &s, &us );
-
-       r = 0;
-       switch(option){
-       case OPT_CLICKS:
-       case OPT_USEC:
-               /* clicks & usecs are the same */
-               r = (s * 1000000) + us;
-               break;
-       case OPT_MSEC:
-               r = (s * 1000) + (us / 1000);
-               break;
-       case OPT_SEC:
-               r = s;
-               break;
-       }
-               
-       Jim_SetResult( interp, Jim_NewWideObj( interp, r ) );
-       return JIM_OK;
-}
-        
-
 static struct {
     const char *name;
     Jim_CmdProc cmdProc;
@@ -12210,7 +12247,6 @@ static struct {
     {"rand", Jim_RandCoreCommand},
     {"package", Jim_PackageCoreCommand},
     {"tailcall", Jim_TailcallCoreCommand},
-       {"clock", Jim_ClockCoreCommand},
     {NULL, NULL},
 };
 
@@ -12250,9 +12286,11 @@ void Jim_PrintErrorMessage(Jim_Interp *interp)
 {
     int len, i;
 
-    Jim_fprintf(interp, interp->cookie_stderr, "Runtime error, file \"%s\", line %d:" JIM_NL,
-                               interp->errorFileName, interp->errorLine);
-    Jim_fprintf(interp,interp->cookie_stderr, "    %s" JIM_NL,
+    if (*interp->errorFileName) {
+        Jim_fprintf(interp, interp->cookie_stderr, "Runtime error, file \"%s\", line %d:" JIM_NL "    ",
+                                    interp->errorFileName, interp->errorLine);
+    }
+    Jim_fprintf(interp,interp->cookie_stderr, "%s" JIM_NL,
             Jim_GetString(interp->result, NULL));
     Jim_ListLength(interp, interp->stackTrace, &len);
     for (i = len-3; i >= 0; i-= 3) {
@@ -12267,9 +12305,18 @@ void Jim_PrintErrorMessage(Jim_Interp *interp)
         Jim_ListIndex(interp, interp->stackTrace, i+2, &objPtr,
                 JIM_NONE);
         line = Jim_GetString(objPtr, NULL);
-               Jim_fprintf( interp, interp->cookie_stderr,
-                "In procedure '%s' called at file \"%s\", line %s" JIM_NL,
-                proc, file, line);
+        if (*proc) {
+            Jim_fprintf( interp, interp->cookie_stderr,
+                    "in procedure '%s' ", proc);
+        }
+        if (*file) {
+            Jim_fprintf( interp, interp->cookie_stderr,
+                    "called at file \"%s\", line %s",
+                    file, line);
+        }
+        if (*file || *proc) {
+            Jim_fprintf( interp, interp->cookie_stderr, JIM_NL);
+        }
     }
 }
 
@@ -12393,7 +12440,6 @@ char* Jim_fgets( Jim_Interp *interp, char *s, int size, void *cookie )
        }
        return (*(interp->cb_fgets))( s, size, cookie );
 }
-
 Jim_Nvp *
 Jim_Nvp_name2value_simple( const Jim_Nvp *p, const char *name )
 {
@@ -12555,7 +12601,7 @@ Jim_GetOpt_Obj( Jim_GetOptInfo *goi, Jim_Obj **puthere )
        Jim_Obj *o;
        
        o = NULL; // failure 
-       if( goi->argc > 0 ){
+       if( goi->argc ){
                // success 
                o = goi->argv[0];
                goi->argc -= 1;
@@ -12704,7 +12750,7 @@ Jim_SetResult_sprintf( Jim_Interp *interp, const char *fmt,... )
 {
        va_list ap;
        char *buf;
-       
+
        va_start(ap,fmt);
        buf = jim_vasprintf( fmt, ap );
        va_end(ap);
@@ -12773,3 +12819,12 @@ Jim_Debug_ArgvString( Jim_Interp *interp, int argc, Jim_Obj *const *argv )
 
        return Jim_GetString( debug_string_obj, NULL );
 }
+
+       
+
+/*
+ * Local Variables: ***
+ * c-basic-offset: 4 ***
+ * tab-width: 4 ***
+ * End: ***
+ */
index 3c04972..7ee8235 100644 (file)
@@ -164,6 +164,7 @@ extern "C" {
 #define JIM_CONTINUE 4
 #define JIM_EVAL 5
 #define JIM_EXIT 6
+#define JIM_ERR_ADDSTACK 7
 #define JIM_MAX_NESTING_DEPTH 10000 /* default max nesting depth */
 
 /* Some function get an integer argument with flags to change
@@ -530,6 +531,7 @@ typedef struct Jim_Interp {
     struct Jim_HashTable sharedStrings; /* Shared Strings hash table */
     Jim_Obj *stackTrace; /* Stack trace object. */
     Jim_Obj *unknown; /* Unknown command cache */
+    int unknown_called; /* The unknown command has been invoked */
     int errorFlag; /* Set if an error occurred during execution. */
     int evalRetcodeLevel; /* Level where the last return with code JIM_EVAL
                              happened. */
@@ -560,6 +562,7 @@ typedef struct Jim_Interp {
  * cached can no longer considered valid. */
 #define Jim_InterpIncrProcEpoch(i) (i)->procEpoch++
 #define Jim_SetResultString(i,s,l) Jim_SetResult(i, Jim_NewStringObj(i,s,l))
+#define Jim_SetResultInt(i,intval) Jim_SetResult(i, Jim_NewIntObj(i,intval))
 #define Jim_SetEmptyResult(i) Jim_SetResult(i, (i)->emptyObj)
 #define Jim_GetResult(i) ((i)->result)
 #define Jim_CmdPrivData(i) ((i)->cmdPrivData)
@@ -1296,7 +1299,7 @@ static void Jim_InitExtension(Jim_Interp *interp)
   JIM_GET_API(Nvp_name2value);
   JIM_GET_API(Nvp_name2value_nocase);
   JIM_GET_API(Nvp_name2value_simple);
-
+  
   JIM_GET_API(Nvp_value2name);
   JIM_GET_API(Nvp_value2name_simple);
 
@@ -1337,3 +1340,10 @@ static __inline__ void Jim_InitEmbedded(void) {
 #endif
 
 #endif /* __JIM__H */
+
+/*
+ * Local Variables: ***
+ * c-basic-offset: 4 ***
+ * tab-width: 4 ***
+ * End: ***
+ */