Jim Tcl
Diff
Not logged in

Differences From Artifact [34b30f5d35276de5]:

To Artifact [ddd61b1575995849]:


62 62 63 63 #include "jim.h" 64 64 65 65 #ifdef HAVE_BACKTRACE 66 66 #include <execinfo.h> 67 67 #endif 68 68 69 -/*#define DEBUG_SHOW_SCRIPT*/ 70 -/*#define DEBUG_SHOW_TOKENS*/ 71 - 72 69 /* For INFINITY, even if math functions are not enabled */ 73 70 #include <math.h> 71 + 72 +/*#define DEBUG_SHOW_SCRIPT*/ 73 +/*#define DEBUG_SHOW_SCRIPT_TOKENS*/ 74 +/*#define DEBUG_SHOW_SUBST*/ 75 +/*#define DEBUG_SHOW_EXPR*/ 76 +/*#define JIM_DEBUG_GC*/ 77 +/*#define JIM_DEBUG_COMMAND*/ 78 + 79 +#if defined(DEBUG_SHOW_SCRIPT) || defined(DEBUG_SHOW_SCRIPT_TOKENS) || defined(DEBUG_SHOW_EXPR) || defined(DEBUG_SHOW_SUBST) 80 +static const char *tt_name(int type); 81 +#endif 74 82 75 83 /* ----------------------------------------------------------------------------- 76 84 * Global variables 77 85 * ---------------------------------------------------------------------------*/ 78 86 79 87 /* A shared empty string for the objects string representation. 80 88 * Jim_InvalidateStringRep knows about it and doesn't try to free it. */ ................................................................................ 96 104 int argc, Jim_Obj *const *argv); 97 105 static int JimEvalObjVector(Jim_Interp *interp, int objc, Jim_Obj *const *objv, 98 106 const char *filename, int linenr); 99 107 static int JimGetWideNoErr(Jim_Interp *interp, Jim_Obj *objPtr, jim_wide * widePtr); 100 108 101 109 static const Jim_HashTableType JimVariablesHashTableType; 102 110 103 -const char *tt_name(int type); 104 - 105 111 /* ----------------------------------------------------------------------------- 106 112 * Utility functions 107 113 * ---------------------------------------------------------------------------*/ 108 114 109 115 /* Glob-style pattern matching. */ 110 116 static int JimStringMatch(const char *pattern, int patternLen, 111 117 const char *string, int stringLen, int nocase) ................................................................................ 3040 3046 struct ScriptToken *token; 3041 3047 /* Number of tokens so far for the current command */ 3042 3048 int lineargs = 0; 3043 3049 /* This is the first token for the current command */ 3044 3050 ScriptToken *linefirst; 3045 3051 int count; 3046 3052 3047 -#ifdef DEBUG_SHOW_TOKENS 3053 +#ifdef DEBUG_SHOW_SCRIPT_TOKENS 3048 3054 printf("==== Tokens ====\n"); 3049 3055 for (i = 0; i < tokenlist->count; i++) { 3050 3056 printf("[%2d]@%d %s '%.*s'\n", i, tokenlist->list[i].line, tt_name(tokenlist->list[i].type), 3051 3057 tokenlist->list[i].len, tokenlist->list[i].token); 3052 3058 } 3053 3059 #endif 3054 3060 ................................................................................ 3078 3084 3079 3085 wordtokens = JimCountWordTokens(tokenlist->list + i); 3080 3086 3081 3087 if (wordtokens == 0) { 3082 3088 /* None, so at end of line */ 3083 3089 if (lineargs) { 3084 3090 linefirst->type = JIM_TT_LINE; 3091 +#ifdef DEBUG_SHOW_SCRIPT 3085 3092 linefirst->objPtr = Jim_NewIntObj(interp, lineargs); 3093 +#else 3094 + linefirst->objPtr = interp->emptyObj; 3095 +#endif 3086 3096 /* Cheat and store the value in the unused 'linenr' for quick access */ 3087 3097 linefirst->linenr = lineargs; 3088 3098 Jim_IncrRefCount(linefirst->objPtr); 3089 3099 3090 3100 /* Reset for new line */ 3091 3101 lineargs = 0; 3092 3102 linefirst = token++; ................................................................................ 3093 3103 } 3094 3104 i++; 3095 3105 continue; 3096 3106 } 3097 3107 else if (wordtokens != 1) { 3098 3108 /* More than 1, or {expand}, so insert a WORD token */ 3099 3109 token->type = JIM_TT_WORD; 3110 +#ifdef DEBUG_SHOW_SCRIPT 3100 3111 token->objPtr = Jim_NewIntObj(interp, wordtokens); 3112 +#else 3113 + token->objPtr = interp->emptyObj; 3114 +#endif 3101 3115 /* Cheat and store the value in the unused 'linenr' for quick access */ 3102 3116 token->linenr = wordtokens; 3103 3117 Jim_IncrRefCount(token->objPtr); 3104 3118 token++; 3105 3119 if (wordtokens < 0) { 3106 3120 /* Skip the expand token */ 3107 3121 i++; ................................................................................ 4450 4464 JimReferencesHTKeyDup, /* key dup */ 4451 4465 NULL, /* val dup */ 4452 4466 JimReferencesHTKeyCompare, /* key compare */ 4453 4467 JimReferencesHTKeyDestructor, /* key destructor */ 4454 4468 NULL /* val destructor */ 4455 4469 }; 4456 4470 4457 -/* #define JIM_DEBUG_GC 1 */ 4458 - 4459 4471 /* Performs the garbage collection. */ 4460 4472 int Jim_Collect(Jim_Interp *interp) 4461 4473 { 4462 4474 Jim_HashTable marks; 4463 4475 Jim_HashTableIterator *htiter; 4464 4476 Jim_HashEntry *he; 4465 4477 Jim_Obj *objPtr; ................................................................................ 5649 5661 return Jim_StringCompareObj(*lhsObj, *rhsObj, 1) * sort_order; 5650 5662 } 5651 5663 5652 5664 static int ListSortInteger(Jim_Obj **lhsObj, Jim_Obj **rhsObj) 5653 5665 { 5654 5666 jim_wide lhs = 0, rhs = 0; 5655 5667 5656 - /* REVISIT: If these are not valid integers, bogus results ... */ 5657 5668 if (Jim_GetWide(sort_interp, *lhsObj, &lhs) != JIM_OK || 5658 5669 Jim_GetWide(sort_interp, *rhsObj, &rhs) != JIM_OK) { 5659 5670 longjmp(sort_jmpbuf, JIM_ERR); 5660 5671 } 5661 5672 5662 5673 return JimSign(lhs - rhs) * sort_order; 5663 5674 } ................................................................................ 7428 7439 rc = JIM_ERR; 7429 7440 break; 7430 7441 } 7431 7442 Jim_DecrRefCount(interp, A); 7432 7443 7433 7444 return rc; 7434 7445 } 7435 - 7436 -static int JimExprOpColon(Jim_Interp *interp, struct JimExprState *e) 7437 -{ 7438 - int rc = JIM_OK; 7439 - 7440 -#if 0 7441 - Jim_Obj *C = ExprPop(e); 7442 - Jim_Obj *B = ExprPop(e); 7443 - Jim_Obj *A = ExprPop(e); 7444 - 7445 - switch (ExprBool(interp, A)) { 7446 - case 0: 7447 - ExprPush(e, C); 7448 - break; 7449 - 7450 - case 1: 7451 - ExprPush(e, B); 7452 - break; 7453 - 7454 - case -1: 7455 - /* Invalid */ 7456 - rc = JIM_ERR; 7457 - break; 7458 - } 7459 - Jim_DecrRefCount(interp, A); 7460 - Jim_DecrRefCount(interp, B); 7461 - Jim_DecrRefCount(interp, C); 7462 - 7463 -#endif 7464 - return rc; 7465 -} 7466 - 7467 7446 7468 7447 static int JimExprOpTernaryLeft(Jim_Interp *interp, struct JimExprState *e) 7469 7448 { 7470 7449 Jim_Obj *skip = ExprPop(e); 7471 7450 Jim_Obj *A = ExprPop(e); 7472 7451 int rc = JIM_OK; 7473 7452 ................................................................................ 7592 7571 [JIM_EXPROP_BITXOR] = {"^", 49, 2, JimExprOpIntBin, LAZY_NONE}, 7593 7572 [JIM_EXPROP_BITOR] = {"|", 48, 2, JimExprOpIntBin, LAZY_NONE}, 7594 7573 7595 7574 [JIM_EXPROP_LOGICAND] = {"&&", 10, 2, NULL, LAZY_OP}, 7596 7575 [JIM_EXPROP_LOGICOR] = {"||", 9, 2, NULL, LAZY_OP}, 7597 7576 7598 7577 [JIM_EXPROP_TERNARY] = {"?", 5, 2, JimExprOpNull, LAZY_OP}, 7599 - [JIM_EXPROP_COLON] = {":", 5, 2, JimExprOpColon, LAZY_OP}, 7578 + [JIM_EXPROP_COLON] = {":", 5, 2, JimExprOpNull, LAZY_OP}, 7600 7579 7601 7580 /* private operators */ 7602 7581 [JIM_EXPROP_TERNARY_LEFT] = {NULL, 5, 2, JimExprOpTernaryLeft, LAZY_LEFT}, 7603 7582 [JIM_EXPROP_TERNARY_RIGHT] = {NULL, 5, 2, JimExprOpNull, LAZY_RIGHT}, 7604 7583 [JIM_EXPROP_COLON_LEFT] = {NULL, 5, 2, JimExprOpColonLeft, LAZY_LEFT}, 7605 7584 [JIM_EXPROP_COLON_RIGHT] = {NULL, 5, 2, JimExprOpNull, LAZY_RIGHT}, 7606 7585 [JIM_EXPROP_LOGICAND_LEFT] = {NULL, 10, 2, JimExprOpAndLeft, LAZY_LEFT}, ................................................................................ 7789 7768 } 7790 7769 7791 7770 static const struct Jim_ExprOperator *JimExprOperatorInfoByOpcode(int opcode) 7792 7771 { 7793 7772 return &Jim_ExprOperators[opcode]; 7794 7773 } 7795 7774 7796 -/* debugging */ 7797 -const char *tt_name(int type) 7775 +#if defined(DEBUG_SHOW_SCRIPT) || defined(DEBUG_SHOW_SCRIPT_TOKENS) || defined(DEBUG_SHOW_EXPR) || defined(DEBUG_SHOW_SUBST) 7776 +static const char *tt_name(int type) 7798 7777 { 7799 7778 static const char * const tt_names[JIM_TT_EXPR_OP] = 7800 7779 { "NIL", "STR", "ESC", "VAR", "ARY", "CMD", "SEP", "EOL", "EOF", "LIN", "WRD", "(((", ")))", "INT", 7801 7780 "DBL" }; 7802 7781 if (type < JIM_TT_EXPR_OP) { 7803 7782 return tt_names[type]; 7804 7783 } ................................................................................ 7809 7788 if (op && op->name) { 7810 7789 return op->name; 7811 7790 } 7812 7791 sprintf(buf, "(%d)", type); 7813 7792 return buf; 7814 7793 } 7815 7794 } 7795 +#endif 7816 7796 7817 7797 /* ----------------------------------------------------------------------------- 7818 7798 * Expression Object 7819 7799 * ---------------------------------------------------------------------------*/ 7820 7800 static void FreeExprInternalRep(Jim_Interp *interp, Jim_Obj *objPtr); 7821 7801 static void DupExprInternalRep(Jim_Interp *interp, Jim_Obj *srcPtr, Jim_Obj *dupPtr); 7822 7802 static int SetExprFromAny(Jim_Interp *interp, struct Jim_Obj *objPtr); ................................................................................ 8184 8164 /* No longer need the token list */ 8185 8165 ScriptTokenListFree(&tokenlist); 8186 8166 8187 8167 if (!expr) { 8188 8168 goto err; 8189 8169 } 8190 8170 8191 -#if 0 8192 - int i; 8171 +#ifdef DEBUG_SHOW_EXPR 8172 + { 8173 + int i; 8193 8174 8194 - printf("==== Expr ====\n"); 8195 - for (i = 0; i < expr->len; i++) { 8196 - ScriptToken *t = &expr->token[i]; 8175 + printf("==== Expr ====\n"); 8176 + for (i = 0; i < expr->len; i++) { 8177 + ScriptToken *t = &expr->token[i]; 8197 8178 8198 - printf("[%2d] %s '%s'\n", i, tt_name(t->type), Jim_GetString(t->objPtr, NULL)); 8179 + printf("[%2d] %s '%s'\n", i, tt_name(t->type), Jim_GetString(t->objPtr, NULL)); 8180 + } 8199 8181 } 8200 8182 #endif 8201 8183 8202 8184 /* Check program correctness. */ 8203 8185 if (ExprCheckCorrectness(expr) != JIM_OK) { 8204 8186 ExprFreeByteCode(interp, expr); 8205 8187 goto invalidexpr; 8206 8188 } 8207 8189 8208 8190 rc = JIM_OK; 8209 8191 8210 -#if 0 8211 - printf("==== Expr ====\n"); 8212 - for (i = 0; i < expr->len; i++) { 8213 - ScriptToken *t = &expr->token[i]; 8214 - 8215 - printf("[%2d] %s '%s'\n", i, tt_name(t->type), Jim_GetString(t->objPtr, NULL)); 8216 - } 8217 -#endif 8218 - 8219 8192 err: 8220 8193 /* Free the old internal rep and set the new one. */ 8221 8194 Jim_FreeIntRep(interp, objPtr); 8222 8195 Jim_SetIntRepPtr(objPtr, expr); 8223 8196 objPtr->typePtr = &exprObjType; 8224 8197 return rc; 8225 8198 } ................................................................................ 9096 9069 * ---------------------------------------------------------------------------*/ 9097 9070 static void JimPrngSeed(Jim_Interp *interp, const unsigned char *seed, int seedLen); 9098 9071 9099 9072 /* Initialize the sbox with the numbers from 0 to 255 */ 9100 9073 static void JimPrngInit(Jim_Interp *interp) 9101 9074 { 9102 9075 int i; 9103 - /* REVISIT: Move off stack */ 9076 + /* XXX: Move off stack */ 9104 9077 unsigned int seed[256]; 9105 9078 9106 9079 interp->prngState = Jim_Alloc(sizeof(Jim_PrngState)); 9107 9080 for (i = 0; i < 256; i++) 9108 9081 seed[i] = (rand() ^ time(NULL) ^ clock()); 9109 9082 JimPrngSeed(interp, (unsigned char *)seed, sizeof(int) * 256); 9110 9083 } ................................................................................ 9132 9105 } 9133 9106 } 9134 9107 9135 9108 /* Re-seed the generator with user-provided bytes */ 9136 9109 static void JimPrngSeed(Jim_Interp *interp, const unsigned char *seed, int seedLen) 9137 9110 { 9138 9111 int i; 9139 - /* REVISIT: Move off stack */ 9112 + /* XXX: Move off stack */ 9140 9113 unsigned char buf[256]; 9141 9114 Jim_PrngState *prng; 9142 9115 9143 9116 /* initialization, only needed the first time */ 9144 9117 if (interp->prngState == NULL) 9145 9118 JimPrngInit(interp); 9146 9119 prng = interp->prngState; ................................................................................ 10123 10096 script->substFlags = flags; 10124 10097 script->fileName = NULL; 10125 10098 SubstObjAddTokens(interp, script, &tokenlist); 10126 10099 10127 10100 /* No longer need the token list */ 10128 10101 ScriptTokenListFree(&tokenlist); 10129 10102 10130 -#if 0 10131 - int i; 10103 +#ifdef DEBUG_SHOW_SUBST 10104 + { 10105 + int i; 10132 10106 10133 - printf("==== Subst ====\n"); 10134 - for (i = 0; i < script->len; i++) { 10135 - printf("[%2d] %s (%d)'%s'\n", i, tt_name(script->token[i].type), 10136 - script->token[i].objPtr->length, script->token[i].objPtr->bytes); 10107 + printf("==== Subst ====\n"); 10108 + for (i = 0; i < script->len; i++) { 10109 + printf("[%2d] %s '%s'\n", i, tt_name(script->token[i].type), 10110 + Jim_GetString(script->token[i].objPtr, NULL)); 10111 + } 10137 10112 } 10138 10113 #endif 10139 10114 10140 10115 /* Free the old internal rep and set the new one. */ 10141 10116 Jim_FreeIntRep(interp, objPtr); 10142 10117 Jim_SetIntRepPtr(objPtr, script); 10143 10118 objPtr->typePtr = &scriptObjType; ................................................................................ 11618 11593 Jim_SetResult(interp, stringObjPtr); 11619 11594 return JIM_OK; 11620 11595 } 11621 11596 11622 11597 /* [debug] */ 11623 11598 static int Jim_DebugCoreCommand(Jim_Interp *interp, int argc, Jim_Obj *const *argv) 11624 11599 { 11600 +#ifdef JIM_DEBUG_COMMAND 11625 11601 const char *options[] = { 11626 11602 "refcount", "objcount", "objects", "invstr", "scriptlen", "exprlen", 11627 11603 "exprbc", 11628 11604 NULL 11629 11605 }; 11630 11606 enum 11631 11607 { ................................................................................ 11646 11622 return JIM_ERR; 11647 11623 } 11648 11624 Jim_SetResultInt(interp, argv[2]->refCount); 11649 11625 return JIM_OK; 11650 11626 } 11651 11627 else if (option == OPT_OBJCOUNT) { 11652 11628 int freeobj = 0, liveobj = 0; 11653 - /* REVISIT: Move off stack */ 11654 11629 char buf[256]; 11655 11630 Jim_Obj *objPtr; 11656 11631 11657 11632 if (argc != 2) { 11658 11633 Jim_WrongNumArgs(interp, 2, argv, ""); 11659 11634 return JIM_ERR; 11660 11635 } ................................................................................ 11678 11653 else if (option == OPT_OBJECTS) { 11679 11654 Jim_Obj *objPtr, *listObjPtr, *subListObjPtr; 11680 11655 11681 11656 /* Count the number of live objects. */ 11682 11657 objPtr = interp->liveList; 11683 11658 listObjPtr = Jim_NewListObj(interp, NULL, 0); 11684 11659 while (objPtr) { 11685 - /* REVISIT: Move off stack */ 11686 11660 char buf[128]; 11687 11661 const char *type = objPtr->typePtr ? objPtr->typePtr->name : ""; 11688 11662 11689 11663 subListObjPtr = Jim_NewListObj(interp, NULL, 0); 11690 11664 sprintf(buf, "%p", objPtr); 11691 11665 Jim_ListAppendElement(interp, subListObjPtr, Jim_NewStringObj(interp, buf, -1)); 11692 11666 Jim_ListAppendElement(interp, subListObjPtr, Jim_NewStringObj(interp, type, -1)); ................................................................................ 11793 11767 return JIM_OK; 11794 11768 } 11795 11769 else { 11796 11770 Jim_SetResultString(interp, 11797 11771 "bad option. Valid options are refcount, " "objcount, objects, invstr", -1); 11798 11772 return JIM_ERR; 11799 11773 } 11800 - return JIM_OK; /* unreached */ 11774 + /* unreached */ 11775 +#else 11776 + Jim_SetResultString(interp, "unsupported", -1); 11777 + return JIM_ERR; 11778 +#endif 11801 11779 } 11802 11780 11803 11781 /* [eval] */ 11804 11782 static int Jim_EvalCoreCommand(Jim_Interp *interp, int argc, Jim_Obj *const *argv) 11805 11783 { 11806 11784 int rc; 11807 11785 Jim_Stack *prevLocalProcs;