-- cgit v0.12 From c86a23de04031e905caf60b8b28dfeed64b8ba5f Mon Sep 17 00:00:00 2001 From: "f.bonnet" Date: Thu, 17 Aug 2017 13:02:27 +0000 Subject: Basic scaffolding for tcl::process --- generic/tclBasic.c | 1 + generic/tclInt.h | 1 + generic/tclProcess.c | 175 +++++++++++++++++++++++++++++++++++++++++++++++++++ tests/process.test | 21 +++++++ unix/Makefile.in | 6 +- win/Makefile.in | 1 + win/buildall.vc.bat | 4 +- win/makefile.vc | 1 + win/tcl.dsp | 4 ++ 9 files changed, 212 insertions(+), 2 deletions(-) create mode 100644 generic/tclProcess.c create mode 100644 tests/process.test diff --git a/generic/tclBasic.c b/generic/tclBasic.c index 8e816a5..b4821ef 100644 --- a/generic/tclBasic.c +++ b/generic/tclBasic.c @@ -813,6 +813,7 @@ Tcl_CreateInterp(void) TclInitNamespaceCmd(interp); TclInitStringCmd(interp); TclInitPrefixCmd(interp); + TclInitProcessCmd(interp); /* * Register "clock" subcommands. These *do* go through diff --git a/generic/tclInt.h b/generic/tclInt.h index 1fbc541..ce6cc1c 100644 --- a/generic/tclInt.h +++ b/generic/tclInt.h @@ -3414,6 +3414,7 @@ MODULE_SCOPE int Tcl_PidObjCmd(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *const objv[]); MODULE_SCOPE Tcl_Command TclInitPrefixCmd(Tcl_Interp *interp); +MODULE_SCOPE Tcl_Command TclInitProcessCmd(Tcl_Interp *interp); MODULE_SCOPE int Tcl_PutsObjCmd(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *const objv[]); diff --git a/generic/tclProcess.c b/generic/tclProcess.c new file mode 100644 index 0000000..3fcdacd --- /dev/null +++ b/generic/tclProcess.c @@ -0,0 +1,175 @@ +/* + * tclProcess.c -- + * + * This file implements the "tcl::process" ensemble for subprocess + * management as defined by TIP #462. + * + * Copyright (c) 2017 Frederic Bonnet. + * + * See the file "license.terms" for information on usage and redistribution of + * this file, and for a DISCLAIMER OF ALL WARRANTIES. + */ + + #include "tclInt.h" + + /* + * Prototypes for functions defined later in this file: + */ + +static int ProcessListObjCmd(ClientData clientData, + Tcl_Interp *interp, int objc, + Tcl_Obj *const objv[]); +static int ProcessStatusObjCmd(ClientData clientData, + Tcl_Interp *interp, int objc, + Tcl_Obj *const objv[]); +static int ProcessPurgeObjCmd(ClientData clientData, + Tcl_Interp *interp, int objc, + Tcl_Obj *const objv[]); +static int ProcessAutopurgeObjCmd(ClientData clientData, + Tcl_Interp *interp, int objc, + Tcl_Obj *const objv[]); + +/*---------------------------------------------------------------------- + * + * ProcessListObjCmd -- + * + * This function implements the 'tcl::process list' Tcl command. + * Refer to the user documentation for details on what it does. + * + * Results: + * Returns a standard Tcl result. + * + * Side effects: + * None.TODO + * + *---------------------------------------------------------------------- + */ + + static int + ProcessListObjCmd( + ClientData clientData, /* Not used. */ + Tcl_Interp *interp, /* Current interpreter. */ + int objc, /* Number of arguments. */ + Tcl_Obj *const objv[]) /* Argument objects. */ + { + /* TODO */ + return TCL_ERROR; + } + +/*---------------------------------------------------------------------- + * + * ProcessStatusObjCmd -- + * + * This function implements the 'tcl::process status' Tcl command. + * Refer to the user documentation for details on what it does. + * + * Results: + * Returns a standard Tcl result. + * + * Side effects: + * None.TODO + * + *---------------------------------------------------------------------- + */ + + static int + ProcessStatusObjCmd( + ClientData clientData, /* Not used. */ + Tcl_Interp *interp, /* Current interpreter. */ + int objc, /* Number of arguments. */ + Tcl_Obj *const objv[]) /* Argument objects. */ + { + /* TODO */ + return TCL_ERROR; + } + +/*---------------------------------------------------------------------- + * + * ProcessPurgeObjCmd -- + * + * This function implements the 'tcl::process purge' Tcl command. + * Refer to the user documentation for details on what it does. + * + * Results: + * Returns a standard Tcl result. + * + * Side effects: + * None.TODO + * + *---------------------------------------------------------------------- + */ + + static int + ProcessPurgeObjCmd( + ClientData clientData, /* Not used. */ + Tcl_Interp *interp, /* Current interpreter. */ + int objc, /* Number of arguments. */ + Tcl_Obj *const objv[]) /* Argument objects. */ + { + /* TODO */ + return TCL_ERROR; + } + +/*---------------------------------------------------------------------- + * + * ProcessAutopurgeObjCmd -- + * + * This function implements the 'tcl::process autopurge' Tcl command. + * Refer to the user documentation for details on what it does. + * + * Results: + * Returns a standard Tcl result. + * + * Side effects: + * None.TODO + * + *---------------------------------------------------------------------- + */ + + static int + ProcessAutopurgeObjCmd( + ClientData clientData, /* Not used. */ + Tcl_Interp *interp, /* Current interpreter. */ + int objc, /* Number of arguments. */ + Tcl_Obj *const objv[]) /* Argument objects. */ + { + /* TODO */ + return TCL_ERROR; + } + +/* + *---------------------------------------------------------------------- + * + * TclInitProcessCmd -- + * + * This procedure creates the "tcl::process" Tcl command. See the user + * documentation for details on what it does. + * + * Results: + * A standard Tcl result. + * + * Side effects: + * See the user documentation. + * + *---------------------------------------------------------------------- + */ + + Tcl_Command + TclInitProcessCmd( + Tcl_Interp *interp) /* Current interpreter. */ + { + static const EnsembleImplMap processImplMap[] = { + {"list", ProcessListObjCmd, TclCompileBasic0ArgCmd, NULL, NULL, 1}, + {"status", ProcessStatusObjCmd, TclCompileBasicMin0ArgCmd, NULL, NULL, 1}, + {"purge", ProcessPurgeObjCmd, TclCompileBasic0Or1ArgCmd, NULL, NULL, 1}, + {"autopurge", ProcessAutopurgeObjCmd, TclCompileBasic0Or1ArgCmd, NULL, NULL, 1}, + {NULL, NULL, NULL, NULL, NULL, 0} + }; + Tcl_Command processCmd; + + processCmd = TclMakeEnsemble(interp, "::tcl::process", processImplMap); + Tcl_Export(interp, Tcl_FindNamespace(interp, "::tcl", NULL, 0), + "process", 0); + return processCmd; + } + \ No newline at end of file diff --git a/tests/process.test b/tests/process.test new file mode 100644 index 0000000..f3275c8 --- /dev/null +++ b/tests/process.test @@ -0,0 +1,21 @@ +# process.test -- +# +# This file contains a collection of tests for the tcl::process ensemble. +# Sourcing this file into Tcl runs the tests and generates output for +# errors. No output means no errors were found. +# +# Copyright (c) 2017 Frederic Bonnet +# See the file "license.terms" for information on usage and redistribution of +# this file, and for a DISCLAIMER OF ALL WARRANTIES. + +if {[lsearch [namespace children] ::tcltest] == -1} { + package require tcltest 2 + namespace import -force ::tcltest::* +} + +test process-1.1 {tcl::process command basic syntax} -returnCodes error -body { + tcl::process +} -result {wrong # args: should be "tcl::process subcommand ?arg ...?"} +test process-1.2 {tcl::process command basic syntax} -returnCodes error -body { + tcl::process ? +} -match glob -result {unknown or ambiguous subcommand "?": must be autopurge, list, purge, or status} diff --git a/unix/Makefile.in b/unix/Makefile.in index c4f6136..25aa003 100644 --- a/unix/Makefile.in +++ b/unix/Makefile.in @@ -303,7 +303,7 @@ GENERIC_OBJS = regcomp.o regexec.o regfree.o regerror.o tclAlloc.o \ tclLiteral.o tclLoad.o tclMain.o tclNamesp.o tclNotify.o \ tclObj.o tclOptimize.o tclPanic.o tclParse.o tclPathObj.o tclPipe.o \ tclPkg.o tclPkgConfig.o tclPosixStr.o \ - tclPreserve.o tclProc.o tclRegexp.o \ + tclPreserve.o tclProc.o tclProcess.o tclRegexp.o \ tclResolve.o tclResult.o tclScan.o tclStringObj.o \ tclStrToD.o tclThread.o \ tclThreadAlloc.o tclThreadJoin.o tclThreadStorage.o tclStubInit.o \ @@ -444,6 +444,7 @@ GENERIC_SRCS = \ $(GENERIC_DIR)/tclPosixStr.c \ $(GENERIC_DIR)/tclPreserve.c \ $(GENERIC_DIR)/tclProc.c \ + $(GENERIC_DIR)/tclProcess.c \ $(GENERIC_DIR)/tclRegexp.c \ $(GENERIC_DIR)/tclResolve.c \ $(GENERIC_DIR)/tclResult.c \ @@ -1286,6 +1287,9 @@ tclPreserve.o: $(GENERIC_DIR)/tclPreserve.c tclProc.o: $(GENERIC_DIR)/tclProc.c $(COMPILEHDR) $(NREHDR) $(CC) -c $(CC_SWITCHES) $(GENERIC_DIR)/tclProc.c +tclProcess.o: $(GENERIC_DIR)/tclProcess.c + $(CC) -c $(CC_SWITCHES) $(GENERIC_DIR)/tclProcess.c + tclRegexp.o: $(GENERIC_DIR)/tclRegexp.c $(TCLREHDRS) $(CC) -c $(CC_SWITCHES) $(GENERIC_DIR)/tclRegexp.c diff --git a/win/Makefile.in b/win/Makefile.in index e967ef3..ad8db34 100644 --- a/win/Makefile.in +++ b/win/Makefile.in @@ -285,6 +285,7 @@ GENERIC_OBJS = \ tclPosixStr.$(OBJEXT) \ tclPreserve.$(OBJEXT) \ tclProc.$(OBJEXT) \ + tclProcess.$(OBJEXT) \ tclRegexp.$(OBJEXT) \ tclResolve.$(OBJEXT) \ tclResult.$(OBJEXT) \ diff --git a/win/buildall.vc.bat b/win/buildall.vc.bat index deb9e39..cb136be 100644 --- a/win/buildall.vc.bat +++ b/win/buildall.vc.bat @@ -38,7 +38,9 @@ if defined WINDOWSSDKDIR (goto :startBuilding) :: might not be correct. You should call it yourself prior to running :: this batchfile. :: -call "C:\Program Files\Microsoft Developer Studio\vc98\bin\vcvars32.bat" +REM call "C:\Program Files\Microsoft Developer Studio\vc98\bin\vcvars32.bat" +set "VSCMD_START_DIR=%CD%" +call "C:\Program Files (x86)\Microsoft Visual Studio\2017\Community\Common7\Tools\VsDevCmd.bat" if errorlevel 1 (goto no_vcvars) :startBuilding diff --git a/win/makefile.vc b/win/makefile.vc index d6de5e1..bdc8511 100644 --- a/win/makefile.vc +++ b/win/makefile.vc @@ -327,6 +327,7 @@ COREOBJS = \ $(TMP_DIR)\tclPosixStr.obj \ $(TMP_DIR)\tclPreserve.obj \ $(TMP_DIR)\tclProc.obj \ + $(TMP_DIR)\tclProcess.obj \ $(TMP_DIR)\tclRegexp.obj \ $(TMP_DIR)\tclResolve.obj \ $(TMP_DIR)\tclResult.obj \ diff --git a/win/tcl.dsp b/win/tcl.dsp index 48eae9d..e3873a3 100644 --- a/win/tcl.dsp +++ b/win/tcl.dsp @@ -1268,6 +1268,10 @@ SOURCE=..\generic\tclProc.c # End Source File # Begin Source File +SOURCE=..\generic\tclProcess.c +# End Source File +# Begin Source File + SOURCE=..\generic\tclRegexp.c # End Source File # Begin Source File -- cgit v0.12 From 0b8e964f45cff8228e6e64598b7f7f80060aa345 Mon Sep 17 00:00:00 2001 From: "f.bonnet" Date: Thu, 17 Aug 2017 13:03:48 +0000 Subject: Fixed line endings --- generic/tclProcess.c | 348 +++++++++++++++++++++++++-------------------------- tests/process.test | 42 +++---- 2 files changed, 195 insertions(+), 195 deletions(-) diff --git a/generic/tclProcess.c b/generic/tclProcess.c index 3fcdacd..516d0d7 100644 --- a/generic/tclProcess.c +++ b/generic/tclProcess.c @@ -1,175 +1,175 @@ -/* - * tclProcess.c -- - * - * This file implements the "tcl::process" ensemble for subprocess - * management as defined by TIP #462. - * - * Copyright (c) 2017 Frederic Bonnet. - * - * See the file "license.terms" for information on usage and redistribution of - * this file, and for a DISCLAIMER OF ALL WARRANTIES. - */ - - #include "tclInt.h" - - /* - * Prototypes for functions defined later in this file: - */ - -static int ProcessListObjCmd(ClientData clientData, - Tcl_Interp *interp, int objc, - Tcl_Obj *const objv[]); -static int ProcessStatusObjCmd(ClientData clientData, - Tcl_Interp *interp, int objc, - Tcl_Obj *const objv[]); -static int ProcessPurgeObjCmd(ClientData clientData, - Tcl_Interp *interp, int objc, - Tcl_Obj *const objv[]); -static int ProcessAutopurgeObjCmd(ClientData clientData, - Tcl_Interp *interp, int objc, - Tcl_Obj *const objv[]); - -/*---------------------------------------------------------------------- - * - * ProcessListObjCmd -- - * - * This function implements the 'tcl::process list' Tcl command. - * Refer to the user documentation for details on what it does. - * - * Results: - * Returns a standard Tcl result. - * - * Side effects: - * None.TODO - * - *---------------------------------------------------------------------- - */ - - static int - ProcessListObjCmd( - ClientData clientData, /* Not used. */ - Tcl_Interp *interp, /* Current interpreter. */ - int objc, /* Number of arguments. */ - Tcl_Obj *const objv[]) /* Argument objects. */ - { - /* TODO */ - return TCL_ERROR; - } - -/*---------------------------------------------------------------------- - * - * ProcessStatusObjCmd -- - * - * This function implements the 'tcl::process status' Tcl command. - * Refer to the user documentation for details on what it does. - * - * Results: - * Returns a standard Tcl result. - * - * Side effects: - * None.TODO - * - *---------------------------------------------------------------------- - */ - - static int - ProcessStatusObjCmd( - ClientData clientData, /* Not used. */ - Tcl_Interp *interp, /* Current interpreter. */ - int objc, /* Number of arguments. */ - Tcl_Obj *const objv[]) /* Argument objects. */ - { - /* TODO */ - return TCL_ERROR; - } - -/*---------------------------------------------------------------------- - * - * ProcessPurgeObjCmd -- - * - * This function implements the 'tcl::process purge' Tcl command. - * Refer to the user documentation for details on what it does. - * - * Results: - * Returns a standard Tcl result. - * - * Side effects: - * None.TODO - * - *---------------------------------------------------------------------- - */ - - static int - ProcessPurgeObjCmd( - ClientData clientData, /* Not used. */ - Tcl_Interp *interp, /* Current interpreter. */ - int objc, /* Number of arguments. */ - Tcl_Obj *const objv[]) /* Argument objects. */ - { - /* TODO */ - return TCL_ERROR; - } - -/*---------------------------------------------------------------------- - * - * ProcessAutopurgeObjCmd -- - * - * This function implements the 'tcl::process autopurge' Tcl command. - * Refer to the user documentation for details on what it does. - * - * Results: - * Returns a standard Tcl result. - * - * Side effects: - * None.TODO - * - *---------------------------------------------------------------------- - */ - - static int - ProcessAutopurgeObjCmd( - ClientData clientData, /* Not used. */ - Tcl_Interp *interp, /* Current interpreter. */ - int objc, /* Number of arguments. */ - Tcl_Obj *const objv[]) /* Argument objects. */ - { - /* TODO */ - return TCL_ERROR; - } - -/* - *---------------------------------------------------------------------- - * - * TclInitProcessCmd -- - * - * This procedure creates the "tcl::process" Tcl command. See the user - * documentation for details on what it does. - * - * Results: - * A standard Tcl result. - * - * Side effects: - * See the user documentation. - * - *---------------------------------------------------------------------- - */ - - Tcl_Command - TclInitProcessCmd( - Tcl_Interp *interp) /* Current interpreter. */ - { - static const EnsembleImplMap processImplMap[] = { - {"list", ProcessListObjCmd, TclCompileBasic0ArgCmd, NULL, NULL, 1}, - {"status", ProcessStatusObjCmd, TclCompileBasicMin0ArgCmd, NULL, NULL, 1}, - {"purge", ProcessPurgeObjCmd, TclCompileBasic0Or1ArgCmd, NULL, NULL, 1}, - {"autopurge", ProcessAutopurgeObjCmd, TclCompileBasic0Or1ArgCmd, NULL, NULL, 1}, - {NULL, NULL, NULL, NULL, NULL, 0} - }; - Tcl_Command processCmd; - - processCmd = TclMakeEnsemble(interp, "::tcl::process", processImplMap); - Tcl_Export(interp, Tcl_FindNamespace(interp, "::tcl", NULL, 0), - "process", 0); - return processCmd; - } +/* + * tclProcess.c -- + * + * This file implements the "tcl::process" ensemble for subprocess + * management as defined by TIP #462. + * + * Copyright (c) 2017 Frederic Bonnet. + * + * See the file "license.terms" for information on usage and redistribution of + * this file, and for a DISCLAIMER OF ALL WARRANTIES. + */ + + #include "tclInt.h" + + /* + * Prototypes for functions defined later in this file: + */ + +static int ProcessListObjCmd(ClientData clientData, + Tcl_Interp *interp, int objc, + Tcl_Obj *const objv[]); +static int ProcessStatusObjCmd(ClientData clientData, + Tcl_Interp *interp, int objc, + Tcl_Obj *const objv[]); +static int ProcessPurgeObjCmd(ClientData clientData, + Tcl_Interp *interp, int objc, + Tcl_Obj *const objv[]); +static int ProcessAutopurgeObjCmd(ClientData clientData, + Tcl_Interp *interp, int objc, + Tcl_Obj *const objv[]); + +/*---------------------------------------------------------------------- + * + * ProcessListObjCmd -- + * + * This function implements the 'tcl::process list' Tcl command. + * Refer to the user documentation for details on what it does. + * + * Results: + * Returns a standard Tcl result. + * + * Side effects: + * None.TODO + * + *---------------------------------------------------------------------- + */ + + static int + ProcessListObjCmd( + ClientData clientData, /* Not used. */ + Tcl_Interp *interp, /* Current interpreter. */ + int objc, /* Number of arguments. */ + Tcl_Obj *const objv[]) /* Argument objects. */ + { + /* TODO */ + return TCL_ERROR; + } + +/*---------------------------------------------------------------------- + * + * ProcessStatusObjCmd -- + * + * This function implements the 'tcl::process status' Tcl command. + * Refer to the user documentation for details on what it does. + * + * Results: + * Returns a standard Tcl result. + * + * Side effects: + * None.TODO + * + *---------------------------------------------------------------------- + */ + + static int + ProcessStatusObjCmd( + ClientData clientData, /* Not used. */ + Tcl_Interp *interp, /* Current interpreter. */ + int objc, /* Number of arguments. */ + Tcl_Obj *const objv[]) /* Argument objects. */ + { + /* TODO */ + return TCL_ERROR; + } + +/*---------------------------------------------------------------------- + * + * ProcessPurgeObjCmd -- + * + * This function implements the 'tcl::process purge' Tcl command. + * Refer to the user documentation for details on what it does. + * + * Results: + * Returns a standard Tcl result. + * + * Side effects: + * None.TODO + * + *---------------------------------------------------------------------- + */ + + static int + ProcessPurgeObjCmd( + ClientData clientData, /* Not used. */ + Tcl_Interp *interp, /* Current interpreter. */ + int objc, /* Number of arguments. */ + Tcl_Obj *const objv[]) /* Argument objects. */ + { + /* TODO */ + return TCL_ERROR; + } + +/*---------------------------------------------------------------------- + * + * ProcessAutopurgeObjCmd -- + * + * This function implements the 'tcl::process autopurge' Tcl command. + * Refer to the user documentation for details on what it does. + * + * Results: + * Returns a standard Tcl result. + * + * Side effects: + * None.TODO + * + *---------------------------------------------------------------------- + */ + + static int + ProcessAutopurgeObjCmd( + ClientData clientData, /* Not used. */ + Tcl_Interp *interp, /* Current interpreter. */ + int objc, /* Number of arguments. */ + Tcl_Obj *const objv[]) /* Argument objects. */ + { + /* TODO */ + return TCL_ERROR; + } + +/* + *---------------------------------------------------------------------- + * + * TclInitProcessCmd -- + * + * This procedure creates the "tcl::process" Tcl command. See the user + * documentation for details on what it does. + * + * Results: + * A standard Tcl result. + * + * Side effects: + * See the user documentation. + * + *---------------------------------------------------------------------- + */ + + Tcl_Command + TclInitProcessCmd( + Tcl_Interp *interp) /* Current interpreter. */ + { + static const EnsembleImplMap processImplMap[] = { + {"list", ProcessListObjCmd, TclCompileBasic0ArgCmd, NULL, NULL, 1}, + {"status", ProcessStatusObjCmd, TclCompileBasicMin0ArgCmd, NULL, NULL, 1}, + {"purge", ProcessPurgeObjCmd, TclCompileBasic0Or1ArgCmd, NULL, NULL, 1}, + {"autopurge", ProcessAutopurgeObjCmd, TclCompileBasic0Or1ArgCmd, NULL, NULL, 1}, + {NULL, NULL, NULL, NULL, NULL, 0} + }; + Tcl_Command processCmd; + + processCmd = TclMakeEnsemble(interp, "::tcl::process", processImplMap); + Tcl_Export(interp, Tcl_FindNamespace(interp, "::tcl", NULL, 0), + "process", 0); + return processCmd; + } \ No newline at end of file diff --git a/tests/process.test b/tests/process.test index f3275c8..cef3adc 100644 --- a/tests/process.test +++ b/tests/process.test @@ -1,21 +1,21 @@ -# process.test -- -# -# This file contains a collection of tests for the tcl::process ensemble. -# Sourcing this file into Tcl runs the tests and generates output for -# errors. No output means no errors were found. -# -# Copyright (c) 2017 Frederic Bonnet -# See the file "license.terms" for information on usage and redistribution of -# this file, and for a DISCLAIMER OF ALL WARRANTIES. - -if {[lsearch [namespace children] ::tcltest] == -1} { - package require tcltest 2 - namespace import -force ::tcltest::* -} - -test process-1.1 {tcl::process command basic syntax} -returnCodes error -body { - tcl::process -} -result {wrong # args: should be "tcl::process subcommand ?arg ...?"} -test process-1.2 {tcl::process command basic syntax} -returnCodes error -body { - tcl::process ? -} -match glob -result {unknown or ambiguous subcommand "?": must be autopurge, list, purge, or status} +# process.test -- +# +# This file contains a collection of tests for the tcl::process ensemble. +# Sourcing this file into Tcl runs the tests and generates output for +# errors. No output means no errors were found. +# +# Copyright (c) 2017 Frederic Bonnet +# See the file "license.terms" for information on usage and redistribution of +# this file, and for a DISCLAIMER OF ALL WARRANTIES. + +if {[lsearch [namespace children] ::tcltest] == -1} { + package require tcltest 2 + namespace import -force ::tcltest::* +} + +test process-1.1 {tcl::process command basic syntax} -returnCodes error -body { + tcl::process +} -result {wrong # args: should be "tcl::process subcommand ?arg ...?"} +test process-1.2 {tcl::process command basic syntax} -returnCodes error -body { + tcl::process ? +} -match glob -result {unknown or ambiguous subcommand "?": must be autopurge, list, purge, or status} -- cgit v0.12 From 5aaef06572dc90a7a493d187959fe9829da27fbb Mon Sep 17 00:00:00 2001 From: "f.bonnet" Date: Fri, 18 Aug 2017 07:51:01 +0000 Subject: Added [tcl::process autopurge] flag management with TclProcessGetAutopurge/TclProcessSetAutopurge companion functions. --- generic/tclInt.h | 9 ++- generic/tclProcess.c | 176 +++++++++++++++++++++++++++++++++++++-------------- tests/process.test | 10 +++ 3 files changed, 148 insertions(+), 47 deletions(-) diff --git a/generic/tclInt.h b/generic/tclInt.h index ce6cc1c..a602e6c 100644 --- a/generic/tclInt.h +++ b/generic/tclInt.h @@ -3414,7 +3414,6 @@ MODULE_SCOPE int Tcl_PidObjCmd(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *const objv[]); MODULE_SCOPE Tcl_Command TclInitPrefixCmd(Tcl_Interp *interp); -MODULE_SCOPE Tcl_Command TclInitProcessCmd(Tcl_Interp *interp); MODULE_SCOPE int Tcl_PutsObjCmd(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *const objv[]); @@ -4023,6 +4022,14 @@ MODULE_SCOPE TCL_HASH_TYPE TclHashObjKey(Tcl_HashTable *tablePtr, void *keyPtr); MODULE_SCOPE int TclFullFinalizationRequested(void); /* + * TIP #462. + */ + +MODULE_SCOPE Tcl_Command TclInitProcessCmd(Tcl_Interp *interp); +MODULE_SCOPE int TclProcessGetAutopurge(void); +MODULE_SCOPE void TclProcessSetAutopurge(int flag); + +/* *---------------------------------------------------------------- * Macros used by the Tcl core to create and release Tcl objects. * TclNewObj(objPtr) creates a new object denoting an empty string. diff --git a/generic/tclProcess.c b/generic/tclProcess.c index 516d0d7..23ba4de 100644 --- a/generic/tclProcess.c +++ b/generic/tclProcess.c @@ -10,7 +10,9 @@ * this file, and for a DISCLAIMER OF ALL WARRANTIES. */ - #include "tclInt.h" +#include "tclInt.h" + +static int autopurge = 1; /* Autopurge flag. */ /* * Prototypes for functions defined later in this file: @@ -45,13 +47,18 @@ static int ProcessAutopurgeObjCmd(ClientData clientData, *---------------------------------------------------------------------- */ - static int - ProcessListObjCmd( - ClientData clientData, /* Not used. */ - Tcl_Interp *interp, /* Current interpreter. */ - int objc, /* Number of arguments. */ - Tcl_Obj *const objv[]) /* Argument objects. */ - { +static int +ProcessListObjCmd( + ClientData clientData, /* Not used. */ + Tcl_Interp *interp, /* Current interpreter. */ + int objc, /* Number of arguments. */ + Tcl_Obj *const objv[]) /* Argument objects. */ +{ + if (objc != 1) { + Tcl_WrongNumArgs(interp, 1, objv, NULL); + return TCL_ERROR; + } + /* TODO */ return TCL_ERROR; } @@ -72,13 +79,18 @@ static int ProcessAutopurgeObjCmd(ClientData clientData, *---------------------------------------------------------------------- */ - static int - ProcessStatusObjCmd( - ClientData clientData, /* Not used. */ - Tcl_Interp *interp, /* Current interpreter. */ - int objc, /* Number of arguments. */ - Tcl_Obj *const objv[]) /* Argument objects. */ - { +static int +ProcessStatusObjCmd( + ClientData clientData, /* Not used. */ + Tcl_Interp *interp, /* Current interpreter. */ + int objc, /* Number of arguments. */ + Tcl_Obj *const objv[]) /* Argument objects. */ +{ + if (objc < 1) { + Tcl_WrongNumArgs(interp, 1, objv, "?switches? ?pids?"); + return TCL_ERROR; + } + /* TODO */ return TCL_ERROR; } @@ -99,13 +111,18 @@ static int ProcessAutopurgeObjCmd(ClientData clientData, *---------------------------------------------------------------------- */ - static int - ProcessPurgeObjCmd( - ClientData clientData, /* Not used. */ - Tcl_Interp *interp, /* Current interpreter. */ - int objc, /* Number of arguments. */ - Tcl_Obj *const objv[]) /* Argument objects. */ - { +static int +ProcessPurgeObjCmd( + ClientData clientData, /* Not used. */ + Tcl_Interp *interp, /* Current interpreter. */ + int objc, /* Number of arguments. */ + Tcl_Obj *const objv[]) /* Argument objects. */ +{ + if (objc != 1 && objc != 2) { + Tcl_WrongNumArgs(interp, 1, objv, "?pids?"); + return TCL_ERROR; + } + /* TODO */ return TCL_ERROR; } @@ -126,17 +143,40 @@ static int ProcessAutopurgeObjCmd(ClientData clientData, *---------------------------------------------------------------------- */ - static int - ProcessAutopurgeObjCmd( - ClientData clientData, /* Not used. */ - Tcl_Interp *interp, /* Current interpreter. */ - int objc, /* Number of arguments. */ - Tcl_Obj *const objv[]) /* Argument objects. */ +static int +ProcessAutopurgeObjCmd( + ClientData clientData, /* Not used. */ + Tcl_Interp *interp, /* Current interpreter. */ + int objc, /* Number of arguments. */ + Tcl_Obj *const objv[]) /* Argument objects. */ { - /* TODO */ - return TCL_ERROR; - } - + if (objc != 1 && objc != 2) { + Tcl_WrongNumArgs(interp, 1, objv, "?flag?"); + return TCL_ERROR; + } + + if (objc == 2) { + /* + * Set given value. + */ + + int flag; + int result = Tcl_GetBooleanFromObj(interp, objv[1], &flag); + if (result != TCL_OK) { + return result; + } + + TclProcessSetAutopurge(flag); + } + + /* + * Return current value. + */ + + Tcl_SetObjResult(interp, Tcl_NewBooleanObj(TclProcessGetAutopurge())); + return TCL_OK; +} + /* *---------------------------------------------------------------------- * @@ -154,22 +194,66 @@ static int ProcessAutopurgeObjCmd(ClientData clientData, *---------------------------------------------------------------------- */ - Tcl_Command - TclInitProcessCmd( - Tcl_Interp *interp) /* Current interpreter. */ - { - static const EnsembleImplMap processImplMap[] = { +Tcl_Command +TclInitProcessCmd( + Tcl_Interp *interp) /* Current interpreter. */ +{ + static const EnsembleImplMap processImplMap[] = { {"list", ProcessListObjCmd, TclCompileBasic0ArgCmd, NULL, NULL, 1}, {"status", ProcessStatusObjCmd, TclCompileBasicMin0ArgCmd, NULL, NULL, 1}, {"purge", ProcessPurgeObjCmd, TclCompileBasic0Or1ArgCmd, NULL, NULL, 1}, {"autopurge", ProcessAutopurgeObjCmd, TclCompileBasic0Or1ArgCmd, NULL, NULL, 1}, {NULL, NULL, NULL, NULL, NULL, 0} - }; - Tcl_Command processCmd; - - processCmd = TclMakeEnsemble(interp, "::tcl::process", processImplMap); - Tcl_Export(interp, Tcl_FindNamespace(interp, "::tcl", NULL, 0), - "process", 0); - return processCmd; - } - \ No newline at end of file + }; + Tcl_Command processCmd; + + processCmd = TclMakeEnsemble(interp, "::tcl::process", processImplMap); + Tcl_Export(interp, Tcl_FindNamespace(interp, "::tcl", NULL, 0), + "process", 0); + return processCmd; +} + +/* + *---------------------------------------------------------------------- + * + * TclProcessGetAutopurge -- + * + * This function queries the value of the autopurge flag. + * + * Results: + * The current boolean value of the autopurge flag. + * + * Side effects: + * None. + * + *---------------------------------------------------------------------- + */ + +int +TclProcessGetAutopurge(void) +{ + return autopurge; +} + +/* + *---------------------------------------------------------------------- + * + * TclProcessSetAutopurge -- + * + * This function sets the value of the autopurge flag. + * + * Results: + * None. + * + * Side effects: + * Sets the autopurge static variable. + * + *---------------------------------------------------------------------- + */ + +void +TclProcessSetAutopurge( + int flag) /* New value for autopurge. */ +{ + autopurge = !!flag; +} diff --git a/tests/process.test b/tests/process.test index cef3adc..fb3a5e2 100644 --- a/tests/process.test +++ b/tests/process.test @@ -19,3 +19,13 @@ test process-1.1 {tcl::process command basic syntax} -returnCodes error -body { test process-1.2 {tcl::process command basic syntax} -returnCodes error -body { tcl::process ? } -match glob -result {unknown or ambiguous subcommand "?": must be autopurge, list, purge, or status} + +test process-2.1 {tcl::process autopurge get} {tcl::process autopurge} {1} +test process-2.2 {tcl::process autopurge set true} { + tcl::process autopurge true + tcl::process autopurge +} {1} +test process-2.3 {tcl::process autopurge set false} { + tcl::process autopurge false + tcl::process autopurge +} {0} -- cgit v0.12 From 03470df2ff2414f1912a85772cd6f558196ca8bc Mon Sep 17 00:00:00 2001 From: "f.bonnet" Date: Fri, 18 Aug 2017 12:49:08 +0000 Subject: Completed [tcl::process autopurge] semantics and added [tcl::process purge] implementation along with the necessary internal functions TclpGetChildPid/TclReapPids --- generic/tclInt.h | 2 ++ generic/tclIntPlatDecls.h | 2 ++ generic/tclPipe.c | 59 ++++++++++++++++++++++++++++++++++++++++++++++- generic/tclProcess.c | 45 +++++++++++++++++++++++++++++++++--- unix/tclUnixPipe.c | 4 +++- win/tclWinPipe.c | 42 ++++++++++++++++++++++++++++++++- 6 files changed, 148 insertions(+), 6 deletions(-) diff --git a/generic/tclInt.h b/generic/tclInt.h index a602e6c..3e99f91 100644 --- a/generic/tclInt.h +++ b/generic/tclInt.h @@ -4028,6 +4028,8 @@ MODULE_SCOPE int TclFullFinalizationRequested(void); MODULE_SCOPE Tcl_Command TclInitProcessCmd(Tcl_Interp *interp); MODULE_SCOPE int TclProcessGetAutopurge(void); MODULE_SCOPE void TclProcessSetAutopurge(int flag); +MODULE_SCOPE void TclReapPids(int numPids, Tcl_Pid *pidPtr); +MODULE_SCOPE Tcl_Pid TclpGetChildPid(int id); /* *---------------------------------------------------------------- diff --git a/generic/tclIntPlatDecls.h b/generic/tclIntPlatDecls.h index 494d6f1..4770747 100644 --- a/generic/tclIntPlatDecls.h +++ b/generic/tclIntPlatDecls.h @@ -562,6 +562,8 @@ extern const TclIntPlatStubs *tclIntPlatStubsPtr; #else # undef TclpGetPid # define TclpGetPid(pid) ((unsigned long) (pid)) +# undef TclpGetChildPid +# define TclpGetChildPid(id) ((Tcl_Pid) (id)) #endif #endif /* _TCLINTPLATDECLS */ diff --git a/generic/tclPipe.c b/generic/tclPipe.c index d6cd188..c98ee7e 100644 --- a/generic/tclPipe.c +++ b/generic/tclPipe.c @@ -247,6 +247,61 @@ Tcl_ReapDetachedProcs(void) /* *---------------------------------------------------------------------- * + * TclReapPids -- + * + * This function is similar to Tcl_ReapDetachedProcs but works on a + * subset of processes. + * + * Results: + * None. + * + * Side effects: + * Processes are waited on, so that they can be reaped by the system. + * + *---------------------------------------------------------------------- + */ + +void +TclReapPids( + int numPids, /* Number of pids to detach: gives size of + * array pointed to by pidPtr. */ + Tcl_Pid *pidPtr) /* Array of pids to detach. */ +{ + register Detached *detPtr; + Detached *nextPtr, *prevPtr; + int status; + Tcl_Pid pid; + int i; + + Tcl_MutexLock(&pipeMutex); + for (detPtr = detList, prevPtr = NULL; detPtr != NULL; ) { + pid = 0; + for (i = 0; i < numPids; i++) { + if (detPtr->pid == pidPtr[i]) { + pid = Tcl_WaitPid(detPtr->pid, &status, WNOHANG); + break; + } + } + if ((pid == 0) || ((pid == (Tcl_Pid) -1) && (errno != ECHILD))) { + prevPtr = detPtr; + detPtr = detPtr->nextPtr; + continue; + } + nextPtr = detPtr->nextPtr; + if (prevPtr == NULL) { + detList = detPtr->nextPtr; + } else { + prevPtr->nextPtr = detPtr->nextPtr; + } + ckfree(detPtr); + detPtr = nextPtr; + } + Tcl_MutexUnlock(&pipeMutex); +} + +/* + *---------------------------------------------------------------------- + * * TclCleanupChildren -- * * This is a utility function used to wait for child processes to exit, @@ -854,7 +909,9 @@ TclCreatePipeline( * arguments between the "|" characters. */ - Tcl_ReapDetachedProcs(); + if (TclProcessGetAutopurge()) { + Tcl_ReapDetachedProcs(); + } pidPtr = ckalloc(cmdCount * sizeof(Tcl_Pid)); curInFile = inputFile; diff --git a/generic/tclProcess.c b/generic/tclProcess.c index 23ba4de..2557067 100644 --- a/generic/tclProcess.c +++ b/generic/tclProcess.c @@ -123,8 +123,47 @@ ProcessPurgeObjCmd( return TCL_ERROR; } - /* TODO */ - return TCL_ERROR; + if (objc == 1) { + /* + * Purge all detached processes. + */ + + Tcl_ReapDetachedProcs(); + } else { + int result; + int numPids; + Tcl_Obj **pidObjs; + Tcl_Pid *pids; + int id; + int i; + + /* + * Get pids from argument. + */ + + result = Tcl_ListObjGetElements(interp, objv[1], &numPids, &pidObjs); + if (result != TCL_OK) { + return result; + } + pids = (Tcl_Pid *) TclStackAlloc(interp, numPids * sizeof(Tcl_Pid)); + for (i = 0; i < numPids; i++) { + result = Tcl_GetIntFromObj(interp, pidObjs[i], (int *) &id); + if (result != TCL_OK) { + TclStackFree(interp, (void *) pids); + return result; + } + pids[i] = TclpGetChildPid(id); + } + + /* + * Purge only provided processes. + */ + + TclReapPids(numPids, pids); + TclStackFree(interp, (void *) pids); + } + + return TCL_OK; } /*---------------------------------------------------------------------- @@ -138,7 +177,7 @@ ProcessPurgeObjCmd( * Returns a standard Tcl result. * * Side effects: - * None.TODO + * Alters detached process handling by Tcl_ReapDetachedProcs(). * *---------------------------------------------------------------------- */ diff --git a/unix/tclUnixPipe.c b/unix/tclUnixPipe.c index be7b4eb..3d8e680 100644 --- a/unix/tclUnixPipe.c +++ b/unix/tclUnixPipe.c @@ -986,7 +986,9 @@ PipeClose2Proc( */ Tcl_DetachPids(pipePtr->numPids, pipePtr->pidPtr); - Tcl_ReapDetachedProcs(); + if (TclProcessGetAutopurge()) { + Tcl_ReapDetachedProcs(); + } if (pipePtr->errorFile) { TclpCloseFile(pipePtr->errorFile); diff --git a/win/tclWinPipe.c b/win/tclWinPipe.c index 4666deb..6dd2173 100644 --- a/win/tclWinPipe.c +++ b/win/tclWinPipe.c @@ -884,6 +884,44 @@ TclpGetPid( Tcl_MutexUnlock(&pipeMutex); return (unsigned long) -1; } + +/* + *-------------------------------------------------------------------------- + * + * TclpGetChildPid -- + * + * Given a process id of a child process, return the HANDLE for that + * child process. + * + * Results: + * Returns the HANDLE for the child process. If the id was not known + * by Tcl, either because the id was not created by Tcl or the child + * process has already been reaped, NULL is returned. + * + * Side effects: + * None. + * + *-------------------------------------------------------------------------- + */ + +Tcl_Pid +TclpGetChildPid( + int id) /* The process id of the child process. */ +{ + ProcInfo *infoPtr; + + PipeInit(); + + Tcl_MutexLock(&pipeMutex); + for (infoPtr = procList; infoPtr != NULL; infoPtr = infoPtr->nextPtr) { + if (infoPtr->dwProcessId == (DWORD) id) { + Tcl_MutexUnlock(&pipeMutex); + return (Tcl_Pid) infoPtr->hProcess; + } + } + Tcl_MutexUnlock(&pipeMutex); + return (Tcl_Pid) NULL; +} /* *---------------------------------------------------------------------- @@ -1991,7 +2029,9 @@ PipeClose2Proc( */ Tcl_DetachPids(pipePtr->numPids, pipePtr->pidPtr); - Tcl_ReapDetachedProcs(); + if (TclProcessGetAutopurge()) { + Tcl_ReapDetachedProcs(); + } if (pipePtr->errorFile) { if (TclpCloseFile(pipePtr->errorFile) != 0) { -- cgit v0.12 From 8dd2373a08bd2ec8d5796041d0f8945d24a811c1 Mon Sep 17 00:00:00 2001 From: "f.bonnet" Date: Wed, 23 Aug 2017 18:31:56 +0000 Subject: Refactoring and preliminary implementation of tcl::process (list|status) --- generic/tclInt.h | 6 +- generic/tclIntPlatDecls.h | 2 - generic/tclPipe.c | 65 +------ generic/tclProcess.c | 455 ++++++++++++++++++++++++++++++++++++++-------- unix/tclUnixPipe.c | 4 +- win/tclWinPipe.c | 42 +---- 6 files changed, 383 insertions(+), 191 deletions(-) diff --git a/generic/tclInt.h b/generic/tclInt.h index 3e99f91..dcdf2f6 100644 --- a/generic/tclInt.h +++ b/generic/tclInt.h @@ -4026,10 +4026,8 @@ MODULE_SCOPE int TclFullFinalizationRequested(void); */ MODULE_SCOPE Tcl_Command TclInitProcessCmd(Tcl_Interp *interp); -MODULE_SCOPE int TclProcessGetAutopurge(void); -MODULE_SCOPE void TclProcessSetAutopurge(int flag); -MODULE_SCOPE void TclReapPids(int numPids, Tcl_Pid *pidPtr); -MODULE_SCOPE Tcl_Pid TclpGetChildPid(int id); +MODULE_SCOPE void TclProcessDetach(Tcl_Pid pid); +MODULE_SCOPE int TclProcessStatus(Tcl_Pid pid, int options); /* *---------------------------------------------------------------- diff --git a/generic/tclIntPlatDecls.h b/generic/tclIntPlatDecls.h index 4770747..494d6f1 100644 --- a/generic/tclIntPlatDecls.h +++ b/generic/tclIntPlatDecls.h @@ -562,8 +562,6 @@ extern const TclIntPlatStubs *tclIntPlatStubsPtr; #else # undef TclpGetPid # define TclpGetPid(pid) ((unsigned long) (pid)) -# undef TclpGetChildPid -# define TclpGetChildPid(id) ((Tcl_Pid) (id)) #endif #endif /* _TCLINTPLATDECLS */ diff --git a/generic/tclPipe.c b/generic/tclPipe.c index c98ee7e..e7c419d 100644 --- a/generic/tclPipe.c +++ b/generic/tclPipe.c @@ -192,6 +192,7 @@ Tcl_DetachPids( detPtr->pid = pidPtr[i]; detPtr->nextPtr = detList; detList = detPtr; + TclProcessDetach(pidPtr[i]); } Tcl_MutexUnlock(&pipeMutex); @@ -221,13 +222,10 @@ Tcl_ReapDetachedProcs(void) { register Detached *detPtr; Detached *nextPtr, *prevPtr; - int status; - Tcl_Pid pid; Tcl_MutexLock(&pipeMutex); for (detPtr = detList, prevPtr = NULL; detPtr != NULL; ) { - pid = Tcl_WaitPid(detPtr->pid, &status, WNOHANG); - if ((pid == 0) || ((pid == (Tcl_Pid) -1) && (errno != ECHILD))) { + if (!TclProcessStatus(detPtr->pid, WNOHANG)) { prevPtr = detPtr; detPtr = detPtr->nextPtr; continue; @@ -247,61 +245,6 @@ Tcl_ReapDetachedProcs(void) /* *---------------------------------------------------------------------- * - * TclReapPids -- - * - * This function is similar to Tcl_ReapDetachedProcs but works on a - * subset of processes. - * - * Results: - * None. - * - * Side effects: - * Processes are waited on, so that they can be reaped by the system. - * - *---------------------------------------------------------------------- - */ - -void -TclReapPids( - int numPids, /* Number of pids to detach: gives size of - * array pointed to by pidPtr. */ - Tcl_Pid *pidPtr) /* Array of pids to detach. */ -{ - register Detached *detPtr; - Detached *nextPtr, *prevPtr; - int status; - Tcl_Pid pid; - int i; - - Tcl_MutexLock(&pipeMutex); - for (detPtr = detList, prevPtr = NULL; detPtr != NULL; ) { - pid = 0; - for (i = 0; i < numPids; i++) { - if (detPtr->pid == pidPtr[i]) { - pid = Tcl_WaitPid(detPtr->pid, &status, WNOHANG); - break; - } - } - if ((pid == 0) || ((pid == (Tcl_Pid) -1) && (errno != ECHILD))) { - prevPtr = detPtr; - detPtr = detPtr->nextPtr; - continue; - } - nextPtr = detPtr->nextPtr; - if (prevPtr == NULL) { - detList = detPtr->nextPtr; - } else { - prevPtr->nextPtr = detPtr->nextPtr; - } - ckfree(detPtr); - detPtr = nextPtr; - } - Tcl_MutexUnlock(&pipeMutex); -} - -/* - *---------------------------------------------------------------------- - * * TclCleanupChildren -- * * This is a utility function used to wait for child processes to exit, @@ -909,9 +852,7 @@ TclCreatePipeline( * arguments between the "|" characters. */ - if (TclProcessGetAutopurge()) { - Tcl_ReapDetachedProcs(); - } + Tcl_ReapDetachedProcs(); pidPtr = ckalloc(cmdCount * sizeof(Tcl_Pid)); curInFile = inputFile; diff --git a/generic/tclProcess.c b/generic/tclProcess.c index 2557067..733b1d7 100644 --- a/generic/tclProcess.c +++ b/generic/tclProcess.c @@ -12,22 +12,45 @@ #include "tclInt.h" +/* + * Autopurge flag. Process-global because of the way Tcl manages child + * processes (see tclPipe.c). + */ + static int autopurge = 1; /* Autopurge flag. */ +/* + * Hash table that keeps track of all child process statuses. Keys are the + * child process ids, values are (ProcessInfo *). + */ + +typedef struct ProcessInfo { + Tcl_Pid pid; /*FRED TODO*/ + int resolvedPid; /*FRED TODO unused?*/ + Tcl_Obj *status; /*FRED TODO*/ + +} ProcessInfo; +static Tcl_HashTable statusTable; +static int statusTableInitialized = 0; /* 0 means not yet initialized. */ +TCL_DECLARE_MUTEX(statusMutex) + /* * Prototypes for functions defined later in this file: */ -static int ProcessListObjCmd(ClientData clientData, +static int GetProcessStatus(Tcl_Pid pid, int resolvedPid, + int options, Tcl_Obj **statusPtr); +static int PurgeProcessStatus(Tcl_HashEntry *entry); +static int ProcessListObjCmd(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *const objv[]); -static int ProcessStatusObjCmd(ClientData clientData, +static int ProcessStatusObjCmd(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *const objv[]); -static int ProcessPurgeObjCmd(ClientData clientData, +static int ProcessPurgeObjCmd(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *const objv[]); -static int ProcessAutopurgeObjCmd(ClientData clientData, +static int ProcessAutopurgeObjCmd(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *const objv[]); @@ -42,7 +65,7 @@ static int ProcessAutopurgeObjCmd(ClientData clientData, * Returns a standard Tcl result. * * Side effects: - * None.TODO + * None.FRED TODO * *---------------------------------------------------------------------- */ @@ -50,18 +73,36 @@ static int ProcessAutopurgeObjCmd(ClientData clientData, static int ProcessListObjCmd( ClientData clientData, /* Not used. */ - Tcl_Interp *interp, /* Current interpreter. */ + Tcl_Interp *interp, /* Current interpreter. */ int objc, /* Number of arguments. */ Tcl_Obj *const objv[]) /* Argument objects. */ { + Tcl_Obj *result; + Tcl_HashEntry *entry; + Tcl_HashSearch search; + ProcessInfo *info; + if (objc != 1) { Tcl_WrongNumArgs(interp, 1, objv, NULL); return TCL_ERROR; } - /* TODO */ - return TCL_ERROR; - } + /* + * Return the list of all chid process ids. + */ + + result = Tcl_NewListObj(0, NULL); + Tcl_MutexLock(&statusMutex); + for (entry = Tcl_FirstHashEntry(&statusTable, &search); entry != NULL; + entry = Tcl_NextHashEntry(&search)) { + info = (ProcessInfo *) Tcl_GetHashValue(entry); + Tcl_ListObjAppendElement(interp, result, + Tcl_NewIntObj(info->resolvedPid)); + } + Tcl_MutexUnlock(&statusMutex); + Tcl_SetObjResult(interp, result); + return TCL_OK; +} /*---------------------------------------------------------------------- * @@ -74,7 +115,7 @@ ProcessListObjCmd( * Returns a standard Tcl result. * * Side effects: - * None.TODO + * None.FRED TODO * *---------------------------------------------------------------------- */ @@ -82,18 +123,61 @@ ProcessListObjCmd( static int ProcessStatusObjCmd( ClientData clientData, /* Not used. */ - Tcl_Interp *interp, /* Current interpreter. */ + Tcl_Interp *interp, /* Current interpreter. */ int objc, /* Number of arguments. */ Tcl_Obj *const objv[]) /* Argument objects. */ { + Tcl_Obj *result; + int options; + Tcl_HashEntry *entry; + Tcl_HashSearch search; + ProcessInfo *info; + if (objc < 1) { Tcl_WrongNumArgs(interp, 1, objv, "?switches? ?pids?"); return TCL_ERROR; } - /* TODO */ - return TCL_ERROR; - } + /* FRED TODO switches */ + options = WNOHANG; + + /* + * Return the list of all chid process statuses. + */ + + result = Tcl_NewDictObj(); + Tcl_MutexLock(&statusMutex); + for (entry = Tcl_FirstHashEntry(&statusTable, &search); entry != NULL; + entry = Tcl_NextHashEntry(&search)) { + info = (ProcessInfo *) Tcl_GetHashValue(entry); + if (autopurge) { + if (GetProcessStatus(info->pid, info->resolvedPid, options, + NULL)) { + /* + * Purge. + */ + + PurgeProcessStatus(entry); + Tcl_DeleteHashEntry(entry); + continue; + } + } else if (!info->status) { + /* + * Update status. + */ + + if (GetProcessStatus(info->pid, info->resolvedPid, options, + &info->status)) { + Tcl_IncrRefCount(info->status); + } + } + Tcl_DictObjPut(interp, result, Tcl_NewIntObj(info->resolvedPid), + info->status ? info->status : Tcl_NewObj()); + } + Tcl_MutexUnlock(&statusMutex); + Tcl_SetObjResult(interp, result); + return TCL_OK; +} /*---------------------------------------------------------------------- * @@ -106,7 +190,7 @@ ProcessStatusObjCmd( * Returns a standard Tcl result. * * Side effects: - * None.TODO + * None.FRED TODO * *---------------------------------------------------------------------- */ @@ -114,57 +198,65 @@ ProcessStatusObjCmd( static int ProcessPurgeObjCmd( ClientData clientData, /* Not used. */ - Tcl_Interp *interp, /* Current interpreter. */ + Tcl_Interp *interp, /* Current interpreter. */ int objc, /* Number of arguments. */ Tcl_Obj *const objv[]) /* Argument objects. */ { + Tcl_HashEntry *entry; + Tcl_HashSearch search; + int numPids; + Tcl_Obj **pidObjs; + int result; + int i; + int pid; + if (objc != 1 && objc != 2) { Tcl_WrongNumArgs(interp, 1, objv, "?pids?"); return TCL_ERROR; } +//FRED TODO update status list first. + if (objc == 1) { /* - * Purge all detached processes. + * Purge all terminated processes. */ - - Tcl_ReapDetachedProcs(); - } else { - int result; - int numPids; - Tcl_Obj **pidObjs; - Tcl_Pid *pids; - int id; - int i; + Tcl_MutexLock(&statusMutex); + for (entry = Tcl_FirstHashEntry(&statusTable, &search); entry != NULL; + entry = Tcl_NextHashEntry(&search)) { + if (PurgeProcessStatus(entry)) { + Tcl_DeleteHashEntry(entry); + } + } + Tcl_MutexUnlock(&statusMutex); + } else { /* - * Get pids from argument. + * Purge only provided processes. */ result = Tcl_ListObjGetElements(interp, objv[1], &numPids, &pidObjs); if (result != TCL_OK) { return result; } - pids = (Tcl_Pid *) TclStackAlloc(interp, numPids * sizeof(Tcl_Pid)); + Tcl_MutexLock(&statusMutex); for (i = 0; i < numPids; i++) { - result = Tcl_GetIntFromObj(interp, pidObjs[i], (int *) &id); + result = Tcl_GetIntFromObj(interp, pidObjs[i], (int *) &pid); if (result != TCL_OK) { - TclStackFree(interp, (void *) pids); + Tcl_MutexUnlock(&statusMutex); return result; } - pids[i] = TclpGetChildPid(id); - } - /* - * Purge only provided processes. - */ - - TclReapPids(numPids, pids); - TclStackFree(interp, (void *) pids); + entry = Tcl_FindHashEntry(&statusTable, INT2PTR(pid)); + if (entry && PurgeProcessStatus(entry)) { + Tcl_DeleteHashEntry(entry); + } + } + Tcl_MutexUnlock(&statusMutex); } return TCL_OK; - } +} /*---------------------------------------------------------------------- * @@ -185,10 +277,10 @@ ProcessPurgeObjCmd( static int ProcessAutopurgeObjCmd( ClientData clientData, /* Not used. */ - Tcl_Interp *interp, /* Current interpreter. */ + Tcl_Interp *interp, /* Current interpreter. */ int objc, /* Number of arguments. */ Tcl_Obj *const objv[]) /* Argument objects. */ - { +{ if (objc != 1 && objc != 2) { Tcl_WrongNumArgs(interp, 1, objv, "?flag?"); return TCL_ERROR; @@ -205,14 +297,14 @@ ProcessAutopurgeObjCmd( return result; } - TclProcessSetAutopurge(flag); + autopurge = !!flag; } /* * Return current value. */ - Tcl_SetObjResult(interp, Tcl_NewBooleanObj(TclProcessGetAutopurge())); + Tcl_SetObjResult(interp, Tcl_NewBooleanObj(autopurge)); return TCL_OK; } @@ -246,53 +338,258 @@ TclInitProcessCmd( }; Tcl_Command processCmd; + if (statusTableInitialized == 0) { + Tcl_MutexLock(&statusMutex); + if (statusTableInitialized == 0) { + Tcl_InitHashTable(&statusTable, TCL_ONE_WORD_KEYS); + statusTableInitialized = 1; + } + Tcl_MutexUnlock(&statusMutex); + } + processCmd = TclMakeEnsemble(interp, "::tcl::process", processImplMap); Tcl_Export(interp, Tcl_FindNamespace(interp, "::tcl", NULL, 0), "process", 0); return processCmd; } -/* - *---------------------------------------------------------------------- - * - * TclProcessGetAutopurge -- - * - * This function queries the value of the autopurge flag. - * - * Results: - * The current boolean value of the autopurge flag. - * - * Side effects: - * None. - * - *---------------------------------------------------------------------- - */ +/* FRED TODO */ +void +TclProcessDetach( + Tcl_Pid pid) +{ + int resolvedPid; + Tcl_HashEntry *entry; + int isNew; + ProcessInfo *info; + + resolvedPid = TclpGetPid(pid); + Tcl_MutexLock(&statusMutex); + entry = Tcl_CreateHashEntry(&statusTable, INT2PTR(resolvedPid), &isNew); + if (!isNew) { + /* + * Pid was reused, free old status and reuse structure. + */ + + info = (ProcessInfo *) Tcl_GetHashValue(entry); + if (info->status) { + Tcl_DecrRefCount(info->status); + } + } else { + /* + * Allocate new info structure. + */ + info = (ProcessInfo *) ckalloc(sizeof(ProcessInfo)); + Tcl_SetHashValue(entry, info); + } + + /* + * Initialize with an empty status. + */ + + info->pid = pid; + info->resolvedPid = resolvedPid; + info->status = NULL; + + Tcl_MutexUnlock(&statusMutex); +} + +/* FRED TODO */ int -TclProcessGetAutopurge(void) +TclProcessStatus( + Tcl_Pid pid, + int options) { - return autopurge; + int resolvedPid; + Tcl_HashEntry *entry; + ProcessInfo *info; + Tcl_Obj *status; + int isNew; + + /* + * We need to get the resolved pid before we wait on it as the windows + * implementation of Tcl_WaitPid deletes the information such that any + * following calls to TclpGetPid fail. + */ + + resolvedPid = TclpGetPid(pid); + + if (!GetProcessStatus(pid, resolvedPid, options, + (autopurge ? NULL /* unused */: &status))) { + /* + * Process still alive, or non child-related error. + */ + + return 0; + } + + if (autopurge) { + /* + * Child terminated, purge. + */ + + Tcl_MutexLock(&statusMutex); + entry = Tcl_FindHashEntry(&statusTable, INT2PTR(resolvedPid)); + if (entry) { + PurgeProcessStatus(entry); + Tcl_DeleteHashEntry(entry); + } + Tcl_MutexUnlock(&statusMutex); + + return 1; + } + + /* + * Store process status. + */ + + Tcl_MutexLock(&statusMutex); + entry = Tcl_CreateHashEntry(&statusTable, INT2PTR(resolvedPid), &isNew); + if (!isNew) { + info = (ProcessInfo *) Tcl_GetHashValue(entry); + if (info->status) { + /* + * Free old status object. + */ + + Tcl_DecrRefCount(info->status); + } + } else { + /* + * Allocate new info structure. + */ + + info = (ProcessInfo *) ckalloc(sizeof(ProcessInfo)); + info->pid = pid; + info->resolvedPid = resolvedPid; + Tcl_SetHashValue(entry, info); + } + + info->status = status; + Tcl_IncrRefCount(status); + Tcl_MutexUnlock(&statusMutex); + + return 1; } -/* - *---------------------------------------------------------------------- - * - * TclProcessSetAutopurge -- - * - * This function sets the value of the autopurge flag. - * - * Results: - * None. - * - * Side effects: - * Sets the autopurge static variable. - * - *---------------------------------------------------------------------- - */ +/* FRED TODO */ +int +GetProcessStatus( + Tcl_Pid pid, + int resolvedPid, + int options, + Tcl_Obj **statusPtr) +{ + int waitStatus; + Tcl_Obj *statusCodes[5]; + const char *msg; -void -TclProcessSetAutopurge( - int flag) /* New value for autopurge. */ + pid = Tcl_WaitPid(pid, &waitStatus, options); + if ((pid == 0) || ((pid == (Tcl_Pid) -1) && (errno != ECHILD))) { + /* + * Process still alive, or non child-related error. + */ + + return 0; + } + + if (!statusPtr) { + return 1; + } + + /* + * Get process status. + */ + + if (pid == (Tcl_Pid) -1) { + /* + * POSIX errName msg + */ + + statusCodes[0] = Tcl_NewStringObj("POSIX", -1); + statusCodes[1] = Tcl_NewStringObj(Tcl_ErrnoId(), -1); + msg = Tcl_ErrnoMsg(errno); + if (errno == ECHILD) { + /* + * This changeup in message suggested by Mark Diekhans to + * remind people that ECHILD errors can occur on some + * systems if SIGCHLD isn't in its default state. + */ + + msg = "child process lost (is SIGCHLD ignored or trapped?)"; + } + statusCodes[2] = Tcl_NewStringObj(msg, -1); + *statusPtr = Tcl_NewListObj(3, statusCodes); + } else if (WIFEXITED(waitStatus)) { + /* + * CHILDSTATUS pid code + * + * Child exited with a non-zero exit status. + */ + + statusCodes[0] = Tcl_NewStringObj("CHILDSTATUS", -1); + statusCodes[1] = Tcl_NewIntObj(resolvedPid); + statusCodes[2] = Tcl_NewIntObj(WEXITSTATUS(waitStatus)); + *statusPtr = Tcl_NewListObj(3, statusCodes); + } else if (WIFSIGNALED(waitStatus)) { + /* + * CHILDKILLED pid sigName msg + * + * Child killed because of a signal + */ + + statusCodes[0] = Tcl_NewStringObj("CHILDKILLED", -1); + statusCodes[1] = Tcl_NewIntObj(resolvedPid); + statusCodes[2] = Tcl_NewStringObj(Tcl_SignalId(WTERMSIG(waitStatus)), -1); + statusCodes[3] = Tcl_NewStringObj(Tcl_SignalMsg(WTERMSIG(waitStatus)), -1); + *statusPtr = Tcl_NewListObj(4, statusCodes); + } else if (WIFSTOPPED(waitStatus)) { + /* + * CHILDSUSP pid sigName msg + * + * Child suspended because of a signal + */ + + statusCodes[0] = Tcl_NewStringObj("CHILDSUSP", -1); + statusCodes[1] = Tcl_NewIntObj(resolvedPid); + statusCodes[2] = Tcl_NewStringObj(Tcl_SignalId(WSTOPSIG(waitStatus)), -1); + statusCodes[3] = Tcl_NewStringObj(Tcl_SignalMsg(WSTOPSIG(waitStatus)), -1); + *statusPtr = Tcl_NewListObj(4, statusCodes); + } else { + /* + * TCL OPERATION EXEC ODDWAITRESULT + * + * Child wait status didn't make sense. + */ + + statusCodes[0] = Tcl_NewStringObj("TCL", -1); + statusCodes[1] = Tcl_NewStringObj("OPERATION", -1); + statusCodes[2] = Tcl_NewStringObj("EXEC", -1); + statusCodes[3] = Tcl_NewStringObj("ODDWAITRESULT", -1); + statusCodes[4] = Tcl_NewIntObj(resolvedPid); + *statusPtr = Tcl_NewListObj(5, statusCodes); + } + + return 1; +} + +/* FRED TODO */ +int +PurgeProcessStatus( + Tcl_HashEntry *entry) { - autopurge = !!flag; + ProcessInfo *info; + + info = (ProcessInfo *) Tcl_GetHashValue(entry); + if (info->status) { + /* + * Process has ended, purge. + */ + + Tcl_DecrRefCount(info->status); + return 1; + } + + return 0; } diff --git a/unix/tclUnixPipe.c b/unix/tclUnixPipe.c index 3d8e680..be7b4eb 100644 --- a/unix/tclUnixPipe.c +++ b/unix/tclUnixPipe.c @@ -986,9 +986,7 @@ PipeClose2Proc( */ Tcl_DetachPids(pipePtr->numPids, pipePtr->pidPtr); - if (TclProcessGetAutopurge()) { - Tcl_ReapDetachedProcs(); - } + Tcl_ReapDetachedProcs(); if (pipePtr->errorFile) { TclpCloseFile(pipePtr->errorFile); diff --git a/win/tclWinPipe.c b/win/tclWinPipe.c index 6dd2173..4666deb 100644 --- a/win/tclWinPipe.c +++ b/win/tclWinPipe.c @@ -884,44 +884,6 @@ TclpGetPid( Tcl_MutexUnlock(&pipeMutex); return (unsigned long) -1; } - -/* - *-------------------------------------------------------------------------- - * - * TclpGetChildPid -- - * - * Given a process id of a child process, return the HANDLE for that - * child process. - * - * Results: - * Returns the HANDLE for the child process. If the id was not known - * by Tcl, either because the id was not created by Tcl or the child - * process has already been reaped, NULL is returned. - * - * Side effects: - * None. - * - *-------------------------------------------------------------------------- - */ - -Tcl_Pid -TclpGetChildPid( - int id) /* The process id of the child process. */ -{ - ProcInfo *infoPtr; - - PipeInit(); - - Tcl_MutexLock(&pipeMutex); - for (infoPtr = procList; infoPtr != NULL; infoPtr = infoPtr->nextPtr) { - if (infoPtr->dwProcessId == (DWORD) id) { - Tcl_MutexUnlock(&pipeMutex); - return (Tcl_Pid) infoPtr->hProcess; - } - } - Tcl_MutexUnlock(&pipeMutex); - return (Tcl_Pid) NULL; -} /* *---------------------------------------------------------------------- @@ -2029,9 +1991,7 @@ PipeClose2Proc( */ Tcl_DetachPids(pipePtr->numPids, pipePtr->pidPtr); - if (TclProcessGetAutopurge()) { - Tcl_ReapDetachedProcs(); - } + Tcl_ReapDetachedProcs(); if (pipePtr->errorFile) { if (TclpCloseFile(pipePtr->errorFile) != 0) { -- cgit v0.12 From 57aa77515aae5d66471140213b35e4ff50972b0e Mon Sep 17 00:00:00 2001 From: "f.bonnet" Date: Wed, 23 Aug 2017 19:51:02 +0000 Subject: Added switches and pid list support to tcl::process status --- generic/tclProcess.c | 159 ++++++++++++++++++++++++++++++++++++++------------- 1 file changed, 119 insertions(+), 40 deletions(-) diff --git a/generic/tclProcess.c b/generic/tclProcess.c index 733b1d7..99bb7e1 100644 --- a/generic/tclProcess.c +++ b/generic/tclProcess.c @@ -77,7 +77,7 @@ ProcessListObjCmd( int objc, /* Number of arguments. */ Tcl_Obj *const objv[]) /* Argument objects. */ { - Tcl_Obj *result; + Tcl_Obj *list; Tcl_HashEntry *entry; Tcl_HashSearch search; ProcessInfo *info; @@ -91,16 +91,16 @@ ProcessListObjCmd( * Return the list of all chid process ids. */ - result = Tcl_NewListObj(0, NULL); + list = Tcl_NewListObj(0, NULL); Tcl_MutexLock(&statusMutex); for (entry = Tcl_FirstHashEntry(&statusTable, &search); entry != NULL; entry = Tcl_NextHashEntry(&search)) { info = (ProcessInfo *) Tcl_GetHashValue(entry); - Tcl_ListObjAppendElement(interp, result, + Tcl_ListObjAppendElement(interp, list, Tcl_NewIntObj(info->resolvedPid)); } Tcl_MutexUnlock(&statusMutex); - Tcl_SetObjResult(interp, result); + Tcl_SetObjResult(interp, list); return TCL_OK; } @@ -127,55 +127,136 @@ ProcessStatusObjCmd( int objc, /* Number of arguments. */ Tcl_Obj *const objv[]) /* Argument objects. */ { - Tcl_Obj *result; - int options; + Tcl_Obj *dict; + int index, options = WNOHANG; Tcl_HashEntry *entry; Tcl_HashSearch search; ProcessInfo *info; + int numPids; + Tcl_Obj **pidObjs; + int result; + int i; + int pid; + Tcl_Obj *const *savedobjv = objv; + static const char *const switches[] = { + "-wait", "--", NULL + }; + enum switches { + STATUS_WAIT, STATUS_LAST + }; - if (objc < 1) { - Tcl_WrongNumArgs(interp, 1, objv, "?switches? ?pids?"); + while (objc > 1) { + if (TclGetString(objv[1])[0] != '-') { + break; + } + if (Tcl_GetIndexFromObj(interp, objv[1], switches, "switches", 0, + &index) != TCL_OK) { + return TCL_ERROR; + } + ++objv; --objc; + if (STATUS_WAIT == (enum switches) index) { + options = 0; + } else { + break; + } + } + + if (objc != 1 && objc != 2) { + Tcl_WrongNumArgs(interp, 1, savedobjv, "?switches? ?pids?"); return TCL_ERROR; } - /* FRED TODO switches */ - options = WNOHANG; + if (objc == 1) { + /* + * Return the list of all child process statuses. + */ - /* - * Return the list of all chid process statuses. - */ + dict = Tcl_NewDictObj(); + Tcl_MutexLock(&statusMutex); + for (entry = Tcl_FirstHashEntry(&statusTable, &search); entry != NULL; + entry = Tcl_NextHashEntry(&search)) { + info = (ProcessInfo *) Tcl_GetHashValue(entry); + if (autopurge) { + if (GetProcessStatus(info->pid, info->resolvedPid, options, + NULL)) { + /* + * Purge. + */ + + PurgeProcessStatus(entry); + Tcl_DeleteHashEntry(entry); + continue; + } + } else if (!info->status) { + /* + * Update status. + */ + + if (GetProcessStatus(info->pid, info->resolvedPid, options, + &info->status)) { + Tcl_IncrRefCount(info->status); + } + } + Tcl_DictObjPut(interp, dict, Tcl_NewIntObj(info->resolvedPid), + info->status ? info->status : Tcl_NewObj()); + } + Tcl_MutexUnlock(&statusMutex); + } else { + /* + * Only return statuses of provided processes. + */ + + result = Tcl_ListObjGetElements(interp, objv[1], &numPids, &pidObjs); + if (result != TCL_OK) { + return result; + } + dict = Tcl_NewDictObj(); + Tcl_MutexLock(&statusMutex); + for (i = 0; i < numPids; i++) { + result = Tcl_GetIntFromObj(interp, pidObjs[i], (int *) &pid); + if (result != TCL_OK) { + Tcl_MutexUnlock(&statusMutex); + Tcl_DecrRefCount(dict); + return result; + } - result = Tcl_NewDictObj(); - Tcl_MutexLock(&statusMutex); - for (entry = Tcl_FirstHashEntry(&statusTable, &search); entry != NULL; - entry = Tcl_NextHashEntry(&search)) { - info = (ProcessInfo *) Tcl_GetHashValue(entry); - if (autopurge) { - if (GetProcessStatus(info->pid, info->resolvedPid, options, - NULL)) { + entry = Tcl_FindHashEntry(&statusTable, INT2PTR(pid)); + if (!entry) { /* - * Purge. + * Skip unknown process. */ - - PurgeProcessStatus(entry); - Tcl_DeleteHashEntry(entry); + continue; } - } else if (!info->status) { - /* - * Update status. - */ - - if (GetProcessStatus(info->pid, info->resolvedPid, options, - &info->status)) { - Tcl_IncrRefCount(info->status); - } + + info = (ProcessInfo *) Tcl_GetHashValue(entry); + if (autopurge) { + if (GetProcessStatus(info->pid, info->resolvedPid, options, + NULL)) { + /* + * Purge. + */ + + PurgeProcessStatus(entry); + Tcl_DeleteHashEntry(entry); + continue; + } + } else if (!info->status) { + /* + * Update status. + */ + + if (GetProcessStatus(info->pid, info->resolvedPid, options, + &info->status)) { + Tcl_IncrRefCount(info->status); + } + } + Tcl_DictObjPut(interp, dict, Tcl_NewIntObj(info->resolvedPid), + info->status ? info->status : Tcl_NewObj()); } - Tcl_DictObjPut(interp, result, Tcl_NewIntObj(info->resolvedPid), - info->status ? info->status : Tcl_NewObj()); + Tcl_MutexUnlock(&statusMutex); } - Tcl_MutexUnlock(&statusMutex); - Tcl_SetObjResult(interp, result); + Tcl_SetObjResult(interp, dict); return TCL_OK; } @@ -215,8 +296,6 @@ ProcessPurgeObjCmd( return TCL_ERROR; } -//FRED TODO update status list first. - if (objc == 1) { /* * Purge all terminated processes. -- cgit v0.12 From 43c89a019c37b43637956e0b21b5788f784b1972 Mon Sep 17 00:00:00 2001 From: "f.bonnet" Date: Sun, 27 Aug 2017 11:05:45 +0000 Subject: Refactoring to support all processes and not just detached ones. --- generic/tclInt.h | 15 +- generic/tclPipe.c | 75 ++----- generic/tclProcess.c | 625 +++++++++++++++++++++++++++++---------------------- 3 files changed, 391 insertions(+), 324 deletions(-) diff --git a/generic/tclInt.h b/generic/tclInt.h index dcdf2f6..c7a0a0d 100644 --- a/generic/tclInt.h +++ b/generic/tclInt.h @@ -4025,9 +4025,20 @@ MODULE_SCOPE int TclFullFinalizationRequested(void); * TIP #462. */ +typedef enum TclProcessWaitStatus { + TCL_PROCESS_ERROR = -1, + TCL_PROCESS_UNCHANGED = 0, + TCL_PROCESS_EXITED = 1, + TCL_PROCESS_SIGNALED = 2, + TCL_PROCESS_STOPPED = 3, + TCL_PROCESS_UNKNOWN_STATUS = 4 +} TclProcessWaitStatus; + MODULE_SCOPE Tcl_Command TclInitProcessCmd(Tcl_Interp *interp); -MODULE_SCOPE void TclProcessDetach(Tcl_Pid pid); -MODULE_SCOPE int TclProcessStatus(Tcl_Pid pid, int options); +MODULE_SCOPE void TclProcessCreated(Tcl_Pid pid); +MODULE_SCOPE TclProcessWaitStatus TclProcessWait(Tcl_Pid pid, int options, + int *codePtr, Tcl_Obj **msgObjPtr, + Tcl_Obj **errorObjPtr); /* *---------------------------------------------------------------- diff --git a/generic/tclPipe.c b/generic/tclPipe.c index e7c419d..d20d8eb 100644 --- a/generic/tclPipe.c +++ b/generic/tclPipe.c @@ -192,7 +192,6 @@ Tcl_DetachPids( detPtr->pid = pidPtr[i]; detPtr->nextPtr = detList; detList = detPtr; - TclProcessDetach(pidPtr[i]); } Tcl_MutexUnlock(&pipeMutex); @@ -222,10 +221,13 @@ Tcl_ReapDetachedProcs(void) { register Detached *detPtr; Detached *nextPtr, *prevPtr; + int status, code; Tcl_MutexLock(&pipeMutex); for (detPtr = detList, prevPtr = NULL; detPtr != NULL; ) { - if (!TclProcessStatus(detPtr->pid, WNOHANG)) { + status = TclProcessWait(detPtr->pid, WNOHANG, &code, NULL, NULL); + if (status == TCL_PROCESS_UNCHANGED || (status == TCL_PROCESS_ERROR + && code != ECHILD)) { prevPtr = detPtr; detPtr = detPtr->nextPtr; continue; @@ -275,37 +277,18 @@ TclCleanupChildren( { int result = TCL_OK; int i, abnormalExit, anyErrorInfo; - Tcl_Pid pid; - int waitStatus; - const char *msg; - unsigned long resolvedPid; + TclProcessWaitStatus waitStatus; + int code; + Tcl_Obj *msg, *error; abnormalExit = 0; for (i = 0; i < numPids; i++) { - /* - * We need to get the resolved pid before we wait on it as the windows - * implementation of Tcl_WaitPid deletes the information such that any - * following calls to TclpGetPid fail. - */ - - resolvedPid = TclpGetPid(pidPtr[i]); - pid = Tcl_WaitPid(pidPtr[i], &waitStatus, 0); - if (pid == (Tcl_Pid) -1) { + waitStatus = TclProcessWait(pidPtr[i], 0, &code, &msg, &error); + if (waitStatus == TCL_PROCESS_ERROR) { result = TCL_ERROR; if (interp != NULL) { - msg = Tcl_PosixError(interp); - if (errno == ECHILD) { - /* - * This changeup in message suggested by Mark Diekhans to - * remind people that ECHILD errors can occur on some - * systems if SIGCHLD isn't in its default state. - */ - - msg = - "child process lost (is SIGCHLD ignored or trapped?)"; - } - Tcl_SetObjResult(interp, Tcl_ObjPrintf( - "error waiting for process to exit: %s", msg)); + Tcl_SetObjErrorCode(interp, error); + Tcl_SetObjResult(interp, msg); } continue; } @@ -317,38 +300,17 @@ TclCleanupChildren( * removed). */ - if (!WIFEXITED(waitStatus) || (WEXITSTATUS(waitStatus) != 0)) { - char msg1[TCL_INTEGER_SPACE], msg2[TCL_INTEGER_SPACE]; - + if (waitStatus != TCL_PROCESS_EXITED || code != 0) { result = TCL_ERROR; - sprintf(msg1, "%lu", resolvedPid); - if (WIFEXITED(waitStatus)) { + if (waitStatus == TCL_PROCESS_EXITED) { if (interp != NULL) { - sprintf(msg2, "%u", WEXITSTATUS(waitStatus)); - Tcl_SetErrorCode(interp, "CHILDSTATUS", msg1, msg2, NULL); + Tcl_SetObjErrorCode(interp, error); + Tcl_DecrRefCount(msg); } abnormalExit = 1; } else if (interp != NULL) { - const char *p; - - if (WIFSIGNALED(waitStatus)) { - p = Tcl_SignalMsg(WTERMSIG(waitStatus)); - Tcl_SetErrorCode(interp, "CHILDKILLED", msg1, - Tcl_SignalId(WTERMSIG(waitStatus)), p, NULL); - Tcl_SetObjResult(interp, Tcl_ObjPrintf( - "child killed: %s\n", p)); - } else if (WIFSTOPPED(waitStatus)) { - p = Tcl_SignalMsg(WSTOPSIG(waitStatus)); - Tcl_SetErrorCode(interp, "CHILDSUSP", msg1, - Tcl_SignalId(WSTOPSIG(waitStatus)), p, NULL); - Tcl_SetObjResult(interp, Tcl_ObjPrintf( - "child suspended: %s\n", p)); - } else { - Tcl_SetObjResult(interp, Tcl_NewStringObj( - "child wait status didn't make sense\n", -1)); - Tcl_SetErrorCode(interp, "TCL", "OPERATION", "EXEC", - "ODDWAITRESULT", msg1, NULL); - } + Tcl_SetObjErrorCode(interp, error); + Tcl_SetObjResult(interp, msg); } } } @@ -380,7 +342,7 @@ TclCleanupChildren( Tcl_PosixError(interp))); } else if (count > 0) { anyErrorInfo = 1; - Tcl_SetObjResult(interp, objPtr); + Tcl_SetObjResult(interp, objPtr); result = TCL_ERROR; } else { Tcl_DecrRefCount(objPtr); @@ -928,6 +890,7 @@ TclCreatePipeline( pidPtr[numPids] = pid; numPids++; + TclProcessCreated(pid); /* * Close off our copies of file descriptors that were set up for this diff --git a/generic/tclProcess.c b/generic/tclProcess.c index 99bb7e1..87fc8bb 100644 --- a/generic/tclProcess.c +++ b/generic/tclProcess.c @@ -20,27 +20,36 @@ static int autopurge = 1; /* Autopurge flag. */ /* - * Hash table that keeps track of all child process statuses. Keys are the - * child process ids, values are (ProcessInfo *). + * Hash tables that keeps track of all child process statuses. Keys are the + * child process ids and resolved pids, values are (ProcessInfo *). */ typedef struct ProcessInfo { Tcl_Pid pid; /*FRED TODO*/ - int resolvedPid; /*FRED TODO unused?*/ - Tcl_Obj *status; /*FRED TODO*/ - + int resolvedPid; /*FRED TODO*/ + int purge; /*FRED TODO*/ + TclProcessWaitStatus status; + int code; /*FRED TODO*/ + Tcl_Obj *msg; /*FRED TODO*/ + Tcl_Obj *error; /*FRED TODO*/ } ProcessInfo; -static Tcl_HashTable statusTable; -static int statusTableInitialized = 0; /* 0 means not yet initialized. */ -TCL_DECLARE_MUTEX(statusMutex) +static Tcl_HashTable infoTablePerPid; +static Tcl_HashTable infoTablePerResolvedPid; +static int infoTablesInitialized = 0; /* 0 means not yet initialized. */ +TCL_DECLARE_MUTEX(infoTablesMutex) /* * Prototypes for functions defined later in this file: */ -static int GetProcessStatus(Tcl_Pid pid, int resolvedPid, - int options, Tcl_Obj **statusPtr); -static int PurgeProcessStatus(Tcl_HashEntry *entry); +static void InitProcessInfo(ProcessInfo *info, Tcl_Pid pid, + int resolvedPid); +static void FreeProcessInfo(ProcessInfo *info, int preserveObjs); +static int RefreshProcessInfo(ProcessInfo *info, int options); +static int WaitProcessStatus(Tcl_Pid pid, int resolvedPid, + int options, int *codePtr, Tcl_Obj **msgPtr, + Tcl_Obj **errorObjPtr); +static Tcl_Obj * BuildProcessStatusObj(ProcessInfo *info); static int ProcessListObjCmd(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *const objv[]); @@ -54,6 +63,231 @@ static int ProcessAutopurgeObjCmd(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *const objv[]); +/* FRED TODO */ +void +InitProcessInfo( + ProcessInfo *info, + Tcl_Pid pid, + int resolvedPid) +{ + info->pid = pid; + info->resolvedPid = resolvedPid; + info->purge = 0; + info->status = TCL_PROCESS_UNCHANGED; + info->code = 0; + info->msg = NULL; + info->error = NULL; +} + +/* FRED TODO */ +void +FreeProcessInfo( + ProcessInfo *info, + int preserveObjs) +{ + if (!preserveObjs) { + if (info->msg) { + Tcl_DecrRefCount(info->msg); + } + if (info->error) { + Tcl_DecrRefCount(info->error); + } + } + ckfree(info); +} + +/* FRED TODO */ +int +RefreshProcessInfo( + ProcessInfo *info, + int options +) +{ + if (info->status == TCL_PROCESS_UNCHANGED) { + /* + * Refresh & store status. + */ + + info->status = WaitProcessStatus(info->pid, info->resolvedPid, + options, &info->code, &info->msg, &info->error); + if (info->msg) Tcl_IncrRefCount(info->msg); + if (info->error) Tcl_IncrRefCount(info->error); + return (info->status != TCL_PROCESS_UNCHANGED); + } else { + return 0; + } +} + +/* FRED TODO */ +int +WaitProcessStatus( + Tcl_Pid pid, + int resolvedPid, + int options, + int *codePtr, + Tcl_Obj **msgObjPtr, + Tcl_Obj **errorObjPtr) +{ + int waitStatus; + Tcl_Obj *errorStrings[5]; + const char *msg; + + pid = Tcl_WaitPid(pid, &waitStatus, options); + if ((pid == 0)) { + /* + * No change. + */ + + return TCL_PROCESS_UNCHANGED; + } + + /* + * Get process status. + */ + + if (pid == (Tcl_Pid) -1) { + /* + * POSIX errName msg + */ + + msg = Tcl_ErrnoMsg(errno); + if (errno == ECHILD) { + /* + * This changeup in message suggested by Mark Diekhans to + * remind people that ECHILD errors can occur on some + * systems if SIGCHLD isn't in its default state. + */ + + msg = "child process lost (is SIGCHLD ignored or trapped?)"; + } + if (codePtr) *codePtr = errno; + if (msgObjPtr) *msgObjPtr = Tcl_ObjPrintf( + "error waiting for process to exit: %s", msg); + if (errorObjPtr) { + errorStrings[0] = Tcl_NewStringObj("POSIX", -1); + errorStrings[1] = Tcl_NewStringObj(Tcl_ErrnoId(), -1); + errorStrings[2] = Tcl_NewStringObj(msg, -1); + *errorObjPtr = Tcl_NewListObj(3, errorStrings); + } + return TCL_PROCESS_ERROR; + } else if (WIFEXITED(waitStatus)) { + if (codePtr) *codePtr = WEXITSTATUS(waitStatus); + if (!WEXITSTATUS(waitStatus)) { + /* + * Normal exit. + */ + + if (msgObjPtr) *msgObjPtr = NULL; + if (errorObjPtr) *errorObjPtr = NULL; + } else { + /* + * CHILDSTATUS pid code + * + * Child exited with a non-zero exit status. + */ + + if (msgObjPtr) *msgObjPtr = Tcl_NewStringObj( + "child process exited abnormally", -1); + if (errorObjPtr) { + errorStrings[0] = Tcl_NewStringObj("CHILDSTATUS", -1); + errorStrings[1] = Tcl_NewIntObj(resolvedPid); + errorStrings[2] = Tcl_NewIntObj(WEXITSTATUS(waitStatus)); + *errorObjPtr = Tcl_NewListObj(3, errorStrings); + } + } + return TCL_PROCESS_EXITED; + } else if (WIFSIGNALED(waitStatus)) { + /* + * CHILDKILLED pid sigName msg + * + * Child killed because of a signal. + */ + + msg = Tcl_SignalMsg(WTERMSIG(waitStatus)); + if (codePtr) *codePtr = WTERMSIG(waitStatus); + if (msgObjPtr) *msgObjPtr = Tcl_ObjPrintf( + "child killed: %s", msg); + if (errorObjPtr) { + errorStrings[0] = Tcl_NewStringObj("CHILDKILLED", -1); + errorStrings[1] = Tcl_NewIntObj(resolvedPid); + errorStrings[2] = Tcl_NewStringObj(Tcl_SignalId(WTERMSIG(waitStatus)), -1); + errorStrings[3] = Tcl_NewStringObj(msg, -1); + *errorObjPtr = Tcl_NewListObj(4, errorStrings); + } + return TCL_PROCESS_SIGNALED; + } else if (WIFSTOPPED(waitStatus)) { + /* + * CHILDSUSP pid sigName msg + * + * Child suspended because of a signal. + */ + + msg = Tcl_SignalMsg(WSTOPSIG(waitStatus)); + if (codePtr) *codePtr = WSTOPSIG(waitStatus); + if (msgObjPtr) *msgObjPtr = Tcl_ObjPrintf( + "child suspended: %s", msg); + if (errorObjPtr) { + errorStrings[0] = Tcl_NewStringObj("CHILDSUSP", -1); + errorStrings[1] = Tcl_NewIntObj(resolvedPid); + errorStrings[2] = Tcl_NewStringObj(Tcl_SignalId(WSTOPSIG(waitStatus)), -1); + errorStrings[3] = Tcl_NewStringObj(msg, -1); + *errorObjPtr = Tcl_NewListObj(4, errorStrings); + } + return TCL_PROCESS_STOPPED; + } else { + /* + * TCL OPERATION EXEC ODDWAITRESULT + * + * Child wait status didn't make sense. + */ + + if (codePtr) *codePtr = waitStatus; + if (msgObjPtr) *msgObjPtr = Tcl_NewStringObj( + "child wait status didn't make sense\n", -1); + if (errorObjPtr) { + errorStrings[0] = Tcl_NewStringObj("TCL", -1); + errorStrings[1] = Tcl_NewStringObj("OPERATION", -1); + errorStrings[2] = Tcl_NewStringObj("EXEC", -1); + errorStrings[3] = Tcl_NewStringObj("ODDWAITRESULT", -1); + errorStrings[4] = Tcl_NewIntObj(resolvedPid); + *errorObjPtr = Tcl_NewListObj(5, errorStrings); + } + return TCL_PROCESS_UNKNOWN_STATUS; + } +} + +/* FRED TODO */ +Tcl_Obj * +BuildProcessStatusObj( + ProcessInfo *info) +{ + Tcl_Obj *resultObjs[3]; + + if (info->status == TCL_PROCESS_UNCHANGED) { + /* + * Process still running, return empty obj. + */ + + return Tcl_NewObj(); + } + if (info->status == TCL_PROCESS_EXITED && info->code == 0) { + /* + * Normal exit, return TCL_OK. + */ + + return Tcl_NewIntObj(TCL_OK); + } + + /* + * Abnormal exit, return {TCL_ERROR msg error} + */ + + resultObjs[0] = Tcl_NewIntObj(TCL_ERROR); + resultObjs[1] = info->msg; + resultObjs[2] = info->error; + return Tcl_NewListObj(3, resultObjs); +} + /*---------------------------------------------------------------------- * * ProcessListObjCmd -- @@ -92,14 +326,14 @@ ProcessListObjCmd( */ list = Tcl_NewListObj(0, NULL); - Tcl_MutexLock(&statusMutex); - for (entry = Tcl_FirstHashEntry(&statusTable, &search); entry != NULL; - entry = Tcl_NextHashEntry(&search)) { + Tcl_MutexLock(&infoTablesMutex); + for (entry = Tcl_FirstHashEntry(&infoTablePerResolvedPid, &search); + entry != NULL; entry = Tcl_NextHashEntry(&search)) { info = (ProcessInfo *) Tcl_GetHashValue(entry); Tcl_ListObjAppendElement(interp, list, Tcl_NewIntObj(info->resolvedPid)); } - Tcl_MutexUnlock(&statusMutex); + Tcl_MutexUnlock(&infoTablesMutex); Tcl_SetObjResult(interp, list); return TCL_OK; } @@ -172,35 +406,17 @@ ProcessStatusObjCmd( */ dict = Tcl_NewDictObj(); - Tcl_MutexLock(&statusMutex); - for (entry = Tcl_FirstHashEntry(&statusTable, &search); entry != NULL; - entry = Tcl_NextHashEntry(&search)) { + Tcl_MutexLock(&infoTablesMutex); + for (entry = Tcl_FirstHashEntry(&infoTablePerResolvedPid, &search); + entry != NULL; entry = Tcl_NextHashEntry(&search)) { info = (ProcessInfo *) Tcl_GetHashValue(entry); - if (autopurge) { - if (GetProcessStatus(info->pid, info->resolvedPid, options, - NULL)) { - /* - * Purge. - */ - - PurgeProcessStatus(entry); - Tcl_DeleteHashEntry(entry); - continue; - } - } else if (!info->status) { - /* - * Update status. - */ + RefreshProcessInfo(info, options); + // TODO purge etc. - if (GetProcessStatus(info->pid, info->resolvedPid, options, - &info->status)) { - Tcl_IncrRefCount(info->status); - } - } - Tcl_DictObjPut(interp, dict, Tcl_NewIntObj(info->resolvedPid), - info->status ? info->status : Tcl_NewObj()); + Tcl_DictObjPut(interp, dict, Tcl_NewIntObj(info->resolvedPid), + BuildProcessStatusObj(info)); } - Tcl_MutexUnlock(&statusMutex); + Tcl_MutexUnlock(&infoTablesMutex); } else { /* * Only return statuses of provided processes. @@ -211,16 +427,16 @@ ProcessStatusObjCmd( return result; } dict = Tcl_NewDictObj(); - Tcl_MutexLock(&statusMutex); + Tcl_MutexLock(&infoTablesMutex); for (i = 0; i < numPids; i++) { result = Tcl_GetIntFromObj(interp, pidObjs[i], (int *) &pid); if (result != TCL_OK) { - Tcl_MutexUnlock(&statusMutex); + Tcl_MutexUnlock(&infoTablesMutex); Tcl_DecrRefCount(dict); return result; } - entry = Tcl_FindHashEntry(&statusTable, INT2PTR(pid)); + entry = Tcl_FindHashEntry(&infoTablePerResolvedPid, INT2PTR(pid)); if (!entry) { /* * Skip unknown process. @@ -230,31 +446,14 @@ ProcessStatusObjCmd( } info = (ProcessInfo *) Tcl_GetHashValue(entry); - if (autopurge) { - if (GetProcessStatus(info->pid, info->resolvedPid, options, - NULL)) { - /* - * Purge. - */ - - PurgeProcessStatus(entry); - Tcl_DeleteHashEntry(entry); - continue; - } - } else if (!info->status) { - /* - * Update status. - */ + RefreshProcessInfo(info, options); - if (GetProcessStatus(info->pid, info->resolvedPid, options, - &info->status)) { - Tcl_IncrRefCount(info->status); - } - } - Tcl_DictObjPut(interp, dict, Tcl_NewIntObj(info->resolvedPid), - info->status ? info->status : Tcl_NewObj()); + // TODO purge etc. + + Tcl_DictObjPut(interp, dict, Tcl_NewIntObj(info->resolvedPid), + BuildProcessStatusObj(info)); } - Tcl_MutexUnlock(&statusMutex); + Tcl_MutexUnlock(&infoTablesMutex); } Tcl_SetObjResult(interp, dict); return TCL_OK; @@ -285,6 +484,7 @@ ProcessPurgeObjCmd( { Tcl_HashEntry *entry; Tcl_HashSearch search; + ProcessInfo *info; int numPids; Tcl_Obj **pidObjs; int result; @@ -301,14 +501,16 @@ ProcessPurgeObjCmd( * Purge all terminated processes. */ - Tcl_MutexLock(&statusMutex); - for (entry = Tcl_FirstHashEntry(&statusTable, &search); entry != NULL; + Tcl_MutexLock(&infoTablesMutex); + for (entry = Tcl_FirstHashEntry(&infoTablePerPid, &search); entry != NULL; entry = Tcl_NextHashEntry(&search)) { - if (PurgeProcessStatus(entry)) { + info = (ProcessInfo *) Tcl_GetHashValue(entry); + if (info->status != TCL_PROCESS_UNCHANGED) { Tcl_DeleteHashEntry(entry); + FreeProcessInfo(info, 0); } } - Tcl_MutexUnlock(&statusMutex); + Tcl_MutexUnlock(&infoTablesMutex); } else { /* * Purge only provided processes. @@ -318,20 +520,24 @@ ProcessPurgeObjCmd( if (result != TCL_OK) { return result; } - Tcl_MutexLock(&statusMutex); + Tcl_MutexLock(&infoTablesMutex); for (i = 0; i < numPids; i++) { result = Tcl_GetIntFromObj(interp, pidObjs[i], (int *) &pid); if (result != TCL_OK) { - Tcl_MutexUnlock(&statusMutex); + Tcl_MutexUnlock(&infoTablesMutex); return result; } - entry = Tcl_FindHashEntry(&statusTable, INT2PTR(pid)); - if (entry && PurgeProcessStatus(entry)) { - Tcl_DeleteHashEntry(entry); + entry = Tcl_FindHashEntry(&infoTablePerPid, INT2PTR(pid)); + if (entry) { + info = (ProcessInfo *) Tcl_GetHashValue(entry); + if (info->status != TCL_PROCESS_UNCHANGED) { + Tcl_DeleteHashEntry(entry); + FreeProcessInfo(info, 0); + } } } - Tcl_MutexUnlock(&statusMutex); + Tcl_MutexUnlock(&infoTablesMutex); } return TCL_OK; @@ -417,13 +623,14 @@ TclInitProcessCmd( }; Tcl_Command processCmd; - if (statusTableInitialized == 0) { - Tcl_MutexLock(&statusMutex); - if (statusTableInitialized == 0) { - Tcl_InitHashTable(&statusTable, TCL_ONE_WORD_KEYS); - statusTableInitialized = 1; + if (infoTablesInitialized == 0) { + Tcl_MutexLock(&infoTablesMutex); + if (infoTablesInitialized == 0) { + Tcl_InitHashTable(&infoTablePerPid, TCL_ONE_WORD_KEYS); + Tcl_InitHashTable(&infoTablePerResolvedPid, TCL_ONE_WORD_KEYS); + infoTablesInitialized = 1; } - Tcl_MutexUnlock(&statusMutex); + Tcl_MutexUnlock(&infoTablesMutex); } processCmd = TclMakeEnsemble(interp, "::tcl::process", processImplMap); @@ -434,7 +641,7 @@ TclInitProcessCmd( /* FRED TODO */ void -TclProcessDetach( +TclProcessCreated( Tcl_Pid pid) { int resolvedPid; @@ -442,233 +649,119 @@ TclProcessDetach( int isNew; ProcessInfo *info; + /* + * Get resolved pid first. + */ + resolvedPid = TclpGetPid(pid); - Tcl_MutexLock(&statusMutex); - entry = Tcl_CreateHashEntry(&statusTable, INT2PTR(resolvedPid), &isNew); + + Tcl_MutexLock(&infoTablesMutex); + + /* + * Create entry in pid table. + */ + + entry = Tcl_CreateHashEntry(&infoTablePerPid, pid, &isNew); if (!isNew) { /* - * Pid was reused, free old status and reuse structure. + * Pid was reused, free old info and reuse structure. */ info = (ProcessInfo *) Tcl_GetHashValue(entry); - if (info->status) { - Tcl_DecrRefCount(info->status); - } - } else { - /* - * Allocate new info structure. - */ - - info = (ProcessInfo *) ckalloc(sizeof(ProcessInfo)); - Tcl_SetHashValue(entry, info); + FreeProcessInfo(info, 0); } - + /* - * Initialize with an empty status. + * Allocate and initialize info structure. */ - info->pid = pid; - info->resolvedPid = resolvedPid; - info->status = NULL; + info = (ProcessInfo *) ckalloc(sizeof(ProcessInfo)); + InitProcessInfo(info, pid, resolvedPid); + + /* + * Add entry to tables. + */ - Tcl_MutexUnlock(&statusMutex); + Tcl_SetHashValue(entry, info); + entry = Tcl_CreateHashEntry(&infoTablePerResolvedPid, INT2PTR(resolvedPid), &isNew); + Tcl_SetHashValue(entry, info); + + Tcl_MutexUnlock(&infoTablesMutex); } + /* FRED TODO */ -int -TclProcessStatus( +TclProcessWaitStatus +TclProcessWait( Tcl_Pid pid, - int options) + int options, + int *codePtr, + Tcl_Obj **msgObjPtr, + Tcl_Obj **errorObjPtr) { - int resolvedPid; Tcl_HashEntry *entry; ProcessInfo *info; - Tcl_Obj *status; - int isNew; - + int result; + /* - * We need to get the resolved pid before we wait on it as the windows - * implementation of Tcl_WaitPid deletes the information such that any - * following calls to TclpGetPid fail. + * First search for pid in table. */ - resolvedPid = TclpGetPid(pid); - - if (!GetProcessStatus(pid, resolvedPid, options, - (autopurge ? NULL /* unused */: &status))) { + entry = Tcl_FindHashEntry(&infoTablePerPid, pid); + if (!entry) { /* - * Process still alive, or non child-related error. + * Unknown process, just call WaitProcessStatus and return. */ - return 0; - } - - if (autopurge) { - /* - * Child terminated, purge. - */ - - Tcl_MutexLock(&statusMutex); - entry = Tcl_FindHashEntry(&statusTable, INT2PTR(resolvedPid)); - if (entry) { - PurgeProcessStatus(entry); - Tcl_DeleteHashEntry(entry); - } - Tcl_MutexUnlock(&statusMutex); - - return 1; + return WaitProcessStatus(pid, TclpGetPid(pid), options, codePtr, + msgObjPtr, errorObjPtr); } - /* - * Store process status. - */ - - Tcl_MutexLock(&statusMutex); - entry = Tcl_CreateHashEntry(&statusTable, INT2PTR(resolvedPid), &isNew); - if (!isNew) { - info = (ProcessInfo *) Tcl_GetHashValue(entry); - if (info->status) { - /* - * Free old status object. - */ - - Tcl_DecrRefCount(info->status); - } - } else { + info = (ProcessInfo *) Tcl_GetHashValue(entry); + if (info->purge) { /* - * Allocate new info structure. + * Process has completed but TclProcessWait has already been called, + * so report no change. */ - - info = (ProcessInfo *) ckalloc(sizeof(ProcessInfo)); - info->pid = pid; - info->resolvedPid = resolvedPid; - Tcl_SetHashValue(entry, info); + + return TCL_PROCESS_UNCHANGED; } - info->status = status; - Tcl_IncrRefCount(status); - Tcl_MutexUnlock(&statusMutex); - - return 1; -} - -/* FRED TODO */ -int -GetProcessStatus( - Tcl_Pid pid, - int resolvedPid, - int options, - Tcl_Obj **statusPtr) -{ - int waitStatus; - Tcl_Obj *statusCodes[5]; - const char *msg; - - pid = Tcl_WaitPid(pid, &waitStatus, options); - if ((pid == 0) || ((pid == (Tcl_Pid) -1) && (errno != ECHILD))) { + RefreshProcessInfo(info, options); + if (info->status == TCL_PROCESS_UNCHANGED) { /* - * Process still alive, or non child-related error. + * No change, stop there. */ - return 0; - } - - if (!statusPtr) { - return 1; + return TCL_PROCESS_UNCHANGED; } /* - * Get process status. + * Set return values. */ - if (pid == (Tcl_Pid) -1) { - /* - * POSIX errName msg - */ + result = info->status; + if (codePtr) *codePtr = info->code; + if (msgObjPtr) *msgObjPtr = info->msg; + if (errorObjPtr) *errorObjPtr = info->error; - statusCodes[0] = Tcl_NewStringObj("POSIX", -1); - statusCodes[1] = Tcl_NewStringObj(Tcl_ErrnoId(), -1); - msg = Tcl_ErrnoMsg(errno); - if (errno == ECHILD) { - /* - * This changeup in message suggested by Mark Diekhans to - * remind people that ECHILD errors can occur on some - * systems if SIGCHLD isn't in its default state. - */ - - msg = "child process lost (is SIGCHLD ignored or trapped?)"; - } - statusCodes[2] = Tcl_NewStringObj(msg, -1); - *statusPtr = Tcl_NewListObj(3, statusCodes); - } else if (WIFEXITED(waitStatus)) { - /* - * CHILDSTATUS pid code - * - * Child exited with a non-zero exit status. - */ - - statusCodes[0] = Tcl_NewStringObj("CHILDSTATUS", -1); - statusCodes[1] = Tcl_NewIntObj(resolvedPid); - statusCodes[2] = Tcl_NewIntObj(WEXITSTATUS(waitStatus)); - *statusPtr = Tcl_NewListObj(3, statusCodes); - } else if (WIFSIGNALED(waitStatus)) { - /* - * CHILDKILLED pid sigName msg - * - * Child killed because of a signal - */ - - statusCodes[0] = Tcl_NewStringObj("CHILDKILLED", -1); - statusCodes[1] = Tcl_NewIntObj(resolvedPid); - statusCodes[2] = Tcl_NewStringObj(Tcl_SignalId(WTERMSIG(waitStatus)), -1); - statusCodes[3] = Tcl_NewStringObj(Tcl_SignalMsg(WTERMSIG(waitStatus)), -1); - *statusPtr = Tcl_NewListObj(4, statusCodes); - } else if (WIFSTOPPED(waitStatus)) { + if (autopurge) { /* - * CHILDSUSP pid sigName msg - * - * Child suspended because of a signal + * Purge now. */ - statusCodes[0] = Tcl_NewStringObj("CHILDSUSP", -1); - statusCodes[1] = Tcl_NewIntObj(resolvedPid); - statusCodes[2] = Tcl_NewStringObj(Tcl_SignalId(WSTOPSIG(waitStatus)), -1); - statusCodes[3] = Tcl_NewStringObj(Tcl_SignalMsg(WSTOPSIG(waitStatus)), -1); - *statusPtr = Tcl_NewListObj(4, statusCodes); + Tcl_DeleteHashEntry(entry); + entry = Tcl_FindHashEntry(&infoTablePerResolvedPid, + INT2PTR(info->resolvedPid)); + Tcl_DeleteHashEntry(entry); + FreeProcessInfo(info, 1); } else { /* - * TCL OPERATION EXEC ODDWAITRESULT - * - * Child wait status didn't make sense. - */ - - statusCodes[0] = Tcl_NewStringObj("TCL", -1); - statusCodes[1] = Tcl_NewStringObj("OPERATION", -1); - statusCodes[2] = Tcl_NewStringObj("EXEC", -1); - statusCodes[3] = Tcl_NewStringObj("ODDWAITRESULT", -1); - statusCodes[4] = Tcl_NewIntObj(resolvedPid); - *statusPtr = Tcl_NewListObj(5, statusCodes); - } - - return 1; -} - -/* FRED TODO */ -int -PurgeProcessStatus( - Tcl_HashEntry *entry) -{ - ProcessInfo *info; - - info = (ProcessInfo *) Tcl_GetHashValue(entry); - if (info->status) { - /* - * Process has ended, purge. + * Eventually purge. Subsequent calls will return + * TCL_PROCESS_UNCHANGED. */ - Tcl_DecrRefCount(info->status); - return 1; + info->purge = 1; } - - return 0; + return result; } -- cgit v0.12 From 935e991786520c81b01c7c2992568703d3d0746f Mon Sep 17 00:00:00 2001 From: "f.bonnet" Date: Sun, 27 Aug 2017 15:24:22 +0000 Subject: On Windows, Tcl_Pids now map to dwProcessId instead of hProcess because the system reuses handles of recently terminated processes. --- win/tclWinPipe.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/win/tclWinPipe.c b/win/tclWinPipe.c index 4666deb..ce132d1 100644 --- a/win/tclWinPipe.c +++ b/win/tclWinPipe.c @@ -876,7 +876,7 @@ TclpGetPid( Tcl_MutexLock(&pipeMutex); for (infoPtr = procList; infoPtr != NULL; infoPtr = infoPtr->nextPtr) { - if (infoPtr->hProcess == (HANDLE) pid) { + if (infoPtr->dwProcessId == (DWORD) pid) { Tcl_MutexUnlock(&pipeMutex); return infoPtr->dwProcessId; } @@ -1187,7 +1187,7 @@ TclpCreateProcess( WaitForInputIdle(procInfo.hProcess, 5000); CloseHandle(procInfo.hThread); - *pidPtr = (Tcl_Pid) procInfo.hProcess; + *pidPtr = (Tcl_Pid) procInfo.dwProcessId; if (*pidPtr != 0) { TclWinAddProcess(procInfo.hProcess, procInfo.dwProcessId); } @@ -2458,7 +2458,7 @@ Tcl_WaitPid( prevPtrPtr = &procList; for (infoPtr = procList; infoPtr != NULL; prevPtrPtr = &infoPtr->nextPtr, infoPtr = infoPtr->nextPtr) { - if (infoPtr->hProcess == (HANDLE) pid) { + if (infoPtr->dwProcessId == (DWORD) pid) { *prevPtrPtr = infoPtr->nextPtr; break; } -- cgit v0.12 From 68b53cfb2571faea3e86f728b3a07222ea9143d0 Mon Sep 17 00:00:00 2001 From: "f.bonnet" Date: Sun, 27 Aug 2017 15:25:57 +0000 Subject: Fixed reference counting issue with objects returned by WaitProcessStatus --- generic/tclInt.h | 17 +++++--- generic/tclPipe.c | 5 ++- generic/tclProcess.c | 110 ++++++++++++++++++++++++++++++++++++--------------- 3 files changed, 93 insertions(+), 39 deletions(-) diff --git a/generic/tclInt.h b/generic/tclInt.h index c7a0a0d..32b0d8a 100644 --- a/generic/tclInt.h +++ b/generic/tclInt.h @@ -4025,13 +4025,18 @@ MODULE_SCOPE int TclFullFinalizationRequested(void); * TIP #462. */ +/* + * The following enum values give the status of a spawned process. + */ + typedef enum TclProcessWaitStatus { - TCL_PROCESS_ERROR = -1, - TCL_PROCESS_UNCHANGED = 0, - TCL_PROCESS_EXITED = 1, - TCL_PROCESS_SIGNALED = 2, - TCL_PROCESS_STOPPED = 3, - TCL_PROCESS_UNKNOWN_STATUS = 4 + TCL_PROCESS_ERROR = -1, /* Error waiting for process to exit */ + TCL_PROCESS_UNCHANGED = 0, /* No change since the last call. */ + TCL_PROCESS_EXITED = 1, /* Process has exited. */ + TCL_PROCESS_SIGNALED = 2, /* Child killed because of a signal. */ + TCL_PROCESS_STOPPED = 3, /* Child suspended because of a signal. */ + TCL_PROCESS_UNKNOWN_STATUS = 4 + /* Child wait status didn't make sense. */ } TclProcessWaitStatus; MODULE_SCOPE Tcl_Command TclInitProcessCmd(Tcl_Interp *interp); diff --git a/generic/tclPipe.c b/generic/tclPipe.c index d20d8eb..fa5c55d 100644 --- a/generic/tclPipe.c +++ b/generic/tclPipe.c @@ -290,6 +290,8 @@ TclCleanupChildren( Tcl_SetObjErrorCode(interp, error); Tcl_SetObjResult(interp, msg); } + Tcl_DecrRefCount(error); + Tcl_DecrRefCount(msg); continue; } @@ -305,7 +307,6 @@ TclCleanupChildren( if (waitStatus == TCL_PROCESS_EXITED) { if (interp != NULL) { Tcl_SetObjErrorCode(interp, error); - Tcl_DecrRefCount(msg); } abnormalExit = 1; } else if (interp != NULL) { @@ -313,6 +314,8 @@ TclCleanupChildren( Tcl_SetObjResult(interp, msg); } } + Tcl_DecrRefCount(error); + Tcl_DecrRefCount(msg); } /* diff --git a/generic/tclProcess.c b/generic/tclProcess.c index 87fc8bb..bd3467b 100644 --- a/generic/tclProcess.c +++ b/generic/tclProcess.c @@ -44,7 +44,7 @@ TCL_DECLARE_MUTEX(infoTablesMutex) static void InitProcessInfo(ProcessInfo *info, Tcl_Pid pid, int resolvedPid); -static void FreeProcessInfo(ProcessInfo *info, int preserveObjs); +static void FreeProcessInfo(ProcessInfo *info); static int RefreshProcessInfo(ProcessInfo *info, int options); static int WaitProcessStatus(Tcl_Pid pid, int resolvedPid, int options, int *codePtr, Tcl_Obj **msgPtr, @@ -82,16 +82,13 @@ InitProcessInfo( /* FRED TODO */ void FreeProcessInfo( - ProcessInfo *info, - int preserveObjs) + ProcessInfo *info) { - if (!preserveObjs) { - if (info->msg) { - Tcl_DecrRefCount(info->msg); - } - if (info->error) { - Tcl_DecrRefCount(info->error); - } + if (info->msg) { + Tcl_DecrRefCount(info->msg); + } + if (info->error) { + Tcl_DecrRefCount(info->error); } ckfree(info); } @@ -402,7 +399,7 @@ ProcessStatusObjCmd( if (objc == 1) { /* - * Return the list of all child process statuses. + * Return a dict with all child process statuses. */ dict = Tcl_NewDictObj(); @@ -411,10 +408,24 @@ ProcessStatusObjCmd( entry != NULL; entry = Tcl_NextHashEntry(&search)) { info = (ProcessInfo *) Tcl_GetHashValue(entry); RefreshProcessInfo(info, options); - // TODO purge etc. - Tcl_DictObjPut(interp, dict, Tcl_NewIntObj(info->resolvedPid), - BuildProcessStatusObj(info)); + if (info->purge && autopurge) { + /* + * Purge entry. + */ + + Tcl_DeleteHashEntry(entry); + entry = Tcl_FindHashEntry(&infoTablePerPid, info->pid); + Tcl_DeleteHashEntry(entry); + FreeProcessInfo(info); + } else { + /* + * Add to result. + */ + + Tcl_DictObjPut(interp, dict, Tcl_NewIntObj(info->resolvedPid), + BuildProcessStatusObj(info)); + } } Tcl_MutexUnlock(&infoTablesMutex); } else { @@ -448,10 +459,23 @@ ProcessStatusObjCmd( info = (ProcessInfo *) Tcl_GetHashValue(entry); RefreshProcessInfo(info, options); - // TODO purge etc. + if (info->purge && autopurge) { + /* + * Purge entry. + */ + + Tcl_DeleteHashEntry(entry); + entry = Tcl_FindHashEntry(&infoTablePerPid, info->pid); + Tcl_DeleteHashEntry(entry); + FreeProcessInfo(info); + } else { + /* + * Add to result. + */ - Tcl_DictObjPut(interp, dict, Tcl_NewIntObj(info->resolvedPid), - BuildProcessStatusObj(info)); + Tcl_DictObjPut(interp, dict, Tcl_NewIntObj(info->resolvedPid), + BuildProcessStatusObj(info)); + } } Tcl_MutexUnlock(&infoTablesMutex); } @@ -496,18 +520,26 @@ ProcessPurgeObjCmd( return TCL_ERROR; } + /* + * First reap detached procs so that their purge flag is up-to-date. + */ + + Tcl_ReapDetachedProcs(); + if (objc == 1) { /* * Purge all terminated processes. */ Tcl_MutexLock(&infoTablesMutex); - for (entry = Tcl_FirstHashEntry(&infoTablePerPid, &search); entry != NULL; - entry = Tcl_NextHashEntry(&search)) { + for (entry = Tcl_FirstHashEntry(&infoTablePerResolvedPid, &search); + entry != NULL; entry = Tcl_NextHashEntry(&search)) { info = (ProcessInfo *) Tcl_GetHashValue(entry); - if (info->status != TCL_PROCESS_UNCHANGED) { + if (info->purge) { + Tcl_DeleteHashEntry(entry); + entry = Tcl_FindHashEntry(&infoTablePerPid, info->pid); Tcl_DeleteHashEntry(entry); - FreeProcessInfo(info, 0); + FreeProcessInfo(info); } } Tcl_MutexUnlock(&infoTablesMutex); @@ -528,13 +560,21 @@ ProcessPurgeObjCmd( return result; } - entry = Tcl_FindHashEntry(&infoTablePerPid, INT2PTR(pid)); - if (entry) { - info = (ProcessInfo *) Tcl_GetHashValue(entry); - if (info->status != TCL_PROCESS_UNCHANGED) { - Tcl_DeleteHashEntry(entry); - FreeProcessInfo(info, 0); - } + entry = Tcl_FindHashEntry(&infoTablePerResolvedPid, INT2PTR(pid)); + if (!entry) { + /* + * Skip unknown process. + */ + + continue; + } + + info = (ProcessInfo *) Tcl_GetHashValue(entry); + if (info->purge) { + Tcl_DeleteHashEntry(entry); + entry = Tcl_FindHashEntry(&infoTablePerPid, info->pid); + Tcl_DeleteHashEntry(entry); + FreeProcessInfo(info); } } Tcl_MutexUnlock(&infoTablesMutex); @@ -668,7 +708,7 @@ TclProcessCreated( */ info = (ProcessInfo *) Tcl_GetHashValue(entry); - FreeProcessInfo(info, 0); + FreeProcessInfo(info); } /* @@ -683,7 +723,8 @@ TclProcessCreated( */ Tcl_SetHashValue(entry, info); - entry = Tcl_CreateHashEntry(&infoTablePerResolvedPid, INT2PTR(resolvedPid), &isNew); + entry = Tcl_CreateHashEntry(&infoTablePerResolvedPid, INT2PTR(resolvedPid), + &isNew); Tcl_SetHashValue(entry, info); Tcl_MutexUnlock(&infoTablesMutex); @@ -713,8 +754,11 @@ TclProcessWait( * Unknown process, just call WaitProcessStatus and return. */ - return WaitProcessStatus(pid, TclpGetPid(pid), options, codePtr, + result = WaitProcessStatus(pid, TclpGetPid(pid), options, codePtr, msgObjPtr, errorObjPtr); + if (msgObjPtr && *msgObjPtr) Tcl_IncrRefCount(*msgObjPtr); + if (errorObjPtr && *errorObjPtr) Tcl_IncrRefCount(*errorObjPtr); + return result; } info = (ProcessInfo *) Tcl_GetHashValue(entry); @@ -744,6 +788,8 @@ TclProcessWait( if (codePtr) *codePtr = info->code; if (msgObjPtr) *msgObjPtr = info->msg; if (errorObjPtr) *errorObjPtr = info->error; + if (msgObjPtr && *msgObjPtr) Tcl_IncrRefCount(*msgObjPtr); + if (errorObjPtr && *errorObjPtr) Tcl_IncrRefCount(*errorObjPtr); if (autopurge) { /* @@ -754,7 +800,7 @@ TclProcessWait( entry = Tcl_FindHashEntry(&infoTablePerResolvedPid, INT2PTR(info->resolvedPid)); Tcl_DeleteHashEntry(entry); - FreeProcessInfo(info, 1); + FreeProcessInfo(info); } else { /* * Eventually purge. Subsequent calls will return -- cgit v0.12 From 0a8718312d30c1e90db63395404caa10c890d9a4 Mon Sep 17 00:00:00 2001 From: "f.bonnet" Date: Sun, 27 Aug 2017 21:25:14 +0000 Subject: Comments and formatting --- generic/tclPipe.c | 2 +- generic/tclProcess.c | 923 +++++++++++++++++++++++++++++---------------------- 2 files changed, 532 insertions(+), 393 deletions(-) diff --git a/generic/tclPipe.c b/generic/tclPipe.c index fa5c55d..bc760b6 100644 --- a/generic/tclPipe.c +++ b/generic/tclPipe.c @@ -345,7 +345,7 @@ TclCleanupChildren( Tcl_PosixError(interp))); } else if (count > 0) { anyErrorInfo = 1; - Tcl_SetObjResult(interp, objPtr); + Tcl_SetObjResult(interp, objPtr); result = TCL_ERROR; } else { Tcl_DecrRefCount(objPtr); diff --git a/generic/tclProcess.c b/generic/tclProcess.c index bd3467b..8d98a23 100644 --- a/generic/tclProcess.c +++ b/generic/tclProcess.c @@ -2,7 +2,7 @@ * tclProcess.c -- * * This file implements the "tcl::process" ensemble for subprocess - * management as defined by TIP #462. + * management as defined by TIP #462. * * Copyright (c) 2017 Frederic Bonnet. * @@ -17,7 +17,7 @@ * processes (see tclPipe.c). */ -static int autopurge = 1; /* Autopurge flag. */ +static int autopurge = 1; /* Autopurge flag. */ /* * Hash tables that keeps track of all child process statuses. Keys are the @@ -25,13 +25,14 @@ static int autopurge = 1; /* Autopurge flag. */ */ typedef struct ProcessInfo { - Tcl_Pid pid; /*FRED TODO*/ - int resolvedPid; /*FRED TODO*/ - int purge; /*FRED TODO*/ - TclProcessWaitStatus status; - int code; /*FRED TODO*/ - Tcl_Obj *msg; /*FRED TODO*/ - Tcl_Obj *error; /*FRED TODO*/ + Tcl_Pid pid; /* Process id. */ + int resolvedPid; /* Resolved process id. */ + int purge; /* Purge eventualy. */ + TclProcessWaitStatus status;/* Process status. */ + int code; /* Error code, exit status or signal + number. */ + Tcl_Obj *msg; /* Error message. */ + Tcl_Obj *error; /* Error code. */ } ProcessInfo; static Tcl_HashTable infoTablePerPid; static Tcl_HashTable infoTablePerResolvedPid; @@ -42,33 +43,48 @@ TCL_DECLARE_MUTEX(infoTablesMutex) * Prototypes for functions defined later in this file: */ -static void InitProcessInfo(ProcessInfo *info, Tcl_Pid pid, - int resolvedPid); -static void FreeProcessInfo(ProcessInfo *info); -static int RefreshProcessInfo(ProcessInfo *info, int options); -static int WaitProcessStatus(Tcl_Pid pid, int resolvedPid, +static void InitProcessInfo(ProcessInfo *info, Tcl_Pid pid, + int resolvedPid); +static void FreeProcessInfo(ProcessInfo *info); +static int RefreshProcessInfo(ProcessInfo *info, int options); +static TclProcessWaitStatus WaitProcessStatus(Tcl_Pid pid, int resolvedPid, int options, int *codePtr, Tcl_Obj **msgPtr, - Tcl_Obj **errorObjPtr); -static Tcl_Obj * BuildProcessStatusObj(ProcessInfo *info); -static int ProcessListObjCmd(ClientData clientData, - Tcl_Interp *interp, int objc, - Tcl_Obj *const objv[]); -static int ProcessStatusObjCmd(ClientData clientData, - Tcl_Interp *interp, int objc, - Tcl_Obj *const objv[]); -static int ProcessPurgeObjCmd(ClientData clientData, - Tcl_Interp *interp, int objc, - Tcl_Obj *const objv[]); -static int ProcessAutopurgeObjCmd(ClientData clientData, - Tcl_Interp *interp, int objc, - Tcl_Obj *const objv[]); - -/* FRED TODO */ + Tcl_Obj **errorObjPtr); +static Tcl_Obj * BuildProcessStatusObj(ProcessInfo *info); +static int ProcessListObjCmd(ClientData clientData, + Tcl_Interp *interp, int objc, + Tcl_Obj *const objv[]); +static int ProcessStatusObjCmd(ClientData clientData, + Tcl_Interp *interp, int objc, + Tcl_Obj *const objv[]); +static int ProcessPurgeObjCmd(ClientData clientData, + Tcl_Interp *interp, int objc, + Tcl_Obj *const objv[]); +static int ProcessAutopurgeObjCmd(ClientData clientData, + Tcl_Interp *interp, int objc, + Tcl_Obj *const objv[]); + +/* + *---------------------------------------------------------------------- + * + * InitProcessInfo -- + * + * Initializes the ProcessInfo structure. + * + * Results: + * None. + * + * Side effects: + * Memory written. + * + *---------------------------------------------------------------------- + */ + void InitProcessInfo( - ProcessInfo *info, - Tcl_Pid pid, - int resolvedPid) + ProcessInfo *info, /* Structure to initialize. */ + Tcl_Pid pid, /* Process id. */ + int resolvedPid) /* Resolved process id. */ { info->pid = pid; info->resolvedPid = resolvedPid; @@ -79,51 +95,115 @@ InitProcessInfo( info->error = NULL; } -/* FRED TODO */ +/* + *---------------------------------------------------------------------- + * + * FreeProcessInfo -- + * + * Free the ProcessInfo structure. + * + * Results: + * None. + * + * Side effects: + * Memory deallocated, Tcl_Obj refcount decreased. + * + *---------------------------------------------------------------------- + */ + void FreeProcessInfo( - ProcessInfo *info) + ProcessInfo *info) /* Structure to free. */ { + /* + * Free stored Tcl_Objs. + */ + if (info->msg) { - Tcl_DecrRefCount(info->msg); + Tcl_DecrRefCount(info->msg); } if (info->error) { - Tcl_DecrRefCount(info->error); + Tcl_DecrRefCount(info->error); } + + /* + * Free allocated structure. + */ + ckfree(info); } -/* FRED TODO */ +/* + *---------------------------------------------------------------------- + * + * RefreshProcessInfo -- + * + * Refresh process info. + * + * Results: + * Nonzero if state changed, else zero. + * + * Side effects: + * May call WaitProcessStatus, which can block if WNOHANG option is set. + * + *---------------------------------------------------------------------- + */ + int RefreshProcessInfo( - ProcessInfo *info, - int options + ProcessInfo *info, /* Structure to refresh. */ + int options /* Options passed to WaitProcessStatus. */ ) { if (info->status == TCL_PROCESS_UNCHANGED) { - /* - * Refresh & store status. - */ - - info->status = WaitProcessStatus(info->pid, info->resolvedPid, - options, &info->code, &info->msg, &info->error); - if (info->msg) Tcl_IncrRefCount(info->msg); - if (info->error) Tcl_IncrRefCount(info->error); - return (info->status != TCL_PROCESS_UNCHANGED); + /* + * Refresh & store status. + */ + + info->status = WaitProcessStatus(info->pid, info->resolvedPid, + options, &info->code, &info->msg, &info->error); + if (info->msg) Tcl_IncrRefCount(info->msg); + if (info->error) Tcl_IncrRefCount(info->error); + return (info->status != TCL_PROCESS_UNCHANGED); } else { - return 0; + /* + * No change. + */ + + return 0; } } -/* FRED TODO */ -int +/* + *---------------------------------------------------------------------- + * + * WaitProcessStatus -- + * + * Wait for process status to change. + * + * Results: + * TclProcessWaitStatus enum value. + * + * Side effects: + * May call WaitProcessStatus, which can block if WNOHANG option is set. + * + *---------------------------------------------------------------------- + */ + +TclProcessWaitStatus WaitProcessStatus( - Tcl_Pid pid, - int resolvedPid, - int options, - int *codePtr, - Tcl_Obj **msgObjPtr, - Tcl_Obj **errorObjPtr) + Tcl_Pid pid, /* Process id. */ + int resolvedPid, /* Resolved process id. */ + int options, /* Options passed to Tcl_WaitPid. */ + int *codePtr, /* If non-NULL, will receive either: + * - 0 for normal exit. + * - errno in case of error. + * - non-zero exit code for abormal exit. + * - signal number if killed or suspended. + * - Tcl_WaitPid status in all other cases. + */ + Tcl_Obj **msgObjPtr, /* If non-NULL, will receive error message. */ + Tcl_Obj **errorObjPtr) /* If non-NULL, will receive error code. */ { int waitStatus; Tcl_Obj *errorStrings[5]; @@ -131,11 +211,11 @@ WaitProcessStatus( pid = Tcl_WaitPid(pid, &waitStatus, options); if ((pid == 0)) { - /* - * No change. - */ - - return TCL_PROCESS_UNCHANGED; + /* + * No change. + */ + + return TCL_PROCESS_UNCHANGED; } /* @@ -143,117 +223,136 @@ WaitProcessStatus( */ if (pid == (Tcl_Pid) -1) { - /* - * POSIX errName msg - */ - - msg = Tcl_ErrnoMsg(errno); - if (errno == ECHILD) { - /* - * This changeup in message suggested by Mark Diekhans to - * remind people that ECHILD errors can occur on some - * systems if SIGCHLD isn't in its default state. - */ - - msg = "child process lost (is SIGCHLD ignored or trapped?)"; - } - if (codePtr) *codePtr = errno; - if (msgObjPtr) *msgObjPtr = Tcl_ObjPrintf( - "error waiting for process to exit: %s", msg); - if (errorObjPtr) { - errorStrings[0] = Tcl_NewStringObj("POSIX", -1); - errorStrings[1] = Tcl_NewStringObj(Tcl_ErrnoId(), -1); - errorStrings[2] = Tcl_NewStringObj(msg, -1); - *errorObjPtr = Tcl_NewListObj(3, errorStrings); - } - return TCL_PROCESS_ERROR; + /* + * POSIX errName msg + */ + + msg = Tcl_ErrnoMsg(errno); + if (errno == ECHILD) { + /* + * This changeup in message suggested by Mark Diekhans to + * remind people that ECHILD errors can occur on some + * systems if SIGCHLD isn't in its default state. + */ + + msg = "child process lost (is SIGCHLD ignored or trapped?)"; + } + if (codePtr) *codePtr = errno; + if (msgObjPtr) *msgObjPtr = Tcl_ObjPrintf( + "error waiting for process to exit: %s", msg); + if (errorObjPtr) { + errorStrings[0] = Tcl_NewStringObj("POSIX", -1); + errorStrings[1] = Tcl_NewStringObj(Tcl_ErrnoId(), -1); + errorStrings[2] = Tcl_NewStringObj(msg, -1); + *errorObjPtr = Tcl_NewListObj(3, errorStrings); + } + return TCL_PROCESS_ERROR; } else if (WIFEXITED(waitStatus)) { - if (codePtr) *codePtr = WEXITSTATUS(waitStatus); - if (!WEXITSTATUS(waitStatus)) { - /* - * Normal exit. - */ - - if (msgObjPtr) *msgObjPtr = NULL; - if (errorObjPtr) *errorObjPtr = NULL; - } else { - /* - * CHILDSTATUS pid code - * - * Child exited with a non-zero exit status. - */ - - if (msgObjPtr) *msgObjPtr = Tcl_NewStringObj( - "child process exited abnormally", -1); - if (errorObjPtr) { - errorStrings[0] = Tcl_NewStringObj("CHILDSTATUS", -1); - errorStrings[1] = Tcl_NewIntObj(resolvedPid); - errorStrings[2] = Tcl_NewIntObj(WEXITSTATUS(waitStatus)); - *errorObjPtr = Tcl_NewListObj(3, errorStrings); - } - } - return TCL_PROCESS_EXITED; + if (codePtr) *codePtr = WEXITSTATUS(waitStatus); + if (!WEXITSTATUS(waitStatus)) { + /* + * Normal exit. + */ + + if (msgObjPtr) *msgObjPtr = NULL; + if (errorObjPtr) *errorObjPtr = NULL; + } else { + /* + * CHILDSTATUS pid code + * + * Child exited with a non-zero exit status. + */ + + if (msgObjPtr) *msgObjPtr = Tcl_NewStringObj( + "child process exited abnormally", -1); + if (errorObjPtr) { + errorStrings[0] = Tcl_NewStringObj("CHILDSTATUS", -1); + errorStrings[1] = Tcl_NewIntObj(resolvedPid); + errorStrings[2] = Tcl_NewIntObj(WEXITSTATUS(waitStatus)); + *errorObjPtr = Tcl_NewListObj(3, errorStrings); + } + } + return TCL_PROCESS_EXITED; } else if (WIFSIGNALED(waitStatus)) { - /* - * CHILDKILLED pid sigName msg - * - * Child killed because of a signal. - */ - - msg = Tcl_SignalMsg(WTERMSIG(waitStatus)); - if (codePtr) *codePtr = WTERMSIG(waitStatus); - if (msgObjPtr) *msgObjPtr = Tcl_ObjPrintf( - "child killed: %s", msg); - if (errorObjPtr) { - errorStrings[0] = Tcl_NewStringObj("CHILDKILLED", -1); - errorStrings[1] = Tcl_NewIntObj(resolvedPid); - errorStrings[2] = Tcl_NewStringObj(Tcl_SignalId(WTERMSIG(waitStatus)), -1); - errorStrings[3] = Tcl_NewStringObj(msg, -1); - *errorObjPtr = Tcl_NewListObj(4, errorStrings); - } - return TCL_PROCESS_SIGNALED; + /* + * CHILDKILLED pid sigName msg + * + * Child killed because of a signal. + */ + + msg = Tcl_SignalMsg(WTERMSIG(waitStatus)); + if (codePtr) *codePtr = WTERMSIG(waitStatus); + if (msgObjPtr) *msgObjPtr = Tcl_ObjPrintf( + "child killed: %s", msg); + if (errorObjPtr) { + errorStrings[0] = Tcl_NewStringObj("CHILDKILLED", -1); + errorStrings[1] = Tcl_NewIntObj(resolvedPid); + errorStrings[2] = Tcl_NewStringObj(Tcl_SignalId(WTERMSIG(waitStatus)), -1); + errorStrings[3] = Tcl_NewStringObj(msg, -1); + *errorObjPtr = Tcl_NewListObj(4, errorStrings); + } + return TCL_PROCESS_SIGNALED; } else if (WIFSTOPPED(waitStatus)) { - /* - * CHILDSUSP pid sigName msg - * - * Child suspended because of a signal. - */ - - msg = Tcl_SignalMsg(WSTOPSIG(waitStatus)); - if (codePtr) *codePtr = WSTOPSIG(waitStatus); - if (msgObjPtr) *msgObjPtr = Tcl_ObjPrintf( - "child suspended: %s", msg); - if (errorObjPtr) { - errorStrings[0] = Tcl_NewStringObj("CHILDSUSP", -1); - errorStrings[1] = Tcl_NewIntObj(resolvedPid); - errorStrings[2] = Tcl_NewStringObj(Tcl_SignalId(WSTOPSIG(waitStatus)), -1); - errorStrings[3] = Tcl_NewStringObj(msg, -1); - *errorObjPtr = Tcl_NewListObj(4, errorStrings); - } - return TCL_PROCESS_STOPPED; + /* + * CHILDSUSP pid sigName msg + * + * Child suspended because of a signal. + */ + + msg = Tcl_SignalMsg(WSTOPSIG(waitStatus)); + if (codePtr) *codePtr = WSTOPSIG(waitStatus); + if (msgObjPtr) *msgObjPtr = Tcl_ObjPrintf( + "child suspended: %s", msg); + if (errorObjPtr) { + errorStrings[0] = Tcl_NewStringObj("CHILDSUSP", -1); + errorStrings[1] = Tcl_NewIntObj(resolvedPid); + errorStrings[2] = Tcl_NewStringObj(Tcl_SignalId(WSTOPSIG(waitStatus)), -1); + errorStrings[3] = Tcl_NewStringObj(msg, -1); + *errorObjPtr = Tcl_NewListObj(4, errorStrings); + } + return TCL_PROCESS_STOPPED; } else { - /* - * TCL OPERATION EXEC ODDWAITRESULT - * - * Child wait status didn't make sense. - */ - - if (codePtr) *codePtr = waitStatus; - if (msgObjPtr) *msgObjPtr = Tcl_NewStringObj( - "child wait status didn't make sense\n", -1); - if (errorObjPtr) { - errorStrings[0] = Tcl_NewStringObj("TCL", -1); - errorStrings[1] = Tcl_NewStringObj("OPERATION", -1); - errorStrings[2] = Tcl_NewStringObj("EXEC", -1); - errorStrings[3] = Tcl_NewStringObj("ODDWAITRESULT", -1); - errorStrings[4] = Tcl_NewIntObj(resolvedPid); - *errorObjPtr = Tcl_NewListObj(5, errorStrings); - } - return TCL_PROCESS_UNKNOWN_STATUS; + /* + * TCL OPERATION EXEC ODDWAITRESULT + * + * Child wait status didn't make sense. + */ + + if (codePtr) *codePtr = waitStatus; + if (msgObjPtr) *msgObjPtr = Tcl_NewStringObj( + "child wait status didn't make sense\n", -1); + if (errorObjPtr) { + errorStrings[0] = Tcl_NewStringObj("TCL", -1); + errorStrings[1] = Tcl_NewStringObj("OPERATION", -1); + errorStrings[2] = Tcl_NewStringObj("EXEC", -1); + errorStrings[3] = Tcl_NewStringObj("ODDWAITRESULT", -1); + errorStrings[4] = Tcl_NewIntObj(resolvedPid); + *errorObjPtr = Tcl_NewListObj(5, errorStrings); + } + return TCL_PROCESS_UNKNOWN_STATUS; } } -/* FRED TODO */ + +/* + *---------------------------------------------------------------------- + * + * BuildProcessStatusObj -- + * + * Build a list object with process status. The first element is always + * a standard Tcl return value, which can be either TCL_OK or TCL_ERROR. + * In the latter case, the second element is the error message and the + * third element is a Tcl error code (see tclvars). + * + * Results: + * A list object. + * + * Side effects: + * Tcl_Objs are created. + * + *---------------------------------------------------------------------- + */ + Tcl_Obj * BuildProcessStatusObj( ProcessInfo *info) @@ -261,18 +360,18 @@ BuildProcessStatusObj( Tcl_Obj *resultObjs[3]; if (info->status == TCL_PROCESS_UNCHANGED) { - /* - * Process still running, return empty obj. - */ + /* + * Process still running, return empty obj. + */ - return Tcl_NewObj(); + return Tcl_NewObj(); } if (info->status == TCL_PROCESS_EXITED && info->code == 0) { - /* - * Normal exit, return TCL_OK. - */ - - return Tcl_NewIntObj(TCL_OK); + /* + * Normal exit, return TCL_OK. + */ + + return Tcl_NewIntObj(TCL_OK); } /* @@ -290,13 +389,13 @@ BuildProcessStatusObj( * ProcessListObjCmd -- * * This function implements the 'tcl::process list' Tcl command. - * Refer to the user documentation for details on what it does. + * Refer to the user documentation for details on what it does. * * Results: * Returns a standard Tcl result. * * Side effects: - * None.FRED TODO + * Access to the internal structures is protected by infoTablesMutex. * *---------------------------------------------------------------------- */ @@ -325,10 +424,10 @@ ProcessListObjCmd( list = Tcl_NewListObj(0, NULL); Tcl_MutexLock(&infoTablesMutex); for (entry = Tcl_FirstHashEntry(&infoTablePerResolvedPid, &search); - entry != NULL; entry = Tcl_NextHashEntry(&search)) { - info = (ProcessInfo *) Tcl_GetHashValue(entry); - Tcl_ListObjAppendElement(interp, list, - Tcl_NewIntObj(info->resolvedPid)); + entry != NULL; entry = Tcl_NextHashEntry(&search)) { + info = (ProcessInfo *) Tcl_GetHashValue(entry); + Tcl_ListObjAppendElement(interp, list, + Tcl_NewIntObj(info->resolvedPid)); } Tcl_MutexUnlock(&infoTablesMutex); Tcl_SetObjResult(interp, list); @@ -340,13 +439,14 @@ ProcessListObjCmd( * ProcessStatusObjCmd -- * * This function implements the 'tcl::process status' Tcl command. - * Refer to the user documentation for details on what it does. + * Refer to the user documentation for details on what it does. * * Results: * Returns a standard Tcl result. * * Side effects: - * None.FRED TODO + * Access to the internal structures is protected by infoTablesMutex. + * Calls RefreshProcessInfo, which can block if -wait switch is given. * *---------------------------------------------------------------------- */ @@ -375,7 +475,7 @@ ProcessStatusObjCmd( enum switches { STATUS_WAIT, STATUS_LAST }; - + while (objc > 1) { if (TclGetString(objv[1])[0] != '-') { break; @@ -391,93 +491,93 @@ ProcessStatusObjCmd( break; } } - + if (objc != 1 && objc != 2) { Tcl_WrongNumArgs(interp, 1, savedobjv, "?switches? ?pids?"); return TCL_ERROR; } if (objc == 1) { - /* - * Return a dict with all child process statuses. - */ - - dict = Tcl_NewDictObj(); - Tcl_MutexLock(&infoTablesMutex); - for (entry = Tcl_FirstHashEntry(&infoTablePerResolvedPid, &search); - entry != NULL; entry = Tcl_NextHashEntry(&search)) { - info = (ProcessInfo *) Tcl_GetHashValue(entry); - RefreshProcessInfo(info, options); - - if (info->purge && autopurge) { - /* - * Purge entry. - */ - - Tcl_DeleteHashEntry(entry); - entry = Tcl_FindHashEntry(&infoTablePerPid, info->pid); - Tcl_DeleteHashEntry(entry); - FreeProcessInfo(info); - } else { - /* - * Add to result. - */ - - Tcl_DictObjPut(interp, dict, Tcl_NewIntObj(info->resolvedPid), - BuildProcessStatusObj(info)); - } - } - Tcl_MutexUnlock(&infoTablesMutex); + /* + * Return a dict with all child process statuses. + */ + + dict = Tcl_NewDictObj(); + Tcl_MutexLock(&infoTablesMutex); + for (entry = Tcl_FirstHashEntry(&infoTablePerResolvedPid, &search); + entry != NULL; entry = Tcl_NextHashEntry(&search)) { + info = (ProcessInfo *) Tcl_GetHashValue(entry); + RefreshProcessInfo(info, options); + + if (info->purge && autopurge) { + /* + * Purge entry. + */ + + Tcl_DeleteHashEntry(entry); + entry = Tcl_FindHashEntry(&infoTablePerPid, info->pid); + Tcl_DeleteHashEntry(entry); + FreeProcessInfo(info); + } else { + /* + * Add to result. + */ + + Tcl_DictObjPut(interp, dict, Tcl_NewIntObj(info->resolvedPid), + BuildProcessStatusObj(info)); + } + } + Tcl_MutexUnlock(&infoTablesMutex); } else { - /* - * Only return statuses of provided processes. - */ - - result = Tcl_ListObjGetElements(interp, objv[1], &numPids, &pidObjs); - if (result != TCL_OK) { - return result; - } - dict = Tcl_NewDictObj(); - Tcl_MutexLock(&infoTablesMutex); - for (i = 0; i < numPids; i++) { - result = Tcl_GetIntFromObj(interp, pidObjs[i], (int *) &pid); - if (result != TCL_OK) { - Tcl_MutexUnlock(&infoTablesMutex); - Tcl_DecrRefCount(dict); - return result; - } - - entry = Tcl_FindHashEntry(&infoTablePerResolvedPid, INT2PTR(pid)); - if (!entry) { - /* - * Skip unknown process. - */ - - continue; - } - - info = (ProcessInfo *) Tcl_GetHashValue(entry); - RefreshProcessInfo(info, options); - - if (info->purge && autopurge) { - /* - * Purge entry. - */ - - Tcl_DeleteHashEntry(entry); - entry = Tcl_FindHashEntry(&infoTablePerPid, info->pid); - Tcl_DeleteHashEntry(entry); - FreeProcessInfo(info); - } else { - /* - * Add to result. - */ - - Tcl_DictObjPut(interp, dict, Tcl_NewIntObj(info->resolvedPid), - BuildProcessStatusObj(info)); - } - } - Tcl_MutexUnlock(&infoTablesMutex); + /* + * Only return statuses of provided processes. + */ + + result = Tcl_ListObjGetElements(interp, objv[1], &numPids, &pidObjs); + if (result != TCL_OK) { + return result; + } + dict = Tcl_NewDictObj(); + Tcl_MutexLock(&infoTablesMutex); + for (i = 0; i < numPids; i++) { + result = Tcl_GetIntFromObj(interp, pidObjs[i], (int *) &pid); + if (result != TCL_OK) { + Tcl_MutexUnlock(&infoTablesMutex); + Tcl_DecrRefCount(dict); + return result; + } + + entry = Tcl_FindHashEntry(&infoTablePerResolvedPid, INT2PTR(pid)); + if (!entry) { + /* + * Skip unknown process. + */ + + continue; + } + + info = (ProcessInfo *) Tcl_GetHashValue(entry); + RefreshProcessInfo(info, options); + + if (info->purge && autopurge) { + /* + * Purge entry. + */ + + Tcl_DeleteHashEntry(entry); + entry = Tcl_FindHashEntry(&infoTablePerPid, info->pid); + Tcl_DeleteHashEntry(entry); + FreeProcessInfo(info); + } else { + /* + * Add to result. + */ + + Tcl_DictObjPut(interp, dict, Tcl_NewIntObj(info->resolvedPid), + BuildProcessStatusObj(info)); + } + } + Tcl_MutexUnlock(&infoTablesMutex); } Tcl_SetObjResult(interp, dict); return TCL_OK; @@ -488,13 +588,13 @@ ProcessStatusObjCmd( * ProcessPurgeObjCmd -- * * This function implements the 'tcl::process purge' Tcl command. - * Refer to the user documentation for details on what it does. + * Refer to the user documentation for details on what it does. * * Results: * Returns a standard Tcl result. * * Side effects: - * None.FRED TODO + * Frees all ProcessInfo structures with their purge flag set. * *---------------------------------------------------------------------- */ @@ -525,61 +625,61 @@ ProcessPurgeObjCmd( */ Tcl_ReapDetachedProcs(); - + if (objc == 1) { - /* - * Purge all terminated processes. - */ - - Tcl_MutexLock(&infoTablesMutex); - for (entry = Tcl_FirstHashEntry(&infoTablePerResolvedPid, &search); - entry != NULL; entry = Tcl_NextHashEntry(&search)) { - info = (ProcessInfo *) Tcl_GetHashValue(entry); - if (info->purge) { - Tcl_DeleteHashEntry(entry); - entry = Tcl_FindHashEntry(&infoTablePerPid, info->pid); - Tcl_DeleteHashEntry(entry); - FreeProcessInfo(info); - } - } - Tcl_MutexUnlock(&infoTablesMutex); + /* + * Purge all terminated processes. + */ + + Tcl_MutexLock(&infoTablesMutex); + for (entry = Tcl_FirstHashEntry(&infoTablePerResolvedPid, &search); + entry != NULL; entry = Tcl_NextHashEntry(&search)) { + info = (ProcessInfo *) Tcl_GetHashValue(entry); + if (info->purge) { + Tcl_DeleteHashEntry(entry); + entry = Tcl_FindHashEntry(&infoTablePerPid, info->pid); + Tcl_DeleteHashEntry(entry); + FreeProcessInfo(info); + } + } + Tcl_MutexUnlock(&infoTablesMutex); } else { - /* - * Purge only provided processes. - */ - - result = Tcl_ListObjGetElements(interp, objv[1], &numPids, &pidObjs); - if (result != TCL_OK) { - return result; - } - Tcl_MutexLock(&infoTablesMutex); - for (i = 0; i < numPids; i++) { - result = Tcl_GetIntFromObj(interp, pidObjs[i], (int *) &pid); - if (result != TCL_OK) { - Tcl_MutexUnlock(&infoTablesMutex); - return result; - } - - entry = Tcl_FindHashEntry(&infoTablePerResolvedPid, INT2PTR(pid)); - if (!entry) { - /* - * Skip unknown process. - */ - - continue; - } - - info = (ProcessInfo *) Tcl_GetHashValue(entry); - if (info->purge) { - Tcl_DeleteHashEntry(entry); - entry = Tcl_FindHashEntry(&infoTablePerPid, info->pid); - Tcl_DeleteHashEntry(entry); - FreeProcessInfo(info); - } - } - Tcl_MutexUnlock(&infoTablesMutex); + /* + * Purge only provided processes. + */ + + result = Tcl_ListObjGetElements(interp, objv[1], &numPids, &pidObjs); + if (result != TCL_OK) { + return result; + } + Tcl_MutexLock(&infoTablesMutex); + for (i = 0; i < numPids; i++) { + result = Tcl_GetIntFromObj(interp, pidObjs[i], (int *) &pid); + if (result != TCL_OK) { + Tcl_MutexUnlock(&infoTablesMutex); + return result; + } + + entry = Tcl_FindHashEntry(&infoTablePerResolvedPid, INT2PTR(pid)); + if (!entry) { + /* + * Skip unknown process. + */ + + continue; + } + + info = (ProcessInfo *) Tcl_GetHashValue(entry); + if (info->purge) { + Tcl_DeleteHashEntry(entry); + entry = Tcl_FindHashEntry(&infoTablePerPid, info->pid); + Tcl_DeleteHashEntry(entry); + FreeProcessInfo(info); + } + } + Tcl_MutexUnlock(&infoTablesMutex); } - + return TCL_OK; } @@ -588,7 +688,7 @@ ProcessPurgeObjCmd( * ProcessAutopurgeObjCmd -- * * This function implements the 'tcl::process autopurge' Tcl command. - * Refer to the user documentation for details on what it does. + * Refer to the user documentation for details on what it does. * * Results: * Returns a standard Tcl result. @@ -612,17 +712,17 @@ ProcessAutopurgeObjCmd( } if (objc == 2) { - /* - * Set given value. - */ - - int flag; - int result = Tcl_GetBooleanFromObj(interp, objv[1], &flag); - if (result != TCL_OK) { - return result; - } - - autopurge = !!flag; + /* + * Set given value. + */ + + int flag; + int result = Tcl_GetBooleanFromObj(interp, objv[1], &flag); + if (result != TCL_OK) { + return result; + } + + autopurge = !!flag; } /* @@ -655,11 +755,11 @@ TclInitProcessCmd( Tcl_Interp *interp) /* Current interpreter. */ { static const EnsembleImplMap processImplMap[] = { - {"list", ProcessListObjCmd, TclCompileBasic0ArgCmd, NULL, NULL, 1}, - {"status", ProcessStatusObjCmd, TclCompileBasicMin0ArgCmd, NULL, NULL, 1}, - {"purge", ProcessPurgeObjCmd, TclCompileBasic0Or1ArgCmd, NULL, NULL, 1}, - {"autopurge", ProcessAutopurgeObjCmd, TclCompileBasic0Or1ArgCmd, NULL, NULL, 1}, - {NULL, NULL, NULL, NULL, NULL, 0} + {"list", ProcessListObjCmd, TclCompileBasic0ArgCmd, NULL, NULL, 1}, + {"status", ProcessStatusObjCmd, TclCompileBasicMin0ArgCmd, NULL, NULL, 1}, + {"purge", ProcessPurgeObjCmd, TclCompileBasic0Or1ArgCmd, NULL, NULL, 1}, + {"autopurge", ProcessAutopurgeObjCmd, TclCompileBasic0Or1ArgCmd, NULL, NULL, 1}, + {NULL, NULL, NULL, NULL, NULL, 0} }; Tcl_Command processCmd; @@ -672,20 +772,35 @@ TclInitProcessCmd( } Tcl_MutexUnlock(&infoTablesMutex); } - + processCmd = TclMakeEnsemble(interp, "::tcl::process", processImplMap); Tcl_Export(interp, Tcl_FindNamespace(interp, "::tcl", NULL, 0), - "process", 0); + "process", 0); return processCmd; } -/* FRED TODO */ +/* + *---------------------------------------------------------------------- + * + * TclProcessCreated -- + * + * Called when a child process has been created by Tcl. + * + * Results: + * None. + * + * Side effects: + * Internal structures are updated with a new ProcessInfo. + * + *---------------------------------------------------------------------- + */ + void TclProcessCreated( - Tcl_Pid pid) + Tcl_Pid pid) /* Process id. */ { int resolvedPid; - Tcl_HashEntry *entry; + Tcl_HashEntry *entry, *entry2; int isNew; ProcessInfo *info; @@ -694,7 +809,7 @@ TclProcessCreated( */ resolvedPid = TclpGetPid(pid); - + Tcl_MutexLock(&infoTablesMutex); /* @@ -703,12 +818,15 @@ TclProcessCreated( entry = Tcl_CreateHashEntry(&infoTablePerPid, pid, &isNew); if (!isNew) { - /* - * Pid was reused, free old info and reuse structure. - */ - - info = (ProcessInfo *) Tcl_GetHashValue(entry); - FreeProcessInfo(info); + /* + * Pid was reused, free old info and reuse structure. + */ + + info = (ProcessInfo *) Tcl_GetHashValue(entry); + entry2 = Tcl_FindHashEntry(&infoTablePerResolvedPid, + INT2PTR(resolvedPid)); + if (entry2) Tcl_DeleteHashEntry(entry2); + FreeProcessInfo(info); } /* @@ -717,32 +835,53 @@ TclProcessCreated( info = (ProcessInfo *) ckalloc(sizeof(ProcessInfo)); InitProcessInfo(info, pid, resolvedPid); - + /* * Add entry to tables. */ Tcl_SetHashValue(entry, info); entry = Tcl_CreateHashEntry(&infoTablePerResolvedPid, INT2PTR(resolvedPid), - &isNew); + &isNew); Tcl_SetHashValue(entry, info); - + Tcl_MutexUnlock(&infoTablesMutex); } +/* + *---------------------------------------------------------------------- + * + * TclProcessWait -- + * + * Wait for process status to change. + * + * Results: + * TclProcessWaitStatus enum value. + * + * Side effects: + * Completed process info structures are purged immediately (autopurge on) + * or eventually (autopurge off). + * + *---------------------------------------------------------------------- + */ -/* FRED TODO */ TclProcessWaitStatus TclProcessWait( - Tcl_Pid pid, - int options, - int *codePtr, - Tcl_Obj **msgObjPtr, - Tcl_Obj **errorObjPtr) + Tcl_Pid pid, /* Process id. */ + int options, /* Options passed to WaitProcessStatus. */ + int *codePtr, /* If non-NULL, will receive either: + * - 0 for normal exit. + * - errno in case of error. + * - non-zero exit code for abormal exit. + * - signal number if killed or suspended. + * - Tcl_WaitPid status in all other cases. + */ + Tcl_Obj **msgObjPtr, /* If non-NULL, will receive error message. */ + Tcl_Obj **errorObjPtr) /* If non-NULL, will receive error code. */ { Tcl_HashEntry *entry; ProcessInfo *info; - int result; + TclProcessWaitStatus result; /* * First search for pid in table. @@ -750,34 +889,34 @@ TclProcessWait( entry = Tcl_FindHashEntry(&infoTablePerPid, pid); if (!entry) { - /* - * Unknown process, just call WaitProcessStatus and return. - */ - - result = WaitProcessStatus(pid, TclpGetPid(pid), options, codePtr, - msgObjPtr, errorObjPtr); - if (msgObjPtr && *msgObjPtr) Tcl_IncrRefCount(*msgObjPtr); - if (errorObjPtr && *errorObjPtr) Tcl_IncrRefCount(*errorObjPtr); - return result; + /* + * Unknown process, just call WaitProcessStatus and return. + */ + + result = WaitProcessStatus(pid, TclpGetPid(pid), options, codePtr, + msgObjPtr, errorObjPtr); + if (msgObjPtr && *msgObjPtr) Tcl_IncrRefCount(*msgObjPtr); + if (errorObjPtr && *errorObjPtr) Tcl_IncrRefCount(*errorObjPtr); + return result; } info = (ProcessInfo *) Tcl_GetHashValue(entry); if (info->purge) { - /* - * Process has completed but TclProcessWait has already been called, - * so report no change. - */ - - return TCL_PROCESS_UNCHANGED; + /* + * Process has completed but TclProcessWait has already been called, + * so report no change. + */ + + return TCL_PROCESS_UNCHANGED; } RefreshProcessInfo(info, options); if (info->status == TCL_PROCESS_UNCHANGED) { - /* - * No change, stop there. - */ - - return TCL_PROCESS_UNCHANGED; + /* + * No change, stop there. + */ + + return TCL_PROCESS_UNCHANGED; } /* @@ -792,22 +931,22 @@ TclProcessWait( if (errorObjPtr && *errorObjPtr) Tcl_IncrRefCount(*errorObjPtr); if (autopurge) { - /* - * Purge now. - */ - - Tcl_DeleteHashEntry(entry); - entry = Tcl_FindHashEntry(&infoTablePerResolvedPid, - INT2PTR(info->resolvedPid)); - Tcl_DeleteHashEntry(entry); - FreeProcessInfo(info); + /* + * Purge now. + */ + + Tcl_DeleteHashEntry(entry); + entry = Tcl_FindHashEntry(&infoTablePerResolvedPid, + INT2PTR(info->resolvedPid)); + Tcl_DeleteHashEntry(entry); + FreeProcessInfo(info); } else { - /* - * Eventually purge. Subsequent calls will return - * TCL_PROCESS_UNCHANGED. - */ + /* + * Eventually purge. Subsequent calls will return + * TCL_PROCESS_UNCHANGED. + */ - info->purge = 1; + info->purge = 1; } return result; } -- cgit v0.12 From 6fff25ecbcc670141c504a6dd0555d01204f761e Mon Sep 17 00:00:00 2001 From: "f.bonnet" Date: Sun, 5 Nov 2017 16:41:11 +0000 Subject: Fixed stupid Tcl_DecrRefCount bug in TclCleanupChildren with normally terminated processes. --- generic/tclPipe.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/generic/tclPipe.c b/generic/tclPipe.c index bc760b6..13f4539 100644 --- a/generic/tclPipe.c +++ b/generic/tclPipe.c @@ -313,9 +313,9 @@ TclCleanupChildren( Tcl_SetObjErrorCode(interp, error); Tcl_SetObjResult(interp, msg); } + Tcl_DecrRefCount(error); + Tcl_DecrRefCount(msg); } - Tcl_DecrRefCount(error); - Tcl_DecrRefCount(msg); } /* -- cgit v0.12 From 0f6d3fd95989e7b5c22a40bbdc90631e3ae10bc1 Mon Sep 17 00:00:00 2001 From: pspjuth Date: Thu, 28 Dec 2017 23:54:57 +0000 Subject: Optimise lrange for unshared object. --- generic/tclExecute.c | 13 +++++++ tests/lrange.test | 102 +++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 115 insertions(+) diff --git a/generic/tclExecute.c b/generic/tclExecute.c index f2cda0c..0f501b9 100644 --- a/generic/tclExecute.c +++ b/generic/tclExecute.c @@ -5140,12 +5140,25 @@ TEBCresume( if (toIdx >= objc) { toIdx = objc-1; } + + /* + * If we are just removing the beginning or the end from an + * unshared object, Tcl_ListObjReplace is very efficient, and also + * guarantees a pure list. + */ + if (fromIdx == 0 && toIdx != objc-1 && !Tcl_IsShared(valuePtr)) { Tcl_ListObjReplace(interp, valuePtr, toIdx + 1, LIST_MAX, 0, NULL); TRACE_APPEND(("%.30s\n", O2S(valuePtr))); NEXT_INST_F(9, 0, 0); } + if (toIdx == objc-1 && !Tcl_IsShared(valuePtr)) { + Tcl_ListObjReplace(interp, valuePtr, + 0, fromIdx, 0, NULL); + TRACE_APPEND(("%.30s\n", O2S(valuePtr))); + NEXT_INST_F(9, 0, 0); + } objResultPtr = Tcl_NewListObj(toIdx-fromIdx+1, objv+fromIdx); } else { TclNewObj(objResultPtr); diff --git a/tests/lrange.test b/tests/lrange.test index 02b9c65..0b1a7ca 100644 --- a/tests/lrange.test +++ b/tests/lrange.test @@ -90,6 +90,108 @@ test lrange-3.1 {Bug 3588366: end-offsets before start} { lrange $l 0 end-5 }} {1 2 3 4 5} } {} + +test lrange-4.1 {lrange pure promise} -body { + set ll1 [list $tcl_version 2 3 4] + # Shared + set ll2 $ll1 + # With string rep + string length $ll1 + set rep1 [tcl::unsupported::representation $ll1] + # Get new pure object + set x [lrange $ll1 0 end] + set rep2 [tcl::unsupported::representation $x] + regexp {object pointer at (\S+)} $rep1 -> obj1 + regexp {object pointer at (\S+)} $rep2 -> obj2 + list $rep1 $rep2 [string equal $obj1 $obj2] + # Check for a new clean object +} -match glob -result {*value is *refcount of 3,*, string rep*value is*refcount of 2,* no string rep* 0} + +test lrange-4.2 {lrange pure promise} -body { + set ll1 [list $tcl_version 2 3 4] + # Shared + set ll2 $ll1 + # With string rep + string length $ll1 + set rep1 [tcl::unsupported::representation $ll1] + # Get new pure object, not compiled + set x [[string cat l range] $ll1 0 end] + set rep2 [tcl::unsupported::representation $x] + regexp {object pointer at (\S+)} $rep1 -> obj1 + regexp {object pointer at (\S+)} $rep2 -> obj2 + list $rep1 $rep2 [string equal $obj1 $obj2] + # Check for a new clean object +} -match glob -result {*value is *refcount of 3,*, string rep*value is*refcount of 2,* no string rep* 0} + +test lrange-4.3 {lrange pure promise} -body { + set ll1 [list $tcl_version 2 3 4] + # With string rep + string length $ll1 + set rep1 [tcl::unsupported::representation $ll1] + # Get pure object, unshared + set ll2 [lrange $ll1[set ll1 {}] 0 end] + set rep2 [tcl::unsupported::representation $ll2] + regexp {object pointer at (\S+)} $rep1 -> obj1 + regexp {object pointer at (\S+)} $rep2 -> obj2 + list $rep1 $rep2 [string equal $obj1 $obj2] + # Internal optimisations should keep the same object +} -match glob -result {*value is *refcount of 2,*, string rep*value is*refcount of 2,* no string rep* 1} + +test lrange-4.4 {lrange pure promise} -body { + set ll1 [list $tcl_version 2 3 4] + # With string rep + string length $ll1 + set rep1 [tcl::unsupported::representation $ll1] + # Get pure object, unshared, not compiled + set ll2 [[string cat l range] $ll1[set ll1 {}] 0 end] + set rep2 [tcl::unsupported::representation $ll2] + regexp {object pointer at (\S+)} $rep1 -> obj1 + regexp {object pointer at (\S+)} $rep2 -> obj2 + list $rep1 $rep2 [string equal $obj1 $obj2] + # Internal optimisations should keep the same object +} -match glob -result {*value is *refcount of 2,*, string rep*value is*refcount of 2,* no string rep* 1} + +# Testing for compiled vs non-compiled behaviour, and shared vs non-shared. +# Far too many variations to check with spelt-out tests. +# Note that this *just* checks whether the different versions are the same +# not whether any of them is correct. +apply {{} { + set lss {{} {a} {a b c} {a b c d}} + set idxs {-2 -1 0 1 2 3 end-3 end-2 end-1 end end+1 end+2} + set lrange lrange + + foreach ls $lss { + foreach a $idxs { + foreach b $idxs { + # Shared, uncompiled + set ls2 $ls + set expected [list [catch {$lrange $ls $a $b} m] $m] + # Shared, compiled + set tester [list lrange $ls $a $b] + set script [list catch $tester m] + set script "list \[$script\] \$m" + test lrange-5.[incr n].1 {lrange shared compiled} \ + [list apply [list {} $script]] $expected + # Unshared, uncompiled + set tester [string map [list %l [list $ls] %a $a %b $b] { + [string cat l range] [lrange %l 0 end] %a %b + }] + set script [list catch $tester m] + set script "list \[$script\] \$m" + test lrange-5.$n.2 {lrange unshared uncompiled} \ + [list apply [list {} $script]] $expected + # Unshared, compiled + set tester [string map [list %l [list $ls] %a $a %b $b] { + lrange [lrange %l 0 end] %a %b + }] + set script [list catch $tester m] + set script "list \[$script\] \$m" + test lrange-5.$n.3 {lrange unshared compiled} \ + [list apply [list {} $script]] $expected + } + } + } +}} # cleanup ::tcltest::cleanupTests -- cgit v0.12 From 651697f7cd746dded1a031d4217376000a176037 Mon Sep 17 00:00:00 2001 From: pspjuth Date: Fri, 29 Dec 2017 18:58:01 +0000 Subject: Refactored lrange to common function. --- generic/tclCmdIL.c | 44 +--------------------------- generic/tclExecute.c | 40 ++------------------------ generic/tclInt.h | 2 ++ generic/tclListObj.c | 81 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 87 insertions(+), 80 deletions(-) diff --git a/generic/tclCmdIL.c b/generic/tclCmdIL.c index b41d312..001b62d 100644 --- a/generic/tclCmdIL.c +++ b/generic/tclCmdIL.c @@ -2543,7 +2543,6 @@ Tcl_LrangeObjCmd( register Tcl_Obj *const objv[]) /* Argument objects. */ { - Tcl_Obj **elemPtrs; int listLen, first, last, result; if (objc != 4) { @@ -2561,55 +2560,14 @@ Tcl_LrangeObjCmd( if (result != TCL_OK) { return result; } - if (first < 0) { - first = 0; - } result = TclGetIntForIndexM(interp, objv[3], /*endValue*/ listLen - 1, &last); if (result != TCL_OK) { return result; } - if (last >= listLen) { - last = listLen - 1; - } - - if (first > last) { - /* - * Returning an empty list is easy. - */ - - return TCL_OK; - } - - result = TclListObjGetElements(interp, objv[1], &listLen, &elemPtrs); - if (result != TCL_OK) { - return result; - } - - if (Tcl_IsShared(objv[1]) || - ((ListRepPtr(objv[1])->refCount > 1))) { - Tcl_SetObjResult(interp, Tcl_NewListObj(last - first + 1, - &elemPtrs[first])); - } else { - /* - * In-place is possible. - */ - - if (last < (listLen - 1)) { - Tcl_ListObjReplace(interp, objv[1], last + 1, listLen - 1 - last, - 0, NULL); - } - - /* - * This one is not conditioned on (first > 0) in order to preserve the - * string-canonizing effect of [lrange 0 end]. - */ - - Tcl_ListObjReplace(interp, objv[1], 0, first, 0, NULL); - Tcl_SetObjResult(interp, objv[1]); - } + Tcl_SetObjResult(interp, TclListObjRange(objv[1], first, last)); return TCL_OK; } diff --git a/generic/tclExecute.c b/generic/tclExecute.c index 0f501b9..8568642 100644 --- a/generic/tclExecute.c +++ b/generic/tclExecute.c @@ -5087,11 +5087,11 @@ TEBCresume( TclGetInt4AtPtr(pc+5))); /* - * Get the contents of the list, making sure that it really is a list + * Get the length of the list, making sure that it really is a list * in the process. */ - if (TclListObjGetElements(interp, valuePtr, &objc, &objv) != TCL_OK) { + if (TclListObjLength(interp, valuePtr, &objc) != TCL_OK) { TRACE_ERROR(interp); goto gotError; } @@ -5128,41 +5128,7 @@ TEBCresume( toIdx = objc; } - /* - * Check if we are referring to a valid, non-empty list range, and if - * so, build the list of elements in that range. - */ - - if (fromIdx<=toIdx && fromIdx=0) { - if (fromIdx < 0) { - fromIdx = 0; - } - if (toIdx >= objc) { - toIdx = objc-1; - } - - /* - * If we are just removing the beginning or the end from an - * unshared object, Tcl_ListObjReplace is very efficient, and also - * guarantees a pure list. - */ - - if (fromIdx == 0 && toIdx != objc-1 && !Tcl_IsShared(valuePtr)) { - Tcl_ListObjReplace(interp, valuePtr, - toIdx + 1, LIST_MAX, 0, NULL); - TRACE_APPEND(("%.30s\n", O2S(valuePtr))); - NEXT_INST_F(9, 0, 0); - } - if (toIdx == objc-1 && !Tcl_IsShared(valuePtr)) { - Tcl_ListObjReplace(interp, valuePtr, - 0, fromIdx, 0, NULL); - TRACE_APPEND(("%.30s\n", O2S(valuePtr))); - NEXT_INST_F(9, 0, 0); - } - objResultPtr = Tcl_NewListObj(toIdx-fromIdx+1, objv+fromIdx); - } else { - TclNewObj(objResultPtr); - } + objResultPtr = TclListObjRange(valuePtr, fromIdx, toIdx); TRACE_APPEND(("\"%.30s\"", O2S(objResultPtr))); NEXT_INST_F(9, 1, 1); diff --git a/generic/tclInt.h b/generic/tclInt.h index 2ba0493..8322095 100644 --- a/generic/tclInt.h +++ b/generic/tclInt.h @@ -3069,6 +3069,8 @@ MODULE_SCOPE Tcl_Obj * TclLindexFlat(Tcl_Interp *interp, Tcl_Obj *listPtr, MODULE_SCOPE void TclListLines(Tcl_Obj *listObj, int line, int n, int *lines, Tcl_Obj *const *elems); MODULE_SCOPE Tcl_Obj * TclListObjCopy(Tcl_Interp *interp, Tcl_Obj *listPtr); +MODULE_SCOPE Tcl_Obj * TclListObjRange(Tcl_Obj *listPtr, int fromIdx, + int toIdx); MODULE_SCOPE Tcl_Obj * TclLsetList(Tcl_Interp *interp, Tcl_Obj *listPtr, Tcl_Obj *indexPtr, Tcl_Obj *valuePtr); MODULE_SCOPE Tcl_Obj * TclLsetFlat(Tcl_Interp *interp, Tcl_Obj *listPtr, diff --git a/generic/tclListObj.c b/generic/tclListObj.c index 43d90ab..c4dafba 100644 --- a/generic/tclListObj.c +++ b/generic/tclListObj.c @@ -423,6 +423,87 @@ TclListObjCopy( /* *---------------------------------------------------------------------- * + * TclListObjRange -- + * + * Makes a slice of a list value. + * *listPtr must be known to be a valid list. + * + * Results: + * Returns a pointer to the sliced list. + * This may be a new object or the same object if not shared. + * + * Side effects: + * The possible conversion of the object referenced by listPtr + * to a list object. + * + *---------------------------------------------------------------------- + */ + +Tcl_Obj * +TclListObjRange( + Tcl_Obj *listPtr, /* List object to take a range from. */ + int fromIdx, /* Index of first element to include. */ + int toIdx) /* Index of last element to include. */ +{ + Tcl_Obj **elemPtrs; + int listLen, i, newLen; + List *listRepPtr; + + TclListObjGetElements(NULL, listPtr, &listLen, &elemPtrs); + + if (fromIdx < 0) { + fromIdx = 0; + } + if (toIdx >= listLen) { + toIdx = listLen-1; + } + if (fromIdx > toIdx) { + return Tcl_NewObj(); + } + + newLen = toIdx - fromIdx + 1; + + if (Tcl_IsShared(listPtr) || + ((ListRepPtr(listPtr)->refCount > 1))) { + return Tcl_NewListObj(newLen, &elemPtrs[fromIdx]); + } + + /* + * In-place is possible. + */ + + /* + * Even if nothing below cause any changes, we still want the + * string-canonizing effect of [lrange 0 end]. + */ + + TclInvalidateStringRep(listPtr); + + /* + * Delete elements that should not be included. + */ + + for (i = 0; i < fromIdx; i++) { + TclDecrRefCount(elemPtrs[i]); + } + for (i = toIdx + 1; i < listLen; i++) { + TclDecrRefCount(elemPtrs[i]); + } + + if (fromIdx > 0) { + memmove(elemPtrs, &elemPtrs[fromIdx], + (size_t) newLen * sizeof(Tcl_Obj*)); + } + + listRepPtr = ListRepPtr(listPtr); + listRepPtr->elemCount = newLen; + + return listPtr; +} + +/* + *---------------------------------------------------------------------- + * * Tcl_ListObjGetElements -- * * This function returns an (objc,objv) array of the elements in a list -- cgit v0.12 From 54590627ee18ff872a23f3a37227324aed8d1fd8 Mon Sep 17 00:00:00 2001 From: pspjuth Date: Tue, 2 Jan 2018 22:03:02 +0000 Subject: Add -stride to lsearch. TIP#351 --- generic/tclCmdIL.c | 187 +++++++++++++++++++++++++++++++++++++++-------------- tests/lsearch.test | 158 +++++++++++++++++++++++++++++++++++++++++--- 2 files changed, 287 insertions(+), 58 deletions(-) diff --git a/generic/tclCmdIL.c b/generic/tclCmdIL.c index b41d312..c514f84 100644 --- a/generic/tclCmdIL.c +++ b/generic/tclCmdIL.c @@ -2939,7 +2939,8 @@ Tcl_LsearchObjCmd( { const char *bytes, *patternBytes; int i, match, index, result, listc, length, elemLen, bisect; - int dataType, isIncreasing, lower, upper, offset; + int allocatedIndexVector = 0; + int dataType, isIncreasing, lower, upper, start, groupSize, groupOffset; Tcl_WideInt patWide, objWide; int allMatches, inlineReturn, negatedMatch, returnSubindices, noCase; double patDouble, objDouble; @@ -2951,7 +2952,7 @@ Tcl_LsearchObjCmd( "-all", "-ascii", "-bisect", "-decreasing", "-dictionary", "-exact", "-glob", "-increasing", "-index", "-inline", "-integer", "-nocase", "-not", - "-real", "-regexp", "-sorted", "-start", + "-real", "-regexp", "-sorted", "-start", "-stride", "-subindices", NULL }; enum options { @@ -2959,7 +2960,7 @@ Tcl_LsearchObjCmd( LSEARCH_DICTIONARY, LSEARCH_EXACT, LSEARCH_GLOB, LSEARCH_INCREASING, LSEARCH_INDEX, LSEARCH_INLINE, LSEARCH_INTEGER, LSEARCH_NOCASE, LSEARCH_NOT, LSEARCH_REAL, LSEARCH_REGEXP, LSEARCH_SORTED, - LSEARCH_START, LSEARCH_SUBINDICES + LSEARCH_START, LSEARCH_STRIDE, LSEARCH_SUBINDICES }; enum datatypes { ASCII, DICTIONARY, INTEGER, REAL @@ -2979,7 +2980,9 @@ Tcl_LsearchObjCmd( bisect = 0; listPtr = NULL; startPtr = NULL; - offset = 0; + groupSize = 1; + groupOffset = 0; + start = 0; noCase = 0; sortInfo.compareCmdPtr = NULL; sortInfo.isIncreasing = 1; @@ -2997,9 +3000,6 @@ Tcl_LsearchObjCmd( for (i = 1; i < objc-2; i++) { if (Tcl_GetIndexFromObj(interp, objv[i], options, "option", 0, &index) != TCL_OK) { - if (startPtr != NULL) { - Tcl_DecrRefCount(startPtr); - } result = TCL_ERROR; goto done; } @@ -3064,6 +3064,7 @@ Tcl_LsearchObjCmd( if (startPtr != NULL) { Tcl_DecrRefCount(startPtr); + startPtr = NULL; } if (i > objc-4) { Tcl_SetObjResult(interp, Tcl_NewStringObj( @@ -3084,25 +3085,47 @@ Tcl_LsearchObjCmd( startPtr = Tcl_DuplicateObj(objv[i]); } else { startPtr = objv[i]; - Tcl_IncrRefCount(startPtr); } + Tcl_IncrRefCount(startPtr); + break; + case LSEARCH_STRIDE: /* -stride */ + if (i > objc-4) { + Tcl_SetObjResult(interp, Tcl_NewStringObj( + "\"-stride\" option must be " + "followed by stride length", -1)); + Tcl_SetErrorCode(interp, "TCL", "ARGUMENT", "MISSING", NULL); + result = TCL_ERROR; + goto done; + } + if (Tcl_GetIntFromObj(interp, objv[i+1], &groupSize) != TCL_OK) { + result = TCL_ERROR; + goto done; + } + if (groupSize < 2) { + Tcl_SetObjResult(interp, Tcl_NewStringObj( + "stride length must be at least 2", -1)); + Tcl_SetErrorCode(interp, "TCL", "OPERATION", "LSORT", + "BADSTRIDE", NULL); + result = TCL_ERROR; + goto done; + } + i++; break; case LSEARCH_INDEX: { /* -index */ Tcl_Obj **indices; int j; - if (sortInfo.indexc > 1) { + if (allocatedIndexVector) { TclStackFree(interp, sortInfo.indexv); + allocatedIndexVector = 0; } if (i > objc-4) { - if (startPtr != NULL) { - Tcl_DecrRefCount(startPtr); - } Tcl_SetObjResult(interp, Tcl_NewStringObj( "\"-index\" option must be followed by list index", -1)); Tcl_SetErrorCode(interp, "TCL", "ARGUMENT", "MISSING", NULL); - return TCL_ERROR; + result = TCL_ERROR; + goto done; } /* @@ -3114,10 +3137,8 @@ Tcl_LsearchObjCmd( i++; if (TclListObjGetElements(interp, objv[i], &sortInfo.indexc, &indices) != TCL_OK) { - if (startPtr != NULL) { - Tcl_DecrRefCount(startPtr); - } - return TCL_ERROR; + result = TCL_ERROR; + goto done; } switch (sortInfo.indexc) { case 0: @@ -3129,6 +3150,8 @@ Tcl_LsearchObjCmd( default: sortInfo.indexv = TclStackAlloc(interp, sizeof(int) * sortInfo.indexc); + allocatedIndexVector = 1; /* Cannot use indexc field, as it + * might be decreased by 1 later. */ } /* @@ -3156,14 +3179,12 @@ Tcl_LsearchObjCmd( */ if (returnSubindices && sortInfo.indexc==0) { - if (startPtr != NULL) { - Tcl_DecrRefCount(startPtr); - } Tcl_SetObjResult(interp, Tcl_NewStringObj( "-subindices cannot be used without -index option", -1)); Tcl_SetErrorCode(interp, "TCL", "OPERATION", "LSEARCH", "BAD_OPTION_MIX", NULL); - return TCL_ERROR; + result = TCL_ERROR; + goto done; } if (bisect && (allMatches || negatedMatch)) { @@ -3171,7 +3192,8 @@ Tcl_LsearchObjCmd( "-bisect is not compatible with -all or -not", -1)); Tcl_SetErrorCode(interp, "TCL", "OPERATION", "LSEARCH", "BAD_OPTION_MIX", NULL); - return TCL_ERROR; + result = TCL_ERROR; + goto done; } if (mode == REGEXP) { @@ -3197,9 +3219,6 @@ Tcl_LsearchObjCmd( } if (regexp == NULL) { - if (startPtr != NULL) { - Tcl_DecrRefCount(startPtr); - } result = TCL_ERROR; goto done; } @@ -3212,24 +3231,67 @@ Tcl_LsearchObjCmd( result = TclListObjGetElements(interp, objv[objc - 2], &listc, &listv); if (result != TCL_OK) { - if (startPtr != NULL) { - Tcl_DecrRefCount(startPtr); - } goto done; } /* + * Check for sanity when grouping elements of the overall list together + * because of the -stride option. [TIP #351] + */ + + if (groupSize > 1) { + if (listc % groupSize) { + Tcl_SetObjResult(interp, Tcl_NewStringObj( + "list size must be a multiple of the stride length", + -1)); + Tcl_SetErrorCode(interp, "TCL", "OPERATION", "LSEARCH", "BADSTRIDE", + NULL); + result = TCL_ERROR; + goto done; + } + if (sortInfo.indexc > 0) { + /* + * Use the first value in the list supplied to -index as the + * offset of the element within each group by which to sort. + */ + + groupOffset = sortInfo.indexv[0]; + if (groupOffset <= SORTIDX_END) { + groupOffset = (groupOffset - SORTIDX_END) + groupSize - 1; + } + if (groupOffset < 0 || groupOffset >= groupSize) { + Tcl_SetObjResult(interp, Tcl_NewStringObj( + "when used with \"-stride\", the leading \"-index\"" + " value must be within the group", -1)); + Tcl_SetErrorCode(interp, "TCL", "OPERATION", "LSEARCH", + "BADINDEX", NULL); + result = TCL_ERROR; + goto done; + } + if (sortInfo.indexc == 1) { + sortInfo.indexc = 0; + sortInfo.indexv = NULL; + } else { + sortInfo.indexc--; + + for (i = 0; i < sortInfo.indexc; i++) { + sortInfo.indexv[i] = sortInfo.indexv[i+1]; + } + } + } + } + + /* * Get the user-specified start offset. */ if (startPtr) { - result = TclGetIntForIndexM(interp, startPtr, listc-1, &offset); - Tcl_DecrRefCount(startPtr); + result = TclGetIntForIndexM(interp, startPtr, listc-1, &start); if (result != TCL_OK) { goto done; } - if (offset < 0) { - offset = 0; + if (start < 0) { + start = 0; } /* @@ -3237,16 +3299,21 @@ Tcl_LsearchObjCmd( * "did not match anything at all" result straight away. [Bug 1374778] */ - if (offset > listc-1) { - if (sortInfo.indexc > 1) { - TclStackFree(interp, sortInfo.indexv); - } + if (start > listc-1) { if (allMatches || inlineReturn) { Tcl_ResetResult(interp); } else { Tcl_SetObjResult(interp, Tcl_NewIntObj(-1)); } - return TCL_OK; + goto done; + } + + /* + * If start points within a group, it points to the start of the group. + */ + + if (groupSize > 1) { + start -= (start % groupSize); } } @@ -3305,18 +3372,23 @@ Tcl_LsearchObjCmd( * sense in doing this when the match sense is inverted. */ - lower = offset - 1; + /* + * With -stride, lower, upper and i are kept as multiples of groupSize. + */ + + lower = start - groupSize; upper = listc; - while (lower + 1 != upper && sortInfo.resultCode == TCL_OK) { + while (lower + groupSize != upper && sortInfo.resultCode == TCL_OK) { i = (lower + upper)/2; + i -= i % groupSize; if (sortInfo.indexc != 0) { - itemPtr = SelectObjFromSublist(listv[i], &sortInfo); + itemPtr = SelectObjFromSublist(listv[i+groupOffset], &sortInfo); if (sortInfo.resultCode != TCL_OK) { result = sortInfo.resultCode; goto done; } } else { - itemPtr = listv[i]; + itemPtr = listv[i+groupOffset]; } switch ((enum datatypes) dataType) { case ASCII: @@ -3405,10 +3477,10 @@ Tcl_LsearchObjCmd( if (allMatches) { listPtr = Tcl_NewListObj(0, NULL); } - for (i = offset; i < listc; i++) { + for (i = start; i < listc; i += groupSize) { match = 0; if (sortInfo.indexc != 0) { - itemPtr = SelectObjFromSublist(listv[i], &sortInfo); + itemPtr = SelectObjFromSublist(listv[i+groupOffset], &sortInfo); if (sortInfo.resultCode != TCL_OK) { if (listPtr != NULL) { Tcl_DecrRefCount(listPtr); @@ -3417,7 +3489,7 @@ Tcl_LsearchObjCmd( goto done; } } else { - itemPtr = listv[i]; + itemPtr = listv[i+groupOffset]; } switch (mode) { @@ -3507,15 +3579,20 @@ Tcl_LsearchObjCmd( */ if (returnSubindices && (sortInfo.indexc != 0)) { - itemPtr = SelectObjFromSublist(listv[i], &sortInfo); + itemPtr = SelectObjFromSublist(listv[i+groupOffset], + &sortInfo); + Tcl_ListObjAppendElement(interp, listPtr, itemPtr); + } else if (groupSize > 1) { + Tcl_ListObjReplace(interp, listPtr, LIST_MAX, 0, + groupSize, &listv[i]); } else { itemPtr = listv[i]; + Tcl_ListObjAppendElement(interp, listPtr, itemPtr); } - Tcl_ListObjAppendElement(interp, listPtr, itemPtr); } else if (returnSubindices) { int j; - itemPtr = Tcl_NewIntObj(i); + itemPtr = Tcl_NewIntObj(i+groupOffset); for (j=0 ; j 1) { + Tcl_SetObjResult(interp, Tcl_NewListObj(groupSize, &listv[index])); + } else { + Tcl_SetObjResult(interp, listv[index]); + } } result = TCL_OK; @@ -3563,7 +3647,10 @@ Tcl_LsearchObjCmd( */ done: - if (sortInfo.indexc > 1) { + if (startPtr != NULL) { + Tcl_DecrRefCount(startPtr); + } + if (allocatedIndexVector) { TclStackFree(interp, sortInfo.indexv); } return result; diff --git a/tests/lsearch.test b/tests/lsearch.test index b2c1812..4e4b206 100644 --- a/tests/lsearch.test +++ b/tests/lsearch.test @@ -59,7 +59,7 @@ test lsearch-2.9 {search modes} { } 1 test lsearch-2.10 {search modes} -returnCodes error -body { lsearch -glib {b.x bx xy bcx} b.x -} -result {bad option "-glib": must be -all, -ascii, -bisect, -decreasing, -dictionary, -exact, -glob, -increasing, -index, -inline, -integer, -nocase, -not, -real, -regexp, -sorted, -start, or -subindices} +} -result {bad option "-glib": must be -all, -ascii, -bisect, -decreasing, -dictionary, -exact, -glob, -increasing, -index, -inline, -integer, -nocase, -not, -real, -regexp, -sorted, -start, -stride, or -subindices} test lsearch-2.11 {search modes with -nocase} { lsearch -exact -nocase {a b c A B C} A } 0 @@ -87,10 +87,10 @@ test lsearch-3.2 {lsearch errors} -returnCodes error -body { } -result {wrong # args: should be "lsearch ?-option value ...? list pattern"} test lsearch-3.3 {lsearch errors} -returnCodes error -body { lsearch a b c -} -result {bad option "a": must be -all, -ascii, -bisect, -decreasing, -dictionary, -exact, -glob, -increasing, -index, -inline, -integer, -nocase, -not, -real, -regexp, -sorted, -start, or -subindices} +} -result {bad option "a": must be -all, -ascii, -bisect, -decreasing, -dictionary, -exact, -glob, -increasing, -index, -inline, -integer, -nocase, -not, -real, -regexp, -sorted, -start, -stride, or -subindices} test lsearch-3.4 {lsearch errors} -returnCodes error -body { lsearch a b c d -} -result {bad option "a": must be -all, -ascii, -bisect, -decreasing, -dictionary, -exact, -glob, -increasing, -index, -inline, -integer, -nocase, -not, -real, -regexp, -sorted, -start, or -subindices} +} -result {bad option "a": must be -all, -ascii, -bisect, -decreasing, -dictionary, -exact, -glob, -increasing, -index, -inline, -integer, -nocase, -not, -real, -regexp, -sorted, -start, -stride, or -subindices} test lsearch-3.5 {lsearch errors} -returnCodes error -body { lsearch "\{" b } -result {unmatched open brace in list} @@ -435,21 +435,24 @@ test lsearch-18.5 {lsearch -index option, list as index basic functionality} { lsearch -all -index {0 0} -exact {{{a c} {a b} {d a}} {{a c} {a b} {d a}}} a } {0 1} -test lsearch-19.1 {lsearch -sunindices option} { +test lsearch-19.1 {lsearch -subindices option} { lsearch -subindices -index {0 0} {{{x x} {x b} {a d}} {{a c} {a b} {a a}}} a } {1 0 0} -test lsearch-19.2 {lsearch -sunindices option} { +test lsearch-19.2 {lsearch -subindices option} { lsearch -subindices -index {2 0} -exact {{{x x} {x b} {a d}} {{a c} {a b} {a a}}} a } {0 2 0} -test lsearch-19.3 {lsearch -sunindices option} { +test lsearch-19.3 {lsearch -subindices option} { lsearch -subindices -index {1 1} -glob {{{ab cb} {ab bb} {ab ab}} {{ab cb} {ab bb} {ab ab}}} b* } {0 1 1} -test lsearch-19.4 {lsearch -sunindices option} { +test lsearch-19.4 {lsearch -subindices option} { lsearch -subindices -index {0 1} -regexp {{{ab cb} {ab bb} {ab ab}} {{ab cb} {ab bb} {ab ab}}} {[cb]b} } {0 0 1} -test lsearch-19.5 {lsearch -sunindices option} { +test lsearch-19.5 {lsearch -subindices option} { lsearch -subindices -all -index {0 0} -exact {{{a c} {a b} {d a}} {{a c} {a b} {d a}}} a } {{0 0 0} {1 0 0}} +test lsearch-19.6 {lsearch -subindices option} { + lsearch -subindices -all -index {1 0} -exact {{{a c} {a b} {d a}} {{a c} {a b} {d a}}} a +} {{0 1 0} {1 1 0}} test lsearch-20.1 {lsearch -index option, index larger than sublists} -body { lsearch -index 2 {{a c} {a b} {a a}} a @@ -509,6 +512,145 @@ test lsearch-22.5 {lsearch -bisect, all equal} { test lsearch-22.6 {lsearch -sorted, all equal} { lsearch -sorted -integer {5 5 5 5} 5 } {0} + +test lsearch-23.1 {lsearch -stride option, errors} -body { + lsearch -stride {a b} a +} -returnCodes error -result {"-stride" option must be followed by stride length} +test lsearch-23.2 {lsearch -stride option, errors} -body { + lsearch -stride 0 {a b} a +} -returnCodes error -result {stride length must be at least 2} +test lsearch-23.3 {lsearch -stride option, errors} -body { + lsearch -stride 2 {a b c} a +} -returnCodes error -result {list size must be a multiple of the stride length} +test lsearch-23.4 {lsearch -stride option, errors} -body { + lsearch -stride 5 {a b c} a +} -returnCodes error -result {list size must be a multiple of the stride length} +test lsearch-23.5 {lsearch -stride option, errors} -body { + # Stride equal to length is ok + lsearch -stride 3 {a b c} a +} -result 0 + +test lsearch-24.1 {lsearch -stride option} -body { + lsearch -stride 2 {a b c d e f g h} d +} -result -1 +test lsearch-24.2 {lsearch -stride option} -body { + lsearch -stride 2 {a b c d e f g h} e +} -result 4 +test lsearch-24.3 {lsearch -stride option} -body { + lsearch -stride 3 {a b c d e f g h i} e +} -result -1 +test lsearch-24.4 {lsearch -stride option} -body { + # Result points first in group + lsearch -stride 3 -index 1 {a b c d e f g h i} e +} -result 3 +test lsearch-24.5 {lsearch -stride option} -body { + lsearch -inline -stride 2 {a b c d e f g h} d +} -result {} +test lsearch-24.6 {lsearch -stride option} -body { + # Inline result is a "single element" strided list + lsearch -inline -stride 2 {a b c d e f g h} e +} -result "e f" +test lsearch-24.7 {lsearch -stride option} -body { + lsearch -inline -stride 3 {a b c d e f g h i} e +} -result {} +test lsearch-24.8 {lsearch -stride option} -body { + lsearch -inline -stride 3 -index 1 {a b c d e f g h i} e +} -result "d e f" +test lsearch-24.9 {lsearch -stride option} -body { + lsearch -all -inline -stride 3 -index 1 {a b c d e f g e i} e +} -result "d e f g e i" +test lsearch-24.10 {lsearch -stride option} -body { + lsearch -all -inline -stride 3 -index 0 {a b c d e f a e i} a +} -result "a b c a e i" + +# 25* mimics 19* but with -inline added to -subindices +test lsearch-25.1 {lsearch -subindices option} { + lsearch -inline -subindices -index {0 0} {{{x x} {x b} {a d}} {{a c} {a b} {a a}}} a +} {a} +test lsearch-25.2 {lsearch -subindices option} { + lsearch -inline -subindices -index {2 0} -exact {{{x x} {x b} {a d}} {{a c} {a b} {a a}}} a +} {a} +test lsearch-25.3 {lsearch -subindices option} { + lsearch -inline -subindices -index {1 1} -glob {{{ab cb} {ab bb} {ab ab}} {{ab cb} {ab bb} {ab ab}}} b* +} {bb} +test lsearch-25.4 {lsearch -subindices option} { + lsearch -inline -subindices -index {0 1} -regexp {{{ab cb} {ab bb} {ab ab}} {{ab cb} {ab bb} {ab ab}}} {[cb]b} +} {cb} +test lsearch-25.5 {lsearch -subindices option} { + lsearch -inline -subindices -all -index {0 0} -exact {{{a c} {a b} {d a}} {{a c} {a b} {d a}}} a +} {a a} +test lsearch-25.6 {lsearch -subindices option} { + lsearch -inline -subindices -all -index {1 0} -exact {{{a c} {a b} {d a}} {{a c} {a b} {d a}}} a +} {a a} + +# 26* mimics 19* but with -stride added +test lsearch-26.1 {lsearch -stride + -subindices option} { + lsearch -stride 3 -subindices -index {0 0} {{x x} {x b} {a d} {a c} {a b} {a a}} a +} {3 0} +test lsearch-26.2 {lsearch -stride + -subindices option} { + lsearch -stride 3 -subindices -index {2 0} -exact {{x x} {x b} {a d} {a c} {a b} {a a}} a +} {2 0} +test lsearch-26.3 {lsearch -stride + -subindices option} { + lsearch -stride 3 -subindices -index {1 1} -glob {{ab cb} {ab bb} {ab ab} {ab cb} {ab bb} {ab ab}} b* +} {1 1} +test lsearch-26.4 {lsearch -stride + -subindices option} { + lsearch -stride 3 -subindices -index {0 1} -regexp {{ab cb} {ab bb} {ab ab} {ab cb} {ab bb} {ab ab}} {[cb]b} +} {0 1} +test lsearch-26.5 {lsearch -stride + -subindices option} { + lsearch -stride 3 -subindices -all -index {0 0} -exact {{a c} {a b} {d a} {a c} {a b} {d a}} a +} {{0 0} {3 0}} +test lsearch-26.6 {lsearch -stride + -subindices option} { + lsearch -stride 3 -subindices -all -index {1 0} -exact {{a c} {a b} {d a} {x c} {a b} {d a}} a +} {{1 0} {4 0}} + +# 27* mimics 25* but with -stride added +test lsearch-27.1 {lsearch -stride + -subindices option} { + lsearch -inline -stride 3 -subindices -index {0 0} {{x x} {x b} {a d} {a c} {a b} {a a}} a +} {a} +test lsearch-27.2 {lsearch -stride + -subindices option} { + lsearch -inline -stride 3 -subindices -index {2 0} -exact {{x x} {x b} {a d} {a c} {a b} {a a}} a +} {a} +test lsearch-27.3 {lsearch -stride + -subindices option} { + lsearch -inline -stride 3 -subindices -index {1 1} -glob {{ab cb} {ab bb} {ab ab} {ab cb} {ab bb} {ab ab}} b* +} {bb} +test lsearch-27.4 {lsearch -stride + -subindices option} { + lsearch -inline -stride 3 -subindices -index {0 1} -regexp {{ab cb} {ab bb} {ab ab} {ab cb} {ab bb} {ab ab}} {[cb]b} +} {cb} +test lsearch-27.5 {lsearch -stride + -subindices option} { + lsearch -inline -stride 3 -subindices -all -index {0 0} -exact {{a c} {a b} {d a} {a c} {a b} {d a}} a +} {a a} +test lsearch-27.6 {lsearch -stride + -subindices option} { + lsearch -inline -stride 3 -subindices -all -index {1 0} -exact {{a c} {a b} {d a} {x c} {a b} {d a}} a +} {a a} + +test lsearch-28.1 {lsearch -sorted with -stride} -body { + lsearch -sorted -stride 2 {5 3 7 8 9 2} 5 +} -result 0 +test lsearch-28.2 {lsearch -sorted with -stride} -body { + lsearch -sorted -stride 2 {5 3 7 8 9 2} 3 +} -result -1 +test lsearch-28.3 {lsearch -sorted with -stride} -body { + lsearch -sorted -stride 2 {5 3 7 8 9 2} 7 +} -result 2 +test lsearch-28.4 {lsearch -sorted with -stride} -body { + lsearch -sorted -stride 2 {5 3 7 8 9 2} 8 +} -result -1 +test lsearch-28.5 {lsearch -sorted with -stride} -body { + lsearch -sorted -stride 2 {5 3 7 8 9 2} 9 +} -result 4 +test lsearch-28.6 {lsearch -sorted with -stride} -body { + lsearch -sorted -stride 2 {5 3 7 8 9 2} 2 +} -result -1 +test lsearch-28.7 {lsearch -sorted with -stride} -body { + lsearch -sorted -stride 2 -index 0 -subindices {5 3 7 8 9 2} 9 +} -result 4 +test lsearch-28.8 {lsearch -sorted with -stride} -body { + lsearch -sorted -stride 2 -index 1 -subindices {3 5 8 7 2 9} 9 +} -result 5 +test lsearch-28.8 {lsearch -sorted with -stride} -body { + lsearch -sorted -stride 2 -index 1 -subindices -inline {3 5 8 7 2 9} 9 +} -result 9 + # cleanup catch {unset res} -- cgit v0.12 From fc03549d341d28a2158b38acb91c75be993d37d0 Mon Sep 17 00:00:00 2001 From: pspjuth Date: Tue, 2 Jan 2018 23:05:25 +0000 Subject: Doc for lsearch -stride --- doc/lsearch.n | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/doc/lsearch.n b/doc/lsearch.n index c2644b8..2f956a5 100644 --- a/doc/lsearch.n +++ b/doc/lsearch.n @@ -148,6 +148,18 @@ or \fB\-not\fR. These options are used to search lists of lists. They may be used with any other options. .TP +\fB\-stride\0\fIstrideLength\fR +. +If this option is specified, the list is treated as consisting of +groups of \fIstrideLength\fR elements and the groups are searched by +either their first element or, if the \fB\-index\fR option is used, +by the element within each group given by the first index passed to +\fB\-index\fR (which is then ignored by \fB\-index\fR). The resulting +index always points to the first element in a group. +.PP +The list length must be an integer multiple of \fIstrideLength\fR, which +in turn must be at least 2. +.TP \fB\-index\fR\0\fIindexList\fR . This option is designed for use when searching within nested lists. @@ -208,6 +220,13 @@ It is also possible to search inside elements: \fBlsearch\fR -index 1 -all -inline {{a abc} {b bcd} {c cde}} *bc* \fI\(-> {a abc} {b bcd}\fR .CE +.PP +The same thing for a flattened list: +.PP +.CS +\fBlsearch\fR -stride 2 -index 1 -all -inline {a abc b bcd c cde} *bc* + \fI\(-> {a abc b bcd}\fR +.CE .SH "SEE ALSO" foreach(n), list(n), lappend(n), lindex(n), linsert(n), llength(n), lset(n), lsort(n), lrange(n), lreplace(n), -- cgit v0.12 From 3b5858bcd23542b0ff0249a128808ef20922beb6 Mon Sep 17 00:00:00 2001 From: oehhar Date: Wed, 10 Jan 2018 23:17:43 +0000 Subject: TIP490: oo for msgcal: new solution enable any command for oo, new command mcpackagenamespacege --- changes | 2 ++ library/msgcat/msgcat.tcl | 49 ++++++++++++++++++++++-------- library/msgcat/pkgIndex.tcl | 2 +- tests/msgcat.test | 74 +++++++++++++++++++++++++++++++++++++++++++++ unix/Makefile.in | 4 +-- win/Makefile.in | 4 +-- 6 files changed, 118 insertions(+), 17 deletions(-) diff --git a/changes b/changes index f89704b..51c0477 100644 --- a/changes +++ b/changes @@ -8879,3 +8879,5 @@ in this changeset (new minor version) rather than bug fixes: 2017-09-02 (bug)[0e4d88] replace command, delete trace kills namespace (porter) --- Released 8.7a1, September 8, 2017 --- http://core.tcl.tk/tcl/ for details + +2017-12-11 (TIP 490) add oo support for msgcat => msgcat 1.6.2 (oehlmann) diff --git a/library/msgcat/msgcat.tcl b/library/msgcat/msgcat.tcl index 646bc17..849adc6 100644 --- a/library/msgcat/msgcat.tcl +++ b/library/msgcat/msgcat.tcl @@ -14,12 +14,12 @@ package require Tcl 8.5- # When the version number changes, be sure to update the pkgIndex.tcl file, # and the installation directory in the Makefiles. -package provide msgcat 1.6.1 +package provide msgcat 1.6.2 namespace eval msgcat { namespace export mc mcexists mcload mclocale mcmax mcmset mcpreferences mcset\ mcunknown mcflset mcflmset mcloadedlocales mcforgetpackage\ - mcpackageconfig mcpackagelocale + mcpackagenamespaceget mcpackageconfig mcpackagelocale # Records the list of locales to search variable Loclist {} @@ -193,9 +193,6 @@ namespace eval msgcat { # format command. proc msgcat::mc {src args} { - # this may be replaced by: - # return [mcget -namespace [uplevel 1 [list ::namespace current]] --\ - # $src {*}$args] # Check for the src in each namespace starting from the local and # ending in the global. @@ -203,7 +200,7 @@ proc msgcat::mc {src args} { variable Msgs variable Loclist - set ns [uplevel 1 [list ::namespace current]] + set ns [PackageNamespaceGet] set loclist [PackagePreferences $ns] set nscur $ns @@ -245,7 +242,7 @@ proc msgcat::mcexists {args} { variable Loclist variable PackageConfig - set ns [uplevel 1 [list ::namespace current]] + set ns [PackageNamespaceGet] set loclist [PackagePreferences $ns] while {[llength $args] != 1} { @@ -462,7 +459,7 @@ proc msgcat::mcpackagelocale {subcommand {locale ""}} { } set locale [string tolower $locale] } - set ns [uplevel 1 {::namespace current}] + set ns [PackageNamespaceGet] switch -exact -- $subcommand { get { return [lindex [PackagePreferences $ns] 0] } @@ -551,7 +548,7 @@ proc msgcat::mcforgetpackage {} { # todo: this may be implemented using an ensemble variable PackageConfig variable Msgs - set ns [uplevel 1 {::namespace current}] + set ns [PackageNamespaceGet] # Remove MC items dict unset Msgs $ns # Remove config items @@ -561,6 +558,15 @@ proc msgcat::mcforgetpackage {} { return } +# msgcat::mcgetmynamespace -- +# +# Return the package namespace of the caller +# This consideres to be called from a class or object. + +proc msgcat::mcpackagenamespaceget {} { + return [PackageNamespaceGet] +} + # msgcat::mcpackageconfig -- # # Get or modify the per caller namespace (e.g. packages) config options. @@ -616,7 +622,7 @@ proc msgcat::mcforgetpackage {} { proc msgcat::mcpackageconfig {subcommand option {value ""}} { variable PackageConfig # get namespace - set ns [uplevel 1 {::namespace current}] + set ns [PackageNamespaceGet] if {$option ni {"mcfolder" "loadcmd" "changecmd" "unknowncmd"}} { return -code error "bad option \"$option\": must be mcfolder, loadcmd,\ @@ -923,7 +929,7 @@ proc msgcat::mcset {locale src {dest ""}} { set dest $src } - set ns [uplevel 1 [list ::namespace current]] + set ns [PackageNamespaceGet] set locale [string tolower $locale] @@ -975,7 +981,7 @@ proc msgcat::mcmset {locale pairs} { } set locale [string tolower $locale] - set ns [uplevel 1 [list ::namespace current]] + set ns [PackageNamespaceGet] foreach {src dest} $pairs { dict set Msgs $ns $locale $src $dest @@ -1106,6 +1112,25 @@ proc msgcat::ConvertLocale {value} { return $ret } +# helper function to find package namespace of stack-frame -2 +# There are 3 possibilities: +# - called from a proc +# - called from a oo class +# - called from a classless oo object +proc ::msgcat::PackageNamespaceGet {} { + uplevel 2 { + # Check for no object + if {0 == [llength [info commands self]]} {return [namespace current]} + set Class [info object class [self]] + # Check for classless defined object + if {$Class eq {::oo::object}} { + return [namespace qualifiers [self]] + } + # Class defined object + return [namespace qualifiers $Class] + } +} + # Initialize the default locale proc msgcat::Init {} { global env diff --git a/library/msgcat/pkgIndex.tcl b/library/msgcat/pkgIndex.tcl index 72c5dc0..bc58cbe 100644 --- a/library/msgcat/pkgIndex.tcl +++ b/library/msgcat/pkgIndex.tcl @@ -1,2 +1,2 @@ if {![package vsatisfies [package provide Tcl] 8.5-]} {return} -package ifneeded msgcat 1.6.1 [list source [file join $dir msgcat.tcl]] +package ifneeded msgcat 1.6.2 [list source [file join $dir msgcat.tcl]] diff --git a/tests/msgcat.test b/tests/msgcat.test index 1c3ce58..9dc8b48 100644 --- a/tests/msgcat.test +++ b/tests/msgcat.test @@ -1073,6 +1073,80 @@ namespace eval ::msgcat::test { } -returnCodes 1\ -result {fail} + + # Tests msgcat-15.*: tcloo coverage + + # There are 3 use-cases, where 2 must be tested now: + # - namespace defined, class defined oo, classless + + test msgcat-15.1 {mc in class} -setup { + namespace eval ::bar { + ::msgcat::mcset foo_BAR con2 con2bar + oo::class create ClassCur + oo::define ClassCur method method1 {} {::msgcat::mc con2} + } + namespace eval ::baz { + set ObjCur [::bar::ClassCur new] + } + variable locale [mclocale] + mclocale foo_BAR + } -cleanup { + mclocale $locale + namespace eval ::bar {::msgcat::mcforgetpackage} + namespace forget ::bar ::baz + } -body { + $::baz::ObjCur method1 + } -result con2bar + + test msgcat-15.2 {mc in classless object} -setup { + namespace eval ::bar { + ::msgcat::mcset foo_BAR con2 con2bar + oo::object create ObjCur + oo::objdefine ObjCur method method1 {} {::msgcat::mc con2} + } + variable locale [mclocale] + mclocale foo_BAR + } -cleanup { + mclocale $locale + namespace eval ::bar {::msgcat::mcforgetpackage} + namespace forget ::bar + } -body { + ::bar::ObjCur method1 + } -result con2bar + + # Test msgcat-16.*: command mcpackagenamespaceget + + test msgcat-16.1 {mcpackagenamespaceget in namespace procedure} -body { + namespace eval ::baz {msgcat::mcpackagenamespaceget} + } -result ::baz + + test msgcat-16.2 {mcpackagenamespaceget in class} -setup { + namespace eval ::bar { + oo::class create ClassCur + oo::define ClassCur method method1 {} {msgcat::mcpackagenamespaceget} + } + namespace eval ::baz { + set ObjCur [::bar::ClassCur new] + } + } -cleanup { + namespace forget ::bar ::baz + } -body { + $::baz::ObjCur method1 + } -result ::bar + + test msgcat-16.3 {mcpackagenamespaceget in classless object} -setup { + namespace eval ::bar { + oo::object create ObjCur + oo::objdefine ObjCur method method1 {} {msgcat::mcpackagenamespaceget} + } + } -cleanup { + namespace forget ::bar + } -body { + ::bar::ObjCur method1 + } -result ::bar + + + interp bgerror {} $bgerrorsaved cleanupTests diff --git a/unix/Makefile.in b/unix/Makefile.in index f3b9782..a343864 100644 --- a/unix/Makefile.in +++ b/unix/Makefile.in @@ -855,8 +855,8 @@ install-libraries: libraries do \ $(INSTALL_DATA) $$i "$(SCRIPT_INSTALL_DIR)"/opt0.4; \ done; - @echo "Installing package msgcat 1.6.1 as a Tcl Module"; - @$(INSTALL_DATA) $(TOP_DIR)/library/msgcat/msgcat.tcl "$(SCRIPT_INSTALL_DIR)"/../tcl8/8.5/msgcat-1.6.1.tm; + @echo "Installing package msgcat 1.6.2 as a Tcl Module"; + @$(INSTALL_DATA) $(TOP_DIR)/library/msgcat/msgcat.tcl "$(SCRIPT_INSTALL_DIR)"/../tcl8/8.5/msgcat-1.6.2.tm; @echo "Installing package tcltest 2.4.1 as a Tcl Module"; @$(INSTALL_DATA) $(TOP_DIR)/library/tcltest/tcltest.tcl "$(SCRIPT_INSTALL_DIR)"/../tcl8/8.5/tcltest-2.4.1.tm; diff --git a/win/Makefile.in b/win/Makefile.in index a3275ba..f3e1bd6 100644 --- a/win/Makefile.in +++ b/win/Makefile.in @@ -664,8 +664,8 @@ install-libraries: libraries install-tzdata install-msgs do \ $(COPY) "$$j" "$(SCRIPT_INSTALL_DIR)/opt0.4"; \ done; - @echo "Installing package msgcat 1.6.1 as a Tcl Module"; - @$(COPY) $(ROOT_DIR)/library/msgcat/msgcat.tcl $(SCRIPT_INSTALL_DIR)/../tcl8/8.5/msgcat-1.6.1.tm; + @echo "Installing package msgcat 1.6.2 as a Tcl Module"; + @$(COPY) $(ROOT_DIR)/library/msgcat/msgcat.tcl $(SCRIPT_INSTALL_DIR)/../tcl8/8.5/msgcat-1.6.2.tm; @echo "Installing package tcltest 2.4.0 as a Tcl Module"; @$(COPY) $(ROOT_DIR)/library/tcltest/tcltest.tcl $(SCRIPT_INSTALL_DIR)/../tcl8/8.5/tcltest-2.4.0.tm; @echo "Installing package platform 1.0.14 as a Tcl Module"; -- cgit v0.12 From 1fda13591a6eff53b73bfa288078edb56ab8a26c Mon Sep 17 00:00:00 2001 From: oehhar Date: Thu, 11 Jan 2018 16:46:09 +0000 Subject: Corrected test cleanups --- tests/msgcat.test | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/tests/msgcat.test b/tests/msgcat.test index 9dc8b48..387ce85 100644 --- a/tests/msgcat.test +++ b/tests/msgcat.test @@ -1093,7 +1093,7 @@ namespace eval ::msgcat::test { } -cleanup { mclocale $locale namespace eval ::bar {::msgcat::mcforgetpackage} - namespace forget ::bar ::baz + namespace delete ::bar ::baz } -body { $::baz::ObjCur method1 } -result con2bar @@ -1109,7 +1109,7 @@ namespace eval ::msgcat::test { } -cleanup { mclocale $locale namespace eval ::bar {::msgcat::mcforgetpackage} - namespace forget ::bar + namespace delete ::bar } -body { ::bar::ObjCur method1 } -result con2bar @@ -1129,7 +1129,7 @@ namespace eval ::msgcat::test { set ObjCur [::bar::ClassCur new] } } -cleanup { - namespace forget ::bar ::baz + namespace delete ::bar ::baz } -body { $::baz::ObjCur method1 } -result ::bar @@ -1140,7 +1140,7 @@ namespace eval ::msgcat::test { oo::objdefine ObjCur method method1 {} {msgcat::mcpackagenamespaceget} } } -cleanup { - namespace forget ::bar + namespace delete ::bar } -body { ::bar::ObjCur method1 } -result ::bar -- cgit v0.12 From e9f2695255b873c200a7fc465f860b4fd5c97a02 Mon Sep 17 00:00:00 2001 From: oehhar Date: Fri, 12 Jan 2018 14:03:04 +0000 Subject: replace "return [uplevel 1 [list [namespace origin ..." by tailcall --- library/msgcat/msgcat.tcl | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/library/msgcat/msgcat.tcl b/library/msgcat/msgcat.tcl index 849adc6..885240f 100644 --- a/library/msgcat/msgcat.tcl +++ b/library/msgcat/msgcat.tcl @@ -216,7 +216,7 @@ proc msgcat::mc {src args} { # call package local or default unknown command set args [linsert $args 0 [lindex $loclist 0] $src] switch -exact -- [Invoke unknowncmd $args $ns result 1] { - 0 { return [uplevel 1 [linsert $args 0 [namespace origin mcunknown]]] } + 0 { tailcall mcunknown {*}$args } 1 { return [DefaultUnknown {*}$args] } default { return $result } } @@ -762,8 +762,7 @@ proc msgcat::ListComplement {list1 list2 {inlistname ""}} { # Returns the number of message catalogs that were loaded. proc msgcat::mcload {langdir} { - return [uplevel 1 [list\ - [namespace origin mcpackageconfig] set mcfolder $langdir]] + tailcall mcpackageconfig set mcfolder $langdir } # msgcat::LoadAll -- @@ -957,7 +956,7 @@ proc msgcat::mcflset {src {dest ""}} { return -code error "must only be used inside a message catalog loaded\ with ::msgcat::mcload" } - return [uplevel 1 [list [namespace origin mcset] $FileLocale $src $dest]] + tailcall mcset $FileLocale $src $dest } # msgcat::mcmset -- @@ -1008,7 +1007,7 @@ proc msgcat::mcflmset {pairs} { return -code error "must only be used inside a message catalog loaded\ with ::msgcat::mcload" } - return [uplevel 1 [list [namespace origin mcmset] $FileLocale $pairs]] + tailcal mcmset $FileLocale $pairs } # msgcat::mcunknown -- @@ -1030,7 +1029,7 @@ proc msgcat::mcflmset {pairs} { # Returns the translated value. proc msgcat::mcunknown {args} { - return [uplevel 1 [list [namespace origin DefaultUnknown] {*}$args]] + tailcall DefaultUnknown {*}$args } # msgcat::DefaultUnknown -- -- cgit v0.12 From 2cfe8bb5619eb9a1de655bda6a208e9e2fb8b81b Mon Sep 17 00:00:00 2001 From: oehhar Date: Fri, 12 Jan 2018 14:13:03 +0000 Subject: Use the test "[namespace which self] ne "::oo::Helpers::self"" to check if we are within an object (undocumented test proposed by dkf on clt 2018-01-12 --- library/msgcat/msgcat.tcl | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/library/msgcat/msgcat.tcl b/library/msgcat/msgcat.tcl index 885240f..66cedea 100644 --- a/library/msgcat/msgcat.tcl +++ b/library/msgcat/msgcat.tcl @@ -1119,7 +1119,10 @@ proc msgcat::ConvertLocale {value} { proc ::msgcat::PackageNamespaceGet {} { uplevel 2 { # Check for no object - if {0 == [llength [info commands self]]} {return [namespace current]} + # (undocumented test proposed by dkf 2018-01-12) + if { [namespace which self] ne "::oo::Helpers::self"} { + return [namespace current] + } set Class [info object class [self]] # Check for classless defined object if {$Class eq {::oo::object}} { -- cgit v0.12 From e1ffd3f0057b68e75bce64f9c514b9993fb8a79c Mon Sep 17 00:00:00 2001 From: oehhar Date: Fri, 12 Jan 2018 14:52:25 +0000 Subject: Implement the "mcn" command as "mc" with explicit namespace. --- library/msgcat/msgcat.tcl | 32 ++++++++++++++++++++++++++++---- tests/msgcat.test | 12 ++++++++++++ 2 files changed, 40 insertions(+), 4 deletions(-) diff --git a/library/msgcat/msgcat.tcl b/library/msgcat/msgcat.tcl index 66cedea..29ccf0a 100644 --- a/library/msgcat/msgcat.tcl +++ b/library/msgcat/msgcat.tcl @@ -17,7 +17,8 @@ package require Tcl 8.5- package provide msgcat 1.6.2 namespace eval msgcat { - namespace export mc mcexists mcload mclocale mcmax mcmset mcpreferences mcset\ + namespace export mc mcn mcexists mcload mclocale mcmax\ + mcmset mcpreferences mcset\ mcunknown mcflset mcflmset mcloadedlocales mcforgetpackage\ mcpackagenamespaceget mcpackageconfig mcpackagelocale @@ -192,7 +193,30 @@ namespace eval msgcat { # Returns the translated string. Propagates errors thrown by the # format command. -proc msgcat::mc {src args} { +proc msgcat::mc {args} { + tailcall mcn [PackageNamespaceGet] {*}$args +} + +# msgcat::mcn -- +# +# Find the translation for the given string based on the current +# locale setting. Check the passed namespace first, then look in each +# parent namespace until the source is found. If additional args are +# specified, use the format command to work them into the traslated +# string. +# If no catalog item is found, mcunknown is called in the caller frame +# and its result is returned. +# +# Arguments: +# ns Package namespace of the translation +# src The string to translate. +# args Args to pass to the format command +# +# Results: +# Returns the translated string. Propagates errors thrown by the +# format command. + +proc msgcat::mcn {ns src args} { # Check for the src in each namespace starting from the local and # ending in the global. @@ -200,7 +224,6 @@ proc msgcat::mc {src args} { variable Msgs variable Loclist - set ns [PackageNamespaceGet] set loclist [PackagePreferences $ns] set nscur $ns @@ -1072,8 +1095,9 @@ proc msgcat::DefaultUnknown {locale src args} { proc msgcat::mcmax {args} { set max 0 + set ns [PackageNamespaceGet] foreach string $args { - set translated [uplevel 1 [list [namespace origin mc] $string]] + set translated [uplevel 1 [list [namespace origin mcn] $ns $string]] set len [string length $translated] if {$len>$max} { set max $len diff --git a/tests/msgcat.test b/tests/msgcat.test index 387ce85..c8f325b 100644 --- a/tests/msgcat.test +++ b/tests/msgcat.test @@ -1144,7 +1144,19 @@ namespace eval ::msgcat::test { } -body { ::bar::ObjCur method1 } -result ::bar + + + # Test msgcat-17.*: mcn command + test msgcat-17.1 {mcn} -setup { + namespace eval bar {::msgcat::mcset foo_BAR con1 con1bar} + variable locale [mclocale] + mclocale foo_BAR + } -cleanup { + mclocale $locale + } -body { + ::msgcat::mcn [namespace current]::bar con1 + } -result con1bar interp bgerror {} $bgerrorsaved -- cgit v0.12 From ecaec63f48c02c5bb7c0e7585ebc1d746b77ffd9 Mon Sep 17 00:00:00 2001 From: oehhar Date: Sat, 13 Jan 2018 15:23:38 +0000 Subject: Extended command msgcat::mcexists by switch "-namespace ns" to explicitly specify namespace --- library/msgcat/msgcat.tcl | 22 ++++++--- tests/msgcat.test | 120 ++++++++++++++++++++++++++++++++++++---------- 2 files changed, 109 insertions(+), 33 deletions(-) diff --git a/library/msgcat/msgcat.tcl b/library/msgcat/msgcat.tcl index 29ccf0a..e57802b 100644 --- a/library/msgcat/msgcat.tcl +++ b/library/msgcat/msgcat.tcl @@ -265,23 +265,31 @@ proc msgcat::mcexists {args} { variable Loclist variable PackageConfig - set ns [PackageNamespaceGet] - set loclist [PackagePreferences $ns] - while {[llength $args] != 1} { set args [lassign $args option] switch -glob -- $option { - -exactnamespace { set exactnamespace 1 } - -exactlocale { set loclist [lrange $loclist 0 0] } + -exactnamespace - -exactlocale { set $option 1 } + -namespace { + if {[llength $args] < 2} { + return -code error\ + "Argument missing for switch \"-namespace\"" + } + set args [lassign $args ns] + } -* { return -code error "unknown option \"$option\"" } default { return -code error "wrong # args: should be\ \"[lindex [info level 0] 0] ?-exactnamespace?\ - ?-exactlocale? src\"" + ?-exactlocale? ?-namespace ns? src\"" } } } set src [lindex $args 0] + + if {![info exists ns]} { set ns [PackageNamespaceGet] } + + set loclist [PackagePreferences $ns] + if {[info exists -exactlocale]} { set loclist [lrange $loclist 0 0] } while {$ns ne ""} { foreach loc $loclist { @@ -289,7 +297,7 @@ proc msgcat::mcexists {args} { return 1 } } - if {[info exists exactnamespace]} {return 0} + if {[info exists -exactnamespace]} {return 0} set ns [namespace parent $ns] } return 0 diff --git a/tests/msgcat.test b/tests/msgcat.test index c8f325b..a99086d 100644 --- a/tests/msgcat.test +++ b/tests/msgcat.test @@ -688,7 +688,7 @@ namespace eval ::msgcat::test { test msgcat-9.1 {mcexists no parameter} -body { mcexists } -returnCodes 1\ - -result {wrong # args: should be "mcexists ?-exactnamespace? ?-exactlocale? src"} + -result {wrong # args: should be "mcexists ?-exactnamespace? ?-exactlocale? ?-namespace ns? src"} test msgcat-9.2 {mcexists unknown option} -body { mcexists -unknown src @@ -724,12 +724,34 @@ namespace eval ::msgcat::test { mcset foo k1 v1 } -cleanup { mclocale $locale + namespace delete ::foo } -body { - namespace eval ::msgcat::test::sub { + namespace eval ::foo { list [::msgcat::mcexists k1]\ - [::msgcat::mcexists -exactnamespace k1] + [::msgcat::mcexists -namespace ::msgcat::test k1] } - } -result {1 0} + } -result {0 1} + + test msgcat-9.6 {mcexists -namespace - ns argument missing} -setup { + mcforgetpackage + variable locale [mclocale] + mclocale foo_bar + mcset foo k1 v1 + } -cleanup { + mclocale $locale + namespace delete ::foo + } -body { + namespace eval ::foo { + list [::msgcat::mcexists k1]\ + [::msgcat::mcexists -namespace ::msgcat::test k1] + } + } -result {0 1} + + test msgcat-9.1 {mcexists -namespace with no parameter} -body { + mcexists -namespace src + } -returnCodes 1\ + -result {Argument missing for switch "-namespace"} + # Tests msgcat-10.*: [mcloadedlocales] @@ -1080,26 +1102,29 @@ namespace eval ::msgcat::test { # - namespace defined, class defined oo, classless test msgcat-15.1 {mc in class} -setup { - namespace eval ::bar { + # full namespace is ::msgcat::test:bar + namespace eval bar { ::msgcat::mcset foo_BAR con2 con2bar oo::class create ClassCur oo::define ClassCur method method1 {} {::msgcat::mc con2} } - namespace eval ::baz { - set ObjCur [::bar::ClassCur new] + # full namespace is ::msgcat::test:baz + namespace eval baz { + set ObjCur [::msgcat::test::bar::ClassCur new] } variable locale [mclocale] mclocale foo_BAR } -cleanup { mclocale $locale - namespace eval ::bar {::msgcat::mcforgetpackage} - namespace delete ::bar ::baz + namespace eval bar {::msgcat::mcforgetpackage} + namespace delete bar baz } -body { - $::baz::ObjCur method1 + $baz::ObjCur method1 } -result con2bar test msgcat-15.2 {mc in classless object} -setup { - namespace eval ::bar { + # full namespace is ::msgcat::test:bar + namespace eval bar { ::msgcat::mcset foo_BAR con2 con2bar oo::object create ObjCur oo::objdefine ObjCur method method1 {} {::msgcat::mc con2} @@ -1108,42 +1133,85 @@ namespace eval ::msgcat::test { mclocale foo_BAR } -cleanup { mclocale $locale - namespace eval ::bar {::msgcat::mcforgetpackage} - namespace delete ::bar + namespace eval bar {::msgcat::mcforgetpackage} + namespace delete bar } -body { - ::bar::ObjCur method1 + bar::ObjCur method1 } -result con2bar + test msgcat-15.3 {mc in classless object with explicite namespace eval}\ + -setup { + # full namespace is ::msgcat::test:bar + namespace eval bar { + ::msgcat::mcset foo_BAR con2 con2bar + oo::object create ObjCur + oo::objdefine ObjCur method method1 {} { + namespace eval ::msgcat::test::baz { + ::msgcat::mc con2 + } + } + } + namespace eval baz { + ::msgcat::mcset foo_BAR con2 con2baz + } + variable locale [mclocale] + mclocale foo_BAR + } -cleanup { + mclocale $locale + namespace eval bar {::msgcat::mcforgetpackage} + namespace eval baz {::msgcat::mcforgetpackage} + namespace delete bar baz + } -body { + bar::ObjCur method1 + } -result con2baz + # Test msgcat-16.*: command mcpackagenamespaceget test msgcat-16.1 {mcpackagenamespaceget in namespace procedure} -body { - namespace eval ::baz {msgcat::mcpackagenamespaceget} - } -result ::baz + namespace eval baz {msgcat::mcpackagenamespaceget} + } -result ::msgcat::test::baz test msgcat-16.2 {mcpackagenamespaceget in class} -setup { - namespace eval ::bar { + namespace eval bar { oo::class create ClassCur oo::define ClassCur method method1 {} {msgcat::mcpackagenamespaceget} } - namespace eval ::baz { - set ObjCur [::bar::ClassCur new] + namespace eval baz { + set ObjCur [::msgcat::test::bar::ClassCur new] } } -cleanup { - namespace delete ::bar ::baz + namespace delete bar baz } -body { - $::baz::ObjCur method1 - } -result ::bar + $baz::ObjCur method1 + } -result ::msgcat::test::bar test msgcat-16.3 {mcpackagenamespaceget in classless object} -setup { - namespace eval ::bar { + namespace eval bar { oo::object create ObjCur oo::objdefine ObjCur method method1 {} {msgcat::mcpackagenamespaceget} } } -cleanup { - namespace delete ::bar + namespace delete bar + } -body { + bar::ObjCur method1 + } -result ::msgcat::test::bar + + test msgcat-16.4\ + {mcpackagenamespaceget in classless object with explicite namespace eval}\ + -setup { + namespace eval bar { + oo::object create ObjCur + oo::objdefine ObjCur method method1 {} { + namespace eval ::msgcat::test::baz { + msgcat::mcpackagenamespaceget + } + } + } + } -cleanup { + namespace delete bar baz } -body { - ::bar::ObjCur method1 - } -result ::bar + bar::ObjCur method1 + } -result ::msgcat::test::baz # Test msgcat-17.*: mcn command -- cgit v0.12 From eaacc9bb568b4c69d6a5bda83a9f11d9f0f46a80 Mon Sep 17 00:00:00 2001 From: oehhar Date: Sat, 13 Jan 2018 16:44:38 +0000 Subject: Changed msgcat version from 1.6.2 to 1.7.0 -> this is not a patch release --- changes | 2 +- library/msgcat/msgcat.tcl | 2 +- library/msgcat/pkgIndex.tcl | 2 +- unix/Makefile.in | 4 ++-- win/Makefile.in | 4 ++-- 5 files changed, 7 insertions(+), 7 deletions(-) diff --git a/changes b/changes index 51c0477..5b5a93e 100644 --- a/changes +++ b/changes @@ -8880,4 +8880,4 @@ in this changeset (new minor version) rather than bug fixes: --- Released 8.7a1, September 8, 2017 --- http://core.tcl.tk/tcl/ for details -2017-12-11 (TIP 490) add oo support for msgcat => msgcat 1.6.2 (oehlmann) +2017-12-11 (TIP 490) add oo support for msgcat => msgcat 1.7.0 (oehlmann) diff --git a/library/msgcat/msgcat.tcl b/library/msgcat/msgcat.tcl index e57802b..4233005 100644 --- a/library/msgcat/msgcat.tcl +++ b/library/msgcat/msgcat.tcl @@ -14,7 +14,7 @@ package require Tcl 8.5- # When the version number changes, be sure to update the pkgIndex.tcl file, # and the installation directory in the Makefiles. -package provide msgcat 1.6.2 +package provide msgcat 1.7.0 namespace eval msgcat { namespace export mc mcn mcexists mcload mclocale mcmax\ diff --git a/library/msgcat/pkgIndex.tcl b/library/msgcat/pkgIndex.tcl index bc58cbe..fe3b3a1 100644 --- a/library/msgcat/pkgIndex.tcl +++ b/library/msgcat/pkgIndex.tcl @@ -1,2 +1,2 @@ if {![package vsatisfies [package provide Tcl] 8.5-]} {return} -package ifneeded msgcat 1.6.2 [list source [file join $dir msgcat.tcl]] +package ifneeded msgcat 1.7.0 [list source [file join $dir msgcat.tcl]] diff --git a/unix/Makefile.in b/unix/Makefile.in index a343864..a3c0e4c 100644 --- a/unix/Makefile.in +++ b/unix/Makefile.in @@ -855,8 +855,8 @@ install-libraries: libraries do \ $(INSTALL_DATA) $$i "$(SCRIPT_INSTALL_DIR)"/opt0.4; \ done; - @echo "Installing package msgcat 1.6.2 as a Tcl Module"; - @$(INSTALL_DATA) $(TOP_DIR)/library/msgcat/msgcat.tcl "$(SCRIPT_INSTALL_DIR)"/../tcl8/8.5/msgcat-1.6.2.tm; + @echo "Installing package msgcat 1.7.0 as a Tcl Module"; + @$(INSTALL_DATA) $(TOP_DIR)/library/msgcat/msgcat.tcl "$(SCRIPT_INSTALL_DIR)"/../tcl8/8.5/msgcat-1.7.0.tm; @echo "Installing package tcltest 2.4.1 as a Tcl Module"; @$(INSTALL_DATA) $(TOP_DIR)/library/tcltest/tcltest.tcl "$(SCRIPT_INSTALL_DIR)"/../tcl8/8.5/tcltest-2.4.1.tm; diff --git a/win/Makefile.in b/win/Makefile.in index f3e1bd6..a97f1a1 100644 --- a/win/Makefile.in +++ b/win/Makefile.in @@ -664,8 +664,8 @@ install-libraries: libraries install-tzdata install-msgs do \ $(COPY) "$$j" "$(SCRIPT_INSTALL_DIR)/opt0.4"; \ done; - @echo "Installing package msgcat 1.6.2 as a Tcl Module"; - @$(COPY) $(ROOT_DIR)/library/msgcat/msgcat.tcl $(SCRIPT_INSTALL_DIR)/../tcl8/8.5/msgcat-1.6.2.tm; + @echo "Installing package msgcat 1.7.0 as a Tcl Module"; + @$(COPY) $(ROOT_DIR)/library/msgcat/msgcat.tcl $(SCRIPT_INSTALL_DIR)/../tcl8/8.5/msgcat-1.7.0.tm; @echo "Installing package tcltest 2.4.0 as a Tcl Module"; @$(COPY) $(ROOT_DIR)/library/tcltest/tcltest.tcl $(SCRIPT_INSTALL_DIR)/../tcl8/8.5/tcltest-2.4.0.tm; @echo "Installing package platform 1.0.14 as a Tcl Module"; -- cgit v0.12 From 87c12599bfbcd60c4b90780c1a7e653c95c2436c Mon Sep 17 00:00:00 2001 From: oehhar Date: Sat, 13 Jan 2018 17:14:22 +0000 Subject: Test numbering and naming corrected --- tests/msgcat.test | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/msgcat.test b/tests/msgcat.test index a99086d..a71ee3f 100644 --- a/tests/msgcat.test +++ b/tests/msgcat.test @@ -732,7 +732,7 @@ namespace eval ::msgcat::test { } } -result {0 1} - test msgcat-9.6 {mcexists -namespace - ns argument missing} -setup { + test msgcat-9.6 {mcexists -namespace ns parameter} -setup { mcforgetpackage variable locale [mclocale] mclocale foo_bar @@ -747,7 +747,7 @@ namespace eval ::msgcat::test { } } -result {0 1} - test msgcat-9.1 {mcexists -namespace with no parameter} -body { + test msgcat-9.7 {mcexists -namespace - ns argument missing} -body { mcexists -namespace src } -returnCodes 1\ -result {Argument missing for switch "-namespace"} -- cgit v0.12 From e841295386a779136b49e7ca3843a43279a8c185 Mon Sep 17 00:00:00 2001 From: oehhar Date: Sat, 13 Jan 2018 17:17:39 +0000 Subject: Install msgcat 1.7 in library folder 8.6 instead 8.5. It uses tailcall and will not work with 8.5 --- unix/Makefile.in | 2 +- win/Makefile.in | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/unix/Makefile.in b/unix/Makefile.in index a3c0e4c..baaab95 100644 --- a/unix/Makefile.in +++ b/unix/Makefile.in @@ -856,7 +856,7 @@ install-libraries: libraries $(INSTALL_DATA) $$i "$(SCRIPT_INSTALL_DIR)"/opt0.4; \ done; @echo "Installing package msgcat 1.7.0 as a Tcl Module"; - @$(INSTALL_DATA) $(TOP_DIR)/library/msgcat/msgcat.tcl "$(SCRIPT_INSTALL_DIR)"/../tcl8/8.5/msgcat-1.7.0.tm; + @$(INSTALL_DATA) $(TOP_DIR)/library/msgcat/msgcat.tcl "$(SCRIPT_INSTALL_DIR)"/../tcl8/8.6/msgcat-1.7.0.tm; @echo "Installing package tcltest 2.4.1 as a Tcl Module"; @$(INSTALL_DATA) $(TOP_DIR)/library/tcltest/tcltest.tcl "$(SCRIPT_INSTALL_DIR)"/../tcl8/8.5/tcltest-2.4.1.tm; diff --git a/win/Makefile.in b/win/Makefile.in index a97f1a1..131f22b 100644 --- a/win/Makefile.in +++ b/win/Makefile.in @@ -665,7 +665,7 @@ install-libraries: libraries install-tzdata install-msgs $(COPY) "$$j" "$(SCRIPT_INSTALL_DIR)/opt0.4"; \ done; @echo "Installing package msgcat 1.7.0 as a Tcl Module"; - @$(COPY) $(ROOT_DIR)/library/msgcat/msgcat.tcl $(SCRIPT_INSTALL_DIR)/../tcl8/8.5/msgcat-1.7.0.tm; + @$(COPY) $(ROOT_DIR)/library/msgcat/msgcat.tcl $(SCRIPT_INSTALL_DIR)/../tcl8/8.6/msgcat-1.7.0.tm; @echo "Installing package tcltest 2.4.0 as a Tcl Module"; @$(COPY) $(ROOT_DIR)/library/tcltest/tcltest.tcl $(SCRIPT_INSTALL_DIR)/../tcl8/8.5/tcltest-2.4.0.tm; @echo "Installing package platform 1.0.14 as a Tcl Module"; -- cgit v0.12 From e89d1e331e09f13b01ad0436d00bf199214d4d46 Mon Sep 17 00:00:00 2001 From: oehhar Date: Tue, 16 Jan 2018 14:13:14 +0000 Subject: Solve case where msgcat is called within a class definition script (works only for 8.7) --- library/msgcat/msgcat.tcl | 29 +++++++++++++++++---------- tests/msgcat.test | 50 ++++++++++++++++++++++++++++++++++++++--------- 2 files changed, 60 insertions(+), 19 deletions(-) diff --git a/library/msgcat/msgcat.tcl b/library/msgcat/msgcat.tcl index 4233005..0b1079b 100644 --- a/library/msgcat/msgcat.tcl +++ b/library/msgcat/msgcat.tcl @@ -1151,17 +1151,26 @@ proc msgcat::ConvertLocale {value} { proc ::msgcat::PackageNamespaceGet {} { uplevel 2 { # Check for no object - # (undocumented test proposed by dkf 2018-01-12) - if { [namespace which self] ne "::oo::Helpers::self"} { - return [namespace current] - } - set Class [info object class [self]] - # Check for classless defined object - if {$Class eq {::oo::object}} { - return [namespace qualifiers [self]] + switch -exact -- [namespace which self] { + {::oo::define::self} { + # We are within a class definition + return [namespace qualifiers [self]] + } + {::oo::Helpers::self} { + # We are within an object + set Class [info object class [self]] + # Check for classless defined object + if {$Class eq {::oo::object}} { + return [namespace qualifiers [self]] + } + # Class defined object + return [namespace qualifiers $Class] + } + default { + # Not in object environment + return [namespace current] + } } - # Class defined object - return [namespace qualifiers $Class] } } diff --git a/tests/msgcat.test b/tests/msgcat.test index a71ee3f..7f872ed 100644 --- a/tests/msgcat.test +++ b/tests/msgcat.test @@ -1098,10 +1098,26 @@ namespace eval ::msgcat::test { # Tests msgcat-15.*: tcloo coverage - # There are 3 use-cases, where 2 must be tested now: - # - namespace defined, class defined oo, classless + # There are 4 use-cases, where 3 must be tested now: + # - namespace defined, in class definition, class defined oo, classless - test msgcat-15.1 {mc in class} -setup { + test msgcat-15.1 {mc in class setup} -setup { + # full namespace is ::msgcat::test:bar + namespace eval bar { + ::msgcat::mcset foo_BAR con2 con2bar + oo::class create ClassCur + } + variable locale [mclocale] + mclocale foo_BAR + } -cleanup { + mclocale $locale + namespace eval bar {::msgcat::mcforgetpackage} + namespace delete bar + } -body { + oo::define bar::ClassCur msgcat::mc con2 + } -result con2bar + + test msgcat-15.2 {mc in class} -setup { # full namespace is ::msgcat::test:bar namespace eval bar { ::msgcat::mcset foo_BAR con2 con2bar @@ -1122,7 +1138,7 @@ namespace eval ::msgcat::test { $baz::ObjCur method1 } -result con2bar - test msgcat-15.2 {mc in classless object} -setup { + test msgcat-15.3 {mc in classless object} -setup { # full namespace is ::msgcat::test:bar namespace eval bar { ::msgcat::mcset foo_BAR con2 con2bar @@ -1139,7 +1155,7 @@ namespace eval ::msgcat::test { bar::ObjCur method1 } -result con2bar - test msgcat-15.3 {mc in classless object with explicite namespace eval}\ + test msgcat-15.4 {mc in classless object with explicite namespace eval}\ -setup { # full namespace is ::msgcat::test:bar namespace eval bar { @@ -1171,7 +1187,18 @@ namespace eval ::msgcat::test { namespace eval baz {msgcat::mcpackagenamespaceget} } -result ::msgcat::test::baz - test msgcat-16.2 {mcpackagenamespaceget in class} -setup { + test msgcat-16.2 {mcpackagenamespaceget in class setup} -setup { + namespace eval bar { + oo::class create ClassCur + oo::define ClassCur variable a + } + } -cleanup { + namespace delete bar + } -body { + oo::define bar::ClassCur msgcat::mcpackagenamespaceget + } -result ::msgcat::test::bar + + test msgcat-16.3 {mcpackagenamespaceget in class} -setup { namespace eval bar { oo::class create ClassCur oo::define ClassCur method method1 {} {msgcat::mcpackagenamespaceget} @@ -1185,7 +1212,7 @@ namespace eval ::msgcat::test { $baz::ObjCur method1 } -result ::msgcat::test::bar - test msgcat-16.3 {mcpackagenamespaceget in classless object} -setup { + test msgcat-16.4 {mcpackagenamespaceget in classless object} -setup { namespace eval bar { oo::object create ObjCur oo::objdefine ObjCur method method1 {} {msgcat::mcpackagenamespaceget} @@ -1196,7 +1223,7 @@ namespace eval ::msgcat::test { bar::ObjCur method1 } -result ::msgcat::test::bar - test msgcat-16.4\ + test msgcat-16.5\ {mcpackagenamespaceget in classless object with explicite namespace eval}\ -setup { namespace eval bar { @@ -1216,7 +1243,12 @@ namespace eval ::msgcat::test { # Test msgcat-17.*: mcn command - test msgcat-17.1 {mcn} -setup { + test msgcat-17.1 {mcn no parameters} -body { + mcn + } -returnCodes 1\ + -result {wrong # args: should be "mcn ns src ?arg ...?"} + + test msgcat-17.2 {mcn} -setup { namespace eval bar {::msgcat::mcset foo_BAR con1 con1bar} variable locale [mclocale] mclocale foo_BAR -- cgit v0.12 From 7c60d44ce6b8c71d89857ce711a3f7f62ce2de2c Mon Sep 17 00:00:00 2001 From: oehhar Date: Tue, 16 Jan 2018 14:53:41 +0000 Subject: Comment updated --- library/msgcat/msgcat.tcl | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/library/msgcat/msgcat.tcl b/library/msgcat/msgcat.tcl index 0b1079b..33ff5cb 100644 --- a/library/msgcat/msgcat.tcl +++ b/library/msgcat/msgcat.tcl @@ -1144,9 +1144,10 @@ proc msgcat::ConvertLocale {value} { } # helper function to find package namespace of stack-frame -2 -# There are 3 possibilities: +# There are 4 possibilities: # - called from a proc -# - called from a oo class +# - called within a class definition script +# - called from an class defined oo object # - called from a classless oo object proc ::msgcat::PackageNamespaceGet {} { uplevel 2 { -- cgit v0.12 From 83df36ac4194e2b04610ad61244a08b9b068a816 Mon Sep 17 00:00:00 2001 From: pspjuth Date: Thu, 25 Jan 2018 20:05:54 +0000 Subject: Allow -stride 1. --- doc/lsearch.n | 3 ++- generic/tclCmdIL.c | 4 ++-- tests/lsearch.test | 6 +++++- 3 files changed, 9 insertions(+), 4 deletions(-) diff --git a/doc/lsearch.n b/doc/lsearch.n index 2f956a5..12c2786 100644 --- a/doc/lsearch.n +++ b/doc/lsearch.n @@ -158,7 +158,8 @@ by the element within each group given by the first index passed to index always points to the first element in a group. .PP The list length must be an integer multiple of \fIstrideLength\fR, which -in turn must be at least 2. +in turn must be at least 1. A \fIstrideLength\fR of 1 is the default and +indicates no grouping. .TP \fB\-index\fR\0\fIindexList\fR . diff --git a/generic/tclCmdIL.c b/generic/tclCmdIL.c index c514f84..e07b5ba 100644 --- a/generic/tclCmdIL.c +++ b/generic/tclCmdIL.c @@ -3101,9 +3101,9 @@ Tcl_LsearchObjCmd( result = TCL_ERROR; goto done; } - if (groupSize < 2) { + if (groupSize < 1) { Tcl_SetObjResult(interp, Tcl_NewStringObj( - "stride length must be at least 2", -1)); + "stride length must be at least 1", -1)); Tcl_SetErrorCode(interp, "TCL", "OPERATION", "LSORT", "BADSTRIDE", NULL); result = TCL_ERROR; diff --git a/tests/lsearch.test b/tests/lsearch.test index 4e4b206..a53a8be 100644 --- a/tests/lsearch.test +++ b/tests/lsearch.test @@ -518,7 +518,7 @@ test lsearch-23.1 {lsearch -stride option, errors} -body { } -returnCodes error -result {"-stride" option must be followed by stride length} test lsearch-23.2 {lsearch -stride option, errors} -body { lsearch -stride 0 {a b} a -} -returnCodes error -result {stride length must be at least 2} +} -returnCodes error -result {stride length must be at least 1} test lsearch-23.3 {lsearch -stride option, errors} -body { lsearch -stride 2 {a b c} a } -returnCodes error -result {list size must be a multiple of the stride length} @@ -562,6 +562,10 @@ test lsearch-24.9 {lsearch -stride option} -body { test lsearch-24.10 {lsearch -stride option} -body { lsearch -all -inline -stride 3 -index 0 {a b c d e f a e i} a } -result "a b c a e i" +test lsearch-24.11 {lsearch -stride option} -body { + # Stride 1 is same as no stride + lsearch -stride 1 {a b c d e f g h} d +} -result 3 # 25* mimics 19* but with -inline added to -subindices test lsearch-25.1 {lsearch -subindices option} { -- cgit v0.12 From 46e8af13b6ce6aaddd0d274991d58db7d44714ca Mon Sep 17 00:00:00 2001 From: dgp Date: Thu, 25 Jan 2018 22:11:34 +0000 Subject: Dup test name --- tests/lsearch.test | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/lsearch.test b/tests/lsearch.test index a53a8be..a7efcdd 100644 --- a/tests/lsearch.test +++ b/tests/lsearch.test @@ -651,7 +651,7 @@ test lsearch-28.7 {lsearch -sorted with -stride} -body { test lsearch-28.8 {lsearch -sorted with -stride} -body { lsearch -sorted -stride 2 -index 1 -subindices {3 5 8 7 2 9} 9 } -result 5 -test lsearch-28.8 {lsearch -sorted with -stride} -body { +test lsearch-28.9 {lsearch -sorted with -stride} -body { lsearch -sorted -stride 2 -index 1 -subindices -inline {3 5 8 7 2 9} 9 } -result 9 -- cgit v0.12 From 3f2c5cd5aa8381ad73336403f1ff98a52230726f Mon Sep 17 00:00:00 2001 From: oehhar Date: Wed, 7 Feb 2018 19:25:30 +0000 Subject: TIP 499: Custom locale search for msgcat --- changes | 3 + library/msgcat/msgcat.tcl | 130 ++++++++++++++++++++++++++++++++------------ library/msgcat/pkgIndex.tcl | 2 +- tests/msgcat.test | 53 +++++++++++++++++- unix/Makefile.in | 4 +- win/Makefile.in | 4 +- 6 files changed, 154 insertions(+), 42 deletions(-) mode change 100644 => 100755 changes mode change 100644 => 100755 library/msgcat/msgcat.tcl mode change 100644 => 100755 library/msgcat/pkgIndex.tcl mode change 100644 => 100755 tests/msgcat.test mode change 100644 => 100755 unix/Makefile.in mode change 100644 => 100755 win/Makefile.in diff --git a/changes b/changes old mode 100644 new mode 100755 index f89704b..120f9ff --- a/changes +++ b/changes @@ -8879,3 +8879,6 @@ in this changeset (new minor version) rather than bug fixes: 2017-09-02 (bug)[0e4d88] replace command, delete trace kills namespace (porter) --- Released 8.7a1, September 8, 2017 --- http://core.tcl.tk/tcl/ for details + +2018-02-07 (TIP 499) custom locale preference list (nijtmans) +=> msgcat 1.7.0 diff --git a/library/msgcat/msgcat.tcl b/library/msgcat/msgcat.tcl old mode 100644 new mode 100755 index 646bc17..0f8f9b3 --- a/library/msgcat/msgcat.tcl +++ b/library/msgcat/msgcat.tcl @@ -14,11 +14,11 @@ package require Tcl 8.5- # When the version number changes, be sure to update the pkgIndex.tcl file, # and the installation directory in the Makefiles. -package provide msgcat 1.6.1 +package provide msgcat 1.7.0 namespace eval msgcat { - namespace export mc mcexists mcload mclocale mcmax mcmset mcpreferences mcset\ - mcunknown mcflset mcflmset mcloadedlocales mcforgetpackage\ + namespace export mc mcexists mcload mclocale mcmax mcmset mcpreferences\ + mcset mcunknown mcflset mcflmset mcloadedlocales mcforgetpackage\ mcpackageconfig mcpackagelocale # Records the list of locales to search @@ -303,14 +303,7 @@ proc msgcat::mclocale {args} { return -code error "invalid newLocale value \"$newLocale\":\ could be path to unsafe code." } - if {[lindex $Loclist 0] ne $newLocale} { - set Loclist [GetPreferences $newLocale] - - # locale not loaded jet - LoadAll $Loclist - # Invoke callback - Invoke changecmd $Loclist - } + mcpreferences {*}[GetPreferences $newLocale] } return [lindex $Loclist 0] } @@ -349,16 +342,51 @@ proc msgcat::GetPreferences {locale} { # most preferred to least preferred. # # Arguments: -# None. +# New location list # # Results: # Returns an ordered list of the locales preferred by the user. -proc msgcat::mcpreferences {} { +proc msgcat::mcpreferences {args} { variable Loclist + + if {[llength $args] > 0} { + # args is the new loclist + if {![ListEqualString $args $Loclist]} { + set Loclist $args + + # locale not loaded jet + LoadAll $Loclist + # Invoke callback + Invoke changecmd $Loclist + } + } return $Loclist } +# msgcat::ListStringEqual -- +# +# Compare two strings for equal string contents +# +# Arguments: +# list1 first list +# list2 second list +# +# Results: +# 1 if lists of strings are identical, 0 otherwise + +proc msgcat::ListEqualString {list1 list2} { + if {[llength $list1] != [llength $list2]} { + return 0 + } + foreach item1 $list1 item2 $list2 { + if {$item1 ne $item2} { + return 0 + } + } + return 1 +} + # msgcat::mcloadedlocales -- # # Get or change the list of currently loaded default locales @@ -442,7 +470,7 @@ proc msgcat::mcloadedlocales {subcommand} { # Results: # Empty string, if not stated differently for the subcommand -proc msgcat::mcpackagelocale {subcommand {locale ""}} { +proc msgcat::mcpackagelocale {subcommand args} { # todo: implement using an ensemble variable Loclist variable LoadedLocales @@ -450,27 +478,39 @@ proc msgcat::mcpackagelocale {subcommand {locale ""}} { variable PackageConfig # Check option # check if required item is exactly provided - if {[llength [info level 0]] == 2} { - # locale not given - unset locale - } else { - # locale given - if {$subcommand in - {"get" "isset" "unset" "preferences" "loaded" "clear"} } { - return -code error "wrong # args: should be\ - \"[lrange [info level 0] 0 1]\"" - } - set locale [string tolower $locale] + if { [llength $args] > 0 + && $subcommand in {"get" "isset" "unset" "loaded" "clear"} } { + return -code error "wrong # args: should be\ + \"[lrange [info level 0] 0 1]\"" } set ns [uplevel 1 {::namespace current}] switch -exact -- $subcommand { get { return [lindex [PackagePreferences $ns] 0] } - preferences { return [PackagePreferences $ns] } loaded { return [PackageLocales $ns] } - present { return [expr {$locale in [PackageLocales $ns]} ]} + present { + if {[llength $args] != 1} { + return -code error "wrong # args: should be\ + \"[lrange [info level 0] 0 1] locale\"" + } + return [expr {[string tolower [lindex $args 0]] + in [PackageLocales $ns]} ] + } isset { return [dict exists $PackageConfig loclist $ns] } - set { # set a package locale or add a package locale + set - preferences { + # set a package locale or add a package locale + set fSet [expr {$subcommand eq "set"}] + + # Check parameter + if {$fSet && 1 < [llength $args] } { + return -code error "wrong # args: should be\ + \"[lrange [info level 0] 0 1] ?locale?\"" + } + + # > Return preferences if no parameter + if {!$fSet && 0 == [llength $args] } { + return [PackagePreferences $ns] + } # Copy the default locale if no package locale set so far if {![dict exists $PackageConfig loclist $ns]} { @@ -478,25 +518,43 @@ proc msgcat::mcpackagelocale {subcommand {locale ""}} { dict set PackageConfig loadedlocales $ns $LoadedLocales } - # Check if changed - set loclist [dict get $PackageConfig loclist $ns] - if {! [info exists locale] || $locale eq [lindex $loclist 0] } { - return [lindex $loclist 0] + # No argument for set: return current package locale + # The difference to no argument and subcommand "preferences" is, + # that "preferences" does not set the package locale property. + # This case is processed above, so no check for fSet here + if { 0 == [llength $args] } { + return [lindex [dict get $PackageConfig loclist $ns] 0] + } + + # Get new loclist + if {$fSet} { + set loclist [GetPreferences [string tolower [lindex $args 0]]] + } else { + set loclist $args + } + + # Check if not changed to return imediately + if { [ListEqualString $loclist\ + [dict get $PackageConfig loclist $ns]] } { + if {$fSet} { + return [lindex $loclist 0] + } + return $loclist } # Change loclist - set loclist [GetPreferences $locale] - set locale [lindex $loclist 0] dict set PackageConfig loclist $ns $loclist # load eventual missing locales set loadedLocales [dict get $PackageConfig loadedlocales $ns] - if {$locale in $loadedLocales} { return $locale } set loadLocales [ListComplement $loadedLocales $loclist] dict set PackageConfig loadedlocales $ns\ [concat $loadedLocales $loadLocales] Load $ns $loadLocales - return $locale + if {$fSet} { + return [lindex $loclist 0] + } + return $loclist } clear { # Remove all locales not contained in Loclist if {![dict exists $PackageConfig loclist $ns]} { diff --git a/library/msgcat/pkgIndex.tcl b/library/msgcat/pkgIndex.tcl old mode 100644 new mode 100755 index 72c5dc0..fe3b3a1 --- a/library/msgcat/pkgIndex.tcl +++ b/library/msgcat/pkgIndex.tcl @@ -1,2 +1,2 @@ if {![package vsatisfies [package provide Tcl] 8.5-]} {return} -package ifneeded msgcat 1.6.1 [list source [file join $dir msgcat.tcl]] +package ifneeded msgcat 1.7.0 [list source [file join $dir msgcat.tcl]] diff --git a/tests/msgcat.test b/tests/msgcat.test old mode 100644 new mode 100755 index 1c3ce58..b0d2bd3 --- a/tests/msgcat.test +++ b/tests/msgcat.test @@ -194,6 +194,28 @@ namespace eval ::msgcat::test { mclocale looks/ok/../../../../but/is/path/to/evil/code } -returnCodes error -match glob -result {invalid newLocale value *} + test msgcat-1.14 {mcpreferences, custom locale preferences} -setup { + variable locale [mclocale] + mclocale en + mcpreferences fr en {} + } -cleanup { + mclocale $locale + } -body { + mcpreferences + } -result {fr en {}} + + test msgcat-1.15 {mcpreferences, overwrite custom locale preferences}\ + -setup { + variable locale [mclocale] + mcpreferences fr en {} + mclocale en + } -cleanup { + mclocale $locale + } -body { + mcpreferences + } -result {en {}} + + # Tests msgcat-2.*: [mcset], [mcmset], namespace partitioning test msgcat-2.1 {mcset, global scope} { @@ -811,13 +833,18 @@ namespace eval ::msgcat::test { test msgcat-12.1 {mcpackagelocale no subcommand} -body { mcpackagelocale } -returnCodes 1\ - -result {wrong # args: should be "mcpackagelocale subcommand ?locale?"} + -result {wrong # args: should be "mcpackagelocale subcommand ?arg ...?"} test msgcat-12.2 {mclpackagelocale wrong subcommand} -body { mcpackagelocale junk } -returnCodes 1\ -result {unknown subcommand "junk": must be clear, get, isset, loaded, present, set, or unset} + test msgcat-12.2.1 {mclpackagelocale set multiple args} -body { + mcpackagelocale set a b + } -returnCodes 1\ + -result {wrong # args: should be "mcpackagelocale set ?locale?"} + test msgcat-12.3 {mcpackagelocale set} -setup { variable locale [mclocale] } -cleanup { @@ -922,6 +949,30 @@ namespace eval ::msgcat::test { list [mcpackagelocale present foo] [mcpackagelocale present bar] } -result {0 1} + test msgcat-12.11 {mcpackagelocale custom preferences} -setup { + variable locale [mclocale] + } -cleanup { + mclocale $locale + mcforgetpackage + } -body { + mclocale foo + set res [list [mcpackagelocale preferences]] + mcpackagelocale preferences bar {} + lappend res [mcpackagelocale preferences] + } -result {{foo {}} {bar {}}} + + test msgcat-12.12 {mcpackagelocale preferences -> no isset} -setup { + variable locale [mclocale] + } -cleanup { + mclocale $locale + mcforgetpackage + } -body { + mclocale foo + mcpackagelocale preferences + mcpackagelocale isset + } -result {0} + + # Tests msgcat-13.*: [mcpackageconfig subcmds] test msgcat-13.1 {mcpackageconfig no subcommand} -body { diff --git a/unix/Makefile.in b/unix/Makefile.in old mode 100644 new mode 100755 index 244ad29..4487ff5 --- a/unix/Makefile.in +++ b/unix/Makefile.in @@ -850,8 +850,8 @@ install-libraries: libraries do \ $(INSTALL_DATA) $$i "$(SCRIPT_INSTALL_DIR)"/opt0.4; \ done; - @echo "Installing package msgcat 1.6.1 as a Tcl Module"; - @$(INSTALL_DATA) $(TOP_DIR)/library/msgcat/msgcat.tcl "$(SCRIPT_INSTALL_DIR)"/../tcl8/8.5/msgcat-1.6.1.tm; + @echo "Installing package msgcat 1.7.0 as a Tcl Module"; + @$(INSTALL_DATA) $(TOP_DIR)/library/msgcat/msgcat.tcl "$(SCRIPT_INSTALL_DIR)"/../tcl8/8.5/msgcat-1.7.0.tm; @echo "Installing package tcltest 2.4.1 as a Tcl Module"; @$(INSTALL_DATA) $(TOP_DIR)/library/tcltest/tcltest.tcl "$(SCRIPT_INSTALL_DIR)"/../tcl8/8.5/tcltest-2.4.1.tm; diff --git a/win/Makefile.in b/win/Makefile.in old mode 100644 new mode 100755 index 5be7492..e5e2384 --- a/win/Makefile.in +++ b/win/Makefile.in @@ -659,8 +659,8 @@ install-libraries: libraries install-tzdata install-msgs do \ $(COPY) "$$j" "$(SCRIPT_INSTALL_DIR)/opt0.4"; \ done; - @echo "Installing package msgcat 1.6.1 as a Tcl Module"; - @$(COPY) $(ROOT_DIR)/library/msgcat/msgcat.tcl $(SCRIPT_INSTALL_DIR)/../tcl8/8.5/msgcat-1.6.1.tm; + @echo "Installing package msgcat 1.7.0 as a Tcl Module"; + @$(COPY) $(ROOT_DIR)/library/msgcat/msgcat.tcl $(SCRIPT_INSTALL_DIR)/../tcl8/8.5/msgcat-1.7.0.tm; @echo "Installing package tcltest 2.4.0 as a Tcl Module"; @$(COPY) $(ROOT_DIR)/library/tcltest/tcltest.tcl $(SCRIPT_INSTALL_DIR)/../tcl8/8.5/tcltest-2.4.0.tm; @echo "Installing package platform 1.0.14 as a Tcl Module"; -- cgit v0.12 From 4cff9271ac34377ccf2717fcb47f3c0adc8b58ee Mon Sep 17 00:00:00 2001 From: oehhar Date: Thu, 8 Feb 2018 09:49:28 +0000 Subject: Add subcommand mcpreferences to export getpreferences and getsystemlocale functions --- library/msgcat/msgcat.tcl | 54 ++++++++++++++++++++++++----------------------- tests/msgcat.test | 35 ++++++++++++++++++++++++++++++ 2 files changed, 63 insertions(+), 26 deletions(-) diff --git a/library/msgcat/msgcat.tcl b/library/msgcat/msgcat.tcl index 0f8f9b3..8fcbefb 100755 --- a/library/msgcat/msgcat.tcl +++ b/library/msgcat/msgcat.tcl @@ -19,7 +19,7 @@ package provide msgcat 1.7.0 namespace eval msgcat { namespace export mc mcexists mcload mclocale mcmax mcmset mcpreferences\ mcset mcunknown mcflset mcflmset mcloadedlocales mcforgetpackage\ - mcpackageconfig mcpackagelocale + mcpackageconfig mcpackagelocale mcutil # Records the list of locales to search variable Loclist {} @@ -41,7 +41,13 @@ namespace eval msgcat { # namespace should be themselves dict values and the value is # the translated string. variable Msgs [dict create] +} +# create ensemble namespace for mcutil command +namespace eval msgcat::mcutil { + namespace export getsystemlocale getpreferences + namespace ensemble create + # Map of language codes used in Windows registry to those of ISO-639 if {[info sharedlibextension] eq ".dll"} { variable WinRegToISO639 [dict create {*}{ @@ -303,25 +309,27 @@ proc msgcat::mclocale {args} { return -code error "invalid newLocale value \"$newLocale\":\ could be path to unsafe code." } - mcpreferences {*}[GetPreferences $newLocale] + mcpreferences {*}[mcutil getpreferences $newLocale] } return [lindex $Loclist 0] } -# msgcat::GetPreferences -- +# msgcat::mcutil::getpreferences -- # # Get list of locales from a locale. # The first element is always the lowercase locale. # Other elements have one component separated by "_" less. # Multiple "_" are seen as one separator: de__ch_spec de__ch de {} # +# This method is part of the ensemble mcutil +# # Arguments: # Locale. # # Results: # Locale list -proc msgcat::GetPreferences {locale} { +proc msgcat::mcutil::getpreferences {locale} { set locale [string tolower $locale] set loclist [list $locale] while {-1 !=[set pos [string last "_" $locale]]} { @@ -528,7 +536,7 @@ proc msgcat::mcpackagelocale {subcommand args} { # Get new loclist if {$fSet} { - set loclist [GetPreferences [string tolower [lindex $args 0]]] + set loclist [mcutil getpreferences [lindex $args 0]] } else { set loclist $args } @@ -1137,7 +1145,7 @@ proc msgcat::mcmax {args} { # Convert the locale values stored in environment variables to a form # suitable for passing to [mclocale] -proc msgcat::ConvertLocale {value} { +proc msgcat::mcutil::ConvertLocale {value} { # Assume $value is of form: $language[_$territory][.$codeset][@modifier] # Convert to form: $language[_$territory][_$modifier] # @@ -1165,7 +1173,7 @@ proc msgcat::ConvertLocale {value} { } # Initialize the default locale -proc msgcat::Init {} { +proc msgcat::mcutil::getsystemlocale {} { global env # @@ -1173,10 +1181,8 @@ proc msgcat::Init {} { # foreach varName {LC_ALL LC_MESSAGES LANG} { if {[info exists env($varName)] && ("" ne $env($varName))} { - if {![catch { - mclocale [ConvertLocale $env($varName)] - }]} { - return + if {![catch { ConvertLocale $env($varName) } locale]} { + return $locale } } } @@ -1184,10 +1190,8 @@ proc msgcat::Init {} { # On Darwin, fallback to current CFLocale identifier if available. # if {[info exists ::tcl::mac::locale] && $::tcl::mac::locale ne ""} { - if {![catch { - mclocale [ConvertLocale $::tcl::mac::locale] - }]} { - return + if {![catch { ConvertLocale $::tcl::mac::locale] } locale]} { + return $locale } } # @@ -1196,8 +1200,7 @@ proc msgcat::Init {} { # if {([info sharedlibextension] ne ".dll") || [catch {package require registry}]} { - mclocale C - return + return C } # # On Windows or Cygwin, try to set locale depending on registry @@ -1228,8 +1231,8 @@ proc msgcat::Init {} { if {[dict exists $modifierDict $script]} { append locale @ [dict get $modifierDict $script] } - if {![catch {mclocale [ConvertLocale $locale]}]} { - return + if {![catch {ConvertLocale $locale} locale]} { + return $locale } } } @@ -1238,8 +1241,7 @@ proc msgcat::Init {} { if {[catch { set locale [registry get $key "locale"] }]} { - mclocale C - return + return C } # # Keep trying to match against smaller and smaller suffixes @@ -1254,15 +1256,15 @@ proc msgcat::Init {} { set locale [string tolower $locale] while {[string length $locale]} { if {![catch { - mclocale [ConvertLocale [dict get $WinRegToISO639 $locale]] - }]} { - return + ConvertLocale [dict get $WinRegToISO639 $locale] + } localeOut]} { + return $localeOut } set locale [string range $locale 1 end] } # # No translation known. Fall back on "C" locale # - mclocale C + return C } -msgcat::Init +msgcat::mclocale [msgcat::mcutil getsystemlocale] diff --git a/tests/msgcat.test b/tests/msgcat.test index b0d2bd3..7a095a6 100755 --- a/tests/msgcat.test +++ b/tests/msgcat.test @@ -1126,6 +1126,41 @@ namespace eval ::msgcat::test { interp bgerror {} $bgerrorsaved + # Tests msgcat-15.*: [mcutil] + + test msgcat-15.1 {mcutil - no argument} -body { + mcutil + } -returnCodes 1\ + -result {wrong # args: should be "mcutil subcommand ?arg ...?"} + + test msgcat-15.2 {mcutil - wrong argument} -body { + mcutil junk + } -returnCodes 1\ + -result {unknown or ambiguous subcommand "junk": must be getpreferences, or getsystemlocale} + + test msgcat-15.3 {mcutil getpreferences - no argument} -body { + mcutil getpreferences + } -returnCodes 1\ + -result {wrong # args: should be "mcutil getpreferences locale"} + + test msgcat-15.4 {mcutil getpreferences - DE_de} -body { + mcutil getpreferences DE_de + } -result {de_de de {}} + + test msgcat-15.5 {mcutil getsystemlocale - wrong argument} -body { + mcutil getsystemlocale DE_de + } -returnCodes 1\ + -result {wrong # args: should be "mcutil getsystemlocale"} + + # The result is system dependent + # So just test if it runs + # The environment variable version was test with test 0.x + test msgcat-15.6 {mcutil getsystemlocale} -body { + mcutil getsystemlocale + set ok ok + } -result {ok} + + cleanupTests } namespace delete ::msgcat::test -- cgit v0.12 From ffae8c82da5227389ee81c50b5e22bc7678ed2f0 Mon Sep 17 00:00:00 2001 From: oehhar Date: Thu, 8 Feb 2018 12:45:50 +0000 Subject: Do not allow prefixed subcommands for mcutil --- library/msgcat/msgcat.tcl | 2 +- tests/msgcat.test | 15 ++++++++++----- 2 files changed, 11 insertions(+), 6 deletions(-) diff --git a/library/msgcat/msgcat.tcl b/library/msgcat/msgcat.tcl index 8fcbefb..3047e4d 100755 --- a/library/msgcat/msgcat.tcl +++ b/library/msgcat/msgcat.tcl @@ -46,7 +46,7 @@ namespace eval msgcat { # create ensemble namespace for mcutil command namespace eval msgcat::mcutil { namespace export getsystemlocale getpreferences - namespace ensemble create + namespace ensemble create -prefix 0 # Map of language codes used in Windows registry to those of ISO-639 if {[info sharedlibextension] eq ".dll"} { diff --git a/tests/msgcat.test b/tests/msgcat.test index 7a095a6..847836b 100755 --- a/tests/msgcat.test +++ b/tests/msgcat.test @@ -1136,18 +1136,23 @@ namespace eval ::msgcat::test { test msgcat-15.2 {mcutil - wrong argument} -body { mcutil junk } -returnCodes 1\ - -result {unknown or ambiguous subcommand "junk": must be getpreferences, or getsystemlocale} + -result {unknown subcommand "junk": must be getpreferences, or getsystemlocale} - test msgcat-15.3 {mcutil getpreferences - no argument} -body { + test msgcat-15.3 {mcutil - partial argument} -body { + mcutil getsystem + } -returnCodes 1\ + -result {unknown subcommand "getsystem": must be getpreferences, or getsystemlocale} + + test msgcat-15.4 {mcutil getpreferences - no argument} -body { mcutil getpreferences } -returnCodes 1\ -result {wrong # args: should be "mcutil getpreferences locale"} - test msgcat-15.4 {mcutil getpreferences - DE_de} -body { + test msgcat-15.5 {mcutil getpreferences - DE_de} -body { mcutil getpreferences DE_de } -result {de_de de {}} - test msgcat-15.5 {mcutil getsystemlocale - wrong argument} -body { + test msgcat-15.6 {mcutil getsystemlocale - wrong argument} -body { mcutil getsystemlocale DE_de } -returnCodes 1\ -result {wrong # args: should be "mcutil getsystemlocale"} @@ -1155,7 +1160,7 @@ namespace eval ::msgcat::test { # The result is system dependent # So just test if it runs # The environment variable version was test with test 0.x - test msgcat-15.6 {mcutil getsystemlocale} -body { + test msgcat-15.7 {mcutil getsystemlocale} -body { mcutil getsystemlocale set ok ok } -result {ok} -- cgit v0.12 From e9c0312caf99f93393a446302d67b7bcafeca575 Mon Sep 17 00:00:00 2001 From: dgp Date: Thu, 1 Mar 2018 04:13:15 +0000 Subject: We have LLONG_MIN and LLONG_MAX to denote range limits of Tcl_WideInt. Use them consistently. Also fix a few TIP 484 bugs. --- generic/tclExecute.c | 26 +++++++++++++------------- generic/tclScan.c | 4 ++-- 2 files changed, 15 insertions(+), 15 deletions(-) diff --git a/generic/tclExecute.c b/generic/tclExecute.c index 1c69474..09b03bd 100644 --- a/generic/tclExecute.c +++ b/generic/tclExecute.c @@ -5766,17 +5766,17 @@ TEBCresume( if (GetNumberFromObj(NULL, OBJ_AT_TOS, &ptr1, &type1) != TCL_OK) { type1 = 0; } else if (type1 == TCL_NUMBER_WIDE) { - /* value is between WIDE_MIN and WIDE_MAX */ + /* value is between LLONG_MIN and LLONG_MAX */ /* [string is integer] is -UINT_MAX to UINT_MAX range */ - /* [string is wideinteger] is -UWIDE_MAX to UWIDE_MAX range */ + /* [string is wideinteger] is -ULLONG_MAX to ULLONG_MAX range */ int i; if (Tcl_GetIntFromObj(NULL, OBJ_AT_TOS, &i) == TCL_OK) { type1 = TCL_NUMBER_LONG; } } else if (type1 == TCL_NUMBER_BIG) { - /* value is an integer outside the WIDE_MIN to WIDE_MAX range */ - /* [string is wideinteger] is -UWIDE_MAX to UWIDE_MAX range */ + /* value is an integer outside the LLONG_MIN to LLONG_MAX range */ + /* [string is wideinteger] is -ULLONG_MAX to ULLONG_MAX range */ Tcl_WideInt w; if (Tcl_GetWideIntFromObj(NULL, OBJ_AT_TOS, &w) == TCL_OK) { @@ -6007,7 +6007,7 @@ TEBCresume( objResultPtr = TCONST(0); TRACE(("%s\n", O2S(objResultPtr))); NEXT_INST_F(1, 2, 1); - } else if (w2 > (Tcl_WideInt) INT_MAX) { + } else if (w2 > INT_MAX) { /* * Technically, we could hold the value (1 << (INT_MAX+1)) * in an mp_int, but since we're using mp_mul_2d() to do @@ -6186,7 +6186,7 @@ TEBCresume( goto divideByZero; } else if ((w1 == LLONG_MIN) && (w2 == -1)) { /* - * Can't represent (-LLONG_MIN) as a long. + * Can't represent (-LLONG_MIN) as a Tcl_WideInt. */ goto overflow; @@ -6206,10 +6206,10 @@ TEBCresume( goto wideResultOfArithmetic; case INST_MULT: - if (((sizeof(long) >= 2*sizeof(int)) + if (((sizeof(Tcl_WideInt) >= 2*sizeof(int)) && (w1 <= INT_MAX) && (w1 >= INT_MIN) && (w2 <= INT_MAX) && (w2 >= INT_MIN)) - || ((sizeof(long) >= 2*sizeof(short)) + || ((sizeof(Tcl_WideInt) >= 2*sizeof(short)) && (w1 <= SHRT_MAX) && (w1 >= SHRT_MIN) && (w2 <= SHRT_MAX) && (w2 >= SHRT_MIN))) { wResult = w1 * w2; @@ -8123,7 +8123,7 @@ ExecuteExtendedBinaryMathOp( */ if ((type2 != TCL_NUMBER_WIDE) - || (*((const Tcl_WideInt *)ptr2) > (long) INT_MAX)) { + || (*((const Tcl_WideInt *)ptr2) > INT_MAX)) { /* * Technically, we could hold the value (1 << (INT_MAX+1)) in * an mp_int, but since we're using mp_mul_2d() to do the @@ -8985,10 +8985,10 @@ TclCompareTwoNumbers( * integer comparison can tell the difference. */ - if (d2 < (double)LONG_MIN) { + if (d2 < (double)LLONG_MIN) { return MP_GT; } - if (d2 > (double)LONG_MAX) { + if (d2 > (double)LLONG_MAX) { return MP_LT; } w2 = (Tcl_WideInt) d2; @@ -9031,7 +9031,7 @@ TclCompareTwoNumbers( return (d1 > 0.0) ? MP_GT : MP_LT; } Tcl_TakeBignumFromObj(NULL, value2Ptr, &big2); - if ((d1 < (double)LONG_MAX) && (d1 > (double)LONG_MIN)) { + if ((d1 < (double)LLONG_MAX) && (d1 > (double)LLONG_MIN)) { if (mp_isneg(&big2)) { compare = MP_GT; } else { @@ -9064,7 +9064,7 @@ TclCompareTwoNumbers( mp_clear(&big1); return compare; } - if ((d2 < (double)LONG_MAX) && (d2 > (double)LONG_MIN)) { + if ((d2 < (double)LLONG_MAX) && (d2 > (double)LLONG_MIN)) { compare = mp_cmp_d(&big1, 0); mp_clear(&big1); return compare; diff --git a/generic/tclScan.c b/generic/tclScan.c index d55d29b..113b4c6 100644 --- a/generic/tclScan.c +++ b/generic/tclScan.c @@ -926,9 +926,9 @@ Tcl_ScanObjCmd( } if (flags & SCAN_LONGER) { if (Tcl_GetWideIntFromObj(NULL, objPtr, &wideValue) != TCL_OK) { - wideValue = ~(Tcl_WideUInt)0 >> 1; /* WIDE_MAX */ + wideValue = LLONG_MAX; if (TclGetString(objPtr)[0] == '-') { - wideValue++; /* WIDE_MAX + 1 = WIDE_MIN */ + wideValue = LLONG_MIN; } } if ((flags & SCAN_UNSIGNED) && (wideValue < 0)) { -- cgit v0.12 From 2cd8bf554e767af28e60465bb3f683399421e0f6 Mon Sep 17 00:00:00 2001 From: dgp Date: Thu, 1 Mar 2018 16:48:55 +0000 Subject: Refactor to eliminate duplicate routine parsing tokens as indices. --- generic/tclCompCmdsGR.c | 61 +++++++++++++++++++++-------------------- generic/tclCompCmdsSZ.c | 72 +++++++------------------------------------------ generic/tclCompile.h | 7 +++++ 3 files changed, 47 insertions(+), 93 deletions(-) diff --git a/generic/tclCompCmdsGR.c b/generic/tclCompCmdsGR.c index ffe39ba..aa0f7bb 100644 --- a/generic/tclCompCmdsGR.c +++ b/generic/tclCompCmdsGR.c @@ -28,12 +28,11 @@ static void CompileReturnInternal(CompileEnv *envPtr, static int IndexTailVarIfKnown(Tcl_Interp *interp, Tcl_Token *varTokenPtr, CompileEnv *envPtr); -#define INDEX_END (-2) /* *---------------------------------------------------------------------- * - * GetIndexFromToken -- + * TclGetIndexFromToken -- * * Parse a token and get the encoded version of the index (as understood * by TEBC), assuming it is at all knowable at compile time. Only handles @@ -48,8 +47,8 @@ static int IndexTailVarIfKnown(Tcl_Interp *interp, *---------------------------------------------------------------------- */ -static inline int -GetIndexFromToken( +int +TclGetIndexFromToken( Tcl_Token *tokenPtr, int *index) { @@ -67,8 +66,8 @@ GetIndexFromToken( result = TCL_ERROR; } } else { - result = TclGetIntForIndexM(NULL, tmpObj, INDEX_END, &idx); - if (result == TCL_OK && idx > INDEX_END) { + result = TclGetIntForIndexM(NULL, tmpObj, TCL_INDEX_END, &idx); + if (result == TCL_OK && idx > TCL_INDEX_END) { result = TCL_ERROR; } } @@ -1053,7 +1052,7 @@ TclCompileLassignCmd( */ TclEmitInstInt4( INST_LIST_RANGE_IMM, idx, envPtr); - TclEmitInt4( INDEX_END, envPtr); + TclEmitInt4( TCL_INDEX_END, envPtr); return TCL_OK; } @@ -1104,7 +1103,7 @@ TclCompileLindexCmd( } idxTokenPtr = TokenAfter(valTokenPtr); - if (GetIndexFromToken(idxTokenPtr, &idx) == TCL_OK) { + if (TclGetIndexFromToken(idxTokenPtr, &idx) == TCL_OK) { /* * All checks have been completed, and we have exactly one of these * constructs: @@ -1258,7 +1257,7 @@ TclCompileListCmd( if (concat && numWords == 2) { TclEmitInstInt4( INST_LIST_RANGE_IMM, 0, envPtr); - TclEmitInt4( INDEX_END, envPtr); + TclEmitInt4( TCL_INDEX_END, envPtr); } return TCL_OK; } @@ -1339,12 +1338,12 @@ TclCompileLrangeCmd( */ tokenPtr = TokenAfter(listTokenPtr); - if (GetIndexFromToken(tokenPtr, &idx1) != TCL_OK) { + if (TclGetIndexFromToken(tokenPtr, &idx1) != TCL_OK) { return TCL_ERROR; } tokenPtr = TokenAfter(tokenPtr); - if (GetIndexFromToken(tokenPtr, &idx2) != TCL_OK) { + if (TclGetIndexFromToken(tokenPtr, &idx2) != TCL_OK) { return TCL_ERROR; } @@ -1396,21 +1395,21 @@ TclCompileLinsertCmd( */ tokenPtr = TokenAfter(listTokenPtr); - if (GetIndexFromToken(tokenPtr, &idx) != TCL_OK) { + if (TclGetIndexFromToken(tokenPtr, &idx) != TCL_OK) { return TCL_ERROR; } /* * There are four main cases. If there are no values to insert, this is * just a confirm-listiness check. If the index is '0', this is a prepend. - * If the index is 'end' (== INDEX_END), this is an append. Otherwise, + * If the index is 'end' (== TCL_INDEX_END), this is an append. Otherwise, * this is a splice (== split, insert values as list, concat-3). */ CompileWord(envPtr, listTokenPtr, interp, 1); if (parsePtr->numWords == 3) { TclEmitInstInt4( INST_LIST_RANGE_IMM, 0, envPtr); - TclEmitInt4( INDEX_END, envPtr); + TclEmitInt4( TCL_INDEX_END, envPtr); return TCL_OK; } @@ -1423,7 +1422,7 @@ TclCompileLinsertCmd( if (idx == 0 /*start*/) { TclEmitInstInt4( INST_REVERSE, 2, envPtr); TclEmitOpcode( INST_LIST_CONCAT, envPtr); - } else if (idx == INDEX_END /*end*/) { + } else if (idx == TCL_INDEX_END /*end*/) { TclEmitOpcode( INST_LIST_CONCAT, envPtr); } else { if (idx < 0) { @@ -1434,7 +1433,7 @@ TclCompileLinsertCmd( TclEmitInt4( idx-1, envPtr); TclEmitInstInt4( INST_REVERSE, 3, envPtr); TclEmitInstInt4( INST_LIST_RANGE_IMM, idx, envPtr); - TclEmitInt4( INDEX_END, envPtr); + TclEmitInt4( TCL_INDEX_END, envPtr); TclEmitOpcode( INST_LIST_CONCAT, envPtr); TclEmitOpcode( INST_LIST_CONCAT, envPtr); } @@ -1479,12 +1478,12 @@ TclCompileLreplaceCmd( */ tokenPtr = TokenAfter(listTokenPtr); - if (GetIndexFromToken(tokenPtr, &idx1) != TCL_OK) { + if (TclGetIndexFromToken(tokenPtr, &idx1) != TCL_OK) { return TCL_ERROR; } tokenPtr = TokenAfter(tokenPtr); - if (GetIndexFromToken(tokenPtr, &idx2) != TCL_OK) { + if (TclGetIndexFromToken(tokenPtr, &idx2) != TCL_OK) { return TCL_ERROR; } @@ -1492,9 +1491,9 @@ TclCompileLreplaceCmd( * idx1, idx2 are now in canonical form: * * - integer: [0,len+1] - * - end index: INDEX_END - * - -ive offset: INDEX_END-[len-1,0] - * - +ive offset: INDEX_END+1 + * - end index: TCL_INDEX_END + * - -ive offset: TCL_INDEX_END-[len-1,0] + * - +ive offset: TCL_INDEX_END+1 */ /* @@ -1503,11 +1502,11 @@ TclCompileLreplaceCmd( * now. [Bug 47ac84309b] */ - if ((idx1 <= INDEX_END) != (idx2 <= INDEX_END)) { + if ((idx1 <= TCL_INDEX_END) != (idx2 <= TCL_INDEX_END)) { return TCL_ERROR; } - if (idx2 != INDEX_END && idx2 >= 0 && idx2 < idx1) { + if (idx2 != TCL_INDEX_END && idx2 >= 0 && idx2 < idx1) { idx2 = idx1 - 1; } @@ -1519,13 +1518,13 @@ TclCompileLreplaceCmd( CompileWord(envPtr, listTokenPtr, interp, 1); if (parsePtr->numWords == 4) { if (idx1 == 0) { - if (idx2 == INDEX_END) { + if (idx2 == TCL_INDEX_END) { goto dropAll; } idx1 = idx2 + 1; - idx2 = INDEX_END; + idx2 = TCL_INDEX_END; goto dropEnd; - } else if (idx2 == INDEX_END) { + } else if (idx2 == TCL_INDEX_END) { idx2 = idx1 - 1; idx1 = 0; goto dropEnd; @@ -1549,13 +1548,13 @@ TclCompileLreplaceCmd( TclEmitInstInt4( INST_LIST, i - 4, envPtr); TclEmitInstInt4( INST_REVERSE, 2, envPtr); if (idx1 == 0) { - if (idx2 == INDEX_END) { + if (idx2 == TCL_INDEX_END) { goto replaceAll; } idx1 = idx2 + 1; - idx2 = INDEX_END; + idx2 = TCL_INDEX_END; goto replaceHead; - } else if (idx2 == INDEX_END) { + } else if (idx2 == TCL_INDEX_END) { idx2 = idx1 - 1; idx1 = 0; goto replaceTail; @@ -1623,7 +1622,7 @@ TclCompileLreplaceCmd( TclEmitInt4( idx1 - 1, envPtr); TclEmitInstInt4( INST_REVERSE, 2, envPtr); TclEmitInstInt4( INST_LIST_RANGE_IMM, idx2 + 1, envPtr); - TclEmitInt4( INDEX_END, envPtr); + TclEmitInt4( TCL_INDEX_END, envPtr); TclEmitOpcode( INST_LIST_CONCAT, envPtr); goto done; @@ -1693,7 +1692,7 @@ TclCompileLreplaceCmd( TclEmitInt4( idx1 - 1, envPtr); TclEmitInstInt4( INST_REVERSE, 2, envPtr); TclEmitInstInt4( INST_LIST_RANGE_IMM, idx2 + 1, envPtr); - TclEmitInt4( INDEX_END, envPtr); + TclEmitInt4( TCL_INDEX_END, envPtr); TclEmitInstInt4( INST_REVERSE, 3, envPtr); TclEmitOpcode( INST_LIST_CONCAT, envPtr); TclEmitInstInt4( INST_REVERSE, 2, envPtr); diff --git a/generic/tclCompCmdsSZ.c b/generic/tclCompCmdsSZ.c index 101edbd..fb0981d 100644 --- a/generic/tclCompCmdsSZ.c +++ b/generic/tclCompCmdsSZ.c @@ -107,58 +107,6 @@ const AuxDataType tclJumptableInfoType = { #define INVOKE(name) \ TclEmitInvoke(envPtr,INST_##name) -#define INDEX_END (-2) - -/* - *---------------------------------------------------------------------- - * - * GetIndexFromToken -- - * - * Parse a token and get the encoded version of the index (as understood - * by TEBC), assuming it is at all knowable at compile time. Only handles - * indices that are integers or 'end' or 'end-integer'. - * - * Returns: - * TCL_OK if parsing succeeded, and TCL_ERROR if it failed. - * - * Side effects: - * Sets *index to the index value if successful. - * - *---------------------------------------------------------------------- - */ - -static inline int -GetIndexFromToken( - Tcl_Token *tokenPtr, - int *index) -{ - Tcl_Obj *tmpObj = Tcl_NewObj(); - int result, idx; - - if (!TclWordKnownAtCompileTime(tokenPtr, tmpObj)) { - Tcl_DecrRefCount(tmpObj); - return TCL_ERROR; - } - - result = TclGetIntFromObj(NULL, tmpObj, &idx); - if (result == TCL_OK) { - if (idx < 0) { - result = TCL_ERROR; - } - } else { - result = TclGetIntForIndexM(NULL, tmpObj, INDEX_END, &idx); - if (result == TCL_OK && idx > INDEX_END) { - result = TCL_ERROR; - } - } - Tcl_DecrRefCount(tmpObj); - - if (result == TCL_OK) { - *index = idx; - } - - return result; -} /* *---------------------------------------------------------------------- @@ -986,10 +934,10 @@ TclCompileStringRangeCmd( * Parse the two indices. */ - if (GetIndexFromToken(fromTokenPtr, &idx1) != TCL_OK) { + if (TclGetIndexFromToken(fromTokenPtr, &idx1) != TCL_OK) { goto nonConstantIndices; } - if (GetIndexFromToken(toTokenPtr, &idx2) != TCL_OK) { + if (TclGetIndexFromToken(toTokenPtr, &idx2) != TCL_OK) { goto nonConstantIndices; } @@ -1044,18 +992,18 @@ TclCompileStringReplaceCmd( */ tokenPtr = TokenAfter(valueTokenPtr); - if (GetIndexFromToken(tokenPtr, &idx1) != TCL_OK) { + if (TclGetIndexFromToken(tokenPtr, &idx1) != TCL_OK) { goto genericReplace; } tokenPtr = TokenAfter(tokenPtr); - if (GetIndexFromToken(tokenPtr, &idx2) != TCL_OK) { + if (TclGetIndexFromToken(tokenPtr, &idx2) != TCL_OK) { goto genericReplace; } /* * We handle these replacements specially: first character (where - * idx1=idx2=0) and last character (where idx1=idx2=INDEX_END). Anything + * idx1=idx2=0) and last character (where idx1=idx2=TCL_INDEX_END). Anything * else and the semantics get rather screwy. */ @@ -1069,7 +1017,7 @@ TclCompileStringReplaceCmd( CompileWord(envPtr, valueTokenPtr, interp, 1); if (replacementTokenPtr == NULL) { /* Drop first */ - OP44( STR_RANGE_IMM, 1, INDEX_END); + OP44( STR_RANGE_IMM, 1, TCL_INDEX_END); return TCL_OK; } /* Replace first */ @@ -1083,12 +1031,12 @@ TclCompileStringReplaceCmd( FIXJUMP1(notEq); TclAdjustStackDepth(1, envPtr); OP4( REVERSE, 2); - OP44( STR_RANGE_IMM, 1, INDEX_END); + OP44( STR_RANGE_IMM, 1, TCL_INDEX_END); OP1( STR_CONCAT1, 2); FIXJUMP1(end); return TCL_OK; - } else if (idx1 == INDEX_END && idx2 == INDEX_END) { + } else if (idx1 == TCL_INDEX_END && idx2 == TCL_INDEX_END) { int notEq, end; /* @@ -1098,7 +1046,7 @@ TclCompileStringReplaceCmd( CompileWord(envPtr, valueTokenPtr, interp, 1); if (replacementTokenPtr == NULL) { /* Drop last */ - OP44( STR_RANGE_IMM, 0, INDEX_END-1); + OP44( STR_RANGE_IMM, 0, TCL_INDEX_END-1); return TCL_OK; } /* Replace last */ @@ -1112,7 +1060,7 @@ TclCompileStringReplaceCmd( FIXJUMP1(notEq); TclAdjustStackDepth(1, envPtr); OP4( REVERSE, 2); - OP44( STR_RANGE_IMM, 0, INDEX_END-1); + OP44( STR_RANGE_IMM, 0, TCL_INDEX_END-1); OP4( REVERSE, 2); OP1( STR_CONCAT1, 2); FIXJUMP1(end); diff --git a/generic/tclCompile.h b/generic/tclCompile.h index c04fc0e..1c64a21 100644 --- a/generic/tclCompile.h +++ b/generic/tclCompile.h @@ -1121,6 +1121,7 @@ MODULE_SCOPE int TclFixupForwardJump(CompileEnv *envPtr, int distThreshold); MODULE_SCOPE void TclFreeCompileEnv(CompileEnv *envPtr); MODULE_SCOPE void TclFreeJumpFixupArray(JumpFixupArray *fixupArrayPtr); +MODULE_SCOPE int TclGetIndexFromToken(Tcl_Token *tokenPtr, int *index); MODULE_SCOPE void TclInitByteCodeObj(Tcl_Obj *objPtr, CompileEnv *envPtr); MODULE_SCOPE void TclInitCompileEnv(Tcl_Interp *interp, @@ -1684,6 +1685,12 @@ MODULE_SCOPE int TclPushProcCallFrame(ClientData clientData, #define TCL_NO_ELEMENT 2 /* Do not push the array element. */ /* + * Special value used by TclGetIndexFromToken to encoding the "end" index. + */ + +#define TCL_INDEX_END (-2) + +/* * DTrace probe macros (NOPs if DTrace support is not enabled). */ -- cgit v0.12 From 683dada2173aaa8eb39f76d13d7e9505e77ec5b7 Mon Sep 17 00:00:00 2001 From: dgp Date: Thu, 1 Mar 2018 20:07:29 +0000 Subject: Some comments info for the next folks who come wandering in. --- generic/tclCompCmdsGR.c | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/generic/tclCompCmdsGR.c b/generic/tclCompCmdsGR.c index aa0f7bb..375653b 100644 --- a/generic/tclCompCmdsGR.c +++ b/generic/tclCompCmdsGR.c @@ -1425,7 +1425,19 @@ TclCompileLinsertCmd( } else if (idx == TCL_INDEX_END /*end*/) { TclEmitOpcode( INST_LIST_CONCAT, envPtr); } else { - if (idx < 0) { + /* + * Here we handle two ranges for idx. First when idx > 0, we + * want the first half of the split to end at index idx-1 and + * the second half to start at index idx. + * Second when idx < TCL_INDEX_END, indicating "end-N" indexing, + * we want the first half of the split to end at index end-N and + * the second half to start at index end-N+1. We accomplish this + * with a pre-adjustment of the end-N value. + * The root of this is that the commands [lrange] and [linsert] + * differ in their interpretation of the "end" index. + */ + + if (idx < TCL_INDEX_END) { idx++; } TclEmitInstInt4( INST_OVER, 1, envPtr); -- cgit v0.12 From 5753c7a42b638962406f9f7f822e48561e7a6253 Mon Sep 17 00:00:00 2001 From: "jan.nijtmans" Date: Thu, 1 Mar 2018 20:43:31 +0000 Subject: Lots of code cleanup, mainly [https://github.com/libtom/libtommath/pull/102|Pull request #102] --- libtommath/README.md | 14 +++++++-- libtommath/bn_error.c | 4 +-- libtommath/bn_fast_mp_invmod.c | 10 ++++-- libtommath/bn_fast_mp_montgomery_reduce.c | 14 ++++++--- libtommath/bn_fast_s_mp_mul_digs.c | 8 ++--- libtommath/bn_fast_s_mp_mul_high_digs.c | 6 ++-- libtommath/bn_fast_s_mp_sqr.c | 10 +++--- libtommath/bn_mp_2expt.c | 2 +- libtommath/bn_mp_clamp.c | 2 +- libtommath/bn_mp_clear_multi.c | 1 + libtommath/bn_mp_cnt_lsb.c | 8 ++--- libtommath/bn_mp_count_bits.c | 4 +-- libtommath/bn_mp_div.c | 30 +++++++++--------- libtommath/bn_mp_div_2.c | 2 +- libtommath/bn_mp_div_2d.c | 8 ++--- libtommath/bn_mp_div_3.c | 14 ++++----- libtommath/bn_mp_div_d.c | 18 +++++------ libtommath/bn_mp_dr_reduce.c | 2 +- libtommath/bn_mp_dr_setup.c | 2 +- libtommath/bn_mp_export.c | 20 ++++++------ libtommath/bn_mp_expt_d_ex.c | 12 +++---- libtommath/bn_mp_exptmod_fast.c | 6 ++-- libtommath/bn_mp_exteuclid.c | 40 ++++++++++++------------ libtommath/bn_mp_fread.c | 22 +++++++------ libtommath/bn_mp_fwrite.c | 4 +-- libtommath/bn_mp_get_int.c | 2 +- libtommath/bn_mp_get_long.c | 2 +- libtommath/bn_mp_get_long_long.c | 2 +- libtommath/bn_mp_grow.c | 2 +- libtommath/bn_mp_import.c | 16 +++++----- libtommath/bn_mp_init.c | 2 +- libtommath/bn_mp_init_multi.c | 1 + libtommath/bn_mp_init_size.c | 2 +- libtommath/bn_mp_invmod.c | 6 ++-- libtommath/bn_mp_invmod_slow.c | 8 ++--- libtommath/bn_mp_is_square.c | 20 ++++++------ libtommath/bn_mp_jacobi.c | 18 +++++------ libtommath/bn_mp_lshd.c | 4 +++ libtommath/bn_mp_mod_2d.c | 4 +-- libtommath/bn_mp_montgomery_calc_normalization.c | 2 +- libtommath/bn_mp_montgomery_reduce.c | 13 ++++---- libtommath/bn_mp_montgomery_setup.c | 14 ++++----- libtommath/bn_mp_mul.c | 4 +-- libtommath/bn_mp_mul_2.c | 6 ++-- libtommath/bn_mp_mul_2d.c | 12 +++---- libtommath/bn_mp_mul_d.c | 4 +-- libtommath/bn_mp_n_root_ex.c | 8 ++--- libtommath/bn_mp_prime_fermat.c | 2 +- libtommath/bn_mp_prime_is_divisible.c | 2 +- libtommath/bn_mp_prime_miller_rabin.c | 8 ++--- libtommath/bn_mp_prime_next_prime.c | 20 ++++++------ libtommath/bn_mp_prime_random_ex.c | 16 +++++----- libtommath/bn_mp_radix_smap.c | 14 +++++++++ libtommath/bn_mp_rand.c | 8 +++-- libtommath/bn_mp_read_radix.c | 26 +++++++-------- libtommath/bn_mp_read_signed_bin.c | 2 +- libtommath/bn_mp_read_unsigned_bin.c | 2 +- libtommath/bn_mp_reduce.c | 6 ++-- libtommath/bn_mp_reduce_2k.c | 2 +- libtommath/bn_mp_reduce_is_2k.c | 2 +- libtommath/bn_mp_set.c | 2 +- libtommath/bn_mp_set_int.c | 2 +- libtommath/bn_mp_shrink.c | 2 +- libtommath/bn_mp_sqr.c | 4 +-- libtommath/bn_mp_sqrtmod_prime.c | 28 ++++++++--------- libtommath/bn_mp_sub_d.c | 4 +-- libtommath/bn_mp_to_signed_bin_n.c | 2 +- libtommath/bn_mp_to_unsigned_bin.c | 4 +-- libtommath/bn_mp_to_unsigned_bin_n.c | 2 +- libtommath/bn_mp_toom_mul.c | 2 +- libtommath/bn_mp_toom_sqr.c | 2 +- libtommath/bn_mp_unsigned_bin_size.c | 2 +- libtommath/bn_prime_tab.c | 1 + libtommath/bn_s_mp_add.c | 4 +-- libtommath/bn_s_mp_exptmod.c | 5 +-- libtommath/bn_s_mp_mul_digs.c | 8 ++--- libtommath/bn_s_mp_mul_high_digs.c | 8 ++--- libtommath/bn_s_mp_sqr.c | 20 ++++++------ libtommath/bn_s_mp_sub.c | 4 +-- libtommath/makefile | 8 ++--- libtommath/makefile_include.mk | 3 ++ libtommath/tommath.h | 33 ++++++++++--------- libtommath/tommath_private.h | 4 ++- 83 files changed, 365 insertions(+), 314 deletions(-) diff --git a/libtommath/README.md b/libtommath/README.md index 4c5da71..3bc491d 100644 --- a/libtommath/README.md +++ b/libtommath/README.md @@ -1,8 +1,14 @@ -[![Build Status - master](https://travis-ci.org/libtom/libtommath.png?branch=master)](https://travis-ci.org/libtom/libtommath) +# libtommath -[![Build Status - develop](https://travis-ci.org/libtom/libtommath.png?branch=develop)](https://travis-ci.org/libtom/libtommath) +This is the git repository for [LibTomMath](http://www.libtom.net/LibTomMath/), a free open source portable number theoretic multiple-precision integer (MPI) library written entirely in C. -This is the git repository for [LibTomMath](http://www.libtom.org/), a free open source portable number theoretic multiple-precision integer (MPI) library written entirely in C. +## Build Status + +master - [![Build Status - master](https://travis-ci.org/libtom/libtommath.png?branch=master)](https://travis-ci.org/libtom/libtommath) + +develop - [![Build Status - develop](https://travis-ci.org/libtom/libtommath.png?branch=develop)](https://travis-ci.org/libtom/libtommath) + +## Summary The `develop` branch contains the in-development version. Stable releases are tagged. @@ -10,6 +16,8 @@ Documentation is built from the LaTeX file `bn.tex`. There is also limited docum The project can be build by using `make`. Along with the usual `make`, `make clean` and `make install`, there are several other build targets, see the makefile for details. There are also makefiles for certain specific platforms. +## Testing + Tests are located in `demo/` and can be built in two flavors. * `make test` creates a test binary that is intended to be run against `mtest`. `mtest` can be built with `make mtest` and test execution is done like `./mtest/mtest | ./test`. `mtest` is creating test vectors using an alternative MPI library and `test` is consuming these vectors to verify correct behavior of ltm * `make test_standalone` creates a stand-alone test binary that executes several test routines. diff --git a/libtommath/bn_error.c b/libtommath/bn_error.c index a51d712..7e816bf 100644 --- a/libtommath/bn_error.c +++ b/libtommath/bn_error.c @@ -27,10 +27,10 @@ static const struct { /* return a char * string for a given code */ const char *mp_error_to_string(int code) { - int x; + size_t x; /* scan the lookup table for the given message */ - for (x = 0; x < (int)(sizeof(msgs) / sizeof(msgs[0])); x++) { + for (x = 0; x < (sizeof(msgs) / sizeof(msgs[0])); x++) { if (msgs[x].code == code) { return msgs[x].msg; } diff --git a/libtommath/bn_fast_mp_invmod.c b/libtommath/bn_fast_mp_invmod.c index 08389dd..6be44f8 100644 --- a/libtommath/bn_fast_mp_invmod.c +++ b/libtommath/bn_fast_mp_invmod.c @@ -46,6 +46,12 @@ int fast_mp_invmod(const mp_int *a, const mp_int *b, mp_int *c) goto LBL_ERR; } + /* if one of x,y is zero return an error! */ + if ((mp_iszero(&x) == MP_YES) || (mp_iszero(&y) == MP_YES)) { + res = MP_VAL; + goto LBL_ERR; + } + /* 3. u=x, v=y, A=1, B=0, C=0,D=1 */ if ((res = mp_copy(&x, &u)) != MP_OKAY) { goto LBL_ERR; @@ -53,7 +59,7 @@ int fast_mp_invmod(const mp_int *a, const mp_int *b, mp_int *c) if ((res = mp_copy(&y, &v)) != MP_OKAY) { goto LBL_ERR; } - mp_set(&D, 1); + mp_set(&D, 1uL); top: /* 4. while u is even do */ @@ -122,7 +128,7 @@ top: /* now a = C, b = D, gcd == g*v */ /* if v != 1 then there is no inverse */ - if (mp_cmp_d(&v, 1) != MP_EQ) { + if (mp_cmp_d(&v, 1uL) != MP_EQ) { res = MP_VAL; goto LBL_ERR; } diff --git a/libtommath/bn_fast_mp_montgomery_reduce.c b/libtommath/bn_fast_mp_montgomery_reduce.c index 54d9b0a..8f91196 100644 --- a/libtommath/bn_fast_mp_montgomery_reduce.c +++ b/libtommath/bn_fast_mp_montgomery_reduce.c @@ -28,6 +28,10 @@ int fast_mp_montgomery_reduce(mp_int *x, const mp_int *n, mp_digit rho) int ix, res, olduse; mp_word W[MP_WARRAY]; + if (x->used > (int)MP_WARRAY) { + return MP_VAL; + } + /* get old used count */ olduse = x->used; @@ -73,7 +77,7 @@ int fast_mp_montgomery_reduce(mp_int *x, const mp_int *n, mp_digit rho) * that W[ix-1] have the carry cleared (see after the inner loop) */ mp_digit mu; - mu = (mp_digit)(((W[ix] & MP_MASK) * rho) & MP_MASK); + mu = ((W[ix] & MP_MASK) * rho) & MP_MASK; /* a = a + mu * m * b**i * @@ -102,12 +106,12 @@ int fast_mp_montgomery_reduce(mp_int *x, const mp_int *n, mp_digit rho) /* inner loop */ for (iy = 0; iy < n->used; iy++) { - *_W++ += ((mp_word)mu) * ((mp_word)*tmpn++); + *_W++ += (mp_word)mu * (mp_word)*tmpn++; } } /* now fix carry for next digit, W[ix+1] */ - W[ix + 1] += W[ix] >> ((mp_word) DIGIT_BIT); + W[ix + 1] += W[ix] >> (mp_word)DIGIT_BIT; } /* now we have to propagate the carries and @@ -127,7 +131,7 @@ int fast_mp_montgomery_reduce(mp_int *x, const mp_int *n, mp_digit rho) _W = W + ++ix; for (; ix <= ((n->used * 2) + 1); ix++) { - *_W++ += *_W1++ >> ((mp_word) DIGIT_BIT); + *_W++ += *_W1++ >> (mp_word)DIGIT_BIT; } /* copy out, A = A/b**n @@ -144,7 +148,7 @@ int fast_mp_montgomery_reduce(mp_int *x, const mp_int *n, mp_digit rho) _W = W + n->used; for (ix = 0; ix < (n->used + 1); ix++) { - *tmpx++ = (mp_digit)(*_W++ & ((mp_word) MP_MASK)); + *tmpx++ = *_W++ & (mp_word)MP_MASK; } /* zero oldused digits, if the input a was larger than diff --git a/libtommath/bn_fast_s_mp_mul_digs.c b/libtommath/bn_fast_s_mp_mul_digs.c index 558d151..e542c2e 100644 --- a/libtommath/bn_fast_s_mp_mul_digs.c +++ b/libtommath/bn_fast_s_mp_mul_digs.c @@ -69,15 +69,15 @@ int fast_s_mp_mul_digs(const mp_int *a, const mp_int *b, mp_int *c, int digs) /* execute loop */ for (iz = 0; iz < iy; ++iz) { - _W += ((mp_word)*tmpx++)*((mp_word)*tmpy--); + _W += (mp_word)*tmpx++ * (mp_word)*tmpy--; } /* store term */ - W[ix] = ((mp_digit)_W) & MP_MASK; + W[ix] = (mp_digit)_W & MP_MASK; /* make next carry */ - _W = _W >> ((mp_word)DIGIT_BIT); + _W = _W >> (mp_word)DIGIT_BIT; } /* setup dest */ @@ -87,7 +87,7 @@ int fast_s_mp_mul_digs(const mp_int *a, const mp_int *b, mp_int *c, int digs) { mp_digit *tmpc; tmpc = c->dp; - for (ix = 0; ix < (pa + 1); ix++) { + for (ix = 0; ix < pa; ix++) { /* now extract the previous digit [below the carry] */ *tmpc++ = W[ix]; } diff --git a/libtommath/bn_fast_s_mp_mul_high_digs.c b/libtommath/bn_fast_s_mp_mul_high_digs.c index 8b662ed..6ea8a6c 100644 --- a/libtommath/bn_fast_s_mp_mul_high_digs.c +++ b/libtommath/bn_fast_s_mp_mul_high_digs.c @@ -60,14 +60,14 @@ int fast_s_mp_mul_high_digs(const mp_int *a, const mp_int *b, mp_int *c, int dig /* execute loop */ for (iz = 0; iz < iy; iz++) { - _W += ((mp_word)*tmpx++)*((mp_word)*tmpy--); + _W += (mp_word)*tmpx++ * (mp_word)*tmpy--; } /* store term */ - W[ix] = ((mp_digit)_W) & MP_MASK; + W[ix] = (mp_digit)_W & MP_MASK; /* make next carry */ - _W = _W >> ((mp_word)DIGIT_BIT); + _W = _W >> (mp_word)DIGIT_BIT; } /* setup dest */ diff --git a/libtommath/bn_fast_s_mp_sqr.c b/libtommath/bn_fast_s_mp_sqr.c index 161f785..1050121 100644 --- a/libtommath/bn_fast_s_mp_sqr.c +++ b/libtommath/bn_fast_s_mp_sqr.c @@ -70,22 +70,22 @@ int fast_s_mp_sqr(const mp_int *a, mp_int *b) /* execute loop */ for (iz = 0; iz < iy; iz++) { - _W += ((mp_word)*tmpx++)*((mp_word)*tmpy--); + _W += (mp_word)*tmpx++ * (mp_word)*tmpy--; } /* double the inner product and add carry */ _W = _W + _W + W1; /* even columns have the square term in them */ - if ((ix&1) == 0) { - _W += ((mp_word)a->dp[ix>>1])*((mp_word)a->dp[ix>>1]); + if (((unsigned)ix & 1u) == 0u) { + _W += (mp_word)a->dp[ix>>1] * (mp_word)a->dp[ix>>1]; } /* store it */ - W[ix] = (mp_digit)(_W & MP_MASK); + W[ix] = _W & MP_MASK; /* make next carry */ - W1 = _W >> ((mp_word)DIGIT_BIT); + W1 = _W >> (mp_word)DIGIT_BIT; } /* setup dest */ diff --git a/libtommath/bn_mp_2expt.c b/libtommath/bn_mp_2expt.c index 701144c..5333d48 100644 --- a/libtommath/bn_mp_2expt.c +++ b/libtommath/bn_mp_2expt.c @@ -36,7 +36,7 @@ int mp_2expt(mp_int *a, int b) a->used = (b / DIGIT_BIT) + 1; /* put the single bit in its place */ - a->dp[b / DIGIT_BIT] = ((mp_digit)1) << (b % DIGIT_BIT); + a->dp[b / DIGIT_BIT] = (mp_digit)1 << (mp_digit)(b % DIGIT_BIT); return MP_OKAY; } diff --git a/libtommath/bn_mp_clamp.c b/libtommath/bn_mp_clamp.c index 3853914..79a5b20 100644 --- a/libtommath/bn_mp_clamp.c +++ b/libtommath/bn_mp_clamp.c @@ -27,7 +27,7 @@ void mp_clamp(mp_int *a) /* decrease used while the most significant digit is * zero. */ - while ((a->used > 0) && (a->dp[a->used - 1] == 0)) { + while ((a->used > 0) && (a->dp[a->used - 1] == 0u)) { --(a->used); } diff --git a/libtommath/bn_mp_clear_multi.c b/libtommath/bn_mp_clear_multi.c index 284fab8..ac3949a 100644 --- a/libtommath/bn_mp_clear_multi.c +++ b/libtommath/bn_mp_clear_multi.c @@ -14,6 +14,7 @@ * * Tom St Denis, tstdenis82@gmail.com, http://libtom.org */ + #include void mp_clear_multi(mp_int *mp, ...) diff --git a/libtommath/bn_mp_cnt_lsb.c b/libtommath/bn_mp_cnt_lsb.c index 9a94d3d..219c369 100644 --- a/libtommath/bn_mp_cnt_lsb.c +++ b/libtommath/bn_mp_cnt_lsb.c @@ -31,17 +31,17 @@ int mp_cnt_lsb(const mp_int *a) } /* scan lower digits until non-zero */ - for (x = 0; (x < a->used) && (a->dp[x] == 0); x++) {} + for (x = 0; (x < a->used) && (a->dp[x] == 0u); x++) {} q = a->dp[x]; x *= DIGIT_BIT; /* now scan this digit until a 1 is found */ - if ((q & 1) == 0) { + if ((q & 1u) == 0u) { do { - qq = q & 15; + qq = q & 15u; x += lnz[qq]; q >>= 4; - } while (qq == 0); + } while (qq == 0u); } return x; } diff --git a/libtommath/bn_mp_count_bits.c b/libtommath/bn_mp_count_bits.c index 7424581..4530c92 100644 --- a/libtommath/bn_mp_count_bits.c +++ b/libtommath/bn_mp_count_bits.c @@ -31,9 +31,9 @@ int mp_count_bits(const mp_int *a) /* take the last digit and count the bits in it */ q = a->dp[a->used - 1]; - while (q > ((mp_digit) 0)) { + while (q > (mp_digit)0) { ++r; - q >>= ((mp_digit) 1); + q >>= (mp_digit)1; } return r; } diff --git a/libtommath/bn_mp_div.c b/libtommath/bn_mp_div.c index dbfdc03..f64f485 100644 --- a/libtommath/bn_mp_div.c +++ b/libtommath/bn_mp_div.c @@ -47,7 +47,7 @@ int mp_div(const mp_int *a, const mp_int *b, mp_int *c, mp_int *d) } - mp_set(&tq, 1); + mp_set(&tq, 1uL); n = mp_count_bits(a) - mp_count_bits(b); if (((res = mp_abs(a, &ta)) != MP_OKAY) || ((res = mp_abs(b, &tb)) != MP_OKAY) || @@ -150,8 +150,8 @@ int mp_div(const mp_int *a, const mp_int *b, mp_int *c, mp_int *d) /* normalize both x and y, ensure that y >= b/2, [b == 2**DIGIT_BIT] */ norm = mp_count_bits(&y) % DIGIT_BIT; - if (norm < (int)(DIGIT_BIT-1)) { - norm = (DIGIT_BIT-1) - norm; + if (norm < (DIGIT_BIT - 1)) { + norm = (DIGIT_BIT - 1) - norm; if ((res = mp_mul_2d(&x, norm, &x)) != MP_OKAY) { goto LBL_Y; } @@ -190,16 +190,16 @@ int mp_div(const mp_int *a, const mp_int *b, mp_int *c, mp_int *d) /* step 3.1 if xi == yt then set q{i-t-1} to b-1, * otherwise set q{i-t-1} to (xi*b + x{i-1})/yt */ if (x.dp[i] == y.dp[t]) { - q.dp[(i - t) - 1] = ((((mp_digit)1) << DIGIT_BIT) - 1); + q.dp[(i - t) - 1] = ((mp_digit)1 << (mp_digit)DIGIT_BIT) - (mp_digit)1; } else { mp_word tmp; - tmp = ((mp_word) x.dp[i]) << ((mp_word) DIGIT_BIT); - tmp |= ((mp_word) x.dp[i - 1]); - tmp /= ((mp_word) y.dp[t]); - if (tmp > (mp_word) MP_MASK) { + tmp = (mp_word)x.dp[i] << (mp_word)DIGIT_BIT; + tmp |= (mp_word)x.dp[i - 1]; + tmp /= (mp_word)y.dp[t]; + if (tmp > (mp_word)MP_MASK) { tmp = MP_MASK; } - q.dp[(i - t) - 1] = (mp_digit)(tmp & (mp_word)(MP_MASK)); + q.dp[(i - t) - 1] = (mp_digit)(tmp & (mp_word)MP_MASK); } /* while (q{i-t-1} * (yt * b + y{t-1})) > @@ -207,13 +207,13 @@ int mp_div(const mp_int *a, const mp_int *b, mp_int *c, mp_int *d) do q{i-t-1} -= 1; */ - q.dp[(i - t) - 1] = (q.dp[(i - t) - 1] + 1) & MP_MASK; + q.dp[(i - t) - 1] = (q.dp[(i - t) - 1] + 1uL) & (mp_digit)MP_MASK; do { - q.dp[(i - t) - 1] = (q.dp[(i - t) - 1] - 1) & MP_MASK; + q.dp[(i - t) - 1] = (q.dp[(i - t) - 1] - 1uL) & (mp_digit)MP_MASK; /* find left hand */ mp_zero(&t1); - t1.dp[0] = ((t - 1) < 0) ? 0 : y.dp[t - 1]; + t1.dp[0] = ((t - 1) < 0) ? 0u : y.dp[t - 1]; t1.dp[1] = y.dp[t]; t1.used = 2; if ((res = mp_mul_d(&t1, q.dp[(i - t) - 1], &t1)) != MP_OKAY) { @@ -221,8 +221,8 @@ int mp_div(const mp_int *a, const mp_int *b, mp_int *c, mp_int *d) } /* find right hand */ - t2.dp[0] = ((i - 2) < 0) ? 0 : x.dp[i - 2]; - t2.dp[1] = ((i - 1) < 0) ? 0 : x.dp[i - 1]; + t2.dp[0] = ((i - 2) < 0) ? 0u : x.dp[i - 2]; + t2.dp[1] = ((i - 1) < 0) ? 0u : x.dp[i - 1]; t2.dp[2] = x.dp[i]; t2.used = 3; } while (mp_cmp_mag(&t1, &t2) == MP_GT); @@ -252,7 +252,7 @@ int mp_div(const mp_int *a, const mp_int *b, mp_int *c, mp_int *d) goto LBL_Y; } - q.dp[(i - t) - 1] = (q.dp[(i - t) - 1] - 1UL) & MP_MASK; + q.dp[(i - t) - 1] = (q.dp[(i - t) - 1] - 1uL) & MP_MASK; } } diff --git a/libtommath/bn_mp_div_2.c b/libtommath/bn_mp_div_2.c index edc8982..2907a1b 100644 --- a/libtommath/bn_mp_div_2.c +++ b/libtommath/bn_mp_div_2.c @@ -42,7 +42,7 @@ int mp_div_2(const mp_int *a, mp_int *b) r = 0; for (x = b->used - 1; x >= 0; x--) { /* get the carry for the next iteration */ - rr = *tmpa & 1; + rr = *tmpa & 1u; /* shift the current digit, add in carry and store */ *tmpb-- = (*tmpa-- >> 1) | (r << (DIGIT_BIT - 1)); diff --git a/libtommath/bn_mp_div_2d.c b/libtommath/bn_mp_div_2d.c index eae3498..aeaa8f2 100644 --- a/libtommath/bn_mp_div_2d.c +++ b/libtommath/bn_mp_div_2d.c @@ -44,20 +44,20 @@ int mp_div_2d(const mp_int *a, int b, mp_int *c, mp_int *d) } /* shift by as many digits in the bit count */ - if (b >= (int)DIGIT_BIT) { + if (b >= DIGIT_BIT) { mp_rshd(c, b / DIGIT_BIT); } /* shift any bit count < DIGIT_BIT */ D = (mp_digit)(b % DIGIT_BIT); - if (D != 0) { + if (D != 0u) { mp_digit *tmpc, mask, shift; /* mask */ - mask = (((mp_digit)1) << D) - 1; + mask = ((mp_digit)1 << D) - 1uL; /* shift for lsb */ - shift = DIGIT_BIT - D; + shift = (mp_digit)DIGIT_BIT - D; /* alias */ tmpc = c->dp + (c->used - 1); diff --git a/libtommath/bn_mp_div_3.c b/libtommath/bn_mp_div_3.c index 9cc8caa..9d41793 100644 --- a/libtommath/bn_mp_div_3.c +++ b/libtommath/bn_mp_div_3.c @@ -24,7 +24,7 @@ int mp_div_3(const mp_int *a, mp_int *c, mp_digit *d) int res, ix; /* b = 2**DIGIT_BIT / 3 */ - b = (((mp_word)1) << ((mp_word)DIGIT_BIT)) / ((mp_word)3); + b = ((mp_word)1 << (mp_word)DIGIT_BIT) / (mp_word)3; if ((res = mp_init_size(&q, a->used)) != MP_OKAY) { return res; @@ -34,11 +34,11 @@ int mp_div_3(const mp_int *a, mp_int *c, mp_digit *d) q.sign = a->sign; w = 0; for (ix = a->used - 1; ix >= 0; ix--) { - w = (w << ((mp_word)DIGIT_BIT)) | ((mp_word)a->dp[ix]); + w = (w << (mp_word)DIGIT_BIT) | (mp_word)a->dp[ix]; - if (w >= 3) { + if (w >= 3u) { /* multiply w by [1/3] */ - t = (w * ((mp_word)b)) >> ((mp_word)DIGIT_BIT); + t = (w * (mp_word)b) >> (mp_word)DIGIT_BIT; /* now subtract 3 * [w/3] from w, to get the remainder */ w -= t+t+t; @@ -46,9 +46,9 @@ int mp_div_3(const mp_int *a, mp_int *c, mp_digit *d) /* fixup the remainder as required since * the optimization is not exact. */ - while (w >= 3) { - t += 1; - w -= 3; + while (w >= 3u) { + t += 1u; + w -= 3u; } } else { t = 0; diff --git a/libtommath/bn_mp_div_d.c b/libtommath/bn_mp_div_d.c index db4a0a2..2124bcc 100644 --- a/libtommath/bn_mp_div_d.c +++ b/libtommath/bn_mp_div_d.c @@ -20,12 +20,12 @@ static int s_is_power_of_two(mp_digit b, int *p) int x; /* fast return if no power of two */ - if ((b == 0) || ((b & (b-1)) != 0)) { + if ((b == 0u) || ((b & (b-1u)) != 0u)) { return 0; } for (x = 0; x < DIGIT_BIT; x++) { - if (b == (((mp_digit)1)<dp[0] & ((((mp_digit)1)<dp[0] & (((mp_digit)1<<(mp_digit)ix) - 1uL); } if (c != NULL) { return mp_div_2d(a, ix, c, NULL); @@ -70,7 +70,7 @@ int mp_div_d(const mp_int *a, mp_digit b, mp_int *c, mp_digit *d) #ifdef BN_MP_DIV_3_C /* three? */ - if (b == 3) { + if (b == 3u) { return mp_div_3(a, c, d); } #endif @@ -84,15 +84,15 @@ int mp_div_d(const mp_int *a, mp_digit b, mp_int *c, mp_digit *d) q.sign = a->sign; w = 0; for (ix = a->used - 1; ix >= 0; ix--) { - w = (w << ((mp_word)DIGIT_BIT)) | ((mp_word)a->dp[ix]); + w = (w << (mp_word)DIGIT_BIT) | (mp_word)a->dp[ix]; if (w >= b) { t = (mp_digit)(w / b); - w -= ((mp_word)t) * ((mp_word)b); + w -= (mp_word)t * (mp_word)b; } else { t = 0; } - q.dp[ix] = (mp_digit)t; + q.dp[ix] = t; } if (d != NULL) { diff --git a/libtommath/bn_mp_dr_reduce.c b/libtommath/bn_mp_dr_reduce.c index 1ccb669..d677b03 100644 --- a/libtommath/bn_mp_dr_reduce.c +++ b/libtommath/bn_mp_dr_reduce.c @@ -61,7 +61,7 @@ top: /* compute (x mod B**m) + k * [x/B**m] inline and inplace */ for (i = 0; i < m; i++) { - r = (((mp_word)*tmpx2++) * (mp_word)k) + *tmpx1 + mu; + r = ((mp_word)*tmpx2++ * (mp_word)k) + *tmpx1 + mu; *tmpx1++ = (mp_digit)(r & MP_MASK); mu = (mp_digit)(r >> ((mp_word)DIGIT_BIT)); } diff --git a/libtommath/bn_mp_dr_setup.c b/libtommath/bn_mp_dr_setup.c index af0e213..32aa582 100644 --- a/libtommath/bn_mp_dr_setup.c +++ b/libtommath/bn_mp_dr_setup.c @@ -21,7 +21,7 @@ void mp_dr_setup(const mp_int *a, mp_digit *d) /* the casts are required if DIGIT_BIT is one less than * the number of bits in a mp_digit [e.g. DIGIT_BIT==31] */ - *d = (mp_digit)((((mp_word)1) << ((mp_word)DIGIT_BIT)) - ((mp_word)a->dp[0])); + *d = (mp_digit)(((mp_word)1 << (mp_word)DIGIT_BIT) - (mp_word)a->dp[0]); } #endif diff --git a/libtommath/bn_mp_export.c b/libtommath/bn_mp_export.c index 4276f4f..92a85d5 100644 --- a/libtommath/bn_mp_export.c +++ b/libtommath/bn_mp_export.c @@ -38,33 +38,33 @@ int mp_export(void *rop, size_t *countp, int order, size_t size, } lint; lint.i = 0x01020304; - endian = (lint.c[0] == 4) ? -1 : 1; + endian = (lint.c[0] == '\x04') ? -1 : 1; } - odd_nails = (nails % 8); + odd_nails = (nails % 8u); odd_nail_mask = 0xff; for (i = 0; i < odd_nails; ++i) { - odd_nail_mask ^= (1 << (7 - i)); + odd_nail_mask ^= (unsigned char)(1u << (7u - i)); } - nail_bytes = nails / 8; + nail_bytes = nails / 8u; - bits = mp_count_bits(&t); - count = (bits / ((size * 8) - nails)) + (((bits % ((size * 8) - nails)) != 0) ? 1 : 0); + bits = (size_t)mp_count_bits(&t); + count = (bits / ((size * 8u) - nails)) + (((bits % ((size * 8u) - nails)) != 0u) ? 1u : 0u); for (i = 0; i < count; ++i) { for (j = 0; j < size; ++j) { unsigned char *byte = (unsigned char *)rop + - (((order == -1) ? i : ((count - 1) - i)) * size) + - ((endian == -1) ? j : ((size - 1) - j)); + (((order == -1) ? i : ((count - 1u) - i)) * size) + + ((endian == -1) ? j : ((size - 1u) - j)); if (j >= (size - nail_bytes)) { *byte = 0; continue; } - *byte = (unsigned char)((j == ((size - nail_bytes) - 1)) ? (t.dp[0] & odd_nail_mask) : (t.dp[0] & 0xFF)); + *byte = (unsigned char)((j == ((size - nail_bytes) - 1u)) ? (t.dp[0] & odd_nail_mask) : (t.dp[0] & 0xFFuL)); - if ((result = mp_div_2d(&t, ((j == ((size - nail_bytes) - 1)) ? (8 - odd_nails) : 8), &t, NULL)) != MP_OKAY) { + if ((result = mp_div_2d(&t, (j == ((size - nail_bytes) - 1u)) ? (int)(8u - odd_nails) : 8, &t, NULL)) != MP_OKAY) { mp_clear(&t); return result; } diff --git a/libtommath/bn_mp_expt_d_ex.c b/libtommath/bn_mp_expt_d_ex.c index 99319a5..d363d59 100644 --- a/libtommath/bn_mp_expt_d_ex.c +++ b/libtommath/bn_mp_expt_d_ex.c @@ -28,12 +28,12 @@ int mp_expt_d_ex(const mp_int *a, mp_digit b, mp_int *c, int fast) } /* set initial result */ - mp_set(c, 1); + mp_set(c, 1uL); if (fast != 0) { - while (b > 0) { + while (b > 0u) { /* if the bit is set multiply */ - if ((b & 1) != 0) { + if ((b & 1u) != 0u) { if ((res = mp_mul(c, &g, c)) != MP_OKAY) { mp_clear(&g); return res; @@ -41,7 +41,7 @@ int mp_expt_d_ex(const mp_int *a, mp_digit b, mp_int *c, int fast) } /* square */ - if (b > 1) { + if (b > 1u) { if ((res = mp_sqr(&g, &g)) != MP_OKAY) { mp_clear(&g); return res; @@ -52,7 +52,7 @@ int mp_expt_d_ex(const mp_int *a, mp_digit b, mp_int *c, int fast) b >>= 1; } } else { - for (x = 0; x < DIGIT_BIT; x++) { + for (x = 0; x < (unsigned)DIGIT_BIT; x++) { /* square */ if ((res = mp_sqr(c, c)) != MP_OKAY) { mp_clear(&g); @@ -60,7 +60,7 @@ int mp_expt_d_ex(const mp_int *a, mp_digit b, mp_int *c, int fast) } /* if the bit is set multiply */ - if ((b & (mp_digit)(((mp_digit)1) << (DIGIT_BIT - 1))) != 0) { + if ((b & ((mp_digit)1 << (DIGIT_BIT - 1))) != 0u) { if ((res = mp_mul(c, &g, c)) != MP_OKAY) { mp_clear(&g); return res; diff --git a/libtommath/bn_mp_exptmod_fast.c b/libtommath/bn_mp_exptmod_fast.c index 4a188d0..52d4a55 100644 --- a/libtommath/bn_mp_exptmod_fast.c +++ b/libtommath/bn_mp_exptmod_fast.c @@ -39,7 +39,7 @@ int mp_exptmod_fast(const mp_int *G, const mp_int *X, const mp_int *P, mp_int *Y * one of many reduction algorithms without modding the guts of * the code with if statements everywhere. */ - int (*redux)(mp_int *,const mp_int *,mp_digit); + int (*redux)(mp_int *x, const mp_int *n, mp_digit rho); /* find window size */ x = mp_count_bits(X); @@ -96,7 +96,7 @@ int mp_exptmod_fast(const mp_int *G, const mp_int *X, const mp_int *P, mp_int *Y /* automatically pick the comba one if available (saves quite a few calls/ifs) */ #ifdef BN_FAST_MP_MONTGOMERY_REDUCE_C - if ((((P->used * 2) + 1) < MP_WARRAY) && + if ((((P->used * 2) + 1) < (int)MP_WARRAY) && (P->used < (1 << ((CHAR_BIT * sizeof(mp_word)) - (2 * DIGIT_BIT))))) { redux = fast_mp_montgomery_reduce; } else @@ -160,7 +160,7 @@ int mp_exptmod_fast(const mp_int *G, const mp_int *X, const mp_int *P, mp_int *Y goto LBL_RES; #endif } else { - mp_set(&res, 1); + mp_set(&res, 1uL); if ((err = mp_mod(G, P, &M[1])) != MP_OKAY) { goto LBL_RES; } diff --git a/libtommath/bn_mp_exteuclid.c b/libtommath/bn_mp_exteuclid.c index 08e5ff2..29bad83 100644 --- a/libtommath/bn_mp_exteuclid.c +++ b/libtommath/bn_mp_exteuclid.c @@ -28,76 +28,76 @@ int mp_exteuclid(const mp_int *a, const mp_int *b, mp_int *U1, mp_int *U2, mp_in } /* initialize, (u1,u2,u3) = (1,0,a) */ - mp_set(&u1, 1); - if ((err = mp_copy(a, &u3)) != MP_OKAY) { + mp_set(&u1, 1uL); + if ((err = mp_copy(a, &u3)) != MP_OKAY) { goto LBL_ERR; } /* initialize, (v1,v2,v3) = (0,1,b) */ - mp_set(&v2, 1); - if ((err = mp_copy(b, &v3)) != MP_OKAY) { + mp_set(&v2, 1uL); + if ((err = mp_copy(b, &v3)) != MP_OKAY) { goto LBL_ERR; } /* loop while v3 != 0 */ while (mp_iszero(&v3) == MP_NO) { /* q = u3/v3 */ - if ((err = mp_div(&u3, &v3, &q, NULL)) != MP_OKAY) { + if ((err = mp_div(&u3, &v3, &q, NULL)) != MP_OKAY) { goto LBL_ERR; } /* (t1,t2,t3) = (u1,u2,u3) - (v1,v2,v3)q */ - if ((err = mp_mul(&v1, &q, &tmp)) != MP_OKAY) { + if ((err = mp_mul(&v1, &q, &tmp)) != MP_OKAY) { goto LBL_ERR; } - if ((err = mp_sub(&u1, &tmp, &t1)) != MP_OKAY) { + if ((err = mp_sub(&u1, &tmp, &t1)) != MP_OKAY) { goto LBL_ERR; } - if ((err = mp_mul(&v2, &q, &tmp)) != MP_OKAY) { + if ((err = mp_mul(&v2, &q, &tmp)) != MP_OKAY) { goto LBL_ERR; } - if ((err = mp_sub(&u2, &tmp, &t2)) != MP_OKAY) { + if ((err = mp_sub(&u2, &tmp, &t2)) != MP_OKAY) { goto LBL_ERR; } - if ((err = mp_mul(&v3, &q, &tmp)) != MP_OKAY) { + if ((err = mp_mul(&v3, &q, &tmp)) != MP_OKAY) { goto LBL_ERR; } - if ((err = mp_sub(&u3, &tmp, &t3)) != MP_OKAY) { + if ((err = mp_sub(&u3, &tmp, &t3)) != MP_OKAY) { goto LBL_ERR; } /* (u1,u2,u3) = (v1,v2,v3) */ - if ((err = mp_copy(&v1, &u1)) != MP_OKAY) { + if ((err = mp_copy(&v1, &u1)) != MP_OKAY) { goto LBL_ERR; } - if ((err = mp_copy(&v2, &u2)) != MP_OKAY) { + if ((err = mp_copy(&v2, &u2)) != MP_OKAY) { goto LBL_ERR; } - if ((err = mp_copy(&v3, &u3)) != MP_OKAY) { + if ((err = mp_copy(&v3, &u3)) != MP_OKAY) { goto LBL_ERR; } /* (v1,v2,v3) = (t1,t2,t3) */ - if ((err = mp_copy(&t1, &v1)) != MP_OKAY) { + if ((err = mp_copy(&t1, &v1)) != MP_OKAY) { goto LBL_ERR; } - if ((err = mp_copy(&t2, &v2)) != MP_OKAY) { + if ((err = mp_copy(&t2, &v2)) != MP_OKAY) { goto LBL_ERR; } - if ((err = mp_copy(&t3, &v3)) != MP_OKAY) { + if ((err = mp_copy(&t3, &v3)) != MP_OKAY) { goto LBL_ERR; } } /* make sure U3 >= 0 */ if (u3.sign == MP_NEG) { - if ((err = mp_neg(&u1, &u1)) != MP_OKAY) { + if ((err = mp_neg(&u1, &u1)) != MP_OKAY) { goto LBL_ERR; } - if ((err = mp_neg(&u2, &u2)) != MP_OKAY) { + if ((err = mp_neg(&u2, &u2)) != MP_OKAY) { goto LBL_ERR; } - if ((err = mp_neg(&u3, &u3)) != MP_OKAY) { + if ((err = mp_neg(&u3, &u3)) != MP_OKAY) { goto LBL_ERR; } } diff --git a/libtommath/bn_mp_fread.c b/libtommath/bn_mp_fread.c index d0de595..6922183 100644 --- a/libtommath/bn_mp_fread.c +++ b/libtommath/bn_mp_fread.c @@ -20,13 +20,14 @@ int mp_fread(mp_int *a, int radix, FILE *stream) { int err, ch, neg, y; + unsigned pos; /* clear a */ mp_zero(a); /* if first digit is - then set negative */ ch = fgetc(stream); - if (ch == '-') { + if (ch == (int)'-') { neg = MP_NEG; ch = fgetc(stream); } else { @@ -34,27 +35,28 @@ int mp_fread(mp_int *a, int radix, FILE *stream) } for (;;) { - /* find y in the radix map */ - for (y = 0; y < radix; y++) { - if (mp_s_rmap[y] == ch) { - break; - } + pos = (unsigned)(ch - (int)'('); + if (mp_s_rmap_reverse_sz < pos) { + break; } - if (y == radix) { + + y = (int)mp_s_rmap_reverse[pos]; + + if ((y == 0xff) || (y >= radix)) { break; } /* shift up and add */ - if ((err = mp_mul_d(a, radix, a)) != MP_OKAY) { + if ((err = mp_mul_d(a, (mp_digit)radix, a)) != MP_OKAY) { return err; } - if ((err = mp_add_d(a, y, a)) != MP_OKAY) { + if ((err = mp_add_d(a, (mp_digit)y, a)) != MP_OKAY) { return err; } ch = fgetc(stream); } - if (mp_cmp_d(a, 0) != MP_EQ) { + if (mp_cmp_d(a, 0uL) != MP_EQ) { a->sign = neg; } diff --git a/libtommath/bn_mp_fwrite.c b/libtommath/bn_mp_fwrite.c index 829dd4a..8541bc7 100644 --- a/libtommath/bn_mp_fwrite.c +++ b/libtommath/bn_mp_fwrite.c @@ -25,7 +25,7 @@ int mp_fwrite(const mp_int *a, int radix, FILE *stream) return err; } - buf = OPT_CAST(char) XMALLOC(len); + buf = OPT_CAST(char) XMALLOC((size_t)len); if (buf == NULL) { return MP_MEM; } @@ -36,7 +36,7 @@ int mp_fwrite(const mp_int *a, int radix, FILE *stream) } for (x = 0; x < len; x++) { - if (fputc(buf[x], stream) == EOF) { + if (fputc((int)buf[x], stream) == EOF) { XFREE(buf); return MP_VAL; } diff --git a/libtommath/bn_mp_get_int.c b/libtommath/bn_mp_get_int.c index f4a347f..d99a0a0 100644 --- a/libtommath/bn_mp_get_int.c +++ b/libtommath/bn_mp_get_int.c @@ -26,7 +26,7 @@ unsigned long mp_get_int(const mp_int *a) } /* get number of digits of the lsb we have to read */ - i = MIN(a->used, (int)(((sizeof(unsigned long) * CHAR_BIT) + DIGIT_BIT - 1) / DIGIT_BIT)) - 1; + i = MIN(a->used, ((((int)sizeof(unsigned long) * CHAR_BIT) + DIGIT_BIT - 1) / DIGIT_BIT)) - 1; /* get most significant digit of result */ res = DIGIT(a, i); diff --git a/libtommath/bn_mp_get_long.c b/libtommath/bn_mp_get_long.c index 3fc7c35..9ec2664 100644 --- a/libtommath/bn_mp_get_long.c +++ b/libtommath/bn_mp_get_long.c @@ -26,7 +26,7 @@ unsigned long mp_get_long(const mp_int *a) } /* get number of digits of the lsb we have to read */ - i = MIN(a->used, (int)(((sizeof(unsigned long) * CHAR_BIT) + DIGIT_BIT - 1) / DIGIT_BIT)) - 1; + i = MIN(a->used, ((((int)sizeof(unsigned long) * CHAR_BIT) + DIGIT_BIT - 1) / DIGIT_BIT)) - 1; /* get most significant digit of result */ res = DIGIT(a, i); diff --git a/libtommath/bn_mp_get_long_long.c b/libtommath/bn_mp_get_long_long.c index 838c3c3..ffde373 100644 --- a/libtommath/bn_mp_get_long_long.c +++ b/libtommath/bn_mp_get_long_long.c @@ -26,7 +26,7 @@ unsigned long long mp_get_long_long(const mp_int *a) } /* get number of digits of the lsb we have to read */ - i = MIN(a->used, (int)(((sizeof(unsigned long long) * CHAR_BIT) + DIGIT_BIT - 1) / DIGIT_BIT)) - 1; + i = MIN(a->used, ((((int)sizeof(unsigned long long) * CHAR_BIT) + DIGIT_BIT - 1) / DIGIT_BIT)) - 1; /* get most significant digit of result */ res = DIGIT(a, i); diff --git a/libtommath/bn_mp_grow.c b/libtommath/bn_mp_grow.c index 0030931..60f8f32 100644 --- a/libtommath/bn_mp_grow.c +++ b/libtommath/bn_mp_grow.c @@ -32,7 +32,7 @@ int mp_grow(mp_int *a, int size) * in case the operation failed we don't want * to overwrite the dp member of a. */ - tmp = OPT_CAST(mp_digit) XREALLOC(a->dp, sizeof(mp_digit) * size); + tmp = OPT_CAST(mp_digit) XREALLOC(a->dp, sizeof(mp_digit) * (size_t)size); if (tmp == NULL) { /* reallocation failed but "a" is still valid [can be freed] */ return MP_MEM; diff --git a/libtommath/bn_mp_import.c b/libtommath/bn_mp_import.c index afd735e..9bbd215 100644 --- a/libtommath/bn_mp_import.c +++ b/libtommath/bn_mp_import.c @@ -34,27 +34,27 @@ int mp_import(mp_int *rop, size_t count, int order, size_t size, } lint; lint.i = 0x01020304; - endian = (lint.c[0] == 4) ? -1 : 1; + endian = (lint.c[0] == '\x04') ? -1 : 1; } - odd_nails = (nails % 8); + odd_nails = (nails % 8u); odd_nail_mask = 0xff; for (i = 0; i < odd_nails; ++i) { - odd_nail_mask ^= (1 << (7 - i)); + odd_nail_mask ^= (unsigned char)(1u << (7u - i)); } - nail_bytes = nails / 8; + nail_bytes = nails / 8u; for (i = 0; i < count; ++i) { for (j = 0; j < (size - nail_bytes); ++j) { unsigned char byte = *((unsigned char *)op + - (((order == 1) ? i : ((count - 1) - i)) * size) + - ((endian == 1) ? (j + nail_bytes) : (((size - 1) - j) - nail_bytes))); + (((order == 1) ? i : ((count - 1u) - i)) * size) + + ((endian == 1) ? (j + nail_bytes) : (((size - 1u) - j) - nail_bytes))); - if ((result = mp_mul_2d(rop, ((j == 0) ? (8 - odd_nails) : 8), rop)) != MP_OKAY) { + if ((result = mp_mul_2d(rop, (j == 0u) ? (int)(8u - odd_nails) : 8, rop)) != MP_OKAY) { return result; } - rop->dp[0] |= (j == 0) ? (byte & odd_nail_mask) : byte; + rop->dp[0] |= (j == 0u) ? (mp_digit)(byte & odd_nail_mask) : (mp_digit)byte; rop->used += 1; } } diff --git a/libtommath/bn_mp_init.c b/libtommath/bn_mp_init.c index 0556aeb..ad630e3 100644 --- a/libtommath/bn_mp_init.c +++ b/libtommath/bn_mp_init.c @@ -21,7 +21,7 @@ int mp_init(mp_int *a) int i; /* allocate memory required and clear it */ - a->dp = OPT_CAST(mp_digit) XMALLOC(sizeof(mp_digit) * MP_PREC); + a->dp = OPT_CAST(mp_digit) XMALLOC(sizeof(mp_digit) * (size_t)MP_PREC); if (a->dp == NULL) { return MP_MEM; } diff --git a/libtommath/bn_mp_init_multi.c b/libtommath/bn_mp_init_multi.c index 0da7803..9ed777c 100644 --- a/libtommath/bn_mp_init_multi.c +++ b/libtommath/bn_mp_init_multi.c @@ -14,6 +14,7 @@ * * Tom St Denis, tstdenis82@gmail.com, http://libtom.org */ + #include int mp_init_multi(mp_int *mp, ...) diff --git a/libtommath/bn_mp_init_size.c b/libtommath/bn_mp_init_size.c index 623a03f..35713ac 100644 --- a/libtommath/bn_mp_init_size.c +++ b/libtommath/bn_mp_init_size.c @@ -24,7 +24,7 @@ int mp_init_size(mp_int *a, int size) size += (MP_PREC * 2) - (size % MP_PREC); /* alloc mem */ - a->dp = OPT_CAST(mp_digit) XMALLOC(sizeof(mp_digit) * size); + a->dp = OPT_CAST(mp_digit) XMALLOC(sizeof(mp_digit) * (size_t)size); if (a->dp == NULL) { return MP_MEM; } diff --git a/libtommath/bn_mp_invmod.c b/libtommath/bn_mp_invmod.c index 525493a..96717ea 100644 --- a/libtommath/bn_mp_invmod.c +++ b/libtommath/bn_mp_invmod.c @@ -18,14 +18,14 @@ /* hac 14.61, pp608 */ int mp_invmod(const mp_int *a, const mp_int *b, mp_int *c) { - /* b cannot be negative */ - if ((b->sign == MP_NEG) || (mp_iszero(b) == MP_YES)) { + /* b cannot be negative and has to be >1 */ + if ((b->sign == MP_NEG) || (mp_cmp_d(b, 1uL) != MP_GT)) { return MP_VAL; } #ifdef BN_FAST_MP_INVMOD_C /* if the modulus is odd we can use a faster routine instead */ - if ((mp_isodd(b) == MP_YES) && (mp_cmp_d(b, 1) != MP_EQ)) { + if ((mp_isodd(b) == MP_YES)) { return fast_mp_invmod(a, b, c); } #endif diff --git a/libtommath/bn_mp_invmod_slow.c b/libtommath/bn_mp_invmod_slow.c index 2bb5196..360f161 100644 --- a/libtommath/bn_mp_invmod_slow.c +++ b/libtommath/bn_mp_invmod_slow.c @@ -53,8 +53,8 @@ int mp_invmod_slow(const mp_int *a, const mp_int *b, mp_int *c) if ((res = mp_copy(&y, &v)) != MP_OKAY) { goto LBL_ERR; } - mp_set(&A, 1); - mp_set(&D, 1); + mp_set(&A, 1uL); + mp_set(&D, 1uL); top: /* 4. while u is even do */ @@ -143,13 +143,13 @@ top: /* now a = C, b = D, gcd == g*v */ /* if v != 1 then there is no inverse */ - if (mp_cmp_d(&v, 1) != MP_EQ) { + if (mp_cmp_d(&v, 1uL) != MP_EQ) { res = MP_VAL; goto LBL_ERR; } /* if its too low */ - while (mp_cmp_d(&C, 0) == MP_LT) { + while (mp_cmp_d(&C, 0uL) == MP_LT) { if ((res = mp_add(&C, b, &C)) != MP_OKAY) { goto LBL_ERR; } diff --git a/libtommath/bn_mp_is_square.c b/libtommath/bn_mp_is_square.c index dd5150e..329d727 100644 --- a/libtommath/bn_mp_is_square.c +++ b/libtommath/bn_mp_is_square.c @@ -58,15 +58,15 @@ int mp_is_square(const mp_int *arg, int *ret) } /* First check mod 128 (suppose that DIGIT_BIT is at least 7) */ - if (rem_128[127 & DIGIT(arg, 0)] == 1) { + if (rem_128[127u & DIGIT(arg, 0)] == (char)1) { return MP_OKAY; } /* Next check mod 105 (3*5*7) */ - if ((res = mp_mod_d(arg, 105, &c)) != MP_OKAY) { + if ((res = mp_mod_d(arg, 105uL, &c)) != MP_OKAY) { return res; } - if (rem_105[c] == 1) { + if (rem_105[c] == (char)1) { return MP_OKAY; } @@ -82,13 +82,13 @@ int mp_is_square(const mp_int *arg, int *ret) * free "t" so the easiest way is to goto ERR. We know that res * is already equal to MP_OKAY from the mp_mod call */ - if (((1L<<(r%11)) & 0x5C4L) != 0L) goto ERR; - if (((1L<<(r%13)) & 0x9E4L) != 0L) goto ERR; - if (((1L<<(r%17)) & 0x5CE8L) != 0L) goto ERR; - if (((1L<<(r%19)) & 0x4F50CL) != 0L) goto ERR; - if (((1L<<(r%23)) & 0x7ACCA0L) != 0L) goto ERR; - if (((1L<<(r%29)) & 0xC2EDD0CL) != 0L) goto ERR; - if (((1L<<(r%31)) & 0x6DE2B848L) != 0L) goto ERR; + if (((1uL<<(r%11uL)) & 0x5C4uL) != 0uL) goto ERR; + if (((1uL<<(r%13uL)) & 0x9E4uL) != 0uL) goto ERR; + if (((1uL<<(r%17uL)) & 0x5CE8uL) != 0uL) goto ERR; + if (((1uL<<(r%19uL)) & 0x4F50CuL) != 0uL) goto ERR; + if (((1uL<<(r%23uL)) & 0x7ACCA0uL) != 0uL) goto ERR; + if (((1uL<<(r%29uL)) & 0xC2EDD0CuL) != 0uL) goto ERR; + if (((1uL<<(r%31uL)) & 0x6DE2B848uL) != 0uL) goto ERR; /* Final check - is sqr(sqrt(arg)) == arg ? */ if ((res = mp_sqrt(arg, &t)) != MP_OKAY) { diff --git a/libtommath/bn_mp_jacobi.c b/libtommath/bn_mp_jacobi.c index c314c82..ef2e72f 100644 --- a/libtommath/bn_mp_jacobi.c +++ b/libtommath/bn_mp_jacobi.c @@ -32,14 +32,14 @@ int mp_jacobi(const mp_int *a, const mp_int *n, int *c) } /* if n <= 0 return MP_VAL */ - if (mp_cmp_d(n, 0) != MP_GT) { + if (mp_cmp_d(n, 0uL) != MP_GT) { return MP_VAL; } /* step 1. handle case of a == 0 */ if (mp_iszero(a) == MP_YES) { /* special case of a == 0 and n == 1 */ - if (mp_cmp_d(n, 1) == MP_EQ) { + if (mp_cmp_d(n, 1uL) == MP_EQ) { *c = 1; } else { *c = 0; @@ -48,7 +48,7 @@ int mp_jacobi(const mp_int *a, const mp_int *n, int *c) } /* step 2. if a == 1, return 1 */ - if (mp_cmp_d(a, 1) == MP_EQ) { + if (mp_cmp_d(a, 1uL) == MP_EQ) { *c = 1; return MP_OKAY; } @@ -72,26 +72,26 @@ int mp_jacobi(const mp_int *a, const mp_int *n, int *c) } /* step 4. if e is even set s=1 */ - if ((k & 1) == 0) { + if (((unsigned)k & 1u) == 0u) { s = 1; } else { /* else set s=1 if p = 1/7 (mod 8) or s=-1 if p = 3/5 (mod 8) */ - residue = n->dp[0] & 7; + residue = n->dp[0] & 7u; - if ((residue == 1) || (residue == 7)) { + if ((residue == 1u) || (residue == 7u)) { s = 1; - } else if ((residue == 3) || (residue == 5)) { + } else if ((residue == 3u) || (residue == 5u)) { s = -1; } } /* step 5. if p == 3 (mod 4) *and* a1 == 3 (mod 4) then s = -s */ - if (((n->dp[0] & 3) == 3) && ((a1.dp[0] & 3) == 3)) { + if (((n->dp[0] & 3u) == 3u) && ((a1.dp[0] & 3u) == 3u)) { s = -s; } /* if a1 == 1 we're done */ - if (mp_cmp_d(&a1, 1) == MP_EQ) { + if (mp_cmp_d(&a1, 1uL) == MP_EQ) { *c = s; } else { /* n1 = n mod a1 */ diff --git a/libtommath/bn_mp_lshd.c b/libtommath/bn_mp_lshd.c index 888989a..b49b545 100644 --- a/libtommath/bn_mp_lshd.c +++ b/libtommath/bn_mp_lshd.c @@ -24,6 +24,10 @@ int mp_lshd(mp_int *a, int b) if (b <= 0) { return MP_OKAY; } + /* no need to shift 0 around */ + if (mp_iszero(a) == MP_YES) { + return MP_OKAY; + } /* grow to fit the new digits */ if (a->alloc < (a->used + b)) { diff --git a/libtommath/bn_mp_mod_2d.c b/libtommath/bn_mp_mod_2d.c index 8e69757..7a74746 100644 --- a/libtommath/bn_mp_mod_2d.c +++ b/libtommath/bn_mp_mod_2d.c @@ -27,7 +27,7 @@ int mp_mod_2d(const mp_int *a, int b, mp_int *c) } /* if the modulus is larger than the value than return */ - if (b >= (int)(a->used * DIGIT_BIT)) { + if (b >= (a->used * DIGIT_BIT)) { res = mp_copy(a, c); return res; } @@ -43,7 +43,7 @@ int mp_mod_2d(const mp_int *a, int b, mp_int *c) } /* clear the digit that is not completely outside/inside the modulus */ c->dp[b / DIGIT_BIT] &= - (mp_digit)((((mp_digit) 1) << (((mp_digit) b) % DIGIT_BIT)) - ((mp_digit) 1)); + ((mp_digit)1 << (mp_digit)(b % DIGIT_BIT)) - (mp_digit)1; mp_clamp(c); return MP_OKAY; } diff --git a/libtommath/bn_mp_montgomery_calc_normalization.c b/libtommath/bn_mp_montgomery_calc_normalization.c index f2b0856..360e3e5 100644 --- a/libtommath/bn_mp_montgomery_calc_normalization.c +++ b/libtommath/bn_mp_montgomery_calc_normalization.c @@ -33,7 +33,7 @@ int mp_montgomery_calc_normalization(mp_int *a, const mp_int *b) return res; } } else { - mp_set(a, 1); + mp_set(a, 1uL); bits = 1; } diff --git a/libtommath/bn_mp_montgomery_reduce.c b/libtommath/bn_mp_montgomery_reduce.c index a38173e..e3a0eaa 100644 --- a/libtommath/bn_mp_montgomery_reduce.c +++ b/libtommath/bn_mp_montgomery_reduce.c @@ -28,9 +28,10 @@ int mp_montgomery_reduce(mp_int *x, const mp_int *n, mp_digit rho) * are fixed up in the inner loop. */ digs = (n->used * 2) + 1; - if ((digs < MP_WARRAY) && + if ((digs < (int)MP_WARRAY) && + (x->used <= (int)MP_WARRAY) && (n->used < - (1 << ((CHAR_BIT * sizeof(mp_word)) - (2 * DIGIT_BIT))))) { + (int)(1u << (((size_t)CHAR_BIT * sizeof(mp_word)) - (2u * (size_t)DIGIT_BIT))))) { return fast_mp_montgomery_reduce(x, n, rho); } @@ -72,19 +73,19 @@ int mp_montgomery_reduce(mp_int *x, const mp_int *n, mp_digit rho) for (iy = 0; iy < n->used; iy++) { /* compute product and sum */ r = ((mp_word)mu * (mp_word)*tmpn++) + - (mp_word) u + (mp_word) *tmpx; + (mp_word)u + (mp_word)*tmpx; /* get carry */ - u = (mp_digit)(r >> ((mp_word) DIGIT_BIT)); + u = (mp_digit)(r >> (mp_word)DIGIT_BIT); /* fix digit */ - *tmpx++ = (mp_digit)(r & ((mp_word) MP_MASK)); + *tmpx++ = (mp_digit)(r & (mp_word)MP_MASK); } /* At this point the ix'th digit of x should be zero */ /* propagate carries upwards as required*/ - while (u != 0) { + while (u != 0u) { *tmpx += u; u = *tmpx >> DIGIT_BIT; *tmpx++ &= MP_MASK; diff --git a/libtommath/bn_mp_montgomery_setup.c b/libtommath/bn_mp_montgomery_setup.c index 685ba51..75da42b 100644 --- a/libtommath/bn_mp_montgomery_setup.c +++ b/libtommath/bn_mp_montgomery_setup.c @@ -30,24 +30,24 @@ int mp_montgomery_setup(const mp_int *n, mp_digit *rho) */ b = n->dp[0]; - if ((b & 1) == 0) { + if ((b & 1u) == 0u) { return MP_VAL; } - x = (((b + 2) & 4) << 1) + b; /* here x*a==1 mod 2**4 */ - x *= 2 - (b * x); /* here x*a==1 mod 2**8 */ + x = (((b + 2u) & 4u) << 1) + b; /* here x*a==1 mod 2**4 */ + x *= 2u - (b * x); /* here x*a==1 mod 2**8 */ #if !defined(MP_8BIT) - x *= 2 - (b * x); /* here x*a==1 mod 2**16 */ + x *= 2u - (b * x); /* here x*a==1 mod 2**16 */ #endif #if defined(MP_64BIT) || !(defined(MP_8BIT) || defined(MP_16BIT)) - x *= 2 - (b * x); /* here x*a==1 mod 2**32 */ + x *= 2u - (b * x); /* here x*a==1 mod 2**32 */ #endif #ifdef MP_64BIT - x *= 2 - (b * x); /* here x*a==1 mod 2**64 */ + x *= 2u - (b * x); /* here x*a==1 mod 2**64 */ #endif /* rho = -1/m mod b */ - *rho = (mp_digit)(((mp_word)1 << ((mp_word) DIGIT_BIT)) - x) & MP_MASK; + *rho = (mp_digit)(((mp_word)1 << (mp_word)DIGIT_BIT) - x) & MP_MASK; return MP_OKAY; } diff --git a/libtommath/bn_mp_mul.c b/libtommath/bn_mp_mul.c index 71d523d..babb12b 100644 --- a/libtommath/bn_mp_mul.c +++ b/libtommath/bn_mp_mul.c @@ -43,9 +43,9 @@ int mp_mul(const mp_int *a, const mp_int *b, mp_int *c) int digs = a->used + b->used + 1; #ifdef BN_FAST_S_MP_MUL_DIGS_C - if ((digs < MP_WARRAY) && + if ((digs < (int)MP_WARRAY) && (MIN(a->used, b->used) <= - (1 << ((CHAR_BIT * sizeof(mp_word)) - (2 * DIGIT_BIT))))) { + (int)(1u << (((size_t)CHAR_BIT * sizeof(mp_word)) - (2u * (size_t)DIGIT_BIT))))) { res = fast_s_mp_mul_digs(a, b, c, digs); } else #endif diff --git a/libtommath/bn_mp_mul_2.c b/libtommath/bn_mp_mul_2.c index 1744681..7611536 100644 --- a/libtommath/bn_mp_mul_2.c +++ b/libtommath/bn_mp_mul_2.c @@ -46,10 +46,10 @@ int mp_mul_2(const mp_int *a, mp_int *b) /* get what will be the *next* carry bit from the * MSB of the current digit */ - rr = *tmpa >> ((mp_digit)(DIGIT_BIT - 1)); + rr = *tmpa >> (mp_digit)(DIGIT_BIT - 1); /* now shift up this digit, add in the carry [from the previous] */ - *tmpb++ = ((*tmpa++ << ((mp_digit)1)) | r) & MP_MASK; + *tmpb++ = ((*tmpa++ << 1uL) | r) & MP_MASK; /* copy the carry that would be from the source * digit into the next iteration @@ -58,7 +58,7 @@ int mp_mul_2(const mp_int *a, mp_int *b) } /* new leading digit? */ - if (r != 0) { + if (r != 0u) { /* add a MSB which is always 1 at this point */ *tmpb = 1; ++(b->used); diff --git a/libtommath/bn_mp_mul_2d.c b/libtommath/bn_mp_mul_2d.c index 4938e57..96aef85 100644 --- a/libtommath/bn_mp_mul_2d.c +++ b/libtommath/bn_mp_mul_2d.c @@ -28,14 +28,14 @@ int mp_mul_2d(const mp_int *a, int b, mp_int *c) } } - if (c->alloc < (int)(c->used + (b / DIGIT_BIT) + 1)) { + if (c->alloc < (c->used + (b / DIGIT_BIT) + 1)) { if ((res = mp_grow(c, c->used + (b / DIGIT_BIT) + 1)) != MP_OKAY) { return res; } } /* shift by as many digits in the bit count */ - if (b >= (int)DIGIT_BIT) { + if (b >= DIGIT_BIT) { if ((res = mp_lshd(c, b / DIGIT_BIT)) != MP_OKAY) { return res; } @@ -43,15 +43,15 @@ int mp_mul_2d(const mp_int *a, int b, mp_int *c) /* shift any bit count < DIGIT_BIT */ d = (mp_digit)(b % DIGIT_BIT); - if (d != 0) { + if (d != 0u) { mp_digit *tmpc, shift, mask, r, rr; int x; /* bitmask for carries */ - mask = (((mp_digit)1) << d) - 1; + mask = ((mp_digit)1 << d) - (mp_digit)1; /* shift for msbs */ - shift = DIGIT_BIT - d; + shift = (mp_digit)DIGIT_BIT - d; /* alias */ tmpc = c->dp; @@ -71,7 +71,7 @@ int mp_mul_2d(const mp_int *a, int b, mp_int *c) } /* set final carry */ - if (r != 0) { + if (r != 0u) { c->dp[(c->used)++] = r; } } diff --git a/libtommath/bn_mp_mul_d.c b/libtommath/bn_mp_mul_d.c index 0f6d03e..13f94a2 100644 --- a/libtommath/bn_mp_mul_d.c +++ b/libtommath/bn_mp_mul_d.c @@ -50,10 +50,10 @@ int mp_mul_d(const mp_int *a, mp_digit b, mp_int *c) r = (mp_word)u + ((mp_word)*tmpa++ * (mp_word)b); /* mask off higher bits to get a single digit */ - *tmpc++ = (mp_digit)(r & ((mp_word)MP_MASK)); + *tmpc++ = (mp_digit)(r & (mp_word)MP_MASK); /* send carry into next iteration */ - u = (mp_digit)(r >> ((mp_word)DIGIT_BIT)); + u = (mp_digit)(r >> (mp_word)DIGIT_BIT); } /* store final carry [if any] and increment ix offset */ diff --git a/libtommath/bn_mp_n_root_ex.c b/libtommath/bn_mp_n_root_ex.c index ca50649..60c9929 100644 --- a/libtommath/bn_mp_n_root_ex.c +++ b/libtommath/bn_mp_n_root_ex.c @@ -31,7 +31,7 @@ int mp_n_root_ex(const mp_int *a, mp_digit b, mp_int *c, int fast) int res; /* input must be positive if b is even */ - if (((b & 1) == 0) && (a->sign == MP_NEG)) { + if (((b & 1u) == 0u) && (a->sign == MP_NEG)) { return MP_VAL; } @@ -52,7 +52,7 @@ int mp_n_root_ex(const mp_int *a, mp_digit b, mp_int *c, int fast) a_.sign = MP_ZPOS; /* t2 = 2 */ - mp_set(&t2, 2); + mp_set(&t2, 2uL); do { /* t1 = t2 */ @@ -63,7 +63,7 @@ int mp_n_root_ex(const mp_int *a, mp_digit b, mp_int *c, int fast) /* t2 = t1 - ((t1**b - a) / (b * t1**(b-1))) */ /* t3 = t1**(b-1) */ - if ((res = mp_expt_d_ex(&t1, b - 1, &t3, fast)) != MP_OKAY) { + if ((res = mp_expt_d_ex(&t1, b - 1u, &t3, fast)) != MP_OKAY) { goto LBL_T3; } @@ -101,7 +101,7 @@ int mp_n_root_ex(const mp_int *a, mp_digit b, mp_int *c, int fast) } if (mp_cmp(&t2, &a_) == MP_GT) { - if ((res = mp_sub_d(&t1, 1, &t1)) != MP_OKAY) { + if ((res = mp_sub_d(&t1, 1uL, &t1)) != MP_OKAY) { goto LBL_T3; } } else { diff --git a/libtommath/bn_mp_prime_fermat.c b/libtommath/bn_mp_prime_fermat.c index 9c15435..e71e0ae 100644 --- a/libtommath/bn_mp_prime_fermat.c +++ b/libtommath/bn_mp_prime_fermat.c @@ -32,7 +32,7 @@ int mp_prime_fermat(const mp_int *a, const mp_int *b, int *result) *result = MP_NO; /* ensure b > 1 */ - if (mp_cmp_d(b, 1) != MP_GT) { + if (mp_cmp_d(b, 1uL) != MP_GT) { return MP_VAL; } diff --git a/libtommath/bn_mp_prime_is_divisible.c b/libtommath/bn_mp_prime_is_divisible.c index c1e1158..c49fdd2 100644 --- a/libtommath/bn_mp_prime_is_divisible.c +++ b/libtommath/bn_mp_prime_is_divisible.c @@ -35,7 +35,7 @@ int mp_prime_is_divisible(const mp_int *a, int *result) } /* is the residue zero? */ - if (res == 0) { + if (res == 0u) { *result = MP_YES; return MP_OKAY; } diff --git a/libtommath/bn_mp_prime_miller_rabin.c b/libtommath/bn_mp_prime_miller_rabin.c index 5de5f05..34c4d1c 100644 --- a/libtommath/bn_mp_prime_miller_rabin.c +++ b/libtommath/bn_mp_prime_miller_rabin.c @@ -31,7 +31,7 @@ int mp_prime_miller_rabin(const mp_int *a, const mp_int *b, int *result) *result = MP_NO; /* ensure b > 1 */ - if (mp_cmp_d(b, 1) != MP_GT) { + if (mp_cmp_d(b, 1uL) != MP_GT) { return MP_VAL; } @@ -39,7 +39,7 @@ int mp_prime_miller_rabin(const mp_int *a, const mp_int *b, int *result) if ((err = mp_init_copy(&n1, a)) != MP_OKAY) { return err; } - if ((err = mp_sub_d(&n1, 1, &n1)) != MP_OKAY) { + if ((err = mp_sub_d(&n1, 1uL, &n1)) != MP_OKAY) { goto LBL_N1; } @@ -67,7 +67,7 @@ int mp_prime_miller_rabin(const mp_int *a, const mp_int *b, int *result) } /* if y != 1 and y != n1 do */ - if ((mp_cmp_d(&y, 1) != MP_EQ) && (mp_cmp(&y, &n1) != MP_EQ)) { + if ((mp_cmp_d(&y, 1uL) != MP_EQ) && (mp_cmp(&y, &n1) != MP_EQ)) { j = 1; /* while j <= s-1 and y != n1 */ while ((j <= (s - 1)) && (mp_cmp(&y, &n1) != MP_EQ)) { @@ -76,7 +76,7 @@ int mp_prime_miller_rabin(const mp_int *a, const mp_int *b, int *result) } /* if y == 1 then composite */ - if (mp_cmp_d(&y, 1) == MP_EQ) { + if (mp_cmp_d(&y, 1uL) == MP_EQ) { goto LBL_Y; } diff --git a/libtommath/bn_mp_prime_next_prime.c b/libtommath/bn_mp_prime_next_prime.c index f383cbb..b106a74 100644 --- a/libtommath/bn_mp_prime_next_prime.c +++ b/libtommath/bn_mp_prime_next_prime.c @@ -46,10 +46,10 @@ int mp_prime_next_prime(mp_int *a, int t, int bbs_style) * however, the prime must be * congruent to 3 mod 4 */ - if ((ltm_prime_tab[x + 1] & 3) != 3) { + if ((ltm_prime_tab[x + 1] & 3u) != 3u) { /* scan upwards for a prime congruent to 3 mod 4 */ for (y = x + 1; y < PRIME_SIZE; y++) { - if ((ltm_prime_tab[y] & 3) == 3) { + if ((ltm_prime_tab[y] & 3u) == 3u) { mp_set(a, ltm_prime_tab[y]); return MP_OKAY; } @@ -62,8 +62,8 @@ int mp_prime_next_prime(mp_int *a, int t, int bbs_style) } } /* at this point a maybe 1 */ - if (mp_cmp_d(a, 1) == MP_EQ) { - mp_set(a, 2); + if (mp_cmp_d(a, 1uL) == MP_EQ) { + mp_set(a, 2uL); return MP_OKAY; } /* fall through to the sieve */ @@ -80,15 +80,15 @@ int mp_prime_next_prime(mp_int *a, int t, int bbs_style) if (bbs_style == 1) { /* if a mod 4 != 3 subtract the correct value to make it so */ - if ((a->dp[0] & 3) != 3) { - if ((err = mp_sub_d(a, (a->dp[0] & 3) + 1, a)) != MP_OKAY) { + if ((a->dp[0] & 3u) != 3u) { + if ((err = mp_sub_d(a, (a->dp[0] & 3u) + 1u, a)) != MP_OKAY) { return err; }; } } else { if (mp_iseven(a) == MP_YES) { /* force odd */ - if ((err = mp_sub_d(a, 1, a)) != MP_OKAY) { + if ((err = mp_sub_d(a, 1uL, a)) != MP_OKAY) { return err; } } @@ -127,11 +127,11 @@ int mp_prime_next_prime(mp_int *a, int t, int bbs_style) } /* set flag if zero */ - if (res_tab[x] == 0) { + if (res_tab[x] == 0u) { y = 1; } } - } while ((y == 1) && (step < ((((mp_digit)1) << DIGIT_BIT) - kstep))); + } while ((y == 1) && (step < (((mp_digit)1 << DIGIT_BIT) - kstep))); /* add the step */ if ((err = mp_add_d(a, step, a)) != MP_OKAY) { @@ -139,7 +139,7 @@ int mp_prime_next_prime(mp_int *a, int t, int bbs_style) } /* if didn't pass sieve and step == MAX then skip test */ - if ((y == 1) && (step >= ((((mp_digit)1) << DIGIT_BIT) - kstep))) { + if ((y == 1) && (step >= (((mp_digit)1 << DIGIT_BIT) - kstep))) { continue; } diff --git a/libtommath/bn_mp_prime_random_ex.c b/libtommath/bn_mp_prime_random_ex.c index d3d6f3d..1ae2934 100644 --- a/libtommath/bn_mp_prime_random_ex.c +++ b/libtommath/bn_mp_prime_random_ex.c @@ -49,7 +49,7 @@ int mp_prime_random_ex(mp_int *a, int t, int size, int flags, ltm_prime_callback bsize = (size>>3) + ((size&7)?1:0); /* we need a buffer of bsize bytes */ - tmp = OPT_CAST(unsigned char) XMALLOC(bsize); + tmp = OPT_CAST(unsigned char) XMALLOC((size_t)bsize); if (tmp == NULL) { return MP_MEM; } @@ -86,12 +86,12 @@ int mp_prime_random_ex(mp_int *a, int t, int size, int flags, ltm_prime_callback tmp[bsize-1] |= maskOR_lsb; /* read it in */ - if ((err = mp_read_unsigned_bin(a, tmp, bsize)) != MP_OKAY) { + if ((err = mp_read_unsigned_bin(a, tmp, bsize)) != MP_OKAY) { goto error; } /* is it prime? */ - if ((err = mp_prime_is_prime(a, t, &res)) != MP_OKAY) { + if ((err = mp_prime_is_prime(a, t, &res)) != MP_OKAY) { goto error; } if (res == MP_NO) { @@ -100,15 +100,15 @@ int mp_prime_random_ex(mp_int *a, int t, int size, int flags, ltm_prime_callback if ((flags & LTM_PRIME_SAFE) != 0) { /* see if (a-1)/2 is prime */ - if ((err = mp_sub_d(a, 1, a)) != MP_OKAY) { + if ((err = mp_sub_d(a, 1uL, a)) != MP_OKAY) { goto error; } - if ((err = mp_div_2(a, a)) != MP_OKAY) { + if ((err = mp_div_2(a, a)) != MP_OKAY) { goto error; } /* is it prime? */ - if ((err = mp_prime_is_prime(a, t, &res)) != MP_OKAY) { + if ((err = mp_prime_is_prime(a, t, &res)) != MP_OKAY) { goto error; } } @@ -116,10 +116,10 @@ int mp_prime_random_ex(mp_int *a, int t, int size, int flags, ltm_prime_callback if ((flags & LTM_PRIME_SAFE) != 0) { /* restore a to the original value */ - if ((err = mp_mul_2(a, a)) != MP_OKAY) { + if ((err = mp_mul_2(a, a)) != MP_OKAY) { goto error; } - if ((err = mp_add_d(a, 1, a)) != MP_OKAY) { + if ((err = mp_add_d(a, 1uL, a)) != MP_OKAY) { goto error; } } diff --git a/libtommath/bn_mp_radix_smap.c b/libtommath/bn_mp_radix_smap.c index 4c6e57c..262775c 100644 --- a/libtommath/bn_mp_radix_smap.c +++ b/libtommath/bn_mp_radix_smap.c @@ -17,6 +17,20 @@ /* chars used in radix conversions */ const char *mp_s_rmap = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz+/"; +const uint8_t mp_s_rmap_reverse[] = { + 0xff, 0xff, 0xff, 0x3e, 0xff, 0xff, 0xff, 0x3f, /* ()*+,-./ */ + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, /* 01234567 */ + 0x08, 0x09, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* 89:;<=>? */ + 0xff, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, /* @ABCDEFG */ + 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, /* HIJKLMNO */ + 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, 0x20, /* PQRSTUVW */ + 0x21, 0x22, 0x23, 0xff, 0xff, 0xff, 0xff, 0xff, /* XYZ[\]^_ */ + 0xff, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2a, /* `abcdefg */ + 0x2b, 0x2c, 0x2d, 0x2e, 0x2f, 0x30, 0x31, 0x32, /* hijklmno */ + 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3a, /* pqrstuvw */ + 0x3b, 0x3c, 0x3d, 0xff, 0xff, 0xff, 0xff, 0xff, /* xyz{|}~. */ +}; +const size_t mp_s_rmap_reverse_sz = sizeof(mp_s_rmap_reverse); #endif /* ref: $Format:%D$ */ diff --git a/libtommath/bn_mp_rand.c b/libtommath/bn_mp_rand.c index 92a9a97..2ed665e 100644 --- a/libtommath/bn_mp_rand.c +++ b/libtommath/bn_mp_rand.c @@ -15,7 +15,10 @@ * Tom St Denis, tstdenis82@gmail.com, http://libtom.org */ -#if MP_GEN_RANDOM_MAX == 0xffffffff +#if defined(MP_8BIT) || defined(MP_16BIT) +#define MP_GEN_RANDOM_SHIFT DIGIT_BIT +#else +#if MP_GEN_RANDOM_MAX == 0xffffffffu #define MP_GEN_RANDOM_SHIFT 32 #elif MP_GEN_RANDOM_MAX == 32767 /* SHRT_MAX */ @@ -26,6 +29,7 @@ #elif !defined(MP_GEN_RANDOM_SHIFT) #error Thou shalt define their own valid MP_GEN_RANDOM_SHIFT #endif +#endif /* makes a pseudo-random int of a given size */ static mp_digit s_gen_random(void) @@ -54,7 +58,7 @@ int mp_rand(mp_int *a, int digits) /* first place a random non-zero digit */ do { d = s_gen_random(); - } while (d == 0); + } while (d == 0u); if ((res = mp_add_d(a, d, a)) != MP_OKAY) { return res; diff --git a/libtommath/bn_mp_read_radix.c b/libtommath/bn_mp_read_radix.c index bc31cc5..55c5ee1 100644 --- a/libtommath/bn_mp_read_radix.c +++ b/libtommath/bn_mp_read_radix.c @@ -19,6 +19,7 @@ int mp_read_radix(mp_int *a, const char *str, int radix) { int y, res, neg; + unsigned pos; char ch; /* zero the digit bignum */ @@ -49,31 +50,30 @@ int mp_read_radix(mp_int *a, const char *str, int radix) * [e.g. in hex] */ ch = (radix <= 36) ? (char)toupper((int)*str) : *str; - for (y = 0; y < 64; y++) { - if (ch == mp_s_rmap[y]) { - break; - } + pos = (unsigned)(ch - '('); + if (mp_s_rmap_reverse_sz < pos) { + break; } + y = (int)mp_s_rmap_reverse[pos]; /* if the char was found in the map * and is less than the given radix add it * to the number, otherwise exit the loop. */ - if (y < radix) { - if ((res = mp_mul_d(a, (mp_digit)radix, a)) != MP_OKAY) { - return res; - } - if ((res = mp_add_d(a, (mp_digit)y, a)) != MP_OKAY) { - return res; - } - } else { + if ((y == 0xff) || (y >= radix)) { break; } + if ((res = mp_mul_d(a, (mp_digit)radix, a)) != MP_OKAY) { + return res; + } + if ((res = mp_add_d(a, (mp_digit)y, a)) != MP_OKAY) { + return res; + } ++str; } /* if an illegal character was found, fail. */ - if (!(*str == '\0' || *str == '\r' || *str == '\n')) { + if (!((*str == '\0') || (*str == '\r') || (*str == '\n'))) { mp_zero(a); return MP_VAL; } diff --git a/libtommath/bn_mp_read_signed_bin.c b/libtommath/bn_mp_read_signed_bin.c index eabc803..17bc6ce 100644 --- a/libtommath/bn_mp_read_signed_bin.c +++ b/libtommath/bn_mp_read_signed_bin.c @@ -26,7 +26,7 @@ int mp_read_signed_bin(mp_int *a, const unsigned char *b, int c) } /* first byte is 0 for positive, non-zero for negative */ - if (b[0] == 0) { + if (b[0] == (unsigned char)0) { a->sign = MP_ZPOS; } else { a->sign = MP_NEG; diff --git a/libtommath/bn_mp_read_unsigned_bin.c b/libtommath/bn_mp_read_unsigned_bin.c index ad9f05f..6398c43 100644 --- a/libtommath/bn_mp_read_unsigned_bin.c +++ b/libtommath/bn_mp_read_unsigned_bin.c @@ -41,7 +41,7 @@ int mp_read_unsigned_bin(mp_int *a, const unsigned char *b, int c) a->used += 1; #else a->dp[0] = (*b & MP_MASK); - a->dp[1] |= ((*b++ >> 7U) & 1); + a->dp[1] |= ((*b++ >> 7) & 1u); a->used += 2; #endif } diff --git a/libtommath/bn_mp_reduce.c b/libtommath/bn_mp_reduce.c index bbc521f..5b1d405 100644 --- a/libtommath/bn_mp_reduce.c +++ b/libtommath/bn_mp_reduce.c @@ -33,7 +33,7 @@ int mp_reduce(mp_int *x, const mp_int *m, const mp_int *mu) mp_rshd(&q, um - 1); /* according to HAC this optimization is ok */ - if (((mp_digit) um) > (((mp_digit)1) << (DIGIT_BIT - 1))) { + if ((mp_digit)um > ((mp_digit)1 << (DIGIT_BIT - 1))) { if ((res = mp_mul(&q, mu, &q)) != MP_OKAY) { goto CLEANUP; } @@ -73,8 +73,8 @@ int mp_reduce(mp_int *x, const mp_int *m, const mp_int *mu) } /* If x < 0, add b**(k+1) to it */ - if (mp_cmp_d(x, 0) == MP_LT) { - mp_set(&q, 1); + if (mp_cmp_d(x, 0uL) == MP_LT) { + mp_set(&q, 1uL); if ((res = mp_lshd(&q, um + 1)) != MP_OKAY) goto CLEANUP; if ((res = mp_add(x, &q, x)) != MP_OKAY) diff --git a/libtommath/bn_mp_reduce_2k.c b/libtommath/bn_mp_reduce_2k.c index 2922cad..e1e2bc8 100644 --- a/libtommath/bn_mp_reduce_2k.c +++ b/libtommath/bn_mp_reduce_2k.c @@ -32,7 +32,7 @@ top: goto ERR; } - if (d != 1) { + if (d != 1u) { /* q = q * d */ if ((res = mp_mul_d(&q, d, &q)) != MP_OKAY) { goto ERR; diff --git a/libtommath/bn_mp_reduce_is_2k.c b/libtommath/bn_mp_reduce_is_2k.c index 932521e..f59d535 100644 --- a/libtommath/bn_mp_reduce_is_2k.c +++ b/libtommath/bn_mp_reduce_is_2k.c @@ -32,7 +32,7 @@ int mp_reduce_is_2k(const mp_int *a) /* Test every bit from the second digit up, must be 1 */ for (ix = DIGIT_BIT; ix < iy; ix++) { - if ((a->dp[iw] & iz) == 0) { + if ((a->dp[iw] & iz) == 0u) { return MP_NO; } iz <<= 1; diff --git a/libtommath/bn_mp_set.c b/libtommath/bn_mp_set.c index eaf7fed..952d080 100644 --- a/libtommath/bn_mp_set.c +++ b/libtommath/bn_mp_set.c @@ -20,7 +20,7 @@ void mp_set(mp_int *a, mp_digit b) { mp_zero(a); a->dp[0] = b & MP_MASK; - a->used = (a->dp[0] != 0) ? 1 : 0; + a->used = (a->dp[0] != 0u) ? 1 : 0; } #endif diff --git a/libtommath/bn_mp_set_int.c b/libtommath/bn_mp_set_int.c index 4c71180..006f263 100644 --- a/libtommath/bn_mp_set_int.c +++ b/libtommath/bn_mp_set_int.c @@ -30,7 +30,7 @@ int mp_set_int(mp_int *a, unsigned long b) } /* OR in the top four bits of the source */ - a->dp[0] |= (b >> 28) & 15; + a->dp[0] |= (mp_digit)(b >> 28) & 15uL; /* shift the source up to the next four bits */ b <<= 4; diff --git a/libtommath/bn_mp_shrink.c b/libtommath/bn_mp_shrink.c index 8ac1f33..3e4dde0 100644 --- a/libtommath/bn_mp_shrink.c +++ b/libtommath/bn_mp_shrink.c @@ -26,7 +26,7 @@ int mp_shrink(mp_int *a) } if (a->alloc != used) { - if ((tmp = OPT_CAST(mp_digit) XREALLOC(a->dp, sizeof(mp_digit) * used)) == NULL) { + if ((tmp = OPT_CAST(mp_digit) XREALLOC(a->dp, sizeof(mp_digit) * (size_t)used)) == NULL) { return MP_MEM; } a->dp = tmp; diff --git a/libtommath/bn_mp_sqr.c b/libtommath/bn_mp_sqr.c index 2b71097..a98f16c 100644 --- a/libtommath/bn_mp_sqr.c +++ b/libtommath/bn_mp_sqr.c @@ -35,9 +35,9 @@ int mp_sqr(const mp_int *a, mp_int *b) { #ifdef BN_FAST_S_MP_SQR_C /* can we use the fast comba multiplier? */ - if ((((a->used * 2) + 1) < MP_WARRAY) && + if ((((a->used * 2) + 1) < (int)MP_WARRAY) && (a->used < - (1 << (((sizeof(mp_word) * CHAR_BIT) - (2 * DIGIT_BIT)) - 1)))) { + (int)(1u << (((sizeof(mp_word) * (size_t)CHAR_BIT) - (2u * (size_t)DIGIT_BIT)) - 1u)))) { res = fast_s_mp_sqr(a, b); } else #endif diff --git a/libtommath/bn_mp_sqrtmod_prime.c b/libtommath/bn_mp_sqrtmod_prime.c index 261723e..d4cf3de 100644 --- a/libtommath/bn_mp_sqrtmod_prime.c +++ b/libtommath/bn_mp_sqrtmod_prime.c @@ -22,11 +22,11 @@ int mp_sqrtmod_prime(const mp_int *n, const mp_int *prime, mp_int *ret) mp_digit i; /* first handle the simple cases */ - if (mp_cmp_d(n, 0) == MP_EQ) { + if (mp_cmp_d(n, 0uL) == MP_EQ) { mp_zero(ret); return MP_OKAY; } - if (mp_cmp_d(prime, 2) == MP_EQ) return MP_VAL; /* prime must be odd */ + if (mp_cmp_d(prime, 2uL) == MP_EQ) return MP_VAL; /* prime must be odd */ if ((res = mp_jacobi(n, prime, &legendre)) != MP_OKAY) return res; if (legendre == -1) return MP_VAL; /* quadratic non-residue mod prime */ @@ -38,9 +38,9 @@ int mp_sqrtmod_prime(const mp_int *n, const mp_int *prime, mp_int *ret) * compute directly: res = n^(prime+1)/4 mod prime * Handbook of Applied Cryptography algorithm 3.36 */ - if ((res = mp_mod_d(prime, 4, &i)) != MP_OKAY) goto cleanup; - if (i == 3) { - if ((res = mp_add_d(prime, 1, &t1)) != MP_OKAY) goto cleanup; + if ((res = mp_mod_d(prime, 4uL, &i)) != MP_OKAY) goto cleanup; + if (i == 3u) { + if ((res = mp_add_d(prime, 1uL, &t1)) != MP_OKAY) goto cleanup; if ((res = mp_div_2(&t1, &t1)) != MP_OKAY) goto cleanup; if ((res = mp_div_2(&t1, &t1)) != MP_OKAY) goto cleanup; if ((res = mp_exptmod(n, &t1, prime, ret)) != MP_OKAY) goto cleanup; @@ -52,30 +52,30 @@ int mp_sqrtmod_prime(const mp_int *n, const mp_int *prime, mp_int *ret) /* factor out powers of 2 from prime-1, defining Q and S as: prime-1 = Q*2^S */ if ((res = mp_copy(prime, &Q)) != MP_OKAY) goto cleanup; - if ((res = mp_sub_d(&Q, 1, &Q)) != MP_OKAY) goto cleanup; + if ((res = mp_sub_d(&Q, 1uL, &Q)) != MP_OKAY) goto cleanup; /* Q = prime - 1 */ mp_zero(&S); /* S = 0 */ while (mp_iseven(&Q) != MP_NO) { if ((res = mp_div_2(&Q, &Q)) != MP_OKAY) goto cleanup; /* Q = Q / 2 */ - if ((res = mp_add_d(&S, 1, &S)) != MP_OKAY) goto cleanup; + if ((res = mp_add_d(&S, 1uL, &S)) != MP_OKAY) goto cleanup; /* S = S + 1 */ } /* find a Z such that the Legendre symbol (Z|prime) == -1 */ - if ((res = mp_set_int(&Z, 2)) != MP_OKAY) goto cleanup; + if ((res = mp_set_int(&Z, 2uL)) != MP_OKAY) goto cleanup; /* Z = 2 */ while (1) { if ((res = mp_jacobi(&Z, prime, &legendre)) != MP_OKAY) goto cleanup; if (legendre == -1) break; - if ((res = mp_add_d(&Z, 1, &Z)) != MP_OKAY) goto cleanup; + if ((res = mp_add_d(&Z, 1uL, &Z)) != MP_OKAY) goto cleanup; /* Z = Z + 1 */ } if ((res = mp_exptmod(&Z, &Q, prime, &C)) != MP_OKAY) goto cleanup; /* C = Z ^ Q mod prime */ - if ((res = mp_add_d(&Q, 1, &t1)) != MP_OKAY) goto cleanup; + if ((res = mp_add_d(&Q, 1uL, &t1)) != MP_OKAY) goto cleanup; if ((res = mp_div_2(&t1, &t1)) != MP_OKAY) goto cleanup; /* t1 = (Q + 1) / 2 */ if ((res = mp_exptmod(n, &t1, prime, &R)) != MP_OKAY) goto cleanup; @@ -84,24 +84,24 @@ int mp_sqrtmod_prime(const mp_int *n, const mp_int *prime, mp_int *ret) /* T = n ^ Q mod prime */ if ((res = mp_copy(&S, &M)) != MP_OKAY) goto cleanup; /* M = S */ - if ((res = mp_set_int(&two, 2)) != MP_OKAY) goto cleanup; + if ((res = mp_set_int(&two, 2uL)) != MP_OKAY) goto cleanup; res = MP_VAL; while (1) { if ((res = mp_copy(&T, &t1)) != MP_OKAY) goto cleanup; i = 0; while (1) { - if (mp_cmp_d(&t1, 1) == MP_EQ) break; + if (mp_cmp_d(&t1, 1uL) == MP_EQ) break; if ((res = mp_exptmod(&t1, &two, prime, &t1)) != MP_OKAY) goto cleanup; i++; } - if (i == 0) { + if (i == 0u) { if ((res = mp_copy(&R, ret)) != MP_OKAY) goto cleanup; res = MP_OKAY; goto cleanup; } if ((res = mp_sub_d(&M, i, &t1)) != MP_OKAY) goto cleanup; - if ((res = mp_sub_d(&t1, 1, &t1)) != MP_OKAY) goto cleanup; + if ((res = mp_sub_d(&t1, 1uL, &t1)) != MP_OKAY) goto cleanup; if ((res = mp_exptmod(&two, &t1, prime, &t1)) != MP_OKAY) goto cleanup; /* t1 = 2 ^ (M - i - 1) */ if ((res = mp_exptmod(&C, &t1, prime, &t1)) != MP_OKAY) goto cleanup; diff --git a/libtommath/bn_mp_sub_d.c b/libtommath/bn_mp_sub_d.c index 4d66a90..e5fbfff 100644 --- a/libtommath/bn_mp_sub_d.c +++ b/libtommath/bn_mp_sub_d.c @@ -67,13 +67,13 @@ int mp_sub_d(const mp_int *a, mp_digit b, mp_int *c) /* subtract first digit */ *tmpc = *tmpa++ - b; - mu = *tmpc >> ((sizeof(mp_digit) * CHAR_BIT) - 1); + mu = *tmpc >> ((sizeof(mp_digit) * (size_t)CHAR_BIT) - 1u); *tmpc++ &= MP_MASK; /* handle rest of the digits */ for (ix = 1; ix < a->used; ix++) { *tmpc = *tmpa++ - mu; - mu = *tmpc >> ((sizeof(mp_digit) * CHAR_BIT) - 1); + mu = *tmpc >> ((sizeof(mp_digit) * (size_t)CHAR_BIT) - 1u); *tmpc++ &= MP_MASK; } } diff --git a/libtommath/bn_mp_to_signed_bin_n.c b/libtommath/bn_mp_to_signed_bin_n.c index 1447624..f1d7c8b 100644 --- a/libtommath/bn_mp_to_signed_bin_n.c +++ b/libtommath/bn_mp_to_signed_bin_n.c @@ -21,7 +21,7 @@ int mp_to_signed_bin_n(const mp_int *a, unsigned char *b, unsigned long *outlen) if (*outlen < (unsigned long)mp_signed_bin_size(a)) { return MP_VAL; } - *outlen = mp_signed_bin_size(a); + *outlen = (unsigned long)mp_signed_bin_size(a); return mp_to_signed_bin(a, b); } #endif diff --git a/libtommath/bn_mp_to_unsigned_bin.c b/libtommath/bn_mp_to_unsigned_bin.c index 9339cce..a53f711 100644 --- a/libtommath/bn_mp_to_unsigned_bin.c +++ b/libtommath/bn_mp_to_unsigned_bin.c @@ -28,9 +28,9 @@ int mp_to_unsigned_bin(const mp_int *a, unsigned char *b) x = 0; while (mp_iszero(&t) == MP_NO) { #ifndef MP_8BIT - b[x++] = (unsigned char)(t.dp[0] & 255); + b[x++] = (unsigned char)(t.dp[0] & 255u); #else - b[x++] = (unsigned char)(t.dp[0] | ((t.dp[1] & 0x01) << 7)); + b[x++] = (unsigned char)(t.dp[0] | ((t.dp[1] & 1u) << 7)); #endif if ((res = mp_div_2d(&t, 8, &t, NULL)) != MP_OKAY) { mp_clear(&t); diff --git a/libtommath/bn_mp_to_unsigned_bin_n.c b/libtommath/bn_mp_to_unsigned_bin_n.c index 707dc82..e7d303c 100644 --- a/libtommath/bn_mp_to_unsigned_bin_n.c +++ b/libtommath/bn_mp_to_unsigned_bin_n.c @@ -21,7 +21,7 @@ int mp_to_unsigned_bin_n(const mp_int *a, unsigned char *b, unsigned long *outle if (*outlen < (unsigned long)mp_unsigned_bin_size(a)) { return MP_VAL; } - *outlen = mp_unsigned_bin_size(a); + *outlen = (unsigned long)mp_unsigned_bin_size(a); return mp_to_unsigned_bin(a, b); } #endif diff --git a/libtommath/bn_mp_toom_mul.c b/libtommath/bn_mp_toom_mul.c index 3554ea8..00b6bfb 100644 --- a/libtommath/bn_mp_toom_mul.c +++ b/libtommath/bn_mp_toom_mul.c @@ -219,7 +219,7 @@ int mp_toom_mul(const mp_int *a, const mp_int *b, mp_int *c) goto ERR; } /* 3r2 - r1 - r3 */ - if ((res = mp_mul_d(&w2, 3, &w2)) != MP_OKAY) { + if ((res = mp_mul_d(&w2, 3uL, &w2)) != MP_OKAY) { goto ERR; } if ((res = mp_sub(&w2, &w1, &w2)) != MP_OKAY) { diff --git a/libtommath/bn_mp_toom_sqr.c b/libtommath/bn_mp_toom_sqr.c index b985435..183de20 100644 --- a/libtommath/bn_mp_toom_sqr.c +++ b/libtommath/bn_mp_toom_sqr.c @@ -162,7 +162,7 @@ int mp_toom_sqr(const mp_int *a, mp_int *b) goto ERR; } /* 3r2 - r1 - r3 */ - if ((res = mp_mul_d(&w2, 3, &w2)) != MP_OKAY) { + if ((res = mp_mul_d(&w2, 3uL, &w2)) != MP_OKAY) { goto ERR; } if ((res = mp_sub(&w2, &w1, &w2)) != MP_OKAY) { diff --git a/libtommath/bn_mp_unsigned_bin_size.c b/libtommath/bn_mp_unsigned_bin_size.c index 04107fe..2b9ce8a 100644 --- a/libtommath/bn_mp_unsigned_bin_size.c +++ b/libtommath/bn_mp_unsigned_bin_size.c @@ -19,7 +19,7 @@ int mp_unsigned_bin_size(const mp_int *a) { int size = mp_count_bits(a); - return (size / 8) + (((size & 7) != 0) ? 1 : 0); + return (size / 8) + ((((unsigned)size & 7u) != 0u) ? 1 : 0); } #endif diff --git a/libtommath/bn_prime_tab.c b/libtommath/bn_prime_tab.c index c8fadcd..bcd23ed 100644 --- a/libtommath/bn_prime_tab.c +++ b/libtommath/bn_prime_tab.c @@ -14,6 +14,7 @@ * * Tom St Denis, tstdenis82@gmail.com, http://libtom.org */ + const mp_digit ltm_prime_tab[] = { 0x0002, 0x0003, 0x0005, 0x0007, 0x000B, 0x000D, 0x0011, 0x0013, 0x0017, 0x001D, 0x001F, 0x0025, 0x0029, 0x002B, 0x002F, 0x0035, diff --git a/libtommath/bn_s_mp_add.c b/libtommath/bn_s_mp_add.c index 2046722..3f908ef 100644 --- a/libtommath/bn_s_mp_add.c +++ b/libtommath/bn_s_mp_add.c @@ -67,7 +67,7 @@ int s_mp_add(const mp_int *a, const mp_int *b, mp_int *c) *tmpc = *tmpa++ + *tmpb++ + u; /* U = carry bit of T[i] */ - u = *tmpc >> ((mp_digit)DIGIT_BIT); + u = *tmpc >> (mp_digit)DIGIT_BIT; /* take away carry bit from T[i] */ *tmpc++ &= MP_MASK; @@ -82,7 +82,7 @@ int s_mp_add(const mp_int *a, const mp_int *b, mp_int *c) *tmpc = x->dp[i] + u; /* U = carry bit of T[i] */ - u = *tmpc >> ((mp_digit)DIGIT_BIT); + u = *tmpc >> (mp_digit)DIGIT_BIT; /* take away carry bit from T[i] */ *tmpc++ &= MP_MASK; diff --git a/libtommath/bn_s_mp_exptmod.c b/libtommath/bn_s_mp_exptmod.c index a886361..a954757 100644 --- a/libtommath/bn_s_mp_exptmod.c +++ b/libtommath/bn_s_mp_exptmod.c @@ -14,6 +14,7 @@ * * Tom St Denis, tstdenis82@gmail.com, http://libtom.org */ + #ifdef MP_LOW_MEM # define TAB_SIZE 32 #else @@ -25,7 +26,7 @@ int s_mp_exptmod(const mp_int *G, const mp_int *X, const mp_int *P, mp_int *Y, i mp_int M[TAB_SIZE], res, mu; mp_digit buf; int err, bitbuf, bitcpy, bitcnt, mode, digidx, x, y, winsize; - int (*redux)(mp_int *, const mp_int *, const mp_int *); + int (*redux)(mp_int *x, const mp_int *m, const mp_int *mu); /* find window size */ x = mp_count_bits(X); @@ -133,7 +134,7 @@ int s_mp_exptmod(const mp_int *G, const mp_int *X, const mp_int *P, mp_int *Y, i if ((err = mp_init(&res)) != MP_OKAY) { goto LBL_MU; } - mp_set(&res, 1); + mp_set(&res, 1uL); /* set initial mode and bit cnt */ mode = 0; diff --git a/libtommath/bn_s_mp_mul_digs.c b/libtommath/bn_s_mp_mul_digs.c index af13a02..214ae31 100644 --- a/libtommath/bn_s_mp_mul_digs.c +++ b/libtommath/bn_s_mp_mul_digs.c @@ -28,9 +28,9 @@ int s_mp_mul_digs(const mp_int *a, const mp_int *b, mp_int *c, int digs) mp_digit tmpx, *tmpt, *tmpy; /* can we use the fast multiplier? */ - if (((digs) < MP_WARRAY) && + if ((digs < (int)MP_WARRAY) && (MIN(a->used, b->used) < - (1 << ((CHAR_BIT * sizeof(mp_word)) - (2 * DIGIT_BIT))))) { + (int)(1u << (((size_t)CHAR_BIT * sizeof(mp_word)) - (2u * (size_t)DIGIT_BIT))))) { return fast_s_mp_mul_digs(a, b, c, digs); } @@ -66,10 +66,10 @@ int s_mp_mul_digs(const mp_int *a, const mp_int *b, mp_int *c, int digs) (mp_word)u; /* the new column is the lower part of the result */ - *tmpt++ = (mp_digit)(r & ((mp_word) MP_MASK)); + *tmpt++ = (mp_digit)(r & (mp_word)MP_MASK); /* get the carry word from the result */ - u = (mp_digit)(r >> ((mp_word) DIGIT_BIT)); + u = (mp_digit)(r >> (mp_word)DIGIT_BIT); } /* set carry if it is placed below digs */ if ((ix + iy) < digs) { diff --git a/libtommath/bn_s_mp_mul_high_digs.c b/libtommath/bn_s_mp_mul_high_digs.c index 37c108e..3c0418a 100644 --- a/libtommath/bn_s_mp_mul_high_digs.c +++ b/libtommath/bn_s_mp_mul_high_digs.c @@ -28,8 +28,8 @@ int s_mp_mul_high_digs(const mp_int *a, const mp_int *b, mp_int *c, int digs) /* can we use the fast multiplier? */ #ifdef BN_FAST_S_MP_MUL_HIGH_DIGS_C - if (((a->used + b->used + 1) < MP_WARRAY) - && (MIN(a->used, b->used) < (1 << ((CHAR_BIT * sizeof(mp_word)) - (2 * DIGIT_BIT))))) { + if (((a->used + b->used + 1) < (int)MP_WARRAY) + && (MIN(a->used, b->used) < (int)(1u << (((size_t)CHAR_BIT * sizeof(mp_word)) - (2u * (size_t)DIGIT_BIT))))) { return fast_s_mp_mul_high_digs(a, b, c, digs); } #endif @@ -61,10 +61,10 @@ int s_mp_mul_high_digs(const mp_int *a, const mp_int *b, mp_int *c, int digs) (mp_word)u; /* get the lower part */ - *tmpt++ = (mp_digit)(r & ((mp_word) MP_MASK)); + *tmpt++ = (mp_digit)(r & (mp_word)MP_MASK); /* carry the carry */ - u = (mp_digit)(r >> ((mp_word) DIGIT_BIT)); + u = (mp_digit)(r >> (mp_word)DIGIT_BIT); } *tmpt = u; } diff --git a/libtommath/bn_s_mp_sqr.c b/libtommath/bn_s_mp_sqr.c index aae06eb..71bbccd 100644 --- a/libtommath/bn_s_mp_sqr.c +++ b/libtommath/bn_s_mp_sqr.c @@ -38,10 +38,10 @@ int s_mp_sqr(const mp_int *a, mp_int *b) ((mp_word)a->dp[ix] * (mp_word)a->dp[ix]); /* store lower part in result */ - t.dp[ix+ix] = (mp_digit)(r & ((mp_word)MP_MASK)); + t.dp[ix+ix] = (mp_digit)(r & (mp_word)MP_MASK); /* get the carry */ - u = (mp_digit)(r >> ((mp_word)DIGIT_BIT)); + u = (mp_digit)(r >> (mp_word)DIGIT_BIT); /* left hand side of A[ix] * A[iy] */ tmpx = a->dp[ix]; @@ -51,24 +51,24 @@ int s_mp_sqr(const mp_int *a, mp_int *b) for (iy = ix + 1; iy < pa; iy++) { /* first calculate the product */ - r = ((mp_word)tmpx) * ((mp_word)a->dp[iy]); + r = (mp_word)tmpx * (mp_word)a->dp[iy]; /* now calculate the double precision result, note we use * addition instead of *2 since it's easier to optimize */ - r = ((mp_word) *tmpt) + r + r + ((mp_word) u); + r = (mp_word)*tmpt + r + r + (mp_word)u; /* store lower part */ - *tmpt++ = (mp_digit)(r & ((mp_word) MP_MASK)); + *tmpt++ = (mp_digit)(r & (mp_word)MP_MASK); /* get carry */ - u = (mp_digit)(r >> ((mp_word) DIGIT_BIT)); + u = (mp_digit)(r >> (mp_word)DIGIT_BIT); } /* propagate upwards */ - while (u != ((mp_digit) 0)) { - r = ((mp_word) *tmpt) + ((mp_word) u); - *tmpt++ = (mp_digit)(r & ((mp_word) MP_MASK)); - u = (mp_digit)(r >> ((mp_word) DIGIT_BIT)); + while (u != 0uL) { + r = (mp_word)*tmpt + (mp_word)u; + *tmpt++ = (mp_digit)(r & (mp_word)MP_MASK); + u = (mp_digit)(r >> (mp_word)DIGIT_BIT); } } diff --git a/libtommath/bn_s_mp_sub.c b/libtommath/bn_s_mp_sub.c index 52b8096..c8472af 100644 --- a/libtommath/bn_s_mp_sub.c +++ b/libtommath/bn_s_mp_sub.c @@ -53,7 +53,7 @@ int s_mp_sub(const mp_int *a, const mp_int *b, mp_int *c) * if a carry does occur it will propagate all the way to the * MSB. As a result a single shift is enough to get the carry */ - u = *tmpc >> ((mp_digit)((CHAR_BIT * sizeof(mp_digit)) - 1)); + u = *tmpc >> (((size_t)CHAR_BIT * sizeof(mp_digit)) - 1u); /* Clear carry from T[i] */ *tmpc++ &= MP_MASK; @@ -65,7 +65,7 @@ int s_mp_sub(const mp_int *a, const mp_int *b, mp_int *c) *tmpc = *tmpa++ - u; /* U = carry bit of T[i] */ - u = *tmpc >> ((mp_digit)((CHAR_BIT * sizeof(mp_digit)) - 1)); + u = *tmpc >> (((size_t)CHAR_BIT * sizeof(mp_digit)) - 1u); /* Clear carry from T[i] */ *tmpc++ &= MP_MASK; diff --git a/libtommath/makefile b/libtommath/makefile index 64d8fcd..5eddae4 100644 --- a/libtommath/makefile +++ b/libtommath/makefile @@ -102,10 +102,6 @@ test_standalone: $(LIBNAME) demo/demo.o mtest: cd mtest ; $(CC) $(CFLAGS) -O0 mtest.c $(LFLAGS) -o mtest -travis_mtest: test mtest - @ for i in `seq 1 10` ; do sleep 500 && echo alive; done & - ./mtest/mtest 666666 | ./test > test.log - timing: $(LIBNAME) $(CC) $(CFLAGS) -DTIMER demo/timing.c $(LIBNAME) $(LFLAGS) -o ltmtest @@ -148,7 +144,7 @@ new_file: perl dep.pl perlcritic: - perlcritic *.pl + perlcritic *.pl doc/*.pl astyle: - astyle --options=astylerc $(OBJECTS:.o=.c) + astyle --options=astylerc $(OBJECTS:.o=.c) tommath*.h demo/*.c etc/*.c mtest/mtest.c diff --git a/libtommath/makefile_include.mk b/libtommath/makefile_include.mk index 3a599e8..45a4895 100644 --- a/libtommath/makefile_include.mk +++ b/libtommath/makefile_include.mk @@ -60,6 +60,9 @@ endif # COMPILE_DEBUG ifneq ($(findstring clang,$(CC)),) CFLAGS += -Wno-typedef-redefinition -Wno-tautological-compare -Wno-builtin-requires-header endif +ifneq ($(findstring mingw,$(CC)),) +CFLAGS += -Wno-shadow +endif ifeq ($(PLATFORM), Darwin) CFLAGS += -Wno-nullability-completeness endif diff --git a/libtommath/tommath.h b/libtommath/tommath.h index 591076e..e229bc6 100644 --- a/libtommath/tommath.h +++ b/libtommath/tommath.h @@ -26,6 +26,11 @@ extern "C" { #endif +/* MS Visual C++ doesn't have a 128bit type for words, so fall back to 32bit MPI's (where words are 64bit) */ +#if defined(_MSC_VER) || defined(__LLP64__) +# define MP_32BIT +#endif + /* detect 64-bit mode if possible */ #if defined(__x86_64__) || defined(_M_X64) || defined(_M_AMD64) || \ defined(__powerpc64__) || defined(__ppc64__) || defined(__PPC64__) || \ @@ -63,9 +68,7 @@ typedef uint32_t mp_word; #elif defined(MP_64BIT) /* for GCC only on supported platforms */ typedef uint64_t mp_digit; -# if defined(_WIN32) -typedef unsigned __int128 mp_word; -# elif defined(__GNUC__) +# if defined(__GNUC__) typedef unsigned long mp_word __attribute__((mode(TI))); # else /* it seems you have a problem @@ -102,7 +105,7 @@ typedef mp_digit mp_min_u32; /* use arc4random on platforms that support it */ #if defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__NetBSD__) || defined(__DragonFly__) # define MP_GEN_RANDOM() arc4random() -# define MP_GEN_RANDOM_MAX 0xffffffff +# define MP_GEN_RANDOM_MAX 0xffffffffu #endif /* use rand() as fall-back if there's no better rand function */ @@ -157,7 +160,7 @@ extern int KARATSUBA_MUL_CUTOFF, #endif /* size of comba arrays, should be at least 2 * 2**(BITS_PER_WORD - BITS_PER_DIGIT*2) */ -#define MP_WARRAY (1 << (((sizeof(mp_word) * CHAR_BIT) - (2 * DIGIT_BIT)) + 1)) +#define MP_WARRAY (1u << (((sizeof(mp_word) * CHAR_BIT) - (2 * DIGIT_BIT)) + 1)) /* the infamous mp_int structure */ typedef struct { @@ -392,7 +395,7 @@ int mp_n_root_ex(const mp_int *a, mp_digit b, mp_int *c, int fast); int mp_sqrt(const mp_int *arg, mp_int *ret); /* special sqrt (mod prime) */ -int mp_sqrtmod_prime(const mp_int *arg, const mp_int *prime, mp_int *ret); +int mp_sqrtmod_prime(const mp_int *n, const mp_int *prime, mp_int *ret); /* is number a square? */ int mp_is_square(const mp_int *arg, int *ret); @@ -405,13 +408,13 @@ int mp_reduce_setup(mp_int *a, const mp_int *b); /* Barrett Reduction, computes a (mod b) with a precomputed value c * - * Assumes that 0 < a <= b*b, note if 0 > a > -(b*b) then you can merely - * compute the reduction as -1 * mp_reduce(mp_abs(a)) [pseudo code]. + * Assumes that 0 < x <= m*m, note if 0 > x > -(m*m) then you can merely + * compute the reduction as -1 * mp_reduce(mp_abs(x)) [pseudo code]. */ -int mp_reduce(mp_int *a, const mp_int *b, const mp_int *c); +int mp_reduce(mp_int *x, const mp_int *m, const mp_int *mu); /* setups the montgomery reduction */ -int mp_montgomery_setup(const mp_int *a, mp_digit *mp); +int mp_montgomery_setup(const mp_int *n, mp_digit *rho); /* computes a = B**n mod b without division or multiplication useful for * normalizing numbers in a Montgomery system. @@ -419,7 +422,7 @@ int mp_montgomery_setup(const mp_int *a, mp_digit *mp); int mp_montgomery_calc_normalization(mp_int *a, const mp_int *b); /* computes x/R == x (mod N) via Montgomery Reduction */ -int mp_montgomery_reduce(mp_int *a, const mp_int *m, mp_digit mp); +int mp_montgomery_reduce(mp_int *x, const mp_int *n, mp_digit rho); /* returns 1 if a is a valid DR modulus */ int mp_dr_is_modulus(const mp_int *a); @@ -427,8 +430,8 @@ int mp_dr_is_modulus(const mp_int *a); /* sets the value of "d" required for mp_dr_reduce */ void mp_dr_setup(const mp_int *a, mp_digit *d); -/* reduces a modulo b using the Diminished Radix method */ -int mp_dr_reduce(mp_int *a, const mp_int *b, mp_digit mp); +/* reduces a modulo n using the Diminished Radix method */ +int mp_dr_reduce(mp_int *x, const mp_int *n, mp_digit k); /* returns true if a can be reduced with mp_reduce_2k */ int mp_reduce_is_2k(const mp_int *a); @@ -448,8 +451,8 @@ int mp_reduce_2k_setup_l(const mp_int *a, mp_int *d); /* reduces a modulo b where b is of the form 2**p - k [0 <= a] */ int mp_reduce_2k_l(mp_int *a, const mp_int *n, const mp_int *d); -/* d = a**b (mod c) */ -int mp_exptmod(const mp_int *a, const mp_int *b, const mp_int *c, mp_int *d); +/* Y = G**X (mod P) */ +int mp_exptmod(const mp_int *G, const mp_int *X, const mp_int *P, mp_int *Y); /* ---> Primes <--- */ diff --git a/libtommath/tommath_private.h b/libtommath/tommath_private.h index 087ddcd..678edc4 100644 --- a/libtommath/tommath_private.h +++ b/libtommath/tommath_private.h @@ -76,6 +76,8 @@ int s_mp_exptmod(const mp_int *G, const mp_int *X, const mp_int *P, mp_int *Y, i void bn_reverse(unsigned char *s, int len); extern const char *mp_s_rmap; +extern const uint8_t mp_s_rmap_reverse[]; +extern const size_t mp_s_rmap_reverse_sz; /* Fancy macro to set an MPI from another type. * There are several things assumed: @@ -99,7 +101,7 @@ int func_name (mp_int * a, type b) \ } \ \ /* OR in the top four bits of the source */ \ - a->dp[0] |= (b >> ((sizeof(type) * 8u) - 4u)) & 15u; \ + a->dp[0] |= (mp_digit)(b >> ((sizeof(type) * 8u) - 4u)) & 15uL;\ \ /* shift the source up to the next four bits */ \ b <<= 4; \ -- cgit v0.12 From 0e5d21e88f45136f6ee23192492095d2c251ffa4 Mon Sep 17 00:00:00 2001 From: "jan.nijtmans" Date: Thu, 1 Mar 2018 22:27:00 +0000 Subject: Re-generate tclTomMath.h. Fix win32 build (due to the use of uint8_t) --- generic/tclTomMath.h | 48 +++++++++++++++++++++---------------------- libtommath/bn_mp_radix_smap.c | 2 +- libtommath/tommath_private.h | 2 +- 3 files changed, 26 insertions(+), 26 deletions(-) diff --git a/generic/tclTomMath.h b/generic/tclTomMath.h index df54ff5..e0f8497 100644 --- a/generic/tclTomMath.h +++ b/generic/tclTomMath.h @@ -26,9 +26,14 @@ extern "C" { #endif +/* MS Visual C++ doesn't have a 128bit type for words, so fall back to 32bit MPI's (where words are 64bit) */ +#if defined(_MSC_VER) || defined(__LLP64__) +# define MP_32BIT +#endif + /* detect 64-bit mode if possible */ -#if defined(NEVER) /* 128-bit ints fail in too many places */ -# if !(defined(MP_32BIT) || defined(MP_16BIT) || defined(MP_8BIT)) +#if defined(NEVER) +# if !(defined(MP_32BIT) || defined(MP_16BIT) || defined(MP_8BIT) || defined(_MSC_VER)) # define MP_64BIT # endif #endif @@ -73,12 +78,7 @@ typedef uint32_t mp_word; typedef uint64_t mp_digit; #define MP_DIGIT_DECLARED #endif -# if defined(_WIN32) -#ifndef MP_WORD_DECLARED -typedef unsigned __int128 mp_word; -#define MP_WORD_DECLARED -#endif -# elif defined(__GNUC__) +# if defined(__GNUC__) typedef unsigned long mp_word __attribute__((mode(TI))); # else /* it seems you have a problem @@ -124,7 +124,7 @@ typedef mp_digit mp_min_u32; /* use arc4random on platforms that support it */ #if defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__NetBSD__) || defined(__DragonFly__) # define MP_GEN_RANDOM() arc4random() -# define MP_GEN_RANDOM_MAX 0xffffffff +# define MP_GEN_RANDOM_MAX 0xffffffffu #endif /* use rand() as fall-back if there's no better rand function */ @@ -181,7 +181,7 @@ MODULE_SCOPE int KARATSUBA_MUL_CUTOFF, #endif /* size of comba arrays, should be at least 2 * 2**(BITS_PER_WORD - BITS_PER_DIGIT*2) */ -#define MP_WARRAY (1 << (((sizeof(mp_word) * CHAR_BIT) - (2 * DIGIT_BIT)) + 1)) +#define MP_WARRAY (1u << (((sizeof(mp_word) * CHAR_BIT) - (2 * DIGIT_BIT)) + 1)) /* the infamous mp_int structure */ #ifndef MP_INT_DECLARED @@ -271,9 +271,9 @@ int mp_set_int(mp_int *a, unsigned long b); int mp_set_long(mp_int *a, unsigned long b); */ -/* set a platform dependent unsigned long long value */ +/* set a platform dependent Tcl_WideUInt value */ /* -int mp_set_long_long(mp_int *a, unsigned long long b); +int mp_set_long_long(mp_int *a, Tcl_WideUInt b); */ /* get a 32-bit value */ @@ -286,9 +286,9 @@ unsigned long mp_get_int(const mp_int *a); unsigned long mp_get_long(const mp_int *a); */ -/* get a platform dependent unsigned long long value */ +/* get a platform dependent Tcl_WideUInt value */ /* -unsigned long long mp_get_long_long(const mp_int *a); +Tcl_WideUInt mp_get_long_long(const mp_int *a); */ /* initialize and set a digit */ @@ -553,7 +553,7 @@ int mp_sqrt(const mp_int *arg, mp_int *ret); /* special sqrt (mod prime) */ /* -int mp_sqrtmod_prime(const mp_int *arg, const mp_int *prime, mp_int *ret); +int mp_sqrtmod_prime(const mp_int *n, const mp_int *prime, mp_int *ret); */ /* is number a square? */ @@ -573,16 +573,16 @@ int mp_reduce_setup(mp_int *a, const mp_int *b); /* Barrett Reduction, computes a (mod b) with a precomputed value c * - * Assumes that 0 < a <= b*b, note if 0 > a > -(b*b) then you can merely - * compute the reduction as -1 * mp_reduce(mp_abs(a)) [pseudo code]. + * Assumes that 0 < x <= m*m, note if 0 > x > -(m*m) then you can merely + * compute the reduction as -1 * mp_reduce(mp_abs(x)) [pseudo code]. */ /* -int mp_reduce(mp_int *a, const mp_int *b, const mp_int *c); +int mp_reduce(mp_int *x, const mp_int *m, const mp_int *mu); */ /* setups the montgomery reduction */ /* -int mp_montgomery_setup(const mp_int *a, mp_digit *mp); +int mp_montgomery_setup(const mp_int *n, mp_digit *rho); */ /* computes a = B**n mod b without division or multiplication useful for @@ -594,7 +594,7 @@ int mp_montgomery_calc_normalization(mp_int *a, const mp_int *b); /* computes x/R == x (mod N) via Montgomery Reduction */ /* -int mp_montgomery_reduce(mp_int *a, const mp_int *m, mp_digit mp); +int mp_montgomery_reduce(mp_int *x, const mp_int *n, mp_digit rho); */ /* returns 1 if a is a valid DR modulus */ @@ -607,9 +607,9 @@ int mp_dr_is_modulus(const mp_int *a); void mp_dr_setup(const mp_int *a, mp_digit *d); */ -/* reduces a modulo b using the Diminished Radix method */ +/* reduces a modulo n using the Diminished Radix method */ /* -int mp_dr_reduce(mp_int *a, const mp_int *b, mp_digit mp); +int mp_dr_reduce(mp_int *x, const mp_int *n, mp_digit k); */ /* returns true if a can be reduced with mp_reduce_2k */ @@ -642,9 +642,9 @@ int mp_reduce_2k_setup_l(const mp_int *a, mp_int *d); int mp_reduce_2k_l(mp_int *a, const mp_int *n, const mp_int *d); */ -/* d = a**b (mod c) */ +/* Y = G**X (mod P) */ /* -int mp_exptmod(const mp_int *a, const mp_int *b, const mp_int *c, mp_int *d); +int mp_exptmod(const mp_int *G, const mp_int *X, const mp_int *P, mp_int *Y); */ /* ---> Primes <--- */ diff --git a/libtommath/bn_mp_radix_smap.c b/libtommath/bn_mp_radix_smap.c index 262775c..5d449f1 100644 --- a/libtommath/bn_mp_radix_smap.c +++ b/libtommath/bn_mp_radix_smap.c @@ -17,7 +17,7 @@ /* chars used in radix conversions */ const char *mp_s_rmap = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz+/"; -const uint8_t mp_s_rmap_reverse[] = { +const unsigned char mp_s_rmap_reverse[] = { 0xff, 0xff, 0xff, 0x3e, 0xff, 0xff, 0xff, 0x3f, /* ()*+,-./ */ 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, /* 01234567 */ 0x08, 0x09, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* 89:;<=>? */ diff --git a/libtommath/tommath_private.h b/libtommath/tommath_private.h index 11942d2..fd25141 100644 --- a/libtommath/tommath_private.h +++ b/libtommath/tommath_private.h @@ -76,7 +76,7 @@ int s_mp_exptmod(const mp_int *G, const mp_int *X, const mp_int *P, mp_int *Y, i void bn_reverse(unsigned char *s, int len); extern const char *mp_s_rmap; -extern const uint8_t mp_s_rmap_reverse[]; +extern const unsigned char mp_s_rmap_reverse[]; extern const size_t mp_s_rmap_reverse_sz; /* Fancy macro to set an MPI from another type. -- cgit v0.12 From 6c0170972f57e3d1daf5684c55eccfb2d78b386f Mon Sep 17 00:00:00 2001 From: sebres Date: Mon, 5 Mar 2018 17:37:21 +0000 Subject: fixes [1873ea0ee4f01b26]: wrong initialization of std-channels, if no std-handles available at all (e. g. non-console application, like "tk") --- generic/tclIO.c | 22 +++++++++++++--------- 1 file changed, 13 insertions(+), 9 deletions(-) diff --git a/generic/tclIO.c b/generic/tclIO.c index 2e1569f..4d3df65 100644 --- a/generic/tclIO.c +++ b/generic/tclIO.c @@ -626,17 +626,18 @@ Tcl_SetStdChannel( { ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&dataKey); + int init = channel ? 1 : -1; switch (type) { case TCL_STDIN: - tsdPtr->stdinInitialized = 1; + tsdPtr->stdinInitialized = init; tsdPtr->stdinChannel = channel; break; case TCL_STDOUT: - tsdPtr->stdoutInitialized = 1; + tsdPtr->stdoutInitialized = init; tsdPtr->stdoutChannel = channel; break; case TCL_STDERR: - tsdPtr->stderrInitialized = 1; + tsdPtr->stderrInitialized = init; tsdPtr->stderrChannel = channel; break; } @@ -673,8 +674,8 @@ Tcl_GetStdChannel( switch (type) { case TCL_STDIN: if (!tsdPtr->stdinInitialized) { + tsdPtr->stdinInitialized = -1; tsdPtr->stdinChannel = TclpGetDefaultStdChannel(TCL_STDIN); - tsdPtr->stdinInitialized = 1; /* * Artificially bump the refcount to ensure that the channel is @@ -686,6 +687,7 @@ Tcl_GetStdChannel( */ if (tsdPtr->stdinChannel != NULL) { + tsdPtr->stdinInitialized = 1; Tcl_RegisterChannel(NULL, tsdPtr->stdinChannel); } } @@ -693,9 +695,10 @@ Tcl_GetStdChannel( break; case TCL_STDOUT: if (!tsdPtr->stdoutInitialized) { + tsdPtr->stdoutInitialized = -1; tsdPtr->stdoutChannel = TclpGetDefaultStdChannel(TCL_STDOUT); - tsdPtr->stdoutInitialized = 1; if (tsdPtr->stdoutChannel != NULL) { + tsdPtr->stdoutInitialized = 1; Tcl_RegisterChannel(NULL, tsdPtr->stdoutChannel); } } @@ -703,9 +706,10 @@ Tcl_GetStdChannel( break; case TCL_STDERR: if (!tsdPtr->stderrInitialized) { + tsdPtr->stderrInitialized = -1; tsdPtr->stderrChannel = TclpGetDefaultStdChannel(TCL_STDERR); - tsdPtr->stderrInitialized = 1; if (tsdPtr->stderrChannel != NULL) { + tsdPtr->stderrInitialized = 1; Tcl_RegisterChannel(NULL, tsdPtr->stderrChannel); } } @@ -975,7 +979,7 @@ CheckForStdChannelsBeingClosed( ChannelState *statePtr = ((Channel *) chan)->state; ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&dataKey); - if (tsdPtr->stdinInitialized + if (tsdPtr->stdinInitialized == 1 && tsdPtr->stdinChannel != NULL && statePtr == ((Channel *)tsdPtr->stdinChannel)->state) { if (statePtr->refCount < 2) { @@ -983,7 +987,7 @@ CheckForStdChannelsBeingClosed( tsdPtr->stdinChannel = NULL; return; } - } else if (tsdPtr->stdoutInitialized + } else if (tsdPtr->stdoutInitialized == 1 && tsdPtr->stdoutChannel != NULL && statePtr == ((Channel *)tsdPtr->stdoutChannel)->state) { if (statePtr->refCount < 2) { @@ -991,7 +995,7 @@ CheckForStdChannelsBeingClosed( tsdPtr->stdoutChannel = NULL; return; } - } else if (tsdPtr->stderrInitialized + } else if (tsdPtr->stderrInitialized == 1 && tsdPtr->stderrChannel != NULL && statePtr == ((Channel *)tsdPtr->stderrChannel)->state) { if (statePtr->refCount < 2) { -- cgit v0.12 From 80c3bfdcaa069911ed98d7400fe426bc84ae8a56 Mon Sep 17 00:00:00 2001 From: dgp Date: Mon, 5 Mar 2018 19:29:12 +0000 Subject: Last bit of TIP 503 implementation. --- generic/tcl.h | 2 -- 1 file changed, 2 deletions(-) diff --git a/generic/tcl.h b/generic/tcl.h index 0d6549f..a3684c3 100644 --- a/generic/tcl.h +++ b/generic/tcl.h @@ -269,8 +269,6 @@ extern "C" { #ifndef CONST # define CONST const #endif -#define CONST84 const -#define CONST84_RETURN const #endif /* !TCL_NO_DEPRECATED */ -- cgit v0.12 From f406561f406ca970ae8d90dd4c4b752122423bfc Mon Sep 17 00:00:00 2001 From: dgp Date: Mon, 5 Mar 2018 20:00:06 +0000 Subject: Take the next step in TIPs 330 and 336, ending in 8.7 the USE_INTERP_RESULT and USE_INTERP_ERRORLINE directives to escape need to migrate to 8.6 interfaces. --- generic/tcl.h | 22 ---------------------- generic/tclResult.c | 17 ----------------- 2 files changed, 39 deletions(-) diff --git a/generic/tcl.h b/generic/tcl.h index 0d6549f..ccfd05e 100644 --- a/generic/tcl.h +++ b/generic/tcl.h @@ -468,31 +468,9 @@ typedef struct Tcl_Interp { /* TIP #330: Strongly discourage extensions from using the string * result. */ -#ifdef USE_INTERP_RESULT - char *result TCL_DEPRECATED_API("use Tcl_GetStringResult/Tcl_SetResult"); - /* If the last command returned a string - * result, this points to it. */ - void (*freeProc) (char *blockPtr) - TCL_DEPRECATED_API("use Tcl_GetStringResult/Tcl_SetResult"); - /* Zero means the string result is statically - * allocated. TCL_DYNAMIC means it was - * allocated with ckalloc and should be freed - * with ckfree. Other values give the address - * of function to invoke to free the result. - * Tcl_Eval must free it before executing next - * command. */ -#else char *resultDontUse; /* Don't use in extensions! */ void (*freeProcDontUse) (char *); /* Don't use in extensions! */ -#endif -#ifdef USE_INTERP_ERRORLINE - int errorLine TCL_DEPRECATED_API("use Tcl_GetErrorLine/Tcl_SetErrorLine"); - /* When TCL_ERROR is returned, this gives the - * line number within the command where the - * error occurred (1 if first line). */ -#else int errorLineDontUse; /* Don't use in extensions! */ -#endif } #endif /* !TCL_NO_DEPRECATED */ Tcl_Interp; diff --git a/generic/tclResult.c b/generic/tclResult.c index 57a6de5..a5ec4be 100644 --- a/generic/tclResult.c +++ b/generic/tclResult.c @@ -651,23 +651,6 @@ Tcl_AppendResultVA( } Tcl_AppendStringsToObjVA(objPtr, argList); Tcl_SetObjResult(interp, objPtr); - - /* - * Strictly we should call Tcl_GetStringResult(interp) here to make sure - * that interp->result is correct according to the old contract, but that - * makes the performance of much code (e.g. in Tk) absolutely awful. So we - * leave it out; code that really wants interp->result can just insert the - * calls to Tcl_GetStringResult() itself. [Patch 1041072 discussion] - */ - -#ifdef USE_INTERP_RESULT - /* - * Ensure that the interp->result is legal so old Tcl 7.* code still - * works. There's still embarrasingly much of it about... - */ - - (void) Tcl_GetStringResult(interp); -#endif /* USE_INTERP_RESULT */ } /* -- cgit v0.12 From d07756fc70e80d9862c042fdea7cbe7a1b222c07 Mon Sep 17 00:00:00 2001 From: dgp Date: Mon, 5 Mar 2018 20:30:38 +0000 Subject: WIP removing bytecode instructions that are no longer issued. --- generic/tclAssembly.c | 4 ++-- generic/tclCompile.h | 10 +++++----- generic/tclExecute.c | 10 ++++++++-- generic/tclOptimize.c | 4 ++-- tests/assemble.test | 24 ++++++++++++------------ 5 files changed, 29 insertions(+), 23 deletions(-) diff --git a/generic/tclAssembly.c b/generic/tclAssembly.c index bdca74c..66a9660 100644 --- a/generic/tclAssembly.c +++ b/generic/tclAssembly.c @@ -406,7 +406,7 @@ static const TalInstDesc TalInstructionTable[] = { {"jumpTrue", ASSEM_JUMP, INST_JUMP_TRUE1, 1, 0}, {"jumpTrue4", ASSEM_JUMP4, INST_JUMP_TRUE4, 1, 0}, {"label", ASSEM_LABEL, 0, 0, 0}, - {"land", ASSEM_1BYTE, INST_LAND, 2, 1}, +// {"land", ASSEM_1BYTE, INST_LAND, 2, 1}, {"lappend", ASSEM_LVT, (INST_LAPPEND_SCALAR1<<8 | INST_LAPPEND_SCALAR4), 1, 1}, @@ -434,7 +434,7 @@ static const TalInstDesc TalInstructionTable[] = { | INST_LOAD_ARRAY4), 1, 1}, {"loadArrayStk", ASSEM_1BYTE, INST_LOAD_ARRAY_STK, 2, 1}, {"loadStk", ASSEM_1BYTE, INST_LOAD_STK, 1, 1}, - {"lor", ASSEM_1BYTE, INST_LOR, 2, 1}, +// {"lor", ASSEM_1BYTE, INST_LOR, 2, 1}, {"lsetFlat", ASSEM_LSET_FLAT,INST_LSET_FLAT, INT_MIN,1}, {"lsetList", ASSEM_1BYTE, INST_LSET_LIST, 3, 1}, {"lshift", ASSEM_1BYTE, INST_LSHIFT, 2, 1}, diff --git a/generic/tclCompile.h b/generic/tclCompile.h index cf9b17c..705b2cd 100644 --- a/generic/tclCompile.h +++ b/generic/tclCompile.h @@ -572,8 +572,8 @@ typedef struct ByteCode { #define INST_JUMP_FALSE4 39 /* Opcodes 40 to 64 */ -#define INST_LOR 40 -#define INST_LAND 41 +//#define INST_LOR 40 +//#define INST_LAND 41 #define INST_BITOR 42 #define INST_BITXOR 43 #define INST_BITAND 44 @@ -601,8 +601,8 @@ typedef struct ByteCode { #define INST_CONTINUE 66 /* Opcodes 67 to 68 */ -#define INST_FOREACH_START4 67 /* DEPRECATED */ -#define INST_FOREACH_STEP4 68 /* DEPRECATED */ +//#define INST_FOREACH_START4 67 /* DEPRECATED */ +//#define INST_FOREACH_STEP4 68 /* DEPRECATED */ /* Opcodes 69 to 72 */ #define INST_BEGIN_CATCH4 69 @@ -694,7 +694,7 @@ typedef struct ByteCode { #define INST_DICT_LAPPEND 115 #define INST_DICT_FIRST 116 #define INST_DICT_NEXT 117 -#define INST_DICT_DONE 118 +//#define INST_DICT_DONE 118 #define INST_DICT_UPDATE_START 119 #define INST_DICT_UPDATE_END 120 diff --git a/generic/tclExecute.c b/generic/tclExecute.c index 83a5815..4cd4184 100644 --- a/generic/tclExecute.c +++ b/generic/tclExecute.c @@ -77,7 +77,7 @@ int tclTraceExec = 0; */ static const char *const operatorStrings[] = { - "||", "&&", "|", "^", "&", "==", "!=", "<", ">", "<=", ">=", "<<", ">>", + "|", "^", "&", "==", "!=", "<", ">", "<=", ">=", "<<", ">>", "+", "-", "*", "/", "%", "+", "-", "~", "!" }; @@ -3825,6 +3825,7 @@ TEBCresume( * This is really an unset operation these days. Do not issue. */ +#if 0 case INST_DICT_DONE: opnd = TclGetUInt4AtPtr(pc+1); TRACE(("%u => OK\n", opnd)); @@ -3844,6 +3845,7 @@ TEBCresume( } NEXT_INST_F(5, 0, 0); } +#endif /* * End of INST_UNSET instructions. @@ -4173,6 +4175,7 @@ TEBCresume( * and LAND is now handled by the expression compiler. */ +#if 0 case INST_LOR: case INST_LAND: { /* @@ -4211,6 +4214,7 @@ TEBCresume( TRACE(("%.20s %.20s => %d\n", O2S(valuePtr),O2S(value2Ptr),iResult)); NEXT_INST_F(1, 2, 1); } +#endif /* * ----------------------------------------------------------------- @@ -6321,6 +6325,7 @@ TEBCresume( TRACE(("=> CONTINUE!\n")); goto processExceptionReturn; +#if 0 { ForeachInfo *infoPtr; Var *iterVarPtr, *listVarPtr; @@ -6485,6 +6490,7 @@ TEBCresume( } } +#endif { ForeachInfo *infoPtr; Tcl_Obj *listPtr, **elements, *tmpPtr; @@ -9118,7 +9124,7 @@ IllegalExprOperandType( if (opcode == INST_EXPON) { operator = "**"; } else if (opcode <= INST_LNOT) { - operator = operatorStrings[opcode - INST_LOR]; + operator = operatorStrings[opcode - INST_BITOR]; } if (GetNumberFromObj(NULL, opndPtr, &ptr, &type) != TCL_OK) { diff --git a/generic/tclOptimize.c b/generic/tclOptimize.c index 8267a7d..48523d0 100644 --- a/generic/tclOptimize.c +++ b/generic/tclOptimize.c @@ -287,8 +287,8 @@ ConvertZeroEffectToNOP( case INST_INCR_ARRAY_STK: case INST_INCR_SCALAR_STK: case INST_INCR_STK: - case INST_LOR: - case INST_LAND: +// case INST_LOR: +// case INST_LAND: case INST_EQ: case INST_NEQ: case INST_LT: diff --git a/tests/assemble.test b/tests/assemble.test index 004d04d..ab7e923 100644 --- a/tests/assemble.test +++ b/tests/assemble.test @@ -532,18 +532,18 @@ test assemble-7.16 {incrStk} { -result 12 -cleanup {rename x {}} } -test assemble-7.17 {land/lor} { - -body { - proc x {a b} { - list \ - [assemble {load a; load b; land}] \ - [assemble {load a; load b; lor}] - } - list [x 0 0] [x 0 23] [x 35 0] [x 47 59] - } - -result {{0 0} {0 1} {0 1} {1 1}} - -cleanup {rename x {}} -} +#test assemble-7.17 {land/lor} { +# -body { +# proc x {a b} { +# list \ +# [assemble {load a; load b; land}] \ +# [assemble {load a; load b; lor}] +# } +# list [x 0 0] [x 0 23] [x 35 0] [x 47 59] +# } +# -result {{0 0} {0 1} {0 1} {1 1}} +# -cleanup {rename x {}} +#} test assemble-7.18 {lappendArrayStk} { -body { proc x {} { -- cgit v0.12 From 695856b85c783cd67abe39821919e6fe2635e14d Mon Sep 17 00:00:00 2001 From: dgp Date: Mon, 5 Mar 2018 20:58:32 +0000 Subject: unbreak --- generic/tclExecute.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/generic/tclExecute.c b/generic/tclExecute.c index 4cd4184..13a6aeb 100644 --- a/generic/tclExecute.c +++ b/generic/tclExecute.c @@ -3844,8 +3844,8 @@ TEBCresume( CACHE_STACK_INFO(); } NEXT_INST_F(5, 0, 0); - } #endif + } /* * End of INST_UNSET instructions. -- cgit v0.12 From 14a3439dd8dfe1533c6b80c40406f7ef420c57eb Mon Sep 17 00:00:00 2001 From: dgp Date: Mon, 5 Mar 2018 22:16:03 +0000 Subject: Remove all code supporting legacy instructions. --- generic/tclAssembly.c | 2 - generic/tclCompile.h | 7 -- generic/tclExecute.c | 237 -------------------------------------------------- generic/tclOptimize.c | 2 - tests/assemble.test | 12 --- 5 files changed, 260 deletions(-) diff --git a/generic/tclAssembly.c b/generic/tclAssembly.c index 66a9660..82071b2 100644 --- a/generic/tclAssembly.c +++ b/generic/tclAssembly.c @@ -406,7 +406,6 @@ static const TalInstDesc TalInstructionTable[] = { {"jumpTrue", ASSEM_JUMP, INST_JUMP_TRUE1, 1, 0}, {"jumpTrue4", ASSEM_JUMP4, INST_JUMP_TRUE4, 1, 0}, {"label", ASSEM_LABEL, 0, 0, 0}, -// {"land", ASSEM_1BYTE, INST_LAND, 2, 1}, {"lappend", ASSEM_LVT, (INST_LAPPEND_SCALAR1<<8 | INST_LAPPEND_SCALAR4), 1, 1}, @@ -434,7 +433,6 @@ static const TalInstDesc TalInstructionTable[] = { | INST_LOAD_ARRAY4), 1, 1}, {"loadArrayStk", ASSEM_1BYTE, INST_LOAD_ARRAY_STK, 2, 1}, {"loadStk", ASSEM_1BYTE, INST_LOAD_STK, 1, 1}, -// {"lor", ASSEM_1BYTE, INST_LOR, 2, 1}, {"lsetFlat", ASSEM_LSET_FLAT,INST_LSET_FLAT, INT_MIN,1}, {"lsetList", ASSEM_1BYTE, INST_LSET_LIST, 3, 1}, {"lshift", ASSEM_1BYTE, INST_LSHIFT, 2, 1}, diff --git a/generic/tclCompile.h b/generic/tclCompile.h index 705b2cd..bf5b3eb 100644 --- a/generic/tclCompile.h +++ b/generic/tclCompile.h @@ -572,8 +572,6 @@ typedef struct ByteCode { #define INST_JUMP_FALSE4 39 /* Opcodes 40 to 64 */ -//#define INST_LOR 40 -//#define INST_LAND 41 #define INST_BITOR 42 #define INST_BITXOR 43 #define INST_BITAND 44 @@ -600,10 +598,6 @@ typedef struct ByteCode { #define INST_BREAK 65 #define INST_CONTINUE 66 -/* Opcodes 67 to 68 */ -//#define INST_FOREACH_START4 67 /* DEPRECATED */ -//#define INST_FOREACH_STEP4 68 /* DEPRECATED */ - /* Opcodes 69 to 72 */ #define INST_BEGIN_CATCH4 69 #define INST_END_CATCH 70 @@ -694,7 +688,6 @@ typedef struct ByteCode { #define INST_DICT_LAPPEND 115 #define INST_DICT_FIRST 116 #define INST_DICT_NEXT 117 -//#define INST_DICT_DONE 118 #define INST_DICT_UPDATE_START 119 #define INST_DICT_UPDATE_END 120 diff --git a/generic/tclExecute.c b/generic/tclExecute.c index 13a6aeb..40ee298 100644 --- a/generic/tclExecute.c +++ b/generic/tclExecute.c @@ -3820,31 +3820,6 @@ TEBCresume( CACHE_STACK_INFO(); TRACE_ERROR(interp); goto gotError; - - /* - * This is really an unset operation these days. Do not issue. - */ - -#if 0 - case INST_DICT_DONE: - opnd = TclGetUInt4AtPtr(pc+1); - TRACE(("%u => OK\n", opnd)); - varPtr = LOCAL(opnd); - while (TclIsVarLink(varPtr)) { - varPtr = varPtr->value.linkPtr; - } - if (TclIsVarDirectUnsettable(varPtr) && !TclIsVarInHash(varPtr)) { - if (!TclIsVarUndefined(varPtr)) { - TclDecrRefCount(varPtr->value.objPtr); - } - varPtr->value.objPtr = NULL; - } else { - DECACHE_STACK_INFO(); - TclPtrUnsetVarIdx(interp, varPtr, NULL, NULL, NULL, 0, opnd); - CACHE_STACK_INFO(); - } - NEXT_INST_F(5, 0, 0); -#endif } /* @@ -4171,52 +4146,6 @@ TEBCresume( } /* - * These two instructions are now redundant: the complete logic of the LOR - * and LAND is now handled by the expression compiler. - */ - -#if 0 - case INST_LOR: - case INST_LAND: { - /* - * Operands must be boolean or numeric. No int->double conversions are - * performed. - */ - - int i1, i2, iResult; - - value2Ptr = OBJ_AT_TOS; - valuePtr = OBJ_UNDER_TOS; - if (TclGetBooleanFromObj(NULL, valuePtr, &i1) != TCL_OK) { - TRACE(("\"%.20s\" => ILLEGAL TYPE %s \n", O2S(valuePtr), - (valuePtr->typePtr? valuePtr->typePtr->name : "null"))); - DECACHE_STACK_INFO(); - IllegalExprOperandType(interp, pc, valuePtr); - CACHE_STACK_INFO(); - goto gotError; - } - - if (TclGetBooleanFromObj(NULL, value2Ptr, &i2) != TCL_OK) { - TRACE(("\"%.20s\" => ILLEGAL TYPE %s \n", O2S(value2Ptr), - (value2Ptr->typePtr? value2Ptr->typePtr->name : "null"))); - DECACHE_STACK_INFO(); - IllegalExprOperandType(interp, pc, value2Ptr); - CACHE_STACK_INFO(); - goto gotError; - } - - if (*pc == INST_LOR) { - iResult = (i1 || i2); - } else { - iResult = (i1 && i2); - } - objResultPtr = TCONST(iResult); - TRACE(("%.20s %.20s => %d\n", O2S(valuePtr),O2S(value2Ptr),iResult)); - NEXT_INST_F(1, 2, 1); - } -#endif - - /* * ----------------------------------------------------------------- * Start of general introspector instructions. */ @@ -6325,172 +6254,6 @@ TEBCresume( TRACE(("=> CONTINUE!\n")); goto processExceptionReturn; -#if 0 - { - ForeachInfo *infoPtr; - Var *iterVarPtr, *listVarPtr; - Tcl_Obj *oldValuePtr, *listPtr, **elements; - ForeachVarList *varListPtr; - int numLists, listTmpIndex, listLen, numVars; - size_t iterNum; - int varIndex, valIndex, continueLoop, j, iterTmpIndex; - long i; - - case INST_FOREACH_START4: /* DEPRECATED */ - /* - * Initialize the temporary local var that holds the count of the - * number of iterations of the loop body to -1. - */ - - opnd = TclGetUInt4AtPtr(pc+1); - infoPtr = codePtr->auxDataArrayPtr[opnd].clientData; - iterTmpIndex = infoPtr->loopCtTemp; - iterVarPtr = LOCAL(iterTmpIndex); - oldValuePtr = iterVarPtr->value.objPtr; - - if (oldValuePtr == NULL) { - TclNewIntObj(iterVarPtr->value.objPtr, -1); - Tcl_IncrRefCount(iterVarPtr->value.objPtr); - } else { - TclSetIntObj(oldValuePtr, -1); - } - TRACE(("%u => loop iter count temp %d\n", opnd, iterTmpIndex)); - -#ifndef TCL_COMPILE_DEBUG - /* - * Remark that the compiler ALWAYS sets INST_FOREACH_STEP4 immediately - * after INST_FOREACH_START4 - let us just fall through instead of - * jumping back to the top. - */ - - pc += 5; - TCL_DTRACE_INST_NEXT(); -#else - NEXT_INST_F(5, 0, 0); -#endif - - case INST_FOREACH_STEP4: /* DEPRECATED */ - /* - * "Step" a foreach loop (i.e., begin its next iteration) by assigning - * the next value list element to each loop var. - */ - - opnd = TclGetUInt4AtPtr(pc+1); - TRACE(("%u => ", opnd)); - infoPtr = codePtr->auxDataArrayPtr[opnd].clientData; - numLists = infoPtr->numLists; - - /* - * Increment the temp holding the loop iteration number. - */ - - iterVarPtr = LOCAL(infoPtr->loopCtTemp); - valuePtr = iterVarPtr->value.objPtr; - iterNum = (size_t)valuePtr->internalRep.wideValue + 1; - TclSetIntObj(valuePtr, iterNum); - - /* - * Check whether all value lists are exhausted and we should stop the - * loop. - */ - - continueLoop = 0; - listTmpIndex = infoPtr->firstValueTemp; - for (i = 0; i < numLists; i++) { - varListPtr = infoPtr->varLists[i]; - numVars = varListPtr->numVars; - - listVarPtr = LOCAL(listTmpIndex); - listPtr = listVarPtr->value.objPtr; - if (TclListObjLength(interp, listPtr, &listLen) != TCL_OK) { - TRACE_APPEND(("ERROR converting list %ld, \"%.30s\": %s\n", - i, O2S(listPtr), O2S(Tcl_GetObjResult(interp)))); - goto gotError; - } - if ((size_t)listLen > iterNum * numVars) { - continueLoop = 1; - } - listTmpIndex++; - } - - /* - * If some var in some var list still has a remaining list element - * iterate one more time. Assign to var the next element from its - * value list. We already checked above that each list temp holds a - * valid list object (by calling Tcl_ListObjLength), but cannot rely - * on that check remaining valid: one list could have been shimmered - * as a side effect of setting a traced variable. - */ - - if (continueLoop) { - listTmpIndex = infoPtr->firstValueTemp; - for (i = 0; i < numLists; i++) { - varListPtr = infoPtr->varLists[i]; - numVars = varListPtr->numVars; - - listVarPtr = LOCAL(listTmpIndex); - listPtr = TclListObjCopy(NULL, listVarPtr->value.objPtr); - TclListObjGetElements(interp, listPtr, &listLen, &elements); - - valIndex = (iterNum * numVars); - for (j = 0; j < numVars; j++) { - if (valIndex >= listLen) { - TclNewObj(valuePtr); - } else { - valuePtr = elements[valIndex]; - } - - varIndex = varListPtr->varIndexes[j]; - varPtr = LOCAL(varIndex); - while (TclIsVarLink(varPtr)) { - varPtr = varPtr->value.linkPtr; - } - if (TclIsVarDirectWritable(varPtr)) { - value2Ptr = varPtr->value.objPtr; - if (valuePtr != value2Ptr) { - if (value2Ptr != NULL) { - TclDecrRefCount(value2Ptr); - } - varPtr->value.objPtr = valuePtr; - Tcl_IncrRefCount(valuePtr); - } - } else { - DECACHE_STACK_INFO(); - if (TclPtrSetVarIdx(interp, varPtr, NULL, NULL, NULL, - valuePtr, TCL_LEAVE_ERR_MSG, varIndex)==NULL){ - CACHE_STACK_INFO(); - TRACE_APPEND(( - "ERROR init. index temp %d: %s\n", - varIndex, O2S(Tcl_GetObjResult(interp)))); - TclDecrRefCount(listPtr); - goto gotError; - } - CACHE_STACK_INFO(); - } - valIndex++; - } - TclDecrRefCount(listPtr); - listTmpIndex++; - } - } - TRACE_APPEND(("%d lists, iter %" TCL_Z_MODIFIER "d, %s loop\n", - numLists, iterNum, (continueLoop? "continue" : "exit"))); - - /* - * Run-time peep-hole optimisation: the compiler ALWAYS follows - * INST_FOREACH_STEP4 with an INST_JUMP_FALSE. We just skip that - * instruction and jump direct from here. - */ - - pc += 5; - if (*pc == INST_JUMP_FALSE1) { - NEXT_INST_F((continueLoop? 2 : TclGetInt1AtPtr(pc+1)), 0, 0); - } else { - NEXT_INST_F((continueLoop? 5 : TclGetInt4AtPtr(pc+1)), 0, 0); - } - - } -#endif { ForeachInfo *infoPtr; Tcl_Obj *listPtr, **elements, *tmpPtr; diff --git a/generic/tclOptimize.c b/generic/tclOptimize.c index 48523d0..abd312d 100644 --- a/generic/tclOptimize.c +++ b/generic/tclOptimize.c @@ -287,8 +287,6 @@ ConvertZeroEffectToNOP( case INST_INCR_ARRAY_STK: case INST_INCR_SCALAR_STK: case INST_INCR_STK: -// case INST_LOR: -// case INST_LAND: case INST_EQ: case INST_NEQ: case INST_LT: diff --git a/tests/assemble.test b/tests/assemble.test index ab7e923..73c3d8f 100644 --- a/tests/assemble.test +++ b/tests/assemble.test @@ -532,18 +532,6 @@ test assemble-7.16 {incrStk} { -result 12 -cleanup {rename x {}} } -#test assemble-7.17 {land/lor} { -# -body { -# proc x {a b} { -# list \ -# [assemble {load a; load b; land}] \ -# [assemble {load a; load b; lor}] -# } -# list [x 0 0] [x 0 23] [x 35 0] [x 47 59] -# } -# -result {{0 0} {0 1} {0 1} {1 1}} -# -cleanup {rename x {}} -#} test assemble-7.18 {lappendArrayStk} { -body { proc x {} { -- cgit v0.12 From a6dd04e6da2cbdaad46f5bbc909837de0df8a3be Mon Sep 17 00:00:00 2001 From: dgp Date: Tue, 6 Mar 2018 04:08:54 +0000 Subject: experiment --- generic/tclCompile.h | 305 +++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 305 insertions(+) diff --git a/generic/tclCompile.h b/generic/tclCompile.h index bf5b3eb..8c4d544 100644 --- a/generic/tclCompile.h +++ b/generic/tclCompile.h @@ -523,6 +523,309 @@ typedef struct ByteCode { * tclExecute.c. */ +#if 1 +enum TclInstruction { + +/* Opcodes 0 to 9 */ +INST_DONE = 0, +INST_PUSH1, +INST_PUSH4, +INST_POP, +INST_DUP, +INST_STR_CONCAT1, +INST_INVOKE_STK1, +INST_INVOKE_STK4, +INST_EVAL_STK, +INST_EXPR_STK, + +/* Opcodes 10 to 23 */ +INST_LOAD_SCALAR1, +INST_LOAD_SCALAR4, +INST_LOAD_SCALAR_STK, +INST_LOAD_ARRAY1, +INST_LOAD_ARRAY4, +INST_LOAD_ARRAY_STK, +INST_LOAD_STK, +INST_STORE_SCALAR1, +INST_STORE_SCALAR4, +INST_STORE_SCALAR_STK, +INST_STORE_ARRAY1, +INST_STORE_ARRAY4, +INST_STORE_ARRAY_STK, +INST_STORE_STK, + +/* Opcodes 24 to 33 */ +INST_INCR_SCALAR1, +INST_INCR_SCALAR_STK, +INST_INCR_ARRAY1, +INST_INCR_ARRAY_STK, +INST_INCR_STK, +INST_INCR_SCALAR1_IMM, +INST_INCR_SCALAR_STK_IMM, +INST_INCR_ARRAY1_IMM, +INST_INCR_ARRAY_STK_IMM, +INST_INCR_STK_IMM, + +/* Opcodes 34 to 39 */ +INST_JUMP1, +INST_JUMP4, +INST_JUMP_TRUE1, +INST_JUMP_TRUE4, +INST_JUMP_FALSE1, +INST_JUMP_FALSE4, + +/* Opcodes 42 to 64 */ +INST_BITOR=42, +INST_BITXOR, +INST_BITAND, +INST_EQ, +INST_NEQ, +INST_LT, +INST_GT, +INST_LE, +INST_GE, +INST_LSHIFT, +INST_RSHIFT, +INST_ADD, +INST_SUB, +INST_MULT, +INST_DIV, +INST_MOD, +INST_UPLUS, +INST_UMINUS, +INST_BITNOT, +INST_LNOT, +INST_TRY_CVT_TO_NUMERIC=64 + + + +}; + + + + +/* Opcodes 65 to 66 */ +#define INST_BREAK 65 +#define INST_CONTINUE 66 + +/* Opcodes 69 to 72 */ +#define INST_BEGIN_CATCH4 69 +#define INST_END_CATCH 70 +#define INST_PUSH_RESULT 71 +#define INST_PUSH_RETURN_CODE 72 + +/* Opcodes 73 to 78 */ +#define INST_STR_EQ 73 +#define INST_STR_NEQ 74 +#define INST_STR_CMP 75 +#define INST_STR_LEN 76 +#define INST_STR_INDEX 77 +#define INST_STR_MATCH 78 + +/* Opcodes 78 to 81 */ +#define INST_LIST 79 +#define INST_LIST_INDEX 80 +#define INST_LIST_LENGTH 81 + +/* Opcodes 82 to 87 */ +#define INST_APPEND_SCALAR1 82 +#define INST_APPEND_SCALAR4 83 +#define INST_APPEND_ARRAY1 84 +#define INST_APPEND_ARRAY4 85 +#define INST_APPEND_ARRAY_STK 86 +#define INST_APPEND_STK 87 + +/* Opcodes 88 to 93 */ +#define INST_LAPPEND_SCALAR1 88 +#define INST_LAPPEND_SCALAR4 89 +#define INST_LAPPEND_ARRAY1 90 +#define INST_LAPPEND_ARRAY4 91 +#define INST_LAPPEND_ARRAY_STK 92 +#define INST_LAPPEND_STK 93 + +/* TIP #22 - LINDEX operator with flat arg list */ + +#define INST_LIST_INDEX_MULTI 94 + +/* + * TIP #33 - 'lset' command. Code gen also required a Forth-like + * OVER operation. + */ + +#define INST_OVER 95 +#define INST_LSET_LIST 96 +#define INST_LSET_FLAT 97 + +/* TIP#90 - 'return' command. */ + +#define INST_RETURN_IMM 98 + +/* TIP#123 - exponentiation operator. */ + +#define INST_EXPON 99 + +/* TIP #157 - {*}... (word expansion) language syntax support. */ + +#define INST_EXPAND_START 100 +#define INST_EXPAND_STKTOP 101 +#define INST_INVOKE_EXPANDED 102 + +/* + * TIP #57 - 'lassign' command. Code generation requires immediate + * LINDEX and LRANGE operators. + */ + +#define INST_LIST_INDEX_IMM 103 +#define INST_LIST_RANGE_IMM 104 + +#define INST_START_CMD 105 + +#define INST_LIST_IN 106 +#define INST_LIST_NOT_IN 107 + +#define INST_PUSH_RETURN_OPTIONS 108 +#define INST_RETURN_STK 109 + +/* + * Dictionary (TIP#111) related commands. + */ + +#define INST_DICT_GET 110 +#define INST_DICT_SET 111 +#define INST_DICT_UNSET 112 +#define INST_DICT_INCR_IMM 113 +#define INST_DICT_APPEND 114 +#define INST_DICT_LAPPEND 115 +#define INST_DICT_FIRST 116 +#define INST_DICT_NEXT 117 +#define INST_DICT_UPDATE_START 119 +#define INST_DICT_UPDATE_END 120 + +/* + * Instruction to support jumps defined by tables (instead of the classic + * [switch] technique of chained comparisons). + */ + +#define INST_JUMP_TABLE 121 + +/* + * Instructions to support compilation of global, variable, upvar and + * [namespace upvar]. + */ + +#define INST_UPVAR 122 +#define INST_NSUPVAR 123 +#define INST_VARIABLE 124 + +/* Instruction to support compiling syntax error to bytecode */ + +#define INST_SYNTAX 125 + +/* Instruction to reverse N items on top of stack */ + +#define INST_REVERSE 126 + +/* regexp instruction */ + +#define INST_REGEXP 127 + +/* For [info exists] compilation */ +#define INST_EXIST_SCALAR 128 +#define INST_EXIST_ARRAY 129 +#define INST_EXIST_ARRAY_STK 130 +#define INST_EXIST_STK 131 + +/* For [subst] compilation */ +#define INST_NOP 132 +#define INST_RETURN_CODE_BRANCH 133 + +/* For [unset] compilation */ +#define INST_UNSET_SCALAR 134 +#define INST_UNSET_ARRAY 135 +#define INST_UNSET_ARRAY_STK 136 +#define INST_UNSET_STK 137 + +/* For [dict with], [dict exists], [dict create] and [dict merge] */ +#define INST_DICT_EXPAND 138 +#define INST_DICT_RECOMBINE_STK 139 +#define INST_DICT_RECOMBINE_IMM 140 +#define INST_DICT_EXISTS 141 +#define INST_DICT_VERIFY 142 + +/* For [string map] and [regsub] compilation */ +#define INST_STR_MAP 143 +#define INST_STR_FIND 144 +#define INST_STR_FIND_LAST 145 +#define INST_STR_RANGE_IMM 146 +#define INST_STR_RANGE 147 + +/* For operations to do with coroutines and other NRE-manipulators */ +#define INST_YIELD 148 +#define INST_COROUTINE_NAME 149 +#define INST_TAILCALL 150 + +/* For compilation of basic information operations */ +#define INST_NS_CURRENT 151 +#define INST_INFO_LEVEL_NUM 152 +#define INST_INFO_LEVEL_ARGS 153 +#define INST_RESOLVE_COMMAND 154 + +/* For compilation relating to TclOO */ +#define INST_TCLOO_SELF 155 +#define INST_TCLOO_CLASS 156 +#define INST_TCLOO_NS 157 +#define INST_TCLOO_IS_OBJECT 158 + +/* For compilation of [array] subcommands */ +#define INST_ARRAY_EXISTS_STK 159 +#define INST_ARRAY_EXISTS_IMM 160 +#define INST_ARRAY_MAKE_STK 161 +#define INST_ARRAY_MAKE_IMM 162 + +#define INST_INVOKE_REPLACE 163 + +#define INST_LIST_CONCAT 164 + +#define INST_EXPAND_DROP 165 + +/* New foreach implementation */ +#define INST_FOREACH_START 166 +#define INST_FOREACH_STEP 167 +#define INST_FOREACH_END 168 +#define INST_LMAP_COLLECT 169 + +/* For compilation of [string trim] and related */ +#define INST_STR_TRIM 170 +#define INST_STR_TRIM_LEFT 171 +#define INST_STR_TRIM_RIGHT 172 + +#define INST_CONCAT_STK 173 + +#define INST_STR_UPPER 174 +#define INST_STR_LOWER 175 +#define INST_STR_TITLE 176 +#define INST_STR_REPLACE 177 + +#define INST_ORIGIN_COMMAND 178 + +#define INST_TCLOO_NEXT 179 +#define INST_TCLOO_NEXT_CLASS 180 + +#define INST_YIELD_TO_INVOKE 181 + +#define INST_NUM_TYPE 182 +#define INST_TRY_CVT_TO_BOOLEAN 183 +#define INST_STR_CLASS 184 + +#define INST_LAPPEND_LIST 185 +#define INST_LAPPEND_LIST_ARRAY 186 +#define INST_LAPPEND_LIST_ARRAY_STK 187 +#define INST_LAPPEND_LIST_STK 188 + +#define INST_CLOCK_READ 189 + +#else + /* Opcodes 0 to 9 */ #define INST_DONE 0 #define INST_PUSH1 1 @@ -814,6 +1117,8 @@ typedef struct ByteCode { #define INST_CLOCK_READ 189 +#endif + /* The last opcode */ #define LAST_INST_OPCODE 189 -- cgit v0.12 From 54654ae7e480be0e9a929d0fe9c3c5ba6d46535c Mon Sep 17 00:00:00 2001 From: dgp Date: Tue, 6 Mar 2018 05:27:21 +0000 Subject: Convert macros to enums - constrained by need for matching table. --- generic/tclCompile.c | 16 +-- generic/tclCompile.h | 282 ++++++++++++++++++++++------------------------- generic/tclDisassemble.c | 2 +- generic/tclExecute.c | 4 +- 4 files changed, 143 insertions(+), 161 deletions(-) diff --git a/generic/tclCompile.c b/generic/tclCompile.c index 52c1f11..cc65d12 100644 --- a/generic/tclCompile.c +++ b/generic/tclCompile.c @@ -129,9 +129,9 @@ InstructionDesc const tclInstructionTable[] = { {"jumpFalse4", 5, -1, 1, {OPERAND_OFFSET4}}, /* Jump relative to (pc + op4) if stktop expr object is false */ - {"lor", 1, -1, 0, {OPERAND_NONE}}, +// {"lor", 1, -1, 0, {OPERAND_NONE}}, /* Logical or: push (stknext || stktop) */ - {"land", 1, -1, 0, {OPERAND_NONE}}, +// {"land", 1, -1, 0, {OPERAND_NONE}}, /* Logical and: push (stknext && stktop) */ {"bitor", 1, -1, 0, {OPERAND_NONE}}, /* Bitwise or: push (stknext | stktop) */ @@ -173,9 +173,9 @@ InstructionDesc const tclInstructionTable[] = { /* Bitwise not: push ~stktop */ {"not", 1, 0, 0, {OPERAND_NONE}}, /* Logical not: push !stktop */ - {"callBuiltinFunc1", 2, 1, 1, {OPERAND_UINT1}}, +// {"callBuiltinFunc1", 2, 1, 1, {OPERAND_UINT1}}, /* Call builtin math function with index op1; any args are on stk */ - {"callFunc1", 2, INT_MIN, 1, {OPERAND_UINT1}}, +// {"callFunc1", 2, INT_MIN, 1, {OPERAND_UINT1}}, /* Call non-builtin func objv[0]; = */ {"tryCvtToNumeric", 1, 0, 0, {OPERAND_NONE}}, /* Try converting stktop to first int then double if possible. */ @@ -186,10 +186,10 @@ InstructionDesc const tclInstructionTable[] = { /* Skip to next iteration of closest enclosing loop; if none, return * TCL_CONTINUE code. */ - {"foreach_start4", 5, 0, 1, {OPERAND_AUX4}}, +// {"foreach_start4", 5, 0, 1, {OPERAND_AUX4}}, /* Initialize execution of a foreach loop. Operand is aux data index * of the ForeachInfo structure for the foreach command. */ - {"foreach_step4", 5, +1, 1, {OPERAND_AUX4}}, +// {"foreach_step4", 5, +1, 1, {OPERAND_AUX4}}, /* "Step" or begin next iteration of foreach loop. Push 0 if to * terminate loop, else push 1. */ @@ -340,7 +340,7 @@ InstructionDesc const tclInstructionTable[] = { {"dictNext", 5, +3, 1, {OPERAND_LVT4}}, /* Get the next iteration from the iterator in op4's local scalar. * Stack: ... => ... value key doneBool */ - {"dictDone", 5, 0, 1, {OPERAND_LVT4}}, +// {"dictDone", 5, 0, 1, {OPERAND_LVT4}}, /* Terminate the iterator in op4's local scalar. Use unsetScalar * instead (with 0 for flags). */ {"dictUpdateStart", 9, 0, 2, {OPERAND_LVT4, OPERAND_AUX4}}, @@ -1428,7 +1428,7 @@ TclInitCompileEnv( { Interp *iPtr = (Interp *) interp; - assert(tclInstructionTable[LAST_INST_OPCODE+1].name == NULL); + assert(tclInstructionTable[LAST_INST_OPCODE].name == NULL); envPtr->iPtr = iPtr; envPtr->source = stringPtr; diff --git a/generic/tclCompile.h b/generic/tclCompile.h index 8c4d544..b84cd48 100644 --- a/generic/tclCompile.h +++ b/generic/tclCompile.h @@ -575,7 +575,7 @@ INST_JUMP_FALSE1, INST_JUMP_FALSE4, /* Opcodes 42 to 64 */ -INST_BITOR=42, +INST_BITOR, INST_BITXOR, INST_BITAND, INST_EQ, @@ -595,234 +595,216 @@ INST_UPLUS, INST_UMINUS, INST_BITNOT, INST_LNOT, -INST_TRY_CVT_TO_NUMERIC=64 - - - -}; - - - +INST_TRY_CVT_TO_NUMERIC, /* Opcodes 65 to 66 */ -#define INST_BREAK 65 -#define INST_CONTINUE 66 +INST_BREAK, +INST_CONTINUE, /* Opcodes 69 to 72 */ -#define INST_BEGIN_CATCH4 69 -#define INST_END_CATCH 70 -#define INST_PUSH_RESULT 71 -#define INST_PUSH_RETURN_CODE 72 +INST_BEGIN_CATCH4, +INST_END_CATCH, +INST_PUSH_RESULT, +INST_PUSH_RETURN_CODE, /* Opcodes 73 to 78 */ -#define INST_STR_EQ 73 -#define INST_STR_NEQ 74 -#define INST_STR_CMP 75 -#define INST_STR_LEN 76 -#define INST_STR_INDEX 77 -#define INST_STR_MATCH 78 - -/* Opcodes 78 to 81 */ -#define INST_LIST 79 -#define INST_LIST_INDEX 80 -#define INST_LIST_LENGTH 81 +INST_STR_EQ, +INST_STR_NEQ, +INST_STR_CMP, +INST_STR_LEN, +INST_STR_INDEX, +INST_STR_MATCH, + +/* Opcodes 79 to 81 */ +INST_LIST, +INST_LIST_INDEX, +INST_LIST_LENGTH, /* Opcodes 82 to 87 */ -#define INST_APPEND_SCALAR1 82 -#define INST_APPEND_SCALAR4 83 -#define INST_APPEND_ARRAY1 84 -#define INST_APPEND_ARRAY4 85 -#define INST_APPEND_ARRAY_STK 86 -#define INST_APPEND_STK 87 +INST_APPEND_SCALAR1, +INST_APPEND_SCALAR4, +INST_APPEND_ARRAY1, +INST_APPEND_ARRAY4, +INST_APPEND_ARRAY_STK, +INST_APPEND_STK, /* Opcodes 88 to 93 */ -#define INST_LAPPEND_SCALAR1 88 -#define INST_LAPPEND_SCALAR4 89 -#define INST_LAPPEND_ARRAY1 90 -#define INST_LAPPEND_ARRAY4 91 -#define INST_LAPPEND_ARRAY_STK 92 -#define INST_LAPPEND_STK 93 +INST_LAPPEND_SCALAR1, +INST_LAPPEND_SCALAR4, +INST_LAPPEND_ARRAY1, +INST_LAPPEND_ARRAY4, +INST_LAPPEND_ARRAY_STK, +INST_LAPPEND_STK, /* TIP #22 - LINDEX operator with flat arg list */ - -#define INST_LIST_INDEX_MULTI 94 +INST_LIST_INDEX_MULTI, /* * TIP #33 - 'lset' command. Code gen also required a Forth-like * OVER operation. */ - -#define INST_OVER 95 -#define INST_LSET_LIST 96 -#define INST_LSET_FLAT 97 +INST_OVER, +INST_LSET_LIST, +INST_LSET_FLAT, /* TIP#90 - 'return' command. */ - -#define INST_RETURN_IMM 98 +INST_RETURN_IMM, /* TIP#123 - exponentiation operator. */ - -#define INST_EXPON 99 +INST_EXPON, /* TIP #157 - {*}... (word expansion) language syntax support. */ - -#define INST_EXPAND_START 100 -#define INST_EXPAND_STKTOP 101 -#define INST_INVOKE_EXPANDED 102 +INST_EXPAND_START, +INST_EXPAND_STKTOP, +INST_INVOKE_EXPANDED, /* * TIP #57 - 'lassign' command. Code generation requires immediate * LINDEX and LRANGE operators. */ - -#define INST_LIST_INDEX_IMM 103 -#define INST_LIST_RANGE_IMM 104 - -#define INST_START_CMD 105 - -#define INST_LIST_IN 106 -#define INST_LIST_NOT_IN 107 - -#define INST_PUSH_RETURN_OPTIONS 108 -#define INST_RETURN_STK 109 +INST_LIST_INDEX_IMM, +INST_LIST_RANGE_IMM, +INST_START_CMD, +INST_LIST_IN, +INST_LIST_NOT_IN, +INST_PUSH_RETURN_OPTIONS, +INST_RETURN_STK, /* * Dictionary (TIP#111) related commands. */ - -#define INST_DICT_GET 110 -#define INST_DICT_SET 111 -#define INST_DICT_UNSET 112 -#define INST_DICT_INCR_IMM 113 -#define INST_DICT_APPEND 114 -#define INST_DICT_LAPPEND 115 -#define INST_DICT_FIRST 116 -#define INST_DICT_NEXT 117 -#define INST_DICT_UPDATE_START 119 -#define INST_DICT_UPDATE_END 120 +INST_DICT_GET, +INST_DICT_SET, +INST_DICT_UNSET, +INST_DICT_INCR_IMM, +INST_DICT_APPEND, +INST_DICT_LAPPEND, +INST_DICT_FIRST, +INST_DICT_NEXT, +INST_DICT_UPDATE_START, +INST_DICT_UPDATE_END, /* * Instruction to support jumps defined by tables (instead of the classic * [switch] technique of chained comparisons). */ - -#define INST_JUMP_TABLE 121 +INST_JUMP_TABLE, /* * Instructions to support compilation of global, variable, upvar and * [namespace upvar]. */ - -#define INST_UPVAR 122 -#define INST_NSUPVAR 123 -#define INST_VARIABLE 124 +INST_UPVAR, +INST_NSUPVAR, +INST_VARIABLE, /* Instruction to support compiling syntax error to bytecode */ - -#define INST_SYNTAX 125 +INST_SYNTAX, /* Instruction to reverse N items on top of stack */ - -#define INST_REVERSE 126 +INST_REVERSE, /* regexp instruction */ - -#define INST_REGEXP 127 +INST_REGEXP, /* For [info exists] compilation */ -#define INST_EXIST_SCALAR 128 -#define INST_EXIST_ARRAY 129 -#define INST_EXIST_ARRAY_STK 130 -#define INST_EXIST_STK 131 +INST_EXIST_SCALAR, +INST_EXIST_ARRAY, +INST_EXIST_ARRAY_STK, +INST_EXIST_STK, /* For [subst] compilation */ -#define INST_NOP 132 -#define INST_RETURN_CODE_BRANCH 133 +INST_NOP, +INST_RETURN_CODE_BRANCH, /* For [unset] compilation */ -#define INST_UNSET_SCALAR 134 -#define INST_UNSET_ARRAY 135 -#define INST_UNSET_ARRAY_STK 136 -#define INST_UNSET_STK 137 +INST_UNSET_SCALAR, +INST_UNSET_ARRAY, +INST_UNSET_ARRAY_STK, +INST_UNSET_STK, /* For [dict with], [dict exists], [dict create] and [dict merge] */ -#define INST_DICT_EXPAND 138 -#define INST_DICT_RECOMBINE_STK 139 -#define INST_DICT_RECOMBINE_IMM 140 -#define INST_DICT_EXISTS 141 -#define INST_DICT_VERIFY 142 +INST_DICT_EXPAND, +INST_DICT_RECOMBINE_STK, +INST_DICT_RECOMBINE_IMM, +INST_DICT_EXISTS, +INST_DICT_VERIFY, /* For [string map] and [regsub] compilation */ -#define INST_STR_MAP 143 -#define INST_STR_FIND 144 -#define INST_STR_FIND_LAST 145 -#define INST_STR_RANGE_IMM 146 -#define INST_STR_RANGE 147 +INST_STR_MAP, +INST_STR_FIND, +INST_STR_FIND_LAST, +INST_STR_RANGE_IMM, +INST_STR_RANGE, /* For operations to do with coroutines and other NRE-manipulators */ -#define INST_YIELD 148 -#define INST_COROUTINE_NAME 149 -#define INST_TAILCALL 150 +INST_YIELD, +INST_COROUTINE_NAME, +INST_TAILCALL, /* For compilation of basic information operations */ -#define INST_NS_CURRENT 151 -#define INST_INFO_LEVEL_NUM 152 -#define INST_INFO_LEVEL_ARGS 153 -#define INST_RESOLVE_COMMAND 154 +INST_NS_CURRENT, +INST_INFO_LEVEL_NUM, +INST_INFO_LEVEL_ARGS, +INST_RESOLVE_COMMAND, /* For compilation relating to TclOO */ -#define INST_TCLOO_SELF 155 -#define INST_TCLOO_CLASS 156 -#define INST_TCLOO_NS 157 -#define INST_TCLOO_IS_OBJECT 158 +INST_TCLOO_SELF, +INST_TCLOO_CLASS, +INST_TCLOO_NS, +INST_TCLOO_IS_OBJECT, /* For compilation of [array] subcommands */ -#define INST_ARRAY_EXISTS_STK 159 -#define INST_ARRAY_EXISTS_IMM 160 -#define INST_ARRAY_MAKE_STK 161 -#define INST_ARRAY_MAKE_IMM 162 +INST_ARRAY_EXISTS_STK, +INST_ARRAY_EXISTS_IMM, +INST_ARRAY_MAKE_STK, +INST_ARRAY_MAKE_IMM, -#define INST_INVOKE_REPLACE 163 +INST_INVOKE_REPLACE, -#define INST_LIST_CONCAT 164 +INST_LIST_CONCAT, -#define INST_EXPAND_DROP 165 +INST_EXPAND_DROP, /* New foreach implementation */ -#define INST_FOREACH_START 166 -#define INST_FOREACH_STEP 167 -#define INST_FOREACH_END 168 -#define INST_LMAP_COLLECT 169 +INST_FOREACH_START, +INST_FOREACH_STEP, +INST_FOREACH_END, +INST_LMAP_COLLECT, /* For compilation of [string trim] and related */ -#define INST_STR_TRIM 170 -#define INST_STR_TRIM_LEFT 171 -#define INST_STR_TRIM_RIGHT 172 +INST_STR_TRIM, +INST_STR_TRIM_LEFT, +INST_STR_TRIM_RIGHT, -#define INST_CONCAT_STK 173 +INST_CONCAT_STK, -#define INST_STR_UPPER 174 -#define INST_STR_LOWER 175 -#define INST_STR_TITLE 176 -#define INST_STR_REPLACE 177 +INST_STR_UPPER, +INST_STR_LOWER, +INST_STR_TITLE, +INST_STR_REPLACE, -#define INST_ORIGIN_COMMAND 178 +INST_ORIGIN_COMMAND, -#define INST_TCLOO_NEXT 179 -#define INST_TCLOO_NEXT_CLASS 180 +INST_TCLOO_NEXT, +INST_TCLOO_NEXT_CLASS, -#define INST_YIELD_TO_INVOKE 181 +INST_YIELD_TO_INVOKE, -#define INST_NUM_TYPE 182 -#define INST_TRY_CVT_TO_BOOLEAN 183 -#define INST_STR_CLASS 184 +INST_NUM_TYPE, +INST_TRY_CVT_TO_BOOLEAN, +INST_STR_CLASS, -#define INST_LAPPEND_LIST 185 -#define INST_LAPPEND_LIST_ARRAY 186 -#define INST_LAPPEND_LIST_ARRAY_STK 187 -#define INST_LAPPEND_LIST_STK 188 +INST_LAPPEND_LIST, +INST_LAPPEND_LIST_ARRAY, +INST_LAPPEND_LIST_ARRAY_STK, +INST_LAPPEND_LIST_STK, -#define INST_CLOCK_READ 189 +INST_CLOCK_READ, + +/* The last opcode */ +LAST_INST_OPCODE +}; #else @@ -1117,10 +1099,10 @@ INST_TRY_CVT_TO_NUMERIC=64 #define INST_CLOCK_READ 189 -#endif - /* The last opcode */ #define LAST_INST_OPCODE 189 +#endif + /* * Table describing the Tcl bytecode instructions: their name (for displaying diff --git a/generic/tclDisassemble.c b/generic/tclDisassemble.c index 874d0d7..77b18df 100644 --- a/generic/tclDisassemble.c +++ b/generic/tclDisassemble.c @@ -820,7 +820,7 @@ UpdateStringOfInstName( size_t len, inst = (size_t)objPtr->internalRep.wideValue; char *s, buf[TCL_INTEGER_SPACE + 5]; - if (inst > LAST_INST_OPCODE) { + if (inst >= LAST_INST_OPCODE) { sprintf(buf, "inst_%" TCL_Z_MODIFIER "d", inst); s = buf; } else { diff --git a/generic/tclExecute.c b/generic/tclExecute.c index 40ee298..56045dd 100644 --- a/generic/tclExecute.c +++ b/generic/tclExecute.c @@ -8824,7 +8824,7 @@ ValidatePcAndStackTop( pc); Tcl_Panic("TclNRExecuteByteCode execution failure: bad pc"); } - if ((unsigned) opCode > LAST_INST_OPCODE) { + if ((unsigned) opCode >= LAST_INST_OPCODE) { fprintf(stderr, "\nBad opcode %d at pc %u in TclNRExecuteByteCode\n", (unsigned) opCode, relativePc); Tcl_Panic("TclNRExecuteByteCode execution failure: bad opcode"); @@ -9714,7 +9714,7 @@ EvalStatsCmd( */ Tcl_AppendPrintfToObj(objPtr, "\nInstruction counts:\n"); - for (i = 0; i <= LAST_INST_OPCODE; i++) { + for (i = 0; i < LAST_INST_OPCODE; i++) { Tcl_AppendPrintfToObj(objPtr, "%20s %8ld ", tclInstructionTable[i].name, statsPtr->instructionCount[i]); if (statsPtr->instructionCount[i]) { -- cgit v0.12 From 057d325d3567e7aa27628c6fb0fff8d1013ec8ce Mon Sep 17 00:00:00 2001 From: dgp Date: Tue, 6 Mar 2018 12:02:11 +0000 Subject: Remove disabled code and reformat. --- generic/tclCompile.c | 18 -- generic/tclCompile.h | 856 +++++++++++++++++---------------------------------- 2 files changed, 279 insertions(+), 595 deletions(-) diff --git a/generic/tclCompile.c b/generic/tclCompile.c index cc65d12..c29e41a 100644 --- a/generic/tclCompile.c +++ b/generic/tclCompile.c @@ -129,10 +129,6 @@ InstructionDesc const tclInstructionTable[] = { {"jumpFalse4", 5, -1, 1, {OPERAND_OFFSET4}}, /* Jump relative to (pc + op4) if stktop expr object is false */ -// {"lor", 1, -1, 0, {OPERAND_NONE}}, - /* Logical or: push (stknext || stktop) */ -// {"land", 1, -1, 0, {OPERAND_NONE}}, - /* Logical and: push (stknext && stktop) */ {"bitor", 1, -1, 0, {OPERAND_NONE}}, /* Bitwise or: push (stknext | stktop) */ {"bitxor", 1, -1, 0, {OPERAND_NONE}}, @@ -173,10 +169,6 @@ InstructionDesc const tclInstructionTable[] = { /* Bitwise not: push ~stktop */ {"not", 1, 0, 0, {OPERAND_NONE}}, /* Logical not: push !stktop */ -// {"callBuiltinFunc1", 2, 1, 1, {OPERAND_UINT1}}, - /* Call builtin math function with index op1; any args are on stk */ -// {"callFunc1", 2, INT_MIN, 1, {OPERAND_UINT1}}, - /* Call non-builtin func objv[0]; = */ {"tryCvtToNumeric", 1, 0, 0, {OPERAND_NONE}}, /* Try converting stktop to first int then double if possible. */ @@ -186,13 +178,6 @@ InstructionDesc const tclInstructionTable[] = { /* Skip to next iteration of closest enclosing loop; if none, return * TCL_CONTINUE code. */ -// {"foreach_start4", 5, 0, 1, {OPERAND_AUX4}}, - /* Initialize execution of a foreach loop. Operand is aux data index - * of the ForeachInfo structure for the foreach command. */ -// {"foreach_step4", 5, +1, 1, {OPERAND_AUX4}}, - /* "Step" or begin next iteration of foreach loop. Push 0 if to - * terminate loop, else push 1. */ - {"beginCatch4", 5, 0, 1, {OPERAND_UINT4}}, /* Record start of catch with the operand's exception index. Push the * current stack depth onto a special catch stack. */ @@ -340,9 +325,6 @@ InstructionDesc const tclInstructionTable[] = { {"dictNext", 5, +3, 1, {OPERAND_LVT4}}, /* Get the next iteration from the iterator in op4's local scalar. * Stack: ... => ... value key doneBool */ -// {"dictDone", 5, 0, 1, {OPERAND_LVT4}}, - /* Terminate the iterator in op4's local scalar. Use unsetScalar - * instead (with 0 for flags). */ {"dictUpdateStart", 9, 0, 2, {OPERAND_LVT4, OPERAND_AUX4}}, /* Create the variables (described in the aux data referred to by the * second immediate argument) to mirror the state of the dictionary in diff --git a/generic/tclCompile.h b/generic/tclCompile.h index b84cd48..93d11ff 100644 --- a/generic/tclCompile.h +++ b/generic/tclCompile.h @@ -519,590 +519,292 @@ typedef struct ByteCode { * Opcodes for the Tcl bytecode instructions. These must correspond to the * entries in the table of instruction descriptions, tclInstructionTable, in * tclCompile.c. Also, the order and number of the expression opcodes (e.g., - * INST_LOR) must match the entries in the array operatorStrings in + * INST_BITOR) must match the entries in the array operatorStrings in * tclExecute.c. */ -#if 1 enum TclInstruction { -/* Opcodes 0 to 9 */ -INST_DONE = 0, -INST_PUSH1, -INST_PUSH4, -INST_POP, -INST_DUP, -INST_STR_CONCAT1, -INST_INVOKE_STK1, -INST_INVOKE_STK4, -INST_EVAL_STK, -INST_EXPR_STK, - -/* Opcodes 10 to 23 */ -INST_LOAD_SCALAR1, -INST_LOAD_SCALAR4, -INST_LOAD_SCALAR_STK, -INST_LOAD_ARRAY1, -INST_LOAD_ARRAY4, -INST_LOAD_ARRAY_STK, -INST_LOAD_STK, -INST_STORE_SCALAR1, -INST_STORE_SCALAR4, -INST_STORE_SCALAR_STK, -INST_STORE_ARRAY1, -INST_STORE_ARRAY4, -INST_STORE_ARRAY_STK, -INST_STORE_STK, - -/* Opcodes 24 to 33 */ -INST_INCR_SCALAR1, -INST_INCR_SCALAR_STK, -INST_INCR_ARRAY1, -INST_INCR_ARRAY_STK, -INST_INCR_STK, -INST_INCR_SCALAR1_IMM, -INST_INCR_SCALAR_STK_IMM, -INST_INCR_ARRAY1_IMM, -INST_INCR_ARRAY_STK_IMM, -INST_INCR_STK_IMM, - -/* Opcodes 34 to 39 */ -INST_JUMP1, -INST_JUMP4, -INST_JUMP_TRUE1, -INST_JUMP_TRUE4, -INST_JUMP_FALSE1, -INST_JUMP_FALSE4, - -/* Opcodes 42 to 64 */ -INST_BITOR, -INST_BITXOR, -INST_BITAND, -INST_EQ, -INST_NEQ, -INST_LT, -INST_GT, -INST_LE, -INST_GE, -INST_LSHIFT, -INST_RSHIFT, -INST_ADD, -INST_SUB, -INST_MULT, -INST_DIV, -INST_MOD, -INST_UPLUS, -INST_UMINUS, -INST_BITNOT, -INST_LNOT, -INST_TRY_CVT_TO_NUMERIC, - -/* Opcodes 65 to 66 */ -INST_BREAK, -INST_CONTINUE, - -/* Opcodes 69 to 72 */ -INST_BEGIN_CATCH4, -INST_END_CATCH, -INST_PUSH_RESULT, -INST_PUSH_RETURN_CODE, - -/* Opcodes 73 to 78 */ -INST_STR_EQ, -INST_STR_NEQ, -INST_STR_CMP, -INST_STR_LEN, -INST_STR_INDEX, -INST_STR_MATCH, - -/* Opcodes 79 to 81 */ -INST_LIST, -INST_LIST_INDEX, -INST_LIST_LENGTH, - -/* Opcodes 82 to 87 */ -INST_APPEND_SCALAR1, -INST_APPEND_SCALAR4, -INST_APPEND_ARRAY1, -INST_APPEND_ARRAY4, -INST_APPEND_ARRAY_STK, -INST_APPEND_STK, - -/* Opcodes 88 to 93 */ -INST_LAPPEND_SCALAR1, -INST_LAPPEND_SCALAR4, -INST_LAPPEND_ARRAY1, -INST_LAPPEND_ARRAY4, -INST_LAPPEND_ARRAY_STK, -INST_LAPPEND_STK, - -/* TIP #22 - LINDEX operator with flat arg list */ -INST_LIST_INDEX_MULTI, - -/* - * TIP #33 - 'lset' command. Code gen also required a Forth-like - * OVER operation. - */ -INST_OVER, -INST_LSET_LIST, -INST_LSET_FLAT, - -/* TIP#90 - 'return' command. */ -INST_RETURN_IMM, - -/* TIP#123 - exponentiation operator. */ -INST_EXPON, - -/* TIP #157 - {*}... (word expansion) language syntax support. */ -INST_EXPAND_START, -INST_EXPAND_STKTOP, -INST_INVOKE_EXPANDED, - -/* - * TIP #57 - 'lassign' command. Code generation requires immediate - * LINDEX and LRANGE operators. - */ -INST_LIST_INDEX_IMM, -INST_LIST_RANGE_IMM, -INST_START_CMD, -INST_LIST_IN, -INST_LIST_NOT_IN, -INST_PUSH_RETURN_OPTIONS, -INST_RETURN_STK, - -/* - * Dictionary (TIP#111) related commands. - */ -INST_DICT_GET, -INST_DICT_SET, -INST_DICT_UNSET, -INST_DICT_INCR_IMM, -INST_DICT_APPEND, -INST_DICT_LAPPEND, -INST_DICT_FIRST, -INST_DICT_NEXT, -INST_DICT_UPDATE_START, -INST_DICT_UPDATE_END, - -/* - * Instruction to support jumps defined by tables (instead of the classic - * [switch] technique of chained comparisons). - */ -INST_JUMP_TABLE, - -/* - * Instructions to support compilation of global, variable, upvar and - * [namespace upvar]. - */ -INST_UPVAR, -INST_NSUPVAR, -INST_VARIABLE, - -/* Instruction to support compiling syntax error to bytecode */ -INST_SYNTAX, - -/* Instruction to reverse N items on top of stack */ -INST_REVERSE, - -/* regexp instruction */ -INST_REGEXP, - -/* For [info exists] compilation */ -INST_EXIST_SCALAR, -INST_EXIST_ARRAY, -INST_EXIST_ARRAY_STK, -INST_EXIST_STK, - -/* For [subst] compilation */ -INST_NOP, -INST_RETURN_CODE_BRANCH, - -/* For [unset] compilation */ -INST_UNSET_SCALAR, -INST_UNSET_ARRAY, -INST_UNSET_ARRAY_STK, -INST_UNSET_STK, - -/* For [dict with], [dict exists], [dict create] and [dict merge] */ -INST_DICT_EXPAND, -INST_DICT_RECOMBINE_STK, -INST_DICT_RECOMBINE_IMM, -INST_DICT_EXISTS, -INST_DICT_VERIFY, - -/* For [string map] and [regsub] compilation */ -INST_STR_MAP, -INST_STR_FIND, -INST_STR_FIND_LAST, -INST_STR_RANGE_IMM, -INST_STR_RANGE, - -/* For operations to do with coroutines and other NRE-manipulators */ -INST_YIELD, -INST_COROUTINE_NAME, -INST_TAILCALL, - -/* For compilation of basic information operations */ -INST_NS_CURRENT, -INST_INFO_LEVEL_NUM, -INST_INFO_LEVEL_ARGS, -INST_RESOLVE_COMMAND, - -/* For compilation relating to TclOO */ -INST_TCLOO_SELF, -INST_TCLOO_CLASS, -INST_TCLOO_NS, -INST_TCLOO_IS_OBJECT, - -/* For compilation of [array] subcommands */ -INST_ARRAY_EXISTS_STK, -INST_ARRAY_EXISTS_IMM, -INST_ARRAY_MAKE_STK, -INST_ARRAY_MAKE_IMM, - -INST_INVOKE_REPLACE, - -INST_LIST_CONCAT, - -INST_EXPAND_DROP, - -/* New foreach implementation */ -INST_FOREACH_START, -INST_FOREACH_STEP, -INST_FOREACH_END, -INST_LMAP_COLLECT, - -/* For compilation of [string trim] and related */ -INST_STR_TRIM, -INST_STR_TRIM_LEFT, -INST_STR_TRIM_RIGHT, - -INST_CONCAT_STK, - -INST_STR_UPPER, -INST_STR_LOWER, -INST_STR_TITLE, -INST_STR_REPLACE, - -INST_ORIGIN_COMMAND, - -INST_TCLOO_NEXT, -INST_TCLOO_NEXT_CLASS, - -INST_YIELD_TO_INVOKE, - -INST_NUM_TYPE, -INST_TRY_CVT_TO_BOOLEAN, -INST_STR_CLASS, - -INST_LAPPEND_LIST, -INST_LAPPEND_LIST_ARRAY, -INST_LAPPEND_LIST_ARRAY_STK, -INST_LAPPEND_LIST_STK, - -INST_CLOCK_READ, - -/* The last opcode */ -LAST_INST_OPCODE + /* Opcodes 0 to 9 */ + INST_DONE = 0, + INST_PUSH1, + INST_PUSH4, + INST_POP, + INST_DUP, + INST_STR_CONCAT1, + INST_INVOKE_STK1, + INST_INVOKE_STK4, + INST_EVAL_STK, + INST_EXPR_STK, + + /* Opcodes 10 to 23 */ + INST_LOAD_SCALAR1, + INST_LOAD_SCALAR4, + INST_LOAD_SCALAR_STK, + INST_LOAD_ARRAY1, + INST_LOAD_ARRAY4, + INST_LOAD_ARRAY_STK, + INST_LOAD_STK, + INST_STORE_SCALAR1, + INST_STORE_SCALAR4, + INST_STORE_SCALAR_STK, + INST_STORE_ARRAY1, + INST_STORE_ARRAY4, + INST_STORE_ARRAY_STK, + INST_STORE_STK, + + /* Opcodes 24 to 33 */ + INST_INCR_SCALAR1, + INST_INCR_SCALAR_STK, + INST_INCR_ARRAY1, + INST_INCR_ARRAY_STK, + INST_INCR_STK, + INST_INCR_SCALAR1_IMM, + INST_INCR_SCALAR_STK_IMM, + INST_INCR_ARRAY1_IMM, + INST_INCR_ARRAY_STK_IMM, + INST_INCR_STK_IMM, + + /* Opcodes 34 to 39 */ + INST_JUMP1, + INST_JUMP4, + INST_JUMP_TRUE1, + INST_JUMP_TRUE4, + INST_JUMP_FALSE1, + INST_JUMP_FALSE4, + + /* Opcodes 42 to 64 */ + INST_BITOR, + INST_BITXOR, + INST_BITAND, + INST_EQ, + INST_NEQ, + INST_LT, + INST_GT, + INST_LE, + INST_GE, + INST_LSHIFT, + INST_RSHIFT, + INST_ADD, + INST_SUB, + INST_MULT, + INST_DIV, + INST_MOD, + INST_UPLUS, + INST_UMINUS, + INST_BITNOT, + INST_LNOT, + INST_TRY_CVT_TO_NUMERIC, + + /* Opcodes 65 to 66 */ + INST_BREAK, + INST_CONTINUE, + + /* Opcodes 69 to 72 */ + INST_BEGIN_CATCH4, + INST_END_CATCH, + INST_PUSH_RESULT, + INST_PUSH_RETURN_CODE, + + /* Opcodes 73 to 78 */ + INST_STR_EQ, + INST_STR_NEQ, + INST_STR_CMP, + INST_STR_LEN, + INST_STR_INDEX, + INST_STR_MATCH, + + /* Opcodes 79 to 81 */ + INST_LIST, + INST_LIST_INDEX, + INST_LIST_LENGTH, + + /* Opcodes 82 to 87 */ + INST_APPEND_SCALAR1, + INST_APPEND_SCALAR4, + INST_APPEND_ARRAY1, + INST_APPEND_ARRAY4, + INST_APPEND_ARRAY_STK, + INST_APPEND_STK, + + /* Opcodes 88 to 93 */ + INST_LAPPEND_SCALAR1, + INST_LAPPEND_SCALAR4, + INST_LAPPEND_ARRAY1, + INST_LAPPEND_ARRAY4, + INST_LAPPEND_ARRAY_STK, + INST_LAPPEND_STK, + + /* TIP #22 - LINDEX operator with flat arg list */ + INST_LIST_INDEX_MULTI, + + /* + * TIP #33 - 'lset' command. Code gen also required a Forth-like + * OVER operation. + */ + INST_OVER, + INST_LSET_LIST, + INST_LSET_FLAT, + + /* TIP#90 - 'return' command. */ + INST_RETURN_IMM, + + /* TIP#123 - exponentiation operator. */ + INST_EXPON, + + /* TIP #157 - {*}... (word expansion) language syntax support. */ + INST_EXPAND_START, + INST_EXPAND_STKTOP, + INST_INVOKE_EXPANDED, + + /* + * TIP #57 - 'lassign' command. Code generation requires immediate + * LINDEX and LRANGE operators. + */ + INST_LIST_INDEX_IMM, + INST_LIST_RANGE_IMM, + INST_START_CMD, + INST_LIST_IN, + INST_LIST_NOT_IN, + INST_PUSH_RETURN_OPTIONS, + INST_RETURN_STK, + + /* + * Dictionary (TIP#111) related commands. + */ + INST_DICT_GET, + INST_DICT_SET, + INST_DICT_UNSET, + INST_DICT_INCR_IMM, + INST_DICT_APPEND, + INST_DICT_LAPPEND, + INST_DICT_FIRST, + INST_DICT_NEXT, + INST_DICT_UPDATE_START, + INST_DICT_UPDATE_END, + + /* + * Instruction to support jumps defined by tables (instead of the classic + * [switch] technique of chained comparisons). + */ + INST_JUMP_TABLE, + + /* + * Instructions to support compilation of global, variable, upvar and + * [namespace upvar]. + */ + INST_UPVAR, + INST_NSUPVAR, + INST_VARIABLE, + + /* Instruction to support compiling syntax error to bytecode */ + INST_SYNTAX, + + /* Instruction to reverse N items on top of stack */ + INST_REVERSE, + + /* regexp instruction */ + INST_REGEXP, + + /* For [info exists] compilation */ + INST_EXIST_SCALAR, + INST_EXIST_ARRAY, + INST_EXIST_ARRAY_STK, + INST_EXIST_STK, + + /* For [subst] compilation */ + INST_NOP, + INST_RETURN_CODE_BRANCH, + + /* For [unset] compilation */ + INST_UNSET_SCALAR, + INST_UNSET_ARRAY, + INST_UNSET_ARRAY_STK, + INST_UNSET_STK, + + /* For [dict with], [dict exists], [dict create] and [dict merge] */ + INST_DICT_EXPAND, + INST_DICT_RECOMBINE_STK, + INST_DICT_RECOMBINE_IMM, + INST_DICT_EXISTS, + INST_DICT_VERIFY, + + /* For [string map] and [regsub] compilation */ + INST_STR_MAP, + INST_STR_FIND, + INST_STR_FIND_LAST, + INST_STR_RANGE_IMM, + INST_STR_RANGE, + + /* For operations to do with coroutines and other NRE-manipulators */ + INST_YIELD, + INST_COROUTINE_NAME, + INST_TAILCALL, + + /* For compilation of basic information operations */ + INST_NS_CURRENT, + INST_INFO_LEVEL_NUM, + INST_INFO_LEVEL_ARGS, + INST_RESOLVE_COMMAND, + + /* For compilation relating to TclOO */ + INST_TCLOO_SELF, + INST_TCLOO_CLASS, + INST_TCLOO_NS, + INST_TCLOO_IS_OBJECT, + + /* For compilation of [array] subcommands */ + INST_ARRAY_EXISTS_STK, + INST_ARRAY_EXISTS_IMM, + INST_ARRAY_MAKE_STK, + INST_ARRAY_MAKE_IMM, + + INST_INVOKE_REPLACE, + + INST_LIST_CONCAT, + + INST_EXPAND_DROP, + + /* New foreach implementation */ + INST_FOREACH_START, + INST_FOREACH_STEP, + INST_FOREACH_END, + INST_LMAP_COLLECT, + + /* For compilation of [string trim] and related */ + INST_STR_TRIM, + INST_STR_TRIM_LEFT, + INST_STR_TRIM_RIGHT, + + INST_CONCAT_STK, + + INST_STR_UPPER, + INST_STR_LOWER, + INST_STR_TITLE, + INST_STR_REPLACE, + + INST_ORIGIN_COMMAND, + + INST_TCLOO_NEXT, + INST_TCLOO_NEXT_CLASS, + + INST_YIELD_TO_INVOKE, + + INST_NUM_TYPE, + INST_TRY_CVT_TO_BOOLEAN, + INST_STR_CLASS, + + INST_LAPPEND_LIST, + INST_LAPPEND_LIST_ARRAY, + INST_LAPPEND_LIST_ARRAY_STK, + INST_LAPPEND_LIST_STK, + + INST_CLOCK_READ, + + /* The last opcode */ + LAST_INST_OPCODE }; -#else - -/* Opcodes 0 to 9 */ -#define INST_DONE 0 -#define INST_PUSH1 1 -#define INST_PUSH4 2 -#define INST_POP 3 -#define INST_DUP 4 -#define INST_STR_CONCAT1 5 -#define INST_INVOKE_STK1 6 -#define INST_INVOKE_STK4 7 -#define INST_EVAL_STK 8 -#define INST_EXPR_STK 9 - -/* Opcodes 10 to 23 */ -#define INST_LOAD_SCALAR1 10 -#define INST_LOAD_SCALAR4 11 -#define INST_LOAD_SCALAR_STK 12 -#define INST_LOAD_ARRAY1 13 -#define INST_LOAD_ARRAY4 14 -#define INST_LOAD_ARRAY_STK 15 -#define INST_LOAD_STK 16 -#define INST_STORE_SCALAR1 17 -#define INST_STORE_SCALAR4 18 -#define INST_STORE_SCALAR_STK 19 -#define INST_STORE_ARRAY1 20 -#define INST_STORE_ARRAY4 21 -#define INST_STORE_ARRAY_STK 22 -#define INST_STORE_STK 23 - -/* Opcodes 24 to 33 */ -#define INST_INCR_SCALAR1 24 -#define INST_INCR_SCALAR_STK 25 -#define INST_INCR_ARRAY1 26 -#define INST_INCR_ARRAY_STK 27 -#define INST_INCR_STK 28 -#define INST_INCR_SCALAR1_IMM 29 -#define INST_INCR_SCALAR_STK_IMM 30 -#define INST_INCR_ARRAY1_IMM 31 -#define INST_INCR_ARRAY_STK_IMM 32 -#define INST_INCR_STK_IMM 33 - -/* Opcodes 34 to 39 */ -#define INST_JUMP1 34 -#define INST_JUMP4 35 -#define INST_JUMP_TRUE1 36 -#define INST_JUMP_TRUE4 37 -#define INST_JUMP_FALSE1 38 -#define INST_JUMP_FALSE4 39 - -/* Opcodes 40 to 64 */ -#define INST_BITOR 42 -#define INST_BITXOR 43 -#define INST_BITAND 44 -#define INST_EQ 45 -#define INST_NEQ 46 -#define INST_LT 47 -#define INST_GT 48 -#define INST_LE 49 -#define INST_GE 50 -#define INST_LSHIFT 51 -#define INST_RSHIFT 52 -#define INST_ADD 53 -#define INST_SUB 54 -#define INST_MULT 55 -#define INST_DIV 56 -#define INST_MOD 57 -#define INST_UPLUS 58 -#define INST_UMINUS 59 -#define INST_BITNOT 60 -#define INST_LNOT 61 -#define INST_TRY_CVT_TO_NUMERIC 64 - -/* Opcodes 65 to 66 */ -#define INST_BREAK 65 -#define INST_CONTINUE 66 - -/* Opcodes 69 to 72 */ -#define INST_BEGIN_CATCH4 69 -#define INST_END_CATCH 70 -#define INST_PUSH_RESULT 71 -#define INST_PUSH_RETURN_CODE 72 - -/* Opcodes 73 to 78 */ -#define INST_STR_EQ 73 -#define INST_STR_NEQ 74 -#define INST_STR_CMP 75 -#define INST_STR_LEN 76 -#define INST_STR_INDEX 77 -#define INST_STR_MATCH 78 - -/* Opcodes 78 to 81 */ -#define INST_LIST 79 -#define INST_LIST_INDEX 80 -#define INST_LIST_LENGTH 81 - -/* Opcodes 82 to 87 */ -#define INST_APPEND_SCALAR1 82 -#define INST_APPEND_SCALAR4 83 -#define INST_APPEND_ARRAY1 84 -#define INST_APPEND_ARRAY4 85 -#define INST_APPEND_ARRAY_STK 86 -#define INST_APPEND_STK 87 - -/* Opcodes 88 to 93 */ -#define INST_LAPPEND_SCALAR1 88 -#define INST_LAPPEND_SCALAR4 89 -#define INST_LAPPEND_ARRAY1 90 -#define INST_LAPPEND_ARRAY4 91 -#define INST_LAPPEND_ARRAY_STK 92 -#define INST_LAPPEND_STK 93 - -/* TIP #22 - LINDEX operator with flat arg list */ - -#define INST_LIST_INDEX_MULTI 94 - -/* - * TIP #33 - 'lset' command. Code gen also required a Forth-like - * OVER operation. - */ - -#define INST_OVER 95 -#define INST_LSET_LIST 96 -#define INST_LSET_FLAT 97 - -/* TIP#90 - 'return' command. */ - -#define INST_RETURN_IMM 98 - -/* TIP#123 - exponentiation operator. */ - -#define INST_EXPON 99 - -/* TIP #157 - {*}... (word expansion) language syntax support. */ - -#define INST_EXPAND_START 100 -#define INST_EXPAND_STKTOP 101 -#define INST_INVOKE_EXPANDED 102 - -/* - * TIP #57 - 'lassign' command. Code generation requires immediate - * LINDEX and LRANGE operators. - */ - -#define INST_LIST_INDEX_IMM 103 -#define INST_LIST_RANGE_IMM 104 - -#define INST_START_CMD 105 - -#define INST_LIST_IN 106 -#define INST_LIST_NOT_IN 107 - -#define INST_PUSH_RETURN_OPTIONS 108 -#define INST_RETURN_STK 109 - -/* - * Dictionary (TIP#111) related commands. - */ - -#define INST_DICT_GET 110 -#define INST_DICT_SET 111 -#define INST_DICT_UNSET 112 -#define INST_DICT_INCR_IMM 113 -#define INST_DICT_APPEND 114 -#define INST_DICT_LAPPEND 115 -#define INST_DICT_FIRST 116 -#define INST_DICT_NEXT 117 -#define INST_DICT_UPDATE_START 119 -#define INST_DICT_UPDATE_END 120 - -/* - * Instruction to support jumps defined by tables (instead of the classic - * [switch] technique of chained comparisons). - */ - -#define INST_JUMP_TABLE 121 - -/* - * Instructions to support compilation of global, variable, upvar and - * [namespace upvar]. - */ - -#define INST_UPVAR 122 -#define INST_NSUPVAR 123 -#define INST_VARIABLE 124 - -/* Instruction to support compiling syntax error to bytecode */ - -#define INST_SYNTAX 125 - -/* Instruction to reverse N items on top of stack */ - -#define INST_REVERSE 126 - -/* regexp instruction */ - -#define INST_REGEXP 127 - -/* For [info exists] compilation */ -#define INST_EXIST_SCALAR 128 -#define INST_EXIST_ARRAY 129 -#define INST_EXIST_ARRAY_STK 130 -#define INST_EXIST_STK 131 - -/* For [subst] compilation */ -#define INST_NOP 132 -#define INST_RETURN_CODE_BRANCH 133 - -/* For [unset] compilation */ -#define INST_UNSET_SCALAR 134 -#define INST_UNSET_ARRAY 135 -#define INST_UNSET_ARRAY_STK 136 -#define INST_UNSET_STK 137 - -/* For [dict with], [dict exists], [dict create] and [dict merge] */ -#define INST_DICT_EXPAND 138 -#define INST_DICT_RECOMBINE_STK 139 -#define INST_DICT_RECOMBINE_IMM 140 -#define INST_DICT_EXISTS 141 -#define INST_DICT_VERIFY 142 - -/* For [string map] and [regsub] compilation */ -#define INST_STR_MAP 143 -#define INST_STR_FIND 144 -#define INST_STR_FIND_LAST 145 -#define INST_STR_RANGE_IMM 146 -#define INST_STR_RANGE 147 - -/* For operations to do with coroutines and other NRE-manipulators */ -#define INST_YIELD 148 -#define INST_COROUTINE_NAME 149 -#define INST_TAILCALL 150 - -/* For compilation of basic information operations */ -#define INST_NS_CURRENT 151 -#define INST_INFO_LEVEL_NUM 152 -#define INST_INFO_LEVEL_ARGS 153 -#define INST_RESOLVE_COMMAND 154 - -/* For compilation relating to TclOO */ -#define INST_TCLOO_SELF 155 -#define INST_TCLOO_CLASS 156 -#define INST_TCLOO_NS 157 -#define INST_TCLOO_IS_OBJECT 158 - -/* For compilation of [array] subcommands */ -#define INST_ARRAY_EXISTS_STK 159 -#define INST_ARRAY_EXISTS_IMM 160 -#define INST_ARRAY_MAKE_STK 161 -#define INST_ARRAY_MAKE_IMM 162 - -#define INST_INVOKE_REPLACE 163 - -#define INST_LIST_CONCAT 164 - -#define INST_EXPAND_DROP 165 - -/* New foreach implementation */ -#define INST_FOREACH_START 166 -#define INST_FOREACH_STEP 167 -#define INST_FOREACH_END 168 -#define INST_LMAP_COLLECT 169 - -/* For compilation of [string trim] and related */ -#define INST_STR_TRIM 170 -#define INST_STR_TRIM_LEFT 171 -#define INST_STR_TRIM_RIGHT 172 - -#define INST_CONCAT_STK 173 - -#define INST_STR_UPPER 174 -#define INST_STR_LOWER 175 -#define INST_STR_TITLE 176 -#define INST_STR_REPLACE 177 - -#define INST_ORIGIN_COMMAND 178 - -#define INST_TCLOO_NEXT 179 -#define INST_TCLOO_NEXT_CLASS 180 - -#define INST_YIELD_TO_INVOKE 181 - -#define INST_NUM_TYPE 182 -#define INST_TRY_CVT_TO_BOOLEAN 183 -#define INST_STR_CLASS 184 - -#define INST_LAPPEND_LIST 185 -#define INST_LAPPEND_LIST_ARRAY 186 -#define INST_LAPPEND_LIST_ARRAY_STK 187 -#define INST_LAPPEND_LIST_STK 188 - -#define INST_CLOCK_READ 189 - -/* The last opcode */ -#define LAST_INST_OPCODE 189 -#endif - /* * Table describing the Tcl bytecode instructions: their name (for displaying -- cgit v0.12 From e5f3c1495b8226eec318ab053c1e693eaf5f96af Mon Sep 17 00:00:00 2001 From: dgp Date: Tue, 6 Mar 2018 12:10:45 +0000 Subject: Compiler warning in a --enable-symbols=compile build --- generic/tclExecute.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/generic/tclExecute.c b/generic/tclExecute.c index 56045dd..c647cd7 100644 --- a/generic/tclExecute.c +++ b/generic/tclExecute.c @@ -8772,7 +8772,7 @@ PrintByteCodeInfo( #endif /* TCL_COMPILE_STATS */ if (procPtr != NULL) { fprintf(stdout, - " Proc 0x%p, refCt %d, args %d, compiled locals %d\n", + " Proc 0x%p, refCt %zd, args %d, compiled locals %d\n", procPtr, procPtr->refCount, procPtr->numArgs, procPtr->numCompiledLocals); } -- cgit v0.12 From da8fbb89c41229c79b8f373f955ce1fb59cb4233 Mon Sep 17 00:00:00 2001 From: dgp Date: Tue, 6 Mar 2018 17:38:44 +0000 Subject: various bits of ranting commentary --- generic/tclCompCmdsGR.c | 25 ++++++++++++++++++++++--- generic/tclCompCmdsSZ.c | 19 +++++++++++++++++++ 2 files changed, 41 insertions(+), 3 deletions(-) diff --git a/generic/tclCompCmdsGR.c b/generic/tclCompCmdsGR.c index 375653b..e46d524 100644 --- a/generic/tclCompCmdsGR.c +++ b/generic/tclCompCmdsGR.c @@ -1505,7 +1505,6 @@ TclCompileLreplaceCmd( * - integer: [0,len+1] * - end index: TCL_INDEX_END * - -ive offset: TCL_INDEX_END-[len-1,0] - * - +ive offset: TCL_INDEX_END+1 */ /* @@ -1515,6 +1514,11 @@ TclCompileLreplaceCmd( */ if ((idx1 <= TCL_INDEX_END) != (idx2 <= TCL_INDEX_END)) { + + /* + * NOTE: when idx1 == 0 and idx2 == TCL_INDEX_END, + * we bail out here! Yet, down below + */ return TCL_ERROR; } @@ -1531,9 +1535,11 @@ TclCompileLreplaceCmd( if (parsePtr->numWords == 4) { if (idx1 == 0) { if (idx2 == TCL_INDEX_END) { + + /* Here we are down below! Now look somewhere else! */ goto dropAll; } - idx1 = idx2 + 1; + idx1 = idx2 + 1; /* TODO: Overflow? */ idx2 = TCL_INDEX_END; goto dropEnd; } else if (idx2 == TCL_INDEX_END) { @@ -1561,9 +1567,10 @@ TclCompileLreplaceCmd( TclEmitInstInt4( INST_REVERSE, 2, envPtr); if (idx1 == 0) { if (idx2 == TCL_INDEX_END) { + /* Another Can't Happen. */ goto replaceAll; } - idx1 = idx2 + 1; + idx1 = idx2 + 1; /* TODO: Overflow? */ idx2 = TCL_INDEX_END; goto replaceHead; } else if (idx2 == TCL_INDEX_END) { @@ -1588,6 +1595,11 @@ TclCompileLreplaceCmd( */ dropAll: /* This just ensures the arg is a list. */ + /* + * And now we're here down below the down below where flow can never go. + * CONCLUSION: This code has no purpose. + */ +Tcl_Panic("Can not get here."); TclEmitOpcode( INST_LIST_LENGTH, envPtr); TclEmitOpcode( INST_POP, envPtr); PushStringLiteral(envPtr, ""); @@ -1615,6 +1627,9 @@ TclCompileLreplaceCmd( * Emit an error if we've been given an empty list. */ +/* If we're generating bytecode to report an error, we've gone wrong. + * Just fallback to direct invocation. + */ TclEmitOpcode( INST_DUP, envPtr); TclEmitOpcode( INST_LIST_LENGTH, envPtr); offset2 = CurrentOffset(envPtr); @@ -1646,6 +1661,7 @@ TclCompileLreplaceCmd( */ replaceAll: +Tcl_Panic("Can not get here."); TclEmitOpcode( INST_LIST_LENGTH, envPtr); TclEmitOpcode( INST_POP, envPtr); goto done; @@ -1685,6 +1701,9 @@ TclCompileLreplaceCmd( * Emit an error if we've been given an empty list. */ +/* If we're generating bytecode to report an error, we've gone wrong. + * Just fallback to direct invocation. + */ TclEmitOpcode( INST_DUP, envPtr); TclEmitOpcode( INST_LIST_LENGTH, envPtr); offset2 = CurrentOffset(envPtr); diff --git a/generic/tclCompCmdsSZ.c b/generic/tclCompCmdsSZ.c index fb0981d..6f0cc8f 100644 --- a/generic/tclCompCmdsSZ.c +++ b/generic/tclCompCmdsSZ.c @@ -1005,6 +1005,14 @@ TclCompileStringReplaceCmd( * We handle these replacements specially: first character (where * idx1=idx2=0) and last character (where idx1=idx2=TCL_INDEX_END). Anything * else and the semantics get rather screwy. + * + * TODO: These seem to be very narrow cases. They are not even + * covered by the test suite, and any programming that ends up + * here could have been coded by the programmer using [string range] + * and [string cat]. [*] Not clear at all to me that the bytecode + * generated here is worthwhile. + * + * [*] Except for the empty string exceptions. UGGGGHHHH. */ if (idx1 == 0 && idx2 == 0) { @@ -1022,6 +1030,14 @@ TclCompileStringReplaceCmd( } /* Replace first */ CompileWord(envPtr, replacementTokenPtr, interp, 4); + + /* + * NOTE: The following tower of bullshit is present because + * [string replace] was boneheadedly defined not to replace + * empty strings, so we actually have to detect the empty + * string case and treat it differently. + */ + OP4( OVER, 1); PUSH( ""); OP( STR_EQ); @@ -1051,6 +1067,9 @@ TclCompileStringReplaceCmd( } /* Replace last */ CompileWord(envPtr, replacementTokenPtr, interp, 4); + + /* More bullshit; see NOTE above. */ + OP4( OVER, 1); PUSH( ""); OP( STR_EQ); -- cgit v0.12 From 847a048c18e68af9dd1140e12e922544b4fb25c6 Mon Sep 17 00:00:00 2001 From: dgp Date: Tue, 6 Mar 2018 20:09:00 +0000 Subject: New internal routine TclGetEndOffsetFromObj. --- generic/tclInt.h | 2 ++ generic/tclUtil.c | 46 +++++++++++++++++++++++++++++++++++++++------- 2 files changed, 41 insertions(+), 7 deletions(-) diff --git a/generic/tclInt.h b/generic/tclInt.h index 567a28c..1b1b078 100644 --- a/generic/tclInt.h +++ b/generic/tclInt.h @@ -2978,6 +2978,8 @@ MODULE_SCOPE int TclGetChannelFromObj(Tcl_Interp *interp, MODULE_SCOPE CmdFrame * TclGetCmdFrameForProcedure(Proc *procPtr); MODULE_SCOPE int TclGetCompletionCodeFromObj(Tcl_Interp *interp, Tcl_Obj *value, int *code); +MODULE_SCOPE int TclGetEndOffsetFromObj(Tcl_Interp *interp, + Tcl_Obj *objPtr, int endValue, int *indexPtr); MODULE_SCOPE int TclGetNumberFromObj(Tcl_Interp *interp, Tcl_Obj *objPtr, ClientData *clientDataPtr, int *typePtr); diff --git a/generic/tclUtil.c b/generic/tclUtil.c index 3424295..beeaae1 100644 --- a/generic/tclUtil.c +++ b/generic/tclUtil.c @@ -3575,13 +3575,7 @@ TclGetIntForIndex( 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. - */ - - *indexPtr = endValue + objPtr->internalRep.longValue; + if (TclGetEndOffsetFromObj(NULL, objPtr, endValue, indexPtr) == TCL_OK) { return TCL_OK; } @@ -3684,6 +3678,42 @@ UpdateStringOfEndOffset( /* *---------------------------------------------------------------------- * + * TclGetEndOffsetFromObj -- + * + * Look for a string of the form "end[+-]offset" and convert it to an + * internal representation holding the offset. + * + * Results: + * Tcl return code. + * + * Side effects: + * May store a Tcl_ObjType. + * + *---------------------------------------------------------------------- + */ + +int +TclGetEndOffsetFromObj( + Tcl_Interp *interp, /* For error reporting, may be NULL. */ + Tcl_Obj *objPtr, /* Pointer to the object to parse */ + int endValue, /* The value to be stored at "indexPtr" if + * "objPtr" holds "end". */ + int *indexPtr) /* Location filled in with an integer + * representing an index. */ +{ + if (SetEndOffsetFromAny(interp, objPtr) != TCL_OK) { + return TCL_ERROR; + } + + /* TODO: Handle overflow cases sensibly */ + *indexPtr = endValue + (int)objPtr->internalRep.longValue; + return TCL_OK; +} + + +/* + *---------------------------------------------------------------------- + * * SetEndOffsetFromAny -- * * Look for a string of the form "end[+-]offset" and convert it to an @@ -3750,6 +3780,8 @@ SetEndOffsetFromAny( return TCL_ERROR; } if (bytes[3] == '-') { + + /* TODO: Review overflow concerns here! */ offset = -offset; } } else { -- cgit v0.12 From 596e89b17d16efdca4d428cf91667142cc1336f3 Mon Sep 17 00:00:00 2001 From: dgp Date: Tue, 6 Mar 2018 20:27:39 +0000 Subject: Have assembler use same index value parser as the bytecode compiler. --- generic/tclAssembly.c | 19 ++++++------------- 1 file changed, 6 insertions(+), 13 deletions(-) diff --git a/generic/tclAssembly.c b/generic/tclAssembly.c index 120fd9a..273a012 100644 --- a/generic/tclAssembly.c +++ b/generic/tclAssembly.c @@ -2248,24 +2248,17 @@ GetListIndexOperand( Tcl_Token* tokenPtr = *tokenPtrPtr; /* INOUT: Pointer to the next token in the * source code */ - Tcl_Obj* intObj; /* Integer from the source code */ - int status; /* Tcl status return */ - - /* - * Extract the next token as a string. - */ - - if (GetNextOperand(assemEnvPtr, tokenPtrPtr, &intObj) != TCL_OK) { - return TCL_ERROR; - } /* * Convert to an integer, advance to the next token and return. */ - - status = TclGetIntForIndex(interp, intObj, -2, result); - Tcl_DecrRefCount(intObj); + int status = TclGetIndexFromToken(tokenPtr, result); *tokenPtrPtr = TokenAfter(tokenPtr); + if (status == TCL_ERROR && interp) { + Tcl_SetObjResult(interp, Tcl_ObjPrintf( + "unsupported index value: \"%.*s\"", tokenPtr->size, + tokenPtr->start)); + } return status; } -- cgit v0.12 From 720c8de45208caf2ba463bac1ad09ea5766fd34c Mon Sep 17 00:00:00 2001 From: dgp Date: Tue, 6 Mar 2018 20:59:44 +0000 Subject: rework error handling to keep test suite happy. --- generic/tclAssembly.c | 20 +++++++++++++------- 1 file changed, 13 insertions(+), 7 deletions(-) diff --git a/generic/tclAssembly.c b/generic/tclAssembly.c index 273a012..f40d662 100644 --- a/generic/tclAssembly.c +++ b/generic/tclAssembly.c @@ -2248,16 +2248,22 @@ GetListIndexOperand( Tcl_Token* tokenPtr = *tokenPtrPtr; /* INOUT: Pointer to the next token in the * source code */ + Tcl_Obj *value; + int status; - /* - * Convert to an integer, advance to the next token and return. - */ - int status = TclGetIndexFromToken(tokenPtr, result); + /* General operand validity check */ + if (GetNextOperand(assemEnvPtr, tokenPtrPtr, &value) != TCL_OK) { + return TCL_ERROR; + } + Tcl_DecrRefCount(value); + + /* Convert to an integer, advance to the next token and return. */ + status = TclGetIndexFromToken(tokenPtr, result); *tokenPtrPtr = TokenAfter(tokenPtr); if (status == TCL_ERROR && interp) { - Tcl_SetObjResult(interp, Tcl_ObjPrintf( - "unsupported index value: \"%.*s\"", tokenPtr->size, - tokenPtr->start)); + Tcl_SetObjResult(interp, Tcl_ObjPrintf("bad index \"%.*s\"", + tokenPtr->size, tokenPtr->start)); + Tcl_SetErrorCode(interp, "TCL", "ASSEM", "BADINDEX", NULL); } return status; } -- cgit v0.12 From c68d043691c94408564f252d18ffce9db7afcdad Mon Sep 17 00:00:00 2001 From: sebres Date: Tue, 6 Mar 2018 21:59:53 +0000 Subject: try to fix [db36fa5122]: better compiled variants of several indices-related commands, test-cases extended --- generic/tclCompCmdsGR.c | 57 +++++++++++++++++++++++++++++++++++++++---------- generic/tclCompCmdsSZ.c | 15 +++++++++---- generic/tclCompile.h | 6 ++++-- generic/tclExecute.c | 6 ++++-- tests/lindex.test | 9 ++++++++ tests/lrange.test | 18 ++++++++++++++++ 6 files changed, 92 insertions(+), 19 deletions(-) diff --git a/generic/tclCompCmdsGR.c b/generic/tclCompCmdsGR.c index 375653b..a5f2ee4 100644 --- a/generic/tclCompCmdsGR.c +++ b/generic/tclCompCmdsGR.c @@ -40,6 +40,11 @@ static int IndexTailVarIfKnown(Tcl_Interp *interp, * * Returns: * TCL_OK if parsing succeeded, and TCL_ERROR if it failed. + * The return value of *index is: + * >= 0 -- constant index from start, + * == minBoundary -- (TCL_INDEX_OUT_OF_RANGE, 0) if out of range (before start) + * == maxBoundary -- (INT_MAX, TCL_INDEX_OUT_OF_RANGE) if out of range (after end) + * <= -2 -- (<= TCL_INDEX_END) negative index from end. * * Side effects: * Sets *index to the index value if successful. @@ -50,7 +55,9 @@ static int IndexTailVarIfKnown(Tcl_Interp *interp, int TclGetIndexFromToken( Tcl_Token *tokenPtr, - int *index) + int *index, + int minBoundary, + int maxBoundary) { Tcl_Obj *tmpObj = Tcl_NewObj(); int result, idx; @@ -62,13 +69,26 @@ TclGetIndexFromToken( result = TclGetIntFromObj(NULL, tmpObj, &idx); if (result == TCL_OK) { - if (idx < 0) { - result = TCL_ERROR; + /* out of range (..., -2] */ + if (idx <= TCL_INDEX_END) { + idx = minBoundary; + /* before start */ } } else { result = TclGetIntForIndexM(NULL, tmpObj, TCL_INDEX_END, &idx); - if (result == TCL_OK && idx > TCL_INDEX_END) { - result = TCL_ERROR; + if (result == TCL_OK) { + int endSyntax = (tmpObj->length >= 3 && *tmpObj->bytes == 'e'); + /* + * Check computed index results to out of range (after end or negative constant), + * set it to -1 in order to avoid ambiguity with "end[+-integer] syntax" + */ + if (idx > TCL_INDEX_END && endSyntax) { + /* after end [end+1, ...) */ + idx = maxBoundary; /* may be TCL_INDEX_OUT_OF_RANGE or INT_MAX */ + } else if (idx < 0 && !endSyntax) { + /* before start, negative constant (..., -1-1] */ + idx = minBoundary; + } } } Tcl_DecrRefCount(tmpObj); @@ -1103,7 +1123,8 @@ TclCompileLindexCmd( } idxTokenPtr = TokenAfter(valTokenPtr); - if (TclGetIndexFromToken(idxTokenPtr, &idx) == TCL_OK) { + if (TclGetIndexFromToken(idxTokenPtr, &idx, + TCL_INDEX_OUT_OF_RANGE, TCL_INDEX_OUT_OF_RANGE) == TCL_OK) { /* * All checks have been completed, and we have exactly one of these * constructs: @@ -1338,14 +1359,17 @@ TclCompileLrangeCmd( */ tokenPtr = TokenAfter(listTokenPtr); - if (TclGetIndexFromToken(tokenPtr, &idx1) != TCL_OK) { + if (TclGetIndexFromToken(tokenPtr, &idx1, -1, INT_MAX) != TCL_OK) { return TCL_ERROR; } tokenPtr = TokenAfter(tokenPtr); - if (TclGetIndexFromToken(tokenPtr, &idx2) != TCL_OK) { + if (TclGetIndexFromToken(tokenPtr, &idx2, -1, INT_MAX) != TCL_OK) { return TCL_ERROR; } + if (idx1 == INT_MAX && idx2 == INT_MAX) { + idx2 = TCL_INDEX_OUT_OF_RANGE; + } /* * Issue instructions. It's not safe to skip doing the LIST_RANGE, as @@ -1395,7 +1419,7 @@ TclCompileLinsertCmd( */ tokenPtr = TokenAfter(listTokenPtr); - if (TclGetIndexFromToken(tokenPtr, &idx) != TCL_OK) { + if (TclGetIndexFromToken(tokenPtr, &idx, 0, INT_MAX) != TCL_OK) { return TCL_ERROR; } @@ -1490,12 +1514,12 @@ TclCompileLreplaceCmd( */ tokenPtr = TokenAfter(listTokenPtr); - if (TclGetIndexFromToken(tokenPtr, &idx1) != TCL_OK) { + if (TclGetIndexFromToken(tokenPtr, &idx1, -1, INT_MAX) != TCL_OK) { return TCL_ERROR; } tokenPtr = TokenAfter(tokenPtr); - if (TclGetIndexFromToken(tokenPtr, &idx2) != TCL_OK) { + if (TclGetIndexFromToken(tokenPtr, &idx2, -1, TCL_INDEX_END) != TCL_OK) { return TCL_ERROR; } @@ -1514,10 +1538,21 @@ TclCompileLreplaceCmd( * now. [Bug 47ac84309b] */ + if (idx1 == INT_MAX) { + /* consider special handling for too large first index + * "list doesn't contain element ...", so still not compiled */ + return TCL_ERROR; + } + if ((idx1 <= TCL_INDEX_END) != (idx2 <= TCL_INDEX_END)) { return TCL_ERROR; } + if (idx1 == -1) { + /* linsert before start or replace from start */ + idx1 = 0; + } + if (idx2 != TCL_INDEX_END && idx2 >= 0 && idx2 < idx1) { idx2 = idx1 - 1; } diff --git a/generic/tclCompCmdsSZ.c b/generic/tclCompCmdsSZ.c index fb0981d..ef1a4b0 100644 --- a/generic/tclCompCmdsSZ.c +++ b/generic/tclCompCmdsSZ.c @@ -934,12 +934,15 @@ TclCompileStringRangeCmd( * Parse the two indices. */ - if (TclGetIndexFromToken(fromTokenPtr, &idx1) != TCL_OK) { + if (TclGetIndexFromToken(fromTokenPtr, &idx1, -1, INT_MAX) != TCL_OK) { goto nonConstantIndices; } - if (TclGetIndexFromToken(toTokenPtr, &idx2) != TCL_OK) { + if (TclGetIndexFromToken(toTokenPtr, &idx2, -1, INT_MAX) != TCL_OK) { goto nonConstantIndices; } + if (idx1 == INT_MAX && idx2 == INT_MAX) { + idx2 = TCL_INDEX_OUT_OF_RANGE; + } /* * Push the operand onto the stack and then the substring operation. @@ -992,12 +995,16 @@ TclCompileStringReplaceCmd( */ tokenPtr = TokenAfter(valueTokenPtr); - if (TclGetIndexFromToken(tokenPtr, &idx1) != TCL_OK) { + if (TclGetIndexFromToken(tokenPtr, &idx1, -1, INT_MAX) != TCL_OK) { goto genericReplace; } tokenPtr = TokenAfter(tokenPtr); - if (TclGetIndexFromToken(tokenPtr, &idx2) != TCL_OK) { + if (TclGetIndexFromToken(tokenPtr, &idx2, -1, INT_MAX) != TCL_OK) { + goto genericReplace; + } + if (idx1 == INT_MAX && idx2 == INT_MAX) { + /* avoid replacement of last char in large string (just don't compile). */ goto genericReplace; } diff --git a/generic/tclCompile.h b/generic/tclCompile.h index 1c64a21..2f23b90 100644 --- a/generic/tclCompile.h +++ b/generic/tclCompile.h @@ -1121,7 +1121,8 @@ MODULE_SCOPE int TclFixupForwardJump(CompileEnv *envPtr, int distThreshold); MODULE_SCOPE void TclFreeCompileEnv(CompileEnv *envPtr); MODULE_SCOPE void TclFreeJumpFixupArray(JumpFixupArray *fixupArrayPtr); -MODULE_SCOPE int TclGetIndexFromToken(Tcl_Token *tokenPtr, int *index); +MODULE_SCOPE int TclGetIndexFromToken(Tcl_Token *tokenPtr, int *index, + int minBoundary, int maxBoundary); MODULE_SCOPE void TclInitByteCodeObj(Tcl_Obj *objPtr, CompileEnv *envPtr); MODULE_SCOPE void TclInitCompileEnv(Tcl_Interp *interp, @@ -1688,7 +1689,8 @@ MODULE_SCOPE int TclPushProcCallFrame(ClientData clientData, * Special value used by TclGetIndexFromToken to encoding the "end" index. */ -#define TCL_INDEX_END (-2) +#define TCL_INDEX_END (-2) +#define TCL_INDEX_OUT_OF_RANGE (-1) /* * DTrace probe macros (NOPs if DTrace support is not enabled). diff --git a/generic/tclExecute.c b/generic/tclExecute.c index 93ed50b..d345899 100644 --- a/generic/tclExecute.c +++ b/generic/tclExecute.c @@ -5091,7 +5091,7 @@ TEBCresume( /* * Select the list item based on the index. Negative operand means - * end-based indexing. + * end-based indexing (-2, ...), and -1 means out of range. */ if (opnd < -1) { @@ -5649,7 +5649,9 @@ TEBCresume( * Adjust indices for end-based indexing. */ - if (fromIdx < -1) { + if (fromIdx == -1) { + fromIdx = 0; + } else if (fromIdx < -1) { fromIdx += 1 + length; if (fromIdx < 0) { fromIdx = 0; diff --git a/tests/lindex.test b/tests/lindex.test index b86e2e0..e513b62 100644 --- a/tests/lindex.test +++ b/tests/lindex.test @@ -79,6 +79,15 @@ test lindex-3.7 {indexes don't shimmer wide ints} { set x [expr {(wide(1)<<31) - 2}] list $x [lindex {1 2 3} $x] [incr x] [incr x] } {2147483646 {} 2147483647 2147483648} +test lindex-3.8 {compiled with static indices out of range, negative} { + list [lindex {a b c} -1] [lindex {a b c} -2] [lindex {a b c} -3] +} [lrepeat 3 {}] +test lindex-3.9 {compiled with calculated indices out of range, negative constant} { + list [lindex {a b c} -1-1] [lindex {a b c} -2+0] [lindex {a b c} -2+1] +} [lrepeat 3 {}] +test lindex-3.10 {compiled with calculated indices out of range, after end} { + list [lindex {a b c} end+1] [lindex {a b c} end+2] [lindex {a b c} end+3] +} [lrepeat 3 {}] # Indices relative to end diff --git a/tests/lrange.test b/tests/lrange.test index 17a757e..ba10354 100644 --- a/tests/lrange.test +++ b/tests/lrange.test @@ -90,6 +90,24 @@ test lrange-3.1 {Bug 3588366: end-offsets before start} { lrange $l 0 end-5 }} {1 2 3 4 5} } {} + +test lrange-3.2 {compiled with static indices out of range, negative} { + list [lrange {a b c} -1 -2] [lrange {a b c} -2 -1] [lrange {a b c} -3 -2] [lrange {a b c} -2 -3] +} [lrepeat 4 {}] +test lrange-3.3 {compiled with calculated indices out of range, negative constant} { + list [lrange {a b c} 0-1 -1-1] [lrange {a b c} -2+0 0-1] [lrange {a b c} -2-1 -2+1] [lrange {a b c} -2+1 -2-1] +} [lrepeat 4 {}] +test lrange-3.4 {compiled with calculated indices out of range, after end} { + list [lrange {a b c} end+1 end+2] [lrange {a b c} end+2 end+1] [lrange {a b c} end+2 end+3] [lrange {a b c} end+3 end+2] +} [lrepeat 4 {}] + +test lrange-3.5 {compiled with calculated indices, start out of range (negative)} { + list [lrange {a b c} -1 1] [lrange {a b c} -1+0 end-1] [lrange {a b c} -2 1] [lrange {a b c} -2+0 0+1] +} [lrepeat 4 {a b}] +test lrange-3.6 {compiled with calculated indices, end out of range (after end)} { + list [lrange {a b c} 1 end+1] [lrange {a b c} 1+0 2+1] [lrange {a b c} 1 end+1] [lrange {a b c} end-1 3+1] +} [lrepeat 4 {b c}] + # cleanup ::tcltest::cleanupTests -- cgit v0.12 From 8c2cbf32116e7f5f5952e0d063a90125fcd4147d Mon Sep 17 00:00:00 2001 From: sebres Date: Tue, 6 Mar 2018 22:27:47 +0000 Subject: test cases for "lsort": coverage for "missing from sublist" error case with negative index (-1-1, -2) --- tests/cmdIL.test | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/tests/cmdIL.test b/tests/cmdIL.test index 23a5f96..7636adc 100644 --- a/tests/cmdIL.test +++ b/tests/cmdIL.test @@ -203,6 +203,18 @@ test cmdIL-3.4.1 {SortCompare procedure, -index option} -body { test cmdIL-3.5 {SortCompare procedure, -index option} -body { lsort -integer -index 2 {{20 10 13} {15}} } -returnCodes error -result {element 2 missing from sublist "15"} +test cmdIL-3.5.1 {SortCompare procedure, -index option (out of range, calculated index)} -body { + lsort -index 1+3 {{1 . c} {2 . b} {3 . a}} +} -returnCodes error -result {element 4 missing from sublist "1 . c"} +test cmdIL-3.5.2 {SortCompare procedure, -index option (out of range, calculated index)} -body { + lsort -index -1-1 {{1 . c} {2 . b} {3 . a}} +} -returnCodes error -result {element -2 missing from sublist "1 . c"} +test cmdIL-3.5.3 {SortCompare procedure, -index option (out of range, calculated index)} -body { + lsort -index -2 {{1 . c} {2 . b} {3 . a}} +} -returnCodes error -result {element -2 missing from sublist "1 . c"} +test cmdIL-3.5.4 {SortCompare procedure, -index option (out of range, calculated index)} -body { + lsort -index end-4 {{1 . c} {2 . b} {3 . a}} +} -returnCodes error -result {element -2 missing from sublist "1 . c"} test cmdIL-3.6 {SortCompare procedure, -index option} { lsort -integer -index 2 {{1 15 30} {2 5 25} {3 25 20}} } {{3 25 20} {2 5 25} {1 15 30}} -- cgit v0.12 From 0254080ca07929caa2f2b25206928d5559048aff Mon Sep 17 00:00:00 2001 From: "jan.nijtmans" Date: Tue, 6 Mar 2018 22:53:00 +0000 Subject: Fix the "package files" command. Due to the NRE enabling of "package" it always started to return an empty list. --- generic/tclPkg.c | 25 +++++++++++++++---------- 1 file changed, 15 insertions(+), 10 deletions(-) diff --git a/generic/tclPkg.c b/generic/tclPkg.c index 6c5b827..e8c2801 100644 --- a/generic/tclPkg.c +++ b/generic/tclPkg.c @@ -728,12 +728,23 @@ SelectPackage(ClientData data[], Tcl_Interp *interp, int result) { */ char *versionToProvide = bestPtr->version; + PkgFiles *pkgFiles; + PkgName *pkgName; + Tcl_Preserve(versionToProvide); pkgPtr->clientData = versionToProvide; if (bestPtr->pkgIndex) { TclPkgFileSeen(interp, bestPtr->pkgIndex); } reqPtr->versionToProvide = versionToProvide; + + pkgFiles = TclInitPkgFiles(interp); + /* Push "ifneeded" package name in "tclPkgFiles" assocdata. */ + pkgName = ckalloc(sizeof(PkgName) + strlen(name)); + pkgName->nextPtr = pkgFiles->names; + strcpy(pkgName->name, name); + pkgFiles->names = pkgName; + Tcl_NRAddCallback(interp, SelectPackageFinal, reqPtr, INT2PTR(reqc), (void *)reqv, data[3]); Tcl_NREvalObj(interp, Tcl_NewStringObj(bestPtr->script, -1), TCL_EVAL_GLOBAL); } @@ -747,20 +758,14 @@ SelectPackageFinal(ClientData data[], Tcl_Interp *interp, int result) { Tcl_Obj **const reqv = data[2]; const char *name = reqPtr->name; char *versionToProvide = reqPtr->versionToProvide; - + void *toBeRemoved; PkgFiles *pkgFiles; - PkgName *pkgName; pkgFiles = TclInitPkgFiles(interp); - /* Push "ifneeded" package name in "tclPkgFiles" assocdata. */ - pkgName = ckalloc(sizeof(PkgName) + strlen(name)); - pkgName->nextPtr = pkgFiles->names; - strcpy(pkgName->name, name); - pkgFiles->names = pkgName; - /* Pop the "ifneeded" package name from "tclPkgFiles" assocdata*/ - pkgFiles->names = pkgName->nextPtr; - ckfree(pkgName); + toBeRemoved = pkgFiles->names; + pkgFiles->names = pkgFiles->names->nextPtr; + ckfree(toBeRemoved); reqPtr->pkgPtr = FindPackage(interp, name); if (result == TCL_OK) { -- cgit v0.12 From f003df5624ef84697f69a9b130bf014e90fb0d31 Mon Sep 17 00:00:00 2001 From: dgp Date: Wed, 7 Mar 2018 13:40:54 +0000 Subject: Tests of [assemble] use of compiled index values. --- tests/assemble.test | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/tests/assemble.test b/tests/assemble.test index 5231048..40c132d 100644 --- a/tests/assemble.test +++ b/tests/assemble.test @@ -1584,6 +1584,12 @@ test assemble-15.7 {listIndexImm} { } -result c } +test assemble-15.8 {listIndexImm} { + assemble {push {a b c}; listIndexImm end+2} +} {} +test assemble-15.9 {listIndexImm} { + assemble {push {a b c}; listIndexImm -1-1} +} {} # assemble-16 - invokeStk -- cgit v0.12 From 7fe003f8d24f263ca82d1ddf0a54f6ab16f01306 Mon Sep 17 00:00:00 2001 From: dgp Date: Wed, 7 Mar 2018 14:16:08 +0000 Subject: Remove pointless duplication. --- generic/tclListObj.c | 12 +++--------- 1 file changed, 3 insertions(+), 9 deletions(-) diff --git a/generic/tclListObj.c b/generic/tclListObj.c index 0d37821..13704b9 100644 --- a/generic/tclListObj.c +++ b/generic/tclListObj.c @@ -1145,15 +1145,9 @@ TclLindexList( return TclLindexFlat(interp, listPtr, 1, &argPtr); } - if (indexListCopy->typePtr == &tclListType) { - List *listRepPtr = ListRepPtr(indexListCopy); - - listPtr = TclLindexFlat(interp, listPtr, listRepPtr->elemCount, - &listRepPtr->elements); - } else { - int indexCount = -1; /* Size of the array of list indices. */ - Tcl_Obj **indices = NULL; - /* Array of list indices. */ + { + int indexCount = -1; /* Size of the array of list indices. */ + Tcl_Obj **indices = NULL; /* Array of list indices. */ Tcl_ListObjGetElements(NULL, indexListCopy, &indexCount, &indices); listPtr = TclLindexFlat(interp, listPtr, indexCount, indices); -- cgit v0.12 From f337281f750a928dcc07884286cc1f4cceeab809 Mon Sep 17 00:00:00 2001 From: sebres Date: Wed, 7 Mar 2018 15:10:44 +0000 Subject: amend to [58716e0e92]: now the duplication is really pointless, so eliminated --- generic/tclListObj.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/generic/tclListObj.c b/generic/tclListObj.c index 13704b9..786e1ce 100644 --- a/generic/tclListObj.c +++ b/generic/tclListObj.c @@ -1149,7 +1149,7 @@ TclLindexList( int indexCount = -1; /* Size of the array of list indices. */ Tcl_Obj **indices = NULL; /* Array of list indices. */ - Tcl_ListObjGetElements(NULL, indexListCopy, &indexCount, &indices); + TclListObjGetElements(NULL, indexListCopy, &indexCount, &indices); listPtr = TclLindexFlat(interp, listPtr, indexCount, indices); } Tcl_DecrRefCount(indexListCopy); -- cgit v0.12 From 612199cbe93e3fb4c39cd92afd245616115ad442 Mon Sep 17 00:00:00 2001 From: dgp Date: Wed, 7 Mar 2018 17:02:50 +0000 Subject: Rework TclGetIndexFromToken to make use of TclGetEndOffsetFromObj, and to lay out the index value encoding cases. --- generic/tclCompCmdsGR.c | 95 +++++++++++++++++++++++++++++++++++++------------ 1 file changed, 73 insertions(+), 22 deletions(-) diff --git a/generic/tclCompCmdsGR.c b/generic/tclCompCmdsGR.c index 2386b6d..8585bce 100644 --- a/generic/tclCompCmdsGR.c +++ b/generic/tclCompCmdsGR.c @@ -34,20 +34,50 @@ static int IndexTailVarIfKnown(Tcl_Interp *interp, * * TclGetIndexFromToken -- * - * Parse a token and get the encoded version of the index (as understood - * by TEBC), assuming it is at all knowable at compile time. Only handles - * indices that are integers or 'end' or 'end-integer'. + * Parse a token to determine if an index value is known at + * compile time. Two cases are possible. The compile time value + * of the token might be parsed as an absolute index value + * in the C signed int range. Note that this includes index + * values that are integers as presented as well as index + * arithmetic expressions that can be fully computed at compile + * time. The absolute index values that can be directly meaningful + * as an index into either a list or a string are those integer + * values >= 0 and < INT_MAX. The largest string supported in Tcl 8 + * has bytelength INT_MAX. This means the largest character supported + * length is also INT_MAX, and the index of the last character in a + * string of length INT_MAX is INT_MAX-1. + * + * Any absolute index value parsed outside that range is encoded + * using the minBoundary and maxBounday values passed in by the + * caller as the encoding to use for indices that are either + * less than or greater than the usable index range. INT_MAX + * is available as a good choice for most callers to use for + * maxBoundary. Likewise, the value -1 is good for most callers + * to use for minBoundary. + * + * A token can also be parsed as an end-relative index expression. + * All end-relative expressions that indicate an index larger + * than end (end+2, end--5) point beyond the end of the indexed + * collection, and can be encoded as maxBoundary. The end-relative + * expressions that indicate an index less than or equal to end + * are encoded relative to the value TCL_INDEX_END (-2). The + * index "end" is encoded as -2, down to the index "end-0x7ffffffe" + * which is encoded as INT_MIN. Since the largest index into a + * string possible in Tcl 8 is 0x7ffffffe, the interpretation of + * "end-0x7ffffffe" for that largest string would be 0. Thus, + * if the tokens "end-0x7fffffff" or "end+-0x80000000" are parsed, + * they can be encoded with the minBoundary value. + * + * These details will require re-examination whenever string and + * list length limits are increased, but that will likely also + * mean a revised routine capable of returning Tcl_WideInt values. * * Returns: * TCL_OK if parsing succeeded, and TCL_ERROR if it failed. - * The return value of *index is: - * >= 0 -- constant index from start, - * == minBoundary -- (TCL_INDEX_OUT_OF_RANGE, 0) if out of range (before start) - * == maxBoundary -- (INT_MAX, TCL_INDEX_OUT_OF_RANGE) if out of range (after end) - * <= -2 -- (<= TCL_INDEX_END) negative index from end. * * Side effects: - * Sets *index to the index value if successful. + * When TCL_OK is returned, the encoded index value is written + * to *index. * *---------------------------------------------------------------------- */ @@ -69,25 +99,46 @@ TclGetIndexFromToken( result = TclGetIntFromObj(NULL, tmpObj, &idx); if (result == TCL_OK) { - /* out of range (..., -2] */ - if (idx <= TCL_INDEX_END) { + /* We parsed a value in the range INT_MIN...INT_MAX */ + integerEncode: + if (idx < 0) { + /* All negative absolute indices are "before the beginning" */ idx = minBoundary; - /* before start */ + } else if (idx == INT_MAX) { + /* This index value is always "after the end" */ + idx = maxBoundary; } + /* usual case, the absolute index value encodes itself */ } else { - result = TclGetIntForIndexM(NULL, tmpObj, TCL_INDEX_END, &idx); + result = TclGetEndOffsetFromObj(NULL, tmpObj, 0, &idx); if (result == TCL_OK) { - int endSyntax = (tmpObj->length >= 3 && *tmpObj->bytes == 'e'); - /* - * Check computed index results to out of range (after end or negative constant), - * set it to -1 in order to avoid ambiguity with "end[+-integer] syntax" + /* + * We parsed an end+offset index value. + * idx holds the offset value in the range INT_MIN...INT_MAX. */ - if (idx > TCL_INDEX_END && endSyntax) { - /* after end [end+1, ...) */ - idx = maxBoundary; /* may be TCL_INDEX_OUT_OF_RANGE or INT_MAX */ - } else if (idx < 0 && !endSyntax) { - /* before start, negative constant (..., -1-1] */ + if (idx > 0) { + /* + * All end+postive or end-negative expressions + * always indicate "after the end". + */ + idx = maxBoundary; + } else if (idx < INT_MIN - TCL_INDEX_END) { + /* These indices alwasy indicate "before the beginning */ idx = minBoundary; + } else { + /* Encoded end-positive (or end+negative) are offset */ + idx += TCL_INDEX_END; + } + } else { + result = TclGetIntForIndexM(NULL, tmpObj, 0, &idx); + if (result == TCL_OK) { + /* + * Only reach this case when the index value is a + * constant index arithmetic expression, and idx + * holds the result. Treat it the same as if it were + * parsed as an absolute integer value. + */ + goto integerEncode; } } } -- cgit v0.12 From 2c44354d13f15b788a4213ab50441eed6ad54f75 Mon Sep 17 00:00:00 2001 From: dgp Date: Wed, 7 Mar 2018 18:39:44 +0000 Subject: Establish 4 symbols for categories of parsed index values: TCL_INDEX_START = 0 The start index. TCL_INDEX_END = -2 The "end" index. TCL_INDEX_BEFORE = -1 All indices less than start. TCL_INDEX_AFTER = INT_MAX All indices greater than "end". Then use these symbols among callers of TclGetIndexFromToken() so that index value parsing can directly implement the callers sense of when out of range indices ought to be treated the same as start or end positions. --- generic/tclAssembly.c | 9 +++- generic/tclCompCmdsGR.c | 116 ++++++++++++++++++++++++++---------------------- generic/tclCompCmdsSZ.c | 43 ++++++++++-------- generic/tclCompile.h | 4 +- 4 files changed, 99 insertions(+), 73 deletions(-) diff --git a/generic/tclAssembly.c b/generic/tclAssembly.c index 02c64bd..a3fac8f 100644 --- a/generic/tclAssembly.c +++ b/generic/tclAssembly.c @@ -2258,8 +2258,13 @@ GetListIndexOperand( Tcl_DecrRefCount(value); /* Convert to an integer, advance to the next token and return. */ - status = TclGetIndexFromToken(tokenPtr, result, TCL_INDEX_OUT_OF_RANGE, - TCL_INDEX_OUT_OF_RANGE); + /* + * NOTE: Indexing a list with an index before it yields the + * same result as indexing after it, and might be more easily portable + * when list size limits grow. + */ + status = TclGetIndexFromToken(tokenPtr, result, TCL_INDEX_BEFORE, + TCL_INDEX_BEFORE); *tokenPtrPtr = TokenAfter(tokenPtr); if (status == TCL_ERROR && interp) { Tcl_SetObjResult(interp, Tcl_ObjPrintf("bad index \"%.*s\"", diff --git a/generic/tclCompCmdsGR.c b/generic/tclCompCmdsGR.c index 8585bce..501c7a4 100644 --- a/generic/tclCompCmdsGR.c +++ b/generic/tclCompCmdsGR.c @@ -42,18 +42,21 @@ static int IndexTailVarIfKnown(Tcl_Interp *interp, * arithmetic expressions that can be fully computed at compile * time. The absolute index values that can be directly meaningful * as an index into either a list or a string are those integer - * values >= 0 and < INT_MAX. The largest string supported in Tcl 8 - * has bytelength INT_MAX. This means the largest character supported - * length is also INT_MAX, and the index of the last character in a - * string of length INT_MAX is INT_MAX-1. + * values >= TCL_INDEX_START (0) and < TCL_INDEX_AFTER (INT_MAX). + * The largest string supported in Tcl 8 has bytelength INT_MAX. + * This means the largest character supported length is also INT_MAX, + * and the index of the last character in a string of length INT_MAX + * is INT_MAX-1. * * Any absolute index value parsed outside that range is encoded * using the minBoundary and maxBounday values passed in by the * caller as the encoding to use for indices that are either - * less than or greater than the usable index range. INT_MAX + * less than or greater than the usable index range. TCL_INDEX_AFTER * is available as a good choice for most callers to use for - * maxBoundary. Likewise, the value -1 is good for most callers - * to use for minBoundary. + * maxBoundary. Likewise, the value TCL_INDEX_BEFORE is good for + * most callers to use for minBoundary. Other values are possible + * when the caller knows it is helpful in producing its own behavior + * for indices before and after the indexed item. * * A token can also be parsed as an end-relative index expression. * All end-relative expressions that indicate an index larger @@ -101,7 +104,7 @@ TclGetIndexFromToken( if (result == TCL_OK) { /* We parsed a value in the range INT_MIN...INT_MAX */ integerEncode: - if (idx < 0) { + if (idx < TCL_INDEX_START) { /* All negative absolute indices are "before the beginning" */ idx = minBoundary; } else if (idx == INT_MAX) { @@ -123,7 +126,7 @@ TclGetIndexFromToken( */ idx = maxBoundary; } else if (idx < INT_MIN - TCL_INDEX_END) { - /* These indices alwasy indicate "before the beginning */ + /* These indices always indicate "before the beginning */ idx = minBoundary; } else { /* Encoded end-positive (or end+negative) are offset */ @@ -214,7 +217,7 @@ TclCompileGlobalCmd( return TCL_ERROR; } - /* TODO: Consider what value can pass throug the + /* TODO: Consider what value can pass through the * IndexTailVarIfKnown() screen. Full CompileWord() * likely does not apply here. Push known value instead. */ CompileWord(envPtr, varTokenPtr, interp, i); @@ -1174,15 +1177,14 @@ TclCompileLindexCmd( } idxTokenPtr = TokenAfter(valTokenPtr); - if (TclGetIndexFromToken(idxTokenPtr, &idx, - TCL_INDEX_OUT_OF_RANGE, TCL_INDEX_OUT_OF_RANGE) == TCL_OK) { + if (TclGetIndexFromToken(idxTokenPtr, &idx, TCL_INDEX_BEFORE, + TCL_INDEX_BEFORE) == TCL_OK) { /* - * All checks have been completed, and we have exactly one of these - * constructs: - * lindex - * lindex end- - * This is best compiled as a push of the arbitrary value followed by - * an "immediate lindex" which is the most efficient variety. + * The idxTokenPtr parsed as a valid index value and was + * encoded as expected by INST_LIST_INDEX_IMM. + * + * NOTE: that we rely on indexing before a list producing the + * same result as indexing after a list. */ CompileWord(envPtr, valTokenPtr, interp, 1); @@ -1403,24 +1405,25 @@ TclCompileLrangeCmd( } listTokenPtr = TokenAfter(parsePtr->tokenPtr); - /* - * Parse the indices. Will only compile if both are constants and not an - * _integer_ less than zero (since we reserve negative indices here for - * end-relative indexing) or an end-based index greater than 'end' itself. - */ - tokenPtr = TokenAfter(listTokenPtr); - if (TclGetIndexFromToken(tokenPtr, &idx1, -1, INT_MAX) != TCL_OK) { + if (TclGetIndexFromToken(tokenPtr, &idx1, TCL_INDEX_START, + TCL_INDEX_AFTER) != TCL_OK) { return TCL_ERROR; } + /* + * Token was an index value, and we treat all "first" indices + * before the list same as the start of the list. + */ tokenPtr = TokenAfter(tokenPtr); - if (TclGetIndexFromToken(tokenPtr, &idx2, -1, INT_MAX) != TCL_OK) { + if (TclGetIndexFromToken(tokenPtr, &idx2, TCL_INDEX_BEFORE, + TCL_INDEX_END) != TCL_OK) { return TCL_ERROR; } - if (idx1 == INT_MAX && idx2 == INT_MAX) { - idx2 = TCL_INDEX_OUT_OF_RANGE; - } + /* + * Token was an index value, and we treat all "last" indices + * after the list same as the end of the list. + */ /* * Issue instructions. It's not safe to skip doing the LIST_RANGE, as @@ -1470,7 +1473,16 @@ TclCompileLinsertCmd( */ tokenPtr = TokenAfter(listTokenPtr); - if (TclGetIndexFromToken(tokenPtr, &idx, 0, INT_MAX) != TCL_OK) { + + /* + * NOTE: This command treats all inserts at indices before the list + * the same as inserts at the start of the list, and all inserts + * after the list the same as inserts at the end of the list. We + * make that transformation here so we can use the optimized bytecode + * as much as possible. + */ + if (TclGetIndexFromToken(tokenPtr, &idx, TCL_INDEX_START, + TCL_INDEX_END) != TCL_OK) { return TCL_ERROR; } @@ -1494,10 +1506,10 @@ TclCompileLinsertCmd( } TclEmitInstInt4( INST_LIST, i-3, envPtr); - if (idx == 0 /*start*/) { + if (idx == TCL_INDEX_START) { TclEmitInstInt4( INST_REVERSE, 2, envPtr); TclEmitOpcode( INST_LIST_CONCAT, envPtr); - } else if (idx == TCL_INDEX_END /*end*/) { + } else if (idx == TCL_INDEX_END) { TclEmitOpcode( INST_LIST_CONCAT, envPtr); } else { /* @@ -1558,42 +1570,42 @@ TclCompileLreplaceCmd( } listTokenPtr = TokenAfter(parsePtr->tokenPtr); - /* - * Parse the indices. Will only compile if both are constants and not an - * _integer_ less than zero (since we reserve negative indices here for - * end-relative indexing) or an end-based index greater than 'end' itself. - */ - tokenPtr = TokenAfter(listTokenPtr); - if (TclGetIndexFromToken(tokenPtr, &idx1, -1, INT_MAX) != TCL_OK) { + if (TclGetIndexFromToken(tokenPtr, &idx1, TCL_INDEX_START, + TCL_INDEX_AFTER) != TCL_OK) { return TCL_ERROR; } tokenPtr = TokenAfter(tokenPtr); - if (TclGetIndexFromToken(tokenPtr, &idx2, -1, TCL_INDEX_END) != TCL_OK) { + if (TclGetIndexFromToken(tokenPtr, &idx2, TCL_INDEX_BEFORE, + TCL_INDEX_END) != TCL_OK) { return TCL_ERROR; } /* - * idx1, idx2 are now in canonical form: - * - * - integer: [0,len+1] - * - end index: TCL_INDEX_END - * - -ive offset: TCL_INDEX_END-[len-1,0] + * idx1, idx2 are the conventional encoded forms of the tokens parsed + * as all forms of index values. Values of idx1 that come before the + * list are treated the same as if they were the start of the list. + * Values of idx2 that come after the list are treated the same as if + * they were the end of the list. */ + if (idx1 == TCL_INDEX_AFTER) { + /* + * [lreplace] treats idx1 value end+1 differently from end+2, etc. + * The operand encoding cannot distinguish them, so we must bail + * out to direct evaluation. + */ + return TCL_ERROR; + } + +/* TODO: ...... */ /* * Compilation fails when one index is end-based but the other isn't. * Fixing this will require more bytecodes, but this is a workaround for * now. [Bug 47ac84309b] */ - if (idx1 == INT_MAX) { - /* consider special handling for too large first index - * "list doesn't contain element ...", so still not compiled */ - return TCL_ERROR; - } - if ((idx1 <= TCL_INDEX_END) != (idx2 <= TCL_INDEX_END)) { /* @@ -3049,7 +3061,7 @@ TclCompileVariableCmd( return TCL_ERROR; } - /* TODO: Consider what value can pass throug the + /* TODO: Consider what value can pass through the * IndexTailVarIfKnown() screen. Full CompileWord() * likely does not apply here. Push known value instead. */ CompileWord(envPtr, varTokenPtr, interp, i); diff --git a/generic/tclCompCmdsSZ.c b/generic/tclCompCmdsSZ.c index bf8c482..d10d1c1 100644 --- a/generic/tclCompCmdsSZ.c +++ b/generic/tclCompCmdsSZ.c @@ -934,15 +934,22 @@ TclCompileStringRangeCmd( * Parse the two indices. */ - if (TclGetIndexFromToken(fromTokenPtr, &idx1, -1, INT_MAX) != TCL_OK) { + if (TclGetIndexFromToken(fromTokenPtr, &idx1, TCL_INDEX_START, + TCL_INDEX_AFTER) != TCL_OK) { goto nonConstantIndices; } - if (TclGetIndexFromToken(toTokenPtr, &idx2, -1, INT_MAX) != TCL_OK) { + /* + * Token parsed as an index expression. We treat all indices before + * the string the same as the start of the string. + */ + if (TclGetIndexFromToken(toTokenPtr, &idx2, TCL_INDEX_BEFORE, + TCL_INDEX_END) != TCL_OK) { goto nonConstantIndices; } - if (idx1 == INT_MAX && idx2 == INT_MAX) { - idx2 = TCL_INDEX_OUT_OF_RANGE; - } + /* + * Token parsed as an index expression. We treat all indices after + * the string the same as the end of the string. + */ /* * Push the operand onto the stack and then the substring operation. @@ -987,27 +994,27 @@ TclCompileStringReplaceCmd( replacementTokenPtr = TokenAfter(tokenPtr); } - /* - * Parse the indices. Will only compile special cases if both are - * constants and not an _integer_ less than zero (since we reserve - * negative indices here for end-relative indexing) or an end-based index - * greater than 'end' itself. - */ - tokenPtr = TokenAfter(valueTokenPtr); - if (TclGetIndexFromToken(tokenPtr, &idx1, -1, INT_MAX) != TCL_OK) { + if (TclGetIndexFromToken(tokenPtr, &idx1, TCL_INDEX_START, + TCL_INDEX_AFTER) != TCL_OK) { goto genericReplace; } + /* + * Token parsed as an index value. Indices before the string are + * treated as index of start of string. + */ tokenPtr = TokenAfter(tokenPtr); - if (TclGetIndexFromToken(tokenPtr, &idx2, -1, INT_MAX) != TCL_OK) { - goto genericReplace; - } - if (idx1 == INT_MAX && idx2 == INT_MAX) { - /* avoid replacement of last char in large string (just don't compile). */ + if (TclGetIndexFromToken(tokenPtr, &idx2, TCL_INDEX_BEFORE, + TCL_INDEX_END) != TCL_OK) { goto genericReplace; } + /* + * Token parsed as an index value. Indices after the string are + * treated as index of end of string. + */ +/* TODO...... */ /* * We handle these replacements specially: first character (where * idx1=idx2=0) and last character (where idx1=idx2=TCL_INDEX_END). Anything diff --git a/generic/tclCompile.h b/generic/tclCompile.h index 2f23b90..9501d93 100644 --- a/generic/tclCompile.h +++ b/generic/tclCompile.h @@ -1690,7 +1690,9 @@ MODULE_SCOPE int TclPushProcCallFrame(ClientData clientData, */ #define TCL_INDEX_END (-2) -#define TCL_INDEX_OUT_OF_RANGE (-1) +#define TCL_INDEX_BEFORE (-1) +#define TCL_INDEX_START (0) +#define TCL_INDEX_AFTER (INT_MAX) /* * DTrace probe macros (NOPs if DTrace support is not enabled). -- cgit v0.12 From 405b9175e62f3133e3e0811262ab863b70c7f1e7 Mon Sep 17 00:00:00 2001 From: "jan.nijtmans" Date: Wed, 7 Mar 2018 19:35:00 +0000 Subject: Fix handling of "pkgIndex" file in "package files" command. This was broken as well, as result of NRE-enabling the "package" command. --- generic/tclPkg.c | 25 +++++++++++-------------- 1 file changed, 11 insertions(+), 14 deletions(-) diff --git a/generic/tclPkg.c b/generic/tclPkg.c index e8c2801..1e54aa7 100644 --- a/generic/tclPkg.c +++ b/generic/tclPkg.c @@ -733,18 +733,17 @@ SelectPackage(ClientData data[], Tcl_Interp *interp, int result) { Tcl_Preserve(versionToProvide); pkgPtr->clientData = versionToProvide; + + pkgFiles = TclInitPkgFiles(interp); + /* Push "ifneeded" package name in "tclPkgFiles" assocdata. */ + pkgName = ckalloc(sizeof(PkgName) + strlen(name)); + pkgName->nextPtr = pkgFiles->names; + strcpy(pkgName->name, name); + pkgFiles->names = pkgName; if (bestPtr->pkgIndex) { TclPkgFileSeen(interp, bestPtr->pkgIndex); } reqPtr->versionToProvide = versionToProvide; - - pkgFiles = TclInitPkgFiles(interp); - /* Push "ifneeded" package name in "tclPkgFiles" assocdata. */ - pkgName = ckalloc(sizeof(PkgName) + strlen(name)); - pkgName->nextPtr = pkgFiles->names; - strcpy(pkgName->name, name); - pkgFiles->names = pkgName; - Tcl_NRAddCallback(interp, SelectPackageFinal, reqPtr, INT2PTR(reqc), (void *)reqv, data[3]); Tcl_NREvalObj(interp, Tcl_NewStringObj(bestPtr->script, -1), TCL_EVAL_GLOBAL); } @@ -758,14 +757,12 @@ SelectPackageFinal(ClientData data[], Tcl_Interp *interp, int result) { Tcl_Obj **const reqv = data[2]; const char *name = reqPtr->name; char *versionToProvide = reqPtr->versionToProvide; - void *toBeRemoved; - PkgFiles *pkgFiles; - pkgFiles = TclInitPkgFiles(interp); /* Pop the "ifneeded" package name from "tclPkgFiles" assocdata*/ - toBeRemoved = pkgFiles->names; - pkgFiles->names = pkgFiles->names->nextPtr; - ckfree(toBeRemoved); + PkgFiles *pkgFiles = Tcl_GetAssocData(interp, "tclPkgFiles", NULL); + PkgName *pkgName = pkgFiles->names; + pkgFiles->names = pkgName->nextPtr; + ckfree(pkgName); reqPtr->pkgPtr = FindPackage(interp, name); if (result == TCL_OK) { -- cgit v0.12 From d7f41b448c046d176a3b6a931a12d09d7e75b626 Mon Sep 17 00:00:00 2001 From: dgp Date: Wed, 7 Mar 2018 19:55:23 +0000 Subject: Express INST_LIST_INDEX_IMM index processinig in terms of TCL_INDEX_END so that consistencies are maintained, and hardcoded values are a bit demystified. --- generic/tclExecute.c | 9 ++------- 1 file changed, 2 insertions(+), 7 deletions(-) diff --git a/generic/tclExecute.c b/generic/tclExecute.c index d345899..6bc5485 100644 --- a/generic/tclExecute.c +++ b/generic/tclExecute.c @@ -5090,15 +5090,10 @@ TEBCresume( } /* - * Select the list item based on the index. Negative operand means - * end-based indexing (-2, ...), and -1 means out of range. + * Decode end-offset index values. */ - if (opnd < -1) { - index = opnd+1 + objc; - } else { - index = opnd; - } + index = opnd + (opnd <= TCL_INDEX_END)*(objc - 1 - TCL_INDEX_END); pcAdjustment = 5; lindexFastPath: -- cgit v0.12 From 3492c92f3dcb820bd5f7aa833e340b6e1eb8f1c5 Mon Sep 17 00:00:00 2001 From: "jan.nijtmans" Date: Wed, 7 Mar 2018 20:24:00 +0000 Subject: Improve -DTCL_NO_DEPRECATED compiles. It now can handle loading stub-enabled extensions with incompatible magic number (backported from trunk) --- generic/tclBasic.c | 11 ++++++++--- generic/tclLoad.c | 13 +++++++++++++ 2 files changed, 21 insertions(+), 3 deletions(-) diff --git a/generic/tclBasic.c b/generic/tclBasic.c index 3d16b70..c493c3d 100644 --- a/generic/tclBasic.c +++ b/generic/tclBasic.c @@ -4462,7 +4462,9 @@ TclNRRunCallbacks( /* All callbacks down to rootPtr not inclusive * are to be run. */ { +#if !defined(TCL_NO_DEPRECATED) && TCL_MAJOR_VERSION < 9 Interp *iPtr = (Interp *) interp; +#endif /* !defined(TCL_NO_DEPRECATED) */ NRE_callback *callbackPtr; Tcl_NRPostProc *procPtr; @@ -4476,9 +4478,11 @@ TclNRRunCallbacks( * are for NR function calls, and those are Tcl_Obj based. */ +#if !defined(TCL_NO_DEPRECATED) && TCL_MAJOR_VERSION < 9 if (*(iPtr->result) != 0) { (void) Tcl_GetObjResult(interp); } +#endif /* !defined(TCL_NO_DEPRECATED) */ /* This is the trampoline. */ @@ -6873,7 +6877,8 @@ Tcl_AddObjErrorInfo( iPtr->flags |= ERR_LEGACY_COPY; if (iPtr->errorInfo == NULL) { - if (iPtr->result[0] != 0) { +#if !defined(TCL_NO_DEPRECATED) && TCL_MAJOR_VERSION < 9 + if (*(iPtr->result) != 0) { /* * The interp's string result is set, apparently by some extension * making a deprecated direct write to it. That extension may @@ -6883,9 +6888,9 @@ Tcl_AddObjErrorInfo( */ iPtr->errorInfo = Tcl_NewStringObj(iPtr->result, -1); - } else { + } else +#endif /* !defined(TCL_NO_DEPRECATED) */ iPtr->errorInfo = iPtr->objResultPtr; - } Tcl_IncrRefCount(iPtr->errorInfo); if (!iPtr->errorCode) { Tcl_SetErrorCode(interp, "NONE", NULL); diff --git a/generic/tclLoad.c b/generic/tclLoad.c index e0bb5ef..77e6425 100644 --- a/generic/tclLoad.c +++ b/generic/tclLoad.c @@ -470,6 +470,19 @@ Tcl_LoadObjCmd( */ if (code != TCL_OK) { +#if defined(TCL_NO_DEPRECATED) || TCL_MAJOR_VERSION > 8 + Interp *iPtr = (Interp *) target; + if (iPtr->result && *(iPtr->result) && !iPtr->freeProc) { + /* + * A call to Tcl_InitStubs() determined the caller extension and + * this interp are incompatible in their stubs mechanisms, and + * recorded the error in the oldest legacy place we have to do so. + */ + Tcl_SetObjResult(target, Tcl_NewStringObj(iPtr->result, -1)); + iPtr->result = &tclEmptyString; + iPtr->freeProc = NULL; + } +#endif /* defined(TCL_NO_DEPRECATED) */ Tcl_TransferResult(target, code, interp); goto done; } -- cgit v0.12 From ce6aa3ea082e901341852037de6a866850f28351 Mon Sep 17 00:00:00 2001 From: dgp Date: Wed, 7 Mar 2018 21:02:44 +0000 Subject: When index parsing alone tells you a [string range] is empty, just push it. --- generic/tclCompCmdsSZ.c | 19 +++++++++++++++++-- 1 file changed, 17 insertions(+), 2 deletions(-) diff --git a/generic/tclCompCmdsSZ.c b/generic/tclCompCmdsSZ.c index d10d1c1..f98d375 100644 --- a/generic/tclCompCmdsSZ.c +++ b/generic/tclCompCmdsSZ.c @@ -930,6 +930,9 @@ TclCompileStringRangeCmd( fromTokenPtr = TokenAfter(stringTokenPtr); toTokenPtr = TokenAfter(fromTokenPtr); + /* Every path must push the string argument */ + CompileWord(envPtr, stringTokenPtr, interp, 1); + /* * Parse the two indices. */ @@ -942,6 +945,14 @@ TclCompileStringRangeCmd( * Token parsed as an index expression. We treat all indices before * the string the same as the start of the string. */ + + if (idx1 == TCL_INDEX_AFTER) { + /* [string range $s end+1 $last] must be empty string */ + OP( POP); + PUSH( ""); + return TCL_OK; + } + if (TclGetIndexFromToken(toTokenPtr, &idx2, TCL_INDEX_BEFORE, TCL_INDEX_END) != TCL_OK) { goto nonConstantIndices; @@ -950,12 +961,17 @@ TclCompileStringRangeCmd( * Token parsed as an index expression. We treat all indices after * the string the same as the end of the string. */ + if (idx2 == TCL_INDEX_BEFORE) { + /* [string range $s $first -1] must be empty string */ + OP( POP); + PUSH( ""); + return TCL_OK; + } /* * Push the operand onto the stack and then the substring operation. */ - CompileWord(envPtr, stringTokenPtr, interp, 1); OP44( STR_RANGE_IMM, idx1, idx2); return TCL_OK; @@ -964,7 +980,6 @@ TclCompileStringRangeCmd( */ nonConstantIndices: - CompileWord(envPtr, stringTokenPtr, interp, 1); CompileWord(envPtr, fromTokenPtr, interp, 2); CompileWord(envPtr, toTokenPtr, interp, 3); OP( STR_RANGE); -- cgit v0.12 From 30e7e05895de1b9534837717365babc905955f7a Mon Sep 17 00:00:00 2001 From: dgp Date: Wed, 7 Mar 2018 21:45:12 +0000 Subject: Streamline index decoding in INST_STR_RANGE_IMM execution. --- generic/tclExecute.c | 45 ++++++++++++++++++++++++++++----------------- 1 file changed, 28 insertions(+), 17 deletions(-) diff --git a/generic/tclExecute.c b/generic/tclExecute.c index 6bc5485..2e3fcb9 100644 --- a/generic/tclExecute.c +++ b/generic/tclExecute.c @@ -5640,33 +5640,44 @@ TEBCresume( length = Tcl_GetCharLength(valuePtr); TRACE(("\"%.20s\" %d %d => ", O2S(valuePtr), fromIdx, toIdx)); - /* - * Adjust indices for end-based indexing. - */ + /* Every range of an empty value is an empty value */ + if (length == 0) { + TRACE_APPEND(("\n")); + NEXT_INST_F(9, 0, 0); + } - if (fromIdx == -1) { - fromIdx = 0; - } else if (fromIdx < -1) { - fromIdx += 1 + length; - if (fromIdx < 0) { - fromIdx = 0; + /* Decode index operands. */ + + assert ( toIdx != TCL_INDEX_BEFORE ); + assert ( toIdx != TCL_INDEX_AFTER); + + if (toIdx <= TCL_INDEX_END) { + toIdx += (length - 1 - TCL_INDEX_END); + if (toIdx < 0) { + goto emptyRange; } - } else if (fromIdx >= length) { - fromIdx = length; - } - if (toIdx < -1) { - toIdx += 1 + length; } else if (toIdx >= length) { toIdx = length - 1; } - /* - * Check if we can do a sane substring. - */ + assert ( toIdx >= 0 && toIdx < length ); + + assert ( fromIdx != TCL_INDEX_BEFORE ); + assert ( fromIdx != TCL_INDEX_AFTER); + + if (fromIdx <= TCL_INDEX_END) { + fromIdx += (length - 1 - TCL_INDEX_END); + if (fromIdx < 0) { + fromIdx = 0; + } + } + + assert ( fromIdx >= 0 ); if (fromIdx <= toIdx) { objResultPtr = Tcl_GetRange(valuePtr, fromIdx, toIdx); } else { + emptyRange: TclNewObj(objResultPtr); } TRACE_APPEND(("%.30s\n", O2S(objResultPtr))); -- cgit v0.12 From 101ac8bca755a22b853816ef11db876e71d0ee29 Mon Sep 17 00:00:00 2001 From: dgp Date: Thu, 8 Mar 2018 02:28:49 +0000 Subject: Reduce the "clever" factor. (Fine line between clever and stupid.) --- generic/tclExecute.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/generic/tclExecute.c b/generic/tclExecute.c index 2e3fcb9..a6042bb 100644 --- a/generic/tclExecute.c +++ b/generic/tclExecute.c @@ -5076,8 +5076,8 @@ TEBCresume( */ valuePtr = OBJ_AT_TOS; - opnd = TclGetInt4AtPtr(pc+1); - TRACE(("\"%.30s\" %d => ", O2S(valuePtr), opnd)); + index = TclGetInt4AtPtr(pc+1); + TRACE(("\"%.30s\" %d => ", O2S(valuePtr), index)); /* * Get the contents of the list, making sure that it really is a list @@ -5093,7 +5093,9 @@ TEBCresume( * Decode end-offset index values. */ - index = opnd + (opnd <= TCL_INDEX_END)*(objc - 1 - TCL_INDEX_END); + if (index <= TCL_INDEX_END) { + index += (objc - 1 - TCL_INDEX_END); + } pcAdjustment = 5; lindexFastPath: -- cgit v0.12 From 64038c5656f9d288cb8a710c5b0b397244911b88 Mon Sep 17 00:00:00 2001 From: dgp Date: Thu, 8 Mar 2018 17:26:49 +0000 Subject: Rollback the stealth change to [lreplace a 1 1] in Tcl 8.6.6. [409ea17e37]. Scratch rewrite of the [lreplace] compiler. --- generic/tclCmdIL.c | 2 +- generic/tclCompCmdsGR.c | 280 +++++++++++++----------------------------------- tests/lreplace.test | 8 +- 3 files changed, 82 insertions(+), 208 deletions(-) diff --git a/generic/tclCmdIL.c b/generic/tclCmdIL.c index e3c5f10..0716afe 100644 --- a/generic/tclCmdIL.c +++ b/generic/tclCmdIL.c @@ -2762,7 +2762,7 @@ Tcl_LreplaceObjCmd( * (to allow for replacing the last elem). */ - if ((first > listLen) && (listLen > 0)) { + if ((first >= listLen) && (listLen > 0)) { Tcl_SetObjResult(interp, Tcl_ObjPrintf( "list doesn't contain element %s", TclGetString(objv[2]))); Tcl_SetErrorCode(interp, "TCL", "OPERATION", "LREPLACE", "BADIDX", diff --git a/generic/tclCompCmdsGR.c b/generic/tclCompCmdsGR.c index 501c7a4..de02ee7 100644 --- a/generic/tclCompCmdsGR.c +++ b/generic/tclCompCmdsGR.c @@ -1562,8 +1562,8 @@ TclCompileLreplaceCmd( { Tcl_Token *tokenPtr, *listTokenPtr; DefineLineInformation; /* TIP #280 */ - Tcl_Obj *tmpObj; int idx1, idx2, i, offset, offset2; + int emptyPrefix, suffixStart = 0; if (parsePtr->numWords < 4) { return TCL_ERROR; @@ -1599,243 +1599,117 @@ TclCompileLreplaceCmd( return TCL_ERROR; } -/* TODO: ...... */ /* - * Compilation fails when one index is end-based but the other isn't. - * Fixing this will require more bytecodes, but this is a workaround for - * now. [Bug 47ac84309b] - */ - - if ((idx1 <= TCL_INDEX_END) != (idx2 <= TCL_INDEX_END)) { - - /* - * NOTE: when idx1 == 0 and idx2 == TCL_INDEX_END, - * we bail out here! Yet, down below - */ - return TCL_ERROR; - } - - if (idx1 == -1) { - /* linsert before start or replace from start */ - idx1 = 0; - } - - if (idx2 != TCL_INDEX_END && idx2 >= 0 && idx2 < idx1) { - idx2 = idx1 - 1; - } - - /* - * Work out what this [lreplace] is actually doing. + * General structure of the [lreplace] result is + * prefix replacement suffix + * In a few cases we can predict various parts will be empty and + * take advantage. + * + * The proper suffix begins with the greater of indices idx1 or + * idx2 + 1. If we cannot tell at compile time which is greater, + * we must defer to direct evaluation. */ - tmpObj = NULL; - CompileWord(envPtr, listTokenPtr, interp, 1); - if (parsePtr->numWords == 4) { - if (idx1 == 0) { - if (idx2 == TCL_INDEX_END) { - - /* Here we are down below! Now look somewhere else! */ - goto dropAll; - } - idx1 = idx2 + 1; /* TODO: Overflow? */ - idx2 = TCL_INDEX_END; - goto dropEnd; - } else if (idx2 == TCL_INDEX_END) { - idx2 = idx1 - 1; - idx1 = 0; - goto dropEnd; - } else { - if (idx2 < idx1) { - idx2 = idx1 - 1; - } - if (idx1 > 0) { - tmpObj = Tcl_NewIntObj(idx1); - Tcl_IncrRefCount(tmpObj); - } - goto dropRange; - } - } - - tokenPtr = TokenAfter(tokenPtr); - for (i=4 ; inumWords ; i++) { - CompileWord(envPtr, tokenPtr, interp, i); - tokenPtr = TokenAfter(tokenPtr); - } - TclEmitInstInt4( INST_LIST, i - 4, envPtr); - TclEmitInstInt4( INST_REVERSE, 2, envPtr); - if (idx1 == 0) { - if (idx2 == TCL_INDEX_END) { - /* Another Can't Happen. */ - goto replaceAll; - } - idx1 = idx2 + 1; /* TODO: Overflow? */ - idx2 = TCL_INDEX_END; - goto replaceHead; + if (idx2 == TCL_INDEX_BEFORE) { + suffixStart = idx1; } else if (idx2 == TCL_INDEX_END) { - idx2 = idx1 - 1; - idx1 = 0; - goto replaceTail; + suffixStart = TCL_INDEX_AFTER; + } else if (((idx2 < TCL_INDEX_END) && (idx1 <= TCL_INDEX_END)) + || ((idx2 >= TCL_INDEX_START) && (idx1 >= TCL_INDEX_START))) { + suffixStart = (idx1 > idx2 + 1) ? idx1 : idx2 + 1; } else { - if (idx2 < idx1) { - idx2 = idx1 - 1; - } - if (idx1 > 0) { - tmpObj = Tcl_NewIntObj(idx1); - Tcl_IncrRefCount(tmpObj); - } - goto replaceRange; + return TCL_ERROR; } - /* - * Issue instructions to perform the operations relating to configurations - * that just drop. The only argument pushed on the stack is the list to - * operate on. - */ + /* All paths start with computing/pushing the original value. */ + CompileWord(envPtr, listTokenPtr, interp, 1); - dropAll: /* This just ensures the arg is a list. */ /* - * And now we're here down below the down below where flow can never go. - * CONCLUSION: This code has no purpose. + * [lreplace] raises an error when idx1 points after the list, but + * only when the list is not empty. This is maximum stupidity. + * + * TODO: TIP this nonsense away! */ -Tcl_Panic("Can not get here."); - TclEmitOpcode( INST_LIST_LENGTH, envPtr); - TclEmitOpcode( INST_POP, envPtr); - PushStringLiteral(envPtr, ""); - goto done; - - dropEnd: - TclEmitInstInt4( INST_LIST_RANGE_IMM, idx1, envPtr); - TclEmitInt4( idx2, envPtr); - goto done; - - dropRange: - if (tmpObj != NULL) { - /* - * Emit bytecode to check the list length. - */ - + if (idx1 >= TCL_INDEX_START) { TclEmitOpcode( INST_DUP, envPtr); TclEmitOpcode( INST_LIST_LENGTH, envPtr); - TclEmitPush(TclAddLiteralObj(envPtr, tmpObj, NULL), envPtr); - TclEmitOpcode( INST_GE, envPtr); + TclEmitOpcode( INST_DUP, envPtr); offset = CurrentOffset(envPtr); - TclEmitInstInt1( INST_JUMP_TRUE1, 0, envPtr); - - /* - * Emit an error if we've been given an empty list. - */ + TclEmitInstInt1( INST_JUMP_FALSE1, 0, envPtr); -/* If we're generating bytecode to report an error, we've gone wrong. - * Just fallback to direct invocation. - */ - TclEmitOpcode( INST_DUP, envPtr); - TclEmitOpcode( INST_LIST_LENGTH, envPtr); + /* List is not empty */ + TclEmitPush(TclAddLiteralObj(envPtr, Tcl_NewIntObj(idx1), + NULL), envPtr); + TclEmitOpcode( INST_GT, envPtr); offset2 = CurrentOffset(envPtr); - TclEmitInstInt1( INST_JUMP_FALSE1, 0, envPtr); + TclEmitInstInt1( INST_JUMP_TRUE1, 0, envPtr); + + /* Idx1 >= list length ===> raise an error */ TclEmitPush(TclAddLiteralObj(envPtr, Tcl_ObjPrintf( "list doesn't contain element %d", idx1), NULL), envPtr); CompileReturnInternal(envPtr, INST_RETURN_IMM, TCL_ERROR, 0, Tcl_ObjPrintf("-errorcode {TCL OPERATION LREPLACE BADIDX}")); TclStoreInt1AtPtr(CurrentOffset(envPtr) - offset, envPtr->codeStart + offset + 1); + TclEmitOpcode( INST_POP, envPtr); TclStoreInt1AtPtr(CurrentOffset(envPtr) - offset2, envPtr->codeStart + offset2 + 1); - TclAdjustStackDepth(-1, envPtr); } - TclEmitOpcode( INST_DUP, envPtr); - TclEmitInstInt4( INST_LIST_RANGE_IMM, 0, envPtr); - TclEmitInt4( idx1 - 1, envPtr); - TclEmitInstInt4( INST_REVERSE, 2, envPtr); - TclEmitInstInt4( INST_LIST_RANGE_IMM, idx2 + 1, envPtr); - TclEmitInt4( TCL_INDEX_END, envPtr); - TclEmitOpcode( INST_LIST_CONCAT, envPtr); - goto done; - - /* - * Issue instructions to perform the operations relating to configurations - * that do real replacement. All arguments are pushed and assembled into a - * pair: the list of values to replace with, and the list to do the - * surgery on. - */ - - replaceAll: -Tcl_Panic("Can not get here."); - TclEmitOpcode( INST_LIST_LENGTH, envPtr); - TclEmitOpcode( INST_POP, envPtr); - goto done; - replaceHead: - TclEmitInstInt4( INST_LIST_RANGE_IMM, idx1, envPtr); - TclEmitInt4( idx2, envPtr); - TclEmitOpcode( INST_LIST_CONCAT, envPtr); - goto done; - - replaceTail: - TclEmitInstInt4( INST_LIST_RANGE_IMM, idx1, envPtr); - TclEmitInt4( idx2, envPtr); - TclEmitInstInt4( INST_REVERSE, 2, envPtr); - TclEmitOpcode( INST_LIST_CONCAT, envPtr); - goto done; - - replaceRange: - if (tmpObj != NULL) { + if ((idx1 == suffixStart) && (parsePtr->numWords == 4)) { /* - * Emit bytecode to check the list length. + * This is a "no-op". Example: [lreplace {a b c} 2 0] + * We still do a list operation to get list-verification + * and canonicalization side effects. */ + TclEmitInstInt4( INST_LIST_RANGE_IMM, 0, envPtr); + TclEmitInt4( TCL_INDEX_END, envPtr); + return TCL_OK; + } + emptyPrefix = (idx1 == TCL_INDEX_START); + if (!emptyPrefix) { + /* Prefix may not be empty; generate bytecode to push it */ TclEmitOpcode( INST_DUP, envPtr); - TclEmitOpcode( INST_LIST_LENGTH, envPtr); - - /* - * Check the list length vs idx1. - */ - - TclEmitPush(TclAddLiteralObj(envPtr, tmpObj, NULL), envPtr); - TclEmitOpcode( INST_GE, envPtr); - offset = CurrentOffset(envPtr); - TclEmitInstInt1( INST_JUMP_TRUE1, 0, envPtr); + TclEmitInstInt4( INST_LIST_RANGE_IMM, 0, envPtr); + TclEmitInt4( idx1 - 1, envPtr); + } - /* - * Emit an error if we've been given an empty list. - */ + if (parsePtr->numWords > 4) { + /* Push the replacement arguments */ + tokenPtr = TokenAfter(tokenPtr); + for (i=4 ; inumWords ; i++) { + CompileWord(envPtr, tokenPtr, interp, i); + tokenPtr = TokenAfter(tokenPtr); + } -/* If we're generating bytecode to report an error, we've gone wrong. - * Just fallback to direct invocation. - */ - TclEmitOpcode( INST_DUP, envPtr); - TclEmitOpcode( INST_LIST_LENGTH, envPtr); - offset2 = CurrentOffset(envPtr); - TclEmitInstInt1( INST_JUMP_FALSE1, 0, envPtr); - TclEmitPush(TclAddLiteralObj(envPtr, Tcl_ObjPrintf( - "list doesn't contain element %d", idx1), NULL), envPtr); - CompileReturnInternal(envPtr, INST_RETURN_IMM, TCL_ERROR, 0, - Tcl_ObjPrintf("-errorcode {TCL OPERATION LREPLACE BADIDX}")); - TclStoreInt1AtPtr(CurrentOffset(envPtr) - offset, - envPtr->codeStart + offset + 1); - TclStoreInt1AtPtr(CurrentOffset(envPtr) - offset2, - envPtr->codeStart + offset2 + 1); - TclAdjustStackDepth(-1, envPtr); + /* Make a list of them... */ + TclEmitInstInt4( INST_LIST, i - 4, envPtr); + if (!emptyPrefix) { + /* ...and join to the prefix, if any. */ + TclEmitOpcode( INST_LIST_CONCAT, envPtr); + } + emptyPrefix = 0; } - TclEmitOpcode( INST_DUP, envPtr); - TclEmitInstInt4( INST_LIST_RANGE_IMM, 0, envPtr); - TclEmitInt4( idx1 - 1, envPtr); - TclEmitInstInt4( INST_REVERSE, 2, envPtr); - TclEmitInstInt4( INST_LIST_RANGE_IMM, idx2 + 1, envPtr); - TclEmitInt4( TCL_INDEX_END, envPtr); - TclEmitInstInt4( INST_REVERSE, 3, envPtr); - TclEmitOpcode( INST_LIST_CONCAT, envPtr); - TclEmitInstInt4( INST_REVERSE, 2, envPtr); - TclEmitOpcode( INST_LIST_CONCAT, envPtr); - goto done; - /* - * Clean up the allocated memory. - */ + if (!emptyPrefix) { + TclEmitInstInt4( INST_REVERSE, 2, envPtr); + } - done: - if (tmpObj != NULL) { - Tcl_DecrRefCount(tmpObj); + if (suffixStart == TCL_INDEX_AFTER) { + TclEmitOpcode( INST_POP, envPtr); + if (emptyPrefix) { + PushStringLiteral(envPtr, ""); + } + } else { + /* Suffix may not be empty; generate bytecode to push it */ + TclEmitInstInt4( INST_LIST_RANGE_IMM, suffixStart, envPtr); + TclEmitInt4( TCL_INDEX_END, envPtr); + if (!emptyPrefix) { + TclEmitOpcode( INST_LIST_CONCAT, envPtr); + } } + return TCL_OK; } diff --git a/tests/lreplace.test b/tests/lreplace.test index d7f8226..392e84d 100644 --- a/tests/lreplace.test +++ b/tests/lreplace.test @@ -98,12 +98,12 @@ test lreplace-1.26 {lreplace command} { [set foo [lreplace $foo end end]] \ [set foo [lreplace $foo end end]] } {a {} {}} -test lreplace-1.27 {lreplace command} { +test lreplace-1.27 {lreplace command} -body { lreplace x 1 1 -} x -test lreplace-1.28 {lreplace command} { +} -returnCodes 1 -result {list doesn't contain element 1} +test lreplace-1.28 {lreplace command} -body { lreplace x 1 1 y -} {x y} +} -returnCodes 1 -result {list doesn't contain element 1} test lreplace-2.1 {lreplace errors} { list [catch lreplace msg] $msg -- cgit v0.12 From 0c5bd7480ec59acdb0b66d61e8efbec87ff38f0a Mon Sep 17 00:00:00 2001 From: dgp Date: Thu, 8 Mar 2018 18:57:16 +0000 Subject: Streamline index decoding in INST_LIST_RANGE_IMM execution. Eliminte the internals intrusion in the unshared in-place operations case. Tcl_ListObjReplace() really ought to be good enough. --- generic/tclExecute.c | 72 ++++++++++++++++++++++------------------------------ 1 file changed, 31 insertions(+), 41 deletions(-) diff --git a/generic/tclExecute.c b/generic/tclExecute.c index a6042bb..7043179 100644 --- a/generic/tclExecute.c +++ b/generic/tclExecute.c @@ -5243,60 +5243,50 @@ TEBCresume( } #endif - /* - * Adjust the indices for end-based handling. - */ + /* Decode index value operands. */ - if (fromIdx < -1) { - fromIdx += 1+objc; - if (fromIdx < -1) { - fromIdx = -1; - } - } else if (fromIdx > objc) { - fromIdx = objc; + assert ( toIdx != TCL_INDEX_AFTER); + + if ((toIdx == TCL_INDEX_BEFORE) || (fromIdx == TCL_INDEX_AFTER)) { + goto emptyList; } - if (toIdx < -1) { - toIdx += 1 + objc; - if (toIdx < -1) { - toIdx = -1; + if (toIdx <= TCL_INDEX_END) { + toIdx += (objc - 1 - TCL_INDEX_END); + if (toIdx < 0) { + goto emptyList; } - } else if (toIdx > objc) { - toIdx = objc; + } else if (toIdx >= objc) { + toIdx = objc - 1; } - /* - * Check if we are referring to a valid, non-empty list range, and if - * so, build the list of elements in that range. - */ + assert ( toIdx >= 0 && toIdx < objc); + assert ( fromIdx != TCL_INDEX_BEFORE ); + assert ( fromIdx != TCL_INDEX_AFTER); - if (fromIdx<=toIdx && fromIdx=0) { + if (fromIdx <= TCL_INDEX_END) { + fromIdx += (objc - 1 - TCL_INDEX_END); if (fromIdx < 0) { fromIdx = 0; } - if (toIdx >= objc) { - toIdx = objc-1; - } - if (fromIdx == 0 && toIdx != objc-1 && !Tcl_IsShared(valuePtr)) { - /* - * BEWARE! This is looking inside the implementation of the - * list type. - */ - - List *listPtr = valuePtr->internalRep.twoPtrValue.ptr1; + } + assert ( fromIdx >= 0 ); - if (listPtr->refCount == 1) { - for (index=toIdx+1; indexelemCount = toIdx+1; - listPtr->canonicalFlag = 1; - TclInvalidateStringRep(valuePtr); - TRACE_APPEND(("%.30s\n", O2S(valuePtr))); - NEXT_INST_F(9, 0, 0); + if (fromIdx <= toIdx) { + /* Construct the subsquence list */ + /* unshared optimization */ + if (Tcl_IsShared(valuePtr)) { + objResultPtr = Tcl_NewListObj(toIdx-fromIdx+1, objv+fromIdx); + } else { + if (toIdx != objc - 1) { + Tcl_ListObjReplace(NULL, valuePtr, toIdx + 1, + objc - 1 - toIdx, 0, NULL); } + Tcl_ListObjReplace(NULL, valuePtr, 0, fromIdx, 0, NULL); + TRACE_APPEND(("%.30s\n", O2S(valuePtr))); + NEXT_INST_F(9, 0, 0); } - objResultPtr = Tcl_NewListObj(toIdx-fromIdx+1, objv+fromIdx); } else { + emptyList: TclNewObj(objResultPtr); } -- cgit v0.12 From b8b87e52802d476aa5e7d6796ff233f89cf0156b Mon Sep 17 00:00:00 2001 From: dgp Date: Thu, 8 Mar 2018 19:28:58 +0000 Subject: New test expose flaw in error ordering. --- tests/lreplace.test | 3 +++ 1 file changed, 3 insertions(+) diff --git a/tests/lreplace.test b/tests/lreplace.test index 392e84d..7377869 100644 --- a/tests/lreplace.test +++ b/tests/lreplace.test @@ -104,6 +104,9 @@ test lreplace-1.27 {lreplace command} -body { test lreplace-1.28 {lreplace command} -body { lreplace x 1 1 y } -returnCodes 1 -result {list doesn't contain element 1} +test lreplace-1.29 {lreplace command} -body { + lreplace x 1 1 [error foo] +} -returnCodes 1 -result {foo} test lreplace-2.1 {lreplace errors} { list [catch lreplace msg] $msg -- cgit v0.12 From ed53b715acb5d9a060c898f5ad4cfa79d6c9db1d Mon Sep 17 00:00:00 2001 From: dgp Date: Thu, 8 Mar 2018 19:43:57 +0000 Subject: Another error ordering test. --- tests/lreplace.test | 3 +++ 1 file changed, 3 insertions(+) diff --git a/tests/lreplace.test b/tests/lreplace.test index 7377869..4a6b853 100644 --- a/tests/lreplace.test +++ b/tests/lreplace.test @@ -107,6 +107,9 @@ test lreplace-1.28 {lreplace command} -body { test lreplace-1.29 {lreplace command} -body { lreplace x 1 1 [error foo] } -returnCodes 1 -result {foo} +test lreplace-1.30 {lreplace command} -body { + lreplace {not {}alist} 0 0 [error foo] +} -returnCodes 1 -result {foo} test lreplace-2.1 {lreplace errors} { list [catch lreplace msg] $msg -- cgit v0.12 From 947fb98db5ca258e0f170c51a9392816a6f48a8f Mon Sep 17 00:00:00 2001 From: dgp Date: Thu, 8 Mar 2018 21:58:30 +0000 Subject: Stop failing error ordering tests in compiled [lreplace]. --- generic/tclCompCmdsGR.c | 49 +++++++++++++++++++++++++++++++------------------ 1 file changed, 31 insertions(+), 18 deletions(-) diff --git a/generic/tclCompCmdsGR.c b/generic/tclCompCmdsGR.c index de02ee7..e2ddb11 100644 --- a/generic/tclCompCmdsGR.c +++ b/generic/tclCompCmdsGR.c @@ -1563,7 +1563,7 @@ TclCompileLreplaceCmd( Tcl_Token *tokenPtr, *listTokenPtr; DefineLineInformation; /* TIP #280 */ int idx1, idx2, i, offset, offset2; - int emptyPrefix, suffixStart = 0; + int emptyPrefix=1, suffixStart = 0; if (parsePtr->numWords < 4) { return TCL_ERROR; @@ -1625,13 +1625,35 @@ TclCompileLreplaceCmd( CompileWord(envPtr, listTokenPtr, interp, 1); /* + * Push all the replacement values next so any errors raised in + * creating them get raised first. + */ + if (parsePtr->numWords > 4) { + /* Push the replacement arguments */ + tokenPtr = TokenAfter(tokenPtr); + for (i=4 ; inumWords ; i++) { + CompileWord(envPtr, tokenPtr, interp, i); + tokenPtr = TokenAfter(tokenPtr); + } + + /* Make a list of them... */ + TclEmitInstInt4( INST_LIST, i - 4, envPtr); + + emptyPrefix = 0; + } + + /* * [lreplace] raises an error when idx1 points after the list, but * only when the list is not empty. This is maximum stupidity. * * TODO: TIP this nonsense away! */ if (idx1 >= TCL_INDEX_START) { - TclEmitOpcode( INST_DUP, envPtr); + if (emptyPrefix) { + TclEmitOpcode( INST_DUP, envPtr); + } else { + TclEmitInstInt4( INST_OVER, 1, envPtr); + } TclEmitOpcode( INST_LIST_LENGTH, envPtr); TclEmitOpcode( INST_DUP, envPtr); offset = CurrentOffset(envPtr); @@ -1667,26 +1689,17 @@ TclCompileLreplaceCmd( return TCL_OK; } - emptyPrefix = (idx1 == TCL_INDEX_START); - if (!emptyPrefix) { + if (idx1 != TCL_INDEX_START) { /* Prefix may not be empty; generate bytecode to push it */ - TclEmitOpcode( INST_DUP, envPtr); + if (emptyPrefix) { + TclEmitOpcode( INST_DUP, envPtr); + } else { + TclEmitInstInt4( INST_OVER, 1, envPtr); + } TclEmitInstInt4( INST_LIST_RANGE_IMM, 0, envPtr); TclEmitInt4( idx1 - 1, envPtr); - } - - if (parsePtr->numWords > 4) { - /* Push the replacement arguments */ - tokenPtr = TokenAfter(tokenPtr); - for (i=4 ; inumWords ; i++) { - CompileWord(envPtr, tokenPtr, interp, i); - tokenPtr = TokenAfter(tokenPtr); - } - - /* Make a list of them... */ - TclEmitInstInt4( INST_LIST, i - 4, envPtr); if (!emptyPrefix) { - /* ...and join to the prefix, if any. */ + TclEmitInstInt4( INST_REVERSE, 2, envPtr); TclEmitOpcode( INST_LIST_CONCAT, envPtr); } emptyPrefix = 0; -- cgit v0.12 From 88812125b1c2634264238a902c01c4ed85c9900c Mon Sep 17 00:00:00 2001 From: dgp Date: Fri, 9 Mar 2018 15:28:35 +0000 Subject: New tests demonstrating index value encoding flaws in [lsearch]. --- tests/lsearch.test | 41 ++++++++++++++++++++++++++++++++++++----- 1 file changed, 36 insertions(+), 5 deletions(-) diff --git a/tests/lsearch.test b/tests/lsearch.test index f36e987..8d03e96 100644 --- a/tests/lsearch.test +++ b/tests/lsearch.test @@ -418,6 +418,31 @@ test lsearch-17.6 {lsearch -index option, basic functionality} { test lsearch-17.7 {lsearch -index option, basic functionality} { lsearch -all -index 1 -regexp {{ab cb} {ab bb} {ab ab}} {[cb]b} } {0 1} +test lsearch-17.8 {lsearch -index option, empty argument} { + lsearch -index {} a a +} 0 +test lsearch-17.9 {lsearch -index option, empty argument} { + lsearch -index {} a a +} [lsearch a a] +test lsearch-17.10 {lsearch -index option, empty argument} { + lsearch -index {} [list \{] \{ +} 0 +test lsearch-17.11 {lsearch -index option, empty argument} { + lsearch -index {} [list \{] \{ +} [lsearch [list \{] \{] +test lsearch-17.12 {lsearch -index option, encoding aliasing} -body { + lsearch -index -2 a a +} -returnCodes error -result {index "-2" cannot select an element from any list} +test lsearch-17.13 {lsearch -index option, encoding aliasing} -body { + lsearch -index -1-1 a a +} -returnCodes error -result {index "-1-1" cannot select an element from any list} +test lsearch-17.14 {lsearch -index option, encoding aliasing} -body { + lsearch -index end--1 a a +} -returnCodes error -result {index "end--1" cannot select an element from any list} +test lsearch-17.15 {lsearch -index option, encoding aliasing} -body { + lsearch -index end+1 a a +} -returnCodes error -result {index "end+1" cannot select an element from any list} + test lsearch-18.1 {lsearch -index option, list as index basic functionality} { lsearch -index {0 0} {{{x x} {x b} {a d}} {{a c} {a b} {a a}}} a @@ -435,21 +460,27 @@ test lsearch-18.5 {lsearch -index option, list as index basic functionality} { lsearch -all -index {0 0} -exact {{{a c} {a b} {d a}} {{a c} {a b} {d a}}} a } {0 1} -test lsearch-19.1 {lsearch -sunindices option} { +test lsearch-19.1 {lsearch -subindices option} { lsearch -subindices -index {0 0} {{{x x} {x b} {a d}} {{a c} {a b} {a a}}} a } {1 0 0} -test lsearch-19.2 {lsearch -sunindices option} { +test lsearch-19.2 {lsearch -subindices option} { lsearch -subindices -index {2 0} -exact {{{x x} {x b} {a d}} {{a c} {a b} {a a}}} a } {0 2 0} -test lsearch-19.3 {lsearch -sunindices option} { +test lsearch-19.3 {lsearch -subindices option} { lsearch -subindices -index {1 1} -glob {{{ab cb} {ab bb} {ab ab}} {{ab cb} {ab bb} {ab ab}}} b* } {0 1 1} -test lsearch-19.4 {lsearch -sunindices option} { +test lsearch-19.4 {lsearch -subindices option} { lsearch -subindices -index {0 1} -regexp {{{ab cb} {ab bb} {ab ab}} {{ab cb} {ab bb} {ab ab}}} {[cb]b} } {0 0 1} -test lsearch-19.5 {lsearch -sunindices option} { +test lsearch-19.5 {lsearch -subindices option} { lsearch -subindices -all -index {0 0} -exact {{{a c} {a b} {d a}} {{a c} {a b} {d a}}} a } {{0 0 0} {1 0 0}} +test lsearch-19.6 {lsearch -subindices option} { + lsearch -subindices -index end {{1 a}} a +} {0 1} +test lsearch-19.7 {lsearch -subindices option} { + lsearch -subindices -all -index end {{1 a}} a +} {{0 1}} test lsearch-20.1 {lsearch -index option, index larger than sublists} -body { lsearch -index 2 {{a c} {a b} {a a}} a -- cgit v0.12 From 5fd318bc35bbaa27e006360af375ca2c078b763a Mon Sep 17 00:00:00 2001 From: dgp Date: Fri, 9 Mar 2018 17:30:30 +0000 Subject: More demonstration tests of index value encoding flaws. --- generic/tclCmdIL.c | 3 +++ tests/cmdIL.test | 25 +++++++++++++++++++++++-- tests/lsearch.test | 3 +++ 3 files changed, 29 insertions(+), 2 deletions(-) diff --git a/generic/tclCmdIL.c b/generic/tclCmdIL.c index 0716afe..afb5b62 100644 --- a/generic/tclCmdIL.c +++ b/generic/tclCmdIL.c @@ -3933,6 +3933,9 @@ Tcl_LsortObjCmd( /* * Do not shrink the actual memory block used; that doesn't * work with TclStackAlloc-allocated memory. [Bug 2918962] + * + * TODO: Consider a pointer increment to replace this + * array shift. */ for (i = 0; i < sortInfo.indexc; i++) { diff --git a/tests/cmdIL.test b/tests/cmdIL.test index 7636adc..c83bd98 100644 --- a/tests/cmdIL.test +++ b/tests/cmdIL.test @@ -147,6 +147,12 @@ test cmdIL-1.36 {lsort -stride and -index: Bug 2918962} { {{b i g} 12345} {{d e m o} 34512} } } {{{b i g} 12345} {{d e m o} 34512} {{c o d e} 54321} {{b l a h} 94729}} +test cmdIL-1.37 {lsort -stride and -index} -body { + lsort -stride 2 -index -2 {a 2 b 1} +} -returnCodes error -result {index "-2" cannot select an element from any list} +test cmdIL-1.38 {lsort -stride and-index} -body { + lsort -stride 2 -index -1-1 {a 2 b 1} +} -returnCodes error -result {index "-1-1" cannot select an element from any list} # Can't think of any good tests for the MergeSort and MergeLists procedures, # except a bunch of random lists to sort. @@ -208,13 +214,28 @@ test cmdIL-3.5.1 {SortCompare procedure, -index option (out of range, calculated } -returnCodes error -result {element 4 missing from sublist "1 . c"} test cmdIL-3.5.2 {SortCompare procedure, -index option (out of range, calculated index)} -body { lsort -index -1-1 {{1 . c} {2 . b} {3 . a}} -} -returnCodes error -result {element -2 missing from sublist "1 . c"} +} -returnCodes error -result {index "-1-1" cannot select an element from any list} test cmdIL-3.5.3 {SortCompare procedure, -index option (out of range, calculated index)} -body { lsort -index -2 {{1 . c} {2 . b} {3 . a}} -} -returnCodes error -result {element -2 missing from sublist "1 . c"} +} -returnCodes error -result {index "-2" cannot select an element from any list} test cmdIL-3.5.4 {SortCompare procedure, -index option (out of range, calculated index)} -body { lsort -index end-4 {{1 . c} {2 . b} {3 . a}} } -returnCodes error -result {element -2 missing from sublist "1 . c"} +test cmdIL-3.5.5 {SortCompare procedure, -index option} { + lsort -index {} {a b} +} {a b} +test cmdIL-3.5.6 {SortCompare procedure, -index option} { + lsort -index {} [list a \{] +} {a \{} +test cmdIL-3.5.7 {SortCompare procedure, -index option (out of range, calculated index)} -body { + lsort -index end--1 {{1 . c} {2 . b} {3 . a}} +} -returnCodes error -result {index "end--1" cannot select an element from any list} +test cmdIL-3.5.8 {SortCompare procedure, -index option (out of range, calculated index)} -body { + lsort -index end+1 {{1 . c} {2 . b} {3 . a}} +} -returnCodes error -result {index "end+1" cannot select an element from any list} +test cmdIL-3.5.9 {SortCompare procedure, -index option (out of range, calculated index)} -body { + lsort -index end+2 {{1 . c} {2 . b} {3 . a}} +} -returnCodes error -result {index "end+2" cannot select an element from any list} test cmdIL-3.6 {SortCompare procedure, -index option} { lsort -integer -index 2 {{1 15 30} {2 5 25} {3 25 20}} } {{3 25 20} {2 5 25} {1 15 30}} diff --git a/tests/lsearch.test b/tests/lsearch.test index 8d03e96..d7f9414 100644 --- a/tests/lsearch.test +++ b/tests/lsearch.test @@ -442,6 +442,9 @@ test lsearch-17.14 {lsearch -index option, encoding aliasing} -body { test lsearch-17.15 {lsearch -index option, encoding aliasing} -body { lsearch -index end+1 a a } -returnCodes error -result {index "end+1" cannot select an element from any list} +test lsearch-17.16 {lsearch -index option, encoding aliasing} -body { + lsearch -index end+2 a a +} -returnCodes error -result {index "end+2" cannot select an element from any list} test lsearch-18.1 {lsearch -index option, list as index basic functionality} { -- cgit v0.12 From 6798b2404f883074422c40ca7d196ad174a2d1ef Mon Sep 17 00:00:00 2001 From: dgp Date: Fri, 9 Mar 2018 19:23:42 +0000 Subject: Refactor the index value encode/decode machinery for broader use. Make use of it to fix index value flaws in [lsearch]. --- generic/tclCmdIL.c | 43 +++++++++------- generic/tclCompile.h | 9 ---- generic/tclInt.h | 15 ++++++ generic/tclUtil.c | 137 +++++++++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 177 insertions(+), 27 deletions(-) diff --git a/generic/tclCmdIL.c b/generic/tclCmdIL.c index afb5b62..7a13b71 100644 --- a/generic/tclCmdIL.c +++ b/generic/tclCmdIL.c @@ -64,8 +64,9 @@ typedef struct SortInfo { * SORTMODE_COMMAND. Pre-initialized to hold * base of command. */ int *indexv; /* If the -index option was specified, this - * holds the indexes contained in the list - * supplied as an argument to that option. + * holds an encoding of the indexes contained + * in the list supplied as an argument to + * that option. * NULL if no indexes supplied, and points to * singleIndex field when only one * supplied. */ @@ -2913,7 +2914,7 @@ Tcl_LsearchObjCmd( Tcl_Obj *const objv[]) /* Argument values. */ { const char *bytes, *patternBytes; - int i, match, index, result, listc, length, elemLen, bisect; + int i, match, index, result=TCL_OK, listc, length, elemLen, bisect; int dataType, isIncreasing, lower, upper, offset; Tcl_WideInt patWide, objWide; int allMatches, inlineReturn, negatedMatch, returnSubindices, noCase; @@ -3113,13 +3114,26 @@ Tcl_LsearchObjCmd( */ for (j=0 ; jresultCode = TCL_ERROR; return NULL; } - index = infoPtr->indexv[i]; - /* - * Adjust for end-based indexing. - */ - - if (index < SORTIDX_NONE) { - index += listLen + 1; - } + index = TclIndexDecode(infoPtr->indexv[i], listLen - 1); if (Tcl_ListObjIndex(infoPtr->interp, objPtr, index, ¤tObj) != TCL_OK) { diff --git a/generic/tclCompile.h b/generic/tclCompile.h index 9501d93..d842fdd 100644 --- a/generic/tclCompile.h +++ b/generic/tclCompile.h @@ -1686,15 +1686,6 @@ MODULE_SCOPE int TclPushProcCallFrame(ClientData clientData, #define TCL_NO_ELEMENT 2 /* Do not push the array element. */ /* - * Special value used by TclGetIndexFromToken to encoding the "end" index. - */ - -#define TCL_INDEX_END (-2) -#define TCL_INDEX_BEFORE (-1) -#define TCL_INDEX_START (0) -#define TCL_INDEX_AFTER (INT_MAX) - -/* * DTrace probe macros (NOPs if DTrace support is not enabled). */ diff --git a/generic/tclInt.h b/generic/tclInt.h index 1b1b078..3821e42 100644 --- a/generic/tclInt.h +++ b/generic/tclInt.h @@ -4013,6 +4013,21 @@ MODULE_SCOPE unsigned TclHashObjKey(Tcl_HashTable *tablePtr, void *keyPtr); MODULE_SCOPE int TclFullFinalizationRequested(void); /* + * Utility routines for encoding index values as integers. Used by both + * some of the command compilers and by [lsort] and [lsearch]. + */ + +MODULE_SCOPE int TclIndexEncode(Tcl_Interp *interp, Tcl_Obj *objPtr, + int before, int after, int *indexPtr); +MODULE_SCOPE int TclIndexDecode(int encoded, int endValue); + +/* Constants used in index value encoding routines. */ +#define TCL_INDEX_END (-2) +#define TCL_INDEX_BEFORE (-1) +#define TCL_INDEX_START (0) +#define TCL_INDEX_AFTER (INT_MAX) + +/* *---------------------------------------------------------------- * Macros used by the Tcl core to create and release Tcl objects. * TclNewObj(objPtr) creates a new object denoting an empty string. diff --git a/generic/tclUtil.c b/generic/tclUtil.c index beeaae1..f6a92fc 100644 --- a/generic/tclUtil.c +++ b/generic/tclUtil.c @@ -3813,6 +3813,143 @@ SetEndOffsetFromAny( /* *---------------------------------------------------------------------- * + * TclIndexEncode -- + * + * Parse objPtr to determine if it is an index value. Two cases + * are possible. The value objPtr might be parsed as an absolute + * index value in the C signed int range. Note that this includes + * index values that are integers as presented and it includes index + * arithmetic expressions. The absolute index values that can be + * directly meaningful as an index into either a list or a string are + * those integer values >= TCL_INDEX_START (0) + * and < TCL_INDEX_AFTER (INT_MAX). + * The largest string supported in Tcl 8 has bytelength INT_MAX. + * This means the largest supported character length is also INT_MAX, + * and the index of the last character in a string of length INT_MAX + * is INT_MAX-1. + * + * Any absolute index value parsed outside that range is encoded + * using the before and after values passed in by the + * caller as the encoding to use for indices that are either + * less than or greater than the usable index range. TCL_INDEX_AFTER + * is available as a good choice for most callers to use for + * after. Likewise, the value TCL_INDEX_BEFORE is good for + * most callers to use for before. Other values are possible + * when the caller knows it is helpful in producing its own behavior + * for indices before and after the indexed item. + * + * A token can also be parsed as an end-relative index expression. + * All end-relative expressions that indicate an index larger + * than end (end+2, end--5) point beyond the end of the indexed + * collection, and can be encoded as after. The end-relative + * expressions that indicate an index less than or equal to end + * are encoded relative to the value TCL_INDEX_END (-2). The + * index "end" is encoded as -2, down to the index "end-0x7ffffffe" + * which is encoded as INT_MIN. Since the largest index into a + * string possible in Tcl 8 is 0x7ffffffe, the interpretation of + * "end-0x7ffffffe" for that largest string would be 0. Thus, + * if the tokens "end-0x7fffffff" or "end+-0x80000000" are parsed, + * they can be encoded with the before value. + * + * These details will require re-examination whenever string and + * list length limits are increased, but that will likely also + * mean a revised routine capable of returning Tcl_WideInt values. + * + * Returns: + * TCL_OK if parsing succeeded, and TCL_ERROR if it failed. + * + * Side effects: + * When TCL_OK is returned, the encoded index value is written + * to *indexPtr. + * + *---------------------------------------------------------------------- + */ + +int +TclIndexEncode( + Tcl_Interp *interp, /* For error reporting, may be NULL */ + Tcl_Obj *objPtr, /* Index value to parse */ + int before, /* Value to return for index before beginning */ + int after, /* Value to return for index after end */ + int *indexPtr) /* Where to write the encoded answer, not NULL */ +{ + int idx; + + if (TCL_OK == TclGetIntFromObj(NULL, objPtr, &idx)) { + /* We parsed a value in the range INT_MIN...INT_MAX */ + integerEncode: + if (idx < TCL_INDEX_START) { + /* All negative absolute indices are "before the beginning" */ + idx = before; + } else if (idx == INT_MAX) { + /* This index value is always "after the end" */ + idx = after; + } + /* usual case, the absolute index value encodes itself */ + } else if (TCL_OK == TclGetEndOffsetFromObj(NULL, objPtr, 0, &idx)) { + /* + * We parsed an end+offset index value. + * idx holds the offset value in the range INT_MIN...INT_MAX. + */ + if (idx > 0) { + /* + * All end+postive or end-negative expressions + * always indicate "after the end". + */ + idx = after; + } else if (idx < INT_MIN - TCL_INDEX_END) { + /* These indices always indicate "before the beginning */ + idx = before; + } else { + /* Encoded end-positive (or end+negative) are offset */ + idx += TCL_INDEX_END; + } + + /* TODO: Consider flag to suppress repeated end-offset parse. */ + } else if (TCL_OK == TclGetIntForIndexM(interp, objPtr, 0, &idx)) { + /* + * Only reach this case when the index value is a + * constant index arithmetic expression, and idx + * holds the result. Treat it the same as if it were + * parsed as an absolute integer value. + */ + goto integerEncode; + } else { + return TCL_ERROR; + } + *indexPtr = idx; + return TCL_OK; +} + +/* + *---------------------------------------------------------------------- + * + * TclIndexDecode -- + * + * Decodes a value previously encoded by TclIndexEncode. The argument + * endValue indicates what value of "end" should be used in the + * decoding. + * + * Results: + * The decoded index value. + * + *---------------------------------------------------------------------- + */ + +int +TclIndexDecode( + int encoded, /* Value to decode */ + int endValue) /* Meaning of "end" to use, > TCL_INDEX_END */ +{ + if (encoded <= TCL_INDEX_END) { + return (encoded - TCL_INDEX_END) + endValue; + } + return encoded; +} + +/* + *---------------------------------------------------------------------- + * * TclCheckBadOctal -- * * This function checks for a bad octal value and appends a meaningful -- cgit v0.12 From a9d546dfbc3ec1d105fe2a2a06fb202295e5301f Mon Sep 17 00:00:00 2001 From: dgp Date: Fri, 9 Mar 2018 19:40:01 +0000 Subject: Use new machinery to repair index value flaws in [lsort]. --- generic/tclCmdIL.c | 35 ++++++++++++++++++----------------- 1 file changed, 18 insertions(+), 17 deletions(-) diff --git a/generic/tclCmdIL.c b/generic/tclCmdIL.c index 7a13b71..3b2cb19 100644 --- a/generic/tclCmdIL.c +++ b/generic/tclCmdIL.c @@ -94,14 +94,6 @@ typedef struct SortInfo { #define SORTMODE_ASCII_NC 8 /* - * Magic values for the index field of the SortInfo structure. Note that the - * index "end-1" will be translated to SORTIDX_END-1, etc. - */ - -#define SORTIDX_NONE -1 /* Not indexed; use whole value. */ -#define SORTIDX_END -2 /* Indexed from end. */ - -/* * Forward declarations for procedures defined in this file: */ @@ -3746,7 +3738,7 @@ Tcl_LsortObjCmd( sortInfo.isIncreasing = 1; break; case LSORT_INDEX: { - int indexc, dummy; + int indexc; Tcl_Obj **indexv; if (i == objc-2) { @@ -3772,8 +3764,20 @@ Tcl_LsortObjCmd( */ for (j=0 ; j= groupSize) { Tcl_SetObjResult(interp, Tcl_NewStringObj( "when used with \"-stride\", the leading \"-index\"" -- cgit v0.12 From c13e34da3740d014ade6f5e1dadcae12e18e27ed Mon Sep 17 00:00:00 2001 From: dgp Date: Fri, 9 Mar 2018 20:34:33 +0000 Subject: Update the command compilers and bytecode execution engine to use new machinery. --- generic/tclAssembly.c | 4 +- generic/tclCompCmdsGR.c | 128 +++++++----------------------------------------- generic/tclCompCmdsSZ.c | 16 +++--- generic/tclCompile.h | 4 +- generic/tclExecute.c | 39 +++++---------- 5 files changed, 44 insertions(+), 147 deletions(-) diff --git a/generic/tclAssembly.c b/generic/tclAssembly.c index a3fac8f..608459e 100644 --- a/generic/tclAssembly.c +++ b/generic/tclAssembly.c @@ -2263,8 +2263,8 @@ GetListIndexOperand( * same result as indexing after it, and might be more easily portable * when list size limits grow. */ - status = TclGetIndexFromToken(tokenPtr, result, TCL_INDEX_BEFORE, - TCL_INDEX_BEFORE); + status = TclGetIndexFromToken(tokenPtr, TCL_INDEX_BEFORE, + TCL_INDEX_BEFORE, result); *tokenPtrPtr = TokenAfter(tokenPtr); if (status == TCL_ERROR && interp) { Tcl_SetObjResult(interp, Tcl_ObjPrintf("bad index \"%.*s\"", diff --git a/generic/tclCompCmdsGR.c b/generic/tclCompCmdsGR.c index e2ddb11..396947c 100644 --- a/generic/tclCompCmdsGR.c +++ b/generic/tclCompCmdsGR.c @@ -35,45 +35,7 @@ static int IndexTailVarIfKnown(Tcl_Interp *interp, * TclGetIndexFromToken -- * * Parse a token to determine if an index value is known at - * compile time. Two cases are possible. The compile time value - * of the token might be parsed as an absolute index value - * in the C signed int range. Note that this includes index - * values that are integers as presented as well as index - * arithmetic expressions that can be fully computed at compile - * time. The absolute index values that can be directly meaningful - * as an index into either a list or a string are those integer - * values >= TCL_INDEX_START (0) and < TCL_INDEX_AFTER (INT_MAX). - * The largest string supported in Tcl 8 has bytelength INT_MAX. - * This means the largest character supported length is also INT_MAX, - * and the index of the last character in a string of length INT_MAX - * is INT_MAX-1. - * - * Any absolute index value parsed outside that range is encoded - * using the minBoundary and maxBounday values passed in by the - * caller as the encoding to use for indices that are either - * less than or greater than the usable index range. TCL_INDEX_AFTER - * is available as a good choice for most callers to use for - * maxBoundary. Likewise, the value TCL_INDEX_BEFORE is good for - * most callers to use for minBoundary. Other values are possible - * when the caller knows it is helpful in producing its own behavior - * for indices before and after the indexed item. - * - * A token can also be parsed as an end-relative index expression. - * All end-relative expressions that indicate an index larger - * than end (end+2, end--5) point beyond the end of the indexed - * collection, and can be encoded as maxBoundary. The end-relative - * expressions that indicate an index less than or equal to end - * are encoded relative to the value TCL_INDEX_END (-2). The - * index "end" is encoded as -2, down to the index "end-0x7ffffffe" - * which is encoded as INT_MIN. Since the largest index into a - * string possible in Tcl 8 is 0x7ffffffe, the interpretation of - * "end-0x7ffffffe" for that largest string would be 0. Thus, - * if the tokens "end-0x7fffffff" or "end+-0x80000000" are parsed, - * they can be encoded with the minBoundary value. - * - * These details will require re-examination whenever string and - * list length limits are increased, but that will likely also - * mean a revised routine capable of returning Tcl_WideInt values. + * compile time. * * Returns: * TCL_OK if parsing succeeded, and TCL_ERROR if it failed. @@ -88,69 +50,17 @@ static int IndexTailVarIfKnown(Tcl_Interp *interp, int TclGetIndexFromToken( Tcl_Token *tokenPtr, - int *index, - int minBoundary, - int maxBoundary) + int before, + int after, + int *indexPtr) { Tcl_Obj *tmpObj = Tcl_NewObj(); - int result, idx; + int result = TCL_ERROR; - if (!TclWordKnownAtCompileTime(tokenPtr, tmpObj)) { - Tcl_DecrRefCount(tmpObj); - return TCL_ERROR; - } - - result = TclGetIntFromObj(NULL, tmpObj, &idx); - if (result == TCL_OK) { - /* We parsed a value in the range INT_MIN...INT_MAX */ - integerEncode: - if (idx < TCL_INDEX_START) { - /* All negative absolute indices are "before the beginning" */ - idx = minBoundary; - } else if (idx == INT_MAX) { - /* This index value is always "after the end" */ - idx = maxBoundary; - } - /* usual case, the absolute index value encodes itself */ - } else { - result = TclGetEndOffsetFromObj(NULL, tmpObj, 0, &idx); - if (result == TCL_OK) { - /* - * We parsed an end+offset index value. - * idx holds the offset value in the range INT_MIN...INT_MAX. - */ - if (idx > 0) { - /* - * All end+postive or end-negative expressions - * always indicate "after the end". - */ - idx = maxBoundary; - } else if (idx < INT_MIN - TCL_INDEX_END) { - /* These indices always indicate "before the beginning */ - idx = minBoundary; - } else { - /* Encoded end-positive (or end+negative) are offset */ - idx += TCL_INDEX_END; - } - } else { - result = TclGetIntForIndexM(NULL, tmpObj, 0, &idx); - if (result == TCL_OK) { - /* - * Only reach this case when the index value is a - * constant index arithmetic expression, and idx - * holds the result. Treat it the same as if it were - * parsed as an absolute integer value. - */ - goto integerEncode; - } - } + if (TclWordKnownAtCompileTime(tokenPtr, tmpObj)) { + result = TclIndexEncode(NULL, tmpObj, before, after, indexPtr); } Tcl_DecrRefCount(tmpObj); - - if (result == TCL_OK) { - *index = idx; - } - return result; } @@ -1177,8 +1087,8 @@ TclCompileLindexCmd( } idxTokenPtr = TokenAfter(valTokenPtr); - if (TclGetIndexFromToken(idxTokenPtr, &idx, TCL_INDEX_BEFORE, - TCL_INDEX_BEFORE) == TCL_OK) { + if (TclGetIndexFromToken(idxTokenPtr, TCL_INDEX_BEFORE, TCL_INDEX_BEFORE, + &idx) == TCL_OK) { /* * The idxTokenPtr parsed as a valid index value and was * encoded as expected by INST_LIST_INDEX_IMM. @@ -1406,8 +1316,8 @@ TclCompileLrangeCmd( listTokenPtr = TokenAfter(parsePtr->tokenPtr); tokenPtr = TokenAfter(listTokenPtr); - if (TclGetIndexFromToken(tokenPtr, &idx1, TCL_INDEX_START, - TCL_INDEX_AFTER) != TCL_OK) { + if (TclGetIndexFromToken(tokenPtr, TCL_INDEX_START, TCL_INDEX_AFTER, + &idx1) != TCL_OK) { return TCL_ERROR; } /* @@ -1416,8 +1326,8 @@ TclCompileLrangeCmd( */ tokenPtr = TokenAfter(tokenPtr); - if (TclGetIndexFromToken(tokenPtr, &idx2, TCL_INDEX_BEFORE, - TCL_INDEX_END) != TCL_OK) { + if (TclGetIndexFromToken(tokenPtr, TCL_INDEX_BEFORE, TCL_INDEX_END, + &idx2) != TCL_OK) { return TCL_ERROR; } /* @@ -1481,8 +1391,8 @@ TclCompileLinsertCmd( * make that transformation here so we can use the optimized bytecode * as much as possible. */ - if (TclGetIndexFromToken(tokenPtr, &idx, TCL_INDEX_START, - TCL_INDEX_END) != TCL_OK) { + if (TclGetIndexFromToken(tokenPtr, TCL_INDEX_START, TCL_INDEX_END, + &idx) != TCL_OK) { return TCL_ERROR; } @@ -1571,14 +1481,14 @@ TclCompileLreplaceCmd( listTokenPtr = TokenAfter(parsePtr->tokenPtr); tokenPtr = TokenAfter(listTokenPtr); - if (TclGetIndexFromToken(tokenPtr, &idx1, TCL_INDEX_START, - TCL_INDEX_AFTER) != TCL_OK) { + if (TclGetIndexFromToken(tokenPtr, TCL_INDEX_START, TCL_INDEX_AFTER, + &idx1) != TCL_OK) { return TCL_ERROR; } tokenPtr = TokenAfter(tokenPtr); - if (TclGetIndexFromToken(tokenPtr, &idx2, TCL_INDEX_BEFORE, - TCL_INDEX_END) != TCL_OK) { + if (TclGetIndexFromToken(tokenPtr, TCL_INDEX_BEFORE, TCL_INDEX_END, + &idx2) != TCL_OK) { return TCL_ERROR; } diff --git a/generic/tclCompCmdsSZ.c b/generic/tclCompCmdsSZ.c index f98d375..5cd1c3b 100644 --- a/generic/tclCompCmdsSZ.c +++ b/generic/tclCompCmdsSZ.c @@ -937,8 +937,8 @@ TclCompileStringRangeCmd( * Parse the two indices. */ - if (TclGetIndexFromToken(fromTokenPtr, &idx1, TCL_INDEX_START, - TCL_INDEX_AFTER) != TCL_OK) { + if (TclGetIndexFromToken(fromTokenPtr, TCL_INDEX_START, TCL_INDEX_AFTER, + &idx1) != TCL_OK) { goto nonConstantIndices; } /* @@ -953,8 +953,8 @@ TclCompileStringRangeCmd( return TCL_OK; } - if (TclGetIndexFromToken(toTokenPtr, &idx2, TCL_INDEX_BEFORE, - TCL_INDEX_END) != TCL_OK) { + if (TclGetIndexFromToken(toTokenPtr, TCL_INDEX_BEFORE, TCL_INDEX_END, + &idx2) != TCL_OK) { goto nonConstantIndices; } /* @@ -1010,8 +1010,8 @@ TclCompileStringReplaceCmd( } tokenPtr = TokenAfter(valueTokenPtr); - if (TclGetIndexFromToken(tokenPtr, &idx1, TCL_INDEX_START, - TCL_INDEX_AFTER) != TCL_OK) { + if (TclGetIndexFromToken(tokenPtr, TCL_INDEX_START, TCL_INDEX_AFTER, + &idx1) != TCL_OK) { goto genericReplace; } /* @@ -1020,8 +1020,8 @@ TclCompileStringReplaceCmd( */ tokenPtr = TokenAfter(tokenPtr); - if (TclGetIndexFromToken(tokenPtr, &idx2, TCL_INDEX_BEFORE, - TCL_INDEX_END) != TCL_OK) { + if (TclGetIndexFromToken(tokenPtr, TCL_INDEX_BEFORE, TCL_INDEX_END, + &idx2) != TCL_OK) { goto genericReplace; } /* diff --git a/generic/tclCompile.h b/generic/tclCompile.h index d842fdd..6aaa855 100644 --- a/generic/tclCompile.h +++ b/generic/tclCompile.h @@ -1121,8 +1121,8 @@ MODULE_SCOPE int TclFixupForwardJump(CompileEnv *envPtr, int distThreshold); MODULE_SCOPE void TclFreeCompileEnv(CompileEnv *envPtr); MODULE_SCOPE void TclFreeJumpFixupArray(JumpFixupArray *fixupArrayPtr); -MODULE_SCOPE int TclGetIndexFromToken(Tcl_Token *tokenPtr, int *index, - int minBoundary, int maxBoundary); +MODULE_SCOPE int TclGetIndexFromToken(Tcl_Token *tokenPtr, + int before, int after, int *indexPtr); MODULE_SCOPE void TclInitByteCodeObj(Tcl_Obj *objPtr, CompileEnv *envPtr); MODULE_SCOPE void TclInitCompileEnv(Tcl_Interp *interp, diff --git a/generic/tclExecute.c b/generic/tclExecute.c index 7043179..188eadc 100644 --- a/generic/tclExecute.c +++ b/generic/tclExecute.c @@ -5093,9 +5093,7 @@ TEBCresume( * Decode end-offset index values. */ - if (index <= TCL_INDEX_END) { - index += (objc - 1 - TCL_INDEX_END); - } + index = TclIndexDecode(index, objc - 1); pcAdjustment = 5; lindexFastPath: @@ -5250,11 +5248,9 @@ TEBCresume( if ((toIdx == TCL_INDEX_BEFORE) || (fromIdx == TCL_INDEX_AFTER)) { goto emptyList; } - if (toIdx <= TCL_INDEX_END) { - toIdx += (objc - 1 - TCL_INDEX_END); - if (toIdx < 0) { - goto emptyList; - } + toIdx = TclIndexDecode(toIdx, objc - 1); + if (toIdx < 0) { + goto emptyList; } else if (toIdx >= objc) { toIdx = objc - 1; } @@ -5263,13 +5259,10 @@ TEBCresume( assert ( fromIdx != TCL_INDEX_BEFORE ); assert ( fromIdx != TCL_INDEX_AFTER); - if (fromIdx <= TCL_INDEX_END) { - fromIdx += (objc - 1 - TCL_INDEX_END); - if (fromIdx < 0) { - fromIdx = 0; - } + fromIdx = TclIndexDecode(fromIdx, objc - 1); + if (fromIdx < 0) { + fromIdx = 0; } - assert ( fromIdx >= 0 ); if (fromIdx <= toIdx) { /* Construct the subsquence list */ @@ -5643,11 +5636,9 @@ TEBCresume( assert ( toIdx != TCL_INDEX_BEFORE ); assert ( toIdx != TCL_INDEX_AFTER); - if (toIdx <= TCL_INDEX_END) { - toIdx += (length - 1 - TCL_INDEX_END); - if (toIdx < 0) { - goto emptyRange; - } + toIdx = TclIndexDecode(toIdx, length - 1); + if (toIdx < 0) { + goto emptyRange; } else if (toIdx >= length) { toIdx = length - 1; } @@ -5657,15 +5648,11 @@ TEBCresume( assert ( fromIdx != TCL_INDEX_BEFORE ); assert ( fromIdx != TCL_INDEX_AFTER); - if (fromIdx <= TCL_INDEX_END) { - fromIdx += (length - 1 - TCL_INDEX_END); - if (fromIdx < 0) { - fromIdx = 0; - } + fromIdx = TclIndexDecode(fromIdx, length - 1); + if (fromIdx < 0) { + fromIdx = 0; } - assert ( fromIdx >= 0 ); - if (fromIdx <= toIdx) { objResultPtr = Tcl_GetRange(valuePtr, fromIdx, toIdx); } else { -- cgit v0.12 From 06c3fd0c5be39e8d5407848be217194519845a43 Mon Sep 17 00:00:00 2001 From: dgp Date: Fri, 9 Mar 2018 20:46:54 +0000 Subject: Newer utility routine is more suitable. --- generic/tclAssembly.c | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-) diff --git a/generic/tclAssembly.c b/generic/tclAssembly.c index 608459e..b6bebb6 100644 --- a/generic/tclAssembly.c +++ b/generic/tclAssembly.c @@ -2255,7 +2255,6 @@ GetListIndexOperand( if (GetNextOperand(assemEnvPtr, tokenPtrPtr, &value) != TCL_OK) { return TCL_ERROR; } - Tcl_DecrRefCount(value); /* Convert to an integer, advance to the next token and return. */ /* @@ -2263,14 +2262,11 @@ GetListIndexOperand( * same result as indexing after it, and might be more easily portable * when list size limits grow. */ - status = TclGetIndexFromToken(tokenPtr, TCL_INDEX_BEFORE, - TCL_INDEX_BEFORE, result); + status = TclIndexEncode(interp, value, + TCL_INDEX_BEFORE,TCL_INDEX_BEFORE, result); + + Tcl_DecrRefCount(value); *tokenPtrPtr = TokenAfter(tokenPtr); - if (status == TCL_ERROR && interp) { - Tcl_SetObjResult(interp, Tcl_ObjPrintf("bad index \"%.*s\"", - tokenPtr->size, tokenPtr->start)); - Tcl_SetErrorCode(interp, "TCL", "ASSEM", "BADINDEX", NULL); - } return status; } -- cgit v0.12 From 954522812e2e6644f38fa1ee44ce949a6c83a9d1 Mon Sep 17 00:00:00 2001 From: dgp Date: Fri, 9 Mar 2018 21:07:12 +0000 Subject: Return routine to file scope. --- generic/tclInt.h | 2 -- generic/tclUtil.c | 12 +++++++----- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/generic/tclInt.h b/generic/tclInt.h index 3821e42..ef48126 100644 --- a/generic/tclInt.h +++ b/generic/tclInt.h @@ -2978,8 +2978,6 @@ MODULE_SCOPE int TclGetChannelFromObj(Tcl_Interp *interp, MODULE_SCOPE CmdFrame * TclGetCmdFrameForProcedure(Proc *procPtr); MODULE_SCOPE int TclGetCompletionCodeFromObj(Tcl_Interp *interp, Tcl_Obj *value, int *code); -MODULE_SCOPE int TclGetEndOffsetFromObj(Tcl_Interp *interp, - Tcl_Obj *objPtr, int endValue, int *indexPtr); MODULE_SCOPE int TclGetNumberFromObj(Tcl_Interp *interp, Tcl_Obj *objPtr, ClientData *clientDataPtr, int *typePtr); diff --git a/generic/tclUtil.c b/generic/tclUtil.c index f6a92fc..768b2f5 100644 --- a/generic/tclUtil.c +++ b/generic/tclUtil.c @@ -107,6 +107,8 @@ static Tcl_ThreadDataKey precisionKey; static void ClearHash(Tcl_HashTable *tablePtr); static void FreeProcessGlobalValue(ClientData clientData); static void FreeThreadHash(ClientData clientData); +static int GetEndOffsetFromObj(Tcl_Interp *interp, + Tcl_Obj *objPtr, int endValue, int *indexPtr); static Tcl_HashTable * GetThreadHash(Tcl_ThreadDataKey *keyPtr); static int SetEndOffsetFromAny(Tcl_Interp *interp, Tcl_Obj *objPtr); @@ -3575,7 +3577,7 @@ TclGetIntForIndex( return TCL_OK; } - if (TclGetEndOffsetFromObj(NULL, objPtr, endValue, indexPtr) == TCL_OK) { + if (GetEndOffsetFromObj(NULL, objPtr, endValue, indexPtr) == TCL_OK) { return TCL_OK; } @@ -3678,7 +3680,7 @@ UpdateStringOfEndOffset( /* *---------------------------------------------------------------------- * - * TclGetEndOffsetFromObj -- + * GetEndOffsetFromObj -- * * Look for a string of the form "end[+-]offset" and convert it to an * internal representation holding the offset. @@ -3692,8 +3694,8 @@ UpdateStringOfEndOffset( *---------------------------------------------------------------------- */ -int -TclGetEndOffsetFromObj( +static int +GetEndOffsetFromObj( Tcl_Interp *interp, /* For error reporting, may be NULL. */ Tcl_Obj *objPtr, /* Pointer to the object to parse */ int endValue, /* The value to be stored at "indexPtr" if @@ -3886,7 +3888,7 @@ TclIndexEncode( idx = after; } /* usual case, the absolute index value encodes itself */ - } else if (TCL_OK == TclGetEndOffsetFromObj(NULL, objPtr, 0, &idx)) { + } else if (TCL_OK == GetEndOffsetFromObj(NULL, objPtr, 0, &idx)) { /* * We parsed an end+offset index value. * idx holds the offset value in the range INT_MIN...INT_MAX. -- cgit v0.12 From cd4e0ec5deffef9dbc4331768ca660fef4590501 Mon Sep 17 00:00:00 2001 From: dgp Date: Fri, 9 Mar 2018 21:18:19 +0000 Subject: Restore safety for legacy bytecode. --- generic/tclExecute.c | 35 ++++++++++++++++++++++++++++++++++- 1 file changed, 34 insertions(+), 1 deletion(-) diff --git a/generic/tclExecute.c b/generic/tclExecute.c index 5d29db9..151a899 100644 --- a/generic/tclExecute.c +++ b/generic/tclExecute.c @@ -5241,7 +5241,14 @@ TEBCresume( /* Decode index value operands. */ + /* assert ( toIdx != TCL_INDEX_AFTER); + * + * Extra safety for legacy bytecodes: + */ + if (toIdx == TCL_INDEX_AFTER) { + toIdx = TCL_INDEX_END; + } if ((toIdx == TCL_INDEX_BEFORE) || (fromIdx == TCL_INDEX_AFTER)) { goto emptyList; @@ -5254,8 +5261,14 @@ TEBCresume( } assert ( toIdx >= 0 && toIdx < objc); + /* assert ( fromIdx != TCL_INDEX_BEFORE ); - assert ( fromIdx != TCL_INDEX_AFTER); + * + * Extra safety for legacy bytecodes: + */ + if (fromIdx == TCL_INDEX_BEFORE) { + fromIdx = TCL_INDEX_START; + } fromIdx = TclIndexDecode(fromIdx, objc - 1); if (fromIdx < 0) { @@ -5631,8 +5644,18 @@ TEBCresume( /* Decode index operands. */ + /* assert ( toIdx != TCL_INDEX_BEFORE ); assert ( toIdx != TCL_INDEX_AFTER); + * + * Extra safety for legacy bytecodes: + */ + if (toIdx == TCL_INDEX_BEFORE) { + goto emptyRange; + } + if (toIdx == TCL_INDEX_AFTER) { + toIdx = TCL_INDEX_END; + } toIdx = TclIndexDecode(toIdx, length - 1); if (toIdx < 0) { @@ -5643,8 +5666,18 @@ TEBCresume( assert ( toIdx >= 0 && toIdx < length ); + /* assert ( fromIdx != TCL_INDEX_BEFORE ); assert ( fromIdx != TCL_INDEX_AFTER); + * + * Extra safety for legacy bytecodes: + */ + if (fromIdx == TCL_INDEX_BEFORE) { + fromIdx = TCL_INDEX_START; + } + if (fromIdx == TCL_INDEX_AFTER) { + goto emptyRange; + } fromIdx = TclIndexDecode(fromIdx, length - 1); if (fromIdx < 0) { -- cgit v0.12 From 6fce39545c66c1b7d03c888c57dfab064288444f Mon Sep 17 00:00:00 2001 From: dgp Date: Sat, 10 Mar 2018 14:37:36 +0000 Subject: rename tests to make room for new tests in 8.7 --- tests/cmdIL.test | 4 ++-- tests/lsearch.test | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/tests/cmdIL.test b/tests/cmdIL.test index c83bd98..68122dd 100644 --- a/tests/cmdIL.test +++ b/tests/cmdIL.test @@ -147,10 +147,10 @@ test cmdIL-1.36 {lsort -stride and -index: Bug 2918962} { {{b i g} 12345} {{d e m o} 34512} } } {{{b i g} 12345} {{d e m o} 34512} {{c o d e} 54321} {{b l a h} 94729}} -test cmdIL-1.37 {lsort -stride and -index} -body { +test cmdIL-1.41 {lsort -stride and -index} -body { lsort -stride 2 -index -2 {a 2 b 1} } -returnCodes error -result {index "-2" cannot select an element from any list} -test cmdIL-1.38 {lsort -stride and-index} -body { +test cmdIL-1.42 {lsort -stride and-index} -body { lsort -stride 2 -index -1-1 {a 2 b 1} } -returnCodes error -result {index "-1-1" cannot select an element from any list} diff --git a/tests/lsearch.test b/tests/lsearch.test index d7f9414..5e8a1f8 100644 --- a/tests/lsearch.test +++ b/tests/lsearch.test @@ -478,10 +478,10 @@ test lsearch-19.4 {lsearch -subindices option} { test lsearch-19.5 {lsearch -subindices option} { lsearch -subindices -all -index {0 0} -exact {{{a c} {a b} {d a}} {{a c} {a b} {d a}}} a } {{0 0 0} {1 0 0}} -test lsearch-19.6 {lsearch -subindices option} { +test lsearch-19.7 {lsearch -subindices option} { lsearch -subindices -index end {{1 a}} a } {0 1} -test lsearch-19.7 {lsearch -subindices option} { +test lsearch-19.8 {lsearch -subindices option} { lsearch -subindices -all -index end {{1 a}} a } {{0 1}} -- cgit v0.12 From e7a86d967ca214c536410f0d3c4b35fcf675fbc0 Mon Sep 17 00:00:00 2001 From: dgp Date: Sat, 10 Mar 2018 14:44:05 +0000 Subject: Use LIST_MAX instead of computing an end index. --- generic/tclExecute.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/generic/tclExecute.c b/generic/tclExecute.c index 151a899..839f6f4 100644 --- a/generic/tclExecute.c +++ b/generic/tclExecute.c @@ -5282,8 +5282,8 @@ TEBCresume( objResultPtr = Tcl_NewListObj(toIdx-fromIdx+1, objv+fromIdx); } else { if (toIdx != objc - 1) { - Tcl_ListObjReplace(NULL, valuePtr, toIdx + 1, - objc - 1 - toIdx, 0, NULL); + Tcl_ListObjReplace(NULL, valuePtr, toIdx + 1, LIST_MAX, + 0, NULL); } Tcl_ListObjReplace(NULL, valuePtr, 0, fromIdx, 0, NULL); TRACE_APPEND(("%.30s\n", O2S(valuePtr))); -- cgit v0.12 From d9dbcf5afb7f7261b5928092e17307280d737106 Mon Sep 17 00:00:00 2001 From: dgp Date: Sat, 10 Mar 2018 15:41:04 +0000 Subject: Remove unused argument. --- generic/tclUtil.c | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/generic/tclUtil.c b/generic/tclUtil.c index 768b2f5..2bd6b51 100644 --- a/generic/tclUtil.c +++ b/generic/tclUtil.c @@ -107,8 +107,8 @@ static Tcl_ThreadDataKey precisionKey; static void ClearHash(Tcl_HashTable *tablePtr); static void FreeProcessGlobalValue(ClientData clientData); static void FreeThreadHash(ClientData clientData); -static int GetEndOffsetFromObj(Tcl_Interp *interp, - Tcl_Obj *objPtr, int endValue, int *indexPtr); +static int GetEndOffsetFromObj(Tcl_Obj *objPtr, int endValue, + int *indexPtr); static Tcl_HashTable * GetThreadHash(Tcl_ThreadDataKey *keyPtr); static int SetEndOffsetFromAny(Tcl_Interp *interp, Tcl_Obj *objPtr); @@ -3577,7 +3577,7 @@ TclGetIntForIndex( return TCL_OK; } - if (GetEndOffsetFromObj(NULL, objPtr, endValue, indexPtr) == TCL_OK) { + if (GetEndOffsetFromObj(objPtr, endValue, indexPtr) == TCL_OK) { return TCL_OK; } @@ -3696,14 +3696,13 @@ UpdateStringOfEndOffset( static int GetEndOffsetFromObj( - Tcl_Interp *interp, /* For error reporting, may be NULL. */ Tcl_Obj *objPtr, /* Pointer to the object to parse */ int endValue, /* The value to be stored at "indexPtr" if * "objPtr" holds "end". */ int *indexPtr) /* Location filled in with an integer * representing an index. */ { - if (SetEndOffsetFromAny(interp, objPtr) != TCL_OK) { + if (SetEndOffsetFromAny(NULL, objPtr) != TCL_OK) { return TCL_ERROR; } @@ -3888,7 +3887,7 @@ TclIndexEncode( idx = after; } /* usual case, the absolute index value encodes itself */ - } else if (TCL_OK == GetEndOffsetFromObj(NULL, objPtr, 0, &idx)) { + } else if (TCL_OK == GetEndOffsetFromObj(objPtr, 0, &idx)) { /* * We parsed an end+offset index value. * idx holds the offset value in the range INT_MIN...INT_MAX. -- cgit v0.12 From 3f3c89a94712629db5dd879be46ee097e61b4944 Mon Sep 17 00:00:00 2001 From: dgp Date: Sun, 11 Mar 2018 12:13:11 +0000 Subject: Screen out empty list value so that assertions are true. --- generic/tclExecute.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/generic/tclExecute.c b/generic/tclExecute.c index 839f6f4..ef64ac1 100644 --- a/generic/tclExecute.c +++ b/generic/tclExecute.c @@ -5239,6 +5239,12 @@ TEBCresume( } #endif + /* Every range of an empty list is an empty list */ + if (objc == 0) { + TRACE_APPEND(("\n")); + NEXT_INST_F(9, 0, 0); + } + /* Decode index value operands. */ /* -- cgit v0.12 From a0374a6e61102ea76e2df357b648e1530508a973 Mon Sep 17 00:00:00 2001 From: dgp Date: Sun, 11 Mar 2018 12:14:05 +0000 Subject: plug memleak of constructed package requirement. --- generic/tclPkg.c | 1 - 1 file changed, 1 deletion(-) diff --git a/generic/tclPkg.c b/generic/tclPkg.c index e956a40..d4080c2 100644 --- a/generic/tclPkg.c +++ b/generic/tclPkg.c @@ -1125,7 +1125,6 @@ TclNRPackageObjCmd( */ ov = Tcl_NewStringObj(version, -1); - Tcl_IncrRefCount(ov); Tcl_AppendStringsToObj(ov, "-", version, NULL); version = NULL; argv3 = TclGetString(objv[3]); -- cgit v0.12 From cd39f34fa58e57741ef315b5f9587783ea6331a3 Mon Sep 17 00:00:00 2001 From: dgp Date: Sun, 11 Mar 2018 18:08:00 +0000 Subject: Attempt at providing the missing instance squelcher. --- generic/tclOO.c | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/generic/tclOO.c b/generic/tclOO.c index c6ea91d..556ad80 100644 --- a/generic/tclOO.c +++ b/generic/tclOO.c @@ -934,10 +934,26 @@ ReleaseClassContents( TclDecrRefCount(filterObj); } ckfree(clsPtr->filters.list); + clsPtr->filters.list = NULL; clsPtr->filters.num = 0; } /* + * Squelch our instances. + */ + + if (clsPtr->instances.num) { + Object *oPtr; + + FOREACH(oPtr, clsPtr->instances) { + TclOODecrRefCount(oPtr); + } + ckfree(clsPtr->instances.list); + clsPtr->instances.list = NULL; + clsPtr->instances.num = 0; + } + + /* * Squelch our metadata. */ -- cgit v0.12 From e7a5b8aaa5817974ac8a090530f79af42ea60544 Mon Sep 17 00:00:00 2001 From: dgp Date: Sun, 11 Mar 2018 21:14:41 +0000 Subject: Prevent leaks of the Object structs of oo::object and oo::class. --- generic/tclOO.c | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/generic/tclOO.c b/generic/tclOO.c index 556ad80..587e46d 100644 --- a/generic/tclOO.c +++ b/generic/tclOO.c @@ -552,6 +552,15 @@ KillFoundation( { Foundation *fPtr = GetFoundation(interp); + /* + * Crude mechanism to avoid leaking the Object struct of the + * foundation components oo::object and oo::class + * + * Should probably be replaced with something more elegantly designed. + */ + while (TclOODecrRefCount(fPtr->objectCls->thisPtr) == 0) {}; + while (TclOODecrRefCount(fPtr->classCls->thisPtr) == 0) {}; + TclDecrRefCount(fPtr->unknownMethodNameObj); TclDecrRefCount(fPtr->constructorName); TclDecrRefCount(fPtr->destructorName); -- cgit v0.12 From a28f176470d4f9c36163a55a0ecee4bd8d08dc3d Mon Sep 17 00:00:00 2001 From: dgp Date: Mon, 12 Mar 2018 02:48:59 +0000 Subject: It is confusingly stupid to use variable "length" to hold an actual length in part of a routine, and hold an end index value later. --- generic/tclCmdMZ.c | 35 ++++++++++++++++++++++++----------- 1 file changed, 24 insertions(+), 11 deletions(-) diff --git a/generic/tclCmdMZ.c b/generic/tclCmdMZ.c index d63a985..92f247a 100644 --- a/generic/tclCmdMZ.c +++ b/generic/tclCmdMZ.c @@ -2352,29 +2352,42 @@ StringRplcCmd( int objc, /* Number of arguments. */ Tcl_Obj *const objv[]) /* Argument objects. */ { - Tcl_UniChar *ustring; - int first, last, length; + int first, last, length, end; if (objc < 4 || objc > 5) { Tcl_WrongNumArgs(interp, 1, objv, "string first last ?string?"); return TCL_ERROR; } - ustring = Tcl_GetUnicodeFromObj(objv[1], &length); - length--; + (void) Tcl_GetUnicodeFromObj(objv[1], &length); + end = length - 1; - if (TclGetIntForIndexM(interp, objv[2], length, &first) != TCL_OK || - TclGetIntForIndexM(interp, objv[3], length, &last) != TCL_OK){ + if (TclGetIntForIndexM(interp, objv[2], end, &first) != TCL_OK || + TclGetIntForIndexM(interp, objv[3], end, &last) != TCL_OK){ return TCL_ERROR; } - if ((last < first) || (last < 0) || (first > length)) { + /* + * [string replace] does not replace empty strings. This is + * unwise, but since it is true, here we quickly screen out + * index pairs that demarcate an empty substring. + */ + + if ((last < 0) || /* Range ends before start of string */ + (first > end) || /* Range begins after end of string */ + (last < first)) { /* Range begins after it starts */ Tcl_SetObjResult(interp, objv[1]); } else { Tcl_Obj *resultPtr; - ustring = Tcl_GetUnicodeFromObj(objv[1], &length); - length--; + /* + * We are re-fetching in case the string argument is same value as + * an index argument, and shimmering cost us our ustring. + */ + + Tcl_UniChar *ustring = Tcl_GetUnicodeFromObj(objv[1], &length); + + end = length - 1; if (first < 0) { first = 0; @@ -2384,9 +2397,9 @@ StringRplcCmd( if (objc == 5) { Tcl_AppendObjToObj(resultPtr, objv[4]); } - if (last < length) { + if (last < end) { Tcl_AppendUnicodeToObj(resultPtr, ustring + last + 1, - length - last); + end - last); } Tcl_SetObjResult(interp, resultPtr); } -- cgit v0.12 From 861217dbe37cbfd71b8cf906c7b32d3ec4f04b2a Mon Sep 17 00:00:00 2001 From: dgp Date: Mon, 12 Mar 2018 13:07:50 +0000 Subject: Convert DOS -> unix line endings. --- win/makefile.vc | 2516 +++++++++++++++++++++++++++---------------------------- 1 file changed, 1258 insertions(+), 1258 deletions(-) diff --git a/win/makefile.vc b/win/makefile.vc index d647fa3..ad33ade 100644 --- a/win/makefile.vc +++ b/win/makefile.vc @@ -1,1258 +1,1258 @@ -#------------------------------------------------------------- -# makefile.vc -- -# -# Microsoft Visual C++ makefile for use with nmake.exe v1.62+ (VC++ 5.0+) -# -# See the file "license.terms" for information on usage and redistribution -# of this file, and for a DISCLAIMER OF ALL WARRANTIES. -# -# Copyright (c) 1995-1996 Sun Microsystems, Inc. -# Copyright (c) 1998-2000 Ajuba Solutions. -# Copyright (c) 2001-2005 ActiveState Corporation. -# Copyright (c) 2001-2004 David Gravereaux. -# Copyright (c) 2003-2008 Pat Thoyts. -#------------------------------------------------------------------------------ - -# Check to see we are configured to build with MSVC (MSDEVDIR, MSVCDIR or -# VCINSTALLDIR) or with the MS Platform SDK (MSSDK or WindowsSDKDir) -!if !defined(MSDEVDIR) && !defined(MSVCDIR) && !defined(VCINSTALLDIR) && !defined(MSSDK) && !defined(WINDOWSSDKDIR) -MSG = ^ -You need to run vcvars32.bat from Developer Studio or setenv.bat from the^ -Platform SDK first to setup the environment. Jump to this line to read^ -the build instructions. -!error $(MSG) -!endif - -#------------------------------------------------------------------------------ -# HOW TO USE this makefile: -# -# 1) It is now necessary to have MSVCDir, MSDevDir or MSSDK set in the -# environment. This is used as a check to see if vcvars32.bat had been -# run prior to running nmake or during the installation of Microsoft -# Visual C++, MSVCDir had been set globally and the PATH adjusted. -# Either way is valid. -# -# You'll need to run vcvars32.bat contained in the MsDev's vc(98)/bin -# directory to setup the proper environment, if needed, for your -# current setup. This is a needed bootstrap requirement and allows the -# swapping of different environments to be easier. -# -# 2) To use the Platform SDK (not expressly needed), run setenv.bat after -# vcvars32.bat according to the instructions for it. This can also -# turn on the 64-bit compiler, if your SDK has it. -# -# 3) Targets are: -# release -- Builds the core, the shell and the dlls. (default) -# dlls -- Just builds the windows extensions -# shell -- Just builds the shell and the core. -# core -- Only builds the core [tclXX.(dll|lib)]. -# all -- Builds everything. -# test -- Builds and runs the test suite. -# tcltest -- Just builds the test shell. -# install -- Installs the built binaries and libraries to $(INSTALLDIR) -# as the root of the install tree. -# tidy/clean/hose -- varying levels of cleaning. -# genstubs -- Rebuilds the Stubs table and support files (dev only). -# depend -- Generates an accurate set of source dependancies for this -# makefile. Helpful to avoid problems when the sources are -# refreshed and you rebuild, but can "overbuild" when common -# headers like tclInt.h just get small changes. -# htmlhelp -- Builds a Windows .chm help file for Tcl and Tk from the -# troff manual pages found in $(ROOT)\doc. You need to -# have installed the HTML Help Compiler package from Microsoft -# to produce the .chm file. -# winhelp -- (deprecated) Builds the windows .hlp file for Tcl from -# the troff man files found in $(ROOT)\doc. This type of -# help file is deprecated by Microsoft in favour of html -# help files (.chm) -# -# 4) Macros usable on the commandline: -# INSTALLDIR= -# Sets where to install Tcl from the built binaries. -# C:\Progra~1\Tcl is assumed when not specified. -# -# OPTS=loimpact,msvcrt,nothreads,pdbs,profile,static,staticpkg,symbols,thrdalloc,tclalloc,unchecked,none -# Sets special options for the core. The default is for none. -# Any combination of the above may be used (comma separated). -# 'none' will over-ride everything to nothing. -# -# loimpact = Adds a flag for how NT treats the heap to keep memory -# in use, low. This is said to impact alloc performance. -# msvcrt = Affects the static option only to switch it from -# using libcmt(d) as the C runtime [by default] to -# msvcrt(d). This is useful for static embedding -# support. -# nothreads= Turns off full multithreading support. -# pdbs = Build detached symbols for release builds. -# profile = Adds profiling hooks. Map file is assumed. -# static = Builds a static library of the core instead of a -# dll. The static library will contain the dde and reg -# extensions. External applications who want to use -# this, need to link with the stub library as well as -# the static Tcl library.The shell will be static (and -# large), as well. -# staticpkg = Affects the static option only to switch -# tclshXX.exe to have the dde and reg extension linked -# inside it. -# symbols = Debug build. Links to the debug C runtime, disables -# optimizations and creates pdb symbols files. -# thrdalloc = Use the thread allocator (shared global free pool) -# This is the default on threaded builds. -# tclalloc = Use the old non-thread allocator -# unchecked= Allows a symbols build to not use the debug -# enabled runtime (msvcrt.dll not msvcrtd.dll -# or libcmt.lib not libcmtd.lib). -# -# STATS=compdbg,memdbg,none -# Sets optional memory and bytecode compiler debugging code added -# to the core. The default is for none. Any combination of the -# above may be used (comma separated). 'none' will over-ride -# everything to nothing. -# -# compdbg = Enables byte compilation logging. -# memdbg = Enables the debugging memory allocator. -# -# CHECKS=64bit,fullwarn,nodep,none -# Sets special macros for checking compatibility. -# -# 64bit = Enable 64bit portability warnings (if available) -# fullwarn = Builds with full compiler and link warnings enabled. -# Very verbose. -# nodep = Turns off compatibility macros to ensure the core -# isn't being built with deprecated functions. -# -# MACHINE=(ARM|AMD64|IA64|IX86) -# Set the machine type used for the compiler, linker, and -# resource compiler. This hook is needed to tell the tools -# when alternate platforms are requested. IX86 is the default -# when not specified. If the CPU environment variable has been -# set (ie: recent Platform SDK) then MACHINE is set from CPU. -# -# TMP_DIR= -# OUT_DIR= -# Hooks to allow the intermediate and output directories to be -# changed. $(OUT_DIR) is assumed to be -# $(BINROOT)\(Release|Debug) based on if symbols are requested. -# $(TMP_DIR) will de $(OUT_DIR)\ by default. -# -# TESTPAT= -# Reads the tests requested to be run from this file. -# -# CFG_ENCODING=encoding -# name of encoding for configuration information. Defaults -# to cp1252 -# -# 5) Examples: -# -# Basic syntax of calling nmake looks like this: -# nmake [-nologo] -f makefile.vc [target|macrodef [target|macrodef] [...]] -# -# Standard (no frills) -# c:\tcl_src\win\>c:\progra~1\micros~1\vc98\bin\vcvars32.bat -# Setting environment for using Microsoft Visual C++ tools. -# c:\tcl_src\win\>nmake -f makefile.vc release -# c:\tcl_src\win\>nmake -f makefile.vc install INSTALLDIR=c:\progra~1\tcl -# -# Building for Win64 -# c:\tcl_src\win\>c:\progra~1\micros~1\vc98\bin\vcvars32.bat -# Setting environment for using Microsoft Visual C++ tools. -# c:\tcl_src\win\>c:\progra~1\platfo~1\setenv.bat /pre64 /RETAIL -# Targeting Windows pre64 RETAIL -# c:\tcl_src\win\>nmake -f makefile.vc MACHINE=IA64 -# -#------------------------------------------------------------------------------ -#============================================================================== -############################################################################### - - -# //==================================================================\\ -# >>[ -> Do not modify below this line. <- ]<< -# >>[ Please, use the commandline macros to modify how Tcl is built. ]<< -# >>[ If you need more features, send us a patch for more macros. ]<< -# \\==================================================================// - - -############################################################################### -#============================================================================== -#------------------------------------------------------------------------------ - -!if !exist("makefile.vc") -MSG = ^ -You must run this makefile only from the directory it is in.^ -Please `cd` to its location first. -!error $(MSG) -!endif - -PROJECT = tcl -!include "rules.vc" - -STUBPREFIX = $(PROJECT)stub -DOTVERSION = $(TCL_MAJOR_VERSION).$(TCL_MINOR_VERSION) -VERSION = $(TCL_MAJOR_VERSION)$(TCL_MINOR_VERSION) - -DDEDOTVERSION = 1.4 -DDEVERSION = $(DDEDOTVERSION:.=) - -REGDOTVERSION = 1.3 -REGVERSION = $(REGDOTVERSION:.=) - -BINROOT = $(MAKEDIR) # originally . -ROOT = $(MAKEDIR)\.. # originally .. - -TCLIMPLIB = $(OUT_DIR)\$(PROJECT)$(VERSION)$(SUFX).lib -TCLLIBNAME = $(PROJECT)$(VERSION)$(SUFX).$(EXT) -TCLLIB = $(OUT_DIR)\$(TCLLIBNAME) - -TCLSTUBLIBNAME = $(STUBPREFIX)$(VERSION).lib -TCLSTUBLIB = $(OUT_DIR)\$(TCLSTUBLIBNAME) - -TCLSHNAME = $(PROJECT)sh$(VERSION)$(SUFX).exe -TCLSH = $(OUT_DIR)\$(TCLSHNAME) - -TCLREGLIBNAME = $(PROJECT)reg$(REGVERSION)$(SUFX:t=).$(EXT) -TCLREGLIB = $(OUT_DIR)\$(TCLREGLIBNAME) - -TCLDDELIBNAME = $(PROJECT)dde$(DDEVERSION)$(SUFX:t=).$(EXT) -TCLDDELIB = $(OUT_DIR)\$(TCLDDELIBNAME) - -TCLTEST = $(OUT_DIR)\$(PROJECT)test.exe -CAT32 = $(OUT_DIR)\cat32.exe - -# Can we run what we build? IX86 runs on all architectures. -!ifndef TCLSH_NATIVE -!if "$(MACHINE)" == "IX86" || "$(MACHINE)" == "$(NATIVE_ARCH)" -TCLSH_NATIVE = $(TCLSH) -!else -!error You must explicitly set TCLSH_NATIVE for cross-compilation -!endif -!endif - -### Make sure we use backslash only. -LIB_INSTALL_DIR = $(_INSTALLDIR)\lib -BIN_INSTALL_DIR = $(_INSTALLDIR)\bin -DOC_INSTALL_DIR = $(_INSTALLDIR)\doc -SCRIPT_INSTALL_DIR = $(_INSTALLDIR)\lib\tcl$(DOTVERSION) -INCLUDE_INSTALL_DIR = $(_INSTALLDIR)\include - -TCLSHOBJS = \ - $(TMP_DIR)\tclAppInit.obj \ -!if !$(STATIC_BUILD) -!if $(TCL_USE_STATIC_PACKAGES) - $(TMP_DIR)\tclWinReg.obj \ - $(TMP_DIR)\tclWinDde.obj \ -!endif -!endif - $(TMP_DIR)\tclsh.res - -TCLTESTOBJS = \ - $(TMP_DIR)\tclTest.obj \ - $(TMP_DIR)\tclTestObj.obj \ - $(TMP_DIR)\tclTestProcBodyObj.obj \ - $(TMP_DIR)\tclThreadTest.obj \ - $(TMP_DIR)\tclWinTest.obj \ -!if !$(STATIC_BUILD) -!if $(TCL_USE_STATIC_PACKAGES) - $(TMP_DIR)\tclWinReg.obj \ - $(TMP_DIR)\tclWinDde.obj \ -!endif -!endif - $(TMP_DIR)\testMain.obj - -COREOBJS = \ - $(TMP_DIR)\regcomp.obj \ - $(TMP_DIR)\regerror.obj \ - $(TMP_DIR)\regexec.obj \ - $(TMP_DIR)\regfree.obj \ - $(TMP_DIR)\tclAlloc.obj \ - $(TMP_DIR)\tclAssembly.obj \ - $(TMP_DIR)\tclAsync.obj \ - $(TMP_DIR)\tclBasic.obj \ - $(TMP_DIR)\tclBinary.obj \ - $(TMP_DIR)\tclCkalloc.obj \ - $(TMP_DIR)\tclClock.obj \ - $(TMP_DIR)\tclCmdAH.obj \ - $(TMP_DIR)\tclCmdIL.obj \ - $(TMP_DIR)\tclCmdMZ.obj \ - $(TMP_DIR)\tclCompCmds.obj \ - $(TMP_DIR)\tclCompCmdsGR.obj \ - $(TMP_DIR)\tclCompCmdsSZ.obj \ - $(TMP_DIR)\tclCompExpr.obj \ - $(TMP_DIR)\tclCompile.obj \ - $(TMP_DIR)\tclConfig.obj \ - $(TMP_DIR)\tclDate.obj \ - $(TMP_DIR)\tclDictObj.obj \ - $(TMP_DIR)\tclDisassemble.obj \ - $(TMP_DIR)\tclEncoding.obj \ - $(TMP_DIR)\tclEnsemble.obj \ - $(TMP_DIR)\tclEnv.obj \ - $(TMP_DIR)\tclEvent.obj \ - $(TMP_DIR)\tclExecute.obj \ - $(TMP_DIR)\tclFCmd.obj \ - $(TMP_DIR)\tclFileName.obj \ - $(TMP_DIR)\tclGet.obj \ - $(TMP_DIR)\tclHash.obj \ - $(TMP_DIR)\tclHistory.obj \ - $(TMP_DIR)\tclIndexObj.obj \ - $(TMP_DIR)\tclInterp.obj \ - $(TMP_DIR)\tclIO.obj \ - $(TMP_DIR)\tclIOCmd.obj \ - $(TMP_DIR)\tclIOGT.obj \ - $(TMP_DIR)\tclIOSock.obj \ - $(TMP_DIR)\tclIOUtil.obj \ - $(TMP_DIR)\tclIORChan.obj \ - $(TMP_DIR)\tclIORTrans.obj \ - $(TMP_DIR)\tclLink.obj \ - $(TMP_DIR)\tclListObj.obj \ - $(TMP_DIR)\tclLiteral.obj \ - $(TMP_DIR)\tclLoad.obj \ - $(TMP_DIR)\tclMain.obj \ - $(TMP_DIR)\tclMain2.obj \ - $(TMP_DIR)\tclNamesp.obj \ - $(TMP_DIR)\tclNotify.obj \ - $(TMP_DIR)\tclOO.obj \ - $(TMP_DIR)\tclOOBasic.obj \ - $(TMP_DIR)\tclOOCall.obj \ - $(TMP_DIR)\tclOODefineCmds.obj \ - $(TMP_DIR)\tclOOInfo.obj \ - $(TMP_DIR)\tclOOMethod.obj \ - $(TMP_DIR)\tclOOStubInit.obj \ - $(TMP_DIR)\tclObj.obj \ - $(TMP_DIR)\tclOptimize.obj \ - $(TMP_DIR)\tclPanic.obj \ - $(TMP_DIR)\tclParse.obj \ - $(TMP_DIR)\tclPathObj.obj \ - $(TMP_DIR)\tclPipe.obj \ - $(TMP_DIR)\tclPkg.obj \ - $(TMP_DIR)\tclPkgConfig.obj \ - $(TMP_DIR)\tclPosixStr.obj \ - $(TMP_DIR)\tclPreserve.obj \ - $(TMP_DIR)\tclProc.obj \ - $(TMP_DIR)\tclProcess.obj \ - $(TMP_DIR)\tclRegexp.obj \ - $(TMP_DIR)\tclResolve.obj \ - $(TMP_DIR)\tclResult.obj \ - $(TMP_DIR)\tclScan.obj \ - $(TMP_DIR)\tclStringObj.obj \ - $(TMP_DIR)\tclStrToD.obj \ - $(TMP_DIR)\tclStubInit.obj \ - $(TMP_DIR)\tclThread.obj \ - $(TMP_DIR)\tclThreadAlloc.obj \ - $(TMP_DIR)\tclThreadJoin.obj \ - $(TMP_DIR)\tclThreadStorage.obj \ - $(TMP_DIR)\tclTimer.obj \ - $(TMP_DIR)\tclTomMathInterface.obj \ - $(TMP_DIR)\tclTrace.obj \ - $(TMP_DIR)\tclUtf.obj \ - $(TMP_DIR)\tclUtil.obj \ - $(TMP_DIR)\tclVar.obj \ - $(TMP_DIR)\tclZlib.obj - -ZLIBOBJS = \ - $(TMP_DIR)\adler32.obj \ - $(TMP_DIR)\compress.obj \ - $(TMP_DIR)\crc32.obj \ - $(TMP_DIR)\deflate.obj \ - $(TMP_DIR)\infback.obj \ - $(TMP_DIR)\inffast.obj \ - $(TMP_DIR)\inflate.obj \ - $(TMP_DIR)\inftrees.obj \ - $(TMP_DIR)\trees.obj \ - $(TMP_DIR)\uncompr.obj \ - $(TMP_DIR)\zutil.obj - -TOMMATHOBJS = \ - $(TMP_DIR)\bncore.obj \ - $(TMP_DIR)\bn_reverse.obj \ - $(TMP_DIR)\bn_fast_s_mp_mul_digs.obj \ - $(TMP_DIR)\bn_fast_s_mp_sqr.obj \ - $(TMP_DIR)\bn_mp_add.obj \ - $(TMP_DIR)\bn_mp_add_d.obj \ - $(TMP_DIR)\bn_mp_and.obj \ - $(TMP_DIR)\bn_mp_clamp.obj \ - $(TMP_DIR)\bn_mp_clear.obj \ - $(TMP_DIR)\bn_mp_clear_multi.obj \ - $(TMP_DIR)\bn_mp_cmp.obj \ - $(TMP_DIR)\bn_mp_cmp_d.obj \ - $(TMP_DIR)\bn_mp_cmp_mag.obj \ - $(TMP_DIR)\bn_mp_cnt_lsb.obj \ - $(TMP_DIR)\bn_mp_copy.obj \ - $(TMP_DIR)\bn_mp_count_bits.obj \ - $(TMP_DIR)\bn_mp_div.obj \ - $(TMP_DIR)\bn_mp_div_d.obj \ - $(TMP_DIR)\bn_mp_div_2.obj \ - $(TMP_DIR)\bn_mp_div_2d.obj \ - $(TMP_DIR)\bn_mp_div_3.obj \ - $(TMP_DIR)\bn_mp_exch.obj \ - $(TMP_DIR)\bn_mp_expt_d.obj \ - $(TMP_DIR)\bn_mp_expt_d_ex.obj \ - $(TMP_DIR)\bn_mp_get_int.obj \ - $(TMP_DIR)\bn_mp_get_long.obj \ - $(TMP_DIR)\bn_mp_get_long_long.obj \ - $(TMP_DIR)\bn_mp_grow.obj \ - $(TMP_DIR)\bn_mp_init.obj \ - $(TMP_DIR)\bn_mp_init_copy.obj \ - $(TMP_DIR)\bn_mp_init_multi.obj \ - $(TMP_DIR)\bn_mp_init_set.obj \ - $(TMP_DIR)\bn_mp_init_set_int.obj \ - $(TMP_DIR)\bn_mp_init_size.obj \ - $(TMP_DIR)\bn_mp_karatsuba_mul.obj \ - $(TMP_DIR)\bn_mp_karatsuba_sqr.obj \ - $(TMP_DIR)\bn_mp_lshd.obj \ - $(TMP_DIR)\bn_mp_mod.obj \ - $(TMP_DIR)\bn_mp_mod_2d.obj \ - $(TMP_DIR)\bn_mp_mul.obj \ - $(TMP_DIR)\bn_mp_mul_2.obj \ - $(TMP_DIR)\bn_mp_mul_2d.obj \ - $(TMP_DIR)\bn_mp_mul_d.obj \ - $(TMP_DIR)\bn_mp_neg.obj \ - $(TMP_DIR)\bn_mp_or.obj \ - $(TMP_DIR)\bn_mp_radix_size.obj \ - $(TMP_DIR)\bn_mp_radix_smap.obj \ - $(TMP_DIR)\bn_mp_read_radix.obj \ - $(TMP_DIR)\bn_mp_rshd.obj \ - $(TMP_DIR)\bn_mp_set.obj \ - $(TMP_DIR)\bn_mp_set_int.obj \ - $(TMP_DIR)\bn_mp_set_long.obj \ - $(TMP_DIR)\bn_mp_set_long_long.obj \ - $(TMP_DIR)\bn_mp_shrink.obj \ - $(TMP_DIR)\bn_mp_sqr.obj \ - $(TMP_DIR)\bn_mp_sqrt.obj \ - $(TMP_DIR)\bn_mp_sub.obj \ - $(TMP_DIR)\bn_mp_sub_d.obj \ - $(TMP_DIR)\bn_mp_to_unsigned_bin.obj \ - $(TMP_DIR)\bn_mp_to_unsigned_bin_n.obj \ - $(TMP_DIR)\bn_mp_toom_mul.obj \ - $(TMP_DIR)\bn_mp_toom_sqr.obj \ - $(TMP_DIR)\bn_mp_toradix_n.obj \ - $(TMP_DIR)\bn_mp_unsigned_bin_size.obj \ - $(TMP_DIR)\bn_mp_xor.obj \ - $(TMP_DIR)\bn_mp_zero.obj \ - $(TMP_DIR)\bn_s_mp_add.obj \ - $(TMP_DIR)\bn_s_mp_mul_digs.obj \ - $(TMP_DIR)\bn_s_mp_sqr.obj \ - $(TMP_DIR)\bn_s_mp_sub.obj - -PLATFORMOBJS = \ - $(TMP_DIR)\tclWin32Dll.obj \ - $(TMP_DIR)\tclWinChan.obj \ - $(TMP_DIR)\tclWinConsole.obj \ - $(TMP_DIR)\tclWinError.obj \ - $(TMP_DIR)\tclWinFCmd.obj \ - $(TMP_DIR)\tclWinFile.obj \ - $(TMP_DIR)\tclWinInit.obj \ - $(TMP_DIR)\tclWinLoad.obj \ - $(TMP_DIR)\tclWinNotify.obj \ - $(TMP_DIR)\tclWinPipe.obj \ - $(TMP_DIR)\tclWinSerial.obj \ - $(TMP_DIR)\tclWinSock.obj \ - $(TMP_DIR)\tclWinThrd.obj \ - $(TMP_DIR)\tclWinTime.obj \ -!if $(STATIC_BUILD) - $(TMP_DIR)\tclWinReg.obj \ - $(TMP_DIR)\tclWinDde.obj \ -!else - $(TMP_DIR)\tcl.res -!endif - -TCLOBJS = $(COREOBJS) $(ZLIBOBJS) $(TOMMATHOBJS) $(PLATFORMOBJS) - -TCLSTUBOBJS = \ - $(TMP_DIR)\tclStubLib.obj \ - $(TMP_DIR)\tclTomMathStubLib.obj \ - $(TMP_DIR)\tclOOStubLib.obj - -### The following paths CANNOT have spaces in them. -COMPATDIR = $(ROOT)\compat -DOCDIR = $(ROOT)\doc -GENERICDIR = $(ROOT)\generic -TOMMATHDIR = $(ROOT)\libtommath -TOOLSDIR = $(ROOT)\tools -WINDIR = $(ROOT)\win -PKGSDIR = $(ROOT)\pkgs - -#--------------------------------------------------------------------- -# Compile flags -#--------------------------------------------------------------------- - -!if !$(DEBUG) -!if $(OPTIMIZING) -### This cranks the optimization level to maximize speed -cdebug = -O2 $(OPTIMIZATIONS) -!else -cdebug = -!endif -!if $(SYMBOLS) -cdebug = $(cdebug) -Zi -!endif -!else if "$(MACHINE)" == "IA64" || "$(MACHINE)" == "AMD64" -### Warnings are too many, can't support warnings into errors. -cdebug = -Zi -Od $(DEBUGFLAGS) -!else -cdebug = -Zi -WX $(DEBUGFLAGS) -!endif - -### Common compiler options that are architecture specific -!if "$(MACHINE)" == "ARM" -carch = -D_ARM_WINAPI_PARTITION_DESKTOP_SDK_AVAILABLE -!else -carch = -!endif - -### Declarations common to all compiler options -cwarn = $(WARNINGS) -D _CRT_SECURE_NO_DEPRECATE -D _CRT_NONSTDC_NO_DEPRECATE -cflags = -nologo -c $(COMPILERFLAGS) $(carch) $(cwarn) -Fp$(TMP_DIR)^\ - -!if $(MSVCRT) -!if $(DEBUG) && !$(UNCHECKED) -crt = -MDd -!else -crt = -MD -!endif -!else -!if $(DEBUG) && !$(UNCHECKED) -crt = -MTd -!else -crt = -MT -!endif -!endif - -TCL_INCLUDES = -I"$(WINDIR)" -I"$(GENERICDIR)" -I"$(TOMMATHDIR)" -TCL_DEFINES = -DMP_PREC=4 -Dinline=__inline -DHAVE_ZLIB=1 -BASE_CFLAGS = $(cflags) $(cdebug) $(crt) $(TCL_INCLUDES) $(TCL_DEFINES) -CON_CFLAGS = $(cflags) $(cdebug) $(crt) -DCONSOLE -TCL_CFLAGS = $(BASE_CFLAGS) $(OPTDEFINES) -STUB_CFLAGS = $(cflags) $(cdebug) $(OPTDEFINES) - - -#--------------------------------------------------------------------- -# Link flags -#--------------------------------------------------------------------- - -!if $(DEBUG) -ldebug = -debug -debugtype:cv -!else -ldebug = -release -opt:ref -opt:icf,3 -!if $(SYMBOLS) -ldebug = $(ldebug) -debug -debugtype:cv -!endif -!endif - -### Declarations common to all linker options -lflags = -nologo -machine:$(MACHINE) $(LINKERFLAGS) $(ldebug) - -!if $(PROFILE) -lflags = $(lflags) -profile -!endif - -!if $(MSVCRT) && !($(DEBUG) && !$(UNCHECKED)) && $(VCVERSION) >= 1900 -lflags = $(lflags) -nodefaultlib:libucrt.lib -!endif - -!if $(ALIGN98_HACK) && !$(STATIC_BUILD) -### Align sections for PE size savings. -lflags = $(lflags) -opt:nowin98 -!else if !$(ALIGN98_HACK) && $(STATIC_BUILD) -### Align sections for speed in loading by choosing the virtual page size. -lflags = $(lflags) -align:4096 -!endif - -!if $(LOIMPACT) -lflags = $(lflags) -ws:aggressive -!endif - -dlllflags = $(lflags) -dll -conlflags = $(lflags) -subsystem:console -guilflags = $(lflags) -subsystem:windows - -baselibs = netapi32.lib kernel32.lib user32.lib advapi32.lib userenv.lib ws2_32.lib -# Avoid 'unresolved external symbol __security_cookie' errors. -# c.f. http://support.microsoft.com/?id=894573 -!if "$(MACHINE)" == "IA64" || "$(MACHINE)" == "AMD64" -!if $(VCVERSION) > 1399 && $(VCVERSION) < 1500 -baselibs = $(baselibs) bufferoverflowU.lib -!endif -!endif -!if $(MSVCRT) && !($(DEBUG) && !$(UNCHECKED)) && $(VCVERSION) >= 1900 -baselibs = $(baselibs) ucrt.lib -!endif - -#--------------------------------------------------------------------- -# TclTest flags -#--------------------------------------------------------------------- - -!if "$(TESTPAT)" != "" -TESTFLAGS = $(TESTFLAGS) -file $(TESTPAT) -!endif - - -#--------------------------------------------------------------------- -# Project specific targets -#--------------------------------------------------------------------- - -release: setup $(TCLSH) $(TCLSTUBLIB) dlls pkgs -core: setup $(TCLLIB) $(TCLSTUBLIB) -shell: setup $(TCLSH) -dlls: setup $(TCLREGLIB) $(TCLDDELIB) -all: setup $(TCLSH) $(TCLSTUBLIB) dlls $(CAT32) pkgs -tcltest: setup $(TCLTEST) dlls $(CAT32) -install: install-binaries install-libraries install-docs install-pkgs - -test: test-core test-pkgs -test-core: setup $(TCLTEST) dlls $(CAT32) - set TCL_LIBRARY=$(ROOT:\=/)/library -!if "$(OS)" == "Windows_NT" || "$(MSVCDIR)" == "IDE" - $(DEBUGGER) $(TCLTEST) "$(ROOT:\=/)/tests/all.tcl" $(TESTFLAGS) -loadfile << - package ifneeded dde 1.4.0 [list load "$(TCLDDELIB:\=/)" dde] - package ifneeded registry 1.3.2 [list load "$(TCLREGLIB:\=/)" registry] -<< -!else - @echo Please wait while the tests are collected... - $(TCLTEST) "$(ROOT:\=/)/tests/all.tcl" $(TESTFLAGS) -loadfile << > tests.log - package ifneeded dde 1.4.0 "$(TCLDDELIB:\=/)" dde] - package ifneeded registry 1.3.2 "$(TCLREGLIB:\=/)" registry] -<< - type tests.log | more -!endif - -runtest: setup $(TCLTEST) dlls $(CAT32) - set TCL_LIBRARY=$(ROOT:\=/)/library - $(DEBUGGER) $(TCLTEST) $(SCRIPT) - -runshell: setup $(TCLSH) dlls - set TCL_LIBRARY=$(ROOT:\=/)/library - $(DEBUGGER) $(TCLSH) $(SCRIPT) - -setup: - @if not exist $(OUT_DIR)\nul mkdir $(OUT_DIR) - @if not exist $(TMP_DIR)\nul mkdir $(TMP_DIR) - -!if !$(STATIC_BUILD) -$(TCLIMPLIB): $(TCLLIB) -!endif - -$(TCLLIB): $(TCLOBJS) -!if $(STATIC_BUILD) - $(lib32) -nologo $(LINKERFLAGS) -out:$@ @<< -$** -<< -!else - $(link32) $(dlllflags) -base:@$(WINDIR)\coffbase.txt,tcl -out:$@ \ - $(baselibs) @<< -$** -<< - $(_VC_MANIFEST_EMBED_DLL) -!endif - -$(TCLSTUBLIB): $(TCLSTUBOBJS) - $(lib32) -nologo $(LINKERFLAGS) -nodefaultlib -out:$@ $(TCLSTUBOBJS) - -$(TCLSH): $(TCLSHOBJS) $(TCLSTUBLIB) $(TCLIMPLIB) - $(link32) $(conlflags) -stack:2300000 -out:$@ $(baselibs) $** - $(_VC_MANIFEST_EMBED_EXE) - -$(TCLTEST): $(TCLTESTOBJS) $(TCLSTUBLIB) $(TCLIMPLIB) - $(link32) $(conlflags) -stack:2300000 -out:$@ $(baselibs) $** - $(_VC_MANIFEST_EMBED_EXE) - -!if $(STATIC_BUILD) -$(TCLDDELIB): $(TMP_DIR)\tclWinDde.obj - $(lib32) -nologo $(LINKERFLAGS) -out:$@ $** -!else -$(TCLDDELIB): $(TMP_DIR)\tclWinDde.obj $(TCLSTUBLIB) - $(link32) $(dlllflags) -base:@$(WINDIR)\coffbase.txt,tcldde -out:$@ \ - $** $(baselibs) - $(_VC_MANIFEST_EMBED_DLL) -!endif - -!if $(STATIC_BUILD) -$(TCLREGLIB): $(TMP_DIR)\tclWinReg.obj - $(lib32) -nologo $(LINKERFLAGS) -out:$@ $** -!else -$(TCLREGLIB): $(TMP_DIR)\tclWinReg.obj $(TCLSTUBLIB) - $(link32) $(dlllflags) -base:@$(WINDIR)\coffbase.txt,tclreg -out:$@ \ - $** $(baselibs) - $(_VC_MANIFEST_EMBED_DLL) -!endif - -pkgs: - @for /d %d in ($(PKGSDIR)\*) do \ - @if exist "%~fd\win\makefile.vc" ( \ - pushd "%~fd\win" & \ - $(MAKE) -$(MAKEFLAGS) -f makefile.vc TCLDIR=$(ROOT) &\ - popd \ - ) - -test-pkgs: - @for /d %d in ($(PKGSDIR)\*) do \ - @if exist "%~fd\win\makefile.vc" ( \ - pushd "%~fd\win" & \ - $(MAKE) -$(MAKEFLAGS) -f makefile.vc TCLDIR=$(ROOT) test &\ - popd \ - ) - -install-pkgs: - @for /d %d in ($(PKGSDIR)\*) do \ - @if exist "%~fd\win\makefile.vc" ( \ - pushd "%~fd\win" & \ - $(MAKE) -$(MAKEFLAGS) -f makefile.vc TCLDIR=$(ROOT) install &\ - popd \ - ) - -clean-pkgs: - @for /d %d in ($(PKGSDIR)\*) do \ - @if exist "%~fd\win\makefile.vc" ( \ - pushd "%~fd\win" & \ - $(MAKE) -$(MAKEFLAGS) -f makefile.vc TCLDIR=$(ROOT) clean &\ - popd \ - ) - -$(CAT32): $(WINDIR)\cat.c - $(cc32) $(CON_CFLAGS) -Fo$(TMP_DIR)\ $? - $(link32) $(conlflags) -out:$@ -stack:16384 $(TMP_DIR)\cat.obj \ - $(baselibs) - $(_VC_MANIFEST_EMBED_EXE) - -#--------------------------------------------------------------------- -# Regenerate the stubs files. [Development use only] -#--------------------------------------------------------------------- - -genstubs: -!if !exist($(TCLSH)) - @echo Build tclsh first! -!else - $(TCLSH) $(TOOLSDIR:\=/)/genStubs.tcl $(GENERICDIR:\=/) \ - $(GENERICDIR:\=/)/tcl.decls $(GENERICDIR:\=/)/tclInt.decls \ - $(GENERICDIR:\=/)/tclTomMath.decls - $(TCLSH) $(TOOLSDIR:\=/)/genStubs.tcl $(GENERICDIR:\=/) \ - $(GENERICDIR:\=/)/tclOO.decls -!endif - - -#---------------------------------------------------------------------- -# The following target generates the file generic/tclTomMath.h. -# It needs to be run (and the results checked) after updating -# to a new release of libtommath. -#---------------------------------------------------------------------- - -gentommath_h: -!if !exist($(TCLSH)) - @echo Build tclsh first! -!else - $(TCLSH) "$(TOOLSDIR:\=/)/fix_tommath_h.tcl" \ - "$(TOMMATHDIR:\=/)/tommath.h" \ - > "$(GENERICDIR)\tclTomMath.h" -!endif - -#--------------------------------------------------------------------- -# Build the Windows HTML help file. -#--------------------------------------------------------------------- - -# NOTE: you can define HHC on the command-line to override this -!ifndef HHC -HHC=""%ProgramFiles%\HTML Help Workshop\hhc.exe"" -!endif -HTMLDIR=$(OUT_DIR)\html -HTMLBASE=TclTk$(VERSION) -HHPFILE=$(HTMLDIR)\$(HTMLBASE).hhp -CHMFILE=$(HTMLDIR)\$(HTMLBASE).chm - -htmlhelp: chmsetup $(CHMFILE) - -$(CHMFILE): $(DOCDIR)\* - @$(TCLSH) $(TOOLSDIR)\tcltk-man2html.tcl "--htmldir=$(HTMLDIR)" - @echo Compiling HTML help project - -$(HHC) <<$(HHPFILE) >NUL -[OPTIONS] -Compatibility=1.1 or later -Compiled file=$(HTMLBASE).chm -Default topic=contents.htm -Display compile progress=no -Error log file=$(HTMLBASE).log -Full-text search=Yes -Language=0x409 English (United States) -Title=Tcl/Tk $(DOT_VERSION) Help -[FILES] -contents.htm -docs.css -Keywords\*.htm -TclCmd\*.htm -TclLib\*.htm -TkCmd\*.htm -TkLib\*.htm -UserCmd\*.htm -<< - -chmsetup: - @if not exist $(HTMLDIR)\nul mkdir $(HTMLDIR) - -#------------------------------------------------------------------------- -# Build the old-style Windows .hlp file -#------------------------------------------------------------------------- - -TCLHLPBASE = $(PROJECT)$(VERSION) -HELPFILE = $(OUT_DIR)\$(TCLHLPBASE).hlp -HELPCNT = $(OUT_DIR)\$(TCLHLPBASE).cnt -DOCTMP_DIR = $(OUT_DIR)\$(PROJECT)_docs -HELPRTF = $(DOCTMP_DIR)\$(PROJECT).rtf -MAN2HELP = $(DOCTMP_DIR)\man2help.tcl -MAN2HELP2 = $(DOCTMP_DIR)\man2help2.tcl -INDEX = $(DOCTMP_DIR)\index.tcl -BMP = $(DOCTMP_DIR)\feather.bmp -BMP_NOPATH = feather.bmp -MAN2TCL = $(DOCTMP_DIR)\man2tcl.exe - -winhelp: docsetup $(HELPFILE) - -docsetup: - @if not exist $(DOCTMP_DIR)\nul mkdir $(DOCTMP_DIR) - -$(MAN2HELP) $(MAN2HELP2) $(INDEX) $(BMP): $(TOOLSDIR)\$$(@F) - @$(CPY) $(TOOLSDIR)\$(@F) $(@D) - -$(HELPFILE): $(HELPRTF) $(BMP) - cd $(DOCTMP_DIR) - start /wait hcrtf.exe -x <<$(PROJECT).hpj -[OPTIONS] -COMPRESS=12 Hall Zeck -LCID=0x409 0x0 0x0 ; English (United States) -TITLE=Tcl/Tk Reference Manual -BMROOT=. -CNT=$(@B).cnt -HLP=$(@B).hlp - -[FILES] -$(PROJECT).rtf - -[WINDOWS] -main="Tcl/Tk Reference Manual",,27648,(r15263976),(r65535) - -[CONFIG] -BrowseButtons() -CreateButton(1, "Web", ExecFile("http://www.tcl.tk")) -CreateButton(2, "SF", ExecFile("http://sf.net/projects/tcl")) -CreateButton(3, "Wiki", ExecFile("http://wiki.tcl.tk")) -CreateButton(4, "FAQ", ExecFile("http://www.purl.org/NET/Tcl-FAQ/")) -<< - cd $(MAKEDIR) - @$(CPY) "$(DOCTMP_DIR)\$(@B).hlp" "$(OUT_DIR)" - @$(CPY) "$(DOCTMP_DIR)\$(@B).cnt" "$(OUT_DIR)" - -$(MAN2TCL): $(TOOLSDIR)\$$(@B).c - $(cc32) $(TCL_CFLAGS) -Fo$(@D)\ $(TOOLSDIR)\$(@B).c - $(link32) $(conlflags) -out:$@ -stack:16384 $(@D)\man2tcl.obj - $(_VC_MANIFEST_EMBED_EXE) - -$(HELPRTF): $(MAN2TCL) $(MAN2HELP) $(MAN2HELP2) $(INDEX) $(DOCDIR)\* - $(TCLSH) $(MAN2HELP) -bitmap $(BMP_NOPATH) $(PROJECT) $(VERSION) $(DOCDIR:\=/) - -install-docs: -!if exist("$(CHMFILE)") - @echo Installing compiled HTML help - @$(CPY) "$(CHMFILE)" "$(DOC_INSTALL_DIR)\" -!endif -!if exist("$(HELPFILE)") - @echo Installing Windows help - @$(CPY) "$(HELPFILE)" "$(DOC_INSTALL_DIR)\" - @$(CPY) "$(HELPCNT)" "$(DOC_INSTALL_DIR)\" -!endif - -#--------------------------------------------------------------------- -# Build tclConfig.sh for the TEA build system. -#--------------------------------------------------------------------- - -tclConfig: $(OUT_DIR)\tclConfig.sh - -$(OUT_DIR)\tclConfig.sh: $(WINDIR)\tclConfig.sh.in - @echo Creating tclConfig.sh - @nmakehlp -s << $** >$@ -@TCL_DLL_FILE@ $(TCLLIBNAME) -@TCL_VERSION@ $(DOTVERSION) -@TCL_MAJOR_VERSION@ $(TCL_MAJOR_VERSION) -@TCL_MINOR_VERSION@ $(TCL_MINOR_VERSION) -@TCL_PATCH_LEVEL@ $(TCL_PATCH_LEVEL) -@CC@ $(CC) -@DEFS@ $(TCL_CFLAGS) -@CFLAGS_DEBUG@ -nologo -c -W3 -YX -Fp$(TMP_DIR)\ -MDd -@CFLAGS_OPTIMIZE@ -nologo -c -W3 -YX -Fp$(TMP_DIR)\ -MD -@LDFLAGS_DEBUG@ -nologo -machine:$(MACHINE) -debug -debugtype:cv -@LDFLAGS_OPTIMIZE@ -nologo -machine:$(MACHINE) -release -opt:ref -opt:icf,3 -@TCL_DBGX@ $(SUFX) -@TCL_LIB_FILE@ $(PROJECT)$(VERSION)$(SUFX).lib -@TCL_NEEDS_EXP_FILE@ -@LIBS@ $(baselibs) -@prefix@ $(_INSTALLDIR) -@exec_prefix@ $(BIN_INSTALL_DIR) -@SHLIB_CFLAGS@ -@STLIB_CFLAGS@ -@CFLAGS_WARNING@ -W3 -@EXTRA_CFLAGS@ -YX -@SHLIB_LD@ $(link32) $(dlllflags) -@STLIB_LD@ $(lib32) -nologo -@SHLIB_LD_LIBS@ $(baselibs) -@SHLIB_SUFFIX@ .dll -@DL_LIBS@ -@LDFLAGS@ -@TCL_CC_SEARCH_FLAGS@ -@TCL_LD_SEARCH_FLAGS@ -@LIBOBJS@ -@RANLIB@ -@TCL_LIB_FLAG@ -@TCL_BUILD_LIB_SPEC@ -@TCL_LIB_SPEC@ $(LIB_INSTALL_DIR)\$(PROJECT)$(VERSION)$(SUFX).lib -@TCL_INCLUDE_SPEC@ -I$(INCLUDE_INSTALL_DIR) -@TCL_LIB_VERSIONS_OK@ -@TCL_SRC_DIR@ $(ROOT) -@TCL_PACKAGE_PATH@ -@TCL_STUB_LIB_FILE@ $(TCLSTUBLIBNAME) -@TCL_STUB_LIB_FLAG@ $(TCLSTUBLIBNAME) -@TCL_STUB_LIB_SPEC@ -L$(LIB_INSTALL_DIR) $(TCLSTUBLIBNAME) -@TCL_THREADS@ $(TCL_THREADS) -@TCL_BUILD_STUB_LIB_SPEC@ -L$(OUT_DIR) $(TCLSTUBLIBNAME) -@TCL_BUILD_STUB_LIB_PATH@ $(TCLSTUBLIB) -@TCL_STUB_LIB_PATH@ $(LIB_INSTALL_DIR)\$(TCLSTUBLIBNAME) -@CFG_TCL_EXPORT_FILE_SUFFIX@ $(VERSION)$(SUFX).lib -@CFG_TCL_SHARED_LIB_SUFFIX@ $(VERSION)$(SUFX).dll -@CFG_TCL_UNSHARED_LIB_SUFFIX@ $(VERSION)$(SUFX).lib -!if $(STATIC_BUILD) -@TCL_SHARED_BUILD@ 0 -!else -@TCL_SHARED_BUILD@ 1 -!endif -<< - - -#--------------------------------------------------------------------- -# The following target generates the file generic/tclDate.c -# from the yacc grammar found in generic/tclGetDate.y. This is -# only run by hand as yacc is not available in all environments. -# The name of the .c file is different than the name of the .y file -# so that make doesn't try to automatically regenerate the .c file. -#--------------------------------------------------------------------- - -gendate: - bison --output-file=$(GENERICDIR)/tclDate.c \ - --name-prefix=TclDate \ - $(GENERICDIR)/tclGetDate.y - -#--------------------------------------------------------------------- -# Special case object file targets -#--------------------------------------------------------------------- - -$(TMP_DIR)\testMain.obj: $(WINDIR)\tclAppInit.c - $(cc32) $(TCL_CFLAGS) -DTCL_TEST \ - -DTCL_USE_STATIC_PACKAGES=$(TCL_USE_STATIC_PACKAGES) \ - -Fo$@ $? - -$(TMP_DIR)\tclMain2.obj: $(GENERICDIR)\tclMain.c - $(cc32) $(TCL_CFLAGS) -DBUILD_tcl -DTCL_ASCII_MAIN \ - -Fo$@ $? - -$(TMP_DIR)\tclTest.obj: $(GENERICDIR)\tclTest.c - $(cc32) $(TCL_CFLAGS) -Fo$@ $? - -$(TMP_DIR)\tclTestObj.obj: $(GENERICDIR)\tclTestObj.c - $(cc32) $(TCL_CFLAGS) -Fo$@ $? - -$(TMP_DIR)\tclWinTest.obj: $(WINDIR)\tclWinTest.c - $(cc32) $(TCL_CFLAGS) -Fo$@ $? - -$(TMP_DIR)\tclZlib.obj: $(GENERICDIR)\tclZlib.c - $(cc32) $(TCL_CFLAGS) -I$(COMPATDIR)\zlib -DBUILD_tcl -Fo$@ $? - -$(TMP_DIR)\tclPkgConfig.obj: $(GENERICDIR)\tclPkgConfig.c - $(cc32) -DBUILD_tcl $(TCL_CFLAGS) \ - -DCFG_INSTALL_LIBDIR="\"$(LIB_INSTALL_DIR:\=\\)\"" \ - -DCFG_INSTALL_BINDIR="\"$(BIN_INSTALL_DIR:\=\\)\"" \ - -DCFG_INSTALL_SCRDIR="\"$(SCRIPT_INSTALL_DIR:\=\\)\"" \ - -DCFG_INSTALL_INCDIR="\"$(INCLUDE_INSTALL_DIR:\=\\)\"" \ - -DCFG_INSTALL_DOCDIR="\"$(DOC_INSTALL_DIR:\=\\)\"" \ - -DCFG_RUNTIME_LIBDIR="\"$(LIB_INSTALL_DIR:\=\\)\"" \ - -DCFG_RUNTIME_BINDIR="\"$(BIN_INSTALL_DIR:\=\\)\"" \ - -DCFG_RUNTIME_SCRDIR="\"$(SCRIPT_INSTALL_DIR:\=\\)\"" \ - -DCFG_RUNTIME_INCDIR="\"$(INCLUDE_INSTALL_DIR:\=\\)\"" \ - -DCFG_RUNTIME_DOCDIR="\"$(DOC_INSTALL_DIR:\=\\)\"" \ - -Fo$@ $? - -$(TMP_DIR)\tclAppInit.obj: $(WINDIR)\tclAppInit.c - $(cc32) $(TCL_CFLAGS) \ - -DTCL_USE_STATIC_PACKAGES=$(TCL_USE_STATIC_PACKAGES) \ - -Fo$@ $? - -### The following objects should be built using the stub interfaces -### *ALL* extensions need to built with -DTCL_THREADS=1 - -$(TMP_DIR)\tclWinReg.obj: $(WINDIR)\tclWinReg.c -!if $(STATIC_BUILD) - $(cc32) $(TCL_CFLAGS) -DTCL_THREADS=1 -DSTATIC_BUILD -Fo$@ $? -!else - $(cc32) $(TCL_CFLAGS) -DTCL_THREADS=1 -DUSE_TCL_STUBS -Fo$@ $? -!endif - - -$(TMP_DIR)\tclWinDde.obj: $(WINDIR)\tclWinDde.c -!if $(STATIC_BUILD) - $(cc32) $(TCL_CFLAGS) -DTCL_THREADS=1 -DSTATIC_BUILD -Fo$@ $? -!else - $(cc32) $(TCL_CFLAGS) -DTCL_THREADS=1 -DUSE_TCL_STUBS -Fo$@ $? -!endif - - -### The following objects are part of the stub library and should not -### be built as DLL objects. -Zl is used to avoid a dependency on any -### specific C run-time. - -$(TMP_DIR)\tclStubLib.obj: $(GENERICDIR)\tclStubLib.c - $(cc32) $(STUB_CFLAGS) -Zl -DSTATIC_BUILD $(TCL_INCLUDES) -Fo$@ $? - -$(TMP_DIR)\tclTomMathStubLib.obj: $(GENERICDIR)\tclTomMathStubLib.c - $(cc32) $(STUB_CFLAGS) -Zl -DSTATIC_BUILD $(TCL_INCLUDES) -Fo$@ $? - -$(TMP_DIR)\tclOOStubLib.obj: $(GENERICDIR)\tclOOStubLib.c - $(cc32) $(STUB_CFLAGS) -Zl -DSTATIC_BUILD $(TCL_INCLUDES) -Fo$@ $? - -$(TMP_DIR)\tclsh.exe.manifest: $(WINDIR)\tclsh.exe.manifest.in - @nmakehlp -s << $** >$@ -@MACHINE@ $(MACHINE:IX86=X86) -@TCL_WIN_VERSION@ $(DOTVERSION).0.0 -<< - -#--------------------------------------------------------------------- -# Generate the source dependencies. Having dependency rules will -# improve incremental build accuracy without having to resort to a -# full rebuild just because some non-global header file like -# tclCompile.h was changed. These rules aren't needed when building -# from scratch. -#--------------------------------------------------------------------- - -depend: -!if !exist($(TCLSH)) - @echo Build tclsh first! -!else - $(TCLSH) $(TOOLSDIR:\=/)/mkdepend.tcl -vc32 -out:"$(OUT_DIR)\depend.mk" \ - -passthru:"-DBUILD_tcl $(TCL_INCLUDES)" $(GENERICDIR),$$(GENERICDIR) \ - $(COMPATDIR),$$(COMPATDIR) $(TOMMATHDIR),$$(TOMMATHDIR) $(WINDIR),$$(WINDIR) @<< -$(TCLOBJS) -<< -!endif - -#--------------------------------------------------------------------- -# Dependency rules -#--------------------------------------------------------------------- - -!if exist("$(OUT_DIR)\depend.mk") -!include "$(OUT_DIR)\depend.mk" -!message *** Dependency rules in use. -!else -!message *** Dependency rules are not being used. -!endif - -### add a spacer in the output -!message - - -#--------------------------------------------------------------------- -# Implicit rules. A limitation exists with nmake that requires that -# source directory can not contain spaces in the path. This an -# absolute. -#--------------------------------------------------------------------- - -{$(WINDIR)}.c{$(TMP_DIR)}.obj:: - $(cc32) $(TCL_CFLAGS) -DBUILD_tcl -Fo$(TMP_DIR)\ @<< -$< -<< - -{$(TOMMATHDIR)}.c{$(TMP_DIR)}.obj:: - $(cc32) $(TCL_CFLAGS) -DBUILD_tcl -Fo$(TMP_DIR)\ @<< -$< -<< - -{$(GENERICDIR)}.c{$(TMP_DIR)}.obj:: - $(cc32) $(TCL_CFLAGS) -DBUILD_tcl -Fo$(TMP_DIR)\ @<< -$< -<< - -{$(COMPATDIR)}.c{$(TMP_DIR)}.obj:: - $(cc32) $(TCL_CFLAGS) -DBUILD_tcl -Fo$(TMP_DIR)\ @<< -$< -<< - -{$(COMPATDIR)\zlib}.c{$(TMP_DIR)}.obj:: - $(cc32) $(TCL_CFLAGS) -DBUILD_tcl -Fo$(TMP_DIR)\ @<< -$< -<< - -{$(WINDIR)}.rc{$(TMP_DIR)}.res: - $(rc32) -fo $@ -r -i "$(GENERICDIR)" -i "$(TMP_DIR)" \ - -d DEBUG=$(DEBUG) -d UNCHECKED=$(UNCHECKED) \ - -d TCL_THREADS=$(TCL_THREADS) \ - -d STATIC_BUILD=$(STATIC_BUILD) \ - $< - -$(TMP_DIR)\tclsh.res: $(TMP_DIR)\tclsh.exe.manifest - -.SUFFIXES: -.SUFFIXES:.c .rc - - -#--------------------------------------------------------------------- -# Installation. -#--------------------------------------------------------------------- - -install-binaries: - @echo Installing to '$(_INSTALLDIR)' - @echo Installing $(TCLLIBNAME) -!if "$(TCLLIB)" != "$(TCLIMPLIB)" - @$(CPY) "$(TCLLIB)" "$(BIN_INSTALL_DIR)\" -!endif - @$(CPY) "$(TCLIMPLIB)" "$(LIB_INSTALL_DIR)\" -!if exist($(TCLSH)) - @echo Installing $(TCLSHNAME) - @$(CPY) "$(TCLSH)" "$(BIN_INSTALL_DIR)\" -!endif - @echo Installing $(TCLSTUBLIBNAME) - @$(CPY) "$(TCLSTUBLIB)" "$(LIB_INSTALL_DIR)\" - -#" emacs fix - -install-libraries: tclConfig install-msgs install-tzdata - @if not exist "$(SCRIPT_INSTALL_DIR)$(NULL)" \ - $(MKDIR) "$(SCRIPT_INSTALL_DIR)" - @if not exist "$(SCRIPT_INSTALL_DIR)\..\tcl8$(NULL)" \ - $(MKDIR) "$(SCRIPT_INSTALL_DIR)\..\tcl8" - @if not exist "$(SCRIPT_INSTALL_DIR)\..\tcl8\8.4$(NULL)" \ - $(MKDIR) "$(SCRIPT_INSTALL_DIR)\..\tcl8\8.4" - @if not exist "$(SCRIPT_INSTALL_DIR)\..\tcl8\8.4\platform$(NULL)" \ - $(MKDIR) "$(SCRIPT_INSTALL_DIR)\..\tcl8\8.4\platform" - @if not exist "$(SCRIPT_INSTALL_DIR)\..\tcl8\8.5$(NULL)" \ - $(MKDIR) "$(SCRIPT_INSTALL_DIR)\..\tcl8\8.5" - @if not exist "$(SCRIPT_INSTALL_DIR)\..\tcl8\8.6$(NULL)" \ - $(MKDIR) "$(SCRIPT_INSTALL_DIR)\..\tcl8\8.6" - @echo Installing header files - @$(CPY) "$(GENERICDIR)\tcl.h" "$(INCLUDE_INSTALL_DIR)\" - @$(CPY) "$(GENERICDIR)\tclDecls.h" "$(INCLUDE_INSTALL_DIR)\" - @$(CPY) "$(GENERICDIR)\tclOO.h" "$(INCLUDE_INSTALL_DIR)\" - @$(CPY) "$(GENERICDIR)\tclOODecls.h" "$(INCLUDE_INSTALL_DIR)\" - @$(CPY) "$(GENERICDIR)\tclPlatDecls.h" "$(INCLUDE_INSTALL_DIR)\" - @$(CPY) "$(GENERICDIR)\tclTomMath.h" "$(INCLUDE_INSTALL_DIR)\" - @$(CPY) "$(GENERICDIR)\tclTomMathDecls.h" "$(INCLUDE_INSTALL_DIR)\" - @$(CPY) "$(TOMMATHDIR)\tommath_class.h" "$(INCLUDE_INSTALL_DIR)\" - @$(CPY) "$(TOMMATHDIR)\tommath_superclass.h" "$(INCLUDE_INSTALL_DIR)\" - @echo Installing library files to $(SCRIPT_INSTALL_DIR) - @$(CPY) "$(ROOT)\library\history.tcl" "$(SCRIPT_INSTALL_DIR)\" - @$(CPY) "$(ROOT)\library\init.tcl" "$(SCRIPT_INSTALL_DIR)\" - @$(CPY) "$(ROOT)\library\clock.tcl" "$(SCRIPT_INSTALL_DIR)\" - @$(CPY) "$(ROOT)\library\tm.tcl" "$(SCRIPT_INSTALL_DIR)\" - @$(CPY) "$(ROOT)\library\parray.tcl" "$(SCRIPT_INSTALL_DIR)\" - @$(CPY) "$(ROOT)\library\safe.tcl" "$(SCRIPT_INSTALL_DIR)\" - @$(CPY) "$(ROOT)\library\tclIndex" "$(SCRIPT_INSTALL_DIR)\" - @$(CPY) "$(ROOT)\library\package.tcl" "$(SCRIPT_INSTALL_DIR)\" - @$(CPY) "$(ROOT)\library\word.tcl" "$(SCRIPT_INSTALL_DIR)\" - @$(CPY) "$(ROOT)\library\auto.tcl" "$(SCRIPT_INSTALL_DIR)\" - @$(CPY) "$(OUT_DIR)\tclConfig.sh" "$(LIB_INSTALL_DIR)\" - @$(CPY) "$(WINDIR)\tclooConfig.sh" "$(LIB_INSTALL_DIR)\" - @echo Installing library http1.0 directory - @$(CPY) "$(ROOT)\library\http1.0\*.tcl" \ - "$(SCRIPT_INSTALL_DIR)\http1.0\" - @echo Installing library opt0.4 directory - @$(CPY) "$(ROOT)\library\opt\*.tcl" \ - "$(SCRIPT_INSTALL_DIR)\opt0.4\" - @echo Installing package http $(PKG_HTTP_VER) as a Tcl Module - @$(COPY) "$(ROOT)\library\http\http.tcl" \ - "$(SCRIPT_INSTALL_DIR)\..\tcl8\8.6\http-$(PKG_HTTP_VER).tm" - @echo Installing package msgcat $(PKG_MSGCAT_VER) as a Tcl Module - @$(COPY) "$(ROOT)\library\msgcat\msgcat.tcl" \ - "$(SCRIPT_INSTALL_DIR)\..\tcl8\8.5\msgcat-$(PKG_MSGCAT_VER).tm" - @echo Installing package tcltest $(PKG_TCLTEST_VER) as a Tcl Module - @$(COPY) "$(ROOT)\library\tcltest\tcltest.tcl" \ - "$(SCRIPT_INSTALL_DIR)\..\tcl8\8.5\tcltest-$(PKG_TCLTEST_VER).tm" - @echo Installing package platform $(PKG_PLATFORM_VER) as a Tcl Module - @$(COPY) "$(ROOT)\library\platform\platform.tcl" \ - "$(SCRIPT_INSTALL_DIR)\..\tcl8\8.4\platform-$(PKG_PLATFORM_VER).tm" - @echo Installing package platform::shell $(PKG_SHELL_VER) as a Tcl Module - @$(COPY) "$(ROOT)\library\platform\shell.tcl" \ - "$(SCRIPT_INSTALL_DIR)\..\tcl8\8.4\platform\shell-$(PKG_SHELL_VER).tm" - @echo Installing $(TCLDDELIBNAME) -!if $(STATIC_BUILD) -!if !$(TCL_USE_STATIC_PACKAGES) - @$(CPY) "$(TCLDDELIB)" "$(LIB_INSTALL_DIR)\" -!endif -!else - @$(CPY) "$(TCLDDELIB)" "$(LIB_INSTALL_DIR)\dde$(DDEDOTVERSION)\" - @$(CPY) "$(ROOT)\library\dde\pkgIndex.tcl" \ - "$(LIB_INSTALL_DIR)\dde$(DDEDOTVERSION)\" -!endif - @echo Installing $(TCLREGLIBNAME) -!if $(STATIC_BUILD) -!if !$(TCL_USE_STATIC_PACKAGES) - @$(CPY) "$(TCLREGLIB)" "$(LIB_INSTALL_DIR)\" -!endif -!else - @$(CPY) "$(TCLREGLIB)" "$(LIB_INSTALL_DIR)\reg$(REGDOTVERSION)\" - @$(CPY) "$(ROOT)\library\reg\pkgIndex.tcl" \ - "$(LIB_INSTALL_DIR)\reg$(REGDOTVERSION)\" -!endif - @echo Installing encodings - @$(CPY) "$(ROOT)\library\encoding\*.enc" \ - "$(SCRIPT_INSTALL_DIR)\encoding\" - -#" emacs fix - -install-tzdata: - @echo Installing time zone data - @set TCL_LIBRARY=$(ROOT:\=/)/library - @$(TCLSH_NATIVE) "$(ROOT:\=/)/tools/installData.tcl" \ - "$(ROOT:\=/)/library/tzdata" "$(SCRIPT_INSTALL_DIR)/tzdata" - -install-msgs: - @echo Installing message catalogs - @set TCL_LIBRARY=$(ROOT:\=/)/library - @$(TCLSH_NATIVE) "$(ROOT:\=/)/tools/installData.tcl" \ - "$(ROOT:\=/)/library/msgs" "$(SCRIPT_INSTALL_DIR)/msgs" - -#--------------------------------------------------------------------- -# Clean up -#--------------------------------------------------------------------- - -tidy: -!if "$(TCLLIB)" != "$(TCLIMPLIB)" - @echo Removing $(TCLLIB) ... - @if exist $(TCLLIB) del $(TCLLIB) -!endif - @echo Removing $(TCLIMPLIB) ... - @if exist $(TCLIMPLIB) del $(TCLIMPLIB) - @echo Removing $(TCLSH) ... - @if exist $(TCLSH) del $(TCLSH) - @echo Removing $(TCLTEST) ... - @if exist $(TCLTEST) del $(TCLTEST) - @echo Removing $(TCLDDELIB) ... - @if exist $(TCLDDELIB) del $(TCLDDELIB) - @echo Removing $(TCLREGLIB) ... - @if exist $(TCLREGLIB) del $(TCLREGLIB) - -clean: clean-pkgs - @echo Cleaning $(TMP_DIR)\* ... - @if exist $(TMP_DIR)\nul $(RMDIR) $(TMP_DIR) - @echo Cleaning $(WINDIR)\nmakehlp.obj ... - @if exist $(WINDIR)\nmakehlp.obj del $(WINDIR)\nmakehlp.obj - @echo Cleaning $(WINDIR)\nmakehlp.exe ... - @if exist $(WINDIR)\nmakehlp.exe del $(WINDIR)\nmakehlp.exe - @echo Cleaning $(WINDIR)\nmhlp-out.txt ... - @if exist $(WINDIR)\nmhlp-out.txt del $(WINDIR)\nmhlp-out.txt - @echo Cleaning $(WINDIR)\_junk.pch ... - @if exist $(WINDIR)\_junk.pch del $(WINDIR)\_junk.pch - @echo Cleaning $(WINDIR)\vercl.x ... - @if exist $(WINDIR)\vercl.x del $(WINDIR)\vercl.x - @echo Cleaning $(WINDIR)\vercl.i ... - @if exist $(WINDIR)\vercl.i del $(WINDIR)\vercl.i - @echo Cleaning $(WINDIR)\versions.vc ... - @if exist $(WINDIR)\versions.vc del $(WINDIR)\versions.vc - -realclean: hose - -hose: - @echo Hosing $(OUT_DIR)\* ... - @if exist $(OUT_DIR)\nul $(RMDIR) $(OUT_DIR) - -# Local Variables: -# mode: makefile -# End: +#------------------------------------------------------------- +# makefile.vc -- +# +# Microsoft Visual C++ makefile for use with nmake.exe v1.62+ (VC++ 5.0+) +# +# See the file "license.terms" for information on usage and redistribution +# of this file, and for a DISCLAIMER OF ALL WARRANTIES. +# +# Copyright (c) 1995-1996 Sun Microsystems, Inc. +# Copyright (c) 1998-2000 Ajuba Solutions. +# Copyright (c) 2001-2005 ActiveState Corporation. +# Copyright (c) 2001-2004 David Gravereaux. +# Copyright (c) 2003-2008 Pat Thoyts. +#------------------------------------------------------------------------------ + +# Check to see we are configured to build with MSVC (MSDEVDIR, MSVCDIR or +# VCINSTALLDIR) or with the MS Platform SDK (MSSDK or WindowsSDKDir) +!if !defined(MSDEVDIR) && !defined(MSVCDIR) && !defined(VCINSTALLDIR) && !defined(MSSDK) && !defined(WINDOWSSDKDIR) +MSG = ^ +You need to run vcvars32.bat from Developer Studio or setenv.bat from the^ +Platform SDK first to setup the environment. Jump to this line to read^ +the build instructions. +!error $(MSG) +!endif + +#------------------------------------------------------------------------------ +# HOW TO USE this makefile: +# +# 1) It is now necessary to have MSVCDir, MSDevDir or MSSDK set in the +# environment. This is used as a check to see if vcvars32.bat had been +# run prior to running nmake or during the installation of Microsoft +# Visual C++, MSVCDir had been set globally and the PATH adjusted. +# Either way is valid. +# +# You'll need to run vcvars32.bat contained in the MsDev's vc(98)/bin +# directory to setup the proper environment, if needed, for your +# current setup. This is a needed bootstrap requirement and allows the +# swapping of different environments to be easier. +# +# 2) To use the Platform SDK (not expressly needed), run setenv.bat after +# vcvars32.bat according to the instructions for it. This can also +# turn on the 64-bit compiler, if your SDK has it. +# +# 3) Targets are: +# release -- Builds the core, the shell and the dlls. (default) +# dlls -- Just builds the windows extensions +# shell -- Just builds the shell and the core. +# core -- Only builds the core [tclXX.(dll|lib)]. +# all -- Builds everything. +# test -- Builds and runs the test suite. +# tcltest -- Just builds the test shell. +# install -- Installs the built binaries and libraries to $(INSTALLDIR) +# as the root of the install tree. +# tidy/clean/hose -- varying levels of cleaning. +# genstubs -- Rebuilds the Stubs table and support files (dev only). +# depend -- Generates an accurate set of source dependancies for this +# makefile. Helpful to avoid problems when the sources are +# refreshed and you rebuild, but can "overbuild" when common +# headers like tclInt.h just get small changes. +# htmlhelp -- Builds a Windows .chm help file for Tcl and Tk from the +# troff manual pages found in $(ROOT)\doc. You need to +# have installed the HTML Help Compiler package from Microsoft +# to produce the .chm file. +# winhelp -- (deprecated) Builds the windows .hlp file for Tcl from +# the troff man files found in $(ROOT)\doc. This type of +# help file is deprecated by Microsoft in favour of html +# help files (.chm) +# +# 4) Macros usable on the commandline: +# INSTALLDIR= +# Sets where to install Tcl from the built binaries. +# C:\Progra~1\Tcl is assumed when not specified. +# +# OPTS=loimpact,msvcrt,nothreads,pdbs,profile,static,staticpkg,symbols,thrdalloc,tclalloc,unchecked,none +# Sets special options for the core. The default is for none. +# Any combination of the above may be used (comma separated). +# 'none' will over-ride everything to nothing. +# +# loimpact = Adds a flag for how NT treats the heap to keep memory +# in use, low. This is said to impact alloc performance. +# msvcrt = Affects the static option only to switch it from +# using libcmt(d) as the C runtime [by default] to +# msvcrt(d). This is useful for static embedding +# support. +# nothreads= Turns off full multithreading support. +# pdbs = Build detached symbols for release builds. +# profile = Adds profiling hooks. Map file is assumed. +# static = Builds a static library of the core instead of a +# dll. The static library will contain the dde and reg +# extensions. External applications who want to use +# this, need to link with the stub library as well as +# the static Tcl library.The shell will be static (and +# large), as well. +# staticpkg = Affects the static option only to switch +# tclshXX.exe to have the dde and reg extension linked +# inside it. +# symbols = Debug build. Links to the debug C runtime, disables +# optimizations and creates pdb symbols files. +# thrdalloc = Use the thread allocator (shared global free pool) +# This is the default on threaded builds. +# tclalloc = Use the old non-thread allocator +# unchecked= Allows a symbols build to not use the debug +# enabled runtime (msvcrt.dll not msvcrtd.dll +# or libcmt.lib not libcmtd.lib). +# +# STATS=compdbg,memdbg,none +# Sets optional memory and bytecode compiler debugging code added +# to the core. The default is for none. Any combination of the +# above may be used (comma separated). 'none' will over-ride +# everything to nothing. +# +# compdbg = Enables byte compilation logging. +# memdbg = Enables the debugging memory allocator. +# +# CHECKS=64bit,fullwarn,nodep,none +# Sets special macros for checking compatibility. +# +# 64bit = Enable 64bit portability warnings (if available) +# fullwarn = Builds with full compiler and link warnings enabled. +# Very verbose. +# nodep = Turns off compatibility macros to ensure the core +# isn't being built with deprecated functions. +# +# MACHINE=(ARM|AMD64|IA64|IX86) +# Set the machine type used for the compiler, linker, and +# resource compiler. This hook is needed to tell the tools +# when alternate platforms are requested. IX86 is the default +# when not specified. If the CPU environment variable has been +# set (ie: recent Platform SDK) then MACHINE is set from CPU. +# +# TMP_DIR= +# OUT_DIR= +# Hooks to allow the intermediate and output directories to be +# changed. $(OUT_DIR) is assumed to be +# $(BINROOT)\(Release|Debug) based on if symbols are requested. +# $(TMP_DIR) will de $(OUT_DIR)\ by default. +# +# TESTPAT= +# Reads the tests requested to be run from this file. +# +# CFG_ENCODING=encoding +# name of encoding for configuration information. Defaults +# to cp1252 +# +# 5) Examples: +# +# Basic syntax of calling nmake looks like this: +# nmake [-nologo] -f makefile.vc [target|macrodef [target|macrodef] [...]] +# +# Standard (no frills) +# c:\tcl_src\win\>c:\progra~1\micros~1\vc98\bin\vcvars32.bat +# Setting environment for using Microsoft Visual C++ tools. +# c:\tcl_src\win\>nmake -f makefile.vc release +# c:\tcl_src\win\>nmake -f makefile.vc install INSTALLDIR=c:\progra~1\tcl +# +# Building for Win64 +# c:\tcl_src\win\>c:\progra~1\micros~1\vc98\bin\vcvars32.bat +# Setting environment for using Microsoft Visual C++ tools. +# c:\tcl_src\win\>c:\progra~1\platfo~1\setenv.bat /pre64 /RETAIL +# Targeting Windows pre64 RETAIL +# c:\tcl_src\win\>nmake -f makefile.vc MACHINE=IA64 +# +#------------------------------------------------------------------------------ +#============================================================================== +############################################################################### + + +# //==================================================================\\ +# >>[ -> Do not modify below this line. <- ]<< +# >>[ Please, use the commandline macros to modify how Tcl is built. ]<< +# >>[ If you need more features, send us a patch for more macros. ]<< +# \\==================================================================// + + +############################################################################### +#============================================================================== +#------------------------------------------------------------------------------ + +!if !exist("makefile.vc") +MSG = ^ +You must run this makefile only from the directory it is in.^ +Please `cd` to its location first. +!error $(MSG) +!endif + +PROJECT = tcl +!include "rules.vc" + +STUBPREFIX = $(PROJECT)stub +DOTVERSION = $(TCL_MAJOR_VERSION).$(TCL_MINOR_VERSION) +VERSION = $(TCL_MAJOR_VERSION)$(TCL_MINOR_VERSION) + +DDEDOTVERSION = 1.4 +DDEVERSION = $(DDEDOTVERSION:.=) + +REGDOTVERSION = 1.3 +REGVERSION = $(REGDOTVERSION:.=) + +BINROOT = $(MAKEDIR) # originally . +ROOT = $(MAKEDIR)\.. # originally .. + +TCLIMPLIB = $(OUT_DIR)\$(PROJECT)$(VERSION)$(SUFX).lib +TCLLIBNAME = $(PROJECT)$(VERSION)$(SUFX).$(EXT) +TCLLIB = $(OUT_DIR)\$(TCLLIBNAME) + +TCLSTUBLIBNAME = $(STUBPREFIX)$(VERSION).lib +TCLSTUBLIB = $(OUT_DIR)\$(TCLSTUBLIBNAME) + +TCLSHNAME = $(PROJECT)sh$(VERSION)$(SUFX).exe +TCLSH = $(OUT_DIR)\$(TCLSHNAME) + +TCLREGLIBNAME = $(PROJECT)reg$(REGVERSION)$(SUFX:t=).$(EXT) +TCLREGLIB = $(OUT_DIR)\$(TCLREGLIBNAME) + +TCLDDELIBNAME = $(PROJECT)dde$(DDEVERSION)$(SUFX:t=).$(EXT) +TCLDDELIB = $(OUT_DIR)\$(TCLDDELIBNAME) + +TCLTEST = $(OUT_DIR)\$(PROJECT)test.exe +CAT32 = $(OUT_DIR)\cat32.exe + +# Can we run what we build? IX86 runs on all architectures. +!ifndef TCLSH_NATIVE +!if "$(MACHINE)" == "IX86" || "$(MACHINE)" == "$(NATIVE_ARCH)" +TCLSH_NATIVE = $(TCLSH) +!else +!error You must explicitly set TCLSH_NATIVE for cross-compilation +!endif +!endif + +### Make sure we use backslash only. +LIB_INSTALL_DIR = $(_INSTALLDIR)\lib +BIN_INSTALL_DIR = $(_INSTALLDIR)\bin +DOC_INSTALL_DIR = $(_INSTALLDIR)\doc +SCRIPT_INSTALL_DIR = $(_INSTALLDIR)\lib\tcl$(DOTVERSION) +INCLUDE_INSTALL_DIR = $(_INSTALLDIR)\include + +TCLSHOBJS = \ + $(TMP_DIR)\tclAppInit.obj \ +!if !$(STATIC_BUILD) +!if $(TCL_USE_STATIC_PACKAGES) + $(TMP_DIR)\tclWinReg.obj \ + $(TMP_DIR)\tclWinDde.obj \ +!endif +!endif + $(TMP_DIR)\tclsh.res + +TCLTESTOBJS = \ + $(TMP_DIR)\tclTest.obj \ + $(TMP_DIR)\tclTestObj.obj \ + $(TMP_DIR)\tclTestProcBodyObj.obj \ + $(TMP_DIR)\tclThreadTest.obj \ + $(TMP_DIR)\tclWinTest.obj \ +!if !$(STATIC_BUILD) +!if $(TCL_USE_STATIC_PACKAGES) + $(TMP_DIR)\tclWinReg.obj \ + $(TMP_DIR)\tclWinDde.obj \ +!endif +!endif + $(TMP_DIR)\testMain.obj + +COREOBJS = \ + $(TMP_DIR)\regcomp.obj \ + $(TMP_DIR)\regerror.obj \ + $(TMP_DIR)\regexec.obj \ + $(TMP_DIR)\regfree.obj \ + $(TMP_DIR)\tclAlloc.obj \ + $(TMP_DIR)\tclAssembly.obj \ + $(TMP_DIR)\tclAsync.obj \ + $(TMP_DIR)\tclBasic.obj \ + $(TMP_DIR)\tclBinary.obj \ + $(TMP_DIR)\tclCkalloc.obj \ + $(TMP_DIR)\tclClock.obj \ + $(TMP_DIR)\tclCmdAH.obj \ + $(TMP_DIR)\tclCmdIL.obj \ + $(TMP_DIR)\tclCmdMZ.obj \ + $(TMP_DIR)\tclCompCmds.obj \ + $(TMP_DIR)\tclCompCmdsGR.obj \ + $(TMP_DIR)\tclCompCmdsSZ.obj \ + $(TMP_DIR)\tclCompExpr.obj \ + $(TMP_DIR)\tclCompile.obj \ + $(TMP_DIR)\tclConfig.obj \ + $(TMP_DIR)\tclDate.obj \ + $(TMP_DIR)\tclDictObj.obj \ + $(TMP_DIR)\tclDisassemble.obj \ + $(TMP_DIR)\tclEncoding.obj \ + $(TMP_DIR)\tclEnsemble.obj \ + $(TMP_DIR)\tclEnv.obj \ + $(TMP_DIR)\tclEvent.obj \ + $(TMP_DIR)\tclExecute.obj \ + $(TMP_DIR)\tclFCmd.obj \ + $(TMP_DIR)\tclFileName.obj \ + $(TMP_DIR)\tclGet.obj \ + $(TMP_DIR)\tclHash.obj \ + $(TMP_DIR)\tclHistory.obj \ + $(TMP_DIR)\tclIndexObj.obj \ + $(TMP_DIR)\tclInterp.obj \ + $(TMP_DIR)\tclIO.obj \ + $(TMP_DIR)\tclIOCmd.obj \ + $(TMP_DIR)\tclIOGT.obj \ + $(TMP_DIR)\tclIOSock.obj \ + $(TMP_DIR)\tclIOUtil.obj \ + $(TMP_DIR)\tclIORChan.obj \ + $(TMP_DIR)\tclIORTrans.obj \ + $(TMP_DIR)\tclLink.obj \ + $(TMP_DIR)\tclListObj.obj \ + $(TMP_DIR)\tclLiteral.obj \ + $(TMP_DIR)\tclLoad.obj \ + $(TMP_DIR)\tclMain.obj \ + $(TMP_DIR)\tclMain2.obj \ + $(TMP_DIR)\tclNamesp.obj \ + $(TMP_DIR)\tclNotify.obj \ + $(TMP_DIR)\tclOO.obj \ + $(TMP_DIR)\tclOOBasic.obj \ + $(TMP_DIR)\tclOOCall.obj \ + $(TMP_DIR)\tclOODefineCmds.obj \ + $(TMP_DIR)\tclOOInfo.obj \ + $(TMP_DIR)\tclOOMethod.obj \ + $(TMP_DIR)\tclOOStubInit.obj \ + $(TMP_DIR)\tclObj.obj \ + $(TMP_DIR)\tclOptimize.obj \ + $(TMP_DIR)\tclPanic.obj \ + $(TMP_DIR)\tclParse.obj \ + $(TMP_DIR)\tclPathObj.obj \ + $(TMP_DIR)\tclPipe.obj \ + $(TMP_DIR)\tclPkg.obj \ + $(TMP_DIR)\tclPkgConfig.obj \ + $(TMP_DIR)\tclPosixStr.obj \ + $(TMP_DIR)\tclPreserve.obj \ + $(TMP_DIR)\tclProc.obj \ + $(TMP_DIR)\tclProcess.obj \ + $(TMP_DIR)\tclRegexp.obj \ + $(TMP_DIR)\tclResolve.obj \ + $(TMP_DIR)\tclResult.obj \ + $(TMP_DIR)\tclScan.obj \ + $(TMP_DIR)\tclStringObj.obj \ + $(TMP_DIR)\tclStrToD.obj \ + $(TMP_DIR)\tclStubInit.obj \ + $(TMP_DIR)\tclThread.obj \ + $(TMP_DIR)\tclThreadAlloc.obj \ + $(TMP_DIR)\tclThreadJoin.obj \ + $(TMP_DIR)\tclThreadStorage.obj \ + $(TMP_DIR)\tclTimer.obj \ + $(TMP_DIR)\tclTomMathInterface.obj \ + $(TMP_DIR)\tclTrace.obj \ + $(TMP_DIR)\tclUtf.obj \ + $(TMP_DIR)\tclUtil.obj \ + $(TMP_DIR)\tclVar.obj \ + $(TMP_DIR)\tclZlib.obj + +ZLIBOBJS = \ + $(TMP_DIR)\adler32.obj \ + $(TMP_DIR)\compress.obj \ + $(TMP_DIR)\crc32.obj \ + $(TMP_DIR)\deflate.obj \ + $(TMP_DIR)\infback.obj \ + $(TMP_DIR)\inffast.obj \ + $(TMP_DIR)\inflate.obj \ + $(TMP_DIR)\inftrees.obj \ + $(TMP_DIR)\trees.obj \ + $(TMP_DIR)\uncompr.obj \ + $(TMP_DIR)\zutil.obj + +TOMMATHOBJS = \ + $(TMP_DIR)\bncore.obj \ + $(TMP_DIR)\bn_reverse.obj \ + $(TMP_DIR)\bn_fast_s_mp_mul_digs.obj \ + $(TMP_DIR)\bn_fast_s_mp_sqr.obj \ + $(TMP_DIR)\bn_mp_add.obj \ + $(TMP_DIR)\bn_mp_add_d.obj \ + $(TMP_DIR)\bn_mp_and.obj \ + $(TMP_DIR)\bn_mp_clamp.obj \ + $(TMP_DIR)\bn_mp_clear.obj \ + $(TMP_DIR)\bn_mp_clear_multi.obj \ + $(TMP_DIR)\bn_mp_cmp.obj \ + $(TMP_DIR)\bn_mp_cmp_d.obj \ + $(TMP_DIR)\bn_mp_cmp_mag.obj \ + $(TMP_DIR)\bn_mp_cnt_lsb.obj \ + $(TMP_DIR)\bn_mp_copy.obj \ + $(TMP_DIR)\bn_mp_count_bits.obj \ + $(TMP_DIR)\bn_mp_div.obj \ + $(TMP_DIR)\bn_mp_div_d.obj \ + $(TMP_DIR)\bn_mp_div_2.obj \ + $(TMP_DIR)\bn_mp_div_2d.obj \ + $(TMP_DIR)\bn_mp_div_3.obj \ + $(TMP_DIR)\bn_mp_exch.obj \ + $(TMP_DIR)\bn_mp_expt_d.obj \ + $(TMP_DIR)\bn_mp_expt_d_ex.obj \ + $(TMP_DIR)\bn_mp_get_int.obj \ + $(TMP_DIR)\bn_mp_get_long.obj \ + $(TMP_DIR)\bn_mp_get_long_long.obj \ + $(TMP_DIR)\bn_mp_grow.obj \ + $(TMP_DIR)\bn_mp_init.obj \ + $(TMP_DIR)\bn_mp_init_copy.obj \ + $(TMP_DIR)\bn_mp_init_multi.obj \ + $(TMP_DIR)\bn_mp_init_set.obj \ + $(TMP_DIR)\bn_mp_init_set_int.obj \ + $(TMP_DIR)\bn_mp_init_size.obj \ + $(TMP_DIR)\bn_mp_karatsuba_mul.obj \ + $(TMP_DIR)\bn_mp_karatsuba_sqr.obj \ + $(TMP_DIR)\bn_mp_lshd.obj \ + $(TMP_DIR)\bn_mp_mod.obj \ + $(TMP_DIR)\bn_mp_mod_2d.obj \ + $(TMP_DIR)\bn_mp_mul.obj \ + $(TMP_DIR)\bn_mp_mul_2.obj \ + $(TMP_DIR)\bn_mp_mul_2d.obj \ + $(TMP_DIR)\bn_mp_mul_d.obj \ + $(TMP_DIR)\bn_mp_neg.obj \ + $(TMP_DIR)\bn_mp_or.obj \ + $(TMP_DIR)\bn_mp_radix_size.obj \ + $(TMP_DIR)\bn_mp_radix_smap.obj \ + $(TMP_DIR)\bn_mp_read_radix.obj \ + $(TMP_DIR)\bn_mp_rshd.obj \ + $(TMP_DIR)\bn_mp_set.obj \ + $(TMP_DIR)\bn_mp_set_int.obj \ + $(TMP_DIR)\bn_mp_set_long.obj \ + $(TMP_DIR)\bn_mp_set_long_long.obj \ + $(TMP_DIR)\bn_mp_shrink.obj \ + $(TMP_DIR)\bn_mp_sqr.obj \ + $(TMP_DIR)\bn_mp_sqrt.obj \ + $(TMP_DIR)\bn_mp_sub.obj \ + $(TMP_DIR)\bn_mp_sub_d.obj \ + $(TMP_DIR)\bn_mp_to_unsigned_bin.obj \ + $(TMP_DIR)\bn_mp_to_unsigned_bin_n.obj \ + $(TMP_DIR)\bn_mp_toom_mul.obj \ + $(TMP_DIR)\bn_mp_toom_sqr.obj \ + $(TMP_DIR)\bn_mp_toradix_n.obj \ + $(TMP_DIR)\bn_mp_unsigned_bin_size.obj \ + $(TMP_DIR)\bn_mp_xor.obj \ + $(TMP_DIR)\bn_mp_zero.obj \ + $(TMP_DIR)\bn_s_mp_add.obj \ + $(TMP_DIR)\bn_s_mp_mul_digs.obj \ + $(TMP_DIR)\bn_s_mp_sqr.obj \ + $(TMP_DIR)\bn_s_mp_sub.obj + +PLATFORMOBJS = \ + $(TMP_DIR)\tclWin32Dll.obj \ + $(TMP_DIR)\tclWinChan.obj \ + $(TMP_DIR)\tclWinConsole.obj \ + $(TMP_DIR)\tclWinError.obj \ + $(TMP_DIR)\tclWinFCmd.obj \ + $(TMP_DIR)\tclWinFile.obj \ + $(TMP_DIR)\tclWinInit.obj \ + $(TMP_DIR)\tclWinLoad.obj \ + $(TMP_DIR)\tclWinNotify.obj \ + $(TMP_DIR)\tclWinPipe.obj \ + $(TMP_DIR)\tclWinSerial.obj \ + $(TMP_DIR)\tclWinSock.obj \ + $(TMP_DIR)\tclWinThrd.obj \ + $(TMP_DIR)\tclWinTime.obj \ +!if $(STATIC_BUILD) + $(TMP_DIR)\tclWinReg.obj \ + $(TMP_DIR)\tclWinDde.obj \ +!else + $(TMP_DIR)\tcl.res +!endif + +TCLOBJS = $(COREOBJS) $(ZLIBOBJS) $(TOMMATHOBJS) $(PLATFORMOBJS) + +TCLSTUBOBJS = \ + $(TMP_DIR)\tclStubLib.obj \ + $(TMP_DIR)\tclTomMathStubLib.obj \ + $(TMP_DIR)\tclOOStubLib.obj + +### The following paths CANNOT have spaces in them. +COMPATDIR = $(ROOT)\compat +DOCDIR = $(ROOT)\doc +GENERICDIR = $(ROOT)\generic +TOMMATHDIR = $(ROOT)\libtommath +TOOLSDIR = $(ROOT)\tools +WINDIR = $(ROOT)\win +PKGSDIR = $(ROOT)\pkgs + +#--------------------------------------------------------------------- +# Compile flags +#--------------------------------------------------------------------- + +!if !$(DEBUG) +!if $(OPTIMIZING) +### This cranks the optimization level to maximize speed +cdebug = -O2 $(OPTIMIZATIONS) +!else +cdebug = +!endif +!if $(SYMBOLS) +cdebug = $(cdebug) -Zi +!endif +!else if "$(MACHINE)" == "IA64" || "$(MACHINE)" == "AMD64" +### Warnings are too many, can't support warnings into errors. +cdebug = -Zi -Od $(DEBUGFLAGS) +!else +cdebug = -Zi -WX $(DEBUGFLAGS) +!endif + +### Common compiler options that are architecture specific +!if "$(MACHINE)" == "ARM" +carch = -D_ARM_WINAPI_PARTITION_DESKTOP_SDK_AVAILABLE +!else +carch = +!endif + +### Declarations common to all compiler options +cwarn = $(WARNINGS) -D _CRT_SECURE_NO_DEPRECATE -D _CRT_NONSTDC_NO_DEPRECATE +cflags = -nologo -c $(COMPILERFLAGS) $(carch) $(cwarn) -Fp$(TMP_DIR)^\ + +!if $(MSVCRT) +!if $(DEBUG) && !$(UNCHECKED) +crt = -MDd +!else +crt = -MD +!endif +!else +!if $(DEBUG) && !$(UNCHECKED) +crt = -MTd +!else +crt = -MT +!endif +!endif + +TCL_INCLUDES = -I"$(WINDIR)" -I"$(GENERICDIR)" -I"$(TOMMATHDIR)" +TCL_DEFINES = -DMP_PREC=4 -Dinline=__inline -DHAVE_ZLIB=1 +BASE_CFLAGS = $(cflags) $(cdebug) $(crt) $(TCL_INCLUDES) $(TCL_DEFINES) +CON_CFLAGS = $(cflags) $(cdebug) $(crt) -DCONSOLE +TCL_CFLAGS = $(BASE_CFLAGS) $(OPTDEFINES) +STUB_CFLAGS = $(cflags) $(cdebug) $(OPTDEFINES) + + +#--------------------------------------------------------------------- +# Link flags +#--------------------------------------------------------------------- + +!if $(DEBUG) +ldebug = -debug -debugtype:cv +!else +ldebug = -release -opt:ref -opt:icf,3 +!if $(SYMBOLS) +ldebug = $(ldebug) -debug -debugtype:cv +!endif +!endif + +### Declarations common to all linker options +lflags = -nologo -machine:$(MACHINE) $(LINKERFLAGS) $(ldebug) + +!if $(PROFILE) +lflags = $(lflags) -profile +!endif + +!if $(MSVCRT) && !($(DEBUG) && !$(UNCHECKED)) && $(VCVERSION) >= 1900 +lflags = $(lflags) -nodefaultlib:libucrt.lib +!endif + +!if $(ALIGN98_HACK) && !$(STATIC_BUILD) +### Align sections for PE size savings. +lflags = $(lflags) -opt:nowin98 +!else if !$(ALIGN98_HACK) && $(STATIC_BUILD) +### Align sections for speed in loading by choosing the virtual page size. +lflags = $(lflags) -align:4096 +!endif + +!if $(LOIMPACT) +lflags = $(lflags) -ws:aggressive +!endif + +dlllflags = $(lflags) -dll +conlflags = $(lflags) -subsystem:console +guilflags = $(lflags) -subsystem:windows + +baselibs = netapi32.lib kernel32.lib user32.lib advapi32.lib userenv.lib ws2_32.lib +# Avoid 'unresolved external symbol __security_cookie' errors. +# c.f. http://support.microsoft.com/?id=894573 +!if "$(MACHINE)" == "IA64" || "$(MACHINE)" == "AMD64" +!if $(VCVERSION) > 1399 && $(VCVERSION) < 1500 +baselibs = $(baselibs) bufferoverflowU.lib +!endif +!endif +!if $(MSVCRT) && !($(DEBUG) && !$(UNCHECKED)) && $(VCVERSION) >= 1900 +baselibs = $(baselibs) ucrt.lib +!endif + +#--------------------------------------------------------------------- +# TclTest flags +#--------------------------------------------------------------------- + +!if "$(TESTPAT)" != "" +TESTFLAGS = $(TESTFLAGS) -file $(TESTPAT) +!endif + + +#--------------------------------------------------------------------- +# Project specific targets +#--------------------------------------------------------------------- + +release: setup $(TCLSH) $(TCLSTUBLIB) dlls pkgs +core: setup $(TCLLIB) $(TCLSTUBLIB) +shell: setup $(TCLSH) +dlls: setup $(TCLREGLIB) $(TCLDDELIB) +all: setup $(TCLSH) $(TCLSTUBLIB) dlls $(CAT32) pkgs +tcltest: setup $(TCLTEST) dlls $(CAT32) +install: install-binaries install-libraries install-docs install-pkgs + +test: test-core test-pkgs +test-core: setup $(TCLTEST) dlls $(CAT32) + set TCL_LIBRARY=$(ROOT:\=/)/library +!if "$(OS)" == "Windows_NT" || "$(MSVCDIR)" == "IDE" + $(DEBUGGER) $(TCLTEST) "$(ROOT:\=/)/tests/all.tcl" $(TESTFLAGS) -loadfile << + package ifneeded dde 1.4.0 [list load "$(TCLDDELIB:\=/)" dde] + package ifneeded registry 1.3.2 [list load "$(TCLREGLIB:\=/)" registry] +<< +!else + @echo Please wait while the tests are collected... + $(TCLTEST) "$(ROOT:\=/)/tests/all.tcl" $(TESTFLAGS) -loadfile << > tests.log + package ifneeded dde 1.4.0 "$(TCLDDELIB:\=/)" dde] + package ifneeded registry 1.3.2 "$(TCLREGLIB:\=/)" registry] +<< + type tests.log | more +!endif + +runtest: setup $(TCLTEST) dlls $(CAT32) + set TCL_LIBRARY=$(ROOT:\=/)/library + $(DEBUGGER) $(TCLTEST) $(SCRIPT) + +runshell: setup $(TCLSH) dlls + set TCL_LIBRARY=$(ROOT:\=/)/library + $(DEBUGGER) $(TCLSH) $(SCRIPT) + +setup: + @if not exist $(OUT_DIR)\nul mkdir $(OUT_DIR) + @if not exist $(TMP_DIR)\nul mkdir $(TMP_DIR) + +!if !$(STATIC_BUILD) +$(TCLIMPLIB): $(TCLLIB) +!endif + +$(TCLLIB): $(TCLOBJS) +!if $(STATIC_BUILD) + $(lib32) -nologo $(LINKERFLAGS) -out:$@ @<< +$** +<< +!else + $(link32) $(dlllflags) -base:@$(WINDIR)\coffbase.txt,tcl -out:$@ \ + $(baselibs) @<< +$** +<< + $(_VC_MANIFEST_EMBED_DLL) +!endif + +$(TCLSTUBLIB): $(TCLSTUBOBJS) + $(lib32) -nologo $(LINKERFLAGS) -nodefaultlib -out:$@ $(TCLSTUBOBJS) + +$(TCLSH): $(TCLSHOBJS) $(TCLSTUBLIB) $(TCLIMPLIB) + $(link32) $(conlflags) -stack:2300000 -out:$@ $(baselibs) $** + $(_VC_MANIFEST_EMBED_EXE) + +$(TCLTEST): $(TCLTESTOBJS) $(TCLSTUBLIB) $(TCLIMPLIB) + $(link32) $(conlflags) -stack:2300000 -out:$@ $(baselibs) $** + $(_VC_MANIFEST_EMBED_EXE) + +!if $(STATIC_BUILD) +$(TCLDDELIB): $(TMP_DIR)\tclWinDde.obj + $(lib32) -nologo $(LINKERFLAGS) -out:$@ $** +!else +$(TCLDDELIB): $(TMP_DIR)\tclWinDde.obj $(TCLSTUBLIB) + $(link32) $(dlllflags) -base:@$(WINDIR)\coffbase.txt,tcldde -out:$@ \ + $** $(baselibs) + $(_VC_MANIFEST_EMBED_DLL) +!endif + +!if $(STATIC_BUILD) +$(TCLREGLIB): $(TMP_DIR)\tclWinReg.obj + $(lib32) -nologo $(LINKERFLAGS) -out:$@ $** +!else +$(TCLREGLIB): $(TMP_DIR)\tclWinReg.obj $(TCLSTUBLIB) + $(link32) $(dlllflags) -base:@$(WINDIR)\coffbase.txt,tclreg -out:$@ \ + $** $(baselibs) + $(_VC_MANIFEST_EMBED_DLL) +!endif + +pkgs: + @for /d %d in ($(PKGSDIR)\*) do \ + @if exist "%~fd\win\makefile.vc" ( \ + pushd "%~fd\win" & \ + $(MAKE) -$(MAKEFLAGS) -f makefile.vc TCLDIR=$(ROOT) &\ + popd \ + ) + +test-pkgs: + @for /d %d in ($(PKGSDIR)\*) do \ + @if exist "%~fd\win\makefile.vc" ( \ + pushd "%~fd\win" & \ + $(MAKE) -$(MAKEFLAGS) -f makefile.vc TCLDIR=$(ROOT) test &\ + popd \ + ) + +install-pkgs: + @for /d %d in ($(PKGSDIR)\*) do \ + @if exist "%~fd\win\makefile.vc" ( \ + pushd "%~fd\win" & \ + $(MAKE) -$(MAKEFLAGS) -f makefile.vc TCLDIR=$(ROOT) install &\ + popd \ + ) + +clean-pkgs: + @for /d %d in ($(PKGSDIR)\*) do \ + @if exist "%~fd\win\makefile.vc" ( \ + pushd "%~fd\win" & \ + $(MAKE) -$(MAKEFLAGS) -f makefile.vc TCLDIR=$(ROOT) clean &\ + popd \ + ) + +$(CAT32): $(WINDIR)\cat.c + $(cc32) $(CON_CFLAGS) -Fo$(TMP_DIR)\ $? + $(link32) $(conlflags) -out:$@ -stack:16384 $(TMP_DIR)\cat.obj \ + $(baselibs) + $(_VC_MANIFEST_EMBED_EXE) + +#--------------------------------------------------------------------- +# Regenerate the stubs files. [Development use only] +#--------------------------------------------------------------------- + +genstubs: +!if !exist($(TCLSH)) + @echo Build tclsh first! +!else + $(TCLSH) $(TOOLSDIR:\=/)/genStubs.tcl $(GENERICDIR:\=/) \ + $(GENERICDIR:\=/)/tcl.decls $(GENERICDIR:\=/)/tclInt.decls \ + $(GENERICDIR:\=/)/tclTomMath.decls + $(TCLSH) $(TOOLSDIR:\=/)/genStubs.tcl $(GENERICDIR:\=/) \ + $(GENERICDIR:\=/)/tclOO.decls +!endif + + +#---------------------------------------------------------------------- +# The following target generates the file generic/tclTomMath.h. +# It needs to be run (and the results checked) after updating +# to a new release of libtommath. +#---------------------------------------------------------------------- + +gentommath_h: +!if !exist($(TCLSH)) + @echo Build tclsh first! +!else + $(TCLSH) "$(TOOLSDIR:\=/)/fix_tommath_h.tcl" \ + "$(TOMMATHDIR:\=/)/tommath.h" \ + > "$(GENERICDIR)\tclTomMath.h" +!endif + +#--------------------------------------------------------------------- +# Build the Windows HTML help file. +#--------------------------------------------------------------------- + +# NOTE: you can define HHC on the command-line to override this +!ifndef HHC +HHC=""%ProgramFiles%\HTML Help Workshop\hhc.exe"" +!endif +HTMLDIR=$(OUT_DIR)\html +HTMLBASE=TclTk$(VERSION) +HHPFILE=$(HTMLDIR)\$(HTMLBASE).hhp +CHMFILE=$(HTMLDIR)\$(HTMLBASE).chm + +htmlhelp: chmsetup $(CHMFILE) + +$(CHMFILE): $(DOCDIR)\* + @$(TCLSH) $(TOOLSDIR)\tcltk-man2html.tcl "--htmldir=$(HTMLDIR)" + @echo Compiling HTML help project + -$(HHC) <<$(HHPFILE) >NUL +[OPTIONS] +Compatibility=1.1 or later +Compiled file=$(HTMLBASE).chm +Default topic=contents.htm +Display compile progress=no +Error log file=$(HTMLBASE).log +Full-text search=Yes +Language=0x409 English (United States) +Title=Tcl/Tk $(DOT_VERSION) Help +[FILES] +contents.htm +docs.css +Keywords\*.htm +TclCmd\*.htm +TclLib\*.htm +TkCmd\*.htm +TkLib\*.htm +UserCmd\*.htm +<< + +chmsetup: + @if not exist $(HTMLDIR)\nul mkdir $(HTMLDIR) + +#------------------------------------------------------------------------- +# Build the old-style Windows .hlp file +#------------------------------------------------------------------------- + +TCLHLPBASE = $(PROJECT)$(VERSION) +HELPFILE = $(OUT_DIR)\$(TCLHLPBASE).hlp +HELPCNT = $(OUT_DIR)\$(TCLHLPBASE).cnt +DOCTMP_DIR = $(OUT_DIR)\$(PROJECT)_docs +HELPRTF = $(DOCTMP_DIR)\$(PROJECT).rtf +MAN2HELP = $(DOCTMP_DIR)\man2help.tcl +MAN2HELP2 = $(DOCTMP_DIR)\man2help2.tcl +INDEX = $(DOCTMP_DIR)\index.tcl +BMP = $(DOCTMP_DIR)\feather.bmp +BMP_NOPATH = feather.bmp +MAN2TCL = $(DOCTMP_DIR)\man2tcl.exe + +winhelp: docsetup $(HELPFILE) + +docsetup: + @if not exist $(DOCTMP_DIR)\nul mkdir $(DOCTMP_DIR) + +$(MAN2HELP) $(MAN2HELP2) $(INDEX) $(BMP): $(TOOLSDIR)\$$(@F) + @$(CPY) $(TOOLSDIR)\$(@F) $(@D) + +$(HELPFILE): $(HELPRTF) $(BMP) + cd $(DOCTMP_DIR) + start /wait hcrtf.exe -x <<$(PROJECT).hpj +[OPTIONS] +COMPRESS=12 Hall Zeck +LCID=0x409 0x0 0x0 ; English (United States) +TITLE=Tcl/Tk Reference Manual +BMROOT=. +CNT=$(@B).cnt +HLP=$(@B).hlp + +[FILES] +$(PROJECT).rtf + +[WINDOWS] +main="Tcl/Tk Reference Manual",,27648,(r15263976),(r65535) + +[CONFIG] +BrowseButtons() +CreateButton(1, "Web", ExecFile("http://www.tcl.tk")) +CreateButton(2, "SF", ExecFile("http://sf.net/projects/tcl")) +CreateButton(3, "Wiki", ExecFile("http://wiki.tcl.tk")) +CreateButton(4, "FAQ", ExecFile("http://www.purl.org/NET/Tcl-FAQ/")) +<< + cd $(MAKEDIR) + @$(CPY) "$(DOCTMP_DIR)\$(@B).hlp" "$(OUT_DIR)" + @$(CPY) "$(DOCTMP_DIR)\$(@B).cnt" "$(OUT_DIR)" + +$(MAN2TCL): $(TOOLSDIR)\$$(@B).c + $(cc32) $(TCL_CFLAGS) -Fo$(@D)\ $(TOOLSDIR)\$(@B).c + $(link32) $(conlflags) -out:$@ -stack:16384 $(@D)\man2tcl.obj + $(_VC_MANIFEST_EMBED_EXE) + +$(HELPRTF): $(MAN2TCL) $(MAN2HELP) $(MAN2HELP2) $(INDEX) $(DOCDIR)\* + $(TCLSH) $(MAN2HELP) -bitmap $(BMP_NOPATH) $(PROJECT) $(VERSION) $(DOCDIR:\=/) + +install-docs: +!if exist("$(CHMFILE)") + @echo Installing compiled HTML help + @$(CPY) "$(CHMFILE)" "$(DOC_INSTALL_DIR)\" +!endif +!if exist("$(HELPFILE)") + @echo Installing Windows help + @$(CPY) "$(HELPFILE)" "$(DOC_INSTALL_DIR)\" + @$(CPY) "$(HELPCNT)" "$(DOC_INSTALL_DIR)\" +!endif + +#--------------------------------------------------------------------- +# Build tclConfig.sh for the TEA build system. +#--------------------------------------------------------------------- + +tclConfig: $(OUT_DIR)\tclConfig.sh + +$(OUT_DIR)\tclConfig.sh: $(WINDIR)\tclConfig.sh.in + @echo Creating tclConfig.sh + @nmakehlp -s << $** >$@ +@TCL_DLL_FILE@ $(TCLLIBNAME) +@TCL_VERSION@ $(DOTVERSION) +@TCL_MAJOR_VERSION@ $(TCL_MAJOR_VERSION) +@TCL_MINOR_VERSION@ $(TCL_MINOR_VERSION) +@TCL_PATCH_LEVEL@ $(TCL_PATCH_LEVEL) +@CC@ $(CC) +@DEFS@ $(TCL_CFLAGS) +@CFLAGS_DEBUG@ -nologo -c -W3 -YX -Fp$(TMP_DIR)\ -MDd +@CFLAGS_OPTIMIZE@ -nologo -c -W3 -YX -Fp$(TMP_DIR)\ -MD +@LDFLAGS_DEBUG@ -nologo -machine:$(MACHINE) -debug -debugtype:cv +@LDFLAGS_OPTIMIZE@ -nologo -machine:$(MACHINE) -release -opt:ref -opt:icf,3 +@TCL_DBGX@ $(SUFX) +@TCL_LIB_FILE@ $(PROJECT)$(VERSION)$(SUFX).lib +@TCL_NEEDS_EXP_FILE@ +@LIBS@ $(baselibs) +@prefix@ $(_INSTALLDIR) +@exec_prefix@ $(BIN_INSTALL_DIR) +@SHLIB_CFLAGS@ +@STLIB_CFLAGS@ +@CFLAGS_WARNING@ -W3 +@EXTRA_CFLAGS@ -YX +@SHLIB_LD@ $(link32) $(dlllflags) +@STLIB_LD@ $(lib32) -nologo +@SHLIB_LD_LIBS@ $(baselibs) +@SHLIB_SUFFIX@ .dll +@DL_LIBS@ +@LDFLAGS@ +@TCL_CC_SEARCH_FLAGS@ +@TCL_LD_SEARCH_FLAGS@ +@LIBOBJS@ +@RANLIB@ +@TCL_LIB_FLAG@ +@TCL_BUILD_LIB_SPEC@ +@TCL_LIB_SPEC@ $(LIB_INSTALL_DIR)\$(PROJECT)$(VERSION)$(SUFX).lib +@TCL_INCLUDE_SPEC@ -I$(INCLUDE_INSTALL_DIR) +@TCL_LIB_VERSIONS_OK@ +@TCL_SRC_DIR@ $(ROOT) +@TCL_PACKAGE_PATH@ +@TCL_STUB_LIB_FILE@ $(TCLSTUBLIBNAME) +@TCL_STUB_LIB_FLAG@ $(TCLSTUBLIBNAME) +@TCL_STUB_LIB_SPEC@ -L$(LIB_INSTALL_DIR) $(TCLSTUBLIBNAME) +@TCL_THREADS@ $(TCL_THREADS) +@TCL_BUILD_STUB_LIB_SPEC@ -L$(OUT_DIR) $(TCLSTUBLIBNAME) +@TCL_BUILD_STUB_LIB_PATH@ $(TCLSTUBLIB) +@TCL_STUB_LIB_PATH@ $(LIB_INSTALL_DIR)\$(TCLSTUBLIBNAME) +@CFG_TCL_EXPORT_FILE_SUFFIX@ $(VERSION)$(SUFX).lib +@CFG_TCL_SHARED_LIB_SUFFIX@ $(VERSION)$(SUFX).dll +@CFG_TCL_UNSHARED_LIB_SUFFIX@ $(VERSION)$(SUFX).lib +!if $(STATIC_BUILD) +@TCL_SHARED_BUILD@ 0 +!else +@TCL_SHARED_BUILD@ 1 +!endif +<< + + +#--------------------------------------------------------------------- +# The following target generates the file generic/tclDate.c +# from the yacc grammar found in generic/tclGetDate.y. This is +# only run by hand as yacc is not available in all environments. +# The name of the .c file is different than the name of the .y file +# so that make doesn't try to automatically regenerate the .c file. +#--------------------------------------------------------------------- + +gendate: + bison --output-file=$(GENERICDIR)/tclDate.c \ + --name-prefix=TclDate \ + $(GENERICDIR)/tclGetDate.y + +#--------------------------------------------------------------------- +# Special case object file targets +#--------------------------------------------------------------------- + +$(TMP_DIR)\testMain.obj: $(WINDIR)\tclAppInit.c + $(cc32) $(TCL_CFLAGS) -DTCL_TEST \ + -DTCL_USE_STATIC_PACKAGES=$(TCL_USE_STATIC_PACKAGES) \ + -Fo$@ $? + +$(TMP_DIR)\tclMain2.obj: $(GENERICDIR)\tclMain.c + $(cc32) $(TCL_CFLAGS) -DBUILD_tcl -DTCL_ASCII_MAIN \ + -Fo$@ $? + +$(TMP_DIR)\tclTest.obj: $(GENERICDIR)\tclTest.c + $(cc32) $(TCL_CFLAGS) -Fo$@ $? + +$(TMP_DIR)\tclTestObj.obj: $(GENERICDIR)\tclTestObj.c + $(cc32) $(TCL_CFLAGS) -Fo$@ $? + +$(TMP_DIR)\tclWinTest.obj: $(WINDIR)\tclWinTest.c + $(cc32) $(TCL_CFLAGS) -Fo$@ $? + +$(TMP_DIR)\tclZlib.obj: $(GENERICDIR)\tclZlib.c + $(cc32) $(TCL_CFLAGS) -I$(COMPATDIR)\zlib -DBUILD_tcl -Fo$@ $? + +$(TMP_DIR)\tclPkgConfig.obj: $(GENERICDIR)\tclPkgConfig.c + $(cc32) -DBUILD_tcl $(TCL_CFLAGS) \ + -DCFG_INSTALL_LIBDIR="\"$(LIB_INSTALL_DIR:\=\\)\"" \ + -DCFG_INSTALL_BINDIR="\"$(BIN_INSTALL_DIR:\=\\)\"" \ + -DCFG_INSTALL_SCRDIR="\"$(SCRIPT_INSTALL_DIR:\=\\)\"" \ + -DCFG_INSTALL_INCDIR="\"$(INCLUDE_INSTALL_DIR:\=\\)\"" \ + -DCFG_INSTALL_DOCDIR="\"$(DOC_INSTALL_DIR:\=\\)\"" \ + -DCFG_RUNTIME_LIBDIR="\"$(LIB_INSTALL_DIR:\=\\)\"" \ + -DCFG_RUNTIME_BINDIR="\"$(BIN_INSTALL_DIR:\=\\)\"" \ + -DCFG_RUNTIME_SCRDIR="\"$(SCRIPT_INSTALL_DIR:\=\\)\"" \ + -DCFG_RUNTIME_INCDIR="\"$(INCLUDE_INSTALL_DIR:\=\\)\"" \ + -DCFG_RUNTIME_DOCDIR="\"$(DOC_INSTALL_DIR:\=\\)\"" \ + -Fo$@ $? + +$(TMP_DIR)\tclAppInit.obj: $(WINDIR)\tclAppInit.c + $(cc32) $(TCL_CFLAGS) \ + -DTCL_USE_STATIC_PACKAGES=$(TCL_USE_STATIC_PACKAGES) \ + -Fo$@ $? + +### The following objects should be built using the stub interfaces +### *ALL* extensions need to built with -DTCL_THREADS=1 + +$(TMP_DIR)\tclWinReg.obj: $(WINDIR)\tclWinReg.c +!if $(STATIC_BUILD) + $(cc32) $(TCL_CFLAGS) -DTCL_THREADS=1 -DSTATIC_BUILD -Fo$@ $? +!else + $(cc32) $(TCL_CFLAGS) -DTCL_THREADS=1 -DUSE_TCL_STUBS -Fo$@ $? +!endif + + +$(TMP_DIR)\tclWinDde.obj: $(WINDIR)\tclWinDde.c +!if $(STATIC_BUILD) + $(cc32) $(TCL_CFLAGS) -DTCL_THREADS=1 -DSTATIC_BUILD -Fo$@ $? +!else + $(cc32) $(TCL_CFLAGS) -DTCL_THREADS=1 -DUSE_TCL_STUBS -Fo$@ $? +!endif + + +### The following objects are part of the stub library and should not +### be built as DLL objects. -Zl is used to avoid a dependency on any +### specific C run-time. + +$(TMP_DIR)\tclStubLib.obj: $(GENERICDIR)\tclStubLib.c + $(cc32) $(STUB_CFLAGS) -Zl -DSTATIC_BUILD $(TCL_INCLUDES) -Fo$@ $? + +$(TMP_DIR)\tclTomMathStubLib.obj: $(GENERICDIR)\tclTomMathStubLib.c + $(cc32) $(STUB_CFLAGS) -Zl -DSTATIC_BUILD $(TCL_INCLUDES) -Fo$@ $? + +$(TMP_DIR)\tclOOStubLib.obj: $(GENERICDIR)\tclOOStubLib.c + $(cc32) $(STUB_CFLAGS) -Zl -DSTATIC_BUILD $(TCL_INCLUDES) -Fo$@ $? + +$(TMP_DIR)\tclsh.exe.manifest: $(WINDIR)\tclsh.exe.manifest.in + @nmakehlp -s << $** >$@ +@MACHINE@ $(MACHINE:IX86=X86) +@TCL_WIN_VERSION@ $(DOTVERSION).0.0 +<< + +#--------------------------------------------------------------------- +# Generate the source dependencies. Having dependency rules will +# improve incremental build accuracy without having to resort to a +# full rebuild just because some non-global header file like +# tclCompile.h was changed. These rules aren't needed when building +# from scratch. +#--------------------------------------------------------------------- + +depend: +!if !exist($(TCLSH)) + @echo Build tclsh first! +!else + $(TCLSH) $(TOOLSDIR:\=/)/mkdepend.tcl -vc32 -out:"$(OUT_DIR)\depend.mk" \ + -passthru:"-DBUILD_tcl $(TCL_INCLUDES)" $(GENERICDIR),$$(GENERICDIR) \ + $(COMPATDIR),$$(COMPATDIR) $(TOMMATHDIR),$$(TOMMATHDIR) $(WINDIR),$$(WINDIR) @<< +$(TCLOBJS) +<< +!endif + +#--------------------------------------------------------------------- +# Dependency rules +#--------------------------------------------------------------------- + +!if exist("$(OUT_DIR)\depend.mk") +!include "$(OUT_DIR)\depend.mk" +!message *** Dependency rules in use. +!else +!message *** Dependency rules are not being used. +!endif + +### add a spacer in the output +!message + + +#--------------------------------------------------------------------- +# Implicit rules. A limitation exists with nmake that requires that +# source directory can not contain spaces in the path. This an +# absolute. +#--------------------------------------------------------------------- + +{$(WINDIR)}.c{$(TMP_DIR)}.obj:: + $(cc32) $(TCL_CFLAGS) -DBUILD_tcl -Fo$(TMP_DIR)\ @<< +$< +<< + +{$(TOMMATHDIR)}.c{$(TMP_DIR)}.obj:: + $(cc32) $(TCL_CFLAGS) -DBUILD_tcl -Fo$(TMP_DIR)\ @<< +$< +<< + +{$(GENERICDIR)}.c{$(TMP_DIR)}.obj:: + $(cc32) $(TCL_CFLAGS) -DBUILD_tcl -Fo$(TMP_DIR)\ @<< +$< +<< + +{$(COMPATDIR)}.c{$(TMP_DIR)}.obj:: + $(cc32) $(TCL_CFLAGS) -DBUILD_tcl -Fo$(TMP_DIR)\ @<< +$< +<< + +{$(COMPATDIR)\zlib}.c{$(TMP_DIR)}.obj:: + $(cc32) $(TCL_CFLAGS) -DBUILD_tcl -Fo$(TMP_DIR)\ @<< +$< +<< + +{$(WINDIR)}.rc{$(TMP_DIR)}.res: + $(rc32) -fo $@ -r -i "$(GENERICDIR)" -i "$(TMP_DIR)" \ + -d DEBUG=$(DEBUG) -d UNCHECKED=$(UNCHECKED) \ + -d TCL_THREADS=$(TCL_THREADS) \ + -d STATIC_BUILD=$(STATIC_BUILD) \ + $< + +$(TMP_DIR)\tclsh.res: $(TMP_DIR)\tclsh.exe.manifest + +.SUFFIXES: +.SUFFIXES:.c .rc + + +#--------------------------------------------------------------------- +# Installation. +#--------------------------------------------------------------------- + +install-binaries: + @echo Installing to '$(_INSTALLDIR)' + @echo Installing $(TCLLIBNAME) +!if "$(TCLLIB)" != "$(TCLIMPLIB)" + @$(CPY) "$(TCLLIB)" "$(BIN_INSTALL_DIR)\" +!endif + @$(CPY) "$(TCLIMPLIB)" "$(LIB_INSTALL_DIR)\" +!if exist($(TCLSH)) + @echo Installing $(TCLSHNAME) + @$(CPY) "$(TCLSH)" "$(BIN_INSTALL_DIR)\" +!endif + @echo Installing $(TCLSTUBLIBNAME) + @$(CPY) "$(TCLSTUBLIB)" "$(LIB_INSTALL_DIR)\" + +#" emacs fix + +install-libraries: tclConfig install-msgs install-tzdata + @if not exist "$(SCRIPT_INSTALL_DIR)$(NULL)" \ + $(MKDIR) "$(SCRIPT_INSTALL_DIR)" + @if not exist "$(SCRIPT_INSTALL_DIR)\..\tcl8$(NULL)" \ + $(MKDIR) "$(SCRIPT_INSTALL_DIR)\..\tcl8" + @if not exist "$(SCRIPT_INSTALL_DIR)\..\tcl8\8.4$(NULL)" \ + $(MKDIR) "$(SCRIPT_INSTALL_DIR)\..\tcl8\8.4" + @if not exist "$(SCRIPT_INSTALL_DIR)\..\tcl8\8.4\platform$(NULL)" \ + $(MKDIR) "$(SCRIPT_INSTALL_DIR)\..\tcl8\8.4\platform" + @if not exist "$(SCRIPT_INSTALL_DIR)\..\tcl8\8.5$(NULL)" \ + $(MKDIR) "$(SCRIPT_INSTALL_DIR)\..\tcl8\8.5" + @if not exist "$(SCRIPT_INSTALL_DIR)\..\tcl8\8.6$(NULL)" \ + $(MKDIR) "$(SCRIPT_INSTALL_DIR)\..\tcl8\8.6" + @echo Installing header files + @$(CPY) "$(GENERICDIR)\tcl.h" "$(INCLUDE_INSTALL_DIR)\" + @$(CPY) "$(GENERICDIR)\tclDecls.h" "$(INCLUDE_INSTALL_DIR)\" + @$(CPY) "$(GENERICDIR)\tclOO.h" "$(INCLUDE_INSTALL_DIR)\" + @$(CPY) "$(GENERICDIR)\tclOODecls.h" "$(INCLUDE_INSTALL_DIR)\" + @$(CPY) "$(GENERICDIR)\tclPlatDecls.h" "$(INCLUDE_INSTALL_DIR)\" + @$(CPY) "$(GENERICDIR)\tclTomMath.h" "$(INCLUDE_INSTALL_DIR)\" + @$(CPY) "$(GENERICDIR)\tclTomMathDecls.h" "$(INCLUDE_INSTALL_DIR)\" + @$(CPY) "$(TOMMATHDIR)\tommath_class.h" "$(INCLUDE_INSTALL_DIR)\" + @$(CPY) "$(TOMMATHDIR)\tommath_superclass.h" "$(INCLUDE_INSTALL_DIR)\" + @echo Installing library files to $(SCRIPT_INSTALL_DIR) + @$(CPY) "$(ROOT)\library\history.tcl" "$(SCRIPT_INSTALL_DIR)\" + @$(CPY) "$(ROOT)\library\init.tcl" "$(SCRIPT_INSTALL_DIR)\" + @$(CPY) "$(ROOT)\library\clock.tcl" "$(SCRIPT_INSTALL_DIR)\" + @$(CPY) "$(ROOT)\library\tm.tcl" "$(SCRIPT_INSTALL_DIR)\" + @$(CPY) "$(ROOT)\library\parray.tcl" "$(SCRIPT_INSTALL_DIR)\" + @$(CPY) "$(ROOT)\library\safe.tcl" "$(SCRIPT_INSTALL_DIR)\" + @$(CPY) "$(ROOT)\library\tclIndex" "$(SCRIPT_INSTALL_DIR)\" + @$(CPY) "$(ROOT)\library\package.tcl" "$(SCRIPT_INSTALL_DIR)\" + @$(CPY) "$(ROOT)\library\word.tcl" "$(SCRIPT_INSTALL_DIR)\" + @$(CPY) "$(ROOT)\library\auto.tcl" "$(SCRIPT_INSTALL_DIR)\" + @$(CPY) "$(OUT_DIR)\tclConfig.sh" "$(LIB_INSTALL_DIR)\" + @$(CPY) "$(WINDIR)\tclooConfig.sh" "$(LIB_INSTALL_DIR)\" + @echo Installing library http1.0 directory + @$(CPY) "$(ROOT)\library\http1.0\*.tcl" \ + "$(SCRIPT_INSTALL_DIR)\http1.0\" + @echo Installing library opt0.4 directory + @$(CPY) "$(ROOT)\library\opt\*.tcl" \ + "$(SCRIPT_INSTALL_DIR)\opt0.4\" + @echo Installing package http $(PKG_HTTP_VER) as a Tcl Module + @$(COPY) "$(ROOT)\library\http\http.tcl" \ + "$(SCRIPT_INSTALL_DIR)\..\tcl8\8.6\http-$(PKG_HTTP_VER).tm" + @echo Installing package msgcat $(PKG_MSGCAT_VER) as a Tcl Module + @$(COPY) "$(ROOT)\library\msgcat\msgcat.tcl" \ + "$(SCRIPT_INSTALL_DIR)\..\tcl8\8.5\msgcat-$(PKG_MSGCAT_VER).tm" + @echo Installing package tcltest $(PKG_TCLTEST_VER) as a Tcl Module + @$(COPY) "$(ROOT)\library\tcltest\tcltest.tcl" \ + "$(SCRIPT_INSTALL_DIR)\..\tcl8\8.5\tcltest-$(PKG_TCLTEST_VER).tm" + @echo Installing package platform $(PKG_PLATFORM_VER) as a Tcl Module + @$(COPY) "$(ROOT)\library\platform\platform.tcl" \ + "$(SCRIPT_INSTALL_DIR)\..\tcl8\8.4\platform-$(PKG_PLATFORM_VER).tm" + @echo Installing package platform::shell $(PKG_SHELL_VER) as a Tcl Module + @$(COPY) "$(ROOT)\library\platform\shell.tcl" \ + "$(SCRIPT_INSTALL_DIR)\..\tcl8\8.4\platform\shell-$(PKG_SHELL_VER).tm" + @echo Installing $(TCLDDELIBNAME) +!if $(STATIC_BUILD) +!if !$(TCL_USE_STATIC_PACKAGES) + @$(CPY) "$(TCLDDELIB)" "$(LIB_INSTALL_DIR)\" +!endif +!else + @$(CPY) "$(TCLDDELIB)" "$(LIB_INSTALL_DIR)\dde$(DDEDOTVERSION)\" + @$(CPY) "$(ROOT)\library\dde\pkgIndex.tcl" \ + "$(LIB_INSTALL_DIR)\dde$(DDEDOTVERSION)\" +!endif + @echo Installing $(TCLREGLIBNAME) +!if $(STATIC_BUILD) +!if !$(TCL_USE_STATIC_PACKAGES) + @$(CPY) "$(TCLREGLIB)" "$(LIB_INSTALL_DIR)\" +!endif +!else + @$(CPY) "$(TCLREGLIB)" "$(LIB_INSTALL_DIR)\reg$(REGDOTVERSION)\" + @$(CPY) "$(ROOT)\library\reg\pkgIndex.tcl" \ + "$(LIB_INSTALL_DIR)\reg$(REGDOTVERSION)\" +!endif + @echo Installing encodings + @$(CPY) "$(ROOT)\library\encoding\*.enc" \ + "$(SCRIPT_INSTALL_DIR)\encoding\" + +#" emacs fix + +install-tzdata: + @echo Installing time zone data + @set TCL_LIBRARY=$(ROOT:\=/)/library + @$(TCLSH_NATIVE) "$(ROOT:\=/)/tools/installData.tcl" \ + "$(ROOT:\=/)/library/tzdata" "$(SCRIPT_INSTALL_DIR)/tzdata" + +install-msgs: + @echo Installing message catalogs + @set TCL_LIBRARY=$(ROOT:\=/)/library + @$(TCLSH_NATIVE) "$(ROOT:\=/)/tools/installData.tcl" \ + "$(ROOT:\=/)/library/msgs" "$(SCRIPT_INSTALL_DIR)/msgs" + +#--------------------------------------------------------------------- +# Clean up +#--------------------------------------------------------------------- + +tidy: +!if "$(TCLLIB)" != "$(TCLIMPLIB)" + @echo Removing $(TCLLIB) ... + @if exist $(TCLLIB) del $(TCLLIB) +!endif + @echo Removing $(TCLIMPLIB) ... + @if exist $(TCLIMPLIB) del $(TCLIMPLIB) + @echo Removing $(TCLSH) ... + @if exist $(TCLSH) del $(TCLSH) + @echo Removing $(TCLTEST) ... + @if exist $(TCLTEST) del $(TCLTEST) + @echo Removing $(TCLDDELIB) ... + @if exist $(TCLDDELIB) del $(TCLDDELIB) + @echo Removing $(TCLREGLIB) ... + @if exist $(TCLREGLIB) del $(TCLREGLIB) + +clean: clean-pkgs + @echo Cleaning $(TMP_DIR)\* ... + @if exist $(TMP_DIR)\nul $(RMDIR) $(TMP_DIR) + @echo Cleaning $(WINDIR)\nmakehlp.obj ... + @if exist $(WINDIR)\nmakehlp.obj del $(WINDIR)\nmakehlp.obj + @echo Cleaning $(WINDIR)\nmakehlp.exe ... + @if exist $(WINDIR)\nmakehlp.exe del $(WINDIR)\nmakehlp.exe + @echo Cleaning $(WINDIR)\nmhlp-out.txt ... + @if exist $(WINDIR)\nmhlp-out.txt del $(WINDIR)\nmhlp-out.txt + @echo Cleaning $(WINDIR)\_junk.pch ... + @if exist $(WINDIR)\_junk.pch del $(WINDIR)\_junk.pch + @echo Cleaning $(WINDIR)\vercl.x ... + @if exist $(WINDIR)\vercl.x del $(WINDIR)\vercl.x + @echo Cleaning $(WINDIR)\vercl.i ... + @if exist $(WINDIR)\vercl.i del $(WINDIR)\vercl.i + @echo Cleaning $(WINDIR)\versions.vc ... + @if exist $(WINDIR)\versions.vc del $(WINDIR)\versions.vc + +realclean: hose + +hose: + @echo Hosing $(OUT_DIR)\* ... + @if exist $(OUT_DIR)\nul $(RMDIR) $(OUT_DIR) + +# Local Variables: +# mode: makefile +# End: -- cgit v0.12 From 67a242e0031c5c5108446b9fc1801d8dec548e70 Mon Sep 17 00:00:00 2001 From: dgp Date: Mon, 12 Mar 2018 13:48:35 +0000 Subject: msgcat 1.7 uses [tailcall], so requires Tcl 8.6. --- library/msgcat/msgcat.tcl | 2 +- library/msgcat/pkgIndex.tcl | 3 ++- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/library/msgcat/msgcat.tcl b/library/msgcat/msgcat.tcl index 33ff5cb..203a1bf 100644 --- a/library/msgcat/msgcat.tcl +++ b/library/msgcat/msgcat.tcl @@ -11,7 +11,7 @@ # See the file "license.terms" for information on usage and redistribution # of this file, and for a DISCLAIMER OF ALL WARRANTIES. -package require Tcl 8.5- +package require Tcl 8.6- # When the version number changes, be sure to update the pkgIndex.tcl file, # and the installation directory in the Makefiles. package provide msgcat 1.7.0 diff --git a/library/msgcat/pkgIndex.tcl b/library/msgcat/pkgIndex.tcl index fe3b3a1..74a284f 100644 --- a/library/msgcat/pkgIndex.tcl +++ b/library/msgcat/pkgIndex.tcl @@ -1,2 +1,3 @@ -if {![package vsatisfies [package provide Tcl] 8.5-]} {return} +if {![package vsatisfies [package provide Tcl] 8.5]} {return} +if {![package vsatisfies [package provide Tcl] 8.6-]} {return} package ifneeded msgcat 1.7.0 [list source [file join $dir msgcat.tcl]] -- cgit v0.12 From f35817ce5a0a1eaf1e96e6e4c46aa3f744301221 Mon Sep 17 00:00:00 2001 From: dgp Date: Mon, 12 Mar 2018 14:07:26 +0000 Subject: Undo setting of execute permissions. --- changes | 0 library/msgcat/msgcat.tcl | 0 library/msgcat/pkgIndex.tcl | 0 tests/msgcat.test | 0 unix/Makefile.in | 0 win/Makefile.in | 0 6 files changed, 0 insertions(+), 0 deletions(-) mode change 100755 => 100644 changes mode change 100755 => 100644 library/msgcat/msgcat.tcl mode change 100755 => 100644 library/msgcat/pkgIndex.tcl mode change 100755 => 100644 tests/msgcat.test mode change 100755 => 100644 unix/Makefile.in mode change 100755 => 100644 win/Makefile.in diff --git a/changes b/changes old mode 100755 new mode 100644 diff --git a/library/msgcat/msgcat.tcl b/library/msgcat/msgcat.tcl old mode 100755 new mode 100644 diff --git a/library/msgcat/pkgIndex.tcl b/library/msgcat/pkgIndex.tcl old mode 100755 new mode 100644 diff --git a/tests/msgcat.test b/tests/msgcat.test old mode 100755 new mode 100644 diff --git a/unix/Makefile.in b/unix/Makefile.in old mode 100755 new mode 100644 diff --git a/win/Makefile.in b/win/Makefile.in old mode 100755 new mode 100644 -- cgit v0.12 From 8bd4a8cf2c0d70bf09729c5f6b203b75f0e6fd52 Mon Sep 17 00:00:00 2001 From: dgp Date: Mon, 12 Mar 2018 14:41:20 +0000 Subject: Revert change that broke usage with Tcl 9 --- library/msgcat/pkgIndex.tcl | 1 - 1 file changed, 1 deletion(-) diff --git a/library/msgcat/pkgIndex.tcl b/library/msgcat/pkgIndex.tcl index 74a284f..2feb9c6 100644 --- a/library/msgcat/pkgIndex.tcl +++ b/library/msgcat/pkgIndex.tcl @@ -1,3 +1,2 @@ -if {![package vsatisfies [package provide Tcl] 8.5]} {return} if {![package vsatisfies [package provide Tcl] 8.6-]} {return} package ifneeded msgcat 1.7.0 [list source [file join $dir msgcat.tcl]] -- cgit v0.12 From 2ae2445072e3f52e56fa916fae2fbb21ac5629d0 Mon Sep 17 00:00:00 2001 From: dgp Date: Mon, 12 Mar 2018 15:57:54 +0000 Subject: msgcat 1.7.0 features need foundation of Tcl 8.7. --- library/msgcat/msgcat.tcl | 3 ++- library/msgcat/pkgIndex.tcl | 2 +- unix/Makefile.in | 2 +- win/Makefile.in | 2 +- win/makefile.vc | 2 +- 5 files changed, 6 insertions(+), 5 deletions(-) diff --git a/library/msgcat/msgcat.tcl b/library/msgcat/msgcat.tcl index 96b0110..50a9064 100644 --- a/library/msgcat/msgcat.tcl +++ b/library/msgcat/msgcat.tcl @@ -11,7 +11,8 @@ # See the file "license.terms" for information on usage and redistribution # of this file, and for a DISCLAIMER OF ALL WARRANTIES. -package require Tcl 8.6- +# We use oo::define::self, which is new in Tcl 8.7 +package require Tcl 8.7- # When the version number changes, be sure to update the pkgIndex.tcl file, # and the installation directory in the Makefiles. package provide msgcat 1.7.0 diff --git a/library/msgcat/pkgIndex.tcl b/library/msgcat/pkgIndex.tcl index 2feb9c6..3309a30 100644 --- a/library/msgcat/pkgIndex.tcl +++ b/library/msgcat/pkgIndex.tcl @@ -1,2 +1,2 @@ -if {![package vsatisfies [package provide Tcl] 8.6-]} {return} +if {![package vsatisfies [package provide Tcl] 8.7-]} {return} package ifneeded msgcat 1.7.0 [list source [file join $dir msgcat.tcl]] diff --git a/unix/Makefile.in b/unix/Makefile.in index 9c9ee53..83a8aed 100644 --- a/unix/Makefile.in +++ b/unix/Makefile.in @@ -852,7 +852,7 @@ install-libraries: libraries $(INSTALL_DATA) $$i "$(SCRIPT_INSTALL_DIR)"/opt0.4; \ done; @echo "Installing package msgcat 1.7.0 as a Tcl Module"; - @$(INSTALL_DATA) $(TOP_DIR)/library/msgcat/msgcat.tcl "$(SCRIPT_INSTALL_DIR)"/../tcl8/8.6/msgcat-1.7.0.tm; + @$(INSTALL_DATA) $(TOP_DIR)/library/msgcat/msgcat.tcl "$(SCRIPT_INSTALL_DIR)"/../tcl8/8.7/msgcat-1.7.0.tm; @echo "Installing package tcltest 2.4.1 as a Tcl Module"; @$(INSTALL_DATA) $(TOP_DIR)/library/tcltest/tcltest.tcl "$(SCRIPT_INSTALL_DIR)"/../tcl8/8.5/tcltest-2.4.1.tm; diff --git a/win/Makefile.in b/win/Makefile.in index 1a72fc7..56ccb4d 100644 --- a/win/Makefile.in +++ b/win/Makefile.in @@ -661,7 +661,7 @@ install-libraries: libraries install-tzdata install-msgs $(COPY) "$$j" "$(SCRIPT_INSTALL_DIR)/opt0.4"; \ done; @echo "Installing package msgcat 1.7.0 as a Tcl Module"; - @$(COPY) $(ROOT_DIR)/library/msgcat/msgcat.tcl $(SCRIPT_INSTALL_DIR)/../tcl8/8.6/msgcat-1.7.0.tm; + @$(COPY) $(ROOT_DIR)/library/msgcat/msgcat.tcl $(SCRIPT_INSTALL_DIR)/../tcl8/8.7/msgcat-1.7.0.tm; @echo "Installing package tcltest 2.4.0 as a Tcl Module"; @$(COPY) $(ROOT_DIR)/library/tcltest/tcltest.tcl $(SCRIPT_INSTALL_DIR)/../tcl8/8.5/tcltest-2.4.0.tm; @echo "Installing package platform 1.0.14 as a Tcl Module"; diff --git a/win/makefile.vc b/win/makefile.vc index 11b15a3..7ed4c63 100644 --- a/win/makefile.vc +++ b/win/makefile.vc @@ -869,7 +869,7 @@ install-libraries: tclConfig tcl-nmake install-msgs install-tzdata "$(SCRIPT_INSTALL_DIR)\..\tcl8\8.6\http-$(PKG_HTTP_VER).tm" @echo Installing package msgcat $(PKG_MSGCAT_VER) as a Tcl Module @$(COPY) "$(ROOT)\library\msgcat\msgcat.tcl" \ - "$(SCRIPT_INSTALL_DIR)\..\tcl8\8.5\msgcat-$(PKG_MSGCAT_VER).tm" + "$(SCRIPT_INSTALL_DIR)\..\tcl8\8.7\msgcat-$(PKG_MSGCAT_VER).tm" @echo Installing package tcltest $(PKG_TCLTEST_VER) as a Tcl Module @$(COPY) "$(ROOT)\library\tcltest\tcltest.tcl" \ "$(SCRIPT_INSTALL_DIR)\..\tcl8\8.5\tcltest-$(PKG_TCLTEST_VER).tm" -- cgit v0.12 From 23178bb2087e384cb320634e4974b3dc6104eb89 Mon Sep 17 00:00:00 2001 From: dgp Date: Tue, 13 Mar 2018 03:15:28 +0000 Subject: Tidy up and comment [string replace] and its corner cases. --- generic/tclCmdMZ.c | 29 +++++++++++++++++++++-------- tests/string.test | 6 ++++++ 2 files changed, 27 insertions(+), 8 deletions(-) diff --git a/generic/tclCmdMZ.c b/generic/tclCmdMZ.c index 30586b1..706d71c 100644 --- a/generic/tclCmdMZ.c +++ b/generic/tclCmdMZ.c @@ -2262,7 +2262,7 @@ StringRplcCmd( Tcl_Obj *const objv[]) /* Argument objects. */ { Tcl_UniChar *ustring; - int first, last, length; + int first, last, length, end; if (objc < 4 || objc > 5) { Tcl_WrongNumArgs(interp, 1, objv, "string first last ?string?"); @@ -2270,20 +2270,33 @@ StringRplcCmd( } ustring = Tcl_GetUnicodeFromObj(objv[1], &length); - length--; + end = length - 1; - if (TclGetIntForIndexM(interp, objv[2], length, &first) != TCL_OK || - TclGetIntForIndexM(interp, objv[3], length, &last) != TCL_OK){ + if (TclGetIntForIndexM(interp, objv[2], end, &first) != TCL_OK || + TclGetIntForIndexM(interp, objv[3], end, &last) != TCL_OK){ return TCL_ERROR; } - if ((last < first) || (last < 0) || (first > length)) { + /* + * The following test screens out most empty substrings as + * candidates for replacement. When they are detected, no + * replacement is done, and the result is the original string, + */ + if ((last < 0) || /* Range ends before start of string */ + (first > end) || /* Range begins after end of string */ + (last < first)) { /* Range begins after it starts */ + + /* + * BUT!!! when (end < 0) -- an empty original string -- we can + * have (first <= end < 0 <= last) and an empty string is permitted + * to be replaced. + */ Tcl_SetObjResult(interp, objv[1]); } else { Tcl_Obj *resultPtr; ustring = Tcl_GetUnicodeFromObj(objv[1], &length); - length--; + end = length-1; if (first < 0) { first = 0; @@ -2293,9 +2306,9 @@ StringRplcCmd( if (objc == 5) { Tcl_AppendObjToObj(resultPtr, objv[4]); } - if (last < length) { + if (last < end) { Tcl_AppendUnicodeToObj(resultPtr, ustring + last + 1, - length - last); + end - last); } Tcl_SetObjResult(interp, resultPtr); } diff --git a/tests/string.test b/tests/string.test index 39abd86..f3bb366 100644 --- a/tests/string.test +++ b/tests/string.test @@ -1294,6 +1294,12 @@ test string-14.16 {string replace} { test string-14.17 {string replace} { string replace abcdefghijklmnop end end-1 } {abcdefghijklmnop} +test string-14.18 {string replace} { + string replace abcdefghijklmnop 10 9 XXX +} {abcdefghijklmnop} +test string-14.19 {string replace} { + string replace {} -1 0 A +} A test string-15.1 {string tolower too few args} { list [catch {string tolower} msg] $msg -- cgit v0.12 From debafda1e72e4b9c63b64dce27e4948c7f448ebc Mon Sep 17 00:00:00 2001 From: dgp Date: Tue, 13 Mar 2018 04:01:03 +0000 Subject: Repair the INST_STR_REPLACE instruction. --- generic/tclExecute.c | 25 ++++++++++++++----------- 1 file changed, 14 insertions(+), 11 deletions(-) diff --git a/generic/tclExecute.c b/generic/tclExecute.c index ef64ac1..2ef627d 100644 --- a/generic/tclExecute.c +++ b/generic/tclExecute.c @@ -5701,18 +5701,18 @@ TEBCresume( { Tcl_UniChar *ustring1, *ustring2, *ustring3, *end, *p; - int length3; + int length3, endIdx; Tcl_Obj *value3Ptr; case INST_STR_REPLACE: value3Ptr = POP_OBJECT(); valuePtr = OBJ_AT_DEPTH(2); - length = Tcl_GetCharLength(valuePtr) - 1; + endIdx = Tcl_GetCharLength(valuePtr) - 1; TRACE(("\"%.20s\" %s %s \"%.20s\" => ", O2S(valuePtr), O2S(OBJ_UNDER_TOS), O2S(OBJ_AT_TOS), O2S(value3Ptr))); - if (TclGetIntForIndexM(interp, OBJ_UNDER_TOS, length, + if (TclGetIntForIndexM(interp, OBJ_UNDER_TOS, endIdx, &fromIdx) != TCL_OK - || TclGetIntForIndexM(interp, OBJ_AT_TOS, length, + || TclGetIntForIndexM(interp, OBJ_AT_TOS, endIdx, &toIdx) != TCL_OK) { TclDecrRefCount(value3Ptr); TRACE_ERROR(interp); @@ -5722,21 +5722,24 @@ TEBCresume( (void) POP_OBJECT(); TclDecrRefCount(OBJ_AT_TOS); (void) POP_OBJECT(); - if (fromIdx < 0) { - fromIdx = 0; - } - if (fromIdx > toIdx || fromIdx > length) { + if ((toIdx < 0) || + (fromIdx > endIdx) || + (toIdx < fromIdx)) { TRACE_APPEND(("\"%.30s\"\n", O2S(valuePtr))); TclDecrRefCount(value3Ptr); NEXT_INST_F(1, 0, 0); } - if (toIdx > length) { - toIdx = length; + if (fromIdx < 0) { + fromIdx = 0; + } + + if (toIdx > endIdx) { + toIdx = endIdx; } - if (fromIdx == 0 && toIdx == length) { + if (fromIdx == 0 && toIdx == endIdx) { TclDecrRefCount(OBJ_AT_TOS); OBJ_AT_TOS = value3Ptr; TRACE_APPEND(("\"%.30s\"\n", O2S(value3Ptr))); -- cgit v0.12 From 962427e8cd982fd685ca30f221083da2e7b62cea Mon Sep 17 00:00:00 2001 From: oehhar Date: Tue, 13 Mar 2018 14:53:16 +0000 Subject: tip490 oo for msgcat: added documentation --- changes | 2 +- doc/msgcat.n | 107 +++++++++++++++++++++++++++++++++++++++++++--- library/msgcat/msgcat.tcl | 4 +- 3 files changed, 103 insertions(+), 10 deletions(-) diff --git a/changes b/changes index feed968..01d4c7a 100644 --- a/changes +++ b/changes @@ -8882,5 +8882,5 @@ in this changeset (new minor version) rather than bug fixes: 2018-03-12 (TIP 490) add oo support for msgcat => msgcat 1.7.0 (oehlmann) -2018-03-12 (TIP 499) custom locale preference list (nijtmans) +2018-03-12 (TIP 499) custom locale preference list (oehlmann) => msgcat 1.7.0 diff --git a/doc/msgcat.n b/doc/msgcat.n index 2fc1eee..fbea20f 100644 --- a/doc/msgcat.n +++ b/doc/msgcat.n @@ -11,9 +11,9 @@ .SH NAME msgcat \- Tcl message catalog .SH SYNOPSIS -\fBpackage require Tcl 8.5\fR +\fBpackage require Tcl 8.7\fR .sp -\fBpackage require msgcat 1.6\fR +\fBpackage require msgcat 1.7\fR .sp \fB::msgcat::mc \fIsrc-string\fR ?\fIarg arg ...\fR? .sp @@ -23,6 +23,10 @@ msgcat \- Tcl message catalog \fB::msgcat::mcexists\fR ?\fB-exactnamespace\fR? ?\fB-exactlocale\fR? \fIsrc-string\fR .VE "TIP 412" .sp +.VS "TIP 490" +\fB::msgcat::mcpackagenamespaceget\fR +.VE "TIP 490" +.sp \fB::msgcat::mclocale \fR?\fInewLocale\fR? .sp \fB::msgcat::mcpreferences\fR @@ -71,6 +75,11 @@ In \fBmsgcat\fR, there is a global locale initialized by the system locale of th Each package may decide to use the global locale or to use a package specific locale. .PP The global locale may be changed on demand, for example by a user initiated language change or within a multi user application like a web server. +.PP +.VS tip490 +Object oriented programming is supported by the use of a package namespace. +.VE tip490 +.PP .SH COMMANDS .TP \fB::msgcat::mc \fIsrc-string\fR ?\fIarg arg ...\fR? @@ -95,6 +104,17 @@ use the result. If an application is written for a single language in this fashion, then it is easy to add support for additional languages later simply by defining new message catalog entries. .RE +.VS "TIP 490" +.TP +\fB::msgcat::mcn \fInamespace\fR \fIsrc-string\fR ?\fIarg arg ...\fR? +. +Like \fB::msgcat::mc\fR, but with the message namespace specified as first argument. +.PP +.RS +\fBmcn\fR may be used for cases where the package namespace is not the namespace of the caller. +An example is shown within the description of the command \fB::msgcat::mcpackagenamespaceget\fR below. +.RE +.PP .TP \fB::msgcat::mcmax ?\fIsrc-string src-string ...\fR? . @@ -103,17 +123,49 @@ of the longest translated string. This is useful when designing localized GUIs, which may require that all buttons, for example, be a fixed width (which will be the width of the widest button). .TP -\fB::msgcat::mcexists\fR ?\fB-exactnamespace\fR? ?\fB-exactlocale\fR? \fIsrc-string\fR -. .VS "TIP 412" +\fB::msgcat::mcexists\fR ?\fB-exactnamespace\fR? ?\fB-exactlocale\fR? ?\fB-namespace\fR \fInamespace\fR? \fIsrc-string\fR +. Return true, if there is a translation for the given \fIsrc-string\fR. .PP .RS The search may be limited by the option \fB\-exactnamespace\fR to only check the current namespace and not any parent namespaces. .PP It may also be limited by the option \fB\-exactlocale\fR to only check the first prefered locale (e.g. first element returned by \fB::msgcat::mcpreferences\fR if global locale is used). -.RE +.PP .VE "TIP 412" +.VS "TIP 490" +An explicit package namespace may be specified by the option \fB-namespace\fR. +The namespace of the caller is used if not explicitly specified. +.RE +.PP +.VE "TIP 490" +.VS "TIP 490" +.TP +\fB::msgcat::mcpackagenamespaceget\fR +. +Return the package namespace of the caller. +This command handles all cases described in section \fBObject oriented programming\fR. +.PP +.RS +Example usage is a tooltip package, which saves the caller package namespace to update the translation each time the tooltip is shown: +.CS +proc ::tooltip::tooltip {widget message} { + ... + set messagenamespace [uplevel 1 {::msgcat::mcpackagenamespaceget}] + ... + bind $widget [list ::tooltip::show $widget $messagenamespace $message] +} + +proc ::tooltip::show {widget messagenamespace message} { + ... + set message [::msgcat::mcn $messagenamespace $message] + ... +} +.CE +.RE +.PP +.VE "TIP 490" .TP \fB::msgcat::mclocale \fR?\fInewLocale\fR? . @@ -563,7 +615,7 @@ A generic unknown handler is used if set to the empty string. This consists in r See section \fBcallback invocation\fR below. The appended arguments are identical to \fB::msgcat::mcunknown\fR. .RE -.SS Callback invocation +.SH Callback invocation A package may decide to register one or multiple callbacks, as described above. .PP Callbacks are invoked, if: @@ -577,7 +629,48 @@ Callbacks are invoked, if: If a called routine fails with an error, the \fBbgerror\fR routine for the interpreter is invoked after command completion. Only exception is the callback \fBunknowncmd\fR, where an error causes the invoking \fBmc\fR-command to fail with that error. .PP -.SS Examples +.VS tip490 +.SH Object oriented programming +\fBmsgcat\fR supports packages implemented by object oriented programming. +Objects and classes should be defined within a package namespace. +.PP +There are 3 supported cases where package namespace sensitive commands of msgcat (\fBmc\fR, \fBmcexists\fR, \fBmcpackagelocale\fR, \fBmcforgetpackage\fR, \fBmcpackagenamespaceget\fR, \fBmcpackageconfig\fR, \fBmcset\fR and \fBmcmset\fR) may be called: +.PP +.SH 1) In class definition script +\fBmsgcat\fR command is called within a class definition script. +.CS +namespace eval ::N2 { + mcload $dir/msgs + oo::class create C1 {puts [mc Hi!]} +} +.CE +.PP +.SH 2) method defined in a class +\fBmsgcat\fR command is called from a method in an object and the method is defined in a class. +.CS +namespace eval ::N3Class { + mcload $dir/msgs + oo::class create C1 + oo::define C1 method m1 { + puts [mc Hi!] + } +} +.CE +.PP +.SH 3) method defined in a classless object +\fBmsgcat\fR command is called from a method of a classless object. +.CS +namespace eval ::N4 { + mcload $dir/msgs + oo::object create O1 + oo::objdefine O1 method m1 {} { + puts [mc Hi!] + } +} +.CE +.PP +.VE tip490 +.SH Examples Packages which display a GUI may update their widgets when the global locale changes. To register to a callback, use: .CS diff --git a/library/msgcat/msgcat.tcl b/library/msgcat/msgcat.tcl index 50a9064..100f425 100644 --- a/library/msgcat/msgcat.tcl +++ b/library/msgcat/msgcat.tcl @@ -4,7 +4,7 @@ # message catalog facility for Tcl programs. It should be # loaded with the command "package require msgcat". # -# Copyright (c) 2010-2015 by Harald Oehlmann. +# Copyright (c) 2010-2018 by Harald Oehlmann. # Copyright (c) 1998-2000 by Ajuba Solutions. # Copyright (c) 1998 by Mark Harrison. # @@ -1218,7 +1218,7 @@ proc msgcat::mcutil::ConvertLocale {value} { # - called from a classless oo object proc ::msgcat::PackageNamespaceGet {} { uplevel 2 { - # Check for no object + # Check self namespace to determine environment switch -exact -- [namespace which self] { {::oo::define::self} { # We are within a class definition -- cgit v0.12 From a275b8a5ea188f0633caab60b3ab709de4239f1f Mon Sep 17 00:00:00 2001 From: dgp Date: Tue, 13 Mar 2018 16:03:39 +0000 Subject: Rewrite the [string replace] compiler to take advantage of the richer set of encoded index values. --- generic/tclCompCmdsSZ.c | 241 +++++++++++++++++++++++++++++------------------- 1 file changed, 145 insertions(+), 96 deletions(-) diff --git a/generic/tclCompCmdsSZ.c b/generic/tclCompCmdsSZ.c index e84f382..c13376b 100644 --- a/generic/tclCompCmdsSZ.c +++ b/generic/tclCompCmdsSZ.c @@ -995,148 +995,197 @@ TclCompileStringReplaceCmd( * compiled. */ CompileEnv *envPtr) /* Holds the resulting instructions. */ { - Tcl_Token *tokenPtr, *valueTokenPtr, *replacementTokenPtr = NULL; + Tcl_Token *tokenPtr, *valueTokenPtr; DefineLineInformation; /* TIP #280 */ - int idx1, idx2; + int first, last; if (parsePtr->numWords < 4 || parsePtr->numWords > 5) { return TCL_ERROR; } + + /* Bytecode to compute/push string argument being replaced */ valueTokenPtr = TokenAfter(parsePtr->tokenPtr); - if (parsePtr->numWords == 5) { - tokenPtr = TokenAfter(valueTokenPtr); - tokenPtr = TokenAfter(tokenPtr); - replacementTokenPtr = TokenAfter(tokenPtr); - } - goto genericReplace; + CompileWord(envPtr, valueTokenPtr, interp, 1); + /* + * Check for first index known and useful at compile time. + */ tokenPtr = TokenAfter(valueTokenPtr); - if (TclGetIndexFromToken(tokenPtr, TCL_INDEX_START, TCL_INDEX_AFTER, - &idx1) != TCL_OK) { + if (TclGetIndexFromToken(tokenPtr, TCL_INDEX_BEFORE, TCL_INDEX_AFTER, + &first) != TCL_OK) { goto genericReplace; } + /* - * Token parsed as an index value. Indices before the string are - * treated as index of start of string. + * Check for last index known and useful at compile time. */ - tokenPtr = TokenAfter(tokenPtr); - if (TclGetIndexFromToken(tokenPtr, TCL_INDEX_BEFORE, TCL_INDEX_END, - &idx2) != TCL_OK) { + if (TclGetIndexFromToken(tokenPtr, TCL_INDEX_BEFORE, TCL_INDEX_AFTER, + &last) != TCL_OK) { goto genericReplace; } - /* - * Token parsed as an index value. Indices after the string are - * treated as index of end of string. - */ -/* TODO...... */ - /* - * We handle these replacements specially: first character (where - * idx1=idx2=0) and last character (where idx1=idx2=TCL_INDEX_END). Anything - * else and the semantics get rather screwy. + /* + * [string replace] is an odd bird. For many arguments it is + * a conventional substring replacer. However it also goes out + * of its way to become a no-op for many cases where it would be + * replacing an empty substring. Precisely, it is a no-op when * - * TODO: These seem to be very narrow cases. They are not even - * covered by the test suite, and any programming that ends up - * here could have been coded by the programmer using [string range] - * and [string cat]. [*] Not clear at all to me that the bytecode - * generated here is worthwhile. + * (last < first) OR + * (last < 0) OR + * (end < first) * - * [*] Except for the empty string exceptions. UGGGGHHHH. + * For some compile-time values we can detect these cases, and + * compile direct to bytecode implementing the no-op. */ - if (idx1 == 0 && idx2 == 0) { - int notEq, end; + if ((last == TCL_INDEX_BEFORE) /* Know (last < 0) */ + || (first == TCL_INDEX_AFTER) /* Know (first > end) */ /* - * Just working with the first character. + * Tricky to determine when runtime (last < first) can be + * certainly known based on the encoded values. Consider the + * cases... + * + * (first <= TCL_INDEX_END) && + * (last == TCL_INDEX_AFTER) => cannot tell REJECT + * (last <= TCL_INDEX END) && (last < first) => ACCEPT + * else => cannot tell REJECT */ - - CompileWord(envPtr, valueTokenPtr, interp, 1); - if (replacementTokenPtr == NULL) { - /* Drop first */ - OP44( STR_RANGE_IMM, 1, TCL_INDEX_END); - return TCL_OK; - } - /* Replace first */ - CompileWord(envPtr, replacementTokenPtr, interp, 4); - + || ((first <= TCL_INDEX_END) && (last <= TCL_INDEX_END) + && (last < first)) /* Know (last < first) */ /* - * NOTE: The following tower of bullshit is present because - * [string replace] was boneheadedly defined not to replace - * empty strings, so we actually have to detect the empty - * string case and treat it differently. + * (first == TCL_INDEX_BEFORE) && + * (last == TCL_INDEX_AFTER) => (first < last) REJECT + * (last <= TCL_INDEX_END) => cannot tell REJECT + * else => (first < last) REJECT + * + * else [[first >= TCL_INDEX_START]] && + * (last == TCL_INDEX_AFTER) => cannot tell REJECT + * (last <= TCL_INDEX_END) => cannot tell REJECT + * else [[last >= TCL_INDEX START]] && (last < first) => ACCEPT */ - - OP4( OVER, 1); - PUSH( ""); - OP( STR_EQ); - JUMP1( JUMP_FALSE, notEq); - OP( POP); - JUMP1( JUMP, end); - FIXJUMP1(notEq); - TclAdjustStackDepth(1, envPtr); - OP4( REVERSE, 2); - OP44( STR_RANGE_IMM, 1, TCL_INDEX_END); - OP1( STR_CONCAT1, 2); - FIXJUMP1(end); + || ((first >= TCL_INDEX_START) && (last >= TCL_INDEX_START) + && (last < first))) { /* Know (last < first) */ + if (parsePtr->numWords == 5) { + tokenPtr = TokenAfter(tokenPtr); + CompileWord(envPtr, tokenPtr, interp, 4); + OP( POP); /* Pop newString */ + } + /* Original string argument now on TOS as result */ return TCL_OK; + } - } else if (idx1 == TCL_INDEX_END && idx2 == TCL_INDEX_END) { - int notEq, end; - - /* - * Just working with the last character. - */ + if (parsePtr->numWords == 5) { + /* + * When we have a string replacement, we have to take care about + * not replacing empty substrings that [string replace] promises + * not to replace + * + * The remaining index values might be suitable for conventional + * string replacement, but only if they cannot possibly meet the + * conditions described above at runtime. If there's a chance they + * might, we would have to emit bytecode to check and at that point + * we're paying more in bytecode execution time than would make + * things worthwhile. Trouble is we are very limited in + * how much we can detect that at compile time. After decoding, + * we need, first: + * + * (first <= end) + * + * The encoded indices (first <= TCL_INDEX END) and + * (first == TCL_INDEX_BEFORE) always meets this condition, but + * any other encoded first index has some list for which it fails. + * + * We also need, second: + * + * (last >= 0) + * + * The encoded indices (last >= TCL_INDEX_START) and + * (last == TCL_INDEX_AFTER) always meet this condition but any + * other encoded last index has some list for which it fails. + * + * Finally we need, third: + * + * (first <= last) + * + * Considered in combination with the constraints we already have, + * we see that we can proceed when (first == TCL_INDEX_BEFORE) + * or (last == TCL_INDEX_AFTER). These also permit simplification + * of the prefix|replace|suffix construction. The other constraints, + * though, interfere with getting a guarantee that first <= last. + */ - CompileWord(envPtr, valueTokenPtr, interp, 1); - if (replacementTokenPtr == NULL) { - /* Drop last */ - OP44( STR_RANGE_IMM, 0, TCL_INDEX_END-1); - return TCL_OK; + if ((first == TCL_INDEX_BEFORE) && (last >= TCL_INDEX_START)) { + /* empty prefix */ + tokenPtr = TokenAfter(tokenPtr); + CompileWord(envPtr, tokenPtr, interp, 4); + OP4( REVERSE, 2); + if (last == TCL_INDEX_AFTER) { + OP( POP); /* Pop original */ + } else { + OP44( STR_RANGE_IMM, last + 1, TCL_INDEX_END); + OP1( STR_CONCAT1, 2); } - /* Replace last */ - CompileWord(envPtr, replacementTokenPtr, interp, 4); - - /* More bullshit; see NOTE above. */ + return TCL_OK; + } - OP4( OVER, 1); - PUSH( ""); - OP( STR_EQ); - JUMP1( JUMP_FALSE, notEq); - OP( POP); - JUMP1( JUMP, end); - FIXJUMP1(notEq); - TclAdjustStackDepth(1, envPtr); - OP4( REVERSE, 2); - OP44( STR_RANGE_IMM, 0, TCL_INDEX_END-1); - OP4( REVERSE, 2); + if ((last == TCL_INDEX_AFTER) && (first <= TCL_INDEX_END)) { + OP44( STR_RANGE_IMM, 0, first-1); + tokenPtr = TokenAfter(tokenPtr); + CompileWord(envPtr, tokenPtr, interp, 4); OP1( STR_CONCAT1, 2); - FIXJUMP1(end); return TCL_OK; + } + + /* FLOW THROUGH TO genericReplace */ } else { - /* - * Need to process indices at runtime. This could be because the - * indices are not constants, or because we need to resolve them to - * absolute indices to work out if a replacement is going to happen. - * In any case, to runtime it is. + /* + * When we have no replacement string to worry about, we may + * have more luck, because the forbidden empty string replacements + * are harmless when they are replaced by another empty string. */ + if ((first == TCL_INDEX_BEFORE) || (first == TCL_INDEX_START)) { + /* empty prefix - build suffix only */ + + if ((last == TCL_INDEX_END) || (last == TCL_INDEX_AFTER)) { + /* empty suffix too => empty result */ + OP( POP); /* Pop original */ + PUSH ( ""); + return TCL_OK; + } + OP44( STR_RANGE_IMM, last + 1, TCL_INDEX_END); + return TCL_OK; + } else { + if ((last == TCL_INDEX_END) || (last == TCL_INDEX_AFTER)) { + /* empty suffix - build prefix only */ + OP44( STR_RANGE_IMM, 0, first-1); + return TCL_OK; + } + OP( DUP); + OP44( STR_RANGE_IMM, 0, first-1); + OP4( REVERSE, 2); + OP44( STR_RANGE_IMM, last + 1, TCL_INDEX_END); + OP1( STR_CONCAT1, 2); + return TCL_OK; + } + } + genericReplace: - CompileWord(envPtr, valueTokenPtr, interp, 1); tokenPtr = TokenAfter(valueTokenPtr); CompileWord(envPtr, tokenPtr, interp, 2); tokenPtr = TokenAfter(tokenPtr); CompileWord(envPtr, tokenPtr, interp, 3); - if (replacementTokenPtr != NULL) { - CompileWord(envPtr, replacementTokenPtr, interp, 4); + if (parsePtr->numWords == 5) { + tokenPtr = TokenAfter(tokenPtr); + CompileWord(envPtr, tokenPtr, interp, 4); } else { PUSH( ""); } OP( STR_REPLACE); return TCL_OK; - } } int -- cgit v0.12 From bbae63cfa9695583ae13a24a1bf42d5931bbb116 Mon Sep 17 00:00:00 2001 From: oehhar Date: Tue, 13 Mar 2018 16:13:02 +0000 Subject: tip 499 msgcat custom preferences: documentation added --- doc/msgcat.n | 112 +++++++++++++++++++++++++++++++++++++++++++++-------------- 1 file changed, 85 insertions(+), 27 deletions(-) diff --git a/doc/msgcat.n b/doc/msgcat.n index fbea20f..9074725 100644 --- a/doc/msgcat.n +++ b/doc/msgcat.n @@ -29,7 +29,9 @@ msgcat \- Tcl message catalog .sp \fB::msgcat::mclocale \fR?\fInewLocale\fR? .sp -\fB::msgcat::mcpreferences\fR +.VS "TIP 499" +\fB::msgcat::mcpreferences\fR ?\fIlocale preference\fR? ... +.VE "TIP 499" .sp .VS "TIP 412" \fB::msgcat::mcloadedlocales subcommand\fR ?\fIlocale\fR? @@ -54,6 +56,10 @@ msgcat \- Tcl message catalog .sp \fB::msgcat::mcforgetpackage\fR .VE "TIP 412" +.sp +.VS "TIP 499" +\fB::msgcat::mcutil subcommand\fR ?\fIlocale\fR? +.VS "TIP 499" .BE .SH DESCRIPTION .PP @@ -145,7 +151,7 @@ The namespace of the caller is used if not explicitly specified. \fB::msgcat::mcpackagenamespaceget\fR . Return the package namespace of the caller. -This command handles all cases described in section \fBObject oriented programming\fR. +This command handles all cases described in section \fBOBJECT ORIENTED PROGRAMMING\fR. .PP .RS Example usage is a tooltip package, which saves the caller package namespace to update the translation each time the tooltip is shown: @@ -169,14 +175,22 @@ proc ::tooltip::show {widget messagenamespace message} { .TP \fB::msgcat::mclocale \fR?\fInewLocale\fR? . -This function sets the locale to \fInewLocale\fR. If \fInewLocale\fR -is omitted, the current locale is returned, otherwise the current locale -is set to \fInewLocale\fR. msgcat stores and compares the locale in a +If \fInewLocale\fR is omitted, the current locale is returned, otherwise the current locale +is set to \fInewLocale\fR. +.PP +.RS +If the new locale is set to \fInewLocale\fR, the corresponding preferences are calculated and set. +For example, if the current locale is en_US_funky, then \fB::msgcat::mcpreferences\fR returns \fB{en_us_funky en_us en {}}\fR. +.PP +The same result may be acheved by \fB::msgcat::mcpreferences\fR {*}[\fB::msgcat::mcutil getpreferences\fR \fInewLocale\fR]. +.PP +The current locale is always the first element of the list returned by \fBmcpreferences\fR. +.PP +msgcat stores and compares the locale in a case-insensitive manner, and returns locales in lowercase. The initial locale is determined by the locale specified in the user's environment. See \fBLOCALE SPECIFICATION\fR below for a description of the locale string format. -.RS .PP .VS "TIP 412" If the locale is set, the preference list of locales is evaluated. @@ -184,16 +198,26 @@ Locales in this list are loaded now, if not jet loaded. .VE "TIP 412" .RE .TP -\fB::msgcat::mcpreferences\fR +\fB::msgcat::mcpreferences\fR ?\fIlocale preference\fR? ... . -Returns an ordered list of the locales preferred by -the user, based on the user's language specification. -The list is ordered from most specific to least -preference. The list is derived from the current -locale set in msgcat by \fB::msgcat::mclocale\fR, and -cannot be set independently. For example, if the -current locale is en_US_funky, then \fB::msgcat::mcpreferences\fR -returns \fB{en_us_funky en_us en {}}\fR. +Without arguments, returns an ordered list of the locales preferred by +the user. +The list is ordered from most specific to least preference. +.PP +.VS "TIP 499" +.RS +A set of locale preferences may be given to set the list of locale preferences. +The current locale is also set, which is the first element of the locale preferences list. +.PP +Locale preferences are loaded now, if not jet loaded. +.PP +As an example, the user may prefer French or English text. This may be configured by: +.CS +::msgcat::mcpreferences fr en {} +.CE +.RE +.PP +.VS "TIP 499" .TP \fB::msgcat:mcloadedlocales subcommand\fR ?\fIlocale\fR? . @@ -284,6 +308,22 @@ Note that this routine is only called if the concerned package did not set a pac The calling package clears all its state within the \fBmsgcat\fR package including all settings and translations. .VE "TIP 412" .PP +.VS "TIP 499" +.TP +\fB::msgcat::mcutil getpreferences\fR \fIlocale\fR +. +Return the preferences list of the given locale as described in section \fBLOCALE SPECIFICATION\fR. +An example is the composition of a preference list for the bilingual region "Biel/Bienne" as a concatenation of swiss german and swiss french: +.CS +% concat [lrange [msgcat::mcutil getpreferences fr_CH] 0 end-1] [msgcat::mcutil getpreferences de_CH] +fr_ch fr de_ch de {} +.CE +.TP +\fB::msgcat::mcutil getsystemlocale\fR +. +The system locale is returned as described by the section \fBLOCALE SPECIFICATION\fR. +.VE "TIP 499" +.PP .SH "LOCALE SPECIFICATION" .PP The locale is specified to \fBmsgcat\fR by a locale string @@ -489,7 +529,7 @@ formatting substitution is done directly. # human-oriented versions by \fBmsgcat::mcset\fR .CE .VS "TIP 412" -.SH Package private locale +.SH "PACKAGE PRIVATE LOCALE" .PP A package using \fBmsgcat\fR may choose to use its own package private locale and its own set of loaded locales, independent to the global @@ -513,10 +553,22 @@ This command may cause the load of locales. . Return the package private locale or the global locale, if no package private locale is set. .TP -\fB::msgcat::mcpackagelocale preferences\fR +\fB::msgcat::mcpackagelocale preferences\fR ?\fIlocale preference\fR? ... . -Return the package private preferences or the global preferences, +With no parameters, return the package private preferences or the global preferences, if no package private locale is set. +The package locale state (set or not) is not changed (in contrast to the command \fB::msgcat::mcpackagelocale set\fR). +.PP +.RS +.VS "TIP 499" +If a set of locale preferences is given, it is set as package locale preference list. +The package locale is set to the first element of the preference list. +A package locale is activated, if it was not set so far. +.PP +Locale preferences are loaded now for the package, if not jet loaded. +.VE "TIP 499" +.RE +.PP .TP \fB::msgcat::mcpackagelocale loaded\fR . @@ -540,7 +592,7 @@ Returns true, if the given locale is loaded for the package. . Clear any loaded locales of the package not present in the package preferences. .PP -.SH Changing package options +.SH "CHANGING PACKAGE OPTIONS" .PP Each package using msgcat has a set of options within \fBmsgcat\fR. The package options are described in the next sectionPackage options. @@ -615,7 +667,7 @@ A generic unknown handler is used if set to the empty string. This consists in r See section \fBcallback invocation\fR below. The appended arguments are identical to \fB::msgcat::mcunknown\fR. .RE -.SH Callback invocation +.SH "Callback invocation" A package may decide to register one or multiple callbacks, as described above. .PP Callbacks are invoked, if: @@ -630,13 +682,15 @@ If a called routine fails with an error, the \fBbgerror\fR routine for the inter Only exception is the callback \fBunknowncmd\fR, where an error causes the invoking \fBmc\fR-command to fail with that error. .PP .VS tip490 -.SH Object oriented programming +.SH "OBJECT ORIENTED PROGRAMMING" \fBmsgcat\fR supports packages implemented by object oriented programming. Objects and classes should be defined within a package namespace. .PP There are 3 supported cases where package namespace sensitive commands of msgcat (\fBmc\fR, \fBmcexists\fR, \fBmcpackagelocale\fR, \fBmcforgetpackage\fR, \fBmcpackagenamespaceget\fR, \fBmcpackageconfig\fR, \fBmcset\fR and \fBmcmset\fR) may be called: .PP -.SH 1) In class definition script +.TP +\fB1) In class definition script\fR +. \fBmsgcat\fR command is called within a class definition script. .CS namespace eval ::N2 { @@ -645,7 +699,9 @@ namespace eval ::N2 { } .CE .PP -.SH 2) method defined in a class +.TP +\fB2) method defined in a class\fR +. \fBmsgcat\fR command is called from a method in an object and the method is defined in a class. .CS namespace eval ::N3Class { @@ -657,7 +713,9 @@ namespace eval ::N3Class { } .CE .PP -.SH 3) method defined in a classless object +.TP +\fB3) method defined in a classless object\fR +. \fBmsgcat\fR command is called from a method of a classless object. .CS namespace eval ::N4 { @@ -670,7 +728,7 @@ namespace eval ::N4 { .CE .PP .VE tip490 -.SH Examples +.SH EXAMPLES Packages which display a GUI may update their widgets when the global locale changes. To register to a callback, use: .CS @@ -736,9 +794,9 @@ proc ::tcl::clock::LocalizeFormat { locale format } { .PP The message catalog code was developed by Mark Harrison. .SH "SEE ALSO" -format(n), scan(n), namespace(n), package(n) +format(n), scan(n), namespace(n), package(n), oo::class(n), oo::object .SH KEYWORDS -internationalization, i18n, localization, l10n, message, text, translation +internationalization, i18n, localization, l10n, message, text, translation, class, object .\" Local Variables: .\" mode: nroff .\" End: -- cgit v0.12 From 9ac074bd097e9924cd88d9fa603e507e9380c2a7 Mon Sep 17 00:00:00 2001 From: dgp Date: Tue, 13 Mar 2018 16:28:43 +0000 Subject: Fix bugs in msgcat that prevent clean test suite run. --- library/msgcat/msgcat.tcl | 2 +- tests/msgcat.test | 5 +++++ 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/library/msgcat/msgcat.tcl b/library/msgcat/msgcat.tcl index 100f425..598330d 100644 --- a/library/msgcat/msgcat.tcl +++ b/library/msgcat/msgcat.tcl @@ -1260,7 +1260,7 @@ proc msgcat::mcutil::getsystemlocale {} { # On Darwin, fallback to current CFLocale identifier if available. # if {[info exists ::tcl::mac::locale] && $::tcl::mac::locale ne ""} { - if {![catch { ConvertLocale $::tcl::mac::locale] } locale]} { + if {![catch { ConvertLocale $::tcl::mac::locale } locale]} { return $locale } } diff --git a/tests/msgcat.test b/tests/msgcat.test index 7ab9bcf..0d2f928 100644 --- a/tests/msgcat.test +++ b/tests/msgcat.test @@ -55,8 +55,13 @@ namespace eval ::msgcat::test { set result [string tolower [lindex $setVars 0]] if {[string length $result] == 0} { if {[info exists ::tcl::mac::locale]} { +if {[package vsatisfies [package provide msgcat] 1.7]} { + set result [string tolower \ + [msgcat::mcutil::ConvertLocale $::tcl::mac::locale]] +} else { set result [string tolower \ [msgcat::ConvertLocale $::tcl::mac::locale]] +} } else { if {([info sharedlibextension] eq ".dll") && ![catch {package require registry}]} { -- cgit v0.12 From 64eaafad72c1c1c0a76fb1adffb7200f79debb04 Mon Sep 17 00:00:00 2001 From: sebres Date: Tue, 13 Mar 2018 18:52:45 +0000 Subject: remove unexpected panic by TclTrimLeft/TclTrimRight, handling rewritten: - instead of check the NTS-byte after string (may cause segfault by access violation if out of range), it checks now the end-character is well-formed utf8-sequence; - both work well now on non-NTS strings (without null character at end); - additionally fixed wrong offsets (trim-length if last char malformed in case of out of range); new function TclTrim introduced (as combination of TclTrimLeft/TclTrimRight). --- generic/tclCmdMZ.c | 3 +- generic/tclInt.h | 2 + generic/tclUtil.c | 228 ++++++++++++++++++++++++++++++++++++++++------------- 3 files changed, 176 insertions(+), 57 deletions(-) diff --git a/generic/tclCmdMZ.c b/generic/tclCmdMZ.c index 30586b1..b20fffb 100644 --- a/generic/tclCmdMZ.c +++ b/generic/tclCmdMZ.c @@ -3127,8 +3127,7 @@ StringTrimCmd( } string1 = TclGetStringFromObj(objv[1], &length1); - triml = TclTrimLeft(string1, length1, string2, length2); - trimr = TclTrimRight(string1 + triml, length1 - triml, string2, length2); + triml = TclTrim(string1, length1, string2, length2, &trimr); Tcl_SetObjResult(interp, Tcl_NewStringObj(string1 + triml, length1 - triml - trimr)); diff --git a/generic/tclInt.h b/generic/tclInt.h index 25bec6a..9d60cbc 100644 --- a/generic/tclInt.h +++ b/generic/tclInt.h @@ -2747,6 +2747,8 @@ MODULE_SCOPE int TclSubstTokens(Tcl_Interp *interp, Tcl_Token *tokenPtr, int *clNextOuter, CONST char *outerScript); MODULE_SCOPE void TclTransferResult(Tcl_Interp *sourceInterp, int result, Tcl_Interp *targetInterp); +MODULE_SCOPE int TclTrim(const char *bytes, int numBytes, + const char *trim, int numTrim, int *trimRight); MODULE_SCOPE int TclTrimLeft(const char *bytes, int numBytes, const char *trim, int numTrim); MODULE_SCOPE int TclTrimRight(const char *bytes, int numBytes, diff --git a/generic/tclUtil.c b/generic/tclUtil.c index d782ea1..96ab96d 100644 --- a/generic/tclUtil.c +++ b/generic/tclUtil.c @@ -1499,9 +1499,46 @@ Tcl_Backslash( /* *---------------------------------------------------------------------- * + * TclUtfWellFormedEnd -- + * Checks the end of utf string is malformed, if yes - wraps bytes + * to the given buffer (as well-formed NTS string). + * + * Results: + * The bytes with well-formed end of the string. + * + * Side effects: + * Buffer (DString) may be allocated, so must be released. + * + *---------------------------------------------------------------------- + */ + +static inline const char* +TclUtfWellFormedEnd( + Tcl_DString *buffer, /* Buffer used to hold well-formed string. */ + CONST char *bytes, /* Pointer to the beginning of the string. */ + int length) /* Length of the string. */ +{ + CONST char *l = bytes + length; + CONST char *p = Tcl_UtfPrev(l, bytes); + + if (Tcl_UtfCharComplete(p, l - p)) { + buffer->string = buffer->staticSpace; + return bytes; + } + /* + * Malformed utf-8 end, be sure we've NTS to safe compare of end-character, + * avoid segfault by access violation out of range. + */ + Tcl_DStringInit(buffer); + Tcl_DStringAppend(buffer, bytes, length); + return Tcl_DStringValue(buffer); +} +/* + *---------------------------------------------------------------------- + * * TclTrimRight -- - * Takes two counted strings in the Tcl encoding which must both be - * null terminated. Conceptually trims from the right side of the + * Takes two counted strings in the Tcl encoding. Conceptually + * finds the sub string (offset) to trim from the right side of the * first string all characters found in the second string. * * Results: @@ -1513,8 +1550,8 @@ Tcl_Backslash( *---------------------------------------------------------------------- */ -int -TclTrimRight( +static inline int +TrimRight( const char *bytes, /* String to be trimmed... */ int numBytes, /* ...and its length in bytes */ const char *trim, /* String of trim characters... */ @@ -1523,15 +1560,6 @@ TclTrimRight( const char *p = bytes + numBytes; int pInc; - if ((bytes[numBytes] != '\0') || (trim[numTrim] != '\0')) { - Tcl_Panic("TclTrimRight works only on null-terminated strings"); - } - - /* Empty strings -> nothing to do */ - if ((numBytes == 0) || (numTrim == 0)) { - return 0; - } - /* Outer loop: iterate over string to be trimmed */ do { Tcl_UniChar ch1; @@ -1563,13 +1591,42 @@ TclTrimRight( return numBytes - (p - bytes); } + +int +TclTrimRight( + const char *bytes, /* String to be trimmed... */ + int numBytes, /* ...and its length in bytes */ + const char *trim, /* String of trim characters... */ + int numTrim) /* ...and its length in bytes */ +{ + int res; + Tcl_DString bytesBuf, trimBuf; + + /* Empty strings -> nothing to do */ + if ((numBytes == 0) || (numTrim == 0)) { + return 0; + } + + bytes = TclUtfWellFormedEnd(&bytesBuf, bytes, numBytes); + trim = TclUtfWellFormedEnd(&trimBuf, trim, numTrim); + + res = TrimRight(bytes, numBytes, trim, numTrim); + if (res > numBytes) { + res = numBytes; + } + + Tcl_DStringFree(&bytesBuf); + Tcl_DStringFree(&trimBuf); + + return res; +} /* *---------------------------------------------------------------------- * * TclTrimLeft -- - * Takes two counted strings in the Tcl encoding which must both be - * null terminated. Conceptually trims from the left side of the + * Takes two counted strings in the Tcl encoding. Conceptually + * finds the sub string (offset) to trim from the left side of the * first string all characters found in the second string. * * Results: @@ -1581,8 +1638,8 @@ TclTrimRight( *---------------------------------------------------------------------- */ -int -TclTrimLeft( +static inline int +TrimLeft( const char *bytes, /* String to be trimmed... */ int numBytes, /* ...and its length in bytes */ const char *trim, /* String of trim characters... */ @@ -1590,15 +1647,6 @@ TclTrimLeft( { const char *p = bytes; - if ((bytes[numBytes] != '\0') || (trim[numTrim] != '\0')) { - Tcl_Panic("TclTrimLeft works only on null-terminated strings"); - } - - /* Empty strings -> nothing to do */ - if ((numBytes == 0) || (numTrim == 0)) { - return 0; - } - /* Outer loop: iterate over string to be trimmed */ do { Tcl_UniChar ch1; @@ -1626,10 +1674,94 @@ TclTrimLeft( p += pInc; numBytes -= pInc; - } while (numBytes); + } while (numBytes > 0); return p - bytes; } + +int +TclTrimLeft( + const char *bytes, /* String to be trimmed... */ + int numBytes, /* ...and its length in bytes */ + const char *trim, /* String of trim characters... */ + int numTrim) /* ...and its length in bytes */ +{ + int res; + Tcl_DString bytesBuf, trimBuf; + + /* Empty strings -> nothing to do */ + if ((numBytes == 0) || (numTrim == 0)) { + return 0; + } + + bytes = TclUtfWellFormedEnd(&bytesBuf, bytes, numBytes); + trim = TclUtfWellFormedEnd(&trimBuf, trim, numTrim); + + res = TrimLeft(bytes, numBytes, trim, numTrim); + if (res > numBytes) { + res = numBytes; + } + + Tcl_DStringFree(&bytesBuf); + Tcl_DStringFree(&trimBuf); + + return res; +} + +/* + *---------------------------------------------------------------------- + * + * TclTrim -- + * Finds the sub string (offset) to trim from both sides of the + * first string all characters found in the second string. + * + * Results: + * The number of bytes to be removed from the start of the string + * + * Side effects: + * None. + * + *---------------------------------------------------------------------- + */ + +int +TclTrim( + const char *bytes, /* String to be trimmed... */ + int numBytes, /* ...and its length in bytes */ + const char *trim, /* String of trim characters... */ + int numTrim, /* ...and its length in bytes */ + int *trimRight) /* Offset from the end of the string. */ +{ + int trimLeft; + Tcl_DString bytesBuf, trimBuf; + + /* Empty strings -> nothing to do */ + if ((numBytes == 0) || (numTrim == 0)) { + return 0; + } + + bytes = TclUtfWellFormedEnd(&bytesBuf, bytes, numBytes); + trim = TclUtfWellFormedEnd(&trimBuf, trim, numTrim); + + trimLeft = TrimLeft(bytes, numBytes, trim, numTrim); + if (trimLeft > numBytes) { + trimLeft = numBytes; + } + numBytes -= trimLeft; + *trimRight = 0; + if (numBytes) { + bytes += trimLeft; + *trimRight = TrimRight(bytes, numBytes, trim, numTrim); + if (*trimRight > numBytes) { + *trimRight = numBytes; + } + } + + Tcl_DStringFree(&bytesBuf); + Tcl_DStringFree(&trimBuf); + + return trimLeft; +} /* *---------------------------------------------------------------------- @@ -1687,25 +1819,18 @@ Tcl_Concat( result = (char *) ckalloc((unsigned) (bytesNeeded + argc)); for (p = result, i = 0; i < argc; i++) { - int trim, elemLength; + int triml, trimr, elemLength; const char *element; element = argv[i]; elemLength = strlen(argv[i]); - /* Trim away the leading whitespace */ - trim = TclTrimLeft(element, elemLength, CONCAT_WS, CONCAT_WS_SIZE); - element += trim; - elemLength -= trim; - - /* - * Trim away the trailing whitespace. Do not permit trimming - * to expose a final backslash character. - */ - - trim = TclTrimRight(element, elemLength, CONCAT_WS, CONCAT_WS_SIZE); - trim -= trim && (element[elemLength - trim - 1] == '\\'); - elemLength -= trim; + /* Trim away the leading/trailing whitespace. */ + triml = TclTrim(element, elemLength, CONCAT_WS, CONCAT_WS_SIZE, &trimr); + element += triml; + elemLength -= triml + trimr; + /* Do not permit trimming to expose a final backslash character. */ + elemLength += trimr && (element[elemLength - 1] == '\\'); /* If we're left with empty element after trimming, do nothing */ if (elemLength == 0) { @@ -1832,23 +1957,16 @@ Tcl_ConcatObj( Tcl_SetObjLength(resPtr, 0); for (i = 0; i < objc; i++) { - int trim; + int triml, trimr; element = TclGetStringFromObj(objv[i], &elemLength); - /* Trim away the leading whitespace */ - trim = TclTrimLeft(element, elemLength, CONCAT_WS, CONCAT_WS_SIZE); - element += trim; - elemLength -= trim; - - /* - * Trim away the trailing whitespace. Do not permit trimming - * to expose a final backslash character. - */ - - trim = TclTrimRight(element, elemLength, CONCAT_WS, CONCAT_WS_SIZE); - trim -= trim && (element[elemLength - trim - 1] == '\\'); - elemLength -= trim; + /* Trim away the leading/trailing whitespace. */ + triml = TclTrim(element, elemLength, CONCAT_WS, CONCAT_WS_SIZE, &trimr); + element += triml; + elemLength -= triml + trimr; + /* Do not permit trimming to expose a final backslash character. */ + elemLength += trimr && (element[elemLength - 1] == '\\'); /* If we're left with empty element after trimming, do nothing */ if (elemLength == 0) { -- cgit v0.12 From 90f38b1023a10f8a5518bdcd04cb4e377d709fe9 Mon Sep 17 00:00:00 2001 From: pooryorick Date: Tue, 13 Mar 2018 20:41:23 +0000 Subject: Audit and correct Object reference counting issues. --- generic/tclOO.c | 196 ++++++++++++++++++++++++++-------------------- generic/tclOODefineCmds.c | 10 +-- tests/oo.test | 8 +- 3 files changed, 123 insertions(+), 91 deletions(-) diff --git a/generic/tclOO.c b/generic/tclOO.c index 587e46d..a129a52 100644 --- a/generic/tclOO.c +++ b/generic/tclOO.c @@ -397,28 +397,39 @@ InitFoundation( fPtr->objectCls = AllocClass(interp, AllocObject(interp, "object", (Namespace *)fPtr->ooNs, NULL)); + /* Corresponding TclOODecrRefCount in KillFoudation */ + AddRef(fPtr->objectCls->thisPtr); + + /* This is why it is unnecessary in this routine to replace the + * incremented reference count of fPtr->objectCls that was swallowed by + * fakeObject. */ + fPtr->objectCls->superclasses.num = 0; + ckfree(fPtr->objectCls->superclasses.list); + fPtr->objectCls->superclasses.list = NULL; + + /* special initialization for the primordial objects */ + fPtr->objectCls->thisPtr->flags |= ROOT_OBJECT; + fPtr->objectCls->flags |= ROOT_OBJECT; + fPtr->classCls = AllocClass(interp, AllocObject(interp, "class", (Namespace *)fPtr->ooNs, NULL)); + /* Corresponding TclOODecrRefCount in KillFoudation */ + AddRef(fPtr->classCls->thisPtr); + + /* + * Increment reference counts for each reference because these + * relationships can be dynamically changed. + * + * Corresponding TclOODecrRefCount for all incremented refcounts is in + * KillFoundation. + */ /* Rewire bootstrapped objects. */ fPtr->objectCls->thisPtr->selfCls = fPtr->classCls; - fPtr->classCls->thisPtr->selfCls = fPtr->classCls; - - AddRef(fPtr->objectCls->thisPtr); - AddRef(fPtr->classCls->thisPtr); - AddRef(fPtr->classCls->thisPtr->selfCls->thisPtr); AddRef(fPtr->objectCls->thisPtr->selfCls->thisPtr); - /* special initialization for the primordial objects */ - fPtr->objectCls->thisPtr->flags |= ROOT_OBJECT; - fPtr->objectCls->flags |= ROOT_OBJECT; - - /* This is why it is unnecessary in this routine to make up for the - * incremented reference count of fPtr->objectCls that was sallwed by - * fakeObject. */ - fPtr->objectCls->superclasses.num = 0; - ckfree(fPtr->objectCls->superclasses.list); - fPtr->objectCls->superclasses.list = NULL; + fPtr->classCls->thisPtr->selfCls = fPtr->classCls; + AddRef(fPtr->classCls->thisPtr->selfCls->thisPtr); fPtr->classCls->thisPtr->flags |= ROOT_CLASS; fPtr->classCls->flags |= ROOT_CLASS; @@ -552,20 +563,20 @@ KillFoundation( { Foundation *fPtr = GetFoundation(interp); - /* - * Crude mechanism to avoid leaking the Object struct of the - * foundation components oo::object and oo::class - * - * Should probably be replaced with something more elegantly designed. - */ - while (TclOODecrRefCount(fPtr->objectCls->thisPtr) == 0) {}; - while (TclOODecrRefCount(fPtr->classCls->thisPtr) == 0) {}; - TclDecrRefCount(fPtr->unknownMethodNameObj); TclDecrRefCount(fPtr->constructorName); TclDecrRefCount(fPtr->destructorName); TclDecrRefCount(fPtr->clonedName); TclDecrRefCount(fPtr->defineName); + if (fPtr->objectCls->thisPtr->selfCls != NULL) { + TclOODecrRefCount(fPtr->objectCls->thisPtr->selfCls->thisPtr); + } + if (fPtr->classCls->thisPtr->selfCls != NULL) { + TclOODecrRefCount(fPtr->classCls->thisPtr->selfCls->thisPtr); + } + TclOODecrRefCount(fPtr->objectCls->thisPtr); + TclOODecrRefCount(fPtr->classCls->thisPtr); + ckfree(fPtr); } @@ -649,6 +660,8 @@ AllocObject( Tcl_ResetResult(interp); } + ((Namespace *)oPtr->namespacePtr)->refCount++; + /* * Make the namespace know about the helper commands. This grants access * to the [self] and [next] commands. @@ -820,10 +833,9 @@ ObjectRenamedTrace( /* * ---------------------------------------------------------------------- * - * ReleaseClassContents -- + * DeleteDescendants -- * - * Tear down the special class data structure, including deleting all - * dependent classes and objects. + * Delete all descendants of a particular class. * * ---------------------------------------------------------------------- */ @@ -835,50 +847,79 @@ DeleteDescendants( { Class *clsPtr = oPtr->classPtr, *subclassPtr, *mixinSubclassPtr; Object *instancePtr; - int i; /* * Squelch classes that this class has been mixed into. */ - FOREACH(mixinSubclassPtr, clsPtr->mixinSubs) { - /* This condition also covers the case where mixinSubclassPtr == - * clsPtr - */ - if (!Deleted(mixinSubclassPtr->thisPtr)) { - Tcl_DeleteCommandFromToken(interp, - mixinSubclassPtr->thisPtr->command); + if (clsPtr->mixinSubs.num > 0) { + while (clsPtr->mixinSubs.num > 0) { + mixinSubclassPtr = clsPtr->mixinSubs.list[clsPtr->mixinSubs.num-1]; + /* This condition also covers the case where mixinSubclassPtr == + * clsPtr + */ + if (!Deleted(mixinSubclassPtr->thisPtr)) { + Tcl_DeleteCommandFromToken(interp, + mixinSubclassPtr->thisPtr->command); + } + TclOORemoveFromMixinSubs(mixinSubclassPtr, clsPtr); } - i -= TclOORemoveFromMixinSubs(mixinSubclassPtr, clsPtr); - TclOODecrRefCount(mixinSubclassPtr->thisPtr); + } + if (clsPtr->mixinSubs.size > 0) { + ckfree(clsPtr->mixinSubs.list); + clsPtr->mixinSubs.size = 0; } /* * Squelch subclasses of this class. */ - FOREACH(subclassPtr, clsPtr->subclasses) { - if (!Deleted(subclassPtr->thisPtr) && !IsRoot(subclassPtr)) { - Tcl_DeleteCommandFromToken(interp, subclassPtr->thisPtr->command); + 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); + } + TclOORemoveFromSubclasses(subclassPtr, clsPtr); } - i -= TclOORemoveFromSubclasses(subclassPtr, clsPtr); - TclOODecrRefCount(subclassPtr->thisPtr); + } + if (clsPtr->subclasses.size > 0) { + ckfree(clsPtr->subclasses.list); + clsPtr->subclasses.list = NULL; + clsPtr->subclasses.size = 0; } /* * Squelch instances of this class (includes objects we're mixed into). */ - if (!IsRootClass(oPtr)) { - FOREACH(instancePtr, clsPtr->instances) { + if (clsPtr->instances.num > 0) { + 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)) { Tcl_DeleteCommandFromToken(interp, instancePtr->command); } - i -= TclOORemoveFromInstances(instancePtr, clsPtr); + TclOORemoveFromInstances(instancePtr, clsPtr); } } + if (clsPtr->instances.size > 0) { + ckfree(clsPtr->instances.list); + clsPtr->instances.list = NULL; + clsPtr->instances.size = 0; + } } + +/* + * ---------------------------------------------------------------------- + * + * ReleaseClassContents -- + * + * Tear down the special class data structure, including deleting all + * dependent classes and objects. + * + * ---------------------------------------------------------------------- + */ static void ReleaseClassContents( @@ -948,21 +989,6 @@ ReleaseClassContents( } /* - * Squelch our instances. - */ - - if (clsPtr->instances.num) { - Object *oPtr; - - FOREACH(oPtr, clsPtr->instances) { - TclOODecrRefCount(oPtr); - } - ckfree(clsPtr->instances.list); - clsPtr->instances.list = NULL; - clsPtr->instances.num = 0; - } - - /* * Squelch our metadata. */ @@ -978,11 +1004,21 @@ ReleaseClassContents( clsPtr->metadataPtr = NULL; } - FOREACH(tmpClsPtr, clsPtr->mixins) { - TclOORemoveFromMixinSubs(clsPtr, tmpClsPtr); + if (clsPtr->mixins.num) { + FOREACH(tmpClsPtr, clsPtr->mixins) { + TclOORemoveFromMixinSubs(clsPtr, tmpClsPtr); + } + ckfree(clsPtr->mixins.list); } - FOREACH(tmpClsPtr, clsPtr->superclasses) { - TclOORemoveFromSubclasses(clsPtr, tmpClsPtr); + + if (clsPtr->superclasses.num > 0) { + FOREACH(tmpClsPtr, clsPtr->superclasses) { + TclOORemoveFromSubclasses(clsPtr, tmpClsPtr); + TclOODecrRefCount(tmpClsPtr->thisPtr); + } + ckfree(clsPtr->superclasses.list); + clsPtr->superclasses.num = 0; + clsPtr->superclasses.list = NULL; } FOREACH_HASH_VALUE(mPtr, &clsPtr->classMethods) { @@ -1110,10 +1146,10 @@ ObjectNamespaceDeleted( /* To do: Should this be protected with a * !IsRoot() condition? */ TclOORemoveFromInstances(oPtr, oPtr->selfCls); - FOREACH(mixinPtr, oPtr->mixins) { - i -= TclOORemoveFromInstances(oPtr, mixinPtr); - } - if (i) { + if (oPtr->mixins.num > 0) { + FOREACH(mixinPtr, oPtr->mixins) { + TclOORemoveFromInstances(oPtr, mixinPtr); + } ckfree(oPtr->mixins.list); } @@ -1185,7 +1221,9 @@ ObjectNamespaceDeleted( * Delete the object structure itself. */ + TclNsDecrRefCount((Namespace *)oPtr->namespacePtr); oPtr->namespacePtr = NULL; + TclOODecrRefCount(oPtr->selfCls->thisPtr); oPtr->selfCls = NULL; TclOODecrRefCount(oPtr); return; @@ -1204,13 +1242,7 @@ ObjectNamespaceDeleted( */ int TclOODecrRefCount(Object *oPtr) { if (oPtr->refCount-- <= 1) { - Class *clsPtr = oPtr->classPtr; if (oPtr->classPtr != NULL) { - ckfree(clsPtr->superclasses.list); - ckfree(clsPtr->subclasses.list); - ckfree(clsPtr->instances.list); - ckfree(clsPtr->mixinSubs.list); - ckfree(clsPtr->mixins.list); ckfree(oPtr->classPtr); } ckfree(oPtr); @@ -1250,9 +1282,6 @@ TclOORemoveFromInstances( { int i, res = 0; Object *instPtr; - if (Deleted(clsPtr->thisPtr)) { - return res; - } FOREACH(instPtr, clsPtr->instances) { if (oPtr == instPtr) { @@ -1315,9 +1344,6 @@ TclOORemoveFromSubclasses( { int i, res = 0; Class *subclsPtr; - if (Deleted(superPtr->thisPtr)) { - return res; - } FOREACH(subclsPtr, superPtr->subclasses) { if (subPtr == subclsPtr) { @@ -1382,10 +1408,6 @@ TclOORemoveFromMixinSubs( int i, res = 0; Class *subclsPtr; - if (Deleted(superPtr->thisPtr)) { - return res; - } - FOREACH(subclsPtr, superPtr->mixinSubs) { if (subPtr == subclsPtr) { RemoveItem(Class, superPtr->mixinSubs, i); @@ -1678,6 +1700,7 @@ TclNewObjectInstanceCommon( oPtr = AllocObject(interp, simpleName, nsPtr, nsNameStr); oPtr->selfCls = classPtr; + AddRef(classPtr->thisPtr); TclOOAddToInstances(oPtr, classPtr); /* * Check to see if we're really creating a class. If so, allocate the @@ -1914,6 +1937,11 @@ Tcl_CopyObjectInstance( cls2Ptr->superclasses.num = clsPtr->superclasses.num; FOREACH(superPtr, cls2Ptr->superclasses) { TclOOAddToSubclasses(cls2Ptr, superPtr); + + /* For the new item in cls2Ptr->superclasses that memcpy just + * created + */ + AddRef(superPtr->thisPtr); } /* diff --git a/generic/tclOODefineCmds.c b/generic/tclOODefineCmds.c index d05d899..dfd2acf 100644 --- a/generic/tclOODefineCmds.c +++ b/generic/tclOODefineCmds.c @@ -1125,12 +1125,13 @@ TclOODefineClassObjCmd( */ if (oPtr->selfCls != clsPtr) { - TclOORemoveFromInstances(oPtr, oPtr->selfCls); - /* Reference count already incremented 3 lines up. */ + TclOORemoveFromInstances(oPtr, oPtr->selfCls); + TclOODecrRefCount(oPtr->selfCls->thisPtr); oPtr->selfCls = clsPtr; - + AddRef(oPtr->selfCls->thisPtr); TclOOAddToInstances(oPtr, oPtr->selfCls); + if (oPtr->classPtr != NULL) { BumpGlobalEpoch(interp, oPtr->classPtr); } else { @@ -2151,7 +2152,6 @@ ClassSuperSet( superclasses[0] = oPtr->fPtr->objectCls; } superc = 1; - /* Corresponding TclOODecrRefCount is near the end of this function */ AddRef(superclasses[0]->thisPtr); } else { for (i=0 ; iclassPtr->superclasses.num = superc; FOREACH(superPtr, oPtr->classPtr->superclasses) { TclOOAddToSubclasses(oPtr->classPtr, superPtr); - /* To account for the AddRef() earlier in this function */ - TclOODecrRefCount(superPtr->thisPtr); } BumpGlobalEpoch(interp, oPtr->classPtr); diff --git a/tests/oo.test b/tests/oo.test index 9cf3133..a698bac 100644 --- a/tests/oo.test +++ b/tests/oo.test @@ -57,7 +57,13 @@ test oo-0.4 {basic test of OO's ability to clean up its initial state} -body { foo destroy } } -constraints memory -result 0 -test oo-0.5 {testing literal leak on interp delete} memory { +test oo-0.5.1 {testing object foundation cleanup} memory { + leaktest { + interp create foo + interp delete foo + } +} 0 +test oo-0.5.2 {testing literal leak on interp delete} memory { leaktest { interp create foo foo eval {oo::object new} -- cgit v0.12 From 261fbdac7ec5b605a259cf6c4dc4c2470c7d099d Mon Sep 17 00:00:00 2001 From: dgp Date: Tue, 13 Mar 2018 23:56:22 +0000 Subject: A few minor revisions. --- generic/tclUtil.c | 27 ++++++++++++++++----------- 1 file changed, 16 insertions(+), 11 deletions(-) diff --git a/generic/tclUtil.c b/generic/tclUtil.c index 96ab96d..58e4cd2 100644 --- a/generic/tclUtil.c +++ b/generic/tclUtil.c @@ -1499,9 +1499,10 @@ Tcl_Backslash( /* *---------------------------------------------------------------------- * - * TclUtfWellFormedEnd -- + * UtfWellFormedEnd -- * Checks the end of utf string is malformed, if yes - wraps bytes - * to the given buffer (as well-formed NTS string). + * to the given buffer (as well-formed NTS string). The buffer + * argument should be initialized by the caller and ready to use. * * Results: * The bytes with well-formed end of the string. @@ -1513,7 +1514,7 @@ Tcl_Backslash( */ static inline const char* -TclUtfWellFormedEnd( +UtfWellFormedEnd( Tcl_DString *buffer, /* Buffer used to hold well-formed string. */ CONST char *bytes, /* Pointer to the beginning of the string. */ int length) /* Length of the string. */ @@ -1522,14 +1523,12 @@ TclUtfWellFormedEnd( CONST char *p = Tcl_UtfPrev(l, bytes); if (Tcl_UtfCharComplete(p, l - p)) { - buffer->string = buffer->staticSpace; return bytes; } /* * Malformed utf-8 end, be sure we've NTS to safe compare of end-character, * avoid segfault by access violation out of range. */ - Tcl_DStringInit(buffer); Tcl_DStringAppend(buffer, bytes, length); return Tcl_DStringValue(buffer); } @@ -1607,8 +1606,10 @@ TclTrimRight( return 0; } - bytes = TclUtfWellFormedEnd(&bytesBuf, bytes, numBytes); - trim = TclUtfWellFormedEnd(&trimBuf, trim, numTrim); + Tcl_DStringInit(&bytesBuf); + Tcl_DStringInit(&trimBuf); + bytes = UtfWellFormedEnd(&bytesBuf, bytes, numBytes); + trim = UtfWellFormedEnd(&trimBuf, trim, numTrim); res = TrimRight(bytes, numBytes, trim, numTrim); if (res > numBytes) { @@ -1694,8 +1695,10 @@ TclTrimLeft( return 0; } - bytes = TclUtfWellFormedEnd(&bytesBuf, bytes, numBytes); - trim = TclUtfWellFormedEnd(&trimBuf, trim, numTrim); + Tcl_DStringInit(&bytesBuf); + Tcl_DStringInit(&trimBuf); + bytes = UtfWellFormedEnd(&bytesBuf, bytes, numBytes); + trim = UtfWellFormedEnd(&trimBuf, trim, numTrim); res = TrimLeft(bytes, numBytes, trim, numTrim); if (res > numBytes) { @@ -1740,8 +1743,10 @@ TclTrim( return 0; } - bytes = TclUtfWellFormedEnd(&bytesBuf, bytes, numBytes); - trim = TclUtfWellFormedEnd(&trimBuf, trim, numTrim); + Tcl_DStringInit(&bytesBuf); + Tcl_DStringInit(&trimBuf); + bytes = UtfWellFormedEnd(&bytesBuf, bytes, numBytes); + trim = UtfWellFormedEnd(&trimBuf, trim, numTrim); trimLeft = TrimLeft(bytes, numBytes, trim, numTrim); if (trimLeft > numBytes) { -- cgit v0.12 From fd2d896c8f9f8e330c209b7a2627cb53f9ff533e Mon Sep 17 00:00:00 2001 From: dgp Date: Wed, 14 Mar 2018 00:45:14 +0000 Subject: TclTrim must write to *trimRight even when making a quick exit. --- generic/tclUtil.c | 1 + 1 file changed, 1 insertion(+) diff --git a/generic/tclUtil.c b/generic/tclUtil.c index 58e4cd2..a8791c5 100644 --- a/generic/tclUtil.c +++ b/generic/tclUtil.c @@ -1740,6 +1740,7 @@ TclTrim( /* Empty strings -> nothing to do */ if ((numBytes == 0) || (numTrim == 0)) { + *trimRight = 0; return 0; } -- cgit v0.12 From 17e2ed6919ccdbd5b8e79be7228635f0b71da3da Mon Sep 17 00:00:00 2001 From: dgp Date: Wed, 14 Mar 2018 01:31:10 +0000 Subject: silence compiler warning --- generic/tclProcess.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/generic/tclProcess.c b/generic/tclProcess.c index 8d98a23..7187ee4 100644 --- a/generic/tclProcess.c +++ b/generic/tclProcess.c @@ -210,7 +210,7 @@ WaitProcessStatus( const char *msg; pid = Tcl_WaitPid(pid, &waitStatus, options); - if ((pid == 0)) { + if (pid == 0) { /* * No change. */ -- cgit v0.12 From b16ec6f23b5b23b658cac89abc3e04ff754a062a Mon Sep 17 00:00:00 2001 From: dgp Date: Wed, 14 Mar 2018 04:26:41 +0000 Subject: Backout recent patch working on Object and Namespace refcounts. It creates new leaks and memory corruption according to valgrind, and the preceding checkin did not. Keep developing on the memleak branch and it can merge again when valgrind and memleak tests both like it. --- generic/tclOO.c | 196 ++++++++++++++++++++-------------------------- generic/tclOODefineCmds.c | 10 ++- tests/oo.test | 8 +- 3 files changed, 91 insertions(+), 123 deletions(-) diff --git a/generic/tclOO.c b/generic/tclOO.c index a129a52..587e46d 100644 --- a/generic/tclOO.c +++ b/generic/tclOO.c @@ -397,39 +397,28 @@ InitFoundation( fPtr->objectCls = AllocClass(interp, AllocObject(interp, "object", (Namespace *)fPtr->ooNs, NULL)); - /* Corresponding TclOODecrRefCount in KillFoudation */ - AddRef(fPtr->objectCls->thisPtr); - - /* This is why it is unnecessary in this routine to replace the - * incremented reference count of fPtr->objectCls that was swallowed by - * fakeObject. */ - fPtr->objectCls->superclasses.num = 0; - ckfree(fPtr->objectCls->superclasses.list); - fPtr->objectCls->superclasses.list = NULL; - - /* special initialization for the primordial objects */ - fPtr->objectCls->thisPtr->flags |= ROOT_OBJECT; - fPtr->objectCls->flags |= ROOT_OBJECT; - fPtr->classCls = AllocClass(interp, AllocObject(interp, "class", (Namespace *)fPtr->ooNs, NULL)); - /* Corresponding TclOODecrRefCount in KillFoudation */ - AddRef(fPtr->classCls->thisPtr); - - /* - * Increment reference counts for each reference because these - * relationships can be dynamically changed. - * - * Corresponding TclOODecrRefCount for all incremented refcounts is in - * KillFoundation. - */ /* Rewire bootstrapped objects. */ fPtr->objectCls->thisPtr->selfCls = fPtr->classCls; - AddRef(fPtr->objectCls->thisPtr->selfCls->thisPtr); - fPtr->classCls->thisPtr->selfCls = fPtr->classCls; + + AddRef(fPtr->objectCls->thisPtr); + AddRef(fPtr->classCls->thisPtr); AddRef(fPtr->classCls->thisPtr->selfCls->thisPtr); + AddRef(fPtr->objectCls->thisPtr->selfCls->thisPtr); + + /* special initialization for the primordial objects */ + fPtr->objectCls->thisPtr->flags |= ROOT_OBJECT; + fPtr->objectCls->flags |= ROOT_OBJECT; + + /* This is why it is unnecessary in this routine to make up for the + * incremented reference count of fPtr->objectCls that was sallwed by + * fakeObject. */ + fPtr->objectCls->superclasses.num = 0; + ckfree(fPtr->objectCls->superclasses.list); + fPtr->objectCls->superclasses.list = NULL; fPtr->classCls->thisPtr->flags |= ROOT_CLASS; fPtr->classCls->flags |= ROOT_CLASS; @@ -563,20 +552,20 @@ KillFoundation( { Foundation *fPtr = GetFoundation(interp); + /* + * Crude mechanism to avoid leaking the Object struct of the + * foundation components oo::object and oo::class + * + * Should probably be replaced with something more elegantly designed. + */ + while (TclOODecrRefCount(fPtr->objectCls->thisPtr) == 0) {}; + while (TclOODecrRefCount(fPtr->classCls->thisPtr) == 0) {}; + TclDecrRefCount(fPtr->unknownMethodNameObj); TclDecrRefCount(fPtr->constructorName); TclDecrRefCount(fPtr->destructorName); TclDecrRefCount(fPtr->clonedName); TclDecrRefCount(fPtr->defineName); - if (fPtr->objectCls->thisPtr->selfCls != NULL) { - TclOODecrRefCount(fPtr->objectCls->thisPtr->selfCls->thisPtr); - } - if (fPtr->classCls->thisPtr->selfCls != NULL) { - TclOODecrRefCount(fPtr->classCls->thisPtr->selfCls->thisPtr); - } - TclOODecrRefCount(fPtr->objectCls->thisPtr); - TclOODecrRefCount(fPtr->classCls->thisPtr); - ckfree(fPtr); } @@ -660,8 +649,6 @@ AllocObject( Tcl_ResetResult(interp); } - ((Namespace *)oPtr->namespacePtr)->refCount++; - /* * Make the namespace know about the helper commands. This grants access * to the [self] and [next] commands. @@ -833,9 +820,10 @@ ObjectRenamedTrace( /* * ---------------------------------------------------------------------- * - * DeleteDescendants -- + * ReleaseClassContents -- * - * Delete all descendants of a particular class. + * Tear down the special class data structure, including deleting all + * dependent classes and objects. * * ---------------------------------------------------------------------- */ @@ -847,79 +835,50 @@ DeleteDescendants( { Class *clsPtr = oPtr->classPtr, *subclassPtr, *mixinSubclassPtr; Object *instancePtr; + int i; /* * Squelch classes that this class has been mixed into. */ - if (clsPtr->mixinSubs.num > 0) { - while (clsPtr->mixinSubs.num > 0) { - mixinSubclassPtr = clsPtr->mixinSubs.list[clsPtr->mixinSubs.num-1]; - /* This condition also covers the case where mixinSubclassPtr == - * clsPtr - */ - if (!Deleted(mixinSubclassPtr->thisPtr)) { - Tcl_DeleteCommandFromToken(interp, - mixinSubclassPtr->thisPtr->command); - } - TclOORemoveFromMixinSubs(mixinSubclassPtr, clsPtr); + FOREACH(mixinSubclassPtr, clsPtr->mixinSubs) { + /* This condition also covers the case where mixinSubclassPtr == + * clsPtr + */ + if (!Deleted(mixinSubclassPtr->thisPtr)) { + Tcl_DeleteCommandFromToken(interp, + mixinSubclassPtr->thisPtr->command); } - } - if (clsPtr->mixinSubs.size > 0) { - ckfree(clsPtr->mixinSubs.list); - clsPtr->mixinSubs.size = 0; + i -= TclOORemoveFromMixinSubs(mixinSubclassPtr, clsPtr); + TclOODecrRefCount(mixinSubclassPtr->thisPtr); } /* * Squelch subclasses of this class. */ - 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); - } - TclOORemoveFromSubclasses(subclassPtr, clsPtr); + FOREACH(subclassPtr, clsPtr->subclasses) { + if (!Deleted(subclassPtr->thisPtr) && !IsRoot(subclassPtr)) { + Tcl_DeleteCommandFromToken(interp, subclassPtr->thisPtr->command); } - } - if (clsPtr->subclasses.size > 0) { - ckfree(clsPtr->subclasses.list); - clsPtr->subclasses.list = NULL; - clsPtr->subclasses.size = 0; + i -= TclOORemoveFromSubclasses(subclassPtr, clsPtr); + TclOODecrRefCount(subclassPtr->thisPtr); } /* * Squelch instances of this class (includes objects we're mixed into). */ - if (clsPtr->instances.num > 0) { - while (clsPtr->instances.num > 0) { - instancePtr = clsPtr->instances.list[clsPtr->instances.num-1]; + if (!IsRootClass(oPtr)) { + FOREACH(instancePtr, clsPtr->instances) { /* This condition also covers the case where instancePtr == oPtr */ if (!Deleted(instancePtr) && !IsRoot(instancePtr)) { Tcl_DeleteCommandFromToken(interp, instancePtr->command); } - TclOORemoveFromInstances(instancePtr, clsPtr); + i -= TclOORemoveFromInstances(instancePtr, clsPtr); } } - if (clsPtr->instances.size > 0) { - ckfree(clsPtr->instances.list); - clsPtr->instances.list = NULL; - clsPtr->instances.size = 0; - } } - -/* - * ---------------------------------------------------------------------- - * - * ReleaseClassContents -- - * - * Tear down the special class data structure, including deleting all - * dependent classes and objects. - * - * ---------------------------------------------------------------------- - */ static void ReleaseClassContents( @@ -989,6 +948,21 @@ ReleaseClassContents( } /* + * Squelch our instances. + */ + + if (clsPtr->instances.num) { + Object *oPtr; + + FOREACH(oPtr, clsPtr->instances) { + TclOODecrRefCount(oPtr); + } + ckfree(clsPtr->instances.list); + clsPtr->instances.list = NULL; + clsPtr->instances.num = 0; + } + + /* * Squelch our metadata. */ @@ -1004,21 +978,11 @@ ReleaseClassContents( clsPtr->metadataPtr = NULL; } - if (clsPtr->mixins.num) { - FOREACH(tmpClsPtr, clsPtr->mixins) { - TclOORemoveFromMixinSubs(clsPtr, tmpClsPtr); - } - ckfree(clsPtr->mixins.list); + FOREACH(tmpClsPtr, clsPtr->mixins) { + TclOORemoveFromMixinSubs(clsPtr, tmpClsPtr); } - - if (clsPtr->superclasses.num > 0) { - FOREACH(tmpClsPtr, clsPtr->superclasses) { - TclOORemoveFromSubclasses(clsPtr, tmpClsPtr); - TclOODecrRefCount(tmpClsPtr->thisPtr); - } - ckfree(clsPtr->superclasses.list); - clsPtr->superclasses.num = 0; - clsPtr->superclasses.list = NULL; + FOREACH(tmpClsPtr, clsPtr->superclasses) { + TclOORemoveFromSubclasses(clsPtr, tmpClsPtr); } FOREACH_HASH_VALUE(mPtr, &clsPtr->classMethods) { @@ -1146,10 +1110,10 @@ ObjectNamespaceDeleted( /* To do: Should this be protected with a * !IsRoot() condition? */ TclOORemoveFromInstances(oPtr, oPtr->selfCls); - if (oPtr->mixins.num > 0) { - FOREACH(mixinPtr, oPtr->mixins) { - TclOORemoveFromInstances(oPtr, mixinPtr); - } + FOREACH(mixinPtr, oPtr->mixins) { + i -= TclOORemoveFromInstances(oPtr, mixinPtr); + } + if (i) { ckfree(oPtr->mixins.list); } @@ -1221,9 +1185,7 @@ ObjectNamespaceDeleted( * Delete the object structure itself. */ - TclNsDecrRefCount((Namespace *)oPtr->namespacePtr); oPtr->namespacePtr = NULL; - TclOODecrRefCount(oPtr->selfCls->thisPtr); oPtr->selfCls = NULL; TclOODecrRefCount(oPtr); return; @@ -1242,7 +1204,13 @@ ObjectNamespaceDeleted( */ int TclOODecrRefCount(Object *oPtr) { if (oPtr->refCount-- <= 1) { + Class *clsPtr = oPtr->classPtr; if (oPtr->classPtr != NULL) { + ckfree(clsPtr->superclasses.list); + ckfree(clsPtr->subclasses.list); + ckfree(clsPtr->instances.list); + ckfree(clsPtr->mixinSubs.list); + ckfree(clsPtr->mixins.list); ckfree(oPtr->classPtr); } ckfree(oPtr); @@ -1282,6 +1250,9 @@ TclOORemoveFromInstances( { int i, res = 0; Object *instPtr; + if (Deleted(clsPtr->thisPtr)) { + return res; + } FOREACH(instPtr, clsPtr->instances) { if (oPtr == instPtr) { @@ -1344,6 +1315,9 @@ TclOORemoveFromSubclasses( { int i, res = 0; Class *subclsPtr; + if (Deleted(superPtr->thisPtr)) { + return res; + } FOREACH(subclsPtr, superPtr->subclasses) { if (subPtr == subclsPtr) { @@ -1408,6 +1382,10 @@ TclOORemoveFromMixinSubs( int i, res = 0; Class *subclsPtr; + if (Deleted(superPtr->thisPtr)) { + return res; + } + FOREACH(subclsPtr, superPtr->mixinSubs) { if (subPtr == subclsPtr) { RemoveItem(Class, superPtr->mixinSubs, i); @@ -1700,7 +1678,6 @@ TclNewObjectInstanceCommon( oPtr = AllocObject(interp, simpleName, nsPtr, nsNameStr); oPtr->selfCls = classPtr; - AddRef(classPtr->thisPtr); TclOOAddToInstances(oPtr, classPtr); /* * Check to see if we're really creating a class. If so, allocate the @@ -1937,11 +1914,6 @@ Tcl_CopyObjectInstance( cls2Ptr->superclasses.num = clsPtr->superclasses.num; FOREACH(superPtr, cls2Ptr->superclasses) { TclOOAddToSubclasses(cls2Ptr, superPtr); - - /* For the new item in cls2Ptr->superclasses that memcpy just - * created - */ - AddRef(superPtr->thisPtr); } /* diff --git a/generic/tclOODefineCmds.c b/generic/tclOODefineCmds.c index dfd2acf..d05d899 100644 --- a/generic/tclOODefineCmds.c +++ b/generic/tclOODefineCmds.c @@ -1125,13 +1125,12 @@ TclOODefineClassObjCmd( */ if (oPtr->selfCls != clsPtr) { - TclOORemoveFromInstances(oPtr, oPtr->selfCls); - TclOODecrRefCount(oPtr->selfCls->thisPtr); + + /* Reference count already incremented 3 lines up. */ oPtr->selfCls = clsPtr; - AddRef(oPtr->selfCls->thisPtr); - TclOOAddToInstances(oPtr, oPtr->selfCls); + TclOOAddToInstances(oPtr, oPtr->selfCls); if (oPtr->classPtr != NULL) { BumpGlobalEpoch(interp, oPtr->classPtr); } else { @@ -2152,6 +2151,7 @@ ClassSuperSet( superclasses[0] = oPtr->fPtr->objectCls; } superc = 1; + /* Corresponding TclOODecrRefCount is near the end of this function */ AddRef(superclasses[0]->thisPtr); } else { for (i=0 ; iclassPtr->superclasses.num = superc; FOREACH(superPtr, oPtr->classPtr->superclasses) { TclOOAddToSubclasses(oPtr->classPtr, superPtr); + /* To account for the AddRef() earlier in this function */ + TclOODecrRefCount(superPtr->thisPtr); } BumpGlobalEpoch(interp, oPtr->classPtr); diff --git a/tests/oo.test b/tests/oo.test index a698bac..9cf3133 100644 --- a/tests/oo.test +++ b/tests/oo.test @@ -57,13 +57,7 @@ test oo-0.4 {basic test of OO's ability to clean up its initial state} -body { foo destroy } } -constraints memory -result 0 -test oo-0.5.1 {testing object foundation cleanup} memory { - leaktest { - interp create foo - interp delete foo - } -} 0 -test oo-0.5.2 {testing literal leak on interp delete} memory { +test oo-0.5 {testing literal leak on interp delete} memory { leaktest { interp create foo foo eval {oo::object new} -- cgit v0.12 From 864d754a8a83ea3c7e345ffa6bc41acee6422ad3 Mon Sep 17 00:00:00 2001 From: dgp Date: Wed, 14 Mar 2018 04:45:29 +0000 Subject: backout the latest merge --- generic/tclCmdMZ.c | 3 +- generic/tclInt.h | 2 - generic/tclOO.c | 211 ++++++++++++++++++-------------------- generic/tclOODefineCmds.c | 21 +++- generic/tclUtil.c | 255 +++++++++++++--------------------------------- tests/oo.test | 8 +- 6 files changed, 191 insertions(+), 309 deletions(-) diff --git a/generic/tclCmdMZ.c b/generic/tclCmdMZ.c index 3c5c5e4..ba96d7c 100644 --- a/generic/tclCmdMZ.c +++ b/generic/tclCmdMZ.c @@ -3228,7 +3228,8 @@ StringTrimCmd( } string1 = TclGetStringFromObj(objv[1], &length1); - triml = TclTrim(string1, length1, string2, length2, &trimr); + triml = TclTrimLeft(string1, length1, string2, length2); + trimr = TclTrimRight(string1 + triml, length1 - triml, string2, length2); Tcl_SetObjResult(interp, Tcl_NewStringObj(string1 + triml, length1 - triml - trimr)); diff --git a/generic/tclInt.h b/generic/tclInt.h index 57f648c..e7794c7 100644 --- a/generic/tclInt.h +++ b/generic/tclInt.h @@ -3198,8 +3198,6 @@ MODULE_SCOPE void TclSubstParse(Tcl_Interp *interp, const char *bytes, MODULE_SCOPE int TclSubstTokens(Tcl_Interp *interp, Tcl_Token *tokenPtr, int count, int *tokensLeftPtr, int line, int *clNextOuter, const char *outerScript); -MODULE_SCOPE int TclTrim(const char *bytes, int numBytes, - const char *trim, int numTrim, int *trimRight); MODULE_SCOPE int TclTrimLeft(const char *bytes, int numBytes, const char *trim, int numTrim); MODULE_SCOPE int TclTrimRight(const char *bytes, int numBytes, diff --git a/generic/tclOO.c b/generic/tclOO.c index c80f039..dcf48ef 100644 --- a/generic/tclOO.c +++ b/generic/tclOO.c @@ -523,47 +523,47 @@ InitClassSystemRoots( fakeCls.thisPtr = &fakeObject; - fPtr->objectCls = AllocClass(interp, AllocObject(interp, "object", (Namespace *)fPtr->ooNs, NULL)); - /* Corresponding TclOODecrRefCount in KillFoudation */ - AddRef(fPtr->objectCls->thisPtr); - - /* This is why it is unnecessary in this routine to replace the - * incremented reference count of fPtr->objectCls that was swallowed by - * fakeObject. */ - fPtr->objectCls->superclasses.num = 0; - ckfree(fPtr->objectCls->superclasses.list); - fPtr->objectCls->superclasses.list = NULL; - - /* special initialization for the primordial objects */ - fPtr->objectCls->thisPtr->flags |= ROOT_OBJECT; - fPtr->objectCls->flags |= ROOT_OBJECT; - fPtr->classCls = AllocClass(interp, AllocObject(interp, "class", (Namespace *)fPtr->ooNs, NULL)); - /* Corresponding TclOODecrRefCount in KillFoudation */ - AddRef(fPtr->classCls->thisPtr); /* - * Increment reference counts for each reference because these - * relationships can be dynamically changed. - * - * Corresponding TclOODecrRefCount for all incremented refcounts is in - * KillFoundation. + * Rewire bootstrapped objects. */ - /* Rewire bootstrapped objects. */ fPtr->objectCls->thisPtr->selfCls = fPtr->classCls; - AddRef(fPtr->objectCls->thisPtr->selfCls->thisPtr); - fPtr->classCls->thisPtr->selfCls = fPtr->classCls; + + AddRef(fPtr->objectCls->thisPtr); + AddRef(fPtr->classCls->thisPtr); AddRef(fPtr->classCls->thisPtr->selfCls->thisPtr); + AddRef(fPtr->objectCls->thisPtr->selfCls->thisPtr); + + /* + * Special initialization for the primordial objects. + */ + + fPtr->objectCls->thisPtr->flags |= ROOT_OBJECT; + fPtr->objectCls->flags |= ROOT_OBJECT; + + /* + * This is why it is unnecessary in this routine to make up for the + * incremented reference count of fPtr->objectCls that was sallwed by + * fakeObject. + */ + + fPtr->objectCls->superclasses.num = 0; + ckfree(fPtr->objectCls->superclasses.list); + fPtr->objectCls->superclasses.list = NULL; fPtr->classCls->thisPtr->flags |= ROOT_CLASS; fPtr->classCls->flags |= ROOT_CLASS; - /* Standard initialization for new Objects */ + /* + * Standard initialization for new Objects. + */ + TclOOAddToInstances(fPtr->objectCls->thisPtr, fPtr->classCls); TclOOAddToInstances(fPtr->classCls->thisPtr, fPtr->classCls); TclOOAddToSubclasses(fPtr->classCls, fPtr->objectCls); @@ -632,20 +632,20 @@ KillFoundation( { Foundation *fPtr = GetFoundation(interp); + /* + * Crude mechanism to avoid leaking the Object struct of the + * foundation components oo::object and oo::class + * + * Should probably be replaced with something more elegantly designed. + */ + while (TclOODecrRefCount(fPtr->objectCls->thisPtr) == 0) {}; + while (TclOODecrRefCount(fPtr->classCls->thisPtr) == 0) {}; + TclDecrRefCount(fPtr->unknownMethodNameObj); TclDecrRefCount(fPtr->constructorName); TclDecrRefCount(fPtr->destructorName); TclDecrRefCount(fPtr->clonedName); TclDecrRefCount(fPtr->defineName); - if (fPtr->objectCls->thisPtr->selfCls != NULL) { - TclOODecrRefCount(fPtr->objectCls->thisPtr->selfCls->thisPtr); - } - if (fPtr->classCls->thisPtr->selfCls != NULL) { - TclOODecrRefCount(fPtr->classCls->thisPtr->selfCls->thisPtr); - } - TclOODecrRefCount(fPtr->objectCls->thisPtr); - TclOODecrRefCount(fPtr->classCls->thisPtr); - ckfree(fPtr); } @@ -729,8 +729,6 @@ AllocObject( Tcl_ResetResult(interp); } - ((Namespace *)oPtr->namespacePtr)->refCount++; - /* * Make the namespace know about the helper commands. This grants access * to the [self] and [next] commands. @@ -903,9 +901,10 @@ ObjectRenamedTrace( /* * ---------------------------------------------------------------------- * - * DeleteDescendants -- + * DeleteDescendants, ReleaseClassContents -- * - * Delete all descendants of a particular class. + * Tear down the special class data structure, including deleting all + * dependent classes and objects. * * ---------------------------------------------------------------------- */ @@ -917,55 +916,44 @@ DeleteDescendants( { Class *clsPtr = oPtr->classPtr, *subclassPtr, *mixinSubclassPtr; Object *instancePtr; + int i; /* * Squelch classes that this class has been mixed into. */ - if (clsPtr->mixinSubs.num > 0) { - while (clsPtr->mixinSubs.num > 0) { - mixinSubclassPtr = clsPtr->mixinSubs.list[clsPtr->mixinSubs.num-1]; - /* This condition also covers the case where mixinSubclassPtr == - * clsPtr - */ - if (!Deleted(mixinSubclassPtr->thisPtr)) { - Tcl_DeleteCommandFromToken(interp, - mixinSubclassPtr->thisPtr->command); - } - TclOORemoveFromMixinSubs(mixinSubclassPtr, clsPtr); + FOREACH(mixinSubclassPtr, clsPtr->mixinSubs) { + /* + * This condition also covers the case where mixinSubclassPtr == + * clsPtr + */ + + if (!Deleted(mixinSubclassPtr->thisPtr)) { + Tcl_DeleteCommandFromToken(interp, + mixinSubclassPtr->thisPtr->command); } - } - if (clsPtr->mixinSubs.size > 0) { - ckfree(clsPtr->mixinSubs.list); - clsPtr->mixinSubs.size = 0; + i -= TclOORemoveFromMixinSubs(mixinSubclassPtr, clsPtr); + TclOODecrRefCount(mixinSubclassPtr->thisPtr); } /* * Squelch subclasses of this class. */ - 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); - } - TclOORemoveFromSubclasses(subclassPtr, clsPtr); + FOREACH(subclassPtr, clsPtr->subclasses) { + if (!Deleted(subclassPtr->thisPtr) && !IsRoot(subclassPtr)) { + Tcl_DeleteCommandFromToken(interp, subclassPtr->thisPtr->command); } - } - if (clsPtr->subclasses.size > 0) { - ckfree(clsPtr->subclasses.list); - clsPtr->subclasses.list = NULL; - clsPtr->subclasses.size = 0; + i -= TclOORemoveFromSubclasses(subclassPtr, clsPtr); + TclOODecrRefCount(subclassPtr->thisPtr); } /* * Squelch instances of this class (includes objects we're mixed into). */ - if (clsPtr->instances.num > 0) { - while (clsPtr->instances.num > 0) { - instancePtr = clsPtr->instances.list[clsPtr->instances.num-1]; + if (!IsRootClass(oPtr)) { + FOREACH(instancePtr, clsPtr->instances) { /* * This condition also covers the case where instancePtr == oPtr */ @@ -973,26 +961,10 @@ DeleteDescendants( if (!Deleted(instancePtr) && !IsRoot(instancePtr)) { Tcl_DeleteCommandFromToken(interp, instancePtr->command); } - TclOORemoveFromInstances(instancePtr, clsPtr); + i -= TclOORemoveFromInstances(instancePtr, clsPtr); } } - if (clsPtr->instances.size > 0) { - ckfree(clsPtr->instances.list); - clsPtr->instances.list = NULL; - clsPtr->instances.size = 0; - } } - -/* - * ---------------------------------------------------------------------- - * - * ReleaseClassContents -- - * - * Tear down the special class data structure, including deleting all - * dependent classes and objects. - * - * ---------------------------------------------------------------------- - */ static void ReleaseClassContents( @@ -1062,6 +1034,21 @@ ReleaseClassContents( } /* + * Squelch our instances. + */ + + if (clsPtr->instances.num) { + Object *oPtr; + + FOREACH(oPtr, clsPtr->instances) { + TclOODecrRefCount(oPtr); + } + ckfree(clsPtr->instances.list); + clsPtr->instances.list = NULL; + clsPtr->instances.num = 0; + } + + /* * Squelch our metadata. */ @@ -1077,21 +1064,11 @@ ReleaseClassContents( clsPtr->metadataPtr = NULL; } - if (clsPtr->mixins.num) { - FOREACH(tmpClsPtr, clsPtr->mixins) { - TclOORemoveFromMixinSubs(clsPtr, tmpClsPtr); - } - ckfree(clsPtr->mixins.list); + FOREACH(tmpClsPtr, clsPtr->mixins) { + TclOORemoveFromMixinSubs(clsPtr, tmpClsPtr); } - - if (clsPtr->superclasses.num > 0) { - FOREACH(tmpClsPtr, clsPtr->superclasses) { - TclOORemoveFromSubclasses(clsPtr, tmpClsPtr); - TclOODecrRefCount(tmpClsPtr->thisPtr); - } - ckfree(clsPtr->superclasses.list); - clsPtr->superclasses.num = 0; - clsPtr->superclasses.list = NULL; + FOREACH(tmpClsPtr, clsPtr->superclasses) { + TclOORemoveFromSubclasses(clsPtr, tmpClsPtr); } FOREACH_HASH_VALUE(mPtr, &clsPtr->classMethods) { @@ -1227,10 +1204,10 @@ ObjectNamespaceDeleted( TclOORemoveFromInstances(oPtr, oPtr->selfCls); - if (oPtr->mixins.num > 0) { - FOREACH(mixinPtr, oPtr->mixins) { - TclOORemoveFromInstances(oPtr, mixinPtr); - } + FOREACH(mixinPtr, oPtr->mixins) { + i -= TclOORemoveFromInstances(oPtr, mixinPtr); + } + if (i) { ckfree(oPtr->mixins.list); } @@ -1299,9 +1276,7 @@ ObjectNamespaceDeleted( * Delete the object structure itself. */ - TclNsDecrRefCount((Namespace *)oPtr->namespacePtr); oPtr->namespacePtr = NULL; - TclOODecrRefCount(oPtr->selfCls->thisPtr); oPtr->selfCls = NULL; TclOODecrRefCount(oPtr); return; @@ -1324,8 +1299,14 @@ TclOODecrRefCount( Object *oPtr) { if (oPtr->refCount-- <= 1) { + Class *clsPtr = oPtr->classPtr; if (oPtr->classPtr != NULL) { + ckfree(clsPtr->superclasses.list); + ckfree(clsPtr->subclasses.list); + ckfree(clsPtr->instances.list); + ckfree(clsPtr->mixinSubs.list); + ckfree(clsPtr->mixins.list); ckfree(oPtr->classPtr); } ckfree(oPtr); @@ -1354,6 +1335,10 @@ TclOORemoveFromInstances( int i, res = 0; Object *instPtr; + if (Deleted(clsPtr->thisPtr)) { + return res; + } + FOREACH(instPtr, clsPtr->instances) { if (oPtr == instPtr) { RemoveItem(Object, clsPtr->instances, i); @@ -1416,6 +1401,10 @@ TclOORemoveFromSubclasses( int i, res = 0; Class *subclsPtr; + if (Deleted(superPtr->thisPtr)) { + return res; + } + FOREACH(subclsPtr, superPtr->subclasses) { if (subPtr == subclsPtr) { RemoveItem(Class, superPtr->subclasses, i); @@ -1480,6 +1469,10 @@ TclOORemoveFromMixinSubs( int i, res = 0; Class *subclsPtr; + if (Deleted(superPtr->thisPtr)) { + return res; + } + FOREACH(subclsPtr, superPtr->mixinSubs) { if (subPtr == subclsPtr) { RemoveItem(Class, superPtr->mixinSubs, i); @@ -1787,7 +1780,6 @@ TclNewObjectInstanceCommon( oPtr = AllocObject(interp, simpleName, nsPtr, nsNameStr); oPtr->selfCls = classPtr; - AddRef(classPtr->thisPtr); TclOOAddToInstances(oPtr, classPtr); /* @@ -2033,11 +2025,6 @@ Tcl_CopyObjectInstance( cls2Ptr->superclasses.num = clsPtr->superclasses.num; FOREACH(superPtr, cls2Ptr->superclasses) { TclOOAddToSubclasses(cls2Ptr, superPtr); - - /* For the new item in cls2Ptr->superclasses that memcpy just - * created - */ - AddRef(superPtr->thisPtr); } /* diff --git a/generic/tclOODefineCmds.c b/generic/tclOODefineCmds.c index 6c1d58a..7c2a641 100644 --- a/generic/tclOODefineCmds.c +++ b/generic/tclOODefineCmds.c @@ -1185,13 +1185,15 @@ TclOODefineClassObjCmd( */ if (oPtr->selfCls != clsPtr) { - TclOORemoveFromInstances(oPtr, oPtr->selfCls); - TclOODecrRefCount(oPtr->selfCls->thisPtr); + + /* + * Reference count already incremented a few lines up. + */ + oPtr->selfCls = clsPtr; - AddRef(oPtr->selfCls->thisPtr); - TclOOAddToInstances(oPtr, oPtr->selfCls); + TclOOAddToInstances(oPtr, oPtr->selfCls); if (oPtr->classPtr != NULL) { BumpGlobalEpoch(interp, oPtr->classPtr); } else { @@ -2232,6 +2234,11 @@ ClassSuperSet( superclasses[0] = oPtr->fPtr->objectCls; } superc = 1; + + /* + * Corresponding TclOODecrRefCount is near the end of this function. + */ + AddRef(superclasses[0]->thisPtr); } else { for (i=0 ; iclassPtr->superclasses.num = superc; FOREACH(superPtr, oPtr->classPtr->superclasses) { TclOOAddToSubclasses(oPtr->classPtr, superPtr); + + /* + * To account for the AddRef() earlier in this function. + */ + + TclOODecrRefCount(superPtr->thisPtr); } BumpGlobalEpoch(interp, oPtr->classPtr); diff --git a/generic/tclUtil.c b/generic/tclUtil.c index 3fbc325..d1b81a9 100644 --- a/generic/tclUtil.c +++ b/generic/tclUtil.c @@ -1647,46 +1647,11 @@ Tcl_Backslash( /* *---------------------------------------------------------------------- * - * UtfWellFormedEnd -- - * Checks the end of utf string is malformed, if yes - wraps bytes - * to the given buffer (as well-formed NTS string). The buffer - * argument should be initialized by the caller and ready to use. - * - * Results: - * The bytes with well-formed end of the string. - * - * Side effects: - * Buffer (DString) may be allocated, so must be released. - * - *---------------------------------------------------------------------- - */ - -static inline const char* -UtfWellFormedEnd( - Tcl_DString *buffer, /* Buffer used to hold well-formed string. */ - const char *bytes, /* Pointer to the beginning of the string. */ - int length) /* Length of the string. */ -{ - const char *l = bytes + length; - const char *p = Tcl_UtfPrev(l, bytes); - - if (Tcl_UtfCharComplete(p, l - p)) { - return bytes; - } - /* - * Malformed utf-8 end, be sure we've NTS to safe compare of end-character, - * avoid segfault by access violation out of range. - */ - Tcl_DStringAppend(buffer, bytes, length); - return Tcl_DStringValue(buffer); -} -/* - *---------------------------------------------------------------------- - * * TclTrimRight -- - * Takes two counted strings in the Tcl encoding. Conceptually - * finds the sub string (offset) to trim from the right side of the - * first string all characters found in the second string. + * + * Takes two counted strings in the Tcl encoding which must both be null + * terminated. Conceptually trims from the right side of the first string + * all characters found in the second string. * * Results: * The number of bytes to be removed from the end of the string. @@ -1697,8 +1662,8 @@ UtfWellFormedEnd( *---------------------------------------------------------------------- */ -static inline int -TrimRight( +int +TclTrimRight( const char *bytes, /* String to be trimmed... */ int numBytes, /* ...and its length in bytes */ const char *trim, /* String of trim characters... */ @@ -1708,6 +1673,18 @@ TrimRight( int pInc; Tcl_UniChar ch1 = 0, ch2 = 0; + if ((bytes[numBytes] != '\0') || (trim[numTrim] != '\0')) { + Tcl_Panic("TclTrimRight works only on null-terminated strings"); + } + + /* + * Empty strings -> nothing to do. + */ + + if ((numBytes == 0) || (numTrim == 0)) { + return 0; + } + /* * Outer loop: iterate over string to be trimmed. */ @@ -1746,46 +1723,15 @@ TrimRight( return numBytes - (p - bytes); } - -int -TclTrimRight( - const char *bytes, /* String to be trimmed... */ - int numBytes, /* ...and its length in bytes */ - const char *trim, /* String of trim characters... */ - int numTrim) /* ...and its length in bytes */ -{ - int res; - Tcl_DString bytesBuf, trimBuf; - - /* Empty strings -> nothing to do */ - if ((numBytes == 0) || (numTrim == 0)) { - return 0; - } - - Tcl_DStringInit(&bytesBuf); - Tcl_DStringInit(&trimBuf); - bytes = UtfWellFormedEnd(&bytesBuf, bytes, numBytes); - trim = UtfWellFormedEnd(&trimBuf, trim, numTrim); - - res = TrimRight(bytes, numBytes, trim, numTrim); - if (res > numBytes) { - res = numBytes; - } - - Tcl_DStringFree(&bytesBuf); - Tcl_DStringFree(&trimBuf); - - return res; -} /* *---------------------------------------------------------------------- * * TclTrimLeft -- * - * Takes two counted strings in the Tcl encoding. Conceptually - * finds the sub string (offset) to trim from the left side of the - * first string all characters found in the second string. + * Takes two counted strings in the Tcl encoding which must both be null + * terminated. Conceptually trims from the left side of the first string + * all characters found in the second string. * * Results: * The number of bytes to be removed from the start of the string. @@ -1796,8 +1742,8 @@ TclTrimRight( *---------------------------------------------------------------------- */ -static inline int -TrimLeft( +int +TclTrimLeft( const char *bytes, /* String to be trimmed... */ int numBytes, /* ...and its length in bytes */ const char *trim, /* String of trim characters... */ @@ -1806,6 +1752,18 @@ TrimLeft( const char *p = bytes; Tcl_UniChar ch1 = 0, ch2 = 0; + if ((bytes[numBytes] != '\0') || (trim[numTrim] != '\0')) { + Tcl_Panic("TclTrimLeft works only on null-terminated strings"); + } + + /* + * Empty strings -> nothing to do. + */ + + if ((numBytes == 0) || (numTrim == 0)) { + return 0; + } + /* * Outer loop: iterate over string to be trimmed. */ @@ -1840,99 +1798,10 @@ TrimLeft( p += pInc; numBytes -= pInc; - } while (numBytes > 0); + } while (numBytes); return p - bytes; } - -int -TclTrimLeft( - const char *bytes, /* String to be trimmed... */ - int numBytes, /* ...and its length in bytes */ - const char *trim, /* String of trim characters... */ - int numTrim) /* ...and its length in bytes */ -{ - int res; - Tcl_DString bytesBuf, trimBuf; - - /* Empty strings -> nothing to do */ - if ((numBytes == 0) || (numTrim == 0)) { - return 0; - } - - Tcl_DStringInit(&bytesBuf); - Tcl_DStringInit(&trimBuf); - bytes = UtfWellFormedEnd(&bytesBuf, bytes, numBytes); - trim = UtfWellFormedEnd(&trimBuf, trim, numTrim); - - res = TrimLeft(bytes, numBytes, trim, numTrim); - if (res > numBytes) { - res = numBytes; - } - - Tcl_DStringFree(&bytesBuf); - Tcl_DStringFree(&trimBuf); - - return res; -} - -/* - *---------------------------------------------------------------------- - * - * TclTrim -- - * Finds the sub string (offset) to trim from both sides of the - * first string all characters found in the second string. - * - * Results: - * The number of bytes to be removed from the start of the string - * - * Side effects: - * None. - * - *---------------------------------------------------------------------- - */ - -int -TclTrim( - const char *bytes, /* String to be trimmed... */ - int numBytes, /* ...and its length in bytes */ - const char *trim, /* String of trim characters... */ - int numTrim, /* ...and its length in bytes */ - int *trimRight) /* Offset from the end of the string. */ -{ - int trimLeft; - Tcl_DString bytesBuf, trimBuf; - - /* Empty strings -> nothing to do */ - if ((numBytes == 0) || (numTrim == 0)) { - *trimRight = 0; - return 0; - } - - Tcl_DStringInit(&bytesBuf); - Tcl_DStringInit(&trimBuf); - bytes = UtfWellFormedEnd(&bytesBuf, bytes, numBytes); - trim = UtfWellFormedEnd(&trimBuf, trim, numTrim); - - trimLeft = TrimLeft(bytes, numBytes, trim, numTrim); - if (trimLeft > numBytes) { - trimLeft = numBytes; - } - numBytes -= trimLeft; - *trimRight = 0; - if (numBytes) { - bytes += trimLeft; - *trimRight = TrimRight(bytes, numBytes, trim, numTrim); - if (*trimRight > numBytes) { - *trimRight = numBytes; - } - } - - Tcl_DStringFree(&bytesBuf); - Tcl_DStringFree(&trimBuf); - - return trimLeft; -} /* *---------------------------------------------------------------------- @@ -2000,20 +1869,30 @@ Tcl_Concat( result = ckalloc((unsigned) (bytesNeeded + argc)); for (p = result, i = 0; i < argc; i++) { - int triml, trimr, elemLength; + int trim, elemLength; const char *element; element = argv[i]; elemLength = strlen(argv[i]); - /* Trim away the leading/trailing whitespace. */ - triml = TclTrim(element, elemLength, CONCAT_TRIM_SET, - CONCAT_WS_SIZE, &trimr); - element += triml; - elemLength -= triml + trimr; + /* + * Trim away the leading whitespace. + */ + + trim = TclTrimLeft(element, elemLength, CONCAT_TRIM_SET, + CONCAT_WS_SIZE); + element += trim; + elemLength -= trim; + + /* + * Trim away the trailing whitespace. Do not permit trimming to expose + * a final backslash character. + */ - /* Do not permit trimming to expose a final backslash character. */ - elemLength += trimr && (element[elemLength - 1] == '\\'); + trim = TclTrimRight(element, elemLength, CONCAT_TRIM_SET, + CONCAT_WS_SIZE); + trim -= trim && (element[elemLength - trim - 1] == '\\'); + elemLength -= trim; /* * If we're left with empty element after trimming, do nothing. @@ -2133,18 +2012,28 @@ Tcl_ConcatObj( Tcl_SetObjLength(resPtr, 0); for (i = 0; i < objc; i++) { - int triml, trimr; + int trim; element = TclGetStringFromObj(objv[i], &elemLength); - /* Trim away the leading/trailing whitespace. */ - triml = TclTrim(element, elemLength, CONCAT_TRIM_SET, - CONCAT_WS_SIZE, &trimr); - element += triml; - elemLength -= triml + trimr; + /* + * Trim away the leading whitespace. + */ + + trim = TclTrimLeft(element, elemLength, CONCAT_TRIM_SET, + CONCAT_WS_SIZE); + element += trim; + elemLength -= trim; + + /* + * Trim away the trailing whitespace. Do not permit trimming to expose + * a final backslash character. + */ - /* Do not permit trimming to expose a final backslash character. */ - elemLength += trimr && (element[elemLength - 1] == '\\'); + trim = TclTrimRight(element, elemLength, CONCAT_TRIM_SET, + CONCAT_WS_SIZE); + trim -= trim && (element[elemLength - trim - 1] == '\\'); + elemLength -= trim; /* * If we're left with empty element after trimming, do nothing. diff --git a/tests/oo.test b/tests/oo.test index 22e3f11..4f9490b 100644 --- a/tests/oo.test +++ b/tests/oo.test @@ -57,13 +57,7 @@ test oo-0.4 {basic test of OO's ability to clean up its initial state} -body { foo destroy } } -constraints memory -result 0 -test oo-0.5.1 {testing object foundation cleanup} memory { - leaktest { - interp create foo - interp delete foo - } -} 0 -test oo-0.5.2 {testing literal leak on interp delete} memory { +test oo-0.5 {testing literal leak on interp delete} memory { leaktest { interp create foo foo eval {oo::object new} -- cgit v0.12 From 0a3e2630364e089f3b5c35a2935c855cc5c5ed5d Mon Sep 17 00:00:00 2001 From: dgp Date: Wed, 14 Mar 2018 05:41:19 +0000 Subject: cherry pick the desirable part of the merge. --- generic/tclCmdMZ.c | 3 +- generic/tclInt.h | 2 + generic/tclUtil.c | 255 ++++++++++++++++++++++++++++++++++++++--------------- 3 files changed, 186 insertions(+), 74 deletions(-) diff --git a/generic/tclCmdMZ.c b/generic/tclCmdMZ.c index ba96d7c..3c5c5e4 100644 --- a/generic/tclCmdMZ.c +++ b/generic/tclCmdMZ.c @@ -3228,8 +3228,7 @@ StringTrimCmd( } string1 = TclGetStringFromObj(objv[1], &length1); - triml = TclTrimLeft(string1, length1, string2, length2); - trimr = TclTrimRight(string1 + triml, length1 - triml, string2, length2); + triml = TclTrim(string1, length1, string2, length2, &trimr); Tcl_SetObjResult(interp, Tcl_NewStringObj(string1 + triml, length1 - triml - trimr)); diff --git a/generic/tclInt.h b/generic/tclInt.h index e7794c7..57f648c 100644 --- a/generic/tclInt.h +++ b/generic/tclInt.h @@ -3198,6 +3198,8 @@ MODULE_SCOPE void TclSubstParse(Tcl_Interp *interp, const char *bytes, MODULE_SCOPE int TclSubstTokens(Tcl_Interp *interp, Tcl_Token *tokenPtr, int count, int *tokensLeftPtr, int line, int *clNextOuter, const char *outerScript); +MODULE_SCOPE int TclTrim(const char *bytes, int numBytes, + const char *trim, int numTrim, int *trimRight); MODULE_SCOPE int TclTrimLeft(const char *bytes, int numBytes, const char *trim, int numTrim); MODULE_SCOPE int TclTrimRight(const char *bytes, int numBytes, diff --git a/generic/tclUtil.c b/generic/tclUtil.c index d1b81a9..3fbc325 100644 --- a/generic/tclUtil.c +++ b/generic/tclUtil.c @@ -1647,11 +1647,46 @@ Tcl_Backslash( /* *---------------------------------------------------------------------- * - * TclTrimRight -- + * UtfWellFormedEnd -- + * Checks the end of utf string is malformed, if yes - wraps bytes + * to the given buffer (as well-formed NTS string). The buffer + * argument should be initialized by the caller and ready to use. + * + * Results: + * The bytes with well-formed end of the string. * - * Takes two counted strings in the Tcl encoding which must both be null - * terminated. Conceptually trims from the right side of the first string - * all characters found in the second string. + * Side effects: + * Buffer (DString) may be allocated, so must be released. + * + *---------------------------------------------------------------------- + */ + +static inline const char* +UtfWellFormedEnd( + Tcl_DString *buffer, /* Buffer used to hold well-formed string. */ + const char *bytes, /* Pointer to the beginning of the string. */ + int length) /* Length of the string. */ +{ + const char *l = bytes + length; + const char *p = Tcl_UtfPrev(l, bytes); + + if (Tcl_UtfCharComplete(p, l - p)) { + return bytes; + } + /* + * Malformed utf-8 end, be sure we've NTS to safe compare of end-character, + * avoid segfault by access violation out of range. + */ + Tcl_DStringAppend(buffer, bytes, length); + return Tcl_DStringValue(buffer); +} +/* + *---------------------------------------------------------------------- + * + * TclTrimRight -- + * Takes two counted strings in the Tcl encoding. Conceptually + * finds the sub string (offset) to trim from the right side of the + * first string all characters found in the second string. * * Results: * The number of bytes to be removed from the end of the string. @@ -1662,8 +1697,8 @@ Tcl_Backslash( *---------------------------------------------------------------------- */ -int -TclTrimRight( +static inline int +TrimRight( const char *bytes, /* String to be trimmed... */ int numBytes, /* ...and its length in bytes */ const char *trim, /* String of trim characters... */ @@ -1673,18 +1708,6 @@ TclTrimRight( int pInc; Tcl_UniChar ch1 = 0, ch2 = 0; - if ((bytes[numBytes] != '\0') || (trim[numTrim] != '\0')) { - Tcl_Panic("TclTrimRight works only on null-terminated strings"); - } - - /* - * Empty strings -> nothing to do. - */ - - if ((numBytes == 0) || (numTrim == 0)) { - return 0; - } - /* * Outer loop: iterate over string to be trimmed. */ @@ -1723,15 +1746,46 @@ TclTrimRight( return numBytes - (p - bytes); } + +int +TclTrimRight( + const char *bytes, /* String to be trimmed... */ + int numBytes, /* ...and its length in bytes */ + const char *trim, /* String of trim characters... */ + int numTrim) /* ...and its length in bytes */ +{ + int res; + Tcl_DString bytesBuf, trimBuf; + + /* Empty strings -> nothing to do */ + if ((numBytes == 0) || (numTrim == 0)) { + return 0; + } + + Tcl_DStringInit(&bytesBuf); + Tcl_DStringInit(&trimBuf); + bytes = UtfWellFormedEnd(&bytesBuf, bytes, numBytes); + trim = UtfWellFormedEnd(&trimBuf, trim, numTrim); + + res = TrimRight(bytes, numBytes, trim, numTrim); + if (res > numBytes) { + res = numBytes; + } + + Tcl_DStringFree(&bytesBuf); + Tcl_DStringFree(&trimBuf); + + return res; +} /* *---------------------------------------------------------------------- * * TclTrimLeft -- * - * Takes two counted strings in the Tcl encoding which must both be null - * terminated. Conceptually trims from the left side of the first string - * all characters found in the second string. + * Takes two counted strings in the Tcl encoding. Conceptually + * finds the sub string (offset) to trim from the left side of the + * first string all characters found in the second string. * * Results: * The number of bytes to be removed from the start of the string. @@ -1742,8 +1796,8 @@ TclTrimRight( *---------------------------------------------------------------------- */ -int -TclTrimLeft( +static inline int +TrimLeft( const char *bytes, /* String to be trimmed... */ int numBytes, /* ...and its length in bytes */ const char *trim, /* String of trim characters... */ @@ -1752,18 +1806,6 @@ TclTrimLeft( const char *p = bytes; Tcl_UniChar ch1 = 0, ch2 = 0; - if ((bytes[numBytes] != '\0') || (trim[numTrim] != '\0')) { - Tcl_Panic("TclTrimLeft works only on null-terminated strings"); - } - - /* - * Empty strings -> nothing to do. - */ - - if ((numBytes == 0) || (numTrim == 0)) { - return 0; - } - /* * Outer loop: iterate over string to be trimmed. */ @@ -1798,10 +1840,99 @@ TclTrimLeft( p += pInc; numBytes -= pInc; - } while (numBytes); + } while (numBytes > 0); return p - bytes; } + +int +TclTrimLeft( + const char *bytes, /* String to be trimmed... */ + int numBytes, /* ...and its length in bytes */ + const char *trim, /* String of trim characters... */ + int numTrim) /* ...and its length in bytes */ +{ + int res; + Tcl_DString bytesBuf, trimBuf; + + /* Empty strings -> nothing to do */ + if ((numBytes == 0) || (numTrim == 0)) { + return 0; + } + + Tcl_DStringInit(&bytesBuf); + Tcl_DStringInit(&trimBuf); + bytes = UtfWellFormedEnd(&bytesBuf, bytes, numBytes); + trim = UtfWellFormedEnd(&trimBuf, trim, numTrim); + + res = TrimLeft(bytes, numBytes, trim, numTrim); + if (res > numBytes) { + res = numBytes; + } + + Tcl_DStringFree(&bytesBuf); + Tcl_DStringFree(&trimBuf); + + return res; +} + +/* + *---------------------------------------------------------------------- + * + * TclTrim -- + * Finds the sub string (offset) to trim from both sides of the + * first string all characters found in the second string. + * + * Results: + * The number of bytes to be removed from the start of the string + * + * Side effects: + * None. + * + *---------------------------------------------------------------------- + */ + +int +TclTrim( + const char *bytes, /* String to be trimmed... */ + int numBytes, /* ...and its length in bytes */ + const char *trim, /* String of trim characters... */ + int numTrim, /* ...and its length in bytes */ + int *trimRight) /* Offset from the end of the string. */ +{ + int trimLeft; + Tcl_DString bytesBuf, trimBuf; + + /* Empty strings -> nothing to do */ + if ((numBytes == 0) || (numTrim == 0)) { + *trimRight = 0; + return 0; + } + + Tcl_DStringInit(&bytesBuf); + Tcl_DStringInit(&trimBuf); + bytes = UtfWellFormedEnd(&bytesBuf, bytes, numBytes); + trim = UtfWellFormedEnd(&trimBuf, trim, numTrim); + + trimLeft = TrimLeft(bytes, numBytes, trim, numTrim); + if (trimLeft > numBytes) { + trimLeft = numBytes; + } + numBytes -= trimLeft; + *trimRight = 0; + if (numBytes) { + bytes += trimLeft; + *trimRight = TrimRight(bytes, numBytes, trim, numTrim); + if (*trimRight > numBytes) { + *trimRight = numBytes; + } + } + + Tcl_DStringFree(&bytesBuf); + Tcl_DStringFree(&trimBuf); + + return trimLeft; +} /* *---------------------------------------------------------------------- @@ -1869,30 +2000,20 @@ Tcl_Concat( result = ckalloc((unsigned) (bytesNeeded + argc)); for (p = result, i = 0; i < argc; i++) { - int trim, elemLength; + int triml, trimr, elemLength; const char *element; element = argv[i]; elemLength = strlen(argv[i]); - /* - * Trim away the leading whitespace. - */ - - trim = TclTrimLeft(element, elemLength, CONCAT_TRIM_SET, - CONCAT_WS_SIZE); - element += trim; - elemLength -= trim; - - /* - * Trim away the trailing whitespace. Do not permit trimming to expose - * a final backslash character. - */ + /* Trim away the leading/trailing whitespace. */ + triml = TclTrim(element, elemLength, CONCAT_TRIM_SET, + CONCAT_WS_SIZE, &trimr); + element += triml; + elemLength -= triml + trimr; - trim = TclTrimRight(element, elemLength, CONCAT_TRIM_SET, - CONCAT_WS_SIZE); - trim -= trim && (element[elemLength - trim - 1] == '\\'); - elemLength -= trim; + /* Do not permit trimming to expose a final backslash character. */ + elemLength += trimr && (element[elemLength - 1] == '\\'); /* * If we're left with empty element after trimming, do nothing. @@ -2012,28 +2133,18 @@ Tcl_ConcatObj( Tcl_SetObjLength(resPtr, 0); for (i = 0; i < objc; i++) { - int trim; + int triml, trimr; element = TclGetStringFromObj(objv[i], &elemLength); - /* - * Trim away the leading whitespace. - */ - - trim = TclTrimLeft(element, elemLength, CONCAT_TRIM_SET, - CONCAT_WS_SIZE); - element += trim; - elemLength -= trim; - - /* - * Trim away the trailing whitespace. Do not permit trimming to expose - * a final backslash character. - */ + /* Trim away the leading/trailing whitespace. */ + triml = TclTrim(element, elemLength, CONCAT_TRIM_SET, + CONCAT_WS_SIZE, &trimr); + element += triml; + elemLength -= triml + trimr; - trim = TclTrimRight(element, elemLength, CONCAT_TRIM_SET, - CONCAT_WS_SIZE); - trim -= trim && (element[elemLength - trim - 1] == '\\'); - elemLength -= trim; + /* Do not permit trimming to expose a final backslash character. */ + elemLength += trimr && (element[elemLength - 1] == '\\'); /* * If we're left with empty element after trimming, do nothing. -- cgit v0.12 From 2d87ed6d2935ef33ceddacd1e31a2695a85f5c44 Mon Sep 17 00:00:00 2001 From: dgp Date: Wed, 14 Mar 2018 15:17:27 +0000 Subject: New routine TclStringReplace() serves as a common implementation for both compiled and direct eval paths of [string replace]. One routine to debug, optimize, convert to new data structures, etc. This routine will also make a good core engine for [string insert]. With this refactoring done, the value of the INST_STR_REPLACE instruction is no longer clear. Until now, the value of compiling to it was that it routed you through the "better" of the two implementations. An instruction that does nothing different from what invocation to the direct eval fallback would do does not have obvious value. --- generic/tclCmdMZ.c | 23 +++----- generic/tclExecute.c | 77 +------------------------- generic/tclInt.h | 3 + generic/tclStringObj.c | 145 +++++++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 157 insertions(+), 91 deletions(-) diff --git a/generic/tclCmdMZ.c b/generic/tclCmdMZ.c index 3c5c5e4..eb1c16c 100644 --- a/generic/tclCmdMZ.c +++ b/generic/tclCmdMZ.c @@ -2339,26 +2339,17 @@ StringRplcCmd( } else { Tcl_Obj *resultPtr; - /* - * We are re-fetching in case the string argument is same value as - * an index argument, and shimmering cost us our ustring. - */ - - ustring = Tcl_GetUnicodeFromObj(objv[1], &length); - end = length-1; - if (first < 0) { first = 0; } - - resultPtr = Tcl_NewUnicodeObj(ustring, first); - if (objc == 5) { - Tcl_AppendObjToObj(resultPtr, objv[4]); - } - if (last < end) { - Tcl_AppendUnicodeToObj(resultPtr, ustring + last + 1, - end - last); + if (last > end) { + last = end; } + + resultPtr = TclStringReplace(interp, objv[1], first, + last + 1 - first, (objc == 5) ? objv[4] : NULL, + TCL_STRING_IN_PLACE); + Tcl_SetObjResult(interp, resultPtr); } return TCL_OK; diff --git a/generic/tclExecute.c b/generic/tclExecute.c index 59f6826..ad09713 100644 --- a/generic/tclExecute.c +++ b/generic/tclExecute.c @@ -5467,82 +5467,9 @@ TEBCresume( NEXT_INST_F(1, 0, 0); } - length3 = Tcl_GetCharLength(value3Ptr); + objResultPtr = TclStringReplace(interp, valuePtr, fromIdx, + toIdx - fromIdx + 1, value3Ptr, TCL_STRING_IN_PLACE); - /* - * See if we can splice in place. This happens when the number of - * characters being replaced is the same as the number of characters - * in the string to be inserted. - */ - - if (length3 - 1 == toIdx - fromIdx) { - unsigned char *bytes1, *bytes2; - - if (Tcl_IsShared(valuePtr)) { - objResultPtr = Tcl_DuplicateObj(valuePtr); - } else { - objResultPtr = valuePtr; - } - if (TclIsPureByteArray(objResultPtr) - && TclIsPureByteArray(value3Ptr)) { - bytes1 = Tcl_GetByteArrayFromObj(objResultPtr, NULL); - bytes2 = Tcl_GetByteArrayFromObj(value3Ptr, NULL); - memcpy(bytes1 + fromIdx, bytes2, length3); - } else { - ustring1 = Tcl_GetUnicodeFromObj(objResultPtr, NULL); - ustring2 = Tcl_GetUnicodeFromObj(value3Ptr, NULL); - memcpy(ustring1 + fromIdx, ustring2, - length3 * sizeof(Tcl_UniChar)); - } - Tcl_InvalidateStringRep(objResultPtr); - TclDecrRefCount(value3Ptr); - TRACE_APPEND(("\"%.30s\"\n", O2S(objResultPtr))); - if (objResultPtr == valuePtr) { - NEXT_INST_F(1, 0, 0); - } else { - NEXT_INST_F(1, 1, 1); - } - } - - /* - * Get the unicode representation; this is where we guarantee to lose - * bytearrays. - */ - - ustring1 = Tcl_GetUnicodeFromObj(valuePtr, &length); - length--; - - /* - * Remove substring using copying. - */ - - objResultPtr = NULL; - if (fromIdx > 0) { - objResultPtr = Tcl_NewUnicodeObj(ustring1, fromIdx); - } - if (length3 > 0) { - if (objResultPtr) { - Tcl_AppendObjToObj(objResultPtr, value3Ptr); - } else if (Tcl_IsShared(value3Ptr)) { - objResultPtr = Tcl_DuplicateObj(value3Ptr); - } else { - objResultPtr = value3Ptr; - } - } - if (toIdx < length) { - if (objResultPtr) { - Tcl_AppendUnicodeToObj(objResultPtr, ustring1 + toIdx + 1, - length - toIdx); - } else { - objResultPtr = Tcl_NewUnicodeObj(ustring1 + toIdx + 1, - length - toIdx); - } - } - if (objResultPtr == NULL) { - /* This has to be the case [string replace $s 0 end {}] */ - /* which has result {} which is same as value3Ptr. */ - objResultPtr = value3Ptr; - } if (objResultPtr == value3Ptr) { /* See [Bug 82e7f67325] */ TclDecrRefCount(OBJ_AT_TOS); diff --git a/generic/tclInt.h b/generic/tclInt.h index 57f648c..81b1c05 100644 --- a/generic/tclInt.h +++ b/generic/tclInt.h @@ -4006,6 +4006,9 @@ MODULE_SCOPE int TclStringLast(Tcl_Obj *needle, Tcl_Obj *haystack, int last); MODULE_SCOPE Tcl_Obj * TclStringRepeat(Tcl_Interp *interp, Tcl_Obj *objPtr, int count, int flags); +MODULE_SCOPE Tcl_Obj * TclStringReplace(Tcl_Interp *interp, Tcl_Obj *objPtr, + int first, int count, Tcl_Obj *insertPtr, + int flags); MODULE_SCOPE Tcl_Obj * TclStringReverse(Tcl_Obj *objPtr, int flags); /* Flag values for the [string] ensemble functions. */ diff --git a/generic/tclStringObj.c b/generic/tclStringObj.c index 26a3a28..9913160 100644 --- a/generic/tclStringObj.c +++ b/generic/tclStringObj.c @@ -38,6 +38,7 @@ #include "tommath.h" #include "tclStringRep.h" +#include "assert.h" /* * Prototypes for functions defined later in this file: */ @@ -3531,6 +3532,150 @@ TclStringReverse( /* *--------------------------------------------------------------------------- * + * TclStringReplace -- + * + * Implements the inner engine of the [string replace] command. + * + * The result is a concatenation of a prefix from objPtr, characters + * 0 through first-1, the insertPtr string value, and a suffix from + * objPtr, characters from first + count to the end. The effect is + * as if the inner substring of characters first through first+count-1 + * are removed and replaced with insertPtr. + * If insertPtr is NULL, it is treated as an empty string. + * When passed the flag TCL_STRING_IN_PLACE, this routine will try + * to do the work within objPtr, so long as no sharing forbids it. + * Without that request, or as needed, a new Tcl value will be allocated + * to be the result. + * + * Results: + * A Tcl value that is the result of the substring replacement. + * May return NULL in case of an error. When NULL is returned and + * interp is non-NULL, error information is left in interp + * + *--------------------------------------------------------------------------- + */ + +Tcl_Obj * +TclStringReplace( + Tcl_Interp *interp, /* For error reporting, may be NULL */ + Tcl_Obj *objPtr, /* String to act upon */ + int first, /* First index to replace */ + int count, /* How many chars to replace */ + Tcl_Obj *insertPtr, /* Replacement string, may be NULL */ + int flags) /* TCL_STRING_IN_PLACE => attempt in-place */ +{ + int inPlace = flags & TCL_STRING_IN_PLACE; + Tcl_Obj *result; + + /* Caller is expected to pass sensible arguments */ + assert ( count >= 0 ) ; + assert ( first >= 0 ) ; + + /* Replace nothing with nothing */ + if ((insertPtr == NULL) && (count == 0)) { + if (inPlace) { + return objPtr; + } else { + return Tcl_DuplicateObj(objPtr); + } + } + + /* + * The caller very likely had to call Tcl_GetCharLength() or similar + * to be able to process index values. This means it is like that + * objPtr is either a proper "bytearray" or a "string" or else it has + * a known and short string rep. + */ + + if (TclIsPureByteArray(objPtr)) { + int numBytes; + unsigned char *bytes = Tcl_GetByteArrayFromObj(objPtr, &numBytes); + + if (insertPtr == NULL) { + /* Replace something with nothing. */ + + assert ( first <= numBytes ) ; + assert ( count <= numBytes ) ; + assert ( first + count <= numBytes ) ; + + result = Tcl_NewByteArrayObj(NULL, numBytes - count);/* PANIC? */ + TclAppendBytesToByteArray(result, bytes, first); + TclAppendBytesToByteArray(result, bytes + first + count, + numBytes - count - first); + return result; + } + + /* Replace everything */ + if ((first == 0) && (count == numBytes)) { + return insertPtr; + } + + if (TclIsPureByteArray(insertPtr)) { + int newBytes; + unsigned char *iBytes + = Tcl_GetByteArrayFromObj(insertPtr, &newBytes); + + if (count == newBytes && inPlace && !Tcl_IsShared(objPtr)) { + /* + * Removal count and replacement count are equal. + * Other conditions permit. Do in-place splice. + */ + + memcpy(bytes + first, iBytes, count); + Tcl_InvalidateStringRep(objPtr); + return objPtr; + } + + if (newBytes > INT_MAX - (numBytes - count)) { + if (interp) { + Tcl_SetObjResult(interp, Tcl_ObjPrintf( + "max size for a Tcl value (%d bytes) exceeded", + INT_MAX)); + Tcl_SetErrorCode(interp, "TCL", "MEMORY", NULL); + } + return NULL; + } + result = Tcl_NewByteArrayObj(NULL, numBytes - count + newBytes); + /* PANIC? */ + TclAppendBytesToByteArray(result, bytes, first); + TclAppendBytesToByteArray(result, iBytes, newBytes); + TclAppendBytesToByteArray(result, bytes + first + count, + numBytes - count - first); + return result; + } + + /* Flow through to try other approaches below */ + } + + /* + * TODO: Figure out how not to generate a Tcl_UniChar array rep + * when it can be determined objPtr->bytes points to a string of + * all single-byte characters so we can index it directly. + */ + + /* The traditional implementation... */ + { + int numChars; + Tcl_UniChar *ustring = Tcl_GetUnicodeFromObj(objPtr, &numChars); + + /* TODO: Is there an in-place option worth pursuing here? */ + + result = Tcl_NewUnicodeObj(ustring, first); + if (insertPtr) { + Tcl_AppendObjToObj(result, insertPtr); + } + if (first + count < numChars) { + Tcl_AppendUnicodeToObj(result, ustring + first + count, + numChars - first - count); + } + + return result; + } +} + +/* + *--------------------------------------------------------------------------- + * * FillUnicodeRep -- * * Populate the Unicode internal rep with the Unicode form of its string -- cgit v0.12 From 6e7c474da78d60f2d601b3ce3e2e269fd086c9d4 Mon Sep 17 00:00:00 2001 From: sebres Date: Wed, 14 Mar 2018 17:17:44 +0000 Subject: TclTrim: special case for TrimRight on single char result of TrimLeft (this char is already verified within TrimLeft, so bypass TrimRight at all) --- generic/tclUtil.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/generic/tclUtil.c b/generic/tclUtil.c index a8791c5..fb5b21c 100644 --- a/generic/tclUtil.c +++ b/generic/tclUtil.c @@ -1738,9 +1738,9 @@ TclTrim( int trimLeft; Tcl_DString bytesBuf, trimBuf; + *trimRight = 0; /* Empty strings -> nothing to do */ if ((numBytes == 0) || (numTrim == 0)) { - *trimRight = 0; return 0; } @@ -1754,8 +1754,8 @@ TclTrim( trimLeft = numBytes; } numBytes -= trimLeft; - *trimRight = 0; - if (numBytes) { + /* have to trim yet (first char was already verified within TrimLeft) */ + if (numBytes > 1) { bytes += trimLeft; *trimRight = TrimRight(bytes, numBytes, trim, numTrim); if (*trimRight > numBytes) { -- cgit v0.12 From 43f670e530b608c214f52ccc187f4fb5756a0256 Mon Sep 17 00:00:00 2001 From: dgp Date: Wed, 14 Mar 2018 17:20:53 +0000 Subject: unused variable fix --- generic/tclCmdMZ.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/generic/tclCmdMZ.c b/generic/tclCmdMZ.c index eb1c16c..0b65758 100644 --- a/generic/tclCmdMZ.c +++ b/generic/tclCmdMZ.c @@ -2305,7 +2305,6 @@ StringRplcCmd( int objc, /* Number of arguments. */ Tcl_Obj *const objv[]) /* Argument objects. */ { - Tcl_UniChar *ustring; int first, last, length, end; if (objc < 4 || objc > 5) { @@ -2313,7 +2312,7 @@ StringRplcCmd( return TCL_ERROR; } - ustring = Tcl_GetUnicodeFromObj(objv[1], &length); + length = Tcl_GetCharLength(objv[1]); end = length - 1; if (TclGetIntForIndexM(interp, objv[2], end, &first) != TCL_OK || -- cgit v0.12 From 1bf60bab3cd706cba08c15df5a6a5267d918aeae Mon Sep 17 00:00:00 2001 From: sebres Date: Wed, 14 Mar 2018 17:23:24 +0000 Subject: optimize compiled (INST_STR_TRIM): use new function TclTrim instead of combination of TclTrimLeft/TclTrimRight --- generic/tclExecute.c | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/generic/tclExecute.c b/generic/tclExecute.c index 2ef627d..aab9092 100644 --- a/generic/tclExecute.c +++ b/generic/tclExecute.c @@ -6022,12 +6022,7 @@ TEBCresume( value2Ptr = OBJ_AT_TOS; /* TrimSet */ string2 = TclGetStringFromObj(value2Ptr, &length2); string1 = TclGetStringFromObj(valuePtr, &length); - trim1 = TclTrimLeft(string1, length, string2, length2); - if (trim1 < length) { - trim2 = TclTrimRight(string1, length, string2, length2); - } else { - trim2 = 0; - } + trim1 = TclTrim(string1, length, string2, length2, &trim2); createTrimmedString: /* * Careful here; trim set often contains non-ASCII characters so we -- cgit v0.12 From 73de582148b73bb111830c206bb3e6f566c21131 Mon Sep 17 00:00:00 2001 From: pooryorick Date: Wed, 14 Mar 2018 20:43:20 +0000 Subject: Further work to improve Object reference accounting in order to plug leaks. --- generic/tclOO.c | 44 ++++++---- generic/tclOODefineCmds.c | 39 ++------- tests/oo.test | 212 +++++++++++++++++++++++++++++++++------------- 3 files changed, 188 insertions(+), 107 deletions(-) diff --git a/generic/tclOO.c b/generic/tclOO.c index a129a52..83646a8 100644 --- a/generic/tclOO.c +++ b/generic/tclOO.c @@ -426,17 +426,17 @@ InitFoundation( /* Rewire bootstrapped objects. */ fPtr->objectCls->thisPtr->selfCls = fPtr->classCls; - AddRef(fPtr->objectCls->thisPtr->selfCls->thisPtr); + AddRef(fPtr->classCls->thisPtr); + TclOOAddToInstances(fPtr->objectCls->thisPtr, fPtr->classCls); fPtr->classCls->thisPtr->selfCls = fPtr->classCls; - AddRef(fPtr->classCls->thisPtr->selfCls->thisPtr); + AddRef(fPtr->classCls->thisPtr); + TclOOAddToInstances(fPtr->classCls->thisPtr, fPtr->classCls); fPtr->classCls->thisPtr->flags |= ROOT_CLASS; fPtr->classCls->flags |= ROOT_CLASS; /* Standard initialization for new Objects */ - TclOOAddToInstances(fPtr->objectCls->thisPtr, fPtr->classCls); - TclOOAddToInstances(fPtr->classCls->thisPtr, fPtr->classCls); TclOOAddToSubclasses(fPtr->classCls, fPtr->objectCls); /* @@ -568,12 +568,6 @@ KillFoundation( TclDecrRefCount(fPtr->destructorName); TclDecrRefCount(fPtr->clonedName); TclDecrRefCount(fPtr->defineName); - if (fPtr->objectCls->thisPtr->selfCls != NULL) { - TclOODecrRefCount(fPtr->objectCls->thisPtr->selfCls->thisPtr); - } - if (fPtr->classCls->thisPtr->selfCls != NULL) { - TclOODecrRefCount(fPtr->classCls->thisPtr->selfCls->thisPtr); - } TclOODecrRefCount(fPtr->objectCls->thisPtr); TclOODecrRefCount(fPtr->classCls->thisPtr); @@ -660,6 +654,9 @@ AllocObject( Tcl_ResetResult(interp); } + + configNamespace: + ((Namespace *)oPtr->namespacePtr)->refCount++; /* @@ -667,7 +664,6 @@ AllocObject( * to the [self] and [next] commands. */ - configNamespace: if (fPtr->helpersNs != NULL) { TclSetNsPath((Namespace *) oPtr->namespacePtr, 1, &fPtr->helpersNs); } @@ -1007,8 +1003,11 @@ ReleaseClassContents( if (clsPtr->mixins.num) { FOREACH(tmpClsPtr, clsPtr->mixins) { TclOORemoveFromMixinSubs(clsPtr, tmpClsPtr); + TclOODecrRefCount(tmpClsPtr->thisPtr); } ckfree(clsPtr->mixins.list); + clsPtr->mixins.list = NULL; + clsPtr->mixins.num = 0; } if (clsPtr->superclasses.num > 0) { @@ -1149,6 +1148,7 @@ ObjectNamespaceDeleted( if (oPtr->mixins.num > 0) { FOREACH(mixinPtr, oPtr->mixins) { TclOORemoveFromInstances(oPtr, mixinPtr); + TclOODecrRefCount(mixinPtr->thisPtr); } ckfree(oPtr->mixins.list); } @@ -1837,16 +1837,22 @@ Tcl_CopyObjectInstance( * Copy the object's mixin references to the new object. */ - FOREACH(mixinPtr, o2Ptr->mixins) { - if (mixinPtr && mixinPtr != o2Ptr->selfCls) { - TclOORemoveFromInstances(o2Ptr, mixinPtr); + if (o2Ptr->mixins.num != 0) { + FOREACH(mixinPtr, o2Ptr->mixins) { + if (mixinPtr && mixinPtr != o2Ptr->selfCls) { + TclOORemoveFromInstances(o2Ptr, mixinPtr); + } + TclOODecrRefCount(mixinPtr->thisPtr); } + ckfree(o2Ptr->mixins.list); } DUPLICATE(o2Ptr->mixins, oPtr->mixins, Class *); FOREACH(mixinPtr, o2Ptr->mixins) { if (mixinPtr && mixinPtr != o2Ptr->selfCls) { TclOOAddToInstances(o2Ptr, mixinPtr); } + /* For the reference just created in DUPLICATE */ + AddRef(mixinPtr->thisPtr); } /* @@ -1924,6 +1930,7 @@ Tcl_CopyObjectInstance( FOREACH(superPtr, cls2Ptr->superclasses) { TclOORemoveFromSubclasses(cls2Ptr, superPtr); + TclOODecrRefCount(superPtr->thisPtr); } if (cls2Ptr->superclasses.num) { cls2Ptr->superclasses.list = ckrealloc(cls2Ptr->superclasses.list, @@ -1967,15 +1974,18 @@ Tcl_CopyObjectInstance( * references to the duplicate). */ - FOREACH(mixinPtr, cls2Ptr->mixins) { - TclOORemoveFromMixinSubs(cls2Ptr, mixinPtr); - } if (cls2Ptr->mixins.num != 0) { + FOREACH(mixinPtr, cls2Ptr->mixins) { + TclOORemoveFromMixinSubs(cls2Ptr, mixinPtr); + TclOODecrRefCount(mixinPtr->thisPtr); + } ckfree(clsPtr->mixins.list); } DUPLICATE(cls2Ptr->mixins, clsPtr->mixins, Class *); FOREACH(mixinPtr, cls2Ptr->mixins) { TclOOAddToMixinSubs(cls2Ptr, mixinPtr); + /* For the copy just created in DUPLICATE */ + AddRef(mixinPtr->thisPtr); } /* diff --git a/generic/tclOODefineCmds.c b/generic/tclOODefineCmds.c index dfd2acf..648ad02 100644 --- a/generic/tclOODefineCmds.c +++ b/generic/tclOODefineCmds.c @@ -327,6 +327,7 @@ TclOOObjectSetMixins( if (oPtr->mixins.num != 0) { FOREACH(mixinPtr, oPtr->mixins) { TclOORemoveFromInstances(oPtr, mixinPtr); + TclOODecrRefCount(mixinPtr->thisPtr); } ckfree(oPtr->mixins.list); oPtr->mixins.num = 0; @@ -338,6 +339,7 @@ TclOOObjectSetMixins( if (mixinPtr && mixinPtr != oPtr->selfCls) { TclOORemoveFromInstances(oPtr, mixinPtr); } + TclOODecrRefCount(mixinPtr->thisPtr); } oPtr->mixins.list = ckrealloc(oPtr->mixins.list, sizeof(Class *) * numMixins); @@ -350,10 +352,8 @@ TclOOObjectSetMixins( FOREACH(mixinPtr, oPtr->mixins) { if (mixinPtr != oPtr->selfCls) { TclOOAddToInstances(oPtr, mixinPtr); - /* Corresponding TclOODecrRefCount() is in the caller of this - * function. - */ - TclOODecrRefCount(mixinPtr->thisPtr); + /* For the new copy created by memcpy */ + AddRef(mixinPtr->thisPtr); } } } @@ -383,6 +383,7 @@ TclOOClassSetMixins( if (classPtr->mixins.num != 0) { FOREACH(mixinPtr, classPtr->mixins) { TclOORemoveFromMixinSubs(classPtr, mixinPtr); + TclOODecrRefCount(mixinPtr->thisPtr); } ckfree(classPtr->mixins.list); classPtr->mixins.num = 0; @@ -391,6 +392,7 @@ TclOOClassSetMixins( if (classPtr->mixins.num != 0) { FOREACH(mixinPtr, classPtr->mixins) { TclOORemoveFromMixinSubs(classPtr, mixinPtr); + TclOODecrRefCount(mixinPtr->thisPtr); } classPtr->mixins.list = ckrealloc(classPtr->mixins.list, sizeof(Class *) * numMixins); @@ -401,10 +403,8 @@ TclOOClassSetMixins( memcpy(classPtr->mixins.list, mixins, sizeof(Class *) * numMixins); FOREACH(mixinPtr, classPtr->mixins) { TclOOAddToMixinSubs(classPtr, mixinPtr); - /* Corresponding TclOODecrRefCount() is in the caller of this - * function - */ - TclOODecrRefCount(mixinPtr->thisPtr); + /* For the new copy created by memcpy */ + AddRef(mixinPtr->thisPtr); } } BumpGlobalEpoch(interp, classPtr); @@ -1125,7 +1125,6 @@ TclOODefineClassObjCmd( */ if (oPtr->selfCls != clsPtr) { - TclOORemoveFromInstances(oPtr, oPtr->selfCls); TclOODecrRefCount(oPtr->selfCls->thisPtr); oPtr->selfCls = clsPtr; @@ -1587,10 +1586,6 @@ TclOODefineMixinObjCmd( goto freeAndError; } mixins[i-1] = clsPtr; - /* Corresponding TclOODecrRefCount() is in TclOOObjectSetMixins, - * TclOOClassSetMixinsk, or just below if this function fails. - */ - AddRef(mixins[i-1]->thisPtr); } if (isInstanceMixin) { @@ -1603,9 +1598,6 @@ TclOODefineMixinObjCmd( return TCL_OK; freeAndError: - while (--i > 0) { - TclOODecrRefCount(mixins[i]->thisPtr); - } TclStackFree(interp, mixins); return TCL_ERROR; } @@ -2030,10 +2022,6 @@ ClassMixinSet( Tcl_SetErrorCode(interp, "TCL", "OO", "SELF_MIXIN", NULL); goto freeAndError; } - /* Corresponding TclOODecrRefCount() is in TclOOClassSetMixins, or just - * below if this function fails - */ - AddRef(mixins[i]->thisPtr); } TclOOClassSetMixins(interp, oPtr->classPtr, mixinc, mixins); @@ -2041,9 +2029,6 @@ ClassMixinSet( return TCL_OK; freeAndError: - while (i-- > 0) { - TclOODecrRefCount(mixins[i]->thisPtr); - } TclStackFree(interp, mixins); return TCL_ERROR; } @@ -2197,6 +2182,7 @@ ClassSuperSet( if (oPtr->classPtr->superclasses.num != 0) { FOREACH(superPtr, oPtr->classPtr->superclasses) { TclOORemoveFromSubclasses(oPtr->classPtr, superPtr); + TclOODecrRefCount(superPtr->thisPtr); } ckfree((char *) oPtr->classPtr->superclasses.list); } @@ -2494,16 +2480,9 @@ ObjMixinSet( mixins[i] = GetClassInOuterContext(interp, mixinv[i], "may only mix in classes"); if (mixins[i] == NULL) { - while (i-- > 0) { - TclOODecrRefCount(mixins[i]->thisPtr); - } TclStackFree(interp, mixins); return TCL_ERROR; } - /* Corresponding TclOODecrRefCount() is in TclOOObjectSetMixins() or - * just above if this function fails. - */ - AddRef(mixins[i]->thisPtr); } TclOOObjectSetMixins(oPtr, mixinc, mixins); diff --git a/tests/oo.test b/tests/oo.test index a698bac..fbf75b6 100644 --- a/tests/oo.test +++ b/tests/oo.test @@ -13,6 +13,13 @@ if {"::tcltest" in [namespace children]} { namespace import -force ::tcltest::* } + +# The foundational objects oo::object and oo::class are sensitive to reference +# counting errors and are deallocated only when an interp is deleted, so in +# this test suite, interp creation and interp deletion are often used in +# leaktests in order to leverage this sensitivity. + + testConstraint memory [llength [info commands memory]] if {[testConstraint memory]} { proc getbytes {} { @@ -271,7 +278,21 @@ test oo-1.18 {OO: create object in NS with same name as global cmd} -setup { rename test-oo-1.18 {} A destroy } -result ::C -test oo-1.18.1 {Bug 75b8433707: memory leak in oo-1.18} -setup { +test oo-1.18.1 {no memory leak: superclass} -setup { +} -constraints memory -body { + + leaktest { + interp create t + t eval { + oo::class create A { + superclass oo::class + } + } + interp delete t + } +} -cleanup { +} -result 0 +test oo-1.18.2 {Bug 75b8433707: memory leak in oo-1.18} -setup { proc test-oo-1.18 {} return } -constraints memory -body { leaktest { @@ -284,7 +305,7 @@ test oo-1.18.1 {Bug 75b8433707: memory leak in oo-1.18} -setup { } -cleanup { rename test-oo-1.18 {} } -result 0 -test oo-1.18.2 {Bug 21c144f0f5} -setup { +test oo-1.18.3 {Bug 21c144f0f5} -setup { interp create slave } -body { slave eval { @@ -1508,7 +1529,56 @@ test oo-11.5 {OO: cleanup} { return done } done -test oo-11.6 { +test oo-11.6.1 { + OO: cleanup of when an class is mixed into itself +} -constraints memory -body { + leaktest { + interp create interp1 + oo::class create obj1 + ::oo::define obj1 {self mixin [uplevel 1 {namespace which obj1}]} + rename obj1 {} + interp delete interp1 + } +} -result 0 -cleanup { +} + +test oo-11.6.2 { + OO: cleanup ReleaseClassContents() where class is mixed into one of its + instances +} -body { + leaktest { + interp create interp1 + interp1 eval { + oo::class create obj1 + ::oo::copy obj1 obj2 + rename obj2 {} + rename obj1 {} + } + interp delete interp1 + } +} -result 0 -cleanup { +} + +test oo-11.6.3 { + OO: cleanup ReleaseClassContents() where class is mixed into one of its + instances +} -body { + leaktest { + interp create interp1 + interp1 eval { + oo::class create obj1 + ::oo::define obj1 {self mixin [uplevel 1 {namespace which obj1}]} + + ::oo::copy obj1 obj2 + rename obj2 {} + rename obj1 {} + } + interp delete interp1 + } +} -result 0 -cleanup { +} + +test oo-11.6.4 { OO: cleanup ReleaseClassContents() where class is mixed into one of its instances } -body { @@ -2071,7 +2141,18 @@ test oo-15.12 {OO: object cloning with target NS} -setup { Super destroy catch {namespace delete ::existing} } -result {::existing refers to an existing namespace} -test oo-15.13 {OO: object cloning with target NS} -setup { +test oo-15.13.1 { + OO: object cloning with target NS + Valgrind will report a leak if the reference count of the namespace isn't + properly incremented. +} -setup { + oo::class create Cls {} +} -body { + oo::copy Cls Cls2 ::dupens + return done +} -cleanup { +} -result done +test oo-15.13.2 {OO: object cloning with target NS} -setup { oo::class create Super oo::class create Cls {superclass Super} } -body { @@ -3666,99 +3747,110 @@ test oo-31.2 {Bug 3111059: when objects and coroutines entangle} -setup { cls destroy } -result {0 {}} -oo::class create SampleSlot { - superclass oo::Slot - constructor {} { - variable contents {a b c} ops {} - } - method contents {} {variable contents; return $contents} - method ops {} {variable ops; return $ops} - method Get {} { - variable contents - variable ops - lappend ops [info level] Get - return $contents - } - method Set {lst} { - variable contents $lst - variable ops - lappend ops [info level] Set $lst - return +proc SampleSlotSetup script { + set script0 { + oo::class create SampleSlot { + superclass oo::Slot + constructor {} { + variable contents {a b c} ops {} + } + method contents {} {variable contents; return $contents} + method ops {} {variable ops; return $ops} + method Get {} { + variable contents + variable ops + lappend ops [info level] Get + return $contents + } + method Set {lst} { + variable contents $lst + variable ops + lappend ops [info level] Set $lst + return + } + } + } + append script0 \n$script +} + +proc SampleSlotCleanup script { + set script0 { + SampleSlot destroy } + append script \n$script0 } -test oo-32.1 {TIP 380: slots - class test} -setup { +test oo-32.1 {TIP 380: slots - class test} -setup [SampleSlotSetup { SampleSlot create sampleSlot -} -body { +}] -body { list [info level] [sampleSlot contents] [sampleSlot ops] -} -cleanup { +} -cleanup [SampleSlotCleanup { rename sampleSlot {} -} -result {0 {a b c} {}} -test oo-32.2 {TIP 380: slots - class test} -setup { +}] -result {0 {a b c} {}} +test oo-32.2 {TIP 380: slots - class test} -setup [SampleSlotSetup { SampleSlot create sampleSlot -} -body { +}] -body { list [info level] [sampleSlot -clear] \ [sampleSlot contents] [sampleSlot ops] -} -cleanup { +} -cleanup [SampleSlotCleanup { rename sampleSlot {} -} -result {0 {} {} {1 Set {}}} -test oo-32.3 {TIP 380: slots - class test} -setup { +}] -result {0 {} {} {1 Set {}}} +test oo-32.3 {TIP 380: slots - class test} -setup [SampleSlotSetup { SampleSlot create sampleSlot -} -body { +}] -body { list [info level] [sampleSlot -append g h i] \ [sampleSlot contents] [sampleSlot ops] -} -cleanup { +} -cleanup [SampleSlotCleanup { rename sampleSlot {} -} -result {0 {} {a b c g h i} {1 Get 1 Set {a b c g h i}}} -test oo-32.4 {TIP 380: slots - class test} -setup { +}] -result {0 {} {a b c g h i} {1 Get 1 Set {a b c g h i}}} +test oo-32.4 {TIP 380: slots - class test} -setup [SampleSlotSetup { SampleSlot create sampleSlot -} -body { +}] -body { list [info level] [sampleSlot -set d e f] \ [sampleSlot contents] [sampleSlot ops] -} -cleanup { +} -cleanup [SampleSlotCleanup { rename sampleSlot {} -} -result {0 {} {d e f} {1 Set {d e f}}} -test oo-32.5 {TIP 380: slots - class test} -setup { +}] -result {0 {} {d e f} {1 Set {d e f}}} +test oo-32.5 {TIP 380: slots - class test} -setup [SampleSlotSetup { SampleSlot create sampleSlot -} -body { +}] -body { list [info level] [sampleSlot -set d e f] [sampleSlot -append g h i] \ [sampleSlot contents] [sampleSlot ops] -} -cleanup { +} -cleanup [SampleSlotCleanup { rename sampleSlot {} -} -result {0 {} {} {d e f g h i} {1 Set {d e f} 1 Get 1 Set {d e f g h i}}} +}] -result {0 {} {} {d e f g h i} {1 Set {d e f} 1 Get 1 Set {d e f g h i}}} -test oo-33.1 {TIP 380: slots - defaulting} -setup { +test oo-33.1 {TIP 380: slots - defaulting} -setup [SampleSlotSetup { set s [SampleSlot new] -} -body { +}] -body { list [$s x y] [$s contents] -} -cleanup { +} -cleanup [SampleSlotCleanup { rename $s {} -} -result {{} {a b c x y}} -test oo-33.2 {TIP 380: slots - defaulting} -setup { +}] -result {{} {a b c x y}} +test oo-33.2 {TIP 380: slots - defaulting} -setup [SampleSlotSetup { set s [SampleSlot new] -} -body { +}] -body { list [$s destroy; $s unknown] [$s contents] -} -cleanup { +} -cleanup [SampleSlotCleanup { rename $s {} -} -result {{} {a b c destroy unknown}} -test oo-33.3 {TIP 380: slots - defaulting} -setup { +}] -result {{} {a b c destroy unknown}} +test oo-33.3 {TIP 380: slots - defaulting} -setup [SampleSlotSetup { set s [SampleSlot new] -} -body { +}] -body { oo::objdefine $s forward --default-operation my -set list [$s destroy; $s unknown] [$s contents] [$s ops] -} -cleanup { +} -cleanup [SampleSlotCleanup { rename $s {} -} -result {{} unknown {1 Set destroy 1 Set unknown}} -test oo-33.4 {TIP 380: slots - errors} -setup { +}] -result {{} unknown {1 Set destroy 1 Set unknown}} +test oo-33.4 {TIP 380: slots - errors} -setup [SampleSlotSetup { set s [SampleSlot new] -} -body { +}] -body { # Method names beginning with "-" are special to slots $s -grill q -} -returnCodes error -cleanup { +} -returnCodes error -cleanup [SampleSlotCleanup { rename $s {} -} -result {unknown method "-grill": must be -append, -clear, -set, contents or ops} - -SampleSlot destroy +}] -result \ + {unknown method "-grill": must be -append, -clear, -set, contents or ops} test oo-34.1 {TIP 380: slots - presence} -setup { set obj [oo::object new] -- cgit v0.12 From 6d4320b5fbe2afd973751c4b5de70a89e0d62214 Mon Sep 17 00:00:00 2001 From: dgp Date: Wed, 14 Mar 2018 20:59:01 +0000 Subject: A few test hygiene fixes. --- tests/oo.test | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/tests/oo.test b/tests/oo.test index fbf75b6..024f890 100644 --- a/tests/oo.test +++ b/tests/oo.test @@ -1545,7 +1545,7 @@ test oo-11.6.1 { test oo-11.6.2 { OO: cleanup ReleaseClassContents() where class is mixed into one of its instances -} -body { +} -constraints memory -body { leaktest { interp create interp1 interp1 eval { @@ -1562,7 +1562,7 @@ test oo-11.6.2 { test oo-11.6.3 { OO: cleanup ReleaseClassContents() where class is mixed into one of its instances -} -body { +} -constraints memory -body { leaktest { interp create interp1 interp1 eval { @@ -2151,6 +2151,8 @@ test oo-15.13.1 { oo::copy Cls Cls2 ::dupens return done } -cleanup { + Cls destroy + Cls2 destroy } -result done test oo-15.13.2 {OO: object cloning with target NS} -setup { oo::class create Super -- cgit v0.12 From c5e979695a611130614e19fa74d14f26de62dab3 Mon Sep 17 00:00:00 2001 From: dgp Date: Thu, 15 Mar 2018 10:58:13 +0000 Subject: Missing test cleanups that break later tests. --- tests/coroutine.test | 2 ++ tests/foreach.test | 6 ++++-- tests/ioCmd.test | 4 ++++ tests/ioTrans.test | 2 ++ 4 files changed, 12 insertions(+), 2 deletions(-) diff --git a/tests/coroutine.test b/tests/coroutine.test index fd68567..8a5494d 100644 --- a/tests/coroutine.test +++ b/tests/coroutine.test @@ -739,6 +739,8 @@ test coroutine-7.12 {coro floor above street level #3008307} -body { } boom ; # does not crash: the coro floor is a good insulator list +} -cleanup { + rename boom {}; rename cc {}; rename c {} } -result {} test coroutine-8.0.0 {coro inject executed} -body { diff --git a/tests/foreach.test b/tests/foreach.test index 6fd5476..84af4bd 100644 --- a/tests/foreach.test +++ b/tests/foreach.test @@ -212,14 +212,16 @@ test foreach-6.4 {break tests} { set msg } {wrong # args: should be "break"} # Check for bug #406709 -test foreach-6.5 {break tests} { +test foreach-6.5 {break tests} -body { proc a {} { set a 1 foreach b b {list [concat a; break]; incr a} incr a } a -} {2} +} -cleanup { + rename a {} +} -result {2} # Test for incorrect "double evaluation" semantics test foreach-7.1 {delayed substitution of body} { diff --git a/tests/ioCmd.test b/tests/ioCmd.test index b4ba04a..cab4e97 100644 --- a/tests/ioCmd.test +++ b/tests/ioCmd.test @@ -2057,6 +2057,8 @@ test iocmd-32.0 {origin interpreter of moved channel gone} -match glob -body { lappend res [catch {interp eval $idb [list close $chan]} msg] $msg set res +} -cleanup { + interp delete $idb } -constraints {testchannel} \ -result {1 {Owner lost} 1 {Owner lost} 1 {Owner lost} 1 {Owner lost} 1 {Owner lost}} @@ -2099,6 +2101,8 @@ test iocmd-32.1 {origin interpreter of moved channel destroyed during access} -m set res }] set res +} -cleanup { + interp delete $idb } -constraints {testchannel} -result {Owner lost} test iocmd-32.2 {delete interp of reflected chan} { diff --git a/tests/ioTrans.test b/tests/ioTrans.test index e179eab..3bebc70 100644 --- a/tests/ioTrans.test +++ b/tests/ioTrans.test @@ -1200,6 +1200,7 @@ test iortrans-11.0 {origin interpreter of moved transform gone} -setup { # without invoking the transform handler. } -cleanup { tempdone + interp delete $idb } -result {1 {Owner lost} 0 0 1 {Owner lost} 1 {Owner lost} 1 {Owner lost}} test iortrans-11.1 {origin interpreter of moved transform destroyed during access} -setup { set ida [interp create]; #puts <<$ida>> @@ -1240,6 +1241,7 @@ test iortrans-11.1 {origin interpreter of moved transform destroyed during acces }] } -cleanup { tempdone + interp delete $idb } -result {Owner lost} test iortrans-11.2 {delete interp of reflected transform} -setup { interp create slave -- cgit v0.12 From df06afadcfb949909d6a640b77fe234e266dc848 Mon Sep 17 00:00:00 2001 From: "jan.nijtmans" Date: Thu, 15 Mar 2018 20:58:00 +0000 Subject: Bring back makefile.vc to CRLF line-endings, as all other *.vc files --- win/makefile.vc | 1890 +++++++++++++++++++++++++++---------------------------- 1 file changed, 945 insertions(+), 945 deletions(-) diff --git a/win/makefile.vc b/win/makefile.vc index 7ed4c63..918c6b7 100644 --- a/win/makefile.vc +++ b/win/makefile.vc @@ -1,945 +1,945 @@ -#------------------------------------------------------------- -*- makefile -*- -# -# Microsoft Visual C++ makefile for building Tcl with nmake -# -# See the file "license.terms" for information on usage and redistribution -# of this file, and for a DISCLAIMER OF ALL WARRANTIES. -# -# Copyright (c) 1995-1996 Sun Microsystems, Inc. -# Copyright (c) 1998-2000 Ajuba Solutions. -# Copyright (c) 2001-2005 ActiveState Corporation. -# Copyright (c) 2001-2004 David Gravereaux. -# Copyright (c) 2003-2008 Pat Thoyts. -# Copyright (c) 2017 Ashok P. Nadkarni -#------------------------------------------------------------------------------ - -# General usage: -# nmake [-nologo] -f makefile.vc [TARGET|MACRODEF [TARGET|MACRODEF] [...]] -# -# For MACRODEF, see TIP 477 (https://core.tcl.tk/tips/doc/trunk/tip/477.md) -# or examine Sections 6-8 in rules.vc. -# -# Possible values of TARGET are: -# release -- Builds the core, the shell and the dlls. (default) -# dlls -- Just builds the windows extensions -# shell -- Just builds the shell and the core. -# core -- Only builds the core [tclXX.(dll|lib)]. -# all -- Builds everything. -# test -- Builds and runs the test suite. -# tcltest -- Just builds the test shell. -# install -- Installs the built binaries and libraries to $(INSTALLDIR) -# as the root of the install tree. -# tidy/clean/hose -- varying levels of cleaning. -# genstubs -- Rebuilds the Stubs table and support files (dev only). -# depend -- Generates an accurate set of source dependancies for this -# makefile. Helpful to avoid problems when the sources are -# refreshed and you rebuild, but can "overbuild" when common -# headers like tclInt.h just get small changes. -# htmlhelp -- Builds a Windows .chm help file for Tcl and Tk from the -# troff manual pages found in $(ROOT)\doc. You need to -# have installed the HTML Help Compiler package from Microsoft -# to produce the .chm file. -# -# The steps to setup a Visual C++ environment depend on which -# version of Visual Studio and/or the Windows SDK you are building -# against and are not described here. The simplest method is generally -# to start a command shell using one of the short cuts installed by -# Visual Studio/Windows SDK for the appropriate target architecture. -# -# NOTE: For older (Visual C++ 6 or the 2003 SDK), to use the Platform -# SDK (not expressly needed), run setenv.bat after -# vcvars32.bat according to the instructions for it. This can also -# turn on the 64-bit compiler, if your SDK has it. -# -# Examples: -# c:\tcl_src\win\>nmake -f makefile.vc release -# c:\tcl_src\win\>nmake -f makefile.vc test -# c:\tcl_src\win\>nmake -f makefile.vc install INSTALLDIR=c:\progra~1\tcl -# c:\tcl_src\win\>nmake -f makefile.vc release OPTS=pdbs -# c:\tcl_src\win\>nmake -f makefile.vc release OPTS=symbols -# - -# NOTE: -# Before modifying this file, check whether the modification is applicable -# to building extensions as well and if so, modify rules.vc instead. - -# The PROJECT macro is used by rules.vc for generating appropriate -# macros and rules. -PROJECT = tcl - -# Default target to build if no target is specified. If unspecified, the -# rules.vc file will set up "all" as the target. -DEFAULT_BUILD_TARGET = release - -# We want to use our own resource file, not the standard template one. -RCFILE = tcl.rc - -# The rules.vc file does most of the hard work in terms of defining -# the build configuration, macros, output directories etc. -!include "rules.vc" - -# Tcl version info based on macros set up by rules.vc -DOTVERSION = $(TCL_MAJOR_VERSION).$(TCL_MINOR_VERSION) -VERSION = $(TCL_MAJOR_VERSION)$(TCL_MINOR_VERSION) - -# We need versions of various core packages to generate appropriate -# file names during installation. -!if [echo REM = This file is generated from makefile.vc > versions.vc] -!endif -!if [echo PKG_HTTP_VER = \>> versions.vc] \ - && [nmakehlp -V ..\library\http\pkgIndex.tcl http >> versions.vc] -!endif -!if [echo PKG_TCLTEST_VER = \>> versions.vc] \ - && [nmakehlp -V ..\library\tcltest\pkgIndex.tcl tcltest >> versions.vc] -!endif -!if [echo PKG_MSGCAT_VER = \>> versions.vc] \ - && [nmakehlp -V ..\library\msgcat\pkgIndex.tcl msgcat >> versions.vc] -!endif -!if [echo PKG_PLATFORM_VER = \>> versions.vc] \ - && [nmakehlp -V ..\library\platform\pkgIndex.tcl "platform " >> versions.vc] -!endif -!if [echo PKG_SHELL_VER = \>> versions.vc] \ - && [nmakehlp -V ..\library\platform\pkgIndex.tcl "platform::shell" >> versions.vc] -!endif -!if [echo PKG_DDE_VER = \>> versions.vc] \ - && [nmakehlp -V ..\library\dde\pkgIndex.tcl "dde " >> versions.vc] -!endif -!if [echo PKG_REG_VER =\>> versions.vc] \ - && [nmakehlp -V ..\library\reg\pkgIndex.tcl registry >> versions.vc] -!endif - -!include versions.vc - -DDEDOTVERSION = 1.4 -DDEVERSION = $(DDEDOTVERSION:.=) - -REGDOTVERSION = 1.3 -REGVERSION = $(REGDOTVERSION:.=) - -TCLREGLIBNAME = $(PROJECT)reg$(REGVERSION)$(SUFX:t=).$(EXT) -TCLREGLIB = $(OUT_DIR)\$(TCLREGLIBNAME) - -TCLDDELIBNAME = $(PROJECT)dde$(DDEVERSION)$(SUFX:t=).$(EXT) -TCLDDELIB = $(OUT_DIR)\$(TCLDDELIBNAME) - -TCLTEST = $(OUT_DIR)\$(PROJECT)test.exe -CAT32 = $(OUT_DIR)\cat32.exe - -TCLSHOBJS = \ - $(TMP_DIR)\tclAppInit.obj \ -!if !$(STATIC_BUILD) -!if $(TCL_USE_STATIC_PACKAGES) - $(TMP_DIR)\tclWinReg.obj \ - $(TMP_DIR)\tclWinDde.obj \ -!endif -!endif - $(TMP_DIR)\tclsh.res - -TCLTESTOBJS = \ - $(TMP_DIR)\tclTest.obj \ - $(TMP_DIR)\tclTestObj.obj \ - $(TMP_DIR)\tclTestProcBodyObj.obj \ - $(TMP_DIR)\tclThreadTest.obj \ - $(TMP_DIR)\tclWinTest.obj \ -!if !$(STATIC_BUILD) -!if $(TCL_USE_STATIC_PACKAGES) - $(TMP_DIR)\tclWinReg.obj \ - $(TMP_DIR)\tclWinDde.obj \ -!endif -!endif - $(TMP_DIR)\testMain.obj - -COREOBJS = \ - $(TMP_DIR)\regcomp.obj \ - $(TMP_DIR)\regerror.obj \ - $(TMP_DIR)\regexec.obj \ - $(TMP_DIR)\regfree.obj \ - $(TMP_DIR)\tclAlloc.obj \ - $(TMP_DIR)\tclAssembly.obj \ - $(TMP_DIR)\tclAsync.obj \ - $(TMP_DIR)\tclBasic.obj \ - $(TMP_DIR)\tclBinary.obj \ - $(TMP_DIR)\tclCkalloc.obj \ - $(TMP_DIR)\tclClock.obj \ - $(TMP_DIR)\tclCmdAH.obj \ - $(TMP_DIR)\tclCmdIL.obj \ - $(TMP_DIR)\tclCmdMZ.obj \ - $(TMP_DIR)\tclCompCmds.obj \ - $(TMP_DIR)\tclCompCmdsGR.obj \ - $(TMP_DIR)\tclCompCmdsSZ.obj \ - $(TMP_DIR)\tclCompExpr.obj \ - $(TMP_DIR)\tclCompile.obj \ - $(TMP_DIR)\tclConfig.obj \ - $(TMP_DIR)\tclDate.obj \ - $(TMP_DIR)\tclDictObj.obj \ - $(TMP_DIR)\tclDisassemble.obj \ - $(TMP_DIR)\tclEncoding.obj \ - $(TMP_DIR)\tclEnsemble.obj \ - $(TMP_DIR)\tclEnv.obj \ - $(TMP_DIR)\tclEvent.obj \ - $(TMP_DIR)\tclExecute.obj \ - $(TMP_DIR)\tclFCmd.obj \ - $(TMP_DIR)\tclFileName.obj \ - $(TMP_DIR)\tclGet.obj \ - $(TMP_DIR)\tclHash.obj \ - $(TMP_DIR)\tclHistory.obj \ - $(TMP_DIR)\tclIndexObj.obj \ - $(TMP_DIR)\tclInterp.obj \ - $(TMP_DIR)\tclIO.obj \ - $(TMP_DIR)\tclIOCmd.obj \ - $(TMP_DIR)\tclIOGT.obj \ - $(TMP_DIR)\tclIOSock.obj \ - $(TMP_DIR)\tclIOUtil.obj \ - $(TMP_DIR)\tclIORChan.obj \ - $(TMP_DIR)\tclIORTrans.obj \ - $(TMP_DIR)\tclLink.obj \ - $(TMP_DIR)\tclListObj.obj \ - $(TMP_DIR)\tclLiteral.obj \ - $(TMP_DIR)\tclLoad.obj \ - $(TMP_DIR)\tclMain.obj \ - $(TMP_DIR)\tclMain2.obj \ - $(TMP_DIR)\tclNamesp.obj \ - $(TMP_DIR)\tclNotify.obj \ - $(TMP_DIR)\tclOO.obj \ - $(TMP_DIR)\tclOOBasic.obj \ - $(TMP_DIR)\tclOOCall.obj \ - $(TMP_DIR)\tclOODefineCmds.obj \ - $(TMP_DIR)\tclOOInfo.obj \ - $(TMP_DIR)\tclOOMethod.obj \ - $(TMP_DIR)\tclOOStubInit.obj \ - $(TMP_DIR)\tclObj.obj \ - $(TMP_DIR)\tclOptimize.obj \ - $(TMP_DIR)\tclPanic.obj \ - $(TMP_DIR)\tclParse.obj \ - $(TMP_DIR)\tclPathObj.obj \ - $(TMP_DIR)\tclPipe.obj \ - $(TMP_DIR)\tclPkg.obj \ - $(TMP_DIR)\tclPkgConfig.obj \ - $(TMP_DIR)\tclPosixStr.obj \ - $(TMP_DIR)\tclPreserve.obj \ - $(TMP_DIR)\tclProc.obj \ - $(TMP_DIR)\tclProcess.obj \ - $(TMP_DIR)\tclRegexp.obj \ - $(TMP_DIR)\tclResolve.obj \ - $(TMP_DIR)\tclResult.obj \ - $(TMP_DIR)\tclScan.obj \ - $(TMP_DIR)\tclStringObj.obj \ - $(TMP_DIR)\tclStrToD.obj \ - $(TMP_DIR)\tclStubInit.obj \ - $(TMP_DIR)\tclThread.obj \ - $(TMP_DIR)\tclThreadAlloc.obj \ - $(TMP_DIR)\tclThreadJoin.obj \ - $(TMP_DIR)\tclThreadStorage.obj \ - $(TMP_DIR)\tclTimer.obj \ - $(TMP_DIR)\tclTomMathInterface.obj \ - $(TMP_DIR)\tclTrace.obj \ - $(TMP_DIR)\tclUtf.obj \ - $(TMP_DIR)\tclUtil.obj \ - $(TMP_DIR)\tclVar.obj \ - $(TMP_DIR)\tclZlib.obj - -ZLIBOBJS = \ - $(TMP_DIR)\adler32.obj \ - $(TMP_DIR)\compress.obj \ - $(TMP_DIR)\crc32.obj \ - $(TMP_DIR)\deflate.obj \ - $(TMP_DIR)\infback.obj \ - $(TMP_DIR)\inffast.obj \ - $(TMP_DIR)\inflate.obj \ - $(TMP_DIR)\inftrees.obj \ - $(TMP_DIR)\trees.obj \ - $(TMP_DIR)\uncompr.obj \ - $(TMP_DIR)\zutil.obj - -TOMMATHOBJS = \ - $(TMP_DIR)\bncore.obj \ - $(TMP_DIR)\bn_reverse.obj \ - $(TMP_DIR)\bn_fast_s_mp_mul_digs.obj \ - $(TMP_DIR)\bn_fast_s_mp_sqr.obj \ - $(TMP_DIR)\bn_mp_add.obj \ - $(TMP_DIR)\bn_mp_add_d.obj \ - $(TMP_DIR)\bn_mp_and.obj \ - $(TMP_DIR)\bn_mp_clamp.obj \ - $(TMP_DIR)\bn_mp_clear.obj \ - $(TMP_DIR)\bn_mp_clear_multi.obj \ - $(TMP_DIR)\bn_mp_cmp.obj \ - $(TMP_DIR)\bn_mp_cmp_d.obj \ - $(TMP_DIR)\bn_mp_cmp_mag.obj \ - $(TMP_DIR)\bn_mp_cnt_lsb.obj \ - $(TMP_DIR)\bn_mp_copy.obj \ - $(TMP_DIR)\bn_mp_count_bits.obj \ - $(TMP_DIR)\bn_mp_div.obj \ - $(TMP_DIR)\bn_mp_div_d.obj \ - $(TMP_DIR)\bn_mp_div_2.obj \ - $(TMP_DIR)\bn_mp_div_2d.obj \ - $(TMP_DIR)\bn_mp_div_3.obj \ - $(TMP_DIR)\bn_mp_exch.obj \ - $(TMP_DIR)\bn_mp_expt_d.obj \ - $(TMP_DIR)\bn_mp_expt_d_ex.obj \ - $(TMP_DIR)\bn_mp_get_int.obj \ - $(TMP_DIR)\bn_mp_get_long.obj \ - $(TMP_DIR)\bn_mp_get_long_long.obj \ - $(TMP_DIR)\bn_mp_grow.obj \ - $(TMP_DIR)\bn_mp_init.obj \ - $(TMP_DIR)\bn_mp_init_copy.obj \ - $(TMP_DIR)\bn_mp_init_multi.obj \ - $(TMP_DIR)\bn_mp_init_set.obj \ - $(TMP_DIR)\bn_mp_init_set_int.obj \ - $(TMP_DIR)\bn_mp_init_size.obj \ - $(TMP_DIR)\bn_mp_karatsuba_mul.obj \ - $(TMP_DIR)\bn_mp_karatsuba_sqr.obj \ - $(TMP_DIR)\bn_mp_lshd.obj \ - $(TMP_DIR)\bn_mp_mod.obj \ - $(TMP_DIR)\bn_mp_mod_2d.obj \ - $(TMP_DIR)\bn_mp_mul.obj \ - $(TMP_DIR)\bn_mp_mul_2.obj \ - $(TMP_DIR)\bn_mp_mul_2d.obj \ - $(TMP_DIR)\bn_mp_mul_d.obj \ - $(TMP_DIR)\bn_mp_neg.obj \ - $(TMP_DIR)\bn_mp_or.obj \ - $(TMP_DIR)\bn_mp_radix_size.obj \ - $(TMP_DIR)\bn_mp_radix_smap.obj \ - $(TMP_DIR)\bn_mp_read_radix.obj \ - $(TMP_DIR)\bn_mp_rshd.obj \ - $(TMP_DIR)\bn_mp_set.obj \ - $(TMP_DIR)\bn_mp_set_int.obj \ - $(TMP_DIR)\bn_mp_set_long.obj \ - $(TMP_DIR)\bn_mp_set_long_long.obj \ - $(TMP_DIR)\bn_mp_shrink.obj \ - $(TMP_DIR)\bn_mp_sqr.obj \ - $(TMP_DIR)\bn_mp_sqrt.obj \ - $(TMP_DIR)\bn_mp_sub.obj \ - $(TMP_DIR)\bn_mp_sub_d.obj \ - $(TMP_DIR)\bn_mp_to_unsigned_bin.obj \ - $(TMP_DIR)\bn_mp_to_unsigned_bin_n.obj \ - $(TMP_DIR)\bn_mp_toom_mul.obj \ - $(TMP_DIR)\bn_mp_toom_sqr.obj \ - $(TMP_DIR)\bn_mp_toradix_n.obj \ - $(TMP_DIR)\bn_mp_unsigned_bin_size.obj \ - $(TMP_DIR)\bn_mp_xor.obj \ - $(TMP_DIR)\bn_mp_zero.obj \ - $(TMP_DIR)\bn_s_mp_add.obj \ - $(TMP_DIR)\bn_s_mp_mul_digs.obj \ - $(TMP_DIR)\bn_s_mp_sqr.obj \ - $(TMP_DIR)\bn_s_mp_sub.obj - -PLATFORMOBJS = \ - $(TMP_DIR)\tclWin32Dll.obj \ - $(TMP_DIR)\tclWinChan.obj \ - $(TMP_DIR)\tclWinConsole.obj \ - $(TMP_DIR)\tclWinError.obj \ - $(TMP_DIR)\tclWinFCmd.obj \ - $(TMP_DIR)\tclWinFile.obj \ - $(TMP_DIR)\tclWinInit.obj \ - $(TMP_DIR)\tclWinLoad.obj \ - $(TMP_DIR)\tclWinNotify.obj \ - $(TMP_DIR)\tclWinPipe.obj \ - $(TMP_DIR)\tclWinSerial.obj \ - $(TMP_DIR)\tclWinSock.obj \ - $(TMP_DIR)\tclWinThrd.obj \ - $(TMP_DIR)\tclWinTime.obj \ -!if $(STATIC_BUILD) - $(TMP_DIR)\tclWinReg.obj \ - $(TMP_DIR)\tclWinDde.obj \ -!else - $(TMP_DIR)\tcl.res -!endif - -TCLOBJS = $(COREOBJS) $(ZLIBOBJS) $(TOMMATHOBJS) $(PLATFORMOBJS) - -TCLSTUBOBJS = \ - $(TMP_DIR)\tclStubLib.obj \ - $(TMP_DIR)\tclTomMathStubLib.obj \ - $(TMP_DIR)\tclOOStubLib.obj - -### The following paths CANNOT have spaces in them as they appear on -### the left side of implicit rules. -TOMMATHDIR = $(ROOT)\libtommath -PKGSDIR = $(ROOT)\pkgs - -# Additional include and C macro definitions for the implicit rules -# defined in rules.vc -PRJ_INCLUDES = -I"$(TOMMATHDIR)" -PRJ_DEFINES = -DTCL_TOMMATH -DMP_PREC=4 -Dinline=__inline -DHAVE_ZLIB=1 -D_CRT_SECURE_NO_DEPRECATE -D_CRT_NONSTDC_NO_DEPRECATE - -# Additional Link libraries needed beyond those in rules.vc -PRJ_LIBS = netapi32.lib user32.lib userenv.lib ws2_32.lib - -#--------------------------------------------------------------------- -# TclTest flags -#--------------------------------------------------------------------- - -!if "$(TESTPAT)" != "" -TESTFLAGS = $(TESTFLAGS) -file $(TESTPAT) -!endif - - -#--------------------------------------------------------------------- -# Project specific targets -#--------------------------------------------------------------------- - -release: setup $(TCLSH) $(TCLSTUBLIB) dlls pkgs -core: setup $(TCLLIB) $(TCLSTUBLIB) -shell: setup $(TCLSH) -dlls: setup $(TCLREGLIB) $(TCLDDELIB) -all: setup $(TCLSH) $(TCLSTUBLIB) dlls $(CAT32) pkgs -tcltest: setup $(TCLTEST) dlls $(CAT32) -install: install-binaries install-libraries install-docs install-pkgs -setup: default-setup - -test: test-core test-pkgs -test-core: setup $(TCLTEST) dlls $(CAT32) - set TCL_LIBRARY=$(ROOT:\=/)/library - $(DEBUGGER) $(TCLTEST) "$(ROOT:\=/)/tests/all.tcl" $(TESTFLAGS) -loadfile << - package ifneeded dde 1.4.0 [list load "$(TCLDDELIB:\=/)" dde] - package ifneeded registry 1.3.2 [list load "$(TCLREGLIB:\=/)" registry] -<< - -runtest: setup $(TCLTEST) dlls $(CAT32) - set TCL_LIBRARY=$(ROOT:\=/)/library - $(DEBUGGER) $(TCLTEST) $(SCRIPT) - -runshell: setup $(TCLSH) dlls - set TCL_LIBRARY=$(ROOT:\=/)/library - $(DEBUGGER) $(TCLSH) $(SCRIPT) - -!if $(STATIC_BUILD) - -$(TCLLIB): $(TCLOBJS) - $(LIBCMD) @<< -$** -<< - -!else - -$(TCLLIB): $(TCLOBJS) - $(DLLCMD) @<< -$** -<< - $(_VC_MANIFEST_EMBED_DLL) -$(TCLIMPLIB): $(TCLLIB) - -!endif # $(STATIC_BUILD) - - -$(TCLSTUBLIB): $(TCLSTUBOBJS) - $(LIBCMD) -nodefaultlib $(TCLSTUBOBJS) - -$(TCLSH): $(TCLSHOBJS) $(TCLSTUBLIB) $(TCLIMPLIB) - $(CONEXECMD) -stack:2300000 $** - $(_VC_MANIFEST_EMBED_EXE) - -$(TCLTEST): $(TCLTESTOBJS) $(TCLSTUBLIB) $(TCLIMPLIB) - $(CONEXECMD) -stack:2300000 $** - $(_VC_MANIFEST_EMBED_EXE) - -!if $(STATIC_BUILD) -$(TCLDDELIB): $(TMP_DIR)\tclWinDde.obj - $(LIBCMD) $** -!else -$(TCLDDELIB): $(TMP_DIR)\tclWinDde.obj $(TCLSTUBLIB) - $(DLLCMD) $** - $(_VC_MANIFEST_EMBED_DLL) -!endif - -!if $(STATIC_BUILD) -$(TCLREGLIB): $(TMP_DIR)\tclWinReg.obj - $(LIBCMD) $** -!else -$(TCLREGLIB): $(TMP_DIR)\tclWinReg.obj $(TCLSTUBLIB) - $(DLLCMD) $** - $(_VC_MANIFEST_EMBED_DLL) -!endif - -pkgs: - @for /d %d in ($(PKGSDIR)\*) do \ - @if exist "%~fd\win\makefile.vc" ( \ - pushd "%~fd\win" & \ - $(MAKE) -$(MAKEFLAGS) -f makefile.vc TCLDIR=$(ROOT) &\ - popd \ - ) - -test-pkgs: - @for /d %d in ($(PKGSDIR)\*) do \ - @if exist "%~fd\win\makefile.vc" ( \ - pushd "%~fd\win" & \ - $(MAKE) -$(MAKEFLAGS) -f makefile.vc TCLDIR=$(ROOT) test &\ - popd \ - ) - -install-pkgs: - @for /d %d in ($(PKGSDIR)\*) do \ - @if exist "%~fd\win\makefile.vc" ( \ - pushd "%~fd\win" & \ - $(MAKE) -$(MAKEFLAGS) -f makefile.vc TCLDIR=$(ROOT) install &\ - popd \ - ) - -clean-pkgs: - @for /d %d in ($(PKGSDIR)\*) do \ - @if exist "%~fd\win\makefile.vc" ( \ - pushd "%~fd\win" & \ - $(MAKE) -$(MAKEFLAGS) -f makefile.vc TCLDIR=$(ROOT) clean &\ - popd \ - ) - -$(CAT32): $(WINDIR)\cat.c - $(cc32) $(cflags) $(crt) -D_CRT_NONSTDC_NO_DEPRECATE -DCONSOLE -Fo$(TMP_DIR)\ $? - $(CONEXECMD) -stack:16384 $(TMP_DIR)\cat.obj - $(_VC_MANIFEST_EMBED_EXE) - -#--------------------------------------------------------------------- -# Regenerate the stubs files. [Development use only] -#--------------------------------------------------------------------- - -genstubs: -!if !exist($(TCLSH)) - @echo Build tclsh first! -!else - $(TCLSH) $(TOOLSDIR:\=/)/genStubs.tcl $(GENERICDIR:\=/) \ - $(GENERICDIR:\=/)/tcl.decls $(GENERICDIR:\=/)/tclInt.decls \ - $(GENERICDIR:\=/)/tclTomMath.decls - $(TCLSH) $(TOOLSDIR:\=/)/genStubs.tcl $(GENERICDIR:\=/) \ - $(GENERICDIR:\=/)/tclOO.decls -!endif - - -#---------------------------------------------------------------------- -# The following target generates the file generic/tclTomMath.h. -# It needs to be run (and the results checked) after updating -# to a new release of libtommath. -#---------------------------------------------------------------------- - -gentommath_h: -!if !exist($(TCLSH)) - @echo Build tclsh first! -!else - $(TCLSH) "$(TOOLSDIR:\=/)/fix_tommath_h.tcl" \ - "$(TOMMATHDIR:\=/)/tommath.h" \ - > "$(GENERICDIR)\tclTomMath.h" -!endif - -#--------------------------------------------------------------------- -# Build the Windows HTML help file. -#--------------------------------------------------------------------- - -# NOTE: you can define HHC on the command-line to override this. -# nmake does not set macro values if already set on the command line. -!if defined(PROCESSOR_ARCHITECTURE) && "$(PROCESSOR_ARCHITECTURE)" == "AMD64" -HHC="%ProgramFiles(x86)%\HTML Help Workshop\hhc.exe" -!else -HHC="%ProgramFiles%\HTML Help Workshop\hhc.exe" -!endif -HTMLDIR=$(OUT_DIR)\html -HTMLBASE=TclTk$(VERSION) -HHPFILE=$(HTMLDIR)\$(HTMLBASE).hhp -CHMFILE=$(HTMLDIR)\$(HTMLBASE).chm - -htmlhelp: chmsetup $(CHMFILE) - -$(CHMFILE): $(DOCDIR)\* - @$(TCLSH) $(TOOLSDIR)\tcltk-man2html.tcl "--htmldir=$(HTMLDIR)" - @echo Compiling HTML help project - -"$(HHC)" <<$(HHPFILE) >NUL -[OPTIONS] -Compatibility=1.1 or later -Compiled file=$(HTMLBASE).chm -Default topic=contents.htm -Display compile progress=no -Error log file=$(HTMLBASE).log -Full-text search=Yes -Language=0x409 English (United States) -Title=Tcl/Tk $(DOTVERSION) Help -[FILES] -contents.htm -docs.css -Keywords\*.htm -TclCmd\*.htm -TclLib\*.htm -TkCmd\*.htm -TkLib\*.htm -UserCmd\*.htm -<< - -chmsetup: - @if not exist $(HTMLDIR)\nul mkdir $(HTMLDIR) - -install-docs: -!if exist("$(CHMFILE)") - @echo Installing compiled HTML help - @$(CPY) "$(CHMFILE)" "$(DOC_INSTALL_DIR)\" -!endif - -# "emacs font-lock highlighting fix - -#--------------------------------------------------------------------- -# Generate the tcl.nmake file which contains the options used to build -# Tcl itself. This is used when building extensions. -#--------------------------------------------------------------------- -tcl-nmake: $(OUT_DIR)\tcl.nmake -$(OUT_DIR)\tcl.nmake: - @type << >$@ -CORE_MACHINE = $(MACHINE) -CORE_DEBUG = $(DEBUG) -CORE_TCL_THREADS = $(TCL_THREADS) -CORE_USE_THREAD_ALLOC = $(USE_THREAD_ALLOC) -CORE_USE_WIDECHAR_API = $(USE_WIDECHAR_API) -<< - -#--------------------------------------------------------------------- -# Build tclConfig.sh for the TEA build system. -#--------------------------------------------------------------------- - -tclConfig: $(OUT_DIR)\tclConfig.sh - -# TBD - is this tclConfig.sh file ever used? The values are incorrect! -$(OUT_DIR)\tclConfig.sh: $(WINDIR)\tclConfig.sh.in - @echo Creating tclConfig.sh - @nmakehlp -s << $** >$@ -@TCL_DLL_FILE@ $(TCLLIBNAME) -@TCL_VERSION@ $(DOTVERSION) -@TCL_MAJOR_VERSION@ $(TCL_MAJOR_VERSION) -@TCL_MINOR_VERSION@ $(TCL_MINOR_VERSION) -@TCL_PATCH_LEVEL@ $(TCL_PATCH_LEVEL) -@CC@ $(CC) -@DEFS@ $(pkgcflags) -@CFLAGS_DEBUG@ -nologo -c -W3 -YX -Fp$(TMP_DIR)\ -MDd -@CFLAGS_OPTIMIZE@ -nologo -c -W3 -YX -Fp$(TMP_DIR)\ -MD -@LDFLAGS_DEBUG@ -nologo -machine:$(MACHINE) -debug -debugtype:cv -@LDFLAGS_OPTIMIZE@ -nologo -machine:$(MACHINE) -release -opt:ref -opt:icf,3 -@TCL_DBGX@ $(SUFX) -@TCL_LIB_FILE@ $(PROJECT)$(VERSION)$(SUFX).lib -@TCL_NEEDS_EXP_FILE@ -@LIBS@ $(baselibs) $(PRJ_LIBS) -@prefix@ $(_INSTALLDIR) -@exec_prefix@ $(BIN_INSTALL_DIR) -@SHLIB_CFLAGS@ -@STLIB_CFLAGS@ -@CFLAGS_WARNING@ -W3 -@EXTRA_CFLAGS@ -YX -@SHLIB_LD@ $(link32) $(dlllflags) -@STLIB_LD@ $(lib32) -nologo -@SHLIB_LD_LIBS@ $(baselibs) $(PRJ_LIBS) -@SHLIB_SUFFIX@ .dll -@DL_LIBS@ -@LDFLAGS@ -@TCL_CC_SEARCH_FLAGS@ -@TCL_LD_SEARCH_FLAGS@ -@LIBOBJS@ -@RANLIB@ -@TCL_LIB_FLAG@ -@TCL_BUILD_LIB_SPEC@ -@TCL_LIB_SPEC@ $(LIB_INSTALL_DIR)\$(PROJECT)$(VERSION)$(SUFX).lib -@TCL_INCLUDE_SPEC@ -I$(INCLUDE_INSTALL_DIR) -@TCL_LIB_VERSIONS_OK@ -@TCL_SRC_DIR@ $(ROOT) -@TCL_PACKAGE_PATH@ -@TCL_STUB_LIB_FILE@ $(TCLSTUBLIBNAME) -@TCL_STUB_LIB_FLAG@ $(TCLSTUBLIBNAME) -@TCL_STUB_LIB_SPEC@ -L$(LIB_INSTALL_DIR) $(TCLSTUBLIBNAME) -@TCL_THREADS@ $(TCL_THREADS) -@TCL_BUILD_STUB_LIB_SPEC@ -L$(OUT_DIR) $(TCLSTUBLIBNAME) -@TCL_BUILD_STUB_LIB_PATH@ $(TCLSTUBLIB) -@TCL_STUB_LIB_PATH@ $(LIB_INSTALL_DIR)\$(TCLSTUBLIBNAME) -@CFG_TCL_EXPORT_FILE_SUFFIX@ $(VERSION)$(SUFX).lib -@CFG_TCL_SHARED_LIB_SUFFIX@ $(VERSION)$(SUFX).dll -@CFG_TCL_UNSHARED_LIB_SUFFIX@ $(VERSION)$(SUFX).lib -!if $(STATIC_BUILD) -@TCL_SHARED_BUILD@ 0 -!else -@TCL_SHARED_BUILD@ 1 -!endif -<< - - -#--------------------------------------------------------------------- -# The following target generates the file generic/tclDate.c -# from the yacc grammar found in generic/tclGetDate.y. This is -# only run by hand as yacc is not available in all environments. -# The name of the .c file is different than the name of the .y file -# so that make doesn't try to automatically regenerate the .c file. -#--------------------------------------------------------------------- - -gendate: - bison --output-file=$(GENERICDIR)/tclDate.c \ - --name-prefix=TclDate \ - $(GENERICDIR)/tclGetDate.y - -#--------------------------------------------------------------------- -# Special case object file targets -#--------------------------------------------------------------------- - -$(TMP_DIR)\testMain.obj: $(WINDIR)\tclAppInit.c - $(cc32) $(appcflags) -DTCL_TEST \ - -DTCL_USE_STATIC_PACKAGES=$(TCL_USE_STATIC_PACKAGES) \ - -Fo$@ $? - -$(TMP_DIR)\tclMain2.obj: $(GENERICDIR)\tclMain.c - $(cc32) $(pkgcflags) -DTCL_ASCII_MAIN \ - -Fo$@ $? - -$(TMP_DIR)\tclTest.obj: $(GENERICDIR)\tclTest.c - $(cc32) $(appcflags) -Fo$@ $? - -$(TMP_DIR)\tclTestObj.obj: $(GENERICDIR)\tclTestObj.c - $(cc32) $(appcflags) -Fo$@ $? - -$(TMP_DIR)\tclWinTest.obj: $(WINDIR)\tclWinTest.c - $(CCAPPCMD) $? - -$(TMP_DIR)\tclZlib.obj: $(GENERICDIR)\tclZlib.c - $(cc32) $(pkgcflags) -I$(COMPATDIR)\zlib -Fo$@ $? - -$(TMP_DIR)\tclPkgConfig.obj: $(GENERICDIR)\tclPkgConfig.c - $(cc32) $(pkgcflags) \ - -DCFG_INSTALL_LIBDIR="\"$(LIB_INSTALL_DIR:\=\\)\"" \ - -DCFG_INSTALL_BINDIR="\"$(BIN_INSTALL_DIR:\=\\)\"" \ - -DCFG_INSTALL_SCRDIR="\"$(SCRIPT_INSTALL_DIR:\=\\)\"" \ - -DCFG_INSTALL_INCDIR="\"$(INCLUDE_INSTALL_DIR:\=\\)\"" \ - -DCFG_INSTALL_DOCDIR="\"$(DOC_INSTALL_DIR:\=\\)\"" \ - -DCFG_RUNTIME_LIBDIR="\"$(LIB_INSTALL_DIR:\=\\)\"" \ - -DCFG_RUNTIME_BINDIR="\"$(BIN_INSTALL_DIR:\=\\)\"" \ - -DCFG_RUNTIME_SCRDIR="\"$(SCRIPT_INSTALL_DIR:\=\\)\"" \ - -DCFG_RUNTIME_INCDIR="\"$(INCLUDE_INSTALL_DIR:\=\\)\"" \ - -DCFG_RUNTIME_DOCDIR="\"$(DOC_INSTALL_DIR:\=\\)\"" \ - -Fo$@ $? - -$(TMP_DIR)\tclAppInit.obj: $(WINDIR)\tclAppInit.c - $(cc32) $(appcflags) \ - -DTCL_USE_STATIC_PACKAGES=$(TCL_USE_STATIC_PACKAGES) \ - -Fo$@ $? - -### The following objects should be built using the stub interfaces -### *ALL* extensions need to built with -DTCL_THREADS=1 - -$(TMP_DIR)\tclWinReg.obj: $(WINDIR)\tclWinReg.c -!if $(STATIC_BUILD) - $(cc32) $(appcflags) -DSTATIC_BUILD -Fo$@ $? -!else - $(cc32) $(appcflags) -DUSE_TCL_STUBS -Fo$@ $? -!endif - - -$(TMP_DIR)\tclWinDde.obj: $(WINDIR)\tclWinDde.c -!if $(STATIC_BUILD) - $(cc32) $(appcflags) -DSTATIC_BUILD -Fo$@ $? -!else - $(cc32) $(appcflags) -DUSE_TCL_STUBS -Fo$@ $? -!endif - - -### The following objects are part of the stub library and should not -### be built as DLL objects. -Zl is used to avoid a dependency on any -### specific C run-time. - -$(TMP_DIR)\tclStubLib.obj: $(GENERICDIR)\tclStubLib.c - $(cc32) $(stubscflags) -Fo$@ $? - -$(TMP_DIR)\tclTomMathStubLib.obj: $(GENERICDIR)\tclTomMathStubLib.c - $(cc32) $(stubscflags) -Fo$@ $? - -$(TMP_DIR)\tclOOStubLib.obj: $(GENERICDIR)\tclOOStubLib.c - $(cc32) $(stubscflags) -Fo$@ $? - -$(TMP_DIR)\tclsh.exe.manifest: $(WINDIR)\tclsh.exe.manifest.in - @nmakehlp -s << $** >$@ -@MACHINE@ $(MACHINE:IX86=X86) -@TCL_WIN_VERSION@ $(DOTVERSION).0.0 -<< - -#--------------------------------------------------------------------- -# Generate the source dependencies. Having dependency rules will -# improve incremental build accuracy without having to resort to a -# full rebuild just because some non-global header file like -# tclCompile.h was changed. These rules aren't needed when building -# from scratch. -#--------------------------------------------------------------------- - -depend: -!if !exist($(TCLSH)) - @echo Build tclsh first! -!else - $(TCLSH) $(TOOLSDIR:\=/)/mkdepend.tcl -vc32 -out:"$(OUT_DIR)\depend.mk" \ - -passthru:"-DBUILD_tcl $(TCL_INCLUDES) $(PRJ_INCLUDES)" $(GENERICDIR),$$(GENERICDIR) \ - $(COMPATDIR),$$(COMPATDIR) $(TOMMATHDIR),$$(TOMMATHDIR) $(WINDIR),$$(WINDIR) @<< -$(TCLOBJS) -<< -!endif - -#--------------------------------------------------------------------- -# Dependency rules -#--------------------------------------------------------------------- - -!if exist("$(OUT_DIR)\depend.mk") -!include "$(OUT_DIR)\depend.mk" -!message *** Dependency rules in use. -!else -!message *** Dependency rules are not being used. -!endif - -### add a spacer in the output -!message - - -#--------------------------------------------------------------------- -# Implicit rules that are not covered by the common ones defined in -# rules.vc. A limitation exists with nmake that requires that -# source directory can not contain spaces in the path. This an -# absolute. -#--------------------------------------------------------------------- - -{$(TOMMATHDIR)}.c{$(TMP_DIR)}.obj:: - $(cc32) $(pkgcflags) -Fo$(TMP_DIR)\ @<< -$< -<< - -{$(COMPATDIR)\zlib}.c{$(TMP_DIR)}.obj:: - $(cc32) $(pkgcflags) -Fo$(TMP_DIR)\ @<< -$< -<< - -$(TMP_DIR)\tclsh.res: $(TMP_DIR)\tclsh.exe.manifest $(WINDIR)\tclsh.rc - - -#--------------------------------------------------------------------- -# Installation. -#--------------------------------------------------------------------- - -install-binaries: - @echo Installing to '$(_INSTALLDIR)' - @echo Installing $(TCLLIBNAME) -!if "$(TCLLIB)" != "$(TCLIMPLIB)" - @$(CPY) "$(TCLLIB)" "$(BIN_INSTALL_DIR)\" -!endif - @$(CPY) "$(TCLIMPLIB)" "$(LIB_INSTALL_DIR)\" -!if exist($(TCLSH)) - @echo Installing $(TCLSHNAME) - @$(CPY) "$(TCLSH)" "$(BIN_INSTALL_DIR)\" -!endif - @echo Installing $(TCLSTUBLIBNAME) - @$(CPY) "$(TCLSTUBLIB)" "$(LIB_INSTALL_DIR)\" - -install-libraries: tclConfig tcl-nmake install-msgs install-tzdata - @if not exist "$(SCRIPT_INSTALL_DIR)" \ - $(MKDIR) "$(SCRIPT_INSTALL_DIR)" - @if not exist "$(SCRIPT_INSTALL_DIR)\..\tcl8" \ - $(MKDIR) "$(SCRIPT_INSTALL_DIR)\..\tcl8" - @if not exist "$(SCRIPT_INSTALL_DIR)\..\tcl8\8.4" \ - $(MKDIR) "$(SCRIPT_INSTALL_DIR)\..\tcl8\8.4" - @if not exist "$(SCRIPT_INSTALL_DIR)\..\tcl8\8.4\platform" \ - $(MKDIR) "$(SCRIPT_INSTALL_DIR)\..\tcl8\8.4\platform" - @if not exist "$(SCRIPT_INSTALL_DIR)\..\tcl8\8.5" \ - $(MKDIR) "$(SCRIPT_INSTALL_DIR)\..\tcl8\8.5" - @if not exist "$(SCRIPT_INSTALL_DIR)\..\tcl8\8.6" \ - $(MKDIR) "$(SCRIPT_INSTALL_DIR)\..\tcl8\8.6" - @if not exist "$(LIB_INSTALL_DIR)\nmake" \ - $(MKDIR) "$(LIB_INSTALL_DIR)\nmake" - @echo Installing header files - @$(CPY) "$(GENERICDIR)\tcl.h" "$(INCLUDE_INSTALL_DIR)\" - @$(CPY) "$(GENERICDIR)\tclDecls.h" "$(INCLUDE_INSTALL_DIR)\" - @$(CPY) "$(GENERICDIR)\tclOO.h" "$(INCLUDE_INSTALL_DIR)\" - @$(CPY) "$(GENERICDIR)\tclOODecls.h" "$(INCLUDE_INSTALL_DIR)\" - @$(CPY) "$(GENERICDIR)\tclPlatDecls.h" "$(INCLUDE_INSTALL_DIR)\" - @$(CPY) "$(GENERICDIR)\tclTomMath.h" "$(INCLUDE_INSTALL_DIR)\" - @$(CPY) "$(GENERICDIR)\tclTomMathDecls.h" "$(INCLUDE_INSTALL_DIR)\" - @$(CPY) "$(TOMMATHDIR)\tommath_class.h" "$(INCLUDE_INSTALL_DIR)\" - @$(CPY) "$(TOMMATHDIR)\tommath_superclass.h" "$(INCLUDE_INSTALL_DIR)\" - @echo Installing library files to $(SCRIPT_INSTALL_DIR) - @$(CPY) "$(ROOT)\library\history.tcl" "$(SCRIPT_INSTALL_DIR)\" - @$(CPY) "$(ROOT)\library\init.tcl" "$(SCRIPT_INSTALL_DIR)\" - @$(CPY) "$(ROOT)\library\clock.tcl" "$(SCRIPT_INSTALL_DIR)\" - @$(CPY) "$(ROOT)\library\tm.tcl" "$(SCRIPT_INSTALL_DIR)\" - @$(CPY) "$(ROOT)\library\parray.tcl" "$(SCRIPT_INSTALL_DIR)\" - @$(CPY) "$(ROOT)\library\safe.tcl" "$(SCRIPT_INSTALL_DIR)\" - @$(CPY) "$(ROOT)\library\tclIndex" "$(SCRIPT_INSTALL_DIR)\" - @$(CPY) "$(ROOT)\library\package.tcl" "$(SCRIPT_INSTALL_DIR)\" - @$(CPY) "$(ROOT)\library\word.tcl" "$(SCRIPT_INSTALL_DIR)\" - @$(CPY) "$(ROOT)\library\auto.tcl" "$(SCRIPT_INSTALL_DIR)\" - @$(CPY) "$(OUT_DIR)\tclConfig.sh" "$(LIB_INSTALL_DIR)\" - @$(CPY) "$(WINDIR)\tclooConfig.sh" "$(LIB_INSTALL_DIR)\" - @$(CPY) "$(WINDIR)\rules.vc" "$(LIB_INSTALL_DIR)\nmake\" - @$(CPY) "$(WINDIR)\targets.vc" "$(LIB_INSTALL_DIR)\nmake\" - @$(CPY) "$(WINDIR)\nmakehlp.c" "$(LIB_INSTALL_DIR)\nmake\" - @$(CPY) "$(OUT_DIR)\tcl.nmake" "$(LIB_INSTALL_DIR)\nmake\" - @echo Installing library opt0.4 directory - @$(CPY) "$(ROOT)\library\opt\*.tcl" \ - "$(SCRIPT_INSTALL_DIR)\opt0.4\" - @echo Installing package http $(PKG_HTTP_VER) as a Tcl Module - @$(COPY) "$(ROOT)\library\http\http.tcl" \ - "$(SCRIPT_INSTALL_DIR)\..\tcl8\8.6\http-$(PKG_HTTP_VER).tm" - @echo Installing package msgcat $(PKG_MSGCAT_VER) as a Tcl Module - @$(COPY) "$(ROOT)\library\msgcat\msgcat.tcl" \ - "$(SCRIPT_INSTALL_DIR)\..\tcl8\8.7\msgcat-$(PKG_MSGCAT_VER).tm" - @echo Installing package tcltest $(PKG_TCLTEST_VER) as a Tcl Module - @$(COPY) "$(ROOT)\library\tcltest\tcltest.tcl" \ - "$(SCRIPT_INSTALL_DIR)\..\tcl8\8.5\tcltest-$(PKG_TCLTEST_VER).tm" - @echo Installing package platform $(PKG_PLATFORM_VER) as a Tcl Module - @$(COPY) "$(ROOT)\library\platform\platform.tcl" \ - "$(SCRIPT_INSTALL_DIR)\..\tcl8\8.4\platform-$(PKG_PLATFORM_VER).tm" - @echo Installing package platform::shell $(PKG_SHELL_VER) as a Tcl Module - @$(COPY) "$(ROOT)\library\platform\shell.tcl" \ - "$(SCRIPT_INSTALL_DIR)\..\tcl8\8.4\platform\shell-$(PKG_SHELL_VER).tm" - @echo Installing $(TCLDDELIBNAME) -!if $(STATIC_BUILD) -!if !$(TCL_USE_STATIC_PACKAGES) - @$(CPY) "$(TCLDDELIB)" "$(LIB_INSTALL_DIR)\" -!endif -!else - @$(CPY) "$(TCLDDELIB)" "$(LIB_INSTALL_DIR)\dde$(DDEDOTVERSION)\" - @$(CPY) "$(ROOT)\library\dde\pkgIndex.tcl" \ - "$(LIB_INSTALL_DIR)\dde$(DDEDOTVERSION)\" -!endif - @echo Installing $(TCLREGLIBNAME) -!if $(STATIC_BUILD) -!if !$(TCL_USE_STATIC_PACKAGES) - @$(CPY) "$(TCLREGLIB)" "$(LIB_INSTALL_DIR)\" -!endif -!else - @$(CPY) "$(TCLREGLIB)" "$(LIB_INSTALL_DIR)\reg$(REGDOTVERSION)\" - @$(CPY) "$(ROOT)\library\reg\pkgIndex.tcl" \ - "$(LIB_INSTALL_DIR)\reg$(REGDOTVERSION)\" -!endif - @echo Installing encodings - @$(CPY) "$(ROOT)\library\encoding\*.enc" \ - "$(SCRIPT_INSTALL_DIR)\encoding\" -# "emacs font-lock highlighting fix - -install-tzdata: - @echo Installing time zone data - @set TCL_LIBRARY=$(ROOT:\=/)/library - @$(TCLSH_NATIVE) "$(ROOT:\=/)/tools/installData.tcl" \ - "$(ROOT:\=/)/library/tzdata" "$(SCRIPT_INSTALL_DIR)/tzdata" - -install-msgs: - @echo Installing message catalogs - @set TCL_LIBRARY=$(ROOT:\=/)/library - @$(TCLSH_NATIVE) "$(ROOT:\=/)/tools/installData.tcl" \ - "$(ROOT:\=/)/library/msgs" "$(SCRIPT_INSTALL_DIR)/msgs" - -#--------------------------------------------------------------------- -# Clean up -#--------------------------------------------------------------------- - -tidy: -!if "$(TCLLIB)" != "$(TCLIMPLIB)" - @echo Removing $(TCLLIB) ... - @if exist $(TCLLIB) del $(TCLLIB) -!endif - @echo Removing $(TCLIMPLIB) ... - @if exist $(TCLIMPLIB) del $(TCLIMPLIB) - @echo Removing $(TCLSH) ... - @if exist $(TCLSH) del $(TCLSH) - @echo Removing $(TCLTEST) ... - @if exist $(TCLTEST) del $(TCLTEST) - @echo Removing $(TCLDDELIB) ... - @if exist $(TCLDDELIB) del $(TCLDDELIB) - @echo Removing $(TCLREGLIB) ... - @if exist $(TCLREGLIB) del $(TCLREGLIB) - -clean: default-clean clean-pkgs -hose: default-hose -realclean: hose - -# Local Variables: -# mode: makefile -# End: +#------------------------------------------------------------- -*- makefile -*- +# +# Microsoft Visual C++ makefile for building Tcl with nmake +# +# See the file "license.terms" for information on usage and redistribution +# of this file, and for a DISCLAIMER OF ALL WARRANTIES. +# +# Copyright (c) 1995-1996 Sun Microsystems, Inc. +# Copyright (c) 1998-2000 Ajuba Solutions. +# Copyright (c) 2001-2005 ActiveState Corporation. +# Copyright (c) 2001-2004 David Gravereaux. +# Copyright (c) 2003-2008 Pat Thoyts. +# Copyright (c) 2017 Ashok P. Nadkarni +#------------------------------------------------------------------------------ + +# General usage: +# nmake [-nologo] -f makefile.vc [TARGET|MACRODEF [TARGET|MACRODEF] [...]] +# +# For MACRODEF, see TIP 477 (https://core.tcl.tk/tips/doc/trunk/tip/477.md) +# or examine Sections 6-8 in rules.vc. +# +# Possible values of TARGET are: +# release -- Builds the core, the shell and the dlls. (default) +# dlls -- Just builds the windows extensions +# shell -- Just builds the shell and the core. +# core -- Only builds the core [tclXX.(dll|lib)]. +# all -- Builds everything. +# test -- Builds and runs the test suite. +# tcltest -- Just builds the test shell. +# install -- Installs the built binaries and libraries to $(INSTALLDIR) +# as the root of the install tree. +# tidy/clean/hose -- varying levels of cleaning. +# genstubs -- Rebuilds the Stubs table and support files (dev only). +# depend -- Generates an accurate set of source dependancies for this +# makefile. Helpful to avoid problems when the sources are +# refreshed and you rebuild, but can "overbuild" when common +# headers like tclInt.h just get small changes. +# htmlhelp -- Builds a Windows .chm help file for Tcl and Tk from the +# troff manual pages found in $(ROOT)\doc. You need to +# have installed the HTML Help Compiler package from Microsoft +# to produce the .chm file. +# +# The steps to setup a Visual C++ environment depend on which +# version of Visual Studio and/or the Windows SDK you are building +# against and are not described here. The simplest method is generally +# to start a command shell using one of the short cuts installed by +# Visual Studio/Windows SDK for the appropriate target architecture. +# +# NOTE: For older (Visual C++ 6 or the 2003 SDK), to use the Platform +# SDK (not expressly needed), run setenv.bat after +# vcvars32.bat according to the instructions for it. This can also +# turn on the 64-bit compiler, if your SDK has it. +# +# Examples: +# c:\tcl_src\win\>nmake -f makefile.vc release +# c:\tcl_src\win\>nmake -f makefile.vc test +# c:\tcl_src\win\>nmake -f makefile.vc install INSTALLDIR=c:\progra~1\tcl +# c:\tcl_src\win\>nmake -f makefile.vc release OPTS=pdbs +# c:\tcl_src\win\>nmake -f makefile.vc release OPTS=symbols +# + +# NOTE: +# Before modifying this file, check whether the modification is applicable +# to building extensions as well and if so, modify rules.vc instead. + +# The PROJECT macro is used by rules.vc for generating appropriate +# macros and rules. +PROJECT = tcl + +# Default target to build if no target is specified. If unspecified, the +# rules.vc file will set up "all" as the target. +DEFAULT_BUILD_TARGET = release + +# We want to use our own resource file, not the standard template one. +RCFILE = tcl.rc + +# The rules.vc file does most of the hard work in terms of defining +# the build configuration, macros, output directories etc. +!include "rules.vc" + +# Tcl version info based on macros set up by rules.vc +DOTVERSION = $(TCL_MAJOR_VERSION).$(TCL_MINOR_VERSION) +VERSION = $(TCL_MAJOR_VERSION)$(TCL_MINOR_VERSION) + +# We need versions of various core packages to generate appropriate +# file names during installation. +!if [echo REM = This file is generated from makefile.vc > versions.vc] +!endif +!if [echo PKG_HTTP_VER = \>> versions.vc] \ + && [nmakehlp -V ..\library\http\pkgIndex.tcl http >> versions.vc] +!endif +!if [echo PKG_TCLTEST_VER = \>> versions.vc] \ + && [nmakehlp -V ..\library\tcltest\pkgIndex.tcl tcltest >> versions.vc] +!endif +!if [echo PKG_MSGCAT_VER = \>> versions.vc] \ + && [nmakehlp -V ..\library\msgcat\pkgIndex.tcl msgcat >> versions.vc] +!endif +!if [echo PKG_PLATFORM_VER = \>> versions.vc] \ + && [nmakehlp -V ..\library\platform\pkgIndex.tcl "platform " >> versions.vc] +!endif +!if [echo PKG_SHELL_VER = \>> versions.vc] \ + && [nmakehlp -V ..\library\platform\pkgIndex.tcl "platform::shell" >> versions.vc] +!endif +!if [echo PKG_DDE_VER = \>> versions.vc] \ + && [nmakehlp -V ..\library\dde\pkgIndex.tcl "dde " >> versions.vc] +!endif +!if [echo PKG_REG_VER =\>> versions.vc] \ + && [nmakehlp -V ..\library\reg\pkgIndex.tcl registry >> versions.vc] +!endif + +!include versions.vc + +DDEDOTVERSION = 1.4 +DDEVERSION = $(DDEDOTVERSION:.=) + +REGDOTVERSION = 1.3 +REGVERSION = $(REGDOTVERSION:.=) + +TCLREGLIBNAME = $(PROJECT)reg$(REGVERSION)$(SUFX:t=).$(EXT) +TCLREGLIB = $(OUT_DIR)\$(TCLREGLIBNAME) + +TCLDDELIBNAME = $(PROJECT)dde$(DDEVERSION)$(SUFX:t=).$(EXT) +TCLDDELIB = $(OUT_DIR)\$(TCLDDELIBNAME) + +TCLTEST = $(OUT_DIR)\$(PROJECT)test.exe +CAT32 = $(OUT_DIR)\cat32.exe + +TCLSHOBJS = \ + $(TMP_DIR)\tclAppInit.obj \ +!if !$(STATIC_BUILD) +!if $(TCL_USE_STATIC_PACKAGES) + $(TMP_DIR)\tclWinReg.obj \ + $(TMP_DIR)\tclWinDde.obj \ +!endif +!endif + $(TMP_DIR)\tclsh.res + +TCLTESTOBJS = \ + $(TMP_DIR)\tclTest.obj \ + $(TMP_DIR)\tclTestObj.obj \ + $(TMP_DIR)\tclTestProcBodyObj.obj \ + $(TMP_DIR)\tclThreadTest.obj \ + $(TMP_DIR)\tclWinTest.obj \ +!if !$(STATIC_BUILD) +!if $(TCL_USE_STATIC_PACKAGES) + $(TMP_DIR)\tclWinReg.obj \ + $(TMP_DIR)\tclWinDde.obj \ +!endif +!endif + $(TMP_DIR)\testMain.obj + +COREOBJS = \ + $(TMP_DIR)\regcomp.obj \ + $(TMP_DIR)\regerror.obj \ + $(TMP_DIR)\regexec.obj \ + $(TMP_DIR)\regfree.obj \ + $(TMP_DIR)\tclAlloc.obj \ + $(TMP_DIR)\tclAssembly.obj \ + $(TMP_DIR)\tclAsync.obj \ + $(TMP_DIR)\tclBasic.obj \ + $(TMP_DIR)\tclBinary.obj \ + $(TMP_DIR)\tclCkalloc.obj \ + $(TMP_DIR)\tclClock.obj \ + $(TMP_DIR)\tclCmdAH.obj \ + $(TMP_DIR)\tclCmdIL.obj \ + $(TMP_DIR)\tclCmdMZ.obj \ + $(TMP_DIR)\tclCompCmds.obj \ + $(TMP_DIR)\tclCompCmdsGR.obj \ + $(TMP_DIR)\tclCompCmdsSZ.obj \ + $(TMP_DIR)\tclCompExpr.obj \ + $(TMP_DIR)\tclCompile.obj \ + $(TMP_DIR)\tclConfig.obj \ + $(TMP_DIR)\tclDate.obj \ + $(TMP_DIR)\tclDictObj.obj \ + $(TMP_DIR)\tclDisassemble.obj \ + $(TMP_DIR)\tclEncoding.obj \ + $(TMP_DIR)\tclEnsemble.obj \ + $(TMP_DIR)\tclEnv.obj \ + $(TMP_DIR)\tclEvent.obj \ + $(TMP_DIR)\tclExecute.obj \ + $(TMP_DIR)\tclFCmd.obj \ + $(TMP_DIR)\tclFileName.obj \ + $(TMP_DIR)\tclGet.obj \ + $(TMP_DIR)\tclHash.obj \ + $(TMP_DIR)\tclHistory.obj \ + $(TMP_DIR)\tclIndexObj.obj \ + $(TMP_DIR)\tclInterp.obj \ + $(TMP_DIR)\tclIO.obj \ + $(TMP_DIR)\tclIOCmd.obj \ + $(TMP_DIR)\tclIOGT.obj \ + $(TMP_DIR)\tclIOSock.obj \ + $(TMP_DIR)\tclIOUtil.obj \ + $(TMP_DIR)\tclIORChan.obj \ + $(TMP_DIR)\tclIORTrans.obj \ + $(TMP_DIR)\tclLink.obj \ + $(TMP_DIR)\tclListObj.obj \ + $(TMP_DIR)\tclLiteral.obj \ + $(TMP_DIR)\tclLoad.obj \ + $(TMP_DIR)\tclMain.obj \ + $(TMP_DIR)\tclMain2.obj \ + $(TMP_DIR)\tclNamesp.obj \ + $(TMP_DIR)\tclNotify.obj \ + $(TMP_DIR)\tclOO.obj \ + $(TMP_DIR)\tclOOBasic.obj \ + $(TMP_DIR)\tclOOCall.obj \ + $(TMP_DIR)\tclOODefineCmds.obj \ + $(TMP_DIR)\tclOOInfo.obj \ + $(TMP_DIR)\tclOOMethod.obj \ + $(TMP_DIR)\tclOOStubInit.obj \ + $(TMP_DIR)\tclObj.obj \ + $(TMP_DIR)\tclOptimize.obj \ + $(TMP_DIR)\tclPanic.obj \ + $(TMP_DIR)\tclParse.obj \ + $(TMP_DIR)\tclPathObj.obj \ + $(TMP_DIR)\tclPipe.obj \ + $(TMP_DIR)\tclPkg.obj \ + $(TMP_DIR)\tclPkgConfig.obj \ + $(TMP_DIR)\tclPosixStr.obj \ + $(TMP_DIR)\tclPreserve.obj \ + $(TMP_DIR)\tclProc.obj \ + $(TMP_DIR)\tclProcess.obj \ + $(TMP_DIR)\tclRegexp.obj \ + $(TMP_DIR)\tclResolve.obj \ + $(TMP_DIR)\tclResult.obj \ + $(TMP_DIR)\tclScan.obj \ + $(TMP_DIR)\tclStringObj.obj \ + $(TMP_DIR)\tclStrToD.obj \ + $(TMP_DIR)\tclStubInit.obj \ + $(TMP_DIR)\tclThread.obj \ + $(TMP_DIR)\tclThreadAlloc.obj \ + $(TMP_DIR)\tclThreadJoin.obj \ + $(TMP_DIR)\tclThreadStorage.obj \ + $(TMP_DIR)\tclTimer.obj \ + $(TMP_DIR)\tclTomMathInterface.obj \ + $(TMP_DIR)\tclTrace.obj \ + $(TMP_DIR)\tclUtf.obj \ + $(TMP_DIR)\tclUtil.obj \ + $(TMP_DIR)\tclVar.obj \ + $(TMP_DIR)\tclZlib.obj + +ZLIBOBJS = \ + $(TMP_DIR)\adler32.obj \ + $(TMP_DIR)\compress.obj \ + $(TMP_DIR)\crc32.obj \ + $(TMP_DIR)\deflate.obj \ + $(TMP_DIR)\infback.obj \ + $(TMP_DIR)\inffast.obj \ + $(TMP_DIR)\inflate.obj \ + $(TMP_DIR)\inftrees.obj \ + $(TMP_DIR)\trees.obj \ + $(TMP_DIR)\uncompr.obj \ + $(TMP_DIR)\zutil.obj + +TOMMATHOBJS = \ + $(TMP_DIR)\bncore.obj \ + $(TMP_DIR)\bn_reverse.obj \ + $(TMP_DIR)\bn_fast_s_mp_mul_digs.obj \ + $(TMP_DIR)\bn_fast_s_mp_sqr.obj \ + $(TMP_DIR)\bn_mp_add.obj \ + $(TMP_DIR)\bn_mp_add_d.obj \ + $(TMP_DIR)\bn_mp_and.obj \ + $(TMP_DIR)\bn_mp_clamp.obj \ + $(TMP_DIR)\bn_mp_clear.obj \ + $(TMP_DIR)\bn_mp_clear_multi.obj \ + $(TMP_DIR)\bn_mp_cmp.obj \ + $(TMP_DIR)\bn_mp_cmp_d.obj \ + $(TMP_DIR)\bn_mp_cmp_mag.obj \ + $(TMP_DIR)\bn_mp_cnt_lsb.obj \ + $(TMP_DIR)\bn_mp_copy.obj \ + $(TMP_DIR)\bn_mp_count_bits.obj \ + $(TMP_DIR)\bn_mp_div.obj \ + $(TMP_DIR)\bn_mp_div_d.obj \ + $(TMP_DIR)\bn_mp_div_2.obj \ + $(TMP_DIR)\bn_mp_div_2d.obj \ + $(TMP_DIR)\bn_mp_div_3.obj \ + $(TMP_DIR)\bn_mp_exch.obj \ + $(TMP_DIR)\bn_mp_expt_d.obj \ + $(TMP_DIR)\bn_mp_expt_d_ex.obj \ + $(TMP_DIR)\bn_mp_get_int.obj \ + $(TMP_DIR)\bn_mp_get_long.obj \ + $(TMP_DIR)\bn_mp_get_long_long.obj \ + $(TMP_DIR)\bn_mp_grow.obj \ + $(TMP_DIR)\bn_mp_init.obj \ + $(TMP_DIR)\bn_mp_init_copy.obj \ + $(TMP_DIR)\bn_mp_init_multi.obj \ + $(TMP_DIR)\bn_mp_init_set.obj \ + $(TMP_DIR)\bn_mp_init_set_int.obj \ + $(TMP_DIR)\bn_mp_init_size.obj \ + $(TMP_DIR)\bn_mp_karatsuba_mul.obj \ + $(TMP_DIR)\bn_mp_karatsuba_sqr.obj \ + $(TMP_DIR)\bn_mp_lshd.obj \ + $(TMP_DIR)\bn_mp_mod.obj \ + $(TMP_DIR)\bn_mp_mod_2d.obj \ + $(TMP_DIR)\bn_mp_mul.obj \ + $(TMP_DIR)\bn_mp_mul_2.obj \ + $(TMP_DIR)\bn_mp_mul_2d.obj \ + $(TMP_DIR)\bn_mp_mul_d.obj \ + $(TMP_DIR)\bn_mp_neg.obj \ + $(TMP_DIR)\bn_mp_or.obj \ + $(TMP_DIR)\bn_mp_radix_size.obj \ + $(TMP_DIR)\bn_mp_radix_smap.obj \ + $(TMP_DIR)\bn_mp_read_radix.obj \ + $(TMP_DIR)\bn_mp_rshd.obj \ + $(TMP_DIR)\bn_mp_set.obj \ + $(TMP_DIR)\bn_mp_set_int.obj \ + $(TMP_DIR)\bn_mp_set_long.obj \ + $(TMP_DIR)\bn_mp_set_long_long.obj \ + $(TMP_DIR)\bn_mp_shrink.obj \ + $(TMP_DIR)\bn_mp_sqr.obj \ + $(TMP_DIR)\bn_mp_sqrt.obj \ + $(TMP_DIR)\bn_mp_sub.obj \ + $(TMP_DIR)\bn_mp_sub_d.obj \ + $(TMP_DIR)\bn_mp_to_unsigned_bin.obj \ + $(TMP_DIR)\bn_mp_to_unsigned_bin_n.obj \ + $(TMP_DIR)\bn_mp_toom_mul.obj \ + $(TMP_DIR)\bn_mp_toom_sqr.obj \ + $(TMP_DIR)\bn_mp_toradix_n.obj \ + $(TMP_DIR)\bn_mp_unsigned_bin_size.obj \ + $(TMP_DIR)\bn_mp_xor.obj \ + $(TMP_DIR)\bn_mp_zero.obj \ + $(TMP_DIR)\bn_s_mp_add.obj \ + $(TMP_DIR)\bn_s_mp_mul_digs.obj \ + $(TMP_DIR)\bn_s_mp_sqr.obj \ + $(TMP_DIR)\bn_s_mp_sub.obj + +PLATFORMOBJS = \ + $(TMP_DIR)\tclWin32Dll.obj \ + $(TMP_DIR)\tclWinChan.obj \ + $(TMP_DIR)\tclWinConsole.obj \ + $(TMP_DIR)\tclWinError.obj \ + $(TMP_DIR)\tclWinFCmd.obj \ + $(TMP_DIR)\tclWinFile.obj \ + $(TMP_DIR)\tclWinInit.obj \ + $(TMP_DIR)\tclWinLoad.obj \ + $(TMP_DIR)\tclWinNotify.obj \ + $(TMP_DIR)\tclWinPipe.obj \ + $(TMP_DIR)\tclWinSerial.obj \ + $(TMP_DIR)\tclWinSock.obj \ + $(TMP_DIR)\tclWinThrd.obj \ + $(TMP_DIR)\tclWinTime.obj \ +!if $(STATIC_BUILD) + $(TMP_DIR)\tclWinReg.obj \ + $(TMP_DIR)\tclWinDde.obj \ +!else + $(TMP_DIR)\tcl.res +!endif + +TCLOBJS = $(COREOBJS) $(ZLIBOBJS) $(TOMMATHOBJS) $(PLATFORMOBJS) + +TCLSTUBOBJS = \ + $(TMP_DIR)\tclStubLib.obj \ + $(TMP_DIR)\tclTomMathStubLib.obj \ + $(TMP_DIR)\tclOOStubLib.obj + +### The following paths CANNOT have spaces in them as they appear on +### the left side of implicit rules. +TOMMATHDIR = $(ROOT)\libtommath +PKGSDIR = $(ROOT)\pkgs + +# Additional include and C macro definitions for the implicit rules +# defined in rules.vc +PRJ_INCLUDES = -I"$(TOMMATHDIR)" +PRJ_DEFINES = -DTCL_TOMMATH -DMP_PREC=4 -Dinline=__inline -DHAVE_ZLIB=1 -D_CRT_SECURE_NO_DEPRECATE -D_CRT_NONSTDC_NO_DEPRECATE + +# Additional Link libraries needed beyond those in rules.vc +PRJ_LIBS = netapi32.lib user32.lib userenv.lib ws2_32.lib + +#--------------------------------------------------------------------- +# TclTest flags +#--------------------------------------------------------------------- + +!if "$(TESTPAT)" != "" +TESTFLAGS = $(TESTFLAGS) -file $(TESTPAT) +!endif + + +#--------------------------------------------------------------------- +# Project specific targets +#--------------------------------------------------------------------- + +release: setup $(TCLSH) $(TCLSTUBLIB) dlls pkgs +core: setup $(TCLLIB) $(TCLSTUBLIB) +shell: setup $(TCLSH) +dlls: setup $(TCLREGLIB) $(TCLDDELIB) +all: setup $(TCLSH) $(TCLSTUBLIB) dlls $(CAT32) pkgs +tcltest: setup $(TCLTEST) dlls $(CAT32) +install: install-binaries install-libraries install-docs install-pkgs +setup: default-setup + +test: test-core test-pkgs +test-core: setup $(TCLTEST) dlls $(CAT32) + set TCL_LIBRARY=$(ROOT:\=/)/library + $(DEBUGGER) $(TCLTEST) "$(ROOT:\=/)/tests/all.tcl" $(TESTFLAGS) -loadfile << + package ifneeded dde 1.4.0 [list load "$(TCLDDELIB:\=/)" dde] + package ifneeded registry 1.3.2 [list load "$(TCLREGLIB:\=/)" registry] +<< + +runtest: setup $(TCLTEST) dlls $(CAT32) + set TCL_LIBRARY=$(ROOT:\=/)/library + $(DEBUGGER) $(TCLTEST) $(SCRIPT) + +runshell: setup $(TCLSH) dlls + set TCL_LIBRARY=$(ROOT:\=/)/library + $(DEBUGGER) $(TCLSH) $(SCRIPT) + +!if $(STATIC_BUILD) + +$(TCLLIB): $(TCLOBJS) + $(LIBCMD) @<< +$** +<< + +!else + +$(TCLLIB): $(TCLOBJS) + $(DLLCMD) @<< +$** +<< + $(_VC_MANIFEST_EMBED_DLL) +$(TCLIMPLIB): $(TCLLIB) + +!endif # $(STATIC_BUILD) + + +$(TCLSTUBLIB): $(TCLSTUBOBJS) + $(LIBCMD) -nodefaultlib $(TCLSTUBOBJS) + +$(TCLSH): $(TCLSHOBJS) $(TCLSTUBLIB) $(TCLIMPLIB) + $(CONEXECMD) -stack:2300000 $** + $(_VC_MANIFEST_EMBED_EXE) + +$(TCLTEST): $(TCLTESTOBJS) $(TCLSTUBLIB) $(TCLIMPLIB) + $(CONEXECMD) -stack:2300000 $** + $(_VC_MANIFEST_EMBED_EXE) + +!if $(STATIC_BUILD) +$(TCLDDELIB): $(TMP_DIR)\tclWinDde.obj + $(LIBCMD) $** +!else +$(TCLDDELIB): $(TMP_DIR)\tclWinDde.obj $(TCLSTUBLIB) + $(DLLCMD) $** + $(_VC_MANIFEST_EMBED_DLL) +!endif + +!if $(STATIC_BUILD) +$(TCLREGLIB): $(TMP_DIR)\tclWinReg.obj + $(LIBCMD) $** +!else +$(TCLREGLIB): $(TMP_DIR)\tclWinReg.obj $(TCLSTUBLIB) + $(DLLCMD) $** + $(_VC_MANIFEST_EMBED_DLL) +!endif + +pkgs: + @for /d %d in ($(PKGSDIR)\*) do \ + @if exist "%~fd\win\makefile.vc" ( \ + pushd "%~fd\win" & \ + $(MAKE) -$(MAKEFLAGS) -f makefile.vc TCLDIR=$(ROOT) &\ + popd \ + ) + +test-pkgs: + @for /d %d in ($(PKGSDIR)\*) do \ + @if exist "%~fd\win\makefile.vc" ( \ + pushd "%~fd\win" & \ + $(MAKE) -$(MAKEFLAGS) -f makefile.vc TCLDIR=$(ROOT) test &\ + popd \ + ) + +install-pkgs: + @for /d %d in ($(PKGSDIR)\*) do \ + @if exist "%~fd\win\makefile.vc" ( \ + pushd "%~fd\win" & \ + $(MAKE) -$(MAKEFLAGS) -f makefile.vc TCLDIR=$(ROOT) install &\ + popd \ + ) + +clean-pkgs: + @for /d %d in ($(PKGSDIR)\*) do \ + @if exist "%~fd\win\makefile.vc" ( \ + pushd "%~fd\win" & \ + $(MAKE) -$(MAKEFLAGS) -f makefile.vc TCLDIR=$(ROOT) clean &\ + popd \ + ) + +$(CAT32): $(WINDIR)\cat.c + $(cc32) $(cflags) $(crt) -D_CRT_NONSTDC_NO_DEPRECATE -DCONSOLE -Fo$(TMP_DIR)\ $? + $(CONEXECMD) -stack:16384 $(TMP_DIR)\cat.obj + $(_VC_MANIFEST_EMBED_EXE) + +#--------------------------------------------------------------------- +# Regenerate the stubs files. [Development use only] +#--------------------------------------------------------------------- + +genstubs: +!if !exist($(TCLSH)) + @echo Build tclsh first! +!else + $(TCLSH) $(TOOLSDIR:\=/)/genStubs.tcl $(GENERICDIR:\=/) \ + $(GENERICDIR:\=/)/tcl.decls $(GENERICDIR:\=/)/tclInt.decls \ + $(GENERICDIR:\=/)/tclTomMath.decls + $(TCLSH) $(TOOLSDIR:\=/)/genStubs.tcl $(GENERICDIR:\=/) \ + $(GENERICDIR:\=/)/tclOO.decls +!endif + + +#---------------------------------------------------------------------- +# The following target generates the file generic/tclTomMath.h. +# It needs to be run (and the results checked) after updating +# to a new release of libtommath. +#---------------------------------------------------------------------- + +gentommath_h: +!if !exist($(TCLSH)) + @echo Build tclsh first! +!else + $(TCLSH) "$(TOOLSDIR:\=/)/fix_tommath_h.tcl" \ + "$(TOMMATHDIR:\=/)/tommath.h" \ + > "$(GENERICDIR)\tclTomMath.h" +!endif + +#--------------------------------------------------------------------- +# Build the Windows HTML help file. +#--------------------------------------------------------------------- + +# NOTE: you can define HHC on the command-line to override this. +# nmake does not set macro values if already set on the command line. +!if defined(PROCESSOR_ARCHITECTURE) && "$(PROCESSOR_ARCHITECTURE)" == "AMD64" +HHC="%ProgramFiles(x86)%\HTML Help Workshop\hhc.exe" +!else +HHC="%ProgramFiles%\HTML Help Workshop\hhc.exe" +!endif +HTMLDIR=$(OUT_DIR)\html +HTMLBASE=TclTk$(VERSION) +HHPFILE=$(HTMLDIR)\$(HTMLBASE).hhp +CHMFILE=$(HTMLDIR)\$(HTMLBASE).chm + +htmlhelp: chmsetup $(CHMFILE) + +$(CHMFILE): $(DOCDIR)\* + @$(TCLSH) $(TOOLSDIR)\tcltk-man2html.tcl "--htmldir=$(HTMLDIR)" + @echo Compiling HTML help project + -"$(HHC)" <<$(HHPFILE) >NUL +[OPTIONS] +Compatibility=1.1 or later +Compiled file=$(HTMLBASE).chm +Default topic=contents.htm +Display compile progress=no +Error log file=$(HTMLBASE).log +Full-text search=Yes +Language=0x409 English (United States) +Title=Tcl/Tk $(DOTVERSION) Help +[FILES] +contents.htm +docs.css +Keywords\*.htm +TclCmd\*.htm +TclLib\*.htm +TkCmd\*.htm +TkLib\*.htm +UserCmd\*.htm +<< + +chmsetup: + @if not exist $(HTMLDIR)\nul mkdir $(HTMLDIR) + +install-docs: +!if exist("$(CHMFILE)") + @echo Installing compiled HTML help + @$(CPY) "$(CHMFILE)" "$(DOC_INSTALL_DIR)\" +!endif + +# "emacs font-lock highlighting fix + +#--------------------------------------------------------------------- +# Generate the tcl.nmake file which contains the options used to build +# Tcl itself. This is used when building extensions. +#--------------------------------------------------------------------- +tcl-nmake: $(OUT_DIR)\tcl.nmake +$(OUT_DIR)\tcl.nmake: + @type << >$@ +CORE_MACHINE = $(MACHINE) +CORE_DEBUG = $(DEBUG) +CORE_TCL_THREADS = $(TCL_THREADS) +CORE_USE_THREAD_ALLOC = $(USE_THREAD_ALLOC) +CORE_USE_WIDECHAR_API = $(USE_WIDECHAR_API) +<< + +#--------------------------------------------------------------------- +# Build tclConfig.sh for the TEA build system. +#--------------------------------------------------------------------- + +tclConfig: $(OUT_DIR)\tclConfig.sh + +# TBD - is this tclConfig.sh file ever used? The values are incorrect! +$(OUT_DIR)\tclConfig.sh: $(WINDIR)\tclConfig.sh.in + @echo Creating tclConfig.sh + @nmakehlp -s << $** >$@ +@TCL_DLL_FILE@ $(TCLLIBNAME) +@TCL_VERSION@ $(DOTVERSION) +@TCL_MAJOR_VERSION@ $(TCL_MAJOR_VERSION) +@TCL_MINOR_VERSION@ $(TCL_MINOR_VERSION) +@TCL_PATCH_LEVEL@ $(TCL_PATCH_LEVEL) +@CC@ $(CC) +@DEFS@ $(pkgcflags) +@CFLAGS_DEBUG@ -nologo -c -W3 -YX -Fp$(TMP_DIR)\ -MDd +@CFLAGS_OPTIMIZE@ -nologo -c -W3 -YX -Fp$(TMP_DIR)\ -MD +@LDFLAGS_DEBUG@ -nologo -machine:$(MACHINE) -debug -debugtype:cv +@LDFLAGS_OPTIMIZE@ -nologo -machine:$(MACHINE) -release -opt:ref -opt:icf,3 +@TCL_DBGX@ $(SUFX) +@TCL_LIB_FILE@ $(PROJECT)$(VERSION)$(SUFX).lib +@TCL_NEEDS_EXP_FILE@ +@LIBS@ $(baselibs) $(PRJ_LIBS) +@prefix@ $(_INSTALLDIR) +@exec_prefix@ $(BIN_INSTALL_DIR) +@SHLIB_CFLAGS@ +@STLIB_CFLAGS@ +@CFLAGS_WARNING@ -W3 +@EXTRA_CFLAGS@ -YX +@SHLIB_LD@ $(link32) $(dlllflags) +@STLIB_LD@ $(lib32) -nologo +@SHLIB_LD_LIBS@ $(baselibs) $(PRJ_LIBS) +@SHLIB_SUFFIX@ .dll +@DL_LIBS@ +@LDFLAGS@ +@TCL_CC_SEARCH_FLAGS@ +@TCL_LD_SEARCH_FLAGS@ +@LIBOBJS@ +@RANLIB@ +@TCL_LIB_FLAG@ +@TCL_BUILD_LIB_SPEC@ +@TCL_LIB_SPEC@ $(LIB_INSTALL_DIR)\$(PROJECT)$(VERSION)$(SUFX).lib +@TCL_INCLUDE_SPEC@ -I$(INCLUDE_INSTALL_DIR) +@TCL_LIB_VERSIONS_OK@ +@TCL_SRC_DIR@ $(ROOT) +@TCL_PACKAGE_PATH@ +@TCL_STUB_LIB_FILE@ $(TCLSTUBLIBNAME) +@TCL_STUB_LIB_FLAG@ $(TCLSTUBLIBNAME) +@TCL_STUB_LIB_SPEC@ -L$(LIB_INSTALL_DIR) $(TCLSTUBLIBNAME) +@TCL_THREADS@ $(TCL_THREADS) +@TCL_BUILD_STUB_LIB_SPEC@ -L$(OUT_DIR) $(TCLSTUBLIBNAME) +@TCL_BUILD_STUB_LIB_PATH@ $(TCLSTUBLIB) +@TCL_STUB_LIB_PATH@ $(LIB_INSTALL_DIR)\$(TCLSTUBLIBNAME) +@CFG_TCL_EXPORT_FILE_SUFFIX@ $(VERSION)$(SUFX).lib +@CFG_TCL_SHARED_LIB_SUFFIX@ $(VERSION)$(SUFX).dll +@CFG_TCL_UNSHARED_LIB_SUFFIX@ $(VERSION)$(SUFX).lib +!if $(STATIC_BUILD) +@TCL_SHARED_BUILD@ 0 +!else +@TCL_SHARED_BUILD@ 1 +!endif +<< + + +#--------------------------------------------------------------------- +# The following target generates the file generic/tclDate.c +# from the yacc grammar found in generic/tclGetDate.y. This is +# only run by hand as yacc is not available in all environments. +# The name of the .c file is different than the name of the .y file +# so that make doesn't try to automatically regenerate the .c file. +#--------------------------------------------------------------------- + +gendate: + bison --output-file=$(GENERICDIR)/tclDate.c \ + --name-prefix=TclDate \ + $(GENERICDIR)/tclGetDate.y + +#--------------------------------------------------------------------- +# Special case object file targets +#--------------------------------------------------------------------- + +$(TMP_DIR)\testMain.obj: $(WINDIR)\tclAppInit.c + $(cc32) $(appcflags) -DTCL_TEST \ + -DTCL_USE_STATIC_PACKAGES=$(TCL_USE_STATIC_PACKAGES) \ + -Fo$@ $? + +$(TMP_DIR)\tclMain2.obj: $(GENERICDIR)\tclMain.c + $(cc32) $(pkgcflags) -DTCL_ASCII_MAIN \ + -Fo$@ $? + +$(TMP_DIR)\tclTest.obj: $(GENERICDIR)\tclTest.c + $(cc32) $(appcflags) -Fo$@ $? + +$(TMP_DIR)\tclTestObj.obj: $(GENERICDIR)\tclTestObj.c + $(cc32) $(appcflags) -Fo$@ $? + +$(TMP_DIR)\tclWinTest.obj: $(WINDIR)\tclWinTest.c + $(CCAPPCMD) $? + +$(TMP_DIR)\tclZlib.obj: $(GENERICDIR)\tclZlib.c + $(cc32) $(pkgcflags) -I$(COMPATDIR)\zlib -Fo$@ $? + +$(TMP_DIR)\tclPkgConfig.obj: $(GENERICDIR)\tclPkgConfig.c + $(cc32) $(pkgcflags) \ + -DCFG_INSTALL_LIBDIR="\"$(LIB_INSTALL_DIR:\=\\)\"" \ + -DCFG_INSTALL_BINDIR="\"$(BIN_INSTALL_DIR:\=\\)\"" \ + -DCFG_INSTALL_SCRDIR="\"$(SCRIPT_INSTALL_DIR:\=\\)\"" \ + -DCFG_INSTALL_INCDIR="\"$(INCLUDE_INSTALL_DIR:\=\\)\"" \ + -DCFG_INSTALL_DOCDIR="\"$(DOC_INSTALL_DIR:\=\\)\"" \ + -DCFG_RUNTIME_LIBDIR="\"$(LIB_INSTALL_DIR:\=\\)\"" \ + -DCFG_RUNTIME_BINDIR="\"$(BIN_INSTALL_DIR:\=\\)\"" \ + -DCFG_RUNTIME_SCRDIR="\"$(SCRIPT_INSTALL_DIR:\=\\)\"" \ + -DCFG_RUNTIME_INCDIR="\"$(INCLUDE_INSTALL_DIR:\=\\)\"" \ + -DCFG_RUNTIME_DOCDIR="\"$(DOC_INSTALL_DIR:\=\\)\"" \ + -Fo$@ $? + +$(TMP_DIR)\tclAppInit.obj: $(WINDIR)\tclAppInit.c + $(cc32) $(appcflags) \ + -DTCL_USE_STATIC_PACKAGES=$(TCL_USE_STATIC_PACKAGES) \ + -Fo$@ $? + +### The following objects should be built using the stub interfaces +### *ALL* extensions need to built with -DTCL_THREADS=1 + +$(TMP_DIR)\tclWinReg.obj: $(WINDIR)\tclWinReg.c +!if $(STATIC_BUILD) + $(cc32) $(appcflags) -DSTATIC_BUILD -Fo$@ $? +!else + $(cc32) $(appcflags) -DUSE_TCL_STUBS -Fo$@ $? +!endif + + +$(TMP_DIR)\tclWinDde.obj: $(WINDIR)\tclWinDde.c +!if $(STATIC_BUILD) + $(cc32) $(appcflags) -DSTATIC_BUILD -Fo$@ $? +!else + $(cc32) $(appcflags) -DUSE_TCL_STUBS -Fo$@ $? +!endif + + +### The following objects are part of the stub library and should not +### be built as DLL objects. -Zl is used to avoid a dependency on any +### specific C run-time. + +$(TMP_DIR)\tclStubLib.obj: $(GENERICDIR)\tclStubLib.c + $(cc32) $(stubscflags) -Fo$@ $? + +$(TMP_DIR)\tclTomMathStubLib.obj: $(GENERICDIR)\tclTomMathStubLib.c + $(cc32) $(stubscflags) -Fo$@ $? + +$(TMP_DIR)\tclOOStubLib.obj: $(GENERICDIR)\tclOOStubLib.c + $(cc32) $(stubscflags) -Fo$@ $? + +$(TMP_DIR)\tclsh.exe.manifest: $(WINDIR)\tclsh.exe.manifest.in + @nmakehlp -s << $** >$@ +@MACHINE@ $(MACHINE:IX86=X86) +@TCL_WIN_VERSION@ $(DOTVERSION).0.0 +<< + +#--------------------------------------------------------------------- +# Generate the source dependencies. Having dependency rules will +# improve incremental build accuracy without having to resort to a +# full rebuild just because some non-global header file like +# tclCompile.h was changed. These rules aren't needed when building +# from scratch. +#--------------------------------------------------------------------- + +depend: +!if !exist($(TCLSH)) + @echo Build tclsh first! +!else + $(TCLSH) $(TOOLSDIR:\=/)/mkdepend.tcl -vc32 -out:"$(OUT_DIR)\depend.mk" \ + -passthru:"-DBUILD_tcl $(TCL_INCLUDES) $(PRJ_INCLUDES)" $(GENERICDIR),$$(GENERICDIR) \ + $(COMPATDIR),$$(COMPATDIR) $(TOMMATHDIR),$$(TOMMATHDIR) $(WINDIR),$$(WINDIR) @<< +$(TCLOBJS) +<< +!endif + +#--------------------------------------------------------------------- +# Dependency rules +#--------------------------------------------------------------------- + +!if exist("$(OUT_DIR)\depend.mk") +!include "$(OUT_DIR)\depend.mk" +!message *** Dependency rules in use. +!else +!message *** Dependency rules are not being used. +!endif + +### add a spacer in the output +!message + + +#--------------------------------------------------------------------- +# Implicit rules that are not covered by the common ones defined in +# rules.vc. A limitation exists with nmake that requires that +# source directory can not contain spaces in the path. This an +# absolute. +#--------------------------------------------------------------------- + +{$(TOMMATHDIR)}.c{$(TMP_DIR)}.obj:: + $(cc32) $(pkgcflags) -Fo$(TMP_DIR)\ @<< +$< +<< + +{$(COMPATDIR)\zlib}.c{$(TMP_DIR)}.obj:: + $(cc32) $(pkgcflags) -Fo$(TMP_DIR)\ @<< +$< +<< + +$(TMP_DIR)\tclsh.res: $(TMP_DIR)\tclsh.exe.manifest $(WINDIR)\tclsh.rc + + +#--------------------------------------------------------------------- +# Installation. +#--------------------------------------------------------------------- + +install-binaries: + @echo Installing to '$(_INSTALLDIR)' + @echo Installing $(TCLLIBNAME) +!if "$(TCLLIB)" != "$(TCLIMPLIB)" + @$(CPY) "$(TCLLIB)" "$(BIN_INSTALL_DIR)\" +!endif + @$(CPY) "$(TCLIMPLIB)" "$(LIB_INSTALL_DIR)\" +!if exist($(TCLSH)) + @echo Installing $(TCLSHNAME) + @$(CPY) "$(TCLSH)" "$(BIN_INSTALL_DIR)\" +!endif + @echo Installing $(TCLSTUBLIBNAME) + @$(CPY) "$(TCLSTUBLIB)" "$(LIB_INSTALL_DIR)\" + +install-libraries: tclConfig tcl-nmake install-msgs install-tzdata + @if not exist "$(SCRIPT_INSTALL_DIR)" \ + $(MKDIR) "$(SCRIPT_INSTALL_DIR)" + @if not exist "$(SCRIPT_INSTALL_DIR)\..\tcl8" \ + $(MKDIR) "$(SCRIPT_INSTALL_DIR)\..\tcl8" + @if not exist "$(SCRIPT_INSTALL_DIR)\..\tcl8\8.4" \ + $(MKDIR) "$(SCRIPT_INSTALL_DIR)\..\tcl8\8.4" + @if not exist "$(SCRIPT_INSTALL_DIR)\..\tcl8\8.4\platform" \ + $(MKDIR) "$(SCRIPT_INSTALL_DIR)\..\tcl8\8.4\platform" + @if not exist "$(SCRIPT_INSTALL_DIR)\..\tcl8\8.5" \ + $(MKDIR) "$(SCRIPT_INSTALL_DIR)\..\tcl8\8.5" + @if not exist "$(SCRIPT_INSTALL_DIR)\..\tcl8\8.6" \ + $(MKDIR) "$(SCRIPT_INSTALL_DIR)\..\tcl8\8.6" + @if not exist "$(LIB_INSTALL_DIR)\nmake" \ + $(MKDIR) "$(LIB_INSTALL_DIR)\nmake" + @echo Installing header files + @$(CPY) "$(GENERICDIR)\tcl.h" "$(INCLUDE_INSTALL_DIR)\" + @$(CPY) "$(GENERICDIR)\tclDecls.h" "$(INCLUDE_INSTALL_DIR)\" + @$(CPY) "$(GENERICDIR)\tclOO.h" "$(INCLUDE_INSTALL_DIR)\" + @$(CPY) "$(GENERICDIR)\tclOODecls.h" "$(INCLUDE_INSTALL_DIR)\" + @$(CPY) "$(GENERICDIR)\tclPlatDecls.h" "$(INCLUDE_INSTALL_DIR)\" + @$(CPY) "$(GENERICDIR)\tclTomMath.h" "$(INCLUDE_INSTALL_DIR)\" + @$(CPY) "$(GENERICDIR)\tclTomMathDecls.h" "$(INCLUDE_INSTALL_DIR)\" + @$(CPY) "$(TOMMATHDIR)\tommath_class.h" "$(INCLUDE_INSTALL_DIR)\" + @$(CPY) "$(TOMMATHDIR)\tommath_superclass.h" "$(INCLUDE_INSTALL_DIR)\" + @echo Installing library files to $(SCRIPT_INSTALL_DIR) + @$(CPY) "$(ROOT)\library\history.tcl" "$(SCRIPT_INSTALL_DIR)\" + @$(CPY) "$(ROOT)\library\init.tcl" "$(SCRIPT_INSTALL_DIR)\" + @$(CPY) "$(ROOT)\library\clock.tcl" "$(SCRIPT_INSTALL_DIR)\" + @$(CPY) "$(ROOT)\library\tm.tcl" "$(SCRIPT_INSTALL_DIR)\" + @$(CPY) "$(ROOT)\library\parray.tcl" "$(SCRIPT_INSTALL_DIR)\" + @$(CPY) "$(ROOT)\library\safe.tcl" "$(SCRIPT_INSTALL_DIR)\" + @$(CPY) "$(ROOT)\library\tclIndex" "$(SCRIPT_INSTALL_DIR)\" + @$(CPY) "$(ROOT)\library\package.tcl" "$(SCRIPT_INSTALL_DIR)\" + @$(CPY) "$(ROOT)\library\word.tcl" "$(SCRIPT_INSTALL_DIR)\" + @$(CPY) "$(ROOT)\library\auto.tcl" "$(SCRIPT_INSTALL_DIR)\" + @$(CPY) "$(OUT_DIR)\tclConfig.sh" "$(LIB_INSTALL_DIR)\" + @$(CPY) "$(WINDIR)\tclooConfig.sh" "$(LIB_INSTALL_DIR)\" + @$(CPY) "$(WINDIR)\rules.vc" "$(LIB_INSTALL_DIR)\nmake\" + @$(CPY) "$(WINDIR)\targets.vc" "$(LIB_INSTALL_DIR)\nmake\" + @$(CPY) "$(WINDIR)\nmakehlp.c" "$(LIB_INSTALL_DIR)\nmake\" + @$(CPY) "$(OUT_DIR)\tcl.nmake" "$(LIB_INSTALL_DIR)\nmake\" + @echo Installing library opt0.4 directory + @$(CPY) "$(ROOT)\library\opt\*.tcl" \ + "$(SCRIPT_INSTALL_DIR)\opt0.4\" + @echo Installing package http $(PKG_HTTP_VER) as a Tcl Module + @$(COPY) "$(ROOT)\library\http\http.tcl" \ + "$(SCRIPT_INSTALL_DIR)\..\tcl8\8.6\http-$(PKG_HTTP_VER).tm" + @echo Installing package msgcat $(PKG_MSGCAT_VER) as a Tcl Module + @$(COPY) "$(ROOT)\library\msgcat\msgcat.tcl" \ + "$(SCRIPT_INSTALL_DIR)\..\tcl8\8.7\msgcat-$(PKG_MSGCAT_VER).tm" + @echo Installing package tcltest $(PKG_TCLTEST_VER) as a Tcl Module + @$(COPY) "$(ROOT)\library\tcltest\tcltest.tcl" \ + "$(SCRIPT_INSTALL_DIR)\..\tcl8\8.5\tcltest-$(PKG_TCLTEST_VER).tm" + @echo Installing package platform $(PKG_PLATFORM_VER) as a Tcl Module + @$(COPY) "$(ROOT)\library\platform\platform.tcl" \ + "$(SCRIPT_INSTALL_DIR)\..\tcl8\8.4\platform-$(PKG_PLATFORM_VER).tm" + @echo Installing package platform::shell $(PKG_SHELL_VER) as a Tcl Module + @$(COPY) "$(ROOT)\library\platform\shell.tcl" \ + "$(SCRIPT_INSTALL_DIR)\..\tcl8\8.4\platform\shell-$(PKG_SHELL_VER).tm" + @echo Installing $(TCLDDELIBNAME) +!if $(STATIC_BUILD) +!if !$(TCL_USE_STATIC_PACKAGES) + @$(CPY) "$(TCLDDELIB)" "$(LIB_INSTALL_DIR)\" +!endif +!else + @$(CPY) "$(TCLDDELIB)" "$(LIB_INSTALL_DIR)\dde$(DDEDOTVERSION)\" + @$(CPY) "$(ROOT)\library\dde\pkgIndex.tcl" \ + "$(LIB_INSTALL_DIR)\dde$(DDEDOTVERSION)\" +!endif + @echo Installing $(TCLREGLIBNAME) +!if $(STATIC_BUILD) +!if !$(TCL_USE_STATIC_PACKAGES) + @$(CPY) "$(TCLREGLIB)" "$(LIB_INSTALL_DIR)\" +!endif +!else + @$(CPY) "$(TCLREGLIB)" "$(LIB_INSTALL_DIR)\reg$(REGDOTVERSION)\" + @$(CPY) "$(ROOT)\library\reg\pkgIndex.tcl" \ + "$(LIB_INSTALL_DIR)\reg$(REGDOTVERSION)\" +!endif + @echo Installing encodings + @$(CPY) "$(ROOT)\library\encoding\*.enc" \ + "$(SCRIPT_INSTALL_DIR)\encoding\" +# "emacs font-lock highlighting fix + +install-tzdata: + @echo Installing time zone data + @set TCL_LIBRARY=$(ROOT:\=/)/library + @$(TCLSH_NATIVE) "$(ROOT:\=/)/tools/installData.tcl" \ + "$(ROOT:\=/)/library/tzdata" "$(SCRIPT_INSTALL_DIR)/tzdata" + +install-msgs: + @echo Installing message catalogs + @set TCL_LIBRARY=$(ROOT:\=/)/library + @$(TCLSH_NATIVE) "$(ROOT:\=/)/tools/installData.tcl" \ + "$(ROOT:\=/)/library/msgs" "$(SCRIPT_INSTALL_DIR)/msgs" + +#--------------------------------------------------------------------- +# Clean up +#--------------------------------------------------------------------- + +tidy: +!if "$(TCLLIB)" != "$(TCLIMPLIB)" + @echo Removing $(TCLLIB) ... + @if exist $(TCLLIB) del $(TCLLIB) +!endif + @echo Removing $(TCLIMPLIB) ... + @if exist $(TCLIMPLIB) del $(TCLIMPLIB) + @echo Removing $(TCLSH) ... + @if exist $(TCLSH) del $(TCLSH) + @echo Removing $(TCLTEST) ... + @if exist $(TCLTEST) del $(TCLTEST) + @echo Removing $(TCLDDELIB) ... + @if exist $(TCLDDELIB) del $(TCLDDELIB) + @echo Removing $(TCLREGLIB) ... + @if exist $(TCLREGLIB) del $(TCLREGLIB) + +clean: default-clean clean-pkgs +hose: default-hose +realclean: hose + +# Local Variables: +# mode: makefile +# End: -- cgit v0.12 From bac2aebf1061014fdf5973b4d8d79544d24e74e0 Mon Sep 17 00:00:00 2001 From: dgp Date: Tue, 20 Mar 2018 16:10:49 +0000 Subject: Test and fix for botch in binary string replace. --- generic/tclStringObj.c | 1 + tests/string.test | 6 ++++++ 2 files changed, 7 insertions(+) diff --git a/generic/tclStringObj.c b/generic/tclStringObj.c index 9913160..2ebec64 100644 --- a/generic/tclStringObj.c +++ b/generic/tclStringObj.c @@ -3637,6 +3637,7 @@ TclStringReplace( } result = Tcl_NewByteArrayObj(NULL, numBytes - count + newBytes); /* PANIC? */ + Tcl_SetByteArrayLength(result, 0); TclAppendBytesToByteArray(result, bytes, first); TclAppendBytesToByteArray(result, iBytes, newBytes); TclAppendBytesToByteArray(result, bytes + first + count, diff --git a/tests/string.test b/tests/string.test index f4b94de..bfd8d58 100644 --- a/tests/string.test +++ b/tests/string.test @@ -20,6 +20,9 @@ if {[lsearch [namespace children] ::tcltest] == -1} { ::tcltest::loadTestedCommands catch [list package require -exact Tcltest [info patchlevel]] +# Helper commands to test various optimizations, code paths, and special cases. +proc makeByteArray {s} {binary format a* $s} + # Some tests require the testobj command testConstraint testobj [expr {[info commands testobj] != {}}] @@ -1396,6 +1399,9 @@ test string-14.18 {string replace} { test string-14.19 {string replace} { string replace {} -1 0 A } A +test string-14.20 {string replace} { + string replace [makeByteArray abcdefghijklmnop] end-10 end-2 [makeByteArray NEW] +} abcdeNEWop test string-15.1 {string tolower too few args} { list [catch {string tolower} msg] $msg -- cgit v0.12 From dc07332444484fd4bdb433ea09e36316be74d8f0 Mon Sep 17 00:00:00 2001 From: dgp Date: Tue, 20 Mar 2018 19:25:54 +0000 Subject: Merge over testing improvements from the TIP 475 work. Test files string.test and stringComp.test had become out of sync. Use one file to maintain even coverage. --- tests/basic.test | 2 +- tests/compile.test | 3 +- tests/string.test | 2537 +++++++++++++++++++++++++++---------------------- tests/stringComp.test | 801 ---------------- 4 files changed, 1389 insertions(+), 1954 deletions(-) delete mode 100644 tests/stringComp.test diff --git a/tests/basic.test b/tests/basic.test index 0e4ddea..2332994 100644 --- a/tests/basic.test +++ b/tests/basic.test @@ -670,7 +670,7 @@ proc l3 {} { } # Do all tests once byte compiled and once with direct string evaluation -for {set noComp 0} {$noComp <= 1} {incr noComp} { +foreach noComp {0 1} { if $noComp { interp alias {} run {} testevalex diff --git a/tests/compile.test b/tests/compile.test index 2fa4147..fb9a87a 100644 --- a/tests/compile.test +++ b/tests/compile.test @@ -499,7 +499,8 @@ test compile-15.5 {proper TCL_RETURN code from [return]} { apply {{} {catch {set a 1}; return}} } "" -for {set noComp 0} {$noComp <= 1} {incr noComp} { +# Do all tests once byte compiled and once with direct string evaluation +foreach noComp {0 1} { if $noComp { interp alias {} run {} testevalex diff --git a/tests/string.test b/tests/string.test index bfd8d58..da302eb 100644 --- a/tests/string.test +++ b/tests/string.test @@ -22,289 +22,470 @@ catch [list package require -exact Tcltest [info patchlevel]] # Helper commands to test various optimizations, code paths, and special cases. proc makeByteArray {s} {binary format a* $s} +proc makeUnicode {s} {lindex [regexp -inline .* $s] 0} +proc makeList {args} {return $args} +proc makeShared {s} {uplevel 1 [list lappend copy $s]; return $s} # Some tests require the testobj command -testConstraint testobj [expr {[info commands testobj] != {}}] -testConstraint testindexobj [expr {[info commands testindexobj] != {}}] +testConstraint testobj [expr {[info commands testobj] ne {}}] +testConstraint testindexobj [expr {[info commands testindexobj] ne {}}] +testConstraint testevalex [expr {[info commands testevalex] ne {}}] testConstraint fullutf [expr {[format %c 0x010000] != "\ufffd"}] # Used for constraining memory leak tests testConstraint memory [llength [info commands memory]] +if {[testConstraint memory]} { + proc getbytes {} { + set lines [split [memory info] \n] + return [lindex $lines 3 3] + } + proc leaktest {script {iterations 3}} { + set end [getbytes] + for {set i 0} {$i < $iterations} {incr i} { + uplevel 1 $script + set tmp $end + set end [getbytes] + } + return [expr {$end - $tmp}] + } +} proc representationpoke s { set r [::tcl::unsupported::representation $s] list [lindex $r 3] [string match {*, string representation "*"} $r] } + +foreach noComp {0 1} { + +if {$noComp} { + if {[info commands testevalex] eq {}} { + test string-0.1.$noComp "show testevalex availability" {testevalex} {list} {} + continue + } + interp alias {} run {} testevalex + set constraints testevalex +} else { + interp alias {} run {} try + set constraints {} +} + -test string-1.1 {error conditions} { - list [catch {string gorp a b} msg] $msg +test string-1.1.$noComp {error conditions} { + list [catch {run {string gorp a b}} msg] $msg } {1 {unknown or ambiguous subcommand "gorp": must be bytelength, cat, compare, equal, first, index, is, last, length, map, match, range, repeat, replace, reverse, tolower, totitle, toupper, trim, trimleft, trimright, wordend, or wordstart}} -test string-1.2 {error conditions} { - list [catch {string} msg] $msg +test string-1.2.$noComp {error conditions} { + list [catch {run {string}} msg] $msg } {1 {wrong # args: should be "string subcommand ?arg ...?"}} +test stringComp-1.3.$noComp {error condition - undefined method during compile} { + # We don't want this to complain about 'never' because it may never + # be called, or string may get redefined. This must compile OK. + proc foo {str i} { + if {"yes" == "no"} { string never called but complains here } + string index $str $i + } + foo abc 0 +} a -test string-2.1 {string compare, too few args} { - list [catch {string compare a} msg] $msg +test string-2.1.$noComp {string compare, too few args} { + list [catch {run {string compare a}} msg] $msg } {1 {wrong # args: should be "string compare ?-nocase? ?-length int? string1 string2"}} -test string-2.2 {string compare, bad args} { - list [catch {string compare a b c} msg] $msg +test string-2.2.$noComp {string compare, bad args} { + list [catch {run {string compare a b c}} msg] $msg } {1 {bad option "a": must be -nocase or -length}} -test string-2.3 {string compare, bad args} { - list [catch {string compare -length -nocase str1 str2} msg] $msg +test string-2.3.$noComp {string compare, bad args} { + list [catch {run {string compare -length -nocase str1 str2}} msg] $msg } {1 {expected integer but got "-nocase"}} -test string-2.4 {string compare, too many args} { - list [catch {string compare -length 10 -nocase str1 str2 str3} msg] $msg +test string-2.4.$noComp {string compare, too many args} { + list [catch {run {string compare -length 10 -nocase str1 str2 str3}} msg] $msg } {1 {wrong # args: should be "string compare ?-nocase? ?-length int? string1 string2"}} -test string-2.5 {string compare with length unspecified} { - list [catch {string compare -length 10 10} msg] $msg +test string-2.5.$noComp {string compare with length unspecified} { + list [catch {run {string compare -length 10 10}} msg] $msg } {1 {wrong # args: should be "string compare ?-nocase? ?-length int? string1 string2"}} -test string-2.6 {string compare} { - string compare abcde abdef +test string-2.6.$noComp {string compare} { + run {string compare abcde abdef} } -1 -test string-2.7 {string compare, shortest method name} { - string co abcde ABCDE +test string-2.7.$noComp {string compare, shortest method name} { + run {string co abcde ABCDE} } 1 -test string-2.8 {string compare} { - string compare abcde abcde +test string-2.8.$noComp {string compare} { + run {string compare abcde abcde} } 0 -test string-2.9 {string compare with length} { - string compare -length 2 abcde abxyz +test string-2.9.$noComp {string compare with length} { + run {string compare -length 2 abcde abxyz} } 0 -test string-2.10 {string compare with special index} { - list [catch {string compare -length end-3 abcde abxyz} msg] $msg +test string-2.10.$noComp {string compare with special index} { + list [catch {run {string compare -length end-3 abcde abxyz}} msg] $msg } {1 {expected integer but got "end-3"}} -test string-2.11 {string compare, unicode} { - string compare ab\u7266 ab\u7267 +test string-2.11.$noComp {string compare, unicode} { + run {string compare ab\u7266 ab\u7267} +} -1 +test string-2.11.1.$noComp {string compare, unicode} { + run {string compare \334 \u00dc} +} 0 +test string-2.11.2.$noComp {string compare, unicode} { + run {string compare \334 \u00fc} } -1 -test string-2.12 {string compare, high bit} { +test string-2.11.3.$noComp {string compare, unicode} { + run {string compare \334\334\334\374\374 \334\334\334\334\334} +} 1 +test string-2.12.$noComp {string compare, high bit} { # This test will fail if the underlying comparaison # is using signed chars instead of unsigned chars. # (like SunOS's default memcmp thus the compat/memcmp.c) - string compare "\x80" "@" + run {string compare "\x80" "@"} # Nb this tests works also in utf8 space because \x80 is # translated into a 2 or more bytelength but whose first byte has # the high bit set. } 1 -test string-2.13 {string compare -nocase} { - string compare -nocase abcde abdef +test string-2.13.$noComp {string compare -nocase} { + run {string compare -nocase abcde abdef} +} -1 +test string-2.13.1.$noComp {string compare -nocase} { + run {string compare -nocase abcde Abdef} } -1 -test string-2.14 {string compare -nocase} { - string compare -nocase abcde ABCDE +test string-2.14.$noComp {string compare -nocase} { + run {string compare -nocase abcde ABCDE} +} 0 +test string-2.15.$noComp {string compare -nocase} { + run {string compare -nocase abcde abcde} +} 0 +test string-2.15.1.$noComp {string compare -nocase} { + run {string compare -nocase \334 \u00dc} } 0 -test string-2.15 {string compare -nocase} { - string compare -nocase abcde abcde +test string-2.15.2.$noComp {string compare -nocase} { + run {string compare -nocase \334\334\334\374\u00fc \334\334\334\334\334} } 0 -test string-2.16 {string compare -nocase with length} { - string compare -length 2 -nocase abcde Abxyz +test string-2.16.$noComp {string compare -nocase with length} { + run {string compare -length 2 -nocase abcde Abxyz} } 0 -test string-2.17 {string compare -nocase with length} { - string compare -nocase -length 3 abcde Abxyz +test string-2.17.$noComp {string compare -nocase with length} { + run {string compare -nocase -length 3 abcde Abxyz} } -1 -test string-2.18 {string compare -nocase with length <= 0} { - string compare -nocase -length -1 abcde AbCdEf +test string-2.18.$noComp {string compare -nocase with length <= 0} { + run {string compare -nocase -length -1 abcde AbCdEf} } -1 -test string-2.19 {string compare -nocase with excessive length} { - string compare -nocase -length 50 AbCdEf abcde +test string-2.19.$noComp {string compare -nocase with excessive length} { + run {string compare -nocase -length 50 AbCdEf abcde} } 1 -test string-2.20 {string compare -len unicode} { +test string-2.20.$noComp {string compare -len unicode} { # These are strings that are 6 BYTELENGTH long, but the length # shouldn't make a different because there are actually 3 CHARS long - string compare -len 5 \334\334\334 \334\334\374 + run {string compare -len 5 \334\334\334 \334\334\374} } -1 -test string-2.21 {string compare -nocase with special index} { - list [catch {string compare -nocase -length end-3 Abcde abxyz} msg] $msg +test string-2.21.$noComp {string compare -nocase with special index} { + list [catch {run {string compare -nocase -length end-3 Abcde abxyz}} msg] $msg } {1 {expected integer but got "end-3"}} -test string-2.22 {string compare, null strings} { - string compare "" "" +test string-2.22.$noComp {string compare, null strings} { + run {string compare "" ""} } 0 -test string-2.23 {string compare, null strings} { - string compare "" foo +test string-2.23.$noComp {string compare, null strings} { + run {string compare "" foo} } -1 -test string-2.24 {string compare, null strings} { - string compare foo "" +test string-2.24.$noComp {string compare, null strings} { + run {string compare foo ""} } 1 -test string-2.25 {string compare -nocase, null strings} { - string compare -nocase "" "" +test string-2.25.$noComp {string compare -nocase, null strings} { + run {string compare -nocase "" ""} } 0 -test string-2.26 {string compare -nocase, null strings} { - string compare -nocase "" foo +test string-2.26.$noComp {string compare -nocase, null strings} { + run {string compare -nocase "" foo} } -1 -test string-2.27 {string compare -nocase, null strings} { - string compare -nocase foo "" +test string-2.27.$noComp {string compare -nocase, null strings} { + run {string compare -nocase foo ""} } 1 -test string-2.28 {string compare with length, unequal strings} { - string compare -length 2 abc abde +test string-2.28.$noComp {string compare with length, unequal strings} { + run {string compare -length 2 abc abde} } 0 -test string-2.29 {string compare with length, unequal strings} { - string compare -length 2 ab abde +test string-2.29.$noComp {string compare with length, unequal strings} { + run {string compare -length 2 ab abde} } 0 -test string-2.30 {string compare with NUL character vs. other ASCII} { +test string-2.30.$noComp {string compare with NUL character vs. other ASCII} { # Be careful here, since UTF-8 rep comparison with memcmp() of # these puts chars in the wrong order - string compare \x00 \x01 + run {string compare \x00 \x01} } -1 -test string-2.31 {string compare, high bit} { - proc foo {} {string compare "a\x80" "a@"} - foo +test string-2.31.$noComp {string compare, high bit} { + run {string compare "a\x80" "a@"} } 1 -test string-2.32 {string compare, high bit} { - proc foo {} {string compare "a\x00" "a\x01"} - foo +test string-2.32.$noComp {string compare, high bit} { + run {string compare "a\x00" "a\x01"} } -1 -test string-2.33 {string compare, high bit} { - proc foo {} {string compare "\x00\x00" "\x00\x01"} - foo +test string-2.33.$noComp {string compare, high bit} { + run {string compare "\x00\x00" "\x00\x01"} } -1 +test string-2.34.$noComp {string compare, binary equal} { + run {string compare [binary format a100 0] [binary format a100 0]} +} 0 +test string-2.35.$noComp {string compare, binary neq} { + run {string compare [binary format a100a 0 1] [binary format a100a 0 0]} +} 1 +test string-2.36.$noComp {string compare, binary neq unequal length} { + run {string compare [binary format a20a 0 1] [binary format a100a 0 0]} +} 1 # only need a few tests on equal, since it uses the same code as # string compare, but just modifies the return output -test string-3.1 {string equal} { - string equal abcde abdef +test string-3.1.$noComp {string equal} { + run {string equal abcde abdef} +} 0 +test string-3.2.$noComp {string equal} { + run {string e abcde ABCDE} +} 0 +test string-3.3.$noComp {string equal} { + run {string equal abcde abcde} +} 1 +test string-3.4.$noComp {string equal -nocase} { + run {string equal -nocase \334\334\334\334\374\374\374\374 \334\334\334\334\334\334\334\334} +} 1 +test string-3.5.$noComp {string equal -nocase} { + run {string equal -nocase abcde abdef} +} 0 +test string-3.6.$noComp {string equal -nocase} { + run {string eq -nocase abcde ABCDE} +} 1 +test string-3.7.$noComp {string equal -nocase} { + run {string equal -nocase abcde abcde} +} 1 +test string-3.8.$noComp {string equal with length, unequal strings} { + run {string equal -length 2 abc abde} +} 1 +test string-3.9.$noComp {string equal, too few args} { + list [catch {run {string equal a}} msg] $msg +} {1 {wrong # args: should be "string equal ?-nocase? ?-length int? string1 string2"}} +test string-3.10.$noComp {string equal, bad args} { + list [catch {run {string equal a b c}} msg] $msg +} {1 {bad option "a": must be -nocase or -length}} +test string-3.11.$noComp {string equal, bad args} { + list [catch {run {string equal -length -nocase str1 str2}} msg] $msg +} {1 {expected integer but got "-nocase"}} +test string-3.12.$noComp {string equal, too many args} { + list [catch {run {string equal -length 10 -nocase str1 str2 str3}} msg] $msg +} {1 {wrong # args: should be "string equal ?-nocase? ?-length int? string1 string2"}} +test string-3.13.$noComp {string equal with length unspecified} { + list [catch {run {string equal -length 10 10}} msg] $msg +} {1 {wrong # args: should be "string equal ?-nocase? ?-length int? string1 string2"}} +test string-3.14.$noComp {string equal with length} { + run {string equal -length 2 abcde abxyz} +} 1 +test string-3.15.$noComp {string equal with special index} { + list [catch {run {string equal -length end-3 abcde abxyz}} msg] $msg +} {1 {expected integer but got "end-3"}} + +test string-3.16.$noComp {string equal, unicode} { + run {string equal ab\u7266 ab\u7267} +} 0 +test string-3.17.$noComp {string equal, unicode} { + run {string equal \334 \u00dc} +} 1 +test string-3.18.$noComp {string equal, unicode} { + run {string equal \334 \u00fc} +} 0 +test string-3.19.$noComp {string equal, unicode} { + run {string equal \334\334\334\374\374 \334\334\334\334\334} +} 0 +test string-3.20.$noComp {string equal, high bit} { + # This test will fail if the underlying comparaison + # is using signed chars instead of unsigned chars. + # (like SunOS's default memcmp thus the compat/memcmp.c) + run {string equal "\x80" "@"} + # Nb this tests works also in utf8 space because \x80 is + # translated into a 2 or more bytelength but whose first byte has + # the high bit set. } 0 -test string-3.2 {string equal} { - string eq abcde ABCDE +test string-3.21.$noComp {string equal -nocase} { + run {string equal -nocase abcde Abdef} } 0 -test string-3.3 {string equal} { - string equal abcde abcde +test string-3.22.$noComp {string equal, -nocase unicode} { + run {string equal -nocase \334 \u00dc} } 1 -test string-3.4 {string equal -nocase} { - string equal -nocase \334\334\334\334\374\374\374\374 \334\334\334\334\334\334\334\334 +test string-3.23.$noComp {string equal, -nocase unicode} { + run {string equal -nocase \334\334\334\374\u00fc \334\334\334\334\334} } 1 -test string-3.5 {string equal -nocase} { - string equal -nocase abcde abdef +test string-3.24.$noComp {string equal -nocase with length} { + run {string equal -length 2 -nocase abcde Abxyz} +} 1 +test string-3.25.$noComp {string equal -nocase with length} { + run {string equal -nocase -length 3 abcde Abxyz} +} 0 +test string-3.26.$noComp {string equal -nocase with length <= 0} { + run {string equal -nocase -length -1 abcde AbCdEf} +} 0 +test string-3.27.$noComp {string equal -nocase with excessive length} { + run {string equal -nocase -length 50 AbCdEf abcde} +} 0 +test string-3.28.$noComp {string equal -len unicode} { + # These are strings that are 6 BYTELENGTH long, but the length + # shouldn't make a different because there are actually 3 CHARS long + run {string equal -len 5 \334\334\334 \334\334\374} } 0 -test string-3.6 {string equal -nocase} { - string eq -nocase abcde ABCDE +test string-3.29.$noComp {string equal -nocase with special index} { + list [catch {run {string equal -nocase -length end-3 Abcde abxyz}} msg] $msg +} {1 {expected integer but got "end-3"}} +test string-3.30.$noComp {string equal, null strings} { + run {string equal "" ""} } 1 -test string-3.7 {string equal -nocase} { - string equal -nocase abcde abcde +test string-3.31.$noComp {string equal, null strings} { + run {string equal "" foo} +} 0 +test string-3.32.$noComp {string equal, null strings} { + run {string equal foo ""} +} 0 +test string-3.33.$noComp {string equal -nocase, null strings} { + run {string equal -nocase "" ""} } 1 -test string-3.8 {string equal with length, unequal strings} { - string equal -length 2 abc abde +test string-3.34.$noComp {string equal -nocase, null strings} { + run {string equal -nocase "" foo} +} 0 +test string-3.35.$noComp {string equal -nocase, null strings} { + run {string equal -nocase foo ""} +} 0 +test string-3.36.$noComp {string equal with NUL character vs. other ASCII} { + # Be careful here, since UTF-8 rep comparison with memcmp() of + # these puts chars in the wrong order + run {string equal \x00 \x01} +} 0 +test string-3.37.$noComp {string equal, high bit} { + run {string equal "a\x80" "a@"} +} 0 +test string-3.38.$noComp {string equal, high bit} { + run {string equal "a\x00" "a\x01"} +} 0 +test string-3.39.$noComp {string equal, high bit} { + run {string equal "a\x00\x00" "a\x00\x01"} +} 0 +test string-3.40.$noComp {string equal, binary equal} { + run {string equal [binary format a100 0] [binary format a100 0]} } 1 +test string-3.41.$noComp {string equal, binary neq} { + run {string equal [binary format a100a 0 1] [binary format a100a 0 0]} +} 0 +test string-3.42.$noComp {string equal, binary neq inequal length} { + run {string equal [binary format a20a 0 1] [binary format a100a 0 0]} +} 0 -test string-4.1 {string first, too few args} { - list [catch {string first a} msg] $msg + +test string-4.1.$noComp {string first, too few args} { + list [catch {run {string first a}} msg] $msg } {1 {wrong # args: should be "string first needleString haystackString ?startIndex?"}} -test string-4.2 {string first, bad args} { - list [catch {string first a b c} msg] $msg +test string-4.2.$noComp {string first, bad args} { + list [catch {run {string first a b c}} msg] $msg } {1 {bad index "c": must be integer?[+-]integer? or end?[+-]integer?}} -test string-4.3 {string first, too many args} { - list [catch {string first a b 5 d} msg] $msg +test string-4.3.$noComp {string first, too many args} { + list [catch {run {string first a b 5 d}} msg] $msg } {1 {wrong # args: should be "string first needleString haystackString ?startIndex?"}} -test string-4.4 {string first} { - string first bq abcdefgbcefgbqrs +test string-4.4.$noComp {string first} { + run {string first bq abcdefgbcefgbqrs} } 12 -test string-4.5 {string first} { - string fir bcd abcdefgbcefgbqrs +test string-4.5.$noComp {string first} { + run {string fir bcd abcdefgbcefgbqrs} } 1 -test string-4.6 {string first} { - string f b abcdefgbcefgbqrs +test string-4.6.$noComp {string first} { + run {string f b abcdefgbcefgbqrs} } 1 -test string-4.7 {string first} { - string first xxx x123xx345xxx789xxx012 +test string-4.7.$noComp {string first} { + run {string first xxx x123xx345xxx789xxx012} } 9 -test string-4.8 {string first} { - string first "" x123xx345xxx789xxx012 +test string-4.8.$noComp {string first} { + run {string first "" x123xx345xxx789xxx012} } -1 -test string-4.9 {string first, unicode} { - string first x abc\u7266x +test string-4.9.$noComp {string first, unicode} { + run {string first x abc\u7266x} } 4 -test string-4.10 {string first, unicode} { - string first \u7266 abc\u7266x +test string-4.10.$noComp {string first, unicode} { + run {string first \u7266 abc\u7266x} } 3 -test string-4.11 {string first, start index} { - string first \u7266 abc\u7266x 3 +test string-4.11.$noComp {string first, start index} { + run {string first \u7266 abc\u7266x 3} } 3 -test string-4.12 {string first, start index} { - string first \u7266 abc\u7266x 4 +test string-4.12.$noComp {string first, start index} { + run {string first \u7266 abc\u7266x 4} } -1 -test string-4.13 {string first, start index} { - string first \u7266 abc\u7266x end-2 +test string-4.13.$noComp {string first, start index} { + run {string first \u7266 abc\u7266x end-2} } 3 -test string-4.14 {string first, negative start index} { - string first b abc -1 +test string-4.14.$noComp {string first, negative start index} { + run {string first b abc -1} } 1 -test string-4.15 {string first, ability to two-byte encoded utf-8 chars} { +test string-4.15.$noComp {string first, ability to two-byte encoded utf-8 chars} { # Test for a bug in Tcl 8.3 where test for all-single-byte-encoded # strings was incorrect, leading to an index returned by [string first] # which pointed past the end of the string. set uchar \u057e ;# character with two-byte encoding in utf-8 - string first % %#$uchar$uchar#$uchar$uchar#% 3 + run {string first % %#$uchar$uchar#$uchar$uchar#% 3} } 8 -test string-4.16 {string first, normal string vs pure unicode string} { +test string-4.16.$noComp {string first, normal string vs pure unicode string} { set s hello regexp ll $s m # Representation checks are canaries - list [representationpoke $s] [representationpoke $m] \ - [string first $m $s] + run {list [representationpoke $s] [representationpoke $m] \ + [string first $m $s]} } {{string 1} {string 0} 2} -test string-5.1 {string index} { - list [catch {string index} msg] $msg +test string-5.1.$noComp {string index} { + list [catch {run {string index}} msg] $msg } {1 {wrong # args: should be "string index string charIndex"}} -test string-5.2 {string index} { - list [catch {string index a b c} msg] $msg +test string-5.2.$noComp {string index} { + list [catch {run {string index a b c}} msg] $msg } {1 {wrong # args: should be "string index string charIndex"}} -test string-5.3 {string index} { - string index abcde 0 +test string-5.3.$noComp {string index} { + run {string index abcde 0} } a -test string-5.4 {string index} { - string in abcde 4 +test string-5.4.$noComp {string index} { + run {string ind abcde 4} } e -test string-5.5 {string index} { - string index abcde 5 +test string-5.5.$noComp {string index} { + run {string index abcde 5} } {} -test string-5.6 {string index} { - list [catch {string index abcde -10} msg] $msg +test string-5.6.$noComp {string index} { + list [catch {run {string index abcde -10}} msg] $msg } {0 {}} -test string-5.7 {string index} { - list [catch {string index a xyz} msg] $msg +test string-5.7.$noComp {string index} { + list [catch {run {string index a xyz}} msg] $msg } {1 {bad index "xyz": must be integer?[+-]integer? or end?[+-]integer?}} -test string-5.8 {string index} { - string index abc end +test string-5.8.$noComp {string index} { + run {string index abc end} } c -test string-5.9 {string index} { - string index abc end-1 +test string-5.9.$noComp {string index} { + run {string index abc end-1} } b -test string-5.10 {string index, unicode} { - string index abc\u7266d 4 +test string-5.10.$noComp {string index, unicode} { + run {string index abc\u7266d 4} } d -test string-5.11 {string index, unicode} { - string index abc\u7266d 3 +test string-5.11.$noComp {string index, unicode} { + run {string index abc\u7266d 3} } \u7266 -test string-5.12 {string index, unicode over char length, under byte length} { - string index \334\374\334\374 6 +test string-5.12.$noComp {string index, unicode over char length, under byte length} { + run {string index \334\374\334\374 6} } {} -test string-5.13 {string index, bytearray object} { - string index [binary format a5 fuz] 0 +test string-5.13.$noComp {string index, bytearray object} { + run {string index [binary format a5 fuz] 0} } f -test string-5.14 {string index, bytearray object} { - string index [binary format I* {0x50515253 0x52}] 3 +test string-5.14.$noComp {string index, bytearray object} { + run {string index [binary format I* {0x50515253 0x52}] 3} } S -test string-5.15 {string index, bytearray object} { +test string-5.15.$noComp {string index, bytearray object} { set b [binary format I* {0x50515253 0x52}] - set i1 [string index $b end-6] - set i2 [string index $b 1] - string compare $i1 $i2 + set i1 [run {string index $b end-6}] + set i2 [run {string index $b 1}] + run {string compare $i1 $i2} } 0 -test string-5.16 {string index, bytearray object with string obj shimmering} { +test string-5.16.$noComp {string index, bytearray object with string obj shimmering} { set str "0123456789\x00 abcdedfghi" binary scan $str H* dump - string compare [string index $str 10] \x00 + run {string compare [run {string index $str 10}] \x00} } 0 -test string-5.17 {string index, bad integer} -body { - list [catch {string index "abc" 0o8} msg] $msg +test string-5.17.$noComp {string index, bad integer} -body { + list [catch {run {string index "abc" 0o8}} msg] $msg } -match glob -result {1 {*invalid octal number*}} -test string-5.18 {string index, bad integer} -body { - list [catch {string index "abc" end-0o0289} msg] $msg +test string-5.18.$noComp {string index, bad integer} -body { + list [catch {run {string index "abc" end-0o0289}} msg] $msg } -match glob -result {1 {*invalid octal number*}} -test string-5.19 {string index, bytearray object out of bounds} { - string index [binary format I* {0x50515253 0x52}] -1 +test string-5.19.$noComp {string index, bytearray object out of bounds} { + run {string index [binary format I* {0x50515253 0x52}] -1} } {} -test string-5.20 {string index, bytearray object out of bounds} { - string index [binary format I* {0x50515253 0x52}] 20 +test string-5.20.$noComp {string index, bytearray object out of bounds} { + run {string index [binary format I* {0x50515253 0x52}] 20} } {} @@ -317,871 +498,871 @@ proc largest_int {} { return [expr {$int-1}] } -test string-6.1 {string is, too few args} { - list [catch {string is} msg] $msg +test string-6.1.$noComp {string is, too few args} { + list [catch {run {string is}} msg] $msg } {1 {wrong # args: should be "string is class ?-strict? ?-failindex var? str"}} -test string-6.2 {string is, too few args} { - list [catch {string is alpha} msg] $msg +test string-6.2.$noComp {string is, too few args} { + list [catch {run {string is alpha}} msg] $msg } {1 {wrong # args: should be "string is class ?-strict? ?-failindex var? str"}} -test string-6.3 {string is, bad args} { - list [catch {string is alpha -failin str} msg] $msg +test string-6.3.$noComp {string is, bad args} { + list [catch {run {string is alpha -failin str}} msg] $msg } {1 {wrong # args: should be "string is alpha ?-strict? ?-failindex var? str"}} -test string-6.4 {string is, too many args} { - list [catch {string is alpha -failin var -strict str more} msg] $msg +test string-6.4.$noComp {string is, too many args} { + list [catch {run {string is alpha -failin var -strict str more}} msg] $msg } {1 {wrong # args: should be "string is class ?-strict? ?-failindex var? str"}} -test string-6.5 {string is, class check} { - list [catch {string is bogus str} msg] $msg +test string-6.5.$noComp {string is, class check} { + list [catch {run {string is bogus str}} msg] $msg } {1 {bad class "bogus": must be alnum, alpha, ascii, control, boolean, digit, double, entier, false, graph, integer, list, lower, print, punct, space, true, upper, wideinteger, wordchar, or xdigit}} -test string-6.6 {string is, ambiguous class} { - list [catch {string is al str} msg] $msg +test string-6.6.$noComp {string is, ambiguous class} { + list [catch {run {string is al str}} msg] $msg } {1 {ambiguous class "al": must be alnum, alpha, ascii, control, boolean, digit, double, entier, false, graph, integer, list, lower, print, punct, space, true, upper, wideinteger, wordchar, or xdigit}} -test string-6.7 {string is alpha, all ok} { - string is alpha -strict -failindex var abc +test string-6.7.$noComp {string is alpha, all ok} { + run {string is alpha -strict -failindex var abc} } 1 -test string-6.8 {string is, error in var} { - list [string is alpha -failindex var abc5def] $var +test string-6.8.$noComp {string is, error in var} { + list [run {string is alpha -failindex var abc5def}] $var } {0 3} -test string-6.9 {string is, var shouldn't get set} { +test string-6.9.$noComp {string is, var shouldn't get set} { catch {unset var} - list [catch {string is alpha -failindex var abc; set var} msg] $msg + list [catch {run {string is alpha -failindex var abc; set var}} msg] $msg } {1 {can't read "var": no such variable}} -test string-6.10 {string is, ok on empty} { - string is alpha {} +test string-6.10.$noComp {string is, ok on empty} { + run {string is alpha {}} } 1 -test string-6.11 {string is, -strict check against empty} { - string is alpha -strict {} +test string-6.11.$noComp {string is, -strict check against empty} { + run {string is alpha -strict {}} } 0 -test string-6.12 {string is alnum, true} { - string is alnum abc123 +test string-6.12.$noComp {string is alnum, true} { + run {string is alnum abc123} } 1 -test string-6.13 {string is alnum, false} { - list [string is alnum -failindex var abc1.23] $var +test string-6.13.$noComp {string is alnum, false} { + list [run {string is alnum -failindex var abc1.23}] $var } {0 4} -test string-6.14 {string is alnum, unicode} "string is alnum abc\xfc" 1 -test string-6.15 {string is alpha, true} { - string is alpha abc +test string-6.14.$noComp {string is alnum, unicode} "run {string is alnum abc\xfc}" 1 +test string-6.15.$noComp {string is alpha, true} { + run {string is alpha abc} } 1 -test string-6.16 {string is alpha, false} { - list [string is alpha -fail var a1bcde] $var +test string-6.16.$noComp {string is alpha, false} { + list [run {string is alpha -fail var a1bcde}] $var } {0 1} -test string-6.17 {string is alpha, unicode} { - string is alpha abc\374 +test string-6.17.$noComp {string is alpha, unicode} { + run {string is alpha abc\374} } 1 -test string-6.18 {string is ascii, true} { - string is ascii abc\u007Fend\u0000 +test string-6.18.$noComp {string is ascii, true} { + run {string is ascii abc\u007Fend\u0000} } 1 -test string-6.19 {string is ascii, false} { - list [string is ascii -fail var abc\u0000def\u0080more] $var +test string-6.19.$noComp {string is ascii, false} { + list [run {string is ascii -fail var abc\u0000def\u0080more}] $var } {0 7} -test string-6.20 {string is boolean, true} { - string is boolean true +test string-6.20.$noComp {string is boolean, true} { + run {string is boolean true} } 1 -test string-6.21 {string is boolean, true} { - string is boolean f +test string-6.21.$noComp {string is boolean, true} { + run {string is boolean f} } 1 -test string-6.22 {string is boolean, true based on type} { - string is bool [string compare a a] +test string-6.22.$noComp {string is boolean, true based on type} { + run {string is bool [run {string compare a a}]} } 1 -test string-6.23 {string is boolean, false} { - list [string is bool -fail var yada] $var +test string-6.23.$noComp {string is boolean, false} { + list [run {string is bool -fail var yada}] $var } {0 0} -test string-6.24 {string is digit, true} { - string is digit 0123456789 +test string-6.24.$noComp {string is digit, true} { + run {string is digit 0123456789} } 1 -test string-6.25 {string is digit, false} { - list [string is digit -fail var 0123\u00dc567] $var +test string-6.25.$noComp {string is digit, false} { + list [run {string is digit -fail var 0123\u00dc567}] $var } {0 4} -test string-6.26 {string is digit, false} { - list [string is digit -fail var +123567] $var +test string-6.26.$noComp {string is digit, false} { + list [run {string is digit -fail var +123567}] $var } {0 0} -test string-6.27 {string is double, true} { - string is double 1 +test string-6.27.$noComp {string is double, true} { + run {string is double 1} } 1 -test string-6.28 {string is double, true} { - string is double [expr double(1)] +test string-6.28.$noComp {string is double, true} { + run {string is double [expr double(1)]} } 1 -test string-6.29 {string is double, true} { - string is double 1.0 +test string-6.29.$noComp {string is double, true} { + run {string is double 1.0} } 1 -test string-6.30 {string is double, true} { - string is double [string compare a a] +test string-6.30.$noComp {string is double, true} { + run {string is double [run {string compare a a}]} } 1 -test string-6.31 {string is double, true} { - string is double " +1.0e-1 " +test string-6.31.$noComp {string is double, true} { + run {string is double " +1.0e-1 "} } 1 -test string-6.32 {string is double, true} { - string is double "\n1.0\v" +test string-6.32.$noComp {string is double, true} { + run {string is double "\n1.0\v"} } 1 -test string-6.33 {string is double, false} { - list [string is double -fail var 1abc] $var +test string-6.33.$noComp {string is double, false} { + list [run {string is double -fail var 1abc}] $var } {0 1} -test string-6.34 {string is double, false} { - list [string is double -fail var abc] $var +test string-6.34.$noComp {string is double, false} { + list [run {string is double -fail var abc}] $var } {0 0} -test string-6.35 {string is double, false} { - list [string is double -fail var " 1.0e4e4 "] $var +test string-6.35.$noComp {string is double, false} { + list [run {string is double -fail var " 1.0e4e4 "}] $var } {0 8} -test string-6.36 {string is double, false} { - list [string is double -fail var "\n"] $var +test string-6.36.$noComp {string is double, false} { + list [run {string is double -fail var "\n"}] $var } {0 0} -test string-6.37 {string is double, false on int overflow} -setup { +test string-6.37.$noComp {string is double, false on int overflow} -setup { set var priorValue } -body { # Make it the largest int recognizable, with one more digit for overflow # Since bignums arrived in Tcl 8.5, the sense of this test changed. # Now integer values that exceed native limits become bignums, and # bignums can convert to doubles without error. - list [string is double -fail var [largest_int]0] $var + list [run {string is double -fail var [largest_int]0}] $var } -result {1 priorValue} # string-6.38 removed, underflow on input is no longer an error. -test string-6.39 {string is double, false} { +test string-6.39.$noComp {string is double, false} { # This test is non-portable because IRIX thinks # that .e1 is a valid double - this is really a bug # on IRIX as .e1 should NOT be a valid double # # Portable now. Tcl 8.5 does its own double parsing. - list [string is double -fail var .e1] $var + list [run {string is double -fail var .e1}] $var } {0 0} -test string-6.40 {string is false, true} { - string is false false +test string-6.40.$noComp {string is false, true} { + run {string is false false} } 1 -test string-6.41 {string is false, true} { - string is false FaLsE +test string-6.41.$noComp {string is false, true} { + run {string is false FaLsE} } 1 -test string-6.42 {string is false, true} { - string is false N +test string-6.42.$noComp {string is false, true} { + run {string is false N} } 1 -test string-6.43 {string is false, true} { - string is false 0 +test string-6.43.$noComp {string is false, true} { + run {string is false 0} } 1 -test string-6.44 {string is false, true} { - string is false off +test string-6.44.$noComp {string is false, true} { + run {string is false off} } 1 -test string-6.45 {string is false, false} { - list [string is false -fail var abc] $var +test string-6.45.$noComp {string is false, false} { + list [run {string is false -fail var abc}] $var } {0 0} -test string-6.46 {string is false, false} { +test string-6.46.$noComp {string is false, false} { catch {unset var} - list [string is false -fail var Y] $var + list [run {string is false -fail var Y}] $var } {0 0} -test string-6.47 {string is false, false} { +test string-6.47.$noComp {string is false, false} { catch {unset var} - list [string is false -fail var offensive] $var + list [run {string is false -fail var offensive}] $var } {0 0} -test string-6.48 {string is integer, true} { - string is integer +1234567890 +test string-6.48.$noComp {string is integer, true} { + run {string is integer +1234567890} } 1 -test string-6.49 {string is integer, true on type} { - string is integer [expr int(50.0)] +test string-6.49.$noComp {string is integer, true on type} { + run {string is integer [expr int(50.0)]} } 1 -test string-6.50 {string is integer, true} { - string is integer [list -10] +test string-6.50.$noComp {string is integer, true} { + run {string is integer [list -10]} } 1 -test string-6.51 {string is integer, true as hex} { - string is integer 0xabcdef +test string-6.51.$noComp {string is integer, true as hex} { + run {string is integer 0xabcdef} } 1 -test string-6.52 {string is integer, true as octal} { - string is integer 012345 +test string-6.52.$noComp {string is integer, true as octal} { + run {string is integer 012345} } 1 -test string-6.53 {string is integer, true with whitespace} { - string is integer " \n1234\v" +test string-6.53.$noComp {string is integer, true with whitespace} { + run {string is integer " \n1234\v"} } 1 -test string-6.54 {string is integer, false} { - list [string is integer -fail var 123abc] $var +test string-6.54.$noComp {string is integer, false} { + list [run {string is integer -fail var 123abc}] $var } {0 3} -test string-6.55 {string is integer, false on overflow} { - list [string is integer -fail var +[largest_int]0] $var +test string-6.55.$noComp {string is integer, false on overflow} { + list [run {string is integer -fail var +[largest_int]0}] $var } {0 -1} -test string-6.56 {string is integer, false} { - list [string is integer -fail var [expr double(1)]] $var +test string-6.56.$noComp {string is integer, false} { + list [run {string is integer -fail var [expr double(1)]}] $var } {0 1} -test string-6.57 {string is integer, false} { - list [string is integer -fail var " "] $var +test string-6.57.$noComp {string is integer, false} { + list [run {string is integer -fail var " "}] $var } {0 0} -test string-6.58 {string is integer, false on bad octal} { - list [string is integer -fail var 0o36963] $var +test string-6.58.$noComp {string is integer, false on bad octal} { + list [run {string is integer -fail var 0o36963}] $var } {0 4} -test string-6.58.1 {string is integer, false on bad octal} { - list [string is integer -fail var 0o36963] $var +test string-6.58.1.$noComp {string is integer, false on bad octal} { + list [run {string is integer -fail var 0o36963}] $var } {0 4} -test string-6.59 {string is integer, false on bad hex} { - list [string is integer -fail var 0X345XYZ] $var +test string-6.59.$noComp {string is integer, false on bad hex} { + list [run {string is integer -fail var 0X345XYZ}] $var } {0 5} -test string-6.60 {string is lower, true} { - string is lower abc +test string-6.60.$noComp {string is lower, true} { + run {string is lower abc} } 1 -test string-6.61 {string is lower, unicode true} { - string is lower abc\u00fcue +test string-6.61.$noComp {string is lower, unicode true} { + run {string is lower abc\u00fcue} } 1 -test string-6.62 {string is lower, false} { - list [string is lower -fail var aBc] $var +test string-6.62.$noComp {string is lower, false} { + list [run {string is lower -fail var aBc}] $var } {0 1} -test string-6.63 {string is lower, false} { - list [string is lower -fail var abc1] $var +test string-6.63.$noComp {string is lower, false} { + list [run {string is lower -fail var abc1}] $var } {0 3} -test string-6.64 {string is lower, unicode false} { - list [string is lower -fail var ab\u00dcUE] $var +test string-6.64.$noComp {string is lower, unicode false} { + list [run {string is lower -fail var ab\u00dcUE}] $var } {0 2} -test string-6.65 {string is space, true} { - string is space " \t\n\v\f" +test string-6.65.$noComp {string is space, true} { + run {string is space " \t\n\v\f"} } 1 -test string-6.66 {string is space, false} { - list [string is space -fail var " \t\n\v1\f"] $var +test string-6.66.$noComp {string is space, false} { + list [run {string is space -fail var " \t\n\v1\f"}] $var } {0 4} -test string-6.67 {string is true, true} { - string is true true +test string-6.67.$noComp {string is true, true} { + run {string is true true} } 1 -test string-6.68 {string is true, true} { - string is true TrU +test string-6.68.$noComp {string is true, true} { + run {string is true TrU} } 1 -test string-6.69 {string is true, true} { - string is true ye +test string-6.69.$noComp {string is true, true} { + run {string is true ye} } 1 -test string-6.70 {string is true, true} { - string is true 1 +test string-6.70.$noComp {string is true, true} { + run {string is true 1} } 1 -test string-6.71 {string is true, true} { - string is true on +test string-6.71.$noComp {string is true, true} { + run {string is true on} } 1 -test string-6.72 {string is true, false} { - list [string is true -fail var onto] $var +test string-6.72.$noComp {string is true, false} { + list [run {string is true -fail var onto}] $var } {0 0} -test string-6.73 {string is true, false} { +test string-6.73.$noComp {string is true, false} { catch {unset var} - list [string is true -fail var 25] $var + list [run {string is true -fail var 25}] $var } {0 0} -test string-6.74 {string is true, false} { +test string-6.74.$noComp {string is true, false} { catch {unset var} - list [string is true -fail var no] $var + list [run {string is true -fail var no}] $var } {0 0} -test string-6.75 {string is upper, true} { - string is upper ABC +test string-6.75.$noComp {string is upper, true} { + run {string is upper ABC} } 1 -test string-6.76 {string is upper, unicode true} { - string is upper ABC\u00dcUE +test string-6.76.$noComp {string is upper, unicode true} { + run {string is upper ABC\u00dcUE} } 1 -test string-6.77 {string is upper, false} { - list [string is upper -fail var AbC] $var +test string-6.77.$noComp {string is upper, false} { + list [run {string is upper -fail var AbC}] $var } {0 1} -test string-6.78 {string is upper, false} { - list [string is upper -fail var AB2C] $var +test string-6.78.$noComp {string is upper, false} { + list [run {string is upper -fail var AB2C}] $var } {0 2} -test string-6.79 {string is upper, unicode false} { - list [string is upper -fail var ABC\u00fcue] $var +test string-6.79.$noComp {string is upper, unicode false} { + list [run {string is upper -fail var ABC\u00fcue}] $var } {0 3} -test string-6.80 {string is wordchar, true} { - string is wordchar abc_123 +test string-6.80.$noComp {string is wordchar, true} { + run {string is wordchar abc_123} } 1 -test string-6.81 {string is wordchar, unicode true} { - string is wordchar abc\u00fcab\u00dcAB\u5001 +test string-6.81.$noComp {string is wordchar, unicode true} { + run {string is wordchar abc\u00fcab\u00dcAB\u5001} } 1 -test string-6.82 {string is wordchar, false} { - list [string is wordchar -fail var abcd.ef] $var +test string-6.82.$noComp {string is wordchar, false} { + list [run {string is wordchar -fail var abcd.ef}] $var } {0 4} -test string-6.83 {string is wordchar, unicode false} { - list [string is wordchar -fail var abc\u0080def] $var +test string-6.83.$noComp {string is wordchar, unicode false} { + list [run {string is wordchar -fail var abc\u0080def}] $var } {0 3} -test string-6.84 {string is control} { +test string-6.84.$noComp {string is control} { ## Control chars are in the ranges ## 00..1F && 7F..9F - list [string is control -fail var \x00\x01\x10\x1F\x7F\x80\x9F\x60] $var + list [run {string is control -fail var \x00\x01\x10\x1F\x7F\x80\x9F\x60}] $var } {0 7} -test string-6.85 {string is control} { - string is control \u0100 +test string-6.85.$noComp {string is control} { + run {string is control \u0100} } 0 -test string-6.86 {string is graph} { +test string-6.86.$noComp {string is graph} { ## graph is any print char, except space - list [string is gra -fail var "0123abc!@#\$\u0100\UE0100\UE01EF "] $var + list [run {string is gra -fail var "0123abc!@#\$\u0100\UE0100\UE01EF "}] $var } {0 14} -test string-6.87 {string is print} { +test string-6.87.$noComp {string is print} { ## basically any printable char - list [string is print -fail var "0123abc!@#\$\u0100 \UE0100\UE01EF\u0010"] $var + list [run {string is print -fail var "0123abc!@#\$\u0100 \UE0100\UE01EF\u0010"}] $var } {0 15} -test string-6.88 {string is punct} { +test string-6.88.$noComp {string is punct} { ## any graph char that isn't alnum - list [string is punct -fail var "_!@#\u00beq0"] $var + list [run {string is punct -fail var "_!@#\u00beq0"}] $var } {0 4} -test string-6.89 {string is xdigit} { - list [string is xdigit -fail var 0123456789\u0061bcdefABCDEFg] $var +test string-6.89.$noComp {string is xdigit} { + list [run {string is xdigit -fail var 0123456789\u0061bcdefABCDEFg}] $var } {0 22} -test string-6.90 {string is integer, bad integers} { +test string-6.90.$noComp {string is integer, bad integers} { # SF bug #634856 set result "" set numbers [list 1 +1 ++1 +-1 -+1 -1 --1 "- +1"] foreach num $numbers { - lappend result [string is int -strict $num] + lappend result [run {string is int -strict $num}] } return $result } {1 1 0 0 0 1 0 0} -test string-6.91 {string is double, bad doubles} { +test string-6.91.$noComp {string is double, bad doubles} { set result "" set numbers [list 1.0 +1.0 ++1.0 +-1.0 -+1.0 -1.0 --1.0 "- +1.0"] foreach num $numbers { - lappend result [string is double -strict $num] + lappend result [run {string is double -strict $num}] } return $result } {1 1 0 0 0 1 0 0} -test string-6.92 {string is integer, 32-bit overflow} { +test string-6.92.$noComp {string is integer, 32-bit overflow} { # Bug 718878 set x 0x100000000 - list [string is integer -failindex var $x] $var + list [run {string is integer -failindex var $x}] $var } {0 -1} -test string-6.93 {string is integer, 32-bit overflow} { +test string-6.93.$noComp {string is integer, 32-bit overflow} { # Bug 718878 set x 0x100000000 append x "" - list [string is integer -failindex var $x] $var + list [run {string is integer -failindex var $x}] $var } {0 -1} -test string-6.94 {string is integer, 32-bit overflow} { +test string-6.94.$noComp {string is integer, 32-bit overflow} { # Bug 718878 set x 0x100000000 - list [string is integer -failindex var [expr {$x}]] $var + list [run {string is integer -failindex var [expr {$x}]}] $var } {0 -1} -test string-6.95 {string is wideinteger, true} { - string is wideinteger +1234567890 +test string-6.95.$noComp {string is wideinteger, true} { + run {string is wideinteger +1234567890} } 1 -test string-6.96 {string is wideinteger, true on type} { - string is wideinteger [expr wide(50.0)] +test string-6.96.$noComp {string is wideinteger, true on type} { + run {string is wideinteger [expr wide(50.0)]} } 1 -test string-6.97 {string is wideinteger, true} { - string is wideinteger [list -10] +test string-6.97.$noComp {string is wideinteger, true} { + run {string is wideinteger [list -10]} } 1 -test string-6.98 {string is wideinteger, true as hex} { - string is wideinteger 0xabcdef +test string-6.98.$noComp {string is wideinteger, true as hex} { + run {string is wideinteger 0xabcdef} } 1 -test string-6.99 {string is wideinteger, true as octal} { - string is wideinteger 0123456 +test string-6.99.$noComp {string is wideinteger, true as octal} { + run {string is wideinteger 0123456} } 1 -test string-6.100 {string is wideinteger, true with whitespace} { - string is wideinteger " \n1234\v" +test string-6.100.$noComp {string is wideinteger, true with whitespace} { + run {string is wideinteger " \n1234\v"} } 1 -test string-6.101 {string is wideinteger, false} { - list [string is wideinteger -fail var 123abc] $var +test string-6.101.$noComp {string is wideinteger, false} { + list [run {string is wideinteger -fail var 123abc}] $var } {0 3} -test string-6.102 {string is wideinteger, false on overflow} { - list [string is wideinteger -fail var +[largest_int]0] $var +test string-6.102.$noComp {string is wideinteger, false on overflow} { + list [run {string is wideinteger -fail var +[largest_int]0}] $var } {0 -1} -test string-6.103 {string is wideinteger, false} { - list [string is wideinteger -fail var [expr double(1)]] $var +test string-6.103.$noComp {string is wideinteger, false} { + list [run {string is wideinteger -fail var [expr double(1)]}] $var } {0 1} -test string-6.104 {string is wideinteger, false} { - list [string is wideinteger -fail var " "] $var +test string-6.104.$noComp {string is wideinteger, false} { + list [run {string is wideinteger -fail var " "}] $var } {0 0} -test string-6.105 {string is wideinteger, false on bad octal} { - list [string is wideinteger -fail var 0o36963] $var +test string-6.105.$noComp {string is wideinteger, false on bad octal} { + list [run {string is wideinteger -fail var 0o36963}] $var } {0 4} -test string-6.105.1 {string is wideinteger, false on bad octal} { - list [string is wideinteger -fail var 0o36963] $var +test string-6.105.1.$noComp {string is wideinteger, false on bad octal} { + list [run {string is wideinteger -fail var 0o36963}] $var } {0 4} -test string-6.106 {string is wideinteger, false on bad hex} { - list [string is wideinteger -fail var 0X345XYZ] $var +test string-6.106.$noComp {string is wideinteger, false on bad hex} { + list [run {string is wideinteger -fail var 0X345XYZ}] $var } {0 5} -test string-6.107 {string is integer, bad integers} { +test string-6.107.$noComp {string is integer, bad integers} { # SF bug #634856 set result "" set numbers [list 1 +1 ++1 +-1 -+1 -1 --1 "- +1"] foreach num $numbers { - lappend result [string is wideinteger -strict $num] + lappend result [run {string is wideinteger -strict $num}] } return $result } {1 1 0 0 0 1 0 0} -test string-6.108 {string is double, Bug 1382287} { +test string-6.108.$noComp {string is double, Bug 1382287} { set x 2turtledoves - string is double $x - string is double $x + run {string is double $x} + run {string is double $x} } 0 -test string-6.109 {string is double, Bug 1360532} { - string is double 1\u00a0 +test string-6.109.$noComp {string is double, Bug 1360532} { + run {string is double 1\u00a0} } 0 -test string-6.110 {string is entier, true} { - string is entier +1234567890 +test string-6.110.$noComp {string is entier, true} { + run {string is entier +1234567890} } 1 -test string-6.111 {string is entier, true on type} { - string is entier [expr wide(50.0)] +test string-6.111.$noComp {string is entier, true on type} { + run {string is entier [expr wide(50.0)]} } 1 -test string-6.112 {string is entier, true} { - string is entier [list -10] +test string-6.112.$noComp {string is entier, true} { + run {string is entier [list -10]} } 1 -test string-6.113 {string is entier, true as hex} { - string is entier 0xabcdef +test string-6.113.$noComp {string is entier, true as hex} { + run {string is entier 0xabcdef} } 1 -test string-6.114 {string is entier, true as octal} { - string is entier 0123456 +test string-6.114.$noComp {string is entier, true as octal} { + run {string is entier 0123456} } 1 -test string-6.115 {string is entier, true with whitespace} { - string is entier " \n1234\v" +test string-6.115.$noComp {string is entier, true with whitespace} { + run {string is entier " \n1234\v"} } 1 -test string-6.116 {string is entier, false} { - list [string is entier -fail var 123abc] $var +test string-6.116.$noComp {string is entier, false} { + list [run {string is entier -fail var 123abc}] $var } {0 3} -test string-6.117 {string is entier, false} { - list [string is entier -fail var 123123123123123123123123123123123123123123123123123123123123123123123123123123123123abc] $var +test string-6.117.$noComp {string is entier, false} { + list [run {string is entier -fail var 123123123123123123123123123123123123123123123123123123123123123123123123123123123123abc}] $var } {0 84} -test string-6.118 {string is entier, false} { - list [string is entier -fail var [expr double(1)]] $var +test string-6.118.$noComp {string is entier, false} { + list [run {string is entier -fail var [expr double(1)]}] $var } {0 1} -test string-6.119 {string is entier, false} { - list [string is entier -fail var " "] $var +test string-6.119.$noComp {string is entier, false} { + list [run {string is entier -fail var " "}] $var } {0 0} -test string-6.120 {string is entier, false on bad octal} { - list [string is entier -fail var 0o36963] $var +test string-6.120.$noComp {string is entier, false on bad octal} { + list [run {string is entier -fail var 0o36963}] $var } {0 4} -test string-6.121.1 {string is entier, false on bad octal} { - list [string is entier -fail var 0o36963] $var +test string-6.121.1.$noComp {string is entier, false on bad octal} { + list [run {string is entier -fail var 0o36963}] $var } {0 4} -test string-6.122 {string is entier, false on bad hex} { - list [string is entier -fail var 0X345XYZ] $var +test string-6.122.$noComp {string is entier, false on bad hex} { + list [run {string is entier -fail var 0X345XYZ}] $var } {0 5} -test string-6.123 {string is entier, bad integers} { +test string-6.123.$noComp {string is entier, bad integers} { # SF bug #634856 set result "" set numbers [list 1 +1 ++1 +-1 -+1 -1 --1 "- +1"] foreach num $numbers { - lappend result [string is entier -strict $num] + lappend result [run {string is entier -strict $num}] } return $result } {1 1 0 0 0 1 0 0} -test string-6.124 {string is entier, true} { - string is entier +1234567890123456789012345678901234567890 +test string-6.124.$noComp {string is entier, true} { + run {string is entier +1234567890123456789012345678901234567890} } 1 -test string-6.125 {string is entier, true} { - string is entier [list -10000000000000000000000000000000000000000000000000000000000000000000000000000000000000] +test string-6.125.$noComp {string is entier, true} { + run {string is entier [list -10000000000000000000000000000000000000000000000000000000000000000000000000000000000000]} } 1 -test string-6.126 {string is entier, true as hex} { - string is entier 0xabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdef +test string-6.126.$noComp {string is entier, true as hex} { + run {string is entier 0xabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdef} } 1 -test string-6.127 {string is entier, true as octal} { - string is entier 0123456112341234561234565623456123456123456123456123456123456123456123456123456123456 +test string-6.127.$noComp {string is entier, true as octal} { + run {string is entier 0123456112341234561234565623456123456123456123456123456123456123456123456123456123456} } 1 -test string-6.128 {string is entier, true with whitespace} { - string is entier " \n12340000000000000000000000000000000000000000000000000000000000000000000000000000000000000\v" +test string-6.128.$noComp {string is entier, true with whitespace} { + run {string is entier " \n12340000000000000000000000000000000000000000000000000000000000000000000000000000000000000\v"} } 1 -test string-6.129 {string is entier, false on bad octal} { - list [string is entier -fail var 0o1234561123412345612345656234561234561234561234561234561234561234561234561234561234536963] $var +test string-6.129.$noComp {string is entier, false on bad octal} { + list [run {string is entier -fail var 0o1234561123412345612345656234561234561234561234561234561234561234561234561234561234536963}] $var } {0 87} -test string-6.130.1 {string is entier, false on bad octal} { - list [string is entier -fail var 0o1234561123412345612345656234561234561234561234561234561234561234561234561234561234536963] $var +test string-6.130.1.$noComp {string is entier, false on bad octal} { + list [run {string is entier -fail var 0o1234561123412345612345656234561234561234561234561234561234561234561234561234561234536963}] $var } {0 87} -test string-6.131 {string is entier, false on bad hex} { - list [string is entier -fail var 0X12345611234123456123456562345612345612345612345612345612345612345612345612345612345345XYZ] $var +test string-6.131.$noComp {string is entier, false on bad hex} { + list [run {string is entier -fail var 0X12345611234123456123456562345612345612345612345612345612345612345612345612345612345345XYZ}] $var } {0 88} catch {rename largest_int {}} -test string-7.1 {string last, too few args} { - list [catch {string last a} msg] $msg +test string-7.1.$noComp {string last, too few args} { + list [catch {run {string last a}} msg] $msg } {1 {wrong # args: should be "string last needleString haystackString ?lastIndex?"}} -test string-7.2 {string last, bad args} { - list [catch {string last a b c} msg] $msg +test string-7.2.$noComp {string last, bad args} { + list [catch {run {string last a b c}} msg] $msg } {1 {bad index "c": must be integer?[+-]integer? or end?[+-]integer?}} -test string-7.3 {string last, too many args} { - list [catch {string last a b c d} msg] $msg +test string-7.3.$noComp {string last, too many args} { + list [catch {run {string last a b c d}} msg] $msg } {1 {wrong # args: should be "string last needleString haystackString ?lastIndex?"}} -test string-7.4 {string last} { - string la xxx xxxx123xx345x678 +test string-7.4.$noComp {string last} { + run {string la xxx xxxx123xx345x678} } 1 -test string-7.5 {string last} { - string last xx xxxx123xx345x678 +test string-7.5.$noComp {string last} { + run {string last xx xxxx123xx345x678} } 7 -test string-7.6 {string last} { - string las x xxxx123xx345x678 +test string-7.6.$noComp {string last} { + run {string las x xxxx123xx345x678} } 12 -test string-7.7 {string last, unicode} { - string las x xxxx12\u7266xx345x678 +test string-7.7.$noComp {string last, unicode} { + run {string las x xxxx12\u7266xx345x678} } 12 -test string-7.8 {string last, unicode} { - string las \u7266 xxxx12\u7266xx345x678 +test string-7.8.$noComp {string last, unicode} { + run {string las \u7266 xxxx12\u7266xx345x678} } 6 -test string-7.9 {string last, stop index} { - string las \u7266 xxxx12\u7266xx345x678 +test string-7.9.$noComp {string last, stop index} { + run {string las \u7266 xxxx12\u7266xx345x678} } 6 -test string-7.10 {string last, unicode} { - string las \u7266 xxxx12\u7266xx345x678 +test string-7.10.$noComp {string last, unicode} { + run {string las \u7266 xxxx12\u7266xx345x678} } 6 -test string-7.11 {string last, start index} { - string last \u7266 abc\u7266x 3 +test string-7.11.$noComp {string last, start index} { + run {string last \u7266 abc\u7266x 3} } 3 -test string-7.12 {string last, start index} { - string last \u7266 abc\u7266x 2 +test string-7.12.$noComp {string last, start index} { + run {string last \u7266 abc\u7266x 2} } -1 -test string-7.13 {string last, start index} { +test string-7.13.$noComp {string last, start index} { ## Constrain to last 'a' should work - string last ba badbad end-1 + run {string last ba badbad end-1} } 3 -test string-7.14 {string last, start index} { +test string-7.14.$noComp {string last, start index} { ## Constrain to last 'b' should skip last 'ba' - string last ba badbad end-2 + run {string last ba badbad end-2} } 0 -test string-7.15 {string last, start index} { - string last \334a \334ad\334ad 0 +test string-7.15.$noComp {string last, start index} { + run {string last \334a \334ad\334ad 0} } -1 -test string-7.16 {string last, start index} { - string last \334a \334ad\334ad end-1 +test string-7.16.$noComp {string last, start index} { + run {string last \334a \334ad\334ad end-1} } 3 -test string-8.1 {string bytelength} { - list [catch {string bytelength} msg] $msg +test string-8.1.$noComp {string bytelength} { + list [catch {run {string bytelength}} msg] $msg } {1 {wrong # args: should be "string bytelength string"}} -test string-8.2 {string bytelength} { - list [catch {string bytelength a b} msg] $msg +test string-8.2.$noComp {string bytelength} { + list [catch {run {string bytelength a b}} msg] $msg } {1 {wrong # args: should be "string bytelength string"}} -test string-8.3 {string bytelength} { - string bytelength "\u00c7" +test string-8.3.$noComp {string bytelength} { + run {string bytelength "\u00c7"} } 2 -test string-8.4 {string bytelength} { - string b "" +test string-8.4.$noComp {string bytelength} { + run {string b ""} } 0 -test string-9.1 {string length} { - list [catch {string length} msg] $msg +test string-9.1.$noComp {string length} { + list [catch {run {string length}} msg] $msg } {1 {wrong # args: should be "string length string"}} -test string-9.2 {string length} { - list [catch {string length a b} msg] $msg +test string-9.2.$noComp {string length} { + list [catch {run {string length a b}} msg] $msg } {1 {wrong # args: should be "string length string"}} -test string-9.3 {string length} { - string length "a little string" +test string-9.3.$noComp {string length} { + run {string length "a little string"} } 15 -test string-9.4 {string length} { - string le "" +test string-9.4.$noComp {string length} { + run {string le ""} } 0 -test string-9.5 {string length, unicode} { - string le "abcd\u7266" +test string-9.5.$noComp {string length, unicode} { + run {string le "abcd\u7266"} } 5 -test string-9.6 {string length, bytearray object} { - string length [binary format a5 foo] +test string-9.6.$noComp {string length, bytearray object} { + run {string length [binary format a5 foo]} } 5 -test string-9.7 {string length, bytearray object} { - string length [binary format I* {0x50515253 0x52}] +test string-9.7.$noComp {string length, bytearray object} { + run {string length [binary format I* {0x50515253 0x52}]} } 8 -test string-10.1 {string map, too few args} { - list [catch {string map} msg] $msg +test string-10.1.$noComp {string map, too few args} { + list [catch {run {string map}} msg] $msg } {1 {wrong # args: should be "string map ?-nocase? charMap string"}} -test string-10.2 {string map, bad args} { - list [catch {string map {a b} abba oops} msg] $msg +test string-10.2.$noComp {string map, bad args} { + list [catch {run {string map {a b} abba oops}} msg] $msg } {1 {bad option "a b": must be -nocase}} -test string-10.3 {string map, too many args} { - list [catch {string map -nocase {a b} str1 str2} msg] $msg +test string-10.3.$noComp {string map, too many args} { + list [catch {run {string map -nocase {a b} str1 str2}} msg] $msg } {1 {wrong # args: should be "string map ?-nocase? charMap string"}} -test string-10.4 {string map} { - string map {a b} abba +test string-10.4.$noComp {string map} { + run {string map {a b} abba} } {bbbb} -test string-10.5 {string map} { - string map {a b} a +test string-10.5.$noComp {string map} { + run {string map {a b} a} } {b} -test string-10.6 {string map -nocase} { - string map -nocase {a b} Abba +test string-10.6.$noComp {string map -nocase} { + run {string map -nocase {a b} Abba} } {bbbb} -test string-10.7 {string map} { - string map {abc 321 ab * a A} aabcabaababcab +test string-10.7.$noComp {string map} { + run {string map {abc 321 ab * a A} aabcabaababcab} } {A321*A*321*} -test string-10.8 {string map -nocase} { - string map -nocase {aBc 321 Ab * a A} aabcabaababcab +test string-10.8.$noComp {string map -nocase} { + run {string map -nocase {aBc 321 Ab * a A} aabcabaababcab} } {A321*A*321*} -test string-10.9 {string map -nocase} { - string map -no {abc 321 Ab * a A} aAbCaBaAbAbcAb +test string-10.9.$noComp {string map -nocase} { + run {string map -no {abc 321 Ab * a A} aAbCaBaAbAbcAb} } {A321*A*321*} -test string-10.10 {string map} { - list [catch {string map {a b c} abba} msg] $msg +test string-10.10.$noComp {string map} { + list [catch {run {string map {a b c} abba}} msg] $msg } {1 {char map list unbalanced}} -test string-10.11 {string map, nulls} { - string map {\x00 NULL blah \x00nix} {qwerty} +test string-10.11.$noComp {string map, nulls} { + run {string map {\x00 NULL blah \x00nix} {qwerty}} } {qwerty} -test string-10.12 {string map, unicode} { - string map [list \374 ue UE \334] "a\374ueUE\000EU" +test string-10.12.$noComp {string map, unicode} { + run {string map [list \374 ue UE \334] "a\374ueUE\000EU"} } aueue\334\0EU -test string-10.13 {string map, -nocase unicode} { - string map -nocase [list \374 ue UE \334] "a\374ueUE\000EU" +test string-10.13.$noComp {string map, -nocase unicode} { + run {string map -nocase [list \374 ue UE \334] "a\374ueUE\000EU"} } aue\334\334\0EU -test string-10.14 {string map, -nocase null arguments} { - string map -nocase {{} abc} foo +test string-10.14.$noComp {string map, -nocase null arguments} { + run {string map -nocase {{} abc} foo} } foo -test string-10.15 {string map, one pair case} { - string map -nocase {abc 32} aAbCaBaAbAbcAb +test string-10.15.$noComp {string map, one pair case} { + run {string map -nocase {abc 32} aAbCaBaAbAbcAb} } {a32aBaAb32Ab} -test string-10.16 {string map, one pair case} { - string map -nocase {ab 4321} aAbCaBaAbAbcAb +test string-10.16.$noComp {string map, one pair case} { + run {string map -nocase {ab 4321} aAbCaBaAbAbcAb} } {a4321C4321a43214321c4321} -test string-10.17 {string map, one pair case} { - string map {Ab 4321} aAbCaBaAbAbcAb +test string-10.17.$noComp {string map, one pair case} { + run {string map {Ab 4321} aAbCaBaAbAbcAb} } {a4321CaBa43214321c4321} -test string-10.18 {string map, empty argument} { - string map -nocase {{} abc} foo +test string-10.18.$noComp {string map, empty argument} { + run {string map -nocase {{} abc} foo} } foo -test string-10.19 {string map, empty arguments} { - string map -nocase {{} abc f bar {} def} foo +test string-10.19.$noComp {string map, empty arguments} { + run {string map -nocase {{} abc f bar {} def} foo} } baroo -test string-10.20 {string map, dictionaries don't alter map ordering} { +test string-10.20.$noComp {string map, dictionaries don't alter map ordering} { set map {aa X a Y} - list [string map [dict create aa X a Y] aaa] [string map $map aaa] [dict size $map] [string map $map aaa] + list [run {string map [dict create aa X a Y] aaa}] [run {string map $map aaa}] [dict size $map] [run {string map $map aaa}] } {XY XY 2 XY} -test string-10.20.1 {string map, dictionaries don't alter map ordering} { +test string-10.20.1.$noComp {string map, dictionaries don't alter map ordering} { set map {a X b Y a Z} - list [string map [dict create a X b Y a Z] aaa] [string map $map aaa] [dict size $map] [string map $map aaa] + list [run {string map [dict create a X b Y a Z] aaa}] [run {string map $map aaa}] [dict size $map] [run {string map $map aaa}] } {ZZZ XXX 2 XXX} -test string-10.21 {string map, ABR checks} { - string map {longstring foob} long +test string-10.21.$noComp {string map, ABR checks} { + run {string map {longstring foob} long} } long -test string-10.22 {string map, ABR checks} { - string map {long foob} long +test string-10.22.$noComp {string map, ABR checks} { + run {string map {long foob} long} } foob -test string-10.23 {string map, ABR checks} { - string map {lon foob} long +test string-10.23.$noComp {string map, ABR checks} { + run {string map {lon foob} long} } foobg -test string-10.24 {string map, ABR checks} { - string map {lon foob} longlo +test string-10.24.$noComp {string map, ABR checks} { + run {string map {lon foob} longlo} } foobglo -test string-10.25 {string map, ABR checks} { - string map {lon foob} longlon +test string-10.25.$noComp {string map, ABR checks} { + run {string map {lon foob} longlon} } foobgfoob -test string-10.26 {string map, ABR checks} { - string map {longstring foob longstring bar} long +test string-10.26.$noComp {string map, ABR checks} { + run {string map {longstring foob longstring bar} long} } long -test string-10.27 {string map, ABR checks} { - string map {long foob longstring bar} long +test string-10.27.$noComp {string map, ABR checks} { + run {string map {long foob longstring bar} long} } foob -test string-10.28 {string map, ABR checks} { - string map {lon foob longstring bar} long +test string-10.28.$noComp {string map, ABR checks} { + run {string map {lon foob longstring bar} long} } foobg -test string-10.29 {string map, ABR checks} { - string map {lon foob longstring bar} longlo +test string-10.29.$noComp {string map, ABR checks} { + run {string map {lon foob longstring bar} longlo} } foobglo -test string-10.30 {string map, ABR checks} { - string map {lon foob longstring bar} longlon +test string-10.30.$noComp {string map, ABR checks} { + run {string map {lon foob longstring bar} longlon} } foobgfoob -test string-10.31 {string map, nasty sharing crash from [Bug 1018562]} { +test string-10.31.$noComp {string map, nasty sharing crash from [Bug 1018562]} { set a {a b} - string map $a $a + run {string map $a $a} } {b b} -test string-11.1 {string match, too few args} { - list [catch {string match a} msg] $msg +test string-11.1.$noComp {string match, too few args} { + list [catch {run {string match a}} msg] $msg } {1 {wrong # args: should be "string match ?-nocase? pattern string"}} -test string-11.2 {string match, too many args} { - list [catch {string match a b c d} msg] $msg +test string-11.2.$noComp {string match, too many args} { + list [catch {run {string match a b c d}} msg] $msg } {1 {wrong # args: should be "string match ?-nocase? pattern string"}} -test string-11.3 {string match} { - string match abc abc +test string-11.3.$noComp {string match} { + run {string match abc abc} } 1 -test string-11.4 {string match} { - string mat abc abd +test string-11.4.$noComp {string match} { + run {string mat abc abd} } 0 -test string-11.5 {string match} { - string match ab*c abc +test string-11.5.$noComp {string match} { + run {string match ab*c abc} } 1 -test string-11.6 {string match} { - string match ab**c abc +test string-11.6.$noComp {string match} { + run {string match ab**c abc} } 1 -test string-11.7 {string match} { - string match ab* abcdef +test string-11.7.$noComp {string match} { + run {string match ab* abcdef} } 1 -test string-11.8 {string match} { - string match *c abc +test string-11.8.$noComp {string match} { + run {string match *c abc} } 1 -test string-11.9 {string match} { - string match *3*6*9 0123456789 +test string-11.9.$noComp {string match} { + run {string match *3*6*9 0123456789} } 1 -test string-11.9.1 {string match} { - string match *3*6*89 0123456789 +test string-11.9.1.$noComp {string match} { + run {string match *3*6*89 0123456789} } 1 -test string-11.9.2 {string match} { - string match *3*456*89 0123456789 +test string-11.9.2.$noComp {string match} { + run {string match *3*456*89 0123456789} } 1 -test string-11.9.3 {string match} { - string match *3*6* 0123456789 +test string-11.9.3.$noComp {string match} { + run {string match *3*6* 0123456789} } 1 -test string-11.9.4 {string match} { - string match *3*56* 0123456789 +test string-11.9.4.$noComp {string match} { + run {string match *3*56* 0123456789} } 1 -test string-11.9.5 {string match} { - string match *3*456*** 0123456789 +test string-11.9.5.$noComp {string match} { + run {string match *3*456*** 0123456789} } 1 -test string-11.9.6 {string match} { - string match **3*456** 0123456789 +test string-11.9.6.$noComp {string match} { + run {string match **3*456** 0123456789} } 1 -test string-11.9.7 {string match} { - string match *3***456* 0123456789 +test string-11.9.7.$noComp {string match} { + run {string match *3***456* 0123456789} } 1 -test string-11.9.8 {string match} { - string match *3***\[456]* 0123456789 +test string-11.9.8.$noComp {string match} { + run {string match *3***\[456]* 0123456789} } 1 -test string-11.9.9 {string match} { - string match *3***\[4-6]* 0123456789 +test string-11.9.9.$noComp {string match} { + run {string match *3***\[4-6]* 0123456789} } 1 -test string-11.9.10 {string match} { - string match *3***\[4-6] 0123456789 +test string-11.9.10.$noComp {string match} { + run {string match *3***\[4-6] 0123456789} } 0 -test string-11.9.11 {string match} { - string match *3***\[4-6] 0123456 +test string-11.9.11.$noComp {string match} { + run {string match *3***\[4-6] 0123456} } 1 -test string-11.10 {string match} { - string match *3*6*9 01234567890 +test string-11.10.$noComp {string match} { + run {string match *3*6*9 01234567890} } 0 -test string-11.10.1 {string match} { - string match *3*6*89 01234567890 +test string-11.10.1.$noComp {string match} { + run {string match *3*6*89 01234567890} } 0 -test string-11.10.2 {string match} { - string match *3*456*89 01234567890 +test string-11.10.2.$noComp {string match} { + run {string match *3*456*89 01234567890} } 0 -test string-11.10.3 {string match} { - string match **3*456*89 01234567890 +test string-11.10.3.$noComp {string match} { + run {string match **3*456*89 01234567890} } 0 -test string-11.10.4 {string match} { - string match *3*456***89 01234567890 +test string-11.10.4.$noComp {string match} { + run {string match *3*456***89 01234567890} } 0 -test string-11.11 {string match} { - string match a?c abc +test string-11.11.$noComp {string match} { + run {string match a?c abc} } 1 -test string-11.12 {string match} { - string match a??c abc +test string-11.12.$noComp {string match} { + run {string match a??c abc} } 0 -test string-11.13 {string match} { - string match ?1??4???8? 0123456789 +test string-11.13.$noComp {string match} { + run {string match ?1??4???8? 0123456789} } 1 -test string-11.14 {string match} { - string match {[abc]bc} abc +test string-11.14.$noComp {string match} { + run {string match {[abc]bc} abc} } 1 -test string-11.15 {string match} { - string match {a[abc]c} abc +test string-11.15.$noComp {string match} { + run {string match {a[abc]c} abc} } 1 -test string-11.16 {string match} { - string match {a[xyz]c} abc +test string-11.16.$noComp {string match} { + run {string match {a[xyz]c} abc} } 0 -test string-11.17 {string match} { - string match {12[2-7]45} 12345 +test string-11.17.$noComp {string match} { + run {string match {12[2-7]45} 12345} } 1 -test string-11.18 {string match} { - string match {12[ab2-4cd]45} 12345 +test string-11.18.$noComp {string match} { + run {string match {12[ab2-4cd]45} 12345} } 1 -test string-11.19 {string match} { - string match {12[ab2-4cd]45} 12b45 +test string-11.19.$noComp {string match} { + run {string match {12[ab2-4cd]45} 12b45} } 1 -test string-11.20 {string match} { - string match {12[ab2-4cd]45} 12d45 +test string-11.20.$noComp {string match} { + run {string match {12[ab2-4cd]45} 12d45} } 1 -test string-11.21 {string match} { - string match {12[ab2-4cd]45} 12145 +test string-11.21.$noComp {string match} { + run {string match {12[ab2-4cd]45} 12145} } 0 -test string-11.22 {string match} { - string match {12[ab2-4cd]45} 12545 +test string-11.22.$noComp {string match} { + run {string match {12[ab2-4cd]45} 12545} } 0 -test string-11.23 {string match} { - string match {a\*b} a*b +test string-11.23.$noComp {string match} { + run {string match {a\*b} a*b} } 1 -test string-11.24 {string match} { - string match {a\*b} ab +test string-11.24.$noComp {string match} { + run {string match {a\*b} ab} } 0 -test string-11.25 {string match} { - string match {a\*\?\[\]\\\x} "a*?\[\]\\x" +test string-11.25.$noComp {string match} { + run {string match {a\*\?\[\]\\\x} "a*?\[\]\\x"} } 1 -test string-11.26 {string match} { - string match ** "" +test string-11.26.$noComp {string match} { + run {string match ** ""} } 1 -test string-11.27 {string match} { - string match *. "" +test string-11.27.$noComp {string match} { + run {string match *. ""} } 0 -test string-11.28 {string match} { - string match "" "" +test string-11.28.$noComp {string match} { + run {string match "" ""} } 1 -test string-11.29 {string match} { - string match \[a a +test string-11.29.$noComp {string match} { + run {string match \[a a} } 1 -test string-11.30 {string match, bad args} { - list [catch {string match - b c} msg] $msg +test string-11.30.$noComp {string match, bad args} { + list [catch {run {string match - b c}} msg] $msg } {1 {bad option "-": must be -nocase}} -test string-11.31 {string match case} { - string match a A +test string-11.31.$noComp {string match case} { + run {string match a A} } 0 -test string-11.32 {string match nocase} { - string match -n a A +test string-11.32.$noComp {string match nocase} { + run {string match -n a A} } 1 -test string-11.33 {string match nocase} { - string match -nocase a\334 A\374 +test string-11.33.$noComp {string match nocase} { + run {string match -nocase a\334 A\374} } 1 -test string-11.34 {string match nocase} { - string match -nocase a*f ABCDEf +test string-11.34.$noComp {string match nocase} { + run {string match -nocase a*f ABCDEf} } 1 -test string-11.35 {string match case, false hope} { +test string-11.35.$noComp {string match case, false hope} { # This is true because '_' lies between the A-Z and a-z ranges - string match {[A-z]} _ + run {string match {[A-z]} _} } 1 -test string-11.36 {string match nocase range} { +test string-11.36.$noComp {string match nocase range} { # This is false because although '_' lies between the A-Z and a-z ranges, # we lower case the end points before checking the ranges. - string match -nocase {[A-z]} _ + run {string match -nocase {[A-z]} _} } 0 -test string-11.37 {string match nocase} { - string match -nocase {[A-fh-Z]} g +test string-11.37.$noComp {string match nocase} { + run {string match -nocase {[A-fh-Z]} g} } 0 -test string-11.38 {string match case, reverse range} { - string match {[A-fh-Z]} g +test string-11.38.$noComp {string match case, reverse range} { + run {string match {[A-fh-Z]} g} } 1 -test string-11.39 {string match, *\ case} { - string match {*\abc} abc +test string-11.39.$noComp {string match, *\ case} { + run {string match {*\abc} abc} } 1 -test string-11.39.1 {string match, *\ case} { - string match {*ab\c} abc +test string-11.39.1.$noComp {string match, *\ case} { + run {string match {*ab\c} abc} } 1 -test string-11.39.2 {string match, *\ case} { - string match {*ab\*} ab* +test string-11.39.2.$noComp {string match, *\ case} { + run {string match {*ab\*} ab*} } 1 -test string-11.39.3 {string match, *\ case} { - string match {*ab\*} abc +test string-11.39.3.$noComp {string match, *\ case} { + run {string match {*ab\*} abc} } 0 -test string-11.39.4 {string match, *\ case} { - string match {*ab\\*} {ab\c} +test string-11.39.4.$noComp {string match, *\ case} { + run {string match {*ab\\*} {ab\c}} } 1 -test string-11.39.5 {string match, *\ case} { - string match {*ab\\*} {ab\*} +test string-11.39.5.$noComp {string match, *\ case} { + run {string match {*ab\\*} {ab\*}} } 1 -test string-11.40 {string match, *special case} { - string match {*[ab]} abc +test string-11.40.$noComp {string match, *special case} { + run {string match {*[ab]} abc} } 0 -test string-11.41 {string match, *special case} { - string match {*[ab]*} abc +test string-11.41.$noComp {string match, *special case} { + run {string match {*[ab]*} abc} } 1 -test string-11.42 {string match, *special case} { - string match "*\\" "\\" +test string-11.42.$noComp {string match, *special case} { + run {string match "*\\" "\\"} } 0 -test string-11.43 {string match, *special case} { - string match "*\\\\" "\\" +test string-11.43.$noComp {string match, *special case} { + run {string match "*\\\\" "\\"} } 1 -test string-11.44 {string match, *special case} { - string match "*???" "12345" +test string-11.44.$noComp {string match, *special case} { + run {string match "*???" "12345"} } 1 -test string-11.45 {string match, *special case} { - string match "*???" "12" +test string-11.45.$noComp {string match, *special case} { + run {string match "*???" "12"} } 0 -test string-11.46 {string match, *special case} { - string match "*\\*" "abc*" +test string-11.46.$noComp {string match, *special case} { + run {string match "*\\*" "abc*"} } 1 -test string-11.47 {string match, *special case} { - string match "*\\*" "*" +test string-11.47.$noComp {string match, *special case} { + run {string match "*\\*" "*"} } 1 -test string-11.48 {string match, *special case} { - string match "*\\*" "*abc" +test string-11.48.$noComp {string match, *special case} { + run {string match "*\\*" "*abc"} } 0 -test string-11.49 {string match, *special case} { - string match "?\\*" "a*" +test string-11.49.$noComp {string match, *special case} { + run {string match "?\\*" "a*"} } 1 -test string-11.50 {string match, *special case} { - string match "\\" "\\" +test string-11.50.$noComp {string match, *special case} { + run {string match "\\" "\\"} } 0 -test string-11.51 {string match; *, -nocase and UTF-8} { - string match -nocase [binary format I 717316707] \ - [binary format I 2028036707] +test string-11.51.$noComp {string match; *, -nocase and UTF-8} { + run {string match -nocase [binary format I 717316707] \ + [binary format I 2028036707]} } 1 -test string-11.52 {string match, null char in string} { +test string-11.52.$noComp {string match, null char in string} { set out "" set ptn "*abc*" foreach elem [list "\u0000@abc" "@abc" "\u0000@abc\u0000" "blahabcblah"] { - lappend out [string match $ptn $elem] + lappend out [run {string match $ptn $elem}] } set out } {1 1 1 1} -test string-11.53 {string match, null char in pattern} { +test string-11.53.$noComp {string match, null char in pattern} { set out "" foreach {ptn elem} [list \ "*\u0000abc\u0000" "\u0000abc\u0000" \ @@ -1190,661 +1371,707 @@ test string-11.53 {string match, null char in pattern} { "*\u0000abc\u0000" "@\u0000abc\u0000ef" \ "*\u0000abc\u0000*" "@\u0000abc\u0000ef" \ ] { - lappend out [string match $ptn $elem] + lappend out [run {string match $ptn $elem}] } set out } {1 0 1 0 1} -test string-11.54 {string match, failure} { +test string-11.54.$noComp {string match, failure} { set longString "" for {set i 0} {$i < 10} {incr i} { append longString "abcdefghijklmnopqrstuvwxy\u0000z01234567890123" } - string first $longString 123 - list [string match *cba* $longString] \ - [string match *a*l*\u0000* $longString] \ - [string match *a*l*\u0000*123 $longString] \ - [string match *a*l*\u0000*123* $longString] \ - [string match *a*l*\u0000*cba* $longString] \ - [string match *===* $longString] + run {string first $longString 123} + list [run {string match *cba* $longString}] \ + [run {string match *a*l*\u0000* $longString}] \ + [run {string match *a*l*\u0000*123 $longString}] \ + [run {string match *a*l*\u0000*123* $longString}] \ + [run {string match *a*l*\u0000*cba* $longString}] \ + [run {string match *===* $longString}] } {0 1 1 1 0 0} -test string-11.55 {string match, invalid binary optimization} { +test string-11.55.$noComp {string match, invalid binary optimization} { [format string] match \u0141 [binary format c 65] } 0 -test string-12.1 {string range} { - list [catch {string range} msg] $msg +test stringComp-12.1.0.$noComp {Bug 3588366: end-offsets before start} { + apply {s { + string range $s 0 end-5 + }} 12345 +} {} +test string-12.1.$noComp {string range} { + list [catch {run {string range}} msg] $msg } {1 {wrong # args: should be "string range string first last"}} -test string-12.2 {string range} { - list [catch {string range a 1} msg] $msg +test string-12.2.$noComp {string range} { + list [catch {run {string range a 1}} msg] $msg } {1 {wrong # args: should be "string range string first last"}} -test string-12.3 {string range} { - list [catch {string range a 1 2 3} msg] $msg +test string-12.3.$noComp {string range} { + list [catch {run {string range a 1 2 3}} msg] $msg } {1 {wrong # args: should be "string range string first last"}} -test string-12.4 {string range} { - string range abcdefghijklmnop 2 14 +test string-12.4.$noComp {string range} { + run {string range abcdefghijklmnop 2 14} } {cdefghijklmno} -test string-12.5 {string range, last > length} { - string range abcdefghijklmnop 7 1000 +test string-12.5.$noComp {string range, last > length} { + run {string range abcdefghijklmnop 7 1000} } {hijklmnop} -test string-12.6 {string range} { - string range abcdefghijklmnop 10 end +test string-12.6.$noComp {string range} { + run {string range abcdefghijklmnop 10 end} } {klmnop} -test string-12.7 {string range, last < first} { - string range abcdefghijklmnop 10 9 +test string-12.7.$noComp {string range, last < first} { + run {string range abcdefghijklmnop 10 9} } {} -test string-12.8 {string range, first < 0} { - string range abcdefghijklmnop -3 2 +test string-12.8.$noComp {string range, first < 0} { + run {string range abcdefghijklmnop -3 2} } {abc} -test string-12.9 {string range} { - string range abcdefghijklmnop -3 -2 +test string-12.9.$noComp {string range} { + run {string range abcdefghijklmnop -3 -2} } {} -test string-12.10 {string range} { - string range abcdefghijklmnop 1000 1010 +test string-12.10.$noComp {string range} { + run {string range abcdefghijklmnop 1000 1010} } {} -test string-12.11 {string range} { - string range abcdefghijklmnop -100 end +test string-12.11.$noComp {string range} { + run {string range abcdefghijklmnop -100 end} } {abcdefghijklmnop} -test string-12.12 {string range} { - list [catch {string range abc abc 1} msg] $msg +test string-12.12.$noComp {string range} { + list [catch {run {string range abc abc 1}} msg] $msg } {1 {bad index "abc": must be integer?[+-]integer? or end?[+-]integer?}} -test string-12.13 {string range} { - list [catch {string range abc 1 eof} msg] $msg +test string-12.13.$noComp {string range} { + list [catch {run {string range abc 1 eof}} msg] $msg } {1 {bad index "eof": must be integer?[+-]integer? or end?[+-]integer?}} -test string-12.14 {string range} { - string range abcdefghijklmnop end-1 end +test string-12.14.$noComp {string range} { + run {string range abcdefghijklmnop end-1 end} } {op} -test string-12.15 {string range} { - string range abcdefghijklmnop end 1000 +test string-12.15.$noComp {string range} { + run {string range abcdefghijklmnop end 1000} } {p} -test string-12.16 {string range} { - string range abcdefghijklmnop end end-1 +test string-12.16.$noComp {string range} { + run {string range abcdefghijklmnop end end-1} } {} -test string-12.17 {string range, unicode} { - string range ab\u7266cdefghijklmnop 5 5 +test string-12.17.$noComp {string range, unicode} { + run {string range ab\u7266cdefghijklmnop 5 5} } e -test string-12.18 {string range, unicode} { - string range ab\u7266cdefghijklmnop 2 3 +test string-12.18.$noComp {string range, unicode} { + run {string range ab\u7266cdefghijklmnop 2 3} } \u7266c -test string-12.19 {string range, bytearray object} { +test string-12.19.$noComp {string range, bytearray object} { set b [binary format I* {0x50515253 0x52}] - set r1 [string range $b 1 end-1] - set r2 [string range $b 1 6] - string equal $r1 $r2 + set r1 [run {string range $b 1 end-1}] + set r2 [run {string range $b 1 6}] + run {string equal $r1 $r2} } 1 -test string-12.20 {string range, out of bounds indices} { - string range \u00ff 0 1 +test string-12.20.$noComp {string range, out of bounds indices} { + run {string range \u00ff 0 1} } \u00ff # Bug 1410553 -test string-12.21 {string range, regenerates correct reps, bug 1410553} { +test string-12.21.$noComp {string range, regenerates correct reps, bug 1410553} { set bytes "\x00 \x03 \x41" set rxBuffer {} foreach ch $bytes { append rxBuffer $ch if {$ch eq "\x03"} { - string length $rxBuffer + run {string length $rxBuffer} } } - set rxCRC [string range $rxBuffer end-1 end] + set rxCRC [run {string range $rxBuffer end-1 end}] binary scan [join $bytes {}] "H*" input_hex binary scan $rxBuffer "H*" rxBuffer_hex binary scan $rxCRC "H*" rxCRC_hex list $input_hex $rxBuffer_hex $rxCRC_hex } {000341 000341 0341} -test string-12.22 {string range, shimmering binary/index} { +test string-12.22.$noComp {string range, shimmering binary/index} { set s 0000000001 binary scan $s a* x - string range $s $s end + run {string range $s $s end} } 000000001 -test string-12.23 {string range, surrogates, bug [11ae2be95dac9417]} fullutf { - list [string range a\U100000b 1 1] [string range a\U100000b 2 2] [string range a\U100000b 3 3] +test string-12.23.$noComp {string range, surrogates, bug [11ae2be95dac9417]} fullutf { + run {list [string range a\U100000b 1 1] [string range a\U100000b 2 2] [string range a\U100000b 3 3]} } [list \U100000 {} b] -test string-13.1 {string repeat} { - list [catch {string repeat} msg] $msg +test string-13.1.$noComp {string repeat} { + list [catch {run {string repeat}} msg] $msg } {1 {wrong # args: should be "string repeat string count"}} -test string-13.2 {string repeat} { - list [catch {string repeat abc 10 oops} msg] $msg +test string-13.2.$noComp {string repeat} { + list [catch {run {string repeat abc 10 oops}} msg] $msg } {1 {wrong # args: should be "string repeat string count"}} -test string-13.3 {string repeat} { - string repeat {} 100 +test string-13.3.$noComp {string repeat} { + run {string repeat {} 100} } {} -test string-13.4 {string repeat} { - string repeat { } 5 +test string-13.4.$noComp {string repeat} { + run {string repeat { } 5} } { } -test string-13.5 {string repeat} { - string repeat abc 3 +test string-13.5.$noComp {string repeat} { + run {string repeat abc 3} } {abcabcabc} -test string-13.6 {string repeat} { - string repeat abc -1 +test string-13.6.$noComp {string repeat} { + run {string repeat abc -1} } {} -test string-13.7 {string repeat} { - list [catch {string repeat abc end} msg] $msg +test string-13.7.$noComp {string repeat} { + list [catch {run {string repeat abc end}} msg] $msg } {1 {expected integer but got "end"}} -test string-13.8 {string repeat} { - string repeat {} -1000 +test string-13.8.$noComp {string repeat} { + run {string repeat {} -1000} } {} -test string-13.9 {string repeat} { - string repeat {} 0 +test string-13.9.$noComp {string repeat} { + run {string repeat {} 0} } {} -test string-13.10 {string repeat} { - string repeat def 0 +test string-13.10.$noComp {string repeat} { + run {string repeat def 0} } {} -test string-13.11 {string repeat} { - string repeat def 1 +test string-13.11.$noComp {string repeat} { + run {string repeat def 1} } def -test string-13.12 {string repeat} { - string repeat ab\u7266cd 3 +test string-13.12.$noComp {string repeat} { + run {string repeat ab\u7266cd 3} } ab\u7266cdab\u7266cdab\u7266cd -test string-13.13 {string repeat} { - string repeat \x00 3 +test string-13.13.$noComp {string repeat} { + run {string repeat \x00 3} } \x00\x00\x00 -test string-13.14 {string repeat} { +test string-13.14.$noComp {string repeat} { # The string range will ensure us that string repeat gets a unicode string - string repeat [string range ab\u7266cd 2 3] 3 + run {string repeat [run {string range ab\u7266cd 2 3}] 3} } \u7266c\u7266c\u7266c -test string-14.1 {string replace} { - list [catch {string replace} msg] $msg +test string-14.1.$noComp {string replace} { + list [catch {run {string replace}} msg] $msg } {1 {wrong # args: should be "string replace string first last ?string?"}} -test string-14.2 {string replace} { - list [catch {string replace a 1} msg] $msg +test string-14.2.$noComp {string replace} { + list [catch {run {string replace a 1}} msg] $msg } {1 {wrong # args: should be "string replace string first last ?string?"}} -test string-14.3 {string replace} { - list [catch {string replace a 1 2 3 4} msg] $msg +test string-14.3.$noComp {string replace} { + list [catch {run {string replace a 1 2 3 4}} msg] $msg } {1 {wrong # args: should be "string replace string first last ?string?"}} -test string-14.4 {string replace} { +test string-14.4.$noComp {string replace} { } {} -test string-14.5 {string replace} { - string replace abcdefghijklmnop 2 14 +test string-14.5.$noComp {string replace} { + run {string replace abcdefghijklmnop 2 14} } {abp} -test string-14.6 {string replace} { - string replace abcdefghijklmnop 7 1000 +test string-14.6.$noComp {string replace} { + run {string replace abcdefghijklmnop 7 1000} } {abcdefg} -test string-14.7 {string replace} { - string replace abcdefghijklmnop 10 end +test string-14.7.$noComp {string replace} { + run {string replace abcdefghijklmnop 10 end} } {abcdefghij} -test string-14.8 {string replace} { - string replace abcdefghijklmnop 10 9 +test string-14.8.$noComp {string replace} { + run {string replace abcdefghijklmnop 10 9} } {abcdefghijklmnop} -test string-14.9 {string replace} { - string replace abcdefghijklmnop -3 2 +test string-14.9.$noComp {string replace} { + run {string replace abcdefghijklmnop -3 2} } {defghijklmnop} -test string-14.10 {string replace} { - string replace abcdefghijklmnop -3 -2 +test string-14.10.$noComp {string replace} { + run {string replace abcdefghijklmnop -3 -2} } {abcdefghijklmnop} -test string-14.11 {string replace} { - string replace abcdefghijklmnop 1000 1010 +test string-14.11.$noComp {string replace} { + run {string replace abcdefghijklmnop 1000 1010} } {abcdefghijklmnop} -test string-14.12 {string replace} { - string replace abcdefghijklmnop -100 end +test string-14.12.$noComp {string replace} { + run {string replace abcdefghijklmnop -100 end} } {} -test string-14.13 {string replace} { - list [catch {string replace abc abc 1} msg] $msg +test string-14.13.$noComp {string replace} { + list [catch {run {string replace abc abc 1}} msg] $msg } {1 {bad index "abc": must be integer?[+-]integer? or end?[+-]integer?}} -test string-14.14 {string replace} { - list [catch {string replace abc 1 eof} msg] $msg +test string-14.14.$noComp {string replace} { + list [catch {run {string replace abc 1 eof}} msg] $msg } {1 {bad index "eof": must be integer?[+-]integer? or end?[+-]integer?}} -test string-14.15 {string replace} { - string replace abcdefghijklmnop end-10 end-2 NEW +test string-14.15.$noComp {string replace} { + run {string replace abcdefghijklmnop end-10 end-2 NEW} } {abcdeNEWop} -test string-14.16 {string replace} { - string replace abcdefghijklmnop 0 end foo +test string-14.16.$noComp {string replace} { + run {string replace abcdefghijklmnop 0 end foo} } {foo} -test string-14.17 {string replace} { - string replace abcdefghijklmnop end end-1 +test string-14.17.$noComp {string replace} { + run {string replace abcdefghijklmnop end end-1} } {abcdefghijklmnop} -test string-14.18 {string replace} { - string replace abcdefghijklmnop 10 9 XXX +test string-14.18.$noComp {string replace} { + run {string replace abcdefghijklmnop 10 9 XXX} } {abcdefghijklmnop} -test string-14.19 {string replace} { - string replace {} -1 0 A +test string-14.19.$noComp {string replace} { + run {string replace {} -1 0 A} } A -test string-14.20 {string replace} { - string replace [makeByteArray abcdefghijklmnop] end-10 end-2 [makeByteArray NEW] -} abcdeNEWop +test string-14.20.$noComp {string replace} { + run {string replace [makeByteArray abcdefghijklmnop] end-10 end-2\ + [makeByteArray NEW]} +} {abcdeNEWop} + -test string-15.1 {string tolower too few args} { - list [catch {string tolower} msg] $msg +test stringComp-14.21.$noComp {Bug 82e7f67325} { + apply {x { + set a [join $x {}] + lappend b [string length [string replace ___! 0 2 $a]] + lappend b [string length [string replace ___! 0 2 $a[unset a]]] + }} {a b} +} {3 3} +test stringComp-14.22.$noComp {Bug 82e7f67325} memory { + # As in stringComp-14.1, but make sure we don't retain too many refs + leaktest { + apply {x { + set a [join $x {}] + lappend b [string length [string replace ___! 0 2 $a]] + lappend b [string length [string replace ___! 0 2 $a[unset a]]] + }} {a b} + } +} {0} +test stringComp-14.23.$noComp {Bug 0dca3bfa8f} { + apply {arg { + set argCopy $arg + set arg [string replace $arg 1 2 aa] + # Crashes in comparison before fix + expr {$arg ne $argCopy} + }} abcde +} 1 +test stringComp-14.24.$noComp {Bug 1af8de570511} { + apply {{x y} { + # Generate an unshared string value + set val "" + for { set i 0 } { $i < $x } { incr i } { + set val [format "0%s" $val] + } + string replace $val[unset val] 1 1 $y + }} 4 x +} 0x00 +test stringComp-14.25.$noComp {} { + string length [string replace [string repeat a\u00fe 2] 3 end {}] +} 3 + +test string-15.1.$noComp {string tolower too few args} { + list [catch {run {string tolower}} msg] $msg } {1 {wrong # args: should be "string tolower string ?first? ?last?"}} -test string-15.2 {string tolower bad args} { - list [catch {string tolower a b} msg] $msg +test string-15.2.$noComp {string tolower bad args} { + list [catch {run {string tolower a b}} msg] $msg } {1 {bad index "b": must be integer?[+-]integer? or end?[+-]integer?}} -test string-15.3 {string tolower too many args} { - list [catch {string tolower ABC 1 end oops} msg] $msg +test string-15.3.$noComp {string tolower too many args} { + list [catch {run {string tolower ABC 1 end oops}} msg] $msg } {1 {wrong # args: should be "string tolower string ?first? ?last?"}} -test string-15.4 {string tolower} { - string tolower ABCDeF +test string-15.4.$noComp {string tolower} { + run {string tolower ABCDeF} } {abcdef} -test string-15.5 {string tolower} { - string tolower "ABC XyZ" +test string-15.5.$noComp {string tolower} { + run {string tolower "ABC XyZ"} } {abc xyz} -test string-15.6 {string tolower} { - string tolower {123#$&*()} +test string-15.6.$noComp {string tolower} { + run {string tolower {123#$&*()}} } {123#$&*()} -test string-15.7 {string tolower} { - string tolower ABC 1 +test string-15.7.$noComp {string tolower} { + run {string tolower ABC 1} } AbC -test string-15.8 {string tolower} { - string tolower ABC 1 end +test string-15.8.$noComp {string tolower} { + run {string tolower ABC 1 end} } Abc -test string-15.9 {string tolower} { - string tolower ABC 0 end-1 +test string-15.9.$noComp {string tolower} { + run {string tolower ABC 0 end-1} } abC -test string-15.10 {string tolower, unicode} { - string tolower ABCabc\xc7\xe7 +test string-15.10.$noComp {string tolower, unicode} { + run {string tolower ABCabc\xc7\xe7} } "abcabc\xe7\xe7" -test string-15.11 {string tolower, compiled} { - lindex [string tolower [list A B [list C]]] 1 +test string-15.11.$noComp {string tolower, compiled} { + lindex [run {string tolower [list A B [list C]]}] 1 } b -test string-16.1 {string toupper} { - list [catch {string toupper} msg] $msg +test string-16.1.$noComp {string toupper} { + list [catch {run {string toupper}} msg] $msg } {1 {wrong # args: should be "string toupper string ?first? ?last?"}} -test string-16.2 {string toupper} { - list [catch {string toupper a b} msg] $msg +test string-16.2.$noComp {string toupper} { + list [catch {run {string toupper a b}} msg] $msg } {1 {bad index "b": must be integer?[+-]integer? or end?[+-]integer?}} -test string-16.3 {string toupper} { - list [catch {string toupper a 1 end oops} msg] $msg +test string-16.3.$noComp {string toupper} { + list [catch {run {string toupper a 1 end oops}} msg] $msg } {1 {wrong # args: should be "string toupper string ?first? ?last?"}} -test string-16.4 {string toupper} { - string toupper abCDEf +test string-16.4.$noComp {string toupper} { + run {string toupper abCDEf} } {ABCDEF} -test string-16.5 {string toupper} { - string toupper "abc xYz" +test string-16.5.$noComp {string toupper} { + run {string toupper "abc xYz"} } {ABC XYZ} -test string-16.6 {string toupper} { - string toupper {123#$&*()} +test string-16.6.$noComp {string toupper} { + run {string toupper {123#$&*()}} } {123#$&*()} -test string-16.7 {string toupper} { - string toupper abc 1 +test string-16.7.$noComp {string toupper} { + run {string toupper abc 1} } aBc -test string-16.8 {string toupper} { - string toupper abc 1 end +test string-16.8.$noComp {string toupper} { + run {string toupper abc 1 end} } aBC -test string-16.9 {string toupper} { - string toupper abc 0 end-1 +test string-16.9.$noComp {string toupper} { + run {string toupper abc 0 end-1} } ABc -test string-16.10 {string toupper, unicode} { - string toupper ABCabc\xc7\xe7 +test string-16.10.$noComp {string toupper, unicode} { + run {string toupper ABCabc\xc7\xe7} } "ABCABC\xc7\xc7" -test string-16.11 {string toupper, compiled} { - lindex [string toupper [list a b [list c]]] 1 +test string-16.11.$noComp {string toupper, compiled} { + lindex [run {string toupper [list a b [list c]]}] 1 } B -test string-17.1 {string totitle} { - list [catch {string totitle} msg] $msg +test string-17.1.$noComp {string totitle} { + list [catch {run {string totitle}} msg] $msg } {1 {wrong # args: should be "string totitle string ?first? ?last?"}} -test string-17.2 {string totitle} { - list [catch {string totitle a b} msg] $msg +test string-17.2.$noComp {string totitle} { + list [catch {run {string totitle a b}} msg] $msg } {1 {bad index "b": must be integer?[+-]integer? or end?[+-]integer?}} -test string-17.3 {string totitle} { - string totitle abCDEf +test string-17.3.$noComp {string totitle} { + run {string totitle abCDEf} } {Abcdef} -test string-17.4 {string totitle} { - string totitle "abc xYz" +test string-17.4.$noComp {string totitle} { + run {string totitle "abc xYz"} } {Abc xyz} -test string-17.5 {string totitle} { - string totitle {123#$&*()} +test string-17.5.$noComp {string totitle} { + run {string totitle {123#$&*()}} } {123#$&*()} -test string-17.6 {string totitle, unicode} { - string totitle ABCabc\xc7\xe7 +test string-17.6.$noComp {string totitle, unicode} { + run {string totitle ABCabc\xc7\xe7} } "Abcabc\xe7\xe7" -test string-17.7 {string totitle, unicode} { - string totitle \u01f3BCabc\xc7\xe7 +test string-17.7.$noComp {string totitle, unicode} { + run {string totitle \u01f3BCabc\xc7\xe7} } "\u01f2bcabc\xe7\xe7" -test string-17.8 {string totitle, compiled} { - lindex [string totitle [list aa bb [list cc]]] 0 +test string-17.8.$noComp {string totitle, compiled} { + lindex [run {string totitle [list aa bb [list cc]]}] 0 } Aa -test string-18.1 {string trim} { - list [catch {string trim} msg] $msg +test string-18.1.$noComp {string trim} { + list [catch {run {string trim}} msg] $msg } {1 {wrong # args: should be "string trim string ?chars?"}} -test string-18.2 {string trim} { - list [catch {string trim a b c} msg] $msg +test string-18.2.$noComp {string trim} { + list [catch {run {string trim a b c}} msg] $msg } {1 {wrong # args: should be "string trim string ?chars?"}} -test string-18.3 {string trim} { - string trim " XYZ " +test string-18.3.$noComp {string trim} { + run {string trim " XYZ "} } {XYZ} -test string-18.4 {string trim} { - string trim "\t\nXYZ\t\n\r\n" +test string-18.4.$noComp {string trim} { + run {string trim "\t\nXYZ\t\n\r\n"} } {XYZ} -test string-18.5 {string trim} { - string trim " A XYZ A " +test string-18.5.$noComp {string trim} { + run {string trim " A XYZ A "} } {A XYZ A} -test string-18.6 {string trim} { - string trim "XXYYZZABC XXYYZZ" ZYX +test string-18.6.$noComp {string trim} { + run {string trim "XXYYZZABC XXYYZZ" ZYX} } {ABC } -test string-18.7 {string trim} { - string trim " \t\r " +test string-18.7.$noComp {string trim} { + run {string trim " \t\r "} } {} -test string-18.8 {string trim} { - string trim {abcdefg} {} +test string-18.8.$noComp {string trim} { + run {string trim {abcdefg} {}} } {abcdefg} -test string-18.9 {string trim} { - string trim {} +test string-18.9.$noComp {string trim} { + run {string trim {}} } {} -test string-18.10 {string trim} { - string trim ABC DEF +test string-18.10.$noComp {string trim} { + run {string trim ABC DEF} } {ABC} -test string-18.11 {string trim, unicode} { - string trim "\xe7\xe8 AB\xe7C \xe8\xe7" \xe7\xe8 +test string-18.11.$noComp {string trim, unicode} { + run {string trim "\xe7\xe8 AB\xe7C \xe8\xe7" \xe7\xe8} } " AB\xe7C " -test string-18.12 {string trim, unicode default} { - string trim \ufeff\x00\u0085\u00a0\u1680\u180eABC\u1361\u2000\u2001\u2002\u2003\u2004\u2005\u2006\u2007\u2008\u2009\u200a\u200b\u2028\u2029\u202f\u205f\u3000 +test string-18.12.$noComp {string trim, unicode default} { + run {string trim \ufeff\x00\u0085\u00a0\u1680\u180eABC\u1361\u2000\u2001\u2002\u2003\u2004\u2005\u2006\u2007\u2008\u2009\u200a\u200b\u2028\u2029\u202f\u205f\u3000} } ABC\u1361 -test string-19.1 {string trimleft} { - list [catch {string trimleft} msg] $msg +test string-19.1.$noComp {string trimleft} { + list [catch {run {string trimleft}} msg] $msg } {1 {wrong # args: should be "string trimleft string ?chars?"}} -test string-19.2 {string trimleft} { - string trimleft " XYZ " +test string-19.2.$noComp {string trimleft} { + run {string trimleft " XYZ "} } {XYZ } -test string-19.3 {string trimleft, unicode default} { - string trimleft \ufeff\u0085\u00a0\x00\u1680\u180e\u2000\u2001\u2002\u2003\u2004\u2005\u2006\u2007\u2008\u2009\u200a\u200b\u2028\u2029\u202f\u205f\u3000\u1361ABC +test string-19.3.$noComp {string trimleft, unicode default} { + run {string trimleft \ufeff\u0085\u00a0\x00\u1680\u180e\u2000\u2001\u2002\u2003\u2004\u2005\u2006\u2007\u2008\u2009\u200a\u200b\u2028\u2029\u202f\u205f\u3000\u1361ABC} } \u1361ABC -test string-20.1 {string trimright errors} { - list [catch {string trimright} msg] $msg +test string-20.1.$noComp {string trimright errors} { + list [catch {run {string trimright}} msg] $msg } {1 {wrong # args: should be "string trimright string ?chars?"}} -test string-20.2 {string trimright errors} { - list [catch {string trimg a} msg] $msg +test string-20.2.$noComp {string trimright errors} { + list [catch {run {string trimg a}} msg] $msg } {1 {unknown or ambiguous subcommand "trimg": must be bytelength, cat, compare, equal, first, index, is, last, length, map, match, range, repeat, replace, reverse, tolower, totitle, toupper, trim, trimleft, trimright, wordend, or wordstart}} -test string-20.3 {string trimright} { - string trimright " XYZ " +test string-20.3.$noComp {string trimright} { + run {string trimright " XYZ "} } { XYZ} -test string-20.4 {string trimright} { - string trimright " " +test string-20.4.$noComp {string trimright} { + run {string trimright " "} } {} -test string-20.5 {string trimright} { - string trimright "" +test string-20.5.$noComp {string trimright} { + run {string trimright ""} } {} -test string-20.6 {string trimright, unicode default} { - string trimright ABC\u1361\u0085\x00\u00a0\u1680\u180e\u2000\u2001\u2002\u2003\u2004\u2005\u2006\u2007\u2008\u2009\u200a\u200b\u2028\u2029\u202f\u205f\u3000 +test string-20.6.$noComp {string trimright, unicode default} { + run {string trimright ABC\u1361\u0085\x00\u00a0\u1680\u180e\u2000\u2001\u2002\u2003\u2004\u2005\u2006\u2007\u2008\u2009\u200a\u200b\u2028\u2029\u202f\u205f\u3000} } ABC\u1361 -test string-21.1 {string wordend} { - list [catch {string wordend a} msg] $msg +test string-21.1.$noComp {string wordend} { + list [catch {run {string wordend a}} msg] $msg } {1 {wrong # args: should be "string wordend string index"}} -test string-21.2 {string wordend} { - list [catch {string wordend a b c} msg] $msg +test string-21.2.$noComp {string wordend} { + list [catch {run {string wordend a b c}} msg] $msg } {1 {wrong # args: should be "string wordend string index"}} -test string-21.3 {string wordend} { - list [catch {string wordend a gorp} msg] $msg +test string-21.3.$noComp {string wordend} { + list [catch {run {string wordend a gorp}} msg] $msg } {1 {bad index "gorp": must be integer?[+-]integer? or end?[+-]integer?}} -test string-21.4 {string wordend} { - string wordend abc. -1 +test string-21.4.$noComp {string wordend} { + run {string wordend abc. -1} } 3 -test string-21.5 {string wordend} { - string wordend abc. 100 +test string-21.5.$noComp {string wordend} { + run {string wordend abc. 100} } 4 -test string-21.6 {string wordend} { - string wordend "word_one two three" 2 +test string-21.6.$noComp {string wordend} { + run {string wordend "word_one two three" 2} } 8 -test string-21.7 {string wordend} { - string wordend "one .&# three" 5 +test string-21.7.$noComp {string wordend} { + run {string wordend "one .&# three" 5} } 6 -test string-21.8 {string wordend} { - string worde "x.y" 0 +test string-21.8.$noComp {string wordend} { + run {string worde "x.y" 0} } 1 -test string-21.9 {string wordend} { - string worde "x.y" end-1 +test string-21.9.$noComp {string wordend} { + run {string worde "x.y" end-1} } 2 -test string-21.10 {string wordend, unicode} { - string wordend "xyz\u00c7de fg" 0 +test string-21.10.$noComp {string wordend, unicode} { + run {string wordend "xyz\u00c7de fg" 0} } 6 -test string-21.11 {string wordend, unicode} { - string wordend "xyz\uc700de fg" 0 +test string-21.11.$noComp {string wordend, unicode} { + run {string wordend "xyz\uc700de fg" 0} } 6 -test string-21.12 {string wordend, unicode} { - string wordend "xyz\u203fde fg" 0 +test string-21.12.$noComp {string wordend, unicode} { + run {string wordend "xyz\u203fde fg" 0} } 6 -test string-21.13 {string wordend, unicode} { - string wordend "xyz\u2045de fg" 0 +test string-21.13.$noComp {string wordend, unicode} { + run {string wordend "xyz\u2045de fg" 0} } 3 -test string-21.14 {string wordend, unicode} { - string wordend "\uc700\uc700 abc" 8 +test string-21.14.$noComp {string wordend, unicode} { + run {string wordend "\uc700\uc700 abc" 8} } 6 -test string-22.1 {string wordstart} { - list [catch {string word a} msg] $msg +test string-22.1.$noComp {string wordstart} { + list [catch {run {string word a}} msg] $msg } {1 {unknown or ambiguous subcommand "word": must be bytelength, cat, compare, equal, first, index, is, last, length, map, match, range, repeat, replace, reverse, tolower, totitle, toupper, trim, trimleft, trimright, wordend, or wordstart}} -test string-22.2 {string wordstart} { - list [catch {string wordstart a} msg] $msg +test string-22.2.$noComp {string wordstart} { + list [catch {run {string wordstart a}} msg] $msg } {1 {wrong # args: should be "string wordstart string index"}} -test string-22.3 {string wordstart} { - list [catch {string wordstart a b c} msg] $msg +test string-22.3.$noComp {string wordstart} { + list [catch {run {string wordstart a b c}} msg] $msg } {1 {wrong # args: should be "string wordstart string index"}} -test string-22.4 {string wordstart} { - list [catch {string wordstart a gorp} msg] $msg +test string-22.4.$noComp {string wordstart} { + list [catch {run {string wordstart a gorp}} msg] $msg } {1 {bad index "gorp": must be integer?[+-]integer? or end?[+-]integer?}} -test string-22.5 {string wordstart} { - string wordstart "one two three_words" 400 +test string-22.5.$noComp {string wordstart} { + run {string wordstart "one two three_words" 400} } 8 -test string-22.6 {string wordstart} { - string wordstart "one two three_words" 2 +test string-22.6.$noComp {string wordstart} { + run {string wordstart "one two three_words" 2} } 0 -test string-22.7 {string wordstart} { - string wordstart "one two three_words" -2 +test string-22.7.$noComp {string wordstart} { + run {string wordstart "one two three_words" -2} } 0 -test string-22.8 {string wordstart} { - string wordstart "one .*&^ three" 6 +test string-22.8.$noComp {string wordstart} { + run {string wordstart "one .*&^ three" 6} } 6 -test string-22.9 {string wordstart} { - string wordstart "one two three" 4 +test string-22.9.$noComp {string wordstart} { + run {string wordstart "one two three" 4} } 4 -test string-22.10 {string wordstart} { - string wordstart "one two three" end-5 +test string-22.10.$noComp {string wordstart} { + run {string wordstart "one two three" end-5} } 7 -test string-22.11 {string wordstart, unicode} { - string wordstart "one tw\u00c7o three" 7 +test string-22.11.$noComp {string wordstart, unicode} { + run {string wordstart "one tw\u00c7o three" 7} } 4 -test string-22.12 {string wordstart, unicode} { - string wordstart "ab\uc700\uc700 cdef ghi" 12 +test string-22.12.$noComp {string wordstart, unicode} { + run {string wordstart "ab\uc700\uc700 cdef ghi" 12} } 10 -test string-22.13 {string wordstart, unicode} { - string wordstart "\uc700\uc700 abc" 8 +test string-22.13.$noComp {string wordstart, unicode} { + run {string wordstart "\uc700\uc700 abc" 8} } 3 -test string-23.0 {string is boolean, Bug 1187123} testindexobj { +test string-23.0.$noComp {string is boolean, Bug 1187123} testindexobj { set x 5 catch {testindexobj $x foo bar soom} - string is boolean $x + run {string is boolean $x} } 0 -test string-23.1 {string is command with empty string} { +test string-23.1.$noComp {string is command with empty string} { set s "" list \ - [string is alnum $s] \ - [string is alpha $s] \ - [string is ascii $s] \ - [string is control $s] \ - [string is boolean $s] \ - [string is digit $s] \ - [string is double $s] \ - [string is false $s] \ - [string is graph $s] \ - [string is integer $s] \ - [string is lower $s] \ - [string is print $s] \ - [string is punct $s] \ - [string is space $s] \ - [string is true $s] \ - [string is upper $s] \ - [string is wordchar $s] \ - [string is xdigit $s] \ + [run {string is alnum $s}] \ + [run {string is alpha $s}] \ + [run {string is ascii $s}] \ + [run {string is control $s}] \ + [run {string is boolean $s}] \ + [run {string is digit $s}] \ + [run {string is double $s}] \ + [run {string is false $s}] \ + [run {string is graph $s}] \ + [run {string is integer $s}] \ + [run {string is lower $s}] \ + [run {string is print $s}] \ + [run {string is punct $s}] \ + [run {string is space $s}] \ + [run {string is true $s}] \ + [run {string is upper $s}] \ + [run {string is wordchar $s}] \ + [run {string is xdigit $s}] \ } {1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1} -test string-23.2 {string is command with empty string} { +test string-23.2.$noComp {string is command with empty string} { set s "" list \ - [string is alnum -strict $s] \ - [string is alpha -strict $s] \ - [string is ascii -strict $s] \ - [string is control -strict $s] \ - [string is boolean -strict $s] \ - [string is digit -strict $s] \ - [string is double -strict $s] \ - [string is false -strict $s] \ - [string is graph -strict $s] \ - [string is integer -strict $s] \ - [string is lower -strict $s] \ - [string is print -strict $s] \ - [string is punct -strict $s] \ - [string is space -strict $s] \ - [string is true -strict $s] \ - [string is upper -strict $s] \ - [string is wordchar -strict $s] \ - [string is xdigit -strict $s] \ + [run {string is alnum -strict $s}] \ + [run {string is alpha -strict $s}] \ + [run {string is ascii -strict $s}] \ + [run {string is control -strict $s}] \ + [run {string is boolean -strict $s}] \ + [run {string is digit -strict $s}] \ + [run {string is double -strict $s}] \ + [run {string is false -strict $s}] \ + [run {string is graph -strict $s}] \ + [run {string is integer -strict $s}] \ + [run {string is lower -strict $s}] \ + [run {string is print -strict $s}] \ + [run {string is punct -strict $s}] \ + [run {string is space -strict $s}] \ + [run {string is true -strict $s}] \ + [run {string is upper -strict $s}] \ + [run {string is wordchar -strict $s}] \ + [run {string is xdigit -strict $s}] \ } {0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0} -test string-24.1 {string reverse command} -body { - string reverse +test string-24.1.$noComp {string reverse command} -body { + run {string reverse} } -returnCodes error -result "wrong # args: should be \"string reverse string\"" -test string-24.2 {string reverse command} -body { - string reverse a b +test string-24.2.$noComp {string reverse command} -body { + run {string reverse a b} } -returnCodes error -result "wrong # args: should be \"string reverse string\"" -test string-24.3 {string reverse command - shared string} { +test string-24.3.$noComp {string reverse command - shared string} { set x abcde - string reverse $x + run {string reverse $x} } edcba -test string-24.4 {string reverse command - unshared string} { +test string-24.4.$noComp {string reverse command - unshared string} { set x abc set y de - string reverse $x$y + run {string reverse $x$y} } edcba -test string-24.5 {string reverse command - shared unicode string} { +test string-24.5.$noComp {string reverse command - shared unicode string} { set x abcde\ud0ad - string reverse $x + run {string reverse $x} } \ud0adedcba -test string-24.6 {string reverse command - unshared string} { +test string-24.6.$noComp {string reverse command - unshared string} { set x abc set y de\ud0ad - string reverse $x$y + run {string reverse $x$y} } \ud0adedcba -test string-24.7 {string reverse command - simple case} { - string reverse a +test string-24.7.$noComp {string reverse command - simple case} { + run {string reverse a} } a -test string-24.8 {string reverse command - simple case} { - string reverse \ud0ad +test string-24.8.$noComp {string reverse command - simple case} { + run {string reverse \ud0ad} } \ud0ad -test string-24.9 {string reverse command - simple case} { - string reverse {} +test string-24.9.$noComp {string reverse command - simple case} { + run {string reverse {}} } {} -test string-24.10 {string reverse command - corner case} { +test string-24.10.$noComp {string reverse command - corner case} { set x \ubeef\ud0ad - string reverse $x + run {string reverse $x} } \ud0ad\ubeef -test string-24.11 {string reverse command - corner case} { +test string-24.11.$noComp {string reverse command - corner case} { set x \ubeef set y \ud0ad - string reverse $x$y + run {string reverse $x$y} } \ud0ad\ubeef -test string-24.12 {string reverse command - corner case} { +test string-24.12.$noComp {string reverse command - corner case} { set x \ubeef set y \ud0ad - string is ascii [string reverse $x$y] + run {string is ascii [run {string reverse $x$y}]} } 0 -test string-24.13 {string reverse command - pure Unicode string} { - string reverse [string range \ubeef\ud0ad\ubeef\ud0ad\ubeef\ud0ad 1 5] +test string-24.13.$noComp {string reverse command - pure Unicode string} { + run {string reverse [run {string range \ubeef\ud0ad\ubeef\ud0ad\ubeef\ud0ad 1 5}]} } \ud0ad\ubeef\ud0ad\ubeef\ud0ad -test string-24.14 {string reverse command - pure bytearray} { - binary scan [string reverse [binary format H* 010203]] H* x +test string-24.14.$noComp {string reverse command - pure bytearray} { + binary scan [run {string reverse [binary format H* 010203]}] H* x set x } 030201 -test string-24.15 {string reverse command - pure bytearray} { - binary scan [tcl::string::reverse [binary format H* 010203]] H* x +test string-24.15.$noComp {string reverse command - pure bytearray} { + binary scan [run {tcl::string::reverse [binary format H* 010203]}] H* x set x } 030201 -test string-25.1 {string is list} { - string is list {a b c} +test string-25.1.$noComp {string is list} { + run {string is list {a b c}} } 1 -test string-25.2 {string is list} { - string is list "a \{b c" +test string-25.2.$noComp {string is list} { + run {string is list "a \{b c"} } 0 -test string-25.3 {string is list} { - string is list {a {b c}d e} +test string-25.3.$noComp {string is list} { + run {string is list {a {b c}d e}} } 0 -test string-25.4 {string is list} { - string is list {} +test string-25.4.$noComp {string is list} { + run {string is list {}} } 1 -test string-25.5 {string is list} { - string is list -strict {a b c} +test string-25.5.$noComp {string is list} { + run {string is list -strict {a b c}} } 1 -test string-25.6 {string is list} { - string is list -strict "a \{b c" +test string-25.6.$noComp {string is list} { + run {string is list -strict "a \{b c"} } 0 -test string-25.7 {string is list} { - string is list -strict {a {b c}d e} +test string-25.7.$noComp {string is list} { + run {string is list -strict {a {b c}d e}} } 0 -test string-25.8 {string is list} { - string is list -strict {} +test string-25.8.$noComp {string is list} { + run {string is list -strict {}} } 1 -test string-25.9 {string is list} { +test string-25.9.$noComp {string is list} { set x {} - list [string is list -failindex x {a b c}] $x + list [run {string is list -failindex x {a b c}}] $x } {1 {}} -test string-25.10 {string is list} { +test string-25.10.$noComp {string is list} { set x {} - list [string is list -failindex x "a \{b c"] $x + list [run {string is list -failindex x "a \{b c"}] $x } {0 2} -test string-25.11 {string is list} { +test string-25.11.$noComp {string is list} { set x {} - list [string is list -failindex x {a b {b c}d e}] $x + list [run {string is list -failindex x {a b {b c}d e}}] $x } {0 4} -test string-25.12 {string is list} { +test string-25.12.$noComp {string is list} { set x {} - list [string is list -failindex x {}] $x + list [run {string is list -failindex x {}}] $x } {1 {}} -test string-25.13 {string is list} { +test string-25.13.$noComp {string is list} { set x {} - list [string is list -failindex x { {b c}d e}] $x + list [run {string is list -failindex x { {b c}d e}}] $x } {0 2} -test string-25.14 {string is list} { +test string-25.14.$noComp {string is list} { set x {} - list [string is list -failindex x "\uabcd {b c}d e"] $x + list [run {string is list -failindex x "\uabcd {b c}d e"}] $x } {0 2} -test string-26.1 {tcl::prefix, too few args} -body { +test string-26.1.$noComp {tcl::prefix, too few args} -body { tcl::prefix match a } -returnCodes 1 -result {wrong # args: should be "tcl::prefix match ?options? table string"} -test string-26.2 {tcl::prefix, bad args} -body { +test string-26.2.$noComp {tcl::prefix, bad args} -body { tcl::prefix match a b c } -returnCodes 1 -result {bad option "a": must be -error, -exact, or -message} -test string-26.2.1 {tcl::prefix, empty table} -body { +test string-26.2.1.$noComp {tcl::prefix, empty table} -body { tcl::prefix match {} foo } -returnCodes 1 -result {bad option "foo": no valid options} -test string-26.3 {tcl::prefix, bad args} -body { +test string-26.3.$noComp {tcl::prefix, bad args} -body { tcl::prefix match -error "{}x" -exact str1 str2 } -returnCodes 1 -result {list element in braces followed by "x" instead of space} -test string-26.3.1 {tcl::prefix, bad args} -body { +test string-26.3.1.$noComp {tcl::prefix, bad args} -body { tcl::prefix match -error "x" -exact str1 str2 } -returnCodes 1 -result {error options must have an even number of elements} -test string-26.3.2 {tcl::prefix, bad args} -body { +test string-26.3.2.$noComp {tcl::prefix, bad args} -body { tcl::prefix match -error str1 str2 } -returnCodes 1 -result {missing value for -error} -test string-26.4 {tcl::prefix, bad args} -body { +test string-26.4.$noComp {tcl::prefix, bad args} -body { tcl::prefix match -message str1 str2 } -returnCodes 1 -result {missing value for -message} -test string-26.5 {tcl::prefix} { +test string-26.5.$noComp {tcl::prefix} { tcl::prefix match {apa bepa cepa depa} cepa } cepa -test string-26.6 {tcl::prefix} { +test string-26.6.$noComp {tcl::prefix} { tcl::prefix match {apa bepa cepa depa} be } bepa -test string-26.7 {tcl::prefix} -body { +test string-26.7.$noComp {tcl::prefix} -body { tcl::prefix match -exact {apa bepa cepa depa} be } -returnCodes 1 -result {bad option "be": must be apa, bepa, cepa, or depa} -test string-26.8 {tcl::prefix} -body { +test string-26.8.$noComp {tcl::prefix} -body { tcl::prefix match -message wombat {apa bepa bear depa} be } -returnCodes 1 -result {ambiguous wombat "be": must be apa, bepa, bear, or depa} -test string-26.9 {tcl::prefix} -body { +test string-26.9.$noComp {tcl::prefix} -body { tcl::prefix match -error {} {apa bepa bear depa} be } -returnCodes 0 -result {} -test string-26.10 {tcl::prefix} -body { +test string-26.10.$noComp {tcl::prefix} -body { tcl::prefix match -error {-level 1} {apa bepa bear depa} be } -returnCodes 2 -result {ambiguous option "be": must be apa, bepa, bear, or depa} -test string-26.10.1 {tcl::prefix} -setup { +test string-26.10.1.$noComp {tcl::prefix} -setup { proc _testprefix {args} { array set opts {-a x -b y -c y} foreach {opt val} $args { @@ -1880,7 +2107,7 @@ proc MemStress {args} { return $res } -test string-26.11 {tcl::prefix: testing for leaks} -body { +test string-26.11.$noComp {tcl::prefix: testing for leaks} -body { # This test is made to stress object reference management MemStress { set table {hejj miff gurk} @@ -1901,7 +2128,7 @@ test string-26.11 {tcl::prefix: testing for leaks} -body { } } -constraints memory -result {0 0 0} -test string-26.12 {tcl::prefix: testing for leaks} -body { +test string-26.12.$noComp {tcl::prefix: testing for leaks} -body { # This is a memory leak test in a form that might actually happen # in real code. The shared literal "miff" causes a connection # between the item and the table. @@ -1919,7 +2146,7 @@ test string-26.12 {tcl::prefix: testing for leaks} -body { } } -constraints memory -result 0 -test string-26.13 {tcl::prefix: testing for leaks} -body { +test string-26.13.$noComp {tcl::prefix: testing for leaks} -body { # This test is made to stress object reference management MemStress { set table [list hejj miff] @@ -1932,147 +2159,155 @@ test string-26.13 {tcl::prefix: testing for leaks} -body { } } -constraints memory -result {0} -test string-27.1 {tcl::prefix all, too few args} -body { +test string-27.1.$noComp {tcl::prefix all, too few args} -body { tcl::prefix all a } -returnCodes 1 -result {wrong # args: should be "tcl::prefix all table string"} -test string-27.2 {tcl::prefix all, bad args} -body { +test string-27.2.$noComp {tcl::prefix all, bad args} -body { tcl::prefix all a b c } -returnCodes 1 -result {wrong # args: should be "tcl::prefix all table string"} -test string-27.3 {tcl::prefix all, bad args} -body { +test string-27.3.$noComp {tcl::prefix all, bad args} -body { tcl::prefix all "{}x" str2 } -returnCodes 1 -result {list element in braces followed by "x" instead of space} -test string-27.4 {tcl::prefix all} { +test string-27.4.$noComp {tcl::prefix all} { tcl::prefix all {apa bepa cepa depa} c } cepa -test string-27.5 {tcl::prefix all} { +test string-27.5.$noComp {tcl::prefix all} { tcl::prefix all {apa bepa cepa depa} cepa } cepa -test string-27.6 {tcl::prefix all} { +test string-27.6.$noComp {tcl::prefix all} { tcl::prefix all {apa bepa cepa depa} cepax } {} -test string-27.7 {tcl::prefix all} { +test string-27.7.$noComp {tcl::prefix all} { tcl::prefix all {apa aska appa} a } {apa aska appa} -test string-27.8 {tcl::prefix all} { +test string-27.8.$noComp {tcl::prefix all} { tcl::prefix all {apa aska appa} ap } {apa appa} -test string-27.9 {tcl::prefix all} { +test string-27.9.$noComp {tcl::prefix all} { tcl::prefix all {apa aska appa} p } {} -test string-27.10 {tcl::prefix all} { +test string-27.10.$noComp {tcl::prefix all} { tcl::prefix all {apa aska appa} {} } {apa aska appa} -test string-28.1 {tcl::prefix longest, too few args} -body { +test string-28.1.$noComp {tcl::prefix longest, too few args} -body { tcl::prefix longest a } -returnCodes 1 -result {wrong # args: should be "tcl::prefix longest table string"} -test string-28.2 {tcl::prefix longest, bad args} -body { +test string-28.2.$noComp {tcl::prefix longest, bad args} -body { tcl::prefix longest a b c } -returnCodes 1 -result {wrong # args: should be "tcl::prefix longest table string"} -test string-28.3 {tcl::prefix longest, bad args} -body { +test string-28.3.$noComp {tcl::prefix longest, bad args} -body { tcl::prefix longest "{}x" str2 } -returnCodes 1 -result {list element in braces followed by "x" instead of space} -test string-28.4 {tcl::prefix longest} { +test string-28.4.$noComp {tcl::prefix longest} { tcl::prefix longest {apa bepa cepa depa} c } cepa -test string-28.5 {tcl::prefix longest} { +test string-28.5.$noComp {tcl::prefix longest} { tcl::prefix longest {apa bepa cepa depa} cepa } cepa -test string-28.6 {tcl::prefix longest} { +test string-28.6.$noComp {tcl::prefix longest} { tcl::prefix longest {apa bepa cepa depa} cepax } {} -test string-28.7 {tcl::prefix longest} { +test string-28.7.$noComp {tcl::prefix longest} { tcl::prefix longest {apa aska appa} a } a -test string-28.8 {tcl::prefix longest} { +test string-28.8.$noComp {tcl::prefix longest} { tcl::prefix longest {apa aska appa} ap } ap -test string-28.9 {tcl::prefix longest} { +test string-28.9.$noComp {tcl::prefix longest} { tcl::prefix longest {apa bska appa} a } ap -test string-28.10 {tcl::prefix longest} { +test string-28.10.$noComp {tcl::prefix longest} { tcl::prefix longest {apa bska appa} {} } {} -test string-28.11 {tcl::prefix longest} { +test string-28.11.$noComp {tcl::prefix longest} { tcl::prefix longest {{} bska appa} {} } {} -test string-28.12 {tcl::prefix longest} { +test string-28.12.$noComp {tcl::prefix longest} { tcl::prefix longest {apa {} appa} {} } {} -test string-28.13 {tcl::prefix longest} { +test string-28.13.$noComp {tcl::prefix longest} { # Test UTF8 handling tcl::prefix longest {ax\x90 bep ax\x91} a } ax -test string-29.1 {string cat, no arg} { - string cat +test string-29.1.$noComp {string cat, no arg} { + run {string cat} } "" -test string-29.2 {string cat, single arg} { +test string-29.2.$noComp {string cat, single arg} { set x FOO - string compare $x [string cat $x] + run {string compare $x [run {string cat $x}]} } 0 -test string-29.3 {string cat, two args} { +test string-29.3.$noComp {string cat, two args} { set x FOO - string compare $x$x [string cat $x $x] + run {string compare $x$x [run {string cat $x $x}]} } 0 -test string-29.4 {string cat, many args} { +test string-29.4.$noComp {string cat, many args} { set x FOO set n 260 - set xx [string repeat $x $n] - set vv [string repeat {$x} $n] - set vvs [string repeat {$x } $n] - set r1 [string compare $xx [subst $vv]] - set r2 [string compare $xx [eval "string cat $vvs"]] + set xx [run {string repeat $x $n}] + set vv [run {string repeat {$x} $n}] + set vvs [run {string repeat {$x } $n}] + set r1 [run {string compare $xx [subst $vv]}] + set r2 [run {string compare $xx [eval "run {string cat $vvs}"]}] list $r1 $r2 } {0 0} -test string-29.5 {string cat, efficiency} -body { - tcl::unsupported::representation [string cat [list x] [list]] +if {$noComp} { +test string-29.5.$noComp {string cat, efficiency} -body { + tcl::unsupported::representation [run {string cat [list x] [list]}] } -match glob -result {*no string representation} -test string-29.6 {string cat, efficiency} -body { - tcl::unsupported::representation [string cat [list] [list x]] +test string-29.6.$noComp {string cat, efficiency} -body { + tcl::unsupported::representation [run {string cat [list] [list x]}] } -match glob -result {*no string representation} -test string-29.7 {string cat, efficiency} -body { - tcl::unsupported::representation [string cat [list x] [list] [list]] +test string-29.7.$noComp {string cat, efficiency} -body { + tcl::unsupported::representation [run {string cat [list x] [list] [list]}] } -match glob -result {*no string representation} -test string-29.8 {string cat, efficiency} -body { - tcl::unsupported::representation [string cat [list] [list x] [list]] +test string-29.8.$noComp {string cat, efficiency} -body { + tcl::unsupported::representation [run {string cat [list] [list x] [list]}] } -match glob -result {*no string representation} -test string-29.9 {string cat, efficiency} -body { - tcl::unsupported::representation [string cat [list] [list] [list x]] +test string-29.9.$noComp {string cat, efficiency} -body { + tcl::unsupported::representation [run {string cat [list] [list] [list x]}] } -match glob -result {*no string representation} -test string-29.10 {string cat, efficiency} -body { - tcl::unsupported::representation [string cat [list x] [list x]] +test string-29.10.$noComp {string cat, efficiency} -body { + tcl::unsupported::representation [run {string cat [list x] [list x]}] } -match glob -result {*, string representation "xx"} -test string-29.11 {string cat, efficiency} -body { +test string-29.11.$noComp {string cat, efficiency} -body { tcl::unsupported::representation \ - [string cat [list x] [encoding convertto utf-8 {}]] + [run {string cat [list x] [encoding convertto utf-8 {}]}] } -match glob -result {*no string representation} -test string-29.12 {string cat, efficiency} -body { +test string-29.12.$noComp {string cat, efficiency} -body { tcl::unsupported::representation \ - [string cat [encoding convertto utf-8 {}] [list x]] + [run {string cat [encoding convertto utf-8 {}] [list x]}] } -match glob -result {*, string representation "x"} -test string-29.13 {string cat, efficiency} -body { - tcl::unsupported::representation [string cat \ - [encoding convertto utf-8 {}] [encoding convertto utf-8 {}] [list x]] +test string-29.13.$noComp {string cat, efficiency} -body { + tcl::unsupported::representation [run {string cat \ + [encoding convertto utf-8 {}] [encoding convertto utf-8 {}] [list x]}] } -match glob -result {*, string representation "x"} -test string-29.14 {string cat, efficiency} -setup { +test string-29.14.$noComp {string cat, efficiency} -setup { set e [encoding convertto utf-8 {}] } -cleanup { unset e } -body { - tcl::unsupported::representation [string cat $e $e [list x]] + tcl::unsupported::representation [run {string cat $e $e [list x]}] } -match glob -result {*no string representation} -test string-29.15 {string cat, efficiency} -setup { +test string-29.15.$noComp {string cat, efficiency} -setup { set e [encoding convertto utf-8 {}] set f [encoding convertto utf-8 {}] } -cleanup { unset e f } -body { - tcl::unsupported::representation [string cat $e $f $e $f [list x]] + tcl::unsupported::representation [run {string cat $e $f $e $f [list x]}] } -match glob -result {*no string representation} - +} + +} + # cleanup rename MemStress {} +rename makeByteArray {} +rename makeUnicode {} +rename makeList {} +rename makeShared {} catch {rename foo {}} ::tcltest::cleanupTests return diff --git a/tests/stringComp.test b/tests/stringComp.test deleted file mode 100644 index 2aeb08e..0000000 --- a/tests/stringComp.test +++ /dev/null @@ -1,801 +0,0 @@ -# Commands covered: string -# -# This file contains a collection of tests for one or more of the Tcl -# built-in commands. Sourcing this file into Tcl runs the tests and -# generates output for errors. No output means no errors were found. -# -# This differs from the original string tests in that the tests call -# things in procs, which uses the compiled string code instead of -# the runtime parse string code. The tests of import should match -# their equivalent number in string.test. -# -# Copyright (c) 2001 by ActiveState Corporation. -# Copyright (c) 2001 by Kevin B. Kenny. All rights reserved. -# -# See the file "license.terms" for information on usage and redistribution -# of this file, and for a DISCLAIMER OF ALL WARRANTIES. - -if {[lsearch [namespace children] ::tcltest] == -1} { - package require tcltest - namespace import -force ::tcltest::* -} - -::tcltest::loadTestedCommands -catch [list package require -exact Tcltest [info patchlevel]] - -# Some tests require the testobj command - -testConstraint testobj [expr {[info commands testobj] != {}}] -testConstraint memory [llength [info commands memory]] -if {[testConstraint memory]} { - proc getbytes {} { - set lines [split [memory info] \n] - return [lindex $lines 3 3] - } - proc leaktest {script {iterations 3}} { - set end [getbytes] - for {set i 0} {$i < $iterations} {incr i} { - uplevel 1 $script - set tmp $end - set end [getbytes] - } - return [expr {$end - $tmp}] - } -} - -test stringComp-1.1 {error conditions} { - proc foo {} {string gorp a b} - list [catch {foo} msg] $msg -} {1 {unknown or ambiguous subcommand "gorp": must be bytelength, cat, compare, equal, first, index, is, last, length, map, match, range, repeat, replace, reverse, tolower, totitle, toupper, trim, trimleft, trimright, wordend, or wordstart}} -test stringComp-1.2 {error conditions} { - proc foo {} {string} - list [catch {foo} msg] $msg -} {1 {wrong # args: should be "string subcommand ?arg ...?"}} -test stringComp-1.3 {error condition - undefined method during compile} { - # We don't want this to complain about 'never' because it may never - # be called, or string may get redefined. This must compile OK. - proc foo {str i} { - if {"yes" == "no"} { string never called but complains here } - string index $str $i - } - foo abc 0 -} a - -## Test string compare|equal over equal constraints -## Use result for string compare, and negate it for string equal -## The body will be tested both in and outside a proc -set i 0 -foreach {tname tbody tresult tcode} { - {too few args} { - string compare a - } {wrong # args: should be "string compare ?-nocase? ?-length int? string1 string2"} {error} - {bad args} { - string compare a b c - } {bad option "a": must be -nocase or -length} {error} - {bad args} { - string compare -length -nocase str1 str2 - } {expected integer but got "-nocase"} {error} - {too many args} { - string compare -length 10 -nocase str1 str2 str3 - } {wrong # args: should be "string compare ?-nocase? ?-length int? string1 string2"} {error} - {compare with length unspecified} { - string compare -length 10 10 - } {wrong # args: should be "string compare ?-nocase? ?-length int? string1 string2"} {error} - {basic operation fail} { - string compare abcde abdef - } {-1} {} - {basic operation success} { - string compare abcde abcde - } {0} {} - {with length} { - string compare -length 2 abcde abxyz - } {0} {} - {with special index} { - string compare -length end-3 abcde abxyz - } {expected integer but got "end-3"} {error} - {unicode} { - string compare ab\u7266 ab\u7267 - } {-1} {} - {unicode} {string compare \334 \u00dc} 0 {} - {unicode} {string compare \334 \u00fc} -1 {} - {unicode} {string compare \334\334\334\374\374 \334\334\334\334\334} 1 {} - {high bit} { - # This test will fail if the underlying comparaison - # is using signed chars instead of unsigned chars. - # (like SunOS's default memcmp thus the compat/memcmp.c) - string compare "\x80" "@" - # Nb this tests works also in utf8 space because \x80 is - # translated into a 2 or more bytelength but whose first byte has - # the high bit set. - } {1} {} - {-nocase 1} {string compare -nocase abcde abdef} {-1} {} - {-nocase 2} {string compare -nocase abcde Abdef} {-1} {} - {-nocase 3} {string compare -nocase abcde ABCDE} {0} {} - {-nocase 4} {string compare -nocase abcde abcde} {0} {} - {-nocase unicode} { - string compare -nocase \334 \u00dc - } 0 {} - {-nocase unicode} { - string compare -nocase \334\334\334\374\u00fc \334\334\334\334\334 - } 0 {} - {-nocase with length} { - string compare -length 2 -nocase abcde Abxyz - } {0} {} - {-nocase with length} { - string compare -nocase -length 3 abcde Abxyz - } {-1} {} - {-nocase with length <= 0} { - string compare -nocase -length -1 abcde AbCdEf - } {-1} {} - {-nocase with excessive length} { - string compare -nocase -length 50 AbCdEf abcde - } {1} {} - {-len unicode} { - # These are strings that are 6 BYTELENGTH long, but the length - # shouldn't make a different because there are actually 3 CHARS long - string compare -len 5 \334\334\334 \334\334\374 - } -1 {} - {-nocase with special index} { - string compare -nocase -length end-3 Abcde abxyz - } {expected integer but got "end-3"} error - {null strings} { - string compare "" "" - } 0 {} - {null strings} { - string compare "" foo - } -1 {} - {null strings} { - string compare foo "" - } 1 {} - {-nocase null strings} { - string compare -nocase "" "" - } 0 {} - {-nocase null strings} { - string compare -nocase "" foo - } -1 {} - {-nocase null strings} { - string compare -nocase foo "" - } 1 {} - {with length, unequal strings} { - string compare -length 2 abc abde - } 0 {} - {with length, unequal strings} { - string compare -length 2 ab abde - } 0 {} - {with NUL character vs. other ASCII} { - # Be careful here, since UTF-8 rep comparison with memcmp() of - # these puts chars in the wrong order - string compare \x00 \x01 - } -1 {} - {high bit} { - string compare "a\x80" "a@" - } 1 {} - {high bit} { - string compare "a\x00" "a\x01" - } -1 {} - {high bit} { - string compare "\x00\x00" "\x00\x01" - } -1 {} - {binary equal} { - string compare [binary format a100 0] [binary format a100 0] - } 0 {} - {binary neq} { - string compare [binary format a100a 0 1] [binary format a100a 0 0] - } 1 {} - {binary neq inequal length} { - string compare [binary format a20a 0 1] [binary format a100a 0 0] - } 1 {} -} { - if {$tname eq ""} { continue } - if {$tcode eq ""} { set tcode ok } - test stringComp-2.[incr i] "string compare, $tname" \ - -body [list eval $tbody] \ - -returnCodes $tcode -result $tresult - test stringComp-2.[incr i] "string compare bc, $tname" \ - -body "[list proc foo {} $tbody];foo" \ - -returnCodes $tcode -result $tresult - if {"error" ni $tcode} { - set tresult [expr {!$tresult}] - } else { - set tresult [string map {compare equal} $tresult] - } - set tbody [string map {compare equal} $tbody] - test stringComp-2.[incr i] "string equal, $tname" \ - -body [list eval $tbody] \ - -returnCodes $tcode -result $tresult - test stringComp-2.[incr i] "string equal bc, $tname" \ - -body "[list proc foo {} $tbody];foo" \ - -returnCodes $tcode -result $tresult -} - -# need a few extra tests short abbr cmd -test stringComp-3.1 {string compare, shortest method name} { - proc foo {} {string co abcde ABCDE} - foo -} 1 -test stringComp-3.2 {string equal, shortest method name} { - proc foo {} {string e abcde ABCDE} - foo -} 0 -test stringComp-3.3 {string equal -nocase} { - proc foo {} {string eq -nocase abcde ABCDE} - foo -} 1 - -test stringComp-4.1 {string first, too few args} { - proc foo {} {string first a} - list [catch {foo} msg] $msg -} {1 {wrong # args: should be "string first needleString haystackString ?startIndex?"}} -test stringComp-4.2 {string first, bad args} { - proc foo {} {string first a b c} - list [catch {foo} msg] $msg -} {1 {bad index "c": must be integer?[+-]integer? or end?[+-]integer?}} -test stringComp-4.3 {string first, too many args} { - proc foo {} {string first a b 5 d} - list [catch {foo} msg] $msg -} {1 {wrong # args: should be "string first needleString haystackString ?startIndex?"}} -test stringComp-4.4 {string first} { - proc foo {} {string first bq abcdefgbcefgbqrs} - foo -} 12 -test stringComp-4.5 {string first} { - proc foo {} {string fir bcd abcdefgbcefgbqrs} - foo -} 1 -test stringComp-4.6 {string first} { - proc foo {} {string f b abcdefgbcefgbqrs} - foo -} 1 -test stringComp-4.7 {string first} { - proc foo {} {string first xxx x123xx345xxx789xxx012} - foo -} 9 -test stringComp-4.8 {string first} { - proc foo {} {string first "" x123xx345xxx789xxx012} - foo -} -1 -test stringComp-4.9 {string first, unicode} { - proc foo {} {string first x abc\u7266x} - foo -} 4 -test stringComp-4.10 {string first, unicode} { - proc foo {} {string first \u7266 abc\u7266x} - foo -} 3 -test stringComp-4.11 {string first, start index} { - proc foo {} {string first \u7266 abc\u7266x 3} - foo -} 3 -test stringComp-4.12 {string first, start index} { - proc foo {} {string first \u7266 abc\u7266x 4} - foo -} -1 -test stringComp-4.13 {string first, start index} { - proc foo {} {string first \u7266 abc\u7266x end-2} - foo -} 3 -test stringComp-4.14 {string first, negative start index} { - proc foo {} {string first b abc -1} - foo -} 1 - -test stringComp-5.1 {string index} { - proc foo {} {string index} - list [catch {foo} msg] $msg -} {1 {wrong # args: should be "string index string charIndex"}} -test stringComp-5.2 {string index} { - proc foo {} {string index a b c} - list [catch {foo} msg] $msg -} {1 {wrong # args: should be "string index string charIndex"}} -test stringComp-5.3 {string index} { - proc foo {} {string index abcde 0} - foo -} a -test stringComp-5.4 {string index} { - proc foo {} {string in abcde 4} - foo -} e -test stringComp-5.5 {string index} { - proc foo {} {string index abcde 5} - foo -} {} -test stringComp-5.6 {string index} { - proc foo {} {string index abcde -10} - list [catch {foo} msg] $msg -} {0 {}} -test stringComp-5.7 {string index} { - proc foo {} {string index a xyz} - list [catch {foo} msg] $msg -} {1 {bad index "xyz": must be integer?[+-]integer? or end?[+-]integer?}} -test stringComp-5.8 {string index} { - proc foo {} {string index abc end} - foo -} c -test stringComp-5.9 {string index} { - proc foo {} {string index abc end-1} - foo -} b -test stringComp-5.10 {string index, unicode} { - proc foo {} {string index abc\u7266d 4} - foo -} d -test stringComp-5.11 {string index, unicode} { - proc foo {} {string index abc\u7266d 3} - foo -} \u7266 -test stringComp-5.12 {string index, unicode over char length, under byte length} { - proc foo {} {string index \334\374\334\374 6} - foo -} {} -test stringComp-5.13 {string index, bytearray object} { - proc foo {} {string index [binary format a5 fuz] 0} - foo -} f -test stringComp-5.14 {string index, bytearray object} { - proc foo {} {string index [binary format I* {0x50515253 0x52}] 3} - foo -} S -test stringComp-5.15 {string index, bytearray object} { - proc foo {} { - set b [binary format I* {0x50515253 0x52}] - set i1 [string index $b end-6] - set i2 [string index $b 1] - string compare $i1 $i2 - } - foo -} 0 -test stringComp-5.16 {string index, bytearray object with string obj shimmering} { - proc foo {} { - set str "0123456789\x00 abcdedfghi" - binary scan $str H* dump - string compare [string index $str 10] \x00 - } - foo -} 0 -test stringComp-5.17 {string index, bad integer} -body { - proc foo {} {string index "abc" 0o8} - list [catch {foo} msg] $msg -} -match glob -result {1 {*invalid octal number*}} -test stringComp-5.18 {string index, bad integer} -body { - proc foo {} {string index "abc" end-0o0289} - list [catch {foo} msg] $msg -} -match glob -result {1 {*invalid octal number*}} -test stringComp-5.19 {string index, bytearray object out of bounds} { - proc foo {} {string index [binary format I* {0x50515253 0x52}] -1} - foo -} {} -test stringComp-5.20 {string index, bytearray object out of bounds} { - proc foo {} {string index [binary format I* {0x50515253 0x52}] 20} - foo -} {} - - -proc largest_int {} { - # This will give us what the largest valid int on this machine is, - # so we can test for overflow properly below on >32 bit systems - set int 1 - set exp 7; # assume we get at least 8 bits - while {$int > 0} { set int [expr {1 << [incr exp]}] } - return [expr {$int-1}] -} - -## string is -## not yet bc - -catch {rename largest_int {}} - -## string last -## not yet bc - -## string length -## not yet bc -test stringComp-8.1 {string bytelength} { - proc foo {} {string bytelength} - list [catch {foo} msg] $msg -} {1 {wrong # args: should be "string bytelength string"}} -test stringComp-8.2 {string bytelength} { - proc foo {} {string bytelength a b} - list [catch {foo} msg] $msg -} {1 {wrong # args: should be "string bytelength string"}} -test stringComp-8.3 {string bytelength} { - proc foo {} {string bytelength "\u00c7"} - foo -} 2 -test stringComp-8.4 {string bytelength} { - proc foo {} {string b ""} - foo -} 0 - -## string length -## -test stringComp-9.1 {string length} { - proc foo {} {string length} - list [catch {foo} msg] $msg -} {1 {wrong # args: should be "string length string"}} -test stringComp-9.2 {string length} { - proc foo {} {string length a b} - list [catch {foo} msg] $msg -} {1 {wrong # args: should be "string length string"}} -test stringComp-9.3 {string length} { - proc foo {} {string length "a little string"} - foo -} 15 -test stringComp-9.4 {string length} { - proc foo {} {string le ""} - foo -} 0 -test stringComp-9.5 {string length, unicode} { - proc foo {} {string le "abcd\u7266"} - foo -} 5 -test stringComp-9.6 {string length, bytearray object} { - proc foo {} {string length [binary format a5 foo]} - foo -} 5 -test stringComp-9.7 {string length, bytearray object} { - proc foo {} {string length [binary format I* {0x50515253 0x52}]} - foo -} 8 - -## string map -## not yet bc - -## string match -## -test stringComp-11.1 {string match, too few args} { - proc foo {} {string match a} - list [catch {foo} msg] $msg -} {1 {wrong # args: should be "string match ?-nocase? pattern string"}} -test stringComp-11.2 {string match, too many args} { - proc foo {} {string match a b c d} - list [catch {foo} msg] $msg -} {1 {wrong # args: should be "string match ?-nocase? pattern string"}} -test stringComp-11.3 {string match} { - proc foo {} {string match abc abc} - foo -} 1 -test stringComp-11.4 {string match} { - proc foo {} {string mat abc abd} - foo -} 0 -test stringComp-11.5 {string match} { - proc foo {} {string match ab*c abc} - foo -} 1 -test stringComp-11.6 {string match} { - proc foo {} {string match ab**c abc} - foo -} 1 -test stringComp-11.7 {string match} { - proc foo {} {string match ab* abcdef} - foo -} 1 -test stringComp-11.8 {string match} { - proc foo {} {string match *c abc} - foo -} 1 -test stringComp-11.9 {string match} { - proc foo {} {string match *3*6*9 0123456789} - foo -} 1 -test stringComp-11.10 {string match} { - proc foo {} {string match *3*6*9 01234567890} - foo -} 0 -test stringComp-11.11 {string match} { - proc foo {} {string match a?c abc} - foo -} 1 -test stringComp-11.12 {string match} { - proc foo {} {string match a??c abc} - foo -} 0 -test stringComp-11.13 {string match} { - proc foo {} {string match ?1??4???8? 0123456789} - foo -} 1 -test stringComp-11.14 {string match} { - proc foo {} {string match {[abc]bc} abc} - foo -} 1 -test stringComp-11.15 {string match} { - proc foo {} {string match {a[abc]c} abc} - foo -} 1 -test stringComp-11.16 {string match} { - proc foo {} {string match {a[xyz]c} abc} - foo -} 0 -test stringComp-11.17 {string match} { - proc foo {} {string match {12[2-7]45} 12345} - foo -} 1 -test stringComp-11.18 {string match} { - proc foo {} {string match {12[ab2-4cd]45} 12345} - foo -} 1 -test stringComp-11.19 {string match} { - proc foo {} {string match {12[ab2-4cd]45} 12b45} - foo -} 1 -test stringComp-11.20 {string match} { - proc foo {} {string match {12[ab2-4cd]45} 12d45} - foo -} 1 -test stringComp-11.21 {string match} { - proc foo {} {string match {12[ab2-4cd]45} 12145} - foo -} 0 -test stringComp-11.22 {string match} { - proc foo {} {string match {12[ab2-4cd]45} 12545} - foo -} 0 -test stringComp-11.23 {string match} { - proc foo {} {string match {a\*b} a*b} - foo -} 1 -test stringComp-11.24 {string match} { - proc foo {} {string match {a\*b} ab} - foo -} 0 -test stringComp-11.25 {string match} { - proc foo {} {string match {a\*\?\[\]\\\x} "a*?\[\]\\x"} - foo -} 1 -test stringComp-11.26 {string match} { - proc foo {} {string match ** ""} - foo -} 1 -test stringComp-11.27 {string match} { - proc foo {} {string match *. ""} - foo -} 0 -test stringComp-11.28 {string match} { - proc foo {} {string match "" ""} - foo -} 1 -test stringComp-11.29 {string match} { - proc foo {} {string match \[a a} - foo -} 1 -test stringComp-11.30 {string match, bad args} { - proc foo {} {string match - b c} - list [catch {foo} msg] $msg -} {1 {bad option "-": must be -nocase}} -test stringComp-11.31 {string match case} { - proc foo {} {string match a A} - foo -} 0 -test stringComp-11.32 {string match nocase} { - proc foo {} {string match -n a A} - foo -} 1 -test stringComp-11.33 {string match nocase} { - proc foo {} {string match -nocase a\334 A\374} - foo -} 1 -test stringComp-11.34 {string match nocase} { - proc foo {} {string match -nocase a*f ABCDEf} - foo -} 1 -test stringComp-11.35 {string match case, false hope} { - # This is true because '_' lies between the A-Z and a-z ranges - proc foo {} {string match {[A-z]} _} - foo -} 1 -test stringComp-11.36 {string match nocase range} { - # This is false because although '_' lies between the A-Z and a-z ranges, - # we lower case the end points before checking the ranges. - proc foo {} {string match -nocase {[A-z]} _} - foo -} 0 -test stringComp-11.37 {string match nocase} { - proc foo {} {string match -nocase {[A-fh-Z]} g} - foo -} 0 -test stringComp-11.38 {string match case, reverse range} { - proc foo {} {string match {[A-fh-Z]} g} - foo -} 1 -test stringComp-11.39 {string match, *\ case} { - proc foo {} {string match {*\abc} abc} - foo -} 1 -test stringComp-11.40 {string match, *special case} { - proc foo {} {string match {*[ab]} abc} - foo -} 0 -test stringComp-11.41 {string match, *special case} { - proc foo {} {string match {*[ab]*} abc} - foo -} 1 -test stringComp-11.42 {string match, *special case} { - proc foo {} {string match "*\\" "\\"} - foo -} 0 -test stringComp-11.43 {string match, *special case} { - proc foo {} {string match "*\\\\" "\\"} - foo -} 1 -test stringComp-11.44 {string match, *special case} { - proc foo {} {string match "*???" "12345"} - foo -} 1 -test stringComp-11.45 {string match, *special case} { - proc foo {} {string match "*???" "12"} - foo -} 0 -test stringComp-11.46 {string match, *special case} { - proc foo {} {string match "*\\*" "abc*"} - foo -} 1 -test stringComp-11.47 {string match, *special case} { - proc foo {} {string match "*\\*" "*"} - foo -} 1 -test stringComp-11.48 {string match, *special case} { - proc foo {} {string match "*\\*" "*abc"} - foo -} 0 -test stringComp-11.49 {string match, *special case} { - proc foo {} {string match "?\\*" "a*"} - foo -} 1 -test stringComp-11.50 {string match, *special case} { - proc foo {} {string match "\\" "\\"} - foo -} 0 -test stringComp-11.51 {string match; *, -nocase and UTF-8} { - proc foo {} {string match -nocase [binary format I 717316707] \ - [binary format I 2028036707]} - foo -} 1 -test stringComp-11.52 {string match, null char in string} { - proc foo {} { - set ptn "*abc*" - foreach elem [list "\u0000@abc" "@abc" "\u0000@abc\u0000" "blahabcblah"] { - lappend out [string match $ptn $elem] - } - set out - } - foo -} {1 1 1 1} -test stringComp-11.53 {string match, null char in pattern} { - proc foo {} { - set out "" - foreach {ptn elem} [list \ - "*\u0000abc\u0000" "\u0000abc\u0000" \ - "*\u0000abc\u0000" "\u0000abc\u0000ef" \ - "*\u0000abc\u0000*" "\u0000abc\u0000ef" \ - "*\u0000abc\u0000" "@\u0000abc\u0000ef" \ - "*\u0000abc\u0000*" "@\u0000abc\u0000ef" \ - ] { - lappend out [string match $ptn $elem] - } - set out - } - foo -} {1 0 1 0 1} -test stringComp-11.54 {string match, failure} { - proc foo {} { - set longString "" - for {set i 0} {$i < 10} {incr i} { - append longString "abcdefghijklmnopqrstuvwxy\u0000z01234567890123" - } - list [string match *cba* $longString] \ - [string match *a*l*\u0000* $longString] \ - [string match *a*l*\u0000*123 $longString] \ - [string match *a*l*\u0000*123* $longString] \ - [string match *a*l*\u0000*cba* $longString] \ - [string match *===* $longString] - } - foo -} {0 1 1 1 0 0} - -## string range -test stringComp-12.1 {Bug 3588366: end-offsets before start} { - apply {s { - string range $s 0 end-5 - }} 12345 -} {} - -## string repeat -## not yet bc - -## string replace -test stringComp-14.1 {Bug 82e7f67325} { - apply {x { - set a [join $x {}] - lappend b [string length [string replace ___! 0 2 $a]] - lappend b [string length [string replace ___! 0 2 $a[unset a]]] - }} {a b} -} {3 3} -test stringComp-14.2 {Bug 82e7f67325} memory { - # As in stringComp-14.1, but make sure we don't retain too many refs - leaktest { - apply {x { - set a [join $x {}] - lappend b [string length [string replace ___! 0 2 $a]] - lappend b [string length [string replace ___! 0 2 $a[unset a]]] - }} {a b} - } -} {0} -test stringComp-14.3 {Bug 0dca3bfa8f} { - apply {arg { - set argCopy $arg - set arg [string replace $arg 1 2 aa] - # Crashes in comparison before fix - expr {$arg ne $argCopy} - }} abcde -} 1 -test stringComp-14.4 {Bug 1af8de570511} { - apply {{x y} { - # Generate an unshared string value - set val "" - for { set i 0 } { $i < $x } { incr i } { - set val [format "0%s" $val] - } - string replace $val[unset val] 1 1 $y - }} 4 x -} 0x00 -test stringComp-14.5 {} { - string length [string replace [string repeat a\u00fe 2] 3 end {}] -} 3 - -## string tolower -## not yet bc - -## string toupper -## not yet bc - -## string totitle -## not yet bc - -## string trim* -## not yet bc - -## string word* -## not yet bc - -## string cat -test stringComp-29.1 {string cat, no arg} { - proc foo {} {string cat} - foo -} "" -test stringComp-29.2 {string cat, single arg} { - proc foo {} { - set x FOO - string compare $x [string cat $x] - } - foo -} 0 -test stringComp-29.3 {string cat, two args} { - proc foo {} { - set x FOO - string compare $x$x [string cat $x $x] - } - foo -} 0 -test stringComp-29.4 {string cat, many args} { - proc foo {} { - set x FOO - set n 260 - set xx [string repeat $x $n] - set vv [string repeat {$x} $n] - set vvs [string repeat {$x } $n] - set r1 [string compare $xx [subst $vv]] - set r2 [string compare $xx [eval "string cat $vvs"]] - list $r1 $r2 - } - foo -} {0 0} - - -# cleanup -catch {rename foo {}} -::tcltest::cleanupTests -return - -# Local Variables: -# mode: tcl -# End: -- cgit v0.12 From 05c789647adebac2a77a4910a46810e94cad3efe Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Ignacio=20Mar=C3=ADn?= Date: Sat, 24 Mar 2018 10:20:43 +0000 Subject: Update TZ info to tzdata2018d. --- library/tzdata/Africa/Accra | 94 ++--- library/tzdata/Africa/Bissau | 2 +- library/tzdata/Africa/Sao_Tome | 2 +- library/tzdata/America/Araguaina | 50 +-- library/tzdata/America/Argentina/Buenos_Aires | 58 +-- library/tzdata/America/Argentina/Catamarca | 56 +-- library/tzdata/America/Argentina/Cordoba | 58 +-- library/tzdata/America/Argentina/Jujuy | 52 +-- library/tzdata/America/Argentina/La_Rioja | 56 +-- library/tzdata/America/Argentina/Mendoza | 52 +-- library/tzdata/America/Argentina/Rio_Gallegos | 56 +-- library/tzdata/America/Argentina/Salta | 56 +-- library/tzdata/America/Argentina/San_Juan | 56 +-- library/tzdata/America/Argentina/San_Luis | 50 +-- library/tzdata/America/Argentina/Tucuman | 58 +-- library/tzdata/America/Argentina/Ushuaia | 56 +-- library/tzdata/America/Asuncion | 250 ++++++------- library/tzdata/America/Bahia | 60 +-- library/tzdata/America/Belem | 28 +- library/tzdata/America/Boa_Vista | 32 +- library/tzdata/America/Bogota | 2 +- library/tzdata/America/Campo_Grande | 252 ++++++------- library/tzdata/America/Cuiaba | 250 ++++++------- library/tzdata/America/Eirunepe | 30 +- library/tzdata/America/Fortaleza | 38 +- library/tzdata/America/Grand_Turk | 4 +- library/tzdata/America/Guayaquil | 2 +- library/tzdata/America/Jamaica | 6 +- library/tzdata/America/Lima | 6 +- library/tzdata/America/Maceio | 40 +- library/tzdata/America/Manaus | 30 +- library/tzdata/America/Montevideo | 126 +++---- library/tzdata/America/Noronha | 38 +- library/tzdata/America/Porto_Velho | 28 +- library/tzdata/America/Punta_Arenas | 106 +++--- library/tzdata/America/Recife | 38 +- library/tzdata/America/Rio_Branco | 28 +- library/tzdata/America/Santarem | 28 +- library/tzdata/America/Santiago | 272 +++++++------- library/tzdata/America/Sao_Paulo | 250 ++++++------- library/tzdata/Antarctica/Casey | 1 + library/tzdata/Antarctica/Palmer | 78 ++-- library/tzdata/Asia/Almaty | 48 +-- library/tzdata/Asia/Aqtau | 48 +-- library/tzdata/Asia/Aqtobe | 46 +-- library/tzdata/Asia/Ashgabat | 22 +- library/tzdata/Asia/Atyrau | 46 +-- library/tzdata/Asia/Baghdad | 104 +++--- library/tzdata/Asia/Baku | 62 ++-- library/tzdata/Asia/Bishkek | 50 +-- library/tzdata/Asia/Choibalsan | 48 +-- library/tzdata/Asia/Dhaka | 2 +- library/tzdata/Asia/Dushanbe | 20 +- library/tzdata/Asia/Gaza | 72 ++-- library/tzdata/Asia/Hebron | 72 ++-- library/tzdata/Asia/Hovd | 48 +-- library/tzdata/Asia/Kuching | 14 +- library/tzdata/Asia/Macau | 2 +- library/tzdata/Asia/Manila | 6 +- library/tzdata/Asia/Oral | 46 +-- library/tzdata/Asia/Qyzylorda | 46 +-- library/tzdata/Asia/Samarkand | 20 +- library/tzdata/Asia/Tashkent | 22 +- library/tzdata/Asia/Tbilisi | 50 +-- library/tzdata/Asia/Tehran | 444 +++++++++++------------ library/tzdata/Asia/Ulaanbaatar | 48 +-- library/tzdata/Asia/Yerevan | 60 +-- library/tzdata/Atlantic/Azores | 2 +- library/tzdata/Atlantic/Cape_Verde | 2 +- library/tzdata/Atlantic/Madeira | 2 +- library/tzdata/Atlantic/Reykjavik | 66 ++-- library/tzdata/Atlantic/Stanley | 66 ++-- library/tzdata/Australia/Lord_Howe | 478 ++++++++++++------------ library/tzdata/Europe/Lisbon | 2 +- library/tzdata/Indian/Mauritius | 4 +- library/tzdata/Pacific/Apia | 362 +++++++++--------- library/tzdata/Pacific/Chatham | 504 +++++++++++++------------- library/tzdata/Pacific/Easter | 262 ++++++------- library/tzdata/Pacific/Efate | 20 +- library/tzdata/Pacific/Enderbury | 2 +- library/tzdata/Pacific/Fiji | 186 +++++----- library/tzdata/Pacific/Galapagos | 2 +- library/tzdata/Pacific/Kiritimati | 2 +- library/tzdata/Pacific/Noumea | 6 +- library/tzdata/Pacific/Rarotonga | 26 +- library/tzdata/Pacific/Tongatapu | 8 +- 86 files changed, 3142 insertions(+), 3141 deletions(-) diff --git a/library/tzdata/Africa/Accra b/library/tzdata/Africa/Accra index 18f4522..f43f751 100644 --- a/library/tzdata/Africa/Accra +++ b/library/tzdata/Africa/Accra @@ -2,51 +2,51 @@ set TZData(:Africa/Accra) { {-9223372036854775808 -52 0 LMT} - {-1640995148 0 0 +0020} - {-1556841600 1200 1 +0020} - {-1546388400 0 0 +0020} - {-1525305600 1200 1 +0020} - {-1514852400 0 0 +0020} - {-1493769600 1200 1 +0020} - {-1483316400 0 0 +0020} - {-1462233600 1200 1 +0020} - {-1451780400 0 0 +0020} - {-1430611200 1200 1 +0020} - {-1420158000 0 0 +0020} - {-1399075200 1200 1 +0020} - {-1388622000 0 0 +0020} - {-1367539200 1200 1 +0020} - {-1357086000 0 0 +0020} - {-1336003200 1200 1 +0020} - {-1325550000 0 0 +0020} - {-1304380800 1200 1 +0020} - {-1293927600 0 0 +0020} - {-1272844800 1200 1 +0020} - {-1262391600 0 0 +0020} - {-1241308800 1200 1 +0020} - {-1230855600 0 0 +0020} - {-1209772800 1200 1 +0020} - {-1199319600 0 0 +0020} - {-1178150400 1200 1 +0020} - {-1167697200 0 0 +0020} - {-1146614400 1200 1 +0020} - {-1136161200 0 0 +0020} - {-1115078400 1200 1 +0020} - {-1104625200 0 0 +0020} - {-1083542400 1200 1 +0020} - {-1073089200 0 0 +0020} - {-1051920000 1200 1 +0020} - {-1041466800 0 0 +0020} - {-1020384000 1200 1 +0020} - {-1009930800 0 0 +0020} - {-988848000 1200 1 +0020} - {-978394800 0 0 +0020} - {-957312000 1200 1 +0020} - {-946858800 0 0 +0020} - {-925689600 1200 1 +0020} - {-915236400 0 0 +0020} - {-894153600 1200 1 +0020} - {-883700400 0 0 +0020} - {-862617600 1200 1 +0020} - {-852164400 0 0 +0020} + {-1640995148 0 0 GMT} + {-1556841600 1200 1 GMT} + {-1546388400 0 0 GMT} + {-1525305600 1200 1 GMT} + {-1514852400 0 0 GMT} + {-1493769600 1200 1 GMT} + {-1483316400 0 0 GMT} + {-1462233600 1200 1 GMT} + {-1451780400 0 0 GMT} + {-1430611200 1200 1 GMT} + {-1420158000 0 0 GMT} + {-1399075200 1200 1 GMT} + {-1388622000 0 0 GMT} + {-1367539200 1200 1 GMT} + {-1357086000 0 0 GMT} + {-1336003200 1200 1 GMT} + {-1325550000 0 0 GMT} + {-1304380800 1200 1 GMT} + {-1293927600 0 0 GMT} + {-1272844800 1200 1 GMT} + {-1262391600 0 0 GMT} + {-1241308800 1200 1 GMT} + {-1230855600 0 0 GMT} + {-1209772800 1200 1 GMT} + {-1199319600 0 0 GMT} + {-1178150400 1200 1 GMT} + {-1167697200 0 0 GMT} + {-1146614400 1200 1 GMT} + {-1136161200 0 0 GMT} + {-1115078400 1200 1 GMT} + {-1104625200 0 0 GMT} + {-1083542400 1200 1 GMT} + {-1073089200 0 0 GMT} + {-1051920000 1200 1 GMT} + {-1041466800 0 0 GMT} + {-1020384000 1200 1 GMT} + {-1009930800 0 0 GMT} + {-988848000 1200 1 GMT} + {-978394800 0 0 GMT} + {-957312000 1200 1 GMT} + {-946858800 0 0 GMT} + {-925689600 1200 1 GMT} + {-915236400 0 0 GMT} + {-894153600 1200 1 GMT} + {-883700400 0 0 GMT} + {-862617600 1200 1 GMT} + {-852164400 0 0 GMT} } diff --git a/library/tzdata/Africa/Bissau b/library/tzdata/Africa/Bissau index 88d9d03..e0568fb 100644 --- a/library/tzdata/Africa/Bissau +++ b/library/tzdata/Africa/Bissau @@ -2,6 +2,6 @@ set TZData(:Africa/Bissau) { {-9223372036854775808 -3740 0 LMT} - {-1830380260 -3600 0 -01} + {-1830380400 -3600 0 -01} {157770000 0 0 GMT} } diff --git a/library/tzdata/Africa/Sao_Tome b/library/tzdata/Africa/Sao_Tome index fe08d89..6a60f5c 100644 --- a/library/tzdata/Africa/Sao_Tome +++ b/library/tzdata/Africa/Sao_Tome @@ -3,6 +3,6 @@ set TZData(:Africa/Sao_Tome) { {-9223372036854775808 1616 0 LMT} {-2713912016 -2205 0 LMT} - {-1830381795 0 0 GMT} + {-1830384000 0 0 GMT} {1514768400 3600 0 WAT} } diff --git a/library/tzdata/America/Araguaina b/library/tzdata/America/Araguaina index b9e2aec..ca64292 100644 --- a/library/tzdata/America/Araguaina +++ b/library/tzdata/America/Araguaina @@ -3,58 +3,58 @@ set TZData(:America/Araguaina) { {-9223372036854775808 -11568 0 LMT} {-1767214032 -10800 0 -03} - {-1206957600 -7200 1 -02} + {-1206957600 -7200 1 -03} {-1191362400 -10800 0 -03} - {-1175374800 -7200 1 -02} + {-1175374800 -7200 1 -03} {-1159826400 -10800 0 -03} - {-633819600 -7200 1 -02} + {-633819600 -7200 1 -03} {-622069200 -10800 0 -03} - {-602283600 -7200 1 -02} + {-602283600 -7200 1 -03} {-591832800 -10800 0 -03} - {-570747600 -7200 1 -02} + {-570747600 -7200 1 -03} {-560210400 -10800 0 -03} - {-539125200 -7200 1 -02} + {-539125200 -7200 1 -03} {-531352800 -10800 0 -03} - {-191365200 -7200 1 -02} + {-191365200 -7200 1 -03} {-184197600 -10800 0 -03} - {-155163600 -7200 1 -02} + {-155163600 -7200 1 -03} {-150069600 -10800 0 -03} - {-128898000 -7200 1 -02} + {-128898000 -7200 1 -03} {-121125600 -10800 0 -03} - {-99954000 -7200 1 -02} + {-99954000 -7200 1 -03} {-89589600 -10800 0 -03} - {-68418000 -7200 1 -02} + {-68418000 -7200 1 -03} {-57967200 -10800 0 -03} - {499748400 -7200 1 -02} + {499748400 -7200 1 -03} {511236000 -10800 0 -03} - {530593200 -7200 1 -02} + {530593200 -7200 1 -03} {540266400 -10800 0 -03} - {562129200 -7200 1 -02} + {562129200 -7200 1 -03} {571197600 -10800 0 -03} - {592974000 -7200 1 -02} + {592974000 -7200 1 -03} {602042400 -10800 0 -03} - {624423600 -7200 1 -02} + {624423600 -7200 1 -03} {634701600 -10800 0 -03} {653536800 -10800 0 -03} {811047600 -10800 0 -03} - {813726000 -7200 1 -02} + {813726000 -7200 1 -03} {824004000 -10800 0 -03} - {844570800 -7200 1 -02} + {844570800 -7200 1 -03} {856058400 -10800 0 -03} - {876106800 -7200 1 -02} + {876106800 -7200 1 -03} {888717600 -10800 0 -03} - {908074800 -7200 1 -02} + {908074800 -7200 1 -03} {919562400 -10800 0 -03} - {938919600 -7200 1 -02} + {938919600 -7200 1 -03} {951616800 -10800 0 -03} - {970974000 -7200 1 -02} + {970974000 -7200 1 -03} {982461600 -10800 0 -03} - {1003028400 -7200 1 -02} + {1003028400 -7200 1 -03} {1013911200 -10800 0 -03} - {1036292400 -7200 1 -02} + {1036292400 -7200 1 -03} {1045360800 -10800 0 -03} {1064368800 -10800 0 -03} - {1350788400 -7200 0 -02} + {1350788400 -7200 0 -03} {1361066400 -10800 0 -03} {1378000800 -10800 0 -03} } diff --git a/library/tzdata/America/Argentina/Buenos_Aires b/library/tzdata/America/Argentina/Buenos_Aires index 8be2c45..40f1912 100644 --- a/library/tzdata/America/Argentina/Buenos_Aires +++ b/library/tzdata/America/Argentina/Buenos_Aires @@ -4,64 +4,64 @@ set TZData(:America/Argentina/Buenos_Aires) { {-9223372036854775808 -14028 0 LMT} {-2372097972 -15408 0 CMT} {-1567453392 -14400 0 -04} - {-1233432000 -10800 0 -03} + {-1233432000 -10800 0 -04} {-1222981200 -14400 0 -04} - {-1205956800 -10800 1 -03} + {-1205956800 -10800 1 -04} {-1194037200 -14400 0 -04} - {-1172865600 -10800 1 -03} + {-1172865600 -10800 1 -04} {-1162501200 -14400 0 -04} - {-1141329600 -10800 1 -03} + {-1141329600 -10800 1 -04} {-1130965200 -14400 0 -04} - {-1109793600 -10800 1 -03} + {-1109793600 -10800 1 -04} {-1099429200 -14400 0 -04} - {-1078257600 -10800 1 -03} + {-1078257600 -10800 1 -04} {-1067806800 -14400 0 -04} - {-1046635200 -10800 1 -03} + {-1046635200 -10800 1 -04} {-1036270800 -14400 0 -04} - {-1015099200 -10800 1 -03} + {-1015099200 -10800 1 -04} {-1004734800 -14400 0 -04} - {-983563200 -10800 1 -03} + {-983563200 -10800 1 -04} {-973198800 -14400 0 -04} - {-952027200 -10800 1 -03} + {-952027200 -10800 1 -04} {-941576400 -14400 0 -04} - {-931032000 -10800 1 -03} + {-931032000 -10800 1 -04} {-900882000 -14400 0 -04} - {-890337600 -10800 1 -03} + {-890337600 -10800 1 -04} {-833749200 -14400 0 -04} - {-827265600 -10800 1 -03} + {-827265600 -10800 1 -04} {-752274000 -14400 0 -04} - {-733780800 -10800 1 -03} + {-733780800 -10800 1 -04} {-197326800 -14400 0 -04} - {-190843200 -10800 1 -03} + {-190843200 -10800 1 -04} {-184194000 -14400 0 -04} - {-164491200 -10800 1 -03} + {-164491200 -10800 1 -04} {-152658000 -14400 0 -04} - {-132955200 -10800 1 -03} + {-132955200 -10800 1 -04} {-121122000 -14400 0 -04} - {-101419200 -10800 1 -03} + {-101419200 -10800 1 -04} {-86821200 -14400 0 -04} - {-71092800 -10800 1 -03} + {-71092800 -10800 1 -04} {-54766800 -14400 0 -04} - {-39038400 -10800 1 -03} + {-39038400 -10800 1 -04} {-23317200 -14400 0 -04} {-7588800 -10800 0 -03} - {128142000 -7200 1 -02} + {128142000 -7200 1 -03} {136605600 -10800 0 -03} - {596948400 -7200 1 -02} + {596948400 -7200 1 -03} {605066400 -10800 0 -03} - {624423600 -7200 1 -02} + {624423600 -7200 1 -03} {636516000 -10800 0 -03} - {656478000 -7200 1 -02} + {656478000 -7200 1 -03} {667965600 -10800 0 -03} - {687927600 -7200 1 -02} + {687927600 -7200 1 -03} {699415200 -10800 0 -03} - {719377200 -7200 1 -02} + {719377200 -7200 1 -03} {731469600 -10800 0 -03} {938916000 -10800 0 -04} - {938919600 -10800 1 -03} + {938919600 -10800 1 -04} {952056000 -10800 0 -03} - {1198983600 -7200 1 -02} + {1198983600 -7200 1 -03} {1205632800 -10800 0 -03} - {1224385200 -7200 1 -02} + {1224385200 -7200 1 -03} {1237082400 -10800 0 -03} } diff --git a/library/tzdata/America/Argentina/Catamarca b/library/tzdata/America/Argentina/Catamarca index a546bfc..da5b42a 100644 --- a/library/tzdata/America/Argentina/Catamarca +++ b/library/tzdata/America/Argentina/Catamarca @@ -4,65 +4,65 @@ set TZData(:America/Argentina/Catamarca) { {-9223372036854775808 -15788 0 LMT} {-2372096212 -15408 0 CMT} {-1567453392 -14400 0 -04} - {-1233432000 -10800 0 -03} + {-1233432000 -10800 0 -04} {-1222981200 -14400 0 -04} - {-1205956800 -10800 1 -03} + {-1205956800 -10800 1 -04} {-1194037200 -14400 0 -04} - {-1172865600 -10800 1 -03} + {-1172865600 -10800 1 -04} {-1162501200 -14400 0 -04} - {-1141329600 -10800 1 -03} + {-1141329600 -10800 1 -04} {-1130965200 -14400 0 -04} - {-1109793600 -10800 1 -03} + {-1109793600 -10800 1 -04} {-1099429200 -14400 0 -04} - {-1078257600 -10800 1 -03} + {-1078257600 -10800 1 -04} {-1067806800 -14400 0 -04} - {-1046635200 -10800 1 -03} + {-1046635200 -10800 1 -04} {-1036270800 -14400 0 -04} - {-1015099200 -10800 1 -03} + {-1015099200 -10800 1 -04} {-1004734800 -14400 0 -04} - {-983563200 -10800 1 -03} + {-983563200 -10800 1 -04} {-973198800 -14400 0 -04} - {-952027200 -10800 1 -03} + {-952027200 -10800 1 -04} {-941576400 -14400 0 -04} - {-931032000 -10800 1 -03} + {-931032000 -10800 1 -04} {-900882000 -14400 0 -04} - {-890337600 -10800 1 -03} + {-890337600 -10800 1 -04} {-833749200 -14400 0 -04} - {-827265600 -10800 1 -03} + {-827265600 -10800 1 -04} {-752274000 -14400 0 -04} - {-733780800 -10800 1 -03} + {-733780800 -10800 1 -04} {-197326800 -14400 0 -04} - {-190843200 -10800 1 -03} + {-190843200 -10800 1 -04} {-184194000 -14400 0 -04} - {-164491200 -10800 1 -03} + {-164491200 -10800 1 -04} {-152658000 -14400 0 -04} - {-132955200 -10800 1 -03} + {-132955200 -10800 1 -04} {-121122000 -14400 0 -04} - {-101419200 -10800 1 -03} + {-101419200 -10800 1 -04} {-86821200 -14400 0 -04} - {-71092800 -10800 1 -03} + {-71092800 -10800 1 -04} {-54766800 -14400 0 -04} - {-39038400 -10800 1 -03} + {-39038400 -10800 1 -04} {-23317200 -14400 0 -04} {-7588800 -10800 0 -03} - {128142000 -7200 1 -02} + {128142000 -7200 1 -03} {136605600 -10800 0 -03} - {596948400 -7200 1 -02} + {596948400 -7200 1 -03} {605066400 -10800 0 -03} - {624423600 -7200 1 -02} + {624423600 -7200 1 -03} {636516000 -10800 0 -03} - {656478000 -7200 1 -02} + {656478000 -7200 1 -03} {667965600 -14400 0 -04} - {687931200 -7200 0 -02} + {687931200 -7200 0 -03} {699415200 -10800 0 -03} - {719377200 -7200 1 -02} + {719377200 -7200 1 -03} {731469600 -10800 0 -03} {938916000 -10800 0 -04} - {938919600 -10800 1 -03} + {938919600 -10800 1 -04} {952056000 -10800 0 -03} {1086058800 -14400 0 -04} {1087704000 -10800 0 -03} - {1198983600 -7200 1 -02} + {1198983600 -7200 1 -03} {1205632800 -10800 0 -03} {1224295200 -10800 0 -03} } diff --git a/library/tzdata/America/Argentina/Cordoba b/library/tzdata/America/Argentina/Cordoba index ec6978e..6a1426e 100644 --- a/library/tzdata/America/Argentina/Cordoba +++ b/library/tzdata/America/Argentina/Cordoba @@ -4,64 +4,64 @@ set TZData(:America/Argentina/Cordoba) { {-9223372036854775808 -15408 0 LMT} {-2372096592 -15408 0 CMT} {-1567453392 -14400 0 -04} - {-1233432000 -10800 0 -03} + {-1233432000 -10800 0 -04} {-1222981200 -14400 0 -04} - {-1205956800 -10800 1 -03} + {-1205956800 -10800 1 -04} {-1194037200 -14400 0 -04} - {-1172865600 -10800 1 -03} + {-1172865600 -10800 1 -04} {-1162501200 -14400 0 -04} - {-1141329600 -10800 1 -03} + {-1141329600 -10800 1 -04} {-1130965200 -14400 0 -04} - {-1109793600 -10800 1 -03} + {-1109793600 -10800 1 -04} {-1099429200 -14400 0 -04} - {-1078257600 -10800 1 -03} + {-1078257600 -10800 1 -04} {-1067806800 -14400 0 -04} - {-1046635200 -10800 1 -03} + {-1046635200 -10800 1 -04} {-1036270800 -14400 0 -04} - {-1015099200 -10800 1 -03} + {-1015099200 -10800 1 -04} {-1004734800 -14400 0 -04} - {-983563200 -10800 1 -03} + {-983563200 -10800 1 -04} {-973198800 -14400 0 -04} - {-952027200 -10800 1 -03} + {-952027200 -10800 1 -04} {-941576400 -14400 0 -04} - {-931032000 -10800 1 -03} + {-931032000 -10800 1 -04} {-900882000 -14400 0 -04} - {-890337600 -10800 1 -03} + {-890337600 -10800 1 -04} {-833749200 -14400 0 -04} - {-827265600 -10800 1 -03} + {-827265600 -10800 1 -04} {-752274000 -14400 0 -04} - {-733780800 -10800 1 -03} + {-733780800 -10800 1 -04} {-197326800 -14400 0 -04} - {-190843200 -10800 1 -03} + {-190843200 -10800 1 -04} {-184194000 -14400 0 -04} - {-164491200 -10800 1 -03} + {-164491200 -10800 1 -04} {-152658000 -14400 0 -04} - {-132955200 -10800 1 -03} + {-132955200 -10800 1 -04} {-121122000 -14400 0 -04} - {-101419200 -10800 1 -03} + {-101419200 -10800 1 -04} {-86821200 -14400 0 -04} - {-71092800 -10800 1 -03} + {-71092800 -10800 1 -04} {-54766800 -14400 0 -04} - {-39038400 -10800 1 -03} + {-39038400 -10800 1 -04} {-23317200 -14400 0 -04} {-7588800 -10800 0 -03} - {128142000 -7200 1 -02} + {128142000 -7200 1 -03} {136605600 -10800 0 -03} - {596948400 -7200 1 -02} + {596948400 -7200 1 -03} {605066400 -10800 0 -03} - {624423600 -7200 1 -02} + {624423600 -7200 1 -03} {636516000 -10800 0 -03} - {656478000 -7200 1 -02} + {656478000 -7200 1 -03} {667965600 -14400 0 -04} - {687931200 -7200 0 -02} + {687931200 -7200 0 -03} {699415200 -10800 0 -03} - {719377200 -7200 1 -02} + {719377200 -7200 1 -03} {731469600 -10800 0 -03} {938916000 -10800 0 -04} - {938919600 -10800 1 -03} + {938919600 -10800 1 -04} {952056000 -10800 0 -03} - {1198983600 -7200 1 -02} + {1198983600 -7200 1 -03} {1205632800 -10800 0 -03} - {1224385200 -7200 1 -02} + {1224385200 -7200 1 -03} {1237082400 -10800 0 -03} } diff --git a/library/tzdata/America/Argentina/Jujuy b/library/tzdata/America/Argentina/Jujuy index 0e11ba2..72080f5 100644 --- a/library/tzdata/America/Argentina/Jujuy +++ b/library/tzdata/America/Argentina/Jujuy @@ -4,64 +4,64 @@ set TZData(:America/Argentina/Jujuy) { {-9223372036854775808 -15672 0 LMT} {-2372096328 -15408 0 CMT} {-1567453392 -14400 0 -04} - {-1233432000 -10800 0 -03} + {-1233432000 -10800 0 -04} {-1222981200 -14400 0 -04} - {-1205956800 -10800 1 -03} + {-1205956800 -10800 1 -04} {-1194037200 -14400 0 -04} - {-1172865600 -10800 1 -03} + {-1172865600 -10800 1 -04} {-1162501200 -14400 0 -04} - {-1141329600 -10800 1 -03} + {-1141329600 -10800 1 -04} {-1130965200 -14400 0 -04} - {-1109793600 -10800 1 -03} + {-1109793600 -10800 1 -04} {-1099429200 -14400 0 -04} - {-1078257600 -10800 1 -03} + {-1078257600 -10800 1 -04} {-1067806800 -14400 0 -04} - {-1046635200 -10800 1 -03} + {-1046635200 -10800 1 -04} {-1036270800 -14400 0 -04} - {-1015099200 -10800 1 -03} + {-1015099200 -10800 1 -04} {-1004734800 -14400 0 -04} - {-983563200 -10800 1 -03} + {-983563200 -10800 1 -04} {-973198800 -14400 0 -04} - {-952027200 -10800 1 -03} + {-952027200 -10800 1 -04} {-941576400 -14400 0 -04} - {-931032000 -10800 1 -03} + {-931032000 -10800 1 -04} {-900882000 -14400 0 -04} - {-890337600 -10800 1 -03} + {-890337600 -10800 1 -04} {-833749200 -14400 0 -04} - {-827265600 -10800 1 -03} + {-827265600 -10800 1 -04} {-752274000 -14400 0 -04} - {-733780800 -10800 1 -03} + {-733780800 -10800 1 -04} {-197326800 -14400 0 -04} - {-190843200 -10800 1 -03} + {-190843200 -10800 1 -04} {-184194000 -14400 0 -04} - {-164491200 -10800 1 -03} + {-164491200 -10800 1 -04} {-152658000 -14400 0 -04} - {-132955200 -10800 1 -03} + {-132955200 -10800 1 -04} {-121122000 -14400 0 -04} - {-101419200 -10800 1 -03} + {-101419200 -10800 1 -04} {-86821200 -14400 0 -04} - {-71092800 -10800 1 -03} + {-71092800 -10800 1 -04} {-54766800 -14400 0 -04} - {-39038400 -10800 1 -03} + {-39038400 -10800 1 -04} {-23317200 -14400 0 -04} {-7588800 -10800 0 -03} - {128142000 -7200 1 -02} + {128142000 -7200 1 -03} {136605600 -10800 0 -03} - {596948400 -7200 1 -02} + {596948400 -7200 1 -03} {605066400 -10800 0 -03} - {624423600 -7200 1 -02} + {624423600 -7200 1 -03} {636516000 -14400 0 -04} {657086400 -10800 1 -03} {669178800 -14400 0 -04} {686721600 -7200 1 -02} {694231200 -7200 0 -03} {699415200 -10800 0 -03} - {719377200 -7200 1 -02} + {719377200 -7200 1 -03} {731469600 -10800 0 -03} {938916000 -10800 0 -04} - {938919600 -10800 1 -03} + {938919600 -10800 1 -04} {952056000 -10800 0 -03} - {1198983600 -7200 1 -02} + {1198983600 -7200 1 -03} {1205632800 -10800 0 -03} {1224295200 -10800 0 -03} } diff --git a/library/tzdata/America/Argentina/La_Rioja b/library/tzdata/America/Argentina/La_Rioja index 90e0030..fb7b237 100644 --- a/library/tzdata/America/Argentina/La_Rioja +++ b/library/tzdata/America/Argentina/La_Rioja @@ -4,66 +4,66 @@ set TZData(:America/Argentina/La_Rioja) { {-9223372036854775808 -16044 0 LMT} {-2372095956 -15408 0 CMT} {-1567453392 -14400 0 -04} - {-1233432000 -10800 0 -03} + {-1233432000 -10800 0 -04} {-1222981200 -14400 0 -04} - {-1205956800 -10800 1 -03} + {-1205956800 -10800 1 -04} {-1194037200 -14400 0 -04} - {-1172865600 -10800 1 -03} + {-1172865600 -10800 1 -04} {-1162501200 -14400 0 -04} - {-1141329600 -10800 1 -03} + {-1141329600 -10800 1 -04} {-1130965200 -14400 0 -04} - {-1109793600 -10800 1 -03} + {-1109793600 -10800 1 -04} {-1099429200 -14400 0 -04} - {-1078257600 -10800 1 -03} + {-1078257600 -10800 1 -04} {-1067806800 -14400 0 -04} - {-1046635200 -10800 1 -03} + {-1046635200 -10800 1 -04} {-1036270800 -14400 0 -04} - {-1015099200 -10800 1 -03} + {-1015099200 -10800 1 -04} {-1004734800 -14400 0 -04} - {-983563200 -10800 1 -03} + {-983563200 -10800 1 -04} {-973198800 -14400 0 -04} - {-952027200 -10800 1 -03} + {-952027200 -10800 1 -04} {-941576400 -14400 0 -04} - {-931032000 -10800 1 -03} + {-931032000 -10800 1 -04} {-900882000 -14400 0 -04} - {-890337600 -10800 1 -03} + {-890337600 -10800 1 -04} {-833749200 -14400 0 -04} - {-827265600 -10800 1 -03} + {-827265600 -10800 1 -04} {-752274000 -14400 0 -04} - {-733780800 -10800 1 -03} + {-733780800 -10800 1 -04} {-197326800 -14400 0 -04} - {-190843200 -10800 1 -03} + {-190843200 -10800 1 -04} {-184194000 -14400 0 -04} - {-164491200 -10800 1 -03} + {-164491200 -10800 1 -04} {-152658000 -14400 0 -04} - {-132955200 -10800 1 -03} + {-132955200 -10800 1 -04} {-121122000 -14400 0 -04} - {-101419200 -10800 1 -03} + {-101419200 -10800 1 -04} {-86821200 -14400 0 -04} - {-71092800 -10800 1 -03} + {-71092800 -10800 1 -04} {-54766800 -14400 0 -04} - {-39038400 -10800 1 -03} + {-39038400 -10800 1 -04} {-23317200 -14400 0 -04} {-7588800 -10800 0 -03} - {128142000 -7200 1 -02} + {128142000 -7200 1 -03} {136605600 -10800 0 -03} - {596948400 -7200 1 -02} + {596948400 -7200 1 -03} {605066400 -10800 0 -03} - {624423600 -7200 1 -02} + {624423600 -7200 1 -03} {636516000 -10800 0 -03} - {656478000 -7200 1 -02} + {656478000 -7200 1 -03} {667792800 -14400 0 -04} {673588800 -10800 0 -03} - {687927600 -7200 1 -02} + {687927600 -7200 1 -03} {699415200 -10800 0 -03} - {719377200 -7200 1 -02} + {719377200 -7200 1 -03} {731469600 -10800 0 -03} {938916000 -10800 0 -04} - {938919600 -10800 1 -03} + {938919600 -10800 1 -04} {952056000 -10800 0 -03} {1086058800 -14400 0 -04} {1087704000 -10800 0 -03} - {1198983600 -7200 1 -02} + {1198983600 -7200 1 -03} {1205632800 -10800 0 -03} {1224295200 -10800 0 -03} } diff --git a/library/tzdata/America/Argentina/Mendoza b/library/tzdata/America/Argentina/Mendoza index 8dfcd2b..af7342e 100644 --- a/library/tzdata/America/Argentina/Mendoza +++ b/library/tzdata/America/Argentina/Mendoza @@ -4,65 +4,65 @@ set TZData(:America/Argentina/Mendoza) { {-9223372036854775808 -16516 0 LMT} {-2372095484 -15408 0 CMT} {-1567453392 -14400 0 -04} - {-1233432000 -10800 0 -03} + {-1233432000 -10800 0 -04} {-1222981200 -14400 0 -04} - {-1205956800 -10800 1 -03} + {-1205956800 -10800 1 -04} {-1194037200 -14400 0 -04} - {-1172865600 -10800 1 -03} + {-1172865600 -10800 1 -04} {-1162501200 -14400 0 -04} - {-1141329600 -10800 1 -03} + {-1141329600 -10800 1 -04} {-1130965200 -14400 0 -04} - {-1109793600 -10800 1 -03} + {-1109793600 -10800 1 -04} {-1099429200 -14400 0 -04} - {-1078257600 -10800 1 -03} + {-1078257600 -10800 1 -04} {-1067806800 -14400 0 -04} - {-1046635200 -10800 1 -03} + {-1046635200 -10800 1 -04} {-1036270800 -14400 0 -04} - {-1015099200 -10800 1 -03} + {-1015099200 -10800 1 -04} {-1004734800 -14400 0 -04} - {-983563200 -10800 1 -03} + {-983563200 -10800 1 -04} {-973198800 -14400 0 -04} - {-952027200 -10800 1 -03} + {-952027200 -10800 1 -04} {-941576400 -14400 0 -04} - {-931032000 -10800 1 -03} + {-931032000 -10800 1 -04} {-900882000 -14400 0 -04} - {-890337600 -10800 1 -03} + {-890337600 -10800 1 -04} {-833749200 -14400 0 -04} - {-827265600 -10800 1 -03} + {-827265600 -10800 1 -04} {-752274000 -14400 0 -04} - {-733780800 -10800 1 -03} + {-733780800 -10800 1 -04} {-197326800 -14400 0 -04} - {-190843200 -10800 1 -03} + {-190843200 -10800 1 -04} {-184194000 -14400 0 -04} - {-164491200 -10800 1 -03} + {-164491200 -10800 1 -04} {-152658000 -14400 0 -04} - {-132955200 -10800 1 -03} + {-132955200 -10800 1 -04} {-121122000 -14400 0 -04} - {-101419200 -10800 1 -03} + {-101419200 -10800 1 -04} {-86821200 -14400 0 -04} - {-71092800 -10800 1 -03} + {-71092800 -10800 1 -04} {-54766800 -14400 0 -04} - {-39038400 -10800 1 -03} + {-39038400 -10800 1 -04} {-23317200 -14400 0 -04} {-7588800 -10800 0 -03} - {128142000 -7200 1 -02} + {128142000 -7200 1 -03} {136605600 -10800 0 -03} - {596948400 -7200 1 -02} + {596948400 -7200 1 -03} {605066400 -10800 0 -03} - {624423600 -7200 1 -02} + {624423600 -7200 1 -03} {636516000 -14400 0 -04} {655963200 -10800 1 -03} {667796400 -14400 0 -04} {687499200 -10800 1 -03} {699418800 -14400 0 -04} - {719380800 -7200 0 -02} + {719380800 -7200 0 -03} {731469600 -10800 0 -03} {938916000 -10800 0 -04} - {938919600 -10800 1 -03} + {938919600 -10800 1 -04} {952056000 -10800 0 -03} {1085281200 -14400 0 -04} {1096171200 -10800 0 -03} - {1198983600 -7200 1 -02} + {1198983600 -7200 1 -03} {1205632800 -10800 0 -03} {1224295200 -10800 0 -03} } diff --git a/library/tzdata/America/Argentina/Rio_Gallegos b/library/tzdata/America/Argentina/Rio_Gallegos index 4b2a348..2a197a4 100644 --- a/library/tzdata/America/Argentina/Rio_Gallegos +++ b/library/tzdata/America/Argentina/Rio_Gallegos @@ -4,65 +4,65 @@ set TZData(:America/Argentina/Rio_Gallegos) { {-9223372036854775808 -16612 0 LMT} {-2372095388 -15408 0 CMT} {-1567453392 -14400 0 -04} - {-1233432000 -10800 0 -03} + {-1233432000 -10800 0 -04} {-1222981200 -14400 0 -04} - {-1205956800 -10800 1 -03} + {-1205956800 -10800 1 -04} {-1194037200 -14400 0 -04} - {-1172865600 -10800 1 -03} + {-1172865600 -10800 1 -04} {-1162501200 -14400 0 -04} - {-1141329600 -10800 1 -03} + {-1141329600 -10800 1 -04} {-1130965200 -14400 0 -04} - {-1109793600 -10800 1 -03} + {-1109793600 -10800 1 -04} {-1099429200 -14400 0 -04} - {-1078257600 -10800 1 -03} + {-1078257600 -10800 1 -04} {-1067806800 -14400 0 -04} - {-1046635200 -10800 1 -03} + {-1046635200 -10800 1 -04} {-1036270800 -14400 0 -04} - {-1015099200 -10800 1 -03} + {-1015099200 -10800 1 -04} {-1004734800 -14400 0 -04} - {-983563200 -10800 1 -03} + {-983563200 -10800 1 -04} {-973198800 -14400 0 -04} - {-952027200 -10800 1 -03} + {-952027200 -10800 1 -04} {-941576400 -14400 0 -04} - {-931032000 -10800 1 -03} + {-931032000 -10800 1 -04} {-900882000 -14400 0 -04} - {-890337600 -10800 1 -03} + {-890337600 -10800 1 -04} {-833749200 -14400 0 -04} - {-827265600 -10800 1 -03} + {-827265600 -10800 1 -04} {-752274000 -14400 0 -04} - {-733780800 -10800 1 -03} + {-733780800 -10800 1 -04} {-197326800 -14400 0 -04} - {-190843200 -10800 1 -03} + {-190843200 -10800 1 -04} {-184194000 -14400 0 -04} - {-164491200 -10800 1 -03} + {-164491200 -10800 1 -04} {-152658000 -14400 0 -04} - {-132955200 -10800 1 -03} + {-132955200 -10800 1 -04} {-121122000 -14400 0 -04} - {-101419200 -10800 1 -03} + {-101419200 -10800 1 -04} {-86821200 -14400 0 -04} - {-71092800 -10800 1 -03} + {-71092800 -10800 1 -04} {-54766800 -14400 0 -04} - {-39038400 -10800 1 -03} + {-39038400 -10800 1 -04} {-23317200 -14400 0 -04} {-7588800 -10800 0 -03} - {128142000 -7200 1 -02} + {128142000 -7200 1 -03} {136605600 -10800 0 -03} - {596948400 -7200 1 -02} + {596948400 -7200 1 -03} {605066400 -10800 0 -03} - {624423600 -7200 1 -02} + {624423600 -7200 1 -03} {636516000 -10800 0 -03} - {656478000 -7200 1 -02} + {656478000 -7200 1 -03} {667965600 -10800 0 -03} - {687927600 -7200 1 -02} + {687927600 -7200 1 -03} {699415200 -10800 0 -03} - {719377200 -7200 1 -02} + {719377200 -7200 1 -03} {731469600 -10800 0 -03} {938916000 -10800 0 -04} - {938919600 -10800 1 -03} + {938919600 -10800 1 -04} {952056000 -10800 0 -03} {1086058800 -14400 0 -04} {1087704000 -10800 0 -03} - {1198983600 -7200 1 -02} + {1198983600 -7200 1 -03} {1205632800 -10800 0 -03} {1224295200 -10800 0 -03} } diff --git a/library/tzdata/America/Argentina/Salta b/library/tzdata/America/Argentina/Salta index 4f9ccf9..d49e82f 100644 --- a/library/tzdata/America/Argentina/Salta +++ b/library/tzdata/America/Argentina/Salta @@ -4,63 +4,63 @@ set TZData(:America/Argentina/Salta) { {-9223372036854775808 -15700 0 LMT} {-2372096300 -15408 0 CMT} {-1567453392 -14400 0 -04} - {-1233432000 -10800 0 -03} + {-1233432000 -10800 0 -04} {-1222981200 -14400 0 -04} - {-1205956800 -10800 1 -03} + {-1205956800 -10800 1 -04} {-1194037200 -14400 0 -04} - {-1172865600 -10800 1 -03} + {-1172865600 -10800 1 -04} {-1162501200 -14400 0 -04} - {-1141329600 -10800 1 -03} + {-1141329600 -10800 1 -04} {-1130965200 -14400 0 -04} - {-1109793600 -10800 1 -03} + {-1109793600 -10800 1 -04} {-1099429200 -14400 0 -04} - {-1078257600 -10800 1 -03} + {-1078257600 -10800 1 -04} {-1067806800 -14400 0 -04} - {-1046635200 -10800 1 -03} + {-1046635200 -10800 1 -04} {-1036270800 -14400 0 -04} - {-1015099200 -10800 1 -03} + {-1015099200 -10800 1 -04} {-1004734800 -14400 0 -04} - {-983563200 -10800 1 -03} + {-983563200 -10800 1 -04} {-973198800 -14400 0 -04} - {-952027200 -10800 1 -03} + {-952027200 -10800 1 -04} {-941576400 -14400 0 -04} - {-931032000 -10800 1 -03} + {-931032000 -10800 1 -04} {-900882000 -14400 0 -04} - {-890337600 -10800 1 -03} + {-890337600 -10800 1 -04} {-833749200 -14400 0 -04} - {-827265600 -10800 1 -03} + {-827265600 -10800 1 -04} {-752274000 -14400 0 -04} - {-733780800 -10800 1 -03} + {-733780800 -10800 1 -04} {-197326800 -14400 0 -04} - {-190843200 -10800 1 -03} + {-190843200 -10800 1 -04} {-184194000 -14400 0 -04} - {-164491200 -10800 1 -03} + {-164491200 -10800 1 -04} {-152658000 -14400 0 -04} - {-132955200 -10800 1 -03} + {-132955200 -10800 1 -04} {-121122000 -14400 0 -04} - {-101419200 -10800 1 -03} + {-101419200 -10800 1 -04} {-86821200 -14400 0 -04} - {-71092800 -10800 1 -03} + {-71092800 -10800 1 -04} {-54766800 -14400 0 -04} - {-39038400 -10800 1 -03} + {-39038400 -10800 1 -04} {-23317200 -14400 0 -04} {-7588800 -10800 0 -03} - {128142000 -7200 1 -02} + {128142000 -7200 1 -03} {136605600 -10800 0 -03} - {596948400 -7200 1 -02} + {596948400 -7200 1 -03} {605066400 -10800 0 -03} - {624423600 -7200 1 -02} + {624423600 -7200 1 -03} {636516000 -10800 0 -03} - {656478000 -7200 1 -02} + {656478000 -7200 1 -03} {667965600 -14400 0 -04} - {687931200 -7200 0 -02} + {687931200 -7200 0 -03} {699415200 -10800 0 -03} - {719377200 -7200 1 -02} + {719377200 -7200 1 -03} {731469600 -10800 0 -03} {938916000 -10800 0 -04} - {938919600 -10800 1 -03} + {938919600 -10800 1 -04} {952056000 -10800 0 -03} - {1198983600 -7200 1 -02} + {1198983600 -7200 1 -03} {1205632800 -10800 0 -03} {1224295200 -10800 0 -03} } diff --git a/library/tzdata/America/Argentina/San_Juan b/library/tzdata/America/Argentina/San_Juan index 1f0530a..d67f688 100644 --- a/library/tzdata/America/Argentina/San_Juan +++ b/library/tzdata/America/Argentina/San_Juan @@ -4,66 +4,66 @@ set TZData(:America/Argentina/San_Juan) { {-9223372036854775808 -16444 0 LMT} {-2372095556 -15408 0 CMT} {-1567453392 -14400 0 -04} - {-1233432000 -10800 0 -03} + {-1233432000 -10800 0 -04} {-1222981200 -14400 0 -04} - {-1205956800 -10800 1 -03} + {-1205956800 -10800 1 -04} {-1194037200 -14400 0 -04} - {-1172865600 -10800 1 -03} + {-1172865600 -10800 1 -04} {-1162501200 -14400 0 -04} - {-1141329600 -10800 1 -03} + {-1141329600 -10800 1 -04} {-1130965200 -14400 0 -04} - {-1109793600 -10800 1 -03} + {-1109793600 -10800 1 -04} {-1099429200 -14400 0 -04} - {-1078257600 -10800 1 -03} + {-1078257600 -10800 1 -04} {-1067806800 -14400 0 -04} - {-1046635200 -10800 1 -03} + {-1046635200 -10800 1 -04} {-1036270800 -14400 0 -04} - {-1015099200 -10800 1 -03} + {-1015099200 -10800 1 -04} {-1004734800 -14400 0 -04} - {-983563200 -10800 1 -03} + {-983563200 -10800 1 -04} {-973198800 -14400 0 -04} - {-952027200 -10800 1 -03} + {-952027200 -10800 1 -04} {-941576400 -14400 0 -04} - {-931032000 -10800 1 -03} + {-931032000 -10800 1 -04} {-900882000 -14400 0 -04} - {-890337600 -10800 1 -03} + {-890337600 -10800 1 -04} {-833749200 -14400 0 -04} - {-827265600 -10800 1 -03} + {-827265600 -10800 1 -04} {-752274000 -14400 0 -04} - {-733780800 -10800 1 -03} + {-733780800 -10800 1 -04} {-197326800 -14400 0 -04} - {-190843200 -10800 1 -03} + {-190843200 -10800 1 -04} {-184194000 -14400 0 -04} - {-164491200 -10800 1 -03} + {-164491200 -10800 1 -04} {-152658000 -14400 0 -04} - {-132955200 -10800 1 -03} + {-132955200 -10800 1 -04} {-121122000 -14400 0 -04} - {-101419200 -10800 1 -03} + {-101419200 -10800 1 -04} {-86821200 -14400 0 -04} - {-71092800 -10800 1 -03} + {-71092800 -10800 1 -04} {-54766800 -14400 0 -04} - {-39038400 -10800 1 -03} + {-39038400 -10800 1 -04} {-23317200 -14400 0 -04} {-7588800 -10800 0 -03} - {128142000 -7200 1 -02} + {128142000 -7200 1 -03} {136605600 -10800 0 -03} - {596948400 -7200 1 -02} + {596948400 -7200 1 -03} {605066400 -10800 0 -03} - {624423600 -7200 1 -02} + {624423600 -7200 1 -03} {636516000 -10800 0 -03} - {656478000 -7200 1 -02} + {656478000 -7200 1 -03} {667792800 -14400 0 -04} {673588800 -10800 0 -03} - {687927600 -7200 1 -02} + {687927600 -7200 1 -03} {699415200 -10800 0 -03} - {719377200 -7200 1 -02} + {719377200 -7200 1 -03} {731469600 -10800 0 -03} {938916000 -10800 0 -04} - {938919600 -10800 1 -03} + {938919600 -10800 1 -04} {952056000 -10800 0 -03} {1085972400 -14400 0 -04} {1090728000 -10800 0 -03} - {1198983600 -7200 1 -02} + {1198983600 -7200 1 -03} {1205632800 -10800 0 -03} {1224295200 -10800 0 -03} } diff --git a/library/tzdata/America/Argentina/San_Luis b/library/tzdata/America/Argentina/San_Luis index 3583a39..4d27c32 100644 --- a/library/tzdata/America/Argentina/San_Luis +++ b/library/tzdata/America/Argentina/San_Luis @@ -4,52 +4,52 @@ set TZData(:America/Argentina/San_Luis) { {-9223372036854775808 -15924 0 LMT} {-2372096076 -15408 0 CMT} {-1567453392 -14400 0 -04} - {-1233432000 -10800 0 -03} + {-1233432000 -10800 0 -04} {-1222981200 -14400 0 -04} - {-1205956800 -10800 1 -03} + {-1205956800 -10800 1 -04} {-1194037200 -14400 0 -04} - {-1172865600 -10800 1 -03} + {-1172865600 -10800 1 -04} {-1162501200 -14400 0 -04} - {-1141329600 -10800 1 -03} + {-1141329600 -10800 1 -04} {-1130965200 -14400 0 -04} - {-1109793600 -10800 1 -03} + {-1109793600 -10800 1 -04} {-1099429200 -14400 0 -04} - {-1078257600 -10800 1 -03} + {-1078257600 -10800 1 -04} {-1067806800 -14400 0 -04} - {-1046635200 -10800 1 -03} + {-1046635200 -10800 1 -04} {-1036270800 -14400 0 -04} - {-1015099200 -10800 1 -03} + {-1015099200 -10800 1 -04} {-1004734800 -14400 0 -04} - {-983563200 -10800 1 -03} + {-983563200 -10800 1 -04} {-973198800 -14400 0 -04} - {-952027200 -10800 1 -03} + {-952027200 -10800 1 -04} {-941576400 -14400 0 -04} - {-931032000 -10800 1 -03} + {-931032000 -10800 1 -04} {-900882000 -14400 0 -04} - {-890337600 -10800 1 -03} + {-890337600 -10800 1 -04} {-833749200 -14400 0 -04} - {-827265600 -10800 1 -03} + {-827265600 -10800 1 -04} {-752274000 -14400 0 -04} - {-733780800 -10800 1 -03} + {-733780800 -10800 1 -04} {-197326800 -14400 0 -04} - {-190843200 -10800 1 -03} + {-190843200 -10800 1 -04} {-184194000 -14400 0 -04} - {-164491200 -10800 1 -03} + {-164491200 -10800 1 -04} {-152658000 -14400 0 -04} - {-132955200 -10800 1 -03} + {-132955200 -10800 1 -04} {-121122000 -14400 0 -04} - {-101419200 -10800 1 -03} + {-101419200 -10800 1 -04} {-86821200 -14400 0 -04} - {-71092800 -10800 1 -03} + {-71092800 -10800 1 -04} {-54766800 -14400 0 -04} - {-39038400 -10800 1 -03} + {-39038400 -10800 1 -04} {-23317200 -14400 0 -04} {-7588800 -10800 0 -03} - {128142000 -7200 1 -02} + {128142000 -7200 1 -03} {136605600 -10800 0 -03} - {596948400 -7200 1 -02} + {596948400 -7200 1 -03} {605066400 -10800 0 -03} - {624423600 -7200 1 -02} + {624423600 -7200 1 -03} {631159200 -7200 1 -02} {637380000 -14400 0 -04} {655963200 -10800 1 -03} @@ -59,10 +59,10 @@ set TZData(:America/Argentina/San_Luis) { {952052400 -10800 0 -03} {1085972400 -14400 0 -04} {1090728000 -10800 0 -03} - {1198983600 -7200 1 -02} + {1198983600 -7200 1 -03} {1200880800 -10800 0 -04} {1205031600 -14400 0 -04} - {1223784000 -10800 1 -03} + {1223784000 -10800 1 -04} {1236481200 -14400 0 -04} {1255233600 -10800 0 -03} } diff --git a/library/tzdata/America/Argentina/Tucuman b/library/tzdata/America/Argentina/Tucuman index 15c5c63..6809800 100644 --- a/library/tzdata/America/Argentina/Tucuman +++ b/library/tzdata/America/Argentina/Tucuman @@ -4,66 +4,66 @@ set TZData(:America/Argentina/Tucuman) { {-9223372036854775808 -15652 0 LMT} {-2372096348 -15408 0 CMT} {-1567453392 -14400 0 -04} - {-1233432000 -10800 0 -03} + {-1233432000 -10800 0 -04} {-1222981200 -14400 0 -04} - {-1205956800 -10800 1 -03} + {-1205956800 -10800 1 -04} {-1194037200 -14400 0 -04} - {-1172865600 -10800 1 -03} + {-1172865600 -10800 1 -04} {-1162501200 -14400 0 -04} - {-1141329600 -10800 1 -03} + {-1141329600 -10800 1 -04} {-1130965200 -14400 0 -04} - {-1109793600 -10800 1 -03} + {-1109793600 -10800 1 -04} {-1099429200 -14400 0 -04} - {-1078257600 -10800 1 -03} + {-1078257600 -10800 1 -04} {-1067806800 -14400 0 -04} - {-1046635200 -10800 1 -03} + {-1046635200 -10800 1 -04} {-1036270800 -14400 0 -04} - {-1015099200 -10800 1 -03} + {-1015099200 -10800 1 -04} {-1004734800 -14400 0 -04} - {-983563200 -10800 1 -03} + {-983563200 -10800 1 -04} {-973198800 -14400 0 -04} - {-952027200 -10800 1 -03} + {-952027200 -10800 1 -04} {-941576400 -14400 0 -04} - {-931032000 -10800 1 -03} + {-931032000 -10800 1 -04} {-900882000 -14400 0 -04} - {-890337600 -10800 1 -03} + {-890337600 -10800 1 -04} {-833749200 -14400 0 -04} - {-827265600 -10800 1 -03} + {-827265600 -10800 1 -04} {-752274000 -14400 0 -04} - {-733780800 -10800 1 -03} + {-733780800 -10800 1 -04} {-197326800 -14400 0 -04} - {-190843200 -10800 1 -03} + {-190843200 -10800 1 -04} {-184194000 -14400 0 -04} - {-164491200 -10800 1 -03} + {-164491200 -10800 1 -04} {-152658000 -14400 0 -04} - {-132955200 -10800 1 -03} + {-132955200 -10800 1 -04} {-121122000 -14400 0 -04} - {-101419200 -10800 1 -03} + {-101419200 -10800 1 -04} {-86821200 -14400 0 -04} - {-71092800 -10800 1 -03} + {-71092800 -10800 1 -04} {-54766800 -14400 0 -04} - {-39038400 -10800 1 -03} + {-39038400 -10800 1 -04} {-23317200 -14400 0 -04} {-7588800 -10800 0 -03} - {128142000 -7200 1 -02} + {128142000 -7200 1 -03} {136605600 -10800 0 -03} - {596948400 -7200 1 -02} + {596948400 -7200 1 -03} {605066400 -10800 0 -03} - {624423600 -7200 1 -02} + {624423600 -7200 1 -03} {636516000 -10800 0 -03} - {656478000 -7200 1 -02} + {656478000 -7200 1 -03} {667965600 -14400 0 -04} - {687931200 -7200 0 -02} + {687931200 -7200 0 -03} {699415200 -10800 0 -03} - {719377200 -7200 1 -02} + {719377200 -7200 1 -03} {731469600 -10800 0 -03} {938916000 -10800 0 -04} - {938919600 -10800 1 -03} + {938919600 -10800 1 -04} {952056000 -10800 0 -03} {1086058800 -14400 0 -04} {1087099200 -10800 0 -03} - {1198983600 -7200 1 -02} + {1198983600 -7200 1 -03} {1205632800 -10800 0 -03} - {1224385200 -7200 1 -02} + {1224385200 -7200 1 -03} {1237082400 -10800 0 -03} } diff --git a/library/tzdata/America/Argentina/Ushuaia b/library/tzdata/America/Argentina/Ushuaia index 4214c1d..c62ca0d 100644 --- a/library/tzdata/America/Argentina/Ushuaia +++ b/library/tzdata/America/Argentina/Ushuaia @@ -4,65 +4,65 @@ set TZData(:America/Argentina/Ushuaia) { {-9223372036854775808 -16392 0 LMT} {-2372095608 -15408 0 CMT} {-1567453392 -14400 0 -04} - {-1233432000 -10800 0 -03} + {-1233432000 -10800 0 -04} {-1222981200 -14400 0 -04} - {-1205956800 -10800 1 -03} + {-1205956800 -10800 1 -04} {-1194037200 -14400 0 -04} - {-1172865600 -10800 1 -03} + {-1172865600 -10800 1 -04} {-1162501200 -14400 0 -04} - {-1141329600 -10800 1 -03} + {-1141329600 -10800 1 -04} {-1130965200 -14400 0 -04} - {-1109793600 -10800 1 -03} + {-1109793600 -10800 1 -04} {-1099429200 -14400 0 -04} - {-1078257600 -10800 1 -03} + {-1078257600 -10800 1 -04} {-1067806800 -14400 0 -04} - {-1046635200 -10800 1 -03} + {-1046635200 -10800 1 -04} {-1036270800 -14400 0 -04} - {-1015099200 -10800 1 -03} + {-1015099200 -10800 1 -04} {-1004734800 -14400 0 -04} - {-983563200 -10800 1 -03} + {-983563200 -10800 1 -04} {-973198800 -14400 0 -04} - {-952027200 -10800 1 -03} + {-952027200 -10800 1 -04} {-941576400 -14400 0 -04} - {-931032000 -10800 1 -03} + {-931032000 -10800 1 -04} {-900882000 -14400 0 -04} - {-890337600 -10800 1 -03} + {-890337600 -10800 1 -04} {-833749200 -14400 0 -04} - {-827265600 -10800 1 -03} + {-827265600 -10800 1 -04} {-752274000 -14400 0 -04} - {-733780800 -10800 1 -03} + {-733780800 -10800 1 -04} {-197326800 -14400 0 -04} - {-190843200 -10800 1 -03} + {-190843200 -10800 1 -04} {-184194000 -14400 0 -04} - {-164491200 -10800 1 -03} + {-164491200 -10800 1 -04} {-152658000 -14400 0 -04} - {-132955200 -10800 1 -03} + {-132955200 -10800 1 -04} {-121122000 -14400 0 -04} - {-101419200 -10800 1 -03} + {-101419200 -10800 1 -04} {-86821200 -14400 0 -04} - {-71092800 -10800 1 -03} + {-71092800 -10800 1 -04} {-54766800 -14400 0 -04} - {-39038400 -10800 1 -03} + {-39038400 -10800 1 -04} {-23317200 -14400 0 -04} {-7588800 -10800 0 -03} - {128142000 -7200 1 -02} + {128142000 -7200 1 -03} {136605600 -10800 0 -03} - {596948400 -7200 1 -02} + {596948400 -7200 1 -03} {605066400 -10800 0 -03} - {624423600 -7200 1 -02} + {624423600 -7200 1 -03} {636516000 -10800 0 -03} - {656478000 -7200 1 -02} + {656478000 -7200 1 -03} {667965600 -10800 0 -03} - {687927600 -7200 1 -02} + {687927600 -7200 1 -03} {699415200 -10800 0 -03} - {719377200 -7200 1 -02} + {719377200 -7200 1 -03} {731469600 -10800 0 -03} {938916000 -10800 0 -04} - {938919600 -10800 1 -03} + {938919600 -10800 1 -04} {952056000 -10800 0 -03} {1085886000 -14400 0 -04} {1087704000 -10800 0 -03} - {1198983600 -7200 1 -02} + {1198983600 -7200 1 -03} {1205632800 -10800 0 -03} {1224295200 -10800 0 -03} } diff --git a/library/tzdata/America/Asuncion b/library/tzdata/America/Asuncion index 606db57..8e6c1b0 100644 --- a/library/tzdata/America/Asuncion +++ b/library/tzdata/America/Asuncion @@ -7,253 +7,253 @@ set TZData(:America/Asuncion) { {86760000 -10800 0 -03} {134017200 -14400 0 -04} {162878400 -14400 0 -04} - {181368000 -10800 1 -03} + {181368000 -10800 1 -04} {194497200 -14400 0 -04} - {212990400 -10800 1 -03} + {212990400 -10800 1 -04} {226033200 -14400 0 -04} - {244526400 -10800 1 -03} + {244526400 -10800 1 -04} {257569200 -14400 0 -04} - {276062400 -10800 1 -03} + {276062400 -10800 1 -04} {291783600 -14400 0 -04} - {307598400 -10800 1 -03} + {307598400 -10800 1 -04} {323406000 -14400 0 -04} - {339220800 -10800 1 -03} + {339220800 -10800 1 -04} {354942000 -14400 0 -04} - {370756800 -10800 1 -03} + {370756800 -10800 1 -04} {386478000 -14400 0 -04} - {402292800 -10800 1 -03} + {402292800 -10800 1 -04} {418014000 -14400 0 -04} - {433828800 -10800 1 -03} + {433828800 -10800 1 -04} {449636400 -14400 0 -04} - {465451200 -10800 1 -03} + {465451200 -10800 1 -04} {481172400 -14400 0 -04} - {496987200 -10800 1 -03} + {496987200 -10800 1 -04} {512708400 -14400 0 -04} - {528523200 -10800 1 -03} + {528523200 -10800 1 -04} {544244400 -14400 0 -04} - {560059200 -10800 1 -03} + {560059200 -10800 1 -04} {575866800 -14400 0 -04} - {591681600 -10800 1 -03} + {591681600 -10800 1 -04} {607402800 -14400 0 -04} - {625032000 -10800 1 -03} + {625032000 -10800 1 -04} {638938800 -14400 0 -04} - {654753600 -10800 1 -03} + {654753600 -10800 1 -04} {670474800 -14400 0 -04} - {686721600 -10800 1 -03} + {686721600 -10800 1 -04} {699418800 -14400 0 -04} - {718257600 -10800 1 -03} + {718257600 -10800 1 -04} {733546800 -14400 0 -04} - {749448000 -10800 1 -03} + {749448000 -10800 1 -04} {762318000 -14400 0 -04} - {780984000 -10800 1 -03} + {780984000 -10800 1 -04} {793767600 -14400 0 -04} - {812520000 -10800 1 -03} + {812520000 -10800 1 -04} {825649200 -14400 0 -04} - {844574400 -10800 1 -03} + {844574400 -10800 1 -04} {856666800 -14400 0 -04} - {876024000 -10800 1 -03} + {876024000 -10800 1 -04} {888721200 -14400 0 -04} - {907473600 -10800 1 -03} + {907473600 -10800 1 -04} {920775600 -14400 0 -04} - {938923200 -10800 1 -03} + {938923200 -10800 1 -04} {952225200 -14400 0 -04} - {970372800 -10800 1 -03} + {970372800 -10800 1 -04} {983674800 -14400 0 -04} - {1002427200 -10800 1 -03} + {1002427200 -10800 1 -04} {1018148400 -14400 0 -04} - {1030852800 -10800 1 -03} + {1030852800 -10800 1 -04} {1049598000 -14400 0 -04} - {1062907200 -10800 1 -03} + {1062907200 -10800 1 -04} {1081047600 -14400 0 -04} - {1097985600 -10800 1 -03} + {1097985600 -10800 1 -04} {1110682800 -14400 0 -04} - {1129435200 -10800 1 -03} + {1129435200 -10800 1 -04} {1142132400 -14400 0 -04} - {1160884800 -10800 1 -03} + {1160884800 -10800 1 -04} {1173582000 -14400 0 -04} - {1192939200 -10800 1 -03} + {1192939200 -10800 1 -04} {1205031600 -14400 0 -04} - {1224388800 -10800 1 -03} + {1224388800 -10800 1 -04} {1236481200 -14400 0 -04} - {1255838400 -10800 1 -03} + {1255838400 -10800 1 -04} {1270954800 -14400 0 -04} - {1286078400 -10800 1 -03} + {1286078400 -10800 1 -04} {1302404400 -14400 0 -04} - {1317528000 -10800 1 -03} + {1317528000 -10800 1 -04} {1333854000 -14400 0 -04} - {1349582400 -10800 1 -03} + {1349582400 -10800 1 -04} {1364094000 -14400 0 -04} - {1381032000 -10800 1 -03} + {1381032000 -10800 1 -04} {1395543600 -14400 0 -04} - {1412481600 -10800 1 -03} + {1412481600 -10800 1 -04} {1426993200 -14400 0 -04} - {1443931200 -10800 1 -03} + {1443931200 -10800 1 -04} {1459047600 -14400 0 -04} - {1475380800 -10800 1 -03} + {1475380800 -10800 1 -04} {1490497200 -14400 0 -04} - {1506830400 -10800 1 -03} + {1506830400 -10800 1 -04} {1521946800 -14400 0 -04} - {1538884800 -10800 1 -03} + {1538884800 -10800 1 -04} {1553396400 -14400 0 -04} - {1570334400 -10800 1 -03} + {1570334400 -10800 1 -04} {1584846000 -14400 0 -04} - {1601784000 -10800 1 -03} + {1601784000 -10800 1 -04} {1616900400 -14400 0 -04} - {1633233600 -10800 1 -03} + {1633233600 -10800 1 -04} {1648350000 -14400 0 -04} - {1664683200 -10800 1 -03} + {1664683200 -10800 1 -04} {1679799600 -14400 0 -04} - {1696132800 -10800 1 -03} + {1696132800 -10800 1 -04} {1711249200 -14400 0 -04} - {1728187200 -10800 1 -03} + {1728187200 -10800 1 -04} {1742698800 -14400 0 -04} - {1759636800 -10800 1 -03} + {1759636800 -10800 1 -04} {1774148400 -14400 0 -04} - {1791086400 -10800 1 -03} + {1791086400 -10800 1 -04} {1806202800 -14400 0 -04} - {1822536000 -10800 1 -03} + {1822536000 -10800 1 -04} {1837652400 -14400 0 -04} - {1853985600 -10800 1 -03} + {1853985600 -10800 1 -04} {1869102000 -14400 0 -04} - {1886040000 -10800 1 -03} + {1886040000 -10800 1 -04} {1900551600 -14400 0 -04} - {1917489600 -10800 1 -03} + {1917489600 -10800 1 -04} {1932001200 -14400 0 -04} - {1948939200 -10800 1 -03} + {1948939200 -10800 1 -04} {1964055600 -14400 0 -04} - {1980388800 -10800 1 -03} + {1980388800 -10800 1 -04} {1995505200 -14400 0 -04} - {2011838400 -10800 1 -03} + {2011838400 -10800 1 -04} {2026954800 -14400 0 -04} - {2043288000 -10800 1 -03} + {2043288000 -10800 1 -04} {2058404400 -14400 0 -04} - {2075342400 -10800 1 -03} + {2075342400 -10800 1 -04} {2089854000 -14400 0 -04} - {2106792000 -10800 1 -03} + {2106792000 -10800 1 -04} {2121303600 -14400 0 -04} - {2138241600 -10800 1 -03} + {2138241600 -10800 1 -04} {2153358000 -14400 0 -04} - {2169691200 -10800 1 -03} + {2169691200 -10800 1 -04} {2184807600 -14400 0 -04} - {2201140800 -10800 1 -03} + {2201140800 -10800 1 -04} {2216257200 -14400 0 -04} - {2233195200 -10800 1 -03} + {2233195200 -10800 1 -04} {2247706800 -14400 0 -04} - {2264644800 -10800 1 -03} + {2264644800 -10800 1 -04} {2279156400 -14400 0 -04} - {2296094400 -10800 1 -03} + {2296094400 -10800 1 -04} {2310606000 -14400 0 -04} - {2327544000 -10800 1 -03} + {2327544000 -10800 1 -04} {2342660400 -14400 0 -04} - {2358993600 -10800 1 -03} + {2358993600 -10800 1 -04} {2374110000 -14400 0 -04} - {2390443200 -10800 1 -03} + {2390443200 -10800 1 -04} {2405559600 -14400 0 -04} - {2422497600 -10800 1 -03} + {2422497600 -10800 1 -04} {2437009200 -14400 0 -04} - {2453947200 -10800 1 -03} + {2453947200 -10800 1 -04} {2468458800 -14400 0 -04} - {2485396800 -10800 1 -03} + {2485396800 -10800 1 -04} {2500513200 -14400 0 -04} - {2516846400 -10800 1 -03} + {2516846400 -10800 1 -04} {2531962800 -14400 0 -04} - {2548296000 -10800 1 -03} + {2548296000 -10800 1 -04} {2563412400 -14400 0 -04} - {2579745600 -10800 1 -03} + {2579745600 -10800 1 -04} {2594862000 -14400 0 -04} - {2611800000 -10800 1 -03} + {2611800000 -10800 1 -04} {2626311600 -14400 0 -04} - {2643249600 -10800 1 -03} + {2643249600 -10800 1 -04} {2657761200 -14400 0 -04} - {2674699200 -10800 1 -03} + {2674699200 -10800 1 -04} {2689815600 -14400 0 -04} - {2706148800 -10800 1 -03} + {2706148800 -10800 1 -04} {2721265200 -14400 0 -04} - {2737598400 -10800 1 -03} + {2737598400 -10800 1 -04} {2752714800 -14400 0 -04} - {2769652800 -10800 1 -03} + {2769652800 -10800 1 -04} {2784164400 -14400 0 -04} - {2801102400 -10800 1 -03} + {2801102400 -10800 1 -04} {2815614000 -14400 0 -04} - {2832552000 -10800 1 -03} + {2832552000 -10800 1 -04} {2847668400 -14400 0 -04} - {2864001600 -10800 1 -03} + {2864001600 -10800 1 -04} {2879118000 -14400 0 -04} - {2895451200 -10800 1 -03} + {2895451200 -10800 1 -04} {2910567600 -14400 0 -04} - {2926900800 -10800 1 -03} + {2926900800 -10800 1 -04} {2942017200 -14400 0 -04} - {2958955200 -10800 1 -03} + {2958955200 -10800 1 -04} {2973466800 -14400 0 -04} - {2990404800 -10800 1 -03} + {2990404800 -10800 1 -04} {3004916400 -14400 0 -04} - {3021854400 -10800 1 -03} + {3021854400 -10800 1 -04} {3036970800 -14400 0 -04} - {3053304000 -10800 1 -03} + {3053304000 -10800 1 -04} {3068420400 -14400 0 -04} - {3084753600 -10800 1 -03} + {3084753600 -10800 1 -04} {3099870000 -14400 0 -04} - {3116808000 -10800 1 -03} + {3116808000 -10800 1 -04} {3131319600 -14400 0 -04} - {3148257600 -10800 1 -03} + {3148257600 -10800 1 -04} {3162769200 -14400 0 -04} - {3179707200 -10800 1 -03} + {3179707200 -10800 1 -04} {3194218800 -14400 0 -04} - {3211156800 -10800 1 -03} + {3211156800 -10800 1 -04} {3226273200 -14400 0 -04} - {3242606400 -10800 1 -03} + {3242606400 -10800 1 -04} {3257722800 -14400 0 -04} - {3274056000 -10800 1 -03} + {3274056000 -10800 1 -04} {3289172400 -14400 0 -04} - {3306110400 -10800 1 -03} + {3306110400 -10800 1 -04} {3320622000 -14400 0 -04} - {3337560000 -10800 1 -03} + {3337560000 -10800 1 -04} {3352071600 -14400 0 -04} - {3369009600 -10800 1 -03} + {3369009600 -10800 1 -04} {3384126000 -14400 0 -04} - {3400459200 -10800 1 -03} + {3400459200 -10800 1 -04} {3415575600 -14400 0 -04} - {3431908800 -10800 1 -03} + {3431908800 -10800 1 -04} {3447025200 -14400 0 -04} - {3463358400 -10800 1 -03} + {3463358400 -10800 1 -04} {3478474800 -14400 0 -04} - {3495412800 -10800 1 -03} + {3495412800 -10800 1 -04} {3509924400 -14400 0 -04} - {3526862400 -10800 1 -03} + {3526862400 -10800 1 -04} {3541374000 -14400 0 -04} - {3558312000 -10800 1 -03} + {3558312000 -10800 1 -04} {3573428400 -14400 0 -04} - {3589761600 -10800 1 -03} + {3589761600 -10800 1 -04} {3604878000 -14400 0 -04} - {3621211200 -10800 1 -03} + {3621211200 -10800 1 -04} {3636327600 -14400 0 -04} - {3653265600 -10800 1 -03} + {3653265600 -10800 1 -04} {3667777200 -14400 0 -04} - {3684715200 -10800 1 -03} + {3684715200 -10800 1 -04} {3699226800 -14400 0 -04} - {3716164800 -10800 1 -03} + {3716164800 -10800 1 -04} {3731281200 -14400 0 -04} - {3747614400 -10800 1 -03} + {3747614400 -10800 1 -04} {3762730800 -14400 0 -04} - {3779064000 -10800 1 -03} + {3779064000 -10800 1 -04} {3794180400 -14400 0 -04} - {3810513600 -10800 1 -03} + {3810513600 -10800 1 -04} {3825630000 -14400 0 -04} - {3842568000 -10800 1 -03} + {3842568000 -10800 1 -04} {3857079600 -14400 0 -04} - {3874017600 -10800 1 -03} + {3874017600 -10800 1 -04} {3888529200 -14400 0 -04} - {3905467200 -10800 1 -03} + {3905467200 -10800 1 -04} {3920583600 -14400 0 -04} - {3936916800 -10800 1 -03} + {3936916800 -10800 1 -04} {3952033200 -14400 0 -04} - {3968366400 -10800 1 -03} + {3968366400 -10800 1 -04} {3983482800 -14400 0 -04} - {4000420800 -10800 1 -03} + {4000420800 -10800 1 -04} {4014932400 -14400 0 -04} - {4031870400 -10800 1 -03} + {4031870400 -10800 1 -04} {4046382000 -14400 0 -04} - {4063320000 -10800 1 -03} + {4063320000 -10800 1 -04} {4077831600 -14400 0 -04} - {4094769600 -10800 1 -03} + {4094769600 -10800 1 -04} } diff --git a/library/tzdata/America/Bahia b/library/tzdata/America/Bahia index 7dbcb90..7aaf834 100644 --- a/library/tzdata/America/Bahia +++ b/library/tzdata/America/Bahia @@ -3,66 +3,66 @@ set TZData(:America/Bahia) { {-9223372036854775808 -9244 0 LMT} {-1767216356 -10800 0 -03} - {-1206957600 -7200 1 -02} + {-1206957600 -7200 1 -03} {-1191362400 -10800 0 -03} - {-1175374800 -7200 1 -02} + {-1175374800 -7200 1 -03} {-1159826400 -10800 0 -03} - {-633819600 -7200 1 -02} + {-633819600 -7200 1 -03} {-622069200 -10800 0 -03} - {-602283600 -7200 1 -02} + {-602283600 -7200 1 -03} {-591832800 -10800 0 -03} - {-570747600 -7200 1 -02} + {-570747600 -7200 1 -03} {-560210400 -10800 0 -03} - {-539125200 -7200 1 -02} + {-539125200 -7200 1 -03} {-531352800 -10800 0 -03} - {-191365200 -7200 1 -02} + {-191365200 -7200 1 -03} {-184197600 -10800 0 -03} - {-155163600 -7200 1 -02} + {-155163600 -7200 1 -03} {-150069600 -10800 0 -03} - {-128898000 -7200 1 -02} + {-128898000 -7200 1 -03} {-121125600 -10800 0 -03} - {-99954000 -7200 1 -02} + {-99954000 -7200 1 -03} {-89589600 -10800 0 -03} - {-68418000 -7200 1 -02} + {-68418000 -7200 1 -03} {-57967200 -10800 0 -03} - {499748400 -7200 1 -02} + {499748400 -7200 1 -03} {511236000 -10800 0 -03} - {530593200 -7200 1 -02} + {530593200 -7200 1 -03} {540266400 -10800 0 -03} - {562129200 -7200 1 -02} + {562129200 -7200 1 -03} {571197600 -10800 0 -03} - {592974000 -7200 1 -02} + {592974000 -7200 1 -03} {602042400 -10800 0 -03} - {624423600 -7200 1 -02} + {624423600 -7200 1 -03} {634701600 -10800 0 -03} - {656478000 -7200 1 -02} + {656478000 -7200 1 -03} {666756000 -10800 0 -03} - {687927600 -7200 1 -02} + {687927600 -7200 1 -03} {697600800 -10800 0 -03} - {719982000 -7200 1 -02} + {719982000 -7200 1 -03} {728445600 -10800 0 -03} - {750826800 -7200 1 -02} + {750826800 -7200 1 -03} {761709600 -10800 0 -03} - {782276400 -7200 1 -02} + {782276400 -7200 1 -03} {793159200 -10800 0 -03} - {813726000 -7200 1 -02} + {813726000 -7200 1 -03} {824004000 -10800 0 -03} - {844570800 -7200 1 -02} + {844570800 -7200 1 -03} {856058400 -10800 0 -03} - {876106800 -7200 1 -02} + {876106800 -7200 1 -03} {888717600 -10800 0 -03} - {908074800 -7200 1 -02} + {908074800 -7200 1 -03} {919562400 -10800 0 -03} - {938919600 -7200 1 -02} + {938919600 -7200 1 -03} {951616800 -10800 0 -03} - {970974000 -7200 1 -02} + {970974000 -7200 1 -03} {982461600 -10800 0 -03} - {1003028400 -7200 1 -02} + {1003028400 -7200 1 -03} {1013911200 -10800 0 -03} - {1036292400 -7200 1 -02} + {1036292400 -7200 1 -03} {1045360800 -10800 0 -03} {1064368800 -10800 0 -03} - {1318734000 -7200 0 -02} + {1318734000 -7200 0 -03} {1330221600 -10800 0 -03} {1350784800 -10800 0 -03} } diff --git a/library/tzdata/America/Belem b/library/tzdata/America/Belem index b2bf3a6..42a3ec5 100644 --- a/library/tzdata/America/Belem +++ b/library/tzdata/America/Belem @@ -3,33 +3,33 @@ set TZData(:America/Belem) { {-9223372036854775808 -11636 0 LMT} {-1767213964 -10800 0 -03} - {-1206957600 -7200 1 -02} + {-1206957600 -7200 1 -03} {-1191362400 -10800 0 -03} - {-1175374800 -7200 1 -02} + {-1175374800 -7200 1 -03} {-1159826400 -10800 0 -03} - {-633819600 -7200 1 -02} + {-633819600 -7200 1 -03} {-622069200 -10800 0 -03} - {-602283600 -7200 1 -02} + {-602283600 -7200 1 -03} {-591832800 -10800 0 -03} - {-570747600 -7200 1 -02} + {-570747600 -7200 1 -03} {-560210400 -10800 0 -03} - {-539125200 -7200 1 -02} + {-539125200 -7200 1 -03} {-531352800 -10800 0 -03} - {-191365200 -7200 1 -02} + {-191365200 -7200 1 -03} {-184197600 -10800 0 -03} - {-155163600 -7200 1 -02} + {-155163600 -7200 1 -03} {-150069600 -10800 0 -03} - {-128898000 -7200 1 -02} + {-128898000 -7200 1 -03} {-121125600 -10800 0 -03} - {-99954000 -7200 1 -02} + {-99954000 -7200 1 -03} {-89589600 -10800 0 -03} - {-68418000 -7200 1 -02} + {-68418000 -7200 1 -03} {-57967200 -10800 0 -03} - {499748400 -7200 1 -02} + {499748400 -7200 1 -03} {511236000 -10800 0 -03} - {530593200 -7200 1 -02} + {530593200 -7200 1 -03} {540266400 -10800 0 -03} - {562129200 -7200 1 -02} + {562129200 -7200 1 -03} {571197600 -10800 0 -03} {590032800 -10800 0 -03} } diff --git a/library/tzdata/America/Boa_Vista b/library/tzdata/America/Boa_Vista index 982249b..0af989e 100644 --- a/library/tzdata/America/Boa_Vista +++ b/library/tzdata/America/Boa_Vista @@ -3,38 +3,38 @@ set TZData(:America/Boa_Vista) { {-9223372036854775808 -14560 0 LMT} {-1767211040 -14400 0 -04} - {-1206954000 -10800 1 -03} + {-1206954000 -10800 1 -04} {-1191358800 -14400 0 -04} - {-1175371200 -10800 1 -03} + {-1175371200 -10800 1 -04} {-1159822800 -14400 0 -04} - {-633816000 -10800 1 -03} + {-633816000 -10800 1 -04} {-622065600 -14400 0 -04} - {-602280000 -10800 1 -03} + {-602280000 -10800 1 -04} {-591829200 -14400 0 -04} - {-570744000 -10800 1 -03} + {-570744000 -10800 1 -04} {-560206800 -14400 0 -04} - {-539121600 -10800 1 -03} + {-539121600 -10800 1 -04} {-531349200 -14400 0 -04} - {-191361600 -10800 1 -03} + {-191361600 -10800 1 -04} {-184194000 -14400 0 -04} - {-155160000 -10800 1 -03} + {-155160000 -10800 1 -04} {-150066000 -14400 0 -04} - {-128894400 -10800 1 -03} + {-128894400 -10800 1 -04} {-121122000 -14400 0 -04} - {-99950400 -10800 1 -03} + {-99950400 -10800 1 -04} {-89586000 -14400 0 -04} - {-68414400 -10800 1 -03} + {-68414400 -10800 1 -04} {-57963600 -14400 0 -04} - {499752000 -10800 1 -03} + {499752000 -10800 1 -04} {511239600 -14400 0 -04} - {530596800 -10800 1 -03} + {530596800 -10800 1 -04} {540270000 -14400 0 -04} - {562132800 -10800 1 -03} + {562132800 -10800 1 -04} {571201200 -14400 0 -04} {590036400 -14400 0 -04} {938664000 -14400 0 -04} - {938923200 -10800 1 -03} + {938923200 -10800 1 -04} {951620400 -14400 0 -04} - {970977600 -10800 1 -03} + {970977600 -10800 1 -04} {971578800 -14400 0 -04} } diff --git a/library/tzdata/America/Bogota b/library/tzdata/America/Bogota index 69e4557..8ca39ba 100644 --- a/library/tzdata/America/Bogota +++ b/library/tzdata/America/Bogota @@ -4,6 +4,6 @@ set TZData(:America/Bogota) { {-9223372036854775808 -17776 0 LMT} {-2707671824 -17776 0 BMT} {-1739041424 -18000 0 -05} - {704869200 -14400 1 -04} + {704869200 -14400 1 -05} {733896000 -18000 0 -05} } diff --git a/library/tzdata/America/Campo_Grande b/library/tzdata/America/Campo_Grande index f8bfb67..5ec7112 100644 --- a/library/tzdata/America/Campo_Grande +++ b/library/tzdata/America/Campo_Grande @@ -3,255 +3,255 @@ set TZData(:America/Campo_Grande) { {-9223372036854775808 -13108 0 LMT} {-1767212492 -14400 0 -04} - {-1206954000 -10800 1 -03} + {-1206954000 -10800 1 -04} {-1191358800 -14400 0 -04} - {-1175371200 -10800 1 -03} + {-1175371200 -10800 1 -04} {-1159822800 -14400 0 -04} - {-633816000 -10800 1 -03} + {-633816000 -10800 1 -04} {-622065600 -14400 0 -04} - {-602280000 -10800 1 -03} + {-602280000 -10800 1 -04} {-591829200 -14400 0 -04} - {-570744000 -10800 1 -03} + {-570744000 -10800 1 -04} {-560206800 -14400 0 -04} - {-539121600 -10800 1 -03} + {-539121600 -10800 1 -04} {-531349200 -14400 0 -04} - {-191361600 -10800 1 -03} + {-191361600 -10800 1 -04} {-184194000 -14400 0 -04} - {-155160000 -10800 1 -03} + {-155160000 -10800 1 -04} {-150066000 -14400 0 -04} - {-128894400 -10800 1 -03} + {-128894400 -10800 1 -04} {-121122000 -14400 0 -04} - {-99950400 -10800 1 -03} + {-99950400 -10800 1 -04} {-89586000 -14400 0 -04} - {-68414400 -10800 1 -03} + {-68414400 -10800 1 -04} {-57963600 -14400 0 -04} - {499752000 -10800 1 -03} + {499752000 -10800 1 -04} {511239600 -14400 0 -04} - {530596800 -10800 1 -03} + {530596800 -10800 1 -04} {540270000 -14400 0 -04} - {562132800 -10800 1 -03} + {562132800 -10800 1 -04} {571201200 -14400 0 -04} - {592977600 -10800 1 -03} + {592977600 -10800 1 -04} {602046000 -14400 0 -04} - {624427200 -10800 1 -03} + {624427200 -10800 1 -04} {634705200 -14400 0 -04} - {656481600 -10800 1 -03} + {656481600 -10800 1 -04} {666759600 -14400 0 -04} - {687931200 -10800 1 -03} + {687931200 -10800 1 -04} {697604400 -14400 0 -04} - {719985600 -10800 1 -03} + {719985600 -10800 1 -04} {728449200 -14400 0 -04} - {750830400 -10800 1 -03} + {750830400 -10800 1 -04} {761713200 -14400 0 -04} - {782280000 -10800 1 -03} + {782280000 -10800 1 -04} {793162800 -14400 0 -04} - {813729600 -10800 1 -03} + {813729600 -10800 1 -04} {824007600 -14400 0 -04} - {844574400 -10800 1 -03} + {844574400 -10800 1 -04} {856062000 -14400 0 -04} - {876110400 -10800 1 -03} + {876110400 -10800 1 -04} {888721200 -14400 0 -04} - {908078400 -10800 1 -03} + {908078400 -10800 1 -04} {919566000 -14400 0 -04} - {938923200 -10800 1 -03} + {938923200 -10800 1 -04} {951620400 -14400 0 -04} - {970977600 -10800 1 -03} + {970977600 -10800 1 -04} {982465200 -14400 0 -04} - {1003032000 -10800 1 -03} + {1003032000 -10800 1 -04} {1013914800 -14400 0 -04} - {1036296000 -10800 1 -03} + {1036296000 -10800 1 -04} {1045364400 -14400 0 -04} - {1066536000 -10800 1 -03} + {1066536000 -10800 1 -04} {1076814000 -14400 0 -04} - {1099368000 -10800 1 -03} + {1099368000 -10800 1 -04} {1108868400 -14400 0 -04} - {1129435200 -10800 1 -03} + {1129435200 -10800 1 -04} {1140318000 -14400 0 -04} - {1162699200 -10800 1 -03} + {1162699200 -10800 1 -04} {1172372400 -14400 0 -04} - {1192334400 -10800 1 -03} + {1192334400 -10800 1 -04} {1203217200 -14400 0 -04} - {1224388800 -10800 1 -03} + {1224388800 -10800 1 -04} {1234666800 -14400 0 -04} - {1255838400 -10800 1 -03} + {1255838400 -10800 1 -04} {1266721200 -14400 0 -04} - {1287288000 -10800 1 -03} + {1287288000 -10800 1 -04} {1298170800 -14400 0 -04} - {1318737600 -10800 1 -03} + {1318737600 -10800 1 -04} {1330225200 -14400 0 -04} - {1350792000 -10800 1 -03} + {1350792000 -10800 1 -04} {1361070000 -14400 0 -04} - {1382241600 -10800 1 -03} + {1382241600 -10800 1 -04} {1392519600 -14400 0 -04} - {1413691200 -10800 1 -03} + {1413691200 -10800 1 -04} {1424574000 -14400 0 -04} - {1445140800 -10800 1 -03} + {1445140800 -10800 1 -04} {1456023600 -14400 0 -04} - {1476590400 -10800 1 -03} + {1476590400 -10800 1 -04} {1487473200 -14400 0 -04} - {1508040000 -10800 1 -03} + {1508040000 -10800 1 -04} {1518922800 -14400 0 -04} - {1541304000 -10800 1 -03} + {1541304000 -10800 1 -04} {1550372400 -14400 0 -04} - {1572753600 -10800 1 -03} + {1572753600 -10800 1 -04} {1581822000 -14400 0 -04} - {1604203200 -10800 1 -03} + {1604203200 -10800 1 -04} {1613876400 -14400 0 -04} - {1636257600 -10800 1 -03} + {1636257600 -10800 1 -04} {1645326000 -14400 0 -04} - {1667707200 -10800 1 -03} + {1667707200 -10800 1 -04} {1677380400 -14400 0 -04} - {1699156800 -10800 1 -03} + {1699156800 -10800 1 -04} {1708225200 -14400 0 -04} - {1730606400 -10800 1 -03} + {1730606400 -10800 1 -04} {1739674800 -14400 0 -04} - {1762056000 -10800 1 -03} + {1762056000 -10800 1 -04} {1771729200 -14400 0 -04} - {1793505600 -10800 1 -03} + {1793505600 -10800 1 -04} {1803178800 -14400 0 -04} - {1825560000 -10800 1 -03} + {1825560000 -10800 1 -04} {1834628400 -14400 0 -04} - {1857009600 -10800 1 -03} + {1857009600 -10800 1 -04} {1866078000 -14400 0 -04} - {1888459200 -10800 1 -03} + {1888459200 -10800 1 -04} {1897527600 -14400 0 -04} - {1919908800 -10800 1 -03} + {1919908800 -10800 1 -04} {1928977200 -14400 0 -04} - {1951358400 -10800 1 -03} + {1951358400 -10800 1 -04} {1960426800 -14400 0 -04} - {1983412800 -10800 1 -03} + {1983412800 -10800 1 -04} {1992481200 -14400 0 -04} - {2014862400 -10800 1 -03} + {2014862400 -10800 1 -04} {2024535600 -14400 0 -04} - {2046312000 -10800 1 -03} + {2046312000 -10800 1 -04} {2055380400 -14400 0 -04} - {2077761600 -10800 1 -03} + {2077761600 -10800 1 -04} {2086830000 -14400 0 -04} - {2109211200 -10800 1 -03} + {2109211200 -10800 1 -04} {2118884400 -14400 0 -04} - {2140660800 -10800 1 -03} + {2140660800 -10800 1 -04} {2150334000 -14400 0 -04} - {2172715200 -10800 1 -03} + {2172715200 -10800 1 -04} {2181783600 -14400 0 -04} - {2204164800 -10800 1 -03} + {2204164800 -10800 1 -04} {2213233200 -14400 0 -04} - {2235614400 -10800 1 -03} + {2235614400 -10800 1 -04} {2244682800 -14400 0 -04} - {2267064000 -10800 1 -03} + {2267064000 -10800 1 -04} {2276132400 -14400 0 -04} - {2298513600 -10800 1 -03} + {2298513600 -10800 1 -04} {2307582000 -14400 0 -04} - {2329963200 -10800 1 -03} + {2329963200 -10800 1 -04} {2339636400 -14400 0 -04} - {2362017600 -10800 1 -03} + {2362017600 -10800 1 -04} {2371086000 -14400 0 -04} - {2393467200 -10800 1 -03} + {2393467200 -10800 1 -04} {2402535600 -14400 0 -04} - {2424916800 -10800 1 -03} + {2424916800 -10800 1 -04} {2433985200 -14400 0 -04} - {2456366400 -10800 1 -03} + {2456366400 -10800 1 -04} {2465434800 -14400 0 -04} - {2487816000 -10800 1 -03} + {2487816000 -10800 1 -04} {2497489200 -14400 0 -04} - {2519870400 -10800 1 -03} + {2519870400 -10800 1 -04} {2528938800 -14400 0 -04} - {2551320000 -10800 1 -03} + {2551320000 -10800 1 -04} {2560388400 -14400 0 -04} - {2582769600 -10800 1 -03} + {2582769600 -10800 1 -04} {2591838000 -14400 0 -04} - {2614219200 -10800 1 -03} + {2614219200 -10800 1 -04} {2623287600 -14400 0 -04} - {2645668800 -10800 1 -03} + {2645668800 -10800 1 -04} {2654737200 -14400 0 -04} - {2677118400 -10800 1 -03} + {2677118400 -10800 1 -04} {2686791600 -14400 0 -04} - {2709172800 -10800 1 -03} + {2709172800 -10800 1 -04} {2718241200 -14400 0 -04} - {2740622400 -10800 1 -03} + {2740622400 -10800 1 -04} {2749690800 -14400 0 -04} - {2772072000 -10800 1 -03} + {2772072000 -10800 1 -04} {2781140400 -14400 0 -04} - {2803521600 -10800 1 -03} + {2803521600 -10800 1 -04} {2812590000 -14400 0 -04} - {2834971200 -10800 1 -03} + {2834971200 -10800 1 -04} {2844039600 -14400 0 -04} - {2867025600 -10800 1 -03} + {2867025600 -10800 1 -04} {2876094000 -14400 0 -04} - {2898475200 -10800 1 -03} + {2898475200 -10800 1 -04} {2907543600 -14400 0 -04} - {2929924800 -10800 1 -03} + {2929924800 -10800 1 -04} {2938993200 -14400 0 -04} - {2961374400 -10800 1 -03} + {2961374400 -10800 1 -04} {2970442800 -14400 0 -04} - {2992824000 -10800 1 -03} + {2992824000 -10800 1 -04} {3001892400 -14400 0 -04} - {3024273600 -10800 1 -03} + {3024273600 -10800 1 -04} {3033946800 -14400 0 -04} - {3056328000 -10800 1 -03} + {3056328000 -10800 1 -04} {3065396400 -14400 0 -04} - {3087777600 -10800 1 -03} + {3087777600 -10800 1 -04} {3096846000 -14400 0 -04} - {3119227200 -10800 1 -03} + {3119227200 -10800 1 -04} {3128295600 -14400 0 -04} - {3150676800 -10800 1 -03} + {3150676800 -10800 1 -04} {3159745200 -14400 0 -04} - {3182126400 -10800 1 -03} + {3182126400 -10800 1 -04} {3191194800 -14400 0 -04} - {3213576000 -10800 1 -03} + {3213576000 -10800 1 -04} {3223249200 -14400 0 -04} - {3245630400 -10800 1 -03} + {3245630400 -10800 1 -04} {3254698800 -14400 0 -04} - {3277080000 -10800 1 -03} + {3277080000 -10800 1 -04} {3286148400 -14400 0 -04} - {3308529600 -10800 1 -03} + {3308529600 -10800 1 -04} {3317598000 -14400 0 -04} - {3339979200 -10800 1 -03} + {3339979200 -10800 1 -04} {3349047600 -14400 0 -04} - {3371428800 -10800 1 -03} + {3371428800 -10800 1 -04} {3381102000 -14400 0 -04} - {3403483200 -10800 1 -03} + {3403483200 -10800 1 -04} {3412551600 -14400 0 -04} - {3434932800 -10800 1 -03} + {3434932800 -10800 1 -04} {3444001200 -14400 0 -04} - {3466382400 -10800 1 -03} + {3466382400 -10800 1 -04} {3475450800 -14400 0 -04} - {3497832000 -10800 1 -03} + {3497832000 -10800 1 -04} {3506900400 -14400 0 -04} - {3529281600 -10800 1 -03} + {3529281600 -10800 1 -04} {3538350000 -14400 0 -04} - {3560731200 -10800 1 -03} + {3560731200 -10800 1 -04} {3570404400 -14400 0 -04} - {3592785600 -10800 1 -03} + {3592785600 -10800 1 -04} {3601854000 -14400 0 -04} - {3624235200 -10800 1 -03} + {3624235200 -10800 1 -04} {3633303600 -14400 0 -04} - {3655684800 -10800 1 -03} + {3655684800 -10800 1 -04} {3664753200 -14400 0 -04} - {3687134400 -10800 1 -03} + {3687134400 -10800 1 -04} {3696202800 -14400 0 -04} - {3718584000 -10800 1 -03} + {3718584000 -10800 1 -04} {3727652400 -14400 0 -04} - {3750638400 -10800 1 -03} + {3750638400 -10800 1 -04} {3759706800 -14400 0 -04} - {3782088000 -10800 1 -03} + {3782088000 -10800 1 -04} {3791156400 -14400 0 -04} - {3813537600 -10800 1 -03} + {3813537600 -10800 1 -04} {3822606000 -14400 0 -04} - {3844987200 -10800 1 -03} + {3844987200 -10800 1 -04} {3854055600 -14400 0 -04} - {3876436800 -10800 1 -03} + {3876436800 -10800 1 -04} {3885505200 -14400 0 -04} - {3907886400 -10800 1 -03} + {3907886400 -10800 1 -04} {3917559600 -14400 0 -04} - {3939940800 -10800 1 -03} + {3939940800 -10800 1 -04} {3949009200 -14400 0 -04} - {3971390400 -10800 1 -03} + {3971390400 -10800 1 -04} {3980458800 -14400 0 -04} - {4002840000 -10800 1 -03} + {4002840000 -10800 1 -04} {4011908400 -14400 0 -04} - {4034289600 -10800 1 -03} + {4034289600 -10800 1 -04} {4043358000 -14400 0 -04} - {4065739200 -10800 1 -03} + {4065739200 -10800 1 -04} {4074807600 -14400 0 -04} - {4097188800 -10800 1 -03} + {4097188800 -10800 1 -04} } diff --git a/library/tzdata/America/Cuiaba b/library/tzdata/America/Cuiaba index 69acddb..09f5b1f 100644 --- a/library/tzdata/America/Cuiaba +++ b/library/tzdata/America/Cuiaba @@ -3,255 +3,255 @@ set TZData(:America/Cuiaba) { {-9223372036854775808 -13460 0 LMT} {-1767212140 -14400 0 -04} - {-1206954000 -10800 1 -03} + {-1206954000 -10800 1 -04} {-1191358800 -14400 0 -04} - {-1175371200 -10800 1 -03} + {-1175371200 -10800 1 -04} {-1159822800 -14400 0 -04} - {-633816000 -10800 1 -03} + {-633816000 -10800 1 -04} {-622065600 -14400 0 -04} - {-602280000 -10800 1 -03} + {-602280000 -10800 1 -04} {-591829200 -14400 0 -04} - {-570744000 -10800 1 -03} + {-570744000 -10800 1 -04} {-560206800 -14400 0 -04} - {-539121600 -10800 1 -03} + {-539121600 -10800 1 -04} {-531349200 -14400 0 -04} - {-191361600 -10800 1 -03} + {-191361600 -10800 1 -04} {-184194000 -14400 0 -04} - {-155160000 -10800 1 -03} + {-155160000 -10800 1 -04} {-150066000 -14400 0 -04} - {-128894400 -10800 1 -03} + {-128894400 -10800 1 -04} {-121122000 -14400 0 -04} - {-99950400 -10800 1 -03} + {-99950400 -10800 1 -04} {-89586000 -14400 0 -04} - {-68414400 -10800 1 -03} + {-68414400 -10800 1 -04} {-57963600 -14400 0 -04} - {499752000 -10800 1 -03} + {499752000 -10800 1 -04} {511239600 -14400 0 -04} - {530596800 -10800 1 -03} + {530596800 -10800 1 -04} {540270000 -14400 0 -04} - {562132800 -10800 1 -03} + {562132800 -10800 1 -04} {571201200 -14400 0 -04} - {592977600 -10800 1 -03} + {592977600 -10800 1 -04} {602046000 -14400 0 -04} - {624427200 -10800 1 -03} + {624427200 -10800 1 -04} {634705200 -14400 0 -04} - {656481600 -10800 1 -03} + {656481600 -10800 1 -04} {666759600 -14400 0 -04} - {687931200 -10800 1 -03} + {687931200 -10800 1 -04} {697604400 -14400 0 -04} - {719985600 -10800 1 -03} + {719985600 -10800 1 -04} {728449200 -14400 0 -04} - {750830400 -10800 1 -03} + {750830400 -10800 1 -04} {761713200 -14400 0 -04} - {782280000 -10800 1 -03} + {782280000 -10800 1 -04} {793162800 -14400 0 -04} - {813729600 -10800 1 -03} + {813729600 -10800 1 -04} {824007600 -14400 0 -04} - {844574400 -10800 1 -03} + {844574400 -10800 1 -04} {856062000 -14400 0 -04} - {876110400 -10800 1 -03} + {876110400 -10800 1 -04} {888721200 -14400 0 -04} - {908078400 -10800 1 -03} + {908078400 -10800 1 -04} {919566000 -14400 0 -04} - {938923200 -10800 1 -03} + {938923200 -10800 1 -04} {951620400 -14400 0 -04} - {970977600 -10800 1 -03} + {970977600 -10800 1 -04} {982465200 -14400 0 -04} - {1003032000 -10800 1 -03} + {1003032000 -10800 1 -04} {1013914800 -14400 0 -04} - {1036296000 -10800 1 -03} + {1036296000 -10800 1 -04} {1045364400 -14400 0 -04} {1064372400 -14400 0 -04} {1096603200 -14400 0 -04} - {1099368000 -10800 1 -03} + {1099368000 -10800 1 -04} {1108868400 -14400 0 -04} - {1129435200 -10800 1 -03} + {1129435200 -10800 1 -04} {1140318000 -14400 0 -04} - {1162699200 -10800 1 -03} + {1162699200 -10800 1 -04} {1172372400 -14400 0 -04} - {1192334400 -10800 1 -03} + {1192334400 -10800 1 -04} {1203217200 -14400 0 -04} - {1224388800 -10800 1 -03} + {1224388800 -10800 1 -04} {1234666800 -14400 0 -04} - {1255838400 -10800 1 -03} + {1255838400 -10800 1 -04} {1266721200 -14400 0 -04} - {1287288000 -10800 1 -03} + {1287288000 -10800 1 -04} {1298170800 -14400 0 -04} - {1318737600 -10800 1 -03} + {1318737600 -10800 1 -04} {1330225200 -14400 0 -04} - {1350792000 -10800 1 -03} + {1350792000 -10800 1 -04} {1361070000 -14400 0 -04} - {1382241600 -10800 1 -03} + {1382241600 -10800 1 -04} {1392519600 -14400 0 -04} - {1413691200 -10800 1 -03} + {1413691200 -10800 1 -04} {1424574000 -14400 0 -04} - {1445140800 -10800 1 -03} + {1445140800 -10800 1 -04} {1456023600 -14400 0 -04} - {1476590400 -10800 1 -03} + {1476590400 -10800 1 -04} {1487473200 -14400 0 -04} - {1508040000 -10800 1 -03} + {1508040000 -10800 1 -04} {1518922800 -14400 0 -04} - {1541304000 -10800 1 -03} + {1541304000 -10800 1 -04} {1550372400 -14400 0 -04} - {1572753600 -10800 1 -03} + {1572753600 -10800 1 -04} {1581822000 -14400 0 -04} - {1604203200 -10800 1 -03} + {1604203200 -10800 1 -04} {1613876400 -14400 0 -04} - {1636257600 -10800 1 -03} + {1636257600 -10800 1 -04} {1645326000 -14400 0 -04} - {1667707200 -10800 1 -03} + {1667707200 -10800 1 -04} {1677380400 -14400 0 -04} - {1699156800 -10800 1 -03} + {1699156800 -10800 1 -04} {1708225200 -14400 0 -04} - {1730606400 -10800 1 -03} + {1730606400 -10800 1 -04} {1739674800 -14400 0 -04} - {1762056000 -10800 1 -03} + {1762056000 -10800 1 -04} {1771729200 -14400 0 -04} - {1793505600 -10800 1 -03} + {1793505600 -10800 1 -04} {1803178800 -14400 0 -04} - {1825560000 -10800 1 -03} + {1825560000 -10800 1 -04} {1834628400 -14400 0 -04} - {1857009600 -10800 1 -03} + {1857009600 -10800 1 -04} {1866078000 -14400 0 -04} - {1888459200 -10800 1 -03} + {1888459200 -10800 1 -04} {1897527600 -14400 0 -04} - {1919908800 -10800 1 -03} + {1919908800 -10800 1 -04} {1928977200 -14400 0 -04} - {1951358400 -10800 1 -03} + {1951358400 -10800 1 -04} {1960426800 -14400 0 -04} - {1983412800 -10800 1 -03} + {1983412800 -10800 1 -04} {1992481200 -14400 0 -04} - {2014862400 -10800 1 -03} + {2014862400 -10800 1 -04} {2024535600 -14400 0 -04} - {2046312000 -10800 1 -03} + {2046312000 -10800 1 -04} {2055380400 -14400 0 -04} - {2077761600 -10800 1 -03} + {2077761600 -10800 1 -04} {2086830000 -14400 0 -04} - {2109211200 -10800 1 -03} + {2109211200 -10800 1 -04} {2118884400 -14400 0 -04} - {2140660800 -10800 1 -03} + {2140660800 -10800 1 -04} {2150334000 -14400 0 -04} - {2172715200 -10800 1 -03} + {2172715200 -10800 1 -04} {2181783600 -14400 0 -04} - {2204164800 -10800 1 -03} + {2204164800 -10800 1 -04} {2213233200 -14400 0 -04} - {2235614400 -10800 1 -03} + {2235614400 -10800 1 -04} {2244682800 -14400 0 -04} - {2267064000 -10800 1 -03} + {2267064000 -10800 1 -04} {2276132400 -14400 0 -04} - {2298513600 -10800 1 -03} + {2298513600 -10800 1 -04} {2307582000 -14400 0 -04} - {2329963200 -10800 1 -03} + {2329963200 -10800 1 -04} {2339636400 -14400 0 -04} - {2362017600 -10800 1 -03} + {2362017600 -10800 1 -04} {2371086000 -14400 0 -04} - {2393467200 -10800 1 -03} + {2393467200 -10800 1 -04} {2402535600 -14400 0 -04} - {2424916800 -10800 1 -03} + {2424916800 -10800 1 -04} {2433985200 -14400 0 -04} - {2456366400 -10800 1 -03} + {2456366400 -10800 1 -04} {2465434800 -14400 0 -04} - {2487816000 -10800 1 -03} + {2487816000 -10800 1 -04} {2497489200 -14400 0 -04} - {2519870400 -10800 1 -03} + {2519870400 -10800 1 -04} {2528938800 -14400 0 -04} - {2551320000 -10800 1 -03} + {2551320000 -10800 1 -04} {2560388400 -14400 0 -04} - {2582769600 -10800 1 -03} + {2582769600 -10800 1 -04} {2591838000 -14400 0 -04} - {2614219200 -10800 1 -03} + {2614219200 -10800 1 -04} {2623287600 -14400 0 -04} - {2645668800 -10800 1 -03} + {2645668800 -10800 1 -04} {2654737200 -14400 0 -04} - {2677118400 -10800 1 -03} + {2677118400 -10800 1 -04} {2686791600 -14400 0 -04} - {2709172800 -10800 1 -03} + {2709172800 -10800 1 -04} {2718241200 -14400 0 -04} - {2740622400 -10800 1 -03} + {2740622400 -10800 1 -04} {2749690800 -14400 0 -04} - {2772072000 -10800 1 -03} + {2772072000 -10800 1 -04} {2781140400 -14400 0 -04} - {2803521600 -10800 1 -03} + {2803521600 -10800 1 -04} {2812590000 -14400 0 -04} - {2834971200 -10800 1 -03} + {2834971200 -10800 1 -04} {2844039600 -14400 0 -04} - {2867025600 -10800 1 -03} + {2867025600 -10800 1 -04} {2876094000 -14400 0 -04} - {2898475200 -10800 1 -03} + {2898475200 -10800 1 -04} {2907543600 -14400 0 -04} - {2929924800 -10800 1 -03} + {2929924800 -10800 1 -04} {2938993200 -14400 0 -04} - {2961374400 -10800 1 -03} + {2961374400 -10800 1 -04} {2970442800 -14400 0 -04} - {2992824000 -10800 1 -03} + {2992824000 -10800 1 -04} {3001892400 -14400 0 -04} - {3024273600 -10800 1 -03} + {3024273600 -10800 1 -04} {3033946800 -14400 0 -04} - {3056328000 -10800 1 -03} + {3056328000 -10800 1 -04} {3065396400 -14400 0 -04} - {3087777600 -10800 1 -03} + {3087777600 -10800 1 -04} {3096846000 -14400 0 -04} - {3119227200 -10800 1 -03} + {3119227200 -10800 1 -04} {3128295600 -14400 0 -04} - {3150676800 -10800 1 -03} + {3150676800 -10800 1 -04} {3159745200 -14400 0 -04} - {3182126400 -10800 1 -03} + {3182126400 -10800 1 -04} {3191194800 -14400 0 -04} - {3213576000 -10800 1 -03} + {3213576000 -10800 1 -04} {3223249200 -14400 0 -04} - {3245630400 -10800 1 -03} + {3245630400 -10800 1 -04} {3254698800 -14400 0 -04} - {3277080000 -10800 1 -03} + {3277080000 -10800 1 -04} {3286148400 -14400 0 -04} - {3308529600 -10800 1 -03} + {3308529600 -10800 1 -04} {3317598000 -14400 0 -04} - {3339979200 -10800 1 -03} + {3339979200 -10800 1 -04} {3349047600 -14400 0 -04} - {3371428800 -10800 1 -03} + {3371428800 -10800 1 -04} {3381102000 -14400 0 -04} - {3403483200 -10800 1 -03} + {3403483200 -10800 1 -04} {3412551600 -14400 0 -04} - {3434932800 -10800 1 -03} + {3434932800 -10800 1 -04} {3444001200 -14400 0 -04} - {3466382400 -10800 1 -03} + {3466382400 -10800 1 -04} {3475450800 -14400 0 -04} - {3497832000 -10800 1 -03} + {3497832000 -10800 1 -04} {3506900400 -14400 0 -04} - {3529281600 -10800 1 -03} + {3529281600 -10800 1 -04} {3538350000 -14400 0 -04} - {3560731200 -10800 1 -03} + {3560731200 -10800 1 -04} {3570404400 -14400 0 -04} - {3592785600 -10800 1 -03} + {3592785600 -10800 1 -04} {3601854000 -14400 0 -04} - {3624235200 -10800 1 -03} + {3624235200 -10800 1 -04} {3633303600 -14400 0 -04} - {3655684800 -10800 1 -03} + {3655684800 -10800 1 -04} {3664753200 -14400 0 -04} - {3687134400 -10800 1 -03} + {3687134400 -10800 1 -04} {3696202800 -14400 0 -04} - {3718584000 -10800 1 -03} + {3718584000 -10800 1 -04} {3727652400 -14400 0 -04} - {3750638400 -10800 1 -03} + {3750638400 -10800 1 -04} {3759706800 -14400 0 -04} - {3782088000 -10800 1 -03} + {3782088000 -10800 1 -04} {3791156400 -14400 0 -04} - {3813537600 -10800 1 -03} + {3813537600 -10800 1 -04} {3822606000 -14400 0 -04} - {3844987200 -10800 1 -03} + {3844987200 -10800 1 -04} {3854055600 -14400 0 -04} - {3876436800 -10800 1 -03} + {3876436800 -10800 1 -04} {3885505200 -14400 0 -04} - {3907886400 -10800 1 -03} + {3907886400 -10800 1 -04} {3917559600 -14400 0 -04} - {3939940800 -10800 1 -03} + {3939940800 -10800 1 -04} {3949009200 -14400 0 -04} - {3971390400 -10800 1 -03} + {3971390400 -10800 1 -04} {3980458800 -14400 0 -04} - {4002840000 -10800 1 -03} + {4002840000 -10800 1 -04} {4011908400 -14400 0 -04} - {4034289600 -10800 1 -03} + {4034289600 -10800 1 -04} {4043358000 -14400 0 -04} - {4065739200 -10800 1 -03} + {4065739200 -10800 1 -04} {4074807600 -14400 0 -04} - {4097188800 -10800 1 -03} + {4097188800 -10800 1 -04} } diff --git a/library/tzdata/America/Eirunepe b/library/tzdata/America/Eirunepe index 41b4cc9..a81b09e 100644 --- a/library/tzdata/America/Eirunepe +++ b/library/tzdata/America/Eirunepe @@ -3,37 +3,37 @@ set TZData(:America/Eirunepe) { {-9223372036854775808 -16768 0 LMT} {-1767208832 -18000 0 -05} - {-1206950400 -14400 1 -04} + {-1206950400 -14400 1 -05} {-1191355200 -18000 0 -05} - {-1175367600 -14400 1 -04} + {-1175367600 -14400 1 -05} {-1159819200 -18000 0 -05} - {-633812400 -14400 1 -04} + {-633812400 -14400 1 -05} {-622062000 -18000 0 -05} - {-602276400 -14400 1 -04} + {-602276400 -14400 1 -05} {-591825600 -18000 0 -05} - {-570740400 -14400 1 -04} + {-570740400 -14400 1 -05} {-560203200 -18000 0 -05} - {-539118000 -14400 1 -04} + {-539118000 -14400 1 -05} {-531345600 -18000 0 -05} - {-191358000 -14400 1 -04} + {-191358000 -14400 1 -05} {-184190400 -18000 0 -05} - {-155156400 -14400 1 -04} + {-155156400 -14400 1 -05} {-150062400 -18000 0 -05} - {-128890800 -14400 1 -04} + {-128890800 -14400 1 -05} {-121118400 -18000 0 -05} - {-99946800 -14400 1 -04} + {-99946800 -14400 1 -05} {-89582400 -18000 0 -05} - {-68410800 -14400 1 -04} + {-68410800 -14400 1 -05} {-57960000 -18000 0 -05} - {499755600 -14400 1 -04} + {499755600 -14400 1 -05} {511243200 -18000 0 -05} - {530600400 -14400 1 -04} + {530600400 -14400 1 -05} {540273600 -18000 0 -05} - {562136400 -14400 1 -04} + {562136400 -14400 1 -05} {571204800 -18000 0 -05} {590040000 -18000 0 -05} {749192400 -18000 0 -05} - {750834000 -14400 1 -04} + {750834000 -14400 1 -05} {761716800 -18000 0 -05} {780206400 -18000 0 -05} {1214283600 -14400 0 -04} diff --git a/library/tzdata/America/Fortaleza b/library/tzdata/America/Fortaleza index 06c7b84..bd806f1 100644 --- a/library/tzdata/America/Fortaleza +++ b/library/tzdata/America/Fortaleza @@ -3,46 +3,46 @@ set TZData(:America/Fortaleza) { {-9223372036854775808 -9240 0 LMT} {-1767216360 -10800 0 -03} - {-1206957600 -7200 1 -02} + {-1206957600 -7200 1 -03} {-1191362400 -10800 0 -03} - {-1175374800 -7200 1 -02} + {-1175374800 -7200 1 -03} {-1159826400 -10800 0 -03} - {-633819600 -7200 1 -02} + {-633819600 -7200 1 -03} {-622069200 -10800 0 -03} - {-602283600 -7200 1 -02} + {-602283600 -7200 1 -03} {-591832800 -10800 0 -03} - {-570747600 -7200 1 -02} + {-570747600 -7200 1 -03} {-560210400 -10800 0 -03} - {-539125200 -7200 1 -02} + {-539125200 -7200 1 -03} {-531352800 -10800 0 -03} - {-191365200 -7200 1 -02} + {-191365200 -7200 1 -03} {-184197600 -10800 0 -03} - {-155163600 -7200 1 -02} + {-155163600 -7200 1 -03} {-150069600 -10800 0 -03} - {-128898000 -7200 1 -02} + {-128898000 -7200 1 -03} {-121125600 -10800 0 -03} - {-99954000 -7200 1 -02} + {-99954000 -7200 1 -03} {-89589600 -10800 0 -03} - {-68418000 -7200 1 -02} + {-68418000 -7200 1 -03} {-57967200 -10800 0 -03} - {499748400 -7200 1 -02} + {499748400 -7200 1 -03} {511236000 -10800 0 -03} - {530593200 -7200 1 -02} + {530593200 -7200 1 -03} {540266400 -10800 0 -03} - {562129200 -7200 1 -02} + {562129200 -7200 1 -03} {571197600 -10800 0 -03} - {592974000 -7200 1 -02} + {592974000 -7200 1 -03} {602042400 -10800 0 -03} - {624423600 -7200 1 -02} + {624423600 -7200 1 -03} {634701600 -10800 0 -03} {653536800 -10800 0 -03} {938660400 -10800 0 -03} - {938919600 -7200 1 -02} + {938919600 -7200 1 -03} {951616800 -10800 0 -03} - {970974000 -7200 1 -02} + {970974000 -7200 1 -03} {972180000 -10800 0 -03} {1000350000 -10800 0 -03} - {1003028400 -7200 1 -02} + {1003028400 -7200 1 -03} {1013911200 -10800 0 -03} {1033437600 -10800 0 -03} } diff --git a/library/tzdata/America/Grand_Turk b/library/tzdata/America/Grand_Turk index c963adc..da5f09b 100644 --- a/library/tzdata/America/Grand_Turk +++ b/library/tzdata/America/Grand_Turk @@ -2,8 +2,8 @@ set TZData(:America/Grand_Turk) { {-9223372036854775808 -17072 0 LMT} - {-2524504528 -18431 0 KMT} - {-1827687169 -18000 0 EST} + {-2524504528 -18430 0 KMT} + {-1827687170 -18000 0 EST} {284014800 -18000 0 EST} {294217200 -14400 1 EDT} {309938400 -18000 0 EST} diff --git a/library/tzdata/America/Guayaquil b/library/tzdata/America/Guayaquil index 353eb69..6ba7b93 100644 --- a/library/tzdata/America/Guayaquil +++ b/library/tzdata/America/Guayaquil @@ -4,6 +4,6 @@ set TZData(:America/Guayaquil) { {-9223372036854775808 -19160 0 LMT} {-2524502440 -18840 0 QMT} {-1230749160 -18000 0 -05} - {722926800 -14400 1 -04} + {722926800 -14400 1 -05} {728884800 -18000 0 -05} } diff --git a/library/tzdata/America/Jamaica b/library/tzdata/America/Jamaica index f752842..0f758bd 100644 --- a/library/tzdata/America/Jamaica +++ b/library/tzdata/America/Jamaica @@ -1,9 +1,9 @@ # created by tools/tclZIC.tcl - do not edit set TZData(:America/Jamaica) { - {-9223372036854775808 -18431 0 LMT} - {-2524503169 -18431 0 KMT} - {-1827687169 -18000 0 EST} + {-9223372036854775808 -18430 0 LMT} + {-2524503170 -18430 0 KMT} + {-1827687170 -18000 0 EST} {126248400 -18000 0 EST} {126687600 -14400 1 EDT} {152085600 -18000 0 EST} diff --git a/library/tzdata/America/Lima b/library/tzdata/America/Lima index b224a64..e8b69d6 100644 --- a/library/tzdata/America/Lima +++ b/library/tzdata/America/Lima @@ -3,11 +3,11 @@ set TZData(:America/Lima) { {-9223372036854775808 -18492 0 LMT} {-2524503108 -18516 0 LMT} - {-1938538284 -14400 0 -04} + {-1938538284 -14400 0 -05} {-1002052800 -18000 0 -05} - {-986756400 -14400 1 -04} + {-986756400 -14400 1 -05} {-971035200 -18000 0 -05} - {-955306800 -14400 1 -04} + {-955306800 -14400 1 -05} {-939585600 -18000 0 -05} {512712000 -18000 0 -05} {544248000 -18000 0 -05} diff --git a/library/tzdata/America/Maceio b/library/tzdata/America/Maceio index e6ed548..eab534e 100644 --- a/library/tzdata/America/Maceio +++ b/library/tzdata/America/Maceio @@ -3,50 +3,50 @@ set TZData(:America/Maceio) { {-9223372036854775808 -8572 0 LMT} {-1767217028 -10800 0 -03} - {-1206957600 -7200 1 -02} + {-1206957600 -7200 1 -03} {-1191362400 -10800 0 -03} - {-1175374800 -7200 1 -02} + {-1175374800 -7200 1 -03} {-1159826400 -10800 0 -03} - {-633819600 -7200 1 -02} + {-633819600 -7200 1 -03} {-622069200 -10800 0 -03} - {-602283600 -7200 1 -02} + {-602283600 -7200 1 -03} {-591832800 -10800 0 -03} - {-570747600 -7200 1 -02} + {-570747600 -7200 1 -03} {-560210400 -10800 0 -03} - {-539125200 -7200 1 -02} + {-539125200 -7200 1 -03} {-531352800 -10800 0 -03} - {-191365200 -7200 1 -02} + {-191365200 -7200 1 -03} {-184197600 -10800 0 -03} - {-155163600 -7200 1 -02} + {-155163600 -7200 1 -03} {-150069600 -10800 0 -03} - {-128898000 -7200 1 -02} + {-128898000 -7200 1 -03} {-121125600 -10800 0 -03} - {-99954000 -7200 1 -02} + {-99954000 -7200 1 -03} {-89589600 -10800 0 -03} - {-68418000 -7200 1 -02} + {-68418000 -7200 1 -03} {-57967200 -10800 0 -03} - {499748400 -7200 1 -02} + {499748400 -7200 1 -03} {511236000 -10800 0 -03} - {530593200 -7200 1 -02} + {530593200 -7200 1 -03} {540266400 -10800 0 -03} - {562129200 -7200 1 -02} + {562129200 -7200 1 -03} {571197600 -10800 0 -03} - {592974000 -7200 1 -02} + {592974000 -7200 1 -03} {602042400 -10800 0 -03} - {624423600 -7200 1 -02} + {624423600 -7200 1 -03} {634701600 -10800 0 -03} {653536800 -10800 0 -03} {813553200 -10800 0 -03} - {813726000 -7200 1 -02} + {813726000 -7200 1 -03} {824004000 -10800 0 -03} {841802400 -10800 0 -03} {938660400 -10800 0 -03} - {938919600 -7200 1 -02} + {938919600 -7200 1 -03} {951616800 -10800 0 -03} - {970974000 -7200 1 -02} + {970974000 -7200 1 -03} {972180000 -10800 0 -03} {1000350000 -10800 0 -03} - {1003028400 -7200 1 -02} + {1003028400 -7200 1 -03} {1013911200 -10800 0 -03} {1033437600 -10800 0 -03} } diff --git a/library/tzdata/America/Manaus b/library/tzdata/America/Manaus index f17023c..a855062 100644 --- a/library/tzdata/America/Manaus +++ b/library/tzdata/America/Manaus @@ -3,37 +3,37 @@ set TZData(:America/Manaus) { {-9223372036854775808 -14404 0 LMT} {-1767211196 -14400 0 -04} - {-1206954000 -10800 1 -03} + {-1206954000 -10800 1 -04} {-1191358800 -14400 0 -04} - {-1175371200 -10800 1 -03} + {-1175371200 -10800 1 -04} {-1159822800 -14400 0 -04} - {-633816000 -10800 1 -03} + {-633816000 -10800 1 -04} {-622065600 -14400 0 -04} - {-602280000 -10800 1 -03} + {-602280000 -10800 1 -04} {-591829200 -14400 0 -04} - {-570744000 -10800 1 -03} + {-570744000 -10800 1 -04} {-560206800 -14400 0 -04} - {-539121600 -10800 1 -03} + {-539121600 -10800 1 -04} {-531349200 -14400 0 -04} - {-191361600 -10800 1 -03} + {-191361600 -10800 1 -04} {-184194000 -14400 0 -04} - {-155160000 -10800 1 -03} + {-155160000 -10800 1 -04} {-150066000 -14400 0 -04} - {-128894400 -10800 1 -03} + {-128894400 -10800 1 -04} {-121122000 -14400 0 -04} - {-99950400 -10800 1 -03} + {-99950400 -10800 1 -04} {-89586000 -14400 0 -04} - {-68414400 -10800 1 -03} + {-68414400 -10800 1 -04} {-57963600 -14400 0 -04} - {499752000 -10800 1 -03} + {499752000 -10800 1 -04} {511239600 -14400 0 -04} - {530596800 -10800 1 -03} + {530596800 -10800 1 -04} {540270000 -14400 0 -04} - {562132800 -10800 1 -03} + {562132800 -10800 1 -04} {571201200 -14400 0 -04} {590036400 -14400 0 -04} {749188800 -14400 0 -04} - {750830400 -10800 1 -03} + {750830400 -10800 1 -04} {761713200 -14400 0 -04} {780202800 -14400 0 -04} } diff --git a/library/tzdata/America/Montevideo b/library/tzdata/America/Montevideo index ff85fb3..27fb76e 100644 --- a/library/tzdata/America/Montevideo +++ b/library/tzdata/America/Montevideo @@ -1,96 +1,96 @@ # created by tools/tclZIC.tcl - do not edit set TZData(:America/Montevideo) { - {-9223372036854775808 -13484 0 LMT} - {-2256668116 -13484 0 MMT} - {-1567455316 -12600 0 -0330} - {-1459542600 -10800 1 -03} + {-9223372036854775808 -13491 0 LMT} + {-1942690509 -13491 0 MMT} + {-1567455309 -14400 0 -04} + {-1459627200 -10800 0 -0330} {-1443819600 -12600 0 -0330} - {-1428006600 -10800 1 -03} + {-1428006600 -10800 1 -0330} {-1412283600 -12600 0 -0330} - {-1396470600 -10800 1 -03} + {-1396470600 -10800 1 -0330} {-1380747600 -12600 0 -0330} - {-1141590600 -10800 1 -03} + {-1141590600 -10800 1 -0330} {-1128286800 -12600 0 -0330} - {-1110141000 -10800 1 -03} + {-1110141000 -10800 1 -0330} {-1096837200 -12600 0 -0330} - {-1078691400 -10800 1 -03} + {-1078691400 -10800 1 -0330} {-1065387600 -12600 0 -0330} - {-1046637000 -10800 1 -03} + {-1047241800 -10800 1 -0330} {-1033938000 -12600 0 -0330} - {-1015187400 -10800 1 -03} + {-1015187400 -10800 1 -0330} {-1002488400 -12600 0 -0330} - {-983737800 -10800 1 -03} + {-983737800 -10800 1 -0330} {-971038800 -12600 0 -0330} - {-952288200 -10800 1 -03} + {-954707400 -10800 1 -0330} {-938984400 -12600 0 -0330} - {-920838600 -10800 1 -03} + {-920838600 -10800 1 -0330} {-907534800 -12600 0 -0330} - {-896819400 -10800 1 -03} - {-853623000 -10800 0 -03} - {-853621200 -7200 1 -02} - {-845848800 -10800 0 -03} - {-334789200 -7200 1 -02} - {-319672800 -10800 0 -03} - {-314226000 -7200 1 -02} + {-896819400 -10800 1 -0330} + {-853621200 -9000 0 -03} + {-845847000 -10800 0 -03} + {-334789200 -9000 1 -03} + {-319671000 -10800 0 -03} + {-315608400 -10800 0 -03} + {-314226000 -7200 1 -03} {-309996000 -10800 0 -03} - {-149720400 -7200 1 -02} + {-149720400 -7200 1 -03} {-134604000 -10800 0 -03} - {-118270800 -7200 1 -02} - {-100044000 -10800 0 -03} - {-86821200 -7200 1 -02} - {-68508000 -10800 0 -03} {-63147600 -10800 0 -03} - {-50446800 -9000 1 -0230} - {-34119000 -10800 0 -03} - {-18910800 -9000 1 -0230} - {-2583000 -10800 0 -03} - {12625200 -9000 1 -0230} - {28953000 -10800 0 -03} - {31546800 -10800 0 -03} - {72932400 -7200 1 -02} - {82692000 -10800 0 -03} + {-50446800 -9000 1 -03} + {-34205400 -10800 0 -03} + {10800 -10800 0 -03} + {9860400 -7200 1 -03} + {14176800 -10800 0 -03} + {72846000 -7200 1 -03} + {80100000 -10800 0 -03} {126241200 -10800 0 -03} - {132116400 -9000 1 -0230} - {156909600 -9000 0 -02} - {156911400 -7200 1 -02} - {212983200 -10800 0 -03} - {250052400 -7200 1 -02} - {260244000 -10800 0 -03} - {307594800 -7200 1 -02} - {325994400 -10800 0 -03} - {566449200 -7200 1 -02} - {574308000 -10800 0 -03} - {597812400 -7200 1 -02} - {605671200 -10800 0 -03} - {625633200 -7200 1 -02} - {636516000 -10800 0 -03} - {656478000 -7200 1 -02} + {127278000 -5400 1 -03} + {132112800 -9000 0 -03} + {147234600 -10800 0 -03} + {156909600 -10800 0 -03} + {156913200 -7200 1 -03} + {165376800 -10800 0 -03} + {219812400 -7200 1 -03} + {226461600 -10800 0 -03} + {250052400 -7200 1 -03} + {257911200 -10800 0 -03} + {282711600 -7200 1 -03} + {289360800 -10800 0 -03} + {294202800 -7200 1 -03} + {322020000 -10800 0 -03} + {566449200 -7200 1 -03} + {573012000 -10800 0 -03} + {597812400 -7200 1 -03} + {605066400 -10800 0 -03} + {625633200 -7200 1 -03} + {635911200 -10800 0 -03} + {656478000 -7200 1 -03} {667965600 -10800 0 -03} - {688532400 -7200 1 -02} + {688532400 -7200 1 -03} {699415200 -10800 0 -03} - {719377200 -7200 1 -02} + {719377200 -7200 1 -03} {730864800 -10800 0 -03} - {1095562800 -7200 1 -02} + {1095562800 -7200 1 -03} {1111896000 -10800 0 -03} - {1128834000 -7200 1 -02} + {1128834000 -7200 1 -03} {1142136000 -10800 0 -03} - {1159678800 -7200 1 -02} + {1159678800 -7200 1 -03} {1173585600 -10800 0 -03} - {1191733200 -7200 1 -02} + {1191733200 -7200 1 -03} {1205035200 -10800 0 -03} - {1223182800 -7200 1 -02} + {1223182800 -7200 1 -03} {1236484800 -10800 0 -03} - {1254632400 -7200 1 -02} + {1254632400 -7200 1 -03} {1268539200 -10800 0 -03} - {1286082000 -7200 1 -02} + {1286082000 -7200 1 -03} {1299988800 -10800 0 -03} - {1317531600 -7200 1 -02} + {1317531600 -7200 1 -03} {1331438400 -10800 0 -03} - {1349586000 -7200 1 -02} + {1349586000 -7200 1 -03} {1362888000 -10800 0 -03} - {1381035600 -7200 1 -02} + {1381035600 -7200 1 -03} {1394337600 -10800 0 -03} - {1412485200 -7200 1 -02} + {1412485200 -7200 1 -03} {1425787200 -10800 0 -03} } diff --git a/library/tzdata/America/Noronha b/library/tzdata/America/Noronha index f24b412..01fb745 100644 --- a/library/tzdata/America/Noronha +++ b/library/tzdata/America/Noronha @@ -3,46 +3,46 @@ set TZData(:America/Noronha) { {-9223372036854775808 -7780 0 LMT} {-1767217820 -7200 0 -02} - {-1206961200 -3600 1 -01} + {-1206961200 -3600 1 -02} {-1191366000 -7200 0 -02} - {-1175378400 -3600 1 -01} + {-1175378400 -3600 1 -02} {-1159830000 -7200 0 -02} - {-633823200 -3600 1 -01} + {-633823200 -3600 1 -02} {-622072800 -7200 0 -02} - {-602287200 -3600 1 -01} + {-602287200 -3600 1 -02} {-591836400 -7200 0 -02} - {-570751200 -3600 1 -01} + {-570751200 -3600 1 -02} {-560214000 -7200 0 -02} - {-539128800 -3600 1 -01} + {-539128800 -3600 1 -02} {-531356400 -7200 0 -02} - {-191368800 -3600 1 -01} + {-191368800 -3600 1 -02} {-184201200 -7200 0 -02} - {-155167200 -3600 1 -01} + {-155167200 -3600 1 -02} {-150073200 -7200 0 -02} - {-128901600 -3600 1 -01} + {-128901600 -3600 1 -02} {-121129200 -7200 0 -02} - {-99957600 -3600 1 -01} + {-99957600 -3600 1 -02} {-89593200 -7200 0 -02} - {-68421600 -3600 1 -01} + {-68421600 -3600 1 -02} {-57970800 -7200 0 -02} - {499744800 -3600 1 -01} + {499744800 -3600 1 -02} {511232400 -7200 0 -02} - {530589600 -3600 1 -01} + {530589600 -3600 1 -02} {540262800 -7200 0 -02} - {562125600 -3600 1 -01} + {562125600 -3600 1 -02} {571194000 -7200 0 -02} - {592970400 -3600 1 -01} + {592970400 -3600 1 -02} {602038800 -7200 0 -02} - {624420000 -3600 1 -01} + {624420000 -3600 1 -02} {634698000 -7200 0 -02} {653533200 -7200 0 -02} {938656800 -7200 0 -02} - {938916000 -3600 1 -01} + {938916000 -3600 1 -02} {951613200 -7200 0 -02} - {970970400 -3600 1 -01} + {970970400 -3600 1 -02} {971571600 -7200 0 -02} {1000346400 -7200 0 -02} - {1003024800 -3600 1 -01} + {1003024800 -3600 1 -02} {1013907600 -7200 0 -02} {1033434000 -7200 0 -02} } diff --git a/library/tzdata/America/Porto_Velho b/library/tzdata/America/Porto_Velho index 42566ad..8d7c8fd 100644 --- a/library/tzdata/America/Porto_Velho +++ b/library/tzdata/America/Porto_Velho @@ -3,33 +3,33 @@ set TZData(:America/Porto_Velho) { {-9223372036854775808 -15336 0 LMT} {-1767210264 -14400 0 -04} - {-1206954000 -10800 1 -03} + {-1206954000 -10800 1 -04} {-1191358800 -14400 0 -04} - {-1175371200 -10800 1 -03} + {-1175371200 -10800 1 -04} {-1159822800 -14400 0 -04} - {-633816000 -10800 1 -03} + {-633816000 -10800 1 -04} {-622065600 -14400 0 -04} - {-602280000 -10800 1 -03} + {-602280000 -10800 1 -04} {-591829200 -14400 0 -04} - {-570744000 -10800 1 -03} + {-570744000 -10800 1 -04} {-560206800 -14400 0 -04} - {-539121600 -10800 1 -03} + {-539121600 -10800 1 -04} {-531349200 -14400 0 -04} - {-191361600 -10800 1 -03} + {-191361600 -10800 1 -04} {-184194000 -14400 0 -04} - {-155160000 -10800 1 -03} + {-155160000 -10800 1 -04} {-150066000 -14400 0 -04} - {-128894400 -10800 1 -03} + {-128894400 -10800 1 -04} {-121122000 -14400 0 -04} - {-99950400 -10800 1 -03} + {-99950400 -10800 1 -04} {-89586000 -14400 0 -04} - {-68414400 -10800 1 -03} + {-68414400 -10800 1 -04} {-57963600 -14400 0 -04} - {499752000 -10800 1 -03} + {499752000 -10800 1 -04} {511239600 -14400 0 -04} - {530596800 -10800 1 -03} + {530596800 -10800 1 -04} {540270000 -14400 0 -04} - {562132800 -10800 1 -03} + {562132800 -10800 1 -04} {571201200 -14400 0 -04} {590036400 -14400 0 -04} } diff --git a/library/tzdata/America/Punta_Arenas b/library/tzdata/America/Punta_Arenas index 75487e7..5e8202a 100644 --- a/library/tzdata/America/Punta_Arenas +++ b/library/tzdata/America/Punta_Arenas @@ -8,115 +8,115 @@ set TZData(:America/Punta_Arenas) { {-1619205434 -14400 0 -04} {-1593806400 -16966 0 SMT} {-1335986234 -18000 0 -05} - {-1335985200 -14400 1 -04} + {-1335985200 -14400 1 -05} {-1317585600 -18000 0 -05} - {-1304362800 -14400 1 -04} + {-1304362800 -14400 1 -05} {-1286049600 -18000 0 -05} - {-1272826800 -14400 1 -04} + {-1272826800 -14400 1 -05} {-1254513600 -18000 0 -05} - {-1241290800 -14400 1 -04} + {-1241290800 -14400 1 -05} {-1222977600 -18000 0 -05} - {-1209754800 -14400 1 -04} + {-1209754800 -14400 1 -05} {-1191355200 -18000 0 -05} {-1178132400 -14400 0 -04} {-870552000 -18000 0 -05} {-865278000 -14400 0 -04} {-718056000 -18000 0 -05} {-713649600 -14400 0 -04} - {-36619200 -10800 1 -03} + {-36619200 -10800 1 -04} {-23922000 -14400 0 -04} - {-3355200 -10800 1 -03} + {-3355200 -10800 1 -04} {7527600 -14400 0 -04} - {24465600 -10800 1 -03} + {24465600 -10800 1 -04} {37767600 -14400 0 -04} - {55915200 -10800 1 -03} + {55915200 -10800 1 -04} {69217200 -14400 0 -04} - {87969600 -10800 1 -03} + {87969600 -10800 1 -04} {100666800 -14400 0 -04} - {118209600 -10800 1 -03} + {118209600 -10800 1 -04} {132116400 -14400 0 -04} - {150868800 -10800 1 -03} + {150868800 -10800 1 -04} {163566000 -14400 0 -04} - {182318400 -10800 1 -03} + {182318400 -10800 1 -04} {195620400 -14400 0 -04} - {213768000 -10800 1 -03} + {213768000 -10800 1 -04} {227070000 -14400 0 -04} - {245217600 -10800 1 -03} + {245217600 -10800 1 -04} {258519600 -14400 0 -04} - {277272000 -10800 1 -03} + {277272000 -10800 1 -04} {289969200 -14400 0 -04} - {308721600 -10800 1 -03} + {308721600 -10800 1 -04} {321418800 -14400 0 -04} - {340171200 -10800 1 -03} + {340171200 -10800 1 -04} {353473200 -14400 0 -04} - {371620800 -10800 1 -03} + {371620800 -10800 1 -04} {384922800 -14400 0 -04} - {403070400 -10800 1 -03} + {403070400 -10800 1 -04} {416372400 -14400 0 -04} - {434520000 -10800 1 -03} + {434520000 -10800 1 -04} {447822000 -14400 0 -04} - {466574400 -10800 1 -03} + {466574400 -10800 1 -04} {479271600 -14400 0 -04} - {498024000 -10800 1 -03} + {498024000 -10800 1 -04} {510721200 -14400 0 -04} - {529473600 -10800 1 -03} + {529473600 -10800 1 -04} {545194800 -14400 0 -04} - {560923200 -10800 1 -03} + {560923200 -10800 1 -04} {574225200 -14400 0 -04} - {592372800 -10800 1 -03} + {592372800 -10800 1 -04} {605674800 -14400 0 -04} - {624427200 -10800 1 -03} + {624427200 -10800 1 -04} {637124400 -14400 0 -04} - {653457600 -10800 1 -03} + {653457600 -10800 1 -04} {668574000 -14400 0 -04} - {687326400 -10800 1 -03} + {687326400 -10800 1 -04} {700628400 -14400 0 -04} - {718776000 -10800 1 -03} + {718776000 -10800 1 -04} {732078000 -14400 0 -04} - {750225600 -10800 1 -03} + {750225600 -10800 1 -04} {763527600 -14400 0 -04} - {781675200 -10800 1 -03} + {781675200 -10800 1 -04} {794977200 -14400 0 -04} - {813729600 -10800 1 -03} + {813729600 -10800 1 -04} {826426800 -14400 0 -04} - {845179200 -10800 1 -03} + {845179200 -10800 1 -04} {859690800 -14400 0 -04} - {876628800 -10800 1 -03} + {876628800 -10800 1 -04} {889930800 -14400 0 -04} - {906868800 -10800 1 -03} + {906868800 -10800 1 -04} {923194800 -14400 0 -04} - {939528000 -10800 1 -03} + {939528000 -10800 1 -04} {952830000 -14400 0 -04} - {971582400 -10800 1 -03} + {971582400 -10800 1 -04} {984279600 -14400 0 -04} - {1003032000 -10800 1 -03} + {1003032000 -10800 1 -04} {1015729200 -14400 0 -04} - {1034481600 -10800 1 -03} + {1034481600 -10800 1 -04} {1047178800 -14400 0 -04} - {1065931200 -10800 1 -03} + {1065931200 -10800 1 -04} {1079233200 -14400 0 -04} - {1097380800 -10800 1 -03} + {1097380800 -10800 1 -04} {1110682800 -14400 0 -04} - {1128830400 -10800 1 -03} + {1128830400 -10800 1 -04} {1142132400 -14400 0 -04} - {1160884800 -10800 1 -03} + {1160884800 -10800 1 -04} {1173582000 -14400 0 -04} - {1192334400 -10800 1 -03} + {1192334400 -10800 1 -04} {1206846000 -14400 0 -04} - {1223784000 -10800 1 -03} + {1223784000 -10800 1 -04} {1237086000 -14400 0 -04} - {1255233600 -10800 1 -03} + {1255233600 -10800 1 -04} {1270350000 -14400 0 -04} - {1286683200 -10800 1 -03} + {1286683200 -10800 1 -04} {1304823600 -14400 0 -04} - {1313899200 -10800 1 -03} + {1313899200 -10800 1 -04} {1335668400 -14400 0 -04} - {1346558400 -10800 1 -03} + {1346558400 -10800 1 -04} {1367118000 -14400 0 -04} - {1378612800 -10800 1 -03} + {1378612800 -10800 1 -04} {1398567600 -14400 0 -04} - {1410062400 -10800 1 -03} + {1410062400 -10800 1 -04} {1463281200 -14400 0 -04} - {1471147200 -10800 1 -03} + {1471147200 -10800 1 -04} {1480820400 -10800 0 -03} } diff --git a/library/tzdata/America/Recife b/library/tzdata/America/Recife index 8eae571..db0a445 100644 --- a/library/tzdata/America/Recife +++ b/library/tzdata/America/Recife @@ -3,46 +3,46 @@ set TZData(:America/Recife) { {-9223372036854775808 -8376 0 LMT} {-1767217224 -10800 0 -03} - {-1206957600 -7200 1 -02} + {-1206957600 -7200 1 -03} {-1191362400 -10800 0 -03} - {-1175374800 -7200 1 -02} + {-1175374800 -7200 1 -03} {-1159826400 -10800 0 -03} - {-633819600 -7200 1 -02} + {-633819600 -7200 1 -03} {-622069200 -10800 0 -03} - {-602283600 -7200 1 -02} + {-602283600 -7200 1 -03} {-591832800 -10800 0 -03} - {-570747600 -7200 1 -02} + {-570747600 -7200 1 -03} {-560210400 -10800 0 -03} - {-539125200 -7200 1 -02} + {-539125200 -7200 1 -03} {-531352800 -10800 0 -03} - {-191365200 -7200 1 -02} + {-191365200 -7200 1 -03} {-184197600 -10800 0 -03} - {-155163600 -7200 1 -02} + {-155163600 -7200 1 -03} {-150069600 -10800 0 -03} - {-128898000 -7200 1 -02} + {-128898000 -7200 1 -03} {-121125600 -10800 0 -03} - {-99954000 -7200 1 -02} + {-99954000 -7200 1 -03} {-89589600 -10800 0 -03} - {-68418000 -7200 1 -02} + {-68418000 -7200 1 -03} {-57967200 -10800 0 -03} - {499748400 -7200 1 -02} + {499748400 -7200 1 -03} {511236000 -10800 0 -03} - {530593200 -7200 1 -02} + {530593200 -7200 1 -03} {540266400 -10800 0 -03} - {562129200 -7200 1 -02} + {562129200 -7200 1 -03} {571197600 -10800 0 -03} - {592974000 -7200 1 -02} + {592974000 -7200 1 -03} {602042400 -10800 0 -03} - {624423600 -7200 1 -02} + {624423600 -7200 1 -03} {634701600 -10800 0 -03} {653536800 -10800 0 -03} {938660400 -10800 0 -03} - {938919600 -7200 1 -02} + {938919600 -7200 1 -03} {951616800 -10800 0 -03} - {970974000 -7200 1 -02} + {970974000 -7200 1 -03} {971575200 -10800 0 -03} {1000350000 -10800 0 -03} - {1003028400 -7200 1 -02} + {1003028400 -7200 1 -03} {1013911200 -10800 0 -03} {1033437600 -10800 0 -03} } diff --git a/library/tzdata/America/Rio_Branco b/library/tzdata/America/Rio_Branco index e3c2f31..088800b 100644 --- a/library/tzdata/America/Rio_Branco +++ b/library/tzdata/America/Rio_Branco @@ -3,33 +3,33 @@ set TZData(:America/Rio_Branco) { {-9223372036854775808 -16272 0 LMT} {-1767209328 -18000 0 -05} - {-1206950400 -14400 1 -04} + {-1206950400 -14400 1 -05} {-1191355200 -18000 0 -05} - {-1175367600 -14400 1 -04} + {-1175367600 -14400 1 -05} {-1159819200 -18000 0 -05} - {-633812400 -14400 1 -04} + {-633812400 -14400 1 -05} {-622062000 -18000 0 -05} - {-602276400 -14400 1 -04} + {-602276400 -14400 1 -05} {-591825600 -18000 0 -05} - {-570740400 -14400 1 -04} + {-570740400 -14400 1 -05} {-560203200 -18000 0 -05} - {-539118000 -14400 1 -04} + {-539118000 -14400 1 -05} {-531345600 -18000 0 -05} - {-191358000 -14400 1 -04} + {-191358000 -14400 1 -05} {-184190400 -18000 0 -05} - {-155156400 -14400 1 -04} + {-155156400 -14400 1 -05} {-150062400 -18000 0 -05} - {-128890800 -14400 1 -04} + {-128890800 -14400 1 -05} {-121118400 -18000 0 -05} - {-99946800 -14400 1 -04} + {-99946800 -14400 1 -05} {-89582400 -18000 0 -05} - {-68410800 -14400 1 -04} + {-68410800 -14400 1 -05} {-57960000 -18000 0 -05} - {499755600 -14400 1 -04} + {499755600 -14400 1 -05} {511243200 -18000 0 -05} - {530600400 -14400 1 -04} + {530600400 -14400 1 -05} {540273600 -18000 0 -05} - {562136400 -14400 1 -04} + {562136400 -14400 1 -05} {571204800 -18000 0 -05} {590040000 -18000 0 -05} {1214283600 -14400 0 -04} diff --git a/library/tzdata/America/Santarem b/library/tzdata/America/Santarem index f81e9b6..5fa3551 100644 --- a/library/tzdata/America/Santarem +++ b/library/tzdata/America/Santarem @@ -3,33 +3,33 @@ set TZData(:America/Santarem) { {-9223372036854775808 -13128 0 LMT} {-1767212472 -14400 0 -04} - {-1206954000 -10800 1 -03} + {-1206954000 -10800 1 -04} {-1191358800 -14400 0 -04} - {-1175371200 -10800 1 -03} + {-1175371200 -10800 1 -04} {-1159822800 -14400 0 -04} - {-633816000 -10800 1 -03} + {-633816000 -10800 1 -04} {-622065600 -14400 0 -04} - {-602280000 -10800 1 -03} + {-602280000 -10800 1 -04} {-591829200 -14400 0 -04} - {-570744000 -10800 1 -03} + {-570744000 -10800 1 -04} {-560206800 -14400 0 -04} - {-539121600 -10800 1 -03} + {-539121600 -10800 1 -04} {-531349200 -14400 0 -04} - {-191361600 -10800 1 -03} + {-191361600 -10800 1 -04} {-184194000 -14400 0 -04} - {-155160000 -10800 1 -03} + {-155160000 -10800 1 -04} {-150066000 -14400 0 -04} - {-128894400 -10800 1 -03} + {-128894400 -10800 1 -04} {-121122000 -14400 0 -04} - {-99950400 -10800 1 -03} + {-99950400 -10800 1 -04} {-89586000 -14400 0 -04} - {-68414400 -10800 1 -03} + {-68414400 -10800 1 -04} {-57963600 -14400 0 -04} - {499752000 -10800 1 -03} + {499752000 -10800 1 -04} {511239600 -14400 0 -04} - {530596800 -10800 1 -03} + {530596800 -10800 1 -04} {540270000 -14400 0 -04} - {562132800 -10800 1 -03} + {562132800 -10800 1 -04} {571201200 -14400 0 -04} {590036400 -14400 0 -04} {1214280000 -10800 0 -03} diff --git a/library/tzdata/America/Santiago b/library/tzdata/America/Santiago index 95e920d..67d5b5c 100644 --- a/library/tzdata/America/Santiago +++ b/library/tzdata/America/Santiago @@ -8,15 +8,15 @@ set TZData(:America/Santiago) { {-1619205434 -14400 0 -04} {-1593806400 -16966 0 SMT} {-1335986234 -18000 0 -05} - {-1335985200 -14400 1 -04} + {-1335985200 -14400 1 -05} {-1317585600 -18000 0 -05} - {-1304362800 -14400 1 -04} + {-1304362800 -14400 1 -05} {-1286049600 -18000 0 -05} - {-1272826800 -14400 1 -04} + {-1272826800 -14400 1 -05} {-1254513600 -18000 0 -05} - {-1241290800 -14400 1 -04} + {-1241290800 -14400 1 -05} {-1222977600 -18000 0 -05} - {-1209754800 -14400 1 -04} + {-1209754800 -14400 1 -05} {-1191355200 -18000 0 -05} {-1178132400 -14400 0 -04} {-870552000 -18000 0 -05} @@ -25,265 +25,265 @@ set TZData(:America/Santiago) { {-736376400 -14400 0 -04} {-718056000 -18000 0 -05} {-713649600 -14400 0 -04} - {-36619200 -10800 1 -03} + {-36619200 -10800 1 -04} {-23922000 -14400 0 -04} - {-3355200 -10800 1 -03} + {-3355200 -10800 1 -04} {7527600 -14400 0 -04} - {24465600 -10800 1 -03} + {24465600 -10800 1 -04} {37767600 -14400 0 -04} - {55915200 -10800 1 -03} + {55915200 -10800 1 -04} {69217200 -14400 0 -04} - {87969600 -10800 1 -03} + {87969600 -10800 1 -04} {100666800 -14400 0 -04} - {118209600 -10800 1 -03} + {118209600 -10800 1 -04} {132116400 -14400 0 -04} - {150868800 -10800 1 -03} + {150868800 -10800 1 -04} {163566000 -14400 0 -04} - {182318400 -10800 1 -03} + {182318400 -10800 1 -04} {195620400 -14400 0 -04} - {213768000 -10800 1 -03} + {213768000 -10800 1 -04} {227070000 -14400 0 -04} - {245217600 -10800 1 -03} + {245217600 -10800 1 -04} {258519600 -14400 0 -04} - {277272000 -10800 1 -03} + {277272000 -10800 1 -04} {289969200 -14400 0 -04} - {308721600 -10800 1 -03} + {308721600 -10800 1 -04} {321418800 -14400 0 -04} - {340171200 -10800 1 -03} + {340171200 -10800 1 -04} {353473200 -14400 0 -04} - {371620800 -10800 1 -03} + {371620800 -10800 1 -04} {384922800 -14400 0 -04} - {403070400 -10800 1 -03} + {403070400 -10800 1 -04} {416372400 -14400 0 -04} - {434520000 -10800 1 -03} + {434520000 -10800 1 -04} {447822000 -14400 0 -04} - {466574400 -10800 1 -03} + {466574400 -10800 1 -04} {479271600 -14400 0 -04} - {498024000 -10800 1 -03} + {498024000 -10800 1 -04} {510721200 -14400 0 -04} - {529473600 -10800 1 -03} + {529473600 -10800 1 -04} {545194800 -14400 0 -04} - {560923200 -10800 1 -03} + {560923200 -10800 1 -04} {574225200 -14400 0 -04} - {592372800 -10800 1 -03} + {592372800 -10800 1 -04} {605674800 -14400 0 -04} - {624427200 -10800 1 -03} + {624427200 -10800 1 -04} {637124400 -14400 0 -04} - {653457600 -10800 1 -03} + {653457600 -10800 1 -04} {668574000 -14400 0 -04} - {687326400 -10800 1 -03} + {687326400 -10800 1 -04} {700628400 -14400 0 -04} - {718776000 -10800 1 -03} + {718776000 -10800 1 -04} {732078000 -14400 0 -04} - {750225600 -10800 1 -03} + {750225600 -10800 1 -04} {763527600 -14400 0 -04} - {781675200 -10800 1 -03} + {781675200 -10800 1 -04} {794977200 -14400 0 -04} - {813729600 -10800 1 -03} + {813729600 -10800 1 -04} {826426800 -14400 0 -04} - {845179200 -10800 1 -03} + {845179200 -10800 1 -04} {859690800 -14400 0 -04} - {876628800 -10800 1 -03} + {876628800 -10800 1 -04} {889930800 -14400 0 -04} - {906868800 -10800 1 -03} + {906868800 -10800 1 -04} {923194800 -14400 0 -04} - {939528000 -10800 1 -03} + {939528000 -10800 1 -04} {952830000 -14400 0 -04} - {971582400 -10800 1 -03} + {971582400 -10800 1 -04} {984279600 -14400 0 -04} - {1003032000 -10800 1 -03} + {1003032000 -10800 1 -04} {1015729200 -14400 0 -04} - {1034481600 -10800 1 -03} + {1034481600 -10800 1 -04} {1047178800 -14400 0 -04} - {1065931200 -10800 1 -03} + {1065931200 -10800 1 -04} {1079233200 -14400 0 -04} - {1097380800 -10800 1 -03} + {1097380800 -10800 1 -04} {1110682800 -14400 0 -04} - {1128830400 -10800 1 -03} + {1128830400 -10800 1 -04} {1142132400 -14400 0 -04} - {1160884800 -10800 1 -03} + {1160884800 -10800 1 -04} {1173582000 -14400 0 -04} - {1192334400 -10800 1 -03} + {1192334400 -10800 1 -04} {1206846000 -14400 0 -04} - {1223784000 -10800 1 -03} + {1223784000 -10800 1 -04} {1237086000 -14400 0 -04} - {1255233600 -10800 1 -03} + {1255233600 -10800 1 -04} {1270350000 -14400 0 -04} - {1286683200 -10800 1 -03} + {1286683200 -10800 1 -04} {1304823600 -14400 0 -04} - {1313899200 -10800 1 -03} + {1313899200 -10800 1 -04} {1335668400 -14400 0 -04} - {1346558400 -10800 1 -03} + {1346558400 -10800 1 -04} {1367118000 -14400 0 -04} - {1378612800 -10800 1 -03} + {1378612800 -10800 1 -04} {1398567600 -14400 0 -04} - {1410062400 -10800 1 -03} + {1410062400 -10800 1 -04} {1463281200 -14400 0 -04} - {1471147200 -10800 1 -03} + {1471147200 -10800 1 -04} {1494730800 -14400 0 -04} - {1502596800 -10800 1 -03} + {1502596800 -10800 1 -04} {1526180400 -14400 0 -04} - {1534046400 -10800 1 -03} + {1534046400 -10800 1 -04} {1557630000 -14400 0 -04} - {1565496000 -10800 1 -03} + {1565496000 -10800 1 -04} {1589079600 -14400 0 -04} - {1596945600 -10800 1 -03} + {1596945600 -10800 1 -04} {1620529200 -14400 0 -04} - {1629000000 -10800 1 -03} + {1629000000 -10800 1 -04} {1652583600 -14400 0 -04} - {1660449600 -10800 1 -03} + {1660449600 -10800 1 -04} {1684033200 -14400 0 -04} - {1691899200 -10800 1 -03} + {1691899200 -10800 1 -04} {1715482800 -14400 0 -04} - {1723348800 -10800 1 -03} + {1723348800 -10800 1 -04} {1746932400 -14400 0 -04} - {1754798400 -10800 1 -03} + {1754798400 -10800 1 -04} {1778382000 -14400 0 -04} - {1786248000 -10800 1 -03} + {1786248000 -10800 1 -04} {1809831600 -14400 0 -04} - {1818302400 -10800 1 -03} + {1818302400 -10800 1 -04} {1841886000 -14400 0 -04} - {1849752000 -10800 1 -03} + {1849752000 -10800 1 -04} {1873335600 -14400 0 -04} - {1881201600 -10800 1 -03} + {1881201600 -10800 1 -04} {1904785200 -14400 0 -04} - {1912651200 -10800 1 -03} + {1912651200 -10800 1 -04} {1936234800 -14400 0 -04} - {1944100800 -10800 1 -03} + {1944100800 -10800 1 -04} {1967684400 -14400 0 -04} - {1976155200 -10800 1 -03} + {1976155200 -10800 1 -04} {1999738800 -14400 0 -04} - {2007604800 -10800 1 -03} + {2007604800 -10800 1 -04} {2031188400 -14400 0 -04} - {2039054400 -10800 1 -03} + {2039054400 -10800 1 -04} {2062638000 -14400 0 -04} - {2070504000 -10800 1 -03} + {2070504000 -10800 1 -04} {2094087600 -14400 0 -04} - {2101953600 -10800 1 -03} + {2101953600 -10800 1 -04} {2125537200 -14400 0 -04} - {2133403200 -10800 1 -03} + {2133403200 -10800 1 -04} {2156986800 -14400 0 -04} - {2165457600 -10800 1 -03} + {2165457600 -10800 1 -04} {2189041200 -14400 0 -04} - {2196907200 -10800 1 -03} + {2196907200 -10800 1 -04} {2220490800 -14400 0 -04} - {2228356800 -10800 1 -03} + {2228356800 -10800 1 -04} {2251940400 -14400 0 -04} - {2259806400 -10800 1 -03} + {2259806400 -10800 1 -04} {2283390000 -14400 0 -04} - {2291256000 -10800 1 -03} + {2291256000 -10800 1 -04} {2314839600 -14400 0 -04} - {2322705600 -10800 1 -03} + {2322705600 -10800 1 -04} {2346894000 -14400 0 -04} - {2354760000 -10800 1 -03} + {2354760000 -10800 1 -04} {2378343600 -14400 0 -04} - {2386209600 -10800 1 -03} + {2386209600 -10800 1 -04} {2409793200 -14400 0 -04} - {2417659200 -10800 1 -03} + {2417659200 -10800 1 -04} {2441242800 -14400 0 -04} - {2449108800 -10800 1 -03} + {2449108800 -10800 1 -04} {2472692400 -14400 0 -04} - {2480558400 -10800 1 -03} + {2480558400 -10800 1 -04} {2504142000 -14400 0 -04} - {2512612800 -10800 1 -03} + {2512612800 -10800 1 -04} {2536196400 -14400 0 -04} - {2544062400 -10800 1 -03} + {2544062400 -10800 1 -04} {2567646000 -14400 0 -04} - {2575512000 -10800 1 -03} + {2575512000 -10800 1 -04} {2599095600 -14400 0 -04} - {2606961600 -10800 1 -03} + {2606961600 -10800 1 -04} {2630545200 -14400 0 -04} - {2638411200 -10800 1 -03} + {2638411200 -10800 1 -04} {2661994800 -14400 0 -04} - {2669860800 -10800 1 -03} + {2669860800 -10800 1 -04} {2693444400 -14400 0 -04} - {2701915200 -10800 1 -03} + {2701915200 -10800 1 -04} {2725498800 -14400 0 -04} - {2733364800 -10800 1 -03} + {2733364800 -10800 1 -04} {2756948400 -14400 0 -04} - {2764814400 -10800 1 -03} + {2764814400 -10800 1 -04} {2788398000 -14400 0 -04} - {2796264000 -10800 1 -03} + {2796264000 -10800 1 -04} {2819847600 -14400 0 -04} - {2827713600 -10800 1 -03} + {2827713600 -10800 1 -04} {2851297200 -14400 0 -04} - {2859768000 -10800 1 -03} + {2859768000 -10800 1 -04} {2883351600 -14400 0 -04} - {2891217600 -10800 1 -03} + {2891217600 -10800 1 -04} {2914801200 -14400 0 -04} - {2922667200 -10800 1 -03} + {2922667200 -10800 1 -04} {2946250800 -14400 0 -04} - {2954116800 -10800 1 -03} + {2954116800 -10800 1 -04} {2977700400 -14400 0 -04} - {2985566400 -10800 1 -03} + {2985566400 -10800 1 -04} {3009150000 -14400 0 -04} - {3017016000 -10800 1 -03} + {3017016000 -10800 1 -04} {3040599600 -14400 0 -04} - {3049070400 -10800 1 -03} + {3049070400 -10800 1 -04} {3072654000 -14400 0 -04} - {3080520000 -10800 1 -03} + {3080520000 -10800 1 -04} {3104103600 -14400 0 -04} - {3111969600 -10800 1 -03} + {3111969600 -10800 1 -04} {3135553200 -14400 0 -04} - {3143419200 -10800 1 -03} + {3143419200 -10800 1 -04} {3167002800 -14400 0 -04} - {3174868800 -10800 1 -03} + {3174868800 -10800 1 -04} {3198452400 -14400 0 -04} - {3206318400 -10800 1 -03} + {3206318400 -10800 1 -04} {3230506800 -14400 0 -04} - {3238372800 -10800 1 -03} + {3238372800 -10800 1 -04} {3261956400 -14400 0 -04} - {3269822400 -10800 1 -03} + {3269822400 -10800 1 -04} {3293406000 -14400 0 -04} - {3301272000 -10800 1 -03} + {3301272000 -10800 1 -04} {3324855600 -14400 0 -04} - {3332721600 -10800 1 -03} + {3332721600 -10800 1 -04} {3356305200 -14400 0 -04} - {3364171200 -10800 1 -03} + {3364171200 -10800 1 -04} {3387754800 -14400 0 -04} - {3396225600 -10800 1 -03} + {3396225600 -10800 1 -04} {3419809200 -14400 0 -04} - {3427675200 -10800 1 -03} + {3427675200 -10800 1 -04} {3451258800 -14400 0 -04} - {3459124800 -10800 1 -03} + {3459124800 -10800 1 -04} {3482708400 -14400 0 -04} - {3490574400 -10800 1 -03} + {3490574400 -10800 1 -04} {3514158000 -14400 0 -04} - {3522024000 -10800 1 -03} + {3522024000 -10800 1 -04} {3545607600 -14400 0 -04} - {3553473600 -10800 1 -03} + {3553473600 -10800 1 -04} {3577057200 -14400 0 -04} - {3585528000 -10800 1 -03} + {3585528000 -10800 1 -04} {3609111600 -14400 0 -04} - {3616977600 -10800 1 -03} + {3616977600 -10800 1 -04} {3640561200 -14400 0 -04} - {3648427200 -10800 1 -03} + {3648427200 -10800 1 -04} {3672010800 -14400 0 -04} - {3679876800 -10800 1 -03} + {3679876800 -10800 1 -04} {3703460400 -14400 0 -04} - {3711326400 -10800 1 -03} + {3711326400 -10800 1 -04} {3734910000 -14400 0 -04} - {3743380800 -10800 1 -03} + {3743380800 -10800 1 -04} {3766964400 -14400 0 -04} - {3774830400 -10800 1 -03} + {3774830400 -10800 1 -04} {3798414000 -14400 0 -04} - {3806280000 -10800 1 -03} + {3806280000 -10800 1 -04} {3829863600 -14400 0 -04} - {3837729600 -10800 1 -03} + {3837729600 -10800 1 -04} {3861313200 -14400 0 -04} - {3869179200 -10800 1 -03} + {3869179200 -10800 1 -04} {3892762800 -14400 0 -04} - {3900628800 -10800 1 -03} + {3900628800 -10800 1 -04} {3924212400 -14400 0 -04} - {3932683200 -10800 1 -03} + {3932683200 -10800 1 -04} {3956266800 -14400 0 -04} - {3964132800 -10800 1 -03} + {3964132800 -10800 1 -04} {3987716400 -14400 0 -04} - {3995582400 -10800 1 -03} + {3995582400 -10800 1 -04} {4019166000 -14400 0 -04} - {4027032000 -10800 1 -03} + {4027032000 -10800 1 -04} {4050615600 -14400 0 -04} - {4058481600 -10800 1 -03} + {4058481600 -10800 1 -04} {4082065200 -14400 0 -04} - {4089931200 -10800 1 -03} + {4089931200 -10800 1 -04} } diff --git a/library/tzdata/America/Sao_Paulo b/library/tzdata/America/Sao_Paulo index 93c524d..235f57a 100644 --- a/library/tzdata/America/Sao_Paulo +++ b/library/tzdata/America/Sao_Paulo @@ -3,256 +3,256 @@ set TZData(:America/Sao_Paulo) { {-9223372036854775808 -11188 0 LMT} {-1767214412 -10800 0 -03} - {-1206957600 -7200 1 -02} + {-1206957600 -7200 1 -03} {-1191362400 -10800 0 -03} - {-1175374800 -7200 1 -02} + {-1175374800 -7200 1 -03} {-1159826400 -10800 0 -03} - {-633819600 -7200 1 -02} + {-633819600 -7200 1 -03} {-622069200 -10800 0 -03} - {-602283600 -7200 1 -02} + {-602283600 -7200 1 -03} {-591832800 -10800 0 -03} - {-570747600 -7200 1 -02} + {-570747600 -7200 1 -03} {-560210400 -10800 0 -03} - {-539125200 -7200 1 -02} + {-539125200 -7200 1 -03} {-531352800 -10800 0 -03} {-195429600 -7200 1 -02} {-189381600 -7200 0 -03} {-184197600 -10800 0 -03} - {-155163600 -7200 1 -02} + {-155163600 -7200 1 -03} {-150069600 -10800 0 -03} - {-128898000 -7200 1 -02} + {-128898000 -7200 1 -03} {-121125600 -10800 0 -03} - {-99954000 -7200 1 -02} + {-99954000 -7200 1 -03} {-89589600 -10800 0 -03} - {-68418000 -7200 1 -02} + {-68418000 -7200 1 -03} {-57967200 -10800 0 -03} - {499748400 -7200 1 -02} + {499748400 -7200 1 -03} {511236000 -10800 0 -03} - {530593200 -7200 1 -02} + {530593200 -7200 1 -03} {540266400 -10800 0 -03} - {562129200 -7200 1 -02} + {562129200 -7200 1 -03} {571197600 -10800 0 -03} - {592974000 -7200 1 -02} + {592974000 -7200 1 -03} {602042400 -10800 0 -03} - {624423600 -7200 1 -02} + {624423600 -7200 1 -03} {634701600 -10800 0 -03} - {656478000 -7200 1 -02} + {656478000 -7200 1 -03} {666756000 -10800 0 -03} - {687927600 -7200 1 -02} + {687927600 -7200 1 -03} {697600800 -10800 0 -03} - {719982000 -7200 1 -02} + {719982000 -7200 1 -03} {728445600 -10800 0 -03} - {750826800 -7200 1 -02} + {750826800 -7200 1 -03} {761709600 -10800 0 -03} - {782276400 -7200 1 -02} + {782276400 -7200 1 -03} {793159200 -10800 0 -03} - {813726000 -7200 1 -02} + {813726000 -7200 1 -03} {824004000 -10800 0 -03} - {844570800 -7200 1 -02} + {844570800 -7200 1 -03} {856058400 -10800 0 -03} - {876106800 -7200 1 -02} + {876106800 -7200 1 -03} {888717600 -10800 0 -03} - {908074800 -7200 1 -02} + {908074800 -7200 1 -03} {919562400 -10800 0 -03} - {938919600 -7200 1 -02} + {938919600 -7200 1 -03} {951616800 -10800 0 -03} - {970974000 -7200 1 -02} + {970974000 -7200 1 -03} {982461600 -10800 0 -03} - {1003028400 -7200 1 -02} + {1003028400 -7200 1 -03} {1013911200 -10800 0 -03} - {1036292400 -7200 1 -02} + {1036292400 -7200 1 -03} {1045360800 -10800 0 -03} - {1066532400 -7200 1 -02} + {1066532400 -7200 1 -03} {1076810400 -10800 0 -03} - {1099364400 -7200 1 -02} + {1099364400 -7200 1 -03} {1108864800 -10800 0 -03} - {1129431600 -7200 1 -02} + {1129431600 -7200 1 -03} {1140314400 -10800 0 -03} - {1162695600 -7200 1 -02} + {1162695600 -7200 1 -03} {1172368800 -10800 0 -03} - {1192330800 -7200 1 -02} + {1192330800 -7200 1 -03} {1203213600 -10800 0 -03} - {1224385200 -7200 1 -02} + {1224385200 -7200 1 -03} {1234663200 -10800 0 -03} - {1255834800 -7200 1 -02} + {1255834800 -7200 1 -03} {1266717600 -10800 0 -03} - {1287284400 -7200 1 -02} + {1287284400 -7200 1 -03} {1298167200 -10800 0 -03} - {1318734000 -7200 1 -02} + {1318734000 -7200 1 -03} {1330221600 -10800 0 -03} - {1350788400 -7200 1 -02} + {1350788400 -7200 1 -03} {1361066400 -10800 0 -03} - {1382238000 -7200 1 -02} + {1382238000 -7200 1 -03} {1392516000 -10800 0 -03} - {1413687600 -7200 1 -02} + {1413687600 -7200 1 -03} {1424570400 -10800 0 -03} - {1445137200 -7200 1 -02} + {1445137200 -7200 1 -03} {1456020000 -10800 0 -03} - {1476586800 -7200 1 -02} + {1476586800 -7200 1 -03} {1487469600 -10800 0 -03} - {1508036400 -7200 1 -02} + {1508036400 -7200 1 -03} {1518919200 -10800 0 -03} - {1541300400 -7200 1 -02} + {1541300400 -7200 1 -03} {1550368800 -10800 0 -03} - {1572750000 -7200 1 -02} + {1572750000 -7200 1 -03} {1581818400 -10800 0 -03} - {1604199600 -7200 1 -02} + {1604199600 -7200 1 -03} {1613872800 -10800 0 -03} - {1636254000 -7200 1 -02} + {1636254000 -7200 1 -03} {1645322400 -10800 0 -03} - {1667703600 -7200 1 -02} + {1667703600 -7200 1 -03} {1677376800 -10800 0 -03} - {1699153200 -7200 1 -02} + {1699153200 -7200 1 -03} {1708221600 -10800 0 -03} - {1730602800 -7200 1 -02} + {1730602800 -7200 1 -03} {1739671200 -10800 0 -03} - {1762052400 -7200 1 -02} + {1762052400 -7200 1 -03} {1771725600 -10800 0 -03} - {1793502000 -7200 1 -02} + {1793502000 -7200 1 -03} {1803175200 -10800 0 -03} - {1825556400 -7200 1 -02} + {1825556400 -7200 1 -03} {1834624800 -10800 0 -03} - {1857006000 -7200 1 -02} + {1857006000 -7200 1 -03} {1866074400 -10800 0 -03} - {1888455600 -7200 1 -02} + {1888455600 -7200 1 -03} {1897524000 -10800 0 -03} - {1919905200 -7200 1 -02} + {1919905200 -7200 1 -03} {1928973600 -10800 0 -03} - {1951354800 -7200 1 -02} + {1951354800 -7200 1 -03} {1960423200 -10800 0 -03} - {1983409200 -7200 1 -02} + {1983409200 -7200 1 -03} {1992477600 -10800 0 -03} - {2014858800 -7200 1 -02} + {2014858800 -7200 1 -03} {2024532000 -10800 0 -03} - {2046308400 -7200 1 -02} + {2046308400 -7200 1 -03} {2055376800 -10800 0 -03} - {2077758000 -7200 1 -02} + {2077758000 -7200 1 -03} {2086826400 -10800 0 -03} - {2109207600 -7200 1 -02} + {2109207600 -7200 1 -03} {2118880800 -10800 0 -03} - {2140657200 -7200 1 -02} + {2140657200 -7200 1 -03} {2150330400 -10800 0 -03} - {2172711600 -7200 1 -02} + {2172711600 -7200 1 -03} {2181780000 -10800 0 -03} - {2204161200 -7200 1 -02} + {2204161200 -7200 1 -03} {2213229600 -10800 0 -03} - {2235610800 -7200 1 -02} + {2235610800 -7200 1 -03} {2244679200 -10800 0 -03} - {2267060400 -7200 1 -02} + {2267060400 -7200 1 -03} {2276128800 -10800 0 -03} - {2298510000 -7200 1 -02} + {2298510000 -7200 1 -03} {2307578400 -10800 0 -03} - {2329959600 -7200 1 -02} + {2329959600 -7200 1 -03} {2339632800 -10800 0 -03} - {2362014000 -7200 1 -02} + {2362014000 -7200 1 -03} {2371082400 -10800 0 -03} - {2393463600 -7200 1 -02} + {2393463600 -7200 1 -03} {2402532000 -10800 0 -03} - {2424913200 -7200 1 -02} + {2424913200 -7200 1 -03} {2433981600 -10800 0 -03} - {2456362800 -7200 1 -02} + {2456362800 -7200 1 -03} {2465431200 -10800 0 -03} - {2487812400 -7200 1 -02} + {2487812400 -7200 1 -03} {2497485600 -10800 0 -03} - {2519866800 -7200 1 -02} + {2519866800 -7200 1 -03} {2528935200 -10800 0 -03} - {2551316400 -7200 1 -02} + {2551316400 -7200 1 -03} {2560384800 -10800 0 -03} - {2582766000 -7200 1 -02} + {2582766000 -7200 1 -03} {2591834400 -10800 0 -03} - {2614215600 -7200 1 -02} + {2614215600 -7200 1 -03} {2623284000 -10800 0 -03} - {2645665200 -7200 1 -02} + {2645665200 -7200 1 -03} {2654733600 -10800 0 -03} - {2677114800 -7200 1 -02} + {2677114800 -7200 1 -03} {2686788000 -10800 0 -03} - {2709169200 -7200 1 -02} + {2709169200 -7200 1 -03} {2718237600 -10800 0 -03} - {2740618800 -7200 1 -02} + {2740618800 -7200 1 -03} {2749687200 -10800 0 -03} - {2772068400 -7200 1 -02} + {2772068400 -7200 1 -03} {2781136800 -10800 0 -03} - {2803518000 -7200 1 -02} + {2803518000 -7200 1 -03} {2812586400 -10800 0 -03} - {2834967600 -7200 1 -02} + {2834967600 -7200 1 -03} {2844036000 -10800 0 -03} - {2867022000 -7200 1 -02} + {2867022000 -7200 1 -03} {2876090400 -10800 0 -03} - {2898471600 -7200 1 -02} + {2898471600 -7200 1 -03} {2907540000 -10800 0 -03} - {2929921200 -7200 1 -02} + {2929921200 -7200 1 -03} {2938989600 -10800 0 -03} - {2961370800 -7200 1 -02} + {2961370800 -7200 1 -03} {2970439200 -10800 0 -03} - {2992820400 -7200 1 -02} + {2992820400 -7200 1 -03} {3001888800 -10800 0 -03} - {3024270000 -7200 1 -02} + {3024270000 -7200 1 -03} {3033943200 -10800 0 -03} - {3056324400 -7200 1 -02} + {3056324400 -7200 1 -03} {3065392800 -10800 0 -03} - {3087774000 -7200 1 -02} + {3087774000 -7200 1 -03} {3096842400 -10800 0 -03} - {3119223600 -7200 1 -02} + {3119223600 -7200 1 -03} {3128292000 -10800 0 -03} - {3150673200 -7200 1 -02} + {3150673200 -7200 1 -03} {3159741600 -10800 0 -03} - {3182122800 -7200 1 -02} + {3182122800 -7200 1 -03} {3191191200 -10800 0 -03} - {3213572400 -7200 1 -02} + {3213572400 -7200 1 -03} {3223245600 -10800 0 -03} - {3245626800 -7200 1 -02} + {3245626800 -7200 1 -03} {3254695200 -10800 0 -03} - {3277076400 -7200 1 -02} + {3277076400 -7200 1 -03} {3286144800 -10800 0 -03} - {3308526000 -7200 1 -02} + {3308526000 -7200 1 -03} {3317594400 -10800 0 -03} - {3339975600 -7200 1 -02} + {3339975600 -7200 1 -03} {3349044000 -10800 0 -03} - {3371425200 -7200 1 -02} + {3371425200 -7200 1 -03} {3381098400 -10800 0 -03} - {3403479600 -7200 1 -02} + {3403479600 -7200 1 -03} {3412548000 -10800 0 -03} - {3434929200 -7200 1 -02} + {3434929200 -7200 1 -03} {3443997600 -10800 0 -03} - {3466378800 -7200 1 -02} + {3466378800 -7200 1 -03} {3475447200 -10800 0 -03} - {3497828400 -7200 1 -02} + {3497828400 -7200 1 -03} {3506896800 -10800 0 -03} - {3529278000 -7200 1 -02} + {3529278000 -7200 1 -03} {3538346400 -10800 0 -03} - {3560727600 -7200 1 -02} + {3560727600 -7200 1 -03} {3570400800 -10800 0 -03} - {3592782000 -7200 1 -02} + {3592782000 -7200 1 -03} {3601850400 -10800 0 -03} - {3624231600 -7200 1 -02} + {3624231600 -7200 1 -03} {3633300000 -10800 0 -03} - {3655681200 -7200 1 -02} + {3655681200 -7200 1 -03} {3664749600 -10800 0 -03} - {3687130800 -7200 1 -02} + {3687130800 -7200 1 -03} {3696199200 -10800 0 -03} - {3718580400 -7200 1 -02} + {3718580400 -7200 1 -03} {3727648800 -10800 0 -03} - {3750634800 -7200 1 -02} + {3750634800 -7200 1 -03} {3759703200 -10800 0 -03} - {3782084400 -7200 1 -02} + {3782084400 -7200 1 -03} {3791152800 -10800 0 -03} - {3813534000 -7200 1 -02} + {3813534000 -7200 1 -03} {3822602400 -10800 0 -03} - {3844983600 -7200 1 -02} + {3844983600 -7200 1 -03} {3854052000 -10800 0 -03} - {3876433200 -7200 1 -02} + {3876433200 -7200 1 -03} {3885501600 -10800 0 -03} - {3907882800 -7200 1 -02} + {3907882800 -7200 1 -03} {3917556000 -10800 0 -03} - {3939937200 -7200 1 -02} + {3939937200 -7200 1 -03} {3949005600 -10800 0 -03} - {3971386800 -7200 1 -02} + {3971386800 -7200 1 -03} {3980455200 -10800 0 -03} - {4002836400 -7200 1 -02} + {4002836400 -7200 1 -03} {4011904800 -10800 0 -03} - {4034286000 -7200 1 -02} + {4034286000 -7200 1 -03} {4043354400 -10800 0 -03} - {4065735600 -7200 1 -02} + {4065735600 -7200 1 -03} {4074804000 -10800 0 -03} - {4097185200 -7200 1 -02} + {4097185200 -7200 1 -03} } diff --git a/library/tzdata/Antarctica/Casey b/library/tzdata/Antarctica/Casey index beb0f9e..aa37480 100644 --- a/library/tzdata/Antarctica/Casey +++ b/library/tzdata/Antarctica/Casey @@ -8,4 +8,5 @@ set TZData(:Antarctica/Casey) { {1319738400 39600 0 +11} {1329843600 28800 0 +08} {1477065600 39600 0 +11} + {1520701200 28800 0 +08} } diff --git a/library/tzdata/Antarctica/Palmer b/library/tzdata/Antarctica/Palmer index bb2be4d..f450e3b 100644 --- a/library/tzdata/Antarctica/Palmer +++ b/library/tzdata/Antarctica/Palmer @@ -4,84 +4,84 @@ set TZData(:Antarctica/Palmer) { {-9223372036854775808 0 0 -00} {-157766400 -14400 0 -04} {-152654400 -14400 0 -04} - {-132955200 -10800 1 -03} + {-132955200 -10800 1 -04} {-121122000 -14400 0 -04} - {-101419200 -10800 1 -03} + {-101419200 -10800 1 -04} {-86821200 -14400 0 -04} - {-71092800 -10800 1 -03} + {-71092800 -10800 1 -04} {-54766800 -14400 0 -04} - {-39038400 -10800 1 -03} + {-39038400 -10800 1 -04} {-23317200 -14400 0 -04} {-7588800 -10800 0 -03} - {128142000 -7200 1 -02} + {128142000 -7200 1 -03} {136605600 -10800 0 -03} {389070000 -14400 0 -04} - {403070400 -10800 1 -03} + {403070400 -10800 1 -04} {416372400 -14400 0 -04} - {434520000 -10800 1 -03} + {434520000 -10800 1 -04} {447822000 -14400 0 -04} - {466574400 -10800 1 -03} + {466574400 -10800 1 -04} {479271600 -14400 0 -04} - {498024000 -10800 1 -03} + {498024000 -10800 1 -04} {510721200 -14400 0 -04} - {529473600 -10800 1 -03} + {529473600 -10800 1 -04} {545194800 -14400 0 -04} - {560923200 -10800 1 -03} + {560923200 -10800 1 -04} {574225200 -14400 0 -04} - {592372800 -10800 1 -03} + {592372800 -10800 1 -04} {605674800 -14400 0 -04} - {624427200 -10800 1 -03} + {624427200 -10800 1 -04} {637124400 -14400 0 -04} - {653457600 -10800 1 -03} + {653457600 -10800 1 -04} {668574000 -14400 0 -04} - {687326400 -10800 1 -03} + {687326400 -10800 1 -04} {700628400 -14400 0 -04} - {718776000 -10800 1 -03} + {718776000 -10800 1 -04} {732078000 -14400 0 -04} - {750225600 -10800 1 -03} + {750225600 -10800 1 -04} {763527600 -14400 0 -04} - {781675200 -10800 1 -03} + {781675200 -10800 1 -04} {794977200 -14400 0 -04} - {813729600 -10800 1 -03} + {813729600 -10800 1 -04} {826426800 -14400 0 -04} - {845179200 -10800 1 -03} + {845179200 -10800 1 -04} {859690800 -14400 0 -04} - {876628800 -10800 1 -03} + {876628800 -10800 1 -04} {889930800 -14400 0 -04} - {906868800 -10800 1 -03} + {906868800 -10800 1 -04} {923194800 -14400 0 -04} - {939528000 -10800 1 -03} + {939528000 -10800 1 -04} {952830000 -14400 0 -04} - {971582400 -10800 1 -03} + {971582400 -10800 1 -04} {984279600 -14400 0 -04} - {1003032000 -10800 1 -03} + {1003032000 -10800 1 -04} {1015729200 -14400 0 -04} - {1034481600 -10800 1 -03} + {1034481600 -10800 1 -04} {1047178800 -14400 0 -04} - {1065931200 -10800 1 -03} + {1065931200 -10800 1 -04} {1079233200 -14400 0 -04} - {1097380800 -10800 1 -03} + {1097380800 -10800 1 -04} {1110682800 -14400 0 -04} - {1128830400 -10800 1 -03} + {1128830400 -10800 1 -04} {1142132400 -14400 0 -04} - {1160884800 -10800 1 -03} + {1160884800 -10800 1 -04} {1173582000 -14400 0 -04} - {1192334400 -10800 1 -03} + {1192334400 -10800 1 -04} {1206846000 -14400 0 -04} - {1223784000 -10800 1 -03} + {1223784000 -10800 1 -04} {1237086000 -14400 0 -04} - {1255233600 -10800 1 -03} + {1255233600 -10800 1 -04} {1270350000 -14400 0 -04} - {1286683200 -10800 1 -03} + {1286683200 -10800 1 -04} {1304823600 -14400 0 -04} - {1313899200 -10800 1 -03} + {1313899200 -10800 1 -04} {1335668400 -14400 0 -04} - {1346558400 -10800 1 -03} + {1346558400 -10800 1 -04} {1367118000 -14400 0 -04} - {1378612800 -10800 1 -03} + {1378612800 -10800 1 -04} {1398567600 -14400 0 -04} - {1410062400 -10800 1 -03} + {1410062400 -10800 1 -04} {1463281200 -14400 0 -04} - {1471147200 -10800 1 -03} + {1471147200 -10800 1 -04} {1480820400 -10800 0 -03} } diff --git a/library/tzdata/Asia/Almaty b/library/tzdata/Asia/Almaty index 2b83197..f42935d 100644 --- a/library/tzdata/Asia/Almaty +++ b/library/tzdata/Asia/Almaty @@ -4,54 +4,54 @@ set TZData(:Asia/Almaty) { {-9223372036854775808 18468 0 LMT} {-1441170468 18000 0 +05} {-1247547600 21600 0 +06} - {354909600 25200 1 +07} + {354909600 25200 1 +06} {370717200 21600 0 +06} - {386445600 25200 1 +07} + {386445600 25200 1 +06} {402253200 21600 0 +06} - {417981600 25200 1 +07} + {417981600 25200 1 +06} {433789200 21600 0 +06} - {449604000 25200 1 +07} + {449604000 25200 1 +06} {465336000 21600 0 +06} - {481060800 25200 1 +07} + {481060800 25200 1 +06} {496785600 21600 0 +06} - {512510400 25200 1 +07} + {512510400 25200 1 +06} {528235200 21600 0 +06} - {543960000 25200 1 +07} + {543960000 25200 1 +06} {559684800 21600 0 +06} - {575409600 25200 1 +07} + {575409600 25200 1 +06} {591134400 21600 0 +06} - {606859200 25200 1 +07} + {606859200 25200 1 +06} {622584000 21600 0 +06} - {638308800 25200 1 +07} + {638308800 25200 1 +06} {654638400 21600 0 +06} {670363200 18000 0 +05} - {670366800 21600 1 +06} + {670366800 21600 1 +05} {686091600 18000 0 +05} {695768400 21600 0 +06} - {701812800 25200 1 +07} + {701812800 25200 1 +06} {717537600 21600 0 +06} - {733262400 25200 1 +07} + {733262400 25200 1 +06} {748987200 21600 0 +06} - {764712000 25200 1 +07} + {764712000 25200 1 +06} {780436800 21600 0 +06} - {796161600 25200 1 +07} + {796161600 25200 1 +06} {811886400 21600 0 +06} - {828216000 25200 1 +07} + {828216000 25200 1 +06} {846360000 21600 0 +06} - {859665600 25200 1 +07} + {859665600 25200 1 +06} {877809600 21600 0 +06} - {891115200 25200 1 +07} + {891115200 25200 1 +06} {909259200 21600 0 +06} - {922564800 25200 1 +07} + {922564800 25200 1 +06} {941313600 21600 0 +06} - {954014400 25200 1 +07} + {954014400 25200 1 +06} {972763200 21600 0 +06} - {985464000 25200 1 +07} + {985464000 25200 1 +06} {1004212800 21600 0 +06} - {1017518400 25200 1 +07} + {1017518400 25200 1 +06} {1035662400 21600 0 +06} - {1048968000 25200 1 +07} + {1048968000 25200 1 +06} {1067112000 21600 0 +06} - {1080417600 25200 1 +07} + {1080417600 25200 1 +06} {1099166400 21600 0 +06} } diff --git a/library/tzdata/Asia/Aqtau b/library/tzdata/Asia/Aqtau index c128b27..41da2ca 100644 --- a/library/tzdata/Asia/Aqtau +++ b/library/tzdata/Asia/Aqtau @@ -6,53 +6,53 @@ set TZData(:Asia/Aqtau) { {-1247544000 18000 0 +05} {370724400 21600 0 +06} {386445600 18000 0 +05} - {386449200 21600 1 +06} + {386449200 21600 1 +05} {402256800 18000 0 +05} - {417985200 21600 1 +06} + {417985200 21600 1 +05} {433792800 18000 0 +05} - {449607600 21600 1 +06} + {449607600 21600 1 +05} {465339600 18000 0 +05} - {481064400 21600 1 +06} + {481064400 21600 1 +05} {496789200 18000 0 +05} - {512514000 21600 1 +06} + {512514000 21600 1 +05} {528238800 18000 0 +05} - {543963600 21600 1 +06} + {543963600 21600 1 +05} {559688400 18000 0 +05} - {575413200 21600 1 +06} + {575413200 21600 1 +05} {591138000 18000 0 +05} - {606862800 21600 1 +06} + {606862800 21600 1 +05} {622587600 18000 0 +05} - {638312400 21600 1 +06} + {638312400 21600 1 +05} {654642000 18000 0 +05} {670366800 14400 0 +04} - {670370400 18000 1 +05} + {670370400 18000 1 +04} {686095200 14400 0 +04} {695772000 18000 0 +05} - {701816400 21600 1 +06} + {701816400 21600 1 +05} {717541200 18000 0 +05} - {733266000 21600 1 +06} + {733266000 21600 1 +05} {748990800 18000 0 +05} - {764715600 21600 1 +06} - {780440400 18000 0 +05} + {764715600 21600 1 +05} + {780440400 18000 0 +04} {780444000 14400 0 +04} - {796168800 18000 1 +05} + {796168800 18000 1 +04} {811893600 14400 0 +04} - {828223200 18000 1 +05} + {828223200 18000 1 +04} {846367200 14400 0 +04} - {859672800 18000 1 +05} + {859672800 18000 1 +04} {877816800 14400 0 +04} - {891122400 18000 1 +05} + {891122400 18000 1 +04} {909266400 14400 0 +04} - {922572000 18000 1 +05} + {922572000 18000 1 +04} {941320800 14400 0 +04} - {954021600 18000 1 +05} + {954021600 18000 1 +04} {972770400 14400 0 +04} - {985471200 18000 1 +05} + {985471200 18000 1 +04} {1004220000 14400 0 +04} - {1017525600 18000 1 +05} + {1017525600 18000 1 +04} {1035669600 14400 0 +04} - {1048975200 18000 1 +05} + {1048975200 18000 1 +04} {1067119200 14400 0 +04} - {1080424800 18000 1 +05} + {1080424800 18000 1 +04} {1099173600 18000 0 +05} } diff --git a/library/tzdata/Asia/Aqtobe b/library/tzdata/Asia/Aqtobe index 55ef556..2316e68 100644 --- a/library/tzdata/Asia/Aqtobe +++ b/library/tzdata/Asia/Aqtobe @@ -7,52 +7,52 @@ set TZData(:Asia/Aqtobe) { {354913200 21600 1 +06} {370720800 21600 0 +06} {386445600 18000 0 +05} - {386449200 21600 1 +06} + {386449200 21600 1 +05} {402256800 18000 0 +05} - {417985200 21600 1 +06} + {417985200 21600 1 +05} {433792800 18000 0 +05} - {449607600 21600 1 +06} + {449607600 21600 1 +05} {465339600 18000 0 +05} - {481064400 21600 1 +06} + {481064400 21600 1 +05} {496789200 18000 0 +05} - {512514000 21600 1 +06} + {512514000 21600 1 +05} {528238800 18000 0 +05} - {543963600 21600 1 +06} + {543963600 21600 1 +05} {559688400 18000 0 +05} - {575413200 21600 1 +06} + {575413200 21600 1 +05} {591138000 18000 0 +05} - {606862800 21600 1 +06} + {606862800 21600 1 +05} {622587600 18000 0 +05} - {638312400 21600 1 +06} + {638312400 21600 1 +05} {654642000 18000 0 +05} {670366800 14400 0 +04} - {670370400 18000 1 +05} + {670370400 18000 1 +04} {686095200 14400 0 +04} {695772000 18000 0 +05} - {701816400 21600 1 +06} + {701816400 21600 1 +05} {717541200 18000 0 +05} - {733266000 21600 1 +06} + {733266000 21600 1 +05} {748990800 18000 0 +05} - {764715600 21600 1 +06} + {764715600 21600 1 +05} {780440400 18000 0 +05} - {796165200 21600 1 +06} + {796165200 21600 1 +05} {811890000 18000 0 +05} - {828219600 21600 1 +06} + {828219600 21600 1 +05} {846363600 18000 0 +05} - {859669200 21600 1 +06} + {859669200 21600 1 +05} {877813200 18000 0 +05} - {891118800 21600 1 +06} + {891118800 21600 1 +05} {909262800 18000 0 +05} - {922568400 21600 1 +06} + {922568400 21600 1 +05} {941317200 18000 0 +05} - {954018000 21600 1 +06} + {954018000 21600 1 +05} {972766800 18000 0 +05} - {985467600 21600 1 +06} + {985467600 21600 1 +05} {1004216400 18000 0 +05} - {1017522000 21600 1 +06} + {1017522000 21600 1 +05} {1035666000 18000 0 +05} - {1048971600 21600 1 +06} + {1048971600 21600 1 +05} {1067115600 18000 0 +05} - {1080421200 21600 1 +06} + {1080421200 21600 1 +05} {1099170000 18000 0 +05} } diff --git a/library/tzdata/Asia/Ashgabat b/library/tzdata/Asia/Ashgabat index fa6a619..feb7725 100644 --- a/library/tzdata/Asia/Ashgabat +++ b/library/tzdata/Asia/Ashgabat @@ -4,28 +4,28 @@ set TZData(:Asia/Ashgabat) { {-9223372036854775808 14012 0 LMT} {-1441166012 14400 0 +04} {-1247544000 18000 0 +05} - {354913200 21600 1 +06} + {354913200 21600 1 +05} {370720800 18000 0 +05} - {386449200 21600 1 +06} + {386449200 21600 1 +05} {402256800 18000 0 +05} - {417985200 21600 1 +06} + {417985200 21600 1 +05} {433792800 18000 0 +05} - {449607600 21600 1 +06} + {449607600 21600 1 +05} {465339600 18000 0 +05} - {481064400 21600 1 +06} + {481064400 21600 1 +05} {496789200 18000 0 +05} - {512514000 21600 1 +06} + {512514000 21600 1 +05} {528238800 18000 0 +05} - {543963600 21600 1 +06} + {543963600 21600 1 +05} {559688400 18000 0 +05} - {575413200 21600 1 +06} + {575413200 21600 1 +05} {591138000 18000 0 +05} - {606862800 21600 1 +06} + {606862800 21600 1 +05} {622587600 18000 0 +05} - {638312400 21600 1 +06} + {638312400 21600 1 +05} {654642000 18000 0 +05} {670366800 14400 0 +04} - {670370400 18000 1 +05} + {670370400 18000 1 +04} {686095200 14400 0 +04} {695772000 18000 0 +05} } diff --git a/library/tzdata/Asia/Atyrau b/library/tzdata/Asia/Atyrau index c31ff11..b6d8253 100644 --- a/library/tzdata/Asia/Atyrau +++ b/library/tzdata/Asia/Atyrau @@ -6,53 +6,53 @@ set TZData(:Asia/Atyrau) { {-1247540400 18000 0 +05} {370724400 21600 0 +06} {386445600 18000 0 +05} - {386449200 21600 1 +06} + {386449200 21600 1 +05} {402256800 18000 0 +05} - {417985200 21600 1 +06} + {417985200 21600 1 +05} {433792800 18000 0 +05} - {449607600 21600 1 +06} + {449607600 21600 1 +05} {465339600 18000 0 +05} - {481064400 21600 1 +06} + {481064400 21600 1 +05} {496789200 18000 0 +05} - {512514000 21600 1 +06} + {512514000 21600 1 +05} {528238800 18000 0 +05} - {543963600 21600 1 +06} + {543963600 21600 1 +05} {559688400 18000 0 +05} - {575413200 21600 1 +06} + {575413200 21600 1 +05} {591138000 18000 0 +05} - {606862800 21600 1 +06} + {606862800 21600 1 +05} {622587600 18000 0 +05} - {638312400 21600 1 +06} + {638312400 21600 1 +05} {654642000 18000 0 +05} {670366800 14400 0 +04} - {670370400 18000 1 +05} + {670370400 18000 1 +04} {686095200 14400 0 +04} {695772000 18000 0 +05} - {701816400 21600 1 +06} + {701816400 21600 1 +05} {717541200 18000 0 +05} - {733266000 21600 1 +06} + {733266000 21600 1 +05} {748990800 18000 0 +05} - {764715600 21600 1 +06} + {764715600 21600 1 +05} {780440400 18000 0 +05} - {796165200 21600 1 +06} + {796165200 21600 1 +05} {811890000 18000 0 +05} - {828219600 21600 1 +06} + {828219600 21600 1 +05} {846363600 18000 0 +05} - {859669200 21600 1 +06} + {859669200 21600 1 +05} {877813200 18000 0 +05} - {891118800 21600 1 +06} + {891118800 21600 1 +05} {909262800 18000 0 +05} {922568400 14400 0 +04} - {922572000 18000 1 +05} + {922572000 18000 1 +04} {941320800 14400 0 +04} - {954021600 18000 1 +05} + {954021600 18000 1 +04} {972770400 14400 0 +04} - {985471200 18000 1 +05} + {985471200 18000 1 +04} {1004220000 14400 0 +04} - {1017525600 18000 1 +05} + {1017525600 18000 1 +04} {1035669600 14400 0 +04} - {1048975200 18000 1 +05} + {1048975200 18000 1 +04} {1067119200 14400 0 +04} - {1080424800 18000 1 +05} + {1080424800 18000 1 +04} {1099173600 18000 0 +05} } diff --git a/library/tzdata/Asia/Baghdad b/library/tzdata/Asia/Baghdad index 623e310..c76a6a1 100644 --- a/library/tzdata/Asia/Baghdad +++ b/library/tzdata/Asia/Baghdad @@ -4,56 +4,56 @@ set TZData(:Asia/Baghdad) { {-9223372036854775808 10660 0 LMT} {-2524532260 10656 0 BMT} {-1641005856 10800 0 +03} - {389048400 14400 0 +04} - {402264000 10800 0 +04} - {417906000 14400 1 +04} - {433800000 10800 0 +04} - {449614800 14400 1 +04} - {465422400 10800 0 +04} - {481150800 14400 1 +04} - {496792800 10800 0 +04} - {512517600 14400 1 +04} - {528242400 10800 0 +04} - {543967200 14400 1 +04} - {559692000 10800 0 +04} - {575416800 14400 1 +04} - {591141600 10800 0 +04} - {606866400 14400 1 +04} - {622591200 10800 0 +04} - {638316000 14400 1 +04} - {654645600 10800 0 +04} - {670464000 14400 1 +04} - {686275200 10800 0 +04} - {702086400 14400 1 +04} - {717897600 10800 0 +04} - {733622400 14400 1 +04} - {749433600 10800 0 +04} - {765158400 14400 1 +04} - {780969600 10800 0 +04} - {796694400 14400 1 +04} - {812505600 10800 0 +04} - {828316800 14400 1 +04} - {844128000 10800 0 +04} - {859852800 14400 1 +04} - {875664000 10800 0 +04} - {891388800 14400 1 +04} - {907200000 10800 0 +04} - {922924800 14400 1 +04} - {938736000 10800 0 +04} - {954547200 14400 1 +04} - {970358400 10800 0 +04} - {986083200 14400 1 +04} - {1001894400 10800 0 +04} - {1017619200 14400 1 +04} - {1033430400 10800 0 +04} - {1049155200 14400 1 +04} - {1064966400 10800 0 +04} - {1080777600 14400 1 +04} - {1096588800 10800 0 +04} - {1112313600 14400 1 +04} - {1128124800 10800 0 +04} - {1143849600 14400 1 +04} - {1159660800 10800 0 +04} - {1175385600 14400 1 +04} - {1191196800 10800 0 +04} + {389048400 14400 0 +03} + {402264000 10800 0 +03} + {417906000 14400 1 +03} + {433800000 10800 0 +03} + {449614800 14400 1 +03} + {465422400 10800 0 +03} + {481150800 14400 1 +03} + {496792800 10800 0 +03} + {512517600 14400 1 +03} + {528242400 10800 0 +03} + {543967200 14400 1 +03} + {559692000 10800 0 +03} + {575416800 14400 1 +03} + {591141600 10800 0 +03} + {606866400 14400 1 +03} + {622591200 10800 0 +03} + {638316000 14400 1 +03} + {654645600 10800 0 +03} + {670464000 14400 1 +03} + {686275200 10800 0 +03} + {702086400 14400 1 +03} + {717897600 10800 0 +03} + {733622400 14400 1 +03} + {749433600 10800 0 +03} + {765158400 14400 1 +03} + {780969600 10800 0 +03} + {796694400 14400 1 +03} + {812505600 10800 0 +03} + {828316800 14400 1 +03} + {844128000 10800 0 +03} + {859852800 14400 1 +03} + {875664000 10800 0 +03} + {891388800 14400 1 +03} + {907200000 10800 0 +03} + {922924800 14400 1 +03} + {938736000 10800 0 +03} + {954547200 14400 1 +03} + {970358400 10800 0 +03} + {986083200 14400 1 +03} + {1001894400 10800 0 +03} + {1017619200 14400 1 +03} + {1033430400 10800 0 +03} + {1049155200 14400 1 +03} + {1064966400 10800 0 +03} + {1080777600 14400 1 +03} + {1096588800 10800 0 +03} + {1112313600 14400 1 +03} + {1128124800 10800 0 +03} + {1143849600 14400 1 +03} + {1159660800 10800 0 +03} + {1175385600 14400 1 +03} + {1191196800 10800 0 +03} } diff --git a/library/tzdata/Asia/Baku b/library/tzdata/Asia/Baku index f945b89..03dee19 100644 --- a/library/tzdata/Asia/Baku +++ b/library/tzdata/Asia/Baku @@ -4,71 +4,71 @@ set TZData(:Asia/Baku) { {-9223372036854775808 11964 0 LMT} {-1441163964 10800 0 +03} {-405140400 14400 0 +04} - {354916800 18000 1 +05} + {354916800 18000 1 +04} {370724400 14400 0 +04} - {386452800 18000 1 +05} + {386452800 18000 1 +04} {402260400 14400 0 +04} - {417988800 18000 1 +05} + {417988800 18000 1 +04} {433796400 14400 0 +04} - {449611200 18000 1 +05} + {449611200 18000 1 +04} {465343200 14400 0 +04} - {481068000 18000 1 +05} + {481068000 18000 1 +04} {496792800 14400 0 +04} - {512517600 18000 1 +05} + {512517600 18000 1 +04} {528242400 14400 0 +04} - {543967200 18000 1 +05} + {543967200 18000 1 +04} {559692000 14400 0 +04} - {575416800 18000 1 +05} + {575416800 18000 1 +04} {591141600 14400 0 +04} - {606866400 18000 1 +05} + {606866400 18000 1 +04} {622591200 14400 0 +04} - {638316000 18000 1 +05} + {638316000 18000 1 +04} {654645600 14400 0 +04} {670370400 10800 0 +03} - {670374000 14400 1 +04} + {670374000 14400 1 +03} {686098800 10800 0 +03} - {701823600 14400 1 +04} + {701823600 14400 1 +03} {717548400 14400 0 +04} {820440000 14400 0 +04} {828234000 18000 1 +05} {846378000 14400 0 +04} {852062400 14400 0 +04} - {859680000 18000 1 +05} + {859680000 18000 1 +04} {877824000 14400 0 +04} - {891129600 18000 1 +05} + {891129600 18000 1 +04} {909273600 14400 0 +04} - {922579200 18000 1 +05} + {922579200 18000 1 +04} {941328000 14400 0 +04} - {954028800 18000 1 +05} + {954028800 18000 1 +04} {972777600 14400 0 +04} - {985478400 18000 1 +05} + {985478400 18000 1 +04} {1004227200 14400 0 +04} - {1017532800 18000 1 +05} + {1017532800 18000 1 +04} {1035676800 14400 0 +04} - {1048982400 18000 1 +05} + {1048982400 18000 1 +04} {1067126400 14400 0 +04} - {1080432000 18000 1 +05} + {1080432000 18000 1 +04} {1099180800 14400 0 +04} - {1111881600 18000 1 +05} + {1111881600 18000 1 +04} {1130630400 14400 0 +04} - {1143331200 18000 1 +05} + {1143331200 18000 1 +04} {1162080000 14400 0 +04} - {1174780800 18000 1 +05} + {1174780800 18000 1 +04} {1193529600 14400 0 +04} - {1206835200 18000 1 +05} + {1206835200 18000 1 +04} {1224979200 14400 0 +04} - {1238284800 18000 1 +05} + {1238284800 18000 1 +04} {1256428800 14400 0 +04} - {1269734400 18000 1 +05} + {1269734400 18000 1 +04} {1288483200 14400 0 +04} - {1301184000 18000 1 +05} + {1301184000 18000 1 +04} {1319932800 14400 0 +04} - {1332633600 18000 1 +05} + {1332633600 18000 1 +04} {1351382400 14400 0 +04} - {1364688000 18000 1 +05} + {1364688000 18000 1 +04} {1382832000 14400 0 +04} - {1396137600 18000 1 +05} + {1396137600 18000 1 +04} {1414281600 14400 0 +04} - {1427587200 18000 1 +05} + {1427587200 18000 1 +04} {1445731200 14400 0 +04} } diff --git a/library/tzdata/Asia/Bishkek b/library/tzdata/Asia/Bishkek index a02d789..bc4cbdd 100644 --- a/library/tzdata/Asia/Bishkek +++ b/library/tzdata/Asia/Bishkek @@ -4,55 +4,55 @@ set TZData(:Asia/Bishkek) { {-9223372036854775808 17904 0 LMT} {-1441169904 18000 0 +05} {-1247547600 21600 0 +06} - {354909600 25200 1 +07} + {354909600 25200 1 +06} {370717200 21600 0 +06} - {386445600 25200 1 +07} + {386445600 25200 1 +06} {402253200 21600 0 +06} - {417981600 25200 1 +07} + {417981600 25200 1 +06} {433789200 21600 0 +06} - {449604000 25200 1 +07} + {449604000 25200 1 +06} {465336000 21600 0 +06} - {481060800 25200 1 +07} + {481060800 25200 1 +06} {496785600 21600 0 +06} - {512510400 25200 1 +07} + {512510400 25200 1 +06} {528235200 21600 0 +06} - {543960000 25200 1 +07} + {543960000 25200 1 +06} {559684800 21600 0 +06} - {575409600 25200 1 +07} + {575409600 25200 1 +06} {591134400 21600 0 +06} - {606859200 25200 1 +07} + {606859200 25200 1 +06} {622584000 21600 0 +06} - {638308800 25200 1 +07} + {638308800 25200 1 +06} {654638400 21600 0 +06} {670363200 18000 0 +05} - {670366800 21600 1 +06} + {670366800 21600 1 +05} {683586000 18000 0 +05} - {703018800 21600 1 +06} + {703018800 21600 1 +05} {717530400 18000 0 +05} - {734468400 21600 1 +06} + {734468400 21600 1 +05} {748980000 18000 0 +05} - {765918000 21600 1 +06} + {765918000 21600 1 +05} {780429600 18000 0 +05} - {797367600 21600 1 +06} + {797367600 21600 1 +05} {811879200 18000 0 +05} - {828817200 21600 1 +06} + {828817200 21600 1 +05} {843933600 18000 0 +05} - {859671000 21600 1 +06} + {859671000 21600 1 +05} {877811400 18000 0 +05} - {891120600 21600 1 +06} + {891120600 21600 1 +05} {909261000 18000 0 +05} - {922570200 21600 1 +06} + {922570200 21600 1 +05} {941315400 18000 0 +05} - {954019800 21600 1 +06} + {954019800 21600 1 +05} {972765000 18000 0 +05} - {985469400 21600 1 +06} + {985469400 21600 1 +05} {1004214600 18000 0 +05} - {1017523800 21600 1 +06} + {1017523800 21600 1 +05} {1035664200 18000 0 +05} - {1048973400 21600 1 +06} + {1048973400 21600 1 +05} {1067113800 18000 0 +05} - {1080423000 21600 1 +06} + {1080423000 21600 1 +05} {1099168200 18000 0 +05} - {1111872600 21600 1 +06} + {1111872600 21600 1 +05} {1123783200 21600 0 +06} } diff --git a/library/tzdata/Asia/Choibalsan b/library/tzdata/Asia/Choibalsan index 3db65de..b072c76 100644 --- a/library/tzdata/Asia/Choibalsan +++ b/library/tzdata/Asia/Choibalsan @@ -4,53 +4,53 @@ set TZData(:Asia/Choibalsan) { {-9223372036854775808 27480 0 LMT} {-2032933080 25200 0 +07} {252435600 28800 0 +08} - {417974400 36000 0 +10} + {417974400 36000 0 +09} {433778400 32400 0 +09} - {449593200 36000 1 +10} + {449593200 36000 1 +09} {465314400 32400 0 +09} - {481042800 36000 1 +10} + {481042800 36000 1 +09} {496764000 32400 0 +09} - {512492400 36000 1 +10} + {512492400 36000 1 +09} {528213600 32400 0 +09} - {543942000 36000 1 +10} + {543942000 36000 1 +09} {559663200 32400 0 +09} - {575391600 36000 1 +10} + {575391600 36000 1 +09} {591112800 32400 0 +09} - {606841200 36000 1 +10} + {606841200 36000 1 +09} {622562400 32400 0 +09} - {638290800 36000 1 +10} + {638290800 36000 1 +09} {654616800 32400 0 +09} - {670345200 36000 1 +10} + {670345200 36000 1 +09} {686066400 32400 0 +09} - {701794800 36000 1 +10} + {701794800 36000 1 +09} {717516000 32400 0 +09} - {733244400 36000 1 +10} + {733244400 36000 1 +09} {748965600 32400 0 +09} - {764694000 36000 1 +10} + {764694000 36000 1 +09} {780415200 32400 0 +09} - {796143600 36000 1 +10} + {796143600 36000 1 +09} {811864800 32400 0 +09} - {828198000 36000 1 +10} + {828198000 36000 1 +09} {843919200 32400 0 +09} - {859647600 36000 1 +10} + {859647600 36000 1 +09} {875368800 32400 0 +09} - {891097200 36000 1 +10} + {891097200 36000 1 +09} {906818400 32400 0 +09} - {988390800 36000 1 +10} + {988390800 36000 1 +09} {1001692800 32400 0 +09} - {1017421200 36000 1 +10} + {1017421200 36000 1 +09} {1033142400 32400 0 +09} - {1048870800 36000 1 +10} + {1048870800 36000 1 +09} {1064592000 32400 0 +09} - {1080320400 36000 1 +10} + {1080320400 36000 1 +09} {1096041600 32400 0 +09} - {1111770000 36000 1 +10} + {1111770000 36000 1 +09} {1127491200 32400 0 +09} - {1143219600 36000 1 +10} + {1143219600 36000 1 +09} {1159545600 32400 0 +09} {1206889200 28800 0 +08} - {1427479200 32400 1 +09} + {1427479200 32400 1 +08} {1443193200 28800 0 +08} - {1458928800 32400 1 +09} + {1458928800 32400 1 +08} {1474642800 28800 0 +08} } diff --git a/library/tzdata/Asia/Dhaka b/library/tzdata/Asia/Dhaka index 0dc3987..c044095 100644 --- a/library/tzdata/Asia/Dhaka +++ b/library/tzdata/Asia/Dhaka @@ -8,6 +8,6 @@ set TZData(:Asia/Dhaka) { {-862637400 23400 0 +0630} {-576138600 21600 0 +06} {1230746400 21600 0 +06} - {1245430800 25200 1 +07} + {1245430800 25200 1 +06} {1262278800 21600 0 +06} } diff --git a/library/tzdata/Asia/Dushanbe b/library/tzdata/Asia/Dushanbe index e9ed132..fe82ce7 100644 --- a/library/tzdata/Asia/Dushanbe +++ b/library/tzdata/Asia/Dushanbe @@ -4,25 +4,25 @@ set TZData(:Asia/Dushanbe) { {-9223372036854775808 16512 0 LMT} {-1441168512 18000 0 +05} {-1247547600 21600 0 +06} - {354909600 25200 1 +07} + {354909600 25200 1 +06} {370717200 21600 0 +06} - {386445600 25200 1 +07} + {386445600 25200 1 +06} {402253200 21600 0 +06} - {417981600 25200 1 +07} + {417981600 25200 1 +06} {433789200 21600 0 +06} - {449604000 25200 1 +07} + {449604000 25200 1 +06} {465336000 21600 0 +06} - {481060800 25200 1 +07} + {481060800 25200 1 +06} {496785600 21600 0 +06} - {512510400 25200 1 +07} + {512510400 25200 1 +06} {528235200 21600 0 +06} - {543960000 25200 1 +07} + {543960000 25200 1 +06} {559684800 21600 0 +06} - {575409600 25200 1 +07} + {575409600 25200 1 +06} {591134400 21600 0 +06} - {606859200 25200 1 +07} + {606859200 25200 1 +06} {622584000 21600 0 +06} - {638308800 25200 1 +07} + {638308800 25200 1 +06} {654638400 21600 0 +06} {670363200 21600 1 +06} {684363600 18000 0 +05} diff --git a/library/tzdata/Asia/Gaza b/library/tzdata/Asia/Gaza index 1149d51..85b9f67 100644 --- a/library/tzdata/Asia/Gaza +++ b/library/tzdata/Asia/Gaza @@ -111,9 +111,9 @@ set TZData(:Asia/Gaza) { {1477692000 7200 0 EET} {1490396400 10800 1 EEST} {1509141600 7200 0 EET} - {1522450800 10800 1 EEST} + {1521846000 10800 1 EEST} {1540591200 7200 0 EET} - {1553900400 10800 1 EEST} + {1553295600 10800 1 EEST} {1572040800 7200 0 EET} {1585350000 10800 1 EEST} {1604095200 7200 0 EET} @@ -123,9 +123,9 @@ set TZData(:Asia/Gaza) { {1666994400 7200 0 EET} {1679698800 10800 1 EEST} {1698444000 7200 0 EET} - {1711753200 10800 1 EEST} + {1711148400 10800 1 EEST} {1729893600 7200 0 EET} - {1743202800 10800 1 EEST} + {1742598000 10800 1 EEST} {1761343200 7200 0 EET} {1774652400 10800 1 EEST} {1793397600 7200 0 EET} @@ -133,11 +133,11 @@ set TZData(:Asia/Gaza) { {1824847200 7200 0 EET} {1837551600 10800 1 EEST} {1856296800 7200 0 EET} - {1869606000 10800 1 EEST} + {1869001200 10800 1 EEST} {1887746400 7200 0 EET} - {1901055600 10800 1 EEST} + {1900450800 10800 1 EEST} {1919196000 7200 0 EET} - {1932505200 10800 1 EEST} + {1931900400 10800 1 EEST} {1950645600 7200 0 EET} {1963954800 10800 1 EEST} {1982700000 7200 0 EET} @@ -145,9 +145,9 @@ set TZData(:Asia/Gaza) { {2014149600 7200 0 EET} {2026854000 10800 1 EEST} {2045599200 7200 0 EET} - {2058908400 10800 1 EEST} + {2058303600 10800 1 EEST} {2077048800 7200 0 EET} - {2090358000 10800 1 EEST} + {2089753200 10800 1 EEST} {2108498400 7200 0 EET} {2121807600 10800 1 EEST} {2140552800 7200 0 EET} @@ -155,11 +155,11 @@ set TZData(:Asia/Gaza) { {2172002400 7200 0 EET} {2184706800 10800 1 EEST} {2203452000 7200 0 EET} - {2216761200 10800 1 EEST} + {2216156400 10800 1 EEST} {2234901600 7200 0 EET} - {2248210800 10800 1 EEST} + {2247606000 10800 1 EEST} {2266351200 7200 0 EET} - {2279660400 10800 1 EEST} + {2279055600 10800 1 EEST} {2297800800 7200 0 EET} {2311110000 10800 1 EEST} {2329855200 7200 0 EET} @@ -167,9 +167,9 @@ set TZData(:Asia/Gaza) { {2361304800 7200 0 EET} {2374009200 10800 1 EEST} {2392754400 7200 0 EET} - {2406063600 10800 1 EEST} + {2405458800 10800 1 EEST} {2424204000 7200 0 EET} - {2437513200 10800 1 EEST} + {2436908400 10800 1 EEST} {2455653600 7200 0 EET} {2468962800 10800 1 EEST} {2487708000 7200 0 EET} @@ -179,9 +179,9 @@ set TZData(:Asia/Gaza) { {2550607200 7200 0 EET} {2563311600 10800 1 EEST} {2582056800 7200 0 EET} - {2595366000 10800 1 EEST} + {2594761200 10800 1 EEST} {2613506400 7200 0 EET} - {2626815600 10800 1 EEST} + {2626210800 10800 1 EEST} {2644956000 7200 0 EET} {2658265200 10800 1 EEST} {2677010400 7200 0 EET} @@ -189,11 +189,11 @@ set TZData(:Asia/Gaza) { {2708460000 7200 0 EET} {2721164400 10800 1 EEST} {2739909600 7200 0 EET} - {2753218800 10800 1 EEST} + {2752614000 10800 1 EEST} {2771359200 7200 0 EET} - {2784668400 10800 1 EEST} + {2784063600 10800 1 EEST} {2802808800 7200 0 EET} - {2816118000 10800 1 EEST} + {2815513200 10800 1 EEST} {2834258400 7200 0 EET} {2847567600 10800 1 EEST} {2866312800 7200 0 EET} @@ -201,9 +201,9 @@ set TZData(:Asia/Gaza) { {2897762400 7200 0 EET} {2910466800 10800 1 EEST} {2929212000 7200 0 EET} - {2942521200 10800 1 EEST} + {2941916400 10800 1 EEST} {2960661600 7200 0 EET} - {2973970800 10800 1 EEST} + {2973366000 10800 1 EEST} {2992111200 7200 0 EET} {3005420400 10800 1 EEST} {3024165600 7200 0 EET} @@ -211,11 +211,11 @@ set TZData(:Asia/Gaza) { {3055615200 7200 0 EET} {3068319600 10800 1 EEST} {3087064800 7200 0 EET} - {3100374000 10800 1 EEST} + {3099769200 10800 1 EEST} {3118514400 7200 0 EET} - {3131823600 10800 1 EEST} + {3131218800 10800 1 EEST} {3149964000 7200 0 EET} - {3163273200 10800 1 EEST} + {3162668400 10800 1 EEST} {3181413600 7200 0 EET} {3194722800 10800 1 EEST} {3213468000 7200 0 EET} @@ -223,9 +223,9 @@ set TZData(:Asia/Gaza) { {3244917600 7200 0 EET} {3257622000 10800 1 EEST} {3276367200 7200 0 EET} - {3289676400 10800 1 EEST} + {3289071600 10800 1 EEST} {3307816800 7200 0 EET} - {3321126000 10800 1 EEST} + {3320521200 10800 1 EEST} {3339266400 7200 0 EET} {3352575600 10800 1 EEST} {3371320800 7200 0 EET} @@ -235,9 +235,9 @@ set TZData(:Asia/Gaza) { {3434220000 7200 0 EET} {3446924400 10800 1 EEST} {3465669600 7200 0 EET} - {3478978800 10800 1 EEST} + {3478374000 10800 1 EEST} {3497119200 7200 0 EET} - {3510428400 10800 1 EEST} + {3509823600 10800 1 EEST} {3528568800 7200 0 EET} {3541878000 10800 1 EEST} {3560623200 7200 0 EET} @@ -245,11 +245,11 @@ set TZData(:Asia/Gaza) { {3592072800 7200 0 EET} {3604777200 10800 1 EEST} {3623522400 7200 0 EET} - {3636831600 10800 1 EEST} + {3636226800 10800 1 EEST} {3654972000 7200 0 EET} - {3668281200 10800 1 EEST} + {3667676400 10800 1 EEST} {3686421600 7200 0 EET} - {3699730800 10800 1 EEST} + {3699126000 10800 1 EEST} {3717871200 7200 0 EET} {3731180400 10800 1 EEST} {3749925600 7200 0 EET} @@ -257,9 +257,9 @@ set TZData(:Asia/Gaza) { {3781375200 7200 0 EET} {3794079600 10800 1 EEST} {3812824800 7200 0 EET} - {3826134000 10800 1 EEST} + {3825529200 10800 1 EEST} {3844274400 7200 0 EET} - {3857583600 10800 1 EEST} + {3856978800 10800 1 EEST} {3875724000 7200 0 EET} {3889033200 10800 1 EEST} {3907778400 7200 0 EET} @@ -267,11 +267,11 @@ set TZData(:Asia/Gaza) { {3939228000 7200 0 EET} {3951932400 10800 1 EEST} {3970677600 7200 0 EET} - {3983986800 10800 1 EEST} + {3983382000 10800 1 EEST} {4002127200 7200 0 EET} - {4015436400 10800 1 EEST} + {4014831600 10800 1 EEST} {4033576800 7200 0 EET} - {4046886000 10800 1 EEST} + {4046281200 10800 1 EEST} {4065026400 7200 0 EET} {4078335600 10800 1 EEST} {4097080800 7200 0 EET} diff --git a/library/tzdata/Asia/Hebron b/library/tzdata/Asia/Hebron index 5d312b8..c0f5447 100644 --- a/library/tzdata/Asia/Hebron +++ b/library/tzdata/Asia/Hebron @@ -110,9 +110,9 @@ set TZData(:Asia/Hebron) { {1477692000 7200 0 EET} {1490396400 10800 1 EEST} {1509141600 7200 0 EET} - {1522450800 10800 1 EEST} + {1521846000 10800 1 EEST} {1540591200 7200 0 EET} - {1553900400 10800 1 EEST} + {1553295600 10800 1 EEST} {1572040800 7200 0 EET} {1585350000 10800 1 EEST} {1604095200 7200 0 EET} @@ -122,9 +122,9 @@ set TZData(:Asia/Hebron) { {1666994400 7200 0 EET} {1679698800 10800 1 EEST} {1698444000 7200 0 EET} - {1711753200 10800 1 EEST} + {1711148400 10800 1 EEST} {1729893600 7200 0 EET} - {1743202800 10800 1 EEST} + {1742598000 10800 1 EEST} {1761343200 7200 0 EET} {1774652400 10800 1 EEST} {1793397600 7200 0 EET} @@ -132,11 +132,11 @@ set TZData(:Asia/Hebron) { {1824847200 7200 0 EET} {1837551600 10800 1 EEST} {1856296800 7200 0 EET} - {1869606000 10800 1 EEST} + {1869001200 10800 1 EEST} {1887746400 7200 0 EET} - {1901055600 10800 1 EEST} + {1900450800 10800 1 EEST} {1919196000 7200 0 EET} - {1932505200 10800 1 EEST} + {1931900400 10800 1 EEST} {1950645600 7200 0 EET} {1963954800 10800 1 EEST} {1982700000 7200 0 EET} @@ -144,9 +144,9 @@ set TZData(:Asia/Hebron) { {2014149600 7200 0 EET} {2026854000 10800 1 EEST} {2045599200 7200 0 EET} - {2058908400 10800 1 EEST} + {2058303600 10800 1 EEST} {2077048800 7200 0 EET} - {2090358000 10800 1 EEST} + {2089753200 10800 1 EEST} {2108498400 7200 0 EET} {2121807600 10800 1 EEST} {2140552800 7200 0 EET} @@ -154,11 +154,11 @@ set TZData(:Asia/Hebron) { {2172002400 7200 0 EET} {2184706800 10800 1 EEST} {2203452000 7200 0 EET} - {2216761200 10800 1 EEST} + {2216156400 10800 1 EEST} {2234901600 7200 0 EET} - {2248210800 10800 1 EEST} + {2247606000 10800 1 EEST} {2266351200 7200 0 EET} - {2279660400 10800 1 EEST} + {2279055600 10800 1 EEST} {2297800800 7200 0 EET} {2311110000 10800 1 EEST} {2329855200 7200 0 EET} @@ -166,9 +166,9 @@ set TZData(:Asia/Hebron) { {2361304800 7200 0 EET} {2374009200 10800 1 EEST} {2392754400 7200 0 EET} - {2406063600 10800 1 EEST} + {2405458800 10800 1 EEST} {2424204000 7200 0 EET} - {2437513200 10800 1 EEST} + {2436908400 10800 1 EEST} {2455653600 7200 0 EET} {2468962800 10800 1 EEST} {2487708000 7200 0 EET} @@ -178,9 +178,9 @@ set TZData(:Asia/Hebron) { {2550607200 7200 0 EET} {2563311600 10800 1 EEST} {2582056800 7200 0 EET} - {2595366000 10800 1 EEST} + {2594761200 10800 1 EEST} {2613506400 7200 0 EET} - {2626815600 10800 1 EEST} + {2626210800 10800 1 EEST} {2644956000 7200 0 EET} {2658265200 10800 1 EEST} {2677010400 7200 0 EET} @@ -188,11 +188,11 @@ set TZData(:Asia/Hebron) { {2708460000 7200 0 EET} {2721164400 10800 1 EEST} {2739909600 7200 0 EET} - {2753218800 10800 1 EEST} + {2752614000 10800 1 EEST} {2771359200 7200 0 EET} - {2784668400 10800 1 EEST} + {2784063600 10800 1 EEST} {2802808800 7200 0 EET} - {2816118000 10800 1 EEST} + {2815513200 10800 1 EEST} {2834258400 7200 0 EET} {2847567600 10800 1 EEST} {2866312800 7200 0 EET} @@ -200,9 +200,9 @@ set TZData(:Asia/Hebron) { {2897762400 7200 0 EET} {2910466800 10800 1 EEST} {2929212000 7200 0 EET} - {2942521200 10800 1 EEST} + {2941916400 10800 1 EEST} {2960661600 7200 0 EET} - {2973970800 10800 1 EEST} + {2973366000 10800 1 EEST} {2992111200 7200 0 EET} {3005420400 10800 1 EEST} {3024165600 7200 0 EET} @@ -210,11 +210,11 @@ set TZData(:Asia/Hebron) { {3055615200 7200 0 EET} {3068319600 10800 1 EEST} {3087064800 7200 0 EET} - {3100374000 10800 1 EEST} + {3099769200 10800 1 EEST} {3118514400 7200 0 EET} - {3131823600 10800 1 EEST} + {3131218800 10800 1 EEST} {3149964000 7200 0 EET} - {3163273200 10800 1 EEST} + {3162668400 10800 1 EEST} {3181413600 7200 0 EET} {3194722800 10800 1 EEST} {3213468000 7200 0 EET} @@ -222,9 +222,9 @@ set TZData(:Asia/Hebron) { {3244917600 7200 0 EET} {3257622000 10800 1 EEST} {3276367200 7200 0 EET} - {3289676400 10800 1 EEST} + {3289071600 10800 1 EEST} {3307816800 7200 0 EET} - {3321126000 10800 1 EEST} + {3320521200 10800 1 EEST} {3339266400 7200 0 EET} {3352575600 10800 1 EEST} {3371320800 7200 0 EET} @@ -234,9 +234,9 @@ set TZData(:Asia/Hebron) { {3434220000 7200 0 EET} {3446924400 10800 1 EEST} {3465669600 7200 0 EET} - {3478978800 10800 1 EEST} + {3478374000 10800 1 EEST} {3497119200 7200 0 EET} - {3510428400 10800 1 EEST} + {3509823600 10800 1 EEST} {3528568800 7200 0 EET} {3541878000 10800 1 EEST} {3560623200 7200 0 EET} @@ -244,11 +244,11 @@ set TZData(:Asia/Hebron) { {3592072800 7200 0 EET} {3604777200 10800 1 EEST} {3623522400 7200 0 EET} - {3636831600 10800 1 EEST} + {3636226800 10800 1 EEST} {3654972000 7200 0 EET} - {3668281200 10800 1 EEST} + {3667676400 10800 1 EEST} {3686421600 7200 0 EET} - {3699730800 10800 1 EEST} + {3699126000 10800 1 EEST} {3717871200 7200 0 EET} {3731180400 10800 1 EEST} {3749925600 7200 0 EET} @@ -256,9 +256,9 @@ set TZData(:Asia/Hebron) { {3781375200 7200 0 EET} {3794079600 10800 1 EEST} {3812824800 7200 0 EET} - {3826134000 10800 1 EEST} + {3825529200 10800 1 EEST} {3844274400 7200 0 EET} - {3857583600 10800 1 EEST} + {3856978800 10800 1 EEST} {3875724000 7200 0 EET} {3889033200 10800 1 EEST} {3907778400 7200 0 EET} @@ -266,11 +266,11 @@ set TZData(:Asia/Hebron) { {3939228000 7200 0 EET} {3951932400 10800 1 EEST} {3970677600 7200 0 EET} - {3983986800 10800 1 EEST} + {3983382000 10800 1 EEST} {4002127200 7200 0 EET} - {4015436400 10800 1 EEST} + {4014831600 10800 1 EEST} {4033576800 7200 0 EET} - {4046886000 10800 1 EEST} + {4046281200 10800 1 EEST} {4065026400 7200 0 EET} {4078335600 10800 1 EEST} {4097080800 7200 0 EET} diff --git a/library/tzdata/Asia/Hovd b/library/tzdata/Asia/Hovd index a9c995b..9b14d5b 100644 --- a/library/tzdata/Asia/Hovd +++ b/library/tzdata/Asia/Hovd @@ -4,52 +4,52 @@ set TZData(:Asia/Hovd) { {-9223372036854775808 21996 0 LMT} {-2032927596 21600 0 +06} {252439200 25200 0 +07} - {417978000 28800 1 +08} + {417978000 28800 1 +07} {433785600 25200 0 +07} - {449600400 28800 1 +08} + {449600400 28800 1 +07} {465321600 25200 0 +07} - {481050000 28800 1 +08} + {481050000 28800 1 +07} {496771200 25200 0 +07} - {512499600 28800 1 +08} + {512499600 28800 1 +07} {528220800 25200 0 +07} - {543949200 28800 1 +08} + {543949200 28800 1 +07} {559670400 25200 0 +07} - {575398800 28800 1 +08} + {575398800 28800 1 +07} {591120000 25200 0 +07} - {606848400 28800 1 +08} + {606848400 28800 1 +07} {622569600 25200 0 +07} - {638298000 28800 1 +08} + {638298000 28800 1 +07} {654624000 25200 0 +07} - {670352400 28800 1 +08} + {670352400 28800 1 +07} {686073600 25200 0 +07} - {701802000 28800 1 +08} + {701802000 28800 1 +07} {717523200 25200 0 +07} - {733251600 28800 1 +08} + {733251600 28800 1 +07} {748972800 25200 0 +07} - {764701200 28800 1 +08} + {764701200 28800 1 +07} {780422400 25200 0 +07} - {796150800 28800 1 +08} + {796150800 28800 1 +07} {811872000 25200 0 +07} - {828205200 28800 1 +08} + {828205200 28800 1 +07} {843926400 25200 0 +07} - {859654800 28800 1 +08} + {859654800 28800 1 +07} {875376000 25200 0 +07} - {891104400 28800 1 +08} + {891104400 28800 1 +07} {906825600 25200 0 +07} - {988398000 28800 1 +08} + {988398000 28800 1 +07} {1001700000 25200 0 +07} - {1017428400 28800 1 +08} + {1017428400 28800 1 +07} {1033149600 25200 0 +07} - {1048878000 28800 1 +08} + {1048878000 28800 1 +07} {1064599200 25200 0 +07} - {1080327600 28800 1 +08} + {1080327600 28800 1 +07} {1096048800 25200 0 +07} - {1111777200 28800 1 +08} + {1111777200 28800 1 +07} {1127498400 25200 0 +07} - {1143226800 28800 1 +08} + {1143226800 28800 1 +07} {1159552800 25200 0 +07} - {1427482800 28800 1 +08} + {1427482800 28800 1 +07} {1443196800 25200 0 +07} - {1458932400 28800 1 +08} + {1458932400 28800 1 +07} {1474646400 25200 0 +07} } diff --git a/library/tzdata/Asia/Kuching b/library/tzdata/Asia/Kuching index d6f5ad4..e5dc1b7 100644 --- a/library/tzdata/Asia/Kuching +++ b/library/tzdata/Asia/Kuching @@ -4,19 +4,19 @@ set TZData(:Asia/Kuching) { {-9223372036854775808 26480 0 LMT} {-1383463280 27000 0 +0730} {-1167636600 28800 0 +08} - {-1082448000 30000 1 +0820} + {-1082448000 30000 1 +08} {-1074586800 28800 0 +08} - {-1050825600 30000 1 +0820} + {-1050825600 30000 1 +08} {-1042964400 28800 0 +08} - {-1019289600 30000 1 +0820} + {-1019289600 30000 1 +08} {-1011428400 28800 0 +08} - {-987753600 30000 1 +0820} + {-987753600 30000 1 +08} {-979892400 28800 0 +08} - {-956217600 30000 1 +0820} + {-956217600 30000 1 +08} {-948356400 28800 0 +08} - {-924595200 30000 1 +0820} + {-924595200 30000 1 +08} {-916734000 28800 0 +08} - {-893059200 30000 1 +0820} + {-893059200 30000 1 +08} {-885198000 28800 0 +08} {-879667200 32400 0 +09} {-767005200 28800 0 +08} diff --git a/library/tzdata/Asia/Macau b/library/tzdata/Asia/Macau index 8458a8a..76a00aa 100644 --- a/library/tzdata/Asia/Macau +++ b/library/tzdata/Asia/Macau @@ -2,7 +2,7 @@ set TZData(:Asia/Macau) { {-9223372036854775808 27260 0 LMT} - {-1830411260 28800 0 CST} + {-1830412800 28800 0 CST} {-277360200 32400 1 CDT} {-257405400 28800 0 CST} {-245910600 32400 1 CDT} diff --git a/library/tzdata/Asia/Manila b/library/tzdata/Asia/Manila index 987919a..b7ffa7a 100644 --- a/library/tzdata/Asia/Manila +++ b/library/tzdata/Asia/Manila @@ -4,12 +4,12 @@ set TZData(:Asia/Manila) { {-9223372036854775808 -57360 0 LMT} {-3944621040 29040 0 LMT} {-2229321840 28800 0 +08} - {-1046678400 32400 1 +09} + {-1046678400 32400 1 +08} {-1038733200 28800 0 +08} {-873273600 32400 0 +09} {-794221200 28800 0 +08} - {-496224000 32400 1 +09} + {-496224000 32400 1 +08} {-489315600 28800 0 +08} - {259344000 32400 1 +09} + {259344000 32400 1 +08} {275151600 28800 0 +08} } diff --git a/library/tzdata/Asia/Oral b/library/tzdata/Asia/Oral index 624a59d..e781b60 100644 --- a/library/tzdata/Asia/Oral +++ b/library/tzdata/Asia/Oral @@ -7,52 +7,52 @@ set TZData(:Asia/Oral) { {354913200 21600 1 +06} {370720800 21600 0 +06} {386445600 18000 0 +05} - {386449200 21600 1 +06} + {386449200 21600 1 +05} {402256800 18000 0 +05} - {417985200 21600 1 +06} + {417985200 21600 1 +05} {433792800 18000 0 +05} - {449607600 21600 1 +06} + {449607600 21600 1 +05} {465339600 18000 0 +05} - {481064400 21600 1 +06} + {481064400 21600 1 +05} {496789200 18000 0 +05} - {512514000 21600 1 +06} + {512514000 21600 1 +05} {528238800 18000 0 +05} - {543963600 21600 1 +06} + {543963600 21600 1 +05} {559688400 18000 0 +05} - {575413200 21600 1 +06} + {575413200 21600 1 +05} {591138000 18000 0 +05} {606862800 14400 0 +04} - {606866400 18000 1 +05} + {606866400 18000 1 +04} {622591200 14400 0 +04} - {638316000 18000 1 +05} + {638316000 18000 1 +04} {654645600 14400 0 +04} - {670370400 18000 1 +05} + {670370400 18000 1 +04} {686095200 14400 0 +04} {701816400 14400 0 +04} - {701820000 18000 1 +05} + {701820000 18000 1 +04} {717544800 14400 0 +04} - {733269600 18000 1 +05} + {733269600 18000 1 +04} {748994400 14400 0 +04} - {764719200 18000 1 +05} + {764719200 18000 1 +04} {780444000 14400 0 +04} - {796168800 18000 1 +05} + {796168800 18000 1 +04} {811893600 14400 0 +04} - {828223200 18000 1 +05} + {828223200 18000 1 +04} {846367200 14400 0 +04} - {859672800 18000 1 +05} + {859672800 18000 1 +04} {877816800 14400 0 +04} - {891122400 18000 1 +05} + {891122400 18000 1 +04} {909266400 14400 0 +04} - {922572000 18000 1 +05} + {922572000 18000 1 +04} {941320800 14400 0 +04} - {954021600 18000 1 +05} + {954021600 18000 1 +04} {972770400 14400 0 +04} - {985471200 18000 1 +05} + {985471200 18000 1 +04} {1004220000 14400 0 +04} - {1017525600 18000 1 +05} + {1017525600 18000 1 +04} {1035669600 14400 0 +04} - {1048975200 18000 1 +05} + {1048975200 18000 1 +04} {1067119200 14400 0 +04} - {1080424800 18000 1 +05} + {1080424800 18000 1 +04} {1099173600 18000 0 +05} } diff --git a/library/tzdata/Asia/Qyzylorda b/library/tzdata/Asia/Qyzylorda index b2e9472..7c6df32 100644 --- a/library/tzdata/Asia/Qyzylorda +++ b/library/tzdata/Asia/Qyzylorda @@ -7,51 +7,51 @@ set TZData(:Asia/Qyzylorda) { {354913200 21600 1 +06} {370720800 21600 0 +06} {386445600 18000 0 +05} - {386449200 21600 1 +06} + {386449200 21600 1 +05} {402256800 18000 0 +05} - {417985200 21600 1 +06} + {417985200 21600 1 +05} {433792800 18000 0 +05} - {449607600 21600 1 +06} + {449607600 21600 1 +05} {465339600 18000 0 +05} - {481064400 21600 1 +06} + {481064400 21600 1 +05} {496789200 18000 0 +05} - {512514000 21600 1 +06} + {512514000 21600 1 +05} {528238800 18000 0 +05} - {543963600 21600 1 +06} + {543963600 21600 1 +05} {559688400 18000 0 +05} - {575413200 21600 1 +06} + {575413200 21600 1 +05} {591138000 18000 0 +05} - {606862800 21600 1 +06} + {606862800 21600 1 +05} {622587600 18000 0 +05} - {638312400 21600 1 +06} + {638312400 21600 1 +05} {654642000 18000 0 +05} {670366800 14400 0 +04} - {670370400 18000 1 +05} + {670370400 18000 1 +04} {701812800 18000 0 +05} - {701816400 21600 1 +06} + {701816400 21600 1 +05} {717541200 18000 0 +05} - {733266000 21600 1 +06} + {733266000 21600 1 +05} {748990800 18000 0 +05} - {764715600 21600 1 +06} + {764715600 21600 1 +05} {780440400 18000 0 +05} - {796165200 21600 1 +06} + {796165200 21600 1 +05} {811890000 18000 0 +05} - {828219600 21600 1 +06} + {828219600 21600 1 +05} {846363600 18000 0 +05} - {859669200 21600 1 +06} + {859669200 21600 1 +05} {877813200 18000 0 +05} - {891118800 21600 1 +06} + {891118800 21600 1 +05} {909262800 18000 0 +05} - {922568400 21600 1 +06} + {922568400 21600 1 +05} {941317200 18000 0 +05} - {954018000 21600 1 +06} + {954018000 21600 1 +05} {972766800 18000 0 +05} - {985467600 21600 1 +06} + {985467600 21600 1 +05} {1004216400 18000 0 +05} - {1017522000 21600 1 +06} + {1017522000 21600 1 +05} {1035666000 18000 0 +05} - {1048971600 21600 1 +06} + {1048971600 21600 1 +05} {1067115600 18000 0 +05} - {1080421200 21600 1 +06} + {1080421200 21600 1 +05} {1099170000 21600 0 +06} } diff --git a/library/tzdata/Asia/Samarkand b/library/tzdata/Asia/Samarkand index 43ad774..805bab7 100644 --- a/library/tzdata/Asia/Samarkand +++ b/library/tzdata/Asia/Samarkand @@ -7,25 +7,25 @@ set TZData(:Asia/Samarkand) { {354913200 21600 1 +06} {370720800 21600 0 +06} {386445600 18000 0 +05} - {386449200 21600 1 +06} + {386449200 21600 1 +05} {402256800 18000 0 +05} - {417985200 21600 1 +06} + {417985200 21600 1 +05} {433792800 18000 0 +05} - {449607600 21600 1 +06} + {449607600 21600 1 +05} {465339600 18000 0 +05} - {481064400 21600 1 +06} + {481064400 21600 1 +05} {496789200 18000 0 +05} - {512514000 21600 1 +06} + {512514000 21600 1 +05} {528238800 18000 0 +05} - {543963600 21600 1 +06} + {543963600 21600 1 +05} {559688400 18000 0 +05} - {575413200 21600 1 +06} + {575413200 21600 1 +05} {591138000 18000 0 +05} - {606862800 21600 1 +06} + {606862800 21600 1 +05} {622587600 18000 0 +05} - {638312400 21600 1 +06} + {638312400 21600 1 +05} {654642000 18000 0 +05} - {670366800 21600 1 +06} + {670366800 21600 1 +05} {686091600 18000 0 +05} {694206000 18000 0 +05} } diff --git a/library/tzdata/Asia/Tashkent b/library/tzdata/Asia/Tashkent index 7b6abe4..bd16c91 100644 --- a/library/tzdata/Asia/Tashkent +++ b/library/tzdata/Asia/Tashkent @@ -4,28 +4,28 @@ set TZData(:Asia/Tashkent) { {-9223372036854775808 16631 0 LMT} {-1441168631 18000 0 +05} {-1247547600 21600 0 +06} - {354909600 25200 1 +07} + {354909600 25200 1 +06} {370717200 21600 0 +06} - {386445600 25200 1 +07} + {386445600 25200 1 +06} {402253200 21600 0 +06} - {417981600 25200 1 +07} + {417981600 25200 1 +06} {433789200 21600 0 +06} - {449604000 25200 1 +07} + {449604000 25200 1 +06} {465336000 21600 0 +06} - {481060800 25200 1 +07} + {481060800 25200 1 +06} {496785600 21600 0 +06} - {512510400 25200 1 +07} + {512510400 25200 1 +06} {528235200 21600 0 +06} - {543960000 25200 1 +07} + {543960000 25200 1 +06} {559684800 21600 0 +06} - {575409600 25200 1 +07} + {575409600 25200 1 +06} {591134400 21600 0 +06} - {606859200 25200 1 +07} + {606859200 25200 1 +06} {622584000 21600 0 +06} - {638308800 25200 1 +07} + {638308800 25200 1 +06} {654638400 21600 0 +06} {670363200 18000 0 +05} - {670366800 21600 1 +06} + {670366800 21600 1 +05} {686091600 18000 0 +05} {694206000 18000 0 +05} } diff --git a/library/tzdata/Asia/Tbilisi b/library/tzdata/Asia/Tbilisi index 60d253c..71e7695 100644 --- a/library/tzdata/Asia/Tbilisi +++ b/library/tzdata/Asia/Tbilisi @@ -5,56 +5,56 @@ set TZData(:Asia/Tbilisi) { {-2840151551 10751 0 TBMT} {-1441162751 10800 0 +03} {-405140400 14400 0 +04} - {354916800 18000 1 +05} + {354916800 18000 1 +04} {370724400 14400 0 +04} - {386452800 18000 1 +05} + {386452800 18000 1 +04} {402260400 14400 0 +04} - {417988800 18000 1 +05} + {417988800 18000 1 +04} {433796400 14400 0 +04} - {449611200 18000 1 +05} + {449611200 18000 1 +04} {465343200 14400 0 +04} - {481068000 18000 1 +05} + {481068000 18000 1 +04} {496792800 14400 0 +04} - {512517600 18000 1 +05} + {512517600 18000 1 +04} {528242400 14400 0 +04} - {543967200 18000 1 +05} + {543967200 18000 1 +04} {559692000 14400 0 +04} - {575416800 18000 1 +05} + {575416800 18000 1 +04} {591141600 14400 0 +04} - {606866400 18000 1 +05} + {606866400 18000 1 +04} {622591200 14400 0 +04} - {638316000 18000 1 +05} + {638316000 18000 1 +04} {654645600 14400 0 +04} {670370400 10800 0 +03} - {670374000 14400 1 +04} + {670374000 14400 1 +03} {686098800 10800 0 +03} {694213200 10800 0 +03} - {701816400 14400 1 +04} + {701816400 14400 1 +03} {717537600 10800 0 +03} - {733266000 14400 1 +04} + {733266000 14400 1 +03} {748987200 10800 0 +03} - {764715600 14400 1 +04} + {764715600 14400 1 +03} {780440400 14400 0 +04} - {796161600 18000 1 +05} + {796161600 18000 1 +04} {811882800 14400 0 +04} - {828216000 18000 1 +05} + {828216000 18000 1 +04} {846360000 18000 1 +05} - {859662000 18000 0 +05} + {859662000 18000 0 +04} {877806000 14400 0 +04} - {891115200 18000 1 +05} + {891115200 18000 1 +04} {909255600 14400 0 +04} - {922564800 18000 1 +05} + {922564800 18000 1 +04} {941310000 14400 0 +04} - {954014400 18000 1 +05} + {954014400 18000 1 +04} {972759600 14400 0 +04} - {985464000 18000 1 +05} + {985464000 18000 1 +04} {1004209200 14400 0 +04} - {1017518400 18000 1 +05} + {1017518400 18000 1 +04} {1035658800 14400 0 +04} - {1048968000 18000 1 +05} + {1048968000 18000 1 +04} {1067108400 14400 0 +04} - {1080417600 18000 1 +05} - {1088280000 14400 0 +04} + {1080417600 18000 1 +04} + {1088280000 14400 0 +03} {1099177200 10800 0 +03} {1111878000 14400 0 +04} } diff --git a/library/tzdata/Asia/Tehran b/library/tzdata/Asia/Tehran index a8912ce..3d44e42 100644 --- a/library/tzdata/Asia/Tehran +++ b/library/tzdata/Asia/Tehran @@ -4,226 +4,226 @@ set TZData(:Asia/Tehran) { {-9223372036854775808 12344 0 LMT} {-1704165944 12344 0 TMT} {-757394744 12600 0 +0330} - {247177800 14400 0 +05} - {259272000 18000 1 +05} - {277758000 14400 0 +05} - {283982400 12600 0 +0430} - {290809800 16200 1 +0430} - {306531000 12600 0 +0430} - {322432200 16200 1 +0430} - {338499000 12600 0 +0430} - {673216200 16200 1 +0430} - {685481400 12600 0 +0430} - {701209800 16200 1 +0430} - {717103800 12600 0 +0430} - {732745800 16200 1 +0430} - {748639800 12600 0 +0430} - {764281800 16200 1 +0430} - {780175800 12600 0 +0430} - {795817800 16200 1 +0430} - {811711800 12600 0 +0430} - {827353800 16200 1 +0430} - {843247800 12600 0 +0430} - {858976200 16200 1 +0430} - {874870200 12600 0 +0430} - {890512200 16200 1 +0430} - {906406200 12600 0 +0430} - {922048200 16200 1 +0430} - {937942200 12600 0 +0430} - {953584200 16200 1 +0430} - {969478200 12600 0 +0430} - {985206600 16200 1 +0430} - {1001100600 12600 0 +0430} - {1016742600 16200 1 +0430} - {1032636600 12600 0 +0430} - {1048278600 16200 1 +0430} - {1064172600 12600 0 +0430} - {1079814600 16200 1 +0430} - {1095708600 12600 0 +0430} - {1111437000 16200 1 +0430} - {1127331000 12600 0 +0430} - {1206045000 16200 1 +0430} - {1221939000 12600 0 +0430} - {1237667400 16200 1 +0430} - {1253561400 12600 0 +0430} - {1269203400 16200 1 +0430} - {1285097400 12600 0 +0430} - {1300739400 16200 1 +0430} - {1316633400 12600 0 +0430} - {1332275400 16200 1 +0430} - {1348169400 12600 0 +0430} - {1363897800 16200 1 +0430} - {1379791800 12600 0 +0430} - {1395433800 16200 1 +0430} - {1411327800 12600 0 +0430} - {1426969800 16200 1 +0430} - {1442863800 12600 0 +0430} - {1458505800 16200 1 +0430} - {1474399800 12600 0 +0430} - {1490128200 16200 1 +0430} - {1506022200 12600 0 +0430} - {1521664200 16200 1 +0430} - {1537558200 12600 0 +0430} - {1553200200 16200 1 +0430} - {1569094200 12600 0 +0430} - {1584736200 16200 1 +0430} - {1600630200 12600 0 +0430} - {1616358600 16200 1 +0430} - {1632252600 12600 0 +0430} - {1647894600 16200 1 +0430} - {1663788600 12600 0 +0430} - {1679430600 16200 1 +0430} - {1695324600 12600 0 +0430} - {1710966600 16200 1 +0430} - {1726860600 12600 0 +0430} - {1742589000 16200 1 +0430} - {1758483000 12600 0 +0430} - {1774125000 16200 1 +0430} - {1790019000 12600 0 +0430} - {1805661000 16200 1 +0430} - {1821555000 12600 0 +0430} - {1837197000 16200 1 +0430} - {1853091000 12600 0 +0430} - {1868733000 16200 1 +0430} - {1884627000 12600 0 +0430} - {1900355400 16200 1 +0430} - {1916249400 12600 0 +0430} - {1931891400 16200 1 +0430} - {1947785400 12600 0 +0430} - {1963427400 16200 1 +0430} - {1979321400 12600 0 +0430} - {1994963400 16200 1 +0430} - {2010857400 12600 0 +0430} - {2026585800 16200 1 +0430} - {2042479800 12600 0 +0430} - {2058121800 16200 1 +0430} - {2074015800 12600 0 +0430} - {2089657800 16200 1 +0430} - {2105551800 12600 0 +0430} - {2121193800 16200 1 +0430} - {2137087800 12600 0 +0430} - {2152729800 16200 1 +0430} - {2168623800 12600 0 +0430} - {2184265800 16200 1 +0430} - {2200159800 12600 0 +0430} - {2215888200 16200 1 +0430} - {2231782200 12600 0 +0430} - {2247424200 16200 1 +0430} - {2263318200 12600 0 +0430} - {2278960200 16200 1 +0430} - {2294854200 12600 0 +0430} - {2310496200 16200 1 +0430} - {2326390200 12600 0 +0430} - {2342118600 16200 1 +0430} - {2358012600 12600 0 +0430} - {2373654600 16200 1 +0430} - {2389548600 12600 0 +0430} - {2405190600 16200 1 +0430} - {2421084600 12600 0 +0430} - {2436726600 16200 1 +0430} - {2452620600 12600 0 +0430} - {2468349000 16200 1 +0430} - {2484243000 12600 0 +0430} - {2499885000 16200 1 +0430} - {2515779000 12600 0 +0430} - {2531421000 16200 1 +0430} - {2547315000 12600 0 +0430} - {2562957000 16200 1 +0430} - {2578851000 12600 0 +0430} - {2594579400 16200 1 +0430} - {2610473400 12600 0 +0430} - {2626115400 16200 1 +0430} - {2642009400 12600 0 +0430} - {2657651400 16200 1 +0430} - {2673545400 12600 0 +0430} - {2689187400 16200 1 +0430} - {2705081400 12600 0 +0430} - {2720809800 16200 1 +0430} - {2736703800 12600 0 +0430} - {2752345800 16200 1 +0430} - {2768239800 12600 0 +0430} - {2783881800 16200 1 +0430} - {2799775800 12600 0 +0430} - {2815417800 16200 1 +0430} - {2831311800 12600 0 +0430} - {2847040200 16200 1 +0430} - {2862934200 12600 0 +0430} - {2878576200 16200 1 +0430} - {2894470200 12600 0 +0430} - {2910112200 16200 1 +0430} - {2926006200 12600 0 +0430} - {2941648200 16200 1 +0430} - {2957542200 12600 0 +0430} - {2973270600 16200 1 +0430} - {2989164600 12600 0 +0430} - {3004806600 16200 1 +0430} - {3020700600 12600 0 +0430} - {3036342600 16200 1 +0430} - {3052236600 12600 0 +0430} - {3067878600 16200 1 +0430} - {3083772600 12600 0 +0430} - {3099501000 16200 1 +0430} - {3115395000 12600 0 +0430} - {3131037000 16200 1 +0430} - {3146931000 12600 0 +0430} - {3162573000 16200 1 +0430} - {3178467000 12600 0 +0430} - {3194109000 16200 1 +0430} - {3210003000 12600 0 +0430} - {3225731400 16200 1 +0430} - {3241625400 12600 0 +0430} - {3257267400 16200 1 +0430} - {3273161400 12600 0 +0430} - {3288803400 16200 1 +0430} - {3304697400 12600 0 +0430} - {3320339400 16200 1 +0430} - {3336233400 12600 0 +0430} - {3351961800 16200 1 +0430} - {3367855800 12600 0 +0430} - {3383497800 16200 1 +0430} - {3399391800 12600 0 +0430} - {3415033800 16200 1 +0430} - {3430927800 12600 0 +0430} - {3446569800 16200 1 +0430} - {3462463800 12600 0 +0430} - {3478192200 16200 1 +0430} - {3494086200 12600 0 +0430} - {3509728200 16200 1 +0430} - {3525622200 12600 0 +0430} - {3541264200 16200 1 +0430} - {3557158200 12600 0 +0430} - {3572800200 16200 1 +0430} - {3588694200 12600 0 +0430} - {3604422600 16200 1 +0430} - {3620316600 12600 0 +0430} - {3635958600 16200 1 +0430} - {3651852600 12600 0 +0430} - {3667494600 16200 1 +0430} - {3683388600 12600 0 +0430} - {3699030600 16200 1 +0430} - {3714924600 12600 0 +0430} - {3730653000 16200 1 +0430} - {3746547000 12600 0 +0430} - {3762189000 16200 1 +0430} - {3778083000 12600 0 +0430} - {3793725000 16200 1 +0430} - {3809619000 12600 0 +0430} - {3825261000 16200 1 +0430} - {3841155000 12600 0 +0430} - {3856883400 16200 1 +0430} - {3872777400 12600 0 +0430} - {3888419400 16200 1 +0430} - {3904313400 12600 0 +0430} - {3919955400 16200 1 +0430} - {3935849400 12600 0 +0430} - {3951491400 16200 1 +0430} - {3967385400 12600 0 +0430} - {3983113800 16200 1 +0430} - {3999007800 12600 0 +0430} - {4014649800 16200 1 +0430} - {4030543800 12600 0 +0430} - {4046185800 16200 1 +0430} - {4062079800 12600 0 +0430} - {4077721800 16200 1 +0430} - {4093615800 12600 0 +0430} + {247177800 14400 0 +04} + {259272000 18000 1 +04} + {277758000 14400 0 +04} + {283982400 12600 0 +0330} + {290809800 16200 1 +0330} + {306531000 12600 0 +0330} + {322432200 16200 1 +0330} + {338499000 12600 0 +0330} + {673216200 16200 1 +0330} + {685481400 12600 0 +0330} + {701209800 16200 1 +0330} + {717103800 12600 0 +0330} + {732745800 16200 1 +0330} + {748639800 12600 0 +0330} + {764281800 16200 1 +0330} + {780175800 12600 0 +0330} + {795817800 16200 1 +0330} + {811711800 12600 0 +0330} + {827353800 16200 1 +0330} + {843247800 12600 0 +0330} + {858976200 16200 1 +0330} + {874870200 12600 0 +0330} + {890512200 16200 1 +0330} + {906406200 12600 0 +0330} + {922048200 16200 1 +0330} + {937942200 12600 0 +0330} + {953584200 16200 1 +0330} + {969478200 12600 0 +0330} + {985206600 16200 1 +0330} + {1001100600 12600 0 +0330} + {1016742600 16200 1 +0330} + {1032636600 12600 0 +0330} + {1048278600 16200 1 +0330} + {1064172600 12600 0 +0330} + {1079814600 16200 1 +0330} + {1095708600 12600 0 +0330} + {1111437000 16200 1 +0330} + {1127331000 12600 0 +0330} + {1206045000 16200 1 +0330} + {1221939000 12600 0 +0330} + {1237667400 16200 1 +0330} + {1253561400 12600 0 +0330} + {1269203400 16200 1 +0330} + {1285097400 12600 0 +0330} + {1300739400 16200 1 +0330} + {1316633400 12600 0 +0330} + {1332275400 16200 1 +0330} + {1348169400 12600 0 +0330} + {1363897800 16200 1 +0330} + {1379791800 12600 0 +0330} + {1395433800 16200 1 +0330} + {1411327800 12600 0 +0330} + {1426969800 16200 1 +0330} + {1442863800 12600 0 +0330} + {1458505800 16200 1 +0330} + {1474399800 12600 0 +0330} + {1490128200 16200 1 +0330} + {1506022200 12600 0 +0330} + {1521664200 16200 1 +0330} + {1537558200 12600 0 +0330} + {1553200200 16200 1 +0330} + {1569094200 12600 0 +0330} + {1584736200 16200 1 +0330} + {1600630200 12600 0 +0330} + {1616358600 16200 1 +0330} + {1632252600 12600 0 +0330} + {1647894600 16200 1 +0330} + {1663788600 12600 0 +0330} + {1679430600 16200 1 +0330} + {1695324600 12600 0 +0330} + {1710966600 16200 1 +0330} + {1726860600 12600 0 +0330} + {1742589000 16200 1 +0330} + {1758483000 12600 0 +0330} + {1774125000 16200 1 +0330} + {1790019000 12600 0 +0330} + {1805661000 16200 1 +0330} + {1821555000 12600 0 +0330} + {1837197000 16200 1 +0330} + {1853091000 12600 0 +0330} + {1868733000 16200 1 +0330} + {1884627000 12600 0 +0330} + {1900355400 16200 1 +0330} + {1916249400 12600 0 +0330} + {1931891400 16200 1 +0330} + {1947785400 12600 0 +0330} + {1963427400 16200 1 +0330} + {1979321400 12600 0 +0330} + {1994963400 16200 1 +0330} + {2010857400 12600 0 +0330} + {2026585800 16200 1 +0330} + {2042479800 12600 0 +0330} + {2058121800 16200 1 +0330} + {2074015800 12600 0 +0330} + {2089657800 16200 1 +0330} + {2105551800 12600 0 +0330} + {2121193800 16200 1 +0330} + {2137087800 12600 0 +0330} + {2152729800 16200 1 +0330} + {2168623800 12600 0 +0330} + {2184265800 16200 1 +0330} + {2200159800 12600 0 +0330} + {2215888200 16200 1 +0330} + {2231782200 12600 0 +0330} + {2247424200 16200 1 +0330} + {2263318200 12600 0 +0330} + {2278960200 16200 1 +0330} + {2294854200 12600 0 +0330} + {2310496200 16200 1 +0330} + {2326390200 12600 0 +0330} + {2342118600 16200 1 +0330} + {2358012600 12600 0 +0330} + {2373654600 16200 1 +0330} + {2389548600 12600 0 +0330} + {2405190600 16200 1 +0330} + {2421084600 12600 0 +0330} + {2436726600 16200 1 +0330} + {2452620600 12600 0 +0330} + {2468349000 16200 1 +0330} + {2484243000 12600 0 +0330} + {2499885000 16200 1 +0330} + {2515779000 12600 0 +0330} + {2531421000 16200 1 +0330} + {2547315000 12600 0 +0330} + {2562957000 16200 1 +0330} + {2578851000 12600 0 +0330} + {2594579400 16200 1 +0330} + {2610473400 12600 0 +0330} + {2626115400 16200 1 +0330} + {2642009400 12600 0 +0330} + {2657651400 16200 1 +0330} + {2673545400 12600 0 +0330} + {2689187400 16200 1 +0330} + {2705081400 12600 0 +0330} + {2720809800 16200 1 +0330} + {2736703800 12600 0 +0330} + {2752345800 16200 1 +0330} + {2768239800 12600 0 +0330} + {2783881800 16200 1 +0330} + {2799775800 12600 0 +0330} + {2815417800 16200 1 +0330} + {2831311800 12600 0 +0330} + {2847040200 16200 1 +0330} + {2862934200 12600 0 +0330} + {2878576200 16200 1 +0330} + {2894470200 12600 0 +0330} + {2910112200 16200 1 +0330} + {2926006200 12600 0 +0330} + {2941648200 16200 1 +0330} + {2957542200 12600 0 +0330} + {2973270600 16200 1 +0330} + {2989164600 12600 0 +0330} + {3004806600 16200 1 +0330} + {3020700600 12600 0 +0330} + {3036342600 16200 1 +0330} + {3052236600 12600 0 +0330} + {3067878600 16200 1 +0330} + {3083772600 12600 0 +0330} + {3099501000 16200 1 +0330} + {3115395000 12600 0 +0330} + {3131037000 16200 1 +0330} + {3146931000 12600 0 +0330} + {3162573000 16200 1 +0330} + {3178467000 12600 0 +0330} + {3194109000 16200 1 +0330} + {3210003000 12600 0 +0330} + {3225731400 16200 1 +0330} + {3241625400 12600 0 +0330} + {3257267400 16200 1 +0330} + {3273161400 12600 0 +0330} + {3288803400 16200 1 +0330} + {3304697400 12600 0 +0330} + {3320339400 16200 1 +0330} + {3336233400 12600 0 +0330} + {3351961800 16200 1 +0330} + {3367855800 12600 0 +0330} + {3383497800 16200 1 +0330} + {3399391800 12600 0 +0330} + {3415033800 16200 1 +0330} + {3430927800 12600 0 +0330} + {3446569800 16200 1 +0330} + {3462463800 12600 0 +0330} + {3478192200 16200 1 +0330} + {3494086200 12600 0 +0330} + {3509728200 16200 1 +0330} + {3525622200 12600 0 +0330} + {3541264200 16200 1 +0330} + {3557158200 12600 0 +0330} + {3572800200 16200 1 +0330} + {3588694200 12600 0 +0330} + {3604422600 16200 1 +0330} + {3620316600 12600 0 +0330} + {3635958600 16200 1 +0330} + {3651852600 12600 0 +0330} + {3667494600 16200 1 +0330} + {3683388600 12600 0 +0330} + {3699030600 16200 1 +0330} + {3714924600 12600 0 +0330} + {3730653000 16200 1 +0330} + {3746547000 12600 0 +0330} + {3762189000 16200 1 +0330} + {3778083000 12600 0 +0330} + {3793725000 16200 1 +0330} + {3809619000 12600 0 +0330} + {3825261000 16200 1 +0330} + {3841155000 12600 0 +0330} + {3856883400 16200 1 +0330} + {3872777400 12600 0 +0330} + {3888419400 16200 1 +0330} + {3904313400 12600 0 +0330} + {3919955400 16200 1 +0330} + {3935849400 12600 0 +0330} + {3951491400 16200 1 +0330} + {3967385400 12600 0 +0330} + {3983113800 16200 1 +0330} + {3999007800 12600 0 +0330} + {4014649800 16200 1 +0330} + {4030543800 12600 0 +0330} + {4046185800 16200 1 +0330} + {4062079800 12600 0 +0330} + {4077721800 16200 1 +0330} + {4093615800 12600 0 +0330} } diff --git a/library/tzdata/Asia/Ulaanbaatar b/library/tzdata/Asia/Ulaanbaatar index e0ba7ab..3a33ef9 100644 --- a/library/tzdata/Asia/Ulaanbaatar +++ b/library/tzdata/Asia/Ulaanbaatar @@ -4,52 +4,52 @@ set TZData(:Asia/Ulaanbaatar) { {-9223372036854775808 25652 0 LMT} {-2032931252 25200 0 +07} {252435600 28800 0 +08} - {417974400 32400 1 +09} + {417974400 32400 1 +08} {433782000 28800 0 +08} - {449596800 32400 1 +09} + {449596800 32400 1 +08} {465318000 28800 0 +08} - {481046400 32400 1 +09} + {481046400 32400 1 +08} {496767600 28800 0 +08} - {512496000 32400 1 +09} + {512496000 32400 1 +08} {528217200 28800 0 +08} - {543945600 32400 1 +09} + {543945600 32400 1 +08} {559666800 28800 0 +08} - {575395200 32400 1 +09} + {575395200 32400 1 +08} {591116400 28800 0 +08} - {606844800 32400 1 +09} + {606844800 32400 1 +08} {622566000 28800 0 +08} - {638294400 32400 1 +09} + {638294400 32400 1 +08} {654620400 28800 0 +08} - {670348800 32400 1 +09} + {670348800 32400 1 +08} {686070000 28800 0 +08} - {701798400 32400 1 +09} + {701798400 32400 1 +08} {717519600 28800 0 +08} - {733248000 32400 1 +09} + {733248000 32400 1 +08} {748969200 28800 0 +08} - {764697600 32400 1 +09} + {764697600 32400 1 +08} {780418800 28800 0 +08} - {796147200 32400 1 +09} + {796147200 32400 1 +08} {811868400 28800 0 +08} - {828201600 32400 1 +09} + {828201600 32400 1 +08} {843922800 28800 0 +08} - {859651200 32400 1 +09} + {859651200 32400 1 +08} {875372400 28800 0 +08} - {891100800 32400 1 +09} + {891100800 32400 1 +08} {906822000 28800 0 +08} - {988394400 32400 1 +09} + {988394400 32400 1 +08} {1001696400 28800 0 +08} - {1017424800 32400 1 +09} + {1017424800 32400 1 +08} {1033146000 28800 0 +08} - {1048874400 32400 1 +09} + {1048874400 32400 1 +08} {1064595600 28800 0 +08} - {1080324000 32400 1 +09} + {1080324000 32400 1 +08} {1096045200 28800 0 +08} - {1111773600 32400 1 +09} + {1111773600 32400 1 +08} {1127494800 28800 0 +08} - {1143223200 32400 1 +09} + {1143223200 32400 1 +08} {1159549200 28800 0 +08} - {1427479200 32400 1 +09} + {1427479200 32400 1 +08} {1443193200 28800 0 +08} - {1458928800 32400 1 +09} + {1458928800 32400 1 +08} {1474642800 28800 0 +08} } diff --git a/library/tzdata/Asia/Yerevan b/library/tzdata/Asia/Yerevan index 25a349a..463bed0 100644 --- a/library/tzdata/Asia/Yerevan +++ b/library/tzdata/Asia/Yerevan @@ -4,67 +4,67 @@ set TZData(:Asia/Yerevan) { {-9223372036854775808 10680 0 LMT} {-1441162680 10800 0 +03} {-405140400 14400 0 +04} - {354916800 18000 1 +05} + {354916800 18000 1 +04} {370724400 14400 0 +04} - {386452800 18000 1 +05} + {386452800 18000 1 +04} {402260400 14400 0 +04} - {417988800 18000 1 +05} + {417988800 18000 1 +04} {433796400 14400 0 +04} - {449611200 18000 1 +05} + {449611200 18000 1 +04} {465343200 14400 0 +04} - {481068000 18000 1 +05} + {481068000 18000 1 +04} {496792800 14400 0 +04} - {512517600 18000 1 +05} + {512517600 18000 1 +04} {528242400 14400 0 +04} - {543967200 18000 1 +05} + {543967200 18000 1 +04} {559692000 14400 0 +04} - {575416800 18000 1 +05} + {575416800 18000 1 +04} {591141600 14400 0 +04} - {606866400 18000 1 +05} + {606866400 18000 1 +04} {622591200 14400 0 +04} - {638316000 18000 1 +05} + {638316000 18000 1 +04} {654645600 14400 0 +04} {670370400 10800 0 +03} - {670374000 14400 1 +04} + {670374000 14400 1 +03} {686098800 10800 0 +03} - {701823600 14400 1 +04} + {701823600 14400 1 +03} {717548400 10800 0 +03} - {733273200 14400 1 +04} + {733273200 14400 1 +03} {748998000 10800 0 +03} - {764722800 14400 1 +04} + {764722800 14400 1 +03} {780447600 10800 0 +03} - {796172400 14400 1 +04} + {796172400 14400 1 +03} {811897200 14400 0 +04} {852062400 14400 0 +04} - {859672800 18000 1 +05} + {859672800 18000 1 +04} {877816800 14400 0 +04} - {891122400 18000 1 +05} + {891122400 18000 1 +04} {909266400 14400 0 +04} - {922572000 18000 1 +05} + {922572000 18000 1 +04} {941320800 14400 0 +04} - {954021600 18000 1 +05} + {954021600 18000 1 +04} {972770400 14400 0 +04} - {985471200 18000 1 +05} + {985471200 18000 1 +04} {1004220000 14400 0 +04} - {1017525600 18000 1 +05} + {1017525600 18000 1 +04} {1035669600 14400 0 +04} - {1048975200 18000 1 +05} + {1048975200 18000 1 +04} {1067119200 14400 0 +04} - {1080424800 18000 1 +05} + {1080424800 18000 1 +04} {1099173600 14400 0 +04} - {1111874400 18000 1 +05} + {1111874400 18000 1 +04} {1130623200 14400 0 +04} - {1143324000 18000 1 +05} + {1143324000 18000 1 +04} {1162072800 14400 0 +04} - {1174773600 18000 1 +05} + {1174773600 18000 1 +04} {1193522400 14400 0 +04} - {1206828000 18000 1 +05} + {1206828000 18000 1 +04} {1224972000 14400 0 +04} - {1238277600 18000 1 +05} + {1238277600 18000 1 +04} {1256421600 14400 0 +04} - {1269727200 18000 1 +05} + {1269727200 18000 1 +04} {1288476000 14400 0 +04} {1293825600 14400 0 +04} - {1301176800 18000 1 +05} + {1301176800 18000 1 +04} {1319925600 14400 0 +04} } diff --git a/library/tzdata/Atlantic/Azores b/library/tzdata/Atlantic/Azores index a9bec94..088dd9a 100644 --- a/library/tzdata/Atlantic/Azores +++ b/library/tzdata/Atlantic/Azores @@ -3,7 +3,7 @@ set TZData(:Atlantic/Azores) { {-9223372036854775808 -6160 0 LMT} {-2713904240 -6872 0 HMT} - {-1830377128 -7200 0 -02} + {-1830376800 -7200 0 -02} {-1689548400 -3600 1 -01} {-1677794400 -7200 0 -02} {-1667430000 -3600 1 -01} diff --git a/library/tzdata/Atlantic/Cape_Verde b/library/tzdata/Atlantic/Cape_Verde index 6fc94eb..595db0b 100644 --- a/library/tzdata/Atlantic/Cape_Verde +++ b/library/tzdata/Atlantic/Cape_Verde @@ -2,7 +2,7 @@ set TZData(:Atlantic/Cape_Verde) { {-9223372036854775808 -5644 0 LMT} - {-1988144756 -7200 0 -02} + {-1830376800 -7200 0 -02} {-862610400 -3600 1 -01} {-764118000 -7200 0 -02} {186120000 -3600 0 -01} diff --git a/library/tzdata/Atlantic/Madeira b/library/tzdata/Atlantic/Madeira index cc5e5f8..fed9c19 100644 --- a/library/tzdata/Atlantic/Madeira +++ b/library/tzdata/Atlantic/Madeira @@ -3,7 +3,7 @@ set TZData(:Atlantic/Madeira) { {-9223372036854775808 -4056 0 LMT} {-2713906344 -4056 0 FMT} - {-1830379944 -3600 0 -01} + {-1830380400 -3600 0 -01} {-1689552000 0 1 +00} {-1677798000 -3600 0 -01} {-1667433600 0 1 +00} diff --git a/library/tzdata/Atlantic/Reykjavik b/library/tzdata/Atlantic/Reykjavik index 5555460..6270572 100644 --- a/library/tzdata/Atlantic/Reykjavik +++ b/library/tzdata/Atlantic/Reykjavik @@ -3,71 +3,71 @@ set TZData(:Atlantic/Reykjavik) { {-9223372036854775808 -5280 0 LMT} {-1956609120 -3600 0 -01} - {-1668211200 0 1 +00} + {-1668211200 0 1 -01} {-1647212400 -3600 0 -01} - {-1636675200 0 1 +00} + {-1636675200 0 1 -01} {-1613430000 -3600 0 -01} - {-1605139200 0 1 +00} + {-1605139200 0 1 -01} {-1581894000 -3600 0 -01} - {-1539561600 0 1 +00} + {-1539561600 0 1 -01} {-1531350000 -3600 0 -01} - {-968025600 0 1 +00} + {-968025600 0 1 -01} {-952293600 -3600 0 -01} - {-942008400 0 1 +00} + {-942008400 0 1 -01} {-920239200 -3600 0 -01} - {-909957600 0 1 +00} + {-909957600 0 1 -01} {-888789600 -3600 0 -01} - {-877903200 0 1 +00} + {-877903200 0 1 -01} {-857944800 -3600 0 -01} - {-846453600 0 1 +00} + {-846453600 0 1 -01} {-826495200 -3600 0 -01} - {-815004000 0 1 +00} + {-815004000 0 1 -01} {-795045600 -3600 0 -01} - {-783554400 0 1 +00} + {-783554400 0 1 -01} {-762991200 -3600 0 -01} - {-752104800 0 1 +00} + {-752104800 0 1 -01} {-731541600 -3600 0 -01} - {-717631200 0 1 +00} + {-717631200 0 1 -01} {-700092000 -3600 0 -01} - {-686181600 0 1 +00} + {-686181600 0 1 -01} {-668642400 -3600 0 -01} - {-654732000 0 1 +00} + {-654732000 0 1 -01} {-636588000 -3600 0 -01} - {-623282400 0 1 +00} + {-623282400 0 1 -01} {-605743200 -3600 0 -01} - {-591832800 0 1 +00} + {-591832800 0 1 -01} {-573688800 -3600 0 -01} - {-559778400 0 1 +00} + {-559778400 0 1 -01} {-542239200 -3600 0 -01} - {-528328800 0 1 +00} + {-528328800 0 1 -01} {-510789600 -3600 0 -01} - {-496879200 0 1 +00} + {-496879200 0 1 -01} {-479340000 -3600 0 -01} - {-465429600 0 1 +00} + {-465429600 0 1 -01} {-447890400 -3600 0 -01} - {-433980000 0 1 +00} + {-433980000 0 1 -01} {-415836000 -3600 0 -01} - {-401925600 0 1 +00} + {-401925600 0 1 -01} {-384386400 -3600 0 -01} - {-370476000 0 1 +00} + {-370476000 0 1 -01} {-352936800 -3600 0 -01} - {-339026400 0 1 +00} + {-339026400 0 1 -01} {-321487200 -3600 0 -01} - {-307576800 0 1 +00} + {-307576800 0 1 -01} {-290037600 -3600 0 -01} - {-276127200 0 1 +00} + {-276127200 0 1 -01} {-258588000 -3600 0 -01} - {-244677600 0 1 +00} + {-244677600 0 1 -01} {-226533600 -3600 0 -01} - {-212623200 0 1 +00} + {-212623200 0 1 -01} {-195084000 -3600 0 -01} - {-181173600 0 1 +00} + {-181173600 0 1 -01} {-163634400 -3600 0 -01} - {-149724000 0 1 +00} + {-149724000 0 1 -01} {-132184800 -3600 0 -01} - {-118274400 0 1 +00} + {-118274400 0 1 -01} {-100735200 -3600 0 -01} - {-86824800 0 1 +00} + {-86824800 0 1 -01} {-68680800 -3600 0 -01} {-54770400 0 0 GMT} } diff --git a/library/tzdata/Atlantic/Stanley b/library/tzdata/Atlantic/Stanley index 5210832..48473ca 100644 --- a/library/tzdata/Atlantic/Stanley +++ b/library/tzdata/Atlantic/Stanley @@ -4,72 +4,72 @@ set TZData(:Atlantic/Stanley) { {-9223372036854775808 -13884 0 LMT} {-2524507716 -13884 0 SMT} {-1824235716 -14400 0 -04} - {-1018209600 -10800 1 -03} + {-1018209600 -10800 1 -04} {-1003093200 -14400 0 -04} - {-986760000 -10800 1 -03} + {-986760000 -10800 1 -04} {-971643600 -14400 0 -04} - {-954705600 -10800 1 -03} + {-954705600 -10800 1 -04} {-939589200 -14400 0 -04} - {-923256000 -10800 1 -03} + {-923256000 -10800 1 -04} {-908139600 -14400 0 -04} - {-891806400 -10800 1 -03} + {-891806400 -10800 1 -04} {-876690000 -14400 0 -04} - {-860356800 -10800 1 -03} + {-860356800 -10800 1 -04} {420606000 -7200 0 -03} - {433303200 -7200 1 -02} + {433303200 -7200 1 -03} {452052000 -10800 0 -03} - {464151600 -7200 1 -02} + {464151600 -7200 1 -03} {483501600 -10800 0 -03} {495597600 -14400 0 -04} - {495604800 -10800 1 -03} + {495604800 -10800 1 -04} {514350000 -14400 0 -04} - {527054400 -10800 1 -03} + {527054400 -10800 1 -04} {545799600 -14400 0 -04} - {558504000 -10800 1 -03} + {558504000 -10800 1 -04} {577249200 -14400 0 -04} - {589953600 -10800 1 -03} + {589953600 -10800 1 -04} {608698800 -14400 0 -04} - {621403200 -10800 1 -03} + {621403200 -10800 1 -04} {640753200 -14400 0 -04} - {652852800 -10800 1 -03} + {652852800 -10800 1 -04} {672202800 -14400 0 -04} - {684907200 -10800 1 -03} + {684907200 -10800 1 -04} {703652400 -14400 0 -04} - {716356800 -10800 1 -03} + {716356800 -10800 1 -04} {735102000 -14400 0 -04} - {747806400 -10800 1 -03} + {747806400 -10800 1 -04} {766551600 -14400 0 -04} - {779256000 -10800 1 -03} + {779256000 -10800 1 -04} {798001200 -14400 0 -04} - {810705600 -10800 1 -03} + {810705600 -10800 1 -04} {830055600 -14400 0 -04} - {842760000 -10800 1 -03} + {842760000 -10800 1 -04} {861505200 -14400 0 -04} - {874209600 -10800 1 -03} + {874209600 -10800 1 -04} {892954800 -14400 0 -04} - {905659200 -10800 1 -03} + {905659200 -10800 1 -04} {924404400 -14400 0 -04} - {937108800 -10800 1 -03} + {937108800 -10800 1 -04} {955854000 -14400 0 -04} - {968558400 -10800 1 -03} + {968558400 -10800 1 -04} {987310800 -14400 0 -04} - {999410400 -10800 1 -03} + {999410400 -10800 1 -04} {1019365200 -14400 0 -04} - {1030860000 -10800 1 -03} + {1030860000 -10800 1 -04} {1050814800 -14400 0 -04} - {1062914400 -10800 1 -03} + {1062914400 -10800 1 -04} {1082264400 -14400 0 -04} - {1094364000 -10800 1 -03} + {1094364000 -10800 1 -04} {1113714000 -14400 0 -04} - {1125813600 -10800 1 -03} + {1125813600 -10800 1 -04} {1145163600 -14400 0 -04} - {1157263200 -10800 1 -03} + {1157263200 -10800 1 -04} {1176613200 -14400 0 -04} - {1188712800 -10800 1 -03} + {1188712800 -10800 1 -04} {1208667600 -14400 0 -04} - {1220767200 -10800 1 -03} + {1220767200 -10800 1 -04} {1240117200 -14400 0 -04} - {1252216800 -10800 1 -03} + {1252216800 -10800 1 -04} {1271566800 -14400 0 -04} {1283662800 -10800 0 -03} } diff --git a/library/tzdata/Australia/Lord_Howe b/library/tzdata/Australia/Lord_Howe index 0e2405e..c595967 100644 --- a/library/tzdata/Australia/Lord_Howe +++ b/library/tzdata/Australia/Lord_Howe @@ -3,243 +3,243 @@ set TZData(:Australia/Lord_Howe) { {-9223372036854775808 38180 0 LMT} {-2364114980 36000 0 AEST} - {352216800 37800 0 +1130} - {372785400 41400 1 +1130} - {384273000 37800 0 +1130} - {404839800 41400 1 +1130} - {415722600 37800 0 +1130} - {436289400 41400 1 +1130} - {447172200 37800 0 +1130} - {467739000 41400 1 +1130} - {478621800 37800 0 +1130} - {488984400 37800 0 +11} - {499188600 39600 1 +11} - {511282800 37800 0 +11} - {530033400 39600 1 +11} - {542732400 37800 0 +11} - {562087800 39600 1 +11} - {574786800 37800 0 +11} - {594142200 39600 1 +11} - {606236400 37800 0 +11} - {625591800 39600 1 +11} - {636476400 37800 0 +11} - {657041400 39600 1 +11} - {667926000 37800 0 +11} - {688491000 39600 1 +11} - {699375600 37800 0 +11} - {719940600 39600 1 +11} - {731430000 37800 0 +11} - {751995000 39600 1 +11} - {762879600 37800 0 +11} - {783444600 39600 1 +11} - {794329200 37800 0 +11} - {814894200 39600 1 +11} - {828198000 37800 0 +11} - {846343800 39600 1 +11} - {859647600 37800 0 +11} - {877793400 39600 1 +11} - {891097200 37800 0 +11} - {909243000 39600 1 +11} - {922546800 37800 0 +11} - {941297400 39600 1 +11} - {953996400 37800 0 +11} - {967303800 39600 1 +11} - {985446000 37800 0 +11} - {1004196600 39600 1 +11} - {1017500400 37800 0 +11} - {1035646200 39600 1 +11} - {1048950000 37800 0 +11} - {1067095800 39600 1 +11} - {1080399600 37800 0 +11} - {1099150200 39600 1 +11} - {1111849200 37800 0 +11} - {1130599800 39600 1 +11} - {1143903600 37800 0 +11} - {1162049400 39600 1 +11} - {1174748400 37800 0 +11} - {1193499000 39600 1 +11} - {1207407600 37800 0 +11} - {1223134200 39600 1 +11} - {1238857200 37800 0 +11} - {1254583800 39600 1 +11} - {1270306800 37800 0 +11} - {1286033400 39600 1 +11} - {1301756400 37800 0 +11} - {1317483000 39600 1 +11} - {1333206000 37800 0 +11} - {1349537400 39600 1 +11} - {1365260400 37800 0 +11} - {1380987000 39600 1 +11} - {1396710000 37800 0 +11} - {1412436600 39600 1 +11} - {1428159600 37800 0 +11} - {1443886200 39600 1 +11} - {1459609200 37800 0 +11} - {1475335800 39600 1 +11} - {1491058800 37800 0 +11} - {1506785400 39600 1 +11} - {1522508400 37800 0 +11} - {1538839800 39600 1 +11} - {1554562800 37800 0 +11} - {1570289400 39600 1 +11} - {1586012400 37800 0 +11} - {1601739000 39600 1 +11} - {1617462000 37800 0 +11} - {1633188600 39600 1 +11} - {1648911600 37800 0 +11} - {1664638200 39600 1 +11} - {1680361200 37800 0 +11} - {1696087800 39600 1 +11} - {1712415600 37800 0 +11} - {1728142200 39600 1 +11} - {1743865200 37800 0 +11} - {1759591800 39600 1 +11} - {1775314800 37800 0 +11} - {1791041400 39600 1 +11} - {1806764400 37800 0 +11} - {1822491000 39600 1 +11} - {1838214000 37800 0 +11} - {1853940600 39600 1 +11} - {1869663600 37800 0 +11} - {1885995000 39600 1 +11} - {1901718000 37800 0 +11} - {1917444600 39600 1 +11} - {1933167600 37800 0 +11} - {1948894200 39600 1 +11} - {1964617200 37800 0 +11} - {1980343800 39600 1 +11} - {1996066800 37800 0 +11} - {2011793400 39600 1 +11} - {2027516400 37800 0 +11} - {2043243000 39600 1 +11} - {2058966000 37800 0 +11} - {2075297400 39600 1 +11} - {2091020400 37800 0 +11} - {2106747000 39600 1 +11} - {2122470000 37800 0 +11} - {2138196600 39600 1 +11} - {2153919600 37800 0 +11} - {2169646200 39600 1 +11} - {2185369200 37800 0 +11} - {2201095800 39600 1 +11} - {2216818800 37800 0 +11} - {2233150200 39600 1 +11} - {2248873200 37800 0 +11} - {2264599800 39600 1 +11} - {2280322800 37800 0 +11} - {2296049400 39600 1 +11} - {2311772400 37800 0 +11} - {2327499000 39600 1 +11} - {2343222000 37800 0 +11} - {2358948600 39600 1 +11} - {2374671600 37800 0 +11} - {2390398200 39600 1 +11} - {2406121200 37800 0 +11} - {2422452600 39600 1 +11} - {2438175600 37800 0 +11} - {2453902200 39600 1 +11} - {2469625200 37800 0 +11} - {2485351800 39600 1 +11} - {2501074800 37800 0 +11} - {2516801400 39600 1 +11} - {2532524400 37800 0 +11} - {2548251000 39600 1 +11} - {2563974000 37800 0 +11} - {2579700600 39600 1 +11} - {2596028400 37800 0 +11} - {2611755000 39600 1 +11} - {2627478000 37800 0 +11} - {2643204600 39600 1 +11} - {2658927600 37800 0 +11} - {2674654200 39600 1 +11} - {2690377200 37800 0 +11} - {2706103800 39600 1 +11} - {2721826800 37800 0 +11} - {2737553400 39600 1 +11} - {2753276400 37800 0 +11} - {2769607800 39600 1 +11} - {2785330800 37800 0 +11} - {2801057400 39600 1 +11} - {2816780400 37800 0 +11} - {2832507000 39600 1 +11} - {2848230000 37800 0 +11} - {2863956600 39600 1 +11} - {2879679600 37800 0 +11} - {2895406200 39600 1 +11} - {2911129200 37800 0 +11} - {2926855800 39600 1 +11} - {2942578800 37800 0 +11} - {2958910200 39600 1 +11} - {2974633200 37800 0 +11} - {2990359800 39600 1 +11} - {3006082800 37800 0 +11} - {3021809400 39600 1 +11} - {3037532400 37800 0 +11} - {3053259000 39600 1 +11} - {3068982000 37800 0 +11} - {3084708600 39600 1 +11} - {3100431600 37800 0 +11} - {3116763000 39600 1 +11} - {3132486000 37800 0 +11} - {3148212600 39600 1 +11} - {3163935600 37800 0 +11} - {3179662200 39600 1 +11} - {3195385200 37800 0 +11} - {3211111800 39600 1 +11} - {3226834800 37800 0 +11} - {3242561400 39600 1 +11} - {3258284400 37800 0 +11} - {3274011000 39600 1 +11} - {3289734000 37800 0 +11} - {3306065400 39600 1 +11} - {3321788400 37800 0 +11} - {3337515000 39600 1 +11} - {3353238000 37800 0 +11} - {3368964600 39600 1 +11} - {3384687600 37800 0 +11} - {3400414200 39600 1 +11} - {3416137200 37800 0 +11} - {3431863800 39600 1 +11} - {3447586800 37800 0 +11} - {3463313400 39600 1 +11} - {3479641200 37800 0 +11} - {3495367800 39600 1 +11} - {3511090800 37800 0 +11} - {3526817400 39600 1 +11} - {3542540400 37800 0 +11} - {3558267000 39600 1 +11} - {3573990000 37800 0 +11} - {3589716600 39600 1 +11} - {3605439600 37800 0 +11} - {3621166200 39600 1 +11} - {3636889200 37800 0 +11} - {3653220600 39600 1 +11} - {3668943600 37800 0 +11} - {3684670200 39600 1 +11} - {3700393200 37800 0 +11} - {3716119800 39600 1 +11} - {3731842800 37800 0 +11} - {3747569400 39600 1 +11} - {3763292400 37800 0 +11} - {3779019000 39600 1 +11} - {3794742000 37800 0 +11} - {3810468600 39600 1 +11} - {3826191600 37800 0 +11} - {3842523000 39600 1 +11} - {3858246000 37800 0 +11} - {3873972600 39600 1 +11} - {3889695600 37800 0 +11} - {3905422200 39600 1 +11} - {3921145200 37800 0 +11} - {3936871800 39600 1 +11} - {3952594800 37800 0 +11} - {3968321400 39600 1 +11} - {3984044400 37800 0 +11} - {4000375800 39600 1 +11} - {4016098800 37800 0 +11} - {4031825400 39600 1 +11} - {4047548400 37800 0 +11} - {4063275000 39600 1 +11} - {4078998000 37800 0 +11} - {4094724600 39600 1 +11} + {352216800 37800 0 +1030} + {372785400 41400 1 +1030} + {384273000 37800 0 +1030} + {404839800 41400 1 +1030} + {415722600 37800 0 +1030} + {436289400 41400 1 +1030} + {447172200 37800 0 +1030} + {467739000 41400 1 +1030} + {478621800 37800 0 +1030} + {488984400 37800 0 +1030} + {499188600 39600 1 +1030} + {511282800 37800 0 +1030} + {530033400 39600 1 +1030} + {542732400 37800 0 +1030} + {562087800 39600 1 +1030} + {574786800 37800 0 +1030} + {594142200 39600 1 +1030} + {606236400 37800 0 +1030} + {625591800 39600 1 +1030} + {636476400 37800 0 +1030} + {657041400 39600 1 +1030} + {667926000 37800 0 +1030} + {688491000 39600 1 +1030} + {699375600 37800 0 +1030} + {719940600 39600 1 +1030} + {731430000 37800 0 +1030} + {751995000 39600 1 +1030} + {762879600 37800 0 +1030} + {783444600 39600 1 +1030} + {794329200 37800 0 +1030} + {814894200 39600 1 +1030} + {828198000 37800 0 +1030} + {846343800 39600 1 +1030} + {859647600 37800 0 +1030} + {877793400 39600 1 +1030} + {891097200 37800 0 +1030} + {909243000 39600 1 +1030} + {922546800 37800 0 +1030} + {941297400 39600 1 +1030} + {953996400 37800 0 +1030} + {967303800 39600 1 +1030} + {985446000 37800 0 +1030} + {1004196600 39600 1 +1030} + {1017500400 37800 0 +1030} + {1035646200 39600 1 +1030} + {1048950000 37800 0 +1030} + {1067095800 39600 1 +1030} + {1080399600 37800 0 +1030} + {1099150200 39600 1 +1030} + {1111849200 37800 0 +1030} + {1130599800 39600 1 +1030} + {1143903600 37800 0 +1030} + {1162049400 39600 1 +1030} + {1174748400 37800 0 +1030} + {1193499000 39600 1 +1030} + {1207407600 37800 0 +1030} + {1223134200 39600 1 +1030} + {1238857200 37800 0 +1030} + {1254583800 39600 1 +1030} + {1270306800 37800 0 +1030} + {1286033400 39600 1 +1030} + {1301756400 37800 0 +1030} + {1317483000 39600 1 +1030} + {1333206000 37800 0 +1030} + {1349537400 39600 1 +1030} + {1365260400 37800 0 +1030} + {1380987000 39600 1 +1030} + {1396710000 37800 0 +1030} + {1412436600 39600 1 +1030} + {1428159600 37800 0 +1030} + {1443886200 39600 1 +1030} + {1459609200 37800 0 +1030} + {1475335800 39600 1 +1030} + {1491058800 37800 0 +1030} + {1506785400 39600 1 +1030} + {1522508400 37800 0 +1030} + {1538839800 39600 1 +1030} + {1554562800 37800 0 +1030} + {1570289400 39600 1 +1030} + {1586012400 37800 0 +1030} + {1601739000 39600 1 +1030} + {1617462000 37800 0 +1030} + {1633188600 39600 1 +1030} + {1648911600 37800 0 +1030} + {1664638200 39600 1 +1030} + {1680361200 37800 0 +1030} + {1696087800 39600 1 +1030} + {1712415600 37800 0 +1030} + {1728142200 39600 1 +1030} + {1743865200 37800 0 +1030} + {1759591800 39600 1 +1030} + {1775314800 37800 0 +1030} + {1791041400 39600 1 +1030} + {1806764400 37800 0 +1030} + {1822491000 39600 1 +1030} + {1838214000 37800 0 +1030} + {1853940600 39600 1 +1030} + {1869663600 37800 0 +1030} + {1885995000 39600 1 +1030} + {1901718000 37800 0 +1030} + {1917444600 39600 1 +1030} + {1933167600 37800 0 +1030} + {1948894200 39600 1 +1030} + {1964617200 37800 0 +1030} + {1980343800 39600 1 +1030} + {1996066800 37800 0 +1030} + {2011793400 39600 1 +1030} + {2027516400 37800 0 +1030} + {2043243000 39600 1 +1030} + {2058966000 37800 0 +1030} + {2075297400 39600 1 +1030} + {2091020400 37800 0 +1030} + {2106747000 39600 1 +1030} + {2122470000 37800 0 +1030} + {2138196600 39600 1 +1030} + {2153919600 37800 0 +1030} + {2169646200 39600 1 +1030} + {2185369200 37800 0 +1030} + {2201095800 39600 1 +1030} + {2216818800 37800 0 +1030} + {2233150200 39600 1 +1030} + {2248873200 37800 0 +1030} + {2264599800 39600 1 +1030} + {2280322800 37800 0 +1030} + {2296049400 39600 1 +1030} + {2311772400 37800 0 +1030} + {2327499000 39600 1 +1030} + {2343222000 37800 0 +1030} + {2358948600 39600 1 +1030} + {2374671600 37800 0 +1030} + {2390398200 39600 1 +1030} + {2406121200 37800 0 +1030} + {2422452600 39600 1 +1030} + {2438175600 37800 0 +1030} + {2453902200 39600 1 +1030} + {2469625200 37800 0 +1030} + {2485351800 39600 1 +1030} + {2501074800 37800 0 +1030} + {2516801400 39600 1 +1030} + {2532524400 37800 0 +1030} + {2548251000 39600 1 +1030} + {2563974000 37800 0 +1030} + {2579700600 39600 1 +1030} + {2596028400 37800 0 +1030} + {2611755000 39600 1 +1030} + {2627478000 37800 0 +1030} + {2643204600 39600 1 +1030} + {2658927600 37800 0 +1030} + {2674654200 39600 1 +1030} + {2690377200 37800 0 +1030} + {2706103800 39600 1 +1030} + {2721826800 37800 0 +1030} + {2737553400 39600 1 +1030} + {2753276400 37800 0 +1030} + {2769607800 39600 1 +1030} + {2785330800 37800 0 +1030} + {2801057400 39600 1 +1030} + {2816780400 37800 0 +1030} + {2832507000 39600 1 +1030} + {2848230000 37800 0 +1030} + {2863956600 39600 1 +1030} + {2879679600 37800 0 +1030} + {2895406200 39600 1 +1030} + {2911129200 37800 0 +1030} + {2926855800 39600 1 +1030} + {2942578800 37800 0 +1030} + {2958910200 39600 1 +1030} + {2974633200 37800 0 +1030} + {2990359800 39600 1 +1030} + {3006082800 37800 0 +1030} + {3021809400 39600 1 +1030} + {3037532400 37800 0 +1030} + {3053259000 39600 1 +1030} + {3068982000 37800 0 +1030} + {3084708600 39600 1 +1030} + {3100431600 37800 0 +1030} + {3116763000 39600 1 +1030} + {3132486000 37800 0 +1030} + {3148212600 39600 1 +1030} + {3163935600 37800 0 +1030} + {3179662200 39600 1 +1030} + {3195385200 37800 0 +1030} + {3211111800 39600 1 +1030} + {3226834800 37800 0 +1030} + {3242561400 39600 1 +1030} + {3258284400 37800 0 +1030} + {3274011000 39600 1 +1030} + {3289734000 37800 0 +1030} + {3306065400 39600 1 +1030} + {3321788400 37800 0 +1030} + {3337515000 39600 1 +1030} + {3353238000 37800 0 +1030} + {3368964600 39600 1 +1030} + {3384687600 37800 0 +1030} + {3400414200 39600 1 +1030} + {3416137200 37800 0 +1030} + {3431863800 39600 1 +1030} + {3447586800 37800 0 +1030} + {3463313400 39600 1 +1030} + {3479641200 37800 0 +1030} + {3495367800 39600 1 +1030} + {3511090800 37800 0 +1030} + {3526817400 39600 1 +1030} + {3542540400 37800 0 +1030} + {3558267000 39600 1 +1030} + {3573990000 37800 0 +1030} + {3589716600 39600 1 +1030} + {3605439600 37800 0 +1030} + {3621166200 39600 1 +1030} + {3636889200 37800 0 +1030} + {3653220600 39600 1 +1030} + {3668943600 37800 0 +1030} + {3684670200 39600 1 +1030} + {3700393200 37800 0 +1030} + {3716119800 39600 1 +1030} + {3731842800 37800 0 +1030} + {3747569400 39600 1 +1030} + {3763292400 37800 0 +1030} + {3779019000 39600 1 +1030} + {3794742000 37800 0 +1030} + {3810468600 39600 1 +1030} + {3826191600 37800 0 +1030} + {3842523000 39600 1 +1030} + {3858246000 37800 0 +1030} + {3873972600 39600 1 +1030} + {3889695600 37800 0 +1030} + {3905422200 39600 1 +1030} + {3921145200 37800 0 +1030} + {3936871800 39600 1 +1030} + {3952594800 37800 0 +1030} + {3968321400 39600 1 +1030} + {3984044400 37800 0 +1030} + {4000375800 39600 1 +1030} + {4016098800 37800 0 +1030} + {4031825400 39600 1 +1030} + {4047548400 37800 0 +1030} + {4063275000 39600 1 +1030} + {4078998000 37800 0 +1030} + {4094724600 39600 1 +1030} } diff --git a/library/tzdata/Europe/Lisbon b/library/tzdata/Europe/Lisbon index 7168f96..b566b51 100644 --- a/library/tzdata/Europe/Lisbon +++ b/library/tzdata/Europe/Lisbon @@ -3,7 +3,7 @@ set TZData(:Europe/Lisbon) { {-9223372036854775808 -2205 0 LMT} {-2713908195 -2205 0 LMT} - {-1830381795 0 0 WET} + {-1830384000 0 0 WET} {-1689555600 3600 1 WEST} {-1677801600 0 0 WET} {-1667437200 3600 1 WEST} diff --git a/library/tzdata/Indian/Mauritius b/library/tzdata/Indian/Mauritius index 2a7a0b1..4c9a051 100644 --- a/library/tzdata/Indian/Mauritius +++ b/library/tzdata/Indian/Mauritius @@ -3,8 +3,8 @@ set TZData(:Indian/Mauritius) { {-9223372036854775808 13800 0 LMT} {-1988164200 14400 0 +04} - {403041600 18000 1 +05} + {403041600 18000 1 +04} {417034800 14400 0 +04} - {1224972000 18000 1 +05} + {1224972000 18000 1 +04} {1238274000 14400 0 +04} } diff --git a/library/tzdata/Pacific/Apia b/library/tzdata/Pacific/Apia index 4c0d84a..4fc91f4 100644 --- a/library/tzdata/Pacific/Apia +++ b/library/tzdata/Pacific/Apia @@ -4,185 +4,185 @@ set TZData(:Pacific/Apia) { {-9223372036854775808 45184 0 LMT} {-2445424384 -41216 0 LMT} {-1861878784 -41400 0 -1130} - {-631110600 -39600 0 -10} - {1285498800 -36000 1 -10} - {1301752800 -39600 0 -10} - {1316872800 -36000 1 -10} - {1325239200 50400 0 +14} - {1333202400 46800 0 +14} - {1348927200 50400 1 +14} - {1365256800 46800 0 +14} - {1380376800 50400 1 +14} - {1396706400 46800 0 +14} - {1411826400 50400 1 +14} - {1428156000 46800 0 +14} - {1443276000 50400 1 +14} - {1459605600 46800 0 +14} - {1474725600 50400 1 +14} - {1491055200 46800 0 +14} - {1506175200 50400 1 +14} - {1522504800 46800 0 +14} - {1538229600 50400 1 +14} - {1554559200 46800 0 +14} - {1569679200 50400 1 +14} - {1586008800 46800 0 +14} - {1601128800 50400 1 +14} - {1617458400 46800 0 +14} - {1632578400 50400 1 +14} - {1648908000 46800 0 +14} - {1664028000 50400 1 +14} - {1680357600 46800 0 +14} - {1695477600 50400 1 +14} - {1712412000 46800 0 +14} - {1727532000 50400 1 +14} - {1743861600 46800 0 +14} - {1758981600 50400 1 +14} - {1775311200 46800 0 +14} - {1790431200 50400 1 +14} - {1806760800 46800 0 +14} - {1821880800 50400 1 +14} - {1838210400 46800 0 +14} - {1853330400 50400 1 +14} - {1869660000 46800 0 +14} - {1885384800 50400 1 +14} - {1901714400 46800 0 +14} - {1916834400 50400 1 +14} - {1933164000 46800 0 +14} - {1948284000 50400 1 +14} - {1964613600 46800 0 +14} - {1979733600 50400 1 +14} - {1996063200 46800 0 +14} - {2011183200 50400 1 +14} - {2027512800 46800 0 +14} - {2042632800 50400 1 +14} - {2058962400 46800 0 +14} - {2074687200 50400 1 +14} - {2091016800 46800 0 +14} - {2106136800 50400 1 +14} - {2122466400 46800 0 +14} - {2137586400 50400 1 +14} - {2153916000 46800 0 +14} - {2169036000 50400 1 +14} - {2185365600 46800 0 +14} - {2200485600 50400 1 +14} - {2216815200 46800 0 +14} - {2232540000 50400 1 +14} - {2248869600 46800 0 +14} - {2263989600 50400 1 +14} - {2280319200 46800 0 +14} - {2295439200 50400 1 +14} - {2311768800 46800 0 +14} - {2326888800 50400 1 +14} - {2343218400 46800 0 +14} - {2358338400 50400 1 +14} - {2374668000 46800 0 +14} - {2389788000 50400 1 +14} - {2406117600 46800 0 +14} - {2421842400 50400 1 +14} - {2438172000 46800 0 +14} - {2453292000 50400 1 +14} - {2469621600 46800 0 +14} - {2484741600 50400 1 +14} - {2501071200 46800 0 +14} - {2516191200 50400 1 +14} - {2532520800 46800 0 +14} - {2547640800 50400 1 +14} - {2563970400 46800 0 +14} - {2579090400 50400 1 +14} - {2596024800 46800 0 +14} - {2611144800 50400 1 +14} - {2627474400 46800 0 +14} - {2642594400 50400 1 +14} - {2658924000 46800 0 +14} - {2674044000 50400 1 +14} - {2690373600 46800 0 +14} - {2705493600 50400 1 +14} - {2721823200 46800 0 +14} - {2736943200 50400 1 +14} - {2753272800 46800 0 +14} - {2768997600 50400 1 +14} - {2785327200 46800 0 +14} - {2800447200 50400 1 +14} - {2816776800 46800 0 +14} - {2831896800 50400 1 +14} - {2848226400 46800 0 +14} - {2863346400 50400 1 +14} - {2879676000 46800 0 +14} - {2894796000 50400 1 +14} - {2911125600 46800 0 +14} - {2926245600 50400 1 +14} - {2942575200 46800 0 +14} - {2958300000 50400 1 +14} - {2974629600 46800 0 +14} - {2989749600 50400 1 +14} - {3006079200 46800 0 +14} - {3021199200 50400 1 +14} - {3037528800 46800 0 +14} - {3052648800 50400 1 +14} - {3068978400 46800 0 +14} - {3084098400 50400 1 +14} - {3100428000 46800 0 +14} - {3116152800 50400 1 +14} - {3132482400 46800 0 +14} - {3147602400 50400 1 +14} - {3163932000 46800 0 +14} - {3179052000 50400 1 +14} - {3195381600 46800 0 +14} - {3210501600 50400 1 +14} - {3226831200 46800 0 +14} - {3241951200 50400 1 +14} - {3258280800 46800 0 +14} - {3273400800 50400 1 +14} - {3289730400 46800 0 +14} - {3305455200 50400 1 +14} - {3321784800 46800 0 +14} - {3336904800 50400 1 +14} - {3353234400 46800 0 +14} - {3368354400 50400 1 +14} - {3384684000 46800 0 +14} - {3399804000 50400 1 +14} - {3416133600 46800 0 +14} - {3431253600 50400 1 +14} - {3447583200 46800 0 +14} - {3462703200 50400 1 +14} - {3479637600 46800 0 +14} - {3494757600 50400 1 +14} - {3511087200 46800 0 +14} - {3526207200 50400 1 +14} - {3542536800 46800 0 +14} - {3557656800 50400 1 +14} - {3573986400 46800 0 +14} - {3589106400 50400 1 +14} - {3605436000 46800 0 +14} - {3620556000 50400 1 +14} - {3636885600 46800 0 +14} - {3652610400 50400 1 +14} - {3668940000 46800 0 +14} - {3684060000 50400 1 +14} - {3700389600 46800 0 +14} - {3715509600 50400 1 +14} - {3731839200 46800 0 +14} - {3746959200 50400 1 +14} - {3763288800 46800 0 +14} - {3778408800 50400 1 +14} - {3794738400 46800 0 +14} - {3809858400 50400 1 +14} - {3826188000 46800 0 +14} - {3841912800 50400 1 +14} - {3858242400 46800 0 +14} - {3873362400 50400 1 +14} - {3889692000 46800 0 +14} - {3904812000 50400 1 +14} - {3921141600 46800 0 +14} - {3936261600 50400 1 +14} - {3952591200 46800 0 +14} - {3967711200 50400 1 +14} - {3984040800 46800 0 +14} - {3999765600 50400 1 +14} - {4016095200 46800 0 +14} - {4031215200 50400 1 +14} - {4047544800 46800 0 +14} - {4062664800 50400 1 +14} - {4078994400 46800 0 +14} - {4094114400 50400 1 +14} + {-631110600 -39600 0 -11} + {1285498800 -36000 1 -11} + {1301752800 -39600 0 -11} + {1316872800 -36000 1 -11} + {1325239200 50400 0 +13} + {1333202400 46800 0 +13} + {1348927200 50400 1 +13} + {1365256800 46800 0 +13} + {1380376800 50400 1 +13} + {1396706400 46800 0 +13} + {1411826400 50400 1 +13} + {1428156000 46800 0 +13} + {1443276000 50400 1 +13} + {1459605600 46800 0 +13} + {1474725600 50400 1 +13} + {1491055200 46800 0 +13} + {1506175200 50400 1 +13} + {1522504800 46800 0 +13} + {1538229600 50400 1 +13} + {1554559200 46800 0 +13} + {1569679200 50400 1 +13} + {1586008800 46800 0 +13} + {1601128800 50400 1 +13} + {1617458400 46800 0 +13} + {1632578400 50400 1 +13} + {1648908000 46800 0 +13} + {1664028000 50400 1 +13} + {1680357600 46800 0 +13} + {1695477600 50400 1 +13} + {1712412000 46800 0 +13} + {1727532000 50400 1 +13} + {1743861600 46800 0 +13} + {1758981600 50400 1 +13} + {1775311200 46800 0 +13} + {1790431200 50400 1 +13} + {1806760800 46800 0 +13} + {1821880800 50400 1 +13} + {1838210400 46800 0 +13} + {1853330400 50400 1 +13} + {1869660000 46800 0 +13} + {1885384800 50400 1 +13} + {1901714400 46800 0 +13} + {1916834400 50400 1 +13} + {1933164000 46800 0 +13} + {1948284000 50400 1 +13} + {1964613600 46800 0 +13} + {1979733600 50400 1 +13} + {1996063200 46800 0 +13} + {2011183200 50400 1 +13} + {2027512800 46800 0 +13} + {2042632800 50400 1 +13} + {2058962400 46800 0 +13} + {2074687200 50400 1 +13} + {2091016800 46800 0 +13} + {2106136800 50400 1 +13} + {2122466400 46800 0 +13} + {2137586400 50400 1 +13} + {2153916000 46800 0 +13} + {2169036000 50400 1 +13} + {2185365600 46800 0 +13} + {2200485600 50400 1 +13} + {2216815200 46800 0 +13} + {2232540000 50400 1 +13} + {2248869600 46800 0 +13} + {2263989600 50400 1 +13} + {2280319200 46800 0 +13} + {2295439200 50400 1 +13} + {2311768800 46800 0 +13} + {2326888800 50400 1 +13} + {2343218400 46800 0 +13} + {2358338400 50400 1 +13} + {2374668000 46800 0 +13} + {2389788000 50400 1 +13} + {2406117600 46800 0 +13} + {2421842400 50400 1 +13} + {2438172000 46800 0 +13} + {2453292000 50400 1 +13} + {2469621600 46800 0 +13} + {2484741600 50400 1 +13} + {2501071200 46800 0 +13} + {2516191200 50400 1 +13} + {2532520800 46800 0 +13} + {2547640800 50400 1 +13} + {2563970400 46800 0 +13} + {2579090400 50400 1 +13} + {2596024800 46800 0 +13} + {2611144800 50400 1 +13} + {2627474400 46800 0 +13} + {2642594400 50400 1 +13} + {2658924000 46800 0 +13} + {2674044000 50400 1 +13} + {2690373600 46800 0 +13} + {2705493600 50400 1 +13} + {2721823200 46800 0 +13} + {2736943200 50400 1 +13} + {2753272800 46800 0 +13} + {2768997600 50400 1 +13} + {2785327200 46800 0 +13} + {2800447200 50400 1 +13} + {2816776800 46800 0 +13} + {2831896800 50400 1 +13} + {2848226400 46800 0 +13} + {2863346400 50400 1 +13} + {2879676000 46800 0 +13} + {2894796000 50400 1 +13} + {2911125600 46800 0 +13} + {2926245600 50400 1 +13} + {2942575200 46800 0 +13} + {2958300000 50400 1 +13} + {2974629600 46800 0 +13} + {2989749600 50400 1 +13} + {3006079200 46800 0 +13} + {3021199200 50400 1 +13} + {3037528800 46800 0 +13} + {3052648800 50400 1 +13} + {3068978400 46800 0 +13} + {3084098400 50400 1 +13} + {3100428000 46800 0 +13} + {3116152800 50400 1 +13} + {3132482400 46800 0 +13} + {3147602400 50400 1 +13} + {3163932000 46800 0 +13} + {3179052000 50400 1 +13} + {3195381600 46800 0 +13} + {3210501600 50400 1 +13} + {3226831200 46800 0 +13} + {3241951200 50400 1 +13} + {3258280800 46800 0 +13} + {3273400800 50400 1 +13} + {3289730400 46800 0 +13} + {3305455200 50400 1 +13} + {3321784800 46800 0 +13} + {3336904800 50400 1 +13} + {3353234400 46800 0 +13} + {3368354400 50400 1 +13} + {3384684000 46800 0 +13} + {3399804000 50400 1 +13} + {3416133600 46800 0 +13} + {3431253600 50400 1 +13} + {3447583200 46800 0 +13} + {3462703200 50400 1 +13} + {3479637600 46800 0 +13} + {3494757600 50400 1 +13} + {3511087200 46800 0 +13} + {3526207200 50400 1 +13} + {3542536800 46800 0 +13} + {3557656800 50400 1 +13} + {3573986400 46800 0 +13} + {3589106400 50400 1 +13} + {3605436000 46800 0 +13} + {3620556000 50400 1 +13} + {3636885600 46800 0 +13} + {3652610400 50400 1 +13} + {3668940000 46800 0 +13} + {3684060000 50400 1 +13} + {3700389600 46800 0 +13} + {3715509600 50400 1 +13} + {3731839200 46800 0 +13} + {3746959200 50400 1 +13} + {3763288800 46800 0 +13} + {3778408800 50400 1 +13} + {3794738400 46800 0 +13} + {3809858400 50400 1 +13} + {3826188000 46800 0 +13} + {3841912800 50400 1 +13} + {3858242400 46800 0 +13} + {3873362400 50400 1 +13} + {3889692000 46800 0 +13} + {3904812000 50400 1 +13} + {3921141600 46800 0 +13} + {3936261600 50400 1 +13} + {3952591200 46800 0 +13} + {3967711200 50400 1 +13} + {3984040800 46800 0 +13} + {3999765600 50400 1 +13} + {4016095200 46800 0 +13} + {4031215200 50400 1 +13} + {4047544800 46800 0 +13} + {4062664800 50400 1 +13} + {4078994400 46800 0 +13} + {4094114400 50400 1 +13} } diff --git a/library/tzdata/Pacific/Chatham b/library/tzdata/Pacific/Chatham index 5d39879..6c1ab19 100644 --- a/library/tzdata/Pacific/Chatham +++ b/library/tzdata/Pacific/Chatham @@ -3,256 +3,256 @@ set TZData(:Pacific/Chatham) { {-9223372036854775808 44028 0 LMT} {-3192437628 44100 0 +1215} - {-757426500 45900 0 +1345} - {152632800 49500 1 +1345} - {162309600 45900 0 +1345} - {183477600 49500 1 +1345} - {194968800 45900 0 +1345} - {215532000 49500 1 +1345} - {226418400 45900 0 +1345} - {246981600 49500 1 +1345} - {257868000 45900 0 +1345} - {278431200 49500 1 +1345} - {289317600 45900 0 +1345} - {309880800 49500 1 +1345} - {320767200 45900 0 +1345} - {341330400 49500 1 +1345} - {352216800 45900 0 +1345} - {372780000 49500 1 +1345} - {384271200 45900 0 +1345} - {404834400 49500 1 +1345} - {415720800 45900 0 +1345} - {436284000 49500 1 +1345} - {447170400 45900 0 +1345} - {467733600 49500 1 +1345} - {478620000 45900 0 +1345} - {499183200 49500 1 +1345} - {510069600 45900 0 +1345} - {530632800 49500 1 +1345} - {541519200 45900 0 +1345} - {562082400 49500 1 +1345} - {573573600 45900 0 +1345} - {594136800 49500 1 +1345} - {605023200 45900 0 +1345} - {623772000 49500 1 +1345} - {637682400 45900 0 +1345} - {655221600 49500 1 +1345} - {669132000 45900 0 +1345} - {686671200 49500 1 +1345} - {700581600 45900 0 +1345} - {718120800 49500 1 +1345} - {732636000 45900 0 +1345} - {749570400 49500 1 +1345} - {764085600 45900 0 +1345} - {781020000 49500 1 +1345} - {795535200 45900 0 +1345} - {812469600 49500 1 +1345} - {826984800 45900 0 +1345} - {844524000 49500 1 +1345} - {858434400 45900 0 +1345} - {875973600 49500 1 +1345} - {889884000 45900 0 +1345} - {907423200 49500 1 +1345} - {921938400 45900 0 +1345} - {938872800 49500 1 +1345} - {953388000 45900 0 +1345} - {970322400 49500 1 +1345} - {984837600 45900 0 +1345} - {1002376800 49500 1 +1345} - {1016287200 45900 0 +1345} - {1033826400 49500 1 +1345} - {1047736800 45900 0 +1345} - {1065276000 49500 1 +1345} - {1079791200 45900 0 +1345} - {1096725600 49500 1 +1345} - {1111240800 45900 0 +1345} - {1128175200 49500 1 +1345} - {1142690400 45900 0 +1345} - {1159624800 49500 1 +1345} - {1174140000 45900 0 +1345} - {1191074400 49500 1 +1345} - {1207404000 45900 0 +1345} - {1222524000 49500 1 +1345} - {1238853600 45900 0 +1345} - {1253973600 49500 1 +1345} - {1270303200 45900 0 +1345} - {1285423200 49500 1 +1345} - {1301752800 45900 0 +1345} - {1316872800 49500 1 +1345} - {1333202400 45900 0 +1345} - {1348927200 49500 1 +1345} - {1365256800 45900 0 +1345} - {1380376800 49500 1 +1345} - {1396706400 45900 0 +1345} - {1411826400 49500 1 +1345} - {1428156000 45900 0 +1345} - {1443276000 49500 1 +1345} - {1459605600 45900 0 +1345} - {1474725600 49500 1 +1345} - {1491055200 45900 0 +1345} - {1506175200 49500 1 +1345} - {1522504800 45900 0 +1345} - {1538229600 49500 1 +1345} - {1554559200 45900 0 +1345} - {1569679200 49500 1 +1345} - {1586008800 45900 0 +1345} - {1601128800 49500 1 +1345} - {1617458400 45900 0 +1345} - {1632578400 49500 1 +1345} - {1648908000 45900 0 +1345} - {1664028000 49500 1 +1345} - {1680357600 45900 0 +1345} - {1695477600 49500 1 +1345} - {1712412000 45900 0 +1345} - {1727532000 49500 1 +1345} - {1743861600 45900 0 +1345} - {1758981600 49500 1 +1345} - {1775311200 45900 0 +1345} - {1790431200 49500 1 +1345} - {1806760800 45900 0 +1345} - {1821880800 49500 1 +1345} - {1838210400 45900 0 +1345} - {1853330400 49500 1 +1345} - {1869660000 45900 0 +1345} - {1885384800 49500 1 +1345} - {1901714400 45900 0 +1345} - {1916834400 49500 1 +1345} - {1933164000 45900 0 +1345} - {1948284000 49500 1 +1345} - {1964613600 45900 0 +1345} - {1979733600 49500 1 +1345} - {1996063200 45900 0 +1345} - {2011183200 49500 1 +1345} - {2027512800 45900 0 +1345} - {2042632800 49500 1 +1345} - {2058962400 45900 0 +1345} - {2074687200 49500 1 +1345} - {2091016800 45900 0 +1345} - {2106136800 49500 1 +1345} - {2122466400 45900 0 +1345} - {2137586400 49500 1 +1345} - {2153916000 45900 0 +1345} - {2169036000 49500 1 +1345} - {2185365600 45900 0 +1345} - {2200485600 49500 1 +1345} - {2216815200 45900 0 +1345} - {2232540000 49500 1 +1345} - {2248869600 45900 0 +1345} - {2263989600 49500 1 +1345} - {2280319200 45900 0 +1345} - {2295439200 49500 1 +1345} - {2311768800 45900 0 +1345} - {2326888800 49500 1 +1345} - {2343218400 45900 0 +1345} - {2358338400 49500 1 +1345} - {2374668000 45900 0 +1345} - {2389788000 49500 1 +1345} - {2406117600 45900 0 +1345} - {2421842400 49500 1 +1345} - {2438172000 45900 0 +1345} - {2453292000 49500 1 +1345} - {2469621600 45900 0 +1345} - {2484741600 49500 1 +1345} - {2501071200 45900 0 +1345} - {2516191200 49500 1 +1345} - {2532520800 45900 0 +1345} - {2547640800 49500 1 +1345} - {2563970400 45900 0 +1345} - {2579090400 49500 1 +1345} - {2596024800 45900 0 +1345} - {2611144800 49500 1 +1345} - {2627474400 45900 0 +1345} - {2642594400 49500 1 +1345} - {2658924000 45900 0 +1345} - {2674044000 49500 1 +1345} - {2690373600 45900 0 +1345} - {2705493600 49500 1 +1345} - {2721823200 45900 0 +1345} - {2736943200 49500 1 +1345} - {2753272800 45900 0 +1345} - {2768997600 49500 1 +1345} - {2785327200 45900 0 +1345} - {2800447200 49500 1 +1345} - {2816776800 45900 0 +1345} - {2831896800 49500 1 +1345} - {2848226400 45900 0 +1345} - {2863346400 49500 1 +1345} - {2879676000 45900 0 +1345} - {2894796000 49500 1 +1345} - {2911125600 45900 0 +1345} - {2926245600 49500 1 +1345} - {2942575200 45900 0 +1345} - {2958300000 49500 1 +1345} - {2974629600 45900 0 +1345} - {2989749600 49500 1 +1345} - {3006079200 45900 0 +1345} - {3021199200 49500 1 +1345} - {3037528800 45900 0 +1345} - {3052648800 49500 1 +1345} - {3068978400 45900 0 +1345} - {3084098400 49500 1 +1345} - {3100428000 45900 0 +1345} - {3116152800 49500 1 +1345} - {3132482400 45900 0 +1345} - {3147602400 49500 1 +1345} - {3163932000 45900 0 +1345} - {3179052000 49500 1 +1345} - {3195381600 45900 0 +1345} - {3210501600 49500 1 +1345} - {3226831200 45900 0 +1345} - {3241951200 49500 1 +1345} - {3258280800 45900 0 +1345} - {3273400800 49500 1 +1345} - {3289730400 45900 0 +1345} - {3305455200 49500 1 +1345} - {3321784800 45900 0 +1345} - {3336904800 49500 1 +1345} - {3353234400 45900 0 +1345} - {3368354400 49500 1 +1345} - {3384684000 45900 0 +1345} - {3399804000 49500 1 +1345} - {3416133600 45900 0 +1345} - {3431253600 49500 1 +1345} - {3447583200 45900 0 +1345} - {3462703200 49500 1 +1345} - {3479637600 45900 0 +1345} - {3494757600 49500 1 +1345} - {3511087200 45900 0 +1345} - {3526207200 49500 1 +1345} - {3542536800 45900 0 +1345} - {3557656800 49500 1 +1345} - {3573986400 45900 0 +1345} - {3589106400 49500 1 +1345} - {3605436000 45900 0 +1345} - {3620556000 49500 1 +1345} - {3636885600 45900 0 +1345} - {3652610400 49500 1 +1345} - {3668940000 45900 0 +1345} - {3684060000 49500 1 +1345} - {3700389600 45900 0 +1345} - {3715509600 49500 1 +1345} - {3731839200 45900 0 +1345} - {3746959200 49500 1 +1345} - {3763288800 45900 0 +1345} - {3778408800 49500 1 +1345} - {3794738400 45900 0 +1345} - {3809858400 49500 1 +1345} - {3826188000 45900 0 +1345} - {3841912800 49500 1 +1345} - {3858242400 45900 0 +1345} - {3873362400 49500 1 +1345} - {3889692000 45900 0 +1345} - {3904812000 49500 1 +1345} - {3921141600 45900 0 +1345} - {3936261600 49500 1 +1345} - {3952591200 45900 0 +1345} - {3967711200 49500 1 +1345} - {3984040800 45900 0 +1345} - {3999765600 49500 1 +1345} - {4016095200 45900 0 +1345} - {4031215200 49500 1 +1345} - {4047544800 45900 0 +1345} - {4062664800 49500 1 +1345} - {4078994400 45900 0 +1345} - {4094114400 49500 1 +1345} + {-757426500 45900 0 +1245} + {152632800 49500 1 +1245} + {162309600 45900 0 +1245} + {183477600 49500 1 +1245} + {194968800 45900 0 +1245} + {215532000 49500 1 +1245} + {226418400 45900 0 +1245} + {246981600 49500 1 +1245} + {257868000 45900 0 +1245} + {278431200 49500 1 +1245} + {289317600 45900 0 +1245} + {309880800 49500 1 +1245} + {320767200 45900 0 +1245} + {341330400 49500 1 +1245} + {352216800 45900 0 +1245} + {372780000 49500 1 +1245} + {384271200 45900 0 +1245} + {404834400 49500 1 +1245} + {415720800 45900 0 +1245} + {436284000 49500 1 +1245} + {447170400 45900 0 +1245} + {467733600 49500 1 +1245} + {478620000 45900 0 +1245} + {499183200 49500 1 +1245} + {510069600 45900 0 +1245} + {530632800 49500 1 +1245} + {541519200 45900 0 +1245} + {562082400 49500 1 +1245} + {573573600 45900 0 +1245} + {594136800 49500 1 +1245} + {605023200 45900 0 +1245} + {623772000 49500 1 +1245} + {637682400 45900 0 +1245} + {655221600 49500 1 +1245} + {669132000 45900 0 +1245} + {686671200 49500 1 +1245} + {700581600 45900 0 +1245} + {718120800 49500 1 +1245} + {732636000 45900 0 +1245} + {749570400 49500 1 +1245} + {764085600 45900 0 +1245} + {781020000 49500 1 +1245} + {795535200 45900 0 +1245} + {812469600 49500 1 +1245} + {826984800 45900 0 +1245} + {844524000 49500 1 +1245} + {858434400 45900 0 +1245} + {875973600 49500 1 +1245} + {889884000 45900 0 +1245} + {907423200 49500 1 +1245} + {921938400 45900 0 +1245} + {938872800 49500 1 +1245} + {953388000 45900 0 +1245} + {970322400 49500 1 +1245} + {984837600 45900 0 +1245} + {1002376800 49500 1 +1245} + {1016287200 45900 0 +1245} + {1033826400 49500 1 +1245} + {1047736800 45900 0 +1245} + {1065276000 49500 1 +1245} + {1079791200 45900 0 +1245} + {1096725600 49500 1 +1245} + {1111240800 45900 0 +1245} + {1128175200 49500 1 +1245} + {1142690400 45900 0 +1245} + {1159624800 49500 1 +1245} + {1174140000 45900 0 +1245} + {1191074400 49500 1 +1245} + {1207404000 45900 0 +1245} + {1222524000 49500 1 +1245} + {1238853600 45900 0 +1245} + {1253973600 49500 1 +1245} + {1270303200 45900 0 +1245} + {1285423200 49500 1 +1245} + {1301752800 45900 0 +1245} + {1316872800 49500 1 +1245} + {1333202400 45900 0 +1245} + {1348927200 49500 1 +1245} + {1365256800 45900 0 +1245} + {1380376800 49500 1 +1245} + {1396706400 45900 0 +1245} + {1411826400 49500 1 +1245} + {1428156000 45900 0 +1245} + {1443276000 49500 1 +1245} + {1459605600 45900 0 +1245} + {1474725600 49500 1 +1245} + {1491055200 45900 0 +1245} + {1506175200 49500 1 +1245} + {1522504800 45900 0 +1245} + {1538229600 49500 1 +1245} + {1554559200 45900 0 +1245} + {1569679200 49500 1 +1245} + {1586008800 45900 0 +1245} + {1601128800 49500 1 +1245} + {1617458400 45900 0 +1245} + {1632578400 49500 1 +1245} + {1648908000 45900 0 +1245} + {1664028000 49500 1 +1245} + {1680357600 45900 0 +1245} + {1695477600 49500 1 +1245} + {1712412000 45900 0 +1245} + {1727532000 49500 1 +1245} + {1743861600 45900 0 +1245} + {1758981600 49500 1 +1245} + {1775311200 45900 0 +1245} + {1790431200 49500 1 +1245} + {1806760800 45900 0 +1245} + {1821880800 49500 1 +1245} + {1838210400 45900 0 +1245} + {1853330400 49500 1 +1245} + {1869660000 45900 0 +1245} + {1885384800 49500 1 +1245} + {1901714400 45900 0 +1245} + {1916834400 49500 1 +1245} + {1933164000 45900 0 +1245} + {1948284000 49500 1 +1245} + {1964613600 45900 0 +1245} + {1979733600 49500 1 +1245} + {1996063200 45900 0 +1245} + {2011183200 49500 1 +1245} + {2027512800 45900 0 +1245} + {2042632800 49500 1 +1245} + {2058962400 45900 0 +1245} + {2074687200 49500 1 +1245} + {2091016800 45900 0 +1245} + {2106136800 49500 1 +1245} + {2122466400 45900 0 +1245} + {2137586400 49500 1 +1245} + {2153916000 45900 0 +1245} + {2169036000 49500 1 +1245} + {2185365600 45900 0 +1245} + {2200485600 49500 1 +1245} + {2216815200 45900 0 +1245} + {2232540000 49500 1 +1245} + {2248869600 45900 0 +1245} + {2263989600 49500 1 +1245} + {2280319200 45900 0 +1245} + {2295439200 49500 1 +1245} + {2311768800 45900 0 +1245} + {2326888800 49500 1 +1245} + {2343218400 45900 0 +1245} + {2358338400 49500 1 +1245} + {2374668000 45900 0 +1245} + {2389788000 49500 1 +1245} + {2406117600 45900 0 +1245} + {2421842400 49500 1 +1245} + {2438172000 45900 0 +1245} + {2453292000 49500 1 +1245} + {2469621600 45900 0 +1245} + {2484741600 49500 1 +1245} + {2501071200 45900 0 +1245} + {2516191200 49500 1 +1245} + {2532520800 45900 0 +1245} + {2547640800 49500 1 +1245} + {2563970400 45900 0 +1245} + {2579090400 49500 1 +1245} + {2596024800 45900 0 +1245} + {2611144800 49500 1 +1245} + {2627474400 45900 0 +1245} + {2642594400 49500 1 +1245} + {2658924000 45900 0 +1245} + {2674044000 49500 1 +1245} + {2690373600 45900 0 +1245} + {2705493600 49500 1 +1245} + {2721823200 45900 0 +1245} + {2736943200 49500 1 +1245} + {2753272800 45900 0 +1245} + {2768997600 49500 1 +1245} + {2785327200 45900 0 +1245} + {2800447200 49500 1 +1245} + {2816776800 45900 0 +1245} + {2831896800 49500 1 +1245} + {2848226400 45900 0 +1245} + {2863346400 49500 1 +1245} + {2879676000 45900 0 +1245} + {2894796000 49500 1 +1245} + {2911125600 45900 0 +1245} + {2926245600 49500 1 +1245} + {2942575200 45900 0 +1245} + {2958300000 49500 1 +1245} + {2974629600 45900 0 +1245} + {2989749600 49500 1 +1245} + {3006079200 45900 0 +1245} + {3021199200 49500 1 +1245} + {3037528800 45900 0 +1245} + {3052648800 49500 1 +1245} + {3068978400 45900 0 +1245} + {3084098400 49500 1 +1245} + {3100428000 45900 0 +1245} + {3116152800 49500 1 +1245} + {3132482400 45900 0 +1245} + {3147602400 49500 1 +1245} + {3163932000 45900 0 +1245} + {3179052000 49500 1 +1245} + {3195381600 45900 0 +1245} + {3210501600 49500 1 +1245} + {3226831200 45900 0 +1245} + {3241951200 49500 1 +1245} + {3258280800 45900 0 +1245} + {3273400800 49500 1 +1245} + {3289730400 45900 0 +1245} + {3305455200 49500 1 +1245} + {3321784800 45900 0 +1245} + {3336904800 49500 1 +1245} + {3353234400 45900 0 +1245} + {3368354400 49500 1 +1245} + {3384684000 45900 0 +1245} + {3399804000 49500 1 +1245} + {3416133600 45900 0 +1245} + {3431253600 49500 1 +1245} + {3447583200 45900 0 +1245} + {3462703200 49500 1 +1245} + {3479637600 45900 0 +1245} + {3494757600 49500 1 +1245} + {3511087200 45900 0 +1245} + {3526207200 49500 1 +1245} + {3542536800 45900 0 +1245} + {3557656800 49500 1 +1245} + {3573986400 45900 0 +1245} + {3589106400 49500 1 +1245} + {3605436000 45900 0 +1245} + {3620556000 49500 1 +1245} + {3636885600 45900 0 +1245} + {3652610400 49500 1 +1245} + {3668940000 45900 0 +1245} + {3684060000 49500 1 +1245} + {3700389600 45900 0 +1245} + {3715509600 49500 1 +1245} + {3731839200 45900 0 +1245} + {3746959200 49500 1 +1245} + {3763288800 45900 0 +1245} + {3778408800 49500 1 +1245} + {3794738400 45900 0 +1245} + {3809858400 49500 1 +1245} + {3826188000 45900 0 +1245} + {3841912800 49500 1 +1245} + {3858242400 45900 0 +1245} + {3873362400 49500 1 +1245} + {3889692000 45900 0 +1245} + {3904812000 49500 1 +1245} + {3921141600 45900 0 +1245} + {3936261600 49500 1 +1245} + {3952591200 45900 0 +1245} + {3967711200 49500 1 +1245} + {3984040800 45900 0 +1245} + {3999765600 49500 1 +1245} + {4016095200 45900 0 +1245} + {4031215200 49500 1 +1245} + {4047544800 45900 0 +1245} + {4062664800 49500 1 +1245} + {4078994400 45900 0 +1245} + {4094114400 49500 1 +1245} } diff --git a/library/tzdata/Pacific/Easter b/library/tzdata/Pacific/Easter index 474a32b..a087cd0 100644 --- a/library/tzdata/Pacific/Easter +++ b/library/tzdata/Pacific/Easter @@ -4,265 +4,265 @@ set TZData(:Pacific/Easter) { {-9223372036854775808 -26248 0 LMT} {-2524495352 -26248 0 EMT} {-1178124152 -25200 0 -07} - {-36619200 -21600 1 -06} + {-36619200 -21600 1 -07} {-23922000 -25200 0 -07} - {-3355200 -21600 1 -06} + {-3355200 -21600 1 -07} {7527600 -25200 0 -07} - {24465600 -21600 1 -06} + {24465600 -21600 1 -07} {37767600 -25200 0 -07} - {55915200 -21600 1 -06} + {55915200 -21600 1 -07} {69217200 -25200 0 -07} - {87969600 -21600 1 -06} + {87969600 -21600 1 -07} {100666800 -25200 0 -07} - {118209600 -21600 1 -06} + {118209600 -21600 1 -07} {132116400 -25200 0 -07} - {150868800 -21600 1 -06} + {150868800 -21600 1 -07} {163566000 -25200 0 -07} - {182318400 -21600 1 -06} + {182318400 -21600 1 -07} {195620400 -25200 0 -07} - {213768000 -21600 1 -06} + {213768000 -21600 1 -07} {227070000 -25200 0 -07} - {245217600 -21600 1 -06} + {245217600 -21600 1 -07} {258519600 -25200 0 -07} - {277272000 -21600 1 -06} + {277272000 -21600 1 -07} {289969200 -25200 0 -07} - {308721600 -21600 1 -06} + {308721600 -21600 1 -07} {321418800 -25200 0 -07} - {340171200 -21600 1 -06} + {340171200 -21600 1 -07} {353473200 -25200 0 -07} - {371620800 -21600 1 -06} + {371620800 -21600 1 -07} {384922800 -21600 0 -06} - {403070400 -18000 1 -05} + {403070400 -18000 1 -06} {416372400 -21600 0 -06} - {434520000 -18000 1 -05} + {434520000 -18000 1 -06} {447822000 -21600 0 -06} - {466574400 -18000 1 -05} + {466574400 -18000 1 -06} {479271600 -21600 0 -06} - {498024000 -18000 1 -05} + {498024000 -18000 1 -06} {510721200 -21600 0 -06} - {529473600 -18000 1 -05} + {529473600 -18000 1 -06} {545194800 -21600 0 -06} - {560923200 -18000 1 -05} + {560923200 -18000 1 -06} {574225200 -21600 0 -06} - {592372800 -18000 1 -05} + {592372800 -18000 1 -06} {605674800 -21600 0 -06} - {624427200 -18000 1 -05} + {624427200 -18000 1 -06} {637124400 -21600 0 -06} - {653457600 -18000 1 -05} + {653457600 -18000 1 -06} {668574000 -21600 0 -06} - {687326400 -18000 1 -05} + {687326400 -18000 1 -06} {700628400 -21600 0 -06} - {718776000 -18000 1 -05} + {718776000 -18000 1 -06} {732078000 -21600 0 -06} - {750225600 -18000 1 -05} + {750225600 -18000 1 -06} {763527600 -21600 0 -06} - {781675200 -18000 1 -05} + {781675200 -18000 1 -06} {794977200 -21600 0 -06} - {813729600 -18000 1 -05} + {813729600 -18000 1 -06} {826426800 -21600 0 -06} - {845179200 -18000 1 -05} + {845179200 -18000 1 -06} {859690800 -21600 0 -06} - {876628800 -18000 1 -05} + {876628800 -18000 1 -06} {889930800 -21600 0 -06} - {906868800 -18000 1 -05} + {906868800 -18000 1 -06} {923194800 -21600 0 -06} - {939528000 -18000 1 -05} + {939528000 -18000 1 -06} {952830000 -21600 0 -06} - {971582400 -18000 1 -05} + {971582400 -18000 1 -06} {984279600 -21600 0 -06} - {1003032000 -18000 1 -05} + {1003032000 -18000 1 -06} {1015729200 -21600 0 -06} - {1034481600 -18000 1 -05} + {1034481600 -18000 1 -06} {1047178800 -21600 0 -06} - {1065931200 -18000 1 -05} + {1065931200 -18000 1 -06} {1079233200 -21600 0 -06} - {1097380800 -18000 1 -05} + {1097380800 -18000 1 -06} {1110682800 -21600 0 -06} - {1128830400 -18000 1 -05} + {1128830400 -18000 1 -06} {1142132400 -21600 0 -06} - {1160884800 -18000 1 -05} + {1160884800 -18000 1 -06} {1173582000 -21600 0 -06} - {1192334400 -18000 1 -05} + {1192334400 -18000 1 -06} {1206846000 -21600 0 -06} - {1223784000 -18000 1 -05} + {1223784000 -18000 1 -06} {1237086000 -21600 0 -06} - {1255233600 -18000 1 -05} + {1255233600 -18000 1 -06} {1270350000 -21600 0 -06} - {1286683200 -18000 1 -05} + {1286683200 -18000 1 -06} {1304823600 -21600 0 -06} - {1313899200 -18000 1 -05} + {1313899200 -18000 1 -06} {1335668400 -21600 0 -06} - {1346558400 -18000 1 -05} + {1346558400 -18000 1 -06} {1367118000 -21600 0 -06} - {1378612800 -18000 1 -05} + {1378612800 -18000 1 -06} {1398567600 -21600 0 -06} - {1410062400 -18000 1 -05} + {1410062400 -18000 1 -06} {1463281200 -21600 0 -06} - {1471147200 -18000 1 -05} + {1471147200 -18000 1 -06} {1494730800 -21600 0 -06} - {1502596800 -18000 1 -05} + {1502596800 -18000 1 -06} {1526180400 -21600 0 -06} - {1534046400 -18000 1 -05} + {1534046400 -18000 1 -06} {1557630000 -21600 0 -06} - {1565496000 -18000 1 -05} + {1565496000 -18000 1 -06} {1589079600 -21600 0 -06} - {1596945600 -18000 1 -05} + {1596945600 -18000 1 -06} {1620529200 -21600 0 -06} - {1629000000 -18000 1 -05} + {1629000000 -18000 1 -06} {1652583600 -21600 0 -06} - {1660449600 -18000 1 -05} + {1660449600 -18000 1 -06} {1684033200 -21600 0 -06} - {1691899200 -18000 1 -05} + {1691899200 -18000 1 -06} {1715482800 -21600 0 -06} - {1723348800 -18000 1 -05} + {1723348800 -18000 1 -06} {1746932400 -21600 0 -06} - {1754798400 -18000 1 -05} + {1754798400 -18000 1 -06} {1778382000 -21600 0 -06} - {1786248000 -18000 1 -05} + {1786248000 -18000 1 -06} {1809831600 -21600 0 -06} - {1818302400 -18000 1 -05} + {1818302400 -18000 1 -06} {1841886000 -21600 0 -06} - {1849752000 -18000 1 -05} + {1849752000 -18000 1 -06} {1873335600 -21600 0 -06} - {1881201600 -18000 1 -05} + {1881201600 -18000 1 -06} {1904785200 -21600 0 -06} - {1912651200 -18000 1 -05} + {1912651200 -18000 1 -06} {1936234800 -21600 0 -06} - {1944100800 -18000 1 -05} + {1944100800 -18000 1 -06} {1967684400 -21600 0 -06} - {1976155200 -18000 1 -05} + {1976155200 -18000 1 -06} {1999738800 -21600 0 -06} - {2007604800 -18000 1 -05} + {2007604800 -18000 1 -06} {2031188400 -21600 0 -06} - {2039054400 -18000 1 -05} + {2039054400 -18000 1 -06} {2062638000 -21600 0 -06} - {2070504000 -18000 1 -05} + {2070504000 -18000 1 -06} {2094087600 -21600 0 -06} - {2101953600 -18000 1 -05} + {2101953600 -18000 1 -06} {2125537200 -21600 0 -06} - {2133403200 -18000 1 -05} + {2133403200 -18000 1 -06} {2156986800 -21600 0 -06} - {2165457600 -18000 1 -05} + {2165457600 -18000 1 -06} {2189041200 -21600 0 -06} - {2196907200 -18000 1 -05} + {2196907200 -18000 1 -06} {2220490800 -21600 0 -06} - {2228356800 -18000 1 -05} + {2228356800 -18000 1 -06} {2251940400 -21600 0 -06} - {2259806400 -18000 1 -05} + {2259806400 -18000 1 -06} {2283390000 -21600 0 -06} - {2291256000 -18000 1 -05} + {2291256000 -18000 1 -06} {2314839600 -21600 0 -06} - {2322705600 -18000 1 -05} + {2322705600 -18000 1 -06} {2346894000 -21600 0 -06} - {2354760000 -18000 1 -05} + {2354760000 -18000 1 -06} {2378343600 -21600 0 -06} - {2386209600 -18000 1 -05} + {2386209600 -18000 1 -06} {2409793200 -21600 0 -06} - {2417659200 -18000 1 -05} + {2417659200 -18000 1 -06} {2441242800 -21600 0 -06} - {2449108800 -18000 1 -05} + {2449108800 -18000 1 -06} {2472692400 -21600 0 -06} - {2480558400 -18000 1 -05} + {2480558400 -18000 1 -06} {2504142000 -21600 0 -06} - {2512612800 -18000 1 -05} + {2512612800 -18000 1 -06} {2536196400 -21600 0 -06} - {2544062400 -18000 1 -05} + {2544062400 -18000 1 -06} {2567646000 -21600 0 -06} - {2575512000 -18000 1 -05} + {2575512000 -18000 1 -06} {2599095600 -21600 0 -06} - {2606961600 -18000 1 -05} + {2606961600 -18000 1 -06} {2630545200 -21600 0 -06} - {2638411200 -18000 1 -05} + {2638411200 -18000 1 -06} {2661994800 -21600 0 -06} - {2669860800 -18000 1 -05} + {2669860800 -18000 1 -06} {2693444400 -21600 0 -06} - {2701915200 -18000 1 -05} + {2701915200 -18000 1 -06} {2725498800 -21600 0 -06} - {2733364800 -18000 1 -05} + {2733364800 -18000 1 -06} {2756948400 -21600 0 -06} - {2764814400 -18000 1 -05} + {2764814400 -18000 1 -06} {2788398000 -21600 0 -06} - {2796264000 -18000 1 -05} + {2796264000 -18000 1 -06} {2819847600 -21600 0 -06} - {2827713600 -18000 1 -05} + {2827713600 -18000 1 -06} {2851297200 -21600 0 -06} - {2859768000 -18000 1 -05} + {2859768000 -18000 1 -06} {2883351600 -21600 0 -06} - {2891217600 -18000 1 -05} + {2891217600 -18000 1 -06} {2914801200 -21600 0 -06} - {2922667200 -18000 1 -05} + {2922667200 -18000 1 -06} {2946250800 -21600 0 -06} - {2954116800 -18000 1 -05} + {2954116800 -18000 1 -06} {2977700400 -21600 0 -06} - {2985566400 -18000 1 -05} + {2985566400 -18000 1 -06} {3009150000 -21600 0 -06} - {3017016000 -18000 1 -05} + {3017016000 -18000 1 -06} {3040599600 -21600 0 -06} - {3049070400 -18000 1 -05} + {3049070400 -18000 1 -06} {3072654000 -21600 0 -06} - {3080520000 -18000 1 -05} + {3080520000 -18000 1 -06} {3104103600 -21600 0 -06} - {3111969600 -18000 1 -05} + {3111969600 -18000 1 -06} {3135553200 -21600 0 -06} - {3143419200 -18000 1 -05} + {3143419200 -18000 1 -06} {3167002800 -21600 0 -06} - {3174868800 -18000 1 -05} + {3174868800 -18000 1 -06} {3198452400 -21600 0 -06} - {3206318400 -18000 1 -05} + {3206318400 -18000 1 -06} {3230506800 -21600 0 -06} - {3238372800 -18000 1 -05} + {3238372800 -18000 1 -06} {3261956400 -21600 0 -06} - {3269822400 -18000 1 -05} + {3269822400 -18000 1 -06} {3293406000 -21600 0 -06} - {3301272000 -18000 1 -05} + {3301272000 -18000 1 -06} {3324855600 -21600 0 -06} - {3332721600 -18000 1 -05} + {3332721600 -18000 1 -06} {3356305200 -21600 0 -06} - {3364171200 -18000 1 -05} + {3364171200 -18000 1 -06} {3387754800 -21600 0 -06} - {3396225600 -18000 1 -05} + {3396225600 -18000 1 -06} {3419809200 -21600 0 -06} - {3427675200 -18000 1 -05} + {3427675200 -18000 1 -06} {3451258800 -21600 0 -06} - {3459124800 -18000 1 -05} + {3459124800 -18000 1 -06} {3482708400 -21600 0 -06} - {3490574400 -18000 1 -05} + {3490574400 -18000 1 -06} {3514158000 -21600 0 -06} - {3522024000 -18000 1 -05} + {3522024000 -18000 1 -06} {3545607600 -21600 0 -06} - {3553473600 -18000 1 -05} + {3553473600 -18000 1 -06} {3577057200 -21600 0 -06} - {3585528000 -18000 1 -05} + {3585528000 -18000 1 -06} {3609111600 -21600 0 -06} - {3616977600 -18000 1 -05} + {3616977600 -18000 1 -06} {3640561200 -21600 0 -06} - {3648427200 -18000 1 -05} + {3648427200 -18000 1 -06} {3672010800 -21600 0 -06} - {3679876800 -18000 1 -05} + {3679876800 -18000 1 -06} {3703460400 -21600 0 -06} - {3711326400 -18000 1 -05} + {3711326400 -18000 1 -06} {3734910000 -21600 0 -06} - {3743380800 -18000 1 -05} + {3743380800 -18000 1 -06} {3766964400 -21600 0 -06} - {3774830400 -18000 1 -05} + {3774830400 -18000 1 -06} {3798414000 -21600 0 -06} - {3806280000 -18000 1 -05} + {3806280000 -18000 1 -06} {3829863600 -21600 0 -06} - {3837729600 -18000 1 -05} + {3837729600 -18000 1 -06} {3861313200 -21600 0 -06} - {3869179200 -18000 1 -05} + {3869179200 -18000 1 -06} {3892762800 -21600 0 -06} - {3900628800 -18000 1 -05} + {3900628800 -18000 1 -06} {3924212400 -21600 0 -06} - {3932683200 -18000 1 -05} + {3932683200 -18000 1 -06} {3956266800 -21600 0 -06} - {3964132800 -18000 1 -05} + {3964132800 -18000 1 -06} {3987716400 -21600 0 -06} - {3995582400 -18000 1 -05} + {3995582400 -18000 1 -06} {4019166000 -21600 0 -06} - {4027032000 -18000 1 -05} + {4027032000 -18000 1 -06} {4050615600 -21600 0 -06} - {4058481600 -18000 1 -05} + {4058481600 -18000 1 -06} {4082065200 -21600 0 -06} - {4089931200 -18000 1 -05} + {4089931200 -18000 1 -06} } diff --git a/library/tzdata/Pacific/Efate b/library/tzdata/Pacific/Efate index a43852e..a026ee1 100644 --- a/library/tzdata/Pacific/Efate +++ b/library/tzdata/Pacific/Efate @@ -3,24 +3,24 @@ set TZData(:Pacific/Efate) { {-9223372036854775808 40396 0 LMT} {-1829387596 39600 0 +11} - {433256400 43200 1 +12} + {433256400 43200 1 +11} {448977600 39600 0 +11} - {467298000 43200 1 +12} + {467298000 43200 1 +11} {480427200 39600 0 +11} - {496760400 43200 1 +12} + {496760400 43200 1 +11} {511876800 39600 0 +11} - {528210000 43200 1 +12} + {528210000 43200 1 +11} {543931200 39600 0 +11} - {559659600 43200 1 +12} + {559659600 43200 1 +11} {575380800 39600 0 +11} - {591109200 43200 1 +12} + {591109200 43200 1 +11} {606830400 39600 0 +11} - {622558800 43200 1 +12} + {622558800 43200 1 +11} {638280000 39600 0 +11} - {654008400 43200 1 +12} + {654008400 43200 1 +11} {669729600 39600 0 +11} - {686062800 43200 1 +12} + {686062800 43200 1 +11} {696340800 39600 0 +11} - {719931600 43200 1 +12} + {719931600 43200 1 +11} {727790400 39600 0 +11} } diff --git a/library/tzdata/Pacific/Enderbury b/library/tzdata/Pacific/Enderbury index 6abd57e..48eaafe 100644 --- a/library/tzdata/Pacific/Enderbury +++ b/library/tzdata/Pacific/Enderbury @@ -4,5 +4,5 @@ set TZData(:Pacific/Enderbury) { {-9223372036854775808 -41060 0 LMT} {-2177411740 -43200 0 -12} {307627200 -39600 0 -11} - {788958000 46800 0 +13} + {788871600 46800 0 +13} } diff --git a/library/tzdata/Pacific/Fiji b/library/tzdata/Pacific/Fiji index f9d393c..610c191 100644 --- a/library/tzdata/Pacific/Fiji +++ b/library/tzdata/Pacific/Fiji @@ -3,189 +3,189 @@ set TZData(:Pacific/Fiji) { {-9223372036854775808 42944 0 LMT} {-1709985344 43200 0 +12} - {909842400 46800 1 +13} + {909842400 46800 1 +12} {920124000 43200 0 +12} - {941896800 46800 1 +13} + {941896800 46800 1 +12} {951573600 43200 0 +12} - {1259416800 46800 1 +13} + {1259416800 46800 1 +12} {1269698400 43200 0 +12} - {1287842400 46800 1 +13} + {1287842400 46800 1 +12} {1299333600 43200 0 +12} - {1319292000 46800 1 +13} + {1319292000 46800 1 +12} {1327154400 43200 0 +12} - {1350741600 46800 1 +13} + {1350741600 46800 1 +12} {1358604000 43200 0 +12} - {1382796000 46800 1 +13} + {1382796000 46800 1 +12} {1390050000 43200 0 +12} - {1414850400 46800 1 +13} + {1414850400 46800 1 +12} {1421503200 43200 0 +12} - {1446300000 46800 1 +13} + {1446300000 46800 1 +12} {1452952800 43200 0 +12} - {1478354400 46800 1 +13} + {1478354400 46800 1 +12} {1484402400 43200 0 +12} - {1509804000 46800 1 +13} + {1509804000 46800 1 +12} {1515852000 43200 0 +12} - {1541253600 46800 1 +13} + {1541253600 46800 1 +12} {1547906400 43200 0 +12} - {1572703200 46800 1 +13} + {1572703200 46800 1 +12} {1579356000 43200 0 +12} - {1604152800 46800 1 +13} + {1604152800 46800 1 +12} {1610805600 43200 0 +12} - {1636207200 46800 1 +13} + {1636207200 46800 1 +12} {1642255200 43200 0 +12} - {1667656800 46800 1 +13} + {1667656800 46800 1 +12} {1673704800 43200 0 +12} - {1699106400 46800 1 +13} + {1699106400 46800 1 +12} {1705154400 43200 0 +12} - {1730556000 46800 1 +13} + {1730556000 46800 1 +12} {1737208800 43200 0 +12} - {1762005600 46800 1 +13} + {1762005600 46800 1 +12} {1768658400 43200 0 +12} - {1793455200 46800 1 +13} + {1793455200 46800 1 +12} {1800108000 43200 0 +12} - {1825509600 46800 1 +13} + {1825509600 46800 1 +12} {1831557600 43200 0 +12} - {1856959200 46800 1 +13} + {1856959200 46800 1 +12} {1863007200 43200 0 +12} - {1888408800 46800 1 +13} + {1888408800 46800 1 +12} {1895061600 43200 0 +12} - {1919858400 46800 1 +13} + {1919858400 46800 1 +12} {1926511200 43200 0 +12} - {1951308000 46800 1 +13} + {1951308000 46800 1 +12} {1957960800 43200 0 +12} - {1983362400 46800 1 +13} + {1983362400 46800 1 +12} {1989410400 43200 0 +12} - {2014812000 46800 1 +13} + {2014812000 46800 1 +12} {2020860000 43200 0 +12} - {2046261600 46800 1 +13} + {2046261600 46800 1 +12} {2052309600 43200 0 +12} - {2077711200 46800 1 +13} + {2077711200 46800 1 +12} {2084364000 43200 0 +12} - {2109160800 46800 1 +13} + {2109160800 46800 1 +12} {2115813600 43200 0 +12} - {2140610400 46800 1 +13} + {2140610400 46800 1 +12} {2147263200 43200 0 +12} - {2172664800 46800 1 +13} + {2172664800 46800 1 +12} {2178712800 43200 0 +12} - {2204114400 46800 1 +13} + {2204114400 46800 1 +12} {2210162400 43200 0 +12} - {2235564000 46800 1 +13} + {2235564000 46800 1 +12} {2242216800 43200 0 +12} - {2267013600 46800 1 +13} + {2267013600 46800 1 +12} {2273666400 43200 0 +12} - {2298463200 46800 1 +13} + {2298463200 46800 1 +12} {2305116000 43200 0 +12} - {2329912800 46800 1 +13} + {2329912800 46800 1 +12} {2336565600 43200 0 +12} - {2361967200 46800 1 +13} + {2361967200 46800 1 +12} {2368015200 43200 0 +12} - {2393416800 46800 1 +13} + {2393416800 46800 1 +12} {2399464800 43200 0 +12} - {2424866400 46800 1 +13} + {2424866400 46800 1 +12} {2431519200 43200 0 +12} - {2456316000 46800 1 +13} + {2456316000 46800 1 +12} {2462968800 43200 0 +12} - {2487765600 46800 1 +13} + {2487765600 46800 1 +12} {2494418400 43200 0 +12} - {2519820000 46800 1 +13} + {2519820000 46800 1 +12} {2525868000 43200 0 +12} - {2551269600 46800 1 +13} + {2551269600 46800 1 +12} {2557317600 43200 0 +12} - {2582719200 46800 1 +13} + {2582719200 46800 1 +12} {2588767200 43200 0 +12} - {2614168800 46800 1 +13} + {2614168800 46800 1 +12} {2620821600 43200 0 +12} - {2645618400 46800 1 +13} + {2645618400 46800 1 +12} {2652271200 43200 0 +12} - {2677068000 46800 1 +13} + {2677068000 46800 1 +12} {2683720800 43200 0 +12} - {2709122400 46800 1 +13} + {2709122400 46800 1 +12} {2715170400 43200 0 +12} - {2740572000 46800 1 +13} + {2740572000 46800 1 +12} {2746620000 43200 0 +12} - {2772021600 46800 1 +13} + {2772021600 46800 1 +12} {2778674400 43200 0 +12} - {2803471200 46800 1 +13} + {2803471200 46800 1 +12} {2810124000 43200 0 +12} - {2834920800 46800 1 +13} + {2834920800 46800 1 +12} {2841573600 43200 0 +12} - {2866975200 46800 1 +13} + {2866975200 46800 1 +12} {2873023200 43200 0 +12} - {2898424800 46800 1 +13} + {2898424800 46800 1 +12} {2904472800 43200 0 +12} - {2929874400 46800 1 +13} + {2929874400 46800 1 +12} {2935922400 43200 0 +12} - {2961324000 46800 1 +13} + {2961324000 46800 1 +12} {2967976800 43200 0 +12} - {2992773600 46800 1 +13} + {2992773600 46800 1 +12} {2999426400 43200 0 +12} - {3024223200 46800 1 +13} + {3024223200 46800 1 +12} {3030876000 43200 0 +12} - {3056277600 46800 1 +13} + {3056277600 46800 1 +12} {3062325600 43200 0 +12} - {3087727200 46800 1 +13} + {3087727200 46800 1 +12} {3093775200 43200 0 +12} - {3119176800 46800 1 +13} + {3119176800 46800 1 +12} {3125829600 43200 0 +12} - {3150626400 46800 1 +13} + {3150626400 46800 1 +12} {3157279200 43200 0 +12} - {3182076000 46800 1 +13} + {3182076000 46800 1 +12} {3188728800 43200 0 +12} - {3213525600 46800 1 +13} + {3213525600 46800 1 +12} {3220178400 43200 0 +12} - {3245580000 46800 1 +13} + {3245580000 46800 1 +12} {3251628000 43200 0 +12} - {3277029600 46800 1 +13} + {3277029600 46800 1 +12} {3283077600 43200 0 +12} - {3308479200 46800 1 +13} + {3308479200 46800 1 +12} {3315132000 43200 0 +12} - {3339928800 46800 1 +13} + {3339928800 46800 1 +12} {3346581600 43200 0 +12} - {3371378400 46800 1 +13} + {3371378400 46800 1 +12} {3378031200 43200 0 +12} - {3403432800 46800 1 +13} + {3403432800 46800 1 +12} {3409480800 43200 0 +12} - {3434882400 46800 1 +13} + {3434882400 46800 1 +12} {3440930400 43200 0 +12} - {3466332000 46800 1 +13} + {3466332000 46800 1 +12} {3472380000 43200 0 +12} - {3497781600 46800 1 +13} + {3497781600 46800 1 +12} {3504434400 43200 0 +12} - {3529231200 46800 1 +13} + {3529231200 46800 1 +12} {3535884000 43200 0 +12} - {3560680800 46800 1 +13} + {3560680800 46800 1 +12} {3567333600 43200 0 +12} - {3592735200 46800 1 +13} + {3592735200 46800 1 +12} {3598783200 43200 0 +12} - {3624184800 46800 1 +13} + {3624184800 46800 1 +12} {3630232800 43200 0 +12} - {3655634400 46800 1 +13} + {3655634400 46800 1 +12} {3662287200 43200 0 +12} - {3687084000 46800 1 +13} + {3687084000 46800 1 +12} {3693736800 43200 0 +12} - {3718533600 46800 1 +13} + {3718533600 46800 1 +12} {3725186400 43200 0 +12} - {3750588000 46800 1 +13} + {3750588000 46800 1 +12} {3756636000 43200 0 +12} - {3782037600 46800 1 +13} + {3782037600 46800 1 +12} {3788085600 43200 0 +12} - {3813487200 46800 1 +13} + {3813487200 46800 1 +12} {3819535200 43200 0 +12} - {3844936800 46800 1 +13} + {3844936800 46800 1 +12} {3851589600 43200 0 +12} - {3876386400 46800 1 +13} + {3876386400 46800 1 +12} {3883039200 43200 0 +12} - {3907836000 46800 1 +13} + {3907836000 46800 1 +12} {3914488800 43200 0 +12} - {3939890400 46800 1 +13} + {3939890400 46800 1 +12} {3945938400 43200 0 +12} - {3971340000 46800 1 +13} + {3971340000 46800 1 +12} {3977388000 43200 0 +12} - {4002789600 46800 1 +13} + {4002789600 46800 1 +12} {4009442400 43200 0 +12} - {4034239200 46800 1 +13} + {4034239200 46800 1 +12} {4040892000 43200 0 +12} - {4065688800 46800 1 +13} + {4065688800 46800 1 +12} {4072341600 43200 0 +12} - {4097138400 46800 1 +13} + {4097138400 46800 1 +12} } diff --git a/library/tzdata/Pacific/Galapagos b/library/tzdata/Pacific/Galapagos index f276f73..180ce6a 100644 --- a/library/tzdata/Pacific/Galapagos +++ b/library/tzdata/Pacific/Galapagos @@ -4,6 +4,6 @@ set TZData(:Pacific/Galapagos) { {-9223372036854775808 -21504 0 LMT} {-1230746496 -18000 0 -05} {504939600 -21600 0 -06} - {722930400 -18000 1 -05} + {722930400 -18000 1 -06} {728888400 -21600 0 -06} } diff --git a/library/tzdata/Pacific/Kiritimati b/library/tzdata/Pacific/Kiritimati index b703f19..7d600f3 100644 --- a/library/tzdata/Pacific/Kiritimati +++ b/library/tzdata/Pacific/Kiritimati @@ -4,5 +4,5 @@ set TZData(:Pacific/Kiritimati) { {-9223372036854775808 -37760 0 LMT} {-2177415040 -38400 0 -1040} {307622400 -36000 0 -10} - {788954400 50400 0 +14} + {788868000 50400 0 +14} } diff --git a/library/tzdata/Pacific/Noumea b/library/tzdata/Pacific/Noumea index 36b570d..c9da825 100644 --- a/library/tzdata/Pacific/Noumea +++ b/library/tzdata/Pacific/Noumea @@ -3,10 +3,10 @@ set TZData(:Pacific/Noumea) { {-9223372036854775808 39948 0 LMT} {-1829387148 39600 0 +11} - {250002000 43200 1 +12} + {250002000 43200 1 +11} {257342400 39600 0 +11} - {281451600 43200 1 +12} + {281451600 43200 1 +11} {288878400 39600 0 +11} - {849366000 43200 1 +12} + {849366000 43200 1 +11} {857228400 39600 0 +11} } diff --git a/library/tzdata/Pacific/Rarotonga b/library/tzdata/Pacific/Rarotonga index 9a70318..2913d68 100644 --- a/library/tzdata/Pacific/Rarotonga +++ b/library/tzdata/Pacific/Rarotonga @@ -3,30 +3,30 @@ set TZData(:Pacific/Rarotonga) { {-9223372036854775808 -38344 0 LMT} {-2177414456 -37800 0 -1030} - {279714600 -34200 0 -0930} + {279714600 -34200 0 -10} {289387800 -36000 0 -10} - {309952800 -34200 1 -0930} + {309952800 -34200 1 -10} {320837400 -36000 0 -10} - {341402400 -34200 1 -0930} + {341402400 -34200 1 -10} {352287000 -36000 0 -10} - {372852000 -34200 1 -0930} + {372852000 -34200 1 -10} {384341400 -36000 0 -10} - {404906400 -34200 1 -0930} + {404906400 -34200 1 -10} {415791000 -36000 0 -10} - {436356000 -34200 1 -0930} + {436356000 -34200 1 -10} {447240600 -36000 0 -10} - {467805600 -34200 1 -0930} + {467805600 -34200 1 -10} {478690200 -36000 0 -10} - {499255200 -34200 1 -0930} + {499255200 -34200 1 -10} {510139800 -36000 0 -10} - {530704800 -34200 1 -0930} + {530704800 -34200 1 -10} {541589400 -36000 0 -10} - {562154400 -34200 1 -0930} + {562154400 -34200 1 -10} {573643800 -36000 0 -10} - {594208800 -34200 1 -0930} + {594208800 -34200 1 -10} {605093400 -36000 0 -10} - {625658400 -34200 1 -0930} + {625658400 -34200 1 -10} {636543000 -36000 0 -10} - {657108000 -34200 1 -0930} + {657108000 -34200 1 -10} {667992600 -36000 0 -10} } diff --git a/library/tzdata/Pacific/Tongatapu b/library/tzdata/Pacific/Tongatapu index 3cfaaaa..104888a 100644 --- a/library/tzdata/Pacific/Tongatapu +++ b/library/tzdata/Pacific/Tongatapu @@ -5,12 +5,12 @@ set TZData(:Pacific/Tongatapu) { {-2177497160 44400 0 +1220} {-915193200 46800 0 +13} {915102000 46800 0 +13} - {939214800 50400 1 +14} + {939214800 50400 1 +13} {953384400 46800 0 +13} - {973342800 50400 1 +14} + {973342800 50400 1 +13} {980596800 46800 0 +13} - {1004792400 50400 1 +14} + {1004792400 50400 1 +13} {1012046400 46800 0 +13} - {1478350800 50400 1 +14} + {1478350800 50400 1 +13} {1484398800 46800 0 +13} } -- cgit v0.12 From 3abde0eac5528b50db5a8267c5fb30b07714c079 Mon Sep 17 00:00:00 2001 From: "jan.nijtmans" Date: Sun, 25 Mar 2018 17:43:09 +0000 Subject: workaround for TclFormatInt on CYGWIN is no longer necessary now. --- generic/tclStubInit.c | 4 ---- 1 file changed, 4 deletions(-) diff --git a/generic/tclStubInit.c b/generic/tclStubInit.c index 86406c1..5df72be 100644 --- a/generic/tclStubInit.c +++ b/generic/tclStubInit.c @@ -335,10 +335,6 @@ static int uniCharNcasecmp(const Tcl_UniChar *ucs, const Tcl_UniChar *uct, unsig return Tcl_UniCharNcasecmp(ucs, uct, (unsigned long)n); } #define Tcl_UniCharNcasecmp (int(*)(const Tcl_UniChar*,const Tcl_UniChar*,unsigned long))uniCharNcasecmp -static int formatInt(char *buffer, int n){ - return TclFormatInt(buffer, (long)n); -} -#define TclFormatInt (int(*)(char *, long))formatInt #endif /* TCL_WIDE_INT_IS_LONG */ -- cgit v0.12 From 08dc58ce408e626f0042eb1bbe92257aa3bdd927 Mon Sep 17 00:00:00 2001 From: "jan.nijtmans" Date: Sun, 25 Mar 2018 19:20:28 +0000 Subject: No need any more on 64-bit cygwin for special *Long* stub entries. --- generic/tclStubInit.c | 22 ---------------------- 1 file changed, 22 deletions(-) diff --git a/generic/tclStubInit.c b/generic/tclStubInit.c index 5df72be..be37bc0 100644 --- a/generic/tclStubInit.c +++ b/generic/tclStubInit.c @@ -265,28 +265,6 @@ Tcl_WinTCharToUtf( * signature. Tcl 9 must find a better solution, but that cannot be done * without introducing a binary incompatibility. */ -#define Tcl_DbNewLongObj ((Tcl_Obj*(*)(long,const char*,int))dbNewLongObj) -static Tcl_Obj *dbNewLongObj( - int intValue, - const char *file, - int line -) { -#ifdef TCL_MEM_DEBUG - register Tcl_Obj *objPtr; - - TclDbNewObj(objPtr, file, line); - objPtr->bytes = NULL; - - objPtr->internalRep.wideValue = (long) intValue; - objPtr->typePtr = &tclIntType; - return objPtr; -#else - return Tcl_NewIntObj(intValue); -#endif -} -#define Tcl_GetLongFromObj (int(*)(Tcl_Interp*,Tcl_Obj*,long*))Tcl_GetIntFromObj -#define Tcl_NewLongObj (Tcl_Obj*(*)(long))Tcl_NewIntObj -#define Tcl_SetLongObj (void(*)(Tcl_Obj*,long))Tcl_SetIntObj static int exprInt(Tcl_Interp *interp, const char *expr, int *ptr){ long longValue; int result = Tcl_ExprLong(interp, expr, &longValue); -- cgit v0.12 From 220d2d7d9c2c61b1c319685a76e410fc3024facf Mon Sep 17 00:00:00 2001 From: "jan.nijtmans" Date: Mon, 26 Mar 2018 20:21:00 +0000 Subject: Remove MINGW32 from the UNIX makefile, since Mingw should always build from the "win" directory. Better to avoid confusion. --- unix/configure | 4 ++-- unix/tcl.m4 | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/unix/configure b/unix/configure index afc6842..36bc4b9 100755 --- a/unix/configure +++ b/unix/configure @@ -5189,7 +5189,7 @@ fi CC_SEARCH_FLAGS="" LD_SEARCH_FLAGS="" ;; - CYGWIN_*|MINGW32*) + CYGWIN_*) SHLIB_CFLAGS="" SHLIB_LD='${CC} -shared' SHLIB_SUFFIX=".dll" @@ -6464,7 +6464,7 @@ fi case $system in AIX-*) ;; BSD/OS*) ;; - CYGWIN_*|MINGW32_*) ;; + CYGWIN_*) ;; IRIX*) ;; NetBSD-*|FreeBSD-*|OpenBSD-*) ;; Darwin-*) ;; diff --git a/unix/tcl.m4 b/unix/tcl.m4 index a6abef1..4acbed0 100644 --- a/unix/tcl.m4 +++ b/unix/tcl.m4 @@ -1196,7 +1196,7 @@ AC_DEFUN([SC_CONFIG_CFLAGS], [ CC_SEARCH_FLAGS="" LD_SEARCH_FLAGS="" ;; - CYGWIN_*|MINGW32*) + CYGWIN_*) SHLIB_CFLAGS="" SHLIB_LD='${CC} -shared' SHLIB_SUFFIX=".dll" @@ -1912,7 +1912,7 @@ dnl # preprocessing tests use only CPPFLAGS. case $system in AIX-*) ;; BSD/OS*) ;; - CYGWIN_*|MINGW32_*) ;; + CYGWIN_*) ;; IRIX*) ;; NetBSD-*|FreeBSD-*|OpenBSD-*) ;; Darwin-*) ;; -- cgit v0.12 From 0ad3b13e2663019e4ff8d3dc944fd030e33eb358 Mon Sep 17 00:00:00 2001 From: dgp Date: Thu, 5 Apr 2018 13:34:58 +0000 Subject: Failed to mutex protect all multi-thread access to the hash tables in the [tcl::process] implementation. This was causing segfaults in thread-8.1. --- generic/tclProcess.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/generic/tclProcess.c b/generic/tclProcess.c index 7187ee4..604b7ce 100644 --- a/generic/tclProcess.c +++ b/generic/tclProcess.c @@ -887,6 +887,7 @@ TclProcessWait( * First search for pid in table. */ + Tcl_MutexLock(&infoTablesMutex); entry = Tcl_FindHashEntry(&infoTablePerPid, pid); if (!entry) { /* @@ -897,6 +898,7 @@ TclProcessWait( msgObjPtr, errorObjPtr); if (msgObjPtr && *msgObjPtr) Tcl_IncrRefCount(*msgObjPtr); if (errorObjPtr && *errorObjPtr) Tcl_IncrRefCount(*errorObjPtr); + Tcl_MutexUnlock(&infoTablesMutex); return result; } @@ -906,6 +908,7 @@ TclProcessWait( * Process has completed but TclProcessWait has already been called, * so report no change. */ + Tcl_MutexUnlock(&infoTablesMutex); return TCL_PROCESS_UNCHANGED; } @@ -915,6 +918,7 @@ TclProcessWait( /* * No change, stop there. */ + Tcl_MutexUnlock(&infoTablesMutex); return TCL_PROCESS_UNCHANGED; } @@ -948,5 +952,6 @@ TclProcessWait( info->purge = 1; } + Tcl_MutexUnlock(&infoTablesMutex); return result; } -- cgit v0.12 From eb8817687f0753816e8308b93b3e992414afeca4 Mon Sep 17 00:00:00 2001 From: dgp Date: Thu, 5 Apr 2018 15:37:40 +0000 Subject: [string cat] was failing to NUL terminate string reps. Stopped "string" values triggering false valgrind alarms when tests make use of [tcl::unsupported::representation]. --- generic/tclStringObj.c | 2 ++ generic/tclStringRep.h | 1 + 2 files changed, 3 insertions(+) diff --git a/generic/tclStringObj.c b/generic/tclStringObj.c index 2ebec64..a2a1d41 100644 --- a/generic/tclStringObj.c +++ b/generic/tclStringObj.c @@ -3205,6 +3205,8 @@ TclStringCat( dst += more; } } + /* Must NUL-terminate! */ + *dst = '\0'; } return objResultPtr; diff --git a/generic/tclStringRep.h b/generic/tclStringRep.h index 1ef1957..fc5a713 100644 --- a/generic/tclStringRep.h +++ b/generic/tclStringRep.h @@ -86,6 +86,7 @@ typedef struct { #define GET_STRING(objPtr) \ ((String *) (objPtr)->internalRep.twoPtrValue.ptr1) #define SET_STRING(objPtr, stringPtr) \ + ((objPtr)->internalRep.twoPtrValue.ptr2 = NULL), \ ((objPtr)->internalRep.twoPtrValue.ptr1 = (void *) (stringPtr)) /* -- cgit v0.12 From 43507f353b82f414fff3810cc0d781a44e7ae3e9 Mon Sep 17 00:00:00 2001 From: dgp Date: Thu, 5 Apr 2018 16:37:35 +0000 Subject: Plug memleak when [scan] raises an error. --- generic/tclScan.c | 19 ++++++++++++++++--- 1 file changed, 16 insertions(+), 3 deletions(-) diff --git a/generic/tclScan.c b/generic/tclScan.c index 113b4c6..0e3da17 100644 --- a/generic/tclScan.c +++ b/generic/tclScan.c @@ -941,11 +941,24 @@ Tcl_ScanObjCmd( } else if (flags & SCAN_BIG) { if (flags & SCAN_UNSIGNED) { mp_int big; - if ((Tcl_GetBignumFromObj(interp, objPtr, &big) != TCL_OK) - || mp_isneg(&big)) { + int code = Tcl_GetBignumFromObj(interp, objPtr, &big); + + if (code == TCL_OK) { + if (mp_isneg(&big)) { + code = TCL_ERROR; + } + mp_clear(&big); + } + + if (code == TCL_ERROR) { + if (objs != NULL) { + ckfree(objs); + } + Tcl_DecrRefCount(objPtr); Tcl_SetObjResult(interp, Tcl_NewStringObj( "unsigned bignum scans are invalid", -1)); - Tcl_SetErrorCode(interp, "TCL", "FORMAT", "BADUNSIGNED",NULL); + Tcl_SetErrorCode(interp, "TCL", "FORMAT", + "BADUNSIGNED",NULL); return TCL_ERROR; } } -- cgit v0.12 From 634c443219ba3420c6a3403b7c1565076d86dbae Mon Sep 17 00:00:00 2001 From: dgp Date: Thu, 5 Apr 2018 17:22:09 +0000 Subject: Plug memleak in [format] applied to bignums. --- generic/tclStringObj.c | 1 + 1 file changed, 1 insertion(+) diff --git a/generic/tclStringObj.c b/generic/tclStringObj.c index a2a1d41..fa50d6d 100644 --- a/generic/tclStringObj.c +++ b/generic/tclStringObj.c @@ -1972,6 +1972,7 @@ Tcl_AppendFormatToObj( if (cmpResult == MP_EQ) gotHash = 0; if (ch == 'u') { if (isNegative) { + mp_clear(&big); msg = "unsigned bignum format is invalid"; errCode = "BADUNSIGNED"; goto errorMsg; -- cgit v0.12