From c93d5f617e0aca98a24b1b88a864a07974c61254 Mon Sep 17 00:00:00 2001 From: griffin Date: Fri, 24 May 2024 17:50:38 +0000 Subject: address ticket [43b7e5b511] - Improve zipfs description in tclsh manual. --- doc/tclsh.1 | 26 +++++++++++++++++--------- 1 file changed, 17 insertions(+), 9 deletions(-) diff --git a/doc/tclsh.1 b/doc/tclsh.1 index 91df79d..c75076f 100644 --- a/doc/tclsh.1 +++ b/doc/tclsh.1 @@ -158,14 +158,22 @@ incomplete commands. See \fBTcl_StandardChannels\fR for more explanations. .SH ZIPVFS .PP -When a zipfile is concatenated to the end of a \fBtclsh\fR, on -startup the contents of the zip archive will be mounted as the -virtual file system /zvfs. If a top level directory tcl8.6 is -present in the zip archive, it will become the directory loaded -as env(TCL_LIBRARY). If a file named \fBmain.tcl\fR is present -in the top level directory of the zip archive, it will be sourced -instead of the shell's normal command line handing. +When a zipfile is concatenated to the end of a \fBtclsh\fR, on startup +the contents of the zip archive will be mounted under the virtual file +system \fB//zipfs:/\fR. If a top level directory \fBtcl_library\fR is +present in the zip archive, it will become the directory loaded as +env(TCL_LIBRARY). If a file named \fBmain.tcl\fR is present in the top +level directory of the zip archive, it will be sourced instead of the +shell's normal command line handing. +.PP +Only one zipfile can be concatenated to the end of executable image +(tclsh, or wish). However, if multiple zipfiles are +concatenated, only the last one is used. + +This filesystem is read-only. Files cannot be added or modified within +this mounted file system. See zipfs(n) for complete details. + .SH "SEE ALSO" -auto_path(n), encoding(n), env(n), fconfigure(n) +auto_path(n), encoding(n), env(n), fconfigure(n), zipfs(n) .SH KEYWORDS -application, argument, interpreter, prompt, script file, shell +application, argument, interpreter, prompt, script file, shell, zipfs -- cgit v0.12 From dfbb9a77ad9a9998eaed2cc0b70254f3ae7bfe65 Mon Sep 17 00:00:00 2001 From: dkf Date: Sat, 25 May 2024 09:13:47 +0000 Subject: Add some more C functions for working with dicts [656fe3c816] --- generic/tclDictObj.c | 114 +++++++++++++++++++++++++++++++++++++++++++++++++++ generic/tclInt.h | 6 +++ 2 files changed, 120 insertions(+) diff --git a/generic/tclDictObj.c b/generic/tclDictObj.c index de3547e..b44e437 100644 --- a/generic/tclDictObj.c +++ b/generic/tclDictObj.c @@ -1440,6 +1440,120 @@ Tcl_DbNewDictObj( #endif } +/***** START OF FUNCTIONS ACTING AS HELPERS *****/ + +/* + *---------------------------------------------------------------------- + * + * TclDictGet -- + * + * Given a key, get its value from the dictionary (or NULL if key is not + * found in dictionary.) + * + * Results: + * A standard Tcl result. The variable pointed to by valuePtrPtr is + * updated with the value for the key. Note that it is not an error for + * the key to have no mapping in the dictionary. + * + * Side effects: + * The object pointed to by dictPtr is converted to a dictionary if it is + * not already one. + * + *---------------------------------------------------------------------- + */ +int +TclDictGet( + Tcl_Interp *interp, + Tcl_Obj *dictPtr, + const char *key, /* The key in a C string. */ + Tcl_Obj **valuePtrPtr) /* Where to write the value. */ +{ + Tcl_Obj *keyPtr = Tcl_NewStringObj(key, -1); + int code; + + Tcl_IncrRefCount(keyPtr); + code = Tcl_DictObjGet(interp, dictPtr, keyPtr, valuePtrPtr); + Tcl_DecrRefCount(keyPtr); + return code; +} + +/* + *---------------------------------------------------------------------- + * + * TclDictPut -- + * + * Add a key,value pair to a dictionary, or update the value for a key if + * that key already has a mapping in the dictionary. + * + * If valuePtr is a zero-count object and is not written into the + * dictionary because of an error, it is freed by this routine. The caller + * does NOT need to do reference count management. + * + * Results: + * A standard Tcl result. + * + * Side effects: + * The object pointed to by dictPtr is converted to a dictionary if it is + * not already one, and any string representation that it has is + * invalidated. + * + *---------------------------------------------------------------------- + */ +int +TclDictPut( + Tcl_Interp *interp, + Tcl_Obj *dictPtr, + const char *key, /* The key in a C string. */ + Tcl_Obj *valuePtr) /* The value to write in. */ +{ + Tcl_Obj *keyPtr = Tcl_NewStringObj(key, -1); + int code; + + Tcl_IncrRefCount(keyPtr); + Tcl_IncrRefCount(valuePtr); + code = Tcl_DictObjPut(interp, dictPtr, keyPtr, valuePtr); + Tcl_DecrRefCount(keyPtr); + Tcl_DecrRefCount(valuePtr); + return code; +} + +/* + *---------------------------------------------------------------------- + * + * TclDictPutString -- + * + * Add a key,value pair to a dictionary, or update the value for a key if + * that key already has a mapping in the dictionary. + * + * Results: + * A standard Tcl result. + * + * Side effects: + * The object pointed to by dictPtr is converted to a dictionary if it is + * not already one, and any string representation that it has is + * invalidated. + * + *---------------------------------------------------------------------- + */ +int +TclDictPutString( + Tcl_Interp *interp, + Tcl_Obj *dictPtr, + const char *key, /* The key in a C string. */ + const char *value) /* The value in a C string. */ +{ + Tcl_Obj *keyPtr = Tcl_NewStringObj(key, -1); + Tcl_Obj *valuePtr = Tcl_NewStringObj(value, -1); + int code; + + Tcl_IncrRefCount(keyPtr); + Tcl_IncrRefCount(valuePtr); + code = Tcl_DictObjPut(interp, dictPtr, keyPtr, valuePtr); + Tcl_DecrRefCount(keyPtr); + Tcl_DecrRefCount(valuePtr); + return code; +} + /***** START OF FUNCTIONS IMPLEMENTING TCL COMMANDS *****/ /* diff --git a/generic/tclInt.h b/generic/tclInt.h index 5890bcb..a3761e5 100644 --- a/generic/tclInt.h +++ b/generic/tclInt.h @@ -2918,6 +2918,12 @@ MODULE_SCOPE int TclFindDictElement(Tcl_Interp *interp, const char *dict, int dictLength, const char **elementPtr, const char **nextPtr, int *sizePtr, int *literalPtr); +MODULE_SCOPE int TclDictGet(Tcl_Interp *interp, Tcl_Obj *dictPtr, + const char *key, Tcl_Obj **valuePtrPtr); +MODULE_SCOPE int TclDictPut(Tcl_Interp *interp, Tcl_Obj *dictPtr, + const char *key, Tcl_Obj *valuePtr); +MODULE_SCOPE int TclDictPutString(Tcl_Interp *interp, Tcl_Obj *dictPtr, + const char *key, const char *value); /* TIP #280 - Modified token based evaluation, with line information. */ MODULE_SCOPE int TclEvalEx(Tcl_Interp *interp, const char *script, int numBytes, int flags, int line, -- cgit v0.12 From 52e0863e247b040ad4634a2d76fb635864cc03f7 Mon Sep 17 00:00:00 2001 From: dkf Date: Sat, 25 May 2024 11:31:34 +0000 Subject: Use the new operations --- generic/tclCmdMZ.c | 6 ++---- generic/tclCompCmds.c | 15 ++++++--------- generic/tclCompCmdsSZ.c | 5 ++--- generic/tclConfig.c | 2 +- generic/tclDictObj.c | 33 ++++++++++++++++++++++++++++++++ generic/tclDisassemble.c | 50 ++++++++++++++++++++---------------------------- generic/tclEncoding.c | 11 ++++------- generic/tclEnsemble.c | 5 ++--- generic/tclEvent.c | 30 +++++++---------------------- generic/tclIOCmd.c | 3 +-- generic/tclInt.h | 2 ++ generic/tclInterp.c | 41 ++++++++++++++++----------------------- generic/tclMain.c | 8 ++------ generic/tclOOInfo.c | 6 ++---- generic/tclZlib.c | 48 ++++++++++++++++------------------------------ 15 files changed, 117 insertions(+), 148 deletions(-) diff --git a/generic/tclCmdMZ.c b/generic/tclCmdMZ.c index 41782b0..a6e9ffd 100644 --- a/generic/tclCmdMZ.c +++ b/generic/tclCmdMZ.c @@ -5115,12 +5115,10 @@ TryPostBody( */ if (code == TCL_ERROR) { - Tcl_Obj *errorCodeName, *errcode, **bits1, **bits2; + Tcl_Obj *errcode, **bits1, **bits2; int len1, len2, j; - TclNewLiteralStringObj(errorCodeName, "-errorcode"); - Tcl_DictObjGet(NULL, options, errorCodeName, &errcode); - Tcl_DecrRefCount(errorCodeName); + TclDictGet(NULL, options, "-errorcode", &errcode); TclListObjGetElements(NULL, info[2], &len1, &bits1); if (TclListObjGetElements(NULL, errcode, &len2, &bits2) != TCL_OK) { diff --git a/generic/tclCompCmds.c b/generic/tclCompCmds.c index bafcb13..a422072 100644 --- a/generic/tclCompCmds.c +++ b/generic/tclCompCmds.c @@ -2293,8 +2293,7 @@ DisassembleDictUpdateInfo( Tcl_ListObjAppendElement(NULL, variables, Tcl_NewIntObj(duiPtr->varIndices[i])); } - Tcl_DictObjPut(NULL, dictObj, Tcl_NewStringObj("variables", -1), - variables); + TclDictPut(NULL, dictObj, "variables", variables); } /* @@ -3035,14 +3034,13 @@ DisassembleForeachInfo( Tcl_ListObjAppendElement(NULL, objPtr, Tcl_NewIntObj(infoPtr->firstValueTemp + i)); } - Tcl_DictObjPut(NULL, dictObj, Tcl_NewStringObj("data", -1), objPtr); + TclDictPut(NULL, dictObj, "data", objPtr); /* * Loop counter. */ - Tcl_DictObjPut(NULL, dictObj, Tcl_NewStringObj("loop", -1), - Tcl_NewIntObj(infoPtr->loopCtTemp)); + TclDictPut(NULL, dictObj, "loop", Tcl_NewIntObj(infoPtr->loopCtTemp)); /* * Assignment targets. @@ -3058,7 +3056,7 @@ DisassembleForeachInfo( } Tcl_ListObjAppendElement(NULL, objPtr, innerPtr); } - Tcl_DictObjPut(NULL, dictObj, Tcl_NewStringObj("assign", -1), objPtr); + TclDictPut(NULL, dictObj, "assign", objPtr); } static void @@ -3077,8 +3075,7 @@ DisassembleNewForeachInfo( * Jump offset. */ - Tcl_DictObjPut(NULL, dictObj, Tcl_NewStringObj("jumpOffset", -1), - Tcl_NewIntObj(infoPtr->loopCtTemp)); + TclDictPut(NULL, dictObj, "jumpOffset", Tcl_NewIntObj(infoPtr->loopCtTemp)); /* * Assignment targets. @@ -3094,7 +3091,7 @@ DisassembleNewForeachInfo( } Tcl_ListObjAppendElement(NULL, objPtr, innerPtr); } - Tcl_DictObjPut(NULL, dictObj, Tcl_NewStringObj("assign", -1), objPtr); + TclDictPut(NULL, dictObj, "assign", objPtr); } /* diff --git a/generic/tclCompCmdsSZ.c b/generic/tclCompCmdsSZ.c index a7db705..4f2ee70 100644 --- a/generic/tclCompCmdsSZ.c +++ b/generic/tclCompCmdsSZ.c @@ -2574,10 +2574,9 @@ DisassembleJumptableInfo( for (; hPtr ; hPtr = Tcl_NextHashEntry(&search)) { keyPtr = (const char *)Tcl_GetHashKey(&jtPtr->hashTable, hPtr); offset = PTR2INT(Tcl_GetHashValue(hPtr)); - Tcl_DictObjPut(NULL, mapping, Tcl_NewStringObj(keyPtr, -1), - Tcl_NewIntObj(offset)); + TclDictPut(NULL, mapping, keyPtr, Tcl_NewIntObj(offset)); } - Tcl_DictObjPut(NULL, dictObj, Tcl_NewStringObj("mapping", -1), mapping); + TclDictPut(NULL, dictObj, "mapping", mapping); } /* diff --git a/generic/tclConfig.c b/generic/tclConfig.c index a1a53bc..8fe8fc9 100644 --- a/generic/tclConfig.c +++ b/generic/tclConfig.c @@ -128,7 +128,7 @@ Tcl_RegisterConfig( */ for (cfg=configuration ; cfg->key!=NULL && cfg->key[0]!='\0' ; cfg++) { - Tcl_DictObjPut(interp, pkgDict, Tcl_NewStringObj(cfg->key, -1), + TclDictPut(interp, pkgDict, cfg->key, Tcl_NewByteArrayObj((unsigned char *)cfg->value, strlen(cfg->value))); } diff --git a/generic/tclDictObj.c b/generic/tclDictObj.c index b44e437..3cd9f43 100644 --- a/generic/tclDictObj.c +++ b/generic/tclDictObj.c @@ -1554,6 +1554,39 @@ TclDictPutString( return code; } +/* + *---------------------------------------------------------------------- + * + * TclDictRemove -- + * + * Remove the key,value pair with the given key from the dictionary; the + * key does not need to be present in the dictionary. + * + * Results: + * A standard Tcl result. + * + * Side effects: + * The object pointed to by dictPtr is converted to a dictionary if it is + * not already one, and any string representation that it has is + * invalidated. + * + *---------------------------------------------------------------------- + */ +int +TclDictRemove( + Tcl_Interp *interp, + Tcl_Obj *dictPtr, + const char *key) /* The key in a C string. */ +{ + Tcl_Obj *keyPtr = Tcl_NewStringObj(key, -1); + int code; + + Tcl_IncrRefCount(keyPtr); + code = Tcl_DictObjRemove(interp, dictPtr, keyPtr); + Tcl_DecrRefCount(keyPtr); + return code; +} + /***** START OF FUNCTIONS IMPLEMENTING TCL COMMANDS *****/ /* diff --git a/generic/tclDisassemble.c b/generic/tclDisassemble.c index 9597beb..a66b6a9 100644 --- a/generic/tclDisassemble.c +++ b/generic/tclDisassemble.c @@ -1113,7 +1113,7 @@ DisassembleByteCodeAsDicts( Tcl_Obj *desc; TclNewObj(desc); - Tcl_DictObjPut(NULL, desc, Tcl_NewStringObj("name", -1), auxDesc); + TclDictPut(NULL, desc, "name", auxDesc); auxDesc = desc; auxData->type->disassembleProc(auxData->clientData, auxDesc, codePtr, 0); @@ -1180,23 +1180,21 @@ DisassembleByteCodeAsDicts( sourceOffset += Decode(srcOffPtr); sourceLength = Decode(srcLenPtr); TclNewObj(cmd); - Tcl_DictObjPut(NULL, cmd, Tcl_NewStringObj("codefrom", -1), - Tcl_NewIntObj(codeOffset)); - Tcl_DictObjPut(NULL, cmd, Tcl_NewStringObj("codeto", -1), - Tcl_NewIntObj(codeOffset + codeLength - 1)); + TclDictPut(NULL, cmd, "codefrom", Tcl_NewIntObj(codeOffset)); + TclDictPut(NULL, cmd, "codeto", Tcl_NewIntObj( + codeOffset + codeLength - 1)); /* * Convert byte offsets to character offsets; important if multibyte * characters are present in the source! */ - Tcl_DictObjPut(NULL, cmd, Tcl_NewStringObj("scriptfrom", -1), - Tcl_NewIntObj(Tcl_NumUtfChars(codePtr->source, - sourceOffset))); - Tcl_DictObjPut(NULL, cmd, Tcl_NewStringObj("scriptto", -1), - Tcl_NewIntObj(Tcl_NumUtfChars(codePtr->source, + TclDictPut(NULL, cmd, "scriptfrom", Tcl_NewIntObj( + Tcl_NumUtfChars(codePtr->source, sourceOffset))); + TclDictPut(NULL, cmd, "scriptto", Tcl_NewIntObj( + Tcl_NumUtfChars(codePtr->source, sourceOffset + sourceLength - 1))); - Tcl_DictObjPut(NULL, cmd, Tcl_NewStringObj("script", -1), + TclDictPut(NULL, cmd, "script", Tcl_NewStringObj(codePtr->source+sourceOffset, sourceLength)); Tcl_ListObjAppendElement(NULL, commands, cmd); } @@ -1215,32 +1213,26 @@ DisassembleByteCodeAsDicts( */ TclNewObj(description); - Tcl_DictObjPut(NULL, description, Tcl_NewStringObj("literals", -1), - literals); - Tcl_DictObjPut(NULL, description, Tcl_NewStringObj("variables", -1), - variables); - Tcl_DictObjPut(NULL, description, Tcl_NewStringObj("exception", -1), exn); - Tcl_DictObjPut(NULL, description, Tcl_NewStringObj("instructions", -1), - instructions); - Tcl_DictObjPut(NULL, description, Tcl_NewStringObj("auxiliary", -1), aux); - Tcl_DictObjPut(NULL, description, Tcl_NewStringObj("commands", -1), - commands); - Tcl_DictObjPut(NULL, description, Tcl_NewStringObj("script", -1), + TclDictPut(NULL, description, "literals", literals); + TclDictPut(NULL, description, "variables", variables); + TclDictPut(NULL, description, "exception", exn); + TclDictPut(NULL, description, "instructions", instructions); + TclDictPut(NULL, description, "auxiliary", aux); + TclDictPut(NULL, description, "commands", commands); + TclDictPut(NULL, description, "script", Tcl_NewStringObj(codePtr->source, codePtr->numSrcBytes)); - Tcl_DictObjPut(NULL, description, Tcl_NewStringObj("namespace", -1), + TclDictPut(NULL, description, "namespace", Tcl_NewStringObj(codePtr->nsPtr->fullName, -1)); - Tcl_DictObjPut(NULL, description, Tcl_NewStringObj("stackdepth", -1), + TclDictPut(NULL, description, "stackdepth", Tcl_NewIntObj(codePtr->maxStackDepth)); - Tcl_DictObjPut(NULL, description, Tcl_NewStringObj("exceptdepth", -1), + TclDictPut(NULL, description, "exceptdepth", Tcl_NewIntObj(codePtr->maxExceptDepth)); if (line > -1) { - Tcl_DictObjPut(NULL, description, - Tcl_NewStringObj("initiallinenumber", -1), + TclDictPut(NULL, description, "initiallinenumber", Tcl_NewIntObj(line)); } if (file) { - Tcl_DictObjPut(NULL, description, - Tcl_NewStringObj("sourcefile", -1), file); + TclDictPut(NULL, description, "sourcefile", file); } return description; } diff --git a/generic/tclEncoding.c b/generic/tclEncoding.c index ba9f811..bbcaeb9 100644 --- a/generic/tclEncoding.c +++ b/generic/tclEncoding.c @@ -1494,8 +1494,7 @@ OpenEncodingFileChannel( const char *name) /* The name of the encoding file on disk and * also the name for new encoding. */ { - Tcl_Obj *nameObj = Tcl_NewStringObj(name, -1); - Tcl_Obj *fileNameObj = Tcl_DuplicateObj(nameObj); + Tcl_Obj *fileNameObj = Tcl_NewStringObj(name, -1); Tcl_Obj *searchPath = Tcl_DuplicateObj(Tcl_GetEncodingSearchPath()); Tcl_Obj *map = TclGetProcessGlobalValue(&encodingFileMap); Tcl_Obj **dir, *path, *directory = NULL; @@ -1503,10 +1502,9 @@ OpenEncodingFileChannel( int i, numDirs; TclListObjGetElements(NULL, searchPath, &numDirs, &dir); - Tcl_IncrRefCount(nameObj); Tcl_AppendToObj(fileNameObj, ".enc", -1); Tcl_IncrRefCount(fileNameObj); - Tcl_DictObjGet(NULL, map, nameObj, &directory); + TclDictGet(NULL, map, name, &directory); /* * Check that any cached directory is still on the encoding search path. @@ -1535,7 +1533,7 @@ OpenEncodingFileChannel( */ map = Tcl_DuplicateObj(map); - Tcl_DictObjRemove(NULL, map, nameObj); + TclDictRemove(NULL, map, name); TclSetProcessGlobalValue(&encodingFileMap, map, NULL); directory = NULL; } @@ -1569,7 +1567,7 @@ OpenEncodingFileChannel( */ map = Tcl_DuplicateObj(TclGetProcessGlobalValue(&encodingFileMap)); - Tcl_DictObjPut(NULL, map, nameObj, dir[i]); + TclDictPut(NULL, map, name, dir[i]); TclSetProcessGlobalValue(&encodingFileMap, map, NULL); } } @@ -1580,7 +1578,6 @@ OpenEncodingFileChannel( Tcl_SetErrorCode(interp, "TCL", "LOOKUP", "ENCODING", name, NULL); } Tcl_DecrRefCount(fileNameObj); - Tcl_DecrRefCount(nameObj); Tcl_DecrRefCount(searchPath); return chan; diff --git a/generic/tclEnsemble.c b/generic/tclEnsemble.c index f1d7134..dea3bed 100644 --- a/generic/tclEnsemble.c +++ b/generic/tclEnsemble.c @@ -1586,17 +1586,16 @@ TclMakeEnsemble( */ if (ensemble != NULL) { - Tcl_Obj *mapDict, *fromObj, *toObj; + Tcl_Obj *mapDict, *toObj; Command *cmdPtr; TclDStringAppendLiteral(&buf, "::"); TclNewObj(mapDict); for (i=0 ; map[i].name != NULL ; i++) { - fromObj = Tcl_NewStringObj(map[i].name, -1); TclNewStringObj(toObj, Tcl_DStringValue(&buf), Tcl_DStringLength(&buf)); Tcl_AppendToObj(toObj, map[i].name, -1); - Tcl_DictObjPut(NULL, mapDict, fromObj, toObj); + TclDictPut(NULL, mapDict, map[i].name, toObj); if (map[i].proc || map[i].nreProc) { /* diff --git a/generic/tclEvent.c b/generic/tclEvent.c index c2e71ec..49880b6 100644 --- a/generic/tclEvent.c +++ b/generic/tclEvent.c @@ -263,13 +263,9 @@ HandleBgErrors( if (errChannel != NULL) { Tcl_Obj *options = Tcl_GetReturnOptions(interp, code); - Tcl_Obj *keyPtr, *valuePtr = NULL; - - TclNewLiteralStringObj(keyPtr, "-errorinfo"); - Tcl_IncrRefCount(keyPtr); - Tcl_DictObjGet(NULL, options, keyPtr, &valuePtr); - Tcl_DecrRefCount(keyPtr); + Tcl_Obj *valuePtr = NULL; + TclDictGet(NULL, options, "-errorinfo", &valuePtr); Tcl_WriteChars(errChannel, "error in background error handler:\n", -1); if (valuePtr) { @@ -313,7 +309,7 @@ TclDefaultBgErrorHandlerObjCmd( int objc, /* Number of arguments. */ Tcl_Obj *const objv[]) /* Argument objects. */ { - Tcl_Obj *keyPtr, *valuePtr; + Tcl_Obj *valuePtr; Tcl_Obj *tempObjv[2]; int result, code, level; Tcl_InterpState saved; @@ -327,10 +323,7 @@ TclDefaultBgErrorHandlerObjCmd( * Check for a valid return options dictionary. */ - TclNewLiteralStringObj(keyPtr, "-level"); - Tcl_IncrRefCount(keyPtr); - result = Tcl_DictObjGet(NULL, objv[2], keyPtr, &valuePtr); - Tcl_DecrRefCount(keyPtr); + result = TclDictGet(NULL, objv[2], "-level", &valuePtr); if (result != TCL_OK || valuePtr == NULL) { Tcl_SetObjResult(interp, Tcl_NewStringObj( "missing return option \"-level\"", -1)); @@ -340,10 +333,7 @@ TclDefaultBgErrorHandlerObjCmd( if (Tcl_GetIntFromObj(interp, valuePtr, &level) == TCL_ERROR) { return TCL_ERROR; } - TclNewLiteralStringObj(keyPtr, "-code"); - Tcl_IncrRefCount(keyPtr); - result = Tcl_DictObjGet(NULL, objv[2], keyPtr, &valuePtr); - Tcl_DecrRefCount(keyPtr); + result = TclDictGet(NULL, objv[2], "-code", &valuePtr); if (result != TCL_OK || valuePtr == NULL) { Tcl_SetObjResult(interp, Tcl_NewStringObj( "missing return option \"-code\"", -1)); @@ -405,18 +395,12 @@ TclDefaultBgErrorHandlerObjCmd( Tcl_SetObjResult(interp, tempObjv[1]); } - TclNewLiteralStringObj(keyPtr, "-errorcode"); - Tcl_IncrRefCount(keyPtr); - result = Tcl_DictObjGet(NULL, objv[2], keyPtr, &valuePtr); - Tcl_DecrRefCount(keyPtr); + result = TclDictGet(NULL, objv[2], "-errorcode", &valuePtr); if (result == TCL_OK && valuePtr != NULL) { Tcl_SetObjErrorCode(interp, valuePtr); } - TclNewLiteralStringObj(keyPtr, "-errorinfo"); - Tcl_IncrRefCount(keyPtr); - result = Tcl_DictObjGet(NULL, objv[2], keyPtr, &valuePtr); - Tcl_DecrRefCount(keyPtr); + result = TclDictGet(NULL, objv[2], "-errorinfo", &valuePtr); if (result == TCL_OK && valuePtr != NULL) { Tcl_AppendObjToErrorInfo(interp, valuePtr); } diff --git a/generic/tclIOCmd.c b/generic/tclIOCmd.c index 5127b99..cdcef10 100644 --- a/generic/tclIOCmd.c +++ b/generic/tclIOCmd.c @@ -2005,8 +2005,7 @@ TclInitChanCmd( * Can assume that reference counts are all incremented. */ - Tcl_DictObjPut(NULL, mapObj, Tcl_NewStringObj(extras[i], -1), - Tcl_NewStringObj(extras[i+1], -1)); + TclDictPutString(NULL, mapObj, extras[i], extras[i + 1]); } Tcl_SetEnsembleMappingDict(interp, ensemble, mapObj); return ensemble; diff --git a/generic/tclInt.h b/generic/tclInt.h index a3761e5..df3d7c8 100644 --- a/generic/tclInt.h +++ b/generic/tclInt.h @@ -2924,6 +2924,8 @@ MODULE_SCOPE int TclDictPut(Tcl_Interp *interp, Tcl_Obj *dictPtr, const char *key, Tcl_Obj *valuePtr); MODULE_SCOPE int TclDictPutString(Tcl_Interp *interp, Tcl_Obj *dictPtr, const char *key, const char *value); +MODULE_SCOPE int TclDictRemove(Tcl_Interp *interp, Tcl_Obj *dictPtr, + const char *key); /* TIP #280 - Modified token based evaluation, with line information. */ MODULE_SCOPE int TclEvalEx(Tcl_Interp *interp, const char *script, int numBytes, int flags, int line, diff --git a/generic/tclInterp.c b/generic/tclInterp.c index b0f6207..ad06293 100644 --- a/generic/tclInterp.c +++ b/generic/tclInterp.c @@ -4428,8 +4428,7 @@ ChildCommandLimitCmd( if (hPtr != NULL) { limitCBPtr = (ScriptLimitCallback *)Tcl_GetHashValue(hPtr); if (limitCBPtr != NULL && limitCBPtr->scriptObj != NULL) { - Tcl_DictObjPut(NULL, dictPtr, Tcl_NewStringObj(options[0], -1), - limitCBPtr->scriptObj); + TclDictPut(NULL, dictPtr, options[0], limitCBPtr->scriptObj); } else { goto putEmptyCommandInDict; } @@ -4438,22 +4437,19 @@ ChildCommandLimitCmd( putEmptyCommandInDict: TclNewObj(empty); - Tcl_DictObjPut(NULL, dictPtr, - Tcl_NewStringObj(options[0], -1), empty); + TclDictPut(NULL, dictPtr, options[0], empty); } - Tcl_DictObjPut(NULL, dictPtr, Tcl_NewStringObj(options[1], -1), - Tcl_NewIntObj(Tcl_LimitGetGranularity(childInterp, - TCL_LIMIT_COMMANDS))); + TclDictPut(NULL, dictPtr, options[1], Tcl_NewIntObj( + Tcl_LimitGetGranularity(childInterp, TCL_LIMIT_COMMANDS))); if (Tcl_LimitTypeEnabled(childInterp, TCL_LIMIT_COMMANDS)) { - Tcl_DictObjPut(NULL, dictPtr, Tcl_NewStringObj(options[2], -1), - Tcl_NewIntObj(Tcl_LimitGetCommands(childInterp))); + TclDictPut(NULL, dictPtr, options[2], Tcl_NewIntObj( + Tcl_LimitGetCommands(childInterp))); } else { Tcl_Obj *empty; TclNewObj(empty); - Tcl_DictObjPut(NULL, dictPtr, - Tcl_NewStringObj(options[2], -1), empty); + TclDictPut(NULL, dictPtr, options[2], empty); } Tcl_SetObjResult(interp, dictPtr); return TCL_OK; @@ -4616,8 +4612,7 @@ ChildTimeLimitCmd( if (hPtr != NULL) { limitCBPtr = (ScriptLimitCallback *)Tcl_GetHashValue(hPtr); if (limitCBPtr != NULL && limitCBPtr->scriptObj != NULL) { - Tcl_DictObjPut(NULL, dictPtr, Tcl_NewStringObj(options[0], -1), - limitCBPtr->scriptObj); + TclDictPut(NULL, dictPtr, options[0], limitCBPtr->scriptObj); } else { goto putEmptyCommandInDict; } @@ -4625,29 +4620,25 @@ ChildTimeLimitCmd( Tcl_Obj *empty; putEmptyCommandInDict: TclNewObj(empty); - Tcl_DictObjPut(NULL, dictPtr, - Tcl_NewStringObj(options[0], -1), empty); + TclDictPut(NULL, dictPtr, options[0], empty); } - Tcl_DictObjPut(NULL, dictPtr, Tcl_NewStringObj(options[1], -1), - Tcl_NewIntObj(Tcl_LimitGetGranularity(childInterp, - TCL_LIMIT_TIME))); + TclDictPut(NULL, dictPtr, options[1], Tcl_NewIntObj( + Tcl_LimitGetGranularity(childInterp, TCL_LIMIT_TIME))); if (Tcl_LimitTypeEnabled(childInterp, TCL_LIMIT_TIME)) { Tcl_Time limitMoment; Tcl_LimitGetTime(childInterp, &limitMoment); - Tcl_DictObjPut(NULL, dictPtr, Tcl_NewStringObj(options[2], -1), - Tcl_NewLongObj(limitMoment.usec/1000)); - Tcl_DictObjPut(NULL, dictPtr, Tcl_NewStringObj(options[3], -1), + TclDictPut(NULL, dictPtr, options[2], + Tcl_NewLongObj(limitMoment.usec / 1000)); + TclDictPut(NULL, dictPtr, options[3], Tcl_NewLongObj(limitMoment.sec)); } else { Tcl_Obj *empty; TclNewObj(empty); - Tcl_DictObjPut(NULL, dictPtr, - Tcl_NewStringObj(options[2], -1), empty); - Tcl_DictObjPut(NULL, dictPtr, - Tcl_NewStringObj(options[3], -1), empty); + TclDictPut(NULL, dictPtr, options[2], empty); + TclDictPut(NULL, dictPtr, options[3], empty); } Tcl_SetObjResult(interp, dictPtr); return TCL_OK; diff --git a/generic/tclMain.c b/generic/tclMain.c index 4f31924..d2ab04a 100644 --- a/generic/tclMain.c +++ b/generic/tclMain.c @@ -405,13 +405,9 @@ Tcl_MainEx( chan = Tcl_GetStdChannel(TCL_STDERR); if (chan) { Tcl_Obj *options = Tcl_GetReturnOptions(interp, code); - Tcl_Obj *keyPtr, *valuePtr; - - TclNewLiteralStringObj(keyPtr, "-errorinfo"); - Tcl_IncrRefCount(keyPtr); - Tcl_DictObjGet(NULL, options, keyPtr, &valuePtr); - Tcl_DecrRefCount(keyPtr); + Tcl_Obj *valuePtr = NULL; + TclDictGet(NULL, options, "-errorinfo", &valuePtr); if (valuePtr) { Tcl_WriteObj(chan, valuePtr); } diff --git a/generic/tclOOInfo.c b/generic/tclOOInfo.c index 081dd5b..8f544e1 100644 --- a/generic/tclOOInfo.c +++ b/generic/tclOOInfo.c @@ -116,10 +116,8 @@ TclOOInitInfo( infoCmd = Tcl_FindCommand(interp, "info", NULL, TCL_GLOBAL_ONLY); if (infoCmd) { Tcl_GetEnsembleMappingDict(NULL, infoCmd, &mapDict); - Tcl_DictObjPut(NULL, mapDict, Tcl_NewStringObj("object", -1), - Tcl_NewStringObj("::oo::InfoObject", -1)); - Tcl_DictObjPut(NULL, mapDict, Tcl_NewStringObj("class", -1), - Tcl_NewStringObj("::oo::InfoClass", -1)); + TclDictPutString(NULL, mapDict, "object", "::oo::InfoObject"); + TclDictPutString(NULL, mapDict, "class", "::oo::InfoClass"); Tcl_SetEnsembleMappingDict(interp, infoCmd, mapDict); } } diff --git a/generic/tclZlib.c b/generic/tclZlib.c index 4b0332b..e043212 100644 --- a/generic/tclZlib.c +++ b/generic/tclZlib.c @@ -385,7 +385,7 @@ ConvertErrorToList( * GenerateHeader -- * * Function for creating a gzip header from the contents of a dictionary - * (as described in the documentation). GetValue is a helper function. + * (as described in the documentation). * * Results: * A Tcl result code. @@ -398,20 +398,6 @@ ConvertErrorToList( *---------------------------------------------------------------------- */ -static inline int -GetValue( - Tcl_Interp *interp, - Tcl_Obj *dictObj, - const char *nameStr, - Tcl_Obj **valuePtrPtr) -{ - Tcl_Obj *name = Tcl_NewStringObj(nameStr, -1); - int result = Tcl_DictObjGet(interp, dictObj, name, valuePtrPtr); - - TclDecrRefCount(name); - return result; -} - static int GenerateHeader( Tcl_Interp *interp, /* Where to put error messages. */ @@ -438,7 +424,7 @@ GenerateHeader( Tcl_Panic("no latin-1 encoding"); } - if (GetValue(interp, dictObj, "comment", &value) != TCL_OK) { + if (TclDictGet(interp, dictObj, "comment", &value) != TCL_OK) { goto error; } else if (value != NULL) { Tcl_EncodingState state; @@ -465,14 +451,14 @@ GenerateHeader( } } - if (GetValue(interp, dictObj, "crc", &value) != TCL_OK) { + if (TclDictGet(interp, dictObj, "crc", &value) != TCL_OK) { goto error; } else if (value != NULL && Tcl_GetBooleanFromObj(interp, value, &headerPtr->header.hcrc)) { goto error; } - if (GetValue(interp, dictObj, "filename", &value) != TCL_OK) { + if (TclDictGet(interp, dictObj, "filename", &value) != TCL_OK) { goto error; } else if (value != NULL) { Tcl_EncodingState state; @@ -499,7 +485,7 @@ GenerateHeader( } } - if (GetValue(interp, dictObj, "os", &value) != TCL_OK) { + if (TclDictGet(interp, dictObj, "os", &value) != TCL_OK) { goto error; } else if (value != NULL && Tcl_GetIntFromObj(interp, value, &headerPtr->header.os) != TCL_OK) { @@ -511,14 +497,14 @@ GenerateHeader( * input data. */ - if (GetValue(interp, dictObj, "time", &value) != TCL_OK) { + if (TclDictGet(interp, dictObj, "time", &value) != TCL_OK) { goto error; } else if (value != NULL && Tcl_GetLongFromObj(interp, value, (long *) &headerPtr->header.time) != TCL_OK) { goto error; } - if (GetValue(interp, dictObj, "type", &value) != TCL_OK) { + if (TclDictGet(interp, dictObj, "type", &value) != TCL_OK) { goto error; } else if (value != NULL && Tcl_GetIndexFromObj(interp, value, types, "type", TCL_EXACT, &headerPtr->header.text) != TCL_OK) { @@ -548,9 +534,6 @@ GenerateHeader( *---------------------------------------------------------------------- */ -#define SetValue(dictObj, key, value) \ - Tcl_DictObjPut(NULL, (dictObj), Tcl_NewStringObj((key), -1), (value)) - static void ExtractHeader( gz_header *headerPtr, /* The gzip header to extract from. */ @@ -573,9 +556,9 @@ ExtractHeader( Tcl_ExternalToUtfDString(latin1enc, (char *) headerPtr->comment, -1, &tmp); - SetValue(dictObj, "comment", TclDStringToObj(&tmp)); + TclDictPut(NULL, dictObj, "comment", TclDStringToObj(&tmp)); } - SetValue(dictObj, "crc", Tcl_NewBooleanObj(headerPtr->hcrc)); + TclDictPut(NULL, dictObj, "crc", Tcl_NewBooleanObj(headerPtr->hcrc)); if (headerPtr->name != Z_NULL) { if (latin1enc == NULL) { /* @@ -590,17 +573,18 @@ ExtractHeader( Tcl_ExternalToUtfDString(latin1enc, (char *) headerPtr->name, -1, &tmp); - SetValue(dictObj, "filename", TclDStringToObj(&tmp)); + TclDictPut(NULL, dictObj, "filename", TclDStringToObj(&tmp)); } if (headerPtr->os != 255) { - SetValue(dictObj, "os", Tcl_NewIntObj(headerPtr->os)); + TclDictPut(NULL, dictObj, "os", Tcl_NewIntObj(headerPtr->os)); } if (headerPtr->time != 0 /* magic - no time */) { - SetValue(dictObj, "time", Tcl_NewLongObj((long) headerPtr->time)); + TclDictPut(NULL, dictObj, "time", + Tcl_NewLongObj((long) headerPtr->time)); } if (headerPtr->text != Z_UNKNOWN) { - SetValue(dictObj, "type", - Tcl_NewStringObj(headerPtr->text ? "text" : "binary", -1)); + TclDictPutString(NULL, dictObj, "type", + headerPtr->text ? "text" : "binary"); } if (latin1enc != NULL) { @@ -1889,7 +1873,7 @@ Tcl_ZlibInflate( Tcl_SetByteArrayLength(obj, stream.total_out); if (headerPtr != NULL) { ExtractHeader(&header, gzipHeaderDictObj); - SetValue(gzipHeaderDictObj, "size", + TclDictPut(NULL, gzipHeaderDictObj, "size", Tcl_NewLongObj(stream.total_out)); ckfree(nameBuf); ckfree(commentBuf); -- cgit v0.12 From bd2dadab2d53cd341caf886ecd8541c5958f9546 Mon Sep 17 00:00:00 2001 From: griffin Date: Sat, 25 May 2024 18:32:05 +0000 Subject: Add note about static vs dynamic builds. --- doc/zipfs.n | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/doc/zipfs.n b/doc/zipfs.n index d4f97a8..60b98c5 100644 --- a/doc/zipfs.n +++ b/doc/zipfs.n @@ -203,6 +203,18 @@ then the resulting image is an executable that will \fBsource\fR the script in that \fBmain.tcl\fR after mounting the ZIP archive, and will \fBexit\fR once that script has been executed. .PP +\fBNote:\fR \fBtclsh\fR and \fBwish\fR can be built using either +dynamic binding or static binding of the core implemenation +libraries. With a dynamic binding, the base application Tcl_Library +contents are attached to the \fBlibtcl\fR and \fBlibtk\fR shared +library, respectively. With a static binding, the Tcl_Library +contents, etc., are attached to the application, \fBtclsh\fR or +\fBwish\fR. When using \fBmkimg\fR with a staticly built tclsh, it is +the user's responsibility to preserve the attached archive by first +extracting it to a temporary location, and then add whatever +additional files desired, before creating and attaching the new +archive to the new application. +.PP \fBCaution:\fR highly experimental, not usable on Android, only partially tested on Linux and Windows. .RE -- cgit v0.12 From ca2e6faeaae3e6a777b4d56cdf0bb2e09f449b0f Mon Sep 17 00:00:00 2001 From: griffin Date: Sun, 26 May 2024 19:21:49 +0000 Subject: Fix spelling errors. --- doc/zipfs.n | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/doc/zipfs.n b/doc/zipfs.n index 60b98c5..9ac283d 100644 --- a/doc/zipfs.n +++ b/doc/zipfs.n @@ -57,7 +57,7 @@ This takes the name of a file, \fIfilename\fR, and produces where it would be mapped into a zipfs mount as its result. If specified, \fImountpoint\fR says within which mount the mapping will be done; if omitted, the main root of the zipfs system is used. The \fIinZipfs\fR argument is a an optional boolean -which controls whether to fully canonicalise the name; it defaults to true. +which controls whether to fully canonicalize the name; it defaults to true. .\" METHOD: exists .TP \fBzipfs exists\fI filename\fR @@ -204,12 +204,12 @@ that \fBmain.tcl\fR after mounting the ZIP archive, and will \fBexit\fR once that script has been executed. .PP \fBNote:\fR \fBtclsh\fR and \fBwish\fR can be built using either -dynamic binding or static binding of the core implemenation +dynamic binding or static binding of the core implementation libraries. With a dynamic binding, the base application Tcl_Library contents are attached to the \fBlibtcl\fR and \fBlibtk\fR shared library, respectively. With a static binding, the Tcl_Library contents, etc., are attached to the application, \fBtclsh\fR or -\fBwish\fR. When using \fBmkimg\fR with a staticly built tclsh, it is +\fBwish\fR. When using \fBmkimg\fR with a statically built tclsh, it is the user's responsibility to preserve the attached archive by first extracting it to a temporary location, and then add whatever additional files desired, before creating and attaching the new -- cgit v0.12 From 1019fc7dc38c97beab50b4151eaccf9de1174683 Mon Sep 17 00:00:00 2001 From: "jan.nijtmans" Date: Mon, 27 May 2024 11:04:53 +0000 Subject: Eliminate TclPrintByteCodeObj()'s 'interp' argument, which is not used. --- generic/tclAssembly.c | 7 +---- generic/tclCompile.c | 34 ++++++++------------- generic/tclCompile.h | 5 ++-- generic/tclDisassemble.c | 78 +++++++++++++++++++++++++----------------------- generic/tclExecute.c | 29 ++++++++---------- 5 files changed, 68 insertions(+), 85 deletions(-) diff --git a/generic/tclAssembly.c b/generic/tclAssembly.c index 61eb319..e596a87 100644 --- a/generic/tclAssembly.c +++ b/generic/tclAssembly.c @@ -923,12 +923,7 @@ CompileAssembleObj( * Report on what the assembler did. */ -#ifdef TCL_COMPILE_DEBUG - if (tclTraceCompile >= 2) { - TclPrintByteCodeObj(interp, objPtr); - fflush(stdout); - } -#endif /* TCL_COMPILE_DEBUG */ + TclDebugPrintByteCodeObj(objPtr); return codePtr; } diff --git a/generic/tclCompile.c b/generic/tclCompile.c index 3e77231..1adb4d7 100644 --- a/generic/tclCompile.c +++ b/generic/tclCompile.c @@ -415,17 +415,17 @@ InstructionDesc const tclInstructionTable[] = { * stktop; op1 is 1 for errors on problems, 0 otherwise */ {"dictExpand", 1, -1, 0, {OPERAND_NONE}}, - /* Probe into a dict and extract it (or a subdict of it) into - * variables with matched names. Produces list of keys bound as - * result. Part of [dict with]. + /* Probe into a dict and extract it (or a subdict of it) into + * variables with matched names. Produces list of keys bound as + * result. Part of [dict with]. * Stack: ... dict path => ... keyList */ {"dictRecombineStk", 1, -3, 0, {OPERAND_NONE}}, - /* Map variable contents back into a dictionary in a variable. Part of - * [dict with]. + /* Map variable contents back into a dictionary in a variable. Part of + * [dict with]. * Stack: ... dictVarName path keyList => ... */ {"dictRecombineImm", 5, -2, 1, {OPERAND_LVT4}}, - /* Map variable contents back into a dictionary in the local variable - * indicated by the LVT index. Part of [dict with]. + /* Map variable contents back into a dictionary in the local variable + * indicated by the LVT index. Part of [dict with]. * Stack: ... path keyList => ... */ {"dictExists", 5, INT_MIN, 1, {OPERAND_UINT4}}, /* The top op4 words (min 1) are a key path into the dictionary just @@ -655,7 +655,7 @@ InstructionDesc const tclInstructionTable[] = { * Stack: ... varName list => ... listVarContents */ {"clockRead", 2, +1, 1, {OPERAND_UINT1}}, - /* Read clock out to the stack. Operand is which clock to read + /* Read clock out to the stack. Operand is which clock to read * 0=clicks, 1=microseconds, 2=milliseconds, 3=seconds. * Stack: ... => ... time */ @@ -896,12 +896,7 @@ TclSetByteCodeFromAny( if (result == TCL_OK) { (void) TclInitByteCodeObj(objPtr, &tclByteCodeType, &compEnv); -#ifdef TCL_COMPILE_DEBUG - if (tclTraceCompile >= 2) { - TclPrintByteCodeObj(interp, objPtr); - fflush(stdout); - } -#endif /* TCL_COMPILE_DEBUG */ + TclDebugPrintByteCodeObj(objPtr); } TclFreeCompileEnv(&compEnv); @@ -1361,12 +1356,7 @@ CompileSubstObj( codePtr->localCachePtr = iPtr->varFramePtr->localCachePtr; codePtr->localCachePtr->refCount++; } -#ifdef TCL_COMPILE_DEBUG - if (tclTraceCompile >= 2) { - TclPrintByteCodeObj(interp, objPtr); - fflush(stdout); - } -#endif /* TCL_COMPILE_DEBUG */ + TclDebugPrintByteCodeObj(objPtr); } return codePtr; } @@ -2489,7 +2479,7 @@ TclCompileTokens( if (numCL >= maxNumCL) { maxNumCL *= 2; clPosition = (int *)ckrealloc(clPosition, - maxNumCL * sizeof(int)); + maxNumCL * sizeof(int)); } clPosition[numCL] = clPos; numCL ++; @@ -2799,7 +2789,7 @@ PreventCycle( * * NOTE: [Bugs 3392070, 3389764] We make a copy based completely * on the string value, and do not call Tcl_DuplicateObj() so we - * can be sure we do not have any lingering cycles hiding in + * can be sure we do not have any lingering cycles hiding in * the internalrep. */ int numBytes; diff --git a/generic/tclCompile.h b/generic/tclCompile.h index 16bc972..d577b6a 100644 --- a/generic/tclCompile.h +++ b/generic/tclCompile.h @@ -1175,8 +1175,9 @@ MODULE_SCOPE Tcl_Size TclLocalScalarFromToken(Tcl_Token *tokenPtr, CompileEnv *envPtr); MODULE_SCOPE void TclOptimizeBytecode(void *envPtr); #ifdef TCL_COMPILE_DEBUG -MODULE_SCOPE void TclPrintByteCodeObj(Tcl_Interp *interp, - Tcl_Obj *objPtr); +MODULE_SCOPE void TclDebugPrintByteCodeObj(Tcl_Obj *objPtr); +#else +#define TclDebugPrintByteCodeObj(objPtr) (void)(objPtr) #endif MODULE_SCOPE int TclPrintInstruction(ByteCode *codePtr, const unsigned char *pc); diff --git a/generic/tclDisassemble.c b/generic/tclDisassemble.c index 304fa30..b6cd9b5 100644 --- a/generic/tclDisassemble.c +++ b/generic/tclDisassemble.c @@ -114,7 +114,7 @@ GetLocationInformation( /* *---------------------------------------------------------------------- * - * TclPrintByteCodeObj -- + * TclDebugPrintByteCodeObj -- * * This procedure prints ("disassembles") the instructions of a bytecode * object to stdout. @@ -129,14 +129,16 @@ GetLocationInformation( */ void -TclPrintByteCodeObj( - TCL_UNUSED(Tcl_Interp *), /* Stuck with this in internal stubs */ +TclDebugPrintByteCodeObj( Tcl_Obj *objPtr) /* The bytecode object to disassemble. */ { - Tcl_Obj *bufPtr = DisassembleByteCodeObj(objPtr); + if (tclTraceCompile >= 2) { + Tcl_Obj *bufPtr = DisassembleByteCodeObj(objPtr); - fprintf(stdout, "\n%s", TclGetString(bufPtr)); - Tcl_DecrRefCount(bufPtr); + fprintf(stdout, "\n%s", TclGetString(bufPtr)); + Tcl_DecrRefCount(bufPtr); + fflush(stdout); + } } /* @@ -703,8 +705,8 @@ TclGetInnerContext( case INST_TRY_CVT_TO_NUMERIC: case INST_EXPAND_STKTOP: case INST_EXPR_STK: - objc = 1; - break; + objc = 1; + break; case INST_LIST_IN: case INST_LIST_NOT_IN: /* Basic list containment operators. */ @@ -731,22 +733,22 @@ TclGetInnerContext( case INST_SUB: case INST_DIV: case INST_MULT: - objc = 2; - break; + objc = 2; + break; case INST_RETURN_STK: - /* early pop. TODO: dig out opt dict too :/ */ - objc = 1; - break; + /* early pop. TODO: dig out opt dict too :/ */ + objc = 1; + break; case INST_SYNTAX: case INST_RETURN_IMM: - objc = 2; - break; + objc = 2; + break; case INST_INVOKE_STK4: objc = TclGetUInt4AtPtr(pc+1); - break; + break; case INST_INVOKE_STK1: objc = TclGetUInt1AtPtr(pc+1); @@ -755,37 +757,37 @@ TclGetInnerContext( result = iPtr->innerContext; if (Tcl_IsShared(result)) { - Tcl_DecrRefCount(result); - iPtr->innerContext = result = Tcl_NewListObj(objc + 1, NULL); - Tcl_IncrRefCount(result); + Tcl_DecrRefCount(result); + iPtr->innerContext = result = Tcl_NewListObj(objc + 1, NULL); + Tcl_IncrRefCount(result); } else { - Tcl_Size len; + Tcl_Size len; - /* - * Reset while keeping the list internalrep as much as possible. - */ + /* + * Reset while keeping the list internalrep as much as possible. + */ TclListObjLength(interp, result, &len); - Tcl_ListObjReplace(interp, result, 0, len, 0, NULL); + Tcl_ListObjReplace(interp, result, 0, len, 0, NULL); } Tcl_ListObjAppendElement(NULL, result, TclNewInstNameObj(*pc)); for (; objc>0 ; objc--) { - Tcl_Obj *objPtr; + Tcl_Obj *objPtr; - objPtr = tosPtr[1 - objc]; - if (!objPtr) { - Tcl_Panic("InnerContext: bad tos -- appending null object"); - } - if ((objPtr->refCount<=0) + objPtr = tosPtr[1 - objc]; + if (!objPtr) { + Tcl_Panic("InnerContext: bad tos -- appending null object"); + } + if ((objPtr->refCount<=0) #ifdef TCL_MEM_DEBUG - || (objPtr->refCount==0x61616161) + || (objPtr->refCount==0x61616161) #endif - ) { - Tcl_Panic("InnerContext: bad tos -- appending freed object %p", - objPtr); - } - Tcl_ListObjAppendElement(NULL, result, objPtr); + ) { + Tcl_Panic("InnerContext: bad tos -- appending freed object %p", + objPtr); + } + Tcl_ListObjAppendElement(NULL, result, objPtr); } return result; @@ -836,7 +838,7 @@ UpdateStringOfInstName( if (inst > LAST_INST_OPCODE) { dst = Tcl_InitStringRep(objPtr, NULL, TCL_INTEGER_SPACE + 5); TclOOM(dst, TCL_INTEGER_SPACE + 5); - snprintf(dst, TCL_INTEGER_SPACE + 5, "inst_%" TCL_Z_MODIFIER "u", inst); + snprintf(dst, TCL_INTEGER_SPACE + 5, "inst_%" TCL_Z_MODIFIER "u", inst); (void) Tcl_InitStringRep(objPtr, NULL, strlen(dst)); } else { const char *s = tclInstructionTable[inst].name; @@ -1229,7 +1231,7 @@ DisassembleByteCodeAsDicts( TclDictPut(NULL, description, "commands", commands); TclDictPut(NULL, description, "script", Tcl_NewStringObj(codePtr->source, codePtr->numSrcBytes)); - TclDictPut(NULL, description, "namespace", + TclDictPut(NULL, description, "namespace", Tcl_NewStringObj(codePtr->nsPtr->fullName, -1)); TclDictPut(NULL, description, "stackdepth", Tcl_NewWideIntObj(codePtr->maxStackDepth)); diff --git a/generic/tclExecute.c b/generic/tclExecute.c index 380a0a3..cdecc08 100644 --- a/generic/tclExecute.c +++ b/generic/tclExecute.c @@ -1520,12 +1520,7 @@ CompileExprObj( codePtr->localCachePtr = iPtr->varFramePtr->localCachePtr; codePtr->localCachePtr->refCount++; } -#ifdef TCL_COMPILE_DEBUG - if (tclTraceCompile == 2) { - TclPrintByteCodeObj(interp, objPtr); - fflush(stdout); - } -#endif /* TCL_COMPILE_DEBUG */ + TclDebugPrintByteCodeObj(objPtr); } return codePtr; } @@ -2082,8 +2077,8 @@ TEBCresume( Tcl_Obj **tosPtr; /* Cached pointer to top of evaluation * stack. */ const unsigned char *pc = (const unsigned char *)data[1]; - /* The current program counter. */ - unsigned char inst; /* The currently running instruction */ + /* The current program counter. */ + unsigned char inst; /* The currently running instruction */ /* * Transfer variables - needed only between opcodes, but not while @@ -2092,7 +2087,7 @@ TEBCresume( int cleanup = PTR2INT(data[2]); Tcl_Obj *objResultPtr; - int checkInterp = 0; /* Indicates when a check of interp readyness + int checkInterp = 0; /* Indicates when a check of interp readyness * is necessary. Set by CACHE_STACK_INFO() */ /* @@ -2146,7 +2141,7 @@ TEBCresume( goto cleanup0; } else { - /* resume from invocation */ + /* resume from invocation */ CACHE_STACK_INFO(); NRE_ASSERT(iPtr->cmdFramePtr == bcFramePtr); @@ -2446,7 +2441,7 @@ TEBCresume( } else { fprintf(stdout, "%" TCL_SIZE_MODIFIER "d: (%" TCL_T_MODIFIER "d) yielding value \"%.30s\"\n", iPtr->numLevels, (pc - codePtr->codeStart), - Tcl_GetString(OBJ_AT_TOS)); + TclGetString(OBJ_AT_TOS)); } fflush(stdout); } @@ -6687,7 +6682,7 @@ TEBCresume( numVars = varListPtr->numVars; listVarPtr = LOCAL(listTmpIndex); - /* Do not use TclListObjCopy here - shimmers arithseries to list */ + /* Do not use TclListObjCopy here - shimmers arithseries to list */ listPtr = Tcl_DuplicateObj(listVarPtr->value.objPtr); TclListObjGetElements(interp, listPtr, &listLen, &elements); @@ -9440,21 +9435,21 @@ TclGetSourceFromFrame( Tcl_Obj *const objv[]) { if (cfPtr == NULL) { - return Tcl_NewListObj(objc, objv); + return Tcl_NewListObj(objc, objv); } if (cfPtr->cmdObj == NULL) { - if (cfPtr->cmd == NULL) { + if (cfPtr->cmd == NULL) { ByteCode *codePtr = (ByteCode *) cfPtr->data.tebc.codePtr; - cfPtr->cmd = GetSrcInfoForPc((unsigned char *) + cfPtr->cmd = GetSrcInfoForPc((unsigned char *) cfPtr->data.tebc.pc, codePtr, &cfPtr->len, NULL, NULL); - } + } if (cfPtr->cmd) { cfPtr->cmdObj = Tcl_NewStringObj(cfPtr->cmd, cfPtr->len); } else { cfPtr->cmdObj = Tcl_NewListObj(objc, objv); } - Tcl_IncrRefCount(cfPtr->cmdObj); + Tcl_IncrRefCount(cfPtr->cmdObj); } return cfPtr->cmdObj; } -- cgit v0.12 From db021e3e310e397f652d3597f5335868957ce8ca Mon Sep 17 00:00:00 2001 From: "jan.nijtmans" Date: Mon, 27 May 2024 12:52:36 +0000 Subject: Missing ',' between "INDEX" and "OUTOFRANGE" --- generic/tclCmdIL.c | 9 +++------ generic/tclListObj.c | 9 +++------ generic/tclUtil.c | 6 ++---- 3 files changed, 8 insertions(+), 16 deletions(-) diff --git a/generic/tclCmdIL.c b/generic/tclCmdIL.c index 37c9822..83320cd 100644 --- a/generic/tclCmdIL.c +++ b/generic/tclCmdIL.c @@ -2638,8 +2638,7 @@ Tcl_LpopObjCmd( /* empty list, throw the same error as with index "end" */ Tcl_SetObjResult(interp, Tcl_NewStringObj( "index \"end\" out of range", -1)); - Tcl_SetErrorCode(interp, "TCL", "VALUE", "INDEX" - "OUTOFRANGE", (char *)NULL); + Tcl_SetErrorCode(interp, "TCL", "VALUE", "INDEX", "OUTOFRANGE", (char *)NULL); return TCL_ERROR; } @@ -3497,8 +3496,7 @@ Tcl_LsearchObjCmd( Tcl_SetObjResult(interp, Tcl_ObjPrintf( "index \"%s\" out of range", TclGetString(indices[j]))); - Tcl_SetErrorCode(interp, "TCL", "VALUE", "INDEX" - "OUTOFRANGE", (char *)NULL); + Tcl_SetErrorCode(interp, "TCL", "VALUE", "INDEX", "OUTOFRANGE", (char *)NULL); result = TCL_ERROR; } if (result == TCL_ERROR) { @@ -4640,8 +4638,7 @@ Tcl_LsortObjCmd( Tcl_SetObjResult(interp, Tcl_ObjPrintf( "index \"%s\" out of range", TclGetString(indexv[j]))); - Tcl_SetErrorCode(interp, "TCL", "VALUE", "INDEX" - "OUTOFRANGE", (char *)NULL); + Tcl_SetErrorCode(interp, "TCL", "VALUE", "INDEX", "OUTOFRANGE", (char *)NULL); result = TCL_ERROR; } if (result == TCL_ERROR) { diff --git a/generic/tclListObj.c b/generic/tclListObj.c index 1bb3587..a8e16d4 100644 --- a/generic/tclListObj.c +++ b/generic/tclListObj.c @@ -2970,10 +2970,8 @@ TclLsetFlat( /* ...the index points outside the sublist. */ if (interp != NULL) { Tcl_SetObjResult(interp, Tcl_ObjPrintf( - "index \"%s\" out of range", - Tcl_GetString(indexArray[-1]))); - Tcl_SetErrorCode(interp, - "TCL", "VALUE", "INDEX" "OUTOFRANGE", (void *)NULL); + "index \"%s\" out of range", TclGetString(indexArray[-1]))); + Tcl_SetErrorCode(interp, "TCL", "VALUE", "INDEX", "OUTOFRANGE", (char *)NULL); } result = TCL_ERROR; break; @@ -3163,8 +3161,7 @@ TclListObjSetElement( if (interp != NULL) { Tcl_SetObjResult(interp, Tcl_ObjPrintf( "index \"%" TCL_SIZE_MODIFIER "d\" out of range", index)); - Tcl_SetErrorCode(interp, "TCL", "VALUE", "INDEX", - "OUTOFRANGE", (void *)NULL); + Tcl_SetErrorCode(interp, "TCL", "VALUE", "INDEX", "OUTOFRANGE", (char *)NULL); } return TCL_ERROR; } diff --git a/generic/tclUtil.c b/generic/tclUtil.c index e2c96a9..c2fa64f 100644 --- a/generic/tclUtil.c +++ b/generic/tclUtil.c @@ -3921,10 +3921,8 @@ TclIndexEncode( rangeerror: if (interp) { - Tcl_SetObjResult( - interp, - Tcl_ObjPrintf("index \"%s\" out of range", TclGetString(objPtr))); - Tcl_SetErrorCode(interp, "TCL", "VALUE", "INDEX", "OUTOFRANGE", (void *)NULL); + Tcl_SetObjResult(interp, Tcl_ObjPrintf("index \"%s\" out of range", TclGetString(objPtr))); + Tcl_SetErrorCode(interp, "TCL", "VALUE", "INDEX", "OUTOFRANGE", (char *)NULL); } return TCL_ERROR; } -- cgit v0.12 From 269c56a9698699f195e90fd7c25d82838befa8bb Mon Sep 17 00:00:00 2001 From: sebres Date: Mon, 27 May 2024 19:26:46 +0000 Subject: fix for [e3f4a8b78dec4bdb]: don't swallow limit errors in further invocations of EvalObjvCore (e. g. direct invocation or NRE, Tcl_EvalObjv, Tcl_EvalObjEx, TclNREvalObjEx, etc); partially reverts [b740e2abbd44c7d0] --- generic/tclBasic.c | 4 ++++ generic/tclInterp.c | 13 ------------- 2 files changed, 4 insertions(+), 13 deletions(-) diff --git a/generic/tclBasic.c b/generic/tclBasic.c index c462278..b66c1cc 100644 --- a/generic/tclBasic.c +++ b/generic/tclBasic.c @@ -4330,6 +4330,10 @@ EvalObjvCore( } if (TclLimitExceeded(iPtr->limit)) { + /* generate error message if not yet already logged at this stage */ + if (!(iPtr->flags & ERR_ALREADY_LOGGED)) { + Tcl_LimitCheck(interp); + } return TCL_ERROR; } diff --git a/generic/tclInterp.c b/generic/tclInterp.c index 2c0035c..ad06293 100644 --- a/generic/tclInterp.c +++ b/generic/tclInterp.c @@ -2795,18 +2795,6 @@ ChildEval( Tcl_Preserve(childInterp); Tcl_AllowExceptions(childInterp); - /* - * If we're transferring to another interpreter, check it's limits first. - * It's much more reliable to do that now rather than waiting for the - * intermittent checks done during running; the slight performance hit for - * a cross-interp call is not a big problem. [Bug e3f4a8b78d] - */ - - if (interp != childInterp && Tcl_LimitCheck(childInterp) != TCL_OK) { - result = TCL_ERROR; - goto done; - } - if (objc == 1) { /* * TIP #280: Make actual argument location available to eval'd script. @@ -2825,7 +2813,6 @@ ChildEval( result = Tcl_EvalObjEx(childInterp, objPtr, 0); Tcl_DecrRefCount(objPtr); } - done: Tcl_TransferResult(childInterp, result, interp); Tcl_Release(childInterp); -- cgit v0.12 From a6bfc24621de4e3215e4d120728991128a7ba534 Mon Sep 17 00:00:00 2001 From: sebres Date: Mon, 27 May 2024 20:09:13 +0000 Subject: speedup interp.test a bit: switch to 50ms-based time limits (instead of 1sec); more tests for interp-34.14 covering [e3f4a8b78d] (direct/NRE) --- tests/interp.test | 76 ++++++++++++++++++++++++++++++------------------------- 1 file changed, 41 insertions(+), 35 deletions(-) diff --git a/tests/interp.test b/tests/interp.test index 31c27ac..24ffb1b 100644 --- a/tests/interp.test +++ b/tests/interp.test @@ -22,6 +22,12 @@ testConstraint testinterpdelete [llength [info commands testinterpdelete]] set hidden_cmds {cd encoding exec exit fconfigure file glob load open pwd socket source tcl:encoding:dirs tcl:file:atime tcl:file:attributes tcl:file:copy tcl:file:delete tcl:file:dirname tcl:file:executable tcl:file:exists tcl:file:extension tcl:file:isdirectory tcl:file:isfile tcl:file:link tcl:file:lstat tcl:file:mkdir tcl:file:mtime tcl:file:nativename tcl:file:normalize tcl:file:owned tcl:file:readable tcl:file:readlink tcl:file:rename tcl:file:rootname tcl:file:size tcl:file:stat tcl:file:tail tcl:file:tempfile tcl:file:type tcl:file:volumes tcl:file:writable unload} +proc _ms_limit_args {ms {t0 {}}} { + if {$t0 eq {}} { set t0 [clock milliseconds] } + incr t0 $ms + list -seconds [expr {$t0 / 1000}] -milliseconds [expr {$t0 % 1000}] +} + foreach i [interp children] { interp delete $i } @@ -3155,7 +3161,7 @@ test interp-34.3 {basic test of limits - pure bytecode loop} -body { } } # We use a time limit here; command limits don't trap this case - $i limit time -seconds [expr {[clock seconds]+2}] + $i limit time {*}[_ms_limit_args 50] $i eval foobar } -returnCodes error -result {time limit exceeded} -cleanup { interp delete $i @@ -3171,7 +3177,7 @@ test interp-34.3.1 {basic test of limits - pure inside-command loop} -body { } } # We use a time limit here; command limits don't trap this case - $i limit time -seconds [expr {[clock seconds] + 2}] + $i limit time {*}[_ms_limit_args 50] $i eval foobar } -returnCodes error -result {time limit exceeded} -cleanup { interp delete $i @@ -3304,7 +3310,7 @@ test interp-34.7 {limits with callbacks: deleting the handler interp} -setup { # Bug 1085023 test interp-34.8 {time limits trigger in vwaits} -body { set i [interp create] - interp limit $i time -seconds [expr {[clock seconds] + 1}] -granularity 1 + interp limit $i time {*}[_ms_limit_args 50] -granularity 1 $i eval { set x {} vwait x @@ -3314,25 +3320,24 @@ test interp-34.8 {time limits trigger in vwaits} -body { } -returnCodes error -result {limit exceeded} test interp-34.9 {time limits trigger in blocking after} { set i [interp create] - set t0 [clock seconds] - interp limit $i time -seconds [expr {$t0 + 1}] -granularity 1 + set t0 [clock milliseconds] + interp limit $i time {*}[_ms_limit_args 50 $t0] -granularity 1 set code [catch { $i eval {after 10000} } msg] - set t1 [clock seconds] + set t1 [clock milliseconds] interp delete $i - list $code $msg [expr {($t1-$t0) < 3 ? "OK" : $t1-$t0}] + list $code $msg [expr {($t1-$t0) < 1000 ? "OK" : $t1-$t0}] } {1 {time limit exceeded} OK} test interp-34.10 {time limits trigger in vwaits: Bug 1221395} -body { set i [interp create] - # Assume someone hasn't set the clock to early 1970! - $i limit time -seconds [expr {[clock seconds] + 1}] -granularity 4 interp alias $i log {} lappend result set result {} + $i limit time {*}[_ms_limit_args 50] -granularity 4 catch { $i eval { log 1 - after 1000 + after 100 log 2 } } msg @@ -3340,10 +3345,10 @@ test interp-34.10 {time limits trigger in vwaits: Bug 1221395} -body { lappend result $msg } -result {1 {time limit exceeded}} test interp-34.11 {time limit extension in callbacks} -setup { - proc cb1 {i t} { + proc cb1 {i args} { global result lappend result cb1 - $i limit time -seconds $t -command cb2 + $i limit time {*}[_ms_limit_args {*}$args] -command cb2 } proc cb2 {} { global result @@ -3351,9 +3356,9 @@ test interp-34.11 {time limit extension in callbacks} -setup { } } -body { set i [interp create] - set t0 [clock seconds] - $i limit time -seconds [expr {$t0 + 1}] -granularity 1 \ - -command "cb1 $i [expr {$t0 + 2}]" + set t0 [clock milliseconds] + $i limit time {*}[_ms_limit_args 50 $t0] \ + -command "cb1 $i 100 $t0" set ::result {} lappend ::result [catch { $i eval { @@ -3362,8 +3367,8 @@ test interp-34.11 {time limit extension in callbacks} -setup { } } } msg] $msg - set t1 [clock seconds] - lappend ::result [expr {$t1-$t0>=2 ? "ok" : "$t0,$t1"}] + set t1 [clock milliseconds] + lappend ::result [expr {$t1-$t0>=100 ? "ok" : "$t0,$t1"}] interp delete $i return $::result } -result {cb1 cb2 1 {time limit exceeded} ok} -cleanup { @@ -3371,27 +3376,27 @@ test interp-34.11 {time limit extension in callbacks} -setup { rename cb2 {} } test interp-34.12 {time limit extension in callbacks} -setup { - proc cb1 {i} { + proc cb1 {i t0} { global result times lappend result cb1 set times [lassign $times t] - $i limit time -seconds $t + $i limit time {*}[_ms_limit_args $t $t0] } } -body { set i [interp create] - set t0 [clock seconds] - set ::times "[expr {$t0 + 2}] [expr {$t0 + 100}]" - $i limit time -seconds [expr {$t0 + 1}] -granularity 1 -command "cb1 $i" + set t0 [clock milliseconds] + set ::times {100 10000} + $i limit time {*}[_ms_limit_args 50] -granularity 1 -command "cb1 $i $t0" set ::result {} lappend ::result [catch { $i eval { - for {set i 0} {$i<30} {incr i} { - after 100 + for {set i 0} {$i<5} {incr i} { + after 50 } } } msg] $msg - set t1 [clock seconds] - lappend ::result [expr {$t1-$t0>=2 ? "ok" : "$t0,$t1"}] + set t1 [clock milliseconds] + lappend ::result [expr {$t1-$t0>=100 ? "ok" : "$t0,$t1"}] interp delete $i return $::result } -result {cb1 cb1 0 {} ok} -cleanup { @@ -3400,7 +3405,7 @@ test interp-34.12 {time limit extension in callbacks} -setup { test interp-34.13 {time limit granularity and vwait: Bug 2891362} -setup { set i [interp create -safe] } -body { - $i limit time -seconds [clock add [clock seconds] 1 second] + $i limit time {*}[_ms_limit_args 50] $i eval { after 2000 set x timeout vwait x @@ -3413,16 +3418,16 @@ test interp-34.14 {[Bug e3f4a8b78d]: interp limit and interp eval} -setup { set i [interp create] set result {} } -body { - $i limit command -value [$i eval {info cmdcount}] - catch {$i eval [list expr 1+3]} msg - lappend result $msg - catch {$i eval [list expr 1+3]} msg - lappend result $msg - catch {interp eval $i [list expr 1+3]} msg - lappend result $msg + $i limit command -value [$i eval {info cmdcount}] -granularity 1 + lappend result [catch {$i eval [list expr 1+3]} msg] $msg + lappend result [catch {$i eval [list expr 1+3]} msg] $msg + lappend result [catch {$i eval {set cmd expr; $cmd 1+3}} msg] $msg + lappend result [catch {$i eval {expr 1+3}} msg] $msg + lappend result [catch {$i eval expr 1+3} msg] $msg + lappend result [catch {interp eval $i [list expr 1+3]} msg] $msg } -cleanup { interp delete $i -} -result {{command count limit exceeded} {command count limit exceeded} {command count limit exceeded}} +} -result [lrepeat 6 1 {command count limit exceeded}] test interp-35.1 {interp limit syntax} -body { interp limit @@ -3684,6 +3689,7 @@ unset -nocomplain hidden_cmds foreach i [interp children] { interp delete $i } +rename _ms_limit_args {} ::tcltest::cleanupTests return -- cgit v0.12 From 34acc36d873d6b1ec6a8cd505af4491dfad7fd57 Mon Sep 17 00:00:00 2001 From: "jan.nijtmans" Date: Mon, 27 May 2024 20:23:37 +0000 Subject: Eliminate TclPrintByteCodeObj()'s 'interp' argument, which is not used --- generic/tclAssembly.c | 66 +++++++++++++++++++---------------------- generic/tclCompile.c | 16 ++-------- generic/tclCompile.h | 5 ++-- generic/tclDisassemble.c | 76 +++++++++++++++++++++++------------------------- generic/tclExecute.c | 57 +++++++++++++++++------------------- 5 files changed, 99 insertions(+), 121 deletions(-) diff --git a/generic/tclAssembly.c b/generic/tclAssembly.c index fa59db0..a871f05 100644 --- a/generic/tclAssembly.c +++ b/generic/tclAssembly.c @@ -6,8 +6,8 @@ * This file contains the procedures that convert Tcl Assembly Language (TAL) * to a sequence of bytecode instructions for the Tcl execution engine. * - * Copyright (c) 2010 by Ozgur Dogan Ugurlu. - * Copyright (c) 2010 by Kevin B. Kenny. + * Copyright (c) 2010 Ozgur Dogan Ugurlu. + * Copyright (c) 2010 Kevin B. Kenny. * * See the file "license.terms" for information on usage and redistribution of * this file, and for a DISCLAIMER OF ALL WARRANTIES. @@ -271,15 +271,14 @@ static void CompileEmbeddedScript(AssemblyEnv*, Tcl_Token*, const TalInstDesc*); static int DefineLabel(AssemblyEnv* envPtr, const char* label); static void DeleteMirrorJumpTable(JumptableInfo* jtPtr); -static void DupAssembleCodeInternalRep(Tcl_Obj* src, - Tcl_Obj* dest); +static Tcl_DupInternalRepProc DupAssembleCodeInternalRep; static void FillInJumpOffsets(AssemblyEnv*); static int CreateMirrorJumpTable(AssemblyEnv* assemEnvPtr, Tcl_Obj* jumpTable); static int FindLocalVar(AssemblyEnv* envPtr, Tcl_Token** tokenPtrPtr); static int FinishAssembly(AssemblyEnv*); -static void FreeAssembleCodeInternalRep(Tcl_Obj *objPtr); +static Tcl_FreeInternalRepProc FreeAssembleCodeInternalRep; static void FreeAssemblyEnv(AssemblyEnv*); static int GetBooleanOperand(AssemblyEnv*, Tcl_Token**, int*); static int GetListIndexOperand(AssemblyEnv*, Tcl_Token**, int*); @@ -759,7 +758,7 @@ BBEmitInst1or4( int Tcl_AssembleObjCmd( - ClientData dummy, /* Not used. */ + void *clientData, /* clientData */ Tcl_Interp *interp, /* Current interpreter. */ int objc, /* Number of arguments. */ Tcl_Obj *const objv[]) /* Argument objects. */ @@ -769,12 +768,12 @@ Tcl_AssembleObjCmd( * because there needs to be one in place to execute bytecode. */ - return Tcl_NRCallObjProc(interp, TclNRAssembleObjCmd, dummy, objc, objv); + return Tcl_NRCallObjProc(interp, TclNRAssembleObjCmd, clientData, objc, objv); } int TclNRAssembleObjCmd( - ClientData dummy, /* Not used. */ + void *dummy, /* Not used. */ Tcl_Interp *interp, /* Current interpreter. */ int objc, /* Number of arguments. */ Tcl_Obj *const objv[]) /* Argument objects. */ @@ -912,12 +911,7 @@ CompileAssembleObj( * Report on what the assembler did. */ -#ifdef TCL_COMPILE_DEBUG - if (tclTraceCompile >= 2) { - TclPrintByteCodeObj(interp, objPtr); - fflush(stdout); - } -#endif /* TCL_COMPILE_DEBUG */ + TclDebugPrintByteCodeObj(objPtr); return codePtr; } @@ -1257,7 +1251,7 @@ AssembleOneLine( Tcl_Obj* instNameObj; /* Name of the instruction */ int tblIdx; /* Index in TalInstructionTable of the * instruction */ - enum TalInstType instType; /* Type of the instruction */ + TalInstType instType; /* Type of the instruction */ Tcl_Obj* operand1Obj = NULL; /* First operand to the instruction */ const char* operand1; /* String rep of the operand */ @@ -1377,7 +1371,7 @@ AssembleOneLine( if (opnd < 0 || opnd > 3) { Tcl_SetObjResult(interp, Tcl_NewStringObj("operand must be [0..3]", -1)); - Tcl_SetErrorCode(interp, "TCL", "ASSEM", "OPERAND<0,>3", NULL); + Tcl_SetErrorCode(interp, "TCL", "ASSEM", "OPERAND<0,>3", (char *)NULL); goto cleanup; } BBEmitInstInt1(assemEnvPtr, tblIdx, opnd, opnd); @@ -1617,7 +1611,7 @@ AssembleOneLine( if (assemEnvPtr->flags & TCL_EVAL_DIRECT) { Tcl_SetObjResult(interp, Tcl_NewStringObj("operand must be >=2", -1)); - Tcl_SetErrorCode(interp, "TCL", "ASSEM", "OPERAND>=2", NULL); + Tcl_SetErrorCode(interp, "TCL", "ASSEM", "OPERAND>=2", (char *)NULL); } goto cleanup; } @@ -1983,7 +1977,7 @@ CreateMirrorJumpTable( Tcl_SetObjResult(interp, Tcl_NewStringObj( "jump table must have an even number of list elements", -1)); - Tcl_SetErrorCode(interp, "TCL", "ASSEM", "BADJUMPTABLE", NULL); + Tcl_SetErrorCode(interp, "TCL", "ASSEM", "BADJUMPTABLE", (char *)NULL); } return TCL_ERROR; } @@ -2011,7 +2005,7 @@ CreateMirrorJumpTable( Tcl_SetObjResult(interp, Tcl_ObjPrintf( "duplicate entry in jump table for \"%s\"", TclGetString(objv[i]))); - Tcl_SetErrorCode(interp, "TCL", "ASSEM", "DUPJUMPTABLEENTRY", NULL); + Tcl_SetErrorCode(interp, "TCL", "ASSEM", "DUPJUMPTABLEENTRY", (char *)NULL); DeleteMirrorJumpTable(jtPtr); return TCL_ERROR; } @@ -2096,7 +2090,7 @@ GetNextOperand( if (assemEnvPtr->flags & TCL_EVAL_DIRECT) { Tcl_SetObjResult(interp, Tcl_NewStringObj( "assembly code may not contain substitutions", -1)); - Tcl_SetErrorCode(interp, "TCL", "ASSEM", "NOSUBST", NULL); + Tcl_SetErrorCode(interp, "TCL", "ASSEM", "NOSUBST", (char *)NULL); } return TCL_ERROR; } @@ -2319,7 +2313,7 @@ FindLocalVar( Tcl_SetObjResult(interp, Tcl_NewStringObj( "cannot use this instruction to create a variable" " in a non-proc context", -1)); - Tcl_SetErrorCode(interp, "TCL", "ASSEM", "LVT", NULL); + Tcl_SetErrorCode(interp, "TCL", "ASSEM", "LVT", (char *)NULL); } return -1; } @@ -2354,7 +2348,7 @@ CheckNamespaceQualifiers( if ((*p == ':') && (p[1] == ':')) { Tcl_SetObjResult(interp, Tcl_ObjPrintf( "variable \"%s\" is not local", name)); - Tcl_SetErrorCode(interp, "TCL", "ASSEM", "NONLOCAL", name, NULL); + Tcl_SetErrorCode(interp, "TCL", "ASSEM", "NONLOCAL", name, (char *)NULL); return TCL_ERROR; } } @@ -2390,7 +2384,7 @@ CheckOneByte( if (value < 0 || value > 0xFF) { result = Tcl_NewStringObj("operand does not fit in one byte", -1); Tcl_SetObjResult(interp, result); - Tcl_SetErrorCode(interp, "TCL", "ASSEM", "1BYTE", NULL); + Tcl_SetErrorCode(interp, "TCL", "ASSEM", "1BYTE", (char *)NULL); return TCL_ERROR; } return TCL_OK; @@ -2425,7 +2419,7 @@ CheckSignedOneByte( if (value > 0x7F || value < -0x80) { result = Tcl_NewStringObj("operand does not fit in one byte", -1); Tcl_SetObjResult(interp, result); - Tcl_SetErrorCode(interp, "TCL", "ASSEM", "1BYTE", NULL); + Tcl_SetErrorCode(interp, "TCL", "ASSEM", "1BYTE", (char *)NULL); return TCL_ERROR; } return TCL_OK; @@ -2458,7 +2452,7 @@ CheckNonNegative( if (value < 0) { result = Tcl_NewStringObj("operand must be nonnegative", -1); Tcl_SetObjResult(interp, result); - Tcl_SetErrorCode(interp, "TCL", "ASSEM", "NONNEGATIVE", NULL); + Tcl_SetErrorCode(interp, "TCL", "ASSEM", "NONNEGATIVE", (char *)NULL); return TCL_ERROR; } return TCL_OK; @@ -2491,7 +2485,7 @@ CheckStrictlyPositive( if (value <= 0) { result = Tcl_NewStringObj("operand must be positive", -1); Tcl_SetObjResult(interp, result); - Tcl_SetErrorCode(interp, "TCL", "ASSEM", "POSITIVE", NULL); + Tcl_SetErrorCode(interp, "TCL", "ASSEM", "POSITIVE", (char *)NULL); return TCL_ERROR; } return TCL_OK; @@ -2543,7 +2537,7 @@ DefineLabel( Tcl_SetObjResult(interp, Tcl_ObjPrintf( "duplicate definition of label \"%s\"", labelName)); Tcl_SetErrorCode(interp, "TCL", "ASSEM", "DUPLABEL", labelName, - NULL); + (char *)NULL); } return TCL_ERROR; } @@ -2944,7 +2938,7 @@ ReportUndefinedLabel( Tcl_SetObjResult(interp, Tcl_ObjPrintf( "undefined label \"%s\"", TclGetString(jumpTarget))); Tcl_SetErrorCode(interp, "TCL", "ASSEM", "NOLABEL", - TclGetString(jumpTarget), NULL); + TclGetString(jumpTarget), (char *)NULL); Tcl_SetErrorLine(interp, bbPtr->jumpLine); } } @@ -3229,7 +3223,7 @@ CheckNonThrowingBlock( "a context where an exception has been " "caught and not disposed of.", tclInstructionTable[opcode].name)); - Tcl_SetErrorCode(interp, "TCL", "ASSEM", "BADTHROW", NULL); + Tcl_SetErrorCode(interp, "TCL", "ASSEM", "BADTHROW", (char *)NULL); AddBasicBlockRangeToErrorInfo(assemEnvPtr, blockPtr); } return TCL_ERROR; @@ -3409,7 +3403,7 @@ StackCheckBasicBlock( */ Tcl_SetErrorLine(interp, blockPtr->startLine); - Tcl_SetErrorCode(interp, "TCL", "ASSEM", "BADSTACK", NULL); + Tcl_SetErrorCode(interp, "TCL", "ASSEM", "BADSTACK", (char *)NULL); } return TCL_ERROR; } @@ -3432,7 +3426,7 @@ StackCheckBasicBlock( if (initialStackDepth + blockPtr->minStackDepth < 0) { if (assemEnvPtr->flags & TCL_EVAL_DIRECT) { Tcl_SetObjResult(interp, Tcl_NewStringObj("stack underflow", -1)); - Tcl_SetErrorCode(interp, "TCL", "ASSEM", "BADSTACK", NULL); + Tcl_SetErrorCode(interp, "TCL", "ASSEM", "BADSTACK", (char *)NULL); AddBasicBlockRangeToErrorInfo(assemEnvPtr, blockPtr); Tcl_SetErrorLine(interp, blockPtr->startLine); } @@ -3451,7 +3445,7 @@ StackCheckBasicBlock( if (assemEnvPtr->flags & TCL_EVAL_DIRECT) { Tcl_SetObjResult(interp, Tcl_NewStringObj( "code pops stack below level of enclosing catch", -1)); - Tcl_SetErrorCode(interp, "TCL", "ASSEM", "BADSTACKINCATCH", NULL); + Tcl_SetErrorCode(interp, "TCL", "ASSEM", "BADSTACKINCATCH", (char *)NULL); AddBasicBlockRangeToErrorInfo(assemEnvPtr, blockPtr); Tcl_SetErrorLine(interp, blockPtr->startLine); } @@ -3579,7 +3573,7 @@ StackCheckExit( Tcl_SetObjResult(interp, Tcl_ObjPrintf( "stack is unbalanced on exit from the code (depth=%d)", depth)); - Tcl_SetErrorCode(interp, "TCL", "ASSEM", "BADSTACK", NULL); + Tcl_SetErrorCode(interp, "TCL", "ASSEM", "BADSTACK", (char *)NULL); } return TCL_ERROR; } @@ -3724,7 +3718,7 @@ ProcessCatchesInBasicBlock( "execution reaches an instruction in inconsistent " "exception contexts", -1)); Tcl_SetErrorLine(interp, bbPtr->startLine); - Tcl_SetErrorCode(interp, "TCL", "ASSEM", "BADCATCH", NULL); + Tcl_SetErrorCode(interp, "TCL", "ASSEM", "BADCATCH", (char *)NULL); } return TCL_ERROR; } @@ -3783,7 +3777,7 @@ ProcessCatchesInBasicBlock( Tcl_SetObjResult(interp, Tcl_NewStringObj( "endCatch without a corresponding beginCatch", -1)); Tcl_SetErrorLine(interp, bbPtr->startLine); - Tcl_SetErrorCode(interp, "TCL", "ASSEM", "BADENDCATCH", NULL); + Tcl_SetErrorCode(interp, "TCL", "ASSEM", "BADENDCATCH", (char *)NULL); } return TCL_ERROR; } @@ -3859,7 +3853,7 @@ CheckForUnclosedCatches( "catch still active on exit from assembly code", -1)); Tcl_SetErrorLine(interp, assemEnvPtr->curr_bb->enclosingCatch->startLine); - Tcl_SetErrorCode(interp, "TCL", "ASSEM", "UNCLOSEDCATCH", NULL); + Tcl_SetErrorCode(interp, "TCL", "ASSEM", "UNCLOSEDCATCH", (char *)NULL); } return TCL_ERROR; } diff --git a/generic/tclCompile.c b/generic/tclCompile.c index 76e0efb..3813077 100644 --- a/generic/tclCompile.c +++ b/generic/tclCompile.c @@ -872,12 +872,7 @@ TclSetByteCodeFromAny( if (result == TCL_OK) { TclInitByteCodeObj(objPtr, &compEnv); -#ifdef TCL_COMPILE_DEBUG - if (tclTraceCompile >= 2) { - TclPrintByteCodeObj(interp, objPtr); - fflush(stdout); - } -#endif /* TCL_COMPILE_DEBUG */ + TclDebugPrintByteCodeObj(objPtr); } TclFreeCompileEnv(&compEnv); @@ -1322,12 +1317,7 @@ CompileSubstObj( codePtr->localCachePtr = iPtr->varFramePtr->localCachePtr; codePtr->localCachePtr->refCount++; } -#ifdef TCL_COMPILE_DEBUG - if (tclTraceCompile >= 2) { - TclPrintByteCodeObj(interp, objPtr); - fflush(stdout); - } -#endif /* TCL_COMPILE_DEBUG */ + TclDebugPrintByteCodeObj(objPtr); } return codePtr; } @@ -2137,7 +2127,7 @@ TclCompileScript( if (iPtr->numLevels / 5 > iPtr->maxNestingDepth / 4) { Tcl_SetObjResult(interp, Tcl_NewStringObj( "too many nested compilations (infinite loop?)", -1)); - Tcl_SetErrorCode(interp, "TCL", "LIMIT", "STACK", NULL); + Tcl_SetErrorCode(interp, "TCL", "LIMIT", "STACK", (char *)NULL); TclCompileSyntaxError(interp, envPtr); return; } diff --git a/generic/tclCompile.h b/generic/tclCompile.h index f262b37..44c89bc 100644 --- a/generic/tclCompile.h +++ b/generic/tclCompile.h @@ -1148,8 +1148,9 @@ MODULE_SCOPE int TclLocalScalarFromToken(Tcl_Token *tokenPtr, CompileEnv *envPtr); MODULE_SCOPE void TclOptimizeBytecode(void *envPtr); #ifdef TCL_COMPILE_DEBUG -MODULE_SCOPE void TclPrintByteCodeObj(Tcl_Interp *interp, - Tcl_Obj *objPtr); +MODULE_SCOPE void TclDebugPrintByteCodeObj(Tcl_Obj *objPtr); +#else +#define TclDebugPrintByteCodeObj(objPtr) (void)(objPtr) #endif MODULE_SCOPE int TclPrintInstruction(ByteCode *codePtr, const unsigned char *pc); diff --git a/generic/tclDisassemble.c b/generic/tclDisassemble.c index a66b6a9..51e281b 100644 --- a/generic/tclDisassemble.c +++ b/generic/tclDisassemble.c @@ -5,7 +5,7 @@ * human-readable or Tcl-processable forms. * * Copyright (c) 1996-1998 Sun Microsystems, Inc. - * Copyright (c) 2001 by Kevin B. Kenny. All rights reserved. + * Copyright (c) 2001 Kevin B. Kenny. All rights reserved. * Copyright (c) 2013-2016 Donal K. Fellows. * * See the file "license.terms" for information on usage and redistribution of @@ -21,10 +21,8 @@ * Prototypes for procedures defined later in this file: */ -static Tcl_Obj * DisassembleByteCodeAsDicts(Tcl_Interp *interp, - Tcl_Obj *objPtr); -static Tcl_Obj * DisassembleByteCodeObj(Tcl_Interp *interp, - Tcl_Obj *objPtr); +static Tcl_Obj * DisassembleByteCodeAsDicts(Tcl_Obj *objPtr); +static Tcl_Obj * DisassembleByteCodeObj(Tcl_Obj *objPtr); static int FormatInstruction(ByteCode *codePtr, const unsigned char *pc, Tcl_Obj *bufferObj); static void GetLocationInformation(Proc *procPtr, @@ -107,7 +105,7 @@ GetLocationInformation( /* *---------------------------------------------------------------------- * - * TclPrintByteCodeObj -- + * TclDebugPrintByteCodeObj -- * * This procedure prints ("disassembles") the instructions of a bytecode * object to stdout. @@ -122,14 +120,16 @@ GetLocationInformation( */ void -TclPrintByteCodeObj( - Tcl_Interp *interp, /* Used only for getting location info. */ +TclDebugPrintByteCodeObj( Tcl_Obj *objPtr) /* The bytecode object to disassemble. */ { - Tcl_Obj *bufPtr = DisassembleByteCodeObj(interp, objPtr); + if (tclTraceCompile == 2) { + Tcl_Obj *bufPtr = DisassembleByteCodeObj(objPtr); - fprintf(stdout, "\n%s", TclGetString(bufPtr)); - Tcl_DecrRefCount(bufPtr); + fprintf(stdout, "\n%s", TclGetString(bufPtr)); + Tcl_DecrRefCount(bufPtr); + fflush(stdout); + } } /* @@ -191,7 +191,7 @@ TclPrintObject( char *bytes; int length; - bytes = Tcl_GetStringFromObj(objPtr, &length); + bytes = TclGetStringFromObj(objPtr, &length); TclPrintSource(outFile, bytes, TclMin(length, maxChars)); } @@ -242,14 +242,14 @@ TclPrintSource( static Tcl_Obj * DisassembleByteCodeObj( - Tcl_Interp *interp, Tcl_Obj *objPtr) /* The bytecode object to disassemble. */ { ByteCode *codePtr = BYTECODE(objPtr); unsigned char *codeStart, *codeLimit, *pc; unsigned char *codeDeltaNext, *codeLengthNext; unsigned char *srcDeltaNext, *srcLengthNext; - int codeOffset, codeLen, srcOffset, srcLen, numCmds, delta, i, line; + int codeOffset, codeLen, srcOffset, srcLen, numCmds, delta, line; + int i; Interp *iPtr = (Interp *) *codePtr->interpHandle; Tcl_Obj *bufferObj, *fileObj; char ptrBuf1[20], ptrBuf2[20]; @@ -277,9 +277,9 @@ DisassembleByteCodeObj( PrintSourceToObj(bufferObj, codePtr->source, TclMin(codePtr->numSrcBytes, 55)); GetLocationInformation(codePtr->procPtr, &fileObj, &line); - if (line > -1 && fileObj != NULL) { + if (line >= 0 && fileObj != NULL) { Tcl_AppendPrintfToObj(bufferObj, "\n File \"%s\" Line %d", - Tcl_GetString(fileObj), line); + TclGetString(fileObj), line); } Tcl_AppendPrintfToObj(bufferObj, "\n Cmds %d, src %d, inst %d, litObjs %u, aux %d, stkDepth %u, code/src %.2f\n", @@ -648,7 +648,7 @@ FormatInstruction( int length; Tcl_AppendToObj(bufferObj, "\t# ", -1); - bytes = Tcl_GetStringFromObj(codePtr->objArrayPtr[opnd], &length); + bytes = TclGetStringFromObj(codePtr->objArrayPtr[opnd], &length); PrintSourceToObj(bufferObj, bytes, TclMin(length, 40)); } else if (suffixBuffer[0]) { Tcl_AppendPrintfToObj(bufferObj, "\t# %s", suffixBuffer); @@ -683,7 +683,7 @@ TclGetInnerContext( const unsigned char *pc, Tcl_Obj **tosPtr) { - int objc = 0, off = 0; + int objc = 0; Tcl_Obj *result; Interp *iPtr = (Interp *) interp; @@ -766,7 +766,7 @@ TclGetInnerContext( for (; objc>0 ; objc--) { Tcl_Obj *objPtr; - objPtr = tosPtr[1 - objc + off]; + objPtr = tosPtr[1 - objc]; if (!objPtr) { Tcl_Panic("InnerContext: bad tos -- appending null object"); } @@ -929,8 +929,6 @@ PrintSourceToObj( static Tcl_Obj * DisassembleByteCodeAsDicts( - Tcl_Interp *interp, /* Used for looking up the CmdFrame for the - * procedure, if one exists. */ Tcl_Obj *objPtr) /* The bytecode-holding value to take apart */ { ByteCode *codePtr = BYTECODE(objPtr); @@ -1221,7 +1219,7 @@ DisassembleByteCodeAsDicts( TclDictPut(NULL, description, "commands", commands); TclDictPut(NULL, description, "script", Tcl_NewStringObj(codePtr->source, codePtr->numSrcBytes)); - TclDictPut(NULL, description, "namespace", + TclDictPut(NULL, description, "namespace", Tcl_NewStringObj(codePtr->nsPtr->fullName, -1)); TclDictPut(NULL, description, "stackdepth", Tcl_NewIntObj(codePtr->maxStackDepth)); @@ -1252,7 +1250,7 @@ DisassembleByteCodeAsDicts( int Tcl_DisassembleObjCmd( - ClientData clientData, /* What type of operation. */ + void *clientData, /* What type of operation. */ Tcl_Interp *interp, /* Current interpreter. */ int objc, /* Number of arguments. */ Tcl_Obj *const objv[]) /* Argument objects. */ @@ -1335,7 +1333,7 @@ Tcl_DisassembleObjCmd( Tcl_SetObjResult(interp, Tcl_ObjPrintf( "\"%s\" isn't a procedure", TclGetString(objv[2]))); Tcl_SetErrorCode(interp, "TCL", "LOOKUP", "PROC", - TclGetString(objv[2]), NULL); + TclGetString(objv[2]), (char *)NULL); return TCL_ERROR; } @@ -1384,7 +1382,7 @@ Tcl_DisassembleObjCmd( Tcl_SetObjResult(interp, Tcl_ObjPrintf( "\"%s\" is not a class", TclGetString(objv[2]))); Tcl_SetErrorCode(interp, "TCL", "LOOKUP", "CLASS", - TclGetString(objv[2]), NULL); + TclGetString(objv[2]), (char *)NULL); return TCL_ERROR; } @@ -1394,7 +1392,7 @@ Tcl_DisassembleObjCmd( "\"%s\" has no defined constructor", TclGetString(objv[2]))); Tcl_SetErrorCode(interp, "TCL", "OPERATION", "DISASSEMBLE", - "CONSRUCTOR", NULL); + "CONSRUCTOR", (char *)NULL); return TCL_ERROR; } procPtr = TclOOGetProcFromMethod(methodPtr); @@ -1402,7 +1400,7 @@ Tcl_DisassembleObjCmd( Tcl_SetObjResult(interp, Tcl_NewStringObj( "body not available for this kind of constructor", -1)); Tcl_SetErrorCode(interp, "TCL", "OPERATION", "DISASSEMBLE", - "METHODTYPE", NULL); + "METHODTYPE", (char *)NULL); return TCL_ERROR; } @@ -1449,7 +1447,7 @@ Tcl_DisassembleObjCmd( Tcl_SetObjResult(interp, Tcl_ObjPrintf( "\"%s\" is not a class", TclGetString(objv[2]))); Tcl_SetErrorCode(interp, "TCL", "LOOKUP", "CLASS", - TclGetString(objv[2]), NULL); + TclGetString(objv[2]), (char *)NULL); return TCL_ERROR; } @@ -1459,7 +1457,7 @@ Tcl_DisassembleObjCmd( "\"%s\" has no defined destructor", TclGetString(objv[2]))); Tcl_SetErrorCode(interp, "TCL", "OPERATION", "DISASSEMBLE", - "DESRUCTOR", NULL); + "DESRUCTOR", (char *)NULL); return TCL_ERROR; } procPtr = TclOOGetProcFromMethod(methodPtr); @@ -1467,7 +1465,7 @@ Tcl_DisassembleObjCmd( Tcl_SetObjResult(interp, Tcl_NewStringObj( "body not available for this kind of destructor", -1)); Tcl_SetErrorCode(interp, "TCL", "OPERATION", "DISASSEMBLE", - "METHODTYPE", NULL); + "METHODTYPE", (char *)NULL); return TCL_ERROR; } @@ -1514,11 +1512,11 @@ Tcl_DisassembleObjCmd( Tcl_SetObjResult(interp, Tcl_ObjPrintf( "\"%s\" is not a class", TclGetString(objv[2]))); Tcl_SetErrorCode(interp, "TCL", "LOOKUP", "CLASS", - TclGetString(objv[2]), NULL); + TclGetString(objv[2]), (char *)NULL); return TCL_ERROR; } hPtr = Tcl_FindHashEntry(&oPtr->classPtr->classMethods, - (char *) objv[3]); + (char *)objv[3]); goto methodBody; case DISAS_OBJECT_METHOD: if (objc != 4) { @@ -1537,7 +1535,7 @@ Tcl_DisassembleObjCmd( if (oPtr->methodsPtr == NULL) { goto unknownMethod; } - hPtr = Tcl_FindHashEntry(oPtr->methodsPtr, (char *) objv[3]); + hPtr = Tcl_FindHashEntry(oPtr->methodsPtr, (char *)objv[3]); /* * Compile (if necessary) and disassemble a method body. @@ -1549,7 +1547,7 @@ Tcl_DisassembleObjCmd( Tcl_SetObjResult(interp, Tcl_ObjPrintf( "unknown method \"%s\"", TclGetString(objv[3]))); Tcl_SetErrorCode(interp, "TCL", "LOOKUP", "METHOD", - TclGetString(objv[3]), NULL); + TclGetString(objv[3]), (char *)NULL); return TCL_ERROR; } procPtr = TclOOGetProcFromMethod((Method *)Tcl_GetHashValue(hPtr)); @@ -1557,7 +1555,7 @@ Tcl_DisassembleObjCmd( Tcl_SetObjResult(interp, Tcl_NewStringObj( "body not available for this kind of method", -1)); Tcl_SetErrorCode(interp, "TCL", "OPERATION", "DISASSEMBLE", - "METHODTYPE", NULL); + "METHODTYPE", (char *)NULL); return TCL_ERROR; } if (procPtr->bodyPtr->typePtr != &tclByteCodeType) { @@ -1592,15 +1590,15 @@ Tcl_DisassembleObjCmd( Tcl_SetObjResult(interp, Tcl_NewStringObj( "may not disassemble prebuilt bytecode", -1)); Tcl_SetErrorCode(interp, "TCL", "OPERATION", "DISASSEMBLE", - "BYTECODE", NULL); + "BYTECODE", (char *)NULL); return TCL_ERROR; } - if (PTR2INT(clientData)) { + if (clientData) { Tcl_SetObjResult(interp, - DisassembleByteCodeAsDicts(interp, codeObjPtr)); + DisassembleByteCodeAsDicts(codeObjPtr)); } else { Tcl_SetObjResult(interp, - DisassembleByteCodeObj(interp, codeObjPtr)); + DisassembleByteCodeObj(codeObjPtr)); } return TCL_OK; } diff --git a/generic/tclExecute.c b/generic/tclExecute.c index 4072781..bdc3785 100644 --- a/generic/tclExecute.c +++ b/generic/tclExecute.c @@ -1582,12 +1582,7 @@ CompileExprObj( codePtr->localCachePtr = iPtr->varFramePtr->localCachePtr; codePtr->localCachePtr->refCount++; } -#ifdef TCL_COMPILE_DEBUG - if (tclTraceCompile == 2) { - TclPrintByteCodeObj(interp, objPtr); - fflush(stdout); - } -#endif /* TCL_COMPILE_DEBUG */ + TclDebugPrintByteCodeObj(objPtr); } return codePtr; } @@ -2519,7 +2514,7 @@ TEBCresume( "yield can only be called in a coroutine", -1)); DECACHE_STACK_INFO(); Tcl_SetErrorCode(interp, "TCL", "COROUTINE", "ILLEGAL_YIELD", - NULL); + (char *)NULL); CACHE_STACK_INFO(); goto gotError; } @@ -2550,7 +2545,7 @@ TEBCresume( "yieldto can only be called in a coroutine", -1)); DECACHE_STACK_INFO(); Tcl_SetErrorCode(interp, "TCL", "COROUTINE", "ILLEGAL_YIELD", - NULL); + (char *)NULL); CACHE_STACK_INFO(); goto gotError; } @@ -2561,7 +2556,7 @@ TEBCresume( "yieldto called in deleted namespace", -1)); DECACHE_STACK_INFO(); Tcl_SetErrorCode(interp, "TCL", "COROUTINE", "YIELDTO_IN_DELETED", - NULL); + (char *)NULL); CACHE_STACK_INFO(); goto gotError; } @@ -2622,7 +2617,7 @@ TEBCresume( Tcl_SetObjResult(interp, Tcl_NewStringObj( "tailcall can only be called from a proc or lambda", -1)); DECACHE_STACK_INFO(); - Tcl_SetErrorCode(interp, "TCL", "TAILCALL", "ILLEGAL", NULL); + Tcl_SetErrorCode(interp, "TCL", "TAILCALL", "ILLEGAL", (char *)NULL); CACHE_STACK_INFO(); goto gotError; } @@ -4408,7 +4403,7 @@ TEBCresume( TclObjVarErrMsg(interp, part1Ptr, NULL, "array set", "variable isn't array", opnd); DECACHE_STACK_INFO(); - Tcl_SetErrorCode(interp, "TCL", "WRITE", "ARRAY", NULL); + Tcl_SetErrorCode(interp, "TCL", "WRITE", "ARRAY", (char *)NULL); CACHE_STACK_INFO(); TRACE_ERROR(interp); goto gotError; @@ -4757,7 +4752,7 @@ TEBCresume( TRACE_ERROR(interp); DECACHE_STACK_INFO(); Tcl_SetErrorCode(interp, "TCL", "LOOKUP", "STACK_LEVEL", - TclGetString(OBJ_AT_TOS), NULL); + TclGetString(OBJ_AT_TOS), (char *)NULL); CACHE_STACK_INFO(); goto gotError; } @@ -4785,7 +4780,7 @@ TEBCresume( "invalid command name \"%s\"", TclGetString(OBJ_AT_TOS))); DECACHE_STACK_INFO(); Tcl_SetErrorCode(interp, "TCL", "LOOKUP", "COMMAND", - TclGetString(OBJ_AT_TOS), NULL); + TclGetString(OBJ_AT_TOS), (char *)NULL); CACHE_STACK_INFO(); TRACE_APPEND(("ERROR: not command\n")); goto gotError; @@ -4820,7 +4815,7 @@ TEBCresume( "self may only be called from inside a method", -1)); DECACHE_STACK_INFO(); - Tcl_SetErrorCode(interp, "TCL", "OO", "CONTEXT_REQUIRED", NULL); + Tcl_SetErrorCode(interp, "TCL", "OO", "CONTEXT_REQUIRED", (char *)NULL); CACHE_STACK_INFO(); goto gotError; } @@ -4848,7 +4843,7 @@ TEBCresume( "nextto may only be called from inside a method", -1)); DECACHE_STACK_INFO(); - Tcl_SetErrorCode(interp, "TCL", "OO", "CONTEXT_REQUIRED", NULL); + Tcl_SetErrorCode(interp, "TCL", "OO", "CONTEXT_REQUIRED", (char *)NULL); CACHE_STACK_INFO(); goto gotError; } @@ -4869,7 +4864,7 @@ TEBCresume( Tcl_SetObjResult(interp, Tcl_ObjPrintf( "\"%s\" is not a class", TclGetString(valuePtr))); DECACHE_STACK_INFO(); - Tcl_SetErrorCode(interp, "TCL", "OO", "CLASS_REQUIRED", NULL); + Tcl_SetErrorCode(interp, "TCL", "OO", "CLASS_REQUIRED", (char *)NULL); CACHE_STACK_INFO(); goto gotError; } @@ -4921,7 +4916,7 @@ TEBCresume( methodType, TclGetString(valuePtr))); DECACHE_STACK_INFO(); Tcl_SetErrorCode(interp, "TCL", "OO", "CLASS_NOT_REACHABLE", - NULL); + (char *)NULL); CACHE_STACK_INFO(); goto gotError; } @@ -4929,7 +4924,7 @@ TEBCresume( "%s has no non-filter implementation by \"%s\"", methodType, TclGetString(valuePtr))); DECACHE_STACK_INFO(); - Tcl_SetErrorCode(interp, "TCL", "OO", "CLASS_NOT_THERE", NULL); + Tcl_SetErrorCode(interp, "TCL", "OO", "CLASS_NOT_THERE", (char *)NULL); CACHE_STACK_INFO(); goto gotError; } @@ -4947,7 +4942,7 @@ TEBCresume( "next may only be called from inside a method", -1)); DECACHE_STACK_INFO(); - Tcl_SetErrorCode(interp, "TCL", "OO", "CONTEXT_REQUIRED", NULL); + Tcl_SetErrorCode(interp, "TCL", "OO", "CONTEXT_REQUIRED", (char *)NULL); CACHE_STACK_INFO(); goto gotError; } @@ -4976,7 +4971,7 @@ TEBCresume( Tcl_SetObjResult(interp, Tcl_ObjPrintf( "no next %s implementation", methodType)); DECACHE_STACK_INFO(); - Tcl_SetErrorCode(interp, "TCL", "OO", "NOTHING_NEXT", NULL); + Tcl_SetErrorCode(interp, "TCL", "OO", "NOTHING_NEXT", (char *)NULL); CACHE_STACK_INFO(); goto gotError; #ifdef TCL_COMPILE_DEBUG @@ -6300,7 +6295,7 @@ TEBCresume( DECACHE_STACK_INFO(); Tcl_SetErrorCode(interp, "ARITH", "DOMAIN", "domain error: argument not in valid range", - NULL); + (char *)NULL); CACHE_STACK_INFO(); #endif /* ERROR_CODE_FOR_EARLY_DETECTED_ARITH_ERROR */ goto gotError; @@ -6349,7 +6344,7 @@ TEBCresume( DECACHE_STACK_INFO(); Tcl_SetErrorCode(interp, "ARITH", "DOMAIN", "domain error: argument not in valid range", - NULL); + (char *)NULL); CACHE_STACK_INFO(); #endif /* ERROR_CODE_FOR_EARLY_DETECTED_ARITH_ERROR */ goto gotError; @@ -6371,7 +6366,7 @@ TEBCresume( #ifdef ERROR_CODE_FOR_EARLY_DETECTED_ARITH_ERROR DECACHE_STACK_INFO(); Tcl_SetErrorCode(interp, "ARITH", "IOVERFLOW", - "integer value too large to represent", NULL); + "integer value too large to represent", (char *)NULL); CACHE_STACK_INFO(); #endif /* ERROR_CODE_FOR_EARLY_DETECTED_ARITH_ERROR */ goto gotError; @@ -7325,7 +7320,7 @@ TEBCresume( TclGetString(OBJ_AT_TOS))); DECACHE_STACK_INFO(); Tcl_SetErrorCode(interp, "TCL", "LOOKUP", "DICT", - TclGetString(OBJ_AT_TOS), NULL); + TclGetString(OBJ_AT_TOS), (char *)NULL); CACHE_STACK_INFO(); TRACE_ERROR(interp); goto gotError; @@ -8012,7 +8007,7 @@ TEBCresume( divideByZero: Tcl_SetObjResult(interp, Tcl_NewStringObj("divide by zero", -1)); DECACHE_STACK_INFO(); - Tcl_SetErrorCode(interp, "ARITH", "DIVZERO", "divide by zero", NULL); + Tcl_SetErrorCode(interp, "ARITH", "DIVZERO", "divide by zero", (char *)NULL); CACHE_STACK_INFO(); goto gotError; @@ -8026,7 +8021,7 @@ TEBCresume( "exponentiation of zero by negative power", -1)); DECACHE_STACK_INFO(); Tcl_SetErrorCode(interp, "ARITH", "DOMAIN", - "exponentiation of zero by negative power", NULL); + "exponentiation of zero by negative power", (char *)NULL); CACHE_STACK_INFO(); /* @@ -9779,7 +9774,7 @@ IllegalExprOperandType( Tcl_SetObjResult(interp, Tcl_ObjPrintf( "can't use %s as operand of \"%s\"", description, op)); - Tcl_SetErrorCode(interp, "ARITH", "DOMAIN", description, NULL); + Tcl_SetErrorCode(interp, "ARITH", "DOMAIN", description, (char *)NULL); } /* @@ -10156,23 +10151,23 @@ TclExprFloatError( if ((errno == EDOM) || TclIsNaN(value)) { s = "domain error: argument not in valid range"; Tcl_SetObjResult(interp, Tcl_NewStringObj(s, -1)); - Tcl_SetErrorCode(interp, "ARITH", "DOMAIN", s, NULL); + Tcl_SetErrorCode(interp, "ARITH", "DOMAIN", s, (char *)NULL); } else if ((errno == ERANGE) || TclIsInfinite(value)) { if (value == 0.0) { s = "floating-point value too small to represent"; Tcl_SetObjResult(interp, Tcl_NewStringObj(s, -1)); - Tcl_SetErrorCode(interp, "ARITH", "UNDERFLOW", s, NULL); + Tcl_SetErrorCode(interp, "ARITH", "UNDERFLOW", s, (char *)NULL); } else { s = "floating-point value too large to represent"; Tcl_SetObjResult(interp, Tcl_NewStringObj(s, -1)); - Tcl_SetErrorCode(interp, "ARITH", "OVERFLOW", s, NULL); + Tcl_SetErrorCode(interp, "ARITH", "OVERFLOW", s, (char *)NULL); } } else { Tcl_Obj *objPtr = Tcl_ObjPrintf( "unknown floating-point error, errno = %d", errno); Tcl_SetErrorCode(interp, "ARITH", "UNKNOWN", - Tcl_GetString(objPtr), NULL); + Tcl_GetString(objPtr), (char *)NULL); Tcl_SetObjResult(interp, objPtr); } } -- cgit v0.12 From d89d16950d0f96afc68a1828744b804f7d509415 Mon Sep 17 00:00:00 2001 From: "jan.nijtmans" Date: Mon, 27 May 2024 21:21:07 +0000 Subject: Improve details about attached zipfs archives in tclsh and wish (backport from 9.0) --- doc/tclsh.1 | 26 +++++++++++++++++--------- doc/zipfs.n | 14 +++++++++++++- 2 files changed, 30 insertions(+), 10 deletions(-) diff --git a/doc/tclsh.1 b/doc/tclsh.1 index 3a78737..965e76d 100644 --- a/doc/tclsh.1 +++ b/doc/tclsh.1 @@ -141,14 +141,22 @@ incomplete commands. See \fBTcl_StandardChannels\fR for more explanations. .SH ZIPVFS .PP -When a zipfile is concatenated to the end of a \fBtclsh\fR, on -startup the contents of the zip archive will be mounted as the -virtual file system /zvfs. If a top level directory tcl8.6 is -present in the zip archive, it will become the directory loaded -as env(TCL_LIBRARY). If a file named \fBmain.tcl\fR is present -in the top level directory of the zip archive, it will be sourced -instead of the shell's normal command line handing. +When a zipfile is concatenated to the end of a \fBtclsh\fR, on startup +the contents of the zip archive will be mounted under the virtual file +system \fB//zipfs:/\fR. If a top level directory \fBtcl_library\fR is +present in the zip archive, it will become the directory loaded as +env(TCL_LIBRARY). If a file named \fBmain.tcl\fR is present in the top +level directory of the zip archive, it will be sourced instead of the +shell's normal command line handing. +.PP +Only one zipfile can be concatenated to the end of executable image +(tclsh, or wish). However, if multiple zipfiles are +concatenated, only the last one is used. + +This filesystem is read-only. Files cannot be added or modified within +this mounted file system. See zipfs(n) for complete details. + .SH "SEE ALSO" -auto_path(n), encoding(n), env(n), fconfigure(n) +auto_path(n), encoding(n), env(n), fconfigure(n), zipfs(n) .SH KEYWORDS -application, argument, interpreter, prompt, script file, shell +application, argument, interpreter, prompt, script file, shell, zipfs diff --git a/doc/zipfs.n b/doc/zipfs.n index 0a05078..9776590 100644 --- a/doc/zipfs.n +++ b/doc/zipfs.n @@ -56,7 +56,7 @@ This takes the name of a file, \fIfilename\fR, and produces where it would be mapped into a zipfs mount as its result. If specified, \fImountpoint\fR says within which mount the mapping will be done; if omitted, the main root of the zipfs system is used. The \fIinZipfs\fR argument is a an optional boolean -which controls whether to fully canonicalise the name; it defaults to true. +which controls whether to fully canonicalize the name; it defaults to true. .TP \fBzipfs exists\fR \fIfilename\fR . @@ -193,6 +193,18 @@ then the resulting image is an executable that will \fBsource\fR the script in that \fBmain.tcl\fR after mounting the ZIP archive, and will \fBexit\fR once that script has been executed. .PP +\fBNote:\fR \fBtclsh\fR and \fBwish\fR can be built using either +dynamic binding or static binding of the core implementation +libraries. With a dynamic binding, the base application Tcl_Library +contents are attached to the \fBlibtcl\fR and \fBlibtk\fR shared +library, respectively. With a static binding, the Tcl_Library +contents, etc., are attached to the application, \fBtclsh\fR or +\fBwish\fR. When using \fBmkimg\fR with a statically built tclsh, it is +the user's responsibility to preserve the attached archive by first +extracting it to a temporary location, and then add whatever +additional files desired, before creating and attaching the new +archive to the new application. +.PP \fBCaution:\fR highly experimental, not usable on Android, only partially tested on Linux and Windows. .RE -- cgit v0.12