From 3b3a5ff07f3a3dd2bff6de66c86bb2d3883d9aa6 Mon Sep 17 00:00:00 2001 From: dgp Date: Thu, 15 Feb 2018 17:24:40 +0000 Subject: Better range checking in "string index". Add test-case to prove point. This opens a large discussion on what the right valid range for index values should be and what overflow behavior should be. New branch opened to answer those questions completely. --- generic/tclUtil.c | 11 ++++++++++- tests/util.test | 6 ++++++ 2 files changed, 16 insertions(+), 1 deletion(-) diff --git a/generic/tclUtil.c b/generic/tclUtil.c index 9557aac..e90477f 100644 --- a/generic/tclUtil.c +++ b/generic/tclUtil.c @@ -3585,7 +3585,16 @@ TclGetIntForIndex( * be converted to one, use it. */ - *indexPtr = endValue + (int)objPtr->internalRep.wideValue; + Tcl_WideInt value = endValue + objPtr->internalRep.wideValue; + if (endValue > 0 && value < objPtr->internalRep.wideValue) { + *indexPtr = INT_MAX; /* numerical overflow */ + } else if (value < INT_MIN || (endValue < 0 && value > objPtr->internalRep.wideValue)) { + *indexPtr = INT_MIN; /* numerical underflow or value < INT_MIN */ + } else if (value > INT_MAX) { + *indexPtr = INT_MAX;/* value > INT_MAX */ + } else { + *indexPtr = (int) value; + } return TCL_OK; } diff --git a/tests/util.test b/tests/util.test index 35fc642..d186523 100644 --- a/tests/util.test +++ b/tests/util.test @@ -729,6 +729,12 @@ test util-9.43 {TclGetIntForIndex} -body { test util-9.44 {TclGetIntForIndex} -body { string index a 0+1000000000000 } -returnCodes error -match glob -result * +test util-9.45 {TclGetIntForIndex} { + string index abcd end+2305843009213693950 +} {} +test util-9.46 {TclGetIntForIndex} { + string index abcd end+4294967294 +} {} test util-10.1 {Tcl_PrintDouble - rounding} {ieeeFloatingPoint} { convertDouble 0x0000000000000000 -- cgit v0.12 From 544d338e0e4d28400ced022ca13ccf6355a2b423 Mon Sep 17 00:00:00 2001 From: dgp Date: Tue, 27 Feb 2018 13:13:11 +0000 Subject: Work In Progress on index value reform -- not working. --- generic/tclUtil.c | 78 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 78 insertions(+) diff --git a/generic/tclUtil.c b/generic/tclUtil.c index e90477f..f31df0c 100644 --- a/generic/tclUtil.c +++ b/generic/tclUtil.c @@ -15,6 +15,7 @@ #include "tclInt.h" #include "tclParse.h" #include "tclStringTrim.h" +#include "tommath.h" #include /* @@ -3560,6 +3561,67 @@ TclFormatInt( */ int +GetWideForIndex( + Tcl_Interp *interp, /* Interpreter to use for error reporting. If + * NULL, then no error message is left after + * errors. */ + Tcl_Obj *objPtr, /* Points to an object containing either "end" + * or an integer. */ + int endValue, /* The value to be stored at "indexPtr" if + * "objPtr" holds "end". */ + Tcl_WideInt *widePtr) /* Location filled in with a wide integer + * representing an index. */ +{ + int numType; + ClientData cd = NULL; + int code = TclGetNumberFromObj(NULL, objPtr, &cd, &numType); + + if (code == TCL_OK) { + if (numType == TCL_NUMBER_WIDE) { + /* objPtr holds an integer in the signed wide range */ + *widePtr = (Tcl_WideInt)(*(Tcl_WideInt *)cd); + return TCL_OK; + } + if (numType == TCL_NUMBER_BIG) { + /* objPtr holds an integer outside the signed wide range */ + mp_int big; + const Tcl_WideInt wideMax = ((~(Tcl_WideUInt)0) >> 1); + + Tcl_TakeBignumFromObj(NULL, objPtr, &big); + if (mp_cmp_d(&big, 0) == MP_LT) { + *widePtr = ~wideMax; + } else { + *widePtr = wideMax; + } + return TCL_OK; + } + + /* Must be a double -> not a valid index */ + goto parseError; + } + + /* objPtr does not hold a number, parse for other index formats */ + + + + /* Report a parse error. */ + parseError: + if (interp != NULL) { + char * bytes = TclGetString(objPtr); + Tcl_SetObjResult(interp, Tcl_ObjPrintf( + "bad index \"%s\": must be integer?[+-]integer? or" + " end?[+-]integer?", bytes)); + if (!strncmp(bytes, "end-", 4)) { + bytes += 4; + } + TclCheckBadOctal(interp, bytes); + Tcl_SetErrorCode(interp, "TCL", "VALUE", "INDEX", NULL); + } + + return TCL_ERROR; +} + +int TclGetIntForIndex( Tcl_Interp *interp, /* Interpreter to use for error reporting. If * NULL, then no error message is left after @@ -3571,6 +3633,21 @@ TclGetIntForIndex( int *indexPtr) /* Location filled in with an integer * representing an index. */ { +#if 1 + Tcl_WideInt wide; + + if (GetWideForIndex(interp, objPtr, endValue, &wide) == TCL_ERROR) { + return TCL_ERROR; + } + if (wide < INT_MIN) { + wide = INT_MIN; + } else if (wide > INT_MAX) { + wide = INT_MAX; + } + *indexPtr = (int) wide; + return TCL_OK; + +#else size_t length; char *opPtr; const char *bytes; @@ -3656,6 +3733,7 @@ TclGetIntForIndex( } return TCL_ERROR; +#endif } /* -- cgit v0.12 From e1efe253d236c463d01bc83d79b3f897e774cbee Mon Sep 17 00:00:00 2001 From: dgp Date: Tue, 27 Feb 2018 18:20:44 +0000 Subject: Much more progress expanding the vocabulary of index values, and getting results that make more intuitive sense. Still a few TODOs and tests to update. --- generic/tclUtil.c | 226 ++++++++++++++++++++++++++++-------------------------- 1 file changed, 119 insertions(+), 107 deletions(-) diff --git a/generic/tclUtil.c b/generic/tclUtil.c index f31df0c..8ef5dfc 100644 --- a/generic/tclUtil.c +++ b/generic/tclUtil.c @@ -18,6 +18,8 @@ #include "tommath.h" #include +const Tcl_WideInt wideMax = ((~(Tcl_WideUInt)0) >> 1); + /* * The absolute pathname of the executable in which this Tcl library is * running. @@ -3567,14 +3569,16 @@ GetWideForIndex( * errors. */ Tcl_Obj *objPtr, /* Points to an object containing either "end" * or an integer. */ - int endValue, /* The value to be stored at "indexPtr" if + Tcl_WideInt endValue, /* The value to be stored at "indexPtr" if * "objPtr" holds "end". */ Tcl_WideInt *widePtr) /* Location filled in with a wide integer * representing an index. */ { - int numType; + const char *opPtr; + int length; ClientData cd = NULL; - int code = TclGetNumberFromObj(NULL, objPtr, &cd, &numType); + int numType, code = TclGetNumberFromObj(NULL, objPtr, &cd, &numType); + if (code == TCL_OK) { if (numType == TCL_NUMBER_WIDE) { @@ -3584,11 +3588,9 @@ GetWideForIndex( } if (numType == TCL_NUMBER_BIG) { /* objPtr holds an integer outside the signed wide range */ - mp_int big; - const Tcl_WideInt wideMax = ((~(Tcl_WideUInt)0) >> 1); + mp_int *bigPtr = (mp_int *)cd; - Tcl_TakeBignumFromObj(NULL, objPtr, &big); - if (mp_cmp_d(&big, 0) == MP_LT) { + if (mp_cmp_d(bigPtr, 0) == MP_LT) { *widePtr = ~wideMax; } else { *widePtr = wideMax; @@ -3600,12 +3602,88 @@ GetWideForIndex( goto parseError; } - /* objPtr does not hold a number, parse for other index formats */ + /* objPtr does not hold a number, check the end+/- format... */ + + if (SetEndOffsetFromAny(NULL, objPtr) == TCL_OK) { + Tcl_WideInt offset = objPtr->internalRep.wideValue; + + if ((endValue ^ offset) < 0) { + /* Different signs, sum cannot overflow */ + *widePtr = endValue + offset; + } else if (endValue >= 0) { + if (endValue < wideMax - offset) { + *widePtr = endValue + offset; + } else { + *widePtr = wideMax; + } + } else { + if (endValue > ~wideMax - offset) { + *widePtr = endValue + offset; + } else { + *widePtr = ~wideMax; + } + } + return TCL_OK; + } + + if (TCL_OK == Tcl_ListObjLength(NULL, objPtr, &length) && (length > 1)) { + goto parseError; + } + /* check the index arithmetic format... */ + if (TCL_OK == TclParseNumber(NULL, objPtr, NULL, NULL, -1, &opPtr, + TCL_PARSE_INTEGER_ONLY)) { + if ((*opPtr != '-') && (*opPtr != '+')) { + goto parseError; + } + TclGetNumberFromObj(NULL, objPtr, &cd, &numType); + if (numType == TCL_NUMBER_WIDE) { + Tcl_WideInt w1 = (*(Tcl_WideInt *)cd); + + if (TCL_OK == TclParseNumber(NULL, objPtr, NULL, opPtr+1, -1, + NULL, TCL_PARSE_INTEGER_ONLY)) { + TclGetNumberFromObj(NULL, objPtr, &cd, &numType); + if (numType == TCL_NUMBER_WIDE) { + Tcl_WideInt w2 = (*(Tcl_WideInt *)cd); + + TclFreeIntRep(objPtr); + if (*opPtr == '-') { + if (w2 == ~wideMax) { + /* TODO: need bignum */ + goto parseError; + } + w2 = -w2; + } + if ((w1 ^ w2) < 0) { + *widePtr = w1 + w2; + } else if (w1 >= 0) { + if (w1 < wideMax - w2) { + *widePtr = w1 + w2; + } else { + *widePtr = wideMax; + } + } else { + if (w1 > ~wideMax - w2) { + *widePtr = w1 + w2; + } else { + *widePtr = ~wideMax; + } + } + return TCL_OK; + } + /* TODO: 2d half is bignum */ + goto parseError; + } + goto parseError; + } + /* TODO: 1st half is bignum */ + goto parseError; + } /* Report a parse error. */ parseError: + TclFreeIntRep(objPtr); if (interp != NULL) { char * bytes = TclGetString(objPtr); Tcl_SetObjResult(interp, Tcl_ObjPrintf( @@ -3633,7 +3711,6 @@ TclGetIntForIndex( int *indexPtr) /* Location filled in with an integer * representing an index. */ { -#if 1 Tcl_WideInt wide; if (GetWideForIndex(interp, objPtr, endValue, &wide) == TCL_ERROR) { @@ -3646,94 +3723,6 @@ TclGetIntForIndex( } *indexPtr = (int) wide; return TCL_OK; - -#else - size_t length; - char *opPtr; - const char *bytes; - - if (TclGetIntFromObj(NULL, objPtr, indexPtr) == TCL_OK) { - return TCL_OK; - } - - if (SetEndOffsetFromAny(NULL, objPtr) == TCL_OK) { - /* - * If the object is already an offset from the end of the list, or can - * be converted to one, use it. - */ - - Tcl_WideInt value = endValue + objPtr->internalRep.wideValue; - if (endValue > 0 && value < objPtr->internalRep.wideValue) { - *indexPtr = INT_MAX; /* numerical overflow */ - } else if (value < INT_MIN || (endValue < 0 && value > objPtr->internalRep.wideValue)) { - *indexPtr = INT_MIN; /* numerical underflow or value < INT_MIN */ - } else if (value > INT_MAX) { - *indexPtr = INT_MAX;/* value > INT_MAX */ - } else { - *indexPtr = (int) value; - } - return TCL_OK; - } - - bytes = TclGetString(objPtr); - length = objPtr->length; - - /* - * Leading whitespace is acceptable in an index. - */ - - while (length && TclIsSpaceProc(*bytes)) { - bytes++; - length--; - } - - if (TclParseNumber(NULL, NULL, NULL, bytes, length, (const char **)&opPtr, - TCL_PARSE_INTEGER_ONLY | TCL_PARSE_NO_WHITESPACE) == TCL_OK) { - int code, first, second; - char savedOp = *opPtr; - - if ((savedOp != '+') && (savedOp != '-')) { - goto parseError; - } - if (TclIsSpaceProc(opPtr[1])) { - goto parseError; - } - *opPtr = '\0'; - code = Tcl_GetInt(interp, bytes, &first); - *opPtr = savedOp; - if (code == TCL_ERROR) { - goto parseError; - } - if (TCL_ERROR == Tcl_GetInt(interp, opPtr+1, &second)) { - goto parseError; - } - if (savedOp == '+') { - *indexPtr = first + second; - } else { - *indexPtr = first - second; - } - return TCL_OK; - } - - /* - * Report a parse error. - */ - - parseError: - if (interp != NULL) { - bytes = TclGetString(objPtr); - Tcl_SetObjResult(interp, Tcl_ObjPrintf( - "bad index \"%s\": must be integer?[+-]integer? or" - " end?[+-]integer?", bytes)); - if (!strncmp(bytes, "end-", 4)) { - bytes += 4; - } - TclCheckBadOctal(interp, bytes); - Tcl_SetErrorCode(interp, "TCL", "VALUE", "INDEX", NULL); - } - - return TCL_ERROR; -#endif } /* @@ -3809,18 +3798,22 @@ SetEndOffsetFromAny( } /* + * Multi-element lists cannot be permitted. Would confuse a single + * index of end[+-]$integer format with list of indices + */ + + if (TCL_OK == Tcl_ListObjLength(NULL, objPtr, &length) && (length > 1)) { + goto badIndexFormat; + } + + /* * Check for a string rep of the right form. */ bytes = TclGetStringFromObj(objPtr, &length); if ((*bytes != 'e') || (strncmp(bytes, "end", (size_t)((length > 3) ? 3 : length)) != 0)) { - if (interp != NULL) { - Tcl_SetObjResult(interp, Tcl_ObjPrintf( - "bad index \"%s\": must be end?[+-]integer?", bytes)); - Tcl_SetErrorCode(interp, "TCL", "VALUE", "INDEX", NULL); - } - return TCL_ERROR; + goto badIndexFormat; } /* @@ -3834,6 +3827,8 @@ SetEndOffsetFromAny( * This is our limited string expression evaluator. Pass everything * after "end-" to TclParseNumber. */ + int numType; + ClientData cd; if (TclIsSpaceProc(bytes[4])) { goto badIndexFormat; @@ -3842,12 +3837,28 @@ SetEndOffsetFromAny( TCL_PARSE_INTEGER_ONLY) != TCL_OK) { return TCL_ERROR; } - if (objPtr->typePtr != &tclIntType) { - goto badIndexFormat; + TclGetNumberFromObj(NULL, objPtr, &cd, &numType); + if (numType == TCL_NUMBER_BIG) { + /* objPtr holds an integer outside the signed wide range */ + mp_int *bigPtr = (mp_int *)cd; + + if (mp_cmp_d(bigPtr, 0) == MP_LT) { + offset = ~wideMax; + } else { + offset = wideMax; + } + } else if (numType == TCL_NUMBER_WIDE) { + offset = (*(Tcl_WideInt *)cd); + } else { + /* Can't happen? */ + goto badIndexFormat; } - offset = objPtr->internalRep.wideValue; if (bytes[3] == '-') { - offset = -offset; + if (offset == ~wideMax) { + offset = wideMax; + } else { + offset = -offset; + } } } else { /* @@ -3856,6 +3867,7 @@ SetEndOffsetFromAny( badIndexFormat: if (interp != NULL) { + bytes = TclGetStringFromObj(objPtr, &length); Tcl_SetObjResult(interp, Tcl_ObjPrintf( "bad index \"%s\": must be end?[+-]integer?", bytes)); Tcl_SetErrorCode(interp, "TCL", "VALUE", "INDEX", NULL); -- cgit v0.12 From 3607c177d947f19065109ff79d751cd5e303bfe5 Mon Sep 17 00:00:00 2001 From: dgp Date: Tue, 27 Feb 2018 22:35:24 +0000 Subject: Don't save indices with values outside the int range in bytecode. --- generic/tclCompCmdsGR.c | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/generic/tclCompCmdsGR.c b/generic/tclCompCmdsGR.c index ff5495c..a4c5a96 100644 --- a/generic/tclCompCmdsGR.c +++ b/generic/tclCompCmdsGR.c @@ -55,13 +55,21 @@ GetIndexFromToken( { Tcl_Obj *tmpObj = Tcl_NewObj(); int result, idx; + Tcl_WideInt wide; if (!TclWordKnownAtCompileTime(tokenPtr, tmpObj)) { Tcl_DecrRefCount(tmpObj); return TCL_ERROR; } - result = TclGetIntFromObj(NULL, tmpObj, &idx); + result = TclGetWideIntFromObj(NULL, tmpObj, &wide); + if (wide < INT_MIN) { + idx = INT_MIN; + } else if (wide > INT_MAX) { + idx = INT_MAX; + } else { + idx = (int) wide; + } if (result == TCL_OK) { if (idx < 0) { result = TCL_ERROR; -- cgit v0.12 From 221f1bc18e15cdf5247d4d7c7f97def268404000 Mon Sep 17 00:00:00 2001 From: dgp Date: Wed, 28 Feb 2018 13:40:36 +0000 Subject: Use mp_isneg() as appropriate. --- generic/tclUtil.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/generic/tclUtil.c b/generic/tclUtil.c index a721497..3fe2c32 100644 --- a/generic/tclUtil.c +++ b/generic/tclUtil.c @@ -3593,7 +3593,7 @@ GetWideForIndex( /* objPtr holds an integer outside the signed wide range */ mp_int *bigPtr = (mp_int *)cd; - if (mp_cmp_d(bigPtr, 0) == MP_LT) { + if (mp_isneg(bigPtr)) { *widePtr = ~wideMax; } else { *widePtr = wideMax; @@ -3808,7 +3808,7 @@ SetEndOffsetFromAny( /* objPtr holds an integer outside the signed wide range */ mp_int *bigPtr = (mp_int *)cd; - if (mp_cmp_d(bigPtr, 0) == MP_LT) { + if (mp_isneg(bigPtr)) { offset = ~wideMax; } else { offset = wideMax; -- cgit v0.12 From 0cb6effe147ce8a5933976d0f99edfc1ca6acdbf Mon Sep 17 00:00:00 2001 From: dgp Date: Thu, 1 Mar 2018 04:19:37 +0000 Subject: Continue consistent use of LLONG_MIN and LLONG_MAX. --- generic/tclUtil.c | 32 +++++++++++++++----------------- 1 file changed, 15 insertions(+), 17 deletions(-) diff --git a/generic/tclUtil.c b/generic/tclUtil.c index 3fe2c32..8afba01 100644 --- a/generic/tclUtil.c +++ b/generic/tclUtil.c @@ -18,8 +18,6 @@ #include "tommath.h" #include -const Tcl_WideInt wideMax = ((~(Tcl_WideUInt)0) >> 1); - /* * The absolute pathname of the executable in which this Tcl library is * running. @@ -3594,9 +3592,9 @@ GetWideForIndex( mp_int *bigPtr = (mp_int *)cd; if (mp_isneg(bigPtr)) { - *widePtr = ~wideMax; + *widePtr = LLONG_MIN; } else { - *widePtr = wideMax; + *widePtr = LLONG_MAX; } return TCL_OK; } @@ -3614,16 +3612,16 @@ GetWideForIndex( /* Different signs, sum cannot overflow */ *widePtr = endValue + offset; } else if (endValue >= 0) { - if (endValue < wideMax - offset) { + if (endValue < LLONG_MAX - offset) { *widePtr = endValue + offset; } else { - *widePtr = wideMax; + *widePtr = LLONG_MAX; } } else { - if (endValue > ~wideMax - offset) { + if (endValue > LLONG_MIN - offset) { *widePtr = endValue + offset; } else { - *widePtr = ~wideMax; + *widePtr = LLONG_MIN; } } return TCL_OK; @@ -3651,7 +3649,7 @@ GetWideForIndex( TclFreeIntRep(objPtr); if (*opPtr == '-') { - if (w2 == ~wideMax) { + if (w2 == LLONG_MIN) { /* TODO: need bignum */ goto parseError; } @@ -3661,16 +3659,16 @@ GetWideForIndex( if ((w1 ^ w2) < 0) { *widePtr = w1 + w2; } else if (w1 >= 0) { - if (w1 < wideMax - w2) { + if (w1 < LLONG_MAX - w2) { *widePtr = w1 + w2; } else { - *widePtr = wideMax; + *widePtr = LLONG_MAX; } } else { - if (w1 > ~wideMax - w2) { + if (w1 > LLONG_MIN - w2) { *widePtr = w1 + w2; } else { - *widePtr = ~wideMax; + *widePtr = LLONG_MIN; } } return TCL_OK; @@ -3809,9 +3807,9 @@ SetEndOffsetFromAny( mp_int *bigPtr = (mp_int *)cd; if (mp_isneg(bigPtr)) { - offset = ~wideMax; + offset = LLONG_MIN; } else { - offset = wideMax; + offset = LLONG_MAX; } } else if (numType == TCL_NUMBER_WIDE) { offset = (*(Tcl_WideInt *)cd); @@ -3820,8 +3818,8 @@ SetEndOffsetFromAny( goto badIndexFormat; } if (bytes[3] == '-') { - if (offset == ~wideMax) { - offset = wideMax; + if (offset == LLONG_MIN) { + offset = LLONG_MAX; } else { offset = -offset; } -- cgit v0.12 From 40dfdbd9290c1863d245b2cb1fb6e0c9f4ed1d33 Mon Sep 17 00:00:00 2001 From: dgp Date: Thu, 1 Mar 2018 19:30:15 +0000 Subject: Avoid full list conversion when we can cheaply discover a multi-element list is not possible. --- generic/tclUtil.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/generic/tclUtil.c b/generic/tclUtil.c index 8afba01..b7faa33 100644 --- a/generic/tclUtil.c +++ b/generic/tclUtil.c @@ -3627,7 +3627,9 @@ GetWideForIndex( return TCL_OK; } - if (TCL_OK == Tcl_ListObjLength(NULL, objPtr, &length) && (length > 1)) { + if ((TclMaxListLength(TclGetString(objPtr), -1, NULL) > 1) + && (TCL_OK == Tcl_ListObjLength(NULL, objPtr, &length)) + && (length > 1)) { goto parseError; } -- cgit v0.12 From 351c77bca3c16380aa5ce476fb96848e0fa63665 Mon Sep 17 00:00:00 2001 From: dgp Date: Tue, 24 Apr 2018 14:02:49 +0000 Subject: silence compiler warning --- generic/tclUtil.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/generic/tclUtil.c b/generic/tclUtil.c index 1890acd..b637a52 100644 --- a/generic/tclUtil.c +++ b/generic/tclUtil.c @@ -3691,7 +3691,6 @@ GetWideForIndex( * representing an index. */ { ClientData cd; - Tcl_WideInt w1, w2; const char *opPtr; int numType, length, t1 = 0, t2 = 0; int code = TclGetNumberFromObj(NULL, objPtr, &cd, &numType); @@ -3745,6 +3744,8 @@ GetWideForIndex( /* Passed the list screen, so parse for index arithmetic expression */ if (TCL_OK == TclParseNumber(NULL, objPtr, NULL, NULL, -1, &opPtr, TCL_PARSE_INTEGER_ONLY)) { + Tcl_WideInt w1=0, w2=0; + /* value starts with valid integer... */ if ((*opPtr == '-') || (*opPtr == '+')) { -- cgit v0.12 From bbdb1f12a0518cfc2a81cd7ec057703ca92e0ffe Mon Sep 17 00:00:00 2001 From: dgp Date: Tue, 9 Oct 2018 18:24:57 +0000 Subject: Use the 4 argument form of [makeFile]. --- tests/winPipe.test | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/tests/winPipe.test b/tests/winPipe.test index 3c051b0..2f59e96 100644 --- a/tests/winPipe.test +++ b/tests/winPipe.test @@ -323,8 +323,9 @@ proc _testExecArgs {single args} { lappend cmds [list $path(echoArgs.bat)] } else { if {![info exists path(echoArgs2.bat)] || ![file exists $path(echoArgs2.bat)]} { - set path(echoArgs2.bat) [makeFile "@[file native [interpreter]] $path(echoArgs.tcl) %*" \ - "[makeDirectory test(Dir)Check]/echo(Cmd)Test Args & Batch.bat"] + set path(echoArgs2.bat) [makeFile \ + "@[file native [interpreter]] $path(echoArgs.tcl) %*" \ + "echo(Cmd)Test Args & Batch.bat" [makeDirectory test(Dir)Check]] } lappend cmds [list $path(echoArgs2.bat)] } -- cgit v0.12 From 45e6ca04f5132d1f57cee45a475fe1d8371de5e9 Mon Sep 17 00:00:00 2001 From: dkf Date: Fri, 12 Oct 2018 07:36:19 +0000 Subject: Document [zipfs canonical] and add examples of how to use passwords. --- doc/zipfs.n | 30 ++++++++++++++++++++++++++++-- generic/tclZipfs.c | 10 +++++----- 2 files changed, 33 insertions(+), 7 deletions(-) diff --git a/doc/zipfs.n b/doc/zipfs.n index 99ab1d3..6e3d6ff 100644 --- a/doc/zipfs.n +++ b/doc/zipfs.n @@ -16,6 +16,7 @@ zipfs \- Mount and work with ZIP files within Tcl .nf \fBpackage require zipfs \fR?\fB1.0\fR? .sp +\fBzipfs canonical\fR ?\fImntpnt\fR? \fIfilename\fR ?\fIZIPFS\fR? \fBzipfs exists\fR \fIfilename\fR \fBzipfs find\fR \fIdirectoryName\fR \fBzipfs info\fR \fIfilename\fR @@ -28,7 +29,6 @@ zipfs \- Mount and work with ZIP files within Tcl \fBzipfs unmount\fR \fImountpoint\fR .fi '\" The following subcommands are *UNDOCUMENTED* (the list here is not documentation) -'\" \fBzipfs canonical\fR ?\fImntpnt\fR? \fIfilename\fR ?\fIZIPFS\fR? '\" \fBzipfs lmkimg\fR \fIoutfile inlist\fR ?\fIpassword infile\fR? '\" \fBzipfs lmkzip\fR \fIoutfile inlist\fR ?\fIpassword\fR? '\" \fBzipfs mount_data\fR ?\fImountpoint\fR? ?\fIdata\fR? @@ -38,7 +38,17 @@ zipfs \- Mount and work with ZIP files within Tcl .PP The \fBzipfs\fR command (the sole public command provided by the built-in package with the same name) provides Tcl with the ability to mount the -contents of a ZIP file as a virtual file system. +contents of a ZIP archive file as a virtual file system. ZIP archives support +simple encryption, sufficient to prevent casual inspection of their contents +but not able to prevent access by even a moderately determined attacker. +.TP +\fBzipfs canonical\fR ?\fImountpoint\fR? \fIfilename\fR ?\fIinZipfs\fR? +. +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. .TP \fBzipfs exists\fR \fIfilename\fR . @@ -175,6 +185,22 @@ set targetZip myApp.zip \fBzipfs mkzip\fR $targetZip $sourceDirectory $sourceDirectory .CE +.PP +Encryption can be applied to ZIP archives by providing a password when +building the ZIP and when mounting it. +.PP +.CS +set zip myApp.zip +set sourceDir [file normalize myApp] +set password "hunter2" +set base [file join [\fbzipfs root\fR] myApp] + +# Create with password +\fBzipfs mkzip\fR $targetZip $sourceDir $sourceDir $password + +# Mount with password +\fBzipfs mount\fR $base $zip $password +.CE '\" WANTED: How to use the passwords '\" WANTED: How to package an application .SH "SEE ALSO" diff --git a/generic/tclZipfs.c b/generic/tclZipfs.c index c9b1a63..7802c45 100644 --- a/generic/tclZipfs.c +++ b/generic/tclZipfs.c @@ -183,7 +183,7 @@ static const char drvletters[] = * Mutex to protect localtime(3) when no reentrant version available. */ -#if !defined(_WIN32) && !defined(HAVE_LOCALTIME_R) && TCL_THREADS +#if !defined(_WIN32) && !defined(HAVE_LOCALTIME_R) && inZipfsTCL_THREADS TCL_DECLARE_MUTEX(localtimeMutex) #endif /* !_WIN32 && !HAVE_LOCALTIME_R && TCL_THREADS */ @@ -665,7 +665,7 @@ CanonicalPath( const char *root, const char *tail, Tcl_DString *dsPtr, - int ZIPFSPATH) + int inZipfs) { char *path; int i, j, c, isUNC = 0, isVfs = 0, n = 0; @@ -742,7 +742,7 @@ CanonicalPath( memcpy(path, tail, j); break; default: - if (ZIPFSPATH) { + if (inZipfs) { Tcl_DStringSetLength(dsPtr, i + j + ZIPFS_VOLUME_LEN); path = Tcl_DStringValue(dsPtr); memcpy(path, ZIPFS_VOLUME, ZIPFS_VOLUME_LEN); @@ -765,7 +765,7 @@ CanonicalPath( } #endif /* _WIN32 */ - if (ZIPFSPATH) { + if (inZipfs) { n = ZIPFS_VOLUME_LEN; } else { n = 0; @@ -2911,7 +2911,7 @@ ZipFSCanonicalObjCmd( Tcl_DString dPath; if (objc < 2 || objc > 4) { - Tcl_WrongNumArgs(interp, 1, objv, "?mntpnt? filename ?ZIPFS?"); + Tcl_WrongNumArgs(interp, 1, objv, "?mountpoint? filename ?inZipfs?"); return TCL_ERROR; } Tcl_DStringInit(&dPath); -- cgit v0.12 From 13e35220c21ac2798f32b53f4e052014b17e4f4b Mon Sep 17 00:00:00 2001 From: dkf Date: Fri, 12 Oct 2018 09:52:56 +0000 Subject: Better document how to package an executable script in a zipfs --- doc/zipfs.n | 38 +++++++++++++++++++++++++++++++++++--- 1 file changed, 35 insertions(+), 3 deletions(-) diff --git a/doc/zipfs.n b/doc/zipfs.n index 6e3d6ff..d82b4d3 100644 --- a/doc/zipfs.n +++ b/doc/zipfs.n @@ -135,6 +135,13 @@ the ZIP archive, otherwise the file returned by \fBinfo nameofexecutable\fR output file and the contents of the ZIP chunk are protected with that password. .PP +If there is a file, \fBmain.tcl\fR, in the root directory of the resulting +archive and the image file that the archive is attached to is a \fBtclsh\fR +(or \fBwish\fR) instance (true by default, but depends on your configuration), +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 \fBCaution:\fR highly experimental, not usable on Android, only partially tested on Linux and Windows. .RE @@ -167,10 +174,10 @@ set zip myApp.zip set base [file join [\fbzipfs root\fR] myApp] \fBzipfs mount\fR $base $zip -\fI# $base now has the contents of myApp.zip\fR +# $base now has the contents of myApp.zip source [file join $base app.tcl] -\fI# use the contents, load libraries from it, etc...\fR +# use the contents, load libraries from it, etc... \fBzipfs unmount\fR $zip .CE @@ -201,10 +208,35 @@ set base [file join [\fbzipfs root\fR] myApp] # Mount with password \fBzipfs mount\fR $base $zip $password .CE +.PP +When creating an executable image with a password, the password is placed +within the executable in a shrouded form so that the application can read +files inside the embedded ZIP archive yet casual inspection cannot read it. +.PP +.CS +set appDir [file normalize myApp] +set img "myApp.bin" +set password "hunter2" + +# Create some simple content to define a basic application +file mkdir $appDir +set f [open $appDir/main.tcl] +puts $f { + puts "Hi. This is [info script]" +} +close $f + +# Create the executable +\fBzipfs mkimg\fR $img $appDir $appDir $password + +# Launch the executable, printing its output to stdout +exec $img >@stdout +# prints: \fI Hi. This is //zipfs:/app/main.tcl\fR +.CE '\" WANTED: How to use the passwords '\" WANTED: How to package an application .SH "SEE ALSO" -tclsh(1), file(n), zlib(n) +tclsh(1), file(n), zipfs(3), zlib(n) .SH "KEYWORDS" compress, filesystem, zip '\" Local Variables: -- cgit v0.12 From 621251ae2e2fd50bbee979906ce537aae53f1e33 Mon Sep 17 00:00:00 2001 From: dkf Date: Fri, 12 Oct 2018 12:07:13 +0000 Subject: Added docs for [zipfs lmkimg] and [zipfs lmkzip] --- doc/zipfs.n | 46 ++++++++++++++++++++++++++++++---------------- 1 file changed, 30 insertions(+), 16 deletions(-) diff --git a/doc/zipfs.n b/doc/zipfs.n index d82b4d3..9ed136d 100644 --- a/doc/zipfs.n +++ b/doc/zipfs.n @@ -21,6 +21,8 @@ zipfs \- Mount and work with ZIP files within Tcl \fBzipfs find\fR \fIdirectoryName\fR \fBzipfs info\fR \fIfilename\fR \fBzipfs list\fR ?(\fB\-glob\fR|\fB\-regexp\fR)? ?\fIpattern\fR? +\fBzipfs lmkimg\fR \fIoutfile inlist\fR ?\fIpassword infile\fR? +\fBzipfs lmkzip\fR \fIoutfile inlist\fR ?\fIpassword\fR? \fBzipfs mkimg\fR \fIoutfile indir\fR ?\fIstrip\fR? ?\fIpassword\fR? ?\fIinfile\fR? \fBzipfs mkkey\fR \fIpassword\fR \fBzipfs mkzip\fR \fIoutfile indir\fR ?\fIstrip\fR? ?\fIpassword\fR? @@ -29,8 +31,6 @@ zipfs \- Mount and work with ZIP files within Tcl \fBzipfs unmount\fR \fImountpoint\fR .fi '\" The following subcommands are *UNDOCUMENTED* (the list here is not documentation) -'\" \fBzipfs lmkimg\fR \fIoutfile inlist\fR ?\fIpassword infile\fR? -'\" \fBzipfs lmkzip\fR \fIoutfile inlist\fR ?\fIpassword\fR? '\" \fBzipfs mount_data\fR ?\fImountpoint\fR? ?\fIdata\fR? '\" \fBzipfs tcl_library\fR .BE @@ -120,11 +120,25 @@ Unmounts a previously mounted ZIP archive mounted to \fImountpoint\fR. This package also provides several commands to aid the creation of ZIP archives as Tcl applications. .TP +\fBzipfs mkzip\fR \fIoutfile indir\fR ?\fIstrip\fR? ?\fIpassword\fR? +. +Creates a ZIP archive file named \fIoutfile\fR from the contents of the input +directory \fIindir\fR (contained regular files only) with optional ZIP +password \fIpassword\fR. While processing the files below \fIindir\fR the +optional file name prefix given in \fIstrip\fR is stripped off the beginning +of the respective file name. When stripping, it is common to remove either +the whole source directory name or the name of its parent directory. +.RS +.PP +\fBCaution:\fR the choice of the \fIindir\fR parameter (less the optional +stripped prefix) determines the later root name of the archive's content. +.RE +.TP \fBzipfs mkimg\fR \fIoutfile indir\fR ?\fIstrip\fR? ?\fIpassword\fR? ?\fIinfile\fR? . Creates an image (potentially a new executable file) similar to \fBzipfs -mkzip\fR; see that subcommand for a description of most parameters to this -subcommand, as they behave identically here. +mkzip\fR; see that command for a description of most parameters to this +command, as they behave identically here. .RS .PP If the \fIinfile\fR parameter is specified, this file is prepended in front of @@ -151,19 +165,19 @@ tested on Linux and Windows. Given the clear text \fIpassword\fR argument, an obfuscated string version is returned with the same format used in the \fBzipfs mkimg\fR command. .TP -\fBzipfs mkzip\fR \fIoutfile indir\fR ?\fIstrip\fR? ?\fIpassword\fR? +\fBzipfs lmkimg\fR \fIoutfile inlist\fR ?\fIpassword infile\fR? . -Creates a ZIP archive file named \fIoutfile\fR from the contents of the input -directory \fIindir\fR (contained regular files only) with optional ZIP -password \fIpassword\fR. While processing the files below \fIindir\fR the -optional file name prefix given in \fIstrip\fR is stripped off the beginning -of the respective file name. When stripping, it is common to remove either -the whole source directory name or the name of its parent directory. -.RS -.PP -\fBCaution:\fR the choice of the \fIindir\fR parameter (less the optional -stripped prefix) determines the later root name of the archive's content. -.RE +This command is like \fBzipfs mkimg\fR, but instead of an input directory, +\fIinlist\fR must be a Tcl list where the odd elements are the names of files +to be copied into the archive in the image, and the even elements are their +respective names within that archive. +.TP +\fBzipfs lmkzip\fR \fIoutfile inlist\fR ?\fIpassword\fR? +. +This command is like \fBzipfs mkzip\fR, but instead of an input directory, +\fIinlist\fR must be a Tcl list where the odd elements are the names of files +to be copied into the archive, and the even elements are their respective +names within that archive. .SH "EXAMPLES" .PP Mounting an ZIP archive as an application directory and running code out of it -- cgit v0.12 From cc945fabb73c3733169f7441140a7b2f2c57572c Mon Sep 17 00:00:00 2001 From: "jan.nijtmans" Date: Fri, 12 Oct 2018 17:54:42 +0000 Subject: Fix test for UNICODE in win/tclAppInit.c. No longer check for "tclsh install", because tclsh is not compiled with that. Fix minizip.c compilation on systems without open64() --- compat/zlib/contrib/minizip/minizip.c | 4 +- generic/tclZipfs.c | 2 +- generic/tclZlib.c | 6 +-- unix/Makefile.in | 5 ++- unix/configure | 71 ++++++++++++++--------------------- unix/tcl.m4 | 67 ++++++++++++++------------------- win/Makefile.in | 5 ++- win/configure | 69 +++++++++++++--------------------- win/tcl.m4 | 67 ++++++++++++++------------------- win/tclAppInit.c | 2 +- 10 files changed, 124 insertions(+), 174 deletions(-) diff --git a/compat/zlib/contrib/minizip/minizip.c b/compat/zlib/contrib/minizip/minizip.c index b5c67cc..17582d0 100644 --- a/compat/zlib/contrib/minizip/minizip.c +++ b/compat/zlib/contrib/minizip/minizip.c @@ -27,7 +27,7 @@ #endif #endif -#ifdef __APPLE__ +#if defined(__APPLE__) || defined(IOAPI_NO_64) // In darwin and perhaps other BSD variants off_t is a 64 bit value, hence no need for specific 64 bit functions #define FOPEN_FUNC(filename, mode) fopen(filename, mode) #define FTELLO_FUNC(stream) ftello(stream) @@ -359,7 +359,7 @@ void addFileToZip(zipFile zf, const char *filenameinzip, const char *password, i void addPathToZip(zipFile zf, const char *filenameinzip, const char *password, int opt_exclude_path,int opt_compress_level) { tinydir_dir dir; int i; - char *newname[512]; + char newname[512]; tinydir_open_sorted(&dir, filenameinzip); diff --git a/generic/tclZipfs.c b/generic/tclZipfs.c index 7802c45..bd2ae13 100644 --- a/generic/tclZipfs.c +++ b/generic/tclZipfs.c @@ -183,7 +183,7 @@ static const char drvletters[] = * Mutex to protect localtime(3) when no reentrant version available. */ -#if !defined(_WIN32) && !defined(HAVE_LOCALTIME_R) && inZipfsTCL_THREADS +#if !defined(_WIN32) && !defined(HAVE_LOCALTIME_R) && TCL_THREADS TCL_DECLARE_MUTEX(localtimeMutex) #endif /* !_WIN32 && !HAVE_LOCALTIME_R && TCL_THREADS */ diff --git a/generic/tclZlib.c b/generic/tclZlib.c index 9bad36d..d4a8ecb 100644 --- a/generic/tclZlib.c +++ b/generic/tclZlib.c @@ -117,7 +117,7 @@ typedef struct { z_stream outStream; /* Structure used by zlib for compression of * output. */ char *inBuffer, *outBuffer; /* Working buffers. */ - int inAllocated, outAllocated; + size_t inAllocated, outAllocated; /* Sizes of working buffers. */ GzipHeader inHeader; /* Header read from input stream, when * decompressing a gzip stream. */ @@ -1515,7 +1515,7 @@ Tcl_ZlibStreamGet( Tcl_ListObjIndex(NULL, zshPtr->outData, 0, &itemObj); itemPtr = Tcl_GetByteArrayFromObj(itemObj, &itemLen); if (itemLen-zshPtr->outPos >= count-dataPos) { - unsigned len = count - dataPos; + size_t len = count - dataPos; memcpy(dataPtr + dataPos, itemPtr + zshPtr->outPos, len); zshPtr->outPos += len; @@ -1524,7 +1524,7 @@ Tcl_ZlibStreamGet( zshPtr->outPos = 0; } } else { - unsigned len = itemLen - zshPtr->outPos; + size_t len = itemLen - zshPtr->outPos; memcpy(dataPtr + dataPos, itemPtr + zshPtr->outPos, len); dataPos += len; diff --git a/unix/Makefile.in b/unix/Makefile.in index d5324dc..487ae61 100644 --- a/unix/Makefile.in +++ b/unix/Makefile.in @@ -691,6 +691,7 @@ ${LIB_FILE}: ${STUB_LIB_FILE} ${OBJS} ${TCL_ZIP_FILE} @MAKE_LIB@ ifeq (${ZIPFS_BUILD},1) cat ${TCL_ZIP_FILE} >> ${LIB_FILE} + ${NATIVE_ZIP} -A ${LIB_FILE} endif ${STUB_LIB_FILE}: ${STUB_LIB_OBJS} @@ -1834,7 +1835,7 @@ deflate.$(HOST_OBJEXT): $(HOST_CC) -o $@ -I$(ZLIB_DIR) -c $(ZLIB_DIR)/deflate.c ioapi.$(HOST_OBJEXT): - $(HOST_CC) -o $@ -I$(ZLIB_DIR) -I$(ZLIB_DIR)/contrib/minizip -c \ + $(HOST_CC) -o $@ -DIOAPI_NO_64 -I$(ZLIB_DIR) -I$(ZLIB_DIR)/contrib/minizip -c \ $(ZLIB_DIR)/contrib/minizip/ioapi.c infback.$(HOST_OBJEXT): @@ -1863,7 +1864,7 @@ zutil.$(HOST_OBJEXT): $(HOST_CC) -o $@ -I$(ZLIB_DIR) -c $(ZLIB_DIR)/zutil.c minizip.$(HOST_OBJEXT): - $(HOST_CC) -o $@ -I$(ZLIB_DIR) -I$(ZLIB_DIR)/contrib/minizip -c \ + $(HOST_CC) -o $@ -DIOAPI_NO_64 -I$(ZLIB_DIR) -I$(ZLIB_DIR)/contrib/minizip -c \ $(ZLIB_DIR)/contrib/minizip/minizip.c minizip${HOST_EXEEXT}: $(MINIZIP_OBJS) diff --git a/unix/configure b/unix/configure index aa7953b..2af5144 100755 --- a/unix/configure +++ b/unix/configure @@ -10209,61 +10209,46 @@ $as_echo "$bfd_cv_build_exeext" >&6; } ZIP_PROG_OPTIONS="" ZIP_PROG_VFSSEARCH="" ZIP_INSTALL_OBJS="" - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for zip" >&5 -$as_echo_n "checking for zip... " >&6; } - # If our native tclsh processes the "install" command line option - # we can use it to mint zip files - if $TCLSH_PROG install; then : - - ZIP_PROG=${TCLSH_PROG} - ZIP_PROG_OPTIONS="install mkzip" - ZIP_PROG_VFSSEARCH="." - { $as_echo "$as_me:${as_lineno-$LINENO}: result: Can use Native Tclsh for Zip encoding" >&5 -$as_echo "Can use Native Tclsh for Zip encoding" >&6; } -fi - - if test "x$ZIP_PROG" = "x" ; then - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for zip" >&5 + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for zip" >&5 $as_echo_n "checking for zip... " >&6; } - if ${ac_cv_path_zip+:} false; then : + if ${ac_cv_path_zip+:} false; then : $as_echo_n "(cached) " >&6 else - search_path=`echo ${PATH} | sed -e 's/:/ /g'` - for dir in $search_path ; do - for j in `ls -r $dir/zip 2> /dev/null` \ - `ls -r $dir/zip 2> /dev/null` ; do - if test x"$ac_cv_path_zip" = x ; then - if test -f "$j" ; then - ac_cv_path_zip=$j - break - fi + search_path=`echo ${PATH} | sed -e 's/:/ /g'` + for dir in $search_path ; do + for j in `ls -r $dir/zip 2> /dev/null` \ + `ls -r $dir/zip 2> /dev/null` ; do + if test x"$ac_cv_path_zip" = x ; then + if test -f "$j" ; then + ac_cv_path_zip=$j + break fi - done + fi done + done fi - if test -f "$ac_cv_path_zip" ; then - ZIP_PROG="$ac_cv_path_zip " - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ZIP_PROG" >&5 + if test -f "$ac_cv_path_zip" ; then + ZIP_PROG="$ac_cv_path_zip " + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ZIP_PROG" >&5 $as_echo "$ZIP_PROG" >&6; } - ZIP_PROG_OPTIONS="-rq" - ZIP_PROG_VFSSEARCH="." - { $as_echo "$as_me:${as_lineno-$LINENO}: result: Found INFO Zip in environment" >&5 + ZIP_PROG_OPTIONS="-rq" + ZIP_PROG_VFSSEARCH="." + { $as_echo "$as_me:${as_lineno-$LINENO}: result: Found INFO Zip in environment" >&5 $as_echo "Found INFO Zip in environment" >&6; } - # Use standard arguments for zip - else - # It is not an error if an installed version of Zip can't be located. - # We can use the locally distributed minizip instead - ZIP_PROG="../minizip${EXEEXT_FOR_BUILD}" - ZIP_PROG_OPTIONS="-o -r" - ZIP_PROG_VFSSEARCH="." - ZIP_INSTALL_OBJS="minizip${EXEEXT_FOR_BUILD}" - { $as_echo "$as_me:${as_lineno-$LINENO}: result: No zip found on PATH building minizip" >&5 -$as_echo "No zip found on PATH building minizip" >&6; } - fi + # Use standard arguments for zip + else + # It is not an error if an installed version of Zip can't be located. + # We can use the locally distributed minizip instead + ZIP_PROG="../minizip${EXEEXT_FOR_BUILD}" + ZIP_PROG_OPTIONS="-o -r" + ZIP_PROG_VFSSEARCH="." + ZIP_INSTALL_OBJS="minizip${EXEEXT_FOR_BUILD}" + { $as_echo "$as_me:${as_lineno-$LINENO}: result: No zip found on PATH. Building minizip" >&5 +$as_echo "No zip found on PATH. Building minizip" >&6; } fi diff --git a/unix/tcl.m4 b/unix/tcl.m4 index 44403dc..b77387a 100644 --- a/unix/tcl.m4 +++ b/unix/tcl.m4 @@ -3047,48 +3047,37 @@ AC_DEFUN([SC_ZIPFS_SUPPORT], [ ZIP_PROG_OPTIONS="" ZIP_PROG_VFSSEARCH="" ZIP_INSTALL_OBJS="" - AC_MSG_CHECKING([for zip]) - # If our native tclsh processes the "install" command line option - # we can use it to mint zip files - AS_IF([$TCLSH_PROG install],[ - ZIP_PROG=${TCLSH_PROG} - ZIP_PROG_OPTIONS="install mkzip" - ZIP_PROG_VFSSEARCH="." - AC_MSG_RESULT([Can use Native Tclsh for Zip encoding]) - ]) - if test "x$ZIP_PROG" = "x" ; then - AC_MSG_CHECKING([for zip]) - AC_CACHE_VAL(ac_cv_path_zip, [ - search_path=`echo ${PATH} | sed -e 's/:/ /g'` - for dir in $search_path ; do - for j in `ls -r $dir/zip 2> /dev/null` \ - `ls -r $dir/zip 2> /dev/null` ; do - if test x"$ac_cv_path_zip" = x ; then - if test -f "$j" ; then - ac_cv_path_zip=$j - break - fi + AC_MSG_CHECKING([for zip]) + AC_CACHE_VAL(ac_cv_path_zip, [ + search_path=`echo ${PATH} | sed -e 's/:/ /g'` + for dir in $search_path ; do + for j in `ls -r $dir/zip 2> /dev/null` \ + `ls -r $dir/zip 2> /dev/null` ; do + if test x"$ac_cv_path_zip" = x ; then + if test -f "$j" ; then + ac_cv_path_zip=$j + break fi - done - done - ]) - if test -f "$ac_cv_path_zip" ; then - ZIP_PROG="$ac_cv_path_zip " - AC_MSG_RESULT([$ZIP_PROG]) - ZIP_PROG_OPTIONS="-rq" - ZIP_PROG_VFSSEARCH="." - AC_MSG_RESULT([Found INFO Zip in environment]) - # Use standard arguments for zip - else - # It is not an error if an installed version of Zip can't be located. - # We can use the locally distributed minizip instead - ZIP_PROG="../minizip${EXEEXT_FOR_BUILD}" - ZIP_PROG_OPTIONS="-o -r" - ZIP_PROG_VFSSEARCH="." - ZIP_INSTALL_OBJS="minizip${EXEEXT_FOR_BUILD}" - AC_MSG_RESULT([No zip found on PATH building minizip]) fi + done + done + ]) + if test -f "$ac_cv_path_zip" ; then + ZIP_PROG="$ac_cv_path_zip " + AC_MSG_RESULT([$ZIP_PROG]) + ZIP_PROG_OPTIONS="-rq" + ZIP_PROG_VFSSEARCH="." + AC_MSG_RESULT([Found INFO Zip in environment]) + # Use standard arguments for zip + else + # It is not an error if an installed version of Zip can't be located. + # We can use the locally distributed minizip instead + ZIP_PROG="../minizip${EXEEXT_FOR_BUILD}" + ZIP_PROG_OPTIONS="-o -r" + ZIP_PROG_VFSSEARCH="." + ZIP_INSTALL_OBJS="minizip${EXEEXT_FOR_BUILD}" + AC_MSG_RESULT([No zip found on PATH. Building minizip]) fi AC_SUBST(ZIP_PROG) AC_SUBST(ZIP_PROG_OPTIONS) diff --git a/win/Makefile.in b/win/Makefile.in index e2acb1b..99cf327 100644 --- a/win/Makefile.in +++ b/win/Makefile.in @@ -516,6 +516,7 @@ ${TCL_DLL_FILE}: ${TCL_OBJS} tcl.$(RES) @ZLIB_DLL_FILE@ ${TCL_ZIP_FILE} @VC_MANIFEST_EMBED_DLL@ ifeq (${ZIPFS_BUILD},1) cat ${TCL_ZIP_FILE} >> ${TCL_DLL_FILE} + ${NATIVE_ZIP} -A ${TCL_DLL_FILE} endif ${TCL_LIB_FILE}: ${TCL_OBJS} ${DDE_OBJS} ${REG_OBJS} @@ -640,7 +641,7 @@ deflate.$(HOST_OBJEXT): $(HOST_CC) -o $@ -I$(ZLIB_DIR) -c $(ZLIB_DIR)/deflate.c ioapi.$(HOST_OBJEXT): - $(HOST_CC) -o $@ -I$(ZLIB_DIR) -I$(ZLIB_DIR)/contrib/minizip -c $(ZLIB_DIR)/contrib/minizip/ioapi.c + $(HOST_CC) -o $@ -DIOAPI_NO_64 -I$(ZLIB_DIR) -I$(ZLIB_DIR)/contrib/minizip -c $(ZLIB_DIR)/contrib/minizip/ioapi.c iowin32.$(HOST_OBJEXT): $(HOST_CC) -o $@ -I$(ZLIB_DIR) -I$(ZLIB_DIR)/contrib/minizip -c $(ZLIB_DIR)/contrib/minizip/iowin32.c @@ -670,7 +671,7 @@ zutil.$(HOST_OBJEXT): $(HOST_CC) -o $@ -I$(ZLIB_DIR) -c $(ZLIB_DIR)/zutil.c minizip.$(HOST_OBJEXT): - $(HOST_CC) -o $@ -I$(ZLIB_DIR) -I$(ZLIB_DIR)/contrib/minizip -c $(ZLIB_DIR)/contrib/minizip/minizip.c + $(HOST_CC) -o $@ -I$(ZLIB_DIR) -DIOAPI_NO_64 -I$(ZLIB_DIR)/contrib/minizip -c $(ZLIB_DIR)/contrib/minizip/minizip.c minizip${HOST_EXEEXT}: $(MINIZIP_OBJS) $(HOST_CC) -o $@ $(MINIZIP_OBJS) diff --git a/win/configure b/win/configure index 06f1f75..21c3cc7 100755 --- a/win/configure +++ b/win/configure @@ -4832,61 +4832,46 @@ $as_echo "No tclsh found on PATH" >&6; } ZIP_PROG_OPTIONS="" ZIP_PROG_VFSSEARCH="" ZIP_INSTALL_OBJS="" - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for zip" >&5 -$as_echo_n "checking for zip... " >&6; } - # If our native tclsh processes the "install" command line option - # we can use it to mint zip files - if $TCLSH_PROG install; then : - - ZIP_PROG=${TCLSH_PROG} - ZIP_PROG_OPTIONS="install mkzip" - ZIP_PROG_VFSSEARCH="." - { $as_echo "$as_me:${as_lineno-$LINENO}: result: Can use Native Tclsh for Zip encoding" >&5 -$as_echo "Can use Native Tclsh for Zip encoding" >&6; } - -fi - if test "x$ZIP_PROG" = "x" ; then - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for zip" >&5 + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for zip" >&5 $as_echo_n "checking for zip... " >&6; } - if ${ac_cv_path_zip+:} false; then : + if ${ac_cv_path_zip+:} false; then : $as_echo_n "(cached) " >&6 else - search_path=`echo ${PATH} | sed -e 's/:/ /g'` - for dir in $search_path ; do - for j in `ls -r $dir/zip 2> /dev/null` \ - `ls -r $dir/zip 2> /dev/null` ; do - if test x"$ac_cv_path_zip" = x ; then - if test -f "$j" ; then - ac_cv_path_zip=$j - break - fi + search_path=`echo ${PATH} | sed -e 's/:/ /g'` + for dir in $search_path ; do + for j in `ls -r $dir/zip 2> /dev/null` \ + `ls -r $dir/zip 2> /dev/null` ; do + if test x"$ac_cv_path_zip" = x ; then + if test -f "$j" ; then + ac_cv_path_zip=$j + break fi - done + fi done + done fi - if test -f "$ac_cv_path_zip" ; then - ZIP_PROG="$ac_cv_path_zip " - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ZIP_PROG" >&5 + if test -f "$ac_cv_path_zip" ; then + ZIP_PROG="$ac_cv_path_zip " + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ZIP_PROG" >&5 $as_echo "$ZIP_PROG" >&6; } - ZIP_PROG_OPTIONS="-rq" - ZIP_PROG_VFSSEARCH="." - { $as_echo "$as_me:${as_lineno-$LINENO}: result: Found INFO Zip in environment" >&5 + ZIP_PROG_OPTIONS="-rq" + ZIP_PROG_VFSSEARCH="." + { $as_echo "$as_me:${as_lineno-$LINENO}: result: Found INFO Zip in environment" >&5 $as_echo "Found INFO Zip in environment" >&6; } - # Use standard arguments for zip - else - # It is not an error if an installed version of Zip can't be located. - # We can use the locally distributed minizip instead - ZIP_PROG="../minizip${EXEEXT_FOR_BUILD}" - ZIP_PROG_OPTIONS="-o -r" - ZIP_PROG_VFSSEARCH="." - ZIP_INSTALL_OBJS="minizip${EXEEXT_FOR_BUILD}" - { $as_echo "$as_me:${as_lineno-$LINENO}: result: No zip found on PATH building minizip" >&5 + # Use standard arguments for zip + else + # It is not an error if an installed version of Zip can't be located. + # We can use the locally distributed minizip instead + ZIP_PROG="../minizip${EXEEXT_FOR_BUILD}" + ZIP_PROG_OPTIONS="-o -r" + ZIP_PROG_VFSSEARCH="." + ZIP_INSTALL_OBJS="minizip${EXEEXT_FOR_BUILD}" + { $as_echo "$as_me:${as_lineno-$LINENO}: result: No zip found on PATH building minizip" >&5 $as_echo "No zip found on PATH building minizip" >&6; } - fi fi diff --git a/win/tcl.m4 b/win/tcl.m4 index 32df552..bdcd8ea 100644 --- a/win/tcl.m4 +++ b/win/tcl.m4 @@ -1250,48 +1250,37 @@ AC_DEFUN([SC_ZIPFS_SUPPORT], [ ZIP_PROG_OPTIONS="" ZIP_PROG_VFSSEARCH="" ZIP_INSTALL_OBJS="" - AC_MSG_CHECKING([for zip]) - # If our native tclsh processes the "install" command line option - # we can use it to mint zip files - AS_IF([$TCLSH_PROG install],[ - ZIP_PROG=${TCLSH_PROG} - ZIP_PROG_OPTIONS="install mkzip" - ZIP_PROG_VFSSEARCH="." - AC_MSG_RESULT([Can use Native Tclsh for Zip encoding]) - ]) - if test "x$ZIP_PROG" = "x" ; then - AC_MSG_CHECKING([for zip]) - AC_CACHE_VAL(ac_cv_path_zip, [ - search_path=`echo ${PATH} | sed -e 's/:/ /g'` - for dir in $search_path ; do - for j in `ls -r $dir/zip 2> /dev/null` \ - `ls -r $dir/zip 2> /dev/null` ; do - if test x"$ac_cv_path_zip" = x ; then - if test -f "$j" ; then - ac_cv_path_zip=$j - break - fi + AC_MSG_CHECKING([for zip]) + AC_CACHE_VAL(ac_cv_path_zip, [ + search_path=`echo ${PATH} | sed -e 's/:/ /g'` + for dir in $search_path ; do + for j in `ls -r $dir/zip 2> /dev/null` \ + `ls -r $dir/zip 2> /dev/null` ; do + if test x"$ac_cv_path_zip" = x ; then + if test -f "$j" ; then + ac_cv_path_zip=$j + break fi - done - done - ]) - if test -f "$ac_cv_path_zip" ; then - ZIP_PROG="$ac_cv_path_zip " - AC_MSG_RESULT([$ZIP_PROG]) - ZIP_PROG_OPTIONS="-rq" - ZIP_PROG_VFSSEARCH="." - AC_MSG_RESULT([Found INFO Zip in environment]) - # Use standard arguments for zip - else - # It is not an error if an installed version of Zip can't be located. - # We can use the locally distributed minizip instead - ZIP_PROG="../minizip${EXEEXT_FOR_BUILD}" - ZIP_PROG_OPTIONS="-o -r" - ZIP_PROG_VFSSEARCH="." - ZIP_INSTALL_OBJS="minizip${EXEEXT_FOR_BUILD}" - AC_MSG_RESULT([No zip found on PATH building minizip]) fi + done + done + ]) + if test -f "$ac_cv_path_zip" ; then + ZIP_PROG="$ac_cv_path_zip " + AC_MSG_RESULT([$ZIP_PROG]) + ZIP_PROG_OPTIONS="-rq" + ZIP_PROG_VFSSEARCH="." + AC_MSG_RESULT([Found INFO Zip in environment]) + # Use standard arguments for zip + else + # It is not an error if an installed version of Zip can't be located. + # We can use the locally distributed minizip instead + ZIP_PROG="../minizip${EXEEXT_FOR_BUILD}" + ZIP_PROG_OPTIONS="-o -r" + ZIP_PROG_VFSSEARCH="." + ZIP_INSTALL_OBJS="minizip${EXEEXT_FOR_BUILD}" + AC_MSG_RESULT([No zip found on PATH building minizip]) fi AC_SUBST(ZIP_PROG) AC_SUBST(ZIP_PROG_OPTIONS) diff --git a/win/tclAppInit.c b/win/tclAppInit.c index 6444b21..fa27756 100644 --- a/win/tclAppInit.c +++ b/win/tclAppInit.c @@ -126,7 +126,7 @@ _tmain( #ifdef TCL_LOCAL_MAIN_HOOK TCL_LOCAL_MAIN_HOOK(&argc, &argv); -#elif !defined(_WIN32) && !defined(UNICODE) +#elif !defined(_WIN32) || defined(UNICODE) /* This doesn't work on Windows without UNICODE */ TclZipfs_AppHook(&argc, &argv); #endif -- cgit v0.12 From 7fcc213b7aa1313c6bbe4ee2f794913e6776b0db Mon Sep 17 00:00:00 2001 From: "jan.nijtmans" Date: Fri, 12 Oct 2018 18:24:20 +0000 Subject: TCL_NUMBER_WIDE is deprecated --- generic/tclUtil.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/generic/tclUtil.c b/generic/tclUtil.c index 97879c7..4ea9c2e 100644 --- a/generic/tclUtil.c +++ b/generic/tclUtil.c @@ -3696,7 +3696,7 @@ GetWideForIndex( int code = TclGetNumberFromObj(NULL, objPtr, &cd, &numType); if (code == TCL_OK) { - if (numType == TCL_NUMBER_WIDE) { + if (numType == TCL_NUMBER_INT) { /* objPtr holds an integer in the signed wide range */ *widePtr = (Tcl_WideInt)(*(Tcl_WideInt *)cd); return TCL_OK; @@ -3753,7 +3753,7 @@ GetWideForIndex( /* Save first integer as wide if possible */ TclGetNumberFromObj(NULL, objPtr, &cd, &t1); - if (t1 == TCL_NUMBER_WIDE) { + if (t1 == TCL_NUMBER_INT) { w1 = (*(Tcl_WideInt *)cd); } @@ -3763,7 +3763,7 @@ GetWideForIndex( /* Save second integer as wide if possible */ TclGetNumberFromObj(NULL, objPtr, &cd, &t2); - if (t2 == TCL_NUMBER_WIDE) { + if (t2 == TCL_NUMBER_INT) { w2 = (*(Tcl_WideInt *)cd); } } @@ -3773,7 +3773,7 @@ GetWideForIndex( if (t1 && t2) { /* We have both integer values */ - if ((t1 == TCL_NUMBER_WIDE) && (t2 == TCL_NUMBER_WIDE)) { + if ((t1 == TCL_NUMBER_INT) && (t2 == TCL_NUMBER_INT)) { /* Both are wide, do wide-integer math */ if (*opPtr == '-') { if ((w2 == LLONG_MIN) && (interp != NULL)) { @@ -3818,7 +3818,7 @@ GetWideForIndex( Tcl_ExprObj(interp, objPtr, &sum); TclGetNumberFromObj(NULL, sum, &cd, &numType); - if (numType == TCL_NUMBER_WIDE) { + if (numType == TCL_NUMBER_INT) { /* sum holds an integer in the signed wide range */ *widePtr = (Tcl_WideInt)(*(Tcl_WideInt *)cd); } else { @@ -4123,7 +4123,7 @@ TclIndexEncode( Tcl_WideInt wide; int idx, numType, code = TclGetNumberFromObj(NULL, objPtr, &cd, &numType); - if ((code == TCL_OK) && (numType == TCL_NUMBER_WIDE)) { + if ((code == TCL_OK) && (numType == TCL_NUMBER_INT)) { /* We parsed a value in the range LLONG_MIN...LLONG_MAX */ wide = (*(Tcl_WideInt *)cd); integerEncode: -- cgit v0.12 From de2192ab2097c8b53fd997775bbd1b74b4e8b8f0 Mon Sep 17 00:00:00 2001 From: dkf Date: Fri, 12 Oct 2018 18:44:25 +0000 Subject: Turn [zipfs tcl_library] into more internal [tcl::zipfs::tcl_library_init]. It wasn't documented and isn't very useful outside of Tcl's startup code. --- generic/tclBasic.c | 1 - generic/tclInterp.c | 2 +- generic/tclZipfs.c | 19 ++++++++++++------- tests/interp.test | 2 +- tests/zipfs.test | 4 ++-- 5 files changed, 16 insertions(+), 12 deletions(-) diff --git a/generic/tclBasic.c b/generic/tclBasic.c index 321b124..179306d 100644 --- a/generic/tclBasic.c +++ b/generic/tclBasic.c @@ -382,7 +382,6 @@ static const UnsafeEnsembleInfo unsafeEnsembleCommands[] = { {"zipfs", "mkzip"}, {"zipfs", "mount"}, {"zipfs", "mount_data"}, - {"zipfs", "tcl_library"}, {"zipfs", "unmount"}, {NULL, NULL} }; diff --git a/generic/tclInterp.c b/generic/tclInterp.c index 90f02f9..1e75298 100644 --- a/generic/tclInterp.c +++ b/generic/tclInterp.c @@ -409,7 +409,7 @@ Tcl_Init( " } else {\n" " lappend scripts {::tcl::pkgconfig get scriptdir,runtime}\n" " }\n" -" lappend scripts {zipfs tcl_library}\n" +" lappend scripts {::tcl::zipfs::tcl_library_init}\n" " lappend scripts {\n" "set parentDir [file dirname [file dirname [info nameofexecutable]]]\n" "set grandParentDir [file dirname $parentDir]\n" diff --git a/generic/tclZipfs.c b/generic/tclZipfs.c index bd2ae13..428be15 100644 --- a/generic/tclZipfs.c +++ b/generic/tclZipfs.c @@ -3257,8 +3257,10 @@ TclZipfs_TclLibrary(void) * * ZipFSTclLibraryObjCmd -- * - * This procedure is invoked to process the [zipfs tcl_library] command. - * It returns the root that Tcl's library files are mounted under. + * This procedure is invoked to process the + * [::tcl::zipfs::tcl_library_init] command, usually called during the + * execution of Tcl's interpreter startup. It returns the root that Tcl's + * library files are mounted under. * * Results: * A standard Tcl result. @@ -3277,12 +3279,14 @@ ZipFSTclLibraryObjCmd( int objc, /* Number of arguments. */ Tcl_Obj *const objv[]) /* Argument objects. */ { - Tcl_Obj *pResult = TclZipfs_TclLibrary(); + if (!Tcl_IsSafe(interp)) { + Tcl_Obj *pResult = TclZipfs_TclLibrary(); - if (!pResult) { - pResult = Tcl_NewObj(); + if (!pResult) { + pResult = Tcl_NewObj(); + } + Tcl_SetObjResult(interp, pResult); } - Tcl_SetObjResult(interp, pResult); return TCL_OK; } @@ -4719,7 +4723,6 @@ TclZipfs_Init( {"list", ZipFSListObjCmd, NULL, NULL, NULL, 0}, {"canonical", ZipFSCanonicalObjCmd, NULL, NULL, NULL, 0}, {"root", ZipFSRootObjCmd, NULL, NULL, NULL, 0}, - {"tcl_library", ZipFSTclLibraryObjCmd, NULL, NULL, NULL, 1}, {NULL, NULL, NULL, NULL, NULL, 0} }; static const char findproc[] = @@ -4769,6 +4772,8 @@ TclZipfs_Init( Tcl_GetEnsembleMappingDict(NULL, ensemble, &mapObj); Tcl_DictObjPut(NULL, mapObj, Tcl_NewStringObj("find", -1), Tcl_NewStringObj("::tcl::zipfs::find", -1)); + Tcl_CreateObjCommand(interp, "::tcl::zipfs::tcl_library_init", + ZipFSTclLibraryObjCmd, NULL, NULL); Tcl_PkgProvide(interp, "zipfs", "2.0"); } return TCL_OK; diff --git a/tests/interp.test b/tests/interp.test index e9f95d7..29e3b2d 100644 --- a/tests/interp.test +++ b/tests/interp.test @@ -20,7 +20,7 @@ catch [list package require -exact Tcltest [info patchlevel]] 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:encoding:system 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 tcl:info:cmdtype tcl:info:nameofexecutable tcl:process:autopurge tcl:process:list tcl:process:purge tcl:process:status tcl:zipfs:lmkimg tcl:zipfs:lmkzip tcl:zipfs:mkimg tcl:zipfs:mkkey tcl:zipfs:mkzip tcl:zipfs:mount tcl:zipfs:mount_data tcl:zipfs:tcl_library tcl:zipfs:unmount unload} +set hidden_cmds {cd encoding exec exit fconfigure file glob load open pwd socket source tcl:encoding:dirs tcl:encoding:system 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 tcl:info:cmdtype tcl:info:nameofexecutable tcl:process:autopurge tcl:process:list tcl:process:purge tcl:process:status tcl:zipfs:lmkimg tcl:zipfs:lmkzip tcl:zipfs:mkimg tcl:zipfs:mkkey tcl:zipfs:mkzip tcl:zipfs:mount tcl:zipfs:mount_data tcl:zipfs:unmount unload} foreach i [interp slaves] { interp delete $i diff --git a/tests/zipfs.test b/tests/zipfs.test index abf9d3f..5715ce8 100644 --- a/tests/zipfs.test +++ b/tests/zipfs.test @@ -247,7 +247,7 @@ test zipfs-3.1 {zipfs in child interpreters} -constraints zipfs -setup { } } -returnCodes error -cleanup { interp delete $interp -} -result {unknown or ambiguous subcommand "?": must be canonical, exists, find, info, list, lmkimg, lmkzip, mkimg, mkkey, mkzip, mount, mount_data, root, tcl_library, or unmount} +} -result {unknown or ambiguous subcommand "?": must be canonical, exists, find, info, list, lmkimg, lmkzip, mkimg, mkkey, mkzip, mount, mount_data, root, or unmount} test zipfs-3.2 {zipfs in child interpreters} -constraints zipfs -setup { set interp [interp create] } -body { @@ -265,7 +265,7 @@ test zipfs-3.3 {zipfs in child interpreters} -constraints zipfs -setup { } } -returnCodes error -cleanup { interp delete $safe -} -result {unknown or ambiguous subcommand "?": must be canonical, exists, find, info, list, lmkimg, lmkzip, mkimg, mkkey, mkzip, mount, mount_data, root, tcl_library, or unmount} +} -result {unknown or ambiguous subcommand "?": must be canonical, exists, find, info, list, lmkimg, lmkzip, mkimg, mkkey, mkzip, mount, mount_data, root, or unmount} test zipfs-3.4 {zipfs in child interpreters} -constraints zipfs -setup { set safe [interp create -safe] } -body { -- cgit v0.12 From 2482413c83a6fc4c661a24357b0972212d5586e3 Mon Sep 17 00:00:00 2001 From: dkf Date: Fri, 12 Oct 2018 18:45:54 +0000 Subject: Minor doc update --- doc/zipfs.n | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/doc/zipfs.n b/doc/zipfs.n index 9ed136d..c27b5d5 100644 --- a/doc/zipfs.n +++ b/doc/zipfs.n @@ -30,9 +30,8 @@ zipfs \- Mount and work with ZIP files within Tcl \fBzipfs root\fR \fBzipfs unmount\fR \fImountpoint\fR .fi -'\" The following subcommands are *UNDOCUMENTED* (the list here is not documentation) +'\" The following subcommand is *UNDOCUMENTED* '\" \fBzipfs mount_data\fR ?\fImountpoint\fR? ?\fIdata\fR? -'\" \fBzipfs tcl_library\fR .BE .SH DESCRIPTION .PP @@ -245,10 +244,8 @@ close $f # Launch the executable, printing its output to stdout exec $img >@stdout -# prints: \fI Hi. This is //zipfs:/app/main.tcl\fR +# prints: \fIHi. This is //zipfs:/app/main.tcl\fR .CE -'\" WANTED: How to use the passwords -'\" WANTED: How to package an application .SH "SEE ALSO" tclsh(1), file(n), zipfs(3), zlib(n) .SH "KEYWORDS" -- cgit v0.12 From ac4291f473c3967c6d9ee72d0076147c7a53d76f Mon Sep 17 00:00:00 2001 From: dgp Date: Wed, 17 Oct 2018 16:03:54 +0000 Subject: Backport test fix. --- tests/macOSXFCmd.test | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/tests/macOSXFCmd.test b/tests/macOSXFCmd.test index 071f11b..132b2fe 100644 --- a/tests/macOSXFCmd.test +++ b/tests/macOSXFCmd.test @@ -151,16 +151,16 @@ test macOSXFCmd-4.1 {TclMacOSXMatchType} {macosxFileAttr notRoot} { file attributes dir.test -hidden 1 } set res [list \ - [catch {glob *.test} msg] $msg \ - [catch {glob -types FOOT *.test} msg] $msg \ - [catch {glob -types {{macintosh type FOOT}} *.test} msg] $msg \ - [catch {glob -types FOOTT *.test} msg] $msg \ - [catch {glob -types {{macintosh type FOOTT}} *.test} msg] $msg \ - [catch {glob -types {{macintosh type {}}} *.test} msg] $msg \ - [catch {glob -types {{macintosh creator FOOC}} *.test} msg] $msg \ - [catch {glob -types {{macintosh creator FOOC} {macintosh type FOOT}} *.test} msg] $msg \ - [catch {glob -types hidden *.test} msg] $msg \ - [catch {glob -types {hidden FOOT} *.test} msg] $msg \ + [catch {lsort [glob *.test]} msg] $msg \ + [catch {lsort [glob -types FOOT *.test]} msg] $msg \ + [catch {lsort [glob -types {{macintosh type FOOT}} *.test]} msg] $msg \ + [catch {lsort [glob -types FOOTT *.test]} msg] $msg \ + [catch {lsort [glob -types {{macintosh type FOOTT}} *.test]} msg] $msg \ + [catch {lsort [glob -types {{macintosh type {}}} *.test]} msg] $msg \ + [catch {lsort [glob -types {{macintosh creator FOOC}} *.test]} msg] $msg \ + [catch {lsort [glob -types {{macintosh creator FOOC} {macintosh type FOOT}} *.test]} msg] $msg \ + [catch {lsort [glob -types hidden *.test]} msg] $msg \ + [catch {lsort [glob -types {hidden FOOT} *.test]} msg] $msg \ ] cd .. file delete -force globtest -- cgit v0.12 From 56b431c4c29b4b9e992e71d6db46a34189006e93 Mon Sep 17 00:00:00 2001 From: dgp Date: Wed, 17 Oct 2018 16:06:38 +0000 Subject: Mark test macOSXFCmf-2.8 non-portable. It appears to pass when the older HFS+ filesystem is in use, often on disk drives in older systems. It appears to fail when APFS is in use, more typical on newer SSD storage. --- tests/macOSXFCmd.test | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/macOSXFCmd.test b/tests/macOSXFCmd.test index 132b2fe..f1758f5 100644 --- a/tests/macOSXFCmd.test +++ b/tests/macOSXFCmd.test @@ -99,7 +99,7 @@ test macOSXFCmd-2.6 {MacOSXSetFileAttribute - hidden} {macosxFileAttr notRoot} { [catch {file attributes foo.test -hidden} msg] $msg \ [file delete -force -- foo.test] } {0 {} 0 1 {}} -test macOSXFCmd-2.7 {MacOSXSetFileAttribute - rsrclength} {macosxFileAttr notRoot} { +test macOSXFCmd-2.7 {MacOSXSetFileAttribute - rsrclength} {macosxFileAttr notRoot nonPortable} { catch {file delete -force -- foo.test} close [open foo.test w] catch { -- cgit v0.12 From e1196c53f256897cfdf6549eae9bdd88eb1aa930 Mon Sep 17 00:00:00 2001 From: dgp Date: Wed, 17 Oct 2018 16:12:42 +0000 Subject: Revert addition of "slowTest" as built-in constraint. (no TIP; no version bump). Let the test file that needs the constraint define it with existing facilities. --- library/tcltest/tcltest.tcl | 4 ---- tests/tcltest.test | 2 +- tests/winPipe.test | 1 + 3 files changed, 2 insertions(+), 5 deletions(-) diff --git a/library/tcltest/tcltest.tcl b/library/tcltest/tcltest.tcl index eb42ff1..f1b6082 100644 --- a/library/tcltest/tcltest.tcl +++ b/library/tcltest/tcltest.tcl @@ -1254,10 +1254,6 @@ proc tcltest::DefineConstraintInitializers {} { ConstraintInitializer interactive \ {expr {[info exists ::tcl_interactive] && $::tcl_interactive}} - # Skip slow tests (to enable slow tests add parameter `-constraints slowTest`) - - ConstraintInitializer slowTest {format 0} - # Some tests can only be run if the installation came from a CD # image instead of a web image. Some tests must be skipped if you # are running as root on Unix. Other tests can only be run if you diff --git a/tests/tcltest.test b/tests/tcltest.test index e176b0c..0bcf342 100644 --- a/tests/tcltest.test +++ b/tests/tcltest.test @@ -312,7 +312,7 @@ test tcltest-5.5 {InitConstraints: list of built-in constraints} \ -result [lsort { 95 98 asyncPipeClose eformat emptyTest exec hasIsoLocale interactive knownBug mac macCrash macOnly macOrPc macOrUnix macOrWin nonBlockFiles - nonPortable notRoot nt pc pcCrash pcOnly root singleTestInterp slowTest socket + nonPortable notRoot nt pc pcCrash pcOnly root singleTestInterp socket stdio tempNotMac tempNotPc tempNotUnix tempNotWin unix unixCrash unixExecs unixOnly unixOrPc unixOrWin userInteraction win winCrash winOnly }] diff --git a/tests/winPipe.test b/tests/winPipe.test index 2f59e96..b3624c2 100644 --- a/tests/winPipe.test +++ b/tests/winPipe.test @@ -30,6 +30,7 @@ testConstraint cat32 [file exists $cat32] testConstraint AllocConsole [catch {puts console1 ""}] testConstraint RealConsole [expr {![testConstraint AllocConsole]}] testConstraint testexcept [llength [info commands testexcept]] +testConstraint slowTest 0 set big bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb\n -- cgit v0.12 From e0209e39ea32294ee016d240fd1dfe9411469832 Mon Sep 17 00:00:00 2001 From: "jan.nijtmans" Date: Wed, 17 Oct 2018 19:51:47 +0000 Subject: Fix test-cases running on Windows 10: [string index $tcl_platform(osVersion) 0] doesn't give the correct answer then (it gives "1", but "10" was expected) --- tests/cmdAH.test | 2 +- tests/fCmd.test | 18 +++++++++--------- tests/fileName.test | 2 +- tests/winFCmd.test | 5 ++--- 4 files changed, 13 insertions(+), 14 deletions(-) diff --git a/tests/cmdAH.test b/tests/cmdAH.test index 45a867a..6cc8c0f 100644 --- a/tests/cmdAH.test +++ b/tests/cmdAH.test @@ -20,7 +20,7 @@ testConstraint testsetplatform [llength [info commands testsetplatform]] testConstraint testvolumetype [llength [info commands testvolumetype]] testConstraint linkDirectory [expr { ![testConstraint win] || - ([string index $tcl_platform(osVersion) 0] >= 5 + ($::tcl_platform(osVersion) >= 5.0 && [lindex [file system [temporaryDirectory]] 1] eq "NTFS") }] diff --git a/tests/fCmd.test b/tests/fCmd.test index 2860001..f53128d 100644 --- a/tests/fCmd.test +++ b/tests/fCmd.test @@ -50,11 +50,10 @@ if {[testConstraint unix]} { # Also used in winFCmd... if {[testConstraint winOnly]} { - set major [string index $tcl_platform(osVersion) 0] - if {[testConstraint nt] && $major > 4} { - if {$major > 5} { + if {[testConstraint nt] && $::tcl_platform(osVersion) >= 5.0} { + if {$::tcl_platform(osVersion) >= 6.0} { testConstraint winVista 1 - } elseif {$major == 5} { + } else { testConstraint win2000orXP 1 } } else { @@ -62,10 +61,11 @@ if {[testConstraint winOnly]} { } } -testConstraint darwin9 [expr {[testConstraint unix] && - $tcl_platform(os) eq "Darwin" && - int([string range $tcl_platform(osVersion) 0 \ - [string first . $tcl_platform(osVersion)]]) >= 9}] +testConstraint darwin9 [expr { + [testConstraint unix] + && $tcl_platform(os) eq "Darwin" + && [package vsatisfies 1.$::tcl_platform(osVersion) 1.9] +}] testConstraint notDarwin9 [expr {![testConstraint darwin9]}] testConstraint fileSharing 0 @@ -2282,7 +2282,7 @@ test fCmd-27.6 {TclFileAttrsCmd - setting more than one option} -setup { if { [testConstraint win] && - ([string index $tcl_platform(osVersion) 0] < 5 + ($::tcl_platform(osVersion) < 5.0 || [lindex [file system [temporaryDirectory]] 1] ne "NTFS") } then { testConstraint linkDirectory 0 diff --git a/tests/fileName.test b/tests/fileName.test index 0851e94..a4c8efe 100644 --- a/tests/fileName.test +++ b/tests/fileName.test @@ -20,7 +20,7 @@ testConstraint testtranslatefilename [llength [info commands testtranslatefilena testConstraint linkDirectory 1 testConstraint symbolicLinkFile 1 if {[testConstraint win]} { - if {[string index $tcl_platform(osVersion) 0] < 5 \ + if {$::tcl_platform(osVersion) < 5.0 \ || [lindex [file system [temporaryDirectory]] 1] ne "NTFS"} { testConstraint linkDirectory 0 } diff --git a/tests/winFCmd.test b/tests/winFCmd.test index f1f2afa..f93f225 100644 --- a/tests/winFCmd.test +++ b/tests/winFCmd.test @@ -53,10 +53,9 @@ proc cleanup {args} { } if {[testConstraint win]} { - set major [string index $tcl_platform(osVersion) 0] - if {$major > 5} { + if {$::tcl_platform(osVersion) >= 5.0} { testConstraint winVista 1 - } elseif {$major == 5} { + } elseif {$::tcl_platform(osVersion) >= 4.0} { testConstraint winXP 1 } } -- cgit v0.12 From 49ebd1264d9cff42e9e5963f2a2f3c0eb732f375 Mon Sep 17 00:00:00 2001 From: "jan.nijtmans" Date: Wed, 17 Oct 2018 22:37:43 +0000 Subject: Add -Wpointer-arith compiler flag to gcc --- unix/configure | 2 +- unix/tcl.m4 | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/unix/configure b/unix/configure index 2af5144..013a8b3 100755 --- a/unix/configure +++ b/unix/configure @@ -4947,7 +4947,7 @@ fi if test "$GCC" = yes; then : CFLAGS_OPTIMIZE=-O2 - CFLAGS_WARNING="-Wall -Wwrite-strings -Wsign-compare -Wdeclaration-after-statement" + CFLAGS_WARNING="-Wall -Wwrite-strings -Wsign-compare -Wdeclaration-after-statement -Wpointer-arith" else diff --git a/unix/tcl.m4 b/unix/tcl.m4 index b77387a..e27cc2c 100644 --- a/unix/tcl.m4 +++ b/unix/tcl.m4 @@ -986,7 +986,7 @@ AC_DEFUN([SC_CONFIG_CFLAGS], [ CFLAGS_DEBUG=-g AS_IF([test "$GCC" = yes], [ CFLAGS_OPTIMIZE=-O2 - CFLAGS_WARNING="-Wall -Wwrite-strings -Wsign-compare -Wdeclaration-after-statement" + CFLAGS_WARNING="-Wall -Wwrite-strings -Wsign-compare -Wdeclaration-after-statement -Wpointer-arith" ], [ CFLAGS_OPTIMIZE=-O CFLAGS_WARNING="" -- cgit v0.12 From e0064189465e2ea63ca9e2dd531928a14c968f52 Mon Sep 17 00:00:00 2001 From: dkf Date: Thu, 18 Oct 2018 14:58:28 +0000 Subject: Tests for advanced object mutation issues. --- generic/tclOODefineCmds.c | 22 +++++++++++++- tests/oo.test | 77 +++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 98 insertions(+), 1 deletion(-) diff --git a/generic/tclOODefineCmds.c b/generic/tclOODefineCmds.c index c924d2b..f5fe676 100644 --- a/generic/tclOODefineCmds.c +++ b/generic/tclOODefineCmds.c @@ -1083,6 +1083,8 @@ TclOODefineClassObjCmd( { Object *oPtr; Class *clsPtr; + Foundation *fPtr = TclOOGetFoundation(interp); + int wasClass, willBeClass; /* * Parse the context to get the object to operate on. @@ -1118,12 +1120,20 @@ TclOODefineClassObjCmd( if (clsPtr == NULL) { return TCL_ERROR; } - + if (oPtr == clsPtr->thisPtr) { + Tcl_SetObjResult(interp, Tcl_NewStringObj( + "may not change classes into an instance of themselves", -1)); + Tcl_SetErrorCode(interp, "TCL", "OO", "MONKEY_BUSINESS", NULL); + return TCL_ERROR; + } /* * Set the object's class. */ + wasClass = (oPtr->classPtr != NULL); + willBeClass = (TclOOIsReachable(fPtr->classCls, clsPtr)); + if (oPtr->selfCls != clsPtr) { TclOORemoveFromInstances(oPtr, oPtr->selfCls); TclOODecrRefCount(oPtr->selfCls->thisPtr); @@ -1131,6 +1141,16 @@ TclOODefineClassObjCmd( AddRef(oPtr->selfCls->thisPtr); TclOOAddToInstances(oPtr, oPtr->selfCls); + /* + * Create or delete the class guts if necessary. + */ + + if (wasClass && !willBeClass) { + /* TODO: DELETE THE STRUCTURE */ + } else if (!wasClass && willBeClass) { + /* TODO: CREATE THE STRUCTURE */ + } + if (oPtr->classPtr != NULL) { BumpGlobalEpoch(interp, oPtr->classPtr); } else { diff --git a/tests/oo.test b/tests/oo.test index 024f890..7f0de4a 100644 --- a/tests/oo.test +++ b/tests/oo.test @@ -1804,6 +1804,83 @@ test oo-13.4 {OO: changing an object's class} -body { foo destroy bar destroy } -result {::foo ::foo ::foo ::bar} +test oo-13.5 {OO: changing an object's class} -setup { + oo::object create fooObj +} -body { + oo::objdefine fooObj { + class oo::class + } + oo::define fooObj { + method x {} {expr 1+2+3} + } + [fooObj new] x +} -cleanup { + fooObj destroy +} -result 6 +test oo-13.6 {OO: changing an object's class} -setup { + oo::class create foo +} -body { + oo::define foo { + method x {} {expr 1+2+3} + } + foo create bar + oo::objdefine foo { + class oo::object + } + list [catch {bar x} msg] $msg +} -cleanup { + catch {bar destroy} + foo destroy +} -result {1 {}} +test oo-13.7 {OO: changing an object's class} -setup { + oo::class create foo + oo::class create bar + unset -nocomplain result +} -body { + oo::define bar method x {} {return ok} + oo::define foo { + method x {} {expr 1+2+3} + self mixin foo + } + lappend result [foo x] + oo::objdefine foo class bar + lappend result [foo x] +} -cleanup { + foo destroy + bar destroy +} -result {6 ok} +test oo-13.7 {OO: changing an object's class to itself} -setup { + oo::class create foo +} -body { + oo::define foo { + method x {} {expr 1+2+3} + } + oo::objdefine foo class foo +} -cleanup { + foo destroy +} -returnCodes error -result {may not change classes into an instance of themselves} +test oo-13.9 {OO: changing an object's class: roots are special} -setup { + set i [interp create] +} -body { + $i eval { + oo::objdefine oo::object { + class oo::class + } + } +} -cleanup { + interp delete $i +} -returnCodes error -result {may not modify the class of the root object class} +test oo-13.10 {OO: changing an object's class: roots are special} -setup { + set i [interp create] +} -body { + $i eval { + oo::objdefine oo::class { + class oo::object + } + } +} -cleanup { + interp delete $i +} -returnCodes error -result {may not modify the class of the class of classes} # todo: changing a class subtype (metaclass) to another class subtype test oo-14.1 {OO: mixins} { -- cgit v0.12 From 6b0dccd9d531ae246fd34f9b4dc3c24ff4d06945 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Ignacio=20Mar=C3=ADn?= Date: Thu, 18 Oct 2018 18:23:50 +0000 Subject: Update TZ info to tzdata2018f. --- library/tzdata/Africa/Ceuta | 1 + library/tzdata/America/Santiago | 324 ++++++++++++++++++++-------------------- library/tzdata/Asia/Macau | 68 ++++++--- library/tzdata/Asia/Manila | 18 +-- library/tzdata/Asia/Pyongyang | 2 +- library/tzdata/Asia/Shanghai | 43 +++--- library/tzdata/Asia/Tokyo | 8 +- library/tzdata/Europe/Volgograd | 1 + library/tzdata/Pacific/Easter | 324 ++++++++++++++++++++-------------------- library/tzdata/Pacific/Fiji | 24 +-- 10 files changed, 427 insertions(+), 386 deletions(-) diff --git a/library/tzdata/Africa/Ceuta b/library/tzdata/Africa/Ceuta index 057ca22..18af8c1 100644 --- a/library/tzdata/Africa/Ceuta +++ b/library/tzdata/Africa/Ceuta @@ -15,6 +15,7 @@ set TZData(:Africa/Ceuta) { {-1316390400 3600 1 WEST} {-1301270400 0 0 WET} {-1293840000 0 0 WET} + {-94694400 0 0 WET} {-81432000 3600 1 WEST} {-71110800 0 0 WET} {141264000 3600 1 WEST} diff --git a/library/tzdata/America/Santiago b/library/tzdata/America/Santiago index 67d5b5c..55212b9 100644 --- a/library/tzdata/America/Santiago +++ b/library/tzdata/America/Santiago @@ -124,166 +124,166 @@ set TZData(:America/Santiago) { {1502596800 -10800 1 -04} {1526180400 -14400 0 -04} {1534046400 -10800 1 -04} - {1557630000 -14400 0 -04} - {1565496000 -10800 1 -04} - {1589079600 -14400 0 -04} - {1596945600 -10800 1 -04} - {1620529200 -14400 0 -04} - {1629000000 -10800 1 -04} - {1652583600 -14400 0 -04} - {1660449600 -10800 1 -04} - {1684033200 -14400 0 -04} - {1691899200 -10800 1 -04} - {1715482800 -14400 0 -04} - {1723348800 -10800 1 -04} - {1746932400 -14400 0 -04} - {1754798400 -10800 1 -04} - {1778382000 -14400 0 -04} - {1786248000 -10800 1 -04} - {1809831600 -14400 0 -04} - {1818302400 -10800 1 -04} - {1841886000 -14400 0 -04} - {1849752000 -10800 1 -04} - {1873335600 -14400 0 -04} - {1881201600 -10800 1 -04} - {1904785200 -14400 0 -04} - {1912651200 -10800 1 -04} - {1936234800 -14400 0 -04} - {1944100800 -10800 1 -04} - {1967684400 -14400 0 -04} - {1976155200 -10800 1 -04} - {1999738800 -14400 0 -04} - {2007604800 -10800 1 -04} - {2031188400 -14400 0 -04} - {2039054400 -10800 1 -04} - {2062638000 -14400 0 -04} - {2070504000 -10800 1 -04} - {2094087600 -14400 0 -04} - {2101953600 -10800 1 -04} - {2125537200 -14400 0 -04} - {2133403200 -10800 1 -04} - {2156986800 -14400 0 -04} - {2165457600 -10800 1 -04} - {2189041200 -14400 0 -04} - {2196907200 -10800 1 -04} - {2220490800 -14400 0 -04} - {2228356800 -10800 1 -04} - {2251940400 -14400 0 -04} - {2259806400 -10800 1 -04} - {2283390000 -14400 0 -04} - {2291256000 -10800 1 -04} - {2314839600 -14400 0 -04} - {2322705600 -10800 1 -04} - {2346894000 -14400 0 -04} - {2354760000 -10800 1 -04} - {2378343600 -14400 0 -04} - {2386209600 -10800 1 -04} - {2409793200 -14400 0 -04} - {2417659200 -10800 1 -04} - {2441242800 -14400 0 -04} - {2449108800 -10800 1 -04} - {2472692400 -14400 0 -04} - {2480558400 -10800 1 -04} - {2504142000 -14400 0 -04} - {2512612800 -10800 1 -04} - {2536196400 -14400 0 -04} - {2544062400 -10800 1 -04} - {2567646000 -14400 0 -04} - {2575512000 -10800 1 -04} - {2599095600 -14400 0 -04} - {2606961600 -10800 1 -04} - {2630545200 -14400 0 -04} - {2638411200 -10800 1 -04} - {2661994800 -14400 0 -04} - {2669860800 -10800 1 -04} - {2693444400 -14400 0 -04} - {2701915200 -10800 1 -04} - {2725498800 -14400 0 -04} - {2733364800 -10800 1 -04} - {2756948400 -14400 0 -04} - {2764814400 -10800 1 -04} - {2788398000 -14400 0 -04} - {2796264000 -10800 1 -04} - {2819847600 -14400 0 -04} - {2827713600 -10800 1 -04} - {2851297200 -14400 0 -04} - {2859768000 -10800 1 -04} - {2883351600 -14400 0 -04} - {2891217600 -10800 1 -04} - {2914801200 -14400 0 -04} - {2922667200 -10800 1 -04} - {2946250800 -14400 0 -04} - {2954116800 -10800 1 -04} - {2977700400 -14400 0 -04} - {2985566400 -10800 1 -04} - {3009150000 -14400 0 -04} - {3017016000 -10800 1 -04} - {3040599600 -14400 0 -04} - {3049070400 -10800 1 -04} - {3072654000 -14400 0 -04} - {3080520000 -10800 1 -04} - {3104103600 -14400 0 -04} - {3111969600 -10800 1 -04} - {3135553200 -14400 0 -04} - {3143419200 -10800 1 -04} - {3167002800 -14400 0 -04} - {3174868800 -10800 1 -04} - {3198452400 -14400 0 -04} - {3206318400 -10800 1 -04} - {3230506800 -14400 0 -04} - {3238372800 -10800 1 -04} - {3261956400 -14400 0 -04} - {3269822400 -10800 1 -04} - {3293406000 -14400 0 -04} - {3301272000 -10800 1 -04} - {3324855600 -14400 0 -04} - {3332721600 -10800 1 -04} - {3356305200 -14400 0 -04} - {3364171200 -10800 1 -04} - {3387754800 -14400 0 -04} - {3396225600 -10800 1 -04} - {3419809200 -14400 0 -04} - {3427675200 -10800 1 -04} - {3451258800 -14400 0 -04} - {3459124800 -10800 1 -04} - {3482708400 -14400 0 -04} - {3490574400 -10800 1 -04} - {3514158000 -14400 0 -04} - {3522024000 -10800 1 -04} - {3545607600 -14400 0 -04} - {3553473600 -10800 1 -04} - {3577057200 -14400 0 -04} - {3585528000 -10800 1 -04} - {3609111600 -14400 0 -04} - {3616977600 -10800 1 -04} - {3640561200 -14400 0 -04} - {3648427200 -10800 1 -04} - {3672010800 -14400 0 -04} - {3679876800 -10800 1 -04} - {3703460400 -14400 0 -04} - {3711326400 -10800 1 -04} - {3734910000 -14400 0 -04} - {3743380800 -10800 1 -04} - {3766964400 -14400 0 -04} - {3774830400 -10800 1 -04} - {3798414000 -14400 0 -04} - {3806280000 -10800 1 -04} - {3829863600 -14400 0 -04} - {3837729600 -10800 1 -04} - {3861313200 -14400 0 -04} - {3869179200 -10800 1 -04} - {3892762800 -14400 0 -04} - {3900628800 -10800 1 -04} - {3924212400 -14400 0 -04} - {3932683200 -10800 1 -04} - {3956266800 -14400 0 -04} - {3964132800 -10800 1 -04} - {3987716400 -14400 0 -04} - {3995582400 -10800 1 -04} - {4019166000 -14400 0 -04} - {4027032000 -10800 1 -04} - {4050615600 -14400 0 -04} - {4058481600 -10800 1 -04} - {4082065200 -14400 0 -04} - {4089931200 -10800 1 -04} + {1554606000 -14400 0 -04} + {1567915200 -10800 1 -04} + {1586055600 -14400 0 -04} + {1599364800 -10800 1 -04} + {1617505200 -14400 0 -04} + {1630814400 -10800 1 -04} + {1648954800 -14400 0 -04} + {1662264000 -10800 1 -04} + {1680404400 -14400 0 -04} + {1693713600 -10800 1 -04} + {1712458800 -14400 0 -04} + {1725768000 -10800 1 -04} + {1743908400 -14400 0 -04} + {1757217600 -10800 1 -04} + {1775358000 -14400 0 -04} + {1788667200 -10800 1 -04} + {1806807600 -14400 0 -04} + {1820116800 -10800 1 -04} + {1838257200 -14400 0 -04} + {1851566400 -10800 1 -04} + {1870311600 -14400 0 -04} + {1883016000 -10800 1 -04} + {1901761200 -14400 0 -04} + {1915070400 -10800 1 -04} + {1933210800 -14400 0 -04} + {1946520000 -10800 1 -04} + {1964660400 -14400 0 -04} + {1977969600 -10800 1 -04} + {1996110000 -14400 0 -04} + {2009419200 -10800 1 -04} + {2027559600 -14400 0 -04} + {2040868800 -10800 1 -04} + {2059614000 -14400 0 -04} + {2072318400 -10800 1 -04} + {2091063600 -14400 0 -04} + {2104372800 -10800 1 -04} + {2122513200 -14400 0 -04} + {2135822400 -10800 1 -04} + {2153962800 -14400 0 -04} + {2167272000 -10800 1 -04} + {2185412400 -14400 0 -04} + {2198721600 -10800 1 -04} + {2217466800 -14400 0 -04} + {2230171200 -10800 1 -04} + {2248916400 -14400 0 -04} + {2262225600 -10800 1 -04} + {2280366000 -14400 0 -04} + {2293675200 -10800 1 -04} + {2311815600 -14400 0 -04} + {2325124800 -10800 1 -04} + {2343265200 -14400 0 -04} + {2356574400 -10800 1 -04} + {2374714800 -14400 0 -04} + {2388024000 -10800 1 -04} + {2406769200 -14400 0 -04} + {2419473600 -10800 1 -04} + {2438218800 -14400 0 -04} + {2451528000 -10800 1 -04} + {2469668400 -14400 0 -04} + {2482977600 -10800 1 -04} + {2501118000 -14400 0 -04} + {2514427200 -10800 1 -04} + {2532567600 -14400 0 -04} + {2545876800 -10800 1 -04} + {2564017200 -14400 0 -04} + {2577326400 -10800 1 -04} + {2596071600 -14400 0 -04} + {2609380800 -10800 1 -04} + {2627521200 -14400 0 -04} + {2640830400 -10800 1 -04} + {2658970800 -14400 0 -04} + {2672280000 -10800 1 -04} + {2690420400 -14400 0 -04} + {2703729600 -10800 1 -04} + {2721870000 -14400 0 -04} + {2735179200 -10800 1 -04} + {2753924400 -14400 0 -04} + {2766628800 -10800 1 -04} + {2785374000 -14400 0 -04} + {2798683200 -10800 1 -04} + {2816823600 -14400 0 -04} + {2830132800 -10800 1 -04} + {2848273200 -14400 0 -04} + {2861582400 -10800 1 -04} + {2879722800 -14400 0 -04} + {2893032000 -10800 1 -04} + {2911172400 -14400 0 -04} + {2924481600 -10800 1 -04} + {2943226800 -14400 0 -04} + {2955931200 -10800 1 -04} + {2974676400 -14400 0 -04} + {2987985600 -10800 1 -04} + {3006126000 -14400 0 -04} + {3019435200 -10800 1 -04} + {3037575600 -14400 0 -04} + {3050884800 -10800 1 -04} + {3069025200 -14400 0 -04} + {3082334400 -10800 1 -04} + {3101079600 -14400 0 -04} + {3113784000 -10800 1 -04} + {3132529200 -14400 0 -04} + {3145838400 -10800 1 -04} + {3163978800 -14400 0 -04} + {3177288000 -10800 1 -04} + {3195428400 -14400 0 -04} + {3208737600 -10800 1 -04} + {3226878000 -14400 0 -04} + {3240187200 -10800 1 -04} + {3258327600 -14400 0 -04} + {3271636800 -10800 1 -04} + {3290382000 -14400 0 -04} + {3303086400 -10800 1 -04} + {3321831600 -14400 0 -04} + {3335140800 -10800 1 -04} + {3353281200 -14400 0 -04} + {3366590400 -10800 1 -04} + {3384730800 -14400 0 -04} + {3398040000 -10800 1 -04} + {3416180400 -14400 0 -04} + {3429489600 -10800 1 -04} + {3447630000 -14400 0 -04} + {3460939200 -10800 1 -04} + {3479684400 -14400 0 -04} + {3492993600 -10800 1 -04} + {3511134000 -14400 0 -04} + {3524443200 -10800 1 -04} + {3542583600 -14400 0 -04} + {3555892800 -10800 1 -04} + {3574033200 -14400 0 -04} + {3587342400 -10800 1 -04} + {3605482800 -14400 0 -04} + {3618792000 -10800 1 -04} + {3637537200 -14400 0 -04} + {3650241600 -10800 1 -04} + {3668986800 -14400 0 -04} + {3682296000 -10800 1 -04} + {3700436400 -14400 0 -04} + {3713745600 -10800 1 -04} + {3731886000 -14400 0 -04} + {3745195200 -10800 1 -04} + {3763335600 -14400 0 -04} + {3776644800 -10800 1 -04} + {3794785200 -14400 0 -04} + {3808094400 -10800 1 -04} + {3826839600 -14400 0 -04} + {3839544000 -10800 1 -04} + {3858289200 -14400 0 -04} + {3871598400 -10800 1 -04} + {3889738800 -14400 0 -04} + {3903048000 -10800 1 -04} + {3921188400 -14400 0 -04} + {3934497600 -10800 1 -04} + {3952638000 -14400 0 -04} + {3965947200 -10800 1 -04} + {3984692400 -14400 0 -04} + {3997396800 -10800 1 -04} + {4016142000 -14400 0 -04} + {4029451200 -10800 1 -04} + {4047591600 -14400 0 -04} + {4060900800 -10800 1 -04} + {4079041200 -14400 0 -04} + {4092350400 -10800 1 -04} } diff --git a/library/tzdata/Asia/Macau b/library/tzdata/Asia/Macau index 76a00aa..cbafd0e 100644 --- a/library/tzdata/Asia/Macau +++ b/library/tzdata/Asia/Macau @@ -1,20 +1,56 @@ # created by tools/tclZIC.tcl - do not edit set TZData(:Asia/Macau) { - {-9223372036854775808 27260 0 LMT} - {-1830412800 28800 0 CST} + {-9223372036854775808 27250 0 LMT} + {-2056692850 28800 0 CST} + {-884509200 32400 0 +09} + {-873280800 36000 1 +09} + {-855918000 32400 0 +09} + {-841744800 36000 1 +09} + {-828529200 32400 0 +10} + {-765363600 28800 0 CT} + {-747046800 32400 1 CDT} + {-733827600 28800 0 CST} + {-716461200 32400 1 CDT} + {-697021200 28800 0 CST} + {-683715600 32400 1 CDT} + {-667990800 28800 0 CST} + {-654771600 32400 1 CDT} + {-636627600 28800 0 CST} + {-623322000 32400 1 CDT} + {-605178000 28800 0 CST} + {-591872400 32400 1 CDT} + {-573642000 28800 0 CST} + {-559818000 32400 1 CDT} + {-541674000 28800 0 CST} + {-528368400 32400 1 CDT} + {-510224400 28800 0 CST} + {-498128400 32400 1 CDT} + {-478774800 28800 0 CST} + {-466678800 32400 1 CDT} + {-446720400 28800 0 CST} + {-435229200 32400 1 CDT} + {-415258200 28800 0 CST} + {-403158600 32400 1 CDT} + {-383808600 28800 0 CST} + {-371709000 32400 1 CDT} + {-352359000 28800 0 CST} + {-340259400 32400 1 CDT} + {-320909400 28800 0 CST} + {-308809800 32400 1 CDT} + {-288855000 28800 0 CST} {-277360200 32400 1 CDT} {-257405400 28800 0 CST} {-245910600 32400 1 CDT} {-225955800 28800 0 CST} - {-214473600 32400 1 CDT} + {-213856200 32400 1 CDT} {-194506200 28800 0 CST} {-182406600 32400 1 CDT} {-163056600 28800 0 CST} - {-150969600 32400 1 CDT} - {-131619600 28800 0 CST} + {-148537800 32400 1 CDT} + {-132820200 28800 0 CST} {-117088200 32400 1 CDT} - {-101367000 28800 0 CST} + {-101370600 28800 0 CST} {-85638600 32400 1 CDT} {-69312600 28800 0 CST} {-53584200 32400 1 CDT} @@ -25,22 +61,16 @@ set TZData(:Asia/Macau) { {25036200 28800 0 CST} {40764600 32400 1 CDT} {56485800 28800 0 CST} - {72201600 32400 1 CDT} - {87922800 28800 0 CST} - {103651200 32400 1 CDT} - {119977200 28800 0 CST} - {135705600 32400 1 CDT} + {72214200 32400 1 CDT} + {88540200 28800 0 CST} + {104268600 32400 1 CDT} + {119989800 28800 0 CST} + {126041400 32400 1 CDT} {151439400 28800 0 CST} {167167800 32400 1 CDT} {182889000 28800 0 CST} {198617400 32400 1 CDT} {214338600 28800 0 CST} - {230067000 32400 1 CDT} - {245788200 28800 0 CST} - {261504000 32400 1 CDT} - {277225200 28800 0 CST} - {292953600 32400 1 CDT} - {309279600 28800 0 CST} - {325008000 32400 1 CDT} - {340729200 28800 0 CST} + {295385400 32400 1 CDT} + {309292200 28800 0 CST} } diff --git a/library/tzdata/Asia/Manila b/library/tzdata/Asia/Manila index b7ffa7a..6eb1db3 100644 --- a/library/tzdata/Asia/Manila +++ b/library/tzdata/Asia/Manila @@ -3,13 +3,13 @@ set TZData(:Asia/Manila) { {-9223372036854775808 -57360 0 LMT} {-3944621040 29040 0 LMT} - {-2229321840 28800 0 +08} - {-1046678400 32400 1 +08} - {-1038733200 28800 0 +08} - {-873273600 32400 0 +09} - {-794221200 28800 0 +08} - {-496224000 32400 1 +08} - {-489315600 28800 0 +08} - {259344000 32400 1 +08} - {275151600 28800 0 +08} + {-2229321840 28800 0 PST} + {-1046678400 32400 1 PDT} + {-1038733200 28800 0 PST} + {-873273600 32400 0 JST} + {-794221200 28800 0 PST} + {-496224000 32400 1 PDT} + {-489315600 28800 0 PST} + {259344000 32400 1 PDT} + {275151600 28800 0 PST} } diff --git a/library/tzdata/Asia/Pyongyang b/library/tzdata/Asia/Pyongyang index 5746472..5351736 100644 --- a/library/tzdata/Asia/Pyongyang +++ b/library/tzdata/Asia/Pyongyang @@ -6,5 +6,5 @@ set TZData(:Asia/Pyongyang) { {-1830414600 32400 0 JST} {-768646800 32400 0 KST} {1439564400 30600 0 KST} - {1525447800 32400 0 KST} + {1525446000 32400 0 KST} } diff --git a/library/tzdata/Asia/Shanghai b/library/tzdata/Asia/Shanghai index ff2d2b5..66bc4339 100644 --- a/library/tzdata/Asia/Shanghai +++ b/library/tzdata/Asia/Shanghai @@ -3,21 +3,30 @@ set TZData(:Asia/Shanghai) { {-9223372036854775808 29143 0 LMT} {-2177481943 28800 0 CST} - {-933494400 32400 1 CDT} - {-923130000 28800 0 CST} - {-908784000 32400 1 CDT} - {-891594000 28800 0 CST} - {-662716800 28800 0 CST} - {515520000 32400 1 CDT} - {527007600 28800 0 CST} - {545155200 32400 1 CDT} - {558457200 28800 0 CST} - {576604800 32400 1 CDT} - {589906800 28800 0 CST} - {608659200 32400 1 CDT} - {621961200 28800 0 CST} - {640108800 32400 1 CDT} - {653410800 28800 0 CST} - {671558400 32400 1 CDT} - {684860400 28800 0 CST} + {-933667200 32400 1 CDT} + {-922093200 28800 0 CST} + {-908870400 32400 1 CDT} + {-888829200 28800 0 CST} + {-881049600 32400 1 CDT} + {-767869200 28800 0 CST} + {-745833600 32400 1 CDT} + {-733827600 28800 0 CST} + {-716889600 32400 1 CDT} + {-699613200 28800 0 CST} + {-683884800 32400 1 CDT} + {-670669200 28800 0 CST} + {-652348800 32400 1 CDT} + {-650016000 28800 0 CST} + {515527200 32400 1 CDT} + {527014800 28800 0 CST} + {545162400 32400 1 CDT} + {558464400 28800 0 CST} + {577216800 32400 1 CDT} + {589914000 28800 0 CST} + {608666400 32400 1 CDT} + {621968400 28800 0 CST} + {640116000 32400 1 CDT} + {653418000 28800 0 CST} + {671565600 32400 1 CDT} + {684867600 28800 0 CST} } diff --git a/library/tzdata/Asia/Tokyo b/library/tzdata/Asia/Tokyo index 790df0a..cc7a857 100644 --- a/library/tzdata/Asia/Tokyo +++ b/library/tzdata/Asia/Tokyo @@ -4,11 +4,11 @@ set TZData(:Asia/Tokyo) { {-9223372036854775808 33539 0 LMT} {-2587712400 32400 0 JST} {-683802000 36000 1 JDT} - {-672314400 32400 0 JST} + {-672310800 32400 0 JST} {-654771600 36000 1 JDT} - {-640864800 32400 0 JST} + {-640861200 32400 0 JST} {-620298000 36000 1 JDT} - {-609415200 32400 0 JST} + {-609411600 32400 0 JST} {-588848400 36000 1 JDT} - {-577965600 32400 0 JST} + {-577962000 32400 0 JST} } diff --git a/library/tzdata/Europe/Volgograd b/library/tzdata/Europe/Volgograd index 05e1044..3938683 100644 --- a/library/tzdata/Europe/Volgograd +++ b/library/tzdata/Europe/Volgograd @@ -68,4 +68,5 @@ set TZData(:Europe/Volgograd) { {1288479600 10800 0 +03} {1301180400 14400 0 +04} {1414274400 10800 0 +03} + {1540681200 14400 0 +04} } diff --git a/library/tzdata/Pacific/Easter b/library/tzdata/Pacific/Easter index a087cd0..7a8d525 100644 --- a/library/tzdata/Pacific/Easter +++ b/library/tzdata/Pacific/Easter @@ -103,166 +103,166 @@ set TZData(:Pacific/Easter) { {1502596800 -18000 1 -06} {1526180400 -21600 0 -06} {1534046400 -18000 1 -06} - {1557630000 -21600 0 -06} - {1565496000 -18000 1 -06} - {1589079600 -21600 0 -06} - {1596945600 -18000 1 -06} - {1620529200 -21600 0 -06} - {1629000000 -18000 1 -06} - {1652583600 -21600 0 -06} - {1660449600 -18000 1 -06} - {1684033200 -21600 0 -06} - {1691899200 -18000 1 -06} - {1715482800 -21600 0 -06} - {1723348800 -18000 1 -06} - {1746932400 -21600 0 -06} - {1754798400 -18000 1 -06} - {1778382000 -21600 0 -06} - {1786248000 -18000 1 -06} - {1809831600 -21600 0 -06} - {1818302400 -18000 1 -06} - {1841886000 -21600 0 -06} - {1849752000 -18000 1 -06} - {1873335600 -21600 0 -06} - {1881201600 -18000 1 -06} - {1904785200 -21600 0 -06} - {1912651200 -18000 1 -06} - {1936234800 -21600 0 -06} - {1944100800 -18000 1 -06} - {1967684400 -21600 0 -06} - {1976155200 -18000 1 -06} - {1999738800 -21600 0 -06} - {2007604800 -18000 1 -06} - {2031188400 -21600 0 -06} - {2039054400 -18000 1 -06} - {2062638000 -21600 0 -06} - {2070504000 -18000 1 -06} - {2094087600 -21600 0 -06} - {2101953600 -18000 1 -06} - {2125537200 -21600 0 -06} - {2133403200 -18000 1 -06} - {2156986800 -21600 0 -06} - {2165457600 -18000 1 -06} - {2189041200 -21600 0 -06} - {2196907200 -18000 1 -06} - {2220490800 -21600 0 -06} - {2228356800 -18000 1 -06} - {2251940400 -21600 0 -06} - {2259806400 -18000 1 -06} - {2283390000 -21600 0 -06} - {2291256000 -18000 1 -06} - {2314839600 -21600 0 -06} - {2322705600 -18000 1 -06} - {2346894000 -21600 0 -06} - {2354760000 -18000 1 -06} - {2378343600 -21600 0 -06} - {2386209600 -18000 1 -06} - {2409793200 -21600 0 -06} - {2417659200 -18000 1 -06} - {2441242800 -21600 0 -06} - {2449108800 -18000 1 -06} - {2472692400 -21600 0 -06} - {2480558400 -18000 1 -06} - {2504142000 -21600 0 -06} - {2512612800 -18000 1 -06} - {2536196400 -21600 0 -06} - {2544062400 -18000 1 -06} - {2567646000 -21600 0 -06} - {2575512000 -18000 1 -06} - {2599095600 -21600 0 -06} - {2606961600 -18000 1 -06} - {2630545200 -21600 0 -06} - {2638411200 -18000 1 -06} - {2661994800 -21600 0 -06} - {2669860800 -18000 1 -06} - {2693444400 -21600 0 -06} - {2701915200 -18000 1 -06} - {2725498800 -21600 0 -06} - {2733364800 -18000 1 -06} - {2756948400 -21600 0 -06} - {2764814400 -18000 1 -06} - {2788398000 -21600 0 -06} - {2796264000 -18000 1 -06} - {2819847600 -21600 0 -06} - {2827713600 -18000 1 -06} - {2851297200 -21600 0 -06} - {2859768000 -18000 1 -06} - {2883351600 -21600 0 -06} - {2891217600 -18000 1 -06} - {2914801200 -21600 0 -06} - {2922667200 -18000 1 -06} - {2946250800 -21600 0 -06} - {2954116800 -18000 1 -06} - {2977700400 -21600 0 -06} - {2985566400 -18000 1 -06} - {3009150000 -21600 0 -06} - {3017016000 -18000 1 -06} - {3040599600 -21600 0 -06} - {3049070400 -18000 1 -06} - {3072654000 -21600 0 -06} - {3080520000 -18000 1 -06} - {3104103600 -21600 0 -06} - {3111969600 -18000 1 -06} - {3135553200 -21600 0 -06} - {3143419200 -18000 1 -06} - {3167002800 -21600 0 -06} - {3174868800 -18000 1 -06} - {3198452400 -21600 0 -06} - {3206318400 -18000 1 -06} - {3230506800 -21600 0 -06} - {3238372800 -18000 1 -06} - {3261956400 -21600 0 -06} - {3269822400 -18000 1 -06} - {3293406000 -21600 0 -06} - {3301272000 -18000 1 -06} - {3324855600 -21600 0 -06} - {3332721600 -18000 1 -06} - {3356305200 -21600 0 -06} - {3364171200 -18000 1 -06} - {3387754800 -21600 0 -06} - {3396225600 -18000 1 -06} - {3419809200 -21600 0 -06} - {3427675200 -18000 1 -06} - {3451258800 -21600 0 -06} - {3459124800 -18000 1 -06} - {3482708400 -21600 0 -06} - {3490574400 -18000 1 -06} - {3514158000 -21600 0 -06} - {3522024000 -18000 1 -06} - {3545607600 -21600 0 -06} - {3553473600 -18000 1 -06} - {3577057200 -21600 0 -06} - {3585528000 -18000 1 -06} - {3609111600 -21600 0 -06} - {3616977600 -18000 1 -06} - {3640561200 -21600 0 -06} - {3648427200 -18000 1 -06} - {3672010800 -21600 0 -06} - {3679876800 -18000 1 -06} - {3703460400 -21600 0 -06} - {3711326400 -18000 1 -06} - {3734910000 -21600 0 -06} - {3743380800 -18000 1 -06} - {3766964400 -21600 0 -06} - {3774830400 -18000 1 -06} - {3798414000 -21600 0 -06} - {3806280000 -18000 1 -06} - {3829863600 -21600 0 -06} - {3837729600 -18000 1 -06} - {3861313200 -21600 0 -06} - {3869179200 -18000 1 -06} - {3892762800 -21600 0 -06} - {3900628800 -18000 1 -06} - {3924212400 -21600 0 -06} - {3932683200 -18000 1 -06} - {3956266800 -21600 0 -06} - {3964132800 -18000 1 -06} - {3987716400 -21600 0 -06} - {3995582400 -18000 1 -06} - {4019166000 -21600 0 -06} - {4027032000 -18000 1 -06} - {4050615600 -21600 0 -06} - {4058481600 -18000 1 -06} - {4082065200 -21600 0 -06} - {4089931200 -18000 1 -06} + {1554606000 -21600 0 -06} + {1567915200 -18000 1 -06} + {1586055600 -21600 0 -06} + {1599364800 -18000 1 -06} + {1617505200 -21600 0 -06} + {1630814400 -18000 1 -06} + {1648954800 -21600 0 -06} + {1662264000 -18000 1 -06} + {1680404400 -21600 0 -06} + {1693713600 -18000 1 -06} + {1712458800 -21600 0 -06} + {1725768000 -18000 1 -06} + {1743908400 -21600 0 -06} + {1757217600 -18000 1 -06} + {1775358000 -21600 0 -06} + {1788667200 -18000 1 -06} + {1806807600 -21600 0 -06} + {1820116800 -18000 1 -06} + {1838257200 -21600 0 -06} + {1851566400 -18000 1 -06} + {1870311600 -21600 0 -06} + {1883016000 -18000 1 -06} + {1901761200 -21600 0 -06} + {1915070400 -18000 1 -06} + {1933210800 -21600 0 -06} + {1946520000 -18000 1 -06} + {1964660400 -21600 0 -06} + {1977969600 -18000 1 -06} + {1996110000 -21600 0 -06} + {2009419200 -18000 1 -06} + {2027559600 -21600 0 -06} + {2040868800 -18000 1 -06} + {2059614000 -21600 0 -06} + {2072318400 -18000 1 -06} + {2091063600 -21600 0 -06} + {2104372800 -18000 1 -06} + {2122513200 -21600 0 -06} + {2135822400 -18000 1 -06} + {2153962800 -21600 0 -06} + {2167272000 -18000 1 -06} + {2185412400 -21600 0 -06} + {2198721600 -18000 1 -06} + {2217466800 -21600 0 -06} + {2230171200 -18000 1 -06} + {2248916400 -21600 0 -06} + {2262225600 -18000 1 -06} + {2280366000 -21600 0 -06} + {2293675200 -18000 1 -06} + {2311815600 -21600 0 -06} + {2325124800 -18000 1 -06} + {2343265200 -21600 0 -06} + {2356574400 -18000 1 -06} + {2374714800 -21600 0 -06} + {2388024000 -18000 1 -06} + {2406769200 -21600 0 -06} + {2419473600 -18000 1 -06} + {2438218800 -21600 0 -06} + {2451528000 -18000 1 -06} + {2469668400 -21600 0 -06} + {2482977600 -18000 1 -06} + {2501118000 -21600 0 -06} + {2514427200 -18000 1 -06} + {2532567600 -21600 0 -06} + {2545876800 -18000 1 -06} + {2564017200 -21600 0 -06} + {2577326400 -18000 1 -06} + {2596071600 -21600 0 -06} + {2609380800 -18000 1 -06} + {2627521200 -21600 0 -06} + {2640830400 -18000 1 -06} + {2658970800 -21600 0 -06} + {2672280000 -18000 1 -06} + {2690420400 -21600 0 -06} + {2703729600 -18000 1 -06} + {2721870000 -21600 0 -06} + {2735179200 -18000 1 -06} + {2753924400 -21600 0 -06} + {2766628800 -18000 1 -06} + {2785374000 -21600 0 -06} + {2798683200 -18000 1 -06} + {2816823600 -21600 0 -06} + {2830132800 -18000 1 -06} + {2848273200 -21600 0 -06} + {2861582400 -18000 1 -06} + {2879722800 -21600 0 -06} + {2893032000 -18000 1 -06} + {2911172400 -21600 0 -06} + {2924481600 -18000 1 -06} + {2943226800 -21600 0 -06} + {2955931200 -18000 1 -06} + {2974676400 -21600 0 -06} + {2987985600 -18000 1 -06} + {3006126000 -21600 0 -06} + {3019435200 -18000 1 -06} + {3037575600 -21600 0 -06} + {3050884800 -18000 1 -06} + {3069025200 -21600 0 -06} + {3082334400 -18000 1 -06} + {3101079600 -21600 0 -06} + {3113784000 -18000 1 -06} + {3132529200 -21600 0 -06} + {3145838400 -18000 1 -06} + {3163978800 -21600 0 -06} + {3177288000 -18000 1 -06} + {3195428400 -21600 0 -06} + {3208737600 -18000 1 -06} + {3226878000 -21600 0 -06} + {3240187200 -18000 1 -06} + {3258327600 -21600 0 -06} + {3271636800 -18000 1 -06} + {3290382000 -21600 0 -06} + {3303086400 -18000 1 -06} + {3321831600 -21600 0 -06} + {3335140800 -18000 1 -06} + {3353281200 -21600 0 -06} + {3366590400 -18000 1 -06} + {3384730800 -21600 0 -06} + {3398040000 -18000 1 -06} + {3416180400 -21600 0 -06} + {3429489600 -18000 1 -06} + {3447630000 -21600 0 -06} + {3460939200 -18000 1 -06} + {3479684400 -21600 0 -06} + {3492993600 -18000 1 -06} + {3511134000 -21600 0 -06} + {3524443200 -18000 1 -06} + {3542583600 -21600 0 -06} + {3555892800 -18000 1 -06} + {3574033200 -21600 0 -06} + {3587342400 -18000 1 -06} + {3605482800 -21600 0 -06} + {3618792000 -18000 1 -06} + {3637537200 -21600 0 -06} + {3650241600 -18000 1 -06} + {3668986800 -21600 0 -06} + {3682296000 -18000 1 -06} + {3700436400 -21600 0 -06} + {3713745600 -18000 1 -06} + {3731886000 -21600 0 -06} + {3745195200 -18000 1 -06} + {3763335600 -21600 0 -06} + {3776644800 -18000 1 -06} + {3794785200 -21600 0 -06} + {3808094400 -18000 1 -06} + {3826839600 -21600 0 -06} + {3839544000 -18000 1 -06} + {3858289200 -21600 0 -06} + {3871598400 -18000 1 -06} + {3889738800 -21600 0 -06} + {3903048000 -18000 1 -06} + {3921188400 -21600 0 -06} + {3934497600 -18000 1 -06} + {3952638000 -21600 0 -06} + {3965947200 -18000 1 -06} + {3984692400 -21600 0 -06} + {3997396800 -18000 1 -06} + {4016142000 -21600 0 -06} + {4029451200 -18000 1 -06} + {4047591600 -21600 0 -06} + {4060900800 -18000 1 -06} + {4079041200 -21600 0 -06} + {4092350400 -18000 1 -06} } diff --git a/library/tzdata/Pacific/Fiji b/library/tzdata/Pacific/Fiji index 610c191..b05985c 100644 --- a/library/tzdata/Pacific/Fiji +++ b/library/tzdata/Pacific/Fiji @@ -26,7 +26,7 @@ set TZData(:Pacific/Fiji) { {1509804000 46800 1 +12} {1515852000 43200 0 +12} {1541253600 46800 1 +12} - {1547906400 43200 0 +12} + {1547301600 43200 0 +12} {1572703200 46800 1 +12} {1579356000 43200 0 +12} {1604152800 46800 1 +12} @@ -48,7 +48,7 @@ set TZData(:Pacific/Fiji) { {1856959200 46800 1 +12} {1863007200 43200 0 +12} {1888408800 46800 1 +12} - {1895061600 43200 0 +12} + {1894456800 43200 0 +12} {1919858400 46800 1 +12} {1926511200 43200 0 +12} {1951308000 46800 1 +12} @@ -60,7 +60,7 @@ set TZData(:Pacific/Fiji) { {2046261600 46800 1 +12} {2052309600 43200 0 +12} {2077711200 46800 1 +12} - {2084364000 43200 0 +12} + {2083759200 43200 0 +12} {2109160800 46800 1 +12} {2115813600 43200 0 +12} {2140610400 46800 1 +12} @@ -70,7 +70,7 @@ set TZData(:Pacific/Fiji) { {2204114400 46800 1 +12} {2210162400 43200 0 +12} {2235564000 46800 1 +12} - {2242216800 43200 0 +12} + {2241612000 43200 0 +12} {2267013600 46800 1 +12} {2273666400 43200 0 +12} {2298463200 46800 1 +12} @@ -82,7 +82,7 @@ set TZData(:Pacific/Fiji) { {2393416800 46800 1 +12} {2399464800 43200 0 +12} {2424866400 46800 1 +12} - {2431519200 43200 0 +12} + {2430914400 43200 0 +12} {2456316000 46800 1 +12} {2462968800 43200 0 +12} {2487765600 46800 1 +12} @@ -104,7 +104,7 @@ set TZData(:Pacific/Fiji) { {2740572000 46800 1 +12} {2746620000 43200 0 +12} {2772021600 46800 1 +12} - {2778674400 43200 0 +12} + {2778069600 43200 0 +12} {2803471200 46800 1 +12} {2810124000 43200 0 +12} {2834920800 46800 1 +12} @@ -116,7 +116,7 @@ set TZData(:Pacific/Fiji) { {2929874400 46800 1 +12} {2935922400 43200 0 +12} {2961324000 46800 1 +12} - {2967976800 43200 0 +12} + {2967372000 43200 0 +12} {2992773600 46800 1 +12} {2999426400 43200 0 +12} {3024223200 46800 1 +12} @@ -126,7 +126,7 @@ set TZData(:Pacific/Fiji) { {3087727200 46800 1 +12} {3093775200 43200 0 +12} {3119176800 46800 1 +12} - {3125829600 43200 0 +12} + {3125224800 43200 0 +12} {3150626400 46800 1 +12} {3157279200 43200 0 +12} {3182076000 46800 1 +12} @@ -138,7 +138,7 @@ set TZData(:Pacific/Fiji) { {3277029600 46800 1 +12} {3283077600 43200 0 +12} {3308479200 46800 1 +12} - {3315132000 43200 0 +12} + {3314527200 43200 0 +12} {3339928800 46800 1 +12} {3346581600 43200 0 +12} {3371378400 46800 1 +12} @@ -160,7 +160,7 @@ set TZData(:Pacific/Fiji) { {3624184800 46800 1 +12} {3630232800 43200 0 +12} {3655634400 46800 1 +12} - {3662287200 43200 0 +12} + {3661682400 43200 0 +12} {3687084000 46800 1 +12} {3693736800 43200 0 +12} {3718533600 46800 1 +12} @@ -172,7 +172,7 @@ set TZData(:Pacific/Fiji) { {3813487200 46800 1 +12} {3819535200 43200 0 +12} {3844936800 46800 1 +12} - {3851589600 43200 0 +12} + {3850984800 43200 0 +12} {3876386400 46800 1 +12} {3883039200 43200 0 +12} {3907836000 46800 1 +12} @@ -182,7 +182,7 @@ set TZData(:Pacific/Fiji) { {3971340000 46800 1 +12} {3977388000 43200 0 +12} {4002789600 46800 1 +12} - {4009442400 43200 0 +12} + {4008837600 43200 0 +12} {4034239200 46800 1 +12} {4040892000 43200 0 +12} {4065688800 46800 1 +12} -- cgit v0.12 From 20213492498c729f4a953da797793ba5471607d8 Mon Sep 17 00:00:00 2001 From: dkf Date: Thu, 18 Oct 2018 21:38:08 +0000 Subject: Make fundamental mutation work. MAGICAL MAGIC MAGICS MAGIC. Abracadabra. --- generic/tclOO.c | 109 +++++++++++++++++++++++++++++----------------- generic/tclOOCall.c | 1 - generic/tclOODefineCmds.c | 14 +++++- generic/tclOOInt.h | 8 ++++ tests/oo.test | 17 +++++--- 5 files changed, 101 insertions(+), 48 deletions(-) diff --git a/generic/tclOO.c b/generic/tclOO.c index 83646a8..573df3e 100644 --- a/generic/tclOO.c +++ b/generic/tclOO.c @@ -56,7 +56,6 @@ static const struct { * Function declarations for things defined in this file. */ -static Class * AllocClass(Tcl_Interp *interp, Object *useThisObj); static Object * AllocObject(Tcl_Interp *interp, const char *nameStr, Namespace *nsPtr, const char *nsNameStr); static int CloneClassMethod(Tcl_Interp *interp, Class *clsPtr, @@ -79,8 +78,6 @@ static void ObjectNamespaceDeleted(ClientData clientData); static void ObjectRenamedTrace(ClientData clientData, Tcl_Interp *interp, const char *oldName, const char *newName, int flags); -static void ReleaseClassContents(Tcl_Interp *interp,Object *oPtr); -static void DeleteDescendants(Tcl_Interp *interp,Object *oPtr); static inline void SquelchCachedName(Object *oPtr); static int PublicObjectCmd(ClientData clientData, @@ -392,10 +389,10 @@ InitFoundation( /* Stand up a phony class for bootstrapping. */ fPtr->objectCls = &fakeCls; - /* referenced in AllocClass to increment the refCount. */ + /* referenced in TclOOAllocClass to increment the refCount. */ fakeCls.thisPtr = &fakeObject; - fPtr->objectCls = AllocClass(interp, + fPtr->objectCls = TclOOAllocClass(interp, AllocObject(interp, "object", (Namespace *)fPtr->ooNs, NULL)); /* Corresponding TclOODecrRefCount in KillFoudation */ AddRef(fPtr->objectCls->thisPtr); @@ -411,7 +408,7 @@ InitFoundation( fPtr->objectCls->thisPtr->flags |= ROOT_OBJECT; fPtr->objectCls->flags |= ROOT_OBJECT; - fPtr->classCls = AllocClass(interp, + fPtr->classCls = TclOOAllocClass(interp, AllocObject(interp, "class", (Namespace *)fPtr->ooNs, NULL)); /* Corresponding TclOODecrRefCount in KillFoudation */ AddRef(fPtr->classCls->thisPtr); @@ -829,15 +826,15 @@ ObjectRenamedTrace( /* * ---------------------------------------------------------------------- * - * DeleteDescendants -- + * TclOODeleteDescendants -- * * Delete all descendants of a particular class. * * ---------------------------------------------------------------------- */ -static void -DeleteDescendants( +void +TclOODeleteDescendants( Tcl_Interp *interp, /* The interpreter containing the class. */ Object *oPtr) /* The object representing the class. */ { @@ -854,7 +851,8 @@ DeleteDescendants( /* This condition also covers the case where mixinSubclassPtr == * clsPtr */ - if (!Deleted(mixinSubclassPtr->thisPtr)) { + if (!Deleted(mixinSubclassPtr->thisPtr) + && !(mixinSubclassPtr->thisPtr->flags & DONT_DELETE)) { Tcl_DeleteCommandFromToken(interp, mixinSubclassPtr->thisPtr->command); } @@ -872,8 +870,10 @@ DeleteDescendants( if (clsPtr->subclasses.num > 0) { while (clsPtr->subclasses.num > 0) { subclassPtr = clsPtr->subclasses.list[clsPtr->subclasses.num-1]; - if (!Deleted(subclassPtr->thisPtr) && !IsRoot(subclassPtr)) { - Tcl_DeleteCommandFromToken(interp, subclassPtr->thisPtr->command); + if (!Deleted(subclassPtr->thisPtr) && !IsRoot(subclassPtr) + && !(subclassPtr->thisPtr->flags & DONT_DELETE)) { + Tcl_DeleteCommandFromToken(interp, + subclassPtr->thisPtr->command); } TclOORemoveFromSubclasses(subclassPtr, clsPtr); } @@ -892,7 +892,8 @@ DeleteDescendants( while (clsPtr->instances.num > 0) { instancePtr = clsPtr->instances.list[clsPtr->instances.num-1]; /* This condition also covers the case where instancePtr == oPtr */ - if (!Deleted(instancePtr) && !IsRoot(instancePtr)) { + if (!Deleted(instancePtr) && !IsRoot(instancePtr) && + !(instancePtr->flags & DONT_DELETE)) { Tcl_DeleteCommandFromToken(interp, instancePtr->command); } TclOORemoveFromInstances(instancePtr, clsPtr); @@ -909,7 +910,7 @@ DeleteDescendants( /* * ---------------------------------------------------------------------- * - * ReleaseClassContents -- + * TclOOReleaseClassContents -- * * Tear down the special class data structure, including deleting all * dependent classes and objects. @@ -917,8 +918,8 @@ DeleteDescendants( * ---------------------------------------------------------------------- */ -static void -ReleaseClassContents( +void +TclOOReleaseClassContents( Tcl_Interp *interp, /* The interpreter containing the class. */ Object *oPtr) /* The object representing the class. */ { @@ -940,9 +941,6 @@ ReleaseClassContents( } else if (IsRootObject(oPtr)) { Tcl_Panic("deleting class structure for non-deleted %s", "::oo::object"); - } else { - Tcl_Panic("deleting class structure for non-deleted %s", - "general object"); } } @@ -1037,6 +1035,7 @@ ReleaseClassContents( if (IsRootClass(oPtr) && !Deleted(fPtr->objectCls->thisPtr)) { Tcl_DeleteCommandFromToken(interp, fPtr->objectCls->thisPtr->command); } + oPtr->classPtr = NULL; } /* @@ -1082,7 +1081,7 @@ ObjectNamespaceDeleted( /* Let the dominoes fall */ if (oPtr->classPtr) { - DeleteDescendants(interp, oPtr); + TclOODeleteDescendants(interp, oPtr); } /* @@ -1194,27 +1193,25 @@ ObjectNamespaceDeleted( } /* - * Because an object can be a class that is an instance of itself, the - * A class object's class structure should only be cleaned after most of - * the cleanup on the object is done. - */ - - - /* + * Because an object can be a class that is an instance of itself, the + * class object's class structure should only be cleaned after most of + * the cleanup on the object is done. + * * The class of objects needs some special care; if it is deleted (and * we're not killing the whole interpreter) we force the delete of the * class of classes now as well. Due to the incestuous nature of those two * classes, if one goes the other must too and yet the tangle can * sometimes not go away automatically; we force it here. [Bug 2962664] */ + if (IsRootObject(oPtr) && !Deleted(fPtr->classCls->thisPtr) - && !Tcl_InterpDeleted(interp)) { + && !Tcl_InterpDeleted(interp)) { Tcl_DeleteCommandFromToken(interp, fPtr->classCls->thisPtr->command); } if (oPtr->classPtr != NULL) { - ReleaseClassContents(interp, oPtr); + TclOOReleaseClassContents(interp, oPtr); } /* @@ -1328,6 +1325,37 @@ TclOOAddToInstances( /* * ---------------------------------------------------------------------- * + * TclOORemoveFromMixins -- + * + * Utility function to remove a class from the list of mixins within an + * object. + * + * ---------------------------------------------------------------------- + */ + +int +TclOORemoveFromMixins( + Class *mixinPtr, /* The mixin to remove. */ + Object *oPtr) /* The object (possibly) containing the + * reference to the mixin. */ +{ + int i, res = 0; + Class *mixPtr; + + FOREACH(mixPtr, oPtr->mixins) { + if (mixinPtr == mixPtr) { + RemoveItem(Class, oPtr->mixins, i); + TclOODecrRefCount(mixPtr->thisPtr); + res++; + break; + } + } + return res; +} + +/* + * ---------------------------------------------------------------------- + * * TclOORemoveFromSubclasses -- * * Utility function to remove a class from the list of subclasses within @@ -1381,7 +1409,8 @@ TclOOAddToSubclasses( if (superPtr->subclasses.size == ALLOC_CHUNK) { superPtr->subclasses.list = ckalloc(sizeof(Class *) * ALLOC_CHUNK); } else { - superPtr->subclasses.list = ckrealloc(superPtr->subclasses.list, sizeof(Class *) * superPtr->subclasses.size); + superPtr->subclasses.list = ckrealloc(superPtr->subclasses.list, + sizeof(Class *) * superPtr->subclasses.size); } } superPtr->subclasses.list[superPtr->subclasses.num++] = subPtr; @@ -1456,16 +1485,16 @@ TclOOAddToMixinSubs( /* * ---------------------------------------------------------------------- * - * AllocClass -- + * TclOOAllocClass -- * - * Allocate a basic class. Does not add class to its - * class's instance list. + * Allocate a basic class. Does not add class to its class's instance + * list. * * ---------------------------------------------------------------------- */ -static Class * -AllocClass( +Class * +TclOOAllocClass( Tcl_Interp *interp, /* Interpreter within which to allocate the * class. */ Object *useThisObj) /* Object that is to act as the class @@ -1709,13 +1738,13 @@ TclNewObjectInstanceCommon( if (TclOOIsReachable(fPtr->classCls, classPtr)) { /* - * Is a class, so attach a class structure. Note that the AllocClass - * function splices the structure into the object, so we don't have - * to. Once that's done, we need to repatch the object to have the - * right class since AllocClass interferes with that. + * Is a class, so attach a class structure. Note that the + * TclOOAllocClass function splices the structure into the object, so + * we don't have to. Once that's done, we need to repatch the object + * to have the right class since TclOOAllocClass interferes with that. */ - AllocClass(interp, oPtr); + TclOOAllocClass(interp, oPtr); TclOOAddToSubclasses(oPtr->classPtr, fPtr->objectCls); } else { oPtr->classPtr = NULL; diff --git a/generic/tclOOCall.c b/generic/tclOOCall.c index c71425b..a46b8bc 100644 --- a/generic/tclOOCall.c +++ b/generic/tclOOCall.c @@ -1444,7 +1444,6 @@ AddSimpleClassChainToCallContext( if (flags & CONSTRUCTOR) { AddMethodToCallChain(classPtr->constructorPtr, cbPtr, doneFilters, filterDecl, flags); - } else if (flags & DESTRUCTOR) { AddMethodToCallChain(classPtr->destructorPtr, cbPtr, doneFilters, filterDecl, flags); diff --git a/generic/tclOODefineCmds.c b/generic/tclOODefineCmds.c index f5fe676..d5f4878 100644 --- a/generic/tclOODefineCmds.c +++ b/generic/tclOODefineCmds.c @@ -1146,9 +1146,19 @@ TclOODefineClassObjCmd( */ if (wasClass && !willBeClass) { - /* TODO: DELETE THE STRUCTURE */ + /* + * This is the most global of all epochs. Bump it! No cache can be + * trusted! + */ + + TclOORemoveFromMixins(oPtr->classPtr, oPtr); + oPtr->fPtr->epoch++; + oPtr->flags |= DONT_DELETE; + TclOODeleteDescendants(interp, oPtr); + oPtr->flags &= ~DONT_DELETE; + TclOOReleaseClassContents(interp, oPtr); } else if (!wasClass && willBeClass) { - /* TODO: CREATE THE STRUCTURE */ + TclOOAllocClass(interp, oPtr); } if (oPtr->classPtr != NULL) { diff --git a/generic/tclOOInt.h b/generic/tclOOInt.h index 61ead01..e59fe8a 100644 --- a/generic/tclOOInt.h +++ b/generic/tclOOInt.h @@ -214,6 +214,7 @@ typedef struct Object { * other spots). */ #define FORCE_UNKNOWN 0x10000 /* States that we are *really* looking up the * unknown method handler at that point. */ +#define DONT_DELETE 0x20000 /* Inhibit deletion of this object. */ /* * And the definition of a class. Note that every class also has an associated @@ -484,6 +485,8 @@ MODULE_SCOPE int TclOO_Object_VarName(ClientData clientData, MODULE_SCOPE void TclOOAddToInstances(Object *oPtr, Class *clsPtr); MODULE_SCOPE void TclOOAddToMixinSubs(Class *subPtr, Class *mixinPtr); MODULE_SCOPE void TclOOAddToSubclasses(Class *subPtr, Class *superPtr); +MODULE_SCOPE Class * TclOOAllocClass(Tcl_Interp *interp, + Object *useThisObj); MODULE_SCOPE int TclNRNewObjectInstance(Tcl_Interp *interp, Tcl_Class cls, const char *nameStr, const char *nsNameStr, int objc, @@ -498,6 +501,8 @@ MODULE_SCOPE int TclOODefineSlots(Foundation *fPtr); MODULE_SCOPE void TclOODeleteChain(CallChain *callPtr); MODULE_SCOPE void TclOODeleteChainCache(Tcl_HashTable *tablePtr); MODULE_SCOPE void TclOODeleteContext(CallContext *contextPtr); +MODULE_SCOPE void TclOODeleteDescendants(Tcl_Interp *interp, + Object *oPtr); MODULE_SCOPE void TclOODelMethodRef(Method *method); MODULE_SCOPE CallContext *TclOOGetCallContext(Object *oPtr, Tcl_Obj *methodNameObj, int flags, @@ -523,7 +528,10 @@ MODULE_SCOPE int TclNRObjectContextInvokeNext(Tcl_Interp *interp, MODULE_SCOPE void TclOONewBasicMethod(Tcl_Interp *interp, Class *clsPtr, const DeclaredClassMethod *dcm); MODULE_SCOPE Tcl_Obj * TclOOObjectName(Tcl_Interp *interp, Object *oPtr); +MODULE_SCOPE void TclOOReleaseClassContents(Tcl_Interp *interp, + Object *oPtr); MODULE_SCOPE int TclOORemoveFromInstances(Object *oPtr, Class *clsPtr); +MODULE_SCOPE int TclOORemoveFromMixins(Class *mixinPtr, Object *oPtr); MODULE_SCOPE int TclOORemoveFromMixinSubs(Class *subPtr, Class *mixinPtr); MODULE_SCOPE int TclOORemoveFromSubclasses(Class *subPtr, diff --git a/tests/oo.test b/tests/oo.test index 7f0de4a..0558746 100644 --- a/tests/oo.test +++ b/tests/oo.test @@ -1804,7 +1804,7 @@ test oo-13.4 {OO: changing an object's class} -body { foo destroy bar destroy } -result {::foo ::foo ::foo ::bar} -test oo-13.5 {OO: changing an object's class} -setup { +test oo-13.5 {OO: changing an object's class: non-class to class} -setup { oo::object create fooObj } -body { oo::objdefine fooObj { @@ -1817,21 +1817,28 @@ test oo-13.5 {OO: changing an object's class} -setup { } -cleanup { fooObj destroy } -result 6 -test oo-13.6 {OO: changing an object's class} -setup { +test oo-13.6 {OO: changing an object's class: class to non-class} -setup { oo::class create foo + unset -nocomplain ::result } -body { + set result dangling oo::define foo { method x {} {expr 1+2+3} } + oo::class create boo { + superclass foo + destructor {set ::result "ok"} + } + boo new foo create bar oo::objdefine foo { class oo::object } - list [catch {bar x} msg] $msg + list $result [catch {bar x} msg] $msg } -cleanup { catch {bar destroy} foo destroy -} -result {1 {}} +} -result {ok 1 {invalid command name "bar"}} test oo-13.7 {OO: changing an object's class} -setup { oo::class create foo oo::class create bar @@ -1849,7 +1856,7 @@ test oo-13.7 {OO: changing an object's class} -setup { foo destroy bar destroy } -result {6 ok} -test oo-13.7 {OO: changing an object's class to itself} -setup { +test oo-13.8 {OO: changing an object's class to itself} -setup { oo::class create foo } -body { oo::define foo { -- cgit v0.12 From 09446c7544e32d0eca9c0c68d7917729e6c33ee8 Mon Sep 17 00:00:00 2001 From: dkf Date: Fri, 19 Oct 2018 09:59:14 +0000 Subject: Added another test case. This one is OK. --- tests/oo.test | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/tests/oo.test b/tests/oo.test index 0558746..db5c14f 100644 --- a/tests/oo.test +++ b/tests/oo.test @@ -1888,6 +1888,22 @@ test oo-13.10 {OO: changing an object's class: roots are special} -setup { } -cleanup { interp delete $i } -returnCodes error -result {may not modify the class of the class of classes} +test oo-13.11 {OO: changing an object's class in a tricky place} -setup { + oo::class create cls + unset -nocomplain result +} -body { + set result gorp + list [catch { + oo::define cls { + method x {} {return} + self class oo::object + ::set ::result ok + method y {} {return}; # I'm sorry, Dave. I'm afraid I can't do that. + } + } msg] $msg $result +} -cleanup { + cls destroy +} -result {1 {attempt to misuse API} ok} # todo: changing a class subtype (metaclass) to another class subtype test oo-14.1 {OO: mixins} { -- cgit v0.12 From 49aba3d99eb7035ee260003ddc27728b26962d43 Mon Sep 17 00:00:00 2001 From: "jan.nijtmans" Date: Fri, 19 Oct 2018 15:51:36 +0000 Subject: Add support for "nostub" in genStubs.tcl. Not used by Tcl 8.6, but might be used by Tk 8.7 when linked against Tcl 8.6 --- tools/genStubs.tcl | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/tools/genStubs.tcl b/tools/genStubs.tcl index 830ba2b..f2f410f 100644 --- a/tools/genStubs.tcl +++ b/tools/genStubs.tcl @@ -198,6 +198,13 @@ proc genStubs::declare {args} { || ($index > $stubs($curName,generic,lastNum))} { set stubs($curName,generic,lastNum) $index } + } elseif {([lindex $platformList 0] eq "nostub")} { + set stubs($curName,nostub,$index) [lindex $platformList 1] + set stubs($curName,generic,$index) $decl + if {![info exists stubs($curName,generic,lastNum)] \ + || ($index > $stubs($curName,generic,lastNum))} { + set stubs($curName,generic,lastNum) $index + } } else { foreach platform $platformList { if {$decl ne ""} { @@ -593,6 +600,8 @@ proc genStubs::makeSlot {name decl index} { set text " " if {[info exists stubs($name,deprecated,$index)]} { append text "TCL_DEPRECATED_API(\"$stubs($name,deprecated,$index)\") " + } elseif {[info exists stubs($name,nostub,$index)]} { + append text "TCL_DEPRECATED_API(\"$stubs($name,nostub,$index)\") " } if {$args eq ""} { append text $rtype " *" $lfname "; /* $index */\n" @@ -705,6 +714,9 @@ proc genStubs::forAllStubs {name slotProc onAll textVar if {[info exists stubs($name,deprecated,$i)]} { append text [$slotProc $name $stubs($name,generic,$i) $i] set emit 1 + } elseif {[info exists stubs($name,nostub,$i)]} { + append text [$slotProc $name $stubs($name,generic,$i) $i] + set emit 1 } elseif {[info exists stubs($name,generic,$i)]} { if {[llength $slots] > 1} { puts stderr "conflicting generic and platform entries:\ -- cgit v0.12