From 998409ea9b162e1f9a271add26637eb24792a2aa Mon Sep 17 00:00:00 2001 From: "jan.nijtmans" Date: Wed, 12 Aug 2020 06:36:31 +0000 Subject: Update .travis.yml: remove deprecated "sudo" and rename "matrix" to "jobs" Fix travis build for Windows/Debug --- .travis.yml | 3 +-- win/tclWinPort.h | 4 +++- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/.travis.yml b/.travis.yml index b309e51..05c2f6a 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,4 +1,3 @@ -sudo: false language: c addons: apt: @@ -10,7 +9,7 @@ addons: - gcc-mingw-w64-i686 - gcc-mingw-w64-x86-64 - gcc-multilib -matrix: +jobs: include: # Testing on Linux with various compilers - name: "Linux/GCC/Shared" diff --git a/win/tclWinPort.h b/win/tclWinPort.h index 3cab385..056c7c8 100644 --- a/win/tclWinPort.h +++ b/win/tclWinPort.h @@ -33,7 +33,9 @@ typedef DWORD_PTR * PDWORD_PTR; /* * Ask for the winsock function typedefs, also. */ -#define INCL_WINSOCK_API_TYPEDEFS 1 +#ifndef INCL_WINSOCK_API_TYPEDEFS +# define INCL_WINSOCK_API_TYPEDEFS 1 +#endif #include #ifdef CHECK_UNICODE_CALLS -- cgit v0.12 From 330e4967abb577c06a94a635e415c031030372f8 Mon Sep 17 00:00:00 2001 From: "jan.nijtmans" Date: Wed, 12 Aug 2020 07:10:57 +0000 Subject: Fix value of CMD_DEAD flag --- generic/tclInt.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/generic/tclInt.h b/generic/tclInt.h index 1e90b70..317ae1f 100644 --- a/generic/tclInt.h +++ b/generic/tclInt.h @@ -1682,7 +1682,7 @@ typedef struct Command { #define CMD_COMPILES_EXPANDED 0x08 #define CMD_REDEF_IN_PROGRESS 0x10 #define CMD_VIA_RESOLVER 0x20 -#define CMD_DEAD 0x30 +#define CMD_DEAD 0x40 /* -- cgit v0.12 From 52549ae747613994a8ced4de9b567bc4cc09443f Mon Sep 17 00:00:00 2001 From: "jan.nijtmans" Date: Wed, 12 Aug 2020 10:25:49 +0000 Subject: Fix [e87000d8425ab86a]: crash for "fconfigure stdout" in Win32. Even though the crash cannot happen in Tcl 8.6, the function Tcl_BadChannelOption() was to blame, so better fix that in 8.6 too. --- generic/tclIO.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/generic/tclIO.c b/generic/tclIO.c index 7abeb68..82eb581 100644 --- a/generic/tclIO.c +++ b/generic/tclIO.c @@ -7699,7 +7699,7 @@ Tcl_BadChannelOption( } Tcl_ResetResult(interp); errObj = Tcl_ObjPrintf("bad option \"%s\": should be one of ", - optionName); + optionName ? optionName : ""); argc--; for (i = 0; i < argc; i++) { Tcl_AppendPrintfToObj(errObj, "-%s, ", argv[i]); -- cgit v0.12 From 1d4f551278f3f36f063591ecc1a6bd2e7964b14f Mon Sep 17 00:00:00 2001 From: pooryorick Date: Wed, 12 Aug 2020 13:28:08 +0000 Subject: Fix for [3422267ed6b7], segmentation fault with imported alias. --- generic/tclNamesp.c | 7 ++++++- generic/tclProc.c | 7 +++++++ tests/interp.test | 7 +++++++ 3 files changed, 20 insertions(+), 1 deletion(-) diff --git a/generic/tclNamesp.c b/generic/tclNamesp.c index 26dca62..fea23aa 100644 --- a/generic/tclNamesp.c +++ b/generic/tclNamesp.c @@ -959,7 +959,7 @@ Tcl_DeleteNamespace( /* * If the namespace has associated ensemble commands, delete them first. * This leaves the actual contents of the namespace alone (unless they are - * linked ensemble commands, of course). Note that this code is actually + * linked ensemble commands, of course). This code is * reentrant so command delete traces won't purturb things badly. */ @@ -1770,7 +1770,9 @@ DoImport( TclInvokeImportedCmd, InvokeImportedNRCmd, dataPtr, DeleteImportedCmd); dataPtr->realCmdPtr = cmdPtr; + cmdPtr->refCount++; dataPtr->selfPtr = (Command *) importedCmd; + dataPtr->selfPtr->refCount++; dataPtr->selfPtr->compileProc = cmdPtr->compileProc; Tcl_DStringFree(&ds); @@ -1781,6 +1783,7 @@ DoImport( refPtr = (ImportRef *)ckalloc(sizeof(ImportRef)); refPtr->importedCmdPtr = (Command *) importedCmd; + refPtr->importedCmdPtr->refCount++; refPtr->nextPtr = cmdPtr->importRefPtr; cmdPtr->importRefPtr = refPtr; } else { @@ -2076,7 +2079,9 @@ DeleteImportedCmd( } else { prevPtr->nextPtr = refPtr->nextPtr; } + TclCleanupCommandMacro(refPtr->importedCmdPtr); ckfree(refPtr); + TclCleanupCommandMacro(selfPtr) ckfree(dataPtr); return; } diff --git a/generic/tclProc.c b/generic/tclProc.c index 0d67c37..150d036 100644 --- a/generic/tclProc.c +++ b/generic/tclProc.c @@ -215,6 +215,7 @@ Tcl_ProcObjCmd( */ procPtr->cmdPtr = (Command *) cmd; + procPtr->cmdPtr->refCount++; /* * TIP #280: Remember the line the procedure body is starting on. In a @@ -2154,6 +2155,12 @@ TclProcCleanupProc( ckfree(localPtr); localPtr = nextPtr; } + /* + * TclOOMethod.c:clOOMakeProcMethod sets cmdPtr to NULL + */ + if (procPtr->cmdPtr) { + TclCleanupCommandMacro(procPtr->cmdPtr); + } ckfree(procPtr); /* diff --git a/tests/interp.test b/tests/interp.test index 599ac08..35f3390 100644 --- a/tests/interp.test +++ b/tests/interp.test @@ -3664,6 +3664,13 @@ test interp-38.8 {interp debug basic setup} -body { } -returnCodes { error } -result {wrong # args: should be "interp debug path ?-frame ?bool??"} + +test interp-39.0 { + no segmentation fault when a command is deleted +} -body { +} -cleanup { +} -result 1 + # cleanup unset -nocomplain hidden_cmds -- cgit v0.12 From 80c4d66b217ec43299960d17a40f07d4cfd870bf Mon Sep 17 00:00:00 2001 From: pooryorick Date: Wed, 12 Aug 2020 13:31:16 +0000 Subject: body of test case for [3422267ed6b79922]. --- tests/interp.test | 30 ++++++++++++++++++++++++++++++ 1 file changed, 30 insertions(+) diff --git a/tests/interp.test b/tests/interp.test index 35f3390..9287756 100644 --- a/tests/interp.test +++ b/tests/interp.test @@ -3668,6 +3668,36 @@ test interp-38.8 {interp debug basic setup} -body { test interp-39.0 { no segmentation fault when a command is deleted } -body { + variable res {} + + proc p1 args { + return success + } + namespace eval ns1 { + namespace export * + } + interp alias {} [namespace current]::ns1::p2 {} [namespace current]::p1 + namespace eval ns2 { + namespace import [namespace parent]::ns1::p2 + } + proc ondelete {oldname newname op} { + variable res + namespace delete ns1 + catch { + ns1::p2 + } res + } + + trace add command ns2::p2 delete [namespace which ondelete] + rename ns2::p2 {} + rename p1 {} + if { + [string match {*invalid command name*ns1::p2*} $res] + } { + return 1 + } else { + return $res + } } -cleanup { } -result 1 -- cgit v0.12 From 840355939de3409373a08bc3c0c216916d74521f Mon Sep 17 00:00:00 2001 From: "jan.nijtmans" Date: Thu, 13 Aug 2020 07:21:34 +0000 Subject: Testcase event-1.1 (still) fails occasionally on macOS --- tests/event.test | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/tests/event.test b/tests/event.test index b42909c..70d4cff 100644 --- a/tests/event.test +++ b/tests/event.test @@ -23,11 +23,12 @@ testConstraint testfilehandler [llength [info commands testfilehandler]] testConstraint testexithandler [llength [info commands testexithandler]] testConstraint testfilewait [llength [info commands testfilewait]] testConstraint exec [llength [info commands exec]] - +testConstraint notOSX [expr {$::tcl_platform(os) ne "Darwin"}] + test event-1.1 {Tcl_CreateFileHandler, reading} -setup { testfilehandler close set result "" -} -constraints testfilehandler -body { +} -constraints {testfilehandler notOSX} -body { testfilehandler create 0 readable off testfilehandler clear 0 testfilehandler oneevent -- cgit v0.12 From 3c1b7f78dc3d31142226b8c29cce38d5d3a86f03 Mon Sep 17 00:00:00 2001 From: "jan.nijtmans" Date: Thu, 13 Aug 2020 12:42:38 +0000 Subject: Backout uncomplete fix for [3422267ed6b79922]: segmentation fault from deleting the the target of an imported alias during a trace on the target of the alias. Since it causes build failures. --- generic/tclNamesp.c | 7 +------ generic/tclProc.c | 7 ------- tests/interp.test | 37 ------------------------------------- 3 files changed, 1 insertion(+), 50 deletions(-) diff --git a/generic/tclNamesp.c b/generic/tclNamesp.c index fea23aa..26dca62 100644 --- a/generic/tclNamesp.c +++ b/generic/tclNamesp.c @@ -959,7 +959,7 @@ Tcl_DeleteNamespace( /* * If the namespace has associated ensemble commands, delete them first. * This leaves the actual contents of the namespace alone (unless they are - * linked ensemble commands, of course). This code is + * linked ensemble commands, of course). Note that this code is actually * reentrant so command delete traces won't purturb things badly. */ @@ -1770,9 +1770,7 @@ DoImport( TclInvokeImportedCmd, InvokeImportedNRCmd, dataPtr, DeleteImportedCmd); dataPtr->realCmdPtr = cmdPtr; - cmdPtr->refCount++; dataPtr->selfPtr = (Command *) importedCmd; - dataPtr->selfPtr->refCount++; dataPtr->selfPtr->compileProc = cmdPtr->compileProc; Tcl_DStringFree(&ds); @@ -1783,7 +1781,6 @@ DoImport( refPtr = (ImportRef *)ckalloc(sizeof(ImportRef)); refPtr->importedCmdPtr = (Command *) importedCmd; - refPtr->importedCmdPtr->refCount++; refPtr->nextPtr = cmdPtr->importRefPtr; cmdPtr->importRefPtr = refPtr; } else { @@ -2079,9 +2076,7 @@ DeleteImportedCmd( } else { prevPtr->nextPtr = refPtr->nextPtr; } - TclCleanupCommandMacro(refPtr->importedCmdPtr); ckfree(refPtr); - TclCleanupCommandMacro(selfPtr) ckfree(dataPtr); return; } diff --git a/generic/tclProc.c b/generic/tclProc.c index 150d036..0d67c37 100644 --- a/generic/tclProc.c +++ b/generic/tclProc.c @@ -215,7 +215,6 @@ Tcl_ProcObjCmd( */ procPtr->cmdPtr = (Command *) cmd; - procPtr->cmdPtr->refCount++; /* * TIP #280: Remember the line the procedure body is starting on. In a @@ -2155,12 +2154,6 @@ TclProcCleanupProc( ckfree(localPtr); localPtr = nextPtr; } - /* - * TclOOMethod.c:clOOMakeProcMethod sets cmdPtr to NULL - */ - if (procPtr->cmdPtr) { - TclCleanupCommandMacro(procPtr->cmdPtr); - } ckfree(procPtr); /* diff --git a/tests/interp.test b/tests/interp.test index 9287756..599ac08 100644 --- a/tests/interp.test +++ b/tests/interp.test @@ -3664,43 +3664,6 @@ test interp-38.8 {interp debug basic setup} -body { } -returnCodes { error } -result {wrong # args: should be "interp debug path ?-frame ?bool??"} - -test interp-39.0 { - no segmentation fault when a command is deleted -} -body { - variable res {} - - proc p1 args { - return success - } - namespace eval ns1 { - namespace export * - } - interp alias {} [namespace current]::ns1::p2 {} [namespace current]::p1 - namespace eval ns2 { - namespace import [namespace parent]::ns1::p2 - } - proc ondelete {oldname newname op} { - variable res - namespace delete ns1 - catch { - ns1::p2 - } res - } - - trace add command ns2::p2 delete [namespace which ondelete] - rename ns2::p2 {} - rename p1 {} - if { - [string match {*invalid command name*ns1::p2*} $res] - } { - return 1 - } else { - return $res - } -} -cleanup { -} -result 1 - # cleanup unset -nocomplain hidden_cmds -- cgit v0.12 From acfbbfa01955b1e6807428aef20496d83af43d17 Mon Sep 17 00:00:00 2001 From: "jan.nijtmans" Date: Thu, 13 Aug 2020 14:20:54 +0000 Subject: More usage of TclNewIntObj() macro --- generic/tclCmdMZ.c | 2 +- generic/tclCompExpr.c | 4 ++-- generic/tclDate.c | 4 ++-- generic/tclExecute.c | 6 +++--- generic/tclGetDate.y | 4 ++-- generic/tclIORChan.c | 8 +++++--- generic/tclLink.c | 10 +++++----- generic/tclOOBasic.c | 2 +- generic/tclPkg.c | 3 ++- generic/tclProcess.c | 12 ++++++------ generic/tclTrace.c | 4 ++-- generic/tclVar.c | 2 +- 12 files changed, 32 insertions(+), 29 deletions(-) diff --git a/generic/tclCmdMZ.c b/generic/tclCmdMZ.c index fe7cddd..f95dd12 100644 --- a/generic/tclCmdMZ.c +++ b/generic/tclCmdMZ.c @@ -4311,7 +4311,7 @@ Tcl_TimeRateObjCmd( */ measureOverhead = 0; - Tcl_SetObjResult(interp, Tcl_NewLongObj(0)); + Tcl_SetObjResult(interp, Tcl_NewWideIntObj(0)); return TCL_OK; } diff --git a/generic/tclCompExpr.c b/generic/tclCompExpr.c index 4fb41fc..74610c7 100644 --- a/generic/tclCompExpr.c +++ b/generic/tclCompExpr.c @@ -2725,7 +2725,7 @@ TclVariadicOpCmd( Tcl_Obj *const *litObjPtrPtr = litObjv; if (lexeme == EXPON) { - litObjv[1] = Tcl_NewIntObj(occdPtr->i.identity); + TclNewIntObj(litObjv[1], occdPtr->i.identity); Tcl_IncrRefCount(litObjv[1]); decrMe = 1; litObjv[0] = objv[1]; @@ -2741,7 +2741,7 @@ TclVariadicOpCmd( if (lexeme == DIVIDE) { litObjv[0] = Tcl_NewDoubleObj(1.0); } else { - litObjv[0] = Tcl_NewIntObj(occdPtr->i.identity); + TclNewIntObj(litObjv[0], occdPtr->i.identity); } Tcl_IncrRefCount(litObjv[0]); litObjv[1] = objv[1]; diff --git a/generic/tclDate.c b/generic/tclDate.c index e9ef9bd..f8552a3 100644 --- a/generic/tclDate.c +++ b/generic/tclDate.c @@ -2501,12 +2501,12 @@ TclDateerror( Tcl_AppendToObj(infoPtr->messages, infoPtr->separatrix, -1); Tcl_AppendToObj(infoPtr->messages, s, -1); Tcl_AppendToObj(infoPtr->messages, " (characters ", -1); - t = Tcl_NewIntObj(location->first_column); + TclNewIntObj(t, location->first_column); Tcl_IncrRefCount(t); Tcl_AppendObjToObj(infoPtr->messages, t); Tcl_DecrRefCount(t); Tcl_AppendToObj(infoPtr->messages, "-", -1); - t = Tcl_NewIntObj(location->last_column); + TclNewIntObj(t, location->last_column); Tcl_IncrRefCount(t); Tcl_AppendObjToObj(infoPtr->messages, t); Tcl_DecrRefCount(t); diff --git a/generic/tclExecute.c b/generic/tclExecute.c index 4c25397..0f1c2cc 100644 --- a/generic/tclExecute.c +++ b/generic/tclExecute.c @@ -3635,7 +3635,7 @@ TEBCresume( case INST_INCR_SCALAR_STK_IMM: case INST_INCR_STK_IMM: increment = TclGetInt1AtPtr(pc+1); - incrPtr = Tcl_NewIntObj(increment); + TclNewIntObj(incrPtr, increment); Tcl_IncrRefCount(incrPtr); pcAdjustment = 2; @@ -3670,7 +3670,7 @@ TEBCresume( case INST_INCR_ARRAY1_IMM: opnd = TclGetUInt1AtPtr(pc+1); increment = TclGetInt1AtPtr(pc+2); - incrPtr = Tcl_NewIntObj(increment); + TclNewIntObj(incrPtr, increment); Tcl_IncrRefCount(incrPtr); pcAdjustment = 3; @@ -7022,7 +7022,7 @@ TEBCresume( if (valuePtr == NULL) { Tcl_DictObjPut(NULL, dictPtr, OBJ_AT_TOS,Tcl_NewIntObj(opnd)); } else { - value2Ptr = Tcl_NewIntObj(opnd); + TclNewIntObj(value2Ptr, opnd); Tcl_IncrRefCount(value2Ptr); if (Tcl_IsShared(valuePtr)) { valuePtr = Tcl_DuplicateObj(valuePtr); diff --git a/generic/tclGetDate.y b/generic/tclGetDate.y index c06e53a..33b23ae 100644 --- a/generic/tclGetDate.y +++ b/generic/tclGetDate.y @@ -716,12 +716,12 @@ TclDateerror( Tcl_AppendToObj(infoPtr->messages, infoPtr->separatrix, -1); Tcl_AppendToObj(infoPtr->messages, s, -1); Tcl_AppendToObj(infoPtr->messages, " (characters ", -1); - t = Tcl_NewIntObj(location->first_column); + TclNewIntObj(t, location->first_column); Tcl_IncrRefCount(t); Tcl_AppendObjToObj(infoPtr->messages, t); Tcl_DecrRefCount(t); Tcl_AppendToObj(infoPtr->messages, "-", -1); - t = Tcl_NewIntObj(location->last_column); + TclNewIntObj(t, location->last_column); Tcl_IncrRefCount(t); Tcl_AppendObjToObj(infoPtr->messages, t); Tcl_DecrRefCount(t); diff --git a/generic/tclIORChan.c b/generic/tclIORChan.c index 8a5675a..c622afa 100644 --- a/generic/tclIORChan.c +++ b/generic/tclIORChan.c @@ -1365,7 +1365,7 @@ ReflectInput( Tcl_Preserve(rcPtr); - toReadObj = Tcl_NewIntObj(toRead); + TclNewIntObj(toReadObj, toRead); Tcl_IncrRefCount(toReadObj); if (InvokeTclMethod(rcPtr, METH_READ, toReadObj, NULL, &resObj)!=TCL_OK) { @@ -3047,8 +3047,10 @@ ForwardProc( } case ForwardedInput: { - Tcl_Obj *toReadObj = Tcl_NewIntObj(paramPtr->input.toRead); - Tcl_IncrRefCount(toReadObj); + Tcl_Obj *toReadObj; + + TclNewIntObj(toReadObj, paramPtr->input.toRead); + Tcl_IncrRefCount(toReadObj); Tcl_Preserve(rcPtr); if (InvokeTclMethod(rcPtr, METH_READ, toReadObj, NULL, &resObj)!=TCL_OK){ diff --git a/generic/tclLink.c b/generic/tclLink.c index 4256f84..c763218 100644 --- a/generic/tclLink.c +++ b/generic/tclLink.c @@ -1296,7 +1296,7 @@ ObjValue( memcpy(linkPtr->lastValue.aryPtr, linkPtr->addr, linkPtr->bytes); objv = (Tcl_Obj **)ckalloc(linkPtr->numElems * sizeof(Tcl_Obj *)); for (i=0; i < linkPtr->numElems; i++) { - objv[i] = Tcl_NewIntObj(linkPtr->lastValue.iPtr[i]); + TclNewIntObj(objv[i], linkPtr->lastValue.iPtr[i]); } resultObj = Tcl_NewListObj(linkPtr->numElems, objv); ckfree(objv); @@ -1348,7 +1348,7 @@ ObjValue( memcpy(linkPtr->lastValue.aryPtr, linkPtr->addr, linkPtr->bytes); objv = (Tcl_Obj **)ckalloc(linkPtr->numElems * sizeof(Tcl_Obj *)); for (i=0; i < linkPtr->numElems; i++) { - objv[i] = Tcl_NewIntObj(linkPtr->lastValue.cPtr[i]); + TclNewIntObj(objv[i], linkPtr->lastValue.cPtr[i]); } resultObj = Tcl_NewListObj(linkPtr->numElems, objv); ckfree(objv); @@ -1361,7 +1361,7 @@ ObjValue( memcpy(linkPtr->lastValue.aryPtr, linkPtr->addr, linkPtr->bytes); objv = (Tcl_Obj **)ckalloc(linkPtr->numElems * sizeof(Tcl_Obj *)); for (i=0; i < linkPtr->numElems; i++) { - objv[i] = Tcl_NewIntObj(linkPtr->lastValue.ucPtr[i]); + TclNewIntObj(objv[i], linkPtr->lastValue.ucPtr[i]); } resultObj = Tcl_NewListObj(linkPtr->numElems, objv); ckfree(objv); @@ -1374,7 +1374,7 @@ ObjValue( memcpy(linkPtr->lastValue.aryPtr, linkPtr->addr, linkPtr->bytes); objv = (Tcl_Obj **)ckalloc(linkPtr->numElems * sizeof(Tcl_Obj *)); for (i=0; i < linkPtr->numElems; i++) { - objv[i] = Tcl_NewIntObj(linkPtr->lastValue.sPtr[i]); + TclNewIntObj(objv[i], linkPtr->lastValue.sPtr[i]); } resultObj = Tcl_NewListObj(linkPtr->numElems, objv); ckfree(objv); @@ -1387,7 +1387,7 @@ ObjValue( memcpy(linkPtr->lastValue.aryPtr, linkPtr->addr, linkPtr->bytes); objv = (Tcl_Obj **)ckalloc(linkPtr->numElems * sizeof(Tcl_Obj *)); for (i=0; i < linkPtr->numElems; i++) { - objv[i] = Tcl_NewIntObj(linkPtr->lastValue.usPtr[i]); + TclNewIntObj(objv[i], linkPtr->lastValue.usPtr[i]); } resultObj = Tcl_NewListObj(linkPtr->numElems, objv); ckfree(objv); diff --git a/generic/tclOOBasic.c b/generic/tclOOBasic.c index 9f7b526..b866c2c 100644 --- a/generic/tclOOBasic.c +++ b/generic/tclOOBasic.c @@ -1249,7 +1249,7 @@ TclOOSelfObjCmd( } case SELF_CALL: result[0] = TclOORenderCallChain(interp, contextPtr->callPtr); - result[1] = Tcl_NewIntObj(contextPtr->index); + TclNewIntObj(result[1], contextPtr->index); Tcl_SetObjResult(interp, Tcl_NewListObj(2, result)); return TCL_OK; } diff --git a/generic/tclPkg.c b/generic/tclPkg.c index b39224e..bdd9a86 100644 --- a/generic/tclPkg.c +++ b/generic/tclPkg.c @@ -905,8 +905,9 @@ SelectPackageFinal( } } } else if (result != TCL_ERROR) { - Tcl_Obj *codePtr = Tcl_NewIntObj(result); + Tcl_Obj *codePtr; + TclNewIntObj(codePtr, result); Tcl_SetObjResult(interp, Tcl_ObjPrintf( "attempt to provide package %s %s failed:" " bad return code: %s", diff --git a/generic/tclProcess.c b/generic/tclProcess.c index 5bf0af8..c0f21e3 100644 --- a/generic/tclProcess.c +++ b/generic/tclProcess.c @@ -267,8 +267,8 @@ WaitProcessStatus( "child process exited abnormally", -1); if (errorObjPtr) { errorStrings[0] = Tcl_NewStringObj("CHILDSTATUS", -1); - errorStrings[1] = Tcl_NewIntObj(resolvedPid); - errorStrings[2] = Tcl_NewIntObj(WEXITSTATUS(waitStatus)); + TclNewIntObj(errorStrings[1], resolvedPid); + TclNewIntObj(errorStrings[2], WEXITSTATUS(waitStatus)); *errorObjPtr = Tcl_NewListObj(3, errorStrings); } } @@ -286,7 +286,7 @@ WaitProcessStatus( "child killed: %s", msg); if (errorObjPtr) { errorStrings[0] = Tcl_NewStringObj("CHILDKILLED", -1); - errorStrings[1] = Tcl_NewIntObj(resolvedPid); + TclNewIntObj(errorStrings[1], resolvedPid); errorStrings[2] = Tcl_NewStringObj(Tcl_SignalId(WTERMSIG(waitStatus)), -1); errorStrings[3] = Tcl_NewStringObj(msg, -1); *errorObjPtr = Tcl_NewListObj(4, errorStrings); @@ -305,7 +305,7 @@ WaitProcessStatus( "child suspended: %s", msg); if (errorObjPtr) { errorStrings[0] = Tcl_NewStringObj("CHILDSUSP", -1); - errorStrings[1] = Tcl_NewIntObj(resolvedPid); + TclNewIntObj(errorStrings[1], resolvedPid); errorStrings[2] = Tcl_NewStringObj(Tcl_SignalId(WSTOPSIG(waitStatus)), -1); errorStrings[3] = Tcl_NewStringObj(msg, -1); *errorObjPtr = Tcl_NewListObj(4, errorStrings); @@ -326,7 +326,7 @@ WaitProcessStatus( errorStrings[1] = Tcl_NewStringObj("OPERATION", -1); errorStrings[2] = Tcl_NewStringObj("EXEC", -1); errorStrings[3] = Tcl_NewStringObj("ODDWAITRESULT", -1); - errorStrings[4] = Tcl_NewIntObj(resolvedPid); + TclNewIntObj(errorStrings[4], resolvedPid); *errorObjPtr = Tcl_NewListObj(5, errorStrings); } return TCL_PROCESS_UNKNOWN_STATUS; @@ -378,7 +378,7 @@ BuildProcessStatusObj( * Abnormal exit, return {TCL_ERROR msg error} */ - resultObjs[0] = Tcl_NewIntObj(TCL_ERROR); + TclNewIntObj(resultObjs[0], TCL_ERROR); resultObjs[1] = info->msg; resultObjs[2] = info->error; return Tcl_NewListObj(3, resultObjs); diff --git a/generic/tclTrace.c b/generic/tclTrace.c index e05fa69..9896e0e 100644 --- a/generic/tclTrace.c +++ b/generic/tclTrace.c @@ -1848,7 +1848,7 @@ TraceExecutionProc( * Append result code. */ - resultCode = Tcl_NewIntObj(code); + TclNewIntObj(resultCode, code); resultCodeStr = Tcl_GetString(resultCode); Tcl_DStringAppendElement(&cmd, resultCodeStr); Tcl_DecrRefCount(resultCode); @@ -1976,7 +1976,7 @@ TraceVarProc( int rewind = ((Interp *)interp)->execEnvPtr->rewind; /* - * We might call Tcl_Eval() below, and that might evaluate [trace vdelete] + * We might call Tcl_EvalEx() below, and that might evaluate [trace vdelete] * which might try to free tvarPtr. We want to use tvarPtr until the end * of this function, so we use Tcl_Preserve() and Tcl_Release() to be sure * it is not freed while we still need it. diff --git a/generic/tclVar.c b/generic/tclVar.c index 72724a4..2818fc9 100644 --- a/generic/tclVar.c +++ b/generic/tclVar.c @@ -2322,7 +2322,7 @@ TclPtrIncrObjVarIdx( VarHashRefCount(varPtr)--; } if (varValuePtr == NULL) { - varValuePtr = Tcl_NewIntObj(0); + TclNewIntObj(varValuePtr, 0); } if (Tcl_IsShared(varValuePtr)) { /* Copy on write */ -- cgit v0.12 From a5455c136a2b022903089f85ebc28327fe31898e Mon Sep 17 00:00:00 2001 From: pooryorick Date: Sun, 16 Aug 2020 10:04:44 +0000 Subject: Fix for [688fcc7082fa], memory error during deletion of imported routine. --- generic/tclBasic.c | 27 +++++++++++++-------------- 1 file changed, 13 insertions(+), 14 deletions(-) diff --git a/generic/tclBasic.c b/generic/tclBasic.c index 4ee2ca0..2b1bae9 100644 --- a/generic/tclBasic.c +++ b/generic/tclBasic.c @@ -3547,6 +3547,19 @@ Tcl_DeleteCommandFromToken( iPtr->compileEpoch++; } + if (!(cmdPtr->flags & CMD_REDEF_IN_PROGRESS)) { + /* + * Delete any imports of this routine before deleting this routine itself. + * See issue 688fcc7082fa. + */ + for (refPtr = cmdPtr->importRefPtr; refPtr != NULL; + refPtr = nextRefPtr) { + nextRefPtr = refPtr->nextPtr; + importCmd = (Tcl_Command) refPtr->importedCmdPtr; + Tcl_DeleteCommandFromToken(interp, importCmd); + } + } + if (cmdPtr->deleteProc != NULL) { /* * Delete the command's client data. If this was an imported command @@ -3567,20 +3580,6 @@ Tcl_DeleteCommandFromToken( } /* - * If this command was imported into other namespaces, then imported - * commands were created that refer back to this command. Delete these - * imported commands now. - */ - if (!(cmdPtr->flags & CMD_REDEF_IN_PROGRESS)) { - for (refPtr = cmdPtr->importRefPtr; refPtr != NULL; - refPtr = nextRefPtr) { - nextRefPtr = refPtr->nextPtr; - importCmd = (Tcl_Command) refPtr->importedCmdPtr; - Tcl_DeleteCommandFromToken(interp, importCmd); - } - } - - /* * Don't use hPtr to delete the hash entry here, because it's possible * that the deletion callback renamed the command. Instead, use * cmdPtr->hptr, and make sure that no-one else has already deleted the -- cgit v0.12 From e1968256d828d5f86f7ee09eaea945332df127b1 Mon Sep 17 00:00:00 2001 From: culler Date: Mon, 17 Aug 2020 15:53:04 +0000 Subject: Try to make io-50.6 more robust on the Travis macOS VM --- tests/io.test | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/tests/io.test b/tests/io.test index 685394c..016c6bd 100644 --- a/tests/io.test +++ b/tests/io.test @@ -6871,7 +6871,7 @@ test io-50.5 {testing handler deletion vs reentrant calls} -constraints {testcha } -cleanup { close $f } -result [list {del calling recursive} {del deleted notcalled} \ - {del deleted myself} {del after recursive}] + {del deleted myself} {del after recursive}] test io-50.6 {testing handler deletion vs reentrant calls} -constraints {testchannelevent testservicemode} -setup { file delete $path(test1) } -body { @@ -6880,6 +6880,7 @@ test io-50.6 {testing handler deletion vs reentrant calls} -constraints {testcha proc first {f} { variable u variable z + variable done if {"$u" == "toplevel"} { lappend z "first called" set u first @@ -6887,6 +6888,7 @@ test io-50.6 {testing handler deletion vs reentrant calls} -constraints {testcha vwait z after cancel $timer lappend z "first after toplevel" + set done 1 } else { lappend z "first called not toplevel" } @@ -6908,19 +6910,24 @@ test io-50.6 {testing handler deletion vs reentrant calls} -constraints {testcha } set z "" set u toplevel + set done 0 testservicemode 0 set f [open $path(test1) r] testchannelevent $f add readable [namespace code [list second $f]] testchannelevent $f add readable [namespace code [list first $f]] testservicemode 1 update + if {!$done} { + set $timer2 [after 200 lappend done timeout] + vwait done + after cancel timer2 + } set z } -cleanup { close $f } -result [list {first called} {first called not toplevel} \ {second called, first time} {second called, second time} \ {first after toplevel}] - test io-51.1 {Test old socket deletion on Macintosh} {socket} { set x 0 set result "" -- cgit v0.12 From 270c9b99d653dad45f98e06a5c503a6338479ac9 Mon Sep 17 00:00:00 2001 From: culler Date: Mon, 17 Aug 2020 16:21:05 +0000 Subject: Add the missing $. --- tests/io.test | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/io.test b/tests/io.test index 016c6bd..6e2c907 100644 --- a/tests/io.test +++ b/tests/io.test @@ -6920,7 +6920,7 @@ test io-50.6 {testing handler deletion vs reentrant calls} -constraints {testcha if {!$done} { set $timer2 [after 200 lappend done timeout] vwait done - after cancel timer2 + after cancel $timer2 } set z } -cleanup { -- cgit v0.12 From 6560454489df369db2c1edeaaf82a094efda0115 Mon Sep 17 00:00:00 2001 From: culler Date: Mon, 17 Aug 2020 16:28:28 +0000 Subject: And remove the other $ and do the test slightly differently. Inability to test locally is a challenge. --- tests/io.test | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/io.test b/tests/io.test index 6e2c907..18636c1 100644 --- a/tests/io.test +++ b/tests/io.test @@ -6918,7 +6918,7 @@ test io-50.6 {testing handler deletion vs reentrant calls} -constraints {testcha testservicemode 1 update if {!$done} { - set $timer2 [after 200 lappend done timeout] + set timer2 [after 200 set done 1] vwait done after cancel $timer2 } -- cgit v0.12 From 591c90cd3e7e44d16dc721a6b3d7a66c6746c2eb Mon Sep 17 00:00:00 2001 From: dgp Date: Fri, 21 Aug 2020 13:59:13 +0000 Subject: Suppress tests that fail starting with OSX Mojave. --- tests/socket.test | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/tests/socket.test b/tests/socket.test index 3544dd9..469367a 100644 --- a/tests/socket.test +++ b/tests/socket.test @@ -199,6 +199,8 @@ if {[testConstraint doTestsWithRemoteServer]} { } } +testConstraint notOSX [string compare $::tcl_platform(os) Darwin] + test socket-1.1 {arg parsing for socket command} {socket} { list [catch {socket -server} msg] $msg } {1 {no argument given for -server option}} @@ -816,7 +818,7 @@ test socket-4.2 {byte order problems, socket numbers, htons} {socket} { } ok test socket-5.1 {byte order problems, socket numbers, htons} \ - {socket unix notRoot} { + {socket unix notRoot notOSX} { set x {couldn't open socket: not owner} if {![catch {socket -server dodo 0x1} msg]} { set x {htons problem, should be disallowed, are you running as SU?} @@ -833,7 +835,7 @@ test socket-5.2 {byte order problems, socket numbers, htons} {socket} { set x } {couldn't open socket: port number too high} test socket-5.3 {byte order problems, socket numbers, htons} \ - {socket unix notRoot} { + {socket unix notRoot notOSX} { set x {couldn't open socket: not owner} if {![catch {socket -server dodo 21} msg]} { set x {htons problem, should be disallowed, are you running as SU?} -- cgit v0.12 From b2d5b24a704988578dfaa93e7cead7428be9ccbc Mon Sep 17 00:00:00 2001 From: "jan.nijtmans" Date: Mon, 24 Aug 2020 07:57:04 +0000 Subject: Upgrade Travis build from bionic to focal --- .travis.yml | 32 ++++++++++++++++---------------- 1 file changed, 16 insertions(+), 16 deletions(-) diff --git a/.travis.yml b/.travis.yml index 05c2f6a..dd86769 100644 --- a/.travis.yml +++ b/.travis.yml @@ -14,48 +14,48 @@ jobs: # Testing on Linux with various compilers - name: "Linux/GCC/Shared" os: linux - dist: bionic + dist: focal compiler: gcc env: - BUILD_DIR=unix - name: "Linux/GCC/Shared: UTF_MAX=4" os: linux - dist: bionic + dist: focal compiler: gcc env: - BUILD_DIR=unix - CFGOPT=CFLAGS=-DTCL_UTF_MAX=4 - name: "Linux/GCC/Shared: UTF_MAX=5" os: linux - dist: bionic + dist: focal compiler: gcc env: - BUILD_DIR=unix - CFGOPT=CFLAGS=-DTCL_UTF_MAX=5 - name: "Linux/GCC/Shared: UTF_MAX=6" os: linux - dist: bionic + dist: focal compiler: gcc env: - BUILD_DIR=unix - CFGOPT=CFLAGS=-DTCL_UTF_MAX=6 - name: "Linux/GCC/Static" os: linux - dist: bionic + dist: focal compiler: gcc env: - CFGOPT="--disable-shared" - BUILD_DIR=unix - name: "Linux/GCC/Debug" os: linux - dist: bionic + dist: focal compiler: gcc env: - BUILD_DIR=unix - CFGOPT="--enable-symbols" - name: "Linux/GCC/Mem-Debug" os: linux - dist: bionic + dist: focal compiler: gcc env: - BUILD_DIR=unix @@ -63,7 +63,7 @@ jobs: # Older versions of GCC... - name: "Linux/GCC 7/Shared" os: linux - dist: bionic + dist: focal compiler: gcc-7 addons: apt: @@ -75,7 +75,7 @@ jobs: - BUILD_DIR=unix - name: "Linux/GCC 6/Shared" os: linux - dist: bionic + dist: focal compiler: gcc-6 addons: apt: @@ -87,7 +87,7 @@ jobs: - BUILD_DIR=unix - name: "Linux/GCC 5/Shared" os: linux - dist: bionic + dist: focal compiler: gcc-5 addons: apt: @@ -100,27 +100,27 @@ jobs: # Clang - name: "Linux/Clang/Shared" os: linux - dist: bionic + dist: focal compiler: clang env: - BUILD_DIR=unix - name: "Linux/Clang/Static" os: linux - dist: bionic + dist: focal compiler: clang env: - CFGOPT="--disable-shared" - BUILD_DIR=unix - name: "Linux/Clang/Debug" os: linux - dist: bionic + dist: focal compiler: clang env: - BUILD_DIR=unix - CFGOPT="--enable-symbols" - name: "Linux/Clang/Mem-Debug" os: linux - dist: bionic + dist: focal compiler: clang env: - BUILD_DIR=unix @@ -174,7 +174,7 @@ jobs: # Doesn't run tests because wine is only an imperfect Windows emulation - name: "Linux-cross-Windows/GCC/Shared/no test" os: linux - dist: bionic + dist: focal compiler: x86_64-w64-mingw32-gcc env: - BUILD_DIR=win @@ -188,7 +188,7 @@ jobs: # Doesn't run tests because wine is only an imperfect Windows emulation - name: "Linux-cross-Windows-32/GCC/Shared/no test" os: linux - dist: bionic + dist: focal compiler: i686-w64-mingw32-gcc env: - BUILD_DIR=win -- cgit v0.12 From 5f4ef0229dcf7281043e2ece43b807f55ae0c461 Mon Sep 17 00:00:00 2001 From: "jan.nijtmans" Date: Mon, 24 Aug 2020 10:19:49 +0000 Subject: Backport improvemenets in .gitignore .fossil-settings/ignore-glob and win/nmakehlp.c --- .fossil-settings/ignore-glob | 4 ++ .gitignore | 3 + win/nmakehlp.c | 131 ++++++++++++++++++++++++++++++++++++++----- 3 files changed, 125 insertions(+), 13 deletions(-) diff --git a/.fossil-settings/ignore-glob b/.fossil-settings/ignore-glob index eca9bcd..651d616 100644 --- a/.fossil-settings/ignore-glob +++ b/.fossil-settings/ignore-glob @@ -1,9 +1,12 @@ *.a *.dll *.dylib +*.dylib.E *.exe *.exp +*.la *.lib +*.lo *.o *.obj *.pdb @@ -61,4 +64,5 @@ win/*.manifest win/pkgs/* win/coffbase.txt win/tcl.hpj +win/nmakehlp.out win/nmhlp-out.txt diff --git a/.gitignore b/.gitignore index 701419b..33579cf 100644 --- a/.gitignore +++ b/.gitignore @@ -2,6 +2,7 @@ *.bundle *.dll *.dylib +*.dylib.E *.exe *.exp *.lib @@ -14,6 +15,7 @@ .fslckout Makefile Tcl-Info.plist +Tclsh-Info.plist autom4te.cache config.cache config.log @@ -59,4 +61,5 @@ win/*.manifest win/pkgs/* win/coffbase.txt win/tcl.hpj +win/nmakehlp.out win/nmhlp-out.txt diff --git a/win/nmakehlp.c b/win/nmakehlp.c index 821d00b..7536ede 100644 --- a/win/nmakehlp.c +++ b/win/nmakehlp.c @@ -14,13 +14,8 @@ #define _CRT_SECURE_NO_DEPRECATE #include -#define NO_SHLWAPI_GDI -#define NO_SHLWAPI_STREAM -#define NO_SHLWAPI_REG -#include #pragma comment (lib, "user32.lib") #pragma comment (lib, "kernel32.lib") -#pragma comment (lib, "shlwapi.lib") #include #include @@ -46,6 +41,7 @@ static int CheckForLinkerFeature(const char **options, int count); static int IsIn(const char *string, const char *substring); static int SubstituteFile(const char *substs, const char *filename); static int QualifyPath(const char *path); +static int LocateDependency(const char *keyfile); static const char *GetVersionFromFile(const char *filename, const char *match, int numdots); static DWORD WINAPI ReadFromPipe(LPVOID args); @@ -171,6 +167,18 @@ main( return 2; } return QualifyPath(argv[2]); + + case 'L': + if (argc != 3) { + chars = snprintf(msg, sizeof(msg) - 1, + "usage: %s -L keypath\n" + "Emit the fully qualified path of directory containing keypath\n" + "exitcodes: 0 == success, 1 == not found, 2 == error\n", argv[0]); + WriteFile(GetStdHandle(STD_ERROR_HANDLE), msg, chars, + &dwWritten, NULL); + return 2; + } + return LocateDependency(argv[2]); } } chars = snprintf(msg, sizeof(msg) - 1, @@ -635,7 +643,7 @@ SubstituteFile( } /* debug: dump the list */ -#ifdef _DEBUG +#ifndef NDEBUG { int n = 0; list_item_t *p = NULL; @@ -675,6 +683,17 @@ SubstituteFile( return 0; } +BOOL FileExists(LPCTSTR szPath) +{ +#ifndef INVALID_FILE_ATTRIBUTES + #define INVALID_FILE_ATTRIBUTES ((DWORD)-1) +#endif + DWORD pathAttr = GetFileAttributes(szPath); + return (pathAttr != INVALID_FILE_ATTRIBUTES && + !(pathAttr & FILE_ATTRIBUTE_DIRECTORY)); +} + + /* * QualifyPath -- * @@ -688,18 +707,104 @@ QualifyPath( const char *szPath) { char szCwd[MAX_PATH + 1]; - char szTmp[MAX_PATH + 1]; - char *p; - GetCurrentDirectory(MAX_PATH, szCwd); - while ((p = strchr(szPath, '/')) && *p) - *p = '\\'; - PathCombine(szTmp, szCwd, szPath); - PathCanonicalize(szCwd, szTmp); + + GetFullPathName(szPath, sizeof(szCwd)-1, szCwd, NULL); printf("%s\n", szCwd); return 0; } /* + * Implements LocateDependency for a single directory. See that command + * for an explanation. + * Returns 0 if found after printing the directory. + * Returns 1 if not found but no errors. + * Returns 2 on any kind of error + * Basically, these are used as exit codes for the process. + */ +static int LocateDependencyHelper(const char *dir, const char *keypath) +{ + HANDLE hSearch; + char path[MAX_PATH+1]; + int dirlen, keylen, ret; + WIN32_FIND_DATA finfo; + + if (dir == NULL || keypath == NULL) + return 2; /* Have no real error reporting mechanism into nmake */ + dirlen = strlen(dir); + if ((dirlen + 3) > sizeof(path)) + return 2; + strncpy(path, dir, dirlen); + strncpy(path+dirlen, "\\*", 3); /* Including terminating \0 */ + keylen = strlen(keypath); + +#if 0 /* This function is not available in Visual C++ 6 */ + /* + * Use numerics 0 -> FindExInfoStandard, + * 1 -> FindExSearchLimitToDirectories, + * as these are not defined in Visual C++ 6 + */ + hSearch = FindFirstFileEx(path, 0, &finfo, 1, NULL, 0); +#else + hSearch = FindFirstFile(path, &finfo); +#endif + if (hSearch == INVALID_HANDLE_VALUE) + return 1; /* Not found */ + + /* Loop through all subdirs checking if the keypath is under there */ + ret = 1; /* Assume not found */ + do { + int sublen; + /* + * We need to check it is a directory despite the + * FindExSearchLimitToDirectories in the above call. See SDK docs + */ + if ((finfo.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) == 0) + continue; + sublen = strlen(finfo.cFileName); + if ((dirlen+1+sublen+1+keylen+1) > sizeof(path)) + continue; /* Path does not fit, assume not matched */ + strncpy(path+dirlen+1, finfo.cFileName, sublen); + path[dirlen+1+sublen] = '\\'; + strncpy(path+dirlen+1+sublen+1, keypath, keylen+1); + if (FileExists(path)) { + /* Found a match, print to stdout */ + path[dirlen+1+sublen] = '\0'; + QualifyPath(path); + ret = 0; + break; + } + } while (FindNextFile(hSearch, &finfo)); + FindClose(hSearch); + return ret; +} + +/* + * LocateDependency -- + * + * Locates a dependency for a package. + * keypath - a relative path within the package directory + * that is used to confirm it is the correct directory. + * The search path for the package directory is currently only + * the parent and grandparent of the current working directory. + * If found, the command prints + * name_DIRPATH= + * and returns 0. If not found, does not print anything and returns 1. + */ +static int LocateDependency(const char *keypath) +{ + int i, ret; + static const char *paths[] = {"..", "..\\..", "..\\..\\.."}; + + for (i = 0; i < (sizeof(paths)/sizeof(paths[0])); ++i) { + ret = LocateDependencyHelper(paths[i], keypath); + if (ret == 0) + return ret; + } + return ret; +} + + +/* * Local variables: * mode: c * c-basic-offset: 4 -- cgit v0.12 From 0d23451993cbdb14bcb0cef73c5db4a979a23648 Mon Sep 17 00:00:00 2001 From: "jan.nijtmans" Date: Tue, 25 Aug 2020 09:42:37 +0000 Subject: Keep gcc-5 and gcc-6 builds on "bionic", because "focal" doesn't have these --- .travis.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.travis.yml b/.travis.yml index dd86769..ad3f03a 100644 --- a/.travis.yml +++ b/.travis.yml @@ -75,7 +75,7 @@ jobs: - BUILD_DIR=unix - name: "Linux/GCC 6/Shared" os: linux - dist: focal + dist: bionic compiler: gcc-6 addons: apt: @@ -87,7 +87,7 @@ jobs: - BUILD_DIR=unix - name: "Linux/GCC 5/Shared" os: linux - dist: focal + dist: bionic compiler: gcc-5 addons: apt: -- cgit v0.12 From 43d2fdc86c454dc83a6fe24125d0fd1188cc1bfa Mon Sep 17 00:00:00 2001 From: "jan.nijtmans" Date: Wed, 26 Aug 2020 14:52:42 +0000 Subject: Testcase chan-io-50.1 still fails sometimes on MacOSX. So put same measures in place as in io-50.1. See: [f586089a2b] --- tests/chanio.test | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/tests/chanio.test b/tests/chanio.test index 66f4a30..10f3624 100644 --- a/tests/chanio.test +++ b/tests/chanio.test @@ -6380,12 +6380,16 @@ test chan-io-50.1 {testing handler deletion} -setup { set f [open $path(test1) w] chan close $f set f [open $path(test1) r] + variable z not_called + set timer [after 50 lappend z timeout] + testservicemode 0 testchannelevent $f add readable [namespace code { variable z called testchannelevent $f delete 0 }] - variable z not_called - update + testservicemode 1 + vwait z + after cancel $timer set z } -cleanup { chan close $f -- cgit v0.12