/hl/tools/testfiles/

ket based channel, or a list of diff --git a/win/tclWinSock.c b/win/tclWinSock.c index f343f82..2703309 100644 --- a/win/tclWinSock.c +++ b/win/tclWinSock.c @@ -191,6 +191,9 @@ struct TcpState { * flag indicates that reentry is * still pending */ #define TCP_ASYNC_FAILED (1<<5) /* An async connect finally failed */ +#define TCP_ASYNC_TEST_MODE (1<<6) /* Async testing activated + * Do not automatically continue connection + * process */ /* * The following structure is what is added to the Tcl event queue when a @@ -602,6 +605,20 @@ WaitForConnect( } /* + * In socket test mode do not continue with the connect + * Exceptions are: + * - Call by recv/send and blocking socket + * (errorCodePtr != NULL && ! flags & TCP_NONBLOCKING) + * - Call by the event queue (errorCodePtr == NULL) + */ + + if ( (statePtr->flags & TCP_ASYNC_TEST_MODE) + && errorCodePtr != NULL && (statePtr->flags & TCP_NONBLOCKING)) { + *errorCodePtr = EWOULDBLOCK; + return -1; + } + + /* * Be sure to disable event servicing so we are truly modal. */ @@ -1123,6 +1140,7 @@ TcpSetOptionProc( const char *optionName, /* Name of the option to set. */ const char *value) /* New value for option. */ { + TcpState *statePtr = instanceData; #ifdef TCL_FEATURE_KEEPALIVE_NAGLE TcpState *statePtr = instanceData; SOCKET sock; @@ -1142,6 +1160,22 @@ TcpSetOptionProc( return TCL_ERROR; } + /* + * Set socket test int value + */ + if (!strcmp(optionName, "-unsupported1")) { + int intValue; + if (Tcl_GetInt(interp, value, &intValue) != TCL_OK) { + return TCL_ERROR; + } + if (intValue & 1) { + SET_BITS(statePtr->flags,TCP_ASYNC_TEST_MODE); + } else { + CLEAR_BITS(statePtr->flags,TCP_ASYNC_TEST_MODE); + } + return TCL_OK; + } + #ifdef TCL_FEATURE_KEEPALIVE_NAGLE #error "TCL_FEATURE_KEEPALIVE_NAGLE not reviewed for whether to treat statePtr->sockets as single fd or list" sock = statePtr->sockets->fd; @@ -1254,7 +1288,9 @@ TcpGetOptionProc( * Go one step in async connect * If any error is thrown save it as backround error to report eventually below */ - WaitForConnect(statePtr, NULL); + if (! (statePtr->flags & TCP_ASYNC_TEST_MODE) ) { + WaitForConnect(statePtr, NULL); + } sock = statePtr->sockets->fd; if (optionName != NULL) { -- cgit v0.12 From a0256cda63dc8d023a3cd11a73c2cf15c164dfb9 Mon Sep 17 00:00:00 2001 From: oehhar Date: Thu, 17 Jul 2014 09:53:36 +0000 Subject: Replaced option "-unsupported1" by test command "testsocket debugflags" (thanks Donal, Donald). --- generic/tclTest.c | 85 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ tests/socket.test | 15 ++++++---- unix/tclUnixSock.c | 67 +++++++++--------------------------------- win/tclWinSock.c | 31 +++++++------------- 4 files changed, 118 insertions(+), 80 deletions(-) diff --git a/generic/tclTest.c b/generic/tclTest.c index a27c95a..80a2a37 100644 --- a/generic/tclTest.c +++ b/generic/tclTest.c @@ -75,6 +75,18 @@ typedef struct TestAsyncHandler { /* Next is list of handlers. */ } TestAsyncHandler; +/* + * Start of the socket driver state structure to acces field testFlags + */ + +typedef struct TcpState TcpState; + +struct TcpState { + Tcl_Channel channel; /* Channel associated with this socket. */ + int testFlags; /* bit field for tests. Is set by testsocket + * test procedure */ +}; + TCL_DECLARE_MUTEX(asyncTestMutex) static TestAsyncHandler *firstHandler = NULL; @@ -362,6 +374,8 @@ static int TestChannelCmd(ClientData clientData, Tcl_Interp *interp, int argc, const char **argv); static int TestChannelEventCmd(ClientData clientData, Tcl_Interp *interp, int argc, const char **argv); +static int TestSocketCmd(ClientData clientData, + Tcl_Interp *interp, int argc, const char **argv); static int TestFilesystemObjCmd(ClientData dummy, Tcl_Interp *interp, int objc, Tcl_Obj *const objv[]); @@ -666,6 +680,8 @@ Tcltest_Init( TestNumUtfCharsCmd, NULL, NULL); Tcl_CreateCommand(interp, "testsetplatform", TestsetplatformCmd, NULL, NULL); + Tcl_CreateCommand(interp, "testsocket", TestSocketCmd, + NULL, NULL); Tcl_CreateCommand(interp, "teststaticpkg", TeststaticpkgCmd, NULL, NULL); Tcl_CreateCommand(interp, "testtranslatefilename", @@ -5970,6 +5986,75 @@ TestChannelEventCmd( /* *---------------------------------------------------------------------- * + * TestSocketCmd -- + * + * Implements the Tcl "testsocket" debugging command and its + * subcommands. This is part of the testing environment. + * + * Results: + * A standard Tcl result. + * + * Side effects: + * None. + * + *---------------------------------------------------------------------- + */ + + /* ARGSUSED */ +static int +TestSocketCmd( + ClientData clientData, /* Not used. */ + Tcl_Interp *interp, /* Interpreter for result. */ + int argc, /* Count of additional args. */ + const char **argv) /* Additional arg strings. */ +{ + const char *cmdName; /* Sub command. */ + size_t len; /* Length of subcommand string. */ + + if (argc < 2) { + Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0], + " subcommand ?additional args..?\"", NULL); + return TCL_ERROR; + } + cmdName = argv[1]; + len = strlen(cmdName); + + if ((cmdName[0] == 't') && (strncmp(cmdName, "testflags", len) == 0)) { + Tcl_Channel hChannel; + int modePtr; + TcpState *statePtr; + /* Set test value in the socket driver + */ + /* Check for argument "channel name" + */ + if (argc < 4) { + Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0], + " testflags channel flags\"", NULL); + return TCL_ERROR; + } + hChannel = Tcl_GetChannel(interp, argv[2], &modePtr); + if ( NULL == hChannel ) { + Tcl_AppendResult(interp, "unknown channel:", argv[2], NULL); + return TCL_ERROR; + } + statePtr = (TcpState *)Tcl_GetChannelInstanceData(hChannel); + if ( NULL == statePtr) { + Tcl_AppendResult(interp, "No channel instance data:", argv[2], + NULL); + return TCL_ERROR; + } + statePtr->testFlags = atoi(argv[3]); + return TCL_OK; + } + + Tcl_AppendResult(interp, "bad option \"", cmdName, "\": should be " + "testflags", NULL); + return TCL_ERROR; +} + +/* + *---------------------------------------------------------------------- + * * TestWrongNumArgsObjCmd -- * * Test the Tcl_WrongNumArgs function. diff --git a/tests/socket.test b/tests/socket.test index b006cb4..839e9d2 100644 --- a/tests/socket.test +++ b/tests/socket.test @@ -72,10 +72,10 @@ testConstraint exec [llength [info commands exec]] # from 49152 through 65535. proc randport {} { expr {int(rand()*16383+49152)} } -# Check if socket_test option is available -testConstraint sockettest [expr {![catch { +# Check if testsocket testflags is available +testConstraint testsocket_testflags [expr {![catch { set h [socket -async localhost [randport]] - fconfigure $h -unsupported1 1 + testsocket testflags $h 0 close $h }]}] @@ -2170,14 +2170,17 @@ test socket-14.11.0 {pending [socket -async] and nonblocking [puts], no listener unset x } -result {socket is not connected} -returnCodes 1 test socket-14.11.1 {pending [socket -async] and nonblocking [puts], no listener, flush} \ - -constraints {socket sockettest} \ + -constraints {socket testsocket_testflags} \ -body { set sock [socket -async localhost [randport]] - fconfigure $sock -unsupported1 1 + # Set the socket in async test mode. + # The async connect will not be continued on the following fconfigure + # and puts/flush. Thus, the connect will fail after them. + testsocket testflags $sock 1 fconfigure $sock -blocking 0 puts $sock ok flush $sock - fconfigure $sock -unsupported1 0 + testsocket testflags $sock 0 fileevent $sock writable {set x 1} vwait x close $sock diff --git a/unix/tclUnixSock.c b/unix/tclUnixSock.c index cf5d7b9..fdd4287 100644 --- a/unix/tclUnixSock.c +++ b/unix/tclUnixSock.c @@ -52,6 +52,8 @@ typedef struct TcpFdList { struct TcpState { Tcl_Channel channel; /* Channel associated with this file. */ + int testFlags; /* bit field for tests. Is set by testsocket + * test procedure */ TcpFdList fds; /* The file descriptors of the sockets. */ int flags; /* ORed combination of the bitfields defined * below. */ @@ -89,7 +91,13 @@ struct TcpState { * flag indicates that reentry is * still pending */ #define TCP_ASYNC_FAILED (1<<5) /* An async connect finally failed */ -#define TCP_ASYNC_TEST_MODE (1<<6) /* Async testing activated + +/* + * These bits may be ORed together into the "testFlags" field of a TcpState + * structure. + */ + +#define TCP_ASYNC_TEST_MODE (1<<0) /* Async testing activated * Do not automatically continue connection * process */ @@ -128,9 +136,6 @@ static int TcpClose2Proc(ClientData instanceData, Tcl_Interp *interp, int flags); static int TcpGetHandleProc(ClientData instanceData, int direction, ClientData *handlePtr); -static int TcpSetOptionProc(ClientData instanceData, - Tcl_Interp *interp, const char *optionName, - const char *value); static int TcpGetOptionProc(ClientData instanceData, Tcl_Interp *interp, const char *optionName, Tcl_DString *dsPtr); @@ -153,7 +158,7 @@ static const Tcl_ChannelType tcpChannelType = { TcpInputProc, /* Input proc. */ TcpOutputProc, /* Output proc. */ NULL, /* Seek proc. */ - TcpSetOptionProc, /* Set option proc. */ + NULL, /* Set option proc. */ TcpGetOptionProc, /* Get option proc. */ TcpWatchProc, /* Initialize notifier. */ TcpGetHandleProc, /* Get OS handles out of channel. */ @@ -453,11 +458,9 @@ WaitForConnect( * (errorCodePtr != NULL && ! flags & TCP_NONBLOCKING) */ - if ( (statePtr->flags & TCP_ASYNC_TEST_MODE) - && !(errorCodePtr != NULL && !(statePtr->flags & TCP_NONBLOCKING))) { - if (errorCodePtr != NULL) { - *errorCodePtr = EWOULDBLOCK; - } + if ( (statePtr->testFlags & TCP_ASYNC_TEST_MODE) + && ! (errorCodePtr != NULL && ! (statePtr->flags & TCP_NONBLOCKING))) { + *errorCodePtr = EWOULDBLOCK; return -1; } @@ -769,50 +772,6 @@ TcpHostPortList( /* *---------------------------------------------------------------------- * - * TcpSetOptionProc -- - * - * Sets Tcp channel specific options. - * - * Results: - * None, unless an error happens. - * - * Side effects: - * Changes attributes of the socket at the system level. - * - *---------------------------------------------------------------------- - */ - -static int -TcpSetOptionProc( - ClientData instanceData, /* Socket state. */ - Tcl_Interp *interp, /* For error reporting - can be NULL. */ - const char *optionName, /* Name of the option to set. */ - const char *value) /* New value for option. */ -{ - TcpState *statePtr = instanceData; - - /* - * Set socket test int value - */ - if (!strcmp(optionName, "-unsupported1")) { - int intValue; - if (Tcl_GetInt(interp, value, &intValue) != TCL_OK) { - return TCL_ERROR; - } - if (intValue & 1) { - SET_BITS(statePtr->flags,TCP_ASYNC_TEST_MODE); - } else { - CLEAR_BITS(statePtr->flags,TCP_ASYNC_TEST_MODE); - } - return TCL_OK; - } - - return Tcl_BadChannelOption(interp, optionName, ""); -} - -/* - *---------------------------------------------------------------------- - * * TcpGetOptionProc -- * * Computes an option value for a TCP socket based channel, or a list of diff --git a/win/tclWinSock.c b/win/tclWinSock.c index 2703309..d6c8e3a 100644 --- a/win/tclWinSock.c +++ b/win/tclWinSock.c @@ -133,6 +133,8 @@ typedef struct TcpFdList { struct TcpState { Tcl_Channel channel; /* Channel associated with this socket. */ + int testFlags; /* bit field for tests. Is set by testsocket + * test procedure */ struct TcpFdList *sockets; /* Windows SOCKET handle. */ int flags; /* Bit field comprised of the flags described * below. */ @@ -191,7 +193,13 @@ struct TcpState { * flag indicates that reentry is * still pending */ #define TCP_ASYNC_FAILED (1<<5) /* An async connect finally failed */ -#define TCP_ASYNC_TEST_MODE (1<<6) /* Async testing activated + +/* + * These bits may be ORed together into the "testFlags" field of a TcpState + * structure. + */ + +#define TCP_ASYNC_TEST_MODE (1<<0) /* Async testing activated * Do not automatically continue connection * process */ @@ -612,7 +620,7 @@ WaitForConnect( * - Call by the event queue (errorCodePtr == NULL) */ - if ( (statePtr->flags & TCP_ASYNC_TEST_MODE) + if ( (statePtr->testFlags & TCP_ASYNC_TEST_MODE) && errorCodePtr != NULL && (statePtr->flags & TCP_NONBLOCKING)) { *errorCodePtr = EWOULDBLOCK; return -1; @@ -1140,7 +1148,6 @@ TcpSetOptionProc( const char *optionName, /* Name of the option to set. */ const char *value) /* New value for option. */ { - TcpState *statePtr = instanceData; #ifdef TCL_FEATURE_KEEPALIVE_NAGLE TcpState *statePtr = instanceData; SOCKET sock; @@ -1160,22 +1167,6 @@ TcpSetOptionProc( return TCL_ERROR; } - /* - * Set socket test int value - */ - if (!strcmp(optionName, "-unsupported1")) { - int intValue; - if (Tcl_GetInt(interp, value, &intValue) != TCL_OK) { - return TCL_ERROR; - } - if (intValue & 1) { - SET_BITS(statePtr->flags,TCP_ASYNC_TEST_MODE); - } else { - CLEAR_BITS(statePtr->flags,TCP_ASYNC_TEST_MODE); - } - return TCL_OK; - } - #ifdef TCL_FEATURE_KEEPALIVE_NAGLE #error "TCL_FEATURE_KEEPALIVE_NAGLE not reviewed for whether to treat statePtr->sockets as single fd or list" sock = statePtr->sockets->fd; @@ -1288,7 +1279,7 @@ TcpGetOptionProc( * Go one step in async connect * If any error is thrown save it as backround error to report eventually below */ - if (! (statePtr->flags & TCP_ASYNC_TEST_MODE) ) { + if (! (statePtr->testFlags & TCP_ASYNC_TEST_MODE) ) { WaitForConnect(statePtr, NULL); } -- cgit v0.12 From da7cc28446f80fb4051f898b794d7e0f6c847c43 Mon Sep 17 00:00:00 2001 From: "jan.nijtmans" Date: Fri, 18 Jul 2014 10:00:52 +0000 Subject: Make sure the "sockettest" command is available even when running socket.test individually. --- tests/socket.test | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/tests/socket.test b/tests/socket.test index 8ffd86b..29f1015 100644 --- a/tests/socket.test +++ b/tests/socket.test @@ -60,8 +60,13 @@ # listening at port 2048. If all fails, a message is printed and the tests # using the remote server are not performed. -package require tcltest 2 -namespace import -force ::tcltest::* +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 Thread package or exec command testConstraint thread [expr {0 == [catch {package require Thread 2.7-}]}] -- cgit v0.12 From ee70b22d5958a32d40ebf81b0679d0982b4d1860 Mon Sep 17 00:00:00 2001 From: "jan.nijtmans" Date: Tue, 22 Nov 2016 10:06:18 +0000 Subject: This is patch.002 from ticket [0b9d3ba2ba3e1e3fc33c97d5a9fa7ef85d11a696|0b9d3ba2ba], as first start of tip-456 implementation --- generic/tclIOCmd.c | 15 ++++++++++++--- unix/tclUnixSock.c | 20 ++++++++++++++++++++ win/tclWinSock.c | 4 ++-- 3 files changed, 34 insertions(+), 5 deletions(-) diff --git a/generic/tclIOCmd.c b/generic/tclIOCmd.c index de65da5..9dc8f07 100644 --- a/generic/tclIOCmd.c +++ b/generic/tclIOCmd.c @@ -1485,12 +1485,12 @@ Tcl_SocketObjCmd( Tcl_Obj *const objv[]) /* Argument objects. */ { static const char *const socketOptions[] = { - "-async", "-myaddr", "-myport", "-server", NULL + "-async", "-myaddr", "-myport", "-server", "-reuseport", NULL }; enum socketOptions { - SKT_ASYNC, SKT_MYADDR, SKT_MYPORT, SKT_SERVER + SKT_ASYNC, SKT_MYADDR, SKT_MYPORT, SKT_SERVER, SKT_REUSEPORT }; - int optionIndex, a, server = 0, port, myport = 0, async = 0; + int optionIndex, a, server = 0, port, myport = 0, async = 0, reuseport = 0; const char *host, *myaddr = NULL; Tcl_Obj *script = NULL; Tcl_Channel chan; @@ -1557,6 +1557,9 @@ Tcl_SocketObjCmd( } script = objv[a]; break; + case SKT_REUSEPORT: + reuseport = 1; + break; default: Tcl_Panic("Tcl_SocketObjCmd: bad option index to SocketOptions"); } @@ -1600,6 +1603,12 @@ Tcl_SocketObjCmd( Tcl_IncrRefCount(script); acceptCallbackPtr->script = script; acceptCallbackPtr->interp = interp; + + /* Hint for Tcl_OpenTcpServer to set socket option REUSEPORT */ + if(reuseport) { + port |= (1 << 16); + } + chan = Tcl_OpenTcpServer(interp, port, host, AcceptCallbackProc, acceptCallbackPtr); if (chan == NULL) { diff --git a/unix/tclUnixSock.c b/unix/tclUnixSock.c index 170aea9..d8a33f9 100644 --- a/unix/tclUnixSock.c +++ b/unix/tclUnixSock.c @@ -113,6 +113,11 @@ struct TcpState { #define SOCKET_BUFSIZE 4096 +#ifdef SO_REUSEPORT +/* Bitmask to check if the setting of SO_REUSEPORT was requested by the caller. */ +#define USE_SOCK_REUSEPORT (1 << 16) +#endif + /* * Static routines for this file: */ @@ -1435,6 +1440,10 @@ Tcl_OpenTcpServer( char channelName[SOCK_CHAN_LENGTH]; const char *errorMsg = NULL; TcpFdList *fds = NULL, *newfds; +#ifdef SO_REUSEPORT + int reuseport = port & USE_SOCK_REUSEPORT; + CLEAR_BITS(port, USE_SOCK_REUSEPORT); +#endif /* * Try to record and return the most meaningful error message, i.e. the @@ -1512,6 +1521,17 @@ Tcl_OpenTcpServer( (void) setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, (char *) &reuseaddr, sizeof(reuseaddr)); +#ifdef SO_REUSEPORT + /* + * Set up to allows multiple sockets on the same host to bind to the same port. + * The flag can be switched on by setting the lowest bit above the valid maximum port (0xffff). + */ + if(reuseport) { + (void) setsockopt(sock, SOL_SOCKET, SO_REUSEPORT, + (char *) &reuseport, sizeof(reuseport)); + } +#endif + /* * Make sure we use the same port number when opening two server * sockets for IPv4 and IPv6 on a random port. diff --git a/win/tclWinSock.c b/win/tclWinSock.c index ec881d2..af8dda1 100644 --- a/win/tclWinSock.c +++ b/win/tclWinSock.c @@ -2111,8 +2111,8 @@ Tcl_OpenTcpServer( /* * Bind to the specified port. Note that we must not call - * setsockopt with SO_REUSEADDR because Microsoft allows addresses - * to be reused even if they are still in use. + * setsockopt with SO_REUSEADDR or SO_REUSEPORT because Microsoft + * allows addresses and ports to be reused even if they are still in use. * * Bind should not be affected by the socket having already been * set into nonblocking mode. If there is trouble, this is one -- cgit v0.12 From 6989a199e7390fd525b1b42b4a2afba1e5964252 Mon Sep 17 00:00:00 2001 From: "jan.nijtmans" Date: Tue, 22 Nov 2016 11:21:00 +0000 Subject: Added stub entry for tip #456. Documentation and tests still missing. Doesn't conform to TIP yet. --- generic/tcl.decls | 11 +++++++++++ generic/tclDecls.h | 8 ++++++++ generic/tclIOCmd.c | 15 +++++---------- generic/tclIOSock.c | 24 ++++++++++++++++++++++++ generic/tclStubInit.c | 1 + unix/tclUnixSock.c | 14 ++++++-------- win/tclWinSock.c | 5 +++-- 7 files changed, 58 insertions(+), 20 deletions(-) diff --git a/generic/tcl.decls b/generic/tcl.decls index 574b49b..20c3f3e 100644 --- a/generic/tcl.decls +++ b/generic/tcl.decls @@ -2326,6 +2326,17 @@ declare 630 { # ----- BASELINE -- FOR -- 8.6.0 ----- # +# TIP #456 +declare 631 { + Tcl_Channel Tcl_OpenTcpServerEx(Tcl_Interp *interp, int port, + const char *host, int flags, Tcl_TcpAcceptProc *acceptProc, + ClientData callbackData) +} + +# ----- BASELINE -- FOR -- 8.7.0 ----- # + + + ############################################################################## # Define the platform specific public Tcl interface. These functions are only diff --git a/generic/tclDecls.h b/generic/tclDecls.h index b022d3c..d1c1170 100644 --- a/generic/tclDecls.h +++ b/generic/tclDecls.h @@ -1816,6 +1816,11 @@ EXTERN int Tcl_FSUnloadFile(Tcl_Interp *interp, EXTERN void Tcl_ZlibStreamSetCompressionDictionary( Tcl_ZlibStream zhandle, Tcl_Obj *compressionDictionaryObj); +/* 631 */ +EXTERN Tcl_Channel Tcl_OpenTcpServerEx(Tcl_Interp *interp, int port, + const char *host, int flags, + Tcl_TcpAcceptProc *acceptProc, + ClientData callbackData); typedef struct { const struct TclPlatStubs *tclPlatStubs; @@ -2482,6 +2487,7 @@ typedef struct TclStubs { void * (*tcl_FindSymbol) (Tcl_Interp *interp, Tcl_LoadHandle handle, const char *symbol); /* 628 */ int (*tcl_FSUnloadFile) (Tcl_Interp *interp, Tcl_LoadHandle handlePtr); /* 629 */ void (*tcl_ZlibStreamSetCompressionDictionary) (Tcl_ZlibStream zhandle, Tcl_Obj *compressionDictionaryObj); /* 630 */ + Tcl_Channel (*tcl_OpenTcpServerEx) (Tcl_Interp *interp, int port, const char *host, int flags, Tcl_TcpAcceptProc *acceptProc, ClientData callbackData); /* 631 */ } TclStubs; extern const TclStubs *tclStubsPtr; @@ -3774,6 +3780,8 @@ extern const TclStubs *tclStubsPtr; (tclStubsPtr->tcl_FSUnloadFile) /* 629 */ #define Tcl_ZlibStreamSetCompressionDictionary \ (tclStubsPtr->tcl_ZlibStreamSetCompressionDictionary) /* 630 */ +#define Tcl_OpenTcpServerEx \ + (tclStubsPtr->tcl_OpenTcpServerEx) /* 631 */ #endif /* defined(USE_TCL_STUBS) */ diff --git a/generic/tclIOCmd.c b/generic/tclIOCmd.c index 9dc8f07..883c6b7 100644 --- a/generic/tclIOCmd.c +++ b/generic/tclIOCmd.c @@ -1490,7 +1490,7 @@ Tcl_SocketObjCmd( enum socketOptions { SKT_ASYNC, SKT_MYADDR, SKT_MYPORT, SKT_SERVER, SKT_REUSEPORT }; - int optionIndex, a, server = 0, port, myport = 0, async = 0, reuseport = 0; + int optionIndex, a, server = 0, port, myport = 0, async = 0, flags = 0; const char *host, *myaddr = NULL; Tcl_Obj *script = NULL; Tcl_Channel chan; @@ -1557,9 +1557,9 @@ Tcl_SocketObjCmd( } script = objv[a]; break; - case SKT_REUSEPORT: - reuseport = 1; - break; + case SKT_REUSEPORT: + flags |= 1; + break; default: Tcl_Panic("Tcl_SocketObjCmd: bad option index to SocketOptions"); } @@ -1604,12 +1604,7 @@ Tcl_SocketObjCmd( acceptCallbackPtr->script = script; acceptCallbackPtr->interp = interp; - /* Hint for Tcl_OpenTcpServer to set socket option REUSEPORT */ - if(reuseport) { - port |= (1 << 16); - } - - chan = Tcl_OpenTcpServer(interp, port, host, AcceptCallbackProc, + chan = Tcl_OpenTcpServerEx(interp, port, host, flags, AcceptCallbackProc, acceptCallbackPtr); if (chan == NULL) { Tcl_DecrRefCount(script); diff --git a/generic/tclIOSock.c b/generic/tclIOSock.c index 7ed751c..72a0b5a 100644 --- a/generic/tclIOSock.c +++ b/generic/tclIOSock.c @@ -283,6 +283,30 @@ TclCreateSocketAddress( } return 1; } + +/* + *---------------------------------------------------------------------- + * + * Tcl_OpenTcpServer -- + * + * Opens a TCP server socket and creates a channel around it. + * + * Results: + * The channel or NULL if failed. If an error occurred, an error message + * is left in the interp's result if interp is not NULL. + * + * Side effects: + * Opens a server socket and creates a new channel. + * + *---------------------------------------------------------------------- + */ +Tcl_Channel Tcl_OpenTcpServer(Tcl_Interp *interp, int port, + const char *host, Tcl_TcpAcceptProc *acceptProc, + ClientData callbackData) +{ + return Tcl_OpenTcpServerEx(interp, port, host, 0, acceptProc, callbackData); +} + /* * Local Variables: diff --git a/generic/tclStubInit.c b/generic/tclStubInit.c index 2f1bb8b..23da6dc 100644 --- a/generic/tclStubInit.c +++ b/generic/tclStubInit.c @@ -1416,6 +1416,7 @@ const TclStubs tclStubs = { Tcl_FindSymbol, /* 628 */ Tcl_FSUnloadFile, /* 629 */ Tcl_ZlibStreamSetCompressionDictionary, /* 630 */ + Tcl_OpenTcpServerEx, /* 631 */ }; /* !END!: Do not edit above this line. */ diff --git a/unix/tclUnixSock.c b/unix/tclUnixSock.c index d8a33f9..6286b2f 100644 --- a/unix/tclUnixSock.c +++ b/unix/tclUnixSock.c @@ -115,7 +115,7 @@ struct TcpState { #ifdef SO_REUSEPORT /* Bitmask to check if the setting of SO_REUSEPORT was requested by the caller. */ -#define USE_SOCK_REUSEPORT (1 << 16) +#define USE_SOCK_REUSEPORT 1 #endif /* @@ -1410,7 +1410,7 @@ TclpMakeTcpClientChannelMode( /* *---------------------------------------------------------------------- * - * Tcl_OpenTcpServer -- + * Tcl_OpenTcpServerEx -- * * Opens a TCP server socket and creates a channel around it. * @@ -1425,10 +1425,11 @@ TclpMakeTcpClientChannelMode( */ Tcl_Channel -Tcl_OpenTcpServer( +Tcl_OpenTcpServerEx( Tcl_Interp *interp, /* For error reporting - may be NULL. */ int port, /* Port number to open. */ const char *myHost, /* Name of local host. */ + int flags, /* Flags. */ Tcl_TcpAcceptProc *acceptProc, /* Callback for accepting connections from new * clients. */ @@ -1440,10 +1441,6 @@ Tcl_OpenTcpServer( char channelName[SOCK_CHAN_LENGTH]; const char *errorMsg = NULL; TcpFdList *fds = NULL, *newfds; -#ifdef SO_REUSEPORT - int reuseport = port & USE_SOCK_REUSEPORT; - CLEAR_BITS(port, USE_SOCK_REUSEPORT); -#endif /* * Try to record and return the most meaningful error message, i.e. the @@ -1526,7 +1523,8 @@ Tcl_OpenTcpServer( * Set up to allows multiple sockets on the same host to bind to the same port. * The flag can be switched on by setting the lowest bit above the valid maximum port (0xffff). */ - if(reuseport) { + if (flags & USE_SOCK_REUSEPORT) { + int reuseport = 1; (void) setsockopt(sock, SOL_SOCKET, SO_REUSEPORT, (char *) &reuseport, sizeof(reuseport)); } diff --git a/win/tclWinSock.c b/win/tclWinSock.c index af8dda1..a389d45 100644 --- a/win/tclWinSock.c +++ b/win/tclWinSock.c @@ -2020,7 +2020,7 @@ Tcl_MakeTcpClientChannel( /* *---------------------------------------------------------------------- * - * Tcl_OpenTcpServer -- + * Tcl_OpenTcpServerEx -- * * Opens a TCP server socket and creates a channel around it. * @@ -2035,10 +2035,11 @@ Tcl_MakeTcpClientChannel( */ Tcl_Channel -Tcl_OpenTcpServer( +Tcl_OpenTcpServerEx( Tcl_Interp *interp, /* For error reporting - may be NULL. */ int port, /* Port number to open. */ const char *myHost, /* Name of local host. */ + int flags, /* Flags (not used) */ Tcl_TcpAcceptProc *acceptProc, /* Callback for accepting connections from new * clients. */ -- cgit v0.12 From 32f810fc3b6dc0ff270d295e623bacb4d766522c Mon Sep 17 00:00:00 2001 From: "jan.nijtmans" Date: Tue, 22 Nov 2016 11:24:48 +0000 Subject: Fix indenting --- unix/tclUnixSock.c | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/unix/tclUnixSock.c b/unix/tclUnixSock.c index 6286b2f..4767522 100644 --- a/unix/tclUnixSock.c +++ b/unix/tclUnixSock.c @@ -1519,15 +1519,15 @@ Tcl_OpenTcpServerEx( (char *) &reuseaddr, sizeof(reuseaddr)); #ifdef SO_REUSEPORT - /* - * Set up to allows multiple sockets on the same host to bind to the same port. - * The flag can be switched on by setting the lowest bit above the valid maximum port (0xffff). - */ - if (flags & USE_SOCK_REUSEPORT) { + /* + * Set up to allows multiple sockets on the same host to bind to the same port. + * The flag can be switched on by setting the lowest bit above the valid maximum port (0xffff). + */ + if (flags & USE_SOCK_REUSEPORT) { int reuseport = 1; - (void) setsockopt(sock, SOL_SOCKET, SO_REUSEPORT, - (char *) &reuseport, sizeof(reuseport)); - } + (void) setsockopt(sock, SOL_SOCKET, SO_REUSEPORT, + (char *) &reuseport, sizeof(reuseport)); + } #endif /* -- cgit v0.12 From 18592932556fe3ca6e78e7c4a11af2db03beb6da Mon Sep 17 00:00:00 2001 From: limeboy Date: Thu, 24 Nov 2016 12:47:21 +0000 Subject: Implement the whole TIP 456 specification. Also introduces the `-reuseaddr' and `-reuseport' options for the `socket' command. --- generic/tcl.decls | 2 +- generic/tcl.h | 7 +++++++ generic/tclDecls.h | 4 ++-- generic/tclIOCmd.c | 23 ++++++++++++++++++----- generic/tclIOSock.c | 6 +++--- unix/tclUnixSock.c | 41 ++++++++++++++++++++--------------------- win/tclWinSock.c | 2 +- 7 files changed, 52 insertions(+), 33 deletions(-) diff --git a/generic/tcl.decls b/generic/tcl.decls index 20c3f3e..af496b3 100644 --- a/generic/tcl.decls +++ b/generic/tcl.decls @@ -2329,7 +2329,7 @@ declare 630 { # TIP #456 declare 631 { Tcl_Channel Tcl_OpenTcpServerEx(Tcl_Interp *interp, int port, - const char *host, int flags, Tcl_TcpAcceptProc *acceptProc, + const char *host, unsigned int flags, Tcl_TcpAcceptProc *acceptProc, ClientData callbackData) } diff --git a/generic/tcl.h b/generic/tcl.h index eb53c70..75a947a 100644 --- a/generic/tcl.h +++ b/generic/tcl.h @@ -2371,6 +2371,13 @@ typedef int (Tcl_ArgvGenFuncProc)(ClientData clientData, Tcl_Interp *interp, /* *---------------------------------------------------------------------------- + * Definitions needed for the Tcl_OpenTcpServerEx function. [TIP #456] + */ +#define TCL_TCPSERVER_REUSEADDR (1<<0) +#define TCL_TCPSERVER_REUSEPORT (1<<1) + +/* + *---------------------------------------------------------------------------- * Single public declaration for NRE. */ diff --git a/generic/tclDecls.h b/generic/tclDecls.h index d1c1170..4810c51 100644 --- a/generic/tclDecls.h +++ b/generic/tclDecls.h @@ -1818,7 +1818,7 @@ EXTERN void Tcl_ZlibStreamSetCompressionDictionary( Tcl_Obj *compressionDictionaryObj); /* 631 */ EXTERN Tcl_Channel Tcl_OpenTcpServerEx(Tcl_Interp *interp, int port, - const char *host, int flags, + const char *host, unsigned int flags, Tcl_TcpAcceptProc *acceptProc, ClientData callbackData); @@ -2487,7 +2487,7 @@ typedef struct TclStubs { void * (*tcl_FindSymbol) (Tcl_Interp *interp, Tcl_LoadHandle handle, const char *symbol); /* 628 */ int (*tcl_FSUnloadFile) (Tcl_Interp *interp, Tcl_LoadHandle handlePtr); /* 629 */ void (*tcl_ZlibStreamSetCompressionDictionary) (Tcl_ZlibStream zhandle, Tcl_Obj *compressionDictionaryObj); /* 630 */ - Tcl_Channel (*tcl_OpenTcpServerEx) (Tcl_Interp *interp, int port, const char *host, int flags, Tcl_TcpAcceptProc *acceptProc, ClientData callbackData); /* 631 */ + Tcl_Channel (*tcl_OpenTcpServerEx) (Tcl_Interp *interp, int port, const char *host, unsigned int flags, Tcl_TcpAcceptProc *acceptProc, ClientData callbackData); /* 631 */ } TclStubs; extern const TclStubs *tclStubsPtr; diff --git a/generic/tclIOCmd.c b/generic/tclIOCmd.c index 883c6b7..b4696fd 100644 --- a/generic/tclIOCmd.c +++ b/generic/tclIOCmd.c @@ -1485,12 +1485,15 @@ Tcl_SocketObjCmd( Tcl_Obj *const objv[]) /* Argument objects. */ { static const char *const socketOptions[] = { - "-async", "-myaddr", "-myport", "-server", "-reuseport", NULL + "-async", "-myaddr", "-myport", "-server", "-reuseaddr", "-reuseport", + NULL }; enum socketOptions { - SKT_ASYNC, SKT_MYADDR, SKT_MYPORT, SKT_SERVER, SKT_REUSEPORT + SKT_ASYNC, SKT_MYADDR, SKT_MYPORT, SKT_SERVER, SKT_REUSEADDR, + SKT_REUSEPORT }; - int optionIndex, a, server = 0, port, myport = 0, async = 0, flags = 0; + int optionIndex, a, server = 0, port, myport = 0, async = 0; + unsigned int flags = 0; const char *host, *myaddr = NULL; Tcl_Obj *script = NULL; Tcl_Channel chan; @@ -1557,8 +1560,11 @@ Tcl_SocketObjCmd( } script = objv[a]; break; + case SKT_REUSEADDR: + flags |= TCL_TCPSERVER_REUSEADDR; + break; case SKT_REUSEPORT: - flags |= 1; + flags |= TCL_TCPSERVER_REUSEPORT; break; default: Tcl_Panic("Tcl_SocketObjCmd: bad option index to SocketOptions"); @@ -1583,7 +1589,14 @@ Tcl_SocketObjCmd( "?-myaddr addr? ?-myport myport? ?-async? host port"); iPtr->flags |= INTERP_ALTERNATE_WRONG_ARGS; Tcl_WrongNumArgs(interp, 1, objv, - "-server command ?-myaddr addr? port"); + "-server command ?-reuseaddr? ?-reuseport? ?-myaddr addr? port"); + return TCL_ERROR; + } + + if (!server && flags != 0) { + Tcl_SetObjResult(interp, Tcl_NewStringObj( + "options -reuseaddr and -reuseport are only valid for servers", + -1)); return TCL_ERROR; } diff --git a/generic/tclIOSock.c b/generic/tclIOSock.c index 72a0b5a..b6e99ba 100644 --- a/generic/tclIOSock.c +++ b/generic/tclIOSock.c @@ -283,7 +283,7 @@ TclCreateSocketAddress( } return 1; } - + /* *---------------------------------------------------------------------- * @@ -304,9 +304,9 @@ Tcl_Channel Tcl_OpenTcpServer(Tcl_Interp *interp, int port, const char *host, Tcl_TcpAcceptProc *acceptProc, ClientData callbackData) { - return Tcl_OpenTcpServerEx(interp, port, host, 0, acceptProc, callbackData); + return Tcl_OpenTcpServerEx(interp, port, host, TCL_TCPSERVER_REUSEADDR, + acceptProc, callbackData); } - /* * Local Variables: diff --git a/unix/tclUnixSock.c b/unix/tclUnixSock.c index 4767522..bb75ed3 100644 --- a/unix/tclUnixSock.c +++ b/unix/tclUnixSock.c @@ -113,11 +113,6 @@ struct TcpState { #define SOCKET_BUFSIZE 4096 -#ifdef SO_REUSEPORT -/* Bitmask to check if the setting of SO_REUSEPORT was requested by the caller. */ -#define USE_SOCK_REUSEPORT 1 -#endif - /* * Static routines for this file: */ @@ -1429,13 +1424,13 @@ Tcl_OpenTcpServerEx( Tcl_Interp *interp, /* For error reporting - may be NULL. */ int port, /* Port number to open. */ const char *myHost, /* Name of local host. */ - int flags, /* Flags. */ + unsigned int flags, /* Flags. */ Tcl_TcpAcceptProc *acceptProc, /* Callback for accepting connections from new * clients. */ ClientData acceptProcData) /* Data for the callback. */ { - int status = 0, sock = -1, reuseaddr = 1, chosenport; + int status = 0, sock = -1, optvalue, chosenport; struct addrinfo *addrlist = NULL, *addrPtr; /* socket address */ TcpState *statePtr = NULL; char channelName[SOCK_CHAN_LENGTH]; @@ -1511,24 +1506,28 @@ Tcl_OpenTcpServerEx( TclSockMinimumBuffers(INT2PTR(sock), SOCKET_BUFSIZE); /* - * Set up to reuse server addresses automatically and bind to the - * specified port. + * Set up to reuse server addresses and/or ports if requested. */ - (void) setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, - (char *) &reuseaddr, sizeof(reuseaddr)); - -#ifdef SO_REUSEPORT - /* - * Set up to allows multiple sockets on the same host to bind to the same port. - * The flag can be switched on by setting the lowest bit above the valid maximum port (0xffff). - */ - if (flags & USE_SOCK_REUSEPORT) { - int reuseport = 1; - (void) setsockopt(sock, SOL_SOCKET, SO_REUSEPORT, - (char *) &reuseport, sizeof(reuseport)); + if (flags & TCL_TCPSERVER_REUSEADDR) { + optvalue = 1; + (void) setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, + (char *) &optvalue, sizeof(optvalue)); } + + if (flags & TCL_TCPSERVER_REUSEPORT) { +#ifndef SO_REUSEPORT + /* + * If the platform doesn't support the SO_REUSEPORT flag we can't do + * much beside erroring out. + */ + errorMsg = "SO_REUSEPORT isn't supported by this platform"; + goto error; #endif + optvalue = 1; + (void) setsockopt(sock, SOL_SOCKET, SO_REUSEPORT, + (char *) &optvalue, sizeof(optvalue)); + } /* * Make sure we use the same port number when opening two server diff --git a/win/tclWinSock.c b/win/tclWinSock.c index a389d45..b228730 100644 --- a/win/tclWinSock.c +++ b/win/tclWinSock.c @@ -2039,7 +2039,7 @@ Tcl_OpenTcpServerEx( Tcl_Interp *interp, /* For error reporting - may be NULL. */ int port, /* Port number to open. */ const char *myHost, /* Name of local host. */ - int flags, /* Flags (not used) */ + unsigned int flags, /* Flags (not used) */ Tcl_TcpAcceptProc *acceptProc, /* Callback for accepting connections from new * clients. */ -- cgit v0.12 From 842d6d00f1e11ebdf17ec934d7c7d49381a456c0 Mon Sep 17 00:00:00 2001 From: "jan.nijtmans" Date: Thu, 24 Nov 2016 13:18:10 +0000 Subject: Fix compile error if SO_REUSEPORT not supported. Put command options in alphabetical order --- generic/tclIOCmd.c | 6 +++--- unix/tclUnixSock.c | 3 ++- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/generic/tclIOCmd.c b/generic/tclIOCmd.c index b4696fd..930f5a3 100644 --- a/generic/tclIOCmd.c +++ b/generic/tclIOCmd.c @@ -1485,12 +1485,12 @@ Tcl_SocketObjCmd( Tcl_Obj *const objv[]) /* Argument objects. */ { static const char *const socketOptions[] = { - "-async", "-myaddr", "-myport", "-server", "-reuseaddr", "-reuseport", + "-async", "-myaddr", "-myport", "-reuseaddr", "-reuseport", "-server", NULL }; enum socketOptions { - SKT_ASYNC, SKT_MYADDR, SKT_MYPORT, SKT_SERVER, SKT_REUSEADDR, - SKT_REUSEPORT + SKT_ASYNC, SKT_MYADDR, SKT_MYPORT, SKT_REUSEADDR, SKT_REUSEPORT, + SKT_SERVER }; int optionIndex, a, server = 0, port, myport = 0, async = 0; unsigned int flags = 0; diff --git a/unix/tclUnixSock.c b/unix/tclUnixSock.c index bb75ed3..187c157 100644 --- a/unix/tclUnixSock.c +++ b/unix/tclUnixSock.c @@ -1523,10 +1523,11 @@ Tcl_OpenTcpServerEx( */ errorMsg = "SO_REUSEPORT isn't supported by this platform"; goto error; -#endif +#else optvalue = 1; (void) setsockopt(sock, SOL_SOCKET, SO_REUSEPORT, (char *) &optvalue, sizeof(optvalue)); +#endif } /* -- cgit v0.12 From 15b2687d3cc301f3e63f0f9953948cf2a258b883 Mon Sep 17 00:00:00 2001 From: limeboy Date: Thu, 24 Nov 2016 15:00:36 +0000 Subject: Adjust the tests and add a handful of new ones. --- tests/socket.test | 31 +++++++++++++++++++++++++------ 1 file changed, 25 insertions(+), 6 deletions(-) diff --git a/tests/socket.test b/tests/socket.test index d43c41c..82dc800 100644 --- a/tests/socket.test +++ b/tests/socket.test @@ -265,13 +265,13 @@ test socket_$af-1.1 {arg parsing for socket command} -constraints [list socket s } -returnCodes error -result {no argument given for -server option} test socket_$af-1.2 {arg parsing for socket command} -constraints [list socket supported_$af] -body { socket -server foo -} -returnCodes error -result {wrong # args: should be "socket ?-myaddr addr? ?-myport myport? ?-async? host port" or "socket -server command ?-myaddr addr? port"} +} -returnCodes error -result {wrong # args: should be "socket ?-myaddr addr? ?-myport myport? ?-async? host port" or "socket -server command ?-reuseaddr? ?-reuseport? ?-myaddr addr? port"} test socket_$af-1.3 {arg parsing for socket command} -constraints [list socket supported_$af] -body { socket -myaddr } -returnCodes error -result {no argument given for -myaddr option} test socket_$af-1.4 {arg parsing for socket command} -constraints [list socket supported_$af] -body { socket -myaddr $localhost -} -returnCodes error -result {wrong # args: should be "socket ?-myaddr addr? ?-myport myport? ?-async? host port" or "socket -server command ?-myaddr addr? port"} +} -returnCodes error -result {wrong # args: should be "socket ?-myaddr addr? ?-myport myport? ?-async? host port" or "socket -server command ?-reuseaddr? ?-reuseport? ?-myaddr addr? port"} test socket_$af-1.5 {arg parsing for socket command} -constraints [list socket supported_$af] -body { socket -myport } -returnCodes error -result {no argument given for -myport option} @@ -280,19 +280,19 @@ test socket_$af-1.6 {arg parsing for socket command} -constraints [list socket s } -returnCodes error -result {expected integer but got "xxxx"} test socket_$af-1.7 {arg parsing for socket command} -constraints [list socket supported_$af] -body { socket -myport 2522 -} -returnCodes error -result {wrong # args: should be "socket ?-myaddr addr? ?-myport myport? ?-async? host port" or "socket -server command ?-myaddr addr? port"} +} -returnCodes error -result {wrong # args: should be "socket ?-myaddr addr? ?-myport myport? ?-async? host port" or "socket -server command ?-reuseaddr? ?-reuseport? ?-myaddr addr? port"} test socket_$af-1.8 {arg parsing for socket command} -constraints [list socket supported_$af] -body { socket -froboz -} -returnCodes error -result {bad option "-froboz": must be -async, -myaddr, -myport, or -server} +} -returnCodes error -result {bad option "-froboz": must be -async, -myaddr, -myport, -server, -reuseaddr, or -reuseport} test socket_$af-1.9 {arg parsing for socket command} -constraints [list socket supported_$af] -body { socket -server foo -myport 2521 3333 } -returnCodes error -result {option -myport is not valid for servers} test socket_$af-1.10 {arg parsing for socket command} -constraints [list socket supported_$af] -body { socket host 2528 -junk -} -returnCodes error -result {wrong # args: should be "socket ?-myaddr addr? ?-myport myport? ?-async? host port" or "socket -server command ?-myaddr addr? port"} +} -returnCodes error -result {wrong # args: should be "socket ?-myaddr addr? ?-myport myport? ?-async? host port" or "socket -server command ?-reuseaddr? ?-reuseport? ?-myaddr addr? port"} test socket_$af-1.11 {arg parsing for socket command} -constraints [list socket supported_$af] -body { socket -server callback 2520 -- -} -returnCodes error -result {wrong # args: should be "socket ?-myaddr addr? ?-myport myport? ?-async? host port" or "socket -server command ?-myaddr addr? port"} +} -returnCodes error -result {wrong # args: should be "socket ?-myaddr addr? ?-myport myport? ?-async? host port" or "socket -server command ?-reuseaddr? ?-reuseport? ?-myaddr addr? port"} test socket_$af-1.12 {arg parsing for socket command} -constraints [list socket supported_$af] -body { socket foo badport } -returnCodes error -result {expected integer but got "badport"} @@ -302,6 +302,12 @@ test socket_$af-1.13 {arg parsing for socket command} -constraints [list socket test socket_$af-1.14 {arg parsing for socket command} -constraints [list socket supported_$af] -body { socket -server foo -async } -returnCodes error -result {cannot set -async option for server sockets} +test socket_$af-1.15 {arg parsing for socket command} -constraints [list socket supported_$af] -body { + socket -reuseaddr 4242 +} -returnCodes error -result {options -reuseaddr and -reuseport are only valid for servers} +test socket_$af-1.16 {arg parsing for socket command} -constraints [list socket supported_$af] -body { + socket -reuseport 4242 +} -returnCodes error -result {options -reuseaddr and -reuseport are only valid for servers} set path(script) [makeFile {} script] @@ -2360,6 +2366,19 @@ test socket-14.18 {bug c6ed4acfd8: running async socket connect made other conne catch {close $csock2} } -result {} +test socket-14.19 {tip 456 -- introduce the -reuseport option} \ + -constraints {socket} \ + -body { + proc accept {channel address port} {} + set port [randport] + set ssock1 [socket -server accept -reuseport $port] + set ssock2 [socket -server accept -reuseport $port] + return ok +} -cleanup { + catch {close $ssock1} + catch {close $ssock2} + } -result ok + set num 0 set x {localhost {socket} 127.0.0.1 {supported_inet} ::1 {supported_inet6}} -- cgit v0.12 From 1b0d436cc7b557e2feaf5131923ce17fb84622eb Mon Sep 17 00:00:00 2001 From: "jan.nijtmans" Date: Thu, 24 Nov 2016 16:20:05 +0000 Subject: Starting implementing the "package files" command. TIP still to be written. --- generic/tclInt.h | 1 + generic/tclLoad.c | 8 ++++- generic/tclPkg.c | 92 ++++++++++++++++++++++++++++++++++++++++++++++++------ tests/package.test | 2 +- 4 files changed, 92 insertions(+), 11 deletions(-) diff --git a/generic/tclInt.h b/generic/tclInt.h index 4257ea1..bfcd002 100644 --- a/generic/tclInt.h +++ b/generic/tclInt.h @@ -3100,6 +3100,7 @@ MODULE_SCOPE int TclpObjChdir(Tcl_Obj *pathPtr); MODULE_SCOPE Tcl_Channel TclpOpenTemporaryFile(Tcl_Obj *dirObj, Tcl_Obj *basenameObj, Tcl_Obj *extensionObj, Tcl_Obj *resultingNameObj); +MODULE_SCOPE void TclPkgFileSeen(Tcl_Interp *interp, const char *fileName); MODULE_SCOPE Tcl_Obj * TclPathPart(Tcl_Interp *interp, Tcl_Obj *pathPtr, Tcl_PathPart portion); MODULE_SCOPE char * TclpReadlink(const char *fileName, diff --git a/generic/tclLoad.c b/generic/tclLoad.c index be296b3..184c158 100644 --- a/generic/tclLoad.c +++ b/generic/tclLoad.c @@ -397,6 +397,12 @@ Tcl_LoadObjCmd( goto done; } + if (target == interp) { + /* Only register the file if the load is done in the + * current interpreter */ + TclPkgFileSeen(target, Tcl_GetString(objv[1])); + } + /* * Create a new record to describe this package. */ @@ -998,7 +1004,7 @@ Tcl_StaticPackage( } /* - * Package isn't loade in the current interp yet. Mark it as now being + * Package isn't loaded in the current interp yet. Mark it as now being * loaded. */ diff --git a/generic/tclPkg.c b/generic/tclPkg.c index 244eb94..3d052a6 100644 --- a/generic/tclPkg.c +++ b/generic/tclPkg.c @@ -32,6 +32,17 @@ typedef struct PkgAvail { * same package. */ } PkgAvail; +typedef struct PkgName { + struct PkgName *nextPtr; /* Next in list of package names being initialized. */ + char name[1]; +} PkgName; + +typedef struct PkgFiles { + PkgName *names; /* Package names being initialized. */ + Tcl_HashTable table; /* Table which contains files for each package */ +} PkgFiles; + + /* * For each package that is known in any way to an interpreter, there is one * record of the following type. These records are stored in the @@ -81,7 +92,7 @@ static const char * PkgRequireCore(Tcl_Interp *interp, const char *name, ((v) = ckalloc(len), memcpy((v),(s),(len))) #define DupString(v,s) \ do { \ - unsigned local__len = (unsigned) (strlen(s) + 1); \ + size_t local__len = strlen(s) + 1; \ DupBlock((v),(s),local__len); \ } while (0) @@ -189,6 +200,29 @@ Tcl_PkgProvideEx( *---------------------------------------------------------------------- */ +static void PkgFilesCleanupProc(ClientData clientData, + Tcl_Interp *interp) +{ + PkgFiles *pkgFiles = (PkgFiles *) clientData; + + while (pkgFiles->names) { + PkgName *name = pkgFiles->names; + pkgFiles->names = name->nextPtr; + ckfree(name); + } + Tcl_DeleteHashTable(&pkgFiles->table); + return; +} + +void TclPkgFileSeen(Tcl_Interp *interp, const char *fileName) +{ + PkgFiles *pkgFiles = (PkgFiles *) Tcl_GetAssocData(interp, "tclPkgFiles", NULL); + if (pkgFiles) { + const char *name = pkgFiles->names->name; + printf("Seen %s for package %s\n", fileName, name); + } +} + #undef Tcl_PkgRequire const char * Tcl_PkgRequire( @@ -489,12 +523,31 @@ PkgRequireCore( */ char *versionToProvide = bestPtr->version; + PkgFiles *pkgFiles; + PkgName *pkgName; script = bestPtr->script; pkgPtr->clientData = versionToProvide; - Tcl_Preserve(script); Tcl_Preserve(versionToProvide); + Tcl_Preserve(script); + /* If assocdata "tclPkgFiles" doesn't exist yet, create it */ + pkgFiles = Tcl_GetAssocData(interp, "tclPkgFiles", NULL); + if (!pkgFiles) { + pkgFiles = ckalloc(sizeof(PkgFiles)); + pkgFiles->names = NULL; + Tcl_InitHashTable(&pkgFiles->table, TCL_STRING_KEYS); + Tcl_SetAssocData(interp, "tclPkgFiles", PkgFilesCleanupProc, pkgFiles); + } + /* Push "ifneeded" package name in "tclPkgFiles" assocdata. */ + pkgName = ckalloc(sizeof(PkgName) + strlen(name)); + pkgName->nextPtr = pkgFiles->names; + strcpy(pkgName->name, name); + pkgFiles->names = pkgName; code = Tcl_EvalEx(interp, script, -1, TCL_EVAL_GLOBAL); + /* Pop the "ifneeded" package name from "tclPkgFiles" assocdata*/ + pkgName = pkgFiles->names; + pkgFiles->names = pkgFiles->names->nextPtr; + ckfree(pkgName); Tcl_Release(script); pkgPtr = FindPackage(interp, name); @@ -764,14 +817,14 @@ Tcl_PackageObjCmd( Tcl_Obj *const objv[]) /* Argument objects. */ { static const char *const pkgOptions[] = { - "forget", "ifneeded", "names", "prefer", "present", - "provide", "require", "unknown", "vcompare", "versions", - "vsatisfies", NULL + "files", "forget", "ifneeded", "names", "prefer", + "present", "provide", "require", "unknown", "vcompare", + "versions", "vsatisfies", NULL }; enum pkgOptions { - PKG_FORGET, PKG_IFNEEDED, PKG_NAMES, PKG_PREFER, PKG_PRESENT, - PKG_PROVIDE, PKG_REQUIRE, PKG_UNKNOWN, PKG_VCOMPARE, PKG_VERSIONS, - PKG_VSATISFIES + PKG_FILES, PKG_FORGET, PKG_IFNEEDED, PKG_NAMES, PKG_PREFER, + PKG_PRESENT, PKG_PROVIDE, PKG_REQUIRE, PKG_UNKNOWN, PKG_VCOMPARE, + PKG_VERSIONS, PKG_VSATISFIES }; Interp *iPtr = (Interp *) interp; int optionIndex, exact, i, satisfies; @@ -794,6 +847,27 @@ Tcl_PackageObjCmd( return TCL_ERROR; } switch ((enum pkgOptions) optionIndex) { + case PKG_FILES: { + const char *keyString; + Tcl_Obj *result = Tcl_NewObj(); + + for (i = 2; i < objc; i++) { + keyString = TclGetString(objv[i]); + hPtr = Tcl_FindHashEntry(&iPtr->packageTable, keyString); + if (hPtr == NULL) { + continue; + } + pkgPtr = Tcl_GetHashValue(hPtr); + availPtr = pkgPtr->availPtr; + while (availPtr != NULL) { + Tcl_ListObjAppendElement(interp, result, Tcl_NewStringObj(availPtr->script, -1)); + availPtr = availPtr->nextPtr; + } + ckfree(pkgPtr); + } + Tcl_SetObjResult(interp, result); + break; + } case PKG_FORGET: { const char *keyString; @@ -1220,7 +1294,7 @@ FindPackage( void TclFreePackageInfo( - Interp *iPtr) /* Interpereter that is being deleted. */ + Interp *iPtr) /* Interpreter that is being deleted. */ { Package *pkgPtr; Tcl_HashSearch search; diff --git a/tests/package.test b/tests/package.test index 49346d8..99f9f06 100644 --- a/tests/package.test +++ b/tests/package.test @@ -832,7 +832,7 @@ test package-4.52 {Tcl_PackageCmd procedure, "vsatisfies" option} { } {0} test package-4.53 {Tcl_PackageCmd procedure, "versions" option} -body { package foo -} -returnCodes error -result {bad option "foo": must be forget, ifneeded, names, prefer, present, provide, require, unknown, vcompare, versions, or vsatisfies} +} -returnCodes error -result {bad option "foo": must be files, forget, ifneeded, names, prefer, present, provide, require, unknown, vcompare, versions, or vsatisfies} test package-4.54 {Tcl_PackageCmd procedure, "vsatisfies" option} -body { package vsatisfies 2.1 2.1-3.2-4.5 } -returnCodes error -result {expected versionMin-versionMax but got "2.1-3.2-4.5"} -- cgit v0.12 From 07020d6350987f39307fa3f60dd7d3414edb04ef Mon Sep 17 00:00:00 2001 From: limeboy Date: Thu, 24 Nov 2016 20:28:42 +0000 Subject: First round of documentation update. --- doc/OpenTcp.3 | 13 ++++++++++++- doc/socket.n | 10 ++++++++++ 2 files changed, 22 insertions(+), 1 deletion(-) diff --git a/doc/OpenTcp.3 b/doc/OpenTcp.3 index 4a7dc1e..040a8e2 100644 --- a/doc/OpenTcp.3 +++ b/doc/OpenTcp.3 @@ -9,7 +9,7 @@ .BS '\" Note: do not modify the .SH NAME line immediately below! .SH NAME -Tcl_OpenTcpClient, Tcl_MakeTcpClientChannel, Tcl_OpenTcpServer \- procedures to open channels using TCP sockets +Tcl_OpenTcpClient, Tcl_MakeTcpClientChannel, Tcl_OpenTcpServer, Tcl_OpenTcpServerEx \- procedures to open channels using TCP sockets .SH SYNOPSIS .nf \fB#include \fR @@ -23,6 +23,9 @@ Tcl_Channel Tcl_Channel \fBTcl_OpenTcpServer\fR(\fIinterp, port, myaddr, proc, clientData\fR) .sp +Tcl_Channel +\fBTcl_OpenTcpServerEx\fR(\fIinterp, port, myaddr, flags, proc, clientData\fR) +.sp .SH ARGUMENTS .AS Tcl_TcpAcceptProc clientData .AP Tcl_Interp *interp in @@ -41,6 +44,9 @@ for the local end of the connection. If NULL, a default interface is chosen. .AP int async in If nonzero, the client socket is connected asynchronously to the server. +.AP "unsigned int" flags in +ORed combination of \fBTCL_TCPSERVER\fR flags that specify additional +informations about the socket being created. .AP ClientData sock in Platform-specific handle for client TCP socket. .AP Tcl_TcpAcceptProc *proc in @@ -158,6 +164,11 @@ register it, use \fBTcl_RegisterChannel\fR. If one of the standard channels, \fBstdin\fR, \fBstdout\fR or \fBstderr\fR was previously closed, the act of creating the new channel also assigns it as a replacement for the standard channel. +.SS TCL_OPENTCPSERVEREX +.PP +\fBTcl_OpenTcpServerEx\fR behaviour is identical to \fBTcl_OpenTcpServer\fR but +gives more flexibility to the user by providing a mean to further customize some +aspects of the socket via the \fIflags\fR parameter. .SH "PLATFORM ISSUES" .PP On Unix platforms, the socket handle is a Unix file descriptor as diff --git a/doc/socket.n b/doc/socket.n index 3efdb37..3d77bab 100644 --- a/doc/socket.n +++ b/doc/socket.n @@ -131,6 +131,16 @@ wildcard address so that it can accept connections from any interface. If \fIaddr\fR is a domain name that resolves to multiple IP addresses that are available on the local machine, the socket will listen on all of them. +.TP +\fB\-reuseaddr\fI boolean\fR +. +Tells the kernel whether to reuse the local address if there's no active socket +listening on it. This is the default on Windows. +.TP +\fB\-reuseport\fI boolean\fR +. +Tells the kernel whether to allow the binding of multiple sockets to the same +socket address. This is the default on Windows. .PP Server channels cannot be used for input or output; their sole use is to accept new client connections. The channels created for each incoming -- cgit v0.12 From 467b6eeb8e37745e3e02deb72d0833995109cc50 Mon Sep 17 00:00:00 2001 From: limeboy Date: Thu, 24 Nov 2016 21:01:43 +0000 Subject: Allow a boolean argument to be passed. --- generic/tclIOCmd.c | 42 +++++++++++++++++++++++++++++++++++------- tests/socket.test | 18 +++++++++--------- unix/tclUnixSock.c | 3 ++- 3 files changed, 46 insertions(+), 17 deletions(-) diff --git a/generic/tclIOCmd.c b/generic/tclIOCmd.c index b4696fd..49c7c06 100644 --- a/generic/tclIOCmd.c +++ b/generic/tclIOCmd.c @@ -1485,14 +1485,14 @@ Tcl_SocketObjCmd( Tcl_Obj *const objv[]) /* Argument objects. */ { static const char *const socketOptions[] = { - "-async", "-myaddr", "-myport", "-server", "-reuseaddr", "-reuseport", + "-async", "-myaddr", "-myport", "-reuseaddr", "-reuseport", "server", NULL }; enum socketOptions { - SKT_ASYNC, SKT_MYADDR, SKT_MYPORT, SKT_SERVER, SKT_REUSEADDR, - SKT_REUSEPORT + SKT_ASYNC, SKT_MYADDR, SKT_MYPORT, SKT_REUSEADDR, SKT_REUSEPORT, + SKT_SERVER }; - int optionIndex, a, server = 0, port, myport = 0, async = 0; + int optionIndex, a, server = 0, port, myport = 0, async = 0, boolTmp; unsigned int flags = 0; const char *host, *myaddr = NULL; Tcl_Obj *script = NULL; @@ -1552,6 +1552,7 @@ Tcl_SocketObjCmd( return TCL_ERROR; } server = 1; + flags = TCL_TCPSERVER_REUSEADDR; a++; if (a >= objc) { Tcl_SetObjResult(interp, Tcl_NewStringObj( @@ -1561,10 +1562,36 @@ Tcl_SocketObjCmd( script = objv[a]; break; case SKT_REUSEADDR: - flags |= TCL_TCPSERVER_REUSEADDR; + a++; + if (a >= objc) { + Tcl_SetObjResult(interp, Tcl_NewStringObj( + "no argument given for -reuseaddr option", -1)); + return TCL_ERROR; + } + if (Tcl_GetBooleanFromObj(interp, objv[a], &boolTmp) != TCL_OK) { + return TCL_ERROR; + } + if (boolTmp) { + flags |= TCL_TCPSERVER_REUSEADDR; + } else { + flags &= ~TCL_TCPSERVER_REUSEADDR; + } break; case SKT_REUSEPORT: - flags |= TCL_TCPSERVER_REUSEPORT; + a++; + if (a >= objc) { + Tcl_SetObjResult(interp, Tcl_NewStringObj( + "no argument given for -reuseport option", -1)); + return TCL_ERROR; + } + if (Tcl_GetBooleanFromObj(interp, objv[a], &boolTmp) != TCL_OK) { + return TCL_ERROR; + } + if (boolTmp) { + flags |= TCL_TCPSERVER_REUSEPORT; + } else { + flags &= ~TCL_TCPSERVER_REUSEPORT; + } break; default: Tcl_Panic("Tcl_SocketObjCmd: bad option index to SocketOptions"); @@ -1589,7 +1616,8 @@ Tcl_SocketObjCmd( "?-myaddr addr? ?-myport myport? ?-async? host port"); iPtr->flags |= INTERP_ALTERNATE_WRONG_ARGS; Tcl_WrongNumArgs(interp, 1, objv, - "-server command ?-reuseaddr? ?-reuseport? ?-myaddr addr? port"); + "-server command ?-reuseaddr boolean? ?-reuseport boolean? " + "?-myaddr addr? port"); return TCL_ERROR; } diff --git a/tests/socket.test b/tests/socket.test index 82dc800..387e08e 100644 --- a/tests/socket.test +++ b/tests/socket.test @@ -265,13 +265,13 @@ test socket_$af-1.1 {arg parsing for socket command} -constraints [list socket s } -returnCodes error -result {no argument given for -server option} test socket_$af-1.2 {arg parsing for socket command} -constraints [list socket supported_$af] -body { socket -server foo -} -returnCodes error -result {wrong # args: should be "socket ?-myaddr addr? ?-myport myport? ?-async? host port" or "socket -server command ?-reuseaddr? ?-reuseport? ?-myaddr addr? port"} +} -returnCodes error -result {wrong # args: should be "socket ?-myaddr addr? ?-myport myport? ?-async? host port" or "socket -server command ?-reuseaddr boolean? ?-reuseport boolean? ?-myaddr addr? port"} test socket_$af-1.3 {arg parsing for socket command} -constraints [list socket supported_$af] -body { socket -myaddr } -returnCodes error -result {no argument given for -myaddr option} test socket_$af-1.4 {arg parsing for socket command} -constraints [list socket supported_$af] -body { socket -myaddr $localhost -} -returnCodes error -result {wrong # args: should be "socket ?-myaddr addr? ?-myport myport? ?-async? host port" or "socket -server command ?-reuseaddr? ?-reuseport? ?-myaddr addr? port"} +} -returnCodes error -result {wrong # args: should be "socket ?-myaddr addr? ?-myport myport? ?-async? host port" or "socket -server command ?-reuseaddr boolean? ?-reuseport boolean? ?-myaddr addr? port"} test socket_$af-1.5 {arg parsing for socket command} -constraints [list socket supported_$af] -body { socket -myport } -returnCodes error -result {no argument given for -myport option} @@ -280,7 +280,7 @@ test socket_$af-1.6 {arg parsing for socket command} -constraints [list socket s } -returnCodes error -result {expected integer but got "xxxx"} test socket_$af-1.7 {arg parsing for socket command} -constraints [list socket supported_$af] -body { socket -myport 2522 -} -returnCodes error -result {wrong # args: should be "socket ?-myaddr addr? ?-myport myport? ?-async? host port" or "socket -server command ?-reuseaddr? ?-reuseport? ?-myaddr addr? port"} +} -returnCodes error -result {wrong # args: should be "socket ?-myaddr addr? ?-myport myport? ?-async? host port" or "socket -server command ?-reuseaddr boolean? ?-reuseport boolean? ?-myaddr addr? port"} test socket_$af-1.8 {arg parsing for socket command} -constraints [list socket supported_$af] -body { socket -froboz } -returnCodes error -result {bad option "-froboz": must be -async, -myaddr, -myport, -server, -reuseaddr, or -reuseport} @@ -289,10 +289,10 @@ test socket_$af-1.9 {arg parsing for socket command} -constraints [list socket s } -returnCodes error -result {option -myport is not valid for servers} test socket_$af-1.10 {arg parsing for socket command} -constraints [list socket supported_$af] -body { socket host 2528 -junk -} -returnCodes error -result {wrong # args: should be "socket ?-myaddr addr? ?-myport myport? ?-async? host port" or "socket -server command ?-reuseaddr? ?-reuseport? ?-myaddr addr? port"} +} -returnCodes error -result {wrong # args: should be "socket ?-myaddr addr? ?-myport myport? ?-async? host port" or "socket -server command ?-reuseaddr boolean? ?-reuseport boolean? ?-myaddr addr? port"} test socket_$af-1.11 {arg parsing for socket command} -constraints [list socket supported_$af] -body { socket -server callback 2520 -- -} -returnCodes error -result {wrong # args: should be "socket ?-myaddr addr? ?-myport myport? ?-async? host port" or "socket -server command ?-reuseaddr? ?-reuseport? ?-myaddr addr? port"} +} -returnCodes error -result {wrong # args: should be "socket ?-myaddr addr? ?-myport myport? ?-async? host port" or "socket -server command ?-reuseaddr boolean? ?-reuseport boolean? ?-myaddr addr? port"} test socket_$af-1.12 {arg parsing for socket command} -constraints [list socket supported_$af] -body { socket foo badport } -returnCodes error -result {expected integer but got "badport"} @@ -303,10 +303,10 @@ test socket_$af-1.14 {arg parsing for socket command} -constraints [list socket socket -server foo -async } -returnCodes error -result {cannot set -async option for server sockets} test socket_$af-1.15 {arg parsing for socket command} -constraints [list socket supported_$af] -body { - socket -reuseaddr 4242 + socket -reuseaddr yes 4242 } -returnCodes error -result {options -reuseaddr and -reuseport are only valid for servers} test socket_$af-1.16 {arg parsing for socket command} -constraints [list socket supported_$af] -body { - socket -reuseport 4242 + socket -reuseport yes 4242 } -returnCodes error -result {options -reuseaddr and -reuseport are only valid for servers} set path(script) [makeFile {} script] @@ -2371,8 +2371,8 @@ test socket-14.19 {tip 456 -- introduce the -reuseport option} \ -body { proc accept {channel address port} {} set port [randport] - set ssock1 [socket -server accept -reuseport $port] - set ssock2 [socket -server accept -reuseport $port] + set ssock1 [socket -server accept -reuseport yes $port] + set ssock2 [socket -server accept -reuseport yes $port] return ok } -cleanup { catch {close $ssock1} diff --git a/unix/tclUnixSock.c b/unix/tclUnixSock.c index bb75ed3..187c157 100644 --- a/unix/tclUnixSock.c +++ b/unix/tclUnixSock.c @@ -1523,10 +1523,11 @@ Tcl_OpenTcpServerEx( */ errorMsg = "SO_REUSEPORT isn't supported by this platform"; goto error; -#endif +#else optvalue = 1; (void) setsockopt(sock, SOL_SOCKET, SO_REUSEPORT, (char *) &optvalue, sizeof(optvalue)); +#endif } /* -- cgit v0.12 From 3d5c28f5270e4958bcec2e6e52425a5fae5f8cc4 Mon Sep 17 00:00:00 2001 From: limeboy Date: Fri, 25 Nov 2016 13:27:56 +0000 Subject: Minor documentation touchups. --- doc/socket.n | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/doc/socket.n b/doc/socket.n index 3d77bab..532ea2e 100644 --- a/doc/socket.n +++ b/doc/socket.n @@ -134,13 +134,13 @@ listen on all of them. .TP \fB\-reuseaddr\fI boolean\fR . -Tells the kernel whether to reuse the local address if there's no active socket -listening on it. This is the default on Windows. +Tells the kernel whether to reuse the local address if there is no socket +actively listening on it. This is the default on Windows. .TP \fB\-reuseport\fI boolean\fR . Tells the kernel whether to allow the binding of multiple sockets to the same -socket address. This is the default on Windows. +address and port as long as all of them specify the \fB-reuseport\fR option. .PP Server channels cannot be used for input or output; their sole use is to accept new client connections. The channels created for each incoming -- cgit v0.12 From 8fe50e3f91ec232823ba032f24dabbaa7c9f298c Mon Sep 17 00:00:00 2001 From: limeboy Date: Fri, 25 Nov 2016 14:53:20 +0000 Subject: Windows support and minor touchups to the documentation. --- doc/socket.n | 2 +- win/tclWinSock.c | 17 +++++++++++++---- 2 files changed, 14 insertions(+), 5 deletions(-) diff --git a/doc/socket.n b/doc/socket.n index 532ea2e..823dbd5 100644 --- a/doc/socket.n +++ b/doc/socket.n @@ -140,7 +140,7 @@ actively listening on it. This is the default on Windows. \fB\-reuseport\fI boolean\fR . Tells the kernel whether to allow the binding of multiple sockets to the same -address and port as long as all of them specify the \fB-reuseport\fR option. +address and port. .PP Server channels cannot be used for input or output; their sole use is to accept new client connections. The channels created for each incoming diff --git a/win/tclWinSock.c b/win/tclWinSock.c index b228730..af22cf8 100644 --- a/win/tclWinSock.c +++ b/win/tclWinSock.c @@ -2039,7 +2039,7 @@ Tcl_OpenTcpServerEx( Tcl_Interp *interp, /* For error reporting - may be NULL. */ int port, /* Port number to open. */ const char *myHost, /* Name of local host. */ - unsigned int flags, /* Flags (not used) */ + unsigned int flags, /* Flags. */ Tcl_TcpAcceptProc *acceptProc, /* Callback for accepting connections from new * clients. */ @@ -2053,6 +2053,7 @@ Tcl_OpenTcpServerEx( char channelName[SOCK_CHAN_LENGTH]; u_long flag = 1; /* Indicates nonblocking mode. */ const char *errorMsg = NULL; + int optvalue; if (TclpHasSockets(interp) != TCL_OK) { return NULL; @@ -2111,9 +2112,17 @@ Tcl_OpenTcpServerEx( } /* - * Bind to the specified port. Note that we must not call - * setsockopt with SO_REUSEADDR or SO_REUSEPORT because Microsoft - * allows addresses and ports to be reused even if they are still in use. + * The SO_REUSEADDR option on Windows behaves like SO_REUSEPORT on unix + * systems. + */ + if (flags & TCL_TCPSERVER_REUSEPORT) { + optvalue = 1; + (void) setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, + (char *) &optvalue, sizeof(optvalue)); + } + + /* + * Bind to the specified port. * * Bind should not be affected by the socket having already been * set into nonblocking mode. If there is trouble, this is one -- cgit v0.12 From cdb6b73776ae7e1c7680e33cbf9ea809a7bc5825 Mon Sep 17 00:00:00 2001 From: dkf Date: Fri, 25 Nov 2016 15:44:43 +0000 Subject: =?UTF-8?q?Implementation=20of=20improved=20notifier=20from=20Luci?= =?UTF-8?q?o=20Andr=C3=A9s=20Illanes=20Albornoz.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- unix/configure | 60 ++++ unix/configure.ac | 28 ++ unix/tclUnixNotfy.c | 768 ++++++++++++++++++++++++++++++++++++++++++++++++---- 3 files changed, 800 insertions(+), 56 deletions(-) diff --git a/unix/configure b/unix/configure index baea1f1..14f88f3 100755 --- a/unix/configure +++ b/unix/configure @@ -8439,6 +8439,66 @@ $as_echo "#define NO_FD_SET 1" >>confdefs.h fi +#----------------------------------------------------------------------------- +# Options for the notifier. Checks for epoll(7) on Linux, and kqueue(2) +# on FreeBSD. +#----------------------------------------------------------------------------- + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for advanced notifier support" >&5 +$as_echo_n "checking for advanced notifier support... " >&6; } +case x`uname -s` in + xLinux) + { $as_echo "$as_me:${as_lineno-$LINENO}: result: epoll(7)" >&5 +$as_echo "epoll(7)" >&6; } + for ac_header in sys/epoll.h +do : + ac_fn_c_check_header_mongrel "$LINENO" "sys/epoll.h" "ac_cv_header_sys_epoll_h" "$ac_includes_default" +if test "x$ac_cv_header_sys_epoll_h" = xyes; then : + cat >>confdefs.h <<_ACEOF +#define HAVE_SYS_EPOLL_H 1 +_ACEOF + +$as_echo "#define HAVE_EPOLL 1" >>confdefs.h + +fi + +done +;; + xFreeBSD) + { $as_echo "$as_me:${as_lineno-$LINENO}: result: kqueue(2)" >&5 +$as_echo "kqueue(2)" >&6; } + # Messy because we want to check if *all* the headers are present, and not + # just *any* + tcl_kqueue_headers=x + for ac_header in sys/types.h sys/event.h sys/time.h +do : + as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh` +ac_fn_c_check_header_mongrel "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default" +if eval test \"x\$"$as_ac_Header"\" = x"yes"; then : + cat >>confdefs.h <<_ACEOF +#define `$as_echo "HAVE_$ac_header" | $as_tr_cpp` 1 +_ACEOF + tcl_kqueue_headers=${tcl_kqueue_headers}y +fi + +done + + if test $tcl_kqueue_headers = xyyy; then : + + +$as_echo "#define HAVE_KQUEUE 1" >>confdefs.h + +fi;; + xDarwin) + # Assume that we've got CoreFoundation present (checked elsewhere because + # of wider impact). + { $as_echo "$as_me:${as_lineno-$LINENO}: result: OSX" >&5 +$as_echo "OSX" >&6; };; + *) + { $as_echo "$as_me:${as_lineno-$LINENO}: result: none" >&5 +$as_echo "none" >&6; };; +esac + #------------------------------------------------------------------------------ # Find out all about time handling differences. #------------------------------------------------------------------------------ diff --git a/unix/configure.ac b/unix/configure.ac index bafb970..2389ab0 100644 --- a/unix/configure.ac +++ b/unix/configure.ac @@ -300,6 +300,34 @@ if test $tcl_ok = no; then AC_DEFINE(NO_FD_SET, 1, [Do we have fd_set?]) fi +#----------------------------------------------------------------------------- +# Options for the notifier. Checks for epoll(7) on Linux, and kqueue(2) +# on FreeBSD. +#----------------------------------------------------------------------------- + +AC_MSG_CHECKING([for advanced notifier support]) +case x`uname -s` in + xLinux) + AC_MSG_RESULT([epoll(7)]) + AC_CHECK_HEADERS([sys/epoll.h], + [AC_DEFINE(HAVE_EPOLL, [1], [Is epoll(7) supported?])]);; + xFreeBSD) + AC_MSG_RESULT([kqueue(2)]) + # Messy because we want to check if *all* the headers are present, and not + # just *any* + tcl_kqueue_headers=x + AC_CHECK_HEADERS([sys/types.h sys/event.h sys/time.h], + [tcl_kqueue_headers=${tcl_kqueue_headers}y]) + AS_IF([test $tcl_kqueue_headers = xyyy], [ + AC_DEFINE(HAVE_KQUEUE, [1], [Is kqueue(2) supported?])]);; + xDarwin) + # Assume that we've got CoreFoundation present (checked elsewhere because + # of wider impact). + AC_MSG_RESULT([OSX]);; + *) + AC_MSG_RESULT([none]);; +esac + #------------------------------------------------------------------------------ # Find out all about time handling differences. #------------------------------------------------------------------------------ diff --git a/unix/tclUnixNotfy.c b/unix/tclUnixNotfy.c index e37962d..485f6f7 100644 --- a/unix/tclUnixNotfy.c +++ b/unix/tclUnixNotfy.c @@ -1,9 +1,10 @@ /* * tclUnixNotfy.c -- * - * This file contains the implementation of the select()-based - * Unix-specific notifier, which is the lowest-level part of the Tcl - * event loop. This file works together with generic/tclNotify.c. + * This file contains the implementation of the Unix-specific notifier, + * based on select()/epoll()/kqueue() depending on platform, which is the + * lowest-level part of the Tcl event loop. This file works together with + * generic/tclNotify.c. * * Copyright (c) 1995-1997 Sun Microsystems, Inc. * @@ -15,12 +16,25 @@ #ifndef HAVE_COREFOUNDATION /* Darwin/Mac OS X CoreFoundation notifier is * in tclMacOSXNotify.c */ #include +#if defined(HAVE_EPOLL) +# include +#elif defined(HAVE_KQUEUE) +# include +# include +# include +#endif /* * This structure is used to keep track of the notifier info for a registered * file. */ +#if defined(HAVE_EPOLL) || defined(HAVE_KQUEUE) +struct PlatformEventData; +#undef USE_SELECT_FOR_NOTIFIER +#else +#define USE_SELECT_FOR_NOTIFIER 1 +#endif /* HAVE_EPOLL || HAVE_KQUEUE */ typedef struct FileHandler { int fd; int mask; /* Mask of desired events: TCL_READABLE, @@ -32,8 +46,41 @@ typedef struct FileHandler { * Tcl_CreateFileHandler. */ ClientData clientData; /* Argument to pass to proc. */ struct FileHandler *nextPtr;/* Next in list of all files we care about. */ +#if defined(HAVE_EPOLL) || defined(HAVE_KQUEUE) + struct PlatformEventData *platformEventData; + /* Pointer associating the platform-specific + * event structures with {file,tsd}Ptrs. */ + int platformReadyMask; /* Platform-specific mask of ready events. */ +#endif /* HAVE_EPOLL || HAVE_KQUEUE */ } FileHandler; +#if defined(HAVE_EPOLL) || defined(HAVE_KQUEUE) +/* + * The following structure is associated with a FileHandler through platform- + * specific event structures (currently either struct epoll_event or kevent) + * whenever Tcl_CreateFileHandler or Tcl_DeleteFileHandler are called. + * It contains a FileHandler and a ThreadSpecificData pointer in order to + * update readyMask and to alert waiting threads. + */ + +struct ThreadSpecificData; +struct PlatformEventData { + FileHandler *filePtr; + struct ThreadSpecificData *tsdPtr; +}; +#else /* !(HAVE_EPOLL || HAVE_KQUEUE) */ +/* + * The following structure contains a set of select() masks to track readable, + * writable, and exception conditions. + */ + +typedef struct { + fd_set readable; + fd_set writable; + fd_set exception; +} SelectMasks; +#endif /* HAVE_EPOLL || HAVE_KQUEUE */ + /* * The following structure is what is added to the Tcl event queue when file * handlers are ready to fire. @@ -50,17 +97,6 @@ typedef struct { } FileHandlerEvent; /* - * The following structure contains a set of select() masks to track readable, - * writable, and exception conditions. - */ - -typedef struct { - fd_set readable; - fd_set writable; - fd_set exception; -} SelectMasks; - -/* * The following static structure contains the state information for the * select based implementation of the Tcl notifier. One of these structures is * created for each thread that is using the notifier. @@ -69,6 +105,7 @@ typedef struct { typedef struct ThreadSpecificData { FileHandler *firstFileHandlerPtr; /* Pointer to head of file handler list. */ +#ifdef USE_SELECT_FOR_NOTIFIER SelectMasks checkMasks; /* This structure is used to build up the * masks to be used in the next call to * select. Bits are set in response to calls @@ -79,6 +116,7 @@ typedef struct ThreadSpecificData { int numFdBits; /* Number of valid bits in checkMasks (one * more than highest fd for which * Tcl_WatchFile has been called). */ +#endif /* USE_SELECT_FOR_NOTIFIER */ #ifdef TCL_THREADS int onList; /* True if it is in this list */ unsigned int pollState; /* pollState is used to implement a polling @@ -169,10 +207,11 @@ static int notifierThreadRunning = 0; static pthread_cond_t notifierCV = PTHREAD_COND_INITIALIZER; /* - * The pollState bits - * POLL_WANT is set by each thread before it waits on its condition - * variable. It is checked by the notifier before it does select. - * POLL_DONE is set by the notifier if it goes into select after seeing + * The pollState bits. + * + * POLL_WANT: Set by each thread before it waits on its condition variable. + * It is checked by the notifier before it does select. + * POLL_DONE: Set by the notifier if it goes into select after seeing * POLL_WANT. The idea is to ensure it tries a select with the * same bits the initial thread had set. */ @@ -185,8 +224,29 @@ static pthread_cond_t notifierCV = PTHREAD_COND_INITIALIZER; */ static Tcl_ThreadId notifierThread; - #endif /* TCL_THREADS */ +#if defined(HAVE_EPOLL) || defined(HAVE_KQUEUE) +/* + * This is the file descriptor for the platform-specific events mechanism + * (currently either epoll_{ctl,wait} or kevent). + */ + +static int eventsFd; + +/* + * This array reflects the readable/writable/error event conditions that + * were found to exist by the last call to the platform-specific events + * mechanism (currently either epoll_wait or kevent) in NotifierThreadProc. + * maxReadyEvents specifies the maximum number of epoll_events in readyEvents. + */ + +#if defined(HAVE_EPOLL) +static struct epoll_event *readyEvents; +#elif defined(HAVE_KQUEUE) +static struct kevent *readyEvents; +#endif /* HAVE_EPOLL */ +static int maxReadyEvents; +#endif /* HAVE_EPOLL || HAVE_KQUEUE */ /* * Static routines defined in this file. @@ -256,6 +316,28 @@ static const WCHAR className[] = L"TclNotifier"; static DWORD __stdcall NotifierProc(void *hwnd, unsigned int message, void *wParam, void *lParam); #endif /* TCL_THREADS && __CYGWIN__ */ + +#if defined(HAVE_EPOLL) || defined(HAVE_KQUEUE) +#define PLATFORMEVENTSCONTROL_ADD 0x01 +#define PLATFORMEVENTSCONTROL_DEL 0x02 +#define PLATFORMEVENTSCONTROL_MOD 0x04 +#define PLATFORMEVENTSCONTROL_AUTO_MASK 0x10 +static void PlatformEventsControl(FileHandler *filePtr, + ThreadSpecificData *tsdPtr, int op, int mask); +static void PlatformEventsFinalize(void); +static int PlatformEventsGet(int numEvent_last, + int numReadyEvents, int skipFd, int wantFd, + int onList); +static void PlatformEventsInit(void); +static int PlatformEventsTranslate(FileHandler *filePtr); +#if defined(HAVE_EPOLL) +static int PlatformEventsWait(struct epoll_event *events, + int numEvents, struct timeval *timePtr); +#elif defined(HAVE_KQUEUE) +static int PlatformEventsWait(struct kevent *events, + int numEvents, struct timeval *timePtr); +#endif /* HAVE_EPOLL */ +#endif /* HAVE_EPOLL || HAVE_KQUEUE */ #if TCL_THREADS /* @@ -273,8 +355,10 @@ static DWORD __stdcall NotifierProc(void *hwnd, unsigned int message, * *---------------------------------------------------------------------- */ + static void -StartNotifierThread(const char *proc) +StartNotifierThread( + const char *proc) { if (!notifierThreadRunning) { pthread_mutex_lock(¬ifierInitMutex); @@ -285,6 +369,7 @@ StartNotifierThread(const char *proc) } pthread_mutex_lock(¬ifierMutex); + /* * Wait for the notifier pipe to be created. */ @@ -325,6 +410,9 @@ Tcl_InitNotifier(void) } else { ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&dataKey); +#if defined(HAVE_EPOLL) || defined(HAVE_KQUEUE) + PlatformEventsInit(); +#endif /* HAVE_EPOLL || HAVE_KQUEUE */ #ifdef TCL_THREADS tsdPtr->eventReady = 0; @@ -443,6 +531,9 @@ Tcl_FinalizeNotifier( } notifierThreadRunning = 0; } +#if defined(HAVE_EPOLL) || defined(HAVE_KQUEUE) + PlatformEventsFinalize(); +#endif /* HAVE_EPOLL || HAVE_KQUEUE */ } } @@ -571,6 +662,360 @@ Tcl_ServiceModeHook( } } +#if defined(HAVE_EPOLL) || defined(HAVE_KQUEUE) +/* + *---------------------------------------------------------------------- + * + * PlatformEventsControl -- + * + * This function abstracts adding, modifying, or deleting a file + * descriptor and its associated FileHandler and ThreadSpecificData + * pointers from an epoll or kqueue fd via either epoll_ctl or kevent. + * + * Results: + * None. + * + * Side effects: + * If successful, a file descriptor is added, deleted, or modified from + * the epoll on Linux and kqueue on FreeBSD fd. + * + *---------------------------------------------------------------------- + */ + +void +PlatformEventsControl( + FileHandler *filePtr, + ThreadSpecificData *tsdPtr, + int op, + int mask) +{ +#if defined(HAVE_EPOLL) + struct epoll_event event; + int epollOp; +#elif defined(HAVE_KQUEUE) + int numEvents; + struct kevent event[2]; + int keventOp; +#endif /* HAVE_EPOLL */ + struct PlatformEventData *platformEventData; + + if (op & PLATFORMEVENTSCONTROL_AUTO_MASK) { + mask = filePtr->mask; + op &= ~PLATFORMEVENTSCONTROL_AUTO_MASK; + } + if (op == PLATFORMEVENTSCONTROL_ADD) { + platformEventData = ckalloc(sizeof(*platformEventData)); + platformEventData->filePtr = filePtr; + platformEventData->tsdPtr = tsdPtr; + filePtr->platformEventData = platformEventData; + } else { + platformEventData = filePtr->platformEventData; + } + filePtr->platformReadyMask = 0; + +#if defined(HAVE_EPOLL) + event.events = EPOLLET; + if (mask & TCL_READABLE) { + event.events |= EPOLLIN; + } + if (mask & TCL_WRITABLE) { + event.events |= EPOLLOUT; + } + if (mask & TCL_EXCEPTION) { + event.events |= EPOLLERR; + } + event.data.ptr = platformEventData; + if (op == PLATFORMEVENTSCONTROL_ADD) { + epollOp = EPOLL_CTL_ADD; + } else if (op == PLATFORMEVENTSCONTROL_DEL) { + epollOp = EPOLL_CTL_DEL; + } else if (op == PLATFORMEVENTSCONTROL_MOD) { + epollOp = EPOLL_CTL_MOD; + } + if (epoll_ctl(eventsFd, epollOp, filePtr->fd, &event) == -1) { + Tcl_Panic("epoll_ctl: %s", strerror(errno)); + } +#elif defined(HAVE_KQUEUE) + + numEvents = 0; + keventOp = 0; + if (op == PLATFORMEVENTSCONTROL_ADD) { + keventOp = EV_ADD; + } else if (op == PLATFORMEVENTSCONTROL_DEL) { + keventOp = EV_DELETE; + } else if (op == PLATFORMEVENTSCONTROL_MOD) { + keventOp = EV_ADD; + } + keventOp |= EV_CLEAR; + if ((mask & TCL_READABLE) || (mask & TCL_EXCEPTION)) { + EV_SET(&event[numEvents], filePtr->fd, EVFILT_READ, keventOp, 0, 0, + platformEventData); + numEvents++; + } + if (mask & TCL_WRITABLE) { + EV_SET(&event[numEvents], filePtr->fd, EVFILT_WRITE, keventOp, 0, 0, + platformEventData); + numEvents++; + } + if (kevent(eventsFd, event, numEvents, NULL, 0, NULL) == -1) { + Tcl_Panic("kevent: %s", strerror(errno)); + } +#endif /* HAVE_EPOLL */ +} + +/* + *---------------------------------------------------------------------- + * + * PlatformEventsFinalize -- + * + * This function abstracts closing the epoll on Linux and kqueue on + * FreeBSD file descriptor and freeing its associated array of returned + * events. + * + * Results: + * None. + * + * Side effects: + * The epoll or kqueue fd is closed if non-zero. The array of returned + * events is freed if non_NULL. + * + *---------------------------------------------------------------------- + */ + +void +PlatformEventsFinalize(void) +{ + if (eventsFd > 0) { + close(eventsFd); + eventsFd = 0; + } + if (readyEvents) { + ckfree(readyEvents); + maxReadyEvents = 0; + } +} + +/* + *---------------------------------------------------------------------- + * + * PlatformEventsGet -- + * + * This function abstracts iterating over the array of returned events + * since the last call to PlatformEventsWait(). If skipFd and/or wantFd + * are non-zero, the specified file descriptor will be skipped or hunted + * for respectively. If onList is non-zero, the ThreadSpecificData asso- + * ciated with the current event must specify a non-zero onList flag. + * + * Results: + * Returns -1 if there were no or no eligible events. Returns the index + * of the event in the array of returned events in all other cases. + * + * Side effects: + * None. + * + *---------------------------------------------------------------------- + */ + +int +PlatformEventsGet( + int numEvent_last, + int numReadyEvents, + int skipFd, + int wantFd, + int onList) +{ + int numEvent; + struct PlatformEventData *platformEventData; + + for (numEvent = numEvent_last; numEvent < numReadyEvents; numEvent++) { +#if defined(HAVE_EPOLL) + platformEventData = readyEvents[numEvent].data.ptr; +#elif defined(HAVE_KQUEUE) + platformEventData = readyEvents[numEvent].udata; +#endif /* HAVE_EPOLL */ + if (!platformEventData) { + continue; + } else if (!platformEventData->filePtr) { + continue; + } else if (!platformEventData->tsdPtr) { + continue; + } else if (skipFd && (platformEventData->filePtr->fd == skipFd)) { + continue; + } else if (wantFd && (platformEventData->filePtr->fd != wantFd)) { + continue; + } else if (onList && !platformEventData->tsdPtr->onList) { + continue; + } else { + return numEvent; + } + } + return -1; +} + +/* + *---------------------------------------------------------------------- + * + * PlatformEventsInit -- + * This function abstracts creating an epoll fd on Linux and a kqueue + * fd on FreeBSD via epoll_create and kqueue system calls respectively. + * + * Results: + * None. + * + * Side effects: + * The epoll or kqueue fd is created if zero. The array of returned + * events is allocated and initialised with space for 128 events if zero. + * + *---------------------------------------------------------------------- + */ + +void +PlatformEventsInit(void) +{ +#if defined(HAVE_EPOLL) + if (eventsFd <= 0) { + eventsFd = epoll_create1(EPOLL_CLOEXEC); + if (eventsFd == -1) { + Tcl_Panic("epoll_create1: %s", strerror(errno)); + } + } +#elif defined(HAVE_KQUEUE) + if (eventsFd <= 0) { + eventsFd = kqueue(); + if (eventsFd == -1) { + Tcl_Panic("kqueue: %s", strerror(errno)); + } + } +#endif /* HAVE_EPOLL */ + if (!readyEvents) { + maxReadyEvents = 128; + readyEvents = ckalloc(maxReadyEvents * sizeof(readyEvents[0])); + } +} + +/* + *---------------------------------------------------------------------- + * + * PlatformEventsTranslate -- + * This function translates the platform-specific mask of returned events + * in and specific to a FileHandler to TCL_{READABLE,WRITABLE,EXCEPTION} + * bits. + * + * Results: + * Returns the translated and thus platform-independent mask. + * + * Side effects: + * None. + * + *---------------------------------------------------------------------- + */ + +int +PlatformEventsTranslate( + FileHandler *filePtr) +{ + int mask; + + mask = 0; +#if defined(HAVE_EPOLL) + if (filePtr->platformReadyMask & EPOLLIN) { + mask |= TCL_READABLE; + } + if (filePtr->platformReadyMask & EPOLLOUT) { + mask |= TCL_WRITABLE; + } + if (filePtr->platformReadyMask & EPOLLERR) { + mask |= TCL_EXCEPTION; + } +#elif defined(HAVE_KQUEUE) + if (filePtr->platformReadyMask & EVFILT_READ) { + mask |= TCL_READABLE; + } + if (filePtr->platformReadyMask & EVFILT_WRITE) { + mask |= TCL_WRITABLE; + } +#endif /* HAVE_EPOLL */ + return mask; +} + +/* + *---------------------------------------------------------------------- + * + * PlatformEventsWait -- + * This function abstracts waiting for I/O events via either epoll_ctl(2) + * on Linux or kevent(2) on FreeBSD. + * + * Results: + * Returns -1 if epoll_ctl(2)/kevent(2) failed. Returns 0 if polling + * and if no events became available whilst polling. Returns a pointer + * to and the count of all returned events in all other cases. + * + * Side effects: + * None. + * + *---------------------------------------------------------------------- + */ + +int +PlatformEventsWait( +#if defined(HAVE_EPOLL) + struct epoll_event *events, +#elif defined(HAVE_KQUEUE) + struct kevent *events, +#endif /* HAVE_EPOLL */ + int numEvents, + struct timeval *timePtr) +{ + int numFound; + struct timeval tv0, tv1, tv_delta; +#if defined(HAVE_EPOLL) + int timeout; +#elif defined(HAVE_KQUEUE) + struct timespec timeout, *timeoutPtr; +#endif /* HAVE_EPOLL */ + + bzero(events, numEvents * sizeof(events[0])); +#if defined(HAVE_EPOLL) + if (!timePtr) { + timeout = -1; + } else if (!timePtr->tv_sec && !timePtr->tv_usec) { + timeout = 0; + } else { + timeout = timePtr->tv_sec; + } + gettimeofday(&tv0, NULL); + numFound = epoll_wait(eventsFd, events, numEvents, timeout); + gettimeofday(&tv1, NULL); + +#elif defined(HAVE_KQUEUE) + if (!timePtr) { + timeoutPtr = NULL; + } else if (!timePtr->tv_sec && !timePtr->tv_usec) { + timeout.tv_sec = 0; + timeout.tv_nsec = 0; + timeoutPtr = &timeout; + } else { + timeout.tv_sec = timePtr->tv_sec; + timeout.tv_nsec = timePtr->tv_usec * 1000; + timeoutPtr = &timeout; + } + gettimeofday(&tv0, NULL); + numFound = kevent(eventsFd, NULL, 0, events, numEvents, timeoutPtr); + gettimeofday(&tv1, NULL); +#endif /* HAVE_EPOLL */ + + if (timePtr) { + timersub(&tv1, &tv0, &tv_delta); + timersub(&tv_delta, timePtr, timePtr); + } + if (numFound == -1) { + bzero(events, numEvents * sizeof(events[0])); + return -1; + } + return numFound; +} +#endif /* HAVE_EPOLL || HAVE_KQUEUE */ + /* *---------------------------------------------------------------------- * @@ -598,6 +1043,10 @@ Tcl_CreateFileHandler( * event. */ ClientData clientData) /* Arbitrary data to pass to proc. */ { +#if defined(HAVE_EPOLL) || defined(HAVE_KQUEUE) + int is_new; +#endif /* HAVE_EPOLL || HAVE_KQUEUE */ + if (tclNotifierHooks.createFileHandlerProc) { tclNotifierHooks.createFileHandlerProc(fd, mask, proc, clientData); return; @@ -617,11 +1066,29 @@ Tcl_CreateFileHandler( filePtr->readyMask = 0; filePtr->nextPtr = tsdPtr->firstFileHandlerPtr; tsdPtr->firstFileHandlerPtr = filePtr; +#if defined(HAVE_EPOLL) || defined(HAVE_KQUEUE) + is_new = 1; + } else { + is_new = 0; +#endif /* HAVE_EPOLL */ } filePtr->proc = proc; filePtr->clientData = clientData; filePtr->mask = mask; +#if defined(HAVE_EPOLL) || defined(HAVE_KQUEUE) + if (eventsFd) { + if (is_new) { + PlatformEventsControl(filePtr, tsdPtr, + PLATFORMEVENTSCONTROL_ADD + | PLATFORMEVENTSCONTROL_AUTO_MASK, 0); + } else { + PlatformEventsControl(filePtr, tsdPtr, + PLATFORMEVENTSCONTROL_MOD + | PLATFORMEVENTSCONTROL_AUTO_MASK, 0); + } + } +#else /* * Update the check masks for this file. */ @@ -644,6 +1111,7 @@ Tcl_CreateFileHandler( if (tsdPtr->numFdBits <= fd) { tsdPtr->numFdBits = fd+1; } +#endif /* HAVE_EPOLL || HAVE_KQUEUE */ } } @@ -673,7 +1141,9 @@ Tcl_DeleteFileHandler( return; } else { FileHandler *filePtr, *prevPtr; +#ifdef USE_SELECT_FOR_NOTIFIER int i; +#endif /* USE_SELECT_FOR_NOTIFIER */ ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&dataKey); /* @@ -694,6 +1164,15 @@ Tcl_DeleteFileHandler( * Update the check masks for this file. */ +#if defined(HAVE_EPOLL) || defined(HAVE_KQUEUE) + if (eventsFd) { + PlatformEventsControl(filePtr, tsdPtr, PLATFORMEVENTSCONTROL_DEL + | PLATFORMEVENTSCONTROL_AUTO_MASK, 0); + } + if (filePtr->platformEventData) { + ckfree(filePtr->platformEventData); + } +#else if (filePtr->mask & TCL_READABLE) { FD_CLR(fd, &tsdPtr->checkMasks.readable); } @@ -721,6 +1200,7 @@ Tcl_DeleteFileHandler( } tsdPtr->numFdBits = numFdBits; } +#endif /* HAVE_EPOLL || HAVE_KQUEUE */ /* * Clean up information in the callback record. @@ -950,7 +1430,11 @@ Tcl_WaitForEvent( tsdPtr->pollState = POLL_WANT; timePtr = NULL; } else { +#if defined(HAVE_EPOLL) || defined(HAVE_KQUEUE) + waitForFiles = 1; +#else waitForFiles = (tsdPtr->numFdBits > 0); +#endif /* HAVE_EPOLL || HAVE_KQUEUE */ tsdPtr->pollState = 0; } @@ -975,9 +1459,11 @@ Tcl_WaitForEvent( } } +#ifdef USE_SELECT_FOR_NOTIFIER FD_ZERO(&tsdPtr->readyMasks.readable); FD_ZERO(&tsdPtr->readyMasks.writable); FD_ZERO(&tsdPtr->readyMasks.exception); +#endif /* USE_SELECT_FOR_NOTIFIER */ if (!tsdPtr->eventReady) { #ifdef __CYGWIN__ @@ -993,7 +1479,7 @@ Tcl_WaitForEvent( MsgWaitForMultipleObjects(1, &tsdPtr->event, 0, timeout, 1279); pthread_mutex_lock(¬ifierMutex); } -#else +#else /* !__CYGWIN__ */ if (timePtr != NULL) { Tcl_Time now; struct timespec ptime; @@ -1054,6 +1540,10 @@ Tcl_WaitForEvent( } #else +#if defined(HAVE_EPOLL) || defined(HAVE_KQUEUE) + tsdPtr->numReadyEvents = PlatformEventsWait(readyEvents, + maxReadyEvents, timeoutPtr); +#else tsdPtr->readyMasks = tsdPtr->checkMasks; numFound = select(tsdPtr->numFdBits, &tsdPtr->readyMasks.readable, &tsdPtr->readyMasks.writable, &tsdPtr->readyMasks.exception, @@ -1069,6 +1559,7 @@ Tcl_WaitForEvent( FD_ZERO(&tsdPtr->readyMasks.writable); FD_ZERO(&tsdPtr->readyMasks.exception); } +#endif /* HAVE_EPOLL || HAVE_KQUEUE */ #endif /* TCL_THREADS */ /* @@ -1077,6 +1568,9 @@ Tcl_WaitForEvent( for (filePtr = tsdPtr->firstFileHandlerPtr; (filePtr != NULL); filePtr = filePtr->nextPtr) { +#if defined(HAVE_EPOLL) || defined(HAVE_KQUEUE) + mask = PlatformEventsTranslate(filePtr); +#else mask = 0; if (FD_ISSET(filePtr->fd, &tsdPtr->readyMasks.readable)) { mask |= TCL_READABLE; @@ -1087,6 +1581,7 @@ Tcl_WaitForEvent( if (FD_ISSET(filePtr->fd, &tsdPtr->readyMasks.exception)) { mask |= TCL_EXCEPTION; } +#endif /* HAVE_EPOLL || HAVE_KQUEUE */ if (!mask) { continue; @@ -1106,6 +1601,9 @@ Tcl_WaitForEvent( Tcl_QueueEvent((Tcl_Event *) fileEvPtr, TCL_QUEUE_TAIL); } filePtr->readyMask = mask; +#if defined(HAVE_EPOLL) || defined(HAVE_KQUEUE) + filePtr->platformReadyMask = 0; +#endif /* HAVE_EPOLL || HAVE_KQUEUE */ } #ifdef TCL_THREADS pthread_mutex_unlock(¬ifierMutex); @@ -1118,6 +1616,56 @@ Tcl_WaitForEvent( /* *---------------------------------------------------------------------- * + * AlertSingleThread -- + * + * Notify a single thread that is waiting on a file descriptor to become + * readable or writable or to have an exception condition. + * notifierMutex must be held. + * + * Result: + * None. + * + * Side effects: + * The condition variable associated with the thread is broadcasted. + * + *---------------------------------------------------------------------- + */ + +static void +AlertSingleThread( + ThreadSpecificData *tsdPtr) +{ + tsdPtr->eventReady = 1; + if (tsdPtr->onList) { + /* + * Remove the ThreadSpecificData structure of this thread + * from the waiting list. This prevents us from + * continuously spining on select until the other threads + * runs and services the file event. + */ + + if (tsdPtr->prevPtr) { + tsdPtr->prevPtr->nextPtr = tsdPtr->nextPtr; + } else { + waitingListPtr = tsdPtr->nextPtr; + } + if (tsdPtr->nextPtr) { + tsdPtr->nextPtr->prevPtr = tsdPtr->prevPtr; + } + tsdPtr->nextPtr = tsdPtr->prevPtr = NULL; + tsdPtr->onList = 0; + tsdPtr->pollState = 0; + } +#ifdef __CYGWIN__ + PostMessageW(tsdPtr->hwnd, 1024, 0, 0); +#else /* __CYGWIN__ */ + pthread_cond_broadcast(&tsdPtr->waitCV); +#endif /* __CYGWIN__ */ +} + +/* + *---------------------------------------------------------------------- + * * NotifierThreadProc -- * * This routine is the initial (and only) function executed by the @@ -1144,14 +1692,23 @@ NotifierThreadProc( ClientData clientData) /* Not used. */ { ThreadSpecificData *tsdPtr; +#ifdef USE_SELECT_FOR_NOTIFIER fd_set readableMask; fd_set writableMask; fd_set exceptionMask; - int fds[2]; - int i, numFdBits = 0, receivePipe; +#endif /* USE_SELECT_FOR_NOTIFIER */ + int i; + int fds[2], receivePipe; long found; struct timeval poll = {0., 0.}, *timePtr; char buf[2]; +#if defined(HAVE_EPOLL) || defined(HAVE_KQUEUE) + int numReadyEvents, numEvent; + FileHandler *filePtr_rP; + struct PlatformEventData *eventDataPtr; +#else + int numFdBits = 0; +#endif /* HAVE_EPOLL || HAVE_KQUEUE */ if (pipe(fds) != 0) { Tcl_Panic("NotifierThreadProc: %s", "could not create trigger pipe"); @@ -1183,6 +1740,19 @@ NotifierThreadProc( pthread_mutex_lock(¬ifierMutex); triggerPipe = fds[1]; +#if defined(HAVE_EPOLL) || defined(HAVE_KQUEUE) + /* + * Set up the epoll/kqueue fd to include the receive pipe. + */ + + filePtr_rP = ckalloc(sizeof(*filePtr_rP)); + filePtr_rP->fd = receivePipe; + tsdPtr = TCL_TSD_INIT(&dataKey); + PlatformEventsControl(filePtr_rP, tsdPtr, PLATFORMEVENTSCONTROL_ADD, + TCL_READABLE); + tsdPtr = NULL; +#endif /* HAVE_EPOLL || HAVE_KQUEUE*/ + /* * Signal any threads that are waiting. */ @@ -1195,12 +1765,28 @@ NotifierThreadProc( */ while (1) { +#if defined(HAVE_EPOLL) || defined(HAVE_KQUEUE) + pthread_mutex_lock(¬ifierMutex); + timePtr = NULL; + for (tsdPtr = waitingListPtr; tsdPtr; tsdPtr = tsdPtr->nextPtr) { + if (tsdPtr->pollState & POLL_WANT) { + /* + * Here we make sure we go through select() with the same mask + * bits that were present when the thread tried to poll. + */ + + tsdPtr->pollState |= POLL_DONE; + timePtr = &poll; + } + } + pthread_mutex_unlock(¬ifierMutex); +#else FD_ZERO(&readableMask); FD_ZERO(&writableMask); FD_ZERO(&exceptionMask); /* - * Compute the logical OR of the select masks from all the waiting + * Compute the logical OR of the masks from all the waiting * notifiers. */ @@ -1232,16 +1818,29 @@ NotifierThreadProc( } } pthread_mutex_unlock(¬ifierMutex); - +#endif /* HAVE_EPOLL || HAVE_KQUEUE */ +#ifdef USE_SELECT_FOR_NOTIFIER /* - * Set up the select mask to include the receive pipe. + * Set up the mask to include the receive pipe. */ if (receivePipe >= numFdBits) { numFdBits = receivePipe + 1; } FD_SET(receivePipe, &readableMask); +#endif /* USE_SELECT_FOR_NOTIFIER */ +#if defined(HAVE_EPOLL) || defined(HAVE_KQUEUE) + numReadyEvents = PlatformEventsWait(readyEvents, maxReadyEvents, + timePtr); + if (numReadyEvents == -1) { + /* + * Try again immediately on an error. + */ + numReadyEvents = 0; + continue; + } +#else if (select(numFdBits, &readableMask, &writableMask, &exceptionMask, timePtr) == -1) { /* @@ -1250,12 +1849,53 @@ NotifierThreadProc( continue; } +#endif /* HAVE_EPOLL || HAVE_KQUEUE*/ /* * Alert any threads that are waiting on a ready file descriptor. */ pthread_mutex_lock(¬ifierMutex); + numEvent = 0; +#if defined(HAVE_EPOLL) || defined(HAVE_KQUEUE) + for (tsdPtr = waitingListPtr; tsdPtr; tsdPtr = tsdPtr->nextPtr) { + if (tsdPtr->pollState & POLL_DONE) { + AlertSingleThread(tsdPtr); + } + } + while (1) { + numEvent = PlatformEventsGet(numEvent, numReadyEvents, + receivePipe, 0, 1); + if (numEvent == -1) { + break; + } +#if defined(HAVE_EPOLL) + eventDataPtr = readyEvents[numEvent].data.ptr; + eventDataPtr->filePtr->platformReadyMask = + readyEvents[numEvent].events; +#elif defined(HAVE_KQUEUE) + eventDataPtr = readyEvents[numEvent].udata; + if (readyEvents[numEvent].filter == EVFILT_READ) { + if (readyEvents[numEvent].flags & (EV_EOF | EV_ERROR)) { + eventDataPtr->filePtr->platformReadyMask |= EV_ERROR; + } else { + eventDataPtr->filePtr->platformReadyMask + |= EVFILT_READ; + } + } + if (readyEvents[numEvent].filter == EVFILT_WRITE) { + if (readyEvents[numEvent].flags & (EV_EOF | EV_ERROR)) { + eventDataPtr->filePtr->platformReadyMask |= EV_ERROR; + } else { + eventDataPtr->filePtr->platformReadyMask + |= EVFILT_WRITE; + } + } +#endif /* HAVE_EPOLL */ + numEvent++; + found = 1; + tsdPtr = eventDataPtr->tsdPtr; +#else for (tsdPtr = waitingListPtr; tsdPtr; tsdPtr = tsdPtr->nextPtr) { found = 0; @@ -1276,34 +1916,10 @@ NotifierThreadProc( found = 1; } } +#endif /* HAVE_EPOLL || HAVE_KQUEUE */ if (found || (tsdPtr->pollState & POLL_DONE)) { - tsdPtr->eventReady = 1; - if (tsdPtr->onList) { - /* - * Remove the ThreadSpecificData structure of this thread - * from the waiting list. This prevents us from - * continuously spining on select until the other threads - * runs and services the file event. - */ - - if (tsdPtr->prevPtr) { - tsdPtr->prevPtr->nextPtr = tsdPtr->nextPtr; - } else { - waitingListPtr = tsdPtr->nextPtr; - } - if (tsdPtr->nextPtr) { - tsdPtr->nextPtr->prevPtr = tsdPtr->prevPtr; - } - tsdPtr->nextPtr = tsdPtr->prevPtr = NULL; - tsdPtr->onList = 0; - tsdPtr->pollState = 0; - } -#ifdef __CYGWIN__ - PostMessageW(tsdPtr->hwnd, 1024, 0, 0); -#else /* __CYGWIN__ */ - pthread_cond_broadcast(&tsdPtr->waitCV); -#endif /* __CYGWIN__ */ + AlertSingleThread(tsdPtr); } } pthread_mutex_unlock(¬ifierMutex); @@ -1314,7 +1930,40 @@ NotifierThreadProc( * avoid a race condition we only read one at a time. */ - if (FD_ISSET(receivePipe, &readableMask)) { +#if defined(HAVE_EPOLL) || defined(HAVE_KQUEUE) + found = 0; + numEvent = 0; + while (1) { + numEvent = PlatformEventsGet(numEvent, numReadyEvents, 0, + receivePipe, 0); + if (numEvent == -1) { + break; + } +#if defined(HAVE_EPOLL) + eventDataPtr = readyEvents[numEvent].data.ptr; + eventDataPtr->filePtr->platformReadyMask = + readyEvents[numEvent].events; +#elif defined(HAVE_KQUEUE) + eventDataPtr = readyEvents[numEvent].udata; + eventDataPtr->filePtr->platformReadyMask = + readyEvents[numEvent].filter; +#endif /* HAVE_EPOLL || HAVE_KQUEUE */ + if (eventDataPtr->filePtr->fd == receivePipe) { + found = 1; + break; + } + numEvent++; + } +#if defined(HAVE_EPOLL) + if (found && readyEvents[numEvent].events & EPOLLIN) +#elif defined(HAVE_KQUEUE) + if (found && (readyEvents[numEvent].filter == EVFILT_READ) + && !(readyEvents[numEvent].flags & (EV_EOF | EV_ERROR))) +#else + if (FD_ISSET(receivePipe, &readableMask)) +#endif /* HAVE_EPOLL */ + { +#endif /* HAVE_EPOLL || HAVE_KQUEUE */ i = read(receivePipe, buf, 1); if ((i == 0) || ((i == 1) && (buf[0] == 'q'))) { @@ -1334,6 +1983,10 @@ NotifierThreadProc( * termination of the notifier thread. */ +#if defined(HAVE_EPOLL) || defined(HAVE_KQUEUE) + PlatformEventsControl(filePtr_rP, tsdPtr, PLATFORMEVENTSCONTROL_DEL, + TCL_READABLE); +#endif /* HAVE_EPOLL || HAVE_KQUEUE */ close(receivePipe); pthread_mutex_lock(¬ifierMutex); triggerPipe = -1; @@ -1371,32 +2024,35 @@ AtForkChild(void) pthread_cond_init(¬ifierCV, NULL); /* - * notifierThreadRunning == 1: thread is running, (there might be data in notifier lists) + * notifierThreadRunning == 1: thread is running, (there might be data in + * notifier lists) * atForkInit == 0: InitNotifier was never called * notifierCount != 0: unbalanced InitNotifier() / FinalizeNotifier calls * waitingListPtr != 0: there are threads currently waiting for events. */ if (atForkInit == 1) { - notifierCount = 0; if (notifierThreadRunning == 1) { ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&dataKey); - notifierThreadRunning = 0; + notifierThreadRunning = 0; close(triggerPipe); triggerPipe = -1; + /* * The waitingListPtr might contain event info from multiple * threads, which are invalid here, so setting it to NULL is not * unreasonable. */ + waitingListPtr = NULL; /* * The tsdPtr from before the fork is copied as well. But since * we are paranoic, we don't trust its condvar and reset it. */ + #ifdef __CYGWIN__ DestroyWindow(tsdPtr->hwnd); tsdPtr->hwnd = CreateWindowExW(NULL, className, -- cgit v0.12 From ee6806b80d84376e44d904884d5afc001ba9a4de Mon Sep 17 00:00:00 2001 From: "jan.nijtmans" Date: Sat, 26 Nov 2016 17:47:27 +0000 Subject: Add "package files" testcase, which doesn give the right answer. So still work to do --- tests/load.test | 4 ++-- tests/package.test | 12 ++++++++++-- 2 files changed, 12 insertions(+), 4 deletions(-) diff --git a/tests/load.test b/tests/load.test index 7c4b47f..94451e9 100644 --- a/tests/load.test +++ b/tests/load.test @@ -197,14 +197,14 @@ test load-8.2 {TclGetLoadedPackages procedure} -body { } -returnCodes error -result {could not find interpreter "gorp"} test load-8.3a {TclGetLoadedPackages procedure} [list teststaticpkg $dll $loaded] { lsort -index 1 [info loaded {}] -} [lsort -index 1 [list {{} Double} {{} More} {{} Another} {{} Test} [list [file join $testDir pkga$ext] Pkga] [list [file join $testDir pkgb$ext] Pkgb] {*}$alreadyLoaded]] +} [lsort -index 1 [list {{} Double} {{} More} {{} Another} {{} Test} [list [file join $testDir pkga$ext] Pkga] [list [file join $testDir pkgb$ext] Pkgb] [list [file join $testDir pkge$ext] Pkge] {*}$alreadyLoaded]] test load-8.3b {TclGetLoadedPackages procedure} [list teststaticpkg $dll $loaded] { lsort -index 1 [info loaded child] } [lsort -index 1 [list {{} Test} [list [file join $testDir pkgb$ext] Pkgb]]] test load-8.4 {TclGetLoadedPackages procedure} [list $dll $loaded teststaticpkg] { load [file join $testDir pkgb$ext] pkgb list [lsort -index 1 [info loaded {}]] [lsort [info commands pkgb_*]] -} [list [lsort -index 1 [concat [list [list [file join $testDir pkgb$ext] Pkgb] {{} Double} {{} More} {{} Another} {{} Test} [list [file join $testDir pkga$ext] Pkga]] $alreadyLoaded]] {pkgb_demo pkgb_sub pkgb_unsafe}] +} [list [lsort -index 1 [concat [list [list [file join $testDir pkgb$ext] Pkgb] [list [file join $testDir pkge$ext] Pkge] {{} Double} {{} More} {{} Another} {{} Test} [list [file join $testDir pkga$ext] Pkga]] $alreadyLoaded]] {pkgb_demo pkgb_sub pkgb_unsafe}] interp delete child test load-9.1 {Tcl_StaticPackage, load already-loaded package into another interp} \ diff --git a/tests/package.test b/tests/package.test index 99f9f06..7e8a42d 100644 --- a/tests/package.test +++ b/tests/package.test @@ -55,8 +55,8 @@ test package-1.7 {pkg::create gives correct output for 1 direct source} { ::pkg::create -name foo -version 1.0 -source test.tcl } {package ifneeded foo 1.0 [list source [file join $dir test.tcl]]} test package-1.8 {pkg::create gives correct output for 2 direct sources} { - ::pkg::create -name foo -version 1.0 -source test.tcl -source test2.tcl -} {package ifneeded foo 1.0 [list source [file join $dir test.tcl]]\n[list source [file join $dir test2.tcl]]} + list [::pkg::create -name foo -version 1.0 -source test.tcl -source test2.tcl] [package files foo] +} {{package ifneeded foo 1.0 [list source [file join $dir test.tcl]]\n[list source [file join $dir test2.tcl]]} {}} test package-1.9 {pkg::create gives correct output for 1 direct load} { ::pkg::create -name foo -version 1.0 -load test.so } {package ifneeded foo 1.0 [list load [file join $dir test.so]]} @@ -870,6 +870,14 @@ test package-5.2 {TclFreePackageInfo procedure} -body { } foo eval package require x 3.1 } -returnCodes error -match glob -result * +test package-5.3 {package files} -body { + interp create foo + foo eval { + package ifneeded t 2.4 {package provide t 2.4;package require http} + } + foo eval package require t 2.4 + foo eval {list [package files http] [package files t]} +} -result "[list {}] [file join $tcl_library http http.tcl]" test package-6.1 {CheckVersion procedure} { package vcompare 1 2.1 -- cgit v0.12 From b7e862c5654df82b0f5cff5fc9ab501022bfe4dd Mon Sep 17 00:00:00 2001 From: "jan.nijtmans" Date: Mon, 28 Nov 2016 13:17:47 +0000 Subject: Complete implementation, tests and documentation --- doc/info.n | 7 +-- doc/package.n | 8 ++++ generic/tclCmdMZ.c | 27 ++++++++++- generic/tclInt.h | 1 + generic/tclInterp.c | 19 +++++++- generic/tclPkg.c | 24 ++++++---- library/init.tcl | 2 +- library/package.tcl | 2 +- library/tclIndex | 134 ++++++++++++++++++++++++++-------------------------- tests/package.test | 2 +- 10 files changed, 140 insertions(+), 86 deletions(-) diff --git a/doc/info.n b/doc/info.n index 477e272..01ca10b 100644 --- a/doc/info.n +++ b/doc/info.n @@ -297,10 +297,11 @@ scripts are stored. This is actually the value of the \fBtcl_library\fR variable and may be changed by setting \fBtcl_library\fR. .TP -\fBinfo loaded \fR?\fIinterp\fR? +\fBinfo loaded \fR?\fIinterp\fR? \fR?\fIpackage\fR? . -Returns a list describing all of the packages that have been loaded into -\fIinterp\fR with the \fBload\fR command. +Returns the filename loaded as part of \fIpackage\fR. If \fIpackage\fR +is not specified, returns a list describing all of the packages +that have been loaded into \fIinterp\fR with the \fBload\fR command. Each list element is a sub-list with two elements consisting of the name of the file from which the package was loaded and the name of the package. diff --git a/doc/package.n b/doc/package.n index 47b2aa6..5687480 100644 --- a/doc/package.n +++ b/doc/package.n @@ -12,6 +12,7 @@ package \- Facilities for package loading and version control .SH SYNOPSIS .nf +\fBpackage files\fR \fIpackage\fR \fBpackage forget\fR ?\fIpackage package ...\fR? \fBpackage ifneeded \fIpackage version\fR ?\fIscript\fR? \fBpackage names\fR @@ -43,6 +44,13 @@ primarily by system scripts that maintain the package database. The behavior of the \fBpackage\fR command is determined by its first argument. The following forms are permitted: .TP +\fBpackage files\fR \fIpackage\fR +. +Lists all files forming part of \fIpackage\fR. Auto-loaded files are not +included in this list, only files which were directly sourced during package +initialization. The list order corresponds with the order in which the +files were sourced. +.TP \fBpackage forget\fR ?\fIpackage package ...\fR? . Removes all information about each specified package from this interpreter, diff --git a/generic/tclCmdMZ.c b/generic/tclCmdMZ.c index ed3d9a5..7f2a2f3 100644 --- a/generic/tclCmdMZ.c +++ b/generic/tclCmdMZ.c @@ -989,8 +989,11 @@ TclNRSourceObjCmd( { const char *encodingName = NULL; Tcl_Obj *fileName; + int result; + void **pkgFiles = NULL; + void *names = NULL; - if (objc != 2 && objc !=4) { + if (objc < 2 || objc > 4) { Tcl_WrongNumArgs(interp, 1, objv, "?-encoding name? fileName"); return TCL_ERROR; } @@ -1008,8 +1011,28 @@ TclNRSourceObjCmd( return TCL_ERROR; } encodingName = TclGetString(objv[2]); + } else if (objc == 3) { + static const char *const nopkgoptions[] = { + "-nopkg", NULL + }; + int index; + + if (TCL_ERROR == Tcl_GetIndexFromObj(interp, objv[1], nopkgoptions, + "option", TCL_EXACT, &index)) { + return TCL_ERROR; + } + pkgFiles = Tcl_GetAssocData(interp, "tclPkgFiles", NULL); + /* Make sure that during the following TclNREvalFile no filenames + * are recorded for inclusion in the "package files" command */ + names = *pkgFiles; + *pkgFiles = NULL; } - return TclNREvalFile(interp, fileName, encodingName); + result = TclNREvalFile(interp, fileName, encodingName); + if (pkgFiles) { + /* restore "tclPkgFiles" assocdata to how it was. */ + *pkgFiles = names; + } + return result; } /* diff --git a/generic/tclInt.h b/generic/tclInt.h index bfcd002..9422a03 100644 --- a/generic/tclInt.h +++ b/generic/tclInt.h @@ -3101,6 +3101,7 @@ MODULE_SCOPE Tcl_Channel TclpOpenTemporaryFile(Tcl_Obj *dirObj, Tcl_Obj *basenameObj, Tcl_Obj *extensionObj, Tcl_Obj *resultingNameObj); MODULE_SCOPE void TclPkgFileSeen(Tcl_Interp *interp, const char *fileName); +MODULE_SCOPE void *TclInitPkgFiles(Tcl_Interp *interp); MODULE_SCOPE Tcl_Obj * TclPathPart(Tcl_Interp *interp, Tcl_Obj *pathPtr, Tcl_PathPart portion); MODULE_SCOPE char * TclpReadlink(const char *fileName, diff --git a/generic/tclInterp.c b/generic/tclInterp.c index 1bfe76a..7874de9 100644 --- a/generic/tclInterp.c +++ b/generic/tclInterp.c @@ -331,13 +331,24 @@ TclSetPreInitScript( *---------------------------------------------------------------------- */ +typedef struct PkgName { + struct PkgName *nextPtr; /* Next in list of package names being initialized. */ + char name[4]; +} PkgName; + int Tcl_Init( Tcl_Interp *interp) /* Interpreter to initialize. */ { + PkgName pkgName = {NULL, "Tcl"}; + PkgName **names = TclInitPkgFiles(interp); + int result = TCL_ERROR; + + pkgName.nextPtr = *names; + *names = &pkgName; if (tclPreInitScript != NULL) { if (Tcl_EvalEx(interp, tclPreInitScript, -1, 0) == TCL_ERROR) { - return TCL_ERROR; + goto end; } } @@ -382,7 +393,7 @@ Tcl_Init( * alternate tclInit command before calling Tcl_Init(). */ - return Tcl_EvalEx(interp, + result = Tcl_EvalEx(interp, "if {[namespace which -command tclInit] eq \"\"} {\n" " proc tclInit {} {\n" " global tcl_libPath tcl_library env tclDefaultLibrary\n" @@ -445,6 +456,10 @@ Tcl_Init( " }\n" "}\n" "tclInit", -1, 0); + +end: + *names = (*names)->nextPtr; + return result; } /* diff --git a/generic/tclPkg.c b/generic/tclPkg.c index c258987..c3cc54e 100644 --- a/generic/tclPkg.c +++ b/generic/tclPkg.c @@ -38,7 +38,7 @@ typedef struct PkgName { } PkgName; typedef struct PkgFiles { - PkgName *names; /* Package names being initialized. */ + PkgName *names; /* Package names being initialized. Must be first field*/ Tcl_HashTable table; /* Table which contains files for each package */ } PkgFiles; @@ -222,6 +222,19 @@ static void PkgFilesCleanupProc(ClientData clientData, return; } +void *TclInitPkgFiles(Tcl_Interp *interp) +{ + /* If assocdata "tclPkgFiles" doesn't exist yet, create it */ + PkgFiles *pkgFiles = Tcl_GetAssocData(interp, "tclPkgFiles", NULL); + if (!pkgFiles) { + pkgFiles = ckalloc(sizeof(PkgFiles)); + pkgFiles->names = NULL; + Tcl_InitHashTable(&pkgFiles->table, TCL_STRING_KEYS); + Tcl_SetAssocData(interp, "tclPkgFiles", PkgFilesCleanupProc, pkgFiles); + } + return pkgFiles; +} + void TclPkgFileSeen(Tcl_Interp *interp, const char *fileName) { PkgFiles *pkgFiles = (PkgFiles *) Tcl_GetAssocData(interp, "tclPkgFiles", NULL); @@ -549,14 +562,7 @@ PkgRequireCore( pkgPtr->clientData = versionToProvide; Tcl_Preserve(versionToProvide); Tcl_Preserve(script); - /* If assocdata "tclPkgFiles" doesn't exist yet, create it */ - pkgFiles = Tcl_GetAssocData(interp, "tclPkgFiles", NULL); - if (!pkgFiles) { - pkgFiles = ckalloc(sizeof(PkgFiles)); - pkgFiles->names = NULL; - Tcl_InitHashTable(&pkgFiles->table, TCL_STRING_KEYS); - Tcl_SetAssocData(interp, "tclPkgFiles", PkgFilesCleanupProc, pkgFiles); - } + pkgFiles = TclInitPkgFiles(interp); /* Push "ifneeded" package name in "tclPkgFiles" assocdata. */ pkgName = ckalloc(sizeof(PkgName) + strlen(name)); pkgName->nextPtr = pkgFiles->names; diff --git a/library/init.tcl b/library/init.tcl index 544ea77..bac6270 100644 --- a/library/init.tcl +++ b/library/init.tcl @@ -483,7 +483,7 @@ proc auto_load_index {} { set dir [lindex $auto_path $i] set f "" if {$issafe} { - catch {source [file join $dir tclIndex]} + catch {source -nopkg [file join $dir tclIndex]} } elseif {[catch {set f [open [file join $dir tclIndex]]}]} { continue } else { diff --git a/library/package.tcl b/library/package.tcl index 44e3b28..cb1bea6 100644 --- a/library/package.tcl +++ b/library/package.tcl @@ -488,7 +488,7 @@ proc tclPkgUnknown {name args} { set dir [file dirname $file] if {![info exists procdDirs($dir)]} { try { - source $file + source -nopkg $file } trap {POSIX EACCES} {} { # $file was not readable; silently ignore continue diff --git a/library/tclIndex b/library/tclIndex index 26603c1..2762ce4 100644 --- a/library/tclIndex +++ b/library/tclIndex @@ -1,75 +1,75 @@ # Tcl autoload index file, version 2.0 # -*- tcl -*- # This file is generated by the "auto_mkindex" command -# and sourced to set up indexing information for one or +# and source -nopkgd to set up indexing information for one or # more commands. Typically each line is a command that # sets an element in the auto_index array, where the # element name is the name of a command and the value is # a script that loads the command. -set auto_index(auto_reset) [list source [file join $dir auto.tcl]] -set auto_index(tcl_findLibrary) [list source [file join $dir auto.tcl]] -set auto_index(auto_mkindex) [list source [file join $dir auto.tcl]] -set auto_index(auto_mkindex_old) [list source [file join $dir auto.tcl]] -set auto_index(::auto_mkindex_parser::init) [list source [file join $dir auto.tcl]] -set auto_index(::auto_mkindex_parser::cleanup) [list source [file join $dir auto.tcl]] -set auto_index(::auto_mkindex_parser::mkindex) [list source [file join $dir auto.tcl]] -set auto_index(::auto_mkindex_parser::hook) [list source [file join $dir auto.tcl]] -set auto_index(::auto_mkindex_parser::slavehook) [list source [file join $dir auto.tcl]] -set auto_index(::auto_mkindex_parser::command) [list source [file join $dir auto.tcl]] -set auto_index(::auto_mkindex_parser::commandInit) [list source [file join $dir auto.tcl]] -set auto_index(::auto_mkindex_parser::fullname) [list source [file join $dir auto.tcl]] -set auto_index(history) [list source [file join $dir history.tcl]] -set auto_index(::tcl::HistAdd) [list source [file join $dir history.tcl]] -set auto_index(::tcl::HistKeep) [list source [file join $dir history.tcl]] -set auto_index(::tcl::HistClear) [list source [file join $dir history.tcl]] -set auto_index(::tcl::HistInfo) [list source [file join $dir history.tcl]] -set auto_index(::tcl::HistRedo) [list source [file join $dir history.tcl]] -set auto_index(::tcl::HistIndex) [list source [file join $dir history.tcl]] -set auto_index(::tcl::HistEvent) [list source [file join $dir history.tcl]] -set auto_index(::tcl::HistChange) [list source [file join $dir history.tcl]] -set auto_index(pkg_mkIndex) [list source [file join $dir package.tcl]] -set auto_index(tclPkgSetup) [list source [file join $dir package.tcl]] -set auto_index(tclPkgUnknown) [list source [file join $dir package.tcl]] -set auto_index(::tcl::MacOSXPkgUnknown) [list source [file join $dir package.tcl]] -set auto_index(::pkg::create) [list source [file join $dir package.tcl]] -set auto_index(parray) [list source [file join $dir parray.tcl]] -set auto_index(::safe::InterpStatics) [list source [file join $dir safe.tcl]] -set auto_index(::safe::InterpNested) [list source [file join $dir safe.tcl]] -set auto_index(::safe::interpCreate) [list source [file join $dir safe.tcl]] -set auto_index(::safe::interpInit) [list source [file join $dir safe.tcl]] -set auto_index(::safe::CheckInterp) [list source [file join $dir safe.tcl]] -set auto_index(::safe::interpConfigure) [list source [file join $dir safe.tcl]] -set auto_index(::safe::InterpCreate) [list source [file join $dir safe.tcl]] -set auto_index(::safe::InterpSetConfig) [list source [file join $dir safe.tcl]] -set auto_index(::safe::interpFindInAccessPath) [list source [file join $dir safe.tcl]] -set auto_index(::safe::interpAddToAccessPath) [list source [file join $dir safe.tcl]] -set auto_index(::safe::InterpInit) [list source [file join $dir safe.tcl]] -set auto_index(::safe::AddSubDirs) [list source [file join $dir safe.tcl]] -set auto_index(::safe::interpDelete) [list source [file join $dir safe.tcl]] -set auto_index(::safe::setLogCmd) [list source [file join $dir safe.tcl]] -set auto_index(::safe::SyncAccessPath) [list source [file join $dir safe.tcl]] -set auto_index(::safe::PathToken) [list source [file join $dir safe.tcl]] -set auto_index(::safe::TranslatePath) [list source [file join $dir safe.tcl]] -set auto_index(::safe::Log) [list source [file join $dir safe.tcl]] -set auto_index(::safe::CheckFileName) [list source [file join $dir safe.tcl]] -set auto_index(::safe::AliasGlob) [list source [file join $dir safe.tcl]] -set auto_index(::safe::AliasSource) [list source [file join $dir safe.tcl]] -set auto_index(::safe::AliasLoad) [list source [file join $dir safe.tcl]] -set auto_index(::safe::FileInAccessPath) [list source [file join $dir safe.tcl]] -set auto_index(::safe::DirInAccessPath) [list source [file join $dir safe.tcl]] -set auto_index(::safe::Subset) [list source [file join $dir safe.tcl]] -set auto_index(::safe::AliasSubset) [list source [file join $dir safe.tcl]] -set auto_index(::safe::AliasEncoding) [list source [file join $dir safe.tcl]] -set auto_index(tcl_wordBreakAfter) [list source [file join $dir word.tcl]] -set auto_index(tcl_wordBreakBefore) [list source [file join $dir word.tcl]] -set auto_index(tcl_endOfWord) [list source [file join $dir word.tcl]] -set auto_index(tcl_startOfNextWord) [list source [file join $dir word.tcl]] -set auto_index(tcl_startOfPreviousWord) [list source [file join $dir word.tcl]] -set auto_index(::tcl::tm::add) [list source [file join $dir tm.tcl]] -set auto_index(::tcl::tm::remove) [list source [file join $dir tm.tcl]] -set auto_index(::tcl::tm::list) [list source [file join $dir tm.tcl]] -set auto_index(::tcl::tm::Defaults) [list source [file join $dir tm.tcl]] -set auto_index(::tcl::tm::UnknownHandler) [list source [file join $dir tm.tcl]] -set auto_index(::tcl::tm::roots) [list source [file join $dir tm.tcl]] -set auto_index(::tcl::tm::path) [list source [file join $dir tm.tcl]] +set auto_index(auto_reset) [list source -nopkg [file join $dir auto.tcl]] +set auto_index(tcl_findLibrary) [list source -nopkg [file join $dir auto.tcl]] +set auto_index(auto_mkindex) [list source -nopkg [file join $dir auto.tcl]] +set auto_index(auto_mkindex_old) [list source -nopkg [file join $dir auto.tcl]] +set auto_index(::auto_mkindex_parser::init) [list source -nopkg [file join $dir auto.tcl]] +set auto_index(::auto_mkindex_parser::cleanup) [list source -nopkg [file join $dir auto.tcl]] +set auto_index(::auto_mkindex_parser::mkindex) [list source -nopkg [file join $dir auto.tcl]] +set auto_index(::auto_mkindex_parser::hook) [list source -nopkg [file join $dir auto.tcl]] +set auto_index(::auto_mkindex_parser::slavehook) [list source -nopkg [file join $dir auto.tcl]] +set auto_index(::auto_mkindex_parser::command) [list source -nopkg [file join $dir auto.tcl]] +set auto_index(::auto_mkindex_parser::commandInit) [list source -nopkg [file join $dir auto.tcl]] +set auto_index(::auto_mkindex_parser::fullname) [list source -nopkg [file join $dir auto.tcl]] +set auto_index(history) [list source -nopkg [file join $dir history.tcl]] +set auto_index(::tcl::HistAdd) [list source -nopkg [file join $dir history.tcl]] +set auto_index(::tcl::HistKeep) [list source -nopkg [file join $dir history.tcl]] +set auto_index(::tcl::HistClear) [list source -nopkg [file join $dir history.tcl]] +set auto_index(::tcl::HistInfo) [list source -nopkg [file join $dir history.tcl]] +set auto_index(::tcl::HistRedo) [list source -nopkg [file join $dir history.tcl]] +set auto_index(::tcl::HistIndex) [list source -nopkg [file join $dir history.tcl]] +set auto_index(::tcl::HistEvent) [list source -nopkg [file join $dir history.tcl]] +set auto_index(::tcl::HistChange) [list source -nopkg [file join $dir history.tcl]] +set auto_index(pkg_mkIndex) [list source -nopkg [file join $dir package.tcl]] +set auto_index(tclPkgSetup) [list source -nopkg [file join $dir package.tcl]] +set auto_index(tclPkgUnknown) [list source -nopkg [file join $dir package.tcl]] +set auto_index(::tcl::MacOSXPkgUnknown) [list source -nopkg [file join $dir package.tcl]] +set auto_index(::pkg::create) [list source -nopkg [file join $dir package.tcl]] +set auto_index(parray) [list source -nopkg [file join $dir parray.tcl]] +set auto_index(::safe::InterpStatics) [list source -nopkg [file join $dir safe.tcl]] +set auto_index(::safe::InterpNested) [list source -nopkg [file join $dir safe.tcl]] +set auto_index(::safe::interpCreate) [list source -nopkg [file join $dir safe.tcl]] +set auto_index(::safe::interpInit) [list source -nopkg [file join $dir safe.tcl]] +set auto_index(::safe::CheckInterp) [list source -nopkg [file join $dir safe.tcl]] +set auto_index(::safe::interpConfigure) [list source -nopkg [file join $dir safe.tcl]] +set auto_index(::safe::InterpCreate) [list source -nopkg [file join $dir safe.tcl]] +set auto_index(::safe::InterpSetConfig) [list source -nopkg [file join $dir safe.tcl]] +set auto_index(::safe::interpFindInAccessPath) [list source -nopkg [file join $dir safe.tcl]] +set auto_index(::safe::interpAddToAccessPath) [list source -nopkg [file join $dir safe.tcl]] +set auto_index(::safe::InterpInit) [list source -nopkg [file join $dir safe.tcl]] +set auto_index(::safe::AddSubDirs) [list source -nopkg [file join $dir safe.tcl]] +set auto_index(::safe::interpDelete) [list source -nopkg [file join $dir safe.tcl]] +set auto_index(::safe::setLogCmd) [list source -nopkg [file join $dir safe.tcl]] +set auto_index(::safe::SyncAccessPath) [list source -nopkg [file join $dir safe.tcl]] +set auto_index(::safe::PathToken) [list source -nopkg [file join $dir safe.tcl]] +set auto_index(::safe::TranslatePath) [list source -nopkg [file join $dir safe.tcl]] +set auto_index(::safe::Log) [list source -nopkg [file join $dir safe.tcl]] +set auto_index(::safe::CheckFileName) [list source -nopkg [file join $dir safe.tcl]] +set auto_index(::safe::AliasGlob) [list source -nopkg [file join $dir safe.tcl]] +set auto_index(::safe::AliasSource) [list source -nopkg [file join $dir safe.tcl]] +set auto_index(::safe::AliasLoad) [list source -nopkg [file join $dir safe.tcl]] +set auto_index(::safe::FileInAccessPath) [list source -nopkg [file join $dir safe.tcl]] +set auto_index(::safe::DirInAccessPath) [list source -nopkg [file join $dir safe.tcl]] +set auto_index(::safe::Subset) [list source -nopkg [file join $dir safe.tcl]] +set auto_index(::safe::AliasSubset) [list source -nopkg [file join $dir safe.tcl]] +set auto_index(::safe::AliasEncoding) [list source -nopkg [file join $dir safe.tcl]] +set auto_index(tcl_wordBreakAfter) [list source -nopkg [file join $dir word.tcl]] +set auto_index(tcl_wordBreakBefore) [list source -nopkg [file join $dir word.tcl]] +set auto_index(tcl_endOfWord) [list source -nopkg [file join $dir word.tcl]] +set auto_index(tcl_startOfNextWord) [list source -nopkg [file join $dir word.tcl]] +set auto_index(tcl_startOfPreviousWord) [list source -nopkg [file join $dir word.tcl]] +set auto_index(::tcl::tm::add) [list source -nopkg [file join $dir tm.tcl]] +set auto_index(::tcl::tm::remove) [list source -nopkg [file join $dir tm.tcl]] +set auto_index(::tcl::tm::list) [list source -nopkg [file join $dir tm.tcl]] +set auto_index(::tcl::tm::Defaults) [list source -nopkg [file join $dir tm.tcl]] +set auto_index(::tcl::tm::UnknownHandler) [list source -nopkg [file join $dir tm.tcl]] +set auto_index(::tcl::tm::roots) [list source -nopkg [file join $dir tm.tcl]] +set auto_index(::tcl::tm::path) [list source -nopkg [file join $dir tm.tcl]] diff --git a/tests/package.test b/tests/package.test index 7e8a42d..55bba8a 100644 --- a/tests/package.test +++ b/tests/package.test @@ -877,7 +877,7 @@ test package-5.3 {package files} -body { } foo eval package require t 2.4 foo eval {list [package files http] [package files t]} -} -result "[list {}] [file join $tcl_library http http.tcl]" +} -result {{} {}} test package-6.1 {CheckVersion procedure} { package vcompare 1 2.1 -- cgit v0.12 From 1df184e86080a75782e405775728a47498d90595 Mon Sep 17 00:00:00 2001 From: "jan.nijtmans" Date: Mon, 28 Nov 2016 15:29:36 +0000 Subject: slightly simpler --- generic/tclPkg.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/generic/tclPkg.c b/generic/tclPkg.c index c3cc54e..c8f418c 100644 --- a/generic/tclPkg.c +++ b/generic/tclPkg.c @@ -570,8 +570,7 @@ PkgRequireCore( pkgFiles->names = pkgName; code = Tcl_EvalEx(interp, script, -1, TCL_EVAL_GLOBAL); /* Pop the "ifneeded" package name from "tclPkgFiles" assocdata*/ - pkgName = pkgFiles->names; - pkgFiles->names = pkgFiles->names->nextPtr; + pkgFiles->names = pkgName->nextPtr; ckfree(pkgName); Tcl_Release(script); -- cgit v0.12 From 804199d4b7c8ed967e5136c796a658fbbcfbb7c2 Mon Sep 17 00:00:00 2001 From: "jan.nijtmans" Date: Tue, 29 Nov 2016 09:45:20 +0000 Subject: Implement the "package forget" part, which was still missing. Handle the case that a filename contains spaces. --- generic/tclPkg.c | 21 ++++++++++++++++----- 1 file changed, 16 insertions(+), 5 deletions(-) diff --git a/generic/tclPkg.c b/generic/tclPkg.c index c8f418c..42dd08d 100644 --- a/generic/tclPkg.c +++ b/generic/tclPkg.c @@ -243,15 +243,16 @@ void TclPkgFileSeen(Tcl_Interp *interp, const char *fileName) Tcl_HashTable *table = &pkgFiles->table; int new; Tcl_HashEntry *entry = Tcl_CreateHashEntry(table, name, &new); - Tcl_Obj *obj = Tcl_NewStringObj(fileName, -1); + Tcl_Obj *list; if (new) { - Tcl_SetHashValue(entry, obj); - Tcl_IncrRefCount(obj); + list = Tcl_NewObj(); + Tcl_SetHashValue(entry, list); + Tcl_IncrRefCount(list); } else { - Tcl_Obj *list = Tcl_GetHashValue(entry); - Tcl_ListObjAppendElement(interp, list, obj); + list = Tcl_GetHashValue(entry); } + Tcl_ListObjAppendElement(interp, list, Tcl_NewStringObj(fileName, -1)); } } @@ -889,9 +890,19 @@ Tcl_PackageObjCmd( } case PKG_FORGET: { const char *keyString; + PkgFiles *pkgFiles = (PkgFiles *) Tcl_GetAssocData(interp, "tclPkgFiles", NULL); for (i = 2; i < objc; i++) { keyString = TclGetString(objv[i]); + if (pkgFiles) { + hPtr = Tcl_FindHashEntry(&pkgFiles->table, keyString); + if (hPtr) { + Tcl_Obj *obj = Tcl_GetHashValue(hPtr); + Tcl_DeleteHashEntry(hPtr); + Tcl_DecrRefCount(obj); + } + } + hPtr = Tcl_FindHashEntry(&iPtr->packageTable, keyString); if (hPtr == NULL) { continue; -- cgit v0.12 From 2e467a4c9a0cb63cb152e21bb05eb3493ea3ca14 Mon Sep 17 00:00:00 2001 From: limeboy Date: Wed, 14 Dec 2016 15:49:27 +0000 Subject: Make OpenTcpServerEx accept a 'service' string parameter instead of a port. --- generic/tcl.decls | 2 +- generic/tclDecls.h | 7 ++++--- generic/tclIOCmd.c | 25 +++++++++++++++---------- unix/tclUnixSock.c | 9 +++++++-- win/tclWinSock.c | 9 +++++++-- 5 files changed, 34 insertions(+), 18 deletions(-) diff --git a/generic/tcl.decls b/generic/tcl.decls index af496b3..ba047a0 100644 --- a/generic/tcl.decls +++ b/generic/tcl.decls @@ -2328,7 +2328,7 @@ declare 630 { # TIP #456 declare 631 { - Tcl_Channel Tcl_OpenTcpServerEx(Tcl_Interp *interp, int port, + Tcl_Channel Tcl_OpenTcpServerEx(Tcl_Interp *interp, const char *service, const char *host, unsigned int flags, Tcl_TcpAcceptProc *acceptProc, ClientData callbackData) } diff --git a/generic/tclDecls.h b/generic/tclDecls.h index 4810c51..49ac440 100644 --- a/generic/tclDecls.h +++ b/generic/tclDecls.h @@ -1817,8 +1817,9 @@ EXTERN void Tcl_ZlibStreamSetCompressionDictionary( Tcl_ZlibStream zhandle, Tcl_Obj *compressionDictionaryObj); /* 631 */ -EXTERN Tcl_Channel Tcl_OpenTcpServerEx(Tcl_Interp *interp, int port, - const char *host, unsigned int flags, +EXTERN Tcl_Channel Tcl_OpenTcpServerEx(Tcl_Interp *interp, + const char *service, const char *host, + unsigned int flags, Tcl_TcpAcceptProc *acceptProc, ClientData callbackData); @@ -2487,7 +2488,7 @@ typedef struct TclStubs { void * (*tcl_FindSymbol) (Tcl_Interp *interp, Tcl_LoadHandle handle, const char *symbol); /* 628 */ int (*tcl_FSUnloadFile) (Tcl_Interp *interp, Tcl_LoadHandle handlePtr); /* 629 */ void (*tcl_ZlibStreamSetCompressionDictionary) (Tcl_ZlibStream zhandle, Tcl_Obj *compressionDictionaryObj); /* 630 */ - Tcl_Channel (*tcl_OpenTcpServerEx) (Tcl_Interp *interp, int port, const char *host, unsigned int flags, Tcl_TcpAcceptProc *acceptProc, ClientData callbackData); /* 631 */ + Tcl_Channel (*tcl_OpenTcpServerEx) (Tcl_Interp *interp, const char *service, const char *host, unsigned int flags, Tcl_TcpAcceptProc *acceptProc, ClientData callbackData); /* 631 */ } TclStubs; extern const TclStubs *tclStubsPtr; diff --git a/generic/tclIOCmd.c b/generic/tclIOCmd.c index d6637a0..951fb5a 100644 --- a/generic/tclIOCmd.c +++ b/generic/tclIOCmd.c @@ -1492,9 +1492,9 @@ Tcl_SocketObjCmd( SKT_ASYNC, SKT_MYADDR, SKT_MYPORT, SKT_REUSEADDR, SKT_REUSEPORT, SKT_SERVER }; - int optionIndex, a, server = 0, port, myport = 0, async = 0, boolTmp; + int optionIndex, a, server = 0, myport = 0, async = 0, boolTmp; unsigned int flags = 0; - const char *host, *myaddr = NULL; + const char *host, *port, *myaddr = NULL; Tcl_Obj *script = NULL; Tcl_Channel chan; @@ -1628,15 +1628,14 @@ Tcl_SocketObjCmd( return TCL_ERROR; } - if (a == objc-1) { - if (TclSockGetPort(interp, TclGetString(objv[a]), "tcp", - &port) != TCL_OK) { - return TCL_ERROR; - } - } else { + // All the arguments should have been parsed by now, 'a' points to the last + // one, the port number. + if (a != objc-1) { goto wrongNumArgs; } + port = TclGetString(objv[a]); + if (server) { AcceptCallback *acceptCallbackPtr = ckalloc(sizeof(AcceptCallback)); @@ -1646,7 +1645,7 @@ Tcl_SocketObjCmd( acceptCallbackPtr->interp = interp; chan = Tcl_OpenTcpServerEx(interp, port, host, flags, AcceptCallbackProc, - acceptCallbackPtr); + acceptCallbackPtr); if (chan == NULL) { Tcl_DecrRefCount(script); ckfree(acceptCallbackPtr); @@ -1670,7 +1669,13 @@ Tcl_SocketObjCmd( Tcl_CreateCloseHandler(chan, TcpServerCloseProc, acceptCallbackPtr); } else { - chan = Tcl_OpenTcpClient(interp, port, host, myaddr, myport, async); + int portNum; + + if (TclSockGetPort(interp, port, "tcp", &portNum) != TCL_OK) { + return TCL_ERROR; + } + + chan = Tcl_OpenTcpClient(interp, portNum, host, myaddr, myport, async); if (chan == NULL) { return TCL_ERROR; } diff --git a/unix/tclUnixSock.c b/unix/tclUnixSock.c index 187c157..8e97543 100644 --- a/unix/tclUnixSock.c +++ b/unix/tclUnixSock.c @@ -1422,7 +1422,7 @@ TclpMakeTcpClientChannelMode( Tcl_Channel Tcl_OpenTcpServerEx( Tcl_Interp *interp, /* For error reporting - may be NULL. */ - int port, /* Port number to open. */ + const char *service, /* Port number to open. */ const char *myHost, /* Name of local host. */ unsigned int flags, /* Flags. */ Tcl_TcpAcceptProc *acceptProc, @@ -1430,7 +1430,7 @@ Tcl_OpenTcpServerEx( * clients. */ ClientData acceptProcData) /* Data for the callback. */ { - int status = 0, sock = -1, optvalue, chosenport; + int status = 0, sock = -1, optvalue, port, chosenport; struct addrinfo *addrlist = NULL, *addrPtr; /* socket address */ TcpState *statePtr = NULL; char channelName[SOCK_CHAN_LENGTH]; @@ -1476,6 +1476,11 @@ Tcl_OpenTcpServerEx( retry++; chosenport = 0; + if (TclSockGetPort(interp, service, "tcp", &port) != TCL_OK) { + errorMsg = "invalid port number"; + goto error; + } + if (!TclCreateSocketAddress(interp, &addrlist, myHost, port, 1, &errorMsg)) { my_errno = errno; goto error; diff --git a/win/tclWinSock.c b/win/tclWinSock.c index af22cf8..5e0d7c8 100644 --- a/win/tclWinSock.c +++ b/win/tclWinSock.c @@ -2037,7 +2037,7 @@ Tcl_MakeTcpClientChannel( Tcl_Channel Tcl_OpenTcpServerEx( Tcl_Interp *interp, /* For error reporting - may be NULL. */ - int port, /* Port number to open. */ + const char *service, /* Port number to open. */ const char *myHost, /* Name of local host. */ unsigned int flags, /* Flags. */ Tcl_TcpAcceptProc *acceptProc, @@ -2053,7 +2053,7 @@ Tcl_OpenTcpServerEx( char channelName[SOCK_CHAN_LENGTH]; u_long flag = 1; /* Indicates nonblocking mode. */ const char *errorMsg = NULL; - int optvalue; + int optvalue, port; if (TclpHasSockets(interp) != TCL_OK) { return NULL; @@ -2073,6 +2073,11 @@ Tcl_OpenTcpServerEx( * Construct the addresses for each end of the socket. */ + if (TclSockGetPort(interp, service, "tcp", &port) != TCL_OK) { + errorMsg = "invalid port number"; + goto error; + } + if (!TclCreateSocketAddress(interp, &addrlist, myHost, port, 1, &errorMsg)) { goto error; } -- cgit v0.12 From caf8932e2eb878f8cf7c759009c944475d513325 Mon Sep 17 00:00:00 2001 From: limeboy Date: Wed, 14 Dec 2016 15:52:21 +0000 Subject: Fix for the argument parsing phase in the [socket] command. --- generic/tclIOCmd.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/generic/tclIOCmd.c b/generic/tclIOCmd.c index 951fb5a..0eb8f99 100644 --- a/generic/tclIOCmd.c +++ b/generic/tclIOCmd.c @@ -1493,7 +1493,7 @@ Tcl_SocketObjCmd( SKT_SERVER }; int optionIndex, a, server = 0, myport = 0, async = 0, boolTmp; - unsigned int flags = 0; + unsigned int flags = TCL_TCPSERVER_REUSEADDR; const char *host, *port, *myaddr = NULL; Tcl_Obj *script = NULL; Tcl_Channel chan; @@ -1552,7 +1552,6 @@ Tcl_SocketObjCmd( return TCL_ERROR; } server = 1; - flags = TCL_TCPSERVER_REUSEADDR; a++; if (a >= objc) { Tcl_SetObjResult(interp, Tcl_NewStringObj( -- cgit v0.12 From cbe4a7dae5d19875cc5634ba423e5a2942191946 Mon Sep 17 00:00:00 2001 From: limeboy Date: Wed, 14 Dec 2016 15:59:43 +0000 Subject: Adjust OpenTcpServer for the latest changes to OpenTcpServerEx --- generic/tclIOSock.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/generic/tclIOSock.c b/generic/tclIOSock.c index b6e99ba..8ad268a 100644 --- a/generic/tclIOSock.c +++ b/generic/tclIOSock.c @@ -304,7 +304,11 @@ Tcl_Channel Tcl_OpenTcpServer(Tcl_Interp *interp, int port, const char *host, Tcl_TcpAcceptProc *acceptProc, ClientData callbackData) { - return Tcl_OpenTcpServerEx(interp, port, host, TCL_TCPSERVER_REUSEADDR, + char portbuf[TCL_INTEGER_SPACE]; + + TclFormatInt(portbuf, port); + + return Tcl_OpenTcpServerEx(interp, portbuf, host, TCL_TCPSERVER_REUSEADDR, acceptProc, callbackData); } -- cgit v0.12 From dfbc8a629679c709f7f7661bbdc2094f8bb43ff7 Mon Sep 17 00:00:00 2001 From: limeboy Date: Wed, 14 Dec 2016 16:03:53 +0000 Subject: Update the documentation --- doc/OpenTcp.3 | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/doc/OpenTcp.3 b/doc/OpenTcp.3 index a39f6f6..10a4815 100644 --- a/doc/OpenTcp.3 +++ b/doc/OpenTcp.3 @@ -24,7 +24,7 @@ Tcl_Channel \fBTcl_OpenTcpServer\fR(\fIinterp, port, myaddr, proc, clientData\fR) .sp Tcl_Channel -\fBTcl_OpenTcpServerEx\fR(\fIinterp, port, myaddr, flags, proc, clientData\fR) +\fBTcl_OpenTcpServerEx\fR(\fIinterp, service, myaddr, flags, proc, clientData\fR) .sp .SH ARGUMENTS .AS Tcl_TcpAcceptProc clientData @@ -33,6 +33,9 @@ Tcl interpreter to use for error reporting. If non-NULL and an error occurs, an error message is left in the interpreter's result. .AP int port in A port number to connect to as a client or to listen on as a server. +.AP "const char" *service in +A string specifying the port number to connect to as a client or to listen on as + a server. .AP "const char" *host in A string specifying a host name or address for the remote end of the connection. .AP int myport in -- cgit v0.12 From e574cfbc71e0788597182949c37f951c56c1d506 Mon Sep 17 00:00:00 2001 From: limeboy Date: Tue, 20 Dec 2016 10:22:22 +0000 Subject: Correct the handling of -server and its options. --- generic/tclIOCmd.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/generic/tclIOCmd.c b/generic/tclIOCmd.c index 0eb8f99..fb37ff6 100644 --- a/generic/tclIOCmd.c +++ b/generic/tclIOCmd.c @@ -1493,7 +1493,7 @@ Tcl_SocketObjCmd( SKT_SERVER }; int optionIndex, a, server = 0, myport = 0, async = 0, boolTmp; - unsigned int flags = TCL_TCPSERVER_REUSEADDR; + unsigned int flags = 0; const char *host, *port, *myaddr = NULL; Tcl_Obj *script = NULL; Tcl_Channel chan; @@ -1552,6 +1552,7 @@ Tcl_SocketObjCmd( return TCL_ERROR; } server = 1; + flags |= TCL_TCPSERVER_REUSEADDR; a++; if (a >= objc) { Tcl_SetObjResult(interp, Tcl_NewStringObj( -- cgit v0.12 From f208386ff790200bd00384f9387957738c69479e Mon Sep 17 00:00:00 2001 From: limeboy Date: Tue, 20 Dec 2016 10:56:53 +0000 Subject: Decouple the switch handling. --- generic/tclIOCmd.c | 25 ++++++++++--------------- 1 file changed, 10 insertions(+), 15 deletions(-) diff --git a/generic/tclIOCmd.c b/generic/tclIOCmd.c index fb37ff6..e64e31d 100644 --- a/generic/tclIOCmd.c +++ b/generic/tclIOCmd.c @@ -1492,7 +1492,8 @@ Tcl_SocketObjCmd( SKT_ASYNC, SKT_MYADDR, SKT_MYPORT, SKT_REUSEADDR, SKT_REUSEPORT, SKT_SERVER }; - int optionIndex, a, server = 0, myport = 0, async = 0, boolTmp; + int optionIndex, a, server = 0, myport = 0, async = 0, reusep = 0, + reusea = 0; unsigned int flags = 0; const char *host, *port, *myaddr = NULL; Tcl_Obj *script = NULL; @@ -1552,7 +1553,8 @@ Tcl_SocketObjCmd( return TCL_ERROR; } server = 1; - flags |= TCL_TCPSERVER_REUSEADDR; + /* [TIP#456] Set for backward-compatibility. */ + reusea = 1; a++; if (a >= objc) { Tcl_SetObjResult(interp, Tcl_NewStringObj( @@ -1568,14 +1570,9 @@ Tcl_SocketObjCmd( "no argument given for -reuseaddr option", -1)); return TCL_ERROR; } - if (Tcl_GetBooleanFromObj(interp, objv[a], &boolTmp) != TCL_OK) { + if (Tcl_GetBooleanFromObj(interp, objv[a], &reusea) != TCL_OK) { return TCL_ERROR; } - if (boolTmp) { - flags |= TCL_TCPSERVER_REUSEADDR; - } else { - flags &= ~TCL_TCPSERVER_REUSEADDR; - } break; case SKT_REUSEPORT: a++; @@ -1584,14 +1581,9 @@ Tcl_SocketObjCmd( "no argument given for -reuseport option", -1)); return TCL_ERROR; } - if (Tcl_GetBooleanFromObj(interp, objv[a], &boolTmp) != TCL_OK) { + if (Tcl_GetBooleanFromObj(interp, objv[a], &reusep) != TCL_OK) { return TCL_ERROR; } - if (boolTmp) { - flags |= TCL_TCPSERVER_REUSEPORT; - } else { - flags &= ~TCL_TCPSERVER_REUSEPORT; - } break; default: Tcl_Panic("Tcl_SocketObjCmd: bad option index to SocketOptions"); @@ -1621,13 +1613,16 @@ Tcl_SocketObjCmd( return TCL_ERROR; } - if (!server && flags != 0) { + if (!server && (reusea != 0 || reusep != 0)) { Tcl_SetObjResult(interp, Tcl_NewStringObj( "options -reuseaddr and -reuseport are only valid for servers", -1)); return TCL_ERROR; } + flags |= reusea ? TCL_TCPSERVER_REUSEADDR : 0; + flags |= reusep ? TCL_TCPSERVER_REUSEPORT : 0; + // All the arguments should have been parsed by now, 'a' points to the last // one, the port number. if (a != objc-1) { -- cgit v0.12 From aba0a7a6cd1bcf03d86534287dfe32ab48b646fe Mon Sep 17 00:00:00 2001 From: "jan.nijtmans" Date: Tue, 20 Dec 2016 12:35:33 +0000 Subject: Make options -reuseaddr/-reuseport forbidden without -server, no matter the value being true or false. Some additional test-cases. --- generic/tclIOCmd.c | 12 +++++------- tests/socket.test | 12 ++++++++++++ 2 files changed, 17 insertions(+), 7 deletions(-) diff --git a/generic/tclIOCmd.c b/generic/tclIOCmd.c index e64e31d..682eaf4 100644 --- a/generic/tclIOCmd.c +++ b/generic/tclIOCmd.c @@ -1492,8 +1492,8 @@ Tcl_SocketObjCmd( SKT_ASYNC, SKT_MYADDR, SKT_MYPORT, SKT_REUSEADDR, SKT_REUSEPORT, SKT_SERVER }; - int optionIndex, a, server = 0, myport = 0, async = 0, reusep = 0, - reusea = 0; + int optionIndex, a, server = 0, myport = 0, async = 0, reusep = -1, + reusea = -1; unsigned int flags = 0; const char *host, *port, *myaddr = NULL; Tcl_Obj *script = NULL; @@ -1553,8 +1553,6 @@ Tcl_SocketObjCmd( return TCL_ERROR; } server = 1; - /* [TIP#456] Set for backward-compatibility. */ - reusea = 1; a++; if (a >= objc) { Tcl_SetObjResult(interp, Tcl_NewStringObj( @@ -1613,15 +1611,15 @@ Tcl_SocketObjCmd( return TCL_ERROR; } - if (!server && (reusea != 0 || reusep != 0)) { + if (!server && (reusea != -1 || reusep != -1)) { Tcl_SetObjResult(interp, Tcl_NewStringObj( "options -reuseaddr and -reuseport are only valid for servers", -1)); return TCL_ERROR; } - flags |= reusea ? TCL_TCPSERVER_REUSEADDR : 0; - flags |= reusep ? TCL_TCPSERVER_REUSEPORT : 0; + if (reusea!=0) flags |= TCL_TCPSERVER_REUSEADDR; + if (reusep==1) flags |= TCL_TCPSERVER_REUSEPORT; // All the arguments should have been parsed by now, 'a' points to the last // one, the port number. diff --git a/tests/socket.test b/tests/socket.test index c1076eb..80b0251 100644 --- a/tests/socket.test +++ b/tests/socket.test @@ -306,8 +306,20 @@ test socket_$af-1.15 {arg parsing for socket command} -constraints [list socket socket -reuseaddr yes 4242 } -returnCodes error -result {options -reuseaddr and -reuseport are only valid for servers} test socket_$af-1.16 {arg parsing for socket command} -constraints [list socket supported_$af] -body { + socket -reuseaddr no 4242 +} -returnCodes error -result {options -reuseaddr and -reuseport are only valid for servers} +test socket_$af-1.17 {arg parsing for socket command} -constraints [list socket supported_$af] -body { + socket -reuseaddr +} -returnCodes error -result {no argument given for -reuseaddr option} +test socket_$af-1.18 {arg parsing for socket command} -constraints [list socket supported_$af] -body { socket -reuseport yes 4242 } -returnCodes error -result {options -reuseaddr and -reuseport are only valid for servers} +test socket_$af-1.19 {arg parsing for socket command} -constraints [list socket supported_$af] -body { + socket -reuseport no 4242 +} -returnCodes error -result {options -reuseaddr and -reuseport are only valid for servers} +test socket_$af-1.20 {arg parsing for socket command} -constraints [list socket supported_$af] -body { + socket -reuseport +} -returnCodes error -result {no argument given for -reuseport option} set path(script) [makeFile {} script] -- cgit v0.12 From a2c66d61f0e05792f61868e5e1228672b38d555f Mon Sep 17 00:00:00 2001 From: limeboy Date: Sun, 1 Jan 2017 22:19:26 +0000 Subject: Make the code slightly more pleasing to the eyes. --- generic/tclIOCmd.c | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/generic/tclIOCmd.c b/generic/tclIOCmd.c index 682eaf4..1bd3fe7 100644 --- a/generic/tclIOCmd.c +++ b/generic/tclIOCmd.c @@ -1618,8 +1618,16 @@ Tcl_SocketObjCmd( return TCL_ERROR; } - if (reusea!=0) flags |= TCL_TCPSERVER_REUSEADDR; - if (reusep==1) flags |= TCL_TCPSERVER_REUSEPORT; + // Set the options to their default value if the user didn't override their + // value. + if (reusep == -1) reusep = 0; + if (reusea == -1) reusea = 1; + + // Build the bitset with the flags values. + if (reusea) + flags |= TCL_TCPSERVER_REUSEADDR; + if (reusep) + flags |= TCL_TCPSERVER_REUSEPORT; // All the arguments should have been parsed by now, 'a' points to the last // one, the port number. -- cgit v0.12 From 76070165e3893ae783285810de732bb0a2a3ecaa Mon Sep 17 00:00:00 2001 From: "jan.nijtmans" Date: Tue, 3 Jan 2017 10:43:32 +0000 Subject: Update zlib to version 1.2.10. Dll's and *.lib files not updated yet --- .fossil-settings/binary-glob | 1 + .fossil-settings/crnl-glob | 3 ++ compat/zlib/CMakeLists.txt | 2 +- compat/zlib/ChangeLog | 7 ++++ compat/zlib/Makefile.in | 7 +++- compat/zlib/README | 6 ++-- compat/zlib/contrib/delphi/ZLib.pas | 2 +- compat/zlib/contrib/dotzlib/DotZLib/UnitTests.cs | 2 +- compat/zlib/contrib/infback9/inftree9.c | 6 ++-- compat/zlib/contrib/minizip/configure.ac | 2 +- compat/zlib/contrib/pascal/zlibpas.pas | 4 +-- compat/zlib/contrib/vstudio/readme.txt | 4 +-- compat/zlib/contrib/vstudio/vc10/zlib.rc | 8 ++--- compat/zlib/contrib/vstudio/vc11/zlib.rc | 8 ++--- compat/zlib/contrib/vstudio/vc12/zlib.rc | 8 ++--- compat/zlib/contrib/vstudio/vc14/zlib.rc | 8 ++--- compat/zlib/contrib/vstudio/vc9/zlib.rc | 8 ++--- compat/zlib/deflate.c | 42 ++++++++++++----------- compat/zlib/gzlib.c | 8 ++--- compat/zlib/gzwrite.c | 1 + compat/zlib/inffast.c | 4 ++- compat/zlib/inftrees.c | 6 ++-- compat/zlib/os400/README400 | 2 +- compat/zlib/os400/zlib.inc | 8 ++--- compat/zlib/qnx/package.qpg | 10 +++--- compat/zlib/treebuild.xml | 4 +-- compat/zlib/win32/README-WIN32.txt | 4 +-- compat/zlib/zlib.3 | 6 ++-- compat/zlib/zlib.3.pdf | Bin 19422 -> 19324 bytes compat/zlib/zlib.h | 25 +++++++------- compat/zlib/zutil.c | 2 +- 31 files changed, 115 insertions(+), 93 deletions(-) diff --git a/.fossil-settings/binary-glob b/.fossil-settings/binary-glob index ca85874..509939c 100644 --- a/.fossil-settings/binary-glob +++ b/.fossil-settings/binary-glob @@ -1,3 +1,4 @@ +compat/zlib/zlib.3.pdf *.bmp *.gif *.png diff --git a/.fossil-settings/crnl-glob b/.fossil-settings/crnl-glob index c014320..cc8dd26 100644 --- a/.fossil-settings/crnl-glob +++ b/.fossil-settings/crnl-glob @@ -1,3 +1,6 @@ +compat/zlib/contrib/dotzlib/DotZLib/UnitTests.cs +compat/zlib/contrib/vstudio/readme.txt +compat/zlib/contrib/vstudio/*/zlib.rc tools/tcl.hpj.in tools/tcl.wse.in win/buildall.vc.bat diff --git a/compat/zlib/CMakeLists.txt b/compat/zlib/CMakeLists.txt index 14411a4..1a954a6 100644 --- a/compat/zlib/CMakeLists.txt +++ b/compat/zlib/CMakeLists.txt @@ -3,7 +3,7 @@ set(CMAKE_ALLOW_LOOSE_LOOP_CONSTRUCTS ON) project(zlib C) -set(VERSION "1.2.9") +set(VERSION "1.2.10") option(ASM686 "Enable building i686 assembly implementation") option(AMD64 "Enable building amd64 assembly implementation") diff --git a/compat/zlib/ChangeLog b/compat/zlib/ChangeLog index 63d0495..fed9adb 100644 --- a/compat/zlib/ChangeLog +++ b/compat/zlib/ChangeLog @@ -1,6 +1,13 @@ ChangeLog file for zlib +Changes in 1.2.10 (2 Jan 2017) +- Avoid warnings on snprintf() return value +- Fix bug in deflate_stored() for zero-length input +- Fix bug in gzwrite.c that produced corrupt gzip files +- Remove files to be installed before copying them in Makefile.in +- Add warnings when compiling with assembler code + Changes in 1.2.9 (31 Dec 2016) - Fix contrib/minizip to permit unzipping with desktop API [Zouzou] - Improve contrib/blast to return unused bytes diff --git a/compat/zlib/Makefile.in b/compat/zlib/Makefile.in index c8b487c..1852192 100644 --- a/compat/zlib/Makefile.in +++ b/compat/zlib/Makefile.in @@ -32,7 +32,7 @@ CPP=$(CC) -E STATICLIB=libz.a SHAREDLIB=libz.so -SHAREDLIBV=libz.so.1.2.9 +SHAREDLIBV=libz.so.1.2.10 SHAREDLIBM=libz.so.1 LIBS=$(STATICLIB) $(SHAREDLIBV) @@ -309,10 +309,12 @@ install-libs: $(LIBS) -@if [ ! -d $(DESTDIR)$(sharedlibdir) ]; then mkdir -p $(DESTDIR)$(sharedlibdir); fi -@if [ ! -d $(DESTDIR)$(man3dir) ]; then mkdir -p $(DESTDIR)$(man3dir); fi -@if [ ! -d $(DESTDIR)$(pkgconfigdir) ]; then mkdir -p $(DESTDIR)$(pkgconfigdir); fi + rm -f $(DESTDIR)$(libdir)/$(STATICLIB) cp $(STATICLIB) $(DESTDIR)$(libdir) chmod 644 $(DESTDIR)$(libdir)/$(STATICLIB) -@($(RANLIB) $(DESTDIR)$(libdir)/libz.a || true) >/dev/null 2>&1 -@if test -n "$(SHAREDLIBV)"; then \ + rm -f $(DESTDIR)$(sharedlibdir)/$(SHAREDLIBV); \ cp $(SHAREDLIBV) $(DESTDIR)$(sharedlibdir); \ echo "cp $(SHAREDLIBV) $(DESTDIR)$(sharedlibdir)"; \ chmod 755 $(DESTDIR)$(sharedlibdir)/$(SHAREDLIBV); \ @@ -322,8 +324,10 @@ install-libs: $(LIBS) ln -s $(SHAREDLIBV) $(DESTDIR)$(sharedlibdir)/$(SHAREDLIBM); \ ($(LDCONFIG) || true) >/dev/null 2>&1; \ fi + rm -f $(DESTDIR)$(man3dir)/zlib.3 cp $(SRCDIR)zlib.3 $(DESTDIR)$(man3dir) chmod 644 $(DESTDIR)$(man3dir)/zlib.3 + rm -f $(DESTDIR)$(pkgconfigdir)/zlib.pc cp zlib.pc $(DESTDIR)$(pkgconfigdir) chmod 644 $(DESTDIR)$(pkgconfigdir)/zlib.pc # The ranlib in install is needed on NeXTSTEP which checks file times @@ -331,6 +335,7 @@ install-libs: $(LIBS) install: install-libs -@if [ ! -d $(DESTDIR)$(includedir) ]; then mkdir -p $(DESTDIR)$(includedir); fi + rm -f $(DESTDIR)$(includedir)/zlib.h $(DESTDIR)$(includedir)/zconf.h cp $(SRCDIR)zlib.h zconf.h $(DESTDIR)$(includedir) chmod 644 $(DESTDIR)$(includedir)/zlib.h $(DESTDIR)$(includedir)/zconf.h diff --git a/compat/zlib/README b/compat/zlib/README index 8002f39..e2250bd 100644 --- a/compat/zlib/README +++ b/compat/zlib/README @@ -1,6 +1,6 @@ ZLIB DATA COMPRESSION LIBRARY -zlib 1.2.9 is a general purpose data compression library. All the code is +zlib 1.2.10 is a general purpose data compression library. All the code is thread safe. The data format used by the zlib library is described by RFCs (Request for Comments) 1950 to 1952 in the files http://tools.ietf.org/html/rfc1950 (zlib format), rfc1951 (deflate format) and @@ -31,7 +31,7 @@ Mark Nelson wrote an article about zlib for the Jan. 1997 issue of Dr. Dobb's Journal; a copy of the article is available at http://marknelson.us/1997/01/01/zlib-engine/ . -The changes made in version 1.2.9 are documented in the file ChangeLog. +The changes made in version 1.2.10 are documented in the file ChangeLog. Unsupported third party contributions are provided in directory contrib/ . @@ -84,7 +84,7 @@ Acknowledgments: Copyright notice: - (C) 1995-2016 Jean-loup Gailly and Mark Adler + (C) 1995-2017 Jean-loup Gailly and Mark Adler This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/compat/zlib/contrib/delphi/ZLib.pas b/compat/zlib/contrib/delphi/ZLib.pas index 7a3cb66..e9d72f0 100644 --- a/compat/zlib/contrib/delphi/ZLib.pas +++ b/compat/zlib/contrib/delphi/ZLib.pas @@ -152,7 +152,7 @@ procedure DecompressToUserBuf(const InBuf: Pointer; InBytes: Integer; const OutBuf: Pointer; BufSize: Integer); const - zlib_version = '1.2.9'; + zlib_version = '1.2.10'; type EZlibError = class(Exception); diff --git a/compat/zlib/contrib/dotzlib/DotZLib/UnitTests.cs b/compat/zlib/contrib/dotzlib/DotZLib/UnitTests.cs index 3d156f4..a0e3985 100644 --- a/compat/zlib/contrib/dotzlib/DotZLib/UnitTests.cs +++ b/compat/zlib/contrib/dotzlib/DotZLib/UnitTests.cs @@ -156,7 +156,7 @@ namespace DotZLibTests public void Info_Version() { Info info = new Info(); - Assert.AreEqual("1.2.9", Info.Version); + Assert.AreEqual("1.2.10", Info.Version); Assert.AreEqual(32, info.SizeOfUInt); Assert.AreEqual(32, info.SizeOfULong); Assert.AreEqual(32, info.SizeOfPointer); diff --git a/compat/zlib/contrib/infback9/inftree9.c b/compat/zlib/contrib/infback9/inftree9.c index 2103aee..ea56047 100644 --- a/compat/zlib/contrib/infback9/inftree9.c +++ b/compat/zlib/contrib/infback9/inftree9.c @@ -1,5 +1,5 @@ /* inftree9.c -- generate Huffman trees for efficient decoding - * Copyright (C) 1995-2016 Mark Adler + * Copyright (C) 1995-2017 Mark Adler * For conditions of distribution and use, see copyright notice in zlib.h */ @@ -9,7 +9,7 @@ #define MAXBITS 15 const char inflate9_copyright[] = - " inflate9 1.2.9 Copyright 1995-2016 Mark Adler "; + " inflate9 1.2.10 Copyright 1995-2017 Mark Adler "; /* If you use the zlib library in a product, an acknowledgment is welcome in the documentation of your product. If for some reason you cannot @@ -64,7 +64,7 @@ unsigned short FAR *work; static const unsigned short lext[31] = { /* Length codes 257..285 extra */ 128, 128, 128, 128, 128, 128, 128, 128, 129, 129, 129, 129, 130, 130, 130, 130, 131, 131, 131, 131, 132, 132, 132, 132, - 133, 133, 133, 133, 144, 192, 79}; + 133, 133, 133, 133, 144, 192, 202}; static const unsigned short dbase[32] = { /* Distance codes 0..31 base */ 1, 2, 3, 4, 5, 7, 9, 13, 17, 25, 33, 49, 65, 97, 129, 193, 257, 385, 513, 769, 1025, 1537, 2049, 3073, diff --git a/compat/zlib/contrib/minizip/configure.ac b/compat/zlib/contrib/minizip/configure.ac index 54d823f..bbb2283 100644 --- a/compat/zlib/contrib/minizip/configure.ac +++ b/compat/zlib/contrib/minizip/configure.ac @@ -1,7 +1,7 @@ # -*- Autoconf -*- # Process this file with autoconf to produce a configure script. -AC_INIT([minizip], [1.2.9], [bugzilla.redhat.com]) +AC_INIT([minizip], [1.2.10], [bugzilla.redhat.com]) AC_CONFIG_SRCDIR([minizip.c]) AM_INIT_AUTOMAKE([foreign]) LT_INIT diff --git a/compat/zlib/contrib/pascal/zlibpas.pas b/compat/zlib/contrib/pascal/zlibpas.pas index aebaea0..2330898 100644 --- a/compat/zlib/contrib/pascal/zlibpas.pas +++ b/compat/zlib/contrib/pascal/zlibpas.pas @@ -10,8 +10,8 @@ unit zlibpas; interface const - ZLIB_VERSION = '1.2.9'; - ZLIB_VERNUM = $1290; + ZLIB_VERSION = '1.2.10'; + ZLIB_VERNUM = $12a0; type alloc_func = function(opaque: Pointer; items, size: Integer): Pointer; diff --git a/compat/zlib/contrib/vstudio/readme.txt b/compat/zlib/contrib/vstudio/readme.txt index 3954bc4..98d8a05 100644 --- a/compat/zlib/contrib/vstudio/readme.txt +++ b/compat/zlib/contrib/vstudio/readme.txt @@ -1,4 +1,4 @@ -Building instructions for the DLL versions of Zlib 1.2.9 +Building instructions for the DLL versions of Zlib 1.2.10 ======================================================== This directory contains projects that build zlib and minizip using @@ -75,4 +75,4 @@ Gilles Vollant info@winimage.com Visual Studio 2013 and 2015 Projects from Sean Hunt -seandhunt_7@yahoo.com \ No newline at end of file +seandhunt_7@yahoo.com diff --git a/compat/zlib/contrib/vstudio/vc10/zlib.rc b/compat/zlib/contrib/vstudio/vc10/zlib.rc index d846820..f1c19bc 100644 --- a/compat/zlib/contrib/vstudio/vc10/zlib.rc +++ b/compat/zlib/contrib/vstudio/vc10/zlib.rc @@ -2,8 +2,8 @@ #define IDR_VERSION1 1 IDR_VERSION1 VERSIONINFO MOVEABLE IMPURE LOADONCALL DISCARDABLE - FILEVERSION 1, 2, 9, 0 - PRODUCTVERSION 1, 2, 9, 0 + FILEVERSION 1, 2, 10, 0 + PRODUCTVERSION 1, 2, 10, 0 FILEFLAGSMASK VS_FFI_FILEFLAGSMASK FILEFLAGS 0 FILEOS VOS_DOS_WINDOWS32 @@ -17,12 +17,12 @@ BEGIN BEGIN VALUE "FileDescription", "zlib data compression and ZIP file I/O library\0" - VALUE "FileVersion", "1.2.9\0" + VALUE "FileVersion", "1.2.10\0" VALUE "InternalName", "zlib\0" VALUE "OriginalFilename", "zlibwapi.dll\0" VALUE "ProductName", "ZLib.DLL\0" VALUE "Comments","DLL support by Alessandro Iacopetti & Gilles Vollant\0" - VALUE "LegalCopyright", "(C) 1995-2016 Jean-loup Gailly & Mark Adler\0" + VALUE "LegalCopyright", "(C) 1995-2017 Jean-loup Gailly & Mark Adler\0" END END BLOCK "VarFileInfo" diff --git a/compat/zlib/contrib/vstudio/vc11/zlib.rc b/compat/zlib/contrib/vstudio/vc11/zlib.rc index d846820..f1c19bc 100644 --- a/compat/zlib/contrib/vstudio/vc11/zlib.rc +++ b/compat/zlib/contrib/vstudio/vc11/zlib.rc @@ -2,8 +2,8 @@ #define IDR_VERSION1 1 IDR_VERSION1 VERSIONINFO MOVEABLE IMPURE LOADONCALL DISCARDABLE - FILEVERSION 1, 2, 9, 0 - PRODUCTVERSION 1, 2, 9, 0 + FILEVERSION 1, 2, 10, 0 + PRODUCTVERSION 1, 2, 10, 0 FILEFLAGSMASK VS_FFI_FILEFLAGSMASK FILEFLAGS 0 FILEOS VOS_DOS_WINDOWS32 @@ -17,12 +17,12 @@ BEGIN BEGIN VALUE "FileDescription", "zlib data compression and ZIP file I/O library\0" - VALUE "FileVersion", "1.2.9\0" + VALUE "FileVersion", "1.2.10\0" VALUE "InternalName", "zlib\0" VALUE "OriginalFilename", "zlibwapi.dll\0" VALUE "ProductName", "ZLib.DLL\0" VALUE "Comments","DLL support by Alessandro Iacopetti & Gilles Vollant\0" - VALUE "LegalCopyright", "(C) 1995-2016 Jean-loup Gailly & Mark Adler\0" + VALUE "LegalCopyright", "(C) 1995-2017 Jean-loup Gailly & Mark Adler\0" END END BLOCK "VarFileInfo" diff --git a/compat/zlib/contrib/vstudio/vc12/zlib.rc b/compat/zlib/contrib/vstudio/vc12/zlib.rc index 4f6396d..ef38298 100644 --- a/compat/zlib/contrib/vstudio/vc12/zlib.rc +++ b/compat/zlib/contrib/vstudio/vc12/zlib.rc @@ -2,8 +2,8 @@ #define IDR_VERSION1 1 IDR_VERSION1 VERSIONINFO MOVEABLE IMPURE LOADONCALL DISCARDABLE - FILEVERSION 1, 2, 9, 0 - PRODUCTVERSION 1, 2, 9, 0 + FILEVERSION 1, 2, 10, 0 + PRODUCTVERSION 1, 2, 10, 0 FILEFLAGSMASK VS_FFI_FILEFLAGSMASK FILEFLAGS 0 FILEOS VOS_DOS_WINDOWS32 @@ -17,12 +17,12 @@ BEGIN BEGIN VALUE "FileDescription", "zlib data compression and ZIP file I/O library\0" - VALUE "FileVersion", "1.2.8.1\0" + VALUE "FileVersion", "1.2.10\0" VALUE "InternalName", "zlib\0" VALUE "OriginalFilename", "zlibwapi.dll\0" VALUE "ProductName", "ZLib.DLL\0" VALUE "Comments","DLL support by Alessandro Iacopetti & Gilles Vollant\0" - VALUE "LegalCopyright", "(C) 1995-2013 Jean-loup Gailly & Mark Adler\0" + VALUE "LegalCopyright", "(C) 1995-2017 Jean-loup Gailly & Mark Adler\0" END END BLOCK "VarFileInfo" diff --git a/compat/zlib/contrib/vstudio/vc14/zlib.rc b/compat/zlib/contrib/vstudio/vc14/zlib.rc index 4f6396d..ef38298 100644 --- a/compat/zlib/contrib/vstudio/vc14/zlib.rc +++ b/compat/zlib/contrib/vstudio/vc14/zlib.rc @@ -2,8 +2,8 @@ #define IDR_VERSION1 1 IDR_VERSION1 VERSIONINFO MOVEABLE IMPURE LOADONCALL DISCARDABLE - FILEVERSION 1, 2, 9, 0 - PRODUCTVERSION 1, 2, 9, 0 + FILEVERSION 1, 2, 10, 0 + PRODUCTVERSION 1, 2, 10, 0 FILEFLAGSMASK VS_FFI_FILEFLAGSMASK FILEFLAGS 0 FILEOS VOS_DOS_WINDOWS32 @@ -17,12 +17,12 @@ BEGIN BEGIN VALUE "FileDescription", "zlib data compression and ZIP file I/O library\0" - VALUE "FileVersion", "1.2.8.1\0" + VALUE "FileVersion", "1.2.10\0" VALUE "InternalName", "zlib\0" VALUE "OriginalFilename", "zlibwapi.dll\0" VALUE "ProductName", "ZLib.DLL\0" VALUE "Comments","DLL support by Alessandro Iacopetti & Gilles Vollant\0" - VALUE "LegalCopyright", "(C) 1995-2013 Jean-loup Gailly & Mark Adler\0" + VALUE "LegalCopyright", "(C) 1995-2017 Jean-loup Gailly & Mark Adler\0" END END BLOCK "VarFileInfo" diff --git a/compat/zlib/contrib/vstudio/vc9/zlib.rc b/compat/zlib/contrib/vstudio/vc9/zlib.rc index d846820..f1c19bc 100644 --- a/compat/zlib/contrib/vstudio/vc9/zlib.rc +++ b/compat/zlib/contrib/vstudio/vc9/zlib.rc @@ -2,8 +2,8 @@ #define IDR_VERSION1 1 IDR_VERSION1 VERSIONINFO MOVEABLE IMPURE LOADONCALL DISCARDABLE - FILEVERSION 1, 2, 9, 0 - PRODUCTVERSION 1, 2, 9, 0 + FILEVERSION 1, 2, 10, 0 + PRODUCTVERSION 1, 2, 10, 0 FILEFLAGSMASK VS_FFI_FILEFLAGSMASK FILEFLAGS 0 FILEOS VOS_DOS_WINDOWS32 @@ -17,12 +17,12 @@ BEGIN BEGIN VALUE "FileDescription", "zlib data compression and ZIP file I/O library\0" - VALUE "FileVersion", "1.2.9\0" + VALUE "FileVersion", "1.2.10\0" VALUE "InternalName", "zlib\0" VALUE "OriginalFilename", "zlibwapi.dll\0" VALUE "ProductName", "ZLib.DLL\0" VALUE "Comments","DLL support by Alessandro Iacopetti & Gilles Vollant\0" - VALUE "LegalCopyright", "(C) 1995-2016 Jean-loup Gailly & Mark Adler\0" + VALUE "LegalCopyright", "(C) 1995-2017 Jean-loup Gailly & Mark Adler\0" END END BLOCK "VarFileInfo" diff --git a/compat/zlib/deflate.c b/compat/zlib/deflate.c index 415adbf..2ad890e 100644 --- a/compat/zlib/deflate.c +++ b/compat/zlib/deflate.c @@ -1,5 +1,5 @@ /* deflate.c -- compress data using the deflation algorithm - * Copyright (C) 1995-2016 Jean-loup Gailly and Mark Adler + * Copyright (C) 1995-2017 Jean-loup Gailly and Mark Adler * For conditions of distribution and use, see copyright notice in zlib.h */ @@ -52,7 +52,7 @@ #include "deflate.h" const char deflate_copyright[] = - " deflate 1.2.9 Copyright 1995-2016 Jean-loup Gailly and Mark Adler "; + " deflate 1.2.10 Copyright 1995-2017 Jean-loup Gailly and Mark Adler "; /* If you use the zlib library in a product, an acknowledgment is welcome in the documentation of your product. If for some reason you cannot @@ -88,6 +88,7 @@ local void putShortMSB OF((deflate_state *s, uInt b)); local void flush_pending OF((z_streamp strm)); local unsigned read_buf OF((z_streamp strm, Bytef *buf, unsigned size)); #ifdef ASMV +# pragma message("Assembler code may have bugs -- use at your own risk") void match_init OF((void)); /* asm code initialization */ uInt longest_match OF((deflate_state *s, IPos cur_match)); #else @@ -1040,7 +1041,6 @@ int ZEXPORT deflate (strm, flush) } } } - Assert(strm->avail_out > 0, "bug2"); if (flush != Z_FINISH) return Z_OK; if (s->wrap <= 0) return Z_STREAM_END; @@ -1653,17 +1653,19 @@ local block_state deflate_stored(s, flush) * possible. If flushing, copy the remaining available input to next_out as * stored blocks, if there is enough space. */ - unsigned len, left, have, last; + unsigned len, left, have, last = 0; unsigned used = s->strm->avail_in; - for (;;) { + do { /* Set len to the maximum size block that we can copy directly with the * available input data and output space. Set left to how much of that * would be copied from what's left in the window. */ len = MAX_STORED; /* maximum deflate stored block length */ have = (s->bi_valid + 42) >> 3; /* number of header bytes */ + if (s->strm->avail_out < have) /* need room for header */ + break; /* maximum stored block length that will fit in avail_out: */ - have = s->strm->avail_out > have ? s->strm->avail_out - have : 0; + have = s->strm->avail_out - have; left = s->strstart - s->block_start; /* bytes left in window */ if (len > (ulg)left + s->strm->avail_in) len = left + s->strm->avail_in; /* limit len to the input */ @@ -1677,7 +1679,8 @@ local block_state deflate_stored(s, flush) * copying to the window and the pending buffer instead. Also don't * write an empty block when flushing -- deflate() does that. */ - if (len < min_block && (len == 0 || flush == Z_NO_FLUSH || + if (len < min_block && ((len == 0 && flush != Z_FINISH) || + flush == Z_NO_FLUSH || len - left != s->strm->avail_in)) break; @@ -1721,7 +1724,7 @@ local block_state deflate_stored(s, flush) s->strm->avail_out -= len; s->strm->total_out += len; } - } + } while (last == 0); /* Update the sliding window with the last s->w_size bytes of the copied * data, or append all of the copied data to the existing window if less @@ -1754,13 +1757,14 @@ local block_state deflate_stored(s, flush) s->insert += MIN(used, s->w_size - s->insert); } - /* If flushing or finishing and all input has been consumed, then done. If - * the code above couldn't write a complete block to next_out, then the - * code following this won't be able to either. - */ - if (flush != Z_NO_FLUSH && s->strm->avail_in == 0 && - (long)s->strstart == s->block_start) - return flush == Z_FINISH ? finish_done : block_done; + /* If the last block was written to next_out, then done. */ + if (last) + return finish_done; + + /* If flushing and all input has been consumed, then done. */ + if (flush != Z_NO_FLUSH && flush != Z_FINISH && + s->strm->avail_in == 0 && (long)s->strstart == s->block_start) + return block_done; /* Fill the window with any remaining input. */ have = s->window_size - s->strstart - 1; @@ -1791,20 +1795,18 @@ local block_state deflate_stored(s, flush) min_block = MIN(have, s->w_size); left = s->strstart - s->block_start; if (left >= min_block || - (left && flush != Z_NO_FLUSH && s->strm->avail_in == 0 && - left <= have)) { + ((left || flush == Z_FINISH) && flush != Z_NO_FLUSH && + s->strm->avail_in == 0 && left <= have)) { len = MIN(left, have); last = flush == Z_FINISH && s->strm->avail_in == 0 && len == left ? 1 : 0; _tr_stored_block(s, (charf *)s->window + s->block_start, len, last); s->block_start += len; flush_pending(s->strm); - if (last) - return finish_started; } /* We've done all we can with the available input and output. */ - return need_more; + return last ? finish_started : need_more; } /* =========================================================================== diff --git a/compat/zlib/gzlib.c b/compat/zlib/gzlib.c index a87d3d1..e142ffb 100644 --- a/compat/zlib/gzlib.c +++ b/compat/zlib/gzlib.c @@ -211,7 +211,7 @@ local gzFile gz_open(path, fd, mode) else #endif #if !defined(NO_snprintf) && !defined(NO_vsnprintf) - snprintf(state->path, len + 1, "%s", (const char *)path); + (void)snprintf(state->path, len + 1, "%s", (const char *)path); #else strcpy(state->path, path); #endif @@ -293,7 +293,7 @@ gzFile ZEXPORT gzdopen(fd, mode) if (fd == -1 || (path = (char *)malloc(7 + 3 * sizeof(int))) == NULL) return NULL; #if !defined(NO_snprintf) && !defined(NO_vsnprintf) - snprintf(path, 7 + 3 * sizeof(int), "", fd); /* for debugging */ + (void)snprintf(path, 7 + 3 * sizeof(int), "", fd); #else sprintf(path, "", fd); /* for debugging */ #endif @@ -608,8 +608,8 @@ void ZLIB_INTERNAL gz_error(state, err, msg) return; } #if !defined(NO_snprintf) && !defined(NO_vsnprintf) - snprintf(state->msg, strlen(state->path) + strlen(msg) + 3, - "%s%s%s", state->path, ": ", msg); + (void)snprintf(state->msg, strlen(state->path) + strlen(msg) + 3, + "%s%s%s", state->path, ": ", msg); #else strcpy(state->msg, state->path); strcat(state->msg, ": "); diff --git a/compat/zlib/gzwrite.c b/compat/zlib/gzwrite.c index a2ee573..1ec1da4 100644 --- a/compat/zlib/gzwrite.c +++ b/compat/zlib/gzwrite.c @@ -117,6 +117,7 @@ local int gz_comp(state, flush) if (strm->avail_out == 0) { strm->avail_out = state->size; strm->next_out = state->out; + state->x.next = state->out; } } diff --git a/compat/zlib/inffast.c b/compat/zlib/inffast.c index a15876d..29eb7d8 100644 --- a/compat/zlib/inffast.c +++ b/compat/zlib/inffast.c @@ -8,7 +8,9 @@ #include "inflate.h" #include "inffast.h" -#ifndef ASMINF +#ifdef ASMINF +# pragma message("Assembler code may have bugs -- use at your own risk") +#else /* Decode literal, length, and distance codes and write out the resulting diff --git a/compat/zlib/inftrees.c b/compat/zlib/inftrees.c index fa27dcb..8a904dd 100644 --- a/compat/zlib/inftrees.c +++ b/compat/zlib/inftrees.c @@ -1,5 +1,5 @@ /* inftrees.c -- generate Huffman trees for efficient decoding - * Copyright (C) 1995-2016 Mark Adler + * Copyright (C) 1995-2017 Mark Adler * For conditions of distribution and use, see copyright notice in zlib.h */ @@ -9,7 +9,7 @@ #define MAXBITS 15 const char inflate_copyright[] = - " inflate 1.2.9 Copyright 1995-2016 Mark Adler "; + " inflate 1.2.10 Copyright 1995-2017 Mark Adler "; /* If you use the zlib library in a product, an acknowledgment is welcome in the documentation of your product. If for some reason you cannot @@ -62,7 +62,7 @@ unsigned short FAR *work; 35, 43, 51, 59, 67, 83, 99, 115, 131, 163, 195, 227, 258, 0, 0}; static const unsigned short lext[31] = { /* Length codes 257..285 extra */ 16, 16, 16, 16, 16, 16, 16, 16, 17, 17, 17, 17, 18, 18, 18, 18, - 19, 19, 19, 19, 20, 20, 20, 20, 21, 21, 21, 21, 16, 192, 79}; + 19, 19, 19, 19, 20, 20, 20, 20, 21, 21, 21, 21, 16, 192, 202}; static const unsigned short dbase[32] = { /* Distance codes 0..29 base */ 1, 2, 3, 4, 5, 7, 9, 13, 17, 25, 33, 49, 65, 97, 129, 193, 257, 385, 513, 769, 1025, 1537, 2049, 3073, 4097, 6145, diff --git a/compat/zlib/os400/README400 b/compat/zlib/os400/README400 index 7926d7c..28dca8c 100644 --- a/compat/zlib/os400/README400 +++ b/compat/zlib/os400/README400 @@ -1,4 +1,4 @@ - ZLIB version 1.2.9 for OS/400 installation instructions + ZLIB version 1.2.10 for OS/400 installation instructions 1) Download and unpack the zlib tarball to some IFS directory. (i.e.: /path/to/the/zlib/ifs/source/directory) diff --git a/compat/zlib/os400/zlib.inc b/compat/zlib/os400/zlib.inc index 5431e54..a2147dd 100644 --- a/compat/zlib/os400/zlib.inc +++ b/compat/zlib/os400/zlib.inc @@ -1,7 +1,7 @@ * ZLIB.INC - Interface to the general purpose compression library * * ILE RPG400 version by Patrick Monnerat, DATASPHERE. - * Version 1.2.9 + * Version 1.2.10 * * * WARNING: @@ -22,12 +22,12 @@ * * Versioning information. * - D ZLIB_VERSION C '1.2.9' - D ZLIB_VERNUM C X'1290' + D ZLIB_VERSION C '1.2.10' + D ZLIB_VERNUM C X'12a0' D ZLIB_VER_MAJOR C 1 D ZLIB_VER_MINOR C 2 D ZLIB_VER_REVISION... - D C 9 + D C 10 D ZLIB_VER_SUBREVISION... D C 0 * diff --git a/compat/zlib/qnx/package.qpg b/compat/zlib/qnx/package.qpg index 67a8777..d9a1229 100644 --- a/compat/zlib/qnx/package.qpg +++ b/compat/zlib/qnx/package.qpg @@ -25,10 +25,10 @@ - - - - + + + + @@ -63,7 +63,7 @@ - 1.2.9 + 1.2.10 Medium Stable diff --git a/compat/zlib/treebuild.xml b/compat/zlib/treebuild.xml index 931ee5a..a530cc0 100644 --- a/compat/zlib/treebuild.xml +++ b/compat/zlib/treebuild.xml @@ -1,6 +1,6 @@ - - + + zip compression library diff --git a/compat/zlib/win32/README-WIN32.txt b/compat/zlib/win32/README-WIN32.txt index 5002f3c..16adcca 100644 --- a/compat/zlib/win32/README-WIN32.txt +++ b/compat/zlib/win32/README-WIN32.txt @@ -1,6 +1,6 @@ ZLIB DATA COMPRESSION LIBRARY -zlib 1.2.9 is a general purpose data compression library. All the code is +zlib 1.2.10 is a general purpose data compression library. All the code is thread safe. The data format used by the zlib library is described by RFCs (Request for Comments) 1950 to 1952 in the files http://www.ietf.org/rfc/rfc1950.txt (zlib format), rfc1951.txt (deflate format) @@ -22,7 +22,7 @@ before asking for help. Manifest: -The package zlib-1.2.9-win32-x86.zip will contain the following files: +The package zlib-1.2.10-win32-x86.zip will contain the following files: README-WIN32.txt This document ChangeLog Changes since previous zlib packages diff --git a/compat/zlib/zlib.3 b/compat/zlib/zlib.3 index cbac458..00dc061 100644 --- a/compat/zlib/zlib.3 +++ b/compat/zlib/zlib.3 @@ -1,4 +1,4 @@ -.TH ZLIB 3 "31 Dec 2016" +.TH ZLIB 3 "2 Jan 2017" .SH NAME zlib \- compression/decompression library .SH SYNOPSIS @@ -105,9 +105,9 @@ before asking for help. Send questions and/or comments to zlib@gzip.org, or (for the Windows DLL version) to Gilles Vollant (info@winimage.com). .SH AUTHORS AND LICENSE -Version 1.2.9 +Version 1.2.10 .LP -Copyright (C) 1995-2016 Jean-loup Gailly and Mark Adler +Copyright (C) 1995-2017 Jean-loup Gailly and Mark Adler .LP This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/compat/zlib/zlib.3.pdf b/compat/zlib/zlib.3.pdf index 5c71eed..20008cd 100644 Binary files a/compat/zlib/zlib.3.pdf and b/compat/zlib/zlib.3.pdf differ diff --git a/compat/zlib/zlib.h b/compat/zlib/zlib.h index 69fbb97..dc90dc8 100644 --- a/compat/zlib/zlib.h +++ b/compat/zlib/zlib.h @@ -1,7 +1,7 @@ /* zlib.h -- interface of the 'zlib' general purpose compression library - version 1.2.9, December 31st, 2016 + version 1.2.10, January 2nd, 2017 - Copyright (C) 1995-2016 Jean-loup Gailly and Mark Adler + Copyright (C) 1995-2017 Jean-loup Gailly and Mark Adler This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -37,11 +37,11 @@ extern "C" { #endif -#define ZLIB_VERSION "1.2.9" -#define ZLIB_VERNUM 0x1290 +#define ZLIB_VERSION "1.2.10" +#define ZLIB_VERNUM 0x12a0 #define ZLIB_VER_MAJOR 1 #define ZLIB_VER_MINOR 2 -#define ZLIB_VER_REVISION 9 +#define ZLIB_VER_REVISION 10 #define ZLIB_VER_SUBREVISION 0 /* @@ -379,10 +379,11 @@ ZEXTERN int ZEXPORT inflateInit OF((z_streamp strm)); Initializes the internal stream state for decompression. The fields next_in, avail_in, zalloc, zfree and opaque must be initialized before by - the caller. In the current version of inflate, the provide input is not - read or consumed. Any memory allocation will be deferred to the first call - of inflate. If zalloc and zfree are set to Z_NULL, inflateInit updates them - to use default allocation functions. + the caller. In the current version of inflate, the provided input is not + read or consumed. The allocation of a sliding window will be deferred to + the first call of inflate (if the decompression does not complete on the + first call). If zalloc and zfree are set to Z_NULL, inflateInit updates + them to use default allocation functions. inflateInit returns Z_OK if success, Z_MEM_ERROR if there was not enough memory, Z_VERSION_ERROR if the zlib library version is incompatible with the @@ -408,7 +409,7 @@ ZEXTERN int ZEXPORT inflate OF((z_streamp strm, int flush)); - Decompress more input starting at next_in and update next_in and avail_in accordingly. If not all input can be processed (because there is not - enough room in the output buffer), then next_in and avail_on are updated + enough room in the output buffer), then next_in and avail_in are updated accordingly, and processing will resume at this point for the next call of inflate(). @@ -1229,7 +1230,7 @@ ZEXTERN int ZEXPORT compress OF((Bytef *dest, uLongf *destLen, the byte length of the source buffer. Upon entry, destLen is the total size of the destination buffer, which must be at least the value returned by compressBound(sourceLen). Upon exit, destLen is the actual size of the - compressed buffer. compress() is equivalent to compress2() with a level + compressed data. compress() is equivalent to compress2() with a level parameter of Z_DEFAULT_COMPRESSION. compress returns Z_OK if success, Z_MEM_ERROR if there was not @@ -1246,7 +1247,7 @@ ZEXTERN int ZEXPORT compress2 OF((Bytef *dest, uLongf *destLen, length of the source buffer. Upon entry, destLen is the total size of the destination buffer, which must be at least the value returned by compressBound(sourceLen). Upon exit, destLen is the actual size of the - compressed buffer. + compressed data. compress2 returns Z_OK if success, Z_MEM_ERROR if there was not enough memory, Z_BUF_ERROR if there was not enough room in the output buffer, diff --git a/compat/zlib/zutil.c b/compat/zlib/zutil.c index 3b4d904..56534fb 100644 --- a/compat/zlib/zutil.c +++ b/compat/zlib/zutil.c @@ -113,7 +113,7 @@ uLong ZEXPORT zlibCompileFlags() } #ifdef ZLIB_DEBUG - +#include # ifndef verbose # define verbose 0 # endif -- cgit v0.12 From acdb5b20262439ca91321aa76c93346f29891eb5 Mon Sep 17 00:00:00 2001 From: "jan.nijtmans" Date: Wed, 4 Jan 2017 13:51:26 +0000 Subject: Fix 2 test-cases, due to changed command options. --- tests/info.test | 4 ++-- tests/package.test | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/tests/info.test b/tests/info.test index a6a5919..fd89b47 100644 --- a/tests/info.test +++ b/tests/info.test @@ -397,8 +397,8 @@ test info-10.3 {info library option} -body { set tcl_library $savedLibrary; unset savedLibrary test info-11.1 {info loaded option} -body { - info loaded a b -} -returnCodes error -result {wrong # args: should be "info loaded ?interp?"} + info loaded a b c +} -returnCodes error -result {wrong # args: should be "info loaded ?interp? ?packageName?"} test info-11.2 {info loaded option} -body { info loaded {}; info loaded gorp } -returnCodes error -result {could not find interpreter "gorp"} diff --git a/tests/package.test b/tests/package.test index 49346d8..99f9f06 100644 --- a/tests/package.test +++ b/tests/package.test @@ -832,7 +832,7 @@ test package-4.52 {Tcl_PackageCmd procedure, "vsatisfies" option} { } {0} test package-4.53 {Tcl_PackageCmd procedure, "versions" option} -body { package foo -} -returnCodes error -result {bad option "foo": must be forget, ifneeded, names, prefer, present, provide, require, unknown, vcompare, versions, or vsatisfies} +} -returnCodes error -result {bad option "foo": must be files, forget, ifneeded, names, prefer, present, provide, require, unknown, vcompare, versions, or vsatisfies} test package-4.54 {Tcl_PackageCmd procedure, "vsatisfies" option} -body { package vsatisfies 2.1 2.1-3.2-4.5 } -returnCodes error -result {expected versionMin-versionMax but got "2.1-3.2-4.5"} -- cgit v0.12 From 2e108cd831c0768e78523e91979084cad3655df6 Mon Sep 17 00:00:00 2001 From: "jan.nijtmans" Date: Wed, 4 Jan 2017 15:16:31 +0000 Subject: Fix safe.tcl test-cases: "source -nopkg" is not necessary here: "source" is an alias for "::safe::AliasSource", which doesn't use "source" --- library/init.tcl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/library/init.tcl b/library/init.tcl index 65a19aa..e3d4ef0 100644 --- a/library/init.tcl +++ b/library/init.tcl @@ -486,7 +486,7 @@ proc auto_load_index {} { set dir [lindex $auto_path $i] set f "" if {$issafe} { - catch {source -nopkg [file join $dir tclIndex]} + catch {source [file join $dir tclIndex]} } elseif {[catch {set f [open [file join $dir tclIndex]]}]} { continue } else { -- cgit v0.12 From 5e02396d5e59a51aa2c1e0cc1adf72c84783b268 Mon Sep 17 00:00:00 2001 From: "jan.nijtmans" Date: Wed, 4 Jan 2017 16:23:23 +0000 Subject: In stead of "source -nopkg" use a ::tcl::Pkg::source utility function. --- generic/tclCmdMZ.c | 28 ++---------- library/init.tcl | 24 ++++++++++- library/package.tcl | 2 +- library/tclIndex | 120 +++++++++++++++++++++++++++++----------------------- 4 files changed, 92 insertions(+), 82 deletions(-) diff --git a/generic/tclCmdMZ.c b/generic/tclCmdMZ.c index fbc9d8f..23e6bd1 100644 --- a/generic/tclCmdMZ.c +++ b/generic/tclCmdMZ.c @@ -989,11 +989,8 @@ TclNRSourceObjCmd( { const char *encodingName = NULL; Tcl_Obj *fileName; - int result; - void **pkgFiles = NULL; - void *names = NULL; - if (objc < 2 || objc > 4) { + if (objc != 2 && objc !=4) { Tcl_WrongNumArgs(interp, 1, objv, "?-encoding name? fileName"); return TCL_ERROR; } @@ -1011,28 +1008,9 @@ TclNRSourceObjCmd( return TCL_ERROR; } encodingName = TclGetString(objv[2]); - } else if (objc == 3) { - static const char *const nopkgoptions[] = { - "-nopkg", NULL - }; - int index; - - if (TCL_ERROR == Tcl_GetIndexFromObj(interp, objv[1], nopkgoptions, - "option", TCL_EXACT, &index)) { - return TCL_ERROR; - } - pkgFiles = Tcl_GetAssocData(interp, "tclPkgFiles", NULL); - /* Make sure that during the following TclNREvalFile no filenames - * are recorded for inclusion in the "package files" command */ - names = *pkgFiles; - *pkgFiles = NULL; - } - result = TclNREvalFile(interp, fileName, encodingName); - if (pkgFiles) { - /* restore "tclPkgFiles" assocdata to how it was. */ - *pkgFiles = names; } - return result; + + return TclNREvalFile(interp, fileName, encodingName); } /* diff --git a/library/init.tcl b/library/init.tcl index e3d4ef0..9101e35 100644 --- a/library/init.tcl +++ b/library/init.tcl @@ -46,8 +46,6 @@ if {![info exists auto_path]} { } } -source [file join $::tcl_library auto.tcl] - namespace eval tcl { variable Dir foreach Dir [list $::tcl_library [file dirname $::tcl_library]] { @@ -115,6 +113,8 @@ namespace eval tcl { } } +namespace eval tcl::Pkg {} + # Windows specific end of initialization if {(![interp issafe]) && ($tcl_platform(platform) eq "windows")} { @@ -460,6 +460,26 @@ proc auto_load {cmd {namespace {}}} { return 0 } +# ::tcl::Pkg::source -- +# This procedure provides an alternative "source" command, which doesn't +# register the file for the "package files" command. Safe interpreters +# don't have to do anything special. +# +# Arguments: +# filename + +proc ::tcl::Pkg::source {filename} { + if {[interp issafe]} { + uplevel 1 [list ::source $filename] + } else { + set f [open $filename] + fconfigure $f -eofchar \032 + set contents [read $f] + close $f + uplevel 1 [list eval $contents] + } +} + # auto_load_index -- # Loads the contents of tclIndex files on the auto_path directory # list. This is usually invoked within auto_load to load the index diff --git a/library/package.tcl b/library/package.tcl index cb1bea6..1cb2d3d 100644 --- a/library/package.tcl +++ b/library/package.tcl @@ -488,7 +488,7 @@ proc tclPkgUnknown {name args} { set dir [file dirname $file] if {![info exists procdDirs($dir)]} { try { - source -nopkg $file + ::tcl::Pkg::source $file } trap {POSIX EACCES} {} { # $file was not readable; silently ignore continue diff --git a/library/tclIndex b/library/tclIndex index 09aba56..87a2814 100644 --- a/library/tclIndex +++ b/library/tclIndex @@ -7,57 +7,69 @@ # element name is the name of a command and the value is # a script that loads the command. -set auto_index(history) [list source [file join $dir history.tcl]] -set auto_index(::tcl::HistAdd) [list source [file join $dir history.tcl]] -set auto_index(::tcl::HistKeep) [list source [file join $dir history.tcl]] -set auto_index(::tcl::HistClear) [list source [file join $dir history.tcl]] -set auto_index(::tcl::HistInfo) [list source [file join $dir history.tcl]] -set auto_index(::tcl::HistRedo) [list source [file join $dir history.tcl]] -set auto_index(::tcl::HistIndex) [list source [file join $dir history.tcl]] -set auto_index(::tcl::HistEvent) [list source [file join $dir history.tcl]] -set auto_index(::tcl::HistChange) [list source [file join $dir history.tcl]] -set auto_index(pkg_mkIndex) [list source [file join $dir package.tcl]] -set auto_index(tclPkgSetup) [list source [file join $dir package.tcl]] -set auto_index(tclPkgUnknown) [list source [file join $dir package.tcl]] -set auto_index(::tcl::MacOSXPkgUnknown) [list source [file join $dir package.tcl]] -set auto_index(::pkg::create) [list source [file join $dir package.tcl]] -set auto_index(parray) [list source [file join $dir parray.tcl]] -set auto_index(::safe::InterpStatics) [list source [file join $dir safe.tcl]] -set auto_index(::safe::InterpNested) [list source [file join $dir safe.tcl]] -set auto_index(::safe::interpCreate) [list source [file join $dir safe.tcl]] -set auto_index(::safe::interpInit) [list source [file join $dir safe.tcl]] -set auto_index(::safe::CheckInterp) [list source [file join $dir safe.tcl]] -set auto_index(::safe::interpConfigure) [list source [file join $dir safe.tcl]] -set auto_index(::safe::InterpCreate) [list source [file join $dir safe.tcl]] -set auto_index(::safe::InterpSetConfig) [list source [file join $dir safe.tcl]] -set auto_index(::safe::interpFindInAccessPath) [list source [file join $dir safe.tcl]] -set auto_index(::safe::interpAddToAccessPath) [list source [file join $dir safe.tcl]] -set auto_index(::safe::InterpInit) [list source [file join $dir safe.tcl]] -set auto_index(::safe::AddSubDirs) [list source [file join $dir safe.tcl]] -set auto_index(::safe::interpDelete) [list source [file join $dir safe.tcl]] -set auto_index(::safe::setLogCmd) [list source [file join $dir safe.tcl]] -set auto_index(::safe::SyncAccessPath) [list source [file join $dir safe.tcl]] -set auto_index(::safe::PathToken) [list source [file join $dir safe.tcl]] -set auto_index(::safe::TranslatePath) [list source [file join $dir safe.tcl]] -set auto_index(::safe::Log) [list source [file join $dir safe.tcl]] -set auto_index(::safe::CheckFileName) [list source [file join $dir safe.tcl]] -set auto_index(::safe::AliasGlob) [list source [file join $dir safe.tcl]] -set auto_index(::safe::AliasSource) [list source [file join $dir safe.tcl]] -set auto_index(::safe::AliasLoad) [list source [file join $dir safe.tcl]] -set auto_index(::safe::FileInAccessPath) [list source [file join $dir safe.tcl]] -set auto_index(::safe::DirInAccessPath) [list source [file join $dir safe.tcl]] -set auto_index(::safe::Subset) [list source [file join $dir safe.tcl]] -set auto_index(::safe::AliasSubset) [list source [file join $dir safe.tcl]] -set auto_index(::safe::AliasEncoding) [list source [file join $dir safe.tcl]] -set auto_index(tcl_wordBreakAfter) [list source [file join $dir word.tcl]] -set auto_index(tcl_wordBreakBefore) [list source [file join $dir word.tcl]] -set auto_index(tcl_endOfWord) [list source [file join $dir word.tcl]] -set auto_index(tcl_startOfNextWord) [list source [file join $dir word.tcl]] -set auto_index(tcl_startOfPreviousWord) [list source [file join $dir word.tcl]] -set auto_index(::tcl::tm::add) [list source [file join $dir tm.tcl]] -set auto_index(::tcl::tm::remove) [list source [file join $dir tm.tcl]] -set auto_index(::tcl::tm::list) [list source [file join $dir tm.tcl]] -set auto_index(::tcl::tm::Defaults) [list source [file join $dir tm.tcl]] -set auto_index(::tcl::tm::UnknownHandler) [list source [file join $dir tm.tcl]] -set auto_index(::tcl::tm::roots) [list source [file join $dir tm.tcl]] -set auto_index(::tcl::tm::path) [list source [file join $dir tm.tcl]] +set auto_index(auto_reset) [list ::tcl::Pkg::source [file join $dir auto.tcl]] +set auto_index(tcl_findLibrary) [list ::tcl::Pkg::source [file join $dir auto.tcl]] +set auto_index(auto_mkindex) [list ::tcl::Pkg::source [file join $dir auto.tcl]] +set auto_index(auto_mkindex_old) [list ::tcl::Pkg::source [file join $dir auto.tcl]] +set auto_index(::auto_mkindex_parser::init) [list ::tcl::Pkg::source [file join $dir auto.tcl]] +set auto_index(::auto_mkindex_parser::cleanup) [list ::tcl::Pkg::source [file join $dir auto.tcl]] +set auto_index(::auto_mkindex_parser::mkindex) [list ::tcl::Pkg::source [file join $dir auto.tcl]] +set auto_index(::auto_mkindex_parser::hook) [list ::tcl::Pkg::source [file join $dir auto.tcl]] +set auto_index(::auto_mkindex_parser::slavehook) [list ::tcl::Pkg::source [file join $dir auto.tcl]] +set auto_index(::auto_mkindex_parser::command) [list ::tcl::Pkg::source [file join $dir auto.tcl]] +set auto_index(::auto_mkindex_parser::commandInit) [list ::tcl::Pkg::source [file join $dir auto.tcl]] +set auto_index(::auto_mkindex_parser::fullname) [list ::tcl::Pkg::source [file join $dir auto.tcl]] +set auto_index(history) [list ::tcl::Pkg::source [file join $dir history.tcl]] +set auto_index(::tcl::HistAdd) [list ::tcl::Pkg::source [file join $dir history.tcl]] +set auto_index(::tcl::HistKeep) [list ::tcl::Pkg::source [file join $dir history.tcl]] +set auto_index(::tcl::HistClear) [list ::tcl::Pkg::source [file join $dir history.tcl]] +set auto_index(::tcl::HistInfo) [list ::tcl::Pkg::source [file join $dir history.tcl]] +set auto_index(::tcl::HistRedo) [list ::tcl::Pkg::source [file join $dir history.tcl]] +set auto_index(::tcl::HistIndex) [list ::tcl::Pkg::source [file join $dir history.tcl]] +set auto_index(::tcl::HistEvent) [list ::tcl::Pkg::source [file join $dir history.tcl]] +set auto_index(::tcl::HistChange) [list ::tcl::Pkg::source [file join $dir history.tcl]] +set auto_index(pkg_mkIndex) [list ::tcl::Pkg::source [file join $dir package.tcl]] +set auto_index(tclPkgSetup) [list ::tcl::Pkg::source [file join $dir package.tcl]] +set auto_index(tclPkgUnknown) [list ::tcl::Pkg::source [file join $dir package.tcl]] +set auto_index(::tcl::MacOSXPkgUnknown) [list ::tcl::Pkg::source [file join $dir package.tcl]] +set auto_index(::pkg::create) [list ::tcl::Pkg::source [file join $dir package.tcl]] +set auto_index(parray) [list ::tcl::Pkg::source [file join $dir parray.tcl]] +set auto_index(::safe::InterpStatics) [list ::tcl::Pkg::source [file join $dir safe.tcl]] +set auto_index(::safe::InterpNested) [list ::tcl::Pkg::source [file join $dir safe.tcl]] +set auto_index(::safe::interpCreate) [list ::tcl::Pkg::source [file join $dir safe.tcl]] +set auto_index(::safe::interpInit) [list ::tcl::Pkg::source [file join $dir safe.tcl]] +set auto_index(::safe::CheckInterp) [list ::tcl::Pkg::source [file join $dir safe.tcl]] +set auto_index(::safe::interpConfigure) [list ::tcl::Pkg::source [file join $dir safe.tcl]] +set auto_index(::safe::InterpCreate) [list ::tcl::Pkg::source [file join $dir safe.tcl]] +set auto_index(::safe::InterpSetConfig) [list ::tcl::Pkg::source [file join $dir safe.tcl]] +set auto_index(::safe::interpFindInAccessPath) [list ::tcl::Pkg::source [file join $dir safe.tcl]] +set auto_index(::safe::interpAddToAccessPath) [list ::tcl::Pkg::source [file join $dir safe.tcl]] +set auto_index(::safe::InterpInit) [list ::tcl::Pkg::source [file join $dir safe.tcl]] +set auto_index(::safe::AddSubDirs) [list ::tcl::Pkg::source [file join $dir safe.tcl]] +set auto_index(::safe::interpDelete) [list ::tcl::Pkg::source [file join $dir safe.tcl]] +set auto_index(::safe::setLogCmd) [list ::tcl::Pkg::source [file join $dir safe.tcl]] +set auto_index(::safe::SyncAccessPath) [list ::tcl::Pkg::source [file join $dir safe.tcl]] +set auto_index(::safe::PathToken) [list ::tcl::Pkg::source [file join $dir safe.tcl]] +set auto_index(::safe::TranslatePath) [list ::tcl::Pkg::source [file join $dir safe.tcl]] +set auto_index(::safe::Log) [list ::tcl::Pkg::source [file join $dir safe.tcl]] +set auto_index(::safe::CheckFileName) [list ::tcl::Pkg::source [file join $dir safe.tcl]] +set auto_index(::safe::AliasGlob) [list ::tcl::Pkg::source [file join $dir safe.tcl]] +set auto_index(::safe::AliasSource) [list ::tcl::Pkg::source [file join $dir safe.tcl]] +set auto_index(::safe::AliasLoad) [list ::tcl::Pkg::source [file join $dir safe.tcl]] +set auto_index(::safe::FileInAccessPath) [list ::tcl::Pkg::source [file join $dir safe.tcl]] +set auto_index(::safe::DirInAccessPath) [list ::tcl::Pkg::source [file join $dir safe.tcl]] +set auto_index(::safe::Subset) [list ::tcl::Pkg::source [file join $dir safe.tcl]] +set auto_index(::safe::AliasSubset) [list ::tcl::Pkg::source [file join $dir safe.tcl]] +set auto_index(::safe::AliasEncoding) [list ::tcl::Pkg::source [file join $dir safe.tcl]] +set auto_index(tcl_wordBreakAfter) [list ::tcl::Pkg::source [file join $dir word.tcl]] +set auto_index(tcl_wordBreakBefore) [list ::tcl::Pkg::source [file join $dir word.tcl]] +set auto_index(tcl_endOfWord) [list ::tcl::Pkg::source [file join $dir word.tcl]] +set auto_index(tcl_startOfNextWord) [list ::tcl::Pkg::source [file join $dir word.tcl]] +set auto_index(tcl_startOfPreviousWord) [list ::tcl::Pkg::source [file join $dir word.tcl]] +set auto_index(::tcl::tm::add) [list ::tcl::Pkg::source [file join $dir tm.tcl]] +set auto_index(::tcl::tm::remove) [list ::tcl::Pkg::source [file join $dir tm.tcl]] +set auto_index(::tcl::tm::list) [list ::tcl::Pkg::source [file join $dir tm.tcl]] +set auto_index(::tcl::tm::Defaults) [list ::tcl::Pkg::source [file join $dir tm.tcl]] +set auto_index(::tcl::tm::UnknownHandler) [list ::tcl::Pkg::source [file join $dir tm.tcl]] +set auto_index(::tcl::tm::roots) [list ::tcl::Pkg::source [file join $dir tm.tcl]] +set auto_index(::tcl::tm::path) [list ::tcl::Pkg::source [file join $dir tm.tcl]] -- cgit v0.12 From 4d7100b8ac0d293b3183995d79d41a94bbd72f8d Mon Sep 17 00:00:00 2001 From: fvogel Date: Wed, 4 Jan 2017 16:33:28 +0000 Subject: Added more glob patterns in order to ignore html generated documentation and Windows-specific compilation products when running fossil extra --- .fossil-settings/ignore-glob | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/.fossil-settings/ignore-glob b/.fossil-settings/ignore-glob index 2f93505..2126c62 100644 --- a/.fossil-settings/ignore-glob +++ b/.fossil-settings/ignore-glob @@ -6,6 +6,7 @@ *.lib *.o *.obj +*.pdb *.res *.sl *.so @@ -17,6 +18,7 @@ */tclsh* */tcltest* */versions.vc +html libtommath/bn.ilg libtommath/bn.ind libtommath/pretty.build @@ -38,5 +40,7 @@ unix/dltest.marker unix/tcl.pc unix/tclIndex unix/pkgs/* +win/Debug_VC* +win/Release_VC* win/pkgs/* win/tcl.hpj -- cgit v0.12 From 8da19e064b1726cad087cc00da596da9c09704c5 Mon Sep 17 00:00:00 2001 From: "jan.nijtmans" Date: Thu, 5 Jan 2017 13:09:26 +0000 Subject: One more ::tcl::Pkg::source, for the Mac --- library/package.tcl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/library/package.tcl b/library/package.tcl index 5257cd6..c72fbfb 100644 --- a/library/package.tcl +++ b/library/package.tcl @@ -590,7 +590,7 @@ proc tcl::MacOSXPkgUnknown {original name args} { set dir [file dirname $file] if {![info exists procdDirs($dir)]} { try { - source $file + ::tcl::Pkg::source $file } trap {POSIX EACCES} {} { # $file was not readable; silently ignore continue -- cgit v0.12 From 570a13bc17e30542ae39ec77fe3b3cdc37a1979c Mon Sep 17 00:00:00 2001 From: "jan.nijtmans" Date: Thu, 5 Jan 2017 14:27:20 +0000 Subject: Fix [7c7d3b4481d4e4e86420b54031f4abd1df18d64|7c7d3b4481]: load test failures. There's a difference between "" and NULL as interpreter name. --- generic/tclCmdIL.c | 3 --- generic/tclLoad.c | 42 +++++++++++++++++++++--------------------- 2 files changed, 21 insertions(+), 24 deletions(-) diff --git a/generic/tclCmdIL.c b/generic/tclCmdIL.c index ec85741..a7a5f43 100644 --- a/generic/tclCmdIL.c +++ b/generic/tclCmdIL.c @@ -1728,9 +1728,6 @@ InfoLoadedCmd( interpName = NULL; } else { /* Get pkgs just in specified interp. */ interpName = TclGetString(objv[1]); - if (!interpName[0]) { - interpName = NULL; - } } if (objc < 3) { /* Get loaded files in all packages. */ packageName = NULL; diff --git a/generic/tclLoad.c b/generic/tclLoad.c index aabe3bb..44085d6 100644 --- a/generic/tclLoad.c +++ b/generic/tclLoad.c @@ -1051,7 +1051,7 @@ TclGetLoadedPackagesEx( * otherwise, just return info about this * interpreter. */ const char *packageName) /* Package name or NULL. If NULL, return info - * all packages. + * for all packages. */ { Tcl_Interp *target; @@ -1060,26 +1060,6 @@ TclGetLoadedPackagesEx( Tcl_Obj *resultObj, *pkgDesc[2]; if (targetName == NULL) { - /* - * Return information about all of the available packages. - */ - if (packageName) { - resultObj = NULL; - Tcl_MutexLock(&packageMutex); - for (pkgPtr = firstPackagePtr; pkgPtr != NULL; - pkgPtr = pkgPtr->nextPtr) { - if (!strcmp(packageName, pkgPtr->packageName)) { - resultObj = Tcl_NewStringObj(pkgPtr->fileName, -1); - break; - } - } - Tcl_MutexUnlock(&packageMutex); - if (resultObj) { - Tcl_SetObjResult(interp, resultObj); - } - return TCL_OK; - } - resultObj = Tcl_NewObj(); Tcl_MutexLock(&packageMutex); for (pkgPtr = firstPackagePtr; pkgPtr != NULL; @@ -1095,6 +1075,26 @@ TclGetLoadedPackagesEx( } /* + * Return information about all of the available packages. + */ + if (packageName) { + resultObj = NULL; + Tcl_MutexLock(&packageMutex); + for (pkgPtr = firstPackagePtr; pkgPtr != NULL; + pkgPtr = pkgPtr->nextPtr) { + if (!strcmp(packageName, pkgPtr->packageName)) { + resultObj = Tcl_NewStringObj(pkgPtr->fileName, -1); + break; + } + } + Tcl_MutexUnlock(&packageMutex); + if (resultObj) { + Tcl_SetObjResult(interp, resultObj); + } + return TCL_OK; + } + + /* * Return information about only the packages that are loaded in a given * interpreter. */ -- cgit v0.12 From 03d119a9373a169ec5f9dc263d5bca02a2759b1b Mon Sep 17 00:00:00 2001 From: "jan.nijtmans" Date: Thu, 5 Jan 2017 15:13:58 +0000 Subject: Make TclGetLoadedPackagesEx() work with other than the only current interpreter (didn't really think about that earlier ... ). Actually slightly more correct. --- generic/tclLoad.c | 20 +++++++++++--------- 1 file changed, 11 insertions(+), 9 deletions(-) diff --git a/generic/tclLoad.c b/generic/tclLoad.c index 44085d6..bcda420 100644 --- a/generic/tclLoad.c +++ b/generic/tclLoad.c @@ -1074,20 +1074,27 @@ TclGetLoadedPackagesEx( return TCL_OK; } + target = Tcl_GetSlave(interp, targetName); + if (target == NULL) { + return TCL_ERROR; + } + ipPtr = Tcl_GetAssocData(target, "tclLoad", NULL); + /* * Return information about all of the available packages. */ if (packageName) { resultObj = NULL; - Tcl_MutexLock(&packageMutex); - for (pkgPtr = firstPackagePtr; pkgPtr != NULL; - pkgPtr = pkgPtr->nextPtr) { + + for (; ipPtr != NULL; ipPtr = ipPtr->nextPtr) { + pkgPtr = ipPtr->pkgPtr; + if (!strcmp(packageName, pkgPtr->packageName)) { resultObj = Tcl_NewStringObj(pkgPtr->fileName, -1); break; } } - Tcl_MutexUnlock(&packageMutex); + if (resultObj) { Tcl_SetObjResult(interp, resultObj); } @@ -1099,11 +1106,6 @@ TclGetLoadedPackagesEx( * interpreter. */ - target = Tcl_GetSlave(interp, targetName); - if (target == NULL) { - return TCL_ERROR; - } - ipPtr = Tcl_GetAssocData(target, "tclLoad", NULL); resultObj = Tcl_NewObj(); for (; ipPtr != NULL; ipPtr = ipPtr->nextPtr) { pkgPtr = ipPtr->pkgPtr; -- cgit v0.12 From aea2e328303ce78ea26528b14c2c579502ccfe15 Mon Sep 17 00:00:00 2001 From: "jan.nijtmans" Date: Fri, 6 Jan 2017 10:24:53 +0000 Subject: Complete the upgrade to Zlib 1.2.10: Now add the *.lib and *.dll files. --- .fossil-settings/binary-glob | 7 ++++++- .fossil-settings/crnl-glob | 4 +++- .fossil-settings/encoding-glob | 2 +- .fossil-settings/ignore-glob | 2 +- compat/zlib/win32/README.txt | 6 +++--- compat/zlib/win32/zdll.lib | Bin 15658 -> 17152 bytes compat/zlib/win32/zlib1.dll | Bin 107520 -> 104960 bytes compat/zlib/win64/libz.dll.a | Bin 46874 -> 51638 bytes compat/zlib/win64/zdll.lib | Bin 15288 -> 16740 bytes compat/zlib/win64/zlib1.dll | Bin 112640 -> 116224 bytes 10 files changed, 14 insertions(+), 7 deletions(-) diff --git a/.fossil-settings/binary-glob b/.fossil-settings/binary-glob index 509939c..ec574be 100644 --- a/.fossil-settings/binary-glob +++ b/.fossil-settings/binary-glob @@ -1,4 +1,9 @@ +compat/zlib/win32/zdll.lib +compat/zlib/win32/zlib1.dll +compat/zlib/win64/zdll.lib +compat/zlib/win64/zlib1.dll +compat/zlib/win64/libz.dll.a compat/zlib/zlib.3.pdf *.bmp *.gif -*.png +*.png \ No newline at end of file diff --git a/.fossil-settings/crnl-glob b/.fossil-settings/crnl-glob index cc8dd26..8773e68 100644 --- a/.fossil-settings/crnl-glob +++ b/.fossil-settings/crnl-glob @@ -1,6 +1,8 @@ compat/zlib/contrib/dotzlib/DotZLib/UnitTests.cs compat/zlib/contrib/vstudio/readme.txt compat/zlib/contrib/vstudio/*/zlib.rc +compat/zlib/win32/*.txt +compat/zlib/win64/*.txt tools/tcl.hpj.in tools/tcl.wse.in win/buildall.vc.bat @@ -10,4 +12,4 @@ win/makefile.vc win/rules.vc win/tcl.dsp win/tcl.dsw -win/tcl.hpj.in +win/tcl.hpj.in \ No newline at end of file diff --git a/.fossil-settings/encoding-glob b/.fossil-settings/encoding-glob index c014320..25ad865 100644 --- a/.fossil-settings/encoding-glob +++ b/.fossil-settings/encoding-glob @@ -7,4 +7,4 @@ win/makefile.vc win/rules.vc win/tcl.dsp win/tcl.dsw -win/tcl.hpj.in +win/tcl.hpj.in \ No newline at end of file diff --git a/.fossil-settings/ignore-glob b/.fossil-settings/ignore-glob index 2126c62..08d388d 100644 --- a/.fossil-settings/ignore-glob +++ b/.fossil-settings/ignore-glob @@ -43,4 +43,4 @@ unix/pkgs/* win/Debug_VC* win/Release_VC* win/pkgs/* -win/tcl.hpj +win/tcl.hpj \ No newline at end of file diff --git a/compat/zlib/win32/README.txt b/compat/zlib/win32/README.txt index 34a13b3..de1d05a 100644 --- a/compat/zlib/win32/README.txt +++ b/compat/zlib/win32/README.txt @@ -6,7 +6,7 @@ What's here Source ====== - zlib version 1.2.8 + zlib version 1.2.10 available at http://www.gzip.org/zlib/ @@ -25,9 +25,9 @@ Build info Contributed by Jan Nijtmans. Compiler: - i686-w64-mingw32-gcc (GCC) 4.5.3 + i686-w64-mingw32-gcc (GCC) 5.4.0 Library: - mingw64-i686-runtime/headers: 3.0b_svn5747-1 + mingw64-i686-runtime/headers: 5.0.0 Build commands: i686-w64-mingw32-gcc -c -DASMV contrib/asm686/match.S i686-w64-mingw32-gcc -c -DASMINF -I. -O3 contrib/inflate86/inffas86.c diff --git a/compat/zlib/win32/zdll.lib b/compat/zlib/win32/zdll.lib index 8e6f719..5807541 100644 Binary files a/compat/zlib/win32/zdll.lib and b/compat/zlib/win32/zdll.lib differ diff --git a/compat/zlib/win32/zlib1.dll b/compat/zlib/win32/zlib1.dll index 9ea38d5..81f53ec 100755 Binary files a/compat/zlib/win32/zlib1.dll and b/compat/zlib/win32/zlib1.dll differ diff --git a/compat/zlib/win64/libz.dll.a b/compat/zlib/win64/libz.dll.a index a3ae403..d90a90c 100644 Binary files a/compat/zlib/win64/libz.dll.a and b/compat/zlib/win64/libz.dll.a differ diff --git a/compat/zlib/win64/zdll.lib b/compat/zlib/win64/zdll.lib index ac9ffc9..db56951 100644 Binary files a/compat/zlib/win64/zdll.lib and b/compat/zlib/win64/zdll.lib differ diff --git a/compat/zlib/win64/zlib1.dll b/compat/zlib/win64/zlib1.dll index bd1dbc6..86b6bbe 100755 Binary files a/compat/zlib/win64/zlib1.dll and b/compat/zlib/win64/zlib1.dll differ -- cgit v0.12 From f736317f655df4b12f6406d9c0b7dc96075a4868 Mon Sep 17 00:00:00 2001 From: sebres Date: Mon, 9 Jan 2017 18:23:44 +0000 Subject: Fix clock test-cases: Make test clock-67.5 time zone independent - execution fails in the time zones below gmt --- tests/clock.test | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/clock.test b/tests/clock.test index 615f3a8..4e44348 100644 --- a/tests/clock.test +++ b/tests/clock.test @@ -36954,10 +36954,10 @@ test clock-67.5 {Change scan %x output on global locale change [Bug 4a0c163d24]} set current [msgcat::mclocale] } -body { msgcat::mclocale de_de - set res [clock scan "01.01.1970" -locale current -format %x] + set res [clock scan "01.01.1970" -locale current -format %x -gmt 1] msgcat::mclocale en_uk # This will fail without the bug fix, as still de_de is active - expr {$res == [clock scan "01/01/1970" -locale current -format %x]} + expr {$res == [clock scan "01/01/1970" -locale current -format %x -gmt 1]} } -cleanup { msgcat::mclocale $current } -result {1} -- cgit v0.12 From 2de37edd0d18facf3d79f7db22020c7fd3df5ab9 Mon Sep 17 00:00:00 2001 From: sebres Date: Mon, 9 Jan 2017 19:09:49 +0000 Subject: New performance measurement routine "timerate" in opposition to "time" the execution limited by fixed time (in milliseconds) instead of repetition count (more precise results, to prevent very long execution time it is no more necessary to estimate repetition count) Syntax: timerate ?-direct? ?-calibrate? ?-overhead double? command ?time? --- generic/tclBasic.c | 1 + generic/tclCmdMZ.c | 333 ++++++++++++++++++++++++++++++++++++++++++++++++++++- 2 files changed, 333 insertions(+), 1 deletion(-) diff --git a/generic/tclBasic.c b/generic/tclBasic.c index 81b3513..dec26b4 100644 --- a/generic/tclBasic.c +++ b/generic/tclBasic.c @@ -286,6 +286,7 @@ static const CmdInfo builtInCmds[] = { {"source", Tcl_SourceObjCmd, NULL, TclNRSourceObjCmd, 0}, {"tell", Tcl_TellObjCmd, NULL, NULL, CMD_IS_SAFE}, {"time", Tcl_TimeObjCmd, NULL, NULL, CMD_IS_SAFE}, + {"timerate", Tcl_TimeRateObjCmd, NULL, NULL, CMD_IS_SAFE}, {"unload", Tcl_UnloadObjCmd, NULL, NULL, 0}, {"update", Tcl_UpdateObjCmd, NULL, NULL, CMD_IS_SAFE}, {"vwait", Tcl_VwaitObjCmd, NULL, NULL, CMD_IS_SAFE}, diff --git a/generic/tclCmdMZ.c b/generic/tclCmdMZ.c index 23e6bd1..c660596 100644 --- a/generic/tclCmdMZ.c +++ b/generic/tclCmdMZ.c @@ -17,6 +17,7 @@ */ #include "tclInt.h" +#include "tclCompile.h" #include "tclRegexp.h" #include "tclStringTrim.h" @@ -3984,7 +3985,7 @@ Tcl_TimeObjCmd( start = TclpGetWideClicks(); #endif while (i-- > 0) { - result = Tcl_EvalObjEx(interp, objPtr, 0); + result = TclEvalObjEx(interp, objPtr, 0, NULL, 0); if (result != TCL_OK) { return result; } @@ -4024,6 +4025,336 @@ Tcl_TimeObjCmd( /* *---------------------------------------------------------------------- * + * Tcl_TimeRateObjCmd -- + * + * This object-based procedure is invoked to process the "timerate" Tcl + * command. + * This is similar to command "time", except the execution limited by + * given time (in milliseconds) instead of repetition count. + * + * Example: + * timerate {after 5} 1000 ; # equivalent for `time {after 5} [expr 1000/5]` + * + * Results: + * A standard Tcl object result. + * + * Side effects: + * See the user documentation. + * + *---------------------------------------------------------------------- + */ + +int +Tcl_TimeRateObjCmd( + ClientData dummy, /* Not used. */ + Tcl_Interp *interp, /* Current interpreter. */ + int objc, /* Number of arguments. */ + Tcl_Obj *const objv[]) /* Argument objects. */ +{ + static + double measureOverhead = 0; /* global measure-overhead */ + double overhead = -1; /* given measure-overhead */ + register Tcl_Obj *objPtr; + register int result, i; + Tcl_Obj *calibrate = NULL, *direct = NULL; + Tcl_WideInt count = 0; /* Holds repetition count */ + Tcl_WideInt maxms = -0x7FFFFFFFFFFFFFFFL; + /* Maximal running time (in milliseconds) */ + Tcl_WideInt threshold = 1; /* Current threshold for check time (faster + * repeat count without time check) */ + Tcl_WideInt maxIterTm = 1; /* Max time of some iteration as max threshold + * additionally avoid divide to zero (never < 1) */ + register Tcl_WideInt start, middle, stop; +#ifndef TCL_WIDE_CLICKS + Tcl_Time now; +#endif + + static const char *const options[] = { + "-direct", "-overhead", "-calibrate", "--", NULL + }; + enum options { + TMRT_EV_DIRECT, TMRT_OVERHEAD, TMRT_CALIBRATE, TMRT_LAST + }; + + NRE_callback *rootPtr; + ByteCode *codePtr = NULL; + + for (i = 1; i < objc - 1; i++) { + int index; + if (Tcl_GetIndexFromObj(NULL, objv[i], options, "option", TCL_EXACT, + &index) != TCL_OK) { + break; + } + if (index == TMRT_LAST) { + i++; + break; + } + switch ((enum options) index) { + case TMRT_EV_DIRECT: + direct = objv[i]; + break; + case TMRT_OVERHEAD: + if (++i >= objc - 1) { + goto usage; + } + if (Tcl_GetDoubleFromObj(interp, objv[i], &overhead) != TCL_OK) { + return TCL_ERROR; + } + break; + case TMRT_CALIBRATE: + calibrate = objv[i]; + break; + } + } + + if (i >= objc || i < objc-2) { +usage: + Tcl_WrongNumArgs(interp, 1, objv, "?-direct? ?-calibrate? ?-overhead double? command ?time?"); + return TCL_ERROR; + } + objPtr = objv[i++]; + if (i < objc) { + result = TclGetWideIntFromObj(interp, objv[i], &maxms); + if (result != TCL_OK) { + return result; + } + } + + /* if calibrate */ + if (calibrate) { + + /* if no time specified for the calibration */ + if (maxms == -0x7FFFFFFFFFFFFFFFL) { + Tcl_Obj *clobjv[6]; + Tcl_WideInt maxCalTime = 5000; + double lastMeasureOverhead = measureOverhead; + + clobjv[0] = objv[0]; + i = 1; + if (direct) { + clobjv[i++] = direct; + } + clobjv[i++] = objPtr; + + /* reset last measurement overhead */ + measureOverhead = (double)0; + + /* self-call with 100 milliseconds to warm-up, + * before entering the calibration cycle */ + TclNewLongObj(clobjv[i], 100); + Tcl_IncrRefCount(clobjv[i]); + result = Tcl_TimeRateObjCmd(dummy, interp, i+1, clobjv); + Tcl_DecrRefCount(clobjv[i]); + if (result != TCL_OK) { + return result; + } + + i--; + clobjv[i++] = calibrate; + clobjv[i++] = objPtr; + + /* set last measurement overhead to max */ + measureOverhead = (double)0x7FFFFFFFFFFFFFFFL; + + /* calibration cycle until it'll be preciser */ + maxms = -1000; + do { + lastMeasureOverhead = measureOverhead; + TclNewLongObj(clobjv[i], (int)maxms); + Tcl_IncrRefCount(clobjv[i]); + result = Tcl_TimeRateObjCmd(dummy, interp, i+1, clobjv); + Tcl_DecrRefCount(clobjv[i]); + if (result != TCL_OK) { + return result; + } + maxCalTime += maxms; + /* increase maxms for preciser calibration */ + maxms -= (-maxms / 4); + /* as long as new value more as 0.05% better */ + } while ( (measureOverhead >= lastMeasureOverhead + || measureOverhead / lastMeasureOverhead <= 0.9995) + && maxCalTime > 0 + ); + + return result; + } + if (maxms == 0) { + /* reset last measurement overhead */ + measureOverhead = 0; + Tcl_SetObjResult(interp, Tcl_NewLongObj(0)); + return TCL_OK; + } + + /* if time is negative - make current overhead more precise */ + if (maxms > 0) { + /* set last measurement overhead to max */ + measureOverhead = (double)0x7FFFFFFFFFFFFFFFL; + } else { + maxms = -maxms; + } + + } + + if (maxms == -0x7FFFFFFFFFFFFFFFL) { + maxms = 1000; + } + if (overhead == -1) { + overhead = measureOverhead; + } + + /* be sure that resetting of result will not smudge the further measurement */ + Tcl_ResetResult(interp); + + /* compile object */ + if (!direct) { + if (TclInterpReady(interp) != TCL_OK) { + return TCL_ERROR; + } + codePtr = TclCompileObj(interp, objPtr, NULL, 0); + TclPreserveByteCode(codePtr); + } + + /* get start and stop time */ +#ifndef TCL_WIDE_CLICKS + Tcl_GetTime(&now); + start = now.sec; start *= 1000000; start += now.usec; +#else + start = TclpGetWideClicks(); +#endif + + /* start measurement */ + stop = start + maxms * 1000; + middle = start; + while (1) { + /* eval single iteration */ + count++; + + if (!direct) { + /* precompiled */ + rootPtr = TOP_CB(interp); + result = TclNRExecuteByteCode(interp, codePtr); + result = TclNRRunCallbacks(interp, result, rootPtr); + } else { + /* eval */ + result = TclEvalObjEx(interp, objPtr, 0, NULL, 0); + } + if (result != TCL_OK) { + goto done; + } + + /* don't check time up to threshold */ + if (--threshold > 0) continue; + + /* check stop time reached, estimate new threshold */ + #ifndef TCL_WIDE_CLICKS + Tcl_GetTime(&now); + middle = now.sec; middle *= 1000000; middle += now.usec; + #else + middle = TclpGetWideClicks(); + #endif + if (middle >= stop) { + break; + } + /* average iteration time in microsecs */ + threshold = (middle - start) / count; + if (threshold > maxIterTm) { + maxIterTm = threshold; + } + /* as relation between remaining time and time since last check */ + threshold = ((stop - middle) / maxIterTm) / 4; + if (threshold > 100000) { /* fix for too large threshold */ + threshold = 100000; + } + } + + { + Tcl_Obj *objarr[8], **objs = objarr; + Tcl_WideInt val; + const char *fmt; + + middle -= start; /* execution time in microsecs */ + + /* if not calibrate */ + if (!calibrate) { + /* minimize influence of measurement overhead */ + if (overhead > 0) { + /* estimate the time of overhead (microsecs) */ + Tcl_WideInt curOverhead = overhead * count; + if (middle > curOverhead) { + middle -= curOverhead; + } else { + middle = 1; + } + } + } else { + /* calibration - obtaining new measurement overhead */ + if (measureOverhead > (double)middle / count) { + measureOverhead = (double)middle / count; + } + objs[0] = Tcl_NewDoubleObj(measureOverhead); + TclNewLiteralStringObj(objs[1], "\xC2\xB5s/#-overhead"); /* mics */ + objs += 2; + } + + val = middle / count; /* microsecs per iteration */ + if (val >= 1000000) { + objs[0] = Tcl_NewWideIntObj(val); + } else { + if (val < 10) { fmt = "%.6f"; } else + if (val < 100) { fmt = "%.4f"; } else + if (val < 1000) { fmt = "%.3f"; } else + if (val < 10000) { fmt = "%.2f"; } else + { fmt = "%.1f"; }; + objs[0] = Tcl_ObjPrintf(fmt, ((double)middle)/count); + } + + objs[2] = Tcl_NewWideIntObj(count); /* iterations */ + + /* calculate speed as rate (count) per sec */ + if (!middle) middle++; /* +1 ms, just to avoid divide by zero */ + if (count < (0x7FFFFFFFFFFFFFFFL / 1000000)) { + val = (count * 1000000) / middle; + if (val < 100000) { + if (val < 100) { fmt = "%.3f"; } else + if (val < 1000) { fmt = "%.2f"; } else + { fmt = "%.1f"; }; + objs[4] = Tcl_ObjPrintf(fmt, ((double)(count * 1000000)) / middle); + } else { + objs[4] = Tcl_NewWideIntObj(val); + } + } else { + objs[4] = Tcl_NewWideIntObj((count / middle) * 1000000); + } + + /* estimated net execution time (in millisecs) */ + if (!calibrate) { + objs[6] = Tcl_ObjPrintf("%.3f", (double)middle / 1000); + TclNewLiteralStringObj(objs[7], "nett-ms"); + } + + /* + * Construct the result as a list because many programs have always parsed + * as such (extracting the first element, typically). + */ + + TclNewLiteralStringObj(objs[1], "\xC2\xB5s/#"); /* mics/# */ + TclNewLiteralStringObj(objs[3], "#"); + TclNewLiteralStringObj(objs[5], "#/sec"); + Tcl_SetObjResult(interp, Tcl_NewListObj(8, objarr)); + } + +done: + + if (codePtr != NULL) { + TclReleaseByteCode(codePtr); + } + + return result; +} + +/* + *---------------------------------------------------------------------- + * * Tcl_TryObjCmd, TclNRTryObjCmd -- * * This procedure is invoked to process the "try" Tcl command. See the -- cgit v0.12 From 704f3a5483fa3c45aaf38ddf4a83ac4d4f6c7733 Mon Sep 17 00:00:00 2001 From: sebres Date: Mon, 9 Jan 2017 19:31:08 +0000 Subject: missing entry of tclInt.h added --- generic/tclInt.h | 3 +++ 1 file changed, 3 insertions(+) diff --git a/generic/tclInt.h b/generic/tclInt.h index dd0c11a..1b37d84 100644 --- a/generic/tclInt.h +++ b/generic/tclInt.h @@ -3461,6 +3461,9 @@ MODULE_SCOPE int Tcl_ThrowObjCmd(ClientData dummy, Tcl_Interp *interp, MODULE_SCOPE int Tcl_TimeObjCmd(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *const objv[]); +MODULE_SCOPE int Tcl_TimeRateObjCmd(ClientData clientData, + Tcl_Interp *interp, int objc, + Tcl_Obj *const objv[]); MODULE_SCOPE int Tcl_TraceObjCmd(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *const objv[]); -- cgit v0.12 From 6aed9a663094ff9d4bd540007174aff66479b0c2 Mon Sep 17 00:00:00 2001 From: sebres Date: Mon, 9 Jan 2017 19:33:23 +0000 Subject: [win] load win-registry library also in development environment (uninstalled) --- library/reg/pkgIndex.tcl | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/library/reg/pkgIndex.tcl b/library/reg/pkgIndex.tcl index b1fe234..ab022ab 100755 --- a/library/reg/pkgIndex.tcl +++ b/library/reg/pkgIndex.tcl @@ -1,9 +1,19 @@ if {([info commands ::tcl::pkgconfig] eq "") - || ([info sharedlibextension] ne ".dll")} return + || ([info sharedlibextension] ne ".dll")} return if {[::tcl::pkgconfig get debug]} { + if {[info exists [file join $dir tclreg13g.dll]]} { package ifneeded registry 1.3.2 \ [list load [file join $dir tclreg13g.dll] registry] + } else { + package ifneeded registry 1.3.2 \ + [list load tclreg13g registry] + } } else { + if {[info exists [file join $dir tclreg13.dll]]} { package ifneeded registry 1.3.2 \ [list load [file join $dir tclreg13.dll] registry] + } else { + package ifneeded registry 1.3.2 \ + [list load tclreg13 registry] + } } -- cgit v0.12 -- cgit v0.12 From a3433951b0a141acbb0fd911aefffcbd34e3b0b3 Mon Sep 17 00:00:00 2001 From: sebres Date: Tue, 10 Jan 2017 21:57:06 +0000 Subject: 1st try to rewrite clock in C --- generic/tclClock.c | 253 ++++++++++++++++++++++++++++++++++++++++------------- library/clock.tcl | 6 +- library/init.tcl | 28 +++--- 3 files changed, 212 insertions(+), 75 deletions(-) diff --git a/generic/tclClock.c b/generic/tclClock.c index 27009fd..e9a59f3 100644 --- a/generic/tclClock.c +++ b/generic/tclClock.c @@ -69,6 +69,7 @@ typedef enum ClockLiteral { LIT_MONTH, LIT_SECONDS, LIT_TZNAME, LIT_TZOFFSET, LIT_YEAR, + LIT_FREESCAN, LIT__END } ClockLiteral; static const char *const literals[] = { @@ -84,7 +85,8 @@ static const char *const literals[] = { "julianDay", "localSeconds", "month", "seconds", "tzName", "tzOffset", - "year" + "year", + "::tcl::clock::FreeScan" }; /* @@ -190,6 +192,9 @@ static int ClockParseformatargsObjCmd( static int ClockSecondsObjCmd( ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *const objv[]); +static int ClockScanObjCmd( + ClientData clientData, Tcl_Interp *interp, + int objc, Tcl_Obj *const objv[]); static struct tm * ThreadSafeLocalTime(const time_t *); static void TzsetIfNecessary(void); static void ClockDeleteCmdProc(ClientData); @@ -202,7 +207,7 @@ struct ClockCommand { const char *name; /* The tail of the command name. The full name * is "::tcl::clock::". When NULL marks * the end of the table. */ - Tcl_ObjCmdProc *objCmdProc; /* Function that implements the command. This + Tcl_ObjCmdProc *objCmdProc; /* Function that implements the command. This * will always have the ClockClientData sent * to it, but may well ignore this data. */ }; @@ -213,6 +218,7 @@ static const struct ClockCommand clockCommands[] = { { "microseconds", ClockMicrosecondsObjCmd }, { "milliseconds", ClockMillisecondsObjCmd }, { "seconds", ClockSecondsObjCmd }, + { "scan", ClockScanObjCmd }, { "Oldscan", TclClockOldscanObjCmd }, { "ConvertLocalToUTC", ClockConvertlocaltoutcObjCmd }, { "GetDateFields", ClockGetdatefieldsObjCmd }, @@ -466,6 +472,9 @@ ClockGetdatefieldsObjCmd( GetMonthDay(&fields); GetYearWeekDay(&fields, changeover); + +/************* split to use structured version from here ************/ + dict = Tcl_NewDictObj(); Tcl_DictObjPut(NULL, dict, literals[LIT_LOCALSECONDS], Tcl_NewWideIntObj(fields.localSeconds)); @@ -1507,9 +1516,9 @@ GetJulianDayFromEraYearMonthDay( * See above bug for details. The casts are necessary. */ if (ym1 >= 0) - ym1o4 = ym1 / 4; + ym1o4 = ym1 / 4; else { - ym1o4 = - (int) (((unsigned int) -ym1) / 4); + ym1o4 = - (int) (((unsigned int) -ym1) / 4); } #endif if (ym1 % 4 < 0) { @@ -1843,6 +1852,96 @@ ClockMicrosecondsObjCmd( return TCL_OK; } + +typedef struct _ClockFmtScnArgs { + Tcl_Obj *formatObj; /* Format */ + Tcl_Obj *localeObj; /* Locale */ + Tcl_Obj *timezoneObj; /* Timezone */ + Tcl_Obj *baseObj; /* Base (scan only) */ +} _ClockFmtScnArgs; + +static int +_ClockParseFmtScnArgs( + ClientData clientData, /* Client data containing literal pool */ + Tcl_Interp *interp, /* Tcl interpreter */ + int objc, /* Parameter count */ + Tcl_Obj *const objv[], /* Parameter vector */ + _ClockFmtScnArgs *resOpts, /* Result vector: format, locale, timezone... */ + int forScan /* Flag to differentiate between format and scan */ +) { + ClockClientData *dataPtr = clientData; + Tcl_Obj **litPtr = dataPtr->literals; + int gmtFlag = 0; + static const char *const options[2][6] = { + { /* Format command line options */ + "-format", "-gmt", "-locale", + "-timezone", NULL }, + { /* Scan command line options */ + "-format", "-gmt", "-locale", + "-timezone", "-base", NULL } + }; + enum optionInd { + CLOCK_FORMAT_FORMAT, CLOCK_FORMAT_GMT, CLOCK_FORMAT_LOCALE, + CLOCK_FORMAT_TIMEZONE, CLOCK_FORMAT_BASE + }; + int optionIndex; /* Index of an option. */ + int saw = 0; /* Flag == 1 if option was seen already. */ + int i; + + /* + * Extract values for the keywords. + */ + + resOpts->formatObj = NULL; + resOpts->localeObj = NULL; + resOpts->timezoneObj = NULL; + resOpts->baseObj = NULL; + for (i = 2; i < objc; i+=2) { + if (Tcl_GetIndexFromObj(interp, objv[i], options[forScan], + "option", 0, &optionIndex) != TCL_OK) { + Tcl_SetErrorCode(interp, "CLOCK", "badOption", + Tcl_GetString(objv[i]), NULL); + return TCL_ERROR; + } + switch (optionIndex) { + case CLOCK_FORMAT_FORMAT: + resOpts->formatObj = objv[i+1]; + break; + case CLOCK_FORMAT_GMT: + if (Tcl_GetBooleanFromObj(interp, objv[i+1], &gmtFlag) != TCL_OK){ + return TCL_ERROR; + } + break; + case CLOCK_FORMAT_LOCALE: + resOpts->localeObj = objv[i+1]; + break; + case CLOCK_FORMAT_TIMEZONE: + resOpts->timezoneObj = objv[i+1]; + break; + case CLOCK_FORMAT_BASE: + resOpts->baseObj = objv[i+1]; + break; + } + saw |= 1 << optionIndex; + } + + /* + * Check options. + */ + + if ((saw & (1 << CLOCK_FORMAT_GMT)) + && (saw & (1 << CLOCK_FORMAT_TIMEZONE))) { + Tcl_SetObjResult(interp, litPtr[LIT_CANNOT_USE_GMT_AND_TIMEZONE]); + Tcl_SetErrorCode(interp, "CLOCK", "gmtWithTimezone", NULL); + return TCL_ERROR; + } + if (gmtFlag) { + resOpts->timezoneObj = litPtr[LIT_GMT]; + } + + return TCL_OK; +} + /* *----------------------------------------------------------------------------- * @@ -1870,22 +1969,9 @@ ClockParseformatargsObjCmd( { ClockClientData *dataPtr = clientData; Tcl_Obj **litPtr = dataPtr->literals; - Tcl_Obj *results[3]; /* Format, locale and timezone */ -#define formatObj results[0] -#define localeObj results[1] -#define timezoneObj results[2] - int gmtFlag = 0; - static const char *const options[] = { /* Command line options expected */ - "-format", "-gmt", "-locale", - "-timezone", NULL }; - enum optionInd { - CLOCK_FORMAT_FORMAT, CLOCK_FORMAT_GMT, CLOCK_FORMAT_LOCALE, - CLOCK_FORMAT_TIMEZONE - }; - int optionIndex; /* Index of an option. */ - int saw = 0; /* Flag == 1 if option was seen already. */ + _ClockFmtScnArgs resOpts; /* Format, locale and timezone */ Tcl_WideInt clockVal; /* Clock value - just used to parse. */ - int i; + int ret; /* * Args consist of a time followed by keyword-value pairs. @@ -1903,33 +1989,10 @@ ClockParseformatargsObjCmd( * Extract values for the keywords. */ - formatObj = litPtr[LIT__DEFAULT_FORMAT]; - localeObj = litPtr[LIT_C]; - timezoneObj = litPtr[LIT__NIL]; - for (i = 2; i < objc; i+=2) { - if (Tcl_GetIndexFromObj(interp, objv[i], options, "option", 0, - &optionIndex) != TCL_OK) { - Tcl_SetErrorCode(interp, "CLOCK", "badOption", - Tcl_GetString(objv[i]), NULL); - return TCL_ERROR; - } - switch (optionIndex) { - case CLOCK_FORMAT_FORMAT: - formatObj = objv[i+1]; - break; - case CLOCK_FORMAT_GMT: - if (Tcl_GetBooleanFromObj(interp, objv[i+1], &gmtFlag) != TCL_OK){ - return TCL_ERROR; - } - break; - case CLOCK_FORMAT_LOCALE: - localeObj = objv[i+1]; - break; - case CLOCK_FORMAT_TIMEZONE: - timezoneObj = objv[i+1]; - break; - } - saw |= 1 << optionIndex; + ret = _ClockParseFmtScnArgs(clientData, interp, objc, objv, + &resOpts, 0); + if (ret != TCL_OK) { + return ret; } /* @@ -1939,26 +2002,98 @@ ClockParseformatargsObjCmd( if (Tcl_GetWideIntFromObj(interp, objv[1], &clockVal) != TCL_OK) { return TCL_ERROR; } - if ((saw & (1 << CLOCK_FORMAT_GMT)) - && (saw & (1 << CLOCK_FORMAT_TIMEZONE))) { - Tcl_SetObjResult(interp, litPtr[LIT_CANNOT_USE_GMT_AND_TIMEZONE]); - Tcl_SetErrorCode(interp, "CLOCK", "gmtWithTimezone", NULL); - return TCL_ERROR; - } - if (gmtFlag) { - timezoneObj = litPtr[LIT_GMT]; - } + if (resOpts.formatObj == NULL) + resOpts.formatObj = litPtr[LIT__DEFAULT_FORMAT]; + if (resOpts.localeObj == NULL) + resOpts.localeObj = litPtr[LIT_C]; + if (resOpts.timezoneObj == NULL) + resOpts.timezoneObj = litPtr[LIT__NIL]; /* * Return options as a list. */ - Tcl_SetObjResult(interp, Tcl_NewListObj(3, results)); + Tcl_SetObjResult(interp, Tcl_NewListObj(3, (Tcl_Obj**)&resOpts)); return TCL_OK; +} + +/*---------------------------------------------------------------------- + * + * ClockScanObjCmd - + * + *---------------------------------------------------------------------- + */ + +int +ClockScanObjCmd( + ClientData clientData, /* Client data containing literal pool */ + Tcl_Interp *interp, /* Tcl interpreter */ + int objc, /* Parameter count */ + Tcl_Obj *const objv[]) /* Parameter values */ +{ + ClockClientData *dataPtr = clientData; + Tcl_Obj **litPtr = dataPtr->literals; + + Tcl_Time retClock; + char *string, *format = NULL; + int gmt, ret = 0; + char *locale; + _ClockFmtScnArgs opts; /* Format, locale, timezone and base */ + Tcl_WideInt baseVal; /* Base value */ + + if ((objc & 1) == 1) { + Tcl_WrongNumArgs(interp, 1, objv, "string " + "?-base seconds? " + "?-format string? " + "?-gmt boolean? " + "?-locale LOCALE? ?-timezone ZONE?"); + Tcl_SetErrorCode(interp, "CLOCK", "wrongNumArgs", NULL); + return TCL_ERROR; + } + + /* + * Extract values for the keywords. + */ + + ret = _ClockParseFmtScnArgs(clientData, interp, objc, objv, + &opts, 1); + if (ret != TCL_OK) { + return ret; + } + + if (opts.baseObj != NULL) { + if (Tcl_GetWideIntFromObj(interp, opts.baseObj, &baseVal) != TCL_OK) { + return TCL_ERROR; + } + } else { + Tcl_Time now; + Tcl_GetTime(&now); + baseVal = (Tcl_WideInt) now.sec; + } + + /* if free scan */ + if (opts.formatObj == NULL) { + Tcl_Obj *callargs[5]; + /* [SB] TODO: Perhaps someday we'll localize the legacy code. Right now, it's not localized. */ + if (opts.localeObj != NULL) { + Tcl_SetResult(interp, + "legacy [clock scan] does not support -locale", TCL_STATIC); + Tcl_SetErrorCode(interp, "CLOCK", "flagWithLegacyFormat", NULL); + return TCL_ERROR; + } + callargs[0] = litPtr[LIT_FREESCAN]; + callargs[1] = objv[1]; + callargs[2] = opts.baseObj != NULL ? opts.baseObj : Tcl_NewWideIntObj(baseVal); + callargs[3] = opts.timezoneObj != NULL ? opts.timezoneObj : litPtr[LIT__NIL]; + callargs[4] = opts.localeObj != NULL ? opts.localeObj : litPtr[LIT_C]; + return Tcl_EvalObjv(interp, 5, callargs, 0); + } -#undef timezoneObj -#undef localeObj -#undef formatObj + // **** + string = TclGetString(objv[1]); + // **** timezone = GetSystemTimeZone() + + return TCL_OK; } /*---------------------------------------------------------------------- diff --git a/library/clock.tcl b/library/clock.tcl index 535a67d..5b48eb3 100755 --- a/library/clock.tcl +++ b/library/clock.tcl @@ -1178,7 +1178,7 @@ proc ::tcl::clock::ParseClockFormatFormat2 {format locale procName} { # #---------------------------------------------------------------------- -proc ::tcl::clock::scan { args } { +proc ::tcl::clock::__org_scan { args } { set format {} @@ -1300,7 +1300,9 @@ proc ::tcl::clock::FreeScan { string base timezone locale } { variable TZData # Get the data for time changes in the given zone - + if {$timezone eq {}} { + set timezone [GetSystemTimeZone] + } try { SetupTimeZone $timezone } on error {retval opts} { diff --git a/library/init.tcl b/library/init.tcl index 544ea77..e6df12b 100644 --- a/library/init.tcl +++ b/library/init.tcl @@ -66,12 +66,12 @@ namespace eval tcl { } if {![interp issafe]} { - variable Path [encoding dirs] - set Dir [file join $::tcl_library encoding] - if {$Dir ni $Path} { + variable Path [encoding dirs] + set Dir [file join $::tcl_library encoding] + if {$Dir ni $Path} { lappend Path $Dir encoding dirs $Path - } + } } # TIP #255 min and max functions @@ -171,14 +171,14 @@ if {[interp issafe]} { proc clock args { namespace eval ::tcl::clock [list namespace ensemble create -command \ - [uplevel 1 [list namespace origin [lindex [info level 0] 0]]] \ - -subcommands { - add clicks format microseconds milliseconds scan seconds - }] + [uplevel 1 [list namespace origin [lindex [info level 0] 0]]] \ + -subcommands { + add clicks format microseconds milliseconds scan seconds + }] # Auto-loading stubs for 'clock.tcl' - foreach cmd {add format scan} { + foreach cmd {add format FreeScan} { proc ::tcl::clock::$cmd args { variable TclLibDir source -encoding utf-8 [file join $TclLibDir clock.tcl] @@ -600,12 +600,12 @@ proc auto_import {pattern} { auto_load_index foreach pattern $patternList { - foreach name [array names auto_index $pattern] { - if {([namespace which -command $name] eq "") + foreach name [array names auto_index $pattern] { + if {([namespace which -command $name] eq "") && ([namespace qualifiers $pattern] eq [namespace qualifiers $name])} { - namespace eval :: $auto_index($name) - } - } + namespace eval :: $auto_index($name) + } + } } } -- cgit v0.12 From 9e52bb21b79848250f66adb912c1195cc9da2c56 Mon Sep 17 00:00:00 2001 From: sebres Date: Tue, 10 Jan 2017 21:58:33 +0000 Subject: [temp-commit]: clock scan with several optimization porting, still not-ready --- generic/tclClock.c | 520 +++++++++++++++++++++++++++++++++++++++++++++++---- generic/tclDate.c | 497 +++++++++++++++++++++++------------------------- generic/tclDate.h | 77 ++++++++ generic/tclGetDate.y | 134 ++++++------- library/clock.tcl | 19 +- library/init.tcl | 2 +- win/makefile.vc | 4 +- 7 files changed, 870 insertions(+), 383 deletions(-) create mode 100644 generic/tclDate.h diff --git a/generic/tclClock.c b/generic/tclClock.c index e9a59f3..24ed095 100644 --- a/generic/tclClock.c +++ b/generic/tclClock.c @@ -14,6 +14,7 @@ */ #include "tclInt.h" +#include "tclDate.h" /* * Windows has mktime. The configurators do not check. @@ -28,6 +29,7 @@ */ #define JULIAN_DAY_POSIX_EPOCH 2440588 +#define GREGORIAN_CHANGE_DATE 2361222 #define SECONDS_PER_DAY 86400 #define JULIAN_SEC_POSIX_EPOCH (((Tcl_WideInt) JULIAN_DAY_POSIX_EPOCH) \ * SECONDS_PER_DAY) @@ -69,7 +71,14 @@ typedef enum ClockLiteral { LIT_MONTH, LIT_SECONDS, LIT_TZNAME, LIT_TZOFFSET, LIT_YEAR, + LIT_CURRENTYEARCENTURY, + LIT_YEAROFCENTURYSWITCH, + LIT_TZDATA, + LIT_GETSYSTEMTIMEZONE, + LIT_SETUPTIMEZONE, +#if 0 LIT_FREESCAN, +#endif LIT__END } ClockLiteral; static const char *const literals[] = { @@ -86,9 +95,18 @@ static const char *const literals[] = { "month", "seconds", "tzName", "tzOffset", "year", + "::tcl::clock::CurrentYearCentury", + "::tcl::clock::YearOfCenturySwitch", + "::tcl::clock::TZData", + "::tcl::clock::GetSystemTimeZone", + "::tcl::clock::SetupTimeZone", +#if 0 "::tcl::clock::FreeScan" +#endif }; +#define CurrentYearCentury 2000 + /* * Structure containing the client data for [clock] */ @@ -168,6 +186,10 @@ static int ClockClicksObjCmd( static int ClockConvertlocaltoutcObjCmd( ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *const objv[]); + +static int ClockGetDateFields(Tcl_Interp *interp, + TclDateFields *fields, Tcl_Obj *tzdata, + int changeover); static int ClockGetdatefieldsObjCmd( ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *const objv[]); @@ -195,6 +217,10 @@ static int ClockSecondsObjCmd( static int ClockScanObjCmd( ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *const objv[]); +static int ClockFreeScan( + ClientData clientData, Tcl_Interp *interp, + Tcl_Obj *strObj, Tcl_WideInt baseVal, + Tcl_Obj *timezoneObj, Tcl_Obj *locale); static struct tm * ThreadSafeLocalTime(const time_t *); static void TzsetIfNecessary(void); static void ClockDeleteCmdProc(ClientData); @@ -296,6 +322,123 @@ TclClockInit( /* *---------------------------------------------------------------------- + */ +inline Tcl_Obj* +ClockGetTZData( + ClientData clientData, /* Opaque pointer to literal pool, etc. */ + Tcl_Interp *interp, /* Tcl interpreter */ + Tcl_Obj *timezoneObj) /* Name of the timezone */ +{ + ClockClientData *dataPtr = clientData; + Tcl_Obj **literals = dataPtr->literals; + + return Tcl_ObjGetVar2(interp, literals[LIT_TZDATA], + timezoneObj, TCL_LEAVE_ERR_MSG); +} +/* + *---------------------------------------------------------------------- + */ +static Tcl_Obj * +ClockGetSystemTimeZone( + ClientData clientData, /* Opaque pointer to literal pool, etc. */ + Tcl_Interp *interp) /* Tcl interpreter */ +{ + ClockClientData *dataPtr = clientData; + Tcl_Obj **literals = dataPtr->literals; + + if (Tcl_EvalObjv(interp, 1, &literals[LIT_GETSYSTEMTIMEZONE], 0) != TCL_OK) { + return NULL; + } + return Tcl_GetObjResult(interp); +} +/* + *---------------------------------------------------------------------- + */ +static int +ClockSetupTimeZone( + ClientData clientData, /* Opaque pointer to literal pool, etc. */ + Tcl_Interp *interp, /* Tcl interpreter */ + Tcl_Obj *timezoneObj) +{ + ClockClientData *dataPtr = clientData; + Tcl_Obj **literals = dataPtr->literals; + Tcl_Obj *callargs[2]; + + callargs[0] = literals[LIT_SETUPTIMEZONE]; + callargs[1] = timezoneObj; + return Tcl_EvalObjv(interp, 2, callargs, 0); +} +/* + *---------------------------------------------------------------------- + * ClockFormatNumericTimeZone - + * + * Formats a time zone as +hhmmss + * + * Parameters: + * z - Time zone in seconds east of Greenwich + * + * Results: + * Returns the time zone object (formatted in a numeric form) + * + * Side effects: + * None. + * + *---------------------------------------------------------------------- + */ + +Tcl_Obj * +ClockFormatNumericTimeZone(int z) { + char sign = '+'; + int h, m; + if ( z < 0 ) { + z = -z; + sign = '-'; + } + h = z / 3600; + z %= 3600; + m = z / 60; + z %= 60; + if (z != 0) { + return Tcl_ObjPrintf("%c%02d%02d%02d", sign, h, m, z); + } + return Tcl_ObjPrintf("%c%02d%02d", sign, h, m); +} + +/* + *---------------------------------------------------------------------- + * [SB] TODO: make constans cacheable (once per second, etc.) ... + */ +inline int +ClockCurrentYearCentury( + ClientData clientData, /* Opaque pointer to literal pool, etc. */ + Tcl_Interp *interp) /* Tcl interpreter */ +{ + ClockClientData *dataPtr = clientData; + Tcl_Obj **literals = dataPtr->literals; + int year = 2000; + + Tcl_Obj * yearObj = Tcl_ObjGetVar2(interp, + literals[LIT_CURRENTYEARCENTURY], NULL, TCL_LEAVE_ERR_MSG); + Tcl_GetIntFromObj(NULL, yearObj, &year); + return year; +} +inline int +ClockGetYearOfCenturySwitch( + ClientData clientData, /* Opaque pointer to literal pool, etc. */ + Tcl_Interp *interp) /* Tcl interpreter */ +{ + ClockClientData *dataPtr = clientData; + Tcl_Obj **literals = dataPtr->literals; + int year = 37; + + Tcl_Obj * yearObj = Tcl_ObjGetVar2(interp, + literals[LIT_YEAROFCENTURYSWITCH], NULL, TCL_LEAVE_ERR_MSG); + Tcl_GetIntFromObj(NULL, yearObj, &year); + return year; +} + +/* + *---------------------------------------------------------------------- * * ClockConvertlocaltoutcObjCmd -- * @@ -426,6 +569,8 @@ ClockGetdatefieldsObjCmd( Tcl_Obj *const *literals = data->literals; int changeover; + fields.tzName = NULL; + /* * Check params. */ @@ -449,31 +594,14 @@ ClockGetdatefieldsObjCmd( return TCL_ERROR; } - /* - * Convert UTC time to local. - */ + /* Extract fields */ - if (ConvertUTCToLocal(interp, &fields, objv[2], changeover) != TCL_OK) { + if (ClockGetDateFields(interp, &fields, objv[2], changeover) + != TCL_OK) { return TCL_ERROR; } - /* - * Extract Julian day. - */ - - fields.julianDay = (int) ((fields.localSeconds + JULIAN_SEC_POSIX_EPOCH) - / SECONDS_PER_DAY); - - /* - * Convert to Julian or Gregorian calendar. - */ - - GetGregorianEraYearDay(&fields, changeover); - GetMonthDay(&fields); - GetYearWeekDay(&fields, changeover); - - -/************* split to use structured version from here ************/ + /* Make dict of fields */ dict = Tcl_NewDictObj(); Tcl_DictObjPut(NULL, dict, literals[LIT_LOCALSECONDS], @@ -511,6 +639,59 @@ ClockGetdatefieldsObjCmd( /* *---------------------------------------------------------------------- + */ +int +ClockGetDateFields( + Tcl_Interp *interp, /* Tcl interpreter */ + TclDateFields *fields, /* Pointer to result fields, where + * fields->seconds contains date to extract */ + Tcl_Obj *tzdata, /* Time zone data object or NULL for gmt */ + int changeover) /* Julian Day Number */ +{ + /* + * Convert UTC time to local. + */ + + if (ConvertUTCToLocal(interp, fields, tzdata, changeover) != TCL_OK) { + return TCL_ERROR; + } + + /* + * Extract Julian day. + */ + + fields->julianDay = (int) ((fields->localSeconds + JULIAN_SEC_POSIX_EPOCH) + / SECONDS_PER_DAY); + + /* + * Convert to Julian or Gregorian calendar. + */ + + GetGregorianEraYearDay(fields, changeover); + GetMonthDay(fields); + GetYearWeekDay(fields, changeover); + + return TCL_OK; +} + +inline +SetDateFieldsTimeZone( + TclDateFields *fields, + Tcl_Obj *timezoneObj) +{ + if (fields->tzName != timezoneObj) { + if (timezoneObj) { + Tcl_IncrRefCount(timezoneObj); + } + if (fields->tzName != NULL) { + Tcl_DecrRefCount(fields->tzName); + } + fields->tzName = timezoneObj; + } +} + +/* + *---------------------------------------------------------------------- * * ClockGetjuliandayfromerayearmonthdayObjCmd -- * @@ -1013,8 +1194,7 @@ ConvertUTCToLocalUsingTable( * Convert the time. */ - fields->tzName = cellv[3]; - Tcl_IncrRefCount(fields->tzName); + SetDateFieldsTimeZone(fields, cellv[3]); fields->localSeconds = fields->seconds + fields->tzOffset; return TCL_OK; } @@ -1107,8 +1287,7 @@ ConvertUTCToLocalUsingC( if (diff > 0) { sprintf(buffer+5, "%02d", diff); } - fields->tzName = Tcl_NewStringObj(buffer, -1); - Tcl_IncrRefCount(fields->tzName); + SetDateFieldsTimeZone(fields, Tcl_NewStringObj(buffer, -1)); return TCL_OK; } @@ -1968,7 +2147,7 @@ ClockParseformatargsObjCmd( Tcl_Obj *const objv[]) /* Parameter vector */ { ClockClientData *dataPtr = clientData; - Tcl_Obj **litPtr = dataPtr->literals; + Tcl_Obj **literals = dataPtr->literals; _ClockFmtScnArgs resOpts; /* Format, locale and timezone */ Tcl_WideInt clockVal; /* Clock value - just used to parse. */ int ret; @@ -2003,11 +2182,11 @@ ClockParseformatargsObjCmd( return TCL_ERROR; } if (resOpts.formatObj == NULL) - resOpts.formatObj = litPtr[LIT__DEFAULT_FORMAT]; + resOpts.formatObj = literals[LIT__DEFAULT_FORMAT]; if (resOpts.localeObj == NULL) - resOpts.localeObj = litPtr[LIT_C]; + resOpts.localeObj = literals[LIT_C]; if (resOpts.timezoneObj == NULL) - resOpts.timezoneObj = litPtr[LIT__NIL]; + resOpts.timezoneObj = literals[LIT__NIL]; /* * Return options as a list. @@ -2032,7 +2211,7 @@ ClockScanObjCmd( Tcl_Obj *const objv[]) /* Parameter values */ { ClockClientData *dataPtr = clientData; - Tcl_Obj **litPtr = dataPtr->literals; + Tcl_Obj **literals = dataPtr->literals; Tcl_Time retClock; char *string, *format = NULL; @@ -2071,8 +2250,10 @@ ClockScanObjCmd( baseVal = (Tcl_WideInt) now.sec; } - /* if free scan */ + /* If free scan */ if (opts.formatObj == NULL) { +#if 0 + /* Tcled FreeScan proc - */ Tcl_Obj *callargs[5]; /* [SB] TODO: Perhaps someday we'll localize the legacy code. Right now, it's not localized. */ if (opts.localeObj != NULL) { @@ -2081,18 +2262,287 @@ ClockScanObjCmd( Tcl_SetErrorCode(interp, "CLOCK", "flagWithLegacyFormat", NULL); return TCL_ERROR; } - callargs[0] = litPtr[LIT_FREESCAN]; + callargs[0] = literals[LIT_FREESCAN]; callargs[1] = objv[1]; callargs[2] = opts.baseObj != NULL ? opts.baseObj : Tcl_NewWideIntObj(baseVal); - callargs[3] = opts.timezoneObj != NULL ? opts.timezoneObj : litPtr[LIT__NIL]; - callargs[4] = opts.localeObj != NULL ? opts.localeObj : litPtr[LIT_C]; + callargs[3] = opts.timezoneObj != NULL ? opts.timezoneObj : literals[LIT__NIL]; + callargs[4] = opts.localeObj != NULL ? opts.localeObj : literals[LIT_C]; return Tcl_EvalObjv(interp, 5, callargs, 0); +#else + /* Use compiled version of FreeScan - */ + + + /* [SB] TODO: Perhaps someday we'll localize the legacy code. Right now, it's not localized. */ + if (opts.localeObj != NULL) { + Tcl_SetResult(interp, + "legacy [clock scan] does not support -locale", TCL_STATIC); + Tcl_SetErrorCode(interp, "CLOCK", "flagWithLegacyFormat", NULL); + return TCL_ERROR; + } + return ClockFreeScan(clientData, interp, objv[1], baseVal, + opts.timezoneObj, opts.localeObj); +#endif } + // **** string = TclGetString(objv[1]); - // **** timezone = GetSystemTimeZone() + // **** timezone = ClockGetSystemTimeZone(clientData, interp) + /* + if (timezoneObj == NULL) { + goto done; + } + */ + + return TCL_OK; +} + +/*---------------------------------------------------------------------- + */ +int +ClockFreeScan( + ClientData clientData, /* Client data containing literal pool */ + Tcl_Interp *interp, /* Tcl interpreter */ + Tcl_Obj *strObj, /* String containing the time to scan */ + Tcl_WideInt baseVal, /* Base time, expressed in seconds from the Epoch */ + Tcl_Obj *timezoneObj, /* Default time zone in which the time will be expressed */ + Tcl_Obj *locale) /* (Unused) Name of the locale where the time will be scanned. */ +{ + ClockClientData *dataPtr = clientData; + Tcl_Obj **literals = dataPtr->literals; + + DateInfo yy; /* parse structure of TclClockFreeScan */ + TclDateFields date; /* date fields used for converting from seconds */ + Tcl_Obj *tzdata; + int secondOfDay; /* Seconds of day (time only calculation) */ + Tcl_WideInt seconds; + int ret = TCL_ERROR; + Tcl_Obj *cleanUpList = Tcl_NewObj(); + + date.tzName = NULL; + + /* If time zone not specified use system time zone */ + if (timezoneObj == NULL || + TclGetString(timezoneObj) == NULL || timezoneObj->length == 0) { + timezoneObj = ClockGetSystemTimeZone(clientData, interp); + if (timezoneObj == NULL) { + goto done; + } + Tcl_ListObjAppendElement(NULL, cleanUpList, timezoneObj); + } + + /* Get the data for time changes in the given zone */ + + if (ClockSetupTimeZone(clientData, interp, timezoneObj) != TCL_OK) { + goto done; + } + + /* + * Extract year, month and day from the base time for the parser to use as + * defaults + */ + + tzdata = ClockGetTZData(clientData, interp, timezoneObj); + if (tzdata == NULL) { + goto done; + } + date.seconds = baseVal; + if (ClockGetDateFields(interp, &date, tzdata, GREGORIAN_CHANGE_DATE) + != TCL_OK) { + goto done; + } + + secondOfDay = date.localSeconds % 86400; + + /* + * Parse the date. The parser will fill a structure "yy" with date, time, + * time zone, relative month/day/seconds, relative weekday, ordinal month. + */ + yy.dateInput = Tcl_GetString(strObj); + + yy.dateYear = date.year; + yy.dateMonth = date.month; + yy.dateDay = date.dayOfMonth; + + if (TclClockFreeScan(interp, &yy) != TCL_OK) { + Tcl_Obj *msg = Tcl_NewObj(); + Tcl_AppendPrintfToObj(msg, "unable to convert date-time string \"", + yy.dateInput, "\":", + TclGetString(Tcl_GetObjResult(interp))); + Tcl_SetObjResult(interp, msg); + goto done; + } + + /* + * If the caller supplied a date in the string, update the date with + * the value. If the caller didn't specify a time with the date, default to + * midnight. + */ + + if (yy.dateHaveDate) { + if (yy.dateYear < 100) { + yy.dateYear += ClockCurrentYearCentury(clientData, interp); + if (yy.dateYear > ClockGetYearOfCenturySwitch(clientData, interp)) { + yy.dateYear -= 100; + } + } + date.era = CE; + date.year = yy.dateYear; + date.month = yy.dateMonth; + date.dayOfMonth = yy.dateDay; + if (yy.dateHaveTime == 0) { + yy.dateHaveTime = -1; + } + } + + /* + * If the caller supplied a time zone in the string, make it into a time + * zone indicator of +-hhmm and setup this time zone. + */ + + if (yy.dateHaveZone) { + int minEast = -yy.dateTimezone; + int dstFlag = 1 - yy.dateDSTmode; + timezoneObj = ClockFormatNumericTimeZone( + 60 * minEast + 3600 * dstFlag); + Tcl_ListObjAppendElement(NULL, cleanUpList, timezoneObj); + if (ClockSetupTimeZone(clientData, interp, timezoneObj) != TCL_OK) { + goto done; + } + tzdata = ClockGetTZData(clientData, interp, timezoneObj); + if (tzdata == NULL) { + goto done; + } + } + + SetDateFieldsTimeZone(&date, timezoneObj); + + /* Assemble date, time, zone into seconds-from-epoch */ + + GetJulianDayFromEraYearMonthDay(&date, GREGORIAN_CHANGE_DATE); + + if (yy.dateHaveTime == -1) { + secondOfDay = 0; + } + else + if (yy.dateHaveTime) { + secondOfDay = ToSeconds(yy.dateHour, yy.dateMinutes, + yy.dateSeconds, yy.dateMeridian); + } + else + if ( (yy.dateHaveDay && !yy.dateHaveDate) + || yy.dateHaveOrdinalMonth + || ( yy.dateHaveRel + && ( yy.dateRelMonth != 0 + || yy.dateRelDay != 0 ) ) + ) { + secondOfDay = 0; + } + + date.localSeconds = + -210866803200L + + ( 86400 * (Tcl_WideInt)date.julianDay ) + + secondOfDay; + + SetDateFieldsTimeZone(&date, timezoneObj); + if (ConvertLocalToUTC(interp, &date, tzdata, GREGORIAN_CHANGE_DATE) + != TCL_OK) { + goto done; + } + + seconds = date.seconds; + + /* + * Do relative times + */ + + if (yy.dateHaveRel) { + + /* [SB] TODO: rewrite it in C: * / + seconds = [add $seconds \ + yy.dateRelMonth months yy.dateRelDay days yy.dateRelMonthSecond seconds \ + -timezone $timezone -locale $locale] + */ + } + + /* + * Do relative weekday + */ + + if (yy.dateHaveDay && !yy.dateHaveDate) { + TclDateFields date2; + date2.tzName = NULL; + + SetDateFieldsTimeZone(&date2, timezoneObj); + + date2.seconds = date.seconds; + if (ClockGetDateFields(interp, &date2, tzdata, GREGORIAN_CHANGE_DATE) + != TCL_OK) { + SetDateFieldsTimeZone(&date2, NULL); + goto done; + } + date2.era = CE; + date2.julianDay = WeekdayOnOrBefore(yy.dateDayNumber, date2.julianDay + 6) + + 7 * yy.dateDayOrdinal; + if (yy.dateDayOrdinal > 0) { + date2.julianDay -= 7; + } + secondOfDay = date2.localSeconds % 86400; + date2.localSeconds = + -210866803200 + + ( 86400 * (Tcl_WideInt)date2.julianDay ) + + secondOfDay; + + SetDateFieldsTimeZone(&date2, timezoneObj); + if (ConvertLocalToUTC(interp, &date2, tzdata, GREGORIAN_CHANGE_DATE) + != TCL_OK) { + SetDateFieldsTimeZone(&date2, NULL); + goto done; + } + SetDateFieldsTimeZone(&date2, NULL); + + seconds = date2.seconds; + } + + /* + * Do relative month + */ + + if (yy.dateHaveOrdinalMonth) { + int monthDiff; + if (yy.dateMonthOrdinal > 0) { + monthDiff = yy.dateMonth - date.month; + if (monthDiff <= 0) { + monthDiff += 12; + } + yy.dateMonthOrdinal--; + } else { + monthDiff = date.month - yy.dateMonth; + if (monthDiff >= 0) { + monthDiff -= 12; + } + yy.dateMonthOrdinal++; + } + /* [SB] TODO: rewrite it in C: * / + seconds = [add $seconds $yy.dateMonthOrdinal years $monthDiff months \ + -timezone $timezone -locale $locale] + */ + } + + ret = TCL_OK; + +done: + + if (date.tzName != NULL) { + Tcl_DecrRefCount(date.tzName); + } + Tcl_DecrRefCount(cleanUpList); + + if (ret != TCL_OK) { + return ret; + } + Tcl_SetObjResult(interp, Tcl_NewWideIntObj(seconds)); return TCL_OK; } diff --git a/generic/tclDate.c b/generic/tclDate.c index e4dd000..a31e0fc 100644 --- a/generic/tclDate.c +++ b/generic/tclDate.c @@ -1,24 +1,22 @@ -/* A Bison parser, made by GNU Bison 2.3. */ +/* A Bison parser, made by GNU Bison 2.4.2. */ /* Skeleton implementation for Bison's Yacc-like parsers in C - - Copyright (C) 1984, 1989, 1990, 2000, 2001, 2002, 2003, 2004, 2005, 2006 - Free Software Foundation, Inc. - - This program is free software; you can redistribute it and/or modify + + Copyright (C) 1984, 1989-1990, 2000-2006, 2009-2010 Free Software + Foundation, Inc. + + This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2, or (at your option) - any later version. - + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. - + You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, - Boston, MA 02110-1301, USA. */ + along with this program. If not, see . */ /* As a special exception, you may create a larger work that contains part or all of the Bison parser skeleton and distribute that work @@ -29,7 +27,7 @@ special exception, which will cause the skeleton and the resulting Bison output files to be licensed under the GNU General Public License without this special exception. - + This special exception was added by the Free Software Foundation in version 2.2 of Bison. */ @@ -47,7 +45,7 @@ #define YYBISON 1 /* Bison version. */ -#define YYBISON_VERSION "2.3" +#define YYBISON_VERSION "2.4.2" /* Skeleton name. */ #define YYSKELETON_NAME "yacc.c" @@ -55,65 +53,24 @@ /* Pure parsers. */ #define YYPURE 1 +/* Push parsers. */ +#define YYPUSH 0 + +/* Pull parsers. */ +#define YYPULL 1 + /* Using locations. */ #define YYLSP_NEEDED 1 /* Substitute the variable and function names. */ -#define yyparse TclDateparse -#define yylex TclDatelex -#define yyerror TclDateerror -#define yylval TclDatelval -#define yychar TclDatechar -#define yydebug TclDatedebug -#define yynerrs TclDatenerrs -#define yylloc TclDatelloc - -/* Tokens. */ -#ifndef YYTOKENTYPE -# define YYTOKENTYPE - /* Put the tokens into the symbol table, so that GDB and other debuggers - know about them. */ - enum yytokentype { - tAGO = 258, - tDAY = 259, - tDAYZONE = 260, - tID = 261, - tMERIDIAN = 262, - tMONTH = 263, - tMONTH_UNIT = 264, - tSTARDATE = 265, - tSEC_UNIT = 266, - tSNUMBER = 267, - tUNUMBER = 268, - tZONE = 269, - tEPOCH = 270, - tDST = 271, - tISOBASE = 272, - tDAY_UNIT = 273, - tNEXT = 274 - }; -#endif -/* Tokens. */ -#define tAGO 258 -#define tDAY 259 -#define tDAYZONE 260 -#define tID 261 -#define tMERIDIAN 262 -#define tMONTH 263 -#define tMONTH_UNIT 264 -#define tSTARDATE 265 -#define tSEC_UNIT 266 -#define tSNUMBER 267 -#define tUNUMBER 268 -#define tZONE 269 -#define tEPOCH 270 -#define tDST 271 -#define tISOBASE 272 -#define tDAY_UNIT 273 -#define tNEXT 274 - - - +#define yyparse TclDateparse +#define yylex TclDatelex +#define yyerror TclDateerror +#define yylval TclDatelval +#define yychar TclDatechar +#define yydebug TclDatedebug +#define yynerrs TclDatenerrs +#define yylloc TclDatelloc /* Copy the first part of user declarations. */ @@ -129,6 +86,7 @@ * * See the file "license.terms" for information on usage and redistribution of * this file, and for a DISCLAIMER OF ALL WARRANTIES. + * */ #include "tclInt.h" @@ -146,44 +104,7 @@ * parsed fields will be returned. */ -typedef struct DateInfo { - - Tcl_Obj* messages; /* Error messages */ - const char* separatrix; /* String separating messages */ - - time_t dateYear; - time_t dateMonth; - time_t dateDay; - int dateHaveDate; - - time_t dateHour; - time_t dateMinutes; - time_t dateSeconds; - int dateMeridian; - int dateHaveTime; - - time_t dateTimezone; - int dateDSTmode; - int dateHaveZone; - - time_t dateRelMonth; - time_t dateRelDay; - time_t dateRelSeconds; - int dateHaveRel; - - time_t dateMonthOrdinal; - int dateHaveOrdinalMonth; - - time_t dateDayOrdinal; - time_t dateDayNumber; - int dateHaveDay; - - const char *dateStart; - const char *dateInput; - time_t *dateRelPointer; - - int dateDigitCount; -} DateInfo; +#include "tclDate.h" #define YYMALLOC ckalloc #define YYFREE(x) (ckfree((void*) (x))) @@ -246,13 +167,6 @@ typedef enum _DSTMODE { DSTon, DSToff, DSTmaybe } DSTMODE; -/* - * Meridian: am, pm, or 24-hour style. - */ - -typedef enum _MERIDIAN { - MERam, MERpm, MER24 -} MERIDIAN; @@ -274,19 +188,49 @@ typedef enum _MERIDIAN { # define YYTOKEN_TABLE 0 #endif + +/* Tokens. */ +#ifndef YYTOKENTYPE +# define YYTOKENTYPE + /* Put the tokens into the symbol table, so that GDB and other debuggers + know about them. */ + enum yytokentype { + tAGO = 258, + tDAY = 259, + tDAYZONE = 260, + tID = 261, + tMERIDIAN = 262, + tMONTH = 263, + tMONTH_UNIT = 264, + tSTARDATE = 265, + tSEC_UNIT = 266, + tSNUMBER = 267, + tUNUMBER = 268, + tZONE = 269, + tEPOCH = 270, + tDST = 271, + tISOBASE = 272, + tDAY_UNIT = 273, + tNEXT = 274 + }; +#endif + + + #if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED typedef union YYSTYPE - { + + time_t Number; enum _MERIDIAN Meridian; -} -/* Line 187 of yacc.c. */ - YYSTYPE; + + +} YYSTYPE; +# define YYSTYPE_IS_TRIVIAL 1 # define yystype YYSTYPE /* obsolescent; will be withdrawn */ # define YYSTYPE_IS_DECLARED 1 -# define YYSTYPE_IS_TRIVIAL 1 #endif #if ! defined YYLTYPE && ! defined YYLTYPE_IS_DECLARED @@ -316,14 +260,10 @@ static int LookupWord(YYSTYPE* yylvalPtr, char *buff); DateInfo* info, const char *s); static int TclDatelex(YYSTYPE* yylvalPtr, YYLTYPE* location, DateInfo* info); -static time_t ToSeconds(time_t Hours, time_t Minutes, - time_t Seconds, MERIDIAN Meridian); MODULE_SCOPE int yyparse(DateInfo*); -/* Line 216 of yacc.c. */ - #ifdef short # undef short @@ -359,15 +299,21 @@ typedef short int yytype_int16; #ifndef YYSIZE_T # ifdef __SIZE_TYPE__ # define YYSIZE_T __SIZE_TYPE__ -# else +# elif defined size_t # define YYSIZE_T size_t +# elif ! defined YYSIZE_T && (defined __STDC__ || defined __C99__FUNC__ \ + || defined __cplusplus || defined _MSC_VER) +# include /* INFRINGES ON USER NAME SPACE */ +# define YYSIZE_T size_t +# else +# define YYSIZE_T unsigned int # endif #endif #define YYSIZE_MAXIMUM ((YYSIZE_T) -1) #ifndef YY_ -# if YYENABLE_NLS +# if defined YYENABLE_NLS && YYENABLE_NLS # if ENABLE_NLS # include /* INFRINGES ON USER NAME SPACE */ # define YY_(msgid) dgettext ("bison-runtime", msgid) @@ -392,14 +338,14 @@ typedef short int yytype_int16; #if (defined __STDC__ || defined __C99__FUNC__ \ || defined __cplusplus || defined _MSC_VER) static int -YYID (int i) +YYID (int yyi) #else static int -YYID (i) - int i; +YYID (yyi) + int yyi; #endif { - return i; + return yyi; } #endif @@ -481,9 +427,9 @@ void free (void *); /* INFRINGES ON USER NAME SPACE */ /* A type that is properly aligned for any stack member. */ union yyalloc { - yytype_int16 yyss; - YYSTYPE yyvs; - YYLTYPE yyls; + yytype_int16 yyss_alloc; + YYSTYPE yyvs_alloc; + YYLTYPE yyls_alloc; }; /* The size of the maximum gap between one aligned stack and the next. */ @@ -518,12 +464,12 @@ union yyalloc elements in the stack, and YYPTR gives the new location of the stack. Advance YYPTR to a properly aligned location for the next stack. */ -# define YYSTACK_RELOCATE(Stack) \ +# define YYSTACK_RELOCATE(Stack_alloc, Stack) \ do \ { \ YYSIZE_T yynewbytes; \ - YYCOPY (&yyptr->Stack, Stack, yysize); \ - Stack = &yyptr->Stack; \ + YYCOPY (&yyptr->Stack_alloc, Stack, yysize); \ + Stack = &yyptr->Stack_alloc; \ yynewbytes = yystacksize * sizeof (*Stack) + YYSTACK_GAP_MAXIMUM; \ yyptr += yynewbytes / sizeof (*yyptr); \ } \ @@ -624,12 +570,12 @@ static const yytype_int8 yyrhs[] = /* YYRLINE[YYN] -- source line where rule number YYN was defined. */ static const yytype_uint16 yyrline[] = { - 0, 225, 225, 226, 229, 232, 235, 238, 241, 244, - 247, 251, 256, 259, 265, 271, 279, 285, 296, 300, - 304, 310, 314, 318, 322, 326, 332, 336, 341, 346, - 351, 356, 360, 365, 369, 374, 381, 385, 391, 400, - 409, 419, 433, 438, 441, 444, 447, 450, 453, 458, - 461, 466, 470, 474, 480, 498, 501 + 0, 176, 176, 177, 180, 183, 186, 189, 192, 195, + 198, 202, 207, 210, 216, 222, 230, 236, 247, 251, + 255, 261, 265, 269, 273, 277, 283, 287, 292, 297, + 302, 307, 311, 316, 320, 325, 332, 336, 342, 351, + 360, 370, 384, 389, 392, 395, 398, 401, 404, 409, + 412, 417, 421, 425, 431, 449, 452 }; #endif @@ -783,9 +729,18 @@ static const yytype_uint8 yystos[] = /* Like YYERROR except do call yyerror. This remains here temporarily to ease the transition to the new meaning of YYERROR, for GCC. - Once GCC version 2 has supplanted version 1, this can go. */ + Once GCC version 2 has supplanted version 1, this can go. However, + YYFAIL appears to be in use. Nevertheless, it is formally deprecated + in Bison 2.4.2's NEWS entry, where a plan to phase it out is + discussed. */ #define YYFAIL goto yyerrlab +#if defined YYFAIL + /* This is here to suppress warnings from the GCC cpp's + -Wunused-macros. Normally we don't worry about that warning, but + some users do, and we want to make it easy for users to remove + YYFAIL uses, which will produce warnings from Bison 2.5. */ +#endif #define YYRECOVERING() (!!yyerrstatus) @@ -842,7 +797,7 @@ while (YYID (0)) we won't break user code: when these are the locations we know. */ #ifndef YY_LOCATION_PRINT -# if YYLTYPE_IS_TRIVIAL +# if defined YYLTYPE_IS_TRIVIAL && YYLTYPE_IS_TRIVIAL # define YY_LOCATION_PRINT(File, Loc) \ fprintf (File, "%d.%d-%d.%d", \ (Loc).first_line, (Loc).first_column, \ @@ -961,17 +916,20 @@ yy_symbol_print (yyoutput, yytype, yyvaluep, yylocationp, info) #if (defined __STDC__ || defined __C99__FUNC__ \ || defined __cplusplus || defined _MSC_VER) static void -yy_stack_print (yytype_int16 *bottom, yytype_int16 *top) +yy_stack_print (yytype_int16 *yybottom, yytype_int16 *yytop) #else static void -yy_stack_print (bottom, top) - yytype_int16 *bottom; - yytype_int16 *top; +yy_stack_print (yybottom, yytop) + yytype_int16 *yybottom; + yytype_int16 *yytop; #endif { YYFPRINTF (stderr, "Stack now"); - for (; bottom <= top; ++bottom) - YYFPRINTF (stderr, " %d", *bottom); + for (; yybottom <= yytop; yybottom++) + { + int yybot = *yybottom; + YYFPRINTF (stderr, " %d", yybot); + } YYFPRINTF (stderr, "\n"); } @@ -1007,11 +965,11 @@ yy_reduce_print (yyvsp, yylsp, yyrule, info) /* The symbols being reduced. */ for (yyi = 0; yyi < yynrhs; yyi++) { - fprintf (stderr, " $%d = ", yyi + 1); + YYFPRINTF (stderr, " $%d = ", yyi + 1); yy_symbol_print (stderr, yyrhs[yyprhs[yyrule] + yyi], &(yyvsp[(yyi + 1) - (yynrhs)]) , &(yylsp[(yyi + 1) - (yynrhs)]) , info); - fprintf (stderr, "\n"); + YYFPRINTF (stderr, "\n"); } } @@ -1295,10 +1253,8 @@ yydestruct (yymsg, yytype, yyvaluep, yylocationp, info) break; } } - /* Prevent warnings from -Wmissing-prototypes. */ - #ifdef YYPARSE_PARAM #if defined __STDC__ || defined __cplusplus int yyparse (void *YYPARSE_PARAM); @@ -1317,10 +1273,9 @@ int yyparse (); - -/*----------. -| yyparse. | -`----------*/ +/*-------------------------. +| yyparse or yypush_parse. | +`-------------------------*/ #ifdef YYPARSE_PARAM #if (defined __STDC__ || defined __C99__FUNC__ \ @@ -1344,88 +1299,97 @@ yyparse (info) #endif #endif { - /* The look-ahead symbol. */ +/* The lookahead symbol. */ int yychar; -/* The semantic value of the look-ahead symbol. */ +/* The semantic value of the lookahead symbol. */ YYSTYPE yylval; -/* Number of syntax errors so far. */ -int yynerrs; -/* Location data for the look-ahead symbol. */ +/* Location data for the lookahead symbol. */ YYLTYPE yylloc; - int yystate; - int yyn; - int yyresult; - /* Number of tokens to shift before error messages enabled. */ - int yyerrstatus; - /* Look-ahead token as an internal (translated) token number. */ - int yytoken = 0; -#if YYERROR_VERBOSE - /* Buffer for error messages, and its allocated size. */ - char yymsgbuf[128]; - char *yymsg = yymsgbuf; - YYSIZE_T yymsg_alloc = sizeof yymsgbuf; -#endif + /* Number of syntax errors so far. */ + int yynerrs; + + int yystate; + /* Number of tokens to shift before error messages enabled. */ + int yyerrstatus; - /* Three stacks and their tools: - `yyss': related to states, - `yyvs': related to semantic values, - `yyls': related to locations. + /* The stacks and their tools: + `yyss': related to states. + `yyvs': related to semantic values. + `yyls': related to locations. - Refer to the stacks thru separate pointers, to allow yyoverflow - to reallocate them elsewhere. */ + Refer to the stacks thru separate pointers, to allow yyoverflow + to reallocate them elsewhere. */ - /* The state stack. */ - yytype_int16 yyssa[YYINITDEPTH]; - yytype_int16 *yyss = yyssa; - yytype_int16 *yyssp; + /* The state stack. */ + yytype_int16 yyssa[YYINITDEPTH]; + yytype_int16 *yyss; + yytype_int16 *yyssp; - /* The semantic value stack. */ - YYSTYPE yyvsa[YYINITDEPTH]; - YYSTYPE *yyvs = yyvsa; - YYSTYPE *yyvsp; + /* The semantic value stack. */ + YYSTYPE yyvsa[YYINITDEPTH]; + YYSTYPE *yyvs; + YYSTYPE *yyvsp; - /* The location stack. */ - YYLTYPE yylsa[YYINITDEPTH]; - YYLTYPE *yyls = yylsa; - YYLTYPE *yylsp; - /* The locations where the error started and ended. */ - YYLTYPE yyerror_range[2]; + /* The location stack. */ + YYLTYPE yylsa[YYINITDEPTH]; + YYLTYPE *yyls; + YYLTYPE *yylsp; -#define YYPOPSTACK(N) (yyvsp -= (N), yyssp -= (N), yylsp -= (N)) + /* The locations where the error started and ended. */ + YYLTYPE yyerror_range[2]; - YYSIZE_T yystacksize = YYINITDEPTH; + YYSIZE_T yystacksize; + int yyn; + int yyresult; + /* Lookahead token as an internal (translated) token number. */ + int yytoken; /* The variables used to return semantic value and location from the action routines. */ YYSTYPE yyval; YYLTYPE yyloc; +#if YYERROR_VERBOSE + /* Buffer for error messages, and its allocated size. */ + char yymsgbuf[128]; + char *yymsg = yymsgbuf; + YYSIZE_T yymsg_alloc = sizeof yymsgbuf; +#endif + +#define YYPOPSTACK(N) (yyvsp -= (N), yyssp -= (N), yylsp -= (N)) + /* The number of symbols on the RHS of the reduced rule. Keep to zero when no symbol should be popped. */ int yylen = 0; + yytoken = 0; + yyss = yyssa; + yyvs = yyvsa; + yyls = yylsa; + yystacksize = YYINITDEPTH; + YYDPRINTF ((stderr, "Starting parse\n")); yystate = 0; yyerrstatus = 0; yynerrs = 0; - yychar = YYEMPTY; /* Cause a token to be read. */ + yychar = YYEMPTY; /* Cause a token to be read. */ /* Initialize stack pointers. Waste one element of value and location stack so that they stay on the same level as the state stack. The wasted elements are never initialized. */ - yyssp = yyss; yyvsp = yyvs; yylsp = yyls; -#if YYLTYPE_IS_TRIVIAL + +#if defined YYLTYPE_IS_TRIVIAL && YYLTYPE_IS_TRIVIAL /* Initialize the default location before parsing starts. */ yylloc.first_line = yylloc.last_line = 1; - yylloc.first_column = yylloc.last_column = 0; + yylloc.first_column = yylloc.last_column = 1; #endif goto yysetstate; @@ -1464,6 +1428,7 @@ YYLTYPE yylloc; &yyvs1, yysize * sizeof (*yyvsp), &yyls1, yysize * sizeof (*yylsp), &yystacksize); + yyls = yyls1; yyss = yyss1; yyvs = yyvs1; @@ -1485,9 +1450,9 @@ YYLTYPE yylloc; (union yyalloc *) YYSTACK_ALLOC (YYSTACK_BYTES (yystacksize)); if (! yyptr) goto yyexhaustedlab; - YYSTACK_RELOCATE (yyss); - YYSTACK_RELOCATE (yyvs); - YYSTACK_RELOCATE (yyls); + YYSTACK_RELOCATE (yyss_alloc, yyss); + YYSTACK_RELOCATE (yyvs_alloc, yyvs); + YYSTACK_RELOCATE (yyls_alloc, yyls); # undef YYSTACK_RELOCATE if (yyss1 != yyssa) YYSTACK_FREE (yyss1); @@ -1508,6 +1473,9 @@ YYLTYPE yylloc; YYDPRINTF ((stderr, "Entering state %d\n", yystate)); + if (yystate == YYFINAL) + YYACCEPT; + goto yybackup; /*-----------. @@ -1516,16 +1484,16 @@ YYLTYPE yylloc; yybackup: /* Do appropriate processing given the current state. Read a - look-ahead token if we need one and don't already have one. */ + lookahead token if we need one and don't already have one. */ - /* First try to decide what to do without reference to look-ahead token. */ + /* First try to decide what to do without reference to lookahead token. */ yyn = yypact[yystate]; if (yyn == YYPACT_NINF) goto yydefault; - /* Not known => get a look-ahead token if don't already have one. */ + /* Not known => get a lookahead token if don't already have one. */ - /* YYCHAR is either YYEMPTY or YYEOF or a valid look-ahead symbol. */ + /* YYCHAR is either YYEMPTY or YYEOF or a valid lookahead symbol. */ if (yychar == YYEMPTY) { YYDPRINTF ((stderr, "Reading a token: ")); @@ -1557,20 +1525,16 @@ yybackup: goto yyreduce; } - if (yyn == YYFINAL) - YYACCEPT; - /* Count tokens shifted since error; after three, turn off error status. */ if (yyerrstatus) yyerrstatus--; - /* Shift the look-ahead token. */ + /* Shift the lookahead token. */ YY_SYMBOL_PRINT ("Shifting", yytoken, &yylval, &yylloc); - /* Discard the shifted token unless it is eof. */ - if (yychar != YYEOF) - yychar = YYEMPTY; + /* Discard the shifted token. */ + yychar = YYEMPTY; yystate = yyn; *++yyvsp = yylval; @@ -2062,7 +2026,6 @@ yyreduce: break; -/* Line 1267 of yacc.c. */ default: break; } @@ -2139,7 +2102,7 @@ yyerrlab: if (yyerrstatus == 3) { - /* If just tried and failed to reuse look-ahead token after an + /* If just tried and failed to reuse lookahead token after an error, discard it. */ if (yychar <= YYEOF) @@ -2156,7 +2119,7 @@ yyerrlab: } } - /* Else will try to reuse look-ahead token after shifting the error + /* Else will try to reuse lookahead token after shifting the error token. */ goto yyerrlab1; @@ -2214,14 +2177,11 @@ yyerrlab1: YY_STACK_PRINT (yyss, yyssp); } - if (yyn == YYFINAL) - YYACCEPT; - *++yyvsp = yylval; yyerror_range[1] = yylloc; /* Using YYLLOC is tempting, but would change the location of - the look-ahead. YYLOC is available though. */ + the lookahead. YYLOC is available though. */ YYLLOC_DEFAULT (yyloc, (yyerror_range - 1), 2); *++yylsp = yyloc; @@ -2246,7 +2206,7 @@ yyabortlab: yyresult = 1; goto yyreturn; -#ifndef yyoverflow +#if !defined(yyoverflow) || YYERROR_VERBOSE /*-------------------------------------------------. | yyexhaustedlab -- memory exhaustion comes here. | `-------------------------------------------------*/ @@ -2257,7 +2217,7 @@ yyexhaustedlab: #endif yyreturn: - if (yychar != YYEOF && yychar != YYEMPTY) + if (yychar != YYEMPTY) yydestruct ("Cleanup: discarding lookahead", yytoken, &yylval, &yylloc, info); /* Do not reclaim the symbols of the rule which action triggered @@ -2513,7 +2473,7 @@ TclDateerror( infoPtr->separatrix = "\n"; } -static time_t +time_t ToSeconds( time_t Hours, time_t Minutes, @@ -2680,7 +2640,7 @@ TclDatelex( location->first_column = yyInput - info->dateStart; for ( ; ; ) { - while (TclIsSpaceProc(*yyInput)) { + while (isspace(UCHAR(*yyInput))) { yyInput++; } @@ -2740,36 +2700,20 @@ TclDatelex( } while (Count > 0); } } - + int -TclClockOldscanObjCmd( - ClientData clientData, /* Unused */ +TclClockFreeScan( Tcl_Interp *interp, /* Tcl interpreter */ - int objc, /* Count of paraneters */ - Tcl_Obj *const *objv) /* Parameters */ + DateInfo *info) /* Input and result parameters */ { - Tcl_Obj *result, *resultElement; - int yr, mo, da; - DateInfo dateInfo; - DateInfo* info = &dateInfo; int status; - if (objc != 5) { - Tcl_WrongNumArgs(interp, 1, objv, - "stringToParse baseYear baseMonth baseDay" ); - return TCL_ERROR; - } - - yyInput = Tcl_GetString( objv[1] ); - dateInfo.dateStart = yyInput; + /* + * yyInput = stringToParse; + * yyYear = baseYear; yyMonth = baseMonth; yyDay = baseDay; + */ yyHaveDate = 0; - if (Tcl_GetIntFromObj(interp, objv[2], &yr) != TCL_OK - || Tcl_GetIntFromObj(interp, objv[3], &mo) != TCL_OK - || Tcl_GetIntFromObj(interp, objv[4], &da) != TCL_OK) { - return TCL_ERROR; - } - yyYear = yr; yyMonth = mo; yyDay = da; yyHaveTime = 0; yyHour = 0; yyMinutes = 0; yySeconds = 0; yyMeridian = MER24; @@ -2786,19 +2730,20 @@ TclClockOldscanObjCmd( yyHaveRel = 0; yyRelMonth = 0; yyRelDay = 0; yyRelSeconds = 0; yyRelPointer = NULL; - dateInfo.messages = Tcl_NewObj(); - dateInfo.separatrix = ""; - Tcl_IncrRefCount(dateInfo.messages); + info->messages = Tcl_NewObj(); + info->separatrix = ""; + Tcl_IncrRefCount(info->messages); - status = yyparse(&dateInfo); + info->dateStart = yyInput; + status = yyparse(info); if (status == 1) { - Tcl_SetObjResult(interp, dateInfo.messages); - Tcl_DecrRefCount(dateInfo.messages); + Tcl_SetObjResult(interp, info->messages); + Tcl_DecrRefCount(info->messages); Tcl_SetErrorCode(interp, "TCL", "VALUE", "DATE", "PARSE", NULL); return TCL_ERROR; } else if (status == 2) { Tcl_SetObjResult(interp, Tcl_NewStringObj("memory exhausted", -1)); - Tcl_DecrRefCount(dateInfo.messages); + Tcl_DecrRefCount(info->messages); Tcl_SetErrorCode(interp, "TCL", "MEMORY", NULL); return TCL_ERROR; } else if (status != 0) { @@ -2806,11 +2751,11 @@ TclClockOldscanObjCmd( "from date parser. Please " "report this error as a " "bug in Tcl.", -1)); - Tcl_DecrRefCount(dateInfo.messages); + Tcl_DecrRefCount(info->messages); Tcl_SetErrorCode(interp, "TCL", "BUG", NULL); return TCL_ERROR; } - Tcl_DecrRefCount(dateInfo.messages); + Tcl_DecrRefCount(info->messages); if (yyHaveDate > 1) { Tcl_SetObjResult(interp, @@ -2843,6 +2788,40 @@ TclClockOldscanObjCmd( return TCL_ERROR; } + return TCL_OK; +} + +int +TclClockOldscanObjCmd( + ClientData clientData, /* Unused */ + Tcl_Interp *interp, /* Tcl interpreter */ + int objc, /* Count of paraneters */ + Tcl_Obj *const *objv) /* Parameters */ +{ + Tcl_Obj *result, *resultElement; + int yr, mo, da; + DateInfo dateInfo; + DateInfo* info = &dateInfo; + + if (objc != 5) { + Tcl_WrongNumArgs(interp, 1, objv, + "stringToParse baseYear baseMonth baseDay" ); + return TCL_ERROR; + } + + yyInput = Tcl_GetString( objv[1] ); + + if (Tcl_GetIntFromObj(interp, objv[2], &yr) != TCL_OK + || Tcl_GetIntFromObj(interp, objv[3], &mo) != TCL_OK + || Tcl_GetIntFromObj(interp, objv[4], &da) != TCL_OK) { + return TCL_ERROR; + } + yyYear = yr; yyMonth = mo; yyDay = da; + + if (TclClockFreeScan(interp, info) != TCL_OK) { + return TCL_ERROR; + } + result = Tcl_NewObj(); resultElement = Tcl_NewObj(); if (yyHaveDate) { diff --git a/generic/tclDate.h b/generic/tclDate.h new file mode 100644 index 0000000..91e677f --- /dev/null +++ b/generic/tclDate.h @@ -0,0 +1,77 @@ +/* + * tclDate.h -- + * + * This header file handles common usage of clock primitives + * between tclDate.c (yacc) and tclClock.c. + * + * Copyright (c) 2014 Serg G. Brester (aka sebres) + * + * See the file "license.terms" for information on usage and redistribution + * of this file, and for a DISCLAIMER OF ALL WARRANTIES. + */ + +#ifndef _TCLCLOCK_H +#define _TCLCLOCK_H + +/* + * Structure contains return parsed fields. + */ + +typedef struct DateInfo { + + Tcl_Obj* messages; /* Error messages */ + const char* separatrix; /* String separating messages */ + + time_t dateYear; + time_t dateMonth; + time_t dateDay; + int dateHaveDate; + + time_t dateHour; + time_t dateMinutes; + time_t dateSeconds; + int dateMeridian; + int dateHaveTime; + + time_t dateTimezone; + int dateDSTmode; + int dateHaveZone; + + time_t dateRelMonth; + time_t dateRelDay; + time_t dateRelSeconds; + int dateHaveRel; + + time_t dateMonthOrdinal; + int dateHaveOrdinalMonth; + + time_t dateDayOrdinal; + time_t dateDayNumber; + int dateHaveDay; + + const char *dateStart; + const char *dateInput; + time_t *dateRelPointer; + + int dateDigitCount; +} DateInfo; + + +/* + * Meridian: am, pm, or 24-hour style. + */ + +typedef enum _MERIDIAN { + MERam, MERpm, MER24 +} MERIDIAN; + +/* + * Prototypes of module functions. + */ + +MODULE_SCOPE time_t ToSeconds(time_t Hours, time_t Minutes, + time_t Seconds, MERIDIAN Meridian); + +MODULE_SCOPE int TclClockFreeScan(Tcl_Interp *interp, DateInfo *info); + +#endif /* _TCLCLOCK_H */ diff --git a/generic/tclGetDate.y b/generic/tclGetDate.y index da4c3fd..ac781ad 100644 --- a/generic/tclGetDate.y +++ b/generic/tclGetDate.y @@ -50,44 +50,7 @@ * parsed fields will be returned. */ -typedef struct DateInfo { - - Tcl_Obj* messages; /* Error messages */ - const char* separatrix; /* String separating messages */ - - time_t dateYear; - time_t dateMonth; - time_t dateDay; - int dateHaveDate; - - time_t dateHour; - time_t dateMinutes; - time_t dateSeconds; - int dateMeridian; - int dateHaveTime; - - time_t dateTimezone; - int dateDSTmode; - int dateHaveZone; - - time_t dateRelMonth; - time_t dateRelDay; - time_t dateRelSeconds; - int dateHaveRel; - - time_t dateMonthOrdinal; - int dateHaveOrdinalMonth; - - time_t dateDayOrdinal; - time_t dateDayNumber; - int dateHaveDay; - - const char *dateStart; - const char *dateInput; - time_t *dateRelPointer; - - int dateDigitCount; -} DateInfo; +#include "tclDate.h" #define YYMALLOC ckalloc #define YYFREE(x) (ckfree((void*) (x))) @@ -150,14 +113,6 @@ typedef enum _DSTMODE { DSTon, DSToff, DSTmaybe } DSTMODE; -/* - * Meridian: am, pm, or 24-hour style. - */ - -typedef enum _MERIDIAN { - MERam, MERpm, MER24 -} MERIDIAN; - %} %union { @@ -176,8 +131,6 @@ static int LookupWord(YYSTYPE* yylvalPtr, char *buff); DateInfo* info, const char *s); static int TclDatelex(YYSTYPE* yylvalPtr, YYLTYPE* location, DateInfo* info); -static time_t ToSeconds(time_t Hours, time_t Minutes, - time_t Seconds, MERIDIAN Meridian); MODULE_SCOPE int yyparse(DateInfo*); %} @@ -730,7 +683,7 @@ TclDateerror( infoPtr->separatrix = "\n"; } -static time_t +time_t ToSeconds( time_t Hours, time_t Minutes, @@ -957,36 +910,20 @@ TclDatelex( } while (Count > 0); } } - + int -TclClockOldscanObjCmd( - ClientData clientData, /* Unused */ +TclClockFreeScan( Tcl_Interp *interp, /* Tcl interpreter */ - int objc, /* Count of paraneters */ - Tcl_Obj *const *objv) /* Parameters */ + DateInfo *info) /* Input and result parameters */ { - Tcl_Obj *result, *resultElement; - int yr, mo, da; - DateInfo dateInfo; - DateInfo* info = &dateInfo; int status; - if (objc != 5) { - Tcl_WrongNumArgs(interp, 1, objv, - "stringToParse baseYear baseMonth baseDay" ); - return TCL_ERROR; - } - - yyInput = Tcl_GetString( objv[1] ); - dateInfo.dateStart = yyInput; + /* + * yyInput = stringToParse; + * yyYear = baseYear; yyMonth = baseMonth; yyDay = baseDay; + */ yyHaveDate = 0; - if (Tcl_GetIntFromObj(interp, objv[2], &yr) != TCL_OK - || Tcl_GetIntFromObj(interp, objv[3], &mo) != TCL_OK - || Tcl_GetIntFromObj(interp, objv[4], &da) != TCL_OK) { - return TCL_ERROR; - } - yyYear = yr; yyMonth = mo; yyDay = da; yyHaveTime = 0; yyHour = 0; yyMinutes = 0; yySeconds = 0; yyMeridian = MER24; @@ -1003,19 +940,20 @@ TclClockOldscanObjCmd( yyHaveRel = 0; yyRelMonth = 0; yyRelDay = 0; yyRelSeconds = 0; yyRelPointer = NULL; - dateInfo.messages = Tcl_NewObj(); - dateInfo.separatrix = ""; - Tcl_IncrRefCount(dateInfo.messages); + info->messages = Tcl_NewObj(); + info->separatrix = ""; + Tcl_IncrRefCount(info->messages); - status = yyparse(&dateInfo); + info->dateStart = yyInput; + status = yyparse(info); if (status == 1) { - Tcl_SetObjResult(interp, dateInfo.messages); - Tcl_DecrRefCount(dateInfo.messages); + Tcl_SetObjResult(interp, info->messages); + Tcl_DecrRefCount(info->messages); Tcl_SetErrorCode(interp, "TCL", "VALUE", "DATE", "PARSE", NULL); return TCL_ERROR; } else if (status == 2) { Tcl_SetObjResult(interp, Tcl_NewStringObj("memory exhausted", -1)); - Tcl_DecrRefCount(dateInfo.messages); + Tcl_DecrRefCount(info->messages); Tcl_SetErrorCode(interp, "TCL", "MEMORY", NULL); return TCL_ERROR; } else if (status != 0) { @@ -1023,11 +961,11 @@ TclClockOldscanObjCmd( "from date parser. Please " "report this error as a " "bug in Tcl.", -1)); - Tcl_DecrRefCount(dateInfo.messages); + Tcl_DecrRefCount(info->messages); Tcl_SetErrorCode(interp, "TCL", "BUG", NULL); return TCL_ERROR; } - Tcl_DecrRefCount(dateInfo.messages); + Tcl_DecrRefCount(info->messages); if (yyHaveDate > 1) { Tcl_SetObjResult(interp, @@ -1060,6 +998,40 @@ TclClockOldscanObjCmd( return TCL_ERROR; } + return TCL_OK; +} + +int +TclClockOldscanObjCmd( + ClientData clientData, /* Unused */ + Tcl_Interp *interp, /* Tcl interpreter */ + int objc, /* Count of paraneters */ + Tcl_Obj *const *objv) /* Parameters */ +{ + Tcl_Obj *result, *resultElement; + int yr, mo, da; + DateInfo dateInfo; + DateInfo* info = &dateInfo; + + if (objc != 5) { + Tcl_WrongNumArgs(interp, 1, objv, + "stringToParse baseYear baseMonth baseDay" ); + return TCL_ERROR; + } + + yyInput = Tcl_GetString( objv[1] ); + + if (Tcl_GetIntFromObj(interp, objv[2], &yr) != TCL_OK + || Tcl_GetIntFromObj(interp, objv[3], &mo) != TCL_OK + || Tcl_GetIntFromObj(interp, objv[4], &da) != TCL_OK) { + return TCL_ERROR; + } + yyYear = yr; yyMonth = mo; yyDay = da; + + if (TclClockFreeScan(interp, info) != TCL_OK) { + return TCL_ERROR; + } + result = Tcl_NewObj(); resultElement = Tcl_NewObj(); if (yyHaveDate) { diff --git a/library/clock.tcl b/library/clock.tcl index 5b48eb3..9c3f95c 100755 --- a/library/clock.tcl +++ b/library/clock.tcl @@ -287,6 +287,10 @@ proc ::tcl::clock::Initialize {} { variable FEB_28 58 + # Current year century and year of century switch + variable CurrentYearCentury 2000 + variable YearOfCenturySwitch 37 + # Translation table to map Windows TZI onto cities, so that the Olson # rules can apply. In some cases the mapping is ambiguous, so it's wise # to specify $::env(TCL_TZ) rather than simply depending on the system @@ -1295,7 +1299,7 @@ proc ::tcl::clock::__org_scan { args } { # #---------------------------------------------------------------------- -proc ::tcl::clock::FreeScan { string base timezone locale } { +proc ::tcl::clock::__org_FreeScan { string base timezone locale } { variable TZData @@ -1341,7 +1345,8 @@ proc ::tcl::clock::FreeScan { string base timezone locale } { if { [llength $parseDate] > 0 } { lassign $parseDate y m d if { $y < 100 } { - if { $y >= 39 } { + variable YearOfCenturySwitch + if { $y > $YearOfCenturySwitch } { incr y 1900 } else { incr y 2000 @@ -2719,12 +2724,14 @@ proc ::tcl::clock::ScanWide { str } { proc ::tcl::clock::InterpretTwoDigitYear { date baseTime { twoDigitField yearOfCentury } { fourDigitField year } } { + variable CurrentYearCentury + variable YearOfCenturySwitch set yr [dict get $date $twoDigitField] - if { $yr <= 37 } { - dict set date $fourDigitField [expr { $yr + 2000 }] - } else { - dict set date $fourDigitField [expr { $yr + 1900 }] + incr yr $CurrentYearCentury + if { $yr <= $YearOfCenturySwitch } { + incr yr -100 } + dict set date $fourDigitField $yr return $date } diff --git a/library/init.tcl b/library/init.tcl index e6df12b..4bbce51 100644 --- a/library/init.tcl +++ b/library/init.tcl @@ -178,7 +178,7 @@ if {[interp issafe]} { # Auto-loading stubs for 'clock.tcl' - foreach cmd {add format FreeScan} { + foreach cmd {add format} { proc ::tcl::clock::$cmd args { variable TclLibDir source -encoding utf-8 [file join $TclLibDir clock.tcl] diff --git a/win/makefile.vc b/win/makefile.vc index d6de5e1..26ee669 100644 --- a/win/makefile.vc +++ b/win/makefile.vc @@ -482,7 +482,9 @@ cdebug = $(cdebug) -Zi ### Warnings are too many, can't support warnings into errors. cdebug = -Zi -Od $(DEBUGFLAGS) !else -cdebug = -Zi -WX $(DEBUGFLAGS) +# no -WX option here (error C2220: warning treated as error): +#cdebug = -Zi -WX $(DEBUGFLAGS) +cdebug = -Zi $(DEBUGFLAGS) !endif ### Declarations common to all compiler options -- cgit v0.12 From 736824a25976c9bdf14978f1592078171cb6dd5b Mon Sep 17 00:00:00 2001 From: sebres Date: Tue, 10 Jan 2017 21:59:59 +0000 Subject: [temp-commit]: ClockFreeScan almost ready, test-performance cases merged --- generic/tclClock.c | 370 +++++++++++++++++++++++++++++++++++++++------- library/clock.tcl | 75 +++++----- library/init.tcl | 2 +- tests-perf/clock.perf.tcl | 59 ++++++++ 4 files changed, 415 insertions(+), 91 deletions(-) create mode 100644 tests-perf/clock.perf.tcl diff --git a/generic/tclClock.c b/generic/tclClock.c index 24ed095..6d619e0 100644 --- a/generic/tclClock.c +++ b/generic/tclClock.c @@ -81,7 +81,7 @@ typedef enum ClockLiteral { #endif LIT__END } ClockLiteral; -static const char *const literals[] = { +static const char *const Literals[] = { "", "%a %b %d %H:%M:%S %Z %Y", "BCE", "C", @@ -114,6 +114,14 @@ static const char *const literals[] = { typedef struct ClockClientData { size_t refCount; /* Number of live references. */ Tcl_Obj **literals; /* Pool of object literals. */ + /* Cache for current clock parameters, imparted via "configure" */ + unsigned int LastTZEpoch; + Tcl_Obj *LastSystemTimeZone; + Tcl_Obj *SystemSetupTZData; + Tcl_Obj *GMTSetupTimeZone; + Tcl_Obj *GMTSetupTZData; + Tcl_Obj *LastSetupTimeZone; + Tcl_Obj *LastSetupTZData; } ClockClientData; /* @@ -171,6 +179,8 @@ static int ConvertLocalToUTCUsingTable(Tcl_Interp *, TclDateFields *, int, Tcl_Obj *const[]); static int ConvertLocalToUTCUsingC(Tcl_Interp *, TclDateFields *, int); +static int ClockConfigureObjCmd(ClientData clientData, + Tcl_Interp *interp, int objc, Tcl_Obj *const objv[]); static Tcl_Obj * LookupLastTransition(Tcl_Interp *, Tcl_WideInt, int, Tcl_Obj *const *); static void GetYearWeekDay(TclDateFields *, int); @@ -222,6 +232,7 @@ static int ClockFreeScan( Tcl_Obj *strObj, Tcl_WideInt baseVal, Tcl_Obj *timezoneObj, Tcl_Obj *locale); static struct tm * ThreadSafeLocalTime(const time_t *); +static unsigned int TzsetGetEpoch(void); static void TzsetIfNecessary(void); static void ClockDeleteCmdProc(ClientData); @@ -245,6 +256,7 @@ static const struct ClockCommand clockCommands[] = { { "milliseconds", ClockMillisecondsObjCmd }, { "seconds", ClockSecondsObjCmd }, { "scan", ClockScanObjCmd }, + { "configure", ClockConfigureObjCmd }, { "Oldscan", TclClockOldscanObjCmd }, { "ConvertLocalToUTC", ClockConvertlocaltoutcObjCmd }, { "GetDateFields", ClockGetdatefieldsObjCmd }, @@ -302,9 +314,16 @@ TclClockInit( data->refCount = 0; data->literals = ckalloc(LIT__END * sizeof(Tcl_Obj*)); for (i = 0; i < LIT__END; ++i) { - data->literals[i] = Tcl_NewStringObj(literals[i], -1); + data->literals[i] = Tcl_NewStringObj(Literals[i], -1); Tcl_IncrRefCount(data->literals[i]); } + data->LastTZEpoch = 0; + data->LastSystemTimeZone = NULL; + data->SystemSetupTZData = NULL; + data->GMTSetupTimeZone = NULL; + data->GMTSetupTZData = NULL; + data->LastSetupTimeZone = NULL; + data->LastSetupTZData = NULL; /* * Install the commands. @@ -322,6 +341,191 @@ TclClockInit( /* *---------------------------------------------------------------------- + * + * ClockDeleteCmdProc -- + * + * Remove a reference to the clock client data, and clean up memory + * when it's all gone. + * + * Results: + * None. + * + *---------------------------------------------------------------------- + */ + +static void +ClockDeleteCmdProc( + ClientData clientData) /* Opaque pointer to the client data */ +{ + ClockClientData *data = clientData; + int i; + + if (data->refCount-- <= 1) { + for (i = 0; i < LIT__END; ++i) { + Tcl_DecrRefCount(data->literals[i]); + } + + if (data->LastSystemTimeZone) { + Tcl_DecrRefCount(data->LastSystemTimeZone); + } + if (data->GMTSetupTimeZone) { + Tcl_DecrRefCount(data->GMTSetupTimeZone); + } + if (data->LastSetupTimeZone) { + Tcl_DecrRefCount(data->LastSetupTimeZone); + } + + ckfree(data->literals); + ckfree(data); + } +} + +/* + *---------------------------------------------------------------------- + */ +inline Tcl_Obj * +NormTimezoneObj( + ClockClientData *dataPtr, /* Client data containing literal pool */ + Tcl_Obj * timezoneObj) +{ + const char * tz; + if ( timezoneObj == dataPtr->literals[LIT_GMT] + || timezoneObj == dataPtr->LastSystemTimeZone + || timezoneObj == dataPtr->LastSetupTimeZone + ) { + return timezoneObj; + } + + tz = TclGetString(timezoneObj); + if ( + strcmp(tz, Literals[LIT_GMT]) == 0 + ) { + timezoneObj = dataPtr->literals[LIT_GMT]; + } + else + if (dataPtr->LastSystemTimeZone != NULL && + (timezoneObj == dataPtr->LastSystemTimeZone + || strcmp(tz, TclGetString(dataPtr->LastSystemTimeZone)) == 0 + ) + ) { + timezoneObj = dataPtr->LastSystemTimeZone; + } + else + if (dataPtr->LastSetupTimeZone != NULL && + (timezoneObj == dataPtr->LastSetupTimeZone + || strcmp(tz, TclGetString(dataPtr->LastSetupTimeZone)) == 0 + ) + ) { + timezoneObj = dataPtr->LastSetupTimeZone; + } + return timezoneObj; +} + +/* + *---------------------------------------------------------------------- + */ +static int +ClockConfigureObjCmd( + ClientData clientData, /* Client data containing literal pool */ + Tcl_Interp *interp, /* Tcl interpreter */ + int objc, /* Parameter count */ + Tcl_Obj *const objv[]) /* Parameter vector */ +{ + ClockClientData *dataPtr = clientData; + Tcl_Obj **litPtr = dataPtr->literals; + + static const char *const options[] = { + "-system-tz", "-setup-tz", "-clear", + NULL + }; + enum optionInd { + CLOCK_SYSTEM_TZ, CLOCK_SETUP_TZ, CLOCK_CLEAR_CACHE, + CLOCK_SETUP_GMT, CLOCK_SETUP_NOP + }; + int optionIndex; /* Index of an option. */ + int i; + + for (i = 1; i < objc; i+=2) { + if (Tcl_GetIndexFromObj(interp, objv[i], options, + "option", 0, &optionIndex) != TCL_OK) { + Tcl_SetErrorCode(interp, "CLOCK", "badOption", + Tcl_GetString(objv[i]), NULL); + return TCL_ERROR; + } + if (optionIndex == CLOCK_SYSTEM_TZ || optionIndex == CLOCK_CLEAR_CACHE) { + if (dataPtr->LastSystemTimeZone) { + Tcl_DecrRefCount(dataPtr->LastSystemTimeZone); + dataPtr->LastSystemTimeZone = NULL; + dataPtr->SystemSetupTZData = NULL; + } + if (optionIndex != CLOCK_CLEAR_CACHE) { + /* validate current tz-epoch */ + unsigned int lastTZEpoch = TzsetGetEpoch(); + if (i+1 < objc) { + Tcl_IncrRefCount( + dataPtr->LastSystemTimeZone = objv[i+1]); + dataPtr->LastTZEpoch = lastTZEpoch; + } else if (dataPtr->LastSystemTimeZone + && dataPtr->LastTZEpoch == lastTZEpoch) { + Tcl_SetObjResult(interp, dataPtr->LastSystemTimeZone); + } + } + } + if (optionIndex == CLOCK_SETUP_TZ || optionIndex == CLOCK_CLEAR_CACHE) { + Tcl_Obj *timezoneObj = NULL; + /* differentiate GMT and system zones, because used often */ + if (i+1 < objc) { + timezoneObj = NormTimezoneObj(dataPtr, objv[i+1]); + if (optionIndex == CLOCK_SETUP_TZ) { + if (timezoneObj == litPtr[LIT_GMT]) { + optionIndex = CLOCK_SETUP_GMT; + } else if (timezoneObj == dataPtr->LastSystemTimeZone) { + optionIndex = CLOCK_SETUP_NOP; + } + } + } + + if (optionIndex == CLOCK_SETUP_GMT || optionIndex == CLOCK_CLEAR_CACHE) { + if (dataPtr->GMTSetupTimeZone) { + Tcl_DecrRefCount(dataPtr->GMTSetupTimeZone); + dataPtr->GMTSetupTimeZone = NULL; + dataPtr->GMTSetupTZData = NULL; + } + if (optionIndex != CLOCK_CLEAR_CACHE) { + if (i+1 < objc) { + Tcl_IncrRefCount( + dataPtr->GMTSetupTimeZone = timezoneObj); + } else if (dataPtr->GMTSetupTimeZone) { + Tcl_SetObjResult(interp, dataPtr->GMTSetupTimeZone); + } + } + } + if (optionIndex == CLOCK_SETUP_TZ || optionIndex == CLOCK_CLEAR_CACHE) { + if (dataPtr->LastSetupTimeZone) { + Tcl_DecrRefCount(dataPtr->LastSetupTimeZone); + dataPtr->LastSetupTimeZone = NULL; + dataPtr->LastSetupTZData = NULL; + } + if (optionIndex != CLOCK_CLEAR_CACHE) { + if (i+1 < objc) { + Tcl_IncrRefCount( + dataPtr->LastSetupTimeZone = timezoneObj); + } else if (dataPtr->LastSetupTimeZone) { + Tcl_SetObjResult(interp, dataPtr->LastSetupTimeZone); + } + } + } + } + if (optionIndex == CLOCK_CLEAR_CACHE) { + dataPtr->LastTZEpoch = 0; + } + } + + return TCL_OK; +} + +/* + *---------------------------------------------------------------------- */ inline Tcl_Obj* ClockGetTZData( @@ -331,9 +535,38 @@ ClockGetTZData( { ClockClientData *dataPtr = clientData; Tcl_Obj **literals = dataPtr->literals; + Tcl_Obj *ret, **out = NULL; + + /* differentiate GMT and system zones, because used often */ + /* simple caching, because almost used the tz-data of last timezone, (unnecessary to + * touch the refCount of it, because it is always referenced in TZData array) + */ + if (timezoneObj == dataPtr->LastSystemTimeZone) { + if (dataPtr->SystemSetupTZData != NULL) + return dataPtr->SystemSetupTZData; + out = &dataPtr->SystemSetupTZData; + } + else + if (timezoneObj == dataPtr->GMTSetupTimeZone) { + if (dataPtr->GMTSetupTZData != NULL) + return dataPtr->GMTSetupTZData; + out = &dataPtr->GMTSetupTZData; + } + else + if (timezoneObj == dataPtr->LastSetupTimeZone) { + if (dataPtr->LastSetupTZData != NULL) { + return dataPtr->LastSetupTZData; + } + out = &dataPtr->LastSetupTZData; + } - return Tcl_ObjGetVar2(interp, literals[LIT_TZDATA], + ret = Tcl_ObjGetVar2(interp, literals[LIT_TZDATA], timezoneObj, TCL_LEAVE_ERR_MSG); + + /* cache using corresponding slot */ + if (ret != NULL && out != NULL) + *out = ret; + return ret; } /* *---------------------------------------------------------------------- @@ -344,7 +577,15 @@ ClockGetSystemTimeZone( Tcl_Interp *interp) /* Tcl interpreter */ { ClockClientData *dataPtr = clientData; - Tcl_Obj **literals = dataPtr->literals; + Tcl_Obj **literals; + + /* if known (cached and same epoch) - return now */ + if (dataPtr->LastSystemTimeZone != NULL + && dataPtr->LastTZEpoch == TzsetGetEpoch()) { + return dataPtr->LastSystemTimeZone; + } + + literals = dataPtr->literals; if (Tcl_EvalObjv(interp, 1, &literals[LIT_GETSYSTEMTIMEZONE], 0) != TCL_OK) { return NULL; @@ -354,7 +595,7 @@ ClockGetSystemTimeZone( /* *---------------------------------------------------------------------- */ -static int +static Tcl_Obj * ClockSetupTimeZone( ClientData clientData, /* Opaque pointer to literal pool, etc. */ Tcl_Interp *interp, /* Tcl interpreter */ @@ -364,9 +605,22 @@ ClockSetupTimeZone( Tcl_Obj **literals = dataPtr->literals; Tcl_Obj *callargs[2]; + /* differentiate GMT and system zones, because used often and already set */ + timezoneObj = NormTimezoneObj(dataPtr, timezoneObj); + if ( timezoneObj == dataPtr->GMTSetupTimeZone + || timezoneObj == dataPtr->LastSystemTimeZone + || timezoneObj == dataPtr->LastSetupTimeZone + ) { + return timezoneObj; + } + callargs[0] = literals[LIT_SETUPTIMEZONE]; callargs[1] = timezoneObj; - return Tcl_EvalObjv(interp, 2, callargs, 0); + + if (Tcl_EvalObjv(interp, 2, callargs, 0) == TCL_OK) { + return NormTimezoneObj(dataPtr, timezoneObj); + } + return NULL; } /* *---------------------------------------------------------------------- @@ -1752,12 +2006,10 @@ static int IsGregorianLeapYear( TclDateFields *fields) /* Date to test */ { - int year; + int year = fields->year; if (fields->era == BCE) { - year = 1 - fields->year; - } else { - year = fields->year; + year = 1 - year; } if (year%4 != 0) { return 0; @@ -2313,13 +2565,15 @@ ClockFreeScan( DateInfo yy; /* parse structure of TclClockFreeScan */ TclDateFields date; /* date fields used for converting from seconds */ + TclDateFields date2; /* date fields used for in-between calculation */ Tcl_Obj *tzdata; int secondOfDay; /* Seconds of day (time only calculation) */ Tcl_WideInt seconds; int ret = TCL_ERROR; - Tcl_Obj *cleanUpList = Tcl_NewObj(); + // Tcl_Obj *cleanUpList = Tcl_NewObj(); date.tzName = NULL; + date2.tzName = NULL; /* If time zone not specified use system time zone */ if (timezoneObj == NULL || @@ -2328,12 +2582,13 @@ ClockFreeScan( if (timezoneObj == NULL) { goto done; } - Tcl_ListObjAppendElement(NULL, cleanUpList, timezoneObj); + // Tcl_ListObjAppendElement(NULL, cleanUpList, timezoneObj); } /* Get the data for time changes in the given zone */ - if (ClockSetupTimeZone(clientData, interp, timezoneObj) != TCL_OK) { + timezoneObj = ClockSetupTimeZone(clientData, interp, timezoneObj); + if (timezoneObj == NULL) { goto done; } @@ -2366,9 +2621,8 @@ ClockFreeScan( if (TclClockFreeScan(interp, &yy) != TCL_OK) { Tcl_Obj *msg = Tcl_NewObj(); - Tcl_AppendPrintfToObj(msg, "unable to convert date-time string \"", - yy.dateInput, "\":", - TclGetString(Tcl_GetObjResult(interp))); + Tcl_AppendPrintfToObj(msg, "unable to convert date-time string \"%s\": %s", + Tcl_GetString(strObj), TclGetString(Tcl_GetObjResult(interp))); Tcl_SetObjResult(interp, msg); goto done; } @@ -2405,8 +2659,9 @@ ClockFreeScan( int dstFlag = 1 - yy.dateDSTmode; timezoneObj = ClockFormatNumericTimeZone( 60 * minEast + 3600 * dstFlag); - Tcl_ListObjAppendElement(NULL, cleanUpList, timezoneObj); - if (ClockSetupTimeZone(clientData, interp, timezoneObj) != TCL_OK) { + // Tcl_ListObjAppendElement(NULL, cleanUpList, timezoneObj); + timezoneObj = ClockSetupTimeZone(clientData, interp, timezoneObj); + if (timezoneObj == NULL) { goto done; } tzdata = ClockGetTZData(clientData, interp, timezoneObj); @@ -2458,7 +2713,7 @@ ClockFreeScan( if (yy.dateHaveRel) { - /* [SB] TODO: rewrite it in C: * / + /* seconds = [add $seconds \ yy.dateRelMonth months yy.dateRelDay days yy.dateRelMonthSecond seconds \ -timezone $timezone -locale $locale] @@ -2470,17 +2725,21 @@ ClockFreeScan( */ if (yy.dateHaveDay && !yy.dateHaveDate) { - TclDateFields date2; - date2.tzName = NULL; + memcpy(&date2, &date, sizeof(date)); + if (date2.tzName != NULL) { + Tcl_IncrRefCount(date2.tzName); + } + /* SetDateFieldsTimeZone(&date2, timezoneObj); date2.seconds = date.seconds; if (ClockGetDateFields(interp, &date2, tzdata, GREGORIAN_CHANGE_DATE) != TCL_OK) { - SetDateFieldsTimeZone(&date2, NULL); goto done; } + */ + date2.era = CE; date2.julianDay = WeekdayOnOrBefore(yy.dateDayNumber, date2.julianDay + 6) + 7 * yy.dateDayOrdinal; @@ -2493,13 +2752,12 @@ ClockFreeScan( + ( 86400 * (Tcl_WideInt)date2.julianDay ) + secondOfDay; - SetDateFieldsTimeZone(&date2, timezoneObj); + // check set time zone again may be really necessary here: + // SetDateFieldsTimeZone(&date2, timezoneObj); if (ConvertLocalToUTC(interp, &date2, tzdata, GREGORIAN_CHANGE_DATE) != TCL_OK) { - SetDateFieldsTimeZone(&date2, NULL); goto done; } - SetDateFieldsTimeZone(&date2, NULL); seconds = date2.seconds; } @@ -2536,7 +2794,10 @@ done: if (date.tzName != NULL) { Tcl_DecrRefCount(date.tzName); } - Tcl_DecrRefCount(cleanUpList); + if (date2.tzName != NULL) { + Tcl_DecrRefCount(date2.tzName); + } + // Tcl_DecrRefCount(cleanUpList); if (ret != TCL_OK) { return ret; @@ -2599,15 +2860,30 @@ ClockSecondsObjCmd( *---------------------------------------------------------------------- */ -static void -TzsetIfNecessary(void) +static unsigned int +TzsetGetEpoch(void) { static char* tzWas = INT2PTR(-1); /* Previous value of TZ, protected by - * clockMutex. */ - const char *tzIsNow; /* Current value of TZ */ + * clockMutex. */ + static long tzNextRefresh = 0; /* Latence before next refresh */ + static unsigned int tzWasEpoch = 1; /* Epoch, signals that TZ changed */ + + const char *tzIsNow; /* Current value of TZ */ + + /* fast check whether environment was changed (once per second) */ + Tcl_Time now; + Tcl_GetTime(&now); + if (now.sec < tzNextRefresh) { + return tzWasEpoch; + } + tzNextRefresh = now.sec + 1; + /* check in lock */ Tcl_MutexLock(&clockMutex); - tzIsNow = getenv("TZ"); + tzIsNow = getenv("TCL_TZ"); + if (tzIsNow == NULL) { + tzIsNow = getenv("TZ"); + } if (tzIsNow != NULL && (tzWas == NULL || tzWas == INT2PTR(-1) || strcmp(tzIsNow, tzWas) != 0)) { tzset(); @@ -2616,42 +2892,22 @@ TzsetIfNecessary(void) } tzWas = ckalloc(strlen(tzIsNow) + 1); strcpy(tzWas, tzIsNow); + tzWasEpoch++; } else if (tzIsNow == NULL && tzWas != NULL) { tzset(); if (tzWas != INT2PTR(-1)) ckfree(tzWas); tzWas = NULL; + tzWasEpoch++; } Tcl_MutexUnlock(&clockMutex); + + return tzWasEpoch; } - -/* - *---------------------------------------------------------------------- - * - * ClockDeleteCmdProc -- - * - * Remove a reference to the clock client data, and clean up memory - * when it's all gone. - * - * Results: - * None. - * - *---------------------------------------------------------------------- - */ static void -ClockDeleteCmdProc( - ClientData clientData) /* Opaque pointer to the client data */ +TzsetIfNecessary(void) { - ClockClientData *data = clientData; - int i; - - if (data->refCount-- <= 1) { - for (i = 0; i < LIT__END; ++i) { - Tcl_DecrRefCount(data->literals[i]); - } - ckfree(data->literals); - ckfree(data); - } + TzsetGetEpoch(); } /* diff --git a/library/clock.tcl b/library/clock.tcl index 9c3f95c..90b3c69 100755 --- a/library/clock.tcl +++ b/library/clock.tcl @@ -633,10 +633,6 @@ proc ::tcl::clock::Initialize {} { # in the given locales and dictionaries # mapping the numerals to their numeric # values. - # variable CachedSystemTimeZone; # If 'CachedSystemTimeZone' exists, - # it contains the value of the - # system time zone, as determined from - # the environment. variable TimeZoneBad {}; # Dictionary whose keys are time zone # names and whose values are 1 if # the time zone is unknown and 0 @@ -2984,13 +2980,12 @@ proc ::tcl::clock::InterpretHMS { date } { # Returns the system time zone. # # Side effects: -# Stores the sustem time zone in the 'CachedSystemTimeZone' -# variable, since determining it may be an expensive process. +# Stores the sustem time zone in engine configuration, since +# determining it may be an expensive process. # #---------------------------------------------------------------------- proc ::tcl::clock::GetSystemTimeZone {} { - variable CachedSystemTimeZone variable TimeZoneBad if {[set result [getenv TCL_TZ]] ne {}} { @@ -2999,29 +2994,33 @@ proc ::tcl::clock::GetSystemTimeZone {} { set timezone $result } if {![info exists timezone]} { - # Cache the time zone only if it was detected by one of the - # expensive methods. - if { [info exists CachedSystemTimeZone] } { - set timezone $CachedSystemTimeZone - } elseif { $::tcl_platform(platform) eq {windows} } { - set timezone [GuessWindowsTimeZone] - } elseif { [file exists /etc/localtime] - && ![catch {ReadZoneinfoFile \ - Tcl/Localtime /etc/localtime}] } { - set timezone :Tcl/Localtime - } else { - set timezone :localtime + # ask engine for the cached timezone: + set timezone [configure -system-tz] + if { $timezone ne "" } { + return $timezone } - set CachedSystemTimeZone $timezone + if { $::tcl_platform(platform) eq {windows} } { + set timezone [GuessWindowsTimeZone] + } elseif { [file exists /etc/localtime] + && ![catch {ReadZoneinfoFile \ + Tcl/Localtime /etc/localtime}] } { + set timezone :Tcl/Localtime + } else { + set timezone :localtime + } } if { ![dict exists $TimeZoneBad $timezone] } { - dict set TimeZoneBad $timezone [catch {SetupTimeZone $timezone}] + catch {SetupTimeZone $timezone} } - if { [dict get $TimeZoneBad $timezone] } { - return :localtime - } else { - return $timezone + + if { [dict exists $TimeZoneBad $timezone] } { + set timezone :localtime } + + # tell backend - current system timezone: + configure -system-tz $timezone + + return $timezone } #---------------------------------------------------------------------- @@ -3077,6 +3076,13 @@ proc ::tcl::clock::SetupTimeZone { timezone } { variable TZData if {! [info exists TZData($timezone)] } { + + variable TimeZoneBad + if { [dict exists $TimeZoneBad $timezone] } { + return -code error \ + -errorcode [list CLOCK badTimeZone $timezone] \ + "time zone \"$timezone\" not found" + } variable MINWIDE if { $timezone eq {:localtime} } { # Nothing to do, we'll convert using the localtime function @@ -3114,6 +3120,7 @@ proc ::tcl::clock::SetupTimeZone { timezone } { LoadZoneinfoFile [string range $timezone 1 end] }] } then { + dict set TimeZoneBad $timezone 1 return -code error \ -errorcode [list CLOCK badTimeZone $timezone] \ "time zone \"$timezone\" not found" @@ -3125,6 +3132,7 @@ proc ::tcl::clock::SetupTimeZone { timezone } { if { [lindex [dict get $opts -errorcode] 0] eq {CLOCK} } { dict unset opts -errorinfo } + dict set TimeZoneBad $timezone 1 return -options $opts $data } else { set TZData($timezone) $data @@ -3137,13 +3145,15 @@ proc ::tcl::clock::SetupTimeZone { timezone } { if { [catch { LoadTimeZoneFile $timezone }] && [catch { LoadZoneinfoFile $timezone } - opts] } { dict unset opts -errorinfo + dict set TimeZoneBad $timezone 1 return -options $opts "time zone $timezone not found" } set TZData($timezone) $TZData(:$timezone) } } - return + # tell backend - timezone is initialized: + configure -setup-tz $timezone } #---------------------------------------------------------------------- @@ -3214,12 +3224,12 @@ proc ::tcl::clock::GuessWindowsTimeZone {} { if { [dict exists $WinZoneInfo $data] } { set tzname [dict get $WinZoneInfo $data] if { ! [dict exists $TimeZoneBad $tzname] } { - dict set TimeZoneBad $tzname [catch {SetupTimeZone $tzname}] + catch {SetupTimeZone $tzname} } } else { set tzname {} } - if { $tzname eq {} || [dict get $TimeZoneBad $tzname] } { + if { $tzname eq {} || [dict exists $TimeZoneBad $tzname] } { lassign $data \ bias stdBias dstBias \ stdYear stdMonth stdDayOfWeek stdDayOfMonth \ @@ -4556,8 +4566,6 @@ proc ::tcl::clock::AddDays { days clockval timezone changeover } { proc ::tcl::clock::ChangeCurrentLocale {args} { variable FormatProc variable LocaleNumeralCache - variable CachedSystemTimeZone - variable TimeZoneBad foreach p [info procs [namespace current]::scanproc'*'current] { rename $p {} @@ -4590,9 +4598,11 @@ proc ::tcl::clock::ChangeCurrentLocale {args} { proc ::tcl::clock::ClearCaches {} { variable FormatProc variable LocaleNumeralCache - variable CachedSystemTimeZone variable TimeZoneBad + # tell backend - should invalidate: + configure -clear + foreach p [info procs [namespace current]::scanproc'*] { rename $p {} } @@ -4600,9 +4610,8 @@ proc ::tcl::clock::ClearCaches {} { rename $p {} } - catch {unset FormatProc} + unset -nocomplain FormatProc set LocaleNumeralCache {} - catch {unset CachedSystemTimeZone} set TimeZoneBad {} InitTZData } diff --git a/library/init.tcl b/library/init.tcl index 4bbce51..5e452b0 100644 --- a/library/init.tcl +++ b/library/init.tcl @@ -178,7 +178,7 @@ if {[interp issafe]} { # Auto-loading stubs for 'clock.tcl' - foreach cmd {add format} { + foreach cmd {add format SetupTimeZone} { proc ::tcl::clock::$cmd args { variable TclLibDir source -encoding utf-8 [file join $TclLibDir clock.tcl] diff --git a/tests-perf/clock.perf.tcl b/tests-perf/clock.perf.tcl new file mode 100644 index 0000000..2e77a26 --- /dev/null +++ b/tests-perf/clock.perf.tcl @@ -0,0 +1,59 @@ +#!/usr/bin/tclsh +# ------------------------------------------------------------------------ +# +# test-performance.tcl -- +# +# This file provides common performance tests for comparison of tcl-speed +# degradation by switching between branches. +# (currently for clock ensemble only) +# +# ------------------------------------------------------------------------ +# +# Copyright (c) 2014 Serg G. Brester (aka sebres) +# +# See the file "license.terms" for information on usage and redistribution +# of this file. +# + +proc test-scan {{rep 100000}} { + foreach {comment c} { + "# FreeScan : relative date" + {clock scan "5 years 18 months 385 days" -base 0 -gmt 1} + "# FreeScan : time only with base" + {clock scan "19:18:30" -base 148863600 -gmt 1} + "# FreeScan : time only without base" + {clock scan "19:18:30" -gmt 1} + "# FreeScan : date, system time zone" + {clock scan "05/08/2016 20:18:30"} + "# FreeScan : date, supplied time zone" + {clock scan "05/08/2016 20:18:30" -timezone :CET} + "# FreeScan : date, supplied gmt (equivalent -timezone :GMT)" + {clock scan "05/08/2016 20:18:30" -gmt 1} + "# FreeScan : time only, numeric zone in string, base time gmt (exchange zones between gmt / -0500)" + {clock scan "20:18:30 -0500" -base 148863600 -gmt 1} + "# FreeScan : time only, zone in string (exchange zones between system / gmt)" + {clock scan "19:18:30 GMT" -base 148863600} + } { + puts "\n% $comment\n% $c" + puts [clock format [{*}$c]] + puts [time $c $rep] + } +} + +proc test-other {{rep 100000}} { + foreach {comment c} { + "# Bad zone" + {catch {clock scan "1 day" -timezone BAD_ZONE}} + } { + puts "\n% $comment\n% $c" + puts [if 1 $c] + puts [time $c $rep] + } +} + +if 1 {;# + test-scan 100000 + test-other 50000 + + puts \n**OK** +};# \ No newline at end of file -- cgit v0.12 From 18b31092c654c918fdb833a1bc70f6ee61449ff4 Mon Sep 17 00:00:00 2001 From: sebres Date: Tue, 10 Jan 2017 22:01:13 +0000 Subject: [temp-commit]: ClockFreeScan seems to be ready, test case should be checked --- generic/tclClock.c | 171 ++++++++++++++++++++++++++++------------------ tests-perf/clock.perf.tcl | 21 +++++- 2 files changed, 124 insertions(+), 68 deletions(-) diff --git a/generic/tclClock.c b/generic/tclClock.c index 6d619e0..5710d6d 100644 --- a/generic/tclClock.c +++ b/generic/tclClock.c @@ -2560,12 +2560,13 @@ ClockFreeScan( Tcl_Obj *timezoneObj, /* Default time zone in which the time will be expressed */ Tcl_Obj *locale) /* (Unused) Name of the locale where the time will be scanned. */ { + enum Flags {CL_INVALIDATE = (signed int)0x80000000}; + ClockClientData *dataPtr = clientData; Tcl_Obj **literals = dataPtr->literals; DateInfo yy; /* parse structure of TclClockFreeScan */ TclDateFields date; /* date fields used for converting from seconds */ - TclDateFields date2; /* date fields used for in-between calculation */ Tcl_Obj *tzdata; int secondOfDay; /* Seconds of day (time only calculation) */ Tcl_WideInt seconds; @@ -2573,7 +2574,6 @@ ClockFreeScan( // Tcl_Obj *cleanUpList = Tcl_NewObj(); date.tzName = NULL; - date2.tzName = NULL; /* If time zone not specified use system time zone */ if (timezoneObj == NULL || @@ -2670,11 +2670,14 @@ ClockFreeScan( } } - SetDateFieldsTimeZone(&date, timezoneObj); + /* on demand (lazy) assemble julianDay using new year, month, etc. */ + date.julianDay = CL_INVALIDATE; - /* Assemble date, time, zone into seconds-from-epoch */ + /* + * Assemble date, time, zone into seconds-from-epoch + */ - GetJulianDayFromEraYearMonthDay(&date, GREGORIAN_CHANGE_DATE); + SetDateFieldsTimeZone(&date, timezoneObj); if (yy.dateHaveTime == -1) { secondOfDay = 0; @@ -2694,80 +2697,79 @@ ClockFreeScan( secondOfDay = 0; } - date.localSeconds = - -210866803200L - + ( 86400 * (Tcl_WideInt)date.julianDay ) - + secondOfDay; - - SetDateFieldsTimeZone(&date, timezoneObj); - if (ConvertLocalToUTC(interp, &date, tzdata, GREGORIAN_CHANGE_DATE) - != TCL_OK) { - goto done; - } - - seconds = date.seconds; - /* * Do relative times */ +repeat_rel: + if (yy.dateHaveRel) { - /* - seconds = [add $seconds \ - yy.dateRelMonth months yy.dateRelDay days yy.dateRelMonthSecond seconds \ - -timezone $timezone -locale $locale] - */ - } + /* add months (or years in months) */ - /* - * Do relative weekday - */ + if (yy.dateRelMonth != 0) { + int m, h; - if (yy.dateHaveDay && !yy.dateHaveDate) { + /* if needed extract year, month, etc. again */ + if (date.month == CL_INVALIDATE) { + GetGregorianEraYearDay(&date, GREGORIAN_CHANGE_DATE); + GetMonthDay(&date); + GetYearWeekDay(&date, GREGORIAN_CHANGE_DATE); + } - memcpy(&date2, &date, sizeof(date)); - if (date2.tzName != NULL) { - Tcl_IncrRefCount(date2.tzName); - } - /* - SetDateFieldsTimeZone(&date2, timezoneObj); + /* add the requisite number of months */ + date.month += yy.dateRelMonth - 1; + date.year += date.month / 12; + m = date.month % 12; + date.month = m + 1; - date2.seconds = date.seconds; - if (ClockGetDateFields(interp, &date2, tzdata, GREGORIAN_CHANGE_DATE) - != TCL_OK) { - goto done; - } - */ + /* if the day doesn't exist in the current month, repair it */ + h = hath[IsGregorianLeapYear(&date)][m]; + if (date.dayOfMonth > h) { + date.dayOfMonth = h; + } - date2.era = CE; - date2.julianDay = WeekdayOnOrBefore(yy.dateDayNumber, date2.julianDay + 6) - + 7 * yy.dateDayOrdinal; - if (yy.dateDayOrdinal > 0) { - date2.julianDay -= 7; + /* on demand (lazy) assemble julianDay using new year, month, etc. */ + date.julianDay = CL_INVALIDATE; + + yy.dateRelMonth = 0; } - secondOfDay = date2.localSeconds % 86400; - date2.localSeconds = - -210866803200 - + ( 86400 * (Tcl_WideInt)date2.julianDay ) - + secondOfDay; - - // check set time zone again may be really necessary here: - // SetDateFieldsTimeZone(&date2, timezoneObj); - if (ConvertLocalToUTC(interp, &date2, tzdata, GREGORIAN_CHANGE_DATE) - != TCL_OK) { - goto done; + + /* add days (or other parts aligned to days) */ + if (yy.dateRelDay) { + + /* assemble julianDay using new year, month, etc. */ + if (date.julianDay == CL_INVALIDATE) { + GetJulianDayFromEraYearMonthDay(&date, GREGORIAN_CHANGE_DATE); + } + date.julianDay += yy.dateRelDay; + + /* julianDay was changed, on demand (lazy) extract year, month, etc. again */ + date.month = CL_INVALIDATE; + + yy.dateRelDay = 0; } - seconds = date2.seconds; + /* relative time (seconds) */ + secondOfDay += yy.dateRelSeconds; + yy.dateRelSeconds = 0; + } /* - * Do relative month + * Do relative (ordinal) month */ if (yy.dateHaveOrdinalMonth) { int monthDiff; + + /* if needed extract year, month, etc. again */ + if (date.month == CL_INVALIDATE) { + GetGregorianEraYearDay(&date, GREGORIAN_CHANGE_DATE); + GetMonthDay(&date); + GetYearWeekDay(&date, GREGORIAN_CHANGE_DATE); + } + if (yy.dateMonthOrdinal > 0) { monthDiff = yy.dateMonth - date.month; if (monthDiff <= 0) { @@ -2781,12 +2783,54 @@ ClockFreeScan( } yy.dateMonthOrdinal++; } - /* [SB] TODO: rewrite it in C: * / - seconds = [add $seconds $yy.dateMonthOrdinal years $monthDiff months \ - -timezone $timezone -locale $locale] - */ + + /* process it further via relative times */ + yy.dateHaveRel++; + date.year += yy.dateMonthOrdinal; + yy.dateRelMonth += monthDiff; + yy.dateHaveOrdinalMonth = 0; + + goto repeat_rel; + } + + /* + * Do relative weekday + */ + + if (yy.dateHaveDay && !yy.dateHaveDate) { + + /* if needed assemble julianDay now */ + if (date.julianDay == CL_INVALIDATE) { + GetJulianDayFromEraYearMonthDay(&date, GREGORIAN_CHANGE_DATE); + } + + date.era = CE; + date.julianDay = WeekdayOnOrBefore(yy.dateDayNumber, date.julianDay + 6) + + 7 * yy.dateDayOrdinal; + if (yy.dateDayOrdinal > 0) { + date.julianDay -= 7; + } + } + + /* If needed assemble julianDay using new year, month, etc. */ + if (date.julianDay == CL_INVALIDATE) { + GetJulianDayFromEraYearMonthDay(&date, GREGORIAN_CHANGE_DATE); + } + + /* Local seconds to UTC */ + + date.localSeconds = + -210866803200L + + ( 86400 * (Tcl_WideInt)date.julianDay ) + + ( secondOfDay % 86400 ); + + if (ConvertLocalToUTC(interp, &date, tzdata, GREGORIAN_CHANGE_DATE) + != TCL_OK) { + goto done; } + seconds = date.seconds; + ret = TCL_OK; done: @@ -2794,9 +2838,6 @@ done: if (date.tzName != NULL) { Tcl_DecrRefCount(date.tzName); } - if (date2.tzName != NULL) { - Tcl_DecrRefCount(date2.tzName); - } // Tcl_DecrRefCount(cleanUpList); if (ret != TCL_OK) { diff --git a/tests-perf/clock.perf.tcl b/tests-perf/clock.perf.tcl index 2e77a26..52bc91f 100644 --- a/tests-perf/clock.perf.tcl +++ b/tests-perf/clock.perf.tcl @@ -19,6 +19,18 @@ proc test-scan {{rep 100000}} { foreach {comment c} { "# FreeScan : relative date" {clock scan "5 years 18 months 385 days" -base 0 -gmt 1} + "# FreeScan : relative date with relative weekday" + {clock scan "5 years 18 months 385 days Fri" -base 0 -gmt 1} + "# FreeScan : relative date with ordinal month" + {clock scan "5 years 18 months 385 days next 1 January" -base 0 -gmt 1} + "# FreeScan : relative date with ordinal month and relative weekday" + {clock scan "5 years 18 months 385 days next January Fri" -base 0 -gmt 1} + "# FreeScan : ordinal month" + {clock scan "next January" -base 0 -gmt 1} + "# FreeScan : relative week" + {clock scan "next Fri" -base 0 -gmt 1} + "# FreeScan : relative weekday and week offset " + {clock scan "next January + 2 week" -base 0 -gmt 1} "# FreeScan : time only with base" {clock scan "19:18:30" -base 148863600 -gmt 1} "# FreeScan : time only without base" @@ -34,8 +46,9 @@ proc test-scan {{rep 100000}} { "# FreeScan : time only, zone in string (exchange zones between system / gmt)" {clock scan "19:18:30 GMT" -base 148863600} } { + if {[string first "**STOP**" $comment] != -1} { return -code error "**STOP**" } puts "\n% $comment\n% $c" - puts [clock format [{*}$c]] + puts [clock format [{*}$c] -locale en] puts [time $c $rep] } } @@ -45,15 +58,17 @@ proc test-other {{rep 100000}} { "# Bad zone" {catch {clock scan "1 day" -timezone BAD_ZONE}} } { + if {[string first "**STOP**" $comment] != -1} { return -code error "**STOP**" } puts "\n% $comment\n% $c" puts [if 1 $c] puts [time $c $rep] } } +set factor 10; # 50 if 1 {;# - test-scan 100000 - test-other 50000 + test-scan [expr 10000 * $factor] + test-other [expr 5000 * $factor] puts \n**OK** };# \ No newline at end of file -- cgit v0.12 From 21878028d55c47c9a84ab38e38d69b0a8123dbe3 Mon Sep 17 00:00:00 2001 From: sebres Date: Tue, 10 Jan 2017 22:02:10 +0000 Subject: [temp-commit]: ClockFreeScan ready, test case passed (2 failure because of wrong :localtime zone by TZ-switch, to be fixed) --- generic/tclClock.c | 26 +++++-- library/clock.tcl | 198 ++--------------------------------------------------- library/init.tcl | 2 +- tests/clock.test | 12 +++- 4 files changed, 37 insertions(+), 201 deletions(-) diff --git a/generic/tclClock.c b/generic/tclClock.c index 5710d6d..7256320 100644 --- a/generic/tclClock.c +++ b/generic/tclClock.c @@ -122,6 +122,7 @@ typedef struct ClockClientData { Tcl_Obj *GMTSetupTZData; Tcl_Obj *LastSetupTimeZone; Tcl_Obj *LastSetupTZData; + Tcl_Obj *LastUsedSetupTimeZone; } ClockClientData; /* @@ -324,6 +325,7 @@ TclClockInit( data->GMTSetupTZData = NULL; data->LastSetupTimeZone = NULL; data->LastSetupTZData = NULL; + data->LastUsedSetupTimeZone = NULL; /* * Install the commands. @@ -477,6 +479,7 @@ ClockConfigureObjCmd( if (i+1 < objc) { timezoneObj = NormTimezoneObj(dataPtr, objv[i+1]); if (optionIndex == CLOCK_SETUP_TZ) { + dataPtr->LastUsedSetupTimeZone = timezoneObj; if (timezoneObj == litPtr[LIT_GMT]) { optionIndex = CLOCK_SETUP_GMT; } else if (timezoneObj == dataPtr->LastSystemTimeZone) { @@ -510,14 +513,15 @@ ClockConfigureObjCmd( if (i+1 < objc) { Tcl_IncrRefCount( dataPtr->LastSetupTimeZone = timezoneObj); - } else if (dataPtr->LastSetupTimeZone) { - Tcl_SetObjResult(interp, dataPtr->LastSetupTimeZone); + } else if (dataPtr->LastUsedSetupTimeZone) { + Tcl_SetObjResult(interp, dataPtr->LastUsedSetupTimeZone); } } } } if (optionIndex == CLOCK_CLEAR_CACHE) { dataPtr->LastTZEpoch = 0; + dataPtr->LastUsedSetupTimeZone = NULL; } } @@ -605,6 +609,11 @@ ClockSetupTimeZone( Tcl_Obj **literals = dataPtr->literals; Tcl_Obj *callargs[2]; + /* if cached (if already setup this one) */ + if (timezoneObj == dataPtr->LastUsedSetupTimeZone) { + return timezoneObj; + } + /* differentiate GMT and system zones, because used often and already set */ timezoneObj = NormTimezoneObj(dataPtr, timezoneObj); if ( timezoneObj == dataPtr->GMTSetupTimeZone @@ -2546,6 +2555,15 @@ ClockScanObjCmd( } */ + if (1) { + /* TODO: Tcled Scan proc - */ + Tcl_Obj *callargs[10]; + memcpy(callargs, objv, objc * sizeof(*objv)); + callargs[0] = Tcl_NewStringObj("::tcl::clock::__org_scan", -1); + return Tcl_EvalObjv(interp, objc, callargs, 0); + } + // Tcl_SetObjResult(interp, Tcl_NewWideIntObj(10000000)); + return TCL_OK; } @@ -2635,10 +2653,10 @@ ClockFreeScan( if (yy.dateHaveDate) { if (yy.dateYear < 100) { - yy.dateYear += ClockCurrentYearCentury(clientData, interp); - if (yy.dateYear > ClockGetYearOfCenturySwitch(clientData, interp)) { + if (yy.dateYear >= ClockGetYearOfCenturySwitch(clientData, interp)) { yy.dateYear -= 100; } + yy.dateYear += ClockCurrentYearCentury(clientData, interp); } date.era = CE; date.year = yy.dateYear; diff --git a/library/clock.tcl b/library/clock.tcl index 90b3c69..b4a7639 100755 --- a/library/clock.tcl +++ b/library/clock.tcl @@ -289,7 +289,7 @@ proc ::tcl::clock::Initialize {} { # Current year century and year of century switch variable CurrentYearCentury 2000 - variable YearOfCenturySwitch 37 + variable YearOfCenturySwitch 38 # Translation table to map Windows TZI onto cities, so that the Olson # rules can apply. In some cases the mapping is ambiguous, so it's wise @@ -1249,18 +1249,6 @@ proc ::tcl::clock::__org_scan { args } { set timezone :GMT } - if { ![info exists saw(-format)] } { - # Perhaps someday we'll localize the legacy code. Right now, it's not - # localized. - if { [info exists saw(-locale)] } { - return -code error \ - -errorcode [list CLOCK flagWithLegacyFormat] \ - "legacy \[clock scan\] does not support -locale" - - } - return [FreeScan $string $base $timezone $locale] - } - # Change locale if a fresh locale has been given on the command line. EnterLocale $locale @@ -1279,184 +1267,6 @@ proc ::tcl::clock::__org_scan { args } { #---------------------------------------------------------------------- # -# FreeScan -- -# -# Scans a time in free format -# -# Parameters: -# string - String containing the time to scan -# base - Base time, expressed in seconds from the Epoch -# timezone - Default time zone in which the time will be expressed -# locale - (Unused) Name of the locale where the time will be scanned. -# -# Results: -# Returns the date and time extracted from the string in seconds from -# the epoch -# -#---------------------------------------------------------------------- - -proc ::tcl::clock::__org_FreeScan { string base timezone locale } { - - variable TZData - - # Get the data for time changes in the given zone - if {$timezone eq {}} { - set timezone [GetSystemTimeZone] - } - try { - SetupTimeZone $timezone - } on error {retval opts} { - dict unset opts -errorinfo - return -options $opts $retval - } - - # Extract year, month and day from the base time for the parser to use as - # defaults - - set date [GetDateFields $base $TZData($timezone) 2361222] - dict set date secondOfDay [expr { - [dict get $date localSeconds] % 86400 - }] - - # Parse the date. The parser will return a list comprising date, time, - # time zone, relative month/day/seconds, relative weekday, ordinal month. - - try { - set scanned [Oldscan $string \ - [dict get $date year] \ - [dict get $date month] \ - [dict get $date dayOfMonth]] - lassign $scanned \ - parseDate parseTime parseZone parseRel \ - parseWeekday parseOrdinalMonth - } on error message { - return -code error \ - "unable to convert date-time string \"$string\": $message" - } - - # If the caller supplied a date in the string, update the 'date' dict with - # the value. If the caller didn't specify a time with the date, default to - # midnight. - - if { [llength $parseDate] > 0 } { - lassign $parseDate y m d - if { $y < 100 } { - variable YearOfCenturySwitch - if { $y > $YearOfCenturySwitch } { - incr y 1900 - } else { - incr y 2000 - } - } - dict set date era CE - dict set date year $y - dict set date month $m - dict set date dayOfMonth $d - if { $parseTime eq {} } { - set parseTime 0 - } - } - - # If the caller supplied a time zone in the string, it comes back as a - # two-element list; the first element is the number of minutes east of - # Greenwich, and the second is a Daylight Saving Time indicator (1 == yes, - # 0 == no, -1 == unknown). We make it into a time zone indicator of - # +-hhmm. - - if { [llength $parseZone] > 0 } { - lassign $parseZone minEast dstFlag - set timezone [FormatNumericTimeZone \ - [expr { 60 * $minEast + 3600 * $dstFlag }]] - SetupTimeZone $timezone - } - dict set date tzName $timezone - - # Assemble date, time, zone into seconds-from-epoch - - set date [GetJulianDayFromEraYearMonthDay $date[set date {}] 2361222] - if { $parseTime ne {} } { - dict set date secondOfDay $parseTime - } elseif { [llength $parseWeekday] != 0 - || [llength $parseOrdinalMonth] != 0 - || ( [llength $parseRel] != 0 - && ( [lindex $parseRel 0] != 0 - || [lindex $parseRel 1] != 0 ) ) } { - dict set date secondOfDay 0 - } - - dict set date localSeconds [expr { - -210866803200 - + ( 86400 * wide([dict get $date julianDay]) ) - + [dict get $date secondOfDay] - }] - dict set date tzName $timezone - set date [ConvertLocalToUTC $date[set date {}] $TZData($timezone) 2361222] - set seconds [dict get $date seconds] - - # Do relative times - - if { [llength $parseRel] > 0 } { - lassign $parseRel relMonth relDay relSecond - set seconds [add $seconds \ - $relMonth months $relDay days $relSecond seconds \ - -timezone $timezone -locale $locale] - } - - # Do relative weekday - - if { [llength $parseWeekday] > 0 } { - lassign $parseWeekday dayOrdinal dayOfWeek - set date2 [GetDateFields $seconds $TZData($timezone) 2361222] - dict set date2 era CE - set jdwkday [WeekdayOnOrBefore $dayOfWeek [expr { - [dict get $date2 julianDay] + 6 - }]] - incr jdwkday [expr { 7 * $dayOrdinal }] - if { $dayOrdinal > 0 } { - incr jdwkday -7 - } - dict set date2 secondOfDay \ - [expr { [dict get $date2 localSeconds] % 86400 }] - dict set date2 julianDay $jdwkday - dict set date2 localSeconds [expr { - -210866803200 - + ( 86400 * wide([dict get $date2 julianDay]) ) - + [dict get $date secondOfDay] - }] - dict set date2 tzName $timezone - set date2 [ConvertLocalToUTC $date2[set date2 {}] $TZData($timezone) \ - 2361222] - set seconds [dict get $date2 seconds] - - } - - # Do relative month - - if { [llength $parseOrdinalMonth] > 0 } { - lassign $parseOrdinalMonth monthOrdinal monthNumber - if { $monthOrdinal > 0 } { - set monthDiff [expr { $monthNumber - [dict get $date month] }] - if { $monthDiff <= 0 } { - incr monthDiff 12 - } - incr monthOrdinal -1 - } else { - set monthDiff [expr { [dict get $date month] - $monthNumber }] - if { $monthDiff >= 0 } { - incr monthDiff -12 - } - incr monthOrdinal - } - set seconds [add $seconds $monthOrdinal years $monthDiff months \ - -timezone $timezone -locale $locale] - } - - return $seconds -} - - -#---------------------------------------------------------------------- -# # ParseClockScanFormat -- # # Parses a format string given to [clock scan -format] @@ -2723,10 +2533,10 @@ proc ::tcl::clock::InterpretTwoDigitYear { date baseTime variable CurrentYearCentury variable YearOfCenturySwitch set yr [dict get $date $twoDigitField] - incr yr $CurrentYearCentury - if { $yr <= $YearOfCenturySwitch } { + if { $yr >= $YearOfCenturySwitch } { incr yr -100 } + incr yr $CurrentYearCentury dict set date $fourDigitField $yr return $date } @@ -3120,7 +2930,7 @@ proc ::tcl::clock::SetupTimeZone { timezone } { LoadZoneinfoFile [string range $timezone 1 end] }] } then { - dict set TimeZoneBad $timezone 1 + dict set TimeZoneBad $timezone 1 return -code error \ -errorcode [list CLOCK badTimeZone $timezone] \ "time zone \"$timezone\" not found" diff --git a/library/init.tcl b/library/init.tcl index 5e452b0..06a9459 100644 --- a/library/init.tcl +++ b/library/init.tcl @@ -178,7 +178,7 @@ if {[interp issafe]} { # Auto-loading stubs for 'clock.tcl' - foreach cmd {add format SetupTimeZone} { + foreach cmd {add format SetupTimeZone GetSystemTimeZone __org_scan} { proc ::tcl::clock::$cmd args { variable TclLibDir source -encoding utf-8 [file join $TclLibDir clock.tcl] diff --git a/tests/clock.test b/tests/clock.test index 6a0fecd..ecc6f5f 100644 --- a/tests/clock.test +++ b/tests/clock.test @@ -35662,7 +35662,7 @@ test clock-34.8 {clock scan tests} { } {Oct 23,1992 15:00 GMT} test clock-34.9 {clock scan tests} { list [catch {clock scan "Jan 12" -bad arg} msg] $msg -} {1 {bad option "-bad", must be -base, -format, -gmt, -locale or -timezone}} +} {1 {bad option "-bad": must be -format, -gmt, -locale, -timezone, or -base}} # The following two two tests test the two year date policy test clock-34.10 {clock scan tests} { set time [clock scan "1/1/71" -gmt true] @@ -35672,7 +35672,15 @@ test clock-34.11 {clock scan tests} { set time [clock scan "1/1/37" -gmt true] clock format $time -format {%b %d,%Y %H:%M GMT} -gmt true } {Jan 01,2037 00:00 GMT} - +test clock-34.11.1 {clock scan tests: same century switch} { + set times [clock scan "1/1/37" -gmt true] +} [clock scan "1/1/37" -format "%m/%d/%y" -gmt true] +test clock-34.11.2 {clock scan tests: same century switch} { + set times [clock scan "1/1/38" -gmt true] +} [clock scan "1/1/38" -format "%m/%d/%y" -gmt true] +test clock-34.11.3 {clock scan tests: same century switch} { + set times [clock scan "1/1/39" -gmt true] +} [clock scan "1/1/39" -format "%m/%d/%y" -gmt true] test clock-34.12 {clock scan, relative times} { set time [clock scan "Oct 23, 1992 -1 day"] clock format $time -format {%b %d, %Y} -- cgit v0.12 From 32b5c49ef3414668839b0fab063c85c2583a15e6 Mon Sep 17 00:00:00 2001 From: sebres Date: Tue, 10 Jan 2017 22:04:49 +0000 Subject: [temp-commit]: ClockFreeScan back-ported (cherry picked), all tests case passed + several new test-cases for bug fixing implemented here; environment epoch ported, several fixes for the time zone / tzdata caching ported; mem-leak fix + memory leak test cases passed --- generic/tclClock.c | 342 +++++++++++++++++++++++++++------------------- generic/tclDate.h | 13 +- generic/tclEnv.c | 8 ++ library/clock.tcl | 12 +- tests-perf/clock.perf.tcl | 78 +++++++---- tests/clock.test | 21 +++ 6 files changed, 296 insertions(+), 178 deletions(-) diff --git a/generic/tclClock.c b/generic/tclClock.c index 7256320..e39e032 100644 --- a/generic/tclClock.c +++ b/generic/tclClock.c @@ -115,14 +115,24 @@ typedef struct ClockClientData { size_t refCount; /* Number of live references. */ Tcl_Obj **literals; /* Pool of object literals. */ /* Cache for current clock parameters, imparted via "configure" */ - unsigned int LastTZEpoch; - Tcl_Obj *LastSystemTimeZone; + unsigned long LastTZEpoch; + Tcl_Obj *SystemTimeZone; Tcl_Obj *SystemSetupTZData; Tcl_Obj *GMTSetupTimeZone; Tcl_Obj *GMTSetupTZData; + Tcl_Obj *AnySetupTimeZone; + Tcl_Obj *AnySetupTZData; + Tcl_Obj *LastUnnormSetupTimeZone; Tcl_Obj *LastSetupTimeZone; Tcl_Obj *LastSetupTZData; - Tcl_Obj *LastUsedSetupTimeZone; + /* + /* [SB] TODO: back-port (from tclSE) the same date caching ... + * Cache for last date (fast convert if date parsed was the same) * / + struct { + DateInfo yy; + TclDateFields date; + } lastDate; + */ } ClockClientData; /* @@ -233,11 +243,29 @@ static int ClockFreeScan( Tcl_Obj *strObj, Tcl_WideInt baseVal, Tcl_Obj *timezoneObj, Tcl_Obj *locale); static struct tm * ThreadSafeLocalTime(const time_t *); -static unsigned int TzsetGetEpoch(void); +static unsigned long TzsetGetEpoch(void); static void TzsetIfNecessary(void); static void ClockDeleteCmdProc(ClientData); /* + * Primitives to safe set, reset and free references. + */ + +#define Tcl_UnsetObjRef(obj) \ + if (obj != NULL) { Tcl_DecrRefCount(obj); obj = NULL; } +#define Tcl_InitObjRef(obj, val) \ + obj = val; if (obj) { Tcl_IncrRefCount(obj); } +#define Tcl_SetObjRef(obj, val) \ +if (1) { \ + Tcl_Obj *nval = val; \ + if (obj != nval) { \ + Tcl_Obj *prev = obj; \ + Tcl_InitObjRef(obj, nval); \ + if (prev != NULL) { Tcl_DecrRefCount(prev); }; \ + } \ +} + +/* * Structure containing description of "native" clock commands to create. */ @@ -319,13 +347,15 @@ TclClockInit( Tcl_IncrRefCount(data->literals[i]); } data->LastTZEpoch = 0; - data->LastSystemTimeZone = NULL; + data->SystemTimeZone = NULL; data->SystemSetupTZData = NULL; data->GMTSetupTimeZone = NULL; data->GMTSetupTZData = NULL; + data->AnySetupTimeZone = NULL; + data->AnySetupTZData = NULL; + data->LastUnnormSetupTimeZone = NULL; data->LastSetupTimeZone = NULL; data->LastSetupTZData = NULL; - data->LastUsedSetupTimeZone = NULL; /* * Install the commands. @@ -356,6 +386,22 @@ TclClockInit( */ static void +ClockConfigureClear( + ClockClientData *data) +{ + data->LastTZEpoch = 0; + Tcl_UnsetObjRef(data->SystemTimeZone); + Tcl_UnsetObjRef(data->SystemSetupTZData); + Tcl_UnsetObjRef(data->GMTSetupTimeZone); + Tcl_UnsetObjRef(data->GMTSetupTZData); + Tcl_UnsetObjRef(data->AnySetupTimeZone); + Tcl_UnsetObjRef(data->AnySetupTZData); + Tcl_UnsetObjRef(data->LastUnnormSetupTimeZone); + Tcl_UnsetObjRef(data->LastSetupTimeZone); + Tcl_UnsetObjRef(data->LastSetupTZData); +} + +static void ClockDeleteCmdProc( ClientData clientData) /* Opaque pointer to the client data */ { @@ -367,15 +413,7 @@ ClockDeleteCmdProc( Tcl_DecrRefCount(data->literals[i]); } - if (data->LastSystemTimeZone) { - Tcl_DecrRefCount(data->LastSystemTimeZone); - } - if (data->GMTSetupTimeZone) { - Tcl_DecrRefCount(data->GMTSetupTimeZone); - } - if (data->LastSetupTimeZone) { - Tcl_DecrRefCount(data->LastSetupTimeZone); - } + ClockConfigureClear(data); ckfree(data->literals); ckfree(data); @@ -391,34 +429,40 @@ NormTimezoneObj( Tcl_Obj * timezoneObj) { const char * tz; - if ( timezoneObj == dataPtr->literals[LIT_GMT] - || timezoneObj == dataPtr->LastSystemTimeZone - || timezoneObj == dataPtr->LastSetupTimeZone + if ( timezoneObj == dataPtr->LastUnnormSetupTimeZone + && dataPtr->LastSetupTimeZone != NULL + ) { + return dataPtr->LastSetupTimeZone; + } + if ( timezoneObj == dataPtr->LastSetupTimeZone + || timezoneObj == dataPtr->literals[LIT_GMT] + || timezoneObj == dataPtr->SystemTimeZone + || timezoneObj == dataPtr->AnySetupTimeZone ) { return timezoneObj; } tz = TclGetString(timezoneObj); - if ( - strcmp(tz, Literals[LIT_GMT]) == 0 + if (dataPtr->AnySetupTimeZone != NULL && + (timezoneObj == dataPtr->AnySetupTimeZone + || strcmp(tz, TclGetString(dataPtr->AnySetupTimeZone)) == 0 + ) ) { - timezoneObj = dataPtr->literals[LIT_GMT]; + timezoneObj = dataPtr->AnySetupTimeZone; } else - if (dataPtr->LastSystemTimeZone != NULL && - (timezoneObj == dataPtr->LastSystemTimeZone - || strcmp(tz, TclGetString(dataPtr->LastSystemTimeZone)) == 0 + if (dataPtr->SystemTimeZone != NULL && + (timezoneObj == dataPtr->SystemTimeZone + || strcmp(tz, TclGetString(dataPtr->SystemTimeZone)) == 0 ) ) { - timezoneObj = dataPtr->LastSystemTimeZone; + timezoneObj = dataPtr->SystemTimeZone; } else - if (dataPtr->LastSetupTimeZone != NULL && - (timezoneObj == dataPtr->LastSetupTimeZone - || strcmp(tz, TclGetString(dataPtr->LastSetupTimeZone)) == 0 - ) + if ( + strcmp(tz, Literals[LIT_GMT]) == 0 ) { - timezoneObj = dataPtr->LastSetupTimeZone; + timezoneObj = dataPtr->literals[LIT_GMT]; } return timezoneObj; } @@ -454,74 +498,64 @@ ClockConfigureObjCmd( Tcl_GetString(objv[i]), NULL); return TCL_ERROR; } - if (optionIndex == CLOCK_SYSTEM_TZ || optionIndex == CLOCK_CLEAR_CACHE) { - if (dataPtr->LastSystemTimeZone) { - Tcl_DecrRefCount(dataPtr->LastSystemTimeZone); - dataPtr->LastSystemTimeZone = NULL; - dataPtr->SystemSetupTZData = NULL; - } - if (optionIndex != CLOCK_CLEAR_CACHE) { - /* validate current tz-epoch */ - unsigned int lastTZEpoch = TzsetGetEpoch(); - if (i+1 < objc) { - Tcl_IncrRefCount( - dataPtr->LastSystemTimeZone = objv[i+1]); - dataPtr->LastTZEpoch = lastTZEpoch; - } else if (dataPtr->LastSystemTimeZone - && dataPtr->LastTZEpoch == lastTZEpoch) { - Tcl_SetObjResult(interp, dataPtr->LastSystemTimeZone); + switch (optionIndex) { + case CLOCK_SYSTEM_TZ: + if (1) { + /* validate current tz-epoch */ + unsigned long lastTZEpoch = TzsetGetEpoch(); + if (i+1 < objc) { + if (dataPtr->SystemTimeZone != objv[i+1]) { + Tcl_SetObjRef(dataPtr->SystemTimeZone, objv[i+1]); + Tcl_UnsetObjRef(dataPtr->SystemSetupTZData); } + dataPtr->LastTZEpoch = lastTZEpoch; + } + if (dataPtr->SystemTimeZone != NULL + && dataPtr->LastTZEpoch == lastTZEpoch) { + Tcl_SetObjResult(interp, dataPtr->SystemTimeZone); } } - if (optionIndex == CLOCK_SETUP_TZ || optionIndex == CLOCK_CLEAR_CACHE) { - Tcl_Obj *timezoneObj = NULL; - /* differentiate GMT and system zones, because used often */ + break; + case CLOCK_SETUP_TZ: if (i+1 < objc) { - timezoneObj = NormTimezoneObj(dataPtr, objv[i+1]); - if (optionIndex == CLOCK_SETUP_TZ) { - dataPtr->LastUsedSetupTimeZone = timezoneObj; - if (timezoneObj == litPtr[LIT_GMT]) { - optionIndex = CLOCK_SETUP_GMT; - } else if (timezoneObj == dataPtr->LastSystemTimeZone) { - optionIndex = CLOCK_SETUP_NOP; - } + /* differentiate GMT and system zones, because used often */ + Tcl_Obj *timezoneObj = NormTimezoneObj(dataPtr, objv[i+1]); + Tcl_SetObjRef(dataPtr->LastUnnormSetupTimeZone, objv[i+1]); + if (dataPtr->LastSetupTimeZone != timezoneObj) { + Tcl_SetObjRef(dataPtr->LastSetupTimeZone, timezoneObj); + Tcl_UnsetObjRef(dataPtr->LastSetupTZData); } - } - - if (optionIndex == CLOCK_SETUP_GMT || optionIndex == CLOCK_CLEAR_CACHE) { - if (dataPtr->GMTSetupTimeZone) { - Tcl_DecrRefCount(dataPtr->GMTSetupTimeZone); - dataPtr->GMTSetupTimeZone = NULL; - dataPtr->GMTSetupTZData = NULL; + if (timezoneObj == litPtr[LIT_GMT]) { + optionIndex = CLOCK_SETUP_GMT; + } else if (timezoneObj == dataPtr->SystemTimeZone) { + optionIndex = CLOCK_SETUP_NOP; } - if (optionIndex != CLOCK_CLEAR_CACHE) { + switch (optionIndex) { + case CLOCK_SETUP_GMT: if (i+1 < objc) { - Tcl_IncrRefCount( - dataPtr->GMTSetupTimeZone = timezoneObj); - } else if (dataPtr->GMTSetupTimeZone) { - Tcl_SetObjResult(interp, dataPtr->GMTSetupTimeZone); + if (dataPtr->GMTSetupTimeZone != timezoneObj) { + Tcl_SetObjRef(dataPtr->GMTSetupTimeZone, timezoneObj); + Tcl_UnsetObjRef(dataPtr->GMTSetupTZData); + } } - } - } - if (optionIndex == CLOCK_SETUP_TZ || optionIndex == CLOCK_CLEAR_CACHE) { - if (dataPtr->LastSetupTimeZone) { - Tcl_DecrRefCount(dataPtr->LastSetupTimeZone); - dataPtr->LastSetupTimeZone = NULL; - dataPtr->LastSetupTZData = NULL; - } - if (optionIndex != CLOCK_CLEAR_CACHE) { + break; + case CLOCK_SETUP_TZ: if (i+1 < objc) { - Tcl_IncrRefCount( - dataPtr->LastSetupTimeZone = timezoneObj); - } else if (dataPtr->LastUsedSetupTimeZone) { - Tcl_SetObjResult(interp, dataPtr->LastUsedSetupTimeZone); - } + if (dataPtr->AnySetupTimeZone != timezoneObj) { + Tcl_SetObjRef(dataPtr->AnySetupTimeZone, timezoneObj); + Tcl_UnsetObjRef(dataPtr->AnySetupTZData); + } + } + break; } } - } - if (optionIndex == CLOCK_CLEAR_CACHE) { - dataPtr->LastTZEpoch = 0; - dataPtr->LastUsedSetupTimeZone = NULL; + if (dataPtr->LastSetupTimeZone != NULL) { + Tcl_SetObjResult(interp, dataPtr->LastSetupTimeZone); + } + break; + case CLOCK_CLEAR_CACHE: + ClockConfigureClear(dataPtr); + break; } } @@ -541,11 +575,19 @@ ClockGetTZData( Tcl_Obj **literals = dataPtr->literals; Tcl_Obj *ret, **out = NULL; + /* if cached (if already setup this one) */ + if ( dataPtr->LastSetupTZData != NULL + && ( timezoneObj == dataPtr->LastSetupTimeZone + || timezoneObj == dataPtr->LastUnnormSetupTimeZone + ) + ) { + return dataPtr->LastSetupTZData; + } + /* differentiate GMT and system zones, because used often */ - /* simple caching, because almost used the tz-data of last timezone, (unnecessary to - * touch the refCount of it, because it is always referenced in TZData array) + /* simple caching, because almost used the tz-data of last timezone */ - if (timezoneObj == dataPtr->LastSystemTimeZone) { + if (timezoneObj == dataPtr->SystemTimeZone) { if (dataPtr->SystemSetupTZData != NULL) return dataPtr->SystemSetupTZData; out = &dataPtr->SystemSetupTZData; @@ -557,19 +599,25 @@ ClockGetTZData( out = &dataPtr->GMTSetupTZData; } else - if (timezoneObj == dataPtr->LastSetupTimeZone) { - if (dataPtr->LastSetupTZData != NULL) { - return dataPtr->LastSetupTZData; + if (timezoneObj == dataPtr->AnySetupTimeZone) { + if (dataPtr->AnySetupTZData != NULL) { + return dataPtr->AnySetupTZData; } - out = &dataPtr->LastSetupTZData; + out = &dataPtr->AnySetupTZData; } ret = Tcl_ObjGetVar2(interp, literals[LIT_TZDATA], timezoneObj, TCL_LEAVE_ERR_MSG); - /* cache using corresponding slot */ - if (ret != NULL && out != NULL) - *out = ret; + /* cache using corresponding slot and as last used */ + if (out != NULL) { + Tcl_SetObjRef(*out, ret); + } + Tcl_SetObjRef(dataPtr->LastSetupTZData, ret); + if (dataPtr->LastSetupTimeZone != timezoneObj) { + Tcl_SetObjRef(dataPtr->LastSetupTimeZone, timezoneObj); + Tcl_UnsetObjRef(dataPtr->LastUnnormSetupTimeZone); + } return ret; } /* @@ -584,9 +632,9 @@ ClockGetSystemTimeZone( Tcl_Obj **literals; /* if known (cached and same epoch) - return now */ - if (dataPtr->LastSystemTimeZone != NULL + if (dataPtr->SystemTimeZone != NULL && dataPtr->LastTZEpoch == TzsetGetEpoch()) { - return dataPtr->LastSystemTimeZone; + return dataPtr->SystemTimeZone; } literals = dataPtr->literals; @@ -610,15 +658,19 @@ ClockSetupTimeZone( Tcl_Obj *callargs[2]; /* if cached (if already setup this one) */ - if (timezoneObj == dataPtr->LastUsedSetupTimeZone) { - return timezoneObj; + if ( dataPtr->LastSetupTimeZone != NULL + && ( timezoneObj == dataPtr->LastSetupTimeZone + || timezoneObj == dataPtr->LastUnnormSetupTimeZone + ) + ) { + return dataPtr->LastSetupTimeZone; } /* differentiate GMT and system zones, because used often and already set */ timezoneObj = NormTimezoneObj(dataPtr, timezoneObj); if ( timezoneObj == dataPtr->GMTSetupTimeZone - || timezoneObj == dataPtr->LastSystemTimeZone - || timezoneObj == dataPtr->LastSetupTimeZone + || timezoneObj == dataPtr->SystemTimeZone + || timezoneObj == dataPtr->AnySetupTimeZone ) { return timezoneObj; } @@ -627,7 +679,7 @@ ClockSetupTimeZone( callargs[1] = timezoneObj; if (Tcl_EvalObjv(interp, 2, callargs, 0) == TCL_OK) { - return NormTimezoneObj(dataPtr, timezoneObj); + return dataPtr->LastSetupTimeZone; } return NULL; } @@ -743,6 +795,7 @@ ClockConvertlocaltoutcObjCmd( int created = 0; int status; + fields.tzName = NULL; /* * Check params and convert time. */ @@ -936,22 +989,6 @@ ClockGetDateFields( return TCL_OK; } - -inline -SetDateFieldsTimeZone( - TclDateFields *fields, - Tcl_Obj *timezoneObj) -{ - if (fields->tzName != timezoneObj) { - if (timezoneObj) { - Tcl_IncrRefCount(timezoneObj); - } - if (fields->tzName != NULL) { - Tcl_DecrRefCount(fields->tzName); - } - fields->tzName = timezoneObj; - } -} /* *---------------------------------------------------------------------- @@ -1030,6 +1067,8 @@ ClockGetjuliandayfromerayearmonthdayObjCmd( int status; int era = 0; + fields.tzName = NULL; + /* * Check params. */ @@ -1114,6 +1153,8 @@ ClockGetjuliandayfromerayearweekdayObjCmd( int status; int era = 0; + fields.tzName = NULL; + /* * Check params. */ @@ -1457,7 +1498,7 @@ ConvertUTCToLocalUsingTable( * Convert the time. */ - SetDateFieldsTimeZone(fields, cellv[3]); + Tcl_SetObjRef(fields->tzName, cellv[3]); fields->localSeconds = fields->seconds + fields->tzOffset; return TCL_OK; } @@ -1550,7 +1591,7 @@ ConvertUTCToLocalUsingC( if (diff > 0) { sprintf(buffer+5, "%02d", diff); } - SetDateFieldsTimeZone(fields, Tcl_NewStringObj(buffer, -1)); + Tcl_SetObjRef(fields->tzName, Tcl_NewStringObj(buffer, -1)); return TCL_OK; } @@ -1647,6 +1688,8 @@ GetYearWeekDay( TclDateFields temp; int dayOfFiscalYear; + temp.tzName = NULL; + /* * Find the given date, minus three days, plus one year. That date's * iso8601 year is an upper bound on the ISO8601 year of the given date. @@ -1863,6 +1906,8 @@ GetJulianDayFromEraYearWeekDay( * given year */ TclDateFields firstWeek; + firstWeek.tzName = NULL; + /* * Find January 4 in the ISO8601 year, which will always be in week 1. */ @@ -2557,13 +2602,16 @@ ClockScanObjCmd( if (1) { /* TODO: Tcled Scan proc - */ + int ret; Tcl_Obj *callargs[10]; memcpy(callargs, objv, objc * sizeof(*objv)); callargs[0] = Tcl_NewStringObj("::tcl::clock::__org_scan", -1); - return Tcl_EvalObjv(interp, objc, callargs, 0); + Tcl_IncrRefCount(callargs[0]); + ret = Tcl_EvalObjv(interp, objc, callargs, 0); + Tcl_DecrRefCount(callargs[0]); + return ret; } - // Tcl_SetObjResult(interp, Tcl_NewWideIntObj(10000000)); - + return TCL_OK; } @@ -2589,7 +2637,6 @@ ClockFreeScan( int secondOfDay; /* Seconds of day (time only calculation) */ Tcl_WideInt seconds; int ret = TCL_ERROR; - // Tcl_Obj *cleanUpList = Tcl_NewObj(); date.tzName = NULL; @@ -2600,7 +2647,6 @@ ClockFreeScan( if (timezoneObj == NULL) { goto done; } - // Tcl_ListObjAppendElement(NULL, cleanUpList, timezoneObj); } /* Get the data for time changes in the given zone */ @@ -2673,12 +2719,16 @@ ClockFreeScan( */ if (yy.dateHaveZone) { + Tcl_Obj *tzObjStor = NULL; int minEast = -yy.dateTimezone; int dstFlag = 1 - yy.dateDSTmode; - timezoneObj = ClockFormatNumericTimeZone( + tzObjStor = ClockFormatNumericTimeZone( 60 * minEast + 3600 * dstFlag); - // Tcl_ListObjAppendElement(NULL, cleanUpList, timezoneObj); - timezoneObj = ClockSetupTimeZone(clientData, interp, timezoneObj); + + timezoneObj = ClockSetupTimeZone(clientData, interp, tzObjStor); + if (tzObjStor != timezoneObj) { + Tcl_DecrRefCount(tzObjStor); + } if (timezoneObj == NULL) { goto done; } @@ -2695,7 +2745,7 @@ ClockFreeScan( * Assemble date, time, zone into seconds-from-epoch */ - SetDateFieldsTimeZone(&date, timezoneObj); + Tcl_SetObjRef(date.tzName, timezoneObj); if (yy.dateHaveTime == -1) { secondOfDay = 0; @@ -2853,10 +2903,7 @@ repeat_rel: done: - if (date.tzName != NULL) { - Tcl_DecrRefCount(date.tzName); - } - // Tcl_DecrRefCount(cleanUpList); + Tcl_UnsetObjRef(date.tzName); if (ret != TCL_OK) { return ret; @@ -2919,23 +2966,30 @@ ClockSecondsObjCmd( *---------------------------------------------------------------------- */ -static unsigned int +static unsigned long TzsetGetEpoch(void) { - static char* tzWas = INT2PTR(-1); /* Previous value of TZ, protected by - * clockMutex. */ - static long tzNextRefresh = 0; /* Latence before next refresh */ - static unsigned int tzWasEpoch = 1; /* Epoch, signals that TZ changed */ + static char* tzWas = INT2PTR(-1); /* Previous value of TZ, protected by + * clockMutex. */ + static long tzLastRefresh = 0; /* Used for latency before next refresh */ + static unsigned long tzWasEpoch = 0; /* Epoch, signals that TZ changed */ + static unsigned long tzEnvEpoch = 0; /* Last env epoch, for faster signaling, + that TZ changed via TCL */ - const char *tzIsNow; /* Current value of TZ */ + const char *tzIsNow; /* Current value of TZ */ - /* fast check whether environment was changed (once per second) */ + /* + * Prevent performance regression on some platforms by resolving of system time zone: + * small latency for check whether environment was changed (once per second) + * no latency if environment was chaned with tcl-env (compare both epoch values) + */ Tcl_Time now; Tcl_GetTime(&now); - if (now.sec < tzNextRefresh) { + if (now.sec == tzLastRefresh && tzEnvEpoch == TclEnvEpoch) { return tzWasEpoch; } - tzNextRefresh = now.sec + 1; + tzEnvEpoch = TclEnvEpoch; + tzLastRefresh = now.sec; /* check in lock */ Tcl_MutexLock(&clockMutex); diff --git a/generic/tclDate.h b/generic/tclDate.h index 91e677f..6ba9620 100644 --- a/generic/tclDate.h +++ b/generic/tclDate.h @@ -19,9 +19,6 @@ typedef struct DateInfo { - Tcl_Obj* messages; /* Error messages */ - const char* separatrix; /* String separating messages */ - time_t dateYear; time_t dateMonth; time_t dateDay; @@ -54,6 +51,9 @@ typedef struct DateInfo { time_t *dateRelPointer; int dateDigitCount; + + Tcl_Obj* messages; /* Error messages */ + const char* separatrix; /* String separating messages */ } DateInfo; @@ -74,4 +74,11 @@ MODULE_SCOPE time_t ToSeconds(time_t Hours, time_t Minutes, MODULE_SCOPE int TclClockFreeScan(Tcl_Interp *interp, DateInfo *info); +/* + * Other externals. + */ + +MODULE_SCOPE unsigned long TclEnvEpoch; /* Epoch of the tcl environment + * (if changed with tcl-env). */ + #endif /* _TCLCLOCK_H */ diff --git a/generic/tclEnv.c b/generic/tclEnv.c index 66ddb57..fd0a8ce 100644 --- a/generic/tclEnv.c +++ b/generic/tclEnv.c @@ -17,6 +17,10 @@ TCL_DECLARE_MUTEX(envMutex) /* To serialize access to environ. */ + +MODULE_SCOPE unsigned long TclEnvEpoch = 0; /* Epoch of the tcl environment + * (if changed with tcl-env). */ + static struct { int cacheSize; /* Number of env strings in cache. */ char **cache; /* Array containing all of the environment @@ -371,6 +375,7 @@ Tcl_PutEnv( value[0] = '\0'; TclSetEnv(name, value+1); } + TclEnvEpoch++; Tcl_DStringFree(&nameString); return 0; @@ -579,6 +584,7 @@ EnvTraceProc( if (flags & TCL_TRACE_ARRAY) { TclSetupEnv(interp); + TclEnvEpoch++; return NULL; } @@ -599,6 +605,7 @@ EnvTraceProc( value = Tcl_GetVar2(interp, "env", name2, TCL_GLOBAL_ONLY); TclSetEnv(name2, value); + TclEnvEpoch++; } /* @@ -622,6 +629,7 @@ EnvTraceProc( if (flags & TCL_TRACE_UNSETS) { TclUnsetEnv(name2); + TclEnvEpoch++; } return NULL; } diff --git a/library/clock.tcl b/library/clock.tcl index b4a7639..ace4176 100755 --- a/library/clock.tcl +++ b/library/clock.tcl @@ -671,7 +671,9 @@ proc ::tcl::clock::format { args } { # Get the data for time changes in the given zone if {$timezone eq ""} { - set timezone [GetSystemTimeZone] + if {[set timezone [configure -system-tz]] eq ""} { + set timezone [GetSystemTimeZone] + } } if {![info exists TZData($timezone)]} { if {[catch {SetupTimeZone $timezone} retval opts]} { @@ -1202,7 +1204,9 @@ proc ::tcl::clock::__org_scan { args } { set format {} set gmt 0 set locale c - set timezone [GetSystemTimeZone] + if {[set timezone [configure -system-tz]] eq ""} { + set timezone [GetSystemTimeZone] + } # Pick up command line options. @@ -4083,7 +4087,9 @@ proc ::tcl::clock::add { clockval args } { set offsets {} set gmt 0 set locale c - set timezone [GetSystemTimeZone] + if {[set timezone [configure -system-tz]] eq ""} { + set timezone [GetSystemTimeZone] + } foreach { a b } $args { if { [string is integer -strict $a] } { diff --git a/tests-perf/clock.perf.tcl b/tests-perf/clock.perf.tcl index 52bc91f..7ef70ce 100644 --- a/tests-perf/clock.perf.tcl +++ b/tests-perf/clock.perf.tcl @@ -15,60 +15,82 @@ # of this file. # +set ::env(TCL_TZ) :CET + +proc {**STOP**} {args} { + return -code error -level 2 "**STOP** in [info level [expr {[info level]-1}]] [join $args { }]" +} + +proc _test_get_commands {lst} { + regsub -all {(?:^|\n)[ \t]*(\#[^\n]*)(?=\n\s*[\{\#])} $lst "\n{\\1}" +} + proc test-scan {{rep 100000}} { - foreach {comment c} { - "# FreeScan : relative date" + foreach c [_test_get_commands { + # FreeScan : relative date {clock scan "5 years 18 months 385 days" -base 0 -gmt 1} - "# FreeScan : relative date with relative weekday" + # FreeScan : relative date with relative weekday {clock scan "5 years 18 months 385 days Fri" -base 0 -gmt 1} - "# FreeScan : relative date with ordinal month" + # FreeScan : relative date with ordinal month {clock scan "5 years 18 months 385 days next 1 January" -base 0 -gmt 1} - "# FreeScan : relative date with ordinal month and relative weekday" + # FreeScan : relative date with ordinal month and relative weekday {clock scan "5 years 18 months 385 days next January Fri" -base 0 -gmt 1} - "# FreeScan : ordinal month" + # FreeScan : ordinal month {clock scan "next January" -base 0 -gmt 1} - "# FreeScan : relative week" + # FreeScan : relative week {clock scan "next Fri" -base 0 -gmt 1} - "# FreeScan : relative weekday and week offset " + # FreeScan : relative weekday and week offset {clock scan "next January + 2 week" -base 0 -gmt 1} - "# FreeScan : time only with base" + # FreeScan : time only with base {clock scan "19:18:30" -base 148863600 -gmt 1} - "# FreeScan : time only without base" + # FreeScan : time only without base, gmt {clock scan "19:18:30" -gmt 1} - "# FreeScan : date, system time zone" + # FreeScan : time only without base, system + {clock scan "19:18:30"} + # FreeScan : date, system time zone {clock scan "05/08/2016 20:18:30"} - "# FreeScan : date, supplied time zone" + # FreeScan : date, supplied time zone {clock scan "05/08/2016 20:18:30" -timezone :CET} - "# FreeScan : date, supplied gmt (equivalent -timezone :GMT)" + # FreeScan : date, supplied gmt (equivalent -timezone :GMT) {clock scan "05/08/2016 20:18:30" -gmt 1} - "# FreeScan : time only, numeric zone in string, base time gmt (exchange zones between gmt / -0500)" + # FreeScan : date, supplied time zone gmt + {clock scan "05/08/2016 20:18:30" -timezone :GMT} + # FreeScan : time only, numeric zone in string, base time gmt (exchange zones between gmt / -0500) {clock scan "20:18:30 -0500" -base 148863600 -gmt 1} - "# FreeScan : time only, zone in string (exchange zones between system / gmt)" + # FreeScan : time only, zone in string (exchange zones between system / gmt) {clock scan "19:18:30 GMT" -base 148863600} - } { - if {[string first "**STOP**" $comment] != -1} { return -code error "**STOP**" } - puts "\n% $comment\n% $c" - puts [clock format [{*}$c] -locale en] + # FreeScan : fast switch of zones in cycle - GMT, MST, CET (system) and EST + {clock scan "19:18:30 MST" -base 148863600 -gmt 1 + clock scan "19:18:30 EST" -base 148863600 + } + }] { + puts "% [regsub -all {\n[ \t]*} $c {; }]" + if {[regexp {\s*\#} $c]} continue + puts [clock format [if 1 $c] -locale en] puts [time $c $rep] + puts "" } } proc test-other {{rep 100000}} { - foreach {comment c} { - "# Bad zone" - {catch {clock scan "1 day" -timezone BAD_ZONE}} - } { - if {[string first "**STOP**" $comment] != -1} { return -code error "**STOP**" } - puts "\n% $comment\n% $c" + foreach c [_test_get_commands { + # Bad zone + {catch {clock scan "1 day" -timezone BAD_ZONE -locale en}} + }] { + puts "% [regsub -all {\n[ \t]*} $c {; }]" + if {[regexp {\s*\#} $c]} continue puts [if 1 $c] puts [time $c $rep] + puts "" } } -set factor 10; # 50 -if 1 {;# +proc test {factor} { + puts "" test-scan [expr 10000 * $factor] test-other [expr 5000 * $factor] puts \n**OK** -};# \ No newline at end of file +} + +test 20; # 50 diff --git a/tests/clock.test b/tests/clock.test index ecc6f5f..477f142 100644 --- a/tests/clock.test +++ b/tests/clock.test @@ -35803,6 +35803,27 @@ test clock-34.40 {clock scan, next day of week} { clock format [clock scan "next thursday" -base [clock scan 20000112]] \ -format {%b %d, %Y} } "Jan 20, 2000" +test clock-34.40.1 {clock scan, ordinal month after relative date} { + # This will fail without the bug fix (clock.tcl), as still missing + # month/julian day conversion before ordinal month increment + clock format [ \ + clock scan "5 years 18 months 387 days" -base 0 -gmt 1 + ] -format {%a, %b %d, %Y} -gmt 1 -locale en_US_roman +} "Sat, Jul 23, 1977" +test clock-34.40.2 {clock scan, ordinal month after relative date} { + # This will fail without the bug fix (clock.tcl), as still missing + # month/julian day conversion before ordinal month increment + clock format [ \ + clock scan "5 years 18 months 387 days next Jan" -base 0 -gmt 1 + ] -format {%a, %b %d, %Y} -gmt 1 -locale en_US_roman +} "Mon, Jan 23, 1978" +test clock-34.40.3 {clock scan, day of week after ordinal date} { + # This will fail without the bug fix (clock.tcl), because the relative + # week day should be applied after whole date conversion + clock format [ \ + clock scan "5 years 18 months 387 days next January Fri" -base 0 -gmt 1 + ] -format {%a, %b %d, %Y} -gmt 1 -locale en_US_roman +} "Fri, Jan 27, 1978" # weekday specification and base. test clock-34.41 {2nd monday in november} { -- cgit v0.12 From 1f1f1e4dfcb5859424591754a5ecc2bdf25a087b Mon Sep 17 00:00:00 2001 From: sebres Date: Tue, 10 Jan 2017 22:07:37 +0000 Subject: [temp-commit]: tclClockFmt.c - 1st try using "timerate" instead "time" by performance measurement tests (more precise and fixed time, so no switch of factor expected) --- generic/tclClock.c | 17 +- generic/tclClockFmt.c | 417 ++++++++++++++++++++++++++++++++++++++++++++++ generic/tclDate.c | 12 +- generic/tclDate.h | 44 ++++- generic/tclGetDate.y | 1 + tests-perf/clock.perf.tcl | 40 +++-- unix/Makefile.in | 4 + win/Makefile.in | 1 + win/makefile.vc | 1 + 9 files changed, 512 insertions(+), 25 deletions(-) create mode 100644 generic/tclClockFmt.c diff --git a/generic/tclClock.c b/generic/tclClock.c index e39e032..c869cf4 100644 --- a/generic/tclClock.c +++ b/generic/tclClock.c @@ -8,6 +8,7 @@ * Copyright 1991-1995 Karl Lehenbauer and Mark Diekhans. * Copyright (c) 1995 Sun Microsystems, Inc. * Copyright (c) 2004 by Kevin B. Kenny. All rights reserved. + * Copyright (c) 2015 by Sergey G. Brester aka sebres. All rights reserved. * * See the file "license.terms" for information on usage and redistribution of * this file, and for a DISCLAIMER OF ALL WARRANTIES. @@ -2600,9 +2601,9 @@ ClockScanObjCmd( } */ - if (1) { + if (0) { /* TODO: Tcled Scan proc - */ - int ret; + int ret; Tcl_Obj *callargs[10]; memcpy(callargs, objv, objc * sizeof(*objv)); callargs[0] = Tcl_NewStringObj("::tcl::clock::__org_scan", -1); @@ -2611,6 +2612,18 @@ ClockScanObjCmd( Tcl_DecrRefCount(callargs[0]); return ret; } + + if (1) { + + ClockFmtScnStorage * fss; + + if ((fss = Tcl_GetClockFrmScnFromObj(interp, opts.formatObj)) == NULL) { + return TCL_ERROR; + }; + + Tcl_SetObjResult(interp, Tcl_NewWideIntObj((Tcl_WideInt)fss)); + + } return TCL_OK; } diff --git a/generic/tclClockFmt.c b/generic/tclClockFmt.c new file mode 100644 index 0000000..fa89dde --- /dev/null +++ b/generic/tclClockFmt.c @@ -0,0 +1,417 @@ +/* + * tclClockFmt.c -- + * + * Contains the date format (and scan) routines. This code is back-ported + * from the time and date facilities of tclSE engine, by Serg G. Brester. + * + * Copyright (c) 2015 by Sergey G. Brester aka sebres. All rights reserved. + * + * See the file "license.terms" for information on usage and redistribution of + * this file, and for a DISCLAIMER OF ALL WARRANTIES. + */ + +#include "tclInt.h" +#include "tclDate.h" + +/* + * Miscellaneous forward declarations and functions used within this file + */ + +static void +ClockFmtObj_DupInternalRep(Tcl_Obj *srcPtr, Tcl_Obj *copyPtr); +static void +ClockFmtObj_FreeInternalRep(Tcl_Obj *objPtr); +static int +ClockFmtObj_SetFromAny(Tcl_Interp *interp, Tcl_Obj *objPtr); +static void +ClockFmtObj_UpdateString(Tcl_Obj *objPtr); + + +TCL_DECLARE_MUTEX(ClockFmtMutex); /* Serializes access to common format list. */ + +static void ClockFmtScnStorageDelete(ClockFmtScnStorage *fss); + +/* + * Clock scan and format facilities. + */ + +#define TOK_CHAIN_BLOCK_SIZE 8 + +/* + *---------------------------------------------------------------------- + */ + +#if CLOCK_FMT_SCN_STORAGE_GC_SIZE > 0 + +static struct { + ClockFmtScnStorage *stackPtr; + ClockFmtScnStorage *stackBound; + unsigned int count; +} ClockFmtScnStorage_GC = {NULL, NULL, 0}; + +inline void +ClockFmtScnStorageGC_In(ClockFmtScnStorage *entry) +{ + /* add new entry */ + TclSpliceIn(entry, ClockFmtScnStorage_GC.stackPtr); + if (ClockFmtScnStorage_GC.stackBound == NULL) { + ClockFmtScnStorage_GC.stackBound = entry; + } + ClockFmtScnStorage_GC.count++; + + /* if GC ist full */ + if (ClockFmtScnStorage_GC.count > CLOCK_FMT_SCN_STORAGE_GC_SIZE) { + + /* GC stack is LIFO: delete first inserted entry */ + ClockFmtScnStorage *delEnt = ClockFmtScnStorage_GC.stackBound; + ClockFmtScnStorage_GC.stackBound = delEnt->prevPtr; + TclSpliceOut(delEnt, ClockFmtScnStorage_GC.stackPtr); + ClockFmtScnStorage_GC.count--; + delEnt->prevPtr = delEnt->nextPtr = NULL; + /* remove it now */ + ClockFmtScnStorageDelete(delEnt); + } +} +inline void +ClockFmtScnStorage_GC_Out(ClockFmtScnStorage *entry) +{ + TclSpliceOut(entry, ClockFmtScnStorage_GC.stackPtr); + ClockFmtScnStorage_GC.count--; + if (ClockFmtScnStorage_GC.stackBound == entry) { + ClockFmtScnStorage_GC.stackBound = entry->prevPtr; + } + entry->prevPtr = entry->nextPtr = NULL; +} + +#endif + +/* + *---------------------------------------------------------------------- + */ + +static Tcl_HashTable FmtScnHashTable; +static int initFmtScnHashTable = 0; + +inline Tcl_HashEntry * +HashEntry4FmtScn(ClockFmtScnStorage *fss) { + return (Tcl_HashEntry*)(fss + 1); +}; +inline ClockFmtScnStorage * +FmtScn4HashEntry(Tcl_HashEntry *hKeyPtr) { + return (ClockFmtScnStorage*)(((char*)hKeyPtr) - sizeof(ClockFmtScnStorage)); +}; + +/* + * Format storage hash (list of formats shared across all threads). + */ + +static Tcl_HashEntry * +ClockFmtScnStorageAllocProc( + Tcl_HashTable *tablePtr, /* Hash table. */ + void *keyPtr) /* Key to store in the hash table entry. */ +{ + ClockFmtScnStorage *fss; + + const char *string = (const char *) keyPtr; + Tcl_HashEntry *hPtr; + unsigned int size, + allocsize = sizeof(ClockFmtScnStorage) + sizeof(Tcl_HashEntry); + + allocsize += (size = strlen(string) + 1); + if (size > sizeof(hPtr->key)) { + allocsize -= sizeof(hPtr->key); + } + + fss = ckalloc(allocsize); + + /* initialize */ + memset(fss, 0, sizeof(*fss)); + + hPtr = HashEntry4FmtScn(fss); + memcpy(&hPtr->key.string, string, size); + hPtr->clientData = 0; /* currently unused */ + + return hPtr; +} + +static void +ClockFmtScnStorageFreeProc( + Tcl_HashEntry *hPtr) +{ + ClockFmtScnStorage *fss = FmtScn4HashEntry(hPtr); + ClockScanToken *tok; + + tok = fss->firstScnTok; + while (tok != NULL) { + if (tok->nextTok == tok + 1) { + tok++; + /*****************************/ + } else { + tok = tok->nextTok; + } + } + + ckfree(fss); +} + +static void +ClockFmtScnStorageDelete(ClockFmtScnStorage *fss) { + Tcl_HashEntry *hPtr = HashEntry4FmtScn(fss); + /* + * This will delete a hash entry and call "ckfree" for storage self, if + * some additionally handling required, freeEntryProc can be used instead + */ + Tcl_DeleteHashEntry(hPtr); +} + + +/* + * Derivation of tclStringHashKeyType with another allocEntryProc + */ + +static Tcl_HashKeyType ClockFmtScnStorageHashKeyType; + + +/* + *---------------------------------------------------------------------- + */ + +static ClockFmtScnStorage * +FindOrCreateFmtScnStorage( + Tcl_Interp *interp, + const char *strFmt) +{ + ClockFmtScnStorage *fss = NULL; + int new; + Tcl_HashEntry *hPtr; + + Tcl_MutexLock(&ClockFmtMutex); + + /* if not yet initialized */ + if (!initFmtScnHashTable) { + /* initialize type */ + memcpy(&ClockFmtScnStorageHashKeyType, &tclStringHashKeyType, sizeof(tclStringHashKeyType)); + ClockFmtScnStorageHashKeyType.allocEntryProc = ClockFmtScnStorageAllocProc; + ClockFmtScnStorageHashKeyType.freeEntryProc = ClockFmtScnStorageFreeProc; + initFmtScnHashTable = 1; + + /* initialize hash table */ + Tcl_InitCustomHashTable(&FmtScnHashTable, TCL_CUSTOM_TYPE_KEYS, + &ClockFmtScnStorageHashKeyType); + } + + /* get or create entry (and alocate storage) */ + hPtr = Tcl_CreateHashEntry(&FmtScnHashTable, strFmt, &new); + if (hPtr != NULL) { + + fss = FmtScn4HashEntry(hPtr); + + #if CLOCK_FMT_SCN_STORAGE_GC_SIZE > 0 + /* unlink if it is currently in GC */ + if (new == 0 && fss->objRefCount == 0) { + ClockFmtScnStorage_GC_Out(fss); + } + #endif + + /* new reference, so increment in lock right now */ + fss->objRefCount++; + } + + Tcl_MutexUnlock(&ClockFmtMutex); + + if (fss == NULL && interp != NULL) { + Tcl_AppendResult(interp, "retrieve clock format failed \"", + strFmt ? strFmt : "", "\"", NULL); + Tcl_SetErrorCode(interp, "TCL", "EINVAL", NULL); + } + + return fss; +} + + +/* + * Type definition. + */ + +Tcl_ObjType ClockFmtObjType = { + "clock-format", /* name */ + ClockFmtObj_FreeInternalRep, /* freeIntRepProc */ + ClockFmtObj_DupInternalRep, /* dupIntRepProc */ + ClockFmtObj_UpdateString, /* updateStringProc */ + ClockFmtObj_SetFromAny /* setFromAnyProc */ +}; + +#define SetObjClockFmtScn(objPtr, fss) \ + objPtr->internalRep.twoPtrValue.ptr1 = fss +#define ObjClockFmtScn(objPtr) \ + (ClockFmtScnStorage *)objPtr->internalRep.twoPtrValue.ptr1; + +#define SetObjLitStorage(objPtr, lit) \ + objPtr->internalRep.twoPtrValue.ptr2 = lit +#define ObjLitStorage(objPtr) \ + (ClockLitStorage *)objPtr->internalRep.twoPtrValue.ptr2; + +#define ClockFmtObj_SetObjIntRep(objPtr, fss, lit) \ + objPtr->internalRep.twoPtrValue.ptr1 = fss, \ + objPtr->internalRep.twoPtrValue.ptr2 = lit, \ + objPtr->typePtr = &ClockFmtObjType; + +/* + *---------------------------------------------------------------------- + */ +static void +ClockFmtObj_DupInternalRep(srcPtr, copyPtr) + Tcl_Obj *srcPtr; + Tcl_Obj *copyPtr; +{ + ClockFmtScnStorage *fss = ObjClockFmtScn(srcPtr); + // ClockLitStorage *lit = ObjLitStorage(srcPtr); + + if (fss != NULL) { + Tcl_MutexLock(&ClockFmtMutex); + fss->objRefCount++; + Tcl_MutexUnlock(&ClockFmtMutex); + } + + ClockFmtObj_SetObjIntRep(copyPtr, fss, NULL); + + /* if no format representation, dup string representation */ + if (fss == NULL) { + copyPtr->bytes = ckalloc(srcPtr->length + 1); + memcpy(copyPtr->bytes, srcPtr->bytes, srcPtr->length + 1); + copyPtr->length = srcPtr->length; + } +} +/* + *---------------------------------------------------------------------- + */ +static void +ClockFmtObj_FreeInternalRep(objPtr) + Tcl_Obj *objPtr; +{ + ClockFmtScnStorage *fss = ObjClockFmtScn(objPtr); + // ClockLitStorage *lit = ObjLitStorage(objPtr); + if (fss != NULL) { + Tcl_MutexLock(&ClockFmtMutex); + /* decrement object reference count of format/scan storage */ + if (--fss->objRefCount <= 0) { + #if CLOCK_FMT_SCN_STORAGE_GC_SIZE > 0 + /* don't remove it right now (may be reusable), just add to GC */ + ClockFmtScnStorageGC_In(fss); + #else + /* remove storage (format representation) */ + ClockFmtScnStorageDelete(fss); + #endif + } + Tcl_MutexUnlock(&ClockFmtMutex); + } + SetObjClockFmtScn(objPtr, NULL); + SetObjLitStorage(objPtr, NULL); + objPtr->typePtr = NULL; +}; +/* + *---------------------------------------------------------------------- + */ +static int +ClockFmtObj_SetFromAny(interp, objPtr) + Tcl_Interp *interp; + Tcl_Obj *objPtr; +{ + ClockFmtScnStorage *fss; + const char *strFmt = TclGetString(objPtr); + + if (!strFmt || (fss = FindOrCreateFmtScnStorage(interp, strFmt)) == NULL) { + return TCL_ERROR; + } + + if (objPtr->typePtr && objPtr->typePtr->freeIntRepProc) + objPtr->typePtr->freeIntRepProc(objPtr); + ClockFmtObj_SetObjIntRep(objPtr, fss, NULL); + return TCL_OK; +}; +/* + *---------------------------------------------------------------------- + */ +static void +ClockFmtObj_UpdateString(objPtr) + Tcl_Obj *objPtr; +{ + char *name = "UNKNOWN"; + int len; + ClockFmtScnStorage *fss = ObjClockFmtScn(objPtr); + + if (fss != NULL) { + Tcl_HashEntry *hPtr = HashEntry4FmtScn(fss); + name = hPtr->key.string; + } + len = strlen(name); + objPtr->length = len, + objPtr->bytes = ckalloc((size_t)++len); + if (objPtr->bytes) + memcpy(objPtr->bytes, name, len); +} + +/* + *---------------------------------------------------------------------- + * + * Tcl_GetClockFrmScnFromObj -- + * + * Returns a clock format/scan representation of (*objPtr), if possible. + * If something goes wrong, NULL is returned, and if interp is non-NULL, + * an error message is written there. + * + * Results: + * Valid representation of type ClockFmtScnStorage. + * + * Side effects: + * Caches the ClockFmtScnStorage reference as the internal rep of (*objPtr) + * and in global hash table, shared across all threads. + * + *---------------------------------------------------------------------- + */ + +ClockFmtScnStorage * +Tcl_GetClockFrmScnFromObj( + Tcl_Interp *interp, + Tcl_Obj *objPtr) +{ + ClockFmtScnStorage *fss; + + if (objPtr->typePtr != &ClockFmtObjType) { + if (ClockFmtObj_SetFromAny(interp, objPtr) != TCL_OK) { + return NULL; + } + } + + fss = ObjClockFmtScn(objPtr); + + if (fss == NULL) { + const char *strFmt = TclGetString(objPtr); + fss = FindOrCreateFmtScnStorage(interp, strFmt); + } + + return fss; +} + + +static void +Tcl_GetClockFrmScnFinalize() +{ +#if CLOCK_FMT_SCN_STORAGE_GC_SIZE > 0 + /* clear GC */ + ClockFmtScnStorage_GC.stackPtr = NULL; + ClockFmtScnStorage_GC.stackBound = NULL; + ClockFmtScnStorage_GC.count = 0; +#endif + if (initFmtScnHashTable) { + Tcl_DeleteHashTable(&FmtScnHashTable); + } + Tcl_MutexFinalize(&ClockFmtMutex); +} +/* + * Local Variables: + * mode: c + * c-basic-offset: 4 + * fill-column: 78 + * End: + */ diff --git a/generic/tclDate.c b/generic/tclDate.c index a31e0fc..389b245 100644 --- a/generic/tclDate.c +++ b/generic/tclDate.c @@ -570,12 +570,12 @@ static const yytype_int8 yyrhs[] = /* YYRLINE[YYN] -- source line where rule number YYN was defined. */ static const yytype_uint16 yyrline[] = { - 0, 176, 176, 177, 180, 183, 186, 189, 192, 195, - 198, 202, 207, 210, 216, 222, 230, 236, 247, 251, - 255, 261, 265, 269, 273, 277, 283, 287, 292, 297, - 302, 307, 311, 316, 320, 325, 332, 336, 342, 351, - 360, 370, 384, 389, 392, 395, 398, 401, 404, 409, - 412, 417, 421, 425, 431, 449, 452 + 0, 177, 177, 178, 181, 184, 187, 190, 193, 196, + 199, 203, 208, 211, 217, 223, 231, 237, 248, 252, + 256, 262, 266, 270, 274, 278, 284, 288, 293, 298, + 303, 308, 312, 317, 321, 326, 333, 337, 343, 352, + 361, 371, 385, 390, 393, 396, 399, 402, 405, 410, + 413, 418, 422, 426, 432, 450, 453 }; #endif diff --git a/generic/tclDate.h b/generic/tclDate.h index 6ba9620..c3c362a 100644 --- a/generic/tclDate.h +++ b/generic/tclDate.h @@ -66,13 +66,55 @@ typedef enum _MERIDIAN { } MERIDIAN; /* + * Clock scan and format facilities. + */ + +#define CLOCK_FMT_SCN_STORAGE_GC_SIZE 32 + + +typedef struct ClockFormatToken ClockFormatToken; +typedef struct ClockScanToken ClockScanToken; +typedef struct ClockFmtScnStorage ClockFmtScnStorage; + +typedef struct ClockFormatToken { + ClockFormatToken *nextTok; +} ClockFormatToken; + +typedef struct ClockScanToken { + ClockScanToken *nextTok; +} ClockScanToken; + +typedef struct ClockFmtScnStorage { + int objRefCount; /* Reference count shared across threads */ + ClockScanToken *firstScnTok; + ClockFormatToken *firstFmtTok; +#if CLOCK_FMT_SCN_STORAGE_GC_SIZE > 0 + ClockFmtScnStorage *nextPtr; + ClockFmtScnStorage *prevPtr; +#endif +/* +Tcl_HashEntry hashEntry /* ClockFmtScnStorage is a derivate of Tcl_HashEntry, + * stored by offset +sizeof(self) */ +} ClockFmtScnStorage; + +typedef struct ClockLitStorage { + int dummy; +} ClockLitStorage; + +/* * Prototypes of module functions. */ MODULE_SCOPE time_t ToSeconds(time_t Hours, time_t Minutes, time_t Seconds, MERIDIAN Meridian); -MODULE_SCOPE int TclClockFreeScan(Tcl_Interp *interp, DateInfo *info); +MODULE_SCOPE int TclClockFreeScan(Tcl_Interp *interp, DateInfo *info); + +/* tclClockFmt.c module declarations */ + +MODULE_SCOPE ClockFmtScnStorage * + Tcl_GetClockFrmScnFromObj(Tcl_Interp *interp, + Tcl_Obj *objPtr); + /* * Other externals. diff --git a/generic/tclGetDate.y b/generic/tclGetDate.y index ac781ad..d500d6b 100644 --- a/generic/tclGetDate.y +++ b/generic/tclGetDate.y @@ -9,6 +9,7 @@ * * Copyright (c) 1992-1995 Karl Lehenbauer and Mark Diekhans. * Copyright (c) 1995-1997 Sun Microsystems, Inc. + * Copyright (c) 2015 Sergey G. Brester aka sebres. * * See the file "license.terms" for information on usage and redistribution of * this file, and for a DISCLAIMER OF ALL WARRANTIES. diff --git a/tests-perf/clock.perf.tcl b/tests-perf/clock.perf.tcl index 7ef70ce..59469fd 100644 --- a/tests-perf/clock.perf.tcl +++ b/tests-perf/clock.perf.tcl @@ -25,8 +25,12 @@ proc _test_get_commands {lst} { regsub -all {(?:^|\n)[ \t]*(\#[^\n]*)(?=\n\s*[\{\#])} $lst "\n{\\1}" } -proc test-scan {{rep 100000}} { - foreach c [_test_get_commands { +proc test-scan {{reptime 1000}} { + foreach _(c) [_test_get_commands { + # Scan : date + {clock scan "25.11.2015" -format "%d.%m.%Y" -base 0 -gmt 1} + #return + #{**STOP** : Wed Nov 25 01:00:00 CET 2015} # FreeScan : relative date {clock scan "5 years 18 months 385 days" -base 0 -gmt 1} # FreeScan : relative date with relative weekday @@ -64,33 +68,37 @@ proc test-scan {{rep 100000}} { clock scan "19:18:30 EST" -base 148863600 } }] { - puts "% [regsub -all {\n[ \t]*} $c {; }]" - if {[regexp {\s*\#} $c]} continue - puts [clock format [if 1 $c] -locale en] - puts [time $c $rep] + puts "% [regsub -all {\n[ \t]*} $_(c) {; }]" + if {[regexp {\s*\#} $_(c)]} continue + puts [clock format [if 1 $_(c)] -locale en] + puts [timerate $_(c) $reptime] puts "" } } -proc test-other {{rep 100000}} { - foreach c [_test_get_commands { +proc test-other {{reptime 1000}} { + foreach _(c) [_test_get_commands { # Bad zone {catch {clock scan "1 day" -timezone BAD_ZONE -locale en}} + # Scan : test rotate of GC objects (format is dynamic, so tcl-obj removed with last reference) + {set i 0; time { clock scan "[incr i] - 25.11.2015" -format "$i - %d.%m.%Y" -base 0 -gmt 1 } 50} + # Scan : test reusability of GC objects (format is dynamic, so tcl-obj removed with last reference) + {set i 50; time { clock scan "[incr i -1] - 25.11.2015" -format "$i - %d.%m.%Y" -base 0 -gmt 1 } 50} }] { - puts "% [regsub -all {\n[ \t]*} $c {; }]" - if {[regexp {\s*\#} $c]} continue - puts [if 1 $c] - puts [time $c $rep] + puts "% [regsub -all {\n[ \t]*} $_(c) {; }]" + if {[regexp {\s*\#} $_(c)]} continue + puts [if 1 $_(c)] + puts [timerate $_(c) $reptime] puts "" } } -proc test {factor} { +proc test {{reptime 1000}} { puts "" - test-scan [expr 10000 * $factor] - test-other [expr 5000 * $factor] + test-scan $reptime + test-other $reptime puts \n**OK** } -test 20; # 50 +test 250; # 250 ms diff --git a/unix/Makefile.in b/unix/Makefile.in index c4f6136..b220139 100644 --- a/unix/Makefile.in +++ b/unix/Makefile.in @@ -396,6 +396,7 @@ GENERIC_SRCS = \ $(GENERIC_DIR)/tclBinary.c \ $(GENERIC_DIR)/tclCkalloc.c \ $(GENERIC_DIR)/tclClock.c \ + $(GENERIC_DIR)/tclClockFmt.c \ $(GENERIC_DIR)/tclCmdAH.c \ $(GENERIC_DIR)/tclCmdIL.c \ $(GENERIC_DIR)/tclCmdMZ.c \ @@ -1073,6 +1074,9 @@ tclCkalloc.o: $(GENERIC_DIR)/tclCkalloc.c tclClock.o: $(GENERIC_DIR)/tclClock.c $(CC) -c $(CC_SWITCHES) $(GENERIC_DIR)/tclClock.c +tclClockFmt.o: $(GENERIC_DIR)/tclClockFmt.c + $(CC) -c $(CC_SWITCHES) $(GENERIC_DIR)/tclClockFmt.c + tclCmdAH.o: $(GENERIC_DIR)/tclCmdAH.c $(CC) -c $(CC_SWITCHES) $(GENERIC_DIR)/tclCmdAH.c diff --git a/win/Makefile.in b/win/Makefile.in index e967ef3..82e5516 100644 --- a/win/Makefile.in +++ b/win/Makefile.in @@ -228,6 +228,7 @@ GENERIC_OBJS = \ tclBinary.$(OBJEXT) \ tclCkalloc.$(OBJEXT) \ tclClock.$(OBJEXT) \ + tclClockFmt.$(OBJEXT) \ tclCmdAH.$(OBJEXT) \ tclCmdIL.$(OBJEXT) \ tclCmdMZ.$(OBJEXT) \ diff --git a/win/makefile.vc b/win/makefile.vc index 26ee669..d6dbf85 100644 --- a/win/makefile.vc +++ b/win/makefile.vc @@ -270,6 +270,7 @@ COREOBJS = \ $(TMP_DIR)\tclBinary.obj \ $(TMP_DIR)\tclCkalloc.obj \ $(TMP_DIR)\tclClock.obj \ + $(TMP_DIR)\tclClockFmt.obj \ $(TMP_DIR)\tclCmdAH.obj \ $(TMP_DIR)\tclCmdIL.obj \ $(TMP_DIR)\tclCmdMZ.obj \ -- cgit v0.12 From 5ab3eafa66c83eedbe4da87a549cb83dfa8abac7 Mon Sep 17 00:00:00 2001 From: sebres Date: Tue, 10 Jan 2017 22:09:02 +0000 Subject: [temp-commit]: tclClockFmt.c - 2nd try (with cherry picking of tclSE incompatible facilities) Prepared for common usage of scan command (free scan / format scan) --- generic/tclClock.c | 328 +++++++++++++++++++--------------------------- generic/tclClockFmt.c | 117 +++++++++++++++-- generic/tclDate.h | 63 ++++++++- tests-perf/clock.perf.tcl | 4 +- 4 files changed, 297 insertions(+), 215 deletions(-) diff --git a/generic/tclClock.c b/generic/tclClock.c index c869cf4..888757f 100644 --- a/generic/tclClock.c +++ b/generic/tclClock.c @@ -136,29 +136,6 @@ typedef struct ClockClientData { */ } ClockClientData; -/* - * Structure containing the fields used in [clock format] and [clock scan] - */ - -typedef struct TclDateFields { - Tcl_WideInt seconds; /* Time expressed in seconds from the Posix - * epoch */ - Tcl_WideInt localSeconds; /* Local time expressed in nominal seconds - * from the Posix epoch */ - int tzOffset; /* Time zone offset in seconds east of - * Greenwich */ - Tcl_Obj *tzName; /* Time zone name */ - int julianDay; /* Julian Day Number in local time zone */ - enum {BCE=1, CE=0} era; /* Era */ - int gregorian; /* Flag == 1 if the date is Gregorian */ - int year; /* Year of the era */ - int dayOfYear; /* Day of the year (1 January == 1) */ - int month; /* Month number */ - int dayOfMonth; /* Day of the month */ - int iso8601Year; /* ISO8601 week-based year */ - int iso8601Week; /* ISO8601 week number */ - int dayOfWeek; /* Day of the week */ -} TclDateFields; static const char *const eras[] = { "CE", "BCE", NULL }; /* @@ -241,8 +218,8 @@ static int ClockScanObjCmd( int objc, Tcl_Obj *const objv[]); static int ClockFreeScan( ClientData clientData, Tcl_Interp *interp, - Tcl_Obj *strObj, Tcl_WideInt baseVal, - Tcl_Obj *timezoneObj, Tcl_Obj *locale); + register TclDateFields *date, + Tcl_Obj *strObj, ClockFmtScnCmdArgs *opts); static struct tm * ThreadSafeLocalTime(const time_t *); static unsigned long TzsetGetEpoch(void); static void TzsetIfNecessary(void); @@ -2339,20 +2316,13 @@ ClockMicrosecondsObjCmd( } -typedef struct _ClockFmtScnArgs { - Tcl_Obj *formatObj; /* Format */ - Tcl_Obj *localeObj; /* Locale */ - Tcl_Obj *timezoneObj; /* Timezone */ - Tcl_Obj *baseObj; /* Base (scan only) */ -} _ClockFmtScnArgs; - static int _ClockParseFmtScnArgs( ClientData clientData, /* Client data containing literal pool */ Tcl_Interp *interp, /* Tcl interpreter */ int objc, /* Parameter count */ Tcl_Obj *const objv[], /* Parameter vector */ - _ClockFmtScnArgs *resOpts, /* Result vector: format, locale, timezone... */ + ClockFmtScnCmdArgs *resOpts, /* Result vector: format, locale, timezone... */ int forScan /* Flag to differentiate between format and scan */ ) { ClockClientData *dataPtr = clientData; @@ -2455,7 +2425,7 @@ ClockParseformatargsObjCmd( { ClockClientData *dataPtr = clientData; Tcl_Obj **literals = dataPtr->literals; - _ClockFmtScnArgs resOpts; /* Format, locale and timezone */ + ClockFmtScnCmdArgs resOpts; /* Format, locale and timezone */ Tcl_WideInt clockVal; /* Clock value - just used to parse. */ int ret; @@ -2520,12 +2490,10 @@ ClockScanObjCmd( ClockClientData *dataPtr = clientData; Tcl_Obj **literals = dataPtr->literals; - Tcl_Time retClock; - char *string, *format = NULL; - int gmt, ret = 0; - char *locale; - _ClockFmtScnArgs opts; /* Format, locale, timezone and base */ - Tcl_WideInt baseVal; /* Base value */ + int ret; + ClockFmtScnCmdArgs opts; /* Format, locale, timezone and base */ + Tcl_WideInt baseVal; /* Base time, expressed in seconds from the Epoch */ + TclDateFields date; /* Date fields used for converting */ if ((objc & 1) == 1) { Tcl_WrongNumArgs(interp, 1, objv, "string " @@ -2547,6 +2515,8 @@ ClockScanObjCmd( return ret; } + ret = TCL_ERROR; + if (opts.baseObj != NULL) { if (Tcl_GetWideIntFromObj(interp, opts.baseObj, &baseVal) != TCL_OK) { return TCL_ERROR; @@ -2557,28 +2527,45 @@ ClockScanObjCmd( baseVal = (Tcl_WideInt) now.sec; } + date.tzName = NULL; + + /* If time zone not specified use system time zone */ + if ( opts.timezoneObj == NULL + || TclGetString(opts.timezoneObj) == NULL + || opts.timezoneObj->length == 0 + ) { + opts.timezoneObj = ClockGetSystemTimeZone(clientData, interp); + if (opts.timezoneObj == NULL) { + goto done; + } + } + + /* Get the data for time changes in the given zone */ + + opts.timezoneObj = ClockSetupTimeZone(clientData, interp, opts.timezoneObj); + if (opts.timezoneObj == NULL) { + goto done; + } + + /* + * Extract year, month and day from the base time for the parser to use as + * defaults + */ + + date.tzData = ClockGetTZData(clientData, interp, opts.timezoneObj); + if (date.tzData == NULL) { + goto done; + } + date.seconds = baseVal; + if (ClockGetDateFields(interp, &date, date.tzData, GREGORIAN_CHANGE_DATE) + != TCL_OK) { + goto done; + } + /* If free scan */ if (opts.formatObj == NULL) { -#if 0 - /* Tcled FreeScan proc - */ - Tcl_Obj *callargs[5]; - /* [SB] TODO: Perhaps someday we'll localize the legacy code. Right now, it's not localized. */ - if (opts.localeObj != NULL) { - Tcl_SetResult(interp, - "legacy [clock scan] does not support -locale", TCL_STATIC); - Tcl_SetErrorCode(interp, "CLOCK", "flagWithLegacyFormat", NULL); - return TCL_ERROR; - } - callargs[0] = literals[LIT_FREESCAN]; - callargs[1] = objv[1]; - callargs[2] = opts.baseObj != NULL ? opts.baseObj : Tcl_NewWideIntObj(baseVal); - callargs[3] = opts.timezoneObj != NULL ? opts.timezoneObj : literals[LIT__NIL]; - callargs[4] = opts.localeObj != NULL ? opts.localeObj : literals[LIT_C]; - return Tcl_EvalObjv(interp, 5, callargs, 0); -#else /* Use compiled version of FreeScan - */ - /* [SB] TODO: Perhaps someday we'll localize the legacy code. Right now, it's not localized. */ if (opts.localeObj != NULL) { Tcl_SetResult(interp, @@ -2586,21 +2573,9 @@ ClockScanObjCmd( Tcl_SetErrorCode(interp, "CLOCK", "flagWithLegacyFormat", NULL); return TCL_ERROR; } - return ClockFreeScan(clientData, interp, objv[1], baseVal, - opts.timezoneObj, opts.localeObj); -#endif - } - - - // **** - string = TclGetString(objv[1]); - // **** timezone = ClockGetSystemTimeZone(clientData, interp) - /* - if (timezoneObj == NULL) { - goto done; - } - */ - + ret = ClockFreeScan(clientData, interp, &date, objv[1], &opts); + } + else if (0) { /* TODO: Tcled Scan proc - */ int ret; @@ -2612,19 +2587,45 @@ ClockScanObjCmd( Tcl_DecrRefCount(callargs[0]); return ret; } + else { + /* Use compiled version of Scan - */ + + ret = ClockScan(clientData, interp, &date, objv[1], &opts); + } - if (1) { + if (ret != TCL_OK) { + goto done; + } - ClockFmtScnStorage * fss; - if ((fss = Tcl_GetClockFrmScnFromObj(interp, opts.formatObj)) == NULL) { - return TCL_ERROR; - }; + /* If needed assemble julianDay using new year, month, etc. */ + if (date.julianDay == CL_INVALIDATE) { + GetJulianDayFromEraYearMonthDay(&date, GREGORIAN_CHANGE_DATE); + } + + /* Local seconds to UTC (stored in date.seconds) */ - Tcl_SetObjResult(interp, Tcl_NewWideIntObj((Tcl_WideInt)fss)); + date.localSeconds = + -210866803200L + + ( 86400 * (Tcl_WideInt)date.julianDay ) + + ( date.secondOfDay % 86400 ); + if (ConvertLocalToUTC(interp, &date, date.tzData, GREGORIAN_CHANGE_DATE) + != TCL_OK) { + goto done; } - + + ret = TCL_OK; + +done: + + Tcl_UnsetObjRef(date.tzName); + + if (ret != TCL_OK) { + return ret; + } + + Tcl_SetObjResult(interp, Tcl_NewWideIntObj(date.seconds)); return TCL_OK; } @@ -2634,57 +2635,17 @@ int ClockFreeScan( ClientData clientData, /* Client data containing literal pool */ Tcl_Interp *interp, /* Tcl interpreter */ + register + TclDateFields *date, /* Date fields used for converting */ Tcl_Obj *strObj, /* String containing the time to scan */ - Tcl_WideInt baseVal, /* Base time, expressed in seconds from the Epoch */ - Tcl_Obj *timezoneObj, /* Default time zone in which the time will be expressed */ - Tcl_Obj *locale) /* (Unused) Name of the locale where the time will be scanned. */ + ClockFmtScnCmdArgs *opts) /* Command options */ { - enum Flags {CL_INVALIDATE = (signed int)0x80000000}; - ClockClientData *dataPtr = clientData; Tcl_Obj **literals = dataPtr->literals; DateInfo yy; /* parse structure of TclClockFreeScan */ - TclDateFields date; /* date fields used for converting from seconds */ - Tcl_Obj *tzdata; - int secondOfDay; /* Seconds of day (time only calculation) */ - Tcl_WideInt seconds; int ret = TCL_ERROR; - date.tzName = NULL; - - /* If time zone not specified use system time zone */ - if (timezoneObj == NULL || - TclGetString(timezoneObj) == NULL || timezoneObj->length == 0) { - timezoneObj = ClockGetSystemTimeZone(clientData, interp); - if (timezoneObj == NULL) { - goto done; - } - } - - /* Get the data for time changes in the given zone */ - - timezoneObj = ClockSetupTimeZone(clientData, interp, timezoneObj); - if (timezoneObj == NULL) { - goto done; - } - - /* - * Extract year, month and day from the base time for the parser to use as - * defaults - */ - - tzdata = ClockGetTZData(clientData, interp, timezoneObj); - if (tzdata == NULL) { - goto done; - } - date.seconds = baseVal; - if (ClockGetDateFields(interp, &date, tzdata, GREGORIAN_CHANGE_DATE) - != TCL_OK) { - goto done; - } - - secondOfDay = date.localSeconds % 86400; /* * Parse the date. The parser will fill a structure "yy" with date, time, @@ -2692,9 +2653,9 @@ ClockFreeScan( */ yy.dateInput = Tcl_GetString(strObj); - yy.dateYear = date.year; - yy.dateMonth = date.month; - yy.dateDay = date.dayOfMonth; + yy.dateYear = date->year; + yy.dateMonth = date->month; + yy.dateDay = date->dayOfMonth; if (TclClockFreeScan(interp, &yy) != TCL_OK) { Tcl_Obj *msg = Tcl_NewObj(); @@ -2717,10 +2678,10 @@ ClockFreeScan( } yy.dateYear += ClockCurrentYearCentury(clientData, interp); } - date.era = CE; - date.year = yy.dateYear; - date.month = yy.dateMonth; - date.dayOfMonth = yy.dateDay; + date->era = CE; + date->year = yy.dateYear; + date->month = yy.dateMonth; + date->dayOfMonth = yy.dateDay; if (yy.dateHaveTime == 0) { yy.dateHaveTime = -1; } @@ -2738,34 +2699,34 @@ ClockFreeScan( tzObjStor = ClockFormatNumericTimeZone( 60 * minEast + 3600 * dstFlag); - timezoneObj = ClockSetupTimeZone(clientData, interp, tzObjStor); - if (tzObjStor != timezoneObj) { + opts->timezoneObj = ClockSetupTimeZone(clientData, interp, tzObjStor); + if (tzObjStor != opts->timezoneObj) { Tcl_DecrRefCount(tzObjStor); } - if (timezoneObj == NULL) { + if (opts->timezoneObj == NULL) { goto done; } - tzdata = ClockGetTZData(clientData, interp, timezoneObj); - if (tzdata == NULL) { + date->tzData = ClockGetTZData(clientData, interp, opts->timezoneObj); + if (date->tzData == NULL) { goto done; } } /* on demand (lazy) assemble julianDay using new year, month, etc. */ - date.julianDay = CL_INVALIDATE; + date->julianDay = CL_INVALIDATE; /* * Assemble date, time, zone into seconds-from-epoch */ - Tcl_SetObjRef(date.tzName, timezoneObj); + Tcl_SetObjRef(date->tzName, opts->timezoneObj); if (yy.dateHaveTime == -1) { - secondOfDay = 0; + date->secondOfDay = 0; } else if (yy.dateHaveTime) { - secondOfDay = ToSeconds(yy.dateHour, yy.dateMinutes, + date->secondOfDay = ToSeconds(yy.dateHour, yy.dateMinutes, yy.dateSeconds, yy.dateMeridian); } else @@ -2775,7 +2736,10 @@ ClockFreeScan( && ( yy.dateRelMonth != 0 || yy.dateRelDay != 0 ) ) ) { - secondOfDay = 0; + date->secondOfDay = 0; + } + else { + date->secondOfDay = date->localSeconds % 86400; } /* @@ -2792,26 +2756,26 @@ repeat_rel: int m, h; /* if needed extract year, month, etc. again */ - if (date.month == CL_INVALIDATE) { - GetGregorianEraYearDay(&date, GREGORIAN_CHANGE_DATE); - GetMonthDay(&date); - GetYearWeekDay(&date, GREGORIAN_CHANGE_DATE); + if (date->month == CL_INVALIDATE) { + GetGregorianEraYearDay(date, GREGORIAN_CHANGE_DATE); + GetMonthDay(date); + GetYearWeekDay(date, GREGORIAN_CHANGE_DATE); } /* add the requisite number of months */ - date.month += yy.dateRelMonth - 1; - date.year += date.month / 12; - m = date.month % 12; - date.month = m + 1; + date->month += yy.dateRelMonth - 1; + date->year += date->month / 12; + m = date->month % 12; + date->month = m + 1; /* if the day doesn't exist in the current month, repair it */ - h = hath[IsGregorianLeapYear(&date)][m]; - if (date.dayOfMonth > h) { - date.dayOfMonth = h; + h = hath[IsGregorianLeapYear(date)][m]; + if (date->dayOfMonth > h) { + date->dayOfMonth = h; } /* on demand (lazy) assemble julianDay using new year, month, etc. */ - date.julianDay = CL_INVALIDATE; + date->julianDay = CL_INVALIDATE; yy.dateRelMonth = 0; } @@ -2820,19 +2784,19 @@ repeat_rel: if (yy.dateRelDay) { /* assemble julianDay using new year, month, etc. */ - if (date.julianDay == CL_INVALIDATE) { - GetJulianDayFromEraYearMonthDay(&date, GREGORIAN_CHANGE_DATE); + if (date->julianDay == CL_INVALIDATE) { + GetJulianDayFromEraYearMonthDay(date, GREGORIAN_CHANGE_DATE); } - date.julianDay += yy.dateRelDay; + date->julianDay += yy.dateRelDay; /* julianDay was changed, on demand (lazy) extract year, month, etc. again */ - date.month = CL_INVALIDATE; + date->month = CL_INVALIDATE; yy.dateRelDay = 0; } /* relative time (seconds) */ - secondOfDay += yy.dateRelSeconds; + date->secondOfDay += yy.dateRelSeconds; yy.dateRelSeconds = 0; } @@ -2845,20 +2809,20 @@ repeat_rel: int monthDiff; /* if needed extract year, month, etc. again */ - if (date.month == CL_INVALIDATE) { - GetGregorianEraYearDay(&date, GREGORIAN_CHANGE_DATE); - GetMonthDay(&date); - GetYearWeekDay(&date, GREGORIAN_CHANGE_DATE); + if (date->month == CL_INVALIDATE) { + GetGregorianEraYearDay(date, GREGORIAN_CHANGE_DATE); + GetMonthDay(date); + GetYearWeekDay(date, GREGORIAN_CHANGE_DATE); } if (yy.dateMonthOrdinal > 0) { - monthDiff = yy.dateMonth - date.month; + monthDiff = yy.dateMonth - date->month; if (monthDiff <= 0) { monthDiff += 12; } yy.dateMonthOrdinal--; } else { - monthDiff = date.month - yy.dateMonth; + monthDiff = date->month - yy.dateMonth; if (monthDiff >= 0) { monthDiff -= 12; } @@ -2867,7 +2831,7 @@ repeat_rel: /* process it further via relative times */ yy.dateHaveRel++; - date.year += yy.dateMonthOrdinal; + date->year += yy.dateMonthOrdinal; yy.dateRelMonth += monthDiff; yy.dateHaveOrdinalMonth = 0; @@ -2881,48 +2845,24 @@ repeat_rel: if (yy.dateHaveDay && !yy.dateHaveDate) { /* if needed assemble julianDay now */ - if (date.julianDay == CL_INVALIDATE) { - GetJulianDayFromEraYearMonthDay(&date, GREGORIAN_CHANGE_DATE); + if (date->julianDay == CL_INVALIDATE) { + GetJulianDayFromEraYearMonthDay(date, GREGORIAN_CHANGE_DATE); } - date.era = CE; - date.julianDay = WeekdayOnOrBefore(yy.dateDayNumber, date.julianDay + 6) + date->era = CE; + date->julianDay = WeekdayOnOrBefore(yy.dateDayNumber, date->julianDay + 6) + 7 * yy.dateDayOrdinal; if (yy.dateDayOrdinal > 0) { - date.julianDay -= 7; + date->julianDay -= 7; } } - /* If needed assemble julianDay using new year, month, etc. */ - if (date.julianDay == CL_INVALIDATE) { - GetJulianDayFromEraYearMonthDay(&date, GREGORIAN_CHANGE_DATE); - } - - /* Local seconds to UTC */ - - date.localSeconds = - -210866803200L - + ( 86400 * (Tcl_WideInt)date.julianDay ) - + ( secondOfDay % 86400 ); - - if (ConvertLocalToUTC(interp, &date, tzdata, GREGORIAN_CHANGE_DATE) - != TCL_OK) { - goto done; - } - - seconds = date.seconds; + /* Free scanning completed - date ready */ ret = TCL_OK; done: - Tcl_UnsetObjRef(date.tzName); - - if (ret != TCL_OK) { - return ret; - } - - Tcl_SetObjResult(interp, Tcl_NewWideIntObj(seconds)); return TCL_OK; } diff --git a/generic/tclClockFmt.c b/generic/tclClockFmt.c index fa89dde..356965d 100644 --- a/generic/tclClockFmt.c +++ b/generic/tclClockFmt.c @@ -35,8 +35,6 @@ static void ClockFmtScnStorageDelete(ClockFmtScnStorage *fss); * Clock scan and format facilities. */ -#define TOK_CHAIN_BLOCK_SIZE 8 - /* *---------------------------------------------------------------------- */ @@ -139,16 +137,16 @@ ClockFmtScnStorageFreeProc( Tcl_HashEntry *hPtr) { ClockFmtScnStorage *fss = FmtScn4HashEntry(hPtr); - ClockScanToken *tok; - - tok = fss->firstScnTok; - while (tok != NULL) { - if (tok->nextTok == tok + 1) { - tok++; - /*****************************/ - } else { - tok = tok->nextTok; - } + + if (fss->scnTok != NULL) { + ckfree(fss->scnTok); + fss->scnTok = NULL; + fss->scnTokC = 0; + } + if (fss->fmtTok != NULL) { + ckfree(fss->fmtTok); + fss->fmtTok = NULL; + fss->fmtTokC = 0; } ckfree(fss); @@ -394,6 +392,101 @@ Tcl_GetClockFrmScnFromObj( } +#define AllocTokenInChain(tok, chain, tokC) \ + if ((tok) >= (chain) + (tokC)) { \ + (char *)(chain) = ckrealloc((char *)(chain), \ + (tokC) + sizeof((**(tok))) * CLOCK_MIN_TOK_CHAIN_BLOCK_SIZE); \ + if ((chain) == NULL) { return NULL; }; \ + (tok) = (chain) + (tokC); \ + (tokC) += CLOCK_MIN_TOK_CHAIN_BLOCK_SIZE; \ + } + +const char *ScnSTokenChars = "dmyYHMS"; +static ClockScanToken ScnSTokens[] = { + {CTOKT_DIGIT, 1, 2, 0}, +}; + +/* + *---------------------------------------------------------------------- + */ +ClockScanToken ** +ClockGetOrParseScanFormat( + Tcl_Interp *interp, /* Tcl interpreter */ + Tcl_Obj *formatObj) /* Format container */ +{ + ClockFmtScnStorage *fss; + ClockScanToken **tok; + + if (formatObj->typePtr != &ClockFmtObjType) { + if (ClockFmtObj_SetFromAny(interp, formatObj) != TCL_OK) { + return NULL; + } + } + + fss = ObjClockFmtScn(formatObj); + + if (fss == NULL) { + fss = FindOrCreateFmtScnStorage(interp, TclGetString(formatObj)); + if (fss == NULL) { + return NULL; + } + } + + /* if first time scanning - tokenize format */ + if (fss->scnTok == NULL) { + const char *strFmt; + register const char *p, *e; + + fss->scnTokC = CLOCK_MIN_TOK_CHAIN_BLOCK_SIZE; + fss->scnTok = + tok = ckalloc(sizeof(**tok) * CLOCK_MIN_TOK_CHAIN_BLOCK_SIZE); + (*tok)->type = CTOKT_EOB; + strFmt = TclGetString(formatObj); + for (e = p = strFmt, e += formatObj->length; p != e; p++) { + switch (*p) { + case '%': + if (p+1 >= e) + goto word_tok; + AllocTokenInChain(tok, fss->scnTok, fss->scnTokC); + p++; + // *tok = + break; + case ' ': + AllocTokenInChain(tok, fss->scnTok, fss->scnTokC); + // *tok = + break; + default: +word_tok: + break; + } + } + } + + return fss->scnTok; +} + +/* + *---------------------------------------------------------------------- + */ +int +ClockScan( + ClientData clientData, /* Client data containing literal pool */ + Tcl_Interp *interp, /* Tcl interpreter */ + TclDateFields *date, /* Date fields used for converting */ + Tcl_Obj *strObj, /* String containing the time to scan */ + ClockFmtScnCmdArgs *opts) /* Command options */ +{ + ClockScanToken **tok; + + if (ClockGetOrParseScanFormat(interp, opts->formatObj) == NULL) { + return TCL_ERROR; + } + + // Tcl_SetObjResult(interp, Tcl_NewWideIntObj((Tcl_WideInt)fss)); + return TCL_ERROR; +} + + static void Tcl_GetClockFrmScnFinalize() { diff --git a/generic/tclDate.h b/generic/tclDate.h index c3c362a..0329b2c 100644 --- a/generic/tclDate.h +++ b/generic/tclDate.h @@ -57,6 +57,44 @@ typedef struct DateInfo { } DateInfo; +enum {CL_INVALIDATE = (signed int)0x80000000}; +/* + * Structure containing the command arguments supplied to [clock format] and [clock scan] + */ + +typedef struct ClockFmtScnCmdArgs { + Tcl_Obj *formatObj; /* Format */ + Tcl_Obj *localeObj; /* Name of the locale where the time will be expressed. */ + Tcl_Obj *timezoneObj; /* Default time zone in which the time will be expressed */ + Tcl_Obj *baseObj; /* Base (scan only) */ +} ClockFmtScnCmdArgs; + +/* + * Structure containing the fields used in [clock format] and [clock scan] + */ + +typedef struct TclDateFields { + Tcl_WideInt seconds; /* Time expressed in seconds from the Posix + * epoch */ + Tcl_WideInt localSeconds; /* Local time expressed in nominal seconds + * from the Posix epoch */ + int secondOfDay; /* Seconds of day (in-between time only calculation) */ + int tzOffset; /* Time zone offset in seconds east of + * Greenwich */ + Tcl_Obj *tzName; /* Time zone name (if set the refCount is incremented) */ + Tcl_Obj *tzData; /* Time zone data object (internally referenced) */ + int julianDay; /* Julian Day Number in local time zone */ + enum {BCE=1, CE=0} era; /* Era */ + int gregorian; /* Flag == 1 if the date is Gregorian */ + int year; /* Year of the era */ + int dayOfYear; /* Day of the year (1 January == 1) */ + int month; /* Month number */ + int dayOfMonth; /* Day of the month */ + int iso8601Year; /* ISO8601 week-based year */ + int iso8601Week; /* ISO8601 week number */ + int dayOfWeek; /* Day of the week */ +} TclDateFields; + /* * Meridian: am, pm, or 24-hour style. */ @@ -71,23 +109,31 @@ typedef enum _MERIDIAN { #define CLOCK_FMT_SCN_STORAGE_GC_SIZE 32 +#define CLOCK_MIN_TOK_CHAIN_BLOCK_SIZE 12 + +typedef enum _CLCKTOK_TYPE { + CTOKT_EOB=0, CTOKT_DIGIT, CTOKT_SPACE +} CLCKTOK_TYPE; -typedef struct ClockFormatToken ClockFormatToken; -typedef struct ClockScanToken ClockScanToken; typedef struct ClockFmtScnStorage ClockFmtScnStorage; typedef struct ClockFormatToken { - ClockFormatToken *nextTok; + CLCKTOK_TYPE type; } ClockFormatToken; typedef struct ClockScanToken { - ClockScanToken *nextTok; + unsigned short int type; + unsigned short int minSize; + unsigned short int maxSize; + unsigned short int offs; } ClockScanToken; typedef struct ClockFmtScnStorage { - int objRefCount; /* Reference count shared across threads */ - ClockScanToken *firstScnTok; - ClockFormatToken *firstFmtTok; + int objRefCount; /* Reference count shared across threads */ + ClockScanToken **scnTok; + unsigned int scnTokC; + ClockFormatToken **fmtTok; + unsigned int fmtTokC; #if CLOCK_FMT_SCN_STORAGE_GC_SIZE > 0 ClockFmtScnStorage *nextPtr; ClockFmtScnStorage *prevPtr; @@ -115,6 +161,9 @@ MODULE_SCOPE ClockFmtScnStorage * Tcl_GetClockFrmScnFromObj(Tcl_Interp *interp, Tcl_Obj *objPtr); +MODULE_SCOPE int ClockScan(ClientData clientData, Tcl_Interp *interp, + TclDateFields *date, Tcl_Obj *strObj, + ClockFmtScnCmdArgs *opts); /* * Other externals. diff --git a/tests-perf/clock.perf.tcl b/tests-perf/clock.perf.tcl index 59469fd..7994428 100644 --- a/tests-perf/clock.perf.tcl +++ b/tests-perf/clock.perf.tcl @@ -28,8 +28,7 @@ proc _test_get_commands {lst} { proc test-scan {{reptime 1000}} { foreach _(c) [_test_get_commands { # Scan : date - {clock scan "25.11.2015" -format "%d.%m.%Y" -base 0 -gmt 1} - #return + #{clock scan "25.11.2015" -format "%d.%m.%Y" -base 0 -gmt 1} #{**STOP** : Wed Nov 25 01:00:00 CET 2015} # FreeScan : relative date {clock scan "5 years 18 months 385 days" -base 0 -gmt 1} @@ -80,6 +79,7 @@ proc test-other {{reptime 1000}} { foreach _(c) [_test_get_commands { # Bad zone {catch {clock scan "1 day" -timezone BAD_ZONE -locale en}} + **STOP** # Scan : test rotate of GC objects (format is dynamic, so tcl-obj removed with last reference) {set i 0; time { clock scan "[incr i] - 25.11.2015" -format "$i - %d.%m.%Y" -base 0 -gmt 1 } 50} # Scan : test reusability of GC objects (format is dynamic, so tcl-obj removed with last reference) -- cgit v0.12 From 898bc97bbea9601d6d2a7ac526e14e9a3b540362 Mon Sep 17 00:00:00 2001 From: sebres Date: Tue, 10 Jan 2017 22:10:44 +0000 Subject: [temp-commit]: tclClockFmt.c - amend for 2nd try (with cherry picking of tclSE incompatible facilities) Prepared for common usage of both scan commands - free scan / scan with format (currently faked via eval to __org_scan); test cases passed. --- generic/tclClock.c | 218 +++++++++++++++++++++++++-------------------------- generic/tclDate.c | 51 +++--------- generic/tclDate.h | 93 ++++++++++++++-------- generic/tclGetDate.y | 39 ++------- 4 files changed, 189 insertions(+), 212 deletions(-) diff --git a/generic/tclClock.c b/generic/tclClock.c index 888757f..3c296b5 100644 --- a/generic/tclClock.c +++ b/generic/tclClock.c @@ -218,7 +218,7 @@ static int ClockScanObjCmd( int objc, Tcl_Obj *const objv[]); static int ClockFreeScan( ClientData clientData, Tcl_Interp *interp, - register TclDateFields *date, + register DateInfo *info, Tcl_Obj *strObj, ClockFmtScnCmdArgs *opts); static struct tm * ThreadSafeLocalTime(const time_t *); static unsigned long TzsetGetEpoch(void); @@ -2492,8 +2492,9 @@ ClockScanObjCmd( int ret; ClockFmtScnCmdArgs opts; /* Format, locale, timezone and base */ - Tcl_WideInt baseVal; /* Base time, expressed in seconds from the Epoch */ - TclDateFields date; /* Date fields used for converting */ + Tcl_WideInt baseVal; /* Base time, expressed in seconds from the Epoch */ + DateInfo yy; /* Common structure used for parsing */ + DateInfo *info = &yy; if ((objc & 1) == 1) { Tcl_WrongNumArgs(interp, 1, objv, "string " @@ -2527,7 +2528,7 @@ ClockScanObjCmd( baseVal = (Tcl_WideInt) now.sec; } - date.tzName = NULL; + yydate.tzName = NULL; /* If time zone not specified use system time zone */ if ( opts.timezoneObj == NULL @@ -2552,12 +2553,12 @@ ClockScanObjCmd( * defaults */ - date.tzData = ClockGetTZData(clientData, interp, opts.timezoneObj); - if (date.tzData == NULL) { + yydate.tzData = ClockGetTZData(clientData, interp, opts.timezoneObj); + if (yydate.tzData == NULL) { goto done; } - date.seconds = baseVal; - if (ClockGetDateFields(interp, &date, date.tzData, GREGORIAN_CHANGE_DATE) + yydate.seconds = baseVal; + if (ClockGetDateFields(interp, &yydate, yydate.tzData, GREGORIAN_CHANGE_DATE) != TCL_OK) { goto done; } @@ -2573,10 +2574,10 @@ ClockScanObjCmd( Tcl_SetErrorCode(interp, "CLOCK", "flagWithLegacyFormat", NULL); return TCL_ERROR; } - ret = ClockFreeScan(clientData, interp, &date, objv[1], &opts); + ret = ClockFreeScan(clientData, interp, info, objv[1], &opts); } else - if (0) { + if (1) { /* TODO: Tcled Scan proc - */ int ret; Tcl_Obj *callargs[10]; @@ -2585,12 +2586,12 @@ ClockScanObjCmd( Tcl_IncrRefCount(callargs[0]); ret = Tcl_EvalObjv(interp, objc, callargs, 0); Tcl_DecrRefCount(callargs[0]); - return ret; + return ret; } else { /* Use compiled version of Scan - */ - ret = ClockScan(clientData, interp, &date, objv[1], &opts); + ret = ClockScan(clientData, interp, &yydate, objv[1], &opts); } if (ret != TCL_OK) { @@ -2599,18 +2600,18 @@ ClockScanObjCmd( /* If needed assemble julianDay using new year, month, etc. */ - if (date.julianDay == CL_INVALIDATE) { - GetJulianDayFromEraYearMonthDay(&date, GREGORIAN_CHANGE_DATE); + if (yydate.julianDay == CL_INVALIDATE) { + GetJulianDayFromEraYearMonthDay(&yydate, GREGORIAN_CHANGE_DATE); } - /* Local seconds to UTC (stored in date.seconds) */ + /* Local seconds to UTC (stored in yydate.seconds) */ - date.localSeconds = + yydate.localSeconds = -210866803200L - + ( 86400 * (Tcl_WideInt)date.julianDay ) - + ( date.secondOfDay % 86400 ); + + ( 86400 * (Tcl_WideInt)yydate.julianDay ) + + ( yySeconds % 86400 ); - if (ConvertLocalToUTC(interp, &date, date.tzData, GREGORIAN_CHANGE_DATE) + if (ConvertLocalToUTC(interp, &yydate, yydate.tzData, GREGORIAN_CHANGE_DATE) != TCL_OK) { goto done; } @@ -2619,13 +2620,13 @@ ClockScanObjCmd( done: - Tcl_UnsetObjRef(date.tzName); + Tcl_UnsetObjRef(yydate.tzName); if (ret != TCL_OK) { return ret; } - Tcl_SetObjResult(interp, Tcl_NewWideIntObj(date.seconds)); + Tcl_SetObjResult(interp, Tcl_NewWideIntObj(yydate.seconds)); return TCL_OK; } @@ -2636,28 +2637,28 @@ ClockFreeScan( ClientData clientData, /* Client data containing literal pool */ Tcl_Interp *interp, /* Tcl interpreter */ register - TclDateFields *date, /* Date fields used for converting */ + DateInfo *info, /* Date fields used for parsing & converting + * simultaneously a yy-parse structure of the + * TclClockFreeScan */ Tcl_Obj *strObj, /* String containing the time to scan */ ClockFmtScnCmdArgs *opts) /* Command options */ { - ClockClientData *dataPtr = clientData; - Tcl_Obj **literals = dataPtr->literals; + // ClockClientData *dataPtr = clientData; + // Tcl_Obj **literals = dataPtr->literals; - DateInfo yy; /* parse structure of TclClockFreeScan */ int ret = TCL_ERROR; - /* - * Parse the date. The parser will fill a structure "yy" with date, time, - * time zone, relative month/day/seconds, relative weekday, ordinal month. + * Parse the date. The parser will fill a structure "info" with date, + * time, time zone, relative month/day/seconds, relative weekday, ordinal + * month. + * Notice that many yy-defines point to values in the "info" or "date" + * structure, e. g. yySeconds -> info->date.secondOfDay or + * yySeconds -> info->date.month (same as yydate.month) */ - yy.dateInput = Tcl_GetString(strObj); + yyInput = Tcl_GetString(strObj); - yy.dateYear = date->year; - yy.dateMonth = date->month; - yy.dateDay = date->dayOfMonth; - - if (TclClockFreeScan(interp, &yy) != TCL_OK) { + if (TclClockFreeScan(interp, info) != TCL_OK) { Tcl_Obj *msg = Tcl_NewObj(); Tcl_AppendPrintfToObj(msg, "unable to convert date-time string \"%s\": %s", Tcl_GetString(strObj), TclGetString(Tcl_GetObjResult(interp))); @@ -2671,19 +2672,16 @@ ClockFreeScan( * midnight. */ - if (yy.dateHaveDate) { - if (yy.dateYear < 100) { - if (yy.dateYear >= ClockGetYearOfCenturySwitch(clientData, interp)) { - yy.dateYear -= 100; + if (yyHaveDate) { + if (yyYear < 100) { + if (yyYear >= ClockGetYearOfCenturySwitch(clientData, interp)) { + yyYear -= 100; } - yy.dateYear += ClockCurrentYearCentury(clientData, interp); + yyYear += ClockCurrentYearCentury(clientData, interp); } - date->era = CE; - date->year = yy.dateYear; - date->month = yy.dateMonth; - date->dayOfMonth = yy.dateDay; - if (yy.dateHaveTime == 0) { - yy.dateHaveTime = -1; + yydate.era = CE; + if (yyHaveTime == 0) { + yyHaveTime = -1; } } @@ -2692,10 +2690,10 @@ ClockFreeScan( * zone indicator of +-hhmm and setup this time zone. */ - if (yy.dateHaveZone) { + if (yyHaveZone) { Tcl_Obj *tzObjStor = NULL; - int minEast = -yy.dateTimezone; - int dstFlag = 1 - yy.dateDSTmode; + int minEast = -yyTimezone; + int dstFlag = 1 - yyDSTmode; tzObjStor = ClockFormatNumericTimeZone( 60 * minEast + 3600 * dstFlag); @@ -2706,40 +2704,40 @@ ClockFreeScan( if (opts->timezoneObj == NULL) { goto done; } - date->tzData = ClockGetTZData(clientData, interp, opts->timezoneObj); - if (date->tzData == NULL) { + yydate.tzData = ClockGetTZData(clientData, interp, opts->timezoneObj); + if (yydate.tzData == NULL) { goto done; } } /* on demand (lazy) assemble julianDay using new year, month, etc. */ - date->julianDay = CL_INVALIDATE; + yydate.julianDay = CL_INVALIDATE; /* * Assemble date, time, zone into seconds-from-epoch */ - Tcl_SetObjRef(date->tzName, opts->timezoneObj); + Tcl_SetObjRef(yydate.tzName, opts->timezoneObj); - if (yy.dateHaveTime == -1) { - date->secondOfDay = 0; + if (yyHaveTime == -1) { + yySeconds = 0; } else - if (yy.dateHaveTime) { - date->secondOfDay = ToSeconds(yy.dateHour, yy.dateMinutes, - yy.dateSeconds, yy.dateMeridian); + if (yyHaveTime) { + yySeconds = ToSeconds(yyHour, yyMinutes, + yySeconds, yyMeridian); } else - if ( (yy.dateHaveDay && !yy.dateHaveDate) - || yy.dateHaveOrdinalMonth - || ( yy.dateHaveRel - && ( yy.dateRelMonth != 0 - || yy.dateRelDay != 0 ) ) + if ( (yyHaveDay && !yyHaveDate) + || yyHaveOrdinalMonth + || ( yyHaveRel + && ( yyRelMonth != 0 + || yyRelDay != 0 ) ) ) { - date->secondOfDay = 0; + yySeconds = 0; } else { - date->secondOfDay = date->localSeconds % 86400; + yySeconds = yydate.localSeconds % 86400; } /* @@ -2748,56 +2746,56 @@ ClockFreeScan( repeat_rel: - if (yy.dateHaveRel) { + if (yyHaveRel) { /* add months (or years in months) */ - if (yy.dateRelMonth != 0) { + if (yyRelMonth != 0) { int m, h; /* if needed extract year, month, etc. again */ - if (date->month == CL_INVALIDATE) { - GetGregorianEraYearDay(date, GREGORIAN_CHANGE_DATE); - GetMonthDay(date); - GetYearWeekDay(date, GREGORIAN_CHANGE_DATE); + if (yyMonth == CL_INVALIDATE) { + GetGregorianEraYearDay(&yydate, GREGORIAN_CHANGE_DATE); + GetMonthDay(&yydate); + GetYearWeekDay(&yydate, GREGORIAN_CHANGE_DATE); } /* add the requisite number of months */ - date->month += yy.dateRelMonth - 1; - date->year += date->month / 12; - m = date->month % 12; - date->month = m + 1; + yyMonth += yyRelMonth - 1; + yyYear += yyMonth / 12; + m = yyMonth % 12; + yyMonth = m + 1; /* if the day doesn't exist in the current month, repair it */ - h = hath[IsGregorianLeapYear(date)][m]; - if (date->dayOfMonth > h) { - date->dayOfMonth = h; + h = hath[IsGregorianLeapYear(&yydate)][m]; + if (yyDay > h) { + yyDay = h; } /* on demand (lazy) assemble julianDay using new year, month, etc. */ - date->julianDay = CL_INVALIDATE; + yydate.julianDay = CL_INVALIDATE; - yy.dateRelMonth = 0; + yyRelMonth = 0; } /* add days (or other parts aligned to days) */ - if (yy.dateRelDay) { + if (yyRelDay) { /* assemble julianDay using new year, month, etc. */ - if (date->julianDay == CL_INVALIDATE) { - GetJulianDayFromEraYearMonthDay(date, GREGORIAN_CHANGE_DATE); + if (yydate.julianDay == CL_INVALIDATE) { + GetJulianDayFromEraYearMonthDay(&yydate, GREGORIAN_CHANGE_DATE); } - date->julianDay += yy.dateRelDay; + yydate.julianDay += yyRelDay; /* julianDay was changed, on demand (lazy) extract year, month, etc. again */ - date->month = CL_INVALIDATE; + yyMonth = CL_INVALIDATE; - yy.dateRelDay = 0; + yyRelDay = 0; } /* relative time (seconds) */ - date->secondOfDay += yy.dateRelSeconds; - yy.dateRelSeconds = 0; + yySeconds += yyRelSeconds; + yyRelSeconds = 0; } @@ -2805,35 +2803,35 @@ repeat_rel: * Do relative (ordinal) month */ - if (yy.dateHaveOrdinalMonth) { + if (yyHaveOrdinalMonth) { int monthDiff; /* if needed extract year, month, etc. again */ - if (date->month == CL_INVALIDATE) { - GetGregorianEraYearDay(date, GREGORIAN_CHANGE_DATE); - GetMonthDay(date); - GetYearWeekDay(date, GREGORIAN_CHANGE_DATE); + if (yyMonth == CL_INVALIDATE) { + GetGregorianEraYearDay(&yydate, GREGORIAN_CHANGE_DATE); + GetMonthDay(&yydate); + GetYearWeekDay(&yydate, GREGORIAN_CHANGE_DATE); } - if (yy.dateMonthOrdinal > 0) { - monthDiff = yy.dateMonth - date->month; + if (yyMonthOrdinalIncr > 0) { + monthDiff = yyMonthOrdinal - yyMonth; if (monthDiff <= 0) { monthDiff += 12; } - yy.dateMonthOrdinal--; + yyMonthOrdinalIncr--; } else { - monthDiff = date->month - yy.dateMonth; + monthDiff = yyMonth - yyMonthOrdinal; if (monthDiff >= 0) { monthDiff -= 12; } - yy.dateMonthOrdinal++; + yyMonthOrdinalIncr++; } /* process it further via relative times */ - yy.dateHaveRel++; - date->year += yy.dateMonthOrdinal; - yy.dateRelMonth += monthDiff; - yy.dateHaveOrdinalMonth = 0; + yyHaveRel++; + yyYear += yyMonthOrdinalIncr; + yyRelMonth += monthDiff; + yyHaveOrdinalMonth = 0; goto repeat_rel; } @@ -2842,18 +2840,18 @@ repeat_rel: * Do relative weekday */ - if (yy.dateHaveDay && !yy.dateHaveDate) { + if (yyHaveDay && !yyHaveDate) { /* if needed assemble julianDay now */ - if (date->julianDay == CL_INVALIDATE) { - GetJulianDayFromEraYearMonthDay(date, GREGORIAN_CHANGE_DATE); + if (yydate.julianDay == CL_INVALIDATE) { + GetJulianDayFromEraYearMonthDay(&yydate, GREGORIAN_CHANGE_DATE); } - date->era = CE; - date->julianDay = WeekdayOnOrBefore(yy.dateDayNumber, date->julianDay + 6) - + 7 * yy.dateDayOrdinal; - if (yy.dateDayOrdinal > 0) { - date->julianDay -= 7; + yydate.era = CE; + yydate.julianDay = WeekdayOnOrBefore(yyDayNumber, yydate.julianDay + 6) + + 7 * yyDayOrdinal; + if (yyDayOrdinal > 0) { + yydate.julianDay -= 7; } } @@ -2863,7 +2861,7 @@ repeat_rel: done: - return TCL_OK; + return ret; } /*---------------------------------------------------------------------- diff --git a/generic/tclDate.c b/generic/tclDate.c index 389b245..a47f43d 100644 --- a/generic/tclDate.c +++ b/generic/tclDate.c @@ -109,31 +109,6 @@ #define YYMALLOC ckalloc #define YYFREE(x) (ckfree((void*) (x))) -#define yyDSTmode (info->dateDSTmode) -#define yyDayOrdinal (info->dateDayOrdinal) -#define yyDayNumber (info->dateDayNumber) -#define yyMonthOrdinal (info->dateMonthOrdinal) -#define yyHaveDate (info->dateHaveDate) -#define yyHaveDay (info->dateHaveDay) -#define yyHaveOrdinalMonth (info->dateHaveOrdinalMonth) -#define yyHaveRel (info->dateHaveRel) -#define yyHaveTime (info->dateHaveTime) -#define yyHaveZone (info->dateHaveZone) -#define yyTimezone (info->dateTimezone) -#define yyDay (info->dateDay) -#define yyMonth (info->dateMonth) -#define yyYear (info->dateYear) -#define yyHour (info->dateHour) -#define yyMinutes (info->dateMinutes) -#define yySeconds (info->dateSeconds) -#define yyMeridian (info->dateMeridian) -#define yyRelMonth (info->dateRelMonth) -#define yyRelDay (info->dateRelDay) -#define yyRelSeconds (info->dateRelSeconds) -#define yyRelPointer (info->dateRelPointer) -#define yyInput (info->dateInput) -#define yyDigitCount (info->dateDigitCount) - #define EPOCH 1970 #define START_OF_TIME 1902 #define END_OF_TIME 2037 @@ -570,12 +545,12 @@ static const yytype_int8 yyrhs[] = /* YYRLINE[YYN] -- source line where rule number YYN was defined. */ static const yytype_uint16 yyrline[] = { - 0, 177, 177, 178, 181, 184, 187, 190, 193, 196, - 199, 203, 208, 211, 217, 223, 231, 237, 248, 252, - 256, 262, 266, 270, 274, 278, 284, 288, 293, 298, - 303, 308, 312, 317, 321, 326, 333, 337, 343, 352, - 361, 371, 385, 390, 393, 396, 399, 402, 405, 410, - 413, 418, 422, 426, 432, 450, 453 + 0, 152, 152, 153, 156, 159, 162, 165, 168, 171, + 174, 178, 183, 186, 192, 198, 206, 212, 223, 227, + 231, 237, 241, 245, 249, 253, 259, 263, 268, 273, + 278, 283, 287, 292, 296, 301, 308, 312, 318, 327, + 336, 346, 360, 365, 368, 371, 374, 377, 380, 385, + 388, 393, 397, 401, 407, 425, 428 }; #endif @@ -1842,16 +1817,16 @@ yyreduce: case 36: { - yyMonthOrdinal = 1; - yyMonth = (yyvsp[(2) - (2)].Number); + yyMonthOrdinalIncr = 1; + yyMonthOrdinal = (yyvsp[(2) - (2)].Number); ;} break; case 37: { - yyMonthOrdinal = (yyvsp[(2) - (3)].Number); - yyMonth = (yyvsp[(3) - (3)].Number); + yyMonthOrdinalIncr = (yyvsp[(2) - (3)].Number); + yyMonthOrdinal = (yyvsp[(3) - (3)].Number); ;} break; @@ -2722,7 +2697,7 @@ TclClockFreeScan( yyTimezone = 0; yyDSTmode = DSTmaybe; yyHaveOrdinalMonth = 0; - yyMonthOrdinal = 0; + yyMonthOrdinalIncr = 0; yyHaveDay = 0; yyDayOrdinal = 0; yyDayNumber = 0; @@ -2873,9 +2848,9 @@ TclClockOldscanObjCmd( resultElement = Tcl_NewObj(); if (yyHaveOrdinalMonth) { Tcl_ListObjAppendElement(interp, resultElement, - Tcl_NewIntObj((int) yyMonthOrdinal)); + Tcl_NewIntObj((int) yyMonthOrdinalIncr)); Tcl_ListObjAppendElement(interp, resultElement, - Tcl_NewIntObj((int) yyMonth)); + Tcl_NewIntObj((int) yyMonthOrdinal)); } Tcl_ListObjAppendElement(interp, result, resultElement); diff --git a/generic/tclDate.h b/generic/tclDate.h index 0329b2c..49420a2 100644 --- a/generic/tclDate.h +++ b/generic/tclDate.h @@ -14,19 +14,43 @@ #define _TCLCLOCK_H /* + * Structure containing the fields used in [clock format] and [clock scan] + */ + +typedef struct TclDateFields { + Tcl_WideInt seconds; /* Time expressed in seconds from the Posix + * epoch */ + Tcl_WideInt localSeconds; /* Local time expressed in nominal seconds + * from the Posix epoch */ + int tzOffset; /* Time zone offset in seconds east of + * Greenwich */ + Tcl_Obj *tzName; /* Time zone name (if set the refCount is incremented) */ + Tcl_Obj *tzData; /* Time zone data object (internally referenced) */ + int julianDay; /* Julian Day Number in local time zone */ + enum {BCE=1, CE=0} era; /* Era */ + int gregorian; /* Flag == 1 if the date is Gregorian */ + int year; /* Year of the era */ + int dayOfYear; /* Day of the year (1 January == 1) */ + int month; /* Month number */ + int dayOfMonth; /* Day of the month */ + int iso8601Year; /* ISO8601 week-based year */ + int iso8601Week; /* ISO8601 week number */ + int dayOfWeek; /* Day of the week */ + int hour; /* Hours of day (in-between time only calculation) */ + int minutes; /* Minutes of day (in-between time only calculation) */ + int secondOfDay; /* Seconds of day (in-between time only calculation) */ +} TclDateFields; + +/* * Structure contains return parsed fields. */ typedef struct DateInfo { - time_t dateYear; - time_t dateMonth; - time_t dateDay; + TclDateFields date; + int dateHaveDate; - time_t dateHour; - time_t dateMinutes; - time_t dateSeconds; int dateMeridian; int dateHaveTime; @@ -39,6 +63,7 @@ typedef struct DateInfo { time_t dateRelSeconds; int dateHaveRel; + time_t dateMonthOrdinalIncr; time_t dateMonthOrdinal; int dateHaveOrdinalMonth; @@ -56,6 +81,36 @@ typedef struct DateInfo { const char* separatrix; /* String separating messages */ } DateInfo; +#define yydate (info->date) /* Date fields used for converting */ + +#define yyDay (info->date.dayOfMonth) +#define yyMonth (info->date.month) +#define yyYear (info->date.year) + +#define yyHour (info->date.hour) +#define yyMinutes (info->date.minutes) +#define yySeconds (info->date.secondOfDay) + +#define yyDSTmode (info->dateDSTmode) +#define yyDayOrdinal (info->dateDayOrdinal) +#define yyDayNumber (info->dateDayNumber) +#define yyMonthOrdinalIncr (info->dateMonthOrdinalIncr) +#define yyMonthOrdinal (info->dateMonthOrdinal) +#define yyHaveDate (info->dateHaveDate) +#define yyHaveDay (info->dateHaveDay) +#define yyHaveOrdinalMonth (info->dateHaveOrdinalMonth) +#define yyHaveRel (info->dateHaveRel) +#define yyHaveTime (info->dateHaveTime) +#define yyHaveZone (info->dateHaveZone) +#define yyTimezone (info->dateTimezone) +#define yyMeridian (info->dateMeridian) +#define yyRelMonth (info->dateRelMonth) +#define yyRelDay (info->dateRelDay) +#define yyRelSeconds (info->dateRelSeconds) +#define yyRelPointer (info->dateRelPointer) +#define yyInput (info->dateInput) +#define yyDigitCount (info->dateDigitCount) + enum {CL_INVALIDATE = (signed int)0x80000000}; /* @@ -70,32 +125,6 @@ typedef struct ClockFmtScnCmdArgs { } ClockFmtScnCmdArgs; /* - * Structure containing the fields used in [clock format] and [clock scan] - */ - -typedef struct TclDateFields { - Tcl_WideInt seconds; /* Time expressed in seconds from the Posix - * epoch */ - Tcl_WideInt localSeconds; /* Local time expressed in nominal seconds - * from the Posix epoch */ - int secondOfDay; /* Seconds of day (in-between time only calculation) */ - int tzOffset; /* Time zone offset in seconds east of - * Greenwich */ - Tcl_Obj *tzName; /* Time zone name (if set the refCount is incremented) */ - Tcl_Obj *tzData; /* Time zone data object (internally referenced) */ - int julianDay; /* Julian Day Number in local time zone */ - enum {BCE=1, CE=0} era; /* Era */ - int gregorian; /* Flag == 1 if the date is Gregorian */ - int year; /* Year of the era */ - int dayOfYear; /* Day of the year (1 January == 1) */ - int month; /* Month number */ - int dayOfMonth; /* Day of the month */ - int iso8601Year; /* ISO8601 week-based year */ - int iso8601Week; /* ISO8601 week number */ - int dayOfWeek; /* Day of the week */ -} TclDateFields; - -/* * Meridian: am, pm, or 24-hour style. */ diff --git a/generic/tclGetDate.y b/generic/tclGetDate.y index d500d6b..571b7df 100644 --- a/generic/tclGetDate.y +++ b/generic/tclGetDate.y @@ -56,31 +56,6 @@ #define YYMALLOC ckalloc #define YYFREE(x) (ckfree((void*) (x))) -#define yyDSTmode (info->dateDSTmode) -#define yyDayOrdinal (info->dateDayOrdinal) -#define yyDayNumber (info->dateDayNumber) -#define yyMonthOrdinal (info->dateMonthOrdinal) -#define yyHaveDate (info->dateHaveDate) -#define yyHaveDay (info->dateHaveDay) -#define yyHaveOrdinalMonth (info->dateHaveOrdinalMonth) -#define yyHaveRel (info->dateHaveRel) -#define yyHaveTime (info->dateHaveTime) -#define yyHaveZone (info->dateHaveZone) -#define yyTimezone (info->dateTimezone) -#define yyDay (info->dateDay) -#define yyMonth (info->dateMonth) -#define yyYear (info->dateYear) -#define yyHour (info->dateHour) -#define yyMinutes (info->dateMinutes) -#define yySeconds (info->dateSeconds) -#define yyMeridian (info->dateMeridian) -#define yyRelMonth (info->dateRelMonth) -#define yyRelDay (info->dateRelDay) -#define yyRelSeconds (info->dateRelSeconds) -#define yyRelPointer (info->dateRelPointer) -#define yyInput (info->dateInput) -#define yyDigitCount (info->dateDigitCount) - #define EPOCH 1970 #define START_OF_TIME 1902 #define END_OF_TIME 2037 @@ -331,12 +306,12 @@ date : tUNUMBER '/' tUNUMBER { ; ordMonth: tNEXT tMONTH { - yyMonthOrdinal = 1; - yyMonth = $2; + yyMonthOrdinalIncr = 1; + yyMonthOrdinal = $2; } | tNEXT tUNUMBER tMONTH { - yyMonthOrdinal = $2; - yyMonth = $3; + yyMonthOrdinalIncr = $2; + yyMonthOrdinal = $3; } ; @@ -933,7 +908,7 @@ TclClockFreeScan( yyTimezone = 0; yyDSTmode = DSTmaybe; yyHaveOrdinalMonth = 0; - yyMonthOrdinal = 0; + yyMonthOrdinalIncr = 0; yyHaveDay = 0; yyDayOrdinal = 0; yyDayNumber = 0; @@ -1084,9 +1059,9 @@ TclClockOldscanObjCmd( resultElement = Tcl_NewObj(); if (yyHaveOrdinalMonth) { Tcl_ListObjAppendElement(interp, resultElement, - Tcl_NewIntObj((int) yyMonthOrdinal)); + Tcl_NewIntObj((int) yyMonthOrdinalIncr)); Tcl_ListObjAppendElement(interp, resultElement, - Tcl_NewIntObj((int) yyMonth)); + Tcl_NewIntObj((int) yyMonthOrdinal)); } Tcl_ListObjAppendElement(interp, result, resultElement); -- cgit v0.12 From aba1f29686731df92a81ca76ce22cd65601f4070 Mon Sep 17 00:00:00 2001 From: sebres Date: Tue, 10 Jan 2017 22:12:07 +0000 Subject: [temp-commit]: rewrite scan token map handling --- generic/tclClock.c | 2 + generic/tclClockFmt.c | 102 ++++++++++++++++++++++++++++++++++++---------- tests-perf/clock.perf.tcl | 12 +++++- 3 files changed, 93 insertions(+), 23 deletions(-) diff --git a/generic/tclClock.c b/generic/tclClock.c index 3c296b5..e00d6a2 100644 --- a/generic/tclClock.c +++ b/generic/tclClock.c @@ -2576,6 +2576,7 @@ ClockScanObjCmd( } ret = ClockFreeScan(clientData, interp, info, objv[1], &opts); } +#if 0 else if (1) { /* TODO: Tcled Scan proc - */ @@ -2588,6 +2589,7 @@ ClockScanObjCmd( Tcl_DecrRefCount(callargs[0]); return ret; } +#endif else { /* Use compiled version of Scan - */ diff --git a/generic/tclClockFmt.c b/generic/tclClockFmt.c index 356965d..93416af 100644 --- a/generic/tclClockFmt.c +++ b/generic/tclClockFmt.c @@ -392,19 +392,32 @@ Tcl_GetClockFrmScnFromObj( } -#define AllocTokenInChain(tok, chain, tokC) \ - if ((tok) >= (chain) + (tokC)) { \ +#define AllocTokenInChain(tok, chain, tokCnt) \ + if (++(tok) >= (chain) + (tokCnt)) { \ (char *)(chain) = ckrealloc((char *)(chain), \ - (tokC) + sizeof((**(tok))) * CLOCK_MIN_TOK_CHAIN_BLOCK_SIZE); \ - if ((chain) == NULL) { return NULL; }; \ - (tok) = (chain) + (tokC); \ - (tokC) += CLOCK_MIN_TOK_CHAIN_BLOCK_SIZE; \ - } - -const char *ScnSTokenChars = "dmyYHMS"; -static ClockScanToken ScnSTokens[] = { + (tokCnt + CLOCK_MIN_TOK_CHAIN_BLOCK_SIZE) * sizeof(*(tok))); \ + if ((chain) == NULL) { goto done; }; \ + (tok) = (chain) + (tokCnt); \ + (tokCnt) += CLOCK_MIN_TOK_CHAIN_BLOCK_SIZE; \ + } \ + *(tok) = NULL; + +const char *ScnSTokenMapChars = + "dmyYHMS"; +static ClockScanToken ScnSTokenMap[] = { + {CTOKT_DIGIT, 1, 2, 0}, + {CTOKT_DIGIT, 1, 2, 0}, + {CTOKT_DIGIT, 1, 2, 0}, + {CTOKT_DIGIT, 1, 4, 0}, + {CTOKT_DIGIT, 1, 2, 0}, + {CTOKT_DIGIT, 1, 2, 0}, {CTOKT_DIGIT, 1, 2, 0}, }; +const char *ScnSpecTokenMapChars = + " %"; +static ClockScanToken ScnSpecTokenMap[] = { + {CTOKT_SPACE, 1, 0xffff, 0}, +}; /* *---------------------------------------------------------------------- @@ -435,31 +448,73 @@ ClockGetOrParseScanFormat( /* if first time scanning - tokenize format */ if (fss->scnTok == NULL) { const char *strFmt; - register const char *p, *e; + register const char *p, *e, *cp, *word_start = NULL; + + Tcl_MutexLock(&ClockFmtMutex); fss->scnTokC = CLOCK_MIN_TOK_CHAIN_BLOCK_SIZE; fss->scnTok = - tok = ckalloc(sizeof(**tok) * CLOCK_MIN_TOK_CHAIN_BLOCK_SIZE); - (*tok)->type = CTOKT_EOB; + tok = ckalloc(sizeof(*tok) * CLOCK_MIN_TOK_CHAIN_BLOCK_SIZE); + *tok = NULL; strFmt = TclGetString(formatObj); for (e = p = strFmt, e += formatObj->length; p != e; p++) { switch (*p) { case '%': - if (p+1 >= e) - goto word_tok; - AllocTokenInChain(tok, fss->scnTok, fss->scnTokC); + if (p+1 >= e) { + word_start = p; + continue; + } p++; - // *tok = + /* try to find modifier: */ + switch (*p) { + case '%': + word_start = p-1; + continue; + break; + case 'E': + goto ext_tok_E; + break; + case 'O': + goto ext_tok_O; + break; + default: + cp = strchr(ScnSTokenMapChars, *p); + if (!cp || *cp == '\0') { + word_start = p-1; + continue; + } + *tok = &ScnSTokenMap[cp - ScnSTokenMapChars]; + AllocTokenInChain(tok, fss->scnTok, fss->scnTokC); + break; + } break; case ' ': + cp = strchr(ScnSpecTokenMapChars, *p); + if (!cp || *cp == '\0') { + p--; + goto word_tok; + } + *tok = &ScnSpecTokenMap[cp - ScnSpecTokenMapChars]; AllocTokenInChain(tok, fss->scnTok, fss->scnTokC); - // *tok = break; default: word_tok: - break; + + continue; } + + continue; +ext_tok_E: + +ext_tok_O: + + /*******************/ + continue; + } + +done: + Tcl_MutexUnlock(&ClockFmtMutex); } return fss->scnTok; @@ -478,11 +533,16 @@ ClockScan( { ClockScanToken **tok; - if (ClockGetOrParseScanFormat(interp, opts->formatObj) == NULL) { + if ((tok = ClockGetOrParseScanFormat(interp, opts->formatObj)) == NULL) { return TCL_ERROR; } - // Tcl_SetObjResult(interp, Tcl_NewWideIntObj((Tcl_WideInt)fss)); + //*********************************** + + Tcl_SetObjResult(interp, Tcl_NewWideIntObj((Tcl_WideInt)tok)); + return TCL_OK; + + return TCL_ERROR; } diff --git a/tests-perf/clock.perf.tcl b/tests-perf/clock.perf.tcl index 7994428..969e279 100644 --- a/tests-perf/clock.perf.tcl +++ b/tests-perf/clock.perf.tcl @@ -28,8 +28,16 @@ proc _test_get_commands {lst} { proc test-scan {{reptime 1000}} { foreach _(c) [_test_get_commands { # Scan : date - #{clock scan "25.11.2015" -format "%d.%m.%Y" -base 0 -gmt 1} - #{**STOP** : Wed Nov 25 01:00:00 CET 2015} + {clock scan "25.11.2015" -format "%d.%m.%Y" -base 0 -gmt 1} + {clock scan "1111" -format "%d%m%y" -base 0 -gmt 1} + {**STOP** : Wed Nov 25 01:00:00 CET 2015} + # Scan : long format test (allock chain) + {clock scan "25.11.2015" -format "%d.%m.%Y %d.%m.%Y %d.%m.%Y %d.%m.%Y %d.%m.%Y %d.%m.%Y %d.%m.%Y %d.%m.%Y" -base 0 -gmt 1} + # Scan : dynamic, very long format test (create obj representation, allock chain, GC, etc): + {clock scan "25.11.2015" -format [string repeat "[incr i] %d.%m.%Y %d.%m.%Y" 10] -base 0 -gmt 1} + # Scan : again: + {clock scan "25.11.2015" -format [string repeat "[incr i -1] %d.%m.%Y %d.%m.%Y" 10] -base 0 -gmt 1} + # FreeScan : relative date {clock scan "5 years 18 months 385 days" -base 0 -gmt 1} # FreeScan : relative date with relative weekday -- cgit v0.12 From a3c42aef3efed25bc18881155ac08426831649dd Mon Sep 17 00:00:00 2001 From: sebres Date: Tue, 10 Jan 2017 22:15:36 +0000 Subject: [temp-commit]: clock scan tokenizer logic ready (still needs many rules) caching extended (currentYearCentury, yearOfCenturySwitch, lastBaseDate ...) --- generic/tclClock.c | 69 +++++++++++---- generic/tclClockFmt.c | 218 +++++++++++++++++++++++++++++++++++++++------- generic/tclDate.c | 1 - generic/tclDate.h | 88 ++++++++++++------- generic/tclGetDate.y | 1 - tests-perf/clock.perf.tcl | 98 ++++++++++++++++----- 6 files changed, 372 insertions(+), 103 deletions(-) diff --git a/generic/tclClock.c b/generic/tclClock.c index e00d6a2..2e7b854 100644 --- a/generic/tclClock.c +++ b/generic/tclClock.c @@ -117,6 +117,8 @@ typedef struct ClockClientData { Tcl_Obj **literals; /* Pool of object literals. */ /* Cache for current clock parameters, imparted via "configure" */ unsigned long LastTZEpoch; + int currentYearCentury; + int yearOfCenturySwitch; Tcl_Obj *SystemTimeZone; Tcl_Obj *SystemSetupTZData; Tcl_Obj *GMTSetupTimeZone; @@ -126,6 +128,9 @@ typedef struct ClockClientData { Tcl_Obj *LastUnnormSetupTimeZone; Tcl_Obj *LastSetupTimeZone; Tcl_Obj *LastSetupTZData; + /* Cache for last base (fast convert if base/tz not changed) */ + Tcl_Obj *lastBaseTimeZone; + TclDateFields lastBaseDate; /* /* [SB] TODO: back-port (from tclSE) the same date caching ... * Cache for last date (fast convert if date parsed was the same) * / @@ -325,6 +330,8 @@ TclClockInit( Tcl_IncrRefCount(data->literals[i]); } data->LastTZEpoch = 0; + data->currentYearCentury = -1; + data->yearOfCenturySwitch = -1; data->SystemTimeZone = NULL; data->SystemSetupTZData = NULL; data->GMTSetupTimeZone = NULL; @@ -335,6 +342,8 @@ TclClockInit( data->LastSetupTimeZone = NULL; data->LastSetupTZData = NULL; + data->lastBaseTimeZone = NULL; + /* * Install the commands. */ @@ -368,6 +377,8 @@ ClockConfigureClear( ClockClientData *data) { data->LastTZEpoch = 0; + data->currentYearCentury = -1; + data->yearOfCenturySwitch = -1; Tcl_UnsetObjRef(data->SystemTimeZone); Tcl_UnsetObjRef(data->SystemSetupTZData); Tcl_UnsetObjRef(data->GMTSetupTimeZone); @@ -708,11 +719,16 @@ ClockCurrentYearCentury( { ClockClientData *dataPtr = clientData; Tcl_Obj **literals = dataPtr->literals; - int year = 2000; + int year = dataPtr->currentYearCentury; - Tcl_Obj * yearObj = Tcl_ObjGetVar2(interp, - literals[LIT_CURRENTYEARCENTURY], NULL, TCL_LEAVE_ERR_MSG); - Tcl_GetIntFromObj(NULL, yearObj, &year); + if (year == -1) { + Tcl_Obj * yearObj; + year = 2000; + yearObj = Tcl_ObjGetVar2(interp, + literals[LIT_CURRENTYEARCENTURY], NULL, TCL_LEAVE_ERR_MSG); + Tcl_GetIntFromObj(NULL, yearObj, &year); + dataPtr->currentYearCentury = year; + } return year; } inline int @@ -722,11 +738,16 @@ ClockGetYearOfCenturySwitch( { ClockClientData *dataPtr = clientData; Tcl_Obj **literals = dataPtr->literals; - int year = 37; - - Tcl_Obj * yearObj = Tcl_ObjGetVar2(interp, - literals[LIT_YEAROFCENTURYSWITCH], NULL, TCL_LEAVE_ERR_MSG); - Tcl_GetIntFromObj(NULL, yearObj, &year); + int year = dataPtr->yearOfCenturySwitch; + + if (year == -1) { + Tcl_Obj * yearObj; + year = 37; + yearObj = Tcl_ObjGetVar2(interp, + literals[LIT_YEAROFCENTURYSWITCH], NULL, TCL_LEAVE_ERR_MSG); + Tcl_GetIntFromObj(NULL, yearObj, &year); + dataPtr->yearOfCenturySwitch = year; + } return year; } @@ -2557,12 +2578,27 @@ ClockScanObjCmd( if (yydate.tzData == NULL) { goto done; } - yydate.seconds = baseVal; - if (ClockGetDateFields(interp, &yydate, yydate.tzData, GREGORIAN_CHANGE_DATE) - != TCL_OK) { - goto done; + Tcl_SetObjRef(yydate.tzName, opts.timezoneObj); + + /* check cached */ + if ( dataPtr->lastBaseTimeZone == opts.timezoneObj + && dataPtr->lastBaseDate.seconds == baseVal) { + memcpy(&yydate, &dataPtr->lastBaseDate, ClockCacheableDateFieldsSize); + } else { + /* extact fields from base */ + yydate.seconds = baseVal; + if (ClockGetDateFields(interp, &yydate, yydate.tzData, GREGORIAN_CHANGE_DATE) + != TCL_OK) { + goto done; + } + /* cache last base */ + memcpy(&dataPtr->lastBaseDate, &yydate, ClockCacheableDateFieldsSize); + dataPtr->lastBaseTimeZone = opts.timezoneObj; } + /* seconds are in localSeconds (relative base date), so reset time here */ + yyHour = 0; yyMinutes = 0; yySeconds = 0; yyMeridian = MER24; + /* If free scan */ if (opts.formatObj == NULL) { /* Use compiled version of FreeScan - */ @@ -2593,7 +2629,7 @@ ClockScanObjCmd( else { /* Use compiled version of Scan - */ - ret = ClockScan(clientData, interp, &yydate, objv[1], &opts); + ret = ClockScan(clientData, interp, info, objv[1], &opts); } if (ret != TCL_OK) { @@ -2710,6 +2746,9 @@ ClockFreeScan( if (yydate.tzData == NULL) { goto done; } + + Tcl_SetObjRef(yydate.tzName, opts->timezoneObj); + } /* on demand (lazy) assemble julianDay using new year, month, etc. */ @@ -2719,8 +2758,6 @@ ClockFreeScan( * Assemble date, time, zone into seconds-from-epoch */ - Tcl_SetObjRef(yydate.tzName, opts->timezoneObj); - if (yyHaveTime == -1) { yySeconds = 0; } diff --git a/generic/tclClockFmt.c b/generic/tclClockFmt.c index 93416af..b074681 100644 --- a/generic/tclClockFmt.c +++ b/generic/tclClockFmt.c @@ -400,35 +400,48 @@ Tcl_GetClockFrmScnFromObj( (tok) = (chain) + (tokCnt); \ (tokCnt) += CLOCK_MIN_TOK_CHAIN_BLOCK_SIZE; \ } \ - *(tok) = NULL; + memset(tok, 0, sizeof(*(tok))); const char *ScnSTokenMapChars = "dmyYHMS"; -static ClockScanToken ScnSTokenMap[] = { - {CTOKT_DIGIT, 1, 2, 0}, - {CTOKT_DIGIT, 1, 2, 0}, - {CTOKT_DIGIT, 1, 2, 0}, - {CTOKT_DIGIT, 1, 4, 0}, - {CTOKT_DIGIT, 1, 2, 0}, - {CTOKT_DIGIT, 1, 2, 0}, - {CTOKT_DIGIT, 1, 2, 0}, +static ClockScanTokenMap ScnSTokenMap[] = { + {CTOKT_DIGIT, CLF_DATE, 1, 2, TclOffset(DateInfo, date.dayOfMonth), + NULL}, + {CTOKT_DIGIT, CLF_DATE, 1, 2, TclOffset(DateInfo, date.month), + NULL}, + {CTOKT_DIGIT, CLF_DATE, 1, 2, TclOffset(DateInfo, date.year), + NULL}, + {CTOKT_DIGIT, CLF_DATE, 1, 4, TclOffset(DateInfo, date.year), + NULL}, + {CTOKT_DIGIT, CLF_TIME, 1, 2, TclOffset(DateInfo, date.hour), + NULL}, + {CTOKT_DIGIT, CLF_TIME, 1, 2, TclOffset(DateInfo, date.minutes), + NULL}, + {CTOKT_DIGIT, CLF_TIME, 1, 2, TclOffset(DateInfo, date.secondOfDay), + NULL}, }; const char *ScnSpecTokenMapChars = - " %"; -static ClockScanToken ScnSpecTokenMap[] = { - {CTOKT_SPACE, 1, 0xffff, 0}, + " "; +static ClockScanTokenMap ScnSpecTokenMap[] = { + {CTOKT_SPACE, 0, 1, 0xffff, 0, + NULL}, +}; + +static ClockScanTokenMap ScnWordTokenMap = { + CTOKT_WORD, 0, 1, 0, 0, + NULL }; /* *---------------------------------------------------------------------- */ -ClockScanToken ** +ClockScanToken * ClockGetOrParseScanFormat( Tcl_Interp *interp, /* Tcl interpreter */ Tcl_Obj *formatObj) /* Format container */ { ClockFmtScnStorage *fss; - ClockScanToken **tok; + ClockScanToken *tok; if (formatObj->typePtr != &ClockFmtObjType) { if (ClockFmtObj_SetFromAny(interp, formatObj) != TCL_OK) { @@ -448,27 +461,30 @@ ClockGetOrParseScanFormat( /* if first time scanning - tokenize format */ if (fss->scnTok == NULL) { const char *strFmt; - register const char *p, *e, *cp, *word_start = NULL; + register const char *p, *e, *cp; Tcl_MutexLock(&ClockFmtMutex); fss->scnTokC = CLOCK_MIN_TOK_CHAIN_BLOCK_SIZE; fss->scnTok = tok = ckalloc(sizeof(*tok) * CLOCK_MIN_TOK_CHAIN_BLOCK_SIZE); - *tok = NULL; + memset(tok, 0, sizeof(*(tok))); strFmt = TclGetString(formatObj); for (e = p = strFmt, e += formatObj->length; p != e; p++) { switch (*p) { case '%': if (p+1 >= e) { - word_start = p; - continue; + goto word_tok; } p++; /* try to find modifier: */ switch (*p) { case '%': - word_start = p-1; + /* begin new word token - don't join with previous word token, + * because current mapping should be "...%%..." -> "...%..." */ + tok->map = &ScnWordTokenMap; + tok->tokWord.start = tok->tokWord.end = p; + AllocTokenInChain(tok, fss->scnTok, fss->scnTokC); continue; break; case 'E': @@ -480,10 +496,24 @@ ClockGetOrParseScanFormat( default: cp = strchr(ScnSTokenMapChars, *p); if (!cp || *cp == '\0') { - word_start = p-1; - continue; + p--; + goto word_tok; + } + tok->map = &ScnSTokenMap[cp - ScnSTokenMapChars]; + /* calculate look ahead value by standing together tokens */ + if (tok > fss->scnTok) { + ClockScanToken *prevTok = tok - 1; + unsigned int lookAhead = tok->map->minSize; + + while (prevTok >= fss->scnTok) { + if (prevTok->map->type != tok->map->type) { + break; + } + prevTok->lookAhead += lookAhead; + prevTok--; + } } - *tok = &ScnSTokenMap[cp - ScnSTokenMapChars]; + /* next token */ AllocTokenInChain(tok, fss->scnTok, fss->scnTokC); break; } @@ -494,18 +524,33 @@ ClockGetOrParseScanFormat( p--; goto word_tok; } - *tok = &ScnSpecTokenMap[cp - ScnSpecTokenMapChars]; + tok->map = &ScnSpecTokenMap[cp - ScnSpecTokenMapChars]; AllocTokenInChain(tok, fss->scnTok, fss->scnTokC); break; default: word_tok: - - continue; + if (1) { + ClockScanToken *wordTok = tok; + if (tok > fss->scnTok && (tok-1)->map == &ScnWordTokenMap) { + wordTok = tok-1; + } + wordTok->tokWord.end = p; + if (wordTok == tok) { + wordTok->tokWord.start = p; + wordTok->map = &ScnWordTokenMap; + AllocTokenInChain(tok, fss->scnTok, fss->scnTokC); + } + continue; + } } continue; + ext_tok_E: + /*******************/ + continue; + ext_tok_O: /*******************/ @@ -527,23 +572,134 @@ int ClockScan( ClientData clientData, /* Client data containing literal pool */ Tcl_Interp *interp, /* Tcl interpreter */ - TclDateFields *date, /* Date fields used for converting */ + register DateInfo *info, /* Date fields used for parsing & converting */ Tcl_Obj *strObj, /* String containing the time to scan */ ClockFmtScnCmdArgs *opts) /* Command options */ { - ClockScanToken **tok; + ClockScanToken *tok; + ClockScanTokenMap *map; + register const char *p, *x, *end; + unsigned short int flags = 0; + int ret = TCL_ERROR; if ((tok = ClockGetOrParseScanFormat(interp, opts->formatObj)) == NULL) { return TCL_ERROR; } + + /* prepare parsing */ + + yyMeridian = MER24; + + /* bypass spaces at begin of string */ + + p = TclGetString(strObj); + end = p + strObj->length; + while (p < end && isspace(UCHAR(*p))) { + p++; + } + info->dateStart = yyInput = p; + + /* parse string */ + for (; tok->map != NULL; yyInput = p, tok++) { + map = tok->map; + switch (map->type) + { + case CTOKT_DIGIT: + if (1) { + unsigned int val = 0; + int size = map->maxSize; + /* greedy find digits (look forward), corresponding pre-calculated lookAhead */ + size += tok->lookAhead; + x = yyInput + size; + while (isdigit(UCHAR(*p)) && p < x) { p++; }; + /* consider reserved (lookAhead) for next tokens */ + p -= tok->lookAhead; + size = p - yyInput; + if (size < map->minSize) { + /* missing input -> error */ + goto done; + } + /* string 2 number */ + p = yyInput; x = p + size; + while (p < x) { + val = val * 10 + (*p++ - '0'); + } + /* put number into info by offset */ + *(time_t *)(((char *)info) + map->offs) = val; + flags |= map->flags; + } + break; + case CTOKT_SPACE: + while (p < end && isspace(UCHAR(*p))) { + p++; + } + break; + case CTOKT_WORD: + x = tok->tokWord.start; + if (x == tok->tokWord.end) { /* single char word */ + if (*p != *x) { + /* no match -> error */ + goto done; + } + p++; + continue; + } + /* multi-char word */ + while (p < end && x < tok->tokWord.end && *p++ == *x++) {}; + if (x < tok->tokWord.end) { + /* no match -> error */ + goto done; + } + break; + } + } - //*********************************** + /* ignore spaces at end */ + while (p < end && isspace(UCHAR(*p))) { + p++; + } + /* check end was reached */ + if (p < end) { + /* something after last token - wrong format */ + goto done; + } - Tcl_SetObjResult(interp, Tcl_NewWideIntObj((Tcl_WideInt)tok)); - return TCL_OK; + /* invalidate result */ + if (flags & CLF_DATE) { + yydate.julianDay = CL_INVALIDATE; + + if (yyYear < 100) { + if (yyYear >= ClockGetYearOfCenturySwitch(clientData, interp)) { + yyYear -= 100; + } + yyYear += ClockCurrentYearCentury(clientData, interp); + } + yydate.era = CE; + if (!(flags & CLF_TIME)) { + yydate.localSeconds = 0; + } + } + + if (flags & CLF_TIME) { + yySeconds = ToSeconds(yyHour, yyMinutes, + yySeconds, yyMeridian); + } else { + yySeconds = yydate.localSeconds % 86400; + } + + ret = TCL_OK; + +done: + + if (ret != TCL_OK) { + Tcl_SetResult(interp, + "input string does not match supplied format", TCL_STATIC); + Tcl_SetErrorCode(interp, "CLOCK", "badInputString", NULL); + return ret; + } - return TCL_ERROR; + return ret; } diff --git a/generic/tclDate.c b/generic/tclDate.c index a47f43d..97d13b4 100644 --- a/generic/tclDate.c +++ b/generic/tclDate.c @@ -2691,7 +2691,6 @@ TclClockFreeScan( yyHaveDate = 0; yyHaveTime = 0; - yyHour = 0; yyMinutes = 0; yySeconds = 0; yyMeridian = MER24; yyHaveZone = 0; yyTimezone = 0; yyDSTmode = DSTmaybe; diff --git a/generic/tclDate.h b/generic/tclDate.h index 49420a2..4b0b47e 100644 --- a/generic/tclDate.h +++ b/generic/tclDate.h @@ -22,60 +22,64 @@ typedef struct TclDateFields { * epoch */ Tcl_WideInt localSeconds; /* Local time expressed in nominal seconds * from the Posix epoch */ - int tzOffset; /* Time zone offset in seconds east of + time_t tzOffset; /* Time zone offset in seconds east of * Greenwich */ + time_t julianDay; /* Julian Day Number in local time zone */ + enum {BCE=1, CE=0} era; /* Era */ + time_t gregorian; /* Flag == 1 if the date is Gregorian */ + time_t year; /* Year of the era */ + time_t dayOfYear; /* Day of the year (1 January == 1) */ + time_t month; /* Month number */ + time_t dayOfMonth; /* Day of the month */ + time_t iso8601Year; /* ISO8601 week-based year */ + time_t iso8601Week; /* ISO8601 week number */ + time_t dayOfWeek; /* Day of the week */ + time_t hour; /* Hours of day (in-between time only calculation) */ + time_t minutes; /* Minutes of day (in-between time only calculation) */ + time_t secondOfDay; /* Seconds of day (in-between time only calculation) */ + Tcl_Obj *tzName; /* Time zone name (if set the refCount is incremented) */ Tcl_Obj *tzData; /* Time zone data object (internally referenced) */ - int julianDay; /* Julian Day Number in local time zone */ - enum {BCE=1, CE=0} era; /* Era */ - int gregorian; /* Flag == 1 if the date is Gregorian */ - int year; /* Year of the era */ - int dayOfYear; /* Day of the year (1 January == 1) */ - int month; /* Month number */ - int dayOfMonth; /* Day of the month */ - int iso8601Year; /* ISO8601 week-based year */ - int iso8601Week; /* ISO8601 week number */ - int dayOfWeek; /* Day of the week */ - int hour; /* Hours of day (in-between time only calculation) */ - int minutes; /* Minutes of day (in-between time only calculation) */ - int secondOfDay; /* Seconds of day (in-between time only calculation) */ } TclDateFields; +#define ClockCacheableDateFieldsSize \ + TclOffset(TclDateFields, tzName) + /* * Structure contains return parsed fields. */ typedef struct DateInfo { + const char *dateStart; + const char *dateInput; TclDateFields date; - int dateHaveDate; + time_t dateHaveDate; - int dateMeridian; - int dateHaveTime; + time_t dateMeridian; + time_t dateHaveTime; time_t dateTimezone; - int dateDSTmode; - int dateHaveZone; + time_t dateDSTmode; + time_t dateHaveZone; time_t dateRelMonth; time_t dateRelDay; time_t dateRelSeconds; - int dateHaveRel; + time_t dateHaveRel; time_t dateMonthOrdinalIncr; time_t dateMonthOrdinal; - int dateHaveOrdinalMonth; + time_t dateHaveOrdinalMonth; time_t dateDayOrdinal; time_t dateDayNumber; - int dateHaveDay; + time_t dateHaveDay; - const char *dateStart; - const char *dateInput; time_t *dateRelPointer; - int dateDigitCount; + time_t dateDigitCount; Tcl_Obj* messages; /* Error messages */ const char* separatrix; /* String separating messages */ @@ -140,8 +144,19 @@ typedef enum _MERIDIAN { #define CLOCK_MIN_TOK_CHAIN_BLOCK_SIZE 12 +typedef struct ClockScanToken ClockScanToken; + + +typedef int ClockScanTokenProc( + DateInfo *info, + ClockScanToken *tok); + + +#define CLF_DATE (1 << 2) +#define CLF_TIME (1 << 3) + typedef enum _CLCKTOK_TYPE { - CTOKT_EOB=0, CTOKT_DIGIT, CTOKT_SPACE + CTOKT_DIGIT = 1, CTOKT_SPACE, CTOKT_WORD } CLCKTOK_TYPE; typedef struct ClockFmtScnStorage ClockFmtScnStorage; @@ -150,18 +165,29 @@ typedef struct ClockFormatToken { CLCKTOK_TYPE type; } ClockFormatToken; -typedef struct ClockScanToken { +typedef struct ClockScanTokenMap { unsigned short int type; + unsigned short int flags; unsigned short int minSize; unsigned short int maxSize; unsigned short int offs; + ClockScanTokenProc *parser; +} ClockScanTokenMap; + +typedef struct ClockScanToken { + ClockScanTokenMap *map; + unsigned int lookAhead; + struct { + const char *start; + const char *end; + } tokWord; } ClockScanToken; typedef struct ClockFmtScnStorage { int objRefCount; /* Reference count shared across threads */ - ClockScanToken **scnTok; + ClockScanToken *scnTok; unsigned int scnTokC; - ClockFormatToken **fmtTok; + ClockFormatToken *fmtTok; unsigned int fmtTokC; #if CLOCK_FMT_SCN_STORAGE_GC_SIZE > 0 ClockFmtScnStorage *nextPtr; @@ -191,8 +217,8 @@ MODULE_SCOPE ClockFmtScnStorage * Tcl_Obj *objPtr); MODULE_SCOPE int ClockScan(ClientData clientData, Tcl_Interp *interp, - TclDateFields *date, Tcl_Obj *strObj, - ClockFmtScnCmdArgs *opts); + register DateInfo *info, + Tcl_Obj *strObj, ClockFmtScnCmdArgs *opts); /* * Other externals. diff --git a/generic/tclGetDate.y b/generic/tclGetDate.y index 571b7df..54087ca 100644 --- a/generic/tclGetDate.y +++ b/generic/tclGetDate.y @@ -902,7 +902,6 @@ TclClockFreeScan( yyHaveDate = 0; yyHaveTime = 0; - yyHour = 0; yyMinutes = 0; yySeconds = 0; yyMeridian = MER24; yyHaveZone = 0; yyTimezone = 0; yyDSTmode = DSTmaybe; diff --git a/tests-perf/clock.perf.tcl b/tests-perf/clock.perf.tcl index 969e279..93a78e4 100644 --- a/tests-perf/clock.perf.tcl +++ b/tests-perf/clock.perf.tcl @@ -25,19 +25,82 @@ proc _test_get_commands {lst} { regsub -all {(?:^|\n)[ \t]*(\#[^\n]*)(?=\n\s*[\{\#])} $lst "\n{\\1}" } +proc _test_out_total {} { + upvar _ _ + + puts [string repeat ** 40] + puts [format "Total %d cases in %.2f sec.:" [llength $_(itcnt)] [expr {[llength $_(itcnt)] * $_(reptime) / 1000.0}]] + lset _(m) 0 [format %.6f [expr [join $_(ittm) +]]] + lset _(m) 2 [expr [join $_(itcnt) +]] + lset _(m) 4 [expr {[lindex $_(m) 2] / ([llength $_(itcnt)] * $_(reptime) / 1000.0)}] + puts $_(m) + puts "Average:" + lset _(m) 0 [format %.6f [expr {[lindex $_(m) 0] / [llength $_(itcnt)]}]] + lset _(m) 2 [expr {[lindex $_(m) 2] / [llength $_(itcnt)]}] + lset _(m) 4 [expr {[lindex $_(m) 2] * (1000 / $_(reptime))}] + puts $_(m) + puts [string repeat ** 40] + puts "" +} + +proc _test_run {reptime lst {outcmd {puts {$_(r)}}}} { + upvar _ _ + array set _ [list ittm {} itcnt {} itrate {} reptime $reptime] + + foreach _(c) [_test_get_commands $lst] { + puts "% [regsub -all {\n[ \t]*} $_(c) {; }]" + if {[regexp {\s*\#} $_(c)]} continue + set _(r) [if 1 $_(c)] + if {$outcmd ne {}} $outcmd + puts [set _(m) [timerate $_(c) $reptime]] + lappend _(ittm) [lindex $_(m) 0] + lappend _(itcnt) [lindex $_(m) 2] + lappend _(itrate) [lindex $_(m) 4] + puts "" + } + _test_out_total +} + proc test-scan {{reptime 1000}} { - foreach _(c) [_test_get_commands { - # Scan : date + _test_run $reptime { + # Scan : date (in gmt) {clock scan "25.11.2015" -format "%d.%m.%Y" -base 0 -gmt 1} + # Scan : date (system time zone, with base) + {clock scan "25.11.2015" -format "%d.%m.%Y" -base 0} + # Scan : date (system time zone, without base) + {clock scan "25.11.2015" -format "%d.%m.%Y"} + # Scan : greedy match + {clock scan "111" -format "%d%m%y" -base 0 -gmt 1} {clock scan "1111" -format "%d%m%y" -base 0 -gmt 1} - {**STOP** : Wed Nov 25 01:00:00 CET 2015} - # Scan : long format test (allock chain) - {clock scan "25.11.2015" -format "%d.%m.%Y %d.%m.%Y %d.%m.%Y %d.%m.%Y %d.%m.%Y %d.%m.%Y %d.%m.%Y %d.%m.%Y" -base 0 -gmt 1} - # Scan : dynamic, very long format test (create obj representation, allock chain, GC, etc): - {clock scan "25.11.2015" -format [string repeat "[incr i] %d.%m.%Y %d.%m.%Y" 10] -base 0 -gmt 1} - # Scan : again: - {clock scan "25.11.2015" -format [string repeat "[incr i -1] %d.%m.%Y %d.%m.%Y" 10] -base 0 -gmt 1} + {clock scan "11111" -format "%d%m%y" -base 0 -gmt 1} + {clock scan "111111" -format "%d%m%y" -base 0 -gmt 1} + + # Scan : date-time (in gmt) + {clock scan "25.11.2015 10:35:55" -format "%d.%m.%Y %H:%M:%S" -base 0 -gmt 1} + # Scan : date-time (system time zone with base) + {clock scan "25.11.2015 10:35:55" -format "%d.%m.%Y %H:%M:%S" -base 0} + # Scan : date-time (system time zone without base) + {clock scan "25.11.2015 10:35:55" -format "%d.%m.%Y %H:%M:%S"} + # Scan : dynamic format (cacheable) + {clock scan "25.11.2015 10:35:55" -format [string trim "%d.%m.%Y %H:%M:%S "] -base 0 -gmt 1} + + # Scan : zone only + {clock scan "CET" -format "%z"} + {clock scan "EST" -format "%z"} + #{**STOP** : Wed Nov 25 01:00:00 CET 2015} + + # # Scan : long format test (allock chain) + # {clock scan "25.11.2015" -format "%d.%m.%Y %d.%m.%Y %d.%m.%Y %d.%m.%Y %d.%m.%Y %d.%m.%Y %d.%m.%Y %d.%m.%Y" -base 0 -gmt 1} + # # Scan : dynamic, very long format test (create obj representation, allock chain, GC, etc): + # {clock scan "25.11.2015" -format [string repeat "[incr i] %d.%m.%Y %d.%m.%Y" 10] -base 0 -gmt 1} + # # Scan : again: + # {clock scan "25.11.2015" -format [string repeat "[incr i -1] %d.%m.%Y %d.%m.%Y" 10] -base 0 -gmt 1} + } {puts [clock format $_(r) -locale en]} +} + +proc test-freescan {{reptime 1000}} { + _test_run $reptime { # FreeScan : relative date {clock scan "5 years 18 months 385 days" -base 0 -gmt 1} # FreeScan : relative date with relative weekday @@ -74,17 +137,11 @@ proc test-scan {{reptime 1000}} { {clock scan "19:18:30 MST" -base 148863600 -gmt 1 clock scan "19:18:30 EST" -base 148863600 } - }] { - puts "% [regsub -all {\n[ \t]*} $_(c) {; }]" - if {[regexp {\s*\#} $_(c)]} continue - puts [clock format [if 1 $_(c)] -locale en] - puts [timerate $_(c) $reptime] - puts "" - } + } {puts [clock format $_(r) -locale en]} } proc test-other {{reptime 1000}} { - foreach _(c) [_test_get_commands { + _test_run $reptime { # Bad zone {catch {clock scan "1 day" -timezone BAD_ZONE -locale en}} **STOP** @@ -92,18 +149,13 @@ proc test-other {{reptime 1000}} { {set i 0; time { clock scan "[incr i] - 25.11.2015" -format "$i - %d.%m.%Y" -base 0 -gmt 1 } 50} # Scan : test reusability of GC objects (format is dynamic, so tcl-obj removed with last reference) {set i 50; time { clock scan "[incr i -1] - 25.11.2015" -format "$i - %d.%m.%Y" -base 0 -gmt 1 } 50} - }] { - puts "% [regsub -all {\n[ \t]*} $_(c) {; }]" - if {[regexp {\s*\#} $_(c)]} continue - puts [if 1 $_(c)] - puts [timerate $_(c) $reptime] - puts "" } } proc test {{reptime 1000}} { puts "" test-scan $reptime + #test-freescan $reptime test-other $reptime puts \n**OK** -- cgit v0.12 From 940c0805c073986447f70bc21a1db6e576911548 Mon Sep 17 00:00:00 2001 From: sebres Date: Tue, 10 Jan 2017 22:19:01 +0000 Subject: [temp-commit]: code review, DST-hole mistake by scan with relative time resolved; caching of UTC2Local / Local2UTC cherry picked --- generic/tclClock.c | 394 ++++++++++++++++++++++++++++------------------ generic/tclClockFmt.c | 220 +++++++++++++++++++++----- generic/tclDate.h | 84 +++++++++- library/clock.tcl | 13 +- tests-perf/clock.perf.tcl | 50 +++++- tests/clock.test | 87 ++++++++++ 6 files changed, 638 insertions(+), 210 deletions(-) diff --git a/generic/tclClock.c b/generic/tclClock.c index 2e7b854..7cc5d86 100644 --- a/generic/tclClock.c +++ b/generic/tclClock.c @@ -26,22 +26,6 @@ #endif /* - * Constants - */ - -#define JULIAN_DAY_POSIX_EPOCH 2440588 -#define GREGORIAN_CHANGE_DATE 2361222 -#define SECONDS_PER_DAY 86400 -#define JULIAN_SEC_POSIX_EPOCH (((Tcl_WideInt) JULIAN_DAY_POSIX_EPOCH) \ - * SECONDS_PER_DAY) -#define FOUR_CENTURIES 146097 /* days */ -#define JDAY_1_JAN_1_CE_JULIAN 1721424 -#define JDAY_1_JAN_1_CE_GREGORIAN 1721426 -#define ONE_CENTURY_GREGORIAN 36524 /* days */ -#define FOUR_YEARS 1461 /* days */ -#define ONE_YEAR 365 /* days */ - -/* * Table of the days in each month, leap and common years */ @@ -72,8 +56,6 @@ typedef enum ClockLiteral { LIT_MONTH, LIT_SECONDS, LIT_TZNAME, LIT_TZOFFSET, LIT_YEAR, - LIT_CURRENTYEARCENTURY, - LIT_YEAROFCENTURYSWITCH, LIT_TZDATA, LIT_GETSYSTEMTIMEZONE, LIT_SETUPTIMEZONE, @@ -96,8 +78,6 @@ static const char *const Literals[] = { "month", "seconds", "tzName", "tzOffset", "year", - "::tcl::clock::CurrentYearCentury", - "::tcl::clock::YearOfCenturySwitch", "::tcl::clock::TZData", "::tcl::clock::GetSystemTimeZone", "::tcl::clock::SetupTimeZone", @@ -106,41 +86,6 @@ static const char *const Literals[] = { #endif }; -#define CurrentYearCentury 2000 - -/* - * Structure containing the client data for [clock] - */ - -typedef struct ClockClientData { - size_t refCount; /* Number of live references. */ - Tcl_Obj **literals; /* Pool of object literals. */ - /* Cache for current clock parameters, imparted via "configure" */ - unsigned long LastTZEpoch; - int currentYearCentury; - int yearOfCenturySwitch; - Tcl_Obj *SystemTimeZone; - Tcl_Obj *SystemSetupTZData; - Tcl_Obj *GMTSetupTimeZone; - Tcl_Obj *GMTSetupTZData; - Tcl_Obj *AnySetupTimeZone; - Tcl_Obj *AnySetupTZData; - Tcl_Obj *LastUnnormSetupTimeZone; - Tcl_Obj *LastSetupTimeZone; - Tcl_Obj *LastSetupTZData; - /* Cache for last base (fast convert if base/tz not changed) */ - Tcl_Obj *lastBaseTimeZone; - TclDateFields lastBaseDate; - /* - /* [SB] TODO: back-port (from tclSE) the same date caching ... - * Cache for last date (fast convert if date parsed was the same) * / - struct { - DateInfo yy; - TclDateFields date; - } lastDate; - */ -} ClockClientData; - static const char *const eras[] = { "CE", "BCE", NULL }; /* @@ -161,13 +106,13 @@ TCL_DECLARE_MUTEX(clockMutex) * Function prototypes for local procedures in this file: */ -static int ConvertUTCToLocal(Tcl_Interp *, +static int ConvertUTCToLocal(ClientData clientData, Tcl_Interp *, TclDateFields *, Tcl_Obj *, int); static int ConvertUTCToLocalUsingTable(Tcl_Interp *, TclDateFields *, int, Tcl_Obj *const[]); static int ConvertUTCToLocalUsingC(Tcl_Interp *, TclDateFields *, int); -static int ConvertLocalToUTC(Tcl_Interp *, +static int ConvertLocalToUTC(ClientData clientData, Tcl_Interp *, TclDateFields *, Tcl_Obj *, int); static int ConvertLocalToUTCUsingTable(Tcl_Interp *, TclDateFields *, int, Tcl_Obj *const[]); @@ -191,9 +136,9 @@ static int ClockConvertlocaltoutcObjCmd( ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *const objv[]); -static int ClockGetDateFields(Tcl_Interp *interp, - TclDateFields *fields, Tcl_Obj *tzdata, - int changeover); +static int ClockGetDateFields(ClientData clientData, + Tcl_Interp *interp, TclDateFields *fields, + Tcl_Obj *tzdata, int changeover); static int ClockGetdatefieldsObjCmd( ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *const objv[]); @@ -330,8 +275,8 @@ TclClockInit( Tcl_IncrRefCount(data->literals[i]); } data->LastTZEpoch = 0; - data->currentYearCentury = -1; - data->yearOfCenturySwitch = -1; + data->currentYearCentury = ClockDefaultYearCentury; + data->yearOfCenturySwitch = ClockDefaultCenturySwitch; data->SystemTimeZone = NULL; data->SystemSetupTZData = NULL; data->GMTSetupTimeZone = NULL; @@ -342,7 +287,10 @@ TclClockInit( data->LastSetupTimeZone = NULL; data->LastSetupTZData = NULL; - data->lastBaseTimeZone = NULL; + data->lastBase.TimeZone = NULL; + data->UTC2Local.tzData = NULL; + data->UTC2Local.tzName = NULL; + data->Local2UTC.tzData = NULL; /* * Install the commands. @@ -377,8 +325,6 @@ ClockConfigureClear( ClockClientData *data) { data->LastTZEpoch = 0; - data->currentYearCentury = -1; - data->yearOfCenturySwitch = -1; Tcl_UnsetObjRef(data->SystemTimeZone); Tcl_UnsetObjRef(data->SystemSetupTZData); Tcl_UnsetObjRef(data->GMTSetupTimeZone); @@ -388,6 +334,11 @@ ClockConfigureClear( Tcl_UnsetObjRef(data->LastUnnormSetupTimeZone); Tcl_UnsetObjRef(data->LastSetupTimeZone); Tcl_UnsetObjRef(data->LastSetupTZData); + + Tcl_UnsetObjRef(data->lastBase.TimeZone); + Tcl_UnsetObjRef(data->UTC2Local.tzData); + Tcl_UnsetObjRef(data->UTC2Local.tzName); + Tcl_UnsetObjRef(data->Local2UTC.tzData); } static void @@ -397,7 +348,8 @@ ClockDeleteCmdProc( ClockClientData *data = clientData; int i; - if (data->refCount-- <= 1) { + data->refCount--; + if (data->refCount == 0) { for (i = 0; i < LIT__END; ++i) { Tcl_DecrRefCount(data->literals[i]); } @@ -471,10 +423,12 @@ ClockConfigureObjCmd( static const char *const options[] = { "-system-tz", "-setup-tz", "-clear", + "-year-century", "-century-switch", NULL }; enum optionInd { CLOCK_SYSTEM_TZ, CLOCK_SETUP_TZ, CLOCK_CLEAR_CACHE, + CLOCK_YEAR_CENTURY, CLOCK_CENTURY_SWITCH, CLOCK_SETUP_GMT, CLOCK_SETUP_NOP }; int optionIndex; /* Index of an option. */ @@ -542,6 +496,32 @@ ClockConfigureObjCmd( Tcl_SetObjResult(interp, dataPtr->LastSetupTimeZone); } break; + case CLOCK_YEAR_CENTURY: + if (i+1 < objc) { + int year; + if (TclGetIntFromObj(interp, objv[i+1], &year) != TCL_OK) { + return TCL_ERROR; + } + dataPtr->currentYearCentury = year; + Tcl_SetObjResult(interp, objv[i+1]); + continue; + } + Tcl_SetObjResult(interp, + Tcl_NewIntObj(dataPtr->currentYearCentury)); + break; + case CLOCK_CENTURY_SWITCH: + if (i+1 < objc) { + int year; + if (TclGetIntFromObj(interp, objv[i+1], &year) != TCL_OK) { + return TCL_ERROR; + } + dataPtr->yearOfCenturySwitch = year; + Tcl_SetObjResult(interp, objv[i+1]); + continue; + } + Tcl_SetObjResult(interp, + Tcl_NewIntObj(dataPtr->yearOfCenturySwitch)); + break; case CLOCK_CLEAR_CACHE: ClockConfigureClear(dataPtr); break; @@ -577,14 +557,16 @@ ClockGetTZData( /* simple caching, because almost used the tz-data of last timezone */ if (timezoneObj == dataPtr->SystemTimeZone) { - if (dataPtr->SystemSetupTZData != NULL) + if (dataPtr->SystemSetupTZData != NULL) { return dataPtr->SystemSetupTZData; + } out = &dataPtr->SystemSetupTZData; } else if (timezoneObj == dataPtr->GMTSetupTimeZone) { - if (dataPtr->GMTSetupTZData != NULL) + if (dataPtr->GMTSetupTZData != NULL) { return dataPtr->GMTSetupTZData; + } out = &dataPtr->GMTSetupTZData; } else @@ -602,11 +584,11 @@ ClockGetTZData( if (out != NULL) { Tcl_SetObjRef(*out, ret); } - Tcl_SetObjRef(dataPtr->LastSetupTZData, ret); + Tcl_SetObjRef(dataPtr->LastSetupTZData, ret); if (dataPtr->LastSetupTimeZone != timezoneObj) { Tcl_SetObjRef(dataPtr->LastSetupTimeZone, timezoneObj); Tcl_UnsetObjRef(dataPtr->LastUnnormSetupTimeZone); - } + } return ret; } /* @@ -710,49 +692,6 @@ ClockFormatNumericTimeZone(int z) { /* *---------------------------------------------------------------------- - * [SB] TODO: make constans cacheable (once per second, etc.) ... - */ -inline int -ClockCurrentYearCentury( - ClientData clientData, /* Opaque pointer to literal pool, etc. */ - Tcl_Interp *interp) /* Tcl interpreter */ -{ - ClockClientData *dataPtr = clientData; - Tcl_Obj **literals = dataPtr->literals; - int year = dataPtr->currentYearCentury; - - if (year == -1) { - Tcl_Obj * yearObj; - year = 2000; - yearObj = Tcl_ObjGetVar2(interp, - literals[LIT_CURRENTYEARCENTURY], NULL, TCL_LEAVE_ERR_MSG); - Tcl_GetIntFromObj(NULL, yearObj, &year); - dataPtr->currentYearCentury = year; - } - return year; -} -inline int -ClockGetYearOfCenturySwitch( - ClientData clientData, /* Opaque pointer to literal pool, etc. */ - Tcl_Interp *interp) /* Tcl interpreter */ -{ - ClockClientData *dataPtr = clientData; - Tcl_Obj **literals = dataPtr->literals; - int year = dataPtr->yearOfCenturySwitch; - - if (year == -1) { - Tcl_Obj * yearObj; - year = 37; - yearObj = Tcl_ObjGetVar2(interp, - literals[LIT_YEAROFCENTURYSWITCH], NULL, TCL_LEAVE_ERR_MSG); - Tcl_GetIntFromObj(NULL, yearObj, &year); - dataPtr->yearOfCenturySwitch = year; - } - return year; -} - -/* - *---------------------------------------------------------------------- * * ClockConvertlocaltoutcObjCmd -- * @@ -816,7 +755,7 @@ ClockConvertlocaltoutcObjCmd( if ((Tcl_GetWideIntFromObj(interp, secondsObj, &fields.localSeconds) != TCL_OK) || (TclGetIntFromObj(interp, objv[3], &changeover) != TCL_OK) - || ConvertLocalToUTC(interp, &fields, objv[2], changeover)) { + || ConvertLocalToUTC(clientData, interp, &fields, objv[2], changeover)) { return TCL_ERROR; } @@ -911,8 +850,8 @@ ClockGetdatefieldsObjCmd( /* Extract fields */ - if (ClockGetDateFields(interp, &fields, objv[2], changeover) - != TCL_OK) { + if (ClockGetDateFields(clientData, interp, &fields, objv[2], + changeover) != TCL_OK) { return TCL_ERROR; } @@ -957,6 +896,7 @@ ClockGetdatefieldsObjCmd( */ int ClockGetDateFields( + ClientData clientData, /* Client data of the interpreter */ Tcl_Interp *interp, /* Tcl interpreter */ TclDateFields *fields, /* Pointer to result fields, where * fields->seconds contains date to extract */ @@ -967,7 +907,8 @@ ClockGetDateFields( * Convert UTC time to local. */ - if (ConvertUTCToLocal(interp, fields, tzdata, changeover) != TCL_OK) { + if (ConvertUTCToLocal(clientData, interp, fields, tzdata, + changeover) != TCL_OK) { return TCL_ERROR; } @@ -1221,15 +1162,33 @@ ClockGetjuliandayfromerayearweekdayObjCmd( static int ConvertLocalToUTC( + ClientData clientData, /* Client data of the interpreter */ Tcl_Interp *interp, /* Tcl interpreter */ TclDateFields *fields, /* Fields of the time */ Tcl_Obj *tzdata, /* Time zone data */ int changeover) /* Julian Day of the Gregorian transition */ { + ClockClientData *dataPtr = clientData; int rowc; /* Number of rows in tzdata */ Tcl_Obj **rowv; /* Pointers to the rows */ /* + * Check cacheable conversion could be used + * (last-minute Local2UTC cache with the same TZ) + */ + if ( tzdata == dataPtr->Local2UTC.tzData + && ( fields->localSeconds == dataPtr->Local2UTC.localSeconds + || fields->localSeconds / 60 == dataPtr->Local2UTC.localSeconds / 60 + ) + && changeover == dataPtr->Local2UTC.changeover + ) { + /* the same time zone and offset (UTC time inside the last minute) */ + fields->tzOffset = dataPtr->Local2UTC.tzOffset; + fields->seconds = fields->localSeconds - fields->tzOffset; + return TCL_OK; + } + + /* * Unpack the tz data. */ @@ -1243,10 +1202,22 @@ ConvertLocalToUTC( */ if (rowc == 0) { - return ConvertLocalToUTCUsingC(interp, fields, changeover); + if (ConvertLocalToUTCUsingC(interp, fields, changeover) != TCL_OK) { + return TCL_ERROR; + }; } else { - return ConvertLocalToUTCUsingTable(interp, fields, rowc, rowv); + if (ConvertLocalToUTCUsingTable(interp, fields, rowc, rowv) != TCL_OK) { + return TCL_ERROR; + }; } + + /* Cache the last conversion */ + Tcl_SetObjRef(dataPtr->Local2UTC.tzData, tzdata); + dataPtr->Local2UTC.localSeconds = fields->localSeconds; + dataPtr->Local2UTC.changeover = changeover; + dataPtr->Local2UTC.tzOffset = fields->tzOffset; + + return TCL_OK; } /* @@ -1321,6 +1292,40 @@ ConvertLocalToUTCUsingTable( } fields->tzOffset = have[i]; fields->seconds = fields->localSeconds - fields->tzOffset; + +#if 0 + /* + * Convert back from UTC, if local times are different - wrong local time + * (local time seems to be in between DST-hole). + */ + if (fields->tzOffset) { + + int corrOffset; + Tcl_WideInt backCompVal; + /* check DST-hole interval contains UTC time */ + Tcl_GetWideIntFromObj(NULL, cellv[0], &backCompVal); + if ( fields->seconds >= backCompVal - fields->tzOffset + && fields->seconds <= backCompVal + fields->tzOffset + ) { + row = LookupLastTransition(interp, fields->seconds, rowc, rowv); + if (row == NULL || + TclListObjGetElements(interp, row, &cellc, &cellv) != TCL_OK || + TclGetIntFromObj(interp, cellv[1], &corrOffset) != TCL_OK) { + return TCL_ERROR; + } + if (fields->localSeconds != fields->seconds + corrOffset) { + Tcl_Panic("wrong local time %ld by LocalToUTC conversion," + " local time seems to be in between DST-hole", + fields->localSeconds); + /* correcting offset * / + fields->tzOffset -= corrOffset; + fields->seconds += fields->tzOffset; + */ + } + } + } +#endif + return TCL_OK; } @@ -1424,15 +1429,34 @@ ConvertLocalToUTCUsingC( static int ConvertUTCToLocal( + ClientData clientData, /* Client data of the interpreter */ Tcl_Interp *interp, /* Tcl interpreter */ TclDateFields *fields, /* Fields of the time */ Tcl_Obj *tzdata, /* Time zone data */ int changeover) /* Julian Day of the Gregorian transition */ { + ClockClientData *dataPtr = clientData; int rowc; /* Number of rows in tzdata */ Tcl_Obj **rowv; /* Pointers to the rows */ /* + * Check cacheable conversion could be used + * (last-minute UTC2Local cache with the same TZ) + */ + if ( tzdata == dataPtr->UTC2Local.tzData + && ( fields->seconds == dataPtr->UTC2Local.seconds + || fields->seconds / 60 == dataPtr->UTC2Local.seconds / 60 + ) + && changeover == dataPtr->UTC2Local.changeover + ) { + /* the same time zone and offset (UTC time inside the last minute) */ + Tcl_SetObjRef(fields->tzName, dataPtr->UTC2Local.tzName); + fields->tzOffset = dataPtr->UTC2Local.tzOffset; + fields->localSeconds = fields->seconds + fields->tzOffset; + return TCL_OK; + } + + /* * Unpack the tz data. */ @@ -1446,10 +1470,22 @@ ConvertUTCToLocal( */ if (rowc == 0) { - return ConvertUTCToLocalUsingC(interp, fields, changeover); + if (ConvertUTCToLocalUsingC(interp, fields, changeover) != TCL_OK) { + return TCL_ERROR; + } } else { - return ConvertUTCToLocalUsingTable(interp, fields, rowc, rowv); + if (ConvertUTCToLocalUsingTable(interp, fields, rowc, rowv) != TCL_OK) { + return TCL_ERROR; + } } + + /* Cache the last conversion */ + Tcl_SetObjRef(dataPtr->UTC2Local.tzData, tzdata); + dataPtr->UTC2Local.seconds = fields->seconds; + dataPtr->UTC2Local.changeover = changeover; + dataPtr->UTC2Local.tzOffset = fields->tzOffset; + Tcl_SetObjRef(dataPtr->UTC2Local.tzName, fields->tzName); + return TCL_OK; } /* @@ -2373,6 +2409,7 @@ _ClockParseFmtScnArgs( resOpts->localeObj = NULL; resOpts->timezoneObj = NULL; resOpts->baseObj = NULL; + resOpts->flags = 0; for (i = 2; i < objc; i+=2) { if (Tcl_GetIndexFromObj(interp, objv[i], options[forScan], "option", 0, &optionIndex) != TCL_OK) { @@ -2539,6 +2576,8 @@ ClockScanObjCmd( ret = TCL_ERROR; + info->flags = 0; + if (opts.baseObj != NULL) { if (Tcl_GetWideIntFromObj(interp, opts.baseObj, &baseVal) != TCL_OK) { return TCL_ERROR; @@ -2580,20 +2619,20 @@ ClockScanObjCmd( } Tcl_SetObjRef(yydate.tzName, opts.timezoneObj); - /* check cached */ - if ( dataPtr->lastBaseTimeZone == opts.timezoneObj - && dataPtr->lastBaseDate.seconds == baseVal) { - memcpy(&yydate, &dataPtr->lastBaseDate, ClockCacheableDateFieldsSize); + /* check base fields already cached (by TZ, last-second cache) */ + if ( dataPtr->lastBase.TimeZone == opts.timezoneObj + && dataPtr->lastBase.Date.seconds == baseVal) { + memcpy(&yydate, &dataPtr->lastBase.Date, ClockCacheableDateFieldsSize); } else { /* extact fields from base */ yydate.seconds = baseVal; - if (ClockGetDateFields(interp, &yydate, yydate.tzData, GREGORIAN_CHANGE_DATE) - != TCL_OK) { + if (ClockGetDateFields(clientData, interp, &yydate, yydate.tzData, + GREGORIAN_CHANGE_DATE) != TCL_OK) { goto done; } /* cache last base */ - memcpy(&dataPtr->lastBaseDate, &yydate, ClockCacheableDateFieldsSize); - dataPtr->lastBaseTimeZone = opts.timezoneObj; + memcpy(&dataPtr->lastBase.Date, &yydate, ClockCacheableDateFieldsSize); + Tcl_SetObjRef(dataPtr->lastBase.TimeZone, opts.timezoneObj); } /* seconds are in localSeconds (relative base date), so reset time here */ @@ -2612,7 +2651,7 @@ ClockScanObjCmd( } ret = ClockFreeScan(clientData, interp, info, objv[1], &opts); } -#if 0 +#if 1 else if (1) { /* TODO: Tcled Scan proc - */ @@ -2636,24 +2675,40 @@ ClockScanObjCmd( goto done; } - /* If needed assemble julianDay using new year, month, etc. */ - if (yydate.julianDay == CL_INVALIDATE) { + if (info->flags & CLF_INVALIDATE_JULIANDAY) { GetJulianDayFromEraYearMonthDay(&yydate, GREGORIAN_CHANGE_DATE); } - + + /* some overflow checks, if not extended */ + if (!(opts.flags & CLF_EXTENDED)) { + if (yydate.julianDay > 5373484) { + Tcl_SetObjResult(interp, Tcl_NewStringObj( + "requested date too large to represent", -1)); + Tcl_SetErrorCode(interp, "CLOCK", "dateTooLarge", NULL); + ret = TCL_ERROR; + goto done; + } + } + /* Local seconds to UTC (stored in yydate.seconds) */ - yydate.localSeconds = - -210866803200L - + ( 86400 * (Tcl_WideInt)yydate.julianDay ) - + ( yySeconds % 86400 ); + if (info->flags & (CLF_INVALIDATE_SECONDS|CLF_INVALIDATE_JULIANDAY)) { + yydate.localSeconds = + -210866803200L + + ( SECONDS_PER_DAY * (Tcl_WideInt)yydate.julianDay ) + + ( yySeconds % SECONDS_PER_DAY ); + } - if (ConvertLocalToUTC(interp, &yydate, yydate.tzData, GREGORIAN_CHANGE_DATE) + if (ConvertLocalToUTC(clientData, interp, &yydate, yydate.tzData, GREGORIAN_CHANGE_DATE) != TCL_OK) { goto done; } + /* Increment UTC seconds with relative time */ + + yydate.seconds += yyRelSeconds; + ret = TCL_OK; done: @@ -2681,7 +2736,7 @@ ClockFreeScan( Tcl_Obj *strObj, /* String containing the time to scan */ ClockFmtScnCmdArgs *opts) /* Command options */ { - // ClockClientData *dataPtr = clientData; + ClockClientData *dataPtr = clientData; // Tcl_Obj **literals = dataPtr->literals; int ret = TCL_ERROR; @@ -2712,15 +2767,16 @@ ClockFreeScan( if (yyHaveDate) { if (yyYear < 100) { - if (yyYear >= ClockGetYearOfCenturySwitch(clientData, interp)) { + if (yyYear >= dataPtr->yearOfCenturySwitch) { yyYear -= 100; } - yyYear += ClockCurrentYearCentury(clientData, interp); + yyYear += dataPtr->currentYearCentury; } yydate.era = CE; if (yyHaveTime == 0) { yyHaveTime = -1; } + info->flags |= CLF_INVALIDATE_JULIANDAY|CLF_INVALIDATE_SECONDS; } /* @@ -2749,22 +2805,22 @@ ClockFreeScan( Tcl_SetObjRef(yydate.tzName, opts->timezoneObj); + info->flags |= CLF_INVALIDATE_SECONDS; } - /* on demand (lazy) assemble julianDay using new year, month, etc. */ - yydate.julianDay = CL_INVALIDATE; - /* * Assemble date, time, zone into seconds-from-epoch */ if (yyHaveTime == -1) { yySeconds = 0; + info->flags |= CLF_INVALIDATE_SECONDS; } else if (yyHaveTime) { yySeconds = ToSeconds(yyHour, yyMinutes, yySeconds, yyMeridian); + info->flags |= CLF_INVALIDATE_SECONDS; } else if ( (yyHaveDay && !yyHaveDate) @@ -2774,9 +2830,10 @@ ClockFreeScan( || yyRelDay != 0 ) ) ) { yySeconds = 0; + info->flags |= CLF_INVALIDATE_SECONDS; } else { - yySeconds = yydate.localSeconds % 86400; + yySeconds = yydate.localSeconds % SECONDS_PER_DAY; } /* @@ -2787,16 +2844,24 @@ repeat_rel: if (yyHaveRel) { + /* + * Relative conversion normally possible in UTC time only, because + * of possible wrong local time increment if ignores in-between DST-hole. + * (see test-cases clock-34.53, clock-34.54). + * So increment date in julianDay, but time inside day in UTC (seconds). + */ + /* add months (or years in months) */ if (yyRelMonth != 0) { int m, h; /* if needed extract year, month, etc. again */ - if (yyMonth == CL_INVALIDATE) { + if (info->flags & CLF_INVALIDATE_DATE) { GetGregorianEraYearDay(&yydate, GREGORIAN_CHANGE_DATE); GetMonthDay(&yydate); GetYearWeekDay(&yydate, GREGORIAN_CHANGE_DATE); + info->flags &= ~CLF_INVALIDATE_DATE; } /* add the requisite number of months */ @@ -2812,7 +2877,7 @@ repeat_rel: } /* on demand (lazy) assemble julianDay using new year, month, etc. */ - yydate.julianDay = CL_INVALIDATE; + info->flags |= CLF_INVALIDATE_JULIANDAY|CLF_INVALIDATE_SECONDS; yyRelMonth = 0; } @@ -2821,21 +2886,33 @@ repeat_rel: if (yyRelDay) { /* assemble julianDay using new year, month, etc. */ - if (yydate.julianDay == CL_INVALIDATE) { + if (info->flags & CLF_INVALIDATE_JULIANDAY) { GetJulianDayFromEraYearMonthDay(&yydate, GREGORIAN_CHANGE_DATE); + info->flags &= ~CLF_INVALIDATE_JULIANDAY; } - yydate.julianDay += yyRelDay; + yydate.julianDay += yyRelDay; /* julianDay was changed, on demand (lazy) extract year, month, etc. again */ - yyMonth = CL_INVALIDATE; + info->flags |= CLF_INVALIDATE_DATE|CLF_INVALIDATE_SECONDS; yyRelDay = 0; } - /* relative time (seconds) */ - yySeconds += yyRelSeconds; - yyRelSeconds = 0; - + /* relative time (seconds), if exceeds current date, do the day conversion and + * leave rest of the increment in yyRelSeconds to add it hereafter in UTC seconds */ + if (yyRelSeconds) { + time_t newSecs = yySeconds + yyRelSeconds; + + /* if seconds increment outside of current date, increment day */ + if (newSecs / SECONDS_PER_DAY != yySeconds / SECONDS_PER_DAY) { + + yyRelDay += newSecs / SECONDS_PER_DAY; + yySeconds = 0; + yyRelSeconds = newSecs % SECONDS_PER_DAY; + + goto repeat_rel; + } + } } /* @@ -2846,10 +2923,11 @@ repeat_rel: int monthDiff; /* if needed extract year, month, etc. again */ - if (yyMonth == CL_INVALIDATE) { + if (info->flags & CLF_INVALIDATE_DATE) { GetGregorianEraYearDay(&yydate, GREGORIAN_CHANGE_DATE); GetMonthDay(&yydate); GetYearWeekDay(&yydate, GREGORIAN_CHANGE_DATE); + info->flags &= ~CLF_INVALIDATE_DATE; } if (yyMonthOrdinalIncr > 0) { @@ -2872,6 +2950,8 @@ repeat_rel: yyRelMonth += monthDiff; yyHaveOrdinalMonth = 0; + info->flags |= CLF_INVALIDATE_JULIANDAY|CLF_INVALIDATE_SECONDS; + goto repeat_rel; } @@ -2882,8 +2962,9 @@ repeat_rel: if (yyHaveDay && !yyHaveDate) { /* if needed assemble julianDay now */ - if (yydate.julianDay == CL_INVALIDATE) { + if (info->flags & CLF_INVALIDATE_JULIANDAY) { GetJulianDayFromEraYearMonthDay(&yydate, GREGORIAN_CHANGE_DATE); + info->flags &= ~CLF_INVALIDATE_JULIANDAY; } yydate.era = CE; @@ -2892,6 +2973,7 @@ repeat_rel: if (yyDayOrdinal > 0) { yydate.julianDay -= 7; } + info->flags |= CLF_INVALIDATE_DATE|CLF_INVALIDATE_SECONDS; } /* Free scanning completed - date ready */ diff --git a/generic/tclClockFmt.c b/generic/tclClockFmt.c index b074681..48b9b69 100644 --- a/generic/tclClockFmt.c +++ b/generic/tclClockFmt.c @@ -35,6 +35,66 @@ static void ClockFmtScnStorageDelete(ClockFmtScnStorage *fss); * Clock scan and format facilities. */ +inline int +_str2int( + time_t *out, + register + const char *p, + const char *e, + int sign) +{ + register time_t val = 0, prev = 0; + if (sign > 0) { + while (p < e) { + val = val * 10 + (*p++ - '0'); + if (val < prev) { + return TCL_ERROR; + } + prev = val; + } + } else { + while (p < e) { + val = val * 10 - (*p++ - '0'); + if (val > prev) { + return TCL_ERROR; + } + prev = val; + } + } + *out = val; + return TCL_OK; +} + +inline int +_str2wideInt( + Tcl_WideInt *out, + register + const char *p, + const char *e, + int sign) +{ + register Tcl_WideInt val = 0, prev = 0; + if (sign > 0) { + while (p < e) { + val = val * 10 + (*p++ - '0'); + if (val < prev) { + return TCL_ERROR; + } + prev = val; + } + } else { + while (p < e) { + val = val * 10 - (*p++ - '0'); + if (val > prev) { + return TCL_ERROR; + } + prev = val; + } + } + *out = val; + return TCL_OK; +} + /* *---------------------------------------------------------------------- */ @@ -403,22 +463,35 @@ Tcl_GetClockFrmScnFromObj( memset(tok, 0, sizeof(*(tok))); const char *ScnSTokenMapChars = - "dmyYHMS"; + "dmyYHMSJs"; static ClockScanTokenMap ScnSTokenMap[] = { - {CTOKT_DIGIT, CLF_DATE, 1, 2, TclOffset(DateInfo, date.dayOfMonth), + /* %d */ + {CTOKT_DIGIT, CLF_DATE, 1, 2, TclOffset(DateInfo, date.dayOfMonth), NULL}, + /* %m */ {CTOKT_DIGIT, CLF_DATE, 1, 2, TclOffset(DateInfo, date.month), NULL}, + /* %y */ {CTOKT_DIGIT, CLF_DATE, 1, 2, TclOffset(DateInfo, date.year), NULL}, + /* %Y */ {CTOKT_DIGIT, CLF_DATE, 1, 4, TclOffset(DateInfo, date.year), NULL}, + /* %H */ {CTOKT_DIGIT, CLF_TIME, 1, 2, TclOffset(DateInfo, date.hour), NULL}, + /* %M */ {CTOKT_DIGIT, CLF_TIME, 1, 2, TclOffset(DateInfo, date.minutes), NULL}, + /* %S */ {CTOKT_DIGIT, CLF_TIME, 1, 2, TclOffset(DateInfo, date.secondOfDay), NULL}, + /* %J */ + {CTOKT_DIGIT, CLF_DATE | CLF_JULIANDAY, 1, 0xffff, TclOffset(DateInfo, date.julianDay), + NULL}, + /* %s */ + {CTOKT_DIGIT, CLF_LOCALSEC | CLF_SIGNED, 1, 0xffff, TclOffset(DateInfo, date.localSeconds), + NULL}, }; const char *ScnSpecTokenMapChars = " "; @@ -576,6 +649,7 @@ ClockScan( Tcl_Obj *strObj, /* String containing the time to scan */ ClockFmtScnCmdArgs *opts) /* Command options */ { + ClockClientData *dataPtr = clientData; ClockScanToken *tok; ClockScanTokenMap *map; register const char *p, *x, *end; @@ -590,46 +664,100 @@ ClockScan( yyMeridian = MER24; - /* bypass spaces at begin of string */ - p = TclGetString(strObj); end = p + strObj->length; - while (p < end && isspace(UCHAR(*p))) { - p++; + /* in strict mode - bypass spaces at begin / end only (not between tokens) */ + if (opts->flags & CLF_STRICT) { + while (p < end && isspace(UCHAR(*p))) { + p++; + } } info->dateStart = yyInput = p; /* parse string */ - for (; tok->map != NULL; yyInput = p, tok++) { + for (; tok->map != NULL; tok++) { map = tok->map; + /* bypass spaces at begin of input before parsing each token */ + if (!(opts->flags & CLF_STRICT) && map->type != CTOKT_SPACE) { + while (p < end && isspace(UCHAR(*p))) { + p++; + } + yyInput = p; + } switch (map->type) { case CTOKT_DIGIT: if (1) { - unsigned int val = 0; int size = map->maxSize; - /* greedy find digits (look forward), corresponding pre-calculated lookAhead */ - size += tok->lookAhead; - x = yyInput + size; - while (isdigit(UCHAR(*p)) && p < x) { p++; }; - /* consider reserved (lookAhead) for next tokens */ - p -= tok->lookAhead; + int sign = 1; + if (map->flags & CLF_SIGNED) { + if (*p == '+') { yyInput = ++p; } + else + if (*p == '-') { yyInput = ++p; sign = -1; }; + } + /* greedy find digits (look for forward digits consider spaces), + * corresponding pre-calculated lookAhead */ + if (size != map->minSize && tok->lookAhead) { + int spcnt = 0; + const char *pe; + size += tok->lookAhead; + x = p + size; if (x > end) { x = end; }; + pe = x; + while (p < x) { + if (isspace(UCHAR(*p))) { + if (pe > p) { pe = p; }; + if (x < end) x++; + p++; + spcnt++; + continue; + } + if (isdigit(UCHAR(*p))) { + p++; + continue; + } + break; + } + /* consider reserved (lookAhead) for next tokens */ + p -= tok->lookAhead + spcnt; + if (p > pe) { + p = pe; + } + } else { + x = p + size; if (x > end) { x = end; }; + while (isdigit(UCHAR(*p)) && p < x) { p++; }; + } size = p - yyInput; if (size < map->minSize) { /* missing input -> error */ - goto done; + goto error; } - /* string 2 number */ + /* string 2 number, put number into info structure by offset */ p = yyInput; x = p + size; - while (p < x) { - val = val * 10 + (*p++ - '0'); + if (!(map->flags & CLF_LOCALSEC)) { + if (_str2int((time_t *)(((char *)info) + map->offs), + p, x, sign) != TCL_OK) { + goto overflow; + } + p = x; + } else { + if (_str2wideInt((Tcl_WideInt *)(((char *)info) + map->offs), + p, x, sign) != TCL_OK) { + goto overflow; + } + p = x; } - /* put number into info by offset */ - *(time_t *)(((char *)info) + map->offs) = val; flags |= map->flags; } break; case CTOKT_SPACE: + /* at least one space in strict mode */ + if (opts->flags & CLF_STRICT) { + if (!isspace(UCHAR(*p))) { + /* unmatched -> error */ + goto error; + } + p++; + } while (p < end && isspace(UCHAR(*p))) { p++; } @@ -639,7 +767,7 @@ ClockScan( if (x == tok->tokWord.end) { /* single char word */ if (*p != *x) { /* no match -> error */ - goto done; + goto error; } p++; continue; @@ -648,7 +776,7 @@ ClockScan( while (p < end && x < tok->tokWord.end && *p++ == *x++) {}; if (x < tok->tokWord.end) { /* no match -> error */ - goto done; + goto error; } break; } @@ -661,43 +789,57 @@ ClockScan( /* check end was reached */ if (p < end) { /* something after last token - wrong format */ - goto done; + goto error; } /* invalidate result */ if (flags & CLF_DATE) { - yydate.julianDay = CL_INVALIDATE; + if (!(flags & CLF_JULIANDAY)) { + info->flags |= CLF_INVALIDATE_SECONDS|CLF_INVALIDATE_JULIANDAY; - if (yyYear < 100) { - if (yyYear >= ClockGetYearOfCenturySwitch(clientData, interp)) { - yyYear -= 100; + if (yyYear < 100) { + if (yyYear >= dataPtr->yearOfCenturySwitch) { + yyYear -= 100; + } + yyYear += dataPtr->currentYearCentury; } - yyYear += ClockCurrentYearCentury(clientData, interp); + yydate.era = CE; } - yydate.era = CE; - if (!(flags & CLF_TIME)) { + /* if date but no time - reset time */ + if (!(flags & (CLF_TIME|CLF_LOCALSEC))) { + info->flags |= CLF_INVALIDATE_SECONDS; yydate.localSeconds = 0; } } if (flags & CLF_TIME) { + info->flags |= CLF_INVALIDATE_SECONDS; yySeconds = ToSeconds(yyHour, yyMinutes, yySeconds, yyMeridian); - } else { - yySeconds = yydate.localSeconds % 86400; + } else + if (!(flags & CLF_LOCALSEC)) { + info->flags |= CLF_INVALIDATE_SECONDS; + yySeconds = yydate.localSeconds % SECONDS_PER_DAY; } ret = TCL_OK; + goto done; -done: +overflow: - if (ret != TCL_OK) { - Tcl_SetResult(interp, - "input string does not match supplied format", TCL_STATIC); - Tcl_SetErrorCode(interp, "CLOCK", "badInputString", NULL); - return ret; - } + Tcl_SetObjResult(interp, Tcl_NewStringObj( + "integer value too large to represent", -1)); + Tcl_SetErrorCode(interp, "CLOCK", "integervalueTooLarge", NULL); + goto done; + +error: + + Tcl_SetResult(interp, + "input string does not match supplied format", TCL_STATIC); + Tcl_SetErrorCode(interp, "CLOCK", "badInputString", NULL); + +done: return ret; } diff --git a/generic/tclDate.h b/generic/tclDate.h index 4b0b47e..47f2a21 100644 --- a/generic/tclDate.h +++ b/generic/tclDate.h @@ -14,6 +14,28 @@ #define _TCLCLOCK_H /* + * Constants + */ + +#define JULIAN_DAY_POSIX_EPOCH 2440588 +#define GREGORIAN_CHANGE_DATE 2361222 +#define SECONDS_PER_DAY 86400 +#define JULIAN_SEC_POSIX_EPOCH (((Tcl_WideInt) JULIAN_DAY_POSIX_EPOCH) \ + * SECONDS_PER_DAY) +#define FOUR_CENTURIES 146097 /* days */ +#define JDAY_1_JAN_1_CE_JULIAN 1721424 +#define JDAY_1_JAN_1_CE_GREGORIAN 1721426 +#define ONE_CENTURY_GREGORIAN 36524 /* days */ +#define FOUR_YEARS 1461 /* days */ +#define ONE_YEAR 365 /* days */ + + +/* On demand (lazy) assemble flags */ +#define CLF_INVALIDATE_DATE (1 << 6) /* assemble year, month, etc. using julianDay */ +#define CLF_INVALIDATE_JULIANDAY (1 << 7) /* assemble julianDay using year, month, etc. */ +#define CLF_INVALIDATE_SECONDS (1 << 8) /* assemble localSeconds (and seconds at end) */ + +/* * Structure containing the fields used in [clock format] and [clock scan] */ @@ -52,6 +74,7 @@ typedef struct TclDateFields { typedef struct DateInfo { const char *dateStart; const char *dateInput; + int flags; TclDateFields date; @@ -116,19 +139,71 @@ typedef struct DateInfo { #define yyDigitCount (info->dateDigitCount) -enum {CL_INVALIDATE = (signed int)0x80000000}; /* * Structure containing the command arguments supplied to [clock format] and [clock scan] */ +#define CLF_EXTENDED (1 << 4) +#define CLF_STRICT (1 << 8) + typedef struct ClockFmtScnCmdArgs { Tcl_Obj *formatObj; /* Format */ Tcl_Obj *localeObj; /* Name of the locale where the time will be expressed. */ Tcl_Obj *timezoneObj; /* Default time zone in which the time will be expressed */ Tcl_Obj *baseObj; /* Base (scan only) */ + int flags; /* Flags control scanning */ } ClockFmtScnCmdArgs; /* + * Structure containing the client data for [clock] + */ + +typedef struct ClockClientData { + int refCount; /* Number of live references. */ + Tcl_Obj **literals; /* Pool of object literals. */ + /* Cache for current clock parameters, imparted via "configure" */ + unsigned long LastTZEpoch; + int currentYearCentury; + int yearOfCenturySwitch; + Tcl_Obj *SystemTimeZone; + Tcl_Obj *SystemSetupTZData; + Tcl_Obj *GMTSetupTimeZone; + Tcl_Obj *GMTSetupTZData; + Tcl_Obj *AnySetupTimeZone; + Tcl_Obj *AnySetupTZData; + Tcl_Obj *LastUnnormSetupTimeZone; + Tcl_Obj *LastSetupTimeZone; + Tcl_Obj *LastSetupTZData; + /* Cache for last base (last-second fast convert if base/tz not changed) */ + struct { + Tcl_Obj *TimeZone; + TclDateFields Date; + } lastBase; + /* Las-minute cache for fast UTC2Local conversion */ + struct { + /* keys */ + Tcl_Obj *tzData; + int changeover; + Tcl_WideInt seconds; + /* values */ + time_t tzOffset; + Tcl_Obj *tzName; + } UTC2Local; + /* Las-minute cache for fast Local2UTC conversion */ + struct { + /* keys */ + Tcl_Obj *tzData; + int changeover; + Tcl_WideInt localSeconds; + /* values */ + time_t tzOffset; + } Local2UTC; +} ClockClientData; + +#define ClockDefaultYearCentury 2000 +#define ClockDefaultCenturySwitch 38 + +/* * Meridian: am, pm, or 24-hour style. */ @@ -152,8 +227,11 @@ typedef int ClockScanTokenProc( ClockScanToken *tok); -#define CLF_DATE (1 << 2) -#define CLF_TIME (1 << 3) +#define CLF_DATE (1 << 2) +#define CLF_JULIANDAY (1 << 3) +#define CLF_TIME (1 << 4) +#define CLF_LOCALSEC (1 << 5) +#define CLF_SIGNED (1 << 8) typedef enum _CLCKTOK_TYPE { CTOKT_DIGIT = 1, CTOKT_SPACE, CTOKT_WORD diff --git a/library/clock.tcl b/library/clock.tcl index ace4176..e0de904 100755 --- a/library/clock.tcl +++ b/library/clock.tcl @@ -287,9 +287,10 @@ proc ::tcl::clock::Initialize {} { variable FEB_28 58 - # Current year century and year of century switch - variable CurrentYearCentury 2000 - variable YearOfCenturySwitch 38 + # Default configuration + + # configure -year-century 2000 \ + # -century-switch 38 # Translation table to map Windows TZI onto cities, so that the Olson # rules can apply. In some cases the mapping is ambiguous, so it's wise @@ -2534,13 +2535,11 @@ proc ::tcl::clock::ScanWide { str } { proc ::tcl::clock::InterpretTwoDigitYear { date baseTime { twoDigitField yearOfCentury } { fourDigitField year } } { - variable CurrentYearCentury - variable YearOfCenturySwitch set yr [dict get $date $twoDigitField] - if { $yr >= $YearOfCenturySwitch } { + if { $yr >= [configure -century-switch] } { incr yr -100 } - incr yr $CurrentYearCentury + incr yr [configure -year-century] dict set date $fourDigitField $yr return $date } diff --git a/tests-perf/clock.perf.tcl b/tests-perf/clock.perf.tcl index 93a78e4..9267684 100644 --- a/tests-perf/clock.perf.tcl +++ b/tests-perf/clock.perf.tcl @@ -15,10 +15,19 @@ # of this file. # + +## set testing defaults: set ::env(TCL_TZ) :CET +## warm-up (load clock.tcl, system zones, etc.): +clock scan "" -gmt 1 +clock scan "" +clock scan "" -timezone :CET + +## ------------------------------------------ + proc {**STOP**} {args} { - return -code error -level 2 "**STOP** in [info level [expr {[info level]-1}]] [join $args { }]" + return -code error -level 4 "**STOP** in [info level [expr {[info level]-2}]] [join $args { }]" } proc _test_get_commands {lst} { @@ -43,7 +52,7 @@ proc _test_out_total {} { puts "" } -proc _test_run {reptime lst {outcmd {puts {$_(r)}}}} { +proc _test_run {reptime lst {outcmd {puts $_(r)}}} { upvar _ _ array set _ [list ittm {} itcnt {} itrate {} reptime $reptime] @@ -74,6 +83,22 @@ proc test-scan {{reptime 1000}} { {clock scan "1111" -format "%d%m%y" -base 0 -gmt 1} {clock scan "11111" -format "%d%m%y" -base 0 -gmt 1} {clock scan "111111" -format "%d%m%y" -base 0 -gmt 1} + # Scan : greedy match (space separated) + {clock scan "1 1 1" -format "%d%m%y" -base 0 -gmt 1} + {clock scan "111 1" -format "%d%m%y" -base 0 -gmt 1} + {clock scan "1 111" -format "%d%m%y" -base 0 -gmt 1} + {clock scan "1 11 1" -format "%d%m%y" -base 0 -gmt 1} + {clock scan "1 11 11" -format "%d%m%y" -base 0 -gmt 1} + {clock scan "11 11 11" -format "%d%m%y" -base 0 -gmt 1} + + # Scan : time (in gmt) + {clock scan "10:35:55" -format "%H:%M:%S" -base 1000000000 -gmt 1} + # Scan : time (system time zone, with base) + {clock scan "10:35:55" -format "%H:%M:%S" -base 1000000000} + # Scan : time (gmt, without base) + {clock scan "10:35:55" -format "%H:%M:%S" -gmt 1} + # Scan : time (system time zone, without base) + {clock scan "10:35:55" -format "%H:%M:%S"} # Scan : date-time (in gmt) {clock scan "25.11.2015 10:35:55" -format "%d.%m.%Y %H:%M:%S" -base 0 -gmt 1} @@ -85,6 +110,17 @@ proc test-scan {{reptime 1000}} { # Scan : dynamic format (cacheable) {clock scan "25.11.2015 10:35:55" -format [string trim "%d.%m.%Y %H:%M:%S "] -base 0 -gmt 1} + # Scan : julian day in gmt + {clock scan 2451545 -format %J -gmt 1} + # Scan : julian day in system TZ + {clock scan 2451545 -format %J} + # Scan : julian day in other TZ + {clock scan 2451545 -format %J -timezone +0200} + # Scan : julian day with time: + {clock scan "2451545 10:20:30" -format "%J %H:%M:%S"} + # Scan : julian day with time (greedy match): + {clock scan "2451545 102030" -format "%J%H%M%S"} + # Scan : zone only {clock scan "CET" -format "%z"} {clock scan "EST" -format "%z"} @@ -144,6 +180,10 @@ proc test-other {{reptime 1000}} { _test_run $reptime { # Bad zone {catch {clock scan "1 day" -timezone BAD_ZONE -locale en}} + + # Scan : julian day (overflow) + {catch {clock scan 5373485 -format %J}} + **STOP** # Scan : test rotate of GC objects (format is dynamic, so tcl-obj removed with last reference) {set i 0; time { clock scan "[incr i] - 25.11.2015" -format "$i - %d.%m.%Y" -base 0 -gmt 1 } 50} @@ -154,11 +194,11 @@ proc test-other {{reptime 1000}} { proc test {{reptime 1000}} { puts "" - test-scan $reptime - #test-freescan $reptime + #test-scan $reptime + test-freescan $reptime test-other $reptime puts \n**OK** } -test 250; # 250 ms +test 100; # ms diff --git a/tests/clock.test b/tests/clock.test index 477f142..9e3dbd7 100644 --- a/tests/clock.test +++ b/tests/clock.test @@ -35917,7 +35917,94 @@ test clock-34.52 {more than one ordinal month} {*}{ -result {unable to convert date-time string "next January next March": more than one ordinal month in string} } +test clock-34.53.1 {relative from base, date switch} { + set base [clock scan "12/31/2016 23:59:59" -gmt 1] + clock format [clock scan "+1 second" \ + -base $base -gmt 1] -gmt 1 -format {%Y-%m-%d %H:%M:%S} +} {2017-01-01 00:00:00} +test clock-34.53.2 {relative time, daylight switch} { + set base [clock scan "03/27/2016" -timezone CET] + set res {} + lappend res [clock format [clock scan "+1 hour" \ + -base $base -timezone CET] -timezone CET -format {%Y-%m-%d %H:%M:%S %Z}] + lappend res [clock format [clock scan "+2 hour" \ + -base $base -timezone CET] -timezone CET -format {%Y-%m-%d %H:%M:%S %Z}] +} {{2016-03-27 01:00:00 CET} {2016-03-27 03:00:00 CEST}} + +test clock-34.53.3 {relative time with day increment / daylight switch} { + set base [clock scan "03/27/2016" -timezone CET] + set res {} + lappend res [clock format [clock scan "+5 day +25 hour" \ + -base [expr {$base - 6*24*60*60}] -timezone CET] -timezone CET -format {%Y-%m-%d %H:%M:%S %Z}] + lappend res [clock format [clock scan "+5 day +26 hour" \ + -base [expr {$base - 6*24*60*60}] -timezone CET] -timezone CET -format {%Y-%m-%d %H:%M:%S %Z}] +} {{2016-03-27 01:00:00 CET} {2016-03-27 03:00:00 CEST}} + +test clock-34.53.4 {relative time with month & day increment / daylight switch} { + set base [clock scan "03/27/2016" -timezone CET] + set res {} + lappend res [clock format [clock scan "next Mar +5 day +25 hour" \ + -base [expr {$base - 35*24*60*60}] -timezone CET] -timezone CET -format {%Y-%m-%d %H:%M:%S %Z}] + lappend res [clock format [clock scan "next Mar +5 day +26 hour" \ + -base [expr {$base - 35*24*60*60}] -timezone CET] -timezone CET -format {%Y-%m-%d %H:%M:%S %Z}] +} {{2016-03-27 01:00:00 CET} {2016-03-27 03:00:00 CEST}} + +test clock-34.54.1 {check date in DST-hole: daylight switch CET -> CEST} { + set res {} + # forwards + set base 1459033200 + for {set i 0} {$i <= 3} {incr i} { + set d [clock scan "+$i hour" -base $base -timezone CET] + lappend res "$d = [clock format $d -timezone CET -format {%Y-%m-%d %H:%M:%S %Z}]" + } + lappend res "#--" + # backwards + set base 1459044000 + for {set i 0} {$i <= 3} {incr i} { + set d [clock scan "-$i hour" -base $base -timezone CET] + lappend res "$d = [clock format $d -timezone CET -format {%Y-%m-%d %H:%M:%S %Z}]" + } + set res +} [split [regsub -all {^\n|\n$} { +1459033200 = 2016-03-27 00:00:00 CET +1459036800 = 2016-03-27 01:00:00 CET +1459040400 = 2016-03-27 03:00:00 CEST +1459044000 = 2016-03-27 04:00:00 CEST +#-- +1459044000 = 2016-03-27 04:00:00 CEST +1459040400 = 2016-03-27 03:00:00 CEST +1459036800 = 2016-03-27 01:00:00 CET +1459033200 = 2016-03-27 00:00:00 CET +} {}] \n] + +test clock-34.54.2 {check date in DST-hole: daylight switch CEST -> CET} { + set res {} + # forwards + set base 1477782000 + for {set i 0} {$i <= 3} {incr i} { + set d [clock scan "+$i hour" -base $base -timezone CET] + lappend res "$d = [clock format $d -timezone CET -format {%Y-%m-%d %H:%M:%S %Z}]" + } + lappend res "#--" + # backwards + set base 1477792800 + for {set i 0} {$i <= 3} {incr i} { + set d [clock scan "-$i hour" -base $base -timezone CET] + lappend res "$d = [clock format $d -timezone CET -format {%Y-%m-%d %H:%M:%S %Z}]" + } + set res +} [split [regsub -all {^\n|\n$} { +1477782000 = 2016-10-30 01:00:00 CEST +1477785600 = 2016-10-30 02:00:00 CEST +1477789200 = 2016-10-30 02:00:00 CET +1477792800 = 2016-10-30 03:00:00 CET +#-- +1477792800 = 2016-10-30 03:00:00 CET +1477789200 = 2016-10-30 02:00:00 CET +1477785600 = 2016-10-30 02:00:00 CEST +1477782000 = 2016-10-30 01:00:00 CEST +} {}] \n] # clock seconds test clock-35.1 {clock seconds tests} { -- cgit v0.12 From bcb2a0a181c0de95732c70b66d5040ec6bd4b2b9 Mon Sep 17 00:00:00 2001 From: sebres Date: Tue, 10 Jan 2017 22:20:25 +0000 Subject: amend for caching of UTC2Local / Local2UTC: * tzdata used internally only (because cached, replaced with timezone object as parameter for several functions) * small improvement (don't need to convert UTC to UTC) --- generic/tclClock.c | 104 ++++++++++++++++++++++++++++++++--------------------- generic/tclDate.h | 14 ++++---- library/clock.tcl | 34 +++++++++--------- 3 files changed, 88 insertions(+), 64 deletions(-) diff --git a/generic/tclClock.c b/generic/tclClock.c index 7cc5d86..6bd6336 100644 --- a/generic/tclClock.c +++ b/generic/tclClock.c @@ -107,13 +107,13 @@ TCL_DECLARE_MUTEX(clockMutex) */ static int ConvertUTCToLocal(ClientData clientData, Tcl_Interp *, - TclDateFields *, Tcl_Obj *, int); + TclDateFields *, Tcl_Obj *timezoneObj, int); static int ConvertUTCToLocalUsingTable(Tcl_Interp *, TclDateFields *, int, Tcl_Obj *const[]); static int ConvertUTCToLocalUsingC(Tcl_Interp *, TclDateFields *, int); static int ConvertLocalToUTC(ClientData clientData, Tcl_Interp *, - TclDateFields *, Tcl_Obj *, int); + TclDateFields *, Tcl_Obj *timezoneObj, int); static int ConvertLocalToUTCUsingTable(Tcl_Interp *, TclDateFields *, int, Tcl_Obj *const[]); static int ConvertLocalToUTCUsingC(Tcl_Interp *, @@ -138,7 +138,7 @@ static int ClockConvertlocaltoutcObjCmd( static int ClockGetDateFields(ClientData clientData, Tcl_Interp *interp, TclDateFields *fields, - Tcl_Obj *tzdata, int changeover); + Tcl_Obj *timezoneObj, int changeover); static int ClockGetdatefieldsObjCmd( ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *const objv[]); @@ -287,10 +287,10 @@ TclClockInit( data->LastSetupTimeZone = NULL; data->LastSetupTZData = NULL; - data->lastBase.TimeZone = NULL; - data->UTC2Local.tzData = NULL; + data->lastBase.timezoneObj = NULL; + data->UTC2Local.timezoneObj = NULL; data->UTC2Local.tzName = NULL; - data->Local2UTC.tzData = NULL; + data->Local2UTC.timezoneObj = NULL; /* * Install the commands. @@ -335,10 +335,10 @@ ClockConfigureClear( Tcl_UnsetObjRef(data->LastSetupTimeZone); Tcl_UnsetObjRef(data->LastSetupTZData); - Tcl_UnsetObjRef(data->lastBase.TimeZone); - Tcl_UnsetObjRef(data->UTC2Local.tzData); + Tcl_UnsetObjRef(data->lastBase.timezoneObj); + Tcl_UnsetObjRef(data->UTC2Local.timezoneObj); Tcl_UnsetObjRef(data->UTC2Local.tzName); - Tcl_UnsetObjRef(data->Local2UTC.tzData); + Tcl_UnsetObjRef(data->Local2UTC.timezoneObj); } static void @@ -699,11 +699,11 @@ ClockFormatNumericTimeZone(int z) { * is available. * * Usage: - * ::tcl::clock::ConvertUTCToLocal dictionary tzdata changeover + * ::tcl::clock::ConvertUTCToLocal dictionary timezone changeover * * Parameters: * dict - Dictionary containing a 'localSeconds' entry. - * tzdata - Time zone data + * timezone - Time zone * changeover - Julian Day of the adoption of the Gregorian calendar. * * Results: @@ -739,7 +739,7 @@ ClockConvertlocaltoutcObjCmd( */ if (objc != 4) { - Tcl_WrongNumArgs(interp, 1, objv, "dict tzdata changeover"); + Tcl_WrongNumArgs(interp, 1, objv, "dict timezone changeover"); return TCL_ERROR; } dict = objv[1]; @@ -789,12 +789,11 @@ ClockConvertlocaltoutcObjCmd( * formatting a date, and populates a dictionary with them. * * Usage: - * ::tcl::clock::GetDateFields seconds tzdata changeover + * ::tcl::clock::GetDateFields seconds timezone changeover * * Parameters: * seconds - Time expressed in seconds from the Posix epoch. - * tzdata - Time zone data of the time zone in which time is to be - * expressed. + * timezone - Time zone in which time is to be expressed. * changeover - Julian Day Number at which the current locale adopted * the Gregorian calendar * @@ -830,7 +829,7 @@ ClockGetdatefieldsObjCmd( */ if (objc != 4) { - Tcl_WrongNumArgs(interp, 1, objv, "seconds tzdata changeover"); + Tcl_WrongNumArgs(interp, 1, objv, "seconds timezone changeover"); return TCL_ERROR; } if (Tcl_GetWideIntFromObj(interp, objv[1], &fields.seconds) != TCL_OK @@ -900,14 +899,14 @@ ClockGetDateFields( Tcl_Interp *interp, /* Tcl interpreter */ TclDateFields *fields, /* Pointer to result fields, where * fields->seconds contains date to extract */ - Tcl_Obj *tzdata, /* Time zone data object or NULL for gmt */ + Tcl_Obj *timezoneObj, /* Time zone object or NULL for gmt */ int changeover) /* Julian Day Number */ { /* * Convert UTC time to local. */ - if (ConvertUTCToLocal(clientData, interp, fields, tzdata, + if (ConvertUTCToLocal(clientData, interp, fields, timezoneObj, changeover) != TCL_OK) { return TCL_ERROR; } @@ -1165,18 +1164,26 @@ ConvertLocalToUTC( ClientData clientData, /* Client data of the interpreter */ Tcl_Interp *interp, /* Tcl interpreter */ TclDateFields *fields, /* Fields of the time */ - Tcl_Obj *tzdata, /* Time zone data */ + Tcl_Obj *timezoneObj, /* Time zone */ int changeover) /* Julian Day of the Gregorian transition */ { ClockClientData *dataPtr = clientData; + Tcl_Obj *tzdata; /* Time zone data */ int rowc; /* Number of rows in tzdata */ Tcl_Obj **rowv; /* Pointers to the rows */ + /* fast phase-out for shared GMT-object (don't need to convert UTC 2 UTC) */ + if (timezoneObj == dataPtr->GMTSetupTimeZone && dataPtr->GMTSetupTimeZone != NULL) { + fields->seconds = fields->localSeconds; + fields->tzOffset = 0; + return TCL_OK; + } + /* * Check cacheable conversion could be used * (last-minute Local2UTC cache with the same TZ) */ - if ( tzdata == dataPtr->Local2UTC.tzData + if ( timezoneObj == dataPtr->Local2UTC.timezoneObj && ( fields->localSeconds == dataPtr->Local2UTC.localSeconds || fields->localSeconds / 60 == dataPtr->Local2UTC.localSeconds / 60 ) @@ -1192,6 +1199,11 @@ ConvertLocalToUTC( * Unpack the tz data. */ + tzdata = ClockGetTZData(clientData, interp, timezoneObj); + if (tzdata == NULL) { + return TCL_ERROR; + } + if (TclListObjGetElements(interp, tzdata, &rowc, &rowv) != TCL_OK) { return TCL_ERROR; } @@ -1212,7 +1224,7 @@ ConvertLocalToUTC( } /* Cache the last conversion */ - Tcl_SetObjRef(dataPtr->Local2UTC.tzData, tzdata); + Tcl_SetObjRef(dataPtr->Local2UTC.timezoneObj, timezoneObj); dataPtr->Local2UTC.localSeconds = fields->localSeconds; dataPtr->Local2UTC.changeover = changeover; dataPtr->Local2UTC.tzOffset = fields->tzOffset; @@ -1432,18 +1444,34 @@ ConvertUTCToLocal( ClientData clientData, /* Client data of the interpreter */ Tcl_Interp *interp, /* Tcl interpreter */ TclDateFields *fields, /* Fields of the time */ - Tcl_Obj *tzdata, /* Time zone data */ + Tcl_Obj *timezoneObj, /* Time zone */ int changeover) /* Julian Day of the Gregorian transition */ { ClockClientData *dataPtr = clientData; + Tcl_Obj *tzdata; /* Time zone data */ int rowc; /* Number of rows in tzdata */ Tcl_Obj **rowv; /* Pointers to the rows */ + /* fast phase-out for shared GMT-object (don't need to convert UTC 2 UTC) */ + if (timezoneObj == dataPtr->GMTSetupTimeZone + && dataPtr->GMTSetupTimeZone != NULL + && dataPtr->GMTSetupTZData != NULL + ) { + fields->localSeconds = fields->seconds; + fields->tzOffset = 0; + if ( TclListObjGetElements(interp, dataPtr->GMTSetupTZData, &rowc, &rowv) != TCL_OK + || Tcl_ListObjIndex(interp, rowv[0], 3, &fields->tzName) != TCL_OK) { + return TCL_ERROR; + } + Tcl_IncrRefCount(fields->tzName); + return TCL_OK; + } + /* * Check cacheable conversion could be used * (last-minute UTC2Local cache with the same TZ) */ - if ( tzdata == dataPtr->UTC2Local.tzData + if ( timezoneObj == dataPtr->UTC2Local.timezoneObj && ( fields->seconds == dataPtr->UTC2Local.seconds || fields->seconds / 60 == dataPtr->UTC2Local.seconds / 60 ) @@ -1460,6 +1488,11 @@ ConvertUTCToLocal( * Unpack the tz data. */ + tzdata = ClockGetTZData(clientData, interp, timezoneObj); + if (tzdata == NULL) { + return TCL_ERROR; + } + if (TclListObjGetElements(interp, tzdata, &rowc, &rowv) != TCL_OK) { return TCL_ERROR; } @@ -1480,7 +1513,7 @@ ConvertUTCToLocal( } /* Cache the last conversion */ - Tcl_SetObjRef(dataPtr->UTC2Local.tzData, tzdata); + Tcl_SetObjRef(dataPtr->UTC2Local.timezoneObj, timezoneObj); dataPtr->UTC2Local.seconds = fields->seconds; dataPtr->UTC2Local.changeover = changeover; dataPtr->UTC2Local.tzOffset = fields->tzOffset; @@ -2607,32 +2640,27 @@ ClockScanObjCmd( if (opts.timezoneObj == NULL) { goto done; } + // Tcl_SetObjRef(yydate.tzName, opts.timezoneObj); /* * Extract year, month and day from the base time for the parser to use as * defaults */ - yydate.tzData = ClockGetTZData(clientData, interp, opts.timezoneObj); - if (yydate.tzData == NULL) { - goto done; - } - Tcl_SetObjRef(yydate.tzName, opts.timezoneObj); - /* check base fields already cached (by TZ, last-second cache) */ - if ( dataPtr->lastBase.TimeZone == opts.timezoneObj + if ( dataPtr->lastBase.timezoneObj == opts.timezoneObj && dataPtr->lastBase.Date.seconds == baseVal) { memcpy(&yydate, &dataPtr->lastBase.Date, ClockCacheableDateFieldsSize); } else { /* extact fields from base */ yydate.seconds = baseVal; - if (ClockGetDateFields(clientData, interp, &yydate, yydate.tzData, + if (ClockGetDateFields(clientData, interp, &yydate, opts.timezoneObj, GREGORIAN_CHANGE_DATE) != TCL_OK) { goto done; } /* cache last base */ memcpy(&dataPtr->lastBase.Date, &yydate, ClockCacheableDateFieldsSize); - Tcl_SetObjRef(dataPtr->lastBase.TimeZone, opts.timezoneObj); + Tcl_SetObjRef(dataPtr->lastBase.timezoneObj, opts.timezoneObj); } /* seconds are in localSeconds (relative base date), so reset time here */ @@ -2700,8 +2728,8 @@ ClockScanObjCmd( + ( yySeconds % SECONDS_PER_DAY ); } - if (ConvertLocalToUTC(clientData, interp, &yydate, yydate.tzData, GREGORIAN_CHANGE_DATE) - != TCL_OK) { + if (ConvertLocalToUTC(clientData, interp, &yydate, opts.timezoneObj, + GREGORIAN_CHANGE_DATE) != TCL_OK) { goto done; } @@ -2798,12 +2826,8 @@ ClockFreeScan( if (opts->timezoneObj == NULL) { goto done; } - yydate.tzData = ClockGetTZData(clientData, interp, opts->timezoneObj); - if (yydate.tzData == NULL) { - goto done; - } - Tcl_SetObjRef(yydate.tzName, opts->timezoneObj); + // Tcl_SetObjRef(yydate.tzName, opts->timezoneObj); info->flags |= CLF_INVALIDATE_SECONDS; } diff --git a/generic/tclDate.h b/generic/tclDate.h index 47f2a21..9585258 100644 --- a/generic/tclDate.h +++ b/generic/tclDate.h @@ -60,8 +60,8 @@ typedef struct TclDateFields { time_t minutes; /* Minutes of day (in-between time only calculation) */ time_t secondOfDay; /* Seconds of day (in-between time only calculation) */ - Tcl_Obj *tzName; /* Time zone name (if set the refCount is incremented) */ - Tcl_Obj *tzData; /* Time zone data object (internally referenced) */ + Tcl_Obj *tzName; /* Name (or corresponding DST-abbreviation) of the + * time zone, if set the refCount is incremented */ } TclDateFields; #define ClockCacheableDateFieldsSize \ @@ -176,14 +176,14 @@ typedef struct ClockClientData { Tcl_Obj *LastSetupTZData; /* Cache for last base (last-second fast convert if base/tz not changed) */ struct { - Tcl_Obj *TimeZone; + Tcl_Obj *timezoneObj; TclDateFields Date; } lastBase; /* Las-minute cache for fast UTC2Local conversion */ struct { /* keys */ - Tcl_Obj *tzData; - int changeover; + Tcl_Obj *timezoneObj; + int changeover; Tcl_WideInt seconds; /* values */ time_t tzOffset; @@ -192,8 +192,8 @@ typedef struct ClockClientData { /* Las-minute cache for fast Local2UTC conversion */ struct { /* keys */ - Tcl_Obj *tzData; - int changeover; + Tcl_Obj *timezoneObj; + int changeover; Tcl_WideInt localSeconds; /* values */ time_t tzOffset; diff --git a/library/clock.tcl b/library/clock.tcl index e0de904..ebbecb9 100755 --- a/library/clock.tcl +++ b/library/clock.tcl @@ -677,7 +677,7 @@ proc ::tcl::clock::format { args } { } } if {![info exists TZData($timezone)]} { - if {[catch {SetupTimeZone $timezone} retval opts]} { + if {[catch {set timezone [SetupTimeZone $timezone]} retval opts]} { dict unset opts -errorinfo return -options $opts $retval } @@ -744,7 +744,7 @@ proc ::tcl::clock::ParseClockFormatFormat2 {format locale procName} { { variable TZData set date [GetDateFields $clockval \ - $TZData($timezone) \ + $timezone \ @GREGORIAN_CHANGE_DATE@] }] set formatString {} @@ -1776,7 +1776,7 @@ proc ::tcl::clock::ParseClockScanFormat {formatString locale} { } } append procBody { - ::tcl::clock::SetupTimeZone $timeZone + set timeZone [::tcl::clock::SetupTimeZone $timeZone] } } @@ -1810,7 +1810,7 @@ proc ::tcl::clock::ParseClockScanFormat {formatString locale} { append procBody { set date [::tcl::clock::ConvertLocalToUTC $date[set date {}] \ - $TZData($timeZone) $changeover] + $timeZone $changeover] } } @@ -2572,7 +2572,7 @@ proc ::tcl::clock::AssignBaseYear { date baseTime timezone changeover } { # Find the Julian Day Number corresponding to the base time, and # find the Gregorian year corresponding to that Julian Day. - set date2 [GetDateFields $baseTime $TZData($timezone) $changeover] + set date2 [GetDateFields $baseTime $timezone $changeover] # Store the converted year @@ -2610,7 +2610,7 @@ proc ::tcl::clock::AssignBaseIso8601Year {date baseTime timeZone changeover} { # Find the Julian Day Number corresponding to the base time - set date2 [GetDateFields $baseTime $TZData($timeZone) $changeover] + set date2 [GetDateFields $baseTime $timeZone $changeover] # Calculate the ISO8601 date and transfer the year @@ -2646,7 +2646,7 @@ proc ::tcl::clock::AssignBaseMonth {date baseTime timezone changeover} { # Find the year and month corresponding to the base time - set date2 [GetDateFields $baseTime $TZData($timezone) $changeover] + set date2 [GetDateFields $baseTime $timezone $changeover] dict set date era [dict get $date2 era] dict set date year [dict get $date2 year] dict set date month [dict get $date2 month] @@ -2680,7 +2680,7 @@ proc ::tcl::clock::AssignBaseWeek {date baseTime timeZone changeover} { # Find the Julian Day Number corresponding to the base time - set date2 [GetDateFields $baseTime $TZData($timeZone) $changeover] + set date2 [GetDateFields $baseTime $timeZone $changeover] # Calculate the ISO8601 date and transfer the year @@ -2716,7 +2716,7 @@ proc ::tcl::clock::AssignBaseJulianDay { date baseTime timeZone changeover } { # Find the Julian Day Number corresponding to the base time - set date2 [GetDateFields $baseTime $TZData($timeZone) $changeover] + set date2 [GetDateFields $baseTime $timeZone $changeover] dict set date julianDay [dict get $date2 julianDay] return $date @@ -2823,7 +2823,7 @@ proc ::tcl::clock::GetSystemTimeZone {} { } } if { ![dict exists $TimeZoneBad $timezone] } { - catch {SetupTimeZone $timezone} + catch {set timezone [SetupTimeZone $timezone]} } if { [dict exists $TimeZoneBad $timezone] } { @@ -2965,7 +2965,7 @@ proc ::tcl::clock::SetupTimeZone { timezone } { } } - # tell backend - timezone is initialized: + # tell backend - timezone is initialized and return shared timezone object: configure -setup-tz $timezone } @@ -3037,7 +3037,7 @@ proc ::tcl::clock::GuessWindowsTimeZone {} { if { [dict exists $WinZoneInfo $data] } { set tzname [dict get $WinZoneInfo $data] if { ! [dict exists $TimeZoneBad $tzname] } { - catch {SetupTimeZone $tzname} + catch {set tzname [SetupTimeZone $tzname]} } } else { set tzname {} @@ -4131,7 +4131,7 @@ proc ::tcl::clock::add { clockval args } { set changeover [mc GREGORIAN_CHANGE_DATE] - if {[catch {SetupTimeZone $timezone} retval opts]} { + if {[catch {set timezone [SetupTimeZone $timezone]} retval opts]} { dict unset opts -errorinfo return -options $opts $retval } @@ -4215,7 +4215,7 @@ proc ::tcl::clock::AddMonths { months clockval timezone changeover } { # Convert the time to year, month, day, and fraction of day. - set date [GetDateFields $clockval $TZData($timezone) $changeover] + set date [GetDateFields $clockval $timezone $changeover] dict set date secondOfDay [expr { [dict get $date localSeconds] % 86400 }] @@ -4252,7 +4252,7 @@ proc ::tcl::clock::AddMonths { months clockval timezone changeover } { + ( 86400 * wide([dict get $date julianDay]) ) + [dict get $date secondOfDay] }] - set date [ConvertLocalToUTC $date[set date {}] $TZData($timezone) \ + set date [ConvertLocalToUTC $date[set date {}] $timezone \ $changeover] return [dict get $date seconds] @@ -4336,7 +4336,7 @@ proc ::tcl::clock::AddDays { days clockval timezone changeover } { # Convert the time to Julian Day - set date [GetDateFields $clockval $TZData($timezone) $changeover] + set date [GetDateFields $clockval $timezone $changeover] dict set date secondOfDay [expr { [dict get $date localSeconds] % 86400 }] @@ -4353,7 +4353,7 @@ proc ::tcl::clock::AddDays { days clockval timezone changeover } { + ( 86400 * wide([dict get $date julianDay]) ) + [dict get $date secondOfDay] }] - set date [ConvertLocalToUTC $date[set date {}] $TZData($timezone) \ + set date [ConvertLocalToUTC $date[set date {}] $timezone \ $changeover] return [dict get $date seconds] -- cgit v0.12 From c5d6cc90d9239f54b212d06b8f98516ff145545b Mon Sep 17 00:00:00 2001 From: sebres Date: Tue, 10 Jan 2017 22:21:26 +0000 Subject: several initialize and finalize facilities --- generic/tclClock.c | 16 +++++++++------- generic/tclClockFmt.c | 26 +++++++++++++++++++++----- generic/tclDate.c | 19 +++---------------- generic/tclDate.h | 14 +++++++++++++- generic/tclGetDate.y | 19 +++---------------- 5 files changed, 49 insertions(+), 45 deletions(-) diff --git a/generic/tclClock.c b/generic/tclClock.c index 6bd6336..a4edb82 100644 --- a/generic/tclClock.c +++ b/generic/tclClock.c @@ -324,6 +324,8 @@ static void ClockConfigureClear( ClockClientData *data) { + ClockFrmScnClearCaches(); + data->LastTZEpoch = 0; Tcl_UnsetObjRef(data->SystemTimeZone); Tcl_UnsetObjRef(data->SystemSetupTZData); @@ -2609,8 +2611,6 @@ ClockScanObjCmd( ret = TCL_ERROR; - info->flags = 0; - if (opts.baseObj != NULL) { if (Tcl_GetWideIntFromObj(interp, opts.baseObj, &baseVal) != TCL_OK) { return TCL_ERROR; @@ -2621,8 +2621,6 @@ ClockScanObjCmd( baseVal = (Tcl_WideInt) now.sec; } - yydate.tzName = NULL; - /* If time zone not specified use system time zone */ if ( opts.timezoneObj == NULL || TclGetString(opts.timezoneObj) == NULL @@ -2630,7 +2628,7 @@ ClockScanObjCmd( ) { opts.timezoneObj = ClockGetSystemTimeZone(clientData, interp); if (opts.timezoneObj == NULL) { - goto done; + return TCL_ERROR; } } @@ -2638,8 +2636,12 @@ ClockScanObjCmd( opts.timezoneObj = ClockSetupTimeZone(clientData, interp, opts.timezoneObj); if (opts.timezoneObj == NULL) { - goto done; + return TCL_ERROR; } + + ClockInitDateInfo(info); + yydate.tzName = NULL; + // Tcl_SetObjRef(yydate.tzName, opts.timezoneObj); /* @@ -2679,7 +2681,7 @@ ClockScanObjCmd( } ret = ClockFreeScan(clientData, interp, info, objv[1], &opts); } -#if 1 +#if 0 else if (1) { /* TODO: Tcled Scan proc - */ diff --git a/generic/tclClockFmt.c b/generic/tclClockFmt.c index 48b9b69..ad04e4b 100644 --- a/generic/tclClockFmt.c +++ b/generic/tclClockFmt.c @@ -31,6 +31,8 @@ TCL_DECLARE_MUTEX(ClockFmtMutex); /* Serializes access to common format list. */ static void ClockFmtScnStorageDelete(ClockFmtScnStorage *fss); +static void ClockFrmScnFinalize(ClientData clientData); + /* * Clock scan and format facilities. */ @@ -148,7 +150,7 @@ ClockFmtScnStorage_GC_Out(ClockFmtScnStorage *entry) */ static Tcl_HashTable FmtScnHashTable; -static int initFmtScnHashTable = 0; +static int initialized = 0; inline Tcl_HashEntry * HashEntry4FmtScn(ClockFmtScnStorage *fss) { @@ -246,16 +248,18 @@ FindOrCreateFmtScnStorage( Tcl_MutexLock(&ClockFmtMutex); /* if not yet initialized */ - if (!initFmtScnHashTable) { + if (!initialized) { /* initialize type */ memcpy(&ClockFmtScnStorageHashKeyType, &tclStringHashKeyType, sizeof(tclStringHashKeyType)); ClockFmtScnStorageHashKeyType.allocEntryProc = ClockFmtScnStorageAllocProc; ClockFmtScnStorageHashKeyType.freeEntryProc = ClockFmtScnStorageFreeProc; - initFmtScnHashTable = 1; /* initialize hash table */ Tcl_InitCustomHashTable(&FmtScnHashTable, TCL_CUSTOM_TYPE_KEYS, &ClockFmtScnStorageHashKeyType); + + initialized = 1; + Tcl_CreateExitHandler(ClockFrmScnFinalize, NULL); } /* get or create entry (and alocate storage) */ @@ -845,18 +849,30 @@ done: } +MODULE_SCOPE void +ClockFrmScnClearCaches(void) +{ + Tcl_MutexLock(&ClockFmtMutex); + /* clear caches ... */ + Tcl_MutexUnlock(&ClockFmtMutex); +} + static void -Tcl_GetClockFrmScnFinalize() +ClockFrmScnFinalize( + ClientData clientData) /* Not used. */ { + Tcl_MutexLock(&ClockFmtMutex); #if CLOCK_FMT_SCN_STORAGE_GC_SIZE > 0 /* clear GC */ ClockFmtScnStorage_GC.stackPtr = NULL; ClockFmtScnStorage_GC.stackBound = NULL; ClockFmtScnStorage_GC.count = 0; #endif - if (initFmtScnHashTable) { + if (initialized) { Tcl_DeleteHashTable(&FmtScnHashTable); + initialized = 0; } + Tcl_MutexUnlock(&ClockFmtMutex); Tcl_MutexFinalize(&ClockFmtMutex); } /* diff --git a/generic/tclDate.c b/generic/tclDate.c index 97d13b4..5bd96d0 100644 --- a/generic/tclDate.c +++ b/generic/tclDate.c @@ -2685,24 +2685,11 @@ TclClockFreeScan( /* * yyInput = stringToParse; - * yyYear = baseYear; yyMonth = baseMonth; yyDay = baseDay; + * + * ClockInitDateInfo(info) should be executed to pre-init info; */ - yyHaveDate = 0; - - yyHaveTime = 0; - - yyHaveZone = 0; - yyTimezone = 0; yyDSTmode = DSTmaybe; - - yyHaveOrdinalMonth = 0; - yyMonthOrdinalIncr = 0; - - yyHaveDay = 0; - yyDayOrdinal = 0; yyDayNumber = 0; - - yyHaveRel = 0; - yyRelMonth = 0; yyRelDay = 0; yyRelSeconds = 0; yyRelPointer = NULL; + yyDSTmode = DSTmaybe; info->messages = Tcl_NewObj(); info->separatrix = ""; diff --git a/generic/tclDate.h b/generic/tclDate.h index 9585258..2010178 100644 --- a/generic/tclDate.h +++ b/generic/tclDate.h @@ -40,6 +40,9 @@ */ typedef struct TclDateFields { + + /* Cacheable fields: */ + Tcl_WideInt seconds; /* Time expressed in seconds from the Posix * epoch */ Tcl_WideInt localSeconds; /* Local time expressed in nominal seconds @@ -60,6 +63,8 @@ typedef struct TclDateFields { time_t minutes; /* Minutes of day (in-between time only calculation) */ time_t secondOfDay; /* Seconds of day (in-between time only calculation) */ + /* Non cacheable fields: */ + Tcl_Obj *tzName; /* Name (or corresponding DST-abbreviation) of the * time zone, if set the refCount is incremented */ } TclDateFields; @@ -74,10 +79,11 @@ typedef struct TclDateFields { typedef struct DateInfo { const char *dateStart; const char *dateInput; - int flags; TclDateFields date; + int flags; + time_t dateHaveDate; time_t dateMeridian; @@ -138,6 +144,10 @@ typedef struct DateInfo { #define yyInput (info->dateInput) #define yyDigitCount (info->dateDigitCount) +inline void +ClockInitDateInfo(DateInfo *info) { + memset(info, 0, sizeof(DateInfo)); +} /* * Structure containing the command arguments supplied to [clock format] and [clock scan] @@ -298,6 +308,8 @@ MODULE_SCOPE int ClockScan(ClientData clientData, Tcl_Interp *interp, register DateInfo *info, Tcl_Obj *strObj, ClockFmtScnCmdArgs *opts); +MODULE_SCOPE void ClockFrmScnClearCaches(void); + /* * Other externals. */ diff --git a/generic/tclGetDate.y b/generic/tclGetDate.y index 54087ca..9e3623f 100644 --- a/generic/tclGetDate.y +++ b/generic/tclGetDate.y @@ -896,24 +896,11 @@ TclClockFreeScan( /* * yyInput = stringToParse; - * yyYear = baseYear; yyMonth = baseMonth; yyDay = baseDay; + * + * ClockInitDateInfo(info) should be executed to pre-init info; */ - yyHaveDate = 0; - - yyHaveTime = 0; - - yyHaveZone = 0; - yyTimezone = 0; yyDSTmode = DSTmaybe; - - yyHaveOrdinalMonth = 0; - yyMonthOrdinalIncr = 0; - - yyHaveDay = 0; - yyDayOrdinal = 0; yyDayNumber = 0; - - yyHaveRel = 0; - yyRelMonth = 0; yyRelDay = 0; yyRelSeconds = 0; yyRelPointer = NULL; + yyDSTmode = DSTmaybe; info->messages = Tcl_NewObj(); info->separatrix = ""; -- cgit v0.12 From 18dc49dd083ec10211463e17378e1655a791df28 Mon Sep 17 00:00:00 2001 From: sebres Date: Tue, 10 Jan 2017 22:23:37 +0000 Subject: [temp-commit]: not ready --- generic/tclClock.c | 167 ++++++++++++++++++++---- generic/tclClockFmt.c | 319 ++++++++++++++++++++++++++++++++++++++-------- generic/tclDate.h | 32 ++++- library/msgcat/msgcat.tcl | 54 +++++++- tests-perf/clock.perf.tcl | 13 +- 5 files changed, 501 insertions(+), 84 deletions(-) diff --git a/generic/tclClock.c b/generic/tclClock.c index a4edb82..1e9abba 100644 --- a/generic/tclClock.c +++ b/generic/tclClock.c @@ -59,6 +59,8 @@ typedef enum ClockLiteral { LIT_TZDATA, LIT_GETSYSTEMTIMEZONE, LIT_SETUPTIMEZONE, + LIT_GETSYSTEMLOCALE, + LIT_SETUPLOCALE, #if 0 LIT_FREESCAN, #endif @@ -81,6 +83,8 @@ static const char *const Literals[] = { "::tcl::clock::TZData", "::tcl::clock::GetSystemTimeZone", "::tcl::clock::SetupTimeZone", + "::tcl::clock::mclocale", + "::tcl::clock::EnterLocale", #if 0 "::tcl::clock::FreeScan" #endif @@ -176,24 +180,6 @@ static void TzsetIfNecessary(void); static void ClockDeleteCmdProc(ClientData); /* - * Primitives to safe set, reset and free references. - */ - -#define Tcl_UnsetObjRef(obj) \ - if (obj != NULL) { Tcl_DecrRefCount(obj); obj = NULL; } -#define Tcl_InitObjRef(obj, val) \ - obj = val; if (obj) { Tcl_IncrRefCount(obj); } -#define Tcl_SetObjRef(obj, val) \ -if (1) { \ - Tcl_Obj *nval = val; \ - if (obj != nval) { \ - Tcl_Obj *prev = obj; \ - Tcl_InitObjRef(obj, nval); \ - if (prev != NULL) { Tcl_DecrRefCount(prev); }; \ - } \ -} - -/* * Structure containing description of "native" clock commands to create. */ @@ -610,12 +596,18 @@ ClockGetSystemTimeZone( return dataPtr->SystemTimeZone; } + Tcl_UnsetObjRef(dataPtr->SystemTimeZone); + Tcl_UnsetObjRef(data->SystemSetupTZData); + literals = dataPtr->literals; if (Tcl_EvalObjv(interp, 1, &literals[LIT_GETSYSTEMTIMEZONE], 0) != TCL_OK) { return NULL; } - return Tcl_GetObjResult(interp); + if (dataPtr->SystemTimeZone == NULL) { + Tcl_SetObjRef(dataPtr->SystemTimeZone, Tcl_GetObjResult(interp)); + } + return dataPtr->SystemTimeZone; } /* *---------------------------------------------------------------------- @@ -694,6 +686,124 @@ ClockFormatNumericTimeZone(int z) { /* *---------------------------------------------------------------------- + */ +inline Tcl_Obj * +NormLocaleObj( + ClockClientData *dataPtr, /* Client data containing literal pool */ + Tcl_Obj *localeObj) +{ + const char * tz; + if ( localeObj == dataPtr->LastUnnormSetupLocale + && dataPtr->LastSetupLocale != NULL + ) { + return dataPtr->LastSetupLocale; + } + if ( localeObj == dataPtr->LastSetupLocale + || localeObj == dataPtr->literals[LIT_CLOCALE] + || localeObj == dataPtr->SystemLocale + || localeObj == dataPtr->AnySetupLocale + ) { + return localeObj; + } + + tz = TclGetString(localeObj); + if (dataPtr->AnySetupLocale != NULL && + (localeObj == dataPtr->AnySetupLocale + || strcmp(tz, TclGetString(dataPtr->AnySetupLocale)) == 0 + ) + ) { + localeObj = dataPtr->AnySetupLocale; + } + else + if (dataPtr->SystemLocale != NULL && + (localeObj == dataPtr->SystemLocale + || strcmp(tz, TclGetString(dataPtr->SystemLocale)) == 0 + ) + ) { + localeObj = dataPtr->SystemLocale; + } + else + if ( + strcmp(tz, Literals[LIT_GMT]) == 0 + ) { + localeObj = dataPtr->literals[LIT_GMT]; + } + return localeObj; +} +/* + *---------------------------------------------------------------------- + */ +static Tcl_Obj * +ClockGetSystemLocale( + ClientData clientData, /* Opaque pointer to literal pool, etc. */ + Tcl_Interp *interp) /* Tcl interpreter */ +{ + ClockClientData *dataPtr = clientData; + Tcl_Obj **literals; + + /* if known (cached) - return now */ + if (dataPtr->SystemLocale != NULL) { + return dataPtr->SystemLocale; + } + + literals = dataPtr->literals; + + if (Tcl_EvalObjv(interp, 1, &literals[LIT_GETSYSTEMLOCALE], 0) != TCL_OK) { + return NULL; + } + Tcl_SetObjRef(dataPtr->SystemLocale, Tcl_GetObjResult(interp)); + return dataPtr->SystemLocale; +} +/* + *---------------------------------------------------------------------- + */ +static Tcl_Obj * +ClockSetupLocale( + ClientData clientData, /* Opaque pointer to literal pool, etc. */ + Tcl_Interp *interp, /* Tcl interpreter */ + Tcl_Obj *localeObj) +{ + ClockClientData *dataPtr = clientData; + Tcl_Obj **literals = dataPtr->literals; + Tcl_Obj *callargs[2]; + + if (localeObj == NULL || localeObj == dataPtr->SystemLocale) { + if (dataPtr->SystemLocale == NULL) { + return ClockGetSystemLocale(clientData, interp); + } + return dataPtr->SystemLocale; + } + +#if 0 + /* if cached (if already setup this one) */ + if ( dataPtr->LastSetupTimeZone != NULL + && ( localeObj == dataPtr->LastSetupTimeZone + || timezoneObj == dataPtr->LastUnnormSetupTimeZone + ) + ) { + return dataPtr->LastSetupTimeZone; + } + + /* differentiate GMT and system zones, because used often and already set */ + timezoneObj = NormTimezoneObj(dataPtr, timezoneObj); + if ( timezoneObj == dataPtr->GMTSetupTimeZone + || timezoneObj == dataPtr->SystemTimeZone + || timezoneObj == dataPtr->AnySetupTimeZone + ) { + return timezoneObj; + } + +#endif + callargs[0] = literals[LIT_SETUPLOCALE]; + callargs[1] = localeObj; + + if (Tcl_EvalObjv(interp, 2, callargs, 0) == TCL_OK) { + return localeObj; // dataPtr->CurrentLocale; + } + return NULL; +} +/* + *---------------------------------------------------------------------- * * ClockConvertlocaltoutcObjCmd -- * @@ -2440,11 +2550,7 @@ _ClockParseFmtScnArgs( * Extract values for the keywords. */ - resOpts->formatObj = NULL; - resOpts->localeObj = NULL; - resOpts->timezoneObj = NULL; - resOpts->baseObj = NULL; - resOpts->flags = 0; + memset(resOpts, 0, sizeof(*resOpts)); for (i = 2; i < objc; i+=2) { if (Tcl_GetIndexFromObj(interp, objv[i], options[forScan], "option", 0, &optionIndex) != TCL_OK) { @@ -2488,6 +2594,9 @@ _ClockParseFmtScnArgs( resOpts->timezoneObj = litPtr[LIT_GMT]; } + resOpts->clientData = clientData; + resOpts->interp = interp; + return TCL_OK; } @@ -2562,7 +2671,7 @@ ClockParseformatargsObjCmd( * Return options as a list. */ - Tcl_SetObjResult(interp, Tcl_NewListObj(3, (Tcl_Obj**)&resOpts)); + Tcl_SetObjResult(interp, Tcl_NewListObj(3, (Tcl_Obj**)&resOpts.formatObj)); return TCL_OK; } @@ -2632,13 +2741,19 @@ ClockScanObjCmd( } } - /* Get the data for time changes in the given zone */ + /* Setup timezone and locale */ opts.timezoneObj = ClockSetupTimeZone(clientData, interp, opts.timezoneObj); if (opts.timezoneObj == NULL) { return TCL_ERROR; } + opts.localeObj = ClockSetupLocale(clientData, interp, opts.localeObj); + if (opts.localeObj == NULL) { + return TCL_ERROR; + } + + ClockInitDateInfo(info); yydate.tzName = NULL; diff --git a/generic/tclClockFmt.c b/generic/tclClockFmt.c index ad04e4b..17181d9 100644 --- a/generic/tclClockFmt.c +++ b/generic/tclClockFmt.c @@ -454,32 +454,170 @@ Tcl_GetClockFrmScnFromObj( return fss; } + +static int +LocaleListSearch(ClockFmtScnCmdArgs *opts, + DateInfo *info, const char * mcKey, int *val) +{ + Tcl_Obj *callargs[4] = {NULL, NULL, NULL, NULL}, **lstv; + int i, lstc; + Tcl_Obj *valObj = NULL; + int ret = TCL_RETURN; + + /* get msgcat value */ + TclNewLiteralStringObj(callargs[0], "::msgcat::mcget"); + TclNewLiteralStringObj(callargs[1], "::tcl::clock"); + callargs[2] = opts->localeObj; + if (opts->localeObj == NULL) { + TclNewLiteralStringObj(callargs[1], "c"); + } + callargs[3] = Tcl_NewStringObj(mcKey, -1); -#define AllocTokenInChain(tok, chain, tokCnt) \ - if (++(tok) >= (chain) + (tokCnt)) { \ - (char *)(chain) = ckrealloc((char *)(chain), \ - (tokCnt + CLOCK_MIN_TOK_CHAIN_BLOCK_SIZE) * sizeof(*(tok))); \ - if ((chain) == NULL) { goto done; }; \ - (tok) = (chain) + (tokCnt); \ - (tokCnt) += CLOCK_MIN_TOK_CHAIN_BLOCK_SIZE; \ - } \ - memset(tok, 0, sizeof(*(tok))); + for (i = 0; i < 4; i++) { + Tcl_IncrRefCount(callargs[i]); + } + if (Tcl_EvalObjv(opts->interp, 4, callargs, 0) != TCL_OK) { + goto done; + } + + Tcl_InitObjRef(valObj, Tcl_GetObjResult(opts->interp)); + + /* is a list */ + if (TclListObjGetElements(opts->interp, valObj, &lstc, &lstv) != TCL_OK) { + goto done; + } + + /* search in list */ + for (i = 0; i < lstc; i++) { + const char *s = TclGetString(lstv[i]); + int l = lstv[i]->length; + if ( l <= info->dateEnd - yyInput + && strncasecmp(yyInput, s, l) == 0 + ) { + *val = i; + yyInput += l; + break; + } + } + + ret = TCL_OK; + /* if not found */ + if (i >= lstc) { + ret = TCL_ERROR; + } + +done: + + Tcl_UnsetObjRef(valObj); + + for (i = 0; i < 4; i++) { + Tcl_UnsetObjRef(callargs[i]); + } + + return ret; +} + +static int +StaticListSearch(ClockFmtScnCmdArgs *opts, + DateInfo *info, const char **lst, int *val) +{ + int len; + const char **s = lst; + while (*s != NULL) { + len = strlen(*s); + if ( len <= info->dateEnd - yyInput + && strncasecmp(yyInput, *s, len) == 0 + ) { + *val = (s - lst); + yyInput += len; + break; + } + s++; + } + if (*s == NULL) { + return TCL_ERROR; + } + + return TCL_OK; +}; + +static int +ClockScnToken_Month_Proc(ClockFmtScnCmdArgs *opts, + DateInfo *info, ClockScanToken *tok) +{ + /* + static const char * months[] = { + /* full * / + "January", "February", "March", + "April", "May", "June", + "July", "August", "September", + "October", "November", "December", + /* abbr * / + "Jan", "Feb", "Mar", "Apr", "May", "Jun", + "Jul", "Aug", "Sep", "Oct", "Nov", "Dec", + NULL + }; + int val; + if (StaticListSearch(opts, info, months, &val) != TCL_OK) { + return TCL_ERROR; + } + yyMonth = (val % 12) + 1; + return TCL_OK; + */ + + int val; + int ret = LocaleListSearch(opts, info, "MONTHS_FULL", &val); + if (ret != TCL_OK) { + if (ret == TCL_RETURN) { + return ret; + } + ret = LocaleListSearch(opts, info, "MONTHS_ABBREV", &val); + if (ret != TCL_OK) { + return ret; + } + } + + yyMonth = val + 1; + return TCL_OK; + +} + + +static int +ClockScnToken_LocaleListMatcher_Proc(ClockFmtScnCmdArgs *opts, + DateInfo *info, ClockScanToken *tok) +{ + int val; + + int ret = LocaleListSearch(opts, info, (char *)tok->map->data, &val); + if (ret != TCL_OK) { + return ret; + } + + *(time_t *)(((char *)info) + tok->map->offs) = val; + + return TCL_OK; +} -const char *ScnSTokenMapChars = - "dmyYHMSJs"; + +static const char *ScnSTokenMapIndex = + "dmbyYHMSJCs"; static ClockScanTokenMap ScnSTokenMap[] = { - /* %d */ + /* %d %e */ {CTOKT_DIGIT, CLF_DATE, 1, 2, TclOffset(DateInfo, date.dayOfMonth), NULL}, /* %m */ {CTOKT_DIGIT, CLF_DATE, 1, 2, TclOffset(DateInfo, date.month), NULL}, + /* %b %B %h */ + {CTOKT_PARSER, CLF_DATE, 0, 0, 0, + ClockScnToken_Month_Proc}, /* %y */ {CTOKT_DIGIT, CLF_DATE, 1, 2, TclOffset(DateInfo, date.year), NULL}, /* %Y */ - {CTOKT_DIGIT, CLF_DATE, 1, 4, TclOffset(DateInfo, date.year), + {CTOKT_DIGIT, CLF_DATE | CLF_CENTURY, 1, 4, TclOffset(DateInfo, date.year), NULL}, /* %H */ {CTOKT_DIGIT, CLF_TIME, 1, 2, TclOffset(DateInfo, date.hour), @@ -493,11 +631,41 @@ static ClockScanTokenMap ScnSTokenMap[] = { /* %J */ {CTOKT_DIGIT, CLF_DATE | CLF_JULIANDAY, 1, 0xffff, TclOffset(DateInfo, date.julianDay), NULL}, + /* %C */ + {CTOKT_DIGIT, CLF_DATE | CLF_CENTURY, 1, 2, TclOffset(DateInfo, dateCentury), + NULL}, /* %s */ {CTOKT_DIGIT, CLF_LOCALSEC | CLF_SIGNED, 1, 0xffff, TclOffset(DateInfo, date.localSeconds), NULL}, }; -const char *ScnSpecTokenMapChars = +static const char *ScnSTokenWrapMapIndex[2] = { + "eBh", + "dbb" +}; + +static const char *ScnETokenMapIndex = + ""; +static ClockScanTokenMap ScnETokenMap[] = { + {0, 0, 0} +}; +static const char *ScnETokenWrapMapIndex[2] = { + "", + "" +}; + +static const char *ScnOTokenMapIndex = + "d"; +static ClockScanTokenMap ScnOTokenMap[] = { + /* %Od %Oe */ + {CTOKT_PARSER, CLF_DATE, 0, 0, TclOffset(DateInfo, date.dayOfMonth), + ClockScnToken_LocaleListMatcher_Proc, "LOCALE_NUMERALS"}, +}; +static const char *ScnOTokenWrapMapIndex[2] = { + "e", + "d" +}; + +static const char *ScnSpecTokenMapIndex = " "; static ClockScanTokenMap ScnSpecTokenMap[] = { {CTOKT_SPACE, 0, 1, 0xffff, 0, @@ -508,6 +676,17 @@ static ClockScanTokenMap ScnWordTokenMap = { CTOKT_WORD, 0, 1, 0, 0, NULL }; + + +#define AllocTokenInChain(tok, chain, tokCnt) \ + if (++(tok) >= (chain) + (tokCnt)) { \ + (char *)(chain) = ckrealloc((char *)(chain), \ + (tokCnt + CLOCK_MIN_TOK_CHAIN_BLOCK_SIZE) * sizeof(*(tok))); \ + if ((chain) == NULL) { goto done; }; \ + (tok) = (chain) + (tokCnt); \ + (tokCnt) += CLOCK_MIN_TOK_CHAIN_BLOCK_SIZE; \ + } \ + memset(tok, 0, sizeof(*(tok))); /* *---------------------------------------------------------------------- @@ -546,10 +725,14 @@ ClockGetOrParseScanFormat( fss->scnTok = tok = ckalloc(sizeof(*tok) * CLOCK_MIN_TOK_CHAIN_BLOCK_SIZE); memset(tok, 0, sizeof(*(tok))); - strFmt = TclGetString(formatObj); - for (e = p = strFmt, e += formatObj->length; p != e; p++) { + strFmt = HashEntry4FmtScn(fss)->key.string; + for (e = p = strFmt, e += strlen(strFmt); p != e; p++) { switch (*p) { case '%': + if (1) { + ClockScanTokenMap * maps = ScnSTokenMap; + const char *mapIndex = ScnSTokenMapIndex, + **wrapIndex = ScnSTokenWrapMapIndex; if (p+1 >= e) { goto word_tok; } @@ -565,43 +748,62 @@ ClockGetOrParseScanFormat( continue; break; case 'E': - goto ext_tok_E; + maps = ScnETokenMap, + mapIndex = ScnETokenMapIndex, + wrapIndex = ScnETokenWrapMapIndex; + p++; break; case 'O': - goto ext_tok_O; + maps = ScnOTokenMap, + mapIndex = ScnOTokenMapIndex, + wrapIndex = ScnOTokenWrapMapIndex; + p++; break; - default: - cp = strchr(ScnSTokenMapChars, *p); + } + /* search direct index */ + cp = strchr(mapIndex, *p); + if (!cp || *cp == '\0') { + /* search wrapper index (multiple chars for same token) */ + cp = strchr(wrapIndex[0], *p); if (!cp || *cp == '\0') { p--; goto word_tok; } - tok->map = &ScnSTokenMap[cp - ScnSTokenMapChars]; - /* calculate look ahead value by standing together tokens */ - if (tok > fss->scnTok) { - ClockScanToken *prevTok = tok - 1; - unsigned int lookAhead = tok->map->minSize; - - while (prevTok >= fss->scnTok) { - if (prevTok->map->type != tok->map->type) { - break; - } - prevTok->lookAhead += lookAhead; - prevTok--; + cp = strchr(mapIndex, wrapIndex[1][cp - wrapIndex[0]]); + if (!cp || *cp == '\0') { /* unexpected, but ... */ + #ifdef DEBUG + Tcl_Panic("token \"%c\" has no map in wrapper resolver", *p); + #endif + p--; + goto word_tok; + } + } + tok->map = &ScnSTokenMap[cp - mapIndex]; + tok->tokWord.start = p; + /* calculate look ahead value by standing together tokens */ + if (tok > fss->scnTok) { + ClockScanToken *prevTok = tok - 1; + unsigned int lookAhead = tok->map->minSize; + + while (prevTok >= fss->scnTok) { + if (prevTok->map->type != tok->map->type) { + break; } + prevTok->lookAhead += lookAhead; + prevTok--; } - /* next token */ - AllocTokenInChain(tok, fss->scnTok, fss->scnTokC); - break; } + /* next token */ + AllocTokenInChain(tok, fss->scnTok, fss->scnTokC); + } break; case ' ': - cp = strchr(ScnSpecTokenMapChars, *p); + cp = strchr(ScnSpecTokenMapIndex, *p); if (!cp || *cp == '\0') { p--; goto word_tok; } - tok->map = &ScnSpecTokenMap[cp - ScnSpecTokenMapChars]; + tok->map = &ScnSpecTokenMap[cp - ScnSpecTokenMapIndex]; AllocTokenInChain(tok, fss->scnTok, fss->scnTokC); break; default: @@ -619,20 +821,10 @@ word_tok: } continue; } + break; } continue; - -ext_tok_E: - - /*******************/ - continue; - -ext_tok_O: - - /*******************/ - continue; - } done: @@ -677,17 +869,20 @@ ClockScan( } } info->dateStart = yyInput = p; + info->dateEnd = end; /* parse string */ for (; tok->map != NULL; tok++) { map = tok->map; /* bypass spaces at begin of input before parsing each token */ - if (!(opts->flags & CLF_STRICT) && map->type != CTOKT_SPACE) { + if ( !(opts->flags & CLF_STRICT) + && (map->type != CTOKT_SPACE && map->type != CTOKT_WORD) + ) { while (p < end && isspace(UCHAR(*p))) { p++; } - yyInput = p; } + yyInput = p; switch (map->type) { case CTOKT_DIGIT: @@ -753,6 +948,20 @@ ClockScan( flags |= map->flags; } break; + case CTOKT_PARSER: + switch (map->parser(opts, info, tok)) { + case TCL_OK: + break; + case TCL_RETURN: + goto done; + break; + default: + goto error; + break; + }; + p = yyInput; + flags |= map->flags; + break; case CTOKT_SPACE: /* at least one space in strict mode */ if (opts->flags & CLF_STRICT) { @@ -803,10 +1012,14 @@ ClockScan( info->flags |= CLF_INVALIDATE_SECONDS|CLF_INVALIDATE_JULIANDAY; if (yyYear < 100) { - if (yyYear >= dataPtr->yearOfCenturySwitch) { - yyYear -= 100; + if (!(flags & CLF_CENTURY)) { + if (yyYear >= dataPtr->yearOfCenturySwitch) { + yyYear -= 100; + } + yyYear += dataPtr->currentYearCentury; + } else { + yyYear += info->dateCentury * 100; } - yyYear += dataPtr->currentYearCentury; } yydate.era = CE; } diff --git a/generic/tclDate.h b/generic/tclDate.h index 2010178..d97cd3c 100644 --- a/generic/tclDate.h +++ b/generic/tclDate.h @@ -36,6 +36,24 @@ #define CLF_INVALIDATE_SECONDS (1 << 8) /* assemble localSeconds (and seconds at end) */ /* + * Primitives to safe set, reset and free references. + */ + +#define Tcl_UnsetObjRef(obj) \ + if (obj != NULL) { Tcl_DecrRefCount(obj); obj = NULL; } +#define Tcl_InitObjRef(obj, val) \ + obj = val; if (obj) { Tcl_IncrRefCount(obj); } +#define Tcl_SetObjRef(obj, val) \ +if (1) { \ + Tcl_Obj *nval = val; \ + if (obj != nval) { \ + Tcl_Obj *prev = obj; \ + Tcl_InitObjRef(obj, nval); \ + if (prev != NULL) { Tcl_DecrRefCount(prev); }; \ + } \ +} + +/* * Structure containing the fields used in [clock format] and [clock scan] */ @@ -79,6 +97,7 @@ typedef struct TclDateFields { typedef struct DateInfo { const char *dateStart; const char *dateInput; + const char *dateEnd; TclDateFields date; @@ -110,6 +129,8 @@ typedef struct DateInfo { time_t dateDigitCount; + time_t dateCentury; + Tcl_Obj* messages; /* Error messages */ const char* separatrix; /* String separating messages */ } DateInfo; @@ -157,6 +178,9 @@ ClockInitDateInfo(DateInfo *info) { #define CLF_STRICT (1 << 8) typedef struct ClockFmtScnCmdArgs { + ClientData clientData, /* Opaque pointer to literal pool, etc. */ + Tcl_Interp *interp, /* Tcl interpreter */ + Tcl_Obj *formatObj; /* Format */ Tcl_Obj *localeObj; /* Name of the locale where the time will be expressed. */ Tcl_Obj *timezoneObj; /* Default time zone in which the time will be expressed */ @@ -233,6 +257,7 @@ typedef struct ClockScanToken ClockScanToken; typedef int ClockScanTokenProc( + ClockFmtScnCmdArgs *opts, DateInfo *info, ClockScanToken *tok); @@ -241,10 +266,11 @@ typedef int ClockScanTokenProc( #define CLF_JULIANDAY (1 << 3) #define CLF_TIME (1 << 4) #define CLF_LOCALSEC (1 << 5) +#define CLF_CENTURY (1 << 6) #define CLF_SIGNED (1 << 8) typedef enum _CLCKTOK_TYPE { - CTOKT_DIGIT = 1, CTOKT_SPACE, CTOKT_WORD + CTOKT_DIGIT = 1, CTOKT_PARSER, CTOKT_SPACE, CTOKT_WORD } CLCKTOK_TYPE; typedef struct ClockFmtScnStorage ClockFmtScnStorage; @@ -260,6 +286,7 @@ typedef struct ClockScanTokenMap { unsigned short int maxSize; unsigned short int offs; ClockScanTokenProc *parser; + void *data; } ClockScanTokenMap; typedef struct ClockScanToken { @@ -271,6 +298,9 @@ typedef struct ClockScanToken { } tokWord; } ClockScanToken; +#define ClockScnTokenChar(tok) \ + *tok->tokWord.start; + typedef struct ClockFmtScnStorage { int objRefCount; /* Reference count shared across threads */ ClockScanToken *scnTok; diff --git a/library/msgcat/msgcat.tcl b/library/msgcat/msgcat.tcl index 928474d..7f23568 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.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.0 @@ -225,6 +225,56 @@ proc msgcat::mc {src args} { } } +# msgcat::mcget -- +# +# Find the translation for the given string based on the given +# locale setting. Check the given 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: +# 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::mcget {ns loc src args} { + variable Msgs + + if {$loc eq {C}} { + set loclist [PackagePreferences $ns] + } else { + variable PackageConfig + # if {![dict exists $PackageConfig $ns $loc]} { + # set loc [mclocale] + # } + set loclist [dict get $PackageConfig locales $ns $loc] + } + for {set nscur $ns} {$nscur != ""} {set nscur [namespace parent $nscur]} { + foreach loc $loclist { + if {[dict exists $Msgs $nscur $loc $src]} { + if {[llength $args]} { + return [format [dict get $Msgs $nscur $loc $src] {*}$args] + } else { + return [dict get $Msgs $nscur $loc $src] + } + } + } + } + # call package local or default unknown command + set args [linsert $args 0 $loclist $src] + switch -exact -- [Invoke unknowncmd $args $ns result 1] { + 0 { return [uplevel 1 [linsert $args 0 [namespace origin mcunknown]]] } + 1 { return [DefaultUnknown {*}$args] } + default { return $result } + } +} + # msgcat::mcexists -- # # Check if a catalog item is set or if mc would invoke mcunknown. @@ -488,6 +538,7 @@ proc msgcat::mcpackagelocale {subcommand {locale ""}} { set loclist [GetPreferences $locale] set locale [lindex $loclist 0] dict set PackageConfig loclist $ns $loclist + dict set PackageConfig locales $ns $locale $loclist # load eventual missing locales set loadedLocales [dict get $PackageConfig loadedlocales $ns] @@ -521,6 +572,7 @@ proc msgcat::mcpackagelocale {subcommand {locale ""}} { [dict get $PackageConfig loadedlocales $ns] $LoadedLocales] dict unset PackageConfig loadedlocales $ns dict unset PackageConfig loclist $ns + dict unset PackageConfig locales $ns # unset keys not in global loaded locales if {[dict exists $Msgs $ns]} { diff --git a/tests-perf/clock.perf.tcl b/tests-perf/clock.perf.tcl index 9267684..fd24068 100644 --- a/tests-perf/clock.perf.tcl +++ b/tests-perf/clock.perf.tcl @@ -121,10 +121,17 @@ proc test-scan {{reptime 1000}} { # Scan : julian day with time (greedy match): {clock scan "2451545 102030" -format "%J%H%M%S"} + # Scan : century, lookup table month + {clock scan {1970 Jan 2} -format {%C%y %b %d} -locale en -gmt 1} + # Scan : century, lookup table month and day + {clock scan {1970 Jan 02} -format {%C%y %b %Od} -locale en -gmt 1} + + break + # Scan : zone only {clock scan "CET" -format "%z"} {clock scan "EST" -format "%z"} - #{**STOP** : Wed Nov 25 01:00:00 CET 2015} + {**STOP** : Wed Nov 25 01:00:00 CET 2015} # # Scan : long format test (allock chain) # {clock scan "25.11.2015" -format "%d.%m.%Y %d.%m.%Y %d.%m.%Y %d.%m.%Y %d.%m.%Y %d.%m.%Y %d.%m.%Y %d.%m.%Y" -base 0 -gmt 1} @@ -194,8 +201,8 @@ proc test-other {{reptime 1000}} { proc test {{reptime 1000}} { puts "" - #test-scan $reptime - test-freescan $reptime + test-scan $reptime + #test-freescan $reptime test-other $reptime puts \n**OK** -- cgit v0.12 From a4c93085d2edbf7fd16083ac2766eae0c57e6278 Mon Sep 17 00:00:00 2001 From: sebres Date: Tue, 10 Jan 2017 22:25:20 +0000 Subject: l10n (with caching) implemented, msgcat package optimized, code review, etc. --- generic/tclClock.c | 448 +++++++++++++++++++++++++++++----------------- generic/tclClockFmt.c | 193 +++++++++++--------- generic/tclDate.h | 45 ++++- library/clock.tcl | 79 +++++--- library/msgcat/msgcat.tcl | 113 +++++++++--- tests-perf/clock.perf.tcl | 31 +++- tests/clock.test | 8 +- 7 files changed, 608 insertions(+), 309 deletions(-) diff --git a/generic/tclClock.c b/generic/tclClock.c index 1e9abba..166a4b3 100644 --- a/generic/tclClock.c +++ b/generic/tclClock.c @@ -59,8 +59,7 @@ typedef enum ClockLiteral { LIT_TZDATA, LIT_GETSYSTEMTIMEZONE, LIT_SETUPTIMEZONE, - LIT_GETSYSTEMLOCALE, - LIT_SETUPLOCALE, + LIT_MCGET, LIT_TCL_CLOCK, #if 0 LIT_FREESCAN, #endif @@ -83,13 +82,17 @@ static const char *const Literals[] = { "::tcl::clock::TZData", "::tcl::clock::GetSystemTimeZone", "::tcl::clock::SetupTimeZone", - "::tcl::clock::mclocale", - "::tcl::clock::EnterLocale", + "::msgcat::mcget", "::tcl::clock" #if 0 "::tcl::clock::FreeScan" #endif }; +/* Msgcat literals for exact match (mcKey) */ +CLOCK_LOCALE_LITERAL_ARRAY(MsgCtLiterals, ""); +/* Msgcat index literals prefixed with _IDX_, used for quick dictionary search */ +CLOCK_LOCALE_LITERAL_ARRAY(MsgCtLitIdxs, "_IDX_"); + static const char *const eras[] = { "CE", "BCE", NULL }; /* @@ -257,9 +260,10 @@ TclClockInit( data->refCount = 0; data->literals = ckalloc(LIT__END * sizeof(Tcl_Obj*)); for (i = 0; i < LIT__END; ++i) { - data->literals[i] = Tcl_NewStringObj(Literals[i], -1); - Tcl_IncrRefCount(data->literals[i]); + Tcl_InitObjRef(data->literals[i], Tcl_NewStringObj(Literals[i], -1)); } + data->mcLiterals = NULL; + data->mcLitIdxs = NULL; data->LastTZEpoch = 0; data->currentYearCentury = ClockDefaultYearCentury; data->yearOfCenturySwitch = ClockDefaultCenturySwitch; @@ -273,6 +277,12 @@ TclClockInit( data->LastSetupTimeZone = NULL; data->LastSetupTZData = NULL; + data->CurrentLocale = NULL; + data->CurrentLocaleDict = NULL; + data->LastUnnormUsedLocale = NULL; + data->LastUsedLocale = NULL; + data->LastUsedLocaleDict = NULL; + data->lastBase.timezoneObj = NULL; data->UTC2Local.timezoneObj = NULL; data->UTC2Local.tzName = NULL; @@ -323,6 +333,12 @@ ClockConfigureClear( Tcl_UnsetObjRef(data->LastSetupTimeZone); Tcl_UnsetObjRef(data->LastSetupTZData); + Tcl_UnsetObjRef(data->CurrentLocale); + Tcl_UnsetObjRef(data->CurrentLocaleDict); + Tcl_UnsetObjRef(data->LastUnnormUsedLocale); + Tcl_UnsetObjRef(data->LastUsedLocale); + Tcl_UnsetObjRef(data->LastUsedLocaleDict); + Tcl_UnsetObjRef(data->lastBase.timezoneObj); Tcl_UnsetObjRef(data->UTC2Local.timezoneObj); Tcl_UnsetObjRef(data->UTC2Local.tzName); @@ -341,6 +357,18 @@ ClockDeleteCmdProc( for (i = 0; i < LIT__END; ++i) { Tcl_DecrRefCount(data->literals[i]); } + if (data->mcLiterals != NULL) { + for (i = 0; i < MCLIT__END; ++i) { + Tcl_DecrRefCount(data->mcLiterals[i]); + } + data->mcLiterals = NULL; + } + if (data->mcLitIdxs != NULL) { + for (i = 0; i < MCLIT__END; ++i) { + Tcl_DecrRefCount(data->mcLitIdxs[i]); + } + data->mcLitIdxs = NULL; + } ClockConfigureClear(data); @@ -355,9 +383,9 @@ ClockDeleteCmdProc( inline Tcl_Obj * NormTimezoneObj( ClockClientData *dataPtr, /* Client data containing literal pool */ - Tcl_Obj * timezoneObj) + Tcl_Obj *timezoneObj) { - const char * tz; + const char *tz; if ( timezoneObj == dataPtr->LastUnnormSetupTimeZone && dataPtr->LastSetupTimeZone != NULL ) { @@ -399,6 +427,208 @@ NormTimezoneObj( /* *---------------------------------------------------------------------- */ +static Tcl_Obj * +NormLocaleObj( + ClockClientData *dataPtr, /* Client data containing literal pool */ + Tcl_Obj *localeObj, + Tcl_Obj **mcDictObj) +{ + const char *loc; + if ( localeObj == NULL || localeObj == dataPtr->CurrentLocale + || localeObj == dataPtr->literals[LIT_C] + ) { + *mcDictObj = dataPtr->CurrentLocaleDict; + return dataPtr->CurrentLocale; + } + if ( localeObj == dataPtr->LastUsedLocale + || localeObj == dataPtr->LastUnnormUsedLocale + ) { + *mcDictObj = dataPtr->LastUsedLocaleDict; + return dataPtr->LastUsedLocale; + } + + loc = TclGetString(localeObj); + if (dataPtr->CurrentLocale != NULL && + (localeObj == dataPtr->CurrentLocale + || strcmp(loc, TclGetString(dataPtr->CurrentLocale)) == 0 + ) + ) { + *mcDictObj = dataPtr->CurrentLocaleDict; + localeObj = dataPtr->CurrentLocale; + } + else + if (dataPtr->LastUsedLocale != NULL && + (localeObj == dataPtr->LastUsedLocale + || strcmp(loc, TclGetString(dataPtr->LastUsedLocale)) == 0 + ) + ) { + *mcDictObj = dataPtr->LastUsedLocaleDict; + Tcl_SetObjRef(dataPtr->LastUnnormUsedLocale, localeObj); + localeObj = dataPtr->LastUsedLocale; + } + else + if ( + strcmp(loc, Literals[LIT_C]) == 0 + ) { + *mcDictObj = dataPtr->CurrentLocaleDict; + localeObj = dataPtr->CurrentLocale; + } + else + { + *mcDictObj = NULL; + } + return localeObj; +} + +/* + *---------------------------------------------------------------------- + */ +MODULE_SCOPE Tcl_Obj * +ClockMCDict(ClockFmtScnCmdArgs *opts) +{ + ClockClientData *dataPtr = opts->clientData; + Tcl_Obj *callargs[3]; + + /* if dict not yet retrieved */ + if (opts->mcDictObj == NULL) { + + /* if locale was not yet used */ + if ( !(opts->flags & CLF_LOCALE_USED) ) { + + opts->localeObj = NormLocaleObj(opts->clientData, + opts->localeObj, &opts->mcDictObj); + + if (opts->localeObj == NULL) { + Tcl_SetResult(opts->interp, + "locale not specified and no default locale set", TCL_STATIC); + Tcl_SetErrorCode(opts->interp, "CLOCK", "badOption", NULL); + return NULL; + } + opts->flags |= CLF_LOCALE_USED; + + /* check locale literals already available (on demand creation) */ + if (dataPtr->mcLiterals == NULL) { + int i; + dataPtr->mcLiterals = ckalloc(MCLIT__END * sizeof(Tcl_Obj*)); + for (i = 0; i < MCLIT__END; ++i) { + Tcl_InitObjRef(dataPtr->mcLiterals[i], + Tcl_NewStringObj(MsgCtLiterals[i], -1)); + } + } + } + + if (opts->mcDictObj == NULL) { + /* get msgcat dictionary - ::msgcat::mcget ::tcl::clock locale */ + callargs[0] = dataPtr->literals[LIT_MCGET]; + callargs[1] = dataPtr->literals[LIT_TCL_CLOCK]; + callargs[2] = opts->localeObj; + + if (Tcl_EvalObjv(opts->interp, 3, callargs, 0) != TCL_OK) { + return NULL; + } + + opts->mcDictObj = Tcl_GetObjResult(opts->interp); + if ( opts->localeObj == dataPtr->CurrentLocale ) { + Tcl_SetObjRef(dataPtr->CurrentLocaleDict, opts->mcDictObj); + } else { + Tcl_SetObjRef(dataPtr->LastUsedLocale, opts->localeObj); + Tcl_UnsetObjRef(dataPtr->LastUnnormUsedLocale); + Tcl_SetObjRef(dataPtr->LastUsedLocaleDict, opts->mcDictObj); + } + } + } + + return opts->mcDictObj; +} + +MODULE_SCOPE Tcl_Obj * +ClockMCGet( + ClockFmtScnCmdArgs *opts, + int mcKey) +{ + ClockClientData *dataPtr = opts->clientData; + + Tcl_Obj *valObj = NULL; + + if (opts->mcDictObj == NULL) { + ClockMCDict(opts); + if (opts->mcDictObj == NULL) + return NULL; + } + + Tcl_DictObjGet(opts->interp, opts->mcDictObj, + dataPtr->mcLiterals[mcKey], &valObj); + + return valObj; /* or NULL in obscure case if Tcl_DictObjGet failed */ +} + +MODULE_SCOPE Tcl_Obj * +ClockMCGetListIdxDict( + ClockFmtScnCmdArgs *opts, + int mcKey) +{ + ClockClientData *dataPtr = opts->clientData; + + Tcl_Obj *valObj = NULL; + + if (opts->mcDictObj == NULL) { + ClockMCDict(opts); + if (opts->mcDictObj == NULL) + return NULL; + } + + /* try to get indices dictionray, + * if not available - create from list */ + + if (Tcl_DictObjGet(NULL, opts->mcDictObj, + dataPtr->mcLitIdxs[mcKey], &valObj) != TCL_OK + ) { + Tcl_Obj **lstv, *intObj; + int i, lstc; + + if (dataPtr->mcLitIdxs == NULL) { + dataPtr->mcLitIdxs = ckalloc(MCLIT__END * sizeof(Tcl_Obj*)); + for (i = 0; i < MCLIT__END; ++i) { + Tcl_InitObjRef(dataPtr->mcLitIdxs[i], + Tcl_NewStringObj(MsgCtLitIdxs[i], -1)); + } + } + + if (Tcl_DictObjGet(opts->interp, opts->mcDictObj, + dataPtr->mcLiterals[mcKey], &valObj) != TCL_OK) { + return NULL; + }; + if (TclListObjGetElements(opts->interp, valObj, + &lstc, &lstv) != TCL_OK) { + return NULL; + }; + + valObj = Tcl_NewDictObj(); + for (i = 0; i < lstc; i++) { + intObj = Tcl_NewIntObj(i); + if (Tcl_DictObjPut(opts->interp, valObj, + lstv[i], intObj) != TCL_OK + ) { + Tcl_DecrRefCount(valObj); + Tcl_DecrRefCount(intObj); + return NULL; + } + }; + + if (Tcl_DictObjPut(opts->interp, opts->mcDictObj, + dataPtr->mcLitIdxs[mcKey], valObj) != TCL_OK + ) { + Tcl_DecrRefCount(valObj); + return NULL; + } + }; + + return valObj; +} + +/* + *---------------------------------------------------------------------- + */ static int ClockConfigureObjCmd( ClientData clientData, /* Client data containing literal pool */ @@ -410,23 +640,25 @@ ClockConfigureObjCmd( Tcl_Obj **litPtr = dataPtr->literals; static const char *const options[] = { - "-system-tz", "-setup-tz", "-clear", + "-system-tz", "-setup-tz", "-default-locale", + "-clear", "-year-century", "-century-switch", NULL }; enum optionInd { - CLOCK_SYSTEM_TZ, CLOCK_SETUP_TZ, CLOCK_CLEAR_CACHE, + CLOCK_SYSTEM_TZ, CLOCK_SETUP_TZ, CLOCK_CURRENT_LOCALE, + CLOCK_CLEAR_CACHE, CLOCK_YEAR_CENTURY, CLOCK_CENTURY_SWITCH, CLOCK_SETUP_GMT, CLOCK_SETUP_NOP }; int optionIndex; /* Index of an option. */ int i; - for (i = 1; i < objc; i+=2) { - if (Tcl_GetIndexFromObj(interp, objv[i], options, + for (i = 1; i < objc; i++) { + if (Tcl_GetIndexFromObj(interp, objv[i++], options, "option", 0, &optionIndex) != TCL_OK) { Tcl_SetErrorCode(interp, "CLOCK", "badOption", - Tcl_GetString(objv[i]), NULL); + Tcl_GetString(objv[i-1]), NULL); return TCL_ERROR; } switch (optionIndex) { @@ -434,24 +666,24 @@ ClockConfigureObjCmd( if (1) { /* validate current tz-epoch */ unsigned long lastTZEpoch = TzsetGetEpoch(); - if (i+1 < objc) { - if (dataPtr->SystemTimeZone != objv[i+1]) { - Tcl_SetObjRef(dataPtr->SystemTimeZone, objv[i+1]); + if (i < objc) { + if (dataPtr->SystemTimeZone != objv[i]) { + Tcl_SetObjRef(dataPtr->SystemTimeZone, objv[i]); Tcl_UnsetObjRef(dataPtr->SystemSetupTZData); } dataPtr->LastTZEpoch = lastTZEpoch; } - if (dataPtr->SystemTimeZone != NULL + if (i+1 >= objc && dataPtr->SystemTimeZone != NULL && dataPtr->LastTZEpoch == lastTZEpoch) { Tcl_SetObjResult(interp, dataPtr->SystemTimeZone); } } break; case CLOCK_SETUP_TZ: - if (i+1 < objc) { + if (i < objc) { /* differentiate GMT and system zones, because used often */ - Tcl_Obj *timezoneObj = NormTimezoneObj(dataPtr, objv[i+1]); - Tcl_SetObjRef(dataPtr->LastUnnormSetupTimeZone, objv[i+1]); + Tcl_Obj *timezoneObj = NormTimezoneObj(dataPtr, objv[i]); + Tcl_SetObjRef(dataPtr->LastUnnormSetupTimeZone, objv[i]); if (dataPtr->LastSetupTimeZone != timezoneObj) { Tcl_SetObjRef(dataPtr->LastSetupTimeZone, timezoneObj); Tcl_UnsetObjRef(dataPtr->LastSetupTZData); @@ -463,7 +695,7 @@ ClockConfigureObjCmd( } switch (optionIndex) { case CLOCK_SETUP_GMT: - if (i+1 < objc) { + if (i < objc) { if (dataPtr->GMTSetupTimeZone != timezoneObj) { Tcl_SetObjRef(dataPtr->GMTSetupTimeZone, timezoneObj); Tcl_UnsetObjRef(dataPtr->GMTSetupTZData); @@ -471,7 +703,7 @@ ClockConfigureObjCmd( } break; case CLOCK_SETUP_TZ: - if (i+1 < objc) { + if (i < objc) { if (dataPtr->AnySetupTimeZone != timezoneObj) { Tcl_SetObjRef(dataPtr->AnySetupTimeZone, timezoneObj); Tcl_UnsetObjRef(dataPtr->AnySetupTZData); @@ -480,35 +712,52 @@ ClockConfigureObjCmd( break; } } - if (dataPtr->LastSetupTimeZone != NULL) { + if (i+1 >= objc && dataPtr->LastSetupTimeZone != NULL) { Tcl_SetObjResult(interp, dataPtr->LastSetupTimeZone); } break; + case CLOCK_CURRENT_LOCALE: + if (i < objc) { + if (dataPtr->CurrentLocale != objv[i]) { + Tcl_SetObjRef(dataPtr->CurrentLocale, objv[i]); + Tcl_UnsetObjRef(dataPtr->CurrentLocaleDict); + } + } + if (i+1 >= objc && dataPtr->CurrentLocale != NULL) { + Tcl_SetObjResult(interp, dataPtr->CurrentLocale); + } + break; case CLOCK_YEAR_CENTURY: - if (i+1 < objc) { + if (i < objc) { int year; - if (TclGetIntFromObj(interp, objv[i+1], &year) != TCL_OK) { + if (TclGetIntFromObj(interp, objv[i], &year) != TCL_OK) { return TCL_ERROR; } dataPtr->currentYearCentury = year; - Tcl_SetObjResult(interp, objv[i+1]); + if (i+1 >= objc) { + Tcl_SetObjResult(interp, objv[i]); + } continue; - } - Tcl_SetObjResult(interp, - Tcl_NewIntObj(dataPtr->currentYearCentury)); + } + if (i+1 >= objc) { + Tcl_SetObjResult(interp, + Tcl_NewIntObj(dataPtr->currentYearCentury)); + } break; case CLOCK_CENTURY_SWITCH: - if (i+1 < objc) { + if (i < objc) { int year; - if (TclGetIntFromObj(interp, objv[i+1], &year) != TCL_OK) { + if (TclGetIntFromObj(interp, objv[i], &year) != TCL_OK) { return TCL_ERROR; } dataPtr->yearOfCenturySwitch = year; - Tcl_SetObjResult(interp, objv[i+1]); + Tcl_SetObjResult(interp, objv[i]); continue; - } - Tcl_SetObjResult(interp, - Tcl_NewIntObj(dataPtr->yearOfCenturySwitch)); + } + if (i+1 >= objc) { + Tcl_SetObjResult(interp, + Tcl_NewIntObj(dataPtr->yearOfCenturySwitch)); + } break; case CLOCK_CLEAR_CACHE: ClockConfigureClear(dataPtr); @@ -597,7 +846,7 @@ ClockGetSystemTimeZone( } Tcl_UnsetObjRef(dataPtr->SystemTimeZone); - Tcl_UnsetObjRef(data->SystemSetupTZData); + Tcl_UnsetObjRef(dataPtr->SystemSetupTZData); literals = dataPtr->literals; @@ -683,125 +932,6 @@ ClockFormatNumericTimeZone(int z) { } return Tcl_ObjPrintf("%c%02d%02d", sign, h, m); } - -/* - *---------------------------------------------------------------------- - */ -inline Tcl_Obj * -NormLocaleObj( - ClockClientData *dataPtr, /* Client data containing literal pool */ - Tcl_Obj *localeObj) -{ - const char * tz; - if ( localeObj == dataPtr->LastUnnormSetupLocale - && dataPtr->LastSetupLocale != NULL - ) { - return dataPtr->LastSetupLocale; - } - if ( localeObj == dataPtr->LastSetupLocale - || localeObj == dataPtr->literals[LIT_CLOCALE] - || localeObj == dataPtr->SystemLocale - || localeObj == dataPtr->AnySetupLocale - ) { - return localeObj; - } - - tz = TclGetString(localeObj); - if (dataPtr->AnySetupLocale != NULL && - (localeObj == dataPtr->AnySetupLocale - || strcmp(tz, TclGetString(dataPtr->AnySetupLocale)) == 0 - ) - ) { - localeObj = dataPtr->AnySetupLocale; - } - else - if (dataPtr->SystemLocale != NULL && - (localeObj == dataPtr->SystemLocale - || strcmp(tz, TclGetString(dataPtr->SystemLocale)) == 0 - ) - ) { - localeObj = dataPtr->SystemLocale; - } - else - if ( - strcmp(tz, Literals[LIT_GMT]) == 0 - ) { - localeObj = dataPtr->literals[LIT_GMT]; - } - return localeObj; -} -/* - *---------------------------------------------------------------------- - */ -static Tcl_Obj * -ClockGetSystemLocale( - ClientData clientData, /* Opaque pointer to literal pool, etc. */ - Tcl_Interp *interp) /* Tcl interpreter */ -{ - ClockClientData *dataPtr = clientData; - Tcl_Obj **literals; - - /* if known (cached) - return now */ - if (dataPtr->SystemLocale != NULL) { - return dataPtr->SystemLocale; - } - - literals = dataPtr->literals; - - if (Tcl_EvalObjv(interp, 1, &literals[LIT_GETSYSTEMLOCALE], 0) != TCL_OK) { - return NULL; - } - Tcl_SetObjRef(dataPtr->SystemLocale, Tcl_GetObjResult(interp)); - return dataPtr->SystemLocale; -} -/* - *---------------------------------------------------------------------- - */ -static Tcl_Obj * -ClockSetupLocale( - ClientData clientData, /* Opaque pointer to literal pool, etc. */ - Tcl_Interp *interp, /* Tcl interpreter */ - Tcl_Obj *localeObj) -{ - ClockClientData *dataPtr = clientData; - Tcl_Obj **literals = dataPtr->literals; - Tcl_Obj *callargs[2]; - - if (localeObj == NULL || localeObj == dataPtr->SystemLocale) { - if (dataPtr->SystemLocale == NULL) { - return ClockGetSystemLocale(clientData, interp); - } - return dataPtr->SystemLocale; - } - -#if 0 - /* if cached (if already setup this one) */ - if ( dataPtr->LastSetupTimeZone != NULL - && ( localeObj == dataPtr->LastSetupTimeZone - || timezoneObj == dataPtr->LastUnnormSetupTimeZone - ) - ) { - return dataPtr->LastSetupTimeZone; - } - - /* differentiate GMT and system zones, because used often and already set */ - timezoneObj = NormTimezoneObj(dataPtr, timezoneObj); - if ( timezoneObj == dataPtr->GMTSetupTimeZone - || timezoneObj == dataPtr->SystemTimeZone - || timezoneObj == dataPtr->AnySetupTimeZone - ) { - return timezoneObj; - } - -#endif - callargs[0] = literals[LIT_SETUPLOCALE]; - callargs[1] = localeObj; - - if (Tcl_EvalObjv(interp, 2, callargs, 0) == TCL_OK) { - return localeObj; // dataPtr->CurrentLocale; - } - return NULL; -} /* *---------------------------------------------------------------------- * @@ -2741,19 +2871,13 @@ ClockScanObjCmd( } } - /* Setup timezone and locale */ + /* Setup timezone (normalize object id needed and load TZ on demand) */ opts.timezoneObj = ClockSetupTimeZone(clientData, interp, opts.timezoneObj); if (opts.timezoneObj == NULL) { return TCL_ERROR; } - opts.localeObj = ClockSetupLocale(clientData, interp, opts.localeObj); - if (opts.localeObj == NULL) { - return TCL_ERROR; - } - - ClockInitDateInfo(info); yydate.tzName = NULL; diff --git a/generic/tclClockFmt.c b/generic/tclClockFmt.c index 17181d9..a3c7f20 100644 --- a/generic/tclClockFmt.c +++ b/generic/tclClockFmt.c @@ -454,45 +454,55 @@ Tcl_GetClockFrmScnFromObj( return fss; } - + +/* + * DetermineGreedySearchLen -- + * + * Determine min/max lengths as exact as possible (speed, greedy match) + * + */ +inline +void DetermineGreedySearchLen(ClockFmtScnCmdArgs *opts, + DateInfo *info, ClockScanToken *tok, int *minLen, int *maxLen) +{ + register const char*p = yyInput; + *minLen = 0; + *maxLen = info->dateEnd - p; + + /* if no tokens anymore */ + if (!(tok+1)->map) { + /* should match to end or first space */ + while (!isspace(UCHAR(*p)) && ++p < info->dateEnd) {}; + *minLen = p - yyInput; + } +} static int LocaleListSearch(ClockFmtScnCmdArgs *opts, - DateInfo *info, const char * mcKey, int *val) + DateInfo *info, int mcKey, int *val, + int minLen, int maxLen) { - Tcl_Obj *callargs[4] = {NULL, NULL, NULL, NULL}, **lstv; - int i, lstc; - Tcl_Obj *valObj = NULL; - int ret = TCL_RETURN; + Tcl_Obj **lstv; + int lstc, i, l; + const char *s; + Tcl_Obj *valObj; /* get msgcat value */ - TclNewLiteralStringObj(callargs[0], "::msgcat::mcget"); - TclNewLiteralStringObj(callargs[1], "::tcl::clock"); - callargs[2] = opts->localeObj; - if (opts->localeObj == NULL) { - TclNewLiteralStringObj(callargs[1], "c"); - } - callargs[3] = Tcl_NewStringObj(mcKey, -1); - - for (i = 0; i < 4; i++) { - Tcl_IncrRefCount(callargs[i]); - } - if (Tcl_EvalObjv(opts->interp, 4, callargs, 0) != TCL_OK) { - goto done; + valObj = ClockMCGet(opts, mcKey); + if (valObj == NULL) { + return TCL_ERROR; } - Tcl_InitObjRef(valObj, Tcl_GetObjResult(opts->interp)); - /* is a list */ if (TclListObjGetElements(opts->interp, valObj, &lstc, &lstv) != TCL_OK) { - goto done; + return TCL_ERROR; } /* search in list */ for (i = 0; i < lstc; i++) { - const char *s = TclGetString(lstv[i]); - int l = lstv[i]->length; - if ( l <= info->dateEnd - yyInput + s = TclGetString(lstv[i]); + l = lstv[i]->length; + if ( l >= minLen && l <= maxLen && strncasecmp(yyInput, s, l) == 0 ) { *val = i; @@ -501,21 +511,11 @@ LocaleListSearch(ClockFmtScnCmdArgs *opts, } } - ret = TCL_OK; /* if not found */ - if (i >= lstc) { - ret = TCL_ERROR; - } - -done: - - Tcl_UnsetObjRef(valObj); - - for (i = 0; i < 4; i++) { - Tcl_UnsetObjRef(callargs[i]); + if (i < lstc) { + return TCL_OK; } - - return ret; + return TCL_RETURN; } static int @@ -535,12 +535,34 @@ StaticListSearch(ClockFmtScnCmdArgs *opts, } s++; } - if (*s == NULL) { - return TCL_ERROR; + if (*s != NULL) { + return TCL_OK; } - - return TCL_OK; -}; + return TCL_RETURN; +} + +inline const char * +FindWordEnd( + ClockScanToken *tok, + register const char * p, const char * end) +{ + register const char *x = tok->tokWord.start; + if (x == tok->tokWord.end) { /* single char word */ + if (*p != *x) { + /* no match -> error */ + return NULL; + } + return ++p; + } + /* multi-char word */ + while (*p++ == *x++) { + if (x >= tok->tokWord.end || p >= end) { + /* no match -> error */ + return NULL; + } + }; + return p; +} static int ClockScnToken_Month_Proc(ClockFmtScnCmdArgs *opts, @@ -560,19 +582,26 @@ ClockScnToken_Month_Proc(ClockFmtScnCmdArgs *opts, }; int val; if (StaticListSearch(opts, info, months, &val) != TCL_OK) { - return TCL_ERROR; + return TCL_RETURN; } yyMonth = (val % 12) + 1; return TCL_OK; */ - int val; - int ret = LocaleListSearch(opts, info, "MONTHS_FULL", &val); + int ret, val; + int minLen; + int maxLen; + + DetermineGreedySearchLen(opts, info, tok, &minLen, &maxLen); + + ret = LocaleListSearch(opts, info, MCLIT_MONTHS_FULL, &val, + minLen, maxLen); if (ret != TCL_OK) { + /* if not found */ if (ret == TCL_RETURN) { - return ret; + ret = LocaleListSearch(opts, info, MCLIT_MONTHS_ABBREV, &val, + minLen, maxLen); } - ret = LocaleListSearch(opts, info, "MONTHS_ABBREV", &val); if (ret != TCL_OK) { return ret; } @@ -588,9 +617,14 @@ static int ClockScnToken_LocaleListMatcher_Proc(ClockFmtScnCmdArgs *opts, DateInfo *info, ClockScanToken *tok) { - int val; + int ret, val; + int minLen; + int maxLen; + + DetermineGreedySearchLen(opts, info, tok, &minLen, &maxLen); - int ret = LocaleListSearch(opts, info, (char *)tok->map->data, &val); + ret = LocaleListSearch(opts, info, (int)tok->map->data, &val, + minLen, maxLen); if (ret != TCL_OK) { return ret; } @@ -639,8 +673,8 @@ static ClockScanTokenMap ScnSTokenMap[] = { NULL}, }; static const char *ScnSTokenWrapMapIndex[2] = { - "eBh", - "dbb" + "eNBh", + "dmbb" }; static const char *ScnETokenMapIndex = @@ -654,11 +688,14 @@ static const char *ScnETokenWrapMapIndex[2] = { }; static const char *ScnOTokenMapIndex = - "d"; + "dm"; static ClockScanTokenMap ScnOTokenMap[] = { /* %Od %Oe */ {CTOKT_PARSER, CLF_DATE, 0, 0, TclOffset(DateInfo, date.dayOfMonth), - ClockScnToken_LocaleListMatcher_Proc, "LOCALE_NUMERALS"}, + ClockScnToken_LocaleListMatcher_Proc, (void *)MCLIT_LOCALE_NUMERALS}, + /* %Om */ + {CTOKT_PARSER, CLF_DATE, 0, 0, TclOffset(DateInfo, date.month), + ClockScnToken_LocaleListMatcher_Proc, (void *)MCLIT_LOCALE_NUMERALS}, }; static const char *ScnOTokenWrapMapIndex[2] = { "e", @@ -730,7 +767,7 @@ ClockGetOrParseScanFormat( switch (*p) { case '%': if (1) { - ClockScanTokenMap * maps = ScnSTokenMap; + ClockScanTokenMap * scnMap = ScnSTokenMap; const char *mapIndex = ScnSTokenMapIndex, **wrapIndex = ScnSTokenWrapMapIndex; if (p+1 >= e) { @@ -748,13 +785,13 @@ ClockGetOrParseScanFormat( continue; break; case 'E': - maps = ScnETokenMap, + scnMap = ScnETokenMap, mapIndex = ScnETokenMapIndex, wrapIndex = ScnETokenWrapMapIndex; p++; break; case 'O': - maps = ScnOTokenMap, + scnMap = ScnOTokenMap, mapIndex = ScnOTokenMapIndex, wrapIndex = ScnOTokenWrapMapIndex; p++; @@ -778,7 +815,7 @@ ClockGetOrParseScanFormat( goto word_tok; } } - tok->map = &ScnSTokenMap[cp - mapIndex]; + tok->map = &scnMap[cp - mapIndex]; tok->tokWord.start = p; /* calculate look ahead value by standing together tokens */ if (tok > fss->scnTok) { @@ -928,7 +965,7 @@ ClockScan( size = p - yyInput; if (size < map->minSize) { /* missing input -> error */ - goto error; + goto not_match; } /* string 2 number, put number into info structure by offset */ p = yyInput; x = p + size; @@ -953,10 +990,10 @@ ClockScan( case TCL_OK: break; case TCL_RETURN: - goto done; + goto not_match; break; default: - goto error; + goto done; break; }; p = yyInput; @@ -967,7 +1004,7 @@ ClockScan( if (opts->flags & CLF_STRICT) { if (!isspace(UCHAR(*p))) { /* unmatched -> error */ - goto error; + goto not_match; } p++; } @@ -976,21 +1013,13 @@ ClockScan( } break; case CTOKT_WORD: - x = tok->tokWord.start; - if (x == tok->tokWord.end) { /* single char word */ - if (*p != *x) { - /* no match -> error */ - goto error; - } - p++; - continue; - } - /* multi-char word */ - while (p < end && x < tok->tokWord.end && *p++ == *x++) {}; - if (x < tok->tokWord.end) { + x = FindWordEnd(tok, p, end); + if (!x) { /* no match -> error */ - goto error; + goto not_match; } + p = x; + continue; break; } } @@ -1002,7 +1031,7 @@ ClockScan( /* check end was reached */ if (p < end) { /* something after last token - wrong format */ - goto error; + goto not_match; } /* invalidate result */ @@ -1045,15 +1074,15 @@ ClockScan( overflow: - Tcl_SetObjResult(interp, Tcl_NewStringObj( - "integer value too large to represent", -1)); - Tcl_SetErrorCode(interp, "CLOCK", "integervalueTooLarge", NULL); + Tcl_SetResult(interp, "requested date too large to represent", + TCL_STATIC); + Tcl_SetErrorCode(interp, "CLOCK", "dateTooLarge", NULL); goto done; -error: +not_match: - Tcl_SetResult(interp, - "input string does not match supplied format", TCL_STATIC); + Tcl_SetResult(interp, "input string does not match supplied format", + TCL_STATIC); Tcl_SetErrorCode(interp, "CLOCK", "badInputString", NULL); done: diff --git a/generic/tclDate.h b/generic/tclDate.h index d97cd3c..1c51a02 100644 --- a/generic/tclDate.h +++ b/generic/tclDate.h @@ -35,6 +35,22 @@ #define CLF_INVALIDATE_JULIANDAY (1 << 7) /* assemble julianDay using year, month, etc. */ #define CLF_INVALIDATE_SECONDS (1 << 8) /* assemble localSeconds (and seconds at end) */ + +/* + * Enumeration of the msgcat literals used in [clock] + */ + +typedef enum ClockMsgCtLiteral { + MCLIT_MONTHS_FULL, MCLIT_MONTHS_ABBREV, + MCLIT_LOCALE_NUMERALS, + MCLIT__END +} ClockMsgCtLiteral; + +#define CLOCK_LOCALE_LITERAL_ARRAY(litarr, pref) static const char *const litarr[] = { \ + pref "MONTHS_FULL", pref "MONTHS_ABBREV", \ + pref "LOCALE_NUMERALS", \ +} + /* * Primitives to safe set, reset and free references. */ @@ -176,16 +192,19 @@ ClockInitDateInfo(DateInfo *info) { #define CLF_EXTENDED (1 << 4) #define CLF_STRICT (1 << 8) +#define CLF_LOCALE_USED (1 << 15) typedef struct ClockFmtScnCmdArgs { - ClientData clientData, /* Opaque pointer to literal pool, etc. */ - Tcl_Interp *interp, /* Tcl interpreter */ + ClientData clientData; /* Opaque pointer to literal pool, etc. */ + Tcl_Interp *interp; /* Tcl interpreter */ Tcl_Obj *formatObj; /* Format */ Tcl_Obj *localeObj; /* Name of the locale where the time will be expressed. */ Tcl_Obj *timezoneObj; /* Default time zone in which the time will be expressed */ Tcl_Obj *baseObj; /* Base (scan only) */ int flags; /* Flags control scanning */ + + Tcl_Obj *mcDictObj; /* Current dictionary of tcl::clock package for given localeObj*/ } ClockFmtScnCmdArgs; /* @@ -194,7 +213,11 @@ typedef struct ClockFmtScnCmdArgs { typedef struct ClockClientData { int refCount; /* Number of live references. */ - Tcl_Obj **literals; /* Pool of object literals. */ + Tcl_Obj **literals; /* Pool of object literals (common, locale independent). */ + Tcl_Obj **mcLiterals; /* Msgcat object literals with mc-keys for search with locale. */ + Tcl_Obj **mcLitIdxs; /* Msgcat object indices prefixed with _IDX_, + * used for quick dictionary search */ + /* Cache for current clock parameters, imparted via "configure" */ unsigned long LastTZEpoch; int currentYearCentury; @@ -208,6 +231,13 @@ typedef struct ClockClientData { Tcl_Obj *LastUnnormSetupTimeZone; Tcl_Obj *LastSetupTimeZone; Tcl_Obj *LastSetupTZData; + + Tcl_Obj *CurrentLocale; + Tcl_Obj *CurrentLocaleDict; + Tcl_Obj *LastUnnormUsedLocale; + Tcl_Obj *LastUsedLocale; + Tcl_Obj *LastUsedLocaleDict; + /* Cache for last base (last-second fast convert if base/tz not changed) */ struct { Tcl_Obj *timezoneObj; @@ -328,6 +358,15 @@ MODULE_SCOPE time_t ToSeconds(time_t Hours, time_t Minutes, MODULE_SCOPE int TclClockFreeScan(Tcl_Interp *interp, DateInfo *info); +/* tclClock.c module declarations */ + +MODULE_SCOPE Tcl_Obj * + ClockMCDict(ClockFmtScnCmdArgs *opts); +MODULE_SCOPE Tcl_Obj * + ClockMCGet(ClockFmtScnCmdArgs *opts, int mcKey); +MODULE_SCOPE Tcl_Obj * + ClockMCGetListIdxDict(ClockFmtScnCmdArgs *opts, int mcKey); + /* tclClockFmt.c module declarations */ MODULE_SCOPE ClockFmtScnStorage * diff --git a/library/clock.tcl b/library/clock.tcl index ebbecb9..b4632b1 100755 --- a/library/clock.tcl +++ b/library/clock.tcl @@ -289,8 +289,9 @@ proc ::tcl::clock::Initialize {} { # Default configuration - # configure -year-century 2000 \ - # -century-switch 38 + configure -default-locale [mclocale] + #configure -year-century 2000 \ + # -century-switch 38 # Translation table to map Windows TZI onto cities, so that the Olson # rules can apply. In some cases the mapping is ambiguous, so it's wise @@ -2105,6 +2106,51 @@ proc ::tcl::clock::MakeParseCodeFromFields { dateFields parseActions } { #---------------------------------------------------------------------- # +# GetSystemTimeZone -- +# +# Determines the system time zone, which is the default for the +# 'clock' command if no other zone is supplied. +# +# Parameters: +# None. +# +# Results: +# Returns the system time zone. +# +# Side effects: +# Stores the sustem time zone in engine configuration, since +# determining it may be an expensive process. +# +#---------------------------------------------------------------------- + +proc ::tcl::clock::GetSystemLocale {} { + if { $::tcl_platform(platform) ne {windows} } { + # On a non-windows platform, the 'system' locale is the same as + # the 'current' locale + + return [mclocale] + } + + # On a windows platform, the 'system' locale is adapted from the + # 'current' locale by applying the date and time formats from the + # Control Panel. First, load the 'current' locale if it's not yet + # loaded + + mcpackagelocale set [mclocale] + + # Make a new locale string for the system locale, and get the + # Control Panel information + + set locale [mclocale]_windows + if { ! [mcpackagelocale present $locale] } { + LoadWindowsDateTimeFormats $locale + } + + return $locale +} + +#---------------------------------------------------------------------- +# # EnterLocale -- # # Switch [mclocale] to a given locale if necessary @@ -2121,33 +2167,12 @@ proc ::tcl::clock::MakeParseCodeFromFields { dateFields parseActions } { #---------------------------------------------------------------------- proc ::tcl::clock::EnterLocale { locale } { - if { $locale eq {system} } { - if { $::tcl_platform(platform) ne {windows} } { - # On a non-windows platform, the 'system' locale is the same as - # the 'current' locale - - set locale current - } else { - # On a windows platform, the 'system' locale is adapted from the - # 'current' locale by applying the date and time formats from the - # Control Panel. First, load the 'current' locale if it's not yet - # loaded - - mcpackagelocale set [mclocale] - - # Make a new locale string for the system locale, and get the - # Control Panel information - - set locale [mclocale]_windows - if { ! [mcpackagelocale present $locale] } { - LoadWindowsDateTimeFormats $locale - } - } - } - if { $locale eq {current}} { + switch -- $locale system { + set locale [GetSystemLocale] + } current { set locale [mclocale] } - # Eventually load the locale + # Select the locale, eventually load it mcpackagelocale set $locale } diff --git a/library/msgcat/msgcat.tcl b/library/msgcat/msgcat.tcl index 7f23568..3fd2cdb 100644 --- a/library/msgcat/msgcat.tcl +++ b/library/msgcat/msgcat.tcl @@ -227,52 +227,61 @@ proc msgcat::mc {src args} { # msgcat::mcget -- # -# Find the translation for the given string based on the given -# locale setting. Check the given 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. +# Return the translation for the given string based on the given +# locale setting or the whole dictionary object of the package/locale. +# Searching of catalog is similar to "msgcat::mc". +# +# Contrary to "msgcat::mc" may additionally load a package catalog +# on demand. # # Arguments: -# src The string to translate. -# args Args to pass to the format command +# ns The package namespace (as catalog selector). +# loc The locale used for 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::mcget {ns loc src args} { +proc msgcat::mcget {ns loc args} { variable Msgs if {$loc eq {C}} { set loclist [PackagePreferences $ns] + set loc [lindex $loclist 0] } else { + set loc [string tolower $loc] variable PackageConfig - # if {![dict exists $PackageConfig $ns $loc]} { - # set loc [mclocale] - # } - set loclist [dict get $PackageConfig locales $ns $loc] + # get locales list for given locale (de_de -> {de_de de {}}) + if {[catch { + set loclist [dict get $PackageConfig locales $ns $loc] + }]} { + # lazy load catalog on demand + mcpackagelocale load $loc $ns + set loclist [dict get $PackageConfig locales $ns $loc] + } } + if {![llength $args]} { + # get whole catalog: + return [msgcat::Merge $ns $loclist] + } + set src [lindex $args 0] + # search translation for each locale (regarding parent namespaces) for {set nscur $ns} {$nscur != ""} {set nscur [namespace parent $nscur]} { foreach loc $loclist { if {[dict exists $Msgs $nscur $loc $src]} { - if {[llength $args]} { - return [format [dict get $Msgs $nscur $loc $src] {*}$args] + if {[llength $args] > 1} { + return [format [dict get $Msgs $nscur $loc $src] \ + {*}[lrange $args 1 end]] } else { return [dict get $Msgs $nscur $loc $src] } } } } - # call package local or default unknown command - set args [linsert $args 0 $loclist $src] - switch -exact -- [Invoke unknowncmd $args $ns result 1] { - 0 { return [uplevel 1 [linsert $args 0 [namespace origin mcunknown]]] } - 1 { return [DefaultUnknown {*}$args] } - default { return $result } - } + # get with package default locale + mcget $ns [lindex $loclist 0] {*}$args } # msgcat::mcexists -- @@ -465,6 +474,10 @@ proc msgcat::mcloadedlocales {subcommand} { # items, if the former locale was the default locale. # Returns the normalized set locale. # The default locale is taken, if locale is not given. +# load +# Load a package locale without set it (lazy loading from mcget). +# Returns the normalized set locale. +# The default locale is taken, if locale is not given. # get # Get the locale valid for this package. # isset @@ -492,7 +505,7 @@ proc msgcat::mcloadedlocales {subcommand} { # Results: # Empty string, if not stated differently for the subcommand -proc msgcat::mcpackagelocale {subcommand {locale ""}} { +proc msgcat::mcpackagelocale {subcommand {locale ""} {ns ""}} { # todo: implement using an ensemble variable Loclist variable LoadedLocales @@ -512,7 +525,9 @@ proc msgcat::mcpackagelocale {subcommand {locale ""}} { } set locale [string tolower $locale] } - set ns [uplevel 1 {::namespace current}] + if {$ns eq ""} { + set ns [uplevel 1 {::namespace current}] + } switch -exact -- $subcommand { get { return [lindex [PackagePreferences $ns] 0] } @@ -520,7 +535,7 @@ proc msgcat::mcpackagelocale {subcommand {locale ""}} { loaded { return [PackageLocales $ns] } present { return [expr {$locale in [PackageLocales $ns]} ]} isset { return [dict exists $PackageConfig loclist $ns] } - set { # set a package locale or add a package locale + set - load { # set a package locale or add a package locale # Copy the default locale if no package locale set so far if {![dict exists $PackageConfig loclist $ns]} { @@ -530,18 +545,21 @@ proc msgcat::mcpackagelocale {subcommand {locale ""}} { # Check if changed set loclist [dict get $PackageConfig loclist $ns] - if {! [info exists locale] || $locale eq [lindex $loclist 0] } { + if {[llength [info level 0]] == 2 || $locale eq [lindex $loclist 0] } { return [lindex $loclist 0] } # Change loclist set loclist [GetPreferences $locale] set locale [lindex $loclist 0] - dict set PackageConfig loclist $ns $loclist - dict set PackageConfig locales $ns $locale $loclist + if {$subcommand eq {set}} { + # set loclist + dict set PackageConfig loclist $ns $loclist + } # load eventual missing locales set loadedLocales [dict get $PackageConfig loadedlocales $ns] + dict set PackageConfig locales $ns $locale $loclist if {$locale in $loadedLocales} { return $locale } set loadLocales [ListComplement $loadedLocales $loclist] dict set PackageConfig loadedlocales $ns\ @@ -899,6 +917,39 @@ proc msgcat::Load {ns locales {callbackonly 0}} { return $x } +# msgcat::Merge -- +# +# Merge message catalog dictionaries to one dictionary. +# +# Arguments: +# ns Namespace (equal package) to load the message catalog. +# locales List of locales to merge. +# +# Results: +# Returns the merged dictionary of message catalogs. +proc msgcat::Merge {ns locales} { + variable Merged + if {![catch { + set mrgcat [dict get $Merged $ns [set loc [lindex $locales 0]]] + }]} { + return $mrgcat + } + variable Msgs + # Merge sequential locales (in reverse order, e. g. {} -> en -> en_en): + if {[llength $locales] > 1} { + set mrgcat [msgcat::Merge $ns [lrange $locales 1 end]] + catch { + set mrgcat [dict merge $mrgcat [dict get $Msgs $ns $loc]] + } + } else { + catch { + set mrgcat [dict get $Msgs $ns $loc] + } + } + dict set Merged $ns $loc $mrgcat + return $mrgcat +} + # msgcat::Invoke -- # # Invoke a set of registered callbacks. @@ -971,6 +1022,7 @@ proc msgcat::Invoke {index arglist {ns ""} {resultname ""} {failerror 0}} { proc msgcat::mcset {locale src {dest ""}} { variable Msgs + variable Merged if {[llength [info level 0]] == 3} { ;# dest not specified set dest $src } @@ -980,6 +1032,7 @@ proc msgcat::mcset {locale src {dest ""}} { set locale [string tolower $locale] dict set Msgs $ns $locale $src $dest + dict unset Merged $ns return $dest } @@ -1019,6 +1072,7 @@ proc msgcat::mcflset {src {dest ""}} { proc msgcat::mcmset {locale pairs} { variable Msgs + variable Merged set length [llength $pairs] if {$length % 2} { @@ -1032,6 +1086,7 @@ proc msgcat::mcmset {locale pairs} { foreach {src dest} $pairs { dict set Msgs $ns $locale $src $dest } + dict unset Merged $ns return [expr {$length / 2}] } diff --git a/tests-perf/clock.perf.tcl b/tests-perf/clock.perf.tcl index fd24068..a005648 100644 --- a/tests-perf/clock.perf.tcl +++ b/tests-perf/clock.perf.tcl @@ -19,10 +19,11 @@ ## set testing defaults: set ::env(TCL_TZ) :CET -## warm-up (load clock.tcl, system zones, etc.): +## warm-up (load clock.tcl, system zones, locales, etc.): clock scan "" -gmt 1 clock scan "" clock scan "" -timezone :CET +clock scan "" -format "" -locale en ## ------------------------------------------ @@ -37,6 +38,20 @@ proc _test_get_commands {lst} { proc _test_out_total {} { upvar _ _ + if {![llength $_(ittm)]} { + puts "" + return + } + + set mintm 0x7fffffff + set maxtm 0 + set i 0 + foreach tm $_(ittm) { + if {$tm > $maxtm} {set maxtm $tm; set maxi $i} + if {$tm < $mintm} {set mintm $tm; set mini $i} + incr i + } + puts [string repeat ** 40] puts [format "Total %d cases in %.2f sec.:" [llength $_(itcnt)] [expr {[llength $_(itcnt)] * $_(reptime) / 1000.0}]] lset _(m) 0 [format %.6f [expr [join $_(ittm) +]]] @@ -48,6 +63,16 @@ proc _test_out_total {} { lset _(m) 2 [expr {[lindex $_(m) 2] / [llength $_(itcnt)]}] lset _(m) 4 [expr {[lindex $_(m) 2] * (1000 / $_(reptime))}] puts $_(m) + puts "Min:" + lset _(m) 0 [lindex $_(ittm) $mini] + lset _(m) 2 [lindex $_(itcnt) $mini] + lset _(m) 2 [lindex $_(itrate) $mini] + puts $_(m) + puts "Max:" + lset _(m) 0 [lindex $_(ittm) $maxi] + lset _(m) 2 [lindex $_(itcnt) $maxi] + lset _(m) 2 [lindex $_(itrate) $maxi] + puts $_(m) puts [string repeat ** 40] puts "" } @@ -123,8 +148,10 @@ proc test-scan {{reptime 1000}} { # Scan : century, lookup table month {clock scan {1970 Jan 2} -format {%C%y %b %d} -locale en -gmt 1} - # Scan : century, lookup table month and day + # Scan : century, lookup table month and day (both entries are first) {clock scan {1970 Jan 02} -format {%C%y %b %Od} -locale en -gmt 1} + # Scan : century, lookup table month and day (list scan: entries with position 12 / 31) + {clock scan {2016 Dec 31} -format {%C%y %b %Od} -locale en -gmt 1} break diff --git a/tests/clock.test b/tests/clock.test index 9e3dbd7..22b5bc1 100644 --- a/tests/clock.test +++ b/tests/clock.test @@ -18553,12 +18553,12 @@ test clock-6.8 {input of seconds} { } 9223372036854775807 test clock-6.9 {input of seconds - overflow} { - list [catch {clock scan -9223372036854775809 -format %s -gmt true} result] $result -} {1 {integer value too large to represent}} + list [catch {clock scan -9223372036854775809 -format %s -gmt true} result] $result $::errorCode +} {1 {requested date too large to represent} {CLOCK dateTooLarge}} test clock-6.10 {input of seconds - overflow} { - list [catch {clock scan 9223372036854775808 -format %s -gmt true} result] $result -} {1 {integer value too large to represent}} + list [catch {clock scan 9223372036854775808 -format %s -gmt true} result] $result $::errorCode +} {1 {requested date too large to represent} {CLOCK dateTooLarge}} test clock-6.11 {input of seconds - two values} { clock scan {1 2} -format {%s %s} -gmt true -- cgit v0.12 From c52322d40935741e19091f547619c69a831515e1 Mon Sep 17 00:00:00 2001 From: sebres Date: Tue, 10 Jan 2017 22:28:25 +0000 Subject: improve LocalizeFormat, internal caching of localized formats inside msgcat for locale and format objects smart reference introduced in dict (smart pointer with 0 object reference but increase dict-reference, provide changeable locale dict) --- generic/tclClock.c | 64 ++++++++++++++++++++++-- generic/tclClockFmt.c | 75 ++++++++++++++++++++-------- generic/tclDate.h | 10 ++-- generic/tclDictObj.c | 122 ++++++++++++++++++++++++++++++++++------------ generic/tclInt.h | 1 + library/clock.tcl | 83 ++++++++++++++++++++----------- library/init.tcl | 2 +- library/msgcat/msgcat.tcl | 3 +- 8 files changed, 269 insertions(+), 91 deletions(-) diff --git a/generic/tclClock.c b/generic/tclClock.c index 166a4b3..e066812 100644 --- a/generic/tclClock.c +++ b/generic/tclClock.c @@ -60,6 +60,7 @@ typedef enum ClockLiteral { LIT_GETSYSTEMTIMEZONE, LIT_SETUPTIMEZONE, LIT_MCGET, LIT_TCL_CLOCK, + LIT_LOCALIZE_FORMAT, #if 0 LIT_FREESCAN, #endif @@ -82,7 +83,8 @@ static const char *const Literals[] = { "::tcl::clock::TZData", "::tcl::clock::GetSystemTimeZone", "::tcl::clock::SetupTimeZone", - "::msgcat::mcget", "::tcl::clock" + "::msgcat::mcget", "::tcl::clock", + "::tcl::clock::LocalizeFormat" #if 0 "::tcl::clock::FreeScan" #endif @@ -487,7 +489,6 @@ MODULE_SCOPE Tcl_Obj * ClockMCDict(ClockFmtScnCmdArgs *opts) { ClockClientData *dataPtr = opts->clientData; - Tcl_Obj *callargs[3]; /* if dict not yet retrieved */ if (opts->mcDictObj == NULL) { @@ -518,6 +519,7 @@ ClockMCDict(ClockFmtScnCmdArgs *opts) } if (opts->mcDictObj == NULL) { + Tcl_Obj *callargs[3]; /* get msgcat dictionary - ::msgcat::mcget ::tcl::clock locale */ callargs[0] = dataPtr->literals[LIT_MCGET]; callargs[1] = dataPtr->literals[LIT_TCL_CLOCK]; @@ -528,6 +530,11 @@ ClockMCDict(ClockFmtScnCmdArgs *opts) } opts->mcDictObj = Tcl_GetObjResult(opts->interp); + /* be sure that object reference not increases (dict changeable) */ + if (opts->mcDictObj->refCount > 0) { + /* smart reference (shared dict as object with no ref-counter) */ + opts->mcDictObj = Tcl_DictObjSmartRef(opts->interp, opts->mcDictObj); + } if ( opts->localeObj == dataPtr->CurrentLocale ) { Tcl_SetObjRef(dataPtr->CurrentLocaleDict, opts->mcDictObj); } else { @@ -535,6 +542,7 @@ ClockMCDict(ClockFmtScnCmdArgs *opts) Tcl_UnsetObjRef(dataPtr->LastUnnormUsedLocale); Tcl_SetObjRef(dataPtr->LastUsedLocaleDict, opts->mcDictObj); } + Tcl_ResetResult(opts->interp); } } @@ -626,6 +634,56 @@ ClockMCGetListIdxDict( return valObj; } +MODULE_SCOPE Tcl_Obj * +ClockLocalizeFormat( + ClockFmtScnCmdArgs *opts) +{ + ClockClientData *dataPtr = opts->clientData; + Tcl_Obj *valObj, *keyObj; + + keyObj = ClockFrmObjGetLocFmtKey(opts->interp, opts->formatObj); + + if (opts->mcDictObj == NULL) { + ClockMCDict(opts); + if (opts->mcDictObj == NULL) + return NULL; + } + + /* try to find in cache within mc-catalog */ + if (Tcl_DictObjGet(NULL, opts->mcDictObj, + keyObj, &valObj) != TCL_OK) { + return NULL; + } + if (valObj == NULL) { + Tcl_Obj *callargs[4]; + /* call LocalizeFormat locale format fmtkey */ + callargs[0] = dataPtr->literals[LIT_LOCALIZE_FORMAT]; + callargs[1] = opts->localeObj; + callargs[2] = opts->formatObj; + callargs[3] = keyObj; + Tcl_IncrRefCount(keyObj); + if (Tcl_EvalObjv(opts->interp, 4, callargs, 0) != TCL_OK + ) { + Tcl_DecrRefCount(keyObj); + return NULL; + } + + valObj = Tcl_GetObjResult(opts->interp); + + if (Tcl_DictObjPut(opts->interp, opts->mcDictObj, + keyObj, valObj) != TCL_OK + ) { + Tcl_DecrRefCount(keyObj); + return NULL; + } + + Tcl_DecrRefCount(keyObj); + Tcl_ResetResult(opts->interp); + } + + return (opts->formatObj = valObj); +} + /* *---------------------------------------------------------------------- */ @@ -2936,7 +2994,7 @@ ClockScanObjCmd( #endif else { /* Use compiled version of Scan - */ - + ret = ClockScan(clientData, interp, info, objv[1], &opts); } diff --git a/generic/tclClockFmt.c b/generic/tclClockFmt.c index a3c7f20..184b52a 100644 --- a/generic/tclClockFmt.c +++ b/generic/tclClockFmt.c @@ -308,14 +308,14 @@ Tcl_ObjType ClockFmtObjType = { #define ObjClockFmtScn(objPtr) \ (ClockFmtScnStorage *)objPtr->internalRep.twoPtrValue.ptr1; -#define SetObjLitStorage(objPtr, lit) \ - objPtr->internalRep.twoPtrValue.ptr2 = lit -#define ObjLitStorage(objPtr) \ - (ClockLitStorage *)objPtr->internalRep.twoPtrValue.ptr2; - -#define ClockFmtObj_SetObjIntRep(objPtr, fss, lit) \ - objPtr->internalRep.twoPtrValue.ptr1 = fss, \ - objPtr->internalRep.twoPtrValue.ptr2 = lit, \ +#define SetObjLocFmtKey(objPtr, key) \ + Tcl_InitObjRef((Tcl_Obj *)objPtr->internalRep.twoPtrValue.ptr2, key) +#define ObjLocFmtKey(objPtr) \ + ((Tcl_Obj *)objPtr->internalRep.twoPtrValue.ptr2) + +#define ClockFmtObj_SetObjIntRep(objPtr, fss, key) \ + objPtr->internalRep.twoPtrValue.ptr1 = fss; \ + Tcl_InitObjRef((Tcl_Obj *)objPtr->internalRep.twoPtrValue.ptr2, key); \ objPtr->typePtr = &ClockFmtObjType; /* @@ -327,7 +327,6 @@ ClockFmtObj_DupInternalRep(srcPtr, copyPtr) Tcl_Obj *copyPtr; { ClockFmtScnStorage *fss = ObjClockFmtScn(srcPtr); - // ClockLitStorage *lit = ObjLitStorage(srcPtr); if (fss != NULL) { Tcl_MutexLock(&ClockFmtMutex); @@ -335,7 +334,7 @@ ClockFmtObj_DupInternalRep(srcPtr, copyPtr) Tcl_MutexUnlock(&ClockFmtMutex); } - ClockFmtObj_SetObjIntRep(copyPtr, fss, NULL); + ClockFmtObj_SetObjIntRep(copyPtr, fss, ObjLocFmtKey(srcPtr)); /* if no format representation, dup string representation */ if (fss == NULL) { @@ -352,7 +351,6 @@ ClockFmtObj_FreeInternalRep(objPtr) Tcl_Obj *objPtr; { ClockFmtScnStorage *fss = ObjClockFmtScn(objPtr); - // ClockLitStorage *lit = ObjLitStorage(objPtr); if (fss != NULL) { Tcl_MutexLock(&ClockFmtMutex); /* decrement object reference count of format/scan storage */ @@ -368,7 +366,7 @@ ClockFmtObj_FreeInternalRep(objPtr) Tcl_MutexUnlock(&ClockFmtMutex); } SetObjClockFmtScn(objPtr, NULL); - SetObjLitStorage(objPtr, NULL); + Tcl_UnsetObjRef(ObjLocFmtKey(objPtr)); objPtr->typePtr = NULL; }; /* @@ -379,16 +377,18 @@ ClockFmtObj_SetFromAny(interp, objPtr) Tcl_Interp *interp; Tcl_Obj *objPtr; { - ClockFmtScnStorage *fss; - const char *strFmt = TclGetString(objPtr); - - if (!strFmt || (fss = FindOrCreateFmtScnStorage(interp, strFmt)) == NULL) { - return TCL_ERROR; - } - + /* validate string representation before free old internal represenation */ + (void)TclGetString(objPtr); + + /* free old internal represenation */ if (objPtr->typePtr && objPtr->typePtr->freeIntRepProc) objPtr->typePtr->freeIntRepProc(objPtr); - ClockFmtObj_SetObjIntRep(objPtr, fss, NULL); + + /* initial state of format object */ + objPtr->internalRep.twoPtrValue.ptr1 = NULL; + objPtr->internalRep.twoPtrValue.ptr2 = NULL; + objPtr->typePtr = &ClockFmtObjType; + return TCL_OK; }; /* @@ -415,6 +415,33 @@ ClockFmtObj_UpdateString(objPtr) /* *---------------------------------------------------------------------- + */ +MODULE_SCOPE Tcl_Obj* +ClockFrmObjGetLocFmtKey( + Tcl_Interp *interp, + Tcl_Obj *objPtr) +{ + Tcl_Obj *keyObj; + + if (objPtr->typePtr != &ClockFmtObjType) { + if (ClockFmtObj_SetFromAny(interp, objPtr) != TCL_OK) { + return NULL; + } + } + + keyObj = ObjLocFmtKey(objPtr); + if (keyObj) { + return keyObj; + } + + keyObj = Tcl_ObjPrintf("FMT_%s", TclGetString(objPtr)); + SetObjLocFmtKey(objPtr, keyObj); + + return keyObj; +} + +/* + *---------------------------------------------------------------------- * * Tcl_GetClockFrmScnFromObj -- * @@ -731,7 +758,7 @@ static ClockScanTokenMap ScnWordTokenMap = { ClockScanToken * ClockGetOrParseScanFormat( Tcl_Interp *interp, /* Tcl interpreter */ - Tcl_Obj *formatObj) /* Format container */ + Tcl_Obj *formatObj) /* Format container */ { ClockFmtScnStorage *fss; ClockScanToken *tok; @@ -889,6 +916,12 @@ ClockScan( unsigned short int flags = 0; int ret = TCL_ERROR; + /* get localized format */ + + if (ClockLocalizeFormat(opts) == NULL) { + return TCL_ERROR; + } + if ((tok = ClockGetOrParseScanFormat(interp, opts->formatObj)) == NULL) { return TCL_ERROR; } diff --git a/generic/tclDate.h b/generic/tclDate.h index 1c51a02..62fa693 100644 --- a/generic/tclDate.h +++ b/generic/tclDate.h @@ -345,10 +345,6 @@ typedef struct ClockFmtScnStorage { * stored by offset +sizeof(self) */ } ClockFmtScnStorage; -typedef struct ClockLitStorage { - int dummy; -} ClockLitStorage; - /* * Prototypes of module functions. */ @@ -366,9 +362,15 @@ MODULE_SCOPE Tcl_Obj * ClockMCGet(ClockFmtScnCmdArgs *opts, int mcKey); MODULE_SCOPE Tcl_Obj * ClockMCGetListIdxDict(ClockFmtScnCmdArgs *opts, int mcKey); +MODULE_SCOPE Tcl_Obj * + ClockLocalizeFormat(ClockFmtScnCmdArgs *opts); /* tclClockFmt.c module declarations */ +MODULE_SCOPE Tcl_Obj* + ClockFrmObjGetLocFmtKey(Tcl_Interp *interp, + Tcl_Obj *objPtr); + MODULE_SCOPE ClockFmtScnStorage * Tcl_GetClockFrmScnFromObj(Tcl_Interp *interp, Tcl_Obj *objPtr); diff --git a/generic/tclDictObj.c b/generic/tclDictObj.c index 1115999..3944173 100644 --- a/generic/tclDictObj.c +++ b/generic/tclDictObj.c @@ -51,6 +51,8 @@ static int DictSetCmd(ClientData dummy, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv); static int DictSizeCmd(ClientData dummy, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv); +static int DictSmartRefCmd(ClientData dummy, Tcl_Interp *interp, + int objc, Tcl_Obj *const *objv); static int DictUnsetCmd(ClientData dummy, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv); static int DictUpdateCmd(ClientData dummy, Tcl_Interp *interp, @@ -98,6 +100,7 @@ static const EnsembleImplMap implementationMap[] = { {"replace", DictReplaceCmd, NULL, NULL, NULL, 0 }, {"set", DictSetCmd, TclCompileDictSetCmd, NULL, NULL, 0 }, {"size", DictSizeCmd, TclCompileBasic1ArgCmd, NULL, NULL, 0 }, + {"smartref",DictSmartRefCmd,NULL, NULL, NULL, 0 }, {"unset", DictUnsetCmd, TclCompileDictUnsetCmd, NULL, NULL, 0 }, {"update", DictUpdateCmd, TclCompileDictUpdateCmd, NULL, NULL, 0 }, {"values", DictValuesCmd, TclCompileBasic1Or2ArgCmd, NULL, NULL, 0 }, @@ -142,7 +145,7 @@ typedef struct Dict { * the entries in the order that they are * created. */ int epoch; /* Epoch counter */ - size_t refCount; /* Reference counter (see above) */ + int refcount; /* Reference counter (see above) */ Tcl_Obj *chain; /* Linked list used for invalidating the * string representations of updated nested * dictionaries. */ @@ -392,7 +395,7 @@ DupDictInternalRep( newDict->epoch = 0; newDict->chain = NULL; - newDict->refCount = 1; + newDict->refcount = 1; /* * Store in the object. @@ -427,7 +430,8 @@ FreeDictInternalRep( { Dict *dict = DICT(dictPtr); - if (dict->refCount-- <= 1) { + dict->refcount--; + if (dict->refcount <= 0) { DeleteDict(dict); } dictPtr->typePtr = NULL; @@ -712,7 +716,7 @@ SetDictFromAny( TclFreeIntRep(objPtr); dict->epoch = 0; dict->chain = NULL; - dict->refCount = 1; + dict->refcount = 1; DICT(objPtr) = dict; objPtr->internalRep.twoPtrValue.ptr2 = NULL; objPtr->typePtr = &tclDictType; @@ -1116,7 +1120,7 @@ Tcl_DictObjFirst( searchPtr->dictionaryPtr = (Tcl_Dict) dict; searchPtr->epoch = dict->epoch; searchPtr->next = cPtr->nextPtr; - dict->refCount++; + dict->refcount++; if (keyPtrPtr != NULL) { *keyPtrPtr = Tcl_GetHashKey(&dict->table, &cPtr->entry); } @@ -1230,7 +1234,8 @@ Tcl_DictObjDone( if (searchPtr->epoch != -1) { searchPtr->epoch = -1; dict = (Dict *) searchPtr->dictionaryPtr; - if (dict->refCount-- <= 1) { + dict->refcount--; + if (dict->refcount <= 0) { DeleteDict(dict); } } @@ -1382,7 +1387,7 @@ Tcl_NewDictObj(void) InitChainTable(dict); dict->epoch = 0; dict->chain = NULL; - dict->refCount = 1; + dict->refcount = 1; DICT(dictPtr) = dict; dictPtr->internalRep.twoPtrValue.ptr2 = NULL; dictPtr->typePtr = &tclDictType; @@ -1432,7 +1437,7 @@ Tcl_DbNewDictObj( InitChainTable(dict); dict->epoch = 0; dict->chain = NULL; - dict->refCount = 1; + dict->refcount = 1; DICT(dictPtr) = dict; dictPtr->internalRep.twoPtrValue.ptr2 = NULL; dictPtr->typePtr = &tclDictType; @@ -1957,6 +1962,77 @@ DictSizeCmd( /* *---------------------------------------------------------------------- + */ + +Tcl_Obj * +Tcl_DictObjSmartRef( + Tcl_Interp *interp, + Tcl_Obj *dictPtr) +{ + Tcl_Obj *result; + Dict *dict; + + if (dictPtr->typePtr != &tclDictType + && SetDictFromAny(interp, dictPtr) != TCL_OK) { + return NULL; + } + + dict = DICT(dictPtr); + + result = Tcl_NewObj(); + DICT(result) = dict; + dict->refcount++; + result->internalRep.twoPtrValue.ptr2 = NULL; + result->typePtr = &tclDictType; + + return result; +} + +/* + *---------------------------------------------------------------------- + * + * DictSmartRefCmd -- + * + * This function implements the "dict smartref" Tcl command. See the user + * documentation for details on what it does, and TIP#111 for the formal + * specification. + * + * Results: + * A standard Tcl result. + * + * Side effects: + * See the user documentation. + * + *---------------------------------------------------------------------- + */ + +static int +DictSmartRefCmd( + ClientData dummy, + Tcl_Interp *interp, + int objc, + Tcl_Obj *const *objv) +{ + Tcl_Obj *result; + Dict *dict; + + if (objc != 2) { + Tcl_WrongNumArgs(interp, 1, objv, "dictionary"); + return TCL_ERROR; + } + + result = Tcl_DictObjSmartRef(interp, objv[1]); + if (result == NULL) { + return TCL_ERROR; + } + + Tcl_SetObjResult(interp, result); + + return TCL_OK; +} + +/* + *---------------------------------------------------------------------- * * DictExistsCmd -- * @@ -2280,7 +2356,7 @@ DictAppendCmd( Tcl_Obj *const *objv) { Tcl_Obj *dictPtr, *valuePtr, *resultPtr; - int allocatedDict = 0; + int i, allocatedDict = 0; if (objc < 3) { Tcl_WrongNumArgs(interp, 1, objv, "dictVarName key ?value ...?"); @@ -2305,33 +2381,15 @@ DictAppendCmd( if ((objc > 3) || (valuePtr == NULL)) { /* Only go through append activites when something will change. */ - Tcl_Obj *appendObjPtr = NULL; - - if (objc > 3) { - /* Something to append */ - - if (objc == 4) { - appendObjPtr = objv[3]; - } else if (TCL_OK != TclStringCatObjv(interp, /* inPlace */ 1, - objc-3, objv+3, &appendObjPtr)) { - return TCL_ERROR; - } - } - if (appendObjPtr == NULL) { - /* => (objc == 3) => (valuePtr == NULL) */ + if (valuePtr == NULL) { TclNewObj(valuePtr); - } else if (valuePtr == NULL) { - valuePtr = appendObjPtr; - appendObjPtr = NULL; + } else if (Tcl_IsShared(valuePtr)) { + valuePtr = Tcl_DuplicateObj(valuePtr); } - if (appendObjPtr) { - if (Tcl_IsShared(valuePtr)) { - valuePtr = Tcl_DuplicateObj(valuePtr); - } - - Tcl_AppendObjToObj(valuePtr, appendObjPtr); + for (i=3 ; i Date: Tue, 10 Jan 2017 22:30:24 +0000 Subject: improve LocalizeFormat, internal caching of localized formats inside msgcat for locale and format objects smart reference introduced in dict (smart pointer with 0 object reference but increase dict-reference, provide changeable locale dict) code review --- generic/tclClock.c | 98 +------------------- generic/tclClockFmt.c | 229 ++++++++++++++++++++++++++++++---------------- generic/tclDate.h | 52 ++++++++++- library/clock.tcl | 19 ++-- tests-perf/clock.perf.tcl | 6 +- 5 files changed, 214 insertions(+), 190 deletions(-) diff --git a/generic/tclClock.c b/generic/tclClock.c index e066812..08bc6ef 100644 --- a/generic/tclClock.c +++ b/generic/tclClock.c @@ -42,53 +42,7 @@ static const int daysInPriorMonths[2][13] = { * Enumeration of the string literals used in [clock] */ -typedef enum ClockLiteral { - LIT__NIL, - LIT__DEFAULT_FORMAT, - LIT_BCE, LIT_C, - LIT_CANNOT_USE_GMT_AND_TIMEZONE, - LIT_CE, - LIT_DAYOFMONTH, LIT_DAYOFWEEK, LIT_DAYOFYEAR, - LIT_ERA, LIT_GMT, LIT_GREGORIAN, - LIT_INTEGER_VALUE_TOO_LARGE, - LIT_ISO8601WEEK, LIT_ISO8601YEAR, - LIT_JULIANDAY, LIT_LOCALSECONDS, - LIT_MONTH, - LIT_SECONDS, LIT_TZNAME, LIT_TZOFFSET, - LIT_YEAR, - LIT_TZDATA, - LIT_GETSYSTEMTIMEZONE, - LIT_SETUPTIMEZONE, - LIT_MCGET, LIT_TCL_CLOCK, - LIT_LOCALIZE_FORMAT, -#if 0 - LIT_FREESCAN, -#endif - LIT__END -} ClockLiteral; -static const char *const Literals[] = { - "", - "%a %b %d %H:%M:%S %Z %Y", - "BCE", "C", - "cannot use -gmt and -timezone in same call", - "CE", - "dayOfMonth", "dayOfWeek", "dayOfYear", - "era", ":GMT", "gregorian", - "integer value too large to represent", - "iso8601Week", "iso8601Year", - "julianDay", "localSeconds", - "month", - "seconds", "tzName", "tzOffset", - "year", - "::tcl::clock::TZData", - "::tcl::clock::GetSystemTimeZone", - "::tcl::clock::SetupTimeZone", - "::msgcat::mcget", "::tcl::clock", - "::tcl::clock::LocalizeFormat" -#if 0 - "::tcl::clock::FreeScan" -#endif -}; +CLOCK_LITERAL_ARRAY(Literals); /* Msgcat literals for exact match (mcKey) */ CLOCK_LOCALE_LITERAL_ARRAY(MsgCtLiterals, ""); @@ -634,56 +588,6 @@ ClockMCGetListIdxDict( return valObj; } -MODULE_SCOPE Tcl_Obj * -ClockLocalizeFormat( - ClockFmtScnCmdArgs *opts) -{ - ClockClientData *dataPtr = opts->clientData; - Tcl_Obj *valObj, *keyObj; - - keyObj = ClockFrmObjGetLocFmtKey(opts->interp, opts->formatObj); - - if (opts->mcDictObj == NULL) { - ClockMCDict(opts); - if (opts->mcDictObj == NULL) - return NULL; - } - - /* try to find in cache within mc-catalog */ - if (Tcl_DictObjGet(NULL, opts->mcDictObj, - keyObj, &valObj) != TCL_OK) { - return NULL; - } - if (valObj == NULL) { - Tcl_Obj *callargs[4]; - /* call LocalizeFormat locale format fmtkey */ - callargs[0] = dataPtr->literals[LIT_LOCALIZE_FORMAT]; - callargs[1] = opts->localeObj; - callargs[2] = opts->formatObj; - callargs[3] = keyObj; - Tcl_IncrRefCount(keyObj); - if (Tcl_EvalObjv(opts->interp, 4, callargs, 0) != TCL_OK - ) { - Tcl_DecrRefCount(keyObj); - return NULL; - } - - valObj = Tcl_GetObjResult(opts->interp); - - if (Tcl_DictObjPut(opts->interp, opts->mcDictObj, - keyObj, valObj) != TCL_OK - ) { - Tcl_DecrRefCount(keyObj); - return NULL; - } - - Tcl_DecrRefCount(keyObj); - Tcl_ResetResult(opts->interp); - } - - return (opts->formatObj = valObj); -} - /* *---------------------------------------------------------------------- */ diff --git a/generic/tclClockFmt.c b/generic/tclClockFmt.c index 184b52a..daedb26 100644 --- a/generic/tclClockFmt.c +++ b/generic/tclClockFmt.c @@ -233,65 +233,6 @@ static Tcl_HashKeyType ClockFmtScnStorageHashKeyType; /* - *---------------------------------------------------------------------- - */ - -static ClockFmtScnStorage * -FindOrCreateFmtScnStorage( - Tcl_Interp *interp, - const char *strFmt) -{ - ClockFmtScnStorage *fss = NULL; - int new; - Tcl_HashEntry *hPtr; - - Tcl_MutexLock(&ClockFmtMutex); - - /* if not yet initialized */ - if (!initialized) { - /* initialize type */ - memcpy(&ClockFmtScnStorageHashKeyType, &tclStringHashKeyType, sizeof(tclStringHashKeyType)); - ClockFmtScnStorageHashKeyType.allocEntryProc = ClockFmtScnStorageAllocProc; - ClockFmtScnStorageHashKeyType.freeEntryProc = ClockFmtScnStorageFreeProc; - - /* initialize hash table */ - Tcl_InitCustomHashTable(&FmtScnHashTable, TCL_CUSTOM_TYPE_KEYS, - &ClockFmtScnStorageHashKeyType); - - initialized = 1; - Tcl_CreateExitHandler(ClockFrmScnFinalize, NULL); - } - - /* get or create entry (and alocate storage) */ - hPtr = Tcl_CreateHashEntry(&FmtScnHashTable, strFmt, &new); - if (hPtr != NULL) { - - fss = FmtScn4HashEntry(hPtr); - - #if CLOCK_FMT_SCN_STORAGE_GC_SIZE > 0 - /* unlink if it is currently in GC */ - if (new == 0 && fss->objRefCount == 0) { - ClockFmtScnStorage_GC_Out(fss); - } - #endif - - /* new reference, so increment in lock right now */ - fss->objRefCount++; - } - - Tcl_MutexUnlock(&ClockFmtMutex); - - if (fss == NULL && interp != NULL) { - Tcl_AppendResult(interp, "retrieve clock format failed \"", - strFmt ? strFmt : "", "\"", NULL); - Tcl_SetErrorCode(interp, "TCL", "EINVAL", NULL); - } - - return fss; -} - - -/* * Type definition. */ @@ -303,20 +244,11 @@ Tcl_ObjType ClockFmtObjType = { ClockFmtObj_SetFromAny /* setFromAnyProc */ }; -#define SetObjClockFmtScn(objPtr, fss) \ - objPtr->internalRep.twoPtrValue.ptr1 = fss #define ObjClockFmtScn(objPtr) \ - (ClockFmtScnStorage *)objPtr->internalRep.twoPtrValue.ptr1; + (*((ClockFmtScnStorage **)&(objPtr)->internalRep.twoPtrValue.ptr1)) -#define SetObjLocFmtKey(objPtr, key) \ - Tcl_InitObjRef((Tcl_Obj *)objPtr->internalRep.twoPtrValue.ptr2, key) #define ObjLocFmtKey(objPtr) \ - ((Tcl_Obj *)objPtr->internalRep.twoPtrValue.ptr2) - -#define ClockFmtObj_SetObjIntRep(objPtr, fss, key) \ - objPtr->internalRep.twoPtrValue.ptr1 = fss; \ - Tcl_InitObjRef((Tcl_Obj *)objPtr->internalRep.twoPtrValue.ptr2, key); \ - objPtr->typePtr = &ClockFmtObjType; + (*((Tcl_Obj **)&(objPtr)->internalRep.twoPtrValue.ptr2)) /* *---------------------------------------------------------------------- @@ -334,7 +266,15 @@ ClockFmtObj_DupInternalRep(srcPtr, copyPtr) Tcl_MutexUnlock(&ClockFmtMutex); } - ClockFmtObj_SetObjIntRep(copyPtr, fss, ObjLocFmtKey(srcPtr)); + ObjClockFmtScn(copyPtr) = fss; + /* regards special case - format not localizable */ + if (ObjLocFmtKey(srcPtr) != srcPtr) { + Tcl_InitObjRef(ObjLocFmtKey(copyPtr), ObjLocFmtKey(srcPtr)); + } else { + ObjLocFmtKey(copyPtr) = copyPtr; + } + copyPtr->typePtr = &ClockFmtObjType; + /* if no format representation, dup string representation */ if (fss == NULL) { @@ -365,8 +305,12 @@ ClockFmtObj_FreeInternalRep(objPtr) } Tcl_MutexUnlock(&ClockFmtMutex); } - SetObjClockFmtScn(objPtr, NULL); - Tcl_UnsetObjRef(ObjLocFmtKey(objPtr)); + ObjClockFmtScn(objPtr) = NULL; + if (ObjLocFmtKey(objPtr) != objPtr) { + Tcl_UnsetObjRef(ObjLocFmtKey(objPtr)); + } else { + ObjLocFmtKey(objPtr) = NULL; + } objPtr->typePtr = NULL; }; /* @@ -385,8 +329,8 @@ ClockFmtObj_SetFromAny(interp, objPtr) objPtr->typePtr->freeIntRepProc(objPtr); /* initial state of format object */ - objPtr->internalRep.twoPtrValue.ptr1 = NULL; - objPtr->internalRep.twoPtrValue.ptr2 = NULL; + ObjClockFmtScn(objPtr) = NULL; + ObjLocFmtKey(objPtr) = NULL; objPtr->typePtr = &ClockFmtObjType; return TCL_OK; @@ -435,13 +379,74 @@ ClockFrmObjGetLocFmtKey( } keyObj = Tcl_ObjPrintf("FMT_%s", TclGetString(objPtr)); - SetObjLocFmtKey(objPtr, keyObj); + Tcl_InitObjRef(ObjLocFmtKey(objPtr), keyObj); return keyObj; } /* *---------------------------------------------------------------------- + */ + +static ClockFmtScnStorage * +FindOrCreateFmtScnStorage( + Tcl_Interp *interp, + Tcl_Obj *objPtr) +{ + const char *strFmt = TclGetString(objPtr); + ClockFmtScnStorage *fss = NULL; + int new; + Tcl_HashEntry *hPtr; + + Tcl_MutexLock(&ClockFmtMutex); + + /* if not yet initialized */ + if (!initialized) { + /* initialize type */ + memcpy(&ClockFmtScnStorageHashKeyType, &tclStringHashKeyType, sizeof(tclStringHashKeyType)); + ClockFmtScnStorageHashKeyType.allocEntryProc = ClockFmtScnStorageAllocProc; + ClockFmtScnStorageHashKeyType.freeEntryProc = ClockFmtScnStorageFreeProc; + + /* initialize hash table */ + Tcl_InitCustomHashTable(&FmtScnHashTable, TCL_CUSTOM_TYPE_KEYS, + &ClockFmtScnStorageHashKeyType); + + initialized = 1; + Tcl_CreateExitHandler(ClockFrmScnFinalize, NULL); + } + + /* get or create entry (and alocate storage) */ + hPtr = Tcl_CreateHashEntry(&FmtScnHashTable, strFmt, &new); + if (hPtr != NULL) { + + fss = FmtScn4HashEntry(hPtr); + + #if CLOCK_FMT_SCN_STORAGE_GC_SIZE > 0 + /* unlink if it is currently in GC */ + if (new == 0 && fss->objRefCount == 0) { + ClockFmtScnStorage_GC_Out(fss); + } + #endif + + /* new reference, so increment in lock right now */ + fss->objRefCount++; + + ObjClockFmtScn(objPtr) = fss; + } + + Tcl_MutexUnlock(&ClockFmtMutex); + + if (fss == NULL && interp != NULL) { + Tcl_AppendResult(interp, "retrieve clock format failed \"", + strFmt ? strFmt : "", "\"", NULL); + Tcl_SetErrorCode(interp, "TCL", "EINVAL", NULL); + } + + return fss; +} + +/* + *---------------------------------------------------------------------- * * Tcl_GetClockFrmScnFromObj -- * @@ -475,8 +480,7 @@ Tcl_GetClockFrmScnFromObj( fss = ObjClockFmtScn(objPtr); if (fss == NULL) { - const char *strFmt = TclGetString(objPtr); - fss = FindOrCreateFmtScnStorage(interp, strFmt); + fss = FindOrCreateFmtScnStorage(interp, objPtr); } return fss; @@ -772,7 +776,7 @@ ClockGetOrParseScanFormat( fss = ObjClockFmtScn(formatObj); if (fss == NULL) { - fss = FindOrCreateFmtScnStorage(interp, TclGetString(formatObj)); + fss = FindOrCreateFmtScnStorage(interp, formatObj); if (fss == NULL) { return NULL; } @@ -898,6 +902,72 @@ done: return fss->scnTok; } +MODULE_SCOPE Tcl_Obj * +ClockLocalizeFormat( + ClockFmtScnCmdArgs *opts) +{ + ClockClientData *dataPtr = opts->clientData; + Tcl_Obj *valObj = NULL, *keyObj; + + keyObj = ClockFrmObjGetLocFmtKey(opts->interp, opts->formatObj); + + /* special case - format object is not localizable */ + if (keyObj == opts->formatObj) { + return opts->formatObj; + } + + if (opts->mcDictObj == NULL) { + ClockMCDict(opts); + if (opts->mcDictObj == NULL) + return NULL; + } + + /* try to find in cache within locale mc-catalog */ + if (Tcl_DictObjGet(NULL, opts->mcDictObj, + keyObj, &valObj) != TCL_OK) { + return NULL; + } + + /* call LocalizeFormat locale format fmtkey */ + if (valObj == NULL) { + Tcl_Obj *callargs[4]; + callargs[0] = dataPtr->literals[LIT_LOCALIZE_FORMAT]; + callargs[1] = opts->localeObj; + callargs[2] = opts->formatObj; + callargs[3] = keyObj; + Tcl_IncrRefCount(keyObj); + if (Tcl_EvalObjv(opts->interp, 4, callargs, 0) != TCL_OK + ) { + goto clean; + } + + valObj = Tcl_GetObjResult(opts->interp); + + /* cache it inside mc-dictionary (this incr. ref count of keyObj/valObj) */ + if (Tcl_DictObjPut(opts->interp, opts->mcDictObj, + keyObj, valObj) != TCL_OK + ) { + valObj = NULL; + goto clean; + } + + /* check special case - format object is not localizable */ + if (valObj == opts->formatObj) { + /* mark it as unlocalizable, by setting self as key (without refcount incr) */ + if (opts->formatObj->typePtr == &ClockFmtObjType) { + Tcl_UnsetObjRef(ObjLocFmtKey(opts->formatObj)); + ObjLocFmtKey(opts->formatObj) = opts->formatObj; + } + } +clean: + + Tcl_UnsetObjRef(keyObj); + Tcl_ResetResult(opts->interp); + } + + return (opts->formatObj = valObj); +} + /* *---------------------------------------------------------------------- */ @@ -917,7 +987,6 @@ ClockScan( int ret = TCL_ERROR; /* get localized format */ - if (ClockLocalizeFormat(opts) == NULL) { return TCL_ERROR; } diff --git a/generic/tclDate.h b/generic/tclDate.h index 62fa693..9f65b1b 100644 --- a/generic/tclDate.h +++ b/generic/tclDate.h @@ -37,6 +37,53 @@ /* + * Enumeration of the string literals used in [clock] + */ + +typedef enum ClockLiteral { + LIT__NIL, + LIT__DEFAULT_FORMAT, + LIT_BCE, LIT_C, + LIT_CANNOT_USE_GMT_AND_TIMEZONE, + LIT_CE, + LIT_DAYOFMONTH, LIT_DAYOFWEEK, LIT_DAYOFYEAR, + LIT_ERA, LIT_GMT, LIT_GREGORIAN, + LIT_INTEGER_VALUE_TOO_LARGE, + LIT_ISO8601WEEK, LIT_ISO8601YEAR, + LIT_JULIANDAY, LIT_LOCALSECONDS, + LIT_MONTH, + LIT_SECONDS, LIT_TZNAME, LIT_TZOFFSET, + LIT_YEAR, + LIT_TZDATA, + LIT_GETSYSTEMTIMEZONE, + LIT_SETUPTIMEZONE, + LIT_MCGET, LIT_TCL_CLOCK, + LIT_LOCALIZE_FORMAT, + LIT__END +} ClockLiteral; + +#define CLOCK_LITERAL_ARRAY(litarr) static const char *const litarr[] = { \ + "", \ + "%a %b %d %H:%M:%S %Z %Y", \ + "BCE", "C", \ + "cannot use -gmt and -timezone in same call", \ + "CE", \ + "dayOfMonth", "dayOfWeek", "dayOfYear", \ + "era", ":GMT", "gregorian", \ + "integer value too large to represent", \ + "iso8601Week", "iso8601Year", \ + "julianDay", "localSeconds", \ + "month", \ + "seconds", "tzName", "tzOffset", \ + "year", \ + "::tcl::clock::TZData", \ + "::tcl::clock::GetSystemTimeZone", \ + "::tcl::clock::SetupTimeZone", \ + "::msgcat::mcget", "::tcl::clock", \ + "::tcl::clock::LocalizeFormat" \ +} + +/* * Enumeration of the msgcat literals used in [clock] */ @@ -362,8 +409,6 @@ MODULE_SCOPE Tcl_Obj * ClockMCGet(ClockFmtScnCmdArgs *opts, int mcKey); MODULE_SCOPE Tcl_Obj * ClockMCGetListIdxDict(ClockFmtScnCmdArgs *opts, int mcKey); -MODULE_SCOPE Tcl_Obj * - ClockLocalizeFormat(ClockFmtScnCmdArgs *opts); /* tclClockFmt.c module declarations */ @@ -374,7 +419,8 @@ MODULE_SCOPE Tcl_Obj* MODULE_SCOPE ClockFmtScnStorage * Tcl_GetClockFrmScnFromObj(Tcl_Interp *interp, Tcl_Obj *objPtr); - +MODULE_SCOPE Tcl_Obj * + ClockLocalizeFormat(ClockFmtScnCmdArgs *opts); MODULE_SCOPE int ClockScan(ClientData clientData, Tcl_Interp *interp, register DateInfo *info, Tcl_Obj *strObj, ClockFmtScnCmdArgs *opts); diff --git a/library/clock.tcl b/library/clock.tcl index 4173174..a532c0d 100755 --- a/library/clock.tcl +++ b/library/clock.tcl @@ -2365,18 +2365,23 @@ proc ::tcl::clock::LocalizeFormat { locale format {fmtkey {}} } { dict set LocaleFormats $locale MLST $mlst } - # translate: - set locfmt [string map $mlst $format] - - # Save original format as long as possible, because of internal representation (performance) - if {$locfmt eq $format} { - set locfmt $format - } + # translate copy of format (don't use format object here, because otherwise + # it can lose its internal representation (string map - convert to unicode) + set locfmt [string map $mlst [string range " $format" 1 end]] # cache it: dict set LocaleFormats $locale $fmtkey $locfmt } + # Save original format as long as possible, because of internal + # representation (performance). + # Note that in this case such format will be never localized (also + # using another locales). To prevent this return a duplicate (but + # it may be slower). + if {$locfmt eq $format} { + set locfmt $format + } + return $locfmt } diff --git a/tests-perf/clock.perf.tcl b/tests-perf/clock.perf.tcl index a005648..3c69414 100644 --- a/tests-perf/clock.perf.tcl +++ b/tests-perf/clock.perf.tcl @@ -132,9 +132,6 @@ proc test-scan {{reptime 1000}} { # Scan : date-time (system time zone without base) {clock scan "25.11.2015 10:35:55" -format "%d.%m.%Y %H:%M:%S"} - # Scan : dynamic format (cacheable) - {clock scan "25.11.2015 10:35:55" -format [string trim "%d.%m.%Y %H:%M:%S "] -base 0 -gmt 1} - # Scan : julian day in gmt {clock scan 2451545 -format %J -gmt 1} # Scan : julian day in system TZ @@ -153,6 +150,9 @@ proc test-scan {{reptime 1000}} { # Scan : century, lookup table month and day (list scan: entries with position 12 / 31) {clock scan {2016 Dec 31} -format {%C%y %b %Od} -locale en -gmt 1} + # Scan : dynamic format (cacheable) + {clock scan "25.11.2015 10:35:55" -format [string trim "%d.%m.%Y %H:%M:%S "] -base 0 -gmt 1} + break # Scan : zone only -- cgit v0.12 From c51ce8e8796729eba5d0dc8d17ff0d7903bebb20 Mon Sep 17 00:00:00 2001 From: sebres Date: Tue, 10 Jan 2017 22:30:49 +0000 Subject: list index logic optimized regarding greedy search (don't stop by first found - try to find longest) --- generic/tclClockFmt.c | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/generic/tclClockFmt.c b/generic/tclClockFmt.c index daedb26..09cbfa4 100644 --- a/generic/tclClockFmt.c +++ b/generic/tclClockFmt.c @@ -514,7 +514,7 @@ LocaleListSearch(ClockFmtScnCmdArgs *opts, int minLen, int maxLen) { Tcl_Obj **lstv; - int lstc, i, l; + int lstc, i, l, lf = -1; const char *s; Tcl_Obj *valObj; @@ -536,16 +536,27 @@ LocaleListSearch(ClockFmtScnCmdArgs *opts, if ( l >= minLen && l <= maxLen && strncasecmp(yyInput, s, l) == 0 ) { + /* found, try to find longest value (greedy search) */ + if (l < maxLen && minLen != maxLen) { + lf = i; + minLen = l + 1; + continue; + } *val = i; yyInput += l; break; } } - /* if not found */ + /* if found */ if (i < lstc) { return TCL_OK; } + if (lf >= 0) { + *val = lf; + yyInput += minLen - 1; + return TCL_OK; + } return TCL_RETURN; } -- cgit v0.12 From caf50ef7eab0d54375a495f8eb9d36ffa264dde2 Mon Sep 17 00:00:00 2001 From: sebres Date: Tue, 10 Jan 2017 22:31:12 +0000 Subject: seconds token (%s) take precedence over all other tokens --- generic/tclClockFmt.c | 56 ++++++++++++++++++++++++++++----------------------- 1 file changed, 31 insertions(+), 25 deletions(-) diff --git a/generic/tclClockFmt.c b/generic/tclClockFmt.c index 09cbfa4..ba924fd 100644 --- a/generic/tclClockFmt.c +++ b/generic/tclClockFmt.c @@ -1147,41 +1147,47 @@ ClockScan( goto not_match; } - /* invalidate result */ - if (flags & CLF_DATE) { + /* + * Invalidate result + */ + + /* seconds token (%s) take precedence over all other tokens */ + if ((opts->flags & CLF_EXTENDED) || !(flags & CLF_LOCALSEC)) { + if (flags & CLF_DATE) { - if (!(flags & CLF_JULIANDAY)) { - info->flags |= CLF_INVALIDATE_SECONDS|CLF_INVALIDATE_JULIANDAY; + if (!(flags & CLF_JULIANDAY)) { + info->flags |= CLF_INVALIDATE_SECONDS|CLF_INVALIDATE_JULIANDAY; - if (yyYear < 100) { - if (!(flags & CLF_CENTURY)) { - if (yyYear >= dataPtr->yearOfCenturySwitch) { - yyYear -= 100; + if (yyYear < 100) { + if (!(flags & CLF_CENTURY)) { + if (yyYear >= dataPtr->yearOfCenturySwitch) { + yyYear -= 100; + } + yyYear += dataPtr->currentYearCentury; + } else { + yyYear += info->dateCentury * 100; } - yyYear += dataPtr->currentYearCentury; - } else { - yyYear += info->dateCentury * 100; } + yydate.era = CE; + } + /* if date but no time - reset time */ + if (!(flags & (CLF_TIME|CLF_LOCALSEC))) { + info->flags |= CLF_INVALIDATE_SECONDS; + yydate.localSeconds = 0; } - yydate.era = CE; } - /* if date but no time - reset time */ - if (!(flags & (CLF_TIME|CLF_LOCALSEC))) { + + if (flags & CLF_TIME) { + info->flags |= CLF_INVALIDATE_SECONDS; + yySeconds = ToSeconds(yyHour, yyMinutes, + yySeconds, yyMeridian); + } else + if (!(flags & CLF_LOCALSEC)) { info->flags |= CLF_INVALIDATE_SECONDS; - yydate.localSeconds = 0; + yySeconds = yydate.localSeconds % SECONDS_PER_DAY; } } - if (flags & CLF_TIME) { - info->flags |= CLF_INVALIDATE_SECONDS; - yySeconds = ToSeconds(yyHour, yyMinutes, - yySeconds, yyMeridian); - } else - if (!(flags & CLF_LOCALSEC)) { - info->flags |= CLF_INVALIDATE_SECONDS; - yySeconds = yydate.localSeconds % SECONDS_PER_DAY; - } - ret = TCL_OK; goto done; -- cgit v0.12 From 6c38124bb987bb10c82631122bcb4a981a47e559 Mon Sep 17 00:00:00 2001 From: sebres Date: Tue, 10 Jan 2017 22:31:43 +0000 Subject: %j token as day of year; clear flags implemented (to provide last-wins functionality) --- generic/tclClock.c | 86 ++++++++++++++++++++++++++++++++++++++------------- generic/tclClockFmt.c | 48 +++++++++++++++------------- generic/tclDate.h | 22 +++++++------ 3 files changed, 103 insertions(+), 53 deletions(-) diff --git a/generic/tclClock.c b/generic/tclClock.c index 08bc6ef..ef0e46b 100644 --- a/generic/tclClock.c +++ b/generic/tclClock.c @@ -2313,7 +2313,47 @@ GetJulianDayFromEraYearMonthDay( + ym1o4; } } +/* + *---------------------------------------------------------------------- + */ +static void +GetJulianDayFromEraYearDay( + TclDateFields *fields, /* Date to convert */ + int changeover) /* Gregorian transition date as a Julian Day */ +{ + int year, ym1; + + /* Get absolute year number from the civil year */ + if (fields->era == BCE) { + year = 1 - fields->year; + } else { + year = fields->year; + } + + ym1 = year - 1; + + /* Try the Gregorian calendar first. */ + fields->gregorian = 1; + fields->julianDay = + 1721425 + + fields->dayOfYear + + ( 365 * ym1 ) + + ( ym1 / 4 ) + - ( ym1 / 100 ) + + ( ym1 / 400 ); + + /* If the date is before the Gregorian change, use the Julian calendar. */ + + if ( fields->julianDay < changeover ) { + fields->gregorian = 0; + fields->julianDay = + 1721423 + + fields->dayOfYear + + ( 365 * ym1 ) + + ( ym1 / 4 ); + } +} /* *---------------------------------------------------------------------- * @@ -2906,9 +2946,13 @@ ClockScanObjCmd( goto done; } - /* If needed assemble julianDay using new year, month, etc. */ - if (info->flags & CLF_INVALIDATE_JULIANDAY) { - GetJulianDayFromEraYearMonthDay(&yydate, GREGORIAN_CHANGE_DATE); + /* If needed assemble julianDay using year, month, etc. */ + if (info->flags & CLF_ASSEMBLE_JULIANDAY) { + if ((info->flags & CLF_DAYOFMONTH) || !(info->flags & CLF_DAYOFYEAR)) { + GetJulianDayFromEraYearMonthDay(&yydate, GREGORIAN_CHANGE_DATE); + } else { + GetJulianDayFromEraYearDay(&yydate, GREGORIAN_CHANGE_DATE); + } } /* some overflow checks, if not extended */ @@ -2924,7 +2968,7 @@ ClockScanObjCmd( /* Local seconds to UTC (stored in yydate.seconds) */ - if (info->flags & (CLF_INVALIDATE_SECONDS|CLF_INVALIDATE_JULIANDAY)) { + if (info->flags & (CLF_ASSEMBLE_SECONDS|CLF_ASSEMBLE_JULIANDAY)) { yydate.localSeconds = -210866803200L + ( SECONDS_PER_DAY * (Tcl_WideInt)yydate.julianDay ) @@ -3007,7 +3051,7 @@ ClockFreeScan( if (yyHaveTime == 0) { yyHaveTime = -1; } - info->flags |= CLF_INVALIDATE_JULIANDAY|CLF_INVALIDATE_SECONDS; + info->flags |= CLF_ASSEMBLE_JULIANDAY|CLF_ASSEMBLE_SECONDS; } /* @@ -3032,7 +3076,7 @@ ClockFreeScan( // Tcl_SetObjRef(yydate.tzName, opts->timezoneObj); - info->flags |= CLF_INVALIDATE_SECONDS; + info->flags |= CLF_ASSEMBLE_SECONDS; } /* @@ -3041,13 +3085,13 @@ ClockFreeScan( if (yyHaveTime == -1) { yySeconds = 0; - info->flags |= CLF_INVALIDATE_SECONDS; + info->flags |= CLF_ASSEMBLE_SECONDS; } else if (yyHaveTime) { yySeconds = ToSeconds(yyHour, yyMinutes, yySeconds, yyMeridian); - info->flags |= CLF_INVALIDATE_SECONDS; + info->flags |= CLF_ASSEMBLE_SECONDS; } else if ( (yyHaveDay && !yyHaveDate) @@ -3057,7 +3101,7 @@ ClockFreeScan( || yyRelDay != 0 ) ) ) { yySeconds = 0; - info->flags |= CLF_INVALIDATE_SECONDS; + info->flags |= CLF_ASSEMBLE_SECONDS; } else { yySeconds = yydate.localSeconds % SECONDS_PER_DAY; @@ -3084,11 +3128,11 @@ repeat_rel: int m, h; /* if needed extract year, month, etc. again */ - if (info->flags & CLF_INVALIDATE_DATE) { + if (info->flags & CLF_ASSEMBLE_DATE) { GetGregorianEraYearDay(&yydate, GREGORIAN_CHANGE_DATE); GetMonthDay(&yydate); GetYearWeekDay(&yydate, GREGORIAN_CHANGE_DATE); - info->flags &= ~CLF_INVALIDATE_DATE; + info->flags &= ~CLF_ASSEMBLE_DATE; } /* add the requisite number of months */ @@ -3104,7 +3148,7 @@ repeat_rel: } /* on demand (lazy) assemble julianDay using new year, month, etc. */ - info->flags |= CLF_INVALIDATE_JULIANDAY|CLF_INVALIDATE_SECONDS; + info->flags |= CLF_ASSEMBLE_JULIANDAY|CLF_ASSEMBLE_SECONDS; yyRelMonth = 0; } @@ -3113,14 +3157,14 @@ repeat_rel: if (yyRelDay) { /* assemble julianDay using new year, month, etc. */ - if (info->flags & CLF_INVALIDATE_JULIANDAY) { + if (info->flags & CLF_ASSEMBLE_JULIANDAY) { GetJulianDayFromEraYearMonthDay(&yydate, GREGORIAN_CHANGE_DATE); - info->flags &= ~CLF_INVALIDATE_JULIANDAY; + info->flags &= ~CLF_ASSEMBLE_JULIANDAY; } yydate.julianDay += yyRelDay; /* julianDay was changed, on demand (lazy) extract year, month, etc. again */ - info->flags |= CLF_INVALIDATE_DATE|CLF_INVALIDATE_SECONDS; + info->flags |= CLF_ASSEMBLE_DATE|CLF_ASSEMBLE_SECONDS; yyRelDay = 0; } @@ -3150,11 +3194,11 @@ repeat_rel: int monthDiff; /* if needed extract year, month, etc. again */ - if (info->flags & CLF_INVALIDATE_DATE) { + if (info->flags & CLF_ASSEMBLE_DATE) { GetGregorianEraYearDay(&yydate, GREGORIAN_CHANGE_DATE); GetMonthDay(&yydate); GetYearWeekDay(&yydate, GREGORIAN_CHANGE_DATE); - info->flags &= ~CLF_INVALIDATE_DATE; + info->flags &= ~CLF_ASSEMBLE_DATE; } if (yyMonthOrdinalIncr > 0) { @@ -3177,7 +3221,7 @@ repeat_rel: yyRelMonth += monthDiff; yyHaveOrdinalMonth = 0; - info->flags |= CLF_INVALIDATE_JULIANDAY|CLF_INVALIDATE_SECONDS; + info->flags |= CLF_ASSEMBLE_JULIANDAY|CLF_ASSEMBLE_SECONDS; goto repeat_rel; } @@ -3189,9 +3233,9 @@ repeat_rel: if (yyHaveDay && !yyHaveDate) { /* if needed assemble julianDay now */ - if (info->flags & CLF_INVALIDATE_JULIANDAY) { + if (info->flags & CLF_ASSEMBLE_JULIANDAY) { GetJulianDayFromEraYearMonthDay(&yydate, GREGORIAN_CHANGE_DATE); - info->flags &= ~CLF_INVALIDATE_JULIANDAY; + info->flags &= ~CLF_ASSEMBLE_JULIANDAY; } yydate.era = CE; @@ -3200,7 +3244,7 @@ repeat_rel: if (yyDayOrdinal > 0) { yydate.julianDay -= 7; } - info->flags |= CLF_INVALIDATE_DATE|CLF_INVALIDATE_SECONDS; + info->flags |= CLF_ASSEMBLE_DATE|CLF_ASSEMBLE_SECONDS; } /* Free scanning completed - date ready */ diff --git a/generic/tclClockFmt.c b/generic/tclClockFmt.c index ba924fd..2c1dfc1 100644 --- a/generic/tclClockFmt.c +++ b/generic/tclClockFmt.c @@ -678,40 +678,43 @@ ClockScnToken_LocaleListMatcher_Proc(ClockFmtScnCmdArgs *opts, static const char *ScnSTokenMapIndex = - "dmbyYHMSJCs"; + "dmbyYHMSJjCs"; static ClockScanTokenMap ScnSTokenMap[] = { /* %d %e */ - {CTOKT_DIGIT, CLF_DATE, 1, 2, TclOffset(DateInfo, date.dayOfMonth), + {CTOKT_DIGIT, CLF_DATE | CLF_DAYOFMONTH, CLF_DAYOFYEAR, 1, 2, TclOffset(DateInfo, date.dayOfMonth), NULL}, /* %m */ - {CTOKT_DIGIT, CLF_DATE, 1, 2, TclOffset(DateInfo, date.month), + {CTOKT_DIGIT, CLF_DATE, CLF_DAYOFYEAR, 1, 2, TclOffset(DateInfo, date.month), NULL}, /* %b %B %h */ - {CTOKT_PARSER, CLF_DATE, 0, 0, 0, + {CTOKT_PARSER, CLF_DATE, CLF_DAYOFYEAR, 0, 0, 0, ClockScnToken_Month_Proc}, /* %y */ - {CTOKT_DIGIT, CLF_DATE, 1, 2, TclOffset(DateInfo, date.year), + {CTOKT_DIGIT, CLF_DATE, 0, 1, 2, TclOffset(DateInfo, date.year), NULL}, /* %Y */ - {CTOKT_DIGIT, CLF_DATE | CLF_CENTURY, 1, 4, TclOffset(DateInfo, date.year), + {CTOKT_DIGIT, CLF_DATE | CLF_CENTURY, 0, 1, 4, TclOffset(DateInfo, date.year), NULL}, /* %H */ - {CTOKT_DIGIT, CLF_TIME, 1, 2, TclOffset(DateInfo, date.hour), + {CTOKT_DIGIT, CLF_TIME, 0, 1, 2, TclOffset(DateInfo, date.hour), NULL}, /* %M */ - {CTOKT_DIGIT, CLF_TIME, 1, 2, TclOffset(DateInfo, date.minutes), + {CTOKT_DIGIT, CLF_TIME, 0, 1, 2, TclOffset(DateInfo, date.minutes), NULL}, /* %S */ - {CTOKT_DIGIT, CLF_TIME, 1, 2, TclOffset(DateInfo, date.secondOfDay), + {CTOKT_DIGIT, CLF_TIME, 0, 1, 2, TclOffset(DateInfo, date.secondOfDay), NULL}, /* %J */ - {CTOKT_DIGIT, CLF_DATE | CLF_JULIANDAY, 1, 0xffff, TclOffset(DateInfo, date.julianDay), + {CTOKT_DIGIT, CLF_DATE | CLF_JULIANDAY, 0, 1, 0xffff, TclOffset(DateInfo, date.julianDay), + NULL}, + /* %j */ + {CTOKT_DIGIT, CLF_DATE | CLF_DAYOFYEAR, CLF_DAYOFMONTH, 1, 3, TclOffset(DateInfo, date.dayOfYear), NULL}, /* %C */ - {CTOKT_DIGIT, CLF_DATE | CLF_CENTURY, 1, 2, TclOffset(DateInfo, dateCentury), + {CTOKT_DIGIT, CLF_DATE | CLF_CENTURY, 0, 1, 2, TclOffset(DateInfo, dateCentury), NULL}, /* %s */ - {CTOKT_DIGIT, CLF_LOCALSEC | CLF_SIGNED, 1, 0xffff, TclOffset(DateInfo, date.localSeconds), + {CTOKT_DIGIT, CLF_LOCALSEC | CLF_SIGNED, 0, 1, 0xffff, TclOffset(DateInfo, date.localSeconds), NULL}, }; static const char *ScnSTokenWrapMapIndex[2] = { @@ -733,10 +736,10 @@ static const char *ScnOTokenMapIndex = "dm"; static ClockScanTokenMap ScnOTokenMap[] = { /* %Od %Oe */ - {CTOKT_PARSER, CLF_DATE, 0, 0, TclOffset(DateInfo, date.dayOfMonth), + {CTOKT_PARSER, CLF_DATE | CLF_DAYOFMONTH, CLF_DAYOFYEAR, 0, 0, TclOffset(DateInfo, date.dayOfMonth), ClockScnToken_LocaleListMatcher_Proc, (void *)MCLIT_LOCALE_NUMERALS}, /* %Om */ - {CTOKT_PARSER, CLF_DATE, 0, 0, TclOffset(DateInfo, date.month), + {CTOKT_PARSER, CLF_DATE, CLF_DAYOFYEAR, 0, 0, TclOffset(DateInfo, date.month), ClockScnToken_LocaleListMatcher_Proc, (void *)MCLIT_LOCALE_NUMERALS}, }; static const char *ScnOTokenWrapMapIndex[2] = { @@ -747,12 +750,12 @@ static const char *ScnOTokenWrapMapIndex[2] = { static const char *ScnSpecTokenMapIndex = " "; static ClockScanTokenMap ScnSpecTokenMap[] = { - {CTOKT_SPACE, 0, 1, 0xffff, 0, + {CTOKT_SPACE, 0, 0, 1, 0xffff, 0, NULL}, }; static ClockScanTokenMap ScnWordTokenMap = { - CTOKT_WORD, 0, 1, 0, 0, + CTOKT_WORD, 0, 0, 1, 0, 0, NULL }; @@ -1095,7 +1098,7 @@ ClockScan( } p = x; } - flags |= map->flags; + flags = (flags & ~map->clearFlags) | map->flags; } break; case CTOKT_PARSER: @@ -1110,7 +1113,7 @@ ClockScan( break; }; p = yyInput; - flags |= map->flags; + flags = (flags & ~map->clearFlags) | map->flags; break; case CTOKT_SPACE: /* at least one space in strict mode */ @@ -1150,13 +1153,14 @@ ClockScan( /* * Invalidate result */ + info->flags |= flags; /* seconds token (%s) take precedence over all other tokens */ if ((opts->flags & CLF_EXTENDED) || !(flags & CLF_LOCALSEC)) { if (flags & CLF_DATE) { if (!(flags & CLF_JULIANDAY)) { - info->flags |= CLF_INVALIDATE_SECONDS|CLF_INVALIDATE_JULIANDAY; + info->flags |= CLF_ASSEMBLE_SECONDS|CLF_ASSEMBLE_JULIANDAY; if (yyYear < 100) { if (!(flags & CLF_CENTURY)) { @@ -1172,18 +1176,18 @@ ClockScan( } /* if date but no time - reset time */ if (!(flags & (CLF_TIME|CLF_LOCALSEC))) { - info->flags |= CLF_INVALIDATE_SECONDS; + info->flags |= CLF_ASSEMBLE_SECONDS; yydate.localSeconds = 0; } } if (flags & CLF_TIME) { - info->flags |= CLF_INVALIDATE_SECONDS; + info->flags |= CLF_ASSEMBLE_SECONDS; yySeconds = ToSeconds(yyHour, yyMinutes, yySeconds, yyMeridian); } else if (!(flags & CLF_LOCALSEC)) { - info->flags |= CLF_INVALIDATE_SECONDS; + info->flags |= CLF_ASSEMBLE_SECONDS; yySeconds = yydate.localSeconds % SECONDS_PER_DAY; } } diff --git a/generic/tclDate.h b/generic/tclDate.h index 9f65b1b..23fe5b3 100644 --- a/generic/tclDate.h +++ b/generic/tclDate.h @@ -30,10 +30,18 @@ #define ONE_YEAR 365 /* days */ +#define CLF_DATE (1 << 2) +#define CLF_JULIANDAY (1 << 3) +#define CLF_TIME (1 << 4) +#define CLF_LOCALSEC (1 << 5) +#define CLF_CENTURY (1 << 6) +#define CLF_DAYOFMONTH (1 << 7) +#define CLF_DAYOFYEAR (1 << 8) +#define CLF_SIGNED (1 << 15) /* On demand (lazy) assemble flags */ -#define CLF_INVALIDATE_DATE (1 << 6) /* assemble year, month, etc. using julianDay */ -#define CLF_INVALIDATE_JULIANDAY (1 << 7) /* assemble julianDay using year, month, etc. */ -#define CLF_INVALIDATE_SECONDS (1 << 8) /* assemble localSeconds (and seconds at end) */ +#define CLF_ASSEMBLE_DATE (1 << 28) /* assemble year, month, etc. using julianDay */ +#define CLF_ASSEMBLE_JULIANDAY (1 << 29) /* assemble julianDay using year, month, etc. */ +#define CLF_ASSEMBLE_SECONDS (1 << 30) /* assemble localSeconds (and seconds at end) */ /* @@ -339,13 +347,6 @@ typedef int ClockScanTokenProc( ClockScanToken *tok); -#define CLF_DATE (1 << 2) -#define CLF_JULIANDAY (1 << 3) -#define CLF_TIME (1 << 4) -#define CLF_LOCALSEC (1 << 5) -#define CLF_CENTURY (1 << 6) -#define CLF_SIGNED (1 << 8) - typedef enum _CLCKTOK_TYPE { CTOKT_DIGIT = 1, CTOKT_PARSER, CTOKT_SPACE, CTOKT_WORD } CLCKTOK_TYPE; @@ -359,6 +360,7 @@ typedef struct ClockFormatToken { typedef struct ClockScanTokenMap { unsigned short int type; unsigned short int flags; + unsigned short int clearFlags; unsigned short int minSize; unsigned short int maxSize; unsigned short int offs; -- cgit v0.12 From feb62aa2bdc63e80cb401c06a17959af188f14c9 Mon Sep 17 00:00:00 2001 From: sebres Date: Tue, 10 Jan 2017 22:32:46 +0000 Subject: scan format: several tokens implemented, bug fixing and code review; precedence yyyymmdd over yyyyddd was changed (and re-covered in test-cases also), see http://core.tcl.tk/tcl/tktview/e7a722cd3573fedda5d1e528f95902776f996e06 --- generic/tclClock.c | 25 +-- generic/tclClockFmt.c | 384 +++++++++++++++++++++++++++++++++++++++------- generic/tclDate.h | 21 ++- library/clock.tcl | 37 ++++- library/msgcat/msgcat.tcl | 5 + tests/clock.test | 66 ++++---- 6 files changed, 436 insertions(+), 102 deletions(-) diff --git a/generic/tclClock.c b/generic/tclClock.c index ef0e46b..1a5141b 100644 --- a/generic/tclClock.c +++ b/generic/tclClock.c @@ -473,13 +473,12 @@ ClockMCDict(ClockFmtScnCmdArgs *opts) } if (opts->mcDictObj == NULL) { - Tcl_Obj *callargs[3]; - /* get msgcat dictionary - ::msgcat::mcget ::tcl::clock locale */ + Tcl_Obj *callargs[2]; + /* get msgcat dictionary - ::tcl::clock::mcget locale */ callargs[0] = dataPtr->literals[LIT_MCGET]; - callargs[1] = dataPtr->literals[LIT_TCL_CLOCK]; - callargs[2] = opts->localeObj; + callargs[1] = opts->localeObj; - if (Tcl_EvalObjv(opts->interp, 3, callargs, 0) != TCL_OK) { + if (Tcl_EvalObjv(opts->interp, 2, callargs, 0) != TCL_OK) { return NULL; } @@ -823,7 +822,7 @@ ClockGetSystemTimeZone( /* *---------------------------------------------------------------------- */ -static Tcl_Obj * +MODULE_SCOPE Tcl_Obj * ClockSetupTimeZone( ClientData clientData, /* Opaque pointer to literal pool, etc. */ Tcl_Interp *interp, /* Tcl interpreter */ @@ -2948,7 +2947,11 @@ ClockScanObjCmd( /* If needed assemble julianDay using year, month, etc. */ if (info->flags & CLF_ASSEMBLE_JULIANDAY) { - if ((info->flags & CLF_DAYOFMONTH) || !(info->flags & CLF_DAYOFYEAR)) { + if ((info->flags & CLF_ISO8601)) { + GetJulianDayFromEraYearWeekDay(&yydate, GREGORIAN_CHANGE_DATE); + } + else + if (!(info->flags & CLF_DAYOFYEAR)) { GetJulianDayFromEraYearMonthDay(&yydate, GREGORIAN_CHANGE_DATE); } else { GetJulianDayFromEraYearDay(&yydate, GREGORIAN_CHANGE_DATE); @@ -3065,11 +3068,11 @@ ClockFreeScan( int dstFlag = 1 - yyDSTmode; tzObjStor = ClockFormatNumericTimeZone( 60 * minEast + 3600 * dstFlag); - + Tcl_IncrRefCount(tzObjStor); + opts->timezoneObj = ClockSetupTimeZone(clientData, interp, tzObjStor); - if (tzObjStor != opts->timezoneObj) { - Tcl_DecrRefCount(tzObjStor); - } + + Tcl_DecrRefCount(tzObjStor); if (opts->timezoneObj == NULL) { goto done; } diff --git a/generic/tclClockFmt.c b/generic/tclClockFmt.c index 2c1dfc1..f965a17 100644 --- a/generic/tclClockFmt.c +++ b/generic/tclClockFmt.c @@ -508,27 +508,14 @@ void DetermineGreedySearchLen(ClockFmtScnCmdArgs *opts, } } -static int -LocaleListSearch(ClockFmtScnCmdArgs *opts, - DateInfo *info, int mcKey, int *val, +inline int +ObjListSearch(ClockFmtScnCmdArgs *opts, + DateInfo *info, int *val, + Tcl_Obj **lstv, int lstc, int minLen, int maxLen) { - Tcl_Obj **lstv; - int lstc, i, l, lf = -1; + int i, l, lf = -1; const char *s; - Tcl_Obj *valObj; - - /* get msgcat value */ - valObj = ClockMCGet(opts, mcKey); - if (valObj == NULL) { - return TCL_ERROR; - } - - /* is a list */ - if (TclListObjGetElements(opts->interp, valObj, &lstc, &lstv) != TCL_OK) { - return TCL_ERROR; - } - /* search in list */ for (i = 0; i < lstc; i++) { s = TclGetString(lstv[i]); @@ -561,6 +548,31 @@ LocaleListSearch(ClockFmtScnCmdArgs *opts, } static int +LocaleListSearch(ClockFmtScnCmdArgs *opts, + DateInfo *info, int mcKey, int *val, + int minLen, int maxLen) +{ + Tcl_Obj **lstv; + int lstc; + Tcl_Obj *valObj; + + /* get msgcat value */ + valObj = ClockMCGet(opts, mcKey); + if (valObj == NULL) { + return TCL_ERROR; + } + + /* is a list */ + if (TclListObjGetElements(opts->interp, valObj, &lstc, &lstv) != TCL_OK) { + return TCL_ERROR; + } + + /* search in list */ + return ObjListSearch(opts, info, val, lstv, lstc, + minLen, maxLen); +} + +static int StaticListSearch(ClockFmtScnCmdArgs *opts, DateInfo *info, const char **lst, int *val) { @@ -631,8 +643,7 @@ ClockScnToken_Month_Proc(ClockFmtScnCmdArgs *opts, */ int ret, val; - int minLen; - int maxLen; + int minLen, maxLen; DetermineGreedySearchLen(opts, info, tok, &minLen, &maxLen); @@ -653,15 +664,115 @@ ClockScnToken_Month_Proc(ClockFmtScnCmdArgs *opts, return TCL_OK; } + +static int +ClockScnToken_DayOfWeek_Proc(ClockFmtScnCmdArgs *opts, + DateInfo *info, ClockScanToken *tok) +{ + int ret, val; + int minLen, maxLen; + char curTok = *tok->tokWord.start; + + DetermineGreedySearchLen(opts, info, tok, &minLen, &maxLen); + + /* %u %w %Ou %Ow */ + if ( curTok != 'a' && curTok != 'A' + && ((minLen <= 1 && maxLen >= 1) || (int)tok->map->data) + ) { + + val = -1; + + if (!(int)tok->map->data) { + if (*yyInput >= '0' && *yyInput <= '9') { + val = *yyInput - '0'; + } + } else { + int ret = LocaleListSearch(opts, info, (int)tok->map->data, &val, + minLen, maxLen); + if (ret == TCL_ERROR) { + return ret; + } + } + + if (val != -1) { + if (val == 0) { + val = 7; + } + if (val > 7 && curTok != 'a' && curTok != 'A') { + Tcl_SetResult(opts->interp, "day of week is greater than 7", + TCL_STATIC); + Tcl_SetErrorCode(opts->interp, "CLOCK", "badDayOfWeek", NULL); + return TCL_ERROR; + } + info->date.dayOfWeek = val; + yyInput++; + return TCL_OK; + } + + + return TCL_RETURN; + } + + /* %a %A */ + ret = LocaleListSearch(opts, info, MCLIT_DAYS_OF_WEEK_FULL, &val, + minLen, maxLen); + if (ret != TCL_OK) { + /* if not found */ + if (ret == TCL_RETURN) { + ret = LocaleListSearch(opts, info, MCLIT_DAYS_OF_WEEK_ABBREV, &val, + minLen, maxLen); + } + if (ret != TCL_OK) { + return ret; + } + } + + if (val == 0) { + val = 7; + } + info->date.dayOfWeek = val; + return TCL_OK; + +} + +static int +ClockScnToken_amPmInd_Proc(ClockFmtScnCmdArgs *opts, + DateInfo *info, ClockScanToken *tok) +{ + int ret, val; + int minLen, maxLen; + Tcl_Obj *amPmObj[2]; + + DetermineGreedySearchLen(opts, info, tok, &minLen, &maxLen); + + amPmObj[0] = ClockMCGet(opts, MCLIT_AM); + amPmObj[1] = ClockMCGet(opts, MCLIT_PM); + + if (amPmObj[0] == NULL || amPmObj == NULL) { + return TCL_ERROR; + } + + ret = ObjListSearch(opts, info, &val, amPmObj, 2, + minLen, maxLen); + if (ret != TCL_OK) { + return ret; + } + + if (val == 0) { + yyMeridian = MERam; + } else { + yyMeridian = MERpm; + } + return TCL_OK; +} static int ClockScnToken_LocaleListMatcher_Proc(ClockFmtScnCmdArgs *opts, DateInfo *info, ClockScanToken *tok) { int ret, val; - int minLen; - int maxLen; + int minLen, maxLen; DetermineGreedySearchLen(opts, info, tok, &minLen, &maxLen); @@ -675,27 +786,106 @@ ClockScnToken_LocaleListMatcher_Proc(ClockFmtScnCmdArgs *opts, return TCL_OK; } + +static int +ClockScnToken_TimeZone_Proc(ClockFmtScnCmdArgs *opts, + DateInfo *info, ClockScanToken *tok) +{ + int minLen, maxLen; + int len = 0; + register const char *p = yyInput; + Tcl_Obj *tzObjStor = NULL; + + DetermineGreedySearchLen(opts, info, tok, &minLen, &maxLen); + + /* numeric timezone */ + if (*p == '+' || *p == '-') { + /* max chars in numeric zone = "+00:00:00" */ + #define MAX_ZONE_LEN 9 + char buf[MAX_ZONE_LEN + 1]; + char *bp = buf; + *bp++ = *p++; len++; + if (maxLen > MAX_ZONE_LEN) + maxLen = MAX_ZONE_LEN; + /* cumulate zone into buf without ':' */ + while (len + 1 < maxLen) { + if (!isdigit(UCHAR(*p))) break; + *bp++ = *p++; len++; + if (!isdigit(UCHAR(*p))) break; + *bp++ = *p++; len++; + if (len + 2 < maxLen) { + if (*p == ':') { + *p++; len++; + } + } + } + *bp = '\0'; + + if (len < minLen) { + return TCL_RETURN; + } + #undef MAX_ZONE_LEN + + /* timezone */ + tzObjStor = Tcl_NewStringObj(buf, bp-buf); + } else { + /* legacy (alnum) timezone like CEST, etc. */ + if (maxLen > 4) + maxLen = 4; + while (len < maxLen) { + if ( (*p & 0x80) + || (!isalpha(UCHAR(*p)) && !isdigit(UCHAR(*p))) + ) { /* INTL: ISO only. */ + break; + } + p++; len++; + } + if (len < minLen) { + return TCL_RETURN; + } + + /* timezone */ + tzObjStor = Tcl_NewStringObj(yyInput, p-yyInput); + + /* convert using dict */ + } + + /* try to apply new time zone */ + Tcl_IncrRefCount(tzObjStor); + + opts->timezoneObj = ClockSetupTimeZone(opts->clientData, opts->interp, + tzObjStor); + + Tcl_DecrRefCount(tzObjStor); + if (opts->timezoneObj == NULL) { + return TCL_ERROR; + } + + yyInput += len; + return TCL_OK; +} + static const char *ScnSTokenMapIndex = - "dmbyYHMSJjCs"; + "dmbyYHMSpJjCgGVazs"; static ClockScanTokenMap ScnSTokenMap[] = { /* %d %e */ - {CTOKT_DIGIT, CLF_DATE | CLF_DAYOFMONTH, CLF_DAYOFYEAR, 1, 2, TclOffset(DateInfo, date.dayOfMonth), + {CTOKT_DIGIT, CLF_DAYOFMONTH, 0, 1, 2, TclOffset(DateInfo, date.dayOfMonth), NULL}, /* %m */ - {CTOKT_DIGIT, CLF_DATE, CLF_DAYOFYEAR, 1, 2, TclOffset(DateInfo, date.month), + {CTOKT_DIGIT, CLF_MONTH, 0, 1, 2, TclOffset(DateInfo, date.month), NULL}, /* %b %B %h */ - {CTOKT_PARSER, CLF_DATE, CLF_DAYOFYEAR, 0, 0, 0, + {CTOKT_PARSER, CLF_MONTH, 0, 0, 0, 0, ClockScnToken_Month_Proc}, /* %y */ - {CTOKT_DIGIT, CLF_DATE, 0, 1, 2, TclOffset(DateInfo, date.year), + {CTOKT_DIGIT, CLF_YEAR, 0, 1, 2, TclOffset(DateInfo, date.year), NULL}, /* %Y */ - {CTOKT_DIGIT, CLF_DATE | CLF_CENTURY, 0, 1, 4, TclOffset(DateInfo, date.year), + {CTOKT_DIGIT, CLF_YEAR | CLF_CENTURY, 0, 1, 4, TclOffset(DateInfo, date.year), NULL}, - /* %H */ + /* %H %k %I %l */ {CTOKT_DIGIT, CLF_TIME, 0, 1, 2, TclOffset(DateInfo, date.hour), NULL}, /* %M */ @@ -704,22 +894,40 @@ static ClockScanTokenMap ScnSTokenMap[] = { /* %S */ {CTOKT_DIGIT, CLF_TIME, 0, 1, 2, TclOffset(DateInfo, date.secondOfDay), NULL}, + /* %p %P */ + {CTOKT_PARSER, CLF_ISO8601, 0, 0, 0, 0, + ClockScnToken_amPmInd_Proc, NULL}, /* %J */ - {CTOKT_DIGIT, CLF_DATE | CLF_JULIANDAY, 0, 1, 0xffff, TclOffset(DateInfo, date.julianDay), + {CTOKT_DIGIT, CLF_JULIANDAY, 0, 1, 0xffff, TclOffset(DateInfo, date.julianDay), NULL}, /* %j */ - {CTOKT_DIGIT, CLF_DATE | CLF_DAYOFYEAR, CLF_DAYOFMONTH, 1, 3, TclOffset(DateInfo, date.dayOfYear), + {CTOKT_DIGIT, CLF_DAYOFYEAR, 0, 1, 3, TclOffset(DateInfo, date.dayOfYear), NULL}, /* %C */ - {CTOKT_DIGIT, CLF_DATE | CLF_CENTURY, 0, 1, 2, TclOffset(DateInfo, dateCentury), + {CTOKT_DIGIT, CLF_CENTURY|CLF_ISO8601CENTURY, 0, 1, 2, TclOffset(DateInfo, dateCentury), + NULL}, + /* %g */ + {CTOKT_DIGIT, CLF_ISO8601YEAR | CLF_ISO8601, 0, 2, 2, TclOffset(DateInfo, date.iso8601Year), + NULL}, + /* %G */ + {CTOKT_DIGIT, CLF_ISO8601YEAR | CLF_ISO8601 | CLF_ISO8601CENTURY, 0, 1, 4, TclOffset(DateInfo, date.iso8601Year), NULL}, + /* %V */ + {CTOKT_DIGIT, CLF_ISO8601, 0, 1, 2, TclOffset(DateInfo, date.iso8601Week), + NULL}, + /* %a %A %u %w */ + {CTOKT_PARSER, CLF_ISO8601, 0, 0, 0, 0, + ClockScnToken_DayOfWeek_Proc, NULL}, + /* %z %Z */ + {CTOKT_PARSER, 0, 0, 0, 0, 0, + ClockScnToken_TimeZone_Proc, NULL}, /* %s */ {CTOKT_DIGIT, CLF_LOCALSEC | CLF_SIGNED, 0, 1, 0xffff, TclOffset(DateInfo, date.localSeconds), NULL}, }; static const char *ScnSTokenWrapMapIndex[2] = { - "eNBh", - "dmbb" + "eNBhkIlPAuwZ", + "dmbbHHHpaaaz" }; static const char *ScnETokenMapIndex = @@ -733,18 +941,33 @@ static const char *ScnETokenWrapMapIndex[2] = { }; static const char *ScnOTokenMapIndex = - "dm"; + "dmyHMSu"; static ClockScanTokenMap ScnOTokenMap[] = { /* %Od %Oe */ - {CTOKT_PARSER, CLF_DATE | CLF_DAYOFMONTH, CLF_DAYOFYEAR, 0, 0, TclOffset(DateInfo, date.dayOfMonth), + {CTOKT_PARSER, CLF_DAYOFMONTH, 0, 0, 0, TclOffset(DateInfo, date.dayOfMonth), ClockScnToken_LocaleListMatcher_Proc, (void *)MCLIT_LOCALE_NUMERALS}, /* %Om */ - {CTOKT_PARSER, CLF_DATE, CLF_DAYOFYEAR, 0, 0, TclOffset(DateInfo, date.month), + {CTOKT_PARSER, CLF_MONTH, 0, 0, 0, TclOffset(DateInfo, date.month), + ClockScnToken_LocaleListMatcher_Proc, (void *)MCLIT_LOCALE_NUMERALS}, + /* %Oy */ + {CTOKT_PARSER, CLF_YEAR, 0, 0, 0, TclOffset(DateInfo, date.year), + ClockScnToken_LocaleListMatcher_Proc, (void *)MCLIT_LOCALE_NUMERALS}, + /* %OH %Ok %OI %Ol */ + {CTOKT_PARSER, CLF_TIME, 0, 0, 0, TclOffset(DateInfo, date.hour), + ClockScnToken_LocaleListMatcher_Proc, (void *)MCLIT_LOCALE_NUMERALS}, + /* %OM */ + {CTOKT_PARSER, CLF_TIME, 0, 0, 0, TclOffset(DateInfo, date.minutes), ClockScnToken_LocaleListMatcher_Proc, (void *)MCLIT_LOCALE_NUMERALS}, + /* %OS */ + {CTOKT_PARSER, CLF_TIME, 0, 0, 0, TclOffset(DateInfo, date.secondOfDay), + ClockScnToken_LocaleListMatcher_Proc, (void *)MCLIT_LOCALE_NUMERALS}, + /* %Ou Ow */ + {CTOKT_PARSER, CLF_ISO8601, 0, 0, 0, 0, + ClockScnToken_DayOfWeek_Proc, (void *)MCLIT_LOCALE_NUMERALS}, }; static const char *ScnOTokenWrapMapIndex[2] = { - "e", - "d" + "ekIlw", + "dHHHu" }; static const char *ScnSpecTokenMapIndex = @@ -1153,7 +1376,6 @@ ClockScan( /* * Invalidate result */ - info->flags |= flags; /* seconds token (%s) take precedence over all other tokens */ if ((opts->flags & CLF_EXTENDED) || !(flags & CLF_LOCALSEC)) { @@ -1162,23 +1384,78 @@ ClockScan( if (!(flags & CLF_JULIANDAY)) { info->flags |= CLF_ASSEMBLE_SECONDS|CLF_ASSEMBLE_JULIANDAY; - if (yyYear < 100) { - if (!(flags & CLF_CENTURY)) { - if (yyYear >= dataPtr->yearOfCenturySwitch) { - yyYear -= 100; + /* dd precedence below ddd */ + switch (flags & (CLF_MONTH|CLF_DAYOFYEAR|CLF_DAYOFMONTH)) { + case (CLF_DAYOFYEAR|CLF_DAYOFMONTH): + /* miss month: ddd over dd (without month) */ + flags &= ~CLF_DAYOFMONTH; + case (CLF_DAYOFYEAR): + /* ddd over naked weekday */ + if (!(flags & CLF_ISO8601YEAR)) { + flags &= ~CLF_ISO8601; + } + break; + case (CLF_MONTH|CLF_DAYOFYEAR|CLF_DAYOFMONTH): + /* both available: mmdd over ddd */ + flags &= ~CLF_DAYOFYEAR; + case (CLF_MONTH|CLF_DAYOFMONTH): + case (CLF_DAYOFMONTH): + /* mmdd / dd over naked weekday */ + if (!(flags & CLF_ISO8601YEAR)) { + flags &= ~CLF_ISO8601; + } + break; + } + + /* YearWeekDay below YearMonthDay */ + if ( (flags & CLF_ISO8601) + && ( (flags & (CLF_YEAR|CLF_DAYOFYEAR)) == (CLF_YEAR|CLF_DAYOFYEAR) + || (flags & (CLF_YEAR|CLF_DAYOFMONTH|CLF_MONTH)) == (CLF_YEAR|CLF_DAYOFMONTH|CLF_MONTH) + ) + ) { + /* yy precedence below yyyy */ + if (!(flags & CLF_ISO8601CENTURY) && (flags & CLF_CENTURY)) { + /* normally precedence of ISO is higher, but no century - so put it down */ + flags &= ~CLF_ISO8601; + } + else + /* yymmdd or yyddd over naked weekday */ + if (!(flags & CLF_ISO8601YEAR)) { + flags &= ~CLF_ISO8601; + } + } + + if (!(flags & CLF_ISO8601)) { + if (yyYear < 100) { + if (!(flags & CLF_CENTURY)) { + if (yyYear >= dataPtr->yearOfCenturySwitch) { + yyYear -= 100; + } + yyYear += dataPtr->currentYearCentury; + } else { + yyYear += info->dateCentury * 100; + } + } + } else { + if (info->date.iso8601Year < 100) { + if (!(flags & CLF_ISO8601CENTURY)) { + if (info->date.iso8601Year >= dataPtr->yearOfCenturySwitch) { + info->date.iso8601Year -= 100; + } + info->date.iso8601Year += dataPtr->currentYearCentury; + } else { + info->date.iso8601Year += info->dateCentury * 100; } - yyYear += dataPtr->currentYearCentury; - } else { - yyYear += info->dateCentury * 100; } } yydate.era = CE; } - /* if date but no time - reset time */ - if (!(flags & (CLF_TIME|CLF_LOCALSEC))) { - info->flags |= CLF_ASSEMBLE_SECONDS; - yydate.localSeconds = 0; - } + } + + /* if no time - reset time */ + if (!(flags & (CLF_TIME|CLF_LOCALSEC))) { + info->flags |= CLF_ASSEMBLE_SECONDS; + yydate.localSeconds = 0; } if (flags & CLF_TIME) { @@ -1192,6 +1469,9 @@ ClockScan( } } + /* tell caller which flags were set */ + info->flags |= flags; + ret = TCL_OK; goto done; diff --git a/generic/tclDate.h b/generic/tclDate.h index 23fe5b3..fc922cb 100644 --- a/generic/tclDate.h +++ b/generic/tclDate.h @@ -30,19 +30,26 @@ #define ONE_YEAR 365 /* days */ -#define CLF_DATE (1 << 2) #define CLF_JULIANDAY (1 << 3) #define CLF_TIME (1 << 4) #define CLF_LOCALSEC (1 << 5) #define CLF_CENTURY (1 << 6) #define CLF_DAYOFMONTH (1 << 7) #define CLF_DAYOFYEAR (1 << 8) +#define CLF_MONTH (1 << 9) +#define CLF_YEAR (1 << 10) +#define CLF_ISO8601YEAR (1 << 12) +#define CLF_ISO8601 (1 << 13) +#define CLF_ISO8601CENTURY (1 << 14) #define CLF_SIGNED (1 << 15) /* On demand (lazy) assemble flags */ #define CLF_ASSEMBLE_DATE (1 << 28) /* assemble year, month, etc. using julianDay */ #define CLF_ASSEMBLE_JULIANDAY (1 << 29) /* assemble julianDay using year, month, etc. */ #define CLF_ASSEMBLE_SECONDS (1 << 30) /* assemble localSeconds (and seconds at end) */ +#define CLF_DATE (CLF_JULIANDAY | CLF_DAYOFMONTH | CLF_DAYOFYEAR | \ + CLF_MONTH | CLF_YEAR | CLF_ISO8601YEAR | CLF_ISO8601) + /* * Enumeration of the string literals used in [clock] @@ -87,7 +94,7 @@ typedef enum ClockLiteral { "::tcl::clock::TZData", \ "::tcl::clock::GetSystemTimeZone", \ "::tcl::clock::SetupTimeZone", \ - "::msgcat::mcget", "::tcl::clock", \ + "::tcl::clock::mcget", "::tcl::clock", \ "::tcl::clock::LocalizeFormat" \ } @@ -96,13 +103,19 @@ typedef enum ClockLiteral { */ typedef enum ClockMsgCtLiteral { + MCLIT__NIL, /* placeholder */ MCLIT_MONTHS_FULL, MCLIT_MONTHS_ABBREV, + MCLIT_DAYS_OF_WEEK_FULL, MCLIT_DAYS_OF_WEEK_ABBREV, + MCLIT_AM, MCLIT_PM, MCLIT_LOCALE_NUMERALS, MCLIT__END } ClockMsgCtLiteral; #define CLOCK_LOCALE_LITERAL_ARRAY(litarr, pref) static const char *const litarr[] = { \ + pref "", \ pref "MONTHS_FULL", pref "MONTHS_ABBREV", \ + pref "DAYS_OF_WEEK_FULL", pref "DAYS_OF_WEEK_ABBREV", \ + pref "AM", pref "PM", \ pref "LOCALE_NUMERALS", \ } @@ -406,6 +419,10 @@ MODULE_SCOPE int TclClockFreeScan(Tcl_Interp *interp, DateInfo *info); /* tclClock.c module declarations */ MODULE_SCOPE Tcl_Obj * + ClockSetupTimeZone(ClientData clientData, + Tcl_Interp *interp, Tcl_Obj *timezoneObj); + +MODULE_SCOPE Tcl_Obj * ClockMCDict(ClockFmtScnCmdArgs *opts); MODULE_SCOPE Tcl_Obj * ClockMCGet(ClockFmtScnCmdArgs *opts, int mcKey); diff --git a/library/clock.tcl b/library/clock.tcl index a532c0d..d4e29d5 100755 --- a/library/clock.tcl +++ b/library/clock.tcl @@ -629,15 +629,17 @@ proc ::tcl::clock::Initialize {} { # Caches - variable LocaleFormats {}; # Dictionary with localized formats + variable LocaleFormats \ + [dict create]; # Dictionary with localized formats - variable LocaleNumeralCache {}; # Dictionary whose keys are locale + variable LocaleNumeralCache \ + [dict create]; # Dictionary whose keys are locale # names and whose values are pairs # comprising regexes matching numerals # in the given locales and dictionaries # mapping the numerals to their numeric # values. - variable TimeZoneBad {}; # Dictionary whose keys are time zone + variable TimeZoneBad [dict create]; # Dictionary whose keys are time zone # names and whose values are 1 if # the time zone is unknown and 0 # if it is known. @@ -653,6 +655,17 @@ proc ::tcl::clock::Initialize {} { ::tcl::clock::Initialize #---------------------------------------------------------------------- + +proc mcget {locale args} { + switch -- $locale system { + set locale [GetSystemLocale] + } current { + set locale [mclocale] + } + msgcat::mcget ::tcl::clock $locale {*}$args +} + +#---------------------------------------------------------------------- # # clock format -- # @@ -2938,7 +2951,7 @@ proc ::tcl::clock::ConvertLegacyTimeZone { tzname } { # #---------------------------------------------------------------------- -proc ::tcl::clock::SetupTimeZone { timezone } { +proc ::tcl::clock::SetupTimeZone { timezone {alias {}} } { variable TZData if {! [info exists TZData($timezone)] } { @@ -3005,6 +3018,19 @@ proc ::tcl::clock::SetupTimeZone { timezone } { } } else { + + variable LegacyTimeZone + + # Check may be a legacy zone: + if { $alias eq {} && ![catch { + set tzname [dict get $LegacyTimeZone [string tolower $timezone]] + }] } { + set tzname [::tcl::clock::SetupTimeZone $tzname $timezone] + set TZData($timezone) $TZData($tzname) + # tell backend - timezone is initialized and return shared timezone object: + return [configure -setup-tz $timezone] + } + # We couldn't parse this as a POSIX time zone. Try again with a # time zone file - this time without a colon @@ -4472,6 +4498,9 @@ proc ::tcl::clock::ClearCaches {} { # tell backend - should invalidate: configure -clear + # clear msgcat cache: + msgcat::ClearCaches ::tcl::clock + foreach p [info procs [namespace current]::scanproc'*] { rename $p {} } diff --git a/library/msgcat/msgcat.tcl b/library/msgcat/msgcat.tcl index a25f6c8..e6452d2 100644 --- a/library/msgcat/msgcat.tcl +++ b/library/msgcat/msgcat.tcl @@ -951,6 +951,11 @@ proc msgcat::Merge {ns locales} { return [dict smartref $mrgcat] } +proc msgcat::ClearCaches {ns} { + variable Merged + dict unset Merged $ns +} + # msgcat::Invoke -- # # Invoke a set of registered callbacks. diff --git a/tests/clock.test b/tests/clock.test index 22b5bc1..e96dec6 100644 --- a/tests/clock.test +++ b/tests/clock.test @@ -21070,78 +21070,78 @@ test clock-10.10 {julian day takes precedence over ccyyddd} { # BEGIN testcases11 -# Test precedence among yyyymmdd and yyyyddd +# Test precedence yyyymmdd over yyyyddd -test clock-11.1 {precedence of ccyyddd and ccyymmdd} { +test clock-11.1 {precedence of ccyymmdd over ccyyddd} { clock scan 19700101002 -format %Y%m%d%j -gmt 1 -} 86400 -test clock-11.2 {precedence of ccyyddd and ccyymmdd} { +} 0 +test clock-11.2 {precedence of ccyymmdd over ccyyddd} { clock scan 01197001002 -format %m%Y%d%j -gmt 1 -} 86400 -test clock-11.3 {precedence of ccyyddd and ccyymmdd} { +} 0 +test clock-11.3 {precedence of ccyymmdd over ccyyddd} { clock scan 01197001002 -format %d%Y%m%j -gmt 1 -} 86400 -test clock-11.4 {precedence of ccyyddd and ccyymmdd} { +} 0 +test clock-11.4 {precedence of ccyymmdd over ccyyddd} { clock scan 00219700101 -format %j%Y%m%d -gmt 1 } 0 -test clock-11.5 {precedence of ccyyddd and ccyymmdd} { +test clock-11.5 {precedence of ccyymmdd over ccyyddd} { clock scan 19700100201 -format %Y%m%j%d -gmt 1 } 0 -test clock-11.6 {precedence of ccyyddd and ccyymmdd} { +test clock-11.6 {precedence of ccyymmdd over ccyyddd} { clock scan 01197000201 -format %m%Y%j%d -gmt 1 } 0 -test clock-11.7 {precedence of ccyyddd and ccyymmdd} { +test clock-11.7 {precedence of ccyymmdd over ccyyddd} { clock scan 01197000201 -format %d%Y%j%m -gmt 1 } 0 -test clock-11.8 {precedence of ccyyddd and ccyymmdd} { +test clock-11.8 {precedence of ccyymmdd over ccyyddd} { clock scan 00219700101 -format %j%Y%d%m -gmt 1 } 0 -test clock-11.9 {precedence of ccyyddd and ccyymmdd} { +test clock-11.9 {precedence of ccyymmdd over ccyyddd} { clock scan 19700101002 -format %Y%d%m%j -gmt 1 -} 86400 -test clock-11.10 {precedence of ccyyddd and ccyymmdd} { +} 0 +test clock-11.10 {precedence of ccyymmdd over ccyyddd} { clock scan 01011970002 -format %m%d%Y%j -gmt 1 -} 86400 -test clock-11.11 {precedence of ccyyddd and ccyymmdd} { +} 0 +test clock-11.11 {precedence of ccyymmdd over ccyyddd} { clock scan 01011970002 -format %d%m%Y%j -gmt 1 -} 86400 -test clock-11.12 {precedence of ccyyddd and ccyymmdd} { +} 0 +test clock-11.12 {precedence of ccyymmdd over ccyyddd} { clock scan 00201197001 -format %j%m%Y%d -gmt 1 } 0 -test clock-11.13 {precedence of ccyyddd and ccyymmdd} { +test clock-11.13 {precedence of ccyymmdd over ccyyddd} { clock scan 19700100201 -format %Y%d%j%m -gmt 1 } 0 -test clock-11.14 {precedence of ccyyddd and ccyymmdd} { +test clock-11.14 {precedence of ccyymmdd over ccyyddd} { clock scan 01010021970 -format %m%d%j%Y -gmt 1 -} 86400 -test clock-11.15 {precedence of ccyyddd and ccyymmdd} { +} 0 +test clock-11.15 {precedence of ccyymmdd over ccyyddd} { clock scan 01010021970 -format %d%m%j%Y -gmt 1 -} 86400 -test clock-11.16 {precedence of ccyyddd and ccyymmdd} { +} 0 +test clock-11.16 {precedence of ccyymmdd over ccyyddd} { clock scan 00201011970 -format %j%m%d%Y -gmt 1 } 0 -test clock-11.17 {precedence of ccyyddd and ccyymmdd} { +test clock-11.17 {precedence of ccyymmdd over ccyyddd} { clock scan 19700020101 -format %Y%j%m%d -gmt 1 } 0 -test clock-11.18 {precedence of ccyyddd and ccyymmdd} { +test clock-11.18 {precedence of ccyymmdd over ccyyddd} { clock scan 01002197001 -format %m%j%Y%d -gmt 1 } 0 -test clock-11.19 {precedence of ccyyddd and ccyymmdd} { +test clock-11.19 {precedence of ccyymmdd over ccyyddd} { clock scan 01002197001 -format %d%j%Y%m -gmt 1 } 0 -test clock-11.20 {precedence of ccyyddd and ccyymmdd} { +test clock-11.20 {precedence of ccyymmdd over ccyyddd} { clock scan 00201197001 -format %j%d%Y%m -gmt 1 } 0 -test clock-11.21 {precedence of ccyyddd and ccyymmdd} { +test clock-11.21 {precedence of ccyymmdd over ccyyddd} { clock scan 19700020101 -format %Y%j%d%m -gmt 1 } 0 -test clock-11.22 {precedence of ccyyddd and ccyymmdd} { +test clock-11.22 {precedence of ccyymmdd over ccyyddd} { clock scan 01002011970 -format %m%j%d%Y -gmt 1 } 0 -test clock-11.23 {precedence of ccyyddd and ccyymmdd} { +test clock-11.23 {precedence of ccyymmdd over ccyyddd} { clock scan 01002011970 -format %d%j%m%Y -gmt 1 } 0 -test clock-11.24 {precedence of ccyyddd and ccyymmdd} { +test clock-11.24 {precedence of ccyymmdd over ccyyddd} { clock scan 00201011970 -format %j%d%m%Y -gmt 1 } 0 # END testcases11 -- cgit v0.12 From 02b4c1de38afe8c1a068834cbab9ea7f403e0c60 Mon Sep 17 00:00:00 2001 From: sebres Date: Tue, 10 Jan 2017 22:33:41 +0000 Subject: repaired system/current locale caching (also for legacy clock format) and legacy timezone cached as last --- generic/tclClock.c | 80 ++++++++++++++++++++++++++++++++++++++++++++------- generic/tclClockFmt.c | 4 ++- generic/tclDate.h | 16 +++++------ library/clock.tcl | 24 +++++++++------- 4 files changed, 93 insertions(+), 31 deletions(-) diff --git a/generic/tclClock.c b/generic/tclClock.c index 1a5141b..a84300a 100644 --- a/generic/tclClock.c +++ b/generic/tclClock.c @@ -383,16 +383,52 @@ NormTimezoneObj( /* *---------------------------------------------------------------------- */ +inline Tcl_Obj * +ClockGetSystemLocale( + ClockClientData *dataPtr, /* Opaque pointer to literal pool, etc. */ + Tcl_Interp *interp) /* Tcl interpreter */ +{ + if (Tcl_EvalObjv(interp, 1, &dataPtr->literals[LIT_GETSYSTEMLOCALE], 0) != TCL_OK) { + return NULL; + } + + return Tcl_GetObjResult(interp); +} +/* + *---------------------------------------------------------------------- + */ +inline Tcl_Obj * +ClockGetCurrentLocale( + ClockClientData *dataPtr, /* Client data containing literal pool */ + Tcl_Interp *interp) /* Tcl interpreter */ +{ + if (Tcl_EvalObjv(interp, 1, &dataPtr->literals[LIT_GETCURRENTLOCALE], 0) != TCL_OK) { + return NULL; + } + + Tcl_SetObjRef(dataPtr->CurrentLocale, Tcl_GetObjResult(interp)); + Tcl_UnsetObjRef(dataPtr->CurrentLocaleDict); + + return dataPtr->CurrentLocale; +} +/* + *---------------------------------------------------------------------- + */ static Tcl_Obj * NormLocaleObj( - ClockClientData *dataPtr, /* Client data containing literal pool */ + ClockClientData *dataPtr, /* Client data containing literal pool */ + Tcl_Interp *interp, /* Tcl interpreter */ Tcl_Obj *localeObj, Tcl_Obj **mcDictObj) { const char *loc; if ( localeObj == NULL || localeObj == dataPtr->CurrentLocale - || localeObj == dataPtr->literals[LIT_C] + || localeObj == dataPtr->literals[LIT_C] + || localeObj == dataPtr->literals[LIT_CURRENT] ) { + if (dataPtr->CurrentLocale == NULL) { + ClockGetCurrentLocale(dataPtr, interp); + } *mcDictObj = dataPtr->CurrentLocaleDict; return dataPtr->CurrentLocale; } @@ -404,19 +440,23 @@ NormLocaleObj( } loc = TclGetString(localeObj); - if (dataPtr->CurrentLocale != NULL && - (localeObj == dataPtr->CurrentLocale - || strcmp(loc, TclGetString(dataPtr->CurrentLocale)) == 0 + if ( dataPtr->CurrentLocale != NULL + && ( localeObj == dataPtr->CurrentLocale + || (localeObj->length == dataPtr->CurrentLocale->length + && strcmp(loc, TclGetString(dataPtr->CurrentLocale)) == 0 ) + ) ) { *mcDictObj = dataPtr->CurrentLocaleDict; localeObj = dataPtr->CurrentLocale; } else - if (dataPtr->LastUsedLocale != NULL && - (localeObj == dataPtr->LastUsedLocale - || strcmp(loc, TclGetString(dataPtr->LastUsedLocale)) == 0 + if ( dataPtr->LastUsedLocale != NULL + && ( localeObj == dataPtr->LastUsedLocale + || (localeObj->length == dataPtr->LastUsedLocale->length + && strcmp(loc, TclGetString(dataPtr->LastUsedLocale)) == 0 ) + ) ) { *mcDictObj = dataPtr->LastUsedLocaleDict; Tcl_SetObjRef(dataPtr->LastUnnormUsedLocale, localeObj); @@ -424,12 +464,28 @@ NormLocaleObj( } else if ( - strcmp(loc, Literals[LIT_C]) == 0 + (localeObj->length == 1 /* C */ + && strncasecmp(loc, Literals[LIT_C], localeObj->length) == 0) + || (localeObj->length == 7 /* current */ + && strncasecmp(loc, Literals[LIT_CURRENT], localeObj->length) == 0) ) { + if (dataPtr->CurrentLocale == NULL) { + ClockGetCurrentLocale(dataPtr, interp); + } *mcDictObj = dataPtr->CurrentLocaleDict; localeObj = dataPtr->CurrentLocale; } else + if ( + (localeObj->length == 6 /* system */ + && strncasecmp(loc, Literals[LIT_SYSTEM], localeObj->length) == 0) + ) { + Tcl_SetObjRef(dataPtr->LastUnnormUsedLocale, localeObj); + localeObj = ClockGetSystemLocale(dataPtr, interp); + Tcl_SetObjRef(dataPtr->LastUsedLocale, localeObj); + *mcDictObj = NULL; + } + else { *mcDictObj = NULL; } @@ -450,7 +506,7 @@ ClockMCDict(ClockFmtScnCmdArgs *opts) /* if locale was not yet used */ if ( !(opts->flags & CLF_LOCALE_USED) ) { - opts->localeObj = NormLocaleObj(opts->clientData, + opts->localeObj = NormLocaleObj(opts->clientData, opts->interp, opts->localeObj, &opts->mcDictObj); if (opts->localeObj == NULL) { @@ -490,6 +546,8 @@ ClockMCDict(ClockFmtScnCmdArgs *opts) } if ( opts->localeObj == dataPtr->CurrentLocale ) { Tcl_SetObjRef(dataPtr->CurrentLocaleDict, opts->mcDictObj); + } else if ( opts->localeObj == dataPtr->LastUsedLocale ) { + Tcl_SetObjRef(dataPtr->LastUsedLocaleDict, opts->mcDictObj); } else { Tcl_SetObjRef(dataPtr->LastUsedLocale, opts->localeObj); Tcl_UnsetObjRef(dataPtr->LastUnnormUsedLocale); @@ -2717,7 +2775,7 @@ _ClockParseFmtScnArgs( if ((saw & (1 << CLOCK_FORMAT_GMT)) && (saw & (1 << CLOCK_FORMAT_TIMEZONE))) { - Tcl_SetObjResult(interp, litPtr[LIT_CANNOT_USE_GMT_AND_TIMEZONE]); + Tcl_SetResult(interp, "cannot use -gmt and -timezone in same call", TCL_STATIC); Tcl_SetErrorCode(interp, "CLOCK", "gmtWithTimezone", NULL); return TCL_ERROR; } diff --git a/generic/tclClockFmt.c b/generic/tclClockFmt.c index f965a17..5d3dcaf 100644 --- a/generic/tclClockFmt.c +++ b/generic/tclClockFmt.c @@ -1199,7 +1199,9 @@ ClockLocalizeFormat( clean: Tcl_UnsetObjRef(keyObj); - Tcl_ResetResult(opts->interp); + if (valObj) { + Tcl_ResetResult(opts->interp); + } } return (opts->formatObj = valObj); diff --git a/generic/tclDate.h b/generic/tclDate.h index fc922cb..e78d4f8 100644 --- a/generic/tclDate.h +++ b/generic/tclDate.h @@ -58,9 +58,8 @@ typedef enum ClockLiteral { LIT__NIL, LIT__DEFAULT_FORMAT, - LIT_BCE, LIT_C, - LIT_CANNOT_USE_GMT_AND_TIMEZONE, - LIT_CE, + LIT_SYSTEM, LIT_CURRENT, + LIT_BCE, LIT_C, LIT_CE, LIT_DAYOFMONTH, LIT_DAYOFWEEK, LIT_DAYOFYEAR, LIT_ERA, LIT_GMT, LIT_GREGORIAN, LIT_INTEGER_VALUE_TOO_LARGE, @@ -72,7 +71,8 @@ typedef enum ClockLiteral { LIT_TZDATA, LIT_GETSYSTEMTIMEZONE, LIT_SETUPTIMEZONE, - LIT_MCGET, LIT_TCL_CLOCK, + LIT_MCGET, + LIT_GETSYSTEMLOCALE, LIT_GETCURRENTLOCALE, LIT_LOCALIZE_FORMAT, LIT__END } ClockLiteral; @@ -80,9 +80,8 @@ typedef enum ClockLiteral { #define CLOCK_LITERAL_ARRAY(litarr) static const char *const litarr[] = { \ "", \ "%a %b %d %H:%M:%S %Z %Y", \ - "BCE", "C", \ - "cannot use -gmt and -timezone in same call", \ - "CE", \ + "system", "current", \ + "BCE", "C", "CE", \ "dayOfMonth", "dayOfWeek", "dayOfYear", \ "era", ":GMT", "gregorian", \ "integer value too large to represent", \ @@ -94,7 +93,8 @@ typedef enum ClockLiteral { "::tcl::clock::TZData", \ "::tcl::clock::GetSystemTimeZone", \ "::tcl::clock::SetupTimeZone", \ - "::tcl::clock::mcget", "::tcl::clock", \ + "::tcl::clock::mcget", \ + "::tcl::clock::GetSystemLocale", "::tcl::clock::mclocale", \ "::tcl::clock::LocalizeFormat" \ } diff --git a/library/clock.tcl b/library/clock.tcl index d4e29d5..f874e4d 100755 --- a/library/clock.tcl +++ b/library/clock.tcl @@ -2352,7 +2352,7 @@ proc ::tcl::clock::LocalizeFormat { locale format {fmtkey {}} } { }] } { # message catalog dictionary: - set mcd [::msgcat::mcget ::tcl::clock $locale] + set mcd [mcget $locale] # Handle locale-dependent format groups by mapping them out of the format # string. Note that the order of the [string map] operations is @@ -3021,21 +3021,23 @@ proc ::tcl::clock::SetupTimeZone { timezone {alias {}} } { variable LegacyTimeZone - # Check may be a legacy zone: - if { $alias eq {} && ![catch { - set tzname [dict get $LegacyTimeZone [string tolower $timezone]] - }] } { - set tzname [::tcl::clock::SetupTimeZone $tzname $timezone] - set TZData($timezone) $TZData($tzname) - # tell backend - timezone is initialized and return shared timezone object: - return [configure -setup-tz $timezone] - } - # We couldn't parse this as a POSIX time zone. Try again with a # time zone file - this time without a colon if { [catch { LoadTimeZoneFile $timezone }] && [catch { LoadZoneinfoFile $timezone } - opts] } { + + # Check may be a legacy zone: + + if { $alias eq {} && ![catch { + set tzname [dict get $LegacyTimeZone [string tolower $timezone]] + }] } { + set tzname [::tcl::clock::SetupTimeZone $tzname $timezone] + set TZData($timezone) $TZData($tzname) + # tell backend - timezone is initialized and return shared timezone object: + return [configure -setup-tz $timezone] + } + dict unset opts -errorinfo dict set TimeZoneBad $timezone 1 return -options $opts "time zone $timezone not found" -- cgit v0.12 From e9177a25c1cbdc5ee7108dbadc69acab26f9abf5 Mon Sep 17 00:00:00 2001 From: sebres Date: Tue, 10 Jan 2017 22:34:11 +0000 Subject: bug fix by match word token (FindWordEnd fixed); repaired current locale switch --- generic/tclClockFmt.c | 6 +++--- library/clock.tcl | 8 ++++++-- 2 files changed, 9 insertions(+), 5 deletions(-) diff --git a/generic/tclClockFmt.c b/generic/tclClockFmt.c index 5d3dcaf..a10d05d 100644 --- a/generic/tclClockFmt.c +++ b/generic/tclClockFmt.c @@ -609,12 +609,12 @@ FindWordEnd( return ++p; } /* multi-char word */ - while (*p++ == *x++) { - if (x >= tok->tokWord.end || p >= end) { + do + if (*p++ != *x++) { /* no match -> error */ return NULL; } - }; + while (x <= tok->tokWord.end && p < end); return p; } diff --git a/library/clock.tcl b/library/clock.tcl index f874e4d..ca12f4a 100755 --- a/library/clock.tcl +++ b/library/clock.tcl @@ -739,7 +739,7 @@ proc ::tcl::clock::ParseClockFormatFormat {procName format locale} { # Map away the locale-dependent composite format groups - EnterLocale $locale + set locale [EnterLocale $locale] # Change locale if a fresh locale has been given on the command line. @@ -2189,6 +2189,7 @@ proc ::tcl::clock::EnterLocale { locale } { } # Select the locale, eventually load it mcpackagelocale set $locale + return $locale } #---------------------------------------------------------------------- @@ -3028,7 +3029,7 @@ proc ::tcl::clock::SetupTimeZone { timezone {alias {}} } { && [catch { LoadZoneinfoFile $timezone } - opts] } { # Check may be a legacy zone: - + if { $alias eq {} && ![catch { set tzname [dict get $LegacyTimeZone [string tolower $timezone]] }] } { @@ -4460,6 +4461,9 @@ proc ::tcl::clock::AddDays { days clockval timezone changeover } { #---------------------------------------------------------------------- proc ::tcl::clock::ChangeCurrentLocale {args} { + + configure -default-locale [lindex $args 0] + variable FormatProc variable LocaleNumeralCache -- cgit v0.12 From 36d60df82c46ec5b74df8d791793fc94347e7938 Mon Sep 17 00:00:00 2001 From: sebres Date: Tue, 10 Jan 2017 22:34:42 +0000 Subject: clock scan almost ready (currently test-case covered tokens only), test cases passed; todo - check other tokens from "clock.tcl" --- generic/tclClockFmt.c | 54 ++++++++++++++++++++++++++++++++++++++++++++++----- generic/tclDate.h | 16 ++++++++++----- 2 files changed, 60 insertions(+), 10 deletions(-) diff --git a/generic/tclClockFmt.c b/generic/tclClockFmt.c index a10d05d..c8158cc 100644 --- a/generic/tclClockFmt.c +++ b/generic/tclClockFmt.c @@ -748,7 +748,7 @@ ClockScnToken_amPmInd_Proc(ClockFmtScnCmdArgs *opts, amPmObj[0] = ClockMCGet(opts, MCLIT_AM); amPmObj[1] = ClockMCGet(opts, MCLIT_PM); - if (amPmObj[0] == NULL || amPmObj == NULL) { + if (amPmObj[0] == NULL || amPmObj[1] == NULL) { return TCL_ERROR; } @@ -768,6 +768,44 @@ ClockScnToken_amPmInd_Proc(ClockFmtScnCmdArgs *opts, } static int +ClockScnToken_LocaleERA_Proc(ClockFmtScnCmdArgs *opts, + DateInfo *info, ClockScanToken *tok) +{ + ClockClientData *dataPtr = opts->clientData; + + int ret, val; + int minLen, maxLen; + Tcl_Obj *eraObj[6]; + + DetermineGreedySearchLen(opts, info, tok, &minLen, &maxLen); + + eraObj[0] = ClockMCGet(opts, MCLIT_BCE); + eraObj[1] = ClockMCGet(opts, MCLIT_CE); + eraObj[2] = dataPtr->mcLiterals[MCLIT_BCE2]; + eraObj[3] = dataPtr->mcLiterals[MCLIT_CE2]; + eraObj[4] = dataPtr->mcLiterals[MCLIT_BCE3]; + eraObj[5] = dataPtr->mcLiterals[MCLIT_CE3]; + + if (eraObj[0] == NULL || eraObj[1] == NULL) { + return TCL_ERROR; + } + + ret = ObjListSearch(opts, info, &val, eraObj, 6, + minLen, maxLen); + if (ret != TCL_OK) { + return ret; + } + + if (val & 1) { + yydate.era = CE; + } else { + yydate.era = BCE; + } + + return TCL_OK; +} + +static int ClockScnToken_LocaleListMatcher_Proc(ClockFmtScnCmdArgs *opts, DateInfo *info, ClockScanToken *tok) { @@ -782,7 +820,9 @@ ClockScnToken_LocaleListMatcher_Proc(ClockFmtScnCmdArgs *opts, return ret; } - *(time_t *)(((char *)info) + tok->map->offs) = val; + if (tok->map->offs > 0) { + *(time_t *)(((char *)info) + tok->map->offs) = val; + } return TCL_OK; } @@ -931,9 +971,14 @@ static const char *ScnSTokenWrapMapIndex[2] = { }; static const char *ScnETokenMapIndex = - ""; + "Ey"; static ClockScanTokenMap ScnETokenMap[] = { - {0, 0, 0} + /* %EE */ + {CTOKT_PARSER, 0, 0, 0, 0, TclOffset(DateInfo, date.year), + ClockScnToken_LocaleERA_Proc, (void *)MCLIT_LOCALE_NUMERALS}, + /* %Ey */ + {CTOKT_PARSER, 0, 0, 0, 0, 0, /* currently no capture, parse only token */ + ClockScnToken_LocaleListMatcher_Proc, (void *)MCLIT_LOCALE_NUMERALS}, }; static const char *ScnETokenWrapMapIndex[2] = { "", @@ -1450,7 +1495,6 @@ ClockScan( } } } - yydate.era = CE; } } diff --git a/generic/tclDate.h b/generic/tclDate.h index e78d4f8..020fa64 100644 --- a/generic/tclDate.h +++ b/generic/tclDate.h @@ -58,8 +58,8 @@ typedef enum ClockLiteral { LIT__NIL, LIT__DEFAULT_FORMAT, - LIT_SYSTEM, LIT_CURRENT, - LIT_BCE, LIT_C, LIT_CE, + LIT_SYSTEM, LIT_CURRENT, LIT_C, + LIT_BCE, LIT_CE, LIT_DAYOFMONTH, LIT_DAYOFWEEK, LIT_DAYOFYEAR, LIT_ERA, LIT_GMT, LIT_GREGORIAN, LIT_INTEGER_VALUE_TOO_LARGE, @@ -80,8 +80,8 @@ typedef enum ClockLiteral { #define CLOCK_LITERAL_ARRAY(litarr) static const char *const litarr[] = { \ "", \ "%a %b %d %H:%M:%S %Z %Y", \ - "system", "current", \ - "BCE", "C", "CE", \ + "system", "current", "C", \ + "BCE", "CE", \ "dayOfMonth", "dayOfWeek", "dayOfYear", \ "era", ":GMT", "gregorian", \ "integer value too large to represent", \ @@ -107,6 +107,9 @@ typedef enum ClockMsgCtLiteral { MCLIT_MONTHS_FULL, MCLIT_MONTHS_ABBREV, MCLIT_DAYS_OF_WEEK_FULL, MCLIT_DAYS_OF_WEEK_ABBREV, MCLIT_AM, MCLIT_PM, + MCLIT_BCE, MCLIT_CE, + MCLIT_BCE2, MCLIT_CE2, + MCLIT_BCE3, MCLIT_CE3, MCLIT_LOCALE_NUMERALS, MCLIT__END } ClockMsgCtLiteral; @@ -115,7 +118,10 @@ typedef enum ClockMsgCtLiteral { pref "", \ pref "MONTHS_FULL", pref "MONTHS_ABBREV", \ pref "DAYS_OF_WEEK_FULL", pref "DAYS_OF_WEEK_ABBREV", \ - pref "AM", pref "PM", \ + pref "AM", pref "PM", \ + pref "BCE", pref "CE", \ + pref "b.c.e.", pref "c.e.", \ + pref "b.c.", pref "a.d.", \ pref "LOCALE_NUMERALS", \ } -- cgit v0.12 From e130d09c74bdbd2531f7c8bf75f5ede84eb0bdab Mon Sep 17 00:00:00 2001 From: sebres Date: Tue, 10 Jan 2017 22:35:14 +0000 Subject: small optimization (determine min/max length, end distance, etc.) --- generic/tclClockFmt.c | 34 ++++++++++++++++++++++++++++++---- generic/tclDate.h | 3 ++- 2 files changed, 32 insertions(+), 5 deletions(-) diff --git a/generic/tclClockFmt.c b/generic/tclClockFmt.c index c8158cc..2873ff7 100644 --- a/generic/tclClockFmt.c +++ b/generic/tclClockFmt.c @@ -498,13 +498,24 @@ void DetermineGreedySearchLen(ClockFmtScnCmdArgs *opts, { register const char*p = yyInput; *minLen = 0; - *maxLen = info->dateEnd - p; + /* max length to the end regarding distance to end (min-width of following tokens) */ + *maxLen = info->dateEnd - p - tok->endDistance; /* if no tokens anymore */ if (!(tok+1)->map) { /* should match to end or first space */ while (!isspace(UCHAR(*p)) && ++p < info->dateEnd) {}; *minLen = p - yyInput; + } else + /* next token is a word */ + if ((tok+1)->map->type == CTOKT_WORD) { + /* should match at least to the first char of this word */ + while (*p != *((tok+1)->tokWord.start) && ++p < info->dateEnd) {}; + *minLen = p - yyInput; + } + + if (*minLen > *maxLen) { + *maxLen = *minLen; } } @@ -1018,7 +1029,7 @@ static const char *ScnOTokenWrapMapIndex[2] = { static const char *ScnSpecTokenMapIndex = " "; static ClockScanTokenMap ScnSpecTokenMap[] = { - {CTOKT_SPACE, 0, 0, 1, 0xffff, 0, + {CTOKT_SPACE, 0, 0, 0, 0xffff, 0, NULL}, }; @@ -1131,9 +1142,9 @@ ClockGetOrParseScanFormat( tok->map = &scnMap[cp - mapIndex]; tok->tokWord.start = p; /* calculate look ahead value by standing together tokens */ - if (tok > fss->scnTok) { - ClockScanToken *prevTok = tok - 1; + if (tok > fss->scnTok && tok->map->minSize) { unsigned int lookAhead = tok->map->minSize; + ClockScanToken *prevTok = tok - 1; while (prevTok >= fss->scnTok) { if (prevTok->map->type != tok->map->type) { @@ -1177,6 +1188,21 @@ word_tok: continue; } + /* calculate end distance value for each tokens */ + if (tok > fss->scnTok) { + unsigned int endDist = 0; + ClockScanToken *prevTok = tok-1; + + while (prevTok >= fss->scnTok) { + prevTok->endDistance = endDist; + if (prevTok->map->type != CTOKT_WORD) { + endDist += prevTok->map->minSize; + } else { + endDist += prevTok->tokWord.end - prevTok->tokWord.start + 1; + } + prevTok--; + } + } done: Tcl_MutexUnlock(&ClockFmtMutex); } diff --git a/generic/tclDate.h b/generic/tclDate.h index 020fa64..00bd234 100644 --- a/generic/tclDate.h +++ b/generic/tclDate.h @@ -389,7 +389,8 @@ typedef struct ClockScanTokenMap { typedef struct ClockScanToken { ClockScanTokenMap *map; - unsigned int lookAhead; + unsigned short int lookAhead; + unsigned short int endDistance; struct { const char *start; const char *end; -- cgit v0.12 From 717e43f1bd2a2b769c8e2a60db22a98c8690db1a Mon Sep 17 00:00:00 2001 From: sebres Date: Tue, 10 Jan 2017 22:35:34 +0000 Subject: estimate token count by % char and format length (don't use fix TOK_CHAIN_BLOCK_SIZE by creation, minimized memory usage) --- generic/tclClockFmt.c | 26 +++++++++++++++++++++----- generic/tclDate.h | 2 +- 2 files changed, 22 insertions(+), 6 deletions(-) diff --git a/generic/tclClockFmt.c b/generic/tclClockFmt.c index 2873ff7..ac34e68 100644 --- a/generic/tclClockFmt.c +++ b/generic/tclClockFmt.c @@ -1080,14 +1080,30 @@ ClockGetOrParseScanFormat( const char *strFmt; register const char *p, *e, *cp; + e = strFmt = HashEntry4FmtScn(fss)->key.string; + e += strlen(strFmt); + + /* estimate token count by % char and format length */ + fss->scnTokC = 0; + p = strFmt; + while (p != e) { + if (*p++ == '%') fss->scnTokC++; + } + p = strFmt + fss->scnTokC * 2; + if (p < e) { + if ((e - p) < fss->scnTokC) { + fss->scnTokC += (e - p); + } else { + fss->scnTokC += fss->scnTokC; + } + } + fss->scnTokC++; + Tcl_MutexLock(&ClockFmtMutex); - fss->scnTokC = CLOCK_MIN_TOK_CHAIN_BLOCK_SIZE; - fss->scnTok = - tok = ckalloc(sizeof(*tok) * CLOCK_MIN_TOK_CHAIN_BLOCK_SIZE); + fss->scnTok = tok = ckalloc(sizeof(*tok) * fss->scnTokC); memset(tok, 0, sizeof(*(tok))); - strFmt = HashEntry4FmtScn(fss)->key.string; - for (e = p = strFmt, e += strlen(strFmt); p != e; p++) { + for (p = strFmt; p != e; p++) { switch (*p) { case '%': if (1) { diff --git a/generic/tclDate.h b/generic/tclDate.h index 00bd234..9e1c506 100644 --- a/generic/tclDate.h +++ b/generic/tclDate.h @@ -355,7 +355,7 @@ typedef enum _MERIDIAN { #define CLOCK_FMT_SCN_STORAGE_GC_SIZE 32 -#define CLOCK_MIN_TOK_CHAIN_BLOCK_SIZE 12 +#define CLOCK_MIN_TOK_CHAIN_BLOCK_SIZE 2 typedef struct ClockScanToken ClockScanToken; -- cgit v0.12 From c5ff074db9dcb68224ba79b0e8a72edcbf63610a Mon Sep 17 00:00:00 2001 From: sebres Date: Tue, 10 Jan 2017 22:36:19 +0000 Subject: cacheable conversions Local2UTC / UTC2Local fixed (some TZ switches time seconds bound) and optimized (last period ranges saved); prepare to back-port clock format --- generic/tclClock.c | 265 +++++++++++++++++++++++++++++++++------------- generic/tclClockFmt.c | 287 +++++++++++++++++++++++++++++++++++++++++++++++++- generic/tclDate.h | 28 ++++- library/clock.tcl | 14 --- 4 files changed, 502 insertions(+), 92 deletions(-) diff --git a/generic/tclClock.c b/generic/tclClock.c index a84300a..0c08391 100644 --- a/generic/tclClock.c +++ b/generic/tclClock.c @@ -72,19 +72,21 @@ TCL_DECLARE_MUTEX(clockMutex) static int ConvertUTCToLocal(ClientData clientData, Tcl_Interp *, TclDateFields *, Tcl_Obj *timezoneObj, int); static int ConvertUTCToLocalUsingTable(Tcl_Interp *, - TclDateFields *, int, Tcl_Obj *const[]); + TclDateFields *, int, Tcl_Obj *const[], + Tcl_WideInt rangesVal[2]); static int ConvertUTCToLocalUsingC(Tcl_Interp *, TclDateFields *, int); static int ConvertLocalToUTC(ClientData clientData, Tcl_Interp *, TclDateFields *, Tcl_Obj *timezoneObj, int); static int ConvertLocalToUTCUsingTable(Tcl_Interp *, - TclDateFields *, int, Tcl_Obj *const[]); + TclDateFields *, int, Tcl_Obj *const[], + Tcl_WideInt rangesVal[2]); static int ConvertLocalToUTCUsingC(Tcl_Interp *, TclDateFields *, int); static int ClockConfigureObjCmd(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *const objv[]); static Tcl_Obj * LookupLastTransition(Tcl_Interp *, Tcl_WideInt, - int, Tcl_Obj *const *); + int, Tcl_Obj *const *, Tcl_WideInt rangesVal[2]); static void GetYearWeekDay(TclDateFields *, int); static void GetGregorianEraYearDay(TclDateFields *, int); static void GetMonthDay(TclDateFields *); @@ -1432,6 +1434,7 @@ ConvertLocalToUTC( Tcl_Obj *tzdata; /* Time zone data */ int rowc; /* Number of rows in tzdata */ Tcl_Obj **rowv; /* Pointers to the rows */ + Tcl_WideInt seconds; /* fast phase-out for shared GMT-object (don't need to convert UTC 2 UTC) */ if (timezoneObj == dataPtr->GMTSetupTimeZone && dataPtr->GMTSetupTimeZone != NULL) { @@ -1442,17 +1445,37 @@ ConvertLocalToUTC( /* * Check cacheable conversion could be used - * (last-minute Local2UTC cache with the same TZ) + * (last-period Local2UTC cache within the same TZ) */ + seconds = fields->localSeconds - dataPtr->Local2UTC.tzOffset; if ( timezoneObj == dataPtr->Local2UTC.timezoneObj && ( fields->localSeconds == dataPtr->Local2UTC.localSeconds - || fields->localSeconds / 60 == dataPtr->Local2UTC.localSeconds / 60 + || ( seconds >= dataPtr->Local2UTC.rangesVal[0] + && seconds < dataPtr->Local2UTC.rangesVal[1]) ) && changeover == dataPtr->Local2UTC.changeover ) { /* the same time zone and offset (UTC time inside the last minute) */ fields->tzOffset = dataPtr->Local2UTC.tzOffset; - fields->seconds = fields->localSeconds - fields->tzOffset; + fields->seconds = seconds; + return TCL_OK; + } + + /* + * Check cacheable back-conversion could be used + * (last-period UTC2Local cache within the same TZ) + */ + seconds = fields->localSeconds - dataPtr->UTC2Local.tzOffset; + if ( timezoneObj == dataPtr->UTC2Local.timezoneObj + && ( seconds == dataPtr->UTC2Local.seconds + || ( seconds >= dataPtr->UTC2Local.rangesVal[0] + && seconds < dataPtr->UTC2Local.rangesVal[1]) + ) + && changeover == dataPtr->UTC2Local.changeover + ) { + /* the same time zone and offset (UTC time inside the last minute) */ + fields->tzOffset = dataPtr->UTC2Local.tzOffset; + fields->seconds = seconds; return TCL_OK; } @@ -1475,11 +1498,15 @@ ConvertLocalToUTC( */ if (rowc == 0) { + dataPtr->Local2UTC.rangesVal[0] = 0; + dataPtr->Local2UTC.rangesVal[1] = 0; + if (ConvertLocalToUTCUsingC(interp, fields, changeover) != TCL_OK) { return TCL_ERROR; }; } else { - if (ConvertLocalToUTCUsingTable(interp, fields, rowc, rowv) != TCL_OK) { + if (ConvertLocalToUTCUsingTable(interp, fields, rowc, rowv, + dataPtr->Local2UTC.rangesVal) != TCL_OK) { return TCL_ERROR; }; } @@ -1516,7 +1543,8 @@ ConvertLocalToUTCUsingTable( Tcl_Interp *interp, /* Tcl interpreter */ TclDateFields *fields, /* Time to convert, with 'seconds' filled in */ int rowc, /* Number of points at which time changes */ - Tcl_Obj *const rowv[]) /* Points at which time changes */ + Tcl_Obj *const rowv[], /* Points at which time changes */ + Tcl_WideInt rangesVal[2]) /* Return bounds for time period */ { Tcl_Obj *row; int cellc; @@ -1540,7 +1568,8 @@ ConvertLocalToUTCUsingTable( fields->tzOffset = 0; fields->seconds = fields->localSeconds; while (!found) { - row = LookupLastTransition(interp, fields->seconds, rowc, rowv); + row = LookupLastTransition(interp, fields->seconds, rowc, rowv, + rangesVal); if ((row == NULL) || TclListObjGetElements(interp, row, &cellc, &cellv) != TCL_OK @@ -1730,11 +1759,12 @@ ConvertUTCToLocal( /* * Check cacheable conversion could be used - * (last-minute UTC2Local cache with the same TZ) + * (last-period UTC2Local cache within the same TZ) */ if ( timezoneObj == dataPtr->UTC2Local.timezoneObj && ( fields->seconds == dataPtr->UTC2Local.seconds - || fields->seconds / 60 == dataPtr->UTC2Local.seconds / 60 + || ( fields->seconds >= dataPtr->UTC2Local.rangesVal[0] + && fields->seconds < dataPtr->UTC2Local.rangesVal[1]) ) && changeover == dataPtr->UTC2Local.changeover ) { @@ -1764,11 +1794,15 @@ ConvertUTCToLocal( */ if (rowc == 0) { + dataPtr->UTC2Local.rangesVal[0] = 0; + dataPtr->UTC2Local.rangesVal[1] = 0; + if (ConvertUTCToLocalUsingC(interp, fields, changeover) != TCL_OK) { return TCL_ERROR; } } else { - if (ConvertUTCToLocalUsingTable(interp, fields, rowc, rowv) != TCL_OK) { + if (ConvertUTCToLocalUsingTable(interp, fields, rowc, rowv, + dataPtr->UTC2Local.rangesVal) != TCL_OK) { return TCL_ERROR; } } @@ -1806,7 +1840,8 @@ ConvertUTCToLocalUsingTable( TclDateFields *fields, /* Fields of the date */ int rowc, /* Number of rows in the conversion table * (>= 1) */ - Tcl_Obj *const rowv[]) /* Rows of the conversion table */ + Tcl_Obj *const rowv[], /* Rows of the conversion table */ + Tcl_WideInt rangesVal[2]) /* Return bounds for time period */ { Tcl_Obj *row; /* Row containing the current information */ int cellc; /* Count of cells in the row (must be 4) */ @@ -1816,7 +1851,7 @@ ConvertUTCToLocalUsingTable( * Look up the nearest transition time. */ - row = LookupLastTransition(interp, fields->seconds, rowc, rowv); + row = LookupLastTransition(interp, fields->seconds, rowc, rowv, rangesVal); if (row == NULL || TclListObjGetElements(interp, row, &cellc, &cellv) != TCL_OK || TclGetIntFromObj(interp, cellv[1], &fields->tzOffset) != TCL_OK) { @@ -1943,12 +1978,13 @@ LookupLastTransition( Tcl_Interp *interp, /* Interpreter for error messages */ Tcl_WideInt tick, /* Time from the epoch */ int rowc, /* Number of rows of tzdata */ - Tcl_Obj *const *rowv) /* Rows in tzdata */ + Tcl_Obj *const *rowv, /* Rows in tzdata */ + Tcl_WideInt rangesVal[2]) /* Return bounds for time period */ { - int l; + int l = 0; int u; Tcl_Obj *compObj; - Tcl_WideInt compVal; + Tcl_WideInt compVal, fromVal = tick, toVal = tick; /* * Examine the first row to make sure we're in bounds. @@ -1965,14 +2001,13 @@ LookupLastTransition( */ if (tick < compVal) { - return rowv[0]; + goto done; } /* * Binary-search to find the transition. */ - l = 0; u = rowc-1; while (l < u) { int m = (l + u + 1) / 2; @@ -1983,10 +2018,19 @@ LookupLastTransition( } if (tick >= compVal) { l = m; + fromVal = compVal; } else { u = m-1; + toVal = compVal; } } + +done: + + if (rangesVal) { + rangesVal[0] = fromVal; + rangesVal[1] = toVal; + } return rowv[l]; } @@ -2713,7 +2757,7 @@ _ClockParseFmtScnArgs( Tcl_Interp *interp, /* Tcl interpreter */ int objc, /* Parameter count */ Tcl_Obj *const objv[], /* Parameter vector */ - ClockFmtScnCmdArgs *resOpts, /* Result vector: format, locale, timezone... */ + ClockFmtScnCmdArgs *opts, /* Result vector: format, locale, timezone... */ int forScan /* Flag to differentiate between format and scan */ ) { ClockClientData *dataPtr = clientData; @@ -2739,7 +2783,7 @@ _ClockParseFmtScnArgs( * Extract values for the keywords. */ - memset(resOpts, 0, sizeof(*resOpts)); + memset(opts, 0, sizeof(*opts)); for (i = 2; i < objc; i+=2) { if (Tcl_GetIndexFromObj(interp, objv[i], options[forScan], "option", 0, &optionIndex) != TCL_OK) { @@ -2749,7 +2793,7 @@ _ClockParseFmtScnArgs( } switch (optionIndex) { case CLOCK_FORMAT_FORMAT: - resOpts->formatObj = objv[i+1]; + opts->formatObj = objv[i+1]; break; case CLOCK_FORMAT_GMT: if (Tcl_GetBooleanFromObj(interp, objv[i+1], &gmtFlag) != TCL_OK){ @@ -2757,13 +2801,13 @@ _ClockParseFmtScnArgs( } break; case CLOCK_FORMAT_LOCALE: - resOpts->localeObj = objv[i+1]; + opts->localeObj = objv[i+1]; break; case CLOCK_FORMAT_TIMEZONE: - resOpts->timezoneObj = objv[i+1]; + opts->timezoneObj = objv[i+1]; break; case CLOCK_FORMAT_BASE: - resOpts->baseObj = objv[i+1]; + opts->baseObj = objv[i+1]; break; } saw |= 1 << optionIndex; @@ -2780,11 +2824,30 @@ _ClockParseFmtScnArgs( return TCL_ERROR; } if (gmtFlag) { - resOpts->timezoneObj = litPtr[LIT_GMT]; + opts->timezoneObj = litPtr[LIT_GMT]; + } + + opts->clientData = clientData; + opts->interp = interp; + + /* If time zone not specified use system time zone */ + + if ( opts->timezoneObj == NULL + || TclGetString(opts->timezoneObj) == NULL + || opts->timezoneObj->length == 0 + ) { + opts->timezoneObj = ClockGetSystemTimeZone(clientData, interp); + if (opts->timezoneObj == NULL) { + return TCL_ERROR; + } } - resOpts->clientData = clientData; - resOpts->interp = interp; + /* Setup timezone (normalize object if needed and load TZ on demand) */ + + opts->timezoneObj = ClockSetupTimeZone(clientData, interp, opts->timezoneObj); + if (opts->timezoneObj == NULL) { + return TCL_ERROR; + } return TCL_OK; } @@ -2816,7 +2879,7 @@ ClockParseformatargsObjCmd( { ClockClientData *dataPtr = clientData; Tcl_Obj **literals = dataPtr->literals; - ClockFmtScnCmdArgs resOpts; /* Format, locale and timezone */ + ClockFmtScnCmdArgs opts; /* Format, locale and timezone */ Tcl_WideInt clockVal; /* Clock value - just used to parse. */ int ret; @@ -2837,7 +2900,7 @@ ClockParseformatargsObjCmd( */ ret = _ClockParseFmtScnArgs(clientData, interp, objc, objv, - &resOpts, 0); + &opts, 0); if (ret != TCL_OK) { return ret; } @@ -2849,18 +2912,110 @@ ClockParseformatargsObjCmd( if (Tcl_GetWideIntFromObj(interp, objv[1], &clockVal) != TCL_OK) { return TCL_ERROR; } - if (resOpts.formatObj == NULL) - resOpts.formatObj = literals[LIT__DEFAULT_FORMAT]; - if (resOpts.localeObj == NULL) - resOpts.localeObj = literals[LIT_C]; - if (resOpts.timezoneObj == NULL) - resOpts.timezoneObj = literals[LIT__NIL]; + if (opts.formatObj == NULL) + opts.formatObj = literals[LIT__DEFAULT_FORMAT]; + if (opts.localeObj == NULL) + opts.localeObj = literals[LIT_C]; + if (opts.timezoneObj == NULL) + opts.timezoneObj = literals[LIT__NIL]; /* * Return options as a list. */ - Tcl_SetObjResult(interp, Tcl_NewListObj(3, (Tcl_Obj**)&resOpts.formatObj)); + Tcl_SetObjResult(interp, Tcl_NewListObj(3, (Tcl_Obj**)&opts.formatObj)); + return TCL_OK; +} + +/*---------------------------------------------------------------------- + * + * ClockFormatObjCmd - + * + *---------------------------------------------------------------------- + */ + +int +ClockFormatObjCmd( + ClientData clientData, /* Client data containing literal pool */ + Tcl_Interp *interp, /* Tcl interpreter */ + int objc, /* Parameter count */ + Tcl_Obj *const objv[]) /* Parameter values */ +{ + ClockClientData *dataPtr = clientData; + + int ret; + ClockFmtScnCmdArgs opts; /* Format, locale, timezone and base */ + Tcl_WideInt clockVal; /* Time, expressed in seconds from the Epoch */ + DateInfo yy; /* Common structure used for parsing */ + DateInfo *info = &yy; + + if ((objc & 1) == 1) { + Tcl_WrongNumArgs(interp, 1, objv, "string " + "?-format string? " + "?-gmt boolean? " + "?-locale LOCALE? ?-timezone ZONE?"); + Tcl_SetErrorCode(interp, "CLOCK", "wrongNumArgs", NULL); + return TCL_ERROR; + } + + /* + * Extract values for the keywords. + */ + + ret = _ClockParseFmtScnArgs(clientData, interp, objc, objv, + &opts, 0); + if (ret != TCL_OK) { + return ret; + } + + ret = TCL_ERROR; + + if (Tcl_GetWideIntFromObj(interp, objv[1], &clockVal) != TCL_OK) { + return TCL_ERROR; + } + + + ClockInitDateInfo(info); + yydate.tzName = NULL; + + /* + * Extract year, month and day from the base time for the parser to use as + * defaults + */ + + /* check base fields already cached (by TZ, last-second cache) */ + if ( dataPtr->lastBase.timezoneObj == opts.timezoneObj + && dataPtr->lastBase.Date.seconds == clockVal) { + memcpy(&yydate, &dataPtr->lastBase.Date, ClockCacheableDateFieldsSize); + } else { + /* extact fields from base */ + yydate.seconds = clockVal; + if (ClockGetDateFields(clientData, interp, &yydate, opts.timezoneObj, + GREGORIAN_CHANGE_DATE) != TCL_OK) { + goto done; + } + /* cache last base */ + memcpy(&dataPtr->lastBase.Date, &yydate, ClockCacheableDateFieldsSize); + Tcl_SetObjRef(dataPtr->lastBase.timezoneObj, opts.timezoneObj); + } + + /* Default format */ + if (opts.formatObj == NULL) { + opts.formatObj = dataPtr->literals[LIT__DEFAULT_FORMAT]; + } + + /* Use compiled version of Format - */ + + ret = ClockFormat(clientData, interp, info, &opts); + +done: + + Tcl_UnsetObjRef(yydate.tzName); + + if (ret != TCL_OK) { + return ret; + } + return TCL_OK; } @@ -2879,7 +3034,6 @@ ClockScanObjCmd( Tcl_Obj *const objv[]) /* Parameter values */ { ClockClientData *dataPtr = clientData; - Tcl_Obj **literals = dataPtr->literals; int ret; ClockFmtScnCmdArgs opts; /* Format, locale, timezone and base */ @@ -2919,29 +3073,9 @@ ClockScanObjCmd( baseVal = (Tcl_WideInt) now.sec; } - /* If time zone not specified use system time zone */ - if ( opts.timezoneObj == NULL - || TclGetString(opts.timezoneObj) == NULL - || opts.timezoneObj->length == 0 - ) { - opts.timezoneObj = ClockGetSystemTimeZone(clientData, interp); - if (opts.timezoneObj == NULL) { - return TCL_ERROR; - } - } - - /* Setup timezone (normalize object id needed and load TZ on demand) */ - - opts.timezoneObj = ClockSetupTimeZone(clientData, interp, opts.timezoneObj); - if (opts.timezoneObj == NULL) { - return TCL_ERROR; - } - ClockInitDateInfo(info); yydate.tzName = NULL; - // Tcl_SetObjRef(yydate.tzName, opts.timezoneObj); - /* * Extract year, month and day from the base time for the parser to use as * defaults @@ -2979,20 +3113,6 @@ ClockScanObjCmd( } ret = ClockFreeScan(clientData, interp, info, objv[1], &opts); } -#if 0 - else - if (1) { - /* TODO: Tcled Scan proc - */ - int ret; - Tcl_Obj *callargs[10]; - memcpy(callargs, objv, objc * sizeof(*objv)); - callargs[0] = Tcl_NewStringObj("::tcl::clock::__org_scan", -1); - Tcl_IncrRefCount(callargs[0]); - ret = Tcl_EvalObjv(interp, objc, callargs, 0); - Tcl_DecrRefCount(callargs[0]); - return ret; - } -#endif else { /* Use compiled version of Scan - */ @@ -3073,7 +3193,6 @@ ClockFreeScan( ClockFmtScnCmdArgs *opts) /* Command options */ { ClockClientData *dataPtr = clientData; - // Tcl_Obj **literals = dataPtr->literals; int ret = TCL_ERROR; diff --git a/generic/tclClockFmt.c b/generic/tclClockFmt.c index ac34e68..5469ee1 100644 --- a/generic/tclClockFmt.c +++ b/generic/tclClockFmt.c @@ -1091,7 +1091,7 @@ ClockGetOrParseScanFormat( } p = strFmt + fss->scnTokC * 2; if (p < e) { - if ((e - p) < fss->scnTokC) { + if ((unsigned int)(e - p) < fss->scnTokC) { fss->scnTokC += (e - p); } else { fss->scnTokC += fss->scnTokC; @@ -1581,6 +1581,291 @@ done: return ret; } +/* + *---------------------------------------------------------------------- + */ +int +ClockFormat( + ClientData clientData, /* Client data containing literal pool */ + Tcl_Interp *interp, /* Tcl interpreter */ + register DateInfo *info, /* Date fields used for parsing & converting */ + ClockFmtScnCmdArgs *opts) /* Command options */ +{ + ClockClientData *dataPtr = clientData; + ClockFormatToken *tok; + ClockFormatTokenMap *map; + + /* get localized format */ + if (ClockLocalizeFormat(opts) == NULL) { + return TCL_ERROR; + } + +/* if ((tok = ClockGetOrParseFmtFormat(interp, opts->formatObj)) == NULL) { + return TCL_ERROR; + } +*/ +#if 0 + /* prepare parsing */ + + yyMeridian = MER24; + + p = TclGetString(strObj); + end = p + strObj->length; + /* in strict mode - bypass spaces at begin / end only (not between tokens) */ + if (opts->flags & CLF_STRICT) { + while (p < end && isspace(UCHAR(*p))) { + p++; + } + } + info->dateStart = yyInput = p; + info->dateEnd = end; + + /* parse string */ + for (; tok->map != NULL; tok++) { + map = tok->map; + /* bypass spaces at begin of input before parsing each token */ + if ( !(opts->flags & CLF_STRICT) + && (map->type != CTOKT_SPACE && map->type != CTOKT_WORD) + ) { + while (p < end && isspace(UCHAR(*p))) { + p++; + } + } + yyInput = p; + switch (map->type) + { + case CTOKT_DIGIT: + if (1) { + int size = map->maxSize; + int sign = 1; + if (map->flags & CLF_SIGNED) { + if (*p == '+') { yyInput = ++p; } + else + if (*p == '-') { yyInput = ++p; sign = -1; }; + } + /* greedy find digits (look for forward digits consider spaces), + * corresponding pre-calculated lookAhead */ + if (size != map->minSize && tok->lookAhead) { + int spcnt = 0; + const char *pe; + size += tok->lookAhead; + x = p + size; if (x > end) { x = end; }; + pe = x; + while (p < x) { + if (isspace(UCHAR(*p))) { + if (pe > p) { pe = p; }; + if (x < end) x++; + p++; + spcnt++; + continue; + } + if (isdigit(UCHAR(*p))) { + p++; + continue; + } + break; + } + /* consider reserved (lookAhead) for next tokens */ + p -= tok->lookAhead + spcnt; + if (p > pe) { + p = pe; + } + } else { + x = p + size; if (x > end) { x = end; }; + while (isdigit(UCHAR(*p)) && p < x) { p++; }; + } + size = p - yyInput; + if (size < map->minSize) { + /* missing input -> error */ + goto not_match; + } + /* string 2 number, put number into info structure by offset */ + p = yyInput; x = p + size; + if (!(map->flags & CLF_LOCALSEC)) { + if (_str2int((time_t *)(((char *)info) + map->offs), + p, x, sign) != TCL_OK) { + goto overflow; + } + p = x; + } else { + if (_str2wideInt((Tcl_WideInt *)(((char *)info) + map->offs), + p, x, sign) != TCL_OK) { + goto overflow; + } + p = x; + } + flags = (flags & ~map->clearFlags) | map->flags; + } + break; + case CTOKT_PARSER: + switch (map->parser(opts, info, tok)) { + case TCL_OK: + break; + case TCL_RETURN: + goto not_match; + break; + default: + goto done; + break; + }; + p = yyInput; + flags = (flags & ~map->clearFlags) | map->flags; + break; + case CTOKT_SPACE: + /* at least one space in strict mode */ + if (opts->flags & CLF_STRICT) { + if (!isspace(UCHAR(*p))) { + /* unmatched -> error */ + goto not_match; + } + p++; + } + while (p < end && isspace(UCHAR(*p))) { + p++; + } + break; + case CTOKT_WORD: + x = FindWordEnd(tok, p, end); + if (!x) { + /* no match -> error */ + goto not_match; + } + p = x; + continue; + break; + } + } + + /* ignore spaces at end */ + while (p < end && isspace(UCHAR(*p))) { + p++; + } + /* check end was reached */ + if (p < end) { + /* something after last token - wrong format */ + goto not_match; + } + + /* + * Invalidate result + */ + + /* seconds token (%s) take precedence over all other tokens */ + if ((opts->flags & CLF_EXTENDED) || !(flags & CLF_LOCALSEC)) { + if (flags & CLF_DATE) { + + if (!(flags & CLF_JULIANDAY)) { + info->flags |= CLF_ASSEMBLE_SECONDS|CLF_ASSEMBLE_JULIANDAY; + + /* dd precedence below ddd */ + switch (flags & (CLF_MONTH|CLF_DAYOFYEAR|CLF_DAYOFMONTH)) { + case (CLF_DAYOFYEAR|CLF_DAYOFMONTH): + /* miss month: ddd over dd (without month) */ + flags &= ~CLF_DAYOFMONTH; + case (CLF_DAYOFYEAR): + /* ddd over naked weekday */ + if (!(flags & CLF_ISO8601YEAR)) { + flags &= ~CLF_ISO8601; + } + break; + case (CLF_MONTH|CLF_DAYOFYEAR|CLF_DAYOFMONTH): + /* both available: mmdd over ddd */ + flags &= ~CLF_DAYOFYEAR; + case (CLF_MONTH|CLF_DAYOFMONTH): + case (CLF_DAYOFMONTH): + /* mmdd / dd over naked weekday */ + if (!(flags & CLF_ISO8601YEAR)) { + flags &= ~CLF_ISO8601; + } + break; + } + + /* YearWeekDay below YearMonthDay */ + if ( (flags & CLF_ISO8601) + && ( (flags & (CLF_YEAR|CLF_DAYOFYEAR)) == (CLF_YEAR|CLF_DAYOFYEAR) + || (flags & (CLF_YEAR|CLF_DAYOFMONTH|CLF_MONTH)) == (CLF_YEAR|CLF_DAYOFMONTH|CLF_MONTH) + ) + ) { + /* yy precedence below yyyy */ + if (!(flags & CLF_ISO8601CENTURY) && (flags & CLF_CENTURY)) { + /* normally precedence of ISO is higher, but no century - so put it down */ + flags &= ~CLF_ISO8601; + } + else + /* yymmdd or yyddd over naked weekday */ + if (!(flags & CLF_ISO8601YEAR)) { + flags &= ~CLF_ISO8601; + } + } + + if (!(flags & CLF_ISO8601)) { + if (yyYear < 100) { + if (!(flags & CLF_CENTURY)) { + if (yyYear >= dataPtr->yearOfCenturySwitch) { + yyYear -= 100; + } + yyYear += dataPtr->currentYearCentury; + } else { + yyYear += info->dateCentury * 100; + } + } + } else { + if (info->date.iso8601Year < 100) { + if (!(flags & CLF_ISO8601CENTURY)) { + if (info->date.iso8601Year >= dataPtr->yearOfCenturySwitch) { + info->date.iso8601Year -= 100; + } + info->date.iso8601Year += dataPtr->currentYearCentury; + } else { + info->date.iso8601Year += info->dateCentury * 100; + } + } + } + } + } + + /* if no time - reset time */ + if (!(flags & (CLF_TIME|CLF_LOCALSEC))) { + info->flags |= CLF_ASSEMBLE_SECONDS; + yydate.localSeconds = 0; + } + + if (flags & CLF_TIME) { + info->flags |= CLF_ASSEMBLE_SECONDS; + yySeconds = ToSeconds(yyHour, yyMinutes, + yySeconds, yyMeridian); + } else + if (!(flags & CLF_LOCALSEC)) { + info->flags |= CLF_ASSEMBLE_SECONDS; + yySeconds = yydate.localSeconds % SECONDS_PER_DAY; + } + } + + /* tell caller which flags were set */ + info->flags |= flags; + + ret = TCL_OK; + goto done; + +overflow: + + Tcl_SetResult(interp, "requested date too large to represent", + TCL_STATIC); + Tcl_SetErrorCode(interp, "CLOCK", "dateTooLarge", NULL); + goto done; + +not_match: + + Tcl_SetResult(interp, "input string does not match supplied format", + TCL_STATIC); + Tcl_SetErrorCode(interp, "CLOCK", "badInputString", NULL); + +done: + + return ret; +#endif +} + MODULE_SCOPE void ClockFrmScnClearCaches(void) diff --git a/generic/tclDate.h b/generic/tclDate.h index 9e1c506..112ed31 100644 --- a/generic/tclDate.h +++ b/generic/tclDate.h @@ -2,7 +2,7 @@ * tclDate.h -- * * This header file handles common usage of clock primitives - * between tclDate.c (yacc) and tclClock.c. + * between tclDate.c (yacc), tclClock.c and tclClockFmt.c. * * Copyright (c) 2014 Serg G. Brester (aka sebres) * @@ -317,22 +317,24 @@ typedef struct ClockClientData { Tcl_Obj *timezoneObj; TclDateFields Date; } lastBase; - /* Las-minute cache for fast UTC2Local conversion */ + /* Las-period cache for fast UTC2Local conversion */ struct { /* keys */ Tcl_Obj *timezoneObj; int changeover; Tcl_WideInt seconds; + Tcl_WideInt rangesVal[2]; /* Bounds for cached time zone offset */ /* values */ time_t tzOffset; Tcl_Obj *tzName; } UTC2Local; - /* Las-minute cache for fast Local2UTC conversion */ + /* Las-period cache for fast Local2UTC conversion */ struct { /* keys */ Tcl_Obj *timezoneObj; int changeover; Tcl_WideInt localSeconds; + Tcl_WideInt rangesVal[2]; /* Bounds for cached time zone offset */ /* values */ time_t tzOffset; } Local2UTC; @@ -372,8 +374,22 @@ typedef enum _CLCKTOK_TYPE { typedef struct ClockFmtScnStorage ClockFmtScnStorage; +typedef struct ClockFormatTokenMap { + unsigned short int type; + unsigned short int flags; + unsigned short int clearFlags; + unsigned short int minSize; + unsigned short int maxSize; + unsigned short int offs; + ClockScanTokenProc *parser; + void *data; +} ClockFormatTokenMap; typedef struct ClockFormatToken { - CLCKTOK_TYPE type; + ClockFormatTokenMap *map; + struct { + const char *start; + const char *end; + } tokWord; } ClockFormatToken; typedef struct ClockScanTokenMap { @@ -447,10 +463,14 @@ MODULE_SCOPE ClockFmtScnStorage * Tcl_Obj *objPtr); MODULE_SCOPE Tcl_Obj * ClockLocalizeFormat(ClockFmtScnCmdArgs *opts); + MODULE_SCOPE int ClockScan(ClientData clientData, Tcl_Interp *interp, register DateInfo *info, Tcl_Obj *strObj, ClockFmtScnCmdArgs *opts); +MODULE_SCOPE int ClockFormat(ClientData clientData, Tcl_Interp *interp, + register DateInfo *info, ClockFmtScnCmdArgs *opts); + MODULE_SCOPE void ClockFrmScnClearCaches(void); /* diff --git a/library/clock.tcl b/library/clock.tcl index ca12f4a..c4e698c 100755 --- a/library/clock.tcl +++ b/library/clock.tcl @@ -685,20 +685,6 @@ proc ::tcl::clock::format { args } { set locale [string tolower $locale] set clockval [lindex $args 0] - # Get the data for time changes in the given zone - - if {$timezone eq ""} { - if {[set timezone [configure -system-tz]] eq ""} { - set timezone [GetSystemTimeZone] - } - } - if {![info exists TZData($timezone)]} { - if {[catch {set timezone [SetupTimeZone $timezone]} retval opts]} { - dict unset opts -errorinfo - return -options $opts $retval - } - } - # Build a procedure to format the result. Cache the built procedure's name # in the 'FormatProc' array to avoid losing its internal representation, # which contains the name resolution. -- cgit v0.12 From 2ba998572c987982e003b6f55f1c51f12bf4b4ce Mon Sep 17 00:00:00 2001 From: sebres Date: Tue, 10 Jan 2017 22:37:40 +0000 Subject: string index tree for fast greedy search of the string (index) by unique string prefix as key; clock scan rewritten to use string index tries search; --- generic/tclClock.c | 74 ++++--- generic/tclClockFmt.c | 444 ++++++++++++++++------------------------- generic/tclDate.h | 22 +- generic/tclStrIdxTree.c | 519 ++++++++++++++++++++++++++++++++++++++++++++++++ generic/tclStrIdxTree.h | 134 +++++++++++++ unix/Makefile.in | 4 + win/Makefile.in | 1 + win/makefile.vc | 1 + 8 files changed, 865 insertions(+), 334 deletions(-) create mode 100644 generic/tclStrIdxTree.c create mode 100644 generic/tclStrIdxTree.h diff --git a/generic/tclClock.c b/generic/tclClock.c index 0c08391..e52b2e7 100644 --- a/generic/tclClock.c +++ b/generic/tclClock.c @@ -15,6 +15,7 @@ */ #include "tclInt.h" +#include "tclStrIdxTree.h" #include "tclDate.h" /* @@ -140,6 +141,10 @@ static unsigned long TzsetGetEpoch(void); static void TzsetIfNecessary(void); static void ClockDeleteCmdProc(ClientData); +static int ClockTestObjCmd( + ClientData clientData, Tcl_Interp *interp, + int objc, Tcl_Obj *const objv[]); + /* * Structure containing description of "native" clock commands to create. */ @@ -169,6 +174,7 @@ static const struct ClockCommand clockCommands[] = { { "GetJulianDayFromEraYearWeekDay", ClockGetjuliandayfromerayearweekdayObjCmd }, { "ParseFormatArgs", ClockParseformatargsObjCmd }, + { "_test", TclStrIdxTreeTestObjCmd }, { NULL, NULL } }; @@ -584,7 +590,7 @@ ClockMCGet( } MODULE_SCOPE Tcl_Obj * -ClockMCGetListIdxDict( +ClockMCGetIdx( ClockFmtScnCmdArgs *opts, int mcKey) { @@ -598,53 +604,45 @@ ClockMCGetListIdxDict( return NULL; } - /* try to get indices dictionray, - * if not available - create from list */ + /* try to get indices object */ + if (dataPtr->mcLitIdxs == NULL) { + return NULL; + } if (Tcl_DictObjGet(NULL, opts->mcDictObj, dataPtr->mcLitIdxs[mcKey], &valObj) != TCL_OK ) { - Tcl_Obj **lstv, *intObj; - int i, lstc; + return NULL; + } - if (dataPtr->mcLitIdxs == NULL) { - dataPtr->mcLitIdxs = ckalloc(MCLIT__END * sizeof(Tcl_Obj*)); - for (i = 0; i < MCLIT__END; ++i) { - Tcl_InitObjRef(dataPtr->mcLitIdxs[i], - Tcl_NewStringObj(MsgCtLitIdxs[i], -1)); - } - } + return valObj; +} - if (Tcl_DictObjGet(opts->interp, opts->mcDictObj, - dataPtr->mcLiterals[mcKey], &valObj) != TCL_OK) { - return NULL; - }; - if (TclListObjGetElements(opts->interp, valObj, - &lstc, &lstv) != TCL_OK) { - return NULL; - }; +MODULE_SCOPE int +ClockMCSetIdx( + ClockFmtScnCmdArgs *opts, + int mcKey, Tcl_Obj *valObj) +{ + ClockClientData *dataPtr = opts->clientData; - valObj = Tcl_NewDictObj(); - for (i = 0; i < lstc; i++) { - intObj = Tcl_NewIntObj(i); - if (Tcl_DictObjPut(opts->interp, valObj, - lstv[i], intObj) != TCL_OK - ) { - Tcl_DecrRefCount(valObj); - Tcl_DecrRefCount(intObj); - return NULL; - } - }; + if (opts->mcDictObj == NULL) { + ClockMCDict(opts); + if (opts->mcDictObj == NULL) + return TCL_ERROR; + } - if (Tcl_DictObjPut(opts->interp, opts->mcDictObj, - dataPtr->mcLitIdxs[mcKey], valObj) != TCL_OK - ) { - Tcl_DecrRefCount(valObj); - return NULL; + /* if literal storage for indices not yet created */ + if (dataPtr->mcLitIdxs == NULL) { + int i; + dataPtr->mcLitIdxs = ckalloc(MCLIT__END * sizeof(Tcl_Obj*)); + for (i = 0; i < MCLIT__END; ++i) { + Tcl_InitObjRef(dataPtr->mcLitIdxs[i], + Tcl_NewStringObj(MsgCtLitIdxs[i], -1)); } - }; + } - return valObj; + return Tcl_DictObjPut(opts->interp, opts->mcDictObj, + dataPtr->mcLitIdxs[mcKey], valObj); } /* diff --git a/generic/tclClockFmt.c b/generic/tclClockFmt.c index 5469ee1..e66c525 100644 --- a/generic/tclClockFmt.c +++ b/generic/tclClockFmt.c @@ -11,6 +11,7 @@ */ #include "tclInt.h" +#include "tclStrIdxTree.h" #include "tclDate.h" /* @@ -33,6 +34,9 @@ static void ClockFmtScnStorageDelete(ClockFmtScnStorage *fss); static void ClockFrmScnFinalize(ClientData clientData); +/* Msgcat index literals prefixed with _IDX_, used for quick dictionary search */ +CLOCK_LOCALE_LITERAL_ARRAY(MsgCtLitIdxs, "_IDX_"); + /* * Clock scan and format facilities. */ @@ -583,6 +587,139 @@ LocaleListSearch(ClockFmtScnCmdArgs *opts, minLen, maxLen); } +static TclStrIdxTree * +ClockMCGetListIdxTree( + ClockFmtScnCmdArgs *opts, + int mcKey) +{ + TclStrIdxTree * idxTree; + Tcl_Obj *objPtr = ClockMCGetIdx(opts, mcKey); + if ( objPtr != NULL + && (idxTree = TclStrIdxTreeGetFromObj(objPtr)) != NULL + ) { + return idxTree; + + } else { + /* build new index */ + + Tcl_Obj **lstv; + int lstc; + Tcl_Obj *valObj; + + objPtr = TclStrIdxTreeNewObj(); + if ((idxTree = TclStrIdxTreeGetFromObj(objPtr)) == NULL) { + goto done; /* unexpected, but ...*/ + } + + valObj = ClockMCGet(opts, mcKey); + if (valObj == NULL) { + goto done; + } + + if (TclListObjGetElements(opts->interp, valObj, + &lstc, &lstv) != TCL_OK) { + goto done; + }; + + if (TclStrIdxTreeBuildFromList(idxTree, lstc, lstv) != TCL_OK) { + goto done; + } + + ClockMCSetIdx(opts, mcKey, objPtr); + objPtr = NULL; + }; + +done: + if (objPtr) { + Tcl_DecrRefCount(objPtr); + idxTree = NULL; + } + + return idxTree; +} + +static TclStrIdxTree * +ClockMCGetMultiListIdxTree( + ClockFmtScnCmdArgs *opts, + int mcKey, + int *mcKeys) +{ + TclStrIdxTree * idxTree; + Tcl_Obj *objPtr = ClockMCGetIdx(opts, mcKey); + if ( objPtr != NULL + && (idxTree = TclStrIdxTreeGetFromObj(objPtr)) != NULL + ) { + return idxTree; + + } else { + /* build new index */ + + Tcl_Obj **lstv; + int lstc; + Tcl_Obj *valObj; + + objPtr = TclStrIdxTreeNewObj(); + if ((idxTree = TclStrIdxTreeGetFromObj(objPtr)) == NULL) { + goto done; /* unexpected, but ...*/ + } + + while (*mcKeys) { + + valObj = ClockMCGet(opts, *mcKeys); + if (valObj == NULL) { + goto done; + } + + if (TclListObjGetElements(opts->interp, valObj, + &lstc, &lstv) != TCL_OK) { + goto done; + }; + + if (TclStrIdxTreeBuildFromList(idxTree, lstc, lstv) != TCL_OK) { + goto done; + } + mcKeys++; + } + + ClockMCSetIdx(opts, mcKey, objPtr); + }; + +done: + if (objPtr) { + Tcl_DecrRefCount(objPtr); + idxTree = NULL; + } + + return idxTree; +} + +inline int +ClockStrIdxTreeSearch(ClockFmtScnCmdArgs *opts, + DateInfo *info, TclStrIdxTree *idxTree, int *val, + int minLen, int maxLen) +{ + const char *f; + TclStrIdx *foundItem; + f = TclStrIdxTreeSearch(NULL, &foundItem, idxTree, + yyInput, yyInput + maxLen); + + if (f <= yyInput || (f - yyInput) < minLen) { + /* not found */ + return TCL_RETURN; + } + if (foundItem->value == -1) { + /* ambigous */ + return TCL_RETURN; + } + + *val = foundItem->value; + + /* shift input pointer */ + yyInput = f; + + return TCL_OK; +} + static int StaticListSearch(ClockFmtScnCmdArgs *opts, DateInfo *info, const char **lst, int *val) @@ -612,21 +749,19 @@ FindWordEnd( register const char * p, const char * end) { register const char *x = tok->tokWord.start; - if (x == tok->tokWord.end) { /* single char word */ - if (*p != *x) { - /* no match -> error */ - return NULL; + const char *pfnd; + if (x == tok->tokWord.end - 1) { /* fast phase-out for single char word */ + if (*p == *x) { + return ++p; } - return ++p; } /* multi-char word */ - do - if (*p++ != *x++) { - /* no match -> error */ - return NULL; - } - while (x <= tok->tokWord.end && p < end); - return p; + x = TclUtfFindEqualNC(x, tok->tokWord.end, p, end, &pfnd); + if (x < tok->tokWord.end) { + /* no match -> error */ + return NULL; + } + return pfnd; } static int @@ -822,11 +957,18 @@ ClockScnToken_LocaleListMatcher_Proc(ClockFmtScnCmdArgs *opts, { int ret, val; int minLen, maxLen; + TclStrIdxTree *idxTree; DetermineGreedySearchLen(opts, info, tok, &minLen, &maxLen); - ret = LocaleListSearch(opts, info, (int)tok->map->data, &val, - minLen, maxLen); + /* get or create tree in msgcat dict */ + + idxTree = ClockMCGetListIdxTree(opts, (int)tok->map->data /* mcKey */); + if (idxTree == NULL) { + return TCL_ERROR; + } + + ret = ClockStrIdxTreeSearch(opts, info, idxTree, &val, minLen, maxLen); if (ret != TCL_OK) { return ret; } @@ -1120,7 +1262,8 @@ ClockGetOrParseScanFormat( /* begin new word token - don't join with previous word token, * because current mapping should be "...%%..." -> "...%..." */ tok->map = &ScnWordTokenMap; - tok->tokWord.start = tok->tokWord.end = p; + tok->tokWord.start = p; + tok->tokWord.end = p+1; AllocTokenInChain(tok, fss->scnTok, fss->scnTokC); continue; break; @@ -1190,7 +1333,7 @@ word_tok: if (tok > fss->scnTok && (tok-1)->map == &ScnWordTokenMap) { wordTok = tok-1; } - wordTok->tokWord.end = p; + wordTok->tokWord.end = p+1; if (wordTok == tok) { wordTok->tokWord.start = p; wordTok->map = &ScnWordTokenMap; @@ -1214,7 +1357,7 @@ word_tok: if (prevTok->map->type != CTOKT_WORD) { endDist += prevTok->map->minSize; } else { - endDist += prevTok->tokWord.end - prevTok->tokWord.start + 1; + endDist += prevTok->tokWord.end - prevTok->tokWord.start; } prevTok--; } @@ -1325,6 +1468,11 @@ ClockScan( yyMeridian = MER24; + /* lower case given string into new object */ + strObj = Tcl_NewStringObj(TclGetString(strObj), strObj->length); + Tcl_IncrRefCount(strObj); + strObj->length = Tcl_UtfToLower(TclGetString(strObj)); + p = TclGetString(strObj); end = p + strObj->length; /* in strict mode - bypass spaces at begin / end only (not between tokens) */ @@ -1578,6 +1726,8 @@ not_match: done: + Tcl_DecrRefCount(strObj); + return ret; } @@ -1604,266 +1754,6 @@ ClockFormat( return TCL_ERROR; } */ -#if 0 - /* prepare parsing */ - - yyMeridian = MER24; - - p = TclGetString(strObj); - end = p + strObj->length; - /* in strict mode - bypass spaces at begin / end only (not between tokens) */ - if (opts->flags & CLF_STRICT) { - while (p < end && isspace(UCHAR(*p))) { - p++; - } - } - info->dateStart = yyInput = p; - info->dateEnd = end; - - /* parse string */ - for (; tok->map != NULL; tok++) { - map = tok->map; - /* bypass spaces at begin of input before parsing each token */ - if ( !(opts->flags & CLF_STRICT) - && (map->type != CTOKT_SPACE && map->type != CTOKT_WORD) - ) { - while (p < end && isspace(UCHAR(*p))) { - p++; - } - } - yyInput = p; - switch (map->type) - { - case CTOKT_DIGIT: - if (1) { - int size = map->maxSize; - int sign = 1; - if (map->flags & CLF_SIGNED) { - if (*p == '+') { yyInput = ++p; } - else - if (*p == '-') { yyInput = ++p; sign = -1; }; - } - /* greedy find digits (look for forward digits consider spaces), - * corresponding pre-calculated lookAhead */ - if (size != map->minSize && tok->lookAhead) { - int spcnt = 0; - const char *pe; - size += tok->lookAhead; - x = p + size; if (x > end) { x = end; }; - pe = x; - while (p < x) { - if (isspace(UCHAR(*p))) { - if (pe > p) { pe = p; }; - if (x < end) x++; - p++; - spcnt++; - continue; - } - if (isdigit(UCHAR(*p))) { - p++; - continue; - } - break; - } - /* consider reserved (lookAhead) for next tokens */ - p -= tok->lookAhead + spcnt; - if (p > pe) { - p = pe; - } - } else { - x = p + size; if (x > end) { x = end; }; - while (isdigit(UCHAR(*p)) && p < x) { p++; }; - } - size = p - yyInput; - if (size < map->minSize) { - /* missing input -> error */ - goto not_match; - } - /* string 2 number, put number into info structure by offset */ - p = yyInput; x = p + size; - if (!(map->flags & CLF_LOCALSEC)) { - if (_str2int((time_t *)(((char *)info) + map->offs), - p, x, sign) != TCL_OK) { - goto overflow; - } - p = x; - } else { - if (_str2wideInt((Tcl_WideInt *)(((char *)info) + map->offs), - p, x, sign) != TCL_OK) { - goto overflow; - } - p = x; - } - flags = (flags & ~map->clearFlags) | map->flags; - } - break; - case CTOKT_PARSER: - switch (map->parser(opts, info, tok)) { - case TCL_OK: - break; - case TCL_RETURN: - goto not_match; - break; - default: - goto done; - break; - }; - p = yyInput; - flags = (flags & ~map->clearFlags) | map->flags; - break; - case CTOKT_SPACE: - /* at least one space in strict mode */ - if (opts->flags & CLF_STRICT) { - if (!isspace(UCHAR(*p))) { - /* unmatched -> error */ - goto not_match; - } - p++; - } - while (p < end && isspace(UCHAR(*p))) { - p++; - } - break; - case CTOKT_WORD: - x = FindWordEnd(tok, p, end); - if (!x) { - /* no match -> error */ - goto not_match; - } - p = x; - continue; - break; - } - } - - /* ignore spaces at end */ - while (p < end && isspace(UCHAR(*p))) { - p++; - } - /* check end was reached */ - if (p < end) { - /* something after last token - wrong format */ - goto not_match; - } - - /* - * Invalidate result - */ - - /* seconds token (%s) take precedence over all other tokens */ - if ((opts->flags & CLF_EXTENDED) || !(flags & CLF_LOCALSEC)) { - if (flags & CLF_DATE) { - - if (!(flags & CLF_JULIANDAY)) { - info->flags |= CLF_ASSEMBLE_SECONDS|CLF_ASSEMBLE_JULIANDAY; - - /* dd precedence below ddd */ - switch (flags & (CLF_MONTH|CLF_DAYOFYEAR|CLF_DAYOFMONTH)) { - case (CLF_DAYOFYEAR|CLF_DAYOFMONTH): - /* miss month: ddd over dd (without month) */ - flags &= ~CLF_DAYOFMONTH; - case (CLF_DAYOFYEAR): - /* ddd over naked weekday */ - if (!(flags & CLF_ISO8601YEAR)) { - flags &= ~CLF_ISO8601; - } - break; - case (CLF_MONTH|CLF_DAYOFYEAR|CLF_DAYOFMONTH): - /* both available: mmdd over ddd */ - flags &= ~CLF_DAYOFYEAR; - case (CLF_MONTH|CLF_DAYOFMONTH): - case (CLF_DAYOFMONTH): - /* mmdd / dd over naked weekday */ - if (!(flags & CLF_ISO8601YEAR)) { - flags &= ~CLF_ISO8601; - } - break; - } - - /* YearWeekDay below YearMonthDay */ - if ( (flags & CLF_ISO8601) - && ( (flags & (CLF_YEAR|CLF_DAYOFYEAR)) == (CLF_YEAR|CLF_DAYOFYEAR) - || (flags & (CLF_YEAR|CLF_DAYOFMONTH|CLF_MONTH)) == (CLF_YEAR|CLF_DAYOFMONTH|CLF_MONTH) - ) - ) { - /* yy precedence below yyyy */ - if (!(flags & CLF_ISO8601CENTURY) && (flags & CLF_CENTURY)) { - /* normally precedence of ISO is higher, but no century - so put it down */ - flags &= ~CLF_ISO8601; - } - else - /* yymmdd or yyddd over naked weekday */ - if (!(flags & CLF_ISO8601YEAR)) { - flags &= ~CLF_ISO8601; - } - } - - if (!(flags & CLF_ISO8601)) { - if (yyYear < 100) { - if (!(flags & CLF_CENTURY)) { - if (yyYear >= dataPtr->yearOfCenturySwitch) { - yyYear -= 100; - } - yyYear += dataPtr->currentYearCentury; - } else { - yyYear += info->dateCentury * 100; - } - } - } else { - if (info->date.iso8601Year < 100) { - if (!(flags & CLF_ISO8601CENTURY)) { - if (info->date.iso8601Year >= dataPtr->yearOfCenturySwitch) { - info->date.iso8601Year -= 100; - } - info->date.iso8601Year += dataPtr->currentYearCentury; - } else { - info->date.iso8601Year += info->dateCentury * 100; - } - } - } - } - } - - /* if no time - reset time */ - if (!(flags & (CLF_TIME|CLF_LOCALSEC))) { - info->flags |= CLF_ASSEMBLE_SECONDS; - yydate.localSeconds = 0; - } - - if (flags & CLF_TIME) { - info->flags |= CLF_ASSEMBLE_SECONDS; - yySeconds = ToSeconds(yyHour, yyMinutes, - yySeconds, yyMeridian); - } else - if (!(flags & CLF_LOCALSEC)) { - info->flags |= CLF_ASSEMBLE_SECONDS; - yySeconds = yydate.localSeconds % SECONDS_PER_DAY; - } - } - - /* tell caller which flags were set */ - info->flags |= flags; - - ret = TCL_OK; - goto done; - -overflow: - - Tcl_SetResult(interp, "requested date too large to represent", - TCL_STATIC); - Tcl_SetErrorCode(interp, "CLOCK", "dateTooLarge", NULL); - goto done; - -not_match: - - Tcl_SetResult(interp, "input string does not match supplied format", - TCL_STATIC); - Tcl_SetErrorCode(interp, "CLOCK", "badInputString", NULL); - -done: - - return ret; -#endif } diff --git a/generic/tclDate.h b/generic/tclDate.h index 112ed31..2728dd3 100644 --- a/generic/tclDate.h +++ b/generic/tclDate.h @@ -126,24 +126,6 @@ typedef enum ClockMsgCtLiteral { } /* - * Primitives to safe set, reset and free references. - */ - -#define Tcl_UnsetObjRef(obj) \ - if (obj != NULL) { Tcl_DecrRefCount(obj); obj = NULL; } -#define Tcl_InitObjRef(obj, val) \ - obj = val; if (obj) { Tcl_IncrRefCount(obj); } -#define Tcl_SetObjRef(obj, val) \ -if (1) { \ - Tcl_Obj *nval = val; \ - if (obj != nval) { \ - Tcl_Obj *prev = obj; \ - Tcl_InitObjRef(obj, nval); \ - if (prev != NULL) { Tcl_DecrRefCount(prev); }; \ - } \ -} - -/* * Structure containing the fields used in [clock format] and [clock scan] */ @@ -450,7 +432,9 @@ MODULE_SCOPE Tcl_Obj * MODULE_SCOPE Tcl_Obj * ClockMCGet(ClockFmtScnCmdArgs *opts, int mcKey); MODULE_SCOPE Tcl_Obj * - ClockMCGetListIdxDict(ClockFmtScnCmdArgs *opts, int mcKey); + ClockMCGetIdx(ClockFmtScnCmdArgs *opts, int mcKey); +MODULE_SCOPE int ClockMCSetIdx(ClockFmtScnCmdArgs *opts, int mcKey, + Tcl_Obj *valObj); /* tclClockFmt.c module declarations */ diff --git a/generic/tclStrIdxTree.c b/generic/tclStrIdxTree.c new file mode 100644 index 0000000..f078c7a --- /dev/null +++ b/generic/tclStrIdxTree.c @@ -0,0 +1,519 @@ +/* + * tclStrIdxTree.c -- + * + * Contains the routines for managing string index tries in Tcl. + * + * This code is back-ported from the tclSE engine, by Serg G. Brester. + * + * Copyright (c) 2016 by Sergey G. Brester aka sebres. All rights reserved. + * + * See the file "license.terms" for information on usage and redistribution of + * this file, and for a DISCLAIMER OF ALL WARRANTIES. + * + * ----------------------------------------------------------------------- + * + * String index tries are prepaired structures used for fast greedy search of the string + * (index) by unique string prefix as key. + * + * Index tree build for two lists together can be explained in the following datagram + * + * Lists: + * + * {Januar Februar Maerz April Mai Juni Juli August September Oktober November Dezember} + * {Jnr Fbr Mrz Apr Mai Jni Jli Agt Spt Okt Nvb Dzb} + * + * Index-Tree: + * + * j -1 * ... + * anuar 0 * + * u -1 * a -1 + * ni 5 * pril 3 + * li 6 * ugust 7 + * n -1 * gt 7 + * r 0 * s 8 + * i 5 * eptember 8 + * li 6 * pt 8 + * f 1 * oktober 9 + * ebruar 1 * n 10 + * br 1 * ovember 10 + * m -1 * vb 10 + * a -1 * d 11 + * erz 2 * ezember 11 + * i 4 * zb 11 + * rz 2 * + * ... + * + * Thereby value -1 shows pure group items (corresponding ambigous matches). + * + * StrIdxTree's are very fast, so: + * build of above-mentioned tree takes about 10 microseconds. + * search of string index in this tree takes fewer as 0.1 microseconds. + * + */ + +#include "tclInt.h" +#include "tclStrIdxTree.h" + + +/* + *---------------------------------------------------------------------- + * + * TclStrIdxTreeSearch -- + * + * Find largest part of string "start" in indexed tree (case sensitive). + * + * Also used for building of string index tree. + * + * Results: + * Return position of UTF character in start after last equal character + * and found item (with parent). + * + * Side effects: + * None. + * + *---------------------------------------------------------------------- + */ + +MODULE_SCOPE const char* +TclStrIdxTreeSearch( + TclStrIdxTree **foundParent, /* Return value of found sub tree (used for tree build) */ + TclStrIdx **foundItem, /* Return value of found item */ + TclStrIdxTree *tree, /* Index tree will be browsed */ + const char *start, /* UTF string to find in tree */ + const char *end) /* End of string */ +{ + TclStrIdxTree *parent = tree, *prevParent = tree; + TclStrIdx *item = tree->firstPtr, *prevItem = NULL; + const char *s = start, *e, *cin, *preve; + int offs = 0; + + if (item == NULL) { + goto done; + } + + /* search in tree */ + do { + cin = TclGetString(item->key) + offs; + e = TclUtfFindEqual(s, end, cin, cin + item->length); + /* if something was found */ + if (e > s) { + /* if whole string was found */ + if (e >= end) { + start = e; + goto done; + }; + /* set new offset and shift start string */ + offs += (e - s); + s = e; + /* if match item, go deeper as long as possible */ + if (offs >= item->length && item->childTree.firstPtr) { + /* save previuosly found item (if not ambigous) for + * possible fallback (few greedy match) */ + if (item->value != -1) { + preve = e; + prevItem = item; + prevParent = parent; + } + parent = &item->childTree; + item = item->childTree.firstPtr; + continue; + } + /* no children - return this item and current chars found */ + start = e; + goto done; + } + + item = item->nextPtr; + + } while (item != NULL); + + /* fallback (few greedy match) not ambigous (has a value) */ + if (prevItem != NULL) { + item = prevItem; + parent = prevParent; + start = preve; + } + +done: + + if (foundParent) + *foundParent = parent; + if (foundItem) + *foundItem = item; + return start; +} + +MODULE_SCOPE void +TclStrIdxTreeFree( + TclStrIdx *tree) +{ + while (tree != NULL) { + TclStrIdx *t; + Tcl_DecrRefCount(tree->key); + if (tree->childTree.firstPtr != NULL) { + TclStrIdxTreeFree(tree->childTree.firstPtr); + } + t = tree, tree = tree->nextPtr; + ckfree(t); + } +} + +/* + * Several bidirectional list primitives + */ +inline void +TclStrIdxTreeInsertBranch( + TclStrIdxTree *parent, + register TclStrIdx *item, + register TclStrIdx *child) +{ + if (parent->firstPtr == child) + parent->firstPtr = item; + if (parent->lastPtr == child) + parent->lastPtr = item; + if (item->nextPtr = child->nextPtr) { + item->nextPtr->prevPtr = item; + child->nextPtr = NULL; + } + if (item->prevPtr = child->prevPtr) { + item->prevPtr->nextPtr = item; + child->prevPtr = NULL; + } + item->childTree.firstPtr = child; + item->childTree.lastPtr = child; +} + +inline void +TclStrIdxTreeAppend( + register TclStrIdxTree *parent, + register TclStrIdx *item) +{ + if (parent->lastPtr != NULL) { + parent->lastPtr->nextPtr = item; + } + item->prevPtr = parent->lastPtr; + item->nextPtr = NULL; + parent->lastPtr = item; + if (parent->firstPtr == NULL) { + parent->firstPtr = item; + } +} + + +/* + *---------------------------------------------------------------------- + * + * TclStrIdxTreeBuildFromList -- + * + * Build or extend string indexed tree from tcl list. + * + * Important: by multiple lists, optimal tree can be created only if list with + * larger strings used firstly. + * + * Results: + * Returns a standard Tcl result. + * + * Side effects: + * None. + * + *---------------------------------------------------------------------- + */ + +MODULE_SCOPE int +TclStrIdxTreeBuildFromList( + TclStrIdxTree *idxTree, + int lstc, + Tcl_Obj **lstv) +{ + Tcl_Obj **lwrv; + int i, ret = TCL_ERROR; + const char *s, *e, *f; + TclStrIdx *item; + + /* create lowercase reflection of the list keys */ + + lwrv = ckalloc(sizeof(Tcl_Obj*) * lstc); + if (lwrv == NULL) { + return TCL_ERROR; + } + for (i = 0; i < lstc; i++) { + lwrv[i] = Tcl_DuplicateObj(lstv[i]); + if (lwrv[i] == NULL) { + return TCL_ERROR; + } + Tcl_IncrRefCount(lwrv[i]); + lwrv[i]->length = Tcl_UtfToLower(TclGetString(lwrv[i])); + } + + /* build index tree of the list keys */ + for (i = 0; i < lstc; i++) { + TclStrIdxTree *foundParent = idxTree; + e = s = TclGetString(lwrv[i]); + e += lwrv[i]->length; + + /* ignore empty values (impossible to index it) */ + if (lwrv[i]->length == 0) continue; + + item = NULL; + if (idxTree->firstPtr != NULL) { + TclStrIdx *foundItem; + f = TclStrIdxTreeSearch(&foundParent, &foundItem, + idxTree, s, e); + /* if common prefix was found */ + if (f > s) { + /* ignore element if fulfilled or ambigous */ + if (f == e) { + continue; + } + /* if shortest key was found with the same value, + * just replace its current key with longest key */ + if ( foundItem->value == i + && foundItem->length < lwrv[i]->length + && foundItem->childTree.firstPtr == NULL + ) { + Tcl_SetObjRef(foundItem->key, lwrv[i]); + foundItem->length = lwrv[i]->length; + continue; + } + /* split tree (e. g. j->(jan,jun) + jul == j->(jan,ju->(jun,jul)) ) + * but don't split by fulfilled child of found item ( ii->iii->iiii ) */ + if (foundItem->length != (f - s)) { + /* first split found item (insert one between parent and found + new one) */ + item = ckalloc(sizeof(*item)); + if (item == NULL) { + goto done; + } + Tcl_InitObjRef(item->key, foundItem->key); + item->length = f - s; + /* set value or mark as ambigous if not the same value of both */ + item->value = (foundItem->value == i) ? i : -1; + /* insert group item between foundParent and foundItem */ + TclStrIdxTreeInsertBranch(foundParent, item, foundItem); + foundParent = &item->childTree; + } else { + /* the new item should be added as child of found item */ + foundParent = &foundItem->childTree; + } + } + } + /* append item at end of found parent */ + item = ckalloc(sizeof(*item)); + if (item == NULL) { + goto done; + } + item->childTree.lastPtr = item->childTree.firstPtr = NULL; + Tcl_InitObjRef(item->key, lwrv[i]); + item->length = lwrv[i]->length; + item->value = i; + TclStrIdxTreeAppend(foundParent, item); + }; + + ret = TCL_OK; + +done: + + if (lwrv != NULL) { + for (i = 0; i < lstc; i++) { + Tcl_DecrRefCount(lwrv[i]); + } + ckfree(lwrv); + } + + if (ret != TCL_OK) { + if (idxTree->firstPtr != NULL) { + TclStrIdxTreeFree(idxTree->firstPtr); + } + } + + return ret; +} + + +static void +StrIdxTreeObj_DupIntRepProc(Tcl_Obj *srcPtr, Tcl_Obj *copyPtr); +static void +StrIdxTreeObj_FreeIntRepProc(Tcl_Obj *objPtr); +static void +StrIdxTreeObj_UpdateStringProc(Tcl_Obj *objPtr); + +Tcl_ObjType StrIdxTreeObjType = { + "str-idx-tree", /* name */ + StrIdxTreeObj_FreeIntRepProc, /* freeIntRepProc */ + StrIdxTreeObj_DupIntRepProc, /* dupIntRepProc */ + StrIdxTreeObj_UpdateStringProc, /* updateStringProc */ + NULL /* setFromAnyProc */ +}; + +MODULE_SCOPE Tcl_Obj* +TclStrIdxTreeNewObj() +{ + Tcl_Obj *objPtr = Tcl_NewObj(); + objPtr->internalRep.twoPtrValue.ptr1 = NULL; + objPtr->internalRep.twoPtrValue.ptr2 = NULL; + objPtr->typePtr = &StrIdxTreeObjType; + /* return tree root in internal representation */ + return objPtr; +} + +static void +StrIdxTreeObj_DupIntRepProc(Tcl_Obj *srcPtr, Tcl_Obj *copyPtr) +{ + /* follow links (smart pointers) */ + if ( srcPtr->internalRep.twoPtrValue.ptr1 != NULL + && srcPtr->internalRep.twoPtrValue.ptr2 == NULL + ) { + srcPtr = (Tcl_Obj*)srcPtr->internalRep.twoPtrValue.ptr1; + } + /* create smart pointer to it (ptr1 != NULL, ptr2 = NULL) */ + Tcl_InitObjRef(((Tcl_Obj *)copyPtr->internalRep.twoPtrValue.ptr1), + srcPtr); + copyPtr->internalRep.twoPtrValue.ptr2 = NULL; + copyPtr->typePtr = &StrIdxTreeObjType; +} + +static void +StrIdxTreeObj_FreeIntRepProc(Tcl_Obj *objPtr) +{ + /* follow links (smart pointers) */ + if ( objPtr->internalRep.twoPtrValue.ptr1 != NULL + && objPtr->internalRep.twoPtrValue.ptr2 == NULL + ) { + /* is a link */ + Tcl_UnsetObjRef(((Tcl_Obj *)objPtr->internalRep.twoPtrValue.ptr1)); + } else { + /* is a tree */ + TclStrIdxTree *tree = (TclStrIdxTree*)&objPtr->internalRep.twoPtrValue.ptr1; + if (tree->firstPtr != NULL) { + TclStrIdxTreeFree(tree->firstPtr); + } + objPtr->internalRep.twoPtrValue.ptr1 = NULL; + objPtr->internalRep.twoPtrValue.ptr2 = NULL; + } + objPtr->typePtr = NULL; +}; + +static void +StrIdxTreeObj_UpdateStringProc(Tcl_Obj *objPtr) +{ + /* currently only dummy empty string possible */ + objPtr->length = 0; + objPtr->bytes = tclEmptyStringRep; +}; + +MODULE_SCOPE TclStrIdxTree * +TclStrIdxTreeGetFromObj(Tcl_Obj *objPtr) { + /* follow links (smart pointers) */ + if (objPtr->typePtr != &StrIdxTreeObjType) { + return NULL; + } + if ( objPtr->internalRep.twoPtrValue.ptr1 != NULL + && objPtr->internalRep.twoPtrValue.ptr2 == NULL + ) { + objPtr = (Tcl_Obj*)objPtr->internalRep.twoPtrValue.ptr1; + } + /* return tree root in internal representation */ + return (TclStrIdxTree*)&objPtr->internalRep.twoPtrValue.ptr1; +} + +/* + * Several debug primitives + */ +#if 1 + +void +TclStrIdxTreePrint( + Tcl_Interp *interp, + TclStrIdx *tree, + int offs) +{ + Tcl_Obj *obj[2]; + const char *s; + Tcl_InitObjRef(obj[0], Tcl_NewStringObj("::puts", -1)); + while (tree != NULL) { + s = TclGetString(tree->key) + offs; + Tcl_InitObjRef(obj[1], Tcl_ObjPrintf("%*s%.*s\t:%d", + offs, "", tree->length - offs, s, tree->value)); + Tcl_PutsObjCmd(NULL, interp, 2, obj); + Tcl_UnsetObjRef(obj[1]); + if (tree->childTree.firstPtr != NULL) { + TclStrIdxTreePrint(interp, tree->childTree.firstPtr, tree->length); + } + tree = tree->nextPtr; + } + Tcl_UnsetObjRef(obj[0]); +} + + +MODULE_SCOPE int +TclStrIdxTreeTestObjCmd( + ClientData clientData, Tcl_Interp *interp, + int objc, Tcl_Obj *const objv[]) +{ + const char *cs, *cin, *ret; + + static const char *const options[] = { + "index", "puts-index", "findequal", + NULL + }; + enum optionInd { + O_INDEX, O_PUTS_INDEX, O_FINDEQUAL + }; + int optionIndex; + + if (objc < 2) { + Tcl_SetResult(interp, "wrong # args", TCL_STATIC); + return TCL_ERROR; + } + if (Tcl_GetIndexFromObj(interp, objv[1], options, + "option", 0, &optionIndex) != TCL_OK) { + Tcl_SetErrorCode(interp, "CLOCK", "badOption", + Tcl_GetString(objv[1]), NULL); + return TCL_ERROR; + } + switch (optionIndex) { + case O_FINDEQUAL: + if (objc < 4) { + Tcl_SetResult(interp, "wrong # args", TCL_STATIC); + return TCL_ERROR; + } + cs = TclGetString(objv[2]); + cin = TclGetString(objv[3]); + ret = TclUtfFindEqual( + cs, cs + objv[1]->length, cin, cin + objv[2]->length); + Tcl_SetObjResult(interp, Tcl_NewIntObj(ret - cs)); + break; + case O_INDEX: + case O_PUTS_INDEX: + + if (1) { + Tcl_Obj **lstv; + int i, lstc; + TclStrIdxTree idxTree = {NULL, NULL}; + i = 1; + while (++i < objc) { + if (TclListObjGetElements(interp, objv[i], + &lstc, &lstv) != TCL_OK) { + return TCL_ERROR; + }; + TclStrIdxTreeBuildFromList(&idxTree, lstc, lstv); + } + if (optionIndex == O_PUTS_INDEX) { + TclStrIdxTreePrint(interp, idxTree.firstPtr, 0); + } + TclStrIdxTreeFree(idxTree.firstPtr); + } + break; + } + + return TCL_OK; +} + +#endif + +/* + * Local Variables: + * mode: c + * c-basic-offset: 4 + * fill-column: 78 + * End: + */ diff --git a/generic/tclStrIdxTree.h b/generic/tclStrIdxTree.h new file mode 100644 index 0000000..e80d3db --- /dev/null +++ b/generic/tclStrIdxTree.h @@ -0,0 +1,134 @@ +/* + * tclStrIdxTree.h -- + * + * Declarations of string index tries and other primitives currently + * back-ported from tclSE. + * + * Copyright (c) 2016 Serg G. Brester (aka sebres) + * + * See the file "license.terms" for information on usage and redistribution + * of this file, and for a DISCLAIMER OF ALL WARRANTIES. + */ + +#ifndef _TCLSTRIDXTREE_H +#define _TCLSTRIDXTREE_H + + +/* + * Main structures declarations of index tree and entry + */ + +typedef struct TclStrIdxTree { + struct TclStrIdx *firstPtr; + struct TclStrIdx *lastPtr; +} TclStrIdxTree; + +typedef struct TclStrIdx { + struct TclStrIdxTree childTree; + struct TclStrIdx *nextPtr; + struct TclStrIdx *prevPtr; + Tcl_Obj *key; + int length; + int value; +} TclStrIdx; + + +/* + *---------------------------------------------------------------------- + * + * TclUtfFindEqual, TclUtfFindEqualNC -- + * + * Find largest part of string cs in string cin (case sensitive and not). + * + * Results: + * Return position of UTF character in cs after last equal character. + * + * Side effects: + * None. + * + *---------------------------------------------------------------------- + */ + +inline const char * +TclUtfFindEqual( + register const char *cs, /* UTF string to find in cin. */ + register const char *cse, /* End of cs */ + register const char *cin, /* UTF string will be browsed. */ + register const char *cine) /* End of cin */ +{ + register const char *ret = cs; + Tcl_UniChar ch1, ch2; + do { + cs += TclUtfToUniChar(cs, &ch1); + cin += TclUtfToUniChar(cin, &ch2); + if (ch1 != ch2) break; + } while ((ret = cs) < cse && cin < cine); + return ret; +} + +inline const char * +TclUtfFindEqualNC( + register const char *cs, /* UTF string to find in cin. */ + register const char *cse, /* End of cs */ + register const char *cin, /* UTF string will be browsed. */ + register const char *cine, /* End of cin */ + const char **cinfnd) /* Return position in cin */ +{ + register const char *ret = cs; + Tcl_UniChar ch1, ch2; + do { + cs += TclUtfToUniChar(cs, &ch1); + cin += TclUtfToUniChar(cin, &ch2); + if (ch1 != ch2) { + ch1 = Tcl_UniCharToLower(ch1); + ch2 = Tcl_UniCharToLower(ch2); + if (ch1 != ch2) break; + } + *cinfnd = cin; + } while ((ret = cs) < cse && cin < cine); + return ret; +} + +/* + * Primitives to safe set, reset and free references. + */ + +#define Tcl_UnsetObjRef(obj) \ + if (obj != NULL) { Tcl_DecrRefCount(obj); obj = NULL; } +#define Tcl_InitObjRef(obj, val) \ + obj = val; if (obj) { Tcl_IncrRefCount(obj); } +#define Tcl_SetObjRef(obj, val) \ +if (1) { \ + Tcl_Obj *nval = val; \ + if (obj != nval) { \ + Tcl_Obj *prev = obj; \ + Tcl_InitObjRef(obj, nval); \ + if (prev != NULL) { Tcl_DecrRefCount(prev); }; \ + } \ +} + +/* + * Prototypes of module functions. + */ + +MODULE_SCOPE const char* + TclStrIdxTreeSearch(TclStrIdxTree **foundParent, + TclStrIdx **foundItem, TclStrIdxTree *tree, + const char *start, const char *end); + +MODULE_SCOPE int TclStrIdxTreeBuildFromList(TclStrIdxTree *idxTree, + int lstc, Tcl_Obj **lstv); + +MODULE_SCOPE Tcl_Obj* + TclStrIdxTreeNewObj(); + +MODULE_SCOPE TclStrIdxTree* + TclStrIdxTreeGetFromObj(Tcl_Obj *objPtr); + +#if 1 + +MODULE_SCOPE int TclStrIdxTreeTestObjCmd(ClientData, Tcl_Interp *, + int, Tcl_Obj *const objv[]); +#endif + +#endif /* _TCLSTRIDXTREE_H */ diff --git a/unix/Makefile.in b/unix/Makefile.in index b220139..19ab6ec 100644 --- a/unix/Makefile.in +++ b/unix/Makefile.in @@ -451,6 +451,7 @@ GENERIC_SRCS = \ $(GENERIC_DIR)/tclScan.c \ $(GENERIC_DIR)/tclStubInit.c \ $(GENERIC_DIR)/tclStringObj.c \ + $(GENERIC_DIR)/tclStrIdxTree.c \ $(GENERIC_DIR)/tclStrToD.c \ $(GENERIC_DIR)/tclTest.c \ $(GENERIC_DIR)/tclTestObj.c \ @@ -1305,6 +1306,9 @@ tclScan.o: $(GENERIC_DIR)/tclScan.c tclStringObj.o: $(GENERIC_DIR)/tclStringObj.c $(MATHHDRS) $(CC) -c $(CC_SWITCHES) $(GENERIC_DIR)/tclStringObj.c +tclStrIdxTree.o: $(GENERIC_DIR)/tclStrIdxTree.c $(MATHHDRS) + $(CC) -c $(CC_SWITCHES) $(GENERIC_DIR)/tclStrIdxTree.c + tclStrToD.o: $(GENERIC_DIR)/tclStrToD.c $(MATHHDRS) $(CC) -c $(CC_SWITCHES) $(GENERIC_DIR)/tclStrToD.c diff --git a/win/Makefile.in b/win/Makefile.in index 82e5516..478bbb9 100644 --- a/win/Makefile.in +++ b/win/Makefile.in @@ -291,6 +291,7 @@ GENERIC_OBJS = \ tclResult.$(OBJEXT) \ tclScan.$(OBJEXT) \ tclStringObj.$(OBJEXT) \ + tclStrIdxTree.$(OBJEXT) \ tclStrToD.$(OBJEXT) \ tclStubInit.$(OBJEXT) \ tclThread.$(OBJEXT) \ diff --git a/win/makefile.vc b/win/makefile.vc index d6dbf85..48bacbc 100644 --- a/win/makefile.vc +++ b/win/makefile.vc @@ -333,6 +333,7 @@ COREOBJS = \ $(TMP_DIR)\tclResult.obj \ $(TMP_DIR)\tclScan.obj \ $(TMP_DIR)\tclStringObj.obj \ + $(TMP_DIR)\tclStrIdxTree.obj \ $(TMP_DIR)\tclStrToD.obj \ $(TMP_DIR)\tclStubInit.obj \ $(TMP_DIR)\tclThread.obj \ -- cgit v0.12 From 20ec6252d16fc908dbef8703ac59d9247c043445 Mon Sep 17 00:00:00 2001 From: sebres Date: Tue, 10 Jan 2017 22:38:22 +0000 Subject: lowercase on demand, string index tree can search any-case now, clock scan considered utf-8 char length in words by format parsing --- generic/tclClockFmt.c | 17 +++++++---------- generic/tclStrIdxTree.c | 20 ++++++++++---------- generic/tclStrIdxTree.h | 35 +++++++++++++++++++++++++++++++++++ 3 files changed, 52 insertions(+), 20 deletions(-) diff --git a/generic/tclClockFmt.c b/generic/tclClockFmt.c index e66c525..92040d8 100644 --- a/generic/tclClockFmt.c +++ b/generic/tclClockFmt.c @@ -1245,7 +1245,7 @@ ClockGetOrParseScanFormat( fss->scnTok = tok = ckalloc(sizeof(*tok) * fss->scnTokC); memset(tok, 0, sizeof(*(tok))); - for (p = strFmt; p != e; p++) { + for (p = strFmt; p < e;) { switch (*p) { case '%': if (1) { @@ -1265,6 +1265,7 @@ ClockGetOrParseScanFormat( tok->tokWord.start = p; tok->tokWord.end = p+1; AllocTokenInChain(tok, fss->scnTok, fss->scnTokC); + p++; continue; break; case 'E': @@ -1315,6 +1316,8 @@ ClockGetOrParseScanFormat( } /* next token */ AllocTokenInChain(tok, fss->scnTok, fss->scnTokC); + p++; + continue; } break; case ' ': @@ -1325,6 +1328,8 @@ ClockGetOrParseScanFormat( } tok->map = &ScnSpecTokenMap[cp - ScnSpecTokenMapIndex]; AllocTokenInChain(tok, fss->scnTok, fss->scnTokC); + p++; + continue; break; default: word_tok: @@ -1339,12 +1344,11 @@ word_tok: wordTok->map = &ScnWordTokenMap; AllocTokenInChain(tok, fss->scnTok, fss->scnTokC); } - continue; } break; } - continue; + p = TclUtfNext(p); } /* calculate end distance value for each tokens */ @@ -1468,11 +1472,6 @@ ClockScan( yyMeridian = MER24; - /* lower case given string into new object */ - strObj = Tcl_NewStringObj(TclGetString(strObj), strObj->length); - Tcl_IncrRefCount(strObj); - strObj->length = Tcl_UtfToLower(TclGetString(strObj)); - p = TclGetString(strObj); end = p + strObj->length; /* in strict mode - bypass spaces at begin / end only (not between tokens) */ @@ -1726,8 +1725,6 @@ not_match: done: - Tcl_DecrRefCount(strObj); - return ret; } diff --git a/generic/tclStrIdxTree.c b/generic/tclStrIdxTree.c index f078c7a..afb53e5 100644 --- a/generic/tclStrIdxTree.c +++ b/generic/tclStrIdxTree.c @@ -84,7 +84,7 @@ TclStrIdxTreeSearch( { TclStrIdxTree *parent = tree, *prevParent = tree; TclStrIdx *item = tree->firstPtr, *prevItem = NULL; - const char *s = start, *e, *cin, *preve; + const char *s = start, *f, *cin, *cinf, *prevf; int offs = 0; if (item == NULL) { @@ -94,23 +94,23 @@ TclStrIdxTreeSearch( /* search in tree */ do { cin = TclGetString(item->key) + offs; - e = TclUtfFindEqual(s, end, cin, cin + item->length); + f = TclUtfFindEqualNCInLwr(s, end, cin, cin + item->length, &cinf); /* if something was found */ - if (e > s) { + if (f > s) { /* if whole string was found */ - if (e >= end) { - start = e; + if (f >= end) { + start = f; goto done; }; /* set new offset and shift start string */ - offs += (e - s); - s = e; + offs += cinf - cin; + s = f; /* if match item, go deeper as long as possible */ if (offs >= item->length && item->childTree.firstPtr) { /* save previuosly found item (if not ambigous) for * possible fallback (few greedy match) */ if (item->value != -1) { - preve = e; + prevf = f; prevItem = item; prevParent = parent; } @@ -119,7 +119,7 @@ TclStrIdxTreeSearch( continue; } /* no children - return this item and current chars found */ - start = e; + start = f; goto done; } @@ -131,7 +131,7 @@ TclStrIdxTreeSearch( if (prevItem != NULL) { item = prevItem; parent = prevParent; - start = preve; + start = prevf; } done: diff --git a/generic/tclStrIdxTree.h b/generic/tclStrIdxTree.h index e80d3db..d2d6f0b 100644 --- a/generic/tclStrIdxTree.h +++ b/generic/tclStrIdxTree.h @@ -89,6 +89,41 @@ TclUtfFindEqualNC( return ret; } +inline const char * +TclUtfFindEqualNCInLwr( + register const char *cs, /* UTF string (in anycase) to find in cin. */ + register const char *cse, /* End of cs */ + register const char *cin, /* UTF string (in lowercase) will be browsed. */ + register const char *cine, /* End of cin */ + const char **cinfnd) /* Return position in cin */ +{ + register const char *ret = cs; + Tcl_UniChar ch1, ch2; + do { + cs += TclUtfToUniChar(cs, &ch1); + cin += TclUtfToUniChar(cin, &ch2); + if (ch1 != ch2) { + ch1 = Tcl_UniCharToLower(ch1); + if (ch1 != ch2) break; + } + *cinfnd = cin; + } while ((ret = cs) < cse && cin < cine); + return ret; +} + +inline char * +TclUtfNext( + register const char *src) /* The current location in the string. */ +{ + if (((unsigned char) *(src)) < 0xC0) { + return ++src; + } else { + Tcl_UniChar ch; + return src + TclUtfToUniChar(src, &ch); + } +} + + /* * Primitives to safe set, reset and free references. */ -- cgit v0.12 From 95b63f4c39cdae6600e1b364f58d663c870b1012 Mon Sep 17 00:00:00 2001 From: sebres Date: Tue, 10 Jan 2017 22:38:56 +0000 Subject: locale months scan switched to from list seek to index tree; bug fixing --- generic/tclClockFmt.c | 23 +++++++++++++---------- generic/tclDate.h | 4 ++-- generic/tclStrIdxTree.h | 2 +- tests/clock.test | 24 ++++++++++++++++++++++++ 4 files changed, 40 insertions(+), 13 deletions(-) diff --git a/generic/tclClockFmt.c b/generic/tclClockFmt.c index 92040d8..478941b 100644 --- a/generic/tclClockFmt.c +++ b/generic/tclClockFmt.c @@ -682,6 +682,7 @@ ClockMCGetMultiListIdxTree( } ClockMCSetIdx(opts, mcKey, objPtr); + objPtr = NULL; }; done: @@ -788,22 +789,24 @@ ClockScnToken_Month_Proc(ClockFmtScnCmdArgs *opts, return TCL_OK; */ + static int monthsKeys[] = {MCLIT_MONTHS_FULL, MCLIT_MONTHS_ABBREV, 0}; + int ret, val; int minLen, maxLen; + TclStrIdxTree *idxTree; DetermineGreedySearchLen(opts, info, tok, &minLen, &maxLen); - ret = LocaleListSearch(opts, info, MCLIT_MONTHS_FULL, &val, - minLen, maxLen); + /* get or create tree in msgcat dict */ + + idxTree = ClockMCGetMultiListIdxTree(opts, MCLIT_MONTHS_COMB, monthsKeys); + if (idxTree == NULL) { + return TCL_ERROR; + } + + ret = ClockStrIdxTreeSearch(opts, info, idxTree, &val, minLen, maxLen); if (ret != TCL_OK) { - /* if not found */ - if (ret == TCL_RETURN) { - ret = LocaleListSearch(opts, info, MCLIT_MONTHS_ABBREV, &val, - minLen, maxLen); - } - if (ret != TCL_OK) { - return ret; - } + return ret; } yyMonth = val + 1; diff --git a/generic/tclDate.h b/generic/tclDate.h index 2728dd3..85bcd35 100644 --- a/generic/tclDate.h +++ b/generic/tclDate.h @@ -104,7 +104,7 @@ typedef enum ClockLiteral { typedef enum ClockMsgCtLiteral { MCLIT__NIL, /* placeholder */ - MCLIT_MONTHS_FULL, MCLIT_MONTHS_ABBREV, + MCLIT_MONTHS_FULL, MCLIT_MONTHS_ABBREV, MCLIT_MONTHS_COMB, MCLIT_DAYS_OF_WEEK_FULL, MCLIT_DAYS_OF_WEEK_ABBREV, MCLIT_AM, MCLIT_PM, MCLIT_BCE, MCLIT_CE, @@ -116,7 +116,7 @@ typedef enum ClockMsgCtLiteral { #define CLOCK_LOCALE_LITERAL_ARRAY(litarr, pref) static const char *const litarr[] = { \ pref "", \ - pref "MONTHS_FULL", pref "MONTHS_ABBREV", \ + pref "MONTHS_FULL", pref "MONTHS_ABBREV", pref "MONTHS_COMB", \ pref "DAYS_OF_WEEK_FULL", pref "DAYS_OF_WEEK_ABBREV", \ pref "AM", pref "PM", \ pref "BCE", pref "CE", \ diff --git a/generic/tclStrIdxTree.h b/generic/tclStrIdxTree.h index d2d6f0b..934e28f 100644 --- a/generic/tclStrIdxTree.h +++ b/generic/tclStrIdxTree.h @@ -111,7 +111,7 @@ TclUtfFindEqualNCInLwr( return ret; } -inline char * +inline const char * TclUtfNext( register const char *src) /* The current location in the string. */ { diff --git a/tests/clock.test b/tests/clock.test index e96dec6..1d02f39 100644 --- a/tests/clock.test +++ b/tests/clock.test @@ -18564,6 +18564,30 @@ test clock-6.11 {input of seconds - two values} { clock scan {1 2} -format {%s %s} -gmt true } 2 +test clock-6.12 {input of unambiguous short locale token (%b)} { + list [clock scan "12 Ja 2001" -format "%d %b %Y" -locale en_US_roman -gmt 1] \ + [clock scan "12 Au 2001" -format "%d %b %Y" -locale en_US_roman -gmt 1] +} {979257600 997574400} +test clock-6.13 {input of lowercase locale token (%b)} { + list [clock scan "12 ja 2001" -format "%d %b %Y" -locale en_US_roman -gmt 1] \ + [clock scan "12 au 2001" -format "%d %b %Y" -locale en_US_roman -gmt 1] +} {979257600 997574400} +test clock-6.14 {input of uppercase locale token (%b)} { + list [clock scan "12 JA 2001" -format "%d %b %Y" -locale en_US_roman -gmt 1] \ + [clock scan "12 AU 2001" -format "%d %b %Y" -locale en_US_roman -gmt 1] +} {979257600 997574400} +test clock-6.15 {input of ambiguous short locale token (%b)} { + list [catch { + clock scan "12 J 2001" -format "%d %b %Y" -locale en_US_roman -gmt 1 + } result] $result $errorCode +} {1 {input string does not match supplied format} {CLOCK badInputString}} +test clock-6.16 {input of ambiguous short locale token (%b)} { + list [catch { + clock scan "12 Ju 2001" -format "%d %b %Y" -locale en_US_roman -gmt 1 + } result] $result $errorCode +} {1 {input string does not match supplied format} {CLOCK badInputString}} + + test clock-7.1 {Julian Day} { clock scan 0 -format %J -gmt true } -210866803200 -- cgit v0.12 From 0f7c885e8c08fc7013f73284498823585b59b2b3 Mon Sep 17 00:00:00 2001 From: sebres Date: Tue, 10 Jan 2017 22:39:45 +0000 Subject: other locale scan token switched from list seek to index tree + list search case insensitive now --- generic/tclClockFmt.c | 44 +++++++++++++++++++++++++++----------------- generic/tclDate.h | 8 ++++---- 2 files changed, 31 insertions(+), 21 deletions(-) diff --git a/generic/tclClockFmt.c b/generic/tclClockFmt.c index 478941b..999f191 100644 --- a/generic/tclClockFmt.c +++ b/generic/tclClockFmt.c @@ -530,20 +530,26 @@ ObjListSearch(ClockFmtScnCmdArgs *opts, int minLen, int maxLen) { int i, l, lf = -1; - const char *s; + const char *s, *f, *sf; /* search in list */ for (i = 0; i < lstc; i++) { s = TclGetString(lstv[i]); l = lstv[i]->length; - if ( l >= minLen && l <= maxLen - && strncasecmp(yyInput, s, l) == 0 + + if ( l >= minLen + && (f = TclUtfFindEqualNC(yyInput, yyInput + maxLen, s, s + l, &sf)) > yyInput ) { + l = f - yyInput; + if (l < minLen) { + continue; + } /* found, try to find longest value (greedy search) */ if (l < maxLen && minLen != maxLen) { lf = i; minLen = l + 1; continue; } + /* max possible - end of search */ *val = i; yyInput += l; break; @@ -818,9 +824,12 @@ static int ClockScnToken_DayOfWeek_Proc(ClockFmtScnCmdArgs *opts, DateInfo *info, ClockScanToken *tok) { + static int dowKeys[] = {MCLIT_DAYS_OF_WEEK_ABBREV, MCLIT_DAYS_OF_WEEK_FULL, 0}; + int ret, val; int minLen, maxLen; char curTok = *tok->tokWord.start; + TclStrIdxTree *idxTree; DetermineGreedySearchLen(opts, info, tok, &minLen, &maxLen); @@ -836,9 +845,13 @@ ClockScnToken_DayOfWeek_Proc(ClockFmtScnCmdArgs *opts, val = *yyInput - '0'; } } else { - int ret = LocaleListSearch(opts, info, (int)tok->map->data, &val, - minLen, maxLen); - if (ret == TCL_ERROR) { + idxTree = ClockMCGetListIdxTree(opts, (int)tok->map->data /* mcKey */); + if (idxTree == NULL) { + return TCL_ERROR; + } + + ret = ClockStrIdxTreeSearch(opts, info, idxTree, &val, minLen, maxLen); + if (ret != TCL_OK) { return ret; } } @@ -847,7 +860,7 @@ ClockScnToken_DayOfWeek_Proc(ClockFmtScnCmdArgs *opts, if (val == 0) { val = 7; } - if (val > 7 && curTok != 'a' && curTok != 'A') { + if (val > 7) { Tcl_SetResult(opts->interp, "day of week is greater than 7", TCL_STATIC); Tcl_SetErrorCode(opts->interp, "CLOCK", "badDayOfWeek", NULL); @@ -863,17 +876,14 @@ ClockScnToken_DayOfWeek_Proc(ClockFmtScnCmdArgs *opts, } /* %a %A */ - ret = LocaleListSearch(opts, info, MCLIT_DAYS_OF_WEEK_FULL, &val, - minLen, maxLen); + idxTree = ClockMCGetMultiListIdxTree(opts, MCLIT_DAYS_OF_WEEK_COMB, dowKeys); + if (idxTree == NULL) { + return TCL_ERROR; + } + + ret = ClockStrIdxTreeSearch(opts, info, idxTree, &val, minLen, maxLen); if (ret != TCL_OK) { - /* if not found */ - if (ret == TCL_RETURN) { - ret = LocaleListSearch(opts, info, MCLIT_DAYS_OF_WEEK_ABBREV, &val, - minLen, maxLen); - } - if (ret != TCL_OK) { - return ret; - } + return ret; } if (val == 0) { diff --git a/generic/tclDate.h b/generic/tclDate.h index 85bcd35..fe38436 100644 --- a/generic/tclDate.h +++ b/generic/tclDate.h @@ -105,8 +105,8 @@ typedef enum ClockLiteral { typedef enum ClockMsgCtLiteral { MCLIT__NIL, /* placeholder */ MCLIT_MONTHS_FULL, MCLIT_MONTHS_ABBREV, MCLIT_MONTHS_COMB, - MCLIT_DAYS_OF_WEEK_FULL, MCLIT_DAYS_OF_WEEK_ABBREV, - MCLIT_AM, MCLIT_PM, + MCLIT_DAYS_OF_WEEK_FULL, MCLIT_DAYS_OF_WEEK_ABBREV, MCLIT_DAYS_OF_WEEK_COMB, + MCLIT_AM, MCLIT_PM, MCLIT_BCE, MCLIT_CE, MCLIT_BCE2, MCLIT_CE2, MCLIT_BCE3, MCLIT_CE3, @@ -117,8 +117,8 @@ typedef enum ClockMsgCtLiteral { #define CLOCK_LOCALE_LITERAL_ARRAY(litarr, pref) static const char *const litarr[] = { \ pref "", \ pref "MONTHS_FULL", pref "MONTHS_ABBREV", pref "MONTHS_COMB", \ - pref "DAYS_OF_WEEK_FULL", pref "DAYS_OF_WEEK_ABBREV", \ - pref "AM", pref "PM", \ + pref "DAYS_OF_WEEK_FULL", pref "DAYS_OF_WEEK_ABBREV", pref "DAYS_OF_WEEK_COMB", \ + pref "AM", pref "PM", \ pref "BCE", pref "CE", \ pref "b.c.e.", pref "c.e.", \ pref "b.c.", pref "a.d.", \ -- cgit v0.12 From 9d7b1b2b0319162c58225a5f443a040be63628f8 Mon Sep 17 00:00:00 2001 From: sebres Date: Tue, 10 Jan 2017 22:40:16 +0000 Subject: min length of %Y token (year with century) is 4, optional tokens possibility (zone), test cases extended --- generic/tclClockFmt.c | 40 ++++++++++++++++++++++++++++++---------- generic/tclDate.h | 1 + tests-perf/clock.perf.tcl | 7 +++++++ tests/clock.test | 12 ++++++++++++ 4 files changed, 50 insertions(+), 10 deletions(-) diff --git a/generic/tclClockFmt.c b/generic/tclClockFmt.c index 999f191..9211481 100644 --- a/generic/tclClockFmt.c +++ b/generic/tclClockFmt.c @@ -1089,7 +1089,7 @@ static ClockScanTokenMap ScnSTokenMap[] = { {CTOKT_DIGIT, CLF_YEAR, 0, 1, 2, TclOffset(DateInfo, date.year), NULL}, /* %Y */ - {CTOKT_DIGIT, CLF_YEAR | CLF_CENTURY, 0, 1, 4, TclOffset(DateInfo, date.year), + {CTOKT_DIGIT, CLF_YEAR | CLF_CENTURY, 0, 4, 4, TclOffset(DateInfo, date.year), NULL}, /* %H %k %I %l */ {CTOKT_DIGIT, CLF_TIME, 0, 1, 2, TclOffset(DateInfo, date.hour), @@ -1116,7 +1116,7 @@ static ClockScanTokenMap ScnSTokenMap[] = { {CTOKT_DIGIT, CLF_ISO8601YEAR | CLF_ISO8601, 0, 2, 2, TclOffset(DateInfo, date.iso8601Year), NULL}, /* %G */ - {CTOKT_DIGIT, CLF_ISO8601YEAR | CLF_ISO8601 | CLF_ISO8601CENTURY, 0, 1, 4, TclOffset(DateInfo, date.iso8601Year), + {CTOKT_DIGIT, CLF_ISO8601YEAR | CLF_ISO8601 | CLF_ISO8601CENTURY, 0, 4, 4, TclOffset(DateInfo, date.iso8601Year), NULL}, /* %V */ {CTOKT_DIGIT, CLF_ISO8601, 0, 1, 2, TclOffset(DateInfo, date.iso8601Week), @@ -1125,7 +1125,7 @@ static ClockScanTokenMap ScnSTokenMap[] = { {CTOKT_PARSER, CLF_ISO8601, 0, 0, 0, 0, ClockScnToken_DayOfWeek_Proc, NULL}, /* %z %Z */ - {CTOKT_PARSER, 0, 0, 0, 0, 0, + {CTOKT_PARSER, CLF_OPTIONAL, 0, 0, 0, 0, ClockScnToken_TimeZone_Proc, NULL}, /* %s */ {CTOKT_DIGIT, CLF_LOCALSEC | CLF_SIGNED, 0, 1, 0xffff, TclOffset(DateInfo, date.localSeconds), @@ -1508,6 +1508,10 @@ ClockScan( } } yyInput = p; + /* end of input string */ + if (p >= end) { + break; + } switch (map->type) { case CTOKT_DIGIT: @@ -1553,6 +1557,10 @@ ClockScan( size = p - yyInput; if (size < map->minSize) { /* missing input -> error */ + if ((map->flags & CLF_OPTIONAL)) { + yyInput = p; + continue; + } goto not_match; } /* string 2 number, put number into info structure by offset */ @@ -1578,6 +1586,10 @@ ClockScan( case TCL_OK: break; case TCL_RETURN: + if ((map->flags & CLF_OPTIONAL)) { + yyInput = p; + continue; + } goto not_match; break; default: @@ -1611,15 +1623,23 @@ ClockScan( break; } } - - /* ignore spaces at end */ - while (p < end && isspace(UCHAR(*p))) { - p++; - } /* check end was reached */ if (p < end) { - /* something after last token - wrong format */ - goto not_match; + /* ignore spaces at end */ + while (p < end && isspace(UCHAR(*p))) { + p++; + } + if (p < end) { + /* something after last token - wrong format */ + goto not_match; + } + } + /* end of string, check only optional tokens at end, otherwise - not match */ + if (tok->map != NULL) { + if ( !(opts->flags & CLF_STRICT) && (tok->map->type == CTOKT_SPACE) + || (tok->map->flags & CLF_OPTIONAL)) { + goto not_match; + } } /* diff --git a/generic/tclDate.h b/generic/tclDate.h index fe38436..64135d3 100644 --- a/generic/tclDate.h +++ b/generic/tclDate.h @@ -30,6 +30,7 @@ #define ONE_YEAR 365 /* days */ +#define CLF_OPTIONAL (1 << 0) /* token is non mandatory */ #define CLF_JULIANDAY (1 << 3) #define CLF_TIME (1 << 4) #define CLF_LOCALSEC (1 << 5) diff --git a/tests-perf/clock.perf.tcl b/tests-perf/clock.perf.tcl index 3c69414..41cc9e1 100644 --- a/tests-perf/clock.perf.tcl +++ b/tests-perf/clock.perf.tcl @@ -150,6 +150,13 @@ proc test-scan {{reptime 1000}} { # Scan : century, lookup table month and day (list scan: entries with position 12 / 31) {clock scan {2016 Dec 31} -format {%C%y %b %Od} -locale en -gmt 1} + # Scan : ISO date-time (CEST) + {clock scan "2009-06-30T18:30:00+02:00" -format "%Y-%m-%dT%H:%M:%S%z"} + {clock scan "2009-06-30T18:30:00 CEST" -format "%Y-%m-%dT%H:%M:%S %z"} + # Scan : ISO date-time (UTC) + {clock scan "2009-06-30T18:30:00Z" -format "%Y-%m-%dT%H:%M:%S%z"} + {clock scan "2009-06-30T18:30:00 UTC" -format "%Y-%m-%dT%H:%M:%S %z"} + # Scan : dynamic format (cacheable) {clock scan "25.11.2015 10:35:55" -format [string trim "%d.%m.%Y %H:%M:%S "] -base 0 -gmt 1} diff --git a/tests/clock.test b/tests/clock.test index 1d02f39..a4641c6 100644 --- a/tests/clock.test +++ b/tests/clock.test @@ -18587,6 +18587,18 @@ test clock-6.16 {input of ambiguous short locale token (%b)} { } result] $result $errorCode } {1 {input string does not match supplied format} {CLOCK badInputString}} +test clock-6.17 {spaces are always optional in non-strict mode (default)} { + list [clock scan "2009-06-30T18:30:00+02:00" -format "%Y-%m-%dT%H:%M:%S %z" -gmt 1] \ + [clock scan "2009-06-30T18:30:00 +02:00" -format "%Y-%m-%dT%H:%M:%S %z" -gmt 1] \ + [clock scan "2009-06-30T18:30:00Z" -format "%Y-%m-%dT%H:%M:%S %z" -timezone CET] \ + [clock scan "2009-06-30T18:30:00 Z" -format "%Y-%m-%dT%H:%M:%S %z" -timezone CET] +} {1246379400 1246379400 1246386600 1246386600} + +test clock-6.18 {zone token (%z) is optional} { + list [clock scan "2009-06-30T18:30:00 -01:00" -format "%Y-%m-%dT%H:%M:%S %z" -gmt 1] \ + [clock scan "2009-06-30T18:30:00" -format "%Y-%m-%dT%H:%M:%S %z" -gmt 1] \ + [clock scan " 2009-06-30T18:30:00 " -format "%Y-%m-%dT%H:%M:%S %z" -gmt 1] \ +} {1246390200 1246386600 1246386600} test clock-7.1 {Julian Day} { clock scan 0 -format %J -gmt true -- cgit v0.12 From 63c8495242fba7a73308cadbe99d5b9baa687aa6 Mon Sep 17 00:00:00 2001 From: sebres Date: Tue, 10 Jan 2017 22:41:18 +0000 Subject: [temp-commit]: format almost ready (missing some tokens) --- generic/tclClock.c | 28 +- generic/tclClockFmt.c | 711 +++++++++++++++++++++++++++++++++++++++++--------- generic/tclDate.h | 75 ++++-- library/clock.tcl | 2 +- library/init.tcl | 2 +- tests/clock.test | 5 + 6 files changed, 651 insertions(+), 172 deletions(-) diff --git a/generic/tclClock.c b/generic/tclClock.c index e52b2e7..935a347 100644 --- a/generic/tclClock.c +++ b/generic/tclClock.c @@ -129,6 +129,9 @@ static int ClockParseformatargsObjCmd( static int ClockSecondsObjCmd( ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *const objv[]); +static int ClockFormatObjCmd( + ClientData clientData, Tcl_Interp *interp, + int objc, Tcl_Obj *const objv[]); static int ClockScanObjCmd( ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *const objv[]); @@ -164,6 +167,7 @@ static const struct ClockCommand clockCommands[] = { { "microseconds", ClockMicrosecondsObjCmd }, { "milliseconds", ClockMillisecondsObjCmd }, { "seconds", ClockSecondsObjCmd }, + { "format", ClockFormatObjCmd }, { "scan", ClockScanObjCmd }, { "configure", ClockConfigureObjCmd }, { "Oldscan", TclClockOldscanObjCmd }, @@ -2944,8 +2948,7 @@ ClockFormatObjCmd( int ret; ClockFmtScnCmdArgs opts; /* Format, locale, timezone and base */ Tcl_WideInt clockVal; /* Time, expressed in seconds from the Epoch */ - DateInfo yy; /* Common structure used for parsing */ - DateInfo *info = &yy; + DateFormat dateFmt; /* Common structure used for formatting */ if ((objc & 1) == 1) { Tcl_WrongNumArgs(interp, 1, objv, "string " @@ -2972,9 +2975,7 @@ ClockFormatObjCmd( return TCL_ERROR; } - - ClockInitDateInfo(info); - yydate.tzName = NULL; + memset(&dateFmt, 0, sizeof(dateFmt)); /* * Extract year, month and day from the base time for the parser to use as @@ -2984,16 +2985,16 @@ ClockFormatObjCmd( /* check base fields already cached (by TZ, last-second cache) */ if ( dataPtr->lastBase.timezoneObj == opts.timezoneObj && dataPtr->lastBase.Date.seconds == clockVal) { - memcpy(&yydate, &dataPtr->lastBase.Date, ClockCacheableDateFieldsSize); + memcpy(&dateFmt.date, &dataPtr->lastBase.Date, ClockCacheableDateFieldsSize); } else { /* extact fields from base */ - yydate.seconds = clockVal; - if (ClockGetDateFields(clientData, interp, &yydate, opts.timezoneObj, + dateFmt.date.seconds = clockVal; + if (ClockGetDateFields(clientData, interp, &dateFmt.date, opts.timezoneObj, GREGORIAN_CHANGE_DATE) != TCL_OK) { goto done; } /* cache last base */ - memcpy(&dataPtr->lastBase.Date, &yydate, ClockCacheableDateFieldsSize); + memcpy(&dataPtr->lastBase.Date, &dateFmt.date, ClockCacheableDateFieldsSize); Tcl_SetObjRef(dataPtr->lastBase.timezoneObj, opts.timezoneObj); } @@ -3004,11 +3005,11 @@ ClockFormatObjCmd( /* Use compiled version of Format - */ - ret = ClockFormat(clientData, interp, info, &opts); + ret = ClockFormat(&dateFmt, &opts); done: - Tcl_UnsetObjRef(yydate.tzName); + Tcl_UnsetObjRef(dateFmt.date.tzName); if (ret != TCL_OK) { return ret; @@ -3072,8 +3073,7 @@ ClockScanObjCmd( } ClockInitDateInfo(info); - yydate.tzName = NULL; - + /* * Extract year, month and day from the base time for the parser to use as * defaults @@ -3114,7 +3114,7 @@ ClockScanObjCmd( else { /* Use compiled version of Scan - */ - ret = ClockScan(clientData, interp, info, objv[1], &opts); + ret = ClockScan(info, objv[1], &opts); } if (ret != TCL_OK) { diff --git a/generic/tclClockFmt.c b/generic/tclClockFmt.c index 9211481..b46b7bf 100644 --- a/generic/tclClockFmt.c +++ b/generic/tclClockFmt.c @@ -490,6 +490,74 @@ Tcl_GetClockFrmScnFromObj( return fss; } +MODULE_SCOPE Tcl_Obj * +ClockLocalizeFormat( + ClockFmtScnCmdArgs *opts) +{ + ClockClientData *dataPtr = opts->clientData; + Tcl_Obj *valObj = NULL, *keyObj; + + keyObj = ClockFrmObjGetLocFmtKey(opts->interp, opts->formatObj); + + /* special case - format object is not localizable */ + if (keyObj == opts->formatObj) { + return opts->formatObj; + } + + if (opts->mcDictObj == NULL) { + ClockMCDict(opts); + if (opts->mcDictObj == NULL) + return NULL; + } + + /* try to find in cache within locale mc-catalog */ + if (Tcl_DictObjGet(NULL, opts->mcDictObj, + keyObj, &valObj) != TCL_OK) { + return NULL; + } + + /* call LocalizeFormat locale format fmtkey */ + if (valObj == NULL) { + Tcl_Obj *callargs[4]; + callargs[0] = dataPtr->literals[LIT_LOCALIZE_FORMAT]; + callargs[1] = opts->localeObj; + callargs[2] = opts->formatObj; + callargs[3] = keyObj; + Tcl_IncrRefCount(keyObj); + if (Tcl_EvalObjv(opts->interp, 4, callargs, 0) != TCL_OK + ) { + goto clean; + } + + valObj = Tcl_GetObjResult(opts->interp); + + /* cache it inside mc-dictionary (this incr. ref count of keyObj/valObj) */ + if (Tcl_DictObjPut(opts->interp, opts->mcDictObj, + keyObj, valObj) != TCL_OK + ) { + valObj = NULL; + goto clean; + } + + /* check special case - format object is not localizable */ + if (valObj == opts->formatObj) { + /* mark it as unlocalizable, by setting self as key (without refcount incr) */ + if (opts->formatObj->typePtr == &ClockFmtObjType) { + Tcl_UnsetObjRef(ObjLocFmtKey(opts->formatObj)); + ObjLocFmtKey(opts->formatObj) = opts->formatObj; + } + } +clean: + + Tcl_UnsetObjRef(keyObj); + if (valObj) { + Tcl_ResetResult(opts->interp); + } + } + + return (opts->formatObj = valObj); +} + /* * DetermineGreedySearchLen -- * @@ -1131,7 +1199,7 @@ static ClockScanTokenMap ScnSTokenMap[] = { {CTOKT_DIGIT, CLF_LOCALSEC | CLF_SIGNED, 0, 1, 0xffff, TclOffset(DateInfo, date.localSeconds), NULL}, }; -static const char *ScnSTokenWrapMapIndex[2] = { +static const char *ScnSTokenMapAliasIndex[2] = { "eNBhkIlPAuwZ", "dmbbHHHpaaaz" }; @@ -1146,7 +1214,7 @@ static ClockScanTokenMap ScnETokenMap[] = { {CTOKT_PARSER, 0, 0, 0, 0, 0, /* currently no capture, parse only token */ ClockScnToken_LocaleListMatcher_Proc, (void *)MCLIT_LOCALE_NUMERALS}, }; -static const char *ScnETokenWrapMapIndex[2] = { +static const char *ScnETokenMapAliasIndex[2] = { "", "" }; @@ -1176,7 +1244,7 @@ static ClockScanTokenMap ScnOTokenMap[] = { {CTOKT_PARSER, CLF_ISO8601, 0, 0, 0, 0, ClockScnToken_DayOfWeek_Proc, (void *)MCLIT_LOCALE_NUMERALS}, }; -static const char *ScnOTokenWrapMapIndex[2] = { +static const char *ScnOTokenMapAliasIndex[2] = { "ekIlw", "dHHHu" }; @@ -1194,6 +1262,29 @@ static ClockScanTokenMap ScnWordTokenMap = { }; +inline unsigned int +EstimateTokenCount( + register const char *fmt, + register const char *end) +{ + register const char *p = fmt; + unsigned int tokcnt; + /* estimate token count by % char and format length */ + tokcnt = 0; + while (p <= end) { + if (*p++ == '%') tokcnt++; + } + p = fmt + tokcnt * 2; + if (p < end) { + if ((unsigned int)(end - p) < tokcnt) { + tokcnt += (end - p); + } else { + tokcnt += tokcnt; + } + } + return ++tokcnt; +} + #define AllocTokenInChain(tok, chain, tokCnt) \ if (++(tok) >= (chain) + (tokCnt)) { \ (char *)(chain) = ckrealloc((char *)(chain), \ @@ -1215,56 +1306,32 @@ ClockGetOrParseScanFormat( ClockFmtScnStorage *fss; ClockScanToken *tok; - if (formatObj->typePtr != &ClockFmtObjType) { - if (ClockFmtObj_SetFromAny(interp, formatObj) != TCL_OK) { - return NULL; - } - } - - fss = ObjClockFmtScn(formatObj); - + fss = Tcl_GetClockFrmScnFromObj(interp, formatObj); if (fss == NULL) { - fss = FindOrCreateFmtScnStorage(interp, formatObj); - if (fss == NULL) { - return NULL; - } + return NULL; } /* if first time scanning - tokenize format */ if (fss->scnTok == NULL) { - const char *strFmt; register const char *p, *e, *cp; - e = strFmt = HashEntry4FmtScn(fss)->key.string; - e += strlen(strFmt); + e = p = HashEntry4FmtScn(fss)->key.string; + e += strlen(p); /* estimate token count by % char and format length */ - fss->scnTokC = 0; - p = strFmt; - while (p != e) { - if (*p++ == '%') fss->scnTokC++; - } - p = strFmt + fss->scnTokC * 2; - if (p < e) { - if ((unsigned int)(e - p) < fss->scnTokC) { - fss->scnTokC += (e - p); - } else { - fss->scnTokC += fss->scnTokC; - } - } - fss->scnTokC++; + fss->scnTokC = EstimateTokenCount(p, e); Tcl_MutexLock(&ClockFmtMutex); fss->scnTok = tok = ckalloc(sizeof(*tok) * fss->scnTokC); memset(tok, 0, sizeof(*(tok))); - for (p = strFmt; p < e;) { + while (p < e) { switch (*p) { case '%': if (1) { ClockScanTokenMap * scnMap = ScnSTokenMap; const char *mapIndex = ScnSTokenMapIndex, - **wrapIndex = ScnSTokenWrapMapIndex; + **aliasIndex = ScnSTokenMapAliasIndex; if (p+1 >= e) { goto word_tok; } @@ -1284,13 +1351,13 @@ ClockGetOrParseScanFormat( case 'E': scnMap = ScnETokenMap, mapIndex = ScnETokenMapIndex, - wrapIndex = ScnETokenWrapMapIndex; + aliasIndex = ScnETokenMapAliasIndex; p++; break; case 'O': scnMap = ScnOTokenMap, mapIndex = ScnOTokenMapIndex, - wrapIndex = ScnOTokenWrapMapIndex; + aliasIndex = ScnOTokenMapAliasIndex; p++; break; } @@ -1298,17 +1365,17 @@ ClockGetOrParseScanFormat( cp = strchr(mapIndex, *p); if (!cp || *cp == '\0') { /* search wrapper index (multiple chars for same token) */ - cp = strchr(wrapIndex[0], *p); + cp = strchr(aliasIndex[0], *p); if (!cp || *cp == '\0') { - p--; + p--; if (scnMap != ScnSTokenMap) p--; goto word_tok; } - cp = strchr(mapIndex, wrapIndex[1][cp - wrapIndex[0]]); + cp = strchr(mapIndex, aliasIndex[1][cp - aliasIndex[0]]); if (!cp || *cp == '\0') { /* unexpected, but ... */ #ifdef DEBUG Tcl_Panic("token \"%c\" has no map in wrapper resolver", *p); #endif - p--; + p--; if (scnMap != ScnSTokenMap) p--; goto word_tok; } } @@ -1351,17 +1418,16 @@ word_tok: if (tok > fss->scnTok && (tok-1)->map == &ScnWordTokenMap) { wordTok = tok-1; } - wordTok->tokWord.end = p+1; if (wordTok == tok) { wordTok->tokWord.start = p; wordTok->map = &ScnWordTokenMap; AllocTokenInChain(tok, fss->scnTok, fss->scnTokC); } + p = TclUtfNext(p); + wordTok->tokWord.end = p; } break; } - - p = TclUtfNext(p); } /* calculate end distance value for each tokens */ @@ -1386,86 +1452,16 @@ done: return fss->scnTok; } -MODULE_SCOPE Tcl_Obj * -ClockLocalizeFormat( - ClockFmtScnCmdArgs *opts) -{ - ClockClientData *dataPtr = opts->clientData; - Tcl_Obj *valObj = NULL, *keyObj; - - keyObj = ClockFrmObjGetLocFmtKey(opts->interp, opts->formatObj); - - /* special case - format object is not localizable */ - if (keyObj == opts->formatObj) { - return opts->formatObj; - } - - if (opts->mcDictObj == NULL) { - ClockMCDict(opts); - if (opts->mcDictObj == NULL) - return NULL; - } - - /* try to find in cache within locale mc-catalog */ - if (Tcl_DictObjGet(NULL, opts->mcDictObj, - keyObj, &valObj) != TCL_OK) { - return NULL; - } - - /* call LocalizeFormat locale format fmtkey */ - if (valObj == NULL) { - Tcl_Obj *callargs[4]; - callargs[0] = dataPtr->literals[LIT_LOCALIZE_FORMAT]; - callargs[1] = opts->localeObj; - callargs[2] = opts->formatObj; - callargs[3] = keyObj; - Tcl_IncrRefCount(keyObj); - if (Tcl_EvalObjv(opts->interp, 4, callargs, 0) != TCL_OK - ) { - goto clean; - } - - valObj = Tcl_GetObjResult(opts->interp); - - /* cache it inside mc-dictionary (this incr. ref count of keyObj/valObj) */ - if (Tcl_DictObjPut(opts->interp, opts->mcDictObj, - keyObj, valObj) != TCL_OK - ) { - valObj = NULL; - goto clean; - } - - /* check special case - format object is not localizable */ - if (valObj == opts->formatObj) { - /* mark it as unlocalizable, by setting self as key (without refcount incr) */ - if (opts->formatObj->typePtr == &ClockFmtObjType) { - Tcl_UnsetObjRef(ObjLocFmtKey(opts->formatObj)); - ObjLocFmtKey(opts->formatObj) = opts->formatObj; - } - } -clean: - - Tcl_UnsetObjRef(keyObj); - if (valObj) { - Tcl_ResetResult(opts->interp); - } - } - - return (opts->formatObj = valObj); -} - /* *---------------------------------------------------------------------- */ int ClockScan( - ClientData clientData, /* Client data containing literal pool */ - Tcl_Interp *interp, /* Tcl interpreter */ register DateInfo *info, /* Date fields used for parsing & converting */ Tcl_Obj *strObj, /* String containing the time to scan */ ClockFmtScnCmdArgs *opts) /* Command options */ { - ClockClientData *dataPtr = clientData; + ClockClientData *dataPtr = opts->clientData; ClockScanToken *tok; ClockScanTokenMap *map; register const char *p, *x, *end; @@ -1477,7 +1473,8 @@ ClockScan( return TCL_ERROR; } - if ((tok = ClockGetOrParseScanFormat(interp, opts->formatObj)) == NULL) { + if ((tok = ClockGetOrParseScanFormat(opts->interp, + opts->formatObj)) == NULL) { return TCL_ERROR; } @@ -1635,11 +1632,14 @@ ClockScan( } } /* end of string, check only optional tokens at end, otherwise - not match */ - if (tok->map != NULL) { - if ( !(opts->flags & CLF_STRICT) && (tok->map->type == CTOKT_SPACE) - || (tok->map->flags & CLF_OPTIONAL)) { + while (tok->map != NULL) { + if (!(opts->flags & CLF_STRICT) && (tok->map->type == CTOKT_SPACE)) { + tok++; + } + if (tok->map != NULL && !(tok->map->flags & CLF_OPTIONAL)) { goto not_match; } + tok++; } /* @@ -1745,33 +1745,377 @@ ClockScan( overflow: - Tcl_SetResult(interp, "requested date too large to represent", + Tcl_SetResult(opts->interp, "requested date too large to represent", TCL_STATIC); - Tcl_SetErrorCode(interp, "CLOCK", "dateTooLarge", NULL); + Tcl_SetErrorCode(opts->interp, "CLOCK", "dateTooLarge", NULL); goto done; not_match: - Tcl_SetResult(interp, "input string does not match supplied format", + Tcl_SetResult(opts->interp, "input string does not match supplied format", TCL_STATIC); - Tcl_SetErrorCode(interp, "CLOCK", "badInputString", NULL); + Tcl_SetErrorCode(opts->interp, "CLOCK", "badInputString", NULL); done: return ret; } + + +inline int +FrmResultAllocate( + register DateFormat *dateFmt, + int len) +{ + int needed = dateFmt->output + len - dateFmt->resEnd; + if (needed >= 0) { /* >= 0 - regards NTS zero */ + int newsize = dateFmt->resEnd - dateFmt->resMem + + needed + MIN_FMT_RESULT_BLOCK_ALLOC; + char *newRes = ckrealloc(dateFmt->resMem, newsize); + if (newRes == NULL) { + return TCL_ERROR; + } + dateFmt->output = newRes + (dateFmt->output - dateFmt->resMem); + dateFmt->resMem = newRes; + dateFmt->resEnd = newRes + newsize; + } + return TCL_OK; +} + +static int +ClockFmtToken_HourAMPM_Proc( + ClockFmtScnCmdArgs *opts, + DateFormat *dateFmt, + ClockFormatToken *tok, + int *val) +{ + *val = ( ( ( *val % 86400 ) + 86400 - 3600 ) / 3600 ) % 12 + 1; + return TCL_OK; +} + +static int +ClockFmtToken_AMPM_Proc( + ClockFmtScnCmdArgs *opts, + DateFormat *dateFmt, + ClockFormatToken *tok, + int *val) +{ + Tcl_Obj *mcObj; + const char *s; + int len; + + if ((*val % 84600) < (84600 / 2)) { + mcObj = ClockMCGet(opts, MCLIT_AM); + } else { + mcObj = ClockMCGet(opts, MCLIT_PM); + } + if (mcObj == NULL) { + return TCL_ERROR; + } + s = TclGetString(mcObj); len = mcObj->length; + if (FrmResultAllocate(dateFmt, len) != TCL_OK) { return TCL_ERROR; }; + memcpy(dateFmt->output, s, len + 1); + if (*tok->tokWord.start == 'p') { + len = Tcl_UtfToUpper(dateFmt->output); + } + dateFmt->output += len; + *dateFmt->output = '\0'; + + return TCL_OK; +} + +static const char *FmtSTokenMapIndex = + "demNbByYCHMSIklpaAugGjJsnt"; +static ClockFormatTokenMap FmtSTokenMap[] = { + /* %d */ + {CFMTT_INT, "%02d", 0, 0, 0, TclOffset(DateFormat, date.dayOfMonth), NULL}, + /* %e */ + {CFMTT_INT, "%2d", 0, 0, 0, TclOffset(DateFormat, date.dayOfMonth), NULL}, + /* %m */ + {CFMTT_INT, "%02d", 0, 0, 0, TclOffset(DateFormat, date.month), NULL}, + /* %N */ + {CFMTT_INT, "%2d", 0, 0, 0, TclOffset(DateFormat, date.month), NULL}, + /* %b %h */ + {CFMTT_INT, NULL, CLFMT_LOCALE_INDX | CLFMT_DECR, 0, 12, TclOffset(DateFormat, date.month), + NULL, (void *)MCLIT_MONTHS_ABBREV}, + /* %B */ + {CFMTT_INT, NULL, CLFMT_LOCALE_INDX | CLFMT_DECR, 0, 12, TclOffset(DateFormat, date.month), + NULL, (void *)MCLIT_MONTHS_FULL}, + /* %y */ + {CFMTT_INT, "%02d", 0, 0, 100, TclOffset(DateFormat, date.year), NULL}, + /* %Y */ + {CFMTT_INT, "%04d", 0, 0, 0, TclOffset(DateFormat, date.year), NULL}, + /* %C */ + {CFMTT_INT, "%02d", 0, 100, 0, TclOffset(DateFormat, date.year), NULL}, + /* %H */ + {CFMTT_INT, "%02d", 0, 3600, 24, TclOffset(DateFormat, date.localSeconds), NULL}, + /* %M */ + {CFMTT_INT, "%02d", 0, 60, 60, TclOffset(DateFormat, date.localSeconds), NULL}, + /* %S */ + {CFMTT_INT, "%02d", 0, 0, 60, TclOffset(DateFormat, date.localSeconds), NULL}, + /* %I */ + {CFMTT_INT, "%02d", CLFMT_CALC, 0, 0, TclOffset(DateFormat, date.localSeconds), + ClockFmtToken_HourAMPM_Proc, NULL}, + /* %k */ + {CFMTT_INT, "%2d", 0, 3600, 24, TclOffset(DateFormat, date.localSeconds), NULL}, + /* %l */ + {CFMTT_INT, "%2d", CLFMT_CALC, 0, 0, TclOffset(DateFormat, date.localSeconds), + ClockFmtToken_HourAMPM_Proc, NULL}, + /* %p %P */ + {CFMTT_INT, "%02d", 0, 0, 0, TclOffset(DateFormat, date.localSeconds), + ClockFmtToken_AMPM_Proc, NULL}, + /* %a */ + {CFMTT_INT, NULL, CLFMT_LOCALE_INDX, 0, 7, TclOffset(DateFormat, date.dayOfWeek), + NULL, (void *)MCLIT_DAYS_OF_WEEK_ABBREV}, + /* %A */ + {CFMTT_INT, NULL, CLFMT_LOCALE_INDX, 0, 7, TclOffset(DateFormat, date.dayOfWeek), + NULL, (void *)MCLIT_DAYS_OF_WEEK_FULL}, + /* %u */ + {CFMTT_INT, "%1d", 0, 0, 0, TclOffset(DateFormat, date.dayOfWeek), NULL}, + /* %g */ + {CFMTT_INT, "%02d", 0, 0, 100, TclOffset(DateFormat, date.iso8601Year), NULL}, + /* %G */ + {CFMTT_INT, "%04d", 0, 0, 0, TclOffset(DateFormat, date.iso8601Year), NULL}, + /* %j */ + {CFMTT_INT, "%03d", 0, 0, 0, TclOffset(DateFormat, date.dayOfYear), NULL}, + /* %J */ + {CFMTT_INT, "%07d", 0, 0, 0, TclOffset(DateFormat, date.julianDay), NULL}, + /* %s */ + {CFMTT_WIDE, "%ld", 0, 0, 0, TclOffset(DateFormat, date.seconds), NULL}, + /* %n */ + {CFMTT_CHAR, "\n", 0, 0, 0, 0, NULL}, + /* %t */ + {CFMTT_CHAR, "\t", 0, 0, 0, 0, NULL}, + +#if 0 + /* %H %k %I %l */ + {CFMTT_INT, CLF_TIME, 1, 2, TclOffset(DateFormat, date.hour), + NULL}, + /* %M */ + {CFMTT_INT, CLF_TIME, 1, 2, TclOffset(DateFormat, date.minutes), + NULL}, + /* %S */ + {CFMTT_INT, CLF_TIME, 1, 2, TclOffset(DateFormat, date.secondOfDay), + NULL}, + /* %p %P */ + {CTOKT_PARSER, CLF_ISO8601, 0, 0, 0, + ClockFmtToken_amPmInd_Proc, NULL}, + /* %J */ + {CFMTT_INT, CLF_JULIANDAY, 1, 0xffff, TclOffset(DateFormat, date.julianDay), + NULL}, + /* %j */ + {CFMTT_INT, CLF_DAYOFYEAR, 1, 3, TclOffset(DateFormat, date.dayOfYear), + NULL}, + /* %g */ + {CFMTT_INT, CLF_ISO8601YEAR | CLF_ISO8601, 2, 2, TclOffset(DateFormat, date.iso8601Year), + NULL}, + /* %G */ + {CFMTT_INT, CLF_ISO8601YEAR | CLF_ISO8601 | CLF_ISO8601CENTURY, 4, 4, TclOffset(DateFormat, date.iso8601Year), + NULL}, + /* %V */ + {CFMTT_INT, CLF_ISO8601, 1, 2, TclOffset(DateFormat, date.iso8601Week), + NULL}, + /* %a %A %u %w */ + {CTOKT_PARSER, CLF_ISO8601, 0, 0, 0, + ClockFmtToken_DayOfWeek_Proc, NULL}, + /* %z %Z */ + {CTOKT_PARSER, CLF_OPTIONAL, 0, 0, 0, + ClockFmtToken_TimeZone_Proc, NULL}, + /* %s */ + {CFMTT_INT, CLF_LOCALSEC | CLF_SIGNED, 0, 1, 0xffff, TclOffset(DateFormat, date.localSeconds), + NULL}, +#endif +}; +static const char *FmtSTokenMapAliasIndex[2] = { + "hP", + "bp" +}; + +static const char *FmtETokenMapIndex = +"";// "Ey"; +static ClockFormatTokenMap FmtETokenMap[] = { + {CFMTT_INT, "%02d", 0, 0, 0, 0, NULL}, +#if 0 + /* %EE */ + {CTOKT_PARSER, 0, 0, 0, 0, TclOffset(DateFormat, date.year), + ClockFmtToken_LocaleERA_Proc, (void *)MCLIT_LOCALE_NUMERALS}, + /* %Ey */ + {CTOKT_PARSER, 0, 0, 0, 0, 0, /* currently no capture, parse only token */ + ClockFmtToken_LocaleListMatcher_Proc, (void *)MCLIT_LOCALE_NUMERALS}, +#endif +}; +static const char *FmtETokenMapAliasIndex[2] = { + "", + "" +}; + +static const char *FmtOTokenMapIndex = +"";// "dmyHMSu"; +static ClockFormatTokenMap FmtOTokenMap[] = { + {CFMTT_INT, "%02d", 0, 0, 0, 0, NULL}, +#if 0 + /* %Od %Oe */ + {CTOKT_PARSER, CLF_DAYOFMONTH, 0, 0, 0, TclOffset(DateFormat, date.dayOfMonth), + ClockFmtToken_LocaleListMatcher_Proc, (void *)MCLIT_LOCALE_NUMERALS}, + /* %Om */ + {CTOKT_PARSER, CLF_MONTH, 0, 0, 0, TclOffset(DateFormat, date.month), + ClockFmtToken_LocaleListMatcher_Proc, (void *)MCLIT_LOCALE_NUMERALS}, + /* %Oy */ + {CTOKT_PARSER, CLF_YEAR, 0, 0, 0, TclOffset(DateFormat, date.year), + ClockFmtToken_LocaleListMatcher_Proc, (void *)MCLIT_LOCALE_NUMERALS}, + /* %OH %Ok %OI %Ol */ + {CTOKT_PARSER, CLF_TIME, 0, 0, 0, TclOffset(DateFormat, date.hour), + ClockFmtToken_LocaleListMatcher_Proc, (void *)MCLIT_LOCALE_NUMERALS}, + /* %OM */ + {CTOKT_PARSER, CLF_TIME, 0, 0, 0, TclOffset(DateFormat, date.minutes), + ClockFmtToken_LocaleListMatcher_Proc, (void *)MCLIT_LOCALE_NUMERALS}, + /* %OS */ + {CTOKT_PARSER, CLF_TIME, 0, 0, 0, TclOffset(DateFormat, date.secondOfDay), + ClockFmtToken_LocaleListMatcher_Proc, (void *)MCLIT_LOCALE_NUMERALS}, + /* %Ou Ow */ + {CTOKT_PARSER, CLF_ISO8601, 0, 0, 0, 0, + ClockFmtToken_DayOfWeek_Proc, (void *)MCLIT_LOCALE_NUMERALS}, +#endif +}; +static const char *FmtOTokenMapAliasIndex[2] = { +"", "" +#if 0 + "ekIlw", + "dHHHu" +#endif +}; + +static ClockFormatTokenMap FmtWordTokenMap = { + CTOKT_WORD, NULL, 0, 0, 0, 0, NULL +}; + +/* + *---------------------------------------------------------------------- + */ +ClockFormatToken * +ClockGetOrParseFmtFormat( + Tcl_Interp *interp, /* Tcl interpreter */ + Tcl_Obj *formatObj) /* Format container */ +{ + ClockFmtScnStorage *fss; + ClockFormatToken *tok; + + fss = Tcl_GetClockFrmScnFromObj(interp, formatObj); + if (fss == NULL) { + return NULL; + } + + /* if first time scanning - tokenize format */ + if (fss->fmtTok == NULL) { + register const char *p, *e, *cp; + + e = p = HashEntry4FmtScn(fss)->key.string; + e += strlen(p); + + /* estimate token count by % char and format length */ + fss->fmtTokC = EstimateTokenCount(p, e); + + Tcl_MutexLock(&ClockFmtMutex); + + fss->fmtTok = tok = ckalloc(sizeof(*tok) * fss->fmtTokC); + memset(tok, 0, sizeof(*(tok))); + while (p < e) { + switch (*p) { + case '%': + if (1) { + ClockFormatTokenMap * fmtMap = FmtSTokenMap; + const char *mapIndex = FmtSTokenMapIndex, + **aliasIndex = FmtSTokenMapAliasIndex; + if (p+1 >= e) { + goto word_tok; + } + p++; + /* try to find modifier: */ + switch (*p) { + case '%': + /* begin new word token - don't join with previous word token, + * because current mapping should be "...%%..." -> "...%..." */ + tok->map = &FmtWordTokenMap; + tok->tokWord.start = p; + tok->tokWord.end = p+1; + AllocTokenInChain(tok, fss->fmtTok, fss->fmtTokC); + p++; + continue; + break; + case 'E': + fmtMap = FmtETokenMap, + mapIndex = FmtETokenMapIndex, + aliasIndex = FmtETokenMapAliasIndex; + p++; + break; + case 'O': + fmtMap = FmtOTokenMap, + mapIndex = FmtOTokenMapIndex, + aliasIndex = FmtOTokenMapAliasIndex; + p++; + break; + } + /* search direct index */ + cp = strchr(mapIndex, *p); + if (!cp || *cp == '\0') { + /* search wrapper index (multiple chars for same token) */ + cp = strchr(aliasIndex[0], *p); + if (!cp || *cp == '\0') { + p--; if (fmtMap != FmtSTokenMap) p--; + goto word_tok; + } + cp = strchr(mapIndex, aliasIndex[1][cp - aliasIndex[0]]); + if (!cp || *cp == '\0') { /* unexpected, but ... */ + #ifdef DEBUG + Tcl_Panic("token \"%c\" has no map in wrapper resolver", *p); + #endif + p--; if (fmtMap != FmtSTokenMap) p--; + goto word_tok; + } + } + tok->map = &fmtMap[cp - mapIndex]; + tok->tokWord.start = p; + /* next token */ + AllocTokenInChain(tok, fss->fmtTok, fss->fmtTokC); + p++; + continue; + } + break; + default: +word_tok: + if (1) { + ClockFormatToken *wordTok = tok; + if (tok > fss->fmtTok && (tok-1)->map == &FmtWordTokenMap) { + wordTok = tok-1; + } + if (wordTok == tok) { + wordTok->tokWord.start = p; + wordTok->map = &FmtWordTokenMap; + AllocTokenInChain(tok, fss->fmtTok, fss->fmtTokC); + } + p = TclUtfNext(p); + wordTok->tokWord.end = p; + } + break; + } + } + +done: + Tcl_MutexUnlock(&ClockFmtMutex); + } + + return fss->fmtTok; +} /* *---------------------------------------------------------------------- */ int ClockFormat( - ClientData clientData, /* Client data containing literal pool */ - Tcl_Interp *interp, /* Tcl interpreter */ - register DateInfo *info, /* Date fields used for parsing & converting */ - ClockFmtScnCmdArgs *opts) /* Command options */ + register DateFormat *dateFmt, /* Date fields used for parsing & converting */ + ClockFmtScnCmdArgs *opts) /* Command options */ { - ClockClientData *dataPtr = clientData; + ClockClientData *dataPtr = opts->clientData; ClockFormatToken *tok; ClockFormatTokenMap *map; @@ -1780,10 +2124,119 @@ ClockFormat( return TCL_ERROR; } -/* if ((tok = ClockGetOrParseFmtFormat(interp, opts->formatObj)) == NULL) { + if ((tok = ClockGetOrParseFmtFormat(opts->interp, + opts->formatObj)) == NULL) { return TCL_ERROR; } -*/ + + dateFmt->resMem = ckalloc(MIN_FMT_RESULT_BLOCK_ALLOC); /* result container object */ + if (dateFmt->resMem == NULL) { + return TCL_ERROR; + } + dateFmt->output = dateFmt->resMem; + dateFmt->resEnd = dateFmt->resMem + MIN_FMT_RESULT_BLOCK_ALLOC; + *dateFmt->output = '\0'; + + /* do format each token */ + for (; tok->map != NULL; tok++) { + map = tok->map; + switch (map->type) + { + case CFMTT_INT: + if (1) { + int val = (int)*(time_t *)(((char *)dateFmt) + map->offs); + if (map->fmtproc == NULL) { + if (map->flags & CLFMT_DECR) { + val--; + } + if (map->flags & CLFMT_INCR) { + val++; + } + if (map->divider) { + val /= map->divider; + } + if (map->divmod) { + val %= map->divmod; + } + } else { + if (map->fmtproc(opts, dateFmt, tok, &val) != TCL_OK) { + goto done; + } + /* if not calculate only (output inside fmtproc) */ + if (!(map->flags & CLFMT_CALC)) { + continue; + } + } + if (!(map->flags & CLFMT_LOCALE_INDX)) { + if (FrmResultAllocate(dateFmt, 10) != TCL_OK) { goto error; }; + dateFmt->output += sprintf(dateFmt->output, map->tostr, val); + } else { + const char *s; + Tcl_Obj * mcObj = ClockMCGet(opts, (int)map->data /* mcKey */); + if (mcObj == NULL) { + goto error; + } + if (Tcl_ListObjIndex(opts->interp, mcObj, val, &mcObj) != TCL_OK) { + goto error; + } + s = TclGetString(mcObj); + if (FrmResultAllocate(dateFmt, mcObj->length) != TCL_OK) { goto error; }; + memcpy(dateFmt->output, s, mcObj->length + 1); + dateFmt->output += mcObj->length; + } + } + break; + case CFMTT_WIDE: + if (1) { + Tcl_WideInt val = *(Tcl_WideInt *)(((char *)dateFmt) + map->offs); + if (FrmResultAllocate(dateFmt, 20) != TCL_OK) { goto error; }; + dateFmt->output += sprintf(dateFmt->output, map->tostr, val); + } + break; + case CFMTT_CHAR: + if (FrmResultAllocate(dateFmt, 1) != TCL_OK) { goto error; }; + *dateFmt->output++ = *map->tostr; + *dateFmt->output = '\0'; + break; + case CFMTT_PROC: + if (map->fmtproc(opts, dateFmt, tok, NULL) != TCL_OK) { + goto error; + }; + break; + case CTOKT_WORD: + if (1) { + int len = tok->tokWord.end - tok->tokWord.start; + if (FrmResultAllocate(dateFmt, len) != TCL_OK) { goto error; }; + memcpy(dateFmt->output, tok->tokWord.start, len); + dateFmt->output += len; + *dateFmt->output = '\0'; + } + break; + } + } + + goto done; + +error: + + ckfree(dateFmt->resMem); + dateFmt->resMem = NULL; + +done: + + if (dateFmt->resMem) { + Tcl_Obj * result = Tcl_NewObj(); + result->length = dateFmt->output - dateFmt->resMem; + result->bytes = NULL; + result->bytes = ckrealloc(dateFmt->resMem, result->length+1); + if (result->bytes == NULL) { + result->bytes = dateFmt->resMem; + } + Tcl_SetObjResult(opts->interp, result); + return TCL_OK; + } + + return TCL_ERROR; } diff --git a/generic/tclDate.h b/generic/tclDate.h index 64135d3..141ad60 100644 --- a/generic/tclDate.h +++ b/generic/tclDate.h @@ -51,7 +51,6 @@ #define CLF_DATE (CLF_JULIANDAY | CLF_DAYOFMONTH | CLF_DAYOFYEAR | \ CLF_MONTH | CLF_YEAR | CLF_ISO8601YEAR | CLF_ISO8601) - /* * Enumeration of the string literals used in [clock] */ @@ -352,12 +351,11 @@ typedef int ClockScanTokenProc( typedef enum _CLCKTOK_TYPE { - CTOKT_DIGIT = 1, CTOKT_PARSER, CTOKT_SPACE, CTOKT_WORD + CTOKT_DIGIT = 1, CTOKT_PARSER, CTOKT_SPACE, CTOKT_WORD, + CFMTT_INT, CFMTT_WIDE, CFMTT_CHAR, CFMTT_PROC } CLCKTOK_TYPE; -typedef struct ClockFmtScnStorage ClockFmtScnStorage; - -typedef struct ClockFormatTokenMap { +typedef struct ClockScanTokenMap { unsigned short int type; unsigned short int flags; unsigned short int clearFlags; @@ -366,38 +364,62 @@ typedef struct ClockFormatTokenMap { unsigned short int offs; ClockScanTokenProc *parser; void *data; -} ClockFormatTokenMap; -typedef struct ClockFormatToken { - ClockFormatTokenMap *map; +} ClockScanTokenMap; + +typedef struct ClockScanToken { + ClockScanTokenMap *map; + unsigned short int lookAhead; + unsigned short int endDistance; struct { const char *start; const char *end; } tokWord; -} ClockFormatToken; +} ClockScanToken; -typedef struct ClockScanTokenMap { + +#define MIN_FMT_RESULT_BLOCK_ALLOC 200 + +typedef struct DateFormat { + char *resMem; + char *resEnd; + char *output; + + TclDateFields date; +} DateFormat; + +#define CLFMT_INCR (1 << 3) +#define CLFMT_DECR (1 << 4) +#define CLFMT_CALC (1 << 5) +#define CLFMT_LOCALE_INDX (1 << 8) + +typedef struct ClockFormatToken ClockFormatToken; + +typedef int ClockFormatTokenProc( + ClockFmtScnCmdArgs *opts, + DateFormat *dateFmt, + ClockFormatToken *tok, + int *val); + +typedef struct ClockFormatTokenMap { unsigned short int type; + const char *tostr; unsigned short int flags; - unsigned short int clearFlags; - unsigned short int minSize; - unsigned short int maxSize; + unsigned short int divider; + unsigned short int divmod; unsigned short int offs; - ClockScanTokenProc *parser; + ClockFormatTokenProc *fmtproc; void *data; -} ClockScanTokenMap; - -typedef struct ClockScanToken { - ClockScanTokenMap *map; - unsigned short int lookAhead; - unsigned short int endDistance; +} ClockFormatTokenMap; +typedef struct ClockFormatToken { + ClockFormatTokenMap *map; struct { const char *start; const char *end; } tokWord; -} ClockScanToken; +} ClockFormatToken; -#define ClockScnTokenChar(tok) \ - *tok->tokWord.start; + +typedef struct ClockFmtScnStorage ClockFmtScnStorage; typedef struct ClockFmtScnStorage { int objRefCount; /* Reference count shared across threads */ @@ -449,12 +471,11 @@ MODULE_SCOPE ClockFmtScnStorage * MODULE_SCOPE Tcl_Obj * ClockLocalizeFormat(ClockFmtScnCmdArgs *opts); -MODULE_SCOPE int ClockScan(ClientData clientData, Tcl_Interp *interp, - register DateInfo *info, +MODULE_SCOPE int ClockScan(register DateInfo *info, Tcl_Obj *strObj, ClockFmtScnCmdArgs *opts); -MODULE_SCOPE int ClockFormat(ClientData clientData, Tcl_Interp *interp, - register DateInfo *info, ClockFmtScnCmdArgs *opts); +MODULE_SCOPE int ClockFormat(register DateFormat *dateFmt, + ClockFmtScnCmdArgs *opts); MODULE_SCOPE void ClockFrmScnClearCaches(void); diff --git a/library/clock.tcl b/library/clock.tcl index c4e698c..06aa10a 100755 --- a/library/clock.tcl +++ b/library/clock.tcl @@ -676,7 +676,7 @@ proc mcget {locale args} { # #---------------------------------------------------------------------- -proc ::tcl::clock::format { args } { +proc ::tcl::clock::__org_format { args } { variable FormatProc variable TZData diff --git a/library/init.tcl b/library/init.tcl index ef0a84a..6f34302 100644 --- a/library/init.tcl +++ b/library/init.tcl @@ -178,7 +178,7 @@ if {[interp issafe]} { # Auto-loading stubs for 'clock.tcl' - foreach cmd {add format LocalizeFormat SetupTimeZone GetSystemTimeZone __org_scan} { + foreach cmd {add LocalizeFormat SetupTimeZone GetSystemTimeZone} { proc ::tcl::clock::$cmd args { variable TclLibDir source -encoding utf-8 [file join $TclLibDir clock.tcl] diff --git a/tests/clock.test b/tests/clock.test index a4641c6..b27d2a3 100644 --- a/tests/clock.test +++ b/tests/clock.test @@ -18600,6 +18600,11 @@ test clock-6.18 {zone token (%z) is optional} { [clock scan " 2009-06-30T18:30:00 " -format "%Y-%m-%dT%H:%M:%S %z" -gmt 1] \ } {1246390200 1246386600 1246386600} +test clock-6.19 {no token parsing} { + list [catch { clock scan "%E%O%" -format "%E%O%" }] \ + [catch { clock scan "...%..." -format "...%%..." }] +} {0 0} + test clock-7.1 {Julian Day} { clock scan 0 -format %J -gmt true } -210866803200 -- cgit v0.12 From d830389b535a333aca4b9f10cf3746317807f2cb Mon Sep 17 00:00:00 2001 From: sebres Date: Tue, 10 Jan 2017 22:42:15 +0000 Subject: [temp-commit]: format almost ready (missing some tokens), sprintf replaced with _itoaw (because "sprintf" too slow) --- generic/tclClock.c | 3 +- generic/tclClockFmt.c | 194 +++++++++++++++++++++++++++++++++++++++----------- generic/tclDate.h | 4 ++ 3 files changed, 157 insertions(+), 44 deletions(-) diff --git a/generic/tclClock.c b/generic/tclClock.c index 935a347..2e2c44b 100644 --- a/generic/tclClock.c +++ b/generic/tclClock.c @@ -93,7 +93,6 @@ static void GetGregorianEraYearDay(TclDateFields *, int); static void GetMonthDay(TclDateFields *); static void GetJulianDayFromEraYearWeekDay(TclDateFields *, int); static void GetJulianDayFromEraYearMonthDay(TclDateFields *, int); -static int IsGregorianLeapYear(TclDateFields *); static int WeekdayOnOrBefore(int, int); static int ClockClicksObjCmd( ClientData clientData, Tcl_Interp *interp, @@ -2471,7 +2470,7 @@ GetJulianDayFromEraYearDay( *---------------------------------------------------------------------- */ -static int +MODULE_SCOPE int IsGregorianLeapYear( TclDateFields *fields) /* Date to test */ { diff --git a/generic/tclClockFmt.c b/generic/tclClockFmt.c index b46b7bf..f1fdf27 100644 --- a/generic/tclClockFmt.c +++ b/generic/tclClockFmt.c @@ -1762,6 +1762,50 @@ done: } +inline char * +_itoaw( + char *buf, + register int val, + char padchar, + unsigned short int width) +{ + register char *p; + static int wrange[] = {1, 10, 100, 1000, 10000, 100000, 1000000, 10000000, 100000000, 1000000000}; + unsigned short int sign = 0; + + /* sign = 1 by negative number */ + if (val < 0) + { + sign = 1; + val = -val; + if (!width) width++; + } + /* check resp. recalculate width (regarding sign) */ + width -= sign; + while (width <= 9 && val >= wrange[width]) { + width++; + } + width += sign; + /* number to string backwards */ + p = buf + width; + *p-- = '\0'; + do { + *p-- = '0' + (val % 10); + val /= 10; + } while (val > 0); + /* sign by 0 padding */ + if (sign && padchar != '0') { *p-- = '-'; sign = 0; } + /* fulling with pad-char */ + while (p >= buf + sign) { + *p-- = padchar; + } + /* sign by non 0 padding */ + if (sign) { *p = '-'; } + + return buf + width; +} + + inline int FrmResultAllocate( register DateFormat *dateFmt, @@ -1789,8 +1833,8 @@ ClockFmtToken_HourAMPM_Proc( ClockFormatToken *tok, int *val) { - *val = ( ( ( *val % 86400 ) + 86400 - 3600 ) / 3600 ) % 12 + 1; - return TCL_OK; + *val = ( ( ( *val % 86400 ) + 86400 - 3600 ) / 3600 ) % 12 + 1; + return TCL_OK; } static int @@ -1819,73 +1863,132 @@ ClockFmtToken_AMPM_Proc( len = Tcl_UtfToUpper(dateFmt->output); } dateFmt->output += len; - *dateFmt->output = '\0'; return TCL_OK; } + +static int +ClockFmtToken_StarDate_Proc( + ClockFmtScnCmdArgs *opts, + DateFormat *dateFmt, + ClockFormatToken *tok, + int *val) + { + int fractYear; + /* Get day of year, zero based */ + int doy = dateFmt->date.dayOfYear - 1; + + /* Convert day of year to a fractional year */ + if (IsGregorianLeapYear(&dateFmt->date)) { + fractYear = 1000 * doy / 366; + } else { + fractYear = 1000 * doy / 365; + } + + /* Put together the StarDate as "Stardate %02d%03d.%1d" */ + if (FrmResultAllocate(dateFmt, 20) != TCL_OK) { return TCL_ERROR; }; + memcpy(dateFmt->output, "Stardate ", 9); + dateFmt->output += 9; + dateFmt->output = _itoaw(dateFmt->output, + dateFmt->date.year - RODDENBERRY, '0', 2); + dateFmt->output = _itoaw(dateFmt->output, + fractYear, '0', 3); + *dateFmt->output++ = '.'; + dateFmt->output = _itoaw(dateFmt->output, + dateFmt->date.localSeconds % 86400 / ( 86400 / 10 ), '0', 1); + + return TCL_OK; +} +static int +ClockFmtToken_WeekOfYear_Proc( + ClockFmtScnCmdArgs *opts, + DateFormat *dateFmt, + ClockFormatToken *tok, + int *val) +{ + int dow = dateFmt->date.dayOfWeek; + if (*tok->tokWord.start == 'U') { + if (dow == 7) { + dow = 0; + } + dow++; + } + *val = ( dateFmt->date.dayOfYear - dow + 7 ) / 7; + return TCL_OK; +} static const char *FmtSTokenMapIndex = - "demNbByYCHMSIklpaAugGjJsnt"; + "demNbByYCHMSIklpaAuwUVgGjJsntQ"; static ClockFormatTokenMap FmtSTokenMap[] = { /* %d */ - {CFMTT_INT, "%02d", 0, 0, 0, TclOffset(DateFormat, date.dayOfMonth), NULL}, + {CFMTT_INT, "0", 2, 0, 0, 0, TclOffset(DateFormat, date.dayOfMonth), NULL}, /* %e */ - {CFMTT_INT, "%2d", 0, 0, 0, TclOffset(DateFormat, date.dayOfMonth), NULL}, + {CFMTT_INT, " ", 2, 0, 0, 0, TclOffset(DateFormat, date.dayOfMonth), NULL}, /* %m */ - {CFMTT_INT, "%02d", 0, 0, 0, TclOffset(DateFormat, date.month), NULL}, + {CFMTT_INT, "0", 2, 0, 0, 0, TclOffset(DateFormat, date.month), NULL}, /* %N */ - {CFMTT_INT, "%2d", 0, 0, 0, TclOffset(DateFormat, date.month), NULL}, + {CFMTT_INT, " ", 2, 0, 0, 0, TclOffset(DateFormat, date.month), NULL}, /* %b %h */ - {CFMTT_INT, NULL, CLFMT_LOCALE_INDX | CLFMT_DECR, 0, 12, TclOffset(DateFormat, date.month), + {CFMTT_INT, NULL, 0, CLFMT_LOCALE_INDX | CLFMT_DECR, 0, 12, TclOffset(DateFormat, date.month), NULL, (void *)MCLIT_MONTHS_ABBREV}, /* %B */ - {CFMTT_INT, NULL, CLFMT_LOCALE_INDX | CLFMT_DECR, 0, 12, TclOffset(DateFormat, date.month), + {CFMTT_INT, NULL, 0, CLFMT_LOCALE_INDX | CLFMT_DECR, 0, 12, TclOffset(DateFormat, date.month), NULL, (void *)MCLIT_MONTHS_FULL}, /* %y */ - {CFMTT_INT, "%02d", 0, 0, 100, TclOffset(DateFormat, date.year), NULL}, + {CFMTT_INT, "0", 2, 0, 0, 100, TclOffset(DateFormat, date.year), NULL}, /* %Y */ - {CFMTT_INT, "%04d", 0, 0, 0, TclOffset(DateFormat, date.year), NULL}, + {CFMTT_INT, "0", 4, 0, 0, 0, TclOffset(DateFormat, date.year), NULL}, /* %C */ - {CFMTT_INT, "%02d", 0, 100, 0, TclOffset(DateFormat, date.year), NULL}, + {CFMTT_INT, "0", 2, 0, 100, 0, TclOffset(DateFormat, date.year), NULL}, /* %H */ - {CFMTT_INT, "%02d", 0, 3600, 24, TclOffset(DateFormat, date.localSeconds), NULL}, + {CFMTT_INT, "0", 2, 0, 3600, 24, TclOffset(DateFormat, date.localSeconds), NULL}, /* %M */ - {CFMTT_INT, "%02d", 0, 60, 60, TclOffset(DateFormat, date.localSeconds), NULL}, + {CFMTT_INT, "0", 2, 0, 60, 60, TclOffset(DateFormat, date.localSeconds), NULL}, /* %S */ - {CFMTT_INT, "%02d", 0, 0, 60, TclOffset(DateFormat, date.localSeconds), NULL}, + {CFMTT_INT, "0", 2, 0, 0, 60, TclOffset(DateFormat, date.localSeconds), NULL}, /* %I */ - {CFMTT_INT, "%02d", CLFMT_CALC, 0, 0, TclOffset(DateFormat, date.localSeconds), + {CFMTT_INT, "0", 2, CLFMT_CALC, 0, 0, TclOffset(DateFormat, date.localSeconds), ClockFmtToken_HourAMPM_Proc, NULL}, /* %k */ - {CFMTT_INT, "%2d", 0, 3600, 24, TclOffset(DateFormat, date.localSeconds), NULL}, + {CFMTT_INT, " ", 2, 0, 3600, 24, TclOffset(DateFormat, date.localSeconds), NULL}, /* %l */ - {CFMTT_INT, "%2d", CLFMT_CALC, 0, 0, TclOffset(DateFormat, date.localSeconds), + {CFMTT_INT, " ", 2, CLFMT_CALC, 0, 0, TclOffset(DateFormat, date.localSeconds), ClockFmtToken_HourAMPM_Proc, NULL}, /* %p %P */ - {CFMTT_INT, "%02d", 0, 0, 0, TclOffset(DateFormat, date.localSeconds), + {CFMTT_INT, NULL, 0, 0, 0, 0, TclOffset(DateFormat, date.localSeconds), ClockFmtToken_AMPM_Proc, NULL}, /* %a */ - {CFMTT_INT, NULL, CLFMT_LOCALE_INDX, 0, 7, TclOffset(DateFormat, date.dayOfWeek), + {CFMTT_INT, NULL, 0, CLFMT_LOCALE_INDX, 0, 7, TclOffset(DateFormat, date.dayOfWeek), NULL, (void *)MCLIT_DAYS_OF_WEEK_ABBREV}, /* %A */ - {CFMTT_INT, NULL, CLFMT_LOCALE_INDX, 0, 7, TclOffset(DateFormat, date.dayOfWeek), + {CFMTT_INT, NULL, 0, CLFMT_LOCALE_INDX, 0, 7, TclOffset(DateFormat, date.dayOfWeek), NULL, (void *)MCLIT_DAYS_OF_WEEK_FULL}, /* %u */ - {CFMTT_INT, "%1d", 0, 0, 0, TclOffset(DateFormat, date.dayOfWeek), NULL}, + {CFMTT_INT, " ", 1, 0, 0, 0, TclOffset(DateFormat, date.dayOfWeek), NULL}, + /* %w */ + {CFMTT_INT, " ", 1, 0, 0, 7, TclOffset(DateFormat, date.dayOfWeek), NULL}, + /* %U %W */ + {CFMTT_INT, "0", 2, CLFMT_CALC, 0, 0, TclOffset(DateFormat, date.dayOfYear), + ClockFmtToken_WeekOfYear_Proc, NULL}, + /* %V */ + {CFMTT_INT, "0", 2, 0, 0, 0, TclOffset(DateFormat, date.iso8601Week), NULL}, /* %g */ - {CFMTT_INT, "%02d", 0, 0, 100, TclOffset(DateFormat, date.iso8601Year), NULL}, + {CFMTT_INT, "0", 2, 0, 0, 100, TclOffset(DateFormat, date.iso8601Year), NULL}, /* %G */ - {CFMTT_INT, "%04d", 0, 0, 0, TclOffset(DateFormat, date.iso8601Year), NULL}, + {CFMTT_INT, "0", 4, 0, 0, 0, TclOffset(DateFormat, date.iso8601Year), NULL}, /* %j */ - {CFMTT_INT, "%03d", 0, 0, 0, TclOffset(DateFormat, date.dayOfYear), NULL}, + {CFMTT_INT, "0", 3, 0, 0, 0, TclOffset(DateFormat, date.dayOfYear), NULL}, /* %J */ - {CFMTT_INT, "%07d", 0, 0, 0, TclOffset(DateFormat, date.julianDay), NULL}, + {CFMTT_INT, "0", 7, 0, 0, 0, TclOffset(DateFormat, date.julianDay), NULL}, /* %s */ - {CFMTT_WIDE, "%ld", 0, 0, 0, TclOffset(DateFormat, date.seconds), NULL}, + {CFMTT_WIDE, "%ld", 0, 0, 0, 0, TclOffset(DateFormat, date.seconds), NULL}, /* %n */ - {CFMTT_CHAR, "\n", 0, 0, 0, 0, NULL}, + {CFMTT_CHAR, "\n", 0, 0, 0, 0, 0, NULL}, /* %t */ - {CFMTT_CHAR, "\t", 0, 0, 0, 0, NULL}, + {CFMTT_CHAR, "\t", 0, 0, 0, 0, 0, NULL}, + /* %Q */ + {CFMTT_INT, NULL, 0, 0, 0, 0, 0, + ClockFmtToken_StarDate_Proc, NULL}, #if 0 /* %H %k %I %l */ @@ -1927,14 +2030,14 @@ static ClockFormatTokenMap FmtSTokenMap[] = { #endif }; static const char *FmtSTokenMapAliasIndex[2] = { - "hP", - "bp" + "hPW", + "bpU" }; static const char *FmtETokenMapIndex = "";// "Ey"; static ClockFormatTokenMap FmtETokenMap[] = { - {CFMTT_INT, "%02d", 0, 0, 0, 0, NULL}, + {CFMTT_INT, "0", 2, 0, 0, 0, 0, NULL}, #if 0 /* %EE */ {CTOKT_PARSER, 0, 0, 0, 0, TclOffset(DateFormat, date.year), @@ -1952,7 +2055,7 @@ static const char *FmtETokenMapAliasIndex[2] = { static const char *FmtOTokenMapIndex = "";// "dmyHMSu"; static ClockFormatTokenMap FmtOTokenMap[] = { - {CFMTT_INT, "%02d", 0, 0, 0, 0, NULL}, + {CFMTT_INT, "0", 2, 0, 0, 0, 0, NULL}, #if 0 /* %Od %Oe */ {CTOKT_PARSER, CLF_DAYOFMONTH, 0, 0, 0, TclOffset(DateFormat, date.dayOfMonth), @@ -1986,7 +2089,7 @@ static const char *FmtOTokenMapAliasIndex[2] = { }; static ClockFormatTokenMap FmtWordTokenMap = { - CTOKT_WORD, NULL, 0, 0, 0, 0, NULL + CTOKT_WORD, NULL, 0, 0, 0, 0, 0, NULL }; /* @@ -2168,8 +2271,12 @@ ClockFormat( } } if (!(map->flags & CLFMT_LOCALE_INDX)) { - if (FrmResultAllocate(dateFmt, 10) != TCL_OK) { goto error; }; - dateFmt->output += sprintf(dateFmt->output, map->tostr, val); + if (FrmResultAllocate(dateFmt, 11) != TCL_OK) { goto error; }; + if (map->width) { + dateFmt->output = _itoaw(dateFmt->output, val, *map->tostr, map->width); + } else { + dateFmt->output += sprintf(dateFmt->output, map->tostr, val); + } } else { const char *s; Tcl_Obj * mcObj = ClockMCGet(opts, (int)map->data /* mcKey */); @@ -2189,14 +2296,13 @@ ClockFormat( case CFMTT_WIDE: if (1) { Tcl_WideInt val = *(Tcl_WideInt *)(((char *)dateFmt) + map->offs); - if (FrmResultAllocate(dateFmt, 20) != TCL_OK) { goto error; }; + if (FrmResultAllocate(dateFmt, 21) != TCL_OK) { goto error; }; dateFmt->output += sprintf(dateFmt->output, map->tostr, val); } break; case CFMTT_CHAR: if (FrmResultAllocate(dateFmt, 1) != TCL_OK) { goto error; }; *dateFmt->output++ = *map->tostr; - *dateFmt->output = '\0'; break; case CFMTT_PROC: if (map->fmtproc(opts, dateFmt, tok, NULL) != TCL_OK) { @@ -2207,9 +2313,12 @@ ClockFormat( if (1) { int len = tok->tokWord.end - tok->tokWord.start; if (FrmResultAllocate(dateFmt, len) != TCL_OK) { goto error; }; - memcpy(dateFmt->output, tok->tokWord.start, len); - dateFmt->output += len; - *dateFmt->output = '\0'; + if (len == 1) { + *dateFmt->output++ = *tok->tokWord.start; + } else { + memcpy(dateFmt->output, tok->tokWord.start, len); + dateFmt->output += len; + } } break; } @@ -2232,6 +2341,7 @@ done: if (result->bytes == NULL) { result->bytes = dateFmt->resMem; } + result->bytes[result->length] = '\0'; Tcl_SetObjResult(opts->interp, result); return TCL_OK; } diff --git a/generic/tclDate.h b/generic/tclDate.h index 141ad60..c5d7da5 100644 --- a/generic/tclDate.h +++ b/generic/tclDate.h @@ -29,6 +29,8 @@ #define FOUR_YEARS 1461 /* days */ #define ONE_YEAR 365 /* days */ +#define RODDENBERRY 1946 /* Another epoch (Hi, Jeff!) */ + #define CLF_OPTIONAL (1 << 0) /* token is non mandatory */ #define CLF_JULIANDAY (1 << 3) @@ -403,6 +405,7 @@ typedef int ClockFormatTokenProc( typedef struct ClockFormatTokenMap { unsigned short int type; const char *tostr; + unsigned short int width; unsigned short int flags; unsigned short int divider; unsigned short int divmod; @@ -441,6 +444,7 @@ typedef struct ClockFmtScnStorage { MODULE_SCOPE time_t ToSeconds(time_t Hours, time_t Minutes, time_t Seconds, MERIDIAN Meridian); +MODULE_SCOPE int IsGregorianLeapYear(TclDateFields *); MODULE_SCOPE int TclClockFreeScan(Tcl_Interp *interp, DateInfo *info); -- cgit v0.12 From bd20b3429aa04d1c42d1f25a1eaf32008211e1d2 Mon Sep 17 00:00:00 2001 From: sebres Date: Tue, 10 Jan 2017 22:43:22 +0000 Subject: porting of clock format completed; all clock test cases passed --- generic/tclClock.c | 30 ++- generic/tclClockFmt.c | 511 +++++++++++++++++++++++++++++++++------------- generic/tclDate.h | 9 + tests-perf/clock.perf.tcl | 75 ++++++- 4 files changed, 478 insertions(+), 147 deletions(-) diff --git a/generic/tclClock.c b/generic/tclClock.c index 2e2c44b..28a484f 100644 --- a/generic/tclClock.c +++ b/generic/tclClock.c @@ -70,8 +70,6 @@ TCL_DECLARE_MUTEX(clockMutex) * Function prototypes for local procedures in this file: */ -static int ConvertUTCToLocal(ClientData clientData, Tcl_Interp *, - TclDateFields *, Tcl_Obj *timezoneObj, int); static int ConvertUTCToLocalUsingTable(Tcl_Interp *, TclDateFields *, int, Tcl_Obj *const[], Tcl_WideInt rangesVal[2]); @@ -86,8 +84,6 @@ static int ConvertLocalToUTCUsingC(Tcl_Interp *, TclDateFields *, int); static int ClockConfigureObjCmd(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *const objv[]); -static Tcl_Obj * LookupLastTransition(Tcl_Interp *, Tcl_WideInt, - int, Tcl_Obj *const *, Tcl_WideInt rangesVal[2]); static void GetYearWeekDay(TclDateFields *, int); static void GetGregorianEraYearDay(TclDateFields *, int); static void GetMonthDay(TclDateFields *); @@ -1730,7 +1726,7 @@ ConvertLocalToUTCUsingC( *---------------------------------------------------------------------- */ -static int +MODULE_SCOPE int ConvertUTCToLocal( ClientData clientData, /* Client data of the interpreter */ Tcl_Interp *interp, /* Tcl interpreter */ @@ -1974,7 +1970,7 @@ ConvertUTCToLocalUsingC( *---------------------------------------------------------------------- */ -static Tcl_Obj * +MODULE_SCOPE Tcl_Obj * LookupLastTransition( Tcl_Interp *interp, /* Interpreter for error messages */ Tcl_WideInt tick, /* Time from the epoch */ @@ -2950,7 +2946,7 @@ ClockFormatObjCmd( DateFormat dateFmt; /* Common structure used for formatting */ if ((objc & 1) == 1) { - Tcl_WrongNumArgs(interp, 1, objv, "string " + Tcl_WrongNumArgs(interp, 1, objv, "clockval " "?-format string? " "?-gmt boolean? " "?-locale LOCALE? ?-timezone ZONE?"); @@ -2974,6 +2970,16 @@ ClockFormatObjCmd( return TCL_ERROR; } + /* + * seconds could be an unsigned number that overflowed. Make sure + * that it isn't. + */ + + if (objv[1]->typePtr == &tclBignumType) { + Tcl_SetObjResult(interp, dataPtr->literals[LIT_INTEGER_VALUE_TOO_LARGE]); + return TCL_ERROR; + } + memset(&dateFmt, 0, sizeof(dateFmt)); /* @@ -3065,6 +3071,16 @@ ClockScanObjCmd( if (Tcl_GetWideIntFromObj(interp, opts.baseObj, &baseVal) != TCL_OK) { return TCL_ERROR; } + /* + * seconds could be an unsigned number that overflowed. Make sure + * that it isn't. + */ + + if (opts.baseObj->typePtr == &tclBignumType) { + Tcl_SetObjResult(interp, dataPtr->literals[LIT_INTEGER_VALUE_TOO_LARGE]); + return TCL_ERROR; + } + } else { Tcl_Time now; Tcl_GetTime(&now); diff --git a/generic/tclClockFmt.c b/generic/tclClockFmt.c index f1fdf27..55e328c 100644 --- a/generic/tclClockFmt.c +++ b/generic/tclClockFmt.c @@ -101,6 +101,161 @@ _str2wideInt( return TCL_OK; } +inline char * +_itoaw( + char *buf, + register int val, + char padchar, + unsigned short int width) +{ + register char *p; + static int wrange[] = {1, 10, 100, 1000, 10000, 100000, 1000000, 10000000, 100000000, 1000000000}; + + /* positive integer */ + + if (val >= 0) + { + /* check resp. recalculate width */ + while (width <= 9 && val >= wrange[width]) { + width++; + } + /* number to string backwards */ + p = buf + width; + *p-- = '\0'; + do { + register char c = (val % 10); val /= 10; + *p-- = '0' + c; + } while (val > 0); + /* fulling with pad-char */ + while (p >= buf) { + *p-- = padchar; + } + + return buf + width; + } + /* negative integer */ + + if (!width) width++; + /* check resp. recalculate width (regarding sign) */ + width--; + while (width <= 9 && val <= -wrange[width]) { + width++; + } + width++; + /* number to string backwards */ + p = buf + width; + *p-- = '\0'; + /* differentiate platforms with -1 % 10 == 1 and -1 % 10 == -1 */ + if (-1 % 10 == -1) { + do { + register char c = (val % 10); val /= 10; + *p-- = '0' - c; + } while (val < 0); + } else { + do { + register char c = (val % 10); val /= 10; + *p-- = '0' + c; + } while (val < 0); + } + /* sign by 0 padding */ + if (padchar != '0') { *p-- = '-'; } + /* fulling with pad-char */ + while (p >= buf + 1) { + *p-- = padchar; + } + /* sign by non 0 padding */ + if (padchar == '0') { *p = '-'; } + + return buf + width; +} + +inline char * +_witoaw( + char *buf, + register Tcl_WideInt val, + char padchar, + unsigned short int width) +{ + register char *p; + static int wrange[] = {1, 10, 100, 1000, 10000, 100000, 1000000, 10000000, 100000000, 1000000000}; + + /* positive integer */ + + if (val >= 0) + { + /* check resp. recalculate width */ + if (val >= 10000000000L) { + Tcl_WideInt val2; + val2 = val / 10000000000L; + while (width <= 9 && val2 >= wrange[width]) { + width++; + } + width += 10; + } else { + while (width <= 9 && val >= wrange[width]) { + width++; + } + } + /* number to string backwards */ + p = buf + width; + *p-- = '\0'; + do { + register char c = (val % 10); val /= 10; + *p-- = '0' + c; + } while (val > 0); + /* fulling with pad-char */ + while (p >= buf) { + *p-- = padchar; + } + + return buf + width; + } + + /* negative integer */ + + if (!width) width++; + /* check resp. recalculate width (regarding sign) */ + width--; + if (val <= 10000000000L) { + Tcl_WideInt val2; + val2 = val / 10000000000L; + while (width <= 9 && val2 <= -wrange[width]) { + width++; + } + width += 10; + } else { + while (width <= 9 && val <= -wrange[width]) { + width++; + } + } + width++; + /* number to string backwards */ + p = buf + width; + *p-- = '\0'; + /* differentiate platforms with -1 % 10 == 1 and -1 % 10 == -1 */ + if (-1 % 10 == -1) { + do { + register char c = (val % 10); val /= 10; + *p-- = '0' - c; + } while (val < 0); + } else { + do { + register char c = (val % 10); val /= 10; + *p-- = '0' + c; + } while (val < 0); + } + /* sign by 0 padding */ + if (padchar != '0') { *p-- = '-'; } + /* fulling with pad-char */ + while (p >= buf + 1) { + *p-- = padchar; + } + /* sign by non 0 padding */ + if (padchar == '0') { *p = '-'; } + + return buf + width; +} + /* *---------------------------------------------------------------------- */ @@ -1760,51 +1915,6 @@ done: return ret; } - - -inline char * -_itoaw( - char *buf, - register int val, - char padchar, - unsigned short int width) -{ - register char *p; - static int wrange[] = {1, 10, 100, 1000, 10000, 100000, 1000000, 10000000, 100000000, 1000000000}; - unsigned short int sign = 0; - - /* sign = 1 by negative number */ - if (val < 0) - { - sign = 1; - val = -val; - if (!width) width++; - } - /* check resp. recalculate width (regarding sign) */ - width -= sign; - while (width <= 9 && val >= wrange[width]) { - width++; - } - width += sign; - /* number to string backwards */ - p = buf + width; - *p-- = '\0'; - do { - *p-- = '0' + (val % 10); - val /= 10; - } while (val > 0); - /* sign by 0 padding */ - if (sign && padchar != '0') { *p-- = '-'; sign = 0; } - /* fulling with pad-char */ - while (p >= buf + sign) { - *p-- = padchar; - } - /* sign by non 0 padding */ - if (sign) { *p = '-'; } - - return buf + width; -} - inline int FrmResultAllocate( @@ -1833,7 +1943,7 @@ ClockFmtToken_HourAMPM_Proc( ClockFormatToken *tok, int *val) { - *val = ( ( ( *val % 86400 ) + 86400 - 3600 ) / 3600 ) % 12 + 1; + *val = ( ( ( *val % SECONDS_PER_DAY ) + SECONDS_PER_DAY - 3600 ) / 3600 ) % 12 + 1; return TCL_OK; } @@ -1848,7 +1958,7 @@ ClockFmtToken_AMPM_Proc( const char *s; int len; - if ((*val % 84600) < (84600 / 2)) { + if ((*val % SECONDS_PER_DAY) < (SECONDS_PER_DAY / 2)) { mcObj = ClockMCGet(opts, MCLIT_AM); } else { mcObj = ClockMCGet(opts, MCLIT_PM); @@ -1895,7 +2005,7 @@ ClockFmtToken_StarDate_Proc( fractYear, '0', 3); *dateFmt->output++ = '.'; dateFmt->output = _itoaw(dateFmt->output, - dateFmt->date.localSeconds % 86400 / ( 86400 / 10 ), '0', 1); + dateFmt->date.localSeconds % SECONDS_PER_DAY / ( SECONDS_PER_DAY / 10 ), '0', 1); return TCL_OK; } @@ -1916,9 +2026,162 @@ ClockFmtToken_WeekOfYear_Proc( *val = ( dateFmt->date.dayOfYear - dow + 7 ) / 7; return TCL_OK; } +static int +ClockFmtToken_TimeZone_Proc( + ClockFmtScnCmdArgs *opts, + DateFormat *dateFmt, + ClockFormatToken *tok, + int *val) +{ + if (*tok->tokWord.start == 'z') { + int z = dateFmt->date.tzOffset; + char sign = '+'; + if ( z < 0 ) { + z = -z; + sign = '-'; + } + if (FrmResultAllocate(dateFmt, 7) != TCL_OK) { return TCL_ERROR; }; + *dateFmt->output++ = sign; + dateFmt->output = _itoaw(dateFmt->output, z / 3600, '0', 2); + z %= 3600; + dateFmt->output = _itoaw(dateFmt->output, z / 60, '0', 2); + z %= 60; + if (z != 0) { + dateFmt->output = _itoaw(dateFmt->output, z, '0', 2); + } + } else { + Tcl_Obj * objPtr; + const char *s; int len; + /* convert seconds to local seconds to obtain tzName object */ + if (ConvertUTCToLocal(opts->clientData, opts->interp, + &dateFmt->date, opts->timezoneObj, + GREGORIAN_CHANGE_DATE) != TCL_OK) { + return TCL_ERROR; + }; + objPtr = dateFmt->date.tzName; + s = TclGetString(objPtr); + len = objPtr->length; + if (FrmResultAllocate(dateFmt, len) != TCL_OK) { return TCL_ERROR; }; + memcpy(dateFmt->output, s, len + 1); + dateFmt->output += len; + } + return TCL_OK; +} + +static int +ClockFmtToken_LocaleERA_Proc( + ClockFmtScnCmdArgs *opts, + DateFormat *dateFmt, + ClockFormatToken *tok, + int *val) +{ + Tcl_Obj *mcObj; + const char *s; + int len; + + if (dateFmt->date.era == BCE) { + mcObj = ClockMCGet(opts, MCLIT_BCE); + } else { + mcObj = ClockMCGet(opts, MCLIT_CE); + } + if (mcObj == NULL) { + return TCL_ERROR; + } + s = TclGetString(mcObj); len = mcObj->length; + if (FrmResultAllocate(dateFmt, len) != TCL_OK) { return TCL_ERROR; }; + memcpy(dateFmt->output, s, len + 1); + dateFmt->output += len; + + return TCL_OK; +} + +static int +ClockFmtToken_LocaleERAYear_Proc( + ClockFmtScnCmdArgs *opts, + DateFormat *dateFmt, + ClockFormatToken *tok, + int *val) +{ + int rowc; + Tcl_Obj **rowv; + + if (dateFmt->localeEra == NULL) { + Tcl_Obj *mcObj = ClockMCGet(opts, MCLIT_LOCALE_ERAS); + if (mcObj == NULL) { + return TCL_ERROR; + } + if (TclListObjGetElements(opts->interp, mcObj, &rowc, &rowv) != TCL_OK) { + return TCL_ERROR; + } + if (rowc != 0) { + dateFmt->localeEra = LookupLastTransition(opts->interp, + dateFmt->date.localSeconds, rowc, rowv, NULL); + } + if (dateFmt->localeEra == NULL) { + dateFmt->localeEra = (Tcl_Obj*)1; + } + } + + /* if no LOCALE_ERAS in catalog or era not found */ + if (dateFmt->localeEra == (Tcl_Obj*)1) { + if (FrmResultAllocate(dateFmt, 11) != TCL_OK) { return TCL_ERROR; }; + if (*tok->tokWord.start == 'C') { /* %EC */ + *val = dateFmt->date.year / 100; + dateFmt->output = _itoaw(dateFmt->output, + *val, '0', 2); + } else { /* %Ey */ + *val = dateFmt->date.year % 100; + dateFmt->output = _itoaw(dateFmt->output, + *val, '0', 2); + } + } else { + Tcl_Obj *objPtr; + const char *s; + int len; + if (*tok->tokWord.start == 'C') { /* %EC */ + if (Tcl_ListObjIndex(opts->interp, dateFmt->localeEra, 1, + &objPtr) != TCL_OK ) { + return TCL_ERROR; + } + } else { /* %Ey */ + if (Tcl_ListObjIndex(opts->interp, dateFmt->localeEra, 2, + &objPtr) != TCL_OK ) { + return TCL_ERROR; + } + if (Tcl_GetIntFromObj(opts->interp, objPtr, val) != TCL_OK) { + return TCL_ERROR; + } + *val = dateFmt->date.year - *val; + /* if year in locale numerals */ + if (*val >= 0 && *val < 100) { + /* year as integer */ + Tcl_Obj * mcObj = ClockMCGet(opts, MCLIT_LOCALE_NUMERALS); + if (mcObj == NULL) { + return TCL_ERROR; + } + if (Tcl_ListObjIndex(opts->interp, mcObj, *val, &objPtr) != TCL_OK) { + return TCL_ERROR; + } + } else { + /* year as integer */ + if (FrmResultAllocate(dateFmt, 11) != TCL_OK) { return TCL_ERROR; }; + dateFmt->output = _itoaw(dateFmt->output, + *val, '0', 2); + return TCL_OK; + } + } + s = TclGetString(objPtr); + len = objPtr->length; + if (FrmResultAllocate(dateFmt, len) != TCL_OK) { return TCL_ERROR; }; + memcpy(dateFmt->output, s, len + 1); + dateFmt->output += len; + } + return TCL_OK; +} + static const char *FmtSTokenMapIndex = - "demNbByYCHMSIklpaAuwUVgGjJsntQ"; + "demNbByYCHMSIklpaAuwUVzgGjJsntQ"; static ClockFormatTokenMap FmtSTokenMap[] = { /* %d */ {CFMTT_INT, "0", 2, 0, 0, 0, TclOffset(DateFormat, date.dayOfMonth), NULL}, @@ -1941,21 +2204,21 @@ static ClockFormatTokenMap FmtSTokenMap[] = { /* %C */ {CFMTT_INT, "0", 2, 0, 100, 0, TclOffset(DateFormat, date.year), NULL}, /* %H */ - {CFMTT_INT, "0", 2, 0, 3600, 24, TclOffset(DateFormat, date.localSeconds), NULL}, + {CFMTT_INT, "0", 2, 0, 3600, 24, TclOffset(DateFormat, date.secondOfDay), NULL}, /* %M */ - {CFMTT_INT, "0", 2, 0, 60, 60, TclOffset(DateFormat, date.localSeconds), NULL}, + {CFMTT_INT, "0", 2, 0, 60, 60, TclOffset(DateFormat, date.secondOfDay), NULL}, /* %S */ - {CFMTT_INT, "0", 2, 0, 0, 60, TclOffset(DateFormat, date.localSeconds), NULL}, + {CFMTT_INT, "0", 2, 0, 0, 60, TclOffset(DateFormat, date.secondOfDay), NULL}, /* %I */ - {CFMTT_INT, "0", 2, CLFMT_CALC, 0, 0, TclOffset(DateFormat, date.localSeconds), + {CFMTT_INT, "0", 2, CLFMT_CALC, 0, 0, TclOffset(DateFormat, date.secondOfDay), ClockFmtToken_HourAMPM_Proc, NULL}, /* %k */ - {CFMTT_INT, " ", 2, 0, 3600, 24, TclOffset(DateFormat, date.localSeconds), NULL}, + {CFMTT_INT, " ", 2, 0, 3600, 24, TclOffset(DateFormat, date.secondOfDay), NULL}, /* %l */ - {CFMTT_INT, " ", 2, CLFMT_CALC, 0, 0, TclOffset(DateFormat, date.localSeconds), + {CFMTT_INT, " ", 2, CLFMT_CALC, 0, 0, TclOffset(DateFormat, date.secondOfDay), ClockFmtToken_HourAMPM_Proc, NULL}, /* %p %P */ - {CFMTT_INT, NULL, 0, 0, 0, 0, TclOffset(DateFormat, date.localSeconds), + {CFMTT_INT, NULL, 0, 0, 0, 0, TclOffset(DateFormat, date.secondOfDay), ClockFmtToken_AMPM_Proc, NULL}, /* %a */ {CFMTT_INT, NULL, 0, CLFMT_LOCALE_INDX, 0, 7, TclOffset(DateFormat, date.dayOfWeek), @@ -1972,6 +2235,9 @@ static ClockFormatTokenMap FmtSTokenMap[] = { ClockFmtToken_WeekOfYear_Proc, NULL}, /* %V */ {CFMTT_INT, "0", 2, 0, 0, 0, TclOffset(DateFormat, date.iso8601Week), NULL}, + /* %z %Z */ + {CFMTT_INT, NULL, 0, 0, 0, 0, 0, + ClockFmtToken_TimeZone_Proc, NULL}, /* %g */ {CFMTT_INT, "0", 2, 0, 0, 100, TclOffset(DateFormat, date.iso8601Year), NULL}, /* %G */ @@ -1981,7 +2247,7 @@ static ClockFormatTokenMap FmtSTokenMap[] = { /* %J */ {CFMTT_INT, "0", 7, 0, 0, 0, TclOffset(DateFormat, date.julianDay), NULL}, /* %s */ - {CFMTT_WIDE, "%ld", 0, 0, 0, 0, TclOffset(DateFormat, date.seconds), NULL}, + {CFMTT_WIDE, "0", 1, 0, 0, 0, TclOffset(DateFormat, date.seconds), NULL}, /* %n */ {CFMTT_CHAR, "\n", 0, 0, 0, 0, 0, NULL}, /* %t */ @@ -1989,103 +2255,61 @@ static ClockFormatTokenMap FmtSTokenMap[] = { /* %Q */ {CFMTT_INT, NULL, 0, 0, 0, 0, 0, ClockFmtToken_StarDate_Proc, NULL}, - -#if 0 - /* %H %k %I %l */ - {CFMTT_INT, CLF_TIME, 1, 2, TclOffset(DateFormat, date.hour), - NULL}, - /* %M */ - {CFMTT_INT, CLF_TIME, 1, 2, TclOffset(DateFormat, date.minutes), - NULL}, - /* %S */ - {CFMTT_INT, CLF_TIME, 1, 2, TclOffset(DateFormat, date.secondOfDay), - NULL}, - /* %p %P */ - {CTOKT_PARSER, CLF_ISO8601, 0, 0, 0, - ClockFmtToken_amPmInd_Proc, NULL}, - /* %J */ - {CFMTT_INT, CLF_JULIANDAY, 1, 0xffff, TclOffset(DateFormat, date.julianDay), - NULL}, - /* %j */ - {CFMTT_INT, CLF_DAYOFYEAR, 1, 3, TclOffset(DateFormat, date.dayOfYear), - NULL}, - /* %g */ - {CFMTT_INT, CLF_ISO8601YEAR | CLF_ISO8601, 2, 2, TclOffset(DateFormat, date.iso8601Year), - NULL}, - /* %G */ - {CFMTT_INT, CLF_ISO8601YEAR | CLF_ISO8601 | CLF_ISO8601CENTURY, 4, 4, TclOffset(DateFormat, date.iso8601Year), - NULL}, - /* %V */ - {CFMTT_INT, CLF_ISO8601, 1, 2, TclOffset(DateFormat, date.iso8601Week), - NULL}, - /* %a %A %u %w */ - {CTOKT_PARSER, CLF_ISO8601, 0, 0, 0, - ClockFmtToken_DayOfWeek_Proc, NULL}, - /* %z %Z */ - {CTOKT_PARSER, CLF_OPTIONAL, 0, 0, 0, - ClockFmtToken_TimeZone_Proc, NULL}, - /* %s */ - {CFMTT_INT, CLF_LOCALSEC | CLF_SIGNED, 0, 1, 0xffff, TclOffset(DateFormat, date.localSeconds), - NULL}, -#endif }; static const char *FmtSTokenMapAliasIndex[2] = { - "hPW", - "bpU" + "hPWZ", + "bpUz" }; static const char *FmtETokenMapIndex = -"";// "Ey"; + "Ey"; static ClockFormatTokenMap FmtETokenMap[] = { - {CFMTT_INT, "0", 2, 0, 0, 0, 0, NULL}, -#if 0 /* %EE */ - {CTOKT_PARSER, 0, 0, 0, 0, TclOffset(DateFormat, date.year), - ClockFmtToken_LocaleERA_Proc, (void *)MCLIT_LOCALE_NUMERALS}, - /* %Ey */ - {CTOKT_PARSER, 0, 0, 0, 0, 0, /* currently no capture, parse only token */ - ClockFmtToken_LocaleListMatcher_Proc, (void *)MCLIT_LOCALE_NUMERALS}, -#endif + {CFMTT_INT, NULL, 0, 0, 0, 0, TclOffset(DateFormat, date.era), + ClockFmtToken_LocaleERA_Proc, NULL}, + /* %Ey %EC */ + {CFMTT_INT, NULL, 0, 0, 0, 0, TclOffset(DateFormat, date.year), + ClockFmtToken_LocaleERAYear_Proc, NULL}, }; static const char *FmtETokenMapAliasIndex[2] = { - "", - "" + "C", + "y" }; static const char *FmtOTokenMapIndex = -"";// "dmyHMSu"; + "dmyHIMSuw"; static ClockFormatTokenMap FmtOTokenMap[] = { - {CFMTT_INT, "0", 2, 0, 0, 0, 0, NULL}, -#if 0 /* %Od %Oe */ - {CTOKT_PARSER, CLF_DAYOFMONTH, 0, 0, 0, TclOffset(DateFormat, date.dayOfMonth), - ClockFmtToken_LocaleListMatcher_Proc, (void *)MCLIT_LOCALE_NUMERALS}, + {CFMTT_INT, NULL, 0, CLFMT_LOCALE_INDX, 0, 100, TclOffset(DateFormat, date.dayOfMonth), + NULL, (void *)MCLIT_LOCALE_NUMERALS}, /* %Om */ - {CTOKT_PARSER, CLF_MONTH, 0, 0, 0, TclOffset(DateFormat, date.month), - ClockFmtToken_LocaleListMatcher_Proc, (void *)MCLIT_LOCALE_NUMERALS}, + {CFMTT_INT, NULL, 0, CLFMT_LOCALE_INDX, 0, 100, TclOffset(DateFormat, date.month), + NULL, (void *)MCLIT_LOCALE_NUMERALS}, /* %Oy */ - {CTOKT_PARSER, CLF_YEAR, 0, 0, 0, TclOffset(DateFormat, date.year), - ClockFmtToken_LocaleListMatcher_Proc, (void *)MCLIT_LOCALE_NUMERALS}, - /* %OH %Ok %OI %Ol */ - {CTOKT_PARSER, CLF_TIME, 0, 0, 0, TclOffset(DateFormat, date.hour), - ClockFmtToken_LocaleListMatcher_Proc, (void *)MCLIT_LOCALE_NUMERALS}, + {CFMTT_INT, NULL, 0, CLFMT_LOCALE_INDX, 0, 100, TclOffset(DateFormat, date.year), + NULL, (void *)MCLIT_LOCALE_NUMERALS}, + /* %OH %Ok */ + {CFMTT_INT, NULL, 0, CLFMT_LOCALE_INDX, 3600, 24, TclOffset(DateFormat, date.secondOfDay), + NULL, (void *)MCLIT_LOCALE_NUMERALS}, + /* %OI %Ol */ + {CFMTT_INT, NULL, 0, CLFMT_CALC | CLFMT_LOCALE_INDX, 0, 0, TclOffset(DateFormat, date.secondOfDay), + ClockFmtToken_HourAMPM_Proc, (void *)MCLIT_LOCALE_NUMERALS}, /* %OM */ - {CTOKT_PARSER, CLF_TIME, 0, 0, 0, TclOffset(DateFormat, date.minutes), - ClockFmtToken_LocaleListMatcher_Proc, (void *)MCLIT_LOCALE_NUMERALS}, + {CFMTT_INT, NULL, 0, CLFMT_LOCALE_INDX, 60, 60, TclOffset(DateFormat, date.secondOfDay), + NULL, (void *)MCLIT_LOCALE_NUMERALS}, /* %OS */ - {CTOKT_PARSER, CLF_TIME, 0, 0, 0, TclOffset(DateFormat, date.secondOfDay), - ClockFmtToken_LocaleListMatcher_Proc, (void *)MCLIT_LOCALE_NUMERALS}, - /* %Ou Ow */ - {CTOKT_PARSER, CLF_ISO8601, 0, 0, 0, 0, - ClockFmtToken_DayOfWeek_Proc, (void *)MCLIT_LOCALE_NUMERALS}, -#endif + {CFMTT_INT, NULL, 0, CLFMT_LOCALE_INDX, 0, 60, TclOffset(DateFormat, date.secondOfDay), + NULL, (void *)MCLIT_LOCALE_NUMERALS}, + /* %Ou */ + {CFMTT_INT, NULL, 0, CLFMT_LOCALE_INDX, 0, 100, TclOffset(DateFormat, date.dayOfWeek), + NULL, (void *)MCLIT_LOCALE_NUMERALS}, + /* %Ow */ + {CFMTT_INT, NULL, 0, CLFMT_LOCALE_INDX, 0, 7, TclOffset(DateFormat, date.dayOfWeek), + NULL, (void *)MCLIT_LOCALE_NUMERALS}, }; static const char *FmtOTokenMapAliasIndex[2] = { -"", "" -#if 0 - "ekIlw", - "dHHHu" -#endif + "ekl", + "dHI" }; static ClockFormatTokenMap FmtWordTokenMap = { @@ -2232,7 +2456,14 @@ ClockFormat( return TCL_ERROR; } - dateFmt->resMem = ckalloc(MIN_FMT_RESULT_BLOCK_ALLOC); /* result container object */ + /* prepare formatting */ + dateFmt->date.secondOfDay = (int)(dateFmt->date.localSeconds % SECONDS_PER_DAY); + if (dateFmt->date.secondOfDay < 0) { + dateFmt->date.secondOfDay += SECONDS_PER_DAY; + } + + /* result container object */ + dateFmt->resMem = ckalloc(MIN_FMT_RESULT_BLOCK_ALLOC); if (dateFmt->resMem == NULL) { return TCL_ERROR; } @@ -2283,7 +2514,9 @@ ClockFormat( if (mcObj == NULL) { goto error; } - if (Tcl_ListObjIndex(opts->interp, mcObj, val, &mcObj) != TCL_OK) { + if ( Tcl_ListObjIndex(opts->interp, mcObj, val, &mcObj) != TCL_OK + || mcObj == NULL + ) { goto error; } s = TclGetString(mcObj); @@ -2297,7 +2530,11 @@ ClockFormat( if (1) { Tcl_WideInt val = *(Tcl_WideInt *)(((char *)dateFmt) + map->offs); if (FrmResultAllocate(dateFmt, 21) != TCL_OK) { goto error; }; - dateFmt->output += sprintf(dateFmt->output, map->tostr, val); + if (map->width) { + dateFmt->output = _witoaw(dateFmt->output, val, *map->tostr, map->width); + } else { + dateFmt->output += sprintf(dateFmt->output, map->tostr, val); + } } break; case CFMTT_CHAR: diff --git a/generic/tclDate.h b/generic/tclDate.h index c5d7da5..7c68b2a 100644 --- a/generic/tclDate.h +++ b/generic/tclDate.h @@ -109,6 +109,7 @@ typedef enum ClockMsgCtLiteral { MCLIT_MONTHS_FULL, MCLIT_MONTHS_ABBREV, MCLIT_MONTHS_COMB, MCLIT_DAYS_OF_WEEK_FULL, MCLIT_DAYS_OF_WEEK_ABBREV, MCLIT_DAYS_OF_WEEK_COMB, MCLIT_AM, MCLIT_PM, + MCLIT_LOCALE_ERAS, MCLIT_BCE, MCLIT_CE, MCLIT_BCE2, MCLIT_CE2, MCLIT_BCE3, MCLIT_CE3, @@ -121,6 +122,7 @@ typedef enum ClockMsgCtLiteral { pref "MONTHS_FULL", pref "MONTHS_ABBREV", pref "MONTHS_COMB", \ pref "DAYS_OF_WEEK_FULL", pref "DAYS_OF_WEEK_ABBREV", pref "DAYS_OF_WEEK_COMB", \ pref "AM", pref "PM", \ + pref "LOCALE_ERAS", \ pref "BCE", pref "CE", \ pref "b.c.e.", pref "c.e.", \ pref "b.c.", pref "a.d.", \ @@ -387,6 +389,8 @@ typedef struct DateFormat { char *output; TclDateFields date; + + Tcl_Obj *localeEra; } DateFormat; #define CLFMT_INCR (1 << 3) @@ -445,6 +449,11 @@ typedef struct ClockFmtScnStorage { MODULE_SCOPE time_t ToSeconds(time_t Hours, time_t Minutes, time_t Seconds, MERIDIAN Meridian); MODULE_SCOPE int IsGregorianLeapYear(TclDateFields *); +MODULE_SCOPE int ConvertUTCToLocal(ClientData clientData, Tcl_Interp *, + TclDateFields *, Tcl_Obj *timezoneObj, int); +MODULE_SCOPE Tcl_Obj * + LookupLastTransition(Tcl_Interp *, Tcl_WideInt, + int, Tcl_Obj *const *, Tcl_WideInt rangesVal[2]); MODULE_SCOPE int TclClockFreeScan(Tcl_Interp *interp, DateInfo *info); diff --git a/tests-perf/clock.perf.tcl b/tests-perf/clock.perf.tcl index 41cc9e1..043d27f 100644 --- a/tests-perf/clock.perf.tcl +++ b/tests-perf/clock.perf.tcl @@ -56,7 +56,7 @@ proc _test_out_total {} { puts [format "Total %d cases in %.2f sec.:" [llength $_(itcnt)] [expr {[llength $_(itcnt)] * $_(reptime) / 1000.0}]] lset _(m) 0 [format %.6f [expr [join $_(ittm) +]]] lset _(m) 2 [expr [join $_(itcnt) +]] - lset _(m) 4 [expr {[lindex $_(m) 2] / ([llength $_(itcnt)] * $_(reptime) / 1000.0)}] + lset _(m) 4 [format %.3f [expr {[lindex $_(m) 2] / ([llength $_(itcnt)] * $_(reptime) / 1000.0)}]] puts $_(m) puts "Average:" lset _(m) 0 [format %.6f [expr {[lindex $_(m) 0] / [llength $_(itcnt)]}]] @@ -95,6 +95,74 @@ proc _test_run {reptime lst {outcmd {puts $_(r)}}} { _test_out_total } +proc test-format {{reptime 1000}} { + _test_run $reptime { + # Format : date only (in gmt) + {clock format 1482525936 -format "%Y-%m-%d" -gmt 1} + # Format : date only (system zone) + {clock format 1482525936 -format "%Y-%m-%d"} + # Format : date only (CEST) + {clock format 1482525936 -format "%Y-%m-%d" -timezone :CET} + # Format : time only (in gmt) + {clock format 1482525936 -format "%H:%M" -gmt 1} + # Format : time only (system zone) + {clock format 1482525936 -format "%H:%M"} + # Format : time only (CEST) + {clock format 1482525936 -format "%H:%M" -timezone :CET} + # Format : time only (in gmt) + {clock format 1482525936 -format "%H:%M:%S" -gmt 1} + # Format : time only (system zone) + {clock format 1482525936 -format "%H:%M:%S"} + # Format : time only (CEST) + {clock format 1482525936 -format "%H:%M:%S" -timezone :CET} + # Format : default (in gmt) + {clock format 1482525936 -gmt 1} + # Format : default (system zone) + {clock format 1482525936} + # Format : default (CEST) + {clock format 1482525936 -timezone :CET} + # Format : ISO date-time (in gmt, numeric zone) + {clock format 1246379400 -format "%Y-%m-%dT%H:%M:%S %z" -gmt 1} + # Format : ISO date-time (system zone, CEST, numeric zone) + {clock format 1246379400 -format "%Y-%m-%dT%H:%M:%S %z"} + # Format : ISO date-time (CEST, numeric zone) + {clock format 1246379400 -format "%Y-%m-%dT%H:%M:%S %z" -timezone :CET} + # Format : ISO date-time (system zone, CEST) + {clock format 1246379400 -format "%Y-%m-%dT%H:%M:%S %Z"} + # Format : julian day with time (in gmt): + {clock format 1246379415 -format "%J %H:%M:%S" -gmt 1} + # Format : julian day with time (system zone): + {clock format 1246379415 -format "%J %H:%M:%S"} + + # Format : locale date-time (en): + {clock format 1246379415 -format "%x %X" -locale en} + # Format : locale date-time (de): + {clock format 1246379415 -format "%x %X" -locale de} + + # Format : locale lookup table month: + {clock format 1246379400 -format "%b" -locale en -gmt 1} + # Format : locale lookup 2 tables - month and day: + {clock format 1246379400 -format "%b %Od" -locale en -gmt 1} + + # Format : dynamic clock value (without converter caches): + {set i 0; continue} + {clock format [incr i] -format "%Y-%m-%dT%H:%M:%S" -locale en -gmt 1} + {puts [clock format $i -format "%Y-%m-%dT%H:%M:%S" -locale en -gmt 1]\n; continue} + # Format : dynamic clock value (without any converter caches, zone range overflow): + {set i 0; continue} + {clock format [incr i 86400] -format "%Y-%m-%dT%H:%M:%S" -locale en -gmt 1} + {puts [clock format $i -format "%Y-%m-%dT%H:%M:%S" -locale en -gmt 1]\n; continue} + + # Format : dynamic format (cacheable) + {clock format 1246379415 -format [string trim "%d.%m.%Y %H:%M:%S "] -gmt 1} + + # Format : all (in gmt, locale en) + {clock format 1482525936 -format "%%a = %a | %%A = %A | %%b = %b | %%h = %h | %%B = %B | %%C = %C | %%d = %d | %%e = %e | %%g = %g | %%G = %G | %%H = %H | %%I = %I | %%j = %j | %%J = %J | %%k = %k | %%l = %l | %%m = %m | %%M = %M | %%N = %N | %%p = %p | %%P = %P | %%Q = %Q | %%s = %s | %%S = %S | %%t = %t | %%u = %u | %%U = %U | %%V = %V | %%w = %w | %%W = %W | %%y = %y | %%Y = %Y | %%z = %z | %%Z = %Z | %%n = %n | %%EE = %EE | %%EC = %EC | %%Ey = %Ey | %%n = %n | %%Od = %Od | %%Oe = %Oe | %%OH = %OH | %%Ok = %Ok | %%OI = %OI | %%Ol = %Ol | %%Om = %Om | %%OM = %OM | %%OS = %OS | %%Ou = %Ou | %%Ow = %Ow | %%Oy = %Oy" -gmt 1 -locale en} + # Format : all (in CET, locale de) + {clock format 1482525936 -format "%%a = %a | %%A = %A | %%b = %b | %%h = %h | %%B = %B | %%C = %C | %%d = %d | %%e = %e | %%g = %g | %%G = %G | %%H = %H | %%I = %I | %%j = %j | %%J = %J | %%k = %k | %%l = %l | %%m = %m | %%M = %M | %%N = %N | %%p = %p | %%P = %P | %%Q = %Q | %%s = %s | %%S = %S | %%t = %t | %%u = %u | %%U = %U | %%V = %V | %%w = %w | %%W = %W | %%y = %y | %%Y = %Y | %%z = %z | %%Z = %Z | %%n = %n | %%EE = %EE | %%EC = %EC | %%Ey = %Ey | %%n = %n | %%Od = %Od | %%Oe = %Oe | %%OH = %OH | %%Ok = %Ok | %%OI = %OI | %%Ol = %Ol | %%Om = %Om | %%OM = %OM | %%OS = %OS | %%Ou = %Ou | %%Ow = %Ow | %%Oy = %Oy" -timezone :CET -locale de} + } +} + proc test-scan {{reptime 1000}} { _test_run $reptime { # Scan : date (in gmt) @@ -146,7 +214,7 @@ proc test-scan {{reptime 1000}} { # Scan : century, lookup table month {clock scan {1970 Jan 2} -format {%C%y %b %d} -locale en -gmt 1} # Scan : century, lookup table month and day (both entries are first) - {clock scan {1970 Jan 02} -format {%C%y %b %Od} -locale en -gmt 1} + {clock scan {1970 Jan 01} -format {%C%y %b %Od} -locale en -gmt 1} # Scan : century, lookup table month and day (list scan: entries with position 12 / 31) {clock scan {2016 Dec 31} -format {%C%y %b %Od} -locale en -gmt 1} @@ -235,8 +303,9 @@ proc test-other {{reptime 1000}} { proc test {{reptime 1000}} { puts "" + test-format $reptime test-scan $reptime - #test-freescan $reptime + test-freescan $reptime test-other $reptime puts \n**OK** -- cgit v0.12 From c97ddc73f6481193801401514372fb3df1993939 Mon Sep 17 00:00:00 2001 From: sebres Date: Tue, 10 Jan 2017 22:44:30 +0000 Subject: several missing scan tokens added, test cases extended and fixed; token "%s" used for seconds only (time zone independent), additionally "%Es" token added for local seconds (zone dependent seconds); --- generic/tclClock.c | 16 ++--- generic/tclClockFmt.c | 174 ++++++++++++++++++++++++++++++++++++++++---------- generic/tclDate.h | 16 ++++- tests/clock.test | 49 +++++++++++++- 4 files changed, 208 insertions(+), 47 deletions(-) diff --git a/generic/tclClock.c b/generic/tclClock.c index 28a484f..a3a9332 100644 --- a/generic/tclClock.c +++ b/generic/tclClock.c @@ -87,8 +87,6 @@ static int ClockConfigureObjCmd(ClientData clientData, static void GetYearWeekDay(TclDateFields *, int); static void GetGregorianEraYearDay(TclDateFields *, int); static void GetMonthDay(TclDateFields *); -static void GetJulianDayFromEraYearWeekDay(TclDateFields *, int); -static void GetJulianDayFromEraYearMonthDay(TclDateFields *, int); static int WeekdayOnOrBefore(int, int); static int ClockClicksObjCmd( ClientData clientData, Tcl_Interp *interp, @@ -2266,7 +2264,7 @@ GetMonthDay( *---------------------------------------------------------------------- */ -static void +MODULE_SCOPE void GetJulianDayFromEraYearWeekDay( TclDateFields *fields, /* Date to convert */ int changeover) /* Julian Day Number of the Gregorian @@ -2319,7 +2317,7 @@ GetJulianDayFromEraYearWeekDay( *---------------------------------------------------------------------- */ -static void +MODULE_SCOPE void GetJulianDayFromEraYearMonthDay( TclDateFields *fields, /* Date to convert */ int changeover) /* Gregorian transition date as a Julian Day */ @@ -2415,7 +2413,7 @@ GetJulianDayFromEraYearMonthDay( *---------------------------------------------------------------------- */ -static void +MODULE_SCOPE void GetJulianDayFromEraYearDay( TclDateFields *fields, /* Date to convert */ int changeover) /* Gregorian transition date as a Julian Day */ @@ -3169,9 +3167,11 @@ ClockScanObjCmd( + ( yySeconds % SECONDS_PER_DAY ); } - if (ConvertLocalToUTC(clientData, interp, &yydate, opts.timezoneObj, - GREGORIAN_CHANGE_DATE) != TCL_OK) { - goto done; + if (info->flags & (CLF_ASSEMBLE_SECONDS|CLF_ASSEMBLE_JULIANDAY|CLF_LOCALSEC)) { + if (ConvertLocalToUTC(clientData, interp, &yydate, opts.timezoneObj, + GREGORIAN_CHANGE_DATE) != TCL_OK) { + goto done; + } } /* Increment UTC seconds with relative time */ diff --git a/generic/tclClockFmt.c b/generic/tclClockFmt.c index 55e328c..7a6fa0b 100644 --- a/generic/tclClockFmt.c +++ b/generic/tclClockFmt.c @@ -50,7 +50,7 @@ _str2int( int sign) { register time_t val = 0, prev = 0; - if (sign > 0) { + if (sign >= 0) { while (p < e) { val = val * 10 + (*p++ - '0'); if (val < prev) { @@ -80,7 +80,7 @@ _str2wideInt( int sign) { register Tcl_WideInt val = 0, prev = 0; - if (sign > 0) { + if (sign >= 0) { while (p < e) { val = val * 10 + (*p++ - '0'); if (val < prev) { @@ -1296,13 +1296,91 @@ ClockScnToken_TimeZone_Proc(ClockFmtScnCmdArgs *opts, return TCL_OK; } +static int +ClockScnToken_StarDate_Proc(ClockFmtScnCmdArgs *opts, + DateInfo *info, ClockScanToken *tok) +{ + int minLen, maxLen; + register const char *p = yyInput, *end; const char *s; + time_t year, fractYear, fractDayDiv, fractDay; + static const char *stardatePref = "stardate "; + + DetermineGreedySearchLen(opts, info, tok, &minLen, &maxLen); + + end = yyInput + maxLen; + + /* stardate string */ + p = TclUtfFindEqualNCInLwr(p, end, stardatePref, stardatePref + 9, &s); + if (p >= end || p - yyInput < 9) { + return TCL_RETURN; + } + /* bypass spaces */ + while (p < end && isspace(UCHAR(*p))) { + p++; + } + if (p >= end) { + return TCL_RETURN; + } + /* currently positive stardate only */ + if (*p == '+') { p++; }; + s = p; + while (p < end && isdigit(UCHAR(*p))) { + p++; + } + if (p >= end || p - s < 4) { + return TCL_RETURN; + } + if ( _str2int(&year, s, p-3, 1) != TCL_OK + || _str2int(&fractYear, p-3, p, 1) != TCL_OK) { + return TCL_RETURN; + }; + if (*p++ != '.') { + return TCL_RETURN; + } + s = p; + fractDayDiv = 1; + while (p < end && isdigit(UCHAR(*p))) { + fractDayDiv *= 10; + p++; + } + if ( _str2int(&fractDay, s, p, 1) != TCL_OK) { + return TCL_RETURN; + }; + yyInput = p; + + /* Build a date from year and fraction. */ + + yydate.year = year + RODDENBERRY; + yydate.era = CE; + yydate.gregorian = 1; + + if (IsGregorianLeapYear(&yydate)) { + fractYear *= 366; + } else { + fractYear *= 365; + } + yydate.dayOfYear = fractYear / 1000 + 1; + if (fractYear % 1000 >= 500) { + yydate.dayOfYear++; + } + + GetJulianDayFromEraYearDay(&yydate, GREGORIAN_CHANGE_DATE); + + yydate.seconds = + -210866803200L + + ( SECONDS_PER_DAY * (Tcl_WideInt)yydate.julianDay ) + + ( SECONDS_PER_DAY * fractDay / fractDayDiv ); + + return TCL_OK; +} + static const char *ScnSTokenMapIndex = - "dmbyYHMSpJjCgGVazs"; + "dmbyYHMSpJjCgGVazUsntQ"; static ClockScanTokenMap ScnSTokenMap[] = { /* %d %e */ {CTOKT_DIGIT, CLF_DAYOFMONTH, 0, 1, 2, TclOffset(DateInfo, date.dayOfMonth), NULL}, - /* %m */ + /* %m %N */ {CTOKT_DIGIT, CLF_MONTH, 0, 1, 2, TclOffset(DateInfo, date.month), NULL}, /* %b %B %h */ @@ -1350,17 +1428,27 @@ static ClockScanTokenMap ScnSTokenMap[] = { /* %z %Z */ {CTOKT_PARSER, CLF_OPTIONAL, 0, 0, 0, 0, ClockScnToken_TimeZone_Proc, NULL}, + /* %U %W */ + {CTOKT_DIGIT, CLF_OPTIONAL, 0, 1, 2, 0, /* currently no capture, parse only token */ + NULL}, /* %s */ - {CTOKT_DIGIT, CLF_LOCALSEC | CLF_SIGNED, 0, 1, 0xffff, TclOffset(DateInfo, date.localSeconds), + {CTOKT_DIGIT, CLF_POSIXSEC | CLF_SIGNED, 0, 1, 0xffff, TclOffset(DateInfo, date.seconds), NULL}, + /* %n */ + {CTOKT_CHAR, 0, 0, 1, 1, 0, NULL, "\n"}, + /* %t */ + {CTOKT_CHAR, 0, 0, 1, 1, 0, NULL, "\t"}, + /* %Q */ + {CTOKT_PARSER, CLF_POSIXSEC, 0, 16, 30, 0, + ClockScnToken_StarDate_Proc, NULL}, }; static const char *ScnSTokenMapAliasIndex[2] = { - "eNBhkIlPAuwZ", - "dmbbHHHpaaaz" + "eNBhkIlPAuwZW", + "dmbbHHHpaaazU" }; static const char *ScnETokenMapIndex = - "Ey"; + "Eys"; static ClockScanTokenMap ScnETokenMap[] = { /* %EE */ {CTOKT_PARSER, 0, 0, 0, 0, TclOffset(DateInfo, date.year), @@ -1368,6 +1456,9 @@ static ClockScanTokenMap ScnETokenMap[] = { /* %Ey */ {CTOKT_PARSER, 0, 0, 0, 0, 0, /* currently no capture, parse only token */ ClockScnToken_LocaleListMatcher_Proc, (void *)MCLIT_LOCALE_NUMERALS}, + /* %Es */ + {CTOKT_DIGIT, CLF_LOCALSEC | CLF_SIGNED, 0, 1, 0xffff, TclOffset(DateInfo, date.localSeconds), + NULL}, }; static const char *ScnETokenMapAliasIndex[2] = { "", @@ -1427,7 +1518,10 @@ EstimateTokenCount( /* estimate token count by % char and format length */ tokcnt = 0; while (p <= end) { - if (*p++ == '%') tokcnt++; + if (*p++ == '%') { + tokcnt++; + p++; + } } p = fmt + tokcnt * 2; if (p < end) { @@ -1653,7 +1747,9 @@ ClockScan( map = tok->map; /* bypass spaces at begin of input before parsing each token */ if ( !(opts->flags & CLF_STRICT) - && (map->type != CTOKT_SPACE && map->type != CTOKT_WORD) + && ( map->type != CTOKT_SPACE + && map->type != CTOKT_WORD + && map->type != CTOKT_CHAR ) ) { while (p < end && isspace(UCHAR(*p))) { p++; @@ -1710,27 +1806,28 @@ ClockScan( if (size < map->minSize) { /* missing input -> error */ if ((map->flags & CLF_OPTIONAL)) { - yyInput = p; continue; } goto not_match; } /* string 2 number, put number into info structure by offset */ - p = yyInput; x = p + size; - if (!(map->flags & CLF_LOCALSEC)) { - if (_str2int((time_t *)(((char *)info) + map->offs), - p, x, sign) != TCL_OK) { - goto overflow; - } - p = x; - } else { - if (_str2wideInt((Tcl_WideInt *)(((char *)info) + map->offs), - p, x, sign) != TCL_OK) { - goto overflow; + if (map->offs) { + p = yyInput; x = p + size; + if (!(map->flags & (CLF_LOCALSEC|CLF_POSIXSEC))) { + if (_str2int((time_t *)(((char *)info) + map->offs), + p, x, sign) != TCL_OK) { + goto overflow; + } + p = x; + } else { + if (_str2wideInt((Tcl_WideInt *)(((char *)info) + map->offs), + p, x, sign) != TCL_OK) { + goto overflow; + } + p = x; } - p = x; + flags = (flags & ~map->clearFlags) | map->flags; } - flags = (flags & ~map->clearFlags) | map->flags; } break; case CTOKT_PARSER: @@ -1771,7 +1868,14 @@ ClockScan( goto not_match; } p = x; - continue; + break; + case CTOKT_CHAR: + x = (char *)map->data; + if (*x != *p) { + /* no match -> error */ + goto not_match; + } + p++; break; } } @@ -1802,7 +1906,7 @@ ClockScan( */ /* seconds token (%s) take precedence over all other tokens */ - if ((opts->flags & CLF_EXTENDED) || !(flags & CLF_LOCALSEC)) { + if ((opts->flags & CLF_EXTENDED) || !(flags & CLF_POSIXSEC)) { if (flags & CLF_DATE) { if (!(flags & CLF_JULIANDAY)) { @@ -1876,7 +1980,7 @@ ClockScan( } /* if no time - reset time */ - if (!(flags & (CLF_TIME|CLF_LOCALSEC))) { + if (!(flags & (CLF_TIME|CLF_LOCALSEC|CLF_POSIXSEC))) { info->flags |= CLF_ASSEMBLE_SECONDS; yydate.localSeconds = 0; } @@ -1886,7 +1990,7 @@ ClockScan( yySeconds = ToSeconds(yyHour, yyMinutes, yySeconds, yyMeridian); } else - if (!(flags & CLF_LOCALSEC)) { + if (!(flags & (CLF_LOCALSEC|CLF_POSIXSEC))) { info->flags |= CLF_ASSEMBLE_SECONDS; yySeconds = yydate.localSeconds % SECONDS_PER_DAY; } @@ -1996,7 +2100,7 @@ ClockFmtToken_StarDate_Proc( } /* Put together the StarDate as "Stardate %02d%03d.%1d" */ - if (FrmResultAllocate(dateFmt, 20) != TCL_OK) { return TCL_ERROR; }; + if (FrmResultAllocate(dateFmt, 30) != TCL_OK) { return TCL_ERROR; }; memcpy(dateFmt->output, "Stardate ", 9); dateFmt->output += 9; dateFmt->output = _itoaw(dateFmt->output, @@ -2005,7 +2109,7 @@ ClockFmtToken_StarDate_Proc( fractYear, '0', 3); *dateFmt->output++ = '.'; dateFmt->output = _itoaw(dateFmt->output, - dateFmt->date.localSeconds % SECONDS_PER_DAY / ( SECONDS_PER_DAY / 10 ), '0', 1); + dateFmt->date.seconds % SECONDS_PER_DAY / ( SECONDS_PER_DAY / 10 ), '0', 1); return TCL_OK; } @@ -2249,9 +2353,9 @@ static ClockFormatTokenMap FmtSTokenMap[] = { /* %s */ {CFMTT_WIDE, "0", 1, 0, 0, 0, TclOffset(DateFormat, date.seconds), NULL}, /* %n */ - {CFMTT_CHAR, "\n", 0, 0, 0, 0, 0, NULL}, + {CTOKT_CHAR, "\n", 0, 0, 0, 0, 0, NULL}, /* %t */ - {CFMTT_CHAR, "\t", 0, 0, 0, 0, 0, NULL}, + {CTOKT_CHAR, "\t", 0, 0, 0, 0, 0, NULL}, /* %Q */ {CFMTT_INT, NULL, 0, 0, 0, 0, 0, ClockFmtToken_StarDate_Proc, NULL}, @@ -2262,7 +2366,7 @@ static const char *FmtSTokenMapAliasIndex[2] = { }; static const char *FmtETokenMapIndex = - "Ey"; + "Eys"; static ClockFormatTokenMap FmtETokenMap[] = { /* %EE */ {CFMTT_INT, NULL, 0, 0, 0, 0, TclOffset(DateFormat, date.era), @@ -2270,6 +2374,8 @@ static ClockFormatTokenMap FmtETokenMap[] = { /* %Ey %EC */ {CFMTT_INT, NULL, 0, 0, 0, 0, TclOffset(DateFormat, date.year), ClockFmtToken_LocaleERAYear_Proc, NULL}, + /* %Es */ + {CFMTT_WIDE, "0", 1, 0, 0, 0, TclOffset(DateFormat, date.localSeconds), NULL}, }; static const char *FmtETokenMapAliasIndex[2] = { "C", @@ -2537,7 +2643,7 @@ ClockFormat( } } break; - case CFMTT_CHAR: + case CTOKT_CHAR: if (FrmResultAllocate(dateFmt, 1) != TCL_OK) { goto error; }; *dateFmt->output++ = *map->tostr; break; diff --git a/generic/tclDate.h b/generic/tclDate.h index 7c68b2a..2ce629d 100644 --- a/generic/tclDate.h +++ b/generic/tclDate.h @@ -33,9 +33,10 @@ #define CLF_OPTIONAL (1 << 0) /* token is non mandatory */ +#define CLF_POSIXSEC (1 << 1) +#define CLF_LOCALSEC (1 << 2) #define CLF_JULIANDAY (1 << 3) #define CLF_TIME (1 << 4) -#define CLF_LOCALSEC (1 << 5) #define CLF_CENTURY (1 << 6) #define CLF_DAYOFMONTH (1 << 7) #define CLF_DAYOFYEAR (1 << 8) @@ -355,8 +356,8 @@ typedef int ClockScanTokenProc( typedef enum _CLCKTOK_TYPE { - CTOKT_DIGIT = 1, CTOKT_PARSER, CTOKT_SPACE, CTOKT_WORD, - CFMTT_INT, CFMTT_WIDE, CFMTT_CHAR, CFMTT_PROC + CTOKT_DIGIT = 1, CTOKT_PARSER, CTOKT_SPACE, CTOKT_WORD, CTOKT_CHAR, + CFMTT_INT, CFMTT_WIDE, CFMTT_PROC } CLCKTOK_TYPE; typedef struct ClockScanTokenMap { @@ -449,6 +450,15 @@ typedef struct ClockFmtScnStorage { MODULE_SCOPE time_t ToSeconds(time_t Hours, time_t Minutes, time_t Seconds, MERIDIAN Meridian); MODULE_SCOPE int IsGregorianLeapYear(TclDateFields *); +MODULE_SCOPE void + GetJulianDayFromEraYearWeekDay( + TclDateFields *fields, int changeover); +MODULE_SCOPE void + GetJulianDayFromEraYearMonthDay( + TclDateFields *fields, int changeover); +MODULE_SCOPE void + GetJulianDayFromEraYearDay( + TclDateFields *fields, int changeover); MODULE_SCOPE int ConvertUTCToLocal(ClientData clientData, Tcl_Interp *, TclDateFields *, Tcl_Obj *timezoneObj, int); MODULE_SCOPE Tcl_Obj * diff --git a/tests/clock.test b/tests/clock.test index b27d2a3..4b0587a 100644 --- a/tests/clock.test +++ b/tests/clock.test @@ -18605,6 +18605,40 @@ test clock-6.19 {no token parsing} { [catch { clock scan "...%..." -format "...%%..." }] } {0 0} +test clock-6.20 {special char tokens %n, %t} { + clock scan "30\t06\t2009\n18\t30" -format "%d%t%m%t%Y%n%H%t%M" -gmt 1 +} 1246386600 + +# Hi, Jeff! +test clock-6.21.0 {Stardate 0 day} { + list [set d [clock format -757382400 -format "%Q" -gmt 1]] \ + [clock scan $d -format "%Q" -gmt 1] +} [list "Stardate 00000.0" -757382400] +test clock-6.21.1 {Stardate} { + list [set d [clock format 1482857280 -format "%Q" -gmt 1]] \ + [clock scan $d -format "%Q" -gmt 1] +} [list "Stardate 70986.7" 1482857280] +test clock-6.21.2 {Stardate next time} { + list [set d [clock format 1482865920 -format "%Q" -gmt 1]] \ + [clock scan $d -format "%Q" -gmt 1] +} [list "Stardate 70986.8" 1482865920] +test clock-6.21.3 {Stardate correct scan over year (leap year, begin, middle and end of the year)} -body { + set s [clock scan "01.01.2016" -f "%d.%m.%Y" -g 1] + set s [set i [clock scan [clock format $s -f "%Q" -g 1] -g 1]] + set wrong {} + while {[incr i 86400] < $s + 86400*366*2} { + set d [clock format $i -f "%Q" -g 1] + set i2 [clock scan $d -f "%Q" -g 1] + if {$i != $i2} { + lappend wrong "$d -- ($i != $i2) -- [clock format $i -g 1]" + } + } + join $wrong \n +} -result {} -cleanup { + unset -nocomplain wrong i i2 s d +} + + test clock-7.1 {Julian Day} { clock scan 0 -format %J -gmt true } -210866803200 @@ -36080,10 +36114,21 @@ test clock-37.1 {%s gmt testing} { set s [clock seconds] set a [clock format $s -format %s -gmt 0] set b [clock format $s -format %s -gmt 1] + set c [clock scan $s -format %s -gmt 0] + set d [clock scan $s -format %s -gmt 1] # %s, being the difference between local and Greenwich, does not # depend on the time zone. - set c [expr {$b-$a}] -} {0} + list [expr {$b-$a}] [expr {$d-$c}] +} {0 0} +test clock-37.2 {%Es gmt testing} { + set s [clock seconds] + set a [clock format $s -format %Es -timezone CET] + set b [clock format $s -format %Es -gmt 1] + set c [clock scan $s -format %Es -timezone CET] + set d [clock scan $s -format %Es -gmt 1] + # %Es depend on the time zone (local seconds instead of posix seconds). + list [expr {$b-$a}] [expr {$d-$c}] +} {-3600 3600} test clock-38.1 {regression - convertUTCToLocalViaC - east of Greenwich} \ -setup { -- cgit v0.12 From 4600d7c02647505afea5e1fdb0f3ae09ec0a8084 Mon Sep 17 00:00:00 2001 From: sebres Date: Tue, 10 Jan 2017 22:44:55 +0000 Subject: performance test cases ready --- tests-perf/clock.perf.tcl | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/tests-perf/clock.perf.tcl b/tests-perf/clock.perf.tcl index 043d27f..34d9429 100644 --- a/tests-perf/clock.perf.tcl +++ b/tests-perf/clock.perf.tcl @@ -97,6 +97,12 @@ proc _test_run {reptime lst {outcmd {puts $_(r)}}} { proc test-format {{reptime 1000}} { _test_run $reptime { + # Format : short, week only (in gmt) + {clock format 1482525936 -format "%u" -gmt 1} + # Format : short, week only (system zone) + {clock format 1482525936 -format "%u"} + # Format : short, week only (CEST) + {clock format 1482525936 -format "%u" -timezone :CET} # Format : date only (in gmt) {clock format 1482525936 -format "%Y-%m-%d" -gmt 1} # Format : date only (system zone) @@ -229,12 +235,6 @@ proc test-scan {{reptime 1000}} { {clock scan "25.11.2015 10:35:55" -format [string trim "%d.%m.%Y %H:%M:%S "] -base 0 -gmt 1} break - - # Scan : zone only - {clock scan "CET" -format "%z"} - {clock scan "EST" -format "%z"} - {**STOP** : Wed Nov 25 01:00:00 CET 2015} - # # Scan : long format test (allock chain) # {clock scan "25.11.2015" -format "%d.%m.%Y %d.%m.%Y %d.%m.%Y %d.%m.%Y %d.%m.%Y %d.%m.%Y %d.%m.%Y %d.%m.%Y" -base 0 -gmt 1} # # Scan : dynamic, very long format test (create obj representation, allock chain, GC, etc): @@ -293,7 +293,6 @@ proc test-other {{reptime 1000}} { # Scan : julian day (overflow) {catch {clock scan 5373485 -format %J}} - **STOP** # Scan : test rotate of GC objects (format is dynamic, so tcl-obj removed with last reference) {set i 0; time { clock scan "[incr i] - 25.11.2015" -format "$i - %d.%m.%Y" -base 0 -gmt 1 } 50} # Scan : test reusability of GC objects (format is dynamic, so tcl-obj removed with last reference) -- cgit v0.12 From 7a654297a08c44ecc24062e08b31343ffddd2bd6 Mon Sep 17 00:00:00 2001 From: sebres Date: Tue, 10 Jan 2017 22:45:29 +0000 Subject: small code review, performance test cases ready. --- generic/tclClock.c | 2 +- generic/tclClockFmt.c | 6 +++--- tests-perf/clock.perf.tcl | 32 ++++++++++++++++++++------------ 3 files changed, 24 insertions(+), 16 deletions(-) diff --git a/generic/tclClock.c b/generic/tclClock.c index a3a9332..7d4263c 100644 --- a/generic/tclClock.c +++ b/generic/tclClock.c @@ -3488,7 +3488,7 @@ ClockSecondsObjCmd( /* *---------------------------------------------------------------------- * - * TzsetIfNecessary -- + * TzsetGetEpoch --, TzsetIfNecessary -- * * Calls the tzset() library function if the contents of the TZ * environment variable has changed. diff --git a/generic/tclClockFmt.c b/generic/tclClockFmt.c index 7a6fa0b..307fc28 100644 --- a/generic/tclClockFmt.c +++ b/generic/tclClockFmt.c @@ -1366,7 +1366,7 @@ ClockScnToken_StarDate_Proc(ClockFmtScnCmdArgs *opts, GetJulianDayFromEraYearDay(&yydate, GREGORIAN_CHANGE_DATE); - yydate.seconds = + yydate.localSeconds = -210866803200L + ( SECONDS_PER_DAY * (Tcl_WideInt)yydate.julianDay ) + ( SECONDS_PER_DAY * fractDay / fractDayDiv ); @@ -1439,7 +1439,7 @@ static ClockScanTokenMap ScnSTokenMap[] = { /* %t */ {CTOKT_CHAR, 0, 0, 1, 1, 0, NULL, "\t"}, /* %Q */ - {CTOKT_PARSER, CLF_POSIXSEC, 0, 16, 30, 0, + {CTOKT_PARSER, CLF_LOCALSEC, 0, 16, 30, 0, ClockScnToken_StarDate_Proc, NULL}, }; static const char *ScnSTokenMapAliasIndex[2] = { @@ -2109,7 +2109,7 @@ ClockFmtToken_StarDate_Proc( fractYear, '0', 3); *dateFmt->output++ = '.'; dateFmt->output = _itoaw(dateFmt->output, - dateFmt->date.seconds % SECONDS_PER_DAY / ( SECONDS_PER_DAY / 10 ), '0', 1); + dateFmt->date.localSeconds % SECONDS_PER_DAY / ( SECONDS_PER_DAY / 10 ), '0', 1); return TCL_OK; } diff --git a/tests-perf/clock.perf.tcl b/tests-perf/clock.perf.tcl index 34d9429..f3b8a10 100644 --- a/tests-perf/clock.perf.tcl +++ b/tests-perf/clock.perf.tcl @@ -32,7 +32,7 @@ proc {**STOP**} {args} { } proc _test_get_commands {lst} { - regsub -all {(?:^|\n)[ \t]*(\#[^\n]*)(?=\n\s*[\{\#])} $lst "\n{\\1}" + regsub -all {(?:^|\n)[ \t]*(\#[^\n]*|\msetup\M[^\n]*|\mcleanup\M[^\n]*)(?=\n\s*(?:[\{\#]|setup|cleanup))} $lst "\n{\\1}" } proc _test_out_total {} { @@ -83,7 +83,11 @@ proc _test_run {reptime lst {outcmd {puts $_(r)}}} { foreach _(c) [_test_get_commands $lst] { puts "% [regsub -all {\n[ \t]*} $_(c) {; }]" - if {[regexp {\s*\#} $_(c)]} continue + if {[regexp {^\s*\#} $_(c)]} continue + if {[regexp {^\s*(?:setup|cleanup)\s+} $_(c)]} { + puts [if 1 [lindex $_(c) 1]] + continue + } set _(r) [if 1 $_(c)] if {$outcmd ne {}} $outcmd puts [set _(m) [timerate $_(c) $reptime]] @@ -122,11 +126,11 @@ proc test-format {{reptime 1000}} { # Format : time only (CEST) {clock format 1482525936 -format "%H:%M:%S" -timezone :CET} # Format : default (in gmt) - {clock format 1482525936 -gmt 1} + {clock format 1482525936 -gmt 1 -locale en} # Format : default (system zone) - {clock format 1482525936} + {clock format 1482525936 -locale en} # Format : default (CEST) - {clock format 1482525936 -timezone :CET} + {clock format 1482525936 -timezone :CET -locale en} # Format : ISO date-time (in gmt, numeric zone) {clock format 1246379400 -format "%Y-%m-%dT%H:%M:%S %z" -gmt 1} # Format : ISO date-time (system zone, CEST, numeric zone) @@ -149,15 +153,19 @@ proc test-format {{reptime 1000}} { {clock format 1246379400 -format "%b" -locale en -gmt 1} # Format : locale lookup 2 tables - month and day: {clock format 1246379400 -format "%b %Od" -locale en -gmt 1} + # Format : locale lookup 3 tables - week, month and day: + {clock format 1246379400 -format "%a %b %Od" -locale en -gmt 1} + # Format : locale lookup 4 tables - week, month, day and year: + {clock format 1246379400 -format "%a %b %Od %Oy" -locale en -gmt 1} # Format : dynamic clock value (without converter caches): - {set i 0; continue} - {clock format [incr i] -format "%Y-%m-%dT%H:%M:%S" -locale en -gmt 1} - {puts [clock format $i -format "%Y-%m-%dT%H:%M:%S" -locale en -gmt 1]\n; continue} + setup {set i 0} + {clock format [incr i] -format "%Y-%m-%dT%H:%M:%S" -locale en -timezone :CET} + cleanup {puts [clock format $i -format "%Y-%m-%dT%H:%M:%S" -locale en -timezone :CET]} # Format : dynamic clock value (without any converter caches, zone range overflow): - {set i 0; continue} - {clock format [incr i 86400] -format "%Y-%m-%dT%H:%M:%S" -locale en -gmt 1} - {puts [clock format $i -format "%Y-%m-%dT%H:%M:%S" -locale en -gmt 1]\n; continue} + setup {set i 0} + {clock format [incr i 86400] -format "%Y-%m-%dT%H:%M:%S" -locale en -timezone :CET} + cleanup {puts [clock format $i -format "%Y-%m-%dT%H:%M:%S" -locale en -timezone :CET]} # Format : dynamic format (cacheable) {clock format 1246379415 -format [string trim "%d.%m.%Y %H:%M:%S "] -gmt 1} @@ -310,4 +318,4 @@ proc test {{reptime 1000}} { puts \n**OK** } -test 100; # ms +test 500; # ms -- cgit v0.12 From 941e45f9078176fa27d4d7b627b2c4e1c6642d06 Mon Sep 17 00:00:00 2001 From: sebres Date: Tue, 10 Jan 2017 22:45:59 +0000 Subject: clock.tcl: clean unused resp. obsolete commands --- library/clock.tcl | 2578 +++++------------------------------------------------ library/init.tcl | 2 +- 2 files changed, 213 insertions(+), 2367 deletions(-) diff --git a/library/clock.tcl b/library/clock.tcl index 06aa10a..3caa270 100755 --- a/library/clock.tcl +++ b/library/clock.tcl @@ -389,152 +389,6 @@ proc ::tcl::clock::Initialize {} { {46800 0 3600 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0} :Pacific/Tongatapu }] - # Groups of fields that specify the date, priorities, and code bursts that - # determine Julian Day Number given those groups. The code in [clock - # scan] will choose the highest priority (lowest numbered) set of fields - # that determines the date. - - variable DateParseActions { - - { seconds } 0 {} - - { julianDay } 1 {} - - { era century yearOfCentury month dayOfMonth } 2 { - dict set date year [expr { 100 * [dict get $date century] - + [dict get $date yearOfCentury] }] - set date [GetJulianDayFromEraYearMonthDay $date[set date {}] \ - $changeover] - } - { era century yearOfCentury dayOfYear } 2 { - dict set date year [expr { 100 * [dict get $date century] - + [dict get $date yearOfCentury] }] - set date [GetJulianDayFromEraYearDay $date[set date {}] \ - $changeover] - } - - { century yearOfCentury month dayOfMonth } 3 { - dict set date era CE - dict set date year [expr { 100 * [dict get $date century] - + [dict get $date yearOfCentury] }] - set date [GetJulianDayFromEraYearMonthDay $date[set date {}] \ - $changeover] - } - { century yearOfCentury dayOfYear } 3 { - dict set date era CE - dict set date year [expr { 100 * [dict get $date century] - + [dict get $date yearOfCentury] }] - set date [GetJulianDayFromEraYearDay $date[set date {}] \ - $changeover] - } - { iso8601Century iso8601YearOfCentury iso8601Week dayOfWeek } 3 { - dict set date era CE - dict set date iso8601Year \ - [expr { 100 * [dict get $date iso8601Century] - + [dict get $date iso8601YearOfCentury] }] - set date [GetJulianDayFromEraYearWeekDay $date[set date {}] \ - $changeover] - } - - { yearOfCentury month dayOfMonth } 4 { - set date [InterpretTwoDigitYear $date[set date {}] $baseTime] - dict set date era CE - set date [GetJulianDayFromEraYearMonthDay $date[set date {}] \ - $changeover] - } - { yearOfCentury dayOfYear } 4 { - set date [InterpretTwoDigitYear $date[set date {}] $baseTime] - dict set date era CE - set date [GetJulianDayFromEraYearDay $date[set date {}] \ - $changeover] - } - { iso8601YearOfCentury iso8601Week dayOfWeek } 4 { - set date [InterpretTwoDigitYear \ - $date[set date {}] $baseTime \ - iso8601YearOfCentury iso8601Year] - dict set date era CE - set date [GetJulianDayFromEraYearWeekDay $date[set date {}] \ - $changeover] - } - - { month dayOfMonth } 5 { - set date [AssignBaseYear $date[set date {}] \ - $baseTime $timeZone $changeover] - set date [GetJulianDayFromEraYearMonthDay $date[set date {}] \ - $changeover] - } - { dayOfYear } 5 { - set date [AssignBaseYear $date[set date {}] \ - $baseTime $timeZone $changeover] - set date [GetJulianDayFromEraYearDay $date[set date {}] \ - $changeover] - } - { iso8601Week dayOfWeek } 5 { - set date [AssignBaseIso8601Year $date[set date {}] \ - $baseTime $timeZone $changeover] - set date [GetJulianDayFromEraYearWeekDay $date[set date {}] \ - $changeover] - } - - { dayOfMonth } 6 { - set date [AssignBaseMonth $date[set date {}] \ - $baseTime $timeZone $changeover] - set date [GetJulianDayFromEraYearMonthDay $date[set date {}] \ - $changeover] - } - - { dayOfWeek } 7 { - set date [AssignBaseWeek $date[set date {}] \ - $baseTime $timeZone $changeover] - set date [GetJulianDayFromEraYearWeekDay $date[set date {}] \ - $changeover] - } - - {} 8 { - set date [AssignBaseJulianDay $date[set date {}] \ - $baseTime $timeZone $changeover] - } - } - - # Groups of fields that specify time of day, priorities, and code that - # processes them - - variable TimeParseActions { - - seconds 1 {} - - { hourAMPM minute second amPmIndicator } 2 { - dict set date secondOfDay [InterpretHMSP $date] - } - { hour minute second } 2 { - dict set date secondOfDay [InterpretHMS $date] - } - - { hourAMPM minute amPmIndicator } 3 { - dict set date second 0 - dict set date secondOfDay [InterpretHMSP $date] - } - { hour minute } 3 { - dict set date second 0 - dict set date secondOfDay [InterpretHMS $date] - } - - { hourAMPM amPmIndicator } 4 { - dict set date minute 0 - dict set date second 0 - dict set date secondOfDay [InterpretHMSP $date] - } - { hour } 4 { - dict set date minute 0 - dict set date second 0 - dict set date secondOfDay [InterpretHMS $date] - } - - { } 5 { - dict set date secondOfDay 0 - } - } - # Legacy time zones, used primarily for parsing RFC822 dates. variable LegacyTimeZone [dict create \ @@ -667,2169 +521,281 @@ proc mcget {locale args} { #---------------------------------------------------------------------- # -# clock format -- -# -# Formats a count of seconds since the Posix Epoch as a time of day. -# -# The 'clock format' command formats times of day for output. Refer to the -# user documentation to see what it does. -# -#---------------------------------------------------------------------- - -proc ::tcl::clock::__org_format { args } { - - variable FormatProc - variable TZData - - lassign [ParseFormatArgs {*}$args] format locale timezone - set locale [string tolower $locale] - set clockval [lindex $args 0] - - # Build a procedure to format the result. Cache the built procedure's name - # in the 'FormatProc' array to avoid losing its internal representation, - # which contains the name resolution. - - set procName formatproc'$format'$locale - set procName [namespace current]::[string map {: {\:} \\ {\\}} $procName] - if {[info exists FormatProc($procName)]} { - set procName $FormatProc($procName) - } else { - set FormatProc($procName) \ - [ParseClockFormatFormat $procName $format $locale] - } - - return [$procName $clockval $timezone] - -} - -#---------------------------------------------------------------------- -# -# ParseClockFormatFormat -- -# -# Builds and caches a procedure that formats a time value. -# -# Parameters: -# format -- Format string to use -# locale -- Locale in which the format string is to be interpreted -# -# Results: -# Returns the name of the newly-built procedure. -# -#---------------------------------------------------------------------- - -proc ::tcl::clock::ParseClockFormatFormat {procName format locale} { - - if {[namespace which $procName] ne {}} { - return $procName - } - - # Map away the locale-dependent composite format groups - - set locale [EnterLocale $locale] - - # Change locale if a fresh locale has been given on the command line. - - try { - return [ParseClockFormatFormat2 $format $locale $procName] - } trap CLOCK {result opts} { - dict unset opts -errorinfo - return -options $opts $result - } -} - -proc ::tcl::clock::ParseClockFormatFormat2 {format locale procName} { - set didLocaleEra 0 - set didLocaleNumerals 0 - set preFormatCode \ - [string map [list @GREGORIAN_CHANGE_DATE@ \ - [mc GREGORIAN_CHANGE_DATE]] \ - { - variable TZData - set date [GetDateFields $clockval \ - $timezone \ - @GREGORIAN_CHANGE_DATE@] - }] - set formatString {} - set substituents {} - set state {} - - set format [LocalizeFormat $locale $format] - - foreach char [split $format {}] { - switch -exact -- $state { - {} { - if { [string equal % $char] } { - set state percent - } else { - append formatString $char - } - } - percent { # Character following a '%' character - set state {} - switch -exact -- $char { - % { # A literal character, '%' - append formatString %% - } - a { # Day of week, abbreviated - append formatString %s - append substituents \ - [string map \ - [list @DAYS_OF_WEEK_ABBREV@ \ - [list [mc DAYS_OF_WEEK_ABBREV]]] \ - { [lindex @DAYS_OF_WEEK_ABBREV@ \ - [expr {[dict get $date dayOfWeek] \ - % 7}]]}] - } - A { # Day of week, spelt out. - append formatString %s - append substituents \ - [string map \ - [list @DAYS_OF_WEEK_FULL@ \ - [list [mc DAYS_OF_WEEK_FULL]]] \ - { [lindex @DAYS_OF_WEEK_FULL@ \ - [expr {[dict get $date dayOfWeek] \ - % 7}]]}] - } - b - h { # Name of month, abbreviated. - append formatString %s - append substituents \ - [string map \ - [list @MONTHS_ABBREV@ \ - [list [mc MONTHS_ABBREV]]] \ - { [lindex @MONTHS_ABBREV@ \ - [expr {[dict get $date month]-1}]]}] - } - B { # Name of month, spelt out - append formatString %s - append substituents \ - [string map \ - [list @MONTHS_FULL@ \ - [list [mc MONTHS_FULL]]] \ - { [lindex @MONTHS_FULL@ \ - [expr {[dict get $date month]-1}]]}] - } - C { # Century number - append formatString %02d - append substituents \ - { [expr {[dict get $date year] / 100}]} - } - d { # Day of month, with leading zero - append formatString %02d - append substituents { [dict get $date dayOfMonth]} - } - e { # Day of month, without leading zero - append formatString %2d - append substituents { [dict get $date dayOfMonth]} - } - E { # Format group in a locale-dependent - # alternative era - set state percentE - if {!$didLocaleEra} { - append preFormatCode \ - [string map \ - [list @LOCALE_ERAS@ \ - [list [mc LOCALE_ERAS]]] \ - { - set date [GetLocaleEra \ - $date[set date {}] \ - @LOCALE_ERAS@]}] \n - set didLocaleEra 1 - } - if {!$didLocaleNumerals} { - append preFormatCode \ - [list set localeNumerals \ - [mc LOCALE_NUMERALS]] \n - set didLocaleNumerals 1 - } - } - g { # Two-digit year relative to ISO8601 - # week number - append formatString %02d - append substituents \ - { [expr { [dict get $date iso8601Year] % 100 }]} - } - G { # Four-digit year relative to ISO8601 - # week number - append formatString %02d - append substituents { [dict get $date iso8601Year]} - } - H { # Hour in the 24-hour day, leading zero - append formatString %02d - append substituents \ - { [expr { [dict get $date localSeconds] \ - / 3600 % 24}]} - } - I { # Hour AM/PM, with leading zero - append formatString %02d - append substituents \ - { [expr { ( ( ( [dict get $date localSeconds] \ - % 86400 ) \ - + 86400 \ - - 3600 ) \ - / 3600 ) \ - % 12 + 1 }] } - } - j { # Day of year (001-366) - append formatString %03d - append substituents { [dict get $date dayOfYear]} - } - J { # Julian Day Number - append formatString %07ld - append substituents { [dict get $date julianDay]} - } - k { # Hour (0-23), no leading zero - append formatString %2d - append substituents \ - { [expr { [dict get $date localSeconds] - / 3600 - % 24 }]} - } - l { # Hour (12-11), no leading zero - append formatString %2d - append substituents \ - { [expr { ( ( ( [dict get $date localSeconds] - % 86400 ) - + 86400 - - 3600 ) - / 3600 ) - % 12 + 1 }]} - } - m { # Month number, leading zero - append formatString %02d - append substituents { [dict get $date month]} - } - M { # Minute of the hour, leading zero - append formatString %02d - append substituents \ - { [expr { [dict get $date localSeconds] - / 60 - % 60 }]} - } - n { # A literal newline - append formatString \n - } - N { # Month number, no leading zero - append formatString %2d - append substituents { [dict get $date month]} - } - O { # A format group in the locale's - # alternative numerals - set state percentO - if {!$didLocaleNumerals} { - append preFormatCode \ - [list set localeNumerals \ - [mc LOCALE_NUMERALS]] \n - set didLocaleNumerals 1 - } - } - p { # Localized 'AM' or 'PM' indicator - # converted to uppercase - append formatString %s - append preFormatCode \ - [list set AM [string toupper [mc AM]]] \n \ - [list set PM [string toupper [mc PM]]] \n - append substituents \ - { [expr {(([dict get $date localSeconds] - % 86400) < 43200) ? - $AM : $PM}]} - } - P { # Localized 'AM' or 'PM' indicator - append formatString %s - append preFormatCode \ - [list set am [mc AM]] \n \ - [list set pm [mc PM]] \n - append substituents \ - { [expr {(([dict get $date localSeconds] - % 86400) < 43200) ? - $am : $pm}]} - - } - Q { # Hi, Jeff! - append formatString %s - append substituents { [FormatStarDate $date]} - } - s { # Seconds from the Posix Epoch - append formatString %s - append substituents { [dict get $date seconds]} - } - S { # Second of the minute, with - # leading zero - append formatString %02d - append substituents \ - { [expr { [dict get $date localSeconds] - % 60 }]} - } - t { # A literal tab character - append formatString \t - } - u { # Day of the week (1-Monday, 7-Sunday) - append formatString %1d - append substituents { [dict get $date dayOfWeek]} - } - U { # Week of the year (00-53). The - # first Sunday of the year is the - # first day of week 01 - append formatString %02d - append preFormatCode { - set dow [dict get $date dayOfWeek] - if { $dow == 7 } { - set dow 0 - } - incr dow - set UweekNumber \ - [expr { ( [dict get $date dayOfYear] - - $dow + 7 ) - / 7 }] - } - append substituents { $UweekNumber} - } - V { # The ISO8601 week number - append formatString %02d - append substituents { [dict get $date iso8601Week]} - } - w { # Day of the week (0-Sunday, - # 6-Saturday) - append formatString %1d - append substituents \ - { [expr { [dict get $date dayOfWeek] % 7 }]} - } - W { # Week of the year (00-53). The first - # Monday of the year is the first day - # of week 01. - append preFormatCode { - set WweekNumber \ - [expr { ( [dict get $date dayOfYear] - - [dict get $date dayOfWeek] - + 7 ) - / 7 }] - } - append formatString %02d - append substituents { $WweekNumber} - } - y { # The two-digit year of the century - append formatString %02d - append substituents \ - { [expr { [dict get $date year] % 100 }]} - } - Y { # The four-digit year - append formatString %04d - append substituents { [dict get $date year]} - } - z { # The time zone as hours and minutes - # east (+) or west (-) of Greenwich - append formatString %s - append substituents { [FormatNumericTimeZone \ - [dict get $date tzOffset]]} - } - Z { # The name of the time zone - append formatString %s - append substituents { [dict get $date tzName]} - } - % { # A literal percent character - append formatString %% - } - default { # An unknown escape sequence - append formatString %% $char - } - } - } - percentE { # Character following %E - set state {} - switch -exact -- $char { - E { - append formatString %s - append substituents { } \ - [string map \ - [list @BCE@ [list [mc BCE]] \ - @CE@ [list [mc CE]]] \ - {[dict get {BCE @BCE@ CE @CE@} \ - [dict get $date era]]}] - } - C { # Locale-dependent era - append formatString %s - append substituents { [dict get $date localeEra]} - } - y { # Locale-dependent year of the era - append preFormatCode { - set y [dict get $date localeYear] - if { $y >= 0 && $y < 100 } { - set Eyear [lindex $localeNumerals $y] - } else { - set Eyear $y - } - } - append formatString %s - append substituents { $Eyear} - } - default { # Unknown %E format group - append formatString %%E $char - } - } - } - percentO { # Character following %O - set state {} - switch -exact -- $char { - d - e { # Day of the month in alternative - # numerals - append formatString %s - append substituents \ - { [lindex $localeNumerals \ - [dict get $date dayOfMonth]]} - } - H - k { # Hour of the day in alternative - # numerals - append formatString %s - append substituents \ - { [lindex $localeNumerals \ - [expr { [dict get $date localSeconds] - / 3600 - % 24 }]]} - } - I - l { # Hour (12-11) AM/PM in alternative - # numerals - append formatString %s - append substituents \ - { [lindex $localeNumerals \ - [expr { ( ( ( [dict get $date localSeconds] - % 86400 ) - + 86400 - - 3600 ) - / 3600 ) - % 12 + 1 }]]} - } - m { # Month number in alternative numerals - append formatString %s - append substituents \ - { [lindex $localeNumerals [dict get $date month]]} - } - M { # Minute of the hour in alternative - # numerals - append formatString %s - append substituents \ - { [lindex $localeNumerals \ - [expr { [dict get $date localSeconds] - / 60 - % 60 }]]} - } - S { # Second of the minute in alternative - # numerals - append formatString %s - append substituents \ - { [lindex $localeNumerals \ - [expr { [dict get $date localSeconds] - % 60 }]]} - } - u { # Day of the week (Monday=1,Sunday=7) - # in alternative numerals - append formatString %s - append substituents \ - { [lindex $localeNumerals \ - [dict get $date dayOfWeek]]} - } - w { # Day of the week (Sunday=0,Saturday=6) - # in alternative numerals - append formatString %s - append substituents \ - { [lindex $localeNumerals \ - [expr { [dict get $date dayOfWeek] % 7 }]]} - } - y { # Year of the century in alternative - # numerals - append formatString %s - append substituents \ - { [lindex $localeNumerals \ - [expr { [dict get $date year] % 100 }]]} - } - default { # Unknown format group - append formatString %%O $char - } - } - } - } - } - - # Clean up any improperly terminated groups - - switch -exact -- $state { - percent { - append formatString %% - } - percentE { - append retval %%E - } - percentO { - append retval %%O - } - } - - proc $procName {clockval timezone} " - $preFormatCode - return \[::format [list $formatString] $substituents\] - " - - # puts [list $procName [info args $procName] [info body $procName]] - - return $procName -} - -#---------------------------------------------------------------------- -# -# clock scan -- -# -# Inputs a count of seconds since the Posix Epoch as a time of day. -# -# The 'clock format' command scans times of day on input. Refer to the user -# documentation to see what it does. -# -#---------------------------------------------------------------------- - -proc ::tcl::clock::__org_scan { args } { - - set format {} - - # Check the count of args - - if { [llength $args] < 1 || [llength $args] % 2 != 1 } { - set cmdName "clock scan" - return -code error \ - -errorcode [list CLOCK wrongNumArgs] \ - "wrong \# args: should be\ - \"$cmdName string\ - ?-base seconds?\ - ?-format string? ?-gmt boolean?\ - ?-locale LOCALE? ?-timezone ZONE?\"" - } - - # Set defaults - - set base [clock seconds] - set string [lindex $args 0] - set format {} - set gmt 0 - set locale c - if {[set timezone [configure -system-tz]] eq ""} { - set timezone [GetSystemTimeZone] - } - - # Pick up command line options. - - foreach { flag value } [lreplace $args 0 0] { - set saw($flag) {} - switch -exact -- $flag { - -b - -ba - -bas - -base { - set base $value - } - -f - -fo - -for - -form - -forma - -format { - set format $value - } - -g - -gm - -gmt { - set gmt $value - } - -l - -lo - -loc - -loca - -local - -locale { - set locale [string tolower $value] - } - -t - -ti - -tim - -time - -timez - -timezo - -timezon - -timezone { - set timezone $value - } - default { - return -code error \ - -errorcode [list CLOCK badOption $flag] \ - "bad option \"$flag\",\ - must be -base, -format, -gmt, -locale or -timezone" - } - } - } - - # Check options for validity - - if { [info exists saw(-gmt)] && [info exists saw(-timezone)] } { - return -code error \ - -errorcode [list CLOCK gmtWithTimezone] \ - "cannot use -gmt and -timezone in same call" - } - if { [catch { expr { wide($base) } } result] } { - return -code error "expected integer but got \"$base\"" - } - if { ![string is boolean -strict $gmt] } { - return -code error "expected boolean value but got \"$gmt\"" - } elseif { $gmt } { - set timezone :GMT - } - - # Change locale if a fresh locale has been given on the command line. - - EnterLocale $locale - - try { - # Map away the locale-dependent composite format groups - - set scanner [ParseClockScanFormat $format $locale] - return [$scanner $string $base $timezone] - } trap CLOCK {result opts} { - # Conceal location of generation of expected errors - dict unset opts -errorinfo - return -options $opts $result - } -} - -#---------------------------------------------------------------------- -# -# ParseClockScanFormat -- +# GetSystemLocale -- # -# Parses a format string given to [clock scan -format] +# Determines the system locale, which corresponds to "system" +# keyword for locale parameter of 'clock' command. # # Parameters: -# formatString - The format being parsed -# locale - The current locale +# None. # # Results: -# Constructs and returns a procedure that accepts the string being -# scanned, the base time, and the time zone. The procedure will either -# return the scanned time or else throw an error that should be rethrown -# to the caller of [clock scan] +# Returns the system locale. # # Side effects: -# The given procedure is defined in the ::tcl::clock namespace. Scan -# procedures are not deleted once installed. -# -# Why do we parse dates by defining a procedure to parse them? The reason is -# that by doing so, we have one convenient place to cache all the information: -# the regular expressions that match the patterns (which will be compiled), -# the code that assembles the date information, everything lands in one place. -# In this way, when a given format is reused at run time, all the information -# of how to apply it is available in a single place. +# None # #---------------------------------------------------------------------- -proc ::tcl::clock::ParseClockScanFormat {formatString locale} { - # Check whether the format has been parsed previously, and return the - # existing recognizer if it has. - - set procName scanproc'$formatString'$locale - set procName [namespace current]::[string map {: {\:} \\ {\\}} $procName] - if { [namespace which $procName] != {} } { - return $procName - } - - variable DateParseActions - variable TimeParseActions - - # Localize the %x, %X, etc. groups - - set formatString [LocalizeFormat $locale $formatString] - - # Condense whitespace - - regsub -all {[[:space:]]+} $formatString { } formatString - - # Walk through the groups of the format string. In this loop, we - # accumulate: - # - a regular expression that matches the string, - # - the count of capturing brackets in the regexp - # - a set of code that post-processes the fields captured by the regexp, - # - a dictionary whose keys are the names of fields that are present - # in the format string. - - set re {^[[:space:]]*} - set captureCount 0 - set postcode {} - set fieldSet [dict create] - set fieldCount 0 - set postSep {} - set state {} - - foreach c [split $formatString {}] { - switch -exact -- $state { - {} { - if { $c eq "%" } { - set state % - } elseif { $c eq " " } { - append re {[[:space:]]+} - } else { - if { ! [string is alnum $c] } { - append re "\\" - } - append re $c - } - } - % { - set state {} - switch -exact -- $c { - % { - append re % - } - { } { - append re "\[\[:space:\]\]*" - } - a - A { # Day of week, in words - set l {} - foreach \ - i {7 1 2 3 4 5 6} \ - abr [mc DAYS_OF_WEEK_ABBREV] \ - full [mc DAYS_OF_WEEK_FULL] { - dict set l [string tolower $abr] $i - dict set l [string tolower $full] $i - incr i - } - lassign [UniquePrefixRegexp $l] regex lookup - append re ( $regex ) - dict set fieldSet dayOfWeek [incr fieldCount] - append postcode "dict set date dayOfWeek \[" \ - "dict get " [list $lookup] " " \ - \[ {string tolower $field} [incr captureCount] \] \ - "\]\n" - } - b - B - h { # Name of month - set i 0 - set l {} - foreach \ - abr [mc MONTHS_ABBREV] \ - full [mc MONTHS_FULL] { - incr i - dict set l [string tolower $abr] $i - dict set l [string tolower $full] $i - } - lassign [UniquePrefixRegexp $l] regex lookup - append re ( $regex ) - dict set fieldSet month [incr fieldCount] - append postcode "dict set date month \[" \ - "dict get " [list $lookup] \ - " " \[ {string tolower $field} \ - [incr captureCount] \] \ - "\]\n" - } - C { # Gregorian century - append re \\s*(\\d\\d?) - dict set fieldSet century [incr fieldCount] - append postcode "dict set date century \[" \ - "::scan \$field" [incr captureCount] " %d" \ - "\]\n" - } - d - e { # Day of month - append re \\s*(\\d\\d?) - dict set fieldSet dayOfMonth [incr fieldCount] - append postcode "dict set date dayOfMonth \[" \ - "::scan \$field" [incr captureCount] " %d" \ - "\]\n" - } - E { # Prefix for locale-specific codes - set state %E - } - g { # ISO8601 2-digit year - append re \\s*(\\d\\d) - dict set fieldSet iso8601YearOfCentury \ - [incr fieldCount] - append postcode \ - "dict set date iso8601YearOfCentury \[" \ - "::scan \$field" [incr captureCount] " %d" \ - "\]\n" - } - G { # ISO8601 4-digit year - append re \\s*(\\d\\d)(\\d\\d) - dict set fieldSet iso8601Century [incr fieldCount] - dict set fieldSet iso8601YearOfCentury \ - [incr fieldCount] - append postcode \ - "dict set date iso8601Century \[" \ - "::scan \$field" [incr captureCount] " %d" \ - "\]\n" \ - "dict set date iso8601YearOfCentury \[" \ - "::scan \$field" [incr captureCount] " %d" \ - "\]\n" - } - H - k { # Hour of day - append re \\s*(\\d\\d?) - dict set fieldSet hour [incr fieldCount] - append postcode "dict set date hour \[" \ - "::scan \$field" [incr captureCount] " %d" \ - "\]\n" - } - I - l { # Hour, AM/PM - append re \\s*(\\d\\d?) - dict set fieldSet hourAMPM [incr fieldCount] - append postcode "dict set date hourAMPM \[" \ - "::scan \$field" [incr captureCount] " %d" \ - "\]\n" - } - j { # Day of year - append re \\s*(\\d\\d?\\d?) - dict set fieldSet dayOfYear [incr fieldCount] - append postcode "dict set date dayOfYear \[" \ - "::scan \$field" [incr captureCount] " %d" \ - "\]\n" - } - J { # Julian Day Number - append re \\s*(\\d+) - dict set fieldSet julianDay [incr fieldCount] - append postcode "dict set date julianDay \[" \ - "::scan \$field" [incr captureCount] " %ld" \ - "\]\n" - } - m - N { # Month number - append re \\s*(\\d\\d?) - dict set fieldSet month [incr fieldCount] - append postcode "dict set date month \[" \ - "::scan \$field" [incr captureCount] " %d" \ - "\]\n" - } - M { # Minute - append re \\s*(\\d\\d?) - dict set fieldSet minute [incr fieldCount] - append postcode "dict set date minute \[" \ - "::scan \$field" [incr captureCount] " %d" \ - "\]\n" - } - n { # Literal newline - append re \\n - } - O { # Prefix for locale numerics - set state %O - } - p - P { # AM/PM indicator - set l [list [string tolower [mc AM]] 0 \ - [string tolower [mc PM]] 1] - lassign [UniquePrefixRegexp $l] regex lookup - append re ( $regex ) - dict set fieldSet amPmIndicator [incr fieldCount] - append postcode "dict set date amPmIndicator \[" \ - "dict get " [list $lookup] " \[string tolower " \ - "\$field" \ - [incr captureCount] \ - "\]\]\n" - } - Q { # Hi, Jeff! - append re {Stardate\s+([-+]?\d+)(\d\d\d)[.](\d)} - incr captureCount - dict set fieldSet seconds [incr fieldCount] - append postcode {dict set date seconds } \[ \ - {ParseStarDate $field} [incr captureCount] \ - { $field} [incr captureCount] \ - { $field} [incr captureCount] \ - \] \n - } - s { # Seconds from Posix Epoch - # This next case is insanely difficult, because it's - # problematic to determine whether the field is - # actually within the range of a wide integer. - append re {\s*([-+]?\d+)} - dict set fieldSet seconds [incr fieldCount] - append postcode {dict set date seconds } \[ \ - {ScanWide $field} [incr captureCount] \] \n - } - S { # Second - append re \\s*(\\d\\d?) - dict set fieldSet second [incr fieldCount] - append postcode "dict set date second \[" \ - "::scan \$field" [incr captureCount] " %d" \ - "\]\n" - } - t { # Literal tab character - append re \\t - } - u - w { # Day number within week, 0 or 7 == Sun - # 1=Mon, 6=Sat - append re \\s*(\\d) - dict set fieldSet dayOfWeek [incr fieldCount] - append postcode {::scan $field} [incr captureCount] \ - { %d dow} \n \ - { - if { $dow == 0 } { - set dow 7 - } elseif { $dow > 7 } { - return -code error \ - -errorcode [list CLOCK badDayOfWeek] \ - "day of week is greater than 7" - } - dict set date dayOfWeek $dow - } - } - U { # Week of year. The first Sunday of - # the year is the first day of week - # 01. No scan rule uses this group. - append re \\s*\\d\\d? - } - V { # Week of ISO8601 year - - append re \\s*(\\d\\d?) - dict set fieldSet iso8601Week [incr fieldCount] - append postcode "dict set date iso8601Week \[" \ - "::scan \$field" [incr captureCount] " %d" \ - "\]\n" - } - W { # Week of the year (00-53). The first - # Monday of the year is the first day - # of week 01. No scan rule uses this - # group. - append re \\s*\\d\\d? - } - y { # Two-digit Gregorian year - append re \\s*(\\d\\d?) - dict set fieldSet yearOfCentury [incr fieldCount] - append postcode "dict set date yearOfCentury \[" \ - "::scan \$field" [incr captureCount] " %d" \ - "\]\n" - } - Y { # 4-digit Gregorian year - append re \\s*(\\d\\d)(\\d\\d) - dict set fieldSet century [incr fieldCount] - dict set fieldSet yearOfCentury [incr fieldCount] - append postcode \ - "dict set date century \[" \ - "::scan \$field" [incr captureCount] " %d" \ - "\]\n" \ - "dict set date yearOfCentury \[" \ - "::scan \$field" [incr captureCount] " %d" \ - "\]\n" - } - z - Z { # Time zone name - append re {(?:([-+]\d\d(?::?\d\d(?::?\d\d)?)?)|([[:alnum:]]{1,4}))} - dict set fieldSet tzName [incr fieldCount] - append postcode \ - {if } \{ { $field} [incr captureCount] \ - { ne "" } \} { } \{ \n \ - {dict set date tzName $field} \ - $captureCount \n \ - \} { else } \{ \n \ - {dict set date tzName } \[ \ - {ConvertLegacyTimeZone $field} \ - [incr captureCount] \] \n \ - \} \n \ - } - % { # Literal percent character - append re % - } - default { - append re % - if { ! [string is alnum $c] } { - append re \\ - } - append re $c - } - } - } - %E { - switch -exact -- $c { - C { # Locale-dependent era - set d {} - foreach triple [mc LOCALE_ERAS] { - lassign $triple t symbol year - dict set d [string tolower $symbol] $year - } - lassign [UniquePrefixRegexp $d] regex lookup - append re (?: $regex ) - } - E { - set l {} - dict set l [string tolower [mc BCE]] BCE - dict set l [string tolower [mc CE]] CE - dict set l b.c.e. BCE - dict set l c.e. CE - dict set l b.c. BCE - dict set l a.d. CE - lassign [UniquePrefixRegexp $l] regex lookup - append re ( $regex ) - dict set fieldSet era [incr fieldCount] - append postcode "dict set date era \["\ - "dict get " [list $lookup] \ - { } \[ {string tolower $field} \ - [incr captureCount] \] \ - "\]\n" - } - y { # Locale-dependent year of the era - lassign [LocaleNumeralMatcher $locale] regex lookup - append re $regex - incr captureCount - } - default { - append re %E - if { ! [string is alnum $c] } { - append re \\ - } - append re $c - } - } - set state {} - } - %O { - switch -exact -- $c { - d - e { - lassign [LocaleNumeralMatcher $locale] regex lookup - append re $regex - dict set fieldSet dayOfMonth [incr fieldCount] - append postcode "dict set date dayOfMonth \[" \ - "dict get " [list $lookup] " \$field" \ - [incr captureCount] \ - "\]\n" - } - H - k { - lassign [LocaleNumeralMatcher $locale] regex lookup - append re $regex - dict set fieldSet hour [incr fieldCount] - append postcode "dict set date hour \[" \ - "dict get " [list $lookup] " \$field" \ - [incr captureCount] \ - "\]\n" - } - I - l { - lassign [LocaleNumeralMatcher $locale] regex lookup - append re $regex - dict set fieldSet hourAMPM [incr fieldCount] - append postcode "dict set date hourAMPM \[" \ - "dict get " [list $lookup] " \$field" \ - [incr captureCount] \ - "\]\n" - } - m { - lassign [LocaleNumeralMatcher $locale] regex lookup - append re $regex - dict set fieldSet month [incr fieldCount] - append postcode "dict set date month \[" \ - "dict get " [list $lookup] " \$field" \ - [incr captureCount] \ - "\]\n" - } - M { - lassign [LocaleNumeralMatcher $locale] regex lookup - append re $regex - dict set fieldSet minute [incr fieldCount] - append postcode "dict set date minute \[" \ - "dict get " [list $lookup] " \$field" \ - [incr captureCount] \ - "\]\n" - } - S { - lassign [LocaleNumeralMatcher $locale] regex lookup - append re $regex - dict set fieldSet second [incr fieldCount] - append postcode "dict set date second \[" \ - "dict get " [list $lookup] " \$field" \ - [incr captureCount] \ - "\]\n" - } - u - w { - lassign [LocaleNumeralMatcher $locale] regex lookup - append re $regex - dict set fieldSet dayOfWeek [incr fieldCount] - append postcode "set dow \[dict get " [list $lookup] \ - { $field} [incr captureCount] \] \n \ - { - if { $dow == 0 } { - set dow 7 - } elseif { $dow > 7 } { - return -code error \ - -errorcode [list CLOCK badDayOfWeek] \ - "day of week is greater than 7" - } - dict set date dayOfWeek $dow - } - } - y { - lassign [LocaleNumeralMatcher $locale] regex lookup - append re $regex - dict set fieldSet yearOfCentury [incr fieldCount] - append postcode {dict set date yearOfCentury } \[ \ - {dict get } [list $lookup] { $field} \ - [incr captureCount] \] \n - } - default { - append re %O - if { ! [string is alnum $c] } { - append re \\ - } - append re $c - } - } - set state {} - } - } - } - - # Clean up any unfinished format groups - - append re $state \\s*\$ - - # Build the procedure - - set procBody {} - append procBody "variable ::tcl::clock::TZData" \n - append procBody "if \{ !\[ regexp -nocase [list $re] \$string ->" - for { set i 1 } { $i <= $captureCount } { incr i } { - append procBody " " field $i - } - append procBody "\] \} \{" \n - append procBody { - return -code error -errorcode [list CLOCK badInputString] \ - {input string does not match supplied format} - } - append procBody \}\n - append procBody "set date \[dict create\]" \n - append procBody {dict set date tzName $timeZone} \n - append procBody $postcode - append procBody [list set changeover [mc GREGORIAN_CHANGE_DATE]] \n - - # Set up the time zone before doing anything with a default base date - # that might need a timezone to interpret it. - - if { ![dict exists $fieldSet seconds] - && ![dict exists $fieldSet starDate] } { - if { [dict exists $fieldSet tzName] } { - append procBody { - set timeZone [dict get $date tzName] - } - } - append procBody { - set timeZone [::tcl::clock::SetupTimeZone $timeZone] - } - } - - # Add code that gets Julian Day Number from the fields. - - append procBody [MakeParseCodeFromFields $fieldSet $DateParseActions] - - # Get time of day - - append procBody [MakeParseCodeFromFields $fieldSet $TimeParseActions] - - # Assemble seconds from the Julian day and second of the day. - # Convert to local time unless epoch seconds or stardate are - # being processed - they're always absolute - - if { ![dict exists $fieldSet seconds] - && ![dict exists $fieldSet starDate] } { - append procBody { - if { [dict get $date julianDay] > 5373484 } { - return -code error -errorcode [list CLOCK dateTooLarge] \ - "requested date too large to represent" - } - dict set date localSeconds [expr { - -210866803200 - + ( 86400 * wide([dict get $date julianDay]) ) - + [dict get $date secondOfDay] - }] - } - - # Finally, convert the date to local time +proc ::tcl::clock::GetSystemLocale {} { + if { $::tcl_platform(platform) ne {windows} } { + # On a non-windows platform, the 'system' locale is the same as + # the 'current' locale - append procBody { - set date [::tcl::clock::ConvertLocalToUTC $date[set date {}] \ - $timeZone $changeover] - } + return [mclocale] } - # Return result - - append procBody {return [dict get $date seconds]} \n - - proc $procName { string baseTime timeZone } $procBody - - # puts [list proc $procName [list string baseTime timeZone] $procBody] - - return $procName -} + # On a windows platform, the 'system' locale is adapted from the + # 'current' locale by applying the date and time formats from the + # Control Panel. First, load the 'current' locale if it's not yet + # loaded -#---------------------------------------------------------------------- -# -# LocaleNumeralMatcher -- -# -# Composes a regexp that captures the numerals in the given locale, and -# a dictionary to map them to conventional numerals. -# -# Parameters: -# locale - Name of the current locale -# -# Results: -# Returns a two-element list comprising the regexp and the dictionary. -# -# Side effects: -# Caches the result. -# -#---------------------------------------------------------------------- + mcpackagelocale set [mclocale] -proc ::tcl::clock::LocaleNumeralMatcher {l} { - variable LocaleNumeralCache + # Make a new locale string for the system locale, and get the + # Control Panel information - if { ![dict exists $LocaleNumeralCache $l] } { - set d {} - set i 0 - set sep \( - foreach n [mc LOCALE_NUMERALS] { - dict set d $n $i - regsub -all {[^[:alnum:]]} $n \\\\& subex - append re $sep $subex - set sep | - incr i - } - append re \) - dict set LocaleNumeralCache $l [list $re $d] + set locale [mclocale]_windows + if { ! [mcpackagelocale present $locale] } { + LoadWindowsDateTimeFormats $locale } - return [dict get $LocaleNumeralCache $l] -} - - - -#---------------------------------------------------------------------- -# -# UniquePrefixRegexp -- -# -# Composes a regexp that performs unique-prefix matching. The RE -# matches one of a supplied set of strings, or any unique prefix -# thereof. -# -# Parameters: -# data - List of alternating match-strings and values. -# Match-strings with distinct values are considered -# distinct. -# -# Results: -# Returns a two-element list. The first is a regexp that matches any -# unique prefix of any of the strings. The second is a dictionary whose -# keys are match values from the regexp and whose values are the -# corresponding values from 'data'. -# -# Side effects: -# None. -# -#---------------------------------------------------------------------- - -proc ::tcl::clock::UniquePrefixRegexp { data } { - # The 'successors' dictionary will contain, for each string that is a - # prefix of any key, all characters that may follow that prefix. The - # 'prefixMapping' dictionary will have keys that are prefixes of keys and - # values that correspond to the keys. - - set prefixMapping [dict create] - set successors [dict create {} {}] - - # Walk the key-value pairs - - foreach { key value } $data { - # Construct all prefixes of the key; - - set prefix {} - foreach char [split $key {}] { - set oldPrefix $prefix - dict set successors $oldPrefix $char {} - append prefix $char - - # Put the prefixes in the 'prefixMapping' and 'successors' - # dictionaries - - dict lappend prefixMapping $prefix $value - if { ![dict exists $successors $prefix] } { - dict set successors $prefix {} - } - } - } - - # Identify those prefixes that designate unique values, and those that are - # the full keys - - set uniquePrefixMapping {} - dict for { key valueList } $prefixMapping { - if { [llength $valueList] == 1 } { - dict set uniquePrefixMapping $key [lindex $valueList 0] - } - } - foreach { key value } $data { - dict set uniquePrefixMapping $key $value - } - - # Construct the re. - - return [list \ - [MakeUniquePrefixRegexp $successors $uniquePrefixMapping {}] \ - $uniquePrefixMapping] -} - -#---------------------------------------------------------------------- -# -# MakeUniquePrefixRegexp -- -# -# Service procedure for 'UniquePrefixRegexp' that constructs a regular -# expresison that matches the unique prefixes. -# -# Parameters: -# successors - Dictionary whose keys are all prefixes -# of keys passed to 'UniquePrefixRegexp' and whose -# values are dictionaries whose keys are the characters -# that may follow those prefixes. -# uniquePrefixMapping - Dictionary whose keys are the unique -# prefixes and whose values are not examined. -# prefixString - Current prefix being processed. -# -# Results: -# Returns a constructed regular expression that matches the set of -# unique prefixes beginning with the 'prefixString'. -# -# Side effects: -# None. -# -#---------------------------------------------------------------------- - -proc ::tcl::clock::MakeUniquePrefixRegexp { successors - uniquePrefixMapping - prefixString } { - - # Get the characters that may follow the current prefix string - - set schars [lsort -ascii [dict keys [dict get $successors $prefixString]]] - if { [llength $schars] == 0 } { - return {} - } - - # If there is more than one successor character, or if the current prefix - # is a unique prefix, surround the generated re with non-capturing - # parentheses. - - set re {} - if { - [dict exists $uniquePrefixMapping $prefixString] - || [llength $schars] > 1 - } then { - append re "(?:" - } - - # Generate a regexp that matches the successors. - - set sep "" - foreach { c } $schars { - set nextPrefix $prefixString$c - regsub -all {[^[:alnum:]]} $c \\\\& rechar - append re $sep $rechar \ - [MakeUniquePrefixRegexp \ - $successors $uniquePrefixMapping $nextPrefix] - set sep | - } - - # If the current prefix is a unique prefix, make all following text - # optional. Otherwise, if there is more than one successor character, - # close the non-capturing parentheses. - - if { [dict exists $uniquePrefixMapping $prefixString] } { - append re ")?" - } elseif { [llength $schars] > 1 } { - append re ")" - } - - return $re -} - -#---------------------------------------------------------------------- -# -# MakeParseCodeFromFields -- -# -# Composes Tcl code to extract the Julian Day Number from a dictionary -# containing date fields. -# -# Parameters: -# dateFields -- Dictionary whose keys are fields of the date, -# and whose values are the rightmost positions -# at which those fields appear. -# parseActions -- List of triples: field set, priority, and -# code to emit. Smaller priorities are better, and -# the list must be in ascending order by priority -# -# Results: -# Returns a burst of code that extracts the day number from the given -# date. -# -# Side effects: -# None. -# -#---------------------------------------------------------------------- - -proc ::tcl::clock::MakeParseCodeFromFields { dateFields parseActions } { - - set currPrio 999 - set currFieldPos [list] - set currCodeBurst { - error "in ::tcl::clock::MakeParseCodeFromFields: can't happen" - } - - foreach { fieldSet prio parseAction } $parseActions { - # If we've found an answer that's better than any that follow, quit - # now. - - if { $prio > $currPrio } { - break - } - - # Accumulate the field positions that are used in the current field - # grouping. - - set fieldPos [list] - set ok true - foreach field $fieldSet { - if { ! [dict exists $dateFields $field] } { - set ok 0 - break - } - lappend fieldPos [dict get $dateFields $field] - } - - # Quit if we don't have a complete set of fields - if { !$ok } { - continue - } - - # Determine whether the current answer is better than the last. - - set fPos [lsort -integer -decreasing $fieldPos] - - if { $prio == $currPrio } { - foreach currPos $currFieldPos newPos $fPos { - if { - ![string is integer $newPos] - || ![string is integer $currPos] - || $newPos > $currPos - } then { - break - } - if { $newPos < $currPos } { - set ok 0 - break - } - } - } - if { !$ok } { - continue - } - - # Remember the best possibility for extracting date information - - set currPrio $prio - set currFieldPos $fPos - set currCodeBurst $parseAction - } - - return $currCodeBurst -} - -#---------------------------------------------------------------------- -# -# GetSystemTimeZone -- -# -# Determines the system time zone, which is the default for the -# 'clock' command if no other zone is supplied. -# -# Parameters: -# None. -# -# Results: -# Returns the system time zone. -# -# Side effects: -# Stores the sustem time zone in engine configuration, since -# determining it may be an expensive process. -# -#---------------------------------------------------------------------- - -proc ::tcl::clock::GetSystemLocale {} { - if { $::tcl_platform(platform) ne {windows} } { - # On a non-windows platform, the 'system' locale is the same as - # the 'current' locale - - return [mclocale] - } - - # On a windows platform, the 'system' locale is adapted from the - # 'current' locale by applying the date and time formats from the - # Control Panel. First, load the 'current' locale if it's not yet - # loaded - - mcpackagelocale set [mclocale] - - # Make a new locale string for the system locale, and get the - # Control Panel information - - set locale [mclocale]_windows - if { ! [mcpackagelocale present $locale] } { - LoadWindowsDateTimeFormats $locale - } - - return $locale -} - -#---------------------------------------------------------------------- -# -# EnterLocale -- -# -# Switch [mclocale] to a given locale if necessary -# -# Parameters: -# locale -- Desired locale -# -# Results: -# Returns the locale that was previously current. -# -# Side effects: -# Does [mclocale]. If necessary, loades the designated locale's files. -# -#---------------------------------------------------------------------- - -proc ::tcl::clock::EnterLocale { locale } { - switch -- $locale system { - set locale [GetSystemLocale] - } current { - set locale [mclocale] - } - # Select the locale, eventually load it - mcpackagelocale set $locale - return $locale -} - -#---------------------------------------------------------------------- -# -# LoadWindowsDateTimeFormats -- -# -# Load the date/time formats from the Control Panel in Windows and -# convert them so that they're usable by Tcl. -# -# Parameters: -# locale - Name of the locale in whose message catalog -# the converted formats are to be stored. -# -# Results: -# None. -# -# Side effects: -# Updates the given message catalog with the locale strings. -# -# Presumes that on entry, [mclocale] is set to the current locale, so that -# default strings can be obtained if the Registry query fails. -# -#---------------------------------------------------------------------- - -proc ::tcl::clock::LoadWindowsDateTimeFormats { locale } { - # Bail out if we can't find the Registry - - variable NoRegistry - if { [info exists NoRegistry] } return - - if { ![catch { - registry get "HKEY_CURRENT_USER\\Control Panel\\International" \ - sShortDate - } string] } { - set quote {} - set datefmt {} - foreach { unquoted quoted } [split $string '] { - append datefmt $quote [string map { - dddd %A - ddd %a - dd %d - d %e - MMMM %B - MMM %b - MM %m - M %N - yyyy %Y - yy %y - y %y - gg {} - } $unquoted] - if { $quoted eq {} } { - set quote ' - } else { - set quote $quoted - } - } - ::msgcat::mcset $locale DATE_FORMAT $datefmt - } - - if { ![catch { - registry get "HKEY_CURRENT_USER\\Control Panel\\International" \ - sLongDate - } string] } { - set quote {} - set ldatefmt {} - foreach { unquoted quoted } [split $string '] { - append ldatefmt $quote [string map { - dddd %A - ddd %a - dd %d - d %e - MMMM %B - MMM %b - MM %m - M %N - yyyy %Y - yy %y - y %y - gg {} - } $unquoted] - if { $quoted eq {} } { - set quote ' - } else { - set quote $quoted - } - } - ::msgcat::mcset $locale LOCALE_DATE_FORMAT $ldatefmt - } - - if { ![catch { - registry get "HKEY_CURRENT_USER\\Control Panel\\International" \ - sTimeFormat - } string] } { - set quote {} - set timefmt {} - foreach { unquoted quoted } [split $string '] { - append timefmt $quote [string map { - HH %H - H %k - hh %I - h %l - mm %M - m %M - ss %S - s %S - tt %p - t %p - } $unquoted] - if { $quoted eq {} } { - set quote ' - } else { - set quote $quoted - } - } - ::msgcat::mcset $locale TIME_FORMAT $timefmt - } - - catch { - ::msgcat::mcset $locale DATE_TIME_FORMAT "$datefmt $timefmt" - } - catch { - ::msgcat::mcset $locale LOCALE_DATE_TIME_FORMAT "$ldatefmt $timefmt" - } - - return - -} - -#---------------------------------------------------------------------- -# -# LocalizeFormat -- -# -# Map away locale-dependent format groups in a clock format. -# -# Parameters: -# locale -- Current [mclocale] locale, supplied to avoid -# an extra call -# format -- Format supplied to [clock scan] or [clock format] -# -# Results: -# Returns the string with locale-dependent composite format groups -# substituted out. -# -# Side effects: -# None. -# -#---------------------------------------------------------------------- - -proc ::tcl::clock::LocalizeFormat { locale format {fmtkey {}} } { - variable LocaleFormats - - if { $fmtkey eq {} } { set fmtkey FMT_$format } - if { [catch { - set locfmt [dict get $LocaleFormats $locale $fmtkey] - }] } { - - # get map list cached or build it: - if { [catch { - set mlst [dict get $LocaleFormats $locale MLST] - }] } { - - # message catalog dictionary: - set mcd [mcget $locale] - - # Handle locale-dependent format groups by mapping them out of the format - # string. Note that the order of the [string map] operations is - # significant because later formats can refer to later ones; for example - # %c can refer to %X, which in turn can refer to %T. - - set mlst { - %% %% - %D %m/%d/%Y - %+ {%a %b %e %H:%M:%S %Z %Y} - } - lappend mlst %EY [string map $mlst [dict get $mcd LOCALE_YEAR_FORMAT]] - lappend mlst %T [string map $mlst [dict get $mcd TIME_FORMAT_24_SECS]] - lappend mlst %R [string map $mlst [dict get $mcd TIME_FORMAT_24]] - lappend mlst %r [string map $mlst [dict get $mcd TIME_FORMAT_12]] - lappend mlst %X [string map $mlst [dict get $mcd TIME_FORMAT]] - lappend mlst %EX [string map $mlst [dict get $mcd LOCALE_TIME_FORMAT]] - lappend mlst %x [string map $mlst [dict get $mcd DATE_FORMAT]] - lappend mlst %Ex [string map $mlst [dict get $mcd LOCALE_DATE_FORMAT]] - lappend mlst %c [string map $mlst [dict get $mcd DATE_TIME_FORMAT]] - lappend mlst %Ec [string map $mlst [dict get $mcd LOCALE_DATE_TIME_FORMAT]] - - dict set LocaleFormats $locale MLST $mlst - } - - # translate copy of format (don't use format object here, because otherwise - # it can lose its internal representation (string map - convert to unicode) - set locfmt [string map $mlst [string range " $format" 1 end]] - - # cache it: - dict set LocaleFormats $locale $fmtkey $locfmt - } - - # Save original format as long as possible, because of internal - # representation (performance). - # Note that in this case such format will be never localized (also - # using another locales). To prevent this return a duplicate (but - # it may be slower). - if {$locfmt eq $format} { - set locfmt $format - } - - return $locfmt -} - -#---------------------------------------------------------------------- -# -# FormatNumericTimeZone -- -# -# Formats a time zone as +hhmmss -# -# Parameters: -# z - Time zone in seconds east of Greenwich -# -# Results: -# Returns the time zone formatted in a numeric form -# -# Side effects: -# None. -# -#---------------------------------------------------------------------- - -proc ::tcl::clock::FormatNumericTimeZone { z } { - if { $z < 0 } { - set z [expr { - $z }] - set retval - - } else { - set retval + - } - append retval [::format %02d [expr { $z / 3600 }]] - set z [expr { $z % 3600 }] - append retval [::format %02d [expr { $z / 60 }]] - set z [expr { $z % 60 }] - if { $z != 0 } { - append retval [::format %02d $z] - } - return $retval -} - -#---------------------------------------------------------------------- -# -# FormatStarDate -- -# -# Formats a date as a StarDate. -# -# Parameters: -# date - Dictionary containing 'year', 'dayOfYear', and -# 'localSeconds' fields. -# -# Results: -# Returns the given date formatted as a StarDate. -# -# Side effects: -# None. -# -# Jeff Hobbs put this in to support an atrocious pun about Tcl being -# "Enterprise ready." Now we're stuck with it. -# -#---------------------------------------------------------------------- - -proc ::tcl::clock::FormatStarDate { date } { - variable Roddenberry - - # Get day of year, zero based - - set doy [expr { [dict get $date dayOfYear] - 1 }] - - # Determine whether the year is a leap year - - set lp [IsGregorianLeapYear $date] - - # Convert day of year to a fractional year - - if { $lp } { - set fractYear [expr { 1000 * $doy / 366 }] - } else { - set fractYear [expr { 1000 * $doy / 365 }] - } - - # Put together the StarDate - - return [::format "Stardate %02d%03d.%1d" \ - [expr { [dict get $date year] - $Roddenberry }] \ - $fractYear \ - [expr { [dict get $date localSeconds] % 86400 - / ( 86400 / 10 ) }]] -} - -#---------------------------------------------------------------------- -# -# ParseStarDate -- -# -# Parses a StarDate -# -# Parameters: -# year - Year from the Roddenberry epoch -# fractYear - Fraction of a year specifiying the day of year. -# fractDay - Fraction of a day -# -# Results: -# Returns a count of seconds from the Posix epoch. -# -# Side effects: -# None. -# -# Jeff Hobbs put this in to support an atrocious pun about Tcl being -# "Enterprise ready." Now we're stuck with it. -# -#---------------------------------------------------------------------- - -proc ::tcl::clock::ParseStarDate { year fractYear fractDay } { - variable Roddenberry - - # Build a tentative date from year and fraction. - - set date [dict create \ - gregorian 1 \ - era CE \ - year [expr { $year + $Roddenberry }] \ - dayOfYear [expr { $fractYear * 365 / 1000 + 1 }]] - set date [GetJulianDayFromGregorianEraYearDay $date[set date {}]] - - # Determine whether the given year is a leap year - - set lp [IsGregorianLeapYear $date] - - # Reconvert the fractional year according to whether the given year is a - # leap year - - if { $lp } { - dict set date dayOfYear \ - [expr { $fractYear * 366 / 1000 + 1 }] - } else { - dict set date dayOfYear \ - [expr { $fractYear * 365 / 1000 + 1 }] - } - dict unset date julianDay - dict unset date gregorian - set date [GetJulianDayFromGregorianEraYearDay $date[set date {}]] - - return [expr { - 86400 * [dict get $date julianDay] - - 210866803200 - + ( 86400 / 10 ) * $fractDay - }] -} - -#---------------------------------------------------------------------- -# -# ScanWide -- -# -# Scans a wide integer from an input -# -# Parameters: -# str - String containing a decimal wide integer -# -# Results: -# Returns the string as a pure wide integer. Throws an error if the -# string is misformatted or out of range. -# -#---------------------------------------------------------------------- - -proc ::tcl::clock::ScanWide { str } { - set count [::scan $str {%ld %c} result junk] - if { $count != 1 } { - return -code error -errorcode [list CLOCK notAnInteger $str] \ - "\"$str\" is not an integer" - } - if { [incr result 0] != $str } { - return -code error -errorcode [list CLOCK integervalueTooLarge] \ - "integer value too large to represent" - } - return $result -} - -#---------------------------------------------------------------------- -# -# InterpretTwoDigitYear -- -# -# Given a date that contains only the year of the century, determines -# the target value of a two-digit year. -# -# Parameters: -# date - Dictionary containing fields of the date. -# baseTime - Base time relative to which the date is expressed. -# twoDigitField - Name of the field that stores the two-digit year. -# Default is 'yearOfCentury' -# fourDigitField - Name of the field that will receive the four-digit -# year. Default is 'year' -# -# Results: -# Returns the dictionary augmented with the four-digit year, stored in -# the given key. -# -# Side effects: -# None. -# -# The current rule for interpreting a two-digit year is that the year shall be -# between 1937 and 2037, thus staying within the range of a 32-bit signed -# value for time. This rule may change to a sliding window in future -# versions, so the 'baseTime' parameter (which is currently ignored) is -# provided in the procedure signature. -# -#---------------------------------------------------------------------- - -proc ::tcl::clock::InterpretTwoDigitYear { date baseTime - { twoDigitField yearOfCentury } - { fourDigitField year } } { - set yr [dict get $date $twoDigitField] - if { $yr >= [configure -century-switch] } { - incr yr -100 - } - incr yr [configure -year-century] - dict set date $fourDigitField $yr - return $date -} - -#---------------------------------------------------------------------- -# -# AssignBaseYear -- -# -# Places the number of the current year into a dictionary. -# -# Parameters: -# date - Dictionary value to update -# baseTime - Base time from which to extract the year, expressed -# in seconds from the Posix epoch -# timezone - the time zone in which the date is being scanned -# changeover - the Julian Day on which the Gregorian calendar -# was adopted in the target locale. -# -# Results: -# Returns the dictionary with the current year assigned. -# -# Side effects: -# None. -# -#---------------------------------------------------------------------- - -proc ::tcl::clock::AssignBaseYear { date baseTime timezone changeover } { - variable TZData - - # Find the Julian Day Number corresponding to the base time, and - # find the Gregorian year corresponding to that Julian Day. - - set date2 [GetDateFields $baseTime $timezone $changeover] - - # Store the converted year - - dict set date era [dict get $date2 era] - dict set date year [dict get $date2 year] - - return $date -} - -#---------------------------------------------------------------------- -# -# AssignBaseIso8601Year -- -# -# Determines the base year in the ISO8601 fiscal calendar. -# -# Parameters: -# date - Dictionary containing the fields of the date that -# is to be augmented with the base year. -# baseTime - Base time expressed in seconds from the Posix epoch. -# timeZone - Target time zone -# changeover - Julian Day of adoption of the Gregorian calendar in -# the target locale. -# -# Results: -# Returns the given date with "iso8601Year" set to the -# base year. -# -# Side effects: -# None. -# -#---------------------------------------------------------------------- - -proc ::tcl::clock::AssignBaseIso8601Year {date baseTime timeZone changeover} { - variable TZData - - # Find the Julian Day Number corresponding to the base time - - set date2 [GetDateFields $baseTime $timeZone $changeover] - - # Calculate the ISO8601 date and transfer the year - - dict set date era CE - dict set date iso8601Year [dict get $date2 iso8601Year] - return $date -} - -#---------------------------------------------------------------------- -# -# AssignBaseMonth -- -# -# Places the number of the current year and month into a -# dictionary. -# -# Parameters: -# date - Dictionary value to update -# baseTime - Time from which the year and month are to be -# obtained, expressed in seconds from the Posix epoch. -# timezone - Name of the desired time zone -# changeover - Julian Day on which the Gregorian calendar was adopted. -# -# Results: -# Returns the dictionary with the base year and month assigned. -# -# Side effects: -# None. -# -#---------------------------------------------------------------------- - -proc ::tcl::clock::AssignBaseMonth {date baseTime timezone changeover} { - variable TZData - - # Find the year and month corresponding to the base time - - set date2 [GetDateFields $baseTime $timezone $changeover] - dict set date era [dict get $date2 era] - dict set date year [dict get $date2 year] - dict set date month [dict get $date2 month] - return $date -} - -#---------------------------------------------------------------------- -# -# AssignBaseWeek -- -# -# Determines the base year and week in the ISO8601 fiscal calendar. -# -# Parameters: -# date - Dictionary containing the fields of the date that -# is to be augmented with the base year and week. -# baseTime - Base time expressed in seconds from the Posix epoch. -# changeover - Julian Day on which the Gregorian calendar was adopted -# in the target locale. -# -# Results: -# Returns the given date with "iso8601Year" set to the -# base year and "iso8601Week" to the week number. -# -# Side effects: -# None. -# -#---------------------------------------------------------------------- - -proc ::tcl::clock::AssignBaseWeek {date baseTime timeZone changeover} { - variable TZData - - # Find the Julian Day Number corresponding to the base time - - set date2 [GetDateFields $baseTime $timeZone $changeover] - - # Calculate the ISO8601 date and transfer the year - dict set date era CE - dict set date iso8601Year [dict get $date2 iso8601Year] - dict set date iso8601Week [dict get $date2 iso8601Week] - return $date + return $locale } #---------------------------------------------------------------------- # -# AssignBaseJulianDay -- +# EnterLocale -- # -# Determines the base day for a time-of-day conversion. +# Switch [mclocale] to a given locale if necessary # # Parameters: -# date - Dictionary that is to get the base day -# baseTime - Base time expressed in seconds from the Posix epoch -# changeover - Julian day on which the Gregorian calendar was -# adpoted in the target locale. +# locale -- Desired locale # # Results: -# Returns the given dictionary augmented with a 'julianDay' field -# that contains the base day. +# Returns the locale that was previously current. # # Side effects: -# None. +# Does [mclocale]. If necessary, loades the designated locale's files. # #---------------------------------------------------------------------- -proc ::tcl::clock::AssignBaseJulianDay { date baseTime timeZone changeover } { - variable TZData - - # Find the Julian Day Number corresponding to the base time - - set date2 [GetDateFields $baseTime $timeZone $changeover] - dict set date julianDay [dict get $date2 julianDay] - - return $date +proc ::tcl::clock::EnterLocale { locale } { + switch -- $locale system { + set locale [GetSystemLocale] + } current { + set locale [mclocale] + } + # Select the locale, eventually load it + mcpackagelocale set $locale + return $locale } #---------------------------------------------------------------------- # -# InterpretHMSP -- +# LoadWindowsDateTimeFormats -- # -# Interprets a time in the form "hh:mm:ss am". +# Load the date/time formats from the Control Panel in Windows and +# convert them so that they're usable by Tcl. # # Parameters: -# date -- Dictionary containing "hourAMPM", "minute", "second" -# and "amPmIndicator" fields. +# locale - Name of the locale in whose message catalog +# the converted formats are to be stored. # # Results: -# Returns the number of seconds from local midnight. +# None. # # Side effects: -# None. +# Updates the given message catalog with the locale strings. +# +# Presumes that on entry, [mclocale] is set to the current locale, so that +# default strings can be obtained if the Registry query fails. # #---------------------------------------------------------------------- -proc ::tcl::clock::InterpretHMSP { date } { - set hr [dict get $date hourAMPM] - if { $hr == 12 } { - set hr 0 +proc ::tcl::clock::LoadWindowsDateTimeFormats { locale } { + # Bail out if we can't find the Registry + + variable NoRegistry + if { [info exists NoRegistry] } return + + if { ![catch { + registry get "HKEY_CURRENT_USER\\Control Panel\\International" \ + sShortDate + } string] } { + set quote {} + set datefmt {} + foreach { unquoted quoted } [split $string '] { + append datefmt $quote [string map { + dddd %A + ddd %a + dd %d + d %e + MMMM %B + MMM %b + MM %m + M %N + yyyy %Y + yy %y + y %y + gg {} + } $unquoted] + if { $quoted eq {} } { + set quote ' + } else { + set quote $quoted + } + } + ::msgcat::mcset $locale DATE_FORMAT $datefmt + } + + if { ![catch { + registry get "HKEY_CURRENT_USER\\Control Panel\\International" \ + sLongDate + } string] } { + set quote {} + set ldatefmt {} + foreach { unquoted quoted } [split $string '] { + append ldatefmt $quote [string map { + dddd %A + ddd %a + dd %d + d %e + MMMM %B + MMM %b + MM %m + M %N + yyyy %Y + yy %y + y %y + gg {} + } $unquoted] + if { $quoted eq {} } { + set quote ' + } else { + set quote $quoted + } + } + ::msgcat::mcset $locale LOCALE_DATE_FORMAT $ldatefmt + } + + if { ![catch { + registry get "HKEY_CURRENT_USER\\Control Panel\\International" \ + sTimeFormat + } string] } { + set quote {} + set timefmt {} + foreach { unquoted quoted } [split $string '] { + append timefmt $quote [string map { + HH %H + H %k + hh %I + h %l + mm %M + m %M + ss %S + s %S + tt %p + t %p + } $unquoted] + if { $quoted eq {} } { + set quote ' + } else { + set quote $quoted + } + } + ::msgcat::mcset $locale TIME_FORMAT $timefmt + } + + catch { + ::msgcat::mcset $locale DATE_TIME_FORMAT "$datefmt $timefmt" } - if { [dict get $date amPmIndicator] } { - incr hr 12 + catch { + ::msgcat::mcset $locale LOCALE_DATE_TIME_FORMAT "$ldatefmt $timefmt" } - dict set date hour $hr - return [InterpretHMS $date[set date {}]] + + return + } #---------------------------------------------------------------------- # -# InterpretHMS -- +# LocalizeFormat -- # -# Interprets a 24-hour time "hh:mm:ss" +# Map away locale-dependent format groups in a clock format. # # Parameters: -# date -- Dictionary containing the "hour", "minute" and "second" -# fields. +# locale -- Current [mclocale] locale, supplied to avoid +# an extra call +# format -- Format supplied to [clock scan] or [clock format] # # Results: -# Returns the given dictionary augmented with a "secondOfDay" -# field containing the number of seconds from local midnight. +# Returns the string with locale-dependent composite format groups +# substituted out. # # Side effects: # None. # #---------------------------------------------------------------------- -proc ::tcl::clock::InterpretHMS { date } { - return [expr { - ( [dict get $date hour] * 60 - + [dict get $date minute] ) * 60 - + [dict get $date second] - }] +proc ::tcl::clock::LocalizeFormat { locale format {fmtkey {}} } { + variable LocaleFormats + + if { $fmtkey eq {} } { set fmtkey FMT_$format } + if { [catch { + set locfmt [dict get $LocaleFormats $locale $fmtkey] + }] } { + + # get map list cached or build it: + if { [catch { + set mlst [dict get $LocaleFormats $locale MLST] + }] } { + + # message catalog dictionary: + set mcd [mcget $locale] + + # Handle locale-dependent format groups by mapping them out of the format + # string. Note that the order of the [string map] operations is + # significant because later formats can refer to later ones; for example + # %c can refer to %X, which in turn can refer to %T. + + set mlst { + %% %% + %D %m/%d/%Y + %+ {%a %b %e %H:%M:%S %Z %Y} + } + lappend mlst %EY [string map $mlst [dict get $mcd LOCALE_YEAR_FORMAT]] + lappend mlst %T [string map $mlst [dict get $mcd TIME_FORMAT_24_SECS]] + lappend mlst %R [string map $mlst [dict get $mcd TIME_FORMAT_24]] + lappend mlst %r [string map $mlst [dict get $mcd TIME_FORMAT_12]] + lappend mlst %X [string map $mlst [dict get $mcd TIME_FORMAT]] + lappend mlst %EX [string map $mlst [dict get $mcd LOCALE_TIME_FORMAT]] + lappend mlst %x [string map $mlst [dict get $mcd DATE_FORMAT]] + lappend mlst %Ex [string map $mlst [dict get $mcd LOCALE_DATE_FORMAT]] + lappend mlst %c [string map $mlst [dict get $mcd DATE_TIME_FORMAT]] + lappend mlst %Ec [string map $mlst [dict get $mcd LOCALE_DATE_TIME_FORMAT]] + + dict set LocaleFormats $locale MLST $mlst + } + + # translate copy of format (don't use format object here, because otherwise + # it can lose its internal representation (string map - convert to unicode) + set locfmt [string map $mlst [string range " $format" 1 end]] + + # cache it: + dict set LocaleFormats $locale $fmtkey $locfmt + } + + # Save original format as long as possible, because of internal + # representation (performance). + # Note that in this case such format will be never localized (also + # using another locales). To prevent this return a duplicate (but + # it may be slower). + if {$locfmt eq $format} { + set locfmt $format + } + + return $locfmt } #---------------------------------------------------------------------- @@ -2891,38 +857,6 @@ proc ::tcl::clock::GetSystemTimeZone {} { #---------------------------------------------------------------------- # -# ConvertLegacyTimeZone -- -# -# Given an alphanumeric time zone identifier and the system time zone, -# convert the alphanumeric identifier to an unambiguous time zone. -# -# Parameters: -# tzname - Name of the time zone to convert -# -# Results: -# Returns a time zone name corresponding to tzname, but in an -# unambiguous form, generally +hhmm. -# -# This procedure is implemented primarily to allow the parsing of RFC822 -# date/time strings. Processing a time zone name on input is not recommended -# practice, because there is considerable room for ambiguity; for instance, is -# BST Brazilian Standard Time, or British Summer Time? -# -#---------------------------------------------------------------------- - -proc ::tcl::clock::ConvertLegacyTimeZone { tzname } { - variable LegacyTimeZone - - set tzname [string tolower $tzname] - if { ![dict exists $LegacyTimeZone $tzname] } { - return -code error -errorcode [list CLOCK badTZName $tzname] \ - "time zone \"$tzname\" not found" - } - return [dict get $LegacyTimeZone $tzname] -} - -#---------------------------------------------------------------------- -# # SetupTimeZone -- # # Given the name or specification of a time zone, sets up its in-memory @@ -3837,43 +1771,6 @@ proc ::tcl::clock::DeterminePosixDSTTime { z bound y } { #---------------------------------------------------------------------- # -# GetLocaleEra -- -# -# Given local time expressed in seconds from the Posix epoch, -# determine localized era and year within the era. -# -# Parameters: -# date - Dictionary that must contain the keys, 'localSeconds', -# whose value is expressed as the appropriate local time; -# and 'year', whose value is the Gregorian year. -# etable - Value of the LOCALE_ERAS key in the message catalogue -# for the target locale. -# -# Results: -# Returns the dictionary, augmented with the keys, 'localeEra' and -# 'localeYear'. -# -#---------------------------------------------------------------------- - -proc ::tcl::clock::GetLocaleEra { date etable } { - set index [BSearch $etable [dict get $date localSeconds]] - if { $index < 0} { - dict set date localeEra \ - [::format %02d [expr { [dict get $date year] / 100 }]] - dict set date localeYear [expr { - [dict get $date year] % 100 - }] - } else { - dict set date localeEra [lindex $etable $index 1] - dict set date localeYear [expr { - [dict get $date year] - [lindex $etable $index 2] - }] - } - return $date -} - -#---------------------------------------------------------------------- -# # GetJulianDayFromEraYearDay -- # # Given a year, month and day on the Gregorian calendar, determines @@ -4051,57 +1948,6 @@ proc ::tcl::clock::WeekdayOnOrBefore { weekday j } { #---------------------------------------------------------------------- # -# BSearch -- -# -# Service procedure that does binary search in several places inside the -# 'clock' command. -# -# Parameters: -# list - List of lists, sorted in ascending order by the -# first elements -# key - Value to search for -# -# Results: -# Returns the index of the greatest element in $list that is less than -# or equal to $key. -# -# Side effects: -# None. -# -#---------------------------------------------------------------------- - -proc ::tcl::clock::BSearch { list key } { - if {[llength $list] == 0} { - return -1 - } - if { $key < [lindex $list 0 0] } { - return -1 - } - - set l 0 - set u [expr { [llength $list] - 1 }] - - while { $l < $u } { - # At this point, we know that - # $k >= [lindex $list $l 0] - # Either $u == [llength $list] or else $k < [lindex $list $u+1 0] - # We find the midpoint of the interval {l,u} rounded UP, compare - # against it, and set l or u to maintain the invariant. Note that the - # interval shrinks at each step, guaranteeing convergence. - - set m [expr { ( $l + $u + 1 ) / 2 }] - if { $key >= [lindex $list $m 0] } { - set l $m - } else { - set u [expr { $m - 1 }] - } - } - - return $l -} - -#---------------------------------------------------------------------- -# # clock add -- # # Adds an offset to a given time. diff --git a/library/init.tcl b/library/init.tcl index 6f34302..f1f1bb4 100644 --- a/library/init.tcl +++ b/library/init.tcl @@ -178,7 +178,7 @@ if {[interp issafe]} { # Auto-loading stubs for 'clock.tcl' - foreach cmd {add LocalizeFormat SetupTimeZone GetSystemTimeZone} { + foreach cmd {add mcget LocalizeFormat SetupTimeZone GetSystemTimeZone} { proc ::tcl::clock::$cmd args { variable TclLibDir source -encoding utf-8 [file join $TclLibDir clock.tcl] -- cgit v0.12 From 866efbc90481ea60325dd2439e321f0d8280c826 Mon Sep 17 00:00:00 2001 From: sebres Date: Tue, 10 Jan 2017 22:52:12 +0000 Subject: some greedy matches are fixed (see test cases clock-6.22.11 and clock-6.22.12), involving space count in look ahead and end distance calculation (because spaces are optional in date-time string as well as in scanning format). --- generic/tclClockFmt.c | 121 ++++++++++++++++++++++++++++++++------------------ generic/tclDate.h | 2 + tests/clock.test | 37 +++++++++++++++ 3 files changed, 117 insertions(+), 43 deletions(-) diff --git a/generic/tclClockFmt.c b/generic/tclClockFmt.c index 307fc28..00ea0ed 100644 --- a/generic/tclClockFmt.c +++ b/generic/tclClockFmt.c @@ -723,24 +723,36 @@ inline void DetermineGreedySearchLen(ClockFmtScnCmdArgs *opts, DateInfo *info, ClockScanToken *tok, int *minLen, int *maxLen) { - register const char*p = yyInput; + register const char *p = yyInput, + *end = info->dateEnd; *minLen = 0; - /* max length to the end regarding distance to end (min-width of following tokens) */ - *maxLen = info->dateEnd - p - tok->endDistance; - /* if no tokens anymore */ - if (!(tok+1)->map) { - /* should match to end or first space */ - while (!isspace(UCHAR(*p)) && ++p < info->dateEnd) {}; - *minLen = p - yyInput; - } else - /* next token is a word */ - if ((tok+1)->map->type == CTOKT_WORD) { - /* should match at least to the first char of this word */ - while (*p != *((tok+1)->tokWord.start) && ++p < info->dateEnd) {}; - *minLen = p - yyInput; + /* if still tokens available */ + if ((tok+1)->map) { + end -= tok->endDistance + yySpaceCount; + /* next token is a word */ + switch ((tok+1)->map->type) { + case CTOKT_WORD: + /* should match at least to the first char of this word */ + while (*p != *((tok+1)->tokWord.start) && ++p < end) {}; + *minLen = p - yyInput; + break; + case CTOKT_CHAR: + while (*p != *((char *)(tok+1)->map->data) && ++p < end) {}; + *minLen = p - yyInput; + break; + } } + /* max length to the end regarding distance to end (min-width of following tokens) */ + *maxLen = end - p; + if (*maxLen > tok->map->maxSize) { + *maxLen = tok->map->maxSize; + }; + + if (*minLen < tok->map->minSize) { + *minLen = tok->map->minSize; + } if (*minLen > *maxLen) { *maxLen = *minLen; } @@ -1384,7 +1396,7 @@ static ClockScanTokenMap ScnSTokenMap[] = { {CTOKT_DIGIT, CLF_MONTH, 0, 1, 2, TclOffset(DateInfo, date.month), NULL}, /* %b %B %h */ - {CTOKT_PARSER, CLF_MONTH, 0, 0, 0, 0, + {CTOKT_PARSER, CLF_MONTH, 0, 0, 0xffff, 0, ClockScnToken_Month_Proc}, /* %y */ {CTOKT_DIGIT, CLF_YEAR, 0, 1, 2, TclOffset(DateInfo, date.year), @@ -1402,7 +1414,7 @@ static ClockScanTokenMap ScnSTokenMap[] = { {CTOKT_DIGIT, CLF_TIME, 0, 1, 2, TclOffset(DateInfo, date.secondOfDay), NULL}, /* %p %P */ - {CTOKT_PARSER, CLF_ISO8601, 0, 0, 0, 0, + {CTOKT_PARSER, CLF_ISO8601, 0, 0, 0xffff, 0, ClockScnToken_amPmInd_Proc, NULL}, /* %J */ {CTOKT_DIGIT, CLF_JULIANDAY, 0, 1, 0xffff, TclOffset(DateInfo, date.julianDay), @@ -1423,10 +1435,10 @@ static ClockScanTokenMap ScnSTokenMap[] = { {CTOKT_DIGIT, CLF_ISO8601, 0, 1, 2, TclOffset(DateInfo, date.iso8601Week), NULL}, /* %a %A %u %w */ - {CTOKT_PARSER, CLF_ISO8601, 0, 0, 0, 0, + {CTOKT_PARSER, CLF_ISO8601, 0, 0, 0xffff, 0, ClockScnToken_DayOfWeek_Proc, NULL}, /* %z %Z */ - {CTOKT_PARSER, CLF_OPTIONAL, 0, 0, 0, 0, + {CTOKT_PARSER, CLF_OPTIONAL, 0, 0, 0xffff, 0, ClockScnToken_TimeZone_Proc, NULL}, /* %U %W */ {CTOKT_DIGIT, CLF_OPTIONAL, 0, 1, 2, 0, /* currently no capture, parse only token */ @@ -1435,9 +1447,9 @@ static ClockScanTokenMap ScnSTokenMap[] = { {CTOKT_DIGIT, CLF_POSIXSEC | CLF_SIGNED, 0, 1, 0xffff, TclOffset(DateInfo, date.seconds), NULL}, /* %n */ - {CTOKT_CHAR, 0, 0, 1, 1, 0, NULL, "\n"}, + {CTOKT_CHAR, 0, 0, 0, 1, 0, NULL, "\n"}, /* min=0 - spaces are optional (in yySpaceCount) */ /* %t */ - {CTOKT_CHAR, 0, 0, 1, 1, 0, NULL, "\t"}, + {CTOKT_CHAR, 0, 0, 0, 1, 0, NULL, "\t"}, /* min=0 - spaces are optional (in yySpaceCount) */ /* %Q */ {CTOKT_PARSER, CLF_LOCALSEC, 0, 16, 30, 0, ClockScnToken_StarDate_Proc, NULL}, @@ -1451,10 +1463,10 @@ static const char *ScnETokenMapIndex = "Eys"; static ClockScanTokenMap ScnETokenMap[] = { /* %EE */ - {CTOKT_PARSER, 0, 0, 0, 0, TclOffset(DateInfo, date.year), + {CTOKT_PARSER, 0, 0, 0, 0xffff, TclOffset(DateInfo, date.year), ClockScnToken_LocaleERA_Proc, (void *)MCLIT_LOCALE_NUMERALS}, /* %Ey */ - {CTOKT_PARSER, 0, 0, 0, 0, 0, /* currently no capture, parse only token */ + {CTOKT_PARSER, 0, 0, 0, 0xffff, 0, /* currently no capture, parse only token */ ClockScnToken_LocaleListMatcher_Proc, (void *)MCLIT_LOCALE_NUMERALS}, /* %Es */ {CTOKT_DIGIT, CLF_LOCALSEC | CLF_SIGNED, 0, 1, 0xffff, TclOffset(DateInfo, date.localSeconds), @@ -1469,25 +1481,25 @@ static const char *ScnOTokenMapIndex = "dmyHMSu"; static ClockScanTokenMap ScnOTokenMap[] = { /* %Od %Oe */ - {CTOKT_PARSER, CLF_DAYOFMONTH, 0, 0, 0, TclOffset(DateInfo, date.dayOfMonth), + {CTOKT_PARSER, CLF_DAYOFMONTH, 0, 0, 0xffff, TclOffset(DateInfo, date.dayOfMonth), ClockScnToken_LocaleListMatcher_Proc, (void *)MCLIT_LOCALE_NUMERALS}, /* %Om */ - {CTOKT_PARSER, CLF_MONTH, 0, 0, 0, TclOffset(DateInfo, date.month), + {CTOKT_PARSER, CLF_MONTH, 0, 0, 0xffff, TclOffset(DateInfo, date.month), ClockScnToken_LocaleListMatcher_Proc, (void *)MCLIT_LOCALE_NUMERALS}, /* %Oy */ - {CTOKT_PARSER, CLF_YEAR, 0, 0, 0, TclOffset(DateInfo, date.year), + {CTOKT_PARSER, CLF_YEAR, 0, 0, 0xffff, TclOffset(DateInfo, date.year), ClockScnToken_LocaleListMatcher_Proc, (void *)MCLIT_LOCALE_NUMERALS}, /* %OH %Ok %OI %Ol */ - {CTOKT_PARSER, CLF_TIME, 0, 0, 0, TclOffset(DateInfo, date.hour), + {CTOKT_PARSER, CLF_TIME, 0, 0, 0xffff, TclOffset(DateInfo, date.hour), ClockScnToken_LocaleListMatcher_Proc, (void *)MCLIT_LOCALE_NUMERALS}, /* %OM */ - {CTOKT_PARSER, CLF_TIME, 0, 0, 0, TclOffset(DateInfo, date.minutes), + {CTOKT_PARSER, CLF_TIME, 0, 0, 0xffff, TclOffset(DateInfo, date.minutes), ClockScnToken_LocaleListMatcher_Proc, (void *)MCLIT_LOCALE_NUMERALS}, /* %OS */ - {CTOKT_PARSER, CLF_TIME, 0, 0, 0, TclOffset(DateInfo, date.secondOfDay), + {CTOKT_PARSER, CLF_TIME, 0, 0, 0xffff, TclOffset(DateInfo, date.secondOfDay), ClockScnToken_LocaleListMatcher_Proc, (void *)MCLIT_LOCALE_NUMERALS}, /* %Ou Ow */ - {CTOKT_PARSER, CLF_ISO8601, 0, 0, 0, 0, + {CTOKT_PARSER, CLF_ISO8601, 0, 0, 0xffff, 0, ClockScnToken_DayOfWeek_Proc, (void *)MCLIT_LOCALE_NUMERALS}, }; static const char *ScnOTokenMapAliasIndex[2] = { @@ -1498,12 +1510,12 @@ static const char *ScnOTokenMapAliasIndex[2] = { static const char *ScnSpecTokenMapIndex = " "; static ClockScanTokenMap ScnSpecTokenMap[] = { - {CTOKT_SPACE, 0, 0, 0, 0xffff, 0, + {CTOKT_SPACE, 0, 0, 0, 0xffff, 0, /* min=0 - spaces are optional (in yySpaceCount) */ NULL}, }; static ClockScanTokenMap ScnWordTokenMap = { - CTOKT_WORD, 0, 0, 1, 0, 0, + CTOKT_WORD, 0, 0, 1, 0xffff, 0, NULL }; @@ -1739,7 +1751,22 @@ ClockScan( p++; } } - info->dateStart = yyInput = p; + yyInput = p; + /* look ahead to count spaces (bypass it by count length and distances) */ + x = end; + while (p < end) { + if (isspace(UCHAR(*p))) { + x = p++; + yySpaceCount++; + continue; + } + x = end; + p++; + } + /* ignore spaces at end */ + yySpaceCount -= (end - x); + end = x; + info->dateStart = p = yyInput; info->dateEnd = end; /* parse string */ @@ -1752,6 +1779,7 @@ ClockScan( && map->type != CTOKT_CHAR ) ) { while (p < end && isspace(UCHAR(*p))) { + yySpaceCount--; p++; } } @@ -1764,16 +1792,17 @@ ClockScan( { case CTOKT_DIGIT: if (1) { - int size = map->maxSize; + int minLen, size; int sign = 1; if (map->flags & CLF_SIGNED) { if (*p == '+') { yyInput = ++p; } else if (*p == '-') { yyInput = ++p; sign = -1; }; } + DetermineGreedySearchLen(opts, info, tok, &minLen, &size); /* greedy find digits (look for forward digits consider spaces), * corresponding pre-calculated lookAhead */ - if (size != map->minSize && tok->lookAhead) { + if (size != minLen && tok->lookAhead) { int spcnt = 0; const char *pe; size += tok->lookAhead; @@ -1845,6 +1874,12 @@ ClockScan( goto done; break; }; + /* decrement count for possible spaces in match */ + while (p < yyInput) { + if (isspace(UCHAR(*p++))) { + yySpaceCount--; + } + } p = yyInput; flags = (flags & ~map->clearFlags) | map->flags; break; @@ -1855,9 +1890,11 @@ ClockScan( /* unmatched -> error */ goto not_match; } + yySpaceCount--; p++; } while (p < end && isspace(UCHAR(*p))) { + yySpaceCount--; p++; } break; @@ -1875,27 +1912,25 @@ ClockScan( /* no match -> error */ goto not_match; } + if (isspace(UCHAR(*x))) { + yySpaceCount--; + } p++; break; } } /* check end was reached */ if (p < end) { - /* ignore spaces at end */ - while (p < end && isspace(UCHAR(*p))) { - p++; - } - if (p < end) { - /* something after last token - wrong format */ - goto not_match; - } + /* something after last token - wrong format */ + goto not_match; } /* end of string, check only optional tokens at end, otherwise - not match */ while (tok->map != NULL) { if (!(opts->flags & CLF_STRICT) && (tok->map->type == CTOKT_SPACE)) { tok++; + if (tok->map == NULL) break; } - if (tok->map != NULL && !(tok->map->flags & CLF_OPTIONAL)) { + if (!(tok->map->flags & CLF_OPTIONAL)) { goto not_match; } tok++; diff --git a/generic/tclDate.h b/generic/tclDate.h index 2ce629d..519a3e5 100644 --- a/generic/tclDate.h +++ b/generic/tclDate.h @@ -204,6 +204,7 @@ typedef struct DateInfo { time_t *dateRelPointer; + time_t dateSpaceCount; time_t dateDigitCount; time_t dateCentury; @@ -241,6 +242,7 @@ typedef struct DateInfo { #define yyRelPointer (info->dateRelPointer) #define yyInput (info->dateInput) #define yyDigitCount (info->dateDigitCount) +#define yySpaceCount (info->dateSpaceCount) inline void ClockInitDateInfo(DateInfo *info) { diff --git a/tests/clock.test b/tests/clock.test index 4b0587a..46a2b29 100644 --- a/tests/clock.test +++ b/tests/clock.test @@ -18638,6 +18638,43 @@ test clock-6.21.3 {Stardate correct scan over year (leap year, begin, middle and unset -nocomplain wrong i i2 s d } +test clock-6.22.1 {Greedy match} { + clock format [clock scan "111" -format "%d%m%y" -gmt 1] -locale en -gmt 1 +} {Mon Jan 01 00:00:00 GMT 2001} +test clock-6.22.2 {Greedy match} { + clock format [clock scan "1111" -format "%d%m%y" -gmt 1] -locale en -gmt 1 +} {Thu Jan 11 00:00:00 GMT 2001} +test clock-6.22.3 {Greedy match} { + clock format [clock scan "11111" -format "%d%m%y" -gmt 1] -locale en -gmt 1 +} {Sun Nov 11 00:00:00 GMT 2001} +test clock-6.22.4 {Greedy match} { + clock format [clock scan "111111" -format "%d%m%y" -gmt 1] -locale en -gmt 1 +} {Fri Nov 11 00:00:00 GMT 2011} +test clock-6.22.5 {Greedy match} { + clock format [clock scan "1 1 1" -format "%d%m%y" -gmt 1] -locale en -gmt 1 +} {Mon Jan 01 00:00:00 GMT 2001} +test clock-6.22.6 {Greedy match} { + clock format [clock scan "111 1" -format "%d%m%y" -gmt 1] -locale en -gmt 1 +} {Thu Jan 11 00:00:00 GMT 2001} +test clock-6.22.7 {Greedy match} { + clock format [clock scan "1 111" -format "%d%m%y" -gmt 1] -locale en -gmt 1 +} {Thu Nov 01 00:00:00 GMT 2001} +test clock-6.22.8 {Greedy match} { + clock format [clock scan "1 11 1" -format "%d%m%y" -gmt 1] -locale en -gmt 1 +} {Thu Nov 01 00:00:00 GMT 2001} +test clock-6.22.9 {Greedy match} { + clock format [clock scan "1 11 11" -format "%d%m%y" -gmt 1] -locale en -gmt 1 +} {Tue Nov 01 00:00:00 GMT 2011} +test clock-6.22.10 {Greedy match} { + clock format [clock scan "11 11 11" -format "%d%m%y" -gmt 1] -locale en -gmt 1 +} {Fri Nov 11 00:00:00 GMT 2011} +test clock-6.22.11 {Greedy match} { + clock format [clock scan "1111 120" -format "%y%m%d %H%M%S" -gmt 1] -locale en -gmt 1 +} {Sat Jan 01 01:02:00 GMT 2011} +test clock-6.22.12 {Greedy match} { + clock format [clock scan "11 1 120" -format "%y%m%d %H%M%S" -gmt 1] -locale en -gmt 1 +} {Mon Jan 01 01:02:00 GMT 2001} + test clock-7.1 {Julian Day} { clock scan 0 -format %J -gmt true -- cgit v0.12 From 264cc47fd4ff7109cc19d544d1102b011b6183b0 Mon Sep 17 00:00:00 2001 From: sebres Date: Tue, 10 Jan 2017 22:52:44 +0000 Subject: another way to make greedy search more precise, some greedy matches are fixed (see test cases clock-6.22.11 - clock-6.22.20), additionally involving look ahead token of known type into pre-search process. --- generic/tclClockFmt.c | 273 ++++++++++++++++++++++++++++++++++---------------- generic/tclDate.h | 7 +- tests/clock.test | 41 ++++++-- 3 files changed, 224 insertions(+), 97 deletions(-) diff --git a/generic/tclClockFmt.c b/generic/tclClockFmt.c index 00ea0ed..680e33d 100644 --- a/generic/tclClockFmt.c +++ b/generic/tclClockFmt.c @@ -713,49 +713,127 @@ clean: return (opts->formatObj = valObj); } +static const char * +FindTokenBegin( + register const char *p, + register const char *end, + ClockScanToken *tok) +{ + char c; + if (p < end) { + /* next token a known token type */ + switch (tok->map->type) { + case CTOKT_DIGIT: + /* should match at least one digit */ + while (!isdigit(UCHAR(*p)) && (p = TclUtfNext(p)) < end) {}; + return p; + break; + case CTOKT_WORD: + c = *(tok->tokWord.start); + /* should match at least to the first char of this word */ + while (*p != c && (p = TclUtfNext(p)) < end) {}; + return p; + break; + case CTOKT_SPACE: + while (!isspace(UCHAR(*p)) && (p = TclUtfNext(p)) < end) {}; + return p; + break; + case CTOKT_CHAR: + c = *((char *)tok->map->data); + while (*p != c && (p = TclUtfNext(p)) < end) {}; + return p; + break; + } + } + return p; +} + /* * DetermineGreedySearchLen -- * * Determine min/max lengths as exact as possible (speed, greedy match) * */ -inline -void DetermineGreedySearchLen(ClockFmtScnCmdArgs *opts, - DateInfo *info, ClockScanToken *tok, int *minLen, int *maxLen) +static void +DetermineGreedySearchLen(ClockFmtScnCmdArgs *opts, + DateInfo *info, ClockScanToken *tok, + int *minLenPtr, int *maxLenPtr) { - register const char *p = yyInput, + register int minLen = tok->map->minSize; + register int maxLen; + register const char *p = yyInput + minLen, *end = info->dateEnd; - *minLen = 0; - /* if still tokens available */ + /* if still tokens available, try to correct minimum length */ if ((tok+1)->map) { end -= tok->endDistance + yySpaceCount; - /* next token is a word */ - switch ((tok+1)->map->type) { - case CTOKT_WORD: - /* should match at least to the first char of this word */ - while (*p != *((tok+1)->tokWord.start) && ++p < end) {}; - *minLen = p - yyInput; - break; - case CTOKT_CHAR: - while (*p != *((char *)(tok+1)->map->data) && ++p < end) {}; - *minLen = p - yyInput; - break; + /* find position of next known token */ + p = FindTokenBegin(p, end, tok+1); + if (p < end) { + minLen = p - yyInput; } } /* max length to the end regarding distance to end (min-width of following tokens) */ - *maxLen = end - p; - if (*maxLen > tok->map->maxSize) { - *maxLen = tok->map->maxSize; + maxLen = end - yyInput; + /* several amendments */ + if (maxLen > tok->map->maxSize) { + maxLen = tok->map->maxSize; }; - - if (*minLen < tok->map->minSize) { - *minLen = tok->map->minSize; + if (minLen < tok->map->minSize) { + minLen = tok->map->minSize; } - if (*minLen > *maxLen) { - *maxLen = *minLen; + if (minLen > maxLen) { + maxLen = minLen; + } + if (maxLen > info->dateEnd - yyInput) { + maxLen = info->dateEnd - yyInput; + } + + /* check digits rigth now */ + if (tok->map->type == CTOKT_DIGIT) { + p = yyInput; + end = p + maxLen; + if (end > info->dateEnd) { end = info->dateEnd; }; + while (isdigit(UCHAR(*p)) && p < end) { p++; }; + maxLen = p - yyInput; + } + + /* try to get max length more precise for greedy match, + * check the next ahead token available there */ + if (minLen < maxLen && tok->lookAhTok) { + ClockScanToken *laTok = tok + tok->lookAhTok + 1; + p = yyInput + maxLen; + /* regards all possible spaces here (because they are optional) */ + end = p + tok->lookAhMax + yySpaceCount + 1; + if (end > info->dateEnd) { + end = info->dateEnd; + } + p += tok->lookAhMin; + if (laTok->map && p < end) { + const char *f; + /* try to find laTok between [lookAhMin, lookAhMax] */ + while (minLen < maxLen) { + f = FindTokenBegin(p, end, laTok); + /* if found (not below lookAhMax) */ + if (f < end) { + break; + } + /* try again with fewer length */ + maxLen--; + p--; + end--; + } + } else if (p > end) { + maxLen -= (p - end); + if (maxLen < minLen) { + maxLen = minLen; + } + } } + + *minLenPtr = minLen; + *maxLenPtr = maxLen; } inline int @@ -1447,9 +1525,9 @@ static ClockScanTokenMap ScnSTokenMap[] = { {CTOKT_DIGIT, CLF_POSIXSEC | CLF_SIGNED, 0, 1, 0xffff, TclOffset(DateInfo, date.seconds), NULL}, /* %n */ - {CTOKT_CHAR, 0, 0, 0, 1, 0, NULL, "\n"}, /* min=0 - spaces are optional (in yySpaceCount) */ + {CTOKT_CHAR, 0, 0, 1, 1, 0, NULL, "\n"}, /* %t */ - {CTOKT_CHAR, 0, 0, 0, 1, 0, NULL, "\t"}, /* min=0 - spaces are optional (in yySpaceCount) */ + {CTOKT_CHAR, 0, 0, 1, 1, 0, NULL, "\t"}, /* %Q */ {CTOKT_PARSER, CLF_LOCALSEC, 0, 16, 30, 0, ClockScnToken_StarDate_Proc, NULL}, @@ -1510,12 +1588,12 @@ static const char *ScnOTokenMapAliasIndex[2] = { static const char *ScnSpecTokenMapIndex = " "; static ClockScanTokenMap ScnSpecTokenMap[] = { - {CTOKT_SPACE, 0, 0, 0, 0xffff, 0, /* min=0 - spaces are optional (in yySpaceCount) */ + {CTOKT_SPACE, 0, 0, 1, 1, 0, NULL}, }; static ClockScanTokenMap ScnWordTokenMap = { - CTOKT_WORD, 0, 0, 1, 0xffff, 0, + CTOKT_WORD, 0, 0, 1, 1, 0, NULL }; @@ -1559,7 +1637,7 @@ EstimateTokenCount( /* *---------------------------------------------------------------------- */ -ClockScanToken * +ClockFmtScnStorage * ClockGetOrParseScanFormat( Tcl_Interp *interp, /* Tcl interpreter */ Tcl_Obj *formatObj) /* Format container */ @@ -1574,6 +1652,7 @@ ClockGetOrParseScanFormat( /* if first time scanning - tokenize format */ if (fss->scnTok == NULL) { + unsigned int tokCnt; register const char *p, *e, *cp; e = p = HashEntry4FmtScn(fss)->key.string; @@ -1581,11 +1660,14 @@ ClockGetOrParseScanFormat( /* estimate token count by % char and format length */ fss->scnTokC = EstimateTokenCount(p, e); + + fss->scnSpaceCount = 0; Tcl_MutexLock(&ClockFmtMutex); fss->scnTok = tok = ckalloc(sizeof(*tok) * fss->scnTokC); memset(tok, 0, sizeof(*(tok))); + tokCnt = 1; while (p < e) { switch (*p) { case '%': @@ -1605,7 +1687,7 @@ ClockGetOrParseScanFormat( tok->map = &ScnWordTokenMap; tok->tokWord.start = p; tok->tokWord.end = p+1; - AllocTokenInChain(tok, fss->scnTok, fss->scnTokC); + AllocTokenInChain(tok, fss->scnTok, fss->scnTokC); tokCnt++; p++; continue; break; @@ -1642,21 +1724,31 @@ ClockGetOrParseScanFormat( } tok->map = &scnMap[cp - mapIndex]; tok->tokWord.start = p; + /* calculate look ahead value by standing together tokens */ - if (tok > fss->scnTok && tok->map->minSize) { - unsigned int lookAhead = tok->map->minSize; + if (tok > fss->scnTok) { ClockScanToken *prevTok = tok - 1; while (prevTok >= fss->scnTok) { if (prevTok->map->type != tok->map->type) { break; } - prevTok->lookAhead += lookAhead; + prevTok->lookAhMin += tok->map->minSize; + prevTok->lookAhMax += tok->map->maxSize; + prevTok->lookAhTok++; prevTok--; } } + + /* increase space count used in format */ + if ( tok->map->type == CTOKT_CHAR + && isspace(UCHAR(*((char *)tok->map->data))) + ) { + fss->scnSpaceCount++; + } + /* next token */ - AllocTokenInChain(tok, fss->scnTok, fss->scnTokC); + AllocTokenInChain(tok, fss->scnTok, fss->scnTokC); tokCnt++; p++; continue; } @@ -1668,7 +1760,10 @@ ClockGetOrParseScanFormat( goto word_tok; } tok->map = &ScnSpecTokenMap[cp - ScnSpecTokenMapIndex]; - AllocTokenInChain(tok, fss->scnTok, fss->scnTokC); + /* increase space count used in format */ + fss->scnSpaceCount++; + /* next token */ + AllocTokenInChain(tok, fss->scnTok, fss->scnTokC); tokCnt++; p++; continue; break; @@ -1679,10 +1774,14 @@ word_tok: if (tok > fss->scnTok && (tok-1)->map == &ScnWordTokenMap) { wordTok = tok-1; } + /* new word token */ if (wordTok == tok) { wordTok->tokWord.start = p; wordTok->map = &ScnWordTokenMap; - AllocTokenInChain(tok, fss->scnTok, fss->scnTokC); + AllocTokenInChain(tok, fss->scnTok, fss->scnTokC); tokCnt++; + } + if (isspace(UCHAR(*p))) { + fss->scnSpaceCount++; } p = TclUtfNext(p); wordTok->tokWord.end = p; @@ -1705,12 +1804,22 @@ word_tok: } prevTok--; } - } + } + + /* correct count of real used tokens and free mem if desired + * (1 is acceptable delta to prevent memory fragmentation) */ + if (fss->scnTokC > tokCnt + (CLOCK_MIN_TOK_CHAIN_BLOCK_SIZE / 2)) { + if ( (tok = ckrealloc(fss->scnTok, tokCnt * sizeof(*tok))) != NULL ) { + fss->scnTok = tok; + } + } + fss->scnTokC = tokCnt; + done: Tcl_MutexUnlock(&ClockFmtMutex); } - return fss->scnTok; + return fss; } /* @@ -1723,6 +1832,7 @@ ClockScan( ClockFmtScnCmdArgs *opts) /* Command options */ { ClockClientData *dataPtr = opts->clientData; + ClockFmtScnStorage *fss; ClockScanToken *tok; ClockScanTokenMap *map; register const char *p, *x, *end; @@ -1734,8 +1844,9 @@ ClockScan( return TCL_ERROR; } - if ((tok = ClockGetOrParseScanFormat(opts->interp, - opts->formatObj)) == NULL) { + if ( !(fss = ClockGetOrParseScanFormat(opts->interp, opts->formatObj)) + || !(tok = fss->scnTok) + ) { return TCL_ERROR; } @@ -1766,6 +1877,11 @@ ClockScan( /* ignore spaces at end */ yySpaceCount -= (end - x); end = x; + /* ignore mandatory spaces used in format */ + yySpaceCount -= fss->scnSpaceCount; + if (yySpaceCount < 0) { + yySpaceCount = 0; + } info->dateStart = p = yyInput; info->dateEnd = end; @@ -1799,39 +1915,9 @@ ClockScan( else if (*p == '-') { yyInput = ++p; sign = -1; }; } + DetermineGreedySearchLen(opts, info, tok, &minLen, &size); - /* greedy find digits (look for forward digits consider spaces), - * corresponding pre-calculated lookAhead */ - if (size != minLen && tok->lookAhead) { - int spcnt = 0; - const char *pe; - size += tok->lookAhead; - x = p + size; if (x > end) { x = end; }; - pe = x; - while (p < x) { - if (isspace(UCHAR(*p))) { - if (pe > p) { pe = p; }; - if (x < end) x++; - p++; - spcnt++; - continue; - } - if (isdigit(UCHAR(*p))) { - p++; - continue; - } - break; - } - /* consider reserved (lookAhead) for next tokens */ - p -= tok->lookAhead + spcnt; - if (p > pe) { - p = pe; - } - } else { - x = p + size; if (x > end) { x = end; }; - while (isdigit(UCHAR(*p)) && p < x) { p++; }; - } - size = p - yyInput; + if (size < map->minSize) { /* missing input -> error */ if ((map->flags & CLF_OPTIONAL)) { @@ -1884,15 +1970,13 @@ ClockScan( flags = (flags & ~map->clearFlags) | map->flags; break; case CTOKT_SPACE: - /* at least one space in strict mode */ - if (opts->flags & CLF_STRICT) { - if (!isspace(UCHAR(*p))) { - /* unmatched -> error */ - goto not_match; - } - yySpaceCount--; - p++; + /* at least one space */ + if (!isspace(UCHAR(*p))) { + /* unmatched -> error */ + goto not_match; } + yySpaceCount--; + p++; while (p < end && isspace(UCHAR(*p))) { yySpaceCount--; p++; @@ -2460,7 +2544,7 @@ static ClockFormatTokenMap FmtWordTokenMap = { /* *---------------------------------------------------------------------- */ -ClockFormatToken * +ClockFmtScnStorage * ClockGetOrParseFmtFormat( Tcl_Interp *interp, /* Tcl interpreter */ Tcl_Obj *formatObj) /* Format container */ @@ -2475,6 +2559,7 @@ ClockGetOrParseFmtFormat( /* if first time scanning - tokenize format */ if (fss->fmtTok == NULL) { + unsigned int tokCnt; register const char *p, *e, *cp; e = p = HashEntry4FmtScn(fss)->key.string; @@ -2487,6 +2572,7 @@ ClockGetOrParseFmtFormat( fss->fmtTok = tok = ckalloc(sizeof(*tok) * fss->fmtTokC); memset(tok, 0, sizeof(*(tok))); + tokCnt = 1; while (p < e) { switch (*p) { case '%': @@ -2506,7 +2592,7 @@ ClockGetOrParseFmtFormat( tok->map = &FmtWordTokenMap; tok->tokWord.start = p; tok->tokWord.end = p+1; - AllocTokenInChain(tok, fss->fmtTok, fss->fmtTokC); + AllocTokenInChain(tok, fss->fmtTok, fss->fmtTokC); tokCnt++; p++; continue; break; @@ -2544,7 +2630,7 @@ ClockGetOrParseFmtFormat( tok->map = &fmtMap[cp - mapIndex]; tok->tokWord.start = p; /* next token */ - AllocTokenInChain(tok, fss->fmtTok, fss->fmtTokC); + AllocTokenInChain(tok, fss->fmtTok, fss->fmtTokC); tokCnt++; p++; continue; } @@ -2559,7 +2645,7 @@ word_tok: if (wordTok == tok) { wordTok->tokWord.start = p; wordTok->map = &FmtWordTokenMap; - AllocTokenInChain(tok, fss->fmtTok, fss->fmtTokC); + AllocTokenInChain(tok, fss->fmtTok, fss->fmtTokC); tokCnt++; } p = TclUtfNext(p); wordTok->tokWord.end = p; @@ -2568,11 +2654,20 @@ word_tok: } } + /* correct count of real used tokens and free mem if desired + * (1 is acceptable delta to prevent memory fragmentation) */ + if (fss->fmtTokC > tokCnt + (CLOCK_MIN_TOK_CHAIN_BLOCK_SIZE / 2)) { + if ( (tok = ckrealloc(fss->fmtTok, tokCnt * sizeof(*tok))) != NULL ) { + fss->fmtTok = tok; + } + } + fss->fmtTokC = tokCnt; + done: Tcl_MutexUnlock(&ClockFmtMutex); } - return fss->fmtTok; + return fss; } /* @@ -2584,6 +2679,7 @@ ClockFormat( ClockFmtScnCmdArgs *opts) /* Command options */ { ClockClientData *dataPtr = opts->clientData; + ClockFmtScnStorage *fss; ClockFormatToken *tok; ClockFormatTokenMap *map; @@ -2592,8 +2688,9 @@ ClockFormat( return TCL_ERROR; } - if ((tok = ClockGetOrParseFmtFormat(opts->interp, - opts->formatObj)) == NULL) { + if ( !(fss = ClockGetOrParseFmtFormat(opts->interp, opts->formatObj)) + || !(tok = fss->fmtTok) + ) { return TCL_ERROR; } diff --git a/generic/tclDate.h b/generic/tclDate.h index 519a3e5..c50753d 100644 --- a/generic/tclDate.h +++ b/generic/tclDate.h @@ -375,12 +375,14 @@ typedef struct ClockScanTokenMap { typedef struct ClockScanToken { ClockScanTokenMap *map; - unsigned short int lookAhead; - unsigned short int endDistance; struct { const char *start; const char *end; } tokWord; + unsigned short int endDistance; + unsigned short int lookAhMin; + unsigned short int lookAhMax; + unsigned short int lookAhTok; } ClockScanToken; @@ -435,6 +437,7 @@ typedef struct ClockFmtScnStorage { int objRefCount; /* Reference count shared across threads */ ClockScanToken *scnTok; unsigned int scnTokC; + unsigned int scnSpaceCount; /* Count of mandatory spaces used in format */ ClockFormatToken *fmtTok; unsigned int fmtTokC; #if CLOCK_FMT_SCN_STORAGE_GC_SIZE > 0 diff --git a/tests/clock.test b/tests/clock.test index 46a2b29..d9c491a 100644 --- a/tests/clock.test +++ b/tests/clock.test @@ -18588,16 +18588,16 @@ test clock-6.16 {input of ambiguous short locale token (%b)} { } {1 {input string does not match supplied format} {CLOCK badInputString}} test clock-6.17 {spaces are always optional in non-strict mode (default)} { - list [clock scan "2009-06-30T18:30:00+02:00" -format "%Y-%m-%dT%H:%M:%S %z" -gmt 1] \ - [clock scan "2009-06-30T18:30:00 +02:00" -format "%Y-%m-%dT%H:%M:%S %z" -gmt 1] \ - [clock scan "2009-06-30T18:30:00Z" -format "%Y-%m-%dT%H:%M:%S %z" -timezone CET] \ - [clock scan "2009-06-30T18:30:00 Z" -format "%Y-%m-%dT%H:%M:%S %z" -timezone CET] + list [clock scan "2009-06-30T18:30:00+02:00" -format "%Y-%m-%dT%H:%M:%S%z" -gmt 1] \ + [clock scan "2009-06-30T18:30:00 +02:00" -format "%Y-%m-%dT%H:%M:%S%z" -gmt 1] \ + [clock scan "2009-06-30T18:30:00Z" -format "%Y-%m-%dT%H:%M:%S%z" -timezone CET] \ + [clock scan "2009-06-30T18:30:00 Z" -format "%Y-%m-%dT%H:%M:%S%z" -timezone CET] } {1246379400 1246379400 1246386600 1246386600} test clock-6.18 {zone token (%z) is optional} { - list [clock scan "2009-06-30T18:30:00 -01:00" -format "%Y-%m-%dT%H:%M:%S %z" -gmt 1] \ - [clock scan "2009-06-30T18:30:00" -format "%Y-%m-%dT%H:%M:%S %z" -gmt 1] \ - [clock scan " 2009-06-30T18:30:00 " -format "%Y-%m-%dT%H:%M:%S %z" -gmt 1] \ + list [clock scan "2009-06-30T18:30:00 -01:00" -format "%Y-%m-%dT%H:%M:%S%z" -gmt 1] \ + [clock scan "2009-06-30T18:30:00" -format "%Y-%m-%dT%H:%M:%S%z" -gmt 1] \ + [clock scan " 2009-06-30T18:30:00 " -format "%Y-%m-%dT%H:%M:%S%z" -gmt 1] \ } {1246390200 1246386600 1246386600} test clock-6.19 {no token parsing} { @@ -18674,6 +18674,33 @@ test clock-6.22.11 {Greedy match} { test clock-6.22.12 {Greedy match} { clock format [clock scan "11 1 120" -format "%y%m%d %H%M%S" -gmt 1] -locale en -gmt 1 } {Mon Jan 01 01:02:00 GMT 2001} +test clock-6.22.13 {Greedy match} { + clock format [clock scan "1 11 120" -format "%y%m%d %H%M%S" -gmt 1] -locale en -gmt 1 +} {Mon Jan 01 01:02:00 GMT 2001} +test clock-6.22.14 {Greedy match} { + clock format [clock scan "111120" -format "%y%m%d%H%M%S" -gmt 1] -locale en -gmt 1 +} {Mon Jan 01 01:02:00 GMT 2001} +test clock-6.22.15 {Greedy match} { + clock format [clock scan "1111120" -format "%y%m%d%H%M%S" -gmt 1] -locale en -gmt 1 +} {Sat Jan 01 01:02:00 GMT 2011} +test clock-6.22.16 {Greedy match} { + clock format [clock scan "11121120" -format "%y%m%d%H%M%S" -gmt 1] -locale en -gmt 1 +} {Thu Dec 01 01:02:00 GMT 2011} +test clock-6.22.17 {Greedy match} { + clock format [clock scan "111213120" -format "%y%m%d%H%M%S" -gmt 1] -locale en -gmt 1 +} {Tue Dec 13 01:02:00 GMT 2011} +test clock-6.22.17 {Greedy match (space wins as date-time separator)} { + clock format [clock scan "1112 13120" -format "%y%m%d %H%M%S" -gmt 1] -locale en -gmt 1 +} {Sun Jan 02 13:12:00 GMT 2011} +test clock-6.22.18 {Greedy match (second space wins as date-time separator)} { + clock format [clock scan "1112 13 120" -format "%y%m%d %H%M%S" -gmt 1] -locale en -gmt 1 +} {Tue Dec 13 01:02:00 GMT 2011} +test clock-6.22.19 {Greedy match (space wins as date-time separator)} { + clock format [clock scan "111 213120" -format "%y%m%d %H%M%S" -gmt 1] -locale en -gmt 1 +} {Mon Jan 01 21:31:20 GMT 2001} +test clock-6.22.20 {Greedy match (second space wins as date-time separator)} { + clock format [clock scan "111 2 13120" -format "%y%m%d %H%M%S" -gmt 1] -locale en -gmt 1 +} {Sun Jan 02 13:12:00 GMT 2011} test clock-7.1 {Julian Day} { -- cgit v0.12 From 27fd5c0793a7bf5332cd99885869ae7e79d66dfb Mon Sep 17 00:00:00 2001 From: sebres Date: Tue, 10 Jan 2017 22:53:05 +0000 Subject: dict: unused variable removed --- generic/tclDictObj.c | 1 - 1 file changed, 1 deletion(-) diff --git a/generic/tclDictObj.c b/generic/tclDictObj.c index 3944173..8e11bfe 100644 --- a/generic/tclDictObj.c +++ b/generic/tclDictObj.c @@ -2014,7 +2014,6 @@ DictSmartRefCmd( Tcl_Obj *const *objv) { Tcl_Obj *result; - Dict *dict; if (objc != 2) { Tcl_WrongNumArgs(interp, 1, objv, "dictionary"); -- cgit v0.12 From d551c0972c261cc3a69b07263ae3c8072d929a50 Mon Sep 17 00:00:00 2001 From: sebres Date: Tue, 10 Jan 2017 22:55:00 +0000 Subject: [unix] build for *nix fixed, code clean-ups; missing declarations; unused vars, functions etc; types normalization; --- generic/tclClock.c | 6 +--- generic/tclClockFmt.c | 31 ++++++++++--------- generic/tclDate.c | 8 ++--- generic/tclDate.h | 80 +++++++++++++++++++++++++------------------------ generic/tclGetDate.y | 8 ++--- generic/tclStrIdxTree.c | 8 ++--- generic/tclStrIdxTree.h | 8 ++--- unix/Makefile.in | 4 +-- 8 files changed, 77 insertions(+), 76 deletions(-) diff --git a/generic/tclClock.c b/generic/tclClock.c index 7d4263c..1b1faae 100644 --- a/generic/tclClock.c +++ b/generic/tclClock.c @@ -137,10 +137,6 @@ static unsigned long TzsetGetEpoch(void); static void TzsetIfNecessary(void); static void ClockDeleteCmdProc(ClientData); -static int ClockTestObjCmd( - ClientData clientData, Tcl_Interp *interp, - int objc, Tcl_Obj *const objv[]); - /* * Structure containing description of "native" clock commands to create. */ @@ -3365,7 +3361,7 @@ repeat_rel: /* relative time (seconds), if exceeds current date, do the day conversion and * leave rest of the increment in yyRelSeconds to add it hereafter in UTC seconds */ if (yyRelSeconds) { - time_t newSecs = yySeconds + yyRelSeconds; + int newSecs = yySeconds + yyRelSeconds; /* if seconds increment outside of current date, increment day */ if (newSecs / SECONDS_PER_DAY != yySeconds / SECONDS_PER_DAY) { diff --git a/generic/tclClockFmt.c b/generic/tclClockFmt.c index 680e33d..a5ddd18 100644 --- a/generic/tclClockFmt.c +++ b/generic/tclClockFmt.c @@ -43,13 +43,13 @@ CLOCK_LOCALE_LITERAL_ARRAY(MsgCtLitIdxs, "_IDX_"); inline int _str2int( - time_t *out, + int *out, register const char *p, const char *e, int sign) { - register time_t val = 0, prev = 0; + register int val = 0, prev = 0; if (sign >= 0) { while (p < e) { val = val * 10 + (*p++ - '0'); @@ -880,6 +880,7 @@ ObjListSearch(ClockFmtScnCmdArgs *opts, } return TCL_RETURN; } +#if 0 static int LocaleListSearch(ClockFmtScnCmdArgs *opts, @@ -905,6 +906,7 @@ LocaleListSearch(ClockFmtScnCmdArgs *opts, return ObjListSearch(opts, info, val, lstv, lstc, minLen, maxLen); } +#endif static TclStrIdxTree * ClockMCGetListIdxTree( @@ -1039,6 +1041,7 @@ ClockStrIdxTreeSearch(ClockFmtScnCmdArgs *opts, return TCL_OK; } +#if 0 static int StaticListSearch(ClockFmtScnCmdArgs *opts, @@ -1062,6 +1065,7 @@ StaticListSearch(ClockFmtScnCmdArgs *opts, } return TCL_RETURN; } +#endif inline const char * FindWordEnd( @@ -1069,7 +1073,7 @@ FindWordEnd( register const char * p, const char * end) { register const char *x = tok->tokWord.start; - const char *pfnd; + const char *pfnd = p; if (x == tok->tokWord.end - 1) { /* fast phase-out for single char word */ if (*p == *x) { return ++p; @@ -1088,14 +1092,14 @@ static int ClockScnToken_Month_Proc(ClockFmtScnCmdArgs *opts, DateInfo *info, ClockScanToken *tok) { - /* +#if 0 static const char * months[] = { - /* full * / + /* full */ "January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December", - /* abbr * / + /* abbr */ "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec", NULL @@ -1106,7 +1110,7 @@ ClockScnToken_Month_Proc(ClockFmtScnCmdArgs *opts, } yyMonth = (val % 12) + 1; return TCL_OK; - */ +#endif static int monthsKeys[] = {MCLIT_MONTHS_FULL, MCLIT_MONTHS_ABBREV, 0}; @@ -1300,7 +1304,7 @@ ClockScnToken_LocaleListMatcher_Proc(ClockFmtScnCmdArgs *opts, } if (tok->map->offs > 0) { - *(time_t *)(((char *)info) + tok->map->offs) = val; + *(int *)(((char *)info) + tok->map->offs) = val; } return TCL_OK; @@ -1334,7 +1338,7 @@ ClockScnToken_TimeZone_Proc(ClockFmtScnCmdArgs *opts, *bp++ = *p++; len++; if (len + 2 < maxLen) { if (*p == ':') { - *p++; len++; + p++; len++; } } } @@ -1392,7 +1396,7 @@ ClockScnToken_StarDate_Proc(ClockFmtScnCmdArgs *opts, { int minLen, maxLen; register const char *p = yyInput, *end; const char *s; - time_t year, fractYear, fractDayDiv, fractDay; + int year, fractYear, fractDayDiv, fractDay; static const char *stardatePref = "stardate "; DetermineGreedySearchLen(opts, info, tok, &minLen, &maxLen); @@ -1626,7 +1630,7 @@ EstimateTokenCount( #define AllocTokenInChain(tok, chain, tokCnt) \ if (++(tok) >= (chain) + (tokCnt)) { \ - (char *)(chain) = ckrealloc((char *)(chain), \ + *((char **)&chain) = ckrealloc((char *)(chain), \ (tokCnt + CLOCK_MIN_TOK_CHAIN_BLOCK_SIZE) * sizeof(*(tok))); \ if ((chain) == NULL) { goto done; }; \ (tok) = (chain) + (tokCnt); \ @@ -1929,7 +1933,7 @@ ClockScan( if (map->offs) { p = yyInput; x = p + size; if (!(map->flags & (CLF_LOCALSEC|CLF_POSIXSEC))) { - if (_str2int((time_t *)(((char *)info) + map->offs), + if (_str2int((int *)(((char *)info) + map->offs), p, x, sign) != TCL_OK) { goto overflow; } @@ -2678,7 +2682,6 @@ ClockFormat( register DateFormat *dateFmt, /* Date fields used for parsing & converting */ ClockFmtScnCmdArgs *opts) /* Command options */ { - ClockClientData *dataPtr = opts->clientData; ClockFmtScnStorage *fss; ClockFormatToken *tok; ClockFormatTokenMap *map; @@ -2716,7 +2719,7 @@ ClockFormat( { case CFMTT_INT: if (1) { - int val = (int)*(time_t *)(((char *)dateFmt) + map->offs); + int val = (int)*(int *)(((char *)dateFmt) + map->offs); if (map->fmtproc == NULL) { if (map->flags & CLFMT_DECR) { val--; diff --git a/generic/tclDate.c b/generic/tclDate.c index 5bd96d0..64cb804 100644 --- a/generic/tclDate.c +++ b/generic/tclDate.c @@ -2448,11 +2448,11 @@ TclDateerror( infoPtr->separatrix = "\n"; } -time_t +MODULE_SCOPE int ToSeconds( - time_t Hours, - time_t Minutes, - time_t Seconds, + int Hours, + int Minutes, + int Seconds, MERIDIAN Meridian) { if (Minutes < 0 || Minutes > 59 || Seconds < 0 || Seconds > 59) { diff --git a/generic/tclDate.h b/generic/tclDate.h index c50753d..c9c6726 100644 --- a/generic/tclDate.h +++ b/generic/tclDate.h @@ -142,21 +142,21 @@ typedef struct TclDateFields { * epoch */ Tcl_WideInt localSeconds; /* Local time expressed in nominal seconds * from the Posix epoch */ - time_t tzOffset; /* Time zone offset in seconds east of + int tzOffset; /* Time zone offset in seconds east of * Greenwich */ - time_t julianDay; /* Julian Day Number in local time zone */ + int julianDay; /* Julian Day Number in local time zone */ enum {BCE=1, CE=0} era; /* Era */ - time_t gregorian; /* Flag == 1 if the date is Gregorian */ - time_t year; /* Year of the era */ - time_t dayOfYear; /* Day of the year (1 January == 1) */ - time_t month; /* Month number */ - time_t dayOfMonth; /* Day of the month */ - time_t iso8601Year; /* ISO8601 week-based year */ - time_t iso8601Week; /* ISO8601 week number */ - time_t dayOfWeek; /* Day of the week */ - time_t hour; /* Hours of day (in-between time only calculation) */ - time_t minutes; /* Minutes of day (in-between time only calculation) */ - time_t secondOfDay; /* Seconds of day (in-between time only calculation) */ + int gregorian; /* Flag == 1 if the date is Gregorian */ + int year; /* Year of the era */ + int dayOfYear; /* Day of the year (1 January == 1) */ + int month; /* Month number */ + int dayOfMonth; /* Day of the month */ + int iso8601Year; /* ISO8601 week-based year */ + int iso8601Week; /* ISO8601 week number */ + int dayOfWeek; /* Day of the week */ + int hour; /* Hours of day (in-between time only calculation) */ + int minutes; /* Minutes of day (in-between time only calculation) */ + int secondOfDay; /* Seconds of day (in-between time only calculation) */ /* Non cacheable fields: */ @@ -180,34 +180,34 @@ typedef struct DateInfo { int flags; - time_t dateHaveDate; + int dateHaveDate; - time_t dateMeridian; - time_t dateHaveTime; + int dateMeridian; + int dateHaveTime; - time_t dateTimezone; - time_t dateDSTmode; - time_t dateHaveZone; + int dateTimezone; + int dateDSTmode; + int dateHaveZone; - time_t dateRelMonth; - time_t dateRelDay; - time_t dateRelSeconds; - time_t dateHaveRel; + int dateRelMonth; + int dateRelDay; + int dateRelSeconds; + int dateHaveRel; - time_t dateMonthOrdinalIncr; - time_t dateMonthOrdinal; - time_t dateHaveOrdinalMonth; + int dateMonthOrdinalIncr; + int dateMonthOrdinal; + int dateHaveOrdinalMonth; - time_t dateDayOrdinal; - time_t dateDayNumber; - time_t dateHaveDay; + int dateDayOrdinal; + int dateDayNumber; + int dateHaveDay; - time_t *dateRelPointer; + int *dateRelPointer; - time_t dateSpaceCount; - time_t dateDigitCount; + int dateSpaceCount; + int dateDigitCount; - time_t dateCentury; + int dateCentury; Tcl_Obj* messages; /* Error messages */ const char* separatrix; /* String separating messages */ @@ -244,7 +244,7 @@ typedef struct DateInfo { #define yyDigitCount (info->dateDigitCount) #define yySpaceCount (info->dateSpaceCount) -inline void +static inline void ClockInitDateInfo(DateInfo *info) { memset(info, 0, sizeof(DateInfo)); } @@ -314,7 +314,7 @@ typedef struct ClockClientData { Tcl_WideInt seconds; Tcl_WideInt rangesVal[2]; /* Bounds for cached time zone offset */ /* values */ - time_t tzOffset; + int tzOffset; Tcl_Obj *tzName; } UTC2Local; /* Las-period cache for fast Local2UTC conversion */ @@ -325,7 +325,7 @@ typedef struct ClockClientData { Tcl_WideInt localSeconds; Tcl_WideInt rangesVal[2]; /* Bounds for cached time zone offset */ /* values */ - time_t tzOffset; + int tzOffset; } Local2UTC; } ClockClientData; @@ -444,16 +444,18 @@ typedef struct ClockFmtScnStorage { ClockFmtScnStorage *nextPtr; ClockFmtScnStorage *prevPtr; #endif -/* +Tcl_HashEntry hashEntry /* ClockFmtScnStorage is a derivate of Tcl_HashEntry, +#if 0 + +Tcl_HashEntry hashEntry /* ClockFmtScnStorage is a derivate of Tcl_HashEntry, * stored by offset +sizeof(self) */ +#endif } ClockFmtScnStorage; /* * Prototypes of module functions. */ -MODULE_SCOPE time_t ToSeconds(time_t Hours, time_t Minutes, - time_t Seconds, MERIDIAN Meridian); +MODULE_SCOPE int ToSeconds(int Hours, int Minutes, + int Seconds, MERIDIAN Meridian); MODULE_SCOPE int IsGregorianLeapYear(TclDateFields *); MODULE_SCOPE void GetJulianDayFromEraYearWeekDay( diff --git a/generic/tclGetDate.y b/generic/tclGetDate.y index 9e3623f..6d6a0d0 100644 --- a/generic/tclGetDate.y +++ b/generic/tclGetDate.y @@ -659,11 +659,11 @@ TclDateerror( infoPtr->separatrix = "\n"; } -time_t +MODULE_SCOPE int ToSeconds( - time_t Hours, - time_t Minutes, - time_t Seconds, + int Hours, + int Minutes, + int Seconds, MERIDIAN Meridian) { if (Minutes < 0 || Minutes > 59 || Seconds < 0 || Seconds > 59) { diff --git a/generic/tclStrIdxTree.c b/generic/tclStrIdxTree.c index afb53e5..b47b4b7 100644 --- a/generic/tclStrIdxTree.c +++ b/generic/tclStrIdxTree.c @@ -171,11 +171,11 @@ TclStrIdxTreeInsertBranch( parent->firstPtr = item; if (parent->lastPtr == child) parent->lastPtr = item; - if (item->nextPtr = child->nextPtr) { + if ( (item->nextPtr = child->nextPtr) ) { item->nextPtr->prevPtr = item; child->nextPtr = NULL; } - if (item->prevPtr = child->prevPtr) { + if ( (item->prevPtr = child->prevPtr) ) { item->prevPtr->nextPtr = item; child->prevPtr = NULL; } @@ -365,7 +365,7 @@ StrIdxTreeObj_DupIntRepProc(Tcl_Obj *srcPtr, Tcl_Obj *copyPtr) srcPtr = (Tcl_Obj*)srcPtr->internalRep.twoPtrValue.ptr1; } /* create smart pointer to it (ptr1 != NULL, ptr2 = NULL) */ - Tcl_InitObjRef(((Tcl_Obj *)copyPtr->internalRep.twoPtrValue.ptr1), + Tcl_InitObjRef(*((Tcl_Obj **)©Ptr->internalRep.twoPtrValue.ptr1), srcPtr); copyPtr->internalRep.twoPtrValue.ptr2 = NULL; copyPtr->typePtr = &StrIdxTreeObjType; @@ -379,7 +379,7 @@ StrIdxTreeObj_FreeIntRepProc(Tcl_Obj *objPtr) && objPtr->internalRep.twoPtrValue.ptr2 == NULL ) { /* is a link */ - Tcl_UnsetObjRef(((Tcl_Obj *)objPtr->internalRep.twoPtrValue.ptr1)); + Tcl_UnsetObjRef(*((Tcl_Obj **)&objPtr->internalRep.twoPtrValue.ptr1)); } else { /* is a tree */ TclStrIdxTree *tree = (TclStrIdxTree*)&objPtr->internalRep.twoPtrValue.ptr1; diff --git a/generic/tclStrIdxTree.h b/generic/tclStrIdxTree.h index 934e28f..305053c 100644 --- a/generic/tclStrIdxTree.h +++ b/generic/tclStrIdxTree.h @@ -49,7 +49,7 @@ typedef struct TclStrIdx { *---------------------------------------------------------------------- */ -inline const char * +static inline const char * TclUtfFindEqual( register const char *cs, /* UTF string to find in cin. */ register const char *cse, /* End of cs */ @@ -66,7 +66,7 @@ TclUtfFindEqual( return ret; } -inline const char * +static inline const char * TclUtfFindEqualNC( register const char *cs, /* UTF string to find in cin. */ register const char *cse, /* End of cs */ @@ -89,7 +89,7 @@ TclUtfFindEqualNC( return ret; } -inline const char * +static inline const char * TclUtfFindEqualNCInLwr( register const char *cs, /* UTF string (in anycase) to find in cin. */ register const char *cse, /* End of cs */ @@ -111,7 +111,7 @@ TclUtfFindEqualNCInLwr( return ret; } -inline const char * +static inline const char * TclUtfNext( register const char *src) /* The current location in the string. */ { diff --git a/unix/Makefile.in b/unix/Makefile.in index 19ab6ec..9bdcacd 100644 --- a/unix/Makefile.in +++ b/unix/Makefile.in @@ -292,7 +292,7 @@ XTTEST_OBJS = xtTestInit.o tclTest.o tclTestObj.o tclTestProcBodyObj.o \ GENERIC_OBJS = regcomp.o regexec.o regfree.o regerror.o tclAlloc.o \ tclAssembly.o tclAsync.o tclBasic.o tclBinary.o tclCkalloc.o \ - tclClock.o tclCmdAH.o tclCmdIL.o tclCmdMZ.o \ + tclClock.o tclClockFmt.o tclCmdAH.o tclCmdIL.o tclCmdMZ.o \ tclCompCmds.o tclCompCmdsGR.o tclCompCmdsSZ.o tclCompExpr.o \ tclCompile.o tclConfig.o tclDate.o tclDictObj.o tclDisassemble.o \ tclEncoding.o tclEnsemble.o \ @@ -304,7 +304,7 @@ GENERIC_OBJS = regcomp.o regexec.o regfree.o regerror.o tclAlloc.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 \ - tclResolve.o tclResult.o tclScan.o tclStringObj.o \ + tclResolve.o tclResult.o tclScan.o tclStringObj.o tclStrIdxTree.o \ tclStrToD.o tclThread.o \ tclThreadAlloc.o tclThreadJoin.o tclThreadStorage.o tclStubInit.o \ tclTimer.o tclTrace.o tclUtf.o tclUtil.o tclVar.o tclZlib.o \ -- cgit v0.12 From bc879a58f2195dd85d8ba603de4a3ae84f1725ec Mon Sep 17 00:00:00 2001 From: sebres Date: Tue, 10 Jan 2017 22:56:13 +0000 Subject: Merge remote-tracking branch 'remotes/fossil/trunk' into sb/trunk-rewrite-clock-in-c; + minor fixes after merge. --- generic/tclClock.c | 3 +-- generic/tclDate.h | 2 +- generic/tclDictObj.c | 50 +++++++++++++++++++++++++++++++---------------- library/msgcat/msgcat.tcl | 2 +- win/makefile.vc | 4 +--- 5 files changed, 37 insertions(+), 24 deletions(-) diff --git a/generic/tclClock.c b/generic/tclClock.c index 1b1faae..a417758 100644 --- a/generic/tclClock.c +++ b/generic/tclClock.c @@ -309,8 +309,7 @@ ClockDeleteCmdProc( ClockClientData *data = clientData; int i; - data->refCount--; - if (data->refCount == 0) { + if (data->refCount-- <= 1) { for (i = 0; i < LIT__END; ++i) { Tcl_DecrRefCount(data->literals[i]); } diff --git a/generic/tclDate.h b/generic/tclDate.h index c9c6726..cf307a6 100644 --- a/generic/tclDate.h +++ b/generic/tclDate.h @@ -275,7 +275,7 @@ typedef struct ClockFmtScnCmdArgs { */ typedef struct ClockClientData { - int refCount; /* Number of live references. */ + size_t refCount; /* Number of live references. */ Tcl_Obj **literals; /* Pool of object literals (common, locale independent). */ Tcl_Obj **mcLiterals; /* Msgcat object literals with mc-keys for search with locale. */ Tcl_Obj **mcLitIdxs; /* Msgcat object indices prefixed with _IDX_, diff --git a/generic/tclDictObj.c b/generic/tclDictObj.c index 8e11bfe..caebbf1 100644 --- a/generic/tclDictObj.c +++ b/generic/tclDictObj.c @@ -145,7 +145,7 @@ typedef struct Dict { * the entries in the order that they are * created. */ int epoch; /* Epoch counter */ - int refcount; /* Reference counter (see above) */ + size_t refCount; /* Reference counter (see above) */ Tcl_Obj *chain; /* Linked list used for invalidating the * string representations of updated nested * dictionaries. */ @@ -395,7 +395,7 @@ DupDictInternalRep( newDict->epoch = 0; newDict->chain = NULL; - newDict->refcount = 1; + newDict->refCount = 1; /* * Store in the object. @@ -430,8 +430,7 @@ FreeDictInternalRep( { Dict *dict = DICT(dictPtr); - dict->refcount--; - if (dict->refcount <= 0) { + if (dict->refCount-- <= 1) { DeleteDict(dict); } dictPtr->typePtr = NULL; @@ -716,7 +715,7 @@ SetDictFromAny( TclFreeIntRep(objPtr); dict->epoch = 0; dict->chain = NULL; - dict->refcount = 1; + dict->refCount = 1; DICT(objPtr) = dict; objPtr->internalRep.twoPtrValue.ptr2 = NULL; objPtr->typePtr = &tclDictType; @@ -1120,7 +1119,7 @@ Tcl_DictObjFirst( searchPtr->dictionaryPtr = (Tcl_Dict) dict; searchPtr->epoch = dict->epoch; searchPtr->next = cPtr->nextPtr; - dict->refcount++; + dict->refCount++; if (keyPtrPtr != NULL) { *keyPtrPtr = Tcl_GetHashKey(&dict->table, &cPtr->entry); } @@ -1234,8 +1233,7 @@ Tcl_DictObjDone( if (searchPtr->epoch != -1) { searchPtr->epoch = -1; dict = (Dict *) searchPtr->dictionaryPtr; - dict->refcount--; - if (dict->refcount <= 0) { + if (dict->refCount-- <= 1) { DeleteDict(dict); } } @@ -1387,7 +1385,7 @@ Tcl_NewDictObj(void) InitChainTable(dict); dict->epoch = 0; dict->chain = NULL; - dict->refcount = 1; + dict->refCount = 1; DICT(dictPtr) = dict; dictPtr->internalRep.twoPtrValue.ptr2 = NULL; dictPtr->typePtr = &tclDictType; @@ -1437,7 +1435,7 @@ Tcl_DbNewDictObj( InitChainTable(dict); dict->epoch = 0; dict->chain = NULL; - dict->refcount = 1; + dict->refCount = 1; DICT(dictPtr) = dict; dictPtr->internalRep.twoPtrValue.ptr2 = NULL; dictPtr->typePtr = &tclDictType; @@ -1981,7 +1979,7 @@ Tcl_DictObjSmartRef( result = Tcl_NewObj(); DICT(result) = dict; - dict->refcount++; + dict->refCount++; result->internalRep.twoPtrValue.ptr2 = NULL; result->typePtr = &tclDictType; @@ -2355,7 +2353,7 @@ DictAppendCmd( Tcl_Obj *const *objv) { Tcl_Obj *dictPtr, *valuePtr, *resultPtr; - int i, allocatedDict = 0; + int allocatedDict = 0; if (objc < 3) { Tcl_WrongNumArgs(interp, 1, objv, "dictVarName key ?value ...?"); @@ -2380,15 +2378,33 @@ DictAppendCmd( if ((objc > 3) || (valuePtr == NULL)) { /* Only go through append activites when something will change. */ + Tcl_Obj *appendObjPtr = NULL; - if (valuePtr == NULL) { + if (objc > 3) { + /* Something to append */ + + if (objc == 4) { + appendObjPtr = objv[3]; + } else if (TCL_OK != TclStringCatObjv(interp, /* inPlace */ 1, + objc-3, objv+3, &appendObjPtr)) { + return TCL_ERROR; + } + } + + if (appendObjPtr == NULL) { + /* => (objc == 3) => (valuePtr == NULL) */ TclNewObj(valuePtr); - } else if (Tcl_IsShared(valuePtr)) { - valuePtr = Tcl_DuplicateObj(valuePtr); + } else if (valuePtr == NULL) { + valuePtr = appendObjPtr; + appendObjPtr = NULL; } - for (i=3 ; i Date: Tue, 10 Jan 2017 22:58:29 +0000 Subject: test-performance: added calibration of `timerate` to minimize influence of the parasitical execution-overhead by extremely fast execution times --- tests-perf/clock.perf.tcl | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/tests-perf/clock.perf.tcl b/tests-perf/clock.perf.tcl index f3b8a10..7b522d0 100644 --- a/tests-perf/clock.perf.tcl +++ b/tests-perf/clock.perf.tcl @@ -19,11 +19,19 @@ ## set testing defaults: set ::env(TCL_TZ) :CET -## warm-up (load clock.tcl, system zones, locales, etc.): +# warm-up interpeter compiler env, clock platform-related features, +# calibrate timerate measurement functionality: +puts -nonewline "Calibration ... "; flush stdout +puts "done: [lrange \ + [timerate -calibrate {}] \ +0 1]" + +## warm-up test-related features (load clock.tcl, system zones, locales, etc.): clock scan "" -gmt 1 clock scan "" clock scan "" -timezone :CET clock scan "" -format "" -locale en +clock scan "" -format "" -locale de ## ------------------------------------------ @@ -239,6 +247,11 @@ proc test-scan {{reptime 1000}} { {clock scan "2009-06-30T18:30:00Z" -format "%Y-%m-%dT%H:%M:%S%z"} {clock scan "2009-06-30T18:30:00 UTC" -format "%Y-%m-%dT%H:%M:%S %z"} + # Scan : locale date-time (en): + {clock scan "06/30/2009 18:30:15" -format "%x %X" -gmt 1 -locale en} + # Scan : locale date-time (de): + {clock scan "30.06.2009 18:30:15" -format "%x %X" -gmt 1 -locale de} + # Scan : dynamic format (cacheable) {clock scan "25.11.2015 10:35:55" -format [string trim "%d.%m.%Y %H:%M:%S "] -base 0 -gmt 1} -- cgit v0.12 From c2ee1525efb460ab0045d454670d0f4b912aebbe Mon Sep 17 00:00:00 2001 From: sebres Date: Tue, 10 Jan 2017 22:59:16 +0000 Subject: [unix] resolving of several warnings (gcc 5.x): - static used in non-static inline function; - x64 int cast on pointer [-Wpointer-to-int-cast]; - (obscure) may be used uninitialized in this function [-Wmaybe-uninitialized]; - TclEnvEpoch initialized and declared extern; --- generic/tclClock.c | 8 ++++---- generic/tclClockFmt.c | 36 ++++++++++++++++++------------------ generic/tclEnv.c | 5 +++-- generic/tclStrIdxTree.c | 2 +- 4 files changed, 26 insertions(+), 25 deletions(-) diff --git a/generic/tclClock.c b/generic/tclClock.c index a417758..a324b65 100644 --- a/generic/tclClock.c +++ b/generic/tclClock.c @@ -336,7 +336,7 @@ ClockDeleteCmdProc( /* *---------------------------------------------------------------------- */ -inline Tcl_Obj * +static inline Tcl_Obj * NormTimezoneObj( ClockClientData *dataPtr, /* Client data containing literal pool */ Tcl_Obj *timezoneObj) @@ -383,7 +383,7 @@ NormTimezoneObj( /* *---------------------------------------------------------------------- */ -inline Tcl_Obj * +static inline Tcl_Obj * ClockGetSystemLocale( ClockClientData *dataPtr, /* Opaque pointer to literal pool, etc. */ Tcl_Interp *interp) /* Tcl interpreter */ @@ -397,7 +397,7 @@ ClockGetSystemLocale( /* *---------------------------------------------------------------------- */ -inline Tcl_Obj * +static inline Tcl_Obj * ClockGetCurrentLocale( ClockClientData *dataPtr, /* Client data containing literal pool */ Tcl_Interp *interp) /* Tcl interpreter */ @@ -782,7 +782,7 @@ ClockConfigureObjCmd( /* *---------------------------------------------------------------------- */ -inline Tcl_Obj* +static inline Tcl_Obj * ClockGetTZData( ClientData clientData, /* Opaque pointer to literal pool, etc. */ Tcl_Interp *interp, /* Tcl interpreter */ diff --git a/generic/tclClockFmt.c b/generic/tclClockFmt.c index a5ddd18..24c0f1d 100644 --- a/generic/tclClockFmt.c +++ b/generic/tclClockFmt.c @@ -41,7 +41,7 @@ CLOCK_LOCALE_LITERAL_ARRAY(MsgCtLitIdxs, "_IDX_"); * Clock scan and format facilities. */ -inline int +static inline int _str2int( int *out, register @@ -71,7 +71,7 @@ _str2int( return TCL_OK; } -inline int +static inline int _str2wideInt( Tcl_WideInt *out, register @@ -101,7 +101,7 @@ _str2wideInt( return TCL_OK; } -inline char * +static inline char * _itoaw( char *buf, register int val, @@ -169,7 +169,7 @@ _itoaw( return buf + width; } -inline char * +static inline char * _witoaw( char *buf, register Tcl_WideInt val, @@ -268,7 +268,7 @@ static struct { unsigned int count; } ClockFmtScnStorage_GC = {NULL, NULL, 0}; -inline void +static inline void ClockFmtScnStorageGC_In(ClockFmtScnStorage *entry) { /* add new entry */ @@ -291,7 +291,7 @@ ClockFmtScnStorageGC_In(ClockFmtScnStorage *entry) ClockFmtScnStorageDelete(delEnt); } } -inline void +static inline void ClockFmtScnStorage_GC_Out(ClockFmtScnStorage *entry) { TclSpliceOut(entry, ClockFmtScnStorage_GC.stackPtr); @@ -311,11 +311,11 @@ ClockFmtScnStorage_GC_Out(ClockFmtScnStorage *entry) static Tcl_HashTable FmtScnHashTable; static int initialized = 0; -inline Tcl_HashEntry * +static inline Tcl_HashEntry * HashEntry4FmtScn(ClockFmtScnStorage *fss) { return (Tcl_HashEntry*)(fss + 1); }; -inline ClockFmtScnStorage * +static inline ClockFmtScnStorage * FmtScn4HashEntry(Tcl_HashEntry *hKeyPtr) { return (ClockFmtScnStorage*)(((char*)hKeyPtr) - sizeof(ClockFmtScnStorage)); }; @@ -836,7 +836,7 @@ DetermineGreedySearchLen(ClockFmtScnCmdArgs *opts, *maxLenPtr = maxLen; } -inline int +static inline int ObjListSearch(ClockFmtScnCmdArgs *opts, DateInfo *info, int *val, Tcl_Obj **lstv, int lstc, @@ -1015,7 +1015,7 @@ done: return idxTree; } -inline int +static inline int ClockStrIdxTreeSearch(ClockFmtScnCmdArgs *opts, DateInfo *info, TclStrIdxTree *idxTree, int *val, int minLen, int maxLen) @@ -1067,7 +1067,7 @@ StaticListSearch(ClockFmtScnCmdArgs *opts, } #endif -inline const char * +static inline const char * FindWordEnd( ClockScanToken *tok, register const char * p, const char * end) @@ -1152,17 +1152,17 @@ ClockScnToken_DayOfWeek_Proc(ClockFmtScnCmdArgs *opts, /* %u %w %Ou %Ow */ if ( curTok != 'a' && curTok != 'A' - && ((minLen <= 1 && maxLen >= 1) || (int)tok->map->data) + && ((minLen <= 1 && maxLen >= 1) || PTR2INT(tok->map->data)) ) { val = -1; - if (!(int)tok->map->data) { + if (PTR2INT(tok->map->data) == 0) { if (*yyInput >= '0' && *yyInput <= '9') { val = *yyInput - '0'; } } else { - idxTree = ClockMCGetListIdxTree(opts, (int)tok->map->data /* mcKey */); + idxTree = ClockMCGetListIdxTree(opts, PTR2INT(tok->map->data) /* mcKey */); if (idxTree == NULL) { return TCL_ERROR; } @@ -1293,7 +1293,7 @@ ClockScnToken_LocaleListMatcher_Proc(ClockFmtScnCmdArgs *opts, /* get or create tree in msgcat dict */ - idxTree = ClockMCGetListIdxTree(opts, (int)tok->map->data /* mcKey */); + idxTree = ClockMCGetListIdxTree(opts, PTR2INT(tok->map->data) /* mcKey */); if (idxTree == NULL) { return TCL_ERROR; } @@ -1602,7 +1602,7 @@ static ClockScanTokenMap ScnWordTokenMap = { }; -inline unsigned int +static inline unsigned int EstimateTokenCount( register const char *fmt, register const char *end) @@ -2143,7 +2143,7 @@ done: return ret; } -inline int +static inline int FrmResultAllocate( register DateFormat *dateFmt, int len) @@ -2751,7 +2751,7 @@ ClockFormat( } } else { const char *s; - Tcl_Obj * mcObj = ClockMCGet(opts, (int)map->data /* mcKey */); + Tcl_Obj * mcObj = ClockMCGet(opts, PTR2INT(map->data) /* mcKey */); if (mcObj == NULL) { goto error; } diff --git a/generic/tclEnv.c b/generic/tclEnv.c index fd0a8ce..0041a40 100644 --- a/generic/tclEnv.c +++ b/generic/tclEnv.c @@ -18,8 +18,9 @@ TCL_DECLARE_MUTEX(envMutex) /* To serialize access to environ. */ -MODULE_SCOPE unsigned long TclEnvEpoch = 0; /* Epoch of the tcl environment - * (if changed with tcl-env). */ +/* MODULE_SCOPE */ +unsigned long TclEnvEpoch = 0; /* Epoch of the tcl environment + * (if changed with tcl-env). */ static struct { int cacheSize; /* Number of env strings in cache. */ diff --git a/generic/tclStrIdxTree.c b/generic/tclStrIdxTree.c index b47b4b7..686c1e4 100644 --- a/generic/tclStrIdxTree.c +++ b/generic/tclStrIdxTree.c @@ -93,7 +93,7 @@ TclStrIdxTreeSearch( /* search in tree */ do { - cin = TclGetString(item->key) + offs; + cinf = cin = TclGetString(item->key) + offs; f = TclUtfFindEqualNCInLwr(s, end, cin, cin + item->length, &cinf); /* if something was found */ if (f > s) { -- cgit v0.12 From 8fa2e7802e55c700d1b4b40bcd58da827584ddde Mon Sep 17 00:00:00 2001 From: sebres Date: Tue, 10 Jan 2017 23:00:05 +0000 Subject: correct output of total resp. average values considering net execution time (overhead considered) --- tests-perf/clock.perf.tcl | 54 +++++++++++++++++++++++++++++------------------ 1 file changed, 33 insertions(+), 21 deletions(-) diff --git a/tests-perf/clock.perf.tcl b/tests-perf/clock.perf.tcl index 7b522d0..16664b2 100644 --- a/tests-perf/clock.perf.tcl +++ b/tests-perf/clock.perf.tcl @@ -46,48 +46,62 @@ proc _test_get_commands {lst} { proc _test_out_total {} { upvar _ _ - if {![llength $_(ittm)]} { + set tcnt [llength $_(itm)] + if {!$tcnt} { puts "" return } set mintm 0x7fffffff set maxtm 0 + set nett 0 + set wtm 0 + set wcnt 0 set i 0 - foreach tm $_(ittm) { + foreach tm $_(itm) { + if {[llength $tm] > 6} { + set nett [expr {$nett + [lindex $tm 6]}] + } + set wtm [expr {$wtm + [lindex $tm 0]}] + set wcnt [expr {$wcnt + [lindex $tm 2]}] + set tm [lindex $tm 0] if {$tm > $maxtm} {set maxtm $tm; set maxi $i} if {$tm < $mintm} {set mintm $tm; set mini $i} incr i } puts [string repeat ** 40] - puts [format "Total %d cases in %.2f sec.:" [llength $_(itcnt)] [expr {[llength $_(itcnt)] * $_(reptime) / 1000.0}]] - lset _(m) 0 [format %.6f [expr [join $_(ittm) +]]] - lset _(m) 2 [expr [join $_(itcnt) +]] - lset _(m) 4 [format %.3f [expr {[lindex $_(m) 2] / ([llength $_(itcnt)] * $_(reptime) / 1000.0)}]] + set s [format "%d cases in %.2f sec." $tcnt [expr {$tcnt * $_(reptime) / 1000.0}]] + if {$nett > 0} { + append s [format " (%.2f nett-sec.)" [expr {$nett / 1000.0}]] + } + puts "Total $s:" + lset _(m) 0 [format %.6f $wtm] + lset _(m) 2 $wcnt + lset _(m) 4 [format %.3f [expr {$wcnt / (($nett ? $nett : ($tcnt * $_(reptime))) / 1000.0)}]] + if {[llength $_(m)] > 6} { + lset _(m) 6 [format %.3f $nett] + } puts $_(m) puts "Average:" - lset _(m) 0 [format %.6f [expr {[lindex $_(m) 0] / [llength $_(itcnt)]}]] - lset _(m) 2 [expr {[lindex $_(m) 2] / [llength $_(itcnt)]}] - lset _(m) 4 [expr {[lindex $_(m) 2] * (1000 / $_(reptime))}] + lset _(m) 0 [format %.6f [expr {[lindex $_(m) 0] / $tcnt}]] + lset _(m) 2 [expr {[lindex $_(m) 2] / $tcnt}] + if {[llength $_(m)] > 6} { + lset _(m) 6 [format %.3f [expr {[lindex $_(m) 6] / $tcnt}]] + lset _(m) 4 [format %.0f [expr {[lindex $_(m) 2] / [lindex $_(m) 6] * 1000}]] + } puts $_(m) puts "Min:" - lset _(m) 0 [lindex $_(ittm) $mini] - lset _(m) 2 [lindex $_(itcnt) $mini] - lset _(m) 2 [lindex $_(itrate) $mini] - puts $_(m) + puts [lindex $_(itm) $mini] puts "Max:" - lset _(m) 0 [lindex $_(ittm) $maxi] - lset _(m) 2 [lindex $_(itcnt) $maxi] - lset _(m) 2 [lindex $_(itrate) $maxi] - puts $_(m) + puts [lindex $_(itm) $maxi] puts [string repeat ** 40] puts "" } proc _test_run {reptime lst {outcmd {puts $_(r)}}} { upvar _ _ - array set _ [list ittm {} itcnt {} itrate {} reptime $reptime] + array set _ [list itm {} reptime $reptime] foreach _(c) [_test_get_commands $lst] { puts "% [regsub -all {\n[ \t]*} $_(c) {; }]" @@ -99,9 +113,7 @@ proc _test_run {reptime lst {outcmd {puts $_(r)}}} { set _(r) [if 1 $_(c)] if {$outcmd ne {}} $outcmd puts [set _(m) [timerate $_(c) $reptime]] - lappend _(ittm) [lindex $_(m) 0] - lappend _(itcnt) [lindex $_(m) 2] - lappend _(itrate) [lindex $_(m) 4] + lappend _(itm) $_(m) puts "" } _test_out_total -- cgit v0.12 From 0a1c05fbb87bf517f2e9a49255351dfde5fc1961 Mon Sep 17 00:00:00 2001 From: sebres Date: Tue, 10 Jan 2017 23:01:23 +0000 Subject: code review and inline documentation --- generic/tclClock.c | 262 +++++++++++++++++++++++++++++++++++++++++++++--- generic/tclClockFmt.c | 3 + generic/tclDate.h | 7 -- generic/tclDictObj.c | 32 +++++- generic/tclInt.h | 7 ++ generic/tclStrIdxTree.c | 3 +- 6 files changed, 288 insertions(+), 26 deletions(-) diff --git a/generic/tclClock.c b/generic/tclClock.c index a324b65..fc7c70c 100644 --- a/generic/tclClock.c +++ b/generic/tclClock.c @@ -167,7 +167,6 @@ static const struct ClockCommand clockCommands[] = { { "GetJulianDayFromEraYearWeekDay", ClockGetjuliandayfromerayearweekdayObjCmd }, { "ParseFormatArgs", ClockParseformatargsObjCmd }, - { "_test", TclStrIdxTreeTestObjCmd }, { NULL, NULL } }; @@ -262,10 +261,11 @@ TclClockInit( /* *---------------------------------------------------------------------- * - * ClockDeleteCmdProc -- + * ClockConfigureClear -- * - * Remove a reference to the clock client data, and clean up memory - * when it's all gone. + * Clean up cached resp. run-time storages used in clock commands. + * + * Shared usage for clean-up (ClockDeleteCmdProc) and "configure -clear". * * Results: * None. @@ -301,7 +301,20 @@ ClockConfigureClear( Tcl_UnsetObjRef(data->UTC2Local.tzName); Tcl_UnsetObjRef(data->Local2UTC.timezoneObj); } - + +/* + *---------------------------------------------------------------------- + * + * ClockDeleteCmdProc -- + * + * Remove a reference to the clock client data, and clean up memory + * when it's all gone. + * + * Results: + * None. + * + *---------------------------------------------------------------------- + */ static void ClockDeleteCmdProc( ClientData clientData) /* Opaque pointer to the client data */ @@ -335,7 +348,20 @@ ClockDeleteCmdProc( /* *---------------------------------------------------------------------- + * + * NormTimezoneObj -- + * + * Normalizes the timezone object (used for caching puposes). + * + * If already cached time zone could be found, returns this + * object (last setup or last used, system (current) or gmt). + * + * Results: + * Normalized tcl object pointer. + * + *---------------------------------------------------------------------- */ + static inline Tcl_Obj * NormTimezoneObj( ClockClientData *dataPtr, /* Client data containing literal pool */ @@ -411,9 +437,23 @@ ClockGetCurrentLocale( return dataPtr->CurrentLocale; } + /* *---------------------------------------------------------------------- + * + * NormLocaleObj -- + * + * Normalizes the locale object (used for caching puposes). + * + * If already cached locale could be found, returns this + * object (current, system (OS) or last used locales). + * + * Results: + * Normalized tcl object pointer. + * + *---------------------------------------------------------------------- */ + static Tcl_Obj * NormLocaleObj( ClockClientData *dataPtr, /* Client data containing literal pool */ @@ -494,7 +534,21 @@ NormLocaleObj( /* *---------------------------------------------------------------------- + * + * ClockMCDict -- + * + * Retrieves a localized storage dictionary object for the given + * locale object. + * + * This corresponds with call `::tcl::clock::mcget locale`. + * Cached representation stored in options (for further access). + * + * Results: + * Tcl-object contains smart reference to msgcat dictionary. + * + *---------------------------------------------------------------------- */ + MODULE_SCOPE Tcl_Obj * ClockMCDict(ClockFmtScnCmdArgs *opts) { @@ -560,6 +614,21 @@ ClockMCDict(ClockFmtScnCmdArgs *opts) return opts->mcDictObj; } +/* + *---------------------------------------------------------------------- + * + * ClockMCGet -- + * + * Retrieves a msgcat value for the given literal integer mcKey + * from localized storage (corresponding given locale object) + * by mcLiterals[mcKey] (e. g. MONTHS_FULL). + * + * Results: + * Tcl-object contains localized value. + * + *---------------------------------------------------------------------- + */ + MODULE_SCOPE Tcl_Obj * ClockMCGet( ClockFmtScnCmdArgs *opts, @@ -581,6 +650,21 @@ ClockMCGet( return valObj; /* or NULL in obscure case if Tcl_DictObjGet failed */ } +/* + *---------------------------------------------------------------------- + * + * ClockMCGetIdx -- + * + * Retrieves an indexed msgcat value for the given literal integer mcKey + * from localized storage (corresponding given locale object) + * by mcLitIdxs[mcKey] (e. g. _IDX_MONTHS_FULL). + * + * Results: + * Tcl-object contains localized indexed value. + * + *---------------------------------------------------------------------- + */ + MODULE_SCOPE Tcl_Obj * ClockMCGetIdx( ClockFmtScnCmdArgs *opts, @@ -609,6 +693,21 @@ ClockMCGetIdx( return valObj; } + +/* + *---------------------------------------------------------------------- + * + * ClockMCSetIdx -- + * + * Sets an indexed msgcat value for the given literal integer mcKey + * in localized storage (corresponding given locale object) + * by mcLitIdxs[mcKey] (e. g. _IDX_MONTHS_FULL). + * + * Results: + * Returns a standard Tcl result. + * + *---------------------------------------------------------------------- + */ MODULE_SCOPE int ClockMCSetIdx( @@ -639,7 +738,23 @@ ClockMCSetIdx( /* *---------------------------------------------------------------------- + * + * ClockConfigureObjCmd -- + * + * This function is invoked to process the Tcl "clock configure" command. + * + * Usage: + * ::tcl::clock::configure ?-option ?value?? + * + * Results: + * Returns a standard Tcl result. + * + * Side effects: + * None. + * + *---------------------------------------------------------------------- */ + static int ClockConfigureObjCmd( ClientData clientData, /* Client data containing literal pool */ @@ -781,7 +896,20 @@ ClockConfigureObjCmd( /* *---------------------------------------------------------------------- + * + * ClockGetTZData -- + * + * Retrieves tzdata table for given normalized timezone. + * + * Results: + * Returns a tcl object with tzdata. + * + * Side effects: + * The tzdata can be cached in ClockClientData structure. + * + *---------------------------------------------------------------------- */ + static inline Tcl_Obj * ClockGetTZData( ClientData clientData, /* Opaque pointer to literal pool, etc. */ @@ -839,9 +967,20 @@ ClockGetTZData( } return ret; } + /* *---------------------------------------------------------------------- + * + * ClockGetSystemTimeZone -- + * + * Returns system (current) timezone. + * + * Results: + * Returns normalized timezone object. + * + *---------------------------------------------------------------------- */ + static Tcl_Obj * ClockGetSystemTimeZone( ClientData clientData, /* Opaque pointer to literal pool, etc. */ @@ -869,9 +1008,20 @@ ClockGetSystemTimeZone( } return dataPtr->SystemTimeZone; } + /* *---------------------------------------------------------------------- + * + * ClockSetupTimeZone -- + * + * Sets up the timezone. Loads tzdata, etc. + * + * Results: + * Returns normalized timezone object. + * + *---------------------------------------------------------------------- */ + MODULE_SCOPE Tcl_Obj * ClockSetupTimeZone( ClientData clientData, /* Opaque pointer to literal pool, etc. */ @@ -908,20 +1058,22 @@ ClockSetupTimeZone( } return NULL; } + /* *---------------------------------------------------------------------- - * ClockFormatNumericTimeZone - * - * Formats a time zone as +hhmmss + * ClockFormatNumericTimeZone -- + * + * Formats a time zone as +hhmmss * * Parameters: - * z - Time zone in seconds east of Greenwich + * z - Time zone in seconds east of Greenwich * * Results: - * Returns the time zone object (formatted in a numeric form) + * Returns the time zone object (formatted in a numeric form) * * Side effects: - * None. + * None. * *---------------------------------------------------------------------- */ @@ -943,6 +1095,7 @@ ClockFormatNumericTimeZone(int z) { } return Tcl_ObjPrintf("%c%02d%02d", sign, h, m); } + /* *---------------------------------------------------------------------- * @@ -1145,7 +1298,20 @@ ClockGetdatefieldsObjCmd( /* *---------------------------------------------------------------------- + * + * ClockGetDateFields -- + * + * Converts given UTC time (seconds in a TclDateFields structure) + * to local time and determines the values that clock routines will + * use in scanning or formatting a date. + * + * Results: + * Date-time values are stored in structure "fields". + * Returns a standard Tcl result. + * + *---------------------------------------------------------------------- */ + int ClockGetDateFields( ClientData clientData, /* Client data of the interpreter */ @@ -1586,6 +1752,7 @@ ConvertLocalToUTCUsingTable( fields->seconds = fields->localSeconds - fields->tzOffset; #if 0 + /* currently unused, test purposes only */ /* * Convert back from UTC, if local times are different - wrong local time * (local time seems to be in between DST-hole). @@ -2404,9 +2571,24 @@ GetJulianDayFromEraYearMonthDay( + ym1o4; } } + /* *---------------------------------------------------------------------- + * + * GetJulianDayFromEraYearDay -- + * + * Given era, year, and dayOfYear (in TclDateFields), and the + * Gregorian transition date, computes the Julian Day Number. + * + * Results: + * None. + * + * Side effects: + * Stores day number in 'julianDay' + * + *---------------------------------------------------------------------- */ + MODULE_SCOPE void GetJulianDayFromEraYearDay( @@ -2740,6 +2922,19 @@ ClockMicrosecondsObjCmd( return TCL_OK; } +/* + *----------------------------------------------------------------------------- + * + * _ClockParseFmtScnArgs -- + * + * Parses the arguments for [clock scan] and [clock format]. + * + * Results: + * Returns a standard Tcl result, and stores parsed options + * (format, the locale, timezone and base) in structure "opts". + * + *----------------------------------------------------------------------------- + */ static int _ClockParseFmtScnArgs( @@ -2853,9 +3048,7 @@ _ClockParseFmtScnArgs( * Returns a standard Tcl result, whose value is a four-element list * comprising the time format, the locale, and the timezone. * - * This function exists because the loop that parses the [clock format] - * options is a known performance "hot spot", and is implemented in an effort - * to speed that particular code up. + * This function exists for backward compatibility purposes. * *----------------------------------------------------------------------------- */ @@ -2919,7 +3112,20 @@ ClockParseformatargsObjCmd( /*---------------------------------------------------------------------- * - * ClockFormatObjCmd - + * ClockFormatObjCmd -- , clock format -- + * + * This function is invoked to process the Tcl "clock format" command. + * + * Formats a count of seconds since the Posix Epoch as a time of day. + * + * The 'clock format' command formats times of day for output. Refer + * to the user documentation to see what it does. + * + * Results: + * Returns a standard Tcl result. + * + * Side effects: + * None. * *---------------------------------------------------------------------- */ @@ -3018,7 +3224,20 @@ done: /*---------------------------------------------------------------------- * - * ClockScanObjCmd - + * ClockScanObjCmd -- , clock scan -- + * + * This function is invoked to process the Tcl "clock scan" command. + * + * Inputs a count of seconds since the Posix Epoch as a time of day. + * + * The 'clock scan' command scans times of day on input. Refer to the + * user documentation to see what it does. + * + * Results: + * Returns a standard Tcl result. + * + * Side effects: + * None. * *---------------------------------------------------------------------- */ @@ -3188,7 +3407,20 @@ done: } /*---------------------------------------------------------------------- + * + * ClockFreeScan -- + * + * Used by ClockScanObjCmd for free scanning without format. + * + * Results: + * Returns a standard Tcl result. + * + * Side effects: + * None. + * + *---------------------------------------------------------------------- */ + int ClockFreeScan( ClientData clientData, /* Client data containing literal pool */ diff --git a/generic/tclClockFmt.c b/generic/tclClockFmt.c index 24c0f1d..ff16714 100644 --- a/generic/tclClockFmt.c +++ b/generic/tclClockFmt.c @@ -881,6 +881,7 @@ ObjListSearch(ClockFmtScnCmdArgs *opts, return TCL_RETURN; } #if 0 +/* currently unused */ static int LocaleListSearch(ClockFmtScnCmdArgs *opts, @@ -1042,6 +1043,7 @@ ClockStrIdxTreeSearch(ClockFmtScnCmdArgs *opts, return TCL_OK; } #if 0 +/* currently unused */ static int StaticListSearch(ClockFmtScnCmdArgs *opts, @@ -1093,6 +1095,7 @@ ClockScnToken_Month_Proc(ClockFmtScnCmdArgs *opts, DateInfo *info, ClockScanToken *tok) { #if 0 +/* currently unused, test purposes only */ static const char * months[] = { /* full */ "January", "February", "March", diff --git a/generic/tclDate.h b/generic/tclDate.h index cf307a6..1519842 100644 --- a/generic/tclDate.h +++ b/generic/tclDate.h @@ -509,11 +509,4 @@ MODULE_SCOPE int ClockFormat(register DateFormat *dateFmt, MODULE_SCOPE void ClockFrmScnClearCaches(void); -/* - * Other externals. - */ - -MODULE_SCOPE unsigned long TclEnvEpoch; /* Epoch of the tcl environment - * (if changed with tcl-env). */ - #endif /* _TCLCLOCK_H */ diff --git a/generic/tclDictObj.c b/generic/tclDictObj.c index caebbf1..b786c4f 100644 --- a/generic/tclDictObj.c +++ b/generic/tclDictObj.c @@ -1960,6 +1960,32 @@ DictSizeCmd( /* *---------------------------------------------------------------------- + * + * Tcl_DictObjSmartRef -- + * + * This function returns new tcl-object with the smart reference to + * dictionary object. + * + * Object returned with this function is a smart reference (pointer), + * so new object of type tclDictType, that directly references given + * dictionary object (with internally increased refCount). + * + * The usage of such pointer objects allows to hold more as one + * reference to the same real dictionary object, allows to make a pointer + * to part of another dictionary, allows to change the dictionary without + * regarding of the "shared" state of the dictionary object. + * + * Prevents "called with shared object" exception if object is multiple + * referenced. + * + * Results: + * The newly create object (contains smart reference) is returned. + * The returned object has a ref count of 0. + * + * Side effects: + * Increases ref count of the referenced dictionary. + * + *---------------------------------------------------------------------- */ Tcl_Obj * @@ -1991,9 +2017,9 @@ Tcl_DictObjSmartRef( * * DictSmartRefCmd -- * - * This function implements the "dict smartref" Tcl command. See the user - * documentation for details on what it does, and TIP#111 for the formal - * specification. + * This function implements the "dict smartref" Tcl command. + * + * See description of Tcl_DictObjSmartRef for details. * * Results: * A standard Tcl result. diff --git a/generic/tclInt.h b/generic/tclInt.h index a569788..15cb355 100644 --- a/generic/tclInt.h +++ b/generic/tclInt.h @@ -4886,6 +4886,13 @@ typedef struct NRE_callback { #define Tcl_Free(ptr) TclpFree(ptr) #endif +/* + * Other externals. + */ + +MODULE_SCOPE unsigned long TclEnvEpoch; /* Epoch of the tcl environment + * (if changed with tcl-env). */ + #endif /* _TCLINT */ /* diff --git a/generic/tclStrIdxTree.c b/generic/tclStrIdxTree.c index 686c1e4..773eb6a 100644 --- a/generic/tclStrIdxTree.c +++ b/generic/tclStrIdxTree.c @@ -418,7 +418,8 @@ TclStrIdxTreeGetFromObj(Tcl_Obj *objPtr) { /* * Several debug primitives */ -#if 1 +#if 0 +/* currently unused, debug resp. test purposes only */ void TclStrIdxTreePrint( -- cgit v0.12 From 01697f2acc39c303ebeedd2f9ebb82380cb388ce Mon Sep 17 00:00:00 2001 From: sebres Date: Tue, 10 Jan 2017 23:02:02 +0000 Subject: "clock add" rewritten in C, using common functionality of "clock scan" (and freescan)... test-performance.tcl: test cases extended to cover "clock add" --- generic/tclClock.c | 735 +++++++++++++++++++++++++++++++--------------- generic/tclDate.h | 2 +- library/clock.tcl | 328 --------------------- library/init.tcl | 2 +- tests-perf/clock.perf.tcl | 39 +++ tests/clock.test | 17 +- 6 files changed, 559 insertions(+), 564 deletions(-) diff --git a/generic/tclClock.c b/generic/tclClock.c index fc7c70c..791898b 100644 --- a/generic/tclClock.c +++ b/generic/tclClock.c @@ -116,9 +116,6 @@ static int ClockMicrosecondsObjCmd( static int ClockMillisecondsObjCmd( ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *const objv[]); -static int ClockParseformatargsObjCmd( - ClientData clientData, Tcl_Interp *interp, - int objc, Tcl_Obj *const objv[]); static int ClockSecondsObjCmd( ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *const objv[]); @@ -128,10 +125,17 @@ static int ClockFormatObjCmd( static int ClockScanObjCmd( ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *const objv[]); +static int ClockScanCommit( + ClientData clientData, register DateInfo *info, + register ClockFmtScnCmdArgs *opts); static int ClockFreeScan( - ClientData clientData, Tcl_Interp *interp, register DateInfo *info, Tcl_Obj *strObj, ClockFmtScnCmdArgs *opts); +static int ClockCalcRelTime( + register DateInfo *info, ClockFmtScnCmdArgs *opts); +static int ClockAddObjCmd( + ClientData clientData, Tcl_Interp *interp, + int objc, Tcl_Obj *const objv[]); static struct tm * ThreadSafeLocalTime(const time_t *); static unsigned long TzsetGetEpoch(void); static void TzsetIfNecessary(void); @@ -151,6 +155,7 @@ struct ClockCommand { }; static const struct ClockCommand clockCommands[] = { + { "add", ClockAddObjCmd }, { "clicks", ClockClicksObjCmd }, { "getenv", ClockGetenvObjCmd }, { "microseconds", ClockMicrosecondsObjCmd }, @@ -166,7 +171,6 @@ static const struct ClockCommand clockCommands[] = { ClockGetjuliandayfromerayearmonthdayObjCmd }, { "GetJulianDayFromEraYearWeekDay", ClockGetjuliandayfromerayearweekdayObjCmd }, - { "ParseFormatArgs", ClockParseformatargsObjCmd }, { NULL, NULL } }; @@ -763,7 +767,6 @@ ClockConfigureObjCmd( Tcl_Obj *const objv[]) /* Parameter vector */ { ClockClientData *dataPtr = clientData; - Tcl_Obj **litPtr = dataPtr->literals; static const char *const options[] = { "-system-tz", "-setup-tz", "-default-locale", @@ -814,7 +817,7 @@ ClockConfigureObjCmd( Tcl_SetObjRef(dataPtr->LastSetupTimeZone, timezoneObj); Tcl_UnsetObjRef(dataPtr->LastSetupTZData); } - if (timezoneObj == litPtr[LIT_GMT]) { + if (timezoneObj == dataPtr->literals[LIT_GMT]) { optionIndex = CLOCK_SETUP_GMT; } else if (timezoneObj == dataPtr->SystemTimeZone) { optionIndex = CLOCK_SETUP_NOP; @@ -1158,7 +1161,7 @@ ClockConvertlocaltoutcObjCmd( "found in dictionary", -1)); return TCL_ERROR; } - if ((Tcl_GetWideIntFromObj(interp, secondsObj, + if ((TclGetWideIntFromObj(interp, secondsObj, &fields.localSeconds) != TCL_OK) || (TclGetIntFromObj(interp, objv[3], &changeover) != TCL_OK) || ConvertLocalToUTC(clientData, interp, &fields, objv[2], changeover)) { @@ -1238,7 +1241,7 @@ ClockGetdatefieldsObjCmd( Tcl_WrongNumArgs(interp, 1, objv, "seconds timezone changeover"); return TCL_ERROR; } - if (Tcl_GetWideIntFromObj(interp, objv[1], &fields.seconds) != TCL_OK + if (TclGetWideIntFromObj(interp, objv[1], &fields.seconds) != TCL_OK || TclGetIntFromObj(interp, objv[3], &changeover) != TCL_OK) { return TCL_ERROR; } @@ -1762,7 +1765,7 @@ ConvertLocalToUTCUsingTable( int corrOffset; Tcl_WideInt backCompVal; /* check DST-hole interval contains UTC time */ - Tcl_GetWideIntFromObj(NULL, cellv[0], &backCompVal); + TclGetWideIntFromObj(NULL, cellv[0], &backCompVal); if ( fields->seconds >= backCompVal - fields->tzOffset && fields->seconds <= backCompVal + fields->tzOffset ) { @@ -2148,7 +2151,7 @@ LookupLastTransition( */ if (Tcl_ListObjIndex(interp, rowv[0], 0, &compObj) != TCL_OK - || Tcl_GetWideIntFromObj(interp, compObj, &compVal) != TCL_OK) { + || TclGetWideIntFromObj(interp, compObj, &compVal) != TCL_OK) { return NULL; } @@ -2170,7 +2173,7 @@ LookupLastTransition( int m = (l + u + 1) / 2; if (Tcl_ListObjIndex(interp, rowv[m], 0, &compObj) != TCL_OK || - Tcl_GetWideIntFromObj(interp, compObj, &compVal) != TCL_OK) { + TclGetWideIntFromObj(interp, compObj, &compVal) != TCL_OK) { return NULL; } if (tick >= compVal) { @@ -2922,10 +2925,21 @@ ClockMicrosecondsObjCmd( return TCL_OK; } +static inline void +ClockInitFmtScnArgs( + ClientData clientData, + Tcl_Interp *interp, + ClockFmtScnCmdArgs *opts) +{ + memset(opts, 0, sizeof(*opts)); + opts->clientData = clientData; + opts->interp = interp; +} + /* *----------------------------------------------------------------------------- * - * _ClockParseFmtScnArgs -- + * ClockParseFmtScnArgs -- * * Parses the arguments for [clock scan] and [clock format]. * @@ -2936,92 +2950,116 @@ ClockMicrosecondsObjCmd( *----------------------------------------------------------------------------- */ +#define CLC_FMT_ARGS (0) +#define CLC_SCN_ARGS (1 << 0) +#define CLC_ADD_ARGS (1 << 1) + static int -_ClockParseFmtScnArgs( - ClientData clientData, /* Client data containing literal pool */ - Tcl_Interp *interp, /* Tcl interpreter */ +ClockParseFmtScnArgs( + register + ClockFmtScnCmdArgs *opts, /* Result vector: format, locale, timezone... */ + TclDateFields *date, /* Extracted date-time corresponding base + * (by scan or add) resp. clockval (by format) */ int objc, /* Parameter count */ Tcl_Obj *const objv[], /* Parameter vector */ - ClockFmtScnCmdArgs *opts, /* Result vector: format, locale, timezone... */ - int forScan /* Flag to differentiate between format and scan */ + int flags /* Flags, differentiates between format, scan, add */ ) { - ClockClientData *dataPtr = clientData; - Tcl_Obj **litPtr = dataPtr->literals; + Tcl_Interp *interp = opts->interp; + ClockClientData *dataPtr = opts->clientData; int gmtFlag = 0; - static const char *const options[2][6] = { - { /* Format command line options */ - "-format", "-gmt", "-locale", - "-timezone", NULL }, - { /* Scan command line options */ + static const char *const options[] = { "-format", "-gmt", "-locale", - "-timezone", "-base", NULL } + "-timezone", "-base", NULL }; enum optionInd { - CLOCK_FORMAT_FORMAT, CLOCK_FORMAT_GMT, CLOCK_FORMAT_LOCALE, - CLOCK_FORMAT_TIMEZONE, CLOCK_FORMAT_BASE + CLC_ARGS_FORMAT, CLC_ARGS_GMT, CLC_ARGS_LOCALE, + CLC_ARGS_TIMEZONE, CLC_ARGS_BASE }; int optionIndex; /* Index of an option. */ int saw = 0; /* Flag == 1 if option was seen already. */ int i; + Tcl_WideInt baseVal; /* Base time, expressed in seconds from the Epoch */ + + /* clock value (as current base) */ + if ( !(flags & (CLC_SCN_ARGS)) ) { + opts->baseObj = objv[1]; + saw |= (1 << CLC_ARGS_BASE); + } /* * Extract values for the keywords. */ - memset(opts, 0, sizeof(*opts)); for (i = 2; i < objc; i+=2) { - if (Tcl_GetIndexFromObj(interp, objv[i], options[forScan], + /* bypass integers (offsets) by "clock add" */ + if (flags & CLC_ADD_ARGS) { + Tcl_WideInt num; + if (TclGetWideIntFromObj(NULL, objv[i], &num) == TCL_OK) { + continue; + } + } + /* get option */ + if (Tcl_GetIndexFromObj(interp, objv[i], options, "option", 0, &optionIndex) != TCL_OK) { - Tcl_SetErrorCode(interp, "CLOCK", "badOption", - Tcl_GetString(objv[i]), NULL); - return TCL_ERROR; + goto badOption; + } + /* if already specified */ + if (saw & (1 << optionIndex)) { + Tcl_SetObjResult(interp, Tcl_ObjPrintf( + "bad option \"%s\": doubly present", + TclGetString(objv[i])) + ); + goto badOption; } switch (optionIndex) { - case CLOCK_FORMAT_FORMAT: + case CLC_ARGS_FORMAT: + if (flags & CLC_ADD_ARGS) { + goto badOptionMsg; + } opts->formatObj = objv[i+1]; break; - case CLOCK_FORMAT_GMT: + case CLC_ARGS_GMT: if (Tcl_GetBooleanFromObj(interp, objv[i+1], &gmtFlag) != TCL_OK){ return TCL_ERROR; } break; - case CLOCK_FORMAT_LOCALE: + case CLC_ARGS_LOCALE: opts->localeObj = objv[i+1]; break; - case CLOCK_FORMAT_TIMEZONE: + case CLC_ARGS_TIMEZONE: opts->timezoneObj = objv[i+1]; break; - case CLOCK_FORMAT_BASE: + case CLC_ARGS_BASE: + if ( !(flags & (CLC_SCN_ARGS)) ) { + goto badOptionMsg; + } opts->baseObj = objv[i+1]; break; } - saw |= 1 << optionIndex; + saw |= (1 << optionIndex); } /* * Check options. */ - if ((saw & (1 << CLOCK_FORMAT_GMT)) - && (saw & (1 << CLOCK_FORMAT_TIMEZONE))) { + if ((saw & (1 << CLC_ARGS_GMT)) + && (saw & (1 << CLC_ARGS_TIMEZONE))) { Tcl_SetResult(interp, "cannot use -gmt and -timezone in same call", TCL_STATIC); Tcl_SetErrorCode(interp, "CLOCK", "gmtWithTimezone", NULL); return TCL_ERROR; } if (gmtFlag) { - opts->timezoneObj = litPtr[LIT_GMT]; + opts->timezoneObj = dataPtr->literals[LIT_GMT]; } - opts->clientData = clientData; - opts->interp = interp; - /* If time zone not specified use system time zone */ if ( opts->timezoneObj == NULL || TclGetString(opts->timezoneObj) == NULL || opts->timezoneObj->length == 0 ) { - opts->timezoneObj = ClockGetSystemTimeZone(clientData, interp); + opts->timezoneObj = ClockGetSystemTimeZone(opts->clientData, interp); if (opts->timezoneObj == NULL) { return TCL_ERROR; } @@ -3029,85 +3067,90 @@ _ClockParseFmtScnArgs( /* Setup timezone (normalize object if needed and load TZ on demand) */ - opts->timezoneObj = ClockSetupTimeZone(clientData, interp, opts->timezoneObj); + opts->timezoneObj = ClockSetupTimeZone(opts->clientData, interp, opts->timezoneObj); if (opts->timezoneObj == NULL) { return TCL_ERROR; } - return TCL_OK; -} - -/* - *----------------------------------------------------------------------------- - * - * ClockParseformatargsObjCmd -- - * - * Parses the arguments for [clock format]. - * - * Results: - * Returns a standard Tcl result, whose value is a four-element list - * comprising the time format, the locale, and the timezone. - * - * This function exists for backward compatibility purposes. - * - *----------------------------------------------------------------------------- - */ + /* Base (by scan or add) or clock value (by format) */ -static int -ClockParseformatargsObjCmd( - ClientData clientData, /* Client data containing literal pool */ - Tcl_Interp *interp, /* Tcl interpreter */ - int objc, /* Parameter count */ - Tcl_Obj *const objv[]) /* Parameter vector */ -{ - ClockClientData *dataPtr = clientData; - Tcl_Obj **literals = dataPtr->literals; - ClockFmtScnCmdArgs opts; /* Format, locale and timezone */ - Tcl_WideInt clockVal; /* Clock value - just used to parse. */ - int ret; + if (opts->baseObj != NULL) { + if (TclGetWideIntFromObj(NULL, opts->baseObj, &baseVal) != TCL_OK) { - /* - * Args consist of a time followed by keyword-value pairs. - */ + /* we accept "-now" as current date-time */ + const char *const nowOpts[] = { + "-now", NULL + }; + int idx; + if (Tcl_GetIndexFromObj(NULL, opts->baseObj, nowOpts, "seconds or -now", + TCL_EXACT, &idx) == TCL_OK + ) { + goto baseNow; + } - if (objc < 2 || (objc % 2) != 0) { - Tcl_WrongNumArgs(interp, 0, objv, - "clock format clockval ?-format string? " - "?-gmt boolean? ?-locale LOCALE? ?-timezone ZONE?"); - Tcl_SetErrorCode(interp, "CLOCK", "wrongNumArgs", NULL); - return TCL_ERROR; - } + Tcl_SetObjResult(interp, Tcl_ObjPrintf( + "expected integer but got \"%s\"", + Tcl_GetString(opts->baseObj))); + Tcl_SetErrorCode(interp, "TCL", "VALUE", "INTEGER", NULL); + i = 1; + goto badOption; + } + /* + * seconds could be an unsigned number that overflowed. Make sure + * that it isn't. + */ - /* - * Extract values for the keywords. - */ + if (opts->baseObj->typePtr == &tclBignumType) { + Tcl_SetObjResult(interp, dataPtr->literals[LIT_INTEGER_VALUE_TOO_LARGE]); + return TCL_ERROR; + } - ret = _ClockParseFmtScnArgs(clientData, interp, objc, objv, - &opts, 0); - if (ret != TCL_OK) { - return ret; + } else { + +baseNow: + { + Tcl_Time now; + Tcl_GetTime(&now); + baseVal = (Tcl_WideInt) now.sec; + } } /* - * Check options. + * Extract year, month and day from the base time for the parser to use as + * defaults */ - if (Tcl_GetWideIntFromObj(interp, objv[1], &clockVal) != TCL_OK) { - return TCL_ERROR; + /* check base fields already cached (by TZ, last-second cache) */ + if ( dataPtr->lastBase.timezoneObj == opts->timezoneObj + && dataPtr->lastBase.Date.seconds == baseVal) { + memcpy(date, &dataPtr->lastBase.Date, ClockCacheableDateFieldsSize); + } else { + /* extact fields from base */ + date->seconds = baseVal; + if (ClockGetDateFields(opts->clientData, interp, date, opts->timezoneObj, + GREGORIAN_CHANGE_DATE) != TCL_OK) { /* TODO - GREGORIAN_CHANGE_DATE should be locale-dependent */ + return TCL_ERROR; + } + /* cache last base */ + memcpy(&dataPtr->lastBase.Date, date, ClockCacheableDateFieldsSize); + Tcl_SetObjRef(dataPtr->lastBase.timezoneObj, opts->timezoneObj); } - if (opts.formatObj == NULL) - opts.formatObj = literals[LIT__DEFAULT_FORMAT]; - if (opts.localeObj == NULL) - opts.localeObj = literals[LIT_C]; - if (opts.timezoneObj == NULL) - opts.timezoneObj = literals[LIT__NIL]; - /* - * Return options as a list. - */ - - Tcl_SetObjResult(interp, Tcl_NewListObj(3, (Tcl_Obj**)&opts.formatObj)); return TCL_OK; + +badOptionMsg: + + Tcl_SetObjResult(interp, Tcl_ObjPrintf( + "bad option \"%s\": unexpected for command \"%s\"", + TclGetString(objv[i]), TclGetString(objv[0])) + ); + +badOption: + + Tcl_SetErrorCode(interp, "CLOCK", "badOption", + i < objc ? Tcl_GetString(objv[i]) : NULL, NULL); + + return TCL_ERROR; } /*---------------------------------------------------------------------- @@ -3141,11 +3184,11 @@ ClockFormatObjCmd( int ret; ClockFmtScnCmdArgs opts; /* Format, locale, timezone and base */ - Tcl_WideInt clockVal; /* Time, expressed in seconds from the Epoch */ DateFormat dateFmt; /* Common structure used for formatting */ + /* even number of arguments */ if ((objc & 1) == 1) { - Tcl_WrongNumArgs(interp, 1, objv, "clockval " + Tcl_WrongNumArgs(interp, 1, objv, "clockval|-now " "?-format string? " "?-gmt boolean? " "?-locale LOCALE? ?-timezone ZONE?"); @@ -3153,53 +3196,17 @@ ClockFormatObjCmd( return TCL_ERROR; } - /* - * Extract values for the keywords. - */ - - ret = _ClockParseFmtScnArgs(clientData, interp, objc, objv, - &opts, 0); - if (ret != TCL_OK) { - return ret; - } - - ret = TCL_ERROR; - - if (Tcl_GetWideIntFromObj(interp, objv[1], &clockVal) != TCL_OK) { - return TCL_ERROR; - } - - /* - * seconds could be an unsigned number that overflowed. Make sure - * that it isn't. - */ - - if (objv[1]->typePtr == &tclBignumType) { - Tcl_SetObjResult(interp, dataPtr->literals[LIT_INTEGER_VALUE_TOO_LARGE]); - return TCL_ERROR; - } - memset(&dateFmt, 0, sizeof(dateFmt)); /* - * Extract year, month and day from the base time for the parser to use as - * defaults + * Extract values for the keywords. */ - /* check base fields already cached (by TZ, last-second cache) */ - if ( dataPtr->lastBase.timezoneObj == opts.timezoneObj - && dataPtr->lastBase.Date.seconds == clockVal) { - memcpy(&dateFmt.date, &dataPtr->lastBase.Date, ClockCacheableDateFieldsSize); - } else { - /* extact fields from base */ - dateFmt.date.seconds = clockVal; - if (ClockGetDateFields(clientData, interp, &dateFmt.date, opts.timezoneObj, - GREGORIAN_CHANGE_DATE) != TCL_OK) { - goto done; - } - /* cache last base */ - memcpy(&dataPtr->lastBase.Date, &dateFmt.date, ClockCacheableDateFieldsSize); - Tcl_SetObjRef(dataPtr->lastBase.timezoneObj, opts.timezoneObj); + ClockInitFmtScnArgs(clientData, interp, &opts); + ret = ClockParseFmtScnArgs(&opts, &dateFmt.date, objc, objv, + CLC_FMT_ARGS); + if (ret != TCL_OK) { + goto done; } /* Default format */ @@ -3249,14 +3256,12 @@ ClockScanObjCmd( int objc, /* Parameter count */ Tcl_Obj *const objv[]) /* Parameter values */ { - ClockClientData *dataPtr = clientData; - int ret; ClockFmtScnCmdArgs opts; /* Format, locale, timezone and base */ - Tcl_WideInt baseVal; /* Base time, expressed in seconds from the Epoch */ DateInfo yy; /* Common structure used for parsing */ DateInfo *info = &yy; + /* even number of arguments */ if ((objc & 1) == 1) { Tcl_WrongNumArgs(interp, 1, objv, "string " "?-base seconds? " @@ -3267,59 +3272,17 @@ ClockScanObjCmd( return TCL_ERROR; } + ClockInitDateInfo(&yy); + /* * Extract values for the keywords. */ - ret = _ClockParseFmtScnArgs(clientData, interp, objc, objv, - &opts, 1); + ClockInitFmtScnArgs(clientData, interp, &opts); + ret = ClockParseFmtScnArgs(&opts, &yy.date, objc, objv, + CLC_SCN_ARGS); if (ret != TCL_OK) { - return ret; - } - - ret = TCL_ERROR; - - if (opts.baseObj != NULL) { - if (Tcl_GetWideIntFromObj(interp, opts.baseObj, &baseVal) != TCL_OK) { - return TCL_ERROR; - } - /* - * seconds could be an unsigned number that overflowed. Make sure - * that it isn't. - */ - - if (opts.baseObj->typePtr == &tclBignumType) { - Tcl_SetObjResult(interp, dataPtr->literals[LIT_INTEGER_VALUE_TOO_LARGE]); - return TCL_ERROR; - } - - } else { - Tcl_Time now; - Tcl_GetTime(&now); - baseVal = (Tcl_WideInt) now.sec; - } - - ClockInitDateInfo(info); - - /* - * Extract year, month and day from the base time for the parser to use as - * defaults - */ - - /* check base fields already cached (by TZ, last-second cache) */ - if ( dataPtr->lastBase.timezoneObj == opts.timezoneObj - && dataPtr->lastBase.Date.seconds == baseVal) { - memcpy(&yydate, &dataPtr->lastBase.Date, ClockCacheableDateFieldsSize); - } else { - /* extact fields from base */ - yydate.seconds = baseVal; - if (ClockGetDateFields(clientData, interp, &yydate, opts.timezoneObj, - GREGORIAN_CHANGE_DATE) != TCL_OK) { - goto done; - } - /* cache last base */ - memcpy(&dataPtr->lastBase.Date, &yydate, ClockCacheableDateFieldsSize); - Tcl_SetObjRef(dataPtr->lastBase.timezoneObj, opts.timezoneObj); + goto done; } /* seconds are in localSeconds (relative base date), so reset time here */ @@ -3336,18 +3299,54 @@ ClockScanObjCmd( Tcl_SetErrorCode(interp, "CLOCK", "flagWithLegacyFormat", NULL); return TCL_ERROR; } - ret = ClockFreeScan(clientData, interp, info, objv[1], &opts); + ret = ClockFreeScan(&yy, objv[1], &opts); } else { /* Use compiled version of Scan - */ - ret = ClockScan(info, objv[1], &opts); + ret = ClockScan(&yy, objv[1], &opts); + } + + /* Convert date info structure into UTC seconds */ + + if (ret == TCL_OK) { + ret = ClockScanCommit(clientData, &yy, &opts); } +done: + + Tcl_UnsetObjRef(yy.date.tzName); + if (ret != TCL_OK) { - goto done; + return ret; } + Tcl_SetObjResult(interp, Tcl_NewWideIntObj(yy.date.seconds)); + return TCL_OK; +} + +/*---------------------------------------------------------------------- + * + * ClockScanCommit -- + * + * Converts date info structure into UTC seconds. + * + * Results: + * Returns a standard Tcl result. + * + * Side effects: + * None. + * + *---------------------------------------------------------------------- + */ + +static int +ClockScanCommit( + ClientData clientData, /* Client data containing literal pool */ + register DateInfo *info, /* Clock scan info structure */ + register + ClockFmtScnCmdArgs *opts) /* Format, locale, timezone and base */ +{ /* If needed assemble julianDay using year, month, etc. */ if (info->flags & CLF_ASSEMBLE_JULIANDAY) { if ((info->flags & CLF_ISO8601)) { @@ -3362,13 +3361,12 @@ ClockScanObjCmd( } /* some overflow checks, if not extended */ - if (!(opts.flags & CLF_EXTENDED)) { + if (!(opts->flags & CLF_EXTENDED)) { if (yydate.julianDay > 5373484) { - Tcl_SetObjResult(interp, Tcl_NewStringObj( + Tcl_SetObjResult(opts->interp, Tcl_NewStringObj( "requested date too large to represent", -1)); - Tcl_SetErrorCode(interp, "CLOCK", "dateTooLarge", NULL); - ret = TCL_ERROR; - goto done; + Tcl_SetErrorCode(opts->interp, "CLOCK", "dateTooLarge", NULL); + return TCL_ERROR; } } @@ -3382,9 +3380,9 @@ ClockScanObjCmd( } if (info->flags & (CLF_ASSEMBLE_SECONDS|CLF_ASSEMBLE_JULIANDAY|CLF_LOCALSEC)) { - if (ConvertLocalToUTC(clientData, interp, &yydate, opts.timezoneObj, + if (ConvertLocalToUTC(clientData, opts->interp, &yydate, opts->timezoneObj, GREGORIAN_CHANGE_DATE) != TCL_OK) { - goto done; + return TCL_ERROR; } } @@ -3392,17 +3390,6 @@ ClockScanObjCmd( yydate.seconds += yyRelSeconds; - ret = TCL_OK; - -done: - - Tcl_UnsetObjRef(yydate.tzName); - - if (ret != TCL_OK) { - return ret; - } - - Tcl_SetObjResult(interp, Tcl_NewWideIntObj(yydate.seconds)); return TCL_OK; } @@ -3423,8 +3410,6 @@ done: int ClockFreeScan( - ClientData clientData, /* Client data containing literal pool */ - Tcl_Interp *interp, /* Tcl interpreter */ register DateInfo *info, /* Date fields used for parsing & converting * simultaneously a yy-parse structure of the @@ -3432,7 +3417,8 @@ ClockFreeScan( Tcl_Obj *strObj, /* String containing the time to scan */ ClockFmtScnCmdArgs *opts) /* Command options */ { - ClockClientData *dataPtr = clientData; + Tcl_Interp *interp = opts->interp; + ClockClientData *dataPtr = opts->clientData; int ret = TCL_ERROR; @@ -3487,7 +3473,7 @@ ClockFreeScan( 60 * minEast + 3600 * dstFlag); Tcl_IncrRefCount(tzObjStor); - opts->timezoneObj = ClockSetupTimeZone(clientData, interp, tzObjStor); + opts->timezoneObj = ClockSetupTimeZone(dataPtr, interp, tzObjStor); Tcl_DecrRefCount(tzObjStor); if (opts->timezoneObj == NULL) { @@ -3531,6 +3517,39 @@ ClockFreeScan( * Do relative times */ + ret = ClockCalcRelTime(info, opts); + + /* Free scanning completed - date ready */ + +done: + + return ret; +} + +/*---------------------------------------------------------------------- + * + * ClockCalcRelTime -- + * + * Used for calculating of relative times. + * + * Results: + * Returns a standard Tcl result. + * + * Side effects: + * None. + * + *---------------------------------------------------------------------- + */ +int +ClockCalcRelTime( + register + DateInfo *info, /* Date fields used for converting */ + ClockFmtScnCmdArgs *opts) /* Command options */ +{ + /* + * Because some calculations require in-between conversion of the + * julian day, we can repeat this processing multiple times + */ repeat_rel: if (yyHaveRel) { @@ -3667,13 +3686,267 @@ repeat_rel: info->flags |= CLF_ASSEMBLE_DATE|CLF_ASSEMBLE_SECONDS; } - /* Free scanning completed - date ready */ + return TCL_OK; +} + + +/*---------------------------------------------------------------------- + * + * ClockWeekdaysOffs -- + * + * Get offset in days for the number of week days corresponding the + * given day of week (skipping Saturdays and Sundays). + * + * + * Results: + * Returns a day increment adjusted the given weekdays + * + *---------------------------------------------------------------------- + */ + +static inline int +ClockWeekdaysOffs( + register int dayOfWeek, + register int offs) +{ + register int weeks, resDayOfWeek; + + /* offset in days */ + weeks = offs / 5; + offs = offs % 5; + /* compiler fix for negative offs - wrap (0, -1) -> (-1, 4) */ + if (offs < 0) { + weeks--; + offs = 5 + offs; + } + offs += 7 * weeks; + + /* resulting day of week */ + { + register int day = (offs % 7); + /* compiler fix for negative offs - wrap (0, -1) -> (-1, 6) */ + if (day < 0) { + day = 7 + day; + } + resDayOfWeek = dayOfWeek + day; + } + + /* adjust if we start from a weekend */ + if (dayOfWeek > 5) { + int adj = 5 - dayOfWeek; + offs += adj; + resDayOfWeek += adj; + } + + /* adjust if we end up on a weekend */ + if (resDayOfWeek > 5) { + offs += 2; + } + + return offs; +} + + + +/*---------------------------------------------------------------------- + * + * ClockAddObjCmd -- , clock add -- + * + * Adds an offset to a given time. + * + * Refer to the user documentation to see what it exactly does. + * + * Syntax: + * clock add clockval ?count unit?... ?-option value? + * + * Parameters: + * clockval -- Starting time value + * count -- Amount of a unit of time to add + * unit -- Unit of time to add, must be one of: + * years year months month weeks week + * days day hours hour minutes minute + * seconds second + * + * Options: + * -gmt BOOLEAN + * Flag synonymous with '-timezone :GMT' + * -timezone ZONE + * Name of the time zone in which calculations are to be done. + * -locale NAME + * Name of the locale in which calculations are to be done. + * Used to determine the Gregorian change date. + * + * Results: + * Returns a standard Tcl result with the given time adjusted + * by the given offset(s) in order. + * + * Notes: + * It is possible that adding a number of months or years will adjust the + * day of the month as well. For instance, the time at one month after + * 31 January is either 28 or 29 February, because February has fewer + * than 31 days. + * + *---------------------------------------------------------------------- + */ + +int +ClockAddObjCmd( + ClientData clientData, /* Client data containing literal pool */ + Tcl_Interp *interp, /* Tcl interpreter */ + int objc, /* Parameter count */ + Tcl_Obj *const objv[]) /* Parameter values */ +{ + ClockClientData *dataPtr = clientData; + int ret; + ClockFmtScnCmdArgs opts; /* Format, locale, timezone and base */ + DateInfo yy; /* Common structure used for parsing */ + DateInfo *info = &yy; + + /* add "week" to units also (because otherwise ambiguous) */ + static const char *const units[] = { + "years", "months", "week", "weeks", + "days", "weekdays", + "hours", "minutes", "seconds", + NULL + }; + enum unitInd { + CLC_ADD_YEARS, CLC_ADD_MONTHS, CLC_ADD_WEEK, CLC_ADD_WEEKS, + CLC_ADD_DAYS, CLC_ADD_WEEKDAYS, + CLC_ADD_HOURS, CLC_ADD_MINUTES, CLC_ADD_SECONDS + }; + int unitIndex; /* Index of an option. */ + int i; + Tcl_WideInt offs; - ret = TCL_OK; + /* even number of arguments */ + if ((objc & 1) == 1) { + Tcl_WrongNumArgs(interp, 1, objv, "clockval|-now ?number units?..." + "?-gmt boolean? " + "?-locale LOCALE? ?-timezone ZONE?"); + Tcl_SetErrorCode(interp, "CLOCK", "wrongNumArgs", NULL); + return TCL_ERROR; + } + + ClockInitDateInfo(&yy); + + /* + * Extract values for the keywords. + */ + + ClockInitFmtScnArgs(clientData, interp, &opts); + ret = ClockParseFmtScnArgs(&opts, &yy.date, objc, objv, + CLC_ADD_ARGS); + if (ret != TCL_OK) { + goto done; + } + + /* time together as seconds of the day */ + yySeconds = yydate.localSeconds % SECONDS_PER_DAY; + /* seconds are in localSeconds (relative base date), so reset time here */ + yyHour = 0; yyMinutes = 0; yyMeridian = MER24; + + ret = TCL_ERROR; + + /* + * Find each offset and process date increment + */ + + for (i = 2; i < objc; i+=2) { + /* bypass not integers (options, allready processed above) */ + if (TclGetWideIntFromObj(NULL, objv[i], &offs) != TCL_OK) { + continue; + } + if (objv[i]->typePtr == &tclBignumType) { + Tcl_SetObjResult(interp, dataPtr->literals[LIT_INTEGER_VALUE_TOO_LARGE]); + goto done; + } + /* get unit */ + if (Tcl_GetIndexFromObj(interp, objv[i+1], units, "unit", 0, + &unitIndex) != TCL_OK) { + goto done; + } + + /* nothing to do if zero quantity */ + if (!offs) { + continue; + } + + /* if in-between conversion needed (already have relative date/time), + * correct date info, because the date may be changed, + * so refresh it now */ + + if ( yyHaveRel + && ( unitIndex == CLC_ADD_WEEKDAYS + /* some months can be shorter as another */ + || yyRelMonth || yyRelDay + /* day changed */ + || yySeconds + yyRelSeconds > SECONDS_PER_DAY + || yySeconds + yyRelSeconds < 0 + ) + ) { + if (ClockCalcRelTime(info, &opts) != TCL_OK) { + goto done; + } + } + + /* process increment by offset + unit */ + yyHaveRel++; + switch (unitIndex) { + case CLC_ADD_YEARS: + yyRelMonth += offs * 12; + break; + case CLC_ADD_MONTHS: + yyRelMonth += offs; + break; + case CLC_ADD_WEEK: + case CLC_ADD_WEEKS: + yyRelDay += offs * 7; + break; + case CLC_ADD_DAYS: + yyRelDay += offs; + break; + case CLC_ADD_WEEKDAYS: + /* add number of week days (skipping Saturdays and Sundays) + * to a relative days value. */ + offs = ClockWeekdaysOffs(yy.date.dayOfWeek, offs); + yyRelDay += offs; + break; + case CLC_ADD_HOURS: + yyRelSeconds += offs * 60 * 60; + break; + case CLC_ADD_MINUTES: + yyRelSeconds += offs * 60; + break; + case CLC_ADD_SECONDS: + yyRelSeconds += offs; + break; + } + } + + /* + * Do relative times (if not yet already processed interim): + */ + + if (yyHaveRel) { + if (ClockCalcRelTime(info, &opts) != TCL_OK) { + goto done; + } + } + + /* Convert date info structure into UTC seconds */ + + ret = ClockScanCommit(clientData, &yy, &opts); done: - return ret; + Tcl_UnsetObjRef(yy.date.tzName); + + if (ret != TCL_OK) { + return ret; + } + + Tcl_SetObjResult(interp, Tcl_NewWideIntObj(yy.date.seconds)); + return TCL_OK; } /*---------------------------------------------------------------------- diff --git a/generic/tclDate.h b/generic/tclDate.h index 1519842..e614f9d 100644 --- a/generic/tclDate.h +++ b/generic/tclDate.h @@ -264,7 +264,7 @@ typedef struct ClockFmtScnCmdArgs { Tcl_Obj *formatObj; /* Format */ Tcl_Obj *localeObj; /* Name of the locale where the time will be expressed. */ Tcl_Obj *timezoneObj; /* Default time zone in which the time will be expressed */ - Tcl_Obj *baseObj; /* Base (scan only) */ + Tcl_Obj *baseObj; /* Base (scan and add) or clockValue (format) */ int flags; /* Flags control scanning */ Tcl_Obj *mcDictObj; /* Current dictionary of tcl::clock package for given localeObj*/ diff --git a/library/clock.tcl b/library/clock.tcl index 3caa270..ba4676b 100755 --- a/library/clock.tcl +++ b/library/clock.tcl @@ -1948,334 +1948,6 @@ proc ::tcl::clock::WeekdayOnOrBefore { weekday j } { #---------------------------------------------------------------------- # -# clock add -- -# -# Adds an offset to a given time. -# -# Syntax: -# clock add clockval ?count unit?... ?-option value? -# -# Parameters: -# clockval -- Starting time value -# count -- Amount of a unit of time to add -# unit -- Unit of time to add, must be one of: -# years year months month weeks week -# days day hours hour minutes minute -# seconds second -# -# Options: -# -gmt BOOLEAN -# (Deprecated) Flag synonymous with '-timezone :GMT' -# -timezone ZONE -# Name of the time zone in which calculations are to be done. -# -locale NAME -# Name of the locale in which calculations are to be done. -# Used to determine the Gregorian change date. -# -# Results: -# Returns the given time adjusted by the given offset(s) in -# order. -# -# Notes: -# It is possible that adding a number of months or years will adjust the -# day of the month as well. For instance, the time at one month after -# 31 January is either 28 or 29 February, because February has fewer -# than 31 days. -# -#---------------------------------------------------------------------- - -proc ::tcl::clock::add { clockval args } { - if { [llength $args] % 2 != 0 } { - set cmdName "clock add" - return -code error \ - -errorcode [list CLOCK wrongNumArgs] \ - "wrong \# args: should be\ - \"$cmdName clockval ?number units?...\ - ?-gmt boolean? ?-locale LOCALE? ?-timezone ZONE?\"" - } - if { [catch { expr {wide($clockval)} } result] } { - return -code error "expected integer but got \"$clockval\"" - } - - set offsets {} - set gmt 0 - set locale c - if {[set timezone [configure -system-tz]] eq ""} { - set timezone [GetSystemTimeZone] - } - - foreach { a b } $args { - if { [string is integer -strict $a] } { - lappend offsets $a $b - } else { - switch -exact -- $a { - -g - -gm - -gmt { - set gmt $b - } - -l - -lo - -loc - -loca - -local - -locale { - set locale [string tolower $b] - } - -t - -ti - -tim - -time - -timez - -timezo - -timezon - - -timezone { - set timezone $b - } - default { - throw [list CLOCK badOption $a] \ - "bad option \"$a\",\ - must be -gmt, -locale or -timezone" - } - } - } - } - - # Check options for validity - - if { [info exists saw(-gmt)] && [info exists saw(-timezone)] } { - return -code error \ - -errorcode [list CLOCK gmtWithTimezone] \ - "cannot use -gmt and -timezone in same call" - } - if { ![string is boolean -strict $gmt] } { - return -code error "expected boolean value but got \"$gmt\"" - } elseif { $gmt } { - set timezone :GMT - } - - EnterLocale $locale - - set changeover [mc GREGORIAN_CHANGE_DATE] - - if {[catch {set timezone [SetupTimeZone $timezone]} retval opts]} { - dict unset opts -errorinfo - return -options $opts $retval - } - - try { - foreach { quantity unit } $offsets { - switch -exact -- $unit { - years - year { - set clockval [AddMonths [expr { 12 * $quantity }] \ - $clockval $timezone $changeover] - } - months - month { - set clockval [AddMonths $quantity $clockval $timezone \ - $changeover] - } - - weeks - week { - set clockval [AddDays [expr { 7 * $quantity }] \ - $clockval $timezone $changeover] - } - days - day { - set clockval [AddDays $quantity $clockval $timezone \ - $changeover] - } - - weekdays - weekday { - set clockval [AddWeekDays $quantity $clockval $timezone \ - $changeover] - } - - hours - hour { - set clockval [expr { 3600 * $quantity + $clockval }] - } - minutes - minute { - set clockval [expr { 60 * $quantity + $clockval }] - } - seconds - second { - set clockval [expr { $quantity + $clockval }] - } - - default { - throw [list CLOCK badUnit $unit] \ - "unknown unit \"$unit\", must be \ - years, months, weeks, days, hours, minutes or seconds" - } - } - } - return $clockval - } trap CLOCK {result opts} { - # Conceal the innards of [clock] when it's an expected error - dict unset opts -errorinfo - return -options $opts $result - } -} - -#---------------------------------------------------------------------- -# -# AddMonths -- -# -# Add a given number of months to a given clock value in a given -# time zone. -# -# Parameters: -# months - Number of months to add (may be negative) -# clockval - Seconds since the epoch before the operation -# timezone - Time zone in which the operation is to be performed -# -# Results: -# Returns the new clock value as a number of seconds since -# the epoch. -# -# Side effects: -# None. -# -#---------------------------------------------------------------------- - -proc ::tcl::clock::AddMonths { months clockval timezone changeover } { - variable DaysInRomanMonthInCommonYear - variable DaysInRomanMonthInLeapYear - variable TZData - - # Convert the time to year, month, day, and fraction of day. - - set date [GetDateFields $clockval $timezone $changeover] - dict set date secondOfDay [expr { - [dict get $date localSeconds] % 86400 - }] - dict set date tzName $timezone - - # Add the requisite number of months - - set m [dict get $date month] - incr m $months - incr m -1 - set delta [expr { $m / 12 }] - set mm [expr { $m % 12 }] - dict set date month [expr { $mm + 1 }] - dict incr date year $delta - - # If the date doesn't exist in the current month, repair it - - if { [IsGregorianLeapYear $date] } { - set hath [lindex $DaysInRomanMonthInLeapYear $mm] - } else { - set hath [lindex $DaysInRomanMonthInCommonYear $mm] - } - if { [dict get $date dayOfMonth] > $hath } { - dict set date dayOfMonth $hath - } - - # Reconvert to a number of seconds - - set date [GetJulianDayFromEraYearMonthDay \ - $date[set date {}]\ - $changeover] - dict set date localSeconds [expr { - -210866803200 - + ( 86400 * wide([dict get $date julianDay]) ) - + [dict get $date secondOfDay] - }] - set date [ConvertLocalToUTC $date[set date {}] $timezone \ - $changeover] - - return [dict get $date seconds] - -} - -#---------------------------------------------------------------------- -# -# AddWeekDays -- -# -# Add a given number of week days (skipping Saturdays and Sundays) -# to a given clock value in a given time zone. -# -# Parameters: -# days - Number of days to add (may be negative) -# clockval - Seconds since the epoch before the operation -# timezone - Time zone in which the operation is to be performed -# changeover - Julian Day on which the Gregorian calendar was adopted -# in the target locale. -# -# Results: -# Returns the new clock value as a number of seconds since the epoch. -# -# Side effects: -# None. -# -#---------------------------------------------------------------------- - -proc ::tcl::clock::AddWeekDays { days clockval timezone changeover } { - - if {$days == 0} { - return $clockval - } - - set day [format $clockval -format %u] - - set weeks [expr {$days / 5}] - set rdays [expr {$days % 5}] - set toAdd [expr {7 * $weeks + $rdays}] - set resDay [expr {$day + ($toAdd % 7)}] - - # Adjust if we start from a weekend - if {$day > 5} { - set adj [expr {5 - $day}] - incr toAdd $adj - incr resDay $adj - } - - # Adjust if we end up on a weekend - if {$resDay > 5} { - incr toAdd 2 - } - - AddDays $toAdd $clockval $timezone $changeover -} - -#---------------------------------------------------------------------- -# -# AddDays -- -# -# Add a given number of days to a given clock value in a given time -# zone. -# -# Parameters: -# days - Number of days to add (may be negative) -# clockval - Seconds since the epoch before the operation -# timezone - Time zone in which the operation is to be performed -# changeover - Julian Day on which the Gregorian calendar was adopted -# in the target locale. -# -# Results: -# Returns the new clock value as a number of seconds since the epoch. -# -# Side effects: -# None. -# -#---------------------------------------------------------------------- - -proc ::tcl::clock::AddDays { days clockval timezone changeover } { - variable TZData - - # Convert the time to Julian Day - - set date [GetDateFields $clockval $timezone $changeover] - dict set date secondOfDay [expr { - [dict get $date localSeconds] % 86400 - }] - dict set date tzName $timezone - - # Add the requisite number of days - - dict incr date julianDay $days - - # Reconvert to a number of seconds - - dict set date localSeconds [expr { - -210866803200 - + ( 86400 * wide([dict get $date julianDay]) ) - + [dict get $date secondOfDay] - }] - set date [ConvertLocalToUTC $date[set date {}] $timezone \ - $changeover] - - return [dict get $date seconds] - -} - -#---------------------------------------------------------------------- -# # ChangeCurrentLocale -- # # The global locale was changed within msgcat. diff --git a/library/init.tcl b/library/init.tcl index f1f1bb4..405a400 100644 --- a/library/init.tcl +++ b/library/init.tcl @@ -178,7 +178,7 @@ if {[interp issafe]} { # Auto-loading stubs for 'clock.tcl' - foreach cmd {add mcget LocalizeFormat SetupTimeZone GetSystemTimeZone} { + foreach cmd {mcget LocalizeFormat SetupTimeZone GetSystemTimeZone} { proc ::tcl::clock::$cmd args { variable TclLibDir source -encoding utf-8 [file join $TclLibDir clock.tcl] diff --git a/tests-perf/clock.perf.tcl b/tests-perf/clock.perf.tcl index 16664b2..733db1a 100644 --- a/tests-perf/clock.perf.tcl +++ b/tests-perf/clock.perf.tcl @@ -318,6 +318,44 @@ proc test-freescan {{reptime 1000}} { } {puts [clock format $_(r) -locale en]} } +proc test-add {{reptime 1000}} { + _test_run $reptime { + # Add : years + {clock add 1246379415 5 years -gmt 1} + # Add : months + {clock add 1246379415 18 months -gmt 1} + # Add : weeks + {clock add 1246379415 20 weeks -gmt 1} + # Add : days + {clock add 1246379415 385 days -gmt 1} + # Add : weekdays + {clock add 1246379415 3 weekdays -gmt 1} + + # Add : hours + {clock add 1246379415 5 hours -gmt 1} + # Add : minutes + {clock add 1246379415 55 minutes -gmt 1} + # Add : seconds + {clock add 1246379415 100 seconds -gmt 1} + + # Add : +/- in gmt + {clock add 1246379415 -5 years +21 months -20 weeks +386 days -19 hours +30 minutes -10 seconds -gmt 1} + # Add : +/- in system timezone + {clock add 1246379415 -5 years +21 months -20 weeks +386 days -19 hours +30 minutes -10 seconds -timezone :CET} + + # Add : gmt + {clock add 1246379415 -5 years 18 months 366 days 5 hours 30 minutes 10 seconds -gmt 1} + # Add : system timezone + {clock add 1246379415 -5 years 18 months 366 days 5 hours 30 minutes 10 seconds -timezone :CET} + + # Add : all in gmt + {clock add 1246379415 4 years 18 months 50 weeks 378 days 3 weekdays 5 hours 30 minutes 10 seconds -gmt 1} + # Add : all in system timezone + {clock add 1246379415 4 years 18 months 50 weeks 378 days 3 weekdays 5 hours 30 minutes 10 seconds -timezone :CET} + + } {puts [clock format $_(r) -locale en]} +} + proc test-other {{reptime 1000}} { _test_run $reptime { # Bad zone @@ -338,6 +376,7 @@ proc test {{reptime 1000}} { test-format $reptime test-scan $reptime test-freescan $reptime + test-add $reptime test-other $reptime puts \n**OK** diff --git a/tests/clock.test b/tests/clock.test index d9c491a..b540024 100644 --- a/tests/clock.test +++ b/tests/clock.test @@ -254,7 +254,7 @@ proc ::testClock::registry { cmd path key } { test clock-1.0 "clock format - wrong # args" { list [catch {clock format} msg] $msg $::errorCode -} {1 {wrong # args: should be "clock format clockval ?-format string? ?-gmt boolean? ?-locale LOCALE? ?-timezone ZONE?"} {CLOCK wrongNumArgs}} +} {1 {wrong # args: should be "clock format clockval|-now ?-format string? ?-gmt boolean? ?-locale LOCALE? ?-timezone ZONE?"} {CLOCK wrongNumArgs}} test clock-1.1 "clock format - bad time" { list [catch {clock format foo} msg] $msg @@ -270,10 +270,11 @@ test clock-1.3 "clock format - empty val" { test clock-1.4 "clock format - bad flag" {*}{ -body { - list [catch {clock format 0 -oops badflag} msg] $msg $::errorCode + # range error message for possible extensions: + list [catch {clock format 0 -oops badflag} msg] [string range $msg 0 60] $::errorCode } -match glob - -result {1 {bad option "-oops": must be -format, -gmt, -locale, or -timezone} {CLOCK badOption -oops}} + -result {1 {bad option "-oops": must be -format, -gmt, -locale, -timezone} {CLOCK badOption -oops}} } test clock-1.5 "clock format - bad timezone" { @@ -288,6 +289,16 @@ test clock-1.7 "clock format - option abbreviations" { clock format 0 -g true -f "%Y-%m-%d" } 1970-01-01 +test clock-1.8 "clock format -now" { + # give one second more for test (if on boundary of the current second): + set n [clock format [clock seconds] -g 1 -f "%s"] + expr {[clock format -now -g 1 -f "%s"] in [list $n [incr n]]} +} 1 + +test clock-1.9 "clock arguments: option doubly present" { + list [catch {clock format 0 -gmt 1 -gmt 0} result] $result +} {1 {bad option "-gmt": doubly present}} + # BEGIN testcases2 # Test formatting of Gregorian year, month, day, all formats -- cgit v0.12 From df7cbb28e0aaf30b8564ec1636870b0327c2ac21 Mon Sep 17 00:00:00 2001 From: sebres Date: Tue, 10 Jan 2017 23:02:14 +0000 Subject: small amend (reset have rel flag) --- generic/tclClock.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/generic/tclClock.c b/generic/tclClock.c index 791898b..efa9120 100644 --- a/generic/tclClock.c +++ b/generic/tclClock.c @@ -3623,6 +3623,8 @@ repeat_rel: goto repeat_rel; } } + + yyHaveRel = 0; } /* -- cgit v0.12 From a841205be9defa27d0eb12214555f45bf141f858 Mon Sep 17 00:00:00 2001 From: sebres Date: Tue, 10 Jan 2017 23:09:23 +0000 Subject: amend lost changes after rebase to fossil --- library/clock.tcl | 1 + tests/clock.test | 1 + 2 files changed, 2 insertions(+) diff --git a/library/clock.tcl b/library/clock.tcl index ba4676b..94d2341 100755 --- a/library/clock.tcl +++ b/library/clock.tcl @@ -10,6 +10,7 @@ #---------------------------------------------------------------------- # # Copyright (c) 2004,2005,2006,2007 by Kevin B. Kenny +# Copyright (c) 2015 by Sergey G. Brester aka sebres. # See the file "license.terms" for information on usage and redistribution # of this file, and for a DISCLAIMER OF ALL WARRANTIES. # diff --git a/tests/clock.test b/tests/clock.test index b540024..9e86c97 100644 --- a/tests/clock.test +++ b/tests/clock.test @@ -7,6 +7,7 @@ # generates output for errors. No output means no errors were found. # # Copyright (c) 2004 by Kevin B. Kenny. All rights reserved. +# Copyright (c) 2015 by Sergey G. Brester aka sebres. # # See the file "license.terms" for information on usage and redistribution # of this file, and for a DISCLAIMER OF ALL WARRANTIES. -- cgit v0.12 From 1ebb964dbc71b70763380a8a55c607671151d51c Mon Sep 17 00:00:00 2001 From: "jan.nijtmans" Date: Wed, 11 Jan 2017 16:23:18 +0000 Subject: Use more Tcl_AppendResult(), in order to prevent the use of a (char *) type case. --- generic/tclTest.c | 56 +++++++++++++++++++++++++++---------------------------- 1 file changed, 28 insertions(+), 28 deletions(-) diff --git a/generic/tclTest.c b/generic/tclTest.c index 85e4a29..faecbc6 100644 --- a/generic/tclTest.c +++ b/generic/tclTest.c @@ -90,7 +90,7 @@ static Tcl_Trace cmdTrace; * TestdelCmd: */ -typedef struct DelCmd { +typedef struct { Tcl_Interp *interp; /* Interpreter in which command exists. */ char *deleteCmd; /* Script to execute when command is deleted. * Malloc'ed. */ @@ -101,7 +101,7 @@ typedef struct DelCmd { * command. */ -typedef struct TclEncoding { +typedef struct { Tcl_Interp *interp; char *toUtfCmd; char *fromUtfCmd; @@ -124,7 +124,7 @@ static int exitMainLoop = 0; * Event structure used in testing the event queue management procedures. */ -typedef struct TestEvent { +typedef struct { Tcl_Event header; /* Header common to all events */ Tcl_Interp *interp; /* Interpreter that will handle the event */ Tcl_Obj *command; /* Command to evaluate when the event occurs */ @@ -823,7 +823,7 @@ TestasyncCmd( if (argc < 2) { wrongNumArgs: - Tcl_SetResult(interp, (char *)"wrong # args", TCL_STATIC); + Tcl_AppendResult(interp, "wrong # args", NULL); return TCL_ERROR; } if (strcmp(argv[1], "create") == 0) { @@ -913,7 +913,7 @@ TestasyncCmd( if (Tcl_CreateThread(&threadID, AsyncThreadProc, INT2PTR(id), TCL_THREAD_STACK_DEFAULT, TCL_THREAD_NOFLAGS) != TCL_OK) { - Tcl_SetResult(interp, (char *)"can't create thread", TCL_STATIC); + Tcl_AppendResult(interp, "can't create thread", NULL); Tcl_MutexUnlock(&asyncTestMutex); return TCL_ERROR; } @@ -1060,7 +1060,7 @@ TestcmdinfoCmd( Tcl_DStringResult(interp, &delString); } else if (strcmp(argv[1], "get") == 0) { if (Tcl_GetCommandInfo(interp, argv[2], &info) ==0) { - Tcl_SetResult(interp, (char *)"??", TCL_STATIC); + Tcl_AppendResult(interp, "??", NULL); return TCL_OK; } if (info.proc == CmdProc1) { @@ -1187,7 +1187,7 @@ TestcmdtokenCmd( token = Tcl_CreateCommand(interp, argv[2], CmdProc1, (ClientData) "original", NULL); sprintf(buf, "%p", (void *)token); - Tcl_SetResult(interp, buf, TCL_VOLATILE); + Tcl_AppendResult(interp, buf, NULL); } else if (strcmp(argv[1], "name") == 0) { Tcl_Obj *objPtr; @@ -1293,7 +1293,7 @@ TestcmdtraceCmd( result = Tcl_EvalEx(interp, argv[2], -1, 0); Tcl_DeleteTrace(interp, cmdTrace); if (!deleteCalled) { - Tcl_SetResult(interp, (char *)"Delete wasn't called", TCL_STATIC); + Tcl_AppendResult(interp, "Delete wasn't called", NULL); return TCL_ERROR; } else { return result; @@ -1593,7 +1593,7 @@ TestdelCmd( Tcl_Interp *slave; if (argc != 4) { - Tcl_SetResult(interp, (char *)"wrong # args", TCL_STATIC); + Tcl_AppendResult(interp, "wrong # args", NULL); return TCL_ERROR; } @@ -1798,7 +1798,7 @@ TestdstringCmd( if (argc < 2) { wrongNumArgs: - Tcl_SetResult(interp, (char *)"wrong # args", TCL_STATIC); + Tcl_AppendResult(interp, "wrong # args", NULL); return TCL_ERROR; } if (strcmp(argv[1], "append") == 0) { @@ -1834,9 +1834,9 @@ TestdstringCmd( goto wrongNumArgs; } if (strcmp(argv[2], "staticsmall") == 0) { - Tcl_SetResult(interp, (char *)"short", TCL_STATIC); + Tcl_AppendResult(interp, "short", NULL); } else if (strcmp(argv[2], "staticlarge") == 0) { - Tcl_SetResult(interp, (char *)"first0 first1 first2 first3 first4 first5 first6 first7 first8 first9\nsecond0 second1 second2 second3 second4 second5 second6 second7 second8 second9\nthird0 third1 third2 third3 third4 third5 third6 third7 third8 third9\nfourth0 fourth1 fourth2 fourth3 fourth4 fourth5 fourth6 fourth7 fourth8 fourth9\nfifth0 fifth1 fifth2 fifth3 fifth4 fifth5 fifth6 fifth7 fifth8 fifth9\nsixth0 sixth1 sixth2 sixth3 sixth4 sixth5 sixth6 sixth7 sixth8 sixth9\nseventh0 seventh1 seventh2 seventh3 seventh4 seventh5 seventh6 seventh7 seventh8 seventh9\n", TCL_STATIC); + Tcl_AppendResult(interp, "first0 first1 first2 first3 first4 first5 first6 first7 first8 first9\nsecond0 second1 second2 second3 second4 second5 second6 second7 second8 second9\nthird0 third1 third2 third3 third4 third5 third6 third7 third8 third9\nfourth0 fourth1 fourth2 fourth3 fourth4 fourth5 fourth6 fourth7 fourth8 fourth9\nfifth0 fifth1 fifth2 fifth3 fifth4 fifth5 fifth6 fifth7 fifth8 fifth9\nsixth0 sixth1 sixth2 sixth3 sixth4 sixth5 sixth6 sixth7 sixth8 sixth9\nseventh0 seventh1 seventh2 seventh3 seventh4 seventh5 seventh6 seventh7 seventh8 seventh9\n", NULL); } else if (strcmp(argv[2], "free") == 0) { char *s = ckalloc(100); strcpy(s, "This is a malloc-ed string"); @@ -1996,7 +1996,7 @@ EncodingToUtfProc( TclEncoding *encodingPtr; encodingPtr = (TclEncoding *) clientData; - Tcl_EvalEx(encodingPtr->interp,encodingPtr->toUtfCmd,-1,TCL_EVAL_GLOBAL); + Tcl_EvalEx(encodingPtr->interp, encodingPtr->toUtfCmd, -1, TCL_EVAL_GLOBAL); len = strlen(Tcl_GetStringResult(encodingPtr->interp)); if (len > dstLen) { @@ -2028,7 +2028,7 @@ EncodingFromUtfProc( TclEncoding *encodingPtr; encodingPtr = (TclEncoding *) clientData; - Tcl_EvalEx(encodingPtr->interp, encodingPtr->fromUtfCmd,-1,TCL_EVAL_GLOBAL); + Tcl_EvalEx(encodingPtr->interp, encodingPtr->fromUtfCmd, -1, TCL_EVAL_GLOBAL); len = strlen(Tcl_GetStringResult(encodingPtr->interp)); if (len > dstLen) { @@ -2436,7 +2436,7 @@ TestexprlongCmd( " expression\"", NULL); return TCL_ERROR; } - Tcl_SetResult(interp, (char *)"This is a result", TCL_STATIC); + Tcl_AppendResult(interp, "This is a result", NULL); result = Tcl_ExprLong(interp, argv[1], &exprResult); if (result != TCL_OK) { return result; @@ -2478,7 +2478,7 @@ TestexprlongobjCmd( Tcl_WrongNumArgs(interp, 1, objv, "expression"); return TCL_ERROR; } - Tcl_SetResult(interp, (char *)"This is a result", TCL_STATIC); + Tcl_AppendResult(interp, "This is a result", NULL); result = Tcl_ExprLongObj(interp, objv[1], &exprResult); if (result != TCL_OK) { return result; @@ -2521,7 +2521,7 @@ TestexprdoubleCmd( " expression\"", NULL); return TCL_ERROR; } - Tcl_SetResult(interp, (char *)"This is a result", TCL_STATIC); + Tcl_AppendResult(interp, "This is a result", NULL); result = Tcl_ExprDouble(interp, argv[1], &exprResult); if (result != TCL_OK) { return result; @@ -2564,7 +2564,7 @@ TestexprdoubleobjCmd( Tcl_WrongNumArgs(interp, 1, objv, "expression"); return TCL_ERROR; } - Tcl_SetResult(interp, (char *)"This is a result", TCL_STATIC); + Tcl_AppendResult(interp, "This is a result", NULL); result = Tcl_ExprDoubleObj(interp, objv[1], &exprResult); if (result != TCL_OK) { return result; @@ -4486,7 +4486,7 @@ TestseterrorcodeCmd( const char **argv) /* Argument strings. */ { if (argc > 6) { - Tcl_SetResult(interp, (char *)"too many args", TCL_STATIC); + Tcl_AppendResult(interp, "too many args", NULL); return TCL_ERROR; } switch (argc) { @@ -5090,7 +5090,7 @@ TestsetCmd( const char *value; if (argc == 2) { - Tcl_SetResult(interp, (char *)"before get", TCL_STATIC); + Tcl_AppendResult(interp, "before get", NULL); value = Tcl_GetVar2(interp, argv[1], NULL, flags); if (value == NULL) { return TCL_ERROR; @@ -5098,7 +5098,7 @@ TestsetCmd( Tcl_AppendElement(interp, value); return TCL_OK; } else if (argc == 3) { - Tcl_SetResult(interp, (char *)"before set", TCL_STATIC); + Tcl_AppendResult(interp, "before set", NULL); value = Tcl_SetVar2(interp, argv[1], NULL, argv[2], flags); if (value == NULL) { return TCL_ERROR; @@ -5122,7 +5122,7 @@ Testset2Cmd( const char *value; if (argc == 3) { - Tcl_SetResult(interp, (char *)"before get", TCL_STATIC); + Tcl_AppendResult(interp, "before get", NULL); value = Tcl_GetVar2(interp, argv[1], argv[2], flags); if (value == NULL) { return TCL_ERROR; @@ -5130,7 +5130,7 @@ Testset2Cmd( Tcl_AppendElement(interp, value); return TCL_OK; } else if (argc == 4) { - Tcl_SetResult(interp, (char *)"before set", TCL_STATIC); + Tcl_AppendResult(interp, "before set", NULL); value = Tcl_SetVar2(interp, argv[1], argv[2], argv[3], flags); if (value == NULL) { return TCL_ERROR; @@ -5200,7 +5200,7 @@ TestsaveresultCmd( objPtr = NULL; /* Lint. */ switch ((enum options) index) { case RESULT_SMALL: - Tcl_SetResult(interp, (char *)"small result", TCL_VOLATILE); + Tcl_AppendResult(interp, "small result", NULL); break; case RESULT_APPEND: Tcl_AppendResult(interp, "append result", NULL); @@ -5310,7 +5310,7 @@ TestmainthreadCmd( Tcl_SetObjResult(interp, idObj); return TCL_OK; } else { - Tcl_SetResult(interp, (char *)"wrong # args", TCL_STATIC); + Tcl_AppendResult(interp, "wrong # args", NULL); return TCL_ERROR; } } @@ -6111,7 +6111,7 @@ TestWrongNumArgsObjCmd( * Don't use Tcl_WrongNumArgs here, as that is the function * we want to test! */ - Tcl_SetResult(interp, (char *)"insufficient arguments", TCL_STATIC); + Tcl_AppendResult(interp, "insufficient arguments", NULL); return TCL_ERROR; } @@ -6128,7 +6128,7 @@ TestWrongNumArgsObjCmd( /* * Asked for more arguments than were given. */ - Tcl_SetResult(interp, (char *)"insufficient arguments", TCL_STATIC); + Tcl_AppendResult(interp, "insufficient arguments", NULL); return TCL_ERROR; } @@ -6905,7 +6905,7 @@ TestgetintCmd( const char **argv) { if (argc < 2) { - Tcl_SetResult(interp, (char *)"wrong # args", TCL_STATIC); + Tcl_AppendResult(interp, "wrong # args", NULL); return TCL_ERROR; } else { int val, i, total=0; -- cgit v0.12 From f03990cd122b2a54155a90896713d3783b343ddd Mon Sep 17 00:00:00 2001 From: sebres Date: Wed, 11 Jan 2017 16:35:41 +0000 Subject: code review: small optimization of msgcat::mcget, prevents infinite loop if at all no translation --- library/msgcat/msgcat.tcl | 24 +++++++++++++----------- 1 file changed, 13 insertions(+), 11 deletions(-) diff --git a/library/msgcat/msgcat.tcl b/library/msgcat/msgcat.tcl index 1260139..f9f57db 100644 --- a/library/msgcat/msgcat.tcl +++ b/library/msgcat/msgcat.tcl @@ -245,8 +245,6 @@ proc msgcat::mc {src args} { # format command. proc msgcat::mcget {ns loc args} { - variable Msgs - if {$loc eq {C}} { set loclist [PackagePreferences $ns] set loc [lindex $loclist 0] @@ -270,18 +268,20 @@ proc msgcat::mcget {ns loc args} { # search translation for each locale (regarding parent namespaces) for {set nscur $ns} {$nscur != ""} {set nscur [namespace parent $nscur]} { foreach loc $loclist { - if {[dict exists $Msgs $nscur $loc $src]} { - if {[llength $args] > 1} { - return [format [dict get $Msgs $nscur $loc $src] \ - {*}[lrange $args 1 end]] - } else { - return [dict get $Msgs $nscur $loc $src] + set msgs [mcget $nscur $loc] + if {![catch { set val [dict get $msgs $src] }]} { + if {[llength $args] == 1} { + return $val } + return [format $val {*}[lrange $args 1 end]] } } } - # get with package default locale - mcget $ns [lindex $loclist 0] {*}$args + # no translation : + if {[llength $args] == 1} { + return $src + } + return [format $src {*}[lrange $args 1 end]] } # msgcat::mcexists -- @@ -942,8 +942,10 @@ proc msgcat::Merge {ns locales} { set mrgcat [dict merge $mrgcat [dict get $Msgs $ns $loc]] } } else { - catch { + if {[catch { set mrgcat [dict get $Msgs $ns $loc] + }]} { + set mrgcat [dict create] } } dict set Merged $ns $loc $mrgcat -- cgit v0.12 From 77481ec3e1c4841e2c18ba404b55e98b2a9995f0 Mon Sep 17 00:00:00 2001 From: sebres Date: Wed, 11 Jan 2017 16:36:28 +0000 Subject: code review and inline documentation --- generic/tclClock.c | 27 +++++ generic/tclClockFmt.c | 323 +++++++++++++++++++++++++++++++++++++++++++++----- 2 files changed, 323 insertions(+), 27 deletions(-) diff --git a/generic/tclClock.c b/generic/tclClock.c index efa9120..c63f425 100644 --- a/generic/tclClock.c +++ b/generic/tclClock.c @@ -412,7 +412,19 @@ NormTimezoneObj( /* *---------------------------------------------------------------------- + * + * ClockGetSystemLocale -- + * + * Returns system locale. + * + * Executes ::tcl::clock::GetSystemLocale in given interpreter. + * + * Results: + * Returns system locale tcl object. + * + *---------------------------------------------------------------------- */ + static inline Tcl_Obj * ClockGetSystemLocale( ClockClientData *dataPtr, /* Opaque pointer to literal pool, etc. */ @@ -426,7 +438,19 @@ ClockGetSystemLocale( } /* *---------------------------------------------------------------------- + * + * ClockGetCurrentLocale -- + * + * Returns current locale. + * + * Executes ::tcl::clock::mclocale in given interpreter. + * + * Results: + * Returns current locale tcl object. + * + *---------------------------------------------------------------------- */ + static inline Tcl_Obj * ClockGetCurrentLocale( ClockClientData *dataPtr, /* Client data containing literal pool */ @@ -978,6 +1002,9 @@ ClockGetTZData( * * Returns system (current) timezone. * + * If system zone not yet cached, it executes ::tcl::clock::GetSystemTimeZone + * in given interpreter and caches its result. + * * Results: * Returns normalized timezone object. * diff --git a/generic/tclClockFmt.c b/generic/tclClockFmt.c index ff16714..d875bd4 100644 --- a/generic/tclClockFmt.c +++ b/generic/tclClockFmt.c @@ -41,6 +41,24 @@ CLOCK_LOCALE_LITERAL_ARRAY(MsgCtLitIdxs, "_IDX_"); * Clock scan and format facilities. */ +/* + *---------------------------------------------------------------------- + * + * _str2int -- , _str2wideInt -- + * + * Fast inline-convertion of string to signed int or wide int by given + * start/end. + * + * The given string should contain numbers chars only (because already + * pre-validated within parsing routines) + * + * Results: + * Returns a standard Tcl result. + * TCL_OK - by successful conversion, TCL_ERROR by (wide) int overflow + * + *---------------------------------------------------------------------- + */ + static inline int _str2int( int *out, @@ -101,6 +119,22 @@ _str2wideInt( return TCL_OK; } +/* + *---------------------------------------------------------------------- + * + * _itoaw -- , _witoaw -- + * + * Fast inline-convertion of signed int or wide int to string, using + * given padding with specified padchar and width (or without padding). + * + * This is a very fast replacement for sprintf("%02d"). + * + * Results: + * Returns position in buffer after end of conversion result. + * + *---------------------------------------------------------------------- + */ + static inline char * _itoaw( char *buf, @@ -257,7 +291,15 @@ _witoaw( } /* - *---------------------------------------------------------------------- + * Global GC as LIFO for released scan/format object storages. + * + * Used to holds last released CLOCK_FMT_SCN_STORAGE_GC_SIZE formats + * (after last reference from Tcl-object will be removed). This is helpful + * to avoid continuous (re)creation and compiling by some dynamically resp. + * variable format objects, that could be often reused. + * + * As long as format storage is used resp. belongs to GC, it takes place in + * FmtScnHashTable also. */ #if CLOCK_FMT_SCN_STORAGE_GC_SIZE > 0 @@ -268,6 +310,24 @@ static struct { unsigned int count; } ClockFmtScnStorage_GC = {NULL, NULL, 0}; +/* + *---------------------------------------------------------------------- + * + * ClockFmtScnStorageGC_In -- + * + * Adds an format storage object to GC. + * + * If current GC is full (size larger as CLOCK_FMT_SCN_STORAGE_GC_SIZE) + * this removes last unused storage at begin of GC stack (LIFO). + * + * Assumes caller holds the ClockFmtMutex. + * + * Results: + * None. + * + *---------------------------------------------------------------------- + */ + static inline void ClockFmtScnStorageGC_In(ClockFmtScnStorage *entry) { @@ -291,6 +351,22 @@ ClockFmtScnStorageGC_In(ClockFmtScnStorage *entry) ClockFmtScnStorageDelete(delEnt); } } + +/* + *---------------------------------------------------------------------- + * + * ClockFmtScnStorage_GC_Out -- + * + * Restores (for reusing) given format storage object from GC. + * + * Assumes caller holds the ClockFmtMutex. + * + * Results: + * None. + * + *---------------------------------------------------------------------- + */ + static inline void ClockFmtScnStorage_GC_Out(ClockFmtScnStorage *entry) { @@ -304,13 +380,19 @@ ClockFmtScnStorage_GC_Out(ClockFmtScnStorage *entry) #endif + /* - *---------------------------------------------------------------------- + * Global format storage hash table of type ClockFmtScnStorageHashKeyType + * (contains list of scan/format object storages, shared across all threads). + * + * Used for fast searching by format string. */ - static Tcl_HashTable FmtScnHashTable; static int initialized = 0; +/* + * Wrappers between pointers to hash entry and format storage object + */ static inline Tcl_HashEntry * HashEntry4FmtScn(ClockFmtScnStorage *fss) { return (Tcl_HashEntry*)(fss + 1); @@ -320,8 +402,18 @@ FmtScn4HashEntry(Tcl_HashEntry *hKeyPtr) { return (ClockFmtScnStorage*)(((char*)hKeyPtr) - sizeof(ClockFmtScnStorage)); }; -/* - * Format storage hash (list of formats shared across all threads). +/* + *---------------------------------------------------------------------- + * + * ClockFmtScnStorageAllocProc -- + * + * Allocate space for a hash entry containing format storage together + * with the string key. + * + * Results: + * The return value is a pointer to the created entry. + * + *---------------------------------------------------------------------- */ static Tcl_HashEntry * @@ -353,6 +445,19 @@ ClockFmtScnStorageAllocProc( return hPtr; } +/* + *---------------------------------------------------------------------- + * + * ClockFmtScnStorageFreeProc -- + * + * Free format storage object and space of given hash entry. + * + * Results: + * None. + * + *---------------------------------------------------------------------- + */ + static void ClockFmtScnStorageFreeProc( Tcl_HashEntry *hPtr) @@ -373,6 +478,19 @@ ClockFmtScnStorageFreeProc( ckfree(fss); } +/* + *---------------------------------------------------------------------- + * + * ClockFmtScnStorageDelete -- + * + * Delete format storage object. + * + * Results: + * None. + * + *---------------------------------------------------------------------- + */ + static void ClockFmtScnStorageDelete(ClockFmtScnStorage *fss) { Tcl_HashEntry *hPtr = HashEntry4FmtScn(fss); @@ -392,7 +510,7 @@ static Tcl_HashKeyType ClockFmtScnStorageHashKeyType; /* - * Type definition. + * Type definition of clock-format tcl object type. */ Tcl_ObjType ClockFmtObjType = { @@ -409,9 +527,6 @@ Tcl_ObjType ClockFmtObjType = { #define ObjLocFmtKey(objPtr) \ (*((Tcl_Obj **)&(objPtr)->internalRep.twoPtrValue.ptr2)) -/* - *---------------------------------------------------------------------- - */ static void ClockFmtObj_DupInternalRep(srcPtr, copyPtr) Tcl_Obj *srcPtr; @@ -442,9 +557,7 @@ ClockFmtObj_DupInternalRep(srcPtr, copyPtr) copyPtr->length = srcPtr->length; } } -/* - *---------------------------------------------------------------------- - */ + static void ClockFmtObj_FreeInternalRep(objPtr) Tcl_Obj *objPtr; @@ -472,9 +585,7 @@ ClockFmtObj_FreeInternalRep(objPtr) } objPtr->typePtr = NULL; }; -/* - *---------------------------------------------------------------------- - */ + static int ClockFmtObj_SetFromAny(interp, objPtr) Tcl_Interp *interp; @@ -494,9 +605,7 @@ ClockFmtObj_SetFromAny(interp, objPtr) return TCL_OK; }; -/* - *---------------------------------------------------------------------- - */ + static void ClockFmtObj_UpdateString(objPtr) Tcl_Obj *objPtr; @@ -518,7 +627,25 @@ ClockFmtObj_UpdateString(objPtr) /* *---------------------------------------------------------------------- + * + * ClockFrmObjGetLocFmtKey -- + * + * Retrieves format key object used to search localized format. + * + * This is normally stored in second pointer of internal representation. + * If format object is not localizable, it is equal the given format + * pointer and the first pointer of internal representation may be NULL. + * + * Results: + * Returns tcl object with key or format object if not localizable. + * + * Side effects: + * Converts given format object to ClockFmtObjType on demand for caching + * the key inside its internal representation. + * + *---------------------------------------------------------------------- */ + MODULE_SCOPE Tcl_Obj* ClockFrmObjGetLocFmtKey( Tcl_Interp *interp, @@ -545,6 +672,25 @@ ClockFrmObjGetLocFmtKey( /* *---------------------------------------------------------------------- + * + * FindOrCreateFmtScnStorage -- + * + * Retrieves format storage for given string format. + * + * This will find the given format in the global storage hash table + * or create a format storage object on demaind and save the + * reference in the first pointer of internal representation of given + * object. + * + * Results: + * Returns scan/format storage pointer to ClockFmtScnStorage. + * + * Side effects: + * Converts given format object to ClockFmtObjType on demand for caching + * the format storage reference inside its internal representation. + * Increments objRefCount of the ClockFmtScnStorage reference. + * + *---------------------------------------------------------------------- */ static ClockFmtScnStorage * @@ -609,16 +755,16 @@ FindOrCreateFmtScnStorage( * * Tcl_GetClockFrmScnFromObj -- * - * Returns a clock format/scan representation of (*objPtr), if possible. - * If something goes wrong, NULL is returned, and if interp is non-NULL, - * an error message is written there. + * Returns a clock format/scan representation of (*objPtr), if possible. + * If something goes wrong, NULL is returned, and if interp is non-NULL, + * an error message is written there. * * Results: - * Valid representation of type ClockFmtScnStorage. + * Valid representation of type ClockFmtScnStorage. * * Side effects: - * Caches the ClockFmtScnStorage reference as the internal rep of (*objPtr) - * and in global hash table, shared across all threads. + * Caches the ClockFmtScnStorage reference as the internal rep of (*objPtr) + * and in global hash table, shared across all threads. * *---------------------------------------------------------------------- */ @@ -644,7 +790,27 @@ Tcl_GetClockFrmScnFromObj( return fss; } - +/* + *---------------------------------------------------------------------- + * + * ClockLocalizeFormat -- + * + * Wrap the format object in options to the localized format, + * corresponding given locale. + * + * This searches localized format in locale catalog, and if not yet + * exists, it executes ::tcl::clock::LocalizeFormat in given interpreter + * and caches its result in the locale catalog. + * + * Results: + * Localized format object. + * + * Side effects: + * Caches the localized format inside locale catalog. + * + *---------------------------------------------------------------------- + */ + MODULE_SCOPE Tcl_Obj * ClockLocalizeFormat( ClockFmtScnCmdArgs *opts) @@ -713,6 +879,22 @@ clean: return (opts->formatObj = valObj); } +/* + *---------------------------------------------------------------------- + * + * FindTokenBegin -- + * + * Find begin of given scan token in string, corresponding token type. + * + * Results: + * Position of token inside string if found. Otherwise - end of string. + * + * Side effects: + * None. + * + *---------------------------------------------------------------------- + */ + static const char * FindTokenBegin( register const char *p, @@ -748,12 +930,22 @@ FindTokenBegin( return p; } -/* +/* + *---------------------------------------------------------------------- + * * DetermineGreedySearchLen -- * - * Determine min/max lengths as exact as possible (speed, greedy match) + * Determine min/max lengths as exact as possible (speed, greedy match). * + * Results: + * None. Lengths are stored in *minLenPtr, *maxLenPtr. + * + * Side effects: + * None. + * + *---------------------------------------------------------------------- */ + static void DetermineGreedySearchLen(ClockFmtScnCmdArgs *opts, DateInfo *info, ClockScanToken *tok, @@ -836,6 +1028,23 @@ DetermineGreedySearchLen(ClockFmtScnCmdArgs *opts, *maxLenPtr = maxLen; } +/* + *---------------------------------------------------------------------- + * + * ObjListSearch -- + * + * Find largest part of the input string from start regarding min and + * max lengths in the given list (utf-8, case sensitive). + * + * Results: + * TCL_OK - match found, TCL_RETURN - not matched, TCL_ERROR in error case. + * + * Side effects: + * Input points to end of the found token in string. + * + *---------------------------------------------------------------------- + */ + static inline int ObjListSearch(ClockFmtScnCmdArgs *opts, DateInfo *info, int *val, @@ -909,6 +1118,26 @@ LocaleListSearch(ClockFmtScnCmdArgs *opts, } #endif +/* + *---------------------------------------------------------------------- + * + * ClockMCGetListIdxTree -- + * + * Retrieves localized string indexed tree in the locale catalog for + * given literal index mcKey (and builds it on demand). + * + * Searches localized index in locale catalog, and if not yet exists, + * creates string indexed tree and stores it in the locale catalog. + * + * Results: + * Localized string index tree. + * + * Side effects: + * Caches the localized string index tree inside locale catalog. + * + *---------------------------------------------------------------------- + */ + static TclStrIdxTree * ClockMCGetListIdxTree( ClockFmtScnCmdArgs *opts, @@ -960,6 +1189,27 @@ done: return idxTree; } +/* + *---------------------------------------------------------------------- + * + * ClockMCGetMultiListIdxTree -- + * + * Retrieves localized string indexed tree in the locale catalog for + * multiple lists by literal indices mcKeys (and builds it on demand). + * + * Searches localized index in locale catalog for mcKey, and if not + * yet exists, creates string indexed tree and stores it in the + * locale catalog. + * + * Results: + * Localized string index tree. + * + * Side effects: + * Caches the localized string index tree inside locale catalog. + * + *---------------------------------------------------------------------- + */ + static TclStrIdxTree * ClockMCGetMultiListIdxTree( ClockFmtScnCmdArgs *opts, @@ -1016,6 +1266,25 @@ done: return idxTree; } +/* + *---------------------------------------------------------------------- + * + * ClockStrIdxTreeSearch -- + * + * Find largest part of the input string from start regarding lengths + * in the given localized string indexed tree (utf-8, case sensitive). + * + * Results: + * TCL_OK - match found and the index stored in *val, + * TCL_RETURN - not matched or ambigous, + * TCL_ERROR - in error case. + * + * Side effects: + * Input points to end of the found token in string. + * + *---------------------------------------------------------------------- + */ + static inline int ClockStrIdxTreeSearch(ClockFmtScnCmdArgs *opts, DateInfo *info, TclStrIdxTree *idxTree, int *val, -- cgit v0.12 From 7461bedeb9e9373c756f021c994a5c187073418c Mon Sep 17 00:00:00 2001 From: "jan.nijtmans" Date: Thu, 12 Jan 2017 10:31:46 +0000 Subject: Fix version number in tcl.dsp (thanks to Arjen Markus for noticing this) --- win/tcl.dsp | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/win/tcl.dsp b/win/tcl.dsp index 96d5893..6f17cdb 100644 --- a/win/tcl.dsp +++ b/win/tcl.dsp @@ -36,7 +36,7 @@ CFG=tcl - Win32 Debug Static # PROP BASE Intermediate_Dir "Release\tcl_Dynamic" # PROP BASE Cmd_Line "nmake -nologo -f makefile.vc OPTS=none MSVCDIR=IDE" # PROP BASE Rebuild_Opt "-a" -# PROP BASE Target_File "Release\tclsh85.exe" +# PROP BASE Target_File "Release\tclsh86.exe" # PROP BASE Bsc_Name "" # PROP BASE Target_Dir "" # PROP Use_MFC 0 @@ -45,7 +45,7 @@ CFG=tcl - Win32 Debug Static # PROP Intermediate_Dir "Release\tcl_Dynamic" # PROP Cmd_Line "nmake -nologo -f makefile.vc OPTS=threads MSVCDIR=IDE" # PROP Rebuild_Opt "clean release" -# PROP Target_File "Release\tclsh85t.exe" +# PROP Target_File "Release\tclsh86t.exe" # PROP Bsc_Name "" # PROP Target_Dir "" @@ -57,7 +57,7 @@ CFG=tcl - Win32 Debug Static # PROP BASE Intermediate_Dir "Debug\tcl_Dynamic" # PROP BASE Cmd_Line "nmake -nologo -f makefile.vc OPTS=symbols MSVCDIR=IDE" # PROP BASE Rebuild_Opt "-a" -# PROP BASE Target_File "Debug\tclsh85g.exe" +# PROP BASE Target_File "Debug\tclsh86g.exe" # PROP BASE Bsc_Name "" # PROP BASE Target_Dir "" # PROP Use_MFC 0 @@ -66,7 +66,7 @@ CFG=tcl - Win32 Debug Static # PROP Intermediate_Dir "Debug\tcl_Dynamic" # PROP Cmd_Line "nmake -nologo -f makefile.vc OPTS=threads,symbols MSVCDIR=IDE" # PROP Rebuild_Opt "clean release" -# PROP Target_File "Debug\tclsh85tg.exe" +# PROP Target_File "Debug\tclsh86tg.exe" # PROP Bsc_Name "" # PROP Target_Dir "" @@ -78,7 +78,7 @@ CFG=tcl - Win32 Debug Static # PROP BASE Intermediate_Dir "Debug\tcl_Static" # PROP BASE Cmd_Line "nmake -nologo -f makefile.vc OPTS=symbols,static MSVCDIR=IDE" # PROP BASE Rebuild_Opt "-a" -# PROP BASE Target_File "Debug\tclsh85sg.exe" +# PROP BASE Target_File "Debug\tclsh86sg.exe" # PROP BASE Bsc_Name "" # PROP BASE Target_Dir "" # PROP Use_MFC 0 @@ -87,7 +87,7 @@ CFG=tcl - Win32 Debug Static # PROP Intermediate_Dir "Debug\tcl_Static" # PROP Cmd_Line "nmake -nologo -f makefile.vc OPTS=symbols,static MSVCDIR=IDE" # PROP Rebuild_Opt "-a" -# PROP Target_File "Debug\tclsh85sg.exe" +# PROP Target_File "Debug\tclsh86sg.exe" # PROP Bsc_Name "" # PROP Target_Dir "" @@ -99,7 +99,7 @@ CFG=tcl - Win32 Debug Static # PROP BASE Intermediate_Dir "Release\tcl_Static" # PROP BASE Cmd_Line "nmake -nologo -f makefile.vc OPTS=static MSVCDIR=IDE" # PROP BASE Rebuild_Opt "-a" -# PROP BASE Target_File "Release\tclsh85s.exe" +# PROP BASE Target_File "Release\tclsh86s.exe" # PROP BASE Bsc_Name "" # PROP BASE Target_Dir "" # PROP Use_MFC 0 @@ -108,7 +108,7 @@ CFG=tcl - Win32 Debug Static # PROP Intermediate_Dir "Release\tcl_Static" # PROP Cmd_Line "nmake -nologo -f makefile.vc OPTS=static MSVCDIR=IDE" # PROP Rebuild_Opt "-a" -# PROP Target_File "Release\tclsh85s.exe" +# PROP Target_File "Release\tclsh86s.exe" # PROP Bsc_Name "" # PROP Target_Dir "" -- cgit v0.12 From 6ecb7aeabf05319bda235ebe45a174137a391447 Mon Sep 17 00:00:00 2001 From: "jan.nijtmans" Date: Fri, 13 Jan 2017 11:17:17 +0000 Subject: Patch from Zoran Vasiljevic, fix for missing proper initialization of the threaded allocator in some situations. --- generic/tclEvent.c | 3 --- generic/tclThreadAlloc.c | 1 + unix/tclUnixThrd.c | 2 -- 3 files changed, 1 insertion(+), 5 deletions(-) diff --git a/generic/tclEvent.c b/generic/tclEvent.c index 0eabc13..b0b8188 100644 --- a/generic/tclEvent.c +++ b/generic/tclEvent.c @@ -1043,9 +1043,6 @@ TclInitSubsystems(void) #if USE_TCLALLOC TclInitAlloc(); /* Process wide mutex init */ #endif -#if defined(TCL_THREADS) && defined(USE_THREAD_ALLOC) - TclpInitAllocCache(); -#endif #ifdef TCL_MEM_DEBUG TclInitDbCkalloc(); /* Process wide mutex init */ #endif diff --git a/generic/tclThreadAlloc.c b/generic/tclThreadAlloc.c index 2ee758e..fc281db 100644 --- a/generic/tclThreadAlloc.c +++ b/generic/tclThreadAlloc.c @@ -210,6 +210,7 @@ GetCache(void) 1 << (NBUCKETS - 2 - i) : 1; bucketInfo[i].lockPtr = TclpNewAllocMutex(); } + TclpInitAllocCache(); } Tcl_MutexUnlock(initLockPtr); } diff --git a/unix/tclUnixThrd.c b/unix/tclUnixThrd.c index 7394545..805599d 100644 --- a/unix/tclUnixThrd.c +++ b/unix/tclUnixThrd.c @@ -711,9 +711,7 @@ TclpFreeAllocMutex( void TclpInitAllocCache(void) { - pthread_mutex_lock(allocLockPtr); pthread_key_create(&key, NULL); - pthread_mutex_unlock(allocLockPtr); } void -- cgit v0.12 From 1ef8141062507aad004bb681df9cb944d7855fd2 Mon Sep 17 00:00:00 2001 From: "jan.nijtmans" Date: Mon, 16 Jan 2017 10:23:14 +0000 Subject: Update zlib to version 1.2.11 --- compat/zlib/CMakeLists.txt | 2 +- compat/zlib/ChangeLog | 4 ++++ compat/zlib/Makefile.in | 4 ++-- compat/zlib/README | 4 ++-- compat/zlib/contrib/delphi/ZLib.pas | 2 +- compat/zlib/contrib/dotzlib/DotZLib/UnitTests.cs | 2 +- compat/zlib/contrib/infback9/inftree9.c | 4 ++-- compat/zlib/contrib/minizip/configure.ac | 2 +- compat/zlib/contrib/pascal/zlibpas.pas | 2 +- compat/zlib/contrib/vstudio/readme.txt | 2 +- compat/zlib/contrib/vstudio/vc10/zlib.rc | 6 +++--- compat/zlib/contrib/vstudio/vc11/zlib.rc | 6 +++--- compat/zlib/contrib/vstudio/vc12/zlib.rc | 6 +++--- .../zlib/contrib/vstudio/vc14/miniunz.vcxproj.user | 4 ---- .../zlib/contrib/vstudio/vc14/minizip.vcxproj.user | 4 ---- .../contrib/vstudio/vc14/testzlib.vcxproj.user | 4 ---- .../contrib/vstudio/vc14/testzlibdll.vcxproj.user | 4 ---- compat/zlib/contrib/vstudio/vc14/zlib.rc | 6 +++--- .../contrib/vstudio/vc14/zlibstat.vcxproj.user | 4 ---- .../zlib/contrib/vstudio/vc14/zlibvc.vcxproj.user | 4 ---- compat/zlib/contrib/vstudio/vc9/zlib.rc | 6 +++--- compat/zlib/deflate.c | 19 ++++++++++++------- compat/zlib/gzlib.c | 2 +- compat/zlib/gzwrite.c | 2 +- compat/zlib/inffast.c | 2 +- compat/zlib/inftrees.c | 4 ++-- compat/zlib/os400/README400 | 2 +- compat/zlib/os400/make.sh | 2 +- compat/zlib/os400/zlib.inc | 6 +++--- compat/zlib/qnx/package.qpg | 10 +++++----- compat/zlib/treebuild.xml | 4 ++-- compat/zlib/trees.c | 4 ++-- compat/zlib/win32/Makefile.msc | 2 +- compat/zlib/win32/README-WIN32.txt | 6 +++--- compat/zlib/win32/README.txt | 4 ++-- compat/zlib/win32/USAGE.txt | 12 ++++++++++-- compat/zlib/win32/VisualC.txt | 2 +- compat/zlib/win32/zdll.lib | Bin 17152 -> 17152 bytes compat/zlib/win32/zlib1.rc | 2 +- compat/zlib/win64/libz.dll.a | Bin 51638 -> 51638 bytes compat/zlib/win64/zdll.lib | Bin 16740 -> 16740 bytes compat/zlib/win64/zlib1.dll | Bin 116224 -> 116736 bytes compat/zlib/zlib.3 | 4 ++-- compat/zlib/zlib.3.pdf | Bin 19324 -> 19318 bytes compat/zlib/zlib.h | 17 +++++++++-------- compat/zlib/zutil.c | 2 +- 46 files changed, 92 insertions(+), 98 deletions(-) delete mode 100644 compat/zlib/contrib/vstudio/vc14/miniunz.vcxproj.user delete mode 100644 compat/zlib/contrib/vstudio/vc14/minizip.vcxproj.user delete mode 100644 compat/zlib/contrib/vstudio/vc14/testzlib.vcxproj.user delete mode 100644 compat/zlib/contrib/vstudio/vc14/testzlibdll.vcxproj.user delete mode 100644 compat/zlib/contrib/vstudio/vc14/zlibstat.vcxproj.user delete mode 100644 compat/zlib/contrib/vstudio/vc14/zlibvc.vcxproj.user mode change 100644 => 100755 compat/zlib/win32/zdll.lib diff --git a/compat/zlib/CMakeLists.txt b/compat/zlib/CMakeLists.txt index 1a954a6..0fe939d 100644 --- a/compat/zlib/CMakeLists.txt +++ b/compat/zlib/CMakeLists.txt @@ -3,7 +3,7 @@ set(CMAKE_ALLOW_LOOSE_LOOP_CONSTRUCTS ON) project(zlib C) -set(VERSION "1.2.10") +set(VERSION "1.2.11") option(ASM686 "Enable building i686 assembly implementation") option(AMD64 "Enable building amd64 assembly implementation") diff --git a/compat/zlib/ChangeLog b/compat/zlib/ChangeLog index fed9adb..30199a6 100644 --- a/compat/zlib/ChangeLog +++ b/compat/zlib/ChangeLog @@ -1,6 +1,10 @@ ChangeLog file for zlib +Changes in 1.2.11 (15 Jan 2017) +- Fix deflate stored bug when pulling last block from window +- Permit immediate deflateParams changes before any deflate input + Changes in 1.2.10 (2 Jan 2017) - Avoid warnings on snprintf() return value - Fix bug in deflate_stored() for zero-length input diff --git a/compat/zlib/Makefile.in b/compat/zlib/Makefile.in index 1852192..5a77949 100644 --- a/compat/zlib/Makefile.in +++ b/compat/zlib/Makefile.in @@ -1,5 +1,5 @@ # Makefile for zlib -# Copyright (C) 1995-2016 Jean-loup Gailly, Mark Adler +# Copyright (C) 1995-2017 Jean-loup Gailly, Mark Adler # For conditions of distribution and use, see copyright notice in zlib.h # To compile and test, type: @@ -32,7 +32,7 @@ CPP=$(CC) -E STATICLIB=libz.a SHAREDLIB=libz.so -SHAREDLIBV=libz.so.1.2.10 +SHAREDLIBV=libz.so.1.2.11 SHAREDLIBM=libz.so.1 LIBS=$(STATICLIB) $(SHAREDLIBV) diff --git a/compat/zlib/README b/compat/zlib/README index e2250bd..51106de 100644 --- a/compat/zlib/README +++ b/compat/zlib/README @@ -1,6 +1,6 @@ ZLIB DATA COMPRESSION LIBRARY -zlib 1.2.10 is a general purpose data compression library. All the code is +zlib 1.2.11 is a general purpose data compression library. All the code is thread safe. The data format used by the zlib library is described by RFCs (Request for Comments) 1950 to 1952 in the files http://tools.ietf.org/html/rfc1950 (zlib format), rfc1951 (deflate format) and @@ -31,7 +31,7 @@ Mark Nelson wrote an article about zlib for the Jan. 1997 issue of Dr. Dobb's Journal; a copy of the article is available at http://marknelson.us/1997/01/01/zlib-engine/ . -The changes made in version 1.2.10 are documented in the file ChangeLog. +The changes made in version 1.2.11 are documented in the file ChangeLog. Unsupported third party contributions are provided in directory contrib/ . diff --git a/compat/zlib/contrib/delphi/ZLib.pas b/compat/zlib/contrib/delphi/ZLib.pas index e9d72f0..060e199 100644 --- a/compat/zlib/contrib/delphi/ZLib.pas +++ b/compat/zlib/contrib/delphi/ZLib.pas @@ -152,7 +152,7 @@ procedure DecompressToUserBuf(const InBuf: Pointer; InBytes: Integer; const OutBuf: Pointer; BufSize: Integer); const - zlib_version = '1.2.10'; + zlib_version = '1.2.11'; type EZlibError = class(Exception); diff --git a/compat/zlib/contrib/dotzlib/DotZLib/UnitTests.cs b/compat/zlib/contrib/dotzlib/DotZLib/UnitTests.cs index a0e3985..44f7633 100644 --- a/compat/zlib/contrib/dotzlib/DotZLib/UnitTests.cs +++ b/compat/zlib/contrib/dotzlib/DotZLib/UnitTests.cs @@ -156,7 +156,7 @@ namespace DotZLibTests public void Info_Version() { Info info = new Info(); - Assert.AreEqual("1.2.10", Info.Version); + Assert.AreEqual("1.2.11", Info.Version); Assert.AreEqual(32, info.SizeOfUInt); Assert.AreEqual(32, info.SizeOfULong); Assert.AreEqual(32, info.SizeOfPointer); diff --git a/compat/zlib/contrib/infback9/inftree9.c b/compat/zlib/contrib/infback9/inftree9.c index ea56047..5f4a767 100644 --- a/compat/zlib/contrib/infback9/inftree9.c +++ b/compat/zlib/contrib/infback9/inftree9.c @@ -9,7 +9,7 @@ #define MAXBITS 15 const char inflate9_copyright[] = - " inflate9 1.2.10 Copyright 1995-2017 Mark Adler "; + " inflate9 1.2.11 Copyright 1995-2017 Mark Adler "; /* If you use the zlib library in a product, an acknowledgment is welcome in the documentation of your product. If for some reason you cannot @@ -64,7 +64,7 @@ unsigned short FAR *work; static const unsigned short lext[31] = { /* Length codes 257..285 extra */ 128, 128, 128, 128, 128, 128, 128, 128, 129, 129, 129, 129, 130, 130, 130, 130, 131, 131, 131, 131, 132, 132, 132, 132, - 133, 133, 133, 133, 144, 192, 202}; + 133, 133, 133, 133, 144, 77, 202}; static const unsigned short dbase[32] = { /* Distance codes 0..31 base */ 1, 2, 3, 4, 5, 7, 9, 13, 17, 25, 33, 49, 65, 97, 129, 193, 257, 385, 513, 769, 1025, 1537, 2049, 3073, diff --git a/compat/zlib/contrib/minizip/configure.ac b/compat/zlib/contrib/minizip/configure.ac index bbb2283..5b11970 100644 --- a/compat/zlib/contrib/minizip/configure.ac +++ b/compat/zlib/contrib/minizip/configure.ac @@ -1,7 +1,7 @@ # -*- Autoconf -*- # Process this file with autoconf to produce a configure script. -AC_INIT([minizip], [1.2.10], [bugzilla.redhat.com]) +AC_INIT([minizip], [1.2.11], [bugzilla.redhat.com]) AC_CONFIG_SRCDIR([minizip.c]) AM_INIT_AUTOMAKE([foreign]) LT_INIT diff --git a/compat/zlib/contrib/pascal/zlibpas.pas b/compat/zlib/contrib/pascal/zlibpas.pas index 2330898..a0dff11 100644 --- a/compat/zlib/contrib/pascal/zlibpas.pas +++ b/compat/zlib/contrib/pascal/zlibpas.pas @@ -10,7 +10,7 @@ unit zlibpas; interface const - ZLIB_VERSION = '1.2.10'; + ZLIB_VERSION = '1.2.11'; ZLIB_VERNUM = $12a0; type diff --git a/compat/zlib/contrib/vstudio/readme.txt b/compat/zlib/contrib/vstudio/readme.txt index 98d8a05..f67eae8 100644 --- a/compat/zlib/contrib/vstudio/readme.txt +++ b/compat/zlib/contrib/vstudio/readme.txt @@ -1,4 +1,4 @@ -Building instructions for the DLL versions of Zlib 1.2.10 +Building instructions for the DLL versions of Zlib 1.2.11 ======================================================== This directory contains projects that build zlib and minizip using diff --git a/compat/zlib/contrib/vstudio/vc10/zlib.rc b/compat/zlib/contrib/vstudio/vc10/zlib.rc index f1c19bc..fee177a 100644 --- a/compat/zlib/contrib/vstudio/vc10/zlib.rc +++ b/compat/zlib/contrib/vstudio/vc10/zlib.rc @@ -2,8 +2,8 @@ #define IDR_VERSION1 1 IDR_VERSION1 VERSIONINFO MOVEABLE IMPURE LOADONCALL DISCARDABLE - FILEVERSION 1, 2, 10, 0 - PRODUCTVERSION 1, 2, 10, 0 + FILEVERSION 1, 2, 11, 0 + PRODUCTVERSION 1, 2, 11, 0 FILEFLAGSMASK VS_FFI_FILEFLAGSMASK FILEFLAGS 0 FILEOS VOS_DOS_WINDOWS32 @@ -17,7 +17,7 @@ BEGIN BEGIN VALUE "FileDescription", "zlib data compression and ZIP file I/O library\0" - VALUE "FileVersion", "1.2.10\0" + VALUE "FileVersion", "1.2.11\0" VALUE "InternalName", "zlib\0" VALUE "OriginalFilename", "zlibwapi.dll\0" VALUE "ProductName", "ZLib.DLL\0" diff --git a/compat/zlib/contrib/vstudio/vc11/zlib.rc b/compat/zlib/contrib/vstudio/vc11/zlib.rc index f1c19bc..fee177a 100644 --- a/compat/zlib/contrib/vstudio/vc11/zlib.rc +++ b/compat/zlib/contrib/vstudio/vc11/zlib.rc @@ -2,8 +2,8 @@ #define IDR_VERSION1 1 IDR_VERSION1 VERSIONINFO MOVEABLE IMPURE LOADONCALL DISCARDABLE - FILEVERSION 1, 2, 10, 0 - PRODUCTVERSION 1, 2, 10, 0 + FILEVERSION 1, 2, 11, 0 + PRODUCTVERSION 1, 2, 11, 0 FILEFLAGSMASK VS_FFI_FILEFLAGSMASK FILEFLAGS 0 FILEOS VOS_DOS_WINDOWS32 @@ -17,7 +17,7 @@ BEGIN BEGIN VALUE "FileDescription", "zlib data compression and ZIP file I/O library\0" - VALUE "FileVersion", "1.2.10\0" + VALUE "FileVersion", "1.2.11\0" VALUE "InternalName", "zlib\0" VALUE "OriginalFilename", "zlibwapi.dll\0" VALUE "ProductName", "ZLib.DLL\0" diff --git a/compat/zlib/contrib/vstudio/vc12/zlib.rc b/compat/zlib/contrib/vstudio/vc12/zlib.rc index ef38298..c4e4b01 100644 --- a/compat/zlib/contrib/vstudio/vc12/zlib.rc +++ b/compat/zlib/contrib/vstudio/vc12/zlib.rc @@ -2,8 +2,8 @@ #define IDR_VERSION1 1 IDR_VERSION1 VERSIONINFO MOVEABLE IMPURE LOADONCALL DISCARDABLE - FILEVERSION 1, 2, 10, 0 - PRODUCTVERSION 1, 2, 10, 0 + FILEVERSION 1, 2, 11, 0 + PRODUCTVERSION 1, 2, 11, 0 FILEFLAGSMASK VS_FFI_FILEFLAGSMASK FILEFLAGS 0 FILEOS VOS_DOS_WINDOWS32 @@ -17,7 +17,7 @@ BEGIN BEGIN VALUE "FileDescription", "zlib data compression and ZIP file I/O library\0" - VALUE "FileVersion", "1.2.10\0" + VALUE "FileVersion", "1.2.11\0" VALUE "InternalName", "zlib\0" VALUE "OriginalFilename", "zlibwapi.dll\0" VALUE "ProductName", "ZLib.DLL\0" diff --git a/compat/zlib/contrib/vstudio/vc14/miniunz.vcxproj.user b/compat/zlib/contrib/vstudio/vc14/miniunz.vcxproj.user deleted file mode 100644 index abe8dd8..0000000 --- a/compat/zlib/contrib/vstudio/vc14/miniunz.vcxproj.user +++ /dev/null @@ -1,4 +0,0 @@ - - - - \ No newline at end of file diff --git a/compat/zlib/contrib/vstudio/vc14/minizip.vcxproj.user b/compat/zlib/contrib/vstudio/vc14/minizip.vcxproj.user deleted file mode 100644 index abe8dd8..0000000 --- a/compat/zlib/contrib/vstudio/vc14/minizip.vcxproj.user +++ /dev/null @@ -1,4 +0,0 @@ - - - - \ No newline at end of file diff --git a/compat/zlib/contrib/vstudio/vc14/testzlib.vcxproj.user b/compat/zlib/contrib/vstudio/vc14/testzlib.vcxproj.user deleted file mode 100644 index abe8dd8..0000000 --- a/compat/zlib/contrib/vstudio/vc14/testzlib.vcxproj.user +++ /dev/null @@ -1,4 +0,0 @@ - - - - \ No newline at end of file diff --git a/compat/zlib/contrib/vstudio/vc14/testzlibdll.vcxproj.user b/compat/zlib/contrib/vstudio/vc14/testzlibdll.vcxproj.user deleted file mode 100644 index abe8dd8..0000000 --- a/compat/zlib/contrib/vstudio/vc14/testzlibdll.vcxproj.user +++ /dev/null @@ -1,4 +0,0 @@ - - - - \ No newline at end of file diff --git a/compat/zlib/contrib/vstudio/vc14/zlib.rc b/compat/zlib/contrib/vstudio/vc14/zlib.rc index ef38298..c4e4b01 100644 --- a/compat/zlib/contrib/vstudio/vc14/zlib.rc +++ b/compat/zlib/contrib/vstudio/vc14/zlib.rc @@ -2,8 +2,8 @@ #define IDR_VERSION1 1 IDR_VERSION1 VERSIONINFO MOVEABLE IMPURE LOADONCALL DISCARDABLE - FILEVERSION 1, 2, 10, 0 - PRODUCTVERSION 1, 2, 10, 0 + FILEVERSION 1, 2, 11, 0 + PRODUCTVERSION 1, 2, 11, 0 FILEFLAGSMASK VS_FFI_FILEFLAGSMASK FILEFLAGS 0 FILEOS VOS_DOS_WINDOWS32 @@ -17,7 +17,7 @@ BEGIN BEGIN VALUE "FileDescription", "zlib data compression and ZIP file I/O library\0" - VALUE "FileVersion", "1.2.10\0" + VALUE "FileVersion", "1.2.11\0" VALUE "InternalName", "zlib\0" VALUE "OriginalFilename", "zlibwapi.dll\0" VALUE "ProductName", "ZLib.DLL\0" diff --git a/compat/zlib/contrib/vstudio/vc14/zlibstat.vcxproj.user b/compat/zlib/contrib/vstudio/vc14/zlibstat.vcxproj.user deleted file mode 100644 index abe8dd8..0000000 --- a/compat/zlib/contrib/vstudio/vc14/zlibstat.vcxproj.user +++ /dev/null @@ -1,4 +0,0 @@ - - - - \ No newline at end of file diff --git a/compat/zlib/contrib/vstudio/vc14/zlibvc.vcxproj.user b/compat/zlib/contrib/vstudio/vc14/zlibvc.vcxproj.user deleted file mode 100644 index abe8dd8..0000000 --- a/compat/zlib/contrib/vstudio/vc14/zlibvc.vcxproj.user +++ /dev/null @@ -1,4 +0,0 @@ - - - - \ No newline at end of file diff --git a/compat/zlib/contrib/vstudio/vc9/zlib.rc b/compat/zlib/contrib/vstudio/vc9/zlib.rc index f1c19bc..fee177a 100644 --- a/compat/zlib/contrib/vstudio/vc9/zlib.rc +++ b/compat/zlib/contrib/vstudio/vc9/zlib.rc @@ -2,8 +2,8 @@ #define IDR_VERSION1 1 IDR_VERSION1 VERSIONINFO MOVEABLE IMPURE LOADONCALL DISCARDABLE - FILEVERSION 1, 2, 10, 0 - PRODUCTVERSION 1, 2, 10, 0 + FILEVERSION 1, 2, 11, 0 + PRODUCTVERSION 1, 2, 11, 0 FILEFLAGSMASK VS_FFI_FILEFLAGSMASK FILEFLAGS 0 FILEOS VOS_DOS_WINDOWS32 @@ -17,7 +17,7 @@ BEGIN BEGIN VALUE "FileDescription", "zlib data compression and ZIP file I/O library\0" - VALUE "FileVersion", "1.2.10\0" + VALUE "FileVersion", "1.2.11\0" VALUE "InternalName", "zlib\0" VALUE "OriginalFilename", "zlibwapi.dll\0" VALUE "ProductName", "ZLib.DLL\0" diff --git a/compat/zlib/deflate.c b/compat/zlib/deflate.c index 2ad890e..1ec7614 100644 --- a/compat/zlib/deflate.c +++ b/compat/zlib/deflate.c @@ -52,7 +52,7 @@ #include "deflate.h" const char deflate_copyright[] = - " deflate 1.2.10 Copyright 1995-2017 Jean-loup Gailly and Mark Adler "; + " deflate 1.2.11 Copyright 1995-2017 Jean-loup Gailly and Mark Adler "; /* If you use the zlib library in a product, an acknowledgment is welcome in the documentation of your product. If for some reason you cannot @@ -586,7 +586,8 @@ int ZEXPORT deflateParams(strm, level, strategy) } func = configuration_table[s->level].func; - if ((strategy != s->strategy || func != configuration_table[level].func)) { + if ((strategy != s->strategy || func != configuration_table[level].func) && + s->high_water) { /* Flush the last buffer: */ int err = deflate(strm, Z_BLOCK); if (err == Z_STREAM_ERROR) @@ -1671,8 +1672,6 @@ local block_state deflate_stored(s, flush) len = left + s->strm->avail_in; /* limit len to the input */ if (len > have) len = have; /* limit len to the output */ - if (left > len) - left = len; /* limit window pull to len */ /* If the stored block would be less than min_block in length, or if * unable to copy all of the available input when flushing, then try @@ -1681,13 +1680,13 @@ local block_state deflate_stored(s, flush) */ if (len < min_block && ((len == 0 && flush != Z_FINISH) || flush == Z_NO_FLUSH || - len - left != s->strm->avail_in)) + len != left + s->strm->avail_in)) break; /* Make a dummy stored block in pending to get the header bytes, * including any pending bits. This also updates the debugging counts. */ - last = flush == Z_FINISH && len - left == s->strm->avail_in ? 1 : 0; + last = flush == Z_FINISH && len == left + s->strm->avail_in ? 1 : 0; _tr_stored_block(s, (char *)0, 0L, last); /* Replace the lengths in the dummy stored block with len. */ @@ -1699,14 +1698,16 @@ local block_state deflate_stored(s, flush) /* Write the stored block header bytes. */ flush_pending(s->strm); - /* Update debugging counts for the data about to be copied. */ #ifdef ZLIB_DEBUG + /* Update debugging counts for the data about to be copied. */ s->compressed_len += len << 3; s->bits_sent += len << 3; #endif /* Copy uncompressed bytes from the window to next_out. */ if (left) { + if (left > len) + left = len; zmemcpy(s->strm->next_out, s->window + s->block_start, left); s->strm->next_out += left; s->strm->avail_out -= left; @@ -1756,6 +1757,8 @@ local block_state deflate_stored(s, flush) s->block_start = s->strstart; s->insert += MIN(used, s->w_size - s->insert); } + if (s->high_water < s->strstart) + s->high_water = s->strstart; /* If the last block was written to next_out, then done. */ if (last) @@ -1783,6 +1786,8 @@ local block_state deflate_stored(s, flush) read_buf(s->strm, s->window + s->strstart, have); s->strstart += have; } + if (s->high_water < s->strstart) + s->high_water = s->strstart; /* There was not enough avail_out to write a complete worthy or flushed * stored block to next_out. Write a stored block to pending instead, if we diff --git a/compat/zlib/gzlib.c b/compat/zlib/gzlib.c index e142ffb..4105e6a 100644 --- a/compat/zlib/gzlib.c +++ b/compat/zlib/gzlib.c @@ -1,5 +1,5 @@ /* gzlib.c -- zlib functions common to reading and writing gzip files - * Copyright (C) 2004, 2010, 2011, 2012, 2013, 2016 Mark Adler + * Copyright (C) 2004-2017 Mark Adler * For conditions of distribution and use, see copyright notice in zlib.h */ diff --git a/compat/zlib/gzwrite.c b/compat/zlib/gzwrite.c index 1ec1da4..c7b5651 100644 --- a/compat/zlib/gzwrite.c +++ b/compat/zlib/gzwrite.c @@ -1,5 +1,5 @@ /* gzwrite.c -- zlib functions for writing gzip files - * Copyright (C) 2004, 2005, 2010, 2011, 2012, 2013, 2016 Mark Adler + * Copyright (C) 2004-2017 Mark Adler * For conditions of distribution and use, see copyright notice in zlib.h */ diff --git a/compat/zlib/inffast.c b/compat/zlib/inffast.c index 29eb7d8..0dbd1db 100644 --- a/compat/zlib/inffast.c +++ b/compat/zlib/inffast.c @@ -1,5 +1,5 @@ /* inffast.c -- fast decoding - * Copyright (C) 1995-2008, 2010, 2013, 2016 Mark Adler + * Copyright (C) 1995-2017 Mark Adler * For conditions of distribution and use, see copyright notice in zlib.h */ diff --git a/compat/zlib/inftrees.c b/compat/zlib/inftrees.c index 8a904dd..2ea08fc 100644 --- a/compat/zlib/inftrees.c +++ b/compat/zlib/inftrees.c @@ -9,7 +9,7 @@ #define MAXBITS 15 const char inflate_copyright[] = - " inflate 1.2.10 Copyright 1995-2017 Mark Adler "; + " inflate 1.2.11 Copyright 1995-2017 Mark Adler "; /* If you use the zlib library in a product, an acknowledgment is welcome in the documentation of your product. If for some reason you cannot @@ -62,7 +62,7 @@ unsigned short FAR *work; 35, 43, 51, 59, 67, 83, 99, 115, 131, 163, 195, 227, 258, 0, 0}; static const unsigned short lext[31] = { /* Length codes 257..285 extra */ 16, 16, 16, 16, 16, 16, 16, 16, 17, 17, 17, 17, 18, 18, 18, 18, - 19, 19, 19, 19, 20, 20, 20, 20, 21, 21, 21, 21, 16, 192, 202}; + 19, 19, 19, 19, 20, 20, 20, 20, 21, 21, 21, 21, 16, 77, 202}; static const unsigned short dbase[32] = { /* Distance codes 0..29 base */ 1, 2, 3, 4, 5, 7, 9, 13, 17, 25, 33, 49, 65, 97, 129, 193, 257, 385, 513, 769, 1025, 1537, 2049, 3073, 4097, 6145, diff --git a/compat/zlib/os400/README400 b/compat/zlib/os400/README400 index 28dca8c..4f98334 100644 --- a/compat/zlib/os400/README400 +++ b/compat/zlib/os400/README400 @@ -1,4 +1,4 @@ - ZLIB version 1.2.10 for OS/400 installation instructions + ZLIB version 1.2.11 for OS/400 installation instructions 1) Download and unpack the zlib tarball to some IFS directory. (i.e.: /path/to/the/zlib/ifs/source/directory) diff --git a/compat/zlib/os400/make.sh b/compat/zlib/os400/make.sh index ddbfb16..19eec11 100644 --- a/compat/zlib/os400/make.sh +++ b/compat/zlib/os400/make.sh @@ -260,7 +260,7 @@ fi echo '#pragma comment(user, "ZLIB version '"${VERSION}"'")' > os400.c echo '#pragma comment(user, __DATE__)' >> os400.c echo '#pragma comment(user, __TIME__)' >> os400.c -echo '#pragma comment(copyright, "Copyright (C) 1995-2016 Jean-Loup Gailly, Mark Adler. OS/400 version by P. Monnerat.")' >> os400.c +echo '#pragma comment(copyright, "Copyright (C) 1995-2017 Jean-Loup Gailly, Mark Adler. OS/400 version by P. Monnerat.")' >> os400.c make_module OS400 os400.c LINK= # No need to rebuild service program yet. MODULES= diff --git a/compat/zlib/os400/zlib.inc b/compat/zlib/os400/zlib.inc index a2147dd..c6aca2c 100644 --- a/compat/zlib/os400/zlib.inc +++ b/compat/zlib/os400/zlib.inc @@ -1,7 +1,7 @@ * ZLIB.INC - Interface to the general purpose compression library * * ILE RPG400 version by Patrick Monnerat, DATASPHERE. - * Version 1.2.10 + * Version 1.2.11 * * * WARNING: @@ -22,12 +22,12 @@ * * Versioning information. * - D ZLIB_VERSION C '1.2.10' + D ZLIB_VERSION C '1.2.11' D ZLIB_VERNUM C X'12a0' D ZLIB_VER_MAJOR C 1 D ZLIB_VER_MINOR C 2 D ZLIB_VER_REVISION... - D C 10 + D C 11 D ZLIB_VER_SUBREVISION... D C 0 * diff --git a/compat/zlib/qnx/package.qpg b/compat/zlib/qnx/package.qpg index d9a1229..31e8e90 100644 --- a/compat/zlib/qnx/package.qpg +++ b/compat/zlib/qnx/package.qpg @@ -25,10 +25,10 @@ - - - - + + + + @@ -63,7 +63,7 @@ - 1.2.10 + 1.2.11 Medium Stable diff --git a/compat/zlib/treebuild.xml b/compat/zlib/treebuild.xml index a530cc0..fd75525 100644 --- a/compat/zlib/treebuild.xml +++ b/compat/zlib/treebuild.xml @@ -1,6 +1,6 @@ - - + + zip compression library diff --git a/compat/zlib/trees.c b/compat/zlib/trees.c index 357f313..50cf4b4 100644 --- a/compat/zlib/trees.c +++ b/compat/zlib/trees.c @@ -1,5 +1,5 @@ /* trees.c -- output deflated data using Huffman coding - * Copyright (C) 1995-2016 Jean-loup Gailly + * Copyright (C) 1995-2017 Jean-loup Gailly * detect_data_type() function provided freely by Cosmin Truta, 2006 * For conditions of distribution and use, see copyright notice in zlib.h */ @@ -906,7 +906,7 @@ void ZLIB_INTERNAL _tr_align(s) /* =========================================================================== * Determine the best encoding for the current block: dynamic trees, static - * trees or store, and output the encoded block to the zip file. + * trees or store, and write out the encoded block. */ void ZLIB_INTERNAL _tr_flush_block(s, buf, stored_len, last) deflate_state *s; diff --git a/compat/zlib/win32/Makefile.msc b/compat/zlib/win32/Makefile.msc index 67b7731..6831882 100644 --- a/compat/zlib/win32/Makefile.msc +++ b/compat/zlib/win32/Makefile.msc @@ -1,5 +1,5 @@ # Makefile for zlib using Microsoft (Visual) C -# zlib is copyright (C) 1995-2006 Jean-loup Gailly and Mark Adler +# zlib is copyright (C) 1995-2017 Jean-loup Gailly and Mark Adler # # Usage: # nmake -f win32/Makefile.msc (standard build) diff --git a/compat/zlib/win32/README-WIN32.txt b/compat/zlib/win32/README-WIN32.txt index 16adcca..df7ab7f 100644 --- a/compat/zlib/win32/README-WIN32.txt +++ b/compat/zlib/win32/README-WIN32.txt @@ -1,6 +1,6 @@ ZLIB DATA COMPRESSION LIBRARY -zlib 1.2.10 is a general purpose data compression library. All the code is +zlib 1.2.11 is a general purpose data compression library. All the code is thread safe. The data format used by the zlib library is described by RFCs (Request for Comments) 1950 to 1952 in the files http://www.ietf.org/rfc/rfc1950.txt (zlib format), rfc1951.txt (deflate format) @@ -22,7 +22,7 @@ before asking for help. Manifest: -The package zlib-1.2.10-win32-x86.zip will contain the following files: +The package zlib-1.2.11-win32-x86.zip will contain the following files: README-WIN32.txt This document ChangeLog Changes since previous zlib packages @@ -72,7 +72,7 @@ are too numerous to cite here. Copyright notice: - (C) 1995-2012 Jean-loup Gailly and Mark Adler + (C) 1995-2017 Jean-loup Gailly and Mark Adler This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/compat/zlib/win32/README.txt b/compat/zlib/win32/README.txt index de1d05a..bd3d18d 100644 --- a/compat/zlib/win32/README.txt +++ b/compat/zlib/win32/README.txt @@ -6,7 +6,7 @@ What's here Source ====== - zlib version 1.2.10 + zlib version 1.2.11 available at http://www.gzip.org/zlib/ @@ -37,7 +37,7 @@ Build info Copyright notice ================ - Copyright (C) 1995-2010 Jean-loup Gailly and Mark Adler + Copyright (C) 1995-2017 Jean-loup Gailly and Mark Adler This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/compat/zlib/win32/USAGE.txt b/compat/zlib/win32/USAGE.txt index 48e594e..22829eb 100644 --- a/compat/zlib/win32/USAGE.txt +++ b/compat/zlib/win32/USAGE.txt @@ -2,6 +2,9 @@ Installing ZLIB1.DLL ==================== Copy ZLIB1.DLL to the SYSTEM or the SYSTEM32 directory. + + If you want to install the 32-bit dll on a 64-bit + machine, use the SysWOW64 directory instead. Using ZLIB1.DLL with Microsoft Visual C++ @@ -20,12 +23,17 @@ Using ZLIB1.DLL with gcc/MinGW 1. Install the supplied header files "zlib.h" and "zconf.h" into the INCLUDE directory. - 2. Copy the supplied library file "zdll.lib" to "libzdll.a": + 2. (32-bit): Copy the supplied library file "zdll.lib" to "libzdll.a": cp lib/zdll.lib lib/libzdll.a OR - 2' Build the import library from the supplied "zlib.def": + 2'. (64-bit): Copy the supplied library file "libz.dll.a" to "libzdll.a": + cp lib/libz.dll.a lib/libzdll.a + + OR + + 2'' Build the import library from the supplied "zlib.def": dlltool -D zlib1.dll -d lib/zlib.def -l lib/libzdll.a 3. Install "libzdll.a" into the LIB directory. diff --git a/compat/zlib/win32/VisualC.txt b/compat/zlib/win32/VisualC.txt index 579a5fc..1005b21 100644 --- a/compat/zlib/win32/VisualC.txt +++ b/compat/zlib/win32/VisualC.txt @@ -1,3 +1,3 @@ To build zlib using the Microsoft Visual C++ environment, -use the appropriate project from the projects/ directory. +use the appropriate project from the contrib/vstudio/ directory. diff --git a/compat/zlib/win32/zdll.lib b/compat/zlib/win32/zdll.lib old mode 100644 new mode 100755 index 5807541..a3e9a39 Binary files a/compat/zlib/win32/zdll.lib and b/compat/zlib/win32/zdll.lib differ diff --git a/compat/zlib/win32/zlib1.rc b/compat/zlib/win32/zlib1.rc index 5c0feed..234e641 100644 --- a/compat/zlib/win32/zlib1.rc +++ b/compat/zlib/win32/zlib1.rc @@ -26,7 +26,7 @@ BEGIN VALUE "FileDescription", "zlib data compression library\0" VALUE "FileVersion", ZLIB_VERSION "\0" VALUE "InternalName", "zlib1.dll\0" - VALUE "LegalCopyright", "(C) 1995-2013 Jean-loup Gailly & Mark Adler\0" + VALUE "LegalCopyright", "(C) 1995-2017 Jean-loup Gailly & Mark Adler\0" VALUE "OriginalFilename", "zlib1.dll\0" VALUE "ProductName", "zlib\0" VALUE "ProductVersion", ZLIB_VERSION "\0" diff --git a/compat/zlib/win64/libz.dll.a b/compat/zlib/win64/libz.dll.a index d90a90c..93be06e 100644 Binary files a/compat/zlib/win64/libz.dll.a and b/compat/zlib/win64/libz.dll.a differ diff --git a/compat/zlib/win64/zdll.lib b/compat/zlib/win64/zdll.lib index db56951..c1be098 100644 Binary files a/compat/zlib/win64/zdll.lib and b/compat/zlib/win64/zdll.lib differ diff --git a/compat/zlib/win64/zlib1.dll b/compat/zlib/win64/zlib1.dll index 86b6bbe..81195c3 100755 Binary files a/compat/zlib/win64/zlib1.dll and b/compat/zlib/win64/zlib1.dll differ diff --git a/compat/zlib/zlib.3 b/compat/zlib/zlib.3 index 00dc061..bda4eb0 100644 --- a/compat/zlib/zlib.3 +++ b/compat/zlib/zlib.3 @@ -1,4 +1,4 @@ -.TH ZLIB 3 "2 Jan 2017" +.TH ZLIB 3 "15 Jan 2017" .SH NAME zlib \- compression/decompression library .SH SYNOPSIS @@ -105,7 +105,7 @@ before asking for help. Send questions and/or comments to zlib@gzip.org, or (for the Windows DLL version) to Gilles Vollant (info@winimage.com). .SH AUTHORS AND LICENSE -Version 1.2.10 +Version 1.2.11 .LP Copyright (C) 1995-2017 Jean-loup Gailly and Mark Adler .LP diff --git a/compat/zlib/zlib.3.pdf b/compat/zlib/zlib.3.pdf index 20008cd..6fa519c 100644 Binary files a/compat/zlib/zlib.3.pdf and b/compat/zlib/zlib.3.pdf differ diff --git a/compat/zlib/zlib.h b/compat/zlib/zlib.h index dc90dc8..f09cdaf 100644 --- a/compat/zlib/zlib.h +++ b/compat/zlib/zlib.h @@ -1,5 +1,5 @@ /* zlib.h -- interface of the 'zlib' general purpose compression library - version 1.2.10, January 2nd, 2017 + version 1.2.11, January 15th, 2017 Copyright (C) 1995-2017 Jean-loup Gailly and Mark Adler @@ -37,11 +37,11 @@ extern "C" { #endif -#define ZLIB_VERSION "1.2.10" -#define ZLIB_VERNUM 0x12a0 +#define ZLIB_VERSION "1.2.11" +#define ZLIB_VERNUM 0x12b0 #define ZLIB_VER_MAJOR 1 #define ZLIB_VER_MINOR 2 -#define ZLIB_VER_REVISION 10 +#define ZLIB_VER_REVISION 11 #define ZLIB_VER_SUBREVISION 0 /* @@ -712,10 +712,11 @@ ZEXTERN int ZEXPORT deflateParams OF((z_streamp strm, used to switch between compression and straight copy of the input data, or to switch to a different kind of input data requiring a different strategy. If the compression approach (which is a function of the level) or the - strategy is changed, then the input available so far is compressed with the - old level and strategy using deflate(strm, Z_BLOCK). There are three - approaches for the compression levels 0, 1..3, and 4..9 respectively. The - new level and strategy will take effect at the next call of deflate(). + strategy is changed, and if any input has been consumed in a previous + deflate() call, then the input available so far is compressed with the old + level and strategy using deflate(strm, Z_BLOCK). There are three approaches + for the compression levels 0, 1..3, and 4..9 respectively. The new level + and strategy will take effect at the next call of deflate(). If a deflate(strm, Z_BLOCK) is performed by deflateParams(), and it does not have enough output space to complete, then the parameter change will not diff --git a/compat/zlib/zutil.c b/compat/zlib/zutil.c index 56534fb..a76c6b0 100644 --- a/compat/zlib/zutil.c +++ b/compat/zlib/zutil.c @@ -1,5 +1,5 @@ /* zutil.c -- target dependent utility functions for the compression library - * Copyright (C) 1995-2005, 2010, 2011, 2012, 2016 Jean-loup Gailly + * Copyright (C) 1995-2017 Jean-loup Gailly * For conditions of distribution and use, see copyright notice in zlib.h */ -- cgit v0.12 From ea1cc886b527b6b90b33b11588769335f4762a47 Mon Sep 17 00:00:00 2001 From: "jan.nijtmans" Date: Tue, 17 Jan 2017 09:02:13 +0000 Subject: Hm. 32-bit zlib dll still was the 1.2.10 version. Corrected now. --- compat/zlib/win32/zlib1.dll | Bin 104960 -> 105472 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/compat/zlib/win32/zlib1.dll b/compat/zlib/win32/zlib1.dll index 81f53ec..3196f4a 100755 Binary files a/compat/zlib/win32/zlib1.dll and b/compat/zlib/win32/zlib1.dll differ -- cgit v0.12 From 3cd704802f4da0e909c95295d850c938de754022 Mon Sep 17 00:00:00 2001 From: "jan.nijtmans" Date: Tue, 17 Jan 2017 10:00:58 +0000 Subject: Test-cases which require Tcl 8.5 (or 8.6) should continue to work unmodified in Tcl 9.0. The "novem" branch will show whether this continues to work. --- tests/all.tcl | 2 +- tests/httpd11.tcl | 2 +- tests/httpold.test | 2 +- tests/msgcat.test | 48 ++++++++++++++++++++++++------------------------ tests/safe.test | 2 +- tests/tm.test | 4 ++-- 6 files changed, 30 insertions(+), 30 deletions(-) diff --git a/tests/all.tcl b/tests/all.tcl index 0a6f57f..69a16ba 100644 --- a/tests/all.tcl +++ b/tests/all.tcl @@ -11,7 +11,7 @@ # of this file, and for a DISCLAIMER OF ALL WARRANTIES. package prefer latest -package require Tcl 8.5 +package require Tcl 8.5- package require tcltest 2.2 namespace import tcltest::* configure {*}$argv -testdir [file dir [info script]] diff --git a/tests/httpd11.tcl b/tests/httpd11.tcl index 6eae2b7..7880494 100644 --- a/tests/httpd11.tcl +++ b/tests/httpd11.tcl @@ -8,7 +8,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.6 +package require Tcl 8.6- proc ::tcl::dict::get? {dict key} { if {[dict exists $dict $key]} { diff --git a/tests/httpold.test b/tests/httpold.test index aeba311..5995bed 100644 --- a/tests/httpold.test +++ b/tests/httpold.test @@ -36,7 +36,7 @@ if {[catch {package require http 1.0}]} { set bindata "This is binary data\x0d\x0amore\x0dmore\x0amore\x00null" catch {unset data} -## +## ## The httpd script implement a stub http server ## source [file join [file dirname [info script]] httpd] diff --git a/tests/msgcat.test b/tests/msgcat.test index ae35272..1c3ce58 100644 --- a/tests/msgcat.test +++ b/tests/msgcat.test @@ -12,7 +12,7 @@ # Note that after running these tests, entries will be left behind in the # message catalogs for locales foo, foo_BAR, and foo_BAR_baz. -package require Tcl 8.5 +package require Tcl 8.5- if {[catch {package require tcltest 2}]} { puts stderr "Skipping tests in [info script]. tcltest 2 required." return @@ -51,7 +51,7 @@ namespace eval ::msgcat::test { variable body variable result variable setVars - foreach setVars [PowerSet $envVars] { + foreach setVars [PowerSet $envVars] { set result [string tolower [lindex $setVars 0]] if {[string length $result] == 0} { if {[info exists ::tcl::mac::locale]} { @@ -94,7 +94,7 @@ namespace eval ::msgcat::test { incr count } unset -nocomplain result - + # Could add tests of initialization from Windows registry here. # Use a fake registry package. @@ -294,11 +294,11 @@ namespace eval ::msgcat::test { variable count 2 variable result array set result { - foo,ov0 ov0_ROOT foo,ov1 ov1_foo foo,ov2 ov2_foo + foo,ov0 ov0_ROOT foo,ov1 ov1_foo foo,ov2 ov2_foo foo,ov3 ov3_foo foo,ov4 ov4 - foo_BAR,ov0 ov0_ROOT foo_BAR,ov1 ov1_foo foo_BAR,ov2 ov2_foo_BAR - foo_BAR,ov3 ov3_foo_BAR foo_BAR,ov4 ov4 - foo_BAR_baz,ov0 ov0_ROOT foo_BAR_baz,ov1 ov1_foo + foo_BAR,ov0 ov0_ROOT foo_BAR,ov1 ov1_foo foo_BAR,ov2 ov2_foo_BAR + foo_BAR,ov3 ov3_foo_BAR foo_BAR,ov4 ov4 + foo_BAR_baz,ov0 ov0_ROOT foo_BAR_baz,ov1 ov1_foo foo_BAR_baz,ov2 ov2_foo_BAR foo_BAR_baz,ov3 ov3_foo_BAR_baz foo_BAR_baz,ov4 ov4 } @@ -417,12 +417,12 @@ namespace eval ::msgcat::test { variable locale [mclocale] ::msgcat::mclocale "" ::msgcat::mcloadedlocales clear - ::msgcat::mcpackageconfig unset mcfolder + ::msgcat::mcpackageconfig unset mcfolder mclocale $loc } -cleanup { mclocale $locale ::msgcat::mcloadedlocales clear - ::msgcat::mcpackageconfig unset mcfolder + ::msgcat::mcpackageconfig unset mcfolder } -body { mcload $msgdir } -result [expr { $count+1 }] @@ -437,7 +437,7 @@ namespace eval ::msgcat::test { } -cleanup { mclocale $locale mcloadedlocales clear - mcpackageconfig unset mcfolder + mcpackageconfig unset mcfolder } -body { mcload $msgdir } -result 3 @@ -448,7 +448,7 @@ namespace eval ::msgcat::test { } -cleanup { mclocale $locale mcloadedlocales clear - mcpackageconfig unset mcfolder + mcpackageconfig unset mcfolder } -body { mcload $msgdir } -result 1 @@ -517,7 +517,7 @@ namespace eval ::msgcat::test { } -cleanup { mclocale $locale mcloadedlocales clear - mcpackageconfig unset mcfolder + mcpackageconfig unset mcfolder } -body { mclocale foo mcpackageconfig set mcfolder $msgdir @@ -536,7 +536,7 @@ namespace eval ::msgcat::test { # Tests msgcat-6.*: [mcset], [mc] namespace inheritance # # Test mcset and mc, ensuring that resolution for messages -# proceeds from the current ns to its parent and so on to the +# proceeds from the current ns to its parent and so on to the # global ns. # # Do this for the 12 permutations of @@ -580,7 +580,7 @@ namespace eval ::msgcat::test { ::msgcat::mcset foo ov3 "ov3_foo_bar_baz" } } - + } variable locale [mclocale] mclocale foo @@ -689,12 +689,12 @@ namespace eval ::msgcat::test { mcexists } -returnCodes 1\ -result {wrong # args: should be "mcexists ?-exactnamespace? ?-exactlocale? src"} - + test msgcat-9.2 {mcexists unknown option} -body { - mcexists -unknown src + mcexists -unknown src } -returnCodes 1\ -result {unknown option "-unknown"} - + test msgcat-9.3 {mcexists} -setup { mcforgetpackage variable locale [mclocale] @@ -716,7 +716,7 @@ namespace eval ::msgcat::test { } -body { list [mcexists k1] [mcexists -exactlocale k1] } -result {1 0} - + test msgcat-9.5 {mcexists parent namespace} -setup { mcforgetpackage variable locale [mclocale] @@ -730,19 +730,19 @@ namespace eval ::msgcat::test { [::msgcat::mcexists -exactnamespace k1] } } -result {1 0} - + # Tests msgcat-10.*: [mcloadedlocales] test msgcat-10.1 {mcloadedlocales no arg} -body { mcloadedlocales } -returnCodes 1\ -result {wrong # args: should be "mcloadedlocales subcommand"} - + test msgcat-10.2 {mcloadedlocales wrong subcommand} -body { mcloadedlocales junk } -returnCodes 1\ -result {unknown subcommand "junk": must be clear, or loaded} - + test msgcat-10.3 {mcloadedlocales loaded} -setup { mcforgetpackage variable locale [mclocale] @@ -755,7 +755,7 @@ namespace eval ::msgcat::test { # The result is position independent so sort set resultlist [lsort [mcloadedlocales loaded]] } -result {{} foo foo_bar} - + test msgcat-10.4 {mcloadedlocales clear} -setup { mcforgetpackage variable locale [mclocale] @@ -961,9 +961,9 @@ namespace eval ::msgcat::test { } -result {0 0 1 0} # option mcfolder is already tested with 5.11 - + # Tests msgcat-14.*: callbacks: loadcmd, changecmd, unknowncmd - + # This routine is used as bgerror and by direct callback invocation proc callbackproc args { variable resultvariable diff --git a/tests/safe.test b/tests/safe.test index 6c9c6c9..e43ce12 100644 --- a/tests/safe.test +++ b/tests/safe.test @@ -10,7 +10,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.5- if {[lsearch [namespace children] ::tcltest] == -1} { package require tcltest 2 diff --git a/tests/tm.test b/tests/tm.test index 1b22f8c..567d351 100644 --- a/tests/tm.test +++ b/tests/tm.test @@ -6,7 +6,7 @@ # Copyright (c) 2004 by Donal K. Fellows. # All rights reserved. -package require Tcl 8.5 +package require Tcl 8.5- if {"::tcltest" ni [namespace children]} { package require tcltest 2 namespace import -force ::tcltest::* @@ -200,7 +200,7 @@ test tm-3.11 {tm: module path management, remove ignores unknown path} -setup { proc genpaths {base} { # Normalizing picks up drive letters on windows [Bug 1053568] set base [file normalize $base] - lassign [split [package present Tcl] .] major minor + lassign [split [package present Tcl] .] major minor set results {} set base [file join $base tcl$major] lappend results [file join $base site-tcl] -- cgit v0.12 From e7e764dbdf02a4e2a1cec81daa8f25bf2312695a Mon Sep 17 00:00:00 2001 From: "jan.nijtmans" Date: Tue, 17 Jan 2017 12:02:43 +0000 Subject: Implement tag "deprecated" in genStubs.tcl. Will be used in Tk 8.7, for tagging the deprecated function Tk_FreeXId() --- tools/genStubs.tcl | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) diff --git a/tools/genStubs.tcl b/tools/genStubs.tcl index 9f2c6ca..742aa46 100644 --- a/tools/genStubs.tcl +++ b/tools/genStubs.tcl @@ -199,6 +199,13 @@ proc genStubs::declare {args} { set stubs($curName,$platform,lastNum) $index } } + if {$platformList eq "deprecated"} { + set stubs($curName,generic,$index) $decl + if {![info exists stubs($curName,generic,lastNum)] \ + || ($index > $stubs($curName,generic,lastNum))} { + set stubs($curName,$platform,lastNum) $index + } + } } return } @@ -455,10 +462,16 @@ proc genStubs::parseArg {arg} { proc genStubs::makeDecl {name decl index} { variable scspec + variable stubs + variable libraryName lassign $decl rtype fname args append text "/* $index */\n" + if {[info exists stubs($name,deprecated,$index)]} { + set line "[string toupper $libraryName]_DEPRECATED $rtype" + } else { set line "$scspec $rtype" + } set count [expr {2 - ([string length $line] / 8)}] append line [string range "\t\t\t" 0 $count] set pad [expr {24 - [string length $line]}] @@ -682,7 +695,10 @@ proc genStubs::forAllStubs {name slotProc onAll textVar for {set i 0} {$i <= $lastNum} {incr i} { set slots [array names stubs $name,*,$i] set emit 0 - if {[info exists stubs($name,generic,$i)]} { + if {[info exists stubs($name,deprecated,$i)]} { + append text [$slotProc $name $stubs($name,generic,$i) $i] + set emit 1 + } elseif {[info exists stubs($name,generic,$i)]} { if {[llength $slots] > 1} { puts stderr "conflicting generic and platform entries:\ $name $i" -- cgit v0.12 From 649902f7fa1502d2873ed4762c1284a1ebe6bee4 Mon Sep 17 00:00:00 2001 From: fvogel Date: Thu, 19 Jan 2017 22:37:48 +0000 Subject: Fix [1f4bb8162f]: lsort -dictionary documentation to be improved --- doc/lsort.n | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/doc/lsort.n b/doc/lsort.n index b0f7973..c3245b2 100644 --- a/doc/lsort.n +++ b/doc/lsort.n @@ -40,7 +40,8 @@ except (a) case is ignored except as a tie-breaker and (b) if two strings contain embedded numbers, the numbers compare as integers, not characters. For example, in \fB\-dictionary\fR mode, \fBbigBoy\fR sorts between \fBbigbang\fR and \fBbigboy\fR, and \fBx10y\fR -sorts between \fBx9y\fR and \fBx11y\fR. +sorts between \fBx9y\fR and \fBx11y\fR. Overrides the \fB\-nocase\fR +option. .TP \fB\-integer\fR . -- cgit v0.12 From 2645c0ef3a6224d21261691e789a43332d87b5e5 Mon Sep 17 00:00:00 2001 From: "jan.nijtmans" Date: Wed, 25 Jan 2017 12:22:16 +0000 Subject: If TCL_NO_DEPRECATED is defined, remove the "case" statement, and use much less interp->result. Implementation mostly taken over from "novem". If TCL_NO_DEPRECATED is not defined, nothing changes. --- generic/tclBasic.c | 2 +- generic/tclCmdAH.c | 3 ++- generic/tclDecls.h | 16 +++++++++++++++ generic/tclIO.c | 41 -------------------------------------- generic/tclInt.h | 2 ++ generic/tclResult.c | 55 +++++++++++++++++++++++++++++++++++++++------------ generic/tclStubInit.c | 41 ++++++++++++++++++++++++++++++++++++-- generic/tclTest.c | 20 ++++++++----------- generic/tclUtil.c | 17 ++++++++++++---- tests/case.test | 5 +++++ tests/result.test | 4 ++-- tools/configure | 2 +- 12 files changed, 131 insertions(+), 77 deletions(-) diff --git a/generic/tclBasic.c b/generic/tclBasic.c index 37dd699..b4d0a7b 100644 --- a/generic/tclBasic.c +++ b/generic/tclBasic.c @@ -203,7 +203,7 @@ static const CmdInfo builtInCmds[] = { {"append", Tcl_AppendObjCmd, TclCompileAppendCmd, NULL, CMD_IS_SAFE}, {"apply", Tcl_ApplyObjCmd, NULL, TclNRApplyObjCmd, CMD_IS_SAFE}, {"break", Tcl_BreakObjCmd, TclCompileBreakCmd, NULL, CMD_IS_SAFE}, -#ifndef EXCLUDE_OBSOLETE_COMMANDS +#ifndef TCL_NO_DEPRECATED {"case", Tcl_CaseObjCmd, NULL, NULL, CMD_IS_SAFE}, #endif {"catch", Tcl_CatchObjCmd, TclCompileCatchCmd, TclNRCatchObjCmd, CMD_IS_SAFE}, diff --git a/generic/tclCmdAH.c b/generic/tclCmdAH.c index 4c299f8..9c6f6a1 100644 --- a/generic/tclCmdAH.c +++ b/generic/tclCmdAH.c @@ -149,7 +149,7 @@ Tcl_BreakObjCmd( * *---------------------------------------------------------------------- */ - +#ifndef TCL_NO_DEPRECATED /* ARGSUSED */ int Tcl_CaseObjCmd( @@ -267,6 +267,7 @@ Tcl_CaseObjCmd( return TCL_OK; } +#endif /* !TCL_NO_DEPRECATED */ /* *---------------------------------------------------------------------- diff --git a/generic/tclDecls.h b/generic/tclDecls.h index 504af18..0dbf345 100644 --- a/generic/tclDecls.h +++ b/generic/tclDecls.h @@ -3869,6 +3869,22 @@ extern const TclStubs *tclStubsPtr; #undef Tcl_AddObjErrorInfo #define Tcl_AddObjErrorInfo(interp, message, length) \ Tcl_AppendObjToErrorInfo(interp, Tcl_NewStringObj(message, length)) +#ifdef TCL_NO_DEPRECATED +#undef Tcl_SetResult +#define Tcl_SetResult(interp, result, freeProc) \ + do { \ + char *__result = result; \ + Tcl_FreeProc *__freeProc = freeProc; \ + Tcl_SetObjResult(interp, Tcl_NewStringObj(__result, -1)); \ + if (__result != NULL && __freeProc != NULL && __freeProc != TCL_VOLATILE) { \ + if (__freeProc == TCL_DYNAMIC) { \ + ckfree(__result); \ + } else { \ + (*__freeProc)(__result); \ + } \ + } \ + } while(0) +#endif /* TCL_NO_DEPRECATED */ #if defined(USE_TCL_STUBS) && !defined(USE_TCL_STUB_PROCS) # if defined(__CYGWIN__) && defined(TCL_WIDE_INT_IS_LONG) diff --git a/generic/tclIO.c b/generic/tclIO.c index 5c39e19..506e6d5 100644 --- a/generic/tclIO.c +++ b/generic/tclIO.c @@ -7127,47 +7127,6 @@ Tcl_Tell( /* *--------------------------------------------------------------------------- * - * Tcl_SeekOld, Tcl_TellOld -- - * - * Backward-compatibility versions of the seek/tell interface that do not - * support 64-bit offsets. This interface is not documented or expected - * to be supported indefinitely. - * - * Results: - * As for Tcl_Seek and Tcl_Tell respectively, except truncated to - * whatever value will fit in an 'int'. - * - * Side effects: - * As for Tcl_Seek and Tcl_Tell respectively. - * - *--------------------------------------------------------------------------- - */ - -int -Tcl_SeekOld( - Tcl_Channel chan, /* The channel on which to seek. */ - int offset, /* Offset to seek to. */ - int mode) /* Relative to which location to seek? */ -{ - Tcl_WideInt wOffset, wResult; - - wOffset = Tcl_LongAsWide((long) offset); - wResult = Tcl_Seek(chan, wOffset, mode); - return (int) Tcl_WideAsLong(wResult); -} - -int -Tcl_TellOld( - Tcl_Channel chan) /* The channel to return pos for. */ -{ - Tcl_WideInt wResult = Tcl_Tell(chan); - - return (int) Tcl_WideAsLong(wResult); -} - -/* - *--------------------------------------------------------------------------- - * * Tcl_TruncateChannel -- * * Truncate a channel to the given length. diff --git a/generic/tclInt.h b/generic/tclInt.h index 8516385..5074378 100644 --- a/generic/tclInt.h +++ b/generic/tclInt.h @@ -3219,9 +3219,11 @@ MODULE_SCOPE Tcl_Command TclInitBinaryCmd(Tcl_Interp *interp); MODULE_SCOPE int Tcl_BreakObjCmd(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *const objv[]); +#ifndef TCL_NO_DEPRECATED MODULE_SCOPE int Tcl_CaseObjCmd(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *const objv[]); +#endif MODULE_SCOPE int Tcl_CatchObjCmd(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *const objv[]); diff --git a/generic/tclResult.c b/generic/tclResult.c index 9d0714c..6346636 100644 --- a/generic/tclResult.c +++ b/generic/tclResult.c @@ -27,7 +27,9 @@ enum returnKeys { static Tcl_Obj ** GetKeys(void); static void ReleaseKeys(ClientData clientData); static void ResetObjResult(Interp *iPtr); +#ifndef TCL_NO_DEPRECATED static void SetupAppendBuffer(Interp *iPtr, int newSpace); +#endif /* !TCL_NO_DEPRECATED */ /* * This structure is used to take a snapshot of the interpreter state in @@ -35,7 +37,7 @@ static void SetupAppendBuffer(Interp *iPtr, int newSpace); * then back up to the result or the error that was previously in progress. */ -typedef struct InterpState { +typedef struct { int status; /* return code status */ int flags; /* Each remaining field saves the */ int returnLevel; /* corresponding field of the Interp */ @@ -407,6 +409,7 @@ Tcl_DiscardResult( *---------------------------------------------------------------------- */ +#ifndef TCL_NO_DEPRECATED void Tcl_SetResult( Tcl_Interp *interp, /* Interpreter with which to associate the @@ -461,6 +464,7 @@ Tcl_SetResult( ResetObjResult(iPtr); } +#endif /* !TCL_NO_DEPRECATED */ /* *---------------------------------------------------------------------- @@ -483,18 +487,21 @@ const char * Tcl_GetStringResult( register Tcl_Interp *interp)/* Interpreter whose result to return. */ { + Interp *iPtr = (Interp *) interp; +#ifdef TCL_NO_DEPRECATED + return Tcl_GetString(iPtr->objResultPtr); +#else /* * If the string result is empty, move the object result to the string * result, then reset the object result. */ - Interp *iPtr = (Interp *) interp; - if (*(iPtr->result) == 0) { Tcl_SetResult(interp, TclGetString(Tcl_GetObjResult(interp)), TCL_VOLATILE); } return iPtr->result; +#endif } /* @@ -536,6 +543,7 @@ Tcl_SetObjResult( TclDecrRefCount(oldObjResult); +#ifndef TCL_NO_DEPRECATED /* * Reset the string result since we just set the result object. */ @@ -550,6 +558,7 @@ Tcl_SetObjResult( } iPtr->result = iPtr->resultSpace; iPtr->resultSpace[0] = 0; +#endif } /* @@ -578,6 +587,7 @@ Tcl_GetObjResult( Tcl_Interp *interp) /* Interpreter whose result to return. */ { register Interp *iPtr = (Interp *) interp; +#ifndef TCL_NO_DEPRECATED Tcl_Obj *objResultPtr; int length; @@ -604,6 +614,7 @@ Tcl_GetObjResult( iPtr->result = iPtr->resultSpace; iPtr->result[0] = 0; } +#endif /* !TCL_NO_DEPRECATED */ return iPtr->objResultPtr; } @@ -722,6 +733,21 @@ Tcl_AppendElement( * to result. */ { Interp *iPtr = (Interp *) interp; +#ifdef TCL_NO_DEPRECATED + Tcl_Obj *elementPtr = Tcl_NewStringObj(element, -1); + Tcl_Obj *listPtr = Tcl_NewListObj(1, &elementPtr); + const char *bytes; + + if (Tcl_IsShared(iPtr->objResultPtr)) { + Tcl_SetObjResult(interp, Tcl_DuplicateObj(iPtr->objResultPtr)); + } + bytes = TclGetString(iPtr->objResultPtr); + if (TclNeedSpace(bytes, bytes+iPtr->objResultPtr->length)) { + Tcl_AppendToObj(iPtr->objResultPtr, " ", 1); + } + Tcl_AppendObjToObj(iPtr->objResultPtr, listPtr); + Tcl_DecrRefCount(listPtr); +#else char *dst; int size; int flags; @@ -765,6 +791,7 @@ Tcl_AppendElement( flags |= TCL_DONT_QUOTE_HASH; } iPtr->appendUsed += Tcl_ConvertElement(element, dst, flags); +#endif /* !TCL_NO_DEPRECATED */ } /* @@ -786,6 +813,7 @@ Tcl_AppendElement( *---------------------------------------------------------------------- */ +#ifndef TCL_NO_DEPRECATED static void SetupAppendBuffer( Interp *iPtr, /* Interpreter whose result is being set up. */ @@ -846,6 +874,7 @@ SetupAppendBuffer( Tcl_FreeResult((Tcl_Interp *) iPtr); iPtr->result = iPtr->appendResult; } +#endif /* !TCL_NO_DEPRECATED */ /* *---------------------------------------------------------------------- @@ -875,6 +904,7 @@ Tcl_FreeResult( { register Interp *iPtr = (Interp *) interp; +#ifndef TCL_NO_DEPRECATED if (iPtr->freeProc != NULL) { if (iPtr->freeProc == TCL_DYNAMIC) { ckfree(iPtr->result); @@ -884,6 +914,7 @@ Tcl_FreeResult( iPtr->freeProc = 0; } +#endif /* !TCL_NO_DEPRECATED */ ResetObjResult(iPtr); } @@ -913,6 +944,7 @@ Tcl_ResetResult( register Interp *iPtr = (Interp *) interp; ResetObjResult(iPtr); +#ifndef TCL_NO_DEPRECATED if (iPtr->freeProc != NULL) { if (iPtr->freeProc == TCL_DYNAMIC) { ckfree(iPtr->result); @@ -923,6 +955,7 @@ Tcl_ResetResult( } iPtr->result = iPtr->resultSpace; iPtr->resultSpace[0] = 0; +#endif /* !TCL_NO_DEPRECATED */ if (iPtr->errorCode) { /* Legacy support */ if (iPtr->flags & ERR_LEGACY_COPY) { @@ -1276,10 +1309,8 @@ TclProcessReturn( Tcl_DictObjGet(NULL, iPtr->returnOpts, keys[KEY_ERRORINFO], &valuePtr); if (valuePtr != NULL) { - int infoLen; - - (void) TclGetStringFromObj(valuePtr, &infoLen); - if (infoLen) { + (void) TclGetString(valuePtr); + if (valuePtr->length) { iPtr->errorInfo = valuePtr; Tcl_IncrRefCount(iPtr->errorInfo); iPtr->flags |= ERR_ALREADY_LOGGED; @@ -1382,13 +1413,11 @@ TclMergeReturnOptions( Tcl_Obj **keys = GetKeys(); for (; objc > 1; objv += 2, objc -= 2) { - int optLen; - const char *opt = TclGetStringFromObj(objv[0], &optLen); - int compareLen; - const char *compare = - TclGetStringFromObj(keys[KEY_OPTIONS], &compareLen); + const char *opt = TclGetString(objv[0]); + const char *compare = TclGetString(keys[KEY_OPTIONS]); - if ((optLen == compareLen) && (memcmp(opt, compare, optLen) == 0)) { + if ((objv[0]->length == keys[KEY_OPTIONS]->length) + && (memcmp(opt, compare, objv[0]->length) == 0)) { Tcl_DictSearch search; int done = 0; Tcl_Obj *keyPtr; diff --git a/generic/tclStubInit.c b/generic/tclStubInit.c index 23da6dc..561b9dd 100644 --- a/generic/tclStubInit.c +++ b/generic/tclStubInit.c @@ -290,10 +290,47 @@ static int formatInt(char *buffer, int n){ #endif #else /* UNIX and MAC */ -# define TclpLocaltime_unix TclpLocaltime -# define TclpGmtime_unix TclpGmtime +# ifdef TCL_NO_DEPRECATED +# define TclpLocaltime_unix 0 +# define TclpGmtime_unix 0 +# else +# define TclpLocaltime_unix TclpLocaltime +# define TclpGmtime_unix TclpGmtime +# endif #endif +#ifdef TCL_NO_DEPRECATED +# define Tcl_SeekOld 0 +# define Tcl_TellOld 0 +# undef Tcl_SetResult +# define Tcl_SetResult 0 +#else /* TCL_NO_DEPRECATED */ +# define Tcl_SeekOld seekOld +# define Tcl_TellOld tellOld + +static int +seekOld( + Tcl_Channel chan, /* The channel on which to seek. */ + int offset, /* Offset to seek to. */ + int mode) /* Relative to which location to seek? */ +{ + Tcl_WideInt wOffset, wResult; + + wOffset = Tcl_LongAsWide((long) offset); + wResult = Tcl_Seek(chan, wOffset, mode); + return (int) Tcl_WideAsLong(wResult); +} + +static int +tellOld( + Tcl_Channel chan) /* The channel to return pos for. */ +{ + Tcl_WideInt wResult = Tcl_Tell(chan); + + return (int) Tcl_WideAsLong(wResult); +} +#endif /* !TCL_NO_DEPRECATED */ + /* * WARNING: The contents of this file is automatically generated by the * tools/genStubs.tcl script. Any modifications to the function declarations diff --git a/generic/tclTest.c b/generic/tclTest.c index faecbc6..a9dc1ca 100644 --- a/generic/tclTest.c +++ b/generic/tclTest.c @@ -290,12 +290,14 @@ static int TestlinkCmd(ClientData dummy, static int TestlocaleCmd(ClientData dummy, Tcl_Interp *interp, int objc, Tcl_Obj *const objv[]); +#ifndef TCL_NO_DEPRECATED static int TestMathFunc(ClientData clientData, Tcl_Interp *interp, Tcl_Value *args, Tcl_Value *resultPtr); static int TestMathFunc2(ClientData clientData, Tcl_Interp *interp, Tcl_Value *args, Tcl_Value *resultPtr); +#endif /* TCL_NO_DEPRECATED */ static int TestmainthreadCmd(ClientData dummy, Tcl_Interp *interp, int argc, const char **argv); static int TestsetmainloopCmd(ClientData dummy, @@ -329,12 +331,10 @@ static int TestreturnObjCmd(ClientData dummy, Tcl_Obj *const objv[]); static void TestregexpXflags(const char *string, int length, int *cflagsPtr, int *eflagsPtr); -#ifndef TCL_NO_DEPRECATED static int TestsaveresultCmd(ClientData dummy, Tcl_Interp *interp, int objc, Tcl_Obj *const objv[]); static void TestsaveresultFree(char *blockPtr); -#endif /* TCL_NO_DEPRECATED */ static int TestsetassocdataCmd(ClientData dummy, Tcl_Interp *interp, int argc, const char **argv); static int TestsetCmd(ClientData dummy, @@ -555,7 +555,7 @@ Tcltest_Init( } /* TIP #268: Full patchlevel instead of just major.minor */ - if (Tcl_PkgProvide(interp, "Tcltest", TCL_PATCH_LEVEL) == TCL_ERROR) { + if (Tcl_PkgProvideEx(interp, "Tcltest", TCL_PATCH_LEVEL, NULL) == TCL_ERROR) { return TCL_ERROR; } @@ -658,10 +658,8 @@ Tcltest_Init( NULL, NULL); Tcl_CreateObjCommand(interp, "testreturn", TestreturnObjCmd, NULL, NULL); -#ifndef TCL_NO_DEPRECATED Tcl_CreateObjCommand(interp, "testsaveresult", TestsaveresultCmd, NULL, NULL); -#endif /* TCL_NO_DEPRECATED */ Tcl_CreateCommand(interp, "testsetassocdata", TestsetassocdataCmd, NULL, NULL); Tcl_CreateCommand(interp, "testsetnoerr", TestsetCmd, @@ -3341,6 +3339,7 @@ TestlocaleCmd( */ /* ARGSUSED */ +#ifndef TCL_NO_DEPRECATED static int TestMathFunc( ClientData clientData, /* Integer value to return. */ @@ -3460,6 +3459,7 @@ TestMathFunc2( } return result; } +#endif /* TCL_NO_DEPRECATED */ /* *---------------------------------------------------------------------- @@ -5144,7 +5144,6 @@ Testset2Cmd( } } -#ifndef TCL_NO_DEPRECATED /* *---------------------------------------------------------------------- * @@ -5197,6 +5196,7 @@ TestsaveresultCmd( return TCL_ERROR; } + freeCount = 0; objPtr = NULL; /* Lint. */ switch ((enum options) index) { case RESULT_SMALL: @@ -5221,7 +5221,6 @@ TestsaveresultCmd( break; } - freeCount = 0; Tcl_SaveResult(interp, &state); if (((enum options) index) == RESULT_OBJECT) { @@ -5239,11 +5238,9 @@ TestsaveresultCmd( switch ((enum options) index) { case RESULT_DYNAMIC: { - int present = iPtr->freeProc == TestsaveresultFree; - int called = freeCount; + int presentOrFreed = (iPtr->freeProc == TestsaveresultFree) ^ freeCount; - Tcl_AppendElement(interp, called ? "called" : "notCalled"); - Tcl_AppendElement(interp, present ? "present" : "missing"); + Tcl_AppendElement(interp, presentOrFreed ? "presentOrFreed" : "missingOrLeak"); break; } case RESULT_OBJECT: @@ -5278,7 +5275,6 @@ TestsaveresultFree( { freeCount++; } -#endif /* TCL_NO_DEPRECATED */ /* *---------------------------------------------------------------------- diff --git a/generic/tclUtil.c b/generic/tclUtil.c index 531f386..ba709cc 100644 --- a/generic/tclUtil.c +++ b/generic/tclUtil.c @@ -2894,7 +2894,6 @@ Tcl_DStringResult( Tcl_DString *dsPtr) /* Dynamic string that is to become the * result of interp. */ { - Tcl_ResetResult(interp); Tcl_SetObjResult(interp, TclDStringToObj(dsPtr)); } @@ -2924,6 +2923,14 @@ Tcl_DStringGetResult( Tcl_DString *dsPtr) /* Dynamic string that is to become the result * of interp. */ { +#ifdef TCL_NO_DEPRECATED + Tcl_Obj *obj = Tcl_GetObjResult(interp); + const char *bytes = TclGetString(obj); + + Tcl_DStringFree(dsPtr); + Tcl_DStringAppend(dsPtr, bytes, obj->length); + Tcl_ResetResult(interp); +#else Interp *iPtr = (Interp *) interp; if (dsPtr->string != dsPtr->staticSpace) { @@ -2932,7 +2939,7 @@ Tcl_DStringGetResult( /* * Do more efficient transfer when we know the result is a Tcl_Obj. When - * there's no st`ring result, we only have to deal with two cases: + * there's no string result, we only have to deal with two cases: * * 1. When the string rep is the empty string, when we don't copy but * instead use the staticSpace in the DString to hold an empty string. @@ -2995,6 +3002,7 @@ Tcl_DStringGetResult( iPtr->result = iPtr->resultSpace; iPtr->resultSpace[0] = 0; +#endif /* !TCL_NO_DEPRECATED */ } /* @@ -3576,7 +3584,7 @@ TclGetIntForIndex( int *indexPtr) /* Location filled in with an integer * representing an index. */ { - int length; + size_t length; char *opPtr; const char *bytes; @@ -3594,7 +3602,8 @@ TclGetIntForIndex( return TCL_OK; } - bytes = TclGetStringFromObj(objPtr, &length); + bytes = TclGetString(objPtr); + length = objPtr->length; /* * Leading whitespace is acceptable in an index. diff --git a/tests/case.test b/tests/case.test index 6d63cea..d7558a9 100644 --- a/tests/case.test +++ b/tests/case.test @@ -11,6 +11,11 @@ # See the file "license.terms" for information on usage and redistribution # of this file, and for a DISCLAIMER OF ALL WARRANTIES. +if {![llength [info commands case]]} { + # No "case" command? So no need to test + return +} + if {[lsearch [namespace children] ::tcltest] == -1} { package require tcltest namespace import -force ::tcltest::* diff --git a/tests/result.test b/tests/result.test index 9e8a66b..859e546 100644 --- a/tests/result.test +++ b/tests/result.test @@ -31,7 +31,7 @@ test result-1.2 {Tcl_SaveInterpResult} {testsaveresult} { } {append result} test result-1.3 {Tcl_SaveInterpResult} {testsaveresult} { testsaveresult dynamic {set x 42} 0 -} {dynamic result notCalled present} +} {dynamic result presentOrFreed} test result-1.4 {Tcl_SaveInterpResult} {testsaveresult} { testsaveresult object {set x 42} 0 } {object result same} @@ -43,7 +43,7 @@ test result-1.6 {Tcl_SaveInterpResult} {testsaveresult} { } {42} test result-1.7 {Tcl_SaveInterpResult} {testsaveresult} { testsaveresult dynamic {set x 42} 1 -} {42 called missing} +} {42 presentOrFreed} test result-1.8 {Tcl_SaveInterpResult} {testsaveresult} { testsaveresult object {set x 42} 1 } {42 different} diff --git a/tools/configure b/tools/configure index 7c4d3db..5903cc8 100755 --- a/tools/configure +++ b/tools/configure @@ -1681,7 +1681,7 @@ ac_compiler_gnu=$ac_cv_c_compiler_gnu # not, assume that its top-level directory is a sibling of ours. #-------------------------------------------------------------------- -DEF_VER=8.6 +DEF_VER=8.7 # Check whether --with-tcl was given. -- cgit v0.12 From 68275b03de1af80b960d68ceaa5199c33ede1b13 Mon Sep 17 00:00:00 2001 From: "jan.nijtmans" Date: Fri, 27 Jan 2017 14:31:12 +0000 Subject: Some code cleanup: More internal use of size_t, less type casts (because of this). No functional changes. --- generic/tclLink.c | 66 ++++++++++++++++++++++--------------------------------- generic/tclObj.c | 17 +++++++------- generic/tclProc.c | 10 ++++----- 3 files changed, 40 insertions(+), 53 deletions(-) diff --git a/generic/tclLink.c b/generic/tclLink.c index 2ead6df..46471f5 100644 --- a/generic/tclLink.c +++ b/generic/tclLink.c @@ -67,10 +67,8 @@ typedef struct Link { static char * LinkTraceProc(ClientData clientData,Tcl_Interp *interp, const char *name1, const char *name2, int flags); static Tcl_Obj * ObjValue(Link *linkPtr); -static int GetInvalidIntFromObj(Tcl_Obj *objPtr, - int *intPtr); -static int GetInvalidDoubleFromObj(Tcl_Obj *objPtr, - double *doublePtr); +static int GetInvalidIntFromObj(Tcl_Obj *objPtr, int *intPtr); +static int GetInvalidDoubleFromObj(Tcl_Obj *objPtr, double *doublePtr); /* * Convenience macro for accessing the value of the C variable pointed to by a @@ -263,7 +261,8 @@ LinkTraceProc( int flags) /* Miscellaneous additional information. */ { Link *linkPtr = clientData; - int changed, valueLength; + int changed; + size_t valueLength; const char *value; char **pp; Tcl_Obj *valueObj; @@ -384,8 +383,7 @@ LinkTraceProc( case TCL_LINK_INT: if (Tcl_GetIntFromObj(NULL, valueObj, &linkPtr->lastValue.i) != TCL_OK) { - if (GetInvalidIntFromObj(valueObj, &linkPtr->lastValue.i) - != TCL_OK) { + if (GetInvalidIntFromObj(valueObj, &linkPtr->lastValue.i) != TCL_OK) { Tcl_ObjSetVar2(interp, linkPtr->varName, NULL, ObjValue(linkPtr), TCL_GLOBAL_ONLY); return (char *) "variable must have integer value"; @@ -397,8 +395,7 @@ LinkTraceProc( case TCL_LINK_WIDE_INT: if (Tcl_GetWideIntFromObj(NULL, valueObj, &linkPtr->lastValue.w) != TCL_OK) { - if (GetInvalidIntFromObj(valueObj, &valueInt) - != TCL_OK) { + if (GetInvalidIntFromObj(valueObj, &valueInt) != TCL_OK) { Tcl_ObjSetVar2(interp, linkPtr->varName, NULL, ObjValue(linkPtr), TCL_GLOBAL_ONLY); return (char *) "variable must have integer value"; @@ -441,8 +438,7 @@ LinkTraceProc( case TCL_LINK_CHAR: if (Tcl_GetIntFromObj(NULL, valueObj, &valueInt) != TCL_OK || valueInt < SCHAR_MIN || valueInt > SCHAR_MAX) { - if (GetInvalidIntFromObj(valueObj, &valueInt) - != TCL_OK) { + if (GetInvalidIntFromObj(valueObj, &valueInt) != TCL_OK) { Tcl_ObjSetVar2(interp, linkPtr->varName, NULL, ObjValue(linkPtr), TCL_GLOBAL_ONLY); return (char *) "variable must have char value"; @@ -455,8 +451,7 @@ LinkTraceProc( case TCL_LINK_UCHAR: if (Tcl_GetIntFromObj(NULL, valueObj, &valueInt) != TCL_OK || valueInt < 0 || valueInt > UCHAR_MAX) { - if (GetInvalidIntFromObj(valueObj, &valueInt) - != TCL_OK) { + if (GetInvalidIntFromObj(valueObj, &valueInt) != TCL_OK) { Tcl_ObjSetVar2(interp, linkPtr->varName, NULL, ObjValue(linkPtr), TCL_GLOBAL_ONLY); return (char *) "variable must have unsigned char value"; @@ -469,8 +464,7 @@ LinkTraceProc( case TCL_LINK_SHORT: if (Tcl_GetIntFromObj(NULL, valueObj, &valueInt) != TCL_OK || valueInt < SHRT_MIN || valueInt > SHRT_MAX) { - if (GetInvalidIntFromObj(valueObj, &valueInt) - != TCL_OK) { + if (GetInvalidIntFromObj(valueObj, &valueInt) != TCL_OK) { Tcl_ObjSetVar2(interp, linkPtr->varName, NULL, ObjValue(linkPtr), TCL_GLOBAL_ONLY); return (char *) "variable must have short value"; @@ -483,8 +477,7 @@ LinkTraceProc( case TCL_LINK_USHORT: if (Tcl_GetIntFromObj(NULL, valueObj, &valueInt) != TCL_OK || valueInt < 0 || valueInt > USHRT_MAX) { - if (GetInvalidIntFromObj(valueObj, &valueInt) - != TCL_OK) { + if (GetInvalidIntFromObj(valueObj, &valueInt) != TCL_OK) { Tcl_ObjSetVar2(interp, linkPtr->varName, NULL, ObjValue(linkPtr), TCL_GLOBAL_ONLY); return (char *) "variable must have unsigned short value"; @@ -497,8 +490,7 @@ LinkTraceProc( case TCL_LINK_UINT: if (Tcl_GetWideIntFromObj(NULL, valueObj, &valueWide) != TCL_OK || valueWide < 0 || valueWide > UINT_MAX) { - if (GetInvalidIntFromObj(valueObj, &valueInt) - != TCL_OK) { + if (GetInvalidIntFromObj(valueObj, &valueInt) != TCL_OK) { Tcl_ObjSetVar2(interp, linkPtr->varName, NULL, ObjValue(linkPtr), TCL_GLOBAL_ONLY); return (char *) "variable must have unsigned int value"; @@ -513,8 +505,7 @@ LinkTraceProc( case TCL_LINK_LONG: if (Tcl_GetWideIntFromObj(NULL, valueObj, &valueWide) != TCL_OK || valueWide < LONG_MIN || valueWide > LONG_MAX) { - if (GetInvalidIntFromObj(valueObj, &valueInt) - != TCL_OK) { + if (GetInvalidIntFromObj(valueObj, &valueInt) != TCL_OK) { Tcl_ObjSetVar2(interp, linkPtr->varName, NULL, ObjValue(linkPtr), TCL_GLOBAL_ONLY); return (char *) "variable must have long value"; @@ -529,8 +520,7 @@ LinkTraceProc( case TCL_LINK_ULONG: if (Tcl_GetWideIntFromObj(NULL, valueObj, &valueWide) != TCL_OK || valueWide < 0 || (Tcl_WideUInt) valueWide > ULONG_MAX) { - if (GetInvalidIntFromObj(valueObj, &valueInt) - != TCL_OK) { + if (GetInvalidIntFromObj(valueObj, &valueInt) != TCL_OK) { Tcl_ObjSetVar2(interp, linkPtr->varName, NULL, ObjValue(linkPtr), TCL_GLOBAL_ONLY); return (char *) "variable must have unsigned long value"; @@ -547,8 +537,7 @@ LinkTraceProc( * FIXME: represent as a bignum. */ if (Tcl_GetWideIntFromObj(NULL, valueObj, &valueWide) != TCL_OK) { - if (GetInvalidIntFromObj(valueObj, &valueInt) - != TCL_OK) { + if (GetInvalidIntFromObj(valueObj, &valueInt) != TCL_OK) { Tcl_ObjSetVar2(interp, linkPtr->varName, NULL, ObjValue(linkPtr), TCL_GLOBAL_ONLY); return (char *) "variable must have unsigned wide int value"; @@ -575,12 +564,12 @@ LinkTraceProc( break; case TCL_LINK_STRING: - value = TclGetStringFromObj(valueObj, &valueLength); - valueLength++; + value = TclGetString(valueObj); + valueLength = valueObj->length + 1; pp = (char **) linkPtr->addr; *pp = ckrealloc(*pp, valueLength); - memcpy(*pp, value, (unsigned) valueLength); + memcpy(*pp, value, valueLength); break; default: @@ -688,17 +677,16 @@ static Tcl_ObjType invalidRealType = { static int SetInvalidRealFromAny(Tcl_Interp *interp, Tcl_Obj *objPtr) { - int length; const char *str; const char *endPtr; - str = TclGetStringFromObj(objPtr, &length); - if ((length == 1) && (str[0] == '.')){ + str = TclGetString(objPtr); + if ((objPtr->length == 1) && (str[0] == '.')){ objPtr->typePtr = &invalidRealType; objPtr->internalRep.doubleValue = 0.0; return TCL_OK; } - if (TclParseNumber(NULL, objPtr, NULL, str, length, &endPtr, + if (TclParseNumber(NULL, objPtr, NULL, str, objPtr->length, &endPtr, TCL_PARSE_DECIMAL_ONLY) == TCL_OK) { /* If number is followed by [eE][+-]?, then it is an invalid * double, but it could be the start of a valid double. */ @@ -708,7 +696,7 @@ SetInvalidRealFromAny(Tcl_Interp *interp, Tcl_Obj *objPtr) { if (*endPtr == 0) { double doubleValue = 0.0; Tcl_GetDoubleFromObj(NULL, objPtr, &doubleValue); - if (objPtr->typePtr->freeIntRepProc) objPtr->typePtr->freeIntRepProc(objPtr); + TclFreeIntRep(objPtr); objPtr->typePtr = &invalidRealType; objPtr->internalRep.doubleValue = doubleValue; return TCL_OK; @@ -726,17 +714,15 @@ SetInvalidRealFromAny(Tcl_Interp *interp, Tcl_Obj *objPtr) { * (upperand lowercase). See bug [39f6304c2e]. */ int -GetInvalidIntFromObj(Tcl_Obj *objPtr, - int *intPtr) +GetInvalidIntFromObj(Tcl_Obj *objPtr, int *intPtr) { - int length; - const char *str = TclGetStringFromObj(objPtr, &length); + const char *str = TclGetString(objPtr); - if ((length == 1) && strchr("+-", str[0])) { + if ((objPtr->length == 1) && strchr("+-", str[0])) { *intPtr = (str[0] == '+'); return TCL_OK; - } else if ((length == 0) || - ((length == 2) && (str[0] == '0') && strchr("xXbBoO", str[1]))) { + } else if ((objPtr->length == 0) || + ((objPtr->length == 2) && (str[0] == '0') && strchr("xXbBoO", str[1]))) { *intPtr = 0; return TCL_OK; } diff --git a/generic/tclObj.c b/generic/tclObj.c index df900ce..d0f7480 100644 --- a/generic/tclObj.c +++ b/generic/tclObj.c @@ -2004,9 +2004,10 @@ static int ParseBoolean( register Tcl_Obj *objPtr) /* The object to parse/convert. */ { - int i, length, newBool; + int newBool; char lowerCase[6]; - const char *str = TclGetStringFromObj(objPtr, &length); + const char *str = TclGetString(objPtr); + size_t i, length = objPtr->length; if ((length == 0) || (length > 5)) { /* @@ -2058,25 +2059,25 @@ ParseBoolean( /* * Checking the 'y' is redundant, but makes the code clearer. */ - if (strncmp(lowerCase, "yes", (size_t) length) == 0) { + if (strncmp(lowerCase, "yes", length) == 0) { newBool = 1; goto goodBoolean; } return TCL_ERROR; case 'n': - if (strncmp(lowerCase, "no", (size_t) length) == 0) { + if (strncmp(lowerCase, "no", length) == 0) { newBool = 0; goto goodBoolean; } return TCL_ERROR; case 't': - if (strncmp(lowerCase, "true", (size_t) length) == 0) { + if (strncmp(lowerCase, "true", length) == 0) { newBool = 1; goto goodBoolean; } return TCL_ERROR; case 'f': - if (strncmp(lowerCase, "false", (size_t) length) == 0) { + if (strncmp(lowerCase, "false", length) == 0) { newBool = 0; goto goodBoolean; } @@ -2085,10 +2086,10 @@ ParseBoolean( if (length < 2) { return TCL_ERROR; } - if (strncmp(lowerCase, "on", (size_t) length) == 0) { + if (strncmp(lowerCase, "on", length) == 0) { newBool = 1; goto goodBoolean; - } else if (strncmp(lowerCase, "off", (size_t) length) == 0) { + } else if (strncmp(lowerCase, "off", length) == 0) { newBool = 0; goto goodBoolean; } diff --git a/generic/tclProc.c b/generic/tclProc.c index bed520a..373192c 100644 --- a/generic/tclProc.c +++ b/generic/tclProc.c @@ -500,7 +500,8 @@ TclCreateProc( } for (i = 0; i < numArgs; i++) { - int fieldCount, nameLength, valueLength; + int fieldCount, nameLength; + size_t valueLength; const char **fieldValues; /* @@ -602,12 +603,11 @@ TclCreateProc( */ if (localPtr->defValuePtr != NULL) { - int tmpLength; - const char *tmpPtr = TclGetStringFromObj(localPtr->defValuePtr, - &tmpLength); + const char *tmpPtr = TclGetString(localPtr->defValuePtr); + size_t tmpLength = localPtr->defValuePtr->length; if ((valueLength != tmpLength) || - strncmp(fieldValues[1], tmpPtr, (size_t) tmpLength)) { + strncmp(fieldValues[1], tmpPtr, tmpLength)) { Tcl_SetObjResult(interp, Tcl_ObjPrintf( "procedure \"%s\": formal parameter \"%s\" has " "default value inconsistent with precompiled body", -- cgit v0.12 From 4b357897d532c34fb10a853da41bbd7d273e729f Mon Sep 17 00:00:00 2001 From: ashok Date: Sat, 28 Jan 2017 06:38:22 +0000 Subject: Added assoc, ftype and move as auto_execok shell built-ins on Windows. --- library/init.tcl | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/library/init.tcl b/library/init.tcl index 544ea77..5a9e87c 100644 --- a/library/init.tcl +++ b/library/init.tcl @@ -636,8 +636,9 @@ proc auto_execok name { } set auto_execs($name) "" - set shellBuiltins [list cls copy date del dir echo erase md mkdir \ - mklink rd ren rename rmdir start time type ver vol] + set shellBuiltins [list assoc cls copy date del dir echo erase ftype \ + md mkdir mklink move rd ren rename rmdir start \ + time type ver vol] if {[info exists env(PATHEXT)]} { # Add an initial ; to have the {} extension check first. set execExtensions [split ";$env(PATHEXT)" ";"] -- cgit v0.12 From e7e8174dbaeced18b08cb902666c2a04b475a171 Mon Sep 17 00:00:00 2001 From: "jan.nijtmans" Date: Tue, 31 Jan 2017 13:15:40 +0000 Subject: Update documentation on recent changes in Tcl_LinkVar. Don't use TCL_NO_DEPRECATED for disabling tests-cases: Those were not deprecated in 8.6 yet. Minor code clean-up. No functional changes. --- doc/LinkVar.3 | 48 ++++++++++++++++++++++++++++++++++++------------ generic/tclLink.c | 38 ++++++++++++++++++++------------------ generic/tclObj.c | 12 ++++++------ generic/tclTest.c | 14 +------------- 4 files changed, 63 insertions(+), 49 deletions(-) diff --git a/doc/LinkVar.3 b/doc/LinkVar.3 index c64720b..0b746b0 100644 --- a/doc/LinkVar.3 +++ b/doc/LinkVar.3 @@ -61,7 +61,9 @@ The C variable is of type \fBint\fR. Any value written into the Tcl variable must have a proper integer form acceptable to \fBTcl_GetIntFromObj\fR; attempts to write non-integer values into \fIvarName\fR will be rejected with -Tcl errors. +Tcl errors. Incomplete integer representations (like the empty +string, '+', '-' or the hex/octal/binary prefix) are accepted +as if they are valid too. .TP \fBTCL_LINK_UINT\fR The C variable is of type \fBunsigned int\fR. @@ -69,14 +71,18 @@ Any value written into the Tcl variable must have a proper unsigned integer form acceptable to \fBTcl_GetWideIntFromObj\fR and in the platform's defined range for the \fBunsigned int\fR type; attempts to write non-integer values (or values outside the range) into -\fIvarName\fR will be rejected with Tcl errors. +\fIvarName\fR will be rejected with Tcl errors. Incomplete integer +representations (like the empty string, '+', '-' or the hex/octal/binary +prefix) are accepted as if they are valid too. .TP \fBTCL_LINK_CHAR\fR The C variable is of type \fBchar\fR. Any value written into the Tcl variable must have a proper integer form acceptable to \fBTcl_GetIntFromObj\fR and be in the range of the \fBchar\fR datatype; attempts to write non-integer or out-of-range -values into \fIvarName\fR will be rejected with Tcl errors. +values into \fIvarName\fR will be rejected with Tcl errors. Incomplete +integer representations (like the empty string, '+', '-' or the +hex/octal/binary prefix) are accepted as if they are valid too. .TP \fBTCL_LINK_UCHAR\fR The C variable is of type \fBunsigned char\fR. @@ -84,14 +90,18 @@ Any value written into the Tcl variable must have a proper unsigned integer form acceptable to \fBTcl_GetIntFromObj\fR and in the platform's defined range for the \fBunsigned char\fR type; attempts to write non-integer values (or values outside the range) into -\fIvarName\fR will be rejected with Tcl errors. +\fIvarName\fR will be rejected with Tcl errors. Incomplete integer +representations (like the empty string, '+', '-' or the hex/octal/binary +prefix) are accepted as if they are valid too. .TP \fBTCL_LINK_SHORT\fR The C variable is of type \fBshort\fR. Any value written into the Tcl variable must have a proper integer form acceptable to \fBTcl_GetIntFromObj\fR and be in the range of the \fBshort\fR datatype; attempts to write non-integer or out-of-range -values into \fIvarName\fR will be rejected with Tcl errors. +values into \fIvarName\fR will be rejected with Tcl errors. Incomplete +integer representations (like the empty string, '+', '-' or the +hex/octal/binary prefix) are accepted as if they are valid too. .TP \fBTCL_LINK_USHORT\fR The C variable is of type \fBunsigned short\fR. @@ -99,14 +109,18 @@ Any value written into the Tcl variable must have a proper unsigned integer form acceptable to \fBTcl_GetIntFromObj\fR and in the platform's defined range for the \fBunsigned short\fR type; attempts to write non-integer values (or values outside the range) into -\fIvarName\fR will be rejected with Tcl errors. +\fIvarName\fR will be rejected with Tcl errors. Incomplete integer +representations (like the empty string, '+', '-' or the hex/octal/binary +prefix) are accepted as if they are valid too. .TP \fBTCL_LINK_LONG\fR The C variable is of type \fBlong\fR. Any value written into the Tcl variable must have a proper integer form acceptable to \fBTcl_GetLongFromObj\fR; attempts to write non-integer or out-of-range -values into \fIvarName\fR will be rejected with Tcl errors. +values into \fIvarName\fR will be rejected with Tcl errors. Incomplete +integer representations (like the empty string, '+', '-' or the +hex/octal/binary prefix) are accepted as if they are valid too. .TP \fBTCL_LINK_ULONG\fR The C variable is of type \fBunsigned long\fR. @@ -114,14 +128,18 @@ Any value written into the Tcl variable must have a proper unsigned integer form acceptable to \fBTcl_GetWideIntFromObj\fR and in the platform's defined range for the \fBunsigned long\fR type; attempts to write non-integer values (or values outside the range) into -\fIvarName\fR will be rejected with Tcl errors. +\fIvarName\fR will be rejected with Tcl errors. Incomplete integer +representations (like the empty string, '+', '-' or the hex/octal/binary +prefix) are accepted as if they are valid too. .TP \fBTCL_LINK_DOUBLE\fR The C variable is of type \fBdouble\fR. Any value written into the Tcl variable must have a proper real form acceptable to \fBTcl_GetDoubleFromObj\fR; attempts to write non-real values into \fIvarName\fR will be rejected with -Tcl errors. +Tcl errors. Incomplete integer or real representations (like the +empty string, '.', '+', '-' or the hex/octal/binary prefix) are +accepted as if they are valid too. .TP \fBTCL_LINK_FLOAT\fR The C variable is of type \fBfloat\fR. @@ -129,7 +147,9 @@ Any value written into the Tcl variable must have a proper real form acceptable to \fBTcl_GetDoubleFromObj\fR and must be within the range acceptable for a \fBfloat\fR; attempts to write non-real values (or values outside the range) into -\fIvarName\fR will be rejected with Tcl errors. +\fIvarName\fR will be rejected with Tcl errors. Incomplete integer +or real representations (like the empty string, '.', '+', '-' or +the hex/octal/binary prefix) are accepted as if they are valid too. .TP \fBTCL_LINK_WIDE_INT\fR The C variable is of type \fBTcl_WideInt\fR (which is an integer type @@ -137,7 +157,9 @@ at least 64-bits wide on all platforms that can support it.) Any value written into the Tcl variable must have a proper integer form acceptable to \fBTcl_GetWideIntFromObj\fR; attempts to write non-integer values into \fIvarName\fR will be rejected with -Tcl errors. +Tcl errors. Incomplete integer representations (like the empty +string, '+', '-' or the hex/octal/binary prefix) are accepted +as if they are valid too. .TP \fBTCL_LINK_WIDE_UINT\fR The C variable is of type \fBTcl_WideUInt\fR (which is an unsigned @@ -148,7 +170,9 @@ integer form acceptable to \fBTcl_GetWideIntFromObj\fR (it will be cast to unsigned); .\" FIXME! Use bignums instead. attempts to write non-integer values into \fIvarName\fR will be -rejected with Tcl errors. +rejected with Tcl errors. Incomplete integer representations (like +the empty string, '+', '-' or the hex/octal/binary prefix) are accepted +as if they are valid too. .TP \fBTCL_LINK_BOOLEAN\fR The C variable is of type \fBint\fR. diff --git a/generic/tclLink.c b/generic/tclLink.c index 6741377..f8f2342 100644 --- a/generic/tclLink.c +++ b/generic/tclLink.c @@ -575,7 +575,7 @@ LinkTraceProc( break; case TCL_LINK_STRING: - value = Tcl_GetStringFromObj(valueObj, &valueLength); + value = TclGetStringFromObj(valueObj, &valueLength); valueLength++; pp = (char **) linkPtr->addr; @@ -722,23 +722,22 @@ SetInvalidRealFromAny(Tcl_Interp *interp, Tcl_Obj *objPtr) { /* * This function checks for integer representations, which are valid * when linking with C variables, but which are invalid in other - * contexts in Tcl. Handled are "", "+", "-", "0x", "0b" and "0o" + * contexts in Tcl. Handled are "+", "-", "", "0x", "0b" and "0o" * (upperand lowercase). See bug [39f6304c2e]. */ int GetInvalidIntFromObj(Tcl_Obj *objPtr, int *intPtr) { - int length; - const char *str = TclGetStringFromObj(objPtr, &length); + const char *str = TclGetString(objPtr); - if ((length == 1) && strchr("+-", str[0])) { - *intPtr = (str[0] == '+'); - return TCL_OK; - } else if ((length == 0) || - ((length == 2) && (str[0] == '0') && strchr("xXbBoO", str[1]))) { + if ((objPtr->length == 0) || + ((objPtr->length == 2) && (str[0] == '0') && strchr("xXbBoO", str[1]))) { *intPtr = 0; return TCL_OK; + } else if ((objPtr->length == 1) && strchr("+-", str[0])) { + *intPtr = (str[0] == '+'); + return TCL_OK; } return TCL_ERROR; } @@ -746,25 +745,28 @@ GetInvalidIntFromObj(Tcl_Obj *objPtr, /* * This function checks for double representations, which are valid * when linking with C variables, but which are invalid in other - * contexts in Tcl. Handled are ".", "+", "-", "0x", "0b" and "0o" + * contexts in Tcl. Handled are "+", "-", "", ".", "0x", "0b" and "0o" * (upper- and lowercase) and sequences like "1e-". See bug [39f6304c2e]. */ int GetInvalidDoubleFromObj(Tcl_Obj *objPtr, double *doublePtr) { - int intValue, result; + int intValue; - if ((objPtr->typePtr == &invalidRealType) || - (SetInvalidRealFromAny(NULL, objPtr) == TCL_OK)) { - *doublePtr = objPtr->internalRep.doubleValue; - return TCL_OK; + if (objPtr->typePtr == &invalidRealType) { + goto gotdouble; } - result = GetInvalidIntFromObj(objPtr, &intValue); - if (result == TCL_OK) { + if (GetInvalidIntFromObj(objPtr, &intValue) == TCL_OK) { *doublePtr = (double) intValue; + return TCL_OK; + } + if (SetInvalidRealFromAny(NULL, objPtr) == TCL_OK) { + gotdouble: + *doublePtr = objPtr->internalRep.doubleValue; + return TCL_OK; } - return result; + return TCL_ERROR; } /* diff --git a/generic/tclObj.c b/generic/tclObj.c index 45f79e4..a346987 100644 --- a/generic/tclObj.c +++ b/generic/tclObj.c @@ -663,7 +663,7 @@ TclContinuationsEnterDerived( * better way which doesn't shimmer?) */ - Tcl_GetStringFromObj(objPtr, &length); + TclGetStringFromObj(objPtr, &length); end = start + length; /* First char after the word */ /* @@ -1989,7 +1989,7 @@ TclSetBooleanFromAny( badBoolean: if (interp != NULL) { int length; - const char *str = Tcl_GetStringFromObj(objPtr, &length); + const char *str = TclGetStringFromObj(objPtr, &length); Tcl_Obj *msg; TclNewLiteralStringObj(msg, "expected boolean value but got \""); @@ -2785,7 +2785,7 @@ Tcl_GetLongFromObj( if (interp != NULL) { Tcl_SetObjResult(interp, Tcl_ObjPrintf( "expected integer but got \"%s\"", - Tcl_GetString(objPtr))); + TclGetString(objPtr))); Tcl_SetErrorCode(interp, "TCL", "VALUE", "INTEGER", NULL); } return TCL_ERROR; @@ -3086,7 +3086,7 @@ Tcl_GetWideIntFromObj( if (interp != NULL) { Tcl_SetObjResult(interp, Tcl_ObjPrintf( "expected integer but got \"%s\"", - Tcl_GetString(objPtr))); + TclGetString(objPtr))); Tcl_SetErrorCode(interp, "TCL", "VALUE", "INTEGER", NULL); } return TCL_ERROR; @@ -3415,7 +3415,7 @@ GetBignumFromObj( if (interp != NULL) { Tcl_SetObjResult(interp, Tcl_ObjPrintf( "expected integer but got \"%s\"", - Tcl_GetString(objPtr))); + TclGetString(objPtr))); Tcl_SetErrorCode(interp, "TCL", "VALUE", "INTEGER", NULL); } return TCL_ERROR; @@ -3965,7 +3965,7 @@ TclCompareObjKeys( Tcl_Obj *objPtr1 = keyPtr; Tcl_Obj *objPtr2 = (Tcl_Obj *) hPtr->key.oneWordValue; register const char *p1, *p2; - register int l1, l2; + register size_t l1, l2; /* * If the object pointers are the same then they match. diff --git a/generic/tclTest.c b/generic/tclTest.c index 568dd01..f2dbfc9 100644 --- a/generic/tclTest.c +++ b/generic/tclTest.c @@ -331,12 +331,10 @@ static int TestreturnObjCmd(ClientData dummy, Tcl_Obj *const objv[]); static void TestregexpXflags(const char *string, int length, int *cflagsPtr, int *eflagsPtr); -#ifndef TCL_NO_DEPRECATED static int TestsaveresultCmd(ClientData dummy, Tcl_Interp *interp, int objc, Tcl_Obj *const objv[]); static void TestsaveresultFree(char *blockPtr); -#endif /* TCL_NO_DEPRECATED */ static int TestsetassocdataCmd(ClientData dummy, Tcl_Interp *interp, int argc, const char **argv); static int TestsetCmd(ClientData dummy, @@ -534,9 +532,7 @@ int Tcltest_Init( Tcl_Interp *interp) /* Interpreter for application. */ { -#ifndef TCL_NO_DEPRECATED Tcl_ValueType t3ArgTypes[2]; -#endif /* TCL_NO_DEPRECATED */ Tcl_Obj *listPtr; Tcl_Obj **objv; @@ -656,10 +652,8 @@ Tcltest_Init( NULL, NULL); Tcl_CreateObjCommand(interp, "testreturn", TestreturnObjCmd, NULL, NULL); -#ifndef TCL_NO_DEPRECATED Tcl_CreateObjCommand(interp, "testsaveresult", TestsaveresultCmd, NULL, NULL); -#endif /* TCL_NO_DEPRECATED */ Tcl_CreateCommand(interp, "testsetassocdata", TestsetassocdataCmd, NULL, NULL); Tcl_CreateCommand(interp, "testsetnoerr", TestsetCmd, @@ -681,10 +675,8 @@ Tcltest_Init( Tcl_CreateCommand(interp, "testtranslatefilename", TesttranslatefilenameCmd, NULL, NULL); Tcl_CreateCommand(interp, "testupvar", TestupvarCmd, NULL, NULL); -#ifndef TCL_NO_DEPRECATED Tcl_CreateMathFunc(interp, "T1", 0, NULL, TestMathFunc, (ClientData) 123); Tcl_CreateMathFunc(interp, "T2", 0, NULL, TestMathFunc, (ClientData) 345); -#endif /* TCL_NO_DEPRECATED */ Tcl_CreateCommand(interp, "testmainthread", TestmainthreadCmd, NULL, NULL); Tcl_CreateCommand(interp, "testsetmainloop", TestsetmainloopCmd, @@ -695,12 +687,10 @@ Tcltest_Init( Tcl_CreateObjCommand(interp, "testcpuid", TestcpuidCmd, (ClientData) 0, NULL); #endif -#ifndef TCL_NO_DEPRECATED t3ArgTypes[0] = TCL_EITHER; t3ArgTypes[1] = TCL_EITHER; Tcl_CreateMathFunc(interp, "T3", 2, t3ArgTypes, TestMathFunc2, NULL); -#endif /* TCL_NO_DEPRECATED */ Tcl_CreateObjCommand(interp, "testnreunwind", TestNREUnwind, NULL, NULL); @@ -4570,7 +4560,7 @@ TestpanicCmd( int argc, /* Number of arguments. */ const char **argv) /* Argument strings. */ { - const char *argString; + char *argString; /* * Put the arguments into a var args structure @@ -5075,7 +5065,6 @@ Testset2Cmd( } } -#ifndef TCL_NO_DEPRECATED /* *---------------------------------------------------------------------- * @@ -5209,7 +5198,6 @@ TestsaveresultFree( { freeCount++; } -#endif /* TCL_NO_DEPRECATED */ /* *---------------------------------------------------------------------- -- cgit v0.12 From d917353c7e3cca82100ad439880e3c2e4c33d8c7 Mon Sep 17 00:00:00 2001 From: "jan.nijtmans" Date: Fri, 3 Feb 2017 11:47:02 +0000 Subject: In TclGetNumberFromObj() macro (tclExecute.c): Don't fill in type if TCL_ERROR is returned: The caller doesn't do anything with this. Don't access (non-const) variable tclEmptyStringRep any more, use its value (&tclEmptyString) directly. Only keep it in tclPkg.c, for error checking. --- generic/tclBasic.c | 2 +- generic/tclDictObj.c | 2 +- generic/tclExecute.c | 4 ++-- generic/tclInt.h | 9 ++++----- generic/tclListObj.c | 16 ++++++++-------- generic/tclObj.c | 5 ++--- generic/tclPathObj.c | 2 +- generic/tclPkg.c | 2 ++ generic/tclResult.c | 4 ++-- generic/tclStringObj.c | 12 ++++++------ generic/tclUtil.c | 6 +++--- unix/tclUnixSock.c | 2 +- 12 files changed, 33 insertions(+), 33 deletions(-) diff --git a/generic/tclBasic.c b/generic/tclBasic.c index b4d0a7b..63c5590 100644 --- a/generic/tclBasic.c +++ b/generic/tclBasic.c @@ -6055,7 +6055,7 @@ TclNREvalObjEx( TclNRAddCallback(interp, TEOEx_ListCallback, listPtr, eoFramePtr, objPtr, NULL); - ListObjGetElements(listPtr, objc, objv); + TclListObjGetElements(NULL, listPtr, &objc, &objv); return TclNREvalObjv(interp, objc, objv, flags, NULL); } diff --git a/generic/tclDictObj.c b/generic/tclDictObj.c index 1115999..970978f 100644 --- a/generic/tclDictObj.c +++ b/generic/tclDictObj.c @@ -506,7 +506,7 @@ UpdateStringOfDict( /* Handle empty list case first, simplifies what follows */ if (numElems == 0) { - dictPtr->bytes = tclEmptyStringRep; + dictPtr->bytes = &tclEmptyString; dictPtr->length = 0; return; } diff --git a/generic/tclExecute.c b/generic/tclExecute.c index c0dc9c0..c244b08 100644 --- a/generic/tclExecute.c +++ b/generic/tclExecute.c @@ -512,7 +512,7 @@ VarHashCreateVar( (&((objPtr)->internalRep.doubleValue)), TCL_OK) : \ ((((objPtr)->typePtr == NULL) && ((objPtr)->bytes == NULL)) || \ (((objPtr)->bytes != NULL) && ((objPtr)->length == 0))) \ - ? (*(tPtr) = TCL_NUMBER_LONG),TCL_ERROR : \ + ? TCL_ERROR : \ TclGetNumberFromObj((interp), (objPtr), (ptrPtr), (tPtr))) #else /* !TCL_WIDE_INT_IS_LONG */ #define GetNumberFromObj(interp, objPtr, ptrPtr, tPtr) \ @@ -532,7 +532,7 @@ VarHashCreateVar( (&((objPtr)->internalRep.doubleValue)), TCL_OK) : \ ((((objPtr)->typePtr == NULL) && ((objPtr)->bytes == NULL)) || \ (((objPtr)->bytes != NULL) && ((objPtr)->length == 0))) \ - ? (*(tPtr) = TCL_NUMBER_LONG),TCL_ERROR : \ + ? TCL_ERROR : \ TclGetNumberFromObj((interp), (objPtr), (ptrPtr), (tPtr))) #endif /* TCL_WIDE_INT_IS_LONG */ diff --git a/generic/tclInt.h b/generic/tclInt.h index 5074378..4b87962 100644 --- a/generic/tclInt.h +++ b/generic/tclInt.h @@ -2745,7 +2745,6 @@ MODULE_SCOPE long tclObjsShared[TCL_MAX_SHARED_OBJ_STATS]; * shared by all new objects allocated by Tcl_NewObj. */ -MODULE_SCOPE char * tclEmptyStringRep; MODULE_SCOPE char tclEmptyString; /* @@ -4066,7 +4065,7 @@ typedef const char *TclDTraceStr; TclIncrObjsAllocated(); \ TclAllocObjStorage(objPtr); \ (objPtr)->refCount = 0; \ - (objPtr)->bytes = tclEmptyStringRep; \ + (objPtr)->bytes = &tclEmptyString; \ (objPtr)->length = 0; \ (objPtr)->typePtr = NULL; \ TCL_DTRACE_OBJ_CREATE(objPtr) @@ -4083,7 +4082,7 @@ typedef const char *TclDTraceStr; if (!(objPtr)->typePtr || !(objPtr)->typePtr->freeIntRepProc) { \ TCL_DTRACE_OBJ_FREE(objPtr); \ if ((objPtr)->bytes \ - && ((objPtr)->bytes != tclEmptyStringRep)) { \ + && ((objPtr)->bytes != &tclEmptyString)) { \ ckfree((objPtr)->bytes); \ } \ (objPtr)->length = -1; \ @@ -4244,7 +4243,7 @@ MODULE_SCOPE void TclDbInitNewObj(Tcl_Obj *objPtr, const char *file, #define TclInitStringRep(objPtr, bytePtr, len) \ if ((len) == 0) { \ - (objPtr)->bytes = tclEmptyStringRep; \ + (objPtr)->bytes = &tclEmptyString; \ (objPtr)->length = 0; \ } else { \ (objPtr)->bytes = (char *) ckalloc((unsigned) ((len) + 1)); \ @@ -4302,7 +4301,7 @@ MODULE_SCOPE void TclDbInitNewObj(Tcl_Obj *objPtr, const char *file, #define TclInvalidateStringRep(objPtr) \ if ((objPtr)->bytes != NULL) { \ - if ((objPtr)->bytes != tclEmptyStringRep) { \ + if ((objPtr)->bytes != &tclEmptyString) { \ ckfree((objPtr)->bytes); \ } \ (objPtr)->bytes = NULL; \ diff --git a/generic/tclListObj.c b/generic/tclListObj.c index c9fd333..11374cc 100644 --- a/generic/tclListObj.c +++ b/generic/tclListObj.c @@ -374,7 +374,7 @@ Tcl_SetListObj( listRepPtr = NewListIntRep(objc, objv, 1); ListSetIntRep(objPtr, listRepPtr); } else { - objPtr->bytes = tclEmptyStringRep; + objPtr->bytes = &tclEmptyString; objPtr->length = 0; } } @@ -465,7 +465,7 @@ Tcl_ListObjGetElements( if (listPtr->typePtr != &tclListType) { int result; - if (listPtr->bytes == tclEmptyStringRep) { + if (listPtr->bytes == &tclEmptyString) { *objcPtr = 0; *objvPtr = NULL; return TCL_OK; @@ -575,7 +575,7 @@ Tcl_ListObjAppendElement( if (listPtr->typePtr != &tclListType) { int result; - if (listPtr->bytes == tclEmptyStringRep) { + if (listPtr->bytes == &tclEmptyString) { Tcl_SetListObj(listPtr, 1, &objPtr); return TCL_OK; } @@ -739,7 +739,7 @@ Tcl_ListObjIndex( if (listPtr->typePtr != &tclListType) { int result; - if (listPtr->bytes == tclEmptyStringRep) { + if (listPtr->bytes == &tclEmptyString) { *objPtrPtr = NULL; return TCL_OK; } @@ -792,7 +792,7 @@ Tcl_ListObjLength( if (listPtr->typePtr != &tclListType) { int result; - if (listPtr->bytes == tclEmptyStringRep) { + if (listPtr->bytes == &tclEmptyString) { *intPtr = 0; return TCL_OK; } @@ -863,7 +863,7 @@ Tcl_ListObjReplace( Tcl_Panic("%s called with shared object", "Tcl_ListObjReplace"); } if (listPtr->typePtr != &tclListType) { - if (listPtr->bytes == tclEmptyStringRep) { + if (listPtr->bytes == &tclEmptyString) { if (!objc) { return TCL_OK; } @@ -1650,7 +1650,7 @@ TclListObjSetElement( if (listPtr->typePtr != &tclListType) { int result; - if (listPtr->bytes == tclEmptyStringRep) { + if (listPtr->bytes == &tclEmptyString) { if (interp != NULL) { Tcl_SetObjResult(interp, Tcl_NewStringObj("list index out of range", -1)); @@ -1979,7 +1979,7 @@ UpdateStringOfList( */ if (numElems == 0) { - listPtr->bytes = tclEmptyStringRep; + listPtr->bytes = &tclEmptyString; listPtr->length = 0; return; } diff --git a/generic/tclObj.c b/generic/tclObj.c index 90df579..1abbb31 100644 --- a/generic/tclObj.c +++ b/generic/tclObj.c @@ -49,7 +49,6 @@ Tcl_Mutex tclObjMutex; */ char tclEmptyString = '\0'; -char *tclEmptyStringRep = &tclEmptyString; #if defined(TCL_MEM_DEBUG) && defined(TCL_THREADS) /* @@ -1060,7 +1059,7 @@ TclDbInitNewObj( * debugging. */ { objPtr->refCount = 0; - objPtr->bytes = tclEmptyStringRep; + objPtr->bytes = &tclEmptyString; objPtr->length = 0; objPtr->typePtr = NULL; @@ -3395,7 +3394,7 @@ GetBignumFromObj( objPtr->internalRep.twoPtrValue.ptr2 = NULL; objPtr->typePtr = NULL; if (objPtr->bytes == NULL) { - TclInitStringRep(objPtr, tclEmptyStringRep, 0); + TclInitStringRep(objPtr, &tclEmptyString, 0); } } return TCL_OK; diff --git a/generic/tclPathObj.c b/generic/tclPathObj.c index 68ec2c4..0053041 100644 --- a/generic/tclPathObj.c +++ b/generic/tclPathObj.c @@ -2608,7 +2608,7 @@ UpdateStringOfFsPath( pathPtr->bytes = TclGetStringFromObj(copy, &cwdLen); pathPtr->length = cwdLen; - copy->bytes = tclEmptyStringRep; + copy->bytes = &tclEmptyString; copy->length = 0; TclDecrRefCount(copy); } diff --git a/generic/tclPkg.c b/generic/tclPkg.c index 42dd08d..2925c34 100644 --- a/generic/tclPkg.c +++ b/generic/tclPkg.c @@ -17,6 +17,8 @@ #include "tclInt.h" +MODULE_SCOPE char *tclEmptyStringRep = &tclEmptyString; + /* * Each invocation of the "package ifneeded" command creates a structure of * the following type, which is used to load the package into the interpreter diff --git a/generic/tclResult.c b/generic/tclResult.c index 6346636..ddf764b 100644 --- a/generic/tclResult.c +++ b/generic/tclResult.c @@ -1015,11 +1015,11 @@ ResetObjResult( Tcl_IncrRefCount(objResultPtr); iPtr->objResultPtr = objResultPtr; } else { - if (objResultPtr->bytes != tclEmptyStringRep) { + if (objResultPtr->bytes != &tclEmptyString) { if (objResultPtr->bytes) { ckfree(objResultPtr->bytes); } - objResultPtr->bytes = tclEmptyStringRep; + objResultPtr->bytes = &tclEmptyString; objResultPtr->length = 0; } TclFreeIntRep(objResultPtr); diff --git a/generic/tclStringObj.c b/generic/tclStringObj.c index db233b3..c45baa1 100644 --- a/generic/tclStringObj.c +++ b/generic/tclStringObj.c @@ -136,7 +136,7 @@ GrowStringBuffer( char *ptr = NULL; int attempt; - if (objPtr->bytes == tclEmptyStringRep) { + if (objPtr->bytes == &tclEmptyString) { objPtr->bytes = NULL; } if (flag == 0 || stringPtr->allocated > 0) { @@ -767,7 +767,7 @@ Tcl_SetObjLength( /* * Need to enlarge the buffer. */ - if (objPtr->bytes == tclEmptyStringRep) { + if (objPtr->bytes == &tclEmptyString) { objPtr->bytes = ckalloc(length + 1); } else { objPtr->bytes = ckrealloc(objPtr->bytes, length + 1); @@ -873,7 +873,7 @@ Tcl_AttemptSetObjLength( char *newBytes; - if (objPtr->bytes == tclEmptyStringRep) { + if (objPtr->bytes == &tclEmptyString) { newBytes = attemptckalloc(length + 1); } else { newBytes = attemptckrealloc(objPtr->bytes, length + 1); @@ -1202,7 +1202,7 @@ Tcl_AppendObjToObj( * that appending nothing to anything leaves that starting anything... */ - if (appendObjPtr->bytes == tclEmptyStringRep) { + if (appendObjPtr->bytes == &tclEmptyString) { return; } @@ -1213,7 +1213,7 @@ Tcl_AppendObjToObj( * information; this is a special-case optimization only. */ - if ((TclIsPureByteArray(objPtr) || objPtr->bytes == tclEmptyStringRep) + if ((TclIsPureByteArray(objPtr) || objPtr->bytes == &tclEmptyString) && TclIsPureByteArray(appendObjPtr)) { /* @@ -3603,7 +3603,7 @@ UpdateStringOfString( stringPtr->allocated = 0; if (stringPtr->numChars == 0) { - TclInitStringRep(objPtr, tclEmptyStringRep, 0); + TclInitStringRep(objPtr, &tclEmptyString, 0); } else { (void) ExtendStringRepWithUnicode(objPtr, stringPtr->unicode, stringPtr->numChars); diff --git a/generic/tclUtil.c b/generic/tclUtil.c index ba709cc..a4d523a 100644 --- a/generic/tclUtil.c +++ b/generic/tclUtil.c @@ -1384,7 +1384,7 @@ TclConvertElement( */ if ((src == NULL) || (length == 0) || (*src == '\0' && length == -1)) { - src = tclEmptyStringRep; + src = &tclEmptyString; length = 0; conversion = CONVERT_BRACE; } @@ -2954,7 +2954,7 @@ Tcl_DStringGetResult( if (!iPtr->result[0] && iPtr->objResultPtr && !Tcl_IsShared(iPtr->objResultPtr)) { - if (iPtr->objResultPtr->bytes == tclEmptyStringRep) { + if (iPtr->objResultPtr->bytes == &tclEmptyString) { dsPtr->string = dsPtr->staticSpace; dsPtr->string[0] = 0; dsPtr->length = 0; @@ -2964,7 +2964,7 @@ Tcl_DStringGetResult( dsPtr->length = iPtr->objResultPtr->length; dsPtr->spaceAvl = dsPtr->length + 1; TclFreeIntRep(iPtr->objResultPtr); - iPtr->objResultPtr->bytes = tclEmptyStringRep; + iPtr->objResultPtr->bytes = &tclEmptyString; iPtr->objResultPtr->length = 0; } return; diff --git a/unix/tclUnixSock.c b/unix/tclUnixSock.c index 8e97543..9387d05 100644 --- a/unix/tclUnixSock.c +++ b/unix/tclUnixSock.c @@ -240,7 +240,7 @@ InitializeHostName( } } if (native == NULL) { - native = tclEmptyStringRep; + native = &tclEmptyString; } #else /* !NO_UNAME */ /* -- cgit v0.12 From 19e0981d356c17f1c104a63c10bc913528b315af Mon Sep 17 00:00:00 2001 From: "jan.nijtmans" Date: Fri, 3 Feb 2017 14:29:50 +0000 Subject: Split tclEmptyStringRep declaration over two lines. Otherwise gcc warning. --- generic/tclPkg.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/generic/tclPkg.c b/generic/tclPkg.c index 2925c34..0759faa 100644 --- a/generic/tclPkg.c +++ b/generic/tclPkg.c @@ -17,7 +17,9 @@ #include "tclInt.h" -MODULE_SCOPE char *tclEmptyStringRep = &tclEmptyString; +MODULE_SCOPE char *tclEmptyStringRep; + +char *tclEmptyStringRep = &tclEmptyString; /* * Each invocation of the "package ifneeded" command creates a structure of -- cgit v0.12 From d5c18c780a2d18b60cb61408c8838d150a02aa49 Mon Sep 17 00:00:00 2001 From: bch Date: Mon, 6 Feb 2017 21:54:30 +0000 Subject: s/then/than/ in Eval.3 manpage --- doc/Eval.3 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/Eval.3 b/doc/Eval.3 index 8661923..191bace 100644 --- a/doc/Eval.3 +++ b/doc/Eval.3 @@ -205,7 +205,7 @@ and sets \fIinterp\fR's result to an error message indicating that the \fBreturn\fR, \fBbreak\fR, or \fBcontinue\fR command was invoked in an inappropriate place. This means that top-level applications should never see a return code -from \fBTcl_EvalObjEx\fR other then \fBTCL_OK\fR or \fBTCL_ERROR\fR. +from \fBTcl_EvalObjEx\fR other than \fBTCL_OK\fR or \fBTCL_ERROR\fR. .SH KEYWORDS execute, file, global, result, script, value -- cgit v0.12 From 0e31751aedc651ce181d544e5ce13cdef1b135ca Mon Sep 17 00:00:00 2001 From: bch Date: Mon, 6 Feb 2017 21:58:48 +0000 Subject: cherrypick typo fix. --- doc/Eval.3 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/Eval.3 b/doc/Eval.3 index 8661923..191bace 100644 --- a/doc/Eval.3 +++ b/doc/Eval.3 @@ -205,7 +205,7 @@ and sets \fIinterp\fR's result to an error message indicating that the \fBreturn\fR, \fBbreak\fR, or \fBcontinue\fR command was invoked in an inappropriate place. This means that top-level applications should never see a return code -from \fBTcl_EvalObjEx\fR other then \fBTCL_OK\fR or \fBTCL_ERROR\fR. +from \fBTcl_EvalObjEx\fR other than \fBTCL_OK\fR or \fBTCL_ERROR\fR. .SH KEYWORDS execute, file, global, result, script, value -- cgit v0.12 From fca34fb8d0eb7f4bcc1395c00b97289685745ff7 Mon Sep 17 00:00:00 2001 From: "jan.nijtmans" Date: Tue, 7 Feb 2017 12:11:29 +0000 Subject: =?UTF-8?q?Code=20cleanup=20(based=20on=20feedback=20from=20Ren?= =?UTF-8?q?=C3=A9=20Zaumseil):=20Only=20call=20GetInvalidIntFromObj()=20wh?= =?UTF-8?q?en=20Tcl=5FGetIntFromObj()=20fails.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- generic/tclLink.c | 203 +++++++++++++++++++++++------------------------------- 1 file changed, 85 insertions(+), 118 deletions(-) diff --git a/generic/tclLink.c b/generic/tclLink.c index f8f2342..7d1e3a8 100644 --- a/generic/tclLink.c +++ b/generic/tclLink.c @@ -67,10 +67,9 @@ typedef struct Link { static char * LinkTraceProc(ClientData clientData,Tcl_Interp *interp, const char *name1, const char *name2, int flags); static Tcl_Obj * ObjValue(Link *linkPtr); -static int GetInvalidIntFromObj(Tcl_Obj *objPtr, - int *intPtr); -static int GetInvalidDoubleFromObj(Tcl_Obj *objPtr, - double *doublePtr); +static int GetInvalidIntFromObj(Tcl_Obj *objPtr, int *intPtr); +static int GetInvalidWideFromObj(Tcl_Obj *objPtr, Tcl_WideInt *widePtr); +static int GetInvalidDoubleFromObj(Tcl_Obj *objPtr, double *doublePtr); /* * Convenience macro for accessing the value of the C variable pointed to by a @@ -263,7 +262,8 @@ LinkTraceProc( int flags) /* Miscellaneous additional information. */ { Link *linkPtr = clientData; - int changed, valueLength; + int changed; + size_t valueLength; const char *value; char **pp; Tcl_Obj *valueObj; @@ -382,40 +382,31 @@ LinkTraceProc( switch (linkPtr->type) { case TCL_LINK_INT: - if (Tcl_GetIntFromObj(NULL, valueObj, &linkPtr->lastValue.i) - != TCL_OK) { - if (GetInvalidIntFromObj(valueObj, &linkPtr->lastValue.i) - != TCL_OK) { - Tcl_ObjSetVar2(interp, linkPtr->varName, NULL, ObjValue(linkPtr), + if (Tcl_GetIntFromObj(NULL, valueObj, &linkPtr->lastValue.i) != TCL_OK + && GetInvalidIntFromObj(valueObj, &linkPtr->lastValue.i) != TCL_OK) { + Tcl_ObjSetVar2(interp, linkPtr->varName, NULL, ObjValue(linkPtr), TCL_GLOBAL_ONLY); - return (char *) "variable must have integer value"; - } + return (char *) "variable must have integer value"; } LinkedVar(int) = linkPtr->lastValue.i; break; case TCL_LINK_WIDE_INT: - if (Tcl_GetWideIntFromObj(NULL, valueObj, &linkPtr->lastValue.w) - != TCL_OK) { - if (GetInvalidIntFromObj(valueObj, &valueInt) - != TCL_OK) { - Tcl_ObjSetVar2(interp, linkPtr->varName, NULL, ObjValue(linkPtr), + if (Tcl_GetWideIntFromObj(NULL, valueObj, &linkPtr->lastValue.w) != TCL_OK + && GetInvalidWideFromObj(valueObj, &linkPtr->lastValue.w) != TCL_OK) { + Tcl_ObjSetVar2(interp, linkPtr->varName, NULL, ObjValue(linkPtr), TCL_GLOBAL_ONLY); - return (char *) "variable must have integer value"; - } - linkPtr->lastValue.w = (Tcl_WideInt) valueInt; + return (char *) "variable must have integer value"; } LinkedVar(Tcl_WideInt) = linkPtr->lastValue.w; break; case TCL_LINK_DOUBLE: - if (Tcl_GetDoubleFromObj(NULL, valueObj, &linkPtr->lastValue.d) - != TCL_OK) { + if (Tcl_GetDoubleFromObj(NULL, valueObj, &linkPtr->lastValue.d) != TCL_OK) { #ifdef ACCEPT_NAN if (valueObj->typePtr != &tclDoubleType) { #endif - if (GetInvalidDoubleFromObj(valueObj, &linkPtr->lastValue.d) - != TCL_OK) { + if (GetInvalidDoubleFromObj(valueObj, &linkPtr->lastValue.d) != TCL_OK) { Tcl_ObjSetVar2(interp, linkPtr->varName, NULL, ObjValue(linkPtr), TCL_GLOBAL_ONLY); return (char *) "variable must have real value"; @@ -429,8 +420,7 @@ LinkTraceProc( break; case TCL_LINK_BOOLEAN: - if (Tcl_GetBooleanFromObj(NULL, valueObj, &linkPtr->lastValue.i) - != TCL_OK) { + if (Tcl_GetBooleanFromObj(NULL, valueObj, &linkPtr->lastValue.i) != TCL_OK) { Tcl_ObjSetVar2(interp, linkPtr->varName, NULL, ObjValue(linkPtr), TCL_GLOBAL_ONLY); return (char *) "variable must have boolean value"; @@ -439,148 +429,113 @@ LinkTraceProc( break; case TCL_LINK_CHAR: - if (Tcl_GetIntFromObj(NULL, valueObj, &valueInt) != TCL_OK + if ((Tcl_GetIntFromObj(NULL, valueObj, &valueInt) != TCL_OK + && GetInvalidIntFromObj(valueObj, &valueInt) != TCL_OK) || valueInt < SCHAR_MIN || valueInt > SCHAR_MAX) { - if (GetInvalidIntFromObj(valueObj, &valueInt) - != TCL_OK) { - Tcl_ObjSetVar2(interp, linkPtr->varName, NULL, ObjValue(linkPtr), - TCL_GLOBAL_ONLY); - return (char *) "variable must have char value"; - } + Tcl_ObjSetVar2(interp, linkPtr->varName, NULL, ObjValue(linkPtr), + TCL_GLOBAL_ONLY); + return (char *) "variable must have char value"; } - linkPtr->lastValue.c = (char)valueInt; - LinkedVar(char) = linkPtr->lastValue.c; + LinkedVar(char) = linkPtr->lastValue.c = (char)valueInt; break; case TCL_LINK_UCHAR: - if (Tcl_GetIntFromObj(NULL, valueObj, &valueInt) != TCL_OK + if ((Tcl_GetIntFromObj(NULL, valueObj, &valueInt) != TCL_OK + && GetInvalidIntFromObj(valueObj, &valueInt) != TCL_OK) || valueInt < 0 || valueInt > UCHAR_MAX) { - if (GetInvalidIntFromObj(valueObj, &valueInt) - != TCL_OK) { - Tcl_ObjSetVar2(interp, linkPtr->varName, NULL, ObjValue(linkPtr), - TCL_GLOBAL_ONLY); - return (char *) "variable must have unsigned char value"; - } + Tcl_ObjSetVar2(interp, linkPtr->varName, NULL, ObjValue(linkPtr), + TCL_GLOBAL_ONLY); + return (char *) "variable must have unsigned char value"; } - linkPtr->lastValue.uc = (unsigned char) valueInt; - LinkedVar(unsigned char) = linkPtr->lastValue.uc; + LinkedVar(unsigned char) = linkPtr->lastValue.uc = (unsigned char) valueInt; break; case TCL_LINK_SHORT: - if (Tcl_GetIntFromObj(NULL, valueObj, &valueInt) != TCL_OK + if ((Tcl_GetIntFromObj(NULL, valueObj, &valueInt) != TCL_OK + && GetInvalidIntFromObj(valueObj, &valueInt) != TCL_OK) || valueInt < SHRT_MIN || valueInt > SHRT_MAX) { - if (GetInvalidIntFromObj(valueObj, &valueInt) - != TCL_OK) { - Tcl_ObjSetVar2(interp, linkPtr->varName, NULL, ObjValue(linkPtr), - TCL_GLOBAL_ONLY); - return (char *) "variable must have short value"; - } + Tcl_ObjSetVar2(interp, linkPtr->varName, NULL, ObjValue(linkPtr), + TCL_GLOBAL_ONLY); + return (char *) "variable must have short value"; } - linkPtr->lastValue.s = (short)valueInt; - LinkedVar(short) = linkPtr->lastValue.s; + LinkedVar(short) = linkPtr->lastValue.s = (short)valueInt; break; case TCL_LINK_USHORT: - if (Tcl_GetIntFromObj(NULL, valueObj, &valueInt) != TCL_OK + if ((Tcl_GetIntFromObj(NULL, valueObj, &valueInt) != TCL_OK + && GetInvalidIntFromObj(valueObj, &valueInt) != TCL_OK) || valueInt < 0 || valueInt > USHRT_MAX) { - if (GetInvalidIntFromObj(valueObj, &valueInt) - != TCL_OK) { - Tcl_ObjSetVar2(interp, linkPtr->varName, NULL, ObjValue(linkPtr), - TCL_GLOBAL_ONLY); - return (char *) "variable must have unsigned short value"; - } + Tcl_ObjSetVar2(interp, linkPtr->varName, NULL, ObjValue(linkPtr), + TCL_GLOBAL_ONLY); + return (char *) "variable must have unsigned short value"; } - linkPtr->lastValue.us = (unsigned short)valueInt; - LinkedVar(unsigned short) = linkPtr->lastValue.us; + LinkedVar(unsigned short) = linkPtr->lastValue.us = (unsigned short)valueInt; break; case TCL_LINK_UINT: - if (Tcl_GetWideIntFromObj(NULL, valueObj, &valueWide) != TCL_OK + if ((Tcl_GetWideIntFromObj(NULL, valueObj, &valueWide) != TCL_OK + && GetInvalidWideFromObj(valueObj, &valueWide) != TCL_OK) || valueWide < 0 || valueWide > UINT_MAX) { - if (GetInvalidIntFromObj(valueObj, &valueInt) - != TCL_OK) { - Tcl_ObjSetVar2(interp, linkPtr->varName, NULL, ObjValue(linkPtr), - TCL_GLOBAL_ONLY); - return (char *) "variable must have unsigned int value"; - } - linkPtr->lastValue.ui = (unsigned int)valueInt; - } else { - linkPtr->lastValue.ui = (unsigned int)valueWide; + Tcl_ObjSetVar2(interp, linkPtr->varName, NULL, ObjValue(linkPtr), + TCL_GLOBAL_ONLY); + return (char *) "variable must have unsigned int value"; } - LinkedVar(unsigned int) = linkPtr->lastValue.ui; + LinkedVar(unsigned int) = linkPtr->lastValue.ui = (unsigned int)valueWide; break; case TCL_LINK_LONG: - if (Tcl_GetWideIntFromObj(NULL, valueObj, &valueWide) != TCL_OK + if ((Tcl_GetWideIntFromObj(NULL, valueObj, &valueWide) != TCL_OK + && GetInvalidWideFromObj(valueObj, &valueWide) != TCL_OK) || valueWide < LONG_MIN || valueWide > LONG_MAX) { - if (GetInvalidIntFromObj(valueObj, &valueInt) - != TCL_OK) { - Tcl_ObjSetVar2(interp, linkPtr->varName, NULL, ObjValue(linkPtr), - TCL_GLOBAL_ONLY); - return (char *) "variable must have long value"; - } - linkPtr->lastValue.l = (long)valueInt; - } else { - linkPtr->lastValue.l = (long)valueWide; + Tcl_ObjSetVar2(interp, linkPtr->varName, NULL, ObjValue(linkPtr), + TCL_GLOBAL_ONLY); + return (char *) "variable must have long value"; } - LinkedVar(long) = linkPtr->lastValue.l; + LinkedVar(long) = linkPtr->lastValue.l = (long)valueWide; break; case TCL_LINK_ULONG: - if (Tcl_GetWideIntFromObj(NULL, valueObj, &valueWide) != TCL_OK + if ((Tcl_GetWideIntFromObj(NULL, valueObj, &valueWide) != TCL_OK + && GetInvalidWideFromObj(valueObj, &valueWide) != TCL_OK) || valueWide < 0 || (Tcl_WideUInt) valueWide > ULONG_MAX) { - if (GetInvalidIntFromObj(valueObj, &valueInt) - != TCL_OK) { - Tcl_ObjSetVar2(interp, linkPtr->varName, NULL, ObjValue(linkPtr), - TCL_GLOBAL_ONLY); - return (char *) "variable must have unsigned long value"; - } - linkPtr->lastValue.ul = (unsigned long)valueInt; - } else { - linkPtr->lastValue.ul = (unsigned long)valueWide; + Tcl_ObjSetVar2(interp, linkPtr->varName, NULL, ObjValue(linkPtr), + TCL_GLOBAL_ONLY); + return (char *) "variable must have unsigned long value"; } - LinkedVar(unsigned long) = linkPtr->lastValue.ul; + LinkedVar(unsigned long) = linkPtr->lastValue.ul = (unsigned long)valueWide; break; case TCL_LINK_WIDE_UINT: /* * FIXME: represent as a bignum. */ - if (Tcl_GetWideIntFromObj(NULL, valueObj, &valueWide) != TCL_OK) { - if (GetInvalidIntFromObj(valueObj, &valueInt) - != TCL_OK) { - Tcl_ObjSetVar2(interp, linkPtr->varName, NULL, ObjValue(linkPtr), - TCL_GLOBAL_ONLY); - return (char *) "variable must have unsigned wide int value"; - } - linkPtr->lastValue.uw = (Tcl_WideUInt)valueInt; - } else { - linkPtr->lastValue.uw = (Tcl_WideUInt)valueWide; + if (Tcl_GetWideIntFromObj(NULL, valueObj, &valueWide) != TCL_OK + && GetInvalidWideFromObj(valueObj, &valueWide) != TCL_OK) { + Tcl_ObjSetVar2(interp, linkPtr->varName, NULL, ObjValue(linkPtr), + TCL_GLOBAL_ONLY); + return (char *) "variable must have unsigned wide int value"; } - LinkedVar(Tcl_WideUInt) = linkPtr->lastValue.uw; + LinkedVar(Tcl_WideUInt) = linkPtr->lastValue.uw = (Tcl_WideUInt)valueWide; break; case TCL_LINK_FLOAT: - if (Tcl_GetDoubleFromObj(NULL, valueObj, &valueDouble) != TCL_OK + if ((Tcl_GetDoubleFromObj(NULL, valueObj, &valueDouble) != TCL_OK + && GetInvalidDoubleFromObj(valueObj, &valueDouble) != TCL_OK) || valueDouble < -FLT_MAX || valueDouble > FLT_MAX) { - if (GetInvalidDoubleFromObj(valueObj, &valueDouble) - != TCL_OK) { - Tcl_ObjSetVar2(interp, linkPtr->varName, NULL, ObjValue(linkPtr), - TCL_GLOBAL_ONLY); - return (char *) "variable must have float value"; - } + Tcl_ObjSetVar2(interp, linkPtr->varName, NULL, ObjValue(linkPtr), + TCL_GLOBAL_ONLY); + return (char *) "variable must have float value"; } - linkPtr->lastValue.f = (float)valueDouble; - LinkedVar(float) = linkPtr->lastValue.f; + LinkedVar(float) = linkPtr->lastValue.f = (float)valueDouble; break; case TCL_LINK_STRING: - value = TclGetStringFromObj(valueObj, &valueLength); - valueLength++; + value = TclGetString(valueObj); + valueLength = valueObj->length + 1; pp = (char **) linkPtr->addr; *pp = ckrealloc(*pp, valueLength); - memcpy(*pp, value, (unsigned) valueLength); + memcpy(*pp, value, valueLength); break; default: @@ -742,6 +697,18 @@ GetInvalidIntFromObj(Tcl_Obj *objPtr, return TCL_ERROR; } +int +GetInvalidWideFromObj(Tcl_Obj *objPtr, Tcl_WideInt *widePtr) +{ + int intValue; + + if (GetInvalidIntFromObj(objPtr, &intValue) != TCL_OK) { + return TCL_ERROR; + } + *widePtr = intValue; + return TCL_OK; +} + /* * This function checks for double representations, which are valid * when linking with C variables, but which are invalid in other -- cgit v0.12 From 8066c6a687d570d513638c2079a6bc8a9a9b364f Mon Sep 17 00:00:00 2001 From: "jan.nijtmans" Date: Wed, 8 Feb 2017 11:42:12 +0000 Subject: FlightAware feedback: "Aside: Any way to find out what the pkgIndex.tcl file a package was defined in was, or does that happen at too high a level?" Answer: Even though the name of the pkgIndex file is available earlier, it is very well possible to remember it and store it with the other files. This commit does exactly that. --- generic/tclPkg.c | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/generic/tclPkg.c b/generic/tclPkg.c index 0759faa..9ad3cb7 100644 --- a/generic/tclPkg.c +++ b/generic/tclPkg.c @@ -32,6 +32,7 @@ typedef struct PkgAvail { char *script; /* Script to invoke to provide this version of * the package. Malloc'ed and protected by * Tcl_Preserve and Tcl_Release. */ + char *pkgIndex; /* Full file name of pkgIndex file */ struct PkgAvail *nextPtr; /* Next in list of available versions of the * same package. */ } PkgAvail; @@ -573,6 +574,9 @@ PkgRequireCore( pkgName->nextPtr = pkgFiles->names; strcpy(pkgName->name, name); pkgFiles->names = pkgName; + if (bestPtr->pkgIndex) { + TclPkgFileSeen(interp, bestPtr->pkgIndex); + } code = Tcl_EvalEx(interp, script, -1, TCL_EVAL_GLOBAL); /* Pop the "ifneeded" package name from "tclPkgFiles" assocdata*/ pkgFiles->names = pkgName->nextPtr; @@ -921,6 +925,9 @@ Tcl_PackageObjCmd( pkgPtr->availPtr = availPtr->nextPtr; Tcl_EventuallyFree(availPtr->version, TCL_DYNAMIC); Tcl_EventuallyFree(availPtr->script, TCL_DYNAMIC); + if (availPtr->pkgIndex) { + Tcl_EventuallyFree(availPtr->pkgIndex, TCL_DYNAMIC); + } ckfree(availPtr); } ckfree(pkgPtr); @@ -971,6 +978,9 @@ Tcl_PackageObjCmd( return TCL_OK; } Tcl_EventuallyFree(availPtr->script, TCL_DYNAMIC); + if (availPtr->pkgIndex) { + Tcl_EventuallyFree(availPtr->pkgIndex, TCL_DYNAMIC); + } break; } } @@ -981,6 +991,7 @@ Tcl_PackageObjCmd( } if (availPtr == NULL) { availPtr = ckalloc(sizeof(PkgAvail)); + availPtr->pkgIndex = 0; DupBlock(availPtr->version, argv3, (unsigned) length + 1); if (prevPtr == NULL) { @@ -991,6 +1002,10 @@ Tcl_PackageObjCmd( prevPtr->nextPtr = availPtr; } } + if (iPtr->scriptFile) { + argv4 = TclGetStringFromObj(iPtr->scriptFile, &length); + DupBlock(availPtr->pkgIndex, argv4, (unsigned) length + 1); + } argv4 = TclGetStringFromObj(objv[4], &length); DupBlock(availPtr->script, argv4, (unsigned) length + 1); break; @@ -1346,6 +1361,9 @@ TclFreePackageInfo( pkgPtr->availPtr = availPtr->nextPtr; Tcl_EventuallyFree(availPtr->version, TCL_DYNAMIC); Tcl_EventuallyFree(availPtr->script, TCL_DYNAMIC); + if (availPtr->pkgIndex) { + Tcl_EventuallyFree(availPtr->pkgIndex, TCL_DYNAMIC); + } ckfree(availPtr); } ckfree(pkgPtr); -- cgit v0.12 From 6db42b86e652e1d29093c8b75793c059b9792dd5 Mon Sep 17 00:00:00 2001 From: "jan.nijtmans" Date: Wed, 8 Feb 2017 14:32:13 +0000 Subject: Shortcut in TclParseNumber(): If obj is a dict or list, don't bother to generate the string representation if we know already beforehand that the parsing will fail. Use TCL_NO_DEPRECATED in stead of KILL_OCTAL for removing the (deprecated un-prefixed) octal support. Adapt test-cases, so they work without octal support as well. --- generic/tclHistory.c | 5 ++--- generic/tclStrToD.c | 27 +++++++++++++++++---------- tests/get.test | 8 ++++---- tests/parseExpr.test | 5 ++--- 4 files changed, 25 insertions(+), 20 deletions(-) diff --git a/generic/tclHistory.c b/generic/tclHistory.c index b08e352..47806d4 100644 --- a/generic/tclHistory.c +++ b/generic/tclHistory.c @@ -62,15 +62,14 @@ Tcl_RecordAndEval( * instead of Tcl_Eval. */ { register Tcl_Obj *cmdPtr; - int length = strlen(cmd); int result; - if (length > 0) { + if (cmd[0]) { /* * Call Tcl_RecordAndEvalObj to do the actual work. */ - cmdPtr = Tcl_NewStringObj(cmd, length); + cmdPtr = Tcl_NewStringObj(cmd, -1); Tcl_IncrRefCount(cmdPtr); result = Tcl_RecordAndEvalObj(interp, cmdPtr, flags); diff --git a/generic/tclStrToD.c b/generic/tclStrToD.c index 6da6df3..77e1839 100644 --- a/generic/tclStrToD.c +++ b/generic/tclStrToD.c @@ -18,13 +18,6 @@ #include /* - * Define KILL_OCTAL to suppress interpretation of numbers with leading zero - * as octal. (Ceterum censeo: numeros octonarios delendos esse.) - */ - -#undef KILL_OCTAL - -/* * This code supports (at least hypothetically), IBM, Cray, VAX and IEEE-754 * floating point; of these, only IEEE-754 can represent NaN. IEEE-754 can be * uniquely determined by radix and by the widths of significand and exponent. @@ -546,6 +539,20 @@ TclParseNumber( */ if (bytes == NULL) { + if (endPtrPtr == NULL) { + if (objPtr->typePtr == &tclDictType) { + /* A dict can never be a (single) number */ + return TCL_ERROR; + } + if (objPtr->typePtr == &tclListType) { + int length; + /* A list can only be a (single) number if its length == 1 */ + TclListObjLength(NULL, objPtr, &length); + if (length != 1) { + return TCL_ERROR; + } + } + } bytes = TclGetString(objPtr); } @@ -657,7 +664,7 @@ TclParseNumber( state = ZERO_O; break; } -#ifdef KILL_OCTAL +#ifdef TCL_NO_DEPRECATED goto decimal; #endif /* FALLTHROUGH */ @@ -740,7 +747,7 @@ TclParseNumber( goto endgame; } -#ifndef KILL_OCTAL +#ifndef TCL_NO_DEPRECATED /* * Scanned a number with a leading zero that contains an 8, 9, @@ -879,7 +886,7 @@ TclParseNumber( * digits. */ -#ifdef KILL_OCTAL +#ifdef TCL_NO_DEPRECATED decimal: #endif acceptState = state; diff --git a/tests/get.test b/tests/get.test index 7aa06c1..d6a7206 100644 --- a/tests/get.test +++ b/tests/get.test @@ -98,17 +98,17 @@ test get-3.2 {Tcl_GetDouble(FromObj), bad numbers} { } {0 1 0 1 1 {expected floating-point number but got "++1.0"} 1 {expected floating-point number but got "+-1.0"} 1 {expected floating-point number but got "-+1.0"} 0 -1 1 {expected floating-point number but got "--1.0"} 1 {expected floating-point number but got "- +1.0"}} # Bug 7114ac6141 test get-3.3 {tcl_GetInt with iffy numbers} testgetint { - lmap x {0 " 0" "0 " " 0 " " 0xa " " 010 " " 0o10 " " 0b10 "} { + lmap x {0 " 0" "0 " " 0 " " 0xa " " 007 " " 0o10 " " 0b10 "} { catch {testgetint 44 $x} x set x } -} {44 44 44 44 54 52 52 46} +} {44 44 44 44 54 51 52 46} test get-3.4 {Tcl_GetDouble with iffy numbers} testdoubleobj { - lmap x {0 0.0 " .0" ".0 " " 0e0 " "09" "- 0" "-0" "0o12" "0b10"} { + lmap x {0 0.0 " .0" ".0 " " 0e0 " "07" "- 0" "-0" "0o12" "0b10"} { catch {testdoubleobj set 1 $x} x set x } -} {0.0 0.0 0.0 0.0 0.0 {expected floating-point number but got "09" (looks like invalid octal number)} {expected floating-point number but got "- 0"} 0.0 10.0 2.0} +} {0.0 0.0 0.0 0.0 0.0 7.0 {expected floating-point number but got "- 0"} 0.0 10.0 2.0} # cleanup ::tcltest::cleanupTests diff --git a/tests/parseExpr.test b/tests/parseExpr.test index fda25b7..47dbec5 100644 --- a/tests/parseExpr.test +++ b/tests/parseExpr.test @@ -1044,9 +1044,8 @@ test parseExpr-22.13 {Bug 3401704} -constraints testexprparser -body { } -result {- {} 0 subexpr naner() 1 operator naner 0 {}} test parseExpr-22.14 {Bug 3401704} -constraints testexprparser -body { - catch {testexprparser 08 -1} m o - dict get $o -errorcode -} -result {TCL PARSE EXPR BADNUMBER OCTAL} + testexprparser 07 -1 +} -result {- {} 0 subexpr 07 1 text 07 0 {}} test parseExpr-22.15 {Bug 3401704} -constraints testexprparser -body { catch {testexprparser 0o8 -1} m o dict get $o -errorcode -- cgit v0.12 From 35539e2f98f007de63a0bef192a769c9f8f9ad91 Mon Sep 17 00:00:00 2001 From: sebres Date: Thu, 9 Feb 2017 11:34:43 +0000 Subject: =?UTF-8?q?resolve=20warning:=20enumeration=20value=20=E2=80=98TMR?= =?UTF-8?q?T=5FLAST=E2=80=99=20not=20handled=20in=20switch=20(impossible?= =?UTF-8?q?=20to=20handle=20in=20switch=20because=20of=20break);?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- generic/tclCmdMZ.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/generic/tclCmdMZ.c b/generic/tclCmdMZ.c index c660596..319799c 100644 --- a/generic/tclCmdMZ.c +++ b/generic/tclCmdMZ.c @@ -4089,7 +4089,7 @@ Tcl_TimeRateObjCmd( i++; break; } - switch ((enum options) index) { + switch (index) { case TMRT_EV_DIRECT: direct = objv[i]; break; -- cgit v0.12 From ca98340c4c69feed95b1823e8a83800a1ea8fae3 Mon Sep 17 00:00:00 2001 From: sebres Date: Thu, 9 Feb 2017 11:36:17 +0000 Subject: [timerate] bug fix: missing scale conversion by Mac OSX on platform where high resolution clicks are not microseconds based; [win] use high resolution timer for the wide clicks and microseconds directly, prevent several forwards/backwards conversions; [win, unix, mac-osx] normalize some functions for common usage in different time units (clicks, micro- and nanoseconds) --- generic/tclClock.c | 9 +-- generic/tclCmdMZ.c | 24 +++++--- generic/tclInt.h | 16 ++++++ unix/tclUnixTime.c | 71 +++++++++++++++++++++++ win/tclWinTime.c | 166 ++++++++++++++++++++++++++++++++++++++++++----------- 5 files changed, 238 insertions(+), 48 deletions(-) diff --git a/generic/tclClock.c b/generic/tclClock.c index 27009fd..5da9511 100644 --- a/generic/tclClock.c +++ b/generic/tclClock.c @@ -1760,8 +1760,7 @@ ClockClicksObjCmd( #endif break; case CLICKS_MICROS: - Tcl_GetTime(&now); - clicks = ((Tcl_WideInt) now.sec * 1000000) + now.usec; + clicks = TclpGetMicroseconds(); break; } @@ -1831,15 +1830,11 @@ ClockMicrosecondsObjCmd( int objc, /* Parameter count */ Tcl_Obj *const *objv) /* Parameter values */ { - Tcl_Time now; - if (objc != 1) { Tcl_WrongNumArgs(interp, 1, objv, NULL); return TCL_ERROR; } - Tcl_GetTime(&now); - Tcl_SetObjResult(interp, Tcl_NewWideIntObj( - ((Tcl_WideInt) now.sec * 1000000) + now.usec)); + Tcl_SetObjResult(interp, Tcl_NewWideIntObj(TclpGetMicroseconds())); return TCL_OK; } diff --git a/generic/tclCmdMZ.c b/generic/tclCmdMZ.c index 319799c..b0212c3 100644 --- a/generic/tclCmdMZ.c +++ b/generic/tclCmdMZ.c @@ -4215,16 +4215,19 @@ usage: } /* get start and stop time */ -#ifndef TCL_WIDE_CLICKS +#ifdef TCL_WIDE_CLICKS + start = middle = TclpGetWideClicks(); + /* time to stop execution (in wide clicks) */ + stop = start + (maxms * 1000 / TclpWideClickInMicrosec()); +#else Tcl_GetTime(&now); start = now.sec; start *= 1000000; start += now.usec; -#else - start = TclpGetWideClicks(); + middle = start; + /* time to stop execution (in microsecs) */ + stop = start + maxms * 1000; #endif /* start measurement */ - stop = start + maxms * 1000; - middle = start; while (1) { /* eval single iteration */ count++; @@ -4246,11 +4249,11 @@ usage: if (--threshold > 0) continue; /* check stop time reached, estimate new threshold */ - #ifndef TCL_WIDE_CLICKS + #ifdef TCL_WIDE_CLICKS + middle = TclpGetWideClicks(); + #else Tcl_GetTime(&now); middle = now.sec; middle *= 1000000; middle += now.usec; - #else - middle = TclpGetWideClicks(); #endif if (middle >= stop) { break; @@ -4274,6 +4277,11 @@ usage: middle -= start; /* execution time in microsecs */ + #ifdef TCL_WIDE_CLICKS + /* convert execution time in wide clicks to microsecs */ + middle *= TclpWideClickInMicrosec(); + #endif + /* if not calibrate */ if (!calibrate) { /* minimize influence of measurement overhead */ diff --git a/generic/tclInt.h b/generic/tclInt.h index 1b37d84..fb0bcb7 100644 --- a/generic/tclInt.h +++ b/generic/tclInt.h @@ -3189,7 +3189,23 @@ MODULE_SCOPE void TclFinalizeThreadStorage(void); #ifdef TCL_WIDE_CLICKS MODULE_SCOPE Tcl_WideInt TclpGetWideClicks(void); MODULE_SCOPE double TclpWideClicksToNanoseconds(Tcl_WideInt clicks); +MODULE_SCOPE double TclpWideClickInMicrosec(void); +#else +# ifdef _WIN32 +# define TCL_WIDE_CLICKS 1 +MODULE_SCOPE Tcl_WideInt TclpGetWideClicks(void); +# define TclpWideClicksToNanoseconds(clicks) \ + ((double)(clicks) * 1000) +# define TclpWideClickInMicrosec() (1) +# endif #endif +#ifndef _WIN32 +MODULE_SCOPE Tcl_WideInt TclpGetMicroseconds(void); +#else +# define TclpGetMicroseconds() \ + TclpGetWideClicks() +#endif + MODULE_SCOPE int TclZlibInit(Tcl_Interp *interp); MODULE_SCOPE void * TclpThreadCreateKey(void); MODULE_SCOPE void TclpThreadDeleteKey(void *keyPtr); diff --git a/unix/tclUnixTime.c b/unix/tclUnixTime.c index d634449..8ec6e8a 100644 --- a/unix/tclUnixTime.c +++ b/unix/tclUnixTime.c @@ -84,6 +84,32 @@ TclpGetSeconds(void) /* *---------------------------------------------------------------------- * + * TclpGetMicroseconds -- + * + * This procedure returns the number of microseconds from the epoch. + * On most Unix systems the epoch is Midnight Jan 1, 1970 GMT. + * + * Results: + * Number of microseconds from the epoch. + * + * Side effects: + * None. + * + *---------------------------------------------------------------------- + */ + +Tcl_WideInt +TclpGetMicroseconds(void) +{ + Tcl_Time time; + + tclGetTimeProcPtr(&time, tclTimeClientData); + return ((Tcl_WideInt)time.sec)*1000000 + time.usec; +} + +/* + *---------------------------------------------------------------------- + * * TclpGetClicks -- * * This procedure returns a value that represents the highest resolution @@ -216,6 +242,51 @@ TclpWideClicksToNanoseconds( return nsec; } + +/* + *---------------------------------------------------------------------- + * + * TclpWideClickInMicrosec -- + * + * This procedure return scale to convert click values from the + * TclpGetWideClicks native resolution to microsecond resolution + * and back. + * + * Results: + * 1 click in microseconds as double. + * + * Side effects: + * None. + * + *---------------------------------------------------------------------- + */ + +double +TclpWideClickInMicrosec(void) +{ + if (tclGetTimeProcPtr != NativeGetTime) { + return 1.0; + } else { +#ifdef MAC_OSX_TCL + static int initialized = 0; + static double scale = 0.0; + + if (initialized) { + return scale; + } else { + mach_timebase_info_data_t tb; + + mach_timebase_info(&tb); + /* value of tb.numer / tb.denom = 1 click in nanoseconds */ + scale = ((double)tb.numer) / tb.denom / 1000; + initialized = 1; + return scale; + } +#else +#error Wide high-resolution clicks not implemented on this platform +#endif + } +} #endif /* TCL_WIDE_CLICKS */ /* diff --git a/win/tclWinTime.c b/win/tclWinTime.c index 81d9458..06ea6cd 100644 --- a/win/tclWinTime.c +++ b/win/tclWinTime.c @@ -123,6 +123,7 @@ static Tcl_WideInt AccumulateSample(Tcl_WideInt perfCounter, Tcl_WideUInt fileTime); static void NativeScaleTime(Tcl_Time* timebuf, ClientData clientData); +static Tcl_WideInt NativeGetMicroseconds(void); static void NativeGetTime(Tcl_Time* timebuf, ClientData clientData); @@ -154,10 +155,19 @@ ClientData tclTimeClientData = NULL; unsigned long TclpGetSeconds(void) { - Tcl_Time t; + Tcl_WideInt usecSincePosixEpoch; - tclGetTimeProcPtr(&t, tclTimeClientData); /* Tcl_GetTime inlined. */ - return t.sec; + /* Try to use high resolution timer */ + if ( tclGetTimeProcPtr == NativeGetTime + && (usecSincePosixEpoch = NativeGetMicroseconds()) + ) { + return usecSincePosixEpoch / 1000000; + } else { + Tcl_Time t; + + tclGetTimeProcPtr(&t, tclTimeClientData); /* Tcl_GetTime inlined. */ + return t.sec; + } } /* @@ -182,19 +192,66 @@ TclpGetSeconds(void) unsigned long TclpGetClicks(void) { - /* - * Use the Tcl_GetTime abstraction to get the time in microseconds, as - * nearly as we can, and return it. - */ + Tcl_WideInt usecSincePosixEpoch; - Tcl_Time now; /* Current Tcl time */ - unsigned long retval; /* Value to return */ + /* Try to use high resolution timer */ + if ( tclGetTimeProcPtr == NativeGetTime + && (usecSincePosixEpoch = NativeGetMicroseconds()) + ) { + return (unsigned long)usecSincePosixEpoch; + } else { + /* + * Use the Tcl_GetTime abstraction to get the time in microseconds, as + * nearly as we can, and return it. + */ - tclGetTimeProcPtr(&now, tclTimeClientData); /* Tcl_GetTime inlined */ + Tcl_Time now; /* Current Tcl time */ - retval = (now.sec * 1000000) + now.usec; - return retval; + tclGetTimeProcPtr(&now, tclTimeClientData); /* Tcl_GetTime inlined */ + return (unsigned long)(now.sec * 1000000) + now.usec; + } +} + +/* + *---------------------------------------------------------------------- + * + * TclpGetWideClicks -- + * + * This procedure returns a WideInt value that represents the highest + * resolution clock in microseconds available on the system. + * + * Results: + * Number of microseconds (from the epoch). + * + * Side effects: + * This should be used for time-delta resp. for measurement purposes + * only, because on some platforms can return microseconds from some + * start time (not from the epoch). + * + *---------------------------------------------------------------------- + */ + +Tcl_WideInt +TclpGetWideClicks(void) +{ + Tcl_WideInt usecSincePosixEpoch; + + /* Try to use high resolution timer */ + if ( tclGetTimeProcPtr == NativeGetTime + && (usecSincePosixEpoch = NativeGetMicroseconds()) + ) { + return usecSincePosixEpoch; + } else { + /* + * Use the Tcl_GetTime abstraction to get the time in microseconds, as + * nearly as we can, and return it. + */ + + Tcl_Time now; + tclGetTimeProcPtr(&now, tclTimeClientData); /* Tcl_GetTime inlined */ + return (((Tcl_WideInt)now.sec) * 1000000) + now.usec; + } } /* @@ -223,7 +280,17 @@ void Tcl_GetTime( Tcl_Time *timePtr) /* Location to store time information. */ { - tclGetTimeProcPtr(timePtr, tclTimeClientData); + Tcl_WideInt usecSincePosixEpoch; + + /* Try to use high resolution timer */ + if ( tclGetTimeProcPtr == NativeGetTime + && (usecSincePosixEpoch = NativeGetMicroseconds()) + ) { + timePtr->sec = (long) (usecSincePosixEpoch / 1000000); + timePtr->usec = (unsigned long) (usecSincePosixEpoch % 1000000); + } else { + tclGetTimeProcPtr(timePtr, tclTimeClientData); + } } /* @@ -256,13 +323,14 @@ NativeScaleTime( /* *---------------------------------------------------------------------- * - * NativeGetTime -- + * NativeGetMicroseconds -- * - * TIP #233: Gets the current system time in seconds and microseconds - * since the beginning of the epoch: 00:00 UCT, January 1, 1970. + * Gets the current system time in microseconds since the beginning + * of the epoch: 00:00 UCT, January 1, 1970. * * Results: - * Returns the current time in timePtr. + * Returns the wide integer with number of microseconds from the epoch, or + * 0 if high resolution timer is not available. * * Side effects: * On the first call, initializes a set of static variables to keep track @@ -275,13 +343,9 @@ NativeScaleTime( *---------------------------------------------------------------------- */ -static void -NativeGetTime( - Tcl_Time *timePtr, - ClientData clientData) +static Tcl_WideInt +NativeGetMicroseconds(void) { - struct _timeb t; - /* * Initialize static storage on the first trip through. * @@ -432,9 +496,7 @@ NativeGetTime( if (curCounter.QuadPart <= perfCounterLastCall.QuadPart) { usecSincePosixEpoch = (fileTimeLastCall.QuadPart - posixEpoch.QuadPart) / 10; - timePtr->sec = (long) (usecSincePosixEpoch / 1000000); - timePtr->usec = (unsigned long) (usecSincePosixEpoch % 1000000); - return; + return usecSincePosixEpoch; } /* @@ -455,19 +517,57 @@ NativeGetTime( * 10000000 / curCounterFreq.QuadPart); usecSincePosixEpoch = (curFileTime - posixEpoch.QuadPart) / 10; - timePtr->sec = (long) (usecSincePosixEpoch / 1000000); - timePtr->usec = (unsigned long) (usecSincePosixEpoch % 1000000); - return; + return usecSincePosixEpoch; } } /* - * High resolution timer is not available. Just use ftime. + * High resolution timer is not available. */ + return 0; +} + +/* + *---------------------------------------------------------------------- + * + * NativeGetTime -- + * + * TIP #233: Gets the current system time in seconds and microseconds + * since the beginning of the epoch: 00:00 UCT, January 1, 1970. + * + * Results: + * Returns the current time in timePtr. + * + * Side effects: + * See NativeGetMicroseconds for more information. + * + *---------------------------------------------------------------------- + */ - _ftime(&t); - timePtr->sec = (long)t.time; - timePtr->usec = t.millitm * 1000; +static void +NativeGetTime( + Tcl_Time *timePtr, + ClientData clientData) +{ + Tcl_WideInt usecSincePosixEpoch; + + /* + * Try to use high resolution timer. + */ + if ( (usecSincePosixEpoch = NativeGetMicroseconds()) ) { + timePtr->sec = (long) (usecSincePosixEpoch / 1000000); + timePtr->usec = (unsigned long) (usecSincePosixEpoch % 1000000); + } else { + /* + * High resolution timer is not available. Just use ftime. + */ + + struct _timeb t; + + _ftime(&t); + timePtr->sec = (long)t.time; + timePtr->usec = t.millitm * 1000; + } } /* -- cgit v0.12 From 8dde174dd4188f1b4d55f6d88a01a1d3887f507b Mon Sep 17 00:00:00 2001 From: sebres Date: Thu, 9 Feb 2017 13:45:14 +0000 Subject: =?UTF-8?q?[win]=20accomplished=20winTime=20module=20using=20very?= =?UTF-8?q?=20fast=20wide=20clicks,=20with=20denominator=20scale=20to/from?= =?UTF-8?q?=20microseconds,=20and=20therefore=20more=20precise=20"timerate?= =?UTF-8?q?"=20results=20under=20windows=20(using=20similar=20mechanisms?= =?UTF-8?q?=20as=20by=20Mac=20OSX).=20Especially=20multi-threaded,=20becau?= =?UTF-8?q?se=20it=20works=20without=20lock=20opposite=20to=20microseconds?= =?UTF-8?q?=20(that=20use=20crictical=20section,=20because=20of=20the=20ca?= =?UTF-8?q?libration=20thread).=20The=20reason=20for=20usage=20of=20wide?= =?UTF-8?q?=20clicks=20instead=20microseconds=20explains=20following=20exa?= =?UTF-8?q?mple=20(shows=2020%=20performance=20deference):=20%=20timerate?= =?UTF-8?q?=20-calibrate=20{}=20%=20timerate=20{clock=20microseconds}=2050?= =?UTF-8?q?00=200.297037=20=C2=B5s/#=2014465901=20#=203366585=20#/sec=2042?= =?UTF-8?q?96.906=20nett-ms=20%=20timerate=20{clock=20clicks}=205000=200.2?= =?UTF-8?q?47797=20=C2=B5s/#=2016869084=20#=204035554=20#/sec=204180.116?= =?UTF-8?q?=20nett-ms?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- generic/tclInt.h | 10 ++---- win/tclWinTime.c | 107 +++++++++++++++++++++++++++++++++++++++++++++++++++---- 2 files changed, 103 insertions(+), 14 deletions(-) diff --git a/generic/tclInt.h b/generic/tclInt.h index fb0bcb7..3c21de0 100644 --- a/generic/tclInt.h +++ b/generic/tclInt.h @@ -3186,6 +3186,7 @@ MODULE_SCOPE int TclpLoadMemory(Tcl_Interp *interp, void *buffer, MODULE_SCOPE void TclInitThreadStorage(void); MODULE_SCOPE void TclFinalizeThreadDataThread(void); MODULE_SCOPE void TclFinalizeThreadStorage(void); + #ifdef TCL_WIDE_CLICKS MODULE_SCOPE Tcl_WideInt TclpGetWideClicks(void); MODULE_SCOPE double TclpWideClicksToNanoseconds(Tcl_WideInt clicks); @@ -3194,17 +3195,12 @@ MODULE_SCOPE double TclpWideClickInMicrosec(void); # ifdef _WIN32 # define TCL_WIDE_CLICKS 1 MODULE_SCOPE Tcl_WideInt TclpGetWideClicks(void); +MODULE_SCOPE double TclpWideClickInMicrosec(void); # define TclpWideClicksToNanoseconds(clicks) \ - ((double)(clicks) * 1000) -# define TclpWideClickInMicrosec() (1) + ((double)(clicks) * TclpWideClickInMicrosec() * 1000) # endif #endif -#ifndef _WIN32 MODULE_SCOPE Tcl_WideInt TclpGetMicroseconds(void); -#else -# define TclpGetMicroseconds() \ - TclpGetWideClicks() -#endif MODULE_SCOPE int TclZlibInit(Tcl_Interp *interp); MODULE_SCOPE void * TclpThreadCreateKey(void); diff --git a/win/tclWinTime.c b/win/tclWinTime.c index 06ea6cd..7cbc1ba 100644 --- a/win/tclWinTime.c +++ b/win/tclWinTime.c @@ -110,6 +110,17 @@ static TimeInfo timeInfo = { }; /* + * Scale to convert wide click values from the TclpGetWideClicks native + * resolution to microsecond resolution and back. + */ +static struct { + int initialized; /* 1 if initialized, 0 otherwise */ + int perfCounter; /* 1 if performance counter usable for wide clicks */ + double microsecsScale; /* Denominator scale between clock / microsecs */ +} wideClick = {0, 0.0}; + + +/* * Declarations for functions defined later in this file. */ @@ -221,7 +232,7 @@ TclpGetClicks(void) * resolution clock in microseconds available on the system. * * Results: - * Number of microseconds (from the epoch). + * Number of microseconds (from some start time). * * Side effects: * This should be used for time-delta resp. for measurement purposes @@ -234,6 +245,87 @@ TclpGetClicks(void) Tcl_WideInt TclpGetWideClicks(void) { + LARGE_INTEGER curCounter; + + if (!wideClick.initialized) { + LARGE_INTEGER perfCounterFreq; + + /* + * The frequency of the performance counter is fixed at system boot and + * is consistent across all processors. Therefore, the frequency need + * only be queried upon application initialization. + */ + if (QueryPerformanceFrequency(&perfCounterFreq)) { + wideClick.perfCounter = 1; + wideClick.microsecsScale = 1000000.0 / perfCounterFreq.QuadPart; + } else { + /* fallback using microseconds */ + wideClick.perfCounter = 0; + wideClick.microsecsScale = 1; + } + + wideClick.initialized = 1; + } + if (wideClick.perfCounter) { + if (QueryPerformanceCounter(&curCounter)) { + return (Tcl_WideInt)curCounter.QuadPart; + } + /* fallback using microseconds */ + wideClick.perfCounter = 0; + wideClick.microsecsScale = 1; + return TclpGetMicroseconds(); + } else { + return TclpGetMicroseconds(); + } +} + +/* + *---------------------------------------------------------------------- + * + * TclpWideClickInMicrosec -- + * + * This procedure return scale to convert wide click values from the + * TclpGetWideClicks native resolution to microsecond resolution + * and back. + * + * Results: + * 1 click in microseconds as double. + * + * Side effects: + * None. + * + *---------------------------------------------------------------------- + */ + +double +TclpWideClickInMicrosec(void) +{ + if (!wideClick.initialized) { + (void)TclpGetWideClicks(); /* initialize */ + } + return wideClick.microsecsScale; +} + +/* + *---------------------------------------------------------------------- + * + * TclpGetMicroseconds -- + * + * This procedure returns a WideInt value that represents the highest + * resolution clock in microseconds available on the system. + * + * Results: + * Number of microseconds (from the epoch). + * + * Side effects: + * None. + * + *---------------------------------------------------------------------- + */ + +Tcl_WideInt +TclpGetMicroseconds(void) +{ Tcl_WideInt usecSincePosixEpoch; /* Try to use high resolution timer */ @@ -346,6 +438,9 @@ NativeScaleTime( static Tcl_WideInt NativeGetMicroseconds(void) { + static LARGE_INTEGER posixEpoch; + /* Posix epoch expressed as 100-ns ticks since + * the windows epoch. */ /* * Initialize static storage on the first trip through. * @@ -356,6 +451,10 @@ NativeGetMicroseconds(void) if (!timeInfo.initialized) { TclpInitLock(); if (!timeInfo.initialized) { + + posixEpoch.LowPart = 0xD53E8000; + posixEpoch.HighPart = 0x019DB1DE; + timeInfo.perfCounterAvailable = QueryPerformanceFrequency(&timeInfo.nominalFreq); @@ -468,15 +567,9 @@ NativeGetMicroseconds(void) /* Current performance counter. */ Tcl_WideInt curFileTime;/* Current estimated time, expressed as 100-ns * ticks since the Windows epoch. */ - static LARGE_INTEGER posixEpoch; - /* Posix epoch expressed as 100-ns ticks since - * the windows epoch. */ Tcl_WideInt usecSincePosixEpoch; /* Current microseconds since Posix epoch. */ - posixEpoch.LowPart = 0xD53E8000; - posixEpoch.HighPart = 0x019DB1DE; - QueryPerformanceCounter(&curCounter); /* -- cgit v0.12 From c77bd091dfde613bacdbbf0e013caeb016baf341 Mon Sep 17 00:00:00 2001 From: aspect Date: Sat, 11 Feb 2017 05:06:43 +0000 Subject: zlib stream finalize calls deflate with no input - this case (and this case only) must be allowed. Fixes 2nd issue in [25842c161f], introduced by [c1aff52ef3] --- generic/tclZlib.c | 4 ++-- tests/zlib.test | 12 ++++++++++++ 2 files changed, 14 insertions(+), 2 deletions(-) diff --git a/generic/tclZlib.c b/generic/tclZlib.c index e5a5946..82486d2 100644 --- a/generic/tclZlib.c +++ b/generic/tclZlib.c @@ -1204,10 +1204,10 @@ Tcl_ZlibStreamPut( zshPtr->stream.avail_in = size; /* - * Must not do a zero-length compress. [Bug 25842c161] + * Must not do a zero-length compress unless finalizing. [Bug 25842c161] */ - if (size == 0) { + if (size == 0 && flush != Z_FINISH) { return TCL_OK; } diff --git a/tests/zlib.test b/tests/zlib.test index ae8742b..3ee7a45 100644 --- a/tests/zlib.test +++ b/tests/zlib.test @@ -157,6 +157,18 @@ test zlib-7.8 {zlib stream: Bug b26e38a3e4} -constraints zlib -setup { catch {$strm close} unset -nocomplain randdata data } -result {120185 18003000} +test zlib-7.9 {zlib stream finalize (bug 25842c161)} -constraints zlib -setup { + set z1 [zlib stream gzip] + set z2 [zlib stream gzip] +} -body { + $z1 put ABCDEedbca.. + $z1 finalize + $z2 put -finalize ABCDEedbca.. + expr {[$z1 get] eq [$z2 get]} +} -cleanup { + $z1 close + $z2 close +} -result 1 test zlib-8.1 {zlib transformation} -constraints zlib -setup { set file [makeFile {} test.gz] -- cgit v0.12 From a638162ed46879635a4c454e2de32f13ea424632 Mon Sep 17 00:00:00 2001 From: aspect Date: Sat, 11 Feb 2017 07:18:08 +0000 Subject: better tests for finalization --- tests/zlib.test | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/tests/zlib.test b/tests/zlib.test index 3ee7a45..9497979 100644 --- a/tests/zlib.test +++ b/tests/zlib.test @@ -169,6 +169,30 @@ test zlib-7.9 {zlib stream finalize (bug 25842c161)} -constraints zlib -setup { $z1 close $z2 close } -result 1 +test zlib-7.9.1 {zlib stream put -finalize (bug 25842c161)} -constraints zlib -setup { + set c [zlib stream gzip] + set d [zlib stream gunzip] +} -body { + $c put abcdeEDCBA.. + $c finalize + $d put [$c get] + $d finalize + $d get +} -cleanup { + $c close + $d close +} -result abcdeEDCBA.. +test zlib-7.9.2 {zlib stream put; zlib stream finalize (bug 25842c161)} -constraints zlib -setup { + set c [zlib stream gzip] + set d [zlib stream gunzip] +} -body { + $c put -finalize abcdeEDCBA.. + $d put -finalize [$c get] + $d get +} -cleanup { + $c close + $d close +} -result abcdeEDCBA.. test zlib-8.1 {zlib transformation} -constraints zlib -setup { set file [makeFile {} test.gz] -- cgit v0.12 From efa3ec69393a1dee51e76e848dbe10ebaa55603e Mon Sep 17 00:00:00 2001 From: dkf Date: Sat, 11 Feb 2017 21:36:36 +0000 Subject: Proposed implementation of [regsub -command]. --- generic/tclCmdMZ.c | 82 +++++++++++++++++++++++++++++++++++++++++++++++---- tests/regexp.test | 22 +++++++++++++- tests/regexpComp.test | 2 +- 3 files changed, 98 insertions(+), 8 deletions(-) diff --git a/generic/tclCmdMZ.c b/generic/tclCmdMZ.c index ba1fc41..ffae8b2 100644 --- a/generic/tclCmdMZ.c +++ b/generic/tclCmdMZ.c @@ -487,26 +487,28 @@ Tcl_RegsubObjCmd( Tcl_Obj *const objv[]) /* Argument objects. */ { int idx, result, cflags, all, wlen, wsublen, numMatches, offset; - int start, end, subStart, subEnd, match; + int start, end, subStart, subEnd, match, command; Tcl_RegExp regExpr; Tcl_RegExpInfo info; Tcl_Obj *resultPtr, *subPtr, *objPtr, *startIndex = NULL; + Tcl_Obj **args = NULL, *parts[2], *cmdObj; Tcl_UniChar ch, *wsrc, *wfirstChar, *wstring, *wsubspec, *wend; static const char *const options[] = { - "-all", "-nocase", "-expanded", - "-line", "-linestop", "-lineanchor", "-start", + "-all", "-command", "-expanded", "-line", + "-linestop", "-lineanchor", "-nocase", "-start", "--", NULL }; enum options { - REGSUB_ALL, REGSUB_NOCASE, REGSUB_EXPANDED, - REGSUB_LINE, REGSUB_LINESTOP, REGSUB_LINEANCHOR, REGSUB_START, + REGSUB_ALL, REGSUB_COMMAND, REGSUB_EXPANDED, REGSUB_LINE, + REGSUB_LINESTOP, REGSUB_LINEANCHOR, REGSUB_NOCASE, REGSUB_START, REGSUB_LAST }; cflags = TCL_REG_ADVANCED; all = 0; offset = 0; + command = 0; resultPtr = NULL; for (idx = 1; idx < objc; idx++) { @@ -528,6 +530,9 @@ Tcl_RegsubObjCmd( case REGSUB_NOCASE: cflags |= TCL_REG_NOCASE; break; + case REGSUB_COMMAND: + command = 1; + break; case REGSUB_EXPANDED: cflags |= TCL_REG_EXPANDED; break; @@ -585,7 +590,7 @@ Tcl_RegsubObjCmd( } } - if (all && (offset == 0) + if (all && (offset == 0) && (command == 0) && (strpbrk(TclGetString(objv[2]), "&\\") == NULL) && (strpbrk(TclGetString(objv[0]), "*+?{}()[].\\|^$") == NULL)) { /* @@ -737,6 +742,68 @@ Tcl_RegsubObjCmd( Tcl_AppendUnicodeToObj(resultPtr, wstring + offset, start); /* + * In -command mode, the substitutions are added as quoted arguments + * to the subSpec to form a command, that is then executed and the + * result used as the string to substitute in. + */ + + if (command) { + if (args == NULL) { + args = ckalloc(sizeof(Tcl_Obj*) * (info.nsubs + 1)); + } + + for (idx = 0 ; idx <= info.nsubs ; idx++) { + subStart = info.matches[idx].start; + subEnd = info.matches[idx].end; + if ((subStart >= 0) && (subEnd >= 0)) { + args[idx] = Tcl_NewUnicodeObj( + wstring + offset + subStart, subEnd - subStart); + } else { + args[idx] = Tcl_NewObj(); + } + } + parts[0] = subPtr; + parts[1] = Tcl_NewListObj(info.nsubs+1, args); + cmdObj = Tcl_ConcatObj(2, parts); + Tcl_IncrRefCount(cmdObj); + Tcl_DecrRefCount(parts[1]); + + result = Tcl_EvalObjEx(interp, cmdObj, TCL_EVAL_DIRECT); + Tcl_DecrRefCount(cmdObj); + if (result != TCL_OK) { + if (result == TCL_ERROR) { + Tcl_AppendObjToErrorInfo(interp, Tcl_ObjPrintf( + "\n (%s substitution computation script)", + options[REGSUB_COMMAND])); + } + goto done; + } + + Tcl_AppendObjToObj(resultPtr, Tcl_GetObjResult(interp)); + Tcl_ResetResult(interp); + + offset += end; + if (end == 0 || start == end) { + /* + * Always consume at least one character of the input string + * in order to prevent infinite loops, even when we + * technically matched the empty string; we must not match + * again at the same spot. + */ + + if (offset < wlen) { + Tcl_AppendUnicodeToObj(resultPtr, wstring + offset, 1); + } + offset++; + } + if (all) { + continue; + } else { + break; + } + } + + /* * Append the subSpec argument to the variable, making appropriate * substitutions. This code is a bit hairy because of the backslash * conventions and because the code saves up ranges of characters in @@ -864,6 +931,9 @@ Tcl_RegsubObjCmd( if (subPtr && (objv[2] == objv[0])) { Tcl_DecrRefCount(subPtr); } + if (args) { + ckfree(args); + } if (resultPtr) { Tcl_DecrRefCount(resultPtr); } diff --git a/tests/regexp.test b/tests/regexp.test index 4ffdbdb..6c77b41 100644 --- a/tests/regexp.test +++ b/tests/regexp.test @@ -453,7 +453,7 @@ test regexp-11.4 {regsub errors} { } {1 {wrong # args: should be "regsub ?-option ...? exp string subSpec ?varName?"}} test regexp-11.5 {regsub errors} { list [catch {regsub -gorp a b c} msg] $msg -} {1 {bad option "-gorp": must be -all, -nocase, -expanded, -line, -linestop, -lineanchor, -start, or --}} +} {1 {bad option "-gorp": must be -all, -command, -expanded, -line, -linestop, -lineanchor, -nocase, -start, or --}} test regexp-11.6 {regsub errors} { list [catch {regsub -nocase a( b c d} msg] $msg } {1 {couldn't compile regular expression pattern: parentheses () not balanced}} @@ -1123,6 +1123,26 @@ test regexp-26.12 {regexp with -line option} { test regexp-26.13 {regexp without -line option} { regexp -all -inline -- {a*} "b\n" } {{} {}} + +test regexp-27.1 {regsub -command} { + regsub -command {.x.} {abcxdef} {string length} +} ab3ef +test regexp-27.2 {regsub -command} { + regsub -command {.x.} {abcxdefxghi} {string length} +} ab3efxghi +test regexp-27.3 {regsub -command} { + set x 0 + regsub -all -command {(?=.)} abcde "incr x;#" +} 1a2b3c4d5e +test regexp-27.4 {regsub -command} -body { + regsub -command {.x.} {abcxdef} error +} -returnCodes error -result cxd +test regexp-27.5 {regsub -command} { + regsub -command {(.)(.)} {abcdef} {list ,} +} {, ab a bcdef} +test regexp-27.6 {regsub -command} { + regsub -command -all {(.)(.)} {abcdef} {list ,} +} {, ab a b, cd c d, ef e f} # cleanup ::tcltest::cleanupTests diff --git a/tests/regexpComp.test b/tests/regexpComp.test index b8e64b6..fbf8012 100644 --- a/tests/regexpComp.test +++ b/tests/regexpComp.test @@ -587,7 +587,7 @@ test regexpComp-11.5 {regsub errors} { evalInProc { list [catch {regsub -gorp a b c} msg] $msg } -} {1 {bad option "-gorp": must be -all, -nocase, -expanded, -line, -linestop, -lineanchor, -start, or --}} +} {1 {bad option "-gorp": must be -all, -command, -expanded, -line, -linestop, -lineanchor, -nocase, -start, or --}} test regexpComp-11.6 {regsub errors} { evalInProc { list [catch {regsub -nocase a( b c d} msg] $msg -- cgit v0.12 From c8646e5c72e90d6e78802f41ce39fa603e32e6b3 Mon Sep 17 00:00:00 2001 From: aspect Date: Sun, 12 Feb 2017 12:57:29 +0000 Subject: fix chan leak with http keepalive vs close (bug [6ca52aec14]) --- library/http/http.tcl | 7 ++++--- tests/http.test | 8 ++++++++ 2 files changed, 12 insertions(+), 3 deletions(-) diff --git a/library/http/http.tcl b/library/http/http.tcl index ccd4cd1..19799b9 100644 --- a/library/http/http.tcl +++ b/library/http/http.tcl @@ -197,9 +197,10 @@ proc http::Finish {token {errormsg ""} {skipCB 0}} { set state(error) [list $errormsg $errorInfo $errorCode] set state(status) "error" } - if { - ($state(status) eq "timeout") || ($state(status) eq "error") || - ([info exists state(connection)] && ($state(connection) eq "close")) + if { ($state(status) eq "timeout") + || ($state(status) eq "error") + || ([info exists state(-keepalive)] && !$state(-keepalive)) + || ([info exists state(connection)] && ($state(connection) eq "close")) } { CloseSocket $state(sock) $token } diff --git a/tests/http.test b/tests/http.test index 12ad475..d7e42c2 100644 --- a/tests/http.test +++ b/tests/http.test @@ -592,6 +592,14 @@ test http-4.15 {http::Event} -body { } -cleanup { catch {http::cleanup $token} } -returnCodes 1 -match glob -result "couldn't open socket*" +test http-1.15 {Leak with Close vs Keepalive (bug [6ca52aec14]} -body { + set before [chan names] + set token [http::geturl $url -headers {X-Connection keep-alive}] + http::cleanup $token + update + set after [chan names] + expr {$before eq $after} +} -result 1 test http-5.1 {http::formatQuery} { http::formatQuery name1 value1 name2 "value two" -- cgit v0.12 From a13289725c7144cf1453ac5a3674bf763450872c Mon Sep 17 00:00:00 2001 From: "jan.nijtmans" Date: Tue, 14 Feb 2017 14:25:08 +0000 Subject: On Windows, Cygwin and 64-bit platforms, no need to handle 'long' in tclLink.c, since its size is equal to either 'int' or 'Tcl_WideInt'. This enhances interoperabilty between win64 extensions loaded in cygwin64 using Tcl_LinkVar(), whill still being 100% compatible. init.tcl: unnecessary spacing. --- generic/tcl.h | 5 +++++ generic/tclLink.c | 16 ++++++++++++++++ library/init.tcl | 4 ++-- 3 files changed, 23 insertions(+), 2 deletions(-) diff --git a/generic/tcl.h b/generic/tcl.h index c0cee27..d678229 100644 --- a/generic/tcl.h +++ b/generic/tcl.h @@ -1147,8 +1147,13 @@ typedef struct Tcl_DString { #define TCL_LINK_SHORT 8 #define TCL_LINK_USHORT 9 #define TCL_LINK_UINT 10 +#if defined(TCL_WIDE_INT_IS_LONG) || defined(_WIN32) || defined(__CYGWIN__) +#define TCL_LINK_LONG ((sizeof(long) != sizeof(int)) ? TCL_LINK_WIDE_INT : TCL_LINK_INT) +#define TCL_LINK_ULONG ((sizeof(long) != sizeof(int)) ? TCL_LINK_WIDE_UINT : TCL_LINK_UINT) +#else #define TCL_LINK_LONG 11 #define TCL_LINK_ULONG 12 +#endif #define TCL_LINK_FLOAT 13 #define TCL_LINK_WIDE_UINT 14 #define TCL_LINK_READ_ONLY 0x80 diff --git a/generic/tclLink.c b/generic/tclLink.c index 1507804..a39dfcd 100644 --- a/generic/tclLink.c +++ b/generic/tclLink.c @@ -36,8 +36,10 @@ typedef struct Link { unsigned int ui; short s; unsigned short us; +#if !defined(TCL_WIDE_INT_IS_LONG) && !defined(_WIN32) && !defined(__CYGWIN__) long l; unsigned long ul; +#endif Tcl_WideInt w; Tcl_WideUInt uw; float f; @@ -129,6 +131,14 @@ Tcl_LinkVar( Tcl_IncrRefCount(linkPtr->varName); linkPtr->addr = addr; linkPtr->type = type & ~TCL_LINK_READ_ONLY; +#if !defined(TCL_NO_DEPRECATED) && (defined(TCL_WIDE_INT_IS_LONG) \ + || defined(_WIN32) || defined(__CYGWIN__)) + if (linkPtr->type == 11 /* legacy TCL_LINK_LONG */) { + linkPtr->type = TCL_LINK_LONG; + } else if (linkPtr->type == 12 /* legacy TCL_LINK_ULONG */) { + linkPtr->type = TCL_LINK_ULONG; + } +#endif if (type & TCL_LINK_READ_ONLY) { linkPtr->flags = LINK_READ_ONLY; } else { @@ -335,12 +345,14 @@ LinkTraceProc( case TCL_LINK_UINT: changed = (LinkedVar(unsigned int) != linkPtr->lastValue.ui); break; +#if !defined(TCL_WIDE_INT_IS_LONG) && !defined(_WIN32) && !defined(__CYGWIN__) case TCL_LINK_LONG: changed = (LinkedVar(long) != linkPtr->lastValue.l); break; case TCL_LINK_ULONG: changed = (LinkedVar(unsigned long) != linkPtr->lastValue.ul); break; +#endif case TCL_LINK_FLOAT: changed = (LinkedVar(float) != linkPtr->lastValue.f); break; @@ -483,6 +495,7 @@ LinkTraceProc( LinkedVar(unsigned int) = linkPtr->lastValue.ui = (unsigned int)valueWide; break; +#if !defined(TCL_WIDE_INT_IS_LONG) && !defined(_WIN32) && !defined(__CYGWIN__) case TCL_LINK_LONG: if ((Tcl_GetWideIntFromObj(NULL, valueObj, &valueWide) != TCL_OK && GetInvalidWideFromObj(valueObj, &valueWide) != TCL_OK) @@ -504,6 +517,7 @@ LinkTraceProc( } LinkedVar(unsigned long) = linkPtr->lastValue.ul = (unsigned long)valueWide; break; +#endif case TCL_LINK_WIDE_UINT: /* @@ -597,12 +611,14 @@ ObjValue( case TCL_LINK_UINT: linkPtr->lastValue.ui = LinkedVar(unsigned int); return Tcl_NewWideIntObj((Tcl_WideInt) linkPtr->lastValue.ui); +#if !defined(TCL_WIDE_INT_IS_LONG) && !defined(_WIN32) && !defined(__CYGWIN__) case TCL_LINK_LONG: linkPtr->lastValue.l = LinkedVar(long); return Tcl_NewWideIntObj((Tcl_WideInt) linkPtr->lastValue.l); case TCL_LINK_ULONG: linkPtr->lastValue.ul = LinkedVar(unsigned long); return Tcl_NewWideIntObj((Tcl_WideInt) linkPtr->lastValue.ul); +#endif case TCL_LINK_FLOAT: linkPtr->lastValue.f = LinkedVar(float); return Tcl_NewDoubleObj(linkPtr->lastValue.f); diff --git a/library/init.tcl b/library/init.tcl index 49a523c..fac1722 100644 --- a/library/init.tcl +++ b/library/init.tcl @@ -470,9 +470,9 @@ proc auto_load {cmd {namespace {}}} { proc ::tcl::Pkg::source {filename} { if {[interp issafe]} { - uplevel 1 [list ::source $filename] + uplevel 1 [list ::source $filename] } else { - uplevel 1 [list ::source -nopkg $filename] + uplevel 1 [list ::source -nopkg $filename] } } -- cgit v0.12 From 462ffc792711dc33c7d17b48fc3bdb65bee277de Mon Sep 17 00:00:00 2001 From: "jan.nijtmans" Date: Wed, 15 Feb 2017 14:04:15 +0000 Subject: More internal use of size_t in stead of int, e.g. for epoch's --- generic/tclBasic.c | 2 +- generic/tclCompile.h | 2 +- generic/tclEnsemble.c | 2 +- generic/tclIO.c | 2 +- generic/tclIO.h | 2 +- generic/tclInt.h | 12 ++++++------ generic/tclObj.c | 6 +++--- 7 files changed, 14 insertions(+), 14 deletions(-) diff --git a/generic/tclBasic.c b/generic/tclBasic.c index 63c5590..6ff5faa 100644 --- a/generic/tclBasic.c +++ b/generic/tclBasic.c @@ -4705,7 +4705,7 @@ TEOV_RunEnterTraces( { Interp *iPtr = (Interp *) interp; Command *cmdPtr = *cmdPtrPtr; - int newEpoch, cmdEpoch = cmdPtr->cmdEpoch; + size_t newEpoch, cmdEpoch = cmdPtr->cmdEpoch; int length, traceCode = TCL_OK; const char *command = TclGetStringFromObj(commandPtr, &length); diff --git a/generic/tclCompile.h b/generic/tclCompile.h index 5ef154e..5bc3e81 100644 --- a/generic/tclCompile.h +++ b/generic/tclCompile.h @@ -425,7 +425,7 @@ typedef struct ByteCode { * compiled. If the code is executed if a * different namespace, it must be * recompiled. */ - int nsEpoch; /* Value of nsPtr->resolverEpoch when this + size_t nsEpoch; /* Value of nsPtr->resolverEpoch when this * ByteCode was compiled. Used to invalidate * code when new namespace resolution rules * are put into effect. */ diff --git a/generic/tclEnsemble.c b/generic/tclEnsemble.c index 6ada155..f3e8187 100644 --- a/generic/tclEnsemble.c +++ b/generic/tclEnsemble.c @@ -92,7 +92,7 @@ static const Tcl_ObjType ensembleCmdType = { */ typedef struct { - int epoch; /* Used to confirm when the data in this + size_t epoch; /* Used to confirm when the data in this * really structure matches up with the * ensemble. */ Command *token; /* Reference to the command for which this diff --git a/generic/tclIO.c b/generic/tclIO.c index 506e6d5..6bf8451 100644 --- a/generic/tclIO.c +++ b/generic/tclIO.c @@ -321,7 +321,7 @@ static int WillRead(Channel *chanPtr); typedef struct ResolvedChanName { ChannelState *statePtr; /* The saved lookup result */ Tcl_Interp *interp; /* The interp in which the lookup was done. */ - int epoch; /* The epoch of the channel when the lookup + size_t epoch; /* The epoch of the channel when the lookup * was done. Use to verify validity. */ size_t refCount; /* Share this struct among many Tcl_Obj. */ } ResolvedChanName; diff --git a/generic/tclIO.h b/generic/tclIO.h index ffbfa31..07c54fa 100644 --- a/generic/tclIO.h +++ b/generic/tclIO.h @@ -214,7 +214,7 @@ typedef struct ChannelState { * because it happened in the background. The * value is the chanMg, if any. #219's * companion to 'unreportedError'. */ - int epoch; /* Used to test validity of stored channelname + size_t epoch; /* Used to test validity of stored channelname * lookup results. */ } ChannelState; diff --git a/generic/tclInt.h b/generic/tclInt.h index 4b87962..f078d18 100644 --- a/generic/tclInt.h +++ b/generic/tclInt.h @@ -265,7 +265,7 @@ typedef struct Namespace { * strings; values have type (Namespace *). If * NULL, there are no children. */ #endif - long nsId; /* Unique id for the namespace. */ + size_t nsId; /* Unique id for the namespace. */ Tcl_Interp *interp; /* The interpreter containing this * namespace. */ int flags; /* OR-ed combination of the namespace status @@ -299,12 +299,12 @@ typedef struct Namespace { * registered using "namespace export". */ int maxExportPatterns; /* Mumber of export patterns for which space * is currently allocated. */ - int cmdRefEpoch; /* Incremented if a newly added command + size_t cmdRefEpoch; /* Incremented if a newly added command * shadows a command for which this namespace * has already cached a Command* pointer; this * causes all its cached Command* pointers to * be invalidated. */ - int resolverEpoch; /* Incremented whenever (a) the name + size_t resolverEpoch; /* Incremented whenever (a) the name * resolution rules change for this namespace * or (b) a newly added command shadows a * command that is compiled to bytecodes. This @@ -331,7 +331,7 @@ typedef struct Namespace { * LookupCompiledLocal to resolve variable * references within the namespace at compile * time. */ - int exportLookupEpoch; /* Incremented whenever a command is added to + size_t exportLookupEpoch; /* Incremented whenever a command is added to * a namespace, removed from a namespace or * the exports of a namespace are changed. * Allows TIP#112-driven command lists to be @@ -432,7 +432,7 @@ typedef struct EnsembleConfig { * if the command has been deleted (or never * existed; the global namespace never has an * ensemble command.) */ - int epoch; /* The epoch at which this ensemble's table of + size_t epoch; /* The epoch at which this ensemble's table of * exported commands is valid. */ char **subcommandArrayPtr; /* Array of ensemble subcommand names. At all * consistent points, this will have the same @@ -1639,7 +1639,7 @@ typedef struct Command { * representing a command's name in a ByteCode * instruction sequence. This structure can be * freed when refCount becomes zero. */ - int cmdEpoch; /* Incremented to invalidate any references + size_t cmdEpoch; /* Incremented to invalidate any references * that point to this command when it is * renamed, deleted, hidden, or exposed. */ CompileProc *compileProc; /* Procedure called to compile command. NULL diff --git a/generic/tclObj.c b/generic/tclObj.c index 1abbb31..7ec259f 100644 --- a/generic/tclObj.c +++ b/generic/tclObj.c @@ -344,17 +344,17 @@ typedef struct ResolvedCmdName { * reference (not the namespace that contains * the referenced command). NULL if the name * is fully qualified.*/ - long refNsId; /* refNsPtr's unique namespace id. Used to + size_t refNsId; /* refNsPtr's unique namespace id. Used to * verify that refNsPtr is still valid (e.g., * it's possible that the cmd's containing * namespace was deleted and a new one created * at the same address). */ - int refNsCmdEpoch; /* Value of the referencing namespace's + size_t refNsCmdEpoch; /* Value of the referencing namespace's * cmdRefEpoch when the pointer was cached. * Before using the cached pointer, we check * if the namespace's epoch was incremented; * if so, this cached pointer is invalid. */ - int cmdEpoch; /* Value of the command's cmdEpoch when this + size_t cmdEpoch; /* Value of the command's cmdEpoch when this * pointer was cached. Before using the cached * pointer, we check if the cmd's epoch was * incremented; if so, the cmd was renamed, -- cgit v0.12 From 3ef7160d4155e52cf26b62290674100b34243e00 Mon Sep 17 00:00:00 2001 From: dkf Date: Fri, 17 Feb 2017 06:08:18 +0000 Subject: Switch to using command prefixes properly. This is quite a bit faster. --- generic/tclCmdMZ.c | 63 +++++++++++++++++++++++++++++++++++++++--------------- tests/regexp.test | 2 +- 2 files changed, 47 insertions(+), 18 deletions(-) diff --git a/generic/tclCmdMZ.c b/generic/tclCmdMZ.c index ffae8b2..d6d0152 100644 --- a/generic/tclCmdMZ.c +++ b/generic/tclCmdMZ.c @@ -487,11 +487,11 @@ Tcl_RegsubObjCmd( Tcl_Obj *const objv[]) /* Argument objects. */ { int idx, result, cflags, all, wlen, wsublen, numMatches, offset; - int start, end, subStart, subEnd, match, command; + int start, end, subStart, subEnd, match, command, numParts, numArgs; Tcl_RegExp regExpr; Tcl_RegExpInfo info; Tcl_Obj *resultPtr, *subPtr, *objPtr, *startIndex = NULL; - Tcl_Obj **args = NULL, *parts[2], *cmdObj; + Tcl_Obj **args = NULL, **parts; Tcl_UniChar ch, *wsrc, *wfirstChar, *wstring, *wsubspec, *wend; static const char *const options[] = { @@ -666,6 +666,20 @@ Tcl_RegsubObjCmd( return TCL_ERROR; } + if (command) { + /* + * In command-prefix mode, we require that the third non-option + * argument be a list, so we enforce that here. Afterwards, we fetch + * the RE compilation again in case objv[0] and objv[2] are the same + * object. (If they aren't, that's cheap to do.) + */ + + if (Tcl_ListObjLength(interp, objv[2], &numParts) != TCL_OK) { + return TCL_ERROR; + } + regExpr = Tcl_GetRegExpFromObj(interp, objv[0], cflags); + } + /* * Make sure to avoid problems where the objects are shared. This can * cause RegExpObj <> UnicodeObj shimmering that causes data corruption. @@ -683,7 +697,9 @@ Tcl_RegsubObjCmd( } else { subPtr = objv[2]; } - wsubspec = Tcl_GetUnicodeFromObj(subPtr, &wsublen); + if (!command) { + wsubspec = Tcl_GetUnicodeFromObj(subPtr, &wsublen); + } result = TCL_OK; @@ -742,34 +758,47 @@ Tcl_RegsubObjCmd( Tcl_AppendUnicodeToObj(resultPtr, wstring + offset, start); /* - * In -command mode, the substitutions are added as quoted arguments - * to the subSpec to form a command, that is then executed and the - * result used as the string to substitute in. + * In command-prefix mode, the substitutions are added as quoted + * arguments to the subSpec to form a command, that is then executed + * and the result used as the string to substitute in. Actually, + * everything is passed through Tcl_EvalObjv, as that's much faster. */ if (command) { if (args == NULL) { - args = ckalloc(sizeof(Tcl_Obj*) * (info.nsubs + 1)); + Tcl_ListObjGetElements(interp, subPtr, &numParts, &parts); + numArgs = numParts + info.nsubs + 1; + args = ckalloc(sizeof(Tcl_Obj*) * numArgs); + memcpy(args, parts, sizeof(Tcl_Obj*) * numParts); } for (idx = 0 ; idx <= info.nsubs ; idx++) { subStart = info.matches[idx].start; subEnd = info.matches[idx].end; if ((subStart >= 0) && (subEnd >= 0)) { - args[idx] = Tcl_NewUnicodeObj( + args[idx + numParts] = Tcl_NewUnicodeObj( wstring + offset + subStart, subEnd - subStart); } else { - args[idx] = Tcl_NewObj(); + args[idx + numParts] = Tcl_NewObj(); } + Tcl_IncrRefCount(args[idx + numParts]); + } + + /* + * At this point, we're locally holding the references to the + * argument words we added for this time round the loop, and the + * subPtr is holding the references to the words that the user + * supplied directly. None are zero-refcount, which is important + * because Tcl_EvalObjv is "hairy monster" in terms of refcount + * handling, being able to optionally add references to any of its + * argument words. We'll drop the local refs immediately + * afterwarsds; subPtr is handled in the main exit stanza. + */ + + result = Tcl_EvalObjv(interp, numArgs, args, 0); + for (idx = 0 ; idx <= info.nsubs ; idx++) { + TclDecrRefCount(args[idx + numParts]); } - parts[0] = subPtr; - parts[1] = Tcl_NewListObj(info.nsubs+1, args); - cmdObj = Tcl_ConcatObj(2, parts); - Tcl_IncrRefCount(cmdObj); - Tcl_DecrRefCount(parts[1]); - - result = Tcl_EvalObjEx(interp, cmdObj, TCL_EVAL_DIRECT); - Tcl_DecrRefCount(cmdObj); if (result != TCL_OK) { if (result == TCL_ERROR) { Tcl_AppendObjToErrorInfo(interp, Tcl_ObjPrintf( diff --git a/tests/regexp.test b/tests/regexp.test index 6c77b41..6c3d774 100644 --- a/tests/regexp.test +++ b/tests/regexp.test @@ -1132,7 +1132,7 @@ test regexp-27.2 {regsub -command} { } ab3efxghi test regexp-27.3 {regsub -command} { set x 0 - regsub -all -command {(?=.)} abcde "incr x;#" + regsub -all -command {(?=.)} abcde {apply {args {incr ::x}}} } 1a2b3c4d5e test regexp-27.4 {regsub -command} -body { regsub -command {.x.} {abcxdef} error -- cgit v0.12 From 5772e32729279c7caac6968a62a65e0eb3550eb4 Mon Sep 17 00:00:00 2001 From: dkf Date: Fri, 17 Feb 2017 09:20:49 +0000 Subject: Stop problems with representation smashes. --- generic/tclCmdMZ.c | 7 +++++++ tests/regexp.test | 6 ++++++ 2 files changed, 13 insertions(+) diff --git a/generic/tclCmdMZ.c b/generic/tclCmdMZ.c index d6d0152..110de4c 100644 --- a/generic/tclCmdMZ.c +++ b/generic/tclCmdMZ.c @@ -811,6 +811,13 @@ Tcl_RegsubObjCmd( Tcl_AppendObjToObj(resultPtr, Tcl_GetObjResult(interp)); Tcl_ResetResult(interp); + /* + * Refetch the unicode, in case the representation was smashed by + * the user code. + */ + + wstring = Tcl_GetUnicodeFromObj(objPtr, &wlen); + offset += end; if (end == 0 || start == end) { /* diff --git a/tests/regexp.test b/tests/regexp.test index 6c3d774..ad770fa 100644 --- a/tests/regexp.test +++ b/tests/regexp.test @@ -1143,6 +1143,12 @@ test regexp-27.5 {regsub -command} { test regexp-27.6 {regsub -command} { regsub -command -all {(.)(.)} {abcdef} {list ,} } {, ab a b, cd c d, ef e f} +test regexp-27.7 {regsub -command representation smash} { + set ::s {123=456 789} + regsub -command -all {\d+} $::s {apply {n { + expr {[llength $::s] + $n} + }}} +} {125=458 791} # cleanup ::tcltest::cleanupTests -- cgit v0.12 From 82296abf086a1bc70975fe726a9887fe102b0330 Mon Sep 17 00:00:00 2001 From: dkf Date: Sat, 18 Feb 2017 14:26:34 +0000 Subject: Add more representation smashing testing and a memleak test. --- tests/regexp.test | 29 +++++++++++++++++++++++++++++ 1 file changed, 29 insertions(+) diff --git a/tests/regexp.test b/tests/regexp.test index ad770fa..f1be6eb 100644 --- a/tests/regexp.test +++ b/tests/regexp.test @@ -19,6 +19,20 @@ if {"::tcltest" ni [namespace children]} { unset -nocomplain foo testConstraint exec [llength [info commands exec]] + +# Used for constraining memory leak tests +testConstraint memory [llength [info commands memory]] +if {[testConstraint memory]} { + proc memtest script { + set end [lindex [split [memory info] \n] 3 3] + for {set i 0} {$i < 5} {incr i} { + uplevel 1 $script + set tmp $end + set end [lindex [split [memory info] \n] 3 3] + } + expr {$end - $tmp} + } +} test regexp-1.1 {basic regexp operation} { regexp ab*c abbbc @@ -1149,6 +1163,21 @@ test regexp-27.7 {regsub -command representation smash} { expr {[llength $::s] + $n} }}} } {125=458 791} +test regexp-27.8 {regsub -command representation smash} { + set ::t {apply {n { + expr {[llength [lindex $::t 1 1 1]] + $n} + }}} + regsub -command -all {\d+} "123=456 789" $::t +} {131=464 797} +test regexp-27.9 {regsub -command memory leak testing} memory { + set ::s "123=456 789" + set ::t {apply {n { + expr {[llength [lindex $::t 1 1 1]] + [llength $::s] + $n} + }}} + memtest { + regsub -command -all {\d+} $::s $::t + } +} 0 # cleanup ::tcltest::cleanupTests -- cgit v0.12 From d18329a21ef2b1a00069fd1be86bd9062a97f4cd Mon Sep 17 00:00:00 2001 From: dkf Date: Sat, 18 Feb 2017 16:24:09 +0000 Subject: Testing for some error cases. --- generic/tclCmdMZ.c | 8 ++++++++ tests/regexp.test | 6 ++++++ 2 files changed, 14 insertions(+) diff --git a/generic/tclCmdMZ.c b/generic/tclCmdMZ.c index 110de4c..d5a6b01 100644 --- a/generic/tclCmdMZ.c +++ b/generic/tclCmdMZ.c @@ -677,6 +677,14 @@ Tcl_RegsubObjCmd( if (Tcl_ListObjLength(interp, objv[2], &numParts) != TCL_OK) { return TCL_ERROR; } + if (numParts < 1) { + Tcl_SetObjResult(interp, Tcl_NewStringObj( + "command prefix must be a list of at least one element", + -1)); + Tcl_SetErrorCode(interp, "TCL", "OPERATION", "REGSUB", + "CMDEMPTY", NULL); + return TCL_ERROR; + } regExpr = Tcl_GetRegExpFromObj(interp, objv[0], cflags); } diff --git a/tests/regexp.test b/tests/regexp.test index f1be6eb..2686526 100644 --- a/tests/regexp.test +++ b/tests/regexp.test @@ -1178,6 +1178,12 @@ test regexp-27.9 {regsub -command memory leak testing} memory { regsub -command -all {\d+} $::s $::t } } 0 +test regexp-27.10 {regsub -command error cases} -returnCodes error -body { + regsub -command . abc "def \{ghi" +} -result {unmatched open brace in list} +test regexp-27.11 {regsub -command error cases} -returnCodes error -body { + regsub -command . abc {} +} -result {command prefix must be a list of at least one element} # cleanup ::tcltest::cleanupTests -- cgit v0.12 From 874b8643e02da9a44cbed7f908d260f372420946 Mon Sep 17 00:00:00 2001 From: dkf Date: Sat, 18 Feb 2017 18:38:52 +0000 Subject: Add documentation of [regsub -command]. --- doc/regsub.n | 72 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ generic/tclCmdMZ.c | 4 +-- 2 files changed, 74 insertions(+), 2 deletions(-) diff --git a/doc/regsub.n b/doc/regsub.n index a5b79de..23bbff9 100644 --- a/doc/regsub.n +++ b/doc/regsub.n @@ -68,6 +68,31 @@ and sequences are handled for each substitution using the information from the corresponding match. .TP +\fB\-command\fR +.VS 8.7 +Changes the handling of the substitution string so that it no longer treats +.QW & +and +.QW \e +as special characters, but instead uses them as a non-empty list of words. +Each time a substitution is processed, another complete Tcl word is appended +to that list for each substitution value (the first such argument represents +the overall matched substring, the subsequent arguments will be one per +capturing sub-RE, much as are returned from \fBregexp\fR \fB\-inline\fR) and +the overall list is then evaluated as a Tcl command call. If the command +finishes successfully, the result of command call is substituted into the +resulting string. +.RS +.PP +If \fB\-all\fR is not also given, the command callback will be invoked at most +once (exactly when the regular expression matches). If \fB\-all\fR is given, +the command callback will be invoked for each matched location, in sequence. +The exact location indices that matched are not made available to the script. +.PP +See \fBEXAMPLES\fR below for illustrative cases. +.RE +.VE 8.7 +.TP \fB\-expanded\fR . Enables use of the expanded regular expression syntax where @@ -183,6 +208,53 @@ set substitution {[format \e\e\e\eu%04x [scan "\e\e&" %c]]} set quoted [subst [string map {\en {\e\eu000a}} \e [\fBregsub\fR -all $RE $string $substitution]]] .CE +.PP +.VS 8.7 +The above operation can be done using \fBregsub \-command\fR instead, which is +often faster. (A full pre-computed \fBstring map\fR would be faster still, but +the cost of computing the map for a transformation as complex as this can be +quite large.) +.PP +.CS +# This RE is just a character class for everything "bad" +set RE {[][{};#\e\e\e$\es\eu0080-\euffff]} + +# This encodes what the RE described above matches +proc encodeChar {ch} { + # newline is handled specially since backslash-newline is a + # special sequence. + if {$ch eq "\en"} { + return "\e\eu000a" + } + # No point in writing this as a one-liner + scan $ch %c charNumber + format "\e\eu%04x" $charNumber +} + +set quoted [\fBregsub\fR -all -command $RE $string encodeChar] +.CE +.PP +Decoding a URL-encoded string using \fBregsub \-command\fR, a lambda term and +the \fBapply\fR command. +.PP +.CS +# Match one of the sequences in a URL-encoded string that needs +# fixing, converting + to space and %XX to the right character +# (e.g., %7e becomes ~) +set RE {(\e+)|%([0-9A-Fa-f]{2})} + +# Note that -command uses a command prefix, not a command name +set decoded [\fBregsub\fR -all -command $RE $string {apply {{- p h} { + # + is a special case; handle directly + if {$p eq "+"} { + return " " + } + # convert hex to a char + scan $h %x charNumber + format %c $charNumber +}}}] +.CE +.VE 8.7 .SH "SEE ALSO" regexp(n), re_syntax(n), subst(n), string(n) .SH KEYWORDS diff --git a/generic/tclCmdMZ.c b/generic/tclCmdMZ.c index d5a6b01..4178ba8 100644 --- a/generic/tclCmdMZ.c +++ b/generic/tclCmdMZ.c @@ -500,8 +500,8 @@ Tcl_RegsubObjCmd( "--", NULL }; enum options { - REGSUB_ALL, REGSUB_COMMAND, REGSUB_EXPANDED, REGSUB_LINE, - REGSUB_LINESTOP, REGSUB_LINEANCHOR, REGSUB_NOCASE, REGSUB_START, + REGSUB_ALL, REGSUB_COMMAND, REGSUB_EXPANDED, REGSUB_LINE, + REGSUB_LINESTOP, REGSUB_LINEANCHOR, REGSUB_NOCASE, REGSUB_START, REGSUB_LAST }; -- cgit v0.12 From 93d3ea1393cc514c4b87c0874138c538db257d02 Mon Sep 17 00:00:00 2001 From: dkf Date: Sun, 26 Feb 2017 13:19:08 +0000 Subject: Make tests produce more meaningful information when they fail. --- tests/zlib.test | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) diff --git a/tests/zlib.test b/tests/zlib.test index 9497979..ba861e0 100644 --- a/tests/zlib.test +++ b/tests/zlib.test @@ -163,13 +163,19 @@ test zlib-7.9 {zlib stream finalize (bug 25842c161)} -constraints zlib -setup { } -body { $z1 put ABCDEedbca.. $z1 finalize - $z2 put -finalize ABCDEedbca.. - expr {[$z1 get] eq [$z2 get]} + zlib gunzip [$z1 get] } -cleanup { $z1 close +} -result ABCDEedbca.. +test zlib-7.9.1 {zlib stream finalize (bug 25842c161)} -constraints zlib -setup { + set z2 [zlib stream gzip] +} -body { + $z2 put -finalize ABCDEedbca.. + zlib gunzip [$z2 get] +} -cleanup { $z2 close -} -result 1 -test zlib-7.9.1 {zlib stream put -finalize (bug 25842c161)} -constraints zlib -setup { +} -result ABCDEedbca.. +test zlib-7.9.2 {zlib stream put -finalize (bug 25842c161)} -constraints zlib -setup { set c [zlib stream gzip] set d [zlib stream gunzip] } -body { @@ -182,7 +188,7 @@ test zlib-7.9.1 {zlib stream put -finalize (bug 25842c161)} -constraints zlib -s $c close $d close } -result abcdeEDCBA.. -test zlib-7.9.2 {zlib stream put; zlib stream finalize (bug 25842c161)} -constraints zlib -setup { +test zlib-7.9.3 {zlib stream put; zlib stream finalize (bug 25842c161)} -constraints zlib -setup { set c [zlib stream gzip] set d [zlib stream gunzip] } -body { -- cgit v0.12 From 203bbab7c962038e5b8d6899f530317254063b6f Mon Sep 17 00:00:00 2001 From: dkf Date: Sun, 26 Feb 2017 15:28:29 +0000 Subject: Might as well number tests more conventionally. --- tests/zlib.test | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/tests/zlib.test b/tests/zlib.test index ba861e0..1e69745 100644 --- a/tests/zlib.test +++ b/tests/zlib.test @@ -167,7 +167,7 @@ test zlib-7.9 {zlib stream finalize (bug 25842c161)} -constraints zlib -setup { } -cleanup { $z1 close } -result ABCDEedbca.. -test zlib-7.9.1 {zlib stream finalize (bug 25842c161)} -constraints zlib -setup { +test zlib-7.10 {zlib stream finalize (bug 25842c161)} -constraints zlib -setup { set z2 [zlib stream gzip] } -body { $z2 put -finalize ABCDEedbca.. @@ -175,7 +175,7 @@ test zlib-7.9.1 {zlib stream finalize (bug 25842c161)} -constraints zlib -setup } -cleanup { $z2 close } -result ABCDEedbca.. -test zlib-7.9.2 {zlib stream put -finalize (bug 25842c161)} -constraints zlib -setup { +test zlib-7.11 {zlib stream put -finalize (bug 25842c161)} -constraints zlib -setup { set c [zlib stream gzip] set d [zlib stream gunzip] } -body { @@ -188,7 +188,7 @@ test zlib-7.9.2 {zlib stream put -finalize (bug 25842c161)} -constraints zlib -s $c close $d close } -result abcdeEDCBA.. -test zlib-7.9.3 {zlib stream put; zlib stream finalize (bug 25842c161)} -constraints zlib -setup { +test zlib-7.12 {zlib stream put; zlib stream finalize (bug 25842c161)} -constraints zlib -setup { set c [zlib stream gzip] set d [zlib stream gunzip] } -body { -- cgit v0.12 From ef3d739cdf66aa26639c9167d6e9da8a2d64a54d Mon Sep 17 00:00:00 2001 From: avl Date: Sun, 5 Mar 2017 15:05:48 +0000 Subject: Fix for Ticket [71c0878b71] + test cases --- generic/tclStrToD.c | 2 +- tests/incr.test | 12 ++++++++++++ 2 files changed, 13 insertions(+), 1 deletion(-) diff --git a/generic/tclStrToD.c b/generic/tclStrToD.c index 77e1839..224ab45 100644 --- a/generic/tclStrToD.c +++ b/generic/tclStrToD.c @@ -539,7 +539,7 @@ TclParseNumber( */ if (bytes == NULL) { - if (endPtrPtr == NULL) { + if (interp == NULL && endPtrPtr == NULL) { if (objPtr->typePtr == &tclDictType) { /* A dict can never be a (single) number */ return TCL_ERROR; diff --git a/tests/incr.test b/tests/incr.test index 9243be0..aa2872a 100644 --- a/tests/incr.test +++ b/tests/incr.test @@ -494,6 +494,18 @@ test incr-2.31 {incr command (compiled): bad increment} { (reading increment) invoked from within "incr x 1a"}} +test incr-2.32 {incr command (compiled): bad pure list increment} { + list [catch {incr x [list 1 2]} msg] $msg $::errorInfo +} {1 {expected integer but got "1 2"} {expected integer but got "1 2" + (reading increment) + invoked from within +"incr x [list 1 2]"}} +test incr-2.33 {incr command (compiled): bad pure dict increment} { + list [catch {incr x [dict create 1 2]} msg] $msg $::errorInfo +} {1 {expected integer but got "1 2"} {expected integer but got "1 2" + (reading increment) + invoked from within +"incr x [dict create 1 2]"}} test incr-3.1 {increment by wide amount: bytecode route} { set x 0 -- cgit v0.12 From 089381e2b134caf0f0f090d827403469a45691b4 Mon Sep 17 00:00:00 2001 From: sebres Date: Mon, 6 Mar 2017 20:02:55 +0000 Subject: zlib.test: fix sporadic errors: - zlib-9.2 hangs because of too short update, if processed another event; - zlib-8.8 wrong non-blocking pipe usage - [string length $compressed] may return sporadically values smaller as expected (< 222) --- tests/zlib.test | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/tests/zlib.test b/tests/zlib.test index 1e69745..63bac7e 100644 --- a/tests/zlib.test +++ b/tests/zlib.test @@ -311,7 +311,7 @@ test zlib-8.8 {transformation and fconfigure} -setup { lassign [chan pipe] inSide outSide } -constraints zlib -body { zlib push compress $outSide -dictionary $spdyDict - fconfigure $outSide -blocking 0 -translation binary -buffering none + fconfigure $outSide -blocking 1 -translation binary -buffering none fconfigure $inSide -blocking 1 -translation binary puts -nonewline $outSide $spdyHeaders chan pop $outSide @@ -508,6 +508,7 @@ test zlib-9.2 "socket fcopy with push" -constraints zlib -setup { chan configure $c -translation binary -buffering none -blocking 0 puts -nonewline $c [zlib gzip [string repeat a 81920]] close $c + set ::total -1 }}} 0] set file [makeFile {} test.gz] } -body { @@ -515,7 +516,10 @@ test zlib-9.2 "socket fcopy with push" -constraints zlib -setup { set sin [socket $addr $port] chan configure $sin -translation binary zlib push gunzip $sin - update + after 1000 {set ::total timeout} + vwait ::total + after cancel {set ::total timeout} + if {$::total != -1} {error "unexpected value $::total of ::total"} set total [fcopy $sin [set fout [open $file wb]]] close $sin close $fout -- cgit v0.12 From 6ba062e0679546a9c8b8081b0b68042005952a3e Mon Sep 17 00:00:00 2001 From: sebres Date: Mon, 6 Mar 2017 20:05:13 +0000 Subject: nre.test: add constraint for nre-0.1 (testnreunwind may be not available) --- tests/nre.test | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/tests/nre.test b/tests/nre.test index 9df5eb1..09061d2 100644 --- a/tests/nre.test +++ b/tests/nre.test @@ -64,9 +64,11 @@ if {[testConstraint testnrelevels]} { namespace import testnre::* } -test nre-0.1 {levels while unwinding} { +test nre-0.1 {levels while unwinding} -body { testnreunwind -} {0 0 0} +} -constraints { + testnrelevels +} -result {0 0 0} test nre-1.1 {self-recursive procs} -setup { proc a i [makebody {a $i}] -- cgit v0.12 From 2a1688c8f53ec0cd628c056cb271f7f0d0114a85 Mon Sep 17 00:00:00 2001 From: sebres Date: Mon, 6 Mar 2017 20:07:08 +0000 Subject: chanio.test: [win] fix test case (setup set translation to "lf", because of default translation on windows "crlf") --- tests/chanio.test | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/chanio.test b/tests/chanio.test index 9a27233..31bef36 100644 --- a/tests/chanio.test +++ b/tests/chanio.test @@ -6775,7 +6775,7 @@ test chan-io-52.10 {TclCopyChannel & encodings} {fcopy} { } 5 test chan-io-52.11 {TclCopyChannel & encodings} -setup { set f [open $path(utf8-fcopy.txt) w] - fconfigure $f -encoding utf-8 + fconfigure $f -encoding utf-8 -translation lf puts $f "\u0410\u0410" close $f } -constraints {fcopy} -body { -- cgit v0.12 From aaa76b7a7da0a9f73cef7abc18e26aa92d154e43 Mon Sep 17 00:00:00 2001 From: sebres Date: Mon, 6 Mar 2017 20:32:54 +0000 Subject: msgcat.test: fixed mcpackagelocale syntax usage test case (msgcat-12.1) --- tests/msgcat.test | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/msgcat.test b/tests/msgcat.test index 1c3ce58..584e420 100644 --- a/tests/msgcat.test +++ b/tests/msgcat.test @@ -811,7 +811,7 @@ 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 ?locale? ?ns?"} test msgcat-12.2 {mclpackagelocale wrong subcommand} -body { mcpackagelocale junk -- cgit v0.12 From fa0de66105f11524c686e70e023dbcdbaa59826e Mon Sep 17 00:00:00 2001 From: sebres Date: Mon, 6 Mar 2017 21:01:53 +0000 Subject: tclEmptyStringRep -> &tclEmptyString --- generic/tclStrIdxTree.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/generic/tclStrIdxTree.c b/generic/tclStrIdxTree.c index 773eb6a..d9b5da0 100644 --- a/generic/tclStrIdxTree.c +++ b/generic/tclStrIdxTree.c @@ -397,7 +397,7 @@ StrIdxTreeObj_UpdateStringProc(Tcl_Obj *objPtr) { /* currently only dummy empty string possible */ objPtr->length = 0; - objPtr->bytes = tclEmptyStringRep; + objPtr->bytes = &tclEmptyString; }; MODULE_SCOPE TclStrIdxTree * -- cgit v0.12 From d183e03dc3c05baa9955589ba4c7af01d01c7295 Mon Sep 17 00:00:00 2001 From: "jan.nijtmans" Date: Tue, 7 Mar 2017 09:36:34 +0000 Subject: Remove "makefile.bc". Not updated for many-many years, most likely it doesn't work any more and it doesn't seem to care anyone. Let's see if someone complains ;-) --- .fossil-settings/crnl-glob | 1 - .fossil-settings/encoding-glob | 1 - doc/LinkVar.3 | 2 +- generic/tcl.h | 1 - generic/tclParse.c | 2 +- macosx/Tcl.xcode/project.pbxproj | 2 - macosx/Tcl.xcodeproj/project.pbxproj | 2 - win/makefile.bc | 594 ----------------------------------- win/tcl.dsp | 4 - 9 files changed, 2 insertions(+), 607 deletions(-) delete mode 100644 win/makefile.bc diff --git a/.fossil-settings/crnl-glob b/.fossil-settings/crnl-glob index 8773e68..f219a75 100644 --- a/.fossil-settings/crnl-glob +++ b/.fossil-settings/crnl-glob @@ -7,7 +7,6 @@ tools/tcl.hpj.in tools/tcl.wse.in win/buildall.vc.bat win/coffbase.txt -win/makefile.bc win/makefile.vc win/rules.vc win/tcl.dsp diff --git a/.fossil-settings/encoding-glob b/.fossil-settings/encoding-glob index 25ad865..8582dd4 100644 --- a/.fossil-settings/encoding-glob +++ b/.fossil-settings/encoding-glob @@ -2,7 +2,6 @@ tools/tcl.hpj.in tools/tcl.wse.in win/buildall.vc.bat win/coffbase.txt -win/makefile.bc win/makefile.vc win/rules.vc win/tcl.dsp diff --git a/doc/LinkVar.3 b/doc/LinkVar.3 index 0b746b0..c80d30d 100644 --- a/doc/LinkVar.3 +++ b/doc/LinkVar.3 @@ -4,7 +4,7 @@ '\" '\" See the file "license.terms" for information on usage and redistribution '\" of this file, and for a DISCLAIMER OF ALL WARRANTIES. -'\" +'\" .TH Tcl_LinkVar 3 7.5 Tcl "Tcl Library Procedures" .so man.macros .BS diff --git a/generic/tcl.h b/generic/tcl.h index 50a9074..64c7d14 100644 --- a/generic/tcl.h +++ b/generic/tcl.h @@ -41,7 +41,6 @@ extern "C" { * unix/configure.in (2 LOC Major, 2 LOC minor, 1 LOC patch) * win/configure.in (as above) * win/tcl.m4 (not patchlevel) - * win/makefile.bc (not patchlevel) 2 LOC * README (sections 0 and 2, with and without separator) * macosx/Tcl.pbproj/project.pbxproj (not patchlevel) 1 LOC * macosx/Tcl.pbproj/default.pbxuser (not patchlevel) 1 LOC diff --git a/generic/tclParse.c b/generic/tclParse.c index fe3ccab..ce87fb0 100644 --- a/generic/tclParse.c +++ b/generic/tclParse.c @@ -1194,7 +1194,7 @@ ParseTokens( nestedPtr = TclStackAlloc(parsePtr->interp, sizeof(Tcl_Parse)); while (1) { const char *curEnd; - + if (Tcl_ParseCommand(parsePtr->interp, src, numBytes, 1, nestedPtr) != TCL_OK) { parsePtr->errorType = nestedPtr->errorType; diff --git a/macosx/Tcl.xcode/project.pbxproj b/macosx/Tcl.xcode/project.pbxproj index a28b8db..589b09c 100644 --- a/macosx/Tcl.xcode/project.pbxproj +++ b/macosx/Tcl.xcode/project.pbxproj @@ -837,7 +837,6 @@ F96D447308F272BA004A47F5 /* coffbase.txt */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = coffbase.txt; sourceTree = ""; }; F96D447408F272BA004A47F5 /* configure */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.script.sh; path = configure; sourceTree = ""; }; F96D447508F272BA004A47F5 /* configure.in */ = {isa = PBXFileReference; explicitFileType = text.script.sh; fileEncoding = 4; path = configure.in; sourceTree = ""; }; - F96D447608F272BA004A47F5 /* makefile.bc */ = {isa = PBXFileReference; explicitFileType = sourcecode.make; fileEncoding = 4; path = makefile.bc; sourceTree = ""; }; F96D447708F272BA004A47F5 /* Makefile.in */ = {isa = PBXFileReference; explicitFileType = sourcecode.make; fileEncoding = 4; path = Makefile.in; sourceTree = ""; }; F96D447808F272BA004A47F5 /* makefile.vc */ = {isa = PBXFileReference; explicitFileType = sourcecode.make; fileEncoding = 4; path = makefile.vc; sourceTree = ""; }; F96D447908F272BA004A47F5 /* nmakehlp.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = nmakehlp.c; sourceTree = ""; }; @@ -1759,7 +1758,6 @@ F96D447308F272BA004A47F5 /* coffbase.txt */, F96D447408F272BA004A47F5 /* configure */, F96D447508F272BA004A47F5 /* configure.in */, - F96D447608F272BA004A47F5 /* makefile.bc */, F96D447708F272BA004A47F5 /* Makefile.in */, F96D447808F272BA004A47F5 /* makefile.vc */, F96D447908F272BA004A47F5 /* nmakehlp.c */, diff --git a/macosx/Tcl.xcodeproj/project.pbxproj b/macosx/Tcl.xcodeproj/project.pbxproj index 7c0d083..9384957 100644 --- a/macosx/Tcl.xcodeproj/project.pbxproj +++ b/macosx/Tcl.xcodeproj/project.pbxproj @@ -837,7 +837,6 @@ F96D447308F272BA004A47F5 /* coffbase.txt */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = coffbase.txt; sourceTree = ""; }; F96D447408F272BA004A47F5 /* configure */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.script.sh; path = configure; sourceTree = ""; }; F96D447508F272BA004A47F5 /* configure.in */ = {isa = PBXFileReference; explicitFileType = text.script.sh; fileEncoding = 4; path = configure.in; sourceTree = ""; }; - F96D447608F272BA004A47F5 /* makefile.bc */ = {isa = PBXFileReference; explicitFileType = sourcecode.make; fileEncoding = 4; path = makefile.bc; sourceTree = ""; }; F96D447708F272BA004A47F5 /* Makefile.in */ = {isa = PBXFileReference; explicitFileType = sourcecode.make; fileEncoding = 4; path = Makefile.in; sourceTree = ""; }; F96D447808F272BA004A47F5 /* makefile.vc */ = {isa = PBXFileReference; explicitFileType = sourcecode.make; fileEncoding = 4; path = makefile.vc; sourceTree = ""; }; F96D447908F272BA004A47F5 /* nmakehlp.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = nmakehlp.c; sourceTree = ""; }; @@ -1759,7 +1758,6 @@ F96D447308F272BA004A47F5 /* coffbase.txt */, F96D447408F272BA004A47F5 /* configure */, F96D447508F272BA004A47F5 /* configure.in */, - F96D447608F272BA004A47F5 /* makefile.bc */, F96D447708F272BA004A47F5 /* Makefile.in */, F96D447808F272BA004A47F5 /* makefile.vc */, F96D447908F272BA004A47F5 /* nmakehlp.c */, diff --git a/win/makefile.bc b/win/makefile.bc deleted file mode 100644 index f5b5acc..0000000 --- a/win/makefile.bc +++ /dev/null @@ -1,594 +0,0 @@ -# -# Makefile for Borland C++ 5.5 (or C++ Builder 5), adapted from the makefile -# for Visual C++ that came with tcl 8.3.3 -# -# 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-1999 by Scriptics Corporation. - -# TIP #59 information. -# -# This makefile does not set the following configuration cpp -# defines. Behind the defines are the makefile variables listed to set -# to -D... when that feature is enabled. -# -# - TCL_CFG_PROFILED PROFDEFINES -# - TCL_CFG_OPTIMIZED OPTDEFINES -# - TCL_CFG_DO64BIT SIXFOURDEFINES - -# Have a look at the complete description on how to build and test Tcl with -# the current Borland compilers at www.ratiosoft.com/tcl/borland. -# -# Usage: -# - Adapt the paths below to match your compiler's location -# - Make sure the compiler's bin directory is on your path -# - Open a console -# - To make a debug version enter -# make -fmakefile.bc -DNODEBUG=0 xxx -# where 'xxx' is the target you want (e.g. 'all', 'test', ...) -# Please note: I omitted the 'd' suffix for debug versions because Tcl -# will always call tclpip83.dll and not tclpip83d.dll, causing an error. -# ^ -# Besides, the debug version goes into a separate directory, so there -# should be no problem having DLLs and EXEs with the same name. -# If you prefer your debug version having the 'd' suffix just uncomment -# the line -# #DBGX = d -# -# - To make a 'normal' version enter -# make -fmakefile.bc xxx -# where 'xxx' is the target you want (e.g. 'all', 'test', ...) -# -# DISCLAIMER: -# This makefile has an experimental status - that is those targets which -# have been modified do in fact compile and link with Borland's C++ -# Builder 5 and with the free Borland compiler (Borland C++ 5.5). -# However the author assumes no responsiblity for any effect which the use of -# this makefile or of the resulting programs might have on your system. -# -# Not yet modified: -# - The 'plug-in-DLL' and the associated shell. -# -# Suggestions and / or improvements are always welcome. -# -# May 2001, H. Giese (hgiese@ratiosoft.com) -# - -# Does not depend on the presence of any environment variables in -# order to compile tcl; all needed information is derived from -# location of the compiler directories. - -# -# Project directories -# -# ROOT = top of source tree -# -# TOOLS32 = location of Borland development tools. -# -# INSTALLDIR = where the install-targets should copy the binaries and -# support files -# - -ROOT = .. -INSTALLDIR = c:\program files\tcl - -# If you have C++ Builder 5 or the free Borland C++ 5.5 compiler -# adapt the following paths as appropriate for your system -TOOLS32 = c:\dev\bcc55 -TOOLS32_rc = c:\dev\bcc55 -#TOOLS32 = c:\bc55 -#TOOLS32_rc = c:\bc55 - -cc32 = "$(TOOLS32)\bin\bcc32.exe" -link32 = "$(TOOLS32)\bin\ilink32.exe" -lib32 = "$(TOOLS32)\bin\tlib.exe" -rc32 = "$(TOOLS32_rc)\bin\brcc32.exe" -include32 = -I"$(TOOLS32)\include" -libpath32 = -L"$(TOOLS32)\lib" - -# Uncomment the following line to compile with thread support -#THREADDEFINES = -DTCL_THREADS=1 - -# Allow definition of NDEBUG via command line -# Set NODEBUG to 0 to compile with symbols -!if !defined(NODEBUG) -NODEBUG = 1 -!endif - -# CFG_ENCODING=encoding -# name of encoding for configuration information. Defaults -# to cp1252 -!if !defined(CFG_ENCODING) -CFG_ENCODING = \"cp1252\" -!endif - -# The following defines can be used to control the amount of debugging -# code that is added to the compilation. -# -# -DTCL_MEM_DEBUG Enables the debugging memory allocator. -# -DTCL_COMPILE_DEBUG Enables byte compilation logging. -# -DTCL_COMPILE_STATS Enables byte compilation statistics gathering. -# -DUSE_TCLALLOC=0 Disables the Tcl memory allocator in favor -# of the native malloc implementation. This is -# needed when using Purify. -# -#DEBUGDEFINES = -DTCL_MEM_DEBUG -DTCL_COMPILE_DEBUG -DTCL_COMPILE_STATS -#DEBUGDEFINES = -DUSE_TCLALLOC=0 - -###################################################################### -# Do not modify below this line -###################################################################### - -NAMEPREFIX = tcl -STUBPREFIX = $(NAMEPREFIX)stub -DOTVERSION = 8.6 -VERSION = 86 - -DDEVERSION = 14 -DDEDOTVERSION = 1.4 - -REGVERSION = 13 -REGDOTVERSION = 1.3 - -BINROOT = .. -!IF "$(NODEBUG)" == "1" -TMPDIRNAME = Release -DBGX = -SYMDEFINES = -DNDEBUG -!ELSE -TMPDIRNAME = Debug -#DBGX = d -DBGX = -SYMDEFINES = -DTCL_CFG_DEBUG -!ENDIF -TMPDIR = $(BINROOT)\$(TMPDIRNAME) -OUTDIRNAME = $(TMPDIRNAME) -OUTDIR = $(TMPDIR) - -TCLLIB = $(OUTDIR)\$(NAMEPREFIX)$(VERSION)$(DBGX).lib -TCLDLLNAME = $(NAMEPREFIX)$(VERSION)$(DBGX).dll -TCLDLL = $(OUTDIR)\$(TCLDLLNAME) - -TCLSTUBLIBNAME = $(STUBPREFIX)$(VERSION)$(DBGX).lib -TCLSTUBLIB = $(OUTDIR)\$(TCLSTUBLIBNAME) - -TCLPLUGINLIB = $(OUTDIR)\$(NAMEPREFIX)$(VERSION)p$(DBGX).lib -TCLPLUGINDLLNAME = $(NAMEPREFIX)$(VERSION)p$(DBGX).dll -TCLPLUGINDLL = $(OUTDIR)\$(TCLPLUGINDLLNAME) -TCLSH = $(OUTDIR)\$(NAMEPREFIX)sh$(VERSION)$(DBGX).exe -TCLSHP = $(OUTDIR)\$(NAMEPREFIX)shp$(VERSION)$(DBGX).exe -TCLREGDLLNAME = $(NAMEPREFIX)reg$(REGVERSION)$(DBGX).dll -TCLREGDLL = $(OUTDIR)\$(TCLREGDLLNAME) -TCLDDEDLLNAME = $(NAMEPREFIX)dde$(DDEVERSION)$(DBGX).dll -TCLDDEDLL = $(OUTDIR)\$(TCLDDEDLLNAME) -TCLTEST = $(OUTDIR)\$(NAMEPREFIX)test.exe -CAT32 = $(TMPDIR)\cat32.exe -RMDIR = .\rmd.bat -MKDIR = .\mkd.bat -RM = del - -LIB_INSTALL_DIR = $(INSTALLDIR)\lib -BIN_INSTALL_DIR = $(INSTALLDIR)\bin -SCRIPT_INSTALL_DIR = $(INSTALLDIR)\lib\tcl$(DOTVERSION) -INCLUDE_INSTALL_DIR = $(INSTALLDIR)\include - -TCLSHOBJS = \ - $(TMPDIR)\tclAppInit.obj - -TCLTESTOBJS = \ - $(TMPDIR)\tclTest.obj \ - $(TMPDIR)\tclTestObj.obj \ - $(TMPDIR)\tclTestProcBodyObj.obj \ - $(TMPDIR)\tclThreadTest.obj \ - $(TMPDIR)\tclWinTest.obj \ - $(TMPDIR)\testMain.obj - -TCLOBJS = \ - $(TMPDIR)\regcomp.obj \ - $(TMPDIR)\regexec.obj \ - $(TMPDIR)\regfree.obj \ - $(TMPDIR)\regerror.obj \ - $(TMPDIR)\tclAlloc.obj \ - $(TMPDIR)\tclAsync.obj \ - $(TMPDIR)\tclBasic.obj \ - $(TMPDIR)\tclBinary.obj \ - $(TMPDIR)\tclCkalloc.obj \ - $(TMPDIR)\tclClock.obj \ - $(TMPDIR)\tclCmdAH.obj \ - $(TMPDIR)\tclCmdIL.obj \ - $(TMPDIR)\tclCmdMZ.obj \ - $(TMPDIR)\tclCompCmds.obj \ - $(TMPDIR)\tclCompCmdsGR.obj \ - $(TMPDIR)\tclCompCmdsSZ.obj \ - $(TMPDIR)\tclCompExpr.obj \ - $(TMPDIR)\tclCompile.obj \ - $(TMPDIR)\tclConfig.obj \ - $(TMPDIR)\tclDate.obj \ - $(TMPDIR)\tclDictObj.obj \ - $(TMPDIR)\tclDisassemble.obj \ - $(TMPDIR)\tclEncoding.obj \ - $(TMPDIR)\tclEnsemble.obj \ - $(TMPDIR)\tclEnv.obj \ - $(TMPDIR)\tclEvent.obj \ - $(TMPDIR)\tclExecute.obj \ - $(TMPDIR)\tclFCmd.obj \ - $(TMPDIR)\tclFileName.obj \ - $(TMPDIR)\tclGet.obj \ - $(TMPDIR)\tclHash.obj \ - $(TMPDIR)\tclHistory.obj \ - $(TMPDIR)\tclIndexObj.obj \ - $(TMPDIR)\tclInterp.obj \ - $(TMPDIR)\tclIO.obj \ - $(TMPDIR)\tclIOCmd.obj \ - $(TMPDIR)\tclIOGT.obj \ - $(TMPDIR)\tclIOSock.obj \ - $(TMPDIR)\tclIOUtil.obj \ - $(TMPDIR)\tclLink.obj \ - $(TMPDIR)\tclLiteral.obj \ - $(TMPDIR)\tclListObj.obj \ - $(TMPDIR)\tclLoad.obj \ - $(TMPDIR)\tclMain.obj \ - $(TMPDIR)\tclNamesp.obj \ - $(TMPDIR)\tclNotify.obj \ - $(TMPDIR)\tclOO.obj \ - $(TMPDIR)\tclOOBasic.obj \ - $(TMPDIR)\tclOOCall.obj \ - $(TMPDIR)\tclOODefineCmds.obj \ - $(TMPDIR)\tclOOInfo.obj \ - $(TMPDIR)\tclOOMethod.obj \ - $(TMPDIR)\tclOOStubInit.obj \ - $(TMPDIR)\tclObj.obj \ - $(TMPDIR)\tclOptimize.obj \ - $(TMPDIR)\tclPanic.obj \ - $(TMPDIR)\tclParse.obj \ - $(TMPDIR)\tclPipe.obj \ - $(TMPDIR)\tclPkg.obj \ - $(TMPDIR)\tclPkgConfig.obj \ - $(TMPDIR)\tclPosixStr.obj \ - $(TMPDIR)\tclPreserve.obj \ - $(TMPDIR)\tclProc.obj \ - $(TMPDIR)\tclRegexp.obj \ - $(TMPDIR)\tclResolve.obj \ - $(TMPDIR)\tclResult.obj \ - $(TMPDIR)\tclScan.obj \ - $(TMPDIR)\tclStringObj.obj \ - $(TMPDIR)\tclStubInit.obj \ - $(TMPDIR)\tclThread.obj \ - $(TMPDIR)\tclThreadJoin.obj \ - $(TMPDIR)\tclTimer.obj \ - $(TMPDIR)\tclTrace.obj \ - $(TMPDIR)\tclUtf.obj \ - $(TMPDIR)\tclUtil.obj \ - $(TMPDIR)\tclVar.obj \ - $(TMPDIR)\tclWin32Dll.obj \ - $(TMPDIR)\tclWinChan.obj \ - $(TMPDIR)\tclWinConsole.obj \ - $(TMPDIR)\tclWinSerial.obj \ - $(TMPDIR)\tclWinError.obj \ - $(TMPDIR)\tclWinFCmd.obj \ - $(TMPDIR)\tclWinFile.obj \ - $(TMPDIR)\tclWinInit.obj \ - $(TMPDIR)\tclWinLoad.obj \ - $(TMPDIR)\tclWinNotify.obj \ - $(TMPDIR)\tclWinPipe.obj \ - $(TMPDIR)\tclWinSock.obj \ - $(TMPDIR)\tclWinThrd.obj \ - $(TMPDIR)\tclWinTime.obj \ - $(TMPDIR)\tclZlib.obj - -TCLSTUBOBJS = \ - $(TMPDIR)\tclStubLib.obj \ - $(TMPDIR)\tclTomMathStubLib.obj \ - $(TMPDIR)\tclOOStubLib.obj - -WINDIR = $(ROOT)\win -GENERICDIR = $(ROOT)\generic - -TCL_INCLUDES = -I"$(WINDIR)" -I"$(GENERICDIR)" -TCL_DEFINES = $(DEBUGDEFINES) $(THREADDEFINES) $(SYMDEFINES) \ - $(PROFDEFINES) $(OPTDEFINES) $(SIXFOURDEFINES) \ - -DTCL_CFGVAL_ENCODING=${CFG_ENCODING} -### TODO: Add -DHAVE_ZLIB=1 - -###################################################################### -# Compiler flags -###################################################################### - -!IF "$(NODEBUG)" == "1" -# these macros cause maximum optimization and no symbols -cdebug = -v- -vi- -O2 -D_DEBUG -!ELSE -# these macros enable debugging -cdebug = -k -Od -r- -v -vi- -y -!ENDIF - -SYSDEFINES = _MT;NO_STRICT;_NO_VCL - -# declarations common to all compiler options -cbase = -c -q -3 -a4 -g0 -tWM -Ve -Vx -X- -WARNINGS = -w-rch -w-pch -w-par -w-dup -w-pro -w-dpu - -ccons = -tWC - -INCLUDEPATH = $(include32) $(TCL_INCLUDES) - -CFLAGS = $(cdebug) $(cbase) $(INCLUDEPATH) $(WARNINGS) -D$(SYSDEFINES) -TCL_CFLAGS = $(CFLAGS) $(TCL_DEFINES) -CONS_CFLAGS = $(CFLAGS) $(TCL_DEFINES) $(ccons) - -###################################################################### -# Linker flags -###################################################################### - -!IF "$(NODEBUG)" == "1" -ldebug = -!ELSE -ldebug = -v -!ENDIF - -# declarations common to all linker options -LNFLAGS = -D"" -Gn -I$(TMPDIR) -x $(ldebug) $(libpath32) -# -Gi: create lib file (is -Gl in doc) -# -aa: Windows app, -ap: Windows console app -LNFLAGS_DLL = -ap -Gi -Tpd -LNFLAGS_CONS = -ap -Tpe - -LNLIBS = import32 cw32mt - - -###################################################################### -# Project specific targets -###################################################################### - -release: setup $(TCLSH) dlls -dlls: setup $(TCLREGDLL) $(TCLDDEDLL) -all: setup $(TCLSH) dlls $(CAT32) -tcltest: setup $(TCLTEST) dlls $(CAT32) -plugin: setup $(TCLPLUGINDLL) $(TCLSHP) -install: install-binaries install-libraries - -test: setup $(TCLTEST) dlls $(CAT32) - set TCL_LIBRARY=$(ROOT)/library - $(TCLTEST) $(ROOT)/tests/all.tcl - -setup: - @if not exist $(OUT_DIR)\nul mkdir $(OUT_DIR) &\ - echo *** Created directory '$(OUT_DIR)' - @if not exist $(TMP_DIR)\nul mkdir $(TMP_DIR) &\ - echo *** Created directory '$(TMP_DIR)' - - -$(TCLLIB): $(TCLDLL) - -$(TCLDLL): $(TCLOBJS) $(TMPDIR)\$(NAMEPREFIX).res - $(link32) $(ldebug) $(LNFLAGS) $(LNFLAGS_DLL) $(TOOLS32)\lib\c0d32 @&&! - $(TCLOBJS), $@, -x, $(LNLIBS),, $(TMPDIR)\$(NAMEPREFIX).res -! - -$(TCLSTUBLIB): $(TCLSTUBOBJS) - $(lib32) /u $@ $(TCLSTUBOBJS) - -$(TCLPLUGINLIB): $(TCLPLUGINDLL) - -$(TCLPLUGINDLL): $(TCLOBJS) $(TMPDIR)\tcl.res - $(link32) $(ldebug) $(dlllflags) \ - -out:$@ $(TMPDIR)\tcl.res $(guilibsdll) @&&! -$(TCLOBJS) -! - -$(TCLSH): $(TCLSHOBJS) $(TCLLIB) $(TMPDIR)\$(NAMEPREFIX)sh.res - $(link32) $(ldebug) -S:2400000 $(LNFLAGS) $(LNFLAGS_CONS) $(TOOLS32)\lib\c0x32 @&&! - $(TCLSHOBJS), $@, -x, $(LNLIBS) $(TCLLIB),, $(TMPDIR)\$(NAMEPREFIX)sh.res -! - -$(TCLSHP): $(TCLSHOBJS) $(TCLPLUGINLIB) $(TMPDIR)\tclsh.res - $(link32) $(ldebug) $(conlflags) $(TMPDIR)\tclsh.res -stack:2300000 \ - -out:$@ $(conlibsdll) $(TCLPLUGINLIB) $(TCLSHOBJS) - -$(TCLTEST): $(TCLTESTOBJS) $(TCLLIB) $(TMPDIR)\$(NAMEPREFIX)sh.res - $(link32) $(ldebug) -S:2400000 $(LNFLAGS) $(LNFLAGS_CONS) $(TOOLS32)\lib\c0x32 @&&! - $(TCLTESTOBJS), $@, -x, $(LNLIBS) $(TCLLIB),, $(TMPDIR)\$(NAMEPREFIX)sh.res -! - -$(TCLDDEDLL): $(TMPDIR)\tclWinDde.obj $(TCLSTUBLIB) - $(link32) $(ldebug) $(LNFLAGS) $(LNFLAGS_DLL) $(TOOLS32)\lib\c0d32 \ - $(TMPDIR)\tclWinDde.obj, $@, -x, $(LNLIBS) $(TCLSTUBLIB),, \ - $(TMPDIR)\$(NAMEPREFIX).res - -$(TCLREGDLL): $(TMPDIR)\tclWinReg.obj $(TCLSTUBLIB) - $(link32) $(ldebug) $(LNFLAGS) $(LNFLAGS_DLL) $(TOOLS32)\lib\c0d32 \ - $(TMPDIR)\tclWinReg.obj, $@, -x, $(LNLIBS) $(TCLSTUBLIB),, \ - $(TMPDIR)\$(NAMEPREFIX).res - -$(CAT32): $(WINDIR)\cat.c - $(cc32) $(CONS_CFLAGS) -o$(TMPDIR)\cat.obj $? - $(link32) $(ldebug) $(LNFLAGS) $(LNFLAGS_CONS) $(TOOLS32)\lib\c0x32 \ - $(TMPDIR)\cat.obj, $@, -x, $(LNLIBS),, - -install-binaries: $(TCLSH) - $(MKDIR) "$(BIN_INSTALL_DIR)" - $(MKDIR) "$(LIB_INSTALL_DIR)" - @echo Installing $(TCLDLLNAME) - @copy "$(TCLDLL)" "$(BIN_INSTALL_DIR)" - @copy "$(TCLLIB)" "$(LIB_INSTALL_DIR)" - @echo Installing "$(TCLSH)" - @copy "$(TCLSH)" "$(BIN_INSTALL_DIR)" - @echo Installing $(TCLSTUBLIBNAME) - @copy "$(TCLSTUBLIB)" "$(LIB_INSTALL_DIR)" - @echo Installing $(WINDIR)\tclooConfig.sh - @copy "$(WINDIR)\tclooConfig.sh" "$(LIB_INSTALL_DIR)" - -install-libraries: - -@$(MKDIR) "$(LIB_INSTALL_DIR)" - -@$(MKDIR) "$(INCLUDE_INSTALL_DIR)" - -@$(MKDIR) "$(SCRIPT_INSTALL_DIR)" - @echo Installing http1.0 - -@$(MKDIR) "$(SCRIPT_INSTALL_DIR)\http1.0" - -@copy "$(ROOT)\library\http1.0\http.tcl" "$(SCRIPT_INSTALL_DIR)\http1.0" - -@copy "$(ROOT)\library\http1.0\pkgIndex.tcl" "$(SCRIPT_INSTALL_DIR)\http1.0" - @echo Installing http2.8 - -@$(MKDIR) "$(SCRIPT_INSTALL_DIR)\http2.8" - -@copy "$(ROOT)\library\http\http.tcl" "$(SCRIPT_INSTALL_DIR)\http2.8" - -@copy "$(ROOT)\library\http\pkgIndex.tcl" "$(SCRIPT_INSTALL_DIR)\http2.8" - @echo Installing opt0.4 - -@$(MKDIR) "$(SCRIPT_INSTALL_DIR)\opt0.4" - -@copy "$(ROOT)\library\opt\optparse.tcl" "$(SCRIPT_INSTALL_DIR)\opt0.4" - -@copy "$(ROOT)\library\opt\pkgIndex.tcl" "$(SCRIPT_INSTALL_DIR)\opt0.4" - @echo Installing msgcat1.5 - -@$(MKDIR) "$(SCRIPT_INSTALL_DIR)\msgcat1.5" - -@copy "$(ROOT)\library\msgcat\msgcat.tcl" "$(SCRIPT_INSTALL_DIR)\msgcat1.5" - -@copy "$(ROOT)\library\msgcat\pkgIndex.tcl" "$(SCRIPT_INSTALL_DIR)\msgcat1.5" - @echo Installing tcltest2.3 - -@$(MKDIR) "$(SCRIPT_INSTALL_DIR)\tcltest2.3" - -@copy "$(ROOT)\library\tcltest\tcltest.tcl" "$(SCRIPT_INSTALL_DIR)\tcltest2.3" - -@copy "$(ROOT)\library\tcltest\pkgIndex.tcl" "$(SCRIPT_INSTALL_DIR)\tcltest2.3" - @echo Installing platform1.0 - -@$(MKDIR) "$(SCRIPT_INSTALL_DIR)\platform1.0" - -@copy "$(ROOT)\library\platform\platform.tcl" "$(SCRIPT_INSTALL_DIR)\platform1.0" - -@copy "$(ROOT)\library\platform\shell.tcl" "$(SCRIPT_INSTALL_DIR)\platform1.0" - -@copy "$(ROOT)\library\platform\pkgIndex.tcl" "$(SCRIPT_INSTALL_DIR)\platform1.0" - @echo Installing $(TCLDDEDLLNAME) - -@$(MKDIR) "$(SCRIPT_INSTALL_DIR)\dde1.3" - -@copy "$(TCLDDEDLL)" "$(SCRIPT_INSTALL_DIR)\dde1.3" - -@copy "$(ROOT)\library\dde\pkgIndex.tcl" "$(SCRIPT_INSTALL_DIR)\dde1.3" - @echo Installing $(TCLREGDLLNAME) - -@$(MKDIR) "$(SCRIPT_INSTALL_DIR)\reg1.2" - -@copy "$(TCLREGDLL)" "$(SCRIPT_INSTALL_DIR)\reg1.3" - -@copy "$(ROOT)\library\reg\pkgIndex.tcl" "$(SCRIPT_INSTALL_DIR)\reg1.2" - @echo Installing encoding files - -@$(MKDIR) "$(SCRIPT_INSTALL_DIR)\encoding" - -@copy "$(ROOT)\library\encoding\*.enc" "$(SCRIPT_INSTALL_DIR)\encoding" - @echo Installing library files - -@copy "$(GENERICDIR)\tcl.h" "$(INCLUDE_INSTALL_DIR)" - -@copy "$(GENERICDIR)\tclDecls.h" "$(INCLUDE_INSTALL_DIR)" - -@copy "$(GENERICDIR)\tclOO.h" "$(INCLUDE_INSTALL_DIR)" - -@copy "$(GENERICDIR)\tclOODecls.h" "$(INCLUDE_INSTALL_DIR)" - -@copy "$(GENERICDIR)\tclPlatDecls.h" "$(INCLUDE_INSTALL_DIR)" - -@copy "$(ROOT)\library\history.tcl" "$(SCRIPT_INSTALL_DIR)" - -@copy "$(ROOT)\library\init.tcl" "$(SCRIPT_INSTALL_DIR)" - -@copy "$(ROOT)\library\parray.tcl" "$(SCRIPT_INSTALL_DIR)" - -@copy "$(ROOT)\library\safe.tcl" "$(SCRIPT_INSTALL_DIR)" - -@copy "$(ROOT)\library\tclIndex" "$(SCRIPT_INSTALL_DIR)" - -@copy "$(ROOT)\library\package.tcl" "$(SCRIPT_INSTALL_DIR)" - -@copy "$(ROOT)\library\word.tcl" "$(SCRIPT_INSTALL_DIR)" - -@copy "$(ROOT)\library\auto.tcl" "$(SCRIPT_INSTALL_DIR)" - -# -# Regenerate the stubs files. -# - -genstubs: - tclsh$(VERSION) $(ROOT)\tools\genStubs.tcl $(GENERICDIR) \ - $(GENERICDIR)\tcl.decls $(GENERICDIR)\tclInt.decls - -# -# Special case object file targets -# -$(TMPDIR)\tclWinInit.obj: $(WINDIR)\tclWinInit.c - $(cc32) -DBUILD_tcl $(TCL_CFLAGS) -o$(TMPDIR)\$@ $? - -$(TMPDIR)\testMain.obj: $(WINDIR)\tclAppInit.c - $(cc32) $(TCL_CFLAGS) -DTCL_TEST -o$(TMPDIR)\testMain.obj $? - -$(TMPDIR)\tclTest.obj: $(GENERICDIR)\tclTest.c - $(cc32) $(TCL_CFLAGS) -o$(TMPDIR)\$@ $? - -$(TMPDIR)\tclTestObj.obj: $(GENERICDIR)\tclTestObj.c - $(cc32) $(TCL_CFLAGS) -o$(TMPDIR)\$@ $? - -$(TMPDIR)\tclWinTest.obj: $(WINDIR)\tclWinTest.c - $(cc32) $(TCL_CFLAGS) -o$(TMPDIR)\$@ $? - -$(TMP_DIR)\tclPkgConfig.obj: $(GENERICDIR)\tclPkgConfig.c - $(cc32) $(TCL_CFLAGS) \ - -DCFG_INSTALL_EXEC_PREFIX=\"$(INSTALL_EXEC_PREFIX)\" \ - -DCFG_INSTALL_PREFIX=\"$(INSTALL_PREFIX)\" \ - -DCFG_RUNTIME_EXEC_PREFIX=\"$(RUNTIME_EXEC_PREFIX)\" \ - -DCFG_RUNTIME_PREFIX=\"$(RUNTIME_PREFIX)\" \ - -o$(TMPDIR)\$@ $? - -$(TMPDIR)\tclAppInit.obj : $(WINDIR)\tclAppInit.c - $(cc32) $(TCL_CFLAGS) -o$(TMPDIR)\$@ $? - -# The following objects should be built using the stub interfaces - -# tclWinReg: Produces errors in ANSI mode -$(TMPDIR)\tclWinReg.obj : $(WINDIR)\tclWinReg.c - $(cc32) $(TCL_CFLAGS) -DUSE_TCL_STUBS -o$(TMPDIR)\$@ $? - -# tclWinDde: Produces errors in ANSI mode -$(TMPDIR)\tclWinDde.obj : $(WINDIR)\tclWinDde.c - $(cc32) $(TCL_CFLAGS) -DUSE_TCL_STUBS -o$(TMPDIR)\$@ $? - - -# The following objects are part of the stub library and should not -# be built as DLL objects but none of the symbols should be exported - -$(TMPDIR)\tclStubLib.obj : $(GENERICDIR)\tclStubLib.c - $(cc32) $(TCL_CFLAGS) -DSTATIC_BUILD -o$(TMPDIR)\$@ $? - -$(TMPDIR)\tclTomMathStubLib.obj : $(GENERICDIR)\tclTomMathStubLib.c - $(cc32) $(TCL_CFLAGS) -DSTATIC_BUILD -o$(TMPDIR)\$@ $? - -$(TMPDIR)\tclOOStubLib.obj : $(GENERICDIR)\tclOOStubLib.c - $(cc32) $(TCL_CFLAGS) -DSTATIC_BUILD -o$(TMPDIR)\$@ $? - - -# Dedependency rules - -$(GENERICDIR)\regcomp.c: \ - $(GENERICDIR)\regguts.h \ - $(GENERICDIR)\regc_lex.c \ - $(GENERICDIR)\regc_color.c \ - $(GENERICDIR)\regc_nfa.c \ - $(GENERICDIR)\regc_cvec.c \ - $(GENERICDIR)\regc_locale.c - -$(GENERICDIR)\regcustom.h: \ - $(GENERICDIR)\tclInt.h \ - $(GENERICDIR)\tclPort.h \ - $(GENERICDIR)\regex.h - -$(GENERICDIR)\regexec.c: \ - $(GENERICDIR)\rege_dfa.c \ - $(GENERICDIR)\regguts.h - -$(GENERICDIR)\regerror.c: $(GENERICDIR)\regguts.h -$(GENERICDIR)\regfree.c: $(GENERICDIR)\regguts.h -$(GENERICDIR)\regfronts.c: $(GENERICDIR)\regguts.h -$(GENERICDIR)\regguts.h: $(GENERICDIR)\regcustom.h - -# -# Implicit rules -# - -{$(WINDIR)}.c{$(TMPDIR)}.obj: - $(cc32) -DBUILD_tcl $(TCL_CFLAGS) -o$@ $< - -{$(GENERICDIR)}.c{$(TMPDIR)}.obj: - $(cc32) -DBUILD_tcl $(TCL_CFLAGS) -o$@ $< - -{$(ROOT)\compat}.c{$(TMPDIR)}.obj: - $(cc32) -DBUILD_tcl $(TCL_CFLAGS) -o$@ $< - -{$(WINDIR)}.rc{$(TMPDIR)}.res: - $(rc32) $(INCLUDEPATH) -D$(USERDEFINES);$(SYSDEFINES) -fo$@ $< - -clean: - -@$(RM) $(OUTDIR)\*.exp - -@$(RM) $(OUTDIR)\*.lib - -@$(RM) $(OUTDIR)\*.dll - -@$(RM) $(OUTDIR)\*.exe - -@$(RM) $(OUTDIR)\*.pdb - -@$(RM) $(TMPDIR)\*.pch - -@$(RM) $(TMPDIR)\*.obj - -@$(RM) $(TMPDIR)\*.res - -@$(RM) $(TMPDIR)\*.exe - -@$(RMDIR) $(OUTDIR) - -@$(RMDIR) $(TMPDIR) - -# Local Variables: -# mode: makefile -# End: diff --git a/win/tcl.dsp b/win/tcl.dsp index 6f17cdb..e8b1a33 100644 --- a/win/tcl.dsp +++ b/win/tcl.dsp @@ -1428,10 +1428,6 @@ SOURCE=.\configure.in # End Source File # Begin Source File -SOURCE=.\makefile.bc -# End Source File -# Begin Source File - SOURCE=.\Makefile.in # End Source File # Begin Source File -- cgit v0.12 From 07050778e3c1a20254341b32a8a5bf564c1e469c Mon Sep 17 00:00:00 2001 From: "jan.nijtmans" Date: Tue, 7 Mar 2017 11:05:26 +0000 Subject: Fix [e14d152114efee10394a7e0b4b1c0478efff52c5|e14d152114]: bundled zlib documentation is under a potentially non-free license --- .fossil-settings/crlf-glob | 14 + compat/zlib/doc/algorithm.txt | 209 --------- compat/zlib/doc/rfc1950.txt | 619 --------------------------- compat/zlib/doc/rfc1951.txt | 955 ------------------------------------------ compat/zlib/doc/rfc1952.txt | 675 ----------------------------- compat/zlib/doc/txtvsbin.txt | 107 ----- 6 files changed, 14 insertions(+), 2565 deletions(-) create mode 100644 .fossil-settings/crlf-glob delete mode 100644 compat/zlib/doc/algorithm.txt delete mode 100644 compat/zlib/doc/rfc1950.txt delete mode 100644 compat/zlib/doc/rfc1951.txt delete mode 100644 compat/zlib/doc/rfc1952.txt delete mode 100644 compat/zlib/doc/txtvsbin.txt diff --git a/.fossil-settings/crlf-glob b/.fossil-settings/crlf-glob new file mode 100644 index 0000000..f219a75 --- /dev/null +++ b/.fossil-settings/crlf-glob @@ -0,0 +1,14 @@ +compat/zlib/contrib/dotzlib/DotZLib/UnitTests.cs +compat/zlib/contrib/vstudio/readme.txt +compat/zlib/contrib/vstudio/*/zlib.rc +compat/zlib/win32/*.txt +compat/zlib/win64/*.txt +tools/tcl.hpj.in +tools/tcl.wse.in +win/buildall.vc.bat +win/coffbase.txt +win/makefile.vc +win/rules.vc +win/tcl.dsp +win/tcl.dsw +win/tcl.hpj.in \ No newline at end of file diff --git a/compat/zlib/doc/algorithm.txt b/compat/zlib/doc/algorithm.txt deleted file mode 100644 index c97f495..0000000 --- a/compat/zlib/doc/algorithm.txt +++ /dev/null @@ -1,209 +0,0 @@ -1. Compression algorithm (deflate) - -The deflation algorithm used by gzip (also zip and zlib) is a variation of -LZ77 (Lempel-Ziv 1977, see reference below). It finds duplicated strings in -the input data. The second occurrence of a string is replaced by a -pointer to the previous string, in the form of a pair (distance, -length). Distances are limited to 32K bytes, and lengths are limited -to 258 bytes. When a string does not occur anywhere in the previous -32K bytes, it is emitted as a sequence of literal bytes. (In this -description, `string' must be taken as an arbitrary sequence of bytes, -and is not restricted to printable characters.) - -Literals or match lengths are compressed with one Huffman tree, and -match distances are compressed with another tree. The trees are stored -in a compact form at the start of each block. The blocks can have any -size (except that the compressed data for one block must fit in -available memory). A block is terminated when deflate() determines that -it would be useful to start another block with fresh trees. (This is -somewhat similar to the behavior of LZW-based _compress_.) - -Duplicated strings are found using a hash table. All input strings of -length 3 are inserted in the hash table. A hash index is computed for -the next 3 bytes. If the hash chain for this index is not empty, all -strings in the chain are compared with the current input string, and -the longest match is selected. - -The hash chains are searched starting with the most recent strings, to -favor small distances and thus take advantage of the Huffman encoding. -The hash chains are singly linked. There are no deletions from the -hash chains, the algorithm simply discards matches that are too old. - -To avoid a worst-case situation, very long hash chains are arbitrarily -truncated at a certain length, determined by a runtime option (level -parameter of deflateInit). So deflate() does not always find the longest -possible match but generally finds a match which is long enough. - -deflate() also defers the selection of matches with a lazy evaluation -mechanism. After a match of length N has been found, deflate() searches for -a longer match at the next input byte. If a longer match is found, the -previous match is truncated to a length of one (thus producing a single -literal byte) and the process of lazy evaluation begins again. Otherwise, -the original match is kept, and the next match search is attempted only N -steps later. - -The lazy match evaluation is also subject to a runtime parameter. If -the current match is long enough, deflate() reduces the search for a longer -match, thus speeding up the whole process. If compression ratio is more -important than speed, deflate() attempts a complete second search even if -the first match is already long enough. - -The lazy match evaluation is not performed for the fastest compression -modes (level parameter 1 to 3). For these fast modes, new strings -are inserted in the hash table only when no match was found, or -when the match is not too long. This degrades the compression ratio -but saves time since there are both fewer insertions and fewer searches. - - -2. Decompression algorithm (inflate) - -2.1 Introduction - -The key question is how to represent a Huffman code (or any prefix code) so -that you can decode fast. The most important characteristic is that shorter -codes are much more common than longer codes, so pay attention to decoding the -short codes fast, and let the long codes take longer to decode. - -inflate() sets up a first level table that covers some number of bits of -input less than the length of longest code. It gets that many bits from the -stream, and looks it up in the table. The table will tell if the next -code is that many bits or less and how many, and if it is, it will tell -the value, else it will point to the next level table for which inflate() -grabs more bits and tries to decode a longer code. - -How many bits to make the first lookup is a tradeoff between the time it -takes to decode and the time it takes to build the table. If building the -table took no time (and if you had infinite memory), then there would only -be a first level table to cover all the way to the longest code. However, -building the table ends up taking a lot longer for more bits since short -codes are replicated many times in such a table. What inflate() does is -simply to make the number of bits in the first table a variable, and then -to set that variable for the maximum speed. - -For inflate, which has 286 possible codes for the literal/length tree, the size -of the first table is nine bits. Also the distance trees have 30 possible -values, and the size of the first table is six bits. Note that for each of -those cases, the table ended up one bit longer than the ``average'' code -length, i.e. the code length of an approximately flat code which would be a -little more than eight bits for 286 symbols and a little less than five bits -for 30 symbols. - - -2.2 More details on the inflate table lookup - -Ok, you want to know what this cleverly obfuscated inflate tree actually -looks like. You are correct that it's not a Huffman tree. It is simply a -lookup table for the first, let's say, nine bits of a Huffman symbol. The -symbol could be as short as one bit or as long as 15 bits. If a particular -symbol is shorter than nine bits, then that symbol's translation is duplicated -in all those entries that start with that symbol's bits. For example, if the -symbol is four bits, then it's duplicated 32 times in a nine-bit table. If a -symbol is nine bits long, it appears in the table once. - -If the symbol is longer than nine bits, then that entry in the table points -to another similar table for the remaining bits. Again, there are duplicated -entries as needed. The idea is that most of the time the symbol will be short -and there will only be one table look up. (That's whole idea behind data -compression in the first place.) For the less frequent long symbols, there -will be two lookups. If you had a compression method with really long -symbols, you could have as many levels of lookups as is efficient. For -inflate, two is enough. - -So a table entry either points to another table (in which case nine bits in -the above example are gobbled), or it contains the translation for the symbol -and the number of bits to gobble. Then you start again with the next -ungobbled bit. - -You may wonder: why not just have one lookup table for how ever many bits the -longest symbol is? The reason is that if you do that, you end up spending -more time filling in duplicate symbol entries than you do actually decoding. -At least for deflate's output that generates new trees every several 10's of -kbytes. You can imagine that filling in a 2^15 entry table for a 15-bit code -would take too long if you're only decoding several thousand symbols. At the -other extreme, you could make a new table for every bit in the code. In fact, -that's essentially a Huffman tree. But then you spend too much time -traversing the tree while decoding, even for short symbols. - -So the number of bits for the first lookup table is a trade of the time to -fill out the table vs. the time spent looking at the second level and above of -the table. - -Here is an example, scaled down: - -The code being decoded, with 10 symbols, from 1 to 6 bits long: - -A: 0 -B: 10 -C: 1100 -D: 11010 -E: 11011 -F: 11100 -G: 11101 -H: 11110 -I: 111110 -J: 111111 - -Let's make the first table three bits long (eight entries): - -000: A,1 -001: A,1 -010: A,1 -011: A,1 -100: B,2 -101: B,2 -110: -> table X (gobble 3 bits) -111: -> table Y (gobble 3 bits) - -Each entry is what the bits decode as and how many bits that is, i.e. how -many bits to gobble. Or the entry points to another table, with the number of -bits to gobble implicit in the size of the table. - -Table X is two bits long since the longest code starting with 110 is five bits -long: - -00: C,1 -01: C,1 -10: D,2 -11: E,2 - -Table Y is three bits long since the longest code starting with 111 is six -bits long: - -000: F,2 -001: F,2 -010: G,2 -011: G,2 -100: H,2 -101: H,2 -110: I,3 -111: J,3 - -So what we have here are three tables with a total of 20 entries that had to -be constructed. That's compared to 64 entries for a single table. Or -compared to 16 entries for a Huffman tree (six two entry tables and one four -entry table). Assuming that the code ideally represents the probability of -the symbols, it takes on the average 1.25 lookups per symbol. That's compared -to one lookup for the single table, or 1.66 lookups per symbol for the -Huffman tree. - -There, I think that gives you a picture of what's going on. For inflate, the -meaning of a particular symbol is often more than just a letter. It can be a -byte (a "literal"), or it can be either a length or a distance which -indicates a base value and a number of bits to fetch after the code that is -added to the base value. Or it might be the special end-of-block code. The -data structures created in inftrees.c try to encode all that information -compactly in the tables. - - -Jean-loup Gailly Mark Adler -jloup@gzip.org madler@alumni.caltech.edu - - -References: - -[LZ77] Ziv J., Lempel A., ``A Universal Algorithm for Sequential Data -Compression,'' IEEE Transactions on Information Theory, Vol. 23, No. 3, -pp. 337-343. - -``DEFLATE Compressed Data Format Specification'' available in -http://tools.ietf.org/html/rfc1951 diff --git a/compat/zlib/doc/rfc1950.txt b/compat/zlib/doc/rfc1950.txt deleted file mode 100644 index ce6428a..0000000 --- a/compat/zlib/doc/rfc1950.txt +++ /dev/null @@ -1,619 +0,0 @@ - - - - - - -Network Working Group P. Deutsch -Request for Comments: 1950 Aladdin Enterprises -Category: Informational J-L. Gailly - Info-ZIP - May 1996 - - - ZLIB Compressed Data Format Specification version 3.3 - -Status of This Memo - - This memo provides information for the Internet community. This memo - does not specify an Internet standard of any kind. Distribution of - this memo is unlimited. - -IESG Note: - - The IESG takes no position on the validity of any Intellectual - Property Rights statements contained in this document. - -Notices - - Copyright (c) 1996 L. Peter Deutsch and Jean-Loup Gailly - - Permission is granted to copy and distribute this document for any - purpose and without charge, including translations into other - languages and incorporation into compilations, provided that the - copyright notice and this notice are preserved, and that any - substantive changes or deletions from the original are clearly - marked. - - A pointer to the latest version of this and related documentation in - HTML format can be found at the URL - . - -Abstract - - This specification defines a lossless compressed data format. The - data can be produced or consumed, even for an arbitrarily long - sequentially presented input data stream, using only an a priori - bounded amount of intermediate storage. The format presently uses - the DEFLATE compression method but can be easily extended to use - other compression methods. It can be implemented readily in a manner - not covered by patents. This specification also defines the ADLER-32 - checksum (an extension and improvement of the Fletcher checksum), - used for detection of data corruption, and provides an algorithm for - computing it. - - - - -Deutsch & Gailly Informational [Page 1] - -RFC 1950 ZLIB Compressed Data Format Specification May 1996 - - -Table of Contents - - 1. Introduction ................................................... 2 - 1.1. Purpose ................................................... 2 - 1.2. Intended audience ......................................... 3 - 1.3. Scope ..................................................... 3 - 1.4. Compliance ................................................ 3 - 1.5. Definitions of terms and conventions used ................ 3 - 1.6. Changes from previous versions ............................ 3 - 2. Detailed specification ......................................... 3 - 2.1. Overall conventions ....................................... 3 - 2.2. Data format ............................................... 4 - 2.3. Compliance ................................................ 7 - 3. References ..................................................... 7 - 4. Source code .................................................... 8 - 5. Security Considerations ........................................ 8 - 6. Acknowledgements ............................................... 8 - 7. Authors' Addresses ............................................. 8 - 8. Appendix: Rationale ............................................ 9 - 9. Appendix: Sample code ..........................................10 - -1. Introduction - - 1.1. Purpose - - The purpose of this specification is to define a lossless - compressed data format that: - - * Is independent of CPU type, operating system, file system, - and character set, and hence can be used for interchange; - - * Can be produced or consumed, even for an arbitrarily long - sequentially presented input data stream, using only an a - priori bounded amount of intermediate storage, and hence can - be used in data communications or similar structures such as - Unix filters; - - * Can use a number of different compression methods; - - * Can be implemented readily in a manner not covered by - patents, and hence can be practiced freely. - - The data format defined by this specification does not attempt to - allow random access to compressed data. - - - - - - - -Deutsch & Gailly Informational [Page 2] - -RFC 1950 ZLIB Compressed Data Format Specification May 1996 - - - 1.2. Intended audience - - This specification is intended for use by implementors of software - to compress data into zlib format and/or decompress data from zlib - format. - - The text of the specification assumes a basic background in - programming at the level of bits and other primitive data - representations. - - 1.3. Scope - - The specification specifies a compressed data format that can be - used for in-memory compression of a sequence of arbitrary bytes. - - 1.4. Compliance - - Unless otherwise indicated below, a compliant decompressor must be - able to accept and decompress any data set that conforms to all - the specifications presented here; a compliant compressor must - produce data sets that conform to all the specifications presented - here. - - 1.5. Definitions of terms and conventions used - - byte: 8 bits stored or transmitted as a unit (same as an octet). - (For this specification, a byte is exactly 8 bits, even on - machines which store a character on a number of bits different - from 8.) See below, for the numbering of bits within a byte. - - 1.6. Changes from previous versions - - Version 3.1 was the first public release of this specification. - In version 3.2, some terminology was changed and the Adler-32 - sample code was rewritten for clarity. In version 3.3, the - support for a preset dictionary was introduced, and the - specification was converted to RFC style. - -2. Detailed specification - - 2.1. Overall conventions - - In the diagrams below, a box like this: - - +---+ - | | <-- the vertical bars might be missing - +---+ - - - - -Deutsch & Gailly Informational [Page 3] - -RFC 1950 ZLIB Compressed Data Format Specification May 1996 - - - represents one byte; a box like this: - - +==============+ - | | - +==============+ - - represents a variable number of bytes. - - Bytes stored within a computer do not have a "bit order", since - they are always treated as a unit. However, a byte considered as - an integer between 0 and 255 does have a most- and least- - significant bit, and since we write numbers with the most- - significant digit on the left, we also write bytes with the most- - significant bit on the left. In the diagrams below, we number the - bits of a byte so that bit 0 is the least-significant bit, i.e., - the bits are numbered: - - +--------+ - |76543210| - +--------+ - - Within a computer, a number may occupy multiple bytes. All - multi-byte numbers in the format described here are stored with - the MOST-significant byte first (at the lower memory address). - For example, the decimal number 520 is stored as: - - 0 1 - +--------+--------+ - |00000010|00001000| - +--------+--------+ - ^ ^ - | | - | + less significant byte = 8 - + more significant byte = 2 x 256 - - 2.2. Data format - - A zlib stream has the following structure: - - 0 1 - +---+---+ - |CMF|FLG| (more-->) - +---+---+ - - - - - - - - -Deutsch & Gailly Informational [Page 4] - -RFC 1950 ZLIB Compressed Data Format Specification May 1996 - - - (if FLG.FDICT set) - - 0 1 2 3 - +---+---+---+---+ - | DICTID | (more-->) - +---+---+---+---+ - - +=====================+---+---+---+---+ - |...compressed data...| ADLER32 | - +=====================+---+---+---+---+ - - Any data which may appear after ADLER32 are not part of the zlib - stream. - - CMF (Compression Method and flags) - This byte is divided into a 4-bit compression method and a 4- - bit information field depending on the compression method. - - bits 0 to 3 CM Compression method - bits 4 to 7 CINFO Compression info - - CM (Compression method) - This identifies the compression method used in the file. CM = 8 - denotes the "deflate" compression method with a window size up - to 32K. This is the method used by gzip and PNG (see - references [1] and [2] in Chapter 3, below, for the reference - documents). CM = 15 is reserved. It might be used in a future - version of this specification to indicate the presence of an - extra field before the compressed data. - - CINFO (Compression info) - For CM = 8, CINFO is the base-2 logarithm of the LZ77 window - size, minus eight (CINFO=7 indicates a 32K window size). Values - of CINFO above 7 are not allowed in this version of the - specification. CINFO is not defined in this specification for - CM not equal to 8. - - FLG (FLaGs) - This flag byte is divided as follows: - - bits 0 to 4 FCHECK (check bits for CMF and FLG) - bit 5 FDICT (preset dictionary) - bits 6 to 7 FLEVEL (compression level) - - The FCHECK value must be such that CMF and FLG, when viewed as - a 16-bit unsigned integer stored in MSB order (CMF*256 + FLG), - is a multiple of 31. - - - - -Deutsch & Gailly Informational [Page 5] - -RFC 1950 ZLIB Compressed Data Format Specification May 1996 - - - FDICT (Preset dictionary) - If FDICT is set, a DICT dictionary identifier is present - immediately after the FLG byte. The dictionary is a sequence of - bytes which are initially fed to the compressor without - producing any compressed output. DICT is the Adler-32 checksum - of this sequence of bytes (see the definition of ADLER32 - below). The decompressor can use this identifier to determine - which dictionary has been used by the compressor. - - FLEVEL (Compression level) - These flags are available for use by specific compression - methods. The "deflate" method (CM = 8) sets these flags as - follows: - - 0 - compressor used fastest algorithm - 1 - compressor used fast algorithm - 2 - compressor used default algorithm - 3 - compressor used maximum compression, slowest algorithm - - The information in FLEVEL is not needed for decompression; it - is there to indicate if recompression might be worthwhile. - - compressed data - For compression method 8, the compressed data is stored in the - deflate compressed data format as described in the document - "DEFLATE Compressed Data Format Specification" by L. Peter - Deutsch. (See reference [3] in Chapter 3, below) - - Other compressed data formats are not specified in this version - of the zlib specification. - - ADLER32 (Adler-32 checksum) - This contains a checksum value of the uncompressed data - (excluding any dictionary data) computed according to Adler-32 - algorithm. This algorithm is a 32-bit extension and improvement - of the Fletcher algorithm, used in the ITU-T X.224 / ISO 8073 - standard. See references [4] and [5] in Chapter 3, below) - - Adler-32 is composed of two sums accumulated per byte: s1 is - the sum of all bytes, s2 is the sum of all s1 values. Both sums - are done modulo 65521. s1 is initialized to 1, s2 to zero. The - Adler-32 checksum is stored as s2*65536 + s1 in most- - significant-byte first (network) order. - - - - - - - - -Deutsch & Gailly Informational [Page 6] - -RFC 1950 ZLIB Compressed Data Format Specification May 1996 - - - 2.3. Compliance - - A compliant compressor must produce streams with correct CMF, FLG - and ADLER32, but need not support preset dictionaries. When the - zlib data format is used as part of another standard data format, - the compressor may use only preset dictionaries that are specified - by this other data format. If this other format does not use the - preset dictionary feature, the compressor must not set the FDICT - flag. - - A compliant decompressor must check CMF, FLG, and ADLER32, and - provide an error indication if any of these have incorrect values. - A compliant decompressor must give an error indication if CM is - not one of the values defined in this specification (only the - value 8 is permitted in this version), since another value could - indicate the presence of new features that would cause subsequent - data to be interpreted incorrectly. A compliant decompressor must - give an error indication if FDICT is set and DICTID is not the - identifier of a known preset dictionary. A decompressor may - ignore FLEVEL and still be compliant. When the zlib data format - is being used as a part of another standard format, a compliant - decompressor must support all the preset dictionaries specified by - the other format. When the other format does not use the preset - dictionary feature, a compliant decompressor must reject any - stream in which the FDICT flag is set. - -3. References - - [1] Deutsch, L.P.,"GZIP Compressed Data Format Specification", - available in ftp://ftp.uu.net/pub/archiving/zip/doc/ - - [2] Thomas Boutell, "PNG (Portable Network Graphics) specification", - available in ftp://ftp.uu.net/graphics/png/documents/ - - [3] Deutsch, L.P.,"DEFLATE Compressed Data Format Specification", - available in ftp://ftp.uu.net/pub/archiving/zip/doc/ - - [4] Fletcher, J. G., "An Arithmetic Checksum for Serial - Transmissions," IEEE Transactions on Communications, Vol. COM-30, - No. 1, January 1982, pp. 247-252. - - [5] ITU-T Recommendation X.224, Annex D, "Checksum Algorithms," - November, 1993, pp. 144, 145. (Available from - gopher://info.itu.ch). ITU-T X.244 is also the same as ISO 8073. - - - - - - - -Deutsch & Gailly Informational [Page 7] - -RFC 1950 ZLIB Compressed Data Format Specification May 1996 - - -4. Source code - - Source code for a C language implementation of a "zlib" compliant - library is available at ftp://ftp.uu.net/pub/archiving/zip/zlib/. - -5. Security Considerations - - A decoder that fails to check the ADLER32 checksum value may be - subject to undetected data corruption. - -6. Acknowledgements - - Trademarks cited in this document are the property of their - respective owners. - - Jean-Loup Gailly and Mark Adler designed the zlib format and wrote - the related software described in this specification. Glenn - Randers-Pehrson converted this document to RFC and HTML format. - -7. Authors' Addresses - - L. Peter Deutsch - Aladdin Enterprises - 203 Santa Margarita Ave. - Menlo Park, CA 94025 - - Phone: (415) 322-0103 (AM only) - FAX: (415) 322-1734 - EMail: - - - Jean-Loup Gailly - - EMail: - - Questions about the technical content of this specification can be - sent by email to - - Jean-Loup Gailly and - Mark Adler - - Editorial comments on this specification can be sent by email to - - L. Peter Deutsch and - Glenn Randers-Pehrson - - - - - - -Deutsch & Gailly Informational [Page 8] - -RFC 1950 ZLIB Compressed Data Format Specification May 1996 - - -8. Appendix: Rationale - - 8.1. Preset dictionaries - - A preset dictionary is specially useful to compress short input - sequences. The compressor can take advantage of the dictionary - context to encode the input in a more compact manner. The - decompressor can be initialized with the appropriate context by - virtually decompressing a compressed version of the dictionary - without producing any output. However for certain compression - algorithms such as the deflate algorithm this operation can be - achieved without actually performing any decompression. - - The compressor and the decompressor must use exactly the same - dictionary. The dictionary may be fixed or may be chosen among a - certain number of predefined dictionaries, according to the kind - of input data. The decompressor can determine which dictionary has - been chosen by the compressor by checking the dictionary - identifier. This document does not specify the contents of - predefined dictionaries, since the optimal dictionaries are - application specific. Standard data formats using this feature of - the zlib specification must precisely define the allowed - dictionaries. - - 8.2. The Adler-32 algorithm - - The Adler-32 algorithm is much faster than the CRC32 algorithm yet - still provides an extremely low probability of undetected errors. - - The modulo on unsigned long accumulators can be delayed for 5552 - bytes, so the modulo operation time is negligible. If the bytes - are a, b, c, the second sum is 3a + 2b + c + 3, and so is position - and order sensitive, unlike the first sum, which is just a - checksum. That 65521 is prime is important to avoid a possible - large class of two-byte errors that leave the check unchanged. - (The Fletcher checksum uses 255, which is not prime and which also - makes the Fletcher check insensitive to single byte changes 0 <-> - 255.) - - The sum s1 is initialized to 1 instead of zero to make the length - of the sequence part of s2, so that the length does not have to be - checked separately. (Any sequence of zeroes has a Fletcher - checksum of zero.) - - - - - - - - -Deutsch & Gailly Informational [Page 9] - -RFC 1950 ZLIB Compressed Data Format Specification May 1996 - - -9. Appendix: Sample code - - The following C code computes the Adler-32 checksum of a data buffer. - It is written for clarity, not for speed. The sample code is in the - ANSI C programming language. Non C users may find it easier to read - with these hints: - - & Bitwise AND operator. - >> Bitwise right shift operator. When applied to an - unsigned quantity, as here, right shift inserts zero bit(s) - at the left. - << Bitwise left shift operator. Left shift inserts zero - bit(s) at the right. - ++ "n++" increments the variable n. - % modulo operator: a % b is the remainder of a divided by b. - - #define BASE 65521 /* largest prime smaller than 65536 */ - - /* - Update a running Adler-32 checksum with the bytes buf[0..len-1] - and return the updated checksum. The Adler-32 checksum should be - initialized to 1. - - Usage example: - - unsigned long adler = 1L; - - while (read_buffer(buffer, length) != EOF) { - adler = update_adler32(adler, buffer, length); - } - if (adler != original_adler) error(); - */ - unsigned long update_adler32(unsigned long adler, - unsigned char *buf, int len) - { - unsigned long s1 = adler & 0xffff; - unsigned long s2 = (adler >> 16) & 0xffff; - int n; - - for (n = 0; n < len; n++) { - s1 = (s1 + buf[n]) % BASE; - s2 = (s2 + s1) % BASE; - } - return (s2 << 16) + s1; - } - - /* Return the adler32 of the bytes buf[0..len-1] */ - - - - -Deutsch & Gailly Informational [Page 10] - -RFC 1950 ZLIB Compressed Data Format Specification May 1996 - - - unsigned long adler32(unsigned char *buf, int len) - { - return update_adler32(1L, buf, len); - } - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Deutsch & Gailly Informational [Page 11] - diff --git a/compat/zlib/doc/rfc1951.txt b/compat/zlib/doc/rfc1951.txt deleted file mode 100644 index 403c8c7..0000000 --- a/compat/zlib/doc/rfc1951.txt +++ /dev/null @@ -1,955 +0,0 @@ - - - - - - -Network Working Group P. Deutsch -Request for Comments: 1951 Aladdin Enterprises -Category: Informational May 1996 - - - DEFLATE Compressed Data Format Specification version 1.3 - -Status of This Memo - - This memo provides information for the Internet community. This memo - does not specify an Internet standard of any kind. Distribution of - this memo is unlimited. - -IESG Note: - - The IESG takes no position on the validity of any Intellectual - Property Rights statements contained in this document. - -Notices - - Copyright (c) 1996 L. Peter Deutsch - - Permission is granted to copy and distribute this document for any - purpose and without charge, including translations into other - languages and incorporation into compilations, provided that the - copyright notice and this notice are preserved, and that any - substantive changes or deletions from the original are clearly - marked. - - A pointer to the latest version of this and related documentation in - HTML format can be found at the URL - . - -Abstract - - This specification defines a lossless compressed data format that - compresses data using a combination of the LZ77 algorithm and Huffman - coding, with efficiency comparable to the best currently available - general-purpose compression methods. The data can be produced or - consumed, even for an arbitrarily long sequentially presented input - data stream, using only an a priori bounded amount of intermediate - storage. The format can be implemented readily in a manner not - covered by patents. - - - - - - - - -Deutsch Informational [Page 1] - -RFC 1951 DEFLATE Compressed Data Format Specification May 1996 - - -Table of Contents - - 1. Introduction ................................................... 2 - 1.1. Purpose ................................................... 2 - 1.2. Intended audience ......................................... 3 - 1.3. Scope ..................................................... 3 - 1.4. Compliance ................................................ 3 - 1.5. Definitions of terms and conventions used ................ 3 - 1.6. Changes from previous versions ............................ 4 - 2. Compressed representation overview ............................. 4 - 3. Detailed specification ......................................... 5 - 3.1. Overall conventions ....................................... 5 - 3.1.1. Packing into bytes .................................. 5 - 3.2. Compressed block format ................................... 6 - 3.2.1. Synopsis of prefix and Huffman coding ............... 6 - 3.2.2. Use of Huffman coding in the "deflate" format ....... 7 - 3.2.3. Details of block format ............................. 9 - 3.2.4. Non-compressed blocks (BTYPE=00) ................... 11 - 3.2.5. Compressed blocks (length and distance codes) ...... 11 - 3.2.6. Compression with fixed Huffman codes (BTYPE=01) .... 12 - 3.2.7. Compression with dynamic Huffman codes (BTYPE=10) .. 13 - 3.3. Compliance ............................................... 14 - 4. Compression algorithm details ................................. 14 - 5. References .................................................... 16 - 6. Security Considerations ....................................... 16 - 7. Source code ................................................... 16 - 8. Acknowledgements .............................................. 16 - 9. Author's Address .............................................. 17 - -1. Introduction - - 1.1. Purpose - - The purpose of this specification is to define a lossless - compressed data format that: - * Is independent of CPU type, operating system, file system, - and character set, and hence can be used for interchange; - * Can be produced or consumed, even for an arbitrarily long - sequentially presented input data stream, using only an a - priori bounded amount of intermediate storage, and hence - can be used in data communications or similar structures - such as Unix filters; - * Compresses data with efficiency comparable to the best - currently available general-purpose compression methods, - and in particular considerably better than the "compress" - program; - * Can be implemented readily in a manner not covered by - patents, and hence can be practiced freely; - - - -Deutsch Informational [Page 2] - -RFC 1951 DEFLATE Compressed Data Format Specification May 1996 - - - * Is compatible with the file format produced by the current - widely used gzip utility, in that conforming decompressors - will be able to read data produced by the existing gzip - compressor. - - The data format defined by this specification does not attempt to: - - * Allow random access to compressed data; - * Compress specialized data (e.g., raster graphics) as well - as the best currently available specialized algorithms. - - A simple counting argument shows that no lossless compression - algorithm can compress every possible input data set. For the - format defined here, the worst case expansion is 5 bytes per 32K- - byte block, i.e., a size increase of 0.015% for large data sets. - English text usually compresses by a factor of 2.5 to 3; - executable files usually compress somewhat less; graphical data - such as raster images may compress much more. - - 1.2. Intended audience - - This specification is intended for use by implementors of software - to compress data into "deflate" format and/or decompress data from - "deflate" format. - - The text of the specification assumes a basic background in - programming at the level of bits and other primitive data - representations. Familiarity with the technique of Huffman coding - is helpful but not required. - - 1.3. Scope - - The specification specifies a method for representing a sequence - of bytes as a (usually shorter) sequence of bits, and a method for - packing the latter bit sequence into bytes. - - 1.4. Compliance - - Unless otherwise indicated below, a compliant decompressor must be - able to accept and decompress any data set that conforms to all - the specifications presented here; a compliant compressor must - produce data sets that conform to all the specifications presented - here. - - 1.5. Definitions of terms and conventions used - - Byte: 8 bits stored or transmitted as a unit (same as an octet). - For this specification, a byte is exactly 8 bits, even on machines - - - -Deutsch Informational [Page 3] - -RFC 1951 DEFLATE Compressed Data Format Specification May 1996 - - - which store a character on a number of bits different from eight. - See below, for the numbering of bits within a byte. - - String: a sequence of arbitrary bytes. - - 1.6. Changes from previous versions - - There have been no technical changes to the deflate format since - version 1.1 of this specification. In version 1.2, some - terminology was changed. Version 1.3 is a conversion of the - specification to RFC style. - -2. Compressed representation overview - - A compressed data set consists of a series of blocks, corresponding - to successive blocks of input data. The block sizes are arbitrary, - except that non-compressible blocks are limited to 65,535 bytes. - - Each block is compressed using a combination of the LZ77 algorithm - and Huffman coding. The Huffman trees for each block are independent - of those for previous or subsequent blocks; the LZ77 algorithm may - use a reference to a duplicated string occurring in a previous block, - up to 32K input bytes before. - - Each block consists of two parts: a pair of Huffman code trees that - describe the representation of the compressed data part, and a - compressed data part. (The Huffman trees themselves are compressed - using Huffman encoding.) The compressed data consists of a series of - elements of two types: literal bytes (of strings that have not been - detected as duplicated within the previous 32K input bytes), and - pointers to duplicated strings, where a pointer is represented as a - pair . The representation used in the - "deflate" format limits distances to 32K bytes and lengths to 258 - bytes, but does not limit the size of a block, except for - uncompressible blocks, which are limited as noted above. - - Each type of value (literals, distances, and lengths) in the - compressed data is represented using a Huffman code, using one code - tree for literals and lengths and a separate code tree for distances. - The code trees for each block appear in a compact form just before - the compressed data for that block. - - - - - - - - - - -Deutsch Informational [Page 4] - -RFC 1951 DEFLATE Compressed Data Format Specification May 1996 - - -3. Detailed specification - - 3.1. Overall conventions In the diagrams below, a box like this: - - +---+ - | | <-- the vertical bars might be missing - +---+ - - represents one byte; a box like this: - - +==============+ - | | - +==============+ - - represents a variable number of bytes. - - Bytes stored within a computer do not have a "bit order", since - they are always treated as a unit. However, a byte considered as - an integer between 0 and 255 does have a most- and least- - significant bit, and since we write numbers with the most- - significant digit on the left, we also write bytes with the most- - significant bit on the left. In the diagrams below, we number the - bits of a byte so that bit 0 is the least-significant bit, i.e., - the bits are numbered: - - +--------+ - |76543210| - +--------+ - - Within a computer, a number may occupy multiple bytes. All - multi-byte numbers in the format described here are stored with - the least-significant byte first (at the lower memory address). - For example, the decimal number 520 is stored as: - - 0 1 - +--------+--------+ - |00001000|00000010| - +--------+--------+ - ^ ^ - | | - | + more significant byte = 2 x 256 - + less significant byte = 8 - - 3.1.1. Packing into bytes - - This document does not address the issue of the order in which - bits of a byte are transmitted on a bit-sequential medium, - since the final data format described here is byte- rather than - - - -Deutsch Informational [Page 5] - -RFC 1951 DEFLATE Compressed Data Format Specification May 1996 - - - bit-oriented. However, we describe the compressed block format - in below, as a sequence of data elements of various bit - lengths, not a sequence of bytes. We must therefore specify - how to pack these data elements into bytes to form the final - compressed byte sequence: - - * Data elements are packed into bytes in order of - increasing bit number within the byte, i.e., starting - with the least-significant bit of the byte. - * Data elements other than Huffman codes are packed - starting with the least-significant bit of the data - element. - * Huffman codes are packed starting with the most- - significant bit of the code. - - In other words, if one were to print out the compressed data as - a sequence of bytes, starting with the first byte at the - *right* margin and proceeding to the *left*, with the most- - significant bit of each byte on the left as usual, one would be - able to parse the result from right to left, with fixed-width - elements in the correct MSB-to-LSB order and Huffman codes in - bit-reversed order (i.e., with the first bit of the code in the - relative LSB position). - - 3.2. Compressed block format - - 3.2.1. Synopsis of prefix and Huffman coding - - Prefix coding represents symbols from an a priori known - alphabet by bit sequences (codes), one code for each symbol, in - a manner such that different symbols may be represented by bit - sequences of different lengths, but a parser can always parse - an encoded string unambiguously symbol-by-symbol. - - We define a prefix code in terms of a binary tree in which the - two edges descending from each non-leaf node are labeled 0 and - 1 and in which the leaf nodes correspond one-for-one with (are - labeled with) the symbols of the alphabet; then the code for a - symbol is the sequence of 0's and 1's on the edges leading from - the root to the leaf labeled with that symbol. For example: - - - - - - - - - - - -Deutsch Informational [Page 6] - -RFC 1951 DEFLATE Compressed Data Format Specification May 1996 - - - /\ Symbol Code - 0 1 ------ ---- - / \ A 00 - /\ B B 1 - 0 1 C 011 - / \ D 010 - A /\ - 0 1 - / \ - D C - - A parser can decode the next symbol from an encoded input - stream by walking down the tree from the root, at each step - choosing the edge corresponding to the next input bit. - - Given an alphabet with known symbol frequencies, the Huffman - algorithm allows the construction of an optimal prefix code - (one which represents strings with those symbol frequencies - using the fewest bits of any possible prefix codes for that - alphabet). Such a code is called a Huffman code. (See - reference [1] in Chapter 5, references for additional - information on Huffman codes.) - - Note that in the "deflate" format, the Huffman codes for the - various alphabets must not exceed certain maximum code lengths. - This constraint complicates the algorithm for computing code - lengths from symbol frequencies. Again, see Chapter 5, - references for details. - - 3.2.2. Use of Huffman coding in the "deflate" format - - The Huffman codes used for each alphabet in the "deflate" - format have two additional rules: - - * All codes of a given bit length have lexicographically - consecutive values, in the same order as the symbols - they represent; - - * Shorter codes lexicographically precede longer codes. - - - - - - - - - - - - -Deutsch Informational [Page 7] - -RFC 1951 DEFLATE Compressed Data Format Specification May 1996 - - - We could recode the example above to follow this rule as - follows, assuming that the order of the alphabet is ABCD: - - Symbol Code - ------ ---- - A 10 - B 0 - C 110 - D 111 - - I.e., 0 precedes 10 which precedes 11x, and 110 and 111 are - lexicographically consecutive. - - Given this rule, we can define the Huffman code for an alphabet - just by giving the bit lengths of the codes for each symbol of - the alphabet in order; this is sufficient to determine the - actual codes. In our example, the code is completely defined - by the sequence of bit lengths (2, 1, 3, 3). The following - algorithm generates the codes as integers, intended to be read - from most- to least-significant bit. The code lengths are - initially in tree[I].Len; the codes are produced in - tree[I].Code. - - 1) Count the number of codes for each code length. Let - bl_count[N] be the number of codes of length N, N >= 1. - - 2) Find the numerical value of the smallest code for each - code length: - - code = 0; - bl_count[0] = 0; - for (bits = 1; bits <= MAX_BITS; bits++) { - code = (code + bl_count[bits-1]) << 1; - next_code[bits] = code; - } - - 3) Assign numerical values to all codes, using consecutive - values for all codes of the same length with the base - values determined at step 2. Codes that are never used - (which have a bit length of zero) must not be assigned a - value. - - for (n = 0; n <= max_code; n++) { - len = tree[n].Len; - if (len != 0) { - tree[n].Code = next_code[len]; - next_code[len]++; - } - - - -Deutsch Informational [Page 8] - -RFC 1951 DEFLATE Compressed Data Format Specification May 1996 - - - } - - Example: - - Consider the alphabet ABCDEFGH, with bit lengths (3, 3, 3, 3, - 3, 2, 4, 4). After step 1, we have: - - N bl_count[N] - - ----------- - 2 1 - 3 5 - 4 2 - - Step 2 computes the following next_code values: - - N next_code[N] - - ------------ - 1 0 - 2 0 - 3 2 - 4 14 - - Step 3 produces the following code values: - - Symbol Length Code - ------ ------ ---- - A 3 010 - B 3 011 - C 3 100 - D 3 101 - E 3 110 - F 2 00 - G 4 1110 - H 4 1111 - - 3.2.3. Details of block format - - Each block of compressed data begins with 3 header bits - containing the following data: - - first bit BFINAL - next 2 bits BTYPE - - Note that the header bits do not necessarily begin on a byte - boundary, since a block does not necessarily occupy an integral - number of bytes. - - - - - -Deutsch Informational [Page 9] - -RFC 1951 DEFLATE Compressed Data Format Specification May 1996 - - - BFINAL is set if and only if this is the last block of the data - set. - - BTYPE specifies how the data are compressed, as follows: - - 00 - no compression - 01 - compressed with fixed Huffman codes - 10 - compressed with dynamic Huffman codes - 11 - reserved (error) - - The only difference between the two compressed cases is how the - Huffman codes for the literal/length and distance alphabets are - defined. - - In all cases, the decoding algorithm for the actual data is as - follows: - - do - read block header from input stream. - if stored with no compression - skip any remaining bits in current partially - processed byte - read LEN and NLEN (see next section) - copy LEN bytes of data to output - otherwise - if compressed with dynamic Huffman codes - read representation of code trees (see - subsection below) - loop (until end of block code recognized) - decode literal/length value from input stream - if value < 256 - copy value (literal byte) to output stream - otherwise - if value = end of block (256) - break from loop - otherwise (value = 257..285) - decode distance from input stream - - move backwards distance bytes in the output - stream, and copy length bytes from this - position to the output stream. - end loop - while not last block - - Note that a duplicated string reference may refer to a string - in a previous block; i.e., the backward distance may cross one - or more block boundaries. However a distance cannot refer past - the beginning of the output stream. (An application using a - - - -Deutsch Informational [Page 10] - -RFC 1951 DEFLATE Compressed Data Format Specification May 1996 - - - preset dictionary might discard part of the output stream; a - distance can refer to that part of the output stream anyway) - Note also that the referenced string may overlap the current - position; for example, if the last 2 bytes decoded have values - X and Y, a string reference with - adds X,Y,X,Y,X to the output stream. - - We now specify each compression method in turn. - - 3.2.4. Non-compressed blocks (BTYPE=00) - - Any bits of input up to the next byte boundary are ignored. - The rest of the block consists of the following information: - - 0 1 2 3 4... - +---+---+---+---+================================+ - | LEN | NLEN |... LEN bytes of literal data...| - +---+---+---+---+================================+ - - LEN is the number of data bytes in the block. NLEN is the - one's complement of LEN. - - 3.2.5. Compressed blocks (length and distance codes) - - As noted above, encoded data blocks in the "deflate" format - consist of sequences of symbols drawn from three conceptually - distinct alphabets: either literal bytes, from the alphabet of - byte values (0..255), or pairs, - where the length is drawn from (3..258) and the distance is - drawn from (1..32,768). In fact, the literal and length - alphabets are merged into a single alphabet (0..285), where - values 0..255 represent literal bytes, the value 256 indicates - end-of-block, and values 257..285 represent length codes - (possibly in conjunction with extra bits following the symbol - code) as follows: - - - - - - - - - - - - - - - - -Deutsch Informational [Page 11] - -RFC 1951 DEFLATE Compressed Data Format Specification May 1996 - - - Extra Extra Extra - Code Bits Length(s) Code Bits Lengths Code Bits Length(s) - ---- ---- ------ ---- ---- ------- ---- ---- ------- - 257 0 3 267 1 15,16 277 4 67-82 - 258 0 4 268 1 17,18 278 4 83-98 - 259 0 5 269 2 19-22 279 4 99-114 - 260 0 6 270 2 23-26 280 4 115-130 - 261 0 7 271 2 27-30 281 5 131-162 - 262 0 8 272 2 31-34 282 5 163-194 - 263 0 9 273 3 35-42 283 5 195-226 - 264 0 10 274 3 43-50 284 5 227-257 - 265 1 11,12 275 3 51-58 285 0 258 - 266 1 13,14 276 3 59-66 - - The extra bits should be interpreted as a machine integer - stored with the most-significant bit first, e.g., bits 1110 - represent the value 14. - - Extra Extra Extra - Code Bits Dist Code Bits Dist Code Bits Distance - ---- ---- ---- ---- ---- ------ ---- ---- -------- - 0 0 1 10 4 33-48 20 9 1025-1536 - 1 0 2 11 4 49-64 21 9 1537-2048 - 2 0 3 12 5 65-96 22 10 2049-3072 - 3 0 4 13 5 97-128 23 10 3073-4096 - 4 1 5,6 14 6 129-192 24 11 4097-6144 - 5 1 7,8 15 6 193-256 25 11 6145-8192 - 6 2 9-12 16 7 257-384 26 12 8193-12288 - 7 2 13-16 17 7 385-512 27 12 12289-16384 - 8 3 17-24 18 8 513-768 28 13 16385-24576 - 9 3 25-32 19 8 769-1024 29 13 24577-32768 - - 3.2.6. Compression with fixed Huffman codes (BTYPE=01) - - The Huffman codes for the two alphabets are fixed, and are not - represented explicitly in the data. The Huffman code lengths - for the literal/length alphabet are: - - Lit Value Bits Codes - --------- ---- ----- - 0 - 143 8 00110000 through - 10111111 - 144 - 255 9 110010000 through - 111111111 - 256 - 279 7 0000000 through - 0010111 - 280 - 287 8 11000000 through - 11000111 - - - -Deutsch Informational [Page 12] - -RFC 1951 DEFLATE Compressed Data Format Specification May 1996 - - - The code lengths are sufficient to generate the actual codes, - as described above; we show the codes in the table for added - clarity. Literal/length values 286-287 will never actually - occur in the compressed data, but participate in the code - construction. - - Distance codes 0-31 are represented by (fixed-length) 5-bit - codes, with possible additional bits as shown in the table - shown in Paragraph 3.2.5, above. Note that distance codes 30- - 31 will never actually occur in the compressed data. - - 3.2.7. Compression with dynamic Huffman codes (BTYPE=10) - - The Huffman codes for the two alphabets appear in the block - immediately after the header bits and before the actual - compressed data, first the literal/length code and then the - distance code. Each code is defined by a sequence of code - lengths, as discussed in Paragraph 3.2.2, above. For even - greater compactness, the code length sequences themselves are - compressed using a Huffman code. The alphabet for code lengths - is as follows: - - 0 - 15: Represent code lengths of 0 - 15 - 16: Copy the previous code length 3 - 6 times. - The next 2 bits indicate repeat length - (0 = 3, ... , 3 = 6) - Example: Codes 8, 16 (+2 bits 11), - 16 (+2 bits 10) will expand to - 12 code lengths of 8 (1 + 6 + 5) - 17: Repeat a code length of 0 for 3 - 10 times. - (3 bits of length) - 18: Repeat a code length of 0 for 11 - 138 times - (7 bits of length) - - A code length of 0 indicates that the corresponding symbol in - the literal/length or distance alphabet will not occur in the - block, and should not participate in the Huffman code - construction algorithm given earlier. If only one distance - code is used, it is encoded using one bit, not zero bits; in - this case there is a single code length of one, with one unused - code. One distance code of zero bits means that there are no - distance codes used at all (the data is all literals). - - We can now define the format of the block: - - 5 Bits: HLIT, # of Literal/Length codes - 257 (257 - 286) - 5 Bits: HDIST, # of Distance codes - 1 (1 - 32) - 4 Bits: HCLEN, # of Code Length codes - 4 (4 - 19) - - - -Deutsch Informational [Page 13] - -RFC 1951 DEFLATE Compressed Data Format Specification May 1996 - - - (HCLEN + 4) x 3 bits: code lengths for the code length - alphabet given just above, in the order: 16, 17, 18, - 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15 - - These code lengths are interpreted as 3-bit integers - (0-7); as above, a code length of 0 means the - corresponding symbol (literal/length or distance code - length) is not used. - - HLIT + 257 code lengths for the literal/length alphabet, - encoded using the code length Huffman code - - HDIST + 1 code lengths for the distance alphabet, - encoded using the code length Huffman code - - The actual compressed data of the block, - encoded using the literal/length and distance Huffman - codes - - The literal/length symbol 256 (end of data), - encoded using the literal/length Huffman code - - The code length repeat codes can cross from HLIT + 257 to the - HDIST + 1 code lengths. In other words, all code lengths form - a single sequence of HLIT + HDIST + 258 values. - - 3.3. Compliance - - A compressor may limit further the ranges of values specified in - the previous section and still be compliant; for example, it may - limit the range of backward pointers to some value smaller than - 32K. Similarly, a compressor may limit the size of blocks so that - a compressible block fits in memory. - - A compliant decompressor must accept the full range of possible - values defined in the previous section, and must accept blocks of - arbitrary size. - -4. Compression algorithm details - - While it is the intent of this document to define the "deflate" - compressed data format without reference to any particular - compression algorithm, the format is related to the compressed - formats produced by LZ77 (Lempel-Ziv 1977, see reference [2] below); - since many variations of LZ77 are patented, it is strongly - recommended that the implementor of a compressor follow the general - algorithm presented here, which is known not to be patented per se. - The material in this section is not part of the definition of the - - - -Deutsch Informational [Page 14] - -RFC 1951 DEFLATE Compressed Data Format Specification May 1996 - - - specification per se, and a compressor need not follow it in order to - be compliant. - - The compressor terminates a block when it determines that starting a - new block with fresh trees would be useful, or when the block size - fills up the compressor's block buffer. - - The compressor uses a chained hash table to find duplicated strings, - using a hash function that operates on 3-byte sequences. At any - given point during compression, let XYZ be the next 3 input bytes to - be examined (not necessarily all different, of course). First, the - compressor examines the hash chain for XYZ. If the chain is empty, - the compressor simply writes out X as a literal byte and advances one - byte in the input. If the hash chain is not empty, indicating that - the sequence XYZ (or, if we are unlucky, some other 3 bytes with the - same hash function value) has occurred recently, the compressor - compares all strings on the XYZ hash chain with the actual input data - sequence starting at the current point, and selects the longest - match. - - The compressor searches the hash chains starting with the most recent - strings, to favor small distances and thus take advantage of the - Huffman encoding. The hash chains are singly linked. There are no - deletions from the hash chains; the algorithm simply discards matches - that are too old. To avoid a worst-case situation, very long hash - chains are arbitrarily truncated at a certain length, determined by a - run-time parameter. - - To improve overall compression, the compressor optionally defers the - selection of matches ("lazy matching"): after a match of length N has - been found, the compressor searches for a longer match starting at - the next input byte. If it finds a longer match, it truncates the - previous match to a length of one (thus producing a single literal - byte) and then emits the longer match. Otherwise, it emits the - original match, and, as described above, advances N bytes before - continuing. - - Run-time parameters also control this "lazy match" procedure. If - compression ratio is most important, the compressor attempts a - complete second search regardless of the length of the first match. - In the normal case, if the current match is "long enough", the - compressor reduces the search for a longer match, thus speeding up - the process. If speed is most important, the compressor inserts new - strings in the hash table only when no match was found, or when the - match is not "too long". This degrades the compression ratio but - saves time since there are both fewer insertions and fewer searches. - - - - - -Deutsch Informational [Page 15] - -RFC 1951 DEFLATE Compressed Data Format Specification May 1996 - - -5. References - - [1] Huffman, D. A., "A Method for the Construction of Minimum - Redundancy Codes", Proceedings of the Institute of Radio - Engineers, September 1952, Volume 40, Number 9, pp. 1098-1101. - - [2] Ziv J., Lempel A., "A Universal Algorithm for Sequential Data - Compression", IEEE Transactions on Information Theory, Vol. 23, - No. 3, pp. 337-343. - - [3] Gailly, J.-L., and Adler, M., ZLIB documentation and sources, - available in ftp://ftp.uu.net/pub/archiving/zip/doc/ - - [4] Gailly, J.-L., and Adler, M., GZIP documentation and sources, - available as gzip-*.tar in ftp://prep.ai.mit.edu/pub/gnu/ - - [5] Schwartz, E. S., and Kallick, B. "Generating a canonical prefix - encoding." Comm. ACM, 7,3 (Mar. 1964), pp. 166-169. - - [6] Hirschberg and Lelewer, "Efficient decoding of prefix codes," - Comm. ACM, 33,4, April 1990, pp. 449-459. - -6. Security Considerations - - Any data compression method involves the reduction of redundancy in - the data. Consequently, any corruption of the data is likely to have - severe effects and be difficult to correct. Uncompressed text, on - the other hand, will probably still be readable despite the presence - of some corrupted bytes. - - It is recommended that systems using this data format provide some - means of validating the integrity of the compressed data. See - reference [3], for example. - -7. Source code - - Source code for a C language implementation of a "deflate" compliant - compressor and decompressor is available within the zlib package at - ftp://ftp.uu.net/pub/archiving/zip/zlib/. - -8. Acknowledgements - - Trademarks cited in this document are the property of their - respective owners. - - Phil Katz designed the deflate format. Jean-Loup Gailly and Mark - Adler wrote the related software described in this specification. - Glenn Randers-Pehrson converted this document to RFC and HTML format. - - - -Deutsch Informational [Page 16] - -RFC 1951 DEFLATE Compressed Data Format Specification May 1996 - - -9. Author's Address - - L. Peter Deutsch - Aladdin Enterprises - 203 Santa Margarita Ave. - Menlo Park, CA 94025 - - Phone: (415) 322-0103 (AM only) - FAX: (415) 322-1734 - EMail: - - Questions about the technical content of this specification can be - sent by email to: - - Jean-Loup Gailly and - Mark Adler - - Editorial comments on this specification can be sent by email to: - - L. Peter Deutsch and - Glenn Randers-Pehrson - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Deutsch Informational [Page 17] - diff --git a/compat/zlib/doc/rfc1952.txt b/compat/zlib/doc/rfc1952.txt deleted file mode 100644 index a8e51b4..0000000 --- a/compat/zlib/doc/rfc1952.txt +++ /dev/null @@ -1,675 +0,0 @@ - - - - - - -Network Working Group P. Deutsch -Request for Comments: 1952 Aladdin Enterprises -Category: Informational May 1996 - - - GZIP file format specification version 4.3 - -Status of This Memo - - This memo provides information for the Internet community. This memo - does not specify an Internet standard of any kind. Distribution of - this memo is unlimited. - -IESG Note: - - The IESG takes no position on the validity of any Intellectual - Property Rights statements contained in this document. - -Notices - - Copyright (c) 1996 L. Peter Deutsch - - Permission is granted to copy and distribute this document for any - purpose and without charge, including translations into other - languages and incorporation into compilations, provided that the - copyright notice and this notice are preserved, and that any - substantive changes or deletions from the original are clearly - marked. - - A pointer to the latest version of this and related documentation in - HTML format can be found at the URL - . - -Abstract - - This specification defines a lossless compressed data format that is - compatible with the widely used GZIP utility. The format includes a - cyclic redundancy check value for detecting data corruption. The - format presently uses the DEFLATE method of compression but can be - easily extended to use other compression methods. The format can be - implemented readily in a manner not covered by patents. - - - - - - - - - - -Deutsch Informational [Page 1] - -RFC 1952 GZIP File Format Specification May 1996 - - -Table of Contents - - 1. Introduction ................................................... 2 - 1.1. Purpose ................................................... 2 - 1.2. Intended audience ......................................... 3 - 1.3. Scope ..................................................... 3 - 1.4. Compliance ................................................ 3 - 1.5. Definitions of terms and conventions used ................. 3 - 1.6. Changes from previous versions ............................ 3 - 2. Detailed specification ......................................... 4 - 2.1. Overall conventions ....................................... 4 - 2.2. File format ............................................... 5 - 2.3. Member format ............................................. 5 - 2.3.1. Member header and trailer ........................... 6 - 2.3.1.1. Extra field ................................... 8 - 2.3.1.2. Compliance .................................... 9 - 3. References .................................................. 9 - 4. Security Considerations .................................... 10 - 5. Acknowledgements ........................................... 10 - 6. Author's Address ........................................... 10 - 7. Appendix: Jean-Loup Gailly's gzip utility .................. 11 - 8. Appendix: Sample CRC Code .................................. 11 - -1. Introduction - - 1.1. Purpose - - The purpose of this specification is to define a lossless - compressed data format that: - - * Is independent of CPU type, operating system, file system, - and character set, and hence can be used for interchange; - * Can compress or decompress a data stream (as opposed to a - randomly accessible file) to produce another data stream, - using only an a priori bounded amount of intermediate - storage, and hence can be used in data communications or - similar structures such as Unix filters; - * Compresses data with efficiency comparable to the best - currently available general-purpose compression methods, - and in particular considerably better than the "compress" - program; - * Can be implemented readily in a manner not covered by - patents, and hence can be practiced freely; - * Is compatible with the file format produced by the current - widely used gzip utility, in that conforming decompressors - will be able to read data produced by the existing gzip - compressor. - - - - -Deutsch Informational [Page 2] - -RFC 1952 GZIP File Format Specification May 1996 - - - The data format defined by this specification does not attempt to: - - * Provide random access to compressed data; - * Compress specialized data (e.g., raster graphics) as well as - the best currently available specialized algorithms. - - 1.2. Intended audience - - This specification is intended for use by implementors of software - to compress data into gzip format and/or decompress data from gzip - format. - - The text of the specification assumes a basic background in - programming at the level of bits and other primitive data - representations. - - 1.3. Scope - - The specification specifies a compression method and a file format - (the latter assuming only that a file can store a sequence of - arbitrary bytes). It does not specify any particular interface to - a file system or anything about character sets or encodings - (except for file names and comments, which are optional). - - 1.4. Compliance - - Unless otherwise indicated below, a compliant decompressor must be - able to accept and decompress any file that conforms to all the - specifications presented here; a compliant compressor must produce - files that conform to all the specifications presented here. The - material in the appendices is not part of the specification per se - and is not relevant to compliance. - - 1.5. Definitions of terms and conventions used - - byte: 8 bits stored or transmitted as a unit (same as an octet). - (For this specification, a byte is exactly 8 bits, even on - machines which store a character on a number of bits different - from 8.) See below for the numbering of bits within a byte. - - 1.6. Changes from previous versions - - There have been no technical changes to the gzip format since - version 4.1 of this specification. In version 4.2, some - terminology was changed, and the sample CRC code was rewritten for - clarity and to eliminate the requirement for the caller to do pre- - and post-conditioning. Version 4.3 is a conversion of the - specification to RFC style. - - - -Deutsch Informational [Page 3] - -RFC 1952 GZIP File Format Specification May 1996 - - -2. Detailed specification - - 2.1. Overall conventions - - In the diagrams below, a box like this: - - +---+ - | | <-- the vertical bars might be missing - +---+ - - represents one byte; a box like this: - - +==============+ - | | - +==============+ - - represents a variable number of bytes. - - Bytes stored within a computer do not have a "bit order", since - they are always treated as a unit. However, a byte considered as - an integer between 0 and 255 does have a most- and least- - significant bit, and since we write numbers with the most- - significant digit on the left, we also write bytes with the most- - significant bit on the left. In the diagrams below, we number the - bits of a byte so that bit 0 is the least-significant bit, i.e., - the bits are numbered: - - +--------+ - |76543210| - +--------+ - - This document does not address the issue of the order in which - bits of a byte are transmitted on a bit-sequential medium, since - the data format described here is byte- rather than bit-oriented. - - Within a computer, a number may occupy multiple bytes. All - multi-byte numbers in the format described here are stored with - the least-significant byte first (at the lower memory address). - For example, the decimal number 520 is stored as: - - 0 1 - +--------+--------+ - |00001000|00000010| - +--------+--------+ - ^ ^ - | | - | + more significant byte = 2 x 256 - + less significant byte = 8 - - - -Deutsch Informational [Page 4] - -RFC 1952 GZIP File Format Specification May 1996 - - - 2.2. File format - - A gzip file consists of a series of "members" (compressed data - sets). The format of each member is specified in the following - section. The members simply appear one after another in the file, - with no additional information before, between, or after them. - - 2.3. Member format - - Each member has the following structure: - - +---+---+---+---+---+---+---+---+---+---+ - |ID1|ID2|CM |FLG| MTIME |XFL|OS | (more-->) - +---+---+---+---+---+---+---+---+---+---+ - - (if FLG.FEXTRA set) - - +---+---+=================================+ - | XLEN |...XLEN bytes of "extra field"...| (more-->) - +---+---+=================================+ - - (if FLG.FNAME set) - - +=========================================+ - |...original file name, zero-terminated...| (more-->) - +=========================================+ - - (if FLG.FCOMMENT set) - - +===================================+ - |...file comment, zero-terminated...| (more-->) - +===================================+ - - (if FLG.FHCRC set) - - +---+---+ - | CRC16 | - +---+---+ - - +=======================+ - |...compressed blocks...| (more-->) - +=======================+ - - 0 1 2 3 4 5 6 7 - +---+---+---+---+---+---+---+---+ - | CRC32 | ISIZE | - +---+---+---+---+---+---+---+---+ - - - - -Deutsch Informational [Page 5] - -RFC 1952 GZIP File Format Specification May 1996 - - - 2.3.1. Member header and trailer - - ID1 (IDentification 1) - ID2 (IDentification 2) - These have the fixed values ID1 = 31 (0x1f, \037), ID2 = 139 - (0x8b, \213), to identify the file as being in gzip format. - - CM (Compression Method) - This identifies the compression method used in the file. CM - = 0-7 are reserved. CM = 8 denotes the "deflate" - compression method, which is the one customarily used by - gzip and which is documented elsewhere. - - FLG (FLaGs) - This flag byte is divided into individual bits as follows: - - bit 0 FTEXT - bit 1 FHCRC - bit 2 FEXTRA - bit 3 FNAME - bit 4 FCOMMENT - bit 5 reserved - bit 6 reserved - bit 7 reserved - - If FTEXT is set, the file is probably ASCII text. This is - an optional indication, which the compressor may set by - checking a small amount of the input data to see whether any - non-ASCII characters are present. In case of doubt, FTEXT - is cleared, indicating binary data. For systems which have - different file formats for ascii text and binary data, the - decompressor can use FTEXT to choose the appropriate format. - We deliberately do not specify the algorithm used to set - this bit, since a compressor always has the option of - leaving it cleared and a decompressor always has the option - of ignoring it and letting some other program handle issues - of data conversion. - - If FHCRC is set, a CRC16 for the gzip header is present, - immediately before the compressed data. The CRC16 consists - of the two least significant bytes of the CRC32 for all - bytes of the gzip header up to and not including the CRC16. - [The FHCRC bit was never set by versions of gzip up to - 1.2.4, even though it was documented with a different - meaning in gzip 1.2.4.] - - If FEXTRA is set, optional extra fields are present, as - described in a following section. - - - -Deutsch Informational [Page 6] - -RFC 1952 GZIP File Format Specification May 1996 - - - If FNAME is set, an original file name is present, - terminated by a zero byte. The name must consist of ISO - 8859-1 (LATIN-1) characters; on operating systems using - EBCDIC or any other character set for file names, the name - must be translated to the ISO LATIN-1 character set. This - is the original name of the file being compressed, with any - directory components removed, and, if the file being - compressed is on a file system with case insensitive names, - forced to lower case. There is no original file name if the - data was compressed from a source other than a named file; - for example, if the source was stdin on a Unix system, there - is no file name. - - If FCOMMENT is set, a zero-terminated file comment is - present. This comment is not interpreted; it is only - intended for human consumption. The comment must consist of - ISO 8859-1 (LATIN-1) characters. Line breaks should be - denoted by a single line feed character (10 decimal). - - Reserved FLG bits must be zero. - - MTIME (Modification TIME) - This gives the most recent modification time of the original - file being compressed. The time is in Unix format, i.e., - seconds since 00:00:00 GMT, Jan. 1, 1970. (Note that this - may cause problems for MS-DOS and other systems that use - local rather than Universal time.) If the compressed data - did not come from a file, MTIME is set to the time at which - compression started. MTIME = 0 means no time stamp is - available. - - XFL (eXtra FLags) - These flags are available for use by specific compression - methods. The "deflate" method (CM = 8) sets these flags as - follows: - - XFL = 2 - compressor used maximum compression, - slowest algorithm - XFL = 4 - compressor used fastest algorithm - - OS (Operating System) - This identifies the type of file system on which compression - took place. This may be useful in determining end-of-line - convention for text files. The currently defined values are - as follows: - - - - - - -Deutsch Informational [Page 7] - -RFC 1952 GZIP File Format Specification May 1996 - - - 0 - FAT filesystem (MS-DOS, OS/2, NT/Win32) - 1 - Amiga - 2 - VMS (or OpenVMS) - 3 - Unix - 4 - VM/CMS - 5 - Atari TOS - 6 - HPFS filesystem (OS/2, NT) - 7 - Macintosh - 8 - Z-System - 9 - CP/M - 10 - TOPS-20 - 11 - NTFS filesystem (NT) - 12 - QDOS - 13 - Acorn RISCOS - 255 - unknown - - XLEN (eXtra LENgth) - If FLG.FEXTRA is set, this gives the length of the optional - extra field. See below for details. - - CRC32 (CRC-32) - This contains a Cyclic Redundancy Check value of the - uncompressed data computed according to CRC-32 algorithm - used in the ISO 3309 standard and in section 8.1.1.6.2 of - ITU-T recommendation V.42. (See http://www.iso.ch for - ordering ISO documents. See gopher://info.itu.ch for an - online version of ITU-T V.42.) - - ISIZE (Input SIZE) - This contains the size of the original (uncompressed) input - data modulo 2^32. - - 2.3.1.1. Extra field - - If the FLG.FEXTRA bit is set, an "extra field" is present in - the header, with total length XLEN bytes. It consists of a - series of subfields, each of the form: - - +---+---+---+---+==================================+ - |SI1|SI2| LEN |... LEN bytes of subfield data ...| - +---+---+---+---+==================================+ - - SI1 and SI2 provide a subfield ID, typically two ASCII letters - with some mnemonic value. Jean-Loup Gailly - is maintaining a registry of subfield - IDs; please send him any subfield ID you wish to use. Subfield - IDs with SI2 = 0 are reserved for future use. The following - IDs are currently defined: - - - -Deutsch Informational [Page 8] - -RFC 1952 GZIP File Format Specification May 1996 - - - SI1 SI2 Data - ---------- ---------- ---- - 0x41 ('A') 0x70 ('P') Apollo file type information - - LEN gives the length of the subfield data, excluding the 4 - initial bytes. - - 2.3.1.2. Compliance - - A compliant compressor must produce files with correct ID1, - ID2, CM, CRC32, and ISIZE, but may set all the other fields in - the fixed-length part of the header to default values (255 for - OS, 0 for all others). The compressor must set all reserved - bits to zero. - - A compliant decompressor must check ID1, ID2, and CM, and - provide an error indication if any of these have incorrect - values. It must examine FEXTRA/XLEN, FNAME, FCOMMENT and FHCRC - at least so it can skip over the optional fields if they are - present. It need not examine any other part of the header or - trailer; in particular, a decompressor may ignore FTEXT and OS - and always produce binary output, and still be compliant. A - compliant decompressor must give an error indication if any - reserved bit is non-zero, since such a bit could indicate the - presence of a new field that would cause subsequent data to be - interpreted incorrectly. - -3. References - - [1] "Information Processing - 8-bit single-byte coded graphic - character sets - Part 1: Latin alphabet No.1" (ISO 8859-1:1987). - The ISO 8859-1 (Latin-1) character set is a superset of 7-bit - ASCII. Files defining this character set are available as - iso_8859-1.* in ftp://ftp.uu.net/graphics/png/documents/ - - [2] ISO 3309 - - [3] ITU-T recommendation V.42 - - [4] Deutsch, L.P.,"DEFLATE Compressed Data Format Specification", - available in ftp://ftp.uu.net/pub/archiving/zip/doc/ - - [5] Gailly, J.-L., GZIP documentation, available as gzip-*.tar in - ftp://prep.ai.mit.edu/pub/gnu/ - - [6] Sarwate, D.V., "Computation of Cyclic Redundancy Checks via Table - Look-Up", Communications of the ACM, 31(8), pp.1008-1013. - - - - -Deutsch Informational [Page 9] - -RFC 1952 GZIP File Format Specification May 1996 - - - [7] Schwaderer, W.D., "CRC Calculation", April 85 PC Tech Journal, - pp.118-133. - - [8] ftp://ftp.adelaide.edu.au/pub/rocksoft/papers/crc_v3.txt, - describing the CRC concept. - -4. Security Considerations - - Any data compression method involves the reduction of redundancy in - the data. Consequently, any corruption of the data is likely to have - severe effects and be difficult to correct. Uncompressed text, on - the other hand, will probably still be readable despite the presence - of some corrupted bytes. - - It is recommended that systems using this data format provide some - means of validating the integrity of the compressed data, such as by - setting and checking the CRC-32 check value. - -5. Acknowledgements - - Trademarks cited in this document are the property of their - respective owners. - - Jean-Loup Gailly designed the gzip format and wrote, with Mark Adler, - the related software described in this specification. Glenn - Randers-Pehrson converted this document to RFC and HTML format. - -6. Author's Address - - L. Peter Deutsch - Aladdin Enterprises - 203 Santa Margarita Ave. - Menlo Park, CA 94025 - - Phone: (415) 322-0103 (AM only) - FAX: (415) 322-1734 - EMail: - - Questions about the technical content of this specification can be - sent by email to: - - Jean-Loup Gailly and - Mark Adler - - Editorial comments on this specification can be sent by email to: - - L. Peter Deutsch and - Glenn Randers-Pehrson - - - -Deutsch Informational [Page 10] - -RFC 1952 GZIP File Format Specification May 1996 - - -7. Appendix: Jean-Loup Gailly's gzip utility - - The most widely used implementation of gzip compression, and the - original documentation on which this specification is based, were - created by Jean-Loup Gailly . Since this - implementation is a de facto standard, we mention some more of its - features here. Again, the material in this section is not part of - the specification per se, and implementations need not follow it to - be compliant. - - When compressing or decompressing a file, gzip preserves the - protection, ownership, and modification time attributes on the local - file system, since there is no provision for representing protection - attributes in the gzip file format itself. Since the file format - includes a modification time, the gzip decompressor provides a - command line switch that assigns the modification time from the file, - rather than the local modification time of the compressed input, to - the decompressed output. - -8. Appendix: Sample CRC Code - - The following sample code represents a practical implementation of - the CRC (Cyclic Redundancy Check). (See also ISO 3309 and ITU-T V.42 - for a formal specification.) - - The sample code is in the ANSI C programming language. Non C users - may find it easier to read with these hints: - - & Bitwise AND operator. - ^ Bitwise exclusive-OR operator. - >> Bitwise right shift operator. When applied to an - unsigned quantity, as here, right shift inserts zero - bit(s) at the left. - ! Logical NOT operator. - ++ "n++" increments the variable n. - 0xNNN 0x introduces a hexadecimal (base 16) constant. - Suffix L indicates a long value (at least 32 bits). - - /* Table of CRCs of all 8-bit messages. */ - unsigned long crc_table[256]; - - /* Flag: has the table been computed? Initially false. */ - int crc_table_computed = 0; - - /* Make the table for a fast CRC. */ - void make_crc_table(void) - { - unsigned long c; - - - -Deutsch Informational [Page 11] - -RFC 1952 GZIP File Format Specification May 1996 - - - int n, k; - for (n = 0; n < 256; n++) { - c = (unsigned long) n; - for (k = 0; k < 8; k++) { - if (c & 1) { - c = 0xedb88320L ^ (c >> 1); - } else { - c = c >> 1; - } - } - crc_table[n] = c; - } - crc_table_computed = 1; - } - - /* - Update a running crc with the bytes buf[0..len-1] and return - the updated crc. The crc should be initialized to zero. Pre- and - post-conditioning (one's complement) is performed within this - function so it shouldn't be done by the caller. Usage example: - - unsigned long crc = 0L; - - while (read_buffer(buffer, length) != EOF) { - crc = update_crc(crc, buffer, length); - } - if (crc != original_crc) error(); - */ - unsigned long update_crc(unsigned long crc, - unsigned char *buf, int len) - { - unsigned long c = crc ^ 0xffffffffL; - int n; - - if (!crc_table_computed) - make_crc_table(); - for (n = 0; n < len; n++) { - c = crc_table[(c ^ buf[n]) & 0xff] ^ (c >> 8); - } - return c ^ 0xffffffffL; - } - - /* Return the CRC of the bytes buf[0..len-1]. */ - unsigned long crc(unsigned char *buf, int len) - { - return update_crc(0L, buf, len); - } - - - - -Deutsch Informational [Page 12] - diff --git a/compat/zlib/doc/txtvsbin.txt b/compat/zlib/doc/txtvsbin.txt deleted file mode 100644 index 3d0f063..0000000 --- a/compat/zlib/doc/txtvsbin.txt +++ /dev/null @@ -1,107 +0,0 @@ -A Fast Method for Identifying Plain Text Files -============================================== - - -Introduction ------------- - -Given a file coming from an unknown source, it is sometimes desirable -to find out whether the format of that file is plain text. Although -this may appear like a simple task, a fully accurate detection of the -file type requires heavy-duty semantic analysis on the file contents. -It is, however, possible to obtain satisfactory results by employing -various heuristics. - -Previous versions of PKZip and other zip-compatible compression tools -were using a crude detection scheme: if more than 80% (4/5) of the bytes -found in a certain buffer are within the range [7..127], the file is -labeled as plain text, otherwise it is labeled as binary. A prominent -limitation of this scheme is the restriction to Latin-based alphabets. -Other alphabets, like Greek, Cyrillic or Asian, make extensive use of -the bytes within the range [128..255], and texts using these alphabets -are most often misidentified by this scheme; in other words, the rate -of false negatives is sometimes too high, which means that the recall -is low. Another weakness of this scheme is a reduced precision, due to -the false positives that may occur when binary files containing large -amounts of textual characters are misidentified as plain text. - -In this article we propose a new, simple detection scheme that features -a much increased precision and a near-100% recall. This scheme is -designed to work on ASCII, Unicode and other ASCII-derived alphabets, -and it handles single-byte encodings (ISO-8859, MacRoman, KOI8, etc.) -and variable-sized encodings (ISO-2022, UTF-8, etc.). Wider encodings -(UCS-2/UTF-16 and UCS-4/UTF-32) are not handled, however. - - -The Algorithm -------------- - -The algorithm works by dividing the set of bytecodes [0..255] into three -categories: -- The white list of textual bytecodes: - 9 (TAB), 10 (LF), 13 (CR), 32 (SPACE) to 255. -- The gray list of tolerated bytecodes: - 7 (BEL), 8 (BS), 11 (VT), 12 (FF), 26 (SUB), 27 (ESC). -- The black list of undesired, non-textual bytecodes: - 0 (NUL) to 6, 14 to 31. - -If a file contains at least one byte that belongs to the white list and -no byte that belongs to the black list, then the file is categorized as -plain text; otherwise, it is categorized as binary. (The boundary case, -when the file is empty, automatically falls into the latter category.) - - -Rationale ---------- - -The idea behind this algorithm relies on two observations. - -The first observation is that, although the full range of 7-bit codes -[0..127] is properly specified by the ASCII standard, most control -characters in the range [0..31] are not used in practice. The only -widely-used, almost universally-portable control codes are 9 (TAB), -10 (LF) and 13 (CR). There are a few more control codes that are -recognized on a reduced range of platforms and text viewers/editors: -7 (BEL), 8 (BS), 11 (VT), 12 (FF), 26 (SUB) and 27 (ESC); but these -codes are rarely (if ever) used alone, without being accompanied by -some printable text. Even the newer, portable text formats such as -XML avoid using control characters outside the list mentioned here. - -The second observation is that most of the binary files tend to contain -control characters, especially 0 (NUL). Even though the older text -detection schemes observe the presence of non-ASCII codes from the range -[128..255], the precision rarely has to suffer if this upper range is -labeled as textual, because the files that are genuinely binary tend to -contain both control characters and codes from the upper range. On the -other hand, the upper range needs to be labeled as textual, because it -is used by virtually all ASCII extensions. In particular, this range is -used for encoding non-Latin scripts. - -Since there is no counting involved, other than simply observing the -presence or the absence of some byte values, the algorithm produces -consistent results, regardless what alphabet encoding is being used. -(If counting were involved, it could be possible to obtain different -results on a text encoded, say, using ISO-8859-16 versus UTF-8.) - -There is an extra category of plain text files that are "polluted" with -one or more black-listed codes, either by mistake or by peculiar design -considerations. In such cases, a scheme that tolerates a small fraction -of black-listed codes would provide an increased recall (i.e. more true -positives). This, however, incurs a reduced precision overall, since -false positives are more likely to appear in binary files that contain -large chunks of textual data. Furthermore, "polluted" plain text should -be regarded as binary by general-purpose text detection schemes, because -general-purpose text processing algorithms might not be applicable. -Under this premise, it is safe to say that our detection method provides -a near-100% recall. - -Experiments have been run on many files coming from various platforms -and applications. We tried plain text files, system logs, source code, -formatted office documents, compiled object code, etc. The results -confirm the optimistic assumptions about the capabilities of this -algorithm. - - --- -Cosmin Truta -Last updated: 2006-May-28 -- cgit v0.12 From 279bfdeef3577e9767bfafc7102011176f88034f Mon Sep 17 00:00:00 2001 From: sebres Date: Tue, 7 Mar 2017 11:35:03 +0000 Subject: timerate: don't calculate threshold by too few iterations, because sometimes first iteration(s) can be too fast (cached, delayed clean up, etc). --- generic/tclCmdMZ.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/generic/tclCmdMZ.c b/generic/tclCmdMZ.c index 14ff5f0..b62ccf8 100644 --- a/generic/tclCmdMZ.c +++ b/generic/tclCmdMZ.c @@ -4282,6 +4282,13 @@ usage: if (middle >= stop) { break; } + + /* don't calculate threshold by few iterations, because sometimes + * first iteration(s) can be too fast (cached, delayed clean up, etc) */ + if (count < 10) { + threshold = 1; continue; + } + /* average iteration time in microsecs */ threshold = (middle - start) / count; if (threshold > maxIterTm) { -- cgit v0.12 From 2c343f8ac185506f8f1b90a54ec8c352da541605 Mon Sep 17 00:00:00 2001 From: sebres Date: Tue, 7 Mar 2017 18:19:55 +0000 Subject: expand test constraints of the load-8.x test cases (wrap setup prerequirements as new constraint "teststaticpkg_8.x") --- tests/load.test | 25 ++++++++++++++++--------- 1 file changed, 16 insertions(+), 9 deletions(-) diff --git a/tests/load.test b/tests/load.test index 7c4b47f..4cd1fcd 100644 --- a/tests/load.test +++ b/tests/load.test @@ -185,23 +185,30 @@ test load-7.4 {Tcl_StaticPackage procedure, redundant calls} -setup { info loaded } -result [list {{} Double} {{} More} {{} Another} {{} Test} {*}$currentRealPackages {*}$alreadyTotalLoaded] -teststaticpkg Test 1 1 -teststaticpkg Another 0 1 -teststaticpkg More 0 1 -teststaticpkg Double 0 1 -test load-8.1 {TclGetLoadedPackages procedure} [list teststaticpkg $dll $loaded] { +testConstraint teststaticpkg_8.x \ + [if {[testConstraint teststaticpkg]} { + teststaticpkg Test 1 1 + teststaticpkg Another 0 1 + teststaticpkg More 0 1 + teststaticpkg Double 0 1 + expr 1 + } else { + expr 0 + }] + +test load-8.1 {TclGetLoadedPackages procedure} [list teststaticpkg_8.x $dll $loaded] { lsort -index 1 [info loaded] } [lsort -index 1 [list {{} Double} {{} More} {{} Another} {{} Test} {*}$currentRealPackages {*}$alreadyTotalLoaded]] -test load-8.2 {TclGetLoadedPackages procedure} -body { +test load-8.2 {TclGetLoadedPackages procedure} -constraints {teststaticpkg_8.x} -body { info loaded gorp } -returnCodes error -result {could not find interpreter "gorp"} -test load-8.3a {TclGetLoadedPackages procedure} [list teststaticpkg $dll $loaded] { +test load-8.3a {TclGetLoadedPackages procedure} [list teststaticpkg_8.x $dll $loaded] { lsort -index 1 [info loaded {}] } [lsort -index 1 [list {{} Double} {{} More} {{} Another} {{} Test} [list [file join $testDir pkga$ext] Pkga] [list [file join $testDir pkgb$ext] Pkgb] {*}$alreadyLoaded]] -test load-8.3b {TclGetLoadedPackages procedure} [list teststaticpkg $dll $loaded] { +test load-8.3b {TclGetLoadedPackages procedure} [list teststaticpkg_8.x $dll $loaded] { lsort -index 1 [info loaded child] } [lsort -index 1 [list {{} Test} [list [file join $testDir pkgb$ext] Pkgb]]] -test load-8.4 {TclGetLoadedPackages procedure} [list $dll $loaded teststaticpkg] { +test load-8.4 {TclGetLoadedPackages procedure} [list teststaticpkg_8.x $dll $loaded] { load [file join $testDir pkgb$ext] pkgb list [lsort -index 1 [info loaded {}]] [lsort [info commands pkgb_*]] } [list [lsort -index 1 [concat [list [list [file join $testDir pkgb$ext] Pkgb] {{} Double} {{} More} {{} Another} {{} Test} [list [file join $testDir pkga$ext] Pkga]] $alreadyLoaded]] {pkgb_demo pkgb_sub pkgb_unsafe}] -- cgit v0.12 From b2181df698c6eb7d579e90e5690d23e24cd6c730 Mon Sep 17 00:00:00 2001 From: "jan.nijtmans" Date: Wed, 8 Mar 2017 13:56:55 +0000 Subject: Fix compile error on Cygwin, and double definition of TclUnixWaitForFile() --- unix/tclEpollNotfy.c | 2 +- unix/tclUnixChan.c | 160 --------------------------------------------------- unix/tclUnixNotfy.c | 4 +- 3 files changed, 2 insertions(+), 164 deletions(-) diff --git a/unix/tclEpollNotfy.c b/unix/tclEpollNotfy.c index 7355564..28fc834 100644 --- a/unix/tclEpollNotfy.c +++ b/unix/tclEpollNotfy.c @@ -745,7 +745,7 @@ Tcl_WaitForEvent( * Wait or poll for new events, queue Tcl events for the FileHandlers * corresponding to them, and update the FileHandlers' mask of events * of interest registered by the last call to Tcl_CreateFileHandler(). - * + * * Events for the eventfd(2)/trigger pipe are processed here in order * to facilitate inter-thread IPC. If another thread intends to wake * up this thread whilst it's blocking on PlatformEventsWait(), it diff --git a/unix/tclUnixChan.c b/unix/tclUnixChan.c index 6418f48..08b4805 100644 --- a/unix/tclUnixChan.c +++ b/unix/tclUnixChan.c @@ -1726,166 +1726,6 @@ Tcl_GetOpenFile( return TCL_ERROR; } -#ifndef HAVE_COREFOUNDATION /* Darwin/Mac OS X CoreFoundation notifier is - * in tclMacOSXNotify.c */ -/* - *---------------------------------------------------------------------- - * - * TclUnixWaitForFile -- - * - * This function waits synchronously for a file to become readable or - * writable, with an optional timeout. - * - * Results: - * The return value is an OR'ed combination of TCL_READABLE, - * TCL_WRITABLE, and TCL_EXCEPTION, indicating the conditions that are - * present on file at the time of the return. This function will not - * return until either "timeout" milliseconds have elapsed or at least - * one of the conditions given by mask has occurred for file (a return - * value of 0 means that a timeout occurred). No normal events will be - * serviced during the execution of this function. - * - * Side effects: - * Time passes. - * - *---------------------------------------------------------------------- - */ - -int -TclUnixWaitForFile( - int fd, /* Handle for file on which to wait. */ - int mask, /* What to wait for: OR'ed combination of - * TCL_READABLE, TCL_WRITABLE, and - * TCL_EXCEPTION. */ - int timeout) /* Maximum amount of time to wait for one of - * the conditions in mask to occur, in - * milliseconds. A value of 0 means don't wait - * at all, and a value of -1 means wait - * forever. */ -{ - Tcl_Time abortTime = {0, 0}, now; /* silence gcc 4 warning */ - struct timeval blockTime, *timeoutPtr; - int numFound, result = 0; - fd_set readableMask; - fd_set writableMask; - fd_set exceptionMask; - -#ifndef _DARWIN_C_SOURCE - /* - * Sanity check fd. - */ - - if (fd >= FD_SETSIZE) { - Tcl_Panic("TclUnixWaitForFile can't handle file id %d", fd); - /* must never get here, or select masks overrun will occur below */ - } -#endif - - /* - * If there is a non-zero finite timeout, compute the time when we give - * up. - */ - - if (timeout > 0) { - Tcl_GetTime(&now); - abortTime.sec = now.sec + timeout/1000; - abortTime.usec = now.usec + (timeout%1000)*1000; - if (abortTime.usec >= 1000000) { - abortTime.usec -= 1000000; - abortTime.sec += 1; - } - timeoutPtr = &blockTime; - } else if (timeout == 0) { - timeoutPtr = &blockTime; - blockTime.tv_sec = 0; - blockTime.tv_usec = 0; - } else { - timeoutPtr = NULL; - } - - /* - * Initialize the select masks. - */ - - FD_ZERO(&readableMask); - FD_ZERO(&writableMask); - FD_ZERO(&exceptionMask); - - /* - * Loop in a mini-event loop of our own, waiting for either the file to - * become ready or a timeout to occur. - */ - - while (1) { - if (timeout > 0) { - blockTime.tv_sec = abortTime.sec - now.sec; - blockTime.tv_usec = abortTime.usec - now.usec; - if (blockTime.tv_usec < 0) { - blockTime.tv_sec -= 1; - blockTime.tv_usec += 1000000; - } - if (blockTime.tv_sec < 0) { - blockTime.tv_sec = 0; - blockTime.tv_usec = 0; - } - } - - /* - * Setup the select masks for the fd. - */ - - if (mask & TCL_READABLE) { - FD_SET(fd, &readableMask); - } - if (mask & TCL_WRITABLE) { - FD_SET(fd, &writableMask); - } - if (mask & TCL_EXCEPTION) { - FD_SET(fd, &exceptionMask); - } - - /* - * Wait for the event or a timeout. - */ - - numFound = select(fd + 1, &readableMask, &writableMask, - &exceptionMask, timeoutPtr); - if (numFound == 1) { - if (FD_ISSET(fd, &readableMask)) { - SET_BITS(result, TCL_READABLE); - } - if (FD_ISSET(fd, &writableMask)) { - SET_BITS(result, TCL_WRITABLE); - } - if (FD_ISSET(fd, &exceptionMask)) { - SET_BITS(result, TCL_EXCEPTION); - } - result &= mask; - if (result) { - break; - } - } - if (timeout == 0) { - break; - } - if (timeout < 0) { - continue; - } - - /* - * The select returned early, so we need to recompute the timeout. - */ - - Tcl_GetTime(&now); - if ((abortTime.sec < now.sec) - || (abortTime.sec==now.sec && abortTime.usec<=now.usec)) { - break; - } - } - return result; -} -#endif /* HAVE_COREFOUNDATION */ - /* *---------------------------------------------------------------------- * diff --git a/unix/tclUnixNotfy.c b/unix/tclUnixNotfy.c index 248504b..eb3e8ba 100644 --- a/unix/tclUnixNotfy.c +++ b/unix/tclUnixNotfy.c @@ -322,7 +322,7 @@ AlertSingleThread( * continuously spinning on epoll_wait until the other * threads runs and services the file event. */ - + if (tsdPtr->prevPtr) { tsdPtr->prevPtr->nextPtr = tsdPtr->nextPtr; } else { @@ -396,8 +396,6 @@ AtForkChild(void) * The tsdPtr from before the fork is copied as well. But since * we are paranoic, we don't trust its condvar and reset it. */ - pthread_cond_destroy(&tsdPtr->waitCV); - pthread_cond_init(&tsdPtr->waitCV, NULL); #ifdef __CYGWIN__ DestroyWindow(tsdPtr->hwnd); tsdPtr->hwnd = CreateWindowExW(NULL, className, -- cgit v0.12 From bed000d72e4b356700d7e2c85ca69971331f827a Mon Sep 17 00:00:00 2001 From: "jan.nijtmans" Date: Wed, 8 Mar 2017 14:32:15 +0000 Subject: A few more end-of-line spacings --- unix/tclKqueueNotfy.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/unix/tclKqueueNotfy.c b/unix/tclKqueueNotfy.c index 5522f06..049829e 100644 --- a/unix/tclKqueueNotfy.c +++ b/unix/tclKqueueNotfy.c @@ -387,7 +387,7 @@ PlatformEventsInit( Tcl_Panic("fcntl: %s", strerror(errno)); } else { fdFl = fcntl(tsdPtr->triggerPipe[i], F_GETFL); - fdFl |= O_NONBLOCK; + fdFl |= O_NONBLOCK; } if (fcntl(tsdPtr->triggerPipe[i], F_SETFL, fdFl) == -1) { Tcl_Panic("fcntl: %s", strerror(errno)); @@ -780,7 +780,7 @@ Tcl_WaitForEvent( * Wait or poll for new events, queue Tcl events for the FileHandlers * corresponding to them, and update the FileHandlers' mask of events * of interest registered by the last call to Tcl_CreateFileHandler(). - * + * * Events for the trigger pipe are processed here in order to facilitate * inter-thread IPC. If another thread intends to wake up this thread * whilst it's blocking on PlatformEventsWait(), it write(2)s to the -- cgit v0.12 From f55296bdf01aad11441825c162f074824f3031b5 Mon Sep 17 00:00:00 2001 From: "jan.nijtmans" Date: Wed, 8 Mar 2017 14:50:44 +0000 Subject: minor simplification --- unix/tclUnixNotfy.c | 10 ++-------- 1 file changed, 2 insertions(+), 8 deletions(-) diff --git a/unix/tclUnixNotfy.c b/unix/tclUnixNotfy.c index eb3e8ba..d7bbabe 100644 --- a/unix/tclUnixNotfy.c +++ b/unix/tclUnixNotfy.c @@ -127,8 +127,7 @@ Tcl_AlertNotifier( #endif /* TCL_THREADS */ #else ThreadSpecificData *tsdPtr = clientData; -#ifdef NOTIFIER_EPOLL -#ifdef HAVE_EVENTFD +#if defined(NOTIFIER_EPOLL) && defined(HAVE_EVENTFD) eventFdVal = 1; if (write(tsdPtr->triggerEventFd, &eventFdVal, sizeof(eventFdVal)) != sizeof(eventFdVal)) { @@ -136,14 +135,9 @@ Tcl_AlertNotifier( (void *)tsdPtr); #else if (write(tsdPtr->triggerPipe[1], "", 1) != 1) { - Tcl_Panic("Tcl_AlertNotifier: unable to write to %p->triggerEventFd", - (void *)tsdPtr); -#endif -#else - if (write(tsdPtr->triggerPipe[1], "", 1) != 1) { Tcl_Panic("Tcl_AlertNotifier: unable to write to %p->triggerPipe", (void *)tsdPtr); -#endif /* NOTIFIER_EPOLL */ +#endif /* NOTIFIER_EPOLL && HAVE_EVENTFD */ } #endif /* NOTIFIER_SELECT */ } -- cgit v0.12 From f090fee89b41ac4813b896edbdb20a31bdd9c703 Mon Sep 17 00:00:00 2001 From: dgp Date: Fri, 10 Mar 2017 15:22:08 +0000 Subject: Start RC branch for Tcl 8.6.7 --- README | 2 +- generic/tcl.h | 4 ++-- library/init.tcl | 2 +- unix/configure | 2 +- unix/configure.in | 2 +- unix/tcl.spec | 2 +- win/configure | 2 +- win/configure.in | 2 +- 8 files changed, 9 insertions(+), 9 deletions(-) diff --git a/README b/README index 401b6e6..57985d3 100644 --- a/README +++ b/README @@ -1,5 +1,5 @@ README: Tcl - This is the Tcl 8.6.6 source distribution. + This is the Tcl 8.6.7 source distribution. http://sourceforge.net/projects/tcl/files/Tcl/ You can get any source release of Tcl from the URL above. diff --git a/generic/tcl.h b/generic/tcl.h index 64c7d14..3790b58 100644 --- a/generic/tcl.h +++ b/generic/tcl.h @@ -55,10 +55,10 @@ extern "C" { #define TCL_MAJOR_VERSION 8 #define TCL_MINOR_VERSION 6 #define TCL_RELEASE_LEVEL TCL_FINAL_RELEASE -#define TCL_RELEASE_SERIAL 6 +#define TCL_RELEASE_SERIAL 7 #define TCL_VERSION "8.6" -#define TCL_PATCH_LEVEL "8.6.6" +#define TCL_PATCH_LEVEL "8.6.7" /* *---------------------------------------------------------------------------- diff --git a/library/init.tcl b/library/init.tcl index 9ca4514..0437412 100644 --- a/library/init.tcl +++ b/library/init.tcl @@ -16,7 +16,7 @@ if {[info commands package] == ""} { error "version mismatch: library\nscripts expect Tcl version 7.5b1 or later but the loaded version is\nonly [info patchlevel]" } -package require -exact Tcl 8.6.6 +package require -exact Tcl 8.6.7 # Compute the auto path to use in this interpreter. # The values on the path come from several locations: diff --git a/unix/configure b/unix/configure index 38c3f9a..a333fc1 100755 --- a/unix/configure +++ b/unix/configure @@ -1335,7 +1335,7 @@ ac_compiler_gnu=$ac_cv_c_compiler_gnu TCL_VERSION=8.6 TCL_MAJOR_VERSION=8 TCL_MINOR_VERSION=6 -TCL_PATCH_LEVEL=".6" +TCL_PATCH_LEVEL=".7" VERSION=${TCL_VERSION} EXTRA_INSTALL_BINARIES=${EXTRA_INSTALL_BINARIES:-"@:"} diff --git a/unix/configure.in b/unix/configure.in index 1d86213..220a4aa 100644 --- a/unix/configure.in +++ b/unix/configure.in @@ -25,7 +25,7 @@ m4_ifdef([SC_USE_CONFIG_HEADERS], [ TCL_VERSION=8.6 TCL_MAJOR_VERSION=8 TCL_MINOR_VERSION=6 -TCL_PATCH_LEVEL=".6" +TCL_PATCH_LEVEL=".7" VERSION=${TCL_VERSION} EXTRA_INSTALL_BINARIES=${EXTRA_INSTALL_BINARIES:-"@:"} diff --git a/unix/tcl.spec b/unix/tcl.spec index 8bf77f3..141511d 100644 --- a/unix/tcl.spec +++ b/unix/tcl.spec @@ -4,7 +4,7 @@ Name: tcl Summary: Tcl scripting language development environment -Version: 8.6.6 +Version: 8.6.7 Release: 2 License: BSD Group: Development/Languages diff --git a/win/configure b/win/configure index e8e4b87..835afb8 100755 --- a/win/configure +++ b/win/configure @@ -1311,7 +1311,7 @@ SHELL=/bin/sh TCL_VERSION=8.6 TCL_MAJOR_VERSION=8 TCL_MINOR_VERSION=6 -TCL_PATCH_LEVEL=".6" +TCL_PATCH_LEVEL=".7" VER=$TCL_MAJOR_VERSION$TCL_MINOR_VERSION TCL_DDE_VERSION=1.4 diff --git a/win/configure.in b/win/configure.in index 8bb9c48..8d712eb 100644 --- a/win/configure.in +++ b/win/configure.in @@ -14,7 +14,7 @@ SHELL=/bin/sh TCL_VERSION=8.6 TCL_MAJOR_VERSION=8 TCL_MINOR_VERSION=6 -TCL_PATCH_LEVEL=".6" +TCL_PATCH_LEVEL=".7" VER=$TCL_MAJOR_VERSION$TCL_MINOR_VERSION TCL_DDE_VERSION=1.4 -- cgit v0.12 From e9e0f57d92722f8c472764114b517ff3556731a0 Mon Sep 17 00:00:00 2001 From: dgp Date: Fri, 10 Mar 2017 15:28:46 +0000 Subject: Dup test name --- tests/link.test | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/link.test b/tests/link.test index dda7d6b..6bff356 100644 --- a/tests/link.test +++ b/tests/link.test @@ -152,7 +152,7 @@ test link-2.8 {writing C variables from Tcl} -constraints {testlink} -setup { set uwide "0O" concat [testlink get] | $int $real $bool $string $wide $char $uchar $short $ushort $uint $long $ulong $float $uwide } -result {0 0.0 0 0 0 0 0 0 0 0 0 0 0.0 0 | 0x 0b 0 0 0O 0X 0B 0O 0x 0b 0o 0X 0B 0O} -test link-2.8 {writing C variables from Tcl} -constraints {testlink} -setup { +test link-2.9 {writing C variables from Tcl} -constraints {testlink} -setup { testlink delete } -body { testlink set 43 1.21 4 - 56785678 64 250 30000 60000 0xbaadbeef 12321 32123 3.25 1231231234 -- cgit v0.12 From 91d32c45568c29a04d91d4ea742c10c290a05e8b Mon Sep 17 00:00:00 2001 From: dgp Date: Fri, 10 Mar 2017 16:41:32 +0000 Subject: Silence valgrind complaints from [representation]. --- generic/tclInt.h | 2 ++ generic/tclObj.c | 1 + 2 files changed, 3 insertions(+) diff --git a/generic/tclInt.h b/generic/tclInt.h index 4d3c0b1..65ef1c6 100644 --- a/generic/tclInt.h +++ b/generic/tclInt.h @@ -4521,6 +4521,7 @@ MODULE_SCOPE Tcl_PackageInitProc Procbodytest_SafeInit; do { \ TclInvalidateStringRep(objPtr); \ TclFreeIntRep(objPtr); \ + (objPtr)->internalRep.twoPtrValue.ptr2 = NULL; \ (objPtr)->internalRep.doubleValue = (double)(d); \ (objPtr)->typePtr = &tclDoubleType; \ } while (0) @@ -4570,6 +4571,7 @@ MODULE_SCOPE Tcl_PackageInitProc Procbodytest_SafeInit; TclAllocObjStorage(objPtr); \ (objPtr)->refCount = 0; \ (objPtr)->bytes = NULL; \ + (objPtr)->internalRep.twoPtrValue.ptr2 = NULL; \ (objPtr)->internalRep.doubleValue = (double)(d); \ (objPtr)->typePtr = &tclDoubleType; \ TCL_DTRACE_OBJ_CREATE(objPtr); \ diff --git a/generic/tclObj.c b/generic/tclObj.c index a346987..d549fdc 100644 --- a/generic/tclObj.c +++ b/generic/tclObj.c @@ -2203,6 +2203,7 @@ Tcl_DbNewDoubleObj( TclDbNewObj(objPtr, file, line); objPtr->bytes = NULL; + objPtr->internalRep.twoPtrValue.ptr2 = NULL; /* valgrind */ objPtr->internalRep.doubleValue = dblValue; objPtr->typePtr = &tclDoubleType; return objPtr; -- cgit v0.12 From d4b614d6551e55fd6e1bb52a335e37657603f91c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Ignacio=20Mar=C3=ADn?= Date: Fri, 10 Mar 2017 16:59:02 +0000 Subject: Update TZ data with tzdata2017a from IANA --- library/tzdata/Africa/Accra | 94 ++-- library/tzdata/Africa/Bissau | 2 +- library/tzdata/Africa/Ceuta | 12 +- library/tzdata/Africa/El_Aaiun | 2 +- library/tzdata/Africa/Monrovia | 2 +- library/tzdata/Africa/Nairobi | 4 +- library/tzdata/Africa/Windhoek | 2 +- library/tzdata/America/Anchorage | 11 +- library/tzdata/America/Araguaina | 110 ++--- library/tzdata/America/Argentina/Buenos_Aires | 122 ++--- library/tzdata/America/Argentina/Catamarca | 124 ++--- library/tzdata/America/Argentina/Cordoba | 122 ++--- library/tzdata/America/Argentina/Jujuy | 122 ++--- library/tzdata/America/Argentina/La_Rioja | 126 ++--- library/tzdata/America/Argentina/Mendoza | 124 ++--- library/tzdata/America/Argentina/Rio_Gallegos | 124 ++--- library/tzdata/America/Argentina/Salta | 120 ++--- library/tzdata/America/Argentina/San_Juan | 126 ++--- library/tzdata/America/Argentina/San_Luis | 124 ++--- library/tzdata/America/Argentina/Tucuman | 126 ++--- library/tzdata/America/Argentina/Ushuaia | 124 ++--- library/tzdata/America/Asuncion | 506 +++++++++---------- library/tzdata/America/Bahia | 126 ++--- library/tzdata/America/Belem | 60 +-- library/tzdata/America/Belize | 50 +- library/tzdata/America/Boa_Vista | 70 +-- library/tzdata/America/Bogota | 6 +- library/tzdata/America/Campo_Grande | 504 +++++++++---------- library/tzdata/America/Caracas | 8 +- library/tzdata/America/Cayenne | 4 +- library/tzdata/America/Cuiaba | 504 +++++++++---------- library/tzdata/America/Curacao | 2 +- library/tzdata/America/Danmarkshavn | 66 +-- library/tzdata/America/Eirunepe | 72 +-- library/tzdata/America/Fortaleza | 86 ++-- library/tzdata/America/Godthab | 482 +++++++++--------- library/tzdata/America/Guayaquil | 4 +- library/tzdata/America/Guyana | 7 +- library/tzdata/America/La_Paz | 2 +- library/tzdata/America/Lima | 20 +- library/tzdata/America/Maceio | 94 ++-- library/tzdata/America/Manaus | 68 +-- library/tzdata/America/Miquelon | 456 ++++++++--------- library/tzdata/America/Montevideo | 176 +++---- library/tzdata/America/Noronha | 86 ++-- library/tzdata/America/Paramaribo | 5 +- library/tzdata/America/Porto_Velho | 60 +-- library/tzdata/America/Punta_Arenas | 122 +++++ library/tzdata/America/Recife | 86 ++-- library/tzdata/America/Rio_Branco | 64 +-- library/tzdata/America/Santarem | 62 +-- library/tzdata/America/Santiago | 562 ++++++++++----------- library/tzdata/America/Santo_Domingo | 10 +- library/tzdata/America/Sao_Paulo | 506 +++++++++---------- library/tzdata/America/Scoresbysund | 482 +++++++++--------- library/tzdata/Antarctica/Macquarie | 2 +- library/tzdata/Antarctica/Palmer | 329 ++++--------- library/tzdata/Asia/Atyrau | 4 +- library/tzdata/Asia/Baghdad | 106 ++-- library/tzdata/Asia/Bangkok | 2 +- library/tzdata/Asia/Brunei | 4 +- library/tzdata/Asia/Choibalsan | 268 ++-------- library/tzdata/Asia/Dhaka | 15 +- library/tzdata/Asia/Dili | 9 +- library/tzdata/Asia/Dubai | 2 +- library/tzdata/Asia/Ho_Chi_Minh | 16 +- library/tzdata/Asia/Hovd | 266 ++-------- library/tzdata/Asia/Jakarta | 12 +- library/tzdata/Asia/Jayapura | 4 +- library/tzdata/Asia/Kabul | 4 +- library/tzdata/Asia/Karachi | 8 +- library/tzdata/Asia/Kathmandu | 4 +- library/tzdata/Asia/Kolkata | 4 +- library/tzdata/Asia/Kuala_Lumpur | 14 +- library/tzdata/Asia/Kuching | 37 +- library/tzdata/Asia/Macau | 82 ++-- library/tzdata/Asia/Makassar | 4 +- library/tzdata/Asia/Manila | 18 +- library/tzdata/Asia/Oral | 4 +- library/tzdata/Asia/Pontianak | 10 +- library/tzdata/Asia/Pyongyang | 3 +- library/tzdata/Asia/Qatar | 4 +- library/tzdata/Asia/Riyadh | 2 +- library/tzdata/Asia/Seoul | 3 +- library/tzdata/Asia/Singapore | 15 +- library/tzdata/Asia/Taipei | 2 +- library/tzdata/Asia/Tehran | 446 ++++++++--------- library/tzdata/Asia/Thimphu | 4 +- library/tzdata/Asia/Tokyo | 2 - library/tzdata/Asia/Ulaanbaatar | 266 ++-------- library/tzdata/Asia/Urumqi | 2 +- library/tzdata/Asia/Yangon | 6 +- library/tzdata/Atlantic/Azores | 682 +++++++++++++------------- library/tzdata/Atlantic/Canary | 2 +- library/tzdata/Atlantic/Cape_Verde | 8 +- library/tzdata/Atlantic/Madeira | 190 ++++--- library/tzdata/Atlantic/Reykjavik | 134 ++--- library/tzdata/Atlantic/South_Georgia | 2 +- library/tzdata/Atlantic/Stanley | 138 +++--- library/tzdata/Australia/Eucla | 40 +- library/tzdata/Australia/Lord_Howe | 477 +++++++++--------- library/tzdata/Europe/Amsterdam | 12 +- library/tzdata/Europe/Madrid | 64 ++- library/tzdata/Europe/Zaporozhye | 2 +- library/tzdata/Indian/Chagos | 4 +- library/tzdata/Indian/Christmas | 2 +- library/tzdata/Indian/Cocos | 2 +- library/tzdata/Indian/Mahe | 2 +- library/tzdata/Indian/Maldives | 2 +- library/tzdata/Indian/Mauritius | 10 +- library/tzdata/Indian/Reunion | 2 +- library/tzdata/Pacific/Apia | 364 +++++++------- library/tzdata/Pacific/Bougainville | 8 +- library/tzdata/Pacific/Chatham | 506 +++++++++---------- library/tzdata/Pacific/Chuuk | 2 +- library/tzdata/Pacific/Easter | 524 ++++++++++---------- library/tzdata/Pacific/Efate | 42 +- library/tzdata/Pacific/Enderbury | 6 +- library/tzdata/Pacific/Fakaofo | 4 +- library/tzdata/Pacific/Fiji | 372 +++++++------- library/tzdata/Pacific/Funafuti | 2 +- library/tzdata/Pacific/Galapagos | 6 +- library/tzdata/Pacific/Gambier | 2 +- library/tzdata/Pacific/Guadalcanal | 2 +- library/tzdata/Pacific/Kiritimati | 6 +- library/tzdata/Pacific/Kosrae | 6 +- library/tzdata/Pacific/Kwajalein | 6 +- library/tzdata/Pacific/Majuro | 4 +- library/tzdata/Pacific/Marquesas | 2 +- library/tzdata/Pacific/Nauru | 8 +- library/tzdata/Pacific/Niue | 6 +- library/tzdata/Pacific/Norfolk | 10 +- library/tzdata/Pacific/Noumea | 14 +- library/tzdata/Pacific/Pago_Pago | 4 +- library/tzdata/Pacific/Palau | 2 +- library/tzdata/Pacific/Pitcairn | 4 +- library/tzdata/Pacific/Pohnpei | 2 +- library/tzdata/Pacific/Port_Moresby | 2 +- library/tzdata/Pacific/Rarotonga | 54 +- library/tzdata/Pacific/Tahiti | 2 +- library/tzdata/Pacific/Tarawa | 2 +- library/tzdata/Pacific/Wake | 2 +- library/tzdata/Pacific/Wallis | 2 +- 143 files changed, 6161 insertions(+), 6716 deletions(-) create mode 100644 library/tzdata/America/Punta_Arenas diff --git a/library/tzdata/Africa/Accra b/library/tzdata/Africa/Accra index 39db976..18f4522 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 GMT} - {-1556841600 1200 1 GHST} - {-1546388400 0 0 GMT} - {-1525305600 1200 1 GHST} - {-1514852400 0 0 GMT} - {-1493769600 1200 1 GHST} - {-1483316400 0 0 GMT} - {-1462233600 1200 1 GHST} - {-1451780400 0 0 GMT} - {-1430611200 1200 1 GHST} - {-1420158000 0 0 GMT} - {-1399075200 1200 1 GHST} - {-1388622000 0 0 GMT} - {-1367539200 1200 1 GHST} - {-1357086000 0 0 GMT} - {-1336003200 1200 1 GHST} - {-1325550000 0 0 GMT} - {-1304380800 1200 1 GHST} - {-1293927600 0 0 GMT} - {-1272844800 1200 1 GHST} - {-1262391600 0 0 GMT} - {-1241308800 1200 1 GHST} - {-1230855600 0 0 GMT} - {-1209772800 1200 1 GHST} - {-1199319600 0 0 GMT} - {-1178150400 1200 1 GHST} - {-1167697200 0 0 GMT} - {-1146614400 1200 1 GHST} - {-1136161200 0 0 GMT} - {-1115078400 1200 1 GHST} - {-1104625200 0 0 GMT} - {-1083542400 1200 1 GHST} - {-1073089200 0 0 GMT} - {-1051920000 1200 1 GHST} - {-1041466800 0 0 GMT} - {-1020384000 1200 1 GHST} - {-1009930800 0 0 GMT} - {-988848000 1200 1 GHST} - {-978394800 0 0 GMT} - {-957312000 1200 1 GHST} - {-946858800 0 0 GMT} - {-925689600 1200 1 GHST} - {-915236400 0 0 GMT} - {-894153600 1200 1 GHST} - {-883700400 0 0 GMT} - {-862617600 1200 1 GHST} - {-852164400 0 0 GMT} + {-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} } diff --git a/library/tzdata/Africa/Bissau b/library/tzdata/Africa/Bissau index 5693228..88d9d03 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 WAT} + {-1830380260 -3600 0 -01} {157770000 0 0 GMT} } diff --git a/library/tzdata/Africa/Ceuta b/library/tzdata/Africa/Ceuta index 882c13d..057ca22 100644 --- a/library/tzdata/Africa/Ceuta +++ b/library/tzdata/Africa/Ceuta @@ -2,18 +2,18 @@ set TZData(:Africa/Ceuta) { {-9223372036854775808 -1276 0 LMT} - {-2177451524 0 0 WET} + {-2177452800 0 0 WET} {-1630112400 3600 1 WEST} {-1616810400 0 0 WET} {-1451692800 0 0 WET} {-1442451600 3600 1 WEST} - {-1427677200 0 0 WET} + {-1427673600 0 0 WET} {-1379293200 3600 1 WEST} - {-1364778000 0 0 WET} + {-1364774400 0 0 WET} {-1348448400 3600 1 WEST} - {-1333328400 0 0 WET} - {-1316394000 3600 1 WEST} - {-1301274000 0 0 WET} + {-1333324800 0 0 WET} + {-1316390400 3600 1 WEST} + {-1301270400 0 0 WET} {-1293840000 0 0 WET} {-81432000 3600 1 WEST} {-71110800 0 0 WET} diff --git a/library/tzdata/Africa/El_Aaiun b/library/tzdata/Africa/El_Aaiun index 77e149e..7bdc496 100644 --- a/library/tzdata/Africa/El_Aaiun +++ b/library/tzdata/Africa/El_Aaiun @@ -2,7 +2,7 @@ set TZData(:Africa/El_Aaiun) { {-9223372036854775808 -3168 0 LMT} - {-1136070432 -3600 0 WAT} + {-1136070432 -3600 0 -01} {198291600 0 0 WET} {199756800 3600 1 WEST} {207702000 0 0 WET} diff --git a/library/tzdata/Africa/Monrovia b/library/tzdata/Africa/Monrovia index 1cfff58..eb069f6 100644 --- a/library/tzdata/Africa/Monrovia +++ b/library/tzdata/Africa/Monrovia @@ -3,6 +3,6 @@ set TZData(:Africa/Monrovia) { {-9223372036854775808 -2588 0 LMT} {-2776979812 -2588 0 MMT} - {-1604359012 -2670 0 LRT} + {-1604359012 -2670 0 -004430} {73529070 0 0 GMT} } diff --git a/library/tzdata/Africa/Nairobi b/library/tzdata/Africa/Nairobi index 6846069..715dc45 100644 --- a/library/tzdata/Africa/Nairobi +++ b/library/tzdata/Africa/Nairobi @@ -3,7 +3,7 @@ set TZData(:Africa/Nairobi) { {-9223372036854775808 8836 0 LMT} {-1309746436 10800 0 EAT} - {-1262314800 9000 0 BEAT} - {-946780200 9900 0 BEAUT} + {-1262314800 9000 0 +0230} + {-946780200 9900 0 +0245} {-315629100 10800 0 EAT} } diff --git a/library/tzdata/Africa/Windhoek b/library/tzdata/Africa/Windhoek index a655f2e..1b8f86a 100644 --- a/library/tzdata/Africa/Windhoek +++ b/library/tzdata/Africa/Windhoek @@ -2,7 +2,7 @@ set TZData(:Africa/Windhoek) { {-9223372036854775808 4104 0 LMT} - {-2458170504 5400 0 SWAT} + {-2458170504 5400 0 +0130} {-2109288600 7200 0 SAST} {-860976000 10800 1 SAST} {-845254800 7200 0 SAST} diff --git a/library/tzdata/America/Anchorage b/library/tzdata/America/Anchorage index e02dd01..127d365 100644 --- a/library/tzdata/America/Anchorage +++ b/library/tzdata/America/Anchorage @@ -3,12 +3,11 @@ set TZData(:America/Anchorage) { {-9223372036854775808 50424 0 LMT} {-3225362424 -35976 0 LMT} - {-2188951224 -36000 0 CAT} - {-883576800 -36000 0 CAWT} - {-880200000 -32400 1 CAWT} - {-769395600 -32400 0 CAPT} - {-765378000 -36000 0 CAPT} - {-757346400 -36000 0 CAT} + {-2188951224 -36000 0 AST} + {-883576800 -36000 0 AST} + {-880200000 -32400 1 AWT} + {-769395600 -32400 1 APT} + {-765378000 -36000 0 AST} {-86882400 -36000 0 AHST} {-31500000 -36000 0 AHST} {-21470400 -32400 1 AHDT} diff --git a/library/tzdata/America/Araguaina b/library/tzdata/America/Araguaina index e4a0d52..b9e2aec 100644 --- a/library/tzdata/America/Araguaina +++ b/library/tzdata/America/Araguaina @@ -2,59 +2,59 @@ set TZData(:America/Araguaina) { {-9223372036854775808 -11568 0 LMT} - {-1767214032 -10800 0 BRT} - {-1206957600 -7200 1 BRST} - {-1191362400 -10800 0 BRT} - {-1175374800 -7200 1 BRST} - {-1159826400 -10800 0 BRT} - {-633819600 -7200 1 BRST} - {-622069200 -10800 0 BRT} - {-602283600 -7200 1 BRST} - {-591832800 -10800 0 BRT} - {-570747600 -7200 1 BRST} - {-560210400 -10800 0 BRT} - {-539125200 -7200 1 BRST} - {-531352800 -10800 0 BRT} - {-191365200 -7200 1 BRST} - {-184197600 -10800 0 BRT} - {-155163600 -7200 1 BRST} - {-150069600 -10800 0 BRT} - {-128898000 -7200 1 BRST} - {-121125600 -10800 0 BRT} - {-99954000 -7200 1 BRST} - {-89589600 -10800 0 BRT} - {-68418000 -7200 1 BRST} - {-57967200 -10800 0 BRT} - {499748400 -7200 1 BRST} - {511236000 -10800 0 BRT} - {530593200 -7200 1 BRST} - {540266400 -10800 0 BRT} - {562129200 -7200 1 BRST} - {571197600 -10800 0 BRT} - {592974000 -7200 1 BRST} - {602042400 -10800 0 BRT} - {624423600 -7200 1 BRST} - {634701600 -10800 0 BRT} - {653536800 -10800 0 BRT} - {811047600 -10800 0 BRT} - {813726000 -7200 1 BRST} - {824004000 -10800 0 BRT} - {844570800 -7200 1 BRST} - {856058400 -10800 0 BRT} - {876106800 -7200 1 BRST} - {888717600 -10800 0 BRT} - {908074800 -7200 1 BRST} - {919562400 -10800 0 BRT} - {938919600 -7200 1 BRST} - {951616800 -10800 0 BRT} - {970974000 -7200 1 BRST} - {982461600 -10800 0 BRT} - {1003028400 -7200 1 BRST} - {1013911200 -10800 0 BRT} - {1036292400 -7200 1 BRST} - {1045360800 -10800 0 BRT} - {1064368800 -10800 0 BRT} - {1350788400 -7200 0 BRST} - {1361066400 -10800 0 BRT} - {1378000800 -10800 0 BRT} + {-1767214032 -10800 0 -03} + {-1206957600 -7200 1 -02} + {-1191362400 -10800 0 -03} + {-1175374800 -7200 1 -02} + {-1159826400 -10800 0 -03} + {-633819600 -7200 1 -02} + {-622069200 -10800 0 -03} + {-602283600 -7200 1 -02} + {-591832800 -10800 0 -03} + {-570747600 -7200 1 -02} + {-560210400 -10800 0 -03} + {-539125200 -7200 1 -02} + {-531352800 -10800 0 -03} + {-191365200 -7200 1 -02} + {-184197600 -10800 0 -03} + {-155163600 -7200 1 -02} + {-150069600 -10800 0 -03} + {-128898000 -7200 1 -02} + {-121125600 -10800 0 -03} + {-99954000 -7200 1 -02} + {-89589600 -10800 0 -03} + {-68418000 -7200 1 -02} + {-57967200 -10800 0 -03} + {499748400 -7200 1 -02} + {511236000 -10800 0 -03} + {530593200 -7200 1 -02} + {540266400 -10800 0 -03} + {562129200 -7200 1 -02} + {571197600 -10800 0 -03} + {592974000 -7200 1 -02} + {602042400 -10800 0 -03} + {624423600 -7200 1 -02} + {634701600 -10800 0 -03} + {653536800 -10800 0 -03} + {811047600 -10800 0 -03} + {813726000 -7200 1 -02} + {824004000 -10800 0 -03} + {844570800 -7200 1 -02} + {856058400 -10800 0 -03} + {876106800 -7200 1 -02} + {888717600 -10800 0 -03} + {908074800 -7200 1 -02} + {919562400 -10800 0 -03} + {938919600 -7200 1 -02} + {951616800 -10800 0 -03} + {970974000 -7200 1 -02} + {982461600 -10800 0 -03} + {1003028400 -7200 1 -02} + {1013911200 -10800 0 -03} + {1036292400 -7200 1 -02} + {1045360800 -10800 0 -03} + {1064368800 -10800 0 -03} + {1350788400 -7200 0 -02} + {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 73cc8e9..8be2c45 100644 --- a/library/tzdata/America/Argentina/Buenos_Aires +++ b/library/tzdata/America/Argentina/Buenos_Aires @@ -3,65 +3,65 @@ set TZData(:America/Argentina/Buenos_Aires) { {-9223372036854775808 -14028 0 LMT} {-2372097972 -15408 0 CMT} - {-1567453392 -14400 0 ART} - {-1233432000 -10800 0 ARST} - {-1222981200 -14400 0 ART} - {-1205956800 -10800 1 ARST} - {-1194037200 -14400 0 ART} - {-1172865600 -10800 1 ARST} - {-1162501200 -14400 0 ART} - {-1141329600 -10800 1 ARST} - {-1130965200 -14400 0 ART} - {-1109793600 -10800 1 ARST} - {-1099429200 -14400 0 ART} - {-1078257600 -10800 1 ARST} - {-1067806800 -14400 0 ART} - {-1046635200 -10800 1 ARST} - {-1036270800 -14400 0 ART} - {-1015099200 -10800 1 ARST} - {-1004734800 -14400 0 ART} - {-983563200 -10800 1 ARST} - {-973198800 -14400 0 ART} - {-952027200 -10800 1 ARST} - {-941576400 -14400 0 ART} - {-931032000 -10800 1 ARST} - {-900882000 -14400 0 ART} - {-890337600 -10800 1 ARST} - {-833749200 -14400 0 ART} - {-827265600 -10800 1 ARST} - {-752274000 -14400 0 ART} - {-733780800 -10800 1 ARST} - {-197326800 -14400 0 ART} - {-190843200 -10800 1 ARST} - {-184194000 -14400 0 ART} - {-164491200 -10800 1 ARST} - {-152658000 -14400 0 ART} - {-132955200 -10800 1 ARST} - {-121122000 -14400 0 ART} - {-101419200 -10800 1 ARST} - {-86821200 -14400 0 ART} - {-71092800 -10800 1 ARST} - {-54766800 -14400 0 ART} - {-39038400 -10800 1 ARST} - {-23317200 -14400 0 ART} - {-7588800 -10800 0 ART} - {128142000 -7200 1 ARST} - {136605600 -10800 0 ART} - {596948400 -7200 1 ARST} - {605066400 -10800 0 ART} - {624423600 -7200 1 ARST} - {636516000 -10800 0 ART} - {656478000 -7200 1 ARST} - {667965600 -10800 0 ART} - {687927600 -7200 1 ARST} - {699415200 -10800 0 ART} - {719377200 -7200 1 ARST} - {731469600 -10800 0 ART} - {938916000 -10800 0 ART} - {938919600 -10800 1 ARST} - {952056000 -10800 0 ART} - {1198983600 -7200 1 ARST} - {1205632800 -10800 0 ART} - {1224385200 -7200 1 ARST} - {1237082400 -10800 0 ART} + {-1567453392 -14400 0 -04} + {-1233432000 -10800 0 -03} + {-1222981200 -14400 0 -04} + {-1205956800 -10800 1 -03} + {-1194037200 -14400 0 -04} + {-1172865600 -10800 1 -03} + {-1162501200 -14400 0 -04} + {-1141329600 -10800 1 -03} + {-1130965200 -14400 0 -04} + {-1109793600 -10800 1 -03} + {-1099429200 -14400 0 -04} + {-1078257600 -10800 1 -03} + {-1067806800 -14400 0 -04} + {-1046635200 -10800 1 -03} + {-1036270800 -14400 0 -04} + {-1015099200 -10800 1 -03} + {-1004734800 -14400 0 -04} + {-983563200 -10800 1 -03} + {-973198800 -14400 0 -04} + {-952027200 -10800 1 -03} + {-941576400 -14400 0 -04} + {-931032000 -10800 1 -03} + {-900882000 -14400 0 -04} + {-890337600 -10800 1 -03} + {-833749200 -14400 0 -04} + {-827265600 -10800 1 -03} + {-752274000 -14400 0 -04} + {-733780800 -10800 1 -03} + {-197326800 -14400 0 -04} + {-190843200 -10800 1 -03} + {-184194000 -14400 0 -04} + {-164491200 -10800 1 -03} + {-152658000 -14400 0 -04} + {-132955200 -10800 1 -03} + {-121122000 -14400 0 -04} + {-101419200 -10800 1 -03} + {-86821200 -14400 0 -04} + {-71092800 -10800 1 -03} + {-54766800 -14400 0 -04} + {-39038400 -10800 1 -03} + {-23317200 -14400 0 -04} + {-7588800 -10800 0 -03} + {128142000 -7200 1 -02} + {136605600 -10800 0 -03} + {596948400 -7200 1 -02} + {605066400 -10800 0 -03} + {624423600 -7200 1 -02} + {636516000 -10800 0 -03} + {656478000 -7200 1 -02} + {667965600 -10800 0 -03} + {687927600 -7200 1 -02} + {699415200 -10800 0 -03} + {719377200 -7200 1 -02} + {731469600 -10800 0 -03} + {938916000 -10800 0 -04} + {938919600 -10800 1 -03} + {952056000 -10800 0 -03} + {1198983600 -7200 1 -02} + {1205632800 -10800 0 -03} + {1224385200 -7200 1 -02} + {1237082400 -10800 0 -03} } diff --git a/library/tzdata/America/Argentina/Catamarca b/library/tzdata/America/Argentina/Catamarca index 7739203..a546bfc 100644 --- a/library/tzdata/America/Argentina/Catamarca +++ b/library/tzdata/America/Argentina/Catamarca @@ -3,66 +3,66 @@ set TZData(:America/Argentina/Catamarca) { {-9223372036854775808 -15788 0 LMT} {-2372096212 -15408 0 CMT} - {-1567453392 -14400 0 ART} - {-1233432000 -10800 0 ARST} - {-1222981200 -14400 0 ART} - {-1205956800 -10800 1 ARST} - {-1194037200 -14400 0 ART} - {-1172865600 -10800 1 ARST} - {-1162501200 -14400 0 ART} - {-1141329600 -10800 1 ARST} - {-1130965200 -14400 0 ART} - {-1109793600 -10800 1 ARST} - {-1099429200 -14400 0 ART} - {-1078257600 -10800 1 ARST} - {-1067806800 -14400 0 ART} - {-1046635200 -10800 1 ARST} - {-1036270800 -14400 0 ART} - {-1015099200 -10800 1 ARST} - {-1004734800 -14400 0 ART} - {-983563200 -10800 1 ARST} - {-973198800 -14400 0 ART} - {-952027200 -10800 1 ARST} - {-941576400 -14400 0 ART} - {-931032000 -10800 1 ARST} - {-900882000 -14400 0 ART} - {-890337600 -10800 1 ARST} - {-833749200 -14400 0 ART} - {-827265600 -10800 1 ARST} - {-752274000 -14400 0 ART} - {-733780800 -10800 1 ARST} - {-197326800 -14400 0 ART} - {-190843200 -10800 1 ARST} - {-184194000 -14400 0 ART} - {-164491200 -10800 1 ARST} - {-152658000 -14400 0 ART} - {-132955200 -10800 1 ARST} - {-121122000 -14400 0 ART} - {-101419200 -10800 1 ARST} - {-86821200 -14400 0 ART} - {-71092800 -10800 1 ARST} - {-54766800 -14400 0 ART} - {-39038400 -10800 1 ARST} - {-23317200 -14400 0 ART} - {-7588800 -10800 0 ART} - {128142000 -7200 1 ARST} - {136605600 -10800 0 ART} - {596948400 -7200 1 ARST} - {605066400 -10800 0 ART} - {624423600 -7200 1 ARST} - {636516000 -10800 0 ART} - {656478000 -7200 1 ARST} - {667965600 -14400 0 WART} - {687931200 -7200 0 ARST} - {699415200 -10800 0 ART} - {719377200 -7200 1 ARST} - {731469600 -10800 0 ART} - {938916000 -10800 0 ART} - {938919600 -10800 1 ARST} - {952056000 -10800 0 ART} - {1086058800 -14400 0 WART} - {1087704000 -10800 0 ART} - {1198983600 -7200 1 ARST} - {1205632800 -10800 0 ART} - {1224295200 -10800 0 ART} + {-1567453392 -14400 0 -04} + {-1233432000 -10800 0 -03} + {-1222981200 -14400 0 -04} + {-1205956800 -10800 1 -03} + {-1194037200 -14400 0 -04} + {-1172865600 -10800 1 -03} + {-1162501200 -14400 0 -04} + {-1141329600 -10800 1 -03} + {-1130965200 -14400 0 -04} + {-1109793600 -10800 1 -03} + {-1099429200 -14400 0 -04} + {-1078257600 -10800 1 -03} + {-1067806800 -14400 0 -04} + {-1046635200 -10800 1 -03} + {-1036270800 -14400 0 -04} + {-1015099200 -10800 1 -03} + {-1004734800 -14400 0 -04} + {-983563200 -10800 1 -03} + {-973198800 -14400 0 -04} + {-952027200 -10800 1 -03} + {-941576400 -14400 0 -04} + {-931032000 -10800 1 -03} + {-900882000 -14400 0 -04} + {-890337600 -10800 1 -03} + {-833749200 -14400 0 -04} + {-827265600 -10800 1 -03} + {-752274000 -14400 0 -04} + {-733780800 -10800 1 -03} + {-197326800 -14400 0 -04} + {-190843200 -10800 1 -03} + {-184194000 -14400 0 -04} + {-164491200 -10800 1 -03} + {-152658000 -14400 0 -04} + {-132955200 -10800 1 -03} + {-121122000 -14400 0 -04} + {-101419200 -10800 1 -03} + {-86821200 -14400 0 -04} + {-71092800 -10800 1 -03} + {-54766800 -14400 0 -04} + {-39038400 -10800 1 -03} + {-23317200 -14400 0 -04} + {-7588800 -10800 0 -03} + {128142000 -7200 1 -02} + {136605600 -10800 0 -03} + {596948400 -7200 1 -02} + {605066400 -10800 0 -03} + {624423600 -7200 1 -02} + {636516000 -10800 0 -03} + {656478000 -7200 1 -02} + {667965600 -14400 0 -04} + {687931200 -7200 0 -02} + {699415200 -10800 0 -03} + {719377200 -7200 1 -02} + {731469600 -10800 0 -03} + {938916000 -10800 0 -04} + {938919600 -10800 1 -03} + {952056000 -10800 0 -03} + {1086058800 -14400 0 -04} + {1087704000 -10800 0 -03} + {1198983600 -7200 1 -02} + {1205632800 -10800 0 -03} + {1224295200 -10800 0 -03} } diff --git a/library/tzdata/America/Argentina/Cordoba b/library/tzdata/America/Argentina/Cordoba index b08539e..ec6978e 100644 --- a/library/tzdata/America/Argentina/Cordoba +++ b/library/tzdata/America/Argentina/Cordoba @@ -3,65 +3,65 @@ set TZData(:America/Argentina/Cordoba) { {-9223372036854775808 -15408 0 LMT} {-2372096592 -15408 0 CMT} - {-1567453392 -14400 0 ART} - {-1233432000 -10800 0 ARST} - {-1222981200 -14400 0 ART} - {-1205956800 -10800 1 ARST} - {-1194037200 -14400 0 ART} - {-1172865600 -10800 1 ARST} - {-1162501200 -14400 0 ART} - {-1141329600 -10800 1 ARST} - {-1130965200 -14400 0 ART} - {-1109793600 -10800 1 ARST} - {-1099429200 -14400 0 ART} - {-1078257600 -10800 1 ARST} - {-1067806800 -14400 0 ART} - {-1046635200 -10800 1 ARST} - {-1036270800 -14400 0 ART} - {-1015099200 -10800 1 ARST} - {-1004734800 -14400 0 ART} - {-983563200 -10800 1 ARST} - {-973198800 -14400 0 ART} - {-952027200 -10800 1 ARST} - {-941576400 -14400 0 ART} - {-931032000 -10800 1 ARST} - {-900882000 -14400 0 ART} - {-890337600 -10800 1 ARST} - {-833749200 -14400 0 ART} - {-827265600 -10800 1 ARST} - {-752274000 -14400 0 ART} - {-733780800 -10800 1 ARST} - {-197326800 -14400 0 ART} - {-190843200 -10800 1 ARST} - {-184194000 -14400 0 ART} - {-164491200 -10800 1 ARST} - {-152658000 -14400 0 ART} - {-132955200 -10800 1 ARST} - {-121122000 -14400 0 ART} - {-101419200 -10800 1 ARST} - {-86821200 -14400 0 ART} - {-71092800 -10800 1 ARST} - {-54766800 -14400 0 ART} - {-39038400 -10800 1 ARST} - {-23317200 -14400 0 ART} - {-7588800 -10800 0 ART} - {128142000 -7200 1 ARST} - {136605600 -10800 0 ART} - {596948400 -7200 1 ARST} - {605066400 -10800 0 ART} - {624423600 -7200 1 ARST} - {636516000 -10800 0 ART} - {656478000 -7200 1 ARST} - {667965600 -14400 0 WART} - {687931200 -7200 0 ARST} - {699415200 -10800 0 ART} - {719377200 -7200 1 ARST} - {731469600 -10800 0 ART} - {938916000 -10800 0 ART} - {938919600 -10800 1 ARST} - {952056000 -10800 0 ART} - {1198983600 -7200 1 ARST} - {1205632800 -10800 0 ART} - {1224385200 -7200 1 ARST} - {1237082400 -10800 0 ART} + {-1567453392 -14400 0 -04} + {-1233432000 -10800 0 -03} + {-1222981200 -14400 0 -04} + {-1205956800 -10800 1 -03} + {-1194037200 -14400 0 -04} + {-1172865600 -10800 1 -03} + {-1162501200 -14400 0 -04} + {-1141329600 -10800 1 -03} + {-1130965200 -14400 0 -04} + {-1109793600 -10800 1 -03} + {-1099429200 -14400 0 -04} + {-1078257600 -10800 1 -03} + {-1067806800 -14400 0 -04} + {-1046635200 -10800 1 -03} + {-1036270800 -14400 0 -04} + {-1015099200 -10800 1 -03} + {-1004734800 -14400 0 -04} + {-983563200 -10800 1 -03} + {-973198800 -14400 0 -04} + {-952027200 -10800 1 -03} + {-941576400 -14400 0 -04} + {-931032000 -10800 1 -03} + {-900882000 -14400 0 -04} + {-890337600 -10800 1 -03} + {-833749200 -14400 0 -04} + {-827265600 -10800 1 -03} + {-752274000 -14400 0 -04} + {-733780800 -10800 1 -03} + {-197326800 -14400 0 -04} + {-190843200 -10800 1 -03} + {-184194000 -14400 0 -04} + {-164491200 -10800 1 -03} + {-152658000 -14400 0 -04} + {-132955200 -10800 1 -03} + {-121122000 -14400 0 -04} + {-101419200 -10800 1 -03} + {-86821200 -14400 0 -04} + {-71092800 -10800 1 -03} + {-54766800 -14400 0 -04} + {-39038400 -10800 1 -03} + {-23317200 -14400 0 -04} + {-7588800 -10800 0 -03} + {128142000 -7200 1 -02} + {136605600 -10800 0 -03} + {596948400 -7200 1 -02} + {605066400 -10800 0 -03} + {624423600 -7200 1 -02} + {636516000 -10800 0 -03} + {656478000 -7200 1 -02} + {667965600 -14400 0 -04} + {687931200 -7200 0 -02} + {699415200 -10800 0 -03} + {719377200 -7200 1 -02} + {731469600 -10800 0 -03} + {938916000 -10800 0 -04} + {938919600 -10800 1 -03} + {952056000 -10800 0 -03} + {1198983600 -7200 1 -02} + {1205632800 -10800 0 -03} + {1224385200 -7200 1 -02} + {1237082400 -10800 0 -03} } diff --git a/library/tzdata/America/Argentina/Jujuy b/library/tzdata/America/Argentina/Jujuy index 4f95f8a..0e11ba2 100644 --- a/library/tzdata/America/Argentina/Jujuy +++ b/library/tzdata/America/Argentina/Jujuy @@ -3,65 +3,65 @@ set TZData(:America/Argentina/Jujuy) { {-9223372036854775808 -15672 0 LMT} {-2372096328 -15408 0 CMT} - {-1567453392 -14400 0 ART} - {-1233432000 -10800 0 ARST} - {-1222981200 -14400 0 ART} - {-1205956800 -10800 1 ARST} - {-1194037200 -14400 0 ART} - {-1172865600 -10800 1 ARST} - {-1162501200 -14400 0 ART} - {-1141329600 -10800 1 ARST} - {-1130965200 -14400 0 ART} - {-1109793600 -10800 1 ARST} - {-1099429200 -14400 0 ART} - {-1078257600 -10800 1 ARST} - {-1067806800 -14400 0 ART} - {-1046635200 -10800 1 ARST} - {-1036270800 -14400 0 ART} - {-1015099200 -10800 1 ARST} - {-1004734800 -14400 0 ART} - {-983563200 -10800 1 ARST} - {-973198800 -14400 0 ART} - {-952027200 -10800 1 ARST} - {-941576400 -14400 0 ART} - {-931032000 -10800 1 ARST} - {-900882000 -14400 0 ART} - {-890337600 -10800 1 ARST} - {-833749200 -14400 0 ART} - {-827265600 -10800 1 ARST} - {-752274000 -14400 0 ART} - {-733780800 -10800 1 ARST} - {-197326800 -14400 0 ART} - {-190843200 -10800 1 ARST} - {-184194000 -14400 0 ART} - {-164491200 -10800 1 ARST} - {-152658000 -14400 0 ART} - {-132955200 -10800 1 ARST} - {-121122000 -14400 0 ART} - {-101419200 -10800 1 ARST} - {-86821200 -14400 0 ART} - {-71092800 -10800 1 ARST} - {-54766800 -14400 0 ART} - {-39038400 -10800 1 ARST} - {-23317200 -14400 0 ART} - {-7588800 -10800 0 ART} - {128142000 -7200 1 ARST} - {136605600 -10800 0 ART} - {596948400 -7200 1 ARST} - {605066400 -10800 0 ART} - {624423600 -7200 1 ARST} - {636516000 -14400 0 WART} - {657086400 -10800 1 WARST} - {669178800 -14400 0 WART} - {686721600 -7200 1 ARST} - {694231200 -7200 0 ART} - {699415200 -10800 0 ART} - {719377200 -7200 1 ARST} - {731469600 -10800 0 ART} - {938916000 -10800 0 ART} - {938919600 -10800 1 ARST} - {952056000 -10800 0 ART} - {1198983600 -7200 1 ARST} - {1205632800 -10800 0 ART} - {1224295200 -10800 0 ART} + {-1567453392 -14400 0 -04} + {-1233432000 -10800 0 -03} + {-1222981200 -14400 0 -04} + {-1205956800 -10800 1 -03} + {-1194037200 -14400 0 -04} + {-1172865600 -10800 1 -03} + {-1162501200 -14400 0 -04} + {-1141329600 -10800 1 -03} + {-1130965200 -14400 0 -04} + {-1109793600 -10800 1 -03} + {-1099429200 -14400 0 -04} + {-1078257600 -10800 1 -03} + {-1067806800 -14400 0 -04} + {-1046635200 -10800 1 -03} + {-1036270800 -14400 0 -04} + {-1015099200 -10800 1 -03} + {-1004734800 -14400 0 -04} + {-983563200 -10800 1 -03} + {-973198800 -14400 0 -04} + {-952027200 -10800 1 -03} + {-941576400 -14400 0 -04} + {-931032000 -10800 1 -03} + {-900882000 -14400 0 -04} + {-890337600 -10800 1 -03} + {-833749200 -14400 0 -04} + {-827265600 -10800 1 -03} + {-752274000 -14400 0 -04} + {-733780800 -10800 1 -03} + {-197326800 -14400 0 -04} + {-190843200 -10800 1 -03} + {-184194000 -14400 0 -04} + {-164491200 -10800 1 -03} + {-152658000 -14400 0 -04} + {-132955200 -10800 1 -03} + {-121122000 -14400 0 -04} + {-101419200 -10800 1 -03} + {-86821200 -14400 0 -04} + {-71092800 -10800 1 -03} + {-54766800 -14400 0 -04} + {-39038400 -10800 1 -03} + {-23317200 -14400 0 -04} + {-7588800 -10800 0 -03} + {128142000 -7200 1 -02} + {136605600 -10800 0 -03} + {596948400 -7200 1 -02} + {605066400 -10800 0 -03} + {624423600 -7200 1 -02} + {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} + {731469600 -10800 0 -03} + {938916000 -10800 0 -04} + {938919600 -10800 1 -03} + {952056000 -10800 0 -03} + {1198983600 -7200 1 -02} + {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 835e29d..90e0030 100644 --- a/library/tzdata/America/Argentina/La_Rioja +++ b/library/tzdata/America/Argentina/La_Rioja @@ -3,67 +3,67 @@ set TZData(:America/Argentina/La_Rioja) { {-9223372036854775808 -16044 0 LMT} {-2372095956 -15408 0 CMT} - {-1567453392 -14400 0 ART} - {-1233432000 -10800 0 ARST} - {-1222981200 -14400 0 ART} - {-1205956800 -10800 1 ARST} - {-1194037200 -14400 0 ART} - {-1172865600 -10800 1 ARST} - {-1162501200 -14400 0 ART} - {-1141329600 -10800 1 ARST} - {-1130965200 -14400 0 ART} - {-1109793600 -10800 1 ARST} - {-1099429200 -14400 0 ART} - {-1078257600 -10800 1 ARST} - {-1067806800 -14400 0 ART} - {-1046635200 -10800 1 ARST} - {-1036270800 -14400 0 ART} - {-1015099200 -10800 1 ARST} - {-1004734800 -14400 0 ART} - {-983563200 -10800 1 ARST} - {-973198800 -14400 0 ART} - {-952027200 -10800 1 ARST} - {-941576400 -14400 0 ART} - {-931032000 -10800 1 ARST} - {-900882000 -14400 0 ART} - {-890337600 -10800 1 ARST} - {-833749200 -14400 0 ART} - {-827265600 -10800 1 ARST} - {-752274000 -14400 0 ART} - {-733780800 -10800 1 ARST} - {-197326800 -14400 0 ART} - {-190843200 -10800 1 ARST} - {-184194000 -14400 0 ART} - {-164491200 -10800 1 ARST} - {-152658000 -14400 0 ART} - {-132955200 -10800 1 ARST} - {-121122000 -14400 0 ART} - {-101419200 -10800 1 ARST} - {-86821200 -14400 0 ART} - {-71092800 -10800 1 ARST} - {-54766800 -14400 0 ART} - {-39038400 -10800 1 ARST} - {-23317200 -14400 0 ART} - {-7588800 -10800 0 ART} - {128142000 -7200 1 ARST} - {136605600 -10800 0 ART} - {596948400 -7200 1 ARST} - {605066400 -10800 0 ART} - {624423600 -7200 1 ARST} - {636516000 -10800 0 ART} - {656478000 -7200 1 ARST} - {667792800 -14400 0 WART} - {673588800 -10800 0 ART} - {687927600 -7200 1 ARST} - {699415200 -10800 0 ART} - {719377200 -7200 1 ARST} - {731469600 -10800 0 ART} - {938916000 -10800 0 ART} - {938919600 -10800 1 ARST} - {952056000 -10800 0 ART} - {1086058800 -14400 0 WART} - {1087704000 -10800 0 ART} - {1198983600 -7200 1 ARST} - {1205632800 -10800 0 ART} - {1224295200 -10800 0 ART} + {-1567453392 -14400 0 -04} + {-1233432000 -10800 0 -03} + {-1222981200 -14400 0 -04} + {-1205956800 -10800 1 -03} + {-1194037200 -14400 0 -04} + {-1172865600 -10800 1 -03} + {-1162501200 -14400 0 -04} + {-1141329600 -10800 1 -03} + {-1130965200 -14400 0 -04} + {-1109793600 -10800 1 -03} + {-1099429200 -14400 0 -04} + {-1078257600 -10800 1 -03} + {-1067806800 -14400 0 -04} + {-1046635200 -10800 1 -03} + {-1036270800 -14400 0 -04} + {-1015099200 -10800 1 -03} + {-1004734800 -14400 0 -04} + {-983563200 -10800 1 -03} + {-973198800 -14400 0 -04} + {-952027200 -10800 1 -03} + {-941576400 -14400 0 -04} + {-931032000 -10800 1 -03} + {-900882000 -14400 0 -04} + {-890337600 -10800 1 -03} + {-833749200 -14400 0 -04} + {-827265600 -10800 1 -03} + {-752274000 -14400 0 -04} + {-733780800 -10800 1 -03} + {-197326800 -14400 0 -04} + {-190843200 -10800 1 -03} + {-184194000 -14400 0 -04} + {-164491200 -10800 1 -03} + {-152658000 -14400 0 -04} + {-132955200 -10800 1 -03} + {-121122000 -14400 0 -04} + {-101419200 -10800 1 -03} + {-86821200 -14400 0 -04} + {-71092800 -10800 1 -03} + {-54766800 -14400 0 -04} + {-39038400 -10800 1 -03} + {-23317200 -14400 0 -04} + {-7588800 -10800 0 -03} + {128142000 -7200 1 -02} + {136605600 -10800 0 -03} + {596948400 -7200 1 -02} + {605066400 -10800 0 -03} + {624423600 -7200 1 -02} + {636516000 -10800 0 -03} + {656478000 -7200 1 -02} + {667792800 -14400 0 -04} + {673588800 -10800 0 -03} + {687927600 -7200 1 -02} + {699415200 -10800 0 -03} + {719377200 -7200 1 -02} + {731469600 -10800 0 -03} + {938916000 -10800 0 -04} + {938919600 -10800 1 -03} + {952056000 -10800 0 -03} + {1086058800 -14400 0 -04} + {1087704000 -10800 0 -03} + {1198983600 -7200 1 -02} + {1205632800 -10800 0 -03} + {1224295200 -10800 0 -03} } diff --git a/library/tzdata/America/Argentina/Mendoza b/library/tzdata/America/Argentina/Mendoza index 2c6fb58..8dfcd2b 100644 --- a/library/tzdata/America/Argentina/Mendoza +++ b/library/tzdata/America/Argentina/Mendoza @@ -3,66 +3,66 @@ set TZData(:America/Argentina/Mendoza) { {-9223372036854775808 -16516 0 LMT} {-2372095484 -15408 0 CMT} - {-1567453392 -14400 0 ART} - {-1233432000 -10800 0 ARST} - {-1222981200 -14400 0 ART} - {-1205956800 -10800 1 ARST} - {-1194037200 -14400 0 ART} - {-1172865600 -10800 1 ARST} - {-1162501200 -14400 0 ART} - {-1141329600 -10800 1 ARST} - {-1130965200 -14400 0 ART} - {-1109793600 -10800 1 ARST} - {-1099429200 -14400 0 ART} - {-1078257600 -10800 1 ARST} - {-1067806800 -14400 0 ART} - {-1046635200 -10800 1 ARST} - {-1036270800 -14400 0 ART} - {-1015099200 -10800 1 ARST} - {-1004734800 -14400 0 ART} - {-983563200 -10800 1 ARST} - {-973198800 -14400 0 ART} - {-952027200 -10800 1 ARST} - {-941576400 -14400 0 ART} - {-931032000 -10800 1 ARST} - {-900882000 -14400 0 ART} - {-890337600 -10800 1 ARST} - {-833749200 -14400 0 ART} - {-827265600 -10800 1 ARST} - {-752274000 -14400 0 ART} - {-733780800 -10800 1 ARST} - {-197326800 -14400 0 ART} - {-190843200 -10800 1 ARST} - {-184194000 -14400 0 ART} - {-164491200 -10800 1 ARST} - {-152658000 -14400 0 ART} - {-132955200 -10800 1 ARST} - {-121122000 -14400 0 ART} - {-101419200 -10800 1 ARST} - {-86821200 -14400 0 ART} - {-71092800 -10800 1 ARST} - {-54766800 -14400 0 ART} - {-39038400 -10800 1 ARST} - {-23317200 -14400 0 ART} - {-7588800 -10800 0 ART} - {128142000 -7200 1 ARST} - {136605600 -10800 0 ART} - {596948400 -7200 1 ARST} - {605066400 -10800 0 ART} - {624423600 -7200 1 ARST} - {636516000 -14400 0 WART} - {655963200 -10800 1 WARST} - {667796400 -14400 0 WART} - {687499200 -10800 1 WARST} - {699418800 -14400 0 WART} - {719380800 -7200 0 ARST} - {731469600 -10800 0 ART} - {938916000 -10800 0 ART} - {938919600 -10800 1 ARST} - {952056000 -10800 0 ART} - {1085281200 -14400 0 WART} - {1096171200 -10800 0 ART} - {1198983600 -7200 1 ARST} - {1205632800 -10800 0 ART} - {1224295200 -10800 0 ART} + {-1567453392 -14400 0 -04} + {-1233432000 -10800 0 -03} + {-1222981200 -14400 0 -04} + {-1205956800 -10800 1 -03} + {-1194037200 -14400 0 -04} + {-1172865600 -10800 1 -03} + {-1162501200 -14400 0 -04} + {-1141329600 -10800 1 -03} + {-1130965200 -14400 0 -04} + {-1109793600 -10800 1 -03} + {-1099429200 -14400 0 -04} + {-1078257600 -10800 1 -03} + {-1067806800 -14400 0 -04} + {-1046635200 -10800 1 -03} + {-1036270800 -14400 0 -04} + {-1015099200 -10800 1 -03} + {-1004734800 -14400 0 -04} + {-983563200 -10800 1 -03} + {-973198800 -14400 0 -04} + {-952027200 -10800 1 -03} + {-941576400 -14400 0 -04} + {-931032000 -10800 1 -03} + {-900882000 -14400 0 -04} + {-890337600 -10800 1 -03} + {-833749200 -14400 0 -04} + {-827265600 -10800 1 -03} + {-752274000 -14400 0 -04} + {-733780800 -10800 1 -03} + {-197326800 -14400 0 -04} + {-190843200 -10800 1 -03} + {-184194000 -14400 0 -04} + {-164491200 -10800 1 -03} + {-152658000 -14400 0 -04} + {-132955200 -10800 1 -03} + {-121122000 -14400 0 -04} + {-101419200 -10800 1 -03} + {-86821200 -14400 0 -04} + {-71092800 -10800 1 -03} + {-54766800 -14400 0 -04} + {-39038400 -10800 1 -03} + {-23317200 -14400 0 -04} + {-7588800 -10800 0 -03} + {128142000 -7200 1 -02} + {136605600 -10800 0 -03} + {596948400 -7200 1 -02} + {605066400 -10800 0 -03} + {624423600 -7200 1 -02} + {636516000 -14400 0 -04} + {655963200 -10800 1 -03} + {667796400 -14400 0 -04} + {687499200 -10800 1 -03} + {699418800 -14400 0 -04} + {719380800 -7200 0 -02} + {731469600 -10800 0 -03} + {938916000 -10800 0 -04} + {938919600 -10800 1 -03} + {952056000 -10800 0 -03} + {1085281200 -14400 0 -04} + {1096171200 -10800 0 -03} + {1198983600 -7200 1 -02} + {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 91d37dd..4b2a348 100644 --- a/library/tzdata/America/Argentina/Rio_Gallegos +++ b/library/tzdata/America/Argentina/Rio_Gallegos @@ -3,66 +3,66 @@ set TZData(:America/Argentina/Rio_Gallegos) { {-9223372036854775808 -16612 0 LMT} {-2372095388 -15408 0 CMT} - {-1567453392 -14400 0 ART} - {-1233432000 -10800 0 ARST} - {-1222981200 -14400 0 ART} - {-1205956800 -10800 1 ARST} - {-1194037200 -14400 0 ART} - {-1172865600 -10800 1 ARST} - {-1162501200 -14400 0 ART} - {-1141329600 -10800 1 ARST} - {-1130965200 -14400 0 ART} - {-1109793600 -10800 1 ARST} - {-1099429200 -14400 0 ART} - {-1078257600 -10800 1 ARST} - {-1067806800 -14400 0 ART} - {-1046635200 -10800 1 ARST} - {-1036270800 -14400 0 ART} - {-1015099200 -10800 1 ARST} - {-1004734800 -14400 0 ART} - {-983563200 -10800 1 ARST} - {-973198800 -14400 0 ART} - {-952027200 -10800 1 ARST} - {-941576400 -14400 0 ART} - {-931032000 -10800 1 ARST} - {-900882000 -14400 0 ART} - {-890337600 -10800 1 ARST} - {-833749200 -14400 0 ART} - {-827265600 -10800 1 ARST} - {-752274000 -14400 0 ART} - {-733780800 -10800 1 ARST} - {-197326800 -14400 0 ART} - {-190843200 -10800 1 ARST} - {-184194000 -14400 0 ART} - {-164491200 -10800 1 ARST} - {-152658000 -14400 0 ART} - {-132955200 -10800 1 ARST} - {-121122000 -14400 0 ART} - {-101419200 -10800 1 ARST} - {-86821200 -14400 0 ART} - {-71092800 -10800 1 ARST} - {-54766800 -14400 0 ART} - {-39038400 -10800 1 ARST} - {-23317200 -14400 0 ART} - {-7588800 -10800 0 ART} - {128142000 -7200 1 ARST} - {136605600 -10800 0 ART} - {596948400 -7200 1 ARST} - {605066400 -10800 0 ART} - {624423600 -7200 1 ARST} - {636516000 -10800 0 ART} - {656478000 -7200 1 ARST} - {667965600 -10800 0 ART} - {687927600 -7200 1 ARST} - {699415200 -10800 0 ART} - {719377200 -7200 1 ARST} - {731469600 -10800 0 ART} - {938916000 -10800 0 ART} - {938919600 -10800 1 ARST} - {952056000 -10800 0 ART} - {1086058800 -14400 0 WART} - {1087704000 -10800 0 ART} - {1198983600 -7200 1 ARST} - {1205632800 -10800 0 ART} - {1224295200 -10800 0 ART} + {-1567453392 -14400 0 -04} + {-1233432000 -10800 0 -03} + {-1222981200 -14400 0 -04} + {-1205956800 -10800 1 -03} + {-1194037200 -14400 0 -04} + {-1172865600 -10800 1 -03} + {-1162501200 -14400 0 -04} + {-1141329600 -10800 1 -03} + {-1130965200 -14400 0 -04} + {-1109793600 -10800 1 -03} + {-1099429200 -14400 0 -04} + {-1078257600 -10800 1 -03} + {-1067806800 -14400 0 -04} + {-1046635200 -10800 1 -03} + {-1036270800 -14400 0 -04} + {-1015099200 -10800 1 -03} + {-1004734800 -14400 0 -04} + {-983563200 -10800 1 -03} + {-973198800 -14400 0 -04} + {-952027200 -10800 1 -03} + {-941576400 -14400 0 -04} + {-931032000 -10800 1 -03} + {-900882000 -14400 0 -04} + {-890337600 -10800 1 -03} + {-833749200 -14400 0 -04} + {-827265600 -10800 1 -03} + {-752274000 -14400 0 -04} + {-733780800 -10800 1 -03} + {-197326800 -14400 0 -04} + {-190843200 -10800 1 -03} + {-184194000 -14400 0 -04} + {-164491200 -10800 1 -03} + {-152658000 -14400 0 -04} + {-132955200 -10800 1 -03} + {-121122000 -14400 0 -04} + {-101419200 -10800 1 -03} + {-86821200 -14400 0 -04} + {-71092800 -10800 1 -03} + {-54766800 -14400 0 -04} + {-39038400 -10800 1 -03} + {-23317200 -14400 0 -04} + {-7588800 -10800 0 -03} + {128142000 -7200 1 -02} + {136605600 -10800 0 -03} + {596948400 -7200 1 -02} + {605066400 -10800 0 -03} + {624423600 -7200 1 -02} + {636516000 -10800 0 -03} + {656478000 -7200 1 -02} + {667965600 -10800 0 -03} + {687927600 -7200 1 -02} + {699415200 -10800 0 -03} + {719377200 -7200 1 -02} + {731469600 -10800 0 -03} + {938916000 -10800 0 -04} + {938919600 -10800 1 -03} + {952056000 -10800 0 -03} + {1086058800 -14400 0 -04} + {1087704000 -10800 0 -03} + {1198983600 -7200 1 -02} + {1205632800 -10800 0 -03} + {1224295200 -10800 0 -03} } diff --git a/library/tzdata/America/Argentina/Salta b/library/tzdata/America/Argentina/Salta index a5a7010..4f9ccf9 100644 --- a/library/tzdata/America/Argentina/Salta +++ b/library/tzdata/America/Argentina/Salta @@ -3,64 +3,64 @@ set TZData(:America/Argentina/Salta) { {-9223372036854775808 -15700 0 LMT} {-2372096300 -15408 0 CMT} - {-1567453392 -14400 0 ART} - {-1233432000 -10800 0 ARST} - {-1222981200 -14400 0 ART} - {-1205956800 -10800 1 ARST} - {-1194037200 -14400 0 ART} - {-1172865600 -10800 1 ARST} - {-1162501200 -14400 0 ART} - {-1141329600 -10800 1 ARST} - {-1130965200 -14400 0 ART} - {-1109793600 -10800 1 ARST} - {-1099429200 -14400 0 ART} - {-1078257600 -10800 1 ARST} - {-1067806800 -14400 0 ART} - {-1046635200 -10800 1 ARST} - {-1036270800 -14400 0 ART} - {-1015099200 -10800 1 ARST} - {-1004734800 -14400 0 ART} - {-983563200 -10800 1 ARST} - {-973198800 -14400 0 ART} - {-952027200 -10800 1 ARST} - {-941576400 -14400 0 ART} - {-931032000 -10800 1 ARST} - {-900882000 -14400 0 ART} - {-890337600 -10800 1 ARST} - {-833749200 -14400 0 ART} - {-827265600 -10800 1 ARST} - {-752274000 -14400 0 ART} - {-733780800 -10800 1 ARST} - {-197326800 -14400 0 ART} - {-190843200 -10800 1 ARST} - {-184194000 -14400 0 ART} - {-164491200 -10800 1 ARST} - {-152658000 -14400 0 ART} - {-132955200 -10800 1 ARST} - {-121122000 -14400 0 ART} - {-101419200 -10800 1 ARST} - {-86821200 -14400 0 ART} - {-71092800 -10800 1 ARST} - {-54766800 -14400 0 ART} - {-39038400 -10800 1 ARST} - {-23317200 -14400 0 ART} - {-7588800 -10800 0 ART} - {128142000 -7200 1 ARST} - {136605600 -10800 0 ART} - {596948400 -7200 1 ARST} - {605066400 -10800 0 ART} - {624423600 -7200 1 ARST} - {636516000 -10800 0 ART} - {656478000 -7200 1 ARST} - {667965600 -14400 0 WART} - {687931200 -7200 0 ARST} - {699415200 -10800 0 ART} - {719377200 -7200 1 ARST} - {731469600 -10800 0 ART} - {938916000 -10800 0 ART} - {938919600 -10800 1 ARST} - {952056000 -10800 0 ART} - {1198983600 -7200 1 ARST} - {1205632800 -10800 0 ART} - {1224295200 -10800 0 ART} + {-1567453392 -14400 0 -04} + {-1233432000 -10800 0 -03} + {-1222981200 -14400 0 -04} + {-1205956800 -10800 1 -03} + {-1194037200 -14400 0 -04} + {-1172865600 -10800 1 -03} + {-1162501200 -14400 0 -04} + {-1141329600 -10800 1 -03} + {-1130965200 -14400 0 -04} + {-1109793600 -10800 1 -03} + {-1099429200 -14400 0 -04} + {-1078257600 -10800 1 -03} + {-1067806800 -14400 0 -04} + {-1046635200 -10800 1 -03} + {-1036270800 -14400 0 -04} + {-1015099200 -10800 1 -03} + {-1004734800 -14400 0 -04} + {-983563200 -10800 1 -03} + {-973198800 -14400 0 -04} + {-952027200 -10800 1 -03} + {-941576400 -14400 0 -04} + {-931032000 -10800 1 -03} + {-900882000 -14400 0 -04} + {-890337600 -10800 1 -03} + {-833749200 -14400 0 -04} + {-827265600 -10800 1 -03} + {-752274000 -14400 0 -04} + {-733780800 -10800 1 -03} + {-197326800 -14400 0 -04} + {-190843200 -10800 1 -03} + {-184194000 -14400 0 -04} + {-164491200 -10800 1 -03} + {-152658000 -14400 0 -04} + {-132955200 -10800 1 -03} + {-121122000 -14400 0 -04} + {-101419200 -10800 1 -03} + {-86821200 -14400 0 -04} + {-71092800 -10800 1 -03} + {-54766800 -14400 0 -04} + {-39038400 -10800 1 -03} + {-23317200 -14400 0 -04} + {-7588800 -10800 0 -03} + {128142000 -7200 1 -02} + {136605600 -10800 0 -03} + {596948400 -7200 1 -02} + {605066400 -10800 0 -03} + {624423600 -7200 1 -02} + {636516000 -10800 0 -03} + {656478000 -7200 1 -02} + {667965600 -14400 0 -04} + {687931200 -7200 0 -02} + {699415200 -10800 0 -03} + {719377200 -7200 1 -02} + {731469600 -10800 0 -03} + {938916000 -10800 0 -04} + {938919600 -10800 1 -03} + {952056000 -10800 0 -03} + {1198983600 -7200 1 -02} + {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 417e234..1f0530a 100644 --- a/library/tzdata/America/Argentina/San_Juan +++ b/library/tzdata/America/Argentina/San_Juan @@ -3,67 +3,67 @@ set TZData(:America/Argentina/San_Juan) { {-9223372036854775808 -16444 0 LMT} {-2372095556 -15408 0 CMT} - {-1567453392 -14400 0 ART} - {-1233432000 -10800 0 ARST} - {-1222981200 -14400 0 ART} - {-1205956800 -10800 1 ARST} - {-1194037200 -14400 0 ART} - {-1172865600 -10800 1 ARST} - {-1162501200 -14400 0 ART} - {-1141329600 -10800 1 ARST} - {-1130965200 -14400 0 ART} - {-1109793600 -10800 1 ARST} - {-1099429200 -14400 0 ART} - {-1078257600 -10800 1 ARST} - {-1067806800 -14400 0 ART} - {-1046635200 -10800 1 ARST} - {-1036270800 -14400 0 ART} - {-1015099200 -10800 1 ARST} - {-1004734800 -14400 0 ART} - {-983563200 -10800 1 ARST} - {-973198800 -14400 0 ART} - {-952027200 -10800 1 ARST} - {-941576400 -14400 0 ART} - {-931032000 -10800 1 ARST} - {-900882000 -14400 0 ART} - {-890337600 -10800 1 ARST} - {-833749200 -14400 0 ART} - {-827265600 -10800 1 ARST} - {-752274000 -14400 0 ART} - {-733780800 -10800 1 ARST} - {-197326800 -14400 0 ART} - {-190843200 -10800 1 ARST} - {-184194000 -14400 0 ART} - {-164491200 -10800 1 ARST} - {-152658000 -14400 0 ART} - {-132955200 -10800 1 ARST} - {-121122000 -14400 0 ART} - {-101419200 -10800 1 ARST} - {-86821200 -14400 0 ART} - {-71092800 -10800 1 ARST} - {-54766800 -14400 0 ART} - {-39038400 -10800 1 ARST} - {-23317200 -14400 0 ART} - {-7588800 -10800 0 ART} - {128142000 -7200 1 ARST} - {136605600 -10800 0 ART} - {596948400 -7200 1 ARST} - {605066400 -10800 0 ART} - {624423600 -7200 1 ARST} - {636516000 -10800 0 ART} - {656478000 -7200 1 ARST} - {667792800 -14400 0 WART} - {673588800 -10800 0 ART} - {687927600 -7200 1 ARST} - {699415200 -10800 0 ART} - {719377200 -7200 1 ARST} - {731469600 -10800 0 ART} - {938916000 -10800 0 ART} - {938919600 -10800 1 ARST} - {952056000 -10800 0 ART} - {1085972400 -14400 0 WART} - {1090728000 -10800 0 ART} - {1198983600 -7200 1 ARST} - {1205632800 -10800 0 ART} - {1224295200 -10800 0 ART} + {-1567453392 -14400 0 -04} + {-1233432000 -10800 0 -03} + {-1222981200 -14400 0 -04} + {-1205956800 -10800 1 -03} + {-1194037200 -14400 0 -04} + {-1172865600 -10800 1 -03} + {-1162501200 -14400 0 -04} + {-1141329600 -10800 1 -03} + {-1130965200 -14400 0 -04} + {-1109793600 -10800 1 -03} + {-1099429200 -14400 0 -04} + {-1078257600 -10800 1 -03} + {-1067806800 -14400 0 -04} + {-1046635200 -10800 1 -03} + {-1036270800 -14400 0 -04} + {-1015099200 -10800 1 -03} + {-1004734800 -14400 0 -04} + {-983563200 -10800 1 -03} + {-973198800 -14400 0 -04} + {-952027200 -10800 1 -03} + {-941576400 -14400 0 -04} + {-931032000 -10800 1 -03} + {-900882000 -14400 0 -04} + {-890337600 -10800 1 -03} + {-833749200 -14400 0 -04} + {-827265600 -10800 1 -03} + {-752274000 -14400 0 -04} + {-733780800 -10800 1 -03} + {-197326800 -14400 0 -04} + {-190843200 -10800 1 -03} + {-184194000 -14400 0 -04} + {-164491200 -10800 1 -03} + {-152658000 -14400 0 -04} + {-132955200 -10800 1 -03} + {-121122000 -14400 0 -04} + {-101419200 -10800 1 -03} + {-86821200 -14400 0 -04} + {-71092800 -10800 1 -03} + {-54766800 -14400 0 -04} + {-39038400 -10800 1 -03} + {-23317200 -14400 0 -04} + {-7588800 -10800 0 -03} + {128142000 -7200 1 -02} + {136605600 -10800 0 -03} + {596948400 -7200 1 -02} + {605066400 -10800 0 -03} + {624423600 -7200 1 -02} + {636516000 -10800 0 -03} + {656478000 -7200 1 -02} + {667792800 -14400 0 -04} + {673588800 -10800 0 -03} + {687927600 -7200 1 -02} + {699415200 -10800 0 -03} + {719377200 -7200 1 -02} + {731469600 -10800 0 -03} + {938916000 -10800 0 -04} + {938919600 -10800 1 -03} + {952056000 -10800 0 -03} + {1085972400 -14400 0 -04} + {1090728000 -10800 0 -03} + {1198983600 -7200 1 -02} + {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 8ca55d7..3583a39 100644 --- a/library/tzdata/America/Argentina/San_Luis +++ b/library/tzdata/America/Argentina/San_Luis @@ -3,66 +3,66 @@ set TZData(:America/Argentina/San_Luis) { {-9223372036854775808 -15924 0 LMT} {-2372096076 -15408 0 CMT} - {-1567453392 -14400 0 ART} - {-1233432000 -10800 0 ARST} - {-1222981200 -14400 0 ART} - {-1205956800 -10800 1 ARST} - {-1194037200 -14400 0 ART} - {-1172865600 -10800 1 ARST} - {-1162501200 -14400 0 ART} - {-1141329600 -10800 1 ARST} - {-1130965200 -14400 0 ART} - {-1109793600 -10800 1 ARST} - {-1099429200 -14400 0 ART} - {-1078257600 -10800 1 ARST} - {-1067806800 -14400 0 ART} - {-1046635200 -10800 1 ARST} - {-1036270800 -14400 0 ART} - {-1015099200 -10800 1 ARST} - {-1004734800 -14400 0 ART} - {-983563200 -10800 1 ARST} - {-973198800 -14400 0 ART} - {-952027200 -10800 1 ARST} - {-941576400 -14400 0 ART} - {-931032000 -10800 1 ARST} - {-900882000 -14400 0 ART} - {-890337600 -10800 1 ARST} - {-833749200 -14400 0 ART} - {-827265600 -10800 1 ARST} - {-752274000 -14400 0 ART} - {-733780800 -10800 1 ARST} - {-197326800 -14400 0 ART} - {-190843200 -10800 1 ARST} - {-184194000 -14400 0 ART} - {-164491200 -10800 1 ARST} - {-152658000 -14400 0 ART} - {-132955200 -10800 1 ARST} - {-121122000 -14400 0 ART} - {-101419200 -10800 1 ARST} - {-86821200 -14400 0 ART} - {-71092800 -10800 1 ARST} - {-54766800 -14400 0 ART} - {-39038400 -10800 1 ARST} - {-23317200 -14400 0 ART} - {-7588800 -10800 0 ART} - {128142000 -7200 1 ARST} - {136605600 -10800 0 ART} - {596948400 -7200 1 ARST} - {605066400 -10800 0 ART} - {624423600 -7200 1 ARST} - {631159200 -7200 1 ARST} - {637380000 -14400 0 WART} - {655963200 -10800 1 WARST} - {667796400 -14400 0 WART} - {675748800 -10800 0 ART} - {938919600 -10800 1 WARST} - {952052400 -10800 0 ART} - {1085972400 -14400 0 WART} - {1090728000 -10800 0 ART} - {1198983600 -7200 1 ARST} - {1200880800 -10800 0 WART} - {1205031600 -14400 0 WART} - {1223784000 -10800 1 WARST} - {1236481200 -14400 0 WART} - {1255233600 -10800 0 ART} + {-1567453392 -14400 0 -04} + {-1233432000 -10800 0 -03} + {-1222981200 -14400 0 -04} + {-1205956800 -10800 1 -03} + {-1194037200 -14400 0 -04} + {-1172865600 -10800 1 -03} + {-1162501200 -14400 0 -04} + {-1141329600 -10800 1 -03} + {-1130965200 -14400 0 -04} + {-1109793600 -10800 1 -03} + {-1099429200 -14400 0 -04} + {-1078257600 -10800 1 -03} + {-1067806800 -14400 0 -04} + {-1046635200 -10800 1 -03} + {-1036270800 -14400 0 -04} + {-1015099200 -10800 1 -03} + {-1004734800 -14400 0 -04} + {-983563200 -10800 1 -03} + {-973198800 -14400 0 -04} + {-952027200 -10800 1 -03} + {-941576400 -14400 0 -04} + {-931032000 -10800 1 -03} + {-900882000 -14400 0 -04} + {-890337600 -10800 1 -03} + {-833749200 -14400 0 -04} + {-827265600 -10800 1 -03} + {-752274000 -14400 0 -04} + {-733780800 -10800 1 -03} + {-197326800 -14400 0 -04} + {-190843200 -10800 1 -03} + {-184194000 -14400 0 -04} + {-164491200 -10800 1 -03} + {-152658000 -14400 0 -04} + {-132955200 -10800 1 -03} + {-121122000 -14400 0 -04} + {-101419200 -10800 1 -03} + {-86821200 -14400 0 -04} + {-71092800 -10800 1 -03} + {-54766800 -14400 0 -04} + {-39038400 -10800 1 -03} + {-23317200 -14400 0 -04} + {-7588800 -10800 0 -03} + {128142000 -7200 1 -02} + {136605600 -10800 0 -03} + {596948400 -7200 1 -02} + {605066400 -10800 0 -03} + {624423600 -7200 1 -02} + {631159200 -7200 1 -02} + {637380000 -14400 0 -04} + {655963200 -10800 1 -03} + {667796400 -14400 0 -04} + {675748800 -10800 0 -03} + {938919600 -10800 1 -03} + {952052400 -10800 0 -03} + {1085972400 -14400 0 -04} + {1090728000 -10800 0 -03} + {1198983600 -7200 1 -02} + {1200880800 -10800 0 -04} + {1205031600 -14400 0 -04} + {1223784000 -10800 1 -03} + {1236481200 -14400 0 -04} + {1255233600 -10800 0 -03} } diff --git a/library/tzdata/America/Argentina/Tucuman b/library/tzdata/America/Argentina/Tucuman index 3500986..15c5c63 100644 --- a/library/tzdata/America/Argentina/Tucuman +++ b/library/tzdata/America/Argentina/Tucuman @@ -3,67 +3,67 @@ set TZData(:America/Argentina/Tucuman) { {-9223372036854775808 -15652 0 LMT} {-2372096348 -15408 0 CMT} - {-1567453392 -14400 0 ART} - {-1233432000 -10800 0 ARST} - {-1222981200 -14400 0 ART} - {-1205956800 -10800 1 ARST} - {-1194037200 -14400 0 ART} - {-1172865600 -10800 1 ARST} - {-1162501200 -14400 0 ART} - {-1141329600 -10800 1 ARST} - {-1130965200 -14400 0 ART} - {-1109793600 -10800 1 ARST} - {-1099429200 -14400 0 ART} - {-1078257600 -10800 1 ARST} - {-1067806800 -14400 0 ART} - {-1046635200 -10800 1 ARST} - {-1036270800 -14400 0 ART} - {-1015099200 -10800 1 ARST} - {-1004734800 -14400 0 ART} - {-983563200 -10800 1 ARST} - {-973198800 -14400 0 ART} - {-952027200 -10800 1 ARST} - {-941576400 -14400 0 ART} - {-931032000 -10800 1 ARST} - {-900882000 -14400 0 ART} - {-890337600 -10800 1 ARST} - {-833749200 -14400 0 ART} - {-827265600 -10800 1 ARST} - {-752274000 -14400 0 ART} - {-733780800 -10800 1 ARST} - {-197326800 -14400 0 ART} - {-190843200 -10800 1 ARST} - {-184194000 -14400 0 ART} - {-164491200 -10800 1 ARST} - {-152658000 -14400 0 ART} - {-132955200 -10800 1 ARST} - {-121122000 -14400 0 ART} - {-101419200 -10800 1 ARST} - {-86821200 -14400 0 ART} - {-71092800 -10800 1 ARST} - {-54766800 -14400 0 ART} - {-39038400 -10800 1 ARST} - {-23317200 -14400 0 ART} - {-7588800 -10800 0 ART} - {128142000 -7200 1 ARST} - {136605600 -10800 0 ART} - {596948400 -7200 1 ARST} - {605066400 -10800 0 ART} - {624423600 -7200 1 ARST} - {636516000 -10800 0 ART} - {656478000 -7200 1 ARST} - {667965600 -14400 0 WART} - {687931200 -7200 0 ARST} - {699415200 -10800 0 ART} - {719377200 -7200 1 ARST} - {731469600 -10800 0 ART} - {938916000 -10800 0 ART} - {938919600 -10800 1 ARST} - {952056000 -10800 0 ART} - {1086058800 -14400 0 WART} - {1087099200 -10800 0 ART} - {1198983600 -7200 1 ARST} - {1205632800 -10800 0 ART} - {1224385200 -7200 1 ARST} - {1237082400 -10800 0 ART} + {-1567453392 -14400 0 -04} + {-1233432000 -10800 0 -03} + {-1222981200 -14400 0 -04} + {-1205956800 -10800 1 -03} + {-1194037200 -14400 0 -04} + {-1172865600 -10800 1 -03} + {-1162501200 -14400 0 -04} + {-1141329600 -10800 1 -03} + {-1130965200 -14400 0 -04} + {-1109793600 -10800 1 -03} + {-1099429200 -14400 0 -04} + {-1078257600 -10800 1 -03} + {-1067806800 -14400 0 -04} + {-1046635200 -10800 1 -03} + {-1036270800 -14400 0 -04} + {-1015099200 -10800 1 -03} + {-1004734800 -14400 0 -04} + {-983563200 -10800 1 -03} + {-973198800 -14400 0 -04} + {-952027200 -10800 1 -03} + {-941576400 -14400 0 -04} + {-931032000 -10800 1 -03} + {-900882000 -14400 0 -04} + {-890337600 -10800 1 -03} + {-833749200 -14400 0 -04} + {-827265600 -10800 1 -03} + {-752274000 -14400 0 -04} + {-733780800 -10800 1 -03} + {-197326800 -14400 0 -04} + {-190843200 -10800 1 -03} + {-184194000 -14400 0 -04} + {-164491200 -10800 1 -03} + {-152658000 -14400 0 -04} + {-132955200 -10800 1 -03} + {-121122000 -14400 0 -04} + {-101419200 -10800 1 -03} + {-86821200 -14400 0 -04} + {-71092800 -10800 1 -03} + {-54766800 -14400 0 -04} + {-39038400 -10800 1 -03} + {-23317200 -14400 0 -04} + {-7588800 -10800 0 -03} + {128142000 -7200 1 -02} + {136605600 -10800 0 -03} + {596948400 -7200 1 -02} + {605066400 -10800 0 -03} + {624423600 -7200 1 -02} + {636516000 -10800 0 -03} + {656478000 -7200 1 -02} + {667965600 -14400 0 -04} + {687931200 -7200 0 -02} + {699415200 -10800 0 -03} + {719377200 -7200 1 -02} + {731469600 -10800 0 -03} + {938916000 -10800 0 -04} + {938919600 -10800 1 -03} + {952056000 -10800 0 -03} + {1086058800 -14400 0 -04} + {1087099200 -10800 0 -03} + {1198983600 -7200 1 -02} + {1205632800 -10800 0 -03} + {1224385200 -7200 1 -02} + {1237082400 -10800 0 -03} } diff --git a/library/tzdata/America/Argentina/Ushuaia b/library/tzdata/America/Argentina/Ushuaia index 4fcf92d..4214c1d 100644 --- a/library/tzdata/America/Argentina/Ushuaia +++ b/library/tzdata/America/Argentina/Ushuaia @@ -3,66 +3,66 @@ set TZData(:America/Argentina/Ushuaia) { {-9223372036854775808 -16392 0 LMT} {-2372095608 -15408 0 CMT} - {-1567453392 -14400 0 ART} - {-1233432000 -10800 0 ARST} - {-1222981200 -14400 0 ART} - {-1205956800 -10800 1 ARST} - {-1194037200 -14400 0 ART} - {-1172865600 -10800 1 ARST} - {-1162501200 -14400 0 ART} - {-1141329600 -10800 1 ARST} - {-1130965200 -14400 0 ART} - {-1109793600 -10800 1 ARST} - {-1099429200 -14400 0 ART} - {-1078257600 -10800 1 ARST} - {-1067806800 -14400 0 ART} - {-1046635200 -10800 1 ARST} - {-1036270800 -14400 0 ART} - {-1015099200 -10800 1 ARST} - {-1004734800 -14400 0 ART} - {-983563200 -10800 1 ARST} - {-973198800 -14400 0 ART} - {-952027200 -10800 1 ARST} - {-941576400 -14400 0 ART} - {-931032000 -10800 1 ARST} - {-900882000 -14400 0 ART} - {-890337600 -10800 1 ARST} - {-833749200 -14400 0 ART} - {-827265600 -10800 1 ARST} - {-752274000 -14400 0 ART} - {-733780800 -10800 1 ARST} - {-197326800 -14400 0 ART} - {-190843200 -10800 1 ARST} - {-184194000 -14400 0 ART} - {-164491200 -10800 1 ARST} - {-152658000 -14400 0 ART} - {-132955200 -10800 1 ARST} - {-121122000 -14400 0 ART} - {-101419200 -10800 1 ARST} - {-86821200 -14400 0 ART} - {-71092800 -10800 1 ARST} - {-54766800 -14400 0 ART} - {-39038400 -10800 1 ARST} - {-23317200 -14400 0 ART} - {-7588800 -10800 0 ART} - {128142000 -7200 1 ARST} - {136605600 -10800 0 ART} - {596948400 -7200 1 ARST} - {605066400 -10800 0 ART} - {624423600 -7200 1 ARST} - {636516000 -10800 0 ART} - {656478000 -7200 1 ARST} - {667965600 -10800 0 ART} - {687927600 -7200 1 ARST} - {699415200 -10800 0 ART} - {719377200 -7200 1 ARST} - {731469600 -10800 0 ART} - {938916000 -10800 0 ART} - {938919600 -10800 1 ARST} - {952056000 -10800 0 ART} - {1085886000 -14400 0 WART} - {1087704000 -10800 0 ART} - {1198983600 -7200 1 ARST} - {1205632800 -10800 0 ART} - {1224295200 -10800 0 ART} + {-1567453392 -14400 0 -04} + {-1233432000 -10800 0 -03} + {-1222981200 -14400 0 -04} + {-1205956800 -10800 1 -03} + {-1194037200 -14400 0 -04} + {-1172865600 -10800 1 -03} + {-1162501200 -14400 0 -04} + {-1141329600 -10800 1 -03} + {-1130965200 -14400 0 -04} + {-1109793600 -10800 1 -03} + {-1099429200 -14400 0 -04} + {-1078257600 -10800 1 -03} + {-1067806800 -14400 0 -04} + {-1046635200 -10800 1 -03} + {-1036270800 -14400 0 -04} + {-1015099200 -10800 1 -03} + {-1004734800 -14400 0 -04} + {-983563200 -10800 1 -03} + {-973198800 -14400 0 -04} + {-952027200 -10800 1 -03} + {-941576400 -14400 0 -04} + {-931032000 -10800 1 -03} + {-900882000 -14400 0 -04} + {-890337600 -10800 1 -03} + {-833749200 -14400 0 -04} + {-827265600 -10800 1 -03} + {-752274000 -14400 0 -04} + {-733780800 -10800 1 -03} + {-197326800 -14400 0 -04} + {-190843200 -10800 1 -03} + {-184194000 -14400 0 -04} + {-164491200 -10800 1 -03} + {-152658000 -14400 0 -04} + {-132955200 -10800 1 -03} + {-121122000 -14400 0 -04} + {-101419200 -10800 1 -03} + {-86821200 -14400 0 -04} + {-71092800 -10800 1 -03} + {-54766800 -14400 0 -04} + {-39038400 -10800 1 -03} + {-23317200 -14400 0 -04} + {-7588800 -10800 0 -03} + {128142000 -7200 1 -02} + {136605600 -10800 0 -03} + {596948400 -7200 1 -02} + {605066400 -10800 0 -03} + {624423600 -7200 1 -02} + {636516000 -10800 0 -03} + {656478000 -7200 1 -02} + {667965600 -10800 0 -03} + {687927600 -7200 1 -02} + {699415200 -10800 0 -03} + {719377200 -7200 1 -02} + {731469600 -10800 0 -03} + {938916000 -10800 0 -04} + {938919600 -10800 1 -03} + {952056000 -10800 0 -03} + {1085886000 -14400 0 -04} + {1087704000 -10800 0 -03} + {1198983600 -7200 1 -02} + {1205632800 -10800 0 -03} + {1224295200 -10800 0 -03} } diff --git a/library/tzdata/America/Asuncion b/library/tzdata/America/Asuncion index 9ea30da..606db57 100644 --- a/library/tzdata/America/Asuncion +++ b/library/tzdata/America/Asuncion @@ -3,257 +3,257 @@ set TZData(:America/Asuncion) { {-9223372036854775808 -13840 0 LMT} {-2524507760 -13840 0 AMT} - {-1206389360 -14400 0 PYT} - {86760000 -10800 0 PYT} - {134017200 -14400 0 PYT} - {162878400 -14400 0 PYT} - {181368000 -10800 1 PYST} - {194497200 -14400 0 PYT} - {212990400 -10800 1 PYST} - {226033200 -14400 0 PYT} - {244526400 -10800 1 PYST} - {257569200 -14400 0 PYT} - {276062400 -10800 1 PYST} - {291783600 -14400 0 PYT} - {307598400 -10800 1 PYST} - {323406000 -14400 0 PYT} - {339220800 -10800 1 PYST} - {354942000 -14400 0 PYT} - {370756800 -10800 1 PYST} - {386478000 -14400 0 PYT} - {402292800 -10800 1 PYST} - {418014000 -14400 0 PYT} - {433828800 -10800 1 PYST} - {449636400 -14400 0 PYT} - {465451200 -10800 1 PYST} - {481172400 -14400 0 PYT} - {496987200 -10800 1 PYST} - {512708400 -14400 0 PYT} - {528523200 -10800 1 PYST} - {544244400 -14400 0 PYT} - {560059200 -10800 1 PYST} - {575866800 -14400 0 PYT} - {591681600 -10800 1 PYST} - {607402800 -14400 0 PYT} - {625032000 -10800 1 PYST} - {638938800 -14400 0 PYT} - {654753600 -10800 1 PYST} - {670474800 -14400 0 PYT} - {686721600 -10800 1 PYST} - {699418800 -14400 0 PYT} - {718257600 -10800 1 PYST} - {733546800 -14400 0 PYT} - {749448000 -10800 1 PYST} - {762318000 -14400 0 PYT} - {780984000 -10800 1 PYST} - {793767600 -14400 0 PYT} - {812520000 -10800 1 PYST} - {825649200 -14400 0 PYT} - {844574400 -10800 1 PYST} - {856666800 -14400 0 PYT} - {876024000 -10800 1 PYST} - {888721200 -14400 0 PYT} - {907473600 -10800 1 PYST} - {920775600 -14400 0 PYT} - {938923200 -10800 1 PYST} - {952225200 -14400 0 PYT} - {970372800 -10800 1 PYST} - {983674800 -14400 0 PYT} - {1002427200 -10800 1 PYST} - {1018148400 -14400 0 PYT} - {1030852800 -10800 1 PYST} - {1049598000 -14400 0 PYT} - {1062907200 -10800 1 PYST} - {1081047600 -14400 0 PYT} - {1097985600 -10800 1 PYST} - {1110682800 -14400 0 PYT} - {1129435200 -10800 1 PYST} - {1142132400 -14400 0 PYT} - {1160884800 -10800 1 PYST} - {1173582000 -14400 0 PYT} - {1192939200 -10800 1 PYST} - {1205031600 -14400 0 PYT} - {1224388800 -10800 1 PYST} - {1236481200 -14400 0 PYT} - {1255838400 -10800 1 PYST} - {1270954800 -14400 0 PYT} - {1286078400 -10800 1 PYST} - {1302404400 -14400 0 PYT} - {1317528000 -10800 1 PYST} - {1333854000 -14400 0 PYT} - {1349582400 -10800 1 PYST} - {1364094000 -14400 0 PYT} - {1381032000 -10800 1 PYST} - {1395543600 -14400 0 PYT} - {1412481600 -10800 1 PYST} - {1426993200 -14400 0 PYT} - {1443931200 -10800 1 PYST} - {1459047600 -14400 0 PYT} - {1475380800 -10800 1 PYST} - {1490497200 -14400 0 PYT} - {1506830400 -10800 1 PYST} - {1521946800 -14400 0 PYT} - {1538884800 -10800 1 PYST} - {1553396400 -14400 0 PYT} - {1570334400 -10800 1 PYST} - {1584846000 -14400 0 PYT} - {1601784000 -10800 1 PYST} - {1616900400 -14400 0 PYT} - {1633233600 -10800 1 PYST} - {1648350000 -14400 0 PYT} - {1664683200 -10800 1 PYST} - {1679799600 -14400 0 PYT} - {1696132800 -10800 1 PYST} - {1711249200 -14400 0 PYT} - {1728187200 -10800 1 PYST} - {1742698800 -14400 0 PYT} - {1759636800 -10800 1 PYST} - {1774148400 -14400 0 PYT} - {1791086400 -10800 1 PYST} - {1806202800 -14400 0 PYT} - {1822536000 -10800 1 PYST} - {1837652400 -14400 0 PYT} - {1853985600 -10800 1 PYST} - {1869102000 -14400 0 PYT} - {1886040000 -10800 1 PYST} - {1900551600 -14400 0 PYT} - {1917489600 -10800 1 PYST} - {1932001200 -14400 0 PYT} - {1948939200 -10800 1 PYST} - {1964055600 -14400 0 PYT} - {1980388800 -10800 1 PYST} - {1995505200 -14400 0 PYT} - {2011838400 -10800 1 PYST} - {2026954800 -14400 0 PYT} - {2043288000 -10800 1 PYST} - {2058404400 -14400 0 PYT} - {2075342400 -10800 1 PYST} - {2089854000 -14400 0 PYT} - {2106792000 -10800 1 PYST} - {2121303600 -14400 0 PYT} - {2138241600 -10800 1 PYST} - {2153358000 -14400 0 PYT} - {2169691200 -10800 1 PYST} - {2184807600 -14400 0 PYT} - {2201140800 -10800 1 PYST} - {2216257200 -14400 0 PYT} - {2233195200 -10800 1 PYST} - {2247706800 -14400 0 PYT} - {2264644800 -10800 1 PYST} - {2279156400 -14400 0 PYT} - {2296094400 -10800 1 PYST} - {2310606000 -14400 0 PYT} - {2327544000 -10800 1 PYST} - {2342660400 -14400 0 PYT} - {2358993600 -10800 1 PYST} - {2374110000 -14400 0 PYT} - {2390443200 -10800 1 PYST} - {2405559600 -14400 0 PYT} - {2422497600 -10800 1 PYST} - {2437009200 -14400 0 PYT} - {2453947200 -10800 1 PYST} - {2468458800 -14400 0 PYT} - {2485396800 -10800 1 PYST} - {2500513200 -14400 0 PYT} - {2516846400 -10800 1 PYST} - {2531962800 -14400 0 PYT} - {2548296000 -10800 1 PYST} - {2563412400 -14400 0 PYT} - {2579745600 -10800 1 PYST} - {2594862000 -14400 0 PYT} - {2611800000 -10800 1 PYST} - {2626311600 -14400 0 PYT} - {2643249600 -10800 1 PYST} - {2657761200 -14400 0 PYT} - {2674699200 -10800 1 PYST} - {2689815600 -14400 0 PYT} - {2706148800 -10800 1 PYST} - {2721265200 -14400 0 PYT} - {2737598400 -10800 1 PYST} - {2752714800 -14400 0 PYT} - {2769652800 -10800 1 PYST} - {2784164400 -14400 0 PYT} - {2801102400 -10800 1 PYST} - {2815614000 -14400 0 PYT} - {2832552000 -10800 1 PYST} - {2847668400 -14400 0 PYT} - {2864001600 -10800 1 PYST} - {2879118000 -14400 0 PYT} - {2895451200 -10800 1 PYST} - {2910567600 -14400 0 PYT} - {2926900800 -10800 1 PYST} - {2942017200 -14400 0 PYT} - {2958955200 -10800 1 PYST} - {2973466800 -14400 0 PYT} - {2990404800 -10800 1 PYST} - {3004916400 -14400 0 PYT} - {3021854400 -10800 1 PYST} - {3036970800 -14400 0 PYT} - {3053304000 -10800 1 PYST} - {3068420400 -14400 0 PYT} - {3084753600 -10800 1 PYST} - {3099870000 -14400 0 PYT} - {3116808000 -10800 1 PYST} - {3131319600 -14400 0 PYT} - {3148257600 -10800 1 PYST} - {3162769200 -14400 0 PYT} - {3179707200 -10800 1 PYST} - {3194218800 -14400 0 PYT} - {3211156800 -10800 1 PYST} - {3226273200 -14400 0 PYT} - {3242606400 -10800 1 PYST} - {3257722800 -14400 0 PYT} - {3274056000 -10800 1 PYST} - {3289172400 -14400 0 PYT} - {3306110400 -10800 1 PYST} - {3320622000 -14400 0 PYT} - {3337560000 -10800 1 PYST} - {3352071600 -14400 0 PYT} - {3369009600 -10800 1 PYST} - {3384126000 -14400 0 PYT} - {3400459200 -10800 1 PYST} - {3415575600 -14400 0 PYT} - {3431908800 -10800 1 PYST} - {3447025200 -14400 0 PYT} - {3463358400 -10800 1 PYST} - {3478474800 -14400 0 PYT} - {3495412800 -10800 1 PYST} - {3509924400 -14400 0 PYT} - {3526862400 -10800 1 PYST} - {3541374000 -14400 0 PYT} - {3558312000 -10800 1 PYST} - {3573428400 -14400 0 PYT} - {3589761600 -10800 1 PYST} - {3604878000 -14400 0 PYT} - {3621211200 -10800 1 PYST} - {3636327600 -14400 0 PYT} - {3653265600 -10800 1 PYST} - {3667777200 -14400 0 PYT} - {3684715200 -10800 1 PYST} - {3699226800 -14400 0 PYT} - {3716164800 -10800 1 PYST} - {3731281200 -14400 0 PYT} - {3747614400 -10800 1 PYST} - {3762730800 -14400 0 PYT} - {3779064000 -10800 1 PYST} - {3794180400 -14400 0 PYT} - {3810513600 -10800 1 PYST} - {3825630000 -14400 0 PYT} - {3842568000 -10800 1 PYST} - {3857079600 -14400 0 PYT} - {3874017600 -10800 1 PYST} - {3888529200 -14400 0 PYT} - {3905467200 -10800 1 PYST} - {3920583600 -14400 0 PYT} - {3936916800 -10800 1 PYST} - {3952033200 -14400 0 PYT} - {3968366400 -10800 1 PYST} - {3983482800 -14400 0 PYT} - {4000420800 -10800 1 PYST} - {4014932400 -14400 0 PYT} - {4031870400 -10800 1 PYST} - {4046382000 -14400 0 PYT} - {4063320000 -10800 1 PYST} - {4077831600 -14400 0 PYT} - {4094769600 -10800 1 PYST} + {-1206389360 -14400 0 -04} + {86760000 -10800 0 -03} + {134017200 -14400 0 -04} + {162878400 -14400 0 -04} + {181368000 -10800 1 -03} + {194497200 -14400 0 -04} + {212990400 -10800 1 -03} + {226033200 -14400 0 -04} + {244526400 -10800 1 -03} + {257569200 -14400 0 -04} + {276062400 -10800 1 -03} + {291783600 -14400 0 -04} + {307598400 -10800 1 -03} + {323406000 -14400 0 -04} + {339220800 -10800 1 -03} + {354942000 -14400 0 -04} + {370756800 -10800 1 -03} + {386478000 -14400 0 -04} + {402292800 -10800 1 -03} + {418014000 -14400 0 -04} + {433828800 -10800 1 -03} + {449636400 -14400 0 -04} + {465451200 -10800 1 -03} + {481172400 -14400 0 -04} + {496987200 -10800 1 -03} + {512708400 -14400 0 -04} + {528523200 -10800 1 -03} + {544244400 -14400 0 -04} + {560059200 -10800 1 -03} + {575866800 -14400 0 -04} + {591681600 -10800 1 -03} + {607402800 -14400 0 -04} + {625032000 -10800 1 -03} + {638938800 -14400 0 -04} + {654753600 -10800 1 -03} + {670474800 -14400 0 -04} + {686721600 -10800 1 -03} + {699418800 -14400 0 -04} + {718257600 -10800 1 -03} + {733546800 -14400 0 -04} + {749448000 -10800 1 -03} + {762318000 -14400 0 -04} + {780984000 -10800 1 -03} + {793767600 -14400 0 -04} + {812520000 -10800 1 -03} + {825649200 -14400 0 -04} + {844574400 -10800 1 -03} + {856666800 -14400 0 -04} + {876024000 -10800 1 -03} + {888721200 -14400 0 -04} + {907473600 -10800 1 -03} + {920775600 -14400 0 -04} + {938923200 -10800 1 -03} + {952225200 -14400 0 -04} + {970372800 -10800 1 -03} + {983674800 -14400 0 -04} + {1002427200 -10800 1 -03} + {1018148400 -14400 0 -04} + {1030852800 -10800 1 -03} + {1049598000 -14400 0 -04} + {1062907200 -10800 1 -03} + {1081047600 -14400 0 -04} + {1097985600 -10800 1 -03} + {1110682800 -14400 0 -04} + {1129435200 -10800 1 -03} + {1142132400 -14400 0 -04} + {1160884800 -10800 1 -03} + {1173582000 -14400 0 -04} + {1192939200 -10800 1 -03} + {1205031600 -14400 0 -04} + {1224388800 -10800 1 -03} + {1236481200 -14400 0 -04} + {1255838400 -10800 1 -03} + {1270954800 -14400 0 -04} + {1286078400 -10800 1 -03} + {1302404400 -14400 0 -04} + {1317528000 -10800 1 -03} + {1333854000 -14400 0 -04} + {1349582400 -10800 1 -03} + {1364094000 -14400 0 -04} + {1381032000 -10800 1 -03} + {1395543600 -14400 0 -04} + {1412481600 -10800 1 -03} + {1426993200 -14400 0 -04} + {1443931200 -10800 1 -03} + {1459047600 -14400 0 -04} + {1475380800 -10800 1 -03} + {1490497200 -14400 0 -04} + {1506830400 -10800 1 -03} + {1521946800 -14400 0 -04} + {1538884800 -10800 1 -03} + {1553396400 -14400 0 -04} + {1570334400 -10800 1 -03} + {1584846000 -14400 0 -04} + {1601784000 -10800 1 -03} + {1616900400 -14400 0 -04} + {1633233600 -10800 1 -03} + {1648350000 -14400 0 -04} + {1664683200 -10800 1 -03} + {1679799600 -14400 0 -04} + {1696132800 -10800 1 -03} + {1711249200 -14400 0 -04} + {1728187200 -10800 1 -03} + {1742698800 -14400 0 -04} + {1759636800 -10800 1 -03} + {1774148400 -14400 0 -04} + {1791086400 -10800 1 -03} + {1806202800 -14400 0 -04} + {1822536000 -10800 1 -03} + {1837652400 -14400 0 -04} + {1853985600 -10800 1 -03} + {1869102000 -14400 0 -04} + {1886040000 -10800 1 -03} + {1900551600 -14400 0 -04} + {1917489600 -10800 1 -03} + {1932001200 -14400 0 -04} + {1948939200 -10800 1 -03} + {1964055600 -14400 0 -04} + {1980388800 -10800 1 -03} + {1995505200 -14400 0 -04} + {2011838400 -10800 1 -03} + {2026954800 -14400 0 -04} + {2043288000 -10800 1 -03} + {2058404400 -14400 0 -04} + {2075342400 -10800 1 -03} + {2089854000 -14400 0 -04} + {2106792000 -10800 1 -03} + {2121303600 -14400 0 -04} + {2138241600 -10800 1 -03} + {2153358000 -14400 0 -04} + {2169691200 -10800 1 -03} + {2184807600 -14400 0 -04} + {2201140800 -10800 1 -03} + {2216257200 -14400 0 -04} + {2233195200 -10800 1 -03} + {2247706800 -14400 0 -04} + {2264644800 -10800 1 -03} + {2279156400 -14400 0 -04} + {2296094400 -10800 1 -03} + {2310606000 -14400 0 -04} + {2327544000 -10800 1 -03} + {2342660400 -14400 0 -04} + {2358993600 -10800 1 -03} + {2374110000 -14400 0 -04} + {2390443200 -10800 1 -03} + {2405559600 -14400 0 -04} + {2422497600 -10800 1 -03} + {2437009200 -14400 0 -04} + {2453947200 -10800 1 -03} + {2468458800 -14400 0 -04} + {2485396800 -10800 1 -03} + {2500513200 -14400 0 -04} + {2516846400 -10800 1 -03} + {2531962800 -14400 0 -04} + {2548296000 -10800 1 -03} + {2563412400 -14400 0 -04} + {2579745600 -10800 1 -03} + {2594862000 -14400 0 -04} + {2611800000 -10800 1 -03} + {2626311600 -14400 0 -04} + {2643249600 -10800 1 -03} + {2657761200 -14400 0 -04} + {2674699200 -10800 1 -03} + {2689815600 -14400 0 -04} + {2706148800 -10800 1 -03} + {2721265200 -14400 0 -04} + {2737598400 -10800 1 -03} + {2752714800 -14400 0 -04} + {2769652800 -10800 1 -03} + {2784164400 -14400 0 -04} + {2801102400 -10800 1 -03} + {2815614000 -14400 0 -04} + {2832552000 -10800 1 -03} + {2847668400 -14400 0 -04} + {2864001600 -10800 1 -03} + {2879118000 -14400 0 -04} + {2895451200 -10800 1 -03} + {2910567600 -14400 0 -04} + {2926900800 -10800 1 -03} + {2942017200 -14400 0 -04} + {2958955200 -10800 1 -03} + {2973466800 -14400 0 -04} + {2990404800 -10800 1 -03} + {3004916400 -14400 0 -04} + {3021854400 -10800 1 -03} + {3036970800 -14400 0 -04} + {3053304000 -10800 1 -03} + {3068420400 -14400 0 -04} + {3084753600 -10800 1 -03} + {3099870000 -14400 0 -04} + {3116808000 -10800 1 -03} + {3131319600 -14400 0 -04} + {3148257600 -10800 1 -03} + {3162769200 -14400 0 -04} + {3179707200 -10800 1 -03} + {3194218800 -14400 0 -04} + {3211156800 -10800 1 -03} + {3226273200 -14400 0 -04} + {3242606400 -10800 1 -03} + {3257722800 -14400 0 -04} + {3274056000 -10800 1 -03} + {3289172400 -14400 0 -04} + {3306110400 -10800 1 -03} + {3320622000 -14400 0 -04} + {3337560000 -10800 1 -03} + {3352071600 -14400 0 -04} + {3369009600 -10800 1 -03} + {3384126000 -14400 0 -04} + {3400459200 -10800 1 -03} + {3415575600 -14400 0 -04} + {3431908800 -10800 1 -03} + {3447025200 -14400 0 -04} + {3463358400 -10800 1 -03} + {3478474800 -14400 0 -04} + {3495412800 -10800 1 -03} + {3509924400 -14400 0 -04} + {3526862400 -10800 1 -03} + {3541374000 -14400 0 -04} + {3558312000 -10800 1 -03} + {3573428400 -14400 0 -04} + {3589761600 -10800 1 -03} + {3604878000 -14400 0 -04} + {3621211200 -10800 1 -03} + {3636327600 -14400 0 -04} + {3653265600 -10800 1 -03} + {3667777200 -14400 0 -04} + {3684715200 -10800 1 -03} + {3699226800 -14400 0 -04} + {3716164800 -10800 1 -03} + {3731281200 -14400 0 -04} + {3747614400 -10800 1 -03} + {3762730800 -14400 0 -04} + {3779064000 -10800 1 -03} + {3794180400 -14400 0 -04} + {3810513600 -10800 1 -03} + {3825630000 -14400 0 -04} + {3842568000 -10800 1 -03} + {3857079600 -14400 0 -04} + {3874017600 -10800 1 -03} + {3888529200 -14400 0 -04} + {3905467200 -10800 1 -03} + {3920583600 -14400 0 -04} + {3936916800 -10800 1 -03} + {3952033200 -14400 0 -04} + {3968366400 -10800 1 -03} + {3983482800 -14400 0 -04} + {4000420800 -10800 1 -03} + {4014932400 -14400 0 -04} + {4031870400 -10800 1 -03} + {4046382000 -14400 0 -04} + {4063320000 -10800 1 -03} + {4077831600 -14400 0 -04} + {4094769600 -10800 1 -03} } diff --git a/library/tzdata/America/Bahia b/library/tzdata/America/Bahia index ac67b71..7dbcb90 100644 --- a/library/tzdata/America/Bahia +++ b/library/tzdata/America/Bahia @@ -2,67 +2,67 @@ set TZData(:America/Bahia) { {-9223372036854775808 -9244 0 LMT} - {-1767216356 -10800 0 BRT} - {-1206957600 -7200 1 BRST} - {-1191362400 -10800 0 BRT} - {-1175374800 -7200 1 BRST} - {-1159826400 -10800 0 BRT} - {-633819600 -7200 1 BRST} - {-622069200 -10800 0 BRT} - {-602283600 -7200 1 BRST} - {-591832800 -10800 0 BRT} - {-570747600 -7200 1 BRST} - {-560210400 -10800 0 BRT} - {-539125200 -7200 1 BRST} - {-531352800 -10800 0 BRT} - {-191365200 -7200 1 BRST} - {-184197600 -10800 0 BRT} - {-155163600 -7200 1 BRST} - {-150069600 -10800 0 BRT} - {-128898000 -7200 1 BRST} - {-121125600 -10800 0 BRT} - {-99954000 -7200 1 BRST} - {-89589600 -10800 0 BRT} - {-68418000 -7200 1 BRST} - {-57967200 -10800 0 BRT} - {499748400 -7200 1 BRST} - {511236000 -10800 0 BRT} - {530593200 -7200 1 BRST} - {540266400 -10800 0 BRT} - {562129200 -7200 1 BRST} - {571197600 -10800 0 BRT} - {592974000 -7200 1 BRST} - {602042400 -10800 0 BRT} - {624423600 -7200 1 BRST} - {634701600 -10800 0 BRT} - {656478000 -7200 1 BRST} - {666756000 -10800 0 BRT} - {687927600 -7200 1 BRST} - {697600800 -10800 0 BRT} - {719982000 -7200 1 BRST} - {728445600 -10800 0 BRT} - {750826800 -7200 1 BRST} - {761709600 -10800 0 BRT} - {782276400 -7200 1 BRST} - {793159200 -10800 0 BRT} - {813726000 -7200 1 BRST} - {824004000 -10800 0 BRT} - {844570800 -7200 1 BRST} - {856058400 -10800 0 BRT} - {876106800 -7200 1 BRST} - {888717600 -10800 0 BRT} - {908074800 -7200 1 BRST} - {919562400 -10800 0 BRT} - {938919600 -7200 1 BRST} - {951616800 -10800 0 BRT} - {970974000 -7200 1 BRST} - {982461600 -10800 0 BRT} - {1003028400 -7200 1 BRST} - {1013911200 -10800 0 BRT} - {1036292400 -7200 1 BRST} - {1045360800 -10800 0 BRT} - {1064368800 -10800 0 BRT} - {1318734000 -7200 0 BRST} - {1330221600 -10800 0 BRT} - {1350784800 -10800 0 BRT} + {-1767216356 -10800 0 -03} + {-1206957600 -7200 1 -02} + {-1191362400 -10800 0 -03} + {-1175374800 -7200 1 -02} + {-1159826400 -10800 0 -03} + {-633819600 -7200 1 -02} + {-622069200 -10800 0 -03} + {-602283600 -7200 1 -02} + {-591832800 -10800 0 -03} + {-570747600 -7200 1 -02} + {-560210400 -10800 0 -03} + {-539125200 -7200 1 -02} + {-531352800 -10800 0 -03} + {-191365200 -7200 1 -02} + {-184197600 -10800 0 -03} + {-155163600 -7200 1 -02} + {-150069600 -10800 0 -03} + {-128898000 -7200 1 -02} + {-121125600 -10800 0 -03} + {-99954000 -7200 1 -02} + {-89589600 -10800 0 -03} + {-68418000 -7200 1 -02} + {-57967200 -10800 0 -03} + {499748400 -7200 1 -02} + {511236000 -10800 0 -03} + {530593200 -7200 1 -02} + {540266400 -10800 0 -03} + {562129200 -7200 1 -02} + {571197600 -10800 0 -03} + {592974000 -7200 1 -02} + {602042400 -10800 0 -03} + {624423600 -7200 1 -02} + {634701600 -10800 0 -03} + {656478000 -7200 1 -02} + {666756000 -10800 0 -03} + {687927600 -7200 1 -02} + {697600800 -10800 0 -03} + {719982000 -7200 1 -02} + {728445600 -10800 0 -03} + {750826800 -7200 1 -02} + {761709600 -10800 0 -03} + {782276400 -7200 1 -02} + {793159200 -10800 0 -03} + {813726000 -7200 1 -02} + {824004000 -10800 0 -03} + {844570800 -7200 1 -02} + {856058400 -10800 0 -03} + {876106800 -7200 1 -02} + {888717600 -10800 0 -03} + {908074800 -7200 1 -02} + {919562400 -10800 0 -03} + {938919600 -7200 1 -02} + {951616800 -10800 0 -03} + {970974000 -7200 1 -02} + {982461600 -10800 0 -03} + {1003028400 -7200 1 -02} + {1013911200 -10800 0 -03} + {1036292400 -7200 1 -02} + {1045360800 -10800 0 -03} + {1064368800 -10800 0 -03} + {1318734000 -7200 0 -02} + {1330221600 -10800 0 -03} + {1350784800 -10800 0 -03} } diff --git a/library/tzdata/America/Belem b/library/tzdata/America/Belem index ed92fd1..b2bf3a6 100644 --- a/library/tzdata/America/Belem +++ b/library/tzdata/America/Belem @@ -2,34 +2,34 @@ set TZData(:America/Belem) { {-9223372036854775808 -11636 0 LMT} - {-1767213964 -10800 0 BRT} - {-1206957600 -7200 1 BRST} - {-1191362400 -10800 0 BRT} - {-1175374800 -7200 1 BRST} - {-1159826400 -10800 0 BRT} - {-633819600 -7200 1 BRST} - {-622069200 -10800 0 BRT} - {-602283600 -7200 1 BRST} - {-591832800 -10800 0 BRT} - {-570747600 -7200 1 BRST} - {-560210400 -10800 0 BRT} - {-539125200 -7200 1 BRST} - {-531352800 -10800 0 BRT} - {-191365200 -7200 1 BRST} - {-184197600 -10800 0 BRT} - {-155163600 -7200 1 BRST} - {-150069600 -10800 0 BRT} - {-128898000 -7200 1 BRST} - {-121125600 -10800 0 BRT} - {-99954000 -7200 1 BRST} - {-89589600 -10800 0 BRT} - {-68418000 -7200 1 BRST} - {-57967200 -10800 0 BRT} - {499748400 -7200 1 BRST} - {511236000 -10800 0 BRT} - {530593200 -7200 1 BRST} - {540266400 -10800 0 BRT} - {562129200 -7200 1 BRST} - {571197600 -10800 0 BRT} - {590032800 -10800 0 BRT} + {-1767213964 -10800 0 -03} + {-1206957600 -7200 1 -02} + {-1191362400 -10800 0 -03} + {-1175374800 -7200 1 -02} + {-1159826400 -10800 0 -03} + {-633819600 -7200 1 -02} + {-622069200 -10800 0 -03} + {-602283600 -7200 1 -02} + {-591832800 -10800 0 -03} + {-570747600 -7200 1 -02} + {-560210400 -10800 0 -03} + {-539125200 -7200 1 -02} + {-531352800 -10800 0 -03} + {-191365200 -7200 1 -02} + {-184197600 -10800 0 -03} + {-155163600 -7200 1 -02} + {-150069600 -10800 0 -03} + {-128898000 -7200 1 -02} + {-121125600 -10800 0 -03} + {-99954000 -7200 1 -02} + {-89589600 -10800 0 -03} + {-68418000 -7200 1 -02} + {-57967200 -10800 0 -03} + {499748400 -7200 1 -02} + {511236000 -10800 0 -03} + {530593200 -7200 1 -02} + {540266400 -10800 0 -03} + {562129200 -7200 1 -02} + {571197600 -10800 0 -03} + {590032800 -10800 0 -03} } diff --git a/library/tzdata/America/Belize b/library/tzdata/America/Belize index 547fd72..5b46388 100644 --- a/library/tzdata/America/Belize +++ b/library/tzdata/America/Belize @@ -3,55 +3,55 @@ set TZData(:America/Belize) { {-9223372036854775808 -21168 0 LMT} {-1822500432 -21600 0 CST} - {-1616954400 -19800 1 CHDT} + {-1616954400 -19800 1 -0530} {-1606069800 -21600 0 CST} - {-1585504800 -19800 1 CHDT} + {-1585504800 -19800 1 -0530} {-1574015400 -21600 0 CST} - {-1554055200 -19800 1 CHDT} + {-1554055200 -19800 1 -0530} {-1542565800 -21600 0 CST} - {-1522605600 -19800 1 CHDT} + {-1522605600 -19800 1 -0530} {-1511116200 -21600 0 CST} - {-1490551200 -19800 1 CHDT} + {-1490551200 -19800 1 -0530} {-1479666600 -21600 0 CST} - {-1459101600 -19800 1 CHDT} + {-1459101600 -19800 1 -0530} {-1448217000 -21600 0 CST} - {-1427652000 -19800 1 CHDT} + {-1427652000 -19800 1 -0530} {-1416162600 -21600 0 CST} - {-1396202400 -19800 1 CHDT} + {-1396202400 -19800 1 -0530} {-1384713000 -21600 0 CST} - {-1364752800 -19800 1 CHDT} + {-1364752800 -19800 1 -0530} {-1353263400 -21600 0 CST} - {-1333303200 -19800 1 CHDT} + {-1333303200 -19800 1 -0530} {-1321813800 -21600 0 CST} - {-1301248800 -19800 1 CHDT} + {-1301248800 -19800 1 -0530} {-1290364200 -21600 0 CST} - {-1269799200 -19800 1 CHDT} + {-1269799200 -19800 1 -0530} {-1258914600 -21600 0 CST} - {-1238349600 -19800 1 CHDT} + {-1238349600 -19800 1 -0530} {-1226860200 -21600 0 CST} - {-1206900000 -19800 1 CHDT} + {-1206900000 -19800 1 -0530} {-1195410600 -21600 0 CST} - {-1175450400 -19800 1 CHDT} + {-1175450400 -19800 1 -0530} {-1163961000 -21600 0 CST} - {-1143396000 -19800 1 CHDT} + {-1143396000 -19800 1 -0530} {-1132511400 -21600 0 CST} - {-1111946400 -19800 1 CHDT} + {-1111946400 -19800 1 -0530} {-1101061800 -21600 0 CST} - {-1080496800 -19800 1 CHDT} + {-1080496800 -19800 1 -0530} {-1069612200 -21600 0 CST} - {-1049047200 -19800 1 CHDT} + {-1049047200 -19800 1 -0530} {-1037557800 -21600 0 CST} - {-1017597600 -19800 1 CHDT} + {-1017597600 -19800 1 -0530} {-1006108200 -21600 0 CST} - {-986148000 -19800 1 CHDT} + {-986148000 -19800 1 -0530} {-974658600 -21600 0 CST} - {-954093600 -19800 1 CHDT} + {-954093600 -19800 1 -0530} {-943209000 -21600 0 CST} - {-922644000 -19800 1 CHDT} + {-922644000 -19800 1 -0530} {-911759400 -21600 0 CST} - {-891194400 -19800 1 CHDT} + {-891194400 -19800 1 -0530} {-879705000 -21600 0 CST} - {-859744800 -19800 1 CHDT} + {-859744800 -19800 1 -0530} {-848255400 -21600 0 CST} {123919200 -18000 1 CDT} {129618000 -21600 0 CST} diff --git a/library/tzdata/America/Boa_Vista b/library/tzdata/America/Boa_Vista index c85bc27..982249b 100644 --- a/library/tzdata/America/Boa_Vista +++ b/library/tzdata/America/Boa_Vista @@ -2,39 +2,39 @@ set TZData(:America/Boa_Vista) { {-9223372036854775808 -14560 0 LMT} - {-1767211040 -14400 0 AMT} - {-1206954000 -10800 1 AMST} - {-1191358800 -14400 0 AMT} - {-1175371200 -10800 1 AMST} - {-1159822800 -14400 0 AMT} - {-633816000 -10800 1 AMST} - {-622065600 -14400 0 AMT} - {-602280000 -10800 1 AMST} - {-591829200 -14400 0 AMT} - {-570744000 -10800 1 AMST} - {-560206800 -14400 0 AMT} - {-539121600 -10800 1 AMST} - {-531349200 -14400 0 AMT} - {-191361600 -10800 1 AMST} - {-184194000 -14400 0 AMT} - {-155160000 -10800 1 AMST} - {-150066000 -14400 0 AMT} - {-128894400 -10800 1 AMST} - {-121122000 -14400 0 AMT} - {-99950400 -10800 1 AMST} - {-89586000 -14400 0 AMT} - {-68414400 -10800 1 AMST} - {-57963600 -14400 0 AMT} - {499752000 -10800 1 AMST} - {511239600 -14400 0 AMT} - {530596800 -10800 1 AMST} - {540270000 -14400 0 AMT} - {562132800 -10800 1 AMST} - {571201200 -14400 0 AMT} - {590036400 -14400 0 AMT} - {938664000 -14400 0 AMT} - {938923200 -10800 1 AMST} - {951620400 -14400 0 AMT} - {970977600 -10800 1 AMST} - {971578800 -14400 0 AMT} + {-1767211040 -14400 0 -04} + {-1206954000 -10800 1 -03} + {-1191358800 -14400 0 -04} + {-1175371200 -10800 1 -03} + {-1159822800 -14400 0 -04} + {-633816000 -10800 1 -03} + {-622065600 -14400 0 -04} + {-602280000 -10800 1 -03} + {-591829200 -14400 0 -04} + {-570744000 -10800 1 -03} + {-560206800 -14400 0 -04} + {-539121600 -10800 1 -03} + {-531349200 -14400 0 -04} + {-191361600 -10800 1 -03} + {-184194000 -14400 0 -04} + {-155160000 -10800 1 -03} + {-150066000 -14400 0 -04} + {-128894400 -10800 1 -03} + {-121122000 -14400 0 -04} + {-99950400 -10800 1 -03} + {-89586000 -14400 0 -04} + {-68414400 -10800 1 -03} + {-57963600 -14400 0 -04} + {499752000 -10800 1 -03} + {511239600 -14400 0 -04} + {530596800 -10800 1 -03} + {540270000 -14400 0 -04} + {562132800 -10800 1 -03} + {571201200 -14400 0 -04} + {590036400 -14400 0 -04} + {938664000 -14400 0 -04} + {938923200 -10800 1 -03} + {951620400 -14400 0 -04} + {970977600 -10800 1 -03} + {971578800 -14400 0 -04} } diff --git a/library/tzdata/America/Bogota b/library/tzdata/America/Bogota index b28abc1..69e4557 100644 --- a/library/tzdata/America/Bogota +++ b/library/tzdata/America/Bogota @@ -3,7 +3,7 @@ set TZData(:America/Bogota) { {-9223372036854775808 -17776 0 LMT} {-2707671824 -17776 0 BMT} - {-1739041424 -18000 0 COT} - {704869200 -14400 1 COST} - {733896000 -18000 0 COT} + {-1739041424 -18000 0 -05} + {704869200 -14400 1 -04} + {733896000 -18000 0 -05} } diff --git a/library/tzdata/America/Campo_Grande b/library/tzdata/America/Campo_Grande index 2cafe14..77cb4d1 100644 --- a/library/tzdata/America/Campo_Grande +++ b/library/tzdata/America/Campo_Grande @@ -2,256 +2,256 @@ set TZData(:America/Campo_Grande) { {-9223372036854775808 -13108 0 LMT} - {-1767212492 -14400 0 AMT} - {-1206954000 -10800 1 AMST} - {-1191358800 -14400 0 AMT} - {-1175371200 -10800 1 AMST} - {-1159822800 -14400 0 AMT} - {-633816000 -10800 1 AMST} - {-622065600 -14400 0 AMT} - {-602280000 -10800 1 AMST} - {-591829200 -14400 0 AMT} - {-570744000 -10800 1 AMST} - {-560206800 -14400 0 AMT} - {-539121600 -10800 1 AMST} - {-531349200 -14400 0 AMT} - {-191361600 -10800 1 AMST} - {-184194000 -14400 0 AMT} - {-155160000 -10800 1 AMST} - {-150066000 -14400 0 AMT} - {-128894400 -10800 1 AMST} - {-121122000 -14400 0 AMT} - {-99950400 -10800 1 AMST} - {-89586000 -14400 0 AMT} - {-68414400 -10800 1 AMST} - {-57963600 -14400 0 AMT} - {499752000 -10800 1 AMST} - {511239600 -14400 0 AMT} - {530596800 -10800 1 AMST} - {540270000 -14400 0 AMT} - {562132800 -10800 1 AMST} - {571201200 -14400 0 AMT} - {592977600 -10800 1 AMST} - {602046000 -14400 0 AMT} - {624427200 -10800 1 AMST} - {634705200 -14400 0 AMT} - {656481600 -10800 1 AMST} - {666759600 -14400 0 AMT} - {687931200 -10800 1 AMST} - {697604400 -14400 0 AMT} - {719985600 -10800 1 AMST} - {728449200 -14400 0 AMT} - {750830400 -10800 1 AMST} - {761713200 -14400 0 AMT} - {782280000 -10800 1 AMST} - {793162800 -14400 0 AMT} - {813729600 -10800 1 AMST} - {824007600 -14400 0 AMT} - {844574400 -10800 1 AMST} - {856062000 -14400 0 AMT} - {876110400 -10800 1 AMST} - {888721200 -14400 0 AMT} - {908078400 -10800 1 AMST} - {919566000 -14400 0 AMT} - {938923200 -10800 1 AMST} - {951620400 -14400 0 AMT} - {970977600 -10800 1 AMST} - {982465200 -14400 0 AMT} - {1003032000 -10800 1 AMST} - {1013914800 -14400 0 AMT} - {1036296000 -10800 1 AMST} - {1045364400 -14400 0 AMT} - {1066536000 -10800 1 AMST} - {1076814000 -14400 0 AMT} - {1099368000 -10800 1 AMST} - {1108868400 -14400 0 AMT} - {1129435200 -10800 1 AMST} - {1140318000 -14400 0 AMT} - {1162699200 -10800 1 AMST} - {1172372400 -14400 0 AMT} - {1192334400 -10800 1 AMST} - {1203217200 -14400 0 AMT} - {1224388800 -10800 1 AMST} - {1234666800 -14400 0 AMT} - {1255838400 -10800 1 AMST} - {1266721200 -14400 0 AMT} - {1287288000 -10800 1 AMST} - {1298170800 -14400 0 AMT} - {1318737600 -10800 1 AMST} - {1330225200 -14400 0 AMT} - {1350792000 -10800 1 AMST} - {1361070000 -14400 0 AMT} - {1382241600 -10800 1 AMST} - {1392519600 -14400 0 AMT} - {1413691200 -10800 1 AMST} - {1424574000 -14400 0 AMT} - {1445140800 -10800 1 AMST} - {1456023600 -14400 0 AMT} - {1476590400 -10800 1 AMST} - {1487473200 -14400 0 AMT} - {1508040000 -10800 1 AMST} - {1518922800 -14400 0 AMT} - {1540094400 -10800 1 AMST} - {1550372400 -14400 0 AMT} - {1571544000 -10800 1 AMST} - {1581822000 -14400 0 AMT} - {1602993600 -10800 1 AMST} - {1613876400 -14400 0 AMT} - {1634443200 -10800 1 AMST} - {1645326000 -14400 0 AMT} - {1665892800 -10800 1 AMST} - {1677380400 -14400 0 AMT} - {1697342400 -10800 1 AMST} - {1708225200 -14400 0 AMT} - {1729396800 -10800 1 AMST} - {1739674800 -14400 0 AMT} - {1760846400 -10800 1 AMST} - {1771729200 -14400 0 AMT} - {1792296000 -10800 1 AMST} - {1803178800 -14400 0 AMT} - {1823745600 -10800 1 AMST} - {1834628400 -14400 0 AMT} - {1855195200 -10800 1 AMST} - {1866078000 -14400 0 AMT} - {1887249600 -10800 1 AMST} - {1897527600 -14400 0 AMT} - {1918699200 -10800 1 AMST} - {1928977200 -14400 0 AMT} - {1950148800 -10800 1 AMST} - {1960426800 -14400 0 AMT} - {1981598400 -10800 1 AMST} - {1992481200 -14400 0 AMT} - {2013048000 -10800 1 AMST} - {2024535600 -14400 0 AMT} - {2044497600 -10800 1 AMST} - {2055380400 -14400 0 AMT} - {2076552000 -10800 1 AMST} - {2086830000 -14400 0 AMT} - {2108001600 -10800 1 AMST} - {2118884400 -14400 0 AMT} - {2139451200 -10800 1 AMST} - {2150334000 -14400 0 AMT} - {2170900800 -10800 1 AMST} - {2181783600 -14400 0 AMT} - {2202350400 -10800 1 AMST} - {2213233200 -14400 0 AMT} - {2234404800 -10800 1 AMST} - {2244682800 -14400 0 AMT} - {2265854400 -10800 1 AMST} - {2276132400 -14400 0 AMT} - {2297304000 -10800 1 AMST} - {2307582000 -14400 0 AMT} - {2328753600 -10800 1 AMST} - {2339636400 -14400 0 AMT} - {2360203200 -10800 1 AMST} - {2371086000 -14400 0 AMT} - {2391652800 -10800 1 AMST} - {2402535600 -14400 0 AMT} - {2423707200 -10800 1 AMST} - {2433985200 -14400 0 AMT} - {2455156800 -10800 1 AMST} - {2465434800 -14400 0 AMT} - {2486606400 -10800 1 AMST} - {2497489200 -14400 0 AMT} - {2518056000 -10800 1 AMST} - {2528938800 -14400 0 AMT} - {2549505600 -10800 1 AMST} - {2560388400 -14400 0 AMT} - {2580955200 -10800 1 AMST} - {2591838000 -14400 0 AMT} - {2613009600 -10800 1 AMST} - {2623287600 -14400 0 AMT} - {2644459200 -10800 1 AMST} - {2654737200 -14400 0 AMT} - {2675908800 -10800 1 AMST} - {2686791600 -14400 0 AMT} - {2707358400 -10800 1 AMST} - {2718241200 -14400 0 AMT} - {2738808000 -10800 1 AMST} - {2749690800 -14400 0 AMT} - {2770862400 -10800 1 AMST} - {2781140400 -14400 0 AMT} - {2802312000 -10800 1 AMST} - {2812590000 -14400 0 AMT} - {2833761600 -10800 1 AMST} - {2844039600 -14400 0 AMT} - {2865211200 -10800 1 AMST} - {2876094000 -14400 0 AMT} - {2896660800 -10800 1 AMST} - {2907543600 -14400 0 AMT} - {2928110400 -10800 1 AMST} - {2938993200 -14400 0 AMT} - {2960164800 -10800 1 AMST} - {2970442800 -14400 0 AMT} - {2991614400 -10800 1 AMST} - {3001892400 -14400 0 AMT} - {3023064000 -10800 1 AMST} - {3033946800 -14400 0 AMT} - {3054513600 -10800 1 AMST} - {3065396400 -14400 0 AMT} - {3085963200 -10800 1 AMST} - {3096846000 -14400 0 AMT} - {3118017600 -10800 1 AMST} - {3128295600 -14400 0 AMT} - {3149467200 -10800 1 AMST} - {3159745200 -14400 0 AMT} - {3180916800 -10800 1 AMST} - {3191194800 -14400 0 AMT} - {3212366400 -10800 1 AMST} - {3223249200 -14400 0 AMT} - {3243816000 -10800 1 AMST} - {3254698800 -14400 0 AMT} - {3275265600 -10800 1 AMST} - {3286148400 -14400 0 AMT} - {3307320000 -10800 1 AMST} - {3317598000 -14400 0 AMT} - {3338769600 -10800 1 AMST} - {3349047600 -14400 0 AMT} - {3370219200 -10800 1 AMST} - {3381102000 -14400 0 AMT} - {3401668800 -10800 1 AMST} - {3412551600 -14400 0 AMT} - {3433118400 -10800 1 AMST} - {3444001200 -14400 0 AMT} - {3464568000 -10800 1 AMST} - {3475450800 -14400 0 AMT} - {3496622400 -10800 1 AMST} - {3506900400 -14400 0 AMT} - {3528072000 -10800 1 AMST} - {3538350000 -14400 0 AMT} - {3559521600 -10800 1 AMST} - {3570404400 -14400 0 AMT} - {3590971200 -10800 1 AMST} - {3601854000 -14400 0 AMT} - {3622420800 -10800 1 AMST} - {3633303600 -14400 0 AMT} - {3654475200 -10800 1 AMST} - {3664753200 -14400 0 AMT} - {3685924800 -10800 1 AMST} - {3696202800 -14400 0 AMT} - {3717374400 -10800 1 AMST} - {3727652400 -14400 0 AMT} - {3748824000 -10800 1 AMST} - {3759706800 -14400 0 AMT} - {3780273600 -10800 1 AMST} - {3791156400 -14400 0 AMT} - {3811723200 -10800 1 AMST} - {3822606000 -14400 0 AMT} - {3843777600 -10800 1 AMST} - {3854055600 -14400 0 AMT} - {3875227200 -10800 1 AMST} - {3885505200 -14400 0 AMT} - {3906676800 -10800 1 AMST} - {3917559600 -14400 0 AMT} - {3938126400 -10800 1 AMST} - {3949009200 -14400 0 AMT} - {3969576000 -10800 1 AMST} - {3980458800 -14400 0 AMT} - {4001630400 -10800 1 AMST} - {4011908400 -14400 0 AMT} - {4033080000 -10800 1 AMST} - {4043358000 -14400 0 AMT} - {4064529600 -10800 1 AMST} - {4074807600 -14400 0 AMT} - {4095979200 -10800 1 AMST} + {-1767212492 -14400 0 -04} + {-1206954000 -10800 1 -03} + {-1191358800 -14400 0 -04} + {-1175371200 -10800 1 -03} + {-1159822800 -14400 0 -04} + {-633816000 -10800 1 -03} + {-622065600 -14400 0 -04} + {-602280000 -10800 1 -03} + {-591829200 -14400 0 -04} + {-570744000 -10800 1 -03} + {-560206800 -14400 0 -04} + {-539121600 -10800 1 -03} + {-531349200 -14400 0 -04} + {-191361600 -10800 1 -03} + {-184194000 -14400 0 -04} + {-155160000 -10800 1 -03} + {-150066000 -14400 0 -04} + {-128894400 -10800 1 -03} + {-121122000 -14400 0 -04} + {-99950400 -10800 1 -03} + {-89586000 -14400 0 -04} + {-68414400 -10800 1 -03} + {-57963600 -14400 0 -04} + {499752000 -10800 1 -03} + {511239600 -14400 0 -04} + {530596800 -10800 1 -03} + {540270000 -14400 0 -04} + {562132800 -10800 1 -03} + {571201200 -14400 0 -04} + {592977600 -10800 1 -03} + {602046000 -14400 0 -04} + {624427200 -10800 1 -03} + {634705200 -14400 0 -04} + {656481600 -10800 1 -03} + {666759600 -14400 0 -04} + {687931200 -10800 1 -03} + {697604400 -14400 0 -04} + {719985600 -10800 1 -03} + {728449200 -14400 0 -04} + {750830400 -10800 1 -03} + {761713200 -14400 0 -04} + {782280000 -10800 1 -03} + {793162800 -14400 0 -04} + {813729600 -10800 1 -03} + {824007600 -14400 0 -04} + {844574400 -10800 1 -03} + {856062000 -14400 0 -04} + {876110400 -10800 1 -03} + {888721200 -14400 0 -04} + {908078400 -10800 1 -03} + {919566000 -14400 0 -04} + {938923200 -10800 1 -03} + {951620400 -14400 0 -04} + {970977600 -10800 1 -03} + {982465200 -14400 0 -04} + {1003032000 -10800 1 -03} + {1013914800 -14400 0 -04} + {1036296000 -10800 1 -03} + {1045364400 -14400 0 -04} + {1066536000 -10800 1 -03} + {1076814000 -14400 0 -04} + {1099368000 -10800 1 -03} + {1108868400 -14400 0 -04} + {1129435200 -10800 1 -03} + {1140318000 -14400 0 -04} + {1162699200 -10800 1 -03} + {1172372400 -14400 0 -04} + {1192334400 -10800 1 -03} + {1203217200 -14400 0 -04} + {1224388800 -10800 1 -03} + {1234666800 -14400 0 -04} + {1255838400 -10800 1 -03} + {1266721200 -14400 0 -04} + {1287288000 -10800 1 -03} + {1298170800 -14400 0 -04} + {1318737600 -10800 1 -03} + {1330225200 -14400 0 -04} + {1350792000 -10800 1 -03} + {1361070000 -14400 0 -04} + {1382241600 -10800 1 -03} + {1392519600 -14400 0 -04} + {1413691200 -10800 1 -03} + {1424574000 -14400 0 -04} + {1445140800 -10800 1 -03} + {1456023600 -14400 0 -04} + {1476590400 -10800 1 -03} + {1487473200 -14400 0 -04} + {1508040000 -10800 1 -03} + {1518922800 -14400 0 -04} + {1540094400 -10800 1 -03} + {1550372400 -14400 0 -04} + {1571544000 -10800 1 -03} + {1581822000 -14400 0 -04} + {1602993600 -10800 1 -03} + {1613876400 -14400 0 -04} + {1634443200 -10800 1 -03} + {1645326000 -14400 0 -04} + {1665892800 -10800 1 -03} + {1677380400 -14400 0 -04} + {1697342400 -10800 1 -03} + {1708225200 -14400 0 -04} + {1729396800 -10800 1 -03} + {1739674800 -14400 0 -04} + {1760846400 -10800 1 -03} + {1771729200 -14400 0 -04} + {1792296000 -10800 1 -03} + {1803178800 -14400 0 -04} + {1823745600 -10800 1 -03} + {1834628400 -14400 0 -04} + {1855195200 -10800 1 -03} + {1866078000 -14400 0 -04} + {1887249600 -10800 1 -03} + {1897527600 -14400 0 -04} + {1918699200 -10800 1 -03} + {1928977200 -14400 0 -04} + {1950148800 -10800 1 -03} + {1960426800 -14400 0 -04} + {1981598400 -10800 1 -03} + {1992481200 -14400 0 -04} + {2013048000 -10800 1 -03} + {2024535600 -14400 0 -04} + {2044497600 -10800 1 -03} + {2055380400 -14400 0 -04} + {2076552000 -10800 1 -03} + {2086830000 -14400 0 -04} + {2108001600 -10800 1 -03} + {2118884400 -14400 0 -04} + {2139451200 -10800 1 -03} + {2150334000 -14400 0 -04} + {2170900800 -10800 1 -03} + {2181783600 -14400 0 -04} + {2202350400 -10800 1 -03} + {2213233200 -14400 0 -04} + {2234404800 -10800 1 -03} + {2244682800 -14400 0 -04} + {2265854400 -10800 1 -03} + {2276132400 -14400 0 -04} + {2297304000 -10800 1 -03} + {2307582000 -14400 0 -04} + {2328753600 -10800 1 -03} + {2339636400 -14400 0 -04} + {2360203200 -10800 1 -03} + {2371086000 -14400 0 -04} + {2391652800 -10800 1 -03} + {2402535600 -14400 0 -04} + {2423707200 -10800 1 -03} + {2433985200 -14400 0 -04} + {2455156800 -10800 1 -03} + {2465434800 -14400 0 -04} + {2486606400 -10800 1 -03} + {2497489200 -14400 0 -04} + {2518056000 -10800 1 -03} + {2528938800 -14400 0 -04} + {2549505600 -10800 1 -03} + {2560388400 -14400 0 -04} + {2580955200 -10800 1 -03} + {2591838000 -14400 0 -04} + {2613009600 -10800 1 -03} + {2623287600 -14400 0 -04} + {2644459200 -10800 1 -03} + {2654737200 -14400 0 -04} + {2675908800 -10800 1 -03} + {2686791600 -14400 0 -04} + {2707358400 -10800 1 -03} + {2718241200 -14400 0 -04} + {2738808000 -10800 1 -03} + {2749690800 -14400 0 -04} + {2770862400 -10800 1 -03} + {2781140400 -14400 0 -04} + {2802312000 -10800 1 -03} + {2812590000 -14400 0 -04} + {2833761600 -10800 1 -03} + {2844039600 -14400 0 -04} + {2865211200 -10800 1 -03} + {2876094000 -14400 0 -04} + {2896660800 -10800 1 -03} + {2907543600 -14400 0 -04} + {2928110400 -10800 1 -03} + {2938993200 -14400 0 -04} + {2960164800 -10800 1 -03} + {2970442800 -14400 0 -04} + {2991614400 -10800 1 -03} + {3001892400 -14400 0 -04} + {3023064000 -10800 1 -03} + {3033946800 -14400 0 -04} + {3054513600 -10800 1 -03} + {3065396400 -14400 0 -04} + {3085963200 -10800 1 -03} + {3096846000 -14400 0 -04} + {3118017600 -10800 1 -03} + {3128295600 -14400 0 -04} + {3149467200 -10800 1 -03} + {3159745200 -14400 0 -04} + {3180916800 -10800 1 -03} + {3191194800 -14400 0 -04} + {3212366400 -10800 1 -03} + {3223249200 -14400 0 -04} + {3243816000 -10800 1 -03} + {3254698800 -14400 0 -04} + {3275265600 -10800 1 -03} + {3286148400 -14400 0 -04} + {3307320000 -10800 1 -03} + {3317598000 -14400 0 -04} + {3338769600 -10800 1 -03} + {3349047600 -14400 0 -04} + {3370219200 -10800 1 -03} + {3381102000 -14400 0 -04} + {3401668800 -10800 1 -03} + {3412551600 -14400 0 -04} + {3433118400 -10800 1 -03} + {3444001200 -14400 0 -04} + {3464568000 -10800 1 -03} + {3475450800 -14400 0 -04} + {3496622400 -10800 1 -03} + {3506900400 -14400 0 -04} + {3528072000 -10800 1 -03} + {3538350000 -14400 0 -04} + {3559521600 -10800 1 -03} + {3570404400 -14400 0 -04} + {3590971200 -10800 1 -03} + {3601854000 -14400 0 -04} + {3622420800 -10800 1 -03} + {3633303600 -14400 0 -04} + {3654475200 -10800 1 -03} + {3664753200 -14400 0 -04} + {3685924800 -10800 1 -03} + {3696202800 -14400 0 -04} + {3717374400 -10800 1 -03} + {3727652400 -14400 0 -04} + {3748824000 -10800 1 -03} + {3759706800 -14400 0 -04} + {3780273600 -10800 1 -03} + {3791156400 -14400 0 -04} + {3811723200 -10800 1 -03} + {3822606000 -14400 0 -04} + {3843777600 -10800 1 -03} + {3854055600 -14400 0 -04} + {3875227200 -10800 1 -03} + {3885505200 -14400 0 -04} + {3906676800 -10800 1 -03} + {3917559600 -14400 0 -04} + {3938126400 -10800 1 -03} + {3949009200 -14400 0 -04} + {3969576000 -10800 1 -03} + {3980458800 -14400 0 -04} + {4001630400 -10800 1 -03} + {4011908400 -14400 0 -04} + {4033080000 -10800 1 -03} + {4043358000 -14400 0 -04} + {4064529600 -10800 1 -03} + {4074807600 -14400 0 -04} + {4095979200 -10800 1 -03} } diff --git a/library/tzdata/America/Caracas b/library/tzdata/America/Caracas index 253c4ce..f0dbffe 100644 --- a/library/tzdata/America/Caracas +++ b/library/tzdata/America/Caracas @@ -3,8 +3,8 @@ set TZData(:America/Caracas) { {-9223372036854775808 -16064 0 LMT} {-2524505536 -16060 0 CMT} - {-1826739140 -16200 0 VET} - {-157750200 -14400 0 VET} - {1197183600 -16200 0 VET} - {1462086000 -14400 0 VET} + {-1826739140 -16200 0 -0430} + {-157750200 -14400 0 -04} + {1197183600 -16200 0 -0430} + {1462086000 -14400 0 -04} } diff --git a/library/tzdata/America/Cayenne b/library/tzdata/America/Cayenne index de3d65b..6b1a3e9 100644 --- a/library/tzdata/America/Cayenne +++ b/library/tzdata/America/Cayenne @@ -2,6 +2,6 @@ set TZData(:America/Cayenne) { {-9223372036854775808 -12560 0 LMT} - {-1846269040 -14400 0 GFT} - {-71092800 -10800 0 GFT} + {-1846269040 -14400 0 -04} + {-71092800 -10800 0 -03} } diff --git a/library/tzdata/America/Cuiaba b/library/tzdata/America/Cuiaba index 0301862..57cd38c 100644 --- a/library/tzdata/America/Cuiaba +++ b/library/tzdata/America/Cuiaba @@ -2,256 +2,256 @@ set TZData(:America/Cuiaba) { {-9223372036854775808 -13460 0 LMT} - {-1767212140 -14400 0 AMT} - {-1206954000 -10800 1 AMST} - {-1191358800 -14400 0 AMT} - {-1175371200 -10800 1 AMST} - {-1159822800 -14400 0 AMT} - {-633816000 -10800 1 AMST} - {-622065600 -14400 0 AMT} - {-602280000 -10800 1 AMST} - {-591829200 -14400 0 AMT} - {-570744000 -10800 1 AMST} - {-560206800 -14400 0 AMT} - {-539121600 -10800 1 AMST} - {-531349200 -14400 0 AMT} - {-191361600 -10800 1 AMST} - {-184194000 -14400 0 AMT} - {-155160000 -10800 1 AMST} - {-150066000 -14400 0 AMT} - {-128894400 -10800 1 AMST} - {-121122000 -14400 0 AMT} - {-99950400 -10800 1 AMST} - {-89586000 -14400 0 AMT} - {-68414400 -10800 1 AMST} - {-57963600 -14400 0 AMT} - {499752000 -10800 1 AMST} - {511239600 -14400 0 AMT} - {530596800 -10800 1 AMST} - {540270000 -14400 0 AMT} - {562132800 -10800 1 AMST} - {571201200 -14400 0 AMT} - {592977600 -10800 1 AMST} - {602046000 -14400 0 AMT} - {624427200 -10800 1 AMST} - {634705200 -14400 0 AMT} - {656481600 -10800 1 AMST} - {666759600 -14400 0 AMT} - {687931200 -10800 1 AMST} - {697604400 -14400 0 AMT} - {719985600 -10800 1 AMST} - {728449200 -14400 0 AMT} - {750830400 -10800 1 AMST} - {761713200 -14400 0 AMT} - {782280000 -10800 1 AMST} - {793162800 -14400 0 AMT} - {813729600 -10800 1 AMST} - {824007600 -14400 0 AMT} - {844574400 -10800 1 AMST} - {856062000 -14400 0 AMT} - {876110400 -10800 1 AMST} - {888721200 -14400 0 AMT} - {908078400 -10800 1 AMST} - {919566000 -14400 0 AMT} - {938923200 -10800 1 AMST} - {951620400 -14400 0 AMT} - {970977600 -10800 1 AMST} - {982465200 -14400 0 AMT} - {1003032000 -10800 1 AMST} - {1013914800 -14400 0 AMT} - {1036296000 -10800 1 AMST} - {1045364400 -14400 0 AMT} - {1064372400 -14400 0 AMT} - {1096603200 -14400 0 AMT} - {1099368000 -10800 1 AMST} - {1108868400 -14400 0 AMT} - {1129435200 -10800 1 AMST} - {1140318000 -14400 0 AMT} - {1162699200 -10800 1 AMST} - {1172372400 -14400 0 AMT} - {1192334400 -10800 1 AMST} - {1203217200 -14400 0 AMT} - {1224388800 -10800 1 AMST} - {1234666800 -14400 0 AMT} - {1255838400 -10800 1 AMST} - {1266721200 -14400 0 AMT} - {1287288000 -10800 1 AMST} - {1298170800 -14400 0 AMT} - {1318737600 -10800 1 AMST} - {1330225200 -14400 0 AMT} - {1350792000 -10800 1 AMST} - {1361070000 -14400 0 AMT} - {1382241600 -10800 1 AMST} - {1392519600 -14400 0 AMT} - {1413691200 -10800 1 AMST} - {1424574000 -14400 0 AMT} - {1445140800 -10800 1 AMST} - {1456023600 -14400 0 AMT} - {1476590400 -10800 1 AMST} - {1487473200 -14400 0 AMT} - {1508040000 -10800 1 AMST} - {1518922800 -14400 0 AMT} - {1540094400 -10800 1 AMST} - {1550372400 -14400 0 AMT} - {1571544000 -10800 1 AMST} - {1581822000 -14400 0 AMT} - {1602993600 -10800 1 AMST} - {1613876400 -14400 0 AMT} - {1634443200 -10800 1 AMST} - {1645326000 -14400 0 AMT} - {1665892800 -10800 1 AMST} - {1677380400 -14400 0 AMT} - {1697342400 -10800 1 AMST} - {1708225200 -14400 0 AMT} - {1729396800 -10800 1 AMST} - {1739674800 -14400 0 AMT} - {1760846400 -10800 1 AMST} - {1771729200 -14400 0 AMT} - {1792296000 -10800 1 AMST} - {1803178800 -14400 0 AMT} - {1823745600 -10800 1 AMST} - {1834628400 -14400 0 AMT} - {1855195200 -10800 1 AMST} - {1866078000 -14400 0 AMT} - {1887249600 -10800 1 AMST} - {1897527600 -14400 0 AMT} - {1918699200 -10800 1 AMST} - {1928977200 -14400 0 AMT} - {1950148800 -10800 1 AMST} - {1960426800 -14400 0 AMT} - {1981598400 -10800 1 AMST} - {1992481200 -14400 0 AMT} - {2013048000 -10800 1 AMST} - {2024535600 -14400 0 AMT} - {2044497600 -10800 1 AMST} - {2055380400 -14400 0 AMT} - {2076552000 -10800 1 AMST} - {2086830000 -14400 0 AMT} - {2108001600 -10800 1 AMST} - {2118884400 -14400 0 AMT} - {2139451200 -10800 1 AMST} - {2150334000 -14400 0 AMT} - {2170900800 -10800 1 AMST} - {2181783600 -14400 0 AMT} - {2202350400 -10800 1 AMST} - {2213233200 -14400 0 AMT} - {2234404800 -10800 1 AMST} - {2244682800 -14400 0 AMT} - {2265854400 -10800 1 AMST} - {2276132400 -14400 0 AMT} - {2297304000 -10800 1 AMST} - {2307582000 -14400 0 AMT} - {2328753600 -10800 1 AMST} - {2339636400 -14400 0 AMT} - {2360203200 -10800 1 AMST} - {2371086000 -14400 0 AMT} - {2391652800 -10800 1 AMST} - {2402535600 -14400 0 AMT} - {2423707200 -10800 1 AMST} - {2433985200 -14400 0 AMT} - {2455156800 -10800 1 AMST} - {2465434800 -14400 0 AMT} - {2486606400 -10800 1 AMST} - {2497489200 -14400 0 AMT} - {2518056000 -10800 1 AMST} - {2528938800 -14400 0 AMT} - {2549505600 -10800 1 AMST} - {2560388400 -14400 0 AMT} - {2580955200 -10800 1 AMST} - {2591838000 -14400 0 AMT} - {2613009600 -10800 1 AMST} - {2623287600 -14400 0 AMT} - {2644459200 -10800 1 AMST} - {2654737200 -14400 0 AMT} - {2675908800 -10800 1 AMST} - {2686791600 -14400 0 AMT} - {2707358400 -10800 1 AMST} - {2718241200 -14400 0 AMT} - {2738808000 -10800 1 AMST} - {2749690800 -14400 0 AMT} - {2770862400 -10800 1 AMST} - {2781140400 -14400 0 AMT} - {2802312000 -10800 1 AMST} - {2812590000 -14400 0 AMT} - {2833761600 -10800 1 AMST} - {2844039600 -14400 0 AMT} - {2865211200 -10800 1 AMST} - {2876094000 -14400 0 AMT} - {2896660800 -10800 1 AMST} - {2907543600 -14400 0 AMT} - {2928110400 -10800 1 AMST} - {2938993200 -14400 0 AMT} - {2960164800 -10800 1 AMST} - {2970442800 -14400 0 AMT} - {2991614400 -10800 1 AMST} - {3001892400 -14400 0 AMT} - {3023064000 -10800 1 AMST} - {3033946800 -14400 0 AMT} - {3054513600 -10800 1 AMST} - {3065396400 -14400 0 AMT} - {3085963200 -10800 1 AMST} - {3096846000 -14400 0 AMT} - {3118017600 -10800 1 AMST} - {3128295600 -14400 0 AMT} - {3149467200 -10800 1 AMST} - {3159745200 -14400 0 AMT} - {3180916800 -10800 1 AMST} - {3191194800 -14400 0 AMT} - {3212366400 -10800 1 AMST} - {3223249200 -14400 0 AMT} - {3243816000 -10800 1 AMST} - {3254698800 -14400 0 AMT} - {3275265600 -10800 1 AMST} - {3286148400 -14400 0 AMT} - {3307320000 -10800 1 AMST} - {3317598000 -14400 0 AMT} - {3338769600 -10800 1 AMST} - {3349047600 -14400 0 AMT} - {3370219200 -10800 1 AMST} - {3381102000 -14400 0 AMT} - {3401668800 -10800 1 AMST} - {3412551600 -14400 0 AMT} - {3433118400 -10800 1 AMST} - {3444001200 -14400 0 AMT} - {3464568000 -10800 1 AMST} - {3475450800 -14400 0 AMT} - {3496622400 -10800 1 AMST} - {3506900400 -14400 0 AMT} - {3528072000 -10800 1 AMST} - {3538350000 -14400 0 AMT} - {3559521600 -10800 1 AMST} - {3570404400 -14400 0 AMT} - {3590971200 -10800 1 AMST} - {3601854000 -14400 0 AMT} - {3622420800 -10800 1 AMST} - {3633303600 -14400 0 AMT} - {3654475200 -10800 1 AMST} - {3664753200 -14400 0 AMT} - {3685924800 -10800 1 AMST} - {3696202800 -14400 0 AMT} - {3717374400 -10800 1 AMST} - {3727652400 -14400 0 AMT} - {3748824000 -10800 1 AMST} - {3759706800 -14400 0 AMT} - {3780273600 -10800 1 AMST} - {3791156400 -14400 0 AMT} - {3811723200 -10800 1 AMST} - {3822606000 -14400 0 AMT} - {3843777600 -10800 1 AMST} - {3854055600 -14400 0 AMT} - {3875227200 -10800 1 AMST} - {3885505200 -14400 0 AMT} - {3906676800 -10800 1 AMST} - {3917559600 -14400 0 AMT} - {3938126400 -10800 1 AMST} - {3949009200 -14400 0 AMT} - {3969576000 -10800 1 AMST} - {3980458800 -14400 0 AMT} - {4001630400 -10800 1 AMST} - {4011908400 -14400 0 AMT} - {4033080000 -10800 1 AMST} - {4043358000 -14400 0 AMT} - {4064529600 -10800 1 AMST} - {4074807600 -14400 0 AMT} - {4095979200 -10800 1 AMST} + {-1767212140 -14400 0 -04} + {-1206954000 -10800 1 -03} + {-1191358800 -14400 0 -04} + {-1175371200 -10800 1 -03} + {-1159822800 -14400 0 -04} + {-633816000 -10800 1 -03} + {-622065600 -14400 0 -04} + {-602280000 -10800 1 -03} + {-591829200 -14400 0 -04} + {-570744000 -10800 1 -03} + {-560206800 -14400 0 -04} + {-539121600 -10800 1 -03} + {-531349200 -14400 0 -04} + {-191361600 -10800 1 -03} + {-184194000 -14400 0 -04} + {-155160000 -10800 1 -03} + {-150066000 -14400 0 -04} + {-128894400 -10800 1 -03} + {-121122000 -14400 0 -04} + {-99950400 -10800 1 -03} + {-89586000 -14400 0 -04} + {-68414400 -10800 1 -03} + {-57963600 -14400 0 -04} + {499752000 -10800 1 -03} + {511239600 -14400 0 -04} + {530596800 -10800 1 -03} + {540270000 -14400 0 -04} + {562132800 -10800 1 -03} + {571201200 -14400 0 -04} + {592977600 -10800 1 -03} + {602046000 -14400 0 -04} + {624427200 -10800 1 -03} + {634705200 -14400 0 -04} + {656481600 -10800 1 -03} + {666759600 -14400 0 -04} + {687931200 -10800 1 -03} + {697604400 -14400 0 -04} + {719985600 -10800 1 -03} + {728449200 -14400 0 -04} + {750830400 -10800 1 -03} + {761713200 -14400 0 -04} + {782280000 -10800 1 -03} + {793162800 -14400 0 -04} + {813729600 -10800 1 -03} + {824007600 -14400 0 -04} + {844574400 -10800 1 -03} + {856062000 -14400 0 -04} + {876110400 -10800 1 -03} + {888721200 -14400 0 -04} + {908078400 -10800 1 -03} + {919566000 -14400 0 -04} + {938923200 -10800 1 -03} + {951620400 -14400 0 -04} + {970977600 -10800 1 -03} + {982465200 -14400 0 -04} + {1003032000 -10800 1 -03} + {1013914800 -14400 0 -04} + {1036296000 -10800 1 -03} + {1045364400 -14400 0 -04} + {1064372400 -14400 0 -04} + {1096603200 -14400 0 -04} + {1099368000 -10800 1 -03} + {1108868400 -14400 0 -04} + {1129435200 -10800 1 -03} + {1140318000 -14400 0 -04} + {1162699200 -10800 1 -03} + {1172372400 -14400 0 -04} + {1192334400 -10800 1 -03} + {1203217200 -14400 0 -04} + {1224388800 -10800 1 -03} + {1234666800 -14400 0 -04} + {1255838400 -10800 1 -03} + {1266721200 -14400 0 -04} + {1287288000 -10800 1 -03} + {1298170800 -14400 0 -04} + {1318737600 -10800 1 -03} + {1330225200 -14400 0 -04} + {1350792000 -10800 1 -03} + {1361070000 -14400 0 -04} + {1382241600 -10800 1 -03} + {1392519600 -14400 0 -04} + {1413691200 -10800 1 -03} + {1424574000 -14400 0 -04} + {1445140800 -10800 1 -03} + {1456023600 -14400 0 -04} + {1476590400 -10800 1 -03} + {1487473200 -14400 0 -04} + {1508040000 -10800 1 -03} + {1518922800 -14400 0 -04} + {1540094400 -10800 1 -03} + {1550372400 -14400 0 -04} + {1571544000 -10800 1 -03} + {1581822000 -14400 0 -04} + {1602993600 -10800 1 -03} + {1613876400 -14400 0 -04} + {1634443200 -10800 1 -03} + {1645326000 -14400 0 -04} + {1665892800 -10800 1 -03} + {1677380400 -14400 0 -04} + {1697342400 -10800 1 -03} + {1708225200 -14400 0 -04} + {1729396800 -10800 1 -03} + {1739674800 -14400 0 -04} + {1760846400 -10800 1 -03} + {1771729200 -14400 0 -04} + {1792296000 -10800 1 -03} + {1803178800 -14400 0 -04} + {1823745600 -10800 1 -03} + {1834628400 -14400 0 -04} + {1855195200 -10800 1 -03} + {1866078000 -14400 0 -04} + {1887249600 -10800 1 -03} + {1897527600 -14400 0 -04} + {1918699200 -10800 1 -03} + {1928977200 -14400 0 -04} + {1950148800 -10800 1 -03} + {1960426800 -14400 0 -04} + {1981598400 -10800 1 -03} + {1992481200 -14400 0 -04} + {2013048000 -10800 1 -03} + {2024535600 -14400 0 -04} + {2044497600 -10800 1 -03} + {2055380400 -14400 0 -04} + {2076552000 -10800 1 -03} + {2086830000 -14400 0 -04} + {2108001600 -10800 1 -03} + {2118884400 -14400 0 -04} + {2139451200 -10800 1 -03} + {2150334000 -14400 0 -04} + {2170900800 -10800 1 -03} + {2181783600 -14400 0 -04} + {2202350400 -10800 1 -03} + {2213233200 -14400 0 -04} + {2234404800 -10800 1 -03} + {2244682800 -14400 0 -04} + {2265854400 -10800 1 -03} + {2276132400 -14400 0 -04} + {2297304000 -10800 1 -03} + {2307582000 -14400 0 -04} + {2328753600 -10800 1 -03} + {2339636400 -14400 0 -04} + {2360203200 -10800 1 -03} + {2371086000 -14400 0 -04} + {2391652800 -10800 1 -03} + {2402535600 -14400 0 -04} + {2423707200 -10800 1 -03} + {2433985200 -14400 0 -04} + {2455156800 -10800 1 -03} + {2465434800 -14400 0 -04} + {2486606400 -10800 1 -03} + {2497489200 -14400 0 -04} + {2518056000 -10800 1 -03} + {2528938800 -14400 0 -04} + {2549505600 -10800 1 -03} + {2560388400 -14400 0 -04} + {2580955200 -10800 1 -03} + {2591838000 -14400 0 -04} + {2613009600 -10800 1 -03} + {2623287600 -14400 0 -04} + {2644459200 -10800 1 -03} + {2654737200 -14400 0 -04} + {2675908800 -10800 1 -03} + {2686791600 -14400 0 -04} + {2707358400 -10800 1 -03} + {2718241200 -14400 0 -04} + {2738808000 -10800 1 -03} + {2749690800 -14400 0 -04} + {2770862400 -10800 1 -03} + {2781140400 -14400 0 -04} + {2802312000 -10800 1 -03} + {2812590000 -14400 0 -04} + {2833761600 -10800 1 -03} + {2844039600 -14400 0 -04} + {2865211200 -10800 1 -03} + {2876094000 -14400 0 -04} + {2896660800 -10800 1 -03} + {2907543600 -14400 0 -04} + {2928110400 -10800 1 -03} + {2938993200 -14400 0 -04} + {2960164800 -10800 1 -03} + {2970442800 -14400 0 -04} + {2991614400 -10800 1 -03} + {3001892400 -14400 0 -04} + {3023064000 -10800 1 -03} + {3033946800 -14400 0 -04} + {3054513600 -10800 1 -03} + {3065396400 -14400 0 -04} + {3085963200 -10800 1 -03} + {3096846000 -14400 0 -04} + {3118017600 -10800 1 -03} + {3128295600 -14400 0 -04} + {3149467200 -10800 1 -03} + {3159745200 -14400 0 -04} + {3180916800 -10800 1 -03} + {3191194800 -14400 0 -04} + {3212366400 -10800 1 -03} + {3223249200 -14400 0 -04} + {3243816000 -10800 1 -03} + {3254698800 -14400 0 -04} + {3275265600 -10800 1 -03} + {3286148400 -14400 0 -04} + {3307320000 -10800 1 -03} + {3317598000 -14400 0 -04} + {3338769600 -10800 1 -03} + {3349047600 -14400 0 -04} + {3370219200 -10800 1 -03} + {3381102000 -14400 0 -04} + {3401668800 -10800 1 -03} + {3412551600 -14400 0 -04} + {3433118400 -10800 1 -03} + {3444001200 -14400 0 -04} + {3464568000 -10800 1 -03} + {3475450800 -14400 0 -04} + {3496622400 -10800 1 -03} + {3506900400 -14400 0 -04} + {3528072000 -10800 1 -03} + {3538350000 -14400 0 -04} + {3559521600 -10800 1 -03} + {3570404400 -14400 0 -04} + {3590971200 -10800 1 -03} + {3601854000 -14400 0 -04} + {3622420800 -10800 1 -03} + {3633303600 -14400 0 -04} + {3654475200 -10800 1 -03} + {3664753200 -14400 0 -04} + {3685924800 -10800 1 -03} + {3696202800 -14400 0 -04} + {3717374400 -10800 1 -03} + {3727652400 -14400 0 -04} + {3748824000 -10800 1 -03} + {3759706800 -14400 0 -04} + {3780273600 -10800 1 -03} + {3791156400 -14400 0 -04} + {3811723200 -10800 1 -03} + {3822606000 -14400 0 -04} + {3843777600 -10800 1 -03} + {3854055600 -14400 0 -04} + {3875227200 -10800 1 -03} + {3885505200 -14400 0 -04} + {3906676800 -10800 1 -03} + {3917559600 -14400 0 -04} + {3938126400 -10800 1 -03} + {3949009200 -14400 0 -04} + {3969576000 -10800 1 -03} + {3980458800 -14400 0 -04} + {4001630400 -10800 1 -03} + {4011908400 -14400 0 -04} + {4033080000 -10800 1 -03} + {4043358000 -14400 0 -04} + {4064529600 -10800 1 -03} + {4074807600 -14400 0 -04} + {4095979200 -10800 1 -03} } diff --git a/library/tzdata/America/Curacao b/library/tzdata/America/Curacao index 5189e9c..0a19090 100644 --- a/library/tzdata/America/Curacao +++ b/library/tzdata/America/Curacao @@ -2,6 +2,6 @@ set TZData(:America/Curacao) { {-9223372036854775808 -16547 0 LMT} - {-1826738653 -16200 0 ANT} + {-1826738653 -16200 0 -0430} {-157750200 -14400 0 AST} } diff --git a/library/tzdata/America/Danmarkshavn b/library/tzdata/America/Danmarkshavn index 8d66d3a..4d9d7bb 100644 --- a/library/tzdata/America/Danmarkshavn +++ b/library/tzdata/America/Danmarkshavn @@ -2,38 +2,38 @@ set TZData(:America/Danmarkshavn) { {-9223372036854775808 -4480 0 LMT} - {-1686091520 -10800 0 WGT} - {323845200 -7200 0 WGST} - {338950800 -10800 0 WGT} - {354675600 -7200 1 WGST} - {370400400 -10800 0 WGT} - {386125200 -7200 1 WGST} - {401850000 -10800 0 WGT} - {417574800 -7200 1 WGST} - {433299600 -10800 0 WGT} - {449024400 -7200 1 WGST} - {465354000 -10800 0 WGT} - {481078800 -7200 1 WGST} - {496803600 -10800 0 WGT} - {512528400 -7200 1 WGST} - {528253200 -10800 0 WGT} - {543978000 -7200 1 WGST} - {559702800 -10800 0 WGT} - {575427600 -7200 1 WGST} - {591152400 -10800 0 WGT} - {606877200 -7200 1 WGST} - {622602000 -10800 0 WGT} - {638326800 -7200 1 WGST} - {654656400 -10800 0 WGT} - {670381200 -7200 1 WGST} - {686106000 -10800 0 WGT} - {701830800 -7200 1 WGST} - {717555600 -10800 0 WGT} - {733280400 -7200 1 WGST} - {749005200 -10800 0 WGT} - {764730000 -7200 1 WGST} - {780454800 -10800 0 WGT} - {796179600 -7200 1 WGST} - {811904400 -10800 0 WGT} + {-1686091520 -10800 0 -03} + {323845200 -7200 0 -02} + {338950800 -10800 0 -03} + {354675600 -7200 1 -02} + {370400400 -10800 0 -03} + {386125200 -7200 1 -02} + {401850000 -10800 0 -03} + {417574800 -7200 1 -02} + {433299600 -10800 0 -03} + {449024400 -7200 1 -02} + {465354000 -10800 0 -03} + {481078800 -7200 1 -02} + {496803600 -10800 0 -03} + {512528400 -7200 1 -02} + {528253200 -10800 0 -03} + {543978000 -7200 1 -02} + {559702800 -10800 0 -03} + {575427600 -7200 1 -02} + {591152400 -10800 0 -03} + {606877200 -7200 1 -02} + {622602000 -10800 0 -03} + {638326800 -7200 1 -02} + {654656400 -10800 0 -03} + {670381200 -7200 1 -02} + {686106000 -10800 0 -03} + {701830800 -7200 1 -02} + {717555600 -10800 0 -03} + {733280400 -7200 1 -02} + {749005200 -10800 0 -03} + {764730000 -7200 1 -02} + {780454800 -10800 0 -03} + {796179600 -7200 1 -02} + {811904400 -10800 0 -03} {820465200 0 0 GMT} } diff --git a/library/tzdata/America/Eirunepe b/library/tzdata/America/Eirunepe index a05631f..41b4cc9 100644 --- a/library/tzdata/America/Eirunepe +++ b/library/tzdata/America/Eirunepe @@ -2,40 +2,40 @@ set TZData(:America/Eirunepe) { {-9223372036854775808 -16768 0 LMT} - {-1767208832 -18000 0 ACT} - {-1206950400 -14400 1 ACST} - {-1191355200 -18000 0 ACT} - {-1175367600 -14400 1 ACST} - {-1159819200 -18000 0 ACT} - {-633812400 -14400 1 ACST} - {-622062000 -18000 0 ACT} - {-602276400 -14400 1 ACST} - {-591825600 -18000 0 ACT} - {-570740400 -14400 1 ACST} - {-560203200 -18000 0 ACT} - {-539118000 -14400 1 ACST} - {-531345600 -18000 0 ACT} - {-191358000 -14400 1 ACST} - {-184190400 -18000 0 ACT} - {-155156400 -14400 1 ACST} - {-150062400 -18000 0 ACT} - {-128890800 -14400 1 ACST} - {-121118400 -18000 0 ACT} - {-99946800 -14400 1 ACST} - {-89582400 -18000 0 ACT} - {-68410800 -14400 1 ACST} - {-57960000 -18000 0 ACT} - {499755600 -14400 1 ACST} - {511243200 -18000 0 ACT} - {530600400 -14400 1 ACST} - {540273600 -18000 0 ACT} - {562136400 -14400 1 ACST} - {571204800 -18000 0 ACT} - {590040000 -18000 0 ACT} - {749192400 -18000 0 ACT} - {750834000 -14400 1 ACST} - {761716800 -18000 0 ACT} - {780206400 -18000 0 ACT} - {1214283600 -14400 0 AMT} - {1384056000 -18000 0 ACT} + {-1767208832 -18000 0 -05} + {-1206950400 -14400 1 -04} + {-1191355200 -18000 0 -05} + {-1175367600 -14400 1 -04} + {-1159819200 -18000 0 -05} + {-633812400 -14400 1 -04} + {-622062000 -18000 0 -05} + {-602276400 -14400 1 -04} + {-591825600 -18000 0 -05} + {-570740400 -14400 1 -04} + {-560203200 -18000 0 -05} + {-539118000 -14400 1 -04} + {-531345600 -18000 0 -05} + {-191358000 -14400 1 -04} + {-184190400 -18000 0 -05} + {-155156400 -14400 1 -04} + {-150062400 -18000 0 -05} + {-128890800 -14400 1 -04} + {-121118400 -18000 0 -05} + {-99946800 -14400 1 -04} + {-89582400 -18000 0 -05} + {-68410800 -14400 1 -04} + {-57960000 -18000 0 -05} + {499755600 -14400 1 -04} + {511243200 -18000 0 -05} + {530600400 -14400 1 -04} + {540273600 -18000 0 -05} + {562136400 -14400 1 -04} + {571204800 -18000 0 -05} + {590040000 -18000 0 -05} + {749192400 -18000 0 -05} + {750834000 -14400 1 -04} + {761716800 -18000 0 -05} + {780206400 -18000 0 -05} + {1214283600 -14400 0 -04} + {1384056000 -18000 0 -05} } diff --git a/library/tzdata/America/Fortaleza b/library/tzdata/America/Fortaleza index 581faa5..06c7b84 100644 --- a/library/tzdata/America/Fortaleza +++ b/library/tzdata/America/Fortaleza @@ -2,47 +2,47 @@ set TZData(:America/Fortaleza) { {-9223372036854775808 -9240 0 LMT} - {-1767216360 -10800 0 BRT} - {-1206957600 -7200 1 BRST} - {-1191362400 -10800 0 BRT} - {-1175374800 -7200 1 BRST} - {-1159826400 -10800 0 BRT} - {-633819600 -7200 1 BRST} - {-622069200 -10800 0 BRT} - {-602283600 -7200 1 BRST} - {-591832800 -10800 0 BRT} - {-570747600 -7200 1 BRST} - {-560210400 -10800 0 BRT} - {-539125200 -7200 1 BRST} - {-531352800 -10800 0 BRT} - {-191365200 -7200 1 BRST} - {-184197600 -10800 0 BRT} - {-155163600 -7200 1 BRST} - {-150069600 -10800 0 BRT} - {-128898000 -7200 1 BRST} - {-121125600 -10800 0 BRT} - {-99954000 -7200 1 BRST} - {-89589600 -10800 0 BRT} - {-68418000 -7200 1 BRST} - {-57967200 -10800 0 BRT} - {499748400 -7200 1 BRST} - {511236000 -10800 0 BRT} - {530593200 -7200 1 BRST} - {540266400 -10800 0 BRT} - {562129200 -7200 1 BRST} - {571197600 -10800 0 BRT} - {592974000 -7200 1 BRST} - {602042400 -10800 0 BRT} - {624423600 -7200 1 BRST} - {634701600 -10800 0 BRT} - {653536800 -10800 0 BRT} - {938660400 -10800 0 BRT} - {938919600 -7200 1 BRST} - {951616800 -10800 0 BRT} - {970974000 -7200 1 BRST} - {972180000 -10800 0 BRT} - {1000350000 -10800 0 BRT} - {1003028400 -7200 1 BRST} - {1013911200 -10800 0 BRT} - {1033437600 -10800 0 BRT} + {-1767216360 -10800 0 -03} + {-1206957600 -7200 1 -02} + {-1191362400 -10800 0 -03} + {-1175374800 -7200 1 -02} + {-1159826400 -10800 0 -03} + {-633819600 -7200 1 -02} + {-622069200 -10800 0 -03} + {-602283600 -7200 1 -02} + {-591832800 -10800 0 -03} + {-570747600 -7200 1 -02} + {-560210400 -10800 0 -03} + {-539125200 -7200 1 -02} + {-531352800 -10800 0 -03} + {-191365200 -7200 1 -02} + {-184197600 -10800 0 -03} + {-155163600 -7200 1 -02} + {-150069600 -10800 0 -03} + {-128898000 -7200 1 -02} + {-121125600 -10800 0 -03} + {-99954000 -7200 1 -02} + {-89589600 -10800 0 -03} + {-68418000 -7200 1 -02} + {-57967200 -10800 0 -03} + {499748400 -7200 1 -02} + {511236000 -10800 0 -03} + {530593200 -7200 1 -02} + {540266400 -10800 0 -03} + {562129200 -7200 1 -02} + {571197600 -10800 0 -03} + {592974000 -7200 1 -02} + {602042400 -10800 0 -03} + {624423600 -7200 1 -02} + {634701600 -10800 0 -03} + {653536800 -10800 0 -03} + {938660400 -10800 0 -03} + {938919600 -7200 1 -02} + {951616800 -10800 0 -03} + {970974000 -7200 1 -02} + {972180000 -10800 0 -03} + {1000350000 -10800 0 -03} + {1003028400 -7200 1 -02} + {1013911200 -10800 0 -03} + {1033437600 -10800 0 -03} } diff --git a/library/tzdata/America/Godthab b/library/tzdata/America/Godthab index 3c003cc..3e45f87 100644 --- a/library/tzdata/America/Godthab +++ b/library/tzdata/America/Godthab @@ -2,245 +2,245 @@ set TZData(:America/Godthab) { {-9223372036854775808 -12416 0 LMT} - {-1686083584 -10800 0 WGT} - {323845200 -7200 0 WGST} - {338950800 -10800 0 WGT} - {354675600 -7200 1 WGST} - {370400400 -10800 0 WGT} - {386125200 -7200 1 WGST} - {401850000 -10800 0 WGT} - {417574800 -7200 1 WGST} - {433299600 -10800 0 WGT} - {449024400 -7200 1 WGST} - {465354000 -10800 0 WGT} - {481078800 -7200 1 WGST} - {496803600 -10800 0 WGT} - {512528400 -7200 1 WGST} - {528253200 -10800 0 WGT} - {543978000 -7200 1 WGST} - {559702800 -10800 0 WGT} - {575427600 -7200 1 WGST} - {591152400 -10800 0 WGT} - {606877200 -7200 1 WGST} - {622602000 -10800 0 WGT} - {638326800 -7200 1 WGST} - {654656400 -10800 0 WGT} - {670381200 -7200 1 WGST} - {686106000 -10800 0 WGT} - {701830800 -7200 1 WGST} - {717555600 -10800 0 WGT} - {733280400 -7200 1 WGST} - {749005200 -10800 0 WGT} - {764730000 -7200 1 WGST} - {780454800 -10800 0 WGT} - {796179600 -7200 1 WGST} - {811904400 -10800 0 WGT} - {828234000 -7200 1 WGST} - {846378000 -10800 0 WGT} - {859683600 -7200 1 WGST} - {877827600 -10800 0 WGT} - {891133200 -7200 1 WGST} - {909277200 -10800 0 WGT} - {922582800 -7200 1 WGST} - {941331600 -10800 0 WGT} - {954032400 -7200 1 WGST} - {972781200 -10800 0 WGT} - {985482000 -7200 1 WGST} - {1004230800 -10800 0 WGT} - {1017536400 -7200 1 WGST} - {1035680400 -10800 0 WGT} - {1048986000 -7200 1 WGST} - {1067130000 -10800 0 WGT} - {1080435600 -7200 1 WGST} - {1099184400 -10800 0 WGT} - {1111885200 -7200 1 WGST} - {1130634000 -10800 0 WGT} - {1143334800 -7200 1 WGST} - {1162083600 -10800 0 WGT} - {1174784400 -7200 1 WGST} - {1193533200 -10800 0 WGT} - {1206838800 -7200 1 WGST} - {1224982800 -10800 0 WGT} - {1238288400 -7200 1 WGST} - {1256432400 -10800 0 WGT} - {1269738000 -7200 1 WGST} - {1288486800 -10800 0 WGT} - {1301187600 -7200 1 WGST} - {1319936400 -10800 0 WGT} - {1332637200 -7200 1 WGST} - {1351386000 -10800 0 WGT} - {1364691600 -7200 1 WGST} - {1382835600 -10800 0 WGT} - {1396141200 -7200 1 WGST} - {1414285200 -10800 0 WGT} - {1427590800 -7200 1 WGST} - {1445734800 -10800 0 WGT} - {1459040400 -7200 1 WGST} - {1477789200 -10800 0 WGT} - {1490490000 -7200 1 WGST} - {1509238800 -10800 0 WGT} - {1521939600 -7200 1 WGST} - {1540688400 -10800 0 WGT} - {1553994000 -7200 1 WGST} - {1572138000 -10800 0 WGT} - {1585443600 -7200 1 WGST} - {1603587600 -10800 0 WGT} - {1616893200 -7200 1 WGST} - {1635642000 -10800 0 WGT} - {1648342800 -7200 1 WGST} - {1667091600 -10800 0 WGT} - {1679792400 -7200 1 WGST} - {1698541200 -10800 0 WGT} - {1711846800 -7200 1 WGST} - {1729990800 -10800 0 WGT} - {1743296400 -7200 1 WGST} - {1761440400 -10800 0 WGT} - {1774746000 -7200 1 WGST} - {1792890000 -10800 0 WGT} - {1806195600 -7200 1 WGST} - {1824944400 -10800 0 WGT} - {1837645200 -7200 1 WGST} - {1856394000 -10800 0 WGT} - {1869094800 -7200 1 WGST} - {1887843600 -10800 0 WGT} - {1901149200 -7200 1 WGST} - {1919293200 -10800 0 WGT} - {1932598800 -7200 1 WGST} - {1950742800 -10800 0 WGT} - {1964048400 -7200 1 WGST} - {1982797200 -10800 0 WGT} - {1995498000 -7200 1 WGST} - {2014246800 -10800 0 WGT} - {2026947600 -7200 1 WGST} - {2045696400 -10800 0 WGT} - {2058397200 -7200 1 WGST} - {2077146000 -10800 0 WGT} - {2090451600 -7200 1 WGST} - {2108595600 -10800 0 WGT} - {2121901200 -7200 1 WGST} - {2140045200 -10800 0 WGT} - {2153350800 -7200 1 WGST} - {2172099600 -10800 0 WGT} - {2184800400 -7200 1 WGST} - {2203549200 -10800 0 WGT} - {2216250000 -7200 1 WGST} - {2234998800 -10800 0 WGT} - {2248304400 -7200 1 WGST} - {2266448400 -10800 0 WGT} - {2279754000 -7200 1 WGST} - {2297898000 -10800 0 WGT} - {2311203600 -7200 1 WGST} - {2329347600 -10800 0 WGT} - {2342653200 -7200 1 WGST} - {2361402000 -10800 0 WGT} - {2374102800 -7200 1 WGST} - {2392851600 -10800 0 WGT} - {2405552400 -7200 1 WGST} - {2424301200 -10800 0 WGT} - {2437606800 -7200 1 WGST} - {2455750800 -10800 0 WGT} - {2469056400 -7200 1 WGST} - {2487200400 -10800 0 WGT} - {2500506000 -7200 1 WGST} - {2519254800 -10800 0 WGT} - {2531955600 -7200 1 WGST} - {2550704400 -10800 0 WGT} - {2563405200 -7200 1 WGST} - {2582154000 -10800 0 WGT} - {2595459600 -7200 1 WGST} - {2613603600 -10800 0 WGT} - {2626909200 -7200 1 WGST} - {2645053200 -10800 0 WGT} - {2658358800 -7200 1 WGST} - {2676502800 -10800 0 WGT} - {2689808400 -7200 1 WGST} - {2708557200 -10800 0 WGT} - {2721258000 -7200 1 WGST} - {2740006800 -10800 0 WGT} - {2752707600 -7200 1 WGST} - {2771456400 -10800 0 WGT} - {2784762000 -7200 1 WGST} - {2802906000 -10800 0 WGT} - {2816211600 -7200 1 WGST} - {2834355600 -10800 0 WGT} - {2847661200 -7200 1 WGST} - {2866410000 -10800 0 WGT} - {2879110800 -7200 1 WGST} - {2897859600 -10800 0 WGT} - {2910560400 -7200 1 WGST} - {2929309200 -10800 0 WGT} - {2942010000 -7200 1 WGST} - {2960758800 -10800 0 WGT} - {2974064400 -7200 1 WGST} - {2992208400 -10800 0 WGT} - {3005514000 -7200 1 WGST} - {3023658000 -10800 0 WGT} - {3036963600 -7200 1 WGST} - {3055712400 -10800 0 WGT} - {3068413200 -7200 1 WGST} - {3087162000 -10800 0 WGT} - {3099862800 -7200 1 WGST} - {3118611600 -10800 0 WGT} - {3131917200 -7200 1 WGST} - {3150061200 -10800 0 WGT} - {3163366800 -7200 1 WGST} - {3181510800 -10800 0 WGT} - {3194816400 -7200 1 WGST} - {3212960400 -10800 0 WGT} - {3226266000 -7200 1 WGST} - {3245014800 -10800 0 WGT} - {3257715600 -7200 1 WGST} - {3276464400 -10800 0 WGT} - {3289165200 -7200 1 WGST} - {3307914000 -10800 0 WGT} - {3321219600 -7200 1 WGST} - {3339363600 -10800 0 WGT} - {3352669200 -7200 1 WGST} - {3370813200 -10800 0 WGT} - {3384118800 -7200 1 WGST} - {3402867600 -10800 0 WGT} - {3415568400 -7200 1 WGST} - {3434317200 -10800 0 WGT} - {3447018000 -7200 1 WGST} - {3465766800 -10800 0 WGT} - {3479072400 -7200 1 WGST} - {3497216400 -10800 0 WGT} - {3510522000 -7200 1 WGST} - {3528666000 -10800 0 WGT} - {3541971600 -7200 1 WGST} - {3560115600 -10800 0 WGT} - {3573421200 -7200 1 WGST} - {3592170000 -10800 0 WGT} - {3604870800 -7200 1 WGST} - {3623619600 -10800 0 WGT} - {3636320400 -7200 1 WGST} - {3655069200 -10800 0 WGT} - {3668374800 -7200 1 WGST} - {3686518800 -10800 0 WGT} - {3699824400 -7200 1 WGST} - {3717968400 -10800 0 WGT} - {3731274000 -7200 1 WGST} - {3750022800 -10800 0 WGT} - {3762723600 -7200 1 WGST} - {3781472400 -10800 0 WGT} - {3794173200 -7200 1 WGST} - {3812922000 -10800 0 WGT} - {3825622800 -7200 1 WGST} - {3844371600 -10800 0 WGT} - {3857677200 -7200 1 WGST} - {3875821200 -10800 0 WGT} - {3889126800 -7200 1 WGST} - {3907270800 -10800 0 WGT} - {3920576400 -7200 1 WGST} - {3939325200 -10800 0 WGT} - {3952026000 -7200 1 WGST} - {3970774800 -10800 0 WGT} - {3983475600 -7200 1 WGST} - {4002224400 -10800 0 WGT} - {4015530000 -7200 1 WGST} - {4033674000 -10800 0 WGT} - {4046979600 -7200 1 WGST} - {4065123600 -10800 0 WGT} - {4078429200 -7200 1 WGST} - {4096573200 -10800 0 WGT} + {-1686083584 -10800 0 -03} + {323845200 -7200 0 -02} + {338950800 -10800 0 -03} + {354675600 -7200 1 -02} + {370400400 -10800 0 -03} + {386125200 -7200 1 -02} + {401850000 -10800 0 -03} + {417574800 -7200 1 -02} + {433299600 -10800 0 -03} + {449024400 -7200 1 -02} + {465354000 -10800 0 -03} + {481078800 -7200 1 -02} + {496803600 -10800 0 -03} + {512528400 -7200 1 -02} + {528253200 -10800 0 -03} + {543978000 -7200 1 -02} + {559702800 -10800 0 -03} + {575427600 -7200 1 -02} + {591152400 -10800 0 -03} + {606877200 -7200 1 -02} + {622602000 -10800 0 -03} + {638326800 -7200 1 -02} + {654656400 -10800 0 -03} + {670381200 -7200 1 -02} + {686106000 -10800 0 -03} + {701830800 -7200 1 -02} + {717555600 -10800 0 -03} + {733280400 -7200 1 -02} + {749005200 -10800 0 -03} + {764730000 -7200 1 -02} + {780454800 -10800 0 -03} + {796179600 -7200 1 -02} + {811904400 -10800 0 -03} + {828234000 -7200 1 -02} + {846378000 -10800 0 -03} + {859683600 -7200 1 -02} + {877827600 -10800 0 -03} + {891133200 -7200 1 -02} + {909277200 -10800 0 -03} + {922582800 -7200 1 -02} + {941331600 -10800 0 -03} + {954032400 -7200 1 -02} + {972781200 -10800 0 -03} + {985482000 -7200 1 -02} + {1004230800 -10800 0 -03} + {1017536400 -7200 1 -02} + {1035680400 -10800 0 -03} + {1048986000 -7200 1 -02} + {1067130000 -10800 0 -03} + {1080435600 -7200 1 -02} + {1099184400 -10800 0 -03} + {1111885200 -7200 1 -02} + {1130634000 -10800 0 -03} + {1143334800 -7200 1 -02} + {1162083600 -10800 0 -03} + {1174784400 -7200 1 -02} + {1193533200 -10800 0 -03} + {1206838800 -7200 1 -02} + {1224982800 -10800 0 -03} + {1238288400 -7200 1 -02} + {1256432400 -10800 0 -03} + {1269738000 -7200 1 -02} + {1288486800 -10800 0 -03} + {1301187600 -7200 1 -02} + {1319936400 -10800 0 -03} + {1332637200 -7200 1 -02} + {1351386000 -10800 0 -03} + {1364691600 -7200 1 -02} + {1382835600 -10800 0 -03} + {1396141200 -7200 1 -02} + {1414285200 -10800 0 -03} + {1427590800 -7200 1 -02} + {1445734800 -10800 0 -03} + {1459040400 -7200 1 -02} + {1477789200 -10800 0 -03} + {1490490000 -7200 1 -02} + {1509238800 -10800 0 -03} + {1521939600 -7200 1 -02} + {1540688400 -10800 0 -03} + {1553994000 -7200 1 -02} + {1572138000 -10800 0 -03} + {1585443600 -7200 1 -02} + {1603587600 -10800 0 -03} + {1616893200 -7200 1 -02} + {1635642000 -10800 0 -03} + {1648342800 -7200 1 -02} + {1667091600 -10800 0 -03} + {1679792400 -7200 1 -02} + {1698541200 -10800 0 -03} + {1711846800 -7200 1 -02} + {1729990800 -10800 0 -03} + {1743296400 -7200 1 -02} + {1761440400 -10800 0 -03} + {1774746000 -7200 1 -02} + {1792890000 -10800 0 -03} + {1806195600 -7200 1 -02} + {1824944400 -10800 0 -03} + {1837645200 -7200 1 -02} + {1856394000 -10800 0 -03} + {1869094800 -7200 1 -02} + {1887843600 -10800 0 -03} + {1901149200 -7200 1 -02} + {1919293200 -10800 0 -03} + {1932598800 -7200 1 -02} + {1950742800 -10800 0 -03} + {1964048400 -7200 1 -02} + {1982797200 -10800 0 -03} + {1995498000 -7200 1 -02} + {2014246800 -10800 0 -03} + {2026947600 -7200 1 -02} + {2045696400 -10800 0 -03} + {2058397200 -7200 1 -02} + {2077146000 -10800 0 -03} + {2090451600 -7200 1 -02} + {2108595600 -10800 0 -03} + {2121901200 -7200 1 -02} + {2140045200 -10800 0 -03} + {2153350800 -7200 1 -02} + {2172099600 -10800 0 -03} + {2184800400 -7200 1 -02} + {2203549200 -10800 0 -03} + {2216250000 -7200 1 -02} + {2234998800 -10800 0 -03} + {2248304400 -7200 1 -02} + {2266448400 -10800 0 -03} + {2279754000 -7200 1 -02} + {2297898000 -10800 0 -03} + {2311203600 -7200 1 -02} + {2329347600 -10800 0 -03} + {2342653200 -7200 1 -02} + {2361402000 -10800 0 -03} + {2374102800 -7200 1 -02} + {2392851600 -10800 0 -03} + {2405552400 -7200 1 -02} + {2424301200 -10800 0 -03} + {2437606800 -7200 1 -02} + {2455750800 -10800 0 -03} + {2469056400 -7200 1 -02} + {2487200400 -10800 0 -03} + {2500506000 -7200 1 -02} + {2519254800 -10800 0 -03} + {2531955600 -7200 1 -02} + {2550704400 -10800 0 -03} + {2563405200 -7200 1 -02} + {2582154000 -10800 0 -03} + {2595459600 -7200 1 -02} + {2613603600 -10800 0 -03} + {2626909200 -7200 1 -02} + {2645053200 -10800 0 -03} + {2658358800 -7200 1 -02} + {2676502800 -10800 0 -03} + {2689808400 -7200 1 -02} + {2708557200 -10800 0 -03} + {2721258000 -7200 1 -02} + {2740006800 -10800 0 -03} + {2752707600 -7200 1 -02} + {2771456400 -10800 0 -03} + {2784762000 -7200 1 -02} + {2802906000 -10800 0 -03} + {2816211600 -7200 1 -02} + {2834355600 -10800 0 -03} + {2847661200 -7200 1 -02} + {2866410000 -10800 0 -03} + {2879110800 -7200 1 -02} + {2897859600 -10800 0 -03} + {2910560400 -7200 1 -02} + {2929309200 -10800 0 -03} + {2942010000 -7200 1 -02} + {2960758800 -10800 0 -03} + {2974064400 -7200 1 -02} + {2992208400 -10800 0 -03} + {3005514000 -7200 1 -02} + {3023658000 -10800 0 -03} + {3036963600 -7200 1 -02} + {3055712400 -10800 0 -03} + {3068413200 -7200 1 -02} + {3087162000 -10800 0 -03} + {3099862800 -7200 1 -02} + {3118611600 -10800 0 -03} + {3131917200 -7200 1 -02} + {3150061200 -10800 0 -03} + {3163366800 -7200 1 -02} + {3181510800 -10800 0 -03} + {3194816400 -7200 1 -02} + {3212960400 -10800 0 -03} + {3226266000 -7200 1 -02} + {3245014800 -10800 0 -03} + {3257715600 -7200 1 -02} + {3276464400 -10800 0 -03} + {3289165200 -7200 1 -02} + {3307914000 -10800 0 -03} + {3321219600 -7200 1 -02} + {3339363600 -10800 0 -03} + {3352669200 -7200 1 -02} + {3370813200 -10800 0 -03} + {3384118800 -7200 1 -02} + {3402867600 -10800 0 -03} + {3415568400 -7200 1 -02} + {3434317200 -10800 0 -03} + {3447018000 -7200 1 -02} + {3465766800 -10800 0 -03} + {3479072400 -7200 1 -02} + {3497216400 -10800 0 -03} + {3510522000 -7200 1 -02} + {3528666000 -10800 0 -03} + {3541971600 -7200 1 -02} + {3560115600 -10800 0 -03} + {3573421200 -7200 1 -02} + {3592170000 -10800 0 -03} + {3604870800 -7200 1 -02} + {3623619600 -10800 0 -03} + {3636320400 -7200 1 -02} + {3655069200 -10800 0 -03} + {3668374800 -7200 1 -02} + {3686518800 -10800 0 -03} + {3699824400 -7200 1 -02} + {3717968400 -10800 0 -03} + {3731274000 -7200 1 -02} + {3750022800 -10800 0 -03} + {3762723600 -7200 1 -02} + {3781472400 -10800 0 -03} + {3794173200 -7200 1 -02} + {3812922000 -10800 0 -03} + {3825622800 -7200 1 -02} + {3844371600 -10800 0 -03} + {3857677200 -7200 1 -02} + {3875821200 -10800 0 -03} + {3889126800 -7200 1 -02} + {3907270800 -10800 0 -03} + {3920576400 -7200 1 -02} + {3939325200 -10800 0 -03} + {3952026000 -7200 1 -02} + {3970774800 -10800 0 -03} + {3983475600 -7200 1 -02} + {4002224400 -10800 0 -03} + {4015530000 -7200 1 -02} + {4033674000 -10800 0 -03} + {4046979600 -7200 1 -02} + {4065123600 -10800 0 -03} + {4078429200 -7200 1 -02} + {4096573200 -10800 0 -03} } diff --git a/library/tzdata/America/Guayaquil b/library/tzdata/America/Guayaquil index e940a5b..353eb69 100644 --- a/library/tzdata/America/Guayaquil +++ b/library/tzdata/America/Guayaquil @@ -3,5 +3,7 @@ set TZData(:America/Guayaquil) { {-9223372036854775808 -19160 0 LMT} {-2524502440 -18840 0 QMT} - {-1230749160 -18000 0 ECT} + {-1230749160 -18000 0 -05} + {722926800 -14400 1 -04} + {728884800 -18000 0 -05} } diff --git a/library/tzdata/America/Guyana b/library/tzdata/America/Guyana index c58a989..fab7855 100644 --- a/library/tzdata/America/Guyana +++ b/library/tzdata/America/Guyana @@ -2,8 +2,7 @@ set TZData(:America/Guyana) { {-9223372036854775808 -13960 0 LMT} - {-1730578040 -13500 0 GBGT} - {-113688900 -13500 0 GYT} - {176010300 -10800 0 GYT} - {662698800 -14400 0 GYT} + {-1730578040 -13500 0 -0345} + {176010300 -10800 0 -03} + {662698800 -14400 0 -04} } diff --git a/library/tzdata/America/La_Paz b/library/tzdata/America/La_Paz index 38ffbb0..a245afd 100644 --- a/library/tzdata/America/La_Paz +++ b/library/tzdata/America/La_Paz @@ -4,5 +4,5 @@ set TZData(:America/La_Paz) { {-9223372036854775808 -16356 0 LMT} {-2524505244 -16356 0 CMT} {-1205954844 -12756 1 BOST} - {-1192307244 -14400 0 BOT} + {-1192307244 -14400 0 -04} } diff --git a/library/tzdata/America/Lima b/library/tzdata/America/Lima index c6e6ac1..b224a64 100644 --- a/library/tzdata/America/Lima +++ b/library/tzdata/America/Lima @@ -3,14 +3,14 @@ set TZData(:America/Lima) { {-9223372036854775808 -18492 0 LMT} {-2524503108 -18516 0 LMT} - {-1938538284 -14400 0 PEST} - {-1002052800 -18000 0 PET} - {-986756400 -14400 1 PEST} - {-971035200 -18000 0 PET} - {-955306800 -14400 1 PEST} - {-939585600 -18000 0 PET} - {512712000 -18000 0 PET} - {544248000 -18000 0 PET} - {638942400 -18000 0 PET} - {765172800 -18000 0 PET} + {-1938538284 -14400 0 -04} + {-1002052800 -18000 0 -05} + {-986756400 -14400 1 -04} + {-971035200 -18000 0 -05} + {-955306800 -14400 1 -04} + {-939585600 -18000 0 -05} + {512712000 -18000 0 -05} + {544248000 -18000 0 -05} + {638942400 -18000 0 -05} + {765172800 -18000 0 -05} } diff --git a/library/tzdata/America/Maceio b/library/tzdata/America/Maceio index 333b878..e6ed548 100644 --- a/library/tzdata/America/Maceio +++ b/library/tzdata/America/Maceio @@ -2,51 +2,51 @@ set TZData(:America/Maceio) { {-9223372036854775808 -8572 0 LMT} - {-1767217028 -10800 0 BRT} - {-1206957600 -7200 1 BRST} - {-1191362400 -10800 0 BRT} - {-1175374800 -7200 1 BRST} - {-1159826400 -10800 0 BRT} - {-633819600 -7200 1 BRST} - {-622069200 -10800 0 BRT} - {-602283600 -7200 1 BRST} - {-591832800 -10800 0 BRT} - {-570747600 -7200 1 BRST} - {-560210400 -10800 0 BRT} - {-539125200 -7200 1 BRST} - {-531352800 -10800 0 BRT} - {-191365200 -7200 1 BRST} - {-184197600 -10800 0 BRT} - {-155163600 -7200 1 BRST} - {-150069600 -10800 0 BRT} - {-128898000 -7200 1 BRST} - {-121125600 -10800 0 BRT} - {-99954000 -7200 1 BRST} - {-89589600 -10800 0 BRT} - {-68418000 -7200 1 BRST} - {-57967200 -10800 0 BRT} - {499748400 -7200 1 BRST} - {511236000 -10800 0 BRT} - {530593200 -7200 1 BRST} - {540266400 -10800 0 BRT} - {562129200 -7200 1 BRST} - {571197600 -10800 0 BRT} - {592974000 -7200 1 BRST} - {602042400 -10800 0 BRT} - {624423600 -7200 1 BRST} - {634701600 -10800 0 BRT} - {653536800 -10800 0 BRT} - {813553200 -10800 0 BRT} - {813726000 -7200 1 BRST} - {824004000 -10800 0 BRT} - {841802400 -10800 0 BRT} - {938660400 -10800 0 BRT} - {938919600 -7200 1 BRST} - {951616800 -10800 0 BRT} - {970974000 -7200 1 BRST} - {972180000 -10800 0 BRT} - {1000350000 -10800 0 BRT} - {1003028400 -7200 1 BRST} - {1013911200 -10800 0 BRT} - {1033437600 -10800 0 BRT} + {-1767217028 -10800 0 -03} + {-1206957600 -7200 1 -02} + {-1191362400 -10800 0 -03} + {-1175374800 -7200 1 -02} + {-1159826400 -10800 0 -03} + {-633819600 -7200 1 -02} + {-622069200 -10800 0 -03} + {-602283600 -7200 1 -02} + {-591832800 -10800 0 -03} + {-570747600 -7200 1 -02} + {-560210400 -10800 0 -03} + {-539125200 -7200 1 -02} + {-531352800 -10800 0 -03} + {-191365200 -7200 1 -02} + {-184197600 -10800 0 -03} + {-155163600 -7200 1 -02} + {-150069600 -10800 0 -03} + {-128898000 -7200 1 -02} + {-121125600 -10800 0 -03} + {-99954000 -7200 1 -02} + {-89589600 -10800 0 -03} + {-68418000 -7200 1 -02} + {-57967200 -10800 0 -03} + {499748400 -7200 1 -02} + {511236000 -10800 0 -03} + {530593200 -7200 1 -02} + {540266400 -10800 0 -03} + {562129200 -7200 1 -02} + {571197600 -10800 0 -03} + {592974000 -7200 1 -02} + {602042400 -10800 0 -03} + {624423600 -7200 1 -02} + {634701600 -10800 0 -03} + {653536800 -10800 0 -03} + {813553200 -10800 0 -03} + {813726000 -7200 1 -02} + {824004000 -10800 0 -03} + {841802400 -10800 0 -03} + {938660400 -10800 0 -03} + {938919600 -7200 1 -02} + {951616800 -10800 0 -03} + {970974000 -7200 1 -02} + {972180000 -10800 0 -03} + {1000350000 -10800 0 -03} + {1003028400 -7200 1 -02} + {1013911200 -10800 0 -03} + {1033437600 -10800 0 -03} } diff --git a/library/tzdata/America/Manaus b/library/tzdata/America/Manaus index 058e0f7..f17023c 100644 --- a/library/tzdata/America/Manaus +++ b/library/tzdata/America/Manaus @@ -2,38 +2,38 @@ set TZData(:America/Manaus) { {-9223372036854775808 -14404 0 LMT} - {-1767211196 -14400 0 AMT} - {-1206954000 -10800 1 AMST} - {-1191358800 -14400 0 AMT} - {-1175371200 -10800 1 AMST} - {-1159822800 -14400 0 AMT} - {-633816000 -10800 1 AMST} - {-622065600 -14400 0 AMT} - {-602280000 -10800 1 AMST} - {-591829200 -14400 0 AMT} - {-570744000 -10800 1 AMST} - {-560206800 -14400 0 AMT} - {-539121600 -10800 1 AMST} - {-531349200 -14400 0 AMT} - {-191361600 -10800 1 AMST} - {-184194000 -14400 0 AMT} - {-155160000 -10800 1 AMST} - {-150066000 -14400 0 AMT} - {-128894400 -10800 1 AMST} - {-121122000 -14400 0 AMT} - {-99950400 -10800 1 AMST} - {-89586000 -14400 0 AMT} - {-68414400 -10800 1 AMST} - {-57963600 -14400 0 AMT} - {499752000 -10800 1 AMST} - {511239600 -14400 0 AMT} - {530596800 -10800 1 AMST} - {540270000 -14400 0 AMT} - {562132800 -10800 1 AMST} - {571201200 -14400 0 AMT} - {590036400 -14400 0 AMT} - {749188800 -14400 0 AMT} - {750830400 -10800 1 AMST} - {761713200 -14400 0 AMT} - {780202800 -14400 0 AMT} + {-1767211196 -14400 0 -04} + {-1206954000 -10800 1 -03} + {-1191358800 -14400 0 -04} + {-1175371200 -10800 1 -03} + {-1159822800 -14400 0 -04} + {-633816000 -10800 1 -03} + {-622065600 -14400 0 -04} + {-602280000 -10800 1 -03} + {-591829200 -14400 0 -04} + {-570744000 -10800 1 -03} + {-560206800 -14400 0 -04} + {-539121600 -10800 1 -03} + {-531349200 -14400 0 -04} + {-191361600 -10800 1 -03} + {-184194000 -14400 0 -04} + {-155160000 -10800 1 -03} + {-150066000 -14400 0 -04} + {-128894400 -10800 1 -03} + {-121122000 -14400 0 -04} + {-99950400 -10800 1 -03} + {-89586000 -14400 0 -04} + {-68414400 -10800 1 -03} + {-57963600 -14400 0 -04} + {499752000 -10800 1 -03} + {511239600 -14400 0 -04} + {530596800 -10800 1 -03} + {540270000 -14400 0 -04} + {562132800 -10800 1 -03} + {571201200 -14400 0 -04} + {590036400 -14400 0 -04} + {749188800 -14400 0 -04} + {750830400 -10800 1 -03} + {761713200 -14400 0 -04} + {780202800 -14400 0 -04} } diff --git a/library/tzdata/America/Miquelon b/library/tzdata/America/Miquelon index a7410f1..c299be6 100644 --- a/library/tzdata/America/Miquelon +++ b/library/tzdata/America/Miquelon @@ -3,232 +3,232 @@ set TZData(:America/Miquelon) { {-9223372036854775808 -13480 0 LMT} {-1850328920 -14400 0 AST} - {326001600 -10800 0 PMST} - {536468400 -10800 0 PMST} - {544597200 -7200 1 PMDT} - {562132800 -10800 0 PMST} - {576046800 -7200 1 PMDT} - {594187200 -10800 0 PMST} - {607496400 -7200 1 PMDT} - {625636800 -10800 0 PMST} - {638946000 -7200 1 PMDT} - {657086400 -10800 0 PMST} - {671000400 -7200 1 PMDT} - {688536000 -10800 0 PMST} - {702450000 -7200 1 PMDT} - {719985600 -10800 0 PMST} - {733899600 -7200 1 PMDT} - {752040000 -10800 0 PMST} - {765349200 -7200 1 PMDT} - {783489600 -10800 0 PMST} - {796798800 -7200 1 PMDT} - {814939200 -10800 0 PMST} - {828853200 -7200 1 PMDT} - {846388800 -10800 0 PMST} - {860302800 -7200 1 PMDT} - {877838400 -10800 0 PMST} - {891752400 -7200 1 PMDT} - {909288000 -10800 0 PMST} - {923202000 -7200 1 PMDT} - {941342400 -10800 0 PMST} - {954651600 -7200 1 PMDT} - {972792000 -10800 0 PMST} - {986101200 -7200 1 PMDT} - {1004241600 -10800 0 PMST} - {1018155600 -7200 1 PMDT} - {1035691200 -10800 0 PMST} - {1049605200 -7200 1 PMDT} - {1067140800 -10800 0 PMST} - {1081054800 -7200 1 PMDT} - {1099195200 -10800 0 PMST} - {1112504400 -7200 1 PMDT} - {1130644800 -10800 0 PMST} - {1143954000 -7200 1 PMDT} - {1162094400 -10800 0 PMST} - {1173589200 -7200 1 PMDT} - {1194148800 -10800 0 PMST} - {1205038800 -7200 1 PMDT} - {1225598400 -10800 0 PMST} - {1236488400 -7200 1 PMDT} - {1257048000 -10800 0 PMST} - {1268542800 -7200 1 PMDT} - {1289102400 -10800 0 PMST} - {1299992400 -7200 1 PMDT} - {1320552000 -10800 0 PMST} - {1331442000 -7200 1 PMDT} - {1352001600 -10800 0 PMST} - {1362891600 -7200 1 PMDT} - {1383451200 -10800 0 PMST} - {1394341200 -7200 1 PMDT} - {1414900800 -10800 0 PMST} - {1425790800 -7200 1 PMDT} - {1446350400 -10800 0 PMST} - {1457845200 -7200 1 PMDT} - {1478404800 -10800 0 PMST} - {1489294800 -7200 1 PMDT} - {1509854400 -10800 0 PMST} - {1520744400 -7200 1 PMDT} - {1541304000 -10800 0 PMST} - {1552194000 -7200 1 PMDT} - {1572753600 -10800 0 PMST} - {1583643600 -7200 1 PMDT} - {1604203200 -10800 0 PMST} - {1615698000 -7200 1 PMDT} - {1636257600 -10800 0 PMST} - {1647147600 -7200 1 PMDT} - {1667707200 -10800 0 PMST} - {1678597200 -7200 1 PMDT} - {1699156800 -10800 0 PMST} - {1710046800 -7200 1 PMDT} - {1730606400 -10800 0 PMST} - {1741496400 -7200 1 PMDT} - {1762056000 -10800 0 PMST} - {1772946000 -7200 1 PMDT} - {1793505600 -10800 0 PMST} - {1805000400 -7200 1 PMDT} - {1825560000 -10800 0 PMST} - {1836450000 -7200 1 PMDT} - {1857009600 -10800 0 PMST} - {1867899600 -7200 1 PMDT} - {1888459200 -10800 0 PMST} - {1899349200 -7200 1 PMDT} - {1919908800 -10800 0 PMST} - {1930798800 -7200 1 PMDT} - {1951358400 -10800 0 PMST} - {1962853200 -7200 1 PMDT} - {1983412800 -10800 0 PMST} - {1994302800 -7200 1 PMDT} - {2014862400 -10800 0 PMST} - {2025752400 -7200 1 PMDT} - {2046312000 -10800 0 PMST} - {2057202000 -7200 1 PMDT} - {2077761600 -10800 0 PMST} - {2088651600 -7200 1 PMDT} - {2109211200 -10800 0 PMST} - {2120101200 -7200 1 PMDT} - {2140660800 -10800 0 PMST} - {2152155600 -7200 1 PMDT} - {2172715200 -10800 0 PMST} - {2183605200 -7200 1 PMDT} - {2204164800 -10800 0 PMST} - {2215054800 -7200 1 PMDT} - {2235614400 -10800 0 PMST} - {2246504400 -7200 1 PMDT} - {2267064000 -10800 0 PMST} - {2277954000 -7200 1 PMDT} - {2298513600 -10800 0 PMST} - {2309403600 -7200 1 PMDT} - {2329963200 -10800 0 PMST} - {2341458000 -7200 1 PMDT} - {2362017600 -10800 0 PMST} - {2372907600 -7200 1 PMDT} - {2393467200 -10800 0 PMST} - {2404357200 -7200 1 PMDT} - {2424916800 -10800 0 PMST} - {2435806800 -7200 1 PMDT} - {2456366400 -10800 0 PMST} - {2467256400 -7200 1 PMDT} - {2487816000 -10800 0 PMST} - {2499310800 -7200 1 PMDT} - {2519870400 -10800 0 PMST} - {2530760400 -7200 1 PMDT} - {2551320000 -10800 0 PMST} - {2562210000 -7200 1 PMDT} - {2582769600 -10800 0 PMST} - {2593659600 -7200 1 PMDT} - {2614219200 -10800 0 PMST} - {2625109200 -7200 1 PMDT} - {2645668800 -10800 0 PMST} - {2656558800 -7200 1 PMDT} - {2677118400 -10800 0 PMST} - {2688613200 -7200 1 PMDT} - {2709172800 -10800 0 PMST} - {2720062800 -7200 1 PMDT} - {2740622400 -10800 0 PMST} - {2751512400 -7200 1 PMDT} - {2772072000 -10800 0 PMST} - {2782962000 -7200 1 PMDT} - {2803521600 -10800 0 PMST} - {2814411600 -7200 1 PMDT} - {2834971200 -10800 0 PMST} - {2846466000 -7200 1 PMDT} - {2867025600 -10800 0 PMST} - {2877915600 -7200 1 PMDT} - {2898475200 -10800 0 PMST} - {2909365200 -7200 1 PMDT} - {2929924800 -10800 0 PMST} - {2940814800 -7200 1 PMDT} - {2961374400 -10800 0 PMST} - {2972264400 -7200 1 PMDT} - {2992824000 -10800 0 PMST} - {3003714000 -7200 1 PMDT} - {3024273600 -10800 0 PMST} - {3035768400 -7200 1 PMDT} - {3056328000 -10800 0 PMST} - {3067218000 -7200 1 PMDT} - {3087777600 -10800 0 PMST} - {3098667600 -7200 1 PMDT} - {3119227200 -10800 0 PMST} - {3130117200 -7200 1 PMDT} - {3150676800 -10800 0 PMST} - {3161566800 -7200 1 PMDT} - {3182126400 -10800 0 PMST} - {3193016400 -7200 1 PMDT} - {3213576000 -10800 0 PMST} - {3225070800 -7200 1 PMDT} - {3245630400 -10800 0 PMST} - {3256520400 -7200 1 PMDT} - {3277080000 -10800 0 PMST} - {3287970000 -7200 1 PMDT} - {3308529600 -10800 0 PMST} - {3319419600 -7200 1 PMDT} - {3339979200 -10800 0 PMST} - {3350869200 -7200 1 PMDT} - {3371428800 -10800 0 PMST} - {3382923600 -7200 1 PMDT} - {3403483200 -10800 0 PMST} - {3414373200 -7200 1 PMDT} - {3434932800 -10800 0 PMST} - {3445822800 -7200 1 PMDT} - {3466382400 -10800 0 PMST} - {3477272400 -7200 1 PMDT} - {3497832000 -10800 0 PMST} - {3508722000 -7200 1 PMDT} - {3529281600 -10800 0 PMST} - {3540171600 -7200 1 PMDT} - {3560731200 -10800 0 PMST} - {3572226000 -7200 1 PMDT} - {3592785600 -10800 0 PMST} - {3603675600 -7200 1 PMDT} - {3624235200 -10800 0 PMST} - {3635125200 -7200 1 PMDT} - {3655684800 -10800 0 PMST} - {3666574800 -7200 1 PMDT} - {3687134400 -10800 0 PMST} - {3698024400 -7200 1 PMDT} - {3718584000 -10800 0 PMST} - {3730078800 -7200 1 PMDT} - {3750638400 -10800 0 PMST} - {3761528400 -7200 1 PMDT} - {3782088000 -10800 0 PMST} - {3792978000 -7200 1 PMDT} - {3813537600 -10800 0 PMST} - {3824427600 -7200 1 PMDT} - {3844987200 -10800 0 PMST} - {3855877200 -7200 1 PMDT} - {3876436800 -10800 0 PMST} - {3887326800 -7200 1 PMDT} - {3907886400 -10800 0 PMST} - {3919381200 -7200 1 PMDT} - {3939940800 -10800 0 PMST} - {3950830800 -7200 1 PMDT} - {3971390400 -10800 0 PMST} - {3982280400 -7200 1 PMDT} - {4002840000 -10800 0 PMST} - {4013730000 -7200 1 PMDT} - {4034289600 -10800 0 PMST} - {4045179600 -7200 1 PMDT} - {4065739200 -10800 0 PMST} - {4076629200 -7200 1 PMDT} - {4097188800 -10800 0 PMST} + {326001600 -10800 0 -03} + {536468400 -10800 0 -02} + {544597200 -7200 1 -02} + {562132800 -10800 0 -02} + {576046800 -7200 1 -02} + {594187200 -10800 0 -02} + {607496400 -7200 1 -02} + {625636800 -10800 0 -02} + {638946000 -7200 1 -02} + {657086400 -10800 0 -02} + {671000400 -7200 1 -02} + {688536000 -10800 0 -02} + {702450000 -7200 1 -02} + {719985600 -10800 0 -02} + {733899600 -7200 1 -02} + {752040000 -10800 0 -02} + {765349200 -7200 1 -02} + {783489600 -10800 0 -02} + {796798800 -7200 1 -02} + {814939200 -10800 0 -02} + {828853200 -7200 1 -02} + {846388800 -10800 0 -02} + {860302800 -7200 1 -02} + {877838400 -10800 0 -02} + {891752400 -7200 1 -02} + {909288000 -10800 0 -02} + {923202000 -7200 1 -02} + {941342400 -10800 0 -02} + {954651600 -7200 1 -02} + {972792000 -10800 0 -02} + {986101200 -7200 1 -02} + {1004241600 -10800 0 -02} + {1018155600 -7200 1 -02} + {1035691200 -10800 0 -02} + {1049605200 -7200 1 -02} + {1067140800 -10800 0 -02} + {1081054800 -7200 1 -02} + {1099195200 -10800 0 -02} + {1112504400 -7200 1 -02} + {1130644800 -10800 0 -02} + {1143954000 -7200 1 -02} + {1162094400 -10800 0 -02} + {1173589200 -7200 1 -02} + {1194148800 -10800 0 -02} + {1205038800 -7200 1 -02} + {1225598400 -10800 0 -02} + {1236488400 -7200 1 -02} + {1257048000 -10800 0 -02} + {1268542800 -7200 1 -02} + {1289102400 -10800 0 -02} + {1299992400 -7200 1 -02} + {1320552000 -10800 0 -02} + {1331442000 -7200 1 -02} + {1352001600 -10800 0 -02} + {1362891600 -7200 1 -02} + {1383451200 -10800 0 -02} + {1394341200 -7200 1 -02} + {1414900800 -10800 0 -02} + {1425790800 -7200 1 -02} + {1446350400 -10800 0 -02} + {1457845200 -7200 1 -02} + {1478404800 -10800 0 -02} + {1489294800 -7200 1 -02} + {1509854400 -10800 0 -02} + {1520744400 -7200 1 -02} + {1541304000 -10800 0 -02} + {1552194000 -7200 1 -02} + {1572753600 -10800 0 -02} + {1583643600 -7200 1 -02} + {1604203200 -10800 0 -02} + {1615698000 -7200 1 -02} + {1636257600 -10800 0 -02} + {1647147600 -7200 1 -02} + {1667707200 -10800 0 -02} + {1678597200 -7200 1 -02} + {1699156800 -10800 0 -02} + {1710046800 -7200 1 -02} + {1730606400 -10800 0 -02} + {1741496400 -7200 1 -02} + {1762056000 -10800 0 -02} + {1772946000 -7200 1 -02} + {1793505600 -10800 0 -02} + {1805000400 -7200 1 -02} + {1825560000 -10800 0 -02} + {1836450000 -7200 1 -02} + {1857009600 -10800 0 -02} + {1867899600 -7200 1 -02} + {1888459200 -10800 0 -02} + {1899349200 -7200 1 -02} + {1919908800 -10800 0 -02} + {1930798800 -7200 1 -02} + {1951358400 -10800 0 -02} + {1962853200 -7200 1 -02} + {1983412800 -10800 0 -02} + {1994302800 -7200 1 -02} + {2014862400 -10800 0 -02} + {2025752400 -7200 1 -02} + {2046312000 -10800 0 -02} + {2057202000 -7200 1 -02} + {2077761600 -10800 0 -02} + {2088651600 -7200 1 -02} + {2109211200 -10800 0 -02} + {2120101200 -7200 1 -02} + {2140660800 -10800 0 -02} + {2152155600 -7200 1 -02} + {2172715200 -10800 0 -02} + {2183605200 -7200 1 -02} + {2204164800 -10800 0 -02} + {2215054800 -7200 1 -02} + {2235614400 -10800 0 -02} + {2246504400 -7200 1 -02} + {2267064000 -10800 0 -02} + {2277954000 -7200 1 -02} + {2298513600 -10800 0 -02} + {2309403600 -7200 1 -02} + {2329963200 -10800 0 -02} + {2341458000 -7200 1 -02} + {2362017600 -10800 0 -02} + {2372907600 -7200 1 -02} + {2393467200 -10800 0 -02} + {2404357200 -7200 1 -02} + {2424916800 -10800 0 -02} + {2435806800 -7200 1 -02} + {2456366400 -10800 0 -02} + {2467256400 -7200 1 -02} + {2487816000 -10800 0 -02} + {2499310800 -7200 1 -02} + {2519870400 -10800 0 -02} + {2530760400 -7200 1 -02} + {2551320000 -10800 0 -02} + {2562210000 -7200 1 -02} + {2582769600 -10800 0 -02} + {2593659600 -7200 1 -02} + {2614219200 -10800 0 -02} + {2625109200 -7200 1 -02} + {2645668800 -10800 0 -02} + {2656558800 -7200 1 -02} + {2677118400 -10800 0 -02} + {2688613200 -7200 1 -02} + {2709172800 -10800 0 -02} + {2720062800 -7200 1 -02} + {2740622400 -10800 0 -02} + {2751512400 -7200 1 -02} + {2772072000 -10800 0 -02} + {2782962000 -7200 1 -02} + {2803521600 -10800 0 -02} + {2814411600 -7200 1 -02} + {2834971200 -10800 0 -02} + {2846466000 -7200 1 -02} + {2867025600 -10800 0 -02} + {2877915600 -7200 1 -02} + {2898475200 -10800 0 -02} + {2909365200 -7200 1 -02} + {2929924800 -10800 0 -02} + {2940814800 -7200 1 -02} + {2961374400 -10800 0 -02} + {2972264400 -7200 1 -02} + {2992824000 -10800 0 -02} + {3003714000 -7200 1 -02} + {3024273600 -10800 0 -02} + {3035768400 -7200 1 -02} + {3056328000 -10800 0 -02} + {3067218000 -7200 1 -02} + {3087777600 -10800 0 -02} + {3098667600 -7200 1 -02} + {3119227200 -10800 0 -02} + {3130117200 -7200 1 -02} + {3150676800 -10800 0 -02} + {3161566800 -7200 1 -02} + {3182126400 -10800 0 -02} + {3193016400 -7200 1 -02} + {3213576000 -10800 0 -02} + {3225070800 -7200 1 -02} + {3245630400 -10800 0 -02} + {3256520400 -7200 1 -02} + {3277080000 -10800 0 -02} + {3287970000 -7200 1 -02} + {3308529600 -10800 0 -02} + {3319419600 -7200 1 -02} + {3339979200 -10800 0 -02} + {3350869200 -7200 1 -02} + {3371428800 -10800 0 -02} + {3382923600 -7200 1 -02} + {3403483200 -10800 0 -02} + {3414373200 -7200 1 -02} + {3434932800 -10800 0 -02} + {3445822800 -7200 1 -02} + {3466382400 -10800 0 -02} + {3477272400 -7200 1 -02} + {3497832000 -10800 0 -02} + {3508722000 -7200 1 -02} + {3529281600 -10800 0 -02} + {3540171600 -7200 1 -02} + {3560731200 -10800 0 -02} + {3572226000 -7200 1 -02} + {3592785600 -10800 0 -02} + {3603675600 -7200 1 -02} + {3624235200 -10800 0 -02} + {3635125200 -7200 1 -02} + {3655684800 -10800 0 -02} + {3666574800 -7200 1 -02} + {3687134400 -10800 0 -02} + {3698024400 -7200 1 -02} + {3718584000 -10800 0 -02} + {3730078800 -7200 1 -02} + {3750638400 -10800 0 -02} + {3761528400 -7200 1 -02} + {3782088000 -10800 0 -02} + {3792978000 -7200 1 -02} + {3813537600 -10800 0 -02} + {3824427600 -7200 1 -02} + {3844987200 -10800 0 -02} + {3855877200 -7200 1 -02} + {3876436800 -10800 0 -02} + {3887326800 -7200 1 -02} + {3907886400 -10800 0 -02} + {3919381200 -7200 1 -02} + {3939940800 -10800 0 -02} + {3950830800 -7200 1 -02} + {3971390400 -10800 0 -02} + {3982280400 -7200 1 -02} + {4002840000 -10800 0 -02} + {4013730000 -7200 1 -02} + {4034289600 -10800 0 -02} + {4045179600 -7200 1 -02} + {4065739200 -10800 0 -02} + {4076629200 -7200 1 -02} + {4097188800 -10800 0 -02} } diff --git a/library/tzdata/America/Montevideo b/library/tzdata/America/Montevideo index 91a5117..ff85fb3 100644 --- a/library/tzdata/America/Montevideo +++ b/library/tzdata/America/Montevideo @@ -3,90 +3,94 @@ set TZData(:America/Montevideo) { {-9223372036854775808 -13484 0 LMT} {-2256668116 -13484 0 MMT} - {-1567455316 -12600 0 UYT} - {-1459542600 -10800 1 UYHST} - {-1443819600 -12600 0 UYT} - {-1428006600 -10800 1 UYHST} - {-1412283600 -12600 0 UYT} - {-1396470600 -10800 1 UYHST} - {-1380747600 -12600 0 UYT} - {-1141590600 -10800 1 UYHST} - {-1128286800 -12600 0 UYT} - {-1110141000 -10800 1 UYHST} - {-1096837200 -12600 0 UYT} - {-1078691400 -10800 1 UYHST} - {-1065387600 -12600 0 UYT} - {-1046637000 -10800 1 UYHST} - {-1033938000 -12600 0 UYT} - {-1015187400 -10800 1 UYHST} - {-1002488400 -12600 0 UYT} - {-983737800 -10800 1 UYHST} - {-971038800 -12600 0 UYT} - {-952288200 -10800 1 UYHST} - {-938984400 -12600 0 UYT} - {-920838600 -10800 1 UYHST} - {-907534800 -12600 0 UYT} - {-896819400 -10800 1 UYHST} - {-853623000 -10800 0 UYT} - {-853621200 -7200 1 UYST} - {-845848800 -10800 0 UYT} - {-334789200 -7200 1 UYST} - {-319672800 -10800 0 UYT} - {-314226000 -7200 1 UYST} - {-309996000 -10800 0 UYT} - {-149720400 -7200 1 UYST} - {-134604000 -10800 0 UYT} - {-118270800 -7200 1 UYST} - {-100044000 -10800 0 UYT} - {-86821200 -7200 1 UYST} - {-68508000 -10800 0 UYT} - {-50446800 -9000 1 UYHST} - {-34119000 -10800 0 UYT} - {-18910800 -9000 1 UYHST} - {-2583000 -10800 0 UYT} - {12625200 -9000 1 UYHST} - {28953000 -10800 0 UYT} - {72932400 -7200 1 UYST} - {82692000 -10800 0 UYT} - {132116400 -9000 1 UYHST} - {156911400 -7200 1 UYST} - {212983200 -10800 0 UYT} - {250052400 -7200 1 UYST} - {260244000 -10800 0 UYT} - {307594800 -7200 1 UYST} - {325994400 -10800 0 UYT} - {566449200 -7200 1 UYST} - {574308000 -10800 0 UYT} - {597812400 -7200 1 UYST} - {605671200 -10800 0 UYT} - {625633200 -7200 1 UYST} - {636516000 -10800 0 UYT} - {656478000 -7200 1 UYST} - {667965600 -10800 0 UYT} - {688532400 -7200 1 UYST} - {699415200 -10800 0 UYT} - {719377200 -7200 1 UYST} - {730864800 -10800 0 UYT} - {1095562800 -7200 1 UYST} - {1111896000 -10800 0 UYT} - {1128834000 -7200 1 UYST} - {1142136000 -10800 0 UYT} - {1159678800 -7200 1 UYST} - {1173585600 -10800 0 UYT} - {1191733200 -7200 1 UYST} - {1205035200 -10800 0 UYT} - {1223182800 -7200 1 UYST} - {1236484800 -10800 0 UYT} - {1254632400 -7200 1 UYST} - {1268539200 -10800 0 UYT} - {1286082000 -7200 1 UYST} - {1299988800 -10800 0 UYT} - {1317531600 -7200 1 UYST} - {1331438400 -10800 0 UYT} - {1349586000 -7200 1 UYST} - {1362888000 -10800 0 UYT} - {1381035600 -7200 1 UYST} - {1394337600 -10800 0 UYT} - {1412485200 -7200 1 UYST} - {1425787200 -10800 0 UYT} + {-1567455316 -12600 0 -0330} + {-1459542600 -10800 1 -03} + {-1443819600 -12600 0 -0330} + {-1428006600 -10800 1 -03} + {-1412283600 -12600 0 -0330} + {-1396470600 -10800 1 -03} + {-1380747600 -12600 0 -0330} + {-1141590600 -10800 1 -03} + {-1128286800 -12600 0 -0330} + {-1110141000 -10800 1 -03} + {-1096837200 -12600 0 -0330} + {-1078691400 -10800 1 -03} + {-1065387600 -12600 0 -0330} + {-1046637000 -10800 1 -03} + {-1033938000 -12600 0 -0330} + {-1015187400 -10800 1 -03} + {-1002488400 -12600 0 -0330} + {-983737800 -10800 1 -03} + {-971038800 -12600 0 -0330} + {-952288200 -10800 1 -03} + {-938984400 -12600 0 -0330} + {-920838600 -10800 1 -03} + {-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} + {-309996000 -10800 0 -03} + {-149720400 -7200 1 -02} + {-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} + {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} + {667965600 -10800 0 -03} + {688532400 -7200 1 -02} + {699415200 -10800 0 -03} + {719377200 -7200 1 -02} + {730864800 -10800 0 -03} + {1095562800 -7200 1 -02} + {1111896000 -10800 0 -03} + {1128834000 -7200 1 -02} + {1142136000 -10800 0 -03} + {1159678800 -7200 1 -02} + {1173585600 -10800 0 -03} + {1191733200 -7200 1 -02} + {1205035200 -10800 0 -03} + {1223182800 -7200 1 -02} + {1236484800 -10800 0 -03} + {1254632400 -7200 1 -02} + {1268539200 -10800 0 -03} + {1286082000 -7200 1 -02} + {1299988800 -10800 0 -03} + {1317531600 -7200 1 -02} + {1331438400 -10800 0 -03} + {1349586000 -7200 1 -02} + {1362888000 -10800 0 -03} + {1381035600 -7200 1 -02} + {1394337600 -10800 0 -03} + {1412485200 -7200 1 -02} + {1425787200 -10800 0 -03} } diff --git a/library/tzdata/America/Noronha b/library/tzdata/America/Noronha index 94d6f42..f24b412 100644 --- a/library/tzdata/America/Noronha +++ b/library/tzdata/America/Noronha @@ -2,47 +2,47 @@ set TZData(:America/Noronha) { {-9223372036854775808 -7780 0 LMT} - {-1767217820 -7200 0 FNT} - {-1206961200 -3600 1 FNST} - {-1191366000 -7200 0 FNT} - {-1175378400 -3600 1 FNST} - {-1159830000 -7200 0 FNT} - {-633823200 -3600 1 FNST} - {-622072800 -7200 0 FNT} - {-602287200 -3600 1 FNST} - {-591836400 -7200 0 FNT} - {-570751200 -3600 1 FNST} - {-560214000 -7200 0 FNT} - {-539128800 -3600 1 FNST} - {-531356400 -7200 0 FNT} - {-191368800 -3600 1 FNST} - {-184201200 -7200 0 FNT} - {-155167200 -3600 1 FNST} - {-150073200 -7200 0 FNT} - {-128901600 -3600 1 FNST} - {-121129200 -7200 0 FNT} - {-99957600 -3600 1 FNST} - {-89593200 -7200 0 FNT} - {-68421600 -3600 1 FNST} - {-57970800 -7200 0 FNT} - {499744800 -3600 1 FNST} - {511232400 -7200 0 FNT} - {530589600 -3600 1 FNST} - {540262800 -7200 0 FNT} - {562125600 -3600 1 FNST} - {571194000 -7200 0 FNT} - {592970400 -3600 1 FNST} - {602038800 -7200 0 FNT} - {624420000 -3600 1 FNST} - {634698000 -7200 0 FNT} - {653533200 -7200 0 FNT} - {938656800 -7200 0 FNT} - {938916000 -3600 1 FNST} - {951613200 -7200 0 FNT} - {970970400 -3600 1 FNST} - {971571600 -7200 0 FNT} - {1000346400 -7200 0 FNT} - {1003024800 -3600 1 FNST} - {1013907600 -7200 0 FNT} - {1033434000 -7200 0 FNT} + {-1767217820 -7200 0 -02} + {-1206961200 -3600 1 -01} + {-1191366000 -7200 0 -02} + {-1175378400 -3600 1 -01} + {-1159830000 -7200 0 -02} + {-633823200 -3600 1 -01} + {-622072800 -7200 0 -02} + {-602287200 -3600 1 -01} + {-591836400 -7200 0 -02} + {-570751200 -3600 1 -01} + {-560214000 -7200 0 -02} + {-539128800 -3600 1 -01} + {-531356400 -7200 0 -02} + {-191368800 -3600 1 -01} + {-184201200 -7200 0 -02} + {-155167200 -3600 1 -01} + {-150073200 -7200 0 -02} + {-128901600 -3600 1 -01} + {-121129200 -7200 0 -02} + {-99957600 -3600 1 -01} + {-89593200 -7200 0 -02} + {-68421600 -3600 1 -01} + {-57970800 -7200 0 -02} + {499744800 -3600 1 -01} + {511232400 -7200 0 -02} + {530589600 -3600 1 -01} + {540262800 -7200 0 -02} + {562125600 -3600 1 -01} + {571194000 -7200 0 -02} + {592970400 -3600 1 -01} + {602038800 -7200 0 -02} + {624420000 -3600 1 -01} + {634698000 -7200 0 -02} + {653533200 -7200 0 -02} + {938656800 -7200 0 -02} + {938916000 -3600 1 -01} + {951613200 -7200 0 -02} + {970970400 -3600 1 -01} + {971571600 -7200 0 -02} + {1000346400 -7200 0 -02} + {1003024800 -3600 1 -01} + {1013907600 -7200 0 -02} + {1033434000 -7200 0 -02} } diff --git a/library/tzdata/America/Paramaribo b/library/tzdata/America/Paramaribo index d15f5c7..7a80f1d 100644 --- a/library/tzdata/America/Paramaribo +++ b/library/tzdata/America/Paramaribo @@ -4,7 +4,6 @@ set TZData(:America/Paramaribo) { {-9223372036854775808 -13240 0 LMT} {-1861906760 -13252 0 PMT} {-1104524348 -13236 0 PMT} - {-765317964 -12600 0 NEGT} - {185686200 -12600 0 SRT} - {465449400 -10800 0 SRT} + {-765317964 -12600 0 -0330} + {465449400 -10800 0 -03} } diff --git a/library/tzdata/America/Porto_Velho b/library/tzdata/America/Porto_Velho index ce611d2..42566ad 100644 --- a/library/tzdata/America/Porto_Velho +++ b/library/tzdata/America/Porto_Velho @@ -2,34 +2,34 @@ set TZData(:America/Porto_Velho) { {-9223372036854775808 -15336 0 LMT} - {-1767210264 -14400 0 AMT} - {-1206954000 -10800 1 AMST} - {-1191358800 -14400 0 AMT} - {-1175371200 -10800 1 AMST} - {-1159822800 -14400 0 AMT} - {-633816000 -10800 1 AMST} - {-622065600 -14400 0 AMT} - {-602280000 -10800 1 AMST} - {-591829200 -14400 0 AMT} - {-570744000 -10800 1 AMST} - {-560206800 -14400 0 AMT} - {-539121600 -10800 1 AMST} - {-531349200 -14400 0 AMT} - {-191361600 -10800 1 AMST} - {-184194000 -14400 0 AMT} - {-155160000 -10800 1 AMST} - {-150066000 -14400 0 AMT} - {-128894400 -10800 1 AMST} - {-121122000 -14400 0 AMT} - {-99950400 -10800 1 AMST} - {-89586000 -14400 0 AMT} - {-68414400 -10800 1 AMST} - {-57963600 -14400 0 AMT} - {499752000 -10800 1 AMST} - {511239600 -14400 0 AMT} - {530596800 -10800 1 AMST} - {540270000 -14400 0 AMT} - {562132800 -10800 1 AMST} - {571201200 -14400 0 AMT} - {590036400 -14400 0 AMT} + {-1767210264 -14400 0 -04} + {-1206954000 -10800 1 -03} + {-1191358800 -14400 0 -04} + {-1175371200 -10800 1 -03} + {-1159822800 -14400 0 -04} + {-633816000 -10800 1 -03} + {-622065600 -14400 0 -04} + {-602280000 -10800 1 -03} + {-591829200 -14400 0 -04} + {-570744000 -10800 1 -03} + {-560206800 -14400 0 -04} + {-539121600 -10800 1 -03} + {-531349200 -14400 0 -04} + {-191361600 -10800 1 -03} + {-184194000 -14400 0 -04} + {-155160000 -10800 1 -03} + {-150066000 -14400 0 -04} + {-128894400 -10800 1 -03} + {-121122000 -14400 0 -04} + {-99950400 -10800 1 -03} + {-89586000 -14400 0 -04} + {-68414400 -10800 1 -03} + {-57963600 -14400 0 -04} + {499752000 -10800 1 -03} + {511239600 -14400 0 -04} + {530596800 -10800 1 -03} + {540270000 -14400 0 -04} + {562132800 -10800 1 -03} + {571201200 -14400 0 -04} + {590036400 -14400 0 -04} } diff --git a/library/tzdata/America/Punta_Arenas b/library/tzdata/America/Punta_Arenas new file mode 100644 index 0000000..75487e7 --- /dev/null +++ b/library/tzdata/America/Punta_Arenas @@ -0,0 +1,122 @@ +# created by tools/tclZIC.tcl - do not edit + +set TZData(:America/Punta_Arenas) { + {-9223372036854775808 -17020 0 LMT} + {-2524504580 -16966 0 SMT} + {-1892661434 -18000 0 -05} + {-1688410800 -16966 0 SMT} + {-1619205434 -14400 0 -04} + {-1593806400 -16966 0 SMT} + {-1335986234 -18000 0 -05} + {-1335985200 -14400 1 -04} + {-1317585600 -18000 0 -05} + {-1304362800 -14400 1 -04} + {-1286049600 -18000 0 -05} + {-1272826800 -14400 1 -04} + {-1254513600 -18000 0 -05} + {-1241290800 -14400 1 -04} + {-1222977600 -18000 0 -05} + {-1209754800 -14400 1 -04} + {-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} + {-23922000 -14400 0 -04} + {-3355200 -10800 1 -03} + {7527600 -14400 0 -04} + {24465600 -10800 1 -03} + {37767600 -14400 0 -04} + {55915200 -10800 1 -03} + {69217200 -14400 0 -04} + {87969600 -10800 1 -03} + {100666800 -14400 0 -04} + {118209600 -10800 1 -03} + {132116400 -14400 0 -04} + {150868800 -10800 1 -03} + {163566000 -14400 0 -04} + {182318400 -10800 1 -03} + {195620400 -14400 0 -04} + {213768000 -10800 1 -03} + {227070000 -14400 0 -04} + {245217600 -10800 1 -03} + {258519600 -14400 0 -04} + {277272000 -10800 1 -03} + {289969200 -14400 0 -04} + {308721600 -10800 1 -03} + {321418800 -14400 0 -04} + {340171200 -10800 1 -03} + {353473200 -14400 0 -04} + {371620800 -10800 1 -03} + {384922800 -14400 0 -04} + {403070400 -10800 1 -03} + {416372400 -14400 0 -04} + {434520000 -10800 1 -03} + {447822000 -14400 0 -04} + {466574400 -10800 1 -03} + {479271600 -14400 0 -04} + {498024000 -10800 1 -03} + {510721200 -14400 0 -04} + {529473600 -10800 1 -03} + {545194800 -14400 0 -04} + {560923200 -10800 1 -03} + {574225200 -14400 0 -04} + {592372800 -10800 1 -03} + {605674800 -14400 0 -04} + {624427200 -10800 1 -03} + {637124400 -14400 0 -04} + {653457600 -10800 1 -03} + {668574000 -14400 0 -04} + {687326400 -10800 1 -03} + {700628400 -14400 0 -04} + {718776000 -10800 1 -03} + {732078000 -14400 0 -04} + {750225600 -10800 1 -03} + {763527600 -14400 0 -04} + {781675200 -10800 1 -03} + {794977200 -14400 0 -04} + {813729600 -10800 1 -03} + {826426800 -14400 0 -04} + {845179200 -10800 1 -03} + {859690800 -14400 0 -04} + {876628800 -10800 1 -03} + {889930800 -14400 0 -04} + {906868800 -10800 1 -03} + {923194800 -14400 0 -04} + {939528000 -10800 1 -03} + {952830000 -14400 0 -04} + {971582400 -10800 1 -03} + {984279600 -14400 0 -04} + {1003032000 -10800 1 -03} + {1015729200 -14400 0 -04} + {1034481600 -10800 1 -03} + {1047178800 -14400 0 -04} + {1065931200 -10800 1 -03} + {1079233200 -14400 0 -04} + {1097380800 -10800 1 -03} + {1110682800 -14400 0 -04} + {1128830400 -10800 1 -03} + {1142132400 -14400 0 -04} + {1160884800 -10800 1 -03} + {1173582000 -14400 0 -04} + {1192334400 -10800 1 -03} + {1206846000 -14400 0 -04} + {1223784000 -10800 1 -03} + {1237086000 -14400 0 -04} + {1255233600 -10800 1 -03} + {1270350000 -14400 0 -04} + {1286683200 -10800 1 -03} + {1304823600 -14400 0 -04} + {1313899200 -10800 1 -03} + {1335668400 -14400 0 -04} + {1346558400 -10800 1 -03} + {1367118000 -14400 0 -04} + {1378612800 -10800 1 -03} + {1398567600 -14400 0 -04} + {1410062400 -10800 1 -03} + {1463281200 -14400 0 -04} + {1471147200 -10800 1 -03} + {1480820400 -10800 0 -03} +} diff --git a/library/tzdata/America/Recife b/library/tzdata/America/Recife index f6ae00e..8eae571 100644 --- a/library/tzdata/America/Recife +++ b/library/tzdata/America/Recife @@ -2,47 +2,47 @@ set TZData(:America/Recife) { {-9223372036854775808 -8376 0 LMT} - {-1767217224 -10800 0 BRT} - {-1206957600 -7200 1 BRST} - {-1191362400 -10800 0 BRT} - {-1175374800 -7200 1 BRST} - {-1159826400 -10800 0 BRT} - {-633819600 -7200 1 BRST} - {-622069200 -10800 0 BRT} - {-602283600 -7200 1 BRST} - {-591832800 -10800 0 BRT} - {-570747600 -7200 1 BRST} - {-560210400 -10800 0 BRT} - {-539125200 -7200 1 BRST} - {-531352800 -10800 0 BRT} - {-191365200 -7200 1 BRST} - {-184197600 -10800 0 BRT} - {-155163600 -7200 1 BRST} - {-150069600 -10800 0 BRT} - {-128898000 -7200 1 BRST} - {-121125600 -10800 0 BRT} - {-99954000 -7200 1 BRST} - {-89589600 -10800 0 BRT} - {-68418000 -7200 1 BRST} - {-57967200 -10800 0 BRT} - {499748400 -7200 1 BRST} - {511236000 -10800 0 BRT} - {530593200 -7200 1 BRST} - {540266400 -10800 0 BRT} - {562129200 -7200 1 BRST} - {571197600 -10800 0 BRT} - {592974000 -7200 1 BRST} - {602042400 -10800 0 BRT} - {624423600 -7200 1 BRST} - {634701600 -10800 0 BRT} - {653536800 -10800 0 BRT} - {938660400 -10800 0 BRT} - {938919600 -7200 1 BRST} - {951616800 -10800 0 BRT} - {970974000 -7200 1 BRST} - {971575200 -10800 0 BRT} - {1000350000 -10800 0 BRT} - {1003028400 -7200 1 BRST} - {1013911200 -10800 0 BRT} - {1033437600 -10800 0 BRT} + {-1767217224 -10800 0 -03} + {-1206957600 -7200 1 -02} + {-1191362400 -10800 0 -03} + {-1175374800 -7200 1 -02} + {-1159826400 -10800 0 -03} + {-633819600 -7200 1 -02} + {-622069200 -10800 0 -03} + {-602283600 -7200 1 -02} + {-591832800 -10800 0 -03} + {-570747600 -7200 1 -02} + {-560210400 -10800 0 -03} + {-539125200 -7200 1 -02} + {-531352800 -10800 0 -03} + {-191365200 -7200 1 -02} + {-184197600 -10800 0 -03} + {-155163600 -7200 1 -02} + {-150069600 -10800 0 -03} + {-128898000 -7200 1 -02} + {-121125600 -10800 0 -03} + {-99954000 -7200 1 -02} + {-89589600 -10800 0 -03} + {-68418000 -7200 1 -02} + {-57967200 -10800 0 -03} + {499748400 -7200 1 -02} + {511236000 -10800 0 -03} + {530593200 -7200 1 -02} + {540266400 -10800 0 -03} + {562129200 -7200 1 -02} + {571197600 -10800 0 -03} + {592974000 -7200 1 -02} + {602042400 -10800 0 -03} + {624423600 -7200 1 -02} + {634701600 -10800 0 -03} + {653536800 -10800 0 -03} + {938660400 -10800 0 -03} + {938919600 -7200 1 -02} + {951616800 -10800 0 -03} + {970974000 -7200 1 -02} + {971575200 -10800 0 -03} + {1000350000 -10800 0 -03} + {1003028400 -7200 1 -02} + {1013911200 -10800 0 -03} + {1033437600 -10800 0 -03} } diff --git a/library/tzdata/America/Rio_Branco b/library/tzdata/America/Rio_Branco index f0ff7fa..e3c2f31 100644 --- a/library/tzdata/America/Rio_Branco +++ b/library/tzdata/America/Rio_Branco @@ -2,36 +2,36 @@ set TZData(:America/Rio_Branco) { {-9223372036854775808 -16272 0 LMT} - {-1767209328 -18000 0 ACT} - {-1206950400 -14400 1 ACST} - {-1191355200 -18000 0 ACT} - {-1175367600 -14400 1 ACST} - {-1159819200 -18000 0 ACT} - {-633812400 -14400 1 ACST} - {-622062000 -18000 0 ACT} - {-602276400 -14400 1 ACST} - {-591825600 -18000 0 ACT} - {-570740400 -14400 1 ACST} - {-560203200 -18000 0 ACT} - {-539118000 -14400 1 ACST} - {-531345600 -18000 0 ACT} - {-191358000 -14400 1 ACST} - {-184190400 -18000 0 ACT} - {-155156400 -14400 1 ACST} - {-150062400 -18000 0 ACT} - {-128890800 -14400 1 ACST} - {-121118400 -18000 0 ACT} - {-99946800 -14400 1 ACST} - {-89582400 -18000 0 ACT} - {-68410800 -14400 1 ACST} - {-57960000 -18000 0 ACT} - {499755600 -14400 1 ACST} - {511243200 -18000 0 ACT} - {530600400 -14400 1 ACST} - {540273600 -18000 0 ACT} - {562136400 -14400 1 ACST} - {571204800 -18000 0 ACT} - {590040000 -18000 0 ACT} - {1214283600 -14400 0 AMT} - {1384056000 -18000 0 ACT} + {-1767209328 -18000 0 -05} + {-1206950400 -14400 1 -04} + {-1191355200 -18000 0 -05} + {-1175367600 -14400 1 -04} + {-1159819200 -18000 0 -05} + {-633812400 -14400 1 -04} + {-622062000 -18000 0 -05} + {-602276400 -14400 1 -04} + {-591825600 -18000 0 -05} + {-570740400 -14400 1 -04} + {-560203200 -18000 0 -05} + {-539118000 -14400 1 -04} + {-531345600 -18000 0 -05} + {-191358000 -14400 1 -04} + {-184190400 -18000 0 -05} + {-155156400 -14400 1 -04} + {-150062400 -18000 0 -05} + {-128890800 -14400 1 -04} + {-121118400 -18000 0 -05} + {-99946800 -14400 1 -04} + {-89582400 -18000 0 -05} + {-68410800 -14400 1 -04} + {-57960000 -18000 0 -05} + {499755600 -14400 1 -04} + {511243200 -18000 0 -05} + {530600400 -14400 1 -04} + {540273600 -18000 0 -05} + {562136400 -14400 1 -04} + {571204800 -18000 0 -05} + {590040000 -18000 0 -05} + {1214283600 -14400 0 -04} + {1384056000 -18000 0 -05} } diff --git a/library/tzdata/America/Santarem b/library/tzdata/America/Santarem index b6e9264..f81e9b6 100644 --- a/library/tzdata/America/Santarem +++ b/library/tzdata/America/Santarem @@ -2,35 +2,35 @@ set TZData(:America/Santarem) { {-9223372036854775808 -13128 0 LMT} - {-1767212472 -14400 0 AMT} - {-1206954000 -10800 1 AMST} - {-1191358800 -14400 0 AMT} - {-1175371200 -10800 1 AMST} - {-1159822800 -14400 0 AMT} - {-633816000 -10800 1 AMST} - {-622065600 -14400 0 AMT} - {-602280000 -10800 1 AMST} - {-591829200 -14400 0 AMT} - {-570744000 -10800 1 AMST} - {-560206800 -14400 0 AMT} - {-539121600 -10800 1 AMST} - {-531349200 -14400 0 AMT} - {-191361600 -10800 1 AMST} - {-184194000 -14400 0 AMT} - {-155160000 -10800 1 AMST} - {-150066000 -14400 0 AMT} - {-128894400 -10800 1 AMST} - {-121122000 -14400 0 AMT} - {-99950400 -10800 1 AMST} - {-89586000 -14400 0 AMT} - {-68414400 -10800 1 AMST} - {-57963600 -14400 0 AMT} - {499752000 -10800 1 AMST} - {511239600 -14400 0 AMT} - {530596800 -10800 1 AMST} - {540270000 -14400 0 AMT} - {562132800 -10800 1 AMST} - {571201200 -14400 0 AMT} - {590036400 -14400 0 AMT} - {1214280000 -10800 0 BRT} + {-1767212472 -14400 0 -04} + {-1206954000 -10800 1 -03} + {-1191358800 -14400 0 -04} + {-1175371200 -10800 1 -03} + {-1159822800 -14400 0 -04} + {-633816000 -10800 1 -03} + {-622065600 -14400 0 -04} + {-602280000 -10800 1 -03} + {-591829200 -14400 0 -04} + {-570744000 -10800 1 -03} + {-560206800 -14400 0 -04} + {-539121600 -10800 1 -03} + {-531349200 -14400 0 -04} + {-191361600 -10800 1 -03} + {-184194000 -14400 0 -04} + {-155160000 -10800 1 -03} + {-150066000 -14400 0 -04} + {-128894400 -10800 1 -03} + {-121122000 -14400 0 -04} + {-99950400 -10800 1 -03} + {-89586000 -14400 0 -04} + {-68414400 -10800 1 -03} + {-57963600 -14400 0 -04} + {499752000 -10800 1 -03} + {511239600 -14400 0 -04} + {530596800 -10800 1 -03} + {540270000 -14400 0 -04} + {562132800 -10800 1 -03} + {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 3a5c0fd..95e920d 100644 --- a/library/tzdata/America/Santiago +++ b/library/tzdata/America/Santiago @@ -3,287 +3,287 @@ set TZData(:America/Santiago) { {-9223372036854775808 -16966 0 LMT} {-2524504634 -16966 0 SMT} - {-1892661434 -18000 0 CLT} + {-1892661434 -18000 0 -05} {-1688410800 -16966 0 SMT} - {-1619205434 -14400 0 CLT} + {-1619205434 -14400 0 -04} {-1593806400 -16966 0 SMT} - {-1335986234 -18000 0 CLT} - {-1335985200 -14400 1 CLST} - {-1317585600 -18000 0 CLT} - {-1304362800 -14400 1 CLST} - {-1286049600 -18000 0 CLT} - {-1272826800 -14400 1 CLST} - {-1254513600 -18000 0 CLT} - {-1241290800 -14400 1 CLST} - {-1222977600 -18000 0 CLT} - {-1209754800 -14400 1 CLST} - {-1191355200 -18000 0 CLT} - {-1178132400 -14400 0 CLT} - {-870552000 -18000 0 CLT} - {-865278000 -14400 0 CLT} - {-740520000 -10800 1 CLST} - {-736376400 -14400 0 CLT} - {-718056000 -18000 0 CLT} - {-713649600 -14400 0 CLT} - {-36619200 -10800 1 CLST} - {-23922000 -14400 0 CLT} - {-3355200 -10800 1 CLST} - {7527600 -14400 0 CLT} - {24465600 -10800 1 CLST} - {37767600 -14400 0 CLT} - {55915200 -10800 1 CLST} - {69217200 -14400 0 CLT} - {87969600 -10800 1 CLST} - {100666800 -14400 0 CLT} - {118209600 -10800 1 CLST} - {132116400 -14400 0 CLT} - {150868800 -10800 1 CLST} - {163566000 -14400 0 CLT} - {182318400 -10800 1 CLST} - {195620400 -14400 0 CLT} - {213768000 -10800 1 CLST} - {227070000 -14400 0 CLT} - {245217600 -10800 1 CLST} - {258519600 -14400 0 CLT} - {277272000 -10800 1 CLST} - {289969200 -14400 0 CLT} - {308721600 -10800 1 CLST} - {321418800 -14400 0 CLT} - {340171200 -10800 1 CLST} - {353473200 -14400 0 CLT} - {371620800 -10800 1 CLST} - {384922800 -14400 0 CLT} - {403070400 -10800 1 CLST} - {416372400 -14400 0 CLT} - {434520000 -10800 1 CLST} - {447822000 -14400 0 CLT} - {466574400 -10800 1 CLST} - {479271600 -14400 0 CLT} - {498024000 -10800 1 CLST} - {510721200 -14400 0 CLT} - {529473600 -10800 1 CLST} - {545194800 -14400 0 CLT} - {560923200 -10800 1 CLST} - {574225200 -14400 0 CLT} - {592372800 -10800 1 CLST} - {605674800 -14400 0 CLT} - {624427200 -10800 1 CLST} - {637124400 -14400 0 CLT} - {653457600 -10800 1 CLST} - {668574000 -14400 0 CLT} - {687326400 -10800 1 CLST} - {700628400 -14400 0 CLT} - {718776000 -10800 1 CLST} - {732078000 -14400 0 CLT} - {750225600 -10800 1 CLST} - {763527600 -14400 0 CLT} - {781675200 -10800 1 CLST} - {794977200 -14400 0 CLT} - {813729600 -10800 1 CLST} - {826426800 -14400 0 CLT} - {845179200 -10800 1 CLST} - {859690800 -14400 0 CLT} - {876628800 -10800 1 CLST} - {889930800 -14400 0 CLT} - {906868800 -10800 1 CLST} - {923194800 -14400 0 CLT} - {939528000 -10800 1 CLST} - {952830000 -14400 0 CLT} - {971582400 -10800 1 CLST} - {984279600 -14400 0 CLT} - {1003032000 -10800 1 CLST} - {1015729200 -14400 0 CLT} - {1034481600 -10800 1 CLST} - {1047178800 -14400 0 CLT} - {1065931200 -10800 1 CLST} - {1079233200 -14400 0 CLT} - {1097380800 -10800 1 CLST} - {1110682800 -14400 0 CLT} - {1128830400 -10800 1 CLST} - {1142132400 -14400 0 CLT} - {1160884800 -10800 1 CLST} - {1173582000 -14400 0 CLT} - {1192334400 -10800 1 CLST} - {1206846000 -14400 0 CLT} - {1223784000 -10800 1 CLST} - {1237086000 -14400 0 CLT} - {1255233600 -10800 1 CLST} - {1270350000 -14400 0 CLT} - {1286683200 -10800 1 CLST} - {1304823600 -14400 0 CLT} - {1313899200 -10800 1 CLST} - {1335668400 -14400 0 CLT} - {1346558400 -10800 1 CLST} - {1367118000 -14400 0 CLT} - {1378612800 -10800 1 CLST} - {1398567600 -14400 0 CLT} - {1410062400 -10800 1 CLST} - {1463281200 -14400 0 CLT} - {1471147200 -10800 1 CLST} - {1494730800 -14400 0 CLT} - {1502596800 -10800 1 CLST} - {1526180400 -14400 0 CLT} - {1534046400 -10800 1 CLST} - {1557630000 -14400 0 CLT} - {1565496000 -10800 1 CLST} - {1589079600 -14400 0 CLT} - {1596945600 -10800 1 CLST} - {1620529200 -14400 0 CLT} - {1629000000 -10800 1 CLST} - {1652583600 -14400 0 CLT} - {1660449600 -10800 1 CLST} - {1684033200 -14400 0 CLT} - {1691899200 -10800 1 CLST} - {1715482800 -14400 0 CLT} - {1723348800 -10800 1 CLST} - {1746932400 -14400 0 CLT} - {1754798400 -10800 1 CLST} - {1778382000 -14400 0 CLT} - {1786248000 -10800 1 CLST} - {1809831600 -14400 0 CLT} - {1818302400 -10800 1 CLST} - {1841886000 -14400 0 CLT} - {1849752000 -10800 1 CLST} - {1873335600 -14400 0 CLT} - {1881201600 -10800 1 CLST} - {1904785200 -14400 0 CLT} - {1912651200 -10800 1 CLST} - {1936234800 -14400 0 CLT} - {1944100800 -10800 1 CLST} - {1967684400 -14400 0 CLT} - {1976155200 -10800 1 CLST} - {1999738800 -14400 0 CLT} - {2007604800 -10800 1 CLST} - {2031188400 -14400 0 CLT} - {2039054400 -10800 1 CLST} - {2062638000 -14400 0 CLT} - {2070504000 -10800 1 CLST} - {2094087600 -14400 0 CLT} - {2101953600 -10800 1 CLST} - {2125537200 -14400 0 CLT} - {2133403200 -10800 1 CLST} - {2156986800 -14400 0 CLT} - {2165457600 -10800 1 CLST} - {2189041200 -14400 0 CLT} - {2196907200 -10800 1 CLST} - {2220490800 -14400 0 CLT} - {2228356800 -10800 1 CLST} - {2251940400 -14400 0 CLT} - {2259806400 -10800 1 CLST} - {2283390000 -14400 0 CLT} - {2291256000 -10800 1 CLST} - {2314839600 -14400 0 CLT} - {2322705600 -10800 1 CLST} - {2346894000 -14400 0 CLT} - {2354760000 -10800 1 CLST} - {2378343600 -14400 0 CLT} - {2386209600 -10800 1 CLST} - {2409793200 -14400 0 CLT} - {2417659200 -10800 1 CLST} - {2441242800 -14400 0 CLT} - {2449108800 -10800 1 CLST} - {2472692400 -14400 0 CLT} - {2480558400 -10800 1 CLST} - {2504142000 -14400 0 CLT} - {2512612800 -10800 1 CLST} - {2536196400 -14400 0 CLT} - {2544062400 -10800 1 CLST} - {2567646000 -14400 0 CLT} - {2575512000 -10800 1 CLST} - {2599095600 -14400 0 CLT} - {2606961600 -10800 1 CLST} - {2630545200 -14400 0 CLT} - {2638411200 -10800 1 CLST} - {2661994800 -14400 0 CLT} - {2669860800 -10800 1 CLST} - {2693444400 -14400 0 CLT} - {2701915200 -10800 1 CLST} - {2725498800 -14400 0 CLT} - {2733364800 -10800 1 CLST} - {2756948400 -14400 0 CLT} - {2764814400 -10800 1 CLST} - {2788398000 -14400 0 CLT} - {2796264000 -10800 1 CLST} - {2819847600 -14400 0 CLT} - {2827713600 -10800 1 CLST} - {2851297200 -14400 0 CLT} - {2859768000 -10800 1 CLST} - {2883351600 -14400 0 CLT} - {2891217600 -10800 1 CLST} - {2914801200 -14400 0 CLT} - {2922667200 -10800 1 CLST} - {2946250800 -14400 0 CLT} - {2954116800 -10800 1 CLST} - {2977700400 -14400 0 CLT} - {2985566400 -10800 1 CLST} - {3009150000 -14400 0 CLT} - {3017016000 -10800 1 CLST} - {3040599600 -14400 0 CLT} - {3049070400 -10800 1 CLST} - {3072654000 -14400 0 CLT} - {3080520000 -10800 1 CLST} - {3104103600 -14400 0 CLT} - {3111969600 -10800 1 CLST} - {3135553200 -14400 0 CLT} - {3143419200 -10800 1 CLST} - {3167002800 -14400 0 CLT} - {3174868800 -10800 1 CLST} - {3198452400 -14400 0 CLT} - {3206318400 -10800 1 CLST} - {3230506800 -14400 0 CLT} - {3238372800 -10800 1 CLST} - {3261956400 -14400 0 CLT} - {3269822400 -10800 1 CLST} - {3293406000 -14400 0 CLT} - {3301272000 -10800 1 CLST} - {3324855600 -14400 0 CLT} - {3332721600 -10800 1 CLST} - {3356305200 -14400 0 CLT} - {3364171200 -10800 1 CLST} - {3387754800 -14400 0 CLT} - {3396225600 -10800 1 CLST} - {3419809200 -14400 0 CLT} - {3427675200 -10800 1 CLST} - {3451258800 -14400 0 CLT} - {3459124800 -10800 1 CLST} - {3482708400 -14400 0 CLT} - {3490574400 -10800 1 CLST} - {3514158000 -14400 0 CLT} - {3522024000 -10800 1 CLST} - {3545607600 -14400 0 CLT} - {3553473600 -10800 1 CLST} - {3577057200 -14400 0 CLT} - {3585528000 -10800 1 CLST} - {3609111600 -14400 0 CLT} - {3616977600 -10800 1 CLST} - {3640561200 -14400 0 CLT} - {3648427200 -10800 1 CLST} - {3672010800 -14400 0 CLT} - {3679876800 -10800 1 CLST} - {3703460400 -14400 0 CLT} - {3711326400 -10800 1 CLST} - {3734910000 -14400 0 CLT} - {3743380800 -10800 1 CLST} - {3766964400 -14400 0 CLT} - {3774830400 -10800 1 CLST} - {3798414000 -14400 0 CLT} - {3806280000 -10800 1 CLST} - {3829863600 -14400 0 CLT} - {3837729600 -10800 1 CLST} - {3861313200 -14400 0 CLT} - {3869179200 -10800 1 CLST} - {3892762800 -14400 0 CLT} - {3900628800 -10800 1 CLST} - {3924212400 -14400 0 CLT} - {3932683200 -10800 1 CLST} - {3956266800 -14400 0 CLT} - {3964132800 -10800 1 CLST} - {3987716400 -14400 0 CLT} - {3995582400 -10800 1 CLST} - {4019166000 -14400 0 CLT} - {4027032000 -10800 1 CLST} - {4050615600 -14400 0 CLT} - {4058481600 -10800 1 CLST} - {4082065200 -14400 0 CLT} - {4089931200 -10800 1 CLST} + {-1335986234 -18000 0 -05} + {-1335985200 -14400 1 -04} + {-1317585600 -18000 0 -05} + {-1304362800 -14400 1 -04} + {-1286049600 -18000 0 -05} + {-1272826800 -14400 1 -04} + {-1254513600 -18000 0 -05} + {-1241290800 -14400 1 -04} + {-1222977600 -18000 0 -05} + {-1209754800 -14400 1 -04} + {-1191355200 -18000 0 -05} + {-1178132400 -14400 0 -04} + {-870552000 -18000 0 -05} + {-865278000 -14400 0 -04} + {-740520000 -10800 1 -03} + {-736376400 -14400 0 -04} + {-718056000 -18000 0 -05} + {-713649600 -14400 0 -04} + {-36619200 -10800 1 -03} + {-23922000 -14400 0 -04} + {-3355200 -10800 1 -03} + {7527600 -14400 0 -04} + {24465600 -10800 1 -03} + {37767600 -14400 0 -04} + {55915200 -10800 1 -03} + {69217200 -14400 0 -04} + {87969600 -10800 1 -03} + {100666800 -14400 0 -04} + {118209600 -10800 1 -03} + {132116400 -14400 0 -04} + {150868800 -10800 1 -03} + {163566000 -14400 0 -04} + {182318400 -10800 1 -03} + {195620400 -14400 0 -04} + {213768000 -10800 1 -03} + {227070000 -14400 0 -04} + {245217600 -10800 1 -03} + {258519600 -14400 0 -04} + {277272000 -10800 1 -03} + {289969200 -14400 0 -04} + {308721600 -10800 1 -03} + {321418800 -14400 0 -04} + {340171200 -10800 1 -03} + {353473200 -14400 0 -04} + {371620800 -10800 1 -03} + {384922800 -14400 0 -04} + {403070400 -10800 1 -03} + {416372400 -14400 0 -04} + {434520000 -10800 1 -03} + {447822000 -14400 0 -04} + {466574400 -10800 1 -03} + {479271600 -14400 0 -04} + {498024000 -10800 1 -03} + {510721200 -14400 0 -04} + {529473600 -10800 1 -03} + {545194800 -14400 0 -04} + {560923200 -10800 1 -03} + {574225200 -14400 0 -04} + {592372800 -10800 1 -03} + {605674800 -14400 0 -04} + {624427200 -10800 1 -03} + {637124400 -14400 0 -04} + {653457600 -10800 1 -03} + {668574000 -14400 0 -04} + {687326400 -10800 1 -03} + {700628400 -14400 0 -04} + {718776000 -10800 1 -03} + {732078000 -14400 0 -04} + {750225600 -10800 1 -03} + {763527600 -14400 0 -04} + {781675200 -10800 1 -03} + {794977200 -14400 0 -04} + {813729600 -10800 1 -03} + {826426800 -14400 0 -04} + {845179200 -10800 1 -03} + {859690800 -14400 0 -04} + {876628800 -10800 1 -03} + {889930800 -14400 0 -04} + {906868800 -10800 1 -03} + {923194800 -14400 0 -04} + {939528000 -10800 1 -03} + {952830000 -14400 0 -04} + {971582400 -10800 1 -03} + {984279600 -14400 0 -04} + {1003032000 -10800 1 -03} + {1015729200 -14400 0 -04} + {1034481600 -10800 1 -03} + {1047178800 -14400 0 -04} + {1065931200 -10800 1 -03} + {1079233200 -14400 0 -04} + {1097380800 -10800 1 -03} + {1110682800 -14400 0 -04} + {1128830400 -10800 1 -03} + {1142132400 -14400 0 -04} + {1160884800 -10800 1 -03} + {1173582000 -14400 0 -04} + {1192334400 -10800 1 -03} + {1206846000 -14400 0 -04} + {1223784000 -10800 1 -03} + {1237086000 -14400 0 -04} + {1255233600 -10800 1 -03} + {1270350000 -14400 0 -04} + {1286683200 -10800 1 -03} + {1304823600 -14400 0 -04} + {1313899200 -10800 1 -03} + {1335668400 -14400 0 -04} + {1346558400 -10800 1 -03} + {1367118000 -14400 0 -04} + {1378612800 -10800 1 -03} + {1398567600 -14400 0 -04} + {1410062400 -10800 1 -03} + {1463281200 -14400 0 -04} + {1471147200 -10800 1 -03} + {1494730800 -14400 0 -04} + {1502596800 -10800 1 -03} + {1526180400 -14400 0 -04} + {1534046400 -10800 1 -03} + {1557630000 -14400 0 -04} + {1565496000 -10800 1 -03} + {1589079600 -14400 0 -04} + {1596945600 -10800 1 -03} + {1620529200 -14400 0 -04} + {1629000000 -10800 1 -03} + {1652583600 -14400 0 -04} + {1660449600 -10800 1 -03} + {1684033200 -14400 0 -04} + {1691899200 -10800 1 -03} + {1715482800 -14400 0 -04} + {1723348800 -10800 1 -03} + {1746932400 -14400 0 -04} + {1754798400 -10800 1 -03} + {1778382000 -14400 0 -04} + {1786248000 -10800 1 -03} + {1809831600 -14400 0 -04} + {1818302400 -10800 1 -03} + {1841886000 -14400 0 -04} + {1849752000 -10800 1 -03} + {1873335600 -14400 0 -04} + {1881201600 -10800 1 -03} + {1904785200 -14400 0 -04} + {1912651200 -10800 1 -03} + {1936234800 -14400 0 -04} + {1944100800 -10800 1 -03} + {1967684400 -14400 0 -04} + {1976155200 -10800 1 -03} + {1999738800 -14400 0 -04} + {2007604800 -10800 1 -03} + {2031188400 -14400 0 -04} + {2039054400 -10800 1 -03} + {2062638000 -14400 0 -04} + {2070504000 -10800 1 -03} + {2094087600 -14400 0 -04} + {2101953600 -10800 1 -03} + {2125537200 -14400 0 -04} + {2133403200 -10800 1 -03} + {2156986800 -14400 0 -04} + {2165457600 -10800 1 -03} + {2189041200 -14400 0 -04} + {2196907200 -10800 1 -03} + {2220490800 -14400 0 -04} + {2228356800 -10800 1 -03} + {2251940400 -14400 0 -04} + {2259806400 -10800 1 -03} + {2283390000 -14400 0 -04} + {2291256000 -10800 1 -03} + {2314839600 -14400 0 -04} + {2322705600 -10800 1 -03} + {2346894000 -14400 0 -04} + {2354760000 -10800 1 -03} + {2378343600 -14400 0 -04} + {2386209600 -10800 1 -03} + {2409793200 -14400 0 -04} + {2417659200 -10800 1 -03} + {2441242800 -14400 0 -04} + {2449108800 -10800 1 -03} + {2472692400 -14400 0 -04} + {2480558400 -10800 1 -03} + {2504142000 -14400 0 -04} + {2512612800 -10800 1 -03} + {2536196400 -14400 0 -04} + {2544062400 -10800 1 -03} + {2567646000 -14400 0 -04} + {2575512000 -10800 1 -03} + {2599095600 -14400 0 -04} + {2606961600 -10800 1 -03} + {2630545200 -14400 0 -04} + {2638411200 -10800 1 -03} + {2661994800 -14400 0 -04} + {2669860800 -10800 1 -03} + {2693444400 -14400 0 -04} + {2701915200 -10800 1 -03} + {2725498800 -14400 0 -04} + {2733364800 -10800 1 -03} + {2756948400 -14400 0 -04} + {2764814400 -10800 1 -03} + {2788398000 -14400 0 -04} + {2796264000 -10800 1 -03} + {2819847600 -14400 0 -04} + {2827713600 -10800 1 -03} + {2851297200 -14400 0 -04} + {2859768000 -10800 1 -03} + {2883351600 -14400 0 -04} + {2891217600 -10800 1 -03} + {2914801200 -14400 0 -04} + {2922667200 -10800 1 -03} + {2946250800 -14400 0 -04} + {2954116800 -10800 1 -03} + {2977700400 -14400 0 -04} + {2985566400 -10800 1 -03} + {3009150000 -14400 0 -04} + {3017016000 -10800 1 -03} + {3040599600 -14400 0 -04} + {3049070400 -10800 1 -03} + {3072654000 -14400 0 -04} + {3080520000 -10800 1 -03} + {3104103600 -14400 0 -04} + {3111969600 -10800 1 -03} + {3135553200 -14400 0 -04} + {3143419200 -10800 1 -03} + {3167002800 -14400 0 -04} + {3174868800 -10800 1 -03} + {3198452400 -14400 0 -04} + {3206318400 -10800 1 -03} + {3230506800 -14400 0 -04} + {3238372800 -10800 1 -03} + {3261956400 -14400 0 -04} + {3269822400 -10800 1 -03} + {3293406000 -14400 0 -04} + {3301272000 -10800 1 -03} + {3324855600 -14400 0 -04} + {3332721600 -10800 1 -03} + {3356305200 -14400 0 -04} + {3364171200 -10800 1 -03} + {3387754800 -14400 0 -04} + {3396225600 -10800 1 -03} + {3419809200 -14400 0 -04} + {3427675200 -10800 1 -03} + {3451258800 -14400 0 -04} + {3459124800 -10800 1 -03} + {3482708400 -14400 0 -04} + {3490574400 -10800 1 -03} + {3514158000 -14400 0 -04} + {3522024000 -10800 1 -03} + {3545607600 -14400 0 -04} + {3553473600 -10800 1 -03} + {3577057200 -14400 0 -04} + {3585528000 -10800 1 -03} + {3609111600 -14400 0 -04} + {3616977600 -10800 1 -03} + {3640561200 -14400 0 -04} + {3648427200 -10800 1 -03} + {3672010800 -14400 0 -04} + {3679876800 -10800 1 -03} + {3703460400 -14400 0 -04} + {3711326400 -10800 1 -03} + {3734910000 -14400 0 -04} + {3743380800 -10800 1 -03} + {3766964400 -14400 0 -04} + {3774830400 -10800 1 -03} + {3798414000 -14400 0 -04} + {3806280000 -10800 1 -03} + {3829863600 -14400 0 -04} + {3837729600 -10800 1 -03} + {3861313200 -14400 0 -04} + {3869179200 -10800 1 -03} + {3892762800 -14400 0 -04} + {3900628800 -10800 1 -03} + {3924212400 -14400 0 -04} + {3932683200 -10800 1 -03} + {3956266800 -14400 0 -04} + {3964132800 -10800 1 -03} + {3987716400 -14400 0 -04} + {3995582400 -10800 1 -03} + {4019166000 -14400 0 -04} + {4027032000 -10800 1 -03} + {4050615600 -14400 0 -04} + {4058481600 -10800 1 -03} + {4082065200 -14400 0 -04} + {4089931200 -10800 1 -03} } diff --git a/library/tzdata/America/Santo_Domingo b/library/tzdata/America/Santo_Domingo index 7706918..28d3a9c 100644 --- a/library/tzdata/America/Santo_Domingo +++ b/library/tzdata/America/Santo_Domingo @@ -6,15 +6,15 @@ set TZData(:America/Santo_Domingo) { {-1159773600 -18000 0 EST} {-100119600 -14400 1 EDT} {-89668800 -18000 0 EST} - {-5770800 -16200 1 EHDT} + {-5770800 -16200 1 -0430} {4422600 -18000 0 EST} - {25678800 -16200 1 EHDT} + {25678800 -16200 1 -0430} {33193800 -18000 0 EST} - {57733200 -16200 1 EHDT} + {57733200 -16200 1 -0430} {64816200 -18000 0 EST} - {89182800 -16200 1 EHDT} + {89182800 -16200 1 -0430} {96438600 -18000 0 EST} - {120632400 -16200 1 EHDT} + {120632400 -16200 1 -0430} {127974600 -18000 0 EST} {152082000 -14400 0 AST} {975823200 -14400 0 AST} diff --git a/library/tzdata/America/Sao_Paulo b/library/tzdata/America/Sao_Paulo index 8d70063..a61c638 100644 --- a/library/tzdata/America/Sao_Paulo +++ b/library/tzdata/America/Sao_Paulo @@ -2,257 +2,257 @@ set TZData(:America/Sao_Paulo) { {-9223372036854775808 -11188 0 LMT} - {-1767214412 -10800 0 BRT} - {-1206957600 -7200 1 BRST} - {-1191362400 -10800 0 BRT} - {-1175374800 -7200 1 BRST} - {-1159826400 -10800 0 BRT} - {-633819600 -7200 1 BRST} - {-622069200 -10800 0 BRT} - {-602283600 -7200 1 BRST} - {-591832800 -10800 0 BRT} - {-570747600 -7200 1 BRST} - {-560210400 -10800 0 BRT} - {-539125200 -7200 1 BRST} - {-531352800 -10800 0 BRT} - {-195429600 -7200 1 BRST} - {-189381600 -7200 0 BRT} - {-184197600 -10800 0 BRT} - {-155163600 -7200 1 BRST} - {-150069600 -10800 0 BRT} - {-128898000 -7200 1 BRST} - {-121125600 -10800 0 BRT} - {-99954000 -7200 1 BRST} - {-89589600 -10800 0 BRT} - {-68418000 -7200 1 BRST} - {-57967200 -10800 0 BRT} - {499748400 -7200 1 BRST} - {511236000 -10800 0 BRT} - {530593200 -7200 1 BRST} - {540266400 -10800 0 BRT} - {562129200 -7200 1 BRST} - {571197600 -10800 0 BRT} - {592974000 -7200 1 BRST} - {602042400 -10800 0 BRT} - {624423600 -7200 1 BRST} - {634701600 -10800 0 BRT} - {656478000 -7200 1 BRST} - {666756000 -10800 0 BRT} - {687927600 -7200 1 BRST} - {697600800 -10800 0 BRT} - {719982000 -7200 1 BRST} - {728445600 -10800 0 BRT} - {750826800 -7200 1 BRST} - {761709600 -10800 0 BRT} - {782276400 -7200 1 BRST} - {793159200 -10800 0 BRT} - {813726000 -7200 1 BRST} - {824004000 -10800 0 BRT} - {844570800 -7200 1 BRST} - {856058400 -10800 0 BRT} - {876106800 -7200 1 BRST} - {888717600 -10800 0 BRT} - {908074800 -7200 1 BRST} - {919562400 -10800 0 BRT} - {938919600 -7200 1 BRST} - {951616800 -10800 0 BRT} - {970974000 -7200 1 BRST} - {982461600 -10800 0 BRT} - {1003028400 -7200 1 BRST} - {1013911200 -10800 0 BRT} - {1036292400 -7200 1 BRST} - {1045360800 -10800 0 BRT} - {1066532400 -7200 1 BRST} - {1076810400 -10800 0 BRT} - {1099364400 -7200 1 BRST} - {1108864800 -10800 0 BRT} - {1129431600 -7200 1 BRST} - {1140314400 -10800 0 BRT} - {1162695600 -7200 1 BRST} - {1172368800 -10800 0 BRT} - {1192330800 -7200 1 BRST} - {1203213600 -10800 0 BRT} - {1224385200 -7200 1 BRST} - {1234663200 -10800 0 BRT} - {1255834800 -7200 1 BRST} - {1266717600 -10800 0 BRT} - {1287284400 -7200 1 BRST} - {1298167200 -10800 0 BRT} - {1318734000 -7200 1 BRST} - {1330221600 -10800 0 BRT} - {1350788400 -7200 1 BRST} - {1361066400 -10800 0 BRT} - {1382238000 -7200 1 BRST} - {1392516000 -10800 0 BRT} - {1413687600 -7200 1 BRST} - {1424570400 -10800 0 BRT} - {1445137200 -7200 1 BRST} - {1456020000 -10800 0 BRT} - {1476586800 -7200 1 BRST} - {1487469600 -10800 0 BRT} - {1508036400 -7200 1 BRST} - {1518919200 -10800 0 BRT} - {1540090800 -7200 1 BRST} - {1550368800 -10800 0 BRT} - {1571540400 -7200 1 BRST} - {1581818400 -10800 0 BRT} - {1602990000 -7200 1 BRST} - {1613872800 -10800 0 BRT} - {1634439600 -7200 1 BRST} - {1645322400 -10800 0 BRT} - {1665889200 -7200 1 BRST} - {1677376800 -10800 0 BRT} - {1697338800 -7200 1 BRST} - {1708221600 -10800 0 BRT} - {1729393200 -7200 1 BRST} - {1739671200 -10800 0 BRT} - {1760842800 -7200 1 BRST} - {1771725600 -10800 0 BRT} - {1792292400 -7200 1 BRST} - {1803175200 -10800 0 BRT} - {1823742000 -7200 1 BRST} - {1834624800 -10800 0 BRT} - {1855191600 -7200 1 BRST} - {1866074400 -10800 0 BRT} - {1887246000 -7200 1 BRST} - {1897524000 -10800 0 BRT} - {1918695600 -7200 1 BRST} - {1928973600 -10800 0 BRT} - {1950145200 -7200 1 BRST} - {1960423200 -10800 0 BRT} - {1981594800 -7200 1 BRST} - {1992477600 -10800 0 BRT} - {2013044400 -7200 1 BRST} - {2024532000 -10800 0 BRT} - {2044494000 -7200 1 BRST} - {2055376800 -10800 0 BRT} - {2076548400 -7200 1 BRST} - {2086826400 -10800 0 BRT} - {2107998000 -7200 1 BRST} - {2118880800 -10800 0 BRT} - {2139447600 -7200 1 BRST} - {2150330400 -10800 0 BRT} - {2170897200 -7200 1 BRST} - {2181780000 -10800 0 BRT} - {2202346800 -7200 1 BRST} - {2213229600 -10800 0 BRT} - {2234401200 -7200 1 BRST} - {2244679200 -10800 0 BRT} - {2265850800 -7200 1 BRST} - {2276128800 -10800 0 BRT} - {2297300400 -7200 1 BRST} - {2307578400 -10800 0 BRT} - {2328750000 -7200 1 BRST} - {2339632800 -10800 0 BRT} - {2360199600 -7200 1 BRST} - {2371082400 -10800 0 BRT} - {2391649200 -7200 1 BRST} - {2402532000 -10800 0 BRT} - {2423703600 -7200 1 BRST} - {2433981600 -10800 0 BRT} - {2455153200 -7200 1 BRST} - {2465431200 -10800 0 BRT} - {2486602800 -7200 1 BRST} - {2497485600 -10800 0 BRT} - {2518052400 -7200 1 BRST} - {2528935200 -10800 0 BRT} - {2549502000 -7200 1 BRST} - {2560384800 -10800 0 BRT} - {2580951600 -7200 1 BRST} - {2591834400 -10800 0 BRT} - {2613006000 -7200 1 BRST} - {2623284000 -10800 0 BRT} - {2644455600 -7200 1 BRST} - {2654733600 -10800 0 BRT} - {2675905200 -7200 1 BRST} - {2686788000 -10800 0 BRT} - {2707354800 -7200 1 BRST} - {2718237600 -10800 0 BRT} - {2738804400 -7200 1 BRST} - {2749687200 -10800 0 BRT} - {2770858800 -7200 1 BRST} - {2781136800 -10800 0 BRT} - {2802308400 -7200 1 BRST} - {2812586400 -10800 0 BRT} - {2833758000 -7200 1 BRST} - {2844036000 -10800 0 BRT} - {2865207600 -7200 1 BRST} - {2876090400 -10800 0 BRT} - {2896657200 -7200 1 BRST} - {2907540000 -10800 0 BRT} - {2928106800 -7200 1 BRST} - {2938989600 -10800 0 BRT} - {2960161200 -7200 1 BRST} - {2970439200 -10800 0 BRT} - {2991610800 -7200 1 BRST} - {3001888800 -10800 0 BRT} - {3023060400 -7200 1 BRST} - {3033943200 -10800 0 BRT} - {3054510000 -7200 1 BRST} - {3065392800 -10800 0 BRT} - {3085959600 -7200 1 BRST} - {3096842400 -10800 0 BRT} - {3118014000 -7200 1 BRST} - {3128292000 -10800 0 BRT} - {3149463600 -7200 1 BRST} - {3159741600 -10800 0 BRT} - {3180913200 -7200 1 BRST} - {3191191200 -10800 0 BRT} - {3212362800 -7200 1 BRST} - {3223245600 -10800 0 BRT} - {3243812400 -7200 1 BRST} - {3254695200 -10800 0 BRT} - {3275262000 -7200 1 BRST} - {3286144800 -10800 0 BRT} - {3307316400 -7200 1 BRST} - {3317594400 -10800 0 BRT} - {3338766000 -7200 1 BRST} - {3349044000 -10800 0 BRT} - {3370215600 -7200 1 BRST} - {3381098400 -10800 0 BRT} - {3401665200 -7200 1 BRST} - {3412548000 -10800 0 BRT} - {3433114800 -7200 1 BRST} - {3443997600 -10800 0 BRT} - {3464564400 -7200 1 BRST} - {3475447200 -10800 0 BRT} - {3496618800 -7200 1 BRST} - {3506896800 -10800 0 BRT} - {3528068400 -7200 1 BRST} - {3538346400 -10800 0 BRT} - {3559518000 -7200 1 BRST} - {3570400800 -10800 0 BRT} - {3590967600 -7200 1 BRST} - {3601850400 -10800 0 BRT} - {3622417200 -7200 1 BRST} - {3633300000 -10800 0 BRT} - {3654471600 -7200 1 BRST} - {3664749600 -10800 0 BRT} - {3685921200 -7200 1 BRST} - {3696199200 -10800 0 BRT} - {3717370800 -7200 1 BRST} - {3727648800 -10800 0 BRT} - {3748820400 -7200 1 BRST} - {3759703200 -10800 0 BRT} - {3780270000 -7200 1 BRST} - {3791152800 -10800 0 BRT} - {3811719600 -7200 1 BRST} - {3822602400 -10800 0 BRT} - {3843774000 -7200 1 BRST} - {3854052000 -10800 0 BRT} - {3875223600 -7200 1 BRST} - {3885501600 -10800 0 BRT} - {3906673200 -7200 1 BRST} - {3917556000 -10800 0 BRT} - {3938122800 -7200 1 BRST} - {3949005600 -10800 0 BRT} - {3969572400 -7200 1 BRST} - {3980455200 -10800 0 BRT} - {4001626800 -7200 1 BRST} - {4011904800 -10800 0 BRT} - {4033076400 -7200 1 BRST} - {4043354400 -10800 0 BRT} - {4064526000 -7200 1 BRST} - {4074804000 -10800 0 BRT} - {4095975600 -7200 1 BRST} + {-1767214412 -10800 0 -03} + {-1206957600 -7200 1 -02} + {-1191362400 -10800 0 -03} + {-1175374800 -7200 1 -02} + {-1159826400 -10800 0 -03} + {-633819600 -7200 1 -02} + {-622069200 -10800 0 -03} + {-602283600 -7200 1 -02} + {-591832800 -10800 0 -03} + {-570747600 -7200 1 -02} + {-560210400 -10800 0 -03} + {-539125200 -7200 1 -02} + {-531352800 -10800 0 -03} + {-195429600 -7200 1 -02} + {-189381600 -7200 0 -03} + {-184197600 -10800 0 -03} + {-155163600 -7200 1 -02} + {-150069600 -10800 0 -03} + {-128898000 -7200 1 -02} + {-121125600 -10800 0 -03} + {-99954000 -7200 1 -02} + {-89589600 -10800 0 -03} + {-68418000 -7200 1 -02} + {-57967200 -10800 0 -03} + {499748400 -7200 1 -02} + {511236000 -10800 0 -03} + {530593200 -7200 1 -02} + {540266400 -10800 0 -03} + {562129200 -7200 1 -02} + {571197600 -10800 0 -03} + {592974000 -7200 1 -02} + {602042400 -10800 0 -03} + {624423600 -7200 1 -02} + {634701600 -10800 0 -03} + {656478000 -7200 1 -02} + {666756000 -10800 0 -03} + {687927600 -7200 1 -02} + {697600800 -10800 0 -03} + {719982000 -7200 1 -02} + {728445600 -10800 0 -03} + {750826800 -7200 1 -02} + {761709600 -10800 0 -03} + {782276400 -7200 1 -02} + {793159200 -10800 0 -03} + {813726000 -7200 1 -02} + {824004000 -10800 0 -03} + {844570800 -7200 1 -02} + {856058400 -10800 0 -03} + {876106800 -7200 1 -02} + {888717600 -10800 0 -03} + {908074800 -7200 1 -02} + {919562400 -10800 0 -03} + {938919600 -7200 1 -02} + {951616800 -10800 0 -03} + {970974000 -7200 1 -02} + {982461600 -10800 0 -03} + {1003028400 -7200 1 -02} + {1013911200 -10800 0 -03} + {1036292400 -7200 1 -02} + {1045360800 -10800 0 -03} + {1066532400 -7200 1 -02} + {1076810400 -10800 0 -03} + {1099364400 -7200 1 -02} + {1108864800 -10800 0 -03} + {1129431600 -7200 1 -02} + {1140314400 -10800 0 -03} + {1162695600 -7200 1 -02} + {1172368800 -10800 0 -03} + {1192330800 -7200 1 -02} + {1203213600 -10800 0 -03} + {1224385200 -7200 1 -02} + {1234663200 -10800 0 -03} + {1255834800 -7200 1 -02} + {1266717600 -10800 0 -03} + {1287284400 -7200 1 -02} + {1298167200 -10800 0 -03} + {1318734000 -7200 1 -02} + {1330221600 -10800 0 -03} + {1350788400 -7200 1 -02} + {1361066400 -10800 0 -03} + {1382238000 -7200 1 -02} + {1392516000 -10800 0 -03} + {1413687600 -7200 1 -02} + {1424570400 -10800 0 -03} + {1445137200 -7200 1 -02} + {1456020000 -10800 0 -03} + {1476586800 -7200 1 -02} + {1487469600 -10800 0 -03} + {1508036400 -7200 1 -02} + {1518919200 -10800 0 -03} + {1540090800 -7200 1 -02} + {1550368800 -10800 0 -03} + {1571540400 -7200 1 -02} + {1581818400 -10800 0 -03} + {1602990000 -7200 1 -02} + {1613872800 -10800 0 -03} + {1634439600 -7200 1 -02} + {1645322400 -10800 0 -03} + {1665889200 -7200 1 -02} + {1677376800 -10800 0 -03} + {1697338800 -7200 1 -02} + {1708221600 -10800 0 -03} + {1729393200 -7200 1 -02} + {1739671200 -10800 0 -03} + {1760842800 -7200 1 -02} + {1771725600 -10800 0 -03} + {1792292400 -7200 1 -02} + {1803175200 -10800 0 -03} + {1823742000 -7200 1 -02} + {1834624800 -10800 0 -03} + {1855191600 -7200 1 -02} + {1866074400 -10800 0 -03} + {1887246000 -7200 1 -02} + {1897524000 -10800 0 -03} + {1918695600 -7200 1 -02} + {1928973600 -10800 0 -03} + {1950145200 -7200 1 -02} + {1960423200 -10800 0 -03} + {1981594800 -7200 1 -02} + {1992477600 -10800 0 -03} + {2013044400 -7200 1 -02} + {2024532000 -10800 0 -03} + {2044494000 -7200 1 -02} + {2055376800 -10800 0 -03} + {2076548400 -7200 1 -02} + {2086826400 -10800 0 -03} + {2107998000 -7200 1 -02} + {2118880800 -10800 0 -03} + {2139447600 -7200 1 -02} + {2150330400 -10800 0 -03} + {2170897200 -7200 1 -02} + {2181780000 -10800 0 -03} + {2202346800 -7200 1 -02} + {2213229600 -10800 0 -03} + {2234401200 -7200 1 -02} + {2244679200 -10800 0 -03} + {2265850800 -7200 1 -02} + {2276128800 -10800 0 -03} + {2297300400 -7200 1 -02} + {2307578400 -10800 0 -03} + {2328750000 -7200 1 -02} + {2339632800 -10800 0 -03} + {2360199600 -7200 1 -02} + {2371082400 -10800 0 -03} + {2391649200 -7200 1 -02} + {2402532000 -10800 0 -03} + {2423703600 -7200 1 -02} + {2433981600 -10800 0 -03} + {2455153200 -7200 1 -02} + {2465431200 -10800 0 -03} + {2486602800 -7200 1 -02} + {2497485600 -10800 0 -03} + {2518052400 -7200 1 -02} + {2528935200 -10800 0 -03} + {2549502000 -7200 1 -02} + {2560384800 -10800 0 -03} + {2580951600 -7200 1 -02} + {2591834400 -10800 0 -03} + {2613006000 -7200 1 -02} + {2623284000 -10800 0 -03} + {2644455600 -7200 1 -02} + {2654733600 -10800 0 -03} + {2675905200 -7200 1 -02} + {2686788000 -10800 0 -03} + {2707354800 -7200 1 -02} + {2718237600 -10800 0 -03} + {2738804400 -7200 1 -02} + {2749687200 -10800 0 -03} + {2770858800 -7200 1 -02} + {2781136800 -10800 0 -03} + {2802308400 -7200 1 -02} + {2812586400 -10800 0 -03} + {2833758000 -7200 1 -02} + {2844036000 -10800 0 -03} + {2865207600 -7200 1 -02} + {2876090400 -10800 0 -03} + {2896657200 -7200 1 -02} + {2907540000 -10800 0 -03} + {2928106800 -7200 1 -02} + {2938989600 -10800 0 -03} + {2960161200 -7200 1 -02} + {2970439200 -10800 0 -03} + {2991610800 -7200 1 -02} + {3001888800 -10800 0 -03} + {3023060400 -7200 1 -02} + {3033943200 -10800 0 -03} + {3054510000 -7200 1 -02} + {3065392800 -10800 0 -03} + {3085959600 -7200 1 -02} + {3096842400 -10800 0 -03} + {3118014000 -7200 1 -02} + {3128292000 -10800 0 -03} + {3149463600 -7200 1 -02} + {3159741600 -10800 0 -03} + {3180913200 -7200 1 -02} + {3191191200 -10800 0 -03} + {3212362800 -7200 1 -02} + {3223245600 -10800 0 -03} + {3243812400 -7200 1 -02} + {3254695200 -10800 0 -03} + {3275262000 -7200 1 -02} + {3286144800 -10800 0 -03} + {3307316400 -7200 1 -02} + {3317594400 -10800 0 -03} + {3338766000 -7200 1 -02} + {3349044000 -10800 0 -03} + {3370215600 -7200 1 -02} + {3381098400 -10800 0 -03} + {3401665200 -7200 1 -02} + {3412548000 -10800 0 -03} + {3433114800 -7200 1 -02} + {3443997600 -10800 0 -03} + {3464564400 -7200 1 -02} + {3475447200 -10800 0 -03} + {3496618800 -7200 1 -02} + {3506896800 -10800 0 -03} + {3528068400 -7200 1 -02} + {3538346400 -10800 0 -03} + {3559518000 -7200 1 -02} + {3570400800 -10800 0 -03} + {3590967600 -7200 1 -02} + {3601850400 -10800 0 -03} + {3622417200 -7200 1 -02} + {3633300000 -10800 0 -03} + {3654471600 -7200 1 -02} + {3664749600 -10800 0 -03} + {3685921200 -7200 1 -02} + {3696199200 -10800 0 -03} + {3717370800 -7200 1 -02} + {3727648800 -10800 0 -03} + {3748820400 -7200 1 -02} + {3759703200 -10800 0 -03} + {3780270000 -7200 1 -02} + {3791152800 -10800 0 -03} + {3811719600 -7200 1 -02} + {3822602400 -10800 0 -03} + {3843774000 -7200 1 -02} + {3854052000 -10800 0 -03} + {3875223600 -7200 1 -02} + {3885501600 -10800 0 -03} + {3906673200 -7200 1 -02} + {3917556000 -10800 0 -03} + {3938122800 -7200 1 -02} + {3949005600 -10800 0 -03} + {3969572400 -7200 1 -02} + {3980455200 -10800 0 -03} + {4001626800 -7200 1 -02} + {4011904800 -10800 0 -03} + {4033076400 -7200 1 -02} + {4043354400 -10800 0 -03} + {4064526000 -7200 1 -02} + {4074804000 -10800 0 -03} + {4095975600 -7200 1 -02} } diff --git a/library/tzdata/America/Scoresbysund b/library/tzdata/America/Scoresbysund index 74a332c..7430635 100644 --- a/library/tzdata/America/Scoresbysund +++ b/library/tzdata/America/Scoresbysund @@ -2,245 +2,245 @@ set TZData(:America/Scoresbysund) { {-9223372036854775808 -5272 0 LMT} - {-1686090728 -7200 0 CGT} - {323841600 -3600 0 CGST} - {338961600 -7200 0 CGT} - {354679200 0 0 EGST} - {370400400 -3600 0 EGT} - {386125200 0 1 EGST} - {401850000 -3600 0 EGT} - {417574800 0 1 EGST} - {433299600 -3600 0 EGT} - {449024400 0 1 EGST} - {465354000 -3600 0 EGT} - {481078800 0 1 EGST} - {496803600 -3600 0 EGT} - {512528400 0 1 EGST} - {528253200 -3600 0 EGT} - {543978000 0 1 EGST} - {559702800 -3600 0 EGT} - {575427600 0 1 EGST} - {591152400 -3600 0 EGT} - {606877200 0 1 EGST} - {622602000 -3600 0 EGT} - {638326800 0 1 EGST} - {654656400 -3600 0 EGT} - {670381200 0 1 EGST} - {686106000 -3600 0 EGT} - {701830800 0 1 EGST} - {717555600 -3600 0 EGT} - {733280400 0 1 EGST} - {749005200 -3600 0 EGT} - {764730000 0 1 EGST} - {780454800 -3600 0 EGT} - {796179600 0 1 EGST} - {811904400 -3600 0 EGT} - {828234000 0 1 EGST} - {846378000 -3600 0 EGT} - {859683600 0 1 EGST} - {877827600 -3600 0 EGT} - {891133200 0 1 EGST} - {909277200 -3600 0 EGT} - {922582800 0 1 EGST} - {941331600 -3600 0 EGT} - {954032400 0 1 EGST} - {972781200 -3600 0 EGT} - {985482000 0 1 EGST} - {1004230800 -3600 0 EGT} - {1017536400 0 1 EGST} - {1035680400 -3600 0 EGT} - {1048986000 0 1 EGST} - {1067130000 -3600 0 EGT} - {1080435600 0 1 EGST} - {1099184400 -3600 0 EGT} - {1111885200 0 1 EGST} - {1130634000 -3600 0 EGT} - {1143334800 0 1 EGST} - {1162083600 -3600 0 EGT} - {1174784400 0 1 EGST} - {1193533200 -3600 0 EGT} - {1206838800 0 1 EGST} - {1224982800 -3600 0 EGT} - {1238288400 0 1 EGST} - {1256432400 -3600 0 EGT} - {1269738000 0 1 EGST} - {1288486800 -3600 0 EGT} - {1301187600 0 1 EGST} - {1319936400 -3600 0 EGT} - {1332637200 0 1 EGST} - {1351386000 -3600 0 EGT} - {1364691600 0 1 EGST} - {1382835600 -3600 0 EGT} - {1396141200 0 1 EGST} - {1414285200 -3600 0 EGT} - {1427590800 0 1 EGST} - {1445734800 -3600 0 EGT} - {1459040400 0 1 EGST} - {1477789200 -3600 0 EGT} - {1490490000 0 1 EGST} - {1509238800 -3600 0 EGT} - {1521939600 0 1 EGST} - {1540688400 -3600 0 EGT} - {1553994000 0 1 EGST} - {1572138000 -3600 0 EGT} - {1585443600 0 1 EGST} - {1603587600 -3600 0 EGT} - {1616893200 0 1 EGST} - {1635642000 -3600 0 EGT} - {1648342800 0 1 EGST} - {1667091600 -3600 0 EGT} - {1679792400 0 1 EGST} - {1698541200 -3600 0 EGT} - {1711846800 0 1 EGST} - {1729990800 -3600 0 EGT} - {1743296400 0 1 EGST} - {1761440400 -3600 0 EGT} - {1774746000 0 1 EGST} - {1792890000 -3600 0 EGT} - {1806195600 0 1 EGST} - {1824944400 -3600 0 EGT} - {1837645200 0 1 EGST} - {1856394000 -3600 0 EGT} - {1869094800 0 1 EGST} - {1887843600 -3600 0 EGT} - {1901149200 0 1 EGST} - {1919293200 -3600 0 EGT} - {1932598800 0 1 EGST} - {1950742800 -3600 0 EGT} - {1964048400 0 1 EGST} - {1982797200 -3600 0 EGT} - {1995498000 0 1 EGST} - {2014246800 -3600 0 EGT} - {2026947600 0 1 EGST} - {2045696400 -3600 0 EGT} - {2058397200 0 1 EGST} - {2077146000 -3600 0 EGT} - {2090451600 0 1 EGST} - {2108595600 -3600 0 EGT} - {2121901200 0 1 EGST} - {2140045200 -3600 0 EGT} - {2153350800 0 1 EGST} - {2172099600 -3600 0 EGT} - {2184800400 0 1 EGST} - {2203549200 -3600 0 EGT} - {2216250000 0 1 EGST} - {2234998800 -3600 0 EGT} - {2248304400 0 1 EGST} - {2266448400 -3600 0 EGT} - {2279754000 0 1 EGST} - {2297898000 -3600 0 EGT} - {2311203600 0 1 EGST} - {2329347600 -3600 0 EGT} - {2342653200 0 1 EGST} - {2361402000 -3600 0 EGT} - {2374102800 0 1 EGST} - {2392851600 -3600 0 EGT} - {2405552400 0 1 EGST} - {2424301200 -3600 0 EGT} - {2437606800 0 1 EGST} - {2455750800 -3600 0 EGT} - {2469056400 0 1 EGST} - {2487200400 -3600 0 EGT} - {2500506000 0 1 EGST} - {2519254800 -3600 0 EGT} - {2531955600 0 1 EGST} - {2550704400 -3600 0 EGT} - {2563405200 0 1 EGST} - {2582154000 -3600 0 EGT} - {2595459600 0 1 EGST} - {2613603600 -3600 0 EGT} - {2626909200 0 1 EGST} - {2645053200 -3600 0 EGT} - {2658358800 0 1 EGST} - {2676502800 -3600 0 EGT} - {2689808400 0 1 EGST} - {2708557200 -3600 0 EGT} - {2721258000 0 1 EGST} - {2740006800 -3600 0 EGT} - {2752707600 0 1 EGST} - {2771456400 -3600 0 EGT} - {2784762000 0 1 EGST} - {2802906000 -3600 0 EGT} - {2816211600 0 1 EGST} - {2834355600 -3600 0 EGT} - {2847661200 0 1 EGST} - {2866410000 -3600 0 EGT} - {2879110800 0 1 EGST} - {2897859600 -3600 0 EGT} - {2910560400 0 1 EGST} - {2929309200 -3600 0 EGT} - {2942010000 0 1 EGST} - {2960758800 -3600 0 EGT} - {2974064400 0 1 EGST} - {2992208400 -3600 0 EGT} - {3005514000 0 1 EGST} - {3023658000 -3600 0 EGT} - {3036963600 0 1 EGST} - {3055712400 -3600 0 EGT} - {3068413200 0 1 EGST} - {3087162000 -3600 0 EGT} - {3099862800 0 1 EGST} - {3118611600 -3600 0 EGT} - {3131917200 0 1 EGST} - {3150061200 -3600 0 EGT} - {3163366800 0 1 EGST} - {3181510800 -3600 0 EGT} - {3194816400 0 1 EGST} - {3212960400 -3600 0 EGT} - {3226266000 0 1 EGST} - {3245014800 -3600 0 EGT} - {3257715600 0 1 EGST} - {3276464400 -3600 0 EGT} - {3289165200 0 1 EGST} - {3307914000 -3600 0 EGT} - {3321219600 0 1 EGST} - {3339363600 -3600 0 EGT} - {3352669200 0 1 EGST} - {3370813200 -3600 0 EGT} - {3384118800 0 1 EGST} - {3402867600 -3600 0 EGT} - {3415568400 0 1 EGST} - {3434317200 -3600 0 EGT} - {3447018000 0 1 EGST} - {3465766800 -3600 0 EGT} - {3479072400 0 1 EGST} - {3497216400 -3600 0 EGT} - {3510522000 0 1 EGST} - {3528666000 -3600 0 EGT} - {3541971600 0 1 EGST} - {3560115600 -3600 0 EGT} - {3573421200 0 1 EGST} - {3592170000 -3600 0 EGT} - {3604870800 0 1 EGST} - {3623619600 -3600 0 EGT} - {3636320400 0 1 EGST} - {3655069200 -3600 0 EGT} - {3668374800 0 1 EGST} - {3686518800 -3600 0 EGT} - {3699824400 0 1 EGST} - {3717968400 -3600 0 EGT} - {3731274000 0 1 EGST} - {3750022800 -3600 0 EGT} - {3762723600 0 1 EGST} - {3781472400 -3600 0 EGT} - {3794173200 0 1 EGST} - {3812922000 -3600 0 EGT} - {3825622800 0 1 EGST} - {3844371600 -3600 0 EGT} - {3857677200 0 1 EGST} - {3875821200 -3600 0 EGT} - {3889126800 0 1 EGST} - {3907270800 -3600 0 EGT} - {3920576400 0 1 EGST} - {3939325200 -3600 0 EGT} - {3952026000 0 1 EGST} - {3970774800 -3600 0 EGT} - {3983475600 0 1 EGST} - {4002224400 -3600 0 EGT} - {4015530000 0 1 EGST} - {4033674000 -3600 0 EGT} - {4046979600 0 1 EGST} - {4065123600 -3600 0 EGT} - {4078429200 0 1 EGST} - {4096573200 -3600 0 EGT} + {-1686090728 -7200 0 -02} + {323841600 -3600 0 -01} + {338961600 -7200 0 -02} + {354679200 0 0 +00} + {370400400 -3600 0 -01} + {386125200 0 1 +00} + {401850000 -3600 0 -01} + {417574800 0 1 +00} + {433299600 -3600 0 -01} + {449024400 0 1 +00} + {465354000 -3600 0 -01} + {481078800 0 1 +00} + {496803600 -3600 0 -01} + {512528400 0 1 +00} + {528253200 -3600 0 -01} + {543978000 0 1 +00} + {559702800 -3600 0 -01} + {575427600 0 1 +00} + {591152400 -3600 0 -01} + {606877200 0 1 +00} + {622602000 -3600 0 -01} + {638326800 0 1 +00} + {654656400 -3600 0 -01} + {670381200 0 1 +00} + {686106000 -3600 0 -01} + {701830800 0 1 +00} + {717555600 -3600 0 -01} + {733280400 0 1 +00} + {749005200 -3600 0 -01} + {764730000 0 1 +00} + {780454800 -3600 0 -01} + {796179600 0 1 +00} + {811904400 -3600 0 -01} + {828234000 0 1 +00} + {846378000 -3600 0 -01} + {859683600 0 1 +00} + {877827600 -3600 0 -01} + {891133200 0 1 +00} + {909277200 -3600 0 -01} + {922582800 0 1 +00} + {941331600 -3600 0 -01} + {954032400 0 1 +00} + {972781200 -3600 0 -01} + {985482000 0 1 +00} + {1004230800 -3600 0 -01} + {1017536400 0 1 +00} + {1035680400 -3600 0 -01} + {1048986000 0 1 +00} + {1067130000 -3600 0 -01} + {1080435600 0 1 +00} + {1099184400 -3600 0 -01} + {1111885200 0 1 +00} + {1130634000 -3600 0 -01} + {1143334800 0 1 +00} + {1162083600 -3600 0 -01} + {1174784400 0 1 +00} + {1193533200 -3600 0 -01} + {1206838800 0 1 +00} + {1224982800 -3600 0 -01} + {1238288400 0 1 +00} + {1256432400 -3600 0 -01} + {1269738000 0 1 +00} + {1288486800 -3600 0 -01} + {1301187600 0 1 +00} + {1319936400 -3600 0 -01} + {1332637200 0 1 +00} + {1351386000 -3600 0 -01} + {1364691600 0 1 +00} + {1382835600 -3600 0 -01} + {1396141200 0 1 +00} + {1414285200 -3600 0 -01} + {1427590800 0 1 +00} + {1445734800 -3600 0 -01} + {1459040400 0 1 +00} + {1477789200 -3600 0 -01} + {1490490000 0 1 +00} + {1509238800 -3600 0 -01} + {1521939600 0 1 +00} + {1540688400 -3600 0 -01} + {1553994000 0 1 +00} + {1572138000 -3600 0 -01} + {1585443600 0 1 +00} + {1603587600 -3600 0 -01} + {1616893200 0 1 +00} + {1635642000 -3600 0 -01} + {1648342800 0 1 +00} + {1667091600 -3600 0 -01} + {1679792400 0 1 +00} + {1698541200 -3600 0 -01} + {1711846800 0 1 +00} + {1729990800 -3600 0 -01} + {1743296400 0 1 +00} + {1761440400 -3600 0 -01} + {1774746000 0 1 +00} + {1792890000 -3600 0 -01} + {1806195600 0 1 +00} + {1824944400 -3600 0 -01} + {1837645200 0 1 +00} + {1856394000 -3600 0 -01} + {1869094800 0 1 +00} + {1887843600 -3600 0 -01} + {1901149200 0 1 +00} + {1919293200 -3600 0 -01} + {1932598800 0 1 +00} + {1950742800 -3600 0 -01} + {1964048400 0 1 +00} + {1982797200 -3600 0 -01} + {1995498000 0 1 +00} + {2014246800 -3600 0 -01} + {2026947600 0 1 +00} + {2045696400 -3600 0 -01} + {2058397200 0 1 +00} + {2077146000 -3600 0 -01} + {2090451600 0 1 +00} + {2108595600 -3600 0 -01} + {2121901200 0 1 +00} + {2140045200 -3600 0 -01} + {2153350800 0 1 +00} + {2172099600 -3600 0 -01} + {2184800400 0 1 +00} + {2203549200 -3600 0 -01} + {2216250000 0 1 +00} + {2234998800 -3600 0 -01} + {2248304400 0 1 +00} + {2266448400 -3600 0 -01} + {2279754000 0 1 +00} + {2297898000 -3600 0 -01} + {2311203600 0 1 +00} + {2329347600 -3600 0 -01} + {2342653200 0 1 +00} + {2361402000 -3600 0 -01} + {2374102800 0 1 +00} + {2392851600 -3600 0 -01} + {2405552400 0 1 +00} + {2424301200 -3600 0 -01} + {2437606800 0 1 +00} + {2455750800 -3600 0 -01} + {2469056400 0 1 +00} + {2487200400 -3600 0 -01} + {2500506000 0 1 +00} + {2519254800 -3600 0 -01} + {2531955600 0 1 +00} + {2550704400 -3600 0 -01} + {2563405200 0 1 +00} + {2582154000 -3600 0 -01} + {2595459600 0 1 +00} + {2613603600 -3600 0 -01} + {2626909200 0 1 +00} + {2645053200 -3600 0 -01} + {2658358800 0 1 +00} + {2676502800 -3600 0 -01} + {2689808400 0 1 +00} + {2708557200 -3600 0 -01} + {2721258000 0 1 +00} + {2740006800 -3600 0 -01} + {2752707600 0 1 +00} + {2771456400 -3600 0 -01} + {2784762000 0 1 +00} + {2802906000 -3600 0 -01} + {2816211600 0 1 +00} + {2834355600 -3600 0 -01} + {2847661200 0 1 +00} + {2866410000 -3600 0 -01} + {2879110800 0 1 +00} + {2897859600 -3600 0 -01} + {2910560400 0 1 +00} + {2929309200 -3600 0 -01} + {2942010000 0 1 +00} + {2960758800 -3600 0 -01} + {2974064400 0 1 +00} + {2992208400 -3600 0 -01} + {3005514000 0 1 +00} + {3023658000 -3600 0 -01} + {3036963600 0 1 +00} + {3055712400 -3600 0 -01} + {3068413200 0 1 +00} + {3087162000 -3600 0 -01} + {3099862800 0 1 +00} + {3118611600 -3600 0 -01} + {3131917200 0 1 +00} + {3150061200 -3600 0 -01} + {3163366800 0 1 +00} + {3181510800 -3600 0 -01} + {3194816400 0 1 +00} + {3212960400 -3600 0 -01} + {3226266000 0 1 +00} + {3245014800 -3600 0 -01} + {3257715600 0 1 +00} + {3276464400 -3600 0 -01} + {3289165200 0 1 +00} + {3307914000 -3600 0 -01} + {3321219600 0 1 +00} + {3339363600 -3600 0 -01} + {3352669200 0 1 +00} + {3370813200 -3600 0 -01} + {3384118800 0 1 +00} + {3402867600 -3600 0 -01} + {3415568400 0 1 +00} + {3434317200 -3600 0 -01} + {3447018000 0 1 +00} + {3465766800 -3600 0 -01} + {3479072400 0 1 +00} + {3497216400 -3600 0 -01} + {3510522000 0 1 +00} + {3528666000 -3600 0 -01} + {3541971600 0 1 +00} + {3560115600 -3600 0 -01} + {3573421200 0 1 +00} + {3592170000 -3600 0 -01} + {3604870800 0 1 +00} + {3623619600 -3600 0 -01} + {3636320400 0 1 +00} + {3655069200 -3600 0 -01} + {3668374800 0 1 +00} + {3686518800 -3600 0 -01} + {3699824400 0 1 +00} + {3717968400 -3600 0 -01} + {3731274000 0 1 +00} + {3750022800 -3600 0 -01} + {3762723600 0 1 +00} + {3781472400 -3600 0 -01} + {3794173200 0 1 +00} + {3812922000 -3600 0 -01} + {3825622800 0 1 +00} + {3844371600 -3600 0 -01} + {3857677200 0 1 +00} + {3875821200 -3600 0 -01} + {3889126800 0 1 +00} + {3907270800 -3600 0 -01} + {3920576400 0 1 +00} + {3939325200 -3600 0 -01} + {3952026000 0 1 +00} + {3970774800 -3600 0 -01} + {3983475600 0 1 +00} + {4002224400 -3600 0 -01} + {4015530000 0 1 +00} + {4033674000 -3600 0 -01} + {4046979600 0 1 +00} + {4065123600 -3600 0 -01} + {4078429200 0 1 +00} + {4096573200 -3600 0 -01} } diff --git a/library/tzdata/Antarctica/Macquarie b/library/tzdata/Antarctica/Macquarie index 9ed0630..60bf7a6 100644 --- a/library/tzdata/Antarctica/Macquarie +++ b/library/tzdata/Antarctica/Macquarie @@ -93,5 +93,5 @@ set TZData(:Antarctica/Macquarie) { {1223136000 39600 1 AEDT} {1238860800 36000 0 AEST} {1254585600 39600 1 AEDT} - {1270310400 39600 0 MIST} + {1270310400 39600 0 +11} } diff --git a/library/tzdata/Antarctica/Palmer b/library/tzdata/Antarctica/Palmer index 62b17e1..bb2be4d 100644 --- a/library/tzdata/Antarctica/Palmer +++ b/library/tzdata/Antarctica/Palmer @@ -2,251 +2,86 @@ set TZData(:Antarctica/Palmer) { {-9223372036854775808 0 0 -00} - {-157766400 -14400 0 ART} - {-152654400 -14400 0 ART} - {-132955200 -10800 1 ARST} - {-121122000 -14400 0 ART} - {-101419200 -10800 1 ARST} - {-86821200 -14400 0 ART} - {-71092800 -10800 1 ARST} - {-54766800 -14400 0 ART} - {-39038400 -10800 1 ARST} - {-23317200 -14400 0 ART} - {-7588800 -10800 0 ART} - {128142000 -7200 1 ARST} - {136605600 -10800 0 ART} - {389070000 -14400 0 CLT} - {403070400 -10800 1 CLST} - {416372400 -14400 0 CLT} - {434520000 -10800 1 CLST} - {447822000 -14400 0 CLT} - {466574400 -10800 1 CLST} - {479271600 -14400 0 CLT} - {498024000 -10800 1 CLST} - {510721200 -14400 0 CLT} - {529473600 -10800 1 CLST} - {545194800 -14400 0 CLT} - {560923200 -10800 1 CLST} - {574225200 -14400 0 CLT} - {592372800 -10800 1 CLST} - {605674800 -14400 0 CLT} - {624427200 -10800 1 CLST} - {637124400 -14400 0 CLT} - {653457600 -10800 1 CLST} - {668574000 -14400 0 CLT} - {687326400 -10800 1 CLST} - {700628400 -14400 0 CLT} - {718776000 -10800 1 CLST} - {732078000 -14400 0 CLT} - {750225600 -10800 1 CLST} - {763527600 -14400 0 CLT} - {781675200 -10800 1 CLST} - {794977200 -14400 0 CLT} - {813729600 -10800 1 CLST} - {826426800 -14400 0 CLT} - {845179200 -10800 1 CLST} - {859690800 -14400 0 CLT} - {876628800 -10800 1 CLST} - {889930800 -14400 0 CLT} - {906868800 -10800 1 CLST} - {923194800 -14400 0 CLT} - {939528000 -10800 1 CLST} - {952830000 -14400 0 CLT} - {971582400 -10800 1 CLST} - {984279600 -14400 0 CLT} - {1003032000 -10800 1 CLST} - {1015729200 -14400 0 CLT} - {1034481600 -10800 1 CLST} - {1047178800 -14400 0 CLT} - {1065931200 -10800 1 CLST} - {1079233200 -14400 0 CLT} - {1097380800 -10800 1 CLST} - {1110682800 -14400 0 CLT} - {1128830400 -10800 1 CLST} - {1142132400 -14400 0 CLT} - {1160884800 -10800 1 CLST} - {1173582000 -14400 0 CLT} - {1192334400 -10800 1 CLST} - {1206846000 -14400 0 CLT} - {1223784000 -10800 1 CLST} - {1237086000 -14400 0 CLT} - {1255233600 -10800 1 CLST} - {1270350000 -14400 0 CLT} - {1286683200 -10800 1 CLST} - {1304823600 -14400 0 CLT} - {1313899200 -10800 1 CLST} - {1335668400 -14400 0 CLT} - {1346558400 -10800 1 CLST} - {1367118000 -14400 0 CLT} - {1378612800 -10800 1 CLST} - {1398567600 -14400 0 CLT} - {1410062400 -10800 1 CLST} - {1463281200 -14400 0 CLT} - {1471147200 -10800 1 CLST} - {1494730800 -14400 0 CLT} - {1502596800 -10800 1 CLST} - {1526180400 -14400 0 CLT} - {1534046400 -10800 1 CLST} - {1557630000 -14400 0 CLT} - {1565496000 -10800 1 CLST} - {1589079600 -14400 0 CLT} - {1596945600 -10800 1 CLST} - {1620529200 -14400 0 CLT} - {1629000000 -10800 1 CLST} - {1652583600 -14400 0 CLT} - {1660449600 -10800 1 CLST} - {1684033200 -14400 0 CLT} - {1691899200 -10800 1 CLST} - {1715482800 -14400 0 CLT} - {1723348800 -10800 1 CLST} - {1746932400 -14400 0 CLT} - {1754798400 -10800 1 CLST} - {1778382000 -14400 0 CLT} - {1786248000 -10800 1 CLST} - {1809831600 -14400 0 CLT} - {1818302400 -10800 1 CLST} - {1841886000 -14400 0 CLT} - {1849752000 -10800 1 CLST} - {1873335600 -14400 0 CLT} - {1881201600 -10800 1 CLST} - {1904785200 -14400 0 CLT} - {1912651200 -10800 1 CLST} - {1936234800 -14400 0 CLT} - {1944100800 -10800 1 CLST} - {1967684400 -14400 0 CLT} - {1976155200 -10800 1 CLST} - {1999738800 -14400 0 CLT} - {2007604800 -10800 1 CLST} - {2031188400 -14400 0 CLT} - {2039054400 -10800 1 CLST} - {2062638000 -14400 0 CLT} - {2070504000 -10800 1 CLST} - {2094087600 -14400 0 CLT} - {2101953600 -10800 1 CLST} - {2125537200 -14400 0 CLT} - {2133403200 -10800 1 CLST} - {2156986800 -14400 0 CLT} - {2165457600 -10800 1 CLST} - {2189041200 -14400 0 CLT} - {2196907200 -10800 1 CLST} - {2220490800 -14400 0 CLT} - {2228356800 -10800 1 CLST} - {2251940400 -14400 0 CLT} - {2259806400 -10800 1 CLST} - {2283390000 -14400 0 CLT} - {2291256000 -10800 1 CLST} - {2314839600 -14400 0 CLT} - {2322705600 -10800 1 CLST} - {2346894000 -14400 0 CLT} - {2354760000 -10800 1 CLST} - {2378343600 -14400 0 CLT} - {2386209600 -10800 1 CLST} - {2409793200 -14400 0 CLT} - {2417659200 -10800 1 CLST} - {2441242800 -14400 0 CLT} - {2449108800 -10800 1 CLST} - {2472692400 -14400 0 CLT} - {2480558400 -10800 1 CLST} - {2504142000 -14400 0 CLT} - {2512612800 -10800 1 CLST} - {2536196400 -14400 0 CLT} - {2544062400 -10800 1 CLST} - {2567646000 -14400 0 CLT} - {2575512000 -10800 1 CLST} - {2599095600 -14400 0 CLT} - {2606961600 -10800 1 CLST} - {2630545200 -14400 0 CLT} - {2638411200 -10800 1 CLST} - {2661994800 -14400 0 CLT} - {2669860800 -10800 1 CLST} - {2693444400 -14400 0 CLT} - {2701915200 -10800 1 CLST} - {2725498800 -14400 0 CLT} - {2733364800 -10800 1 CLST} - {2756948400 -14400 0 CLT} - {2764814400 -10800 1 CLST} - {2788398000 -14400 0 CLT} - {2796264000 -10800 1 CLST} - {2819847600 -14400 0 CLT} - {2827713600 -10800 1 CLST} - {2851297200 -14400 0 CLT} - {2859768000 -10800 1 CLST} - {2883351600 -14400 0 CLT} - {2891217600 -10800 1 CLST} - {2914801200 -14400 0 CLT} - {2922667200 -10800 1 CLST} - {2946250800 -14400 0 CLT} - {2954116800 -10800 1 CLST} - {2977700400 -14400 0 CLT} - {2985566400 -10800 1 CLST} - {3009150000 -14400 0 CLT} - {3017016000 -10800 1 CLST} - {3040599600 -14400 0 CLT} - {3049070400 -10800 1 CLST} - {3072654000 -14400 0 CLT} - {3080520000 -10800 1 CLST} - {3104103600 -14400 0 CLT} - {3111969600 -10800 1 CLST} - {3135553200 -14400 0 CLT} - {3143419200 -10800 1 CLST} - {3167002800 -14400 0 CLT} - {3174868800 -10800 1 CLST} - {3198452400 -14400 0 CLT} - {3206318400 -10800 1 CLST} - {3230506800 -14400 0 CLT} - {3238372800 -10800 1 CLST} - {3261956400 -14400 0 CLT} - {3269822400 -10800 1 CLST} - {3293406000 -14400 0 CLT} - {3301272000 -10800 1 CLST} - {3324855600 -14400 0 CLT} - {3332721600 -10800 1 CLST} - {3356305200 -14400 0 CLT} - {3364171200 -10800 1 CLST} - {3387754800 -14400 0 CLT} - {3396225600 -10800 1 CLST} - {3419809200 -14400 0 CLT} - {3427675200 -10800 1 CLST} - {3451258800 -14400 0 CLT} - {3459124800 -10800 1 CLST} - {3482708400 -14400 0 CLT} - {3490574400 -10800 1 CLST} - {3514158000 -14400 0 CLT} - {3522024000 -10800 1 CLST} - {3545607600 -14400 0 CLT} - {3553473600 -10800 1 CLST} - {3577057200 -14400 0 CLT} - {3585528000 -10800 1 CLST} - {3609111600 -14400 0 CLT} - {3616977600 -10800 1 CLST} - {3640561200 -14400 0 CLT} - {3648427200 -10800 1 CLST} - {3672010800 -14400 0 CLT} - {3679876800 -10800 1 CLST} - {3703460400 -14400 0 CLT} - {3711326400 -10800 1 CLST} - {3734910000 -14400 0 CLT} - {3743380800 -10800 1 CLST} - {3766964400 -14400 0 CLT} - {3774830400 -10800 1 CLST} - {3798414000 -14400 0 CLT} - {3806280000 -10800 1 CLST} - {3829863600 -14400 0 CLT} - {3837729600 -10800 1 CLST} - {3861313200 -14400 0 CLT} - {3869179200 -10800 1 CLST} - {3892762800 -14400 0 CLT} - {3900628800 -10800 1 CLST} - {3924212400 -14400 0 CLT} - {3932683200 -10800 1 CLST} - {3956266800 -14400 0 CLT} - {3964132800 -10800 1 CLST} - {3987716400 -14400 0 CLT} - {3995582400 -10800 1 CLST} - {4019166000 -14400 0 CLT} - {4027032000 -10800 1 CLST} - {4050615600 -14400 0 CLT} - {4058481600 -10800 1 CLST} - {4082065200 -14400 0 CLT} - {4089931200 -10800 1 CLST} + {-157766400 -14400 0 -04} + {-152654400 -14400 0 -04} + {-132955200 -10800 1 -03} + {-121122000 -14400 0 -04} + {-101419200 -10800 1 -03} + {-86821200 -14400 0 -04} + {-71092800 -10800 1 -03} + {-54766800 -14400 0 -04} + {-39038400 -10800 1 -03} + {-23317200 -14400 0 -04} + {-7588800 -10800 0 -03} + {128142000 -7200 1 -02} + {136605600 -10800 0 -03} + {389070000 -14400 0 -04} + {403070400 -10800 1 -03} + {416372400 -14400 0 -04} + {434520000 -10800 1 -03} + {447822000 -14400 0 -04} + {466574400 -10800 1 -03} + {479271600 -14400 0 -04} + {498024000 -10800 1 -03} + {510721200 -14400 0 -04} + {529473600 -10800 1 -03} + {545194800 -14400 0 -04} + {560923200 -10800 1 -03} + {574225200 -14400 0 -04} + {592372800 -10800 1 -03} + {605674800 -14400 0 -04} + {624427200 -10800 1 -03} + {637124400 -14400 0 -04} + {653457600 -10800 1 -03} + {668574000 -14400 0 -04} + {687326400 -10800 1 -03} + {700628400 -14400 0 -04} + {718776000 -10800 1 -03} + {732078000 -14400 0 -04} + {750225600 -10800 1 -03} + {763527600 -14400 0 -04} + {781675200 -10800 1 -03} + {794977200 -14400 0 -04} + {813729600 -10800 1 -03} + {826426800 -14400 0 -04} + {845179200 -10800 1 -03} + {859690800 -14400 0 -04} + {876628800 -10800 1 -03} + {889930800 -14400 0 -04} + {906868800 -10800 1 -03} + {923194800 -14400 0 -04} + {939528000 -10800 1 -03} + {952830000 -14400 0 -04} + {971582400 -10800 1 -03} + {984279600 -14400 0 -04} + {1003032000 -10800 1 -03} + {1015729200 -14400 0 -04} + {1034481600 -10800 1 -03} + {1047178800 -14400 0 -04} + {1065931200 -10800 1 -03} + {1079233200 -14400 0 -04} + {1097380800 -10800 1 -03} + {1110682800 -14400 0 -04} + {1128830400 -10800 1 -03} + {1142132400 -14400 0 -04} + {1160884800 -10800 1 -03} + {1173582000 -14400 0 -04} + {1192334400 -10800 1 -03} + {1206846000 -14400 0 -04} + {1223784000 -10800 1 -03} + {1237086000 -14400 0 -04} + {1255233600 -10800 1 -03} + {1270350000 -14400 0 -04} + {1286683200 -10800 1 -03} + {1304823600 -14400 0 -04} + {1313899200 -10800 1 -03} + {1335668400 -14400 0 -04} + {1346558400 -10800 1 -03} + {1367118000 -14400 0 -04} + {1378612800 -10800 1 -03} + {1398567600 -14400 0 -04} + {1410062400 -10800 1 -03} + {1463281200 -14400 0 -04} + {1471147200 -10800 1 -03} + {1480820400 -10800 0 -03} } diff --git a/library/tzdata/Asia/Atyrau b/library/tzdata/Asia/Atyrau index f274540..c31ff11 100644 --- a/library/tzdata/Asia/Atyrau +++ b/library/tzdata/Asia/Atyrau @@ -2,8 +2,8 @@ set TZData(:Asia/Atyrau) { {-9223372036854775808 12464 0 LMT} - {-1441164464 14400 0 +04} - {-1247544000 18000 0 +05} + {-1441164464 10800 0 +03} + {-1247540400 18000 0 +05} {370724400 21600 0 +06} {386445600 18000 0 +05} {386449200 21600 1 +06} diff --git a/library/tzdata/Asia/Baghdad b/library/tzdata/Asia/Baghdad index c1058cb..623e310 100644 --- a/library/tzdata/Asia/Baghdad +++ b/library/tzdata/Asia/Baghdad @@ -3,57 +3,57 @@ set TZData(:Asia/Baghdad) { {-9223372036854775808 10660 0 LMT} {-2524532260 10656 0 BMT} - {-1641005856 10800 0 AST} - {389048400 14400 0 ADT} - {402264000 10800 0 AST} - {417906000 14400 1 ADT} - {433800000 10800 0 AST} - {449614800 14400 1 ADT} - {465422400 10800 0 AST} - {481150800 14400 1 ADT} - {496792800 10800 0 AST} - {512517600 14400 1 ADT} - {528242400 10800 0 AST} - {543967200 14400 1 ADT} - {559692000 10800 0 AST} - {575416800 14400 1 ADT} - {591141600 10800 0 AST} - {606866400 14400 1 ADT} - {622591200 10800 0 AST} - {638316000 14400 1 ADT} - {654645600 10800 0 AST} - {670464000 14400 1 ADT} - {686275200 10800 0 AST} - {702086400 14400 1 ADT} - {717897600 10800 0 AST} - {733622400 14400 1 ADT} - {749433600 10800 0 AST} - {765158400 14400 1 ADT} - {780969600 10800 0 AST} - {796694400 14400 1 ADT} - {812505600 10800 0 AST} - {828316800 14400 1 ADT} - {844128000 10800 0 AST} - {859852800 14400 1 ADT} - {875664000 10800 0 AST} - {891388800 14400 1 ADT} - {907200000 10800 0 AST} - {922924800 14400 1 ADT} - {938736000 10800 0 AST} - {954547200 14400 1 ADT} - {970358400 10800 0 AST} - {986083200 14400 1 ADT} - {1001894400 10800 0 AST} - {1017619200 14400 1 ADT} - {1033430400 10800 0 AST} - {1049155200 14400 1 ADT} - {1064966400 10800 0 AST} - {1080777600 14400 1 ADT} - {1096588800 10800 0 AST} - {1112313600 14400 1 ADT} - {1128124800 10800 0 AST} - {1143849600 14400 1 ADT} - {1159660800 10800 0 AST} - {1175385600 14400 1 ADT} - {1191196800 10800 0 AST} + {-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} } diff --git a/library/tzdata/Asia/Bangkok b/library/tzdata/Asia/Bangkok index 6df7680..aeb5473 100644 --- a/library/tzdata/Asia/Bangkok +++ b/library/tzdata/Asia/Bangkok @@ -3,5 +3,5 @@ set TZData(:Asia/Bangkok) { {-9223372036854775808 24124 0 LMT} {-2840164924 24124 0 BMT} - {-1570084924 25200 0 ICT} + {-1570084924 25200 0 +07} } diff --git a/library/tzdata/Asia/Brunei b/library/tzdata/Asia/Brunei index 63d380b..e8cc8c3 100644 --- a/library/tzdata/Asia/Brunei +++ b/library/tzdata/Asia/Brunei @@ -2,6 +2,6 @@ set TZData(:Asia/Brunei) { {-9223372036854775808 27580 0 LMT} - {-1383464380 27000 0 BNT} - {-1167636600 28800 0 BNT} + {-1383464380 27000 0 +0730} + {-1167636600 28800 0 +08} } diff --git a/library/tzdata/Asia/Choibalsan b/library/tzdata/Asia/Choibalsan index 2bcf7f7..3db65de 100644 --- a/library/tzdata/Asia/Choibalsan +++ b/library/tzdata/Asia/Choibalsan @@ -2,221 +2,55 @@ set TZData(:Asia/Choibalsan) { {-9223372036854775808 27480 0 LMT} - {-2032933080 25200 0 ULAT} - {252435600 28800 0 ULAT} - {417974400 36000 0 CHOST} - {433778400 32400 0 CHOT} - {449593200 36000 1 CHOST} - {465314400 32400 0 CHOT} - {481042800 36000 1 CHOST} - {496764000 32400 0 CHOT} - {512492400 36000 1 CHOST} - {528213600 32400 0 CHOT} - {543942000 36000 1 CHOST} - {559663200 32400 0 CHOT} - {575391600 36000 1 CHOST} - {591112800 32400 0 CHOT} - {606841200 36000 1 CHOST} - {622562400 32400 0 CHOT} - {638290800 36000 1 CHOST} - {654616800 32400 0 CHOT} - {670345200 36000 1 CHOST} - {686066400 32400 0 CHOT} - {701794800 36000 1 CHOST} - {717516000 32400 0 CHOT} - {733244400 36000 1 CHOST} - {748965600 32400 0 CHOT} - {764694000 36000 1 CHOST} - {780415200 32400 0 CHOT} - {796143600 36000 1 CHOST} - {811864800 32400 0 CHOT} - {828198000 36000 1 CHOST} - {843919200 32400 0 CHOT} - {859647600 36000 1 CHOST} - {875368800 32400 0 CHOT} - {891097200 36000 1 CHOST} - {906818400 32400 0 CHOT} - {988390800 36000 1 CHOST} - {1001692800 32400 0 CHOT} - {1017421200 36000 1 CHOST} - {1033142400 32400 0 CHOT} - {1048870800 36000 1 CHOST} - {1064592000 32400 0 CHOT} - {1080320400 36000 1 CHOST} - {1096041600 32400 0 CHOT} - {1111770000 36000 1 CHOST} - {1127491200 32400 0 CHOT} - {1143219600 36000 1 CHOST} - {1159545600 32400 0 CHOT} - {1206889200 28800 0 CHOT} - {1427479200 32400 1 CHOST} - {1443193200 28800 0 CHOT} - {1458928800 32400 1 CHOST} - {1474642800 28800 0 CHOT} - {1490378400 32400 1 CHOST} - {1506697200 28800 0 CHOT} - {1522432800 32400 1 CHOST} - {1538146800 28800 0 CHOT} - {1553882400 32400 1 CHOST} - {1569596400 28800 0 CHOT} - {1585332000 32400 1 CHOST} - {1601046000 28800 0 CHOT} - {1616781600 32400 1 CHOST} - {1632495600 28800 0 CHOT} - {1648231200 32400 1 CHOST} - {1663945200 28800 0 CHOT} - {1679680800 32400 1 CHOST} - {1695999600 28800 0 CHOT} - {1711735200 32400 1 CHOST} - {1727449200 28800 0 CHOT} - {1743184800 32400 1 CHOST} - {1758898800 28800 0 CHOT} - {1774634400 32400 1 CHOST} - {1790348400 28800 0 CHOT} - {1806084000 32400 1 CHOST} - {1821798000 28800 0 CHOT} - {1837533600 32400 1 CHOST} - {1853852400 28800 0 CHOT} - {1869588000 32400 1 CHOST} - {1885302000 28800 0 CHOT} - {1901037600 32400 1 CHOST} - {1916751600 28800 0 CHOT} - {1932487200 32400 1 CHOST} - {1948201200 28800 0 CHOT} - {1963936800 32400 1 CHOST} - {1979650800 28800 0 CHOT} - {1995386400 32400 1 CHOST} - {2011100400 28800 0 CHOT} - {2026836000 32400 1 CHOST} - {2043154800 28800 0 CHOT} - {2058890400 32400 1 CHOST} - {2074604400 28800 0 CHOT} - {2090340000 32400 1 CHOST} - {2106054000 28800 0 CHOT} - {2121789600 32400 1 CHOST} - {2137503600 28800 0 CHOT} - {2153239200 32400 1 CHOST} - {2168953200 28800 0 CHOT} - {2184688800 32400 1 CHOST} - {2200402800 28800 0 CHOT} - {2216743200 32400 1 CHOST} - {2232457200 28800 0 CHOT} - {2248192800 32400 1 CHOST} - {2263906800 28800 0 CHOT} - {2279642400 32400 1 CHOST} - {2295356400 28800 0 CHOT} - {2311092000 32400 1 CHOST} - {2326806000 28800 0 CHOT} - {2342541600 32400 1 CHOST} - {2358255600 28800 0 CHOT} - {2373991200 32400 1 CHOST} - {2390310000 28800 0 CHOT} - {2406045600 32400 1 CHOST} - {2421759600 28800 0 CHOT} - {2437495200 32400 1 CHOST} - {2453209200 28800 0 CHOT} - {2468944800 32400 1 CHOST} - {2484658800 28800 0 CHOT} - {2500394400 32400 1 CHOST} - {2516108400 28800 0 CHOT} - {2531844000 32400 1 CHOST} - {2547558000 28800 0 CHOT} - {2563293600 32400 1 CHOST} - {2579612400 28800 0 CHOT} - {2595348000 32400 1 CHOST} - {2611062000 28800 0 CHOT} - {2626797600 32400 1 CHOST} - {2642511600 28800 0 CHOT} - {2658247200 32400 1 CHOST} - {2673961200 28800 0 CHOT} - {2689696800 32400 1 CHOST} - {2705410800 28800 0 CHOT} - {2721146400 32400 1 CHOST} - {2737465200 28800 0 CHOT} - {2753200800 32400 1 CHOST} - {2768914800 28800 0 CHOT} - {2784650400 32400 1 CHOST} - {2800364400 28800 0 CHOT} - {2816100000 32400 1 CHOST} - {2831814000 28800 0 CHOT} - {2847549600 32400 1 CHOST} - {2863263600 28800 0 CHOT} - {2878999200 32400 1 CHOST} - {2894713200 28800 0 CHOT} - {2910448800 32400 1 CHOST} - {2926767600 28800 0 CHOT} - {2942503200 32400 1 CHOST} - {2958217200 28800 0 CHOT} - {2973952800 32400 1 CHOST} - {2989666800 28800 0 CHOT} - {3005402400 32400 1 CHOST} - {3021116400 28800 0 CHOT} - {3036852000 32400 1 CHOST} - {3052566000 28800 0 CHOT} - {3068301600 32400 1 CHOST} - {3084015600 28800 0 CHOT} - {3100356000 32400 1 CHOST} - {3116070000 28800 0 CHOT} - {3131805600 32400 1 CHOST} - {3147519600 28800 0 CHOT} - {3163255200 32400 1 CHOST} - {3178969200 28800 0 CHOT} - {3194704800 32400 1 CHOST} - {3210418800 28800 0 CHOT} - {3226154400 32400 1 CHOST} - {3241868400 28800 0 CHOT} - {3257604000 32400 1 CHOST} - {3273922800 28800 0 CHOT} - {3289658400 32400 1 CHOST} - {3305372400 28800 0 CHOT} - {3321108000 32400 1 CHOST} - {3336822000 28800 0 CHOT} - {3352557600 32400 1 CHOST} - {3368271600 28800 0 CHOT} - {3384007200 32400 1 CHOST} - {3399721200 28800 0 CHOT} - {3415456800 32400 1 CHOST} - {3431170800 28800 0 CHOT} - {3446906400 32400 1 CHOST} - {3463225200 28800 0 CHOT} - {3478960800 32400 1 CHOST} - {3494674800 28800 0 CHOT} - {3510410400 32400 1 CHOST} - {3526124400 28800 0 CHOT} - {3541860000 32400 1 CHOST} - {3557574000 28800 0 CHOT} - {3573309600 32400 1 CHOST} - {3589023600 28800 0 CHOT} - {3604759200 32400 1 CHOST} - {3621078000 28800 0 CHOT} - {3636813600 32400 1 CHOST} - {3652527600 28800 0 CHOT} - {3668263200 32400 1 CHOST} - {3683977200 28800 0 CHOT} - {3699712800 32400 1 CHOST} - {3715426800 28800 0 CHOT} - {3731162400 32400 1 CHOST} - {3746876400 28800 0 CHOT} - {3762612000 32400 1 CHOST} - {3778326000 28800 0 CHOT} - {3794061600 32400 1 CHOST} - {3810380400 28800 0 CHOT} - {3826116000 32400 1 CHOST} - {3841830000 28800 0 CHOT} - {3857565600 32400 1 CHOST} - {3873279600 28800 0 CHOT} - {3889015200 32400 1 CHOST} - {3904729200 28800 0 CHOT} - {3920464800 32400 1 CHOST} - {3936178800 28800 0 CHOT} - {3951914400 32400 1 CHOST} - {3967628400 28800 0 CHOT} - {3983968800 32400 1 CHOST} - {3999682800 28800 0 CHOT} - {4015418400 32400 1 CHOST} - {4031132400 28800 0 CHOT} - {4046868000 32400 1 CHOST} - {4062582000 28800 0 CHOT} - {4078317600 32400 1 CHOST} - {4094031600 28800 0 CHOT} + {-2032933080 25200 0 +07} + {252435600 28800 0 +08} + {417974400 36000 0 +10} + {433778400 32400 0 +09} + {449593200 36000 1 +10} + {465314400 32400 0 +09} + {481042800 36000 1 +10} + {496764000 32400 0 +09} + {512492400 36000 1 +10} + {528213600 32400 0 +09} + {543942000 36000 1 +10} + {559663200 32400 0 +09} + {575391600 36000 1 +10} + {591112800 32400 0 +09} + {606841200 36000 1 +10} + {622562400 32400 0 +09} + {638290800 36000 1 +10} + {654616800 32400 0 +09} + {670345200 36000 1 +10} + {686066400 32400 0 +09} + {701794800 36000 1 +10} + {717516000 32400 0 +09} + {733244400 36000 1 +10} + {748965600 32400 0 +09} + {764694000 36000 1 +10} + {780415200 32400 0 +09} + {796143600 36000 1 +10} + {811864800 32400 0 +09} + {828198000 36000 1 +10} + {843919200 32400 0 +09} + {859647600 36000 1 +10} + {875368800 32400 0 +09} + {891097200 36000 1 +10} + {906818400 32400 0 +09} + {988390800 36000 1 +10} + {1001692800 32400 0 +09} + {1017421200 36000 1 +10} + {1033142400 32400 0 +09} + {1048870800 36000 1 +10} + {1064592000 32400 0 +09} + {1080320400 36000 1 +10} + {1096041600 32400 0 +09} + {1111770000 36000 1 +10} + {1127491200 32400 0 +09} + {1143219600 36000 1 +10} + {1159545600 32400 0 +09} + {1206889200 28800 0 +08} + {1427479200 32400 1 +09} + {1443193200 28800 0 +08} + {1458928800 32400 1 +09} + {1474642800 28800 0 +08} } diff --git a/library/tzdata/Asia/Dhaka b/library/tzdata/Asia/Dhaka index 6e8a334..0dc3987 100644 --- a/library/tzdata/Asia/Dhaka +++ b/library/tzdata/Asia/Dhaka @@ -3,12 +3,11 @@ set TZData(:Asia/Dhaka) { {-9223372036854775808 21700 0 LMT} {-2524543300 21200 0 HMT} - {-891582800 23400 0 BURT} - {-872058600 19800 0 IST} - {-862637400 23400 0 BURT} - {-576138600 21600 0 DACT} - {38772000 21600 0 BDT} - {1230746400 21600 0 BDT} - {1245430800 25200 1 BDST} - {1262278800 21600 0 BDT} + {-891582800 23400 0 +0630} + {-872058600 19800 0 +0530} + {-862637400 23400 0 +0630} + {-576138600 21600 0 +06} + {1230746400 21600 0 +06} + {1245430800 25200 1 +07} + {1262278800 21600 0 +06} } diff --git a/library/tzdata/Asia/Dili b/library/tzdata/Asia/Dili index f783557..89cf22f 100644 --- a/library/tzdata/Asia/Dili +++ b/library/tzdata/Asia/Dili @@ -2,9 +2,8 @@ set TZData(:Asia/Dili) { {-9223372036854775808 30140 0 LMT} - {-1830414140 28800 0 TLT} - {-879152400 32400 0 JST} - {-766054800 32400 0 TLT} - {199897200 28800 0 WITA} - {969120000 32400 0 TLT} + {-1830414140 28800 0 +08} + {-879152400 32400 0 +09} + {199897200 28800 0 +08} + {969120000 32400 0 +09} } diff --git a/library/tzdata/Asia/Dubai b/library/tzdata/Asia/Dubai index b8730e5..6c18e79 100644 --- a/library/tzdata/Asia/Dubai +++ b/library/tzdata/Asia/Dubai @@ -2,5 +2,5 @@ set TZData(:Asia/Dubai) { {-9223372036854775808 13272 0 LMT} - {-1577936472 14400 0 GST} + {-1577936472 14400 0 +04} } diff --git a/library/tzdata/Asia/Ho_Chi_Minh b/library/tzdata/Asia/Ho_Chi_Minh index 9da89f4..b4e749b 100644 --- a/library/tzdata/Asia/Ho_Chi_Minh +++ b/library/tzdata/Asia/Ho_Chi_Minh @@ -3,12 +3,12 @@ set TZData(:Asia/Ho_Chi_Minh) { {-9223372036854775808 25600 0 LMT} {-2004073600 25590 0 PLMT} - {-1851577590 25200 0 ICT} - {-852105600 28800 0 IDT} - {-782643600 32400 0 JST} - {-767869200 25200 0 ICT} - {-718095600 28800 0 IDT} - {-457776000 25200 0 ICT} - {-315648000 28800 0 IDT} - {171820800 25200 0 ICT} + {-1851577590 25200 0 +07} + {-852105600 28800 0 +08} + {-782643600 32400 0 +09} + {-767869200 25200 0 +07} + {-718095600 28800 0 +08} + {-457776000 25200 0 +07} + {-315648000 28800 0 +08} + {171820800 25200 0 +07} } diff --git a/library/tzdata/Asia/Hovd b/library/tzdata/Asia/Hovd index 3d200a6..a9c995b 100644 --- a/library/tzdata/Asia/Hovd +++ b/library/tzdata/Asia/Hovd @@ -2,220 +2,54 @@ set TZData(:Asia/Hovd) { {-9223372036854775808 21996 0 LMT} - {-2032927596 21600 0 HOVT} - {252439200 25200 0 HOVT} - {417978000 28800 1 HOVST} - {433785600 25200 0 HOVT} - {449600400 28800 1 HOVST} - {465321600 25200 0 HOVT} - {481050000 28800 1 HOVST} - {496771200 25200 0 HOVT} - {512499600 28800 1 HOVST} - {528220800 25200 0 HOVT} - {543949200 28800 1 HOVST} - {559670400 25200 0 HOVT} - {575398800 28800 1 HOVST} - {591120000 25200 0 HOVT} - {606848400 28800 1 HOVST} - {622569600 25200 0 HOVT} - {638298000 28800 1 HOVST} - {654624000 25200 0 HOVT} - {670352400 28800 1 HOVST} - {686073600 25200 0 HOVT} - {701802000 28800 1 HOVST} - {717523200 25200 0 HOVT} - {733251600 28800 1 HOVST} - {748972800 25200 0 HOVT} - {764701200 28800 1 HOVST} - {780422400 25200 0 HOVT} - {796150800 28800 1 HOVST} - {811872000 25200 0 HOVT} - {828205200 28800 1 HOVST} - {843926400 25200 0 HOVT} - {859654800 28800 1 HOVST} - {875376000 25200 0 HOVT} - {891104400 28800 1 HOVST} - {906825600 25200 0 HOVT} - {988398000 28800 1 HOVST} - {1001700000 25200 0 HOVT} - {1017428400 28800 1 HOVST} - {1033149600 25200 0 HOVT} - {1048878000 28800 1 HOVST} - {1064599200 25200 0 HOVT} - {1080327600 28800 1 HOVST} - {1096048800 25200 0 HOVT} - {1111777200 28800 1 HOVST} - {1127498400 25200 0 HOVT} - {1143226800 28800 1 HOVST} - {1159552800 25200 0 HOVT} - {1427482800 28800 1 HOVST} - {1443196800 25200 0 HOVT} - {1458932400 28800 1 HOVST} - {1474646400 25200 0 HOVT} - {1490382000 28800 1 HOVST} - {1506700800 25200 0 HOVT} - {1522436400 28800 1 HOVST} - {1538150400 25200 0 HOVT} - {1553886000 28800 1 HOVST} - {1569600000 25200 0 HOVT} - {1585335600 28800 1 HOVST} - {1601049600 25200 0 HOVT} - {1616785200 28800 1 HOVST} - {1632499200 25200 0 HOVT} - {1648234800 28800 1 HOVST} - {1663948800 25200 0 HOVT} - {1679684400 28800 1 HOVST} - {1696003200 25200 0 HOVT} - {1711738800 28800 1 HOVST} - {1727452800 25200 0 HOVT} - {1743188400 28800 1 HOVST} - {1758902400 25200 0 HOVT} - {1774638000 28800 1 HOVST} - {1790352000 25200 0 HOVT} - {1806087600 28800 1 HOVST} - {1821801600 25200 0 HOVT} - {1837537200 28800 1 HOVST} - {1853856000 25200 0 HOVT} - {1869591600 28800 1 HOVST} - {1885305600 25200 0 HOVT} - {1901041200 28800 1 HOVST} - {1916755200 25200 0 HOVT} - {1932490800 28800 1 HOVST} - {1948204800 25200 0 HOVT} - {1963940400 28800 1 HOVST} - {1979654400 25200 0 HOVT} - {1995390000 28800 1 HOVST} - {2011104000 25200 0 HOVT} - {2026839600 28800 1 HOVST} - {2043158400 25200 0 HOVT} - {2058894000 28800 1 HOVST} - {2074608000 25200 0 HOVT} - {2090343600 28800 1 HOVST} - {2106057600 25200 0 HOVT} - {2121793200 28800 1 HOVST} - {2137507200 25200 0 HOVT} - {2153242800 28800 1 HOVST} - {2168956800 25200 0 HOVT} - {2184692400 28800 1 HOVST} - {2200406400 25200 0 HOVT} - {2216746800 28800 1 HOVST} - {2232460800 25200 0 HOVT} - {2248196400 28800 1 HOVST} - {2263910400 25200 0 HOVT} - {2279646000 28800 1 HOVST} - {2295360000 25200 0 HOVT} - {2311095600 28800 1 HOVST} - {2326809600 25200 0 HOVT} - {2342545200 28800 1 HOVST} - {2358259200 25200 0 HOVT} - {2373994800 28800 1 HOVST} - {2390313600 25200 0 HOVT} - {2406049200 28800 1 HOVST} - {2421763200 25200 0 HOVT} - {2437498800 28800 1 HOVST} - {2453212800 25200 0 HOVT} - {2468948400 28800 1 HOVST} - {2484662400 25200 0 HOVT} - {2500398000 28800 1 HOVST} - {2516112000 25200 0 HOVT} - {2531847600 28800 1 HOVST} - {2547561600 25200 0 HOVT} - {2563297200 28800 1 HOVST} - {2579616000 25200 0 HOVT} - {2595351600 28800 1 HOVST} - {2611065600 25200 0 HOVT} - {2626801200 28800 1 HOVST} - {2642515200 25200 0 HOVT} - {2658250800 28800 1 HOVST} - {2673964800 25200 0 HOVT} - {2689700400 28800 1 HOVST} - {2705414400 25200 0 HOVT} - {2721150000 28800 1 HOVST} - {2737468800 25200 0 HOVT} - {2753204400 28800 1 HOVST} - {2768918400 25200 0 HOVT} - {2784654000 28800 1 HOVST} - {2800368000 25200 0 HOVT} - {2816103600 28800 1 HOVST} - {2831817600 25200 0 HOVT} - {2847553200 28800 1 HOVST} - {2863267200 25200 0 HOVT} - {2879002800 28800 1 HOVST} - {2894716800 25200 0 HOVT} - {2910452400 28800 1 HOVST} - {2926771200 25200 0 HOVT} - {2942506800 28800 1 HOVST} - {2958220800 25200 0 HOVT} - {2973956400 28800 1 HOVST} - {2989670400 25200 0 HOVT} - {3005406000 28800 1 HOVST} - {3021120000 25200 0 HOVT} - {3036855600 28800 1 HOVST} - {3052569600 25200 0 HOVT} - {3068305200 28800 1 HOVST} - {3084019200 25200 0 HOVT} - {3100359600 28800 1 HOVST} - {3116073600 25200 0 HOVT} - {3131809200 28800 1 HOVST} - {3147523200 25200 0 HOVT} - {3163258800 28800 1 HOVST} - {3178972800 25200 0 HOVT} - {3194708400 28800 1 HOVST} - {3210422400 25200 0 HOVT} - {3226158000 28800 1 HOVST} - {3241872000 25200 0 HOVT} - {3257607600 28800 1 HOVST} - {3273926400 25200 0 HOVT} - {3289662000 28800 1 HOVST} - {3305376000 25200 0 HOVT} - {3321111600 28800 1 HOVST} - {3336825600 25200 0 HOVT} - {3352561200 28800 1 HOVST} - {3368275200 25200 0 HOVT} - {3384010800 28800 1 HOVST} - {3399724800 25200 0 HOVT} - {3415460400 28800 1 HOVST} - {3431174400 25200 0 HOVT} - {3446910000 28800 1 HOVST} - {3463228800 25200 0 HOVT} - {3478964400 28800 1 HOVST} - {3494678400 25200 0 HOVT} - {3510414000 28800 1 HOVST} - {3526128000 25200 0 HOVT} - {3541863600 28800 1 HOVST} - {3557577600 25200 0 HOVT} - {3573313200 28800 1 HOVST} - {3589027200 25200 0 HOVT} - {3604762800 28800 1 HOVST} - {3621081600 25200 0 HOVT} - {3636817200 28800 1 HOVST} - {3652531200 25200 0 HOVT} - {3668266800 28800 1 HOVST} - {3683980800 25200 0 HOVT} - {3699716400 28800 1 HOVST} - {3715430400 25200 0 HOVT} - {3731166000 28800 1 HOVST} - {3746880000 25200 0 HOVT} - {3762615600 28800 1 HOVST} - {3778329600 25200 0 HOVT} - {3794065200 28800 1 HOVST} - {3810384000 25200 0 HOVT} - {3826119600 28800 1 HOVST} - {3841833600 25200 0 HOVT} - {3857569200 28800 1 HOVST} - {3873283200 25200 0 HOVT} - {3889018800 28800 1 HOVST} - {3904732800 25200 0 HOVT} - {3920468400 28800 1 HOVST} - {3936182400 25200 0 HOVT} - {3951918000 28800 1 HOVST} - {3967632000 25200 0 HOVT} - {3983972400 28800 1 HOVST} - {3999686400 25200 0 HOVT} - {4015422000 28800 1 HOVST} - {4031136000 25200 0 HOVT} - {4046871600 28800 1 HOVST} - {4062585600 25200 0 HOVT} - {4078321200 28800 1 HOVST} - {4094035200 25200 0 HOVT} + {-2032927596 21600 0 +06} + {252439200 25200 0 +07} + {417978000 28800 1 +08} + {433785600 25200 0 +07} + {449600400 28800 1 +08} + {465321600 25200 0 +07} + {481050000 28800 1 +08} + {496771200 25200 0 +07} + {512499600 28800 1 +08} + {528220800 25200 0 +07} + {543949200 28800 1 +08} + {559670400 25200 0 +07} + {575398800 28800 1 +08} + {591120000 25200 0 +07} + {606848400 28800 1 +08} + {622569600 25200 0 +07} + {638298000 28800 1 +08} + {654624000 25200 0 +07} + {670352400 28800 1 +08} + {686073600 25200 0 +07} + {701802000 28800 1 +08} + {717523200 25200 0 +07} + {733251600 28800 1 +08} + {748972800 25200 0 +07} + {764701200 28800 1 +08} + {780422400 25200 0 +07} + {796150800 28800 1 +08} + {811872000 25200 0 +07} + {828205200 28800 1 +08} + {843926400 25200 0 +07} + {859654800 28800 1 +08} + {875376000 25200 0 +07} + {891104400 28800 1 +08} + {906825600 25200 0 +07} + {988398000 28800 1 +08} + {1001700000 25200 0 +07} + {1017428400 28800 1 +08} + {1033149600 25200 0 +07} + {1048878000 28800 1 +08} + {1064599200 25200 0 +07} + {1080327600 28800 1 +08} + {1096048800 25200 0 +07} + {1111777200 28800 1 +08} + {1127498400 25200 0 +07} + {1143226800 28800 1 +08} + {1159552800 25200 0 +07} + {1427482800 28800 1 +08} + {1443196800 25200 0 +07} + {1458932400 28800 1 +08} + {1474646400 25200 0 +07} } diff --git a/library/tzdata/Asia/Jakarta b/library/tzdata/Asia/Jakarta index 75cd659..21da168 100644 --- a/library/tzdata/Asia/Jakarta +++ b/library/tzdata/Asia/Jakarta @@ -3,11 +3,11 @@ set TZData(:Asia/Jakarta) { {-9223372036854775808 25632 0 LMT} {-3231299232 25632 0 BMT} - {-1451719200 26400 0 JAVT} - {-1172906400 27000 0 WIB} - {-876641400 32400 0 JST} - {-766054800 27000 0 WIB} - {-683883000 28800 0 WIB} - {-620812800 27000 0 WIB} + {-1451719200 26400 0 +0720} + {-1172906400 27000 0 +0730} + {-876641400 32400 0 +09} + {-766054800 27000 0 +0730} + {-683883000 28800 0 +08} + {-620812800 27000 0 +0730} {-189415800 25200 0 WIB} } diff --git a/library/tzdata/Asia/Jayapura b/library/tzdata/Asia/Jayapura index f3a4c44..1432488 100644 --- a/library/tzdata/Asia/Jayapura +++ b/library/tzdata/Asia/Jayapura @@ -2,7 +2,7 @@ set TZData(:Asia/Jayapura) { {-9223372036854775808 33768 0 LMT} - {-1172913768 32400 0 WIT} - {-799491600 34200 0 ACST} + {-1172913768 32400 0 +09} + {-799491600 34200 0 +0930} {-189423000 32400 0 WIT} } diff --git a/library/tzdata/Asia/Kabul b/library/tzdata/Asia/Kabul index 33d7282..3613de4 100644 --- a/library/tzdata/Asia/Kabul +++ b/library/tzdata/Asia/Kabul @@ -2,6 +2,6 @@ set TZData(:Asia/Kabul) { {-9223372036854775808 16608 0 LMT} - {-2524538208 14400 0 AFT} - {-788932800 16200 0 AFT} + {-2524538208 14400 0 +04} + {-788932800 16200 0 +0430} } diff --git a/library/tzdata/Asia/Karachi b/library/tzdata/Asia/Karachi index 669c11a..1d81926 100644 --- a/library/tzdata/Asia/Karachi +++ b/library/tzdata/Asia/Karachi @@ -2,10 +2,10 @@ set TZData(:Asia/Karachi) { {-9223372036854775808 16092 0 LMT} - {-1988166492 19800 0 IST} - {-862637400 23400 1 IST} - {-764145000 19800 0 IST} - {-576135000 18000 0 KART} + {-1988166492 19800 0 +0530} + {-862637400 23400 1 +0630} + {-764145000 19800 0 +0530} + {-576135000 18000 0 +05} {38775600 18000 0 PKT} {1018119600 21600 1 PKST} {1033840800 18000 0 PKT} diff --git a/library/tzdata/Asia/Kathmandu b/library/tzdata/Asia/Kathmandu index dbec1f0..f88a5a2 100644 --- a/library/tzdata/Asia/Kathmandu +++ b/library/tzdata/Asia/Kathmandu @@ -2,6 +2,6 @@ set TZData(:Asia/Kathmandu) { {-9223372036854775808 20476 0 LMT} - {-1577943676 19800 0 IST} - {504901800 20700 0 NPT} + {-1577943676 19800 0 +0530} + {504901800 20700 0 +0545} } diff --git a/library/tzdata/Asia/Kolkata b/library/tzdata/Asia/Kolkata index a87bf31..6b3b9fb 100644 --- a/library/tzdata/Asia/Kolkata +++ b/library/tzdata/Asia/Kolkata @@ -3,8 +3,8 @@ set TZData(:Asia/Kolkata) { {-9223372036854775808 21208 0 LMT} {-2840162008 21200 0 HMT} - {-891582800 23400 0 BURT} + {-891582800 23400 0 +0630} {-872058600 19800 0 IST} - {-862637400 23400 1 IST} + {-862637400 23400 1 +0630} {-764145000 19800 0 IST} } diff --git a/library/tzdata/Asia/Kuala_Lumpur b/library/tzdata/Asia/Kuala_Lumpur index 7a54bd6..84eae1d 100644 --- a/library/tzdata/Asia/Kuala_Lumpur +++ b/library/tzdata/Asia/Kuala_Lumpur @@ -3,11 +3,11 @@ set TZData(:Asia/Kuala_Lumpur) { {-9223372036854775808 24406 0 LMT} {-2177477206 24925 0 SMT} - {-2038200925 25200 0 MALT} - {-1167634800 26400 1 MALST} - {-1073028000 26400 0 MALT} - {-894180000 27000 0 MALT} - {-879665400 32400 0 JST} - {-767005200 27000 0 MALT} - {378664200 28800 0 MYT} + {-2038200925 25200 0 +07} + {-1167634800 26400 1 +0720} + {-1073028000 26400 0 +0720} + {-894180000 27000 0 +0730} + {-879665400 32400 0 +09} + {-767005200 27000 0 +0730} + {378664200 28800 0 +08} } diff --git a/library/tzdata/Asia/Kuching b/library/tzdata/Asia/Kuching index 0f9110c..d6f5ad4 100644 --- a/library/tzdata/Asia/Kuching +++ b/library/tzdata/Asia/Kuching @@ -2,23 +2,22 @@ set TZData(:Asia/Kuching) { {-9223372036854775808 26480 0 LMT} - {-1383463280 27000 0 BORT} - {-1167636600 28800 0 BORT} - {-1082448000 30000 1 BORTST} - {-1074586800 28800 0 BORT} - {-1050825600 30000 1 BORTST} - {-1042964400 28800 0 BORT} - {-1019289600 30000 1 BORTST} - {-1011428400 28800 0 BORT} - {-987753600 30000 1 BORTST} - {-979892400 28800 0 BORT} - {-956217600 30000 1 BORTST} - {-948356400 28800 0 BORT} - {-924595200 30000 1 BORTST} - {-916734000 28800 0 BORT} - {-893059200 30000 1 BORTST} - {-885198000 28800 0 BORT} - {-879667200 32400 0 JST} - {-767005200 28800 0 BORT} - {378662400 28800 0 MYT} + {-1383463280 27000 0 +0730} + {-1167636600 28800 0 +08} + {-1082448000 30000 1 +0820} + {-1074586800 28800 0 +08} + {-1050825600 30000 1 +0820} + {-1042964400 28800 0 +08} + {-1019289600 30000 1 +0820} + {-1011428400 28800 0 +08} + {-987753600 30000 1 +0820} + {-979892400 28800 0 +08} + {-956217600 30000 1 +0820} + {-948356400 28800 0 +08} + {-924595200 30000 1 +0820} + {-916734000 28800 0 +08} + {-893059200 30000 1 +0820} + {-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 9d4abfe..8458a8a 100644 --- a/library/tzdata/Asia/Macau +++ b/library/tzdata/Asia/Macau @@ -2,45 +2,45 @@ set TZData(:Asia/Macau) { {-9223372036854775808 27260 0 LMT} - {-1830411260 28800 0 MOT} - {-277360200 32400 1 MOST} - {-257405400 28800 0 MOT} - {-245910600 32400 1 MOST} - {-225955800 28800 0 MOT} - {-214473600 32400 1 MOST} - {-194506200 28800 0 MOT} - {-182406600 32400 1 MOST} - {-163056600 28800 0 MOT} - {-150969600 32400 1 MOST} - {-131619600 28800 0 MOT} - {-117088200 32400 1 MOST} - {-101367000 28800 0 MOT} - {-85638600 32400 1 MOST} - {-69312600 28800 0 MOT} - {-53584200 32400 1 MOST} - {-37863000 28800 0 MOT} - {-22134600 32400 1 MOST} - {-6413400 28800 0 MOT} - {9315000 32400 1 MOST} - {25036200 28800 0 MOT} - {40764600 32400 1 MOST} - {56485800 28800 0 MOT} - {72201600 32400 1 MOST} - {87922800 28800 0 MOT} - {103651200 32400 1 MOST} - {119977200 28800 0 MOT} - {135705600 32400 1 MOST} - {151439400 28800 0 MOT} - {167167800 32400 1 MOST} - {182889000 28800 0 MOT} - {198617400 32400 1 MOST} - {214338600 28800 0 MOT} - {230067000 32400 1 MOST} - {245788200 28800 0 MOT} - {261504000 32400 1 MOST} - {277225200 28800 0 MOT} - {292953600 32400 1 MOST} - {309279600 28800 0 MOT} - {325008000 32400 1 MOST} - {340729200 28800 0 MOT} + {-1830411260 28800 0 CST} + {-277360200 32400 1 CDT} + {-257405400 28800 0 CST} + {-245910600 32400 1 CDT} + {-225955800 28800 0 CST} + {-214473600 32400 1 CDT} + {-194506200 28800 0 CST} + {-182406600 32400 1 CDT} + {-163056600 28800 0 CST} + {-150969600 32400 1 CDT} + {-131619600 28800 0 CST} + {-117088200 32400 1 CDT} + {-101367000 28800 0 CST} + {-85638600 32400 1 CDT} + {-69312600 28800 0 CST} + {-53584200 32400 1 CDT} + {-37863000 28800 0 CST} + {-22134600 32400 1 CDT} + {-6413400 28800 0 CST} + {9315000 32400 1 CDT} + {25036200 28800 0 CST} + {40764600 32400 1 CDT} + {56485800 28800 0 CST} + {72201600 32400 1 CDT} + {87922800 28800 0 CST} + {103651200 32400 1 CDT} + {119977200 28800 0 CST} + {135705600 32400 1 CDT} + {151439400 28800 0 CST} + {167167800 32400 1 CDT} + {182889000 28800 0 CST} + {198617400 32400 1 CDT} + {214338600 28800 0 CST} + {230067000 32400 1 CDT} + {245788200 28800 0 CST} + {261504000 32400 1 CDT} + {277225200 28800 0 CST} + {292953600 32400 1 CDT} + {309279600 28800 0 CST} + {325008000 32400 1 CDT} + {340729200 28800 0 CST} } diff --git a/library/tzdata/Asia/Makassar b/library/tzdata/Asia/Makassar index be947f3..1be5c59 100644 --- a/library/tzdata/Asia/Makassar +++ b/library/tzdata/Asia/Makassar @@ -3,7 +3,7 @@ set TZData(:Asia/Makassar) { {-9223372036854775808 28656 0 LMT} {-1577951856 28656 0 MMT} - {-1172908656 28800 0 WITA} - {-880272000 32400 0 JST} + {-1172908656 28800 0 +08} + {-880272000 32400 0 +09} {-766054800 28800 0 WITA} } diff --git a/library/tzdata/Asia/Manila b/library/tzdata/Asia/Manila index 9cc25e8..987919a 100644 --- a/library/tzdata/Asia/Manila +++ b/library/tzdata/Asia/Manila @@ -3,13 +3,13 @@ set TZData(:Asia/Manila) { {-9223372036854775808 -57360 0 LMT} {-3944621040 29040 0 LMT} - {-2229321840 28800 0 PHT} - {-1046678400 32400 1 PHST} - {-1038733200 28800 0 PHT} - {-873273600 32400 0 JST} - {-794221200 28800 0 PHT} - {-496224000 32400 1 PHST} - {-489315600 28800 0 PHT} - {259344000 32400 1 PHST} - {275151600 28800 0 PHT} + {-2229321840 28800 0 +08} + {-1046678400 32400 1 +09} + {-1038733200 28800 0 +08} + {-873273600 32400 0 +09} + {-794221200 28800 0 +08} + {-496224000 32400 1 +09} + {-489315600 28800 0 +08} + {259344000 32400 1 +09} + {275151600 28800 0 +08} } diff --git a/library/tzdata/Asia/Oral b/library/tzdata/Asia/Oral index 962111b..624a59d 100644 --- a/library/tzdata/Asia/Oral +++ b/library/tzdata/Asia/Oral @@ -2,8 +2,8 @@ set TZData(:Asia/Oral) { {-9223372036854775808 12324 0 LMT} - {-1441164324 14400 0 +04} - {-1247544000 18000 0 +05} + {-1441164324 10800 0 +03} + {-1247540400 18000 0 +05} {354913200 21600 1 +06} {370720800 21600 0 +06} {386445600 18000 0 +05} diff --git a/library/tzdata/Asia/Pontianak b/library/tzdata/Asia/Pontianak index 728b552..ed59e9d 100644 --- a/library/tzdata/Asia/Pontianak +++ b/library/tzdata/Asia/Pontianak @@ -3,11 +3,11 @@ set TZData(:Asia/Pontianak) { {-9223372036854775808 26240 0 LMT} {-1946186240 26240 0 PMT} - {-1172906240 27000 0 WIB} - {-881220600 32400 0 JST} - {-766054800 27000 0 WIB} - {-683883000 28800 0 WIB} - {-620812800 27000 0 WIB} + {-1172906240 27000 0 +0730} + {-881220600 32400 0 +09} + {-766054800 27000 0 +0730} + {-683883000 28800 0 +08} + {-620812800 27000 0 +0730} {-189415800 28800 0 WITA} {567964800 25200 0 WIB} } diff --git a/library/tzdata/Asia/Pyongyang b/library/tzdata/Asia/Pyongyang index 4ade8e6..72e7f23 100644 --- a/library/tzdata/Asia/Pyongyang +++ b/library/tzdata/Asia/Pyongyang @@ -3,8 +3,7 @@ set TZData(:Asia/Pyongyang) { {-9223372036854775808 30180 0 LMT} {-1948782180 30600 0 KST} - {-1830414600 32400 0 JCST} - {-1017824400 32400 0 JST} + {-1830414600 32400 0 JST} {-768646800 32400 0 KST} {1439564400 30600 0 KST} } diff --git a/library/tzdata/Asia/Qatar b/library/tzdata/Asia/Qatar index bfb4eb4..10b4f6d 100644 --- a/library/tzdata/Asia/Qatar +++ b/library/tzdata/Asia/Qatar @@ -2,6 +2,6 @@ set TZData(:Asia/Qatar) { {-9223372036854775808 12368 0 LMT} - {-1577935568 14400 0 GST} - {76190400 10800 0 AST} + {-1577935568 14400 0 +04} + {76190400 10800 0 +03} } diff --git a/library/tzdata/Asia/Riyadh b/library/tzdata/Asia/Riyadh index 12c9e24..af5efa8 100644 --- a/library/tzdata/Asia/Riyadh +++ b/library/tzdata/Asia/Riyadh @@ -2,5 +2,5 @@ set TZData(:Asia/Riyadh) { {-9223372036854775808 11212 0 LMT} - {-719636812 10800 0 AST} + {-719636812 10800 0 +03} } diff --git a/library/tzdata/Asia/Seoul b/library/tzdata/Asia/Seoul index c24a1d8..b226eb5 100644 --- a/library/tzdata/Asia/Seoul +++ b/library/tzdata/Asia/Seoul @@ -3,8 +3,7 @@ set TZData(:Asia/Seoul) { {-9223372036854775808 30472 0 LMT} {-1948782472 30600 0 KST} - {-1830414600 32400 0 JCST} - {-1017824400 32400 0 JST} + {-1830414600 32400 0 JST} {-767350800 32400 0 KST} {-498128400 30600 0 KST} {-462702600 34200 1 KDT} diff --git a/library/tzdata/Asia/Singapore b/library/tzdata/Asia/Singapore index e2f226e..f10eb1f 100644 --- a/library/tzdata/Asia/Singapore +++ b/library/tzdata/Asia/Singapore @@ -3,12 +3,11 @@ set TZData(:Asia/Singapore) { {-9223372036854775808 24925 0 LMT} {-2177477725 24925 0 SMT} - {-2038200925 25200 0 MALT} - {-1167634800 26400 1 MALST} - {-1073028000 26400 0 MALT} - {-894180000 27000 0 MALT} - {-879665400 32400 0 JST} - {-767005200 27000 0 MALT} - {-138785400 27000 0 SGT} - {378664200 28800 0 SGT} + {-2038200925 25200 0 +07} + {-1167634800 26400 1 +0720} + {-1073028000 26400 0 +0720} + {-894180000 27000 0 +0730} + {-879665400 32400 0 +09} + {-767005200 27000 0 +0730} + {378664200 28800 0 +08} } diff --git a/library/tzdata/Asia/Taipei b/library/tzdata/Asia/Taipei index 61c77ef..cb8fb89 100644 --- a/library/tzdata/Asia/Taipei +++ b/library/tzdata/Asia/Taipei @@ -2,7 +2,7 @@ set TZData(:Asia/Taipei) { {-9223372036854775808 29160 0 LMT} - {-2335248360 28800 0 JWST} + {-2335248360 28800 0 CST} {-1017820800 32400 0 JST} {-766224000 28800 0 CST} {-745833600 32400 1 CDT} diff --git a/library/tzdata/Asia/Tehran b/library/tzdata/Asia/Tehran index 5fd840d..a8912ce 100644 --- a/library/tzdata/Asia/Tehran +++ b/library/tzdata/Asia/Tehran @@ -3,227 +3,227 @@ set TZData(:Asia/Tehran) { {-9223372036854775808 12344 0 LMT} {-1704165944 12344 0 TMT} - {-757394744 12600 0 IRST} - {247177800 14400 0 IRST} - {259272000 18000 1 IRDT} - {277758000 14400 0 IRST} - {283982400 12600 0 IRST} - {290809800 16200 1 IRDT} - {306531000 12600 0 IRST} - {322432200 16200 1 IRDT} - {338499000 12600 0 IRST} - {673216200 16200 1 IRDT} - {685481400 12600 0 IRST} - {701209800 16200 1 IRDT} - {717103800 12600 0 IRST} - {732745800 16200 1 IRDT} - {748639800 12600 0 IRST} - {764281800 16200 1 IRDT} - {780175800 12600 0 IRST} - {795817800 16200 1 IRDT} - {811711800 12600 0 IRST} - {827353800 16200 1 IRDT} - {843247800 12600 0 IRST} - {858976200 16200 1 IRDT} - {874870200 12600 0 IRST} - {890512200 16200 1 IRDT} - {906406200 12600 0 IRST} - {922048200 16200 1 IRDT} - {937942200 12600 0 IRST} - {953584200 16200 1 IRDT} - {969478200 12600 0 IRST} - {985206600 16200 1 IRDT} - {1001100600 12600 0 IRST} - {1016742600 16200 1 IRDT} - {1032636600 12600 0 IRST} - {1048278600 16200 1 IRDT} - {1064172600 12600 0 IRST} - {1079814600 16200 1 IRDT} - {1095708600 12600 0 IRST} - {1111437000 16200 1 IRDT} - {1127331000 12600 0 IRST} - {1206045000 16200 1 IRDT} - {1221939000 12600 0 IRST} - {1237667400 16200 1 IRDT} - {1253561400 12600 0 IRST} - {1269203400 16200 1 IRDT} - {1285097400 12600 0 IRST} - {1300739400 16200 1 IRDT} - {1316633400 12600 0 IRST} - {1332275400 16200 1 IRDT} - {1348169400 12600 0 IRST} - {1363897800 16200 1 IRDT} - {1379791800 12600 0 IRST} - {1395433800 16200 1 IRDT} - {1411327800 12600 0 IRST} - {1426969800 16200 1 IRDT} - {1442863800 12600 0 IRST} - {1458505800 16200 1 IRDT} - {1474399800 12600 0 IRST} - {1490128200 16200 1 IRDT} - {1506022200 12600 0 IRST} - {1521664200 16200 1 IRDT} - {1537558200 12600 0 IRST} - {1553200200 16200 1 IRDT} - {1569094200 12600 0 IRST} - {1584736200 16200 1 IRDT} - {1600630200 12600 0 IRST} - {1616358600 16200 1 IRDT} - {1632252600 12600 0 IRST} - {1647894600 16200 1 IRDT} - {1663788600 12600 0 IRST} - {1679430600 16200 1 IRDT} - {1695324600 12600 0 IRST} - {1710966600 16200 1 IRDT} - {1726860600 12600 0 IRST} - {1742589000 16200 1 IRDT} - {1758483000 12600 0 IRST} - {1774125000 16200 1 IRDT} - {1790019000 12600 0 IRST} - {1805661000 16200 1 IRDT} - {1821555000 12600 0 IRST} - {1837197000 16200 1 IRDT} - {1853091000 12600 0 IRST} - {1868733000 16200 1 IRDT} - {1884627000 12600 0 IRST} - {1900355400 16200 1 IRDT} - {1916249400 12600 0 IRST} - {1931891400 16200 1 IRDT} - {1947785400 12600 0 IRST} - {1963427400 16200 1 IRDT} - {1979321400 12600 0 IRST} - {1994963400 16200 1 IRDT} - {2010857400 12600 0 IRST} - {2026585800 16200 1 IRDT} - {2042479800 12600 0 IRST} - {2058121800 16200 1 IRDT} - {2074015800 12600 0 IRST} - {2089657800 16200 1 IRDT} - {2105551800 12600 0 IRST} - {2121193800 16200 1 IRDT} - {2137087800 12600 0 IRST} - {2152729800 16200 1 IRDT} - {2168623800 12600 0 IRST} - {2184265800 16200 1 IRDT} - {2200159800 12600 0 IRST} - {2215888200 16200 1 IRDT} - {2231782200 12600 0 IRST} - {2247424200 16200 1 IRDT} - {2263318200 12600 0 IRST} - {2278960200 16200 1 IRDT} - {2294854200 12600 0 IRST} - {2310496200 16200 1 IRDT} - {2326390200 12600 0 IRST} - {2342118600 16200 1 IRDT} - {2358012600 12600 0 IRST} - {2373654600 16200 1 IRDT} - {2389548600 12600 0 IRST} - {2405190600 16200 1 IRDT} - {2421084600 12600 0 IRST} - {2436726600 16200 1 IRDT} - {2452620600 12600 0 IRST} - {2468349000 16200 1 IRDT} - {2484243000 12600 0 IRST} - {2499885000 16200 1 IRDT} - {2515779000 12600 0 IRST} - {2531421000 16200 1 IRDT} - {2547315000 12600 0 IRST} - {2562957000 16200 1 IRDT} - {2578851000 12600 0 IRST} - {2594579400 16200 1 IRDT} - {2610473400 12600 0 IRST} - {2626115400 16200 1 IRDT} - {2642009400 12600 0 IRST} - {2657651400 16200 1 IRDT} - {2673545400 12600 0 IRST} - {2689187400 16200 1 IRDT} - {2705081400 12600 0 IRST} - {2720809800 16200 1 IRDT} - {2736703800 12600 0 IRST} - {2752345800 16200 1 IRDT} - {2768239800 12600 0 IRST} - {2783881800 16200 1 IRDT} - {2799775800 12600 0 IRST} - {2815417800 16200 1 IRDT} - {2831311800 12600 0 IRST} - {2847040200 16200 1 IRDT} - {2862934200 12600 0 IRST} - {2878576200 16200 1 IRDT} - {2894470200 12600 0 IRST} - {2910112200 16200 1 IRDT} - {2926006200 12600 0 IRST} - {2941648200 16200 1 IRDT} - {2957542200 12600 0 IRST} - {2973270600 16200 1 IRDT} - {2989164600 12600 0 IRST} - {3004806600 16200 1 IRDT} - {3020700600 12600 0 IRST} - {3036342600 16200 1 IRDT} - {3052236600 12600 0 IRST} - {3067878600 16200 1 IRDT} - {3083772600 12600 0 IRST} - {3099501000 16200 1 IRDT} - {3115395000 12600 0 IRST} - {3131037000 16200 1 IRDT} - {3146931000 12600 0 IRST} - {3162573000 16200 1 IRDT} - {3178467000 12600 0 IRST} - {3194109000 16200 1 IRDT} - {3210003000 12600 0 IRST} - {3225731400 16200 1 IRDT} - {3241625400 12600 0 IRST} - {3257267400 16200 1 IRDT} - {3273161400 12600 0 IRST} - {3288803400 16200 1 IRDT} - {3304697400 12600 0 IRST} - {3320339400 16200 1 IRDT} - {3336233400 12600 0 IRST} - {3351961800 16200 1 IRDT} - {3367855800 12600 0 IRST} - {3383497800 16200 1 IRDT} - {3399391800 12600 0 IRST} - {3415033800 16200 1 IRDT} - {3430927800 12600 0 IRST} - {3446569800 16200 1 IRDT} - {3462463800 12600 0 IRST} - {3478192200 16200 1 IRDT} - {3494086200 12600 0 IRST} - {3509728200 16200 1 IRDT} - {3525622200 12600 0 IRST} - {3541264200 16200 1 IRDT} - {3557158200 12600 0 IRST} - {3572800200 16200 1 IRDT} - {3588694200 12600 0 IRST} - {3604422600 16200 1 IRDT} - {3620316600 12600 0 IRST} - {3635958600 16200 1 IRDT} - {3651852600 12600 0 IRST} - {3667494600 16200 1 IRDT} - {3683388600 12600 0 IRST} - {3699030600 16200 1 IRDT} - {3714924600 12600 0 IRST} - {3730653000 16200 1 IRDT} - {3746547000 12600 0 IRST} - {3762189000 16200 1 IRDT} - {3778083000 12600 0 IRST} - {3793725000 16200 1 IRDT} - {3809619000 12600 0 IRST} - {3825261000 16200 1 IRDT} - {3841155000 12600 0 IRST} - {3856883400 16200 1 IRDT} - {3872777400 12600 0 IRST} - {3888419400 16200 1 IRDT} - {3904313400 12600 0 IRST} - {3919955400 16200 1 IRDT} - {3935849400 12600 0 IRST} - {3951491400 16200 1 IRDT} - {3967385400 12600 0 IRST} - {3983113800 16200 1 IRDT} - {3999007800 12600 0 IRST} - {4014649800 16200 1 IRDT} - {4030543800 12600 0 IRST} - {4046185800 16200 1 IRDT} - {4062079800 12600 0 IRST} - {4077721800 16200 1 IRDT} - {4093615800 12600 0 IRST} + {-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} } diff --git a/library/tzdata/Asia/Thimphu b/library/tzdata/Asia/Thimphu index 8c981de..55c3d7f 100644 --- a/library/tzdata/Asia/Thimphu +++ b/library/tzdata/Asia/Thimphu @@ -2,6 +2,6 @@ set TZData(:Asia/Thimphu) { {-9223372036854775808 21516 0 LMT} - {-706341516 19800 0 IST} - {560025000 21600 0 BTT} + {-706341516 19800 0 +0530} + {560025000 21600 0 +06} } diff --git a/library/tzdata/Asia/Tokyo b/library/tzdata/Asia/Tokyo index 5bfc75c..10add1c 100644 --- a/library/tzdata/Asia/Tokyo +++ b/library/tzdata/Asia/Tokyo @@ -3,8 +3,6 @@ set TZData(:Asia/Tokyo) { {-9223372036854775808 33539 0 LMT} {-2587712400 32400 0 JST} - {-2335251600 32400 0 JCST} - {-1017824400 32400 0 JST} {-683794800 36000 1 JDT} {-672393600 32400 0 JST} {-654764400 36000 1 JDT} diff --git a/library/tzdata/Asia/Ulaanbaatar b/library/tzdata/Asia/Ulaanbaatar index 93e066c..e0ba7ab 100644 --- a/library/tzdata/Asia/Ulaanbaatar +++ b/library/tzdata/Asia/Ulaanbaatar @@ -2,220 +2,54 @@ set TZData(:Asia/Ulaanbaatar) { {-9223372036854775808 25652 0 LMT} - {-2032931252 25200 0 ULAT} - {252435600 28800 0 ULAT} - {417974400 32400 1 ULAST} - {433782000 28800 0 ULAT} - {449596800 32400 1 ULAST} - {465318000 28800 0 ULAT} - {481046400 32400 1 ULAST} - {496767600 28800 0 ULAT} - {512496000 32400 1 ULAST} - {528217200 28800 0 ULAT} - {543945600 32400 1 ULAST} - {559666800 28800 0 ULAT} - {575395200 32400 1 ULAST} - {591116400 28800 0 ULAT} - {606844800 32400 1 ULAST} - {622566000 28800 0 ULAT} - {638294400 32400 1 ULAST} - {654620400 28800 0 ULAT} - {670348800 32400 1 ULAST} - {686070000 28800 0 ULAT} - {701798400 32400 1 ULAST} - {717519600 28800 0 ULAT} - {733248000 32400 1 ULAST} - {748969200 28800 0 ULAT} - {764697600 32400 1 ULAST} - {780418800 28800 0 ULAT} - {796147200 32400 1 ULAST} - {811868400 28800 0 ULAT} - {828201600 32400 1 ULAST} - {843922800 28800 0 ULAT} - {859651200 32400 1 ULAST} - {875372400 28800 0 ULAT} - {891100800 32400 1 ULAST} - {906822000 28800 0 ULAT} - {988394400 32400 1 ULAST} - {1001696400 28800 0 ULAT} - {1017424800 32400 1 ULAST} - {1033146000 28800 0 ULAT} - {1048874400 32400 1 ULAST} - {1064595600 28800 0 ULAT} - {1080324000 32400 1 ULAST} - {1096045200 28800 0 ULAT} - {1111773600 32400 1 ULAST} - {1127494800 28800 0 ULAT} - {1143223200 32400 1 ULAST} - {1159549200 28800 0 ULAT} - {1427479200 32400 1 ULAST} - {1443193200 28800 0 ULAT} - {1458928800 32400 1 ULAST} - {1474642800 28800 0 ULAT} - {1490378400 32400 1 ULAST} - {1506697200 28800 0 ULAT} - {1522432800 32400 1 ULAST} - {1538146800 28800 0 ULAT} - {1553882400 32400 1 ULAST} - {1569596400 28800 0 ULAT} - {1585332000 32400 1 ULAST} - {1601046000 28800 0 ULAT} - {1616781600 32400 1 ULAST} - {1632495600 28800 0 ULAT} - {1648231200 32400 1 ULAST} - {1663945200 28800 0 ULAT} - {1679680800 32400 1 ULAST} - {1695999600 28800 0 ULAT} - {1711735200 32400 1 ULAST} - {1727449200 28800 0 ULAT} - {1743184800 32400 1 ULAST} - {1758898800 28800 0 ULAT} - {1774634400 32400 1 ULAST} - {1790348400 28800 0 ULAT} - {1806084000 32400 1 ULAST} - {1821798000 28800 0 ULAT} - {1837533600 32400 1 ULAST} - {1853852400 28800 0 ULAT} - {1869588000 32400 1 ULAST} - {1885302000 28800 0 ULAT} - {1901037600 32400 1 ULAST} - {1916751600 28800 0 ULAT} - {1932487200 32400 1 ULAST} - {1948201200 28800 0 ULAT} - {1963936800 32400 1 ULAST} - {1979650800 28800 0 ULAT} - {1995386400 32400 1 ULAST} - {2011100400 28800 0 ULAT} - {2026836000 32400 1 ULAST} - {2043154800 28800 0 ULAT} - {2058890400 32400 1 ULAST} - {2074604400 28800 0 ULAT} - {2090340000 32400 1 ULAST} - {2106054000 28800 0 ULAT} - {2121789600 32400 1 ULAST} - {2137503600 28800 0 ULAT} - {2153239200 32400 1 ULAST} - {2168953200 28800 0 ULAT} - {2184688800 32400 1 ULAST} - {2200402800 28800 0 ULAT} - {2216743200 32400 1 ULAST} - {2232457200 28800 0 ULAT} - {2248192800 32400 1 ULAST} - {2263906800 28800 0 ULAT} - {2279642400 32400 1 ULAST} - {2295356400 28800 0 ULAT} - {2311092000 32400 1 ULAST} - {2326806000 28800 0 ULAT} - {2342541600 32400 1 ULAST} - {2358255600 28800 0 ULAT} - {2373991200 32400 1 ULAST} - {2390310000 28800 0 ULAT} - {2406045600 32400 1 ULAST} - {2421759600 28800 0 ULAT} - {2437495200 32400 1 ULAST} - {2453209200 28800 0 ULAT} - {2468944800 32400 1 ULAST} - {2484658800 28800 0 ULAT} - {2500394400 32400 1 ULAST} - {2516108400 28800 0 ULAT} - {2531844000 32400 1 ULAST} - {2547558000 28800 0 ULAT} - {2563293600 32400 1 ULAST} - {2579612400 28800 0 ULAT} - {2595348000 32400 1 ULAST} - {2611062000 28800 0 ULAT} - {2626797600 32400 1 ULAST} - {2642511600 28800 0 ULAT} - {2658247200 32400 1 ULAST} - {2673961200 28800 0 ULAT} - {2689696800 32400 1 ULAST} - {2705410800 28800 0 ULAT} - {2721146400 32400 1 ULAST} - {2737465200 28800 0 ULAT} - {2753200800 32400 1 ULAST} - {2768914800 28800 0 ULAT} - {2784650400 32400 1 ULAST} - {2800364400 28800 0 ULAT} - {2816100000 32400 1 ULAST} - {2831814000 28800 0 ULAT} - {2847549600 32400 1 ULAST} - {2863263600 28800 0 ULAT} - {2878999200 32400 1 ULAST} - {2894713200 28800 0 ULAT} - {2910448800 32400 1 ULAST} - {2926767600 28800 0 ULAT} - {2942503200 32400 1 ULAST} - {2958217200 28800 0 ULAT} - {2973952800 32400 1 ULAST} - {2989666800 28800 0 ULAT} - {3005402400 32400 1 ULAST} - {3021116400 28800 0 ULAT} - {3036852000 32400 1 ULAST} - {3052566000 28800 0 ULAT} - {3068301600 32400 1 ULAST} - {3084015600 28800 0 ULAT} - {3100356000 32400 1 ULAST} - {3116070000 28800 0 ULAT} - {3131805600 32400 1 ULAST} - {3147519600 28800 0 ULAT} - {3163255200 32400 1 ULAST} - {3178969200 28800 0 ULAT} - {3194704800 32400 1 ULAST} - {3210418800 28800 0 ULAT} - {3226154400 32400 1 ULAST} - {3241868400 28800 0 ULAT} - {3257604000 32400 1 ULAST} - {3273922800 28800 0 ULAT} - {3289658400 32400 1 ULAST} - {3305372400 28800 0 ULAT} - {3321108000 32400 1 ULAST} - {3336822000 28800 0 ULAT} - {3352557600 32400 1 ULAST} - {3368271600 28800 0 ULAT} - {3384007200 32400 1 ULAST} - {3399721200 28800 0 ULAT} - {3415456800 32400 1 ULAST} - {3431170800 28800 0 ULAT} - {3446906400 32400 1 ULAST} - {3463225200 28800 0 ULAT} - {3478960800 32400 1 ULAST} - {3494674800 28800 0 ULAT} - {3510410400 32400 1 ULAST} - {3526124400 28800 0 ULAT} - {3541860000 32400 1 ULAST} - {3557574000 28800 0 ULAT} - {3573309600 32400 1 ULAST} - {3589023600 28800 0 ULAT} - {3604759200 32400 1 ULAST} - {3621078000 28800 0 ULAT} - {3636813600 32400 1 ULAST} - {3652527600 28800 0 ULAT} - {3668263200 32400 1 ULAST} - {3683977200 28800 0 ULAT} - {3699712800 32400 1 ULAST} - {3715426800 28800 0 ULAT} - {3731162400 32400 1 ULAST} - {3746876400 28800 0 ULAT} - {3762612000 32400 1 ULAST} - {3778326000 28800 0 ULAT} - {3794061600 32400 1 ULAST} - {3810380400 28800 0 ULAT} - {3826116000 32400 1 ULAST} - {3841830000 28800 0 ULAT} - {3857565600 32400 1 ULAST} - {3873279600 28800 0 ULAT} - {3889015200 32400 1 ULAST} - {3904729200 28800 0 ULAT} - {3920464800 32400 1 ULAST} - {3936178800 28800 0 ULAT} - {3951914400 32400 1 ULAST} - {3967628400 28800 0 ULAT} - {3983968800 32400 1 ULAST} - {3999682800 28800 0 ULAT} - {4015418400 32400 1 ULAST} - {4031132400 28800 0 ULAT} - {4046868000 32400 1 ULAST} - {4062582000 28800 0 ULAT} - {4078317600 32400 1 ULAST} - {4094031600 28800 0 ULAT} + {-2032931252 25200 0 +07} + {252435600 28800 0 +08} + {417974400 32400 1 +09} + {433782000 28800 0 +08} + {449596800 32400 1 +09} + {465318000 28800 0 +08} + {481046400 32400 1 +09} + {496767600 28800 0 +08} + {512496000 32400 1 +09} + {528217200 28800 0 +08} + {543945600 32400 1 +09} + {559666800 28800 0 +08} + {575395200 32400 1 +09} + {591116400 28800 0 +08} + {606844800 32400 1 +09} + {622566000 28800 0 +08} + {638294400 32400 1 +09} + {654620400 28800 0 +08} + {670348800 32400 1 +09} + {686070000 28800 0 +08} + {701798400 32400 1 +09} + {717519600 28800 0 +08} + {733248000 32400 1 +09} + {748969200 28800 0 +08} + {764697600 32400 1 +09} + {780418800 28800 0 +08} + {796147200 32400 1 +09} + {811868400 28800 0 +08} + {828201600 32400 1 +09} + {843922800 28800 0 +08} + {859651200 32400 1 +09} + {875372400 28800 0 +08} + {891100800 32400 1 +09} + {906822000 28800 0 +08} + {988394400 32400 1 +09} + {1001696400 28800 0 +08} + {1017424800 32400 1 +09} + {1033146000 28800 0 +08} + {1048874400 32400 1 +09} + {1064595600 28800 0 +08} + {1080324000 32400 1 +09} + {1096045200 28800 0 +08} + {1111773600 32400 1 +09} + {1127494800 28800 0 +08} + {1143223200 32400 1 +09} + {1159549200 28800 0 +08} + {1427479200 32400 1 +09} + {1443193200 28800 0 +08} + {1458928800 32400 1 +09} + {1474642800 28800 0 +08} } diff --git a/library/tzdata/Asia/Urumqi b/library/tzdata/Asia/Urumqi index 4f3cd67..194e090 100644 --- a/library/tzdata/Asia/Urumqi +++ b/library/tzdata/Asia/Urumqi @@ -2,5 +2,5 @@ set TZData(:Asia/Urumqi) { {-9223372036854775808 21020 0 LMT} - {-1325483420 21600 0 XJT} + {-1325483420 21600 0 +06} } diff --git a/library/tzdata/Asia/Yangon b/library/tzdata/Asia/Yangon index 40cfa02..8e17d82 100644 --- a/library/tzdata/Asia/Yangon +++ b/library/tzdata/Asia/Yangon @@ -3,7 +3,7 @@ set TZData(:Asia/Yangon) { {-9223372036854775808 23080 0 LMT} {-2840163880 23080 0 RMT} - {-1577946280 23400 0 BURT} - {-873268200 32400 0 JST} - {-778410000 23400 0 MMT} + {-1577946280 23400 0 +0630} + {-873268200 32400 0 +09} + {-778410000 23400 0 +0630} } diff --git a/library/tzdata/Atlantic/Azores b/library/tzdata/Atlantic/Azores index fd47ba5..a9bec94 100644 --- a/library/tzdata/Atlantic/Azores +++ b/library/tzdata/Atlantic/Azores @@ -3,347 +3,343 @@ set TZData(:Atlantic/Azores) { {-9223372036854775808 -6160 0 LMT} {-2713904240 -6872 0 HMT} - {-1830377128 -7200 0 AZOT} - {-1689548400 -3600 1 AZOST} - {-1677794400 -7200 0 AZOT} - {-1667430000 -3600 1 AZOST} - {-1647730800 -7200 0 AZOT} - {-1635807600 -3600 1 AZOST} - {-1616194800 -7200 0 AZOT} - {-1604358000 -3600 1 AZOST} - {-1584658800 -7200 0 AZOT} - {-1572735600 -3600 1 AZOST} - {-1553036400 -7200 0 AZOT} - {-1541199600 -3600 1 AZOST} - {-1521500400 -7200 0 AZOT} - {-1442444400 -3600 1 AZOST} - {-1426806000 -7200 0 AZOT} - {-1379286000 -3600 1 AZOST} - {-1364770800 -7200 0 AZOT} - {-1348441200 -3600 1 AZOST} - {-1333321200 -7200 0 AZOT} - {-1316386800 -3600 1 AZOST} - {-1301266800 -7200 0 AZOT} - {-1284332400 -3600 1 AZOST} - {-1269817200 -7200 0 AZOT} - {-1221433200 -3600 1 AZOST} - {-1206918000 -7200 0 AZOT} - {-1191193200 -3600 1 AZOST} - {-1175468400 -7200 0 AZOT} - {-1127689200 -3600 1 AZOST} - {-1111964400 -7200 0 AZOT} - {-1096844400 -3600 1 AZOST} - {-1080514800 -7200 0 AZOT} - {-1063580400 -3600 1 AZOST} - {-1049065200 -7200 0 AZOT} - {-1033340400 -3600 1 AZOST} - {-1017615600 -7200 0 AZOT} - {-1002495600 -3600 1 AZOST} - {-986166000 -7200 0 AZOT} - {-969231600 -3600 1 AZOST} - {-950482800 -7200 0 AZOT} - {-942015600 -3600 1 AZOST} - {-922662000 -7200 0 AZOT} - {-906937200 -3600 1 AZOST} - {-891126000 -7200 0 AZOT} - {-877302000 -3600 1 AZOST} - {-873676800 0 1 AZOMT} - {-864000000 -3600 1 AZOST} - {-857948400 -7200 0 AZOT} - {-845852400 -3600 1 AZOST} - {-842832000 0 1 AZOMT} - {-831340800 -3600 1 AZOST} - {-825894000 -7200 0 AZOT} - {-814402800 -3600 1 AZOST} - {-810777600 0 1 AZOMT} - {-799891200 -3600 1 AZOST} - {-794444400 -7200 0 AZOT} - {-782953200 -3600 1 AZOST} - {-779328000 0 1 AZOMT} - {-768441600 -3600 1 AZOST} - {-762994800 -7200 0 AZOT} - {-749084400 -3600 1 AZOST} - {-733359600 -7200 0 AZOT} - {-717624000 -3600 1 AZOST} - {-701899200 -7200 0 AZOT} - {-686174400 -3600 1 AZOST} - {-670449600 -7200 0 AZOT} - {-654724800 -3600 1 AZOST} - {-639000000 -7200 0 AZOT} - {-591825600 -3600 1 AZOST} - {-575496000 -7200 0 AZOT} - {-559771200 -3600 1 AZOST} - {-544046400 -7200 0 AZOT} - {-528321600 -3600 1 AZOST} - {-512596800 -7200 0 AZOT} - {-496872000 -3600 1 AZOST} - {-481147200 -7200 0 AZOT} - {-465422400 -3600 1 AZOST} - {-449697600 -7200 0 AZOT} - {-433972800 -3600 1 AZOST} - {-417643200 -7200 0 AZOT} - {-401918400 -3600 1 AZOST} - {-386193600 -7200 0 AZOT} - {-370468800 -3600 1 AZOST} - {-354744000 -7200 0 AZOT} - {-339019200 -3600 1 AZOST} - {-323294400 -7200 0 AZOT} - {-307569600 -3600 1 AZOST} - {-291844800 -7200 0 AZOT} - {-276120000 -3600 1 AZOST} - {-260395200 -7200 0 AZOT} - {-244670400 -3600 1 AZOST} - {-228340800 -7200 0 AZOT} - {-212616000 -3600 1 AZOST} - {-196891200 -7200 0 AZOT} - {-181166400 -3600 1 AZOST} - {-165441600 -7200 0 AZOT} - {-149716800 -3600 1 AZOST} - {-133992000 -7200 0 AZOT} - {-118267200 -3600 0 AZOT} - {228272400 0 1 AZOST} - {243997200 -3600 0 AZOT} - {260326800 0 1 AZOST} - {276051600 -3600 0 AZOT} - {291776400 0 1 AZOST} - {307504800 -3600 0 AZOT} - {323226000 0 1 AZOST} - {338954400 -3600 0 AZOT} - {354679200 0 1 AZOST} - {370404000 -3600 0 AZOT} - {386128800 0 1 AZOST} - {401853600 -3600 0 AZOT} - {417582000 0 1 AZOST} - {433303200 -3600 0 AZOT} - {449028000 0 1 AZOST} - {465357600 -3600 0 AZOT} - {481082400 0 1 AZOST} - {496807200 -3600 0 AZOT} - {512532000 0 1 AZOST} - {528256800 -3600 0 AZOT} - {543981600 0 1 AZOST} - {559706400 -3600 0 AZOT} - {575431200 0 1 AZOST} - {591156000 -3600 0 AZOT} - {606880800 0 1 AZOST} - {622605600 -3600 0 AZOT} - {638330400 0 1 AZOST} - {654660000 -3600 0 AZOT} - {670384800 0 1 AZOST} - {686109600 -3600 0 AZOT} - {701834400 0 1 AZOST} - {733280400 0 0 AZOST} - {749005200 -3600 0 AZOT} - {764730000 0 1 AZOST} - {780454800 -3600 0 AZOT} - {796179600 0 1 AZOST} - {811904400 -3600 0 AZOT} - {828234000 0 1 AZOST} - {846378000 -3600 0 AZOT} - {859683600 0 1 AZOST} - {877827600 -3600 0 AZOT} - {891133200 0 1 AZOST} - {909277200 -3600 0 AZOT} - {922582800 0 1 AZOST} - {941331600 -3600 0 AZOT} - {954032400 0 1 AZOST} - {972781200 -3600 0 AZOT} - {985482000 0 1 AZOST} - {1004230800 -3600 0 AZOT} - {1017536400 0 1 AZOST} - {1035680400 -3600 0 AZOT} - {1048986000 0 1 AZOST} - {1067130000 -3600 0 AZOT} - {1080435600 0 1 AZOST} - {1099184400 -3600 0 AZOT} - {1111885200 0 1 AZOST} - {1130634000 -3600 0 AZOT} - {1143334800 0 1 AZOST} - {1162083600 -3600 0 AZOT} - {1174784400 0 1 AZOST} - {1193533200 -3600 0 AZOT} - {1206838800 0 1 AZOST} - {1224982800 -3600 0 AZOT} - {1238288400 0 1 AZOST} - {1256432400 -3600 0 AZOT} - {1269738000 0 1 AZOST} - {1288486800 -3600 0 AZOT} - {1301187600 0 1 AZOST} - {1319936400 -3600 0 AZOT} - {1332637200 0 1 AZOST} - {1351386000 -3600 0 AZOT} - {1364691600 0 1 AZOST} - {1382835600 -3600 0 AZOT} - {1396141200 0 1 AZOST} - {1414285200 -3600 0 AZOT} - {1427590800 0 1 AZOST} - {1445734800 -3600 0 AZOT} - {1459040400 0 1 AZOST} - {1477789200 -3600 0 AZOT} - {1490490000 0 1 AZOST} - {1509238800 -3600 0 AZOT} - {1521939600 0 1 AZOST} - {1540688400 -3600 0 AZOT} - {1553994000 0 1 AZOST} - {1572138000 -3600 0 AZOT} - {1585443600 0 1 AZOST} - {1603587600 -3600 0 AZOT} - {1616893200 0 1 AZOST} - {1635642000 -3600 0 AZOT} - {1648342800 0 1 AZOST} - {1667091600 -3600 0 AZOT} - {1679792400 0 1 AZOST} - {1698541200 -3600 0 AZOT} - {1711846800 0 1 AZOST} - {1729990800 -3600 0 AZOT} - {1743296400 0 1 AZOST} - {1761440400 -3600 0 AZOT} - {1774746000 0 1 AZOST} - {1792890000 -3600 0 AZOT} - {1806195600 0 1 AZOST} - {1824944400 -3600 0 AZOT} - {1837645200 0 1 AZOST} - {1856394000 -3600 0 AZOT} - {1869094800 0 1 AZOST} - {1887843600 -3600 0 AZOT} - {1901149200 0 1 AZOST} - {1919293200 -3600 0 AZOT} - {1932598800 0 1 AZOST} - {1950742800 -3600 0 AZOT} - {1964048400 0 1 AZOST} - {1982797200 -3600 0 AZOT} - {1995498000 0 1 AZOST} - {2014246800 -3600 0 AZOT} - {2026947600 0 1 AZOST} - {2045696400 -3600 0 AZOT} - {2058397200 0 1 AZOST} - {2077146000 -3600 0 AZOT} - {2090451600 0 1 AZOST} - {2108595600 -3600 0 AZOT} - {2121901200 0 1 AZOST} - {2140045200 -3600 0 AZOT} - {2153350800 0 1 AZOST} - {2172099600 -3600 0 AZOT} - {2184800400 0 1 AZOST} - {2203549200 -3600 0 AZOT} - {2216250000 0 1 AZOST} - {2234998800 -3600 0 AZOT} - {2248304400 0 1 AZOST} - {2266448400 -3600 0 AZOT} - {2279754000 0 1 AZOST} - {2297898000 -3600 0 AZOT} - {2311203600 0 1 AZOST} - {2329347600 -3600 0 AZOT} - {2342653200 0 1 AZOST} - {2361402000 -3600 0 AZOT} - {2374102800 0 1 AZOST} - {2392851600 -3600 0 AZOT} - {2405552400 0 1 AZOST} - {2424301200 -3600 0 AZOT} - {2437606800 0 1 AZOST} - {2455750800 -3600 0 AZOT} - {2469056400 0 1 AZOST} - {2487200400 -3600 0 AZOT} - {2500506000 0 1 AZOST} - {2519254800 -3600 0 AZOT} - {2531955600 0 1 AZOST} - {2550704400 -3600 0 AZOT} - {2563405200 0 1 AZOST} - {2582154000 -3600 0 AZOT} - {2595459600 0 1 AZOST} - {2613603600 -3600 0 AZOT} - {2626909200 0 1 AZOST} - {2645053200 -3600 0 AZOT} - {2658358800 0 1 AZOST} - {2676502800 -3600 0 AZOT} - {2689808400 0 1 AZOST} - {2708557200 -3600 0 AZOT} - {2721258000 0 1 AZOST} - {2740006800 -3600 0 AZOT} - {2752707600 0 1 AZOST} - {2771456400 -3600 0 AZOT} - {2784762000 0 1 AZOST} - {2802906000 -3600 0 AZOT} - {2816211600 0 1 AZOST} - {2834355600 -3600 0 AZOT} - {2847661200 0 1 AZOST} - {2866410000 -3600 0 AZOT} - {2879110800 0 1 AZOST} - {2897859600 -3600 0 AZOT} - {2910560400 0 1 AZOST} - {2929309200 -3600 0 AZOT} - {2942010000 0 1 AZOST} - {2960758800 -3600 0 AZOT} - {2974064400 0 1 AZOST} - {2992208400 -3600 0 AZOT} - {3005514000 0 1 AZOST} - {3023658000 -3600 0 AZOT} - {3036963600 0 1 AZOST} - {3055712400 -3600 0 AZOT} - {3068413200 0 1 AZOST} - {3087162000 -3600 0 AZOT} - {3099862800 0 1 AZOST} - {3118611600 -3600 0 AZOT} - {3131917200 0 1 AZOST} - {3150061200 -3600 0 AZOT} - {3163366800 0 1 AZOST} - {3181510800 -3600 0 AZOT} - {3194816400 0 1 AZOST} - {3212960400 -3600 0 AZOT} - {3226266000 0 1 AZOST} - {3245014800 -3600 0 AZOT} - {3257715600 0 1 AZOST} - {3276464400 -3600 0 AZOT} - {3289165200 0 1 AZOST} - {3307914000 -3600 0 AZOT} - {3321219600 0 1 AZOST} - {3339363600 -3600 0 AZOT} - {3352669200 0 1 AZOST} - {3370813200 -3600 0 AZOT} - {3384118800 0 1 AZOST} - {3402867600 -3600 0 AZOT} - {3415568400 0 1 AZOST} - {3434317200 -3600 0 AZOT} - {3447018000 0 1 AZOST} - {3465766800 -3600 0 AZOT} - {3479072400 0 1 AZOST} - {3497216400 -3600 0 AZOT} - {3510522000 0 1 AZOST} - {3528666000 -3600 0 AZOT} - {3541971600 0 1 AZOST} - {3560115600 -3600 0 AZOT} - {3573421200 0 1 AZOST} - {3592170000 -3600 0 AZOT} - {3604870800 0 1 AZOST} - {3623619600 -3600 0 AZOT} - {3636320400 0 1 AZOST} - {3655069200 -3600 0 AZOT} - {3668374800 0 1 AZOST} - {3686518800 -3600 0 AZOT} - {3699824400 0 1 AZOST} - {3717968400 -3600 0 AZOT} - {3731274000 0 1 AZOST} - {3750022800 -3600 0 AZOT} - {3762723600 0 1 AZOST} - {3781472400 -3600 0 AZOT} - {3794173200 0 1 AZOST} - {3812922000 -3600 0 AZOT} - {3825622800 0 1 AZOST} - {3844371600 -3600 0 AZOT} - {3857677200 0 1 AZOST} - {3875821200 -3600 0 AZOT} - {3889126800 0 1 AZOST} - {3907270800 -3600 0 AZOT} - {3920576400 0 1 AZOST} - {3939325200 -3600 0 AZOT} - {3952026000 0 1 AZOST} - {3970774800 -3600 0 AZOT} - {3983475600 0 1 AZOST} - {4002224400 -3600 0 AZOT} - {4015530000 0 1 AZOST} - {4033674000 -3600 0 AZOT} - {4046979600 0 1 AZOST} - {4065123600 -3600 0 AZOT} - {4078429200 0 1 AZOST} - {4096573200 -3600 0 AZOT} + {-1830377128 -7200 0 -02} + {-1689548400 -3600 1 -01} + {-1677794400 -7200 0 -02} + {-1667430000 -3600 1 -01} + {-1647730800 -7200 0 -02} + {-1635807600 -3600 1 -01} + {-1616194800 -7200 0 -02} + {-1604358000 -3600 1 -01} + {-1584658800 -7200 0 -02} + {-1572735600 -3600 1 -01} + {-1553036400 -7200 0 -02} + {-1541199600 -3600 1 -01} + {-1521500400 -7200 0 -02} + {-1442444400 -3600 1 -01} + {-1426806000 -7200 0 -02} + {-1379286000 -3600 1 -01} + {-1364770800 -7200 0 -02} + {-1348441200 -3600 1 -01} + {-1333321200 -7200 0 -02} + {-1316386800 -3600 1 -01} + {-1301266800 -7200 0 -02} + {-1284332400 -3600 1 -01} + {-1269817200 -7200 0 -02} + {-1221433200 -3600 1 -01} + {-1206918000 -7200 0 -02} + {-1191193200 -3600 1 -01} + {-1175468400 -7200 0 -02} + {-1127689200 -3600 1 -01} + {-1111964400 -7200 0 -02} + {-1096844400 -3600 1 -01} + {-1080514800 -7200 0 -02} + {-1063580400 -3600 1 -01} + {-1049065200 -7200 0 -02} + {-1033340400 -3600 1 -01} + {-1017615600 -7200 0 -02} + {-1002495600 -3600 1 -01} + {-986166000 -7200 0 -02} + {-969231600 -3600 1 -01} + {-950482800 -7200 0 -02} + {-942015600 -3600 1 -01} + {-922662000 -7200 0 -02} + {-906937200 -3600 1 -01} + {-891126000 -7200 0 -02} + {-877302000 -3600 1 -01} + {-864000000 -3600 0 -01} + {-857948400 -7200 0 -02} + {-845852400 -3600 1 -01} + {-831340800 -3600 0 -01} + {-825894000 -7200 0 -02} + {-814402800 -3600 1 -01} + {-799891200 -3600 0 -01} + {-794444400 -7200 0 -02} + {-782953200 -3600 1 -01} + {-768441600 -3600 0 -01} + {-762994800 -7200 0 -02} + {-749084400 -3600 1 -01} + {-733359600 -7200 0 -02} + {-717624000 -3600 1 -01} + {-701899200 -7200 0 -02} + {-686174400 -3600 1 -01} + {-670449600 -7200 0 -02} + {-654724800 -3600 1 -01} + {-639000000 -7200 0 -02} + {-591825600 -3600 1 -01} + {-575496000 -7200 0 -02} + {-559771200 -3600 1 -01} + {-544046400 -7200 0 -02} + {-528321600 -3600 1 -01} + {-512596800 -7200 0 -02} + {-496872000 -3600 1 -01} + {-481147200 -7200 0 -02} + {-465422400 -3600 1 -01} + {-449697600 -7200 0 -02} + {-433972800 -3600 1 -01} + {-417643200 -7200 0 -02} + {-401918400 -3600 1 -01} + {-386193600 -7200 0 -02} + {-370468800 -3600 1 -01} + {-354744000 -7200 0 -02} + {-339019200 -3600 1 -01} + {-323294400 -7200 0 -02} + {-307569600 -3600 1 -01} + {-291844800 -7200 0 -02} + {-276120000 -3600 1 -01} + {-260395200 -7200 0 -02} + {-244670400 -3600 1 -01} + {-228340800 -7200 0 -02} + {-212616000 -3600 1 -01} + {-196891200 -7200 0 -02} + {-181166400 -3600 1 -01} + {-165441600 -7200 0 -02} + {-149716800 -3600 1 -01} + {-133992000 -7200 0 -02} + {-118267200 -3600 0 -01} + {228272400 0 1 +00} + {243997200 -3600 0 -01} + {260326800 0 1 +00} + {276051600 -3600 0 -01} + {291776400 0 1 +00} + {307504800 -3600 0 -01} + {323226000 0 1 +00} + {338954400 -3600 0 -01} + {354679200 0 1 +00} + {370404000 -3600 0 -01} + {386128800 0 1 +00} + {401853600 -3600 0 -01} + {417582000 0 1 +00} + {433303200 -3600 0 -01} + {449028000 0 1 +00} + {465357600 -3600 0 -01} + {481082400 0 1 +00} + {496807200 -3600 0 -01} + {512532000 0 1 +00} + {528256800 -3600 0 -01} + {543981600 0 1 +00} + {559706400 -3600 0 -01} + {575431200 0 1 +00} + {591156000 -3600 0 -01} + {606880800 0 1 +00} + {622605600 -3600 0 -01} + {638330400 0 1 +00} + {654660000 -3600 0 -01} + {670384800 0 1 +00} + {686109600 -3600 0 -01} + {701834400 0 1 +00} + {733280400 0 0 +00} + {749005200 -3600 0 -01} + {764730000 0 1 +00} + {780454800 -3600 0 -01} + {796179600 0 1 +00} + {811904400 -3600 0 -01} + {828234000 0 1 +00} + {846378000 -3600 0 -01} + {859683600 0 1 +00} + {877827600 -3600 0 -01} + {891133200 0 1 +00} + {909277200 -3600 0 -01} + {922582800 0 1 +00} + {941331600 -3600 0 -01} + {954032400 0 1 +00} + {972781200 -3600 0 -01} + {985482000 0 1 +00} + {1004230800 -3600 0 -01} + {1017536400 0 1 +00} + {1035680400 -3600 0 -01} + {1048986000 0 1 +00} + {1067130000 -3600 0 -01} + {1080435600 0 1 +00} + {1099184400 -3600 0 -01} + {1111885200 0 1 +00} + {1130634000 -3600 0 -01} + {1143334800 0 1 +00} + {1162083600 -3600 0 -01} + {1174784400 0 1 +00} + {1193533200 -3600 0 -01} + {1206838800 0 1 +00} + {1224982800 -3600 0 -01} + {1238288400 0 1 +00} + {1256432400 -3600 0 -01} + {1269738000 0 1 +00} + {1288486800 -3600 0 -01} + {1301187600 0 1 +00} + {1319936400 -3600 0 -01} + {1332637200 0 1 +00} + {1351386000 -3600 0 -01} + {1364691600 0 1 +00} + {1382835600 -3600 0 -01} + {1396141200 0 1 +00} + {1414285200 -3600 0 -01} + {1427590800 0 1 +00} + {1445734800 -3600 0 -01} + {1459040400 0 1 +00} + {1477789200 -3600 0 -01} + {1490490000 0 1 +00} + {1509238800 -3600 0 -01} + {1521939600 0 1 +00} + {1540688400 -3600 0 -01} + {1553994000 0 1 +00} + {1572138000 -3600 0 -01} + {1585443600 0 1 +00} + {1603587600 -3600 0 -01} + {1616893200 0 1 +00} + {1635642000 -3600 0 -01} + {1648342800 0 1 +00} + {1667091600 -3600 0 -01} + {1679792400 0 1 +00} + {1698541200 -3600 0 -01} + {1711846800 0 1 +00} + {1729990800 -3600 0 -01} + {1743296400 0 1 +00} + {1761440400 -3600 0 -01} + {1774746000 0 1 +00} + {1792890000 -3600 0 -01} + {1806195600 0 1 +00} + {1824944400 -3600 0 -01} + {1837645200 0 1 +00} + {1856394000 -3600 0 -01} + {1869094800 0 1 +00} + {1887843600 -3600 0 -01} + {1901149200 0 1 +00} + {1919293200 -3600 0 -01} + {1932598800 0 1 +00} + {1950742800 -3600 0 -01} + {1964048400 0 1 +00} + {1982797200 -3600 0 -01} + {1995498000 0 1 +00} + {2014246800 -3600 0 -01} + {2026947600 0 1 +00} + {2045696400 -3600 0 -01} + {2058397200 0 1 +00} + {2077146000 -3600 0 -01} + {2090451600 0 1 +00} + {2108595600 -3600 0 -01} + {2121901200 0 1 +00} + {2140045200 -3600 0 -01} + {2153350800 0 1 +00} + {2172099600 -3600 0 -01} + {2184800400 0 1 +00} + {2203549200 -3600 0 -01} + {2216250000 0 1 +00} + {2234998800 -3600 0 -01} + {2248304400 0 1 +00} + {2266448400 -3600 0 -01} + {2279754000 0 1 +00} + {2297898000 -3600 0 -01} + {2311203600 0 1 +00} + {2329347600 -3600 0 -01} + {2342653200 0 1 +00} + {2361402000 -3600 0 -01} + {2374102800 0 1 +00} + {2392851600 -3600 0 -01} + {2405552400 0 1 +00} + {2424301200 -3600 0 -01} + {2437606800 0 1 +00} + {2455750800 -3600 0 -01} + {2469056400 0 1 +00} + {2487200400 -3600 0 -01} + {2500506000 0 1 +00} + {2519254800 -3600 0 -01} + {2531955600 0 1 +00} + {2550704400 -3600 0 -01} + {2563405200 0 1 +00} + {2582154000 -3600 0 -01} + {2595459600 0 1 +00} + {2613603600 -3600 0 -01} + {2626909200 0 1 +00} + {2645053200 -3600 0 -01} + {2658358800 0 1 +00} + {2676502800 -3600 0 -01} + {2689808400 0 1 +00} + {2708557200 -3600 0 -01} + {2721258000 0 1 +00} + {2740006800 -3600 0 -01} + {2752707600 0 1 +00} + {2771456400 -3600 0 -01} + {2784762000 0 1 +00} + {2802906000 -3600 0 -01} + {2816211600 0 1 +00} + {2834355600 -3600 0 -01} + {2847661200 0 1 +00} + {2866410000 -3600 0 -01} + {2879110800 0 1 +00} + {2897859600 -3600 0 -01} + {2910560400 0 1 +00} + {2929309200 -3600 0 -01} + {2942010000 0 1 +00} + {2960758800 -3600 0 -01} + {2974064400 0 1 +00} + {2992208400 -3600 0 -01} + {3005514000 0 1 +00} + {3023658000 -3600 0 -01} + {3036963600 0 1 +00} + {3055712400 -3600 0 -01} + {3068413200 0 1 +00} + {3087162000 -3600 0 -01} + {3099862800 0 1 +00} + {3118611600 -3600 0 -01} + {3131917200 0 1 +00} + {3150061200 -3600 0 -01} + {3163366800 0 1 +00} + {3181510800 -3600 0 -01} + {3194816400 0 1 +00} + {3212960400 -3600 0 -01} + {3226266000 0 1 +00} + {3245014800 -3600 0 -01} + {3257715600 0 1 +00} + {3276464400 -3600 0 -01} + {3289165200 0 1 +00} + {3307914000 -3600 0 -01} + {3321219600 0 1 +00} + {3339363600 -3600 0 -01} + {3352669200 0 1 +00} + {3370813200 -3600 0 -01} + {3384118800 0 1 +00} + {3402867600 -3600 0 -01} + {3415568400 0 1 +00} + {3434317200 -3600 0 -01} + {3447018000 0 1 +00} + {3465766800 -3600 0 -01} + {3479072400 0 1 +00} + {3497216400 -3600 0 -01} + {3510522000 0 1 +00} + {3528666000 -3600 0 -01} + {3541971600 0 1 +00} + {3560115600 -3600 0 -01} + {3573421200 0 1 +00} + {3592170000 -3600 0 -01} + {3604870800 0 1 +00} + {3623619600 -3600 0 -01} + {3636320400 0 1 +00} + {3655069200 -3600 0 -01} + {3668374800 0 1 +00} + {3686518800 -3600 0 -01} + {3699824400 0 1 +00} + {3717968400 -3600 0 -01} + {3731274000 0 1 +00} + {3750022800 -3600 0 -01} + {3762723600 0 1 +00} + {3781472400 -3600 0 -01} + {3794173200 0 1 +00} + {3812922000 -3600 0 -01} + {3825622800 0 1 +00} + {3844371600 -3600 0 -01} + {3857677200 0 1 +00} + {3875821200 -3600 0 -01} + {3889126800 0 1 +00} + {3907270800 -3600 0 -01} + {3920576400 0 1 +00} + {3939325200 -3600 0 -01} + {3952026000 0 1 +00} + {3970774800 -3600 0 -01} + {3983475600 0 1 +00} + {4002224400 -3600 0 -01} + {4015530000 0 1 +00} + {4033674000 -3600 0 -01} + {4046979600 0 1 +00} + {4065123600 -3600 0 -01} + {4078429200 0 1 +00} + {4096573200 -3600 0 -01} } diff --git a/library/tzdata/Atlantic/Canary b/library/tzdata/Atlantic/Canary index dcfba83..b5c2997 100644 --- a/library/tzdata/Atlantic/Canary +++ b/library/tzdata/Atlantic/Canary @@ -2,7 +2,7 @@ set TZData(:Atlantic/Canary) { {-9223372036854775808 -3696 0 LMT} - {-1509663504 -3600 0 CANT} + {-1509663504 -3600 0 -01} {-733874400 0 0 WET} {323827200 3600 1 WEST} {338950800 0 0 WET} diff --git a/library/tzdata/Atlantic/Cape_Verde b/library/tzdata/Atlantic/Cape_Verde index f0bb79f..6fc94eb 100644 --- a/library/tzdata/Atlantic/Cape_Verde +++ b/library/tzdata/Atlantic/Cape_Verde @@ -2,8 +2,8 @@ set TZData(:Atlantic/Cape_Verde) { {-9223372036854775808 -5644 0 LMT} - {-1988144756 -7200 0 CVT} - {-862610400 -3600 1 CVST} - {-764118000 -7200 0 CVT} - {186120000 -3600 0 CVT} + {-1988144756 -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 fac7f92..cc5e5f8 100644 --- a/library/tzdata/Atlantic/Madeira +++ b/library/tzdata/Atlantic/Madeira @@ -3,103 +3,99 @@ set TZData(:Atlantic/Madeira) { {-9223372036854775808 -4056 0 LMT} {-2713906344 -4056 0 FMT} - {-1830379944 -3600 0 MADT} - {-1689552000 0 1 MADST} - {-1677798000 -3600 0 MADT} - {-1667433600 0 1 MADST} - {-1647734400 -3600 0 MADT} - {-1635811200 0 1 MADST} - {-1616198400 -3600 0 MADT} - {-1604361600 0 1 MADST} - {-1584662400 -3600 0 MADT} - {-1572739200 0 1 MADST} - {-1553040000 -3600 0 MADT} - {-1541203200 0 1 MADST} - {-1521504000 -3600 0 MADT} - {-1442448000 0 1 MADST} - {-1426809600 -3600 0 MADT} - {-1379289600 0 1 MADST} - {-1364774400 -3600 0 MADT} - {-1348444800 0 1 MADST} - {-1333324800 -3600 0 MADT} - {-1316390400 0 1 MADST} - {-1301270400 -3600 0 MADT} - {-1284336000 0 1 MADST} - {-1269820800 -3600 0 MADT} - {-1221436800 0 1 MADST} - {-1206921600 -3600 0 MADT} - {-1191196800 0 1 MADST} - {-1175472000 -3600 0 MADT} - {-1127692800 0 1 MADST} - {-1111968000 -3600 0 MADT} - {-1096848000 0 1 MADST} - {-1080518400 -3600 0 MADT} - {-1063584000 0 1 MADST} - {-1049068800 -3600 0 MADT} - {-1033344000 0 1 MADST} - {-1017619200 -3600 0 MADT} - {-1002499200 0 1 MADST} - {-986169600 -3600 0 MADT} - {-969235200 0 1 MADST} - {-950486400 -3600 0 MADT} - {-942019200 0 1 MADST} - {-922665600 -3600 0 MADT} - {-906940800 0 1 MADST} - {-891129600 -3600 0 MADT} - {-877305600 0 1 MADST} - {-873680400 3600 1 MADMT} - {-864003600 0 1 MADST} - {-857952000 -3600 0 MADT} - {-845856000 0 1 MADST} - {-842835600 3600 1 MADMT} - {-831344400 0 1 MADST} - {-825897600 -3600 0 MADT} - {-814406400 0 1 MADST} - {-810781200 3600 1 MADMT} - {-799894800 0 1 MADST} - {-794448000 -3600 0 MADT} - {-782956800 0 1 MADST} - {-779331600 3600 1 MADMT} - {-768445200 0 1 MADST} - {-762998400 -3600 0 MADT} - {-749088000 0 1 MADST} - {-733363200 -3600 0 MADT} - {-717627600 0 1 MADST} - {-701902800 -3600 0 MADT} - {-686178000 0 1 MADST} - {-670453200 -3600 0 MADT} - {-654728400 0 1 MADST} - {-639003600 -3600 0 MADT} - {-591829200 0 1 MADST} - {-575499600 -3600 0 MADT} - {-559774800 0 1 MADST} - {-544050000 -3600 0 MADT} - {-528325200 0 1 MADST} - {-512600400 -3600 0 MADT} - {-496875600 0 1 MADST} - {-481150800 -3600 0 MADT} - {-465426000 0 1 MADST} - {-449701200 -3600 0 MADT} - {-433976400 0 1 MADST} - {-417646800 -3600 0 MADT} - {-401922000 0 1 MADST} - {-386197200 -3600 0 MADT} - {-370472400 0 1 MADST} - {-354747600 -3600 0 MADT} - {-339022800 0 1 MADST} - {-323298000 -3600 0 MADT} - {-307573200 0 1 MADST} - {-291848400 -3600 0 MADT} - {-276123600 0 1 MADST} - {-260398800 -3600 0 MADT} - {-244674000 0 1 MADST} - {-228344400 -3600 0 MADT} - {-212619600 0 1 MADST} - {-196894800 -3600 0 MADT} - {-181170000 0 1 MADST} - {-165445200 -3600 0 MADT} - {-149720400 0 1 MADST} - {-133995600 -3600 0 MADT} + {-1830379944 -3600 0 -01} + {-1689552000 0 1 +00} + {-1677798000 -3600 0 -01} + {-1667433600 0 1 +00} + {-1647734400 -3600 0 -01} + {-1635811200 0 1 +00} + {-1616198400 -3600 0 -01} + {-1604361600 0 1 +00} + {-1584662400 -3600 0 -01} + {-1572739200 0 1 +00} + {-1553040000 -3600 0 -01} + {-1541203200 0 1 +00} + {-1521504000 -3600 0 -01} + {-1442448000 0 1 +00} + {-1426809600 -3600 0 -01} + {-1379289600 0 1 +00} + {-1364774400 -3600 0 -01} + {-1348444800 0 1 +00} + {-1333324800 -3600 0 -01} + {-1316390400 0 1 +00} + {-1301270400 -3600 0 -01} + {-1284336000 0 1 +00} + {-1269820800 -3600 0 -01} + {-1221436800 0 1 +00} + {-1206921600 -3600 0 -01} + {-1191196800 0 1 +00} + {-1175472000 -3600 0 -01} + {-1127692800 0 1 +00} + {-1111968000 -3600 0 -01} + {-1096848000 0 1 +00} + {-1080518400 -3600 0 -01} + {-1063584000 0 1 +00} + {-1049068800 -3600 0 -01} + {-1033344000 0 1 +00} + {-1017619200 -3600 0 -01} + {-1002499200 0 1 +00} + {-986169600 -3600 0 -01} + {-969235200 0 1 +00} + {-950486400 -3600 0 -01} + {-942019200 0 1 +00} + {-922665600 -3600 0 -01} + {-906940800 0 1 +00} + {-891129600 -3600 0 -01} + {-877305600 0 1 +00} + {-864003600 0 0 +00} + {-857952000 -3600 0 -01} + {-845856000 0 1 +00} + {-831344400 0 0 +00} + {-825897600 -3600 0 -01} + {-814406400 0 1 +00} + {-799894800 0 0 +00} + {-794448000 -3600 0 -01} + {-782956800 0 1 +00} + {-768445200 0 0 +00} + {-762998400 -3600 0 -01} + {-749088000 0 1 +00} + {-733363200 -3600 0 -01} + {-717627600 0 1 +00} + {-701902800 -3600 0 -01} + {-686178000 0 1 +00} + {-670453200 -3600 0 -01} + {-654728400 0 1 +00} + {-639003600 -3600 0 -01} + {-591829200 0 1 +00} + {-575499600 -3600 0 -01} + {-559774800 0 1 +00} + {-544050000 -3600 0 -01} + {-528325200 0 1 +00} + {-512600400 -3600 0 -01} + {-496875600 0 1 +00} + {-481150800 -3600 0 -01} + {-465426000 0 1 +00} + {-449701200 -3600 0 -01} + {-433976400 0 1 +00} + {-417646800 -3600 0 -01} + {-401922000 0 1 +00} + {-386197200 -3600 0 -01} + {-370472400 0 1 +00} + {-354747600 -3600 0 -01} + {-339022800 0 1 +00} + {-323298000 -3600 0 -01} + {-307573200 0 1 +00} + {-291848400 -3600 0 -01} + {-276123600 0 1 +00} + {-260398800 -3600 0 -01} + {-244674000 0 1 +00} + {-228344400 -3600 0 -01} + {-212619600 0 1 +00} + {-196894800 -3600 0 -01} + {-181170000 0 1 +00} + {-165445200 -3600 0 -01} + {-149720400 0 1 +00} + {-133995600 -3600 0 -01} {-118270800 0 0 WET} {228268800 3600 1 WEST} {243993600 0 0 WET} diff --git a/library/tzdata/Atlantic/Reykjavik b/library/tzdata/Atlantic/Reykjavik index ad7f0db..5555460 100644 --- a/library/tzdata/Atlantic/Reykjavik +++ b/library/tzdata/Atlantic/Reykjavik @@ -2,72 +2,72 @@ set TZData(:Atlantic/Reykjavik) { {-9223372036854775808 -5280 0 LMT} - {-1956609120 -3600 0 IST} - {-1668211200 0 1 ISST} - {-1647212400 -3600 0 IST} - {-1636675200 0 1 ISST} - {-1613430000 -3600 0 IST} - {-1605139200 0 1 ISST} - {-1581894000 -3600 0 IST} - {-1539561600 0 1 ISST} - {-1531350000 -3600 0 IST} - {-968025600 0 1 ISST} - {-952293600 -3600 0 IST} - {-942008400 0 1 ISST} - {-920239200 -3600 0 IST} - {-909957600 0 1 ISST} - {-888789600 -3600 0 IST} - {-877903200 0 1 ISST} - {-857944800 -3600 0 IST} - {-846453600 0 1 ISST} - {-826495200 -3600 0 IST} - {-815004000 0 1 ISST} - {-795045600 -3600 0 IST} - {-783554400 0 1 ISST} - {-762991200 -3600 0 IST} - {-752104800 0 1 ISST} - {-731541600 -3600 0 IST} - {-717631200 0 1 ISST} - {-700092000 -3600 0 IST} - {-686181600 0 1 ISST} - {-668642400 -3600 0 IST} - {-654732000 0 1 ISST} - {-636588000 -3600 0 IST} - {-623282400 0 1 ISST} - {-605743200 -3600 0 IST} - {-591832800 0 1 ISST} - {-573688800 -3600 0 IST} - {-559778400 0 1 ISST} - {-542239200 -3600 0 IST} - {-528328800 0 1 ISST} - {-510789600 -3600 0 IST} - {-496879200 0 1 ISST} - {-479340000 -3600 0 IST} - {-465429600 0 1 ISST} - {-447890400 -3600 0 IST} - {-433980000 0 1 ISST} - {-415836000 -3600 0 IST} - {-401925600 0 1 ISST} - {-384386400 -3600 0 IST} - {-370476000 0 1 ISST} - {-352936800 -3600 0 IST} - {-339026400 0 1 ISST} - {-321487200 -3600 0 IST} - {-307576800 0 1 ISST} - {-290037600 -3600 0 IST} - {-276127200 0 1 ISST} - {-258588000 -3600 0 IST} - {-244677600 0 1 ISST} - {-226533600 -3600 0 IST} - {-212623200 0 1 ISST} - {-195084000 -3600 0 IST} - {-181173600 0 1 ISST} - {-163634400 -3600 0 IST} - {-149724000 0 1 ISST} - {-132184800 -3600 0 IST} - {-118274400 0 1 ISST} - {-100735200 -3600 0 IST} - {-86824800 0 1 ISST} - {-68680800 -3600 0 IST} + {-1956609120 -3600 0 -01} + {-1668211200 0 1 +00} + {-1647212400 -3600 0 -01} + {-1636675200 0 1 +00} + {-1613430000 -3600 0 -01} + {-1605139200 0 1 +00} + {-1581894000 -3600 0 -01} + {-1539561600 0 1 +00} + {-1531350000 -3600 0 -01} + {-968025600 0 1 +00} + {-952293600 -3600 0 -01} + {-942008400 0 1 +00} + {-920239200 -3600 0 -01} + {-909957600 0 1 +00} + {-888789600 -3600 0 -01} + {-877903200 0 1 +00} + {-857944800 -3600 0 -01} + {-846453600 0 1 +00} + {-826495200 -3600 0 -01} + {-815004000 0 1 +00} + {-795045600 -3600 0 -01} + {-783554400 0 1 +00} + {-762991200 -3600 0 -01} + {-752104800 0 1 +00} + {-731541600 -3600 0 -01} + {-717631200 0 1 +00} + {-700092000 -3600 0 -01} + {-686181600 0 1 +00} + {-668642400 -3600 0 -01} + {-654732000 0 1 +00} + {-636588000 -3600 0 -01} + {-623282400 0 1 +00} + {-605743200 -3600 0 -01} + {-591832800 0 1 +00} + {-573688800 -3600 0 -01} + {-559778400 0 1 +00} + {-542239200 -3600 0 -01} + {-528328800 0 1 +00} + {-510789600 -3600 0 -01} + {-496879200 0 1 +00} + {-479340000 -3600 0 -01} + {-465429600 0 1 +00} + {-447890400 -3600 0 -01} + {-433980000 0 1 +00} + {-415836000 -3600 0 -01} + {-401925600 0 1 +00} + {-384386400 -3600 0 -01} + {-370476000 0 1 +00} + {-352936800 -3600 0 -01} + {-339026400 0 1 +00} + {-321487200 -3600 0 -01} + {-307576800 0 1 +00} + {-290037600 -3600 0 -01} + {-276127200 0 1 +00} + {-258588000 -3600 0 -01} + {-244677600 0 1 +00} + {-226533600 -3600 0 -01} + {-212623200 0 1 +00} + {-195084000 -3600 0 -01} + {-181173600 0 1 +00} + {-163634400 -3600 0 -01} + {-149724000 0 1 +00} + {-132184800 -3600 0 -01} + {-118274400 0 1 +00} + {-100735200 -3600 0 -01} + {-86824800 0 1 +00} + {-68680800 -3600 0 -01} {-54770400 0 0 GMT} } diff --git a/library/tzdata/Atlantic/South_Georgia b/library/tzdata/Atlantic/South_Georgia index cbfc826..eb7307c 100644 --- a/library/tzdata/Atlantic/South_Georgia +++ b/library/tzdata/Atlantic/South_Georgia @@ -2,5 +2,5 @@ set TZData(:Atlantic/South_Georgia) { {-9223372036854775808 -8768 0 LMT} - {-2524512832 -7200 0 GST} + {-2524512832 -7200 0 -02} } diff --git a/library/tzdata/Atlantic/Stanley b/library/tzdata/Atlantic/Stanley index c287238..5210832 100644 --- a/library/tzdata/Atlantic/Stanley +++ b/library/tzdata/Atlantic/Stanley @@ -3,73 +3,73 @@ set TZData(:Atlantic/Stanley) { {-9223372036854775808 -13884 0 LMT} {-2524507716 -13884 0 SMT} - {-1824235716 -14400 0 FKT} - {-1018209600 -10800 1 FKST} - {-1003093200 -14400 0 FKT} - {-986760000 -10800 1 FKST} - {-971643600 -14400 0 FKT} - {-954705600 -10800 1 FKST} - {-939589200 -14400 0 FKT} - {-923256000 -10800 1 FKST} - {-908139600 -14400 0 FKT} - {-891806400 -10800 1 FKST} - {-876690000 -14400 0 FKT} - {-860356800 -10800 1 FKST} - {420606000 -7200 0 FKT} - {433303200 -7200 1 FKST} - {452052000 -10800 0 FKT} - {464151600 -7200 1 FKST} - {483501600 -10800 0 FKT} - {495597600 -14400 0 FKT} - {495604800 -10800 1 FKST} - {514350000 -14400 0 FKT} - {527054400 -10800 1 FKST} - {545799600 -14400 0 FKT} - {558504000 -10800 1 FKST} - {577249200 -14400 0 FKT} - {589953600 -10800 1 FKST} - {608698800 -14400 0 FKT} - {621403200 -10800 1 FKST} - {640753200 -14400 0 FKT} - {652852800 -10800 1 FKST} - {672202800 -14400 0 FKT} - {684907200 -10800 1 FKST} - {703652400 -14400 0 FKT} - {716356800 -10800 1 FKST} - {735102000 -14400 0 FKT} - {747806400 -10800 1 FKST} - {766551600 -14400 0 FKT} - {779256000 -10800 1 FKST} - {798001200 -14400 0 FKT} - {810705600 -10800 1 FKST} - {830055600 -14400 0 FKT} - {842760000 -10800 1 FKST} - {861505200 -14400 0 FKT} - {874209600 -10800 1 FKST} - {892954800 -14400 0 FKT} - {905659200 -10800 1 FKST} - {924404400 -14400 0 FKT} - {937108800 -10800 1 FKST} - {955854000 -14400 0 FKT} - {968558400 -10800 1 FKST} - {987310800 -14400 0 FKT} - {999410400 -10800 1 FKST} - {1019365200 -14400 0 FKT} - {1030860000 -10800 1 FKST} - {1050814800 -14400 0 FKT} - {1062914400 -10800 1 FKST} - {1082264400 -14400 0 FKT} - {1094364000 -10800 1 FKST} - {1113714000 -14400 0 FKT} - {1125813600 -10800 1 FKST} - {1145163600 -14400 0 FKT} - {1157263200 -10800 1 FKST} - {1176613200 -14400 0 FKT} - {1188712800 -10800 1 FKST} - {1208667600 -14400 0 FKT} - {1220767200 -10800 1 FKST} - {1240117200 -14400 0 FKT} - {1252216800 -10800 1 FKST} - {1271566800 -14400 0 FKT} - {1283662800 -10800 0 FKST} + {-1824235716 -14400 0 -04} + {-1018209600 -10800 1 -03} + {-1003093200 -14400 0 -04} + {-986760000 -10800 1 -03} + {-971643600 -14400 0 -04} + {-954705600 -10800 1 -03} + {-939589200 -14400 0 -04} + {-923256000 -10800 1 -03} + {-908139600 -14400 0 -04} + {-891806400 -10800 1 -03} + {-876690000 -14400 0 -04} + {-860356800 -10800 1 -03} + {420606000 -7200 0 -03} + {433303200 -7200 1 -02} + {452052000 -10800 0 -03} + {464151600 -7200 1 -02} + {483501600 -10800 0 -03} + {495597600 -14400 0 -04} + {495604800 -10800 1 -03} + {514350000 -14400 0 -04} + {527054400 -10800 1 -03} + {545799600 -14400 0 -04} + {558504000 -10800 1 -03} + {577249200 -14400 0 -04} + {589953600 -10800 1 -03} + {608698800 -14400 0 -04} + {621403200 -10800 1 -03} + {640753200 -14400 0 -04} + {652852800 -10800 1 -03} + {672202800 -14400 0 -04} + {684907200 -10800 1 -03} + {703652400 -14400 0 -04} + {716356800 -10800 1 -03} + {735102000 -14400 0 -04} + {747806400 -10800 1 -03} + {766551600 -14400 0 -04} + {779256000 -10800 1 -03} + {798001200 -14400 0 -04} + {810705600 -10800 1 -03} + {830055600 -14400 0 -04} + {842760000 -10800 1 -03} + {861505200 -14400 0 -04} + {874209600 -10800 1 -03} + {892954800 -14400 0 -04} + {905659200 -10800 1 -03} + {924404400 -14400 0 -04} + {937108800 -10800 1 -03} + {955854000 -14400 0 -04} + {968558400 -10800 1 -03} + {987310800 -14400 0 -04} + {999410400 -10800 1 -03} + {1019365200 -14400 0 -04} + {1030860000 -10800 1 -03} + {1050814800 -14400 0 -04} + {1062914400 -10800 1 -03} + {1082264400 -14400 0 -04} + {1094364000 -10800 1 -03} + {1113714000 -14400 0 -04} + {1125813600 -10800 1 -03} + {1145163600 -14400 0 -04} + {1157263200 -10800 1 -03} + {1176613200 -14400 0 -04} + {1188712800 -10800 1 -03} + {1208667600 -14400 0 -04} + {1220767200 -10800 1 -03} + {1240117200 -14400 0 -04} + {1252216800 -10800 1 -03} + {1271566800 -14400 0 -04} + {1283662800 -10800 0 -03} } diff --git a/library/tzdata/Australia/Eucla b/library/tzdata/Australia/Eucla index 08a1948..8008980 100644 --- a/library/tzdata/Australia/Eucla +++ b/library/tzdata/Australia/Eucla @@ -2,24 +2,24 @@ set TZData(:Australia/Eucla) { {-9223372036854775808 30928 0 LMT} - {-2337928528 31500 0 ACWST} - {-1672562640 35100 1 ACWDT} - {-1665387900 31500 0 ACWST} - {-883637100 35100 1 ACWDT} - {-876123900 31500 0 ACWST} - {-860395500 35100 1 ACWDT} - {-844674300 31500 0 ACWST} - {-836473500 35100 0 ACWST} - {152039700 35100 1 ACWDT} - {162926100 31500 0 ACWST} - {436295700 35100 1 ACWDT} - {447182100 31500 0 ACWST} - {690311700 35100 1 ACWDT} - {699383700 31500 0 ACWST} - {1165079700 35100 1 ACWDT} - {1174756500 31500 0 ACWST} - {1193505300 35100 1 ACWDT} - {1206810900 31500 0 ACWST} - {1224954900 35100 1 ACWDT} - {1238260500 31500 0 ACWST} + {-2337928528 31500 0 +0945} + {-1672562640 35100 1 +0945} + {-1665387900 31500 0 +0945} + {-883637100 35100 1 +0945} + {-876123900 31500 0 +0945} + {-860395500 35100 1 +0945} + {-844674300 31500 0 +0945} + {-836473500 35100 0 +0945} + {152039700 35100 1 +0945} + {162926100 31500 0 +0945} + {436295700 35100 1 +0945} + {447182100 31500 0 +0945} + {690311700 35100 1 +0945} + {699383700 31500 0 +0945} + {1165079700 35100 1 +0945} + {1174756500 31500 0 +0945} + {1193505300 35100 1 +0945} + {1206810900 31500 0 +0945} + {1224954900 35100 1 +0945} + {1238260500 31500 0 +0945} } diff --git a/library/tzdata/Australia/Lord_Howe b/library/tzdata/Australia/Lord_Howe index a8ff80e..0e2405e 100644 --- a/library/tzdata/Australia/Lord_Howe +++ b/library/tzdata/Australia/Lord_Howe @@ -3,242 +3,243 @@ set TZData(:Australia/Lord_Howe) { {-9223372036854775808 38180 0 LMT} {-2364114980 36000 0 AEST} - {352216800 37800 0 LHST} - {372785400 41400 1 LHDT} - {384273000 37800 0 LHST} - {404839800 41400 1 LHDT} - {415722600 37800 0 LHST} - {436289400 41400 1 LHDT} - {447172200 37800 0 LHST} - {467739000 41400 1 LHDT} - {478621800 37800 0 LHST} - {499188600 39600 1 LHDT} - {511282800 37800 0 LHST} - {530033400 39600 1 LHDT} - {542732400 37800 0 LHST} - {562087800 39600 1 LHDT} - {574786800 37800 0 LHST} - {594142200 39600 1 LHDT} - {606236400 37800 0 LHST} - {625591800 39600 1 LHDT} - {636476400 37800 0 LHST} - {657041400 39600 1 LHDT} - {667926000 37800 0 LHST} - {688491000 39600 1 LHDT} - {699375600 37800 0 LHST} - {719940600 39600 1 LHDT} - {731430000 37800 0 LHST} - {751995000 39600 1 LHDT} - {762879600 37800 0 LHST} - {783444600 39600 1 LHDT} - {794329200 37800 0 LHST} - {814894200 39600 1 LHDT} - {828198000 37800 0 LHST} - {846343800 39600 1 LHDT} - {859647600 37800 0 LHST} - {877793400 39600 1 LHDT} - {891097200 37800 0 LHST} - {909243000 39600 1 LHDT} - {922546800 37800 0 LHST} - {941297400 39600 1 LHDT} - {953996400 37800 0 LHST} - {967303800 39600 1 LHDT} - {985446000 37800 0 LHST} - {1004196600 39600 1 LHDT} - {1017500400 37800 0 LHST} - {1035646200 39600 1 LHDT} - {1048950000 37800 0 LHST} - {1067095800 39600 1 LHDT} - {1080399600 37800 0 LHST} - {1099150200 39600 1 LHDT} - {1111849200 37800 0 LHST} - {1130599800 39600 1 LHDT} - {1143903600 37800 0 LHST} - {1162049400 39600 1 LHDT} - {1174748400 37800 0 LHST} - {1193499000 39600 1 LHDT} - {1207407600 37800 0 LHST} - {1223134200 39600 1 LHDT} - {1238857200 37800 0 LHST} - {1254583800 39600 1 LHDT} - {1270306800 37800 0 LHST} - {1286033400 39600 1 LHDT} - {1301756400 37800 0 LHST} - {1317483000 39600 1 LHDT} - {1333206000 37800 0 LHST} - {1349537400 39600 1 LHDT} - {1365260400 37800 0 LHST} - {1380987000 39600 1 LHDT} - {1396710000 37800 0 LHST} - {1412436600 39600 1 LHDT} - {1428159600 37800 0 LHST} - {1443886200 39600 1 LHDT} - {1459609200 37800 0 LHST} - {1475335800 39600 1 LHDT} - {1491058800 37800 0 LHST} - {1506785400 39600 1 LHDT} - {1522508400 37800 0 LHST} - {1538839800 39600 1 LHDT} - {1554562800 37800 0 LHST} - {1570289400 39600 1 LHDT} - {1586012400 37800 0 LHST} - {1601739000 39600 1 LHDT} - {1617462000 37800 0 LHST} - {1633188600 39600 1 LHDT} - {1648911600 37800 0 LHST} - {1664638200 39600 1 LHDT} - {1680361200 37800 0 LHST} - {1696087800 39600 1 LHDT} - {1712415600 37800 0 LHST} - {1728142200 39600 1 LHDT} - {1743865200 37800 0 LHST} - {1759591800 39600 1 LHDT} - {1775314800 37800 0 LHST} - {1791041400 39600 1 LHDT} - {1806764400 37800 0 LHST} - {1822491000 39600 1 LHDT} - {1838214000 37800 0 LHST} - {1853940600 39600 1 LHDT} - {1869663600 37800 0 LHST} - {1885995000 39600 1 LHDT} - {1901718000 37800 0 LHST} - {1917444600 39600 1 LHDT} - {1933167600 37800 0 LHST} - {1948894200 39600 1 LHDT} - {1964617200 37800 0 LHST} - {1980343800 39600 1 LHDT} - {1996066800 37800 0 LHST} - {2011793400 39600 1 LHDT} - {2027516400 37800 0 LHST} - {2043243000 39600 1 LHDT} - {2058966000 37800 0 LHST} - {2075297400 39600 1 LHDT} - {2091020400 37800 0 LHST} - {2106747000 39600 1 LHDT} - {2122470000 37800 0 LHST} - {2138196600 39600 1 LHDT} - {2153919600 37800 0 LHST} - {2169646200 39600 1 LHDT} - {2185369200 37800 0 LHST} - {2201095800 39600 1 LHDT} - {2216818800 37800 0 LHST} - {2233150200 39600 1 LHDT} - {2248873200 37800 0 LHST} - {2264599800 39600 1 LHDT} - {2280322800 37800 0 LHST} - {2296049400 39600 1 LHDT} - {2311772400 37800 0 LHST} - {2327499000 39600 1 LHDT} - {2343222000 37800 0 LHST} - {2358948600 39600 1 LHDT} - {2374671600 37800 0 LHST} - {2390398200 39600 1 LHDT} - {2406121200 37800 0 LHST} - {2422452600 39600 1 LHDT} - {2438175600 37800 0 LHST} - {2453902200 39600 1 LHDT} - {2469625200 37800 0 LHST} - {2485351800 39600 1 LHDT} - {2501074800 37800 0 LHST} - {2516801400 39600 1 LHDT} - {2532524400 37800 0 LHST} - {2548251000 39600 1 LHDT} - {2563974000 37800 0 LHST} - {2579700600 39600 1 LHDT} - {2596028400 37800 0 LHST} - {2611755000 39600 1 LHDT} - {2627478000 37800 0 LHST} - {2643204600 39600 1 LHDT} - {2658927600 37800 0 LHST} - {2674654200 39600 1 LHDT} - {2690377200 37800 0 LHST} - {2706103800 39600 1 LHDT} - {2721826800 37800 0 LHST} - {2737553400 39600 1 LHDT} - {2753276400 37800 0 LHST} - {2769607800 39600 1 LHDT} - {2785330800 37800 0 LHST} - {2801057400 39600 1 LHDT} - {2816780400 37800 0 LHST} - {2832507000 39600 1 LHDT} - {2848230000 37800 0 LHST} - {2863956600 39600 1 LHDT} - {2879679600 37800 0 LHST} - {2895406200 39600 1 LHDT} - {2911129200 37800 0 LHST} - {2926855800 39600 1 LHDT} - {2942578800 37800 0 LHST} - {2958910200 39600 1 LHDT} - {2974633200 37800 0 LHST} - {2990359800 39600 1 LHDT} - {3006082800 37800 0 LHST} - {3021809400 39600 1 LHDT} - {3037532400 37800 0 LHST} - {3053259000 39600 1 LHDT} - {3068982000 37800 0 LHST} - {3084708600 39600 1 LHDT} - {3100431600 37800 0 LHST} - {3116763000 39600 1 LHDT} - {3132486000 37800 0 LHST} - {3148212600 39600 1 LHDT} - {3163935600 37800 0 LHST} - {3179662200 39600 1 LHDT} - {3195385200 37800 0 LHST} - {3211111800 39600 1 LHDT} - {3226834800 37800 0 LHST} - {3242561400 39600 1 LHDT} - {3258284400 37800 0 LHST} - {3274011000 39600 1 LHDT} - {3289734000 37800 0 LHST} - {3306065400 39600 1 LHDT} - {3321788400 37800 0 LHST} - {3337515000 39600 1 LHDT} - {3353238000 37800 0 LHST} - {3368964600 39600 1 LHDT} - {3384687600 37800 0 LHST} - {3400414200 39600 1 LHDT} - {3416137200 37800 0 LHST} - {3431863800 39600 1 LHDT} - {3447586800 37800 0 LHST} - {3463313400 39600 1 LHDT} - {3479641200 37800 0 LHST} - {3495367800 39600 1 LHDT} - {3511090800 37800 0 LHST} - {3526817400 39600 1 LHDT} - {3542540400 37800 0 LHST} - {3558267000 39600 1 LHDT} - {3573990000 37800 0 LHST} - {3589716600 39600 1 LHDT} - {3605439600 37800 0 LHST} - {3621166200 39600 1 LHDT} - {3636889200 37800 0 LHST} - {3653220600 39600 1 LHDT} - {3668943600 37800 0 LHST} - {3684670200 39600 1 LHDT} - {3700393200 37800 0 LHST} - {3716119800 39600 1 LHDT} - {3731842800 37800 0 LHST} - {3747569400 39600 1 LHDT} - {3763292400 37800 0 LHST} - {3779019000 39600 1 LHDT} - {3794742000 37800 0 LHST} - {3810468600 39600 1 LHDT} - {3826191600 37800 0 LHST} - {3842523000 39600 1 LHDT} - {3858246000 37800 0 LHST} - {3873972600 39600 1 LHDT} - {3889695600 37800 0 LHST} - {3905422200 39600 1 LHDT} - {3921145200 37800 0 LHST} - {3936871800 39600 1 LHDT} - {3952594800 37800 0 LHST} - {3968321400 39600 1 LHDT} - {3984044400 37800 0 LHST} - {4000375800 39600 1 LHDT} - {4016098800 37800 0 LHST} - {4031825400 39600 1 LHDT} - {4047548400 37800 0 LHST} - {4063275000 39600 1 LHDT} - {4078998000 37800 0 LHST} - {4094724600 39600 1 LHDT} + {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} } diff --git a/library/tzdata/Europe/Amsterdam b/library/tzdata/Europe/Amsterdam index bd89127..b683c99 100644 --- a/library/tzdata/Europe/Amsterdam +++ b/library/tzdata/Europe/Amsterdam @@ -46,12 +46,12 @@ set TZData(:Europe/Amsterdam) { {-1061331572 4772 1 NST} {-1049062772 1172 0 AMT} {-1029190772 4772 1 NST} - {-1025741972 4800 0 NEST} - {-1017613200 1200 0 NET} - {-998259600 4800 1 NEST} - {-986163600 1200 0 NET} - {-966723600 4800 1 NEST} - {-954109200 1200 0 NET} + {-1025741972 4800 0 +0120} + {-1017613200 1200 0 +0020} + {-998259600 4800 1 +0120} + {-986163600 1200 0 +0020} + {-966723600 4800 1 +0120} + {-954109200 1200 0 +0020} {-935022000 7200 0 CEST} {-857257200 3600 0 CET} {-844556400 7200 1 CEST} diff --git a/library/tzdata/Europe/Madrid b/library/tzdata/Europe/Madrid index 50de14f..f4dd484 100644 --- a/library/tzdata/Europe/Madrid +++ b/library/tzdata/Europe/Madrid @@ -2,52 +2,50 @@ set TZData(:Europe/Madrid) { {-9223372036854775808 -884 0 LMT} - {-2177451916 0 0 WET} - {-1661734800 3600 1 WEST} - {-1648429200 0 0 WET} + {-2177452800 0 0 WET} {-1631926800 3600 1 WEST} - {-1616893200 0 0 WET} - {-1601254800 3600 1 WEST} - {-1585357200 0 0 WET} + {-1616889600 0 0 WET} + {-1601168400 3600 1 WEST} + {-1585353600 0 0 WET} {-1442451600 3600 1 WEST} - {-1427677200 0 0 WET} + {-1427673600 0 0 WET} {-1379293200 3600 1 WEST} - {-1364778000 0 0 WET} + {-1364774400 0 0 WET} {-1348448400 3600 1 WEST} - {-1333328400 0 0 WET} - {-1316394000 3600 1 WEST} - {-1301274000 0 0 WET} + {-1333324800 0 0 WET} + {-1316390400 3600 1 WEST} + {-1301270400 0 0 WET} {-1284339600 3600 1 WEST} - {-1269824400 0 0 WET} - {-1029114000 3600 1 WEST} - {-1017622800 0 0 WET} - {-1002848400 3600 1 WEST} - {-986173200 0 0 WET} - {-969238800 3600 1 WEST} - {-954118800 0 0 WET} - {-940208400 3600 1 WEST} - {-873079200 7200 1 WEMT} - {-862538400 3600 1 WEST} - {-842839200 7200 1 WEMT} - {-828237600 3600 1 WEST} - {-811389600 7200 1 WEMT} - {-796010400 3600 1 WEST} - {-779940000 7200 1 WEMT} - {-765421200 3600 1 WEST} - {-748490400 7200 1 WEMT} - {-733881600 3600 0 CET} + {-1269820800 0 0 WET} + {-1026954000 3600 1 WEST} + {-1017619200 0 0 WET} + {-1001898000 3600 1 WEST} + {-999482400 7200 1 WEMT} + {-986090400 3600 1 WEST} + {-954115200 0 0 WET} + {-940208400 3600 0 CET} + {-873079200 7200 1 CEST} + {-862621200 3600 0 CET} + {-842839200 7200 1 CEST} + {-828320400 3600 0 CET} + {-811389600 7200 1 CEST} + {-796870800 3600 0 CET} + {-779940000 7200 1 CEST} + {-765421200 3600 0 CET} + {-748490400 7200 1 CEST} + {-733971600 3600 0 CET} {-652327200 7200 1 CEST} - {-639190800 3600 0 CET} + {-639018000 3600 0 CET} {135122400 7200 1 CEST} {150246000 3600 0 CET} - {167176800 7200 1 CEST} + {166572000 7200 1 CEST} {181695600 3600 0 CET} {196812000 7200 1 CEST} {212540400 3600 0 CET} {228866400 7200 1 CEST} {243990000 3600 0 CET} - {260402400 7200 1 CEST} - {276044400 3600 0 CET} + {260326800 7200 1 CEST} + {276051600 3600 0 CET} {283993200 3600 0 CET} {291776400 7200 1 CEST} {307501200 3600 0 CET} diff --git a/library/tzdata/Europe/Zaporozhye b/library/tzdata/Europe/Zaporozhye index 01418cd..478a61c 100644 --- a/library/tzdata/Europe/Zaporozhye +++ b/library/tzdata/Europe/Zaporozhye @@ -2,7 +2,7 @@ set TZData(:Europe/Zaporozhye) { {-9223372036854775808 8440 0 LMT} - {-2840149240 8400 0 CUT} + {-2840149240 8400 0 +0220} {-1441160400 7200 0 EET} {-1247536800 10800 0 MSK} {-894769200 3600 0 CET} diff --git a/library/tzdata/Indian/Chagos b/library/tzdata/Indian/Chagos index a5cec61..23ea790 100644 --- a/library/tzdata/Indian/Chagos +++ b/library/tzdata/Indian/Chagos @@ -2,6 +2,6 @@ set TZData(:Indian/Chagos) { {-9223372036854775808 17380 0 LMT} - {-1988167780 18000 0 IOT} - {820436400 21600 0 IOT} + {-1988167780 18000 0 +05} + {820436400 21600 0 +06} } diff --git a/library/tzdata/Indian/Christmas b/library/tzdata/Indian/Christmas index c36e973..76f8cbe 100644 --- a/library/tzdata/Indian/Christmas +++ b/library/tzdata/Indian/Christmas @@ -2,5 +2,5 @@ set TZData(:Indian/Christmas) { {-9223372036854775808 25372 0 LMT} - {-2364102172 25200 0 CXT} + {-2364102172 25200 0 +07} } diff --git a/library/tzdata/Indian/Cocos b/library/tzdata/Indian/Cocos index a63ae68..833eb20 100644 --- a/library/tzdata/Indian/Cocos +++ b/library/tzdata/Indian/Cocos @@ -2,5 +2,5 @@ set TZData(:Indian/Cocos) { {-9223372036854775808 23260 0 LMT} - {-2209012060 23400 0 CCT} + {-2209012060 23400 0 +0630} } diff --git a/library/tzdata/Indian/Mahe b/library/tzdata/Indian/Mahe index c88a24b..3dd5b40 100644 --- a/library/tzdata/Indian/Mahe +++ b/library/tzdata/Indian/Mahe @@ -2,5 +2,5 @@ set TZData(:Indian/Mahe) { {-9223372036854775808 13308 0 LMT} - {-2006653308 14400 0 SCT} + {-2006653308 14400 0 +04} } diff --git a/library/tzdata/Indian/Maldives b/library/tzdata/Indian/Maldives index 2c2c739..b23bf2b 100644 --- a/library/tzdata/Indian/Maldives +++ b/library/tzdata/Indian/Maldives @@ -3,5 +3,5 @@ set TZData(:Indian/Maldives) { {-9223372036854775808 17640 0 LMT} {-2840158440 17640 0 MMT} - {-315636840 18000 0 MVT} + {-315636840 18000 0 +05} } diff --git a/library/tzdata/Indian/Mauritius b/library/tzdata/Indian/Mauritius index a9c07eb..2a7a0b1 100644 --- a/library/tzdata/Indian/Mauritius +++ b/library/tzdata/Indian/Mauritius @@ -2,9 +2,9 @@ set TZData(:Indian/Mauritius) { {-9223372036854775808 13800 0 LMT} - {-1988164200 14400 0 MUT} - {403041600 18000 1 MUST} - {417034800 14400 0 MUT} - {1224972000 18000 1 MUST} - {1238274000 14400 0 MUT} + {-1988164200 14400 0 +04} + {403041600 18000 1 +05} + {417034800 14400 0 +04} + {1224972000 18000 1 +05} + {1238274000 14400 0 +04} } diff --git a/library/tzdata/Indian/Reunion b/library/tzdata/Indian/Reunion index de2dd60..aa78dec 100644 --- a/library/tzdata/Indian/Reunion +++ b/library/tzdata/Indian/Reunion @@ -2,5 +2,5 @@ set TZData(:Indian/Reunion) { {-9223372036854775808 13312 0 LMT} - {-1848886912 14400 0 RET} + {-1848886912 14400 0 +04} } diff --git a/library/tzdata/Pacific/Apia b/library/tzdata/Pacific/Apia index 21d6669..feef374 100644 --- a/library/tzdata/Pacific/Apia +++ b/library/tzdata/Pacific/Apia @@ -3,186 +3,186 @@ set TZData(:Pacific/Apia) { {-9223372036854775808 45184 0 LMT} {-2855737984 -41216 0 LMT} - {-1861878784 -41400 0 WSST} - {-631110600 -39600 0 SST} - {1285498800 -36000 1 SDT} - {1301752800 -39600 0 SST} - {1316872800 -36000 1 SDT} - {1325239200 50400 0 WSDT} - {1333202400 46800 0 WSST} - {1348927200 50400 1 WSDT} - {1365256800 46800 0 WSST} - {1380376800 50400 1 WSDT} - {1396706400 46800 0 WSST} - {1411826400 50400 1 WSDT} - {1428156000 46800 0 WSST} - {1443276000 50400 1 WSDT} - {1459605600 46800 0 WSST} - {1474725600 50400 1 WSDT} - {1491055200 46800 0 WSST} - {1506175200 50400 1 WSDT} - {1522504800 46800 0 WSST} - {1538229600 50400 1 WSDT} - {1554559200 46800 0 WSST} - {1569679200 50400 1 WSDT} - {1586008800 46800 0 WSST} - {1601128800 50400 1 WSDT} - {1617458400 46800 0 WSST} - {1632578400 50400 1 WSDT} - {1648908000 46800 0 WSST} - {1664028000 50400 1 WSDT} - {1680357600 46800 0 WSST} - {1695477600 50400 1 WSDT} - {1712412000 46800 0 WSST} - {1727532000 50400 1 WSDT} - {1743861600 46800 0 WSST} - {1758981600 50400 1 WSDT} - {1775311200 46800 0 WSST} - {1790431200 50400 1 WSDT} - {1806760800 46800 0 WSST} - {1821880800 50400 1 WSDT} - {1838210400 46800 0 WSST} - {1853330400 50400 1 WSDT} - {1869660000 46800 0 WSST} - {1885384800 50400 1 WSDT} - {1901714400 46800 0 WSST} - {1916834400 50400 1 WSDT} - {1933164000 46800 0 WSST} - {1948284000 50400 1 WSDT} - {1964613600 46800 0 WSST} - {1979733600 50400 1 WSDT} - {1996063200 46800 0 WSST} - {2011183200 50400 1 WSDT} - {2027512800 46800 0 WSST} - {2042632800 50400 1 WSDT} - {2058962400 46800 0 WSST} - {2074687200 50400 1 WSDT} - {2091016800 46800 0 WSST} - {2106136800 50400 1 WSDT} - {2122466400 46800 0 WSST} - {2137586400 50400 1 WSDT} - {2153916000 46800 0 WSST} - {2169036000 50400 1 WSDT} - {2185365600 46800 0 WSST} - {2200485600 50400 1 WSDT} - {2216815200 46800 0 WSST} - {2232540000 50400 1 WSDT} - {2248869600 46800 0 WSST} - {2263989600 50400 1 WSDT} - {2280319200 46800 0 WSST} - {2295439200 50400 1 WSDT} - {2311768800 46800 0 WSST} - {2326888800 50400 1 WSDT} - {2343218400 46800 0 WSST} - {2358338400 50400 1 WSDT} - {2374668000 46800 0 WSST} - {2389788000 50400 1 WSDT} - {2406117600 46800 0 WSST} - {2421842400 50400 1 WSDT} - {2438172000 46800 0 WSST} - {2453292000 50400 1 WSDT} - {2469621600 46800 0 WSST} - {2484741600 50400 1 WSDT} - {2501071200 46800 0 WSST} - {2516191200 50400 1 WSDT} - {2532520800 46800 0 WSST} - {2547640800 50400 1 WSDT} - {2563970400 46800 0 WSST} - {2579090400 50400 1 WSDT} - {2596024800 46800 0 WSST} - {2611144800 50400 1 WSDT} - {2627474400 46800 0 WSST} - {2642594400 50400 1 WSDT} - {2658924000 46800 0 WSST} - {2674044000 50400 1 WSDT} - {2690373600 46800 0 WSST} - {2705493600 50400 1 WSDT} - {2721823200 46800 0 WSST} - {2736943200 50400 1 WSDT} - {2753272800 46800 0 WSST} - {2768997600 50400 1 WSDT} - {2785327200 46800 0 WSST} - {2800447200 50400 1 WSDT} - {2816776800 46800 0 WSST} - {2831896800 50400 1 WSDT} - {2848226400 46800 0 WSST} - {2863346400 50400 1 WSDT} - {2879676000 46800 0 WSST} - {2894796000 50400 1 WSDT} - {2911125600 46800 0 WSST} - {2926245600 50400 1 WSDT} - {2942575200 46800 0 WSST} - {2958300000 50400 1 WSDT} - {2974629600 46800 0 WSST} - {2989749600 50400 1 WSDT} - {3006079200 46800 0 WSST} - {3021199200 50400 1 WSDT} - {3037528800 46800 0 WSST} - {3052648800 50400 1 WSDT} - {3068978400 46800 0 WSST} - {3084098400 50400 1 WSDT} - {3100428000 46800 0 WSST} - {3116152800 50400 1 WSDT} - {3132482400 46800 0 WSST} - {3147602400 50400 1 WSDT} - {3163932000 46800 0 WSST} - {3179052000 50400 1 WSDT} - {3195381600 46800 0 WSST} - {3210501600 50400 1 WSDT} - {3226831200 46800 0 WSST} - {3241951200 50400 1 WSDT} - {3258280800 46800 0 WSST} - {3273400800 50400 1 WSDT} - {3289730400 46800 0 WSST} - {3305455200 50400 1 WSDT} - {3321784800 46800 0 WSST} - {3336904800 50400 1 WSDT} - {3353234400 46800 0 WSST} - {3368354400 50400 1 WSDT} - {3384684000 46800 0 WSST} - {3399804000 50400 1 WSDT} - {3416133600 46800 0 WSST} - {3431253600 50400 1 WSDT} - {3447583200 46800 0 WSST} - {3462703200 50400 1 WSDT} - {3479637600 46800 0 WSST} - {3494757600 50400 1 WSDT} - {3511087200 46800 0 WSST} - {3526207200 50400 1 WSDT} - {3542536800 46800 0 WSST} - {3557656800 50400 1 WSDT} - {3573986400 46800 0 WSST} - {3589106400 50400 1 WSDT} - {3605436000 46800 0 WSST} - {3620556000 50400 1 WSDT} - {3636885600 46800 0 WSST} - {3652610400 50400 1 WSDT} - {3668940000 46800 0 WSST} - {3684060000 50400 1 WSDT} - {3700389600 46800 0 WSST} - {3715509600 50400 1 WSDT} - {3731839200 46800 0 WSST} - {3746959200 50400 1 WSDT} - {3763288800 46800 0 WSST} - {3778408800 50400 1 WSDT} - {3794738400 46800 0 WSST} - {3809858400 50400 1 WSDT} - {3826188000 46800 0 WSST} - {3841912800 50400 1 WSDT} - {3858242400 46800 0 WSST} - {3873362400 50400 1 WSDT} - {3889692000 46800 0 WSST} - {3904812000 50400 1 WSDT} - {3921141600 46800 0 WSST} - {3936261600 50400 1 WSDT} - {3952591200 46800 0 WSST} - {3967711200 50400 1 WSDT} - {3984040800 46800 0 WSST} - {3999765600 50400 1 WSDT} - {4016095200 46800 0 WSST} - {4031215200 50400 1 WSDT} - {4047544800 46800 0 WSST} - {4062664800 50400 1 WSDT} - {4078994400 46800 0 WSST} - {4094114400 50400 1 WSDT} + {-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} } diff --git a/library/tzdata/Pacific/Bougainville b/library/tzdata/Pacific/Bougainville index 06996f9..3c00b29 100644 --- a/library/tzdata/Pacific/Bougainville +++ b/library/tzdata/Pacific/Bougainville @@ -3,8 +3,8 @@ set TZData(:Pacific/Bougainville) { {-9223372036854775808 37336 0 LMT} {-2840178136 35312 0 PMMT} - {-2366790512 36000 0 PGT} - {-868010400 32400 0 JST} - {-768906000 36000 0 PGT} - {1419696000 39600 0 BST} + {-2366790512 36000 0 +10} + {-868010400 32400 0 +09} + {-768906000 36000 0 +10} + {1419696000 39600 0 +11} } diff --git a/library/tzdata/Pacific/Chatham b/library/tzdata/Pacific/Chatham index 94a5512..5d39879 100644 --- a/library/tzdata/Pacific/Chatham +++ b/library/tzdata/Pacific/Chatham @@ -2,257 +2,257 @@ set TZData(:Pacific/Chatham) { {-9223372036854775808 44028 0 LMT} - {-3192437628 44100 0 CHAST} - {-757426500 45900 0 CHAST} - {152632800 49500 1 CHADT} - {162309600 45900 0 CHAST} - {183477600 49500 1 CHADT} - {194968800 45900 0 CHAST} - {215532000 49500 1 CHADT} - {226418400 45900 0 CHAST} - {246981600 49500 1 CHADT} - {257868000 45900 0 CHAST} - {278431200 49500 1 CHADT} - {289317600 45900 0 CHAST} - {309880800 49500 1 CHADT} - {320767200 45900 0 CHAST} - {341330400 49500 1 CHADT} - {352216800 45900 0 CHAST} - {372780000 49500 1 CHADT} - {384271200 45900 0 CHAST} - {404834400 49500 1 CHADT} - {415720800 45900 0 CHAST} - {436284000 49500 1 CHADT} - {447170400 45900 0 CHAST} - {467733600 49500 1 CHADT} - {478620000 45900 0 CHAST} - {499183200 49500 1 CHADT} - {510069600 45900 0 CHAST} - {530632800 49500 1 CHADT} - {541519200 45900 0 CHAST} - {562082400 49500 1 CHADT} - {573573600 45900 0 CHAST} - {594136800 49500 1 CHADT} - {605023200 45900 0 CHAST} - {623772000 49500 1 CHADT} - {637682400 45900 0 CHAST} - {655221600 49500 1 CHADT} - {669132000 45900 0 CHAST} - {686671200 49500 1 CHADT} - {700581600 45900 0 CHAST} - {718120800 49500 1 CHADT} - {732636000 45900 0 CHAST} - {749570400 49500 1 CHADT} - {764085600 45900 0 CHAST} - {781020000 49500 1 CHADT} - {795535200 45900 0 CHAST} - {812469600 49500 1 CHADT} - {826984800 45900 0 CHAST} - {844524000 49500 1 CHADT} - {858434400 45900 0 CHAST} - {875973600 49500 1 CHADT} - {889884000 45900 0 CHAST} - {907423200 49500 1 CHADT} - {921938400 45900 0 CHAST} - {938872800 49500 1 CHADT} - {953388000 45900 0 CHAST} - {970322400 49500 1 CHADT} - {984837600 45900 0 CHAST} - {1002376800 49500 1 CHADT} - {1016287200 45900 0 CHAST} - {1033826400 49500 1 CHADT} - {1047736800 45900 0 CHAST} - {1065276000 49500 1 CHADT} - {1079791200 45900 0 CHAST} - {1096725600 49500 1 CHADT} - {1111240800 45900 0 CHAST} - {1128175200 49500 1 CHADT} - {1142690400 45900 0 CHAST} - {1159624800 49500 1 CHADT} - {1174140000 45900 0 CHAST} - {1191074400 49500 1 CHADT} - {1207404000 45900 0 CHAST} - {1222524000 49500 1 CHADT} - {1238853600 45900 0 CHAST} - {1253973600 49500 1 CHADT} - {1270303200 45900 0 CHAST} - {1285423200 49500 1 CHADT} - {1301752800 45900 0 CHAST} - {1316872800 49500 1 CHADT} - {1333202400 45900 0 CHAST} - {1348927200 49500 1 CHADT} - {1365256800 45900 0 CHAST} - {1380376800 49500 1 CHADT} - {1396706400 45900 0 CHAST} - {1411826400 49500 1 CHADT} - {1428156000 45900 0 CHAST} - {1443276000 49500 1 CHADT} - {1459605600 45900 0 CHAST} - {1474725600 49500 1 CHADT} - {1491055200 45900 0 CHAST} - {1506175200 49500 1 CHADT} - {1522504800 45900 0 CHAST} - {1538229600 49500 1 CHADT} - {1554559200 45900 0 CHAST} - {1569679200 49500 1 CHADT} - {1586008800 45900 0 CHAST} - {1601128800 49500 1 CHADT} - {1617458400 45900 0 CHAST} - {1632578400 49500 1 CHADT} - {1648908000 45900 0 CHAST} - {1664028000 49500 1 CHADT} - {1680357600 45900 0 CHAST} - {1695477600 49500 1 CHADT} - {1712412000 45900 0 CHAST} - {1727532000 49500 1 CHADT} - {1743861600 45900 0 CHAST} - {1758981600 49500 1 CHADT} - {1775311200 45900 0 CHAST} - {1790431200 49500 1 CHADT} - {1806760800 45900 0 CHAST} - {1821880800 49500 1 CHADT} - {1838210400 45900 0 CHAST} - {1853330400 49500 1 CHADT} - {1869660000 45900 0 CHAST} - {1885384800 49500 1 CHADT} - {1901714400 45900 0 CHAST} - {1916834400 49500 1 CHADT} - {1933164000 45900 0 CHAST} - {1948284000 49500 1 CHADT} - {1964613600 45900 0 CHAST} - {1979733600 49500 1 CHADT} - {1996063200 45900 0 CHAST} - {2011183200 49500 1 CHADT} - {2027512800 45900 0 CHAST} - {2042632800 49500 1 CHADT} - {2058962400 45900 0 CHAST} - {2074687200 49500 1 CHADT} - {2091016800 45900 0 CHAST} - {2106136800 49500 1 CHADT} - {2122466400 45900 0 CHAST} - {2137586400 49500 1 CHADT} - {2153916000 45900 0 CHAST} - {2169036000 49500 1 CHADT} - {2185365600 45900 0 CHAST} - {2200485600 49500 1 CHADT} - {2216815200 45900 0 CHAST} - {2232540000 49500 1 CHADT} - {2248869600 45900 0 CHAST} - {2263989600 49500 1 CHADT} - {2280319200 45900 0 CHAST} - {2295439200 49500 1 CHADT} - {2311768800 45900 0 CHAST} - {2326888800 49500 1 CHADT} - {2343218400 45900 0 CHAST} - {2358338400 49500 1 CHADT} - {2374668000 45900 0 CHAST} - {2389788000 49500 1 CHADT} - {2406117600 45900 0 CHAST} - {2421842400 49500 1 CHADT} - {2438172000 45900 0 CHAST} - {2453292000 49500 1 CHADT} - {2469621600 45900 0 CHAST} - {2484741600 49500 1 CHADT} - {2501071200 45900 0 CHAST} - {2516191200 49500 1 CHADT} - {2532520800 45900 0 CHAST} - {2547640800 49500 1 CHADT} - {2563970400 45900 0 CHAST} - {2579090400 49500 1 CHADT} - {2596024800 45900 0 CHAST} - {2611144800 49500 1 CHADT} - {2627474400 45900 0 CHAST} - {2642594400 49500 1 CHADT} - {2658924000 45900 0 CHAST} - {2674044000 49500 1 CHADT} - {2690373600 45900 0 CHAST} - {2705493600 49500 1 CHADT} - {2721823200 45900 0 CHAST} - {2736943200 49500 1 CHADT} - {2753272800 45900 0 CHAST} - {2768997600 49500 1 CHADT} - {2785327200 45900 0 CHAST} - {2800447200 49500 1 CHADT} - {2816776800 45900 0 CHAST} - {2831896800 49500 1 CHADT} - {2848226400 45900 0 CHAST} - {2863346400 49500 1 CHADT} - {2879676000 45900 0 CHAST} - {2894796000 49500 1 CHADT} - {2911125600 45900 0 CHAST} - {2926245600 49500 1 CHADT} - {2942575200 45900 0 CHAST} - {2958300000 49500 1 CHADT} - {2974629600 45900 0 CHAST} - {2989749600 49500 1 CHADT} - {3006079200 45900 0 CHAST} - {3021199200 49500 1 CHADT} - {3037528800 45900 0 CHAST} - {3052648800 49500 1 CHADT} - {3068978400 45900 0 CHAST} - {3084098400 49500 1 CHADT} - {3100428000 45900 0 CHAST} - {3116152800 49500 1 CHADT} - {3132482400 45900 0 CHAST} - {3147602400 49500 1 CHADT} - {3163932000 45900 0 CHAST} - {3179052000 49500 1 CHADT} - {3195381600 45900 0 CHAST} - {3210501600 49500 1 CHADT} - {3226831200 45900 0 CHAST} - {3241951200 49500 1 CHADT} - {3258280800 45900 0 CHAST} - {3273400800 49500 1 CHADT} - {3289730400 45900 0 CHAST} - {3305455200 49500 1 CHADT} - {3321784800 45900 0 CHAST} - {3336904800 49500 1 CHADT} - {3353234400 45900 0 CHAST} - {3368354400 49500 1 CHADT} - {3384684000 45900 0 CHAST} - {3399804000 49500 1 CHADT} - {3416133600 45900 0 CHAST} - {3431253600 49500 1 CHADT} - {3447583200 45900 0 CHAST} - {3462703200 49500 1 CHADT} - {3479637600 45900 0 CHAST} - {3494757600 49500 1 CHADT} - {3511087200 45900 0 CHAST} - {3526207200 49500 1 CHADT} - {3542536800 45900 0 CHAST} - {3557656800 49500 1 CHADT} - {3573986400 45900 0 CHAST} - {3589106400 49500 1 CHADT} - {3605436000 45900 0 CHAST} - {3620556000 49500 1 CHADT} - {3636885600 45900 0 CHAST} - {3652610400 49500 1 CHADT} - {3668940000 45900 0 CHAST} - {3684060000 49500 1 CHADT} - {3700389600 45900 0 CHAST} - {3715509600 49500 1 CHADT} - {3731839200 45900 0 CHAST} - {3746959200 49500 1 CHADT} - {3763288800 45900 0 CHAST} - {3778408800 49500 1 CHADT} - {3794738400 45900 0 CHAST} - {3809858400 49500 1 CHADT} - {3826188000 45900 0 CHAST} - {3841912800 49500 1 CHADT} - {3858242400 45900 0 CHAST} - {3873362400 49500 1 CHADT} - {3889692000 45900 0 CHAST} - {3904812000 49500 1 CHADT} - {3921141600 45900 0 CHAST} - {3936261600 49500 1 CHADT} - {3952591200 45900 0 CHAST} - {3967711200 49500 1 CHADT} - {3984040800 45900 0 CHAST} - {3999765600 49500 1 CHADT} - {4016095200 45900 0 CHAST} - {4031215200 49500 1 CHADT} - {4047544800 45900 0 CHAST} - {4062664800 49500 1 CHADT} - {4078994400 45900 0 CHAST} - {4094114400 49500 1 CHADT} + {-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} } diff --git a/library/tzdata/Pacific/Chuuk b/library/tzdata/Pacific/Chuuk index 70b14b2..4e9d099 100644 --- a/library/tzdata/Pacific/Chuuk +++ b/library/tzdata/Pacific/Chuuk @@ -2,5 +2,5 @@ set TZData(:Pacific/Chuuk) { {-9223372036854775808 36428 0 LMT} - {-2177489228 36000 0 CHUT} + {-2177489228 36000 0 +10} } diff --git a/library/tzdata/Pacific/Easter b/library/tzdata/Pacific/Easter index ef0f2d5..474a32b 100644 --- a/library/tzdata/Pacific/Easter +++ b/library/tzdata/Pacific/Easter @@ -3,266 +3,266 @@ set TZData(:Pacific/Easter) { {-9223372036854775808 -26248 0 LMT} {-2524495352 -26248 0 EMT} - {-1178124152 -25200 0 EAST} - {-36619200 -21600 1 EASST} - {-23922000 -25200 0 EAST} - {-3355200 -21600 1 EASST} - {7527600 -25200 0 EAST} - {24465600 -21600 1 EASST} - {37767600 -25200 0 EAST} - {55915200 -21600 1 EASST} - {69217200 -25200 0 EAST} - {87969600 -21600 1 EASST} - {100666800 -25200 0 EAST} - {118209600 -21600 1 EASST} - {132116400 -25200 0 EAST} - {150868800 -21600 1 EASST} - {163566000 -25200 0 EAST} - {182318400 -21600 1 EASST} - {195620400 -25200 0 EAST} - {213768000 -21600 1 EASST} - {227070000 -25200 0 EAST} - {245217600 -21600 1 EASST} - {258519600 -25200 0 EAST} - {277272000 -21600 1 EASST} - {289969200 -25200 0 EAST} - {308721600 -21600 1 EASST} - {321418800 -25200 0 EAST} - {340171200 -21600 1 EASST} - {353473200 -25200 0 EAST} - {371620800 -21600 1 EASST} - {384922800 -21600 0 EAST} - {403070400 -18000 1 EASST} - {416372400 -21600 0 EAST} - {434520000 -18000 1 EASST} - {447822000 -21600 0 EAST} - {466574400 -18000 1 EASST} - {479271600 -21600 0 EAST} - {498024000 -18000 1 EASST} - {510721200 -21600 0 EAST} - {529473600 -18000 1 EASST} - {545194800 -21600 0 EAST} - {560923200 -18000 1 EASST} - {574225200 -21600 0 EAST} - {592372800 -18000 1 EASST} - {605674800 -21600 0 EAST} - {624427200 -18000 1 EASST} - {637124400 -21600 0 EAST} - {653457600 -18000 1 EASST} - {668574000 -21600 0 EAST} - {687326400 -18000 1 EASST} - {700628400 -21600 0 EAST} - {718776000 -18000 1 EASST} - {732078000 -21600 0 EAST} - {750225600 -18000 1 EASST} - {763527600 -21600 0 EAST} - {781675200 -18000 1 EASST} - {794977200 -21600 0 EAST} - {813729600 -18000 1 EASST} - {826426800 -21600 0 EAST} - {845179200 -18000 1 EASST} - {859690800 -21600 0 EAST} - {876628800 -18000 1 EASST} - {889930800 -21600 0 EAST} - {906868800 -18000 1 EASST} - {923194800 -21600 0 EAST} - {939528000 -18000 1 EASST} - {952830000 -21600 0 EAST} - {971582400 -18000 1 EASST} - {984279600 -21600 0 EAST} - {1003032000 -18000 1 EASST} - {1015729200 -21600 0 EAST} - {1034481600 -18000 1 EASST} - {1047178800 -21600 0 EAST} - {1065931200 -18000 1 EASST} - {1079233200 -21600 0 EAST} - {1097380800 -18000 1 EASST} - {1110682800 -21600 0 EAST} - {1128830400 -18000 1 EASST} - {1142132400 -21600 0 EAST} - {1160884800 -18000 1 EASST} - {1173582000 -21600 0 EAST} - {1192334400 -18000 1 EASST} - {1206846000 -21600 0 EAST} - {1223784000 -18000 1 EASST} - {1237086000 -21600 0 EAST} - {1255233600 -18000 1 EASST} - {1270350000 -21600 0 EAST} - {1286683200 -18000 1 EASST} - {1304823600 -21600 0 EAST} - {1313899200 -18000 1 EASST} - {1335668400 -21600 0 EAST} - {1346558400 -18000 1 EASST} - {1367118000 -21600 0 EAST} - {1378612800 -18000 1 EASST} - {1398567600 -21600 0 EAST} - {1410062400 -18000 1 EASST} - {1463281200 -21600 0 EAST} - {1471147200 -18000 1 EASST} - {1494730800 -21600 0 EAST} - {1502596800 -18000 1 EASST} - {1526180400 -21600 0 EAST} - {1534046400 -18000 1 EASST} - {1557630000 -21600 0 EAST} - {1565496000 -18000 1 EASST} - {1589079600 -21600 0 EAST} - {1596945600 -18000 1 EASST} - {1620529200 -21600 0 EAST} - {1629000000 -18000 1 EASST} - {1652583600 -21600 0 EAST} - {1660449600 -18000 1 EASST} - {1684033200 -21600 0 EAST} - {1691899200 -18000 1 EASST} - {1715482800 -21600 0 EAST} - {1723348800 -18000 1 EASST} - {1746932400 -21600 0 EAST} - {1754798400 -18000 1 EASST} - {1778382000 -21600 0 EAST} - {1786248000 -18000 1 EASST} - {1809831600 -21600 0 EAST} - {1818302400 -18000 1 EASST} - {1841886000 -21600 0 EAST} - {1849752000 -18000 1 EASST} - {1873335600 -21600 0 EAST} - {1881201600 -18000 1 EASST} - {1904785200 -21600 0 EAST} - {1912651200 -18000 1 EASST} - {1936234800 -21600 0 EAST} - {1944100800 -18000 1 EASST} - {1967684400 -21600 0 EAST} - {1976155200 -18000 1 EASST} - {1999738800 -21600 0 EAST} - {2007604800 -18000 1 EASST} - {2031188400 -21600 0 EAST} - {2039054400 -18000 1 EASST} - {2062638000 -21600 0 EAST} - {2070504000 -18000 1 EASST} - {2094087600 -21600 0 EAST} - {2101953600 -18000 1 EASST} - {2125537200 -21600 0 EAST} - {2133403200 -18000 1 EASST} - {2156986800 -21600 0 EAST} - {2165457600 -18000 1 EASST} - {2189041200 -21600 0 EAST} - {2196907200 -18000 1 EASST} - {2220490800 -21600 0 EAST} - {2228356800 -18000 1 EASST} - {2251940400 -21600 0 EAST} - {2259806400 -18000 1 EASST} - {2283390000 -21600 0 EAST} - {2291256000 -18000 1 EASST} - {2314839600 -21600 0 EAST} - {2322705600 -18000 1 EASST} - {2346894000 -21600 0 EAST} - {2354760000 -18000 1 EASST} - {2378343600 -21600 0 EAST} - {2386209600 -18000 1 EASST} - {2409793200 -21600 0 EAST} - {2417659200 -18000 1 EASST} - {2441242800 -21600 0 EAST} - {2449108800 -18000 1 EASST} - {2472692400 -21600 0 EAST} - {2480558400 -18000 1 EASST} - {2504142000 -21600 0 EAST} - {2512612800 -18000 1 EASST} - {2536196400 -21600 0 EAST} - {2544062400 -18000 1 EASST} - {2567646000 -21600 0 EAST} - {2575512000 -18000 1 EASST} - {2599095600 -21600 0 EAST} - {2606961600 -18000 1 EASST} - {2630545200 -21600 0 EAST} - {2638411200 -18000 1 EASST} - {2661994800 -21600 0 EAST} - {2669860800 -18000 1 EASST} - {2693444400 -21600 0 EAST} - {2701915200 -18000 1 EASST} - {2725498800 -21600 0 EAST} - {2733364800 -18000 1 EASST} - {2756948400 -21600 0 EAST} - {2764814400 -18000 1 EASST} - {2788398000 -21600 0 EAST} - {2796264000 -18000 1 EASST} - {2819847600 -21600 0 EAST} - {2827713600 -18000 1 EASST} - {2851297200 -21600 0 EAST} - {2859768000 -18000 1 EASST} - {2883351600 -21600 0 EAST} - {2891217600 -18000 1 EASST} - {2914801200 -21600 0 EAST} - {2922667200 -18000 1 EASST} - {2946250800 -21600 0 EAST} - {2954116800 -18000 1 EASST} - {2977700400 -21600 0 EAST} - {2985566400 -18000 1 EASST} - {3009150000 -21600 0 EAST} - {3017016000 -18000 1 EASST} - {3040599600 -21600 0 EAST} - {3049070400 -18000 1 EASST} - {3072654000 -21600 0 EAST} - {3080520000 -18000 1 EASST} - {3104103600 -21600 0 EAST} - {3111969600 -18000 1 EASST} - {3135553200 -21600 0 EAST} - {3143419200 -18000 1 EASST} - {3167002800 -21600 0 EAST} - {3174868800 -18000 1 EASST} - {3198452400 -21600 0 EAST} - {3206318400 -18000 1 EASST} - {3230506800 -21600 0 EAST} - {3238372800 -18000 1 EASST} - {3261956400 -21600 0 EAST} - {3269822400 -18000 1 EASST} - {3293406000 -21600 0 EAST} - {3301272000 -18000 1 EASST} - {3324855600 -21600 0 EAST} - {3332721600 -18000 1 EASST} - {3356305200 -21600 0 EAST} - {3364171200 -18000 1 EASST} - {3387754800 -21600 0 EAST} - {3396225600 -18000 1 EASST} - {3419809200 -21600 0 EAST} - {3427675200 -18000 1 EASST} - {3451258800 -21600 0 EAST} - {3459124800 -18000 1 EASST} - {3482708400 -21600 0 EAST} - {3490574400 -18000 1 EASST} - {3514158000 -21600 0 EAST} - {3522024000 -18000 1 EASST} - {3545607600 -21600 0 EAST} - {3553473600 -18000 1 EASST} - {3577057200 -21600 0 EAST} - {3585528000 -18000 1 EASST} - {3609111600 -21600 0 EAST} - {3616977600 -18000 1 EASST} - {3640561200 -21600 0 EAST} - {3648427200 -18000 1 EASST} - {3672010800 -21600 0 EAST} - {3679876800 -18000 1 EASST} - {3703460400 -21600 0 EAST} - {3711326400 -18000 1 EASST} - {3734910000 -21600 0 EAST} - {3743380800 -18000 1 EASST} - {3766964400 -21600 0 EAST} - {3774830400 -18000 1 EASST} - {3798414000 -21600 0 EAST} - {3806280000 -18000 1 EASST} - {3829863600 -21600 0 EAST} - {3837729600 -18000 1 EASST} - {3861313200 -21600 0 EAST} - {3869179200 -18000 1 EASST} - {3892762800 -21600 0 EAST} - {3900628800 -18000 1 EASST} - {3924212400 -21600 0 EAST} - {3932683200 -18000 1 EASST} - {3956266800 -21600 0 EAST} - {3964132800 -18000 1 EASST} - {3987716400 -21600 0 EAST} - {3995582400 -18000 1 EASST} - {4019166000 -21600 0 EAST} - {4027032000 -18000 1 EASST} - {4050615600 -21600 0 EAST} - {4058481600 -18000 1 EASST} - {4082065200 -21600 0 EAST} - {4089931200 -18000 1 EASST} + {-1178124152 -25200 0 -07} + {-36619200 -21600 1 -06} + {-23922000 -25200 0 -07} + {-3355200 -21600 1 -06} + {7527600 -25200 0 -07} + {24465600 -21600 1 -06} + {37767600 -25200 0 -07} + {55915200 -21600 1 -06} + {69217200 -25200 0 -07} + {87969600 -21600 1 -06} + {100666800 -25200 0 -07} + {118209600 -21600 1 -06} + {132116400 -25200 0 -07} + {150868800 -21600 1 -06} + {163566000 -25200 0 -07} + {182318400 -21600 1 -06} + {195620400 -25200 0 -07} + {213768000 -21600 1 -06} + {227070000 -25200 0 -07} + {245217600 -21600 1 -06} + {258519600 -25200 0 -07} + {277272000 -21600 1 -06} + {289969200 -25200 0 -07} + {308721600 -21600 1 -06} + {321418800 -25200 0 -07} + {340171200 -21600 1 -06} + {353473200 -25200 0 -07} + {371620800 -21600 1 -06} + {384922800 -21600 0 -06} + {403070400 -18000 1 -05} + {416372400 -21600 0 -06} + {434520000 -18000 1 -05} + {447822000 -21600 0 -06} + {466574400 -18000 1 -05} + {479271600 -21600 0 -06} + {498024000 -18000 1 -05} + {510721200 -21600 0 -06} + {529473600 -18000 1 -05} + {545194800 -21600 0 -06} + {560923200 -18000 1 -05} + {574225200 -21600 0 -06} + {592372800 -18000 1 -05} + {605674800 -21600 0 -06} + {624427200 -18000 1 -05} + {637124400 -21600 0 -06} + {653457600 -18000 1 -05} + {668574000 -21600 0 -06} + {687326400 -18000 1 -05} + {700628400 -21600 0 -06} + {718776000 -18000 1 -05} + {732078000 -21600 0 -06} + {750225600 -18000 1 -05} + {763527600 -21600 0 -06} + {781675200 -18000 1 -05} + {794977200 -21600 0 -06} + {813729600 -18000 1 -05} + {826426800 -21600 0 -06} + {845179200 -18000 1 -05} + {859690800 -21600 0 -06} + {876628800 -18000 1 -05} + {889930800 -21600 0 -06} + {906868800 -18000 1 -05} + {923194800 -21600 0 -06} + {939528000 -18000 1 -05} + {952830000 -21600 0 -06} + {971582400 -18000 1 -05} + {984279600 -21600 0 -06} + {1003032000 -18000 1 -05} + {1015729200 -21600 0 -06} + {1034481600 -18000 1 -05} + {1047178800 -21600 0 -06} + {1065931200 -18000 1 -05} + {1079233200 -21600 0 -06} + {1097380800 -18000 1 -05} + {1110682800 -21600 0 -06} + {1128830400 -18000 1 -05} + {1142132400 -21600 0 -06} + {1160884800 -18000 1 -05} + {1173582000 -21600 0 -06} + {1192334400 -18000 1 -05} + {1206846000 -21600 0 -06} + {1223784000 -18000 1 -05} + {1237086000 -21600 0 -06} + {1255233600 -18000 1 -05} + {1270350000 -21600 0 -06} + {1286683200 -18000 1 -05} + {1304823600 -21600 0 -06} + {1313899200 -18000 1 -05} + {1335668400 -21600 0 -06} + {1346558400 -18000 1 -05} + {1367118000 -21600 0 -06} + {1378612800 -18000 1 -05} + {1398567600 -21600 0 -06} + {1410062400 -18000 1 -05} + {1463281200 -21600 0 -06} + {1471147200 -18000 1 -05} + {1494730800 -21600 0 -06} + {1502596800 -18000 1 -05} + {1526180400 -21600 0 -06} + {1534046400 -18000 1 -05} + {1557630000 -21600 0 -06} + {1565496000 -18000 1 -05} + {1589079600 -21600 0 -06} + {1596945600 -18000 1 -05} + {1620529200 -21600 0 -06} + {1629000000 -18000 1 -05} + {1652583600 -21600 0 -06} + {1660449600 -18000 1 -05} + {1684033200 -21600 0 -06} + {1691899200 -18000 1 -05} + {1715482800 -21600 0 -06} + {1723348800 -18000 1 -05} + {1746932400 -21600 0 -06} + {1754798400 -18000 1 -05} + {1778382000 -21600 0 -06} + {1786248000 -18000 1 -05} + {1809831600 -21600 0 -06} + {1818302400 -18000 1 -05} + {1841886000 -21600 0 -06} + {1849752000 -18000 1 -05} + {1873335600 -21600 0 -06} + {1881201600 -18000 1 -05} + {1904785200 -21600 0 -06} + {1912651200 -18000 1 -05} + {1936234800 -21600 0 -06} + {1944100800 -18000 1 -05} + {1967684400 -21600 0 -06} + {1976155200 -18000 1 -05} + {1999738800 -21600 0 -06} + {2007604800 -18000 1 -05} + {2031188400 -21600 0 -06} + {2039054400 -18000 1 -05} + {2062638000 -21600 0 -06} + {2070504000 -18000 1 -05} + {2094087600 -21600 0 -06} + {2101953600 -18000 1 -05} + {2125537200 -21600 0 -06} + {2133403200 -18000 1 -05} + {2156986800 -21600 0 -06} + {2165457600 -18000 1 -05} + {2189041200 -21600 0 -06} + {2196907200 -18000 1 -05} + {2220490800 -21600 0 -06} + {2228356800 -18000 1 -05} + {2251940400 -21600 0 -06} + {2259806400 -18000 1 -05} + {2283390000 -21600 0 -06} + {2291256000 -18000 1 -05} + {2314839600 -21600 0 -06} + {2322705600 -18000 1 -05} + {2346894000 -21600 0 -06} + {2354760000 -18000 1 -05} + {2378343600 -21600 0 -06} + {2386209600 -18000 1 -05} + {2409793200 -21600 0 -06} + {2417659200 -18000 1 -05} + {2441242800 -21600 0 -06} + {2449108800 -18000 1 -05} + {2472692400 -21600 0 -06} + {2480558400 -18000 1 -05} + {2504142000 -21600 0 -06} + {2512612800 -18000 1 -05} + {2536196400 -21600 0 -06} + {2544062400 -18000 1 -05} + {2567646000 -21600 0 -06} + {2575512000 -18000 1 -05} + {2599095600 -21600 0 -06} + {2606961600 -18000 1 -05} + {2630545200 -21600 0 -06} + {2638411200 -18000 1 -05} + {2661994800 -21600 0 -06} + {2669860800 -18000 1 -05} + {2693444400 -21600 0 -06} + {2701915200 -18000 1 -05} + {2725498800 -21600 0 -06} + {2733364800 -18000 1 -05} + {2756948400 -21600 0 -06} + {2764814400 -18000 1 -05} + {2788398000 -21600 0 -06} + {2796264000 -18000 1 -05} + {2819847600 -21600 0 -06} + {2827713600 -18000 1 -05} + {2851297200 -21600 0 -06} + {2859768000 -18000 1 -05} + {2883351600 -21600 0 -06} + {2891217600 -18000 1 -05} + {2914801200 -21600 0 -06} + {2922667200 -18000 1 -05} + {2946250800 -21600 0 -06} + {2954116800 -18000 1 -05} + {2977700400 -21600 0 -06} + {2985566400 -18000 1 -05} + {3009150000 -21600 0 -06} + {3017016000 -18000 1 -05} + {3040599600 -21600 0 -06} + {3049070400 -18000 1 -05} + {3072654000 -21600 0 -06} + {3080520000 -18000 1 -05} + {3104103600 -21600 0 -06} + {3111969600 -18000 1 -05} + {3135553200 -21600 0 -06} + {3143419200 -18000 1 -05} + {3167002800 -21600 0 -06} + {3174868800 -18000 1 -05} + {3198452400 -21600 0 -06} + {3206318400 -18000 1 -05} + {3230506800 -21600 0 -06} + {3238372800 -18000 1 -05} + {3261956400 -21600 0 -06} + {3269822400 -18000 1 -05} + {3293406000 -21600 0 -06} + {3301272000 -18000 1 -05} + {3324855600 -21600 0 -06} + {3332721600 -18000 1 -05} + {3356305200 -21600 0 -06} + {3364171200 -18000 1 -05} + {3387754800 -21600 0 -06} + {3396225600 -18000 1 -05} + {3419809200 -21600 0 -06} + {3427675200 -18000 1 -05} + {3451258800 -21600 0 -06} + {3459124800 -18000 1 -05} + {3482708400 -21600 0 -06} + {3490574400 -18000 1 -05} + {3514158000 -21600 0 -06} + {3522024000 -18000 1 -05} + {3545607600 -21600 0 -06} + {3553473600 -18000 1 -05} + {3577057200 -21600 0 -06} + {3585528000 -18000 1 -05} + {3609111600 -21600 0 -06} + {3616977600 -18000 1 -05} + {3640561200 -21600 0 -06} + {3648427200 -18000 1 -05} + {3672010800 -21600 0 -06} + {3679876800 -18000 1 -05} + {3703460400 -21600 0 -06} + {3711326400 -18000 1 -05} + {3734910000 -21600 0 -06} + {3743380800 -18000 1 -05} + {3766964400 -21600 0 -06} + {3774830400 -18000 1 -05} + {3798414000 -21600 0 -06} + {3806280000 -18000 1 -05} + {3829863600 -21600 0 -06} + {3837729600 -18000 1 -05} + {3861313200 -21600 0 -06} + {3869179200 -18000 1 -05} + {3892762800 -21600 0 -06} + {3900628800 -18000 1 -05} + {3924212400 -21600 0 -06} + {3932683200 -18000 1 -05} + {3956266800 -21600 0 -06} + {3964132800 -18000 1 -05} + {3987716400 -21600 0 -06} + {3995582400 -18000 1 -05} + {4019166000 -21600 0 -06} + {4027032000 -18000 1 -05} + {4050615600 -21600 0 -06} + {4058481600 -18000 1 -05} + {4082065200 -21600 0 -06} + {4089931200 -18000 1 -05} } diff --git a/library/tzdata/Pacific/Efate b/library/tzdata/Pacific/Efate index 18db6de..a43852e 100644 --- a/library/tzdata/Pacific/Efate +++ b/library/tzdata/Pacific/Efate @@ -2,25 +2,25 @@ set TZData(:Pacific/Efate) { {-9223372036854775808 40396 0 LMT} - {-1829387596 39600 0 VUT} - {433256400 43200 1 VUST} - {448977600 39600 0 VUT} - {467298000 43200 1 VUST} - {480427200 39600 0 VUT} - {496760400 43200 1 VUST} - {511876800 39600 0 VUT} - {528210000 43200 1 VUST} - {543931200 39600 0 VUT} - {559659600 43200 1 VUST} - {575380800 39600 0 VUT} - {591109200 43200 1 VUST} - {606830400 39600 0 VUT} - {622558800 43200 1 VUST} - {638280000 39600 0 VUT} - {654008400 43200 1 VUST} - {669729600 39600 0 VUT} - {686062800 43200 1 VUST} - {696340800 39600 0 VUT} - {719931600 43200 1 VUST} - {727790400 39600 0 VUT} + {-1829387596 39600 0 +11} + {433256400 43200 1 +12} + {448977600 39600 0 +11} + {467298000 43200 1 +12} + {480427200 39600 0 +11} + {496760400 43200 1 +12} + {511876800 39600 0 +11} + {528210000 43200 1 +12} + {543931200 39600 0 +11} + {559659600 43200 1 +12} + {575380800 39600 0 +11} + {591109200 43200 1 +12} + {606830400 39600 0 +11} + {622558800 43200 1 +12} + {638280000 39600 0 +11} + {654008400 43200 1 +12} + {669729600 39600 0 +11} + {686062800 43200 1 +12} + {696340800 39600 0 +11} + {719931600 43200 1 +12} + {727790400 39600 0 +11} } diff --git a/library/tzdata/Pacific/Enderbury b/library/tzdata/Pacific/Enderbury index 55784c4..6abd57e 100644 --- a/library/tzdata/Pacific/Enderbury +++ b/library/tzdata/Pacific/Enderbury @@ -2,7 +2,7 @@ set TZData(:Pacific/Enderbury) { {-9223372036854775808 -41060 0 LMT} - {-2177411740 -43200 0 PHOT} - {307627200 -39600 0 PHOT} - {788958000 46800 0 PHOT} + {-2177411740 -43200 0 -12} + {307627200 -39600 0 -11} + {788958000 46800 0 +13} } diff --git a/library/tzdata/Pacific/Fakaofo b/library/tzdata/Pacific/Fakaofo index 6ec98eb..d75030d 100644 --- a/library/tzdata/Pacific/Fakaofo +++ b/library/tzdata/Pacific/Fakaofo @@ -2,6 +2,6 @@ set TZData(:Pacific/Fakaofo) { {-9223372036854775808 -41096 0 LMT} - {-2177411704 -39600 0 TKT} - {1325242800 46800 0 TKT} + {-2177411704 -39600 0 -11} + {1325242800 46800 0 +13} } diff --git a/library/tzdata/Pacific/Fiji b/library/tzdata/Pacific/Fiji index 8f8b12f..fa8c99e 100644 --- a/library/tzdata/Pacific/Fiji +++ b/library/tzdata/Pacific/Fiji @@ -2,190 +2,190 @@ set TZData(:Pacific/Fiji) { {-9223372036854775808 42944 0 LMT} - {-1709985344 43200 0 FJT} - {909842400 46800 1 FJST} - {920124000 43200 0 FJT} - {941896800 46800 1 FJST} - {951573600 43200 0 FJT} - {1259416800 46800 1 FJST} - {1269698400 43200 0 FJT} - {1287842400 46800 1 FJST} - {1299333600 43200 0 FJT} - {1319292000 46800 1 FJST} - {1327154400 43200 0 FJT} - {1350741600 46800 1 FJST} - {1358604000 43200 0 FJT} - {1382796000 46800 1 FJST} - {1390050000 43200 0 FJT} - {1414850400 46800 1 FJST} - {1421503200 43200 0 FJT} - {1446300000 46800 1 FJST} - {1452952800 43200 0 FJT} - {1478354400 46800 1 FJST} - {1484402400 43200 0 FJT} - {1509804000 46800 1 FJST} - {1516456800 43200 0 FJT} - {1541253600 46800 1 FJST} - {1547906400 43200 0 FJT} - {1572703200 46800 1 FJST} - {1579356000 43200 0 FJT} - {1604152800 46800 1 FJST} - {1610805600 43200 0 FJT} - {1636207200 46800 1 FJST} - {1642255200 43200 0 FJT} - {1667656800 46800 1 FJST} - {1673704800 43200 0 FJT} - {1699106400 46800 1 FJST} - {1705759200 43200 0 FJT} - {1730556000 46800 1 FJST} - {1737208800 43200 0 FJT} - {1762005600 46800 1 FJST} - {1768658400 43200 0 FJT} - {1793455200 46800 1 FJST} - {1800108000 43200 0 FJT} - {1825509600 46800 1 FJST} - {1831557600 43200 0 FJT} - {1856959200 46800 1 FJST} - {1863612000 43200 0 FJT} - {1888408800 46800 1 FJST} - {1895061600 43200 0 FJT} - {1919858400 46800 1 FJST} - {1926511200 43200 0 FJT} - {1951308000 46800 1 FJST} - {1957960800 43200 0 FJT} - {1983362400 46800 1 FJST} - {1989410400 43200 0 FJT} - {2014812000 46800 1 FJST} - {2020860000 43200 0 FJT} - {2046261600 46800 1 FJST} - {2052914400 43200 0 FJT} - {2077711200 46800 1 FJST} - {2084364000 43200 0 FJT} - {2109160800 46800 1 FJST} - {2115813600 43200 0 FJT} - {2140610400 46800 1 FJST} - {2147263200 43200 0 FJT} - {2172664800 46800 1 FJST} - {2178712800 43200 0 FJT} - {2204114400 46800 1 FJST} - {2210162400 43200 0 FJT} - {2235564000 46800 1 FJST} - {2242216800 43200 0 FJT} - {2267013600 46800 1 FJST} - {2273666400 43200 0 FJT} - {2298463200 46800 1 FJST} - {2305116000 43200 0 FJT} - {2329912800 46800 1 FJST} - {2336565600 43200 0 FJT} - {2361967200 46800 1 FJST} - {2368015200 43200 0 FJT} - {2393416800 46800 1 FJST} - {2400069600 43200 0 FJT} - {2424866400 46800 1 FJST} - {2431519200 43200 0 FJT} - {2456316000 46800 1 FJST} - {2462968800 43200 0 FJT} - {2487765600 46800 1 FJST} - {2494418400 43200 0 FJT} - {2519820000 46800 1 FJST} - {2525868000 43200 0 FJT} - {2551269600 46800 1 FJST} - {2557317600 43200 0 FJT} - {2582719200 46800 1 FJST} - {2589372000 43200 0 FJT} - {2614168800 46800 1 FJST} - {2620821600 43200 0 FJT} - {2645618400 46800 1 FJST} - {2652271200 43200 0 FJT} - {2677068000 46800 1 FJST} - {2683720800 43200 0 FJT} - {2709122400 46800 1 FJST} - {2715170400 43200 0 FJT} - {2740572000 46800 1 FJST} - {2747224800 43200 0 FJT} - {2772021600 46800 1 FJST} - {2778674400 43200 0 FJT} - {2803471200 46800 1 FJST} - {2810124000 43200 0 FJT} - {2834920800 46800 1 FJST} - {2841573600 43200 0 FJT} - {2866975200 46800 1 FJST} - {2873023200 43200 0 FJT} - {2898424800 46800 1 FJST} - {2904472800 43200 0 FJT} - {2929874400 46800 1 FJST} - {2936527200 43200 0 FJT} - {2961324000 46800 1 FJST} - {2967976800 43200 0 FJT} - {2992773600 46800 1 FJST} - {2999426400 43200 0 FJT} - {3024223200 46800 1 FJST} - {3030876000 43200 0 FJT} - {3056277600 46800 1 FJST} - {3062325600 43200 0 FJT} - {3087727200 46800 1 FJST} - {3093775200 43200 0 FJT} - {3119176800 46800 1 FJST} - {3125829600 43200 0 FJT} - {3150626400 46800 1 FJST} - {3157279200 43200 0 FJT} - {3182076000 46800 1 FJST} - {3188728800 43200 0 FJT} - {3213525600 46800 1 FJST} - {3220178400 43200 0 FJT} - {3245580000 46800 1 FJST} - {3251628000 43200 0 FJT} - {3277029600 46800 1 FJST} - {3283682400 43200 0 FJT} - {3308479200 46800 1 FJST} - {3315132000 43200 0 FJT} - {3339928800 46800 1 FJST} - {3346581600 43200 0 FJT} - {3371378400 46800 1 FJST} - {3378031200 43200 0 FJT} - {3403432800 46800 1 FJST} - {3409480800 43200 0 FJT} - {3434882400 46800 1 FJST} - {3440930400 43200 0 FJT} - {3466332000 46800 1 FJST} - {3472984800 43200 0 FJT} - {3497781600 46800 1 FJST} - {3504434400 43200 0 FJT} - {3529231200 46800 1 FJST} - {3535884000 43200 0 FJT} - {3560680800 46800 1 FJST} - {3567333600 43200 0 FJT} - {3592735200 46800 1 FJST} - {3598783200 43200 0 FJT} - {3624184800 46800 1 FJST} - {3630837600 43200 0 FJT} - {3655634400 46800 1 FJST} - {3662287200 43200 0 FJT} - {3687084000 46800 1 FJST} - {3693736800 43200 0 FJT} - {3718533600 46800 1 FJST} - {3725186400 43200 0 FJT} - {3750588000 46800 1 FJST} - {3756636000 43200 0 FJT} - {3782037600 46800 1 FJST} - {3788085600 43200 0 FJT} - {3813487200 46800 1 FJST} - {3820140000 43200 0 FJT} - {3844936800 46800 1 FJST} - {3851589600 43200 0 FJT} - {3876386400 46800 1 FJST} - {3883039200 43200 0 FJT} - {3907836000 46800 1 FJST} - {3914488800 43200 0 FJT} - {3939890400 46800 1 FJST} - {3945938400 43200 0 FJT} - {3971340000 46800 1 FJST} - {3977388000 43200 0 FJT} - {4002789600 46800 1 FJST} - {4009442400 43200 0 FJT} - {4034239200 46800 1 FJST} - {4040892000 43200 0 FJT} - {4065688800 46800 1 FJST} - {4072341600 43200 0 FJT} - {4097138400 46800 1 FJST} + {-1709985344 43200 0 +12} + {909842400 46800 1 +13} + {920124000 43200 0 +12} + {941896800 46800 1 +13} + {951573600 43200 0 +12} + {1259416800 46800 1 +13} + {1269698400 43200 0 +12} + {1287842400 46800 1 +13} + {1299333600 43200 0 +12} + {1319292000 46800 1 +13} + {1327154400 43200 0 +12} + {1350741600 46800 1 +13} + {1358604000 43200 0 +12} + {1382796000 46800 1 +13} + {1390050000 43200 0 +12} + {1414850400 46800 1 +13} + {1421503200 43200 0 +12} + {1446300000 46800 1 +13} + {1452952800 43200 0 +12} + {1478354400 46800 1 +13} + {1484402400 43200 0 +12} + {1509804000 46800 1 +13} + {1516456800 43200 0 +12} + {1541253600 46800 1 +13} + {1547906400 43200 0 +12} + {1572703200 46800 1 +13} + {1579356000 43200 0 +12} + {1604152800 46800 1 +13} + {1610805600 43200 0 +12} + {1636207200 46800 1 +13} + {1642255200 43200 0 +12} + {1667656800 46800 1 +13} + {1673704800 43200 0 +12} + {1699106400 46800 1 +13} + {1705759200 43200 0 +12} + {1730556000 46800 1 +13} + {1737208800 43200 0 +12} + {1762005600 46800 1 +13} + {1768658400 43200 0 +12} + {1793455200 46800 1 +13} + {1800108000 43200 0 +12} + {1825509600 46800 1 +13} + {1831557600 43200 0 +12} + {1856959200 46800 1 +13} + {1863612000 43200 0 +12} + {1888408800 46800 1 +13} + {1895061600 43200 0 +12} + {1919858400 46800 1 +13} + {1926511200 43200 0 +12} + {1951308000 46800 1 +13} + {1957960800 43200 0 +12} + {1983362400 46800 1 +13} + {1989410400 43200 0 +12} + {2014812000 46800 1 +13} + {2020860000 43200 0 +12} + {2046261600 46800 1 +13} + {2052914400 43200 0 +12} + {2077711200 46800 1 +13} + {2084364000 43200 0 +12} + {2109160800 46800 1 +13} + {2115813600 43200 0 +12} + {2140610400 46800 1 +13} + {2147263200 43200 0 +12} + {2172664800 46800 1 +13} + {2178712800 43200 0 +12} + {2204114400 46800 1 +13} + {2210162400 43200 0 +12} + {2235564000 46800 1 +13} + {2242216800 43200 0 +12} + {2267013600 46800 1 +13} + {2273666400 43200 0 +12} + {2298463200 46800 1 +13} + {2305116000 43200 0 +12} + {2329912800 46800 1 +13} + {2336565600 43200 0 +12} + {2361967200 46800 1 +13} + {2368015200 43200 0 +12} + {2393416800 46800 1 +13} + {2400069600 43200 0 +12} + {2424866400 46800 1 +13} + {2431519200 43200 0 +12} + {2456316000 46800 1 +13} + {2462968800 43200 0 +12} + {2487765600 46800 1 +13} + {2494418400 43200 0 +12} + {2519820000 46800 1 +13} + {2525868000 43200 0 +12} + {2551269600 46800 1 +13} + {2557317600 43200 0 +12} + {2582719200 46800 1 +13} + {2589372000 43200 0 +12} + {2614168800 46800 1 +13} + {2620821600 43200 0 +12} + {2645618400 46800 1 +13} + {2652271200 43200 0 +12} + {2677068000 46800 1 +13} + {2683720800 43200 0 +12} + {2709122400 46800 1 +13} + {2715170400 43200 0 +12} + {2740572000 46800 1 +13} + {2747224800 43200 0 +12} + {2772021600 46800 1 +13} + {2778674400 43200 0 +12} + {2803471200 46800 1 +13} + {2810124000 43200 0 +12} + {2834920800 46800 1 +13} + {2841573600 43200 0 +12} + {2866975200 46800 1 +13} + {2873023200 43200 0 +12} + {2898424800 46800 1 +13} + {2904472800 43200 0 +12} + {2929874400 46800 1 +13} + {2936527200 43200 0 +12} + {2961324000 46800 1 +13} + {2967976800 43200 0 +12} + {2992773600 46800 1 +13} + {2999426400 43200 0 +12} + {3024223200 46800 1 +13} + {3030876000 43200 0 +12} + {3056277600 46800 1 +13} + {3062325600 43200 0 +12} + {3087727200 46800 1 +13} + {3093775200 43200 0 +12} + {3119176800 46800 1 +13} + {3125829600 43200 0 +12} + {3150626400 46800 1 +13} + {3157279200 43200 0 +12} + {3182076000 46800 1 +13} + {3188728800 43200 0 +12} + {3213525600 46800 1 +13} + {3220178400 43200 0 +12} + {3245580000 46800 1 +13} + {3251628000 43200 0 +12} + {3277029600 46800 1 +13} + {3283682400 43200 0 +12} + {3308479200 46800 1 +13} + {3315132000 43200 0 +12} + {3339928800 46800 1 +13} + {3346581600 43200 0 +12} + {3371378400 46800 1 +13} + {3378031200 43200 0 +12} + {3403432800 46800 1 +13} + {3409480800 43200 0 +12} + {3434882400 46800 1 +13} + {3440930400 43200 0 +12} + {3466332000 46800 1 +13} + {3472984800 43200 0 +12} + {3497781600 46800 1 +13} + {3504434400 43200 0 +12} + {3529231200 46800 1 +13} + {3535884000 43200 0 +12} + {3560680800 46800 1 +13} + {3567333600 43200 0 +12} + {3592735200 46800 1 +13} + {3598783200 43200 0 +12} + {3624184800 46800 1 +13} + {3630837600 43200 0 +12} + {3655634400 46800 1 +13} + {3662287200 43200 0 +12} + {3687084000 46800 1 +13} + {3693736800 43200 0 +12} + {3718533600 46800 1 +13} + {3725186400 43200 0 +12} + {3750588000 46800 1 +13} + {3756636000 43200 0 +12} + {3782037600 46800 1 +13} + {3788085600 43200 0 +12} + {3813487200 46800 1 +13} + {3820140000 43200 0 +12} + {3844936800 46800 1 +13} + {3851589600 43200 0 +12} + {3876386400 46800 1 +13} + {3883039200 43200 0 +12} + {3907836000 46800 1 +13} + {3914488800 43200 0 +12} + {3939890400 46800 1 +13} + {3945938400 43200 0 +12} + {3971340000 46800 1 +13} + {3977388000 43200 0 +12} + {4002789600 46800 1 +13} + {4009442400 43200 0 +12} + {4034239200 46800 1 +13} + {4040892000 43200 0 +12} + {4065688800 46800 1 +13} + {4072341600 43200 0 +12} + {4097138400 46800 1 +13} } diff --git a/library/tzdata/Pacific/Funafuti b/library/tzdata/Pacific/Funafuti index b94e4fb..d806525 100644 --- a/library/tzdata/Pacific/Funafuti +++ b/library/tzdata/Pacific/Funafuti @@ -2,5 +2,5 @@ set TZData(:Pacific/Funafuti) { {-9223372036854775808 43012 0 LMT} - {-2177495812 43200 0 TVT} + {-2177495812 43200 0 +12} } diff --git a/library/tzdata/Pacific/Galapagos b/library/tzdata/Pacific/Galapagos index d8c80e8..f276f73 100644 --- a/library/tzdata/Pacific/Galapagos +++ b/library/tzdata/Pacific/Galapagos @@ -2,6 +2,8 @@ set TZData(:Pacific/Galapagos) { {-9223372036854775808 -21504 0 LMT} - {-1230746496 -18000 0 ECT} - {504939600 -21600 0 GALT} + {-1230746496 -18000 0 -05} + {504939600 -21600 0 -06} + {722930400 -18000 1 -05} + {728888400 -21600 0 -06} } diff --git a/library/tzdata/Pacific/Gambier b/library/tzdata/Pacific/Gambier index d69f99a..9ebd97c 100644 --- a/library/tzdata/Pacific/Gambier +++ b/library/tzdata/Pacific/Gambier @@ -2,5 +2,5 @@ set TZData(:Pacific/Gambier) { {-9223372036854775808 -32388 0 LMT} - {-1806678012 -32400 0 GAMT} + {-1806678012 -32400 0 -09} } diff --git a/library/tzdata/Pacific/Guadalcanal b/library/tzdata/Pacific/Guadalcanal index 09a67dd..7e13e6e 100644 --- a/library/tzdata/Pacific/Guadalcanal +++ b/library/tzdata/Pacific/Guadalcanal @@ -2,5 +2,5 @@ set TZData(:Pacific/Guadalcanal) { {-9223372036854775808 38388 0 LMT} - {-1806748788 39600 0 SBT} + {-1806748788 39600 0 +11} } diff --git a/library/tzdata/Pacific/Kiritimati b/library/tzdata/Pacific/Kiritimati index 06b695b..b703f19 100644 --- a/library/tzdata/Pacific/Kiritimati +++ b/library/tzdata/Pacific/Kiritimati @@ -2,7 +2,7 @@ set TZData(:Pacific/Kiritimati) { {-9223372036854775808 -37760 0 LMT} - {-2177415040 -38400 0 LINT} - {307622400 -36000 0 LINT} - {788954400 50400 0 LINT} + {-2177415040 -38400 0 -1040} + {307622400 -36000 0 -10} + {788954400 50400 0 +14} } diff --git a/library/tzdata/Pacific/Kosrae b/library/tzdata/Pacific/Kosrae index a16b19d..04bed35 100644 --- a/library/tzdata/Pacific/Kosrae +++ b/library/tzdata/Pacific/Kosrae @@ -2,7 +2,7 @@ set TZData(:Pacific/Kosrae) { {-9223372036854775808 39116 0 LMT} - {-2177491916 39600 0 KOST} - {-7988400 43200 0 KOST} - {915105600 39600 0 KOST} + {-2177491916 39600 0 +11} + {-7988400 43200 0 +12} + {915105600 39600 0 +11} } diff --git a/library/tzdata/Pacific/Kwajalein b/library/tzdata/Pacific/Kwajalein index 8600b3b..19e1067 100644 --- a/library/tzdata/Pacific/Kwajalein +++ b/library/tzdata/Pacific/Kwajalein @@ -2,7 +2,7 @@ set TZData(:Pacific/Kwajalein) { {-9223372036854775808 40160 0 LMT} - {-2177492960 39600 0 MHT} - {-7988400 -43200 0 KWAT} - {745848000 43200 0 MHT} + {-2177492960 39600 0 +11} + {-7988400 -43200 0 -12} + {745848000 43200 0 +12} } diff --git a/library/tzdata/Pacific/Majuro b/library/tzdata/Pacific/Majuro index 468baab..5e9ac99 100644 --- a/library/tzdata/Pacific/Majuro +++ b/library/tzdata/Pacific/Majuro @@ -2,6 +2,6 @@ set TZData(:Pacific/Majuro) { {-9223372036854775808 41088 0 LMT} - {-2177493888 39600 0 MHT} - {-7988400 43200 0 MHT} + {-2177493888 39600 0 +11} + {-7988400 43200 0 +12} } diff --git a/library/tzdata/Pacific/Marquesas b/library/tzdata/Pacific/Marquesas index 9bb508f..ac77a2f 100644 --- a/library/tzdata/Pacific/Marquesas +++ b/library/tzdata/Pacific/Marquesas @@ -2,5 +2,5 @@ set TZData(:Pacific/Marquesas) { {-9223372036854775808 -33480 0 LMT} - {-1806676920 -34200 0 MART} + {-1806676920 -34200 0 -0930} } diff --git a/library/tzdata/Pacific/Nauru b/library/tzdata/Pacific/Nauru index 2da1e25..de10811 100644 --- a/library/tzdata/Pacific/Nauru +++ b/library/tzdata/Pacific/Nauru @@ -2,8 +2,8 @@ set TZData(:Pacific/Nauru) { {-9223372036854775808 40060 0 LMT} - {-1545131260 41400 0 NRT} - {-877347000 32400 0 JST} - {-800960400 41400 0 NRT} - {294323400 43200 0 NRT} + {-1545131260 41400 0 +1130} + {-877347000 32400 0 +09} + {-800960400 41400 0 +1130} + {294323400 43200 0 +12} } diff --git a/library/tzdata/Pacific/Niue b/library/tzdata/Pacific/Niue index cf149fc..fe19c59 100644 --- a/library/tzdata/Pacific/Niue +++ b/library/tzdata/Pacific/Niue @@ -2,7 +2,7 @@ set TZData(:Pacific/Niue) { {-9223372036854775808 -40780 0 LMT} - {-2177412020 -40800 0 NUT} - {-599575200 -41400 0 NUT} - {276089400 -39600 0 NUT} + {-2177412020 -40800 0 -1120} + {-599575200 -41400 0 -1130} + {276089400 -39600 0 -11} } diff --git a/library/tzdata/Pacific/Norfolk b/library/tzdata/Pacific/Norfolk index b12ab8c..f0556ab 100644 --- a/library/tzdata/Pacific/Norfolk +++ b/library/tzdata/Pacific/Norfolk @@ -2,9 +2,9 @@ set TZData(:Pacific/Norfolk) { {-9223372036854775808 40312 0 LMT} - {-2177493112 40320 0 NMT} - {-599656320 41400 0 NFT} - {152029800 45000 1 NFST} - {162912600 41400 0 NFT} - {1443882600 39600 0 NFT} + {-2177493112 40320 0 +1112} + {-599656320 41400 0 +1130} + {152029800 45000 1 +1230} + {162912600 41400 0 +1130} + {1443882600 39600 0 +11} } diff --git a/library/tzdata/Pacific/Noumea b/library/tzdata/Pacific/Noumea index db1eeae..36b570d 100644 --- a/library/tzdata/Pacific/Noumea +++ b/library/tzdata/Pacific/Noumea @@ -2,11 +2,11 @@ set TZData(:Pacific/Noumea) { {-9223372036854775808 39948 0 LMT} - {-1829387148 39600 0 NCT} - {250002000 43200 1 NCST} - {257342400 39600 0 NCT} - {281451600 43200 1 NCST} - {288878400 39600 0 NCT} - {849366000 43200 1 NCST} - {857228400 39600 0 NCT} + {-1829387148 39600 0 +11} + {250002000 43200 1 +12} + {257342400 39600 0 +11} + {281451600 43200 1 +12} + {288878400 39600 0 +11} + {849366000 43200 1 +12} + {857228400 39600 0 +11} } diff --git a/library/tzdata/Pacific/Pago_Pago b/library/tzdata/Pacific/Pago_Pago index ca261d0..d30c981 100644 --- a/library/tzdata/Pacific/Pago_Pago +++ b/library/tzdata/Pacific/Pago_Pago @@ -3,7 +3,5 @@ set TZData(:Pacific/Pago_Pago) { {-9223372036854775808 45432 0 LMT} {-2855738232 -40968 0 LMT} - {-1861879032 -39600 0 NST} - {-86878800 -39600 0 BST} - {439038000 -39600 0 SST} + {-1861879032 -39600 0 SST} } diff --git a/library/tzdata/Pacific/Palau b/library/tzdata/Pacific/Palau index ee0606d..a50fd2a 100644 --- a/library/tzdata/Pacific/Palau +++ b/library/tzdata/Pacific/Palau @@ -2,5 +2,5 @@ set TZData(:Pacific/Palau) { {-9223372036854775808 32276 0 LMT} - {-2177485076 32400 0 PWT} + {-2177485076 32400 0 +09} } diff --git a/library/tzdata/Pacific/Pitcairn b/library/tzdata/Pacific/Pitcairn index d62644e..6813978 100644 --- a/library/tzdata/Pacific/Pitcairn +++ b/library/tzdata/Pacific/Pitcairn @@ -2,6 +2,6 @@ set TZData(:Pacific/Pitcairn) { {-9223372036854775808 -31220 0 LMT} - {-2177421580 -30600 0 PNT} - {893665800 -28800 0 PST} + {-2177421580 -30600 0 -0830} + {893665800 -28800 0 -08} } diff --git a/library/tzdata/Pacific/Pohnpei b/library/tzdata/Pacific/Pohnpei index 58978da..3fcb5d0 100644 --- a/library/tzdata/Pacific/Pohnpei +++ b/library/tzdata/Pacific/Pohnpei @@ -2,5 +2,5 @@ set TZData(:Pacific/Pohnpei) { {-9223372036854775808 37972 0 LMT} - {-2177490772 39600 0 PONT} + {-2177490772 39600 0 +11} } diff --git a/library/tzdata/Pacific/Port_Moresby b/library/tzdata/Pacific/Port_Moresby index 65eb533..c3a5e4f 100644 --- a/library/tzdata/Pacific/Port_Moresby +++ b/library/tzdata/Pacific/Port_Moresby @@ -3,5 +3,5 @@ set TZData(:Pacific/Port_Moresby) { {-9223372036854775808 35320 0 LMT} {-2840176120 35312 0 PMMT} - {-2366790512 36000 0 PGT} + {-2366790512 36000 0 +10} } diff --git a/library/tzdata/Pacific/Rarotonga b/library/tzdata/Pacific/Rarotonga index a4ecf8d..9a70318 100644 --- a/library/tzdata/Pacific/Rarotonga +++ b/library/tzdata/Pacific/Rarotonga @@ -2,31 +2,31 @@ set TZData(:Pacific/Rarotonga) { {-9223372036854775808 -38344 0 LMT} - {-2177414456 -37800 0 CKT} - {279714600 -34200 0 CKHST} - {289387800 -36000 0 CKT} - {309952800 -34200 1 CKHST} - {320837400 -36000 0 CKT} - {341402400 -34200 1 CKHST} - {352287000 -36000 0 CKT} - {372852000 -34200 1 CKHST} - {384341400 -36000 0 CKT} - {404906400 -34200 1 CKHST} - {415791000 -36000 0 CKT} - {436356000 -34200 1 CKHST} - {447240600 -36000 0 CKT} - {467805600 -34200 1 CKHST} - {478690200 -36000 0 CKT} - {499255200 -34200 1 CKHST} - {510139800 -36000 0 CKT} - {530704800 -34200 1 CKHST} - {541589400 -36000 0 CKT} - {562154400 -34200 1 CKHST} - {573643800 -36000 0 CKT} - {594208800 -34200 1 CKHST} - {605093400 -36000 0 CKT} - {625658400 -34200 1 CKHST} - {636543000 -36000 0 CKT} - {657108000 -34200 1 CKHST} - {667992600 -36000 0 CKT} + {-2177414456 -37800 0 -1030} + {279714600 -34200 0 -0930} + {289387800 -36000 0 -10} + {309952800 -34200 1 -0930} + {320837400 -36000 0 -10} + {341402400 -34200 1 -0930} + {352287000 -36000 0 -10} + {372852000 -34200 1 -0930} + {384341400 -36000 0 -10} + {404906400 -34200 1 -0930} + {415791000 -36000 0 -10} + {436356000 -34200 1 -0930} + {447240600 -36000 0 -10} + {467805600 -34200 1 -0930} + {478690200 -36000 0 -10} + {499255200 -34200 1 -0930} + {510139800 -36000 0 -10} + {530704800 -34200 1 -0930} + {541589400 -36000 0 -10} + {562154400 -34200 1 -0930} + {573643800 -36000 0 -10} + {594208800 -34200 1 -0930} + {605093400 -36000 0 -10} + {625658400 -34200 1 -0930} + {636543000 -36000 0 -10} + {657108000 -34200 1 -0930} + {667992600 -36000 0 -10} } diff --git a/library/tzdata/Pacific/Tahiti b/library/tzdata/Pacific/Tahiti index f739223..768553c 100644 --- a/library/tzdata/Pacific/Tahiti +++ b/library/tzdata/Pacific/Tahiti @@ -2,5 +2,5 @@ set TZData(:Pacific/Tahiti) { {-9223372036854775808 -35896 0 LMT} - {-1806674504 -36000 0 TAHT} + {-1806674504 -36000 0 -10} } diff --git a/library/tzdata/Pacific/Tarawa b/library/tzdata/Pacific/Tarawa index 2dab5a2..2b9b556 100644 --- a/library/tzdata/Pacific/Tarawa +++ b/library/tzdata/Pacific/Tarawa @@ -2,5 +2,5 @@ set TZData(:Pacific/Tarawa) { {-9223372036854775808 41524 0 LMT} - {-2177494324 43200 0 GILT} + {-2177494324 43200 0 +12} } diff --git a/library/tzdata/Pacific/Wake b/library/tzdata/Pacific/Wake index 5afedf5..67eab37 100644 --- a/library/tzdata/Pacific/Wake +++ b/library/tzdata/Pacific/Wake @@ -2,5 +2,5 @@ set TZData(:Pacific/Wake) { {-9223372036854775808 39988 0 LMT} - {-2177492788 43200 0 WAKT} + {-2177492788 43200 0 +12} } diff --git a/library/tzdata/Pacific/Wallis b/library/tzdata/Pacific/Wallis index 7bdd964..152e6af 100644 --- a/library/tzdata/Pacific/Wallis +++ b/library/tzdata/Pacific/Wallis @@ -2,5 +2,5 @@ set TZData(:Pacific/Wallis) { {-9223372036854775808 44120 0 LMT} - {-2177496920 43200 0 WFT} + {-2177496920 43200 0 +12} } -- cgit v0.12 From c0bedd810fd8cf8ed91641043fb615153a1da6ec Mon Sep 17 00:00:00 2001 From: dkf Date: Sun, 12 Mar 2017 18:36:21 +0000 Subject: Add mappings for groff-style character naming, used in experimental branches of Tk. --- tools/tcltk-man2html-utils.tcl | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/tools/tcltk-man2html-utils.tcl b/tools/tcltk-man2html-utils.tcl index 9052049..c887edd 100644 --- a/tools/tcltk-man2html-utils.tcl +++ b/tools/tcltk-man2html-utils.tcl @@ -155,8 +155,16 @@ proc process-text {text} { {\fP} {\fR} \ {\.} . \ {\(bu} "•" \ - {\*(qo} "ô" \ + "\\*(qo" "ô" \ ] + # This might make a few invalid mappings, but we don't use them + foreach c {a e i o u y A E I O U Y} { + foreach {prefix suffix} { + o circ / slash : uml ' acute ^ circ ` grave + } { + lappend charmap "\\\[${prefix}${c}\]" "&${c}${suffix};" + } + } lappend charmap {\-\|\-} -- ; # two hyphens lappend charmap {\-} - ; # a hyphen -- cgit v0.12 From c010901ea91557cfd0e0529eee7e0eeabacb7bbf Mon Sep 17 00:00:00 2001 From: fvogel Date: Sun, 12 Mar 2017 19:45:00 +0000 Subject: Fix error in formatting in info.n --- doc/info.n | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/info.n b/doc/info.n index 01ca10b..061e178 100644 --- a/doc/info.n +++ b/doc/info.n @@ -297,7 +297,7 @@ scripts are stored. This is actually the value of the \fBtcl_library\fR variable and may be changed by setting \fBtcl_library\fR. .TP -\fBinfo loaded \fR?\fIinterp\fR? \fR?\fIpackage\fR? +\fBinfo loaded \fR?\fIinterp\fR? \fIpackage\fR? . Returns the filename loaded as part of \fIpackage\fR. If \fIpackage\fR is not specified, returns a list describing all of the packages -- cgit v0.12 From 4ccedfaec494d98f1677ce45925f496c2d7c2b70 Mon Sep 17 00:00:00 2001 From: dkf Date: Mon, 13 Mar 2017 06:16:45 +0000 Subject: Add back missing significant character --- doc/info.n | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/info.n b/doc/info.n index 061e178..c3a62c9 100644 --- a/doc/info.n +++ b/doc/info.n @@ -297,7 +297,7 @@ scripts are stored. This is actually the value of the \fBtcl_library\fR variable and may be changed by setting \fBtcl_library\fR. .TP -\fBinfo loaded \fR?\fIinterp\fR? \fIpackage\fR? +\fBinfo loaded \fR?\fIinterp\fR? ?\fIpackage\fR? . Returns the filename loaded as part of \fIpackage\fR. If \fIpackage\fR is not specified, returns a list describing all of the packages -- cgit v0.12 From 6f905e1f0fa598055c516aa33529d41d2fadbe4a Mon Sep 17 00:00:00 2001 From: "jan.nijtmans" Date: Mon, 13 Mar 2017 08:38:18 +0000 Subject: Eliminate internal use of TclNewBooleanObj()/TclSetBooleanObj()/TclSetIntObj(). Replace Tcl_DbNewBooleanObj() with trivial macro. --- generic/tcl.h | 2 +- generic/tclAssembly.c | 2 +- generic/tclDecls.h | 4 ++-- generic/tclExecute.c | 4 ++-- generic/tclInt.h | 26 -------------------------- generic/tclObj.c | 12 +++++++----- generic/tclStubInit.c | 2 ++ 7 files changed, 15 insertions(+), 37 deletions(-) diff --git a/generic/tcl.h b/generic/tcl.h index c67eafc..1491745 100644 --- a/generic/tcl.h +++ b/generic/tcl.h @@ -2538,7 +2538,7 @@ EXTERN void Tcl_GetMemoryInfo(Tcl_DString *dsPtr); Tcl_DbNewBignumObj(val, __FILE__, __LINE__) # undef Tcl_NewBooleanObj # define Tcl_NewBooleanObj(val) \ - Tcl_DbNewBooleanObj(val, __FILE__, __LINE__) + Tcl_DbNewLongObj((val)!=0, __FILE__, __LINE__) # undef Tcl_NewByteArrayObj # define Tcl_NewByteArrayObj(bytes, len) \ Tcl_DbNewByteArrayObj(bytes, len, __FILE__, __LINE__) diff --git a/generic/tclAssembly.c b/generic/tclAssembly.c index 2212d1c..8c6f81a 100644 --- a/generic/tclAssembly.c +++ b/generic/tclAssembly.c @@ -4246,7 +4246,7 @@ AddBasicBlockRangeToErrorInfo( Tcl_AppendObjToErrorInfo(interp, lineNo); Tcl_AddErrorInfo(interp, " and "); if (bbPtr->successor1 != NULL) { - Tcl_SetIntObj(lineNo, bbPtr->successor1->startLine); + TclSetLongObj(lineNo, bbPtr->successor1->startLine); Tcl_AppendObjToErrorInfo(interp, lineNo); } else { Tcl_AddErrorInfo(interp, "end of assembly code"); diff --git a/generic/tclDecls.h b/generic/tclDecls.h index 0dbf345..fb7f8bc 100644 --- a/generic/tclDecls.h +++ b/generic/tclDecls.h @@ -3835,13 +3835,13 @@ extern const TclStubs *tclStubsPtr; sizeof(char *), msg, flags, indexPtr) #undef Tcl_NewBooleanObj #define Tcl_NewBooleanObj(boolValue) \ - Tcl_NewIntObj((boolValue)!=0) + Tcl_NewLongObj((boolValue)!=0) #undef Tcl_DbNewBooleanObj #define Tcl_DbNewBooleanObj(boolValue, file, line) \ Tcl_DbNewLongObj((boolValue)!=0, file, line) #undef Tcl_SetBooleanObj #define Tcl_SetBooleanObj(objPtr, boolValue) \ - Tcl_SetIntObj((objPtr), (boolValue)!=0) + Tcl_SetLongObj((objPtr), (boolValue)!=0) #undef Tcl_SetVar #define Tcl_SetVar(interp, varName, newValue, flags) \ Tcl_SetVar2(interp, varName, NULL, newValue, flags) diff --git a/generic/tclExecute.c b/generic/tclExecute.c index c244b08..e3fa730 100644 --- a/generic/tclExecute.c +++ b/generic/tclExecute.c @@ -910,9 +910,9 @@ TclCreateExecEnv( + (size_t) (size-1) * sizeof(Tcl_Obj *)); eePtr->execStackPtr = esPtr; - TclNewBooleanObj(eePtr->constants[0], 0); + TclNewLongObj(eePtr->constants[0], 0); Tcl_IncrRefCount(eePtr->constants[0]); - TclNewBooleanObj(eePtr->constants[1], 1); + TclNewLongObj(eePtr->constants[1], 1); Tcl_IncrRefCount(eePtr->constants[1]); eePtr->interp = interp; eePtr->callbackPtr = NULL; diff --git a/generic/tclInt.h b/generic/tclInt.h index f078d18..9cca14a 100644 --- a/generic/tclInt.h +++ b/generic/tclInt.h @@ -4516,9 +4516,7 @@ MODULE_SCOPE Tcl_PackageInitProc Procbodytest_SafeInit; * core. They should only be called on unshared objects. The ANSI C * "prototypes" for these macros are: * - * MODULE_SCOPE void TclSetIntObj(Tcl_Obj *objPtr, int intValue); * MODULE_SCOPE void TclSetLongObj(Tcl_Obj *objPtr, long longValue); - * MODULE_SCOPE void TclSetBooleanObj(Tcl_Obj *objPtr, long boolValue); * MODULE_SCOPE void TclSetWideIntObj(Tcl_Obj *objPtr, Tcl_WideInt w); * MODULE_SCOPE void TclSetDoubleObj(Tcl_Obj *objPtr, double d); *---------------------------------------------------------------- @@ -4532,19 +4530,6 @@ MODULE_SCOPE Tcl_PackageInitProc Procbodytest_SafeInit; (objPtr)->typePtr = &tclIntType; \ } while (0) -#define TclSetIntObj(objPtr, l) \ - TclSetLongObj(objPtr, l) - -/* - * NOTE: There is to be no such thing as a "pure" boolean. Boolean values set - * programmatically go straight to being "int" Tcl_Obj's, with value 0 or 1. - * The only "boolean" Tcl_Obj's shall be those holding the cached boolean - * value of strings like: "yes", "no", "true", "false", "on", "off". - */ - -#define TclSetBooleanObj(objPtr, b) \ - TclSetLongObj(objPtr, (b)!=0); - #ifndef TCL_WIDE_INT_IS_LONG #define TclSetWideIntObj(objPtr, w) \ do { \ @@ -4570,7 +4555,6 @@ MODULE_SCOPE Tcl_PackageInitProc Procbodytest_SafeInit; * the core. The ANSI C "prototypes" for these macros are: * * MODULE_SCOPE void TclNewLongObj(Tcl_Obj *objPtr, long l); - * MODULE_SCOPE void TclNewBooleanObj(Tcl_Obj *objPtr, int b); * MODULE_SCOPE void TclNewWideObj(Tcl_Obj *objPtr, Tcl_WideInt w); * MODULE_SCOPE void TclNewDoubleObj(Tcl_Obj *objPtr, double d); * MODULE_SCOPE void TclNewStringObj(Tcl_Obj *objPtr, const char *s, int len); @@ -4591,13 +4575,6 @@ MODULE_SCOPE Tcl_PackageInitProc Procbodytest_SafeInit; TCL_DTRACE_OBJ_CREATE(objPtr); \ } while (0) -/* - * NOTE: There is to be no such thing as a "pure" boolean. - * See comment above TclSetBooleanObj macro above. - */ -#define TclNewBooleanObj(objPtr, b) \ - TclNewLongObj((objPtr), (b)!=0) - #define TclNewDoubleObj(objPtr, d) \ do { \ TclIncrObjsAllocated(); \ @@ -4623,9 +4600,6 @@ MODULE_SCOPE Tcl_PackageInitProc Procbodytest_SafeInit; #define TclNewLongObj(objPtr, l) \ (objPtr) = Tcl_NewLongObj(l) -#define TclNewBooleanObj(objPtr, b) \ - (objPtr) = Tcl_NewBooleanObj(b) - #define TclNewDoubleObj(objPtr, d) \ (objPtr) = Tcl_NewDoubleObj(d) diff --git a/generic/tclObj.c b/generic/tclObj.c index 7ec259f..bfef5fb 100644 --- a/generic/tclObj.c +++ b/generic/tclObj.c @@ -1732,7 +1732,7 @@ Tcl_InvalidateStringRep( * is coerced to 1. * * When TCL_MEM_DEBUG is defined, this function just returns the result - * of calling the debugging version Tcl_DbNewBooleanObj. + * of calling the debugging version Tcl_DbNewLongObj. * * Results: * The newly created object is returned. This object will have an invalid @@ -1751,7 +1751,7 @@ Tcl_Obj * Tcl_NewBooleanObj( register int boolValue) /* Boolean used to initialize new object. */ { - return Tcl_DbNewBooleanObj(boolValue, "unknown", 0); + return Tcl_DbNewLongObj(boolValue!=0, "unknown", 0); } #else /* if not TCL_MEM_DEBUG */ @@ -1762,7 +1762,7 @@ Tcl_NewBooleanObj( { register Tcl_Obj *objPtr; - TclNewBooleanObj(objPtr, boolValue); + TclNewLongObj(objPtr, boolValue!=0); return objPtr; } #endif /* TCL_MEM_DEBUG */ @@ -1793,6 +1793,7 @@ Tcl_NewBooleanObj( *---------------------------------------------------------------------- */ +#ifndef TCL_NO_DEPRECATED #undef Tcl_DbNewBooleanObj #ifdef TCL_MEM_DEBUG @@ -1827,6 +1828,7 @@ Tcl_DbNewBooleanObj( return Tcl_NewBooleanObj(boolValue); } #endif /* TCL_MEM_DEBUG */ +#endif /* TCL_NO_DEPRECATED */ /* *---------------------------------------------------------------------- @@ -1856,7 +1858,7 @@ Tcl_SetBooleanObj( Tcl_Panic("%s called with shared object", "Tcl_SetBooleanObj"); } - TclSetBooleanObj(objPtr, boolValue); + TclSetLongObj(objPtr, boolValue!=0); } /* @@ -2458,7 +2460,7 @@ Tcl_SetIntObj( Tcl_Panic("%s called with shared object", "Tcl_SetIntObj"); } - TclSetIntObj(objPtr, intValue); + TclSetLongObj(objPtr, intValue); } /* diff --git a/generic/tclStubInit.c b/generic/tclStubInit.c index 561b9dd..816650e 100644 --- a/generic/tclStubInit.c +++ b/generic/tclStubInit.c @@ -304,6 +304,8 @@ static int formatInt(char *buffer, int n){ # define Tcl_TellOld 0 # undef Tcl_SetResult # define Tcl_SetResult 0 +# undef Tcl_DbNewBooleanObj +# define Tcl_DbNewBooleanObj 0 #else /* TCL_NO_DEPRECATED */ # define Tcl_SeekOld seekOld # define Tcl_TellOld tellOld -- cgit v0.12 From daac4e5d3412030256d30b357bd455dbfa09630f Mon Sep 17 00:00:00 2001 From: dgp Date: Mon, 13 Mar 2017 17:03:50 +0000 Subject: Different solution to silencing the non-useful valgrind alerts. --- generic/tclInt.h | 2 -- generic/tclObj.c | 19 ++++++++++++++++++- 2 files changed, 18 insertions(+), 3 deletions(-) diff --git a/generic/tclInt.h b/generic/tclInt.h index 65ef1c6..4d3c0b1 100644 --- a/generic/tclInt.h +++ b/generic/tclInt.h @@ -4521,7 +4521,6 @@ MODULE_SCOPE Tcl_PackageInitProc Procbodytest_SafeInit; do { \ TclInvalidateStringRep(objPtr); \ TclFreeIntRep(objPtr); \ - (objPtr)->internalRep.twoPtrValue.ptr2 = NULL; \ (objPtr)->internalRep.doubleValue = (double)(d); \ (objPtr)->typePtr = &tclDoubleType; \ } while (0) @@ -4571,7 +4570,6 @@ MODULE_SCOPE Tcl_PackageInitProc Procbodytest_SafeInit; TclAllocObjStorage(objPtr); \ (objPtr)->refCount = 0; \ (objPtr)->bytes = NULL; \ - (objPtr)->internalRep.twoPtrValue.ptr2 = NULL; \ (objPtr)->internalRep.doubleValue = (double)(d); \ (objPtr)->typePtr = &tclDoubleType; \ TCL_DTRACE_OBJ_CREATE(objPtr); \ diff --git a/generic/tclObj.c b/generic/tclObj.c index d549fdc..3bf5b8e 100644 --- a/generic/tclObj.c +++ b/generic/tclObj.c @@ -2203,7 +2203,6 @@ Tcl_DbNewDoubleObj( TclDbNewObj(objPtr, file, line); objPtr->bytes = NULL; - objPtr->internalRep.twoPtrValue.ptr2 = NULL; /* valgrind */ objPtr->internalRep.doubleValue = dblValue; objPtr->typePtr = &tclDoubleType; return objPtr; @@ -4489,6 +4488,24 @@ Tcl_RepresentationCmd( objv[1]->typePtr ? objv[1]->typePtr->name : "pure string", objv[1]->refCount, ptrBuffer); + /* + * This is a workaround to silence reports from `make valgrind` + * on 64-bit systems. The problem is that the test suite + * includes calling the [represenation] command on values of + * &tclDoubleType. When these values are created, the "doubleValue" + * is set, but when the "twoPtrValue" is examined, its "ptr2" + * field has never been initialized. Since [representation] + * presents the value of the ptr2 value in its output, valgrind + * alerts about the read of uninitialized memory. + * + * The general problem with [representation], that it can read + * and report uninitialized fields, is still present. This is + * just the minimal workaround to silence one particular test. + */ + + if ((sizeof(void *) > 4) && objv[1]->typePtr == &tclDoubleType) { + objv[1]->internalRep.twoPtrValue.ptr2 = NULL; + } if (objv[1]->typePtr) { sprintf(ptrBuffer, "%p:%p", (void *) objv[1]->internalRep.twoPtrValue.ptr1, -- cgit v0.12 From 5ddb691286f2aa5d37b524769d0267211527f155 Mon Sep 17 00:00:00 2001 From: Kevin B Kenny Date: Tue, 14 Mar 2017 21:09:27 +0000 Subject: Make 'clock' and 'encoding' into proper compilable ensembles --- generic/tclBasic.c | 10 +- generic/tclClock.c | 18 ++++ generic/tclCmdAH.c | 300 +++++++++++++++++++++++++++++++++++++++++------------ generic/tclInt.h | 5 +- library/init.tcl | 11 +- 5 files changed, 261 insertions(+), 83 deletions(-) diff --git a/generic/tclBasic.c b/generic/tclBasic.c index d6a460d..c14c15b 100644 --- a/generic/tclBasic.c +++ b/generic/tclBasic.c @@ -265,7 +265,6 @@ static const CmdInfo builtInCmds[] = { {"cd", Tcl_CdObjCmd, NULL, NULL, 0}, {"close", Tcl_CloseObjCmd, NULL, NULL, CMD_IS_SAFE}, {"eof", Tcl_EofObjCmd, NULL, NULL, CMD_IS_SAFE}, - {"encoding", Tcl_EncodingObjCmd, NULL, NULL, 0}, {"exec", Tcl_ExecObjCmd, NULL, NULL, 0}, {"exit", Tcl_ExitObjCmd, NULL, NULL, 0}, {"fblocked", Tcl_FblockedObjCmd, NULL, NULL, CMD_IS_SAFE}, @@ -789,16 +788,17 @@ Tcl_CreateInterp(void) } /* - * Create the "array", "binary", "chan", "dict", "file", "info", - * "namespace" and "string" ensembles. Note that all these commands (and - * their subcommands that are not present in the global namespace) are - * wholly safe *except* for "file". + * Create the "array", "binary", "chan", "clock", "dict", "encoding", + * "file", "info", "namespace" and "string" ensembles. Note that all these + * commands (and their subcommands that are not present in the global + * namespace) are wholly safe *except* for "clock", "encoding" and "file". */ TclInitArrayCmd(interp); TclInitBinaryCmd(interp); TclInitChanCmd(interp); TclInitDictCmd(interp); + TclInitEncodingCmd(interp); TclInitFileCmd(interp); TclInitInfoCmd(interp); TclInitNamespaceCmd(interp); diff --git a/generic/tclClock.c b/generic/tclClock.c index c3b29e9..bb9fbeb 100644 --- a/generic/tclClock.c +++ b/generic/tclClock.c @@ -253,6 +253,19 @@ TclClockInit( ClockClientData *data; int i; + /* Structure of the 'clock' ensemble */ + + static const EnsembleImplMap clockImplMap[] = { + {"add", NULL, TclCompileBasicMin1ArgCmd, NULL, NULL, 0}, + {"clicks", NULL, TclCompileBasicMin0ArgCmd, NULL, NULL, 0}, + {"format", NULL, TclCompileBasicMin1ArgCmd, NULL, NULL, 0}, + {"microseconds", NULL, TclCompileBasicMin0ArgCmd, NULL, NULL, 0}, + {"milliseconds", NULL, TclCompileBasicMin0ArgCmd, NULL, NULL, 0}, + {"scan", NULL, TclCompileBasicMin1ArgCmd, NULL, NULL, 0}, + {"seconds", NULL, TclCompileBasicMin0ArgCmd, NULL, NULL, 0}, + {NULL, NULL, NULL, NULL, NULL, 0} + }; + /* * Safe interps get [::clock] as alias to a master, so do not need their * own copies of the support routines. @@ -276,6 +289,7 @@ TclClockInit( /* * Install the commands. + * TODO - Let Tcl_MakeEnsemble do this? */ #define TCL_CLOCK_PREFIX_LEN 14 /* == strlen("::tcl::clock::") */ @@ -286,6 +300,10 @@ TclClockInit( Tcl_CreateObjCommand(interp, cmdName, clockCmdPtr->objCmdProc, data, ClockDeleteCmdProc); } + + /* Make the clock ensemble */ + + TclMakeEnsemble(interp, "clock", clockImplMap); } /* diff --git a/generic/tclCmdAH.c b/generic/tclCmdAH.c index 4c299f8..61de353 100644 --- a/generic/tclCmdAH.c +++ b/generic/tclCmdAH.c @@ -46,9 +46,21 @@ struct ForeachState { static int CheckAccess(Tcl_Interp *interp, Tcl_Obj *pathPtr, int mode); +static int EncodingConvertfromObjCmd(ClientData dummy, + Tcl_Interp *interp, int objc, + Tcl_Obj *const objv[]); +static int EncodingConverttoObjCmd(ClientData dummy, + Tcl_Interp *interp, int objc, + Tcl_Obj *const objv[]); static int EncodingDirsObjCmd(ClientData dummy, Tcl_Interp *interp, int objc, Tcl_Obj *const objv[]); +static int EncodingNamesObjCmd(ClientData dummy, + Tcl_Interp *interp, int objc, + Tcl_Obj *const objv[]); +static int EncodingSystemObjCmd(ClientData dummy, + Tcl_Interp *interp, int objc, + Tcl_Obj *const objv[]); static inline int ForeachAssignments(Tcl_Interp *interp, struct ForeachState *statePtr); static inline void ForeachCleanup(Tcl_Interp *interp, @@ -541,79 +553,173 @@ Tcl_EncodingObjCmd( switch ((enum options) index) { case ENC_CONVERTTO: - case ENC_CONVERTFROM: { - Tcl_Obj *data; - Tcl_DString ds; - Tcl_Encoding encoding; - int length; - const char *stringPtr; - - if (objc == 3) { - encoding = Tcl_GetEncoding(interp, NULL); - data = objv[2]; - } else if (objc == 4) { - if (Tcl_GetEncodingFromObj(interp, objv[2], &encoding) != TCL_OK) { - return TCL_ERROR; - } - data = objv[3]; - } else { - Tcl_WrongNumArgs(interp, 2, objv, "?encoding? data"); + return EncodingConverttoObjCmd(dummy, interp, objc, objv); + case ENC_CONVERTFROM: + return EncodingConvertfromObjCmd(dummy, interp, objc, objv); + case ENC_DIRS: + return EncodingDirsObjCmd(dummy, interp, objc, objv); + case ENC_NAMES: + return EncodingNamesObjCmd(dummy, interp, objc, objv); + case ENC_SYSTEM: + return EncodingSystemObjCmd(dummy, interp, objc, objv); + } + return TCL_OK; +} + +/* + *----------------------------------------------------------------------------- + * + * TclInitEncodingCmd -- + * + * This function creates the 'encoding' ensemble. + * + * Results: + * Returns the Tcl_Command so created. + * + * Side effects: + * The ensemble is initialized. + * + * This command is not installed in a safe interpreter. + */ + +Tcl_Command +TclInitEncodingCmd( + Tcl_Interp* interp) /* Tcl interpreter */ +{ + static const EnsembleImplMap encodingImplMap[] = { + {"convertfrom", EncodingConvertfromObjCmd, TclCompileBasic1Or2ArgCmd, NULL, NULL, 0}, + {"convertto", EncodingConverttoObjCmd, TclCompileBasic1Or2ArgCmd, NULL, NULL, 0}, + {"dirs", EncodingDirsObjCmd, TclCompileBasic0Or1ArgCmd, NULL, NULL, 0}, + {"names", EncodingNamesObjCmd, TclCompileBasic0ArgCmd, NULL, NULL, 0}, + {"system", EncodingSystemObjCmd, TclCompileBasic0Or1ArgCmd, NULL, NULL, 0}, + {NULL, NULL, NULL, NULL, NULL, 0} + }; + + return TclMakeEnsemble(interp, "encoding", encodingImplMap); +} + +/* + *---------------------------------------------------------------------- + * + * EncodingConvertfromObjCmd -- + * + * This command converts a byte array in an external encoding into a + * Tcl string + * + * Results: + * A standard Tcl result. + * + *---------------------------------------------------------------------- + */ + +int +EncodingConvertfromObjCmd( + ClientData dummy, /* Not used. */ + Tcl_Interp *interp, /* Current interpreter. */ + int objc, /* Number of arguments. */ + Tcl_Obj *const objv[]) /* Argument objects. */ +{ + Tcl_Obj *data; /* Byte array to convert */ + Tcl_DString ds; /* Buffer to hold the string */ + Tcl_Encoding encoding; /* Encoding to use */ + int length; /* Length of the byte array being converted */ + const char *bytesPtr; /* Pointer to the first byte of the array */ + + if (objc == 2) { + encoding = Tcl_GetEncoding(interp, NULL); + data = objv[1]; + } else if (objc == 3) { + if (Tcl_GetEncodingFromObj(interp, objv[1], &encoding) != TCL_OK) { return TCL_ERROR; } + data = objv[2]; + } else { + Tcl_WrongNumArgs(interp, 1, objv, "?encoding? data"); + return TCL_ERROR; + } - if ((enum options) index == ENC_CONVERTFROM) { - /* - * Treat the string as binary data. - */ + /* + * Convert the string into a byte array in 'ds' + */ + bytesPtr = (char *) Tcl_GetByteArrayFromObj(data, &length); + Tcl_ExternalToUtfDString(encoding, bytesPtr, length, &ds); - stringPtr = (char *) Tcl_GetByteArrayFromObj(data, &length); - Tcl_ExternalToUtfDString(encoding, stringPtr, length, &ds); + /* + * Note that we cannot use Tcl_DStringResult here because it will + * truncate the string at the first null byte. + */ - /* - * Note that we cannot use Tcl_DStringResult here because it will - * truncate the string at the first null byte. - */ + Tcl_SetObjResult(interp, TclDStringToObj(&ds)); - Tcl_SetObjResult(interp, TclDStringToObj(&ds)); - } else { - /* - * Store the result as binary data. - */ - - stringPtr = TclGetStringFromObj(data, &length); - Tcl_UtfToExternalDString(encoding, stringPtr, length, &ds); - Tcl_SetObjResult(interp, Tcl_NewByteArrayObj( - (unsigned char *) Tcl_DStringValue(&ds), - Tcl_DStringLength(&ds))); - Tcl_DStringFree(&ds); - } + /* + * We're done with the encoding + */ - Tcl_FreeEncoding(encoding); - break; - } - case ENC_DIRS: - return EncodingDirsObjCmd(dummy, interp, objc, objv); - case ENC_NAMES: - if (objc > 2) { - Tcl_WrongNumArgs(interp, 2, objv, NULL); - return TCL_ERROR; - } - Tcl_GetEncodingNames(interp); - break; - case ENC_SYSTEM: - if (objc > 3) { - Tcl_WrongNumArgs(interp, 2, objv, "?encoding?"); + Tcl_FreeEncoding(encoding); + return TCL_OK; + +} + +/* + *---------------------------------------------------------------------- + * + * EncodingConverttoObjCmd -- + * + * This command converts a Tcl string into a byte array that + * encodes the string according to some encoding. + * + * Results: + * A standard Tcl result. + * + *---------------------------------------------------------------------- + */ + +int +EncodingConverttoObjCmd( + ClientData dummy, /* Not used. */ + Tcl_Interp *interp, /* Current interpreter. */ + int objc, /* Number of arguments. */ + Tcl_Obj *const objv[]) /* Argument objects. */ +{ + Tcl_Obj *data; /* String to convert */ + Tcl_DString ds; /* Buffer to hold the byte array */ + Tcl_Encoding encoding; /* Encoding to use */ + int length; /* Length of the string being converted */ + const char *stringPtr; /* Pointer to the first byte of the string */ + + /* TODO - ADJUST OBJ INDICES WHEN ENSEMBLIFYING THIS */ + + if (objc == 2) { + encoding = Tcl_GetEncoding(interp, NULL); + data = objv[1]; + } else if (objc == 3) { + if (Tcl_GetEncodingFromObj(interp, objv[1], &encoding) != TCL_OK) { return TCL_ERROR; } - if (objc == 2) { - Tcl_SetObjResult(interp, Tcl_NewStringObj( - Tcl_GetEncodingName(NULL), -1)); - } else { - return Tcl_SetSystemEncoding(interp, TclGetString(objv[2])); - } - break; + data = objv[2]; + } else { + Tcl_WrongNumArgs(interp, 1, objv, "?encoding? data"); + return TCL_ERROR; } + + /* + * Convert the string to a byte array in 'ds' + */ + + stringPtr = TclGetStringFromObj(data, &length); + Tcl_UtfToExternalDString(encoding, stringPtr, length, &ds); + Tcl_SetObjResult(interp, + Tcl_NewByteArrayObj((unsigned char*) Tcl_DStringValue(&ds), + Tcl_DStringLength(&ds))); + Tcl_DStringFree(&ds); + + /* + * We're done with the encoding + */ + + Tcl_FreeEncoding(encoding); return TCL_OK; + } /* @@ -641,16 +747,16 @@ EncodingDirsObjCmd( { Tcl_Obj *dirListObj; - if (objc > 3) { - Tcl_WrongNumArgs(interp, 2, objv, "?dirList?"); + if (objc > 2) { + Tcl_WrongNumArgs(interp, 1, objv, "?dirList?"); return TCL_ERROR; } - if (objc == 2) { + if (objc == 1) { Tcl_SetObjResult(interp, Tcl_GetEncodingSearchPath()); return TCL_OK; } - dirListObj = objv[2]; + dirListObj = objv[1]; if (Tcl_SetEncodingSearchPath(dirListObj) == TCL_ERROR) { Tcl_SetObjResult(interp, Tcl_ObjPrintf( "expected directory list but got \"%s\"", @@ -664,6 +770,68 @@ EncodingDirsObjCmd( } /* + *----------------------------------------------------------------------------- + * + * EncodingNamesObjCmd -- + * + * This command returns a list of the available encoding names + * + * Results: + * Returns a standard Tcl result + * + *----------------------------------------------------------------------------- + */ + +int +EncodingNamesObjCmd(ClientData dummy, /* Unused */ + Tcl_Interp* interp, /* Tcl interpreter */ + int objc, /* Number of command line args */ + Tcl_Obj* const objv[]) /* Vector of command line args */ +{ + if (objc > 1) { + Tcl_WrongNumArgs(interp, 1, objv, NULL); + return TCL_ERROR; + } + Tcl_GetEncodingNames(interp); + return TCL_OK; +} + +/* + *----------------------------------------------------------------------------- + * + * EncodingSystemObjCmd -- + * + * This command retrieves or changes the system encoding + * + * Results: + * Returns a standard Tcl result + * + * Side effects: + * May change the system encoding. + * + *----------------------------------------------------------------------------- + */ + +int +EncodingSystemObjCmd(ClientData dummy, /* Unused */ + Tcl_Interp* interp, /* Tcl interpreter */ + int objc, /* Number of command line args */ + Tcl_Obj* const objv[]) /* Vector of command line args */ +{ + if (objc > 2) { + Tcl_WrongNumArgs(interp, 1, objv, "?encoding?"); + return TCL_ERROR; + } + if (objc == 1) { + Tcl_SetObjResult(interp, + Tcl_NewStringObj(Tcl_GetEncodingName(NULL), -1)); + } else { + return Tcl_SetSystemEncoding(interp, TclGetString(objv[1])); + } + return TCL_OK; +} + +/* *---------------------------------------------------------------------- * * Tcl_ErrorObjCmd -- diff --git a/generic/tclInt.h b/generic/tclInt.h index 4d3c0b1..6aa292c 100644 --- a/generic/tclInt.h +++ b/generic/tclInt.h @@ -3239,10 +3239,7 @@ MODULE_SCOPE int Tcl_AssembleObjCmd(ClientData clientData, MODULE_SCOPE int TclNRAssembleObjCmd(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *const objv[]); - -MODULE_SCOPE int Tcl_EncodingObjCmd(ClientData clientData, - Tcl_Interp *interp, int objc, - Tcl_Obj *const objv[]); +MODULE_SCOPE Tcl_Command TclInitEncodingCmd(Tcl_Interp *interp); MODULE_SCOPE int Tcl_EofObjCmd(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *const objv[]); diff --git a/library/init.tcl b/library/init.tcl index 9ca4514..a202054 100644 --- a/library/init.tcl +++ b/library/init.tcl @@ -169,13 +169,7 @@ if {[interp issafe]} { namespace eval ::tcl::clock [list variable TclLibDir $::tcl_library] - proc clock args { - namespace eval ::tcl::clock [list namespace ensemble create -command \ - [uplevel 1 [list namespace origin [lindex [info level 0] 0]]] \ - -subcommands { - add clicks format microseconds milliseconds scan seconds - }] - + proc ::tcl::initClock {} { # Auto-loading stubs for 'clock.tcl' foreach cmd {add format scan} { @@ -186,8 +180,9 @@ if {[interp issafe]} { } } - return [uplevel 1 [info level 0]] + rename ::tcl::initClock {} } + ::tcl::initClock } # Conditionalize for presence of exec. -- cgit v0.12 From 6212b342f6712c047d9e997ad21f767af934983d Mon Sep 17 00:00:00 2001 From: Kevin B Kenny Date: Tue, 14 Mar 2017 22:06:43 +0000 Subject: Make 'clock' and 'encoding' into compilable ensembles that play with safe interps --- generic/tclBasic.c | 1 + generic/tclCmdAH.c | 112 ++++++++++++++++++++++++++++++++++++++++++++++++++++- generic/tclInt.h | 1 + tests/cmdAH.test | 4 +- tests/interp.test | 2 +- 5 files changed, 116 insertions(+), 4 deletions(-) diff --git a/generic/tclBasic.c b/generic/tclBasic.c index c14c15b..4bddbce 100644 --- a/generic/tclBasic.c +++ b/generic/tclBasic.c @@ -1026,6 +1026,7 @@ TclHideUnsafeCommands( Tcl_HideCommand(interp, cmdInfoPtr->name, cmdInfoPtr->name); } } + TclMakeEncodingCommandSafe(interp); /* Ugh! */ TclMakeFileCommandSafe(interp); /* Ugh! */ return TCL_OK; } diff --git a/generic/tclCmdAH.c b/generic/tclCmdAH.c index 61de353..6d66a32 100644 --- a/generic/tclCmdAH.c +++ b/generic/tclCmdAH.c @@ -46,6 +46,9 @@ struct ForeachState { static int CheckAccess(Tcl_Interp *interp, Tcl_Obj *pathPtr, int mode); +static int BadEncodingSubcommand(ClientData dummy, + Tcl_Interp *interp, int objc, + Tcl_Obj *const objv[]); static int EncodingConvertfromObjCmd(ClientData dummy, Tcl_Interp *interp, int objc, Tcl_Obj *const objv[]); @@ -579,7 +582,7 @@ Tcl_EncodingObjCmd( * Side effects: * The ensemble is initialized. * - * This command is not installed in a safe interpreter. + * This command is hidden in a safe interpreter. */ Tcl_Command @@ -599,6 +602,113 @@ TclInitEncodingCmd( } /* + *----------------------------------------------------------------------------- + * + * TclMakeEncodingCommandSafe -- + * + * This function hides the unsafe 'dirs' and 'system' subcommands of + * the "encoding" Tcl command ensemble. It must be called only from + * TclHideUnsafeCommands. + * + * Results: + * A standard Tcl result + * + * Side effects: + * Adds commands to the table of hidden commands. + * + *----------------------------------------------------------------------------- + */ + +int +TclMakeEncodingCommandSafe( + Tcl_Interp* interp) /* Tcl interpreter */ +{ + static const struct { + const char *cmdName; + int unsafe; + } unsafeInfo[] = { + {"convertfrom", 0}, + {"convertto", 0}, + {"dirs", 1}, + {"names", 0}, + {"system", 0}, + {NULL, 0} + }; + + int i; + Tcl_DString oldBuf, newBuf; + + Tcl_DStringInit(&oldBuf); + TclDStringAppendLiteral(&oldBuf, "::tcl::encoding::"); + Tcl_DStringInit(&newBuf); + TclDStringAppendLiteral(&newBuf, "tcl:encoding:"); + for (i=0 ; unsafeInfo[i].cmdName != NULL ; i++) { + if (unsafeInfo[i].unsafe) { + const char *oldName, *newName; + + Tcl_DStringSetLength(&oldBuf, 17); + oldName = Tcl_DStringAppend(&oldBuf, unsafeInfo[i].cmdName, -1); + Tcl_DStringSetLength(&newBuf, 13); + newName = Tcl_DStringAppend(&newBuf, unsafeInfo[i].cmdName, -1); + if (TclRenameCommand(interp, oldName, "___tmp") != TCL_OK + || Tcl_HideCommand(interp, "___tmp", newName) != TCL_OK) { + Tcl_Panic("problem making 'encoding %s' safe: %s", + unsafeInfo[i].cmdName, + Tcl_GetString(Tcl_GetObjResult(interp))); + } + Tcl_CreateObjCommand(interp, oldName, BadEncodingSubcommand, + (ClientData) unsafeInfo[i].cmdName, NULL); + } + } + Tcl_DStringFree(&oldBuf); + Tcl_DStringFree(&newBuf); + + /* + * Ugh. The [encoding] command is now actually safe, but it is assumed by + * scripts that it is not, which messes up security policies. + */ + + if (Tcl_HideCommand(interp, "encoding", "encoding") != TCL_OK) { + Tcl_Panic("problem making 'encoding' safe: %s", + Tcl_GetString(Tcl_GetObjResult(interp))); + } + return TCL_OK; +} + +/* + *---------------------------------------------------------------------- + * + * BadEncodingSubcommand -- + * + * Command used to act as a backstop implementation when subcommands of + * "encoding" are unsafe (the real implementations of the subcommands are + * hidden). The clientData is always the full official subcommand name. + * + * Results: + * A standard Tcl result (always a TCL_ERROR). + * + * Side effects: + * None. + * + *---------------------------------------------------------------------- + */ + +static int +BadEncodingSubcommand( + ClientData clientData, + Tcl_Interp *interp, + int objc, + Tcl_Obj *const objv[]) +{ + const char *subcommandName = (const char *) clientData; + + Tcl_SetObjResult(interp, Tcl_ObjPrintf( + "not allowed to invoke subcommand %s of encoding", subcommandName)); + Tcl_SetErrorCode(interp, "TCL", "SAFE", "SUBCOMMAND", NULL); + return TCL_ERROR; +} + +/* *---------------------------------------------------------------------- * * EncodingConvertfromObjCmd -- diff --git a/generic/tclInt.h b/generic/tclInt.h index 6aa292c..3749735 100644 --- a/generic/tclInt.h +++ b/generic/tclInt.h @@ -3240,6 +3240,7 @@ MODULE_SCOPE int TclNRAssembleObjCmd(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *const objv[]); MODULE_SCOPE Tcl_Command TclInitEncodingCmd(Tcl_Interp *interp); +MODULE_SCOPE int TclMakeEncodingCommandSafe(Tcl_Interp *interp); MODULE_SCOPE int Tcl_EofObjCmd(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *const objv[]); diff --git a/tests/cmdAH.test b/tests/cmdAH.test index b4ef605..3c58c1b 100644 --- a/tests/cmdAH.test +++ b/tests/cmdAH.test @@ -167,10 +167,10 @@ test cmdAH-3.2 {Tcl_ContinueObjCmd, success} { test cmdAH-4.1 {Tcl_EncodingObjCmd} -returnCodes error -body { encoding -} -result {wrong # args: should be "encoding option ?arg ...?"} +} -result {wrong # args: should be "encoding subcommand ?arg ...?"} test cmdAH-4.2 {Tcl_EncodingObjCmd} -returnCodes error -body { encoding foo -} -result {bad option "foo": must be convertfrom, convertto, dirs, names, or system} +} -result {unknown or ambiguous subcommand "foo": must be convertfrom, convertto, dirs, names, or system} test cmdAH-4.3 {Tcl_EncodingObjCmd} -returnCodes error -body { encoding convertto } -result {wrong # args: should be "encoding convertto ?encoding? data"} diff --git a/tests/interp.test b/tests/interp.test index 6000ffd..4d61e35 100644 --- a/tests/interp.test +++ b/tests/interp.test @@ -20,7 +20,7 @@ catch [list package require -exact Tcltest [info patchlevel]] testConstraint testinterpdelete [llength [info commands testinterpdelete]] -set hidden_cmds {cd encoding exec exit fconfigure file glob load open pwd socket source tcl:file:atime tcl:file:attributes tcl:file:copy tcl:file:delete tcl:file:dirname tcl:file:executable tcl:file:exists tcl:file:extension tcl:file:isdirectory tcl:file:isfile tcl:file:link tcl:file:lstat tcl:file:mkdir tcl:file:mtime tcl:file:nativename tcl:file:normalize tcl:file:owned tcl:file:readable tcl:file:readlink tcl:file:rename tcl:file:rootname tcl:file:size tcl:file:stat tcl:file:tail tcl:file:tempfile tcl:file:type tcl:file:volumes tcl:file:writable unload} +set hidden_cmds {cd encoding exec exit fconfigure file glob load open pwd socket source tcl:encoding:dirs tcl:file:atime tcl:file:attributes tcl:file:copy tcl:file:delete tcl:file:dirname tcl:file:executable tcl:file:exists tcl:file:extension tcl:file:isdirectory tcl:file:isfile tcl:file:link tcl:file:lstat tcl:file:mkdir tcl:file:mtime tcl:file:nativename tcl:file:normalize tcl:file:owned tcl:file:readable tcl:file:readlink tcl:file:rename tcl:file:rootname tcl:file:size tcl:file:stat tcl:file:tail tcl:file:tempfile tcl:file:type tcl:file:volumes tcl:file:writable unload} foreach i [interp slaves] { interp delete $i -- cgit v0.12 From 43d597b30f23c04837758d424f4baa7478b7202a Mon Sep 17 00:00:00 2001 From: Kevin B Kenny Date: Wed, 15 Mar 2017 02:39:04 +0000 Subject: Compile [clock clicks], [clock microseconds], [clock milliseconds] and [clock seconds]. --- generic/tclAssembly.c | 20 +++++++++++ generic/tclClock.c | 20 +++++------ generic/tclCompCmds.c | 99 +++++++++++++++++++++++++++++++++++++++++++++++++++ generic/tclCompile.c | 5 +++ generic/tclCompile.h | 4 ++- generic/tclExecute.c | 33 +++++++++++++++++ generic/tclInt.h | 6 ++++ 7 files changed, 174 insertions(+), 13 deletions(-) diff --git a/generic/tclAssembly.c b/generic/tclAssembly.c index f56da8f..120fd9a 100644 --- a/generic/tclAssembly.c +++ b/generic/tclAssembly.c @@ -137,6 +137,8 @@ typedef enum TalInstType { * ranges */ ASSEM_BOOL, /* One Boolean operand */ ASSEM_BOOL_LVT4, /* One Boolean, one 4-byte LVT ref. */ + ASSEM_CLOCK_READ, /* 1-byte unsigned-integer case number, in the + * range 0-3 */ ASSEM_CONCAT1, /* 1-byte unsigned-integer operand count, must * be strictly positive, consumes N, produces * 1 */ @@ -350,6 +352,7 @@ static const TalInstDesc TalInstructionTable[] = { {"bitnot", ASSEM_1BYTE, INST_BITNOT, 1, 1}, {"bitor", ASSEM_1BYTE, INST_BITOR, 2, 1}, {"bitxor", ASSEM_1BYTE, INST_BITXOR, 2, 1}, + {"clockRead", ASSEM_CLOCK_READ, INST_CLOCK_READ, 0, 1}, {"concat", ASSEM_CONCAT1, INST_STR_CONCAT1, INT_MIN,1}, {"concatStk", ASSEM_LIST, INST_CONCAT_STK, INT_MIN,1}, {"coroName", ASSEM_1BYTE, INST_COROUTINE_NAME, 0, 1}, @@ -1363,6 +1366,23 @@ AssembleOneLine( TclEmitInt4(localVar, envPtr); break; + case ASSEM_CLOCK_READ: + if (parsePtr->numWords != 2) { + Tcl_WrongNumArgs(interp, 1, &instNameObj, "imm8"); + goto cleanup; + } + if (GetIntegerOperand(assemEnvPtr, &tokenPtr, &opnd) != TCL_OK) { + goto cleanup; + } + if (opnd < 0 || opnd > 3) { + Tcl_SetObjResult(interp, + Tcl_NewStringObj("operand must be [0..3]", -1)); + Tcl_SetErrorCode(interp, "TCL", "ASSEM", "OPERAND<0,>3", NULL); + goto cleanup; + } + BBEmitInstInt1(assemEnvPtr, tblIdx, opnd, opnd); + break; + case ASSEM_CONCAT1: if (parsePtr->numWords != 2) { Tcl_WrongNumArgs(interp, 1, &instNameObj, "imm8"); diff --git a/generic/tclClock.c b/generic/tclClock.c index bb9fbeb..02b2845 100644 --- a/generic/tclClock.c +++ b/generic/tclClock.c @@ -208,11 +208,7 @@ struct ClockCommand { }; static const struct ClockCommand clockCommands[] = { - { "clicks", ClockClicksObjCmd }, { "getenv", ClockGetenvObjCmd }, - { "microseconds", ClockMicrosecondsObjCmd }, - { "milliseconds", ClockMillisecondsObjCmd }, - { "seconds", ClockSecondsObjCmd }, { "Oldscan", TclClockOldscanObjCmd }, { "ConvertLocalToUTC", ClockConvertlocaltoutcObjCmd }, { "GetDateFields", ClockGetdatefieldsObjCmd }, @@ -256,14 +252,14 @@ TclClockInit( /* Structure of the 'clock' ensemble */ static const EnsembleImplMap clockImplMap[] = { - {"add", NULL, TclCompileBasicMin1ArgCmd, NULL, NULL, 0}, - {"clicks", NULL, TclCompileBasicMin0ArgCmd, NULL, NULL, 0}, - {"format", NULL, TclCompileBasicMin1ArgCmd, NULL, NULL, 0}, - {"microseconds", NULL, TclCompileBasicMin0ArgCmd, NULL, NULL, 0}, - {"milliseconds", NULL, TclCompileBasicMin0ArgCmd, NULL, NULL, 0}, - {"scan", NULL, TclCompileBasicMin1ArgCmd, NULL, NULL, 0}, - {"seconds", NULL, TclCompileBasicMin0ArgCmd, NULL, NULL, 0}, - {NULL, NULL, NULL, NULL, NULL, 0} + {"add", NULL, TclCompileBasicMin1ArgCmd, NULL, NULL, 0}, + {"clicks", ClockClicksObjCmd, TclCompileClockClicksCmd, NULL, NULL, 0}, + {"format", NULL, TclCompileBasicMin1ArgCmd, NULL, NULL, 0}, + {"microseconds", ClockMicrosecondsObjCmd, TclCompileClockReadingCmd, NULL, INT2PTR(1), 0}, + {"milliseconds", ClockMillisecondsObjCmd, TclCompileClockReadingCmd, NULL, INT2PTR(2), 0}, + {"scan", NULL, TclCompileBasicMin1ArgCmd, NULL, NULL , 0}, + {"seconds", ClockSecondsObjCmd, TclCompileClockReadingCmd, NULL, INT2PTR(3), 0}, + {NULL, NULL, NULL, NULL, NULL, 0} }; /* diff --git a/generic/tclCompCmds.c b/generic/tclCompCmds.c index 7dba232..635447c 100644 --- a/generic/tclCompCmds.c +++ b/generic/tclCompCmds.c @@ -734,6 +734,105 @@ TclCompileCatchCmd( return TCL_OK; } +/*---------------------------------------------------------------------- + * + * TclCompileClockClicksCmd -- + * + * Procedure called to compile the "tcl::clock::clicks" command. + * + * Results: + * Returns TCL_OK for a successful compile. Returns TCL_ERROR to defer + * evaluation to run time. + * + * Side effects: + * Instructions are added to envPtr to execute the "clock clicks" + * command at runtime. + * + *---------------------------------------------------------------------- + */ + +int +TclCompileClockClicksCmd( + Tcl_Interp* interp, /* Tcl interpreter */ + Tcl_Parse *parsePtr, /* Points to a parse structure for the command + * created by Tcl_ParseCommand. */ + Command *cmdPtr, /* Points to defintion of command being + * compiled. */ + CompileEnv *envPtr) /* Holds resulting instructions. */ +{ + Tcl_Token* tokenPtr; + + switch (parsePtr->numWords) { + case 1: + /* + * No args + */ + TclEmitInstInt1(INST_CLOCK_READ, 0, envPtr); + break; + case 2: + /* + * -milliseconds or -microseconds + */ + tokenPtr = TokenAfter(parsePtr->tokenPtr); + if (tokenPtr->type != TCL_TOKEN_SIMPLE_WORD + || tokenPtr[1].size < 4 + || tokenPtr[1].size > 13) { + return TCL_ERROR; + } else if (!strncmp(tokenPtr[1].start, "-microseconds", + tokenPtr[1].size)) { + TclEmitInstInt1(INST_CLOCK_READ, 1, envPtr); + break; + } else if (!strncmp(tokenPtr[1].start, "-milliseconds", + tokenPtr[1].size)) { + TclEmitInstInt1(INST_CLOCK_READ, 2, envPtr); + break; + } else { + return TCL_ERROR; + } + default: + return TCL_ERROR; + } + return TCL_OK; +} + + +/*---------------------------------------------------------------------- + * + * TclCompileClockReadingCmd -- + * + * Procedure called to compile the "tcl::clock::microseconds", + * "tcl::clock::milliseconds" and "tcl::clock::seconds" commands. + * + * Results: + * Returns TCL_OK for a successful compile. Returns TCL_ERROR to defer + * evaluation to run time. + * + * Side effects: + * Instructions are added to envPtr to execute the "clock clicks" + * command at runtime. + * + * Client data is 1 for microseconds, 2 for milliseconds, 3 for seconds. + *---------------------------------------------------------------------- + */ + +int +TclCompileClockReadingCmd( + Tcl_Interp* interp, /* Tcl interpreter */ + Tcl_Parse *parsePtr, /* Points to a parse structure for the command + * created by Tcl_ParseCommand. */ + Command *cmdPtr, /* Points to defintion of command being + * compiled. */ + CompileEnv *envPtr) /* Holds resulting instructions. */ +{ + if (parsePtr->numWords != 1) { + return TCL_ERROR; + } + + TclEmitInstInt1(INST_CLOCK_READ, PTR2INT(cmdPtr->objClientData), envPtr); + + return TCL_OK; +} + /* *---------------------------------------------------------------------- * diff --git a/generic/tclCompile.c b/generic/tclCompile.c index f6b3c52..f716195 100644 --- a/generic/tclCompile.c +++ b/generic/tclCompile.c @@ -654,6 +654,11 @@ InstructionDesc const tclInstructionTable[] = { /* Lappend list to general variable. * Stack: ... varName list => ... listVarContents */ + {"clockRead", 2, +1, 1, {OPERAND_UINT1}}, + /* Read clock out to the stack. Operand is which clock to read + * 0=clicks, 1=microseconds, 2=milliseconds, 3=seconds. + * Stack: ... => ... time */ + {NULL, 0, 0, 0, {OPERAND_NONE}} }; diff --git a/generic/tclCompile.h b/generic/tclCompile.h index ba6ad44..e5d026c 100644 --- a/generic/tclCompile.h +++ b/generic/tclCompile.h @@ -821,8 +821,10 @@ typedef struct ByteCode { #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 188 +#define LAST_INST_OPCODE 189 /* * Table describing the Tcl bytecode instructions: their name (for displaying diff --git a/generic/tclExecute.c b/generic/tclExecute.c index 1d3a825..4250958 100644 --- a/generic/tclExecute.c +++ b/generic/tclExecute.c @@ -7840,6 +7840,39 @@ TEBCresume( * ----------------------------------------------------------------- */ + case INST_CLOCK_READ: + { /* Read the wall clock */ + Tcl_WideInt wval; + Tcl_Time now; + switch(TclGetUInt1AtPtr(pc+1)) { + case 0: /* clicks */ +#ifdef TCL_WIDE_CLICKS + wval = TclpGetWideClicks(); +#else + wval = (Tcl_WideInt) TclpGetClicks(); +#endif + break; + case 1: /* microseconds */ + Tcl_GetTime(&now); + wval = (Tcl_WideInt) now.sec * 1000000 + now.usec; + break; + case 2: /* milliseconds */ + Tcl_GetTime(&now); + wval = (Tcl_WideInt) now.sec * 1000 + now.usec / 1000; + break; + case 3: /* seconds */ + Tcl_GetTime(&now); + wval = (Tcl_WideInt) now.sec; + break; + default: + Tcl_Panic("clockRead instruction with unknown clock#"); + } + /* TclNewWideObj(objResultPtr, wval); doesn't exist */ + objResultPtr = Tcl_NewWideIntObj(wval); + TRACE_WITH_OBJ(("=> "), objResultPtr); + NEXT_INST_F(2, 0, 1); + } + default: Tcl_Panic("TclNRExecuteByteCode: unrecognized opCode %u", *pc); } /* end of switch on opCode */ diff --git a/generic/tclInt.h b/generic/tclInt.h index 3749735..1deda3c 100644 --- a/generic/tclInt.h +++ b/generic/tclInt.h @@ -3478,6 +3478,12 @@ MODULE_SCOPE int TclCompileBreakCmd(Tcl_Interp *interp, MODULE_SCOPE int TclCompileCatchCmd(Tcl_Interp *interp, Tcl_Parse *parsePtr, Command *cmdPtr, struct CompileEnv *envPtr); +MODULE_SCOPE int TclCompileClockClicksCmd(Tcl_Interp *interp, + Tcl_Parse *parsePtr, Command *cmdPtr, + struct CompileEnv *envPtr); +MODULE_SCOPE int TclCompileClockReadingCmd(Tcl_Interp *interp, + Tcl_Parse *parsePtr, Command *cmdPtr, + struct CompileEnv *envPtr); MODULE_SCOPE int TclCompileConcatCmd(Tcl_Interp *interp, Tcl_Parse *parsePtr, Command *cmdPtr, struct CompileEnv *envPtr); -- cgit v0.12 From d287c6c8b0efb0e056f86257161620015ae9e6a2 Mon Sep 17 00:00:00 2001 From: "jan.nijtmans" Date: Wed, 15 Mar 2017 15:13:43 +0000 Subject: redundant end-of-line spacing --- generic/tclCmdAH.c | 14 +++++++------- generic/tclCompCmds.c | 4 ++-- generic/tclExecute.c | 2 +- generic/tclTomMath.h | 12 ++++++------ 4 files changed, 16 insertions(+), 16 deletions(-) diff --git a/generic/tclCmdAH.c b/generic/tclCmdAH.c index 6d66a32..a48dfc7 100644 --- a/generic/tclCmdAH.c +++ b/generic/tclCmdAH.c @@ -748,8 +748,8 @@ EncodingConvertfromObjCmd( return TCL_ERROR; } - /* - * Convert the string into a byte array in 'ds' + /* + * Convert the string into a byte array in 'ds' */ bytesPtr = (char *) Tcl_GetByteArrayFromObj(data, &length); Tcl_ExternalToUtfDString(encoding, bytesPtr, length, &ds); @@ -811,18 +811,18 @@ EncodingConverttoObjCmd( Tcl_WrongNumArgs(interp, 1, objv, "?encoding? data"); return TCL_ERROR; } - + /* * Convert the string to a byte array in 'ds' */ - + stringPtr = TclGetStringFromObj(data, &length); Tcl_UtfToExternalDString(encoding, stringPtr, length, &ds); - Tcl_SetObjResult(interp, + Tcl_SetObjResult(interp, Tcl_NewByteArrayObj((unsigned char*) Tcl_DStringValue(&ds), Tcl_DStringLength(&ds))); Tcl_DStringFree(&ds); - + /* * We're done with the encoding */ @@ -933,7 +933,7 @@ EncodingSystemObjCmd(ClientData dummy, /* Unused */ return TCL_ERROR; } if (objc == 1) { - Tcl_SetObjResult(interp, + Tcl_SetObjResult(interp, Tcl_NewStringObj(Tcl_GetEncodingName(NULL), -1)); } else { return Tcl_SetSystemEncoding(interp, TclGetString(objv[1])); diff --git a/generic/tclCompCmds.c b/generic/tclCompCmds.c index 635447c..c2b4bdb 100644 --- a/generic/tclCompCmds.c +++ b/generic/tclCompCmds.c @@ -778,11 +778,11 @@ TclCompileClockClicksCmd( || tokenPtr[1].size < 4 || tokenPtr[1].size > 13) { return TCL_ERROR; - } else if (!strncmp(tokenPtr[1].start, "-microseconds", + } else if (!strncmp(tokenPtr[1].start, "-microseconds", tokenPtr[1].size)) { TclEmitInstInt1(INST_CLOCK_READ, 1, envPtr); break; - } else if (!strncmp(tokenPtr[1].start, "-milliseconds", + } else if (!strncmp(tokenPtr[1].start, "-milliseconds", tokenPtr[1].size)) { TclEmitInstInt1(INST_CLOCK_READ, 2, envPtr); break; diff --git a/generic/tclExecute.c b/generic/tclExecute.c index 4250958..cb4e6dc 100644 --- a/generic/tclExecute.c +++ b/generic/tclExecute.c @@ -7845,7 +7845,7 @@ TEBCresume( Tcl_WideInt wval; Tcl_Time now; switch(TclGetUInt1AtPtr(pc+1)) { - case 0: /* clicks */ + case 0: /* clicks */ #ifdef TCL_WIDE_CLICKS wval = TclpGetWideClicks(); #else diff --git a/generic/tclTomMath.h b/generic/tclTomMath.h index c1d83c4..41512f0 100644 --- a/generic/tclTomMath.h +++ b/generic/tclTomMath.h @@ -87,7 +87,7 @@ extern "C" { # define DIGIT_BIT 60 #else /* this is the default case, 28-bit digits */ - + /* this is to make porting into LibTomCrypt easier :-) */ #ifndef CRYPT # if defined(_MSC_VER) || defined(__BORLANDC__) @@ -105,14 +105,14 @@ extern "C" { #endif typedef ulong64 mp_word; -#ifdef MP_31BIT +#ifdef MP_31BIT /* this is an extension that uses 31-bit digits */ # define DIGIT_BIT 31 #else /* default case is 28-bit digits, defines MP_28BIT as a handy macro to test */ # define DIGIT_BIT 28 # define MP_28BIT -#endif +#endif #endif /* define heap macros */ @@ -646,7 +646,7 @@ int mp_prime_miller_rabin(mp_int *a, mp_int *b, int *result); */ /* This gives [for a given bit size] the number of trials required - * such that Miller-Rabin gives a prob of failure lower than 2^-96 + * such that Miller-Rabin gives a prob of failure lower than 2^-96 */ /* int mp_prime_rabin_miller_trials(int size); @@ -673,7 +673,7 @@ int mp_prime_next_prime(mp_int *a, int t, int bbs_style); */ /* makes a truly random prime of a given size (bytes), - * call with bbs = 1 if you want it to be congruent to 3 mod 4 + * call with bbs = 1 if you want it to be congruent to 3 mod 4 * * You have to supply a callback which fills in a buffer with random bytes. "dat" is a parameter you can * have passed to the callback (e.g. a state or something). This function doesn't use "dat" itself @@ -686,7 +686,7 @@ int mp_prime_next_prime(mp_int *a, int t, int bbs_style); /* makes a truly random prime of a given size (bits), * * Flags are as follows: - * + * * LTM_PRIME_BBS - make prime congruent to 3 mod 4 * LTM_PRIME_SAFE - make sure (p-1)/2 is prime as well (implies LTM_PRIME_BBS) * LTM_PRIME_2MSB_OFF - make the 2nd highest bit zero -- cgit v0.12 From 909f1a1a30d5d11579ff2e40d34529a13d5727ec Mon Sep 17 00:00:00 2001 From: dkf Date: Thu, 16 Mar 2017 09:07:19 +0000 Subject: Fixes to docs made possible by recent HTML rendering fixes for Tk. --- doc/re_syntax.n | 6 +++--- tools/tcltk-man2html-utils.tcl | 3 +-- 2 files changed, 4 insertions(+), 5 deletions(-) diff --git a/doc/re_syntax.n b/doc/re_syntax.n index 7988071..8d732ed 100644 --- a/doc/re_syntax.n +++ b/doc/re_syntax.n @@ -293,12 +293,12 @@ treatment is as if the enclosing delimiters were .QW \fB[.\fR \& and .QW \fB.]\fR .) -For example, if \fBo\fR and \fB\*(qo\fR are the members of an +For example, if \fBo\fR and \fB\[^o]\fR are the members of an equivalence class, then .QW \fB[[=o=]]\fR , -.QW \fB[[=\*(qo=]]\fR , +.QW \fB[[=\[^o]=]]\fR , and -.QW \fB[o\*(qo]\fR \& +.QW \fB[o\[^o]]\fR \& are all synonymous. An equivalence class may not be an endpoint of a range. .RS .PP diff --git a/tools/tcltk-man2html-utils.tcl b/tools/tcltk-man2html-utils.tcl index c887edd..b69e601 100644 --- a/tools/tcltk-man2html-utils.tcl +++ b/tools/tcltk-man2html-utils.tcl @@ -155,12 +155,11 @@ proc process-text {text} { {\fP} {\fR} \ {\.} . \ {\(bu} "•" \ - "\\*(qo" "ô" \ ] # This might make a few invalid mappings, but we don't use them foreach c {a e i o u y A E I O U Y} { foreach {prefix suffix} { - o circ / slash : uml ' acute ^ circ ` grave + o ring / slash : uml ' acute ^ circ ` grave } { lappend charmap "\\\[${prefix}${c}\]" "&${c}${suffix};" } -- cgit v0.12 From 5617ad7c180796ca3ded40478d67504694057ee6 Mon Sep 17 00:00:00 2001 From: "jan.nijtmans" Date: Fri, 17 Mar 2017 10:57:24 +0000 Subject: If Tcl is compiled with -DTCL_NO_DEPRECATED, make sure that iPtr->(resultSpace|appendResult|appendAvl|appendUsed) are not used any more. --- doc/RecEvalObj.3 | 2 -- generic/tclBasic.c | 10 ++++++++++ generic/tclInt.h | 10 ++++++++++ generic/tclResult.c | 2 +- generic/tclStubInit.c | 19 +++++++++++++++++++ 5 files changed, 40 insertions(+), 3 deletions(-) diff --git a/doc/RecEvalObj.3 b/doc/RecEvalObj.3 index 1b0f292..f9550a2 100644 --- a/doc/RecEvalObj.3 +++ b/doc/RecEvalObj.3 @@ -32,8 +32,6 @@ the command at global level instead of the current stack level. .PP \fBTcl_RecordAndEvalObj\fR is invoked to record a command as an event on the history list and then execute it using \fBTcl_EvalObjEx\fR -(or \fBTcl_GlobalEvalObj\fR if the \fBTCL_EVAL_GLOBAL\fR bit is set -in \fIflags\fR). It returns a completion code such as \fBTCL_OK\fR just like \fBTcl_EvalObjEx\fR, as well as a result value containing additional information (a result value or error message) diff --git a/generic/tclBasic.c b/generic/tclBasic.c index 32caac5..685e64c 100644 --- a/generic/tclBasic.c +++ b/generic/tclBasic.c @@ -510,7 +510,11 @@ Tcl_CreateInterp(void) iPtr = ckalloc(sizeof(Interp)); interp = (Tcl_Interp *) iPtr; +#ifdef TCL_NO_DEPRECATED + iPtr->result = &tclEmptyString; +#else iPtr->result = iPtr->resultSpace; +#endif iPtr->freeProc = NULL; iPtr->errorLine = 0; iPtr->objResultPtr = Tcl_NewObj(); @@ -570,9 +574,11 @@ Tcl_CreateInterp(void) iPtr->rootFramePtr = NULL; /* Initialise as soon as :: is available */ iPtr->lookupNsPtr = NULL; +#ifndef TCL_NO_DEPRECATED iPtr->appendResult = NULL; iPtr->appendAvl = 0; iPtr->appendUsed = 0; +#endif Tcl_InitHashTable(&iPtr->packageTable, TCL_STRING_KEYS); iPtr->packageUnknown = NULL; @@ -602,7 +608,9 @@ Tcl_CreateInterp(void) iPtr->emptyObjPtr = Tcl_NewObj(); /* Another empty object. */ Tcl_IncrRefCount(iPtr->emptyObjPtr); +#ifndef TCL_NO_DEPRECATED iPtr->resultSpace[0] = 0; +#endif iPtr->threadId = Tcl_GetCurrentThread(); /* TIP #378 */ @@ -1535,10 +1543,12 @@ DeleteInterpProc( if (iPtr->returnOpts) { Tcl_DecrRefCount(iPtr->returnOpts); } +#ifndef TCL_NO_DEPRECATED if (iPtr->appendResult != NULL) { ckfree(iPtr->appendResult); iPtr->appendResult = NULL; } +#endif TclFreePackageInfo(iPtr); while (iPtr->tracePtr != NULL) { Tcl_DeleteTrace((Tcl_Interp *) iPtr, (Tcl_Trace) iPtr->tracePtr); diff --git a/generic/tclInt.h b/generic/tclInt.h index 562e895..3845598 100644 --- a/generic/tclInt.h +++ b/generic/tclInt.h @@ -1862,6 +1862,7 @@ typedef struct Interp { * See Tcl_AppendResult code for details. */ +#ifndef TCL_NO_DEPRECATED char *appendResult; /* Storage space for results generated by * Tcl_AppendResult. Ckalloc-ed. NULL means * not yet allocated. */ @@ -1869,6 +1870,11 @@ typedef struct Interp { * partialResult. */ int appendUsed; /* Number of non-null bytes currently stored * at partialResult. */ +#else + char *appendResultDontUse; + int appendAvlDontUse; + int appendUsedDontUse; +#endif /* * Information about packages. Used only in tclPkg.c. @@ -1930,8 +1936,12 @@ typedef struct Interp { * string. Returned by Tcl_ObjSetVar2 when * variable traces change a variable in a * gross way. */ +#ifndef TCL_NO_DEPRECATED char resultSpace[TCL_RESULT_SIZE+1]; /* Static space holding small results. */ +#else + char resultSpaceDontUse[TCL_RESULT_SIZE+1]; +#endif Tcl_Obj *objResultPtr; /* If the last command returned an object * result, this points to it. Should not be * accessed directly; see comment above. */ diff --git a/generic/tclResult.c b/generic/tclResult.c index ddf764b..57a6de5 100644 --- a/generic/tclResult.c +++ b/generic/tclResult.c @@ -232,6 +232,7 @@ Tcl_DiscardInterpState( *---------------------------------------------------------------------- */ +#ifndef TCL_NO_DEPRECATED #undef Tcl_SaveResult void Tcl_SaveResult( @@ -409,7 +410,6 @@ Tcl_DiscardResult( *---------------------------------------------------------------------- */ -#ifndef TCL_NO_DEPRECATED void Tcl_SetResult( Tcl_Interp *interp, /* Interpreter with which to associate the diff --git a/generic/tclStubInit.c b/generic/tclStubInit.c index 816650e..121cf59 100644 --- a/generic/tclStubInit.c +++ b/generic/tclStubInit.c @@ -306,6 +306,25 @@ static int formatInt(char *buffer, int n){ # define Tcl_SetResult 0 # undef Tcl_DbNewBooleanObj # define Tcl_DbNewBooleanObj 0 +# undef Tcl_EvalObj +# define Tcl_EvalObj 0 +# undef Tcl_GlobalEvalObj +# define Tcl_GlobalEvalObj 0 +# define Tcl_NewBooleanObj 0 +# undef Tcl_SetBooleanObj +# define Tcl_SetBooleanObj 0 +# undef Tcl_PkgPresent +# define Tcl_PkgPresent 0 +# undef Tcl_PkgProvide +# define Tcl_PkgProvide 0 +# undef Tcl_PkgRequire +# define Tcl_PkgRequire 0 +# undef Tcl_DiscardResult +# define Tcl_DiscardResult 0 +# undef Tcl_RestoreResult +# define Tcl_RestoreResult 0 +# undef Tcl_SaveResult +# define Tcl_SaveResult 0 #else /* TCL_NO_DEPRECATED */ # define Tcl_SeekOld seekOld # define Tcl_TellOld tellOld -- cgit v0.12 From 754b233873390beef740d1af75437ec3684b198b Mon Sep 17 00:00:00 2001 From: "jan.nijtmans" Date: Mon, 20 Mar 2017 10:24:11 +0000 Subject: If compiled with TCL_NO_DEPRECATED, remove some more stub entries which are not used any more. --- generic/tclBasic.c | 6 ++++++ generic/tclDecls.h | 33 ++++++++++++++++++++++++++++----- generic/tclIndexObj.c | 2 ++ generic/tclInterp.c | 3 --- generic/tclObj.c | 2 +- generic/tclPreserve.c | 2 +- generic/tclStubInit.c | 44 +++++++++++++++++++++++++++++++------------- generic/tclStubLib.c | 2 +- generic/tclTest.c | 8 ++++---- generic/tclVar.c | 16 +++++++++------- 10 files changed, 83 insertions(+), 35 deletions(-) diff --git a/generic/tclBasic.c b/generic/tclBasic.c index 685e64c..8e816a5 100644 --- a/generic/tclBasic.c +++ b/generic/tclBasic.c @@ -5861,6 +5861,7 @@ TclArgumentGet( *---------------------------------------------------------------------- */ +#ifndef TCL_NO_DEPRECATED #undef Tcl_Eval int Tcl_Eval( @@ -5879,6 +5880,7 @@ Tcl_Eval( (void) Tcl_GetStringResult(interp); return code; } +#endif /* TCL_NO_DEPRECATED */ /* *---------------------------------------------------------------------- @@ -6739,6 +6741,7 @@ Tcl_AppendObjToErrorInfo( *---------------------------------------------------------------------- */ +#ifndef TCL_NO_DEPRECATED #undef Tcl_AddErrorInfo void Tcl_AddErrorInfo( @@ -6748,6 +6751,7 @@ Tcl_AddErrorInfo( { Tcl_AddObjErrorInfo(interp, message, -1); } +#endif /* TCL_NO_DEPRECATED */ /* *---------------------------------------------------------------------- @@ -6920,6 +6924,7 @@ Tcl_VarEval( *---------------------------------------------------------------------- */ +#ifndef TCL_NO_DEPRECATED #undef Tcl_GlobalEval int Tcl_GlobalEval( @@ -6937,6 +6942,7 @@ Tcl_GlobalEval( iPtr->varFramePtr = savedVarFramePtr; return result; } +#endif /* TCL_NO_DEPRECATED */ /* *---------------------------------------------------------------------- diff --git a/generic/tclDecls.h b/generic/tclDecls.h index fb7f8bc..d990889 100644 --- a/generic/tclDecls.h +++ b/generic/tclDecls.h @@ -3841,7 +3841,7 @@ extern const TclStubs *tclStubsPtr; Tcl_DbNewLongObj((boolValue)!=0, file, line) #undef Tcl_SetBooleanObj #define Tcl_SetBooleanObj(objPtr, boolValue) \ - Tcl_SetLongObj((objPtr), (boolValue)!=0) + Tcl_SetLongObj(objPtr, (boolValue)!=0) #undef Tcl_SetVar #define Tcl_SetVar(interp, varName, newValue, flags) \ Tcl_SetVar2(interp, varName, NULL, newValue, flags) @@ -3870,6 +3870,29 @@ extern const TclStubs *tclStubsPtr; #define Tcl_AddObjErrorInfo(interp, message, length) \ Tcl_AppendObjToErrorInfo(interp, Tcl_NewStringObj(message, length)) #ifdef TCL_NO_DEPRECATED +#undef Tcl_Eval +#define Tcl_Eval(interp, objPtr) \ + Tcl_EvalEx(interp, objPtr, -1, 0) +#undef Tcl_GlobalEval +#define Tcl_GlobalEval(interp, objPtr) \ + Tcl_EvalEx(interp, objPtr, -1, TCL_EVAL_GLOBAL) +#undef Tcl_SaveResult +#define Tcl_SaveResult(interp, statePtr) \ + do { \ + (statePtr)->objResultPtr = Tcl_GetObjResult(interp); \ + Tcl_IncrRefCount((statePtr)->objResultPtr); \ + Tcl_SetObjResult(interp, Tcl_NewObj()); \ + } while(0) +#undef Tcl_RestoreResult +#define Tcl_RestoreResult(interp, statePtr) \ + do { \ + Tcl_ResetResult(interp); \ + Tcl_SetObjResult(interp, (statePtr)->objResultPtr); \ + Tcl_DecrRefCount((statePtr)->objResultPtr); \ + } while(0) +#undef Tcl_DiscardResult +#define Tcl_DiscardResult(statePtr) \ + Tcl_DecrRefCount((statePtr)->objResultPtr) #undef Tcl_SetResult #define Tcl_SetResult(interp, result, freeProc) \ do { \ @@ -3939,10 +3962,10 @@ extern const TclStubs *tclStubsPtr; */ #undef Tcl_EvalObj -#define Tcl_EvalObj(interp,objPtr) \ - Tcl_EvalObjEx((interp),(objPtr),0) +#define Tcl_EvalObj(interp, objPtr) \ + Tcl_EvalObjEx(interp, objPtr, 0) #undef Tcl_GlobalEvalObj -#define Tcl_GlobalEvalObj(interp,objPtr) \ - Tcl_EvalObjEx((interp),(objPtr),TCL_EVAL_GLOBAL) +#define Tcl_GlobalEvalObj(interp, objPtr) \ + Tcl_EvalObjEx(interp, objPtr, TCL_EVAL_GLOBAL) #endif /* _TCLDECLS */ diff --git a/generic/tclIndexObj.c b/generic/tclIndexObj.c index 6a3e4e3..9f38638 100644 --- a/generic/tclIndexObj.c +++ b/generic/tclIndexObj.c @@ -101,6 +101,7 @@ typedef struct { *---------------------------------------------------------------------- */ +#ifndef TCL_NO_DEPRECATED #undef Tcl_GetIndexFromObj int Tcl_GetIndexFromObj( @@ -137,6 +138,7 @@ Tcl_GetIndexFromObj( return Tcl_GetIndexFromObjStruct(interp, objPtr, tablePtr, sizeof(char *), msg, flags, indexPtr); } +#endif /* TCL_NO_DEPRECATED */ /* *---------------------------------------------------------------------- diff --git a/generic/tclInterp.c b/generic/tclInterp.c index af9f1bf..d9dfd37 100644 --- a/generic/tclInterp.c +++ b/generic/tclInterp.c @@ -3533,9 +3533,6 @@ Tcl_LimitAddHandler( if (deleteProc == (Tcl_LimitHandlerDeleteProc *) TCL_DYNAMIC) { deleteProc = (Tcl_LimitHandlerDeleteProc *) Tcl_Free; } - if (deleteProc == (Tcl_LimitHandlerDeleteProc *) TCL_STATIC) { - deleteProc = NULL; - } /* * Allocate a handler record. diff --git a/generic/tclObj.c b/generic/tclObj.c index bfef5fb..8069a7c 100644 --- a/generic/tclObj.c +++ b/generic/tclObj.c @@ -1828,7 +1828,6 @@ Tcl_DbNewBooleanObj( return Tcl_NewBooleanObj(boolValue); } #endif /* TCL_MEM_DEBUG */ -#endif /* TCL_NO_DEPRECATED */ /* *---------------------------------------------------------------------- @@ -1860,6 +1859,7 @@ Tcl_SetBooleanObj( TclSetLongObj(objPtr, boolValue!=0); } +#endif /* TCL_NO_DEPRECATED */ /* *---------------------------------------------------------------------- diff --git a/generic/tclPreserve.c b/generic/tclPreserve.c index 2d0e15c..5c6097f 100644 --- a/generic/tclPreserve.c +++ b/generic/tclPreserve.c @@ -155,7 +155,7 @@ Tcl_Preserve( refPtr->clientData = clientData; refPtr->refCount = 1; refPtr->mustFree = 0; - refPtr->freeProc = TCL_STATIC; + refPtr->freeProc = 0; inUse += 1; Tcl_MutexUnlock(&preserveMutex); } diff --git a/generic/tclStubInit.c b/generic/tclStubInit.c index 121cf59..50fac4b 100644 --- a/generic/tclStubInit.c +++ b/generic/tclStubInit.c @@ -302,15 +302,6 @@ static int formatInt(char *buffer, int n){ #ifdef TCL_NO_DEPRECATED # define Tcl_SeekOld 0 # define Tcl_TellOld 0 -# undef Tcl_SetResult -# define Tcl_SetResult 0 -# undef Tcl_DbNewBooleanObj -# define Tcl_DbNewBooleanObj 0 -# undef Tcl_EvalObj -# define Tcl_EvalObj 0 -# undef Tcl_GlobalEvalObj -# define Tcl_GlobalEvalObj 0 -# define Tcl_NewBooleanObj 0 # undef Tcl_SetBooleanObj # define Tcl_SetBooleanObj 0 # undef Tcl_PkgPresent @@ -319,12 +310,39 @@ static int formatInt(char *buffer, int n){ # define Tcl_PkgProvide 0 # undef Tcl_PkgRequire # define Tcl_PkgRequire 0 -# undef Tcl_DiscardResult -# define Tcl_DiscardResult 0 -# undef Tcl_RestoreResult -# define Tcl_RestoreResult 0 +# undef Tcl_GetIndexFromObj +# define Tcl_GetIndexFromObj 0 +# define Tcl_NewBooleanObj 0 +# undef Tcl_DbNewBooleanObj +# define Tcl_DbNewBooleanObj 0 +# undef Tcl_SetBooleanObj +# define Tcl_SetBooleanObj 0 +# undef Tcl_SetVar +# define Tcl_SetVar 0 +# undef Tcl_UnsetVar +# define Tcl_UnsetVar 0 +# undef Tcl_GetVar +# define Tcl_GetVar 0 +# undef Tcl_AddErrorInfo +# define Tcl_AddErrorInfo 0 +# undef Tcl_AddObjErrorInfo +# define Tcl_AddObjErrorInfo 0 +# undef Tcl_Eval +# define Tcl_Eval 0 +# undef Tcl_GlobalEval +# define Tcl_GlobalEval 0 # undef Tcl_SaveResult # define Tcl_SaveResult 0 +# undef Tcl_RestoreResult +# define Tcl_RestoreResult 0 +# undef Tcl_DiscardResult +# define Tcl_DiscardResult 0 +# undef Tcl_SetResult +# define Tcl_SetResult 0 +# undef Tcl_EvalObj +# define Tcl_EvalObj 0 +# undef Tcl_GlobalEvalObj +# define Tcl_GlobalEvalObj 0 #else /* TCL_NO_DEPRECATED */ # define Tcl_SeekOld seekOld # define Tcl_TellOld tellOld diff --git a/generic/tclStubLib.c b/generic/tclStubLib.c index dd951bf..5261591 100644 --- a/generic/tclStubLib.c +++ b/generic/tclStubLib.c @@ -67,7 +67,7 @@ Tcl_InitStubs( if (!stubsPtr || (stubsPtr->magic != (((exact&0xff00) >= 0x900) ? magic : TCL_STUB_MAGIC))) { iPtr->result = (char *)"interpreter uses an incompatible stubs mechanism"; - iPtr->freeProc = TCL_STATIC; + iPtr->freeProc = 0; return NULL; } diff --git a/generic/tclTest.c b/generic/tclTest.c index a9dc1ca..84d4ea1 100644 --- a/generic/tclTest.c +++ b/generic/tclTest.c @@ -3405,7 +3405,7 @@ TestMathFunc2( resultPtr->type = TCL_WIDE_INT; resultPtr->wideValue = ((w0 > w1)? w0 : w1); } else { - Tcl_SetResult(interp, (char *)"T3: wrong type for arg 2", TCL_STATIC); + Tcl_AppendResult(interp, "T3: wrong type for arg 2", NULL); result = TCL_ERROR; } } else if (args[0].type == TCL_DOUBLE) { @@ -3427,7 +3427,7 @@ TestMathFunc2( resultPtr->type = TCL_DOUBLE; resultPtr->doubleValue = ((d0 > d1)? d0 : d1); } else { - Tcl_SetResult(interp, (char *)"T3: wrong type for arg 2", TCL_STATIC); + Tcl_AppendResult(interp, "T3: wrong type for arg 2", NULL); result = TCL_ERROR; } } else if (args[0].type == TCL_WIDE_INT) { @@ -3450,11 +3450,11 @@ TestMathFunc2( resultPtr->type = TCL_WIDE_INT; resultPtr->wideValue = ((w0 > w1)? w0 : w1); } else { - Tcl_SetResult(interp, (char *)"T3: wrong type for arg 2", TCL_STATIC); + Tcl_AppendResult(interp, "T3: wrong type for arg 2", NULL); result = TCL_ERROR; } } else { - Tcl_SetResult(interp, (char *)"T3: wrong type for arg 1", TCL_STATIC); + Tcl_AppendResult(interp, "T3: wrong type for arg 1", NULL); result = TCL_ERROR; } return result; diff --git a/generic/tclVar.c b/generic/tclVar.c index 5ab6e8b..6090d61 100644 --- a/generic/tclVar.c +++ b/generic/tclVar.c @@ -1067,6 +1067,7 @@ TclLookupArrayElement( *---------------------------------------------------------------------- */ +#ifndef TCL_NO_DEPRECATED #undef Tcl_GetVar const char * Tcl_GetVar( @@ -1087,6 +1088,7 @@ Tcl_GetVar( } return TclGetString(resultPtr); } +#endif /* TCL_NO_DEPRECATED */ /* *---------------------------------------------------------------------- @@ -1410,6 +1412,7 @@ Tcl_SetObjCmd( *---------------------------------------------------------------------- */ +#ifndef TCL_NO_DEPRECATED #undef Tcl_SetVar const char * Tcl_SetVar( @@ -1422,18 +1425,15 @@ Tcl_SetVar( * TCL_APPEND_VALUE, TCL_LIST_ELEMENT, * TCL_LEAVE_ERR_MSG. */ { - Tcl_Obj *varValuePtr, *varNamePtr = Tcl_NewStringObj(varName, -1); - - Tcl_IncrRefCount(varNamePtr); - varValuePtr = Tcl_ObjSetVar2(interp, varNamePtr, NULL, + Tcl_Obj *varValuePtr = Tcl_SetVar2Ex(interp, varName, NULL, Tcl_NewStringObj(newValue, -1), flags); - Tcl_DecrRefCount(varNamePtr); if (varValuePtr == NULL) { return NULL; } return TclGetString(varValuePtr); } +#endif /* TCL_NO_DEPRECATED */ /* *---------------------------------------------------------------------- @@ -2005,6 +2005,7 @@ TclPtrIncrObjVar( *---------------------------------------------------------------------- */ +#ifndef TCL_NO_DEPRECATED #undef Tcl_UnsetVar int Tcl_UnsetVar( @@ -2033,6 +2034,7 @@ Tcl_UnsetVar( Tcl_DecrRefCount(varNamePtr); return result; } +#endif /* TCL_NO_DEPRECATED */ /* *---------------------------------------------------------------------- @@ -4050,7 +4052,7 @@ TclInitArrayCmd( * * Results: * A standard Tcl completion code. If an error occurs then an error - * message is left in iPtr->result. + * message is left in interp. * * Side effects: * The variable given by myName is linked to the variable in framePtr @@ -4144,7 +4146,7 @@ ObjMakeUpvar( * * Results: * A standard Tcl completion code. If an error occurs then an error - * message is left in iPtr->result. + * message is left in interp. * * Side effects: * The variable given by myName is linked to the variable in framePtr -- cgit v0.12 From dc25a1a62b5759e600a6346d6279f71c6d421299 Mon Sep 17 00:00:00 2001 From: "jan.nijtmans" Date: Tue, 21 Mar 2017 09:01:09 +0000 Subject: Addendum to previous commit: If compiled with TCL_NO_DEPRECATED, remove a few more stub entries which are not used any more. --- generic/tclStubInit.c | 8 ++++++++ generic/tclTrace.c | 6 ++++++ generic/tclVar.c | 2 ++ 3 files changed, 16 insertions(+) diff --git a/generic/tclStubInit.c b/generic/tclStubInit.c index 50fac4b..7957389 100644 --- a/generic/tclStubInit.c +++ b/generic/tclStubInit.c @@ -323,6 +323,14 @@ static int formatInt(char *buffer, int n){ # define Tcl_UnsetVar 0 # undef Tcl_GetVar # define Tcl_GetVar 0 +# undef Tcl_TraceVar +# define Tcl_TraceVar 0 +# undef Tcl_UntraceVar +# define Tcl_UntraceVar 0 +# undef Tcl_VarTraceInfo +# define Tcl_VarTraceInfo 0 +# undef Tcl_UpVar +# define Tcl_UpVar 0 # undef Tcl_AddErrorInfo # define Tcl_AddErrorInfo 0 # undef Tcl_AddObjErrorInfo diff --git a/generic/tclTrace.c b/generic/tclTrace.c index bea3162..f86f472 100644 --- a/generic/tclTrace.c +++ b/generic/tclTrace.c @@ -2819,6 +2819,7 @@ DisposeTraceResult( *---------------------------------------------------------------------- */ +#ifndef TCL_NO_DEPRECATED #undef Tcl_UntraceVar void Tcl_UntraceVar( @@ -2834,6 +2835,7 @@ Tcl_UntraceVar( { Tcl_UntraceVar2(interp, varName, NULL, flags, proc, clientData); } +#endif /* TCL_NO_DEPRECATED */ /* *---------------------------------------------------------------------- @@ -2988,6 +2990,7 @@ Tcl_UntraceVar2( *---------------------------------------------------------------------- */ +#ifndef TCL_NO_DEPRECATED #undef Tcl_VarTraceInfo ClientData Tcl_VarTraceInfo( @@ -3005,6 +3008,7 @@ Tcl_VarTraceInfo( return Tcl_VarTraceInfo2(interp, varName, NULL, flags, proc, prevClientData); } +#endif /* TCL_NO_DEPRECATED */ /* *---------------------------------------------------------------------- @@ -3097,6 +3101,7 @@ Tcl_VarTraceInfo2( *---------------------------------------------------------------------- */ +#ifndef TCL_NO_DEPRECATED #undef Tcl_TraceVar int Tcl_TraceVar( @@ -3114,6 +3119,7 @@ Tcl_TraceVar( { return Tcl_TraceVar2(interp, varName, NULL, flags, proc, clientData); } +#endif /* TCL_NO_DEPRECATED */ /* *---------------------------------------------------------------------- diff --git a/generic/tclVar.c b/generic/tclVar.c index 6090d61..1947c8d 100644 --- a/generic/tclVar.c +++ b/generic/tclVar.c @@ -4322,6 +4322,7 @@ TclPtrObjMakeUpvar( *---------------------------------------------------------------------- */ +#ifndef TCL_NO_DEPRECATED #undef Tcl_UpVar int Tcl_UpVar( @@ -4355,6 +4356,7 @@ Tcl_UpVar( Tcl_DecrRefCount(localNamePtr); return result; } +#endif /* TCL_NO_DEPRECATED */ /* *---------------------------------------------------------------------- -- cgit v0.12 From 5894e1b0854dbf8ee25305caf1bfdc5913b71536 Mon Sep 17 00:00:00 2001 From: dgp Date: Wed, 22 Mar 2017 19:42:57 +0000 Subject: New(ish) test interp-14.11 was missing its -cleanup. --- tests/interp.test | 2 ++ 1 file changed, 2 insertions(+) diff --git a/tests/interp.test b/tests/interp.test index 4d61e35..5299d82 100644 --- a/tests/interp.test +++ b/tests/interp.test @@ -615,6 +615,8 @@ test interp-14.11 {{interp alias} {target named the empty string} {bug 2bf56185} } -body { interp alias {} p1 $interp {} p1 one two three +} -cleanup { + interp delete $interp } -result {one two three} # part 15: testing file sharing -- cgit v0.12 From 4703c1399dcfcaf70b53f268e196b9a8fd597675 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Ignacio=20Mar=C3=ADn?= Date: Thu, 23 Mar 2017 08:25:57 +0000 Subject: Update TZ info to tzcode2017b. --- library/tzdata/Africa/Monrovia | 4 +- library/tzdata/America/Port-au-Prince | 166 ++++++++++++++++++++++++++++++++++ 2 files changed, 168 insertions(+), 2 deletions(-) diff --git a/library/tzdata/Africa/Monrovia b/library/tzdata/Africa/Monrovia index eb069f6..2b311bb 100644 --- a/library/tzdata/Africa/Monrovia +++ b/library/tzdata/Africa/Monrovia @@ -3,6 +3,6 @@ set TZData(:Africa/Monrovia) { {-9223372036854775808 -2588 0 LMT} {-2776979812 -2588 0 MMT} - {-1604359012 -2670 0 -004430} - {73529070 0 0 GMT} + {-1604359012 -2670 0 MMT} + {63593070 0 0 GMT} } diff --git a/library/tzdata/America/Port-au-Prince b/library/tzdata/America/Port-au-Prince index b8b60d6..23e7de4 100644 --- a/library/tzdata/America/Port-au-Prince +++ b/library/tzdata/America/Port-au-Prince @@ -46,4 +46,170 @@ set TZData(:America/Port-au-Prince) { {1414908000 -18000 0 EST} {1425798000 -14400 1 EDT} {1446357600 -18000 0 EST} + {1489302000 -14400 1 EDT} + {1509861600 -18000 0 EST} + {1520751600 -14400 1 EDT} + {1541311200 -18000 0 EST} + {1552201200 -14400 1 EDT} + {1572760800 -18000 0 EST} + {1583650800 -14400 1 EDT} + {1604210400 -18000 0 EST} + {1615705200 -14400 1 EDT} + {1636264800 -18000 0 EST} + {1647154800 -14400 1 EDT} + {1667714400 -18000 0 EST} + {1678604400 -14400 1 EDT} + {1699164000 -18000 0 EST} + {1710054000 -14400 1 EDT} + {1730613600 -18000 0 EST} + {1741503600 -14400 1 EDT} + {1762063200 -18000 0 EST} + {1772953200 -14400 1 EDT} + {1793512800 -18000 0 EST} + {1805007600 -14400 1 EDT} + {1825567200 -18000 0 EST} + {1836457200 -14400 1 EDT} + {1857016800 -18000 0 EST} + {1867906800 -14400 1 EDT} + {1888466400 -18000 0 EST} + {1899356400 -14400 1 EDT} + {1919916000 -18000 0 EST} + {1930806000 -14400 1 EDT} + {1951365600 -18000 0 EST} + {1962860400 -14400 1 EDT} + {1983420000 -18000 0 EST} + {1994310000 -14400 1 EDT} + {2014869600 -18000 0 EST} + {2025759600 -14400 1 EDT} + {2046319200 -18000 0 EST} + {2057209200 -14400 1 EDT} + {2077768800 -18000 0 EST} + {2088658800 -14400 1 EDT} + {2109218400 -18000 0 EST} + {2120108400 -14400 1 EDT} + {2140668000 -18000 0 EST} + {2152162800 -14400 1 EDT} + {2172722400 -18000 0 EST} + {2183612400 -14400 1 EDT} + {2204172000 -18000 0 EST} + {2215062000 -14400 1 EDT} + {2235621600 -18000 0 EST} + {2246511600 -14400 1 EDT} + {2267071200 -18000 0 EST} + {2277961200 -14400 1 EDT} + {2298520800 -18000 0 EST} + {2309410800 -14400 1 EDT} + {2329970400 -18000 0 EST} + {2341465200 -14400 1 EDT} + {2362024800 -18000 0 EST} + {2372914800 -14400 1 EDT} + {2393474400 -18000 0 EST} + {2404364400 -14400 1 EDT} + {2424924000 -18000 0 EST} + {2435814000 -14400 1 EDT} + {2456373600 -18000 0 EST} + {2467263600 -14400 1 EDT} + {2487823200 -18000 0 EST} + {2499318000 -14400 1 EDT} + {2519877600 -18000 0 EST} + {2530767600 -14400 1 EDT} + {2551327200 -18000 0 EST} + {2562217200 -14400 1 EDT} + {2582776800 -18000 0 EST} + {2593666800 -14400 1 EDT} + {2614226400 -18000 0 EST} + {2625116400 -14400 1 EDT} + {2645676000 -18000 0 EST} + {2656566000 -14400 1 EDT} + {2677125600 -18000 0 EST} + {2688620400 -14400 1 EDT} + {2709180000 -18000 0 EST} + {2720070000 -14400 1 EDT} + {2740629600 -18000 0 EST} + {2751519600 -14400 1 EDT} + {2772079200 -18000 0 EST} + {2782969200 -14400 1 EDT} + {2803528800 -18000 0 EST} + {2814418800 -14400 1 EDT} + {2834978400 -18000 0 EST} + {2846473200 -14400 1 EDT} + {2867032800 -18000 0 EST} + {2877922800 -14400 1 EDT} + {2898482400 -18000 0 EST} + {2909372400 -14400 1 EDT} + {2929932000 -18000 0 EST} + {2940822000 -14400 1 EDT} + {2961381600 -18000 0 EST} + {2972271600 -14400 1 EDT} + {2992831200 -18000 0 EST} + {3003721200 -14400 1 EDT} + {3024280800 -18000 0 EST} + {3035775600 -14400 1 EDT} + {3056335200 -18000 0 EST} + {3067225200 -14400 1 EDT} + {3087784800 -18000 0 EST} + {3098674800 -14400 1 EDT} + {3119234400 -18000 0 EST} + {3130124400 -14400 1 EDT} + {3150684000 -18000 0 EST} + {3161574000 -14400 1 EDT} + {3182133600 -18000 0 EST} + {3193023600 -14400 1 EDT} + {3213583200 -18000 0 EST} + {3225078000 -14400 1 EDT} + {3245637600 -18000 0 EST} + {3256527600 -14400 1 EDT} + {3277087200 -18000 0 EST} + {3287977200 -14400 1 EDT} + {3308536800 -18000 0 EST} + {3319426800 -14400 1 EDT} + {3339986400 -18000 0 EST} + {3350876400 -14400 1 EDT} + {3371436000 -18000 0 EST} + {3382930800 -14400 1 EDT} + {3403490400 -18000 0 EST} + {3414380400 -14400 1 EDT} + {3434940000 -18000 0 EST} + {3445830000 -14400 1 EDT} + {3466389600 -18000 0 EST} + {3477279600 -14400 1 EDT} + {3497839200 -18000 0 EST} + {3508729200 -14400 1 EDT} + {3529288800 -18000 0 EST} + {3540178800 -14400 1 EDT} + {3560738400 -18000 0 EST} + {3572233200 -14400 1 EDT} + {3592792800 -18000 0 EST} + {3603682800 -14400 1 EDT} + {3624242400 -18000 0 EST} + {3635132400 -14400 1 EDT} + {3655692000 -18000 0 EST} + {3666582000 -14400 1 EDT} + {3687141600 -18000 0 EST} + {3698031600 -14400 1 EDT} + {3718591200 -18000 0 EST} + {3730086000 -14400 1 EDT} + {3750645600 -18000 0 EST} + {3761535600 -14400 1 EDT} + {3782095200 -18000 0 EST} + {3792985200 -14400 1 EDT} + {3813544800 -18000 0 EST} + {3824434800 -14400 1 EDT} + {3844994400 -18000 0 EST} + {3855884400 -14400 1 EDT} + {3876444000 -18000 0 EST} + {3887334000 -14400 1 EDT} + {3907893600 -18000 0 EST} + {3919388400 -14400 1 EDT} + {3939948000 -18000 0 EST} + {3950838000 -14400 1 EDT} + {3971397600 -18000 0 EST} + {3982287600 -14400 1 EDT} + {4002847200 -18000 0 EST} + {4013737200 -14400 1 EDT} + {4034296800 -18000 0 EST} + {4045186800 -14400 1 EDT} + {4065746400 -18000 0 EST} + {4076636400 -14400 1 EDT} + {4097196000 -18000 0 EST} } -- cgit v0.12 From 321cd769b746ae6c9ef1b15e193fb645de9a0d0b Mon Sep 17 00:00:00 2001 From: "jan.nijtmans" Date: Thu, 23 Mar 2017 16:35:08 +0000 Subject: Use portable %p modifier in "generic/tclThreadTest.c", in stead of more complicated TCL_LL_MODIFIER. --- generic/tclThreadTest.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/generic/tclThreadTest.c b/generic/tclThreadTest.c index 1a05f80..5bb0165 100644 --- a/generic/tclThreadTest.c +++ b/generic/tclThreadTest.c @@ -655,7 +655,7 @@ ThreadErrorProc( char *script; char buf[TCL_DOUBLE_SPACE+1]; - sprintf(buf, "%" TCL_LL_MODIFIER "d", (Tcl_WideInt)(size_t)Tcl_GetCurrentThread()); + sprintf(buf, "%p", Tcl_GetCurrentThread()); errorInfo = Tcl_GetVar2(interp, "errorInfo", NULL, TCL_GLOBAL_ONLY); if (errorProcString == NULL) { -- cgit v0.12 From ab08379d1c20b87f25e17de1c9e8bac2b0360e47 Mon Sep 17 00:00:00 2001 From: "jan.nijtmans" Date: Fri, 24 Mar 2017 09:33:00 +0000 Subject: Add TCL_NORETURN attribute to TclpThreadExit() and Tcl_ExitThread() --- generic/tcl.decls | 2 +- generic/tclDecls.h | 4 ++-- generic/tclInt.h | 2 +- macosx/tclMacOSXNotify.c | 5 ++--- unix/tclUnixNotfy.c | 4 ++-- 5 files changed, 8 insertions(+), 9 deletions(-) diff --git a/generic/tcl.decls b/generic/tcl.decls index ba047a0..b2b91a9 100644 --- a/generic/tcl.decls +++ b/generic/tcl.decls @@ -1059,7 +1059,7 @@ declare 293 { int Tcl_EvalObjEx(Tcl_Interp *interp, Tcl_Obj *objPtr, int flags) } declare 294 { - void Tcl_ExitThread(int status) + TCL_NORETURN void Tcl_ExitThread(int status) } declare 295 { int Tcl_ExternalToUtf(Tcl_Interp *interp, Tcl_Encoding encoding, diff --git a/generic/tclDecls.h b/generic/tclDecls.h index d990889..d543238 100644 --- a/generic/tclDecls.h +++ b/generic/tclDecls.h @@ -878,7 +878,7 @@ EXTERN int Tcl_EvalObjv(Tcl_Interp *interp, int objc, EXTERN int Tcl_EvalObjEx(Tcl_Interp *interp, Tcl_Obj *objPtr, int flags); /* 294 */ -EXTERN void Tcl_ExitThread(int status); +EXTERN TCL_NORETURN void Tcl_ExitThread(int status); /* 295 */ EXTERN int Tcl_ExternalToUtf(Tcl_Interp *interp, Tcl_Encoding encoding, const char *src, @@ -2151,7 +2151,7 @@ typedef struct TclStubs { int (*tcl_EvalEx) (Tcl_Interp *interp, const char *script, int numBytes, int flags); /* 291 */ int (*tcl_EvalObjv) (Tcl_Interp *interp, int objc, Tcl_Obj *const objv[], int flags); /* 292 */ int (*tcl_EvalObjEx) (Tcl_Interp *interp, Tcl_Obj *objPtr, int flags); /* 293 */ - void (*tcl_ExitThread) (int status); /* 294 */ + TCL_NORETURN1 void (*tcl_ExitThread) (int status); /* 294 */ int (*tcl_ExternalToUtf) (Tcl_Interp *interp, Tcl_Encoding encoding, const char *src, int srcLen, int flags, Tcl_EncodingState *statePtr, char *dst, int dstLen, int *srcReadPtr, int *dstWrotePtr, int *dstCharsPtr); /* 295 */ char * (*tcl_ExternalToUtfDString) (Tcl_Encoding encoding, const char *src, int srcLen, Tcl_DString *dsPtr); /* 296 */ void (*tcl_FinalizeThread) (void); /* 297 */ diff --git a/generic/tclInt.h b/generic/tclInt.h index 3845598..1fbc541 100644 --- a/generic/tclInt.h +++ b/generic/tclInt.h @@ -3124,7 +3124,7 @@ MODULE_SCOPE void TclpSetVariables(Tcl_Interp *interp); MODULE_SCOPE void * TclThreadStorageKeyGet(Tcl_ThreadDataKey *keyPtr); MODULE_SCOPE void TclThreadStorageKeySet(Tcl_ThreadDataKey *keyPtr, void *data); -MODULE_SCOPE void TclpThreadExit(int status); +MODULE_SCOPE TCL_NORETURN void TclpThreadExit(int status); MODULE_SCOPE void TclRememberCondition(Tcl_Condition *mutex); MODULE_SCOPE void TclRememberJoinableThread(Tcl_ThreadId id); MODULE_SCOPE void TclRememberMutex(Tcl_Mutex *mutex); diff --git a/macosx/tclMacOSXNotify.c b/macosx/tclMacOSXNotify.c index a7f26b7..1af73de 100644 --- a/macosx/tclMacOSXNotify.c +++ b/macosx/tclMacOSXNotify.c @@ -385,8 +385,7 @@ static CFStringRef tclEventsOnlyRunLoopMode = NULL; */ static void StartNotifierThread(void); -static void NotifierThreadProc(ClientData clientData) - __attribute__ ((__noreturn__)); +static TCL_NORETURN void NotifierThreadProc(ClientData clientData); static int FileHandlerEventProc(Tcl_Event *evPtr, int flags); static void TimerWakeUp(CFRunLoopTimerRef timer, void *info); static void QueueFileEvents(void *info); @@ -1753,7 +1752,7 @@ TclUnixWaitForFile( *---------------------------------------------------------------------- */ -static void +static TCL_NORETURN void NotifierThreadProc( ClientData clientData) /* Not used. */ { diff --git a/unix/tclUnixNotfy.c b/unix/tclUnixNotfy.c index e37962d..6b7669d 100644 --- a/unix/tclUnixNotfy.c +++ b/unix/tclUnixNotfy.c @@ -193,7 +193,7 @@ static Tcl_ThreadId notifierThread; */ #ifdef TCL_THREADS -static void NotifierThreadProc(ClientData clientData); +static TCL_NORETURN void NotifierThreadProc(ClientData clientData); #if defined(HAVE_PTHREAD_ATFORK) static int atForkInit = 0; static void AtForkChild(void); @@ -1139,7 +1139,7 @@ Tcl_WaitForEvent( *---------------------------------------------------------------------- */ -static void +static TCL_NORETURN void NotifierThreadProc( ClientData clientData) /* Not used. */ { -- cgit v0.12 From 920aa8280f7ad6756c06787903f8ee5b9a5497a3 Mon Sep 17 00:00:00 2001 From: "jan.nijtmans" Date: Fri, 24 Mar 2017 15:52:42 +0000 Subject: Supply more C99-compatible (and MSVC) format options: '%p' for pointers, 'z'/'j'/'I' for size_t/intptr_diff, 'j'/'q' for long long. Also add "I32" froom MSVC. Remove TCL_LL_MODIFIER specified as "L" for Borland: This must be wrong as "L" is meant for long double. Just assume that later Borland compilers are MSVC-compatible. --- generic/tcl.h | 6 +----- generic/tclStringObj.c | 39 +++++++++++++++++++++++++++++++++------ generic/tclTest.c | 4 +++- tests/util.test | 32 ++++++++++++++++++++++++++++---- 4 files changed, 65 insertions(+), 16 deletions(-) diff --git a/generic/tcl.h b/generic/tcl.h index 1491745..bdb4035 100644 --- a/generic/tcl.h +++ b/generic/tcl.h @@ -393,11 +393,7 @@ typedef long LONG; #if !defined(TCL_WIDE_INT_TYPE)&&!defined(TCL_WIDE_INT_IS_LONG) # if defined(_WIN32) # define TCL_WIDE_INT_TYPE __int64 -# ifdef __BORLANDC__ -# define TCL_LL_MODIFIER "L" -# else /* __BORLANDC__ */ -# define TCL_LL_MODIFIER "I64" -# endif /* __BORLANDC__ */ +# define TCL_LL_MODIFIER "I64" # elif defined(__GNUC__) # define TCL_WIDE_INT_TYPE long long # define TCL_LL_MODIFIER "ll" diff --git a/generic/tclStringObj.c b/generic/tclStringObj.c index c45baa1..b8b64d4 100644 --- a/generic/tclStringObj.c +++ b/generic/tclStringObj.c @@ -1865,11 +1865,22 @@ Tcl_AppendFormatToObj( useWide = 1; #endif } - } else if ((ch == 'I') && (format[1] == '6') && (format[2] == '4')) { - format += (step + 2); + } else if (ch == 'I') { + if ((format[1] == '6') && (format[2] == '4')) { + format += (step + 2); + step = Tcl_UtfToUniChar(format, &ch); + useBig = 1; + } else if ((format[1] == '3') && (format[2] == '2')) { + format += (step + 2); + step = Tcl_UtfToUniChar(format, &ch); + } else { + format += step; + step = Tcl_UtfToUniChar(format, &ch); + } + } else if ((ch == 't') || (ch == 'z')) { + format += step; step = Tcl_UtfToUniChar(format, &ch); - useBig = 1; - } else if (ch == 'L') { + } else if ((ch == 'q') ||(ch == 'j')) { format += step; step = Tcl_UtfToUniChar(format, &ch); useBig = 1; @@ -1925,6 +1936,7 @@ Tcl_AppendFormatToObj( } case 'd': case 'o': + case 'p': case 'x': case 'X': case 'b': { @@ -1993,13 +2005,14 @@ Tcl_AppendFormatToObj( segmentLimit -= 1; } - if (gotHash) { + if (gotHash || (ch == 'p')) { switch (ch) { case 'o': Tcl_AppendToObj(segment, "0", 1); segmentLimit -= 1; precision--; break; + case 'p': case 'x': case 'X': Tcl_AppendToObj(segment, "0x", 2); @@ -2078,6 +2091,7 @@ Tcl_AppendFormatToObj( case 'u': case 'o': + case 'p': case 'x': case 'X': case 'b': { @@ -2467,6 +2481,7 @@ AppendPrintfToObjVA( case 'u': case 'd': case 'o': + case 'p': case 'x': case 'X': seekingConversion = 0; @@ -2517,7 +2532,15 @@ AppendPrintfToObjVA( ++size; p++; break; - case 'L': + case 't': + case 'z': + if (sizeof(size_t) == sizeof(Tcl_WideInt)) { + size = 2; + } + p++; + break; + case 'j': + case 'q': size = 2; p++; break; @@ -2525,6 +2548,10 @@ AppendPrintfToObjVA( if (p[1]=='6' && p[2]=='4') { p += 2; size = 2; + } else if (p[1]=='3' && p[2]=='2') { + p += 2; + } else if (sizeof(size_t) == sizeof(Tcl_WideInt)) { + size = 2; } p++; break; diff --git a/generic/tclTest.c b/generic/tclTest.c index 84d4ea1..0f019bb 100644 --- a/generic/tclTest.c +++ b/generic/tclTest.c @@ -3847,6 +3847,7 @@ TestprintObjCmd( Tcl_Obj *const objv[]) /* The argument objects. */ { Tcl_WideInt argv1 = 0; + size_t argv2; if (objc < 2 || objc > 3) { Tcl_WrongNumArgs(interp, 1, objv, "format wideint"); @@ -3855,7 +3856,8 @@ TestprintObjCmd( if (objc > 1) { Tcl_GetWideIntFromObj(interp, objv[2], &argv1); } - Tcl_SetObjResult(interp, Tcl_ObjPrintf(Tcl_GetString(objv[1]), argv1)); + argv2 = (size_t)argv1; + Tcl_SetObjResult(interp, Tcl_ObjPrintf(Tcl_GetString(objv[1]), argv1, argv2, argv2)); return TCL_OK; } diff --git a/tests/util.test b/tests/util.test index 1a3eecb..22d120b 100644 --- a/tests/util.test +++ b/tests/util.test @@ -4027,21 +4027,45 @@ test util-18.2 {Tcl_ObjPrintf} {testprint} { } {9223372036854775807} test util-18.3 {Tcl_ObjPrintf} {testprint} { - testprint %Ld [expr 2**63-1] + testprint %qd [expr 2**63-1] } {9223372036854775807} test util-18.4 {Tcl_ObjPrintf} {testprint} { + testprint %jd [expr 2**63-1] +} {9223372036854775807} + +test util-18.5 {Tcl_ObjPrintf} {testprint} { testprint %lld [expr -2**63] } {-9223372036854775808} -test util-18.5 {Tcl_ObjPrintf} {testprint} { +test util-18.6 {Tcl_ObjPrintf} {testprint} { testprint %I64d [expr -2**63] } {-9223372036854775808} -test util-18.6 {Tcl_ObjPrintf} {testprint} { - testprint %Ld [expr -2**63] +test util-18.7 {Tcl_ObjPrintf} {testprint} { + testprint %qd [expr -2**63] } {-9223372036854775808} +test util-18.8 {Tcl_ObjPrintf} {testprint} { + testprint %jd [expr -2**63] +} {-9223372036854775808} + +test util-18.9 {Tcl_ObjPrintf} {testprint} { + testprint "%I64d %I32d" [expr -2**63+2] +} {-9223372036854775806 2} + +test util-18.10 {Tcl_ObjPrintf} {testprint} { + testprint "%I64d %p" 65535 +} {65535 0xffff} + +test util-18.11 {Tcl_ObjPrintf} {testprint} { + testprint "%I64d %td" 65536 +} {65536 65536} + +test util-18.12 {Tcl_ObjPrintf} {testprint} { + testprint "%I64d %Id" 65537 +} {65537 65537} + set ::tcl_precision $saved_precision # cleanup -- cgit v0.12 From 0d54bf371184c2ddc80a0640d56446078478cbda Mon Sep 17 00:00:00 2001 From: "jan.nijtmans" Date: Mon, 27 Mar 2017 13:01:34 +0000 Subject: Improve comment on TCL_WIDE_INT_IS_LONG, making it less misleading. In tclThreadTest.c, allow mainThreadId to be >32 bits. --- generic/tcl.h | 4 ++-- generic/tclThreadTest.c | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/generic/tcl.h b/generic/tcl.h index 64c7d14..759f824 100644 --- a/generic/tcl.h +++ b/generic/tcl.h @@ -372,8 +372,8 @@ typedef long LONG; * we have one, we can have the other.) * * Also defines the following macros: - * TCL_WIDE_INT_IS_LONG - if wide ints are really longs (i.e. we're on a real - * 64-bit system.) + * TCL_WIDE_INT_IS_LONG - if wide ints are really longs (i.e. we're on a + * LP64 system such as modern Solaris or Linux ... not including Win64) * Tcl_WideAsLong - forgetful converter from wideInt to long. * Tcl_LongAsWide - sign-extending converter from long to wideInt. * Tcl_WideAsDouble - converter from wideInt to double. diff --git a/generic/tclThreadTest.c b/generic/tclThreadTest.c index 9c66313..fcf3880 100644 --- a/generic/tclThreadTest.c +++ b/generic/tclThreadTest.c @@ -341,7 +341,7 @@ ThreadObjCmd( } else if (objc == 3 && strcmp("-main", Tcl_GetString(objv[2])) == 0) { Tcl_MutexLock(&threadMutex); - idObj = Tcl_NewLongObj((long)(size_t)mainThreadId); + idObj = Tcl_NewWideIntObj((Tcl_WideInt)(size_t)mainThreadId); Tcl_MutexUnlock(&threadMutex); } else { Tcl_WrongNumArgs(interp, 2, objv, NULL); -- cgit v0.12 From 0c0b1e14981ac6b1b9d1ba4f5f423b62a7f07cdb Mon Sep 17 00:00:00 2001 From: aspect Date: Mon, 27 Mar 2017 13:02:22 +0000 Subject: Correct this use of isWanted to ensure NO_IMPLEMENTATION methods are not listed (bug [900cb0284bc]) --- generic/tclOOCall.c | 1 + tests/oo.test | 38 ++++++++++++++++++++++++++++++++++++++ 2 files changed, 39 insertions(+) diff --git a/generic/tclOOCall.c b/generic/tclOOCall.c index 8003345..c861eb9 100644 --- a/generic/tclOOCall.c +++ b/generic/tclOOCall.c @@ -618,6 +618,7 @@ AddClassMethodNames( if (isNew) { int isWanted = (!(flags & PUBLIC_METHOD) || (mPtr->flags & PUBLIC_METHOD)) ? IN_LIST : 0; + isWanted |= (mPtr->typePtr == NULL ? NO_IMPLEMENTATION : 0); Tcl_SetHashValue(hPtr, INT2PTR(isWanted)); } else if ((PTR2INT(Tcl_GetHashValue(hPtr)) & NO_IMPLEMENTATION) diff --git a/tests/oo.test b/tests/oo.test index ccb05c1..290e41d 100644 --- a/tests/oo.test +++ b/tests/oo.test @@ -2242,6 +2242,44 @@ test oo-17.10 {OO: class introspection} -setup { info class methods foo -all } -result {} +test oo-17.11 {OO: object method unexport (bug 900cb0284bc)} -setup { + oo::object create o + oo::objdefine o unexport m +} -cleanup { + o destroy +} -body { + expr {"m" in [info object methods o -all -private]} +} -result 0 +test oo-17.12 {OO: instance method unexport (bug 900cb0284bc)} -setup { + oo::class create c + c create o + oo::objdefine o unexport m +} -cleanup { + o destroy + c destroy +} -body { + expr {"m" in [info object methods o -all -private]} +} -result 0 +test oo-17.13 {OO: class method unexport (bug 900cb0284bc)} -setup { + oo::class create c + oo::define c unexport m +} -cleanup { + c destroy +} -body { + expr {"m" in [info class methods c -all -private]} +} -result 0 +test oo-17.14 {OO: instance method unexport (bug 900cb0284bc)} -setup { + oo::class create c + oo::define c unexport m + c create o +} -cleanup { + o destroy + c destroy +} -body { + expr {"m" in [info object methods o -all -private]} +} -result 0 + + test oo-18.1 {OO: define command support} { list [catch {oo::define oo::object {error foo}} msg] $msg $errorInfo } {1 foo {foo -- cgit v0.12 From 24f5b98e8c8a4d160980f769e07bebe60f286eee Mon Sep 17 00:00:00 2001 From: "jan.nijtmans" Date: Wed, 29 Mar 2017 12:16:28 +0000 Subject: In comments and documentation, distinguish between __int64 (a Microsoft 64-bit integer type) and int64_t (C99 equivalent) --- doc/IntObj.3 | 2 +- generic/tclIO.c | 2 +- generic/tclStrToD.c | 4 ++-- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/doc/IntObj.3 b/doc/IntObj.3 index dc62642..2acb446 100644 --- a/doc/IntObj.3 +++ b/doc/IntObj.3 @@ -97,7 +97,7 @@ are provided by the C language standard. The \fBTcl_WideInt\fR type is a typedef defined to be whatever signed integral type covers at least the 64-bit integer range (-9223372036854775808 to 9223372036854775807). Depending on the platform and the C compiler, the actual type might be -\fBlong int\fR, \fBlong long int\fR, \fBint64\fR, or something else. +\fBlong int\fR, \fBlong long int\fR, \fB__int64\fR, or something else. The \fBmp_int\fR type is a multiple-precision integer type defined by the LibTomMath multiple-precision integer library. .PP diff --git a/generic/tclIO.c b/generic/tclIO.c index ffd2430..64501fd 100644 --- a/generic/tclIO.c +++ b/generic/tclIO.c @@ -9317,7 +9317,7 @@ MBWrite( * then the calculations involving extra must be made wide too. * * Noted with Win32/MSVC debug build treating the warning (possible of - * data in int64 to int conversion) as error. + * data in __int64 to int conversion) as error. */ bufPtr = AllocChannelBuffer(extra); diff --git a/generic/tclStrToD.c b/generic/tclStrToD.c index 6da6df3..67b6482 100644 --- a/generic/tclStrToD.c +++ b/generic/tclStrToD.c @@ -3798,7 +3798,7 @@ ShorteningBignumConversion( --s5; /* - * IDEA: It might possibly be a win to fall back to int64 + * IDEA: It might possibly be a win to fall back to int64_t * arithmetic here if S < 2**64/10. But it's a win only for * a fairly narrow range of magnitudes so perhaps not worth * bothering. We already know that we shorten the @@ -3963,7 +3963,7 @@ StrictBignumConversion( * As with the shortening bignum conversion, it's possible at this * point that we will have reduced the denominator to less than * 2**64/10, at which point it would be possible to fall back to - * to int64 arithmetic. But the potential payoff is tremendously + * to int64_t arithmetic. But the potential payoff is tremendously * less - unless we're working in F format - because we know that * three groups of digits will always suffice for %#.17e, the * longest format that doesn't introduce empty precision. -- cgit v0.12 From 0abecbc87da774aa9756a4ce64948de62419cc34 Mon Sep 17 00:00:00 2001 From: "jan.nijtmans" Date: Wed, 29 Mar 2017 14:53:54 +0000 Subject: Fix [4768eb5c166a1b923e3472d18d75fdccc1a47513|4768eb5c16]: format-8.20 failure. Since "%q" now is a valid length specifier, we cannot use it any more to test for "bad field specifier" --- tests/format.test | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/format.test b/tests/format.test index e199398..7186729 100644 --- a/tests/format.test +++ b/tests/format.test @@ -349,9 +349,9 @@ test format-8.19 {error conditions} { catch {format %q x} } 1 test format-8.20 {error conditions} { - catch {format %q x} msg + catch {format %r x} msg set msg -} {bad field specifier "q"} +} {bad field specifier "r"} test format-8.21 {error conditions} { catch {format %d} } 1 -- cgit v0.12 From 8dfdec39fdad708127121a63c2b9e0ca7cb4a0d2 Mon Sep 17 00:00:00 2001 From: dkf Date: Wed, 29 Mar 2017 19:05:17 +0000 Subject: Tweak to make tests a little clearer. --- generic/tclOOCall.c | 2 +- tests/oo.test | 26 +++++++++++++------------- 2 files changed, 14 insertions(+), 14 deletions(-) diff --git a/generic/tclOOCall.c b/generic/tclOOCall.c index c861eb9..ac0b94d 100644 --- a/generic/tclOOCall.c +++ b/generic/tclOOCall.c @@ -618,8 +618,8 @@ AddClassMethodNames( if (isNew) { int isWanted = (!(flags & PUBLIC_METHOD) || (mPtr->flags & PUBLIC_METHOD)) ? IN_LIST : 0; - isWanted |= (mPtr->typePtr == NULL ? NO_IMPLEMENTATION : 0); + isWanted |= (mPtr->typePtr == NULL ? NO_IMPLEMENTATION : 0); Tcl_SetHashValue(hPtr, INT2PTR(isWanted)); } else if ((PTR2INT(Tcl_GetHashValue(hPtr)) & NO_IMPLEMENTATION) && mPtr->typePtr != NULL) { diff --git a/tests/oo.test b/tests/oo.test index 290e41d..e03911b 100644 --- a/tests/oo.test +++ b/tests/oo.test @@ -2241,43 +2241,43 @@ test oo-17.10 {OO: class introspection} -setup { oo::define foo unexport {*}[info class methods foo -all] info class methods foo -all } -result {} - +set stdmethods { destroy eval unknown variable varname} test oo-17.11 {OO: object method unexport (bug 900cb0284bc)} -setup { oo::object create o oo::objdefine o unexport m +} -body { + lsort [info object methods o -all -private] } -cleanup { o destroy -} -body { - expr {"m" in [info object methods o -all -private]} -} -result 0 +} -result $stdmethods test oo-17.12 {OO: instance method unexport (bug 900cb0284bc)} -setup { oo::class create c c create o oo::objdefine o unexport m +} -body { + lsort [info object methods o -all -private] } -cleanup { o destroy c destroy -} -body { - expr {"m" in [info object methods o -all -private]} -} -result 0 +} -result $stdmethods test oo-17.13 {OO: class method unexport (bug 900cb0284bc)} -setup { oo::class create c oo::define c unexport m +} -body { + lsort [info class methods c -all -private] } -cleanup { c destroy -} -body { - expr {"m" in [info class methods c -all -private]} -} -result 0 +} -result $stdmethods test oo-17.14 {OO: instance method unexport (bug 900cb0284bc)} -setup { oo::class create c oo::define c unexport m c create o +} -body { + lsort [info object methods o -all -private] } -cleanup { o destroy c destroy -} -body { - expr {"m" in [info object methods o -all -private]} -} -result 0 +} -result $stdmethods test oo-18.1 {OO: define command support} { -- cgit v0.12 From c552943f9e361bd0e1facefafda71d3af4f991f3 Mon Sep 17 00:00:00 2001 From: dkf Date: Wed, 29 Mar 2017 19:16:32 +0000 Subject: [900cb0284bc] Ensure that masking pseudo-methods used for export management are not introspectable directly. [cherrypick] --- generic/tclOOCall.c | 1 + tests/oo.test | 37 +++++++++++++++++++++++++++++++++++++ 2 files changed, 38 insertions(+) diff --git a/generic/tclOOCall.c b/generic/tclOOCall.c index 8003345..ac0b94d 100644 --- a/generic/tclOOCall.c +++ b/generic/tclOOCall.c @@ -619,6 +619,7 @@ AddClassMethodNames( int isWanted = (!(flags & PUBLIC_METHOD) || (mPtr->flags & PUBLIC_METHOD)) ? IN_LIST : 0; + isWanted |= (mPtr->typePtr == NULL ? NO_IMPLEMENTATION : 0); Tcl_SetHashValue(hPtr, INT2PTR(isWanted)); } else if ((PTR2INT(Tcl_GetHashValue(hPtr)) & NO_IMPLEMENTATION) && mPtr->typePtr != NULL) { diff --git a/tests/oo.test b/tests/oo.test index 2601c37..cb37a76 100644 --- a/tests/oo.test +++ b/tests/oo.test @@ -2241,6 +2241,43 @@ test oo-17.10 {OO: class introspection} -setup { oo::define foo unexport {*}[info class methods foo -all] info class methods foo -all } -result {} +set stdmethods { destroy eval unknown variable varname} +test oo-17.11 {OO: object method unexport (bug 900cb0284bc)} -setup { + oo::object create o + oo::objdefine o unexport m +} -body { + lsort [info object methods o -all -private] +} -cleanup { + o destroy +} -result $stdmethods +test oo-17.12 {OO: instance method unexport (bug 900cb0284bc)} -setup { + oo::class create c + c create o + oo::objdefine o unexport m +} -body { + lsort [info object methods o -all -private] +} -cleanup { + o destroy + c destroy +} -result $stdmethods +test oo-17.13 {OO: class method unexport (bug 900cb0284bc)} -setup { + oo::class create c + oo::define c unexport m +} -body { + lsort [info class methods c -all -private] +} -cleanup { + c destroy +} -result $stdmethods +test oo-17.14 {OO: instance method unexport (bug 900cb0284bc)} -setup { + oo::class create c + oo::define c unexport m + c create o +} -body { + lsort [info object methods o -all -private] +} -cleanup { + o destroy + c destroy +} -result $stdmethods test oo-18.1 {OO: define command support} { list [catch {oo::define oo::object {error foo}} msg] $msg $errorInfo -- cgit v0.12 From ce7746b49e4fc37fb8b21d41292585113eaa940f Mon Sep 17 00:00:00 2001 From: "jan.nijtmans" Date: Fri, 31 Mar 2017 14:44:08 +0000 Subject: Since Tcl_AppendPrintfToObj() now understands the %p format, we can use it. Eliminating some internal string buffers. --- generic/tclDisassemble.c | 12 ++++-------- generic/tclObj.c | 21 +++++++++++---------- 2 files changed, 15 insertions(+), 18 deletions(-) diff --git a/generic/tclDisassemble.c b/generic/tclDisassemble.c index 0d6da8e..5e977e6 100644 --- a/generic/tclDisassemble.c +++ b/generic/tclDisassemble.c @@ -254,7 +254,6 @@ DisassembleByteCodeObj( int codeOffset, codeLen, srcOffset, srcLen, numCmds, delta, i, line; Interp *iPtr = (Interp *) *codePtr->interpHandle; Tcl_Obj *bufferObj, *fileObj; - char ptrBuf1[20], ptrBuf2[20]; TclNewObj(bufferObj); if (codePtr->refCount <= 0) { @@ -269,11 +268,9 @@ DisassembleByteCodeObj( * Print header lines describing the ByteCode. */ - sprintf(ptrBuf1, "%p", codePtr); - sprintf(ptrBuf2, "%p", iPtr); Tcl_AppendPrintfToObj(bufferObj, - "ByteCode 0x%s, refCt %u, epoch %u, interp 0x%s (epoch %u)\n", - ptrBuf1, codePtr->refCount, codePtr->compileEpoch, ptrBuf2, + "ByteCode %p, refCt %u, epoch %u, interp %p (epoch %u)\n", + codePtr, codePtr->refCount, codePtr->compileEpoch, iPtr, iPtr->compileEpoch); Tcl_AppendToObj(bufferObj, " Source ", -1); PrintSourceToObj(bufferObj, codePtr->source, @@ -316,10 +313,9 @@ DisassembleByteCodeObj( Proc *procPtr = codePtr->procPtr; int numCompiledLocals = procPtr->numCompiledLocals; - sprintf(ptrBuf1, "%p", procPtr); Tcl_AppendPrintfToObj(bufferObj, - " Proc 0x%s, refCt %d, args %d, compiled locals %d\n", - ptrBuf1, procPtr->refCount, procPtr->numArgs, + " Proc %p, refCt %d, args %d, compiled locals %d\n", + procPtr, procPtr->refCount, procPtr->numArgs, numCompiledLocals); if (numCompiledLocals > 0) { CompiledLocal *localPtr = procPtr->firstLocalPtr; diff --git a/generic/tclObj.c b/generic/tclObj.c index 8069a7c..dfcaff0 100644 --- a/generic/tclObj.c +++ b/generic/tclObj.c @@ -4455,7 +4455,6 @@ Tcl_RepresentationCmd( int objc, Tcl_Obj *const objv[]) { - char ptrBuffer[2*TCL_INTEGER_SPACE+6]; Tcl_Obj *descObj; if (objc != 2) { @@ -4469,18 +4468,20 @@ Tcl_RepresentationCmd( * "1872361827361287" */ - sprintf(ptrBuffer, "%p", (void *) objv[1]); descObj = Tcl_ObjPrintf("value is a %s with a refcount of %d," - " object pointer at %s", - objv[1]->typePtr ? objv[1]->typePtr->name : "pure string", - objv[1]->refCount, ptrBuffer); + " object pointer at %p", + objv[1]->typePtr ? objv[1]->typePtr->name : "pure string", + objv[1]->refCount, objv[1]); if (objv[1]->typePtr) { - sprintf(ptrBuffer, "%p:%p", - (void *) objv[1]->internalRep.twoPtrValue.ptr1, - (void *) objv[1]->internalRep.twoPtrValue.ptr2); - Tcl_AppendPrintfToObj(descObj, ", internal representation %s", - ptrBuffer); + if (objv[1]->typePtr == &tclDoubleType) { + Tcl_AppendPrintfToObj(descObj, ", internal representation %g", + objv[1]->internalRep.doubleValue); + } else { + Tcl_AppendPrintfToObj(descObj, ", internal representation %p:%p", + (void *) objv[1]->internalRep.twoPtrValue.ptr1, + (void *) objv[1]->internalRep.twoPtrValue.ptr2); + } } if (objv[1]->bytes) { -- cgit v0.12 From d10ba45b4b07890f74e2625560bfb21e8099e2d4 Mon Sep 17 00:00:00 2001 From: "jan.nijtmans" Date: Mon, 3 Apr 2017 11:53:34 +0000 Subject: Code optimization/reduction: If TCL_WIDE_INT_IS_LONG is defined, the variable useWide is always 0, so related code can be eliminated without loss of functionality. --- generic/tclStringObj.c | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-) diff --git a/generic/tclStringObj.c b/generic/tclStringObj.c index 91c0e74..4e19750 100644 --- a/generic/tclStringObj.c +++ b/generic/tclStringObj.c @@ -1702,8 +1702,11 @@ Tcl_AppendFormatToObj( while (*format != '\0') { char *end; - int gotMinus, gotHash, gotZero, gotSpace, gotPlus, sawFlag; - int width, gotPrecision, precision, useShort, useWide, useBig; + int gotMinus = 0, gotHash = 0, gotZero = 0, gotSpace = 0, gotPlus = 0; + int width, gotPrecision, precision, sawFlag, useShort = 0, useBig = 0; +#ifndef TCL_WIDE_INT_IS_LONG + int useWide = 0; +#endif int newXpg, numChars, allocSegment = 0, segmentLimit, segmentNumBytes; Tcl_Obj *segment; Tcl_UniChar ch; @@ -1779,7 +1782,6 @@ Tcl_AppendFormatToObj( * Step 2. Set of flags. */ - gotMinus = gotHash = gotZero = gotSpace = gotPlus = 0; sawFlag = 1; do { switch (ch) { @@ -1880,7 +1882,6 @@ Tcl_AppendFormatToObj( * Step 5. Length modifier. */ - useShort = useWide = useBig = 0; if (ch == 'h') { useShort = 1; format += step; @@ -1964,6 +1965,7 @@ Tcl_AppendFormatToObj( goto error; } isNegative = (mp_cmp_d(&big, 0) == MP_LT); +#ifndef TCL_WIDE_INT_IS_LONG } else if (useWide) { if (Tcl_GetWideIntFromObj(NULL, segment, &w) != TCL_OK) { Tcl_Obj *objPtr; @@ -1978,6 +1980,7 @@ Tcl_AppendFormatToObj( Tcl_DecrRefCount(objPtr); } isNegative = (w < (Tcl_WideInt) 0); +#endif } else if (TclGetLongFromObj(NULL, segment, &l) != TCL_OK) { if (Tcl_GetWideIntFromObj(NULL, segment, &w) != TCL_OK) { Tcl_Obj *objPtr; @@ -2044,8 +2047,10 @@ Tcl_AppendFormatToObj( if (useShort) { pure = Tcl_NewIntObj((int) s); +#ifndef TCL_WIDE_INT_IS_LONG } else if (useWide) { pure = Tcl_NewWideIntObj(w); +#endif } else if (useBig) { pure = Tcl_NewBignumObj(&big); } else { @@ -2128,6 +2133,7 @@ Tcl_AppendFormatToObj( numDigits++; us /= base; } +#ifndef TCL_WIDE_INT_IS_LONG } else if (useWide) { Tcl_WideUInt uw = (Tcl_WideUInt) w; @@ -2136,6 +2142,7 @@ Tcl_AppendFormatToObj( numDigits++; uw /= base; } +#endif } else if (useBig && big.used) { int leftover = (big.used * DIGIT_BIT) % numBits; mp_digit mask = (~(mp_digit)0) << (DIGIT_BIT-leftover); @@ -2328,7 +2335,7 @@ Tcl_AppendFormatToObj( } } - Tcl_GetStringFromObj(segment, &segmentNumBytes); + TclGetStringFromObj(segment, &segmentNumBytes); if (segmentNumBytes > limit) { if (allocSegment) { Tcl_DecrRefCount(segment); -- cgit v0.12 -- cgit v0.12 From 72ac20b7d7e65869c797750d7aad03dc0aed22bf Mon Sep 17 00:00:00 2001 From: sebres Date: Tue, 4 Apr 2017 11:13:36 +0000 Subject: bug fix for [42202ba1e5ff566e0f9abb9f890e460fbc6c1c5c]: segfault by coro inject rewritten callback for ::tcl::unsupported::inject, without leave the interpreter in unusable state (inaccurate environment exchange by adding eval callback), test covered now. --- generic/tclBasic.c | 32 +++++++++++++++++++++++++++++++- tests/coroutine.test | 39 +++++++++++++++++++++++++++++++++++++++ 2 files changed, 70 insertions(+), 1 deletion(-) diff --git a/generic/tclBasic.c b/generic/tclBasic.c index 4bddbce..f604ac1 100644 --- a/generic/tclBasic.c +++ b/generic/tclBasic.c @@ -8748,6 +8748,35 @@ TclNRCoroutineActivateCallback( /* *---------------------------------------------------------------------- * + * TclNREvalList -- + * + * Callback to invoke command as list, used in order to delayed + * processing of canonical list command in sane environment. + * + *---------------------------------------------------------------------- + */ + +static int +TclNREvalList( + ClientData data[], + Tcl_Interp *interp, + int result) +{ + int objc; + Tcl_Obj **objv; + Tcl_Obj *listPtr = data[0]; + + Tcl_IncrRefCount(listPtr); + + TclMarkTailcall(interp); + TclNRAddCallback(interp, TclNRReleaseValues, listPtr, NULL, NULL,NULL); + TclListObjGetElements(NULL, listPtr, &objc, &objv); + return TclNREvalObjv(interp, objc, objv, 0, NULL); +} + +/* + *---------------------------------------------------------------------- + * * NRCoroInjectObjCmd -- * * Implementation of [::tcl::unsupported::inject] command. @@ -8799,7 +8828,8 @@ NRCoroInjectObjCmd( */ iPtr->execEnvPtr = corPtr->eePtr; - TclNREvalObjEx(interp, Tcl_NewListObj(objc-2, objv+2), 0, NULL, INT_MIN); + TclNRAddCallback(interp, TclNREvalList, Tcl_NewListObj(objc-2, objv+2), + NULL, NULL, NULL); iPtr->execEnvPtr = savedEEPtr; return TCL_OK; diff --git a/tests/coroutine.test b/tests/coroutine.test index 205da67..fd68567 100644 --- a/tests/coroutine.test +++ b/tests/coroutine.test @@ -741,6 +741,45 @@ test coroutine-7.12 {coro floor above street level #3008307} -body { list } -result {} +test coroutine-8.0.0 {coro inject executed} -body { + coroutine demo apply {{} { foreach i {1 2} yield }} + demo + set ::result none + tcl::unsupported::inject demo set ::result inject-executed + demo + set ::result +} -result {inject-executed} +test coroutine-8.0.1 {coro inject after error} -body { + coroutine demo apply {{} { foreach i {1 2} yield; error test }} + demo + set ::result none + tcl::unsupported::inject demo set ::result inject-executed + lappend ::result [catch {demo} err] $err +} -result {inject-executed 1 test} +test coroutine-8.1.1 {coro inject, ticket 42202ba1e5ff566e} -body { + interp create slave + slave eval { + coroutine demo apply {{} { while {1} yield }} + demo + tcl::unsupported::inject demo set ::result inject-executed + } + interp delete slave +} -result {} +test coroutine-8.1.2 {coro inject with result, ticket 42202ba1e5ff566e} -body { + interp create slave + slave eval { + coroutine demo apply {{} { while {1} yield }} + demo + tcl::unsupported::inject demo set ::result inject-executed + } + slave eval demo + set result [slave eval {set ::result}] + + interp delete slave + set result +} -result {inject-executed} + + # cleanup unset lambda -- cgit v0.12 From ea8cb9b7bbc9be827be479c3aad3700cbe5774a4 Mon Sep 17 00:00:00 2001 From: "jan.nijtmans" Date: Wed, 5 Apr 2017 08:41:48 +0000 Subject: Fix [4b12ccb3363e81b132e8dbe12aeec596102be1a8|4b12ccb336]: format/scan %llu doesn't work. Also added new test-cases showing the expected behavior. --- generic/tclScan.c | 21 +++++++++++++-------- generic/tclStringObj.c | 14 +++++++++----- tests/format.test | 6 ++++++ tests/scan.test | 13 +++++++++++++ 4 files changed, 41 insertions(+), 13 deletions(-) diff --git a/generic/tclScan.c b/generic/tclScan.c index 3edb8be..5ea7e46 100644 --- a/generic/tclScan.c +++ b/generic/tclScan.c @@ -10,6 +10,7 @@ */ #include "tclInt.h" +#include "tommath.h" /* * Flag values used by Tcl_ScanObjCmd. @@ -415,14 +416,7 @@ ValidateFormat( case 'x': case 'X': case 'b': - break; case 'u': - if (flags & SCAN_BIG) { - Tcl_SetObjResult(interp, Tcl_NewStringObj( - "unsigned bignum scans are invalid", -1)); - Tcl_SetErrorCode(interp, "TCL", "FORMAT", "BADUNSIGNED",NULL); - goto error; - } break; /* * Bracket terms need special checking @@ -936,7 +930,18 @@ Tcl_ScanObjCmd( } else { Tcl_SetWideIntObj(objPtr, wideValue); } - } else if (!(flags & SCAN_BIG)) { + } else if (flags & SCAN_BIG) { + if (flags & SCAN_UNSIGNED) { + mp_int big; + if ((Tcl_GetBignumFromObj(interp, objPtr, &big) != TCL_OK) + || (mp_cmp_d(&big, 0) == MP_LT)) { + Tcl_SetObjResult(interp, Tcl_NewStringObj( + "unsigned bignum scans are invalid", -1)); + Tcl_SetErrorCode(interp, "TCL", "FORMAT", "BADUNSIGNED",NULL); + return TCL_ERROR; + } + } + } else { if (TclGetLongFromObj(NULL, objPtr, &value) != TCL_OK) { if (TclGetString(objPtr)[0] == '-') { value = LONG_MIN; diff --git a/generic/tclStringObj.c b/generic/tclStringObj.c index 4e19750..6cce073 100644 --- a/generic/tclStringObj.c +++ b/generic/tclStringObj.c @@ -1943,11 +1943,6 @@ Tcl_AppendFormatToObj( } case 'u': - if (useBig) { - msg = "unsigned bignum format is invalid"; - errCode = "BADUNSIGNED"; - goto errorMsg; - } case 'd': case 'o': case 'x': @@ -1965,6 +1960,15 @@ Tcl_AppendFormatToObj( goto error; } isNegative = (mp_cmp_d(&big, 0) == MP_LT); + if (ch == 'u') { + if (isNegative) { + msg = "unsigned bignum format is invalid"; + errCode = "BADUNSIGNED"; + goto errorMsg; + } else { + ch = 'd'; + } + } #ifndef TCL_WIDE_INT_IS_LONG } else if (useWide) { if (Tcl_GetWideIntFromObj(NULL, segment, &w) != TCL_OK) { diff --git a/tests/format.test b/tests/format.test index e199398..dbf6af0 100644 --- a/tests/format.test +++ b/tests/format.test @@ -528,6 +528,12 @@ test format-17.3 {testing %ld with non-wide} {wideIs64bit} { test format-17.4 {testing %l with non-integer} { format %lf 1 } 1.000000 +test format-17.5 {testing %llu with bignum} { + format %llu 0xabcdef0123456789abcdef +} 207698809136909011942886895 +test format-17.6 {testing %llu with negative number} -body { + format %llu -1 +} -returnCodes 1 -result {unsigned bignum format is invalid} test format-18.1 {do not demote existing numeric values} { set a 0xaaaaaaaa diff --git a/tests/scan.test b/tests/scan.test index 7540c9c..8ddb595 100644 --- a/tests/scan.test +++ b/tests/scan.test @@ -541,6 +541,19 @@ test scan-5.15 {Bug be003d570f} { test scan-5.16 {Bug be003d570f} { scan 0x40 %b } 0 +test scan-5.17 {bigint scanning} -setup { + set a {}; set b {}; set c {}; set d {} +} -body { + list [scan "207698809136909011942886895,207698809136909011942886895,abcdef0123456789abcdef,125715736004432126361152746757" \ + %llu,%lld,%llx,%llo a b c d] $a $b $c $d +} -result {4 207698809136909011942886895 207698809136909011942886895 207698809136909011942886895 207698809136909011942886895} +test scan-5.18 {bigint scanning underflow} -setup { + set a {}; +} -body { + list [scan "-207698809136909011942886895" \ + %llu a] $a +} -returnCodes 1 -result {unsigned bignum scans are invalid} + test scan-6.1 {floating-point scanning} -setup { set a {}; set b {}; set c {}; set d {} -- cgit v0.12 From 14192d21ddce62aa6d4736302ae3711fceb4c5ae Mon Sep 17 00:00:00 2001 From: sebres Date: Wed, 5 Apr 2017 10:40:29 +0000 Subject: Contributed by "stanko" as patch within 8bd13f07bde6fb0631f27927e36461fdefe8ca95 Resolves blocking of pipes-thread (reader/writer) under huge last: Terminating threads during their initialization resp. teardown phase may result LoaderLock in the ntdll.dll's (to remain locked indefinitely). This causes ntdll.dll's LdrpInitializeThread() to deadlock trying to acquire LoaderLock. Possible fix for 9d75181ee70af318830e99ede6ebb5df72a9b079 --- win/tclWinConsole.c | 53 +++++++++++++++++++++++++++++++-- win/tclWinPipe.c | 84 +++++++++++++++++++++++++++++++++++++++++++++++++---- win/tclWinSerial.c | 41 ++++++++++++++++++++++++-- 3 files changed, 167 insertions(+), 11 deletions(-) diff --git a/win/tclWinConsole.c b/win/tclWinConsole.c index ab55035..5c0b43b 100644 --- a/win/tclWinConsole.c +++ b/win/tclWinConsole.c @@ -51,6 +51,8 @@ TCL_DECLARE_MUTEX(consoleMutex) typedef struct ConsoleThreadInfo { HANDLE thread; /* Handle to reader or writer thread. */ + HANDLE threadInitialized; /* Manual-reset event to signal that thread has been initialized. */ + int threadExiting; /* Boolean indicating that thread is exiting. */ HANDLE readyEvent; /* Manual-reset event to signal _to_ the main * thread when the worker thread has finished * waiting for its normal work to happen. */ @@ -536,9 +538,12 @@ StartChannelThread( threadInfoPtr->readyEvent = CreateEvent(NULL, TRUE, TRUE, NULL); threadInfoPtr->startEvent = CreateEvent(NULL, FALSE, FALSE, NULL); + threadInfoPtr->threadInitialized = CreateEvent(NULL, TRUE, FALSE, NULL); + threadInfoPtr->threadExiting = FALSE; threadInfoPtr->stopEvent = CreateEvent(NULL, FALSE, FALSE, NULL); threadInfoPtr->thread = CreateThread(NULL, 256, threadProc, infoPtr, 0, &id); + WaitForSingleObject(threadInfoPtr->threadInitialized, INFINITE); /* wait for thread to initialize */ SetThreadPriority(threadInfoPtr->thread, THREAD_PRIORITY_HIGHEST); } @@ -572,11 +577,28 @@ StopChannelThread( * Note that we need to guard against terminating the thread while * it is in the middle of Tcl_ThreadAlert because it won't be able * to release the notifier lock. + * + * Also note that terminating threads during their initialization or teardown phase + * may result in ntdll.dll's LoaderLock to remain locked indefinitely. + * This causes ntdll.dll's LdrpInitializeThread() to deadlock trying to acquire LoaderLock. + * LdrpInitializeThread() is executed within new threads to perform + * initialization and to execute DllMain() of all loaded dlls. + * As a result, all new threads are deadlocked in their initialization phase and never execute, + * even though CreateThread() reports successful thread creation. + * This results in a very weird process-wide behavior, which is extremely hard to debug. + * + * THREADS SHOULD NEVER BE TERMINATED. Period. + * + * But for now, check if thread is exiting, and if so, let it die peacefully. */ Tcl_MutexLock(&consoleMutex); - /* BUG: this leaks memory. */ - TerminateThread(threadInfoPtr->thread, 0); + if ( threadInfoPtr->threadExiting ) { + WaitForSingleObject(threadInfoPtr->thread, INFINITE); + } else { + /* BUG: this leaks memory. */ + TerminateThread(threadInfoPtr->thread, 0); + } Tcl_MutexUnlock(&consoleMutex); } } @@ -587,6 +609,7 @@ StopChannelThread( */ CloseHandle(threadInfoPtr->thread); + CloseHandle(threadInfoPtr->threadInitialized); CloseHandle(threadInfoPtr->readyEvent); CloseHandle(threadInfoPtr->startEvent); CloseHandle(threadInfoPtr->stopEvent); @@ -1186,6 +1209,11 @@ ConsoleReaderThread( HANDLE wEvents[2]; /* + * Notify StartChannelThread() that this thread is initialized + */ + SetEvent(threadInfo->threadInitialized); + + /* * The first event takes precedence. */ @@ -1253,6 +1281,14 @@ ConsoleReaderThread( Tcl_MutexUnlock(&consoleMutex); } + /* + * Inform StopChannelThread() that this thread should not be terminated, since it is about to exit. + * See comment in StopChannelThread() for reasons. + */ + Tcl_MutexLock(&consoleMutex); + threadInfo->threadExiting = TRUE; + Tcl_MutexUnlock(&consoleMutex); + return 0; } @@ -1287,6 +1323,11 @@ ConsoleWriterThread( HANDLE wEvents[2]; /* + * Notify StartChannelThread() that this thread is initialized + */ + SetEvent(threadInfo->threadInitialized); + + /* * The first event takes precedence. */ @@ -1351,6 +1392,14 @@ ConsoleWriterThread( Tcl_MutexUnlock(&consoleMutex); } + /* + * Inform StopChannelThread() that this thread should not be terminated, since it is about to exit. + * See comment in StopChannelThread() for reasons. + */ + Tcl_MutexLock(&consoleMutex); + threadInfo->threadExiting = TRUE; + Tcl_MutexUnlock(&consoleMutex); + return 0; } diff --git a/win/tclWinPipe.c b/win/tclWinPipe.c index 4666deb..9677792 100644 --- a/win/tclWinPipe.c +++ b/win/tclWinPipe.c @@ -111,6 +111,10 @@ typedef struct PipeInfo { * threads. */ HANDLE writeThread; /* Handle to writer thread. */ HANDLE readThread; /* Handle to reader thread. */ + HANDLE writeThreadInitialized; /* Manual-reset event to signal that writer thread has been initialized */ + HANDLE readThreadInitialized; /* Manual-reset event to signal that reader thread has been initialized */ + int writeThreadExiting; /* Boolean indicating that write thread is exiting */ + int readThreadExiting; /* Boolean indicating that read thread is exiting */ HANDLE writable; /* Manual-reset event to signal when the * writer thread has finished waiting for the * current buffer to be written. */ @@ -1601,8 +1605,11 @@ TclpCreateCommandChannel( infoPtr->readable = CreateEvent(NULL, TRUE, TRUE, NULL); infoPtr->startReader = CreateEvent(NULL, FALSE, FALSE, NULL); infoPtr->stopReader = CreateEvent(NULL, TRUE, FALSE, NULL); + infoPtr->readThreadInitialized = CreateEvent(NULL, TRUE, FALSE, NULL); + infoPtr->readThreadExiting = FALSE; infoPtr->readThread = CreateThread(NULL, 256, PipeReaderThread, infoPtr, 0, &id); + WaitForSingleObject(infoPtr->readThreadInitialized, INFINITE); /* wait for thread to initialize */ SetThreadPriority(infoPtr->readThread, THREAD_PRIORITY_HIGHEST); infoPtr->validMask |= TCL_READABLE; } else { @@ -1616,8 +1623,11 @@ TclpCreateCommandChannel( infoPtr->writable = CreateEvent(NULL, TRUE, TRUE, NULL); infoPtr->startWriter = CreateEvent(NULL, FALSE, FALSE, NULL); infoPtr->stopWriter = CreateEvent(NULL, TRUE, FALSE, NULL); + infoPtr->writeThreadInitialized = CreateEvent(NULL, TRUE, FALSE, NULL); + infoPtr->writeThreadExiting = FALSE; infoPtr->writeThread = CreateThread(NULL, 256, PipeWriterThread, infoPtr, 0, &id); + WaitForSingleObject(infoPtr->writeThreadInitialized, INFINITE); /* wait for thread to initialize */ SetThreadPriority(infoPtr->readThread, THREAD_PRIORITY_HIGHEST); infoPtr->validMask |= TCL_WRITABLE; } @@ -1853,17 +1863,35 @@ PipeClose2Proc( * Note that we need to guard against terminating the * thread while it is in the middle of Tcl_ThreadAlert * because it won't be able to release the notifier lock. + * + * Also note that terminating threads during their initialization or teardown phase + * may result in ntdll.dll's LoaderLock to remain locked indefinitely. + * This causes ntdll.dll's LdrpInitializeThread() to deadlock trying to acquire LoaderLock. + * LdrpInitializeThread() is executed within new threads to perform + * initialization and to execute DllMain() of all loaded dlls. + * As a result, all new threads are deadlocked in their initialization phase and never execute, + * even though CreateThread() reports successful thread creation. + * This results in a very weird process-wide behavior, which is extremely hard to debug. + * + * THREADS SHOULD NEVER BE TERMINATED. Period. + * + * But for now, check if thread is exiting, and if so, let it die peacefully. */ Tcl_MutexLock(&pipeMutex); - /* BUG: this leaks memory */ - TerminateThread(pipePtr->readThread, 0); + if ( pipePtr->readThreadExiting ) { + WaitForSingleObject(pipePtr->readThread, INFINITE); + } else { + /* BUG: this leaks memory */ + TerminateThread(pipePtr->readThread, 0); + } Tcl_MutexUnlock(&pipeMutex); } } CloseHandle(pipePtr->readThread); + CloseHandle(pipePtr->readThreadInitialized); CloseHandle(pipePtr->readable); CloseHandle(pipePtr->startReader); CloseHandle(pipePtr->stopReader); @@ -1909,8 +1937,8 @@ PipeClose2Proc( if (exitCode == STILL_ACTIVE) { /* - * Set the stop event so that if the reader thread is blocked - * in PipeReaderThread on WaitForMultipleEvents, it will exit + * Set the stop event so that if the writer thread is blocked + * in PipeWriterThread on WaitForMultipleEvents, it will exit * cleanly. */ @@ -1935,17 +1963,35 @@ PipeClose2Proc( * Note that we need to guard against terminating the * thread while it is in the middle of Tcl_ThreadAlert * because it won't be able to release the notifier lock. + * + * Also note that terminating threads during their initialization or teardown phase + * may result in ntdll.dll's LoaderLock to remain locked indefinitely. + * This causes ntdll.dll's LdrpInitializeThread() to deadlock trying to acquire LoaderLock. + * LdrpInitializeThread() is executed within new threads to perform + * initialization and to execute DllMain() of all loaded dlls. + * As a result, all new threads are deadlocked in their initialization phase and never execute, + * even though CreateThread() reports successful thread creation. + * This results in a very weird process-wide behavior, which is extremely hard to debug. + * + * THREADS SHOULD NEVER BE TERMINATED. Period. + * + * But for now, check if thread is exiting, and if so, let it die peacefully. */ Tcl_MutexLock(&pipeMutex); - /* BUG: this leaks memory */ - TerminateThread(pipePtr->writeThread, 0); + if ( pipePtr->writeThreadExiting ) { + WaitForSingleObject(pipePtr->writeThread, INFINITE); + } else { + /* BUG: this leaks memory */ + TerminateThread(pipePtr->writeThread, 0); + } Tcl_MutexUnlock(&pipeMutex); } } CloseHandle(pipePtr->writeThread); + CloseHandle(pipePtr->writeThreadInitialized); CloseHandle(pipePtr->writable); CloseHandle(pipePtr->startWriter); CloseHandle(pipePtr->stopWriter); @@ -2821,6 +2867,11 @@ PipeReaderThread( HANDLE wEvents[2]; DWORD waitResult; + /* + * Let TclpCreateCommandChannel() know that this thread has been initialized + */ + SetEvent(infoPtr->readThreadInitialized); + wEvents[0] = infoPtr->stopReader; wEvents[1] = infoPtr->startReader; @@ -2913,6 +2964,14 @@ PipeReaderThread( Tcl_MutexUnlock(&pipeMutex); } + /* + * Inform PipeClose2Proc() that this thread should not be terminated, since it is about to exit. + * See comment in PipeClose2Proc() for reasons. + */ + Tcl_MutexLock(&pipeMutex); + infoPtr->readThreadExiting = TRUE; + Tcl_MutexUnlock(&pipeMutex); + return 0; } @@ -2945,6 +3004,11 @@ PipeWriterThread( HANDLE wEvents[2]; DWORD waitResult; + /* + * Let TclpCreateCommandChannel() know that this thread has been initialized + */ + SetEvent(infoPtr->writeThreadInitialized); + wEvents[0] = infoPtr->stopWriter; wEvents[1] = infoPtr->startWriter; @@ -3011,6 +3075,14 @@ PipeWriterThread( Tcl_MutexUnlock(&pipeMutex); } + /* + * Inform PipeClose2Proc() that this thread should not be terminated, since it is about to exit. + * See comment in PipeClose2Proc() for reasons. + */ + Tcl_MutexLock(&pipeMutex); + infoPtr->writeThreadExiting = TRUE; + Tcl_MutexUnlock(&pipeMutex); + return 0; } diff --git a/win/tclWinSerial.c b/win/tclWinSerial.c index 0730a46..3c6a3cc 100644 --- a/win/tclWinSerial.c +++ b/win/tclWinSerial.c @@ -94,6 +94,8 @@ typedef struct SerialInfo { OVERLAPPED osRead; /* OVERLAPPED structure for read operations. */ OVERLAPPED osWrite; /* OVERLAPPED structure for write operations */ HANDLE writeThread; /* Handle to writer thread. */ + HANDLE writeThreadInitialized; /* Manual-reset event to signal that thread has been initialized. */ + int writeThreadExiting; /* Boolean indicating that thread is exiting. */ CRITICAL_SECTION csWrite; /* Writer thread synchronisation. */ HANDLE evWritable; /* Manual-reset event to signal when the * writer thread has finished waiting for the @@ -643,18 +645,35 @@ SerialCloseProc( * Note that we need to guard against terminating the thread * while it is in the middle of Tcl_ThreadAlert because it * won't be able to release the notifier lock. + * + * Also note that terminating threads during their initialization or teardown phase + * may result in ntdll.dll's LoaderLock to remain locked indefinitely. + * This causes ntdll.dll's LdrpInitializeThread() to deadlock trying to acquire LoaderLock. + * LdrpInitializeThread() is executed within new threads to perform + * initialization and to execute DllMain() of all loaded dlls. + * As a result, all new threads are deadlocked in their initialization phase and never execute, + * even though CreateThread() reports successful thread creation. + * This results in a very weird process-wide behavior, which is extremely hard to debug. + * + * THREADS SHOULD NEVER BE TERMINATED. Period. + * + * But for now, check if thread is exiting, and if so, let it die peacefully. */ Tcl_MutexLock(&serialMutex); - /* BUG: this leaks memory */ - TerminateThread(serialPtr->writeThread, 0); - + if ( serialPtr->writeThreadExiting ) { + WaitForSingleObject(serialPtr->writeThread, INFINITE); + } else { + /* BUG: this leaks memory. */ + TerminateThread(serialPtr->writeThread, 0); + } Tcl_MutexUnlock(&serialMutex); } } CloseHandle(serialPtr->writeThread); + CloseHandle(serialPtr->writeThreadInitialized); CloseHandle(serialPtr->osWrite.hEvent); CloseHandle(serialPtr->evWritable); CloseHandle(serialPtr->evStartWriter); @@ -1320,6 +1339,11 @@ SerialWriterThread( HANDLE wEvents[2]; /* + * Notify TclWinOpenSerialChannel() that this thread is initialized + */ + SetEvent(infoPtr->writeThreadInitialized); + + /* * The stop event takes precedence by being first in the list. */ @@ -1404,6 +1428,14 @@ SerialWriterThread( Tcl_MutexUnlock(&serialMutex); } + /* + * Inform SerialCloseProc() that this thread should not be terminated, since it is about to exit. + * See comment in SerialCloseProc() for reasons. + */ + Tcl_MutexLock(&serialMutex); + infoPtr->writeThreadExiting = TRUE; + Tcl_MutexUnlock(&serialMutex); + return 0; } @@ -1531,8 +1563,11 @@ TclWinOpenSerialChannel( infoPtr->evWritable = CreateEvent(NULL, TRUE, TRUE, NULL); infoPtr->evStartWriter = CreateEvent(NULL, FALSE, FALSE, NULL); infoPtr->evStopWriter = CreateEvent(NULL, FALSE, FALSE, NULL); + infoPtr->writeThreadInitialized = CreateEvent(NULL, TRUE, FALSE, NULL); + infoPtr->writeThreadExiting = FALSE; infoPtr->writeThread = CreateThread(NULL, 256, SerialWriterThread, infoPtr, 0, &id); + WaitForSingleObject(infoPtr->writeThreadInitialized, INFINITE); /* wait for thread to initialize */ } /* -- cgit v0.12 From b9cc513f2fc6fc01a9c999ce5397d77a74221742 Mon Sep 17 00:00:00 2001 From: sebres Date: Wed, 5 Apr 2017 10:40:51 +0000 Subject: small review: rewritten using already available event handles, additionally prevents infinite waits (using timeout 5000ms); --- win/tclWinConsole.c | 55 +++++++++++++++++++--------------- win/tclWinPipe.c | 85 +++++++++++++++++++++++++++++------------------------ win/tclWinSerial.c | 34 ++++++++++----------- 3 files changed, 94 insertions(+), 80 deletions(-) diff --git a/win/tclWinConsole.c b/win/tclWinConsole.c index 5c0b43b..42bc56f 100644 --- a/win/tclWinConsole.c +++ b/win/tclWinConsole.c @@ -51,14 +51,14 @@ TCL_DECLARE_MUTEX(consoleMutex) typedef struct ConsoleThreadInfo { HANDLE thread; /* Handle to reader or writer thread. */ - HANDLE threadInitialized; /* Manual-reset event to signal that thread has been initialized. */ int threadExiting; /* Boolean indicating that thread is exiting. */ HANDLE readyEvent; /* Manual-reset event to signal _to_ the main * thread when the worker thread has finished * waiting for its normal work to happen. */ HANDLE startEvent; /* Auto-reset event used by the main thread to * signal when the thread should attempt to do - * its normal work. */ + * its normal work. Additionally this event + * used as wait for thread event (init phase). */ HANDLE stopEvent; /* Auto-reset event used by the main thread to * signal when the thread should exit. */ } ConsoleThreadInfo; @@ -538,12 +538,10 @@ StartChannelThread( threadInfoPtr->readyEvent = CreateEvent(NULL, TRUE, TRUE, NULL); threadInfoPtr->startEvent = CreateEvent(NULL, FALSE, FALSE, NULL); - threadInfoPtr->threadInitialized = CreateEvent(NULL, TRUE, FALSE, NULL); threadInfoPtr->threadExiting = FALSE; threadInfoPtr->stopEvent = CreateEvent(NULL, FALSE, FALSE, NULL); threadInfoPtr->thread = CreateThread(NULL, 256, threadProc, infoPtr, 0, &id); - WaitForSingleObject(threadInfoPtr->threadInitialized, INFINITE); /* wait for thread to initialize */ SetThreadPriority(threadInfoPtr->thread, THREAD_PRIORITY_HIGHEST); } @@ -592,14 +590,14 @@ StopChannelThread( * But for now, check if thread is exiting, and if so, let it die peacefully. */ - Tcl_MutexLock(&consoleMutex); - if ( threadInfoPtr->threadExiting ) { - WaitForSingleObject(threadInfoPtr->thread, INFINITE); - } else { - /* BUG: this leaks memory. */ - TerminateThread(threadInfoPtr->thread, 0); + if ( !threadInfoPtr->threadExiting + || WaitForSingleObject(threadInfoPtr->thread, 5000) != WAIT_OBJECT_0 + ) { + Tcl_MutexLock(&consoleMutex); + /* BUG: this leaks memory. */ + TerminateThread(threadInfoPtr->thread, 0); + Tcl_MutexUnlock(&consoleMutex); } - Tcl_MutexUnlock(&consoleMutex); } } @@ -609,7 +607,6 @@ StopChannelThread( */ CloseHandle(threadInfoPtr->thread); - CloseHandle(threadInfoPtr->threadInitialized); CloseHandle(threadInfoPtr->readyEvent); CloseHandle(threadInfoPtr->startEvent); CloseHandle(threadInfoPtr->stopEvent); @@ -1209,9 +1206,10 @@ ConsoleReaderThread( HANDLE wEvents[2]; /* - * Notify StartChannelThread() that this thread is initialized + * Notify caller (using startEvent) that this thread is initialized */ - SetEvent(threadInfo->threadInitialized); + SetEvent(threadInfo->startEvent); + SuspendThread(threadInfo->thread); /* until main thread get an event */ /* * The first event takes precedence. @@ -1282,12 +1280,10 @@ ConsoleReaderThread( } /* - * Inform StopChannelThread() that this thread should not be terminated, since it is about to exit. + * Inform caller that this thread should not be terminated, since it is about to exit. * See comment in StopChannelThread() for reasons. */ - Tcl_MutexLock(&consoleMutex); threadInfo->threadExiting = TRUE; - Tcl_MutexUnlock(&consoleMutex); return 0; } @@ -1323,9 +1319,10 @@ ConsoleWriterThread( HANDLE wEvents[2]; /* - * Notify StartChannelThread() that this thread is initialized + * Notify caller (using startEvent) that this thread is initialized */ - SetEvent(threadInfo->threadInitialized); + SetEvent(threadInfo->startEvent); + SuspendThread(threadInfo->thread); /* until main thread get an event */ /* * The first event takes precedence. @@ -1393,12 +1390,10 @@ ConsoleWriterThread( } /* - * Inform StopChannelThread() that this thread should not be terminated, since it is about to exit. + * Inform caller that this thread should not be terminated, since it is about to exit. * See comment in StopChannelThread() for reasons. */ - Tcl_MutexLock(&consoleMutex); threadInfo->threadExiting = TRUE; - Tcl_MutexUnlock(&consoleMutex); return 0; } @@ -1429,7 +1424,8 @@ TclWinOpenConsoleChannel( { char encoding[4 + TCL_INTEGER_SPACE]; ConsoleInfo *infoPtr; - DWORD modes; + DWORD modes, wEventsCnt = 0; + HANDLE wEvents[2], wEventsPtr = wEvents; ConsoleInit(); @@ -1471,12 +1467,25 @@ TclWinOpenConsoleChannel( modes |= ENABLE_LINE_INPUT; SetConsoleMode(infoPtr->handle, modes); StartChannelThread(infoPtr, &infoPtr->reader, ConsoleReaderThread); + wEvents[wEventsCnt++] = infoPtr->reader.startEvent; } if (permissions & TCL_WRITABLE) { StartChannelThread(infoPtr, &infoPtr->writer, ConsoleWriterThread); + wEvents[wEventsCnt++] = infoPtr->writer.startEvent; } + /* + * Wait for both threads to initialize (using theirs startEvent) + */ + if (wEventsCnt) { + WaitForMultipleObjects(wEventsCnt, wEvents, TRUE, 5000); + /* Resume both waiting threads */ + if (infoPtr->reader.thread) + ResumeThread(infoPtr->reader.thread); + if (infoPtr->writer.thread) + ResumeThread(infoPtr->writer.thread); + } /* * Files have default translation of AUTO and ^Z eof char, which means * that a ^Z will be accepted as EOF when reading. diff --git a/win/tclWinPipe.c b/win/tclWinPipe.c index 9677792..48dcc25 100644 --- a/win/tclWinPipe.c +++ b/win/tclWinPipe.c @@ -111,10 +111,8 @@ typedef struct PipeInfo { * threads. */ HANDLE writeThread; /* Handle to writer thread. */ HANDLE readThread; /* Handle to reader thread. */ - HANDLE writeThreadInitialized; /* Manual-reset event to signal that writer thread has been initialized */ - HANDLE readThreadInitialized; /* Manual-reset event to signal that reader thread has been initialized */ - int writeThreadExiting; /* Boolean indicating that write thread is exiting */ - int readThreadExiting; /* Boolean indicating that read thread is exiting */ + int writeThreadExiting; /* Boolean indicating that write thread is exiting */ + int readThreadExiting; /* Boolean indicating that read thread is exiting */ HANDLE writable; /* Manual-reset event to signal when the * writer thread has finished waiting for the * current buffer to be written. */ @@ -123,12 +121,14 @@ typedef struct PipeInfo { * input. */ HANDLE startWriter; /* Auto-reset event used by the main thread to * signal when the writer thread should - * attempt to write to the pipe. */ + * attempt to write to the pipe. Additionally + * this event used as wait for thread event (init). */ HANDLE stopWriter; /* Manual-reset event used to alert the reader * thread to fall-out and exit */ HANDLE startReader; /* Auto-reset event used by the main thread to * signal when the reader thread should - * attempt to read from the pipe. */ + * attempt to read from the pipe. Additionally + * this event used as wait for thread event (init). */ HANDLE stopReader; /* Manual-reset event used to alert the reader * thread to fall-out and exit */ DWORD writeError; /* An error caused by the last background @@ -1575,7 +1575,8 @@ TclpCreateCommandChannel( Tcl_Pid *pidPtr) /* An array of process identifiers. */ { char channelName[16 + TCL_INTEGER_SPACE]; - DWORD id; + DWORD id, wEventsCnt = 0; + HANDLE wEvents[2]; PipeInfo *infoPtr = ckalloc(sizeof(PipeInfo)); PipeInit(); @@ -1605,13 +1606,12 @@ TclpCreateCommandChannel( infoPtr->readable = CreateEvent(NULL, TRUE, TRUE, NULL); infoPtr->startReader = CreateEvent(NULL, FALSE, FALSE, NULL); infoPtr->stopReader = CreateEvent(NULL, TRUE, FALSE, NULL); - infoPtr->readThreadInitialized = CreateEvent(NULL, TRUE, FALSE, NULL); infoPtr->readThreadExiting = FALSE; infoPtr->readThread = CreateThread(NULL, 256, PipeReaderThread, infoPtr, 0, &id); - WaitForSingleObject(infoPtr->readThreadInitialized, INFINITE); /* wait for thread to initialize */ SetThreadPriority(infoPtr->readThread, THREAD_PRIORITY_HIGHEST); infoPtr->validMask |= TCL_READABLE; + wEvents[wEventsCnt++] = infoPtr->startReader; } else { infoPtr->readThread = 0; } @@ -1623,13 +1623,26 @@ TclpCreateCommandChannel( infoPtr->writable = CreateEvent(NULL, TRUE, TRUE, NULL); infoPtr->startWriter = CreateEvent(NULL, FALSE, FALSE, NULL); infoPtr->stopWriter = CreateEvent(NULL, TRUE, FALSE, NULL); - infoPtr->writeThreadInitialized = CreateEvent(NULL, TRUE, FALSE, NULL); infoPtr->writeThreadExiting = FALSE; infoPtr->writeThread = CreateThread(NULL, 256, PipeWriterThread, infoPtr, 0, &id); - WaitForSingleObject(infoPtr->writeThreadInitialized, INFINITE); /* wait for thread to initialize */ SetThreadPriority(infoPtr->readThread, THREAD_PRIORITY_HIGHEST); infoPtr->validMask |= TCL_WRITABLE; + wEvents[wEventsCnt++] = infoPtr->startWriter; + } else { + infoPtr->writeThread = 0; + } + + /* + * Wait for both threads to initialize (using theirs start-events) + */ + if (wEventsCnt) { + WaitForMultipleObjects(wEventsCnt, wEvents, TRUE, 5000); + /* Resume both waiting threads */ + if (infoPtr->readThread) + ResumeThread(infoPtr->readThread); + if (infoPtr->writeThread) + ResumeThread(infoPtr->writeThread); } /* @@ -1878,20 +1891,18 @@ PipeClose2Proc( * But for now, check if thread is exiting, and if so, let it die peacefully. */ - Tcl_MutexLock(&pipeMutex); - - if ( pipePtr->readThreadExiting ) { - WaitForSingleObject(pipePtr->readThread, INFINITE); - } else { - /* BUG: this leaks memory */ - TerminateThread(pipePtr->readThread, 0); + if ( !pipePtr->readThreadExiting + || WaitForSingleObject(pipePtr->readThread, 5000) != WAIT_OBJECT_0 + ) { + Tcl_MutexLock(&pipeMutex); + /* BUG: this leaks memory */ + TerminateThread(pipePtr->readThread, 0); + Tcl_MutexUnlock(&pipeMutex); } - Tcl_MutexUnlock(&pipeMutex); } } CloseHandle(pipePtr->readThread); - CloseHandle(pipePtr->readThreadInitialized); CloseHandle(pipePtr->readable); CloseHandle(pipePtr->startReader); CloseHandle(pipePtr->stopReader); @@ -1978,20 +1989,18 @@ PipeClose2Proc( * But for now, check if thread is exiting, and if so, let it die peacefully. */ - Tcl_MutexLock(&pipeMutex); - - if ( pipePtr->writeThreadExiting ) { - WaitForSingleObject(pipePtr->writeThread, INFINITE); - } else { - /* BUG: this leaks memory */ - TerminateThread(pipePtr->writeThread, 0); + if ( !pipePtr->writeThreadExiting + || WaitForSingleObject(pipePtr->writeThread, 5000) != WAIT_OBJECT_0 + ) { + Tcl_MutexLock(&pipeMutex); + /* BUG: this leaks memory */ + TerminateThread(pipePtr->writeThread, 0); + Tcl_MutexUnlock(&pipeMutex); } - Tcl_MutexUnlock(&pipeMutex); } } CloseHandle(pipePtr->writeThread); - CloseHandle(pipePtr->writeThreadInitialized); CloseHandle(pipePtr->writable); CloseHandle(pipePtr->startWriter); CloseHandle(pipePtr->stopWriter); @@ -2868,9 +2877,10 @@ PipeReaderThread( DWORD waitResult; /* - * Let TclpCreateCommandChannel() know that this thread has been initialized + * Notify caller that this thread has been initialized */ - SetEvent(infoPtr->readThreadInitialized); + SetEvent(infoPtr->startReader); + SuspendThread(infoPtr->readThread); /* until main thread get an event */ wEvents[0] = infoPtr->stopReader; wEvents[1] = infoPtr->startReader; @@ -2965,12 +2975,10 @@ PipeReaderThread( } /* - * Inform PipeClose2Proc() that this thread should not be terminated, since it is about to exit. + * Inform caller that this thread should not be terminated, since it is about to exit. * See comment in PipeClose2Proc() for reasons. */ - Tcl_MutexLock(&pipeMutex); infoPtr->readThreadExiting = TRUE; - Tcl_MutexUnlock(&pipeMutex); return 0; } @@ -3005,9 +3013,10 @@ PipeWriterThread( DWORD waitResult; /* - * Let TclpCreateCommandChannel() know that this thread has been initialized + * Notify caller that this thread has been initialized */ - SetEvent(infoPtr->writeThreadInitialized); + SetEvent(infoPtr->startWriter); + SuspendThread(infoPtr->writeThread); /* until main thread get an event */ wEvents[0] = infoPtr->stopWriter; wEvents[1] = infoPtr->startWriter; @@ -3076,12 +3085,10 @@ PipeWriterThread( } /* - * Inform PipeClose2Proc() that this thread should not be terminated, since it is about to exit. + * Inform caller that this thread should not be terminated, since it is about to exit. * See comment in PipeClose2Proc() for reasons. */ - Tcl_MutexLock(&pipeMutex); infoPtr->writeThreadExiting = TRUE; - Tcl_MutexUnlock(&pipeMutex); return 0; } diff --git a/win/tclWinSerial.c b/win/tclWinSerial.c index 3c6a3cc..fa135ab 100644 --- a/win/tclWinSerial.c +++ b/win/tclWinSerial.c @@ -94,15 +94,15 @@ typedef struct SerialInfo { OVERLAPPED osRead; /* OVERLAPPED structure for read operations. */ OVERLAPPED osWrite; /* OVERLAPPED structure for write operations */ HANDLE writeThread; /* Handle to writer thread. */ - HANDLE writeThreadInitialized; /* Manual-reset event to signal that thread has been initialized. */ - int writeThreadExiting; /* Boolean indicating that thread is exiting. */ + int writeThreadExiting; /* Boolean indicating that thread is exiting. */ CRITICAL_SECTION csWrite; /* Writer thread synchronisation. */ HANDLE evWritable; /* Manual-reset event to signal when the * writer thread has finished waiting for the * current buffer to be written. */ HANDLE evStartWriter; /* Auto-reset event used by the main thread to * signal when the writer thread should - * attempt to write to the serial. */ + * attempt to write to the serial. Additionally + * this event used as wait for thread event (init). */ HANDLE evStopWriter; /* Auto-reset event used by the main thread to * signal when the writer thread should close. */ @@ -660,20 +660,18 @@ SerialCloseProc( * But for now, check if thread is exiting, and if so, let it die peacefully. */ - Tcl_MutexLock(&serialMutex); - - if ( serialPtr->writeThreadExiting ) { - WaitForSingleObject(serialPtr->writeThread, INFINITE); - } else { - /* BUG: this leaks memory. */ - TerminateThread(serialPtr->writeThread, 0); + if ( !serialPtr->writeThreadExiting + || WaitForSingleObject(serialPtr->writeThread, 5000) != WAIT_OBJECT_0 + ) { + Tcl_MutexLock(&serialMutex); + /* BUG: this leaks memory. */ + TerminateThread(serialPtr->writeThread, 0); + Tcl_MutexUnlock(&serialMutex); } - Tcl_MutexUnlock(&serialMutex); } } CloseHandle(serialPtr->writeThread); - CloseHandle(serialPtr->writeThreadInitialized); CloseHandle(serialPtr->osWrite.hEvent); CloseHandle(serialPtr->evWritable); CloseHandle(serialPtr->evStartWriter); @@ -1341,7 +1339,8 @@ SerialWriterThread( /* * Notify TclWinOpenSerialChannel() that this thread is initialized */ - SetEvent(infoPtr->writeThreadInitialized); + SetEvent(infoPtr->evStartWriter); + SuspendThread(infoPtr->writeThread); /* until main thread get an event */ /* * The stop event takes precedence by being first in the list. @@ -1429,12 +1428,10 @@ SerialWriterThread( } /* - * Inform SerialCloseProc() that this thread should not be terminated, since it is about to exit. + * Inform caller that this thread should not be terminated, since it is about to exit. * See comment in SerialCloseProc() for reasons. */ - Tcl_MutexLock(&serialMutex); infoPtr->writeThreadExiting = TRUE; - Tcl_MutexUnlock(&serialMutex); return 0; } @@ -1563,11 +1560,12 @@ TclWinOpenSerialChannel( infoPtr->evWritable = CreateEvent(NULL, TRUE, TRUE, NULL); infoPtr->evStartWriter = CreateEvent(NULL, FALSE, FALSE, NULL); infoPtr->evStopWriter = CreateEvent(NULL, FALSE, FALSE, NULL); - infoPtr->writeThreadInitialized = CreateEvent(NULL, TRUE, FALSE, NULL); infoPtr->writeThreadExiting = FALSE; infoPtr->writeThread = CreateThread(NULL, 256, SerialWriterThread, infoPtr, 0, &id); - WaitForSingleObject(infoPtr->writeThreadInitialized, INFINITE); /* wait for thread to initialize */ + /* Wait for thread to initialize (using evStartWriter) */ + WaitForSingleObject(infoPtr->evStartWriter, 5000); + ResumeThread(infoPtr->writeThread); } /* -- cgit v0.12 From 2ae10f0b3391991adbe6138238681d4d0f3ead11 Mon Sep 17 00:00:00 2001 From: sebres Date: Wed, 5 Apr 2017 10:41:05 +0000 Subject: fix typo-bug (using wrong thread handle by set priority) --- win/tclWinPipe.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/win/tclWinPipe.c b/win/tclWinPipe.c index 48dcc25..fce039c 100644 --- a/win/tclWinPipe.c +++ b/win/tclWinPipe.c @@ -1626,7 +1626,7 @@ TclpCreateCommandChannel( infoPtr->writeThreadExiting = FALSE; infoPtr->writeThread = CreateThread(NULL, 256, PipeWriterThread, infoPtr, 0, &id); - SetThreadPriority(infoPtr->readThread, THREAD_PRIORITY_HIGHEST); + SetThreadPriority(infoPtr->writeThread, THREAD_PRIORITY_HIGHEST); infoPtr->validMask |= TCL_WRITABLE; wEvents[wEventsCnt++] = infoPtr->startWriter; } else { -- cgit v0.12 From 55edd253ffe75b5f8d2a8a2501a966f81515659a Mon Sep 17 00:00:00 2001 From: max Date: Wed, 5 Apr 2017 14:47:45 +0000 Subject: Use a random unused port for the dummy http server to avoid conflicts with local services running on port 8010. --- tests/http.test | 8 ++------ tests/httpd | 7 ++++++- tests/httpold.test | 6 +++--- 3 files changed, 11 insertions(+), 10 deletions(-) diff --git a/tests/http.test b/tests/http.test index 12ad475..75c963d 100644 --- a/tests/http.test +++ b/tests/http.test @@ -36,7 +36,6 @@ proc bgerror {args} { puts stderr $errorInfo } -set port 8010 set bindata "This is binary data\x0d\x0amore\x0dmore\x0amore\x00null" catch {unset data} @@ -55,9 +54,8 @@ catch {package require Thread 2.7-} if {[catch {package present Thread}] == 0 && [file exists $httpdFile]} { set httpthread [thread::create -preserved] thread::send $httpthread [list source $httpdFile] - thread::send $httpthread [list set port $port] thread::send $httpthread [list set bindata $bindata] - thread::send $httpthread {httpd_init $port} + thread::send $httpthread {httpd_init 0; set port} port puts "Running httpd in thread $httpthread" } else { if {![file exists $httpdFile]} { @@ -69,10 +67,8 @@ if {[catch {package present Thread}] == 0 && [file exists $httpdFile]} { # Let the OS pick the port; that's much more flexible if {[catch {httpd_init 0} listen]} { puts "Cannot start http server, http test skipped" - unset port + catch {unset port} return - } else { - set port [lindex [fconfigure $listen -sockname] 2] } } diff --git a/tests/httpd b/tests/httpd index 40e10df..f15d71b 100644 --- a/tests/httpd +++ b/tests/httpd @@ -11,7 +11,12 @@ #set httpLog 1 proc httpd_init {{port 8015}} { - socket -server httpdAccept $port + set s [socket -server httpdAccept $port] + # Save the actual port number in a global variable. + # This is important when we're called with port 0 + # for picking an unused port at random. + set ::port [lindex [chan configure $s -sockname] 2] + return $s } proc httpd_log {args} { global httpLog diff --git a/tests/httpold.test b/tests/httpold.test index 5995bed..ab26613 100644 --- a/tests/httpold.test +++ b/tests/httpold.test @@ -1,3 +1,4 @@ +# -*- tcl -*- # Commands covered: http_config, http_get, http_wait, http_reset # # This file contains a collection of tests for the http script library. @@ -41,10 +42,9 @@ catch {unset data} ## source [file join [file dirname [info script]] httpd] -set port 8010 -if [catch {httpd_init $port} listen] { +if [catch {httpd_init 0} listen] { puts "Cannot start http server, http test skipped" - unset port + catch {unset port} ::tcltest::cleanupTests return } -- cgit v0.12 From ceb75ca9ffc56aa82860dae87970bee9d91914f3 Mon Sep 17 00:00:00 2001 From: sebres Date: Wed, 5 Apr 2017 19:52:23 +0000 Subject: the same handling to initialize thread without suspend/resume helpers (otherwise may be dangerous by very huge resp. too busy system); --- win/tclWinConsole.c | 12 +++++------- win/tclWinPipe.c | 14 +++++++------- win/tclWinSerial.c | 6 +++--- 3 files changed, 15 insertions(+), 17 deletions(-) diff --git a/win/tclWinConsole.c b/win/tclWinConsole.c index 42bc56f..d4893ee 100644 --- a/win/tclWinConsole.c +++ b/win/tclWinConsole.c @@ -1208,8 +1208,7 @@ ConsoleReaderThread( /* * Notify caller (using startEvent) that this thread is initialized */ - SetEvent(threadInfo->startEvent); - SuspendThread(threadInfo->thread); /* until main thread get an event */ + SignalObjectAndWait(threadInfo->startEvent, threadInfo->stopEvent, INFINITE, FALSE); /* * The first event takes precedence. @@ -1321,8 +1320,7 @@ ConsoleWriterThread( /* * Notify caller (using startEvent) that this thread is initialized */ - SetEvent(threadInfo->startEvent); - SuspendThread(threadInfo->thread); /* until main thread get an event */ + SignalObjectAndWait(threadInfo->startEvent, threadInfo->stopEvent, INFINITE, FALSE); /* * The first event takes precedence. @@ -1480,11 +1478,11 @@ TclWinOpenConsoleChannel( */ if (wEventsCnt) { WaitForMultipleObjects(wEventsCnt, wEvents, TRUE, 5000); - /* Resume both waiting threads */ + /* Resume both waiting threads, we've get the events */ if (infoPtr->reader.thread) - ResumeThread(infoPtr->reader.thread); + SetEvent(infoPtr->reader.stopEvent); if (infoPtr->writer.thread) - ResumeThread(infoPtr->writer.thread); + SetEvent(infoPtr->writer.stopEvent); } /* * Files have default translation of AUTO and ^Z eof char, which means diff --git a/win/tclWinPipe.c b/win/tclWinPipe.c index fce039c..523d4eb 100644 --- a/win/tclWinPipe.c +++ b/win/tclWinPipe.c @@ -1638,11 +1638,11 @@ TclpCreateCommandChannel( */ if (wEventsCnt) { WaitForMultipleObjects(wEventsCnt, wEvents, TRUE, 5000); - /* Resume both waiting threads */ + /* Resume both waiting threads, we've get the events */ if (infoPtr->readThread) - ResumeThread(infoPtr->readThread); + SetEvent(infoPtr->stopReader); if (infoPtr->writeThread) - ResumeThread(infoPtr->writeThread); + SetEvent(infoPtr->stopWriter); } /* @@ -2879,8 +2879,8 @@ PipeReaderThread( /* * Notify caller that this thread has been initialized */ - SetEvent(infoPtr->startReader); - SuspendThread(infoPtr->readThread); /* until main thread get an event */ + SignalObjectAndWait(infoPtr->startReader, infoPtr->stopReader, INFINITE, FALSE); + ResetEvent(infoPtr->stopReader); /* not auto-reset */ wEvents[0] = infoPtr->stopReader; wEvents[1] = infoPtr->startReader; @@ -3015,8 +3015,8 @@ PipeWriterThread( /* * Notify caller that this thread has been initialized */ - SetEvent(infoPtr->startWriter); - SuspendThread(infoPtr->writeThread); /* until main thread get an event */ + SignalObjectAndWait(infoPtr->startWriter, infoPtr->stopWriter, INFINITE, FALSE); + ResetEvent(infoPtr->stopWriter); /* not auto-reset */ wEvents[0] = infoPtr->stopWriter; wEvents[1] = infoPtr->startWriter; diff --git a/win/tclWinSerial.c b/win/tclWinSerial.c index fa135ab..f55f5f1 100644 --- a/win/tclWinSerial.c +++ b/win/tclWinSerial.c @@ -1339,8 +1339,7 @@ SerialWriterThread( /* * Notify TclWinOpenSerialChannel() that this thread is initialized */ - SetEvent(infoPtr->evStartWriter); - SuspendThread(infoPtr->writeThread); /* until main thread get an event */ + SignalObjectAndWait(infoPtr->evStartWriter, infoPtr->evStopWriter, INFINITE, FALSE); /* * The stop event takes precedence by being first in the list. @@ -1565,7 +1564,8 @@ TclWinOpenSerialChannel( infoPtr, 0, &id); /* Wait for thread to initialize (using evStartWriter) */ WaitForSingleObject(infoPtr->evStartWriter, 5000); - ResumeThread(infoPtr->writeThread); + /* Wake-up it to signal we've get an event */ + SetEvent(infoPtr->evStopWriter); } /* -- cgit v0.12 From 44de3dd8dad74f8031286f0750738099156cef0c Mon Sep 17 00:00:00 2001 From: "jan.nijtmans" Date: Thu, 6 Apr 2017 11:13:22 +0000 Subject: If compiled with TCL_NO_DEPRECATED, the functions TclpGetDate/TclpLocaltime/TclpGmtime can be removed: They are internal and not used for anything any more. --- generic/tclBasic.c | 2 +- generic/tclStubInit.c | 22 ++++++++++++---------- tools/tcltk-man2html.tcl | 2 +- unix/tclUnixTime.c | 7 +++++++ win/tclWinTime.c | 8 ++++++++ 5 files changed, 29 insertions(+), 12 deletions(-) diff --git a/generic/tclBasic.c b/generic/tclBasic.c index 8e816a5..b29e19e 100644 --- a/generic/tclBasic.c +++ b/generic/tclBasic.c @@ -5880,7 +5880,6 @@ Tcl_Eval( (void) Tcl_GetStringResult(interp); return code; } -#endif /* TCL_NO_DEPRECATED */ /* *---------------------------------------------------------------------- @@ -5915,6 +5914,7 @@ Tcl_GlobalEvalObj( { return Tcl_EvalObjEx(interp, objPtr, TCL_EVAL_GLOBAL); } +#endif /* TCL_NO_DEPRECATED */ /* *---------------------------------------------------------------------- diff --git a/generic/tclStubInit.c b/generic/tclStubInit.c index 7957389..3f0a8ff 100644 --- a/generic/tclStubInit.c +++ b/generic/tclStubInit.c @@ -287,17 +287,9 @@ static int formatInt(char *buffer, int n){ } #define TclFormatInt (int(*)(char *, long))formatInt -#endif +#endif /* TCL_WIDE_INT_IS_LONG */ -#else /* UNIX and MAC */ -# ifdef TCL_NO_DEPRECATED -# define TclpLocaltime_unix 0 -# define TclpGmtime_unix 0 -# else -# define TclpLocaltime_unix TclpLocaltime -# define TclpGmtime_unix TclpGmtime -# endif -#endif +#endif /* __CYGWIN__ */ #ifdef TCL_NO_DEPRECATED # define Tcl_SeekOld 0 @@ -351,9 +343,19 @@ static int formatInt(char *buffer, int n){ # define Tcl_EvalObj 0 # undef Tcl_GlobalEvalObj # define Tcl_GlobalEvalObj 0 +# undef TclpGetDate +# define TclpGetDate 0 +# undef TclpLocaltime +# define TclpLocaltime 0 +# undef TclpGmtime +# define TclpGmtime 0 +# define TclpLocaltime_unix 0 +# define TclpGmtime_unix 0 #else /* TCL_NO_DEPRECATED */ # define Tcl_SeekOld seekOld # define Tcl_TellOld tellOld +# define TclpLocaltime_unix TclpLocaltime +# define TclpGmtime_unix TclpGmtime static int seekOld( diff --git a/tools/tcltk-man2html.tcl b/tools/tcltk-man2html.tcl index 9a372b7..7ec6365 100755 --- a/tools/tcltk-man2html.tcl +++ b/tools/tcltk-man2html.tcl @@ -4,7 +4,7 @@ if {[catch {package require Tcl 8.6-} msg]} { puts stderr "ERROR: $msg" puts stderr "If running this script from 'make html', set the\ NATIVE_TCLSH environment\nvariable to point to an installed\ - tclsh8.6 (or the equivalent tclsh86.exe\non Windows)." + tclsh8.7 (or the equivalent tclsh87.exe\non Windows)." exit 1 } diff --git a/unix/tclUnixTime.c b/unix/tclUnixTime.c index d634449..6a73ac2 100644 --- a/unix/tclUnixTime.c +++ b/unix/tclUnixTime.c @@ -22,6 +22,7 @@ * variable is the key to this buffer. */ +#ifndef TCL_NO_DEPRECATED static Tcl_ThreadDataKey tmKey; typedef struct { struct tm gmtime_buf; @@ -45,6 +46,8 @@ static char *lastTZ = NULL; /* Holds the last setting of the TZ static void SetTZIfNecessary(void); static void CleanupMemory(ClientData clientData); +#endif /* TCL_NO_DEPRECATED */ + static void NativeScaleTime(Tcl_Time *timebuf, ClientData clientData); static void NativeGetTime(Tcl_Time *timebuf, @@ -263,6 +266,7 @@ Tcl_GetTime( *---------------------------------------------------------------------- */ +#ifndef TCL_NO_DEPRECATED struct tm * TclpGetDate( const time_t *time, @@ -352,6 +356,7 @@ TclpLocaltime( return &tsdPtr->localtime_buf; } +#endif /* TCL_NO_DEPRECATED */ /* *---------------------------------------------------------------------- @@ -486,6 +491,7 @@ NativeGetTime( *---------------------------------------------------------------------- */ +#ifndef TCL_NO_DEPRECATED static void SetTZIfNecessary(void) { @@ -531,6 +537,7 @@ CleanupMemory( { ckfree(lastTZ); } +#endif /* TCL_NO_DEPRECATED */ /* * Local Variables: diff --git a/win/tclWinTime.c b/win/tclWinTime.c index 81d9458..18702e7 100644 --- a/win/tclWinTime.c +++ b/win/tclWinTime.c @@ -27,6 +27,7 @@ * month, where index 1 is January. */ +#ifndef TCL_NO_DEPRECATED static const int normalDays[] = { -1, 30, 58, 89, 119, 150, 180, 211, 242, 272, 303, 333, 364 }; @@ -40,6 +41,7 @@ typedef struct { struct tm tm; /* time information */ } ThreadSpecificData; static Tcl_ThreadDataKey dataKey; +#endif /* TCL_NO_DEPRECATED */ /* * Data for managing high-resolution timers. @@ -113,7 +115,9 @@ static TimeInfo timeInfo = { * Declarations for functions defined later in this file. */ +#ifndef TCL_NO_DEPRECATED static struct tm * ComputeGMT(const time_t *tp); +#endif /* TCL_NO_DEPRECATED */ static void StopCalibration(ClientData clientData); static DWORD WINAPI CalibrationThread(LPVOID arg); static void UpdateTimeEachSecond(void); @@ -522,6 +526,7 @@ StopCalibration( *---------------------------------------------------------------------- */ +#ifndef TCL_NO_DEPRECATED struct tm * TclpGetDate( const time_t *t, @@ -724,6 +729,7 @@ ComputeGMT( return tmPtr; } +#endif /* TCL_NO_DEPRECATED */ /* *---------------------------------------------------------------------- @@ -1068,6 +1074,7 @@ AccumulateSample( *---------------------------------------------------------------------- */ +#ifndef TCL_NO_DEPRECATED struct tm * TclpGmtime( const time_t *timePtr) /* Pointer to the number of seconds since the @@ -1112,6 +1119,7 @@ TclpLocaltime( return localtime(timePtr); } +#endif /* TCL_NO_DEPRECATED */ /* *---------------------------------------------------------------------- -- cgit v0.12 From 904733362eb59a805100de75715e20a5214a98f2 Mon Sep 17 00:00:00 2001 From: "jan.nijtmans" Date: Thu, 6 Apr 2017 15:25:44 +0000 Subject: Some more (internal) stub entries which can be cleaned up with -DTCL_NO_DEPRECATED, because they are not used any more. --- generic/tclStubInit.c | 20 ++++++++++++++++++-- tools/tcltk-man2html.tcl | 2 +- unix/tclUnixThrd.c | 2 ++ win/tclWinSock.c | 2 ++ 4 files changed, 23 insertions(+), 3 deletions(-) diff --git a/generic/tclStubInit.c b/generic/tclStubInit.c index 3f0a8ff..59325b7 100644 --- a/generic/tclStubInit.c +++ b/generic/tclStubInit.c @@ -41,15 +41,15 @@ #undef Tcl_FindExecutable #undef TclpGetPid #undef TclSockMinimumBuffers -#define TclBackgroundException Tcl_BackgroundException #undef Tcl_SetIntObj #undef TclpInetNtoa #undef TclWinGetServByName #undef TclWinGetSockOpt #undef TclWinSetSockOpt +#undef TclWinNToHS /* See bug 510001: TclSockMinimumBuffers needs plat imp */ -#ifdef _WIN64 +#if defined(_WIN64) || defined(TCL_NO_DEPRECATED) # define TclSockMinimumBuffersOld 0 #else #define TclSockMinimumBuffersOld sockMinimumBuffersOld @@ -59,6 +59,17 @@ static int TclSockMinimumBuffersOld(int sock, int size) } #endif +#if defined(TCL_NO_DEPRECATED) +# define TclSetStartupScriptPath 0 +# define TclGetStartupScriptPath 0 +# define TclSetStartupScriptFileName 0 +# define TclGetStartupScriptFileName 0 +# define TclpInetNtoa 0 +# define TclWinGetServByName 0 +# define TclWinGetSockOpt 0 +# define TclWinSetSockOpt 0 +# define TclWinNToHS 0 +#else #define TclSetStartupScriptPath setStartupScriptPath static void TclSetStartupScriptPath(Tcl_Obj *path) { @@ -92,6 +103,7 @@ static unsigned short TclWinNToHS(unsigned short ns) { return ntohs(ns); } #endif +#endif /* TCL_NO_DEPRECATED */ #ifdef _WIN32 # define TclUnixWaitForFile 0 @@ -343,6 +355,9 @@ static int formatInt(char *buffer, int n){ # define Tcl_EvalObj 0 # undef Tcl_GlobalEvalObj # define Tcl_GlobalEvalObj 0 +# define TclBackgroundException 0 +# undef TclpReaddir +# define TclpReaddir 0 # undef TclpGetDate # define TclpGetDate 0 # undef TclpLocaltime @@ -354,6 +369,7 @@ static int formatInt(char *buffer, int n){ #else /* TCL_NO_DEPRECATED */ # define Tcl_SeekOld seekOld # define Tcl_TellOld tellOld +# define TclBackgroundException Tcl_BackgroundException # define TclpLocaltime_unix TclpLocaltime # define TclpGmtime_unix TclpGmtime diff --git a/tools/tcltk-man2html.tcl b/tools/tcltk-man2html.tcl index 7ec6365..5d21866 100755 --- a/tools/tcltk-man2html.tcl +++ b/tools/tcltk-man2html.tcl @@ -22,7 +22,7 @@ if {[catch {package require Tcl 8.6-} msg]} { # Copyright (c) 1995-1997 Roger E. Critchlow Jr # Copyright (c) 2004-2010 Donal K. Fellows -set ::Version "50/8.6" +set ::Version "50/8.7" set ::CSSFILE "docs.css" ## diff --git a/unix/tclUnixThrd.c b/unix/tclUnixThrd.c index 805599d..f475aed 100644 --- a/unix/tclUnixThrd.c +++ b/unix/tclUnixThrd.c @@ -644,6 +644,7 @@ TclpFinalizeCondition( *---------------------------------------------------------------------- */ +#ifndef TCL_NO_DEPRECATED Tcl_DirEntry * TclpReaddir( DIR * dir) @@ -666,6 +667,7 @@ TclpInetNtoa( return inet_ntoa(addr); #endif } +#endif /* TCL_NO_DEPRECATED */ #ifdef TCL_THREADS /* diff --git a/win/tclWinSock.c b/win/tclWinSock.c index 5e0d7c8..81a5449 100644 --- a/win/tclWinSock.c +++ b/win/tclWinSock.c @@ -3239,6 +3239,7 @@ FindFDInList( *---------------------------------------------------------------------- */ +#ifndef TCL_NO_DEPRECATED #undef TclWinGetSockOpt int TclWinGetSockOpt( @@ -3278,6 +3279,7 @@ TclWinGetServByName( { return getservbyname(name, proto); } +#endif /* TCL_NO_DEPRECATED */ /* *---------------------------------------------------------------------- -- cgit v0.12 From ff4b11441b14dae3eb536004db30a89fa64e365a Mon Sep 17 00:00:00 2001 From: "jan.nijtmans" Date: Fri, 7 Apr 2017 15:11:47 +0000 Subject: Minor simplification in tcl.h: For the Tcl_WideAsLong/Tcl_LongAsWide/Tcl_WideAsDouble/Tcl_DoubleAsWide #defines, one set suffices: No need to have two versions depending on TCL_WIDE_INT_IS_LONG. --- generic/tcl.h | 13 +++++-------- 1 file changed, 5 insertions(+), 8 deletions(-) diff --git a/generic/tcl.h b/generic/tcl.h index 731724e..6ec47c6 100644 --- a/generic/tcl.h +++ b/generic/tcl.h @@ -419,10 +419,6 @@ typedef TCL_WIDE_INT_TYPE Tcl_WideInt; typedef unsigned TCL_WIDE_INT_TYPE Tcl_WideUInt; #ifdef TCL_WIDE_INT_IS_LONG -# define Tcl_WideAsLong(val) ((long)(val)) -# define Tcl_LongAsWide(val) ((long)(val)) -# define Tcl_WideAsDouble(val) ((double)((long)(val))) -# define Tcl_DoubleAsWide(val) ((long)((double)(val))) # ifndef TCL_LL_MODIFIER # define TCL_LL_MODIFIER "l" # endif /* !TCL_LL_MODIFIER */ @@ -434,12 +430,13 @@ typedef unsigned TCL_WIDE_INT_TYPE Tcl_WideUInt; # ifndef TCL_LL_MODIFIER # define TCL_LL_MODIFIER "ll" # endif /* !TCL_LL_MODIFIER */ -# define Tcl_WideAsLong(val) ((long)((Tcl_WideInt)(val))) -# define Tcl_LongAsWide(val) ((Tcl_WideInt)((long)(val))) -# define Tcl_WideAsDouble(val) ((double)((Tcl_WideInt)(val))) -# define Tcl_DoubleAsWide(val) ((Tcl_WideInt)((double)(val))) #endif /* TCL_WIDE_INT_IS_LONG */ +#define Tcl_WideAsLong(val) ((long)((Tcl_WideInt)(val))) +#define Tcl_LongAsWide(val) ((Tcl_WideInt)((long)(val))) +#define Tcl_WideAsDouble(val) ((double)((Tcl_WideInt)(val))) +#define Tcl_DoubleAsWide(val) ((Tcl_WideInt)((double)(val))) + #if defined(_WIN32) # ifdef __BORLANDC__ typedef struct stati64 Tcl_StatBuf; -- cgit v0.12 From d00198bd14d66e196b9640683d02023b8a0b2dd7 Mon Sep 17 00:00:00 2001 From: dkf Date: Sun, 9 Apr 2017 16:51:27 +0000 Subject: Minor style issues through the socket implementation code. --- generic/tclIOCmd.c | 40 ++-- generic/tclIOSock.c | 27 ++- unix/tclUnixSock.c | 276 ++++++++++++++----------- win/tclWinSock.c | 578 +++++++++++++++++++++++++++++++++------------------- 4 files changed, 573 insertions(+), 348 deletions(-) diff --git a/generic/tclIOCmd.c b/generic/tclIOCmd.c index 1bd3fe7..e52200d 100644 --- a/generic/tclIOCmd.c +++ b/generic/tclIOCmd.c @@ -1618,19 +1618,34 @@ Tcl_SocketObjCmd( return TCL_ERROR; } - // Set the options to their default value if the user didn't override their - // value. - if (reusep == -1) reusep = 0; - if (reusea == -1) reusea = 1; + /* + * Set the options to their default value if the user didn't override + * their value. + */ - // Build the bitset with the flags values. - if (reusea) + if (reusep == -1) { + reusep = 0; + } + if (reusea == -1) { + reusea = 1; + } + + /* + * Build the bitset with the flags values. + */ + + if (reusea) { flags |= TCL_TCPSERVER_REUSEADDR; - if (reusep) + } + if (reusep) { flags |= TCL_TCPSERVER_REUSEPORT; + } + + /* + * All the arguments should have been parsed by now, 'a' points to the + * last one, the port number. + */ - // All the arguments should have been parsed by now, 'a' points to the last - // one, the port number. if (a != objc-1) { goto wrongNumArgs; } @@ -1638,15 +1653,14 @@ Tcl_SocketObjCmd( port = TclGetString(objv[a]); if (server) { - AcceptCallback *acceptCallbackPtr = - ckalloc(sizeof(AcceptCallback)); + AcceptCallback *acceptCallbackPtr = ckalloc(sizeof(AcceptCallback)); Tcl_IncrRefCount(script); acceptCallbackPtr->script = script; acceptCallbackPtr->interp = interp; - chan = Tcl_OpenTcpServerEx(interp, port, host, flags, AcceptCallbackProc, - acceptCallbackPtr); + chan = Tcl_OpenTcpServerEx(interp, port, host, flags, + AcceptCallbackProc, acceptCallbackPtr); if (chan == NULL) { Tcl_DecrRefCount(script); ckfree(acceptCallbackPtr); diff --git a/generic/tclIOSock.c b/generic/tclIOSock.c index 8ad268a..82d2fc1 100644 --- a/generic/tclIOSock.c +++ b/generic/tclIOSock.c @@ -12,7 +12,9 @@ #include "tclInt.h" #if defined(_WIN32) && defined(UNICODE) -/* On Windows, we need to do proper Unicode->UTF-8 conversion. */ +/* + * On Windows, we need to do proper Unicode->UTF-8 conversion. + */ typedef struct ThreadSpecificData { int initialized; @@ -21,7 +23,10 @@ typedef struct ThreadSpecificData { static Tcl_ThreadDataKey dataKey; #undef gai_strerror -static const char *gai_strerror(int code) { +static const char * +gai_strerror( + int code) +{ ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&dataKey); if (tsdPtr->initialized) { @@ -126,7 +131,7 @@ TclSockMinimumBuffers( } len = sizeof(int); getsockopt((SOCKET)(size_t) sock, SOL_SOCKET, SO_RCVBUF, - (char *) ¤t, &len); + (char *) ¤t, &len); if (current < size) { len = sizeof(int); setsockopt((SOCKET)(size_t) sock, SOL_SOCKET, SO_RCVBUF, @@ -215,7 +220,7 @@ TclCreateSocketAddress( * We found some problems when using AI_ADDRCONFIG, e.g. on systems that * have no networking besides the loopback interface and want to resolve * localhost. See [Bugs 3385024, 3382419, 3382431]. As the advantage of - * using AI_ADDRCONFIG in situations where it works, is probably low, + * using AI_ADDRCONFIG is probably low even in situations where it works, * we'll leave it out for now. After all, it is just an optimisation. * * Missing on: OpenBSD, NetBSD. @@ -300,16 +305,20 @@ TclCreateSocketAddress( * *---------------------------------------------------------------------- */ -Tcl_Channel Tcl_OpenTcpServer(Tcl_Interp *interp, int port, - const char *host, Tcl_TcpAcceptProc *acceptProc, - ClientData callbackData) + +Tcl_Channel +Tcl_OpenTcpServer( + Tcl_Interp *interp, + int port, + const char *host, + Tcl_TcpAcceptProc *acceptProc, + ClientData callbackData) { char portbuf[TCL_INTEGER_SPACE]; TclFormatInt(portbuf, port); - return Tcl_OpenTcpServerEx(interp, portbuf, host, TCL_TCPSERVER_REUSEADDR, - acceptProc, callbackData); + acceptProc, callbackData); } /* diff --git a/unix/tclUnixSock.c b/unix/tclUnixSock.c index 9387d05..a64157e 100644 --- a/unix/tclUnixSock.c +++ b/unix/tclUnixSock.c @@ -117,8 +117,7 @@ struct TcpState { * Static routines for this file: */ -static int TcpConnect(Tcl_Interp *interp, - TcpState *state); +static int TcpConnect(Tcl_Interp *interp, TcpState *state); static void TcpAccept(ClientData data, int mask); static int TcpBlockModeProc(ClientData data, int mode); static int TcpCloseProc(ClientData instanceData, @@ -173,21 +172,24 @@ static ProcessGlobalValue hostName = #if 0 /* printf debugging */ -void printaddrinfo(struct addrinfo *addrlist, char *prefix) +void +printaddrinfo( + struct addrinfo *addrlist, + char *prefix) { char host[NI_MAXHOST], port[NI_MAXSERV]; struct addrinfo *ai; + for (ai = addrlist; ai != NULL; ai = ai->ai_next) { getnameinfo(ai->ai_addr, ai->ai_addrlen, - host, sizeof(host), - port, sizeof(port), - NI_NUMERICHOST|NI_NUMERICSERV); + host, sizeof(host), port, sizeof(port), + NI_NUMERICHOST|NI_NUMERICSERV); fprintf(stderr,"%s: %s:%s\n", prefix, host, port); } } #endif /* - *---------------------------------------------------------------------- + * ---------------------------------------------------------------------- * * InitializeHostName -- * @@ -197,7 +199,7 @@ void printaddrinfo(struct addrinfo *addrlist, char *prefix) * Results: * None. * - *---------------------------------------------------------------------- + * ---------------------------------------------------------------------- */ static void @@ -276,7 +278,7 @@ InitializeHostName( } /* - *---------------------------------------------------------------------- + * ---------------------------------------------------------------------- * * Tcl_GetHostName -- * @@ -290,7 +292,7 @@ InitializeHostName( * Side effects: * Caches the name to return for future calls. * - *---------------------------------------------------------------------- + * ---------------------------------------------------------------------- */ const char * @@ -300,7 +302,7 @@ Tcl_GetHostName(void) } /* - *---------------------------------------------------------------------- + * ---------------------------------------------------------------------- * * TclpHasSockets -- * @@ -312,7 +314,7 @@ Tcl_GetHostName(void) * Side effects: * None. * - *---------------------------------------------------------------------- + * ---------------------------------------------------------------------- */ int @@ -323,7 +325,7 @@ TclpHasSockets( } /* - *---------------------------------------------------------------------- + * ---------------------------------------------------------------------- * * TclpFinalizeSockets -- * @@ -335,7 +337,7 @@ TclpHasSockets( * Side effects: * None. * - *---------------------------------------------------------------------- + * ---------------------------------------------------------------------- */ void @@ -345,7 +347,7 @@ TclpFinalizeSockets(void) } /* - *---------------------------------------------------------------------- + * ---------------------------------------------------------------------- * * TcpBlockModeProc -- * @@ -358,7 +360,7 @@ TclpFinalizeSockets(void) * Side effects: * Sets the device into blocking or nonblocking mode. * - *---------------------------------------------------------------------- + * ---------------------------------------------------------------------- */ /* ARGSUSED */ @@ -387,33 +389,32 @@ TcpBlockModeProc( } /* - *---------------------------------------------------------------------- + * ---------------------------------------------------------------------- * * WaitForConnect -- * - * Check the state of an async connect process. If a connection - * attempt terminated, process it, which may finalize it or may - * start the next attempt. If a connect error occures, it is saved - * in statePtr->connectError to be reported by 'fconfigure -error'. + * Check the state of an async connect process. If a connection attempt + * terminated, process it, which may finalize it or may start the next + * attempt. If a connect error occures, it is saved in + * statePtr->connectError to be reported by 'fconfigure -error'. * * There are two modes of operation, defined by errorCodePtr: - * * non-NULL: Called by explicite read/write command. block if + * * non-NULL: Called by explicite read/write command. Blocks if the * socket is blocking. * May return two error codes: * * EWOULDBLOCK: if connect is still in progress - * * ENOTCONN: if connect failed. This would be the error - * message of a rect or sendto syscall so this is - * emulated here. - * * NULL: Called by a backround operation. Do not block and - * don't return any error code. + * * ENOTCONN: if connect failed. This would be the error message + * of a rect or sendto syscall so this is emulated here. + * * NULL: Called by a backround operation. Do not block and do not + * return any error code. * * Results: - * 0 if the connection has completed, -1 if still in progress - * or there is an error. + * 0 if the connection has completed, -1 if still in progress or there is + * an error. * * Side effects: - * Processes socket events off the system queue. - * May process asynchroneous connect. + * Processes socket events off the system queue. May process + * asynchroneous connects. * *---------------------------------------------------------------------- */ @@ -426,8 +427,8 @@ WaitForConnect( int timeout; /* - * Check if an async connect failed already and error reporting is demanded, - * return the error ENOTCONN + * Check if an async connect failed already and error reporting is + * demanded, return the error ENOTCONN */ if (errorCodePtr != NULL && (statePtr->flags & TCP_ASYNC_FAILED)) { @@ -450,11 +451,14 @@ WaitForConnect( } do { if (TclUnixWaitForFile(statePtr->fds.fd, - TCL_WRITABLE | TCL_EXCEPTION, timeout) != 0) { + TCL_WRITABLE | TCL_EXCEPTION, timeout) != 0) { TcpConnect(NULL, statePtr); } - /* Do this only once in the nonblocking case and repeat it until the - * socket is final when blocking */ + + /* + * Do this only once in the nonblocking case and repeat it until the + * socket is final when blocking. + */ } while (timeout == -1 && statePtr->flags & TCP_ASYNC_CONNECT); if (errorCodePtr != NULL) { @@ -615,6 +619,7 @@ TcpCloseProc( fds = statePtr->fds.next; while (fds != NULL) { TcpFdList *next = fds->next; + ckfree(fds); fds = next; } @@ -685,10 +690,9 @@ TcpClose2Proc( * * TcpHostPortList -- * - * This function is called by the -gethostname and -getpeername - * switches of TcpGetOptionProc() to add three list elements - * with the textual representation of the given address to the - * given DString. + * This function is called by the -gethostname and -getpeername switches + * of TcpGetOptionProc() to add three list elements with the textual + * representation of the given address to the given DString. * * Results: * None. @@ -709,22 +713,22 @@ TcpHostPortList( char host[NI_MAXHOST], nhost[NI_MAXHOST], nport[NI_MAXSERV]; int flags = 0; - getnameinfo(&addr.sa, salen, - nhost, sizeof(nhost), nport, sizeof(nport), - NI_NUMERICHOST | NI_NUMERICSERV); + getnameinfo(&addr.sa, salen, nhost, sizeof(nhost), nport, sizeof(nport), + NI_NUMERICHOST | NI_NUMERICSERV); Tcl_DStringAppendElement(dsPtr, nhost); + /* - * We don't want to resolve INADDR_ANY and sin6addr_any; they - * can sometimes cause problems (and never have a name). + * We don't want to resolve INADDR_ANY and sin6addr_any; they can + * sometimes cause problems (and never have a name). */ + if (addr.sa.sa_family == AF_INET) { if (addr.sa4.sin_addr.s_addr == INADDR_ANY) { flags |= NI_NUMERICHOST; } #ifndef NEED_FAKE_RFC2553 } else if (addr.sa.sa_family == AF_INET6) { - if ((IN6_ARE_ADDR_EQUAL(&addr.sa6.sin6_addr, - &in6addr_any)) + if ((IN6_ARE_ADDR_EQUAL(&addr.sa6.sin6_addr, &in6addr_any)) || (IN6_IS_ADDR_V4MAPPED(&addr.sa6.sin6_addr) && addr.sa6.sin6_addr.s6_addr[12] == 0 && addr.sa6.sin6_addr.s6_addr[13] == 0 && @@ -734,15 +738,27 @@ TcpHostPortList( } #endif /* NEED_FAKE_RFC2553 */ } - /* Check if reverse DNS has been switched off globally */ - if (interp != NULL && Tcl_GetVar2(interp, SUPPRESS_RDNS_VAR, NULL, 0) != NULL) { + + /* + * Check if reverse DNS has been switched off globally. + */ + + if (interp != NULL && + Tcl_GetVar2(interp, SUPPRESS_RDNS_VAR, NULL, 0) != NULL) { flags |= NI_NUMERICHOST; } - if (getnameinfo(&addr.sa, salen, host, sizeof(host), NULL, 0, flags) == 0) { - /* Reverse mapping worked */ + if (getnameinfo(&addr.sa, salen, host, sizeof(host), NULL, 0, + flags) == 0) { + /* + * Reverse mapping worked. + */ + Tcl_DStringAppendElement(dsPtr, host); } else { - /* Reverse mappong failed - use the numeric rep once more */ + /* + * Reverse mapping failed - use the numeric rep once more. + */ + Tcl_DStringAppendElement(dsPtr, nhost); } Tcl_DStringAppendElement(dsPtr, nport); @@ -793,15 +809,19 @@ TcpGetOptionProc( socklen_t optlen = sizeof(int); if (statePtr->flags & TCP_ASYNC_CONNECT) { - /* Suppress errors as long as we are not done */ + /* + * Suppress errors as long as we are not done. + */ + errno = 0; } else if (statePtr->connectError != 0) { errno = statePtr->connectError; statePtr->connectError = 0; } else { int err; - getsockopt(statePtr->fds.fd, SOL_SOCKET, SO_ERROR, - (char *) &err, &optlen); + + getsockopt(statePtr->fds.fd, SOL_SOCKET, SO_ERROR, (char *) &err, + &optlen); errno = err; } if (errno != 0) { @@ -814,7 +834,7 @@ TcpGetOptionProc( (strncmp(optionName, "-connecting", len) == 0)) { Tcl_DStringAppend(dsPtr, - (statePtr->flags & TCP_ASYNC_CONNECT) ? "1" : "0", -1); + (statePtr->flags & TCP_ASYNC_CONNECT) ? "1" : "0", -1); return TCL_OK; } @@ -823,10 +843,11 @@ TcpGetOptionProc( address peername; socklen_t size = sizeof(peername); - if ( (statePtr->flags & TCP_ASYNC_CONNECT) ) { + if (statePtr->flags & TCP_ASYNC_CONNECT) { /* * In async connect output an empty string */ + if (len == 0) { Tcl_DStringAppendElement(dsPtr, "-peername"); Tcl_DStringAppendElement(dsPtr, ""); @@ -837,6 +858,7 @@ TcpGetOptionProc( /* * Peername fetch succeeded - output list */ + if (len == 0) { Tcl_DStringAppendElement(dsPtr, "-peername"); Tcl_DStringStartSublist(dsPtr); @@ -876,11 +898,12 @@ TcpGetOptionProc( Tcl_DStringAppendElement(dsPtr, "-sockname"); Tcl_DStringStartSublist(dsPtr); } - if ( (statePtr->flags & TCP_ASYNC_CONNECT) ) { + if (statePtr->flags & TCP_ASYNC_CONNECT) { /* * In async connect output an empty string */ - found = 1; + + found = 1; } else { for (fds = &statePtr->fds; fds != NULL; fds = fds->next) { size = sizeof(sockname); @@ -905,14 +928,15 @@ TcpGetOptionProc( } if (len > 0) { - return Tcl_BadChannelOption(interp, optionName, "connecting peername sockname"); + return Tcl_BadChannelOption(interp, optionName, + "connecting peername sockname"); } return TCL_OK; } /* - *---------------------------------------------------------------------- + * ---------------------------------------------------------------------- * * TcpWatchProc -- * @@ -925,7 +949,7 @@ TcpGetOptionProc( * Sets up the notifier so that a future event on the channel will be * seen by Tcl. * - *---------------------------------------------------------------------- + * ---------------------------------------------------------------------- */ static void @@ -938,17 +962,17 @@ WrapNotify( if (newmask == 0) { /* - * There was no overlap between the states the channel is - * interested in notifications for, and the states that are - * reported present on the file descriptor by select(). The - * only way that can happen is when the channel is interested - * in a writable condition, and only a readable state is reported - * present (see TcpWatchProc() below). In that case, signal back - * to the caller the writable state, which is really an error - * condition. As an extra check on that assumption, check for - * a non-zero value of errno before reporting an artificial + * There was no overlap between the states the channel is interested + * in notifications for, and the states that are reported present on + * the file descriptor by select(). The only way that can happen is + * when the channel is interested in a writable condition, and only a + * readable state is reported present (see TcpWatchProc() below). In + * that case, signal back to the caller the writable state, which is + * really an error condition. As an extra check on that assumption, + * check for a non-zero value of errno before reporting an artificial * writable state. */ + if (errno == 0) { return; } @@ -972,33 +996,36 @@ TcpWatchProc( * be readable or writable at the Tcl level. This keeps Tcl scripts * from interfering with the -accept behavior (bug #3394732). */ + return; } if (statePtr->flags & TCP_ASYNC_PENDING) { - /* Async sockets use a FileHandler internally while connecting, so we - * need to cache this request until the connection has succeeded. */ + /* + * Async sockets use a FileHandler internally while connecting, so we + * need to cache this request until the connection has succeeded. + */ + statePtr->filehandlers = mask; } else if (mask) { /* - * Whether it is a bug or feature or otherwise, it is a fact - * of life that on at least some Linux kernels select() fails - * to report that a socket file descriptor is writable when - * the other end of the socket is closed. This is in contrast - * to the guarantees Tcl makes that its channels become - * writable and fire writable events on an error conditon. - * This has caused a leak of file descriptors in a state of + * Whether it is a bug or feature or otherwise, it is a fact of life + * that on at least some Linux kernels select() fails to report that a + * socket file descriptor is writable when the other end of the socket + * is closed. This is in contrast to the guarantees Tcl makes that + * its channels become writable and fire writable events on an error + * conditon. This has caused a leak of file descriptors in a state of * background flushing. See Tcl ticket 1758a0b603. * - * As a workaround, when our caller indicates an interest in - * writable notifications, we must tell the notifier built - * around select() that we are interested in the readable state - * of the file descriptor as well, as that is the only reliable - * means to get notified of error conditions. Then it is the - * task of WrapNotify() above to untangle the meaning of these - * channel states and report the chan events as best it can. - * We save a copy of the mask passed in to assist with that. + * As a workaround, when our caller indicates an interest in writable + * notifications, we must tell the notifier built around select() that + * we are interested in the readable state of the file descriptor as + * well, as that is the only reliable means to get notified of error + * conditions. Then it is the task of WrapNotify() above to untangle + * the meaning of these channel states and report the chan events as + * best it can. We save a copy of the mask passed in to assist with + * that. */ statePtr->interest = mask; @@ -1010,7 +1037,7 @@ TcpWatchProc( } /* - *---------------------------------------------------------------------- + * ---------------------------------------------------------------------- * * TcpGetHandleProc -- * @@ -1024,7 +1051,7 @@ TcpWatchProc( * Side effects: * None. * - *---------------------------------------------------------------------- + * ---------------------------------------------------------------------- */ /* ARGSUSED */ @@ -1041,16 +1068,17 @@ TcpGetHandleProc( } /* - *---------------------------------------------------------------------- + * ---------------------------------------------------------------------- * * TcpAsyncCallback -- * - * Called by the event handler that TcpConnect sets up - * internally for [socket -async] to get notified when the - * asyncronous connection attempt has succeeded or failed. + * Called by the event handler that TcpConnect sets up internally for + * [socket -async] to get notified when the asyncronous connection + * attempt has succeeded or failed. * - *---------------------------------------------------------------------- + * ---------------------------------------------------------------------- */ + static void TcpAsyncCallback( ClientData clientData, /* The socket state. */ @@ -1062,7 +1090,7 @@ TcpAsyncCallback( } /* - *---------------------------------------------------------------------- + * ---------------------------------------------------------------------- * * TcpConnect -- * @@ -1088,7 +1116,7 @@ TcpAsyncCallback( * return and the loops resume as if they had never been interrupted. * For syncronously connecting sockets, the loops work the usual way. * - *---------------------------------------------------------------------- + * ---------------------------------------------------------------------- */ static int @@ -1108,7 +1136,8 @@ TcpConnect( for (statePtr->addr = statePtr->addrlist; statePtr->addr != NULL; statePtr->addr = statePtr->addr->ai_next) { - for (statePtr->myaddr = statePtr->myaddrlist; statePtr->myaddr != NULL; + for (statePtr->myaddr = statePtr->myaddrlist; + statePtr->myaddr != NULL; statePtr->myaddr = statePtr->myaddr->ai_next) { int reuseaddr = 1; @@ -1132,7 +1161,8 @@ TcpConnect( errno = 0; } - statePtr->fds.fd = socket(statePtr->addr->ai_family, SOCK_STREAM, 0); + statePtr->fds.fd = socket(statePtr->addr->ai_family, SOCK_STREAM, + 0); if (statePtr->fds.fd < 0) { continue; } @@ -1151,14 +1181,18 @@ TcpConnect( TclSockMinimumBuffers(INT2PTR(statePtr->fds.fd), SOCKET_BUFSIZE); if (async) { - ret = TclUnixSetBlockingMode(statePtr->fds.fd,TCL_MODE_NONBLOCKING); + ret = TclUnixSetBlockingMode(statePtr->fds.fd, + TCL_MODE_NONBLOCKING); if (ret < 0) { continue; } } - /* Gotta reset the error variable here, before we use it for the - * first time in this iteration. */ + /* + * Must reset the error variable here, before we use it for the + * first time in this iteration. + */ + error = 0; (void) setsockopt(statePtr->fds.fd, SOL_SOCKET, SO_REUSEADDR, @@ -1179,10 +1213,13 @@ TcpConnect( ret = connect(statePtr->fds.fd, statePtr->addr->ai_addr, statePtr->addr->ai_addrlen); - if (ret < 0) error = errno; + if (ret < 0) { + error = errno; + } if (ret < 0 && errno == EINPROGRESS) { Tcl_CreateFileHandler(statePtr->fds.fd, - TCL_WRITABLE|TCL_EXCEPTION, TcpAsyncCallback, statePtr); + TCL_WRITABLE | TCL_EXCEPTION, TcpAsyncCallback, + statePtr); errno = EWOULDBLOCK; SET_BITS(statePtr->flags, TCP_ASYNC_PENDING); return TCL_OK; @@ -1210,7 +1247,7 @@ TcpConnect( } } -out: + out: statePtr->connectError = error; CLEAR_BITS(statePtr->flags, TCP_ASYNC_CONNECT); if (async_callback) { @@ -1308,6 +1345,7 @@ Tcl_OpenTcpClient( /* * Allocate a new TcpState for this socket. */ + statePtr = ckalloc(sizeof(TcpState)); memset(statePtr, 0, sizeof(TcpState)); statePtr->flags = async ? TCP_ASYNC_CONNECT : 0; @@ -1319,6 +1357,7 @@ Tcl_OpenTcpClient( /* * Create a new client socket and wrap it in a channel. */ + if (TcpConnect(interp, statePtr) != TCL_OK) { TcpCloseProc(statePtr, NULL); return NULL; @@ -1326,8 +1365,8 @@ Tcl_OpenTcpClient( sprintf(channelName, SOCK_TEMPLATE, (long) statePtr); - statePtr->channel = Tcl_CreateChannel(&tcpChannelType, channelName, statePtr, - (TCL_READABLE | TCL_WRITABLE)); + statePtr->channel = Tcl_CreateChannel(&tcpChannelType, channelName, + statePtr, TCL_READABLE | TCL_WRITABLE); if (Tcl_SetChannelOption(interp, statePtr->channel, "-translation", "auto crlf") == TCL_ERROR) { Tcl_Close(NULL, statePtr->channel); @@ -1356,7 +1395,8 @@ Tcl_Channel Tcl_MakeTcpClientChannel( ClientData sock) /* The socket to wrap up into a channel. */ { - return (Tcl_Channel) TclpMakeTcpClientChannelMode(sock, (TCL_READABLE | TCL_WRITABLE)); + return (Tcl_Channel) TclpMakeTcpClientChannelMode(sock, + TCL_READABLE | TCL_WRITABLE); } /* @@ -1456,6 +1496,7 @@ Tcl_OpenTcpServerEx( * families. We try this at most MAXRETRY times to avoid an endless loop * if all ports are taken. */ + int retry = 0; #define MAXRETRY 10 @@ -1481,7 +1522,8 @@ Tcl_OpenTcpServerEx( goto error; } - if (!TclCreateSocketAddress(interp, &addrlist, myHost, port, 1, &errorMsg)) { + if (!TclCreateSocketAddress(interp, &addrlist, myHost, port, 1, + &errorMsg)) { my_errno = errno; goto error; } @@ -1517,21 +1559,22 @@ Tcl_OpenTcpServerEx( if (flags & TCL_TCPSERVER_REUSEADDR) { optvalue = 1; (void) setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, - (char *) &optvalue, sizeof(optvalue)); + (char *) &optvalue, sizeof(optvalue)); } if (flags & TCL_TCPSERVER_REUSEPORT) { #ifndef SO_REUSEPORT /* - * If the platform doesn't support the SO_REUSEPORT flag we can't do - * much beside erroring out. + * If the platform doesn't support the SO_REUSEPORT flag we can't + * do much beside erroring out. */ + errorMsg = "SO_REUSEPORT isn't supported by this platform"; goto error; #else optvalue = 1; (void) setsockopt(sock, SOL_SOCKET, SO_REUSEPORT, - (char *) &optvalue, sizeof(optvalue)); + (char *) &optvalue, sizeof(optvalue)); #endif } @@ -1549,7 +1592,10 @@ Tcl_OpenTcpServerEx( } #ifdef IPV6_V6ONLY - /* Missing on: Solaris 2.8 */ + /* + * Missing on: Solaris 2.8 + */ + if (addrPtr->ai_family == AF_INET6) { int v6only = 1; @@ -1701,7 +1747,7 @@ TcpAccept( sprintf(channelName, SOCK_TEMPLATE, (long) newSockState); newSockState->channel = Tcl_CreateChannel(&tcpChannelType, channelName, - newSockState, (TCL_READABLE | TCL_WRITABLE)); + newSockState, TCL_READABLE | TCL_WRITABLE); Tcl_SetChannelOption(NULL, newSockState->channel, "-translation", "auto crlf"); diff --git a/win/tclWinSock.c b/win/tclWinSock.c index 81a5449..d6aca1b 100644 --- a/win/tclWinSock.c +++ b/win/tclWinSock.c @@ -297,17 +297,25 @@ static ProcessGlobalValue hostName = * Address print debug functions */ #if 0 -void printaddrinfo(struct addrinfo *ai, char *prefix) +void +printaddrinfo( + struct addrinfo *ai, + char *prefix) { char host[NI_MAXHOST], port[NI_MAXSERV]; + getnameinfo(ai->ai_addr, ai->ai_addrlen, - host, sizeof(host), - port, sizeof(port), - NI_NUMERICHOST|NI_NUMERICSERV); + host, sizeof(host), port, sizeof(port), + NI_NUMERICHOST|NI_NUMERICSERV); } -void printaddrinfolist(struct addrinfo *addrlist, char *prefix) + +void +printaddrinfolist( + struct addrinfo *addrlist, + char *prefix) { struct addrinfo *ai; + for (ai = addrlist; ai != NULL; ai = ai->ai_next) { printaddrinfo(ai, prefix); } @@ -524,9 +532,9 @@ TcpBlockModeProc( TcpState *statePtr = instanceData; if (mode == TCL_MODE_NONBLOCKING) { - statePtr->flags |= TCP_NONBLOCKING; + SET_BITS(statePtr->flags, TCP_NONBLOCKING); } else { - statePtr->flags &= ~(TCP_NONBLOCKING); + CLEAR_BITS(statePtr->flags, TCP_NONBLOCKING); } return 0; } @@ -536,29 +544,28 @@ TcpBlockModeProc( * * WaitForConnect -- * - * Check the state of an async connect process. If a connection - * attempt terminated, process it, which may finalize it or may - * start the next attempt. If a connect error occures, it is saved - * in statePtr->connectError to be reported by 'fconfigure -error'. + * Check the state of an async connect process. If a connection attempt + * terminated, process it, which may finalize it or may start the next + * attempt. If a connect error occures, it is saved in + * statePtr->connectError to be reported by 'fconfigure -error'. * * There are two modes of operation, defined by errorCodePtr: - * * non-NULL: Called by explicite read/write command. block if - * socket is blocking. + * * non-NULL: Called by explicite read/write command. Block if socket + * is blocking. * May return two error codes: * * EWOULDBLOCK: if connect is still in progress - * * ENOTCONN: if connect failed. This would be the error - * message of a rect or sendto syscall so this is - * emulated here. - * * Null: Called by a backround operation. Do not block and - * don't return any error code. + * * ENOTCONN: if connect failed. This would be the error message + * of a rect or sendto syscall so this is emulated here. + * * Null: Called by a backround operation. Do not block and don't + * return any error code. * * Results: - * 0 if the connection has completed, -1 if still in progress - * or there is an error. + * 0 if the connection has completed, -1 if still in progress or there is + * an error. * * Side effects: - * Processes socket events off the system queue. - * May process asynchroneous connect. + * Processes socket events off the system queue. May process + * asynchroneous connect. * *---------------------------------------------------------------------- */ @@ -566,17 +573,16 @@ TcpBlockModeProc( static int WaitForConnect( TcpState *statePtr, /* State of the socket. */ - int *errorCodePtr) /* Where to store errors? - * A passed null-pointer activates background mode. - */ + int *errorCodePtr) /* Where to store errors? A passed + * null-pointer activates background mode. */ { int result; int oldMode; ThreadSpecificData *tsdPtr; /* - * Check if an async connect failed already and error reporting is demanded, - * return the error ENOTCONN + * Check if an async connect failed already and error reporting is + * demanded, return the error ENOTCONN. */ if (errorCodePtr != NULL && (statePtr->flags & TCP_ASYNC_FAILED)) { @@ -603,36 +609,51 @@ WaitForConnect( */ while (1) { + /* + * Get the statePtr lock. + */ - /* get statePtr lock */ tsdPtr = TclThreadDataKeyGet(&dataKey); WaitForSingleObject(tsdPtr->socketListLock, INFINITE); - /* Check for connect event */ + /* + * Check for connect event. + */ + if (statePtr->readyEvents & FD_CONNECT) { + /* + * Consume the connect event. + */ - /* Consume the connect event */ - statePtr->readyEvents &= ~(FD_CONNECT); + CLEAR_BITS(statePtr->readyEvents, FD_CONNECT); /* - * For blocking sockets and foreground processing - * disable async connect as we continue now synchoneously + * For blocking sockets and foreground processing, disable async + * connect as we continue now synchoneously. */ - if ( errorCodePtr != NULL && - ! (statePtr->flags & TCP_NONBLOCKING) ) { + + if (errorCodePtr != NULL && + !(statePtr->flags & TCP_NONBLOCKING)) { CLEAR_BITS(statePtr->flags, TCP_ASYNC_CONNECT); } - /* Free list lock */ + /* + * Free list lock. + */ + SetEvent(tsdPtr->socketListLock); /* - * Continue connect. - * If switched to synchroneous connect, the connect is terminated. + * Continue connect. If switched to synchroneous connect, the + * connect is terminated. */ + result = TcpConnect(NULL, statePtr); - /* Restore event service mode */ + /* + * Restore event service mode. + */ + (void) Tcl_SetServiceMode(oldMode); /* @@ -641,10 +662,11 @@ WaitForConnect( if (result == TCL_OK) { /* - * Check for async connect restart - * (not possible for foreground blocking operation) + * Check for async connect restart (not possible for + * foreground blocking operation) */ - if ( statePtr->flags & TCP_ASYNC_PENDING ) { + + if (statePtr->flags & TCP_ASYNC_PENDING) { if (errorCodePtr != NULL) { *errorCodePtr = EWOULDBLOCK; } @@ -654,8 +676,8 @@ WaitForConnect( } /* - * Connect finally failed. - * For foreground operation return ENOTCONN. + * Connect finally failed. For foreground operation return + * ENOTCONN. */ if (errorCodePtr != NULL) { @@ -664,7 +686,10 @@ WaitForConnect( return -1; } - /* Free list lock */ + /* + * Free list lock. + */ + SetEvent(tsdPtr->socketListLock); /* @@ -672,13 +697,13 @@ WaitForConnect( * event */ - if ( errorCodePtr == NULL ) { + if (errorCodePtr == NULL) { return -1; } /* - * A non blocking socket waiting for an asyncronous connect - * returns directly the error EWOULDBLOCK + * A non blocking socket waiting for an asyncronous connect returns + * directly the error EWOULDBLOCK. */ if (statePtr->flags & TCP_NONBLOCKING) { @@ -770,16 +795,20 @@ TcpInputProc( while (1) { SendMessage(tsdPtr->hwnd, SOCKET_SELECT, (WPARAM) UNSELECT, (LPARAM) statePtr); - /* single fd operation: this proc is only called for a connected socket. */ + /* + * Single fd operation: this proc is only called for a connected + * socket. + */ + bytesRead = recv(statePtr->sockets->fd, buf, bufSize, 0); - statePtr->readyEvents &= ~(FD_READ); + CLEAR_BITS(statePtr->readyEvents, FD_READ); /* * Check for end-of-file condition or successful read. */ if (bytesRead == 0) { - statePtr->flags |= SOCKET_EOF; + SET_BITS(statePtr->flags, SOCKET_EOF); } if (bytesRead != SOCKET_ERROR) { break; @@ -791,7 +820,7 @@ TcpInputProc( */ if (statePtr->readyEvents & FD_CLOSE) { - statePtr->flags |= SOCKET_EOF; + SET_BITS(statePtr->flags, SOCKET_EOF); bytesRead = 0; break; } @@ -804,7 +833,7 @@ TcpInputProc( */ if (error == WSAECONNRESET) { - statePtr->flags |= SOCKET_EOF; + SET_BITS(statePtr->flags, SOCKET_EOF); bytesRead = 0; break; } @@ -892,7 +921,11 @@ TcpOutputProc( SendMessage(tsdPtr->hwnd, SOCKET_SELECT, (WPARAM) UNSELECT, (LPARAM) statePtr); - /* single fd operation: this proc is only called for a connected socket. */ + /* + * Single fd operation: this proc is only called for a connected + * socket. + */ + written = send(statePtr->sockets->fd, buf, toWrite, 0); if (written != SOCKET_ERROR) { /* @@ -917,7 +950,7 @@ TcpOutputProc( error = WSAGetLastError(); if (error == WSAEWOULDBLOCK) { - statePtr->readyEvents &= ~(FD_WRITE); + CLEAR_BITS(statePtr->readyEvents, FD_WRITE); if (statePtr->flags & TCP_NONBLOCKING) { *errorCodePtr = EWOULDBLOCK; written = -1; @@ -941,7 +974,8 @@ TcpOutputProc( } } - SendMessage(tsdPtr->hwnd, SOCKET_SELECT, (WPARAM)SELECT, (LPARAM)statePtr); + SendMessage(tsdPtr->hwnd, SOCKET_SELECT, (WPARAM)SELECT, + (LPARAM)statePtr); return written; } @@ -988,10 +1022,10 @@ TcpCloseProc( * background. */ - while ( statePtr->sockets != NULL ) { + while (statePtr->sockets != NULL) { TcpFdList *thisfd = statePtr->sockets; - statePtr->sockets = thisfd->next; + statePtr->sockets = thisfd->next; if (closesocket(thisfd->fd) == SOCKET_ERROR) { TclWinConvertError((DWORD) WSAGetLastError()); errorCode = Tcl_GetErrno(); @@ -1009,18 +1043,25 @@ TcpCloseProc( /* * Clear an eventual tsd info list pointer. + * * This may be called, if an async socket connect fails or is closed * between connect and thread action callback. */ + if (tsdPtr->pendingTcpState != NULL && tsdPtr->pendingTcpState == statePtr) { + /* + * Get infoPtr lock, because this concerns the notifier thread. + */ - /* get infoPtr lock, because this concerns the notifier thread */ WaitForSingleObject(tsdPtr->socketListLock, INFINITE); tsdPtr->pendingTcpState = NULL; - /* Free list lock */ + /* + * Free list lock. + */ + SetEvent(tsdPtr->socketListLock); } @@ -1081,8 +1122,11 @@ TcpClose2Proc( return TCL_ERROR; } - /* single fd operation: Tcl_OpenTcpServer() does not set TCL_READABLE or - * TCL_WRITABLE so this should never be called for a server socket. */ + /* + * Single fd operation: Tcl_OpenTcpServer() does not set TCL_READABLE or + * TCL_WRITABLE so this should never be called for a server socket. + */ + if (shutdown(statePtr->sockets->fd, sd) == SOCKET_ERROR) { TclWinConvertError((DWORD) WSAGetLastError()); errorCode = Tcl_GetErrno(); @@ -1134,7 +1178,7 @@ TcpSetOptionProc( } #ifdef TCL_FEATURE_KEEPALIVE_NAGLE - #error "TCL_FEATURE_KEEPALIVE_NAGLE not reviewed for whether to treat statePtr->sockets as single fd or list" +#error "TCL_FEATURE_KEEPALIVE_NAGLE not reviewed for whether to treat statePtr->sockets as single fd or list" sock = statePtr->sockets->fd; if (!strcasecmp(optionName, "-keepalive")) { @@ -1243,8 +1287,11 @@ TcpGetOptionProc( /* * Go one step in async connect - * If any error is thrown save it as backround error to report eventually below + * + * If any error is thrown save it as backround error to report eventually + * below. */ + WaitForConnect(statePtr, NULL); sock = statePtr->sockets->fd; @@ -1254,31 +1301,26 @@ TcpGetOptionProc( if ((len > 1) && (optionName[1] == 'e') && (strncmp(optionName, "-error", len) == 0)) { - /* - * Do not return any errors if async connect is running - */ - if ( ! (statePtr->flags & TCP_ASYNC_PENDING) ) { - - - if ( statePtr->flags & TCP_ASYNC_FAILED ) { + * Do not return any errors if async connect is running. + */ + if (!(statePtr->flags & TCP_ASYNC_PENDING)) { + if (statePtr->flags & TCP_ASYNC_FAILED) { /* * In case of a failed async connect, eventually report the - * connect error only once. - * Do not report the system error, as this comes again and again. + * connect error only once. Do not report the system error, + * as this comes again and again. */ - if ( statePtr->connectError != 0 ) { + if (statePtr->connectError != 0) { Tcl_DStringAppend(dsPtr, Tcl_ErrnoMsg(statePtr->connectError), -1); statePtr->connectError = 0; } - } else { - /* - * Report an eventual last error of the socket system + * Report an eventual last error of the socket system. */ int optlen; @@ -1286,24 +1328,30 @@ TcpGetOptionProc( DWORD err; /* - * Populater the err Variable with a possix error + * Populate the err variable with a POSIX error */ + optlen = sizeof(int); ret = getsockopt(sock, SOL_SOCKET, SO_ERROR, (char *)&err, &optlen); + /* - * The error was not returned directly but should be - * taken from WSA + * The error was not returned directly but should be taken + * from WSA. */ + if (ret == SOCKET_ERROR) { err = WSAGetLastError(); } + /* - * Return error message + * Return error message. */ + if (err) { TclWinConvertError(err); - Tcl_DStringAppend(dsPtr, Tcl_ErrnoMsg(Tcl_GetErrno()), -1); + Tcl_DStringAppend(dsPtr, Tcl_ErrnoMsg(Tcl_GetErrno()), + -1); } } } @@ -1312,14 +1360,14 @@ TcpGetOptionProc( if ((len > 1) && (optionName[1] == 'c') && (strncmp(optionName, "-connecting", len) == 0)) { - Tcl_DStringAppend(dsPtr, (statePtr->flags & TCP_ASYNC_PENDING) ? "1" : "0", -1); return TCL_OK; } - if (interp != NULL && Tcl_GetVar2(interp, SUPPRESS_RDNS_VAR, NULL, 0) != NULL) { + if (interp != NULL + && Tcl_GetVar2(interp, SUPPRESS_RDNS_VAR, NULL, 0) != NULL) { reverseDNS = NI_NUMERICHOST; } @@ -1328,20 +1376,23 @@ TcpGetOptionProc( address peername; socklen_t size = sizeof(peername); - if ( (statePtr->flags & TCP_ASYNC_PENDING) ) { + if (statePtr->flags & TCP_ASYNC_PENDING) { /* * In async connect output an empty string */ + if (len == 0) { Tcl_DStringAppendElement(dsPtr, "-peername"); Tcl_DStringAppendElement(dsPtr, ""); } else { return TCL_OK; } - } else if ( getpeername(sock, (LPSOCKADDR) &(peername.sa), &size) == 0) { + } else if (getpeername(sock, (LPSOCKADDR) &(peername.sa), + &size) == 0) { /* * Peername fetch succeeded - output list */ + if (len == 0) { Tcl_DStringAppendElement(dsPtr, "-peername"); Tcl_DStringStartSublist(dsPtr); @@ -1390,11 +1441,12 @@ TcpGetOptionProc( Tcl_DStringAppendElement(dsPtr, "-sockname"); Tcl_DStringStartSublist(dsPtr); } - if ( (statePtr->flags & TCP_ASYNC_PENDING ) ) { + if (statePtr->flags & TCP_ASYNC_PENDING) { /* * In async connect output an empty string */ - found = 1; + + found = 1; } else { for (fds = statePtr->sockets; fds != NULL; fds = fds->next) { sock = fds->fd; @@ -1408,9 +1460,11 @@ TcpGetOptionProc( Tcl_DStringAppendElement(dsPtr, host); /* - * We don't want to resolve INADDR_ANY and sin6addr_any; they - * can sometimes cause problems (and never have a name). + * We don't want to resolve INADDR_ANY and sin6addr_any; + * they can sometimes cause problems (and never have a + * name). */ + flags |= NI_NUMERICSERV; if (sockname.sa.sa_family == AF_INET) { if (sockname.sa4.sin_addr.s_addr == INADDR_ANY) { @@ -1494,7 +1548,8 @@ TcpGetOptionProc( return Tcl_BadChannelOption(interp, optionName, "connecting peername sockname keepalive nagle"); #else - return Tcl_BadChannelOption(interp, optionName, "connecting peername sockname"); + return Tcl_BadChannelOption(interp, optionName, + "connecting peername sockname"); #endif /*TCL_FEATURE_KEEPALIVE_NAGLE*/ } @@ -1536,10 +1591,10 @@ TcpWatchProc( if (!statePtr->acceptProc) { statePtr->watchEvents = 0; if (mask & TCL_READABLE) { - statePtr->watchEvents |= (FD_READ|FD_CLOSE); + SET_BITS(statePtr->watchEvents, FD_READ | FD_CLOSE); } if (mask & TCL_WRITABLE) { - statePtr->watchEvents |= (FD_WRITE|FD_CLOSE); + SET_BITS(statePtr->watchEvents, FD_WRITE | FD_CLOSE); } /* @@ -1630,13 +1685,13 @@ TcpConnect( TcpState *statePtr) { DWORD error; - /* - * We are started with async connect and the connect notification - * was not jet received - */ int async_connect = statePtr->flags & TCP_ASYNC_CONNECT; - /* We were called by the event procedure and continue our loop */ + /* We are started with async connect and the + * connect notification was not yet + * received. */ int async_callback = statePtr->flags & TCP_ASYNC_PENDING; + /* We were called by the event procedure and + * continue our loop. */ ThreadSpecificData *tsdPtr = TclThreadDataKeyGet(&dataKey); if (async_callback) { @@ -1644,11 +1699,10 @@ TcpConnect( } for (statePtr->addr = statePtr->addrlist; statePtr->addr != NULL; - statePtr->addr = statePtr->addr->ai_next) { - - for (statePtr->myaddr = statePtr->myaddrlist; statePtr->myaddr != NULL; - statePtr->myaddr = statePtr->myaddr->ai_next) { - + statePtr->addr = statePtr->addr->ai_next) { + for (statePtr->myaddr = statePtr->myaddrlist; + statePtr->myaddr != NULL; + statePtr->myaddr = statePtr->myaddr->ai_next) { /* * No need to try combinations of local and remote addresses * of different families. @@ -1662,25 +1716,37 @@ TcpConnect( * Close the socket if it is still open from the last unsuccessful * iteration. */ + if (statePtr->sockets->fd != INVALID_SOCKET) { closesocket(statePtr->sockets->fd); } - /* get statePtr lock */ + /* + * Get statePtr lock. + */ + WaitForSingleObject(tsdPtr->socketListLock, INFINITE); /* * Reset last error from last try */ + statePtr->notifierConnectError = 0; Tcl_SetErrno(0); - statePtr->sockets->fd = socket(statePtr->myaddr->ai_family, SOCK_STREAM, 0); + statePtr->sockets->fd = socket(statePtr->myaddr->ai_family, + SOCK_STREAM, 0); + + /* + * Free list lock. + */ - /* Free list lock */ SetEvent(tsdPtr->socketListLock); - /* continue on socket creation error */ + /* + * Continue on socket creation error. + */ + if (statePtr->sockets->fd == INVALID_SOCKET) { TclWinConvertError((DWORD) WSAGetLastError()); continue; @@ -1691,31 +1757,39 @@ TcpConnect( * processes by default. Turn off the inherit bit. */ - SetHandleInformation((HANDLE) statePtr->sockets->fd, HANDLE_FLAG_INHERIT, 0); + SetHandleInformation((HANDLE) statePtr->sockets->fd, + HANDLE_FLAG_INHERIT, 0); /* * Set kernel space buffering */ - TclSockMinimumBuffers((void *) statePtr->sockets->fd, TCP_BUFFER_SIZE); + TclSockMinimumBuffers((void *) statePtr->sockets->fd, + TCP_BUFFER_SIZE); /* * Try to bind to a local port. */ if (bind(statePtr->sockets->fd, statePtr->myaddr->ai_addr, - statePtr->myaddr->ai_addrlen) == SOCKET_ERROR) { + statePtr->myaddr->ai_addrlen) == SOCKET_ERROR) { TclWinConvertError((DWORD) WSAGetLastError()); continue; } + /* * For asyncroneous connect set the socket in nonblocking mode * and activate connect notification */ + if (async_connect) { TcpState *statePtr2; int in_socket_list = 0; - /* get statePtr lock */ + + /* + * Get statePtr lock. + */ + WaitForSingleObject(tsdPtr->socketListLock, INFINITE); /* @@ -1725,8 +1799,8 @@ TcpConnect( * It is set after this call by TcpThreadActionProc and is set * on a second round. * - * If not, we buffer my statePtr in the tsd memory so it is not - * lost by the event procedure + * If not, we buffer my statePtr in the tsd memory so it is + * not lost by the event procedure */ for (statePtr2 = tsdPtr->socketList; statePtr2 != NULL; @@ -1739,19 +1813,26 @@ TcpConnect( if (!in_socket_list) { tsdPtr->pendingTcpState = statePtr; } + /* * Set connect mask to connect events - * This is activated by a SOCKET_SELECT message to the notifier - * thread. + * + * This is activated by a SOCKET_SELECT message to the + * notifier thread. */ - statePtr->selectEvents |= FD_CONNECT; + + SET_BITS(statePtr->selectEvents, FD_CONNECT); /* - * Free list lock + * Free list lock. */ + SetEvent(tsdPtr->socketListLock); - /* activate accept notification */ + /* + * Activate accept notification. + */ + SendMessage(tsdPtr->hwnd, SOCKET_SELECT, (WPARAM) SELECT, (LPARAM) statePtr); } @@ -1769,12 +1850,11 @@ TcpConnect( if (async_connect && error == WSAEWOULDBLOCK) { /* * Asynchroneous connect - */ - - /* + * * Remember that we jump back behind this next round */ - statePtr->flags |= TCP_ASYNC_PENDING; + + SET_BITS(statePtr->flags, TCP_ASYNC_PENDING); return TCL_OK; reenter: @@ -1784,21 +1864,39 @@ TcpConnect( * * Clear the reenter flag */ - statePtr->flags &= ~(TCP_ASYNC_PENDING); - /* get statePtr lock */ + + CLEAR_BITS(statePtr->flags, TCP_ASYNC_PENDING); + + /* + * Get statePtr lock. + */ + WaitForSingleObject(tsdPtr->socketListLock, INFINITE); - /* Get signaled connect error */ + + /* + * Get signaled connect error. + */ + TclWinConvertError((DWORD) statePtr->notifierConnectError); - /* Clear eventual connect flag */ - statePtr->selectEvents &= ~(FD_CONNECT); - /* Free list lock */ + + /* + * Clear eventual connect flag. + */ + + CLEAR_BITS(statePtr->selectEvents, FD_CONNECT); + + /* + * Free list lock. + */ + SetEvent(tsdPtr->socketListLock); } /* - * Clear the tsd socket list pointer if we did not wait for - * the FD_CONNECT asyncroneously + * Clear the tsd socket list pointer if we did not wait for the + * FD_CONNECT asynchronously. */ + tsdPtr->pendingTcpState = NULL; if (Tcl_GetErrno() == 0) { @@ -1807,7 +1905,7 @@ TcpConnect( } } -out: + out: /* * Socket connected or connection failed */ @@ -1818,13 +1916,13 @@ out: CLEAR_BITS(statePtr->flags, TCP_ASYNC_CONNECT); - if ( Tcl_GetErrno() == 0 ) { + if (Tcl_GetErrno() == 0) { /* * Succesfully connected - */ - /* + * * Set up the select mask for read/write events. */ + statePtr->selectEvents = FD_READ | FD_WRITE | FD_CLOSE; /* @@ -1837,30 +1935,52 @@ out: } else { /* * Connect failed - */ - - /* + * * For async connect schedule a writable event to report the fail. */ + if (async_callback) { /* * Set up the select mask for read/write events. */ + statePtr->selectEvents = FD_WRITE|FD_READ; - /* get statePtr lock */ + + /* + * Get statePtr lock. + */ + WaitForSingleObject(tsdPtr->socketListLock, INFINITE); - /* Signal ready readable and writable events */ - statePtr->readyEvents |= FD_WRITE | FD_READ; - /* Flag error to event routine */ - statePtr->flags |= TCP_ASYNC_FAILED; - /* Save connect error to be reported by 'fconfigure -error' */ + + /* + * Signal ready readable and writable events. + */ + + SET_BITS(statePtr->readyEvents, FD_WRITE | FD_READ); + + /* + * Flag error to event routine. + */ + + SET_BITS(statePtr->flags, TCP_ASYNC_FAILED); + + /* + * Save connect error to be reported by 'fconfigure -error'. + */ + statePtr->connectError = Tcl_GetErrno(); - /* Free list lock */ + + /* + * Free list lock. + */ + SetEvent(tsdPtr->socketListLock); } + /* * Error message on syncroneous connect */ + if (interp != NULL) { Tcl_SetObjResult(interp, Tcl_ObjPrintf( "couldn't open socket: %s", Tcl_PosixError(interp))); @@ -1938,7 +2058,7 @@ Tcl_OpenTcpClient( statePtr->addrlist = addrlist; statePtr->myaddrlist = myaddrlist; if (async) { - statePtr->flags |= TCP_ASYNC_CONNECT; + SET_BITS(statePtr->flags, TCP_ASYNC_CONNECT); } /* @@ -2008,7 +2128,8 @@ Tcl_MakeTcpClientChannel( */ statePtr->selectEvents = FD_READ | FD_CLOSE | FD_WRITE; - SendMessage(tsdPtr->hwnd, SOCKET_SELECT, (WPARAM)SELECT, (LPARAM)statePtr); + SendMessage(tsdPtr->hwnd, SOCKET_SELECT, (WPARAM)SELECT, + (LPARAM)statePtr); sprintf(channelName, SOCK_TEMPLATE, statePtr); statePtr->channel = Tcl_CreateChannel(&tcpChannelType, channelName, @@ -2078,7 +2199,8 @@ Tcl_OpenTcpServerEx( goto error; } - if (!TclCreateSocketAddress(interp, &addrlist, myHost, port, 1, &errorMsg)) { + if (!TclCreateSocketAddress(interp, &addrlist, myHost, port, 1, + &errorMsg)) { goto error; } @@ -2117,13 +2239,14 @@ Tcl_OpenTcpServerEx( } /* - * The SO_REUSEADDR option on Windows behaves like SO_REUSEPORT on unix - * systems. + * The SO_REUSEADDR option on Windows behaves like SO_REUSEPORT on + * unix systems. */ + if (flags & TCL_TCPSERVER_REUSEPORT) { optvalue = 1; (void) setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, - (char *) &optvalue, sizeof(optvalue)); + (char *) &optvalue, sizeof(optvalue)); } /* @@ -2134,8 +2257,8 @@ Tcl_OpenTcpServerEx( * place to look for bugs. */ - if (bind(sock, addrPtr->ai_addr, addrPtr->ai_addrlen) - == SOCKET_ERROR) { + if (bind(sock, addrPtr->ai_addr, + addrPtr->ai_addrlen) == SOCKET_ERROR) { TclWinConvertError((DWORD) WSAGetLastError()); closesocket(sock); continue; @@ -2170,13 +2293,14 @@ Tcl_OpenTcpServerEx( /* * Add this socket to the global list of sockets. */ + statePtr = NewSocketInfo(sock); } else { - AddSocketInfoFd( statePtr, sock ); + AddSocketInfoFd(statePtr, sock); } } -error: + error: if (addrlist != NULL) { freeaddrinfo(addrlist); } @@ -2202,7 +2326,7 @@ error: ioctlsocket(sock, (long) FIONBIO, &flag); SendMessage(tsdPtr->hwnd, SOCKET_SELECT, (WPARAM) SELECT, - (LPARAM) statePtr); + (LPARAM) statePtr); if (Tcl_SetChannelOption(interp, statePtr->channel, "-eofchar", "") == TCL_ERROR) { Tcl_Close(NULL, statePtr->channel); @@ -2564,9 +2688,8 @@ SocketCheckProc( statePtr = statePtr->nextPtr) { if ((statePtr->readyEvents & (statePtr->watchEvents | FD_CONNECT | FD_ACCEPT)) - && !(statePtr->flags & SOCKET_PENDING) - ) { - statePtr->flags |= SOCKET_PENDING; + && !(statePtr->flags & SOCKET_PENDING)) { + SET_BITS(statePtr->flags, SOCKET_PENDING); evPtr = ckalloc(sizeof(SocketEvent)); evPtr->header.proc = SocketEventProc; evPtr->socket = statePtr->sockets->fd; @@ -2641,29 +2764,26 @@ SocketEventProc( * Clear flag that (this) event is pending */ - statePtr->flags &= ~SOCKET_PENDING; + CLEAR_BITS(statePtr->flags, SOCKET_PENDING); /* * Continue async connect if pending and ready */ - if ( statePtr->readyEvents & FD_CONNECT ) { - if ( statePtr->flags & TCP_ASYNC_PENDING ) { - + if (statePtr->readyEvents & FD_CONNECT) { + if (statePtr->flags & TCP_ASYNC_PENDING) { /* * Do one step and save eventual connect error */ SetEvent(tsdPtr->socketListLock); WaitForConnect(statePtr,NULL); - } else { - /* * No async connect reenter pending. Just clear event. */ - statePtr->readyEvents &= ~(FD_CONNECT); + CLEAR_BITS(statePtr->readyEvents, FD_CONNECT); SetEvent(tsdPtr->socketListLock); } return 1; @@ -2672,20 +2792,23 @@ SocketEventProc( /* * Handle connection requests directly. */ + if (statePtr->readyEvents & FD_ACCEPT) { for (fds = statePtr->sockets; fds != NULL; fds = fds->next) { - /* - * Accept the incoming connection request. - */ - len = sizeof(address); + * Accept the incoming connection request. + */ + len = sizeof(address); newSocket = accept(fds->fd, &(addr.sa), &len); - /* On Tcl server sockets with multiple OS fds we loop over the fds trying - * an accept() on each, so we expect INVALID_SOCKET. There are also other - * network stack conditions that can result in FD_ACCEPT but a subsequent - * failure on accept() by the time we get around to it. + /* + * On Tcl server sockets with multiple OS fds we loop over the fds + * trying an accept() on each, so we expect INVALID_SOCKET. There + * are also other network stack conditions that can result in + * FD_ACCEPT but a subsequent failure on accept() by the time we + * get around to it. + * * Access to sockets (acceptEventCount, readyEvents) in socketList * is still protected by the lock (prevents reintroduction of * SF Tcl Bug 3056775. @@ -2697,35 +2820,40 @@ SocketEventProc( } /* - * It is possible that more than one FD_ACCEPT has been sent, so an extra - * count must be kept. Decrement the count, and reset the readyEvent bit - * if the count is no longer > 0. + * It is possible that more than one FD_ACCEPT has been sent, so + * an extra count must be kept. Decrement the count, and reset the + * readyEvent bit if the count is no longer > 0. */ + statePtr->acceptEventCount--; if (statePtr->acceptEventCount <= 0) { - statePtr->readyEvents &= ~(FD_ACCEPT); + CLEAR_BITS(statePtr->readyEvents, FD_ACCEPT); } SetEvent(tsdPtr->socketListLock); - /* Caution: TcpAccept() has the side-effect of evaluating the server - * accept script (via AcceptCallbackProc() in tclIOCmd.c), which can - * close the server socket and invalidate statePtr and fds. - * If TcpAccept() accepts a socket we must return immediately and let - * SocketCheckProc queue additional FD_ACCEPT events. + /* + * Caution: TcpAccept() has the side-effect of evaluating the + * server accept script (via AcceptCallbackProc() in tclIOCmd.c), + * which can close the server socket and invalidate statePtr and + * fds. If TcpAccept() accepts a socket we must return immediately + * and let SocketCheckProc queue additional FD_ACCEPT events. */ + TcpAccept(fds, newSocket, addr); return 1; } - /* Loop terminated with no sockets accepted; clear the ready mask so + /* + * Loop terminated with no sockets accepted; clear the ready mask so * we can detect the next connection request. Note that connection * requests are level triggered, so if there is a request already * pending, a new event will be generated. */ + statePtr->acceptEventCount = 0; - statePtr->readyEvents &= ~(FD_ACCEPT); + CLEAR_BITS(statePtr->readyEvents, FD_ACCEPT); SetEvent(tsdPtr->socketListLock); return 1; @@ -2754,16 +2882,15 @@ SocketEventProc( Tcl_Time blockTime = { 0, 0 }; Tcl_SetMaxBlockTime(&blockTime); - mask |= TCL_READABLE|TCL_WRITABLE; + SET_BITS(mask, TCL_READABLE | TCL_WRITABLE); } else if (events & FD_READ) { /* * Throw the readable event if an async connect failed. */ - if ( statePtr->flags & TCP_ASYNC_FAILED ) { - - mask |= TCL_READABLE; + if (statePtr->flags & TCP_ASYNC_FAILED) { + SET_BITS(mask, TCL_READABLE); } else { fd_set readFds; @@ -2786,9 +2913,9 @@ SocketEventProc( timeout.tv_sec = 0; if (select(0, &readFds, NULL, NULL, &timeout) != 0) { - mask |= TCL_READABLE; + SET_BITS(mask, TCL_READABLE); } else { - statePtr->readyEvents &= ~(FD_READ); + CLEAR_BITS(statePtr->readyEvents, FD_READ); SendMessage(tsdPtr->hwnd, SOCKET_SELECT, (WPARAM) SELECT, (LPARAM) statePtr); } @@ -2800,7 +2927,7 @@ SocketEventProc( */ if (events & FD_WRITE) { - mask |= TCL_WRITABLE; + SET_BITS(mask, TCL_WRITABLE); } /* @@ -2837,13 +2964,19 @@ AddSocketInfoFd( { TcpFdList *fds = statePtr->sockets; - if ( fds == NULL ) { - /* Add the first FD */ + if (fds == NULL) { + /* + * Add the first FD. + */ + statePtr->sockets = ckalloc(sizeof(TcpFdList)); fds = statePtr->sockets; } else { - /* Find end of list and append FD */ - while ( fds->next != NULL ) { + /* + * Find end of list and append FD. + */ + + while (fds->next != NULL) { fds = fds->next; } @@ -2851,7 +2984,10 @@ AddSocketInfoFd( fds = fds->next; } - /* Populate new FD */ + /* + * Populate new FD. + */ + fds->fd = socket; fds->statePtr = statePtr; fds->next = NULL; @@ -2921,6 +3057,7 @@ WaitForSocketEvent( int result = 1; int oldMode; ThreadSpecificData *tsdPtr = TclThreadDataKeyGet(&dataKey); + /* * Be sure to disable event servicing so we are truly modal. */ @@ -2939,21 +3076,36 @@ WaitForSocketEvent( while (1) { int event_found; - /* get statePtr lock */ + /* + * Get statePtr lock. + */ + WaitForSingleObject(tsdPtr->socketListLock, INFINITE); - /* Check if event occured */ + /* + * Check if event occured. + */ + event_found = (statePtr->readyEvents & events); - /* Free list lock */ + /* + * Free list lock. + */ + SetEvent(tsdPtr->socketListLock); - /* exit loop if event occured */ + /* + * Exit loop if event occured. + */ + if (event_found) { break; } - /* Exit loop if event did not occur but this is a non-blocking channel */ + /* + * Exit loop if event did not occur but this is a non-blocking channel + */ + if (statePtr->flags & TCP_NONBLOCKING) { *errorCodePtr = EWOULDBLOCK; result = 0; @@ -3110,34 +3262,34 @@ SocketProc( for (statePtr = tsdPtr->socketList; statePtr != NULL; statePtr = statePtr->nextPtr) { - if ( FindFDInList(statePtr,socket) ) { + if (FindFDInList(statePtr, socket)) { info_found = 1; break; } } + /* - * Check if there is a pending info structure not jet in the - * list + * Check if there is a pending info structure not jet in the list. */ - if ( !info_found + + if (!info_found && tsdPtr->pendingTcpState != NULL - && FindFDInList(tsdPtr->pendingTcpState,socket) ) { + && FindFDInList(tsdPtr->pendingTcpState, socket)) { statePtr = tsdPtr->pendingTcpState; info_found = 1; } if (info_found) { - /* * Update the socket state. * * A count of FD_ACCEPTS is stored, so if an FD_CLOSE event - * happens, then clear the FD_ACCEPT count. Otherwise, - * increment the count if the current event is an FD_ACCEPT. + * happens, then clear the FD_ACCEPT count. Otherwise, increment + * the count if the current event is an FD_ACCEPT. */ if (event & FD_CLOSE) { statePtr->acceptEventCount = 0; - statePtr->readyEvents &= ~(FD_WRITE|FD_ACCEPT); + CLEAR_BITS(statePtr->readyEvents, FD_WRITE | FD_ACCEPT); } else if (event & FD_ACCEPT) { statePtr->acceptEventCount++; } @@ -3147,18 +3299,22 @@ SocketProc( * Remember any error that occurred so we can report * connection failures. */ + if (error != ERROR_SUCCESS) { statePtr->notifierConnectError = error; } } + /* * Inform main thread about signaled events */ - statePtr->readyEvents |= event; + + SET_BITS(statePtr->readyEvents, event); /* * Wake up the Main Thread. */ + SetEvent(tsdPtr->readyEvent); Tcl_ThreadAlert(tsdPtr->threadId); } -- cgit v0.12 From bbfc7b1ea2d467b198933a82184a6c53de48ac00 Mon Sep 17 00:00:00 2001 From: dkf Date: Mon, 10 Apr 2017 16:21:31 +0000 Subject: More minor style fixes. --- generic/tclIO.c | 729 ++++++++++++++++++++++++++++----------------------- generic/tclIORChan.c | 57 ++-- generic/tclIOUtil.c | 51 ++-- generic/tclTimer.c | 12 +- unix/tclUnixSock.c | 48 ++-- win/tclWinSock.c | 150 ++++++----- 6 files changed, 572 insertions(+), 475 deletions(-) diff --git a/generic/tclIO.c b/generic/tclIO.c index a509ebf..32fbd59 100644 --- a/generic/tclIO.c +++ b/generic/tclIO.c @@ -321,7 +321,7 @@ static int WillRead(Channel *chanPtr); typedef struct ResolvedChanName { ChannelState *statePtr; /* The saved lookup result */ Tcl_Interp *interp; /* The interp in which the lookup was done. */ - size_t epoch; /* The epoch of the channel when the lookup + size_t epoch; /* The epoch of the channel when the lookup * was done. Use to verify validity. */ size_t refCount; /* Share this struct among many Tcl_Obj. */ } ResolvedChanName; @@ -381,20 +381,20 @@ ChanCloseHalf( * * ChanRead -- * - * Read up to dstSize bytes using the inputProc of chanPtr, store - * them at dst, and return the number of bytes stored. + * Read up to dstSize bytes using the inputProc of chanPtr, store them at + * dst, and return the number of bytes stored. * * Results: * The return value of the driver inputProc, * - number of bytes stored at dst, ot - * - -1 on error, with a Posix error code available to the - * caller by calling Tcl_GetErrno(). + * - -1 on error, with a Posix error code available to the caller by + * calling Tcl_GetErrno(). * * Side effects: - * The CHANNEL_BLOCKED and CHANNEL_EOF flags of the channel state are - * set as appropriate. - * On EOF, the inputEncodingFlags are set to perform ending operations - * on decoding. + * The CHANNEL_BLOCKED and CHANNEL_EOF flags of the channel state are set + * as appropriate. On EOF, the inputEncodingFlags are set to perform + * ending operations on decoding. + * * TODO - Is this really the right place for that? * *--------------------------------------------------------------------------- @@ -408,15 +408,17 @@ ChanRead( int bytesRead, result; /* - * If the caller asked for zero bytes, we'd force the inputProc - * to return zero bytes, and then misinterpret that as EOF. + * If the caller asked for zero bytes, we'd force the inputProc to return + * zero bytes, and then misinterpret that as EOF. */ + assert(dstSize > 0); /* * Each read op must set the blocked and eof states anew, not let * the effect of prior reads leak through. */ + if (GotFlag(chanPtr->state, CHANNEL_EOF)) { chanPtr->state->inputEncodingFlags |= TCL_ENCODING_START; } @@ -429,7 +431,10 @@ ChanRead( bytesRead = chanPtr->typePtr->inputProc(chanPtr->instanceData, dst, dstSize, &result); - /* Stop any flag leakage through stacked channel levels */ + /* + * Stop any flag leakage through stacked channel levels. + */ + if (GotFlag(chanPtr->state, CHANNEL_EOF)) { chanPtr->state->inputEncodingFlags |= TCL_ENCODING_START; } @@ -437,10 +442,10 @@ ChanRead( chanPtr->state->inputEncodingFlags &= ~TCL_ENCODING_END; if (bytesRead > 0) { /* - * If we get a short read, signal up that we may be BLOCKED. - * We should avoid calling the driver because on some - * platforms we will block in the low level reading code even - * though the channel is set into nonblocking mode. + * If we get a short read, signal up that we may be BLOCKED. We should + * avoid calling the driver because on some platforms we will block in + * the low level reading code even though the channel is set into + * nonblocking mode. */ if (bytesRead < dstSize) { @@ -574,7 +579,10 @@ TclFinalizeIOSubsystem(void) int active = 1; /* Flag == 1 while there's still work to do */ int doflushnb; - /* Fetch the pre-TIP#398 compatibility flag */ + /* + * Fetch the pre-TIP#398 compatibility flag. + */ + { const char *s; Tcl_DString ds; @@ -619,18 +627,20 @@ TclFinalizeIOSubsystem(void) */ if (active) { - TclChannelPreserve((Tcl_Channel)chanPtr); + /* - * TIP #398: by default, we no longer set the channel back into - * blocking mode. To restore the old blocking behavior, the - * environment variable TCL_FLUSH_NONBLOCKING_ON_EXIT must be set + * TIP #398: by default, we no longer set the channel back into + * blocking mode. To restore the old blocking behavior, the + * environment variable TCL_FLUSH_NONBLOCKING_ON_EXIT must be set * and not be "0". */ + if (doflushnb) { - /* Set the channel back into blocking mode to ensure that we wait - * for all data to flush out. - */ + /* + * Set the channel back into blocking mode to ensure that we + * wait for all data to flush out. + */ (void) Tcl_SetChannelOption(NULL, (Tcl_Channel) chanPtr, "-blocking", "on"); @@ -1511,8 +1521,10 @@ TclGetChannelFromObj( if ((resPtr->interp == interp) /* Same interp context */ /* No epoch change in channel since lookup */ && (resPtr->epoch == statePtr->epoch)) { + /* + * Have a valid saved lookup. Jump to end to return it. + */ - /* Have a valid saved lookup. Jump to end to return it. */ goto valid; } } @@ -1527,7 +1539,10 @@ TclGetChannelFromObj( } if (resPtr && resPtr->refCount == 1) { - /* Re-use the ResolvedCmdName struct */ + /* + * Re-use the ResolvedCmdName struct. + */ + Tcl_Release((ClientData) resPtr->statePtr); } else { @@ -1671,7 +1686,7 @@ Tcl_CreateChannel( * Set the channel up initially in AUTO input translation mode to accept * "\n", "\r" and "\r\n". Output translation mode is set to a platform * specific default value. The eofChar is set to 0 for both input and - * output, so that Tcl does not look for an in-file EOF indicator (e.g. + * output, so that Tcl does not look for an in-file EOF indicator (e.g., * ^Z) and does not append an EOF indicator to files. */ @@ -1899,7 +1914,6 @@ Tcl_StackChannel( */ if (((mask & TCL_READABLE) != 0) && (statePtr->inQueueHead != NULL)) { - /* * When statePtr->inQueueHead is not NULL, we know * prevChanPtr->inQueueHead must be NULL. @@ -2031,9 +2045,7 @@ Tcl_UnstackChannel( * of registered channels we wind down the state of the * transformation, and then restore the state of underlying channel * into the old structure. - */ - - /* + * * TODO: Figure out how to handle the situation where the chan * operations called below by this unstacking operation cause * another unstacking recursively. In that case the downChanPtr @@ -2511,6 +2523,7 @@ RecycleBuffer( /* * Do we have to free the buffer to the OS? */ + if (IsShared(bufPtr)) { mustDiscard = 1; } @@ -2521,9 +2534,8 @@ RecycleBuffer( } /* - * Only save buffers which have the requested buffersize for the - * channel. This is to honor dynamic changes of the buffersize - * made by the user. + * Only save buffers which have the requested buffersize for the channel. + * This is to honor dynamic changes of the buffersize made by the user. */ if ((bufPtr->bufLength - BUFFER_PADDING) != statePtr->bufSize) { @@ -2693,14 +2705,18 @@ FlushChannel( /* * Should we shift the current output buffer over to the output queue? * First check that there are bytes in it. If so then... - * If the output queue is empty, then yes, trusting the caller called - * us only when written bytes ought to be flushed. - * If the current output buffer is full, then yes, so we can meet - * the post-condition that on a successful return to caller we've - * left space in the current output buffer for more writing (the flush - * call was to make new room). - * If the channel is blocking, then yes, so we guarantee that - * blocking flushes actually flush all pending data. + * + * If the output queue is empty, then yes, trusting the caller called us + * only when written bytes ought to be flushed. + * + * If the current output buffer is full, then yes, so we can meet the + * post-condition that on a successful return to caller we've left space + * in the current output buffer for more writing (the flush call was to + * make new room). + * + * If the channel is blocking, then yes, so we guarantee that blocking + * flushes actually flush all pending data. + * * Otherwise, no. Keep the current output buffer where it is so more * can be written to it, possibly filling it, to promote more efficient * buffer usage. @@ -2794,8 +2810,8 @@ FlushChannel( /* * TIP #219, Tcl Channel Reflection API. * When defering the error copy a message from the bypass into - * the unreported area. Or discard it if the new error is to be - * ignored in favor of an earlier defered error. + * the unreported area. Or discard it if the new error is to + * be ignored in favor of an earlier defered error. */ Tcl_Obj *msg = statePtr->chanMsg; @@ -2847,8 +2863,11 @@ FlushChannel( ReleaseChannelBuffer(bufPtr); break; } else { - /* TODO: Consider detecting and reacting to short writes - * on blocking channels. Ought not happen. See iocmd-24.2. */ + /* + * TODO: Consider detecting and reacting to short writes on + * blocking channels. Ought not happen. See iocmd-24.2. + */ + wroteSome = 1; } @@ -2882,7 +2901,6 @@ FlushChannel( ResetFlag(statePtr, BG_FLUSH_SCHEDULED); ChanWatch(chanPtr, statePtr->interestMask); } else { - /* * When we are calledFromAsyncFlush, that means a writable * state on the channel triggered the call, so we should be @@ -2927,7 +2945,8 @@ FlushChannel( (statePtr->outQueueHead == NULL) && ((statePtr->curOutPtr == NULL) || IsBufferEmpty(statePtr->curOutPtr))) { - errorCode = CloseChannelPart(interp, chanPtr, errorCode, TCL_CLOSE_WRITE); + errorCode = CloseChannelPart(interp, chanPtr, errorCode, + TCL_CLOSE_WRITE); goto done; } @@ -3398,7 +3417,6 @@ Tcl_Close( if (GotFlag(statePtr, TCL_WRITABLE) && (statePtr->encoding != NULL) && !(statePtr->outputEncodingFlags & TCL_ENCODING_START)) { - int code = CheckChannelErrors(statePtr, TCL_WRITABLE); if (code == 0) { @@ -3488,12 +3506,14 @@ Tcl_Close( } return TCL_ERROR; } + /* * Bug 97069ea11a: set error message if a flush code is set and no error * message set up to now. */ + if (flushcode != 0 && interp != NULL - && 0 == Tcl_GetCharLength(Tcl_GetObjResult(interp)) ) { + && 0 == Tcl_GetCharLength(Tcl_GetObjResult(interp))) { Tcl_SetErrno(flushcode); Tcl_SetObjResult(interp, Tcl_NewStringObj(Tcl_PosixError(interp), -1)); @@ -3588,8 +3608,8 @@ Tcl_CloseEx( } /* - * A user may try to call half-close from within a channel close - * handler. That won't do. + * A user may try to call half-close from within a channel close handler. + * That won't do. */ if (statePtr->flags & CHANNEL_INCLOSE) { @@ -3660,9 +3680,12 @@ CloseWrite( * closed. May still be used by some * interpreter */ { - /* Notes: clear-channel-handlers - write side only ? or keep around, just - * not called. */ - /* No close cllbacks are run - channel is still open (read side) */ + /* + * Notes: clear-channel-handlers - write side only ? or keep around, just + * not called. + * + * No close callbacks are run - channel is still open (read side) + */ ChannelState *statePtr = chanPtr->state; /* State of real IO channel. */ @@ -3687,9 +3710,9 @@ CloseWrite( * Notes: Due to the assertion of CHANNEL_CLOSEDWRITE in the flags * FlushChannel() has called CloseChannelPart(). While we can still access * "chan" (no structures were freed), the only place which may still - * contain a message is the interpreter itself, and "CloseChannelPart" made - * sure to lift any channel message it generated into it. Hence the NULL - * argument in the call below. + * contain a message is the interpreter itself, and "CloseChannelPart" + * made sure to lift any channel message it generated into it. Hence the + * NULL argument in the call below. */ if (TclChanCaughtErrorBypass(interp, NULL)) { @@ -3913,10 +3936,10 @@ Tcl_ClearChannelHandlers( StopCopy(statePtr->csPtrW); /* - * Must set the interest mask now to 0, otherwise infinite loops - * will occur if Tcl_DoOneEvent is called before the channel is - * finally deleted in FlushChannel. This can happen if the channel - * has a background flush active. + * Must set the interest mask now to 0, otherwise infinite loops will + * occur if Tcl_DoOneEvent is called before the channel is finally deleted + * in FlushChannel. This can happen if the channel has a background flush + * active. */ statePtr->interestMask = 0; @@ -4185,22 +4208,24 @@ WillRead( Channel *chanPtr) { if (chanPtr->typePtr == NULL) { - /* Prevent read attempts on a closed channel */ + /* + * Prevent read attempts on a closed channel. + */ + DiscardInputQueued(chanPtr->state, 0); Tcl_SetErrno(EINVAL); return -1; } if ((chanPtr->typePtr->seekProc != NULL) && (Tcl_OutputBuffered((Tcl_Channel) chanPtr) > 0)) { - /* - * CAVEAT - The assumption here is that FlushChannel() will - * push out the bytes of any writes that are in progress. - * Since this is a seekable channel, we assume it is not one - * that can block and force bg flushing. Channels we know that - * can do that -- sockets, pipes -- are not seekable. If the - * assumption is wrong, more drastic measures may be required here - * like temporarily setting the channel into blocking mode. + * CAVEAT - The assumption here is that FlushChannel() will push out + * the bytes of any writes that are in progress. Since this is a + * seekable channel, we assume it is not one that can block and force + * bg flushing. Channels we know that can do that - sockets, pipes - + * are not seekable. If the assumption is wrong, more drastic measures + * may be required here like temporarily setting the channel into + * blocking mode. */ if (FlushChannel(NULL, chanPtr, 0) != 0) { @@ -4292,11 +4317,17 @@ Write( &statePtr->outputEncodingState, dst, dstLen + BUFFER_PADDING, &srcRead, &dstWrote, NULL); - /* See chan-io-1.[89]. Tcl Bug 506297. */ + /* + * See chan-io-1.[89]. Tcl Bug 506297. + */ + statePtr->outputEncodingFlags &= ~TCL_ENCODING_START; if ((result != TCL_OK) && (srcRead + dstWrote == 0)) { - /* We're reading from invalid/incomplete UTF-8 */ + /* + * We're reading from invalid/incomplete UTF-8. + */ + ReleaseChannelBuffer(bufPtr); if (total == 0) { Tcl_SetErrno(EINVAL); @@ -4336,11 +4367,10 @@ Write( } result |= Tcl_UtfToExternal(NULL, encoding, nl, nlLen, - statePtr->outputEncodingFlags, - &statePtr->outputEncodingState, dst, - dstLen + BUFFER_PADDING, &srcRead, &dstWrote, NULL); - - assert (srcRead == nlLen); + statePtr->outputEncodingFlags, + &statePtr->outputEncodingState, dst, + dstLen + BUFFER_PADDING, &srcRead, &dstWrote, NULL); + assert(srcRead == nlLen); bufPtr->nextAdded += dstWrote; src++; @@ -4354,11 +4384,11 @@ Write( if (IsBufferOverflowing(bufPtr)) { /* - * When translating from UTF-8 to external encoding, we - * allowed the translation to produce a character that crossed - * the end of the output buffer, so that we would get a - * completely full buffer before flushing it. The extra bytes - * will be moved to the beginning of the next buffer. + * When translating from UTF-8 to external encoding, we allowed + * the translation to produce a character that crossed the end of + * the output buffer, so that we would get a completely full + * buffer before flushing it. The extra bytes will be moved to the + * beginning of the next buffer. */ saved = -SpaceLeft(bufPtr); @@ -4378,15 +4408,16 @@ Write( flushed += statePtr->bufSize; /* - * We just flushed. So if we have needNlFlush set to record - * that we need to flush because theres a (translated) newline - * in the buffer, that's likely not true any more. But there - * is a tricky exception. If we have saved bytes that did not - * really get flushed and those bytes came from a translation - * of a newline as the last thing taken from the src array, - * then needNlFlush needs to remain set to flag that the - * next buffer still needs a newline flush. + * We just flushed. So if we have needNlFlush set to record that + * we need to flush because theres a (translated) newline in the + * buffer, that's likely not true any more. But there is a tricky + * exception. If we have saved bytes that did not really get + * flushed and those bytes came from a translation of a newline as + * the last thing taken from the src array, then needNlFlush needs + * to remain set to flag that the next buffer still needs a + * newline flush. */ + if (needNlFlush && (saved == 0 || src[-1] != '\n')) { needNlFlush = 0; } @@ -4492,8 +4523,8 @@ Tcl_GetsObj( if (GotFlag(statePtr, CHANNEL_STICKY_EOF)) { SetFlag(statePtr, CHANNEL_EOF); - assert( statePtr->inputEncodingFlags & TCL_ENCODING_END ); - assert( !GotFlag(statePtr, CHANNEL_BLOCKED|INPUT_SAW_CR) ); + assert(statePtr->inputEncodingFlags & TCL_ENCODING_END); + assert(!GotFlag(statePtr, CHANNEL_BLOCKED|INPUT_SAW_CR)); /* TODO: Do we need this? */ UpdateInterest(chanPtr); @@ -4833,17 +4864,17 @@ Tcl_GetsObj( */ done: - assert(!GotFlag(statePtr, CHANNEL_EOF) - || GotFlag(statePtr, CHANNEL_STICKY_EOF) - || Tcl_InputBuffered((Tcl_Channel)chanPtr) == 0); - - assert( !(GotFlag(statePtr, CHANNEL_EOF|CHANNEL_BLOCKED) - == (CHANNEL_EOF|CHANNEL_BLOCKED)) ); + assert(!GotFlag(statePtr, CHANNEL_EOF) + || GotFlag(statePtr, CHANNEL_STICKY_EOF) + || Tcl_InputBuffered((Tcl_Channel)chanPtr) == 0); + assert(!(GotFlag(statePtr, CHANNEL_EOF|CHANNEL_BLOCKED) + == (CHANNEL_EOF|CHANNEL_BLOCKED))); /* * Regenerate the top channel, in case it was changed due to * self-modifying reflected transforms. */ + if (chanPtr != statePtr->topChanPtr) { TclChannelRelease((Tcl_Channel)chanPtr); chanPtr = statePtr->topChanPtr; @@ -4863,10 +4894,9 @@ Tcl_GetsObj( * end-of-line or end-of-file has been seen. Bytes read from the input * channel return as a ByteArray obj. * - * WARNING! The notion of "binary" used here is different from - * notions of "binary" used in other places. In particular, this - * "binary" routine may be called when an -eofchar is set on the - * channel. + * WARNING! The notion of "binary" used here is different from notions + * of "binary" used in other places. In particular, this "binary" routine + * may be called when an -eofchar is set on the channel. * * Results: * Number of characters accumulated in the object or -1 if error, @@ -4932,8 +4962,8 @@ TclGetsObjBinary( ResetFlag(statePtr, CHANNEL_BLOCKED); while (1) { /* - * Subtract the number of bytes that were removed from channel - * buffer during last call. + * Subtract the number of bytes that were removed from channel buffer + * during last call. */ if (bufPtr != NULL) { @@ -4945,10 +4975,11 @@ TclGetsObjBinary( if ((bufPtr == NULL) || (bufPtr->nextAdded == BUFFER_PADDING)) { /* - * All channel buffers were exhausted and the caller still - * hasn't seen EOL. Need to read more bytes from the channel - * device. Side effect is to allocate another channel buffer. + * All channel buffers were exhausted and the caller still hasn't + * seen EOL. Need to read more bytes from the channel device. Side + * effect is to allocate another channel buffer. */ + if (GetInput(chanPtr) != 0) { goto restore; } @@ -4958,15 +4989,15 @@ TclGetsObjBinary( } } else { /* - * Incoming CHANNEL_STICKY_EOF is filtered out on entry. - * A new CHANNEL_STICKY_EOF set in this routine leads to - * return before coming back here. When we are not dealing - * with CHANNEL_STICKY_EOF, a CHANNEL_EOF implies an - * empty buffer. Here the buffer is non-empty so we know - * we're a non-EOF */ + * Incoming CHANNEL_STICKY_EOF is filtered out on entry. A new + * CHANNEL_STICKY_EOF set in this routine leads to return before + * coming back here. When we are not dealing with + * CHANNEL_STICKY_EOF, a CHANNEL_EOF implies an empty buffer. + * Here the buffer is non-empty so we know we're a non-EOF. + */ - assert ( !GotFlag(statePtr, CHANNEL_STICKY_EOF) ); - assert ( !GotFlag(statePtr, CHANNEL_EOF) ); + assert(!GotFlag(statePtr, CHANNEL_STICKY_EOF)); + assert(!GotFlag(statePtr, CHANNEL_EOF)); } dst = (unsigned char *) RemovePoint(bufPtr); @@ -5033,8 +5064,8 @@ TclGetsObjBinary( } /* - * Copy bytes from the channel buffer to the ByteArray. - * This may realloc space, so keep track of result. + * Copy bytes from the channel buffer to the ByteArray. This may + * realloc space, so keep track of result. */ rawLen = dstEnd - dst; @@ -5118,11 +5149,11 @@ TclGetsObjBinary( */ done: - assert(!GotFlag(statePtr, CHANNEL_EOF) - || GotFlag(statePtr, CHANNEL_STICKY_EOF) - || Tcl_InputBuffered((Tcl_Channel)chanPtr) == 0); - assert( !(GotFlag(statePtr, CHANNEL_EOF|CHANNEL_BLOCKED) - == (CHANNEL_EOF|CHANNEL_BLOCKED)) ); + assert(!GotFlag(statePtr, CHANNEL_EOF) + || GotFlag(statePtr, CHANNEL_STICKY_EOF) + || Tcl_InputBuffered((Tcl_Channel)chanPtr) == 0); + assert(!(GotFlag(statePtr, CHANNEL_EOF|CHANNEL_BLOCKED) + == (CHANNEL_EOF|CHANNEL_BLOCKED))); UpdateInterest(chanPtr); TclChannelRelease((Tcl_Channel)chanPtr); return copiedTotal; @@ -5255,15 +5286,15 @@ FilterInputBytes( } } else { /* - * Incoming CHANNEL_STICKY_EOF is filtered out on entry. - * A new CHANNEL_STICKY_EOF set in this routine leads to - * return before coming back here. When we are not dealing - * with CHANNEL_STICKY_EOF, a CHANNEL_EOF implies an - * empty buffer. Here the buffer is non-empty so we know - * we're a non-EOF */ + * Incoming CHANNEL_STICKY_EOF is filtered out on entry. A new + * CHANNEL_STICKY_EOF set in this routine leads to return before + * coming back here. When we are not dealing with CHANNEL_STICKY_EOF, + * a CHANNEL_EOF implies an empty buffer. Here the buffer is + * non-empty so we know we're a non-EOF. + */ - assert ( !GotFlag(statePtr, CHANNEL_STICKY_EOF) ); - assert ( !GotFlag(statePtr, CHANNEL_EOF) ); + assert(!GotFlag(statePtr, CHANNEL_STICKY_EOF)); + assert(!GotFlag(statePtr, CHANNEL_EOF)); } /* @@ -5593,7 +5624,9 @@ Tcl_ReadRaw( return -1; } - /* First read bytes from the push-back buffers. */ + /* + * First read bytes from the push-back buffers. + */ while (chanPtr->inQueueHead && bytesToRead > 0) { ChannelBuffer *bufPtr = chanPtr->inQueueHead; @@ -5601,7 +5634,9 @@ Tcl_ReadRaw( int toCopy = (bytesInBuffer < bytesToRead) ? bytesInBuffer : bytesToRead; - /* Copy the current chunk into the read buffer. */ + /* + * Copy the current chunk into the read buffer. + */ memcpy(readBuf, RemovePoint(bufPtr), (size_t) toCopy); bufPtr->nextRemoved += toCopy; @@ -5609,7 +5644,9 @@ Tcl_ReadRaw( readBuf += toCopy; bytesToRead -= toCopy; - /* If the current buffer is empty recycle it. */ + /* + * If the current buffer is empty recycle it. + */ if (IsBufferEmpty(bufPtr)) { chanPtr->inQueueHead = bufPtr->nextPtr; @@ -5621,37 +5658,40 @@ Tcl_ReadRaw( } /* - * Go to the driver only if we got nothing from pushback. - * Have to do it this way to avoid EOF mis-timings when we - * consider the ability that EOF may not be a permanent - * condition in the driver, and in that case we have to - * synchronize. + * Go to the driver only if we got nothing from pushback. Have to do it + * this way to avoid EOF mis-timings when we consider the ability that EOF + * may not be a permanent condition in the driver, and in that case we + * have to synchronize. */ if (copied) { return copied; } - /* This test not needed. */ - if (bytesToRead > 0) { + /* + * This test not needed. + */ + if (bytesToRead > 0) { int nread = ChanRead(chanPtr, readBuf, bytesToRead); if (nread > 0) { - /* Successful read (short is OK) - add to bytes copied */ + /* + * Successful read (short is OK) - add to bytes copied. + */ + copied += nread; } else if (nread < 0) { /* - * An error signaled. If CHANNEL_BLOCKED, then the error - * is not real, but an indication of blocked state. In - * that case, retain the flag and let caller receive the - * short read of copied bytes from the pushback. - * HOWEVER, if copied==0 bytes from pushback then repeat - * signalling the blocked state as an error to caller so - * there is no false report of an EOF. - * When !CHANNEL_BLOCKED, the error is real and passes on - * to caller. + * An error signaled. If CHANNEL_BLOCKED, then the error is not + * real, but an indication of blocked state. In that case, retain + * the flag and let caller receive the short read of copied bytes + * from the pushback. HOWEVER, if copied==0 bytes from pushback + * then repeat signalling the blocked state as an error to caller + * so there is no false report of an EOF. When !CHANNEL_BLOCKED, + * the error is real and passes on to caller. */ + if (!GotFlag(statePtr, CHANNEL_BLOCKED) || copied == 0) { copied = -1; } @@ -5788,21 +5828,23 @@ DoReadChars( /* * Early out when next read will see eofchar. * - * NOTE: See DoRead for argument that it's a bug (one we're keeping) - * to have this escape before the one for zero-char read request. + * NOTE: See DoRead for argument that it's a bug (one we're keeping) to + * have this escape before the one for zero-char read request. */ if (GotFlag(statePtr, CHANNEL_STICKY_EOF)) { SetFlag(statePtr, CHANNEL_EOF); - assert( statePtr->inputEncodingFlags & TCL_ENCODING_END ); - assert( !GotFlag(statePtr, CHANNEL_BLOCKED|INPUT_SAW_CR) ); + assert(statePtr->inputEncodingFlags & TCL_ENCODING_END); + assert(!GotFlag(statePtr, CHANNEL_BLOCKED|INPUT_SAW_CR)); /* TODO: We don't need this call? */ UpdateInterest(chanPtr); return 0; } - /* Special handling for zero-char read request. */ + /* + * Special handling for zero-char read request. + */ if (toRead == 0) { if (GotFlag(statePtr, CHANNEL_EOF)) { statePtr->inputEncodingFlags |= TCL_ENCODING_START; @@ -5821,7 +5863,10 @@ DoReadChars( chanPtr = statePtr->topChanPtr; TclChannelPreserve((Tcl_Channel)chanPtr); - /* Must clear the BLOCKED|EOF flags here since we check before reading */ + /* + * Must clear the BLOCKED|EOF flags here since we check before reading. + */ + if (GotFlag(statePtr, CHANNEL_EOF)) { statePtr->inputEncodingFlags |= TCL_ENCODING_START; } @@ -5879,10 +5924,11 @@ DoReadChars( } /* - * Failure to fill a channel buffer may have left channel reporting - * a "blocked" state, but so long as we fulfilled the request here, - * the caller does not consider us blocked. + * Failure to fill a channel buffer may have left channel reporting a + * "blocked" state, but so long as we fulfilled the request here, the + * caller does not consider us blocked. */ + if (toRead == 0) { ResetFlag(statePtr, CHANNEL_BLOCKED); } @@ -5891,6 +5937,7 @@ DoReadChars( * Regenerate the top channel, in case it was changed due to * self-modifying reflected transforms. */ + if (chanPtr != statePtr->topChanPtr) { TclChannelRelease((Tcl_Channel)chanPtr); chanPtr = statePtr->topChanPtr; @@ -5901,11 +5948,12 @@ DoReadChars( * Update the notifier state so we don't block while there is still data * in the buffers. */ - assert(!GotFlag(statePtr, CHANNEL_EOF) - || GotFlag(statePtr, CHANNEL_STICKY_EOF) - || Tcl_InputBuffered((Tcl_Channel)chanPtr) == 0); - assert( !(GotFlag(statePtr, CHANNEL_EOF|CHANNEL_BLOCKED) - == (CHANNEL_EOF|CHANNEL_BLOCKED)) ); + + assert(!GotFlag(statePtr, CHANNEL_EOF) + || GotFlag(statePtr, CHANNEL_STICKY_EOF) + || Tcl_InputBuffered((Tcl_Channel)chanPtr) == 0); + assert(!(GotFlag(statePtr, CHANNEL_EOF|CHANNEL_BLOCKED) + == (CHANNEL_EOF|CHANNEL_BLOCKED))); UpdateInterest(chanPtr); TclChannelRelease((Tcl_Channel)chanPtr); return copied; @@ -6022,11 +6070,10 @@ ReadChars( int numBytes, srcLen = BytesLeft(bufPtr); /* - * One src byte can yield at most one character. So when the - * number of src bytes we plan to read is less than the limit on - * character count to be read, clearly we will remain within that - * limit, and we can use the value of "srcLen" as a tighter limit - * for sizing receiving buffers. + * One src byte can yield at most one character. So when the number of + * src bytes we plan to read is less than the limit on character count to + * be read, clearly we will remain within that limit, and we can use the + * value of "srcLen" as a tighter limit for sizing receiving buffers. */ int toRead = ((charsToRead<0)||(charsToRead > srcLen)) ? srcLen : charsToRead; @@ -6044,6 +6091,7 @@ ReadChars( Tcl_AppendToObj(objPtr, NULL, dstLimit); if (toRead == srcLen) { unsigned int size; + dst = TclGetStringStorage(objPtr, &size) + numBytes; dstLimit = size - numBytes; } else { @@ -6051,19 +6099,18 @@ ReadChars( } /* - * This routine is burdened with satisfying several constraints. - * It cannot append more than 'charsToRead` chars onto objPtr. - * This is measured after encoding and translation transformations - * are completed. There is no precise number of src bytes that can - * be associated with the limit. Yet, when we are done, we must know - * precisely the number of src bytes that were consumed to produce - * the appended chars, so that all subsequent bytes are left in - * the buffers for future read operations. + * This routine is burdened with satisfying several constraints. It cannot + * append more than 'charsToRead` chars onto objPtr. This is measured + * after encoding and translation transformations are completed. There is + * no precise number of src bytes that can be associated with the limit. + * Yet, when we are done, we must know precisely the number of src bytes + * that were consumed to produce the appended chars, so that all + * subsequent bytes are left in the buffers for future read operations. * - * The consequence is that we have no choice but to implement a - * "trial and error" approach, where in general we may need to - * perform transformations and copies multiple times to achieve - * a consistent set of results. This takes the shape of a loop. + * The consequence is that we have no choice but to implement a "trial and + * error" approach, where in general we may need to perform + * transformations and copies multiple times to achieve a consistent set + * of results. This takes the shape of a loop. */ while (1) { @@ -6076,18 +6123,17 @@ ReadChars( } /* - * Perform the encoding transformation. Read no more than - * srcLen bytes, write no more than dstLimit bytes. + * Perform the encoding transformation. Read no more than srcLen + * bytes, write no more than dstLimit bytes. * - * Some trickiness with encoding flags here. We do not want - * the end of a buffer to be treated as the end of all input - * when the presence of bytes in a next buffer are already - * known to exist. This is checked with an assert() because - * so far no test case causing the assertion to be false has - * been created. The normal operations of channel reading - * appear to cause EOF and TCL_ENCODING_END setting to appear - * only in situations where there are no further bytes in - * any buffers. + * Some trickiness with encoding flags here. We do not want the end + * of a buffer to be treated as the end of all input when the presence + * of bytes in a next buffer are already known to exist. This is + * checked with an assert() because so far no test case causing the + * assertion to be false has been created. The normal operations of + * channel reading appear to cause EOF and TCL_ENCODING_END setting to + * appear only in situations where there are no further bytes in any + * buffers. */ assert(bufPtr->nextPtr == NULL || BytesLeft(bufPtr->nextPtr) == 0 @@ -6098,10 +6144,10 @@ ReadChars( dst, dstLimit, &srcRead, &dstDecoded, &numChars); /* - * Perform the translation transformation in place. Read no more - * than the dstDecoded bytes the encoding transformation actually - * produced. Capture the number of bytes written in dstWrote. - * Capture the number of bytes actually consumed in dstRead. + * Perform the translation transformation in place. Read no more than + * the dstDecoded bytes the encoding transformation actually produced. + * Capture the number of bytes written in dstWrote. Capture the number + * of bytes actually consumed in dstRead. */ dstWrote = dstLimit; @@ -6109,11 +6155,9 @@ ReadChars( TranslateInputEOL(statePtr, dst, dst, &dstWrote, &dstRead); if (dstRead < dstDecoded) { - /* - * The encoding transformation produced bytes that the - * translation transformation did not consume. Why did - * this happen? + * The encoding transformation produced bytes that the translation + * transformation did not consume. Why did this happen? */ if (statePtr->inEofChar && dst[dstRead] == statePtr->inEofChar) { @@ -6122,40 +6166,38 @@ ReadChars( * we saw it and stopped translating at that point. * * NOTE the bizarre spec of TranslateInputEOL in this case. - * Clearly the eof char had to be read in order to account - * for the stopping, but the value of dstRead does not - * include it. + * Clearly the eof char had to be read in order to account for + * the stopping, but the value of dstRead does not include it. * - * Also rather bizarre, our caller can only notice an - * EOF condition if we return the value -1 as the number - * of chars read. This forces us to perform a 2-call - * dance where the first call can read all the chars - * up to the eof char, and the second call is solely - * for consuming the encoded eof char then pointed at - * by src so that we can return that magic -1 value. - * This seems really wasteful, especially since - * the first decoding pass of each call is likely to - * decode many bytes beyond that eof char that's all we - * care about. + * Also rather bizarre, our caller can only notice an EOF + * condition if we return the value -1 as the number of chars + * read. This forces us to perform a 2-call dance where the + * first call can read all the chars up to the eof char, and + * the second call is solely for consuming the encoded eof + * char then pointed at by src so that we can return that + * magic -1 value. This seems really wasteful, especially + * since the first decoding pass of each call is likely to + * decode many bytes beyond that eof char that's all we care + * about. */ if (dstRead == 0) { /* - * Curious choice in the eof char handling. We leave - * the eof char in the buffer. So, no need to compute - * a proper srcRead value. At this point, there - * are no chars before the eof char in the buffer. + * Curious choice in the eof char handling. We leave the + * eof char in the buffer. So, no need to compute a proper + * srcRead value. At this point, there are no chars before + * the eof char in the buffer. */ + Tcl_SetObjLength(objPtr, numBytes); return -1; } { /* - * There are chars leading the buffer before the eof - * char. Adjust the dstLimit so we go back and read - * only those and do not encounter the eof char this - * time. + * There are chars leading the buffer before the eof char. + * Adjust the dstLimit so we go back and read only those + * and do not encounter the eof char this time. */ dstLimit = dstRead - 1 + TCL_UTF_MAX; @@ -6167,10 +6209,9 @@ ReadChars( } /* - * 2) The other way to read fewer bytes than are decoded - * is when the final byte is \r and we're in a CRLF - * translation mode so we cannot decide whether to - * record \r or \n yet. + * 2) The other way to read fewer bytes than are decoded is when + * the final byte is \r and we're in a CRLF translation mode so + * we cannot decide whether to record \r or \n yet. */ assert(dst[dstRead] == '\r'); @@ -6178,10 +6219,10 @@ ReadChars( if (dstWrote > 0) { /* - * There are chars we can read before we hit the bare cr. - * Go back with a smaller dstLimit so we get them in the - * next pass, compute a matching srcRead, and don't end - * up back here in this call. + * There are chars we can read before we hit the bare CR. Go + * back with a smaller dstLimit so we get them in the next + * pass, compute a matching srcRead, and don't end up back + * here in this call. */ dstLimit = dstRead - 1 + TCL_UTF_MAX; @@ -6195,9 +6236,9 @@ ReadChars( assert(dstRead == 0); /* - * We decoded only the bare cr, and we cannot read a - * translated char from that alone. We have to know what's - * next. So why do we only have the one decoded char? + * We decoded only the bare CR, and we cannot read a translated + * char from that alone. We have to know what's next. So why do + * we only have the one decoded char? */ if (code != TCL_OK) { @@ -6238,10 +6279,9 @@ ReadChars( } } else if (statePtr->flags & CHANNEL_EOF) { - /* - * The bare \r is the only char and we will never read - * a subsequent char to make the determination. + * The bare \r is the only char and we will never read a + * subsequent char to make the determination. */ dst[0] = '\r'; @@ -6251,8 +6291,8 @@ ReadChars( } /* - * Revise the dstRead value so that the numChars calc - * below correctly computes zero characters read. + * Revise the dstRead value so that the numChars calc below + * correctly computes zero characters read. */ dstRead = numChars; @@ -6261,9 +6301,9 @@ ReadChars( } /* - * The translation transformation can only reduce the number - * of chars when it converts \r\n into \n. The reduction in - * the number of chars is the difference in bytes read and written. + * The translation transformation can only reduce the number of chars + * when it converts \r\n into \n. The reduction in the number of chars + * is the difference in bytes read and written. */ numChars -= (dstRead - dstWrote); @@ -6273,10 +6313,9 @@ ReadChars( /* * TODO: This cannot happen anymore. * - * We read more chars than allowed. Reset limits to - * prevent that and try again. Don't forget the extra - * padding of TCL_UTF_MAX bytes demanded by the - * Tcl_ExternalToUtf() call! + * We read more chars than allowed. Reset limits to prevent that + * and try again. Don't forget the extra padding of TCL_UTF_MAX + * bytes demanded by the Tcl_ExternalToUtf() call! */ dstLimit = Tcl_UtfAtIndex(dst, charsToRead) - 1 + TCL_UTF_MAX - dst; @@ -6289,18 +6328,19 @@ ReadChars( if (dstWrote == 0) { ChannelBuffer *nextPtr; - /* We were not able to read any chars. */ + /* + * We were not able to read any chars. + */ - assert (numChars == 0); + assert(numChars == 0); /* - * There is one situation where this is the correct final - * result. If the src buffer contains only a single \n - * byte, and we are in TCL_TRANSLATE_AUTO mode, and - * when the translation pass was made the INPUT_SAW_CR - * flag was set on the channel. In that case, the - * correct behavior is to consume that \n and produce the - * empty string. + * There is one situation where this is the correct final result. + * If the src buffer contains only a single \n byte, and we are in + * TCL_TRANSLATE_AUTO mode, and when the translation pass was made + * the INPUT_SAW_CR flag was set on the channel. In that case, the + * correct behavior is to consume that \n and produce the empty + * string. */ if (dstRead == 1 && dst[0] == '\n') { @@ -6309,12 +6349,13 @@ ReadChars( goto consume; } - /* Otherwise, reading zero characters indicates there's - * something incomplete at the end of the src buffer. - * Maybe there were not enough src bytes to decode into - * a char. Maybe a lone \r could not be translated (crlf - * mode). Need to combine any unused src bytes we have - * in the first buffer with subsequent bytes to try again. + /* + * Otherwise, reading zero characters indicates there's something + * incomplete at the end of the src buffer. Maybe there were not + * enough src bytes to decode into a char. Maybe a lone \r could + * not be translated (crlf mode). Need to combine any unused src + * bytes we have in the first buffer with subsequent bytes to try + * again. */ nextPtr = bufPtr->nextPtr; @@ -6329,15 +6370,15 @@ ReadChars( /* * Space is made at the beginning of the buffer to copy the - * previous unused bytes there. Check first if the buffer we - * are using actually has enough space at its beginning for - * the data we are copying. Because if not we will write over - * the buffer management information, especially the 'nextPtr'. + * previous unused bytes there. Check first if the buffer we are + * using actually has enough space at its beginning for the data + * we are copying. Because if not we will write over the buffer + * management information, especially the 'nextPtr'. * - * Note that the BUFFER_PADDING (See AllocChannelBuffer) is - * used to prevent exactly this situation. I.e. it should never - * happen. Therefore it is ok to panic should it happen despite - * the precautions. + * Note that the BUFFER_PADDING (See AllocChannelBuffer) is used + * to prevent exactly this situation. I.e. it should never happen. + * Therefore it is ok to panic should it happen despite the + * precautions. */ if (nextPtr->nextRemoved - srcLen < 0) { @@ -6356,10 +6397,12 @@ ReadChars( consume: bufPtr->nextRemoved += srcRead; + /* - * If this read contained multibyte characters, revise factorPtr - * so the next read will allocate bigger buffers. + * If this read contained multibyte characters, revise factorPtr so + * the next read will allocate bigger buffers. */ + if (numChars && numChars < srcRead) { *factorPtr = srcRead * UTF_EXPANSION_FACTOR / numChars; } @@ -6407,22 +6450,27 @@ TranslateInputEOL( int inEofChar = statePtr->inEofChar; /* - * Depending on the translation mode in use, there's no need - * to scan more srcLen bytes at srcStart than can possibly transform - * to dstLen bytes. This keeps the scan for eof char below from - * being pointlessly long. + * Depending on the translation mode in use, there's no need to scan more + * srcLen bytes at srcStart than can possibly transform to dstLen bytes. + * This keeps the scan for eof char below from being pointlessly long. */ switch (statePtr->inputTranslation) { case TCL_TRANSLATE_LF: case TCL_TRANSLATE_CR: if (srcLen > dstLen) { - /* In these modes, each src byte become a dst byte. */ + /* + * In these modes, each src byte become a dst byte. + */ + srcLen = dstLen; } break; default: - /* In other modes, at most 2 src bytes become a dst byte. */ + /* + * In other modes, at most 2 src bytes become a dst byte. + */ + if (srcLen/2 > dstLen) { srcLen = 2 * dstLen; } @@ -6755,7 +6803,7 @@ GetInput( * eofchar. */ - assert( !GotFlag(statePtr, CHANNEL_STICKY_EOF) ); + assert(!GotFlag(statePtr, CHANNEL_STICKY_EOF)); /* * Prevent reading from a dead channel -- a channel that has been closed @@ -6769,24 +6817,21 @@ GetInput( } /* - * WARNING: There was once a comment here claiming that it was - * a bad idea to make another call to the inputproc of a channel - * driver when EOF has already been detected on the channel. Through - * much of Tcl's history, this warning was then completely negated - * by having all (most?) read paths clear the EOF setting before - * reaching here. So we had a guard that was never triggered. + * WARNING: There was once a comment here claiming that it was a bad idea + * to make another call to the inputproc of a channel driver when EOF has + * already been detected on the channel. Through much of Tcl's history, + * this warning was then completely negated by having all (most?) read + * paths clear the EOF setting before reaching here. So we had a guard + * that was never triggered. + * + * Don't be tempted to restore the guard. Even if EOF is set on the + * channel, continue through and call the inputproc again. This is the + * way to enable the ability to [read] again beyond the EOF, which seems a + * strange thing to do, but for which use cases exist [Tcl Bug 5adc350683] + * and which may even be essential for channels representing things like + * ttys or other devices where the stream might take the logical form of a + * series of 'files' separated by an EOF condition. * - * Don't be tempted to restore the guard. Even if EOF is set on - * the channel, continue through and call the inputproc again. This - * is the way to enable the ability to [read] again beyond the EOF, - * which seems a strange thing to do, but for which use cases exist - * [Tcl Bug 5adc350683] and which may even be essential for channels - * representing things like ttys or other devices where the stream - * might take the logical form of a series of 'files' separated by - * an EOF condition. - */ - - /* * First check for more buffers in the pushback area of the topmost * channel in the stack and use them. They can be the result of a * transformation which went away without reading all the information @@ -6794,7 +6839,6 @@ GetInput( */ if (chanPtr->inQueueHead != NULL) { - /* TODO: Tests to cover this. */ assert(statePtr->inQueueHead == NULL); @@ -6824,8 +6868,9 @@ GetInput( /* * Check the actual buffersize against the requested buffersize. - * Saved buffers of the wrong size are squashed. This is done - * to honor dynamic changes of the buffersize made by the user. + * Saved buffers of the wrong size are squashed. This is done to honor + * dynamic changes of the buffersize made by the user. + * * TODO: Tests to cover this. */ @@ -7132,7 +7177,7 @@ Tcl_Tell( * Truncate a channel to the given length. * * Results: - * TCL_OK on success, TCL_ERROR if the operation failed (e.g. is not + * TCL_OK on success, TCL_ERROR if the operation failed (e.g., is not * supported by the type of channel, or the underlying OS operation * failed in some way). * @@ -9492,7 +9537,10 @@ CopyData( } if (size == 0) { if (!GotFlag(inStatePtr, CHANNEL_NONBLOCKING)) { - /* We allowed a short read. Keep trying. */ + /* + * We allowed a short read. Keep trying. + */ + continue; } if (bufObj != NULL) { @@ -9706,7 +9754,7 @@ DoRead( ChannelState *statePtr = chanPtr->state; char *p = dst; - assert (bytesToRead >= 0); + assert(bytesToRead >= 0); /* * Early out when we know a read will get the eofchar. @@ -9722,15 +9770,18 @@ DoRead( if (GotFlag(statePtr, CHANNEL_STICKY_EOF)) { SetFlag(statePtr, CHANNEL_EOF); - assert( statePtr->inputEncodingFlags & TCL_ENCODING_END ); - assert( !GotFlag(statePtr, CHANNEL_BLOCKED|INPUT_SAW_CR) ); + assert(statePtr->inputEncodingFlags & TCL_ENCODING_END); + assert(!GotFlag(statePtr, CHANNEL_BLOCKED|INPUT_SAW_CR)); /* TODO: Don't need this call */ UpdateInterest(chanPtr); return 0; } - /* Special handling for zero-char read request. */ + /* + * Special handling for zero-char read request. + */ + if (bytesToRead == 0) { if (GotFlag(statePtr, CHANNEL_EOF)) { statePtr->inputEncodingFlags |= TCL_ENCODING_START; @@ -9745,8 +9796,8 @@ DoRead( TclChannelPreserve((Tcl_Channel)chanPtr); while (bytesToRead) { /* - * Each pass through the loop is intended to process up to - * one channel buffer. + * Each pass through the loop is intended to process up to one channel + * buffer. */ int bytesRead, bytesWritten; @@ -9758,33 +9809,39 @@ DoRead( while (!bufPtr || /* We got no buffer! OR */ (!IsBufferFull(bufPtr) && /* Our buffer has room AND */ - (BytesLeft(bufPtr) < bytesToRead) ) ) { - /* Not enough bytes in it - * yet to fill the dst */ + (BytesLeft(bufPtr) < bytesToRead))) { + /* Not enough bytes in it yet + * to fill the dst */ int code; moreData: code = GetInput(chanPtr); bufPtr = statePtr->inQueueHead; - assert (bufPtr != NULL); + assert(bufPtr != NULL); if (GotFlag(statePtr, CHANNEL_EOF|CHANNEL_BLOCKED)) { - /* Further reads cannot do any more */ + /* + * Further reads cannot do any more. + */ + break; } if (code) { - /* Read error */ + /* + * Read error + */ + UpdateInterest(chanPtr); TclChannelRelease((Tcl_Channel)chanPtr); return -1; } - assert (IsBufferFull(bufPtr)); + assert(IsBufferFull(bufPtr)); } - assert (bufPtr != NULL); + assert(bufPtr != NULL); bytesRead = BytesLeft(bufPtr); bytesWritten = bytesToRead; @@ -9799,8 +9856,8 @@ DoRead( /* * Buffer is not empty. How can that be? * - * 0) We stopped early because we got all the bytes - * we were seeking. That's fine. + * 0) We stopped early because we got all the bytes we were + * seeking. That's fine. */ if (bytesToRead == 0) { @@ -9816,8 +9873,8 @@ DoRead( } /* - * 2) The buffer holds a \r while in CRLF translation, - * followed by the end of the buffer. + * 2) The buffer holds a \r while in CRLF translation, followed by + * the end of the buffer. */ assert(statePtr->inputTranslation == TCL_TRANSLATE_CRLF); @@ -9825,26 +9882,38 @@ DoRead( assert(BytesLeft(bufPtr) == 1); if (bufPtr->nextPtr == NULL) { - /* There's no more buffered data.... */ + /* + * There's no more buffered data... + */ if (statePtr->flags & CHANNEL_EOF) { - /* ...and there never will be. */ + /* + * ...and there never will be. + */ *p++ = '\r'; bytesToRead--; bufPtr->nextRemoved++; } else if (statePtr->flags & CHANNEL_BLOCKED) { - /* ...and we cannot get more now. */ + /* + * ...and we cannot get more now. + */ + SetFlag(statePtr, CHANNEL_NEED_MORE_DATA); break; } else { - /* ... so we need to get some. */ + /* + * ...so we need to get some. + */ + goto moreData; } } if (bufPtr->nextPtr) { - /* There's a next buffer. Shift orphan \r to it. */ + /* + * There's a next buffer. Shift orphan \r to it. + */ ChannelBuffer *nextPtr = bufPtr->nextPtr; @@ -9869,8 +9938,8 @@ DoRead( } /* - * When there's no buffered data to read, and we're at EOF, - * escape to the caller. + * When there's no buffered data to read, and we're at EOF, escape to + * the caller. */ if (GotFlag(statePtr, CHANNEL_EOF) @@ -9882,11 +9951,11 @@ DoRead( ResetFlag(statePtr, CHANNEL_BLOCKED); } - assert(!GotFlag(statePtr, CHANNEL_EOF) - || GotFlag(statePtr, CHANNEL_STICKY_EOF) - || Tcl_InputBuffered((Tcl_Channel)chanPtr) == 0); - assert( !(GotFlag(statePtr, CHANNEL_EOF|CHANNEL_BLOCKED) - == (CHANNEL_EOF|CHANNEL_BLOCKED)) ); + assert(!GotFlag(statePtr, CHANNEL_EOF) + || GotFlag(statePtr, CHANNEL_STICKY_EOF) + || Tcl_InputBuffered((Tcl_Channel)chanPtr) == 0); + assert(!(GotFlag(statePtr, CHANNEL_EOF|CHANNEL_BLOCKED) + == (CHANNEL_EOF|CHANNEL_BLOCKED))); UpdateInterest(chanPtr); TclChannelRelease((Tcl_Channel)chanPtr); return (int)(p - dst); diff --git a/generic/tclIORChan.c b/generic/tclIORChan.c index 2fed3f4..433fb6f 100644 --- a/generic/tclIORChan.c +++ b/generic/tclIORChan.c @@ -851,11 +851,12 @@ TclChanPostEventObjCmd( } /* - * Note that the search above subsumes several of the older checks, namely: + * Note that the search above subsumes several of the older checks, + * namely: * - * (1) Does the channel handle refer to a reflected channel ? + * (1) Does the channel handle refer to a reflected channel? * (2) Is the post event issued from the interpreter holding the handler - * of the reflected channel ? + * of the reflected channel? * * A successful search answers yes to both. Because the map holds only * handles of reflected channels, and only of such whose handler is @@ -939,7 +940,8 @@ TclChanPostEventObjCmd( (void) GetThreadReflectedChannelMap(); - /* XXX Race condition !! + /* + * XXX Race condition !! * XXX The destination thread may not exist anymore already. * XXX (Delayed postevent executed after channel got removed). * XXX Can we detect this ? (check the validity of the owner threadid ?) @@ -1221,8 +1223,8 @@ ReflectClose( #endif tctPtr = ((Channel *)rcPtr->chan)->typePtr; if (tctPtr && tctPtr != &tclRChannelType) { - ckfree(tctPtr); - ((Channel *)rcPtr->chan)->typePtr = NULL; + ckfree(tctPtr); + ((Channel *)rcPtr->chan)->typePtr = NULL; } Tcl_EventuallyFree(rcPtr, (Tcl_FreeProc *) FreeReflectedChannel); return (result == TCL_OK) ? EOK : EINVAL; @@ -1272,7 +1274,10 @@ ReflectInput( if (p.base.code != TCL_OK) { if (p.base.code < 0) { - /* No error message, this is an errno signal. */ + /* + * No error message, this is an errno signal. + */ + *errorCodePtr = -p.base.code; } else { PassReceivedError(rcPtr->chan, &p); @@ -1375,7 +1380,10 @@ ReflectOutput( if (p.base.code != TCL_OK) { if (p.base.code < 0) { - /* No error message, this is an errno signal. */ + /* + * No error message, this is an errno signal. + */ + *errorCodePtr = -p.base.code; } else { PassReceivedError(rcPtr->chan, &p); @@ -1426,8 +1434,8 @@ ReflectOutput( if ((written == 0) && (toWrite > 0)) { /* - * The handler claims to have written nothing of what it was - * given. That is bad. + * The handler claims to have written nothing of what it was given. + * That is bad. */ SetChannelErrorStr(rcPtr->chan, msg_write_nothing); @@ -2373,8 +2381,8 @@ InvokeTclMethod( * None. * * Users: - * ReflectInput/Output(), to enable the signaling of EAGAIN - * on 0-sized short reads/writes. + * ReflectInput/Output(), to enable the signaling of EAGAIN on 0-sized + * short reads/writes. * *---------------------------------------------------------------------- */ @@ -2560,7 +2568,10 @@ DeleteReflectedChannelMap( evPtr = resultPtr->evPtr; - /* Basic crash safety until this routine can get revised [3411310] */ + /* + * Basic crash safety until this routine can get revised [3411310] + */ + if (evPtr == NULL) { continue; } @@ -2675,8 +2686,8 @@ DeleteThreadReflectedChannelMap( /* * Go through the list of pending results and cancel all whose events were - * destined for this thread. While this is in progress we block any - * other access to the list of pending results. + * destined for this thread. While this is in progress we block any other + * access to the list of pending results. */ Tcl_MutexLock(&rcForwardMutex); @@ -2707,7 +2718,10 @@ DeleteThreadReflectedChannelMap( evPtr = resultPtr->evPtr; - /* Basic crash safety until this routine can get revised [3411310] */ + /* + * Basic crash safety until this routine can get revised [3411310] + */ + if (evPtr == NULL ) { continue; } @@ -2761,8 +2775,8 @@ ForwardOpToHandlerThread( const void *param) /* Arguments */ { /* - * Core of the communication from OWNER to HANDLER thread. - * The receiver is ForwardProc() below. + * Core of the communication from OWNER to HANDLER thread. The receiver is + * ForwardProc() below. */ Tcl_ThreadId dst = rcPtr->thread; @@ -2812,7 +2826,10 @@ ForwardOpToHandlerThread( */ TclSpliceIn(resultPtr, forwardList); - /* Do not unlock here. That is done by the ConditionWait */ + + /* + * Do not unlock here. That is done by the ConditionWait. + */ /* * Ensure cleanup of the event if the origin thread exits while this event @@ -2888,7 +2905,7 @@ ForwardProc( * Notes regarding access to the referenced data. * * In principle the data belongs to the originating thread (see - * evPtr->src), however this thread is currently blocked at (*), i.e. + * evPtr->src), however this thread is currently blocked at (*), i.e., * quiescent. Because of this we can treat the data as belonging to us, * without fear of race conditions. I.e. we can read and write as we like. * diff --git a/generic/tclIOUtil.c b/generic/tclIOUtil.c index de5d62d..5f79e6e 100644 --- a/generic/tclIOUtil.c +++ b/generic/tclIOUtil.c @@ -611,6 +611,7 @@ FsRecacheFilesystemList(void) while (toFree) { FilesystemRecord *next = toFree->nextPtr; + toFree->fsPtr = NULL; ckfree(toFree); toFree = next; @@ -672,7 +673,6 @@ TclFSEpoch(void) return tsdPtr->filesystemEpoch; } - /* * If non-NULL, clientData is owned by us and must be freed later. @@ -784,7 +784,9 @@ TclFinalizeFilesystem(void) while (fsRecPtr != NULL) { FilesystemRecord *tmpFsRecPtr = fsRecPtr->nextPtr; - /* The native filesystem is static, so we don't free it. */ + /* + * The native filesystem is static, so we don't free it. + */ if (fsRecPtr != &nativeFilesystemRecord) { ckfree(fsRecPtr); @@ -947,7 +949,7 @@ Tcl_FSRegister( int Tcl_FSUnregister( - const Tcl_Filesystem *fsPtr) /* The filesystem record to remove. */ + const Tcl_Filesystem *fsPtr)/* The filesystem record to remove. */ { int retVal = TCL_ERROR; FilesystemRecord *fsRecPtr; @@ -1233,7 +1235,7 @@ FsAddMountsToGlobResult( len--; } - len++; /* account for '/' in the mElt [Bug 1602539] */ + len++; /* account for '/' in the mElt [Bug 1602539] */ mElt = TclNewFSPathObj(pathPtr, mount + len, mlen - len); Tcl_ListObjAppendElement(NULL, resultPtr, mElt); } @@ -1403,7 +1405,7 @@ TclFSNormalizeToUniquePath( * Call each of the "normalise path" functions in succession. This is a * special case, in which if we have a native filesystem handler, we call * it first. This is because the root of Tcl's filesystem is always a - * native filesystem (i.e. '/' on unix is native). + * native filesystem (i.e., '/' on unix is native). */ firstFsRecPtr = FsGetFirstFilesystem(); @@ -1525,7 +1527,7 @@ TclGetOpenModeEx( #define RW_MODES (O_RDONLY|O_WRONLY|O_RDWR) /* - * Check for the simpler fopen-like access modes (e.g. "r"). They are + * Check for the simpler fopen-like access modes (e.g., "r"). They are * distinguished from the POSIX access modes by the presence of a * lower-case first letter. */ @@ -2671,6 +2673,7 @@ Tcl_FSGetCwd( fsRecPtr = fsRecPtr->nextPtr) { ClientData retCd; TclFSGetCwdProc2 *proc2; + if (fsRecPtr->fsPtr->getCwdProc == NULL) { continue; } @@ -3143,8 +3146,8 @@ Tcl_FSLoadFile( * Workaround for issue with modern HPUX which do allow the unlink (no ETXTBSY * error) yet somehow trash some internal data structures which prevents the * second and further shared libraries from getting properly loaded. Only the - * first is ok. We try to get around the issue by not unlinking, - * i.e. emulating the behaviour of the older HPUX which denied removal. + * first is ok. We try to get around the issue by not unlinking, i.e., + * emulating the behaviour of the older HPUX which denied removal. * * Doing the unlink is also an issue within docker containers, whose AUFS * bungles this as well, see @@ -3162,28 +3165,30 @@ Tcl_FSLoadFile( */ int -TclSkipUnlink (Tcl_Obj* shlibFile) +TclSkipUnlink( + Tcl_Obj *shlibFile) { - /* Order of testing: + /* + * Order of testing: * 1. On hpux we generally want to skip unlink in general * * Outside of hpux then: - * 2. For a general user request (TCL_TEMPLOAD_NO_UNLINK present, non-empty, => int) + * 2. For a general user request (TCL_TEMPLOAD_NO_UNLINK present, + * non-empty, => int) * 3. For general AUFS environment (statfs, if available). * * Ad 2: This variable can disable/override the AUFS detection, i.e. for - * testing if a newer AUFS does not have the bug any more. + * testing if a newer AUFS does not have the bug any more. * - * Ad 3: This is conditionally compiled in. Condition currently must be set manually. - * This part needs proper tests in the configure(.in). + * Ad 3: This is conditionally compiled in. Condition currently must be + * set manually. This part needs proper tests in the configure(.in). */ #ifdef hpux return 1; #else - char* skipstr; + char *skipstr = getenv("TCL_TEMPLOAD_NO_UNLINK"); - skipstr = getenv ("TCL_TEMPLOAD_NO_UNLINK"); if (skipstr && (skipstr[0] != '\0')) { return atoi(skipstr); } @@ -3192,7 +3197,8 @@ TclSkipUnlink (Tcl_Obj* shlibFile) #ifndef NO_FSTATFS { struct statfs fs; - /* Have fstatfs. May not have the AUFS super magic ... Indeed our build + /* + * Have fstatfs. May not have the AUFS super magic ... Indeed our build * box is too old to have it directly in the headers. Define taken from * http://mooon.googlecode.com/svn/trunk/linux_include/linux/aufs_type.h * http://aufs.sourceforge.net/ @@ -3209,8 +3215,10 @@ TclSkipUnlink (Tcl_Obj* shlibFile) #endif /* ... NO_FSTATFS */ #endif /* ... TCL_TEMPLOAD_NO_UNLINK */ - /* Fallback: !hpux, no EV override, no AUFS (detection, nor detected): - * Don't skip */ + /* + * Fallback: !hpux, no EV override, no AUFS (detection, nor detected): + * Don't skip + */ return 0; #endif /* hpux */ } @@ -3415,9 +3423,8 @@ Tcl_LoadFile( * avoids any worries about leaving the copy laying around on exit. */ - if ( - !TclSkipUnlink (copyToPtr) && - (Tcl_FSDeleteFile(copyToPtr) == TCL_OK)) { + if (!TclSkipUnlink(copyToPtr) && + (Tcl_FSDeleteFile(copyToPtr) == TCL_OK)) { Tcl_DecrRefCount(copyToPtr); /* diff --git a/generic/tclTimer.c b/generic/tclTimer.c index 6d3938b..3467305 100644 --- a/generic/tclTimer.c +++ b/generic/tclTimer.c @@ -1053,11 +1053,17 @@ AfterDelay( if (diff > TCL_TIME_MAXIMUM_SLICE) { diff = TCL_TIME_MAXIMUM_SLICE; } - if (diff == 0 && TCL_TIME_BEFORE(now, endTime)) diff = 1; + if (diff == 0 && TCL_TIME_BEFORE(now, endTime)) { + diff = 1; + } if (diff > 0) { Tcl_Sleep((long) diff); - if (diff < SLEEP_OFFLOAD_GETTIMEOFDAY) break; - } else break; + if (diff < SLEEP_OFFLOAD_GETTIMEOFDAY) { + break; + } + } else { + break; + } } else { diff = TCL_TIME_DIFF_MS(iPtr->limit.time, now); #ifndef TCL_WIDE_INT_IS_LONG diff --git a/unix/tclUnixSock.c b/unix/tclUnixSock.c index 0ae500b..b404080 100644 --- a/unix/tclUnixSock.c +++ b/unix/tclUnixSock.c @@ -19,6 +19,7 @@ #define SET_BITS(var, bits) ((var) |= (bits)) #define CLEAR_BITS(var, bits) ((var) &= ~(bits)) +#define GOT_BITS(var, bits) (((var) & (bits)) != 0) /* "sock" + a pointer in hex + \0 */ #define SOCK_CHAN_LENGTH (4 + sizeof(void *) * 2 + 1) @@ -99,9 +100,9 @@ struct TcpState { * structure. */ -#define TCP_ASYNC_TEST_MODE (1<<0) /* Async testing activated - * Do not automatically continue connection - * process */ +#define TCP_ASYNC_TEST_MODE (1<<0) /* Async testing activated. Do not + * automatically continue connection + * process. */ /* * The following defines the maximum length of the listen queue. This is the @@ -389,7 +390,7 @@ TcpBlockModeProc( } else { SET_BITS(statePtr->flags, TCP_NONBLOCKING); } - if (statePtr->flags & TCP_ASYNC_CONNECT) { + if (GOT_BITS(statePtr->flags, TCP_ASYNC_CONNECT)) { statePtr->cachedBlocking = mode; return 0; } @@ -442,7 +443,7 @@ WaitForConnect( * demanded, return the error ENOTCONN */ - if (errorCodePtr != NULL && (statePtr->flags & TCP_ASYNC_FAILED)) { + if (errorCodePtr != NULL && GOT_BITS(statePtr->flags, TCP_ASYNC_FAILED)) { *errorCodePtr = ENOTCONN; return -1; } @@ -451,24 +452,25 @@ WaitForConnect( * Check if an async connect is running. If not return ok */ - if (!(statePtr->flags & TCP_ASYNC_PENDING)) { + if (!GOT_BITS(statePtr->flags, TCP_ASYNC_PENDING)) { return 0; } /* - * In socket test mode do not continue with the connect + * In socket test mode do not continue with the connect. * Exceptions are: * - Call by recv/send and blocking socket - * (errorCodePtr != NULL && ! flags & TCP_NONBLOCKING) + * (errorCodePtr != NULL && !GOT_BITS(flags, TCP_NONBLOCKING)) */ - if ( (statePtr->testFlags & TCP_ASYNC_TEST_MODE) - && ! (errorCodePtr != NULL && ! (statePtr->flags & TCP_NONBLOCKING))) { + if (GOT_BITS(statePtr->testFlags, TCP_ASYNC_TEST_MODE) + && !(errorCodePtr != NULL + && !GOT_BITS(statePtr->flags, TCP_NONBLOCKING))) { *errorCodePtr = EWOULDBLOCK; return -1; } - if (errorCodePtr == NULL || (statePtr->flags & TCP_NONBLOCKING)) { + if (errorCodePtr == NULL || GOT_BITS(statePtr->flags, TCP_NONBLOCKING)) { timeout = 0; } else { timeout = -1; @@ -483,10 +485,10 @@ WaitForConnect( * Do this only once in the nonblocking case and repeat it until the * socket is final when blocking. */ - } while (timeout == -1 && statePtr->flags & TCP_ASYNC_CONNECT); + } while (timeout == -1 && GOT_BITS(statePtr->flags, TCP_ASYNC_CONNECT)); if (errorCodePtr != NULL) { - if (statePtr->flags & TCP_ASYNC_PENDING) { + if (GOT_BITS(statePtr->flags, TCP_ASYNC_PENDING)) { *errorCodePtr = EAGAIN; return -1; } else if (statePtr->connectError != 0) { @@ -832,7 +834,7 @@ TcpGetOptionProc( (strncmp(optionName, "-error", len) == 0)) { socklen_t optlen = sizeof(int); - if (statePtr->flags & TCP_ASYNC_CONNECT) { + if (GOT_BITS(statePtr->flags, TCP_ASYNC_CONNECT)) { /* * Suppress errors as long as we are not done. */ @@ -856,9 +858,8 @@ TcpGetOptionProc( if ((len > 1) && (optionName[1] == 'c') && (strncmp(optionName, "-connecting", len) == 0)) { - Tcl_DStringAppend(dsPtr, - (statePtr->flags & TCP_ASYNC_CONNECT) ? "1" : "0", -1); + GOT_BITS(statePtr->flags, TCP_ASYNC_CONNECT) ? "1" : "0", -1); return TCL_OK; } @@ -867,7 +868,7 @@ TcpGetOptionProc( address peername; socklen_t size = sizeof(peername); - if (statePtr->flags & TCP_ASYNC_CONNECT) { + if (GOT_BITS(statePtr->flags, TCP_ASYNC_CONNECT)) { /* * In async connect output an empty string */ @@ -922,7 +923,7 @@ TcpGetOptionProc( Tcl_DStringAppendElement(dsPtr, "-sockname"); Tcl_DStringStartSublist(dsPtr); } - if (statePtr->flags & TCP_ASYNC_CONNECT) { + if (GOT_BITS(statePtr->flags, TCP_ASYNC_CONNECT)) { /* * In async connect output an empty string */ @@ -1024,7 +1025,7 @@ TcpWatchProc( return; } - if (statePtr->flags & TCP_ASYNC_PENDING) { + if (GOT_BITS(statePtr->flags, TCP_ASYNC_PENDING)) { /* * Async sockets use a FileHandler internally while connecting, so we * need to cache this request until the connection has succeeded. @@ -1149,9 +1150,9 @@ TcpConnect( TcpState *statePtr) { socklen_t optlen; - int async_callback = statePtr->flags & TCP_ASYNC_PENDING; + int async_callback = GOT_BITS(statePtr->flags, TCP_ASYNC_PENDING); int ret = -1, error = EHOSTUNREACH; - int async = statePtr->flags & TCP_ASYNC_CONNECT; + int async = GOT_BITS(statePtr->flags, TCP_ASYNC_CONNECT); if (async_callback) { goto reenter; @@ -1159,7 +1160,6 @@ TcpConnect( for (statePtr->addr = statePtr->addrlist; statePtr->addr != NULL; statePtr->addr = statePtr->addr->ai_next) { - for (statePtr->myaddr = statePtr->myaddrlist; statePtr->myaddr != NULL; statePtr->myaddr = statePtr->myaddr->ai_next) { @@ -1580,13 +1580,13 @@ Tcl_OpenTcpServerEx( * Set up to reuse server addresses and/or ports if requested. */ - if (flags & TCL_TCPSERVER_REUSEADDR) { + if (GOT_BITS(flags, TCL_TCPSERVER_REUSEADDR)) { optvalue = 1; (void) setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, (char *) &optvalue, sizeof(optvalue)); } - if (flags & TCL_TCPSERVER_REUSEPORT) { + if (GOT_BITS(flags, TCL_TCPSERVER_REUSEPORT)) { #ifndef SO_REUSEPORT /* * If the platform doesn't support the SO_REUSEPORT flag we can't diff --git a/win/tclWinSock.c b/win/tclWinSock.c index a5d98ae..8e0f7d0 100644 --- a/win/tclWinSock.c +++ b/win/tclWinSock.c @@ -69,6 +69,7 @@ #define SET_BITS(var, bits) ((var) |= (bits)) #define CLEAR_BITS(var, bits) ((var) &= ~(bits)) +#define GOT_BITS(var, bits) (((var) & (bits)) != 0) /* "sock" + a pointer in hex + \0 */ #define SOCK_CHAN_LENGTH (4 + sizeof(void *) * 2 + 1) @@ -190,8 +191,8 @@ struct TcpState { * structure. */ -#define TCP_ASYNC_TEST_MODE (1<<0) /* Async testing activated - * Do not automatically continue connection +#define TCP_ASYNC_TEST_MODE (1<<0) /* Async testing activated. Do not + * automatically continue connection * process */ /* @@ -303,6 +304,15 @@ static const Tcl_ChannelType tcpChannelType = { static TclInitProcessGlobalValueProc InitializeHostName; static ProcessGlobalValue hostName = {0, 0, NULL, NULL, InitializeHostName, NULL, NULL}; + +/* + * Simple wrapper round the SendMessage syscall. + */ + +#define SendSelectMessage(tsdPtr, message, payload) \ + SendMessage((tsdPtr)->hwnd, SOCKET_SELECT, \ + (WPARAM) (message), (LPARAM) (payload)) + /* * Address print debug functions @@ -596,7 +606,7 @@ WaitForConnect( * demanded, return the error ENOTCONN. */ - if (errorCodePtr != NULL && (statePtr->flags & TCP_ASYNC_FAILED)) { + if (errorCodePtr != NULL && GOT_BITS(statePtr->flags, TCP_ASYNC_FAILED)) { *errorCodePtr = ENOTCONN; return -1; } @@ -605,7 +615,7 @@ WaitForConnect( * Check if an async connect is running. If not return ok */ - if (!(statePtr->flags & TCP_ASYNC_CONNECT)) { + if (!GOT_BITS(statePtr->flags, TCP_ASYNC_CONNECT)) { return 0; } @@ -613,12 +623,13 @@ WaitForConnect( * In socket test mode do not continue with the connect * Exceptions are: * - Call by recv/send and blocking socket - * (errorCodePtr != NULL && ! flags & TCP_NONBLOCKING) + * (errorCodePtr != NULL && !GOT_BITS(flags, TCP_NONBLOCKING)) * - Call by the event queue (errorCodePtr == NULL) */ - if ( (statePtr->testFlags & TCP_ASYNC_TEST_MODE) - && errorCodePtr != NULL && (statePtr->flags & TCP_NONBLOCKING)) { + if (GOT_BITS(statePtr->testFlags, TCP_ASYNC_TEST_MODE) + && errorCodePtr != NULL + && GOT_BITS(statePtr->flags, TCP_NONBLOCKING)) { *errorCodePtr = EWOULDBLOCK; return -1; } @@ -645,7 +656,7 @@ WaitForConnect( * Check for connect event. */ - if (statePtr->readyEvents & FD_CONNECT) { + if (GOT_BITS(statePtr->readyEvents, FD_CONNECT)) { /* * Consume the connect event. */ @@ -658,7 +669,7 @@ WaitForConnect( */ if (errorCodePtr != NULL && - !(statePtr->flags & TCP_NONBLOCKING)) { + !GOT_BITS(statePtr->flags, TCP_NONBLOCKING)) { CLEAR_BITS(statePtr->flags, TCP_ASYNC_CONNECT); } @@ -691,7 +702,7 @@ WaitForConnect( * foreground blocking operation) */ - if (statePtr->flags & TCP_ASYNC_PENDING) { + if (GOT_BITS(statePtr->flags, TCP_ASYNC_PENDING)) { if (errorCodePtr != NULL) { *errorCodePtr = EWOULDBLOCK; } @@ -731,7 +742,7 @@ WaitForConnect( * directly the error EWOULDBLOCK. */ - if (statePtr->flags & TCP_NONBLOCKING) { + if (GOT_BITS(statePtr->flags, TCP_NONBLOCKING)) { *errorCodePtr = EWOULDBLOCK; return -1; } @@ -795,7 +806,7 @@ TcpInputProc( * socket stack after the first time EOF is detected. */ - if (statePtr->flags & SOCKET_EOF) { + if (GOT_BITS(statePtr->flags, SOCKET_EOF)) { return 0; } @@ -818,8 +829,8 @@ TcpInputProc( */ while (1) { - SendMessage(tsdPtr->hwnd, SOCKET_SELECT, - (WPARAM) UNSELECT, (LPARAM) statePtr); + SendSelectMessage(tsdPtr, UNSELECT, statePtr); + /* * Single fd operation: this proc is only called for a connected * socket. @@ -844,7 +855,7 @@ TcpInputProc( * error and report an EOF. */ - if (statePtr->readyEvents & FD_CLOSE) { + if (GOT_BITS(statePtr->readyEvents, FD_CLOSE)) { SET_BITS(statePtr->flags, SOCKET_EOF); bytesRead = 0; break; @@ -867,7 +878,8 @@ TcpInputProc( * Check for error condition or underflow in non-blocking case. */ - if ((statePtr->flags & TCP_NONBLOCKING) || (error != WSAEWOULDBLOCK)) { + if (GOT_BITS(statePtr->flags, TCP_NONBLOCKING) + || (error != WSAEWOULDBLOCK)) { TclWinConvertError(error); *errorCodePtr = Tcl_GetErrno(); bytesRead = -1; @@ -885,7 +897,7 @@ TcpInputProc( } } - SendMessage(tsdPtr->hwnd, SOCKET_SELECT, (WPARAM)SELECT, (LPARAM)statePtr); + SendSelectMessage(tsdPtr, SELECT, statePtr); return bytesRead; } @@ -943,8 +955,7 @@ TcpOutputProc( } while (1) { - SendMessage(tsdPtr->hwnd, SOCKET_SELECT, - (WPARAM) UNSELECT, (LPARAM) statePtr); + SendSelectMessage(tsdPtr, UNSELECT, statePtr); /* * Single fd operation: this proc is only called for a connected @@ -959,8 +970,9 @@ TcpOutputProc( * until the condition changes. */ - if (statePtr->watchEvents & FD_WRITE) { + if (GOT_BITS(statePtr->watchEvents, FD_WRITE)) { Tcl_Time blockTime = { 0, 0 }; + Tcl_SetMaxBlockTime(&blockTime); } break; @@ -976,7 +988,7 @@ TcpOutputProc( error = WSAGetLastError(); if (error == WSAEWOULDBLOCK) { CLEAR_BITS(statePtr->readyEvents, FD_WRITE); - if (statePtr->flags & TCP_NONBLOCKING) { + if (GOT_BITS(statePtr->flags, TCP_NONBLOCKING)) { *errorCodePtr = EWOULDBLOCK; written = -1; break; @@ -999,8 +1011,7 @@ TcpOutputProc( } } - SendMessage(tsdPtr->hwnd, SOCKET_SELECT, (WPARAM)SELECT, - (LPARAM)statePtr); + SendSelectMessage(tsdPtr, SELECT, statePtr); return written; } @@ -1317,7 +1328,7 @@ TcpGetOptionProc( * below. */ - if (! (statePtr->testFlags & TCP_ASYNC_TEST_MODE) ) { + if (!GOT_BITS(statePtr->testFlags, TCP_ASYNC_TEST_MODE)) { WaitForConnect(statePtr, NULL); } @@ -1332,8 +1343,8 @@ TcpGetOptionProc( * Do not return any errors if async connect is running. */ - if (!(statePtr->flags & TCP_ASYNC_PENDING)) { - if (statePtr->flags & TCP_ASYNC_FAILED) { + if (!GOT_BITS(statePtr->flags, TCP_ASYNC_PENDING)) { + if (GOT_BITS(statePtr->flags, TCP_ASYNC_FAILED)) { /* * In case of a failed async connect, eventually report the * connect error only once. Do not report the system error, @@ -1388,7 +1399,7 @@ TcpGetOptionProc( if ((len > 1) && (optionName[1] == 'c') && (strncmp(optionName, "-connecting", len) == 0)) { Tcl_DStringAppend(dsPtr, - (statePtr->flags & TCP_ASYNC_PENDING) + GOT_BITS(statePtr->flags, TCP_ASYNC_PENDING) ? "1" : "0", -1); return TCL_OK; } @@ -1403,7 +1414,7 @@ TcpGetOptionProc( address peername; socklen_t size = sizeof(peername); - if (statePtr->flags & TCP_ASYNC_PENDING) { + if (GOT_BITS(statePtr->flags, TCP_ASYNC_PENDING)) { /* * In async connect output an empty string */ @@ -1468,7 +1479,7 @@ TcpGetOptionProc( Tcl_DStringAppendElement(dsPtr, "-sockname"); Tcl_DStringStartSublist(dsPtr); } - if (statePtr->flags & TCP_ASYNC_PENDING) { + if (GOT_BITS(statePtr->flags, TCP_ASYNC_PENDING)) { /* * In async connect output an empty string */ @@ -1617,10 +1628,10 @@ TcpWatchProc( if (!statePtr->acceptProc) { statePtr->watchEvents = 0; - if (mask & TCL_READABLE) { + if (GOT_BITS(mask, TCL_READABLE)) { SET_BITS(statePtr->watchEvents, FD_READ | FD_CLOSE); } - if (mask & TCL_WRITABLE) { + if (GOT_BITS(mask, TCL_WRITABLE)) { SET_BITS(statePtr->watchEvents, FD_WRITE | FD_CLOSE); } @@ -1712,11 +1723,11 @@ TcpConnect( TcpState *statePtr) { DWORD error; - int async_connect = statePtr->flags & TCP_ASYNC_CONNECT; + int async_connect = GOT_BITS(statePtr->flags, TCP_ASYNC_CONNECT); /* We are started with async connect and the * connect notification was not yet * received. */ - int async_callback = statePtr->flags & TCP_ASYNC_PENDING; + int async_callback = GOT_BITS(statePtr->flags, TCP_ASYNC_PENDING); /* We were called by the event procedure and * continue our loop. */ ThreadSpecificData *tsdPtr = TclThreadDataKeyGet(&dataKey); @@ -1860,8 +1871,7 @@ TcpConnect( * Activate accept notification. */ - SendMessage(tsdPtr->hwnd, SOCKET_SELECT, (WPARAM) SELECT, - (LPARAM) statePtr); + SendSelectMessage(tsdPtr, SELECT, statePtr); } /* @@ -1957,8 +1967,7 @@ TcpConnect( * automatically places the socket into non-blocking mode. */ - SendMessage(tsdPtr->hwnd, SOCKET_SELECT, (WPARAM) SELECT, - (LPARAM) statePtr); + SendSelectMessage(tsdPtr, SELECT, statePtr); } else { /* * Connect failed @@ -2155,8 +2164,7 @@ Tcl_MakeTcpClientChannel( */ statePtr->selectEvents = FD_READ | FD_CLOSE | FD_WRITE; - SendMessage(tsdPtr->hwnd, SOCKET_SELECT, (WPARAM)SELECT, - (LPARAM)statePtr); + SendSelectMessage(tsdPtr, SELECT, statePtr); sprintf(channelName, SOCK_TEMPLATE, statePtr); statePtr->channel = Tcl_CreateChannel(&tcpChannelType, channelName, @@ -2270,7 +2278,7 @@ Tcl_OpenTcpServerEx( * unix systems. */ - if (flags & TCL_TCPSERVER_REUSEPORT) { + if (GOT_BITS(flags, TCL_TCPSERVER_REUSEPORT)) { optvalue = 1; (void) setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, (char *) &optvalue, sizeof(optvalue)); @@ -2352,8 +2360,7 @@ Tcl_OpenTcpServerEx( */ ioctlsocket(sock, (long) FIONBIO, &flag); - SendMessage(tsdPtr->hwnd, SOCKET_SELECT, (WPARAM) SELECT, - (LPARAM) statePtr); + SendSelectMessage(tsdPtr, SELECT, statePtr); if (Tcl_SetChannelOption(interp, statePtr->channel, "-eofchar", "") == TCL_ERROR) { Tcl_Close(NULL, statePtr->channel); @@ -2422,8 +2429,7 @@ TcpAccept( */ newInfoPtr->selectEvents = (FD_READ | FD_WRITE | FD_CLOSE); - SendMessage(tsdPtr->hwnd, SOCKET_SELECT, (WPARAM) SELECT, - (LPARAM) newInfoPtr); + SendSelectMessage(tsdPtr, SELECT, newInfoPtr); sprintf(channelName, SOCK_TEMPLATE, newInfoPtr); newInfoPtr->channel = Tcl_CreateChannel(&tcpChannelType, channelName, @@ -2654,7 +2660,7 @@ SocketSetupProc( Tcl_Time blockTime = { 0, 0 }; ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&dataKey); - if (!(flags & TCL_FILE_EVENTS)) { + if (!GET_BITS(flags, TCL_FILE_EVENTS)) { return; } @@ -2664,9 +2670,8 @@ SocketSetupProc( WaitForSingleObject(tsdPtr->socketListLock, INFINITE); for (statePtr = tsdPtr->socketList; statePtr != NULL; statePtr = statePtr->nextPtr) { - if (statePtr->readyEvents & - (statePtr->watchEvents | FD_CONNECT | FD_ACCEPT) - ) { + if (GOT_BITS(statePtr->readyEvents, + statePtr->watchEvents | FD_CONNECT | FD_ACCEPT)) { Tcl_SetMaxBlockTime(&blockTime); break; } @@ -2700,7 +2705,7 @@ SocketCheckProc( SocketEvent *evPtr; ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&dataKey); - if (!(flags & TCL_FILE_EVENTS)) { + if (!GOT_BITS(flags, TCL_FILE_EVENTS)) { return; } @@ -2713,9 +2718,9 @@ SocketCheckProc( WaitForSingleObject(tsdPtr->socketListLock, INFINITE); for (statePtr = tsdPtr->socketList; statePtr != NULL; statePtr = statePtr->nextPtr) { - if ((statePtr->readyEvents & - (statePtr->watchEvents | FD_CONNECT | FD_ACCEPT)) - && !(statePtr->flags & SOCKET_PENDING)) { + if (GOT_BITS(statePtr->readyEvents, + statePtr->watchEvents | FD_CONNECT | FD_ACCEPT) + && !GOT_BITS(statePtr->flags, SOCKET_PENDING)) { SET_BITS(statePtr->flags, SOCKET_PENDING); evPtr = ckalloc(sizeof(SocketEvent)); evPtr->header.proc = SocketEventProc; @@ -2762,7 +2767,7 @@ SocketEventProc( address addr; int len; - if (!(flags & TCL_FILE_EVENTS)) { + if (!GOT_BITS(flags, TCL_FILE_EVENTS)) { return 0; } @@ -2797,8 +2802,8 @@ SocketEventProc( * Continue async connect if pending and ready */ - if (statePtr->readyEvents & FD_CONNECT) { - if (statePtr->flags & TCP_ASYNC_PENDING) { + if (GOT_BITS(statePtr->readyEvents, FD_CONNECT)) { + if (GOT_BITS(statePtr->flags, TCP_ASYNC_PENDING)) { /* * Do one step and save eventual connect error */ @@ -2820,7 +2825,7 @@ SocketEventProc( * Handle connection requests directly. */ - if (statePtr->readyEvents & FD_ACCEPT) { + if (GOT_BITS(statePtr->readyEvents, FD_ACCEPT)) { for (fds = statePtr->sockets; fds != NULL; fds = fds->next) { /* * Accept the incoming connection request. @@ -2895,7 +2900,7 @@ SocketEventProc( events = statePtr->readyEvents & statePtr->watchEvents; - if (events & FD_CLOSE) { + if (GOT_BITS(events, FD_CLOSE)) { /* * If the socket was closed and the channel is still interested in * read events, then we need to ensure that we keep polling for this @@ -2910,15 +2915,13 @@ SocketEventProc( Tcl_SetMaxBlockTime(&blockTime); SET_BITS(mask, TCL_READABLE | TCL_WRITABLE); - } else if (events & FD_READ) { - + } else if (GOT_BITS(events, FD_READ)) { /* * Throw the readable event if an async connect failed. */ - if (statePtr->flags & TCP_ASYNC_FAILED) { + if (GOT_BITS(statePtr->flags, TCP_ASYNC_FAILED)) { SET_BITS(mask, TCL_READABLE); - } else { fd_set readFds; struct timeval timeout; @@ -2931,8 +2934,7 @@ SocketEventProc( * async select handler and keep waiting. */ - SendMessage(tsdPtr->hwnd, SOCKET_SELECT, - (WPARAM) UNSELECT, (LPARAM) statePtr); + SendSelectMessage(tsdPtr, UNSELECT, statePtr); FD_ZERO(&readFds); FD_SET(statePtr->sockets->fd, &readFds); @@ -2943,8 +2945,7 @@ SocketEventProc( SET_BITS(mask, TCL_READABLE); } else { CLEAR_BITS(statePtr->readyEvents, FD_READ); - SendMessage(tsdPtr->hwnd, SOCKET_SELECT, - (WPARAM) SELECT, (LPARAM) statePtr); + SendSelectMessage(tsdPtr, SELECT, statePtr); } } } @@ -2953,7 +2954,7 @@ SocketEventProc( * writable event */ - if (events & FD_WRITE) { + if (GOT_BITS(events, FD_WRITE)) { SET_BITS(mask, TCL_WRITABLE); } @@ -3095,10 +3096,8 @@ WaitForSocketEvent( * Reset WSAAsyncSelect so we have a fresh set of events pending. */ - SendMessage(tsdPtr->hwnd, SOCKET_SELECT, (WPARAM) UNSELECT, - (LPARAM) statePtr); - SendMessage(tsdPtr->hwnd, SOCKET_SELECT, (WPARAM) SELECT, - (LPARAM) statePtr); + SendSelectMessage(tsdPtr, UNSELECT, statePtr); + SendSelectMessage(tsdPtr, SELECT, statePtr); while (1) { int event_found; @@ -3113,7 +3112,7 @@ WaitForSocketEvent( * Check if event occured. */ - event_found = (statePtr->readyEvents & events); + event_found = GOT_BITS(statePtr->readyEvents, events); /* * Free list lock. @@ -3314,14 +3313,14 @@ SocketProc( * the count if the current event is an FD_ACCEPT. */ - if (event & FD_CLOSE) { + if (GOT_BITS(event, FD_CLOSE)) { statePtr->acceptEventCount = 0; CLEAR_BITS(statePtr->readyEvents, FD_WRITE | FD_ACCEPT); - } else if (event & FD_ACCEPT) { + } else if (GOT_BITS(event, FD_ACCEPT)) { statePtr->acceptEventCount++; } - if (event & FD_CONNECT) { + if (GOT_BITS(event, FD_CONNECT)) { /* * Remember any error that occurred so we can report * connection failures. @@ -3552,8 +3551,7 @@ TcpThreadActionProc( * thread. */ - SendMessage(tsdPtr->hwnd, SOCKET_SELECT, - (WPARAM) notifyCmd, (LPARAM) statePtr); + SendSelectMessage(tsdPtr, notifyCmd, statePtr); } /* -- cgit v0.12 From 26f98a5e562b865e82adcc6b7de05df4b0fa07de Mon Sep 17 00:00:00 2001 From: "jan.nijtmans" Date: Tue, 11 Apr 2017 11:30:47 +0000 Subject: unbreak windows build (by previous commit) --- win/tclWinSock.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/win/tclWinSock.c b/win/tclWinSock.c index 8e0f7d0..ee6be96 100644 --- a/win/tclWinSock.c +++ b/win/tclWinSock.c @@ -2660,7 +2660,7 @@ SocketSetupProc( Tcl_Time blockTime = { 0, 0 }; ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&dataKey); - if (!GET_BITS(flags, TCL_FILE_EVENTS)) { + if (!GOT_BITS(flags, TCL_FILE_EVENTS)) { return; } -- cgit v0.12 From cd48f2d3131be957186014e7012d9445e2bd26ff Mon Sep 17 00:00:00 2001 From: "jan.nijtmans" Date: Tue, 11 Apr 2017 15:20:07 +0000 Subject: Remove some unnecessary "struct" definitions and some type casts no longer necessary. No functional changes. --- generic/tclBasic.c | 2 +- generic/tclClock.c | 2 +- generic/tclEvent.c | 2 +- generic/tclIO.c | 2 +- generic/tclIOCmd.c | 5 ++--- generic/tclIORChan.c | 14 +++++++------- generic/tclIORTrans.c | 2 +- generic/tclIOSock.c | 2 +- generic/tclIOUtil.c | 2 +- generic/tclInt.h | 2 +- generic/tclNamesp.c | 2 +- generic/tclObj.c | 2 +- generic/tclRegexp.c | 4 ++-- generic/tclUtil.c | 4 ++-- 14 files changed, 23 insertions(+), 24 deletions(-) diff --git a/generic/tclBasic.c b/generic/tclBasic.c index b29e19e..aae7ab6 100644 --- a/generic/tclBasic.c +++ b/generic/tclBasic.c @@ -1071,7 +1071,7 @@ Tcl_CallWhenDeleted( Interp *iPtr = (Interp *) interp; static Tcl_ThreadDataKey assocDataCounterKey; int *assocDataCounterPtr = - Tcl_GetThreadData(&assocDataCounterKey, (int)sizeof(int)); + Tcl_GetThreadData(&assocDataCounterKey, sizeof(int)); int isNew; char buffer[32 + TCL_INTEGER_SPACE]; AssocData *dPtr = ckalloc(sizeof(AssocData)); diff --git a/generic/tclClock.c b/generic/tclClock.c index ac4a4d6..d44e9dc 100644 --- a/generic/tclClock.c +++ b/generic/tclClock.c @@ -1694,7 +1694,7 @@ ThreadSafeLocalTime( * Get a thread-local buffer to hold the returned time. */ - struct tm *tmPtr = Tcl_GetThreadData(&tmKey, (int) sizeof(struct tm)); + struct tm *tmPtr = Tcl_GetThreadData(&tmKey, sizeof(struct tm)); #ifdef HAVE_LOCALTIME_R localtime_r(timePtr, tmPtr); #else diff --git a/generic/tclEvent.c b/generic/tclEvent.c index 436db7a..49fd2ae 100644 --- a/generic/tclEvent.c +++ b/generic/tclEvent.c @@ -37,7 +37,7 @@ typedef struct BgError { * pending background errors for the interpreter. */ -typedef struct ErrAssocData { +typedef struct { Tcl_Interp *interp; /* Interpreter in which error occurred. */ Tcl_Obj *cmdPrefix; /* First word(s) of the handler command */ BgError *firstBgPtr; /* First in list of all background errors diff --git a/generic/tclIO.c b/generic/tclIO.c index 32fbd59..1460392 100644 --- a/generic/tclIO.c +++ b/generic/tclIO.c @@ -116,7 +116,7 @@ typedef struct CopyState { * The structure defined below is used in this file only. */ -typedef struct ThreadSpecificData { +typedef struct { NextChannelHandler *nestedHandlerPtr; /* This variable holds the list of nested * Tcl_NotifyChannel invocations. */ diff --git a/generic/tclIOCmd.c b/generic/tclIOCmd.c index e52200d..6e8bd09 100644 --- a/generic/tclIOCmd.c +++ b/generic/tclIOCmd.c @@ -25,7 +25,7 @@ typedef struct AcceptCallback { * It must be per-thread because of std channel limitations. */ -typedef struct ThreadSpecificData { +typedef struct { int initialized; /* Set to 1 when the module is initialized. */ Tcl_Obj *stdoutObjPtr; /* Cached stdout channel Tcl_Obj */ } ThreadSpecificData; @@ -113,7 +113,6 @@ Tcl_PutsObjCmd( int newline; /* Add a newline at end? */ int result; /* Result of puts operation. */ int mode; /* Mode in which channel is opened. */ - ThreadSpecificData *tsdPtr; switch (objc) { case 2: /* [puts $x] */ @@ -160,7 +159,7 @@ Tcl_PutsObjCmd( } if (chanObjPtr == NULL) { - tsdPtr = TCL_TSD_INIT(&dataKey); + ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&dataKey); if (!tsdPtr->initialized) { tsdPtr->initialized = 1; diff --git a/generic/tclIORChan.c b/generic/tclIORChan.c index 433fb6f..aefa104 100644 --- a/generic/tclIORChan.c +++ b/generic/tclIORChan.c @@ -234,7 +234,7 @@ typedef enum { * sharing problems. */ -typedef struct ForwardParamBase { +typedef struct { int code; /* O: Ok/Fail of the cmd handler */ char *msgStr; /* O: Error message for handler failure */ int mustFree; /* O: True if msgStr is allocated, false if @@ -309,7 +309,7 @@ typedef struct ForwardingResult ForwardingResult; * General event structure, with reference to operation specific data. */ -typedef struct ForwardingEvent { +typedef struct { Tcl_Event event; /* Basic event data, has to be first item */ ForwardingResult *resultPtr; ForwardedOperation op; /* Forwarded driver operation */ @@ -346,7 +346,7 @@ struct ForwardingResult { * results. */ }; -typedef struct ThreadSpecificData { +typedef struct { /* * Table of all reflected channels owned by this thread. This is the * per-thread version of the per-interpreter map. @@ -723,7 +723,7 @@ TclChanCreateObjCmd( Tcl_DecrRefCount(rcPtr->name); Tcl_DecrRefCount(rcPtr->methods); Tcl_DecrRefCount(rcPtr->cmd); - ckfree((char*) rcPtr); + ckfree(rcPtr); return TCL_ERROR; #undef MODE @@ -748,7 +748,7 @@ TclChanCreateObjCmd( *---------------------------------------------------------------------- */ -typedef struct ReflectEvent { +typedef struct { Tcl_Event header; ReflectedChannel *rcPtr; int events; @@ -1223,8 +1223,8 @@ ReflectClose( #endif tctPtr = ((Channel *)rcPtr->chan)->typePtr; if (tctPtr && tctPtr != &tclRChannelType) { - ckfree(tctPtr); - ((Channel *)rcPtr->chan)->typePtr = NULL; + ckfree(tctPtr); + ((Channel *)rcPtr->chan)->typePtr = NULL; } Tcl_EventuallyFree(rcPtr, (Tcl_FreeProc *) FreeReflectedChannel); return (result == TCL_OK) ? EOK : EINVAL; diff --git a/generic/tclIORTrans.c b/generic/tclIORTrans.c index 8375926..f198c69 100644 --- a/generic/tclIORTrans.c +++ b/generic/tclIORTrans.c @@ -329,7 +329,7 @@ struct ForwardingResult { * results. */ }; -typedef struct ThreadSpecificData { +typedef struct { /* * Table of all reflected transformations owned by this thread. */ diff --git a/generic/tclIOSock.c b/generic/tclIOSock.c index 82d2fc1..6abfa60 100644 --- a/generic/tclIOSock.c +++ b/generic/tclIOSock.c @@ -16,7 +16,7 @@ * On Windows, we need to do proper Unicode->UTF-8 conversion. */ -typedef struct ThreadSpecificData { +typedef struct { int initialized; Tcl_DString errorMsg; /* UTF-8 encoded error-message */ } ThreadSpecificData; diff --git a/generic/tclIOUtil.c b/generic/tclIOUtil.c index 5f79e6e..ea407ab 100644 --- a/generic/tclIOUtil.c +++ b/generic/tclIOUtil.c @@ -57,7 +57,7 @@ typedef struct FilesystemRecord { * this information each time the corresponding epoch counter changes. */ -typedef struct ThreadSpecificData { +typedef struct { int initialized; size_t cwdPathEpoch; size_t filesystemEpoch; diff --git a/generic/tclInt.h b/generic/tclInt.h index 1fbc541..d725688 100644 --- a/generic/tclInt.h +++ b/generic/tclInt.h @@ -1357,7 +1357,7 @@ MODULE_SCOPE void TclThreadDataKeySet(Tcl_ThreadDataKey *keyPtr, */ #define TCL_TSD_INIT(keyPtr) \ - (ThreadSpecificData *)Tcl_GetThreadData((keyPtr), sizeof(ThreadSpecificData)) + Tcl_GetThreadData((keyPtr), sizeof(ThreadSpecificData)) /* *---------------------------------------------------------------- diff --git a/generic/tclNamesp.c b/generic/tclNamesp.c index 1e360d1..e1bad0e 100644 --- a/generic/tclNamesp.c +++ b/generic/tclNamesp.c @@ -31,7 +31,7 @@ * limited to a single interpreter. */ -typedef struct ThreadSpecificData { +typedef struct { size_t numNsCreated; /* Count of the number of namespaces created * within the thread. This value is used as a * unique id for each namespace. Cannot be diff --git a/generic/tclObj.c b/generic/tclObj.c index dfcaff0..f4b81f2 100644 --- a/generic/tclObj.c +++ b/generic/tclObj.c @@ -75,7 +75,7 @@ typedef struct ObjData { * The structure defined below is used in this file only. */ -typedef struct ThreadSpecificData { +typedef struct { Tcl_HashTable *lineCLPtr; /* This table remembers for each Tcl_Obj * generated by a call to the function * TclSubstTokens() from a literal text diff --git a/generic/tclRegexp.c b/generic/tclRegexp.c index eb23f72..5f8dc20 100644 --- a/generic/tclRegexp.c +++ b/generic/tclRegexp.c @@ -64,7 +64,7 @@ #define NUM_REGEXPS 30 -typedef struct ThreadSpecificData { +typedef struct { int initialized; /* Set to 1 when the module is initialized. */ char *patterns[NUM_REGEXPS];/* Strings corresponding to compiled regular * expression patterns. NULL means that this @@ -679,7 +679,7 @@ TclRegAbout( resultObj = Tcl_NewObj(); Tcl_ListObjAppendElement(NULL, resultObj, - Tcl_NewIntObj((int) regexpPtr->re.re_nsub)); + Tcl_NewWideIntObj((Tcl_WideInt) regexpPtr->re.re_nsub)); /* * Now append a list of all the bit-flags set for the RE. diff --git a/generic/tclUtil.c b/generic/tclUtil.c index a4d523a..91cc3b4 100644 --- a/generic/tclUtil.c +++ b/generic/tclUtil.c @@ -3153,7 +3153,7 @@ Tcl_PrintDouble( int signum; char *digits; char *end; - int *precisionPtr = Tcl_GetThreadData(&precisionKey, (int) sizeof(int)); + int *precisionPtr = Tcl_GetThreadData(&precisionKey, sizeof(int)); /* * Handle NaN. @@ -3326,7 +3326,7 @@ TclPrecTraceProc( { Tcl_Obj *value; int prec; - int *precisionPtr = Tcl_GetThreadData(&precisionKey, (int) sizeof(int)); + int *precisionPtr = Tcl_GetThreadData(&precisionKey, sizeof(int)); /* * If the variable is unset, then recreate the trace. -- cgit v0.12 From 8b0910d31f1affbd2ccefd74d2df1eeba7a1f736 Mon Sep 17 00:00:00 2001 From: sebres Date: Tue, 11 Apr 2017 18:07:30 +0000 Subject: fix typo- resp. copy-paste-bug (using wrong threadInfo pointer in ConsoleOutputProc, should be writer, not reader) --- win/tclWinConsole.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/win/tclWinConsole.c b/win/tclWinConsole.c index d4893ee..da995c5 100644 --- a/win/tclWinConsole.c +++ b/win/tclWinConsole.c @@ -828,7 +828,7 @@ ConsoleOutputProc( int *errorCode) /* Where to store error code. */ { ConsoleInfo *infoPtr = instanceData; - ConsoleThreadInfo *threadInfo = &infoPtr->reader; + ConsoleThreadInfo *threadInfo = &infoPtr->writer; DWORD bytesWritten, timeout; *errorCode = 0; -- cgit v0.12 From 119d9ad3aa713f76079c0aebb625fb861b09fa68 Mon Sep 17 00:00:00 2001 From: sebres Date: Tue, 11 Apr 2017 18:08:12 +0000 Subject: shared structures of pipe-workers rewritten using atomic state of the thread; asynchronous start/stop of pipe-workers (if possible), try the soft way to end workers using cancelSynchronousIo before it would be terminated; --- win/tclWinInit.c | 20 ++ win/tclWinInt.h | 9 + win/tclWinPipe.c | 578 ++++++++++++++++++++++++++++++++----------------------- 3 files changed, 371 insertions(+), 236 deletions(-) diff --git a/win/tclWinInit.c b/win/tclWinInit.c index 8b600f6..03ef5df 100644 --- a/win/tclWinInit.c +++ b/win/tclWinInit.c @@ -76,6 +76,15 @@ typedef struct { #define PROCESSOR_ARCHITECTURE_UNKNOWN 0xFFFF #endif + +/* + * Windows version dependend functions + */ +static TclWinProcs _tclWinProcs = { + NULL +}; +TclWinProcs *tclWinProcs = &_tclWinProcs; + /* * The following arrays contain the human readable strings for the Windows * platform and processor values. @@ -132,6 +141,7 @@ TclpInitPlatform(void) { WSADATA wsaData; WORD wVersionRequested = MAKEWORD(2, 2); + HINSTANCE hInstance; tclPlatform = TCL_PLATFORM_WINDOWS; @@ -150,6 +160,16 @@ TclpInitPlatform(void) TclWinInit(GetModuleHandle(NULL)); #endif + + /* + * Fill available functions depending on windows version + */ + hInstance = LoadLibraryW(L"kernel32"); + if (hInstance != NULL) { + _tclWinProcs.cancelSynchronousIo = + (BOOL (WINAPI *)(HANDLE)) GetProcAddress(hInstance, + "CancelSynchronousIo"); + } } /* diff --git a/win/tclWinInt.h b/win/tclWinInt.h index 6b098f8..b8d493e 100644 --- a/win/tclWinInt.h +++ b/win/tclWinInt.h @@ -32,6 +32,15 @@ typedef struct TCLEXCEPTION_REGISTRATION { #endif /* + * Windows version dependend functions + */ +typedef struct TclWinProcs { + BOOL (WINAPI *cancelSynchronousIo)(HANDLE); +} TclWinProcs; + +MODULE_SCOPE TclWinProcs *tclWinProcs; + +/* * Some versions of Borland C have a define for the OSVERSIONINFO for * Win32s and for NT, but not for Windows 95. * Define VER_PLATFORM_WIN32_CE for those without newer headers. diff --git a/win/tclWinPipe.c b/win/tclWinPipe.c index 523d4eb..bb76eef 100644 --- a/win/tclWinPipe.c +++ b/win/tclWinPipe.c @@ -91,6 +91,284 @@ static ProcInfo *procList; * This structure describes per-instance data for a pipe based channel. */ +typedef struct PipeThreadInfo { + HANDLE evControl; /* Auto-reset event used by the main thread to + * signal when the pipe thread should attempt + * to do read/write operation. Additionally + * used as signal to stop (state set to -1) */ + volatile LONG state; /* Indicates current state of the thread */ + ClientData clientData; /* Referenced data of the main thread */ +} PipeThreadInfo; + + +#define PTI_STATE_IDLE 0 +#define PTI_STATE_WORK 1 +#define PTI_STATE_STOP 2 +#define PTI_STATE_END 4 +#define PTI_STATE_DOWN 8 + +int +PipeThreadWaitForSignal( + PipeThreadInfo **pipeTIPtr) +{ + PipeThreadInfo *pipeTI = *pipeTIPtr; + LONG state; + DWORD waitResult; + + if (!pipeTI) { + return 0; + } + /* + * Wait for the main thread to signal before attempting to do the work. + */ + + /* reset work state of thread (idle/waiting) */ + if ((state = InterlockedCompareExchange(&pipeTI->state, + PTI_STATE_IDLE, PTI_STATE_WORK)) & (PTI_STATE_STOP|PTI_STATE_END)) { + /* end of work, check the owner of structure */ + goto end; + } + /* entering wait */ + waitResult = WaitForSingleObject(pipeTI->evControl, INFINITE); + + if (waitResult != WAIT_OBJECT_0) { + + /* + * The control event was not signaled, so end of work (unexpected + * behaviour, main thread can be dead?). + */ + goto end; + } + + /* try to set work state of thread */ + if ((state = InterlockedCompareExchange(&pipeTI->state, + PTI_STATE_WORK, PTI_STATE_IDLE)) & (PTI_STATE_STOP|PTI_STATE_END)) { + /* end of work */ + goto end; + } + + /* signaled to work */ + return 1; + +end: + /* end of work, check the owner of the TI structure */ + if (state != PTI_STATE_STOP) { + *pipeTIPtr = NULL; + } + return 0; +} + +static inline void +PipeThreadSignal( + PipeThreadInfo **pipeTIPtr) +{ + PipeThreadInfo *pipeTI = *pipeTIPtr; + if (pipeTI) { + SetEvent(pipeTI->evControl); + } +} + +int +PipeThreadStopSignal( + PipeThreadInfo **pipeTIPtr) +{ + PipeThreadInfo *pipeTI = *pipeTIPtr; + HANDLE evControl; + int state; + + if (!pipeTI) { + return 1; + } + evControl = pipeTI->evControl; + switch ( + (state = InterlockedCompareExchange(&pipeTI->state, + PTI_STATE_STOP, PTI_STATE_IDLE)) + ) { + + case PTI_STATE_IDLE: + + /* Thread was idle/waiting, notify it goes teardown */ + SetEvent(evControl); + + *pipeTIPtr = NULL; + + case PTI_STATE_DOWN: + + return 1; + + default: + /* + * Thread works currently, we should try to end it, own the TI structure + * (because of possible sharing the joint structures with thread) + */ + InterlockedExchange(&pipeTI->state, PTI_STATE_END); + break; + } + + return 0; +} + +void +PipeThreadStop( + PipeThreadInfo **pipeTIPtr, + HANDLE hThread) +{ + PipeThreadInfo *pipeTI = *pipeTIPtr; + HANDLE evControl; + int state; + + if (!pipeTI) { + return; + } + pipeTI = *pipeTIPtr; + evControl = pipeTI->evControl; + /* + * Try to sane stop the pipe worker, corresponding its current state + */ + switch ( + (state = InterlockedCompareExchange(&pipeTI->state, + PTI_STATE_STOP, PTI_STATE_IDLE)) + ) { + + case PTI_STATE_IDLE: + + /* Thread was idle/waiting, notify it goes teardown */ + SetEvent(evControl); + + /* we don't need to wait for it at all, thread frees himself (owns the TI structure) */ + pipeTI = NULL; + break; + + case PTI_STATE_STOP: + /* already stopped, thread frees himself (owns the TI structure) */ + pipeTI = NULL; + break; + case PTI_STATE_DOWN: + /* Thread already down (?), do nothing */ + + /* we don't need to wait for it, but we should free pipeTI */ + hThread = NULL; + break; + + /* case PTI_STATE_WORK: */ + default: + /* + * Thread works currently, we should try to end it, own the TI structure + * (because of possible sharing the joint structures with thread) + */ + InterlockedExchange(&pipeTI->state, PTI_STATE_END); + break; + } + + if (pipeTI && hThread) { + DWORD exitCode; + + /* + * The thread may already have closed on its own. Check its exit + * code. + */ + + GetExitCodeThread(hThread, &exitCode); + + if (exitCode == STILL_ACTIVE) { + /* + * Set the stop event so that if the pipe thread is blocked + * somewhere, it may hereafter sane exit cleanly. + */ + + SetEvent(evControl); + + /* + * Cancel all sync-IO of this thread (may be blocked there). + */ + if (tclWinProcs->cancelSynchronousIo) { + tclWinProcs->cancelSynchronousIo(hThread); + } + + /* + * Wait at most 20 milliseconds for the reader thread to + * close (regarding TIP#398-fast-exit). + */ + + /* if we want TIP#398-fast-exit. */ + if (WaitForSingleObject(hThread, + TclInExit() ? 0 : 0) == WAIT_TIMEOUT) { + + /* + * The thread must be blocked waiting for the pipe to + * become readable in ReadFile(). There isn't a clean way + * to exit the thread from this condition. We should + * terminate the child process instead to get the reader + * thread to fall out of ReadFile with a FALSE. (below) is + * not the correct way to do this, but will stay here + * until a better solution is found. + * + * Note that we need to guard against terminating the + * thread while it is in the middle of Tcl_ThreadAlert + * because it won't be able to release the notifier lock. + * + * Also note that terminating threads during their initialization or teardown phase + * may result in ntdll.dll's LoaderLock to remain locked indefinitely. + * This causes ntdll.dll's LdrpInitializeThread() to deadlock trying to acquire LoaderLock. + * LdrpInitializeThread() is executed within new threads to perform + * initialization and to execute DllMain() of all loaded dlls. + * As a result, all new threads are deadlocked in their initialization phase and never execute, + * even though CreateThread() reports successful thread creation. + * This results in a very weird process-wide behavior, which is extremely hard to debug. + * + * THREADS SHOULD NEVER BE TERMINATED. Period. + * + * But for now, check if thread is exiting, and if so, let it die peacefully. + */ + + if ( pipeTI->state != PTI_STATE_DOWN + && WaitForSingleObject(hThread, + TclInExit() ? 0 : 5000) != WAIT_OBJECT_0 + ) { + Tcl_MutexLock(&pipeMutex); + /* BUG: this leaks memory */ + if (!TerminateThread(hThread, 0)) { + /* terminate fails, just give thread a chance to exit */ + if (InterlockedExchange(&pipeTI->state, + PTI_STATE_STOP) != PTI_STATE_DOWN) { + pipeTI = NULL; + } + }; + Tcl_MutexUnlock(&pipeMutex); + } + } + } + } + + *pipeTIPtr = NULL; + if (pipeTI) { + CloseHandle(pipeTI->evControl); + ckfree(pipeTI); + } +} + +void +PipeThreadExit( + PipeThreadInfo **pipeTIPtr) +{ + LONG state; + PipeThreadInfo *pipeTI = *pipeTIPtr; + /* + * If state of thread was set to stop (exactly), we can sane free its info + * structure, otherwise it is shared with main thread, so main thread will + * own it. + */ + if (!pipeTI) { + return; + } + *pipeTIPtr = NULL; + if ((state = InterlockedExchange(&pipeTI->state, + PTI_STATE_DOWN)) == PTI_STATE_STOP) { + CloseHandle(pipeTI->evControl); + ckfree(pipeTI); + } +} + typedef struct PipeInfo { struct PipeInfo *nextPtr; /* Pointer to next registered pipe. */ Tcl_Channel channel; /* Pointer to channel structure. */ @@ -109,28 +387,17 @@ typedef struct PipeInfo { Tcl_ThreadId threadId; /* Thread to which events should be reported. * This value is used by the reader/writer * threads. */ + PipeThreadInfo *writeTI; /* Thread info of writer and reader, this */ + PipeThreadInfo *readTI; /* structure owned by corresponding thread. */ HANDLE writeThread; /* Handle to writer thread. */ HANDLE readThread; /* Handle to reader thread. */ - int writeThreadExiting; /* Boolean indicating that write thread is exiting */ - int readThreadExiting; /* Boolean indicating that read thread is exiting */ + HANDLE writable; /* Manual-reset event to signal when the * writer thread has finished waiting for the * current buffer to be written. */ HANDLE readable; /* Manual-reset event to signal when the * reader thread has finished waiting for * input. */ - HANDLE startWriter; /* Auto-reset event used by the main thread to - * signal when the writer thread should - * attempt to write to the pipe. Additionally - * this event used as wait for thread event (init). */ - HANDLE stopWriter; /* Manual-reset event used to alert the reader - * thread to fall-out and exit */ - HANDLE startReader; /* Auto-reset event used by the main thread to - * signal when the reader thread should - * attempt to read from the pipe. Additionally - * this event used as wait for thread event (init). */ - HANDLE stopReader; /* Manual-reset event used to alert the reader - * thread to fall-out and exit */ DWORD writeError; /* An error caused by the last background * write. Set to 0 if no error has been * detected. This word is shared with the @@ -1575,8 +1842,7 @@ TclpCreateCommandChannel( Tcl_Pid *pidPtr) /* An array of process identifiers. */ { char channelName[16 + TCL_INTEGER_SPACE]; - DWORD id, wEventsCnt = 0; - HANDLE wEvents[2]; + DWORD id; PipeInfo *infoPtr = ckalloc(sizeof(PipeInfo)); PipeInit(); @@ -1603,16 +1869,18 @@ TclpCreateCommandChannel( * Start the background reader thread. */ + PipeThreadInfo *pipeTI = ckalloc(sizeof(PipeThreadInfo)); + pipeTI->evControl = CreateEvent(NULL, FALSE, FALSE, NULL); + pipeTI->state = PTI_STATE_IDLE; + pipeTI->clientData = infoPtr; + infoPtr->readTI = pipeTI; infoPtr->readable = CreateEvent(NULL, TRUE, TRUE, NULL); - infoPtr->startReader = CreateEvent(NULL, FALSE, FALSE, NULL); - infoPtr->stopReader = CreateEvent(NULL, TRUE, FALSE, NULL); - infoPtr->readThreadExiting = FALSE; infoPtr->readThread = CreateThread(NULL, 256, PipeReaderThread, - infoPtr, 0, &id); + pipeTI, 0, &id); SetThreadPriority(infoPtr->readThread, THREAD_PRIORITY_HIGHEST); infoPtr->validMask |= TCL_READABLE; - wEvents[wEventsCnt++] = infoPtr->startReader; } else { + infoPtr->readTI = NULL; infoPtr->readThread = 0; } if (writeFile != NULL) { @@ -1620,31 +1888,21 @@ TclpCreateCommandChannel( * Start the background writer thread. */ + PipeThreadInfo *pipeTI = ckalloc(sizeof(PipeThreadInfo)); + pipeTI->evControl = CreateEvent(NULL, FALSE, FALSE, NULL); + pipeTI->state = PTI_STATE_IDLE; + pipeTI->clientData = infoPtr; + infoPtr->writeTI = pipeTI; infoPtr->writable = CreateEvent(NULL, TRUE, TRUE, NULL); - infoPtr->startWriter = CreateEvent(NULL, FALSE, FALSE, NULL); - infoPtr->stopWriter = CreateEvent(NULL, TRUE, FALSE, NULL); - infoPtr->writeThreadExiting = FALSE; infoPtr->writeThread = CreateThread(NULL, 256, PipeWriterThread, - infoPtr, 0, &id); + pipeTI, 0, &id); SetThreadPriority(infoPtr->writeThread, THREAD_PRIORITY_HIGHEST); infoPtr->validMask |= TCL_WRITABLE; - wEvents[wEventsCnt++] = infoPtr->startWriter; } else { + infoPtr->writeTI = NULL; infoPtr->writeThread = 0; } - /* - * Wait for both threads to initialize (using theirs start-events) - */ - if (wEventsCnt) { - WaitForMultipleObjects(wEventsCnt, wEvents, TRUE, 5000); - /* Resume both waiting threads, we've get the events */ - if (infoPtr->readThread) - SetEvent(infoPtr->stopReader); - if (infoPtr->writeThread) - SetEvent(infoPtr->stopWriter); - } - /* * For backward compatibility with previous versions of Tcl, we use * "file%d" as the base name for pipes even though it would be more @@ -1828,7 +2086,6 @@ PipeClose2Proc( int errorCode, result; PipeInfo *infoPtr, **nextPtrPtr; ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&dataKey); - DWORD exitCode; errorCode = 0; result = 0; @@ -1841,71 +2098,10 @@ PipeClose2Proc( */ if (pipePtr->readThread) { - /* - * The thread may already have closed on its own. Check its exit - * code. - */ - - GetExitCodeThread(pipePtr->readThread, &exitCode); - - if (exitCode == STILL_ACTIVE) { - /* - * Set the stop event so that if the reader thread is blocked - * in PipeReaderThread on WaitForMultipleEvents, it will exit - * cleanly. - */ - - SetEvent(pipePtr->stopReader); - - /* - * Wait at most 20 milliseconds for the reader thread to - * close. - */ - - if (WaitForSingleObject(pipePtr->readThread, - 20) == WAIT_TIMEOUT) { - /* - * The thread must be blocked waiting for the pipe to - * become readable in ReadFile(). There isn't a clean way - * to exit the thread from this condition. We should - * terminate the child process instead to get the reader - * thread to fall out of ReadFile with a FALSE. (below) is - * not the correct way to do this, but will stay here - * until a better solution is found. - * - * Note that we need to guard against terminating the - * thread while it is in the middle of Tcl_ThreadAlert - * because it won't be able to release the notifier lock. - * - * Also note that terminating threads during their initialization or teardown phase - * may result in ntdll.dll's LoaderLock to remain locked indefinitely. - * This causes ntdll.dll's LdrpInitializeThread() to deadlock trying to acquire LoaderLock. - * LdrpInitializeThread() is executed within new threads to perform - * initialization and to execute DllMain() of all loaded dlls. - * As a result, all new threads are deadlocked in their initialization phase and never execute, - * even though CreateThread() reports successful thread creation. - * This results in a very weird process-wide behavior, which is extremely hard to debug. - * - * THREADS SHOULD NEVER BE TERMINATED. Period. - * - * But for now, check if thread is exiting, and if so, let it die peacefully. - */ - - if ( !pipePtr->readThreadExiting - || WaitForSingleObject(pipePtr->readThread, 5000) != WAIT_OBJECT_0 - ) { - Tcl_MutexLock(&pipeMutex); - /* BUG: this leaks memory */ - TerminateThread(pipePtr->readThread, 0); - Tcl_MutexUnlock(&pipeMutex); - } - } - } + PipeThreadStop(&pipePtr->readTI, pipePtr->readThread); CloseHandle(pipePtr->readThread); CloseHandle(pipePtr->readable); - CloseHandle(pipePtr->startReader); - CloseHandle(pipePtr->stopReader); pipePtr->readThread = NULL; } if (TclpCloseFile(pipePtr->readFile) != 0) { @@ -1917,93 +2113,32 @@ PipeClose2Proc( if ((!flags || flags & TCL_CLOSE_WRITE) && (pipePtr->writeFile != NULL)) { if (pipePtr->writeThread) { - /* - * Wait for the writer thread to finish the current buffer, then - * terminate the thread and close the handles. If the channel is - * nonblocking but blocked during exit, bail out since the worker - * thread is not interruptible and we want TIP#398-fast-exit. - */ - if (TclInExit() - && (pipePtr->flags & PIPE_ASYNC)) { - - /* give it a chance to leave honorably */ - SetEvent(pipePtr->stopWriter); - - if (WaitForSingleObject(pipePtr->writable, 0) == WAIT_TIMEOUT) { - return EWOULDBLOCK; - } - - } else { - WaitForSingleObject(pipePtr->writable, INFINITE); - - } - - /* - * The thread may already have closed on it's own. Check its exit - * code. - */ - - GetExitCodeThread(pipePtr->writeThread, &exitCode); - - if (exitCode == STILL_ACTIVE) { + /* Notify thread we will stop work and check it still seems to work */ + if (!PipeThreadStopSignal(&pipePtr->writeTI)) { /* - * Set the stop event so that if the writer thread is blocked - * in PipeWriterThread on WaitForMultipleEvents, it will exit - * cleanly. + * Wait for the writer thread to finish the current buffer, then + * terminate the thread and close the handles. If the channel is + * nonblocking or may block during exit, bail out since the worker + * thread is not interruptible and we want TIP#398-fast-exit. */ + if ((pipePtr->flags & PIPE_ASYNC) || TclInExit()) { - SetEvent(pipePtr->stopWriter); + /* give it a chance to leave honorably */ + if (WaitForSingleObject(pipePtr->writable, 0) == WAIT_TIMEOUT) { + return EWOULDBLOCK; + } - /* - * Wait at most 20 milliseconds for the reader thread to - * close. - */ + } else { - if (WaitForSingleObject(pipePtr->writeThread, - 20) == WAIT_TIMEOUT) { - /* - * The thread must be blocked waiting for the pipe to - * consume input in WriteFile(). There isn't a clean way - * to exit the thread from this condition. We should - * terminate the child process instead to get the writer - * thread to fall out of WriteFile with a FALSE. (below) - * is not the correct way to do this, but will stay here - * until a better solution is found. - * - * Note that we need to guard against terminating the - * thread while it is in the middle of Tcl_ThreadAlert - * because it won't be able to release the notifier lock. - * - * Also note that terminating threads during their initialization or teardown phase - * may result in ntdll.dll's LoaderLock to remain locked indefinitely. - * This causes ntdll.dll's LdrpInitializeThread() to deadlock trying to acquire LoaderLock. - * LdrpInitializeThread() is executed within new threads to perform - * initialization and to execute DllMain() of all loaded dlls. - * As a result, all new threads are deadlocked in their initialization phase and never execute, - * even though CreateThread() reports successful thread creation. - * This results in a very weird process-wide behavior, which is extremely hard to debug. - * - * THREADS SHOULD NEVER BE TERMINATED. Period. - * - * But for now, check if thread is exiting, and if so, let it die peacefully. - */ + WaitForSingleObject(pipePtr->writable, INFINITE); - if ( !pipePtr->writeThreadExiting - || WaitForSingleObject(pipePtr->writeThread, 5000) != WAIT_OBJECT_0 - ) { - Tcl_MutexLock(&pipeMutex); - /* BUG: this leaks memory */ - TerminateThread(pipePtr->writeThread, 0); - Tcl_MutexUnlock(&pipeMutex); - } } } + PipeThreadStop(&pipePtr->writeTI, pipePtr->writeThread); - CloseHandle(pipePtr->writeThread); CloseHandle(pipePtr->writable); - CloseHandle(pipePtr->startWriter); - CloseHandle(pipePtr->stopWriter); + CloseHandle(pipePtr->writeThread); pipePtr->writeThread = NULL; } if (TclpCloseFile(pipePtr->writeFile) != 0) { @@ -2257,7 +2392,7 @@ PipeOutputProc( memcpy(infoPtr->writeBuf, buf, (size_t) toWrite); infoPtr->toWrite = toWrite; ResetEvent(infoPtr->writable); - SetEvent(infoPtr->startWriter); + PipeThreadSignal(&infoPtr->writeTI); bytesWritten = toWrite; } else { /* @@ -2841,7 +2976,7 @@ WaitForRead( */ ResetEvent(infoPtr->readable); - SetEvent(infoPtr->startReader); + PipeThreadSignal(&infoPtr->readTI); } } @@ -2869,39 +3004,27 @@ static DWORD WINAPI PipeReaderThread( LPVOID arg) { - PipeInfo *infoPtr = (PipeInfo *)arg; - HANDLE *handle = ((WinFile *) infoPtr->readFile)->handle; + PipeThreadInfo *pipeTI = (PipeThreadInfo *)arg; + PipeInfo *infoPtr = NULL; /* access info only after success init/wait */ + HANDLE handle = NULL; DWORD count, err; int done = 0; - HANDLE wEvents[2]; - DWORD waitResult; - - /* - * Notify caller that this thread has been initialized - */ - SignalObjectAndWait(infoPtr->startReader, infoPtr->stopReader, INFINITE, FALSE); - ResetEvent(infoPtr->stopReader); /* not auto-reset */ - - wEvents[0] = infoPtr->stopReader; - wEvents[1] = infoPtr->startReader; - + while (!done) { /* * Wait for the main thread to signal before attempting to wait on the * pipe becoming readable. */ - - waitResult = WaitForMultipleObjects(2, wEvents, FALSE, INFINITE); - - if (waitResult != (WAIT_OBJECT_0 + 1)) { - /* - * The start event was not signaled. It might be the stop event or - * an error, so exit. - */ - + if (!PipeThreadWaitForSignal(&pipeTI)) { + /* exit */ break; } + if (!infoPtr) { + infoPtr = (PipeInfo *)pipeTI->clientData; + handle = ((WinFile *) infoPtr->readFile)->handle; + } + /* * Try waiting for 0 bytes. This will block until some data is * available on NT, but will return immediately on Win 95. So, if no @@ -2948,7 +3071,6 @@ PipeReaderThread( } } - /* * Signal the main thread by signalling the readable event and then * waking up the notifier thread. @@ -2975,10 +3097,10 @@ PipeReaderThread( } /* - * Inform caller that this thread should not be terminated, since it is about to exit. - * See comment in PipeClose2Proc() for reasons. - */ - infoPtr->readThreadExiting = TRUE; + * If state of thread was set to stop, we can sane free info structure, + * otherwise it is shared with main thread, so main thread will own it + */ + PipeThreadExit(&pipeTI); return 0; } @@ -3004,43 +3126,27 @@ static DWORD WINAPI PipeWriterThread( LPVOID arg) { - PipeInfo *infoPtr = (PipeInfo *)arg; - HANDLE *handle = ((WinFile *) infoPtr->writeFile)->handle; + PipeThreadInfo *pipeTI = (PipeThreadInfo *)arg; + PipeInfo *infoPtr = NULL; /* access info only after success init/wait */ + HANDLE handle = NULL; DWORD count, toWrite; char *buf; int done = 0; - HANDLE wEvents[2]; - DWORD waitResult; - - /* - * Notify caller that this thread has been initialized - */ - SignalObjectAndWait(infoPtr->startWriter, infoPtr->stopWriter, INFINITE, FALSE); - ResetEvent(infoPtr->stopWriter); /* not auto-reset */ - - wEvents[0] = infoPtr->stopWriter; - wEvents[1] = infoPtr->startWriter; while (!done) { /* * Wait for the main thread to signal before attempting to write. */ - - waitResult = WaitForMultipleObjects(2, wEvents, FALSE, INFINITE); - - if (waitResult != (WAIT_OBJECT_0 + 1)) { - /* - * The start event was not signaled. It might be the stop event or - * an error, so exit. - */ - - if (waitResult == WAIT_OBJECT_0) { - SetEvent(infoPtr->writable); - } - + if (!PipeThreadWaitForSignal(&pipeTI)) { + /* exit */ break; } + if (!infoPtr) { + infoPtr = (PipeInfo *)pipeTI->clientData; + handle = ((WinFile *) infoPtr->writeFile)->handle; + } + buf = infoPtr->writeBuf; toWrite = infoPtr->toWrite; @@ -3085,10 +3191,10 @@ PipeWriterThread( } /* - * Inform caller that this thread should not be terminated, since it is about to exit. - * See comment in PipeClose2Proc() for reasons. + * If state of thread was set to stop, we can sane free info structure, + * otherwise it is shared with main thread, so main thread will own it. */ - infoPtr->writeThreadExiting = TRUE; + PipeThreadExit(&pipeTI); return 0; } -- cgit v0.12 From f5538049ef0a44bcdc024febef5803c397b4067a Mon Sep 17 00:00:00 2001 From: sebres Date: Tue, 11 Apr 2017 18:08:43 +0000 Subject: code review and fix small memory leak using ckalloc, without finalization of tcl subsystem in the worker (if it owns TI structure and calls ckfree) --- win/tclWinPipe.c | 107 ++++++++++++++++++++++++++++++++++++------------------- 1 file changed, 71 insertions(+), 36 deletions(-) diff --git a/win/tclWinPipe.c b/win/tclWinPipe.c index bb76eef..13d90b6 100644 --- a/win/tclWinPipe.c +++ b/win/tclWinPipe.c @@ -101,11 +101,42 @@ typedef struct PipeThreadInfo { } PipeThreadInfo; -#define PTI_STATE_IDLE 0 -#define PTI_STATE_WORK 1 -#define PTI_STATE_STOP 2 -#define PTI_STATE_END 4 -#define PTI_STATE_DOWN 8 +/* If pipe-workers will use some tcl subsystem, we can use ckalloc without + * more overhead for finalize thread (should be executed anyway) + * + * #define _PTI_USE_CKALLOC 1 + */ + +/* + * State of the pipe-worker. + * + * State PTI_STATE_STOP possible from idle state only, worker owns TI structure. + * Otherwise PTI_STATE_END used (main thread hold ownership of the TI). + */ + +#define PTI_STATE_IDLE 0 /* idle or not yet initialzed */ +#define PTI_STATE_WORK 1 /* in work */ +#define PTI_STATE_STOP 2 /* thread should stop work (owns TI structure) */ +#define PTI_STATE_END 4 /* thread should stop work (worker is busy) */ +#define PTI_STATE_DOWN 8 /* worker is down */ + + +PipeThreadInfo * +PipeThreadCreateTI( + PipeThreadInfo **pipeTIPtr, + ClientData clientData) +{ + PipeThreadInfo *pipeTI; +#ifndef _PTI_USE_CKALLOC + pipeTI = malloc(sizeof(PipeThreadInfo)); +#else + pipeTI = ckalloc(sizeof(PipeThreadInfo)); +#endif + pipeTI->evControl = CreateEvent(NULL, FALSE, FALSE, NULL); + pipeTI->state = PTI_STATE_IDLE; + pipeTI->clientData = clientData; + return (*pipeTIPtr = pipeTI); +} int PipeThreadWaitForSignal( @@ -292,7 +323,7 @@ PipeThreadStop( /* if we want TIP#398-fast-exit. */ if (WaitForSingleObject(hThread, - TclInExit() ? 0 : 0) == WAIT_TIMEOUT) { + TclInExit() ? 0 : 20) == WAIT_TIMEOUT) { /* * The thread must be blocked waiting for the pipe to @@ -343,7 +374,11 @@ PipeThreadStop( *pipeTIPtr = NULL; if (pipeTI) { CloseHandle(pipeTI->evControl); + #ifndef _PTI_USE_CKALLOC + free(pipeTI); + #else ckfree(pipeTI); + #endif } } @@ -365,7 +400,13 @@ PipeThreadExit( if ((state = InterlockedExchange(&pipeTI->state, PTI_STATE_DOWN)) == PTI_STATE_STOP) { CloseHandle(pipeTI->evControl); + #ifndef _PTI_USE_CKALLOC + free(pipeTI); + #else ckfree(pipeTI); + /* be sure all subsystems used are finalized */ + Tcl_FinalizeThread(); + #endif } } @@ -1869,14 +1910,9 @@ TclpCreateCommandChannel( * Start the background reader thread. */ - PipeThreadInfo *pipeTI = ckalloc(sizeof(PipeThreadInfo)); - pipeTI->evControl = CreateEvent(NULL, FALSE, FALSE, NULL); - pipeTI->state = PTI_STATE_IDLE; - pipeTI->clientData = infoPtr; - infoPtr->readTI = pipeTI; infoPtr->readable = CreateEvent(NULL, TRUE, TRUE, NULL); infoPtr->readThread = CreateThread(NULL, 256, PipeReaderThread, - pipeTI, 0, &id); + PipeThreadCreateTI(&infoPtr->readTI, infoPtr), 0, &id); SetThreadPriority(infoPtr->readThread, THREAD_PRIORITY_HIGHEST); infoPtr->validMask |= TCL_READABLE; } else { @@ -1888,14 +1924,9 @@ TclpCreateCommandChannel( * Start the background writer thread. */ - PipeThreadInfo *pipeTI = ckalloc(sizeof(PipeThreadInfo)); - pipeTI->evControl = CreateEvent(NULL, FALSE, FALSE, NULL); - pipeTI->state = PTI_STATE_IDLE; - pipeTI->clientData = infoPtr; - infoPtr->writeTI = pipeTI; infoPtr->writable = CreateEvent(NULL, TRUE, TRUE, NULL); infoPtr->writeThread = CreateThread(NULL, 256, PipeWriterThread, - pipeTI, 0, &id); + PipeThreadCreateTI(&infoPtr->writeTI, infoPtr), 0, &id); SetThreadPriority(infoPtr->writeThread, THREAD_PRIORITY_HIGHEST); infoPtr->validMask |= TCL_WRITABLE; } else { @@ -2114,27 +2145,27 @@ PipeClose2Proc( && (pipePtr->writeFile != NULL)) { if (pipePtr->writeThread) { - /* Notify thread we will stop work and check it still seems to work */ - if (!PipeThreadStopSignal(&pipePtr->writeTI)) { - /* - * Wait for the writer thread to finish the current buffer, then - * terminate the thread and close the handles. If the channel is - * nonblocking or may block during exit, bail out since the worker - * thread is not interruptible and we want TIP#398-fast-exit. - */ - if ((pipePtr->flags & PIPE_ASYNC) || TclInExit()) { + /* + * Wait for the writer thread to finish the current buffer, then + * terminate the thread and close the handles. If the channel is + * nonblocking or may block during exit, bail out since the worker + * thread is not interruptible and we want TIP#398-fast-exit. + */ + if ((pipePtr->flags & PIPE_ASYNC) && TclInExit()) { - /* give it a chance to leave honorably */ - if (WaitForSingleObject(pipePtr->writable, 0) == WAIT_TIMEOUT) { - return EWOULDBLOCK; - } + /* give it a chance to leave honorably */ + PipeThreadStopSignal(&pipePtr->writeTI); - } else { + if (WaitForSingleObject(pipePtr->writable, 20) == WAIT_TIMEOUT) { + return EWOULDBLOCK; + } - WaitForSingleObject(pipePtr->writable, INFINITE); + } else { + + WaitForSingleObject(pipePtr->writable, INFINITE); - } } + PipeThreadStop(&pipePtr->writeTI, pipePtr->writeThread); CloseHandle(pipePtr->writable); @@ -3128,7 +3159,7 @@ PipeWriterThread( { PipeThreadInfo *pipeTI = (PipeThreadInfo *)arg; PipeInfo *infoPtr = NULL; /* access info only after success init/wait */ - HANDLE handle = NULL; + HANDLE handle = NULL, writable = NULL; DWORD count, toWrite; char *buf; int done = 0; @@ -3139,12 +3170,16 @@ PipeWriterThread( */ if (!PipeThreadWaitForSignal(&pipeTI)) { /* exit */ + if (writable) { + SetEvent(writable); + } break; } if (!infoPtr) { infoPtr = (PipeInfo *)pipeTI->clientData; handle = ((WinFile *) infoPtr->writeFile)->handle; + writable = infoPtr->writable; } buf = infoPtr->writeBuf; @@ -3170,7 +3205,7 @@ PipeWriterThread( * waking up the notifier thread. */ - SetEvent(infoPtr->writable); + SetEvent(writable); /* * Alert the foreground thread. Note that we need to treat this like a -- cgit v0.12 From b8186ff7078b1c41f2c3cb7dec93cc7d72cd2c01 Mon Sep 17 00:00:00 2001 From: sebres Date: Tue, 11 Apr 2017 18:09:06 +0000 Subject: prepared to use pipe-helpers (TI-structure handling) for all pipe-workers (tclWinConsole, tclWinSerial) --- win/tclWinInt.h | 56 + win/tclWinPipe.c | 4698 +++++++++++++++++++++++++++--------------------------- 2 files changed, 2428 insertions(+), 2326 deletions(-) diff --git a/win/tclWinInt.h b/win/tclWinInt.h index b8d493e..8ce4152 100644 --- a/win/tclWinInt.h +++ b/win/tclWinInt.h @@ -95,4 +95,60 @@ MODULE_SCOPE void TclpSetAllocCache(void *); #define FILE_ATTRIBUTE_REPARSE_POINT 0x00000400 #endif +/* + *---------------------------------------------------------------------- + * Declarations of helper-workers threaded facilities for a pipe based channel. + * + * Corresponding functionality provided in "tclWinPipe.c". + *---------------------------------------------------------------------- + */ + +typedef struct TclPipeThreadInfo { + HANDLE evControl; /* Auto-reset event used by the main thread to + * signal when the pipe thread should attempt + * to do read/write operation. Additionally + * used as signal to stop (state set to -1) */ + volatile LONG state; /* Indicates current state of the thread */ + ClientData clientData; /* Referenced data of the main thread */ +} TclPipeThreadInfo; + + +/* If pipe-workers will use some tcl subsystem, we can use ckalloc without + * more overhead for finalize thread (should be executed anyway) + * + * #define _PTI_USE_CKALLOC 1 + */ + +/* + * State of the pipe-worker. + * + * State PTI_STATE_STOP possible from idle state only, worker owns TI structure. + * Otherwise PTI_STATE_END used (main thread hold ownership of the TI). + */ + +#define PTI_STATE_IDLE 0 /* idle or not yet initialzed */ +#define PTI_STATE_WORK 1 /* in work */ +#define PTI_STATE_STOP 2 /* thread should stop work (owns TI structure) */ +#define PTI_STATE_END 4 /* thread should stop work (worker is busy) */ +#define PTI_STATE_DOWN 8 /* worker is down */ + + +MODULE_SCOPE +TclPipeThreadInfo * TclPipeThreadCreateTI(TclPipeThreadInfo **pipeTIPtr, ClientData clientData); +MODULE_SCOPE int TclPipeThreadWaitForSignal(TclPipeThreadInfo **pipeTIPtr); + +static inline void +TclPipeThreadSignal( + TclPipeThreadInfo **pipeTIPtr) +{ + TclPipeThreadInfo *pipeTI = *pipeTIPtr; + if (pipeTI) { + SetEvent(pipeTI->evControl); + } +}; + +MODULE_SCOPE int TclPipeThreadStopSignal(TclPipeThreadInfo **pipeTIPtr); +MODULE_SCOPE void TclPipeThreadStop(TclPipeThreadInfo **pipeTIPtr, HANDLE hThread); +MODULE_SCOPE void TclPipeThreadExit(TclPipeThreadInfo **pipeTIPtr); + #endif /* _TCLWININT */ diff --git a/win/tclWinPipe.c b/win/tclWinPipe.c index 13d90b6..4b4e68d 100644 --- a/win/tclWinPipe.c +++ b/win/tclWinPipe.c @@ -91,325 +91,6 @@ static ProcInfo *procList; * This structure describes per-instance data for a pipe based channel. */ -typedef struct PipeThreadInfo { - HANDLE evControl; /* Auto-reset event used by the main thread to - * signal when the pipe thread should attempt - * to do read/write operation. Additionally - * used as signal to stop (state set to -1) */ - volatile LONG state; /* Indicates current state of the thread */ - ClientData clientData; /* Referenced data of the main thread */ -} PipeThreadInfo; - - -/* If pipe-workers will use some tcl subsystem, we can use ckalloc without - * more overhead for finalize thread (should be executed anyway) - * - * #define _PTI_USE_CKALLOC 1 - */ - -/* - * State of the pipe-worker. - * - * State PTI_STATE_STOP possible from idle state only, worker owns TI structure. - * Otherwise PTI_STATE_END used (main thread hold ownership of the TI). - */ - -#define PTI_STATE_IDLE 0 /* idle or not yet initialzed */ -#define PTI_STATE_WORK 1 /* in work */ -#define PTI_STATE_STOP 2 /* thread should stop work (owns TI structure) */ -#define PTI_STATE_END 4 /* thread should stop work (worker is busy) */ -#define PTI_STATE_DOWN 8 /* worker is down */ - - -PipeThreadInfo * -PipeThreadCreateTI( - PipeThreadInfo **pipeTIPtr, - ClientData clientData) -{ - PipeThreadInfo *pipeTI; -#ifndef _PTI_USE_CKALLOC - pipeTI = malloc(sizeof(PipeThreadInfo)); -#else - pipeTI = ckalloc(sizeof(PipeThreadInfo)); -#endif - pipeTI->evControl = CreateEvent(NULL, FALSE, FALSE, NULL); - pipeTI->state = PTI_STATE_IDLE; - pipeTI->clientData = clientData; - return (*pipeTIPtr = pipeTI); -} - -int -PipeThreadWaitForSignal( - PipeThreadInfo **pipeTIPtr) -{ - PipeThreadInfo *pipeTI = *pipeTIPtr; - LONG state; - DWORD waitResult; - - if (!pipeTI) { - return 0; - } - /* - * Wait for the main thread to signal before attempting to do the work. - */ - - /* reset work state of thread (idle/waiting) */ - if ((state = InterlockedCompareExchange(&pipeTI->state, - PTI_STATE_IDLE, PTI_STATE_WORK)) & (PTI_STATE_STOP|PTI_STATE_END)) { - /* end of work, check the owner of structure */ - goto end; - } - /* entering wait */ - waitResult = WaitForSingleObject(pipeTI->evControl, INFINITE); - - if (waitResult != WAIT_OBJECT_0) { - - /* - * The control event was not signaled, so end of work (unexpected - * behaviour, main thread can be dead?). - */ - goto end; - } - - /* try to set work state of thread */ - if ((state = InterlockedCompareExchange(&pipeTI->state, - PTI_STATE_WORK, PTI_STATE_IDLE)) & (PTI_STATE_STOP|PTI_STATE_END)) { - /* end of work */ - goto end; - } - - /* signaled to work */ - return 1; - -end: - /* end of work, check the owner of the TI structure */ - if (state != PTI_STATE_STOP) { - *pipeTIPtr = NULL; - } - return 0; -} - -static inline void -PipeThreadSignal( - PipeThreadInfo **pipeTIPtr) -{ - PipeThreadInfo *pipeTI = *pipeTIPtr; - if (pipeTI) { - SetEvent(pipeTI->evControl); - } -} - -int -PipeThreadStopSignal( - PipeThreadInfo **pipeTIPtr) -{ - PipeThreadInfo *pipeTI = *pipeTIPtr; - HANDLE evControl; - int state; - - if (!pipeTI) { - return 1; - } - evControl = pipeTI->evControl; - switch ( - (state = InterlockedCompareExchange(&pipeTI->state, - PTI_STATE_STOP, PTI_STATE_IDLE)) - ) { - - case PTI_STATE_IDLE: - - /* Thread was idle/waiting, notify it goes teardown */ - SetEvent(evControl); - - *pipeTIPtr = NULL; - - case PTI_STATE_DOWN: - - return 1; - - default: - /* - * Thread works currently, we should try to end it, own the TI structure - * (because of possible sharing the joint structures with thread) - */ - InterlockedExchange(&pipeTI->state, PTI_STATE_END); - break; - } - - return 0; -} - -void -PipeThreadStop( - PipeThreadInfo **pipeTIPtr, - HANDLE hThread) -{ - PipeThreadInfo *pipeTI = *pipeTIPtr; - HANDLE evControl; - int state; - - if (!pipeTI) { - return; - } - pipeTI = *pipeTIPtr; - evControl = pipeTI->evControl; - /* - * Try to sane stop the pipe worker, corresponding its current state - */ - switch ( - (state = InterlockedCompareExchange(&pipeTI->state, - PTI_STATE_STOP, PTI_STATE_IDLE)) - ) { - - case PTI_STATE_IDLE: - - /* Thread was idle/waiting, notify it goes teardown */ - SetEvent(evControl); - - /* we don't need to wait for it at all, thread frees himself (owns the TI structure) */ - pipeTI = NULL; - break; - - case PTI_STATE_STOP: - /* already stopped, thread frees himself (owns the TI structure) */ - pipeTI = NULL; - break; - case PTI_STATE_DOWN: - /* Thread already down (?), do nothing */ - - /* we don't need to wait for it, but we should free pipeTI */ - hThread = NULL; - break; - - /* case PTI_STATE_WORK: */ - default: - /* - * Thread works currently, we should try to end it, own the TI structure - * (because of possible sharing the joint structures with thread) - */ - InterlockedExchange(&pipeTI->state, PTI_STATE_END); - break; - } - - if (pipeTI && hThread) { - DWORD exitCode; - - /* - * The thread may already have closed on its own. Check its exit - * code. - */ - - GetExitCodeThread(hThread, &exitCode); - - if (exitCode == STILL_ACTIVE) { - /* - * Set the stop event so that if the pipe thread is blocked - * somewhere, it may hereafter sane exit cleanly. - */ - - SetEvent(evControl); - - /* - * Cancel all sync-IO of this thread (may be blocked there). - */ - if (tclWinProcs->cancelSynchronousIo) { - tclWinProcs->cancelSynchronousIo(hThread); - } - - /* - * Wait at most 20 milliseconds for the reader thread to - * close (regarding TIP#398-fast-exit). - */ - - /* if we want TIP#398-fast-exit. */ - if (WaitForSingleObject(hThread, - TclInExit() ? 0 : 20) == WAIT_TIMEOUT) { - - /* - * The thread must be blocked waiting for the pipe to - * become readable in ReadFile(). There isn't a clean way - * to exit the thread from this condition. We should - * terminate the child process instead to get the reader - * thread to fall out of ReadFile with a FALSE. (below) is - * not the correct way to do this, but will stay here - * until a better solution is found. - * - * Note that we need to guard against terminating the - * thread while it is in the middle of Tcl_ThreadAlert - * because it won't be able to release the notifier lock. - * - * Also note that terminating threads during their initialization or teardown phase - * may result in ntdll.dll's LoaderLock to remain locked indefinitely. - * This causes ntdll.dll's LdrpInitializeThread() to deadlock trying to acquire LoaderLock. - * LdrpInitializeThread() is executed within new threads to perform - * initialization and to execute DllMain() of all loaded dlls. - * As a result, all new threads are deadlocked in their initialization phase and never execute, - * even though CreateThread() reports successful thread creation. - * This results in a very weird process-wide behavior, which is extremely hard to debug. - * - * THREADS SHOULD NEVER BE TERMINATED. Period. - * - * But for now, check if thread is exiting, and if so, let it die peacefully. - */ - - if ( pipeTI->state != PTI_STATE_DOWN - && WaitForSingleObject(hThread, - TclInExit() ? 0 : 5000) != WAIT_OBJECT_0 - ) { - Tcl_MutexLock(&pipeMutex); - /* BUG: this leaks memory */ - if (!TerminateThread(hThread, 0)) { - /* terminate fails, just give thread a chance to exit */ - if (InterlockedExchange(&pipeTI->state, - PTI_STATE_STOP) != PTI_STATE_DOWN) { - pipeTI = NULL; - } - }; - Tcl_MutexUnlock(&pipeMutex); - } - } - } - } - - *pipeTIPtr = NULL; - if (pipeTI) { - CloseHandle(pipeTI->evControl); - #ifndef _PTI_USE_CKALLOC - free(pipeTI); - #else - ckfree(pipeTI); - #endif - } -} - -void -PipeThreadExit( - PipeThreadInfo **pipeTIPtr) -{ - LONG state; - PipeThreadInfo *pipeTI = *pipeTIPtr; - /* - * If state of thread was set to stop (exactly), we can sane free its info - * structure, otherwise it is shared with main thread, so main thread will - * own it. - */ - if (!pipeTI) { - return; - } - *pipeTIPtr = NULL; - if ((state = InterlockedExchange(&pipeTI->state, - PTI_STATE_DOWN)) == PTI_STATE_STOP) { - CloseHandle(pipeTI->evControl); - #ifndef _PTI_USE_CKALLOC - free(pipeTI); - #else - ckfree(pipeTI); - /* be sure all subsystems used are finalized */ - Tcl_FinalizeThread(); - #endif - } -} - typedef struct PipeInfo { struct PipeInfo *nextPtr; /* Pointer to next registered pipe. */ Tcl_Channel channel; /* Pointer to channel structure. */ @@ -428,8 +109,8 @@ typedef struct PipeInfo { Tcl_ThreadId threadId; /* Thread to which events should be reported. * This value is used by the reader/writer * threads. */ - PipeThreadInfo *writeTI; /* Thread info of writer and reader, this */ - PipeThreadInfo *readTI; /* structure owned by corresponding thread. */ + TclPipeThreadInfo *writeTI; /* Thread info of writer and reader, this */ + TclPipeThreadInfo *readTI; /* structure owned by corresponding thread. */ HANDLE writeThread; /* Handle to writer thread. */ HANDLE readThread; /* Handle to reader thread. */ @@ -614,445 +295,921 @@ TclpFinalizePipes(void) /* *---------------------------------------------------------------------- * - * PipeSetupProc -- + * PipeSetupProc -- + * + * This function is invoked before Tcl_DoOneEvent blocks waiting for an + * event. + * + * Results: + * None. + * + * Side effects: + * Adjusts the block time if needed. + * + *---------------------------------------------------------------------- + */ + +void +PipeSetupProc( + ClientData data, /* Not used. */ + int flags) /* Event flags as passed to Tcl_DoOneEvent. */ +{ + PipeInfo *infoPtr; + Tcl_Time blockTime = { 0, 0 }; + int block = 1; + ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&dataKey); + + if (!(flags & TCL_FILE_EVENTS)) { + return; + } + + /* + * Look to see if any events are already pending. If they are, poll. + */ + + for (infoPtr = tsdPtr->firstPipePtr; infoPtr != NULL; + infoPtr = infoPtr->nextPtr) { + if (infoPtr->watchMask & TCL_WRITABLE) { + if (WaitForSingleObject(infoPtr->writable, 0) != WAIT_TIMEOUT) { + block = 0; + } + } + if (infoPtr->watchMask & TCL_READABLE) { + if (WaitForRead(infoPtr, 0) >= 0) { + block = 0; + } + } + } + if (!block) { + Tcl_SetMaxBlockTime(&blockTime); + } +} + +/* + *---------------------------------------------------------------------- + * + * PipeCheckProc -- + * + * This function is called by Tcl_DoOneEvent to check the pipe event + * source for events. + * + * Results: + * None. + * + * Side effects: + * May queue an event. + * + *---------------------------------------------------------------------- + */ + +static void +PipeCheckProc( + ClientData data, /* Not used. */ + int flags) /* Event flags as passed to Tcl_DoOneEvent. */ +{ + PipeInfo *infoPtr; + PipeEvent *evPtr; + int needEvent; + ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&dataKey); + + if (!(flags & TCL_FILE_EVENTS)) { + return; + } + + /* + * Queue events for any ready pipes that don't already have events queued. + */ + + for (infoPtr = tsdPtr->firstPipePtr; infoPtr != NULL; + infoPtr = infoPtr->nextPtr) { + if (infoPtr->flags & PIPE_PENDING) { + continue; + } + + /* + * Queue an event if the pipe is signaled for reading or writing. + */ + + needEvent = 0; + if ((infoPtr->watchMask & TCL_WRITABLE) && + (WaitForSingleObject(infoPtr->writable, 0) != WAIT_TIMEOUT)) { + needEvent = 1; + } + + if ((infoPtr->watchMask & TCL_READABLE) && + (WaitForRead(infoPtr, 0) >= 0)) { + needEvent = 1; + } + + if (needEvent) { + infoPtr->flags |= PIPE_PENDING; + evPtr = ckalloc(sizeof(PipeEvent)); + evPtr->header.proc = PipeEventProc; + evPtr->infoPtr = infoPtr; + Tcl_QueueEvent((Tcl_Event *) evPtr, TCL_QUEUE_TAIL); + } + } +} + +/* + *---------------------------------------------------------------------- + * + * TclWinMakeFile -- + * + * This function constructs a new TclFile from a given data and type + * value. + * + * Results: + * Returns a newly allocated WinFile as a TclFile. + * + * Side effects: + * None. + * + *---------------------------------------------------------------------- + */ + +TclFile +TclWinMakeFile( + HANDLE handle) /* Type-specific data. */ +{ + WinFile *filePtr; + + filePtr = ckalloc(sizeof(WinFile)); + filePtr->type = WIN_FILE; + filePtr->handle = handle; + + return (TclFile)filePtr; +} + +/* + *---------------------------------------------------------------------- + * + * TempFileName -- + * + * Gets a temporary file name and deals with the fact that the temporary + * file path provided by Windows may not actually exist if the TMP or + * TEMP environment variables refer to a non-existent directory. + * + * Results: + * 0 if error, non-zero otherwise. If non-zero is returned, the name + * buffer will be filled with a name that can be used to construct a + * temporary file. + * + * Side effects: + * None. + * + *---------------------------------------------------------------------- + */ + +static int +TempFileName( + TCHAR name[MAX_PATH]) /* Buffer in which name for temporary file + * gets stored. */ +{ + const TCHAR *prefix = TEXT("TCL"); + if (GetTempPath(MAX_PATH, name) != 0) { + if (GetTempFileName(name, prefix, 0, name) != 0) { + return 1; + } + } + name[0] = '.'; + name[1] = '\0'; + return GetTempFileName(name, prefix, 0, name); +} + +/* + *---------------------------------------------------------------------- + * + * TclpMakeFile -- + * + * Make a TclFile from a channel. + * + * Results: + * Returns a new TclFile or NULL on failure. + * + * Side effects: + * None. + * + *---------------------------------------------------------------------- + */ + +TclFile +TclpMakeFile( + Tcl_Channel channel, /* Channel to get file from. */ + int direction) /* Either TCL_READABLE or TCL_WRITABLE. */ +{ + HANDLE handle; + + if (Tcl_GetChannelHandle(channel, direction, + (ClientData *) &handle) == TCL_OK) { + return TclWinMakeFile(handle); + } else { + return (TclFile) NULL; + } +} + +/* + *---------------------------------------------------------------------- + * + * TclpOpenFile -- * - * This function is invoked before Tcl_DoOneEvent blocks waiting for an - * event. + * This function opens files for use in a pipeline. * * Results: - * None. + * Returns a newly allocated TclFile structure containing the file + * handle. * * Side effects: - * Adjusts the block time if needed. + * None. * *---------------------------------------------------------------------- */ -void -PipeSetupProc( - ClientData data, /* Not used. */ - int flags) /* Event flags as passed to Tcl_DoOneEvent. */ +TclFile +TclpOpenFile( + const char *path, /* The name of the file to open. */ + int mode) /* In what mode to open the file? */ { - PipeInfo *infoPtr; - Tcl_Time blockTime = { 0, 0 }; - int block = 1; - ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&dataKey); + HANDLE handle; + DWORD accessMode, createMode, shareMode, flags; + Tcl_DString ds; + const TCHAR *nativePath; - if (!(flags & TCL_FILE_EVENTS)) { - return; + /* + * Map the access bits to the NT access mode. + */ + + switch (mode & (O_RDONLY | O_WRONLY | O_RDWR)) { + case O_RDONLY: + accessMode = GENERIC_READ; + break; + case O_WRONLY: + accessMode = GENERIC_WRITE; + break; + case O_RDWR: + accessMode = (GENERIC_READ | GENERIC_WRITE); + break; + default: + TclWinConvertError(ERROR_INVALID_FUNCTION); + return NULL; } /* - * Look to see if any events are already pending. If they are, poll. + * Map the creation flags to the NT create mode. */ - for (infoPtr = tsdPtr->firstPipePtr; infoPtr != NULL; - infoPtr = infoPtr->nextPtr) { - if (infoPtr->watchMask & TCL_WRITABLE) { - if (WaitForSingleObject(infoPtr->writable, 0) != WAIT_TIMEOUT) { - block = 0; - } + switch (mode & (O_CREAT | O_EXCL | O_TRUNC)) { + case (O_CREAT | O_EXCL): + case (O_CREAT | O_EXCL | O_TRUNC): + createMode = CREATE_NEW; + break; + case (O_CREAT | O_TRUNC): + createMode = CREATE_ALWAYS; + break; + case O_CREAT: + createMode = OPEN_ALWAYS; + break; + case O_TRUNC: + case (O_TRUNC | O_EXCL): + createMode = TRUNCATE_EXISTING; + break; + default: + createMode = OPEN_EXISTING; + break; + } + + nativePath = Tcl_WinUtfToTChar(path, -1, &ds); + + /* + * If the file is not being created, use the existing file attributes. + */ + + flags = 0; + if (!(mode & O_CREAT)) { + flags = GetFileAttributes(nativePath); + if (flags == 0xFFFFFFFF) { + flags = 0; } - if (infoPtr->watchMask & TCL_READABLE) { - if (WaitForRead(infoPtr, 0) >= 0) { - block = 0; - } + } + + /* + * Set up the file sharing mode. We want to allow simultaneous access. + */ + + shareMode = FILE_SHARE_READ | FILE_SHARE_WRITE; + + /* + * Now we get to create the file. + */ + + handle = CreateFile(nativePath, accessMode, shareMode, + NULL, createMode, flags, NULL); + Tcl_DStringFree(&ds); + + if (handle == INVALID_HANDLE_VALUE) { + DWORD err; + + err = GetLastError(); + if ((err & 0xffffL) == ERROR_OPEN_FAILED) { + err = (mode & O_CREAT) ? ERROR_FILE_EXISTS : ERROR_FILE_NOT_FOUND; } + TclWinConvertError(err); + return NULL; } - if (!block) { - Tcl_SetMaxBlockTime(&blockTime); + + /* + * Seek to the end of file if we are writing. + */ + + if (mode & (O_WRONLY|O_APPEND)) { + SetFilePointer(handle, 0, NULL, FILE_END); } + + return TclWinMakeFile(handle); } /* *---------------------------------------------------------------------- * - * PipeCheckProc -- + * TclpCreateTempFile -- * - * This function is called by Tcl_DoOneEvent to check the pipe event - * source for events. + * This function opens a unique file with the property that it will be + * deleted when its file handle is closed. The temporary file is created + * in the system temporary directory. * * Results: - * None. + * Returns a valid TclFile, or NULL on failure. * * Side effects: - * May queue an event. + * Creates a new temporary file. * *---------------------------------------------------------------------- */ -static void -PipeCheckProc( - ClientData data, /* Not used. */ - int flags) /* Event flags as passed to Tcl_DoOneEvent. */ +TclFile +TclpCreateTempFile( + const char *contents) /* String to write into temp file, or NULL. */ { - PipeInfo *infoPtr; - PipeEvent *evPtr; - int needEvent; - ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&dataKey); + TCHAR name[MAX_PATH]; + const char *native; + Tcl_DString dstring; + HANDLE handle; - if (!(flags & TCL_FILE_EVENTS)) { - return; + if (TempFileName(name) == 0) { + return NULL; + } + + handle = CreateFile(name, + GENERIC_READ | GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, + FILE_ATTRIBUTE_TEMPORARY|FILE_FLAG_DELETE_ON_CLOSE, NULL); + if (handle == INVALID_HANDLE_VALUE) { + goto error; } /* - * Queue events for any ready pipes that don't already have events queued. + * Write the file out, doing line translations on the way. */ - for (infoPtr = tsdPtr->firstPipePtr; infoPtr != NULL; - infoPtr = infoPtr->nextPtr) { - if (infoPtr->flags & PIPE_PENDING) { - continue; - } + if (contents != NULL) { + DWORD result, length; + const char *p; + int toCopy; /* - * Queue an event if the pipe is signaled for reading or writing. + * Convert the contents from UTF to native encoding */ - needEvent = 0; - if ((infoPtr->watchMask & TCL_WRITABLE) && - (WaitForSingleObject(infoPtr->writable, 0) != WAIT_TIMEOUT)) { - needEvent = 1; - } + native = Tcl_UtfToExternalDString(NULL, contents, -1, &dstring); - if ((infoPtr->watchMask & TCL_READABLE) && - (WaitForRead(infoPtr, 0) >= 0)) { - needEvent = 1; + toCopy = Tcl_DStringLength(&dstring); + for (p = native; toCopy > 0; p++, toCopy--) { + if (*p == '\n') { + length = p - native; + if (length > 0) { + if (!WriteFile(handle, native, length, &result, NULL)) { + goto error; + } + } + if (!WriteFile(handle, "\r\n", 2, &result, NULL)) { + goto error; + } + native = p+1; + } } - - if (needEvent) { - infoPtr->flags |= PIPE_PENDING; - evPtr = ckalloc(sizeof(PipeEvent)); - evPtr->header.proc = PipeEventProc; - evPtr->infoPtr = infoPtr; - Tcl_QueueEvent((Tcl_Event *) evPtr, TCL_QUEUE_TAIL); + length = p - native; + if (length > 0) { + if (!WriteFile(handle, native, length, &result, NULL)) { + goto error; + } + } + Tcl_DStringFree(&dstring); + if (SetFilePointer(handle, 0, NULL, FILE_BEGIN) == 0xFFFFFFFF) { + goto error; } } + + return TclWinMakeFile(handle); + + error: + /* + * Free the native representation of the contents if necessary. + */ + + if (contents != NULL) { + Tcl_DStringFree(&dstring); + } + + TclWinConvertError(GetLastError()); + CloseHandle(handle); + DeleteFile(name); + return NULL; +} + +/* + *---------------------------------------------------------------------- + * + * TclpTempFileName -- + * + * This function returns a unique filename. + * + * Results: + * Returns a valid Tcl_Obj* with refCount 0, or NULL on failure. + * + * Side effects: + * None. + * + *---------------------------------------------------------------------- + */ + +Tcl_Obj * +TclpTempFileName(void) +{ + TCHAR fileName[MAX_PATH]; + + if (TempFileName(fileName) == 0) { + return NULL; + } + + return TclpNativeToNormalized(fileName); } /* *---------------------------------------------------------------------- * - * TclWinMakeFile -- + * TclpCreatePipe -- * - * This function constructs a new TclFile from a given data and type - * value. + * Creates an anonymous pipe. * * Results: - * Returns a newly allocated WinFile as a TclFile. + * Returns 1 on success, 0 on failure. * * Side effects: - * None. + * Creates a pipe. * *---------------------------------------------------------------------- */ -TclFile -TclWinMakeFile( - HANDLE handle) /* Type-specific data. */ +int +TclpCreatePipe( + TclFile *readPipe, /* Location to store file handle for read side + * of pipe. */ + TclFile *writePipe) /* Location to store file handle for write + * side of pipe. */ { - WinFile *filePtr; + HANDLE readHandle, writeHandle; - filePtr = ckalloc(sizeof(WinFile)); - filePtr->type = WIN_FILE; - filePtr->handle = handle; + if (CreatePipe(&readHandle, &writeHandle, NULL, 0) != 0) { + *readPipe = TclWinMakeFile(readHandle); + *writePipe = TclWinMakeFile(writeHandle); + return 1; + } - return (TclFile)filePtr; + TclWinConvertError(GetLastError()); + return 0; } /* *---------------------------------------------------------------------- * - * TempFileName -- + * TclpCloseFile -- * - * Gets a temporary file name and deals with the fact that the temporary - * file path provided by Windows may not actually exist if the TMP or - * TEMP environment variables refer to a non-existent directory. + * Closes a pipeline file handle. These handles are created by + * TclpOpenFile, TclpCreatePipe, or TclpMakeFile. * * Results: - * 0 if error, non-zero otherwise. If non-zero is returned, the name - * buffer will be filled with a name that can be used to construct a - * temporary file. + * 0 on success, -1 on failure. * * Side effects: - * None. + * The file is closed and deallocated. * *---------------------------------------------------------------------- */ -static int -TempFileName( - TCHAR name[MAX_PATH]) /* Buffer in which name for temporary file - * gets stored. */ +int +TclpCloseFile( + TclFile file) /* The file to close. */ { - const TCHAR *prefix = TEXT("TCL"); - if (GetTempPath(MAX_PATH, name) != 0) { - if (GetTempFileName(name, prefix, 0, name) != 0) { - return 1; + WinFile *filePtr = (WinFile *) file; + + switch (filePtr->type) { + case WIN_FILE: + /* + * Don't close the Win32 handle if the handle is a standard channel + * during the thread exit process. Otherwise, one thread may kill the + * stdio of another. + */ + + if (!TclInThreadExit() + || ((GetStdHandle(STD_INPUT_HANDLE) != filePtr->handle) + && (GetStdHandle(STD_OUTPUT_HANDLE) != filePtr->handle) + && (GetStdHandle(STD_ERROR_HANDLE) != filePtr->handle))) { + if (filePtr->handle != NULL && + CloseHandle(filePtr->handle) == FALSE) { + TclWinConvertError(GetLastError()); + ckfree(filePtr); + return -1; + } } + break; + + default: + Tcl_Panic("TclpCloseFile: unexpected file type"); } - name[0] = '.'; - name[1] = '\0'; - return GetTempFileName(name, prefix, 0, name); + + ckfree(filePtr); + return 0; } /* - *---------------------------------------------------------------------- + *-------------------------------------------------------------------------- * - * TclpMakeFile -- + * TclpGetPid -- * - * Make a TclFile from a channel. + * Given a HANDLE to a child process, return the process id for that + * child process. * * Results: - * Returns a new TclFile or NULL on failure. + * Returns the process id for the child process. If the pid was not known + * by Tcl, either because the pid was not created by Tcl or the child + * process has already been reaped, -1 is returned. * * Side effects: * None. * - *---------------------------------------------------------------------- + *-------------------------------------------------------------------------- */ -TclFile -TclpMakeFile( - Tcl_Channel channel, /* Channel to get file from. */ - int direction) /* Either TCL_READABLE or TCL_WRITABLE. */ +int +TclpGetPid( + Tcl_Pid pid) /* The HANDLE of the child process. */ { - HANDLE handle; + ProcInfo *infoPtr; - if (Tcl_GetChannelHandle(channel, direction, - (ClientData *) &handle) == TCL_OK) { - return TclWinMakeFile(handle); - } else { - return (TclFile) NULL; + PipeInit(); + + Tcl_MutexLock(&pipeMutex); + for (infoPtr = procList; infoPtr != NULL; infoPtr = infoPtr->nextPtr) { + if (infoPtr->hProcess == (HANDLE) pid) { + Tcl_MutexUnlock(&pipeMutex); + return infoPtr->dwProcessId; + } } + Tcl_MutexUnlock(&pipeMutex); + return (unsigned long) -1; } /* *---------------------------------------------------------------------- * - * TclpOpenFile -- + * TclpCreateProcess -- * - * This function opens files for use in a pipeline. + * Create a child process that has the specified files as its standard + * input, output, and error. The child process runs asynchronously under + * Windows NT and Windows 9x, and runs with the same environment + * variables as the creating process. + * + * The complete Windows search path is searched to find the specified + * executable. If an executable by the given name is not found, + * automatically tries appending standard extensions to the + * executable name. * * Results: - * Returns a newly allocated TclFile structure containing the file - * handle. + * The return value is TCL_ERROR and an error message is left in the + * interp's result if there was a problem creating the child process. + * Otherwise, the return value is TCL_OK and *pidPtr is filled with the + * process id of the child process. * * Side effects: - * None. + * A process is created. * *---------------------------------------------------------------------- */ -TclFile -TclpOpenFile( - const char *path, /* The name of the file to open. */ - int mode) /* In what mode to open the file? */ +int +TclpCreateProcess( + Tcl_Interp *interp, /* Interpreter in which to leave errors that + * occurred when creating the child process. + * Error messages from the child process + * itself are sent to errorFile. */ + int argc, /* Number of arguments in following array. */ + const char **argv, /* Array of argument strings. argv[0] contains + * the name of the executable converted to + * native format (using the + * Tcl_TranslateFileName call). Additional + * arguments have not been converted. */ + TclFile inputFile, /* If non-NULL, gives the file to use as input + * for the child process. If inputFile file is + * not readable or is NULL, the child will + * receive no standard input. */ + TclFile outputFile, /* If non-NULL, gives the file that receives + * output from the child process. If + * outputFile file is not writeable or is + * NULL, output from the child will be + * discarded. */ + TclFile errorFile, /* If non-NULL, gives the file that receives + * errors from the child process. If errorFile + * file is not writeable or is NULL, errors + * from the child will be discarded. errorFile + * may be the same as outputFile. */ + Tcl_Pid *pidPtr) /* If this function is successful, pidPtr is + * filled with the process id of the child + * process. */ { - HANDLE handle; - DWORD accessMode, createMode, shareMode, flags; - Tcl_DString ds; - const TCHAR *nativePath; - - /* - * Map the access bits to the NT access mode. - */ - - switch (mode & (O_RDONLY | O_WRONLY | O_RDWR)) { - case O_RDONLY: - accessMode = GENERIC_READ; - break; - case O_WRONLY: - accessMode = GENERIC_WRITE; - break; - case O_RDWR: - accessMode = (GENERIC_READ | GENERIC_WRITE); - break; - default: - TclWinConvertError(ERROR_INVALID_FUNCTION); - return NULL; - } + int result, applType, createFlags; + Tcl_DString cmdLine; /* Complete command line (TCHAR). */ + STARTUPINFO startInfo; + PROCESS_INFORMATION procInfo; + SECURITY_ATTRIBUTES secAtts; + HANDLE hProcess, h, inputHandle, outputHandle, errorHandle; + char execPath[MAX_PATH * TCL_UTF_MAX]; + WinFile *filePtr; - /* - * Map the creation flags to the NT create mode. - */ + PipeInit(); - switch (mode & (O_CREAT | O_EXCL | O_TRUNC)) { - case (O_CREAT | O_EXCL): - case (O_CREAT | O_EXCL | O_TRUNC): - createMode = CREATE_NEW; - break; - case (O_CREAT | O_TRUNC): - createMode = CREATE_ALWAYS; - break; - case O_CREAT: - createMode = OPEN_ALWAYS; - break; - case O_TRUNC: - case (O_TRUNC | O_EXCL): - createMode = TRUNCATE_EXISTING; - break; - default: - createMode = OPEN_EXISTING; - break; + applType = ApplicationType(interp, argv[0], execPath); + if (applType == APPL_NONE) { + return TCL_ERROR; } - nativePath = Tcl_WinUtfToTChar(path, -1, &ds); + result = TCL_ERROR; + Tcl_DStringInit(&cmdLine); + hProcess = GetCurrentProcess(); /* - * If the file is not being created, use the existing file attributes. + * STARTF_USESTDHANDLES must be used to pass handles to child process. + * Using SetStdHandle() and/or dup2() only works when a console mode + * parent process is spawning an attached console mode child process. */ - flags = 0; - if (!(mode & O_CREAT)) { - flags = GetFileAttributes(nativePath); - if (flags == 0xFFFFFFFF) { - flags = 0; - } - } + ZeroMemory(&startInfo, sizeof(startInfo)); + startInfo.cb = sizeof(startInfo); + startInfo.dwFlags = STARTF_USESTDHANDLES; + startInfo.hStdInput = INVALID_HANDLE_VALUE; + startInfo.hStdOutput= INVALID_HANDLE_VALUE; + startInfo.hStdError = INVALID_HANDLE_VALUE; + + secAtts.nLength = sizeof(SECURITY_ATTRIBUTES); + secAtts.lpSecurityDescriptor = NULL; + secAtts.bInheritHandle = TRUE; /* - * Set up the file sharing mode. We want to allow simultaneous access. + * We have to check the type of each file, since we cannot duplicate some + * file types. */ - shareMode = FILE_SHARE_READ | FILE_SHARE_WRITE; + inputHandle = INVALID_HANDLE_VALUE; + if (inputFile != NULL) { + filePtr = (WinFile *)inputFile; + if (filePtr->type == WIN_FILE) { + inputHandle = filePtr->handle; + } + } + outputHandle = INVALID_HANDLE_VALUE; + if (outputFile != NULL) { + filePtr = (WinFile *)outputFile; + if (filePtr->type == WIN_FILE) { + outputHandle = filePtr->handle; + } + } + errorHandle = INVALID_HANDLE_VALUE; + if (errorFile != NULL) { + filePtr = (WinFile *)errorFile; + if (filePtr->type == WIN_FILE) { + errorHandle = filePtr->handle; + } + } /* - * Now we get to create the file. + * Duplicate all the handles which will be passed off as stdin, stdout and + * stderr of the child process. The duplicate handles are set to be + * inheritable, so the child process can use them. */ - handle = CreateFile(nativePath, accessMode, shareMode, - NULL, createMode, flags, NULL); - Tcl_DStringFree(&ds); - - if (handle == INVALID_HANDLE_VALUE) { - DWORD err; + if (inputHandle == INVALID_HANDLE_VALUE) { + /* + * If handle was not set, stdin should return immediate EOF. Under + * Windows95, some applications (both 16 and 32 bit!) cannot read from + * the NUL device; they read from console instead. When running tk, + * this is fatal because the child process would hang forever waiting + * for EOF from the unmapped console window used by the helper + * application. + * + * Fortunately, the helper application detects a closed pipe as an + * immediate EOF and can pass that information to the child process. + */ - err = GetLastError(); - if ((err & 0xffffL) == ERROR_OPEN_FAILED) { - err = (mode & O_CREAT) ? ERROR_FILE_EXISTS : ERROR_FILE_NOT_FOUND; + if (CreatePipe(&startInfo.hStdInput, &h, &secAtts, 0) != FALSE) { + CloseHandle(h); } - TclWinConvertError(err); - return NULL; + } else { + DuplicateHandle(hProcess, inputHandle, hProcess, &startInfo.hStdInput, + 0, TRUE, DUPLICATE_SAME_ACCESS); + } + if (startInfo.hStdInput == INVALID_HANDLE_VALUE) { + TclWinConvertError(GetLastError()); + Tcl_SetObjResult(interp, Tcl_ObjPrintf( + "couldn't duplicate input handle: %s", + Tcl_PosixError(interp))); + goto end; } - /* - * Seek to the end of file if we are writing. - */ + if (outputHandle == INVALID_HANDLE_VALUE) { + /* + * If handle was not set, output should be sent to an infinitely deep + * sink. Under Windows 95, some 16 bit applications cannot have stdout + * redirected to NUL; they send their output to the console instead. + * Some applications, like "more" or "dir /p", when outputting + * multiple pages to the console, also then try and read from the + * console to go the next page. When running tk, this is fatal because + * the child process would hang forever waiting for input from the + * unmapped console window used by the helper application. + * + * Fortunately, the helper application will detect a closed pipe as a + * sink. + */ - if (mode & (O_WRONLY|O_APPEND)) { - SetFilePointer(handle, 0, NULL, FILE_END); + startInfo.hStdOutput = CreateFile(TEXT("NUL:"), GENERIC_WRITE, 0, + &secAtts, OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL); + } else { + DuplicateHandle(hProcess, outputHandle, hProcess, + &startInfo.hStdOutput, 0, TRUE, DUPLICATE_SAME_ACCESS); + } + if (startInfo.hStdOutput == INVALID_HANDLE_VALUE) { + TclWinConvertError(GetLastError()); + Tcl_SetObjResult(interp, Tcl_ObjPrintf( + "couldn't duplicate output handle: %s", + Tcl_PosixError(interp))); + goto end; } - return TclWinMakeFile(handle); -} - -/* - *---------------------------------------------------------------------- - * - * TclpCreateTempFile -- - * - * This function opens a unique file with the property that it will be - * deleted when its file handle is closed. The temporary file is created - * in the system temporary directory. - * - * Results: - * Returns a valid TclFile, or NULL on failure. - * - * Side effects: - * Creates a new temporary file. - * - *---------------------------------------------------------------------- - */ - -TclFile -TclpCreateTempFile( - const char *contents) /* String to write into temp file, or NULL. */ -{ - TCHAR name[MAX_PATH]; - const char *native; - Tcl_DString dstring; - HANDLE handle; + if (errorHandle == INVALID_HANDLE_VALUE) { + /* + * If handle was not set, errors should be sent to an infinitely deep + * sink. + */ - if (TempFileName(name) == 0) { - return NULL; + startInfo.hStdError = CreateFile(TEXT("NUL:"), GENERIC_WRITE, 0, + &secAtts, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); + } else { + DuplicateHandle(hProcess, errorHandle, hProcess, &startInfo.hStdError, + 0, TRUE, DUPLICATE_SAME_ACCESS); } - - handle = CreateFile(name, - GENERIC_READ | GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, - FILE_ATTRIBUTE_TEMPORARY|FILE_FLAG_DELETE_ON_CLOSE, NULL); - if (handle == INVALID_HANDLE_VALUE) { - goto error; + if (startInfo.hStdError == INVALID_HANDLE_VALUE) { + TclWinConvertError(GetLastError()); + Tcl_SetObjResult(interp, Tcl_ObjPrintf( + "couldn't duplicate error handle: %s", + Tcl_PosixError(interp))); + goto end; } /* - * Write the file out, doing line translations on the way. + * If we do not have a console window, then we must run DOS and WIN32 + * console mode applications as detached processes. This tells the loader + * that the child application should not inherit the console, and that it + * should not create a new console window for the child application. The + * child application should get its stdio from the redirection handles + * provided by this application, and run in the background. + * + * If we are starting a GUI process, they don't automatically get a + * console, so it doesn't matter if they are started as foreground or + * detached processes. The GUI window will still pop up to the foreground. */ - if (contents != NULL) { - DWORD result, length; - const char *p; - int toCopy; - - /* - * Convert the contents from UTF to native encoding - */ - - native = Tcl_UtfToExternalDString(NULL, contents, -1, &dstring); + if (TclWinGetPlatformId() == VER_PLATFORM_WIN32_NT) { + if (HasConsole()) { + createFlags = 0; + } else if (applType == APPL_DOS) { + /* + * Under NT, 16-bit DOS applications will not run unless they can + * be attached to a console. If we are running without a console, + * run the 16-bit program as an normal process inside of a hidden + * console application, and then run that hidden console as a + * detached process. + */ - toCopy = Tcl_DStringLength(&dstring); - for (p = native; toCopy > 0; p++, toCopy--) { - if (*p == '\n') { - length = p - native; - if (length > 0) { - if (!WriteFile(handle, native, length, &result, NULL)) { - goto error; - } - } - if (!WriteFile(handle, "\r\n", 2, &result, NULL)) { - goto error; - } - native = p+1; - } + startInfo.wShowWindow = SW_HIDE; + startInfo.dwFlags |= STARTF_USESHOWWINDOW; + createFlags = CREATE_NEW_CONSOLE; + TclDStringAppendLiteral(&cmdLine, "cmd.exe /c"); + } else { + createFlags = DETACHED_PROCESS; } - length = p - native; - if (length > 0) { - if (!WriteFile(handle, native, length, &result, NULL)) { - goto error; - } + } else { + if (HasConsole()) { + createFlags = 0; + } else { + createFlags = DETACHED_PROCESS; } - Tcl_DStringFree(&dstring); - if (SetFilePointer(handle, 0, NULL, FILE_BEGIN) == 0xFFFFFFFF) { - goto error; + + if (applType == APPL_DOS) { + Tcl_SetObjResult(interp, Tcl_NewStringObj( + "DOS application process not supported on this platform", + -1)); + Tcl_SetErrorCode(interp, "TCL", "OPERATION", "EXEC", "DOS_APP", + NULL); + goto end; } } - return TclWinMakeFile(handle); + /* + * cmdLine gets the full command line used to invoke the executable, + * including the name of the executable itself. The command line arguments + * in argv[] are stored in cmdLine separated by spaces. Special characters + * in individual arguments from argv[] must be quoted when being stored in + * cmdLine. + * + * When calling any application, bear in mind that arguments that specify + * a path name are not converted. If an argument contains forward slashes + * as path separators, it may or may not be recognized as a path name, + * depending on the program. In general, most applications accept forward + * slashes only as option delimiters and backslashes only as paths. + * + * Additionally, when calling a 16-bit dos or windows application, all + * path names must use the short, cryptic, path format (e.g., using + * ab~1.def instead of "a b.default"). + */ + + BuildCommandLine(execPath, argc, argv, &cmdLine); + + if (CreateProcess(NULL, (TCHAR *) Tcl_DStringValue(&cmdLine), + NULL, NULL, TRUE, (DWORD) createFlags, NULL, NULL, &startInfo, + &procInfo) == 0) { + TclWinConvertError(GetLastError()); + Tcl_SetObjResult(interp, Tcl_ObjPrintf("couldn't execute \"%s\": %s", + argv[0], Tcl_PosixError(interp))); + goto end; + } + + /* + * This wait is used to force the OS to give some time to the DOS process. + */ + + if (applType == APPL_DOS) { + WaitForSingleObject(procInfo.hProcess, 50); + } - error: /* - * Free the native representation of the contents if necessary. + * "When an application spawns a process repeatedly, a new thread instance + * will be created for each process but the previous instances may not be + * cleaned up. This results in a significant virtual memory loss each time + * the process is spawned. If there is a WaitForInputIdle() call between + * CreateProcess() and CloseHandle(), the problem does not occur." PSS ID + * Number: Q124121 */ - if (contents != NULL) { - Tcl_DStringFree(&dstring); + WaitForInputIdle(procInfo.hProcess, 5000); + CloseHandle(procInfo.hThread); + + *pidPtr = (Tcl_Pid) procInfo.hProcess; + if (*pidPtr != 0) { + TclWinAddProcess(procInfo.hProcess, procInfo.dwProcessId); } + result = TCL_OK; - TclWinConvertError(GetLastError()); - CloseHandle(handle); - DeleteFile(name); - return NULL; + end: + Tcl_DStringFree(&cmdLine); + if (startInfo.hStdInput != INVALID_HANDLE_VALUE) { + CloseHandle(startInfo.hStdInput); + } + if (startInfo.hStdOutput != INVALID_HANDLE_VALUE) { + CloseHandle(startInfo.hStdOutput); + } + if (startInfo.hStdError != INVALID_HANDLE_VALUE) { + CloseHandle(startInfo.hStdError); + } + return result; } + /* *---------------------------------------------------------------------- * - * TclpTempFileName -- + * HasConsole -- * - * This function returns a unique filename. + * Determines whether the current application is attached to a console. * * Results: - * Returns a valid Tcl_Obj* with refCount 0, or NULL on failure. + * Returns TRUE if this application has a console, else FALSE. * * Side effects: * None. @@ -1060,2322 +1217,2211 @@ TclpCreateTempFile( *---------------------------------------------------------------------- */ -Tcl_Obj * -TclpTempFileName(void) +static BOOL +HasConsole(void) { - TCHAR fileName[MAX_PATH]; + HANDLE handle; - if (TempFileName(fileName) == 0) { - return NULL; - } + handle = CreateFileA("CONOUT$", GENERIC_WRITE, FILE_SHARE_WRITE, + NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); - return TclpNativeToNormalized(fileName); + if (handle != INVALID_HANDLE_VALUE) { + CloseHandle(handle); + return TRUE; + } else { + return FALSE; + } } /* - *---------------------------------------------------------------------- + *-------------------------------------------------------------------- * - * TclpCreatePipe -- + * ApplicationType -- * - * Creates an anonymous pipe. + * Search for the specified program and identify if it refers to a DOS, + * Windows 3.X, or Win32 program. Used to determine how to invoke a + * program, or if it can even be invoked. + * + * It is possible to almost positively identify DOS and Windows + * applications that contain the appropriate magic numbers. However, DOS + * .com files do not seem to contain a magic number; if the program name + * ends with .com and could not be identified as a Windows .com file, it + * will be assumed to be a DOS application, even if it was just random + * data. If the program name does not end with .com, no such assumption + * is made. + * + * The Win32 function GetBinaryType incorrectly identifies any junk file + * that ends with .exe as a dos executable and some executables that + * don't end with .exe as not executable. Plus it doesn't exist under + * win95, so I won't feel bad about reimplementing functionality. * * Results: - * Returns 1 on success, 0 on failure. + * The return value is one of APPL_DOS, APPL_WIN3X, or APPL_WIN32 if the + * filename referred to the corresponding application type. If the file + * name could not be found or did not refer to any known application + * type, APPL_NONE is returned and an error message is left in interp. + * .bat files are identified as APPL_DOS. * * Side effects: - * Creates a pipe. + * None. * *---------------------------------------------------------------------- */ -int -TclpCreatePipe( - TclFile *readPipe, /* Location to store file handle for read side - * of pipe. */ - TclFile *writePipe) /* Location to store file handle for write - * side of pipe. */ +static int +ApplicationType( + Tcl_Interp *interp, /* Interp, for error message. */ + const char *originalName, /* Name of the application to find. */ + char fullName[]) /* Filled with complete path to + * application. */ { - HANDLE readHandle, writeHandle; + int applType, i, nameLen, found; + HANDLE hFile; + TCHAR *rest; + char *ext; + char buf[2]; + DWORD attr, read; + IMAGE_DOS_HEADER header; + Tcl_DString nameBuf, ds; + const TCHAR *nativeName; + TCHAR nativeFullPath[MAX_PATH]; + static const char extensions[][5] = {"", ".com", ".exe", ".bat", ".cmd"}; - if (CreatePipe(&readHandle, &writeHandle, NULL, 0) != 0) { - *readPipe = TclWinMakeFile(readHandle); - *writePipe = TclWinMakeFile(writeHandle); - return 1; + /* + * Look for the program as an external program. First try the name as it + * is, then try adding .com, .exe, and .bat, in that order, to the name, + * looking for an executable. + * + * Using the raw SearchPath() function doesn't do quite what is necessary. + * If the name of the executable already contains a '.' character, it will + * not try appending the specified extension when searching (in other + * words, SearchPath will not find the program "a.b.exe" if the arguments + * specified "a.b" and ".exe"). So, first look for the file as it is + * named. Then manually append the extensions, looking for a match. + */ + + applType = APPL_NONE; + Tcl_DStringInit(&nameBuf); + Tcl_DStringAppend(&nameBuf, originalName, -1); + nameLen = Tcl_DStringLength(&nameBuf); + + for (i = 0; i < (int) (sizeof(extensions) / sizeof(extensions[0])); i++) { + Tcl_DStringSetLength(&nameBuf, nameLen); + Tcl_DStringAppend(&nameBuf, extensions[i], -1); + nativeName = Tcl_WinUtfToTChar(Tcl_DStringValue(&nameBuf), + Tcl_DStringLength(&nameBuf), &ds); + found = SearchPath(NULL, nativeName, NULL, MAX_PATH, + nativeFullPath, &rest); + Tcl_DStringFree(&ds); + if (found == 0) { + continue; + } + + /* + * Ignore matches on directories or data files, return if identified a + * known type. + */ + + attr = GetFileAttributes(nativeFullPath); + if ((attr == 0xffffffff) || (attr & FILE_ATTRIBUTE_DIRECTORY)) { + continue; + } + strcpy(fullName, Tcl_WinTCharToUtf(nativeFullPath, -1, &ds)); + Tcl_DStringFree(&ds); + + ext = strrchr(fullName, '.'); + if ((ext != NULL) && + (strcasecmp(ext, ".cmd") == 0 || strcasecmp(ext, ".bat") == 0)) { + applType = APPL_DOS; + break; + } + + hFile = CreateFile(nativeFullPath, + GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, + FILE_ATTRIBUTE_NORMAL, NULL); + if (hFile == INVALID_HANDLE_VALUE) { + continue; + } + + header.e_magic = 0; + ReadFile(hFile, (void *) &header, sizeof(header), &read, NULL); + if (header.e_magic != IMAGE_DOS_SIGNATURE) { + /* + * Doesn't have the magic number for relocatable executables. If + * filename ends with .com, assume it's a DOS application anyhow. + * Note that we didn't make this assumption at first, because some + * supposed .com files are really 32-bit executables with all the + * magic numbers and everything. + */ + + CloseHandle(hFile); + if ((ext != NULL) && (strcasecmp(ext, ".com") == 0)) { + applType = APPL_DOS; + break; + } + continue; + } + if (header.e_lfarlc != sizeof(header)) { + /* + * All Windows 3.X and Win32 and some DOS programs have this value + * set here. If it doesn't, assume that since it already had the + * other magic number it was a DOS application. + */ + + CloseHandle(hFile); + applType = APPL_DOS; + break; + } + + /* + * The DWORD at header.e_lfanew points to yet another magic number. + */ + + buf[0] = '\0'; + SetFilePointer(hFile, header.e_lfanew, NULL, FILE_BEGIN); + ReadFile(hFile, (void *) buf, 2, &read, NULL); + CloseHandle(hFile); + + if ((buf[0] == 'N') && (buf[1] == 'E')) { + applType = APPL_WIN3X; + } else if ((buf[0] == 'P') && (buf[1] == 'E')) { + applType = APPL_WIN32; + } else { + /* + * Strictly speaking, there should be a test that there is an 'L' + * and 'E' at buf[0..1], to identify the type as DOS, but of + * course we ran into a DOS executable that _doesn't_ have the + * magic number - specifically, one compiled using the Lahey + * Fortran90 compiler. + */ + + applType = APPL_DOS; + } + break; } + Tcl_DStringFree(&nameBuf); - TclWinConvertError(GetLastError()); - return 0; + if (applType == APPL_NONE) { + TclWinConvertError(GetLastError()); + Tcl_SetObjResult(interp, Tcl_ObjPrintf("couldn't execute \"%s\": %s", + originalName, Tcl_PosixError(interp))); + return APPL_NONE; + } + + if ((applType == APPL_DOS) || (applType == APPL_WIN3X)) { + /* + * Replace long path name of executable with short path name for + * 16-bit applications. Otherwise the application may not be able to + * correctly parse its own command line to separate off the + * application name from the arguments. + */ + + GetShortPathName(nativeFullPath, nativeFullPath, MAX_PATH); + strcpy(fullName, Tcl_WinTCharToUtf(nativeFullPath, -1, &ds)); + Tcl_DStringFree(&ds); + } + return applType; } /* *---------------------------------------------------------------------- * - * TclpCloseFile -- + * BuildCommandLine -- * - * Closes a pipeline file handle. These handles are created by - * TclpOpenFile, TclpCreatePipe, or TclpMakeFile. + * The command line arguments are stored in linePtr separated by spaces, + * in a form that CreateProcess() understands. Special characters in + * individual arguments from argv[] must be quoted when being stored in + * cmdLine. * * Results: - * 0 on success, -1 on failure. + * None. * * Side effects: - * The file is closed and deallocated. + * None. * *---------------------------------------------------------------------- */ -int -TclpCloseFile( - TclFile file) /* The file to close. */ +static void +BuildCommandLine( + const char *executable, /* Full path of executable (including + * extension). Replacement for argv[0]. */ + int argc, /* Number of arguments. */ + const char **argv, /* Argument strings in UTF. */ + Tcl_DString *linePtr) /* Initialized Tcl_DString that receives the + * command line (TCHAR). */ { - WinFile *filePtr = (WinFile *) file; + const char *arg, *start, *special; + int quote, i; + Tcl_DString ds; - switch (filePtr->type) { - case WIN_FILE: - /* - * Don't close the Win32 handle if the handle is a standard channel - * during the thread exit process. Otherwise, one thread may kill the - * stdio of another. - */ + Tcl_DStringInit(&ds); - if (!TclInThreadExit() - || ((GetStdHandle(STD_INPUT_HANDLE) != filePtr->handle) - && (GetStdHandle(STD_OUTPUT_HANDLE) != filePtr->handle) - && (GetStdHandle(STD_ERROR_HANDLE) != filePtr->handle))) { - if (filePtr->handle != NULL && - CloseHandle(filePtr->handle) == FALSE) { - TclWinConvertError(GetLastError()); - ckfree(filePtr); - return -1; - } - } - break; + /* + * Prime the path. Add a space separator if we were primed with something. + */ - default: - Tcl_Panic("TclpCloseFile: unexpected file type"); + TclDStringAppendDString(&ds, linePtr); + if (Tcl_DStringLength(linePtr) > 0) { + TclDStringAppendLiteral(&ds, " "); } - ckfree(filePtr); - return 0; -} - -/* - *-------------------------------------------------------------------------- - * - * TclpGetPid -- - * - * Given a HANDLE to a child process, return the process id for that - * child process. - * - * Results: - * Returns the process id for the child process. If the pid was not known - * by Tcl, either because the pid was not created by Tcl or the child - * process has already been reaped, -1 is returned. - * - * Side effects: - * None. - * - *-------------------------------------------------------------------------- - */ + for (i = 0; i < argc; i++) { + if (i == 0) { + arg = executable; + } else { + arg = argv[i]; + TclDStringAppendLiteral(&ds, " "); + } -int -TclpGetPid( - Tcl_Pid pid) /* The HANDLE of the child process. */ -{ - ProcInfo *infoPtr; + quote = 0; + if (arg[0] == '\0') { + quote = 1; + } else { + int count; + Tcl_UniChar ch; - PipeInit(); + for (start = arg; *start != '\0'; start += count) { + count = Tcl_UtfToUniChar(start, &ch); + if (Tcl_UniCharIsSpace(ch)) { /* INTL: ISO space. */ + quote = 1; + break; + } + } + } + if (quote) { + TclDStringAppendLiteral(&ds, "\""); + } + start = arg; + for (special = arg; ; ) { + if ((*special == '\\') && (special[1] == '\\' || + special[1] == '"' || (quote && special[1] == '\0'))) { + Tcl_DStringAppend(&ds, start, (int) (special - start)); + start = special; + while (1) { + special++; + if (*special == '"' || (quote && *special == '\0')) { + /* + * N backslashes followed a quote -> insert N * 2 + 1 + * backslashes then a quote. + */ - Tcl_MutexLock(&pipeMutex); - for (infoPtr = procList; infoPtr != NULL; infoPtr = infoPtr->nextPtr) { - if (infoPtr->hProcess == (HANDLE) pid) { - Tcl_MutexUnlock(&pipeMutex); - return infoPtr->dwProcessId; + Tcl_DStringAppend(&ds, start, + (int) (special - start)); + break; + } + if (*special != '\\') { + break; + } + } + Tcl_DStringAppend(&ds, start, (int) (special - start)); + start = special; + } + if (*special == '"') { + Tcl_DStringAppend(&ds, start, (int) (special - start)); + TclDStringAppendLiteral(&ds, "\\\""); + start = special + 1; + } + if (*special == '\0') { + break; + } + special++; + } + Tcl_DStringAppend(&ds, start, (int) (special - start)); + if (quote) { + TclDStringAppendLiteral(&ds, "\""); } } - Tcl_MutexUnlock(&pipeMutex); - return (unsigned long) -1; + Tcl_DStringFree(linePtr); + Tcl_WinUtfToTChar(Tcl_DStringValue(&ds), Tcl_DStringLength(&ds), linePtr); + Tcl_DStringFree(&ds); } /* *---------------------------------------------------------------------- * - * TclpCreateProcess -- - * - * Create a child process that has the specified files as its standard - * input, output, and error. The child process runs asynchronously under - * Windows NT and Windows 9x, and runs with the same environment - * variables as the creating process. + * TclpCreateCommandChannel -- * - * The complete Windows search path is searched to find the specified - * executable. If an executable by the given name is not found, - * automatically tries appending standard extensions to the - * executable name. + * This function is called by Tcl_OpenCommandChannel to perform the + * platform specific channel initialization for a command channel. * * Results: - * The return value is TCL_ERROR and an error message is left in the - * interp's result if there was a problem creating the child process. - * Otherwise, the return value is TCL_OK and *pidPtr is filled with the - * process id of the child process. + * Returns a new channel or NULL on failure. * * Side effects: - * A process is created. + * Allocates a new channel. * *---------------------------------------------------------------------- */ -int -TclpCreateProcess( - Tcl_Interp *interp, /* Interpreter in which to leave errors that - * occurred when creating the child process. - * Error messages from the child process - * itself are sent to errorFile. */ - int argc, /* Number of arguments in following array. */ - const char **argv, /* Array of argument strings. argv[0] contains - * the name of the executable converted to - * native format (using the - * Tcl_TranslateFileName call). Additional - * arguments have not been converted. */ - TclFile inputFile, /* If non-NULL, gives the file to use as input - * for the child process. If inputFile file is - * not readable or is NULL, the child will - * receive no standard input. */ - TclFile outputFile, /* If non-NULL, gives the file that receives - * output from the child process. If - * outputFile file is not writeable or is - * NULL, output from the child will be - * discarded. */ - TclFile errorFile, /* If non-NULL, gives the file that receives - * errors from the child process. If errorFile - * file is not writeable or is NULL, errors - * from the child will be discarded. errorFile - * may be the same as outputFile. */ - Tcl_Pid *pidPtr) /* If this function is successful, pidPtr is - * filled with the process id of the child - * process. */ +Tcl_Channel +TclpCreateCommandChannel( + TclFile readFile, /* If non-null, gives the file for reading. */ + TclFile writeFile, /* If non-null, gives the file for writing. */ + TclFile errorFile, /* If non-null, gives the file where errors + * can be read. */ + int numPids, /* The number of pids in the pid array. */ + Tcl_Pid *pidPtr) /* An array of process identifiers. */ { - int result, applType, createFlags; - Tcl_DString cmdLine; /* Complete command line (TCHAR). */ - STARTUPINFO startInfo; - PROCESS_INFORMATION procInfo; - SECURITY_ATTRIBUTES secAtts; - HANDLE hProcess, h, inputHandle, outputHandle, errorHandle; - char execPath[MAX_PATH * TCL_UTF_MAX]; - WinFile *filePtr; - - PipeInit(); - - applType = ApplicationType(interp, argv[0], execPath); - if (applType == APPL_NONE) { - return TCL_ERROR; - } - - result = TCL_ERROR; - Tcl_DStringInit(&cmdLine); - hProcess = GetCurrentProcess(); - - /* - * STARTF_USESTDHANDLES must be used to pass handles to child process. - * Using SetStdHandle() and/or dup2() only works when a console mode - * parent process is spawning an attached console mode child process. - */ - - ZeroMemory(&startInfo, sizeof(startInfo)); - startInfo.cb = sizeof(startInfo); - startInfo.dwFlags = STARTF_USESTDHANDLES; - startInfo.hStdInput = INVALID_HANDLE_VALUE; - startInfo.hStdOutput= INVALID_HANDLE_VALUE; - startInfo.hStdError = INVALID_HANDLE_VALUE; - - secAtts.nLength = sizeof(SECURITY_ATTRIBUTES); - secAtts.lpSecurityDescriptor = NULL; - secAtts.bInheritHandle = TRUE; - - /* - * We have to check the type of each file, since we cannot duplicate some - * file types. - */ + char channelName[16 + TCL_INTEGER_SPACE]; + DWORD id; + PipeInfo *infoPtr = ckalloc(sizeof(PipeInfo)); - inputHandle = INVALID_HANDLE_VALUE; - if (inputFile != NULL) { - filePtr = (WinFile *)inputFile; - if (filePtr->type == WIN_FILE) { - inputHandle = filePtr->handle; - } - } - outputHandle = INVALID_HANDLE_VALUE; - if (outputFile != NULL) { - filePtr = (WinFile *)outputFile; - if (filePtr->type == WIN_FILE) { - outputHandle = filePtr->handle; - } - } - errorHandle = INVALID_HANDLE_VALUE; - if (errorFile != NULL) { - filePtr = (WinFile *)errorFile; - if (filePtr->type == WIN_FILE) { - errorHandle = filePtr->handle; - } - } + PipeInit(); - /* - * Duplicate all the handles which will be passed off as stdin, stdout and - * stderr of the child process. The duplicate handles are set to be - * inheritable, so the child process can use them. - */ + infoPtr->watchMask = 0; + infoPtr->flags = 0; + infoPtr->readFlags = 0; + infoPtr->readFile = readFile; + infoPtr->writeFile = writeFile; + infoPtr->errorFile = errorFile; + infoPtr->numPids = numPids; + infoPtr->pidPtr = pidPtr; + infoPtr->writeBuf = 0; + infoPtr->writeBufLen = 0; + infoPtr->writeError = 0; + infoPtr->channel = NULL; - if (inputHandle == INVALID_HANDLE_VALUE) { - /* - * If handle was not set, stdin should return immediate EOF. Under - * Windows95, some applications (both 16 and 32 bit!) cannot read from - * the NUL device; they read from console instead. When running tk, - * this is fatal because the child process would hang forever waiting - * for EOF from the unmapped console window used by the helper - * application. - * - * Fortunately, the helper application detects a closed pipe as an - * immediate EOF and can pass that information to the child process. - */ + infoPtr->validMask = 0; - if (CreatePipe(&startInfo.hStdInput, &h, &secAtts, 0) != FALSE) { - CloseHandle(h); - } - } else { - DuplicateHandle(hProcess, inputHandle, hProcess, &startInfo.hStdInput, - 0, TRUE, DUPLICATE_SAME_ACCESS); - } - if (startInfo.hStdInput == INVALID_HANDLE_VALUE) { - TclWinConvertError(GetLastError()); - Tcl_SetObjResult(interp, Tcl_ObjPrintf( - "couldn't duplicate input handle: %s", - Tcl_PosixError(interp))); - goto end; - } + infoPtr->threadId = Tcl_GetCurrentThread(); - if (outputHandle == INVALID_HANDLE_VALUE) { + if (readFile != NULL) { /* - * If handle was not set, output should be sent to an infinitely deep - * sink. Under Windows 95, some 16 bit applications cannot have stdout - * redirected to NUL; they send their output to the console instead. - * Some applications, like "more" or "dir /p", when outputting - * multiple pages to the console, also then try and read from the - * console to go the next page. When running tk, this is fatal because - * the child process would hang forever waiting for input from the - * unmapped console window used by the helper application. - * - * Fortunately, the helper application will detect a closed pipe as a - * sink. + * Start the background reader thread. */ - startInfo.hStdOutput = CreateFile(TEXT("NUL:"), GENERIC_WRITE, 0, - &secAtts, OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL); + infoPtr->readable = CreateEvent(NULL, TRUE, TRUE, NULL); + infoPtr->readThread = CreateThread(NULL, 256, PipeReaderThread, + TclPipeThreadCreateTI(&infoPtr->readTI, infoPtr), 0, &id); + SetThreadPriority(infoPtr->readThread, THREAD_PRIORITY_HIGHEST); + infoPtr->validMask |= TCL_READABLE; } else { - DuplicateHandle(hProcess, outputHandle, hProcess, - &startInfo.hStdOutput, 0, TRUE, DUPLICATE_SAME_ACCESS); - } - if (startInfo.hStdOutput == INVALID_HANDLE_VALUE) { - TclWinConvertError(GetLastError()); - Tcl_SetObjResult(interp, Tcl_ObjPrintf( - "couldn't duplicate output handle: %s", - Tcl_PosixError(interp))); - goto end; + infoPtr->readTI = NULL; + infoPtr->readThread = 0; } - - if (errorHandle == INVALID_HANDLE_VALUE) { + if (writeFile != NULL) { /* - * If handle was not set, errors should be sent to an infinitely deep - * sink. + * Start the background writer thread. */ - startInfo.hStdError = CreateFile(TEXT("NUL:"), GENERIC_WRITE, 0, - &secAtts, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); + infoPtr->writable = CreateEvent(NULL, TRUE, TRUE, NULL); + infoPtr->writeThread = CreateThread(NULL, 256, PipeWriterThread, + TclPipeThreadCreateTI(&infoPtr->writeTI, infoPtr), 0, &id); + SetThreadPriority(infoPtr->writeThread, THREAD_PRIORITY_HIGHEST); + infoPtr->validMask |= TCL_WRITABLE; } else { - DuplicateHandle(hProcess, errorHandle, hProcess, &startInfo.hStdError, - 0, TRUE, DUPLICATE_SAME_ACCESS); - } - if (startInfo.hStdError == INVALID_HANDLE_VALUE) { - TclWinConvertError(GetLastError()); - Tcl_SetObjResult(interp, Tcl_ObjPrintf( - "couldn't duplicate error handle: %s", - Tcl_PosixError(interp))); - goto end; + infoPtr->writeTI = NULL; + infoPtr->writeThread = 0; } /* - * If we do not have a console window, then we must run DOS and WIN32 - * console mode applications as detached processes. This tells the loader - * that the child application should not inherit the console, and that it - * should not create a new console window for the child application. The - * child application should get its stdio from the redirection handles - * provided by this application, and run in the background. - * - * If we are starting a GUI process, they don't automatically get a - * console, so it doesn't matter if they are started as foreground or - * detached processes. The GUI window will still pop up to the foreground. + * For backward compatibility with previous versions of Tcl, we use + * "file%d" as the base name for pipes even though it would be more + * natural to use "pipe%d". Use the pointer to keep the channel names + * unique, in case channels share handles (stdin/stdout). */ - if (TclWinGetPlatformId() == VER_PLATFORM_WIN32_NT) { - if (HasConsole()) { - createFlags = 0; - } else if (applType == APPL_DOS) { - /* - * Under NT, 16-bit DOS applications will not run unless they can - * be attached to a console. If we are running without a console, - * run the 16-bit program as an normal process inside of a hidden - * console application, and then run that hidden console as a - * detached process. - */ - - startInfo.wShowWindow = SW_HIDE; - startInfo.dwFlags |= STARTF_USESHOWWINDOW; - createFlags = CREATE_NEW_CONSOLE; - TclDStringAppendLiteral(&cmdLine, "cmd.exe /c"); - } else { - createFlags = DETACHED_PROCESS; - } - } else { - if (HasConsole()) { - createFlags = 0; - } else { - createFlags = DETACHED_PROCESS; - } - - if (applType == APPL_DOS) { - Tcl_SetObjResult(interp, Tcl_NewStringObj( - "DOS application process not supported on this platform", - -1)); - Tcl_SetErrorCode(interp, "TCL", "OPERATION", "EXEC", "DOS_APP", - NULL); - goto end; - } - } + sprintf(channelName, "file%" TCL_I_MODIFIER "x", (size_t) infoPtr); + infoPtr->channel = Tcl_CreateChannel(&pipeChannelType, channelName, + infoPtr, infoPtr->validMask); /* - * cmdLine gets the full command line used to invoke the executable, - * including the name of the executable itself. The command line arguments - * in argv[] are stored in cmdLine separated by spaces. Special characters - * in individual arguments from argv[] must be quoted when being stored in - * cmdLine. - * - * When calling any application, bear in mind that arguments that specify - * a path name are not converted. If an argument contains forward slashes - * as path separators, it may or may not be recognized as a path name, - * depending on the program. In general, most applications accept forward - * slashes only as option delimiters and backslashes only as paths. - * - * Additionally, when calling a 16-bit dos or windows application, all - * path names must use the short, cryptic, path format (e.g., using - * ab~1.def instead of "a b.default"). + * Pipes have AUTO translation mode on Windows and ^Z eof char, which + * means that a ^Z will be appended to them at close. This is needed for + * Windows programs that expect a ^Z at EOF. */ - BuildCommandLine(execPath, argc, argv, &cmdLine); + Tcl_SetChannelOption(NULL, infoPtr->channel, "-translation", "auto"); + Tcl_SetChannelOption(NULL, infoPtr->channel, "-eofchar", "\032 {}"); + return infoPtr->channel; +} + +/* + *---------------------------------------------------------------------- + * + * Tcl_CreatePipe -- + * + * System dependent interface to create a pipe for the [chan pipe] + * command. Stolen from TclX. + * + * Results: + * TCL_OK or TCL_ERROR. + * + *---------------------------------------------------------------------- + */ - if (CreateProcess(NULL, (TCHAR *) Tcl_DStringValue(&cmdLine), - NULL, NULL, TRUE, (DWORD) createFlags, NULL, NULL, &startInfo, - &procInfo) == 0) { +int +Tcl_CreatePipe( + Tcl_Interp *interp, /* Errors returned in result.*/ + Tcl_Channel *rchan, /* Where to return the read side. */ + Tcl_Channel *wchan, /* Where to return the write side. */ + int flags) /* Reserved for future use. */ +{ + HANDLE readHandle, writeHandle; + SECURITY_ATTRIBUTES sec; + + sec.nLength = sizeof(SECURITY_ATTRIBUTES); + sec.lpSecurityDescriptor = NULL; + sec.bInheritHandle = FALSE; + + if (!CreatePipe(&readHandle, &writeHandle, &sec, 0)) { TclWinConvertError(GetLastError()); - Tcl_SetObjResult(interp, Tcl_ObjPrintf("couldn't execute \"%s\": %s", - argv[0], Tcl_PosixError(interp))); - goto end; + Tcl_SetObjResult(interp, Tcl_ObjPrintf( + "pipe creation failed: %s", Tcl_PosixError(interp))); + return TCL_ERROR; } - /* - * This wait is used to force the OS to give some time to the DOS process. - */ + *rchan = Tcl_MakeFileChannel((ClientData) readHandle, TCL_READABLE); + Tcl_RegisterChannel(interp, *rchan); + + *wchan = Tcl_MakeFileChannel((ClientData) writeHandle, TCL_WRITABLE); + Tcl_RegisterChannel(interp, *wchan); + + return TCL_OK; +} + +/* + *---------------------------------------------------------------------- + * + * TclGetAndDetachPids -- + * + * Stores a list of the command PIDs for a command channel in the + * interp's result. + * + * Results: + * None. + * + * Side effects: + * Modifies the interp's result. + * + *---------------------------------------------------------------------- + */ - if (applType == APPL_DOS) { - WaitForSingleObject(procInfo.hProcess, 50); - } +void +TclGetAndDetachPids( + Tcl_Interp *interp, + Tcl_Channel chan) +{ + PipeInfo *pipePtr; + const Tcl_ChannelType *chanTypePtr; + Tcl_Obj *pidsObj; + int i; /* - * "When an application spawns a process repeatedly, a new thread instance - * will be created for each process but the previous instances may not be - * cleaned up. This results in a significant virtual memory loss each time - * the process is spawned. If there is a WaitForInputIdle() call between - * CreateProcess() and CloseHandle(), the problem does not occur." PSS ID - * Number: Q124121 + * Punt if the channel is not a command channel. */ - WaitForInputIdle(procInfo.hProcess, 5000); - CloseHandle(procInfo.hThread); - - *pidPtr = (Tcl_Pid) procInfo.hProcess; - if (*pidPtr != 0) { - TclWinAddProcess(procInfo.hProcess, procInfo.dwProcessId); + chanTypePtr = Tcl_GetChannelType(chan); + if (chanTypePtr != &pipeChannelType) { + return; } - result = TCL_OK; - end: - Tcl_DStringFree(&cmdLine); - if (startInfo.hStdInput != INVALID_HANDLE_VALUE) { - CloseHandle(startInfo.hStdInput); - } - if (startInfo.hStdOutput != INVALID_HANDLE_VALUE) { - CloseHandle(startInfo.hStdOutput); + pipePtr = Tcl_GetChannelInstanceData(chan); + TclNewObj(pidsObj); + for (i = 0; i < pipePtr->numPids; i++) { + Tcl_ListObjAppendElement(NULL, pidsObj, + Tcl_NewWideIntObj((unsigned) + TclpGetPid(pipePtr->pidPtr[i]))); + Tcl_DetachPids(1, &pipePtr->pidPtr[i]); } - if (startInfo.hStdError != INVALID_HANDLE_VALUE) { - CloseHandle(startInfo.hStdError); + Tcl_SetObjResult(interp, pidsObj); + if (pipePtr->numPids > 0) { + ckfree(pipePtr->pidPtr); + pipePtr->numPids = 0; } - return result; } - /* *---------------------------------------------------------------------- * - * HasConsole -- + * PipeBlockModeProc -- * - * Determines whether the current application is attached to a console. + * Set blocking or non-blocking mode on channel. * * Results: - * Returns TRUE if this application has a console, else FALSE. + * 0 if successful, errno when failed. * * Side effects: - * None. + * Sets the device into blocking or non-blocking mode. * *---------------------------------------------------------------------- */ -static BOOL -HasConsole(void) +static int +PipeBlockModeProc( + ClientData instanceData, /* Instance data for channel. */ + int mode) /* TCL_MODE_BLOCKING or + * TCL_MODE_NONBLOCKING. */ { - HANDLE handle; + PipeInfo *infoPtr = (PipeInfo *) instanceData; - handle = CreateFileA("CONOUT$", GENERIC_WRITE, FILE_SHARE_WRITE, - NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); + /* + * Pipes on Windows can not be switched between blocking and nonblocking, + * hence we have to emulate the behavior. This is done in the input + * function by checking against a bit in the state. We set or unset the + * bit here to cause the input function to emulate the correct behavior. + */ - if (handle != INVALID_HANDLE_VALUE) { - CloseHandle(handle); - return TRUE; + if (mode == TCL_MODE_NONBLOCKING) { + infoPtr->flags |= PIPE_ASYNC; } else { - return FALSE; + infoPtr->flags &= ~(PIPE_ASYNC); } + return 0; } /* - *-------------------------------------------------------------------- - * - * ApplicationType -- - * - * Search for the specified program and identify if it refers to a DOS, - * Windows 3.X, or Win32 program. Used to determine how to invoke a - * program, or if it can even be invoked. + *---------------------------------------------------------------------- * - * It is possible to almost positively identify DOS and Windows - * applications that contain the appropriate magic numbers. However, DOS - * .com files do not seem to contain a magic number; if the program name - * ends with .com and could not be identified as a Windows .com file, it - * will be assumed to be a DOS application, even if it was just random - * data. If the program name does not end with .com, no such assumption - * is made. + * PipeClose2Proc -- * - * The Win32 function GetBinaryType incorrectly identifies any junk file - * that ends with .exe as a dos executable and some executables that - * don't end with .exe as not executable. Plus it doesn't exist under - * win95, so I won't feel bad about reimplementing functionality. + * Closes a pipe based IO channel. * * Results: - * The return value is one of APPL_DOS, APPL_WIN3X, or APPL_WIN32 if the - * filename referred to the corresponding application type. If the file - * name could not be found or did not refer to any known application - * type, APPL_NONE is returned and an error message is left in interp. - * .bat files are identified as APPL_DOS. + * 0 on success, errno otherwise. * * Side effects: - * None. + * Closes the physical channel. * *---------------------------------------------------------------------- */ static int -ApplicationType( - Tcl_Interp *interp, /* Interp, for error message. */ - const char *originalName, /* Name of the application to find. */ - char fullName[]) /* Filled with complete path to - * application. */ +PipeClose2Proc( + ClientData instanceData, /* Pointer to PipeInfo structure. */ + Tcl_Interp *interp, /* For error reporting. */ + int flags) /* Flags that indicate which side to close. */ { - int applType, i, nameLen, found; - HANDLE hFile; - TCHAR *rest; - char *ext; - char buf[2]; - DWORD attr, read; - IMAGE_DOS_HEADER header; - Tcl_DString nameBuf, ds; - const TCHAR *nativeName; - TCHAR nativeFullPath[MAX_PATH]; - static const char extensions[][5] = {"", ".com", ".exe", ".bat", ".cmd"}; - - /* - * Look for the program as an external program. First try the name as it - * is, then try adding .com, .exe, and .bat, in that order, to the name, - * looking for an executable. - * - * Using the raw SearchPath() function doesn't do quite what is necessary. - * If the name of the executable already contains a '.' character, it will - * not try appending the specified extension when searching (in other - * words, SearchPath will not find the program "a.b.exe" if the arguments - * specified "a.b" and ".exe"). So, first look for the file as it is - * named. Then manually append the extensions, looking for a match. - */ - - applType = APPL_NONE; - Tcl_DStringInit(&nameBuf); - Tcl_DStringAppend(&nameBuf, originalName, -1); - nameLen = Tcl_DStringLength(&nameBuf); + PipeInfo *pipePtr = (PipeInfo *) instanceData; + Tcl_Channel errChan; + int errorCode, result; + PipeInfo *infoPtr, **nextPtrPtr; + ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&dataKey); - for (i = 0; i < (int) (sizeof(extensions) / sizeof(extensions[0])); i++) { - Tcl_DStringSetLength(&nameBuf, nameLen); - Tcl_DStringAppend(&nameBuf, extensions[i], -1); - nativeName = Tcl_WinUtfToTChar(Tcl_DStringValue(&nameBuf), - Tcl_DStringLength(&nameBuf), &ds); - found = SearchPath(NULL, nativeName, NULL, MAX_PATH, - nativeFullPath, &rest); - Tcl_DStringFree(&ds); - if (found == 0) { - continue; - } + errorCode = 0; + result = 0; + if ((!flags || flags == TCL_CLOSE_READ) && (pipePtr->readFile != NULL)) { /* - * Ignore matches on directories or data files, return if identified a - * known type. + * Clean up the background thread if necessary. Note that this must be + * done before we can close the file, since the thread may be blocking + * trying to read from the pipe. */ - attr = GetFileAttributes(nativeFullPath); - if ((attr == 0xffffffff) || (attr & FILE_ATTRIBUTE_DIRECTORY)) { - continue; - } - strcpy(fullName, Tcl_WinTCharToUtf(nativeFullPath, -1, &ds)); - Tcl_DStringFree(&ds); + if (pipePtr->readThread) { - ext = strrchr(fullName, '.'); - if ((ext != NULL) && - (strcasecmp(ext, ".cmd") == 0 || strcasecmp(ext, ".bat") == 0)) { - applType = APPL_DOS; - break; + TclPipeThreadStop(&pipePtr->readTI, pipePtr->readThread); + CloseHandle(pipePtr->readThread); + CloseHandle(pipePtr->readable); + pipePtr->readThread = NULL; } - - hFile = CreateFile(nativeFullPath, - GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, - FILE_ATTRIBUTE_NORMAL, NULL); - if (hFile == INVALID_HANDLE_VALUE) { - continue; + if (TclpCloseFile(pipePtr->readFile) != 0) { + errorCode = errno; } + pipePtr->validMask &= ~TCL_READABLE; + pipePtr->readFile = NULL; + } + if ((!flags || flags & TCL_CLOSE_WRITE) + && (pipePtr->writeFile != NULL)) { + if (pipePtr->writeThread) { - header.e_magic = 0; - ReadFile(hFile, (void *) &header, sizeof(header), &read, NULL); - if (header.e_magic != IMAGE_DOS_SIGNATURE) { /* - * Doesn't have the magic number for relocatable executables. If - * filename ends with .com, assume it's a DOS application anyhow. - * Note that we didn't make this assumption at first, because some - * supposed .com files are really 32-bit executables with all the - * magic numbers and everything. + * Wait for the writer thread to finish the current buffer, then + * terminate the thread and close the handles. If the channel is + * nonblocking or may block during exit, bail out since the worker + * thread is not interruptible and we want TIP#398-fast-exit. */ + if ((pipePtr->flags & PIPE_ASYNC) && TclInExit()) { + + /* give it a chance to leave honorably */ + TclPipeThreadStopSignal(&pipePtr->writeTI); + + if (WaitForSingleObject(pipePtr->writable, 20) == WAIT_TIMEOUT) { + return EWOULDBLOCK; + } + + } else { + + WaitForSingleObject(pipePtr->writable, INFINITE); + + } + + TclPipeThreadStop(&pipePtr->writeTI, pipePtr->writeThread); + + CloseHandle(pipePtr->writable); + CloseHandle(pipePtr->writeThread); + pipePtr->writeThread = NULL; + } + if (TclpCloseFile(pipePtr->writeFile) != 0) { + if (errorCode == 0) { + errorCode = errno; + } + } + pipePtr->validMask &= ~TCL_WRITABLE; + pipePtr->writeFile = NULL; + } + + pipePtr->watchMask &= pipePtr->validMask; + + /* + * Don't free the channel if any of the flags were set. + */ + + if (flags) { + return errorCode; + } - CloseHandle(hFile); - if ((ext != NULL) && (strcasecmp(ext, ".com") == 0)) { - applType = APPL_DOS; - break; - } - continue; - } - if (header.e_lfarlc != sizeof(header)) { - /* - * All Windows 3.X and Win32 and some DOS programs have this value - * set here. If it doesn't, assume that since it already had the - * other magic number it was a DOS application. - */ + /* + * Remove the file from the list of watched files. + */ - CloseHandle(hFile); - applType = APPL_DOS; + for (nextPtrPtr = &(tsdPtr->firstPipePtr), infoPtr = *nextPtrPtr; + infoPtr != NULL; + nextPtrPtr = &infoPtr->nextPtr, infoPtr = *nextPtrPtr) { + if (infoPtr == (PipeInfo *)pipePtr) { + *nextPtrPtr = infoPtr->nextPtr; break; } + } + if ((pipePtr->flags & PIPE_ASYNC) || TclInExit()) { /* - * The DWORD at header.e_lfanew points to yet another magic number. + * If the channel is non-blocking or Tcl is being cleaned up, just + * detach the children PIDs, reap them (important if we are in a + * dynamic load module), and discard the errorFile. */ - buf[0] = '\0'; - SetFilePointer(hFile, header.e_lfanew, NULL, FILE_BEGIN); - ReadFile(hFile, (void *) buf, 2, &read, NULL); - CloseHandle(hFile); + Tcl_DetachPids(pipePtr->numPids, pipePtr->pidPtr); + Tcl_ReapDetachedProcs(); - if ((buf[0] == 'N') && (buf[1] == 'E')) { - applType = APPL_WIN3X; - } else if ((buf[0] == 'P') && (buf[1] == 'E')) { - applType = APPL_WIN32; - } else { - /* - * Strictly speaking, there should be a test that there is an 'L' - * and 'E' at buf[0..1], to identify the type as DOS, but of - * course we ran into a DOS executable that _doesn't_ have the - * magic number - specifically, one compiled using the Lahey - * Fortran90 compiler. - */ + if (pipePtr->errorFile) { + if (TclpCloseFile(pipePtr->errorFile) != 0) { + if (errorCode == 0) { + errorCode = errno; + } + } + } + result = 0; + } else { + /* + * Wrap the error file into a channel and give it to the cleanup + * routine. + */ - applType = APPL_DOS; + if (pipePtr->errorFile) { + WinFile *filePtr = (WinFile *) pipePtr->errorFile; + + errChan = Tcl_MakeFileChannel((ClientData) filePtr->handle, + TCL_READABLE); + ckfree(filePtr); + } else { + errChan = NULL; } - break; + + result = TclCleanupChildren(interp, pipePtr->numPids, + pipePtr->pidPtr, errChan); } - Tcl_DStringFree(&nameBuf); - if (applType == APPL_NONE) { - TclWinConvertError(GetLastError()); - Tcl_SetObjResult(interp, Tcl_ObjPrintf("couldn't execute \"%s\": %s", - originalName, Tcl_PosixError(interp))); - return APPL_NONE; + if (pipePtr->numPids > 0) { + ckfree(pipePtr->pidPtr); } - if ((applType == APPL_DOS) || (applType == APPL_WIN3X)) { - /* - * Replace long path name of executable with short path name for - * 16-bit applications. Otherwise the application may not be able to - * correctly parse its own command line to separate off the - * application name from the arguments. - */ + if (pipePtr->writeBuf != NULL) { + ckfree(pipePtr->writeBuf); + } - GetShortPathName(nativeFullPath, nativeFullPath, MAX_PATH); - strcpy(fullName, Tcl_WinTCharToUtf(nativeFullPath, -1, &ds)); - Tcl_DStringFree(&ds); + ckfree(pipePtr); + + if (errorCode == 0) { + return result; } - return applType; + return errorCode; } /* *---------------------------------------------------------------------- * - * BuildCommandLine -- + * PipeInputProc -- * - * The command line arguments are stored in linePtr separated by spaces, - * in a form that CreateProcess() understands. Special characters in - * individual arguments from argv[] must be quoted when being stored in - * cmdLine. + * Reads input from the IO channel into the buffer given. Returns count + * of how many bytes were actually read, and an error indication. * * Results: - * None. + * A count of how many bytes were read is returned and an error + * indication is returned in an output argument. * * Side effects: - * None. + * Reads input from the actual channel. * *---------------------------------------------------------------------- */ -static void -BuildCommandLine( - const char *executable, /* Full path of executable (including - * extension). Replacement for argv[0]. */ - int argc, /* Number of arguments. */ - const char **argv, /* Argument strings in UTF. */ - Tcl_DString *linePtr) /* Initialized Tcl_DString that receives the - * command line (TCHAR). */ +static int +PipeInputProc( + ClientData instanceData, /* Pipe state. */ + char *buf, /* Where to store data read. */ + int bufSize, /* How much space is available in the + * buffer? */ + int *errorCode) /* Where to store error code. */ { - const char *arg, *start, *special; - int quote, i; - Tcl_DString ds; + PipeInfo *infoPtr = (PipeInfo *) instanceData; + WinFile *filePtr = (WinFile*) infoPtr->readFile; + DWORD count, bytesRead = 0; + int result; - Tcl_DStringInit(&ds); + *errorCode = 0; + /* + * Synchronize with the reader thread. + */ + + result = WaitForRead(infoPtr, (infoPtr->flags & PIPE_ASYNC) ? 0 : 1); /* - * Prime the path. Add a space separator if we were primed with something. + * If an error occurred, return immediately. */ - TclDStringAppendDString(&ds, linePtr); - if (Tcl_DStringLength(linePtr) > 0) { - TclDStringAppendLiteral(&ds, " "); + if (result == -1) { + *errorCode = errno; + return -1; } - for (i = 0; i < argc; i++) { - if (i == 0) { - arg = executable; - } else { - arg = argv[i]; - TclDStringAppendLiteral(&ds, " "); - } + if (infoPtr->readFlags & PIPE_EXTRABYTE) { + /* + * The reader thread consumed 1 byte as a side effect of waiting so we + * need to move it into the buffer. + */ - quote = 0; - if (arg[0] == '\0') { - quote = 1; - } else { - int count; - Tcl_UniChar ch; + *buf = infoPtr->extraByte; + infoPtr->readFlags &= ~PIPE_EXTRABYTE; + buf++; + bufSize--; + bytesRead = 1; - for (start = arg; *start != '\0'; start += count) { - count = Tcl_UtfToUniChar(start, &ch); - if (Tcl_UniCharIsSpace(ch)) { /* INTL: ISO space. */ - quote = 1; - break; - } - } - } - if (quote) { - TclDStringAppendLiteral(&ds, "\""); - } - start = arg; - for (special = arg; ; ) { - if ((*special == '\\') && (special[1] == '\\' || - special[1] == '"' || (quote && special[1] == '\0'))) { - Tcl_DStringAppend(&ds, start, (int) (special - start)); - start = special; - while (1) { - special++; - if (*special == '"' || (quote && *special == '\0')) { - /* - * N backslashes followed a quote -> insert N * 2 + 1 - * backslashes then a quote. - */ + /* + * If further read attempts would block, return what we have. + */ - Tcl_DStringAppend(&ds, start, - (int) (special - start)); - break; - } - if (*special != '\\') { - break; - } - } - Tcl_DStringAppend(&ds, start, (int) (special - start)); - start = special; - } - if (*special == '"') { - Tcl_DStringAppend(&ds, start, (int) (special - start)); - TclDStringAppendLiteral(&ds, "\\\""); - start = special + 1; - } - if (*special == '\0') { - break; - } - special++; - } - Tcl_DStringAppend(&ds, start, (int) (special - start)); - if (quote) { - TclDStringAppendLiteral(&ds, "\""); + if (result == 0) { + return bytesRead; } } - Tcl_DStringFree(linePtr); - Tcl_WinUtfToTChar(Tcl_DStringValue(&ds), Tcl_DStringLength(&ds), linePtr); - Tcl_DStringFree(&ds); + + /* + * Attempt to read bufSize bytes. The read will return immediately if + * there is any data available. Otherwise it will block until at least one + * byte is available or an EOF occurs. + */ + + if (ReadFile(filePtr->handle, (LPVOID) buf, (DWORD) bufSize, &count, + (LPOVERLAPPED) NULL) == TRUE) { + return bytesRead + count; + } else if (bytesRead) { + /* + * Ignore errors if we have data to return. + */ + + return bytesRead; + } + + TclWinConvertError(GetLastError()); + if (errno == EPIPE) { + infoPtr->readFlags |= PIPE_EOF; + return 0; + } + *errorCode = errno; + return -1; } /* *---------------------------------------------------------------------- * - * TclpCreateCommandChannel -- + * PipeOutputProc -- * - * This function is called by Tcl_OpenCommandChannel to perform the - * platform specific channel initialization for a command channel. + * Writes the given output on the IO channel. Returns count of how many + * characters were actually written, and an error indication. * * Results: - * Returns a new channel or NULL on failure. + * A count of how many characters were written is returned and an error + * indication is returned in an output argument. * * Side effects: - * Allocates a new channel. + * Writes output on the actual channel. * *---------------------------------------------------------------------- */ -Tcl_Channel -TclpCreateCommandChannel( - TclFile readFile, /* If non-null, gives the file for reading. */ - TclFile writeFile, /* If non-null, gives the file for writing. */ - TclFile errorFile, /* If non-null, gives the file where errors - * can be read. */ - int numPids, /* The number of pids in the pid array. */ - Tcl_Pid *pidPtr) /* An array of process identifiers. */ +static int +PipeOutputProc( + ClientData instanceData, /* Pipe state. */ + const char *buf, /* The data buffer. */ + int toWrite, /* How many bytes to write? */ + int *errorCode) /* Where to store error code. */ { - char channelName[16 + TCL_INTEGER_SPACE]; - DWORD id; - PipeInfo *infoPtr = ckalloc(sizeof(PipeInfo)); + PipeInfo *infoPtr = (PipeInfo *) instanceData; + WinFile *filePtr = (WinFile*) infoPtr->writeFile; + DWORD bytesWritten, timeout; - PipeInit(); + *errorCode = 0; + timeout = (infoPtr->flags & PIPE_ASYNC) ? 0 : INFINITE; + if (WaitForSingleObject(infoPtr->writable, timeout) == WAIT_TIMEOUT) { + /* + * The writer thread is blocked waiting for a write to complete and + * the channel is in non-blocking mode. + */ - infoPtr->watchMask = 0; - infoPtr->flags = 0; - infoPtr->readFlags = 0; - infoPtr->readFile = readFile; - infoPtr->writeFile = writeFile; - infoPtr->errorFile = errorFile; - infoPtr->numPids = numPids; - infoPtr->pidPtr = pidPtr; - infoPtr->writeBuf = 0; - infoPtr->writeBufLen = 0; - infoPtr->writeError = 0; - infoPtr->channel = NULL; + errno = EWOULDBLOCK; + goto error; + } - infoPtr->validMask = 0; + /* + * Check for a background error on the last write. + */ - infoPtr->threadId = Tcl_GetCurrentThread(); + if (infoPtr->writeError) { + TclWinConvertError(infoPtr->writeError); + infoPtr->writeError = 0; + goto error; + } - if (readFile != NULL) { + if (infoPtr->flags & PIPE_ASYNC) { /* - * Start the background reader thread. + * The pipe is non-blocking, so copy the data into the output buffer + * and restart the writer thread. */ - infoPtr->readable = CreateEvent(NULL, TRUE, TRUE, NULL); - infoPtr->readThread = CreateThread(NULL, 256, PipeReaderThread, - PipeThreadCreateTI(&infoPtr->readTI, infoPtr), 0, &id); - SetThreadPriority(infoPtr->readThread, THREAD_PRIORITY_HIGHEST); - infoPtr->validMask |= TCL_READABLE; + if (toWrite > infoPtr->writeBufLen) { + /* + * Reallocate the buffer to be large enough to hold the data. + */ + + if (infoPtr->writeBuf) { + ckfree(infoPtr->writeBuf); + } + infoPtr->writeBufLen = toWrite; + infoPtr->writeBuf = ckalloc(toWrite); + } + memcpy(infoPtr->writeBuf, buf, (size_t) toWrite); + infoPtr->toWrite = toWrite; + ResetEvent(infoPtr->writable); + TclPipeThreadSignal(&infoPtr->writeTI); + bytesWritten = toWrite; } else { - infoPtr->readTI = NULL; - infoPtr->readThread = 0; - } - if (writeFile != NULL) { /* - * Start the background writer thread. + * In the blocking case, just try to write the buffer directly. This + * avoids an unnecessary copy. */ - infoPtr->writable = CreateEvent(NULL, TRUE, TRUE, NULL); - infoPtr->writeThread = CreateThread(NULL, 256, PipeWriterThread, - PipeThreadCreateTI(&infoPtr->writeTI, infoPtr), 0, &id); - SetThreadPriority(infoPtr->writeThread, THREAD_PRIORITY_HIGHEST); - infoPtr->validMask |= TCL_WRITABLE; - } else { - infoPtr->writeTI = NULL; - infoPtr->writeThread = 0; + if (WriteFile(filePtr->handle, (LPVOID) buf, (DWORD) toWrite, + &bytesWritten, (LPOVERLAPPED) NULL) == FALSE) { + TclWinConvertError(GetLastError()); + goto error; + } } + return bytesWritten; - /* - * For backward compatibility with previous versions of Tcl, we use - * "file%d" as the base name for pipes even though it would be more - * natural to use "pipe%d". Use the pointer to keep the channel names - * unique, in case channels share handles (stdin/stdout). - */ - - sprintf(channelName, "file%" TCL_I_MODIFIER "x", (size_t) infoPtr); - infoPtr->channel = Tcl_CreateChannel(&pipeChannelType, channelName, - infoPtr, infoPtr->validMask); - - /* - * Pipes have AUTO translation mode on Windows and ^Z eof char, which - * means that a ^Z will be appended to them at close. This is needed for - * Windows programs that expect a ^Z at EOF. - */ + error: + *errorCode = errno; + return -1; - Tcl_SetChannelOption(NULL, infoPtr->channel, "-translation", "auto"); - Tcl_SetChannelOption(NULL, infoPtr->channel, "-eofchar", "\032 {}"); - return infoPtr->channel; } /* *---------------------------------------------------------------------- * - * Tcl_CreatePipe -- + * PipeEventProc -- * - * System dependent interface to create a pipe for the [chan pipe] - * command. Stolen from TclX. + * This function is invoked by Tcl_ServiceEvent when a file event reaches + * the front of the event queue. This function invokes Tcl_NotifyChannel + * on the pipe. * * Results: - * TCL_OK or TCL_ERROR. + * Returns 1 if the event was handled, meaning it should be removed from + * the queue. Returns 0 if the event was not handled, meaning it should + * stay on the queue. The only time the event isn't handled is if the + * TCL_FILE_EVENTS flag bit isn't set. + * + * Side effects: + * Whatever the notifier callback does. * *---------------------------------------------------------------------- */ -int -Tcl_CreatePipe( - Tcl_Interp *interp, /* Errors returned in result.*/ - Tcl_Channel *rchan, /* Where to return the read side. */ - Tcl_Channel *wchan, /* Where to return the write side. */ - int flags) /* Reserved for future use. */ +static int +PipeEventProc( + Tcl_Event *evPtr, /* Event to service. */ + int flags) /* Flags that indicate what events to + * handle, such as TCL_FILE_EVENTS. */ { - HANDLE readHandle, writeHandle; - SECURITY_ATTRIBUTES sec; + PipeEvent *pipeEvPtr = (PipeEvent *)evPtr; + PipeInfo *infoPtr; + int mask; + ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&dataKey); - sec.nLength = sizeof(SECURITY_ATTRIBUTES); - sec.lpSecurityDescriptor = NULL; - sec.bInheritHandle = FALSE; + if (!(flags & TCL_FILE_EVENTS)) { + return 0; + } - if (!CreatePipe(&readHandle, &writeHandle, &sec, 0)) { - TclWinConvertError(GetLastError()); - Tcl_SetObjResult(interp, Tcl_ObjPrintf( - "pipe creation failed: %s", Tcl_PosixError(interp))); - return TCL_ERROR; + /* + * Search through the list of watched pipes for the one whose handle + * matches the event. We do this rather than simply dereferencing the + * handle in the event so that pipes can be deleted while the event is in + * the queue. + */ + + for (infoPtr = tsdPtr->firstPipePtr; infoPtr != NULL; + infoPtr = infoPtr->nextPtr) { + if (pipeEvPtr->infoPtr == infoPtr) { + infoPtr->flags &= ~(PIPE_PENDING); + break; + } } - *rchan = Tcl_MakeFileChannel((ClientData) readHandle, TCL_READABLE); - Tcl_RegisterChannel(interp, *rchan); + /* + * Remove stale events. + */ - *wchan = Tcl_MakeFileChannel((ClientData) writeHandle, TCL_WRITABLE); - Tcl_RegisterChannel(interp, *wchan); + if (!infoPtr) { + return 1; + } - return TCL_OK; + /* + * Check to see if the pipe is readable. Note that we can't tell if a pipe + * is writable, so we always report it as being writable unless we have + * detected EOF. + */ + + mask = 0; + if ((infoPtr->watchMask & TCL_WRITABLE) && + (WaitForSingleObject(infoPtr->writable, 0) != WAIT_TIMEOUT)) { + mask = TCL_WRITABLE; + } + + if ((infoPtr->watchMask & TCL_READABLE) && (WaitForRead(infoPtr,0) >= 0)) { + if (infoPtr->readFlags & PIPE_EOF) { + mask = TCL_READABLE; + } else { + mask |= TCL_READABLE; + } + } + + /* + * Inform the channel of the events. + */ + + Tcl_NotifyChannel(infoPtr->channel, infoPtr->watchMask & mask); + return 1; } /* *---------------------------------------------------------------------- * - * TclGetAndDetachPids -- + * PipeWatchProc -- * - * Stores a list of the command PIDs for a command channel in the - * interp's result. + * Called by the notifier to set up to watch for events on this channel. * * Results: * None. * * Side effects: - * Modifies the interp's result. + * None. * *---------------------------------------------------------------------- */ -void -TclGetAndDetachPids( - Tcl_Interp *interp, - Tcl_Channel chan) +static void +PipeWatchProc( + ClientData instanceData, /* Pipe state. */ + int mask) /* What events to watch for, OR-ed combination + * of TCL_READABLE, TCL_WRITABLE and + * TCL_EXCEPTION. */ { - PipeInfo *pipePtr; - const Tcl_ChannelType *chanTypePtr; - Tcl_Obj *pidsObj; - int i; + PipeInfo **nextPtrPtr, *ptr; + PipeInfo *infoPtr = (PipeInfo *) instanceData; + int oldMask = infoPtr->watchMask; + ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&dataKey); /* - * Punt if the channel is not a command channel. + * Since most of the work is handled by the background threads, we just + * need to update the watchMask and then force the notifier to poll once. */ - chanTypePtr = Tcl_GetChannelType(chan); - if (chanTypePtr != &pipeChannelType) { - return; - } + infoPtr->watchMask = mask & infoPtr->validMask; + if (infoPtr->watchMask) { + Tcl_Time blockTime = { 0, 0 }; + if (!oldMask) { + infoPtr->nextPtr = tsdPtr->firstPipePtr; + tsdPtr->firstPipePtr = infoPtr; + } + Tcl_SetMaxBlockTime(&blockTime); + } else { + if (oldMask) { + /* + * Remove the pipe from the list of watched pipes. + */ - pipePtr = Tcl_GetChannelInstanceData(chan); - TclNewObj(pidsObj); - for (i = 0; i < pipePtr->numPids; i++) { - Tcl_ListObjAppendElement(NULL, pidsObj, - Tcl_NewWideIntObj((unsigned) - TclpGetPid(pipePtr->pidPtr[i]))); - Tcl_DetachPids(1, &pipePtr->pidPtr[i]); - } - Tcl_SetObjResult(interp, pidsObj); - if (pipePtr->numPids > 0) { - ckfree(pipePtr->pidPtr); - pipePtr->numPids = 0; + for (nextPtrPtr = &(tsdPtr->firstPipePtr), ptr = *nextPtrPtr; + ptr != NULL; + nextPtrPtr = &ptr->nextPtr, ptr = *nextPtrPtr) { + if (infoPtr == ptr) { + *nextPtrPtr = ptr->nextPtr; + break; + } + } + } } } /* *---------------------------------------------------------------------- * - * PipeBlockModeProc -- + * PipeGetHandleProc -- * - * Set blocking or non-blocking mode on channel. + * Called from Tcl_GetChannelHandle to retrieve OS handles from inside a + * command pipeline based channel. * * Results: - * 0 if successful, errno when failed. + * Returns TCL_OK with the fd in handlePtr, or TCL_ERROR if there is no + * handle for the specified direction. * * Side effects: - * Sets the device into blocking or non-blocking mode. + * None. * *---------------------------------------------------------------------- */ static int -PipeBlockModeProc( - ClientData instanceData, /* Instance data for channel. */ - int mode) /* TCL_MODE_BLOCKING or - * TCL_MODE_NONBLOCKING. */ +PipeGetHandleProc( + ClientData instanceData, /* The pipe state. */ + int direction, /* TCL_READABLE or TCL_WRITABLE */ + ClientData *handlePtr) /* Where to store the handle. */ { PipeInfo *infoPtr = (PipeInfo *) instanceData; + WinFile *filePtr; - /* - * Pipes on Windows can not be switched between blocking and nonblocking, - * hence we have to emulate the behavior. This is done in the input - * function by checking against a bit in the state. We set or unset the - * bit here to cause the input function to emulate the correct behavior. - */ - - if (mode == TCL_MODE_NONBLOCKING) { - infoPtr->flags |= PIPE_ASYNC; - } else { - infoPtr->flags &= ~(PIPE_ASYNC); + if (direction == TCL_READABLE && infoPtr->readFile) { + filePtr = (WinFile*) infoPtr->readFile; + *handlePtr = (ClientData) filePtr->handle; + return TCL_OK; } - return 0; + if (direction == TCL_WRITABLE && infoPtr->writeFile) { + filePtr = (WinFile*) infoPtr->writeFile; + *handlePtr = (ClientData) filePtr->handle; + return TCL_OK; + } + return TCL_ERROR; } /* *---------------------------------------------------------------------- * - * PipeClose2Proc -- + * Tcl_WaitPid -- * - * Closes a pipe based IO channel. + * Emulates the waitpid system call. * * Results: - * 0 on success, errno otherwise. + * Returns 0 if the process is still alive, -1 on an error, or the pid on + * a clean close. * * Side effects: - * Closes the physical channel. + * Unless WNOHANG is set and the wait times out, the process information + * record will be deleted and the process handle will be closed. * *---------------------------------------------------------------------- */ -static int -PipeClose2Proc( - ClientData instanceData, /* Pointer to PipeInfo structure. */ - Tcl_Interp *interp, /* For error reporting. */ - int flags) /* Flags that indicate which side to close. */ +Tcl_Pid +Tcl_WaitPid( + Tcl_Pid pid, + int *statPtr, + int options) { - PipeInfo *pipePtr = (PipeInfo *) instanceData; - Tcl_Channel errChan; - int errorCode, result; - PipeInfo *infoPtr, **nextPtrPtr; - ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&dataKey); - - errorCode = 0; - result = 0; + ProcInfo *infoPtr = NULL, **prevPtrPtr; + DWORD flags; + Tcl_Pid result; + DWORD ret, exitCode; - if ((!flags || flags == TCL_CLOSE_READ) && (pipePtr->readFile != NULL)) { - /* - * Clean up the background thread if necessary. Note that this must be - * done before we can close the file, since the thread may be blocking - * trying to read from the pipe. - */ + PipeInit(); - if (pipePtr->readThread) { + /* + * If no pid is specified, do nothing. + */ - PipeThreadStop(&pipePtr->readTI, pipePtr->readThread); - CloseHandle(pipePtr->readThread); - CloseHandle(pipePtr->readable); - pipePtr->readThread = NULL; - } - if (TclpCloseFile(pipePtr->readFile) != 0) { - errorCode = errno; - } - pipePtr->validMask &= ~TCL_READABLE; - pipePtr->readFile = NULL; + if (pid == 0) { + *statPtr = 0; + return 0; } - if ((!flags || flags & TCL_CLOSE_WRITE) - && (pipePtr->writeFile != NULL)) { - if (pipePtr->writeThread) { - - /* - * Wait for the writer thread to finish the current buffer, then - * terminate the thread and close the handles. If the channel is - * nonblocking or may block during exit, bail out since the worker - * thread is not interruptible and we want TIP#398-fast-exit. - */ - if ((pipePtr->flags & PIPE_ASYNC) && TclInExit()) { - - /* give it a chance to leave honorably */ - PipeThreadStopSignal(&pipePtr->writeTI); - - if (WaitForSingleObject(pipePtr->writable, 20) == WAIT_TIMEOUT) { - return EWOULDBLOCK; - } - - } else { - - WaitForSingleObject(pipePtr->writable, INFINITE); - - } - PipeThreadStop(&pipePtr->writeTI, pipePtr->writeThread); + /* + * Find the process and cut it from the process list. + */ - CloseHandle(pipePtr->writable); - CloseHandle(pipePtr->writeThread); - pipePtr->writeThread = NULL; - } - if (TclpCloseFile(pipePtr->writeFile) != 0) { - if (errorCode == 0) { - errorCode = errno; - } + Tcl_MutexLock(&pipeMutex); + prevPtrPtr = &procList; + for (infoPtr = procList; infoPtr != NULL; + prevPtrPtr = &infoPtr->nextPtr, infoPtr = infoPtr->nextPtr) { + if (infoPtr->hProcess == (HANDLE) pid) { + *prevPtrPtr = infoPtr->nextPtr; + break; } - pipePtr->validMask &= ~TCL_WRITABLE; - pipePtr->writeFile = NULL; } - - pipePtr->watchMask &= pipePtr->validMask; + Tcl_MutexUnlock(&pipeMutex); /* - * Don't free the channel if any of the flags were set. + * If the pid is not one of the processes we know about (we started it) + * then do nothing. */ - if (flags) { - return errorCode; + if (infoPtr == NULL) { + *statPtr = 0; + return 0; } /* - * Remove the file from the list of watched files. + * Officially "wait" for it to finish. We either poll (WNOHANG) or wait + * for an infinite amount of time. */ - for (nextPtrPtr = &(tsdPtr->firstPipePtr), infoPtr = *nextPtrPtr; - infoPtr != NULL; - nextPtrPtr = &infoPtr->nextPtr, infoPtr = *nextPtrPtr) { - if (infoPtr == (PipeInfo *)pipePtr) { - *nextPtrPtr = infoPtr->nextPtr; - break; - } + if (options & WNOHANG) { + flags = 0; + } else { + flags = INFINITE; } + ret = WaitForSingleObject(infoPtr->hProcess, flags); + if (ret == WAIT_TIMEOUT) { + *statPtr = 0; + if (options & WNOHANG) { + /* + * Re-insert this infoPtr back on the list. + */ + + Tcl_MutexLock(&pipeMutex); + infoPtr->nextPtr = procList; + procList = infoPtr; + Tcl_MutexUnlock(&pipeMutex); + return 0; + } else { + result = 0; + } + } else if (ret == WAIT_OBJECT_0) { + GetExitCodeProcess(infoPtr->hProcess, &exitCode); - if ((pipePtr->flags & PIPE_ASYNC) || TclInExit()) { /* - * If the channel is non-blocking or Tcl is being cleaned up, just - * detach the children PIDs, reap them (important if we are in a - * dynamic load module), and discard the errorFile. + * Does the exit code look like one of the exception codes? */ - Tcl_DetachPids(pipePtr->numPids, pipePtr->pidPtr); - Tcl_ReapDetachedProcs(); + switch (exitCode) { + case EXCEPTION_FLT_DENORMAL_OPERAND: + case EXCEPTION_FLT_DIVIDE_BY_ZERO: + case EXCEPTION_FLT_INEXACT_RESULT: + case EXCEPTION_FLT_INVALID_OPERATION: + case EXCEPTION_FLT_OVERFLOW: + case EXCEPTION_FLT_STACK_CHECK: + case EXCEPTION_FLT_UNDERFLOW: + case EXCEPTION_INT_DIVIDE_BY_ZERO: + case EXCEPTION_INT_OVERFLOW: + *statPtr = 0xC0000000 | SIGFPE; + break; - if (pipePtr->errorFile) { - if (TclpCloseFile(pipePtr->errorFile) != 0) { - if (errorCode == 0) { - errorCode = errno; - } - } - } - result = 0; - } else { - /* - * Wrap the error file into a channel and give it to the cleanup - * routine. - */ + case EXCEPTION_PRIV_INSTRUCTION: + case EXCEPTION_ILLEGAL_INSTRUCTION: + *statPtr = 0xC0000000 | SIGILL; + break; + + case EXCEPTION_ACCESS_VIOLATION: + case EXCEPTION_ARRAY_BOUNDS_EXCEEDED: + case EXCEPTION_STACK_OVERFLOW: + case EXCEPTION_NONCONTINUABLE_EXCEPTION: + case EXCEPTION_INVALID_DISPOSITION: + case EXCEPTION_GUARD_PAGE: + case EXCEPTION_INVALID_HANDLE: + *statPtr = 0xC0000000 | SIGSEGV; + break; - if (pipePtr->errorFile) { - WinFile *filePtr = (WinFile *) pipePtr->errorFile; + case EXCEPTION_DATATYPE_MISALIGNMENT: + *statPtr = 0xC0000000 | SIGBUS; + break; - errChan = Tcl_MakeFileChannel((ClientData) filePtr->handle, - TCL_READABLE); - ckfree(filePtr); - } else { - errChan = NULL; - } + case EXCEPTION_BREAKPOINT: + case EXCEPTION_SINGLE_STEP: + *statPtr = 0xC0000000 | SIGTRAP; + break; - result = TclCleanupChildren(interp, pipePtr->numPids, - pipePtr->pidPtr, errChan); - } + case CONTROL_C_EXIT: + *statPtr = 0xC0000000 | SIGINT; + break; - if (pipePtr->numPids > 0) { - ckfree(pipePtr->pidPtr); - } + default: + /* + * Non-exceptional, normal, exit code. Note that the exit code is + * truncated to a signed short range [-32768,32768) whether it + * fits into this range or not. + * + * BUG: Even though the exit code is a DWORD, it is understood by + * convention to be a signed integer, yet there isn't enough room + * to fit this into the POSIX style waitstatus mask without + * truncating it. + */ - if (pipePtr->writeBuf != NULL) { - ckfree(pipePtr->writeBuf); + *statPtr = exitCode; + break; + } + result = pid; + } else { + errno = ECHILD; + *statPtr = 0xC0000000 | ECHILD; + result = (Tcl_Pid) -1; } - ckfree(pipePtr); + /* + * Officially close the process handle. + */ - if (errorCode == 0) { - return result; - } - return errorCode; + CloseHandle(infoPtr->hProcess); + ckfree(infoPtr); + + return result; } /* *---------------------------------------------------------------------- * - * PipeInputProc -- + * TclWinAddProcess -- * - * Reads input from the IO channel into the buffer given. Returns count - * of how many bytes were actually read, and an error indication. + * Add a process to the process list so that we can use Tcl_WaitPid on + * the process. * * Results: - * A count of how many bytes were read is returned and an error - * indication is returned in an output argument. + * None * * Side effects: - * Reads input from the actual channel. + * Adds the specified process handle to the process list so Tcl_WaitPid + * knows about it. * *---------------------------------------------------------------------- */ -static int -PipeInputProc( - ClientData instanceData, /* Pipe state. */ - char *buf, /* Where to store data read. */ - int bufSize, /* How much space is available in the - * buffer? */ - int *errorCode) /* Where to store error code. */ +void +TclWinAddProcess( + void *hProcess, /* Handle to process */ + unsigned long id) /* Global process identifier */ { - PipeInfo *infoPtr = (PipeInfo *) instanceData; - WinFile *filePtr = (WinFile*) infoPtr->readFile; - DWORD count, bytesRead = 0; - int result; - - *errorCode = 0; - /* - * Synchronize with the reader thread. - */ - - result = WaitForRead(infoPtr, (infoPtr->flags & PIPE_ASYNC) ? 0 : 1); - - /* - * If an error occurred, return immediately. - */ - - if (result == -1) { - *errorCode = errno; - return -1; - } - - if (infoPtr->readFlags & PIPE_EXTRABYTE) { - /* - * The reader thread consumed 1 byte as a side effect of waiting so we - * need to move it into the buffer. - */ - - *buf = infoPtr->extraByte; - infoPtr->readFlags &= ~PIPE_EXTRABYTE; - buf++; - bufSize--; - bytesRead = 1; - - /* - * If further read attempts would block, return what we have. - */ - - if (result == 0) { - return bytesRead; - } - } - - /* - * Attempt to read bufSize bytes. The read will return immediately if - * there is any data available. Otherwise it will block until at least one - * byte is available or an EOF occurs. - */ - - if (ReadFile(filePtr->handle, (LPVOID) buf, (DWORD) bufSize, &count, - (LPOVERLAPPED) NULL) == TRUE) { - return bytesRead + count; - } else if (bytesRead) { - /* - * Ignore errors if we have data to return. - */ + ProcInfo *procPtr = ckalloc(sizeof(ProcInfo)); - return bytesRead; - } + PipeInit(); - TclWinConvertError(GetLastError()); - if (errno == EPIPE) { - infoPtr->readFlags |= PIPE_EOF; - return 0; - } - *errorCode = errno; - return -1; + procPtr->hProcess = hProcess; + procPtr->dwProcessId = id; + Tcl_MutexLock(&pipeMutex); + procPtr->nextPtr = procList; + procList = procPtr; + Tcl_MutexUnlock(&pipeMutex); } /* *---------------------------------------------------------------------- * - * PipeOutputProc -- + * Tcl_PidObjCmd -- * - * Writes the given output on the IO channel. Returns count of how many - * characters were actually written, and an error indication. + * This function is invoked to process the "pid" Tcl command. See the + * user documentation for details on what it does. * * Results: - * A count of how many characters were written is returned and an error - * indication is returned in an output argument. + * A standard Tcl result. * * Side effects: - * Writes output on the actual channel. + * See the user documentation. * *---------------------------------------------------------------------- */ -static int -PipeOutputProc( - ClientData instanceData, /* Pipe state. */ - const char *buf, /* The data buffer. */ - int toWrite, /* How many bytes to write? */ - int *errorCode) /* Where to store error code. */ + /* ARGSUSED */ +int +Tcl_PidObjCmd( + ClientData dummy, /* Not used. */ + Tcl_Interp *interp, /* Current interpreter. */ + int objc, /* Number of arguments. */ + Tcl_Obj *const *objv) /* Argument strings. */ { - PipeInfo *infoPtr = (PipeInfo *) instanceData; - WinFile *filePtr = (WinFile*) infoPtr->writeFile; - DWORD bytesWritten, timeout; - - *errorCode = 0; - timeout = (infoPtr->flags & PIPE_ASYNC) ? 0 : INFINITE; - if (WaitForSingleObject(infoPtr->writable, timeout) == WAIT_TIMEOUT) { - /* - * The writer thread is blocked waiting for a write to complete and - * the channel is in non-blocking mode. - */ - - errno = EWOULDBLOCK; - goto error; - } - - /* - * Check for a background error on the last write. - */ + Tcl_Channel chan; + const Tcl_ChannelType *chanTypePtr; + PipeInfo *pipePtr; + int i; + Tcl_Obj *resultPtr; - if (infoPtr->writeError) { - TclWinConvertError(infoPtr->writeError); - infoPtr->writeError = 0; - goto error; + if (objc > 2) { + Tcl_WrongNumArgs(interp, 1, objv, "?channelId?"); + return TCL_ERROR; } - - if (infoPtr->flags & PIPE_ASYNC) { - /* - * The pipe is non-blocking, so copy the data into the output buffer - * and restart the writer thread. - */ - - if (toWrite > infoPtr->writeBufLen) { - /* - * Reallocate the buffer to be large enough to hold the data. - */ - - if (infoPtr->writeBuf) { - ckfree(infoPtr->writeBuf); - } - infoPtr->writeBufLen = toWrite; - infoPtr->writeBuf = ckalloc(toWrite); - } - memcpy(infoPtr->writeBuf, buf, (size_t) toWrite); - infoPtr->toWrite = toWrite; - ResetEvent(infoPtr->writable); - PipeThreadSignal(&infoPtr->writeTI); - bytesWritten = toWrite; + if (objc == 1) { + Tcl_SetObjResult(interp, Tcl_NewWideIntObj((unsigned) getpid())); } else { - /* - * In the blocking case, just try to write the buffer directly. This - * avoids an unnecessary copy. - */ + chan = Tcl_GetChannel(interp, Tcl_GetString(objv[1]), + NULL); + if (chan == (Tcl_Channel) NULL) { + return TCL_ERROR; + } + chanTypePtr = Tcl_GetChannelType(chan); + if (chanTypePtr != &pipeChannelType) { + return TCL_OK; + } - if (WriteFile(filePtr->handle, (LPVOID) buf, (DWORD) toWrite, - &bytesWritten, (LPOVERLAPPED) NULL) == FALSE) { - TclWinConvertError(GetLastError()); - goto error; + pipePtr = (PipeInfo *) Tcl_GetChannelInstanceData(chan); + resultPtr = Tcl_NewObj(); + for (i = 0; i < pipePtr->numPids; i++) { + Tcl_ListObjAppendElement(/*interp*/ NULL, resultPtr, + Tcl_NewWideIntObj((unsigned) + TclpGetPid(pipePtr->pidPtr[i]))); } + Tcl_SetObjResult(interp, resultPtr); } - return bytesWritten; - - error: - *errorCode = errno; - return -1; - + return TCL_OK; } /* *---------------------------------------------------------------------- * - * PipeEventProc -- + * WaitForRead -- * - * This function is invoked by Tcl_ServiceEvent when a file event reaches - * the front of the event queue. This function invokes Tcl_NotifyChannel - * on the pipe. + * Wait until some data is available, the pipe is at EOF or the reader + * thread is blocked waiting for data (if the channel is in non-blocking + * mode). * * Results: - * Returns 1 if the event was handled, meaning it should be removed from - * the queue. Returns 0 if the event was not handled, meaning it should - * stay on the queue. The only time the event isn't handled is if the - * TCL_FILE_EVENTS flag bit isn't set. + * Returns 1 if pipe is readable. Returns 0 if there is no data on the + * pipe, but there is buffered data. Returns -1 if an error occurred. If + * an error occurred, the threads may not be synchronized. * * Side effects: - * Whatever the notifier callback does. + * Updates the shared state flags and may consume 1 byte of data from the + * pipe. If no error occurred, the reader thread is blocked waiting for a + * signal from the main thread. * *---------------------------------------------------------------------- */ static int -PipeEventProc( - Tcl_Event *evPtr, /* Event to service. */ - int flags) /* Flags that indicate what events to - * handle, such as TCL_FILE_EVENTS. */ +WaitForRead( + PipeInfo *infoPtr, /* Pipe state. */ + int blocking) /* Indicates whether call should be blocking + * or not. */ { - PipeEvent *pipeEvPtr = (PipeEvent *)evPtr; - PipeInfo *infoPtr; - int mask; - ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&dataKey); + DWORD timeout, count; + HANDLE *handle = ((WinFile *) infoPtr->readFile)->handle; - if (!(flags & TCL_FILE_EVENTS)) { - return 0; - } + while (1) { + /* + * Synchronize with the reader thread. + */ - /* - * Search through the list of watched pipes for the one whose handle - * matches the event. We do this rather than simply dereferencing the - * handle in the event so that pipes can be deleted while the event is in - * the queue. - */ + timeout = blocking ? INFINITE : 0; + if (WaitForSingleObject(infoPtr->readable, timeout) == WAIT_TIMEOUT) { + /* + * The reader thread is blocked waiting for data and the channel + * is in non-blocking mode. + */ - for (infoPtr = tsdPtr->firstPipePtr; infoPtr != NULL; - infoPtr = infoPtr->nextPtr) { - if (pipeEvPtr->infoPtr == infoPtr) { - infoPtr->flags &= ~(PIPE_PENDING); - break; + errno = EWOULDBLOCK; + return -1; } - } - /* - * Remove stale events. - */ + /* + * At this point, the two threads are synchronized, so it is safe to + * access shared state. + */ - if (!infoPtr) { - return 1; - } + /* + * If the pipe has hit EOF, it is always readable. + */ - /* - * Check to see if the pipe is readable. Note that we can't tell if a pipe - * is writable, so we always report it as being writable unless we have - * detected EOF. - */ + if (infoPtr->readFlags & PIPE_EOF) { + return 1; + } - mask = 0; - if ((infoPtr->watchMask & TCL_WRITABLE) && - (WaitForSingleObject(infoPtr->writable, 0) != WAIT_TIMEOUT)) { - mask = TCL_WRITABLE; - } + /* + * Check to see if there is any data sitting in the pipe. + */ - if ((infoPtr->watchMask & TCL_READABLE) && (WaitForRead(infoPtr,0) >= 0)) { - if (infoPtr->readFlags & PIPE_EOF) { - mask = TCL_READABLE; - } else { - mask |= TCL_READABLE; + if (PeekNamedPipe(handle, (LPVOID) NULL, (DWORD) 0, + (LPDWORD) NULL, &count, (LPDWORD) NULL) != TRUE) { + TclWinConvertError(GetLastError()); + + /* + * Check to see if the peek failed because of EOF. + */ + + if (errno == EPIPE) { + infoPtr->readFlags |= PIPE_EOF; + return 1; + } + + /* + * Ignore errors if there is data in the buffer. + */ + + if (infoPtr->readFlags & PIPE_EXTRABYTE) { + return 0; + } else { + return -1; + } } - } - /* - * Inform the channel of the events. - */ + /* + * We found some data in the pipe, so it must be readable. + */ - Tcl_NotifyChannel(infoPtr->channel, infoPtr->watchMask & mask); - return 1; + if (count > 0) { + return 1; + } + + /* + * The pipe isn't readable, but there is some data sitting in the + * buffer, so return immediately. + */ + + if (infoPtr->readFlags & PIPE_EXTRABYTE) { + return 0; + } + + /* + * There wasn't any data available, so reset the thread and try again. + */ + + ResetEvent(infoPtr->readable); + TclPipeThreadSignal(&infoPtr->readTI); + } } /* *---------------------------------------------------------------------- * - * PipeWatchProc -- + * PipeReaderThread -- * - * Called by the notifier to set up to watch for events on this channel. + * This function runs in a separate thread and waits for input to become + * available on a pipe. * * Results: * None. * * Side effects: - * None. + * Signals the main thread when input become available. May cause the + * main thread to wake up by posting a message. May consume one byte from + * the pipe for each wait operation. Will cause a memory leak of ~4k, if + * forcefully terminated with TerminateThread(). * *---------------------------------------------------------------------- */ -static void -PipeWatchProc( - ClientData instanceData, /* Pipe state. */ - int mask) /* What events to watch for, OR-ed combination - * of TCL_READABLE, TCL_WRITABLE and - * TCL_EXCEPTION. */ +static DWORD WINAPI +PipeReaderThread( + LPVOID arg) { - PipeInfo **nextPtrPtr, *ptr; - PipeInfo *infoPtr = (PipeInfo *) instanceData; - int oldMask = infoPtr->watchMask; - ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&dataKey); + TclPipeThreadInfo *pipeTI = (TclPipeThreadInfo *)arg; + PipeInfo *infoPtr = NULL; /* access info only after success init/wait */ + HANDLE handle = NULL; + DWORD count, err; + int done = 0; + + while (!done) { + /* + * Wait for the main thread to signal before attempting to wait on the + * pipe becoming readable. + */ + if (!TclPipeThreadWaitForSignal(&pipeTI)) { + /* exit */ + break; + } - /* - * Since most of the work is handled by the background threads, we just - * need to update the watchMask and then force the notifier to poll once. - */ + if (!infoPtr) { + infoPtr = (PipeInfo *)pipeTI->clientData; + handle = ((WinFile *) infoPtr->readFile)->handle; + } + + /* + * Try waiting for 0 bytes. This will block until some data is + * available on NT, but will return immediately on Win 95. So, if no + * data is available after the first read, we block until we can read + * a single byte off of the pipe. + */ + + if (ReadFile(handle, NULL, 0, &count, NULL) == FALSE || + PeekNamedPipe(handle, NULL, 0, NULL, &count, NULL) == FALSE) { + /* + * The error is a result of an EOF condition, so set the EOF bit + * before signalling the main thread. + */ + + err = GetLastError(); + if (err == ERROR_BROKEN_PIPE) { + infoPtr->readFlags |= PIPE_EOF; + done = 1; + } else if (err == ERROR_INVALID_HANDLE) { + break; + } + } else if (count == 0) { + if (ReadFile(handle, &(infoPtr->extraByte), 1, &count, NULL) + != FALSE) { + /* + * One byte was consumed as a side effect of waiting for the + * pipe to become readable. + */ + + infoPtr->readFlags |= PIPE_EXTRABYTE; + } else { + err = GetLastError(); + if (err == ERROR_BROKEN_PIPE) { + /* + * The error is a result of an EOF condition, so set the + * EOF bit before signalling the main thread. + */ + + infoPtr->readFlags |= PIPE_EOF; + done = 1; + } else if (err == ERROR_INVALID_HANDLE) { + break; + } + } + } + + /* + * Signal the main thread by signalling the readable event and then + * waking up the notifier thread. + */ + + SetEvent(infoPtr->readable); + + /* + * Alert the foreground thread. Note that we need to treat this like a + * critical section so the foreground thread does not terminate this + * thread while we are holding a mutex in the notifier code. + */ - infoPtr->watchMask = mask & infoPtr->validMask; - if (infoPtr->watchMask) { - Tcl_Time blockTime = { 0, 0 }; - if (!oldMask) { - infoPtr->nextPtr = tsdPtr->firstPipePtr; - tsdPtr->firstPipePtr = infoPtr; - } - Tcl_SetMaxBlockTime(&blockTime); - } else { - if (oldMask) { + Tcl_MutexLock(&pipeMutex); + if (infoPtr->threadId != NULL) { /* - * Remove the pipe from the list of watched pipes. + * TIP #218. When in flight ignore the event, no one will receive + * it anyway. */ - for (nextPtrPtr = &(tsdPtr->firstPipePtr), ptr = *nextPtrPtr; - ptr != NULL; - nextPtrPtr = &ptr->nextPtr, ptr = *nextPtrPtr) { - if (infoPtr == ptr) { - *nextPtrPtr = ptr->nextPtr; - break; - } - } + Tcl_ThreadAlert(infoPtr->threadId); } + Tcl_MutexUnlock(&pipeMutex); } -} - -/* - *---------------------------------------------------------------------- - * - * PipeGetHandleProc -- - * - * Called from Tcl_GetChannelHandle to retrieve OS handles from inside a - * command pipeline based channel. - * - * Results: - * Returns TCL_OK with the fd in handlePtr, or TCL_ERROR if there is no - * handle for the specified direction. - * - * Side effects: - * None. - * - *---------------------------------------------------------------------- - */ -static int -PipeGetHandleProc( - ClientData instanceData, /* The pipe state. */ - int direction, /* TCL_READABLE or TCL_WRITABLE */ - ClientData *handlePtr) /* Where to store the handle. */ -{ - PipeInfo *infoPtr = (PipeInfo *) instanceData; - WinFile *filePtr; + /* + * If state of thread was set to stop, we can sane free info structure, + * otherwise it is shared with main thread, so main thread will own it + */ + TclPipeThreadExit(&pipeTI); - if (direction == TCL_READABLE && infoPtr->readFile) { - filePtr = (WinFile*) infoPtr->readFile; - *handlePtr = (ClientData) filePtr->handle; - return TCL_OK; - } - if (direction == TCL_WRITABLE && infoPtr->writeFile) { - filePtr = (WinFile*) infoPtr->writeFile; - *handlePtr = (ClientData) filePtr->handle; - return TCL_OK; - } - return TCL_ERROR; + return 0; } /* *---------------------------------------------------------------------- * - * Tcl_WaitPid -- + * PipeWriterThread -- * - * Emulates the waitpid system call. + * This function runs in a separate thread and writes data onto a pipe. * * Results: - * Returns 0 if the process is still alive, -1 on an error, or the pid on - * a clean close. + * Always returns 0. * * Side effects: - * Unless WNOHANG is set and the wait times out, the process information - * record will be deleted and the process handle will be closed. + * Signals the main thread when an output operation is completed. May + * cause the main thread to wake up by posting a message. * *---------------------------------------------------------------------- */ -Tcl_Pid -Tcl_WaitPid( - Tcl_Pid pid, - int *statPtr, - int options) +static DWORD WINAPI +PipeWriterThread( + LPVOID arg) { - ProcInfo *infoPtr = NULL, **prevPtrPtr; - DWORD flags; - Tcl_Pid result; - DWORD ret, exitCode; - - PipeInit(); - - /* - * If no pid is specified, do nothing. - */ - - if (pid == 0) { - *statPtr = 0; - return 0; - } - - /* - * Find the process and cut it from the process list. - */ + TclPipeThreadInfo *pipeTI = (TclPipeThreadInfo *)arg; + PipeInfo *infoPtr = NULL; /* access info only after success init/wait */ + HANDLE handle = NULL, writable = NULL; + DWORD count, toWrite; + char *buf; + int done = 0; - Tcl_MutexLock(&pipeMutex); - prevPtrPtr = &procList; - for (infoPtr = procList; infoPtr != NULL; - prevPtrPtr = &infoPtr->nextPtr, infoPtr = infoPtr->nextPtr) { - if (infoPtr->hProcess == (HANDLE) pid) { - *prevPtrPtr = infoPtr->nextPtr; + while (!done) { + /* + * Wait for the main thread to signal before attempting to write. + */ + if (!TclPipeThreadWaitForSignal(&pipeTI)) { + /* exit */ + if (writable) { + SetEvent(writable); + } break; } - } - Tcl_MutexUnlock(&pipeMutex); - - /* - * If the pid is not one of the processes we know about (we started it) - * then do nothing. - */ - if (infoPtr == NULL) { - *statPtr = 0; - return 0; - } + if (!infoPtr) { + infoPtr = (PipeInfo *)pipeTI->clientData; + handle = ((WinFile *) infoPtr->writeFile)->handle; + writable = infoPtr->writable; + } - /* - * Officially "wait" for it to finish. We either poll (WNOHANG) or wait - * for an infinite amount of time. - */ + buf = infoPtr->writeBuf; + toWrite = infoPtr->toWrite; - if (options & WNOHANG) { - flags = 0; - } else { - flags = INFINITE; - } - ret = WaitForSingleObject(infoPtr->hProcess, flags); - if (ret == WAIT_TIMEOUT) { - *statPtr = 0; - if (options & WNOHANG) { - /* - * Re-insert this infoPtr back on the list. - */ + /* + * Loop until all of the bytes are written or an error occurs. + */ - Tcl_MutexLock(&pipeMutex); - infoPtr->nextPtr = procList; - procList = infoPtr; - Tcl_MutexUnlock(&pipeMutex); - return 0; - } else { - result = 0; + while (toWrite > 0) { + if (WriteFile(handle, buf, toWrite, &count, NULL) == FALSE) { + infoPtr->writeError = GetLastError(); + done = 1; + break; + } else { + toWrite -= count; + buf += count; + } } - } else if (ret == WAIT_OBJECT_0) { - GetExitCodeProcess(infoPtr->hProcess, &exitCode); /* - * Does the exit code look like one of the exception codes? + * Signal the main thread by signalling the writable event and then + * waking up the notifier thread. */ - switch (exitCode) { - case EXCEPTION_FLT_DENORMAL_OPERAND: - case EXCEPTION_FLT_DIVIDE_BY_ZERO: - case EXCEPTION_FLT_INEXACT_RESULT: - case EXCEPTION_FLT_INVALID_OPERATION: - case EXCEPTION_FLT_OVERFLOW: - case EXCEPTION_FLT_STACK_CHECK: - case EXCEPTION_FLT_UNDERFLOW: - case EXCEPTION_INT_DIVIDE_BY_ZERO: - case EXCEPTION_INT_OVERFLOW: - *statPtr = 0xC0000000 | SIGFPE; - break; - - case EXCEPTION_PRIV_INSTRUCTION: - case EXCEPTION_ILLEGAL_INSTRUCTION: - *statPtr = 0xC0000000 | SIGILL; - break; - - case EXCEPTION_ACCESS_VIOLATION: - case EXCEPTION_ARRAY_BOUNDS_EXCEEDED: - case EXCEPTION_STACK_OVERFLOW: - case EXCEPTION_NONCONTINUABLE_EXCEPTION: - case EXCEPTION_INVALID_DISPOSITION: - case EXCEPTION_GUARD_PAGE: - case EXCEPTION_INVALID_HANDLE: - *statPtr = 0xC0000000 | SIGSEGV; - break; - - case EXCEPTION_DATATYPE_MISALIGNMENT: - *statPtr = 0xC0000000 | SIGBUS; - break; - - case EXCEPTION_BREAKPOINT: - case EXCEPTION_SINGLE_STEP: - *statPtr = 0xC0000000 | SIGTRAP; - break; + SetEvent(writable); - case CONTROL_C_EXIT: - *statPtr = 0xC0000000 | SIGINT; - break; + /* + * Alert the foreground thread. Note that we need to treat this like a + * critical section so the foreground thread does not terminate this + * thread while we are holding a mutex in the notifier code. + */ - default: + Tcl_MutexLock(&pipeMutex); + if (infoPtr->threadId != NULL) { /* - * Non-exceptional, normal, exit code. Note that the exit code is - * truncated to a signed short range [-32768,32768) whether it - * fits into this range or not. - * - * BUG: Even though the exit code is a DWORD, it is understood by - * convention to be a signed integer, yet there isn't enough room - * to fit this into the POSIX style waitstatus mask without - * truncating it. + * TIP #218. When in flight ignore the event, no one will receive + * it anyway. */ - *statPtr = exitCode; - break; + Tcl_ThreadAlert(infoPtr->threadId); } - result = pid; - } else { - errno = ECHILD; - *statPtr = 0xC0000000 | ECHILD; - result = (Tcl_Pid) -1; + Tcl_MutexUnlock(&pipeMutex); } /* - * Officially close the process handle. + * If state of thread was set to stop, we can sane free info structure, + * otherwise it is shared with main thread, so main thread will own it. */ + TclPipeThreadExit(&pipeTI); - CloseHandle(infoPtr->hProcess); - ckfree(infoPtr); - - return result; + return 0; } /* *---------------------------------------------------------------------- * - * TclWinAddProcess -- + * PipeThreadActionProc -- * - * Add a process to the process list so that we can use Tcl_WaitPid on - * the process. + * Insert or remove any thread local refs to this channel. * * Results: - * None + * None. * * Side effects: - * Adds the specified process handle to the process list so Tcl_WaitPid - * knows about it. + * Changes thread local list of valid channels. * *---------------------------------------------------------------------- */ -void -TclWinAddProcess( - void *hProcess, /* Handle to process */ - unsigned long id) /* Global process identifier */ +static void +PipeThreadActionProc( + ClientData instanceData, + int action) { - ProcInfo *procPtr = ckalloc(sizeof(ProcInfo)); + PipeInfo *infoPtr = (PipeInfo *) instanceData; - PipeInit(); + /* + * We do not access firstPipePtr in the thread structures. This is not for + * all pipes managed by the thread, but only those we are watching. + * Removal of the filevent handlers before transfer thus takes care of + * this structure. + */ - procPtr->hProcess = hProcess; - procPtr->dwProcessId = id; Tcl_MutexLock(&pipeMutex); - procPtr->nextPtr = procList; - procList = procPtr; - Tcl_MutexUnlock(&pipeMutex); -} - -/* - *---------------------------------------------------------------------- - * - * Tcl_PidObjCmd -- - * - * This function is invoked to process the "pid" Tcl command. See the - * user documentation for details on what it does. - * - * Results: - * A standard Tcl result. - * - * Side effects: - * See the user documentation. - * - *---------------------------------------------------------------------- - */ - - /* ARGSUSED */ -int -Tcl_PidObjCmd( - ClientData dummy, /* Not used. */ - Tcl_Interp *interp, /* Current interpreter. */ - int objc, /* Number of arguments. */ - Tcl_Obj *const *objv) /* Argument strings. */ -{ - Tcl_Channel chan; - const Tcl_ChannelType *chanTypePtr; - PipeInfo *pipePtr; - int i; - Tcl_Obj *resultPtr; - - if (objc > 2) { - Tcl_WrongNumArgs(interp, 1, objv, "?channelId?"); - return TCL_ERROR; - } - if (objc == 1) { - Tcl_SetObjResult(interp, Tcl_NewWideIntObj((unsigned) getpid())); - } else { - chan = Tcl_GetChannel(interp, Tcl_GetString(objv[1]), - NULL); - if (chan == (Tcl_Channel) NULL) { - return TCL_ERROR; - } - chanTypePtr = Tcl_GetChannelType(chan); - if (chanTypePtr != &pipeChannelType) { - return TCL_OK; - } + if (action == TCL_CHANNEL_THREAD_INSERT) { + /* + * We can't copy the thread information from the channel when the + * channel is created. At this time the channel back pointer has not + * been set yet. However in that case the threadId has already been + * set by TclpCreateCommandChannel itself, so the structure is still + * good. + */ - pipePtr = (PipeInfo *) Tcl_GetChannelInstanceData(chan); - resultPtr = Tcl_NewObj(); - for (i = 0; i < pipePtr->numPids; i++) { - Tcl_ListObjAppendElement(/*interp*/ NULL, resultPtr, - Tcl_NewWideIntObj((unsigned) - TclpGetPid(pipePtr->pidPtr[i]))); + PipeInit(); + if (infoPtr->channel != NULL) { + infoPtr->threadId = Tcl_GetChannelThread(infoPtr->channel); } - Tcl_SetObjResult(interp, resultPtr); + } else { + infoPtr->threadId = NULL; } - return TCL_OK; + Tcl_MutexUnlock(&pipeMutex); } /* *---------------------------------------------------------------------- * - * WaitForRead -- + * TclpOpenTemporaryFile -- * - * Wait until some data is available, the pipe is at EOF or the reader - * thread is blocked waiting for data (if the channel is in non-blocking - * mode). + * Creates a temporary file, possibly based on the supplied bits and + * pieces of template supplied in the first three arguments. If the + * fourth argument is non-NULL, it contains a Tcl_Obj to store the name + * of the temporary file in (and it is caller's responsibility to clean + * up). If the fourth argument is NULL, try to arrange for the temporary + * file to go away once it is no longer needed. * * Results: - * Returns 1 if pipe is readable. Returns 0 if there is no data on the - * pipe, but there is buffered data. Returns -1 if an error occurred. If - * an error occurred, the threads may not be synchronized. - * - * Side effects: - * Updates the shared state flags and may consume 1 byte of data from the - * pipe. If no error occurred, the reader thread is blocked waiting for a - * signal from the main thread. + * A read-write Tcl Channel open on the file. * *---------------------------------------------------------------------- */ -static int -WaitForRead( - PipeInfo *infoPtr, /* Pipe state. */ - int blocking) /* Indicates whether call should be blocking - * or not. */ +Tcl_Channel +TclpOpenTemporaryFile( + Tcl_Obj *dirObj, + Tcl_Obj *basenameObj, + Tcl_Obj *extensionObj, + Tcl_Obj *resultingNameObj) { - DWORD timeout, count; - HANDLE *handle = ((WinFile *) infoPtr->readFile)->handle; - - while (1) { - /* - * Synchronize with the reader thread. - */ - - timeout = blocking ? INFINITE : 0; - if (WaitForSingleObject(infoPtr->readable, timeout) == WAIT_TIMEOUT) { - /* - * The reader thread is blocked waiting for data and the channel - * is in non-blocking mode. - */ - - errno = EWOULDBLOCK; - return -1; - } - - /* - * At this point, the two threads are synchronized, so it is safe to - * access shared state. - */ - - /* - * If the pipe has hit EOF, it is always readable. - */ - - if (infoPtr->readFlags & PIPE_EOF) { - return 1; - } + TCHAR name[MAX_PATH]; + char *namePtr; + HANDLE handle; + DWORD flags = FILE_ATTRIBUTE_TEMPORARY; + int length, counter, counter2; + Tcl_DString buf; - /* - * Check to see if there is any data sitting in the pipe. - */ + if (!resultingNameObj) { + flags |= FILE_FLAG_DELETE_ON_CLOSE; + } - if (PeekNamedPipe(handle, (LPVOID) NULL, (DWORD) 0, - (LPDWORD) NULL, &count, (LPDWORD) NULL) != TRUE) { - TclWinConvertError(GetLastError()); + namePtr = (char *) name; + length = GetTempPath(MAX_PATH, name); + if (length == 0) { + goto gotError; + } + namePtr += length * sizeof(TCHAR); + if (basenameObj) { + const char *string = Tcl_GetString(basenameObj); - /* - * Check to see if the peek failed because of EOF. - */ + Tcl_WinUtfToTChar(string, basenameObj->length, &buf); + memcpy(namePtr, Tcl_DStringValue(&buf), Tcl_DStringLength(&buf)); + namePtr += Tcl_DStringLength(&buf); + Tcl_DStringFree(&buf); + } else { + const TCHAR *baseStr = TEXT("TCL"); + int length = 3 * sizeof(TCHAR); - if (errno == EPIPE) { - infoPtr->readFlags |= PIPE_EOF; - return 1; - } + memcpy(namePtr, baseStr, length); + namePtr += length; + } + counter = TclpGetClicks() % 65533; + counter2 = 1024; /* Only try this many times! Prevents + * an infinite loop. */ - /* - * Ignore errors if there is data in the buffer. - */ + do { + char number[TCL_INTEGER_SPACE + 4]; - if (infoPtr->readFlags & PIPE_EXTRABYTE) { - return 0; - } else { - return -1; - } - } + sprintf(number, "%d.TMP", counter); + counter = (unsigned short) (counter + 1); + Tcl_WinUtfToTChar(number, strlen(number), &buf); + Tcl_DStringSetLength(&buf, Tcl_DStringLength(&buf) + 1); + memcpy(namePtr, Tcl_DStringValue(&buf), Tcl_DStringLength(&buf) + 1); + Tcl_DStringFree(&buf); - /* - * We found some data in the pipe, so it must be readable. - */ + handle = CreateFile(name, + GENERIC_READ|GENERIC_WRITE, 0, NULL, CREATE_NEW, flags, NULL); + } while (handle == INVALID_HANDLE_VALUE + && --counter2 > 0 + && GetLastError() == ERROR_FILE_EXISTS); + if (handle == INVALID_HANDLE_VALUE) { + goto gotError; + } - if (count > 0) { - return 1; - } + if (resultingNameObj) { + Tcl_Obj *tmpObj = TclpNativeToNormalized(name); - /* - * The pipe isn't readable, but there is some data sitting in the - * buffer, so return immediately. - */ + Tcl_AppendObjToObj(resultingNameObj, tmpObj); + TclDecrRefCount(tmpObj); + } - if (infoPtr->readFlags & PIPE_EXTRABYTE) { - return 0; - } + return Tcl_MakeFileChannel((ClientData) handle, + TCL_READABLE|TCL_WRITABLE); - /* - * There wasn't any data available, so reset the thread and try again. - */ + gotError: + TclWinConvertError(GetLastError()); + return NULL; +} + +/* + *---------------------------------------------------------------------- + * + * TclPipeThreadCreateTI -- + * + * Creates a thread info structure, can be owned by worker. + * + * Results: + * Pointer to created TI structure. + * + *---------------------------------------------------------------------- + */ - ResetEvent(infoPtr->readable); - PipeThreadSignal(&infoPtr->readTI); - } +TclPipeThreadInfo * +TclPipeThreadCreateTI( + TclPipeThreadInfo **pipeTIPtr, + ClientData clientData) +{ + TclPipeThreadInfo *pipeTI; +#ifndef _PTI_USE_CKALLOC + pipeTI = malloc(sizeof(TclPipeThreadInfo)); +#else + pipeTI = ckalloc(sizeof(TclPipeThreadInfo)); +#endif + pipeTI->evControl = CreateEvent(NULL, FALSE, FALSE, NULL); + pipeTI->state = PTI_STATE_IDLE; + pipeTI->clientData = clientData; + return (*pipeTIPtr = pipeTI); } /* *---------------------------------------------------------------------- * - * PipeReaderThread -- + * TclPipeThreadWaitForSignal -- * - * This function runs in a separate thread and waits for input to become - * available on a pipe. + * Wait for work/stop signals inside pipe worker. * * Results: - * None. + * 1 if signaled to work, 0 if signaled to stop. * * Side effects: - * Signals the main thread when input become available. May cause the - * main thread to wake up by posting a message. May consume one byte from - * the pipe for each wait operation. Will cause a memory leak of ~4k, if - * forcefully terminated with TerminateThread(). + * If this function returns 0, TI-structure pointer given via pipeTIPtr + * may be NULL, so not accessible (can be owned by main thread). * *---------------------------------------------------------------------- */ -static DWORD WINAPI -PipeReaderThread( - LPVOID arg) +int +TclPipeThreadWaitForSignal( + TclPipeThreadInfo **pipeTIPtr) { - PipeThreadInfo *pipeTI = (PipeThreadInfo *)arg; - PipeInfo *infoPtr = NULL; /* access info only after success init/wait */ - HANDLE handle = NULL; - DWORD count, err; - int done = 0; - - while (!done) { - /* - * Wait for the main thread to signal before attempting to wait on the - * pipe becoming readable. - */ - if (!PipeThreadWaitForSignal(&pipeTI)) { - /* exit */ - break; - } - - if (!infoPtr) { - infoPtr = (PipeInfo *)pipeTI->clientData; - handle = ((WinFile *) infoPtr->readFile)->handle; - } - - /* - * Try waiting for 0 bytes. This will block until some data is - * available on NT, but will return immediately on Win 95. So, if no - * data is available after the first read, we block until we can read - * a single byte off of the pipe. - */ - - if (ReadFile(handle, NULL, 0, &count, NULL) == FALSE || - PeekNamedPipe(handle, NULL, 0, NULL, &count, NULL) == FALSE) { - /* - * The error is a result of an EOF condition, so set the EOF bit - * before signalling the main thread. - */ - - err = GetLastError(); - if (err == ERROR_BROKEN_PIPE) { - infoPtr->readFlags |= PIPE_EOF; - done = 1; - } else if (err == ERROR_INVALID_HANDLE) { - break; - } - } else if (count == 0) { - if (ReadFile(handle, &(infoPtr->extraByte), 1, &count, NULL) - != FALSE) { - /* - * One byte was consumed as a side effect of waiting for the - * pipe to become readable. - */ - - infoPtr->readFlags |= PIPE_EXTRABYTE; - } else { - err = GetLastError(); - if (err == ERROR_BROKEN_PIPE) { - /* - * The error is a result of an EOF condition, so set the - * EOF bit before signalling the main thread. - */ + TclPipeThreadInfo *pipeTI = *pipeTIPtr; + LONG state; + DWORD waitResult; - infoPtr->readFlags |= PIPE_EOF; - done = 1; - } else if (err == ERROR_INVALID_HANDLE) { - break; - } - } - } + if (!pipeTI) { + return 0; + } + /* + * Wait for the main thread to signal before attempting to do the work. + */ - /* - * Signal the main thread by signalling the readable event and then - * waking up the notifier thread. - */ + /* reset work state of thread (idle/waiting) */ + if ((state = InterlockedCompareExchange(&pipeTI->state, + PTI_STATE_IDLE, PTI_STATE_WORK)) & (PTI_STATE_STOP|PTI_STATE_END)) { + /* end of work, check the owner of structure */ + goto end; + } + /* entering wait */ + waitResult = WaitForSingleObject(pipeTI->evControl, INFINITE); - SetEvent(infoPtr->readable); + if (waitResult != WAIT_OBJECT_0) { /* - * Alert the foreground thread. Note that we need to treat this like a - * critical section so the foreground thread does not terminate this - * thread while we are holding a mutex in the notifier code. + * The control event was not signaled, so end of work (unexpected + * behaviour, main thread can be dead?). */ + goto end; + } - Tcl_MutexLock(&pipeMutex); - if (infoPtr->threadId != NULL) { - /* - * TIP #218. When in flight ignore the event, no one will receive - * it anyway. - */ - - Tcl_ThreadAlert(infoPtr->threadId); - } - Tcl_MutexUnlock(&pipeMutex); + /* try to set work state of thread */ + if ((state = InterlockedCompareExchange(&pipeTI->state, + PTI_STATE_WORK, PTI_STATE_IDLE)) & (PTI_STATE_STOP|PTI_STATE_END)) { + /* end of work */ + goto end; } - /* - * If state of thread was set to stop, we can sane free info structure, - * otherwise it is shared with main thread, so main thread will own it - */ - PipeThreadExit(&pipeTI); + /* signaled to work */ + return 1; +end: + /* end of work, check the owner of the TI structure */ + if (state != PTI_STATE_STOP) { + *pipeTIPtr = NULL; + } return 0; } /* *---------------------------------------------------------------------- * - * PipeWriterThread -- + * TclPipeThreadStopSignal -- * - * This function runs in a separate thread and writes data onto a pipe. + * Send stop signal to the pipe worker (without waiting). * - * Results: - * Always returns 0. + * After calling of this function, TI-structure pointer given via pipeTIPtr + * may be NULL. * - * Side effects: - * Signals the main thread when an output operation is completed. May - * cause the main thread to wake up by posting a message. + * Results: + * 1 if signaled (or pipe-thread is down), 0 if pipe thread still working. * *---------------------------------------------------------------------- */ -static DWORD WINAPI -PipeWriterThread( - LPVOID arg) +int +TclPipeThreadStopSignal( + TclPipeThreadInfo **pipeTIPtr) { - PipeThreadInfo *pipeTI = (PipeThreadInfo *)arg; - PipeInfo *infoPtr = NULL; /* access info only after success init/wait */ - HANDLE handle = NULL, writable = NULL; - DWORD count, toWrite; - char *buf; - int done = 0; - - while (!done) { - /* - * Wait for the main thread to signal before attempting to write. - */ - if (!PipeThreadWaitForSignal(&pipeTI)) { - /* exit */ - if (writable) { - SetEvent(writable); - } - break; - } - - if (!infoPtr) { - infoPtr = (PipeInfo *)pipeTI->clientData; - handle = ((WinFile *) infoPtr->writeFile)->handle; - writable = infoPtr->writable; - } - - buf = infoPtr->writeBuf; - toWrite = infoPtr->toWrite; + TclPipeThreadInfo *pipeTI = *pipeTIPtr; + HANDLE evControl; + int state; - /* - * Loop until all of the bytes are written or an error occurs. - */ + if (!pipeTI) { + return 1; + } + evControl = pipeTI->evControl; + switch ( + (state = InterlockedCompareExchange(&pipeTI->state, + PTI_STATE_STOP, PTI_STATE_IDLE)) + ) { - while (toWrite > 0) { - if (WriteFile(handle, buf, toWrite, &count, NULL) == FALSE) { - infoPtr->writeError = GetLastError(); - done = 1; - break; - } else { - toWrite -= count; - buf += count; - } - } + case PTI_STATE_IDLE: - /* - * Signal the main thread by signalling the writable event and then - * waking up the notifier thread. - */ + /* Thread was idle/waiting, notify it goes teardown */ + SetEvent(evControl); - SetEvent(writable); + *pipeTIPtr = NULL; - /* - * Alert the foreground thread. Note that we need to treat this like a - * critical section so the foreground thread does not terminate this - * thread while we are holding a mutex in the notifier code. - */ + case PTI_STATE_DOWN: + + return 1; - Tcl_MutexLock(&pipeMutex); - if (infoPtr->threadId != NULL) { + default: /* - * TIP #218. When in flight ignore the event, no one will receive - * it anyway. + * Thread works currently, we should try to end it, own the TI structure + * (because of possible sharing the joint structures with thread) */ - - Tcl_ThreadAlert(infoPtr->threadId); - } - Tcl_MutexUnlock(&pipeMutex); + InterlockedExchange(&pipeTI->state, PTI_STATE_END); + break; } - /* - * If state of thread was set to stop, we can sane free info structure, - * otherwise it is shared with main thread, so main thread will own it. - */ - PipeThreadExit(&pipeTI); - return 0; } /* *---------------------------------------------------------------------- * - * PipeThreadActionProc -- + * TclPipeThreadStop -- + * + * Send stop signal to the pipe worker and wait for thread completion. * - * Insert or remove any thread local refs to this channel. + * May be combined with TclPipeThreadStopSignal. + * + * After calling of this function, TI-structure pointer given via pipeTIPtr + * is not accessible (owned by pipe worker or released here). * * Results: * None. * * Side effects: - * Changes thread local list of valid channels. + * Can terminate pipe worker (and / or stop its synchronous operations). * *---------------------------------------------------------------------- */ -static void -PipeThreadActionProc( - ClientData instanceData, - int action) +void +TclPipeThreadStop( + TclPipeThreadInfo **pipeTIPtr, + HANDLE hThread) { - PipeInfo *infoPtr = (PipeInfo *) instanceData; + TclPipeThreadInfo *pipeTI = *pipeTIPtr; + HANDLE evControl; + int state; + if (!pipeTI) { + return; + } + pipeTI = *pipeTIPtr; + evControl = pipeTI->evControl; /* - * We do not access firstPipePtr in the thread structures. This is not for - * all pipes managed by the thread, but only those we are watching. - * Removal of the filevent handlers before transfer thus takes care of - * this structure. + * Try to sane stop the pipe worker, corresponding its current state */ + switch ( + (state = InterlockedCompareExchange(&pipeTI->state, + PTI_STATE_STOP, PTI_STATE_IDLE)) + ) { - Tcl_MutexLock(&pipeMutex); - if (action == TCL_CHANNEL_THREAD_INSERT) { + case PTI_STATE_IDLE: + + /* Thread was idle/waiting, notify it goes teardown */ + SetEvent(evControl); + + /* we don't need to wait for it at all, thread frees himself (owns the TI structure) */ + pipeTI = NULL; + break; + + case PTI_STATE_STOP: + /* already stopped, thread frees himself (owns the TI structure) */ + pipeTI = NULL; + break; + case PTI_STATE_DOWN: + /* Thread already down (?), do nothing */ + + /* we don't need to wait for it, but we should free pipeTI */ + hThread = NULL; + break; + + /* case PTI_STATE_WORK: */ + default: + /* + * Thread works currently, we should try to end it, own the TI structure + * (because of possible sharing the joint structures with thread) + */ + InterlockedExchange(&pipeTI->state, PTI_STATE_END); + break; + } + + if (pipeTI && hThread) { + DWORD exitCode; + /* - * We can't copy the thread information from the channel when the - * channel is created. At this time the channel back pointer has not - * been set yet. However in that case the threadId has already been - * set by TclpCreateCommandChannel itself, so the structure is still - * good. + * The thread may already have closed on its own. Check its exit + * code. */ - PipeInit(); - if (infoPtr->channel != NULL) { - infoPtr->threadId = Tcl_GetChannelThread(infoPtr->channel); + GetExitCodeThread(hThread, &exitCode); + + if (exitCode == STILL_ACTIVE) { + /* + * Set the stop event so that if the pipe thread is blocked + * somewhere, it may hereafter sane exit cleanly. + */ + + SetEvent(evControl); + + /* + * Cancel all sync-IO of this thread (may be blocked there). + */ + if (tclWinProcs->cancelSynchronousIo) { + tclWinProcs->cancelSynchronousIo(hThread); + } + + /* + * Wait at most 20 milliseconds for the reader thread to + * close (regarding TIP#398-fast-exit). + */ + + /* if we want TIP#398-fast-exit. */ + if (WaitForSingleObject(hThread, + TclInExit() ? 0 : 20) == WAIT_TIMEOUT) { + + /* + * The thread must be blocked waiting for the pipe to + * become readable in ReadFile(). There isn't a clean way + * to exit the thread from this condition. We should + * terminate the child process instead to get the reader + * thread to fall out of ReadFile with a FALSE. (below) is + * not the correct way to do this, but will stay here + * until a better solution is found. + * + * Note that we need to guard against terminating the + * thread while it is in the middle of Tcl_ThreadAlert + * because it won't be able to release the notifier lock. + * + * Also note that terminating threads during their initialization or teardown phase + * may result in ntdll.dll's LoaderLock to remain locked indefinitely. + * This causes ntdll.dll's LdrpInitializeThread() to deadlock trying to acquire LoaderLock. + * LdrpInitializeThread() is executed within new threads to perform + * initialization and to execute DllMain() of all loaded dlls. + * As a result, all new threads are deadlocked in their initialization phase and never execute, + * even though CreateThread() reports successful thread creation. + * This results in a very weird process-wide behavior, which is extremely hard to debug. + * + * THREADS SHOULD NEVER BE TERMINATED. Period. + * + * But for now, check if thread is exiting, and if so, let it die peacefully. + */ + + if ( pipeTI->state != PTI_STATE_DOWN + && WaitForSingleObject(hThread, + TclInExit() ? 0 : 5000) != WAIT_OBJECT_0 + ) { + Tcl_MutexLock(&pipeMutex); + /* BUG: this leaks memory */ + if (!TerminateThread(hThread, 0)) { + /* terminate fails, just give thread a chance to exit */ + if (InterlockedExchange(&pipeTI->state, + PTI_STATE_STOP) != PTI_STATE_DOWN) { + pipeTI = NULL; + } + }; + Tcl_MutexUnlock(&pipeMutex); + } + } } - } else { - infoPtr->threadId = NULL; } - Tcl_MutexUnlock(&pipeMutex); + + *pipeTIPtr = NULL; + if (pipeTI) { + CloseHandle(pipeTI->evControl); + #ifndef _PTI_USE_CKALLOC + free(pipeTI); + #else + ckfree(pipeTI); + #endif + } } /* *---------------------------------------------------------------------- * - * TclpOpenTemporaryFile -- + * TclPipeThreadExit -- * - * Creates a temporary file, possibly based on the supplied bits and - * pieces of template supplied in the first three arguments. If the - * fourth argument is non-NULL, it contains a Tcl_Obj to store the name - * of the temporary file in (and it is caller's responsibility to clean - * up). If the fourth argument is NULL, try to arrange for the temporary - * file to go away once it is no longer needed. + * Clean-up for the pipe thread (removes owned TI-structure in worker). + * + * Should be executed on worker exit, to inform the main thread or + * free TI-structure (if owned). + * + * After calling of this function, TI-structure pointer given via pipeTIPtr + * is not accessible (owned by main thread or released here). * * Results: - * A read-write Tcl Channel open on the file. + * None. * *---------------------------------------------------------------------- */ -Tcl_Channel -TclpOpenTemporaryFile( - Tcl_Obj *dirObj, - Tcl_Obj *basenameObj, - Tcl_Obj *extensionObj, - Tcl_Obj *resultingNameObj) +void +TclPipeThreadExit( + TclPipeThreadInfo **pipeTIPtr) { - TCHAR name[MAX_PATH]; - char *namePtr; - HANDLE handle; - DWORD flags = FILE_ATTRIBUTE_TEMPORARY; - int length, counter, counter2; - Tcl_DString buf; - - if (!resultingNameObj) { - flags |= FILE_FLAG_DELETE_ON_CLOSE; - } - - namePtr = (char *) name; - length = GetTempPath(MAX_PATH, name); - if (length == 0) { - goto gotError; - } - namePtr += length * sizeof(TCHAR); - if (basenameObj) { - const char *string = Tcl_GetString(basenameObj); - - Tcl_WinUtfToTChar(string, basenameObj->length, &buf); - memcpy(namePtr, Tcl_DStringValue(&buf), Tcl_DStringLength(&buf)); - namePtr += Tcl_DStringLength(&buf); - Tcl_DStringFree(&buf); - } else { - const TCHAR *baseStr = TEXT("TCL"); - int length = 3 * sizeof(TCHAR); - - memcpy(namePtr, baseStr, length); - namePtr += length; - } - counter = TclpGetClicks() % 65533; - counter2 = 1024; /* Only try this many times! Prevents - * an infinite loop. */ - - do { - char number[TCL_INTEGER_SPACE + 4]; - - sprintf(number, "%d.TMP", counter); - counter = (unsigned short) (counter + 1); - Tcl_WinUtfToTChar(number, strlen(number), &buf); - Tcl_DStringSetLength(&buf, Tcl_DStringLength(&buf) + 1); - memcpy(namePtr, Tcl_DStringValue(&buf), Tcl_DStringLength(&buf) + 1); - Tcl_DStringFree(&buf); - - handle = CreateFile(name, - GENERIC_READ|GENERIC_WRITE, 0, NULL, CREATE_NEW, flags, NULL); - } while (handle == INVALID_HANDLE_VALUE - && --counter2 > 0 - && GetLastError() == ERROR_FILE_EXISTS); - if (handle == INVALID_HANDLE_VALUE) { - goto gotError; + LONG state; + TclPipeThreadInfo *pipeTI = *pipeTIPtr; + /* + * If state of thread was set to stop (exactly), we can sane free its info + * structure, otherwise it is shared with main thread, so main thread will + * own it. + */ + if (!pipeTI) { + return; } - - if (resultingNameObj) { - Tcl_Obj *tmpObj = TclpNativeToNormalized(name); - - Tcl_AppendObjToObj(resultingNameObj, tmpObj); - TclDecrRefCount(tmpObj); + *pipeTIPtr = NULL; + if ((state = InterlockedExchange(&pipeTI->state, + PTI_STATE_DOWN)) == PTI_STATE_STOP) { + CloseHandle(pipeTI->evControl); + #ifndef _PTI_USE_CKALLOC + free(pipeTI); + #else + ckfree(pipeTI); + /* be sure all subsystems used are finalized */ + Tcl_FinalizeThread(); + #endif } - - return Tcl_MakeFileChannel((ClientData) handle, - TCL_READABLE|TCL_WRITABLE); - - gotError: - TclWinConvertError(GetLastError()); - return NULL; } /* -- cgit v0.12 From 9b95c002189e5e5c0a09edb48f595afc8e236dab Mon Sep 17 00:00:00 2001 From: sebres Date: Tue, 11 Apr 2017 18:09:38 +0000 Subject: added wake-up event to prevent possible dead-locks by some waiting thread (e. g. for writable events) --- win/tclWinInt.h | 6 ++++-- win/tclWinPipe.c | 35 +++++++++++++++++++++++------------ 2 files changed, 27 insertions(+), 14 deletions(-) diff --git a/win/tclWinInt.h b/win/tclWinInt.h index 8ce4152..67b00a8 100644 --- a/win/tclWinInt.h +++ b/win/tclWinInt.h @@ -110,6 +110,7 @@ typedef struct TclPipeThreadInfo { * used as signal to stop (state set to -1) */ volatile LONG state; /* Indicates current state of the thread */ ClientData clientData; /* Referenced data of the main thread */ + HANDLE evWakeUp; /* Optional wake-up event worker set by shutdown */ } TclPipeThreadInfo; @@ -134,7 +135,8 @@ typedef struct TclPipeThreadInfo { MODULE_SCOPE -TclPipeThreadInfo * TclPipeThreadCreateTI(TclPipeThreadInfo **pipeTIPtr, ClientData clientData); +TclPipeThreadInfo * TclPipeThreadCreateTI(TclPipeThreadInfo **pipeTIPtr, + ClientData clientData, HANDLE wakeEvent); MODULE_SCOPE int TclPipeThreadWaitForSignal(TclPipeThreadInfo **pipeTIPtr); static inline void @@ -147,7 +149,7 @@ TclPipeThreadSignal( } }; -MODULE_SCOPE int TclPipeThreadStopSignal(TclPipeThreadInfo **pipeTIPtr); +MODULE_SCOPE int TclPipeThreadStopSignal(TclPipeThreadInfo **pipeTIPtr, HANDLE wakeEvent); MODULE_SCOPE void TclPipeThreadStop(TclPipeThreadInfo **pipeTIPtr, HANDLE hThread); MODULE_SCOPE void TclPipeThreadExit(TclPipeThreadInfo **pipeTIPtr); diff --git a/win/tclWinPipe.c b/win/tclWinPipe.c index 4b4e68d..528f950 100644 --- a/win/tclWinPipe.c +++ b/win/tclWinPipe.c @@ -1564,7 +1564,6 @@ TclpCreateCommandChannel( Tcl_Pid *pidPtr) /* An array of process identifiers. */ { char channelName[16 + TCL_INTEGER_SPACE]; - DWORD id; PipeInfo *infoPtr = ckalloc(sizeof(PipeInfo)); PipeInit(); @@ -1593,7 +1592,7 @@ TclpCreateCommandChannel( infoPtr->readable = CreateEvent(NULL, TRUE, TRUE, NULL); infoPtr->readThread = CreateThread(NULL, 256, PipeReaderThread, - TclPipeThreadCreateTI(&infoPtr->readTI, infoPtr), 0, &id); + TclPipeThreadCreateTI(&infoPtr->readTI, infoPtr, NULL), 0, NULL); SetThreadPriority(infoPtr->readThread, THREAD_PRIORITY_HIGHEST); infoPtr->validMask |= TCL_READABLE; } else { @@ -1607,7 +1606,8 @@ TclpCreateCommandChannel( infoPtr->writable = CreateEvent(NULL, TRUE, TRUE, NULL); infoPtr->writeThread = CreateThread(NULL, 256, PipeWriterThread, - TclPipeThreadCreateTI(&infoPtr->writeTI, infoPtr), 0, &id); + TclPipeThreadCreateTI(&infoPtr->writeTI, infoPtr, infoPtr->writable), + 0, NULL); SetThreadPriority(infoPtr->writeThread, THREAD_PRIORITY_HIGHEST); infoPtr->validMask |= TCL_WRITABLE; } else { @@ -1835,7 +1835,7 @@ PipeClose2Proc( if ((pipePtr->flags & PIPE_ASYNC) && TclInExit()) { /* give it a chance to leave honorably */ - TclPipeThreadStopSignal(&pipePtr->writeTI); + TclPipeThreadStopSignal(&pipePtr->writeTI, pipePtr->writable); if (WaitForSingleObject(pipePtr->writable, 20) == WAIT_TIMEOUT) { return EWOULDBLOCK; @@ -2840,7 +2840,7 @@ PipeWriterThread( { TclPipeThreadInfo *pipeTI = (TclPipeThreadInfo *)arg; PipeInfo *infoPtr = NULL; /* access info only after success init/wait */ - HANDLE handle = NULL, writable = NULL; + HANDLE handle = NULL; DWORD count, toWrite; char *buf; int done = 0; @@ -2851,16 +2851,12 @@ PipeWriterThread( */ if (!TclPipeThreadWaitForSignal(&pipeTI)) { /* exit */ - if (writable) { - SetEvent(writable); - } break; } if (!infoPtr) { infoPtr = (PipeInfo *)pipeTI->clientData; handle = ((WinFile *) infoPtr->writeFile)->handle; - writable = infoPtr->writable; } buf = infoPtr->writeBuf; @@ -2886,7 +2882,7 @@ PipeWriterThread( * waking up the notifier thread. */ - SetEvent(writable); + SetEvent(infoPtr->writable); /* * Alert the foreground thread. Note that we need to treat this like a @@ -3075,7 +3071,8 @@ TclpOpenTemporaryFile( TclPipeThreadInfo * TclPipeThreadCreateTI( TclPipeThreadInfo **pipeTIPtr, - ClientData clientData) + ClientData clientData, + HANDLE wakeEvent) { TclPipeThreadInfo *pipeTI; #ifndef _PTI_USE_CKALLOC @@ -3086,6 +3083,7 @@ TclPipeThreadCreateTI( pipeTI->evControl = CreateEvent(NULL, FALSE, FALSE, NULL); pipeTI->state = PTI_STATE_IDLE; pipeTI->clientData = clientData; + pipeTI->evWakeUp = wakeEvent; return (*pipeTIPtr = pipeTI); } @@ -3113,10 +3111,13 @@ TclPipeThreadWaitForSignal( TclPipeThreadInfo *pipeTI = *pipeTIPtr; LONG state; DWORD waitResult; + HANDLE wakeEvent; if (!pipeTI) { return 0; } + + wakeEvent = pipeTI->evWakeUp; /* * Wait for the main thread to signal before attempting to do the work. */ @@ -3153,6 +3154,11 @@ end: /* end of work, check the owner of the TI structure */ if (state != PTI_STATE_STOP) { *pipeTIPtr = NULL; + } else { + pipeTI->evWakeUp = NULL; + } + if (wakeEvent) { + SetEvent(wakeEvent); } return 0; } @@ -3175,7 +3181,7 @@ end: int TclPipeThreadStopSignal( - TclPipeThreadInfo **pipeTIPtr) + TclPipeThreadInfo **pipeTIPtr, HANDLE wakeEvent) { TclPipeThreadInfo *pipeTI = *pipeTIPtr; HANDLE evControl; @@ -3185,6 +3191,7 @@ TclPipeThreadStopSignal( return 1; } evControl = pipeTI->evControl; + pipeTI->evWakeUp = wakeEvent; switch ( (state = InterlockedCompareExchange(&pipeTI->state, PTI_STATE_STOP, PTI_STATE_IDLE)) @@ -3248,6 +3255,7 @@ TclPipeThreadStop( } pipeTI = *pipeTIPtr; evControl = pipeTI->evControl; + pipeTI->evWakeUp = NULL; /* * Try to sane stop the pipe worker, corresponding its current state */ @@ -3414,6 +3422,9 @@ TclPipeThreadExit( if ((state = InterlockedExchange(&pipeTI->state, PTI_STATE_DOWN)) == PTI_STATE_STOP) { CloseHandle(pipeTI->evControl); + if (pipeTI->evWakeUp) { + SetEvent(pipeTI->evWakeUp); + } #ifndef _PTI_USE_CKALLOC free(pipeTI); #else -- cgit v0.12 From 76054b46467848b368ff2641818ca2a72ad2b98e Mon Sep 17 00:00:00 2001 From: sebres Date: Tue, 11 Apr 2017 18:09:52 +0000 Subject: code review, robustness increase, avoid infinite wait by exit, thread exit and by pipes of closed processes); use pipe-helpers (TI-structure handling) for all pipe-workers (tclWinConsole, tclWinSerial); --- win/tclWinConsole.c | 281 ++++++++++++++-------------------------------------- win/tclWinInt.h | 8 ++ win/tclWinPipe.c | 51 ++++++---- win/tclWinSerial.c | 124 +++-------------------- 4 files changed, 132 insertions(+), 332 deletions(-) diff --git a/win/tclWinConsole.c b/win/tclWinConsole.c index da995c5..7a0965d 100644 --- a/win/tclWinConsole.c +++ b/win/tclWinConsole.c @@ -51,16 +51,10 @@ TCL_DECLARE_MUTEX(consoleMutex) typedef struct ConsoleThreadInfo { HANDLE thread; /* Handle to reader or writer thread. */ - int threadExiting; /* Boolean indicating that thread is exiting. */ HANDLE readyEvent; /* Manual-reset event to signal _to_ the main * thread when the worker thread has finished * waiting for its normal work to happen. */ - HANDLE startEvent; /* Auto-reset event used by the main thread to - * signal when the thread should attempt to do - * its normal work. Additionally this event - * used as wait for thread event (init phase). */ - HANDLE stopEvent; /* Auto-reset event used by the main thread to - * signal when the thread should exit. */ + TclPipeThreadInfo *TI; /* Thread info structure of writer and reader. */ } ConsoleThreadInfo; /* @@ -84,16 +78,14 @@ typedef struct ConsoleInfo { * threads. */ ConsoleThreadInfo writer; /* A specialized thread for handling * asynchronous writes to the console; the - * waiting starts when a start event is sent, + * waiting starts when a control event is sent, * and a reset event is sent back to the main - * thread when the write is done. A stop event - * is used to terminate the thread. */ + * thread when the write is done. */ ConsoleThreadInfo reader; /* A specialized thread for handling * asynchronous reads from the console; the - * waiting starts when a start event is sent, + * waiting starts when a control event is sent, * and a reset event is sent back to the main - * thread when input is available. A stop - * event is used to terminate the thread. */ + * thread when input is available. */ DWORD writeError; /* An error caused by the last background * write. Set to 0 if no error has been * detected. This word is shared with the @@ -170,10 +162,6 @@ static BOOL ReadConsoleBytes(HANDLE hConsole, LPVOID lpBuffer, static BOOL WriteConsoleBytes(HANDLE hConsole, const void *lpBuffer, DWORD nbytes, LPDWORD nbyteswritten); -static void StartChannelThread(ConsoleInfo *infoPtr, - ConsoleThreadInfo *threadInfoPtr, - LPTHREAD_START_ROUTINE threadProc); -static void StopChannelThread(ConsoleThreadInfo *threadInfoPtr); /* * This structure describes the channel type structure for command console @@ -520,102 +508,6 @@ ConsoleBlockModeProc( /* *---------------------------------------------------------------------- * - * StartChannelThread, StopChannelThread -- - * - * Helpers that codify how to ask one of the console service threads to - * start and stop. - * - *---------------------------------------------------------------------- - */ - -static void -StartChannelThread( - ConsoleInfo *infoPtr, - ConsoleThreadInfo *threadInfoPtr, - LPTHREAD_START_ROUTINE threadProc) -{ - DWORD id; - - threadInfoPtr->readyEvent = CreateEvent(NULL, TRUE, TRUE, NULL); - threadInfoPtr->startEvent = CreateEvent(NULL, FALSE, FALSE, NULL); - threadInfoPtr->threadExiting = FALSE; - threadInfoPtr->stopEvent = CreateEvent(NULL, FALSE, FALSE, NULL); - threadInfoPtr->thread = CreateThread(NULL, 256, threadProc, infoPtr, 0, - &id); - SetThreadPriority(threadInfoPtr->thread, THREAD_PRIORITY_HIGHEST); -} - -static void -StopChannelThread( - ConsoleThreadInfo *threadInfoPtr) -{ - DWORD exitCode = 0; - - /* - * The thread may already have closed on it's own. Check it's exit - * code. - */ - - GetExitCodeThread(threadInfoPtr->thread, &exitCode); - if (exitCode == STILL_ACTIVE) { - /* - * Set the stop event so that if the reader thread is blocked in - * ConsoleReaderThread on WaitForMultipleEvents, it will exit cleanly. - */ - - SetEvent(threadInfoPtr->stopEvent); - - /* - * Wait at most 20 milliseconds for the reader thread to close. - */ - - if (WaitForSingleObject(threadInfoPtr->thread, 20) == WAIT_TIMEOUT) { - /* - * Forcibly terminate the background thread as a last resort. - * Note that we need to guard against terminating the thread while - * it is in the middle of Tcl_ThreadAlert because it won't be able - * to release the notifier lock. - * - * Also note that terminating threads during their initialization or teardown phase - * may result in ntdll.dll's LoaderLock to remain locked indefinitely. - * This causes ntdll.dll's LdrpInitializeThread() to deadlock trying to acquire LoaderLock. - * LdrpInitializeThread() is executed within new threads to perform - * initialization and to execute DllMain() of all loaded dlls. - * As a result, all new threads are deadlocked in their initialization phase and never execute, - * even though CreateThread() reports successful thread creation. - * This results in a very weird process-wide behavior, which is extremely hard to debug. - * - * THREADS SHOULD NEVER BE TERMINATED. Period. - * - * But for now, check if thread is exiting, and if so, let it die peacefully. - */ - - if ( !threadInfoPtr->threadExiting - || WaitForSingleObject(threadInfoPtr->thread, 5000) != WAIT_OBJECT_0 - ) { - Tcl_MutexLock(&consoleMutex); - /* BUG: this leaks memory. */ - TerminateThread(threadInfoPtr->thread, 0); - Tcl_MutexUnlock(&consoleMutex); - } - } - } - - /* - * Close all the handles associated with the thread, and set the thread - * handle field to NULL to mark that the thread has been cleaned up. - */ - - CloseHandle(threadInfoPtr->thread); - CloseHandle(threadInfoPtr->readyEvent); - CloseHandle(threadInfoPtr->startEvent); - CloseHandle(threadInfoPtr->stopEvent); - threadInfoPtr->thread = NULL; -} - -/* - *---------------------------------------------------------------------- - * * ConsoleCloseProc -- * * Closes a console based IO channel. @@ -646,7 +538,10 @@ ConsoleCloseProc( */ if (consolePtr->reader.thread) { - StopChannelThread(&consolePtr->reader); + TclPipeThreadStop(&consolePtr->reader.TI, consolePtr->reader.thread); + CloseHandle(consolePtr->reader.thread); + CloseHandle(consolePtr->reader.readyEvent); + consolePtr->reader.thread = NULL; } consolePtr->validMask &= ~TCL_READABLE; @@ -663,10 +558,13 @@ ConsoleCloseProc( * prevent infinite wait on exit. [Python Bug 216289] */ - WaitForSingleObject(consolePtr->writer.readyEvent, INFINITE); + WaitForSingleObject(consolePtr->writer.readyEvent, 5000); } - StopChannelThread(&consolePtr->writer); + TclPipeThreadStop(&consolePtr->writer.TI, consolePtr->writer.thread); + CloseHandle(consolePtr->writer.thread); + CloseHandle(consolePtr->writer.readyEvent); + consolePtr->writer.thread = NULL; } consolePtr->validMask &= ~TCL_WRITABLE; @@ -832,8 +730,11 @@ ConsoleOutputProc( DWORD bytesWritten, timeout; *errorCode = 0; - timeout = (infoPtr->flags & CONSOLE_ASYNC) ? 0 : INFINITE; - if (WaitForSingleObject(threadInfo->readyEvent,timeout) == WAIT_TIMEOUT) { + + /* avoid blocking if pipe-thread exited */ + timeout = (infoPtr->flags & CONSOLE_ASYNC) || !TclPipeThreadIsAlive(&threadInfo->TI) + || TclInExit() || TclInThreadExit() ? 0 : INFINITE; + if (WaitForSingleObject(threadInfo->readyEvent, timeout) == WAIT_TIMEOUT) { /* * The writer thread is blocked waiting for a write to complete and * the channel is in non-blocking mode. @@ -873,7 +774,7 @@ ConsoleOutputProc( memcpy(infoPtr->writeBuf, buf, (size_t) toWrite); infoPtr->toWrite = toWrite; ResetEvent(threadInfo->readyEvent); - SetEvent(threadInfo->startEvent); + TclPipeThreadSignal(&threadInfo->TI); bytesWritten = toWrite; } else { /* @@ -1110,9 +1011,10 @@ WaitForRead( * Synchronize with the reader thread. */ - timeout = blocking ? INFINITE : 0; - if (WaitForSingleObject(threadInfo->readyEvent, - timeout) == WAIT_TIMEOUT) { + /* avoid blocking if pipe-thread exited */ + timeout = (!blocking || !TclPipeThreadIsAlive(&threadInfo->TI) + || TclInExit() || TclInThreadExit()) ? 0 : INFINITE; + if (WaitForSingleObject(threadInfo->readyEvent, timeout) == WAIT_TIMEOUT) { /* * The reader thread is blocked waiting for data and the channel * is in non-blocking mode. @@ -1172,7 +1074,7 @@ WaitForRead( */ ResetEvent(threadInfo->readyEvent); - SetEvent(threadInfo->startEvent); + TclPipeThreadSignal(&threadInfo->TI); } } @@ -1199,39 +1101,27 @@ static DWORD WINAPI ConsoleReaderThread( LPVOID arg) { - ConsoleInfo *infoPtr = arg; - HANDLE *handle = infoPtr->handle; - ConsoleThreadInfo *threadInfo = &infoPtr->reader; - DWORD waitResult; - HANDLE wEvents[2]; - - /* - * Notify caller (using startEvent) that this thread is initialized - */ - SignalObjectAndWait(threadInfo->startEvent, threadInfo->stopEvent, INFINITE, FALSE); - - /* - * The first event takes precedence. - */ - - wEvents[0] = threadInfo->stopEvent; - wEvents[1] = threadInfo->startEvent; - - for (;;) { + TclPipeThreadInfo *pipeTI = (TclPipeThreadInfo *)arg; + ConsoleInfo *infoPtr = NULL; /* access info only after success init/wait */ + HANDLE *handle = NULL; + ConsoleThreadInfo *threadInfo = NULL; + int done = 0; + + while (!done) { /* - * Wait for the main thread to signal before attempting to wait. + * Wait for the main thread to signal before attempting to read. */ - waitResult = WaitForMultipleObjects(2, wEvents, FALSE, INFINITE); - - if (waitResult != (WAIT_OBJECT_0 + 1)) { - /* - * The start event was not signaled. It must be the stop event or - * an error, so exit this thread. - */ - + if (!TclPipeThreadWaitForSignal(&pipeTI)) { + /* exit */ break; } + if (!infoPtr) { + infoPtr = (ConsoleInfo *)pipeTI->clientData; + handle = infoPtr->handle; + threadInfo = &infoPtr->reader; + } + /* * Look for data on the console, but first ignore any events that are @@ -1251,6 +1141,7 @@ ConsoleReaderThread( if (err == (DWORD) EOF) { infoPtr->readFlags = CONSOLE_EOF; } + done = 1; } /* @@ -1278,11 +1169,8 @@ ConsoleReaderThread( Tcl_MutexUnlock(&consoleMutex); } - /* - * Inform caller that this thread should not be terminated, since it is about to exit. - * See comment in StopChannelThread() for reasons. - */ - threadInfo->threadExiting = TRUE; + /* Worker exit, so inform the main thread or free TI-structure (if owned) */ + TclPipeThreadExit(&pipeTI); return 0; } @@ -1310,40 +1198,27 @@ static DWORD WINAPI ConsoleWriterThread( LPVOID arg) { - ConsoleInfo *infoPtr = arg; - HANDLE *handle = infoPtr->handle; - ConsoleThreadInfo *threadInfo = &infoPtr->writer; - DWORD count, toWrite, waitResult; + TclPipeThreadInfo *pipeTI = (TclPipeThreadInfo *)arg; + ConsoleInfo *infoPtr = NULL; /* access info only after success init/wait */ + HANDLE *handle = NULL; + ConsoleThreadInfo *threadInfo = NULL; + DWORD count, toWrite; char *buf; - HANDLE wEvents[2]; - - /* - * Notify caller (using startEvent) that this thread is initialized - */ - SignalObjectAndWait(threadInfo->startEvent, threadInfo->stopEvent, INFINITE, FALSE); - - /* - * The first event takes precedence. - */ - - wEvents[0] = threadInfo->stopEvent; - wEvents[1] = threadInfo->startEvent; - - for (;;) { + int done = 0; + + while (!done) { /* * Wait for the main thread to signal before attempting to write. */ - - waitResult = WaitForMultipleObjects(2, wEvents, FALSE, INFINITE); - - if (waitResult != (WAIT_OBJECT_0 + 1)) { - /* - * The start event was not signaled. It must be the stop event or - * an error, so exit this thread. - */ - + if (!TclPipeThreadWaitForSignal(&pipeTI)) { + /* exit */ break; } + if (!infoPtr) { + infoPtr = (ConsoleInfo *)pipeTI->clientData; + handle = infoPtr->handle; + threadInfo = &infoPtr->writer; + } buf = infoPtr->writeBuf; toWrite = infoPtr->toWrite; @@ -1356,6 +1231,7 @@ ConsoleWriterThread( if (WriteConsoleBytes(handle, buf, (DWORD) toWrite, &count) == FALSE) { infoPtr->writeError = GetLastError(); + done = 1; break; } toWrite -= count; @@ -1387,11 +1263,8 @@ ConsoleWriterThread( Tcl_MutexUnlock(&consoleMutex); } - /* - * Inform caller that this thread should not be terminated, since it is about to exit. - * See comment in StopChannelThread() for reasons. - */ - threadInfo->threadExiting = TRUE; + /* Worker exit, so inform the main thread or free TI-structure (if owned) */ + TclPipeThreadExit(&pipeTI); return 0; } @@ -1422,8 +1295,7 @@ TclWinOpenConsoleChannel( { char encoding[4 + TCL_INTEGER_SPACE]; ConsoleInfo *infoPtr; - DWORD modes, wEventsCnt = 0; - HANDLE wEvents[2], wEventsPtr = wEvents; + DWORD modes; ConsoleInit(); @@ -1464,26 +1336,23 @@ TclWinOpenConsoleChannel( modes &= ~(ENABLE_WINDOW_INPUT | ENABLE_MOUSE_INPUT); modes |= ENABLE_LINE_INPUT; SetConsoleMode(infoPtr->handle, modes); - StartChannelThread(infoPtr, &infoPtr->reader, ConsoleReaderThread); - wEvents[wEventsCnt++] = infoPtr->reader.startEvent; + + infoPtr->reader.readyEvent = CreateEvent(NULL, TRUE, TRUE, NULL); + infoPtr->reader.thread = CreateThread(NULL, 256, ConsoleReaderThread, + TclPipeThreadCreateTI(&infoPtr->reader.TI, infoPtr, + infoPtr->reader.readyEvent), 0, NULL); + SetThreadPriority(infoPtr->reader.thread, THREAD_PRIORITY_HIGHEST); } if (permissions & TCL_WRITABLE) { - StartChannelThread(infoPtr, &infoPtr->writer, ConsoleWriterThread); - wEvents[wEventsCnt++] = infoPtr->writer.startEvent; - } - /* - * Wait for both threads to initialize (using theirs startEvent) - */ - if (wEventsCnt) { - WaitForMultipleObjects(wEventsCnt, wEvents, TRUE, 5000); - /* Resume both waiting threads, we've get the events */ - if (infoPtr->reader.thread) - SetEvent(infoPtr->reader.stopEvent); - if (infoPtr->writer.thread) - SetEvent(infoPtr->writer.stopEvent); + infoPtr->writer.readyEvent = CreateEvent(NULL, TRUE, TRUE, NULL); + infoPtr->writer.thread = CreateThread(NULL, 256, ConsoleWriterThread, + TclPipeThreadCreateTI(&infoPtr->writer.TI, infoPtr, + infoPtr->writer.readyEvent), 0, NULL); + SetThreadPriority(infoPtr->writer.thread, THREAD_PRIORITY_HIGHEST); } + /* * Files have default translation of AUTO and ^Z eof char, which means * that a ^Z will be accepted as EOF when reading. diff --git a/win/tclWinInt.h b/win/tclWinInt.h index 67b00a8..86945a9 100644 --- a/win/tclWinInt.h +++ b/win/tclWinInt.h @@ -149,6 +149,14 @@ TclPipeThreadSignal( } }; +static inline int +TclPipeThreadIsAlive( + TclPipeThreadInfo **pipeTIPtr) +{ + TclPipeThreadInfo *pipeTI = *pipeTIPtr; + return (pipeTI && pipeTI->state != PTI_STATE_DOWN); +}; + MODULE_SCOPE int TclPipeThreadStopSignal(TclPipeThreadInfo **pipeTIPtr, HANDLE wakeEvent); MODULE_SCOPE void TclPipeThreadStop(TclPipeThreadInfo **pipeTIPtr, HANDLE hThread); MODULE_SCOPE void TclPipeThreadExit(TclPipeThreadInfo **pipeTIPtr); diff --git a/win/tclWinPipe.c b/win/tclWinPipe.c index 528f950..87ce790 100644 --- a/win/tclWinPipe.c +++ b/win/tclWinPipe.c @@ -1592,7 +1592,8 @@ TclpCreateCommandChannel( infoPtr->readable = CreateEvent(NULL, TRUE, TRUE, NULL); infoPtr->readThread = CreateThread(NULL, 256, PipeReaderThread, - TclPipeThreadCreateTI(&infoPtr->readTI, infoPtr, NULL), 0, NULL); + TclPipeThreadCreateTI(&infoPtr->readTI, infoPtr, infoPtr->readable), + 0, NULL); SetThreadPriority(infoPtr->readThread, THREAD_PRIORITY_HIGHEST); infoPtr->validMask |= TCL_READABLE; } else { @@ -1798,6 +1799,7 @@ PipeClose2Proc( int errorCode, result; PipeInfo *infoPtr, **nextPtrPtr; ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&dataKey); + int inExit = (TclInExit() || TclInThreadExit()); errorCode = 0; result = 0; @@ -1832,7 +1834,7 @@ PipeClose2Proc( * nonblocking or may block during exit, bail out since the worker * thread is not interruptible and we want TIP#398-fast-exit. */ - if ((pipePtr->flags & PIPE_ASYNC) && TclInExit()) { + if ((pipePtr->flags & PIPE_ASYNC) && inExit) { /* give it a chance to leave honorably */ TclPipeThreadStopSignal(&pipePtr->writeTI, pipePtr->writable); @@ -1843,7 +1845,7 @@ PipeClose2Proc( } else { - WaitForSingleObject(pipePtr->writable, INFINITE); + WaitForSingleObject(pipePtr->writable, inExit ? 5000 : INFINITE); } @@ -1885,7 +1887,7 @@ PipeClose2Proc( } } - if ((pipePtr->flags & PIPE_ASYNC) || TclInExit()) { + if ((pipePtr->flags & PIPE_ASYNC) || inExit) { /* * If the channel is non-blocking or Tcl is being cleaned up, just * detach the children PIDs, reap them (important if we are in a @@ -2063,7 +2065,10 @@ PipeOutputProc( DWORD bytesWritten, timeout; *errorCode = 0; - timeout = (infoPtr->flags & PIPE_ASYNC) ? 0 : INFINITE; + + /* avoid blocking if pipe-thread exited */ + timeout = ((infoPtr->flags & PIPE_ASYNC) || !TclPipeThreadIsAlive(&infoPtr->writeTI) + || TclInExit() || TclInThreadExit()) ? 0 : INFINITE; if (WaitForSingleObject(infoPtr->writable, timeout) == WAIT_TIMEOUT) { /* * The writer thread is blocked waiting for a write to complete and @@ -2614,7 +2619,9 @@ WaitForRead( * Synchronize with the reader thread. */ - timeout = blocking ? INFINITE : 0; + /* avoid blocking if pipe-thread exited */ + timeout = (!blocking || !TclPipeThreadIsAlive(&infoPtr->readTI) + || TclInExit() || TclInThreadExit()) ? 0 : INFINITE; if (WaitForSingleObject(infoPtr->readable, timeout) == WAIT_TIMEOUT) { /* * The reader thread is blocked waiting for data and the channel @@ -2756,7 +2763,7 @@ PipeReaderThread( infoPtr->readFlags |= PIPE_EOF; done = 1; } else if (err == ERROR_INVALID_HANDLE) { - break; + done = 1; } } else if (count == 0) { if (ReadFile(handle, &(infoPtr->extraByte), 1, &count, NULL) @@ -2778,7 +2785,7 @@ PipeReaderThread( infoPtr->readFlags |= PIPE_EOF; done = 1; } else if (err == ERROR_INVALID_HANDLE) { - break; + done = 1; } } } @@ -3247,7 +3254,7 @@ TclPipeThreadStop( HANDLE hThread) { TclPipeThreadInfo *pipeTI = *pipeTIPtr; - HANDLE evControl; + HANDLE evControl, wakeEvent; int state; if (!pipeTI) { @@ -3255,6 +3262,7 @@ TclPipeThreadStop( } pipeTI = *pipeTIPtr; evControl = pipeTI->evControl; + wakeEvent = pipeTI->evWakeUp; pipeTI->evWakeUp = NULL; /* * Try to sane stop the pipe worker, corresponding its current state @@ -3290,7 +3298,12 @@ TclPipeThreadStop( * Thread works currently, we should try to end it, own the TI structure * (because of possible sharing the joint structures with thread) */ - InterlockedExchange(&pipeTI->state, PTI_STATE_END); + if ((state = InterlockedCompareExchange(&pipeTI->state, + PTI_STATE_END, PTI_STATE_WORK)) == PTI_STATE_DOWN + ) { + /* we don't need to wait for it, but we should free pipeTI */ + hThread = NULL; + }; break; } @@ -3305,6 +3318,8 @@ TclPipeThreadStop( GetExitCodeThread(hThread, &exitCode); if (exitCode == STILL_ACTIVE) { + + int inExit = (TclInExit() || TclInThreadExit()); /* * Set the stop event so that if the pipe thread is blocked * somewhere, it may hereafter sane exit cleanly. @@ -3325,8 +3340,7 @@ TclPipeThreadStop( */ /* if we want TIP#398-fast-exit. */ - if (WaitForSingleObject(hThread, - TclInExit() ? 0 : 20) == WAIT_TIMEOUT) { + if (WaitForSingleObject(hThread, inExit ? 0 : 20) == WAIT_TIMEOUT) { /* * The thread must be blocked waiting for the pipe to @@ -3353,22 +3367,22 @@ TclPipeThreadStop( * THREADS SHOULD NEVER BE TERMINATED. Period. * * But for now, check if thread is exiting, and if so, let it die peacefully. + * + * Also don't terminate if in exit (otherwise deadlocked in ntdll.dll's). */ if ( pipeTI->state != PTI_STATE_DOWN && WaitForSingleObject(hThread, - TclInExit() ? 0 : 5000) != WAIT_OBJECT_0 + inExit ? 50 : 5000) != WAIT_OBJECT_0 ) { - Tcl_MutexLock(&pipeMutex); /* BUG: this leaks memory */ - if (!TerminateThread(hThread, 0)) { - /* terminate fails, just give thread a chance to exit */ + if (inExit || !TerminateThread(hThread, 0)) { + /* in exit or terminate fails, just give thread a chance to exit */ if (InterlockedExchange(&pipeTI->state, PTI_STATE_STOP) != PTI_STATE_DOWN) { pipeTI = NULL; } }; - Tcl_MutexUnlock(&pipeMutex); } } } @@ -3376,6 +3390,9 @@ TclPipeThreadStop( *pipeTIPtr = NULL; if (pipeTI) { + if (pipeTI->evWakeUp) { + SetEvent(pipeTI->evWakeUp); + } CloseHandle(pipeTI->evControl); #ifndef _PTI_USE_CKALLOC free(pipeTI); diff --git a/win/tclWinSerial.c b/win/tclWinSerial.c index f55f5f1..f78aa5a 100644 --- a/win/tclWinSerial.c +++ b/win/tclWinSerial.c @@ -93,19 +93,12 @@ typedef struct SerialInfo { * threads. */ OVERLAPPED osRead; /* OVERLAPPED structure for read operations. */ OVERLAPPED osWrite; /* OVERLAPPED structure for write operations */ + TclPipeThreadInfo *writeTI; /* Thread info structure of writer worker. */ HANDLE writeThread; /* Handle to writer thread. */ - int writeThreadExiting; /* Boolean indicating that thread is exiting. */ CRITICAL_SECTION csWrite; /* Writer thread synchronisation. */ HANDLE evWritable; /* Manual-reset event to signal when the * writer thread has finished waiting for the * current buffer to be written. */ - HANDLE evStartWriter; /* Auto-reset event used by the main thread to - * signal when the writer thread should - * attempt to write to the serial. Additionally - * this event used as wait for thread event (init). */ - HANDLE evStopWriter; /* Auto-reset event used by the main thread to - * signal when the writer thread should close. - */ DWORD writeError; /* An error caused by the last background * write. Set to 0 if no error has been * detected. This word is shared with the @@ -601,7 +594,6 @@ SerialCloseProc( int errorCode, result = 0; SerialInfo *infoPtr, **nextPtrPtr; ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&dataKey); - DWORD exitCode; errorCode = 0; @@ -611,71 +603,13 @@ SerialCloseProc( } serialPtr->validMask &= ~TCL_READABLE; - if (serialPtr->validMask & TCL_WRITABLE) { - /* - * Generally we cannot wait for a pending write operation because it - * may hang due to handshake - * WaitForSingleObject(serialPtr->evWritable, INFINITE); - */ - - /* - * The thread may have already closed on it's own. Check it's exit - * code. - */ - - GetExitCodeThread(serialPtr->writeThread, &exitCode); - - if (exitCode == STILL_ACTIVE) { - /* - * Set the stop event so that if the writer thread is blocked in - * SerialWriterThread on WaitForMultipleEvents, it will exit - * cleanly. - */ + if (serialPtr->writeThread) { - SetEvent(serialPtr->evStopWriter); + TclPipeThreadStop(&serialPtr->writeTI, serialPtr->writeThread); - /* - * Wait at most 20 milliseconds for the writer thread to close. - */ - - if (WaitForSingleObject(serialPtr->writeThread, - 20) == WAIT_TIMEOUT) { - /* - * Forcibly terminate the background thread as a last resort. - * Note that we need to guard against terminating the thread - * while it is in the middle of Tcl_ThreadAlert because it - * won't be able to release the notifier lock. - * - * Also note that terminating threads during their initialization or teardown phase - * may result in ntdll.dll's LoaderLock to remain locked indefinitely. - * This causes ntdll.dll's LdrpInitializeThread() to deadlock trying to acquire LoaderLock. - * LdrpInitializeThread() is executed within new threads to perform - * initialization and to execute DllMain() of all loaded dlls. - * As a result, all new threads are deadlocked in their initialization phase and never execute, - * even though CreateThread() reports successful thread creation. - * This results in a very weird process-wide behavior, which is extremely hard to debug. - * - * THREADS SHOULD NEVER BE TERMINATED. Period. - * - * But for now, check if thread is exiting, and if so, let it die peacefully. - */ - - if ( !serialPtr->writeThreadExiting - || WaitForSingleObject(serialPtr->writeThread, 5000) != WAIT_OBJECT_0 - ) { - Tcl_MutexLock(&serialMutex); - /* BUG: this leaks memory. */ - TerminateThread(serialPtr->writeThread, 0); - Tcl_MutexUnlock(&serialMutex); - } - } - } - - CloseHandle(serialPtr->writeThread); CloseHandle(serialPtr->osWrite.hEvent); CloseHandle(serialPtr->evWritable); - CloseHandle(serialPtr->evStartWriter); - CloseHandle(serialPtr->evStopWriter); + CloseHandle(serialPtr->writeThread); serialPtr->writeThread = NULL; PurgeComm(serialPtr->handle, PURGE_TXABORT | PURGE_TXCLEAR); @@ -1093,7 +1027,7 @@ SerialOutputProc( memcpy(infoPtr->writeBuf, buf, (size_t) toWrite); infoPtr->toWrite = toWrite; ResetEvent(infoPtr->evWritable); - SetEvent(infoPtr->evStartWriter); + TclPipeThreadSignal(&infoPtr->writeTI); bytesWritten = (DWORD) toWrite; } else { @@ -1330,39 +1264,21 @@ static DWORD WINAPI SerialWriterThread( LPVOID arg) { - SerialInfo *infoPtr = (SerialInfo *)arg; - DWORD bytesWritten, toWrite, waitResult; + TclPipeThreadInfo *pipeTI = (TclPipeThreadInfo *)arg; + SerialInfo *infoPtr = NULL; /* access info only after success init/wait */ + DWORD bytesWritten, toWrite; char *buf; OVERLAPPED myWrite; /* Have an own OVERLAPPED in this thread. */ - HANDLE wEvents[2]; - - /* - * Notify TclWinOpenSerialChannel() that this thread is initialized - */ - SignalObjectAndWait(infoPtr->evStartWriter, infoPtr->evStopWriter, INFINITE, FALSE); - - /* - * The stop event takes precedence by being first in the list. - */ - - wEvents[0] = infoPtr->evStopWriter; - wEvents[1] = infoPtr->evStartWriter; for (;;) { /* * Wait for the main thread to signal before attempting to write. */ - - waitResult = WaitForMultipleObjects(2, wEvents, FALSE, INFINITE); - - if (waitResult != (WAIT_OBJECT_0 + 1)) { - /* - * The start event was not signaled. It might be the stop event or - * an error, so exit. - */ - + if (!TclPipeThreadWaitForSignal(&pipeTI)) { + /* exit */ break; } + infoPtr = (SerialInfo *)pipeTI->clientData; buf = infoPtr->writeBuf; toWrite = infoPtr->toWrite; @@ -1426,11 +1342,8 @@ SerialWriterThread( Tcl_MutexUnlock(&serialMutex); } - /* - * Inform caller that this thread should not be terminated, since it is about to exit. - * See comment in SerialCloseProc() for reasons. - */ - infoPtr->writeThreadExiting = TRUE; + /* Worker exit, so inform the main thread or free TI-structure (if owned) */ + TclPipeThreadExit(&pipeTI); return 0; } @@ -1505,7 +1418,6 @@ TclWinOpenSerialChannel( int permissions) { SerialInfo *infoPtr; - DWORD id; SerialInit(); @@ -1557,15 +1469,9 @@ TclWinOpenSerialChannel( infoPtr->osWrite.hEvent = CreateEvent(NULL, TRUE, FALSE, NULL); infoPtr->evWritable = CreateEvent(NULL, TRUE, TRUE, NULL); - infoPtr->evStartWriter = CreateEvent(NULL, FALSE, FALSE, NULL); - infoPtr->evStopWriter = CreateEvent(NULL, FALSE, FALSE, NULL); - infoPtr->writeThreadExiting = FALSE; infoPtr->writeThread = CreateThread(NULL, 256, SerialWriterThread, - infoPtr, 0, &id); - /* Wait for thread to initialize (using evStartWriter) */ - WaitForSingleObject(infoPtr->evStartWriter, 5000); - /* Wake-up it to signal we've get an event */ - SetEvent(infoPtr->evStopWriter); + TclPipeThreadCreateTI(&infoPtr->writeTI, infoPtr, + infoPtr->evWritable), 0, NULL); } /* -- cgit v0.12 From 85cc06f56cc4b132ed6cd77c097bb83150af55bd Mon Sep 17 00:00:00 2001 From: sebres Date: Tue, 11 Apr 2017 18:10:09 +0000 Subject: improves robustness of the socket tests against busy random ports (fixed sporadic errors "already in use") --- tests/socket.test | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) diff --git a/tests/socket.test b/tests/socket.test index d43c41c..a3e5704 100644 --- a/tests/socket.test +++ b/tests/socket.test @@ -69,7 +69,22 @@ testConstraint exec [llength [info commands exec]] # Produce a random port number in the Dynamic/Private range # from 49152 through 65535. -proc randport {} { expr {int(rand()*16383+49152)} } +proc randport {} { + # firstly try dynamic port via server-socket(0): + set port 0x7fffffff + catch { + set port [lindex [fconfigure [set s [socket -server {} 0]] -sockname] 2] + close $s + } + while {[catch { + close [socket -server {} $port] + } msg]} { + if {[incr i] > 1000} {return -code error "too many iterations to get free random port: $msg"} + # try random port: + set port [expr {int(rand()*16383+49152)}] + } + return $port +} # Test the latency of tcp connections over the loopback interface. Some OSes # (e.g. NetBSD) seem to use the Nagle algorithm and delayed ACKs, so it takes -- cgit v0.12 From 1638a98f0ed7697b66bdba7f4bb6b5b85f8f17e9 Mon Sep 17 00:00:00 2001 From: sebres Date: Tue, 11 Apr 2017 18:13:56 +0000 Subject: fixes sporadically errors in several not event-driven test cases zlib-8.x (wrong non-blocking pipe usage, without fileevent resp. vwait) --- tests/zlib.test | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/tests/zlib.test b/tests/zlib.test index 63bac7e..9f06eb1 100644 --- a/tests/zlib.test +++ b/tests/zlib.test @@ -330,7 +330,7 @@ test zlib-8.9 {transformation and fconfigure} -setup { set strm [zlib stream decompress] } -constraints zlib -body { zlib push compress $outSide -dictionary $spdyDict - fconfigure $outSide -blocking 0 -translation binary -buffering none + fconfigure $outSide -blocking 1 -translation binary -buffering none fconfigure $inSide -blocking 1 -translation binary puts -nonewline $outSide $spdyHeaders set result [fconfigure $outSide -checksum] @@ -347,7 +347,7 @@ test zlib-8.10 {transformation and fconfigure} -setup { lassign [chan pipe] inSide outSide } -constraints {zlib recentZlib} -body { zlib push deflate $outSide -dictionary $spdyDict - fconfigure $outSide -blocking 0 -translation binary -buffering none + fconfigure $outSide -blocking 1 -translation binary -buffering none fconfigure $inSide -blocking 1 -translation binary puts -nonewline $outSide $spdyHeaders chan pop $outSide @@ -369,7 +369,7 @@ test zlib-8.11 {transformation and fconfigure} -setup { set strm [zlib stream inflate] } -constraints zlib -body { zlib push deflate $outSide -dictionary $spdyDict - fconfigure $outSide -blocking 0 -translation binary -buffering none + fconfigure $outSide -blocking 1 -translation binary -buffering none fconfigure $inSide -blocking 1 -translation binary puts -nonewline $outSide $spdyHeaders chan pop $outSide @@ -387,7 +387,7 @@ test zlib-8.12 {transformation and fconfigure} -setup { } -constraints zlib -body { $strm put -dictionary $spdyDict -finalize $spdyHeaders zlib push decompress $inSide - fconfigure $outSide -blocking 0 -translation binary + fconfigure $outSide -blocking 1 -translation binary fconfigure $inSide -translation binary -dictionary $spdyDict puts -nonewline $outSide [$strm get] close $outSide @@ -404,7 +404,7 @@ test zlib-8.13 {transformation and fconfigure} -setup { } -constraints zlib -body { $strm put -dictionary $spdyDict -finalize $spdyHeaders zlib push decompress $inSide -dictionary $spdyDict - fconfigure $outSide -blocking 0 -translation binary + fconfigure $outSide -blocking 1 -translation binary fconfigure $inSide -translation binary puts -nonewline $outSide [$strm get] close $outSide @@ -421,7 +421,7 @@ test zlib-8.14 {transformation and fconfigure} -setup { } -constraints zlib -body { $strm put -finalize -dictionary $spdyDict $spdyHeaders zlib push inflate $inSide - fconfigure $outSide -blocking 0 -buffering none -translation binary + fconfigure $outSide -blocking 1 -buffering none -translation binary fconfigure $inSide -translation binary -dictionary $spdyDict puts -nonewline $outSide [$strm get] close $outSide @@ -437,7 +437,7 @@ test zlib-8.15 {transformation and fconfigure} -setup { } -constraints zlib -body { $strm put -finalize -dictionary $spdyDict $spdyHeaders zlib push inflate $inSide -dictionary $spdyDict - fconfigure $outSide -blocking 0 -buffering none -translation binary + fconfigure $outSide -blocking 1 -buffering none -translation binary fconfigure $inSide -translation binary puts -nonewline $outSide [$strm get] close $outSide -- cgit v0.12 From 1e22d92c69c72995470074b19b377d18ad60b4e6 Mon Sep 17 00:00:00 2001 From: dgp Date: Tue, 11 Apr 2017 19:11:27 +0000 Subject: More changes work --- changes | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/changes b/changes index 68b2fb5..c3a4be3 100644 --- a/changes +++ b/changes @@ -8704,6 +8704,15 @@ improvements to regexp engine from Postgres (lane,porter,fellows,seltenreich) 2016-09-07 (bug)[4dbdd9] Memleak in test var-8.3 (mr_calvin,porter) 2016-10-03 (bug)[2bf561] Allow empty command as alias target (yorick,nijtmans) + *** POTENTIAL INCOMPATIBILITY *** + +2016-10-04 (bug)[4d5ae7] Crash in async connects host no address (gahr,fellows) + +2016-10-08 (bug)[838e99] treat application/xml as text (gahr,fellows) +=> http 2.8.10 + +2016-10-11 (bug)[3cc1d9] Thread finalization crash in zippy (neumann) + -- cgit v0.12 From 0cc7fd3498bf486b2eb5bc20a67f5671f2830097 Mon Sep 17 00:00:00 2001 From: "jan.nijtmans" Date: Wed, 12 Apr 2017 09:23:23 +0000 Subject: Fix sporadically errors in zlib-8.x and socket tests, cherry-picked from "fix-1997007" branch. Credit to "sebres"! --- tests/socket.test | 17 ++++++++++++++++- tests/zlib.test | 14 +++++++------- 2 files changed, 23 insertions(+), 8 deletions(-) diff --git a/tests/socket.test b/tests/socket.test index d43c41c..a3e5704 100644 --- a/tests/socket.test +++ b/tests/socket.test @@ -69,7 +69,22 @@ testConstraint exec [llength [info commands exec]] # Produce a random port number in the Dynamic/Private range # from 49152 through 65535. -proc randport {} { expr {int(rand()*16383+49152)} } +proc randport {} { + # firstly try dynamic port via server-socket(0): + set port 0x7fffffff + catch { + set port [lindex [fconfigure [set s [socket -server {} 0]] -sockname] 2] + close $s + } + while {[catch { + close [socket -server {} $port] + } msg]} { + if {[incr i] > 1000} {return -code error "too many iterations to get free random port: $msg"} + # try random port: + set port [expr {int(rand()*16383+49152)}] + } + return $port +} # Test the latency of tcp connections over the loopback interface. Some OSes # (e.g. NetBSD) seem to use the Nagle algorithm and delayed ACKs, so it takes diff --git a/tests/zlib.test b/tests/zlib.test index 63bac7e..9f06eb1 100644 --- a/tests/zlib.test +++ b/tests/zlib.test @@ -330,7 +330,7 @@ test zlib-8.9 {transformation and fconfigure} -setup { set strm [zlib stream decompress] } -constraints zlib -body { zlib push compress $outSide -dictionary $spdyDict - fconfigure $outSide -blocking 0 -translation binary -buffering none + fconfigure $outSide -blocking 1 -translation binary -buffering none fconfigure $inSide -blocking 1 -translation binary puts -nonewline $outSide $spdyHeaders set result [fconfigure $outSide -checksum] @@ -347,7 +347,7 @@ test zlib-8.10 {transformation and fconfigure} -setup { lassign [chan pipe] inSide outSide } -constraints {zlib recentZlib} -body { zlib push deflate $outSide -dictionary $spdyDict - fconfigure $outSide -blocking 0 -translation binary -buffering none + fconfigure $outSide -blocking 1 -translation binary -buffering none fconfigure $inSide -blocking 1 -translation binary puts -nonewline $outSide $spdyHeaders chan pop $outSide @@ -369,7 +369,7 @@ test zlib-8.11 {transformation and fconfigure} -setup { set strm [zlib stream inflate] } -constraints zlib -body { zlib push deflate $outSide -dictionary $spdyDict - fconfigure $outSide -blocking 0 -translation binary -buffering none + fconfigure $outSide -blocking 1 -translation binary -buffering none fconfigure $inSide -blocking 1 -translation binary puts -nonewline $outSide $spdyHeaders chan pop $outSide @@ -387,7 +387,7 @@ test zlib-8.12 {transformation and fconfigure} -setup { } -constraints zlib -body { $strm put -dictionary $spdyDict -finalize $spdyHeaders zlib push decompress $inSide - fconfigure $outSide -blocking 0 -translation binary + fconfigure $outSide -blocking 1 -translation binary fconfigure $inSide -translation binary -dictionary $spdyDict puts -nonewline $outSide [$strm get] close $outSide @@ -404,7 +404,7 @@ test zlib-8.13 {transformation and fconfigure} -setup { } -constraints zlib -body { $strm put -dictionary $spdyDict -finalize $spdyHeaders zlib push decompress $inSide -dictionary $spdyDict - fconfigure $outSide -blocking 0 -translation binary + fconfigure $outSide -blocking 1 -translation binary fconfigure $inSide -translation binary puts -nonewline $outSide [$strm get] close $outSide @@ -421,7 +421,7 @@ test zlib-8.14 {transformation and fconfigure} -setup { } -constraints zlib -body { $strm put -finalize -dictionary $spdyDict $spdyHeaders zlib push inflate $inSide - fconfigure $outSide -blocking 0 -buffering none -translation binary + fconfigure $outSide -blocking 1 -buffering none -translation binary fconfigure $inSide -translation binary -dictionary $spdyDict puts -nonewline $outSide [$strm get] close $outSide @@ -437,7 +437,7 @@ test zlib-8.15 {transformation and fconfigure} -setup { } -constraints zlib -body { $strm put -finalize -dictionary $spdyDict $spdyHeaders zlib push inflate $inSide -dictionary $spdyDict - fconfigure $outSide -blocking 0 -buffering none -translation binary + fconfigure $outSide -blocking 1 -buffering none -translation binary fconfigure $inSide -translation binary puts -nonewline $outSide [$strm get] close $outSide -- cgit v0.12 -- cgit v0.12 From 9faad3da69bd700e51e75388518f53efd46cb32c Mon Sep 17 00:00:00 2001 From: "jan.nijtmans" Date: Wed, 12 Apr 2017 12:11:12 +0000 Subject: Another attempt to fix the two executable flags. --- library/clock.tcl | 0 win/tclWinFile.c | 0 2 files changed, 0 insertions(+), 0 deletions(-) mode change 100755 => 100644 library/clock.tcl mode change 100755 => 100644 win/tclWinFile.c diff --git a/library/clock.tcl b/library/clock.tcl old mode 100755 new mode 100644 diff --git a/win/tclWinFile.c b/win/tclWinFile.c old mode 100755 new mode 100644 -- cgit v0.12 From 244e69a10ad133c5b1b878b0a8bb22537625762e Mon Sep 17 00:00:00 2001 From: dgp Date: Wed, 12 Apr 2017 13:14:38 +0000 Subject: Revert recent commit [80252e0aed]. TIP 237 is clear that %llu is invalid. --- generic/tclScan.c | 21 ++++++++------------- generic/tclStringObj.c | 14 +++++--------- tests/format.test | 6 ------ tests/scan.test | 13 ------------- 4 files changed, 13 insertions(+), 41 deletions(-) diff --git a/generic/tclScan.c b/generic/tclScan.c index 5ea7e46..3edb8be 100644 --- a/generic/tclScan.c +++ b/generic/tclScan.c @@ -10,7 +10,6 @@ */ #include "tclInt.h" -#include "tommath.h" /* * Flag values used by Tcl_ScanObjCmd. @@ -416,7 +415,14 @@ ValidateFormat( case 'x': case 'X': case 'b': + break; case 'u': + if (flags & SCAN_BIG) { + Tcl_SetObjResult(interp, Tcl_NewStringObj( + "unsigned bignum scans are invalid", -1)); + Tcl_SetErrorCode(interp, "TCL", "FORMAT", "BADUNSIGNED",NULL); + goto error; + } break; /* * Bracket terms need special checking @@ -930,18 +936,7 @@ Tcl_ScanObjCmd( } else { Tcl_SetWideIntObj(objPtr, wideValue); } - } else if (flags & SCAN_BIG) { - if (flags & SCAN_UNSIGNED) { - mp_int big; - if ((Tcl_GetBignumFromObj(interp, objPtr, &big) != TCL_OK) - || (mp_cmp_d(&big, 0) == MP_LT)) { - Tcl_SetObjResult(interp, Tcl_NewStringObj( - "unsigned bignum scans are invalid", -1)); - Tcl_SetErrorCode(interp, "TCL", "FORMAT", "BADUNSIGNED",NULL); - return TCL_ERROR; - } - } - } else { + } else if (!(flags & SCAN_BIG)) { if (TclGetLongFromObj(NULL, objPtr, &value) != TCL_OK) { if (TclGetString(objPtr)[0] == '-') { value = LONG_MIN; diff --git a/generic/tclStringObj.c b/generic/tclStringObj.c index 6cce073..4e19750 100644 --- a/generic/tclStringObj.c +++ b/generic/tclStringObj.c @@ -1943,6 +1943,11 @@ Tcl_AppendFormatToObj( } case 'u': + if (useBig) { + msg = "unsigned bignum format is invalid"; + errCode = "BADUNSIGNED"; + goto errorMsg; + } case 'd': case 'o': case 'x': @@ -1960,15 +1965,6 @@ Tcl_AppendFormatToObj( goto error; } isNegative = (mp_cmp_d(&big, 0) == MP_LT); - if (ch == 'u') { - if (isNegative) { - msg = "unsigned bignum format is invalid"; - errCode = "BADUNSIGNED"; - goto errorMsg; - } else { - ch = 'd'; - } - } #ifndef TCL_WIDE_INT_IS_LONG } else if (useWide) { if (Tcl_GetWideIntFromObj(NULL, segment, &w) != TCL_OK) { diff --git a/tests/format.test b/tests/format.test index dbf6af0..e199398 100644 --- a/tests/format.test +++ b/tests/format.test @@ -528,12 +528,6 @@ test format-17.3 {testing %ld with non-wide} {wideIs64bit} { test format-17.4 {testing %l with non-integer} { format %lf 1 } 1.000000 -test format-17.5 {testing %llu with bignum} { - format %llu 0xabcdef0123456789abcdef -} 207698809136909011942886895 -test format-17.6 {testing %llu with negative number} -body { - format %llu -1 -} -returnCodes 1 -result {unsigned bignum format is invalid} test format-18.1 {do not demote existing numeric values} { set a 0xaaaaaaaa diff --git a/tests/scan.test b/tests/scan.test index 8ddb595..7540c9c 100644 --- a/tests/scan.test +++ b/tests/scan.test @@ -541,19 +541,6 @@ test scan-5.15 {Bug be003d570f} { test scan-5.16 {Bug be003d570f} { scan 0x40 %b } 0 -test scan-5.17 {bigint scanning} -setup { - set a {}; set b {}; set c {}; set d {} -} -body { - list [scan "207698809136909011942886895,207698809136909011942886895,abcdef0123456789abcdef,125715736004432126361152746757" \ - %llu,%lld,%llx,%llo a b c d] $a $b $c $d -} -result {4 207698809136909011942886895 207698809136909011942886895 207698809136909011942886895 207698809136909011942886895} -test scan-5.18 {bigint scanning underflow} -setup { - set a {}; -} -body { - list [scan "-207698809136909011942886895" \ - %llu a] $a -} -returnCodes 1 -result {unsigned bignum scans are invalid} - test scan-6.1 {floating-point scanning} -setup { set a {}; set b {}; set c {}; set d {} -- cgit v0.12 From 5ba18ec98dfa4afe775a3f7a7caa8d55774d907d Mon Sep 17 00:00:00 2001 From: "jan.nijtmans" Date: Wed, 12 Apr 2017 13:43:15 +0000 Subject: If %llu is considered invalid, it means that "%" TCL_LL_MODIFIER "u" cannot be used Tcl_ObjPrintf(), but only in sprintf(). That's unfortunate, clearly an oversight in TIP #237. Conclusion: new TIP must be written to correct this. I'll read a TIP and see what case you have, but TCL_LL_MODIFIER was never meant to play any role in [format] or in Tcl_ObjPrintf(). TCL_LL_MODIFIER exists to help deal with platform differences in sprintf() calls. Tcl_ObjPrintf() in contrast ought to be consistent in its behavior across platforms and should not need such things. If that's false, then fixes to Tcl_ObjPrintf() are in order. --- generic/tclCkalloc.c | 2 +- generic/tclStringObj.c | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/generic/tclCkalloc.c b/generic/tclCkalloc.c index 3484a97..123d872 100644 --- a/generic/tclCkalloc.c +++ b/generic/tclCkalloc.c @@ -859,7 +859,7 @@ MemoryCmd( } if (strcmp(argv[1],"info") == 0) { Tcl_SetObjResult(interp, Tcl_ObjPrintf( - "%-25s %10u\n%-25s %10u\n%-25s %10u\n%-25s %10" TCL_LL_MODIFIER"u\n%-25s %10u\n%-25s %10" TCL_LL_MODIFIER "u\n", + "%-25s %10u\n%-25s %10u\n%-25s %10u\n%-25s %10" TCL_LL_MODIFIER"d\n%-25s %10u\n%-25s %10" TCL_LL_MODIFIER "d\n", "total mallocs", total_mallocs, "total frees", total_frees, "current packets allocated", current_malloc_packets, "current bytes allocated", (Tcl_WideInt)current_bytes_malloced, diff --git a/generic/tclStringObj.c b/generic/tclStringObj.c index 560c169..7c898b7 100644 --- a/generic/tclStringObj.c +++ b/generic/tclStringObj.c @@ -2780,7 +2780,7 @@ TclStringRepeat( if (interp) { Tcl_SetObjResult(interp, Tcl_ObjPrintf( "string size overflow: unable to alloc %" - TCL_LL_MODIFIER "u bytes", + TCL_LL_MODIFIER "d bytes", (Tcl_WideUInt)STRING_SIZE(count*length))); Tcl_SetErrorCode(interp, "TCL", "MEMORY", NULL); } @@ -3004,7 +3004,7 @@ TclStringCatObjv( if (interp) { Tcl_SetObjResult(interp, Tcl_ObjPrintf( "concatenation failed: unable to alloc %" - TCL_LL_MODIFIER "u bytes", + TCL_LL_MODIFIER "d bytes", (Tcl_WideUInt)STRING_SIZE(length))); Tcl_SetErrorCode(interp, "TCL", "MEMORY", NULL); } @@ -3020,7 +3020,7 @@ TclStringCatObjv( if (interp) { Tcl_SetObjResult(interp, Tcl_ObjPrintf( "concatenation failed: unable to alloc %" - TCL_LL_MODIFIER "u bytes", + TCL_LL_MODIFIER "d bytes", (Tcl_WideUInt)STRING_SIZE(length))); Tcl_SetErrorCode(interp, "TCL", "MEMORY", NULL); } -- cgit v0.12 From ea1a2f3fbf4607b58ceffe3606b2d2e7e59e609f Mon Sep 17 00:00:00 2001 From: sebres Date: Wed, 12 Apr 2017 14:52:10 +0000 Subject: [win] fixes "wrong" checking of the flag TCL_CLOSE_READ in close2proc (using mask) --- win/tclWinPipe.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/win/tclWinPipe.c b/win/tclWinPipe.c index 87ce790..d303f8f 100644 --- a/win/tclWinPipe.c +++ b/win/tclWinPipe.c @@ -1804,7 +1804,7 @@ PipeClose2Proc( errorCode = 0; result = 0; - if ((!flags || flags == TCL_CLOSE_READ) && (pipePtr->readFile != NULL)) { + if ((!flags || flags & TCL_CLOSE_READ) && (pipePtr->readFile != NULL)) { /* * Clean up the background thread if necessary. Note that this must be * done before we can close the file, since the thread may be blocking @@ -1824,8 +1824,7 @@ PipeClose2Proc( pipePtr->validMask &= ~TCL_READABLE; pipePtr->readFile = NULL; } - if ((!flags || flags & TCL_CLOSE_WRITE) - && (pipePtr->writeFile != NULL)) { + if ((!flags || flags & TCL_CLOSE_WRITE) && (pipePtr->writeFile != NULL)) { if (pipePtr->writeThread) { /* -- cgit v0.12 From 5b059dfd6b3afbaed367204e6b690a4dafb54908 Mon Sep 17 00:00:00 2001 From: dgp Date: Wed, 12 Apr 2017 20:23:56 +0000 Subject: Bump msgcat and tcl tests and continue updates to changes. --- changes | 12 ++++++++++++ library/msgcat/msgcat.tcl | 2 +- library/msgcat/pkgIndex.tcl | 2 +- library/tcltest/pkgIndex.tcl | 2 +- library/tcltest/tcltest.tcl | 2 +- unix/Makefile.in | 8 ++++---- win/Makefile.in | 8 ++++---- 7 files changed, 24 insertions(+), 12 deletions(-) diff --git a/changes b/changes index c3a4be3..bf25784 100644 --- a/changes +++ b/changes @@ -8713,6 +8713,18 @@ improvements to regexp engine from Postgres (lane,porter,fellows,seltenreich) 2016-10-11 (bug)[3cc1d9] Thread finalization crash in zippy (neumann) +2016-10-12 (bug)[be003d] Fix [scan 0x1 %b], [scan 0x1 %o] (porter) + +2016-10-14 (bug)[eb6b68] Fix stringComp-14.5 (porter) + +2016-10-30 (bug)[b26e38] Fix zlib-7.8 (fellows) + +2016-10-30 (bug)[1ae129] Fix memleak in [history] destruction (fellows) + +2016-11-04 (feature) Provision Tcl 9 support in msgcat and tcltest (nijtmans) +=> msgcat 1.6.1 +=> tcltest 2.4.1 + diff --git a/library/msgcat/msgcat.tcl b/library/msgcat/msgcat.tcl index 928474d..646bc17 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.0 +package provide msgcat 1.6.1 namespace eval msgcat { namespace export mc mcexists mcload mclocale mcmax mcmset mcpreferences mcset\ diff --git a/library/msgcat/pkgIndex.tcl b/library/msgcat/pkgIndex.tcl index 7399c92..7cdb703 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.0 [list source [file join $dir msgcat.tcl]] +package ifneeded msgcat 1.6.1 [list source [file join $dir msgcat.tcl]] diff --git a/library/tcltest/pkgIndex.tcl b/library/tcltest/pkgIndex.tcl index 5ac8823..c9d3759 100644 --- a/library/tcltest/pkgIndex.tcl +++ b/library/tcltest/pkgIndex.tcl @@ -9,4 +9,4 @@ # full path name of this file's directory. if {![package vsatisfies [package provide Tcl] 8.5]} {return} -package ifneeded tcltest 2.4.0 [list source [file join $dir tcltest.tcl]] +package ifneeded tcltest 2.4.1 [list source [file join $dir tcltest.tcl]] diff --git a/library/tcltest/tcltest.tcl b/library/tcltest/tcltest.tcl index 75975d2..f1b6082 100644 --- a/library/tcltest/tcltest.tcl +++ b/library/tcltest/tcltest.tcl @@ -22,7 +22,7 @@ namespace eval tcltest { # When the version number changes, be sure to update the pkgIndex.tcl file, # and the install directory in the Makefiles. When the minor version # changes (new feature) be sure to update the man page as well. - variable Version 2.4.0 + variable Version 2.4.1 # Compatibility support for dumb variables defined in tcltest 1 # Do not use these. Call [package provide Tcl] and [info patchlevel] diff --git a/unix/Makefile.in b/unix/Makefile.in index 9ad106c..e03e874 100644 --- a/unix/Makefile.in +++ b/unix/Makefile.in @@ -847,10 +847,10 @@ install-libraries: libraries do \ $(INSTALL_DATA) $$i "$(SCRIPT_INSTALL_DIR)"/opt0.4; \ done; - @echo "Installing package msgcat 1.6.0 as a Tcl Module"; - @$(INSTALL_DATA) $(TOP_DIR)/library/msgcat/msgcat.tcl "$(SCRIPT_INSTALL_DIR)"/../tcl8/8.5/msgcat-1.6.0.tm; - @echo "Installing package tcltest 2.4.0 as a Tcl Module"; - @$(INSTALL_DATA) $(TOP_DIR)/library/tcltest/tcltest.tcl "$(SCRIPT_INSTALL_DIR)"/../tcl8/8.5/tcltest-2.4.0.tm; + @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 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; @echo "Installing package platform 1.0.14 as a Tcl Module"; @$(INSTALL_DATA) $(TOP_DIR)/library/platform/platform.tcl "$(SCRIPT_INSTALL_DIR)"/../tcl8/8.4/platform-1.0.14.tm; diff --git a/win/Makefile.in b/win/Makefile.in index 0ab4204..255c9b4 100644 --- a/win/Makefile.in +++ b/win/Makefile.in @@ -658,10 +658,10 @@ install-libraries: libraries install-tzdata install-msgs do \ $(COPY) "$$j" "$(SCRIPT_INSTALL_DIR)/opt0.4"; \ done; - @echo "Installing package msgcat 1.6.0 as a Tcl Module"; - @$(COPY) $(ROOT_DIR)/library/msgcat/msgcat.tcl $(SCRIPT_INSTALL_DIR)/../tcl8/8.5/msgcat-1.6.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 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 tcltest 2.4.1 as a Tcl Module"; + @$(COPY) $(ROOT_DIR)/library/tcltest/tcltest.tcl $(SCRIPT_INSTALL_DIR)/../tcl8/8.5/tcltest-2.4.1.tm; @echo "Installing package platform 1.0.14 as a Tcl Module"; @$(COPY) $(ROOT_DIR)/library/platform/platform.tcl $(SCRIPT_INSTALL_DIR)/../tcl8/8.4/platform-1.0.14.tm; @echo "Installing package platform::shell 1.1.4 as a Tcl Module"; -- cgit v0.12 From 6be0cf66e023bc64e38f0a037a3e74e5d31b18f7 Mon Sep 17 00:00:00 2001 From: "jan.nijtmans" Date: Thu, 13 Apr 2017 12:20:37 +0000 Subject: Translate all \u???? sequences to their UTF-8 counterpart in *.msg files: It is faster during parsing (since no backslash-sequences have to be handled) and makes the msg-files better readable by humans. TODO: adapt tools/loadICU.tcl to generate UTF-8 in stead of those sequences. This tools seems to be out-of-date a long time already, I couldn't make it run with latest ICU. --- library/msgs/ar.msg | 84 ++++++++++++++++++++++----------------------- library/msgs/ar_jo.msg | 62 +++++++++++++++++----------------- library/msgs/ar_lb.msg | 62 +++++++++++++++++----------------- library/msgs/ar_sy.msg | 62 +++++++++++++++++----------------- library/msgs/be.msg | 80 +++++++++++++++++++++---------------------- library/msgs/bg.msg | 56 +++++++++++++++--------------- library/msgs/bn.msg | 80 +++++++++++++++++++++---------------------- library/msgs/ca.msg | 4 +-- library/msgs/cs.msg | 34 +++++++++---------- library/msgs/da.msg | 8 ++--- library/msgs/de.msg | 2 +- library/msgs/de_at.msg | 8 ++--- library/msgs/de_be.msg | 4 +-- library/msgs/el.msg | 80 +++++++++++++++++++++---------------------- library/msgs/eo.msg | 10 +++--- library/msgs/es.msg | 8 ++--- library/msgs/et.msg | 16 ++++----- library/msgs/fa.msg | 76 ++++++++++++++++++++--------------------- library/msgs/fa_in.msg | 80 +++++++++++++++++++++---------------------- library/msgs/fa_ir.msg | 8 ++--- library/msgs/fi.msg | 8 ++--- library/msgs/fo.msg | 18 +++++----- library/msgs/fr.msg | 12 +++---- library/msgs/ga.msg | 50 +++++++++++++-------------- library/msgs/gl.msg | 12 +++---- library/msgs/he.msg | 80 +++++++++++++++++++++---------------------- library/msgs/hi.msg | 64 +++++++++++++++++------------------ library/msgs/hr.msg | 12 +++---- library/msgs/hu.msg | 34 +++++++++---------- library/msgs/is.msg | 44 ++++++++++++------------ library/msgs/it.msg | 10 +++--- library/msgs/ja.msg | 68 ++++++++++++++++++------------------- library/msgs/ko.msg | 86 +++++++++++++++++++++++----------------------- library/msgs/ko_kr.msg | 4 +-- library/msgs/kok.msg | 66 ++++++++++++++++++------------------ library/msgs/lt.msg | 20 +++++------ library/msgs/lv.msg | 22 ++++++------ library/msgs/mk.msg | 80 +++++++++++++++++++++---------------------- library/msgs/mr.msg | 62 +++++++++++++++++----------------- library/msgs/mt.msg | 8 ++--- library/msgs/nb.msg | 8 ++--- library/msgs/nn.msg | 4 +-- library/msgs/pl.msg | 22 ++++++------ library/msgs/pt.msg | 8 ++--- library/msgs/ro.msg | 8 ++--- library/msgs/ru.msg | 80 +++++++++++++++++++++---------------------- library/msgs/sh.msg | 4 +-- library/msgs/sk.msg | 26 +++++++------- library/msgs/sl.msg | 6 ++-- library/msgs/sq.msg | 16 ++++----- library/msgs/sr.msg | 80 +++++++++++++++++++++---------------------- library/msgs/sv.msg | 12 +++---- library/msgs/ta.msg | 66 ++++++++++++++++++------------------ library/msgs/te.msg | 76 ++++++++++++++++++++--------------------- library/msgs/te_in.msg | 4 +-- library/msgs/th.msg | 84 ++++++++++++++++++++++----------------------- library/msgs/tr.msg | 24 ++++++------- library/msgs/uk.msg | 80 +++++++++++++++++++++---------------------- library/msgs/vi.msg | 38 ++++++++++----------- library/msgs/zh.msg | 92 +++++++++++++++++++++++++------------------------- library/msgs/zh_cn.msg | 2 +- library/msgs/zh_hk.msg | 42 +++++++++++------------ library/msgs/zh_sg.msg | 4 +-- library/msgs/zh_tw.msg | 4 +-- tools/loadICU.tcl | 3 ++ 65 files changed, 1190 insertions(+), 1187 deletions(-) diff --git a/library/msgs/ar.msg b/library/msgs/ar.msg index 257157f..2d403ec 100644 --- a/library/msgs/ar.msg +++ b/library/msgs/ar.msg @@ -1,53 +1,53 @@ # created by tools/loadICU.tcl -- do not edit namespace eval ::tcl::clock { ::msgcat::mcset ar DAYS_OF_WEEK_ABBREV [list \ - "\u062d"\ - "\u0646"\ - "\u062b"\ - "\u0631"\ - "\u062e"\ - "\u062c"\ - "\u0633"] + "ح"\ + "ن"\ + "ث"\ + "ر"\ + "خ"\ + "ج"\ + "س"] ::msgcat::mcset ar DAYS_OF_WEEK_FULL [list \ - "\u0627\u0644\u0623\u062d\u062f"\ - "\u0627\u0644\u0627\u062b\u0646\u064a\u0646"\ - "\u0627\u0644\u062b\u0644\u0627\u062b\u0627\u0621"\ - "\u0627\u0644\u0623\u0631\u0628\u0639\u0627\u0621"\ - "\u0627\u0644\u062e\u0645\u064a\u0633"\ - "\u0627\u0644\u062c\u0645\u0639\u0629"\ - "\u0627\u0644\u0633\u0628\u062a"] + "الأحد"\ + "الاثنين"\ + "الثلاثاء"\ + "الأربعاء"\ + "الخميس"\ + "الجمعة"\ + "السبت"] ::msgcat::mcset ar MONTHS_ABBREV [list \ - "\u064a\u0646\u0627"\ - "\u0641\u0628\u0631"\ - "\u0645\u0627\u0631"\ - "\u0623\u0628\u0631"\ - "\u0645\u0627\u064a"\ - "\u064a\u0648\u0646"\ - "\u064a\u0648\u0644"\ - "\u0623\u063a\u0633"\ - "\u0633\u0628\u062a"\ - "\u0623\u0643\u062a"\ - "\u0646\u0648\u0641"\ - "\u062f\u064a\u0633"\ + "ينا"\ + "فبر"\ + "مار"\ + "أبر"\ + "ماي"\ + "يون"\ + "يول"\ + "أغس"\ + "سبت"\ + "أكت"\ + "نوف"\ + "ديس"\ ""] ::msgcat::mcset ar MONTHS_FULL [list \ - "\u064a\u0646\u0627\u064a\u0631"\ - "\u0641\u0628\u0631\u0627\u064a\u0631"\ - "\u0645\u0627\u0631\u0633"\ - "\u0623\u0628\u0631\u064a\u0644"\ - "\u0645\u0627\u064a\u0648"\ - "\u064a\u0648\u0646\u064a\u0648"\ - "\u064a\u0648\u0644\u064a\u0648"\ - "\u0623\u063a\u0633\u0637\u0633"\ - "\u0633\u0628\u062a\u0645\u0628\u0631"\ - "\u0623\u0643\u062a\u0648\u0628\u0631"\ - "\u0646\u0648\u0641\u0645\u0628\u0631"\ - "\u062f\u064a\u0633\u0645\u0628\u0631"\ + "يناير"\ + "فبراير"\ + "مارس"\ + "أبريل"\ + "مايو"\ + "يونيو"\ + "يوليو"\ + "أغسطس"\ + "سبتمبر"\ + "أكتوبر"\ + "نوفمبر"\ + "ديسمبر"\ ""] - ::msgcat::mcset ar BCE "\u0642.\u0645" - ::msgcat::mcset ar CE "\u0645" - ::msgcat::mcset ar AM "\u0635" - ::msgcat::mcset ar PM "\u0645" + ::msgcat::mcset ar BCE "ق.م" + ::msgcat::mcset ar CE "م" + ::msgcat::mcset ar AM "ص" + ::msgcat::mcset ar PM "م" ::msgcat::mcset ar DATE_FORMAT "%d/%m/%Y" ::msgcat::mcset ar TIME_FORMAT_12 "%I:%M:%S %P" ::msgcat::mcset ar DATE_TIME_FORMAT "%d/%m/%Y %I:%M:%S %P %z" diff --git a/library/msgs/ar_jo.msg b/library/msgs/ar_jo.msg index 0f5e269..9a9dda0 100644 --- a/library/msgs/ar_jo.msg +++ b/library/msgs/ar_jo.msg @@ -1,39 +1,39 @@ # created by tools/loadICU.tcl -- do not edit namespace eval ::tcl::clock { ::msgcat::mcset ar_JO DAYS_OF_WEEK_ABBREV [list \ - "\u0627\u0644\u0623\u062d\u062f"\ - "\u0627\u0644\u0627\u062b\u0646\u064a\u0646"\ - "\u0627\u0644\u062b\u0644\u0627\u062b\u0627\u0621"\ - "\u0627\u0644\u0623\u0631\u0628\u0639\u0627\u0621"\ - "\u0627\u0644\u062e\u0645\u064a\u0633"\ - "\u0627\u0644\u062c\u0645\u0639\u0629"\ - "\u0627\u0644\u0633\u0628\u062a"] + "الأحد"\ + "الاثنين"\ + "الثلاثاء"\ + "الأربعاء"\ + "الخميس"\ + "الجمعة"\ + "السبت"] ::msgcat::mcset ar_JO MONTHS_ABBREV [list \ - "\u0643\u0627\u0646\u0648\u0646 \u0627\u0644\u062b\u0627\u0646\u064a"\ - "\u0634\u0628\u0627\u0637"\ - "\u0622\u0630\u0627\u0631"\ - "\u0646\u064a\u0633\u0627\u0646"\ - "\u0646\u0648\u0627\u0631"\ - "\u062d\u0632\u064a\u0631\u0627\u0646"\ - "\u062a\u0645\u0648\u0632"\ - "\u0622\u0628"\ - "\u0623\u064a\u0644\u0648\u0644"\ - "\u062a\u0634\u0631\u064a\u0646 \u0627\u0644\u0623\u0648\u0644"\ - "\u062a\u0634\u0631\u064a\u0646 \u0627\u0644\u062b\u0627\u0646\u064a"\ - "\u0643\u0627\u0646\u0648\u0646 \u0627\u0644\u0623\u0648\u0644"\ + "كانون الثاني"\ + "شباط"\ + "آذار"\ + "نيسان"\ + "نوار"\ + "حزيران"\ + "تموز"\ + "آب"\ + "أيلول"\ + "تشرين الأول"\ + "تشرين الثاني"\ + "كانون الأول"\ ""] ::msgcat::mcset ar_JO MONTHS_FULL [list \ - "\u0643\u0627\u0646\u0648\u0646 \u0627\u0644\u062b\u0627\u0646\u064a"\ - "\u0634\u0628\u0627\u0637"\ - "\u0622\u0630\u0627\u0631"\ - "\u0646\u064a\u0633\u0627\u0646"\ - "\u0646\u0648\u0627\u0631"\ - "\u062d\u0632\u064a\u0631\u0627\u0646"\ - "\u062a\u0645\u0648\u0632"\ - "\u0622\u0628"\ - "\u0623\u064a\u0644\u0648\u0644"\ - "\u062a\u0634\u0631\u064a\u0646 \u0627\u0644\u0623\u0648\u0644"\ - "\u062a\u0634\u0631\u064a\u0646 \u0627\u0644\u062b\u0627\u0646\u064a"\ - "\u0643\u0627\u0646\u0648\u0646 \u0627\u0644\u0623\u0648\u0644"\ + "كانون الثاني"\ + "شباط"\ + "آذار"\ + "نيسان"\ + "نوار"\ + "حزيران"\ + "تموز"\ + "آب"\ + "أيلول"\ + "تشرين الأول"\ + "تشرين الثاني"\ + "كانون الأول"\ ""] } diff --git a/library/msgs/ar_lb.msg b/library/msgs/ar_lb.msg index e62acd3..c23aa2c 100644 --- a/library/msgs/ar_lb.msg +++ b/library/msgs/ar_lb.msg @@ -1,39 +1,39 @@ # created by tools/loadICU.tcl -- do not edit namespace eval ::tcl::clock { ::msgcat::mcset ar_LB DAYS_OF_WEEK_ABBREV [list \ - "\u0627\u0644\u0623\u062d\u062f"\ - "\u0627\u0644\u0627\u062b\u0646\u064a\u0646"\ - "\u0627\u0644\u062b\u0644\u0627\u062b\u0627\u0621"\ - "\u0627\u0644\u0623\u0631\u0628\u0639\u0627\u0621"\ - "\u0627\u0644\u062e\u0645\u064a\u0633"\ - "\u0627\u0644\u062c\u0645\u0639\u0629"\ - "\u0627\u0644\u0633\u0628\u062a"] + "الأحد"\ + "الاثنين"\ + "الثلاثاء"\ + "الأربعاء"\ + "الخميس"\ + "الجمعة"\ + "السبت"] ::msgcat::mcset ar_LB MONTHS_ABBREV [list \ - "\u0643\u0627\u0646\u0648\u0646 \u0627\u0644\u062b\u0627\u0646\u064a"\ - "\u0634\u0628\u0627\u0637"\ - "\u0622\u0630\u0627\u0631"\ - "\u0646\u064a\u0633\u0627\u0646"\ - "\u0646\u0648\u0627\u0631"\ - "\u062d\u0632\u064a\u0631\u0627\u0646"\ - "\u062a\u0645\u0648\u0632"\ - "\u0622\u0628"\ - "\u0623\u064a\u0644\u0648\u0644"\ - "\u062a\u0634\u0631\u064a\u0646 \u0627\u0644\u0623\u0648\u0644"\ - "\u062a\u0634\u0631\u064a\u0646 \u0627\u0644\u062b\u0627\u0646\u064a"\ - "\u0643\u0627\u0646\u0648\u0646 \u0627\u0644\u0623\u0648\u0644"\ + "كانون الثاني"\ + "شباط"\ + "آذار"\ + "نيسان"\ + "نوار"\ + "حزيران"\ + "تموز"\ + "آب"\ + "أيلول"\ + "تشرين الأول"\ + "تشرين الثاني"\ + "كانون الأول"\ ""] ::msgcat::mcset ar_LB MONTHS_FULL [list \ - "\u0643\u0627\u0646\u0648\u0646 \u0627\u0644\u062b\u0627\u0646\u064a"\ - "\u0634\u0628\u0627\u0637"\ - "\u0622\u0630\u0627\u0631"\ - "\u0646\u064a\u0633\u0627\u0646"\ - "\u0646\u0648\u0627\u0631"\ - "\u062d\u0632\u064a\u0631\u0627\u0646"\ - "\u062a\u0645\u0648\u0632"\ - "\u0622\u0628"\ - "\u0623\u064a\u0644\u0648\u0644"\ - "\u062a\u0634\u0631\u064a\u0646 \u0627\u0644\u0623\u0648\u0644"\ - "\u062a\u0634\u0631\u064a\u0646 \u0627\u0644\u062b\u0627\u0646\u064a"\ - "\u0643\u0627\u0646\u0648\u0646 \u0627\u0644\u0623\u0648\u0644"\ + "كانون الثاني"\ + "شباط"\ + "آذار"\ + "نيسان"\ + "نوار"\ + "حزيران"\ + "تموز"\ + "آب"\ + "أيلول"\ + "تشرين الأول"\ + "تشرين الثاني"\ + "كانون الأول"\ ""] } diff --git a/library/msgs/ar_sy.msg b/library/msgs/ar_sy.msg index d5e1c87..f0daec0 100644 --- a/library/msgs/ar_sy.msg +++ b/library/msgs/ar_sy.msg @@ -1,39 +1,39 @@ # created by tools/loadICU.tcl -- do not edit namespace eval ::tcl::clock { ::msgcat::mcset ar_SY DAYS_OF_WEEK_ABBREV [list \ - "\u0627\u0644\u0623\u062d\u062f"\ - "\u0627\u0644\u0627\u062b\u0646\u064a\u0646"\ - "\u0627\u0644\u062b\u0644\u0627\u062b\u0627\u0621"\ - "\u0627\u0644\u0623\u0631\u0628\u0639\u0627\u0621"\ - "\u0627\u0644\u062e\u0645\u064a\u0633"\ - "\u0627\u0644\u062c\u0645\u0639\u0629"\ - "\u0627\u0644\u0633\u0628\u062a"] + "الأحد"\ + "الاثنين"\ + "الثلاثاء"\ + "الأربعاء"\ + "الخميس"\ + "الجمعة"\ + "السبت"] ::msgcat::mcset ar_SY MONTHS_ABBREV [list \ - "\u0643\u0627\u0646\u0648\u0646 \u0627\u0644\u062b\u0627\u0646\u064a"\ - "\u0634\u0628\u0627\u0637"\ - "\u0622\u0630\u0627\u0631"\ - "\u0646\u064a\u0633\u0627\u0646"\ - "\u0646\u0648\u0627\u0631"\ - "\u062d\u0632\u064a\u0631\u0627\u0646"\ - "\u062a\u0645\u0648\u0632"\ - "\u0622\u0628"\ - "\u0623\u064a\u0644\u0648\u0644"\ - "\u062a\u0634\u0631\u064a\u0646 \u0627\u0644\u0623\u0648\u0644"\ - "\u062a\u0634\u0631\u064a\u0646 \u0627\u0644\u062b\u0627\u0646\u064a"\ - "\u0643\u0627\u0646\u0648\u0646 \u0627\u0644\u0623\u0648\u0644"\ + "كانون الثاني"\ + "شباط"\ + "آذار"\ + "نيسان"\ + "نوار"\ + "حزيران"\ + "تموز"\ + "آب"\ + "أيلول"\ + "تشرين الأول"\ + "تشرين الثاني"\ + "كانون الأول"\ ""] ::msgcat::mcset ar_SY MONTHS_FULL [list \ - "\u0643\u0627\u0646\u0648\u0646 \u0627\u0644\u062b\u0627\u0646\u064a"\ - "\u0634\u0628\u0627\u0637"\ - "\u0622\u0630\u0627\u0631"\ - "\u0646\u064a\u0633\u0627\u0646"\ - "\u0646\u0648\u0627\u0631\u0627\u0646"\ - "\u062d\u0632\u064a\u0631"\ - "\u062a\u0645\u0648\u0632"\ - "\u0622\u0628"\ - "\u0623\u064a\u0644\u0648\u0644"\ - "\u062a\u0634\u0631\u064a\u0646 \u0627\u0644\u0623\u0648\u0644"\ - "\u062a\u0634\u0631\u064a\u0646 \u0627\u0644\u062b\u0627\u0646\u064a"\ - "\u0643\u0627\u0646\u0648\u0646 \u0627\u0644\u0623\u0648\u0644"\ + "كانون الثاني"\ + "شباط"\ + "آذار"\ + "نيسان"\ + "نواران"\ + "حزير"\ + "تموز"\ + "آب"\ + "أيلول"\ + "تشرين الأول"\ + "تشرين الثاني"\ + "كانون الأول"\ ""] } diff --git a/library/msgs/be.msg b/library/msgs/be.msg index 379a1d7..a0aceed 100644 --- a/library/msgs/be.msg +++ b/library/msgs/be.msg @@ -1,51 +1,51 @@ # created by tools/loadICU.tcl -- do not edit namespace eval ::tcl::clock { ::msgcat::mcset be DAYS_OF_WEEK_ABBREV [list \ - "\u043d\u0434"\ - "\u043f\u043d"\ - "\u0430\u0442"\ - "\u0441\u0440"\ - "\u0447\u0446"\ - "\u043f\u0442"\ - "\u0441\u0431"] + "нд"\ + "пн"\ + "ат"\ + "ср"\ + "чц"\ + "пт"\ + "сб"] ::msgcat::mcset be DAYS_OF_WEEK_FULL [list \ - "\u043d\u044f\u0434\u0437\u0435\u043b\u044f"\ - "\u043f\u0430\u043d\u044f\u0434\u0437\u0435\u043b\u0430\u043a"\ - "\u0430\u045e\u0442\u043e\u0440\u0430\u043a"\ - "\u0441\u0435\u0440\u0430\u0434\u0430"\ - "\u0447\u0430\u0446\u0432\u0435\u0440"\ - "\u043f\u044f\u0442\u043d\u0456\u0446\u0430"\ - "\u0441\u0443\u0431\u043e\u0442\u0430"] + "нядзеля"\ + "панядзелак"\ + "аўторак"\ + "серада"\ + "чацвер"\ + "пятніца"\ + "субота"] ::msgcat::mcset be MONTHS_ABBREV [list \ - "\u0441\u0442\u0434"\ - "\u043b\u044e\u0442"\ - "\u0441\u043a\u0432"\ - "\u043a\u0440\u0441"\ - "\u043c\u0430\u0439"\ - "\u0447\u0440\u0432"\ - "\u043b\u043f\u043d"\ - "\u0436\u043d\u0432"\ - "\u0432\u0440\u0441"\ - "\u043a\u0441\u0442"\ - "\u043b\u0441\u0442"\ - "\u0441\u043d\u0436"\ + "стд"\ + "лют"\ + "скв"\ + "крс"\ + "май"\ + "чрв"\ + "лпн"\ + "жнв"\ + "врс"\ + "кст"\ + "лст"\ + "снж"\ ""] ::msgcat::mcset be MONTHS_FULL [list \ - "\u0441\u0442\u0443\u0434\u0437\u0435\u043d\u044f"\ - "\u043b\u044e\u0442\u0430\u0433\u0430"\ - "\u0441\u0430\u043a\u0430\u0432\u0456\u043a\u0430"\ - "\u043a\u0440\u0430\u0441\u0430\u0432\u0456\u043a\u0430"\ - "\u043c\u0430\u044f"\ - "\u0447\u0440\u0432\u0435\u043d\u044f"\ - "\u043b\u0456\u043f\u0435\u043d\u044f"\ - "\u0436\u043d\u0456\u045e\u043d\u044f"\ - "\u0432\u0435\u0440\u0430\u0441\u043d\u044f"\ - "\u043a\u0430\u0441\u0442\u0440\u044b\u0447\u043d\u0456\u043a\u0430"\ - "\u043b\u0438\u0441\u0442\u0430\u043f\u0430\u0434\u0430"\ - "\u0441\u043d\u0435\u0436\u043d\u044f"\ + "студзеня"\ + "лютага"\ + "сакавіка"\ + "красавіка"\ + "мая"\ + "чрвеня"\ + "ліпеня"\ + "жніўня"\ + "верасня"\ + "кастрычніка"\ + "листапада"\ + "снежня"\ ""] - ::msgcat::mcset be BCE "\u0434\u0430 \u043d.\u0435." - ::msgcat::mcset be CE "\u043d.\u0435." + ::msgcat::mcset be BCE "да н.е." + ::msgcat::mcset be CE "н.е." ::msgcat::mcset be DATE_FORMAT "%e.%m.%Y" ::msgcat::mcset be TIME_FORMAT "%k.%M.%S" ::msgcat::mcset be DATE_TIME_FORMAT "%e.%m.%Y %k.%M.%S %z" diff --git a/library/msgs/bg.msg b/library/msgs/bg.msg index ff17759..2e7730d 100644 --- a/library/msgs/bg.msg +++ b/library/msgs/bg.msg @@ -1,21 +1,21 @@ # created by tools/loadICU.tcl -- do not edit namespace eval ::tcl::clock { ::msgcat::mcset bg DAYS_OF_WEEK_ABBREV [list \ - "\u041d\u0434"\ - "\u041f\u043d"\ - "\u0412\u0442"\ - "\u0421\u0440"\ - "\u0427\u0442"\ - "\u041f\u0442"\ - "\u0421\u0431"] + "Нд"\ + "Пн"\ + "Вт"\ + "Ср"\ + "Чт"\ + "Пт"\ + "Сб"] ::msgcat::mcset bg DAYS_OF_WEEK_FULL [list \ - "\u041d\u0435\u0434\u0435\u043b\u044f"\ - "\u041f\u043e\u043d\u0435\u0434\u0435\u043b\u043d\u0438\u043a"\ - "\u0412\u0442\u043e\u0440\u043d\u0438\u043a"\ - "\u0421\u0440\u044f\u0434\u0430"\ - "\u0427\u0435\u0442\u0432\u044a\u0440\u0442\u044a\u043a"\ - "\u041f\u0435\u0442\u044a\u043a"\ - "\u0421\u044a\u0431\u043e\u0442\u0430"] + "Неделя"\ + "Понеделник"\ + "Вторник"\ + "Сряда"\ + "Четвъртък"\ + "Петък"\ + "Събота"] ::msgcat::mcset bg MONTHS_ABBREV [list \ "I"\ "II"\ @@ -31,21 +31,21 @@ namespace eval ::tcl::clock { "XII"\ ""] ::msgcat::mcset bg MONTHS_FULL [list \ - "\u042f\u043d\u0443\u0430\u0440\u0438"\ - "\u0424\u0435\u0432\u0440\u0443\u0430\u0440\u0438"\ - "\u041c\u0430\u0440\u0442"\ - "\u0410\u043f\u0440\u0438\u043b"\ - "\u041c\u0430\u0439"\ - "\u042e\u043d\u0438"\ - "\u042e\u043b\u0438"\ - "\u0410\u0432\u0433\u0443\u0441\u0442"\ - "\u0421\u0435\u043f\u0442\u0435\u043c\u0432\u0440\u0438"\ - "\u041e\u043a\u0442\u043e\u043c\u0432\u0440\u0438"\ - "\u041d\u043e\u0435\u043c\u0432\u0440\u0438"\ - "\u0414\u0435\u043a\u0435\u043c\u0432\u0440\u0438"\ + "Януари"\ + "Февруари"\ + "Март"\ + "Април"\ + "Май"\ + "Юни"\ + "Юли"\ + "Август"\ + "Септември"\ + "Октомври"\ + "Ноември"\ + "Декември"\ ""] - ::msgcat::mcset bg BCE "\u043f\u0440.\u043d.\u0435." - ::msgcat::mcset bg CE "\u043d.\u0435." + ::msgcat::mcset bg BCE "пр.н.е." + ::msgcat::mcset bg CE "н.е." ::msgcat::mcset bg DATE_FORMAT "%Y-%m-%e" ::msgcat::mcset bg TIME_FORMAT "%k:%M:%S" ::msgcat::mcset bg DATE_TIME_FORMAT "%Y-%m-%e %k:%M:%S %z" diff --git a/library/msgs/bn.msg b/library/msgs/bn.msg index 664b9d8..a0aef13 100644 --- a/library/msgs/bn.msg +++ b/library/msgs/bn.msg @@ -1,49 +1,49 @@ # created by tools/loadICU.tcl -- do not edit namespace eval ::tcl::clock { ::msgcat::mcset bn DAYS_OF_WEEK_ABBREV [list \ - "\u09b0\u09ac\u09bf"\ - "\u09b8\u09cb\u09ae"\ - "\u09ae\u0999\u0997\u09b2"\ - "\u09ac\u09c1\u09a7"\ - "\u09ac\u09c3\u09b9\u09b8\u09cd\u09aa\u09a4\u09bf"\ - "\u09b6\u09c1\u0995\u09cd\u09b0"\ - "\u09b6\u09a8\u09bf"] + "রবি"\ + "সোম"\ + "মঙগল"\ + "বুধ"\ + "বৃহস্পতি"\ + "শুক্র"\ + "শনি"] ::msgcat::mcset bn DAYS_OF_WEEK_FULL [list \ - "\u09b0\u09ac\u09bf\u09ac\u09be\u09b0"\ - "\u09b8\u09cb\u09ae\u09ac\u09be\u09b0"\ - "\u09ae\u0999\u0997\u09b2\u09ac\u09be\u09b0"\ - "\u09ac\u09c1\u09a7\u09ac\u09be\u09b0"\ - "\u09ac\u09c3\u09b9\u09b8\u09cd\u09aa\u09a4\u09bf\u09ac\u09be\u09b0"\ - "\u09b6\u09c1\u0995\u09cd\u09b0\u09ac\u09be\u09b0"\ - "\u09b6\u09a8\u09bf\u09ac\u09be\u09b0"] + "রবিবার"\ + "সোমবার"\ + "মঙগলবার"\ + "বুধবার"\ + "বৃহস্পতিবার"\ + "শুক্রবার"\ + "শনিবার"] ::msgcat::mcset bn MONTHS_ABBREV [list \ - "\u099c\u09be\u09a8\u09c1\u09df\u09be\u09b0\u09c0"\ - "\u09ab\u09c7\u09ac\u09cd\u09b0\u09c1\u09df\u09be\u09b0\u09c0"\ - "\u09ae\u09be\u09b0\u09cd\u099a"\ - "\u098f\u09aa\u09cd\u09b0\u09bf\u09b2"\ - "\u09ae\u09c7"\ - "\u099c\u09c1\u09a8"\ - "\u099c\u09c1\u09b2\u09be\u0987"\ - "\u0986\u0997\u09b8\u09cd\u099f"\ - "\u09b8\u09c7\u09aa\u09cd\u099f\u09c7\u09ae\u09cd\u09ac\u09b0"\ - "\u0985\u0995\u09cd\u099f\u09cb\u09ac\u09b0"\ - "\u09a8\u09ad\u09c7\u09ae\u09cd\u09ac\u09b0"\ - "\u09a1\u09bf\u09b8\u09c7\u09ae\u09cd\u09ac\u09b0"\ + "জানুয়ারী"\ + "ফেব্রুয়ারী"\ + "মার্চ"\ + "এপ্রিল"\ + "মে"\ + "জুন"\ + "জুলাই"\ + "আগস্ট"\ + "সেপ্টেম্বর"\ + "অক্টোবর"\ + "নভেম্বর"\ + "ডিসেম্বর"\ ""] ::msgcat::mcset bn MONTHS_FULL [list \ - "\u099c\u09be\u09a8\u09c1\u09df\u09be\u09b0\u09c0"\ - "\u09ab\u09c7\u09ac\u09cd\u09b0\u09c1\u09df\u09be\u09b0\u09c0"\ - "\u09ae\u09be\u09b0\u09cd\u099a"\ - "\u098f\u09aa\u09cd\u09b0\u09bf\u09b2"\ - "\u09ae\u09c7"\ - "\u099c\u09c1\u09a8"\ - "\u099c\u09c1\u09b2\u09be\u0987"\ - "\u0986\u0997\u09b8\u09cd\u099f"\ - "\u09b8\u09c7\u09aa\u09cd\u099f\u09c7\u09ae\u09cd\u09ac\u09b0"\ - "\u0985\u0995\u09cd\u099f\u09cb\u09ac\u09b0"\ - "\u09a8\u09ad\u09c7\u09ae\u09cd\u09ac\u09b0"\ - "\u09a1\u09bf\u09b8\u09c7\u09ae\u09cd\u09ac\u09b0"\ + "জানুয়ারী"\ + "ফেব্রুয়ারী"\ + "মার্চ"\ + "এপ্রিল"\ + "মে"\ + "জুন"\ + "জুলাই"\ + "আগস্ট"\ + "সেপ্টেম্বর"\ + "অক্টোবর"\ + "নভেম্বর"\ + "ডিসেম্বর"\ ""] - ::msgcat::mcset bn AM "\u09aa\u09c2\u09b0\u09cd\u09ac\u09be\u09b9\u09cd\u09a3" - ::msgcat::mcset bn PM "\u0985\u09aa\u09b0\u09be\u09b9\u09cd\u09a3" + ::msgcat::mcset bn AM "পূর্বাহ্ণ" + ::msgcat::mcset bn PM "অপরাহ্ণ" } diff --git a/library/msgs/ca.msg b/library/msgs/ca.msg index 36c9772..272f682 100644 --- a/library/msgs/ca.msg +++ b/library/msgs/ca.msg @@ -19,7 +19,7 @@ namespace eval ::tcl::clock { ::msgcat::mcset ca MONTHS_ABBREV [list \ "gen."\ "feb."\ - "mar\u00e7"\ + "març"\ "abr."\ "maig"\ "juny"\ @@ -33,7 +33,7 @@ namespace eval ::tcl::clock { ::msgcat::mcset ca MONTHS_FULL [list \ "gener"\ "febrer"\ - "mar\u00e7"\ + "març"\ "abril"\ "maig"\ "juny"\ diff --git a/library/msgs/cs.msg b/library/msgs/cs.msg index 8db8bdd..4673cd4 100644 --- a/library/msgs/cs.msg +++ b/library/msgs/cs.msg @@ -3,18 +3,18 @@ namespace eval ::tcl::clock { ::msgcat::mcset cs DAYS_OF_WEEK_ABBREV [list \ "Ne"\ "Po"\ - "\u00dat"\ + "Út"\ "St"\ - "\u010ct"\ - "P\u00e1"\ + "Čt"\ + "Pá"\ "So"] ::msgcat::mcset cs DAYS_OF_WEEK_FULL [list \ - "Ned\u011ble"\ - "Pond\u011bl\u00ed"\ - "\u00dater\u00fd"\ - "St\u0159eda"\ - "\u010ctvrtek"\ - "P\u00e1tek"\ + "Neděle"\ + "Pondělí"\ + "Úterý"\ + "Středa"\ + "Čtvrtek"\ + "Pátek"\ "Sobota"] ::msgcat::mcset cs MONTHS_ABBREV [list \ "I"\ @@ -32,19 +32,19 @@ namespace eval ::tcl::clock { ""] ::msgcat::mcset cs MONTHS_FULL [list \ "leden"\ - "\u00fanor"\ - "b\u0159ezen"\ + "únor"\ + "březen"\ "duben"\ - "kv\u011bten"\ - "\u010derven"\ - "\u010dervenec"\ + "květen"\ + "červen"\ + "červenec"\ "srpen"\ - "z\u00e1\u0159\u00ed"\ - "\u0159\u00edjen"\ + "září"\ + "říjen"\ "listopad"\ "prosinec"\ ""] - ::msgcat::mcset cs BCE "p\u0159.Kr." + ::msgcat::mcset cs BCE "př.Kr." ::msgcat::mcset cs CE "po Kr." ::msgcat::mcset cs AM "dop." ::msgcat::mcset cs PM "odp." diff --git a/library/msgs/da.msg b/library/msgs/da.msg index e4fec7f..abed3c5 100644 --- a/library/msgs/da.msg +++ b/library/msgs/da.msg @@ -1,21 +1,21 @@ # created by tools/loadICU.tcl -- do not edit namespace eval ::tcl::clock { ::msgcat::mcset da DAYS_OF_WEEK_ABBREV [list \ - "s\u00f8"\ + "sø"\ "ma"\ "ti"\ "on"\ "to"\ "fr"\ - "l\u00f8"] + "lø"] ::msgcat::mcset da DAYS_OF_WEEK_FULL [list \ - "s\u00f8ndag"\ + "søndag"\ "mandag"\ "tirsdag"\ "onsdag"\ "torsdag"\ "fredag"\ - "l\u00f8rdag"] + "lørdag"] ::msgcat::mcset da MONTHS_ABBREV [list \ "jan"\ "feb"\ diff --git a/library/msgs/de.msg b/library/msgs/de.msg index 9eb3145..0bb7399 100644 --- a/library/msgs/de.msg +++ b/library/msgs/de.msg @@ -33,7 +33,7 @@ namespace eval ::tcl::clock { ::msgcat::mcset de MONTHS_FULL [list \ "Januar"\ "Februar"\ - "M\u00e4rz"\ + "März"\ "April"\ "Mai"\ "Juni"\ diff --git a/library/msgs/de_at.msg b/library/msgs/de_at.msg index 61bc266..1a0a0f5 100644 --- a/library/msgs/de_at.msg +++ b/library/msgs/de_at.msg @@ -1,9 +1,9 @@ # created by tools/loadICU.tcl -- do not edit namespace eval ::tcl::clock { ::msgcat::mcset de_AT MONTHS_ABBREV [list \ - "J\u00e4n"\ + "Jän"\ "Feb"\ - "M\u00e4r"\ + "Mär"\ "Apr"\ "Mai"\ "Jun"\ @@ -15,9 +15,9 @@ namespace eval ::tcl::clock { "Dez"\ ""] ::msgcat::mcset de_AT MONTHS_FULL [list \ - "J\u00e4nner"\ + "Jänner"\ "Februar"\ - "M\u00e4rz"\ + "März"\ "April"\ "Mai"\ "Juni"\ diff --git a/library/msgs/de_be.msg b/library/msgs/de_be.msg index 3614763..04cf88c 100644 --- a/library/msgs/de_be.msg +++ b/library/msgs/de_be.msg @@ -19,7 +19,7 @@ namespace eval ::tcl::clock { ::msgcat::mcset de_BE MONTHS_ABBREV [list \ "Jan"\ "Feb"\ - "M\u00e4r"\ + "Mär"\ "Apr"\ "Mai"\ "Jun"\ @@ -33,7 +33,7 @@ namespace eval ::tcl::clock { ::msgcat::mcset de_BE MONTHS_FULL [list \ "Januar"\ "Februar"\ - "M\u00e4rz"\ + "März"\ "April"\ "Mai"\ "Juni"\ diff --git a/library/msgs/el.msg b/library/msgs/el.msg index ac19f62..26bdfe9 100644 --- a/library/msgs/el.msg +++ b/library/msgs/el.msg @@ -1,51 +1,51 @@ # created by tools/loadICU.tcl -- do not edit namespace eval ::tcl::clock { ::msgcat::mcset el DAYS_OF_WEEK_ABBREV [list \ - "\u039a\u03c5\u03c1"\ - "\u0394\u03b5\u03c5"\ - "\u03a4\u03c1\u03b9"\ - "\u03a4\u03b5\u03c4"\ - "\u03a0\u03b5\u03bc"\ - "\u03a0\u03b1\u03c1"\ - "\u03a3\u03b1\u03b2"] + "Κυρ"\ + "Δευ"\ + "Τρι"\ + "Τετ"\ + "Πεμ"\ + "Παρ"\ + "Σαβ"] ::msgcat::mcset el DAYS_OF_WEEK_FULL [list \ - "\u039a\u03c5\u03c1\u03b9\u03b1\u03ba\u03ae"\ - "\u0394\u03b5\u03c5\u03c4\u03ad\u03c1\u03b1"\ - "\u03a4\u03c1\u03af\u03c4\u03b7"\ - "\u03a4\u03b5\u03c4\u03ac\u03c1\u03c4\u03b7"\ - "\u03a0\u03ad\u03bc\u03c0\u03c4\u03b7"\ - "\u03a0\u03b1\u03c1\u03b1\u03c3\u03ba\u03b5\u03c5\u03ae"\ - "\u03a3\u03ac\u03b2\u03b2\u03b1\u03c4\u03bf"] + "Κυριακή"\ + "Δευτέρα"\ + "Τρίτη"\ + "Τετάρτη"\ + "Πέμπτη"\ + "Παρασκευή"\ + "Σάββατο"] ::msgcat::mcset el MONTHS_ABBREV [list \ - "\u0399\u03b1\u03bd"\ - "\u03a6\u03b5\u03b2"\ - "\u039c\u03b1\u03c1"\ - "\u0391\u03c0\u03c1"\ - "\u039c\u03b1\u03ca"\ - "\u0399\u03bf\u03c5\u03bd"\ - "\u0399\u03bf\u03c5\u03bb"\ - "\u0391\u03c5\u03b3"\ - "\u03a3\u03b5\u03c0"\ - "\u039f\u03ba\u03c4"\ - "\u039d\u03bf\u03b5"\ - "\u0394\u03b5\u03ba"\ + "Ιαν"\ + "Φεβ"\ + "Μαρ"\ + "Απρ"\ + "Μαϊ"\ + "Ιουν"\ + "Ιουλ"\ + "Αυγ"\ + "Σεπ"\ + "Οκτ"\ + "Νοε"\ + "Δεκ"\ ""] ::msgcat::mcset el MONTHS_FULL [list \ - "\u0399\u03b1\u03bd\u03bf\u03c5\u03ac\u03c1\u03b9\u03bf\u03c2"\ - "\u03a6\u03b5\u03b2\u03c1\u03bf\u03c5\u03ac\u03c1\u03b9\u03bf\u03c2"\ - "\u039c\u03ac\u03c1\u03c4\u03b9\u03bf\u03c2"\ - "\u0391\u03c0\u03c1\u03af\u03bb\u03b9\u03bf\u03c2"\ - "\u039c\u03ac\u03ca\u03bf\u03c2"\ - "\u0399\u03bf\u03cd\u03bd\u03b9\u03bf\u03c2"\ - "\u0399\u03bf\u03cd\u03bb\u03b9\u03bf\u03c2"\ - "\u0391\u03cd\u03b3\u03bf\u03c5\u03c3\u03c4\u03bf\u03c2"\ - "\u03a3\u03b5\u03c0\u03c4\u03ad\u03bc\u03b2\u03c1\u03b9\u03bf\u03c2"\ - "\u039f\u03ba\u03c4\u03ce\u03b2\u03c1\u03b9\u03bf\u03c2"\ - "\u039d\u03bf\u03ad\u03bc\u03b2\u03c1\u03b9\u03bf\u03c2"\ - "\u0394\u03b5\u03ba\u03ad\u03bc\u03b2\u03c1\u03b9\u03bf\u03c2"\ + "Ιανουάριος"\ + "Φεβρουάριος"\ + "Μάρτιος"\ + "Απρίλιος"\ + "Μάϊος"\ + "Ιούνιος"\ + "Ιούλιος"\ + "Αύγουστος"\ + "Σεπτέμβριος"\ + "Οκτώβριος"\ + "Νοέμβριος"\ + "Δεκέμβριος"\ ""] - ::msgcat::mcset el AM "\u03c0\u03bc" - ::msgcat::mcset el PM "\u03bc\u03bc" + ::msgcat::mcset el AM "πμ" + ::msgcat::mcset el PM "μμ" ::msgcat::mcset el DATE_FORMAT "%e/%m/%Y" ::msgcat::mcset el TIME_FORMAT_12 "%l:%M:%S %P" ::msgcat::mcset el DATE_TIME_FORMAT "%e/%m/%Y %l:%M:%S %P %z" diff --git a/library/msgs/eo.msg b/library/msgs/eo.msg index 1d2a24f..b9b1500 100644 --- a/library/msgs/eo.msg +++ b/library/msgs/eo.msg @@ -5,15 +5,15 @@ namespace eval ::tcl::clock { "lu"\ "ma"\ "me"\ - "\u0135a"\ + "ĵa"\ "ve"\ "sa"] ::msgcat::mcset eo DAYS_OF_WEEK_FULL [list \ - "diman\u0109o"\ + "dimanĉo"\ "lundo"\ "mardo"\ "merkredo"\ - "\u0135a\u016ddo"\ + "ĵaŭdo"\ "vendredo"\ "sabato"] ::msgcat::mcset eo MONTHS_ABBREV [list \ @@ -24,7 +24,7 @@ namespace eval ::tcl::clock { "maj"\ "jun"\ "jul"\ - "a\u016dg"\ + "aŭg"\ "sep"\ "okt"\ "nov"\ @@ -38,7 +38,7 @@ namespace eval ::tcl::clock { "majo"\ "junio"\ "julio"\ - "a\u016dgusto"\ + "aŭgusto"\ "septembro"\ "oktobro"\ "novembro"\ diff --git a/library/msgs/es.msg b/library/msgs/es.msg index a24f0a1..6090eab 100644 --- a/library/msgs/es.msg +++ b/library/msgs/es.msg @@ -4,18 +4,18 @@ namespace eval ::tcl::clock { "dom"\ "lun"\ "mar"\ - "mi\u00e9"\ + "mié"\ "jue"\ "vie"\ - "s\u00e1b"] + "sáb"] ::msgcat::mcset es DAYS_OF_WEEK_FULL [list \ "domingo"\ "lunes"\ "martes"\ - "mi\u00e9rcoles"\ + "miércoles"\ "jueves"\ "viernes"\ - "s\u00e1bado"] + "sábado"] ::msgcat::mcset es MONTHS_ABBREV [list \ "ene"\ "feb"\ diff --git a/library/msgs/et.msg b/library/msgs/et.msg index 8d32e9e..a782f9b 100644 --- a/library/msgs/et.msg +++ b/library/msgs/et.msg @@ -9,17 +9,17 @@ namespace eval ::tcl::clock { "R"\ "L"] ::msgcat::mcset et DAYS_OF_WEEK_FULL [list \ - "p\u00fchap\u00e4ev"\ - "esmasp\u00e4ev"\ - "teisip\u00e4ev"\ - "kolmap\u00e4ev"\ - "neljap\u00e4ev"\ + "pühapäev"\ + "esmaspäev"\ + "teisipäev"\ + "kolmapäev"\ + "neljapäev"\ "reede"\ - "laup\u00e4ev"] + "laupäev"] ::msgcat::mcset et MONTHS_ABBREV [list \ "Jaan"\ "Veebr"\ - "M\u00e4rts"\ + "Märts"\ "Apr"\ "Mai"\ "Juuni"\ @@ -33,7 +33,7 @@ namespace eval ::tcl::clock { ::msgcat::mcset et MONTHS_FULL [list \ "Jaanuar"\ "Veebruar"\ - "M\u00e4rts"\ + "Märts"\ "Aprill"\ "Mai"\ "Juuni"\ diff --git a/library/msgs/fa.msg b/library/msgs/fa.msg index 89b2f90..6166e28 100644 --- a/library/msgs/fa.msg +++ b/library/msgs/fa.msg @@ -1,47 +1,47 @@ # created by tools/loadICU.tcl -- do not edit namespace eval ::tcl::clock { ::msgcat::mcset fa DAYS_OF_WEEK_ABBREV [list \ - "\u06cc\u2214"\ - "\u062f\u2214"\ - "\u0633\u2214"\ - "\u0686\u2214"\ - "\u067e\u2214"\ - "\u062c\u2214"\ - "\u0634\u2214"] + "ی∔"\ + "د∔"\ + "س∔"\ + "چ∔"\ + "پ∔"\ + "ج∔"\ + "ش∔"] ::msgcat::mcset fa DAYS_OF_WEEK_FULL [list \ - "\u06cc\u06cc\u200c\u0634\u0646\u0628\u0647"\ - "\u062f\u0648\u0634\u0646\u0628\u0647"\ - "\u0633\u0647\u200c\u0634\u0646\u0628\u0647"\ - "\u0686\u0647\u0627\u0631\u0634\u0646\u0628\u0647"\ - "\u067e\u0646\u062c\u200c\u0634\u0646\u0628\u0647"\ - "\u062c\u0645\u0639\u0647"\ - "\u0634\u0646\u0628\u0647"] + "یی‌شنبه"\ + "دوشنبه"\ + "سه‌شنبه"\ + "چهارشنبه"\ + "پنج‌شنبه"\ + "جمعه"\ + "شنبه"] ::msgcat::mcset fa MONTHS_ABBREV [list \ - "\u0698\u0627\u0646"\ - "\u0641\u0648\u0631"\ - "\u0645\u0627\u0631"\ - "\u0622\u0648\u0631"\ - "\u0645\u0640\u0647"\ - "\u0698\u0648\u0646"\ - "\u0698\u0648\u06cc"\ - "\u0627\u0648\u062a"\ - "\u0633\u067e\u062a"\ - "\u0627\u0643\u062a"\ - "\u0646\u0648\u0627"\ - "\u062f\u0633\u0627"\ + "ژان"\ + "فور"\ + "مار"\ + "آور"\ + "مـه"\ + "ژون"\ + "ژوی"\ + "اوت"\ + "سپت"\ + "اكت"\ + "نوا"\ + "دسا"\ ""] ::msgcat::mcset fa MONTHS_FULL [list \ - "\u0698\u0627\u0646\u0648\u06cc\u0647"\ - "\u0641\u0648\u0631\u0648\u06cc\u0647"\ - "\u0645\u0627\u0631\u0633"\ - "\u0622\u0648\u0631\u06cc\u0644"\ - "\u0645\u0647"\ - "\u0698\u0648\u0626\u0646"\ - "\u0698\u0648\u0626\u06cc\u0647"\ - "\u0627\u0648\u062a"\ - "\u0633\u067e\u062a\u0627\u0645\u0628\u0631"\ - "\u0627\u0643\u062a\u0628\u0631"\ - "\u0646\u0648\u0627\u0645\u0628\u0631"\ - "\u062f\u0633\u0627\u0645\u0628\u0631"\ + "ژانویه"\ + "فورویه"\ + "مارس"\ + "آوریل"\ + "مه"\ + "ژوئن"\ + "ژوئیه"\ + "اوت"\ + "سپتامبر"\ + "اكتبر"\ + "نوامبر"\ + "دسامبر"\ ""] } diff --git a/library/msgs/fa_in.msg b/library/msgs/fa_in.msg index adc9e91..ce32f99 100644 --- a/library/msgs/fa_in.msg +++ b/library/msgs/fa_in.msg @@ -1,51 +1,51 @@ # created by tools/loadICU.tcl -- do not edit namespace eval ::tcl::clock { ::msgcat::mcset fa_IN DAYS_OF_WEEK_ABBREV [list \ - "\u06cc\u2214"\ - "\u062f\u2214"\ - "\u0633\u2214"\ - "\u0686\u2214"\ - "\u067e\u2214"\ - "\u062c\u2214"\ - "\u0634\u2214"] + "ی∔"\ + "د∔"\ + "س∔"\ + "چ∔"\ + "پ∔"\ + "ج∔"\ + "ش∔"] ::msgcat::mcset fa_IN DAYS_OF_WEEK_FULL [list \ - "\u06cc\u06cc\u200c\u0634\u0646\u0628\u0647"\ - "\u062f\u0648\u0634\u0646\u0628\u0647"\ - "\u0633\u0647\u200c\u0634\u0646\u0628\u0647"\ - "\u0686\u0647\u0627\u0631\u0634\u0646\u0628\u0647"\ - "\u067e\u0646\u062c\u200c\u0634\u0646\u0628\u0647"\ - "\u062c\u0645\u0639\u0647"\ - "\u0634\u0646\u0628\u0647"] + "یی‌شنبه"\ + "دوشنبه"\ + "سه‌شنبه"\ + "چهارشنبه"\ + "پنج‌شنبه"\ + "جمعه"\ + "شنبه"] ::msgcat::mcset fa_IN MONTHS_ABBREV [list \ - "\u0698\u0627\u0646"\ - "\u0641\u0648\u0631"\ - "\u0645\u0627\u0631"\ - "\u0622\u0648\u0631"\ - "\u0645\u0640\u0647"\ - "\u0698\u0648\u0646"\ - "\u0698\u0648\u06cc"\ - "\u0627\u0648\u062a"\ - "\u0633\u067e\u062a"\ - "\u0627\u0643\u062a"\ - "\u0646\u0648\u0627"\ - "\u062f\u0633\u0627"\ + "ژان"\ + "فور"\ + "مار"\ + "آور"\ + "مـه"\ + "ژون"\ + "ژوی"\ + "اوت"\ + "سپت"\ + "اكت"\ + "نوا"\ + "دسا"\ ""] ::msgcat::mcset fa_IN MONTHS_FULL [list \ - "\u0698\u0627\u0646\u0648\u06cc\u0647"\ - "\u0641\u0648\u0631\u0648\u06cc\u0647"\ - "\u0645\u0627\u0631\u0633"\ - "\u0622\u0648\u0631\u06cc\u0644"\ - "\u0645\u0647"\ - "\u0698\u0648\u0626\u0646"\ - "\u0698\u0648\u0626\u06cc\u0647"\ - "\u0627\u0648\u062a"\ - "\u0633\u067e\u062a\u0627\u0645\u0628\u0631"\ - "\u0627\u0643\u062a\u0628\u0631"\ - "\u0646\u0648\u0627\u0645\u0628\u0631"\ - "\u062f\u0633\u0627\u0645\u0628\u0631"\ + "ژانویه"\ + "فورویه"\ + "مارس"\ + "آوریل"\ + "مه"\ + "ژوئن"\ + "ژوئیه"\ + "اوت"\ + "سپتامبر"\ + "اكتبر"\ + "نوامبر"\ + "دسامبر"\ ""] - ::msgcat::mcset fa_IN AM "\u0635\u0628\u062d" - ::msgcat::mcset fa_IN PM "\u0639\u0635\u0631" + ::msgcat::mcset fa_IN AM "صبح" + ::msgcat::mcset fa_IN PM "عصر" ::msgcat::mcset fa_IN DATE_FORMAT "%A %d %B %Y" ::msgcat::mcset fa_IN TIME_FORMAT_12 "%I:%M:%S %z" ::msgcat::mcset fa_IN DATE_TIME_FORMAT "%A %d %B %Y %I:%M:%S %z %z" diff --git a/library/msgs/fa_ir.msg b/library/msgs/fa_ir.msg index 597ce9d..9ce9284 100644 --- a/library/msgs/fa_ir.msg +++ b/library/msgs/fa_ir.msg @@ -1,9 +1,9 @@ # created by tools/loadICU.tcl -- do not edit namespace eval ::tcl::clock { - ::msgcat::mcset fa_IR AM "\u0635\u0628\u062d" - ::msgcat::mcset fa_IR PM "\u0639\u0635\u0631" - ::msgcat::mcset fa_IR DATE_FORMAT "%d\u2044%m\u2044%Y" + ::msgcat::mcset fa_IR AM "صبح" + ::msgcat::mcset fa_IR PM "عصر" + ::msgcat::mcset fa_IR DATE_FORMAT "%d⁄%m⁄%Y" ::msgcat::mcset fa_IR TIME_FORMAT "%S:%M:%H" ::msgcat::mcset fa_IR TIME_FORMAT_12 "%S:%M:%l %P" - ::msgcat::mcset fa_IR DATE_TIME_FORMAT "%d\u2044%m\u2044%Y %S:%M:%H %z" + ::msgcat::mcset fa_IR DATE_TIME_FORMAT "%d⁄%m⁄%Y %S:%M:%H %z" } diff --git a/library/msgs/fi.msg b/library/msgs/fi.msg index acabba0..69be367 100644 --- a/library/msgs/fi.msg +++ b/library/msgs/fi.msg @@ -22,8 +22,8 @@ namespace eval ::tcl::clock { "maalis"\ "huhti"\ "touko"\ - "kes\u00e4"\ - "hein\u00e4"\ + "kesä"\ + "heinä"\ "elo"\ "syys"\ "loka"\ @@ -36,8 +36,8 @@ namespace eval ::tcl::clock { "maaliskuu"\ "huhtikuu"\ "toukokuu"\ - "kes\u00e4kuu"\ - "hein\u00e4kuu"\ + "kesäkuu"\ + "heinäkuu"\ "elokuu"\ "syyskuu"\ "lokakuu"\ diff --git a/library/msgs/fo.msg b/library/msgs/fo.msg index 4696e62..1f1794d 100644 --- a/library/msgs/fo.msg +++ b/library/msgs/fo.msg @@ -2,19 +2,19 @@ namespace eval ::tcl::clock { ::msgcat::mcset fo DAYS_OF_WEEK_ABBREV [list \ "sun"\ - "m\u00e1n"\ - "t\u00fds"\ + "mán"\ + "týs"\ "mik"\ - "h\u00f3s"\ - "fr\u00ed"\ + "hós"\ + "frí"\ "ley"] ::msgcat::mcset fo DAYS_OF_WEEK_FULL [list \ "sunnudagur"\ - "m\u00e1nadagur"\ - "t\u00fdsdagur"\ + "mánadagur"\ + "týsdagur"\ "mikudagur"\ - "h\u00f3sdagur"\ - "fr\u00edggjadagur"\ + "hósdagur"\ + "fríggjadagur"\ "leygardagur"] ::msgcat::mcset fo MONTHS_ABBREV [list \ "jan"\ @@ -34,7 +34,7 @@ namespace eval ::tcl::clock { "januar"\ "februar"\ "mars"\ - "apr\u00edl"\ + "apríl"\ "mai"\ "juni"\ "juli"\ diff --git a/library/msgs/fr.msg b/library/msgs/fr.msg index 55b19bf..a274468 100644 --- a/library/msgs/fr.msg +++ b/library/msgs/fr.msg @@ -18,31 +18,31 @@ namespace eval ::tcl::clock { "samedi"] ::msgcat::mcset fr MONTHS_ABBREV [list \ "janv."\ - "f\u00e9vr."\ + "févr."\ "mars"\ "avr."\ "mai"\ "juin"\ "juil."\ - "ao\u00fbt"\ + "août"\ "sept."\ "oct."\ "nov."\ - "d\u00e9c."\ + "déc."\ ""] ::msgcat::mcset fr MONTHS_FULL [list \ "janvier"\ - "f\u00e9vrier"\ + "février"\ "mars"\ "avril"\ "mai"\ "juin"\ "juillet"\ - "ao\u00fbt"\ + "août"\ "septembre"\ "octobre"\ "novembre"\ - "d\u00e9cembre"\ + "décembre"\ ""] ::msgcat::mcset fr BCE "av. J.-C." ::msgcat::mcset fr CE "ap. J.-C." diff --git a/library/msgs/ga.msg b/library/msgs/ga.msg index 6edf13a..056c9a0 100644 --- a/library/msgs/ga.msg +++ b/library/msgs/ga.msg @@ -3,45 +3,45 @@ namespace eval ::tcl::clock { ::msgcat::mcset ga DAYS_OF_WEEK_ABBREV [list \ "Domh"\ "Luan"\ - "M\u00e1irt"\ - "C\u00e9ad"\ - "D\u00e9ar"\ + "Máirt"\ + "Céad"\ + "Déar"\ "Aoine"\ "Sath"] ::msgcat::mcset ga DAYS_OF_WEEK_FULL [list \ - "D\u00e9 Domhnaigh"\ - "D\u00e9 Luain"\ - "D\u00e9 M\u00e1irt"\ - "D\u00e9 C\u00e9adaoin"\ - "D\u00e9ardaoin"\ - "D\u00e9 hAoine"\ - "D\u00e9 Sathairn"] + "Dé Domhnaigh"\ + "Dé Luain"\ + "Dé Máirt"\ + "Dé Céadaoin"\ + "Déardaoin"\ + "Dé hAoine"\ + "Dé Sathairn"] ::msgcat::mcset ga MONTHS_ABBREV [list \ "Ean"\ "Feabh"\ - "M\u00e1rta"\ + "Márta"\ "Aib"\ "Beal"\ "Meith"\ - "I\u00fail"\ - "L\u00fan"\ - "MF\u00f3mh"\ - "DF\u00f3mh"\ + "Iúil"\ + "Lún"\ + "MFómh"\ + "DFómh"\ "Samh"\ "Noll"\ ""] ::msgcat::mcset ga MONTHS_FULL [list \ - "Ean\u00e1ir"\ + "Eanáir"\ "Feabhra"\ - "M\u00e1rta"\ - "Aibre\u00e1n"\ - "M\u00ed na Bealtaine"\ + "Márta"\ + "Aibreán"\ + "Mí na Bealtaine"\ "Meith"\ - "I\u00fail"\ - "L\u00fanasa"\ - "Me\u00e1n F\u00f3mhair"\ - "Deireadh F\u00f3mhair"\ - "M\u00ed na Samhna"\ - "M\u00ed na Nollag"\ + "Iúil"\ + "Lúnasa"\ + "Meán Fómhair"\ + "Deireadh Fómhair"\ + "Mí na Samhna"\ + "Mí na Nollag"\ ""] } diff --git a/library/msgs/gl.msg b/library/msgs/gl.msg index 4b869e8..c2fefc9 100644 --- a/library/msgs/gl.msg +++ b/library/msgs/gl.msg @@ -4,25 +4,25 @@ namespace eval ::tcl::clock { "Dom"\ "Lun"\ "Mar"\ - "M\u00e9r"\ + "Mér"\ "Xov"\ "Ven"\ - "S\u00e1b"] + "Sáb"] ::msgcat::mcset gl DAYS_OF_WEEK_FULL [list \ "Domingo"\ "Luns"\ "Martes"\ - "M\u00e9rcores"\ + "Mércores"\ "Xoves"\ "Venres"\ - "S\u00e1bado"] + "Sábado"] ::msgcat::mcset gl MONTHS_ABBREV [list \ "Xan"\ "Feb"\ "Mar"\ "Abr"\ "Mai"\ - "Xu\u00f1"\ + "Xuñ"\ "Xul"\ "Ago"\ "Set"\ @@ -36,7 +36,7 @@ namespace eval ::tcl::clock { "Marzo"\ "Abril"\ "Maio"\ - "Xu\u00f1o"\ + "Xuño"\ "Xullo"\ "Agosto"\ "Setembro"\ diff --git a/library/msgs/he.msg b/library/msgs/he.msg index 4fd921d..13a81b7 100644 --- a/library/msgs/he.msg +++ b/library/msgs/he.msg @@ -1,51 +1,51 @@ # created by tools/loadICU.tcl -- do not edit namespace eval ::tcl::clock { ::msgcat::mcset he DAYS_OF_WEEK_ABBREV [list \ - "\u05d0"\ - "\u05d1"\ - "\u05d2"\ - "\u05d3"\ - "\u05d4"\ - "\u05d5"\ - "\u05e9"] + "א"\ + "ב"\ + "ג"\ + "ד"\ + "ה"\ + "ו"\ + "ש"] ::msgcat::mcset he DAYS_OF_WEEK_FULL [list \ - "\u05d9\u05d5\u05dd \u05e8\u05d0\u05e9\u05d5\u05df"\ - "\u05d9\u05d5\u05dd \u05e9\u05e0\u05d9"\ - "\u05d9\u05d5\u05dd \u05e9\u05dc\u05d9\u05e9\u05d9"\ - "\u05d9\u05d5\u05dd \u05e8\u05d1\u05d9\u05e2\u05d9"\ - "\u05d9\u05d5\u05dd \u05d7\u05de\u05d9\u05e9\u05d9"\ - "\u05d9\u05d5\u05dd \u05e9\u05d9\u05e9\u05d9"\ - "\u05e9\u05d1\u05ea"] + "יום ראשון"\ + "יום שני"\ + "יום שלישי"\ + "יום רביעי"\ + "יום חמישי"\ + "יום שישי"\ + "שבת"] ::msgcat::mcset he MONTHS_ABBREV [list \ - "\u05d9\u05e0\u05d5"\ - "\u05e4\u05d1\u05e8"\ - "\u05de\u05e8\u05e5"\ - "\u05d0\u05e4\u05e8"\ - "\u05de\u05d0\u05d9"\ - "\u05d9\u05d5\u05e0"\ - "\u05d9\u05d5\u05dc"\ - "\u05d0\u05d5\u05d2"\ - "\u05e1\u05e4\u05d8"\ - "\u05d0\u05d5\u05e7"\ - "\u05e0\u05d5\u05d1"\ - "\u05d3\u05e6\u05de"\ + "ינו"\ + "פבר"\ + "מרץ"\ + "אפר"\ + "מאי"\ + "יונ"\ + "יול"\ + "אוג"\ + "ספט"\ + "אוק"\ + "נוב"\ + "דצמ"\ ""] ::msgcat::mcset he MONTHS_FULL [list \ - "\u05d9\u05e0\u05d5\u05d0\u05e8"\ - "\u05e4\u05d1\u05e8\u05d5\u05d0\u05e8"\ - "\u05de\u05e8\u05e5"\ - "\u05d0\u05e4\u05e8\u05d9\u05dc"\ - "\u05de\u05d0\u05d9"\ - "\u05d9\u05d5\u05e0\u05d9"\ - "\u05d9\u05d5\u05dc\u05d9"\ - "\u05d0\u05d5\u05d2\u05d5\u05e1\u05d8"\ - "\u05e1\u05e4\u05d8\u05de\u05d1\u05e8"\ - "\u05d0\u05d5\u05e7\u05d8\u05d5\u05d1\u05e8"\ - "\u05e0\u05d5\u05d1\u05de\u05d1\u05e8"\ - "\u05d3\u05e6\u05de\u05d1\u05e8"\ + "ינואר"\ + "פברואר"\ + "מרץ"\ + "אפריל"\ + "מאי"\ + "יוני"\ + "יולי"\ + "אוגוסט"\ + "ספטמבר"\ + "אוקטובר"\ + "נובמבר"\ + "דצמבר"\ ""] - ::msgcat::mcset he BCE "\u05dc\u05e1\u05d4\u0022\u05e0" - ::msgcat::mcset he CE "\u05dc\u05e4\u05e1\u05d4\u0022\u05e0" + ::msgcat::mcset he BCE "לסה"נ" + ::msgcat::mcset he CE "לפסה"נ" ::msgcat::mcset he DATE_FORMAT "%d/%m/%Y" ::msgcat::mcset he TIME_FORMAT "%H:%M:%S" ::msgcat::mcset he DATE_TIME_FORMAT "%d/%m/%Y %H:%M:%S %z" diff --git a/library/msgs/hi.msg b/library/msgs/hi.msg index 50c9fb8..18c8bf0 100644 --- a/library/msgs/hi.msg +++ b/library/msgs/hi.msg @@ -1,39 +1,39 @@ # created by tools/loadICU.tcl -- do not edit namespace eval ::tcl::clock { ::msgcat::mcset hi DAYS_OF_WEEK_FULL [list \ - "\u0930\u0935\u093f\u0935\u093e\u0930"\ - "\u0938\u094b\u092e\u0935\u093e\u0930"\ - "\u092e\u0902\u0917\u0932\u0935\u093e\u0930"\ - "\u092c\u0941\u0927\u0935\u093e\u0930"\ - "\u0917\u0941\u0930\u0941\u0935\u093e\u0930"\ - "\u0936\u0941\u0915\u094d\u0930\u0935\u093e\u0930"\ - "\u0936\u0928\u093f\u0935\u093e\u0930"] + "रविवार"\ + "सोमवार"\ + "मंगलवार"\ + "बुधवार"\ + "गुरुवार"\ + "शुक्रवार"\ + "शनिवार"] ::msgcat::mcset hi MONTHS_ABBREV [list \ - "\u091c\u0928\u0935\u0930\u0940"\ - "\u092b\u093c\u0930\u0935\u0930\u0940"\ - "\u092e\u093e\u0930\u094d\u091a"\ - "\u0905\u092a\u094d\u0930\u0947\u0932"\ - "\u092e\u0908"\ - "\u091c\u0942\u0928"\ - "\u091c\u0941\u0932\u093e\u0908"\ - "\u0905\u0917\u0938\u094d\u0924"\ - "\u0938\u093f\u0924\u092e\u094d\u092c\u0930"\ - "\u0905\u0915\u094d\u091f\u0942\u092c\u0930"\ - "\u0928\u0935\u092e\u094d\u092c\u0930"\ - "\u0926\u093f\u0938\u092e\u094d\u092c\u0930"] + "जनवरी"\ + "फ़रवरी"\ + "मार्च"\ + "अप्रेल"\ + "मई"\ + "जून"\ + "जुलाई"\ + "अगस्त"\ + "सितम्बर"\ + "अक्टूबर"\ + "नवम्बर"\ + "दिसम्बर"] ::msgcat::mcset hi MONTHS_FULL [list \ - "\u091c\u0928\u0935\u0930\u0940"\ - "\u092b\u093c\u0930\u0935\u0930\u0940"\ - "\u092e\u093e\u0930\u094d\u091a"\ - "\u0905\u092a\u094d\u0930\u0947\u0932"\ - "\u092e\u0908"\ - "\u091c\u0942\u0928"\ - "\u091c\u0941\u0932\u093e\u0908"\ - "\u0905\u0917\u0938\u094d\u0924"\ - "\u0938\u093f\u0924\u092e\u094d\u092c\u0930"\ - "\u0905\u0915\u094d\u091f\u0942\u092c\u0930"\ - "\u0928\u0935\u092e\u094d\u092c\u0930"\ - "\u0926\u093f\u0938\u092e\u094d\u092c\u0930"] - ::msgcat::mcset hi AM "\u0908\u0938\u093e\u092a\u0942\u0930\u094d\u0935" + "जनवरी"\ + "फ़रवरी"\ + "मार्च"\ + "अप्रेल"\ + "मई"\ + "जून"\ + "जुलाई"\ + "अगस्त"\ + "सितम्बर"\ + "अक्टूबर"\ + "नवम्बर"\ + "दिसम्बर"] + ::msgcat::mcset hi AM "ईसापूर्व" ::msgcat::mcset hi PM "." } diff --git a/library/msgs/hr.msg b/library/msgs/hr.msg index cec145b..30491e1 100644 --- a/library/msgs/hr.msg +++ b/library/msgs/hr.msg @@ -5,7 +5,7 @@ namespace eval ::tcl::clock { "pon"\ "uto"\ "sri"\ - "\u010det"\ + "čet"\ "pet"\ "sub"] ::msgcat::mcset hr DAYS_OF_WEEK_FULL [list \ @@ -13,13 +13,13 @@ namespace eval ::tcl::clock { "ponedjeljak"\ "utorak"\ "srijeda"\ - "\u010detvrtak"\ + "četvrtak"\ "petak"\ "subota"] ::msgcat::mcset hr MONTHS_ABBREV [list \ "sij"\ "vel"\ - "o\u017eu"\ + "ožu"\ "tra"\ "svi"\ "lip"\ @@ -31,9 +31,9 @@ namespace eval ::tcl::clock { "pro"\ ""] ::msgcat::mcset hr MONTHS_FULL [list \ - "sije\u010danj"\ - "velja\u010da"\ - "o\u017eujak"\ + "siječanj"\ + "veljača"\ + "ožujak"\ "travanj"\ "svibanj"\ "lipanj"\ diff --git a/library/msgs/hu.msg b/library/msgs/hu.msg index e5e68d9..46776dd 100644 --- a/library/msgs/hu.msg +++ b/library/msgs/hu.msg @@ -9,21 +9,21 @@ namespace eval ::tcl::clock { "P"\ "Szo"] ::msgcat::mcset hu DAYS_OF_WEEK_FULL [list \ - "vas\u00e1rnap"\ - "h\u00e9tf\u0151"\ + "vasárnap"\ + "hétfő"\ "kedd"\ "szerda"\ - "cs\u00fct\u00f6rt\u00f6k"\ - "p\u00e9ntek"\ + "csütörtök"\ + "péntek"\ "szombat"] ::msgcat::mcset hu MONTHS_ABBREV [list \ "jan."\ "febr."\ - "m\u00e1rc."\ - "\u00e1pr."\ - "m\u00e1j."\ - "j\u00fan."\ - "j\u00fal."\ + "márc."\ + "ápr."\ + "máj."\ + "jún."\ + "júl."\ "aug."\ "szept."\ "okt."\ @@ -31,16 +31,16 @@ namespace eval ::tcl::clock { "dec."\ ""] ::msgcat::mcset hu MONTHS_FULL [list \ - "janu\u00e1r"\ - "febru\u00e1r"\ - "m\u00e1rcius"\ - "\u00e1prilis"\ - "m\u00e1jus"\ - "j\u00fanius"\ - "j\u00falius"\ + "január"\ + "február"\ + "március"\ + "április"\ + "május"\ + "június"\ + "július"\ "augusztus"\ "szeptember"\ - "okt\u00f3ber"\ + "október"\ "november"\ "december"\ ""] diff --git a/library/msgs/is.msg b/library/msgs/is.msg index adc2d2a..a369b89 100644 --- a/library/msgs/is.msg +++ b/library/msgs/is.msg @@ -2,46 +2,46 @@ namespace eval ::tcl::clock { ::msgcat::mcset is DAYS_OF_WEEK_ABBREV [list \ "sun."\ - "m\u00e1n."\ - "\u00feri."\ - "mi\u00f0."\ + "mán."\ + "þri."\ + "mið."\ "fim."\ - "f\u00f6s."\ + "fös."\ "lau."] ::msgcat::mcset is DAYS_OF_WEEK_FULL [list \ "sunnudagur"\ - "m\u00e1nudagur"\ - "\u00feri\u00f0judagur"\ - "mi\u00f0vikudagur"\ + "mánudagur"\ + "þriðjudagur"\ + "miðvikudagur"\ "fimmtudagur"\ - "f\u00f6studagur"\ + "föstudagur"\ "laugardagur"] ::msgcat::mcset is MONTHS_ABBREV [list \ "jan."\ "feb."\ "mar."\ "apr."\ - "ma\u00ed"\ - "j\u00fan."\ - "j\u00fal."\ - "\u00e1g\u00fa."\ + "maí"\ + "jún."\ + "júl."\ + "ágú."\ "sep."\ "okt."\ - "n\u00f3v."\ + "nóv."\ "des."\ ""] ::msgcat::mcset is MONTHS_FULL [list \ - "jan\u00faar"\ - "febr\u00faar"\ + "janúar"\ + "febrúar"\ "mars"\ - "apr\u00edl"\ - "ma\u00ed"\ - "j\u00fan\u00ed"\ - "j\u00fal\u00ed"\ - "\u00e1g\u00fast"\ + "apríl"\ + "maí"\ + "júní"\ + "júlí"\ + "ágúst"\ "september"\ - "okt\u00f3ber"\ - "n\u00f3vember"\ + "október"\ + "nóvember"\ "desember"\ ""] ::msgcat::mcset is DATE_FORMAT "%e.%m.%Y" diff --git a/library/msgs/it.msg b/library/msgs/it.msg index b641cde..e51aee2 100644 --- a/library/msgs/it.msg +++ b/library/msgs/it.msg @@ -10,11 +10,11 @@ namespace eval ::tcl::clock { "sab"] ::msgcat::mcset it DAYS_OF_WEEK_FULL [list \ "domenica"\ - "luned\u00ec"\ - "marted\u00ec"\ - "mercoled\u00ec"\ - "gioved\u00ec"\ - "venerd\u00ec"\ + "lunedì"\ + "martedì"\ + "mercoledì"\ + "giovedì"\ + "venerdì"\ "sabato"] ::msgcat::mcset it MONTHS_ABBREV [list \ "gen"\ diff --git a/library/msgs/ja.msg b/library/msgs/ja.msg index 2767665..76b5fa4 100644 --- a/library/msgs/ja.msg +++ b/library/msgs/ja.msg @@ -1,44 +1,44 @@ # created by tools/loadICU.tcl -- do not edit namespace eval ::tcl::clock { ::msgcat::mcset ja DAYS_OF_WEEK_ABBREV [list \ - "\u65e5"\ - "\u6708"\ - "\u706b"\ - "\u6c34"\ - "\u6728"\ - "\u91d1"\ - "\u571f"] + "日"\ + "月"\ + "火"\ + "水"\ + "木"\ + "金"\ + "土"] ::msgcat::mcset ja DAYS_OF_WEEK_FULL [list \ - "\u65e5\u66dc\u65e5"\ - "\u6708\u66dc\u65e5"\ - "\u706b\u66dc\u65e5"\ - "\u6c34\u66dc\u65e5"\ - "\u6728\u66dc\u65e5"\ - "\u91d1\u66dc\u65e5"\ - "\u571f\u66dc\u65e5"] + "日曜日"\ + "月曜日"\ + "火曜日"\ + "水曜日"\ + "木曜日"\ + "金曜日"\ + "土曜日"] ::msgcat::mcset ja MONTHS_FULL [list \ - "1\u6708"\ - "2\u6708"\ - "3\u6708"\ - "4\u6708"\ - "5\u6708"\ - "6\u6708"\ - "7\u6708"\ - "8\u6708"\ - "9\u6708"\ - "10\u6708"\ - "11\u6708"\ - "12\u6708"] - ::msgcat::mcset ja BCE "\u7d00\u5143\u524d" - ::msgcat::mcset ja CE "\u897f\u66a6" - ::msgcat::mcset ja AM "\u5348\u524d" - ::msgcat::mcset ja PM "\u5348\u5f8c" + "1月"\ + "2月"\ + "3月"\ + "4月"\ + "5月"\ + "6月"\ + "7月"\ + "8月"\ + "9月"\ + "10月"\ + "11月"\ + "12月"] + ::msgcat::mcset ja BCE "紀元前" + ::msgcat::mcset ja CE "西暦" + ::msgcat::mcset ja AM "午前" + ::msgcat::mcset ja PM "午後" ::msgcat::mcset ja DATE_FORMAT "%Y/%m/%d" ::msgcat::mcset ja TIME_FORMAT "%k:%M:%S" ::msgcat::mcset ja TIME_FORMAT_12 "%P %I:%M:%S" ::msgcat::mcset ja DATE_TIME_FORMAT "%Y/%m/%d %k:%M:%S %z" - ::msgcat::mcset ja LOCALE_DATE_FORMAT "%EY\u5e74%m\u6708%d\u65e5" - ::msgcat::mcset ja LOCALE_TIME_FORMAT "%H\u6642%M\u5206%S\u79d2" - ::msgcat::mcset ja LOCALE_DATE_TIME_FORMAT "%EY\u5e74%m\u6708%d\u65e5 (%a) %H\u6642%M\u5206%S\u79d2 %z" - ::msgcat::mcset ja LOCALE_ERAS "\u007b-9223372036854775808 \u897f\u66a6 0\u007d \u007b-3061011600 \u660e\u6cbb 1867\u007d \u007b-1812186000 \u5927\u6b63 1911\u007d \u007b-1357635600 \u662d\u548c 1925\u007d \u007b600220800 \u5e73\u6210 1988\u007d" + ::msgcat::mcset ja LOCALE_DATE_FORMAT "%EY年%m月%d日" + ::msgcat::mcset ja LOCALE_TIME_FORMAT "%H時%M分%S秒" + ::msgcat::mcset ja LOCALE_DATE_TIME_FORMAT "%EY年%m月%d日 (%a) %H時%M分%S秒 %z" + ::msgcat::mcset ja LOCALE_ERAS "{-9223372036854775808 西暦 0} {-3061011600 明治 1867} {-1812186000 大正 1911} {-1357635600 昭和 1925} {600220800 平成 1988}" } diff --git a/library/msgs/ko.msg b/library/msgs/ko.msg index 0cd17a1..817c2e7 100644 --- a/library/msgs/ko.msg +++ b/library/msgs/ko.msg @@ -1,55 +1,55 @@ # created by tools/loadICU.tcl -- do not edit namespace eval ::tcl::clock { ::msgcat::mcset ko DAYS_OF_WEEK_ABBREV [list \ - "\uc77c"\ - "\uc6d4"\ - "\ud654"\ - "\uc218"\ - "\ubaa9"\ - "\uae08"\ - "\ud1a0"] + "일"\ + "월"\ + "화"\ + "수"\ + "목"\ + "금"\ + "토"] ::msgcat::mcset ko DAYS_OF_WEEK_FULL [list \ - "\uc77c\uc694\uc77c"\ - "\uc6d4\uc694\uc77c"\ - "\ud654\uc694\uc77c"\ - "\uc218\uc694\uc77c"\ - "\ubaa9\uc694\uc77c"\ - "\uae08\uc694\uc77c"\ - "\ud1a0\uc694\uc77c"] + "일요일"\ + "월요일"\ + "화요일"\ + "수요일"\ + "목요일"\ + "금요일"\ + "토요일"] ::msgcat::mcset ko MONTHS_ABBREV [list \ - "1\uc6d4"\ - "2\uc6d4"\ - "3\uc6d4"\ - "4\uc6d4"\ - "5\uc6d4"\ - "6\uc6d4"\ - "7\uc6d4"\ - "8\uc6d4"\ - "9\uc6d4"\ - "10\uc6d4"\ - "11\uc6d4"\ - "12\uc6d4"\ + "1월"\ + "2월"\ + "3월"\ + "4월"\ + "5월"\ + "6월"\ + "7월"\ + "8월"\ + "9월"\ + "10월"\ + "11월"\ + "12월"\ ""] ::msgcat::mcset ko MONTHS_FULL [list \ - "1\uc6d4"\ - "2\uc6d4"\ - "3\uc6d4"\ - "4\uc6d4"\ - "5\uc6d4"\ - "6\uc6d4"\ - "7\uc6d4"\ - "8\uc6d4"\ - "9\uc6d4"\ - "10\uc6d4"\ - "11\uc6d4"\ - "12\uc6d4"\ + "1월"\ + "2월"\ + "3월"\ + "4월"\ + "5월"\ + "6월"\ + "7월"\ + "8월"\ + "9월"\ + "10월"\ + "11월"\ + "12월"\ ""] - ::msgcat::mcset ko AM "\uc624\uc804" - ::msgcat::mcset ko PM "\uc624\ud6c4" + ::msgcat::mcset ko AM "오전" + ::msgcat::mcset ko PM "오후" ::msgcat::mcset ko DATE_FORMAT "%Y-%m-%d" ::msgcat::mcset ko TIME_FORMAT_12 "%P %l:%M:%S" ::msgcat::mcset ko DATE_TIME_FORMAT "%Y-%m-%d %P %l:%M:%S %z" - ::msgcat::mcset ko LOCALE_DATE_FORMAT "%Y\ub144%B%Od\uc77c" - ::msgcat::mcset ko LOCALE_TIME_FORMAT "%H\uc2dc%M\ubd84%S\ucd08" - ::msgcat::mcset ko LOCALE_DATE_TIME_FORMAT "%A %Y\ub144%B%Od\uc77c%H\uc2dc%M\ubd84%S\ucd08 %z" + ::msgcat::mcset ko LOCALE_DATE_FORMAT "%Y년%B%Od일" + ::msgcat::mcset ko LOCALE_TIME_FORMAT "%H시%M분%S초" + ::msgcat::mcset ko LOCALE_DATE_TIME_FORMAT "%A %Y년%B%Od일%H시%M분%S초 %z" } diff --git a/library/msgs/ko_kr.msg b/library/msgs/ko_kr.msg index ea5bbd7..f23bd6b 100644 --- a/library/msgs/ko_kr.msg +++ b/library/msgs/ko_kr.msg @@ -1,7 +1,7 @@ # created by tools/loadICU.tcl -- do not edit namespace eval ::tcl::clock { - ::msgcat::mcset ko_KR BCE "\uae30\uc6d0\uc804" - ::msgcat::mcset ko_KR CE "\uc11c\uae30" + ::msgcat::mcset ko_KR BCE "기원전" + ::msgcat::mcset ko_KR CE "서기" ::msgcat::mcset ko_KR DATE_FORMAT "%Y.%m.%d" ::msgcat::mcset ko_KR TIME_FORMAT_12 "%P %l:%M:%S" ::msgcat::mcset ko_KR DATE_TIME_FORMAT "%Y.%m.%d %P %l:%M:%S %z" diff --git a/library/msgs/kok.msg b/library/msgs/kok.msg index 0869f20..231853b 100644 --- a/library/msgs/kok.msg +++ b/library/msgs/kok.msg @@ -1,39 +1,39 @@ # created by tools/loadICU.tcl -- do not edit namespace eval ::tcl::clock { ::msgcat::mcset kok DAYS_OF_WEEK_FULL [list \ - "\u0906\u0926\u093f\u0924\u094d\u092f\u0935\u093e\u0930"\ - "\u0938\u094b\u092e\u0935\u093e\u0930"\ - "\u092e\u0902\u0917\u0933\u093e\u0930"\ - "\u092c\u0941\u0927\u0935\u093e\u0930"\ - "\u0917\u0941\u0930\u0941\u0935\u093e\u0930"\ - "\u0936\u0941\u0915\u094d\u0930\u0935\u093e\u0930"\ - "\u0936\u0928\u093f\u0935\u093e\u0930"] + "आदित्यवार"\ + "सोमवार"\ + "मंगळार"\ + "बुधवार"\ + "गुरुवार"\ + "शुक्रवार"\ + "शनिवार"] ::msgcat::mcset kok MONTHS_ABBREV [list \ - "\u091c\u093e\u0928\u0947\u0935\u093e\u0930\u0940"\ - "\u092b\u0947\u092c\u0943\u0935\u093e\u0930\u0940"\ - "\u092e\u093e\u0930\u094d\u091a"\ - "\u090f\u092a\u094d\u0930\u093f\u0932"\ - "\u092e\u0947"\ - "\u091c\u0942\u0928"\ - "\u091c\u0941\u0932\u0948"\ - "\u0913\u0917\u0938\u094d\u091f"\ - "\u0938\u0947\u092a\u094d\u091f\u0947\u0902\u092c\u0930"\ - "\u0913\u0915\u094d\u091f\u094b\u092c\u0930"\ - "\u0928\u094b\u0935\u094d\u0939\u0947\u0902\u092c\u0930"\ - "\u0921\u093f\u0938\u0947\u0902\u092c\u0930"] + "जानेवारी"\ + "फेबृवारी"\ + "मार्च"\ + "एप्रिल"\ + "मे"\ + "जून"\ + "जुलै"\ + "ओगस्ट"\ + "सेप्टेंबर"\ + "ओक्टोबर"\ + "नोव्हेंबर"\ + "डिसेंबर"] ::msgcat::mcset kok MONTHS_FULL [list \ - "\u091c\u093e\u0928\u0947\u0935\u093e\u0930\u0940"\ - "\u092b\u0947\u092c\u094d\u0930\u0941\u0935\u093e\u0930\u0940"\ - "\u092e\u093e\u0930\u094d\u091a"\ - "\u090f\u092a\u094d\u0930\u093f\u0932"\ - "\u092e\u0947"\ - "\u091c\u0942\u0928"\ - "\u091c\u0941\u0932\u0948"\ - "\u0913\u0917\u0938\u094d\u091f"\ - "\u0938\u0947\u092a\u094d\u091f\u0947\u0902\u092c\u0930"\ - "\u0913\u0915\u094d\u091f\u094b\u092c\u0930"\ - "\u0928\u094b\u0935\u094d\u0939\u0947\u0902\u092c\u0930"\ - "\u0921\u093f\u0938\u0947\u0902\u092c\u0930"] - ::msgcat::mcset kok AM "\u0915\u094d\u0930\u093f\u0938\u094d\u0924\u092a\u0942\u0930\u094d\u0935" - ::msgcat::mcset kok PM "\u0915\u094d\u0930\u093f\u0938\u094d\u0924\u0936\u0916\u093e" + "जानेवारी"\ + "फेब्रुवारी"\ + "मार्च"\ + "एप्रिल"\ + "मे"\ + "जून"\ + "जुलै"\ + "ओगस्ट"\ + "सेप्टेंबर"\ + "ओक्टोबर"\ + "नोव्हेंबर"\ + "डिसेंबर"] + ::msgcat::mcset kok AM "क्रिस्तपूर्व" + ::msgcat::mcset kok PM "क्रिस्तशखा" } diff --git a/library/msgs/lt.msg b/library/msgs/lt.msg index 27b0985..15829a9 100644 --- a/library/msgs/lt.msg +++ b/library/msgs/lt.msg @@ -7,15 +7,15 @@ namespace eval ::tcl::clock { "Tr"\ "Kt"\ "Pn"\ - "\u0160t"] + "Št"] ::msgcat::mcset lt DAYS_OF_WEEK_FULL [list \ "Sekmadienis"\ "Pirmadienis"\ "Antradienis"\ - "Tre\u010diadienis"\ + "Trečiadienis"\ "Ketvirtadienis"\ "Penktadienis"\ - "\u0160e\u0161tadienis"] + "Šeštadienis"] ::msgcat::mcset lt MONTHS_ABBREV [list \ "Sau"\ "Vas"\ @@ -34,15 +34,15 @@ namespace eval ::tcl::clock { "Sausio"\ "Vasario"\ "Kovo"\ - "Baland\u017eio"\ - "Gegu\u017e\u0117s"\ - "Bir\u017eelio"\ + "Balandžio"\ + "Gegužės"\ + "Birželio"\ "Liepos"\ - "Rugpj\u016b\u010dio"\ - "Rugs\u0117jo"\ + "Rugpjūčio"\ + "Rugsėjo"\ "Spalio"\ - "Lapkri\u010dio"\ - "Gruod\u017eio"\ + "Lapkričio"\ + "Gruodžio"\ ""] ::msgcat::mcset lt BCE "pr.Kr." ::msgcat::mcset lt CE "po.Kr." diff --git a/library/msgs/lv.msg b/library/msgs/lv.msg index a037b15..730fd33 100644 --- a/library/msgs/lv.msg +++ b/library/msgs/lv.msg @@ -9,10 +9,10 @@ namespace eval ::tcl::clock { "Pk"\ "S"] ::msgcat::mcset lv DAYS_OF_WEEK_FULL [list \ - "sv\u0113tdiena"\ + "svētdiena"\ "pirmdiena"\ "otrdiena"\ - "tre\u0161diena"\ + "trešdiena"\ "ceturdien"\ "piektdiena"\ "sestdiena"] @@ -22,8 +22,8 @@ namespace eval ::tcl::clock { "Mar"\ "Apr"\ "Maijs"\ - "J\u016bn"\ - "J\u016bl"\ + "Jūn"\ + "Jūl"\ "Aug"\ "Sep"\ "Okt"\ @@ -31,21 +31,21 @@ namespace eval ::tcl::clock { "Dec"\ ""] ::msgcat::mcset lv MONTHS_FULL [list \ - "janv\u0101ris"\ - "febru\u0101ris"\ + "janvāris"\ + "februāris"\ "marts"\ - "apr\u012blis"\ + "aprīlis"\ "maijs"\ - "j\u016bnijs"\ - "j\u016blijs"\ + "jūnijs"\ + "jūlijs"\ "augusts"\ "septembris"\ "oktobris"\ "novembris"\ "decembris"\ ""] - ::msgcat::mcset lv BCE "pm\u0113" - ::msgcat::mcset lv CE "m\u0113" + ::msgcat::mcset lv BCE "pmē" + ::msgcat::mcset lv CE "mē" ::msgcat::mcset lv DATE_FORMAT "%Y.%e.%m" ::msgcat::mcset lv TIME_FORMAT "%H:%M:%S" ::msgcat::mcset lv DATE_TIME_FORMAT "%Y.%e.%m %H:%M:%S %z" diff --git a/library/msgs/mk.msg b/library/msgs/mk.msg index 41cf60d..9b7bd9d 100644 --- a/library/msgs/mk.msg +++ b/library/msgs/mk.msg @@ -1,51 +1,51 @@ # created by tools/loadICU.tcl -- do not edit namespace eval ::tcl::clock { ::msgcat::mcset mk DAYS_OF_WEEK_ABBREV [list \ - "\u043d\u0435\u0434."\ - "\u043f\u043e\u043d."\ - "\u0432\u0442."\ - "\u0441\u0440\u0435."\ - "\u0447\u0435\u0442."\ - "\u043f\u0435\u0442."\ - "\u0441\u0430\u0431."] + "нед."\ + "пон."\ + "вт."\ + "сре."\ + "чет."\ + "пет."\ + "саб."] ::msgcat::mcset mk DAYS_OF_WEEK_FULL [list \ - "\u043d\u0435\u0434\u0435\u043b\u0430"\ - "\u043f\u043e\u043d\u0435\u0434\u0435\u043b\u043d\u0438\u043a"\ - "\u0432\u0442\u043e\u0440\u043d\u0438\u043a"\ - "\u0441\u0440\u0435\u0434\u0430"\ - "\u0447\u0435\u0442\u0432\u0440\u0442\u043e\u043a"\ - "\u043f\u0435\u0442\u043e\u043a"\ - "\u0441\u0430\u0431\u043e\u0442\u0430"] + "недела"\ + "понеделник"\ + "вторник"\ + "среда"\ + "четврток"\ + "петок"\ + "сабота"] ::msgcat::mcset mk MONTHS_ABBREV [list \ - "\u0458\u0430\u043d."\ - "\u0444\u0435\u0432."\ - "\u043c\u0430\u0440."\ - "\u0430\u043f\u0440."\ - "\u043c\u0430\u0458."\ - "\u0458\u0443\u043d."\ - "\u0458\u0443\u043b."\ - "\u0430\u0432\u0433."\ - "\u0441\u0435\u043f\u0442."\ - "\u043e\u043a\u0442."\ - "\u043d\u043e\u0435\u043c."\ - "\u0434\u0435\u043a\u0435\u043c."\ + "јан."\ + "фев."\ + "мар."\ + "апр."\ + "мај."\ + "јун."\ + "јул."\ + "авг."\ + "септ."\ + "окт."\ + "ноем."\ + "декем."\ ""] ::msgcat::mcset mk MONTHS_FULL [list \ - "\u0458\u0430\u043d\u0443\u0430\u0440\u0438"\ - "\u0444\u0435\u0432\u0440\u0443\u0430\u0440\u0438"\ - "\u043c\u0430\u0440\u0442"\ - "\u0430\u043f\u0440\u0438\u043b"\ - "\u043c\u0430\u0458"\ - "\u0458\u0443\u043d\u0438"\ - "\u0458\u0443\u043b\u0438"\ - "\u0430\u0432\u0433\u0443\u0441\u0442"\ - "\u0441\u0435\u043f\u0442\u0435\u043c\u0432\u0440\u0438"\ - "\u043e\u043a\u0442\u043e\u043c\u0432\u0440\u0438"\ - "\u043d\u043e\u0435\u043c\u0432\u0440\u0438"\ - "\u0434\u0435\u043a\u0435\u043c\u0432\u0440\u0438"\ + "јануари"\ + "февруари"\ + "март"\ + "април"\ + "мај"\ + "јуни"\ + "јули"\ + "август"\ + "септември"\ + "октомври"\ + "ноември"\ + "декември"\ ""] - ::msgcat::mcset mk BCE "\u043f\u0440.\u043d.\u0435." - ::msgcat::mcset mk CE "\u0430\u0435." + ::msgcat::mcset mk BCE "пр.н.е." + ::msgcat::mcset mk CE "ае." ::msgcat::mcset mk DATE_FORMAT "%e.%m.%Y" ::msgcat::mcset mk TIME_FORMAT "%H:%M:%S %z" ::msgcat::mcset mk DATE_TIME_FORMAT "%e.%m.%Y %H:%M:%S %z %z" diff --git a/library/msgs/mr.msg b/library/msgs/mr.msg index cea427a..e475615 100644 --- a/library/msgs/mr.msg +++ b/library/msgs/mr.msg @@ -1,39 +1,39 @@ # created by tools/loadICU.tcl -- do not edit namespace eval ::tcl::clock { ::msgcat::mcset mr DAYS_OF_WEEK_FULL [list \ - "\u0930\u0935\u093f\u0935\u093e\u0930"\ - "\u0938\u094b\u092e\u0935\u093e\u0930"\ - "\u092e\u0902\u0917\u0933\u0935\u093e\u0930"\ - "\u092e\u0902\u0917\u0933\u0935\u093e\u0930"\ - "\u0917\u0941\u0930\u0941\u0935\u093e\u0930"\ - "\u0936\u0941\u0915\u094d\u0930\u0935\u093e\u0930"\ - "\u0936\u0928\u093f\u0935\u093e\u0930"] + "रविवार"\ + "सोमवार"\ + "मंगळवार"\ + "मंगळवार"\ + "गुरुवार"\ + "शुक्रवार"\ + "शनिवार"] ::msgcat::mcset mr MONTHS_ABBREV [list \ - "\u091c\u093e\u0928\u0947\u0935\u093e\u0930\u0940"\ - "\u092b\u0947\u092c\u0943\u0935\u093e\u0930\u0940"\ - "\u092e\u093e\u0930\u094d\u091a"\ - "\u090f\u092a\u094d\u0930\u093f\u0932"\ - "\u092e\u0947"\ - "\u091c\u0942\u0928"\ - "\u091c\u0941\u0932\u0948"\ - "\u0913\u0917\u0938\u094d\u091f"\ - "\u0938\u0947\u092a\u094d\u091f\u0947\u0902\u092c\u0930"\ - "\u0913\u0915\u094d\u091f\u094b\u092c\u0930"\ - "\u0928\u094b\u0935\u094d\u0939\u0947\u0902\u092c\u0930"\ - "\u0921\u093f\u0938\u0947\u0902\u092c\u0930"] + "जानेवारी"\ + "फेबृवारी"\ + "मार्च"\ + "एप्रिल"\ + "मे"\ + "जून"\ + "जुलै"\ + "ओगस्ट"\ + "सेप्टेंबर"\ + "ओक्टोबर"\ + "नोव्हेंबर"\ + "डिसेंबर"] ::msgcat::mcset mr MONTHS_FULL [list \ - "\u091c\u093e\u0928\u0947\u0935\u093e\u0930\u0940"\ - "\u092b\u0947\u092c\u0943\u0935\u093e\u0930\u0940"\ - "\u092e\u093e\u0930\u094d\u091a"\ - "\u090f\u092a\u094d\u0930\u093f\u0932"\ - "\u092e\u0947"\ - "\u091c\u0942\u0928"\ - "\u091c\u0941\u0932\u0948"\ - "\u0913\u0917\u0938\u094d\u091f"\ - "\u0938\u0947\u092a\u094d\u091f\u0947\u0902\u092c\u0930"\ - "\u0913\u0915\u094d\u091f\u094b\u092c\u0930"\ - "\u0928\u094b\u0935\u094d\u0939\u0947\u0902\u092c\u0930"\ - "\u0921\u093f\u0938\u0947\u0902\u092c\u0930"] + "जानेवारी"\ + "फेबृवारी"\ + "मार्च"\ + "एप्रिल"\ + "मे"\ + "जून"\ + "जुलै"\ + "ओगस्ट"\ + "सेप्टेंबर"\ + "ओक्टोबर"\ + "नोव्हेंबर"\ + "डिसेंबर"] ::msgcat::mcset mr AM "BC" ::msgcat::mcset mr PM "AD" } diff --git a/library/msgs/mt.msg b/library/msgs/mt.msg index ddd5446..c479e47 100644 --- a/library/msgs/mt.msg +++ b/library/msgs/mt.msg @@ -1,19 +1,19 @@ # created by tools/loadICU.tcl -- do not edit namespace eval ::tcl::clock { ::msgcat::mcset mt DAYS_OF_WEEK_ABBREV [list \ - "\u0126ad"\ + "Ħad"\ "Tne"\ "Tli"\ "Erb"\ - "\u0126am"\ - "\u0120im"] + "Ħam"\ + "Ġim"] ::msgcat::mcset mt MONTHS_ABBREV [list \ "Jan"\ "Fra"\ "Mar"\ "Apr"\ "Mej"\ - "\u0120un"\ + "Ġun"\ "Lul"\ "Awi"\ "Set"\ diff --git a/library/msgs/nb.msg b/library/msgs/nb.msg index 90d49a3..4dd76c7 100644 --- a/library/msgs/nb.msg +++ b/library/msgs/nb.msg @@ -1,21 +1,21 @@ # created by tools/loadICU.tcl -- do not edit namespace eval ::tcl::clock { ::msgcat::mcset nb DAYS_OF_WEEK_ABBREV [list \ - "s\u00f8"\ + "sø"\ "ma"\ "ti"\ "on"\ "to"\ "fr"\ - "l\u00f8"] + "lø"] ::msgcat::mcset nb DAYS_OF_WEEK_FULL [list \ - "s\u00f8ndag"\ + "søndag"\ "mandag"\ "tirsdag"\ "onsdag"\ "torsdag"\ "fredag"\ - "l\u00f8rdag"] + "lørdag"] ::msgcat::mcset nb MONTHS_ABBREV [list \ "jan"\ "feb"\ diff --git a/library/msgs/nn.msg b/library/msgs/nn.msg index bd61ac9..b61a2dd 100644 --- a/library/msgs/nn.msg +++ b/library/msgs/nn.msg @@ -2,7 +2,7 @@ namespace eval ::tcl::clock { ::msgcat::mcset nn DAYS_OF_WEEK_ABBREV [list \ "su"\ - "m\u00e5"\ + "må"\ "ty"\ "on"\ "to"\ @@ -10,7 +10,7 @@ namespace eval ::tcl::clock { "lau"] ::msgcat::mcset nn DAYS_OF_WEEK_FULL [list \ "sundag"\ - "m\u00e5ndag"\ + "måndag"\ "tysdag"\ "onsdag"\ "torsdag"\ diff --git a/library/msgs/pl.msg b/library/msgs/pl.msg index d206f4b..821eea7 100644 --- a/library/msgs/pl.msg +++ b/library/msgs/pl.msg @@ -4,17 +4,17 @@ namespace eval ::tcl::clock { "N"\ "Pn"\ "Wt"\ - "\u015ar"\ + "Śr"\ "Cz"\ "Pt"\ "So"] ::msgcat::mcset pl DAYS_OF_WEEK_FULL [list \ "niedziela"\ - "poniedzia\u0142ek"\ + "poniedziałek"\ "wtorek"\ - "\u015broda"\ + "środa"\ "czwartek"\ - "pi\u0105tek"\ + "piątek"\ "sobota"] ::msgcat::mcset pl MONTHS_ABBREV [list \ "sty"\ @@ -26,23 +26,23 @@ namespace eval ::tcl::clock { "lip"\ "sie"\ "wrz"\ - "pa\u017a"\ + "paź"\ "lis"\ "gru"\ ""] ::msgcat::mcset pl MONTHS_FULL [list \ - "stycze\u0144"\ + "styczeń"\ "luty"\ "marzec"\ - "kwiecie\u0144"\ + "kwiecień"\ "maj"\ "czerwiec"\ "lipiec"\ - "sierpie\u0144"\ - "wrzesie\u0144"\ - "pa\u017adziernik"\ + "sierpień"\ + "wrzesień"\ + "październik"\ "listopad"\ - "grudzie\u0144"\ + "grudzień"\ ""] ::msgcat::mcset pl BCE "p.n.e." ::msgcat::mcset pl CE "n.e." diff --git a/library/msgs/pt.msg b/library/msgs/pt.msg index 96fdb35..425c1f6 100644 --- a/library/msgs/pt.msg +++ b/library/msgs/pt.msg @@ -7,15 +7,15 @@ namespace eval ::tcl::clock { "Qua"\ "Qui"\ "Sex"\ - "S\u00e1b"] + "Sáb"] ::msgcat::mcset pt DAYS_OF_WEEK_FULL [list \ "Domingo"\ "Segunda-feira"\ - "Ter\u00e7a-feira"\ + "Terça-feira"\ "Quarta-feira"\ "Quinta-feira"\ "Sexta-feira"\ - "S\u00e1bado"] + "Sábado"] ::msgcat::mcset pt MONTHS_ABBREV [list \ "Jan"\ "Fev"\ @@ -33,7 +33,7 @@ namespace eval ::tcl::clock { ::msgcat::mcset pt MONTHS_FULL [list \ "Janeiro"\ "Fevereiro"\ - "Mar\u00e7o"\ + "Março"\ "Abril"\ "Maio"\ "Junho"\ diff --git a/library/msgs/ro.msg b/library/msgs/ro.msg index bdd7c61..f4452ba 100644 --- a/library/msgs/ro.msg +++ b/library/msgs/ro.msg @@ -9,13 +9,13 @@ namespace eval ::tcl::clock { "V"\ "S"] ::msgcat::mcset ro DAYS_OF_WEEK_FULL [list \ - "duminic\u0103"\ + "duminică"\ "luni"\ - "mar\u0163i"\ + "marţi"\ "miercuri"\ "joi"\ "vineri"\ - "s\u00eemb\u0103t\u0103"] + "sîmbătă"] ::msgcat::mcset ro MONTHS_ABBREV [list \ "Ian"\ "Feb"\ @@ -45,7 +45,7 @@ namespace eval ::tcl::clock { "decembrie"\ ""] ::msgcat::mcset ro BCE "d.C." - ::msgcat::mcset ro CE "\u00ee.d.C." + ::msgcat::mcset ro CE "î.d.C." ::msgcat::mcset ro DATE_FORMAT "%d.%m.%Y" ::msgcat::mcset ro TIME_FORMAT "%H:%M:%S" ::msgcat::mcset ro DATE_TIME_FORMAT "%d.%m.%Y %H:%M:%S %z" diff --git a/library/msgs/ru.msg b/library/msgs/ru.msg index 65b075d..983a253 100644 --- a/library/msgs/ru.msg +++ b/library/msgs/ru.msg @@ -1,51 +1,51 @@ # created by tools/loadICU.tcl -- do not edit namespace eval ::tcl::clock { ::msgcat::mcset ru DAYS_OF_WEEK_ABBREV [list \ - "\u0412\u0441"\ - "\u041f\u043d"\ - "\u0412\u0442"\ - "\u0421\u0440"\ - "\u0427\u0442"\ - "\u041f\u0442"\ - "\u0421\u0431"] + "Вс"\ + "Пн"\ + "Вт"\ + "Ср"\ + "Чт"\ + "Пт"\ + "Сб"] ::msgcat::mcset ru DAYS_OF_WEEK_FULL [list \ - "\u0432\u043e\u0441\u043a\u0440\u0435\u0441\u0435\u043d\u044c\u0435"\ - "\u043f\u043e\u043d\u0435\u0434\u0435\u043b\u044c\u043d\u0438\u043a"\ - "\u0432\u0442\u043e\u0440\u043d\u0438\u043a"\ - "\u0441\u0440\u0435\u0434\u0430"\ - "\u0447\u0435\u0442\u0432\u0435\u0440\u0433"\ - "\u043f\u044f\u0442\u043d\u0438\u0446\u0430"\ - "\u0441\u0443\u0431\u0431\u043e\u0442\u0430"] + "воскресенье"\ + "понедельник"\ + "вторник"\ + "среда"\ + "четверг"\ + "пятница"\ + "суббота"] ::msgcat::mcset ru MONTHS_ABBREV [list \ - "\u044f\u043d\u0432"\ - "\u0444\u0435\u0432"\ - "\u043c\u0430\u0440"\ - "\u0430\u043f\u0440"\ - "\u043c\u0430\u0439"\ - "\u0438\u044e\u043d"\ - "\u0438\u044e\u043b"\ - "\u0430\u0432\u0433"\ - "\u0441\u0435\u043d"\ - "\u043e\u043a\u0442"\ - "\u043d\u043e\u044f"\ - "\u0434\u0435\u043a"\ + "янв"\ + "фев"\ + "мар"\ + "апр"\ + "май"\ + "июн"\ + "июл"\ + "авг"\ + "сен"\ + "окт"\ + "ноя"\ + "дек"\ ""] ::msgcat::mcset ru MONTHS_FULL [list \ - "\u042f\u043d\u0432\u0430\u0440\u044c"\ - "\u0424\u0435\u0432\u0440\u0430\u043b\u044c"\ - "\u041c\u0430\u0440\u0442"\ - "\u0410\u043f\u0440\u0435\u043b\u044c"\ - "\u041c\u0430\u0439"\ - "\u0418\u044e\u043d\u044c"\ - "\u0418\u044e\u043b\u044c"\ - "\u0410\u0432\u0433\u0443\u0441\u0442"\ - "\u0421\u0435\u043d\u0442\u044f\u0431\u0440\u044c"\ - "\u041e\u043a\u0442\u044f\u0431\u0440\u044c"\ - "\u041d\u043e\u044f\u0431\u0440\u044c"\ - "\u0414\u0435\u043a\u0430\u0431\u0440\u044c"\ + "Январь"\ + "Февраль"\ + "Март"\ + "Апрель"\ + "Май"\ + "Июнь"\ + "Июль"\ + "Август"\ + "Сентябрь"\ + "Октябрь"\ + "Ноябрь"\ + "Декабрь"\ ""] - ::msgcat::mcset ru BCE "\u0434\u043e \u043d.\u044d." - ::msgcat::mcset ru CE "\u043d.\u044d." + ::msgcat::mcset ru BCE "до н.э." + ::msgcat::mcset ru CE "н.э." ::msgcat::mcset ru DATE_FORMAT "%d.%m.%Y" ::msgcat::mcset ru TIME_FORMAT "%k:%M:%S" ::msgcat::mcset ru DATE_TIME_FORMAT "%d.%m.%Y %k:%M:%S %z" diff --git a/library/msgs/sh.msg b/library/msgs/sh.msg index 6ee0fc7..2e4143d 100644 --- a/library/msgs/sh.msg +++ b/library/msgs/sh.msg @@ -5,7 +5,7 @@ namespace eval ::tcl::clock { "Pon"\ "Uto"\ "Sre"\ - "\u010cet"\ + "Čet"\ "Pet"\ "Sub"] ::msgcat::mcset sh DAYS_OF_WEEK_FULL [list \ @@ -13,7 +13,7 @@ namespace eval ::tcl::clock { "Ponedeljak"\ "Utorak"\ "Sreda"\ - "\u010cetvrtak"\ + "Četvrtak"\ "Petak"\ "Subota"] ::msgcat::mcset sh MONTHS_ABBREV [list \ diff --git a/library/msgs/sk.msg b/library/msgs/sk.msg index 9b2f0aa..dc6f6b6 100644 --- a/library/msgs/sk.msg +++ b/library/msgs/sk.msg @@ -5,15 +5,15 @@ namespace eval ::tcl::clock { "Po"\ "Ut"\ "St"\ - "\u0160t"\ + "Št"\ "Pa"\ "So"] ::msgcat::mcset sk DAYS_OF_WEEK_FULL [list \ - "Nede\u013ee"\ + "Nedeľe"\ "Pondelok"\ "Utorok"\ "Streda"\ - "\u0160tvrtok"\ + "Štvrtok"\ "Piatok"\ "Sobota"] ::msgcat::mcset sk MONTHS_ABBREV [list \ @@ -21,9 +21,9 @@ namespace eval ::tcl::clock { "feb"\ "mar"\ "apr"\ - "m\u00e1j"\ - "j\u00fan"\ - "j\u00fal"\ + "máj"\ + "jún"\ + "júl"\ "aug"\ "sep"\ "okt"\ @@ -31,16 +31,16 @@ namespace eval ::tcl::clock { "dec"\ ""] ::msgcat::mcset sk MONTHS_FULL [list \ - "janu\u00e1r"\ - "febru\u00e1r"\ + "január"\ + "február"\ "marec"\ - "apr\u00edl"\ - "m\u00e1j"\ - "j\u00fan"\ - "j\u00fal"\ + "apríl"\ + "máj"\ + "jún"\ + "júl"\ "august"\ "september"\ - "okt\u00f3ber"\ + "október"\ "november"\ "december"\ ""] diff --git a/library/msgs/sl.msg b/library/msgs/sl.msg index 42bc509..2ee0a03 100644 --- a/library/msgs/sl.msg +++ b/library/msgs/sl.msg @@ -5,7 +5,7 @@ namespace eval ::tcl::clock { "Pon"\ "Tor"\ "Sre"\ - "\u010cet"\ + "Čet"\ "Pet"\ "Sob"] ::msgcat::mcset sl DAYS_OF_WEEK_FULL [list \ @@ -13,7 +13,7 @@ namespace eval ::tcl::clock { "Ponedeljek"\ "Torek"\ "Sreda"\ - "\u010cetrtek"\ + "Četrtek"\ "Petek"\ "Sobota"] ::msgcat::mcset sl MONTHS_ABBREV [list \ @@ -44,7 +44,7 @@ namespace eval ::tcl::clock { "november"\ "december"\ ""] - ::msgcat::mcset sl BCE "pr.n.\u0161." + ::msgcat::mcset sl BCE "pr.n.š." ::msgcat::mcset sl CE "po Kr." ::msgcat::mcset sl DATE_FORMAT "%Y.%m.%e" ::msgcat::mcset sl TIME_FORMAT "%k:%M:%S" diff --git a/library/msgs/sq.msg b/library/msgs/sq.msg index 8fb1fce..65da407 100644 --- a/library/msgs/sq.msg +++ b/library/msgs/sq.msg @@ -2,20 +2,20 @@ namespace eval ::tcl::clock { ::msgcat::mcset sq DAYS_OF_WEEK_ABBREV [list \ "Die"\ - "H\u00ebn"\ + "Hën"\ "Mar"\ - "M\u00ebr"\ + "Mër"\ "Enj"\ "Pre"\ "Sht"] ::msgcat::mcset sq DAYS_OF_WEEK_FULL [list \ "e diel"\ - "e h\u00ebn\u00eb"\ - "e mart\u00eb"\ - "e m\u00ebrkur\u00eb"\ + "e hënë"\ + "e martë"\ + "e mërkurë"\ "e enjte"\ "e premte"\ - "e shtun\u00eb"] + "e shtunë"] ::msgcat::mcset sq MONTHS_ABBREV [list \ "Jan"\ "Shk"\ @@ -27,7 +27,7 @@ namespace eval ::tcl::clock { "Gsh"\ "Sht"\ "Tet"\ - "N\u00ebn"\ + "Nën"\ "Dhj"\ ""] ::msgcat::mcset sq MONTHS_FULL [list \ @@ -41,7 +41,7 @@ namespace eval ::tcl::clock { "gusht"\ "shtator"\ "tetor"\ - "n\u00ebntor"\ + "nëntor"\ "dhjetor"\ ""] ::msgcat::mcset sq BCE "p.e.r." diff --git a/library/msgs/sr.msg b/library/msgs/sr.msg index 7576668..3d84d6c 100644 --- a/library/msgs/sr.msg +++ b/library/msgs/sr.msg @@ -1,51 +1,51 @@ # created by tools/loadICU.tcl -- do not edit namespace eval ::tcl::clock { ::msgcat::mcset sr DAYS_OF_WEEK_ABBREV [list \ - "\u041d\u0435\u0434"\ - "\u041f\u043e\u043d"\ - "\u0423\u0442\u043e"\ - "\u0421\u0440\u0435"\ - "\u0427\u0435\u0442"\ - "\u041f\u0435\u0442"\ - "\u0421\u0443\u0431"] + "Нед"\ + "Пон"\ + "Уто"\ + "Сре"\ + "Чет"\ + "Пет"\ + "Суб"] ::msgcat::mcset sr DAYS_OF_WEEK_FULL [list \ - "\u041d\u0435\u0434\u0435\u0459\u0430"\ - "\u041f\u043e\u043d\u0435\u0434\u0435\u0459\u0430\u043a"\ - "\u0423\u0442\u043e\u0440\u0430\u043a"\ - "\u0421\u0440\u0435\u0434\u0430"\ - "\u0427\u0435\u0442\u0432\u0440\u0442\u0430\u043a"\ - "\u041f\u0435\u0442\u0430\u043a"\ - "\u0421\u0443\u0431\u043e\u0442\u0430"] + "Недеља"\ + "Понедељак"\ + "Уторак"\ + "Среда"\ + "Четвртак"\ + "Петак"\ + "Субота"] ::msgcat::mcset sr MONTHS_ABBREV [list \ - "\u0408\u0430\u043d"\ - "\u0424\u0435\u0431"\ - "\u041c\u0430\u0440"\ - "\u0410\u043f\u0440"\ - "\u041c\u0430\u0458"\ - "\u0408\u0443\u043d"\ - "\u0408\u0443\u043b"\ - "\u0410\u0432\u0433"\ - "\u0421\u0435\u043f"\ - "\u041e\u043a\u0442"\ - "\u041d\u043e\u0432"\ - "\u0414\u0435\u0446"\ + "Јан"\ + "Феб"\ + "Мар"\ + "Апр"\ + "Мај"\ + "Јун"\ + "Јул"\ + "Авг"\ + "Сеп"\ + "Окт"\ + "Нов"\ + "Дец"\ ""] ::msgcat::mcset sr MONTHS_FULL [list \ - "\u0408\u0430\u043d\u0443\u0430\u0440"\ - "\u0424\u0435\u0431\u0440\u0443\u0430\u0440"\ - "\u041c\u0430\u0440\u0442"\ - "\u0410\u043f\u0440\u0438\u043b"\ - "\u041c\u0430\u0458"\ - "\u0408\u0443\u043d\u0438"\ - "\u0408\u0443\u043b\u0438"\ - "\u0410\u0432\u0433\u0443\u0441\u0442"\ - "\u0421\u0435\u043f\u0442\u0435\u043c\u0431\u0430\u0440"\ - "\u041e\u043a\u0442\u043e\u0431\u0430\u0440"\ - "\u041d\u043e\u0432\u0435\u043c\u0431\u0430\u0440"\ - "\u0414\u0435\u0446\u0435\u043c\u0431\u0430\u0440"\ + "Јануар"\ + "Фебруар"\ + "Март"\ + "Април"\ + "Мај"\ + "Јуни"\ + "Јули"\ + "Август"\ + "Септембар"\ + "Октобар"\ + "Новембар"\ + "Децембар"\ ""] - ::msgcat::mcset sr BCE "\u043f. \u043d. \u0435." - ::msgcat::mcset sr CE "\u043d. \u0435" + ::msgcat::mcset sr BCE "п. н. е." + ::msgcat::mcset sr CE "н. е" ::msgcat::mcset sr DATE_FORMAT "%Y.%m.%e" ::msgcat::mcset sr TIME_FORMAT "%k.%M.%S" ::msgcat::mcset sr DATE_TIME_FORMAT "%Y.%m.%e %k.%M.%S %z" diff --git a/library/msgs/sv.msg b/library/msgs/sv.msg index f7a67c6..5716092 100644 --- a/library/msgs/sv.msg +++ b/library/msgs/sv.msg @@ -1,21 +1,21 @@ # created by tools/loadICU.tcl -- do not edit namespace eval ::tcl::clock { ::msgcat::mcset sv DAYS_OF_WEEK_ABBREV [list \ - "s\u00f6"\ - "m\u00e5"\ + "sö"\ + "må"\ "ti"\ "on"\ "to"\ "fr"\ - "l\u00f6"] + "lö"] ::msgcat::mcset sv DAYS_OF_WEEK_FULL [list \ - "s\u00f6ndag"\ - "m\u00e5ndag"\ + "söndag"\ + "måndag"\ "tisdag"\ "onsdag"\ "torsdag"\ "fredag"\ - "l\u00f6rdag"] + "lördag"] ::msgcat::mcset sv MONTHS_ABBREV [list \ "jan"\ "feb"\ diff --git a/library/msgs/ta.msg b/library/msgs/ta.msg index 4abb90c..ea62552 100644 --- a/library/msgs/ta.msg +++ b/library/msgs/ta.msg @@ -1,39 +1,39 @@ # created by tools/loadICU.tcl -- do not edit namespace eval ::tcl::clock { ::msgcat::mcset ta DAYS_OF_WEEK_FULL [list \ - "\u0b9e\u0bbe\u0baf\u0bbf\u0bb1\u0bc1"\ - "\u0ba4\u0bbf\u0b99\u0bcd\u0b95\u0bb3\u0bcd"\ - "\u0b9a\u0bc6\u0bb5\u0bcd\u0bb5\u0bbe\u0baf\u0bcd"\ - "\u0baa\u0bc1\u0ba4\u0ba9\u0bcd"\ - "\u0bb5\u0bbf\u0baf\u0bbe\u0bb4\u0ba9\u0bcd"\ - "\u0bb5\u0bc6\u0bb3\u0bcd\u0bb3\u0bbf"\ - "\u0b9a\u0ba9\u0bbf"] + "ஞாயிறு"\ + "திங்கள்"\ + "செவ்வாய்"\ + "புதன்"\ + "வியாழன்"\ + "வெள்ளி"\ + "சனி"] ::msgcat::mcset ta MONTHS_ABBREV [list \ - "\u0b9c\u0ba9\u0bb5\u0bb0\u0bbf"\ - "\u0baa\u0bc6\u0baa\u0bcd\u0bb0\u0bb5\u0bb0\u0bbf"\ - "\u0bae\u0bbe\u0bb0\u0bcd\u0b9a\u0bcd"\ - "\u0b8f\u0baa\u0bcd\u0bb0\u0bb2\u0bcd"\ - "\u0bae\u0bc7"\ - "\u0b9c\u0bc2\u0ba9\u0bcd"\ - "\u0b9c\u0bc2\u0bb2\u0bc8"\ - "\u0b86\u0b95\u0bb8\u0bcd\u0b9f\u0bcd"\ - "\u0b9a\u0bc6\u0baa\u0bcd\u0b9f\u0bae\u0bcd\u0baa\u0bb0\u0bcd"\ - "\u0b85\u0b95\u0bcd\u0b9f\u0bcb\u0baa\u0bb0\u0bcd"\ - "\u0ba8\u0bb5\u0bae\u0bcd\u0baa\u0bb0\u0bcd"\ - "\u0b9f\u0bbf\u0b9a\u0bae\u0bcd\u0baa\u0bb0\u0bcdr"] + "ஜனவரி"\ + "பெப்ரவரி"\ + "மார்ச்"\ + "ஏப்ரல்"\ + "மே"\ + "ஜூன்"\ + "ஜூலை"\ + "ஆகஸ்ட்"\ + "செப்டம்பர்"\ + "அக்டோபர்"\ + "நவம்பர்"\ + "டிசம்பர்r"] ::msgcat::mcset ta MONTHS_FULL [list \ - "\u0b9c\u0ba9\u0bb5\u0bb0\u0bbf"\ - "\u0baa\u0bc6\u0baa\u0bcd\u0bb0\u0bb5\u0bb0\u0bbf"\ - "\u0bae\u0bbe\u0bb0\u0bcd\u0b9a\u0bcd"\ - "\u0b8f\u0baa\u0bcd\u0bb0\u0bb2\u0bcd"\ - "\u0bae\u0bc7"\ - "\u0b9c\u0bc2\u0ba9\u0bcd"\ - "\u0b9c\u0bc2\u0bb2\u0bc8"\ - "\u0b86\u0b95\u0bb8\u0bcd\u0b9f\u0bcd"\ - "\u0b9a\u0bc6\u0baa\u0bcd\u0b9f\u0bae\u0bcd\u0baa\u0bb0\u0bcd"\ - "\u0b85\u0b95\u0bcd\u0b9f\u0bcb\u0baa\u0bb0\u0bcd"\ - "\u0ba8\u0bb5\u0bae\u0bcd\u0baa\u0bb0\u0bcd"\ - "\u0b9f\u0bbf\u0b9a\u0bae\u0bcd\u0baa\u0bb0\u0bcdr"] - ::msgcat::mcset ta AM "\u0b95\u0bbf\u0bae\u0bc1" - ::msgcat::mcset ta PM "\u0b95\u0bbf\u0baa\u0bbf" + "ஜனவரி"\ + "பெப்ரவரி"\ + "மார்ச்"\ + "ஏப்ரல்"\ + "மே"\ + "ஜூன்"\ + "ஜூலை"\ + "ஆகஸ்ட்"\ + "செப்டம்பர்"\ + "அக்டோபர்"\ + "நவம்பர்"\ + "டிசம்பர்r"] + ::msgcat::mcset ta AM "கிமு" + ::msgcat::mcset ta PM "கிபி" } diff --git a/library/msgs/te.msg b/library/msgs/te.msg index 6111473..f35ece4 100644 --- a/library/msgs/te.msg +++ b/library/msgs/te.msg @@ -1,47 +1,47 @@ # created by tools/loadICU.tcl -- do not edit namespace eval ::tcl::clock { ::msgcat::mcset te DAYS_OF_WEEK_ABBREV [list \ - "\u0c06\u0c26\u0c3f"\ - "\u0c38\u0c4b\u0c2e"\ - "\u0c2e\u0c02\u0c17\u0c33"\ - "\u0c2c\u0c41\u0c27"\ - "\u0c17\u0c41\u0c30\u0c41"\ - "\u0c36\u0c41\u0c15\u0c4d\u0c30"\ - "\u0c36\u0c28\u0c3f"] + "ఆది"\ + "సోమ"\ + "మంగళ"\ + "బుధ"\ + "గురు"\ + "శుక్ర"\ + "శని"] ::msgcat::mcset te DAYS_OF_WEEK_FULL [list \ - "\u0c06\u0c26\u0c3f\u0c35\u0c3e\u0c30\u0c02"\ - "\u0c38\u0c4b\u0c2e\u0c35\u0c3e\u0c30\u0c02"\ - "\u0c2e\u0c02\u0c17\u0c33\u0c35\u0c3e\u0c30\u0c02"\ - "\u0c2c\u0c41\u0c27\u0c35\u0c3e\u0c30\u0c02"\ - "\u0c17\u0c41\u0c30\u0c41\u0c35\u0c3e\u0c30\u0c02"\ - "\u0c36\u0c41\u0c15\u0c4d\u0c30\u0c35\u0c3e\u0c30\u0c02"\ - "\u0c36\u0c28\u0c3f\u0c35\u0c3e\u0c30\u0c02"] + "ఆదివారం"\ + "సోమవారం"\ + "మంగళవారం"\ + "బుధవారం"\ + "గురువారం"\ + "శుక్రవారం"\ + "శనివారం"] ::msgcat::mcset te MONTHS_ABBREV [list \ - "\u0c1c\u0c28\u0c35\u0c30\u0c3f"\ - "\u0c2b\u0c3f\u0c2c\u0c4d\u0c30\u0c35\u0c30\u0c3f"\ - "\u0c2e\u0c3e\u0c30\u0c4d\u0c1a\u0c3f"\ - "\u0c0f\u0c2a\u0c4d\u0c30\u0c3f\u0c32\u0c4d"\ - "\u0c2e\u0c47"\ - "\u0c1c\u0c42\u0c28\u0c4d"\ - "\u0c1c\u0c42\u0c32\u0c48"\ - "\u0c06\u0c17\u0c38\u0c4d\u0c1f\u0c41"\ - "\u0c38\u0c46\u0c2a\u0c4d\u0c1f\u0c46\u0c02\u0c2c\u0c30\u0c4d"\ - "\u0c05\u0c15\u0c4d\u0c1f\u0c4b\u0c2c\u0c30\u0c4d"\ - "\u0c28\u0c35\u0c02\u0c2c\u0c30\u0c4d"\ - "\u0c21\u0c3f\u0c38\u0c46\u0c02\u0c2c\u0c30\u0c4d"\ + "జనవరి"\ + "ఫిబ్రవరి"\ + "మార్చి"\ + "ఏప్రిల్"\ + "మే"\ + "జూన్"\ + "జూలై"\ + "ఆగస్టు"\ + "సెప్టెంబర్"\ + "అక్టోబర్"\ + "నవంబర్"\ + "డిసెంబర్"\ ""] ::msgcat::mcset te MONTHS_FULL [list \ - "\u0c1c\u0c28\u0c35\u0c30\u0c3f"\ - "\u0c2b\u0c3f\u0c2c\u0c4d\u0c30\u0c35\u0c30\u0c3f"\ - "\u0c2e\u0c3e\u0c30\u0c4d\u0c1a\u0c3f"\ - "\u0c0f\u0c2a\u0c4d\u0c30\u0c3f\u0c32\u0c4d"\ - "\u0c2e\u0c47"\ - "\u0c1c\u0c42\u0c28\u0c4d"\ - "\u0c1c\u0c42\u0c32\u0c48"\ - "\u0c06\u0c17\u0c38\u0c4d\u0c1f\u0c41"\ - "\u0c38\u0c46\u0c2a\u0c4d\u0c1f\u0c46\u0c02\u0c2c\u0c30\u0c4d"\ - "\u0c05\u0c15\u0c4d\u0c1f\u0c4b\u0c2c\u0c30\u0c4d"\ - "\u0c28\u0c35\u0c02\u0c2c\u0c30\u0c4d"\ - "\u0c21\u0c3f\u0c38\u0c46\u0c02\u0c2c\u0c30\u0c4d"\ + "జనవరి"\ + "ఫిబ్రవరి"\ + "మార్చి"\ + "ఏప్రిల్"\ + "మే"\ + "జూన్"\ + "జూలై"\ + "ఆగస్టు"\ + "సెప్టెంబర్"\ + "అక్టోబర్"\ + "నవంబర్"\ + "డిసెంబర్"\ ""] } diff --git a/library/msgs/te_in.msg b/library/msgs/te_in.msg index 61638b5..84dd2b3 100644 --- a/library/msgs/te_in.msg +++ b/library/msgs/te_in.msg @@ -1,7 +1,7 @@ # created by tools/loadICU.tcl -- do not edit namespace eval ::tcl::clock { - ::msgcat::mcset te_IN AM "\u0c2a\u0c42\u0c30\u0c4d\u0c35\u0c3e\u0c39\u0c4d\u0c28" - ::msgcat::mcset te_IN PM "\u0c05\u0c2a\u0c30\u0c3e\u0c39\u0c4d\u0c28" + ::msgcat::mcset te_IN AM "పూర్వాహ్న" + ::msgcat::mcset te_IN PM "అపరాహ్న" ::msgcat::mcset te_IN DATE_FORMAT "%d/%m/%Y" ::msgcat::mcset te_IN TIME_FORMAT_12 "%I:%M:%S %P" ::msgcat::mcset te_IN DATE_TIME_FORMAT "%d/%m/%Y %I:%M:%S %P %z" diff --git a/library/msgs/th.msg b/library/msgs/th.msg index 7486c35..edaa149 100644 --- a/library/msgs/th.msg +++ b/library/msgs/th.msg @@ -1,53 +1,53 @@ # created by tools/loadICU.tcl -- do not edit namespace eval ::tcl::clock { ::msgcat::mcset th DAYS_OF_WEEK_ABBREV [list \ - "\u0e2d\u0e32."\ - "\u0e08."\ - "\u0e2d."\ - "\u0e1e."\ - "\u0e1e\u0e24."\ - "\u0e28."\ - "\u0e2a."] + "อา."\ + "จ."\ + "อ."\ + "พ."\ + "พฤ."\ + "ศ."\ + "ส."] ::msgcat::mcset th DAYS_OF_WEEK_FULL [list \ - "\u0e27\u0e31\u0e19\u0e2d\u0e32\u0e17\u0e34\u0e15\u0e22\u0e4c"\ - "\u0e27\u0e31\u0e19\u0e08\u0e31\u0e19\u0e17\u0e23\u0e4c"\ - "\u0e27\u0e31\u0e19\u0e2d\u0e31\u0e07\u0e04\u0e32\u0e23"\ - "\u0e27\u0e31\u0e19\u0e1e\u0e38\u0e18"\ - "\u0e27\u0e31\u0e19\u0e1e\u0e24\u0e2b\u0e31\u0e2a\u0e1a\u0e14\u0e35"\ - "\u0e27\u0e31\u0e19\u0e28\u0e38\u0e01\u0e23\u0e4c"\ - "\u0e27\u0e31\u0e19\u0e40\u0e2a\u0e32\u0e23\u0e4c"] + "วันอาทิตย์"\ + "วันจันทร์"\ + "วันอังคาร"\ + "วันพุธ"\ + "วันพฤหัสบดี"\ + "วันศุกร์"\ + "วันเสาร์"] ::msgcat::mcset th MONTHS_ABBREV [list \ - "\u0e21.\u0e04."\ - "\u0e01.\u0e1e."\ - "\u0e21\u0e35.\u0e04."\ - "\u0e40\u0e21.\u0e22."\ - "\u0e1e.\u0e04."\ - "\u0e21\u0e34.\u0e22."\ - "\u0e01.\u0e04."\ - "\u0e2a.\u0e04."\ - "\u0e01.\u0e22."\ - "\u0e15.\u0e04."\ - "\u0e1e.\u0e22."\ - "\u0e18.\u0e04."\ + "ม.ค."\ + "ก.พ."\ + "มี.ค."\ + "เม.ย."\ + "พ.ค."\ + "มิ.ย."\ + "ก.ค."\ + "ส.ค."\ + "ก.ย."\ + "ต.ค."\ + "พ.ย."\ + "ธ.ค."\ ""] ::msgcat::mcset th MONTHS_FULL [list \ - "\u0e21\u0e01\u0e23\u0e32\u0e04\u0e21"\ - "\u0e01\u0e38\u0e21\u0e20\u0e32\u0e1e\u0e31\u0e19\u0e18\u0e4c"\ - "\u0e21\u0e35\u0e19\u0e32\u0e04\u0e21"\ - "\u0e40\u0e21\u0e29\u0e32\u0e22\u0e19"\ - "\u0e1e\u0e24\u0e29\u0e20\u0e32\u0e04\u0e21"\ - "\u0e21\u0e34\u0e16\u0e38\u0e19\u0e32\u0e22\u0e19"\ - "\u0e01\u0e23\u0e01\u0e0e\u0e32\u0e04\u0e21"\ - "\u0e2a\u0e34\u0e07\u0e2b\u0e32\u0e04\u0e21"\ - "\u0e01\u0e31\u0e19\u0e22\u0e32\u0e22\u0e19"\ - "\u0e15\u0e38\u0e25\u0e32\u0e04\u0e21"\ - "\u0e1e\u0e24\u0e28\u0e08\u0e34\u0e01\u0e32\u0e22\u0e19"\ - "\u0e18\u0e31\u0e19\u0e27\u0e32\u0e04\u0e21"\ + "มกราคม"\ + "กุมภาพันธ์"\ + "มีนาคม"\ + "เมษายน"\ + "พฤษภาคม"\ + "มิถุนายน"\ + "กรกฎาคม"\ + "สิงหาคม"\ + "กันยายน"\ + "ตุลาคม"\ + "พฤศจิกายน"\ + "ธันวาคม"\ ""] - ::msgcat::mcset th BCE "\u0e25\u0e17\u0e35\u0e48" - ::msgcat::mcset th CE "\u0e04.\u0e28." - ::msgcat::mcset th AM "\u0e01\u0e48\u0e2d\u0e19\u0e40\u0e17\u0e35\u0e48\u0e22\u0e07" - ::msgcat::mcset th PM "\u0e2b\u0e25\u0e31\u0e07\u0e40\u0e17\u0e35\u0e48\u0e22\u0e07" + ::msgcat::mcset th BCE "ลที่" + ::msgcat::mcset th CE "ค.ศ." + ::msgcat::mcset th AM "ก่อนเที่ยง" + ::msgcat::mcset th PM "หลังเที่ยง" ::msgcat::mcset th DATE_FORMAT "%e/%m/%Y" ::msgcat::mcset th TIME_FORMAT "%k:%M:%S" ::msgcat::mcset th DATE_TIME_FORMAT "%e/%m/%Y %k:%M:%S %z" diff --git a/library/msgs/tr.msg b/library/msgs/tr.msg index 7b2ecf9..12869ee 100644 --- a/library/msgs/tr.msg +++ b/library/msgs/tr.msg @@ -4,27 +4,27 @@ namespace eval ::tcl::clock { "Paz"\ "Pzt"\ "Sal"\ - "\u00c7ar"\ + "Çar"\ "Per"\ "Cum"\ "Cmt"] ::msgcat::mcset tr DAYS_OF_WEEK_FULL [list \ "Pazar"\ "Pazartesi"\ - "Sal\u0131"\ - "\u00c7ar\u015famba"\ - "Per\u015fembe"\ + "Salı"\ + "Çarşamba"\ + "Perşembe"\ "Cuma"\ "Cumartesi"] ::msgcat::mcset tr MONTHS_ABBREV [list \ "Oca"\ - "\u015eub"\ + "Şub"\ "Mar"\ "Nis"\ "May"\ "Haz"\ "Tem"\ - "A\u011fu"\ + "Ağu"\ "Eyl"\ "Eki"\ "Kas"\ @@ -32,17 +32,17 @@ namespace eval ::tcl::clock { ""] ::msgcat::mcset tr MONTHS_FULL [list \ "Ocak"\ - "\u015eubat"\ + "Şubat"\ "Mart"\ "Nisan"\ - "May\u0131s"\ + "Mayıs"\ "Haziran"\ "Temmuz"\ - "A\u011fustos"\ - "Eyl\u00fcl"\ + "Ağustos"\ + "Eylül"\ "Ekim"\ - "Kas\u0131m"\ - "Aral\u0131k"\ + "Kasım"\ + "Aralık"\ ""] ::msgcat::mcset tr DATE_FORMAT "%d.%m.%Y" ::msgcat::mcset tr TIME_FORMAT "%H:%M:%S" diff --git a/library/msgs/uk.msg b/library/msgs/uk.msg index 7d4c64a..42eb095 100644 --- a/library/msgs/uk.msg +++ b/library/msgs/uk.msg @@ -1,51 +1,51 @@ # created by tools/loadICU.tcl -- do not edit namespace eval ::tcl::clock { ::msgcat::mcset uk DAYS_OF_WEEK_ABBREV [list \ - "\u043d\u0434"\ - "\u043f\u043d"\ - "\u0432\u0442"\ - "\u0441\u0440"\ - "\u0447\u0442"\ - "\u043f\u0442"\ - "\u0441\u0431"] + "нд"\ + "пн"\ + "вт"\ + "ср"\ + "чт"\ + "пт"\ + "сб"] ::msgcat::mcset uk DAYS_OF_WEEK_FULL [list \ - "\u043d\u0435\u0434\u0456\u043b\u044f"\ - "\u043f\u043e\u043d\u0435\u0434\u0456\u043b\u043e\u043a"\ - "\u0432\u0456\u0432\u0442\u043e\u0440\u043e\u043a"\ - "\u0441\u0435\u0440\u0435\u0434\u0430"\ - "\u0447\u0435\u0442\u0432\u0435\u0440"\ - "\u043f'\u044f\u0442\u043d\u0438\u0446\u044f"\ - "\u0441\u0443\u0431\u043e\u0442\u0430"] + "неділя"\ + "понеділок"\ + "вівторок"\ + "середа"\ + "четвер"\ + "п'ятниця"\ + "субота"] ::msgcat::mcset uk MONTHS_ABBREV [list \ - "\u0441\u0456\u0447"\ - "\u043b\u044e\u0442"\ - "\u0431\u0435\u0440"\ - "\u043a\u0432\u0456\u0442"\ - "\u0442\u0440\u0430\u0432"\ - "\u0447\u0435\u0440\u0432"\ - "\u043b\u0438\u043f"\ - "\u0441\u0435\u0440\u043f"\ - "\u0432\u0435\u0440"\ - "\u0436\u043e\u0432\u0442"\ - "\u043b\u0438\u0441\u0442"\ - "\u0433\u0440\u0443\u0434"\ + "січ"\ + "лют"\ + "бер"\ + "квіт"\ + "трав"\ + "черв"\ + "лип"\ + "серп"\ + "вер"\ + "жовт"\ + "лист"\ + "груд"\ ""] ::msgcat::mcset uk MONTHS_FULL [list \ - "\u0441\u0456\u0447\u043d\u044f"\ - "\u043b\u044e\u0442\u043e\u0433\u043e"\ - "\u0431\u0435\u0440\u0435\u0437\u043d\u044f"\ - "\u043a\u0432\u0456\u0442\u043d\u044f"\ - "\u0442\u0440\u0430\u0432\u043d\u044f"\ - "\u0447\u0435\u0440\u0432\u043d\u044f"\ - "\u043b\u0438\u043f\u043d\u044f"\ - "\u0441\u0435\u0440\u043f\u043d\u044f"\ - "\u0432\u0435\u0440\u0435\u0441\u043d\u044f"\ - "\u0436\u043e\u0432\u0442\u043d\u044f"\ - "\u043b\u0438\u0441\u0442\u043e\u043f\u0430\u0434\u0430"\ - "\u0433\u0440\u0443\u0434\u043d\u044f"\ + "січня"\ + "лютого"\ + "березня"\ + "квітня"\ + "травня"\ + "червня"\ + "липня"\ + "серпня"\ + "вересня"\ + "жовтня"\ + "листопада"\ + "грудня"\ ""] - ::msgcat::mcset uk BCE "\u0434\u043e \u043d.\u0435." - ::msgcat::mcset uk CE "\u043f\u0456\u0441\u043b\u044f \u043d.\u0435." + ::msgcat::mcset uk BCE "до н.е." + ::msgcat::mcset uk CE "після н.е." ::msgcat::mcset uk DATE_FORMAT "%e/%m/%Y" ::msgcat::mcset uk TIME_FORMAT "%k:%M:%S" ::msgcat::mcset uk DATE_TIME_FORMAT "%e/%m/%Y %k:%M:%S %z" diff --git a/library/msgs/vi.msg b/library/msgs/vi.msg index c98b2a6..3437ebf 100644 --- a/library/msgs/vi.msg +++ b/library/msgs/vi.msg @@ -9,13 +9,13 @@ namespace eval ::tcl::clock { "Th 7"\ "CN"] ::msgcat::mcset vi DAYS_OF_WEEK_FULL [list \ - "Th\u01b0\u0301 hai"\ - "Th\u01b0\u0301 ba"\ - "Th\u01b0\u0301 t\u01b0"\ - "Th\u01b0\u0301 n\u0103m"\ - "Th\u01b0\u0301 s\u00e1u"\ - "Th\u01b0\u0301 ba\u0309y"\ - "Chu\u0309 nh\u00e2\u0323t"] + "Thứ hai"\ + "Thứ ba"\ + "Thứ tư"\ + "Thứ năm"\ + "Thứ sáu"\ + "Thứ bảy"\ + "Chủ nhật"] ::msgcat::mcset vi MONTHS_ABBREV [list \ "Thg 1"\ "Thg 2"\ @@ -31,18 +31,18 @@ namespace eval ::tcl::clock { "Thg 12"\ ""] ::msgcat::mcset vi MONTHS_FULL [list \ - "Th\u00e1ng m\u00f4\u0323t"\ - "Th\u00e1ng hai"\ - "Th\u00e1ng ba"\ - "Th\u00e1ng t\u01b0"\ - "Th\u00e1ng n\u0103m"\ - "Th\u00e1ng s\u00e1u"\ - "Th\u00e1ng ba\u0309y"\ - "Th\u00e1ng t\u00e1m"\ - "Th\u00e1ng ch\u00edn"\ - "Th\u00e1ng m\u01b0\u01a1\u0300i"\ - "Th\u00e1ng m\u01b0\u01a1\u0300i m\u00f4\u0323t"\ - "Th\u00e1ng m\u01b0\u01a1\u0300i hai"\ + "Tháng một"\ + "Tháng hai"\ + "Tháng ba"\ + "Tháng tư"\ + "Tháng năm"\ + "Tháng sáu"\ + "Tháng bảy"\ + "Tháng tám"\ + "Tháng chín"\ + "Tháng mười"\ + "Tháng mười một"\ + "Tháng mười hai"\ ""] ::msgcat::mcset vi DATE_FORMAT "%d %b %Y" ::msgcat::mcset vi TIME_FORMAT "%H:%M:%S" diff --git a/library/msgs/zh.msg b/library/msgs/zh.msg index b799a32..9c1d08b 100644 --- a/library/msgs/zh.msg +++ b/library/msgs/zh.msg @@ -1,55 +1,55 @@ # created by tools/loadICU.tcl -- do not edit namespace eval ::tcl::clock { ::msgcat::mcset zh DAYS_OF_WEEK_ABBREV [list \ - "\u661f\u671f\u65e5"\ - "\u661f\u671f\u4e00"\ - "\u661f\u671f\u4e8c"\ - "\u661f\u671f\u4e09"\ - "\u661f\u671f\u56db"\ - "\u661f\u671f\u4e94"\ - "\u661f\u671f\u516d"] + "星期日"\ + "星期一"\ + "星期二"\ + "星期三"\ + "星期四"\ + "星期五"\ + "星期六"] ::msgcat::mcset zh DAYS_OF_WEEK_FULL [list \ - "\u661f\u671f\u65e5"\ - "\u661f\u671f\u4e00"\ - "\u661f\u671f\u4e8c"\ - "\u661f\u671f\u4e09"\ - "\u661f\u671f\u56db"\ - "\u661f\u671f\u4e94"\ - "\u661f\u671f\u516d"] + "星期日"\ + "星期一"\ + "星期二"\ + "星期三"\ + "星期四"\ + "星期五"\ + "星期六"] ::msgcat::mcset zh MONTHS_ABBREV [list \ - "\u4e00\u6708"\ - "\u4e8c\u6708"\ - "\u4e09\u6708"\ - "\u56db\u6708"\ - "\u4e94\u6708"\ - "\u516d\u6708"\ - "\u4e03\u6708"\ - "\u516b\u6708"\ - "\u4e5d\u6708"\ - "\u5341\u6708"\ - "\u5341\u4e00\u6708"\ - "\u5341\u4e8c\u6708"\ + "一月"\ + "二月"\ + "三月"\ + "四月"\ + "五月"\ + "六月"\ + "七月"\ + "八月"\ + "九月"\ + "十月"\ + "十一月"\ + "十二月"\ ""] ::msgcat::mcset zh MONTHS_FULL [list \ - "\u4e00\u6708"\ - "\u4e8c\u6708"\ - "\u4e09\u6708"\ - "\u56db\u6708"\ - "\u4e94\u6708"\ - "\u516d\u6708"\ - "\u4e03\u6708"\ - "\u516b\u6708"\ - "\u4e5d\u6708"\ - "\u5341\u6708"\ - "\u5341\u4e00\u6708"\ - "\u5341\u4e8c\u6708"\ + "一月"\ + "二月"\ + "三月"\ + "四月"\ + "五月"\ + "六月"\ + "七月"\ + "八月"\ + "九月"\ + "十月"\ + "十一月"\ + "十二月"\ ""] - ::msgcat::mcset zh BCE "\u516c\u5143\u524d" - ::msgcat::mcset zh CE "\u516c\u5143" - ::msgcat::mcset zh AM "\u4e0a\u5348" - ::msgcat::mcset zh PM "\u4e0b\u5348" - ::msgcat::mcset zh LOCALE_NUMERALS "\u3007 \u4e00 \u4e8c \u4e09 \u56db \u4e94 \u516d \u4e03 \u516b \u4e5d \u5341 \u5341\u4e00 \u5341\u4e8c \u5341\u4e09 \u5341\u56db \u5341\u4e94 \u5341\u516d \u5341\u4e03 \u5341\u516b \u5341\u4e5d \u4e8c\u5341 \u5eff\u4e00 \u5eff\u4e8c \u5eff\u4e09 \u5eff\u56db \u5eff\u4e94 \u5eff\u516d \u5eff\u4e03 \u5eff\u516b \u5eff\u4e5d \u4e09\u5341 \u5345\u4e00 \u5345\u4e8c \u5345\u4e09 \u5345\u56db \u5345\u4e94 \u5345\u516d \u5345\u4e03 \u5345\u516b \u5345\u4e5d \u56db\u5341 \u56db\u5341\u4e00 \u56db\u5341\u4e8c \u56db\u5341\u4e09 \u56db\u5341\u56db \u56db\u5341\u4e94 \u56db\u5341\u516d \u56db\u5341\u4e03 \u56db\u5341\u516b \u56db\u5341\u4e5d \u4e94\u5341 \u4e94\u5341\u4e00 \u4e94\u5341\u4e8c \u4e94\u5341\u4e09 \u4e94\u5341\u56db \u4e94\u5341\u4e94 \u4e94\u5341\u516d \u4e94\u5341\u4e03 \u4e94\u5341\u516b \u4e94\u5341\u4e5d \u516d\u5341 \u516d\u5341\u4e00 \u516d\u5341\u4e8c \u516d\u5341\u4e09 \u516d\u5341\u56db \u516d\u5341\u4e94 \u516d\u5341\u516d \u516d\u5341\u4e03 \u516d\u5341\u516b \u516d\u5341\u4e5d \u4e03\u5341 \u4e03\u5341\u4e00 \u4e03\u5341\u4e8c \u4e03\u5341\u4e09 \u4e03\u5341\u56db \u4e03\u5341\u4e94 \u4e03\u5341\u516d \u4e03\u5341\u4e03 \u4e03\u5341\u516b \u4e03\u5341\u4e5d \u516b\u5341 \u516b\u5341\u4e00 \u516b\u5341\u4e8c \u516b\u5341\u4e09 \u516b\u5341\u56db \u516b\u5341\u4e94 \u516b\u5341\u516d \u516b\u5341\u4e03 \u516b\u5341\u516b \u516b\u5341\u4e5d \u4e5d\u5341 \u4e5d\u5341\u4e00 \u4e5d\u5341\u4e8c \u4e5d\u5341\u4e09 \u4e5d\u5341\u56db \u4e5d\u5341\u4e94 \u4e5d\u5341\u516d \u4e5d\u5341\u4e03 \u4e5d\u5341\u516b \u4e5d\u5341\u4e5d" - ::msgcat::mcset zh LOCALE_DATE_FORMAT "\u516c\u5143%Y\u5e74%B%Od\u65e5" - ::msgcat::mcset zh LOCALE_TIME_FORMAT "%OH\u65f6%OM\u5206%OS\u79d2" - ::msgcat::mcset zh LOCALE_DATE_TIME_FORMAT "%A %Y\u5e74%B%Od\u65e5%OH\u65f6%OM\u5206%OS\u79d2 %z" + ::msgcat::mcset zh BCE "公元前" + ::msgcat::mcset zh CE "公元" + ::msgcat::mcset zh AM "上午" + ::msgcat::mcset zh PM "下午" + ::msgcat::mcset zh LOCALE_NUMERALS "〇 一 二 三 四 五 六 七 八 九 十 十一 十二 十三 十四 十五 十六 十七 十八 十九 二十 廿一 廿二 廿三 廿四 廿五 廿六 廿七 廿八 廿九 三十 卅一 卅二 卅三 卅四 卅五 卅六 卅七 卅八 卅九 四十 四十一 四十二 四十三 四十四 四十五 四十六 四十七 四十八 四十九 五十 五十一 五十二 五十三 五十四 五十五 五十六 五十七 五十八 五十九 六十 六十一 六十二 六十三 六十四 六十五 六十六 六十七 六十八 六十九 七十 七十一 七十二 七十三 七十四 七十五 七十六 七十七 七十八 七十九 八十 八十一 八十二 八十三 八十四 八十五 八十六 八十七 八十八 八十九 九十 九十一 九十二 九十三 九十四 九十五 九十六 九十七 九十八 九十九" + ::msgcat::mcset zh LOCALE_DATE_FORMAT "公元%Y年%B%Od日" + ::msgcat::mcset zh LOCALE_TIME_FORMAT "%OH时%OM分%OS秒" + ::msgcat::mcset zh LOCALE_DATE_TIME_FORMAT "%A %Y年%B%Od日%OH时%OM分%OS秒 %z" } diff --git a/library/msgs/zh_cn.msg b/library/msgs/zh_cn.msg index d62ce77..da2869a 100644 --- a/library/msgs/zh_cn.msg +++ b/library/msgs/zh_cn.msg @@ -2,6 +2,6 @@ namespace eval ::tcl::clock { ::msgcat::mcset zh_CN DATE_FORMAT "%Y-%m-%e" ::msgcat::mcset zh_CN TIME_FORMAT "%k:%M:%S" - ::msgcat::mcset zh_CN TIME_FORMAT_12 "%P%I\u65f6%M\u5206%S\u79d2" + ::msgcat::mcset zh_CN TIME_FORMAT_12 "%P%I时%M分%S秒" ::msgcat::mcset zh_CN DATE_TIME_FORMAT "%Y-%m-%e %k:%M:%S %z" } diff --git a/library/msgs/zh_hk.msg b/library/msgs/zh_hk.msg index badb1dd..7f1b181 100644 --- a/library/msgs/zh_hk.msg +++ b/library/msgs/zh_hk.msg @@ -1,28 +1,28 @@ # created by tools/loadICU.tcl -- do not edit namespace eval ::tcl::clock { ::msgcat::mcset zh_HK DAYS_OF_WEEK_ABBREV [list \ - "\u65e5"\ - "\u4e00"\ - "\u4e8c"\ - "\u4e09"\ - "\u56db"\ - "\u4e94"\ - "\u516d"] + "日"\ + "一"\ + "二"\ + "三"\ + "四"\ + "五"\ + "六"] ::msgcat::mcset zh_HK MONTHS_ABBREV [list \ - "1\u6708"\ - "2\u6708"\ - "3\u6708"\ - "4\u6708"\ - "5\u6708"\ - "6\u6708"\ - "7\u6708"\ - "8\u6708"\ - "9\u6708"\ - "10\u6708"\ - "11\u6708"\ - "12\u6708"\ + "1月"\ + "2月"\ + "3月"\ + "4月"\ + "5月"\ + "6月"\ + "7月"\ + "8月"\ + "9月"\ + "10月"\ + "11月"\ + "12月"\ ""] - ::msgcat::mcset zh_HK DATE_FORMAT "%Y\u5e74%m\u6708%e\u65e5" + ::msgcat::mcset zh_HK DATE_FORMAT "%Y年%m月%e日" ::msgcat::mcset zh_HK TIME_FORMAT_12 "%P%I:%M:%S" - ::msgcat::mcset zh_HK DATE_TIME_FORMAT "%Y\u5e74%m\u6708%e\u65e5 %P%I:%M:%S %z" + ::msgcat::mcset zh_HK DATE_TIME_FORMAT "%Y年%m月%e日 %P%I:%M:%S %z" } diff --git a/library/msgs/zh_sg.msg b/library/msgs/zh_sg.msg index a2f3e39..690edf7 100644 --- a/library/msgs/zh_sg.msg +++ b/library/msgs/zh_sg.msg @@ -1,7 +1,7 @@ # created by tools/loadICU.tcl -- do not edit namespace eval ::tcl::clock { - ::msgcat::mcset zh_SG AM "\u4e0a\u5348" - ::msgcat::mcset zh_SG PM "\u4e2d\u5348" + ::msgcat::mcset zh_SG AM "上午" + ::msgcat::mcset zh_SG PM "中午" ::msgcat::mcset zh_SG DATE_FORMAT "%d %B %Y" ::msgcat::mcset zh_SG TIME_FORMAT_12 "%P %I:%M:%S" ::msgcat::mcset zh_SG DATE_TIME_FORMAT "%d %B %Y %P %I:%M:%S %z" diff --git a/library/msgs/zh_tw.msg b/library/msgs/zh_tw.msg index e0796b1..17a6dd7 100644 --- a/library/msgs/zh_tw.msg +++ b/library/msgs/zh_tw.msg @@ -1,7 +1,7 @@ # created by tools/loadICU.tcl -- do not edit namespace eval ::tcl::clock { - ::msgcat::mcset zh_TW BCE "\u6c11\u570b\u524d" - ::msgcat::mcset zh_TW CE "\u6c11\u570b" + ::msgcat::mcset zh_TW BCE "民國前" + ::msgcat::mcset zh_TW CE "民國" ::msgcat::mcset zh_TW DATE_FORMAT "%Y/%m/%e" ::msgcat::mcset zh_TW TIME_FORMAT_12 "%P %I:%M:%S" ::msgcat::mcset zh_TW DATE_TIME_FORMAT "%Y/%m/%e %P %I:%M:%S %z" diff --git a/tools/loadICU.tcl b/tools/loadICU.tcl index 31f1e54..43d7e6a 100755 --- a/tools/loadICU.tcl +++ b/tools/loadICU.tcl @@ -27,6 +27,9 @@ # of this file, and for a DISCLAIMER OF ALL WARRANTIES. #---------------------------------------------------------------------- +puts stdout "TODO: output in UTF-8 in stead of using \\uhhhh sequences" +exit; # Remove those two lines after modifying this tool. + # Calculate the Chinese numerals from zero to ninety-nine. set zhDigits [list {} \u4e00 \u4e8c \u4e09 \u56db \ -- cgit v0.12 From d2595ccfea5ca3671786fe69396b9ad3130be57a Mon Sep 17 00:00:00 2001 From: dgp Date: Thu, 13 Apr 2017 16:39:15 +0000 Subject: Bump TclOO 1.0.6; finish changes. --- changes | 29 +++++++++++++++++++++++++++-- generic/tclOO.h | 2 +- unix/tclooConfig.sh | 2 +- win/tclooConfig.sh | 2 +- 4 files changed, 30 insertions(+), 5 deletions(-) diff --git a/changes b/changes index bf25784..74ab4ee 100644 --- a/changes +++ b/changes @@ -8721,19 +8721,44 @@ improvements to regexp engine from Postgres (lane,porter,fellows,seltenreich) 2016-10-30 (bug)[1ae129] Fix memleak in [history] destruction (fellows) -2016-11-04 (feature) Provision Tcl 9 support in msgcat and tcltest (nijtmans) +2016-11-04 (feature) Provisional Tcl 9 support in msgcat and tcltest (nijtmans) => msgcat 1.6.1 => tcltest 2.4.1 +2016-11-04 (bug)[824752] Crash in Tcl_ListObjReplace() (gahr,porter) +2016-11-11 (bug)[79614f] invalidate VFS mounts on sytem encoding change (yorick) +2016-11-14 OSX: End panic() as legacy support macro; system conflicts (nijtmans) + *** POTENTIAL INCOMPATIBILITY *** + +2016-11-15 (bug) TclOO fix stops crash mixing Itcl and snit (fellows) +2016-11-17 (update) Reconcile libtommath updates; purge unused files (nijtmans) + *** POTENTIAL INCOMPATIBILITY *** +2017-01-09 (bug)[b87ad7] Repair drifts in timer clock (sebres) +2017-01-17 (update) => zlib 1.2.11 (nijtmans) + +2017-01-31 (bug)[39f630] Revise Tcl_LinkVar to tolerate some prefixes (nijtmans) + *** POTENTIAL INCOMPATIBILITY *** + +2017-02-01 (bug)[d0f7ba] Improper NAN optimization. expr-22.1[01] (aspect) + +2017-02-26 (bug)[25842c] zlib stream finalization (aspect) + +2017-03-07 (deprecate) Remove unmaintained makefile.bc file (nijtmans) + *** POTENTIAL INCOMPATIBILITY *** +2017-03-14 (enhancement) [clock] and [encoding] are now ensembles (kenny) +2017-03-15 (enhancement) several [clock] subcommands bytecoded (kenny) +2017-03-23 tzdata updated to Olson's tzdata2017b (jima) +2017-03-29 (bug)[900cb0] Fix OO unexport introspection (napier) +2017-04-12 (bug)[42202b] Nesting imbalance in coro injection (nadkarni,sebres) ---- Released 8.6.7, March 31, 2016 --- http://core.tcl.tk/tcl/ for details +--- Released 8.6.7, April 30, 2016 --- http://core.tcl.tk/tcl/ for details diff --git a/generic/tclOO.h b/generic/tclOO.h index 46f01fb..823d773 100644 --- a/generic/tclOO.h +++ b/generic/tclOO.h @@ -24,7 +24,7 @@ * win/tclooConfig.sh */ -#define TCLOO_VERSION "1.0.5" +#define TCLOO_VERSION "1.0.6" #define TCLOO_PATCHLEVEL TCLOO_VERSION #include "tcl.h" diff --git a/unix/tclooConfig.sh b/unix/tclooConfig.sh index ee10b81..e5d42bb 100644 --- a/unix/tclooConfig.sh +++ b/unix/tclooConfig.sh @@ -16,4 +16,4 @@ TCLOO_STUB_LIB_SPEC="" TCLOO_INCLUDE_SPEC="" TCLOO_PRIVATE_INCLUDE_SPEC="" TCLOO_CFLAGS="" -TCLOO_VERSION=1.0.4 +TCLOO_VERSION=1.0.6 diff --git a/win/tclooConfig.sh b/win/tclooConfig.sh index ee10b81..e5d42bb 100644 --- a/win/tclooConfig.sh +++ b/win/tclooConfig.sh @@ -16,4 +16,4 @@ TCLOO_STUB_LIB_SPEC="" TCLOO_INCLUDE_SPEC="" TCLOO_PRIVATE_INCLUDE_SPEC="" TCLOO_CFLAGS="" -TCLOO_VERSION=1.0.4 +TCLOO_VERSION=1.0.6 -- cgit v0.12 From 490e5ace3ad5f5790685e654bb03b2fe5e5d2048 Mon Sep 17 00:00:00 2001 From: "jan.nijtmans" Date: Fri, 14 Apr 2017 09:05:01 +0000 Subject: Don't use "0%o" format in test-cases, as it suggest's it's the normal way to format octal numbers: it isn't. Better use "%#o". Add tests for "format" and "scan" corner-cases which weren't documented (except in TIP's) neither had tests before. --- generic/tclBasic.c | 2 +- tests/chanio.test | 8 ++++---- tests/format.test | 42 ++++++++++++++++++++++++------------------ tests/io.test | 4 ++-- tests/scan.test | 18 ++++++++++++++++++ 5 files changed, 49 insertions(+), 25 deletions(-) diff --git a/generic/tclBasic.c b/generic/tclBasic.c index f604ac1..0486383 100644 --- a/generic/tclBasic.c +++ b/generic/tclBasic.c @@ -8765,7 +8765,7 @@ TclNREvalList( int objc; Tcl_Obj **objv; Tcl_Obj *listPtr = data[0]; - + Tcl_IncrRefCount(listPtr); TclMarkTailcall(interp); diff --git a/tests/chanio.test b/tests/chanio.test index 31bef36..cee2675 100644 --- a/tests/chanio.test +++ b/tests/chanio.test @@ -5338,22 +5338,22 @@ test chan-io-40.2 {POSIX open access modes: CREAT} -setup { } -constraints {unix} -body { set f [open $path(test3) {WRONLY CREAT} 0600] file stat $path(test3) stats - set x [format "0%o" [expr $stats(mode)&0o777]] + set x [format "%#o" [expr $stats(mode)&0o777]] chan puts $f "line 1" chan close $f set f [open $path(test3) r] lappend x [chan gets $f] } -cleanup { chan close $f -} -result {0600 {line 1}} +} -result {0o600 {line 1}} test chan-io-40.3 {POSIX open access modes: CREAT} -setup { file delete $path(test3) } -constraints {unix umask} -body { # This test only works if your umask is 2, like ouster's. chan close [open $path(test3) {WRONLY CREAT}] file stat $path(test3) stats - format "0%o" [expr $stats(mode)&0o777] -} -result [format %04o [expr {0o666 & ~ $umaskValue}]] + format "%#o" [expr $stats(mode)&0o777] +} -result [format %#5o [expr {0o666 & ~ $umaskValue}]] test chan-io-40.4 {POSIX open access modes: CREAT} -setup { file delete $path(test3) } -body { diff --git a/tests/format.test b/tests/format.test index e199398..9afedd9 100644 --- a/tests/format.test +++ b/tests/format.test @@ -52,32 +52,32 @@ test format-1.7.1 {integer formatting} longIs64bit { format "%4x %4x %4x %4x" 6 34 16923 -12 -1 } { 6 22 421b fffffffffffffff4} test format-1.8 {integer formatting} longIs32bit { - format "%#x %#X %#X %#x" 6 34 16923 -12 -1 -} {0x6 0X22 0X421B 0xfffffff4} + format "%#x %#x %#X %#X %#x" 0 6 34 16923 -12 -1 +} {0x0 0x6 0X22 0X421B 0xfffffff4} test format-1.8.1 {integer formatting} longIs64bit { - format "%#x %#X %#X %#x" 6 34 16923 -12 -1 -} {0x6 0X22 0X421B 0xfffffffffffffff4} + format "%#x %#x %#X %#X %#x" 0 6 34 16923 -12 -1 +} {0x0 0x6 0X22 0X421B 0xfffffffffffffff4} test format-1.9 {integer formatting} longIs32bit { - format "%#20x %#20x %#20x %#20x" 6 34 16923 -12 -1 -} { 0x6 0x22 0x421b 0xfffffff4} + format "%#5x %#20x %#20x %#20x %#20x" 0 6 34 16923 -12 -1 +} { 0x0 0x6 0x22 0x421b 0xfffffff4} test format-1.9.1 {integer formatting} longIs64bit { - format "%#20x %#20x %#20x %#20x" 6 34 16923 -12 -1 -} { 0x6 0x22 0x421b 0xfffffffffffffff4} + format "%#5x %#20x %#20x %#20x %#20x" 0 6 34 16923 -12 -1 +} { 0x0 0x6 0x22 0x421b 0xfffffffffffffff4} test format-1.10 {integer formatting} longIs32bit { - format "%-#20x %-#20x %-#20x %-#20x" 6 34 16923 -12 -1 -} {0x6 0x22 0x421b 0xfffffff4 } + format "%-#5x %-#20x %-#20x %-#20x %-#20x" 0 6 34 16923 -12 -1 +} {0x0 0x6 0x22 0x421b 0xfffffff4 } test format-1.10.1 {integer formatting} longIs64bit { - format "%-#20x %-#20x %-#20x %-#20x" 6 34 16923 -12 -1 -} {0x6 0x22 0x421b 0xfffffffffffffff4 } + format "%-#5x %-#20x %-#20x %-#20x %-#20x" 0 6 34 16923 -12 -1 +} {0x0 0x6 0x22 0x421b 0xfffffffffffffff4 } test format-1.11 {integer formatting} longIs32bit { - format "%-#20o %#-20o %#-20o %#-20o" 6 34 16923 -12 -1 -} {06 042 041033 037777777764 } + format "%-#5o %-#20o %#-20o %#-20o %#-20o" 0 6 34 16923 -12 -1 +} {0 06 042 041033 037777777764 } test format-1.11.1 {integer formatting} longIs64bit { - format "%-#20o %#-20o %#-20o %#-20o" 6 34 16923 -12 -1 -} {06 042 041033 01777777777777777777764} + format "%-#5o %-#20o %#-20o %#-20o %#-20o" 0 6 34 16923 -12 -1 +} {0 06 042 041033 01777777777777777777764} test format-1.12 {integer formatting} { - format "%b %#b %llb" 5 5 [expr {2**100}] -} {101 0b101 10000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000} + format "%b %#b %#b %llb" 5 0 5 [expr {2**100}] +} {101 0b0 0b101 10000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000} test format-2.1 {string formatting} { format "%s %s %c %s" abcd {This is a very long test string.} 120 x @@ -528,6 +528,12 @@ test format-17.3 {testing %ld with non-wide} {wideIs64bit} { test format-17.4 {testing %l with non-integer} { format %lf 1 } 1.000000 +test format-17.5 {testing %llu with positive bignum} -body { + format %llu 0xabcdef0123456789abcdef +} -returnCodes 1 -result {unsigned bignum format is invalid} +test format-17.6 {testing %llu with negative number} -body { + format %llu -1 +} -returnCodes 1 -result {unsigned bignum format is invalid} test format-18.1 {do not demote existing numeric values} { set a 0xaaaaaaaa diff --git a/tests/io.test b/tests/io.test index e2a05dc..7d8c80f 100644 --- a/tests/io.test +++ b/tests/io.test @@ -5652,8 +5652,8 @@ test io-40.3 {POSIX open access modes: CREAT} {unix umask} { set f [open $path(test3) {WRONLY CREAT}] close $f file stat $path(test3) stats - format "0%o" [expr $stats(mode)&0o777] -} [format %04o [expr {0o666 & ~ $umaskValue}]] + format "%#o" [expr $stats(mode)&0o777] +} [format %#5o [expr {0o666 & ~ $umaskValue}]] test io-40.4 {POSIX open access modes: CREAT} { file delete $path(test3) set f [open $path(test3) w] diff --git a/tests/scan.test b/tests/scan.test index 7540c9c..b36b412 100644 --- a/tests/scan.test +++ b/tests/scan.test @@ -541,6 +541,24 @@ test scan-5.15 {Bug be003d570f} { test scan-5.16 {Bug be003d570f} { scan 0x40 %b } 0 +test scan-5.17 {bigint scanning} -setup { + set a {}; set b {}; set c {} +} -body { + list [scan "207698809136909011942886895,abcdef0123456789abcdef,125715736004432126361152746757" \ + %lld,%llx,%llo a b c] $a $b $c +} -result {3 207698809136909011942886895 207698809136909011942886895 207698809136909011942886895} +test scan-5.18 {bigint scanning underflow} -setup { + set a {}; +} -body { + list [scan "-207698809136909011942886895" \ + %llu a] $a +} -returnCodes 1 -result {unsigned bignum scans are invalid} +test scan-5.18 {bigint scanning invalid} -setup { + set a {}; +} -body { + list [scan "207698809136909011942886895" \ + %llu a] $a +} -returnCodes 1 -result {unsigned bignum scans are invalid} test scan-6.1 {floating-point scanning} -setup { set a {}; set b {}; set c {}; set d {} -- cgit v0.12 From 56739b80365465180878af37675a2e8524cc1976 Mon Sep 17 00:00:00 2001 From: dgp Date: Mon, 17 Apr 2017 11:59:35 +0000 Subject: Repair revised tests that failed. --- tests/chanio.test | 4 ++-- tests/io.test | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/tests/chanio.test b/tests/chanio.test index cee2675..db2475c 100644 --- a/tests/chanio.test +++ b/tests/chanio.test @@ -5345,7 +5345,7 @@ test chan-io-40.2 {POSIX open access modes: CREAT} -setup { lappend x [chan gets $f] } -cleanup { chan close $f -} -result {0o600 {line 1}} +} -result {0600 {line 1}} test chan-io-40.3 {POSIX open access modes: CREAT} -setup { file delete $path(test3) } -constraints {unix umask} -body { @@ -5353,7 +5353,7 @@ test chan-io-40.3 {POSIX open access modes: CREAT} -setup { chan close [open $path(test3) {WRONLY CREAT}] file stat $path(test3) stats format "%#o" [expr $stats(mode)&0o777] -} -result [format %#5o [expr {0o666 & ~ $umaskValue}]] +} -result [format %#4o [expr {0o666 & ~ $umaskValue}]] test chan-io-40.4 {POSIX open access modes: CREAT} -setup { file delete $path(test3) } -body { diff --git a/tests/io.test b/tests/io.test index 7d8c80f..197fc36 100644 --- a/tests/io.test +++ b/tests/io.test @@ -5653,7 +5653,7 @@ test io-40.3 {POSIX open access modes: CREAT} {unix umask} { close $f file stat $path(test3) stats format "%#o" [expr $stats(mode)&0o777] -} [format %#5o [expr {0o666 & ~ $umaskValue}]] +} [format %#4o [expr {0o666 & ~ $umaskValue}]] test io-40.4 {POSIX open access modes: CREAT} { file delete $path(test3) set f [open $path(test3) w] -- cgit v0.12 From 6f7ac0e29ceacd0fce5b06ff83d80c43812c3b3d Mon Sep 17 00:00:00 2001 From: "jan.nijtmans" Date: Tue, 18 Apr 2017 19:01:51 +0000 Subject: Fix [bc432269b74e9b246bf01f354714fed47cb227ed|bc432269]: http fails in a safe interpreter --- library/http/http.tcl | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) diff --git a/library/http/http.tcl b/library/http/http.tcl index ccd4cd1..03751a3 100644 --- a/library/http/http.tcl +++ b/library/http/http.tcl @@ -28,10 +28,19 @@ namespace eval http { # We need a useragent string of this style or various servers will refuse to # send us compressed content even when we ask for it. This follows the # de-facto layout of user-agent strings in current browsers. - set http(-useragent) "Mozilla/5.0\ - ([string totitle $::tcl_platform(platform)]; U;\ - $::tcl_platform(os) $::tcl_platform(osVersion))\ - http/[package provide http] Tcl/[package provide Tcl]" + # Safe interpreters do not have ::tcl_platform(os) or + # ::tcl_platform(osVersion). + if {[interp issafe]} { + set http(-useragent) "Mozilla/5.0\ + (Windows; U;\ + Windows NT 10.0)\ + http/[package provide http] Tcl/[package provide Tcl]" + } else { + set http(-useragent) "Mozilla/5.0\ + ([string totitle $::tcl_platform(platform)]; U;\ + $::tcl_platform(os) $::tcl_platform(osVersion))\ + http/[package provide http] Tcl/[package provide Tcl]" + } } proc init {} { -- cgit v0.12 From bcbbf6dacf34d9e895fb57c1fea54adc38baed35 Mon Sep 17 00:00:00 2001 From: gcramer Date: Thu, 20 Apr 2017 10:13:02 +0000 Subject: Entry for text.n into exclude_refs_map inserted. --- tools/tcltk-man2html.tcl | 1 + 1 file changed, 1 insertion(+) diff --git a/tools/tcltk-man2html.tcl b/tools/tcltk-man2html.tcl index 5d21866..b0c2d8f 100755 --- a/tools/tcltk-man2html.tcl +++ b/tools/tcltk-man2html.tcl @@ -586,6 +586,7 @@ array set exclude_refs_map { scrollbar.n {set} selection.n {string} tcltest.n {error} + text.n {bind image lower raise} tkvars.n {tk} tkwait.n {variable} tm.n {exec} -- cgit v0.12 From c1b1e9af62be03f294b7d515133f9e55c0c9688e Mon Sep 17 00:00:00 2001 From: "jan.nijtmans" Date: Thu, 20 Apr 2017 11:44:05 +0000 Subject: Remove unused functions like TclWinSetSockOpt()/Tcl_DStringTrunc() if compiled with -DTCL_NO_DEPRECATED --- generic/tcl.h | 17 +++++++++++------ generic/tclInt.h | 2 +- generic/tclStubInit.c | 2 ++ 3 files changed, 14 insertions(+), 7 deletions(-) diff --git a/generic/tcl.h b/generic/tcl.h index 6ec47c6..6fa26f9 100644 --- a/generic/tcl.h +++ b/generic/tcl.h @@ -60,6 +60,7 @@ extern "C" { #define TCL_VERSION "8.7" #define TCL_PATCH_LEVEL "8.7a0" +#if !defined(TCL_NO_DEPRECATED) || defined(RC_INVOKED) /* *---------------------------------------------------------------------------- * The following definitions set up the proper options for Windows compilers. @@ -88,6 +89,7 @@ extern "C" { # define JOIN(a,b) JOIN1(a,b) # define JOIN1(a,b) a##b #endif +#endif /* !TCL_NO_DEPRECATED */ /* * A special definition used to allow this header file to be included from @@ -139,7 +141,7 @@ extern "C" { # define TCL_VARARGS(type, name) (type name, ...) # define TCL_VARARGS_DEF(type, name) (type name, ...) # define TCL_VARARGS_START(type, name, list) (va_start(list, name), name) -#endif +#endif /* !TCL_NO_DEPRECATED */ #if defined(__GNUC__) && (__GNUC__ > 2) # define TCL_FORMAT_PRINTF(a,b) __attribute__ ((__format__ (__printf__, a, b))) # define TCL_NORETURN __attribute__ ((noreturn)) @@ -255,7 +257,7 @@ extern "C" { #ifndef TCL_NO_DEPRECATED # undef _ANSI_ARGS_ # define _ANSI_ARGS_(x) x -#endif +#endif /* !TCL_NO_DEPRECATED */ /* * Definitions that allow this header file to be used either with or without @@ -521,7 +523,7 @@ typedef struct Tcl_Interp int errorLineDontUse; /* Don't use in extensions! */ #endif } -#endif /* TCL_NO_DEPRECATED */ +#endif /* !TCL_NO_DEPRECATED */ Tcl_Interp; typedef struct Tcl_AsyncHandler_ *Tcl_AsyncHandler; @@ -995,7 +997,9 @@ typedef struct Tcl_DString { #define Tcl_DStringLength(dsPtr) ((dsPtr)->length) #define Tcl_DStringValue(dsPtr) ((dsPtr)->string) -#define Tcl_DStringTrunc Tcl_DStringSetLength +#ifndef TCL_NO_DEPRECATED +# define Tcl_DStringTrunc Tcl_DStringSetLength +#endif /* !TCL_NO_DEPRECATED */ /* * Definitions for the maximum number of digits of precision that may be @@ -1123,7 +1127,7 @@ typedef struct Tcl_DString { #ifndef TCL_NO_DEPRECATED # define TCL_PARSE_PART1 0x400 -#endif +#endif /* !TCL_NO_DEPRECATED */ /* * Types for linked variables: @@ -2624,7 +2628,6 @@ EXTERN void Tcl_GetMemoryInfo(Tcl_DString *dsPtr); # define panic Tcl_Panic #endif # define panicVA Tcl_PanicVA -#endif /* !TCL_NO_DEPRECATED */ /* *---------------------------------------------------------------------------- @@ -2635,6 +2638,8 @@ EXTERN void Tcl_GetMemoryInfo(Tcl_DString *dsPtr); extern Tcl_AppInitProc Tcl_AppInit; +#endif /* !TCL_NO_DEPRECATED */ + #endif /* RC_INVOKED */ /* diff --git a/generic/tclInt.h b/generic/tclInt.h index d725688..fdbdb9b 100644 --- a/generic/tclInt.h +++ b/generic/tclInt.h @@ -2630,7 +2630,7 @@ typedef void (TclInitProcessGlobalValueProc)(char **valuePtr, size_t *lengthPtr, */ typedef struct ProcessGlobalValue { - size_t epoch; /* Epoch counter to detect changes in the + size_t epoch; /* Epoch counter to detect changes in the * master value. */ size_t numBytes; /* Length of the master string. */ char *value; /* The master string value. */ diff --git a/generic/tclStubInit.c b/generic/tclStubInit.c index 59325b7..55ef325 100644 --- a/generic/tclStubInit.c +++ b/generic/tclStubInit.c @@ -143,6 +143,7 @@ void *TclWinGetTclInstance() return hInstance; } +#ifndef TCL_NO_DEPRECATED #define TclWinSetSockOpt winSetSockOpt static int TclWinSetSockOpt(SOCKET s, int level, int optname, @@ -165,6 +166,7 @@ TclWinGetServByName(const char *name, const char *proto) { return getservbyname(name, proto); } +#endif /* TCL_NO_DEPRECATED */ #define TclWinNoBackslash winNoBackslash static char * -- cgit v0.12 From 251dc3a322ad2fd4b39b11c5696ac34ddc9a15a5 Mon Sep 17 00:00:00 2001 From: "jan.nijtmans" Date: Thu, 20 Apr 2017 14:07:30 +0000 Subject: Add flag TCL_CC_SEARCH_FLAGS to tclConfig.sh on Windows, just as it exists on unix, even though it should just be empty: TEA extensions might depend on it. --- unix/tclConfig.sh.in | 2 +- win/configure | 3 ++- win/configure.in | 1 + win/makefile.vc | 1 + win/tclConfig.sh.in | 3 ++- 5 files changed, 7 insertions(+), 3 deletions(-) diff --git a/unix/tclConfig.sh.in b/unix/tclConfig.sh.in index b58e9fd..f768690 100644 --- a/unix/tclConfig.sh.in +++ b/unix/tclConfig.sh.in @@ -81,7 +81,7 @@ TCL_DL_LIBS='@DL_LIBS@' # an executable tclsh or tcltest binary. TCL_LD_FLAGS='@LDFLAGS@' -# Flags to pass to ld, such as "-R /usr/local/tcl/lib", that tell the +# Flags to pass to cc/ld, such as "-R /usr/local/tcl/lib", that tell the # run-time dynamic linker where to look for shared libraries such as # libtcl.so. Used when linking applications. Only works if there # is a variable "LIB_RUNTIME_DIR" defined in the Makefile. diff --git a/win/configure b/win/configure index e8e4b87..85dc0ba 100755 --- a/win/configure +++ b/win/configure @@ -309,7 +309,7 @@ ac_includes_default="\ # include #endif" -ac_subst_vars='SHELL PATH_SEPARATOR PACKAGE_NAME PACKAGE_TARNAME PACKAGE_VERSION PACKAGE_STRING PACKAGE_BUGREPORT exec_prefix prefix program_transform_name bindir sbindir libexecdir datadir sysconfdir sharedstatedir localstatedir libdir includedir oldincludedir infodir mandir build_alias host_alias target_alias DEFS ECHO_C ECHO_N ECHO_T LIBS CC CFLAGS LDFLAGS CPPFLAGS ac_ct_CC EXEEXT OBJEXT CPP EGREP AR ac_ct_AR RANLIB ac_ct_RANLIB RC ac_ct_RC SET_MAKE TCL_THREADS CYGPATH CELIB_DIR DL_LIBS CFLAGS_DEBUG CFLAGS_OPTIMIZE CFLAGS_WARNING ZLIB_DLL_FILE ZLIB_LIBS ZLIB_OBJS CFLAGS_DEFAULT LDFLAGS_DEFAULT VC_MANIFEST_EMBED_DLL VC_MANIFEST_EMBED_EXE TCL_WIN_VERSION MACHINE TCL_VERSION TCL_MAJOR_VERSION TCL_MINOR_VERSION TCL_PATCH_LEVEL PKG_CFG_ARGS TCL_EXE TCL_LIB_FILE TCL_LIB_FLAG TCL_STATIC_LIB_FILE TCL_STATIC_LIB_FLAG TCL_IMPORT_LIB_FILE TCL_IMPORT_LIB_FLAG TCL_LIB_SPEC TCL_STUB_LIB_FILE TCL_STUB_LIB_FLAG TCL_STUB_LIB_SPEC TCL_STUB_LIB_PATH TCL_INCLUDE_SPEC TCL_BUILD_STUB_LIB_SPEC TCL_BUILD_STUB_LIB_PATH TCL_DLL_FILE TCL_SRC_DIR TCL_BIN_DIR TCL_DBGX CFG_TCL_SHARED_LIB_SUFFIX CFG_TCL_UNSHARED_LIB_SUFFIX CFG_TCL_EXPORT_FILE_SUFFIX EXTRA_CFLAGS DEPARG CC_OBJNAME CC_EXENAME LDFLAGS_DEBUG LDFLAGS_OPTIMIZE LDFLAGS_CONSOLE LDFLAGS_WINDOW STLIB_LD SHLIB_LD SHLIB_LD_LIBS SHLIB_CFLAGS SHLIB_SUFFIX TCL_SHARED_BUILD LIBS_GUI DLLSUFFIX LIBPREFIX LIBSUFFIX EXESUFFIX LIBRARIES MAKE_LIB MAKE_STUB_LIB POST_MAKE_LIB MAKE_DLL MAKE_EXE TCL_BUILD_LIB_SPEC TCL_LD_SEARCH_FLAGS TCL_NEEDS_EXP_FILE TCL_BUILD_EXP_FILE TCL_EXP_FILE TCL_LIB_VERSIONS_OK TCL_PACKAGE_PATH TCL_DDE_VERSION TCL_DDE_MAJOR_VERSION TCL_DDE_MINOR_VERSION TCL_REG_VERSION TCL_REG_MAJOR_VERSION TCL_REG_MINOR_VERSION RC_OUT RC_TYPE RC_INCLUDE RC_DEFINE RC_DEFINES RES LIBOBJS LTLIBOBJS' +ac_subst_vars='SHELL PATH_SEPARATOR PACKAGE_NAME PACKAGE_TARNAME PACKAGE_VERSION PACKAGE_STRING PACKAGE_BUGREPORT exec_prefix prefix program_transform_name bindir sbindir libexecdir datadir sysconfdir sharedstatedir localstatedir libdir includedir oldincludedir infodir mandir build_alias host_alias target_alias DEFS ECHO_C ECHO_N ECHO_T LIBS CC CFLAGS LDFLAGS CPPFLAGS ac_ct_CC EXEEXT OBJEXT CPP EGREP AR ac_ct_AR RANLIB ac_ct_RANLIB RC ac_ct_RC SET_MAKE TCL_THREADS CYGPATH CELIB_DIR DL_LIBS CFLAGS_DEBUG CFLAGS_OPTIMIZE CFLAGS_WARNING ZLIB_DLL_FILE ZLIB_LIBS ZLIB_OBJS CFLAGS_DEFAULT LDFLAGS_DEFAULT VC_MANIFEST_EMBED_DLL VC_MANIFEST_EMBED_EXE TCL_WIN_VERSION MACHINE TCL_VERSION TCL_MAJOR_VERSION TCL_MINOR_VERSION TCL_PATCH_LEVEL PKG_CFG_ARGS TCL_EXE TCL_LIB_FILE TCL_LIB_FLAG TCL_STATIC_LIB_FILE TCL_STATIC_LIB_FLAG TCL_IMPORT_LIB_FILE TCL_IMPORT_LIB_FLAG TCL_LIB_SPEC TCL_STUB_LIB_FILE TCL_STUB_LIB_FLAG TCL_STUB_LIB_SPEC TCL_STUB_LIB_PATH TCL_INCLUDE_SPEC TCL_BUILD_STUB_LIB_SPEC TCL_BUILD_STUB_LIB_PATH TCL_DLL_FILE TCL_SRC_DIR TCL_BIN_DIR TCL_DBGX CFG_TCL_SHARED_LIB_SUFFIX CFG_TCL_UNSHARED_LIB_SUFFIX CFG_TCL_EXPORT_FILE_SUFFIX EXTRA_CFLAGS DEPARG CC_OBJNAME CC_EXENAME LDFLAGS_DEBUG LDFLAGS_OPTIMIZE LDFLAGS_CONSOLE LDFLAGS_WINDOW STLIB_LD SHLIB_LD SHLIB_LD_LIBS SHLIB_CFLAGS SHLIB_SUFFIX TCL_SHARED_BUILD LIBS_GUI DLLSUFFIX LIBPREFIX LIBSUFFIX EXESUFFIX LIBRARIES MAKE_LIB MAKE_STUB_LIB POST_MAKE_LIB MAKE_DLL MAKE_EXE TCL_BUILD_LIB_SPEC TCL_CC_SEARCH_FLAGS TCL_LD_SEARCH_FLAGS TCL_NEEDS_EXP_FILE TCL_BUILD_EXP_FILE TCL_EXP_FILE TCL_LIB_VERSIONS_OK TCL_PACKAGE_PATH TCL_DDE_VERSION TCL_DDE_MAJOR_VERSION TCL_DDE_MINOR_VERSION TCL_REG_VERSION TCL_REG_MAJOR_VERSION TCL_REG_MINOR_VERSION RC_OUT RC_TYPE RC_INCLUDE RC_DEFINE RC_DEFINES RES LIBOBJS LTLIBOBJS' ac_subst_files='' # Initialize some variables set by options. @@ -6010,6 +6010,7 @@ s,@POST_MAKE_LIB@,$POST_MAKE_LIB,;t t s,@MAKE_DLL@,$MAKE_DLL,;t t s,@MAKE_EXE@,$MAKE_EXE,;t t s,@TCL_BUILD_LIB_SPEC@,$TCL_BUILD_LIB_SPEC,;t t +s,@TCL_CC_SEARCH_FLAGS@,$TCL_CC_SEARCH_FLAGS,;t t s,@TCL_LD_SEARCH_FLAGS@,$TCL_LD_SEARCH_FLAGS,;t t s,@TCL_NEEDS_EXP_FILE@,$TCL_NEEDS_EXP_FILE,;t t s,@TCL_BUILD_EXP_FILE@,$TCL_BUILD_EXP_FILE,;t t diff --git a/win/configure.in b/win/configure.in index 8bb9c48..b478d1e 100644 --- a/win/configure.in +++ b/win/configure.in @@ -433,6 +433,7 @@ AC_SUBST(MAKE_EXE) # empty on win, but needs sub'ing AC_SUBST(TCL_BUILD_LIB_SPEC) +AC_SUBST(TCL_CC_SEARCH_FLAGS) AC_SUBST(TCL_LD_SEARCH_FLAGS) AC_SUBST(TCL_NEEDS_EXP_FILE) AC_SUBST(TCL_BUILD_EXP_FILE) diff --git a/win/makefile.vc b/win/makefile.vc index 8cbae2e..ada08cc 100644 --- a/win/makefile.vc +++ b/win/makefile.vc @@ -878,6 +878,7 @@ $(OUT_DIR)\tclConfig.sh: $(WINDIR)\tclConfig.sh.in @SHLIB_SUFFIX@ .dll @DL_LIBS@ @LDFLAGS@ +@TCL_CC_SEARCH_FLAGS@ @TCL_LD_SEARCH_FLAGS@ @LIBOBJS@ @RANLIB@ diff --git a/win/tclConfig.sh.in b/win/tclConfig.sh.in index 75324b2..6ed06e2 100644 --- a/win/tclConfig.sh.in +++ b/win/tclConfig.sh.in @@ -92,10 +92,11 @@ TCL_DL_LIBS='@DL_LIBS@' # an executable tclsh or tcltest binary. TCL_LD_FLAGS='@LDFLAGS@' -# Flags to pass to ld, such as "-R /usr/local/tcl/lib", that tell the +# Flags to pass to cc/ld, such as "-R /usr/local/tcl/lib", that tell the # run-time dynamic linker where to look for shared libraries such as # libtcl.so. Used when linking applications. Only works if there # is a variable "LIB_RUNTIME_DIR" defined in the Makefile. +TCL_CC_SEARCH_FLAGS='@TCL_CC_SEARCH_FLAGS@' TCL_LD_SEARCH_FLAGS='@TCL_LD_SEARCH_FLAGS@' # Additional object files linked with Tcl to provide compatibility -- cgit v0.12 From 99143db529398b45e139029b3af9727927b1f7c6 Mon Sep 17 00:00:00 2001 From: dkf Date: Sat, 22 Apr 2017 14:57:17 +0000 Subject: A better way of getting source file location information when disassembling. --- generic/tclDisassemble.c | 34 ++++++++++++++++------------------ generic/tclInt.h | 5 +++-- generic/tclProc.c | 35 +++++++++++++++++++++++++++++++++++ 3 files changed, 54 insertions(+), 20 deletions(-) diff --git a/generic/tclDisassemble.c b/generic/tclDisassemble.c index 1d616fb..f62c260 100644 --- a/generic/tclDisassemble.c +++ b/generic/tclDisassemble.c @@ -27,9 +27,8 @@ static Tcl_Obj * DisassembleByteCodeObj(Tcl_Interp *interp, Tcl_Obj *objPtr); static int FormatInstruction(ByteCode *codePtr, const unsigned char *pc, Tcl_Obj *bufferObj); -static void GetLocationInformation(Tcl_Interp *interp, - Proc *procPtr, Tcl_Obj **fileObjPtr, - int *linePtr); +static void GetLocationInformation(Proc *procPtr, + Tcl_Obj **fileObjPtr, int *linePtr); static void PrintSourceToObj(Tcl_Obj *appendObj, const char *stringPtr, int maxChars); static void UpdateStringOfInstName(Tcl_Obj *objPtr); @@ -73,8 +72,6 @@ static const Tcl_ObjType tclInstNameType = { static void GetLocationInformation( - Tcl_Interp *interp, /* Where to look up the location - * information. */ Proc *procPtr, /* What to look up the information for. */ Tcl_Obj **fileObjPtr, /* Where to write the information about what * file the code came from. Will be written @@ -88,20 +85,21 @@ GetLocationInformation( * either with the line number or with -1 if * the information is not available. */ { - Interp *iPtr = (Interp *) interp; - Tcl_HashEntry *hePtr; - CmdFrame *cfPtr; + CmdFrame *cfPtr = TclGetCmdFrameForProcedure(procPtr); *fileObjPtr = NULL; *linePtr = -1; - if (iPtr != NULL && procPtr != NULL) { - hePtr = Tcl_FindHashEntry(iPtr->linePBodyPtr, procPtr); - if (hePtr != NULL && (cfPtr = Tcl_GetHashValue(hePtr)) != NULL) { - *linePtr = cfPtr->line[0]; - if (cfPtr->type == TCL_LOCATION_SOURCE) { - *fileObjPtr = cfPtr->data.eval.path; - } - } + if (cfPtr == NULL) { + return; + } + + /* + * Get the source location data out of the CmdFrame. + */ + + *linePtr = cfPtr->line[0]; + if (cfPtr->type == TCL_LOCATION_SOURCE) { + *fileObjPtr = cfPtr->data.eval.path; } } @@ -278,7 +276,7 @@ DisassembleByteCodeObj( Tcl_AppendToObj(bufferObj, " Source ", -1); PrintSourceToObj(bufferObj, codePtr->source, TclMin(codePtr->numSrcBytes, 55)); - GetLocationInformation(interp, codePtr->procPtr, &fileObj, &line); + GetLocationInformation(codePtr->procPtr, &fileObj, &line); if (line > -1 && fileObj != NULL) { Tcl_AppendPrintfToObj(bufferObj, "\n File \"%s\" Line %d", Tcl_GetString(fileObj), line); @@ -1221,7 +1219,7 @@ DisassembleByteCodeAsDicts( * system if it is available. */ - GetLocationInformation(interp, codePtr->procPtr, &file, &line); + GetLocationInformation(codePtr->procPtr, &file, &line); /* * Build the overall result. diff --git a/generic/tclInt.h b/generic/tclInt.h index 1deda3c..fe4fefd 100644 --- a/generic/tclInt.h +++ b/generic/tclInt.h @@ -2940,7 +2940,8 @@ MODULE_SCOPE Tcl_Obj * TclGetBgErrorHandler(Tcl_Interp *interp); MODULE_SCOPE int TclGetChannelFromObj(Tcl_Interp *interp, Tcl_Obj *objPtr, Tcl_Channel *chanPtr, int *modePtr, int flags); -MODULE_SCOPE int TclGetCompletionCodeFromObj(Tcl_Interp *interp, +MODULE_SCOPE CmdFrame * TclGetCmdFrameForProcedure(Proc *procPtr); +MODULE_SCOPE int TclGetCompletionCodeFromObj(Tcl_Interp *interp, Tcl_Obj *value, int *code); MODULE_SCOPE int TclGetNumberFromObj(Tcl_Interp *interp, Tcl_Obj *objPtr, ClientData *clientDataPtr, @@ -3920,7 +3921,7 @@ MODULE_SCOPE int TclCompileAssembleCmd(Tcl_Interp *interp, struct CompileEnv *envPtr); /* - * Functions defined in generic/tclVar.c and currenttly exported only for use + * Functions defined in generic/tclVar.c and currently exported only for use * by the bytecode compiler and engine. Some of these could later be placed in * the public interface. */ diff --git a/generic/tclProc.c b/generic/tclProc.c index ae9e7cd..5c68e17 100644 --- a/generic/tclProc.c +++ b/generic/tclProc.c @@ -2774,6 +2774,41 @@ MakeLambdaError( } /* + *---------------------------------------------------------------------- + * + * TclGetCmdFrameForProcedure -- + * + * How to get the CmdFrame information for a procedure. + * + * Results: + * A pointer to the CmdFrame (only guaranteed to be valid until the next + * Tcl command is processed or the interpreter's state is otherwise + * modified) or a NULL if the information is not available. + * + * Side effects: + * none. + * + *---------------------------------------------------------------------- + */ + +CmdFrame * +TclGetCmdFrameForProcedure( + Proc *procPtr) /* The procedure whose cmd-frame is to be + * looked up. */ +{ + Tcl_HashEntry *hePtr; + + if (procPtr == NULL || procPtr->iPtr == NULL) { + return NULL; + } + hePtr = Tcl_FindHashEntry(procPtr->iPtr->linePBodyPtr, procPtr); + if (hePtr == NULL) { + return NULL; + } + return (CmdFrame *) Tcl_GetHashValue(hePtr); +} + +/* * Local Variables: * mode: c * c-basic-offset: 4 -- cgit v0.12 From 1f25f80d5bca40729db30c5a551cdbf1e6fa145a Mon Sep 17 00:00:00 2001 From: dkf Date: Tue, 25 Apr 2017 13:08:52 +0000 Subject: Deal with a couple of obscure causes of warnings on some versions of OSX. --- unix/tclUnixInit.c | 58 ++++++++++++++++++++++++++++++++++++------------------ unix/tclUnixSock.c | 35 +++++++++++++++++++++++++------- 2 files changed, 67 insertions(+), 26 deletions(-) diff --git a/unix/tclUnixInit.c b/unix/tclUnixInit.c index badfb36..67e0b65 100644 --- a/unix/tclUnixInit.c +++ b/unix/tclUnixInit.c @@ -744,6 +744,43 @@ Tcl_GetEncodingNameFromEnvironment( *---------------------------------------------------------------------- */ +#if defined(HAVE_COREFOUNDATION) && MAC_OS_X_VERSION_MAX_ALLOWED > 1020 +/* + * Helper because whether CFLocaleCopyCurrent and CFLocaleGetIdentifier are + * strongly or weakly bound varies by version of OSX, triggering warnings. + */ + +static inline void +InitMacLocaleInfoVar( + CFLocaleRef (*localeCopyCurrent)(void), + CFStringRef (*localeGetIdentifier)(CFLocaleRef), + Tcl_Interp *interp) +{ + CFLocaleRef localeRef; + CFStringRef locale; + char loc[256]; + + if (localeCopyCurrent == NULL || localeGetIdentifier == NULL) { + return; + } + + localeRef = localeCopyCurrent(); + if (!localeRef) { + return; + } + + locale = localeGetIdentifier(localeRef); + if (locale && CFStringGetCString(locale, loc, 256, + kCFStringEncodingUTF8)) { + if (!Tcl_CreateNamespace(interp, "::tcl::mac", NULL, NULL)) { + Tcl_ResetResult(interp); + } + Tcl_SetVar(interp, "::tcl::mac::locale", loc, TCL_GLOBAL_ONLY); + } + CFRelease(localeRef); +} +#endif /*defined(HAVE_COREFOUNDATION) && MAC_OS_X_VERSION_MAX_ALLOWED > 1020*/ + void TclpSetVariables( Tcl_Interp *interp) @@ -762,29 +799,12 @@ TclpSetVariables( #ifdef HAVE_COREFOUNDATION char tclLibPath[MAXPATHLEN + 1]; -#if MAC_OS_X_VERSION_MAX_ALLOWED > 1020 /* * Set msgcat fallback locale to current CFLocale identifier. */ - CFLocaleRef localeRef; - - if (&CFLocaleCopyCurrent != NULL && &CFLocaleGetIdentifier != NULL && - (localeRef = CFLocaleCopyCurrent())) { - CFStringRef locale = CFLocaleGetIdentifier(localeRef); - - if (locale) { - char loc[256]; - - if (CFStringGetCString(locale, loc, 256, kCFStringEncodingUTF8)) { - if (!Tcl_CreateNamespace(interp, "::tcl::mac", NULL, NULL)) { - Tcl_ResetResult(interp); - } - Tcl_SetVar(interp, "::tcl::mac::locale", loc, TCL_GLOBAL_ONLY); - } - } - CFRelease(localeRef); - } +#if MAC_OS_X_VERSION_MAX_ALLOWED > 1020 + InitMacLocaleInfoVar(CFLocaleCopyCurrent, CFLocaleGetIdentifier, interp); #endif /* MAC_OS_X_VERSION_MAX_ALLOWED > 1020 */ if (MacOSXGetLibraryPath(interp, MAXPATHLEN, tclLibPath) == TCL_OK) { diff --git a/unix/tclUnixSock.c b/unix/tclUnixSock.c index ca8d677..e8767e2 100644 --- a/unix/tclUnixSock.c +++ b/unix/tclUnixSock.c @@ -698,6 +698,33 @@ TcpClose2Proc( * *---------------------------------------------------------------------- */ + +#ifndef NEED_FAKE_RFC2553 +static inline int +IPv6AddressNeedsNumericRendering( + struct in6_addr addr) +{ + if (IN6_ARE_ADDR_EQUAL(&addr, &in6addr_any)) { + return 1; + } + + /* + * The IN6_IS_ADDR_V4MAPPED macro has a problem with aliasing warnings on + * at least some versions of OSX. + */ + +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wstrict-aliasing" + if (!IN6_IS_ADDR_V4MAPPED(&addr)) { +#pragma GCC diagnostic pop + return 0; + } + + return (addr.s6_addr[12] == 0 && addr.s6_addr[13] == 0 + && addr.s6_addr[14] == 0 && addr.s6_addr[15] == 0); +} +#endif /* NEED_FAKE_RFC2553 */ + static void TcpHostPortList( Tcl_Interp *interp, @@ -723,13 +750,7 @@ TcpHostPortList( } #ifndef NEED_FAKE_RFC2553 } else if (addr.sa.sa_family == AF_INET6) { - if ((IN6_ARE_ADDR_EQUAL(&addr.sa6.sin6_addr, - &in6addr_any)) - || (IN6_IS_ADDR_V4MAPPED(&addr.sa6.sin6_addr) && - addr.sa6.sin6_addr.s6_addr[12] == 0 && - addr.sa6.sin6_addr.s6_addr[13] == 0 && - addr.sa6.sin6_addr.s6_addr[14] == 0 && - addr.sa6.sin6_addr.s6_addr[15] == 0)) { + if (IPv6AddressNeedsNumericRendering(addr.sa6.sin6_addr)) { flags |= NI_NUMERICHOST; } #endif /* NEED_FAKE_RFC2553 */ -- cgit v0.12 From 85dbf412fdd48e0963d920799c9b611556663b1c Mon Sep 17 00:00:00 2001 From: dkf Date: Tue, 25 Apr 2017 19:32:46 +0000 Subject: [50750c735a] Fix for uninit memory handling issue in zlib transforms. --- generic/tclZlib.c | 34 ++++++++++++++++------------------ tests/zlib.test | 2 +- 2 files changed, 17 insertions(+), 19 deletions(-) diff --git a/generic/tclZlib.c b/generic/tclZlib.c index 82486d2..fc20d7e 100644 --- a/generic/tclZlib.c +++ b/generic/tclZlib.c @@ -3113,30 +3113,28 @@ ZlibTransformOutput( errorCodePtr); } + /* + * No zero-length writes. Flushes must be explicit. + */ + + if (toWrite == 0) { + return 0; + } + cd->outStream.next_in = (Bytef *) buf; cd->outStream.avail_in = toWrite; - do { + while (cd->outStream.avail_in > 0) { e = Deflate(&cd->outStream, cd->outBuffer, cd->outAllocated, Z_NO_FLUSH, &produced); + if (e != Z_OK || produced == 0) { + break; + } - if ((e == Z_OK && produced > 0) || e == Z_BUF_ERROR) { - /* - * deflate() indicates that it is out of space by returning - * Z_BUF_ERROR *or* by simply returning Z_OK with no remaining - * space; in either case, we must write the whole buffer out and - * retry to compress what is left. - */ - - if (e == Z_BUF_ERROR) { - produced = cd->outAllocated; - e = Z_OK; - } - if (Tcl_WriteRaw(cd->parent, cd->outBuffer, produced) < 0) { - *errorCodePtr = Tcl_GetErrno(); - return -1; - } + if (Tcl_WriteRaw(cd->parent, cd->outBuffer, produced) < 0) { + *errorCodePtr = Tcl_GetErrno(); + return -1; } - } while (e == Z_OK && produced > 0 && cd->outStream.avail_in > 0); + } if (e == Z_OK) { return toWrite - cd->outStream.avail_in; diff --git a/tests/zlib.test b/tests/zlib.test index 9f06eb1..c2f7825 100644 --- a/tests/zlib.test +++ b/tests/zlib.test @@ -1004,7 +1004,7 @@ test zlib-12.2 {Patrick Dunnigan's issue} -constraints zlib -setup { } -cleanup { removeFile $filesrc removeFile $filedst -} -result 4152 +} -result 56 ::tcltest::cleanupTests return -- cgit v0.12 From fbbc93906e624113a7eeaa6d2dd6ddc01072804d Mon Sep 17 00:00:00 2001 From: "jan.nijtmans" Date: Wed, 26 Apr 2017 13:48:13 +0000 Subject: Move some variable declarations closer to where they are used. No change in functionality. --- unix/tclEpollNotfy.c | 16 +++++----------- unix/tclUnixNotfy.c | 7 +------ 2 files changed, 6 insertions(+), 17 deletions(-) diff --git a/unix/tclEpollNotfy.c b/unix/tclEpollNotfy.c index 28fc834..5ed5d5d 100644 --- a/unix/tclEpollNotfy.c +++ b/unix/tclEpollNotfy.c @@ -354,24 +354,21 @@ PlatformEventsInit( if (errno) { Tcl_Panic("Tcl_InitNotifier: %s", "could not create mutex"); } + filePtr = ckalloc(sizeof(*filePtr)); #ifdef HAVE_EVENTFD if ((tsdPtr->triggerEventFd = eventfd(0, EFD_CLOEXEC | EFD_NONBLOCK)) <= 0) { Tcl_Panic("Tcl_InitNotifier: %s", "could not create trigger eventfd"); } + filePtr->fd = tsdPtr->triggerEventFd; #else if (pipe2(tsdPtr->triggerPipe, O_CLOEXEC | O_NONBLOCK) != 0) { Tcl_Panic("Tcl_InitNotifier: %s", "could not create trigger pipe"); } + filePtr->fd = tsdPtr->triggerPipe[0]; #endif if ((tsdPtr->eventsFd = epoll_create1(EPOLL_CLOEXEC)) == -1) { Tcl_Panic("epoll_create1: %s", strerror(errno)); } - filePtr = ckalloc(sizeof(*filePtr)); -#ifdef HAVE_EVENTFD - filePtr->fd = tsdPtr->triggerEventFd; -#else - filePtr->fd = tsdPtr->triggerPipe[0]; -#endif filePtr->mask = TCL_READABLE; PlatformEventsControl(filePtr, tsdPtr, EPOLL_CTL_ADD, 1); if (!tsdPtr->readyEvents) { @@ -660,11 +657,6 @@ Tcl_WaitForEvent( ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&dataKey); int numQueued; ssize_t i; -#ifdef HAVE_EVENTFD - uint64_t eventFdVal; -#else - char triggerPipeVal; -#endif /* * Set up the timeout structure. Note that if there are no events to @@ -760,10 +752,12 @@ Tcl_WaitForEvent( mask = PlatformEventsTranslate(&tsdPtr->readyEvents[numEvent]); #ifdef HAVE_EVENTFD if (filePtr->fd == tsdPtr->triggerEventFd) { + uint64_t eventFdVal; i = read(tsdPtr->triggerEventFd, &eventFdVal, sizeof(eventFdVal)); if ((i != sizeof(eventFdVal)) && (errno != EAGAIN)) { #else if (filePtr->fd == tsdPtr->triggerPipe[0]) { + char triggerPipeVal; i = read(tsdPtr->triggerPipe[0], &triggerPipeVal, sizeof(triggerPipeVal)); if ((i != sizeof(triggerPipeVal)) && (errno != EAGAIN)) { #endif diff --git a/unix/tclUnixNotfy.c b/unix/tclUnixNotfy.c index 17307dc..5bc753a 100644 --- a/unix/tclUnixNotfy.c +++ b/unix/tclUnixNotfy.c @@ -102,11 +102,6 @@ void Tcl_AlertNotifier( ClientData clientData) { -#ifdef NOTIFIER_EPOLL -#ifdef HAVE_EVENTFD - uint64_t eventFdVal; -#endif /* HAVE_EVENTFD */ -#endif /* NOTIFIER_EPOLL */ if (tclNotifierHooks.alertNotifierProc) { tclNotifierHooks.alertNotifierProc(clientData); return; @@ -128,7 +123,7 @@ Tcl_AlertNotifier( #else ThreadSpecificData *tsdPtr = clientData; #if defined(NOTIFIER_EPOLL) && defined(HAVE_EVENTFD) - eventFdVal = 1; + uint64_t eventFdVal = 1; if (write(tsdPtr->triggerEventFd, &eventFdVal, sizeof(eventFdVal)) != sizeof(eventFdVal)) { Tcl_Panic("Tcl_AlertNotifier: unable to write to %p->triggerEventFd", -- cgit v0.12 From e3a9350e58588d7d50bc37bc15abd1efb84dcbc1 Mon Sep 17 00:00:00 2001 From: dkf Date: Thu, 27 Apr 2017 12:38:21 +0000 Subject: Start of implementation of TIP #470. --- generic/tclOO.c | 1 + generic/tclOODefineCmds.c | 43 ++++++++++++++++++++++++++++++++++++++----- generic/tclOOInt.h | 3 +++ 3 files changed, 42 insertions(+), 5 deletions(-) diff --git a/generic/tclOO.c b/generic/tclOO.c index ef0c987..73acce8 100644 --- a/generic/tclOO.c +++ b/generic/tclOO.c @@ -41,6 +41,7 @@ static const struct { {"forward", TclOODefineForwardObjCmd, 1}, {"method", TclOODefineMethodObjCmd, 1}, {"renamemethod", TclOODefineRenameMethodObjCmd, 1}, + {"self", TclOODefineObjSelfObjCmd, 0}, {"unexport", TclOODefineUnexportObjCmd, 1}, {NULL, NULL, 0} }; diff --git a/generic/tclOODefineCmds.c b/generic/tclOODefineCmds.c index 5b0dfc3..d3ab1eb 100644 --- a/generic/tclOODefineCmds.c +++ b/generic/tclOODefineCmds.c @@ -1028,16 +1028,16 @@ TclOODefineSelfObjCmd( int result; Object *oPtr; - if (objc < 2) { - Tcl_WrongNumArgs(interp, 1, objv, "arg ?arg ...?"); - return TCL_ERROR; - } - oPtr = (Object *) TclOOGetDefineCmdContext(interp); if (oPtr == NULL) { return TCL_ERROR; } + if (objc < 2) { + Tcl_SetObjResult(interp, TclOOObjectName(interp, oPtr)); + return TCL_OK; + } + /* * Make the oo::objdefine namespace the current namespace and evaluate the * command(s). @@ -1113,6 +1113,39 @@ TclOODefineSelfObjCmd( /* * ---------------------------------------------------------------------- * + * TclOODefineObjSelfObjCmd -- + * Implementation of the "self" subcommand of the "oo::objdefine" + * command. + * + * ---------------------------------------------------------------------- + */ + +int +TclOODefineObjSelfObjCmd( + ClientData clientData, + Tcl_Interp *interp, + int objc, + Tcl_Obj *const *objv) +{ + Object *oPtr; + + if (objc != 1) { + Tcl_WrongNumArgs(interp, 1, objv, NULL); + return TCL_ERROR; + } + + oPtr = (Object *) TclOOGetDefineCmdContext(interp); + if (oPtr == NULL) { + return TCL_ERROR; + } + + Tcl_SetObjResult(interp, TclOOObjectName(interp, oPtr)); + return TCL_OK; +} + +/* + * ---------------------------------------------------------------------- + * * TclOODefineClassObjCmd -- * Implementation of the "class" subcommand of the "oo::objdefine" * command. diff --git a/generic/tclOOInt.h b/generic/tclOOInt.h index ae24dee..476446d 100644 --- a/generic/tclOOInt.h +++ b/generic/tclOOInt.h @@ -431,6 +431,9 @@ MODULE_SCOPE int TclOODefineClassObjCmd(ClientData clientData, MODULE_SCOPE int TclOODefineSelfObjCmd(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv); +MODULE_SCOPE int TclOODefineObjSelfObjCmd(ClientData clientData, + Tcl_Interp *interp, int objc, + Tcl_Obj *const *objv); MODULE_SCOPE int TclOOUnknownDefinition(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv); -- cgit v0.12 From 2bf6ae09b3ac48095177c0f52735fb9bfa10f164 Mon Sep 17 00:00:00 2001 From: dgp Date: Thu, 27 Apr 2017 17:19:31 +0000 Subject: [04e26c02c0] Remove useless condition that raises warnings. --- generic/tclExecute.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/generic/tclExecute.c b/generic/tclExecute.c index cb4e6dc..d30e757 100644 --- a/generic/tclExecute.c +++ b/generic/tclExecute.c @@ -510,8 +510,7 @@ VarHashCreateVar( : (*(tPtr) = TCL_NUMBER_DOUBLE)), \ *(ptrPtr) = (ClientData) \ (&((objPtr)->internalRep.doubleValue)), TCL_OK) : \ - ((((objPtr)->typePtr == NULL) && ((objPtr)->bytes == NULL)) || \ - (((objPtr)->bytes != NULL) && ((objPtr)->length == 0))) \ + (((objPtr)->bytes != NULL) && ((objPtr)->length == 0)) \ ? (*(tPtr) = TCL_NUMBER_LONG),TCL_ERROR : \ TclGetNumberFromObj((interp), (objPtr), (ptrPtr), (tPtr))) #else /* !TCL_WIDE_INT_IS_LONG */ @@ -530,8 +529,7 @@ VarHashCreateVar( : (*(tPtr) = TCL_NUMBER_DOUBLE)), \ *(ptrPtr) = (ClientData) \ (&((objPtr)->internalRep.doubleValue)), TCL_OK) : \ - ((((objPtr)->typePtr == NULL) && ((objPtr)->bytes == NULL)) || \ - (((objPtr)->bytes != NULL) && ((objPtr)->length == 0))) \ + (((objPtr)->bytes != NULL) && ((objPtr)->length == 0)) \ ? (*(tPtr) = TCL_NUMBER_LONG),TCL_ERROR : \ TclGetNumberFromObj((interp), (objPtr), (ptrPtr), (tPtr))) #endif /* TCL_WIDE_INT_IS_LONG */ -- cgit v0.12 From 513d77788d26b5ffb845e468b2d6451aab09d199 Mon Sep 17 00:00:00 2001 From: "jan.nijtmans" Date: Fri, 28 Apr 2017 13:13:10 +0000 Subject: (cherry-pick from "fix-1997007" branch): fix typo-bug (using wrong thread handle by set priority) --- win/tclWinPipe.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/win/tclWinPipe.c b/win/tclWinPipe.c index 4666deb..4775418 100644 --- a/win/tclWinPipe.c +++ b/win/tclWinPipe.c @@ -1618,7 +1618,7 @@ TclpCreateCommandChannel( infoPtr->stopWriter = CreateEvent(NULL, TRUE, FALSE, NULL); infoPtr->writeThread = CreateThread(NULL, 256, PipeWriterThread, infoPtr, 0, &id); - SetThreadPriority(infoPtr->readThread, THREAD_PRIORITY_HIGHEST); + SetThreadPriority(infoPtr->writeThread, THREAD_PRIORITY_HIGHEST); infoPtr->validMask |= TCL_WRITABLE; } -- cgit v0.12 From fecff1bcf0617bd35993cd9cb43a5f6a61618336 Mon Sep 17 00:00:00 2001 From: "jan.nijtmans" Date: Fri, 28 Apr 2017 13:17:20 +0000 Subject: (cherry-pick from "fix-1997007" branch): fix typo- resp. copy-paste-bug (using wrong threadInfo pointer in ConsoleOutputProc, should be writer, not reader) --- unix/tclUnixSock.c | 2 +- win/tclWinConsole.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/unix/tclUnixSock.c b/unix/tclUnixSock.c index e8767e2..b9b6b53 100644 --- a/unix/tclUnixSock.c +++ b/unix/tclUnixSock.c @@ -713,7 +713,7 @@ IPv6AddressNeedsNumericRendering( * at least some versions of OSX. */ -#pragma GCC diagnostic push +#pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Wstrict-aliasing" if (!IN6_IS_ADDR_V4MAPPED(&addr)) { #pragma GCC diagnostic pop diff --git a/win/tclWinConsole.c b/win/tclWinConsole.c index ab55035..71facef 100644 --- a/win/tclWinConsole.c +++ b/win/tclWinConsole.c @@ -808,7 +808,7 @@ ConsoleOutputProc( int *errorCode) /* Where to store error code. */ { ConsoleInfo *infoPtr = instanceData; - ConsoleThreadInfo *threadInfo = &infoPtr->reader; + ConsoleThreadInfo *threadInfo = &infoPtr->writer; DWORD bytesWritten, timeout; *errorCode = 0; -- cgit v0.12 From dc9c72819c2c48b04051b15afad583edecfc5aa7 Mon Sep 17 00:00:00 2001 From: dgp Date: Fri, 28 Apr 2017 14:15:18 +0000 Subject: silence uninit variable warnings --- generic/tclExecute.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/generic/tclExecute.c b/generic/tclExecute.c index d30e757..6499cf8 100644 --- a/generic/tclExecute.c +++ b/generic/tclExecute.c @@ -9408,7 +9408,7 @@ TclCompareTwoNumbers( Tcl_Obj *valuePtr, Tcl_Obj *value2Ptr) { - int type1, type2, compare; + int type1 = TCL_NUMBER_NAN, type2 = TCL_NUMBER_NAN, compare; ClientData ptr1, ptr2; mp_int big1, big2; double d1, d2, tmp; -- cgit v0.12 From 90ffbb41701e9550ed98e8454d100d5a48531b33 Mon Sep 17 00:00:00 2001 From: fvogel Date: Sat, 29 Apr 2017 14:41:20 +0000 Subject: Make trunk compile on MSVC (problem was: warning C4554: '&' : check operator precedence for possible error; use parentheses to clarify precedence) --- win/tclWinChan.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/win/tclWinChan.c b/win/tclWinChan.c index 010621c..2898db0 100644 --- a/win/tclWinChan.c +++ b/win/tclWinChan.c @@ -128,7 +128,7 @@ static const Tcl_ChannelType fileChannelType = { #define SET_FLAG(var, flag) ((var) |= (flag)) #define CLEAR_FLAG(var, flag) ((var) &= ~(flag)) -#define TEST_FLAG(value, flag) ((value) & (flag) != 0) +#define TEST_FLAG(value, flag) (((value) & (flag)) != 0) /* *---------------------------------------------------------------------- -- cgit v0.12 From be831d7ecb9df8ebfad280ac50be1773124c08bd Mon Sep 17 00:00:00 2001 From: dgp Date: Mon, 1 May 2017 20:29:02 +0000 Subject: Revert the colorful debug garbage mistakenly committed. --- generic/tclPathObj.c | 10 ++-------- 1 file changed, 2 insertions(+), 8 deletions(-) diff --git a/generic/tclPathObj.c b/generic/tclPathObj.c index ffeb688..5984c16 100644 --- a/generic/tclPathObj.c +++ b/generic/tclPathObj.c @@ -1322,14 +1322,8 @@ TclNewFSPathObj( fsPathPtr->translatedPathPtr = NULL; fsPathPtr->normPathPtr = Tcl_NewStringObj(addStrRep, len); Tcl_IncrRefCount(fsPathPtr->normPathPtr); - - if (TCL_PATH_ABSOLUTE == Tcl_FSGetPathType(dirPtr)) { - fsPathPtr->cwdPtr = Tcl_FSGetNormalizedPath(NULL, dirPtr); - } else { -fprintf(stdout, "FUCKING BROKEN!\n"); fflush(stdout); - fsPathPtr->cwdPtr = dirPtr; - } - Tcl_IncrRefCount(fsPathPtr->cwdPtr); + fsPathPtr->cwdPtr = dirPtr; + Tcl_IncrRefCount(dirPtr); fsPathPtr->nativePathPtr = NULL; fsPathPtr->fsPtr = NULL; fsPathPtr->filesystemEpoch = 0; -- cgit v0.12 From 910200b637f2025d21da89213ea124bb28785632 Mon Sep 17 00:00:00 2001 From: "jan.nijtmans" Date: Tue, 2 May 2017 12:36:42 +0000 Subject: Extend "deprecated" functionality of genStubs.tcl: XX_DEPRECATED macro now accepts a message text, which will be used in the compiler's error message. Not used (yet) in Tcl. --- tools/genStubs.tcl | 32 +++++++++++++++++++------------- 1 file changed, 19 insertions(+), 13 deletions(-) diff --git a/tools/genStubs.tcl b/tools/genStubs.tcl index 742aa46..5956711 100644 --- a/tools/genStubs.tcl +++ b/tools/genStubs.tcl @@ -191,19 +191,21 @@ proc genStubs::declare {args} { regsub -all "\[ \t\n\]+" [string trim $decl] " " decl set decl [parseDecl $decl] - foreach platform $platformList { - if {$decl ne ""} { - set stubs($curName,$platform,$index) $decl - if {![info exists stubs($curName,$platform,lastNum)] \ - || ($index > $stubs($curName,$platform,lastNum))} { - set stubs($curName,$platform,lastNum) $index - } + if {([lindex $platformList 0] eq "deprecated")} { + set stubs($curName,deprecated,$index) [lindex $platformList 1] + set stubs($curName,generic,$index) $decl + if {![info exists stubs($curName,generic,lastNum)] \ + || ($index > $stubs($curName,generic,lastNum))} { + set stubs($curName,generic,lastNum) $index } - if {$platformList eq "deprecated"} { - set stubs($curName,generic,$index) $decl - if {![info exists stubs($curName,generic,lastNum)] \ - || ($index > $stubs($curName,generic,lastNum))} { - set stubs($curName,$platform,lastNum) $index + } else { + foreach platform $platformList { + if {$decl ne ""} { + set stubs($curName,$platform,$index) $decl + if {![info exists stubs($curName,$platform,lastNum)] \ + || ($index > $stubs($curName,$platform,lastNum))} { + set stubs($curName,$platform,lastNum) $index + } } } } @@ -468,7 +470,7 @@ proc genStubs::makeDecl {name decl index} { append text "/* $index */\n" if {[info exists stubs($name,deprecated,$index)]} { - set line "[string toupper $libraryName]_DEPRECATED $rtype" + set line "[string toupper $libraryName]_DEPRECATED(\"$stubs($name,deprecated,$index)\")\n$rtype" } else { set line "$scspec $rtype" } @@ -582,11 +584,15 @@ proc genStubs::makeMacro {name decl index} { proc genStubs::makeSlot {name decl index} { lassign $decl rtype fname args + variable stubs set lfname [string tolower [string index $fname 0]] append lfname [string range $fname 1 end] set text " " + if {[info exists stubs($name,deprecated,$index)]} { + append text "TCL_DEPRECATED_API(\"$stubs($name,deprecated,$index)\") " + } if {$args eq ""} { append text $rtype " *" $lfname "; /* $index */\n" return $text -- cgit v0.12 From 709366bdfe97b432487806c7cdbfe1eed1c365f2 Mon Sep 17 00:00:00 2001 From: "jan.nijtmans" Date: Wed, 3 May 2017 10:03:00 +0000 Subject: slightly better formatting, both in genStubs.tcl and in the generated XXX_DEPRECATED functions. --- tools/genStubs.tcl | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/tools/genStubs.tcl b/tools/genStubs.tcl index 5956711..830ba2b 100644 --- a/tools/genStubs.tcl +++ b/tools/genStubs.tcl @@ -470,9 +470,10 @@ proc genStubs::makeDecl {name decl index} { append text "/* $index */\n" if {[info exists stubs($name,deprecated,$index)]} { - set line "[string toupper $libraryName]_DEPRECATED(\"$stubs($name,deprecated,$index)\")\n$rtype" + append text "[string toupper $libraryName]_DEPRECATED(\"$stubs($name,deprecated,$index)\")\n" + set line "$rtype" } else { - set line "$scspec $rtype" + set line "$scspec $rtype" } set count [expr {2 - ([string length $line] / 8)}] append line [string range "\t\t\t" 0 $count] -- cgit v0.12 From fd7ea3420f7e0a7c10eae2adb29e7fe119c8eddf Mon Sep 17 00:00:00 2001 From: "jan.nijtmans" Date: Thu, 4 May 2017 09:35:14 +0000 Subject: Fix gcc warning: unused variable wakeEvent --- win/tclWinPipe.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/win/tclWinPipe.c b/win/tclWinPipe.c index 3e7e5eb..5246d53 100644 --- a/win/tclWinPipe.c +++ b/win/tclWinPipe.c @@ -3253,7 +3253,7 @@ TclPipeThreadStop( HANDLE hThread) { TclPipeThreadInfo *pipeTI = *pipeTIPtr; - HANDLE evControl, wakeEvent; + HANDLE evControl; int state; if (!pipeTI) { @@ -3261,7 +3261,6 @@ TclPipeThreadStop( } pipeTI = *pipeTIPtr; evControl = pipeTI->evControl; - wakeEvent = pipeTI->evWakeUp; pipeTI->evWakeUp = NULL; /* * Try to sane stop the pipe worker, corresponding its current state -- cgit v0.12 From 46f75926ff14edcf9e58e0f665d1f2cd3a413a3f Mon Sep 17 00:00:00 2001 From: "jan.nijtmans" Date: Tue, 9 May 2017 09:28:06 +0000 Subject: Let local variables declared from within macro's always start with underscore, this fixes some gcc warnings with -Wshadow. --- generic/tclCompile.h | 24 +++++++++++----------- generic/tclInt.h | 58 ++++++++++++++++++++++++++-------------------------- 2 files changed, 41 insertions(+), 41 deletions(-) diff --git a/generic/tclCompile.h b/generic/tclCompile.h index e5d026c..c04fc0e 100644 --- a/generic/tclCompile.h +++ b/generic/tclCompile.h @@ -1261,10 +1261,10 @@ MODULE_SCOPE int TclPushProcCallFrame(ClientData clientData, #define TclCheckStackDepth(depth, envPtr) \ do { \ - int dd = (depth); \ - if (dd != (envPtr)->currStackDepth) { \ + int _dd = (depth); \ + if (_dd != (envPtr)->currStackDepth) { \ Tcl_Panic("bad stack depth computations: is %i, should be %i", \ - (envPtr)->currStackDepth, dd); \ + (envPtr)->currStackDepth, _dd); \ } \ } while (0) @@ -1280,12 +1280,12 @@ MODULE_SCOPE int TclPushProcCallFrame(ClientData clientData, #define TclUpdateStackReqs(op, i, envPtr) \ do { \ - int delta = tclInstructionTable[(op)].stackEffect; \ - if (delta) { \ - if (delta == INT_MIN) { \ - delta = 1 - (i); \ + int _delta = tclInstructionTable[(op)].stackEffect; \ + if (_delta) { \ + if (_delta == INT_MIN) { \ + _delta = 1 - (i); \ } \ - TclAdjustStackDepth(delta, envPtr); \ + TclAdjustStackDepth(_delta, envPtr); \ } \ } while (0) @@ -1399,11 +1399,11 @@ MODULE_SCOPE int TclPushProcCallFrame(ClientData clientData, #define TclEmitPush(objIndex, envPtr) \ do { \ - register int objIndexCopy = (objIndex); \ - if (objIndexCopy <= 255) { \ - TclEmitInstInt1(INST_PUSH1, objIndexCopy, (envPtr)); \ + register int _objIndexCopy = (objIndex); \ + if (_objIndexCopy <= 255) { \ + TclEmitInstInt1(INST_PUSH1, _objIndexCopy, (envPtr)); \ } else { \ - TclEmitInstInt4(INST_PUSH4, objIndexCopy, (envPtr)); \ + TclEmitInstInt4(INST_PUSH4, _objIndexCopy, (envPtr)); \ } \ } while (0) diff --git a/generic/tclInt.h b/generic/tclInt.h index fe4fefd..2938074 100644 --- a/generic/tclInt.h +++ b/generic/tclInt.h @@ -4305,13 +4305,13 @@ MODULE_SCOPE void TclDbInitNewObj(Tcl_Obj *objPtr, const char *file, #define TCL_MAX_TOKENS (int)(UINT_MAX / sizeof(Tcl_Token)) #define TclGrowTokenArray(tokenPtr, used, available, append, staticPtr) \ do { \ - int needed = (used) + (append); \ - if (needed > TCL_MAX_TOKENS) { \ + int _needed = (used) + (append); \ + if (_needed > TCL_MAX_TOKENS) { \ Tcl_Panic("max # of tokens for a Tcl parse (%d) exceeded", \ TCL_MAX_TOKENS); \ } \ - if (needed > (available)) { \ - int allocated = 2 * needed; \ + if (_needed > (available)) { \ + int allocated = 2 * _needed; \ Tcl_Token *oldPtr = (tokenPtr); \ Tcl_Token *newPtr; \ if (oldPtr == (staticPtr)) { \ @@ -4323,7 +4323,7 @@ MODULE_SCOPE void TclDbInitNewObj(Tcl_Obj *objPtr, const char *file, newPtr = (Tcl_Token *) attemptckrealloc((char *) oldPtr, \ (unsigned int) (allocated * sizeof(Tcl_Token))); \ if (newPtr == NULL) { \ - allocated = needed + (append) + TCL_MIN_TOKEN_GROWTH; \ + allocated = _needed + (append) + TCL_MIN_TOKEN_GROWTH; \ if (allocated > TCL_MAX_TOKENS) { \ allocated = TCL_MAX_TOKENS; \ } \ @@ -4375,14 +4375,14 @@ MODULE_SCOPE void TclDbInitNewObj(Tcl_Obj *objPtr, const char *file, #define TclNumUtfChars(numChars, bytes, numBytes) \ do { \ - int count, i = (numBytes); \ - unsigned char *str = (unsigned char *) (bytes); \ - while (i && (*str < 0xC0)) { i--; str++; } \ - count = (numBytes) - i; \ - if (i) { \ - count += Tcl_NumUtfChars((bytes) + count, i); \ + int _count, _i = (numBytes); \ + unsigned char *_str = (unsigned char *) (bytes); \ + while (_i && (*_str < 0xC0)) { _i--; _str++; } \ + _count = (numBytes) - _i; \ + if (_i) { \ + _count += Tcl_NumUtfChars((bytes) + _count, _i); \ } \ - (numChars) = count; \ + (numChars) = _count; \ } while (0); /* @@ -4741,11 +4741,11 @@ MODULE_SCOPE Tcl_PackageInitProc Procbodytest_SafeInit; #ifndef TCL_MEM_DEBUG #define TclSmallAllocEx(interp, nbytes, memPtr) \ do { \ - Tcl_Obj *objPtr; \ + Tcl_Obj *_objPtr; \ TCL_CT_ASSERT((nbytes)<=sizeof(Tcl_Obj)); \ TclIncrObjsAllocated(); \ - TclAllocObjStorageEx((interp), (objPtr)); \ - memPtr = (ClientData) (objPtr); \ + TclAllocObjStorageEx((interp), (_objPtr)); \ + memPtr = (ClientData) (_objPtr); \ } while (0) #define TclSmallFreeEx(interp, memPtr) \ @@ -4757,19 +4757,19 @@ MODULE_SCOPE Tcl_PackageInitProc Procbodytest_SafeInit; #else /* TCL_MEM_DEBUG */ #define TclSmallAllocEx(interp, nbytes, memPtr) \ do { \ - Tcl_Obj *objPtr; \ + Tcl_Obj *_objPtr; \ TCL_CT_ASSERT((nbytes)<=sizeof(Tcl_Obj)); \ - TclNewObj(objPtr); \ - memPtr = (ClientData) objPtr; \ + TclNewObj(_objPtr); \ + memPtr = (ClientData) _objPtr; \ } while (0) #define TclSmallFreeEx(interp, memPtr) \ do { \ - Tcl_Obj *objPtr = (Tcl_Obj *) memPtr; \ + Tcl_Obj *_objPtr = (Tcl_Obj *) memPtr; \ objPtr->bytes = NULL; \ objPtr->typePtr = NULL; \ objPtr->refCount = 1; \ - TclDecrRefCount(objPtr); \ + TclDecrRefCount(_objPtr); \ } while (0) #endif /* TCL_MEM_DEBUG */ @@ -4821,15 +4821,15 @@ typedef struct NRE_callback { #define TclNRAddCallback(interp,postProcPtr,data0,data1,data2,data3) \ do { \ - NRE_callback *callbackPtr; \ - TCLNR_ALLOC((interp), (callbackPtr)); \ - callbackPtr->procPtr = (postProcPtr); \ - callbackPtr->data[0] = (ClientData)(data0); \ - callbackPtr->data[1] = (ClientData)(data1); \ - callbackPtr->data[2] = (ClientData)(data2); \ - callbackPtr->data[3] = (ClientData)(data3); \ - callbackPtr->nextPtr = TOP_CB(interp); \ - TOP_CB(interp) = callbackPtr; \ + NRE_callback *_callbackPtr; \ + TCLNR_ALLOC((interp), (_callbackPtr)); \ + _callbackPtr->procPtr = (postProcPtr); \ + _callbackPtr->data[0] = (ClientData)(data0); \ + _callbackPtr->data[1] = (ClientData)(data1); \ + _callbackPtr->data[2] = (ClientData)(data2); \ + _callbackPtr->data[3] = (ClientData)(data3); \ + _callbackPtr->nextPtr = TOP_CB(interp); \ + TOP_CB(interp) = _callbackPtr; \ } while (0) #if NRE_USE_SMALL_ALLOC -- cgit v0.12 From 2752a9f58b6ee57703c3bc087133751e0192f150 Mon Sep 17 00:00:00 2001 From: sebres Date: Tue, 9 May 2017 22:24:44 +0000 Subject: add missing compile functionality (TclPreserveByteCode/TclReleaseByteCode back-ported as inline from trunk) --- generic/tclCompile.h | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/generic/tclCompile.h b/generic/tclCompile.h index c04fc0e..90edf07 100644 --- a/generic/tclCompile.h +++ b/generic/tclCompile.h @@ -1159,6 +1159,25 @@ MODULE_SCOPE void TclPushVarName(Tcl_Interp *interp, Tcl_Token *varTokenPtr, CompileEnv *envPtr, int flags, int *localIndexPtr, int *isScalarPtr); + +static inline void +TclPreserveByteCode( + register ByteCode *codePtr) +{ + codePtr->refCount++; +} + +static inline void +TclReleaseByteCode( + register ByteCode *codePtr) +{ + if (codePtr->refCount-- > 1) { + return; + } + /* Just dropped to refcount==0. Clean up. */ + TclCleanupByteCode(codePtr); +} + MODULE_SCOPE void TclReleaseLiteral(Tcl_Interp *interp, Tcl_Obj *objPtr); MODULE_SCOPE void TclInvalidateCmdLiteral(Tcl_Interp *interp, const char *name, Namespace *nsPtr); -- cgit v0.12 From a021af135e023aebc82a9062835c46473a1777fd Mon Sep 17 00:00:00 2001 From: sebres Date: Wed, 10 May 2017 12:29:42 +0000 Subject: clock.test normalized (compared with trunk) --- tests/clock.test | 135 ++++++++++++++++++++++++++++++++++++++----------------- 1 file changed, 95 insertions(+), 40 deletions(-) diff --git a/tests/clock.test b/tests/clock.test index 103f254..9e86c97 100644 --- a/tests/clock.test +++ b/tests/clock.test @@ -36,9 +36,9 @@ testConstraint y2038 \ # TEST PLAN # clock-1: -# [clock format] - tests of bad and empty arguments +# [clock format] - tests of bad and empty arguments # -# clock-2 +# clock-2 # formatting of year, month and day of month # # clock-3 @@ -196,7 +196,7 @@ namespace eval ::tcl::clock { l li lii liii liv lv lvi lvii lviii lix lx lxi lxii lxiii lxiv lxv lxvi lxvii lxviii lxix lxx lxxi lxxii lxxiii lxxiv lxxv lxxvi lxxvii lxxviii lxxix - lxxx lxxxi lxxxii lxxxiii lxxxiv lxxxv lxxxvi lxxxvii lxxxviii + lxxx lxxxi lxxxii lxxxiii lxxxiv lxxxv lxxxvi lxxxvii lxxxviii lxxxix xc xci xcii xciii xciv xcv xcvi xcvii xcviii xcix c @@ -273,7 +273,7 @@ test clock-1.4 "clock format - bad flag" {*}{ -body { # range error message for possible extensions: list [catch {clock format 0 -oops badflag} msg] [string range $msg 0 60] $::errorCode - } + } -match glob -result {1 {bad option "-oops": must be -format, -gmt, -locale, -timezone} {CLOCK badOption -oops}} } @@ -35143,6 +35143,10 @@ test clock-29.1800 {time parsing} { } 86399 # END testcases29 + +# BEGIN testcases30 + +# Test [clock add] test clock-30.1 {clock add years} { set t [clock scan 2000-01-01 -format %Y-%m-%d -timezone :UTC] set f [clock add $t 1 year -timezone :UTC] @@ -35369,10 +35373,61 @@ test clock-30.25 {clock add seconds at DST conversion} { set x1 [clock format $f1 -format {%Y-%m-%d %H:%M:%S %z} \ -timezone EST05:00EDT04:00,M4.1.0/02:00,M10.5.0/02:00] } {2004-10-31 01:00:00 -0500} +test clock-30.26 {clock add weekdays} { + set t [clock scan {2013-11-20}] ;# Wednesday + set f1 [clock add $t 3 weekdays] + set x1 [clock format $f1 -format {%Y-%m-%d}] +} {2013-11-25} +test clock-30.27 {clock add weekdays starting on Saturday} { + set t [clock scan {2013-11-23}] ;# Saturday + set f1 [clock add $t 1 weekday] + set x1 [clock format $f1 -format {%Y-%m-%d}] +} {2013-11-25} +test clock-30.28 {clock add weekdays starting on Sunday} { + set t [clock scan {2013-11-24}] ;# Sunday + set f1 [clock add $t 1 weekday] + set x1 [clock format $f1 -format {%Y-%m-%d}] +} {2013-11-25} +test clock-30.29 {clock add 0 weekdays starting on a weekend} { + set t [clock scan {2016-02-27}] ;# Saturday + set f1 [clock add $t 0 weekdays] + set x1 [clock format $f1 -format {%Y-%m-%d}] +} {2016-02-27} +test clock-30.30 {clock add weekdays and back} -body { + set n [clock seconds] + # we start on each day of the week + for {set i 0} {$i < 7} {incr i} { + set start [clock add $n $i days] + set startu [clock format $start -format %u] + # add 0 - 100 weekdays + for {set j 0} {$j < 100} {incr j} { + set forth [clock add $start $j weekdays] + set back [clock add $forth -$j weekdays] + # If $s was a weekday or $j was 0, $b must be the same day. + # Otherwise, $b must be the immediately preceeding Friday + set fail 0 + if {$j == 0 || $startu < 6} { + if {$start != $back} { set fail 1} + } else { + set friday [clock add $start -[expr {$startu % 5}] days] + if {$friday != $back} { set fail 1 } + } + if {$fail} { + set sdate [clock format $start -format {%Y-%m-%d}] + set bdate [clock format $back -format {%Y-%m-%d}] + return "$sdate + $j - $j := $bdate" + } + } + } + return "OK" +} -result {OK} + +# END testcases30 + test clock-31.1 {system locale} \ -constraints win \ - -setup { + -setup { namespace eval ::tcl::clock { namespace import -force ::testClock::registry } @@ -35395,7 +35450,7 @@ test clock-31.1 {system locale} \ test clock-31.2 {system locale} \ -constraints win \ - -setup { + -setup { namespace eval ::tcl::clock { namespace import -force ::testClock::registry } @@ -35418,7 +35473,7 @@ test clock-31.2 {system locale} \ test clock-31.3 {system locale} \ -constraints win \ - -setup { + -setup { namespace eval ::tcl::clock { namespace import -force ::testClock::registry } @@ -35441,7 +35496,7 @@ test clock-31.3 {system locale} \ test clock-31.4 {system locale} \ -constraints win \ - -setup { + -setup { namespace eval ::tcl::clock { namespace import -force ::testClock::registry } @@ -35478,7 +35533,7 @@ test clock-31.4 {system locale} \ test clock-31.5 {system locale} \ -constraints win \ - -setup { + -setup { namespace eval ::tcl::clock { namespace import -force ::testClock::registry } @@ -35515,7 +35570,7 @@ test clock-31.5 {system locale} \ test clock-31.6 {system locale} \ -constraints win \ - -setup { + -setup { namespace eval ::tcl::clock { namespace import -force ::testClock::registry } @@ -35585,7 +35640,7 @@ test clock-32.1 {scan/format across the Gregorian change} { } set problems } {} - + # Legacy tests # clock clicks @@ -35619,7 +35674,7 @@ test clock-33.5 {clock clicks tests, millisecond timing test} { # 60 msecs seems to be the max time slice under Windows 95/98 expr { ($end > $start) && (($end - $start) <= 60) ? - "ok" : + "ok" : "test should have taken 0-60 ms, actually took [expr $end - $start]"} } {ok} test clock-33.5a {clock tests, millisecond timing test} { @@ -35631,7 +35686,7 @@ test clock-33.5a {clock tests, millisecond timing test} { # 60 msecs seems to be the max time slice under Windows 95/98 expr { ($end > $start) && (($end - $start) <= 60) ? - "ok" : + "ok" : "test should have taken 0-60 ms, actually took [expr $end - $start]"} } {ok} test clock-33.6 {clock clicks, milli with too much abbreviation} { @@ -35984,31 +36039,31 @@ test clock-34.47 {ago with multiple relative units} { } 180000 test clock-34.48 {more than one ToD} {*}{ - -body {clock scan {10:00 11:00}} + -body {clock scan {10:00 11:00}} -returnCodes error -result {unable to convert date-time string "10:00 11:00": more than one time of day in string} } test clock-34.49 {more than one date} {*}{ - -body {clock scan {1/1/2001 2/2/2002}} + -body {clock scan {1/1/2001 2/2/2002}} -returnCodes error -result {unable to convert date-time string "1/1/2001 2/2/2002": more than one date in string} } test clock-34.50 {more than one time zone} {*}{ - -body {clock scan {10:00 EST CST}} + -body {clock scan {10:00 EST CST}} -returnCodes error -result {unable to convert date-time string "10:00 EST CST": more than one time zone in string} } test clock-34.51 {more than one weekday} {*}{ - -body {clock scan {Monday Tuesday}} + -body {clock scan {Monday Tuesday}} -returnCodes error -result {unable to convert date-time string "Monday Tuesday": more than one weekday in string} } test clock-34.52 {more than one ordinal month} {*}{ - -body {clock scan {next January next March}} + -body {clock scan {next January next March}} -returnCodes error -result {unable to convert date-time string "next January next March": more than one ordinal month in string} } @@ -36202,7 +36257,7 @@ test clock-38.2 {make sure TZ is not cached after unset} \ } } \ -result 1 - + test clock-39.1 {regression - synonym timezones} { clock format 0 -format {%H:%M:%S} -timezone :US/Eastern @@ -36274,7 +36329,7 @@ test clock-44.1 {regression test - time zone name containing hyphen } \ } } \ -result {12:34:56-0500} - + test clock-45.1 {regression test - time zone containing only two digits} \ -body { clock scan 1985-04-12T10:15:30+04 -format %Y-%m-%dT%H:%M:%S%Z @@ -36319,7 +36374,7 @@ test clock-48.1 {Bug 1185933: 'i' destroyed by clock init} -setup { test clock-49.1 {regression test - localtime with negative arg (Bug 1237907)} \ -body { - list [catch { + list [catch { clock format -86400 -timezone :localtime -format %Y } result] $result } \ @@ -36558,7 +36613,7 @@ test clock-56.1 {use of zoneinfo, version 1} {*}{ } -result {2004-01-01 00:00:00 MST} } - + test clock-56.2 {use of zoneinfo, version 2} {*}{ -setup { clock format [clock seconds] @@ -36608,7 +36663,7 @@ test clock-56.2 {use of zoneinfo, version 2} {*}{ removeFile PhoenixTwo $tzdir2 removeDirectory Test $tzdir removeDirectory zoneinfo - } + } -body { clock format 1072940400 -timezone :Test/PhoenixTwo \ -format {%Y-%m-%d %H:%M:%S %Z} @@ -36818,7 +36873,7 @@ test clock-56.3 {use of zoneinfo, version 2, Y2038 compliance} {*}{ removeFile TijuanaTwo $tzdir2 removeDirectory Test $tzdir removeDirectory zoneinfo - } + } -body { clock format 2224738800 -timezone :Test/TijuanaTwo \ -format {%Y-%m-%d %H:%M:%S %Z} @@ -36970,7 +37025,7 @@ test clock-56.4 {Bug 3470928} {*}{ removeFile Windhoek $tzdir2 removeDirectory Test $tzdir removeDirectory zoneinfo - } + } -result {Sun Jan 08 22:30:06 WAST 2012} } @@ -36981,7 +37036,7 @@ test clock-57.1 {clock scan - abbreviated options} { test clock-58.1 {clock l10n - Japanese localisation} {*}{ -setup { proc backslashify { string } { - + set retval {} foreach char [split $string {}] { scan $char %c ccode @@ -37087,52 +37142,52 @@ test clock-59.1 {military time zones} { test clock-60.1 {case insensitive weekday names} { clock scan "2000-W01 monday" -gmt true -format "%G-W%V %a" -} [clock scan "2000-W01-1" -gmt true -format "%G-W%V-%u"] +} [clock scan "2000-W01-1" -gmt true -format "%G-W%V-%u"] test clock-60.2 {case insensitive weekday names} { clock scan "2000-W01 Monday" -gmt true -format "%G-W%V %a" -} [clock scan "2000-W01-1" -gmt true -format "%G-W%V-%u"] +} [clock scan "2000-W01-1" -gmt true -format "%G-W%V-%u"] test clock-60.3 {case insensitive weekday names} { clock scan "2000-W01 MONDAY" -gmt true -format "%G-W%V %a" -} [clock scan "2000-W01-1" -gmt true -format "%G-W%V-%u"] +} [clock scan "2000-W01-1" -gmt true -format "%G-W%V-%u"] test clock-60.4 {case insensitive weekday names} { clock scan "2000-W01 friday" -gmt true -format "%G-W%V %a" -} [clock scan "2000-W01-5" -gmt true -format "%G-W%V-%u"] +} [clock scan "2000-W01-5" -gmt true -format "%G-W%V-%u"] test clock-60.5 {case insensitive weekday names} { clock scan "2000-W01 Friday" -gmt true -format "%G-W%V %a" -} [clock scan "2000-W01-5" -gmt true -format "%G-W%V-%u"] +} [clock scan "2000-W01-5" -gmt true -format "%G-W%V-%u"] test clock-60.6 {case insensitive weekday names} { clock scan "2000-W01 FRIDAY" -gmt true -format "%G-W%V %a" -} [clock scan "2000-W01-5" -gmt true -format "%G-W%V-%u"] +} [clock scan "2000-W01-5" -gmt true -format "%G-W%V-%u"] test clock-60.7 {case insensitive month names} { clock scan "1 january 2000" -gmt true -format "%d %b %Y" -} [clock scan "2000-01-01" -gmt true -format "%Y-%m-%d"] +} [clock scan "2000-01-01" -gmt true -format "%Y-%m-%d"] test clock-60.8 {case insensitive month names} { clock scan "1 January 2000" -gmt true -format "%d %b %Y" -} [clock scan "2000-01-01" -gmt true -format "%Y-%m-%d"] +} [clock scan "2000-01-01" -gmt true -format "%Y-%m-%d"] test clock-60.9 {case insensitive month names} { clock scan "1 JANUARY 2000" -gmt true -format "%d %b %Y" -} [clock scan "2000-01-01" -gmt true -format "%Y-%m-%d"] +} [clock scan "2000-01-01" -gmt true -format "%Y-%m-%d"] test clock-60.10 {case insensitive month names} { clock scan "1 december 2000" -gmt true -format "%d %b %Y" -} [clock scan "2000-12-01" -gmt true -format "%Y-%m-%d"] +} [clock scan "2000-12-01" -gmt true -format "%Y-%m-%d"] test clock-60.11 {case insensitive month names} { clock scan "1 December 2000" -gmt true -format "%d %b %Y" -} [clock scan "2000-12-01" -gmt true -format "%Y-%m-%d"] +} [clock scan "2000-12-01" -gmt true -format "%Y-%m-%d"] test clock-60.12 {case insensitive month names} { clock scan "1 DECEMBER 2000" -gmt true -format "%d %b %Y" -} [clock scan "2000-12-01" -gmt true -format "%Y-%m-%d"] +} [clock scan "2000-12-01" -gmt true -format "%Y-%m-%d"] test clock-61.1 {overflow of a wide integer on output} {*}{ -body { clock format 0x8000000000000000 -format %s -gmt true - } + } -result {integer value too large to represent} -returnCodes error } test clock-61.2 {overflow of a wide integer on output} {*}{ -body { clock format -0x8000000000000001 -format %s -gmt true - } + } -result {integer value too large to represent} -returnCodes error } -- cgit v0.12 From d9b0bec7d68dc00ac744a5a0e3d0ba5d7d8404f1 Mon Sep 17 00:00:00 2001 From: sebres Date: Wed, 10 May 2017 12:29:49 +0000 Subject: resolving differences between 8.6 and trunk --- generic/tclDictObj.c | 18 ++++++++---------- 1 file changed, 8 insertions(+), 10 deletions(-) diff --git a/generic/tclDictObj.c b/generic/tclDictObj.c index 4088883..593f5a3 100644 --- a/generic/tclDictObj.c +++ b/generic/tclDictObj.c @@ -145,7 +145,7 @@ typedef struct Dict { * the entries in the order that they are * created. */ int epoch; /* Epoch counter */ - int refcount; /* Reference counter (see above) */ + size_t refCount; /* Reference counter (see above) */ Tcl_Obj *chain; /* Linked list used for invalidating the * string representations of updated nested * dictionaries. */ @@ -395,7 +395,7 @@ DupDictInternalRep( newDict->epoch = 0; newDict->chain = NULL; - newDict->refcount = 1; + newDict->refCount = 1; /* * Store in the object. @@ -430,8 +430,7 @@ FreeDictInternalRep( { Dict *dict = DICT(dictPtr); - dict->refcount--; - if (dict->refcount <= 0) { + if (dict->refCount-- <= 1) { DeleteDict(dict); } dictPtr->typePtr = NULL; @@ -716,7 +715,7 @@ SetDictFromAny( TclFreeIntRep(objPtr); dict->epoch = 0; dict->chain = NULL; - dict->refcount = 1; + dict->refCount = 1; DICT(objPtr) = dict; objPtr->internalRep.twoPtrValue.ptr2 = NULL; objPtr->typePtr = &tclDictType; @@ -1120,7 +1119,7 @@ Tcl_DictObjFirst( searchPtr->dictionaryPtr = (Tcl_Dict) dict; searchPtr->epoch = dict->epoch; searchPtr->next = cPtr->nextPtr; - dict->refcount++; + dict->refCount++; if (keyPtrPtr != NULL) { *keyPtrPtr = Tcl_GetHashKey(&dict->table, &cPtr->entry); } @@ -1234,8 +1233,7 @@ Tcl_DictObjDone( if (searchPtr->epoch != -1) { searchPtr->epoch = -1; dict = (Dict *) searchPtr->dictionaryPtr; - dict->refcount--; - if (dict->refcount <= 0) { + if (dict->refCount-- <= 1) { DeleteDict(dict); } } @@ -1387,7 +1385,7 @@ Tcl_NewDictObj(void) InitChainTable(dict); dict->epoch = 0; dict->chain = NULL; - dict->refcount = 1; + dict->refCount = 1; DICT(dictPtr) = dict; dictPtr->internalRep.twoPtrValue.ptr2 = NULL; dictPtr->typePtr = &tclDictType; @@ -1437,7 +1435,7 @@ Tcl_DbNewDictObj( InitChainTable(dict); dict->epoch = 0; dict->chain = NULL; - dict->refcount = 1; + dict->refCount = 1; DICT(dictPtr) = dict; dictPtr->internalRep.twoPtrValue.ptr2 = NULL; dictPtr->typePtr = &tclDictType; -- cgit v0.12 From 3fe213e03172327d71bc8a7b2d174b5887434738 Mon Sep 17 00:00:00 2001 From: sebres Date: Wed, 10 May 2017 12:29:54 +0000 Subject: Ensemble "clock" fixed after merge with kbk's clock ensemble solution. All commands (including new) compiled now also in ensemble (implemented without TclMakeEnsemble, because it can be extended via new map entries). Ensemble handling partially cherry-picked from new performance branch (TODO: check temporary "-compile" option can be reverted if it becomes ready/merged). --- generic/tclClock.c | 66 +++++++++++++++++++++++++-------------------------- generic/tclEnsemble.c | 20 +++++++++++++--- library/init.tcl | 15 ++++++++---- 3 files changed, 61 insertions(+), 40 deletions(-) diff --git a/generic/tclClock.c b/generic/tclClock.c index 8e176b6..ad3d6e7 100644 --- a/generic/tclClock.c +++ b/generic/tclClock.c @@ -17,6 +17,7 @@ #include "tclInt.h" #include "tclStrIdxTree.h" #include "tclDate.h" +#include "tclCompile.h" /* * Windows has mktime. The configurators do not check. @@ -152,21 +153,29 @@ struct ClockCommand { Tcl_ObjCmdProc *objCmdProc; /* Function that implements the command. This * will always have the ClockClientData sent * to it, but may well ignore this data. */ + CompileProc *compileProc; /* The compiler for the command. */ + ClientData clientData; /* Any clientData to give the command (if NULL + * a reference to ClockClientData will be sent) */ }; static const struct ClockCommand clockCommands[] = { - { "getenv", ClockGetenvObjCmd }, - { "format", ClockFormatObjCmd }, - { "scan", ClockScanObjCmd }, - { "configure", ClockConfigureObjCmd }, - { "Oldscan", TclClockOldscanObjCmd }, - { "ConvertLocalToUTC", ClockConvertlocaltoutcObjCmd }, - { "GetDateFields", ClockGetdatefieldsObjCmd }, - { "GetJulianDayFromEraYearMonthDay", - ClockGetjuliandayfromerayearmonthdayObjCmd }, - { "GetJulianDayFromEraYearWeekDay", - ClockGetjuliandayfromerayearweekdayObjCmd }, - { NULL, NULL } + {"add", ClockAddObjCmd, TclCompileBasicMin1ArgCmd, NULL}, + {"clicks", ClockClicksObjCmd, TclCompileClockClicksCmd, NULL}, + {"format", ClockFormatObjCmd, TclCompileBasicMin1ArgCmd, NULL}, + {"getenv", ClockGetenvObjCmd, TclCompileBasicMin1ArgCmd, NULL}, + {"microseconds", ClockMicrosecondsObjCmd,TclCompileClockReadingCmd, INT2PTR(1)}, + {"milliseconds", ClockMillisecondsObjCmd,TclCompileClockReadingCmd, INT2PTR(2)}, + {"scan", ClockScanObjCmd, TclCompileBasicMin1ArgCmd, NULL}, + {"seconds", ClockSecondsObjCmd, TclCompileClockReadingCmd, INT2PTR(3)}, + {"configure", ClockConfigureObjCmd, NULL, NULL}, + {"Oldscan", TclClockOldscanObjCmd, NULL, NULL}, + {"ConvertLocalToUTC", ClockConvertlocaltoutcObjCmd, NULL, NULL}, + {"GetDateFields", ClockGetdatefieldsObjCmd, NULL, NULL}, + {"GetJulianDayFromEraYearMonthDay", + ClockGetjuliandayfromerayearmonthdayObjCmd, NULL, NULL}, + {"GetJulianDayFromEraYearWeekDay", + ClockGetjuliandayfromerayearweekdayObjCmd, NULL, NULL}, + {NULL, NULL, NULL, NULL} }; /* @@ -195,22 +204,10 @@ TclClockInit( char cmdName[50]; /* Buffer large enough to hold the string *::tcl::clock::GetJulianDayFromEraYearMonthDay * plus a terminating NUL. */ + Command *cmdPtr; ClockClientData *data; int i; - /* Structure of the 'clock' ensemble */ - - static const EnsembleImplMap clockImplMap[] = { - {"add", NULL, TclCompileBasicMin1ArgCmd, NULL, NULL, 0}, - {"clicks", ClockClicksObjCmd, TclCompileClockClicksCmd, NULL, NULL, 0}, - {"format", NULL, TclCompileBasicMin1ArgCmd, NULL, NULL, 0}, - {"microseconds", ClockMicrosecondsObjCmd, TclCompileClockReadingCmd, NULL, INT2PTR(1), 0}, - {"milliseconds", ClockMillisecondsObjCmd, TclCompileClockReadingCmd, NULL, INT2PTR(2), 0}, - {"scan", NULL, TclCompileBasicMin1ArgCmd, NULL, NULL , 0}, - {"seconds", ClockSecondsObjCmd, TclCompileClockReadingCmd, NULL, INT2PTR(3), 0}, - {NULL, NULL, NULL, NULL, NULL, 0} - }; - /* * Safe interps get [::clock] as alias to a master, so do not need their * own copies of the support routines. @@ -258,21 +255,24 @@ TclClockInit( /* * Install the commands. - * TODO - Let Tcl_MakeEnsemble do this? */ #define TCL_CLOCK_PREFIX_LEN 14 /* == strlen("::tcl::clock::") */ memcpy(cmdName, "::tcl::clock::", TCL_CLOCK_PREFIX_LEN); for (clockCmdPtr=clockCommands ; clockCmdPtr->name!=NULL ; clockCmdPtr++) { + ClientData clientData; + strcpy(cmdName + TCL_CLOCK_PREFIX_LEN, clockCmdPtr->name); - data->refCount++; - Tcl_CreateObjCommand(interp, cmdName, clockCmdPtr->objCmdProc, data, - ClockDeleteCmdProc); + if (!(clientData = clockCmdPtr->clientData)) { + clientData = data; + data->refCount++; + } + cmdPtr = (Command *)Tcl_CreateObjCommand(interp, cmdName, + clockCmdPtr->objCmdProc, clientData, + clockCmdPtr->clientData ? NULL : ClockDeleteCmdProc); + cmdPtr->compileProc = clockCmdPtr->compileProc ? + clockCmdPtr->compileProc : TclCompileBasicMin0ArgCmd; } - - /* Make the clock ensemble */ - - TclMakeEnsemble(interp, "clock", clockImplMap); } /* diff --git a/generic/tclEnsemble.c b/generic/tclEnsemble.c index c1b0890..2480685 100644 --- a/generic/tclEnsemble.c +++ b/generic/tclEnsemble.c @@ -55,11 +55,12 @@ enum EnsSubcmds { }; static const char *const ensembleCreateOptions[] = { - "-command", "-map", "-parameters", "-prefixes", "-subcommands", - "-unknown", NULL + "-command", "-compile", "-map", "-parameters", "-prefixes", + "-subcommands", "-unknown", NULL }; enum EnsCreateOpts { - CRT_CMD, CRT_MAP, CRT_PARAM, CRT_PREFIX, CRT_SUBCMDS, CRT_UNKNOWN + CRT_CMD, CRT_COMPILE, CRT_MAP, CRT_PARAM, CRT_PREFIX, + CRT_SUBCMDS, CRT_UNKNOWN }; static const char *const ensembleConfigOptions[] = { @@ -183,6 +184,7 @@ TclNamespaceEnsembleCmd( int permitPrefix = 1; Tcl_Obj *unknownObj = NULL; Tcl_Obj *paramObj = NULL; + int ensCompFlag = -1; /* * Check that we've got option-value pairs... [Bug 1558654] @@ -325,6 +327,12 @@ TclNamespaceEnsembleCmd( return TCL_ERROR; } continue; + case CRT_COMPILE: + if (Tcl_GetBooleanFromObj(interp, objv[1], + &ensCompFlag) != TCL_OK) { + return TCL_ERROR; + }; + continue; case CRT_UNKNOWN: if (TclListObjLength(interp, objv[1], &len) != TCL_OK) { if (allocatedMapFlag) { @@ -350,6 +358,12 @@ TclNamespaceEnsembleCmd( Tcl_SetEnsembleMappingDict(interp, token, mapObj); Tcl_SetEnsembleUnknownHandler(interp, token, unknownObj); Tcl_SetEnsembleParameterList(interp, token, paramObj); + /* + * Ensemble should be compiled if it has map (performance purposes) + */ + if (ensCompFlag > 0 && mapObj != NULL) { + Tcl_SetEnsembleFlags(interp, token, ENSEMBLE_COMPILE); + } /* * Tricky! Must ensure that the result is not shared (command delete diff --git a/library/init.tcl b/library/init.tcl index 87e84e4..824f66f 100644 --- a/library/init.tcl +++ b/library/init.tcl @@ -45,6 +45,7 @@ if {![info exists auto_path]} { set auto_path "" } } + namespace eval tcl { variable Dir foreach Dir [list $::tcl_library [file dirname $::tcl_library]] { @@ -169,9 +170,16 @@ if {[interp issafe]} { namespace eval ::tcl::clock [list variable TclLibDir $::tcl_library] - proc ::tcl::initClock {} { - # Auto-loading stubs for 'clock.tcl' + proc clock args { + set cmdmap [dict create] + foreach cmd {add clicks format microseconds milliseconds scan seconds configure} { + dict set cmdmap $cmd ::tcl::clock::$cmd + } + namespace eval ::tcl::clock [list namespace ensemble create -command \ + [uplevel 1 [list namespace origin [lindex [info level 0] 0]]] \ + -map $cmdmap -compile 1] + # Auto-loading stubs for 'clock.tcl' foreach cmd {mcget LocalizeFormat SetupTimeZone GetSystemTimeZone} { proc ::tcl::clock::$cmd args { variable TclLibDir @@ -180,9 +188,8 @@ if {[interp issafe]} { } } - rename ::tcl::initClock {} + return [uplevel 1 [info level 0]] } - ::tcl::initClock } # Conditionalize for presence of exec. -- cgit v0.12 From ba8e7c4211e910d243158064e8e7dcd85620fce7 Mon Sep 17 00:00:00 2001 From: sebres Date: Wed, 10 May 2017 12:29:59 +0000 Subject: Fixed wrong args message (e.g. "clock format ..." instead of "::tcl::clock::format") if failed through compiled ensemble execution. --- generic/tclClock.c | 14 +++++++------- tests/clock.test | 4 ++++ 2 files changed, 11 insertions(+), 7 deletions(-) diff --git a/generic/tclClock.c b/generic/tclClock.c index ad3d6e7..a066f73 100644 --- a/generic/tclClock.c +++ b/generic/tclClock.c @@ -2865,7 +2865,7 @@ ClockClicksObjCmd( } break; default: - Tcl_WrongNumArgs(interp, 1, objv, "?-switch?"); + Tcl_WrongNumArgs(interp, 0, NULL, "clock clicks ?-switch?"); return TCL_ERROR; } @@ -2918,7 +2918,7 @@ ClockMillisecondsObjCmd( Tcl_Time now; if (objc != 1) { - Tcl_WrongNumArgs(interp, 1, objv, NULL); + Tcl_WrongNumArgs(interp, 0, NULL, "clock milliseconds"); return TCL_ERROR; } Tcl_GetTime(&now); @@ -2953,7 +2953,7 @@ ClockMicrosecondsObjCmd( Tcl_Obj *const *objv) /* Parameter values */ { if (objc != 1) { - Tcl_WrongNumArgs(interp, 1, objv, NULL); + Tcl_WrongNumArgs(interp, 0, NULL, "clock microseconds"); return TCL_ERROR; } Tcl_SetObjResult(interp, Tcl_NewWideIntObj(TclpGetMicroseconds())); @@ -3223,7 +3223,7 @@ ClockFormatObjCmd( /* even number of arguments */ if ((objc & 1) == 1) { - Tcl_WrongNumArgs(interp, 1, objv, "clockval|-now " + Tcl_WrongNumArgs(interp, 0, NULL, "clock format clockval|-now " "?-format string? " "?-gmt boolean? " "?-locale LOCALE? ?-timezone ZONE?"); @@ -3298,7 +3298,7 @@ ClockScanObjCmd( /* even number of arguments */ if ((objc & 1) == 1) { - Tcl_WrongNumArgs(interp, 1, objv, "string " + Tcl_WrongNumArgs(interp, 0, NULL, "clock scan string " "?-base seconds? " "?-format string? " "?-gmt boolean? " @@ -3857,7 +3857,7 @@ ClockAddObjCmd( /* even number of arguments */ if ((objc & 1) == 1) { - Tcl_WrongNumArgs(interp, 1, objv, "clockval|-now ?number units?..." + Tcl_WrongNumArgs(interp, 0, NULL, "clock add clockval|-now ?number units?..." "?-gmt boolean? " "?-locale LOCALE? ?-timezone ZONE?"); Tcl_SetErrorCode(interp, "CLOCK", "wrongNumArgs", NULL); @@ -4014,7 +4014,7 @@ ClockSecondsObjCmd( Tcl_Time now; if (objc != 1) { - Tcl_WrongNumArgs(interp, 1, objv, NULL); + Tcl_WrongNumArgs(interp, 0, NULL, "clock seconds"); return TCL_ERROR; } Tcl_GetTime(&now); diff --git a/tests/clock.test b/tests/clock.test index 9e86c97..214d4cb 100644 --- a/tests/clock.test +++ b/tests/clock.test @@ -257,6 +257,10 @@ test clock-1.0 "clock format - wrong # args" { list [catch {clock format} msg] $msg $::errorCode } {1 {wrong # args: should be "clock format clockval|-now ?-format string? ?-gmt boolean? ?-locale LOCALE? ?-timezone ZONE?"} {CLOCK wrongNumArgs}} +test clock-1.0.1 "clock format - wrong # args (compiled ensemble with invalid syntax)" { + list [catch {clock format 0 -too-few-options-4-test} msg] $msg $::errorCode +} {1 {wrong # args: should be "clock format clockval|-now ?-format string? ?-gmt boolean? ?-locale LOCALE? ?-timezone ZONE?"} {CLOCK wrongNumArgs}} + test clock-1.1 "clock format - bad time" { list [catch {clock format foo} msg] $msg } {1 {expected integer but got "foo"}} -- cgit v0.12 From 19b2d40089ec87c4f53419baea8e46524011eb54 Mon Sep 17 00:00:00 2001 From: sebres Date: Wed, 10 May 2017 12:30:04 +0000 Subject: Fixed possible wrong current date for CET / CEST test cases. --- tests/clock.test | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/tests/clock.test b/tests/clock.test index 214d4cb..0737558 100644 --- a/tests/clock.test +++ b/tests/clock.test @@ -36191,7 +36191,7 @@ test clock-36.3 {clock scan next monthname} { } "05.2001" test clock-37.1 {%s gmt testing} { - set s [clock seconds] + set s [clock scan "2017-05-10 09:00:00" -gmt 1] set a [clock format $s -format %s -gmt 0] set b [clock format $s -format %s -gmt 1] set c [clock scan $s -format %s -gmt 0] @@ -36200,8 +36200,8 @@ test clock-37.1 {%s gmt testing} { # depend on the time zone. list [expr {$b-$a}] [expr {$d-$c}] } {0 0} -test clock-37.2 {%Es gmt testing} { - set s [clock seconds] +test clock-37.2 {%Es gmt testing CET} { + set s [clock scan "2017-01-10 09:00:00" -gmt 1] set a [clock format $s -format %Es -timezone CET] set b [clock format $s -format %Es -gmt 1] set c [clock scan $s -format %Es -timezone CET] @@ -36209,6 +36209,15 @@ test clock-37.2 {%Es gmt testing} { # %Es depend on the time zone (local seconds instead of posix seconds). list [expr {$b-$a}] [expr {$d-$c}] } {-3600 3600} +test clock-37.3 {%Es gmt testing CEST} { + set s [clock scan "2017-05-10 09:00:00" -gmt 1] + set a [clock format $s -format %Es -timezone CET] + set b [clock format $s -format %Es -gmt 1] + set c [clock scan $s -format %Es -timezone CET] + set d [clock scan $s -format %Es -gmt 1] + # %Es depend on the time zone (local seconds instead of posix seconds). + list [expr {$b-$a}] [expr {$d-$c}] +} {-7200 7200} test clock-38.1 {regression - convertUTCToLocalViaC - east of Greenwich} \ -setup { -- cgit v0.12 From 2eaa3d3c8d7ede2057e65ea1e7edaaa2214f51c2 Mon Sep 17 00:00:00 2001 From: sebres Date: Wed, 10 May 2017 13:02:17 +0000 Subject: Added files missing after merge/back-port (rebase with merge point) --- generic/tclClockFmt.c | 3135 +++++++++++++++++++++++++++++++++++++++++++++ generic/tclDate.h | 512 ++++++++ generic/tclStrIdxTree.c | 520 ++++++++ generic/tclStrIdxTree.h | 169 +++ tests-perf/clock.perf.tcl | 385 ++++++ 5 files changed, 4721 insertions(+) create mode 100644 generic/tclClockFmt.c create mode 100644 generic/tclDate.h create mode 100644 generic/tclStrIdxTree.c create mode 100644 generic/tclStrIdxTree.h create mode 100644 tests-perf/clock.perf.tcl diff --git a/generic/tclClockFmt.c b/generic/tclClockFmt.c new file mode 100644 index 0000000..d875bd4 --- /dev/null +++ b/generic/tclClockFmt.c @@ -0,0 +1,3135 @@ +/* + * tclClockFmt.c -- + * + * Contains the date format (and scan) routines. This code is back-ported + * from the time and date facilities of tclSE engine, by Serg G. Brester. + * + * Copyright (c) 2015 by Sergey G. Brester aka sebres. All rights reserved. + * + * See the file "license.terms" for information on usage and redistribution of + * this file, and for a DISCLAIMER OF ALL WARRANTIES. + */ + +#include "tclInt.h" +#include "tclStrIdxTree.h" +#include "tclDate.h" + +/* + * Miscellaneous forward declarations and functions used within this file + */ + +static void +ClockFmtObj_DupInternalRep(Tcl_Obj *srcPtr, Tcl_Obj *copyPtr); +static void +ClockFmtObj_FreeInternalRep(Tcl_Obj *objPtr); +static int +ClockFmtObj_SetFromAny(Tcl_Interp *interp, Tcl_Obj *objPtr); +static void +ClockFmtObj_UpdateString(Tcl_Obj *objPtr); + + +TCL_DECLARE_MUTEX(ClockFmtMutex); /* Serializes access to common format list. */ + +static void ClockFmtScnStorageDelete(ClockFmtScnStorage *fss); + +static void ClockFrmScnFinalize(ClientData clientData); + +/* Msgcat index literals prefixed with _IDX_, used for quick dictionary search */ +CLOCK_LOCALE_LITERAL_ARRAY(MsgCtLitIdxs, "_IDX_"); + +/* + * Clock scan and format facilities. + */ + +/* + *---------------------------------------------------------------------- + * + * _str2int -- , _str2wideInt -- + * + * Fast inline-convertion of string to signed int or wide int by given + * start/end. + * + * The given string should contain numbers chars only (because already + * pre-validated within parsing routines) + * + * Results: + * Returns a standard Tcl result. + * TCL_OK - by successful conversion, TCL_ERROR by (wide) int overflow + * + *---------------------------------------------------------------------- + */ + +static inline int +_str2int( + int *out, + register + const char *p, + const char *e, + int sign) +{ + register int val = 0, prev = 0; + if (sign >= 0) { + while (p < e) { + val = val * 10 + (*p++ - '0'); + if (val < prev) { + return TCL_ERROR; + } + prev = val; + } + } else { + while (p < e) { + val = val * 10 - (*p++ - '0'); + if (val > prev) { + return TCL_ERROR; + } + prev = val; + } + } + *out = val; + return TCL_OK; +} + +static inline int +_str2wideInt( + Tcl_WideInt *out, + register + const char *p, + const char *e, + int sign) +{ + register Tcl_WideInt val = 0, prev = 0; + if (sign >= 0) { + while (p < e) { + val = val * 10 + (*p++ - '0'); + if (val < prev) { + return TCL_ERROR; + } + prev = val; + } + } else { + while (p < e) { + val = val * 10 - (*p++ - '0'); + if (val > prev) { + return TCL_ERROR; + } + prev = val; + } + } + *out = val; + return TCL_OK; +} + +/* + *---------------------------------------------------------------------- + * + * _itoaw -- , _witoaw -- + * + * Fast inline-convertion of signed int or wide int to string, using + * given padding with specified padchar and width (or without padding). + * + * This is a very fast replacement for sprintf("%02d"). + * + * Results: + * Returns position in buffer after end of conversion result. + * + *---------------------------------------------------------------------- + */ + +static inline char * +_itoaw( + char *buf, + register int val, + char padchar, + unsigned short int width) +{ + register char *p; + static int wrange[] = {1, 10, 100, 1000, 10000, 100000, 1000000, 10000000, 100000000, 1000000000}; + + /* positive integer */ + + if (val >= 0) + { + /* check resp. recalculate width */ + while (width <= 9 && val >= wrange[width]) { + width++; + } + /* number to string backwards */ + p = buf + width; + *p-- = '\0'; + do { + register char c = (val % 10); val /= 10; + *p-- = '0' + c; + } while (val > 0); + /* fulling with pad-char */ + while (p >= buf) { + *p-- = padchar; + } + + return buf + width; + } + /* negative integer */ + + if (!width) width++; + /* check resp. recalculate width (regarding sign) */ + width--; + while (width <= 9 && val <= -wrange[width]) { + width++; + } + width++; + /* number to string backwards */ + p = buf + width; + *p-- = '\0'; + /* differentiate platforms with -1 % 10 == 1 and -1 % 10 == -1 */ + if (-1 % 10 == -1) { + do { + register char c = (val % 10); val /= 10; + *p-- = '0' - c; + } while (val < 0); + } else { + do { + register char c = (val % 10); val /= 10; + *p-- = '0' + c; + } while (val < 0); + } + /* sign by 0 padding */ + if (padchar != '0') { *p-- = '-'; } + /* fulling with pad-char */ + while (p >= buf + 1) { + *p-- = padchar; + } + /* sign by non 0 padding */ + if (padchar == '0') { *p = '-'; } + + return buf + width; +} + +static inline char * +_witoaw( + char *buf, + register Tcl_WideInt val, + char padchar, + unsigned short int width) +{ + register char *p; + static int wrange[] = {1, 10, 100, 1000, 10000, 100000, 1000000, 10000000, 100000000, 1000000000}; + + /* positive integer */ + + if (val >= 0) + { + /* check resp. recalculate width */ + if (val >= 10000000000L) { + Tcl_WideInt val2; + val2 = val / 10000000000L; + while (width <= 9 && val2 >= wrange[width]) { + width++; + } + width += 10; + } else { + while (width <= 9 && val >= wrange[width]) { + width++; + } + } + /* number to string backwards */ + p = buf + width; + *p-- = '\0'; + do { + register char c = (val % 10); val /= 10; + *p-- = '0' + c; + } while (val > 0); + /* fulling with pad-char */ + while (p >= buf) { + *p-- = padchar; + } + + return buf + width; + } + + /* negative integer */ + + if (!width) width++; + /* check resp. recalculate width (regarding sign) */ + width--; + if (val <= 10000000000L) { + Tcl_WideInt val2; + val2 = val / 10000000000L; + while (width <= 9 && val2 <= -wrange[width]) { + width++; + } + width += 10; + } else { + while (width <= 9 && val <= -wrange[width]) { + width++; + } + } + width++; + /* number to string backwards */ + p = buf + width; + *p-- = '\0'; + /* differentiate platforms with -1 % 10 == 1 and -1 % 10 == -1 */ + if (-1 % 10 == -1) { + do { + register char c = (val % 10); val /= 10; + *p-- = '0' - c; + } while (val < 0); + } else { + do { + register char c = (val % 10); val /= 10; + *p-- = '0' + c; + } while (val < 0); + } + /* sign by 0 padding */ + if (padchar != '0') { *p-- = '-'; } + /* fulling with pad-char */ + while (p >= buf + 1) { + *p-- = padchar; + } + /* sign by non 0 padding */ + if (padchar == '0') { *p = '-'; } + + return buf + width; +} + +/* + * Global GC as LIFO for released scan/format object storages. + * + * Used to holds last released CLOCK_FMT_SCN_STORAGE_GC_SIZE formats + * (after last reference from Tcl-object will be removed). This is helpful + * to avoid continuous (re)creation and compiling by some dynamically resp. + * variable format objects, that could be often reused. + * + * As long as format storage is used resp. belongs to GC, it takes place in + * FmtScnHashTable also. + */ + +#if CLOCK_FMT_SCN_STORAGE_GC_SIZE > 0 + +static struct { + ClockFmtScnStorage *stackPtr; + ClockFmtScnStorage *stackBound; + unsigned int count; +} ClockFmtScnStorage_GC = {NULL, NULL, 0}; + +/* + *---------------------------------------------------------------------- + * + * ClockFmtScnStorageGC_In -- + * + * Adds an format storage object to GC. + * + * If current GC is full (size larger as CLOCK_FMT_SCN_STORAGE_GC_SIZE) + * this removes last unused storage at begin of GC stack (LIFO). + * + * Assumes caller holds the ClockFmtMutex. + * + * Results: + * None. + * + *---------------------------------------------------------------------- + */ + +static inline void +ClockFmtScnStorageGC_In(ClockFmtScnStorage *entry) +{ + /* add new entry */ + TclSpliceIn(entry, ClockFmtScnStorage_GC.stackPtr); + if (ClockFmtScnStorage_GC.stackBound == NULL) { + ClockFmtScnStorage_GC.stackBound = entry; + } + ClockFmtScnStorage_GC.count++; + + /* if GC ist full */ + if (ClockFmtScnStorage_GC.count > CLOCK_FMT_SCN_STORAGE_GC_SIZE) { + + /* GC stack is LIFO: delete first inserted entry */ + ClockFmtScnStorage *delEnt = ClockFmtScnStorage_GC.stackBound; + ClockFmtScnStorage_GC.stackBound = delEnt->prevPtr; + TclSpliceOut(delEnt, ClockFmtScnStorage_GC.stackPtr); + ClockFmtScnStorage_GC.count--; + delEnt->prevPtr = delEnt->nextPtr = NULL; + /* remove it now */ + ClockFmtScnStorageDelete(delEnt); + } +} + +/* + *---------------------------------------------------------------------- + * + * ClockFmtScnStorage_GC_Out -- + * + * Restores (for reusing) given format storage object from GC. + * + * Assumes caller holds the ClockFmtMutex. + * + * Results: + * None. + * + *---------------------------------------------------------------------- + */ + +static inline void +ClockFmtScnStorage_GC_Out(ClockFmtScnStorage *entry) +{ + TclSpliceOut(entry, ClockFmtScnStorage_GC.stackPtr); + ClockFmtScnStorage_GC.count--; + if (ClockFmtScnStorage_GC.stackBound == entry) { + ClockFmtScnStorage_GC.stackBound = entry->prevPtr; + } + entry->prevPtr = entry->nextPtr = NULL; +} + +#endif + + +/* + * Global format storage hash table of type ClockFmtScnStorageHashKeyType + * (contains list of scan/format object storages, shared across all threads). + * + * Used for fast searching by format string. + */ +static Tcl_HashTable FmtScnHashTable; +static int initialized = 0; + +/* + * Wrappers between pointers to hash entry and format storage object + */ +static inline Tcl_HashEntry * +HashEntry4FmtScn(ClockFmtScnStorage *fss) { + return (Tcl_HashEntry*)(fss + 1); +}; +static inline ClockFmtScnStorage * +FmtScn4HashEntry(Tcl_HashEntry *hKeyPtr) { + return (ClockFmtScnStorage*)(((char*)hKeyPtr) - sizeof(ClockFmtScnStorage)); +}; + +/* + *---------------------------------------------------------------------- + * + * ClockFmtScnStorageAllocProc -- + * + * Allocate space for a hash entry containing format storage together + * with the string key. + * + * Results: + * The return value is a pointer to the created entry. + * + *---------------------------------------------------------------------- + */ + +static Tcl_HashEntry * +ClockFmtScnStorageAllocProc( + Tcl_HashTable *tablePtr, /* Hash table. */ + void *keyPtr) /* Key to store in the hash table entry. */ +{ + ClockFmtScnStorage *fss; + + const char *string = (const char *) keyPtr; + Tcl_HashEntry *hPtr; + unsigned int size, + allocsize = sizeof(ClockFmtScnStorage) + sizeof(Tcl_HashEntry); + + allocsize += (size = strlen(string) + 1); + if (size > sizeof(hPtr->key)) { + allocsize -= sizeof(hPtr->key); + } + + fss = ckalloc(allocsize); + + /* initialize */ + memset(fss, 0, sizeof(*fss)); + + hPtr = HashEntry4FmtScn(fss); + memcpy(&hPtr->key.string, string, size); + hPtr->clientData = 0; /* currently unused */ + + return hPtr; +} + +/* + *---------------------------------------------------------------------- + * + * ClockFmtScnStorageFreeProc -- + * + * Free format storage object and space of given hash entry. + * + * Results: + * None. + * + *---------------------------------------------------------------------- + */ + +static void +ClockFmtScnStorageFreeProc( + Tcl_HashEntry *hPtr) +{ + ClockFmtScnStorage *fss = FmtScn4HashEntry(hPtr); + + if (fss->scnTok != NULL) { + ckfree(fss->scnTok); + fss->scnTok = NULL; + fss->scnTokC = 0; + } + if (fss->fmtTok != NULL) { + ckfree(fss->fmtTok); + fss->fmtTok = NULL; + fss->fmtTokC = 0; + } + + ckfree(fss); +} + +/* + *---------------------------------------------------------------------- + * + * ClockFmtScnStorageDelete -- + * + * Delete format storage object. + * + * Results: + * None. + * + *---------------------------------------------------------------------- + */ + +static void +ClockFmtScnStorageDelete(ClockFmtScnStorage *fss) { + Tcl_HashEntry *hPtr = HashEntry4FmtScn(fss); + /* + * This will delete a hash entry and call "ckfree" for storage self, if + * some additionally handling required, freeEntryProc can be used instead + */ + Tcl_DeleteHashEntry(hPtr); +} + + +/* + * Derivation of tclStringHashKeyType with another allocEntryProc + */ + +static Tcl_HashKeyType ClockFmtScnStorageHashKeyType; + + +/* + * Type definition of clock-format tcl object type. + */ + +Tcl_ObjType ClockFmtObjType = { + "clock-format", /* name */ + ClockFmtObj_FreeInternalRep, /* freeIntRepProc */ + ClockFmtObj_DupInternalRep, /* dupIntRepProc */ + ClockFmtObj_UpdateString, /* updateStringProc */ + ClockFmtObj_SetFromAny /* setFromAnyProc */ +}; + +#define ObjClockFmtScn(objPtr) \ + (*((ClockFmtScnStorage **)&(objPtr)->internalRep.twoPtrValue.ptr1)) + +#define ObjLocFmtKey(objPtr) \ + (*((Tcl_Obj **)&(objPtr)->internalRep.twoPtrValue.ptr2)) + +static void +ClockFmtObj_DupInternalRep(srcPtr, copyPtr) + Tcl_Obj *srcPtr; + Tcl_Obj *copyPtr; +{ + ClockFmtScnStorage *fss = ObjClockFmtScn(srcPtr); + + if (fss != NULL) { + Tcl_MutexLock(&ClockFmtMutex); + fss->objRefCount++; + Tcl_MutexUnlock(&ClockFmtMutex); + } + + ObjClockFmtScn(copyPtr) = fss; + /* regards special case - format not localizable */ + if (ObjLocFmtKey(srcPtr) != srcPtr) { + Tcl_InitObjRef(ObjLocFmtKey(copyPtr), ObjLocFmtKey(srcPtr)); + } else { + ObjLocFmtKey(copyPtr) = copyPtr; + } + copyPtr->typePtr = &ClockFmtObjType; + + + /* if no format representation, dup string representation */ + if (fss == NULL) { + copyPtr->bytes = ckalloc(srcPtr->length + 1); + memcpy(copyPtr->bytes, srcPtr->bytes, srcPtr->length + 1); + copyPtr->length = srcPtr->length; + } +} + +static void +ClockFmtObj_FreeInternalRep(objPtr) + Tcl_Obj *objPtr; +{ + ClockFmtScnStorage *fss = ObjClockFmtScn(objPtr); + if (fss != NULL) { + Tcl_MutexLock(&ClockFmtMutex); + /* decrement object reference count of format/scan storage */ + if (--fss->objRefCount <= 0) { + #if CLOCK_FMT_SCN_STORAGE_GC_SIZE > 0 + /* don't remove it right now (may be reusable), just add to GC */ + ClockFmtScnStorageGC_In(fss); + #else + /* remove storage (format representation) */ + ClockFmtScnStorageDelete(fss); + #endif + } + Tcl_MutexUnlock(&ClockFmtMutex); + } + ObjClockFmtScn(objPtr) = NULL; + if (ObjLocFmtKey(objPtr) != objPtr) { + Tcl_UnsetObjRef(ObjLocFmtKey(objPtr)); + } else { + ObjLocFmtKey(objPtr) = NULL; + } + objPtr->typePtr = NULL; +}; + +static int +ClockFmtObj_SetFromAny(interp, objPtr) + Tcl_Interp *interp; + Tcl_Obj *objPtr; +{ + /* validate string representation before free old internal represenation */ + (void)TclGetString(objPtr); + + /* free old internal represenation */ + if (objPtr->typePtr && objPtr->typePtr->freeIntRepProc) + objPtr->typePtr->freeIntRepProc(objPtr); + + /* initial state of format object */ + ObjClockFmtScn(objPtr) = NULL; + ObjLocFmtKey(objPtr) = NULL; + objPtr->typePtr = &ClockFmtObjType; + + return TCL_OK; +}; + +static void +ClockFmtObj_UpdateString(objPtr) + Tcl_Obj *objPtr; +{ + char *name = "UNKNOWN"; + int len; + ClockFmtScnStorage *fss = ObjClockFmtScn(objPtr); + + if (fss != NULL) { + Tcl_HashEntry *hPtr = HashEntry4FmtScn(fss); + name = hPtr->key.string; + } + len = strlen(name); + objPtr->length = len, + objPtr->bytes = ckalloc((size_t)++len); + if (objPtr->bytes) + memcpy(objPtr->bytes, name, len); +} + +/* + *---------------------------------------------------------------------- + * + * ClockFrmObjGetLocFmtKey -- + * + * Retrieves format key object used to search localized format. + * + * This is normally stored in second pointer of internal representation. + * If format object is not localizable, it is equal the given format + * pointer and the first pointer of internal representation may be NULL. + * + * Results: + * Returns tcl object with key or format object if not localizable. + * + * Side effects: + * Converts given format object to ClockFmtObjType on demand for caching + * the key inside its internal representation. + * + *---------------------------------------------------------------------- + */ + +MODULE_SCOPE Tcl_Obj* +ClockFrmObjGetLocFmtKey( + Tcl_Interp *interp, + Tcl_Obj *objPtr) +{ + Tcl_Obj *keyObj; + + if (objPtr->typePtr != &ClockFmtObjType) { + if (ClockFmtObj_SetFromAny(interp, objPtr) != TCL_OK) { + return NULL; + } + } + + keyObj = ObjLocFmtKey(objPtr); + if (keyObj) { + return keyObj; + } + + keyObj = Tcl_ObjPrintf("FMT_%s", TclGetString(objPtr)); + Tcl_InitObjRef(ObjLocFmtKey(objPtr), keyObj); + + return keyObj; +} + +/* + *---------------------------------------------------------------------- + * + * FindOrCreateFmtScnStorage -- + * + * Retrieves format storage for given string format. + * + * This will find the given format in the global storage hash table + * or create a format storage object on demaind and save the + * reference in the first pointer of internal representation of given + * object. + * + * Results: + * Returns scan/format storage pointer to ClockFmtScnStorage. + * + * Side effects: + * Converts given format object to ClockFmtObjType on demand for caching + * the format storage reference inside its internal representation. + * Increments objRefCount of the ClockFmtScnStorage reference. + * + *---------------------------------------------------------------------- + */ + +static ClockFmtScnStorage * +FindOrCreateFmtScnStorage( + Tcl_Interp *interp, + Tcl_Obj *objPtr) +{ + const char *strFmt = TclGetString(objPtr); + ClockFmtScnStorage *fss = NULL; + int new; + Tcl_HashEntry *hPtr; + + Tcl_MutexLock(&ClockFmtMutex); + + /* if not yet initialized */ + if (!initialized) { + /* initialize type */ + memcpy(&ClockFmtScnStorageHashKeyType, &tclStringHashKeyType, sizeof(tclStringHashKeyType)); + ClockFmtScnStorageHashKeyType.allocEntryProc = ClockFmtScnStorageAllocProc; + ClockFmtScnStorageHashKeyType.freeEntryProc = ClockFmtScnStorageFreeProc; + + /* initialize hash table */ + Tcl_InitCustomHashTable(&FmtScnHashTable, TCL_CUSTOM_TYPE_KEYS, + &ClockFmtScnStorageHashKeyType); + + initialized = 1; + Tcl_CreateExitHandler(ClockFrmScnFinalize, NULL); + } + + /* get or create entry (and alocate storage) */ + hPtr = Tcl_CreateHashEntry(&FmtScnHashTable, strFmt, &new); + if (hPtr != NULL) { + + fss = FmtScn4HashEntry(hPtr); + + #if CLOCK_FMT_SCN_STORAGE_GC_SIZE > 0 + /* unlink if it is currently in GC */ + if (new == 0 && fss->objRefCount == 0) { + ClockFmtScnStorage_GC_Out(fss); + } + #endif + + /* new reference, so increment in lock right now */ + fss->objRefCount++; + + ObjClockFmtScn(objPtr) = fss; + } + + Tcl_MutexUnlock(&ClockFmtMutex); + + if (fss == NULL && interp != NULL) { + Tcl_AppendResult(interp, "retrieve clock format failed \"", + strFmt ? strFmt : "", "\"", NULL); + Tcl_SetErrorCode(interp, "TCL", "EINVAL", NULL); + } + + return fss; +} + +/* + *---------------------------------------------------------------------- + * + * Tcl_GetClockFrmScnFromObj -- + * + * Returns a clock format/scan representation of (*objPtr), if possible. + * If something goes wrong, NULL is returned, and if interp is non-NULL, + * an error message is written there. + * + * Results: + * Valid representation of type ClockFmtScnStorage. + * + * Side effects: + * Caches the ClockFmtScnStorage reference as the internal rep of (*objPtr) + * and in global hash table, shared across all threads. + * + *---------------------------------------------------------------------- + */ + +ClockFmtScnStorage * +Tcl_GetClockFrmScnFromObj( + Tcl_Interp *interp, + Tcl_Obj *objPtr) +{ + ClockFmtScnStorage *fss; + + if (objPtr->typePtr != &ClockFmtObjType) { + if (ClockFmtObj_SetFromAny(interp, objPtr) != TCL_OK) { + return NULL; + } + } + + fss = ObjClockFmtScn(objPtr); + + if (fss == NULL) { + fss = FindOrCreateFmtScnStorage(interp, objPtr); + } + + return fss; +} +/* + *---------------------------------------------------------------------- + * + * ClockLocalizeFormat -- + * + * Wrap the format object in options to the localized format, + * corresponding given locale. + * + * This searches localized format in locale catalog, and if not yet + * exists, it executes ::tcl::clock::LocalizeFormat in given interpreter + * and caches its result in the locale catalog. + * + * Results: + * Localized format object. + * + * Side effects: + * Caches the localized format inside locale catalog. + * + *---------------------------------------------------------------------- + */ + +MODULE_SCOPE Tcl_Obj * +ClockLocalizeFormat( + ClockFmtScnCmdArgs *opts) +{ + ClockClientData *dataPtr = opts->clientData; + Tcl_Obj *valObj = NULL, *keyObj; + + keyObj = ClockFrmObjGetLocFmtKey(opts->interp, opts->formatObj); + + /* special case - format object is not localizable */ + if (keyObj == opts->formatObj) { + return opts->formatObj; + } + + if (opts->mcDictObj == NULL) { + ClockMCDict(opts); + if (opts->mcDictObj == NULL) + return NULL; + } + + /* try to find in cache within locale mc-catalog */ + if (Tcl_DictObjGet(NULL, opts->mcDictObj, + keyObj, &valObj) != TCL_OK) { + return NULL; + } + + /* call LocalizeFormat locale format fmtkey */ + if (valObj == NULL) { + Tcl_Obj *callargs[4]; + callargs[0] = dataPtr->literals[LIT_LOCALIZE_FORMAT]; + callargs[1] = opts->localeObj; + callargs[2] = opts->formatObj; + callargs[3] = keyObj; + Tcl_IncrRefCount(keyObj); + if (Tcl_EvalObjv(opts->interp, 4, callargs, 0) != TCL_OK + ) { + goto clean; + } + + valObj = Tcl_GetObjResult(opts->interp); + + /* cache it inside mc-dictionary (this incr. ref count of keyObj/valObj) */ + if (Tcl_DictObjPut(opts->interp, opts->mcDictObj, + keyObj, valObj) != TCL_OK + ) { + valObj = NULL; + goto clean; + } + + /* check special case - format object is not localizable */ + if (valObj == opts->formatObj) { + /* mark it as unlocalizable, by setting self as key (without refcount incr) */ + if (opts->formatObj->typePtr == &ClockFmtObjType) { + Tcl_UnsetObjRef(ObjLocFmtKey(opts->formatObj)); + ObjLocFmtKey(opts->formatObj) = opts->formatObj; + } + } +clean: + + Tcl_UnsetObjRef(keyObj); + if (valObj) { + Tcl_ResetResult(opts->interp); + } + } + + return (opts->formatObj = valObj); +} + +/* + *---------------------------------------------------------------------- + * + * FindTokenBegin -- + * + * Find begin of given scan token in string, corresponding token type. + * + * Results: + * Position of token inside string if found. Otherwise - end of string. + * + * Side effects: + * None. + * + *---------------------------------------------------------------------- + */ + +static const char * +FindTokenBegin( + register const char *p, + register const char *end, + ClockScanToken *tok) +{ + char c; + if (p < end) { + /* next token a known token type */ + switch (tok->map->type) { + case CTOKT_DIGIT: + /* should match at least one digit */ + while (!isdigit(UCHAR(*p)) && (p = TclUtfNext(p)) < end) {}; + return p; + break; + case CTOKT_WORD: + c = *(tok->tokWord.start); + /* should match at least to the first char of this word */ + while (*p != c && (p = TclUtfNext(p)) < end) {}; + return p; + break; + case CTOKT_SPACE: + while (!isspace(UCHAR(*p)) && (p = TclUtfNext(p)) < end) {}; + return p; + break; + case CTOKT_CHAR: + c = *((char *)tok->map->data); + while (*p != c && (p = TclUtfNext(p)) < end) {}; + return p; + break; + } + } + return p; +} + +/* + *---------------------------------------------------------------------- + * + * DetermineGreedySearchLen -- + * + * Determine min/max lengths as exact as possible (speed, greedy match). + * + * Results: + * None. Lengths are stored in *minLenPtr, *maxLenPtr. + * + * Side effects: + * None. + * + *---------------------------------------------------------------------- + */ + +static void +DetermineGreedySearchLen(ClockFmtScnCmdArgs *opts, + DateInfo *info, ClockScanToken *tok, + int *minLenPtr, int *maxLenPtr) +{ + register int minLen = tok->map->minSize; + register int maxLen; + register const char *p = yyInput + minLen, + *end = info->dateEnd; + + /* if still tokens available, try to correct minimum length */ + if ((tok+1)->map) { + end -= tok->endDistance + yySpaceCount; + /* find position of next known token */ + p = FindTokenBegin(p, end, tok+1); + if (p < end) { + minLen = p - yyInput; + } + } + + /* max length to the end regarding distance to end (min-width of following tokens) */ + maxLen = end - yyInput; + /* several amendments */ + if (maxLen > tok->map->maxSize) { + maxLen = tok->map->maxSize; + }; + if (minLen < tok->map->minSize) { + minLen = tok->map->minSize; + } + if (minLen > maxLen) { + maxLen = minLen; + } + if (maxLen > info->dateEnd - yyInput) { + maxLen = info->dateEnd - yyInput; + } + + /* check digits rigth now */ + if (tok->map->type == CTOKT_DIGIT) { + p = yyInput; + end = p + maxLen; + if (end > info->dateEnd) { end = info->dateEnd; }; + while (isdigit(UCHAR(*p)) && p < end) { p++; }; + maxLen = p - yyInput; + } + + /* try to get max length more precise for greedy match, + * check the next ahead token available there */ + if (minLen < maxLen && tok->lookAhTok) { + ClockScanToken *laTok = tok + tok->lookAhTok + 1; + p = yyInput + maxLen; + /* regards all possible spaces here (because they are optional) */ + end = p + tok->lookAhMax + yySpaceCount + 1; + if (end > info->dateEnd) { + end = info->dateEnd; + } + p += tok->lookAhMin; + if (laTok->map && p < end) { + const char *f; + /* try to find laTok between [lookAhMin, lookAhMax] */ + while (minLen < maxLen) { + f = FindTokenBegin(p, end, laTok); + /* if found (not below lookAhMax) */ + if (f < end) { + break; + } + /* try again with fewer length */ + maxLen--; + p--; + end--; + } + } else if (p > end) { + maxLen -= (p - end); + if (maxLen < minLen) { + maxLen = minLen; + } + } + } + + *minLenPtr = minLen; + *maxLenPtr = maxLen; +} + +/* + *---------------------------------------------------------------------- + * + * ObjListSearch -- + * + * Find largest part of the input string from start regarding min and + * max lengths in the given list (utf-8, case sensitive). + * + * Results: + * TCL_OK - match found, TCL_RETURN - not matched, TCL_ERROR in error case. + * + * Side effects: + * Input points to end of the found token in string. + * + *---------------------------------------------------------------------- + */ + +static inline int +ObjListSearch(ClockFmtScnCmdArgs *opts, + DateInfo *info, int *val, + Tcl_Obj **lstv, int lstc, + int minLen, int maxLen) +{ + int i, l, lf = -1; + const char *s, *f, *sf; + /* search in list */ + for (i = 0; i < lstc; i++) { + s = TclGetString(lstv[i]); + l = lstv[i]->length; + + if ( l >= minLen + && (f = TclUtfFindEqualNC(yyInput, yyInput + maxLen, s, s + l, &sf)) > yyInput + ) { + l = f - yyInput; + if (l < minLen) { + continue; + } + /* found, try to find longest value (greedy search) */ + if (l < maxLen && minLen != maxLen) { + lf = i; + minLen = l + 1; + continue; + } + /* max possible - end of search */ + *val = i; + yyInput += l; + break; + } + } + + /* if found */ + if (i < lstc) { + return TCL_OK; + } + if (lf >= 0) { + *val = lf; + yyInput += minLen - 1; + return TCL_OK; + } + return TCL_RETURN; +} +#if 0 +/* currently unused */ + +static int +LocaleListSearch(ClockFmtScnCmdArgs *opts, + DateInfo *info, int mcKey, int *val, + int minLen, int maxLen) +{ + Tcl_Obj **lstv; + int lstc; + Tcl_Obj *valObj; + + /* get msgcat value */ + valObj = ClockMCGet(opts, mcKey); + if (valObj == NULL) { + return TCL_ERROR; + } + + /* is a list */ + if (TclListObjGetElements(opts->interp, valObj, &lstc, &lstv) != TCL_OK) { + return TCL_ERROR; + } + + /* search in list */ + return ObjListSearch(opts, info, val, lstv, lstc, + minLen, maxLen); +} +#endif + +/* + *---------------------------------------------------------------------- + * + * ClockMCGetListIdxTree -- + * + * Retrieves localized string indexed tree in the locale catalog for + * given literal index mcKey (and builds it on demand). + * + * Searches localized index in locale catalog, and if not yet exists, + * creates string indexed tree and stores it in the locale catalog. + * + * Results: + * Localized string index tree. + * + * Side effects: + * Caches the localized string index tree inside locale catalog. + * + *---------------------------------------------------------------------- + */ + +static TclStrIdxTree * +ClockMCGetListIdxTree( + ClockFmtScnCmdArgs *opts, + int mcKey) +{ + TclStrIdxTree * idxTree; + Tcl_Obj *objPtr = ClockMCGetIdx(opts, mcKey); + if ( objPtr != NULL + && (idxTree = TclStrIdxTreeGetFromObj(objPtr)) != NULL + ) { + return idxTree; + + } else { + /* build new index */ + + Tcl_Obj **lstv; + int lstc; + Tcl_Obj *valObj; + + objPtr = TclStrIdxTreeNewObj(); + if ((idxTree = TclStrIdxTreeGetFromObj(objPtr)) == NULL) { + goto done; /* unexpected, but ...*/ + } + + valObj = ClockMCGet(opts, mcKey); + if (valObj == NULL) { + goto done; + } + + if (TclListObjGetElements(opts->interp, valObj, + &lstc, &lstv) != TCL_OK) { + goto done; + }; + + if (TclStrIdxTreeBuildFromList(idxTree, lstc, lstv) != TCL_OK) { + goto done; + } + + ClockMCSetIdx(opts, mcKey, objPtr); + objPtr = NULL; + }; + +done: + if (objPtr) { + Tcl_DecrRefCount(objPtr); + idxTree = NULL; + } + + return idxTree; +} + +/* + *---------------------------------------------------------------------- + * + * ClockMCGetMultiListIdxTree -- + * + * Retrieves localized string indexed tree in the locale catalog for + * multiple lists by literal indices mcKeys (and builds it on demand). + * + * Searches localized index in locale catalog for mcKey, and if not + * yet exists, creates string indexed tree and stores it in the + * locale catalog. + * + * Results: + * Localized string index tree. + * + * Side effects: + * Caches the localized string index tree inside locale catalog. + * + *---------------------------------------------------------------------- + */ + +static TclStrIdxTree * +ClockMCGetMultiListIdxTree( + ClockFmtScnCmdArgs *opts, + int mcKey, + int *mcKeys) +{ + TclStrIdxTree * idxTree; + Tcl_Obj *objPtr = ClockMCGetIdx(opts, mcKey); + if ( objPtr != NULL + && (idxTree = TclStrIdxTreeGetFromObj(objPtr)) != NULL + ) { + return idxTree; + + } else { + /* build new index */ + + Tcl_Obj **lstv; + int lstc; + Tcl_Obj *valObj; + + objPtr = TclStrIdxTreeNewObj(); + if ((idxTree = TclStrIdxTreeGetFromObj(objPtr)) == NULL) { + goto done; /* unexpected, but ...*/ + } + + while (*mcKeys) { + + valObj = ClockMCGet(opts, *mcKeys); + if (valObj == NULL) { + goto done; + } + + if (TclListObjGetElements(opts->interp, valObj, + &lstc, &lstv) != TCL_OK) { + goto done; + }; + + if (TclStrIdxTreeBuildFromList(idxTree, lstc, lstv) != TCL_OK) { + goto done; + } + mcKeys++; + } + + ClockMCSetIdx(opts, mcKey, objPtr); + objPtr = NULL; + }; + +done: + if (objPtr) { + Tcl_DecrRefCount(objPtr); + idxTree = NULL; + } + + return idxTree; +} + +/* + *---------------------------------------------------------------------- + * + * ClockStrIdxTreeSearch -- + * + * Find largest part of the input string from start regarding lengths + * in the given localized string indexed tree (utf-8, case sensitive). + * + * Results: + * TCL_OK - match found and the index stored in *val, + * TCL_RETURN - not matched or ambigous, + * TCL_ERROR - in error case. + * + * Side effects: + * Input points to end of the found token in string. + * + *---------------------------------------------------------------------- + */ + +static inline int +ClockStrIdxTreeSearch(ClockFmtScnCmdArgs *opts, + DateInfo *info, TclStrIdxTree *idxTree, int *val, + int minLen, int maxLen) +{ + const char *f; + TclStrIdx *foundItem; + f = TclStrIdxTreeSearch(NULL, &foundItem, idxTree, + yyInput, yyInput + maxLen); + + if (f <= yyInput || (f - yyInput) < minLen) { + /* not found */ + return TCL_RETURN; + } + if (foundItem->value == -1) { + /* ambigous */ + return TCL_RETURN; + } + + *val = foundItem->value; + + /* shift input pointer */ + yyInput = f; + + return TCL_OK; +} +#if 0 +/* currently unused */ + +static int +StaticListSearch(ClockFmtScnCmdArgs *opts, + DateInfo *info, const char **lst, int *val) +{ + int len; + const char **s = lst; + while (*s != NULL) { + len = strlen(*s); + if ( len <= info->dateEnd - yyInput + && strncasecmp(yyInput, *s, len) == 0 + ) { + *val = (s - lst); + yyInput += len; + break; + } + s++; + } + if (*s != NULL) { + return TCL_OK; + } + return TCL_RETURN; +} +#endif + +static inline const char * +FindWordEnd( + ClockScanToken *tok, + register const char * p, const char * end) +{ + register const char *x = tok->tokWord.start; + const char *pfnd = p; + if (x == tok->tokWord.end - 1) { /* fast phase-out for single char word */ + if (*p == *x) { + return ++p; + } + } + /* multi-char word */ + x = TclUtfFindEqualNC(x, tok->tokWord.end, p, end, &pfnd); + if (x < tok->tokWord.end) { + /* no match -> error */ + return NULL; + } + return pfnd; +} + +static int +ClockScnToken_Month_Proc(ClockFmtScnCmdArgs *opts, + DateInfo *info, ClockScanToken *tok) +{ +#if 0 +/* currently unused, test purposes only */ + static const char * months[] = { + /* full */ + "January", "February", "March", + "April", "May", "June", + "July", "August", "September", + "October", "November", "December", + /* abbr */ + "Jan", "Feb", "Mar", "Apr", "May", "Jun", + "Jul", "Aug", "Sep", "Oct", "Nov", "Dec", + NULL + }; + int val; + if (StaticListSearch(opts, info, months, &val) != TCL_OK) { + return TCL_RETURN; + } + yyMonth = (val % 12) + 1; + return TCL_OK; +#endif + + static int monthsKeys[] = {MCLIT_MONTHS_FULL, MCLIT_MONTHS_ABBREV, 0}; + + int ret, val; + int minLen, maxLen; + TclStrIdxTree *idxTree; + + DetermineGreedySearchLen(opts, info, tok, &minLen, &maxLen); + + /* get or create tree in msgcat dict */ + + idxTree = ClockMCGetMultiListIdxTree(opts, MCLIT_MONTHS_COMB, monthsKeys); + if (idxTree == NULL) { + return TCL_ERROR; + } + + ret = ClockStrIdxTreeSearch(opts, info, idxTree, &val, minLen, maxLen); + if (ret != TCL_OK) { + return ret; + } + + yyMonth = val + 1; + return TCL_OK; + +} + +static int +ClockScnToken_DayOfWeek_Proc(ClockFmtScnCmdArgs *opts, + DateInfo *info, ClockScanToken *tok) +{ + static int dowKeys[] = {MCLIT_DAYS_OF_WEEK_ABBREV, MCLIT_DAYS_OF_WEEK_FULL, 0}; + + int ret, val; + int minLen, maxLen; + char curTok = *tok->tokWord.start; + TclStrIdxTree *idxTree; + + DetermineGreedySearchLen(opts, info, tok, &minLen, &maxLen); + + /* %u %w %Ou %Ow */ + if ( curTok != 'a' && curTok != 'A' + && ((minLen <= 1 && maxLen >= 1) || PTR2INT(tok->map->data)) + ) { + + val = -1; + + if (PTR2INT(tok->map->data) == 0) { + if (*yyInput >= '0' && *yyInput <= '9') { + val = *yyInput - '0'; + } + } else { + idxTree = ClockMCGetListIdxTree(opts, PTR2INT(tok->map->data) /* mcKey */); + if (idxTree == NULL) { + return TCL_ERROR; + } + + ret = ClockStrIdxTreeSearch(opts, info, idxTree, &val, minLen, maxLen); + if (ret != TCL_OK) { + return ret; + } + } + + if (val != -1) { + if (val == 0) { + val = 7; + } + if (val > 7) { + Tcl_SetResult(opts->interp, "day of week is greater than 7", + TCL_STATIC); + Tcl_SetErrorCode(opts->interp, "CLOCK", "badDayOfWeek", NULL); + return TCL_ERROR; + } + info->date.dayOfWeek = val; + yyInput++; + return TCL_OK; + } + + + return TCL_RETURN; + } + + /* %a %A */ + idxTree = ClockMCGetMultiListIdxTree(opts, MCLIT_DAYS_OF_WEEK_COMB, dowKeys); + if (idxTree == NULL) { + return TCL_ERROR; + } + + ret = ClockStrIdxTreeSearch(opts, info, idxTree, &val, minLen, maxLen); + if (ret != TCL_OK) { + return ret; + } + + if (val == 0) { + val = 7; + } + info->date.dayOfWeek = val; + return TCL_OK; + +} + +static int +ClockScnToken_amPmInd_Proc(ClockFmtScnCmdArgs *opts, + DateInfo *info, ClockScanToken *tok) +{ + int ret, val; + int minLen, maxLen; + Tcl_Obj *amPmObj[2]; + + DetermineGreedySearchLen(opts, info, tok, &minLen, &maxLen); + + amPmObj[0] = ClockMCGet(opts, MCLIT_AM); + amPmObj[1] = ClockMCGet(opts, MCLIT_PM); + + if (amPmObj[0] == NULL || amPmObj[1] == NULL) { + return TCL_ERROR; + } + + ret = ObjListSearch(opts, info, &val, amPmObj, 2, + minLen, maxLen); + if (ret != TCL_OK) { + return ret; + } + + if (val == 0) { + yyMeridian = MERam; + } else { + yyMeridian = MERpm; + } + + return TCL_OK; +} + +static int +ClockScnToken_LocaleERA_Proc(ClockFmtScnCmdArgs *opts, + DateInfo *info, ClockScanToken *tok) +{ + ClockClientData *dataPtr = opts->clientData; + + int ret, val; + int minLen, maxLen; + Tcl_Obj *eraObj[6]; + + DetermineGreedySearchLen(opts, info, tok, &minLen, &maxLen); + + eraObj[0] = ClockMCGet(opts, MCLIT_BCE); + eraObj[1] = ClockMCGet(opts, MCLIT_CE); + eraObj[2] = dataPtr->mcLiterals[MCLIT_BCE2]; + eraObj[3] = dataPtr->mcLiterals[MCLIT_CE2]; + eraObj[4] = dataPtr->mcLiterals[MCLIT_BCE3]; + eraObj[5] = dataPtr->mcLiterals[MCLIT_CE3]; + + if (eraObj[0] == NULL || eraObj[1] == NULL) { + return TCL_ERROR; + } + + ret = ObjListSearch(opts, info, &val, eraObj, 6, + minLen, maxLen); + if (ret != TCL_OK) { + return ret; + } + + if (val & 1) { + yydate.era = CE; + } else { + yydate.era = BCE; + } + + return TCL_OK; +} + +static int +ClockScnToken_LocaleListMatcher_Proc(ClockFmtScnCmdArgs *opts, + DateInfo *info, ClockScanToken *tok) +{ + int ret, val; + int minLen, maxLen; + TclStrIdxTree *idxTree; + + DetermineGreedySearchLen(opts, info, tok, &minLen, &maxLen); + + /* get or create tree in msgcat dict */ + + idxTree = ClockMCGetListIdxTree(opts, PTR2INT(tok->map->data) /* mcKey */); + if (idxTree == NULL) { + return TCL_ERROR; + } + + ret = ClockStrIdxTreeSearch(opts, info, idxTree, &val, minLen, maxLen); + if (ret != TCL_OK) { + return ret; + } + + if (tok->map->offs > 0) { + *(int *)(((char *)info) + tok->map->offs) = val; + } + + return TCL_OK; +} + +static int +ClockScnToken_TimeZone_Proc(ClockFmtScnCmdArgs *opts, + DateInfo *info, ClockScanToken *tok) +{ + int minLen, maxLen; + int len = 0; + register const char *p = yyInput; + Tcl_Obj *tzObjStor = NULL; + + DetermineGreedySearchLen(opts, info, tok, &minLen, &maxLen); + + /* numeric timezone */ + if (*p == '+' || *p == '-') { + /* max chars in numeric zone = "+00:00:00" */ + #define MAX_ZONE_LEN 9 + char buf[MAX_ZONE_LEN + 1]; + char *bp = buf; + *bp++ = *p++; len++; + if (maxLen > MAX_ZONE_LEN) + maxLen = MAX_ZONE_LEN; + /* cumulate zone into buf without ':' */ + while (len + 1 < maxLen) { + if (!isdigit(UCHAR(*p))) break; + *bp++ = *p++; len++; + if (!isdigit(UCHAR(*p))) break; + *bp++ = *p++; len++; + if (len + 2 < maxLen) { + if (*p == ':') { + p++; len++; + } + } + } + *bp = '\0'; + + if (len < minLen) { + return TCL_RETURN; + } + #undef MAX_ZONE_LEN + + /* timezone */ + tzObjStor = Tcl_NewStringObj(buf, bp-buf); + } else { + /* legacy (alnum) timezone like CEST, etc. */ + if (maxLen > 4) + maxLen = 4; + while (len < maxLen) { + if ( (*p & 0x80) + || (!isalpha(UCHAR(*p)) && !isdigit(UCHAR(*p))) + ) { /* INTL: ISO only. */ + break; + } + p++; len++; + } + + if (len < minLen) { + return TCL_RETURN; + } + + /* timezone */ + tzObjStor = Tcl_NewStringObj(yyInput, p-yyInput); + + /* convert using dict */ + } + + /* try to apply new time zone */ + Tcl_IncrRefCount(tzObjStor); + + opts->timezoneObj = ClockSetupTimeZone(opts->clientData, opts->interp, + tzObjStor); + + Tcl_DecrRefCount(tzObjStor); + if (opts->timezoneObj == NULL) { + return TCL_ERROR; + } + + yyInput += len; + + return TCL_OK; +} + +static int +ClockScnToken_StarDate_Proc(ClockFmtScnCmdArgs *opts, + DateInfo *info, ClockScanToken *tok) +{ + int minLen, maxLen; + register const char *p = yyInput, *end; const char *s; + int year, fractYear, fractDayDiv, fractDay; + static const char *stardatePref = "stardate "; + + DetermineGreedySearchLen(opts, info, tok, &minLen, &maxLen); + + end = yyInput + maxLen; + + /* stardate string */ + p = TclUtfFindEqualNCInLwr(p, end, stardatePref, stardatePref + 9, &s); + if (p >= end || p - yyInput < 9) { + return TCL_RETURN; + } + /* bypass spaces */ + while (p < end && isspace(UCHAR(*p))) { + p++; + } + if (p >= end) { + return TCL_RETURN; + } + /* currently positive stardate only */ + if (*p == '+') { p++; }; + s = p; + while (p < end && isdigit(UCHAR(*p))) { + p++; + } + if (p >= end || p - s < 4) { + return TCL_RETURN; + } + if ( _str2int(&year, s, p-3, 1) != TCL_OK + || _str2int(&fractYear, p-3, p, 1) != TCL_OK) { + return TCL_RETURN; + }; + if (*p++ != '.') { + return TCL_RETURN; + } + s = p; + fractDayDiv = 1; + while (p < end && isdigit(UCHAR(*p))) { + fractDayDiv *= 10; + p++; + } + if ( _str2int(&fractDay, s, p, 1) != TCL_OK) { + return TCL_RETURN; + }; + yyInput = p; + + /* Build a date from year and fraction. */ + + yydate.year = year + RODDENBERRY; + yydate.era = CE; + yydate.gregorian = 1; + + if (IsGregorianLeapYear(&yydate)) { + fractYear *= 366; + } else { + fractYear *= 365; + } + yydate.dayOfYear = fractYear / 1000 + 1; + if (fractYear % 1000 >= 500) { + yydate.dayOfYear++; + } + + GetJulianDayFromEraYearDay(&yydate, GREGORIAN_CHANGE_DATE); + + yydate.localSeconds = + -210866803200L + + ( SECONDS_PER_DAY * (Tcl_WideInt)yydate.julianDay ) + + ( SECONDS_PER_DAY * fractDay / fractDayDiv ); + + return TCL_OK; +} + +static const char *ScnSTokenMapIndex = + "dmbyYHMSpJjCgGVazUsntQ"; +static ClockScanTokenMap ScnSTokenMap[] = { + /* %d %e */ + {CTOKT_DIGIT, CLF_DAYOFMONTH, 0, 1, 2, TclOffset(DateInfo, date.dayOfMonth), + NULL}, + /* %m %N */ + {CTOKT_DIGIT, CLF_MONTH, 0, 1, 2, TclOffset(DateInfo, date.month), + NULL}, + /* %b %B %h */ + {CTOKT_PARSER, CLF_MONTH, 0, 0, 0xffff, 0, + ClockScnToken_Month_Proc}, + /* %y */ + {CTOKT_DIGIT, CLF_YEAR, 0, 1, 2, TclOffset(DateInfo, date.year), + NULL}, + /* %Y */ + {CTOKT_DIGIT, CLF_YEAR | CLF_CENTURY, 0, 4, 4, TclOffset(DateInfo, date.year), + NULL}, + /* %H %k %I %l */ + {CTOKT_DIGIT, CLF_TIME, 0, 1, 2, TclOffset(DateInfo, date.hour), + NULL}, + /* %M */ + {CTOKT_DIGIT, CLF_TIME, 0, 1, 2, TclOffset(DateInfo, date.minutes), + NULL}, + /* %S */ + {CTOKT_DIGIT, CLF_TIME, 0, 1, 2, TclOffset(DateInfo, date.secondOfDay), + NULL}, + /* %p %P */ + {CTOKT_PARSER, CLF_ISO8601, 0, 0, 0xffff, 0, + ClockScnToken_amPmInd_Proc, NULL}, + /* %J */ + {CTOKT_DIGIT, CLF_JULIANDAY, 0, 1, 0xffff, TclOffset(DateInfo, date.julianDay), + NULL}, + /* %j */ + {CTOKT_DIGIT, CLF_DAYOFYEAR, 0, 1, 3, TclOffset(DateInfo, date.dayOfYear), + NULL}, + /* %C */ + {CTOKT_DIGIT, CLF_CENTURY|CLF_ISO8601CENTURY, 0, 1, 2, TclOffset(DateInfo, dateCentury), + NULL}, + /* %g */ + {CTOKT_DIGIT, CLF_ISO8601YEAR | CLF_ISO8601, 0, 2, 2, TclOffset(DateInfo, date.iso8601Year), + NULL}, + /* %G */ + {CTOKT_DIGIT, CLF_ISO8601YEAR | CLF_ISO8601 | CLF_ISO8601CENTURY, 0, 4, 4, TclOffset(DateInfo, date.iso8601Year), + NULL}, + /* %V */ + {CTOKT_DIGIT, CLF_ISO8601, 0, 1, 2, TclOffset(DateInfo, date.iso8601Week), + NULL}, + /* %a %A %u %w */ + {CTOKT_PARSER, CLF_ISO8601, 0, 0, 0xffff, 0, + ClockScnToken_DayOfWeek_Proc, NULL}, + /* %z %Z */ + {CTOKT_PARSER, CLF_OPTIONAL, 0, 0, 0xffff, 0, + ClockScnToken_TimeZone_Proc, NULL}, + /* %U %W */ + {CTOKT_DIGIT, CLF_OPTIONAL, 0, 1, 2, 0, /* currently no capture, parse only token */ + NULL}, + /* %s */ + {CTOKT_DIGIT, CLF_POSIXSEC | CLF_SIGNED, 0, 1, 0xffff, TclOffset(DateInfo, date.seconds), + NULL}, + /* %n */ + {CTOKT_CHAR, 0, 0, 1, 1, 0, NULL, "\n"}, + /* %t */ + {CTOKT_CHAR, 0, 0, 1, 1, 0, NULL, "\t"}, + /* %Q */ + {CTOKT_PARSER, CLF_LOCALSEC, 0, 16, 30, 0, + ClockScnToken_StarDate_Proc, NULL}, +}; +static const char *ScnSTokenMapAliasIndex[2] = { + "eNBhkIlPAuwZW", + "dmbbHHHpaaazU" +}; + +static const char *ScnETokenMapIndex = + "Eys"; +static ClockScanTokenMap ScnETokenMap[] = { + /* %EE */ + {CTOKT_PARSER, 0, 0, 0, 0xffff, TclOffset(DateInfo, date.year), + ClockScnToken_LocaleERA_Proc, (void *)MCLIT_LOCALE_NUMERALS}, + /* %Ey */ + {CTOKT_PARSER, 0, 0, 0, 0xffff, 0, /* currently no capture, parse only token */ + ClockScnToken_LocaleListMatcher_Proc, (void *)MCLIT_LOCALE_NUMERALS}, + /* %Es */ + {CTOKT_DIGIT, CLF_LOCALSEC | CLF_SIGNED, 0, 1, 0xffff, TclOffset(DateInfo, date.localSeconds), + NULL}, +}; +static const char *ScnETokenMapAliasIndex[2] = { + "", + "" +}; + +static const char *ScnOTokenMapIndex = + "dmyHMSu"; +static ClockScanTokenMap ScnOTokenMap[] = { + /* %Od %Oe */ + {CTOKT_PARSER, CLF_DAYOFMONTH, 0, 0, 0xffff, TclOffset(DateInfo, date.dayOfMonth), + ClockScnToken_LocaleListMatcher_Proc, (void *)MCLIT_LOCALE_NUMERALS}, + /* %Om */ + {CTOKT_PARSER, CLF_MONTH, 0, 0, 0xffff, TclOffset(DateInfo, date.month), + ClockScnToken_LocaleListMatcher_Proc, (void *)MCLIT_LOCALE_NUMERALS}, + /* %Oy */ + {CTOKT_PARSER, CLF_YEAR, 0, 0, 0xffff, TclOffset(DateInfo, date.year), + ClockScnToken_LocaleListMatcher_Proc, (void *)MCLIT_LOCALE_NUMERALS}, + /* %OH %Ok %OI %Ol */ + {CTOKT_PARSER, CLF_TIME, 0, 0, 0xffff, TclOffset(DateInfo, date.hour), + ClockScnToken_LocaleListMatcher_Proc, (void *)MCLIT_LOCALE_NUMERALS}, + /* %OM */ + {CTOKT_PARSER, CLF_TIME, 0, 0, 0xffff, TclOffset(DateInfo, date.minutes), + ClockScnToken_LocaleListMatcher_Proc, (void *)MCLIT_LOCALE_NUMERALS}, + /* %OS */ + {CTOKT_PARSER, CLF_TIME, 0, 0, 0xffff, TclOffset(DateInfo, date.secondOfDay), + ClockScnToken_LocaleListMatcher_Proc, (void *)MCLIT_LOCALE_NUMERALS}, + /* %Ou Ow */ + {CTOKT_PARSER, CLF_ISO8601, 0, 0, 0xffff, 0, + ClockScnToken_DayOfWeek_Proc, (void *)MCLIT_LOCALE_NUMERALS}, +}; +static const char *ScnOTokenMapAliasIndex[2] = { + "ekIlw", + "dHHHu" +}; + +static const char *ScnSpecTokenMapIndex = + " "; +static ClockScanTokenMap ScnSpecTokenMap[] = { + {CTOKT_SPACE, 0, 0, 1, 1, 0, + NULL}, +}; + +static ClockScanTokenMap ScnWordTokenMap = { + CTOKT_WORD, 0, 0, 1, 1, 0, + NULL +}; + + +static inline unsigned int +EstimateTokenCount( + register const char *fmt, + register const char *end) +{ + register const char *p = fmt; + unsigned int tokcnt; + /* estimate token count by % char and format length */ + tokcnt = 0; + while (p <= end) { + if (*p++ == '%') { + tokcnt++; + p++; + } + } + p = fmt + tokcnt * 2; + if (p < end) { + if ((unsigned int)(end - p) < tokcnt) { + tokcnt += (end - p); + } else { + tokcnt += tokcnt; + } + } + return ++tokcnt; +} + +#define AllocTokenInChain(tok, chain, tokCnt) \ + if (++(tok) >= (chain) + (tokCnt)) { \ + *((char **)&chain) = ckrealloc((char *)(chain), \ + (tokCnt + CLOCK_MIN_TOK_CHAIN_BLOCK_SIZE) * sizeof(*(tok))); \ + if ((chain) == NULL) { goto done; }; \ + (tok) = (chain) + (tokCnt); \ + (tokCnt) += CLOCK_MIN_TOK_CHAIN_BLOCK_SIZE; \ + } \ + memset(tok, 0, sizeof(*(tok))); + +/* + *---------------------------------------------------------------------- + */ +ClockFmtScnStorage * +ClockGetOrParseScanFormat( + Tcl_Interp *interp, /* Tcl interpreter */ + Tcl_Obj *formatObj) /* Format container */ +{ + ClockFmtScnStorage *fss; + ClockScanToken *tok; + + fss = Tcl_GetClockFrmScnFromObj(interp, formatObj); + if (fss == NULL) { + return NULL; + } + + /* if first time scanning - tokenize format */ + if (fss->scnTok == NULL) { + unsigned int tokCnt; + register const char *p, *e, *cp; + + e = p = HashEntry4FmtScn(fss)->key.string; + e += strlen(p); + + /* estimate token count by % char and format length */ + fss->scnTokC = EstimateTokenCount(p, e); + + fss->scnSpaceCount = 0; + + Tcl_MutexLock(&ClockFmtMutex); + + fss->scnTok = tok = ckalloc(sizeof(*tok) * fss->scnTokC); + memset(tok, 0, sizeof(*(tok))); + tokCnt = 1; + while (p < e) { + switch (*p) { + case '%': + if (1) { + ClockScanTokenMap * scnMap = ScnSTokenMap; + const char *mapIndex = ScnSTokenMapIndex, + **aliasIndex = ScnSTokenMapAliasIndex; + if (p+1 >= e) { + goto word_tok; + } + p++; + /* try to find modifier: */ + switch (*p) { + case '%': + /* begin new word token - don't join with previous word token, + * because current mapping should be "...%%..." -> "...%..." */ + tok->map = &ScnWordTokenMap; + tok->tokWord.start = p; + tok->tokWord.end = p+1; + AllocTokenInChain(tok, fss->scnTok, fss->scnTokC); tokCnt++; + p++; + continue; + break; + case 'E': + scnMap = ScnETokenMap, + mapIndex = ScnETokenMapIndex, + aliasIndex = ScnETokenMapAliasIndex; + p++; + break; + case 'O': + scnMap = ScnOTokenMap, + mapIndex = ScnOTokenMapIndex, + aliasIndex = ScnOTokenMapAliasIndex; + p++; + break; + } + /* search direct index */ + cp = strchr(mapIndex, *p); + if (!cp || *cp == '\0') { + /* search wrapper index (multiple chars for same token) */ + cp = strchr(aliasIndex[0], *p); + if (!cp || *cp == '\0') { + p--; if (scnMap != ScnSTokenMap) p--; + goto word_tok; + } + cp = strchr(mapIndex, aliasIndex[1][cp - aliasIndex[0]]); + if (!cp || *cp == '\0') { /* unexpected, but ... */ + #ifdef DEBUG + Tcl_Panic("token \"%c\" has no map in wrapper resolver", *p); + #endif + p--; if (scnMap != ScnSTokenMap) p--; + goto word_tok; + } + } + tok->map = &scnMap[cp - mapIndex]; + tok->tokWord.start = p; + + /* calculate look ahead value by standing together tokens */ + if (tok > fss->scnTok) { + ClockScanToken *prevTok = tok - 1; + + while (prevTok >= fss->scnTok) { + if (prevTok->map->type != tok->map->type) { + break; + } + prevTok->lookAhMin += tok->map->minSize; + prevTok->lookAhMax += tok->map->maxSize; + prevTok->lookAhTok++; + prevTok--; + } + } + + /* increase space count used in format */ + if ( tok->map->type == CTOKT_CHAR + && isspace(UCHAR(*((char *)tok->map->data))) + ) { + fss->scnSpaceCount++; + } + + /* next token */ + AllocTokenInChain(tok, fss->scnTok, fss->scnTokC); tokCnt++; + p++; + continue; + } + break; + case ' ': + cp = strchr(ScnSpecTokenMapIndex, *p); + if (!cp || *cp == '\0') { + p--; + goto word_tok; + } + tok->map = &ScnSpecTokenMap[cp - ScnSpecTokenMapIndex]; + /* increase space count used in format */ + fss->scnSpaceCount++; + /* next token */ + AllocTokenInChain(tok, fss->scnTok, fss->scnTokC); tokCnt++; + p++; + continue; + break; + default: +word_tok: + if (1) { + ClockScanToken *wordTok = tok; + if (tok > fss->scnTok && (tok-1)->map == &ScnWordTokenMap) { + wordTok = tok-1; + } + /* new word token */ + if (wordTok == tok) { + wordTok->tokWord.start = p; + wordTok->map = &ScnWordTokenMap; + AllocTokenInChain(tok, fss->scnTok, fss->scnTokC); tokCnt++; + } + if (isspace(UCHAR(*p))) { + fss->scnSpaceCount++; + } + p = TclUtfNext(p); + wordTok->tokWord.end = p; + } + break; + } + } + + /* calculate end distance value for each tokens */ + if (tok > fss->scnTok) { + unsigned int endDist = 0; + ClockScanToken *prevTok = tok-1; + + while (prevTok >= fss->scnTok) { + prevTok->endDistance = endDist; + if (prevTok->map->type != CTOKT_WORD) { + endDist += prevTok->map->minSize; + } else { + endDist += prevTok->tokWord.end - prevTok->tokWord.start; + } + prevTok--; + } + } + + /* correct count of real used tokens and free mem if desired + * (1 is acceptable delta to prevent memory fragmentation) */ + if (fss->scnTokC > tokCnt + (CLOCK_MIN_TOK_CHAIN_BLOCK_SIZE / 2)) { + if ( (tok = ckrealloc(fss->scnTok, tokCnt * sizeof(*tok))) != NULL ) { + fss->scnTok = tok; + } + } + fss->scnTokC = tokCnt; + +done: + Tcl_MutexUnlock(&ClockFmtMutex); + } + + return fss; +} + +/* + *---------------------------------------------------------------------- + */ +int +ClockScan( + register DateInfo *info, /* Date fields used for parsing & converting */ + Tcl_Obj *strObj, /* String containing the time to scan */ + ClockFmtScnCmdArgs *opts) /* Command options */ +{ + ClockClientData *dataPtr = opts->clientData; + ClockFmtScnStorage *fss; + ClockScanToken *tok; + ClockScanTokenMap *map; + register const char *p, *x, *end; + unsigned short int flags = 0; + int ret = TCL_ERROR; + + /* get localized format */ + if (ClockLocalizeFormat(opts) == NULL) { + return TCL_ERROR; + } + + if ( !(fss = ClockGetOrParseScanFormat(opts->interp, opts->formatObj)) + || !(tok = fss->scnTok) + ) { + return TCL_ERROR; + } + + /* prepare parsing */ + + yyMeridian = MER24; + + p = TclGetString(strObj); + end = p + strObj->length; + /* in strict mode - bypass spaces at begin / end only (not between tokens) */ + if (opts->flags & CLF_STRICT) { + while (p < end && isspace(UCHAR(*p))) { + p++; + } + } + yyInput = p; + /* look ahead to count spaces (bypass it by count length and distances) */ + x = end; + while (p < end) { + if (isspace(UCHAR(*p))) { + x = p++; + yySpaceCount++; + continue; + } + x = end; + p++; + } + /* ignore spaces at end */ + yySpaceCount -= (end - x); + end = x; + /* ignore mandatory spaces used in format */ + yySpaceCount -= fss->scnSpaceCount; + if (yySpaceCount < 0) { + yySpaceCount = 0; + } + info->dateStart = p = yyInput; + info->dateEnd = end; + + /* parse string */ + for (; tok->map != NULL; tok++) { + map = tok->map; + /* bypass spaces at begin of input before parsing each token */ + if ( !(opts->flags & CLF_STRICT) + && ( map->type != CTOKT_SPACE + && map->type != CTOKT_WORD + && map->type != CTOKT_CHAR ) + ) { + while (p < end && isspace(UCHAR(*p))) { + yySpaceCount--; + p++; + } + } + yyInput = p; + /* end of input string */ + if (p >= end) { + break; + } + switch (map->type) + { + case CTOKT_DIGIT: + if (1) { + int minLen, size; + int sign = 1; + if (map->flags & CLF_SIGNED) { + if (*p == '+') { yyInput = ++p; } + else + if (*p == '-') { yyInput = ++p; sign = -1; }; + } + + DetermineGreedySearchLen(opts, info, tok, &minLen, &size); + + if (size < map->minSize) { + /* missing input -> error */ + if ((map->flags & CLF_OPTIONAL)) { + continue; + } + goto not_match; + } + /* string 2 number, put number into info structure by offset */ + if (map->offs) { + p = yyInput; x = p + size; + if (!(map->flags & (CLF_LOCALSEC|CLF_POSIXSEC))) { + if (_str2int((int *)(((char *)info) + map->offs), + p, x, sign) != TCL_OK) { + goto overflow; + } + p = x; + } else { + if (_str2wideInt((Tcl_WideInt *)(((char *)info) + map->offs), + p, x, sign) != TCL_OK) { + goto overflow; + } + p = x; + } + flags = (flags & ~map->clearFlags) | map->flags; + } + } + break; + case CTOKT_PARSER: + switch (map->parser(opts, info, tok)) { + case TCL_OK: + break; + case TCL_RETURN: + if ((map->flags & CLF_OPTIONAL)) { + yyInput = p; + continue; + } + goto not_match; + break; + default: + goto done; + break; + }; + /* decrement count for possible spaces in match */ + while (p < yyInput) { + if (isspace(UCHAR(*p++))) { + yySpaceCount--; + } + } + p = yyInput; + flags = (flags & ~map->clearFlags) | map->flags; + break; + case CTOKT_SPACE: + /* at least one space */ + if (!isspace(UCHAR(*p))) { + /* unmatched -> error */ + goto not_match; + } + yySpaceCount--; + p++; + while (p < end && isspace(UCHAR(*p))) { + yySpaceCount--; + p++; + } + break; + case CTOKT_WORD: + x = FindWordEnd(tok, p, end); + if (!x) { + /* no match -> error */ + goto not_match; + } + p = x; + break; + case CTOKT_CHAR: + x = (char *)map->data; + if (*x != *p) { + /* no match -> error */ + goto not_match; + } + if (isspace(UCHAR(*x))) { + yySpaceCount--; + } + p++; + break; + } + } + /* check end was reached */ + if (p < end) { + /* something after last token - wrong format */ + goto not_match; + } + /* end of string, check only optional tokens at end, otherwise - not match */ + while (tok->map != NULL) { + if (!(opts->flags & CLF_STRICT) && (tok->map->type == CTOKT_SPACE)) { + tok++; + if (tok->map == NULL) break; + } + if (!(tok->map->flags & CLF_OPTIONAL)) { + goto not_match; + } + tok++; + } + + /* + * Invalidate result + */ + + /* seconds token (%s) take precedence over all other tokens */ + if ((opts->flags & CLF_EXTENDED) || !(flags & CLF_POSIXSEC)) { + if (flags & CLF_DATE) { + + if (!(flags & CLF_JULIANDAY)) { + info->flags |= CLF_ASSEMBLE_SECONDS|CLF_ASSEMBLE_JULIANDAY; + + /* dd precedence below ddd */ + switch (flags & (CLF_MONTH|CLF_DAYOFYEAR|CLF_DAYOFMONTH)) { + case (CLF_DAYOFYEAR|CLF_DAYOFMONTH): + /* miss month: ddd over dd (without month) */ + flags &= ~CLF_DAYOFMONTH; + case (CLF_DAYOFYEAR): + /* ddd over naked weekday */ + if (!(flags & CLF_ISO8601YEAR)) { + flags &= ~CLF_ISO8601; + } + break; + case (CLF_MONTH|CLF_DAYOFYEAR|CLF_DAYOFMONTH): + /* both available: mmdd over ddd */ + flags &= ~CLF_DAYOFYEAR; + case (CLF_MONTH|CLF_DAYOFMONTH): + case (CLF_DAYOFMONTH): + /* mmdd / dd over naked weekday */ + if (!(flags & CLF_ISO8601YEAR)) { + flags &= ~CLF_ISO8601; + } + break; + } + + /* YearWeekDay below YearMonthDay */ + if ( (flags & CLF_ISO8601) + && ( (flags & (CLF_YEAR|CLF_DAYOFYEAR)) == (CLF_YEAR|CLF_DAYOFYEAR) + || (flags & (CLF_YEAR|CLF_DAYOFMONTH|CLF_MONTH)) == (CLF_YEAR|CLF_DAYOFMONTH|CLF_MONTH) + ) + ) { + /* yy precedence below yyyy */ + if (!(flags & CLF_ISO8601CENTURY) && (flags & CLF_CENTURY)) { + /* normally precedence of ISO is higher, but no century - so put it down */ + flags &= ~CLF_ISO8601; + } + else + /* yymmdd or yyddd over naked weekday */ + if (!(flags & CLF_ISO8601YEAR)) { + flags &= ~CLF_ISO8601; + } + } + + if (!(flags & CLF_ISO8601)) { + if (yyYear < 100) { + if (!(flags & CLF_CENTURY)) { + if (yyYear >= dataPtr->yearOfCenturySwitch) { + yyYear -= 100; + } + yyYear += dataPtr->currentYearCentury; + } else { + yyYear += info->dateCentury * 100; + } + } + } else { + if (info->date.iso8601Year < 100) { + if (!(flags & CLF_ISO8601CENTURY)) { + if (info->date.iso8601Year >= dataPtr->yearOfCenturySwitch) { + info->date.iso8601Year -= 100; + } + info->date.iso8601Year += dataPtr->currentYearCentury; + } else { + info->date.iso8601Year += info->dateCentury * 100; + } + } + } + } + } + + /* if no time - reset time */ + if (!(flags & (CLF_TIME|CLF_LOCALSEC|CLF_POSIXSEC))) { + info->flags |= CLF_ASSEMBLE_SECONDS; + yydate.localSeconds = 0; + } + + if (flags & CLF_TIME) { + info->flags |= CLF_ASSEMBLE_SECONDS; + yySeconds = ToSeconds(yyHour, yyMinutes, + yySeconds, yyMeridian); + } else + if (!(flags & (CLF_LOCALSEC|CLF_POSIXSEC))) { + info->flags |= CLF_ASSEMBLE_SECONDS; + yySeconds = yydate.localSeconds % SECONDS_PER_DAY; + } + } + + /* tell caller which flags were set */ + info->flags |= flags; + + ret = TCL_OK; + goto done; + +overflow: + + Tcl_SetResult(opts->interp, "requested date too large to represent", + TCL_STATIC); + Tcl_SetErrorCode(opts->interp, "CLOCK", "dateTooLarge", NULL); + goto done; + +not_match: + + Tcl_SetResult(opts->interp, "input string does not match supplied format", + TCL_STATIC); + Tcl_SetErrorCode(opts->interp, "CLOCK", "badInputString", NULL); + +done: + + return ret; +} + +static inline int +FrmResultAllocate( + register DateFormat *dateFmt, + int len) +{ + int needed = dateFmt->output + len - dateFmt->resEnd; + if (needed >= 0) { /* >= 0 - regards NTS zero */ + int newsize = dateFmt->resEnd - dateFmt->resMem + + needed + MIN_FMT_RESULT_BLOCK_ALLOC; + char *newRes = ckrealloc(dateFmt->resMem, newsize); + if (newRes == NULL) { + return TCL_ERROR; + } + dateFmt->output = newRes + (dateFmt->output - dateFmt->resMem); + dateFmt->resMem = newRes; + dateFmt->resEnd = newRes + newsize; + } + return TCL_OK; +} + +static int +ClockFmtToken_HourAMPM_Proc( + ClockFmtScnCmdArgs *opts, + DateFormat *dateFmt, + ClockFormatToken *tok, + int *val) +{ + *val = ( ( ( *val % SECONDS_PER_DAY ) + SECONDS_PER_DAY - 3600 ) / 3600 ) % 12 + 1; + return TCL_OK; +} + +static int +ClockFmtToken_AMPM_Proc( + ClockFmtScnCmdArgs *opts, + DateFormat *dateFmt, + ClockFormatToken *tok, + int *val) +{ + Tcl_Obj *mcObj; + const char *s; + int len; + + if ((*val % SECONDS_PER_DAY) < (SECONDS_PER_DAY / 2)) { + mcObj = ClockMCGet(opts, MCLIT_AM); + } else { + mcObj = ClockMCGet(opts, MCLIT_PM); + } + if (mcObj == NULL) { + return TCL_ERROR; + } + s = TclGetString(mcObj); len = mcObj->length; + if (FrmResultAllocate(dateFmt, len) != TCL_OK) { return TCL_ERROR; }; + memcpy(dateFmt->output, s, len + 1); + if (*tok->tokWord.start == 'p') { + len = Tcl_UtfToUpper(dateFmt->output); + } + dateFmt->output += len; + + return TCL_OK; +} + +static int +ClockFmtToken_StarDate_Proc( + ClockFmtScnCmdArgs *opts, + DateFormat *dateFmt, + ClockFormatToken *tok, + int *val) + { + int fractYear; + /* Get day of year, zero based */ + int doy = dateFmt->date.dayOfYear - 1; + + /* Convert day of year to a fractional year */ + if (IsGregorianLeapYear(&dateFmt->date)) { + fractYear = 1000 * doy / 366; + } else { + fractYear = 1000 * doy / 365; + } + + /* Put together the StarDate as "Stardate %02d%03d.%1d" */ + if (FrmResultAllocate(dateFmt, 30) != TCL_OK) { return TCL_ERROR; }; + memcpy(dateFmt->output, "Stardate ", 9); + dateFmt->output += 9; + dateFmt->output = _itoaw(dateFmt->output, + dateFmt->date.year - RODDENBERRY, '0', 2); + dateFmt->output = _itoaw(dateFmt->output, + fractYear, '0', 3); + *dateFmt->output++ = '.'; + dateFmt->output = _itoaw(dateFmt->output, + dateFmt->date.localSeconds % SECONDS_PER_DAY / ( SECONDS_PER_DAY / 10 ), '0', 1); + + return TCL_OK; +} +static int +ClockFmtToken_WeekOfYear_Proc( + ClockFmtScnCmdArgs *opts, + DateFormat *dateFmt, + ClockFormatToken *tok, + int *val) +{ + int dow = dateFmt->date.dayOfWeek; + if (*tok->tokWord.start == 'U') { + if (dow == 7) { + dow = 0; + } + dow++; + } + *val = ( dateFmt->date.dayOfYear - dow + 7 ) / 7; + return TCL_OK; +} +static int +ClockFmtToken_TimeZone_Proc( + ClockFmtScnCmdArgs *opts, + DateFormat *dateFmt, + ClockFormatToken *tok, + int *val) +{ + if (*tok->tokWord.start == 'z') { + int z = dateFmt->date.tzOffset; + char sign = '+'; + if ( z < 0 ) { + z = -z; + sign = '-'; + } + if (FrmResultAllocate(dateFmt, 7) != TCL_OK) { return TCL_ERROR; }; + *dateFmt->output++ = sign; + dateFmt->output = _itoaw(dateFmt->output, z / 3600, '0', 2); + z %= 3600; + dateFmt->output = _itoaw(dateFmt->output, z / 60, '0', 2); + z %= 60; + if (z != 0) { + dateFmt->output = _itoaw(dateFmt->output, z, '0', 2); + } + } else { + Tcl_Obj * objPtr; + const char *s; int len; + /* convert seconds to local seconds to obtain tzName object */ + if (ConvertUTCToLocal(opts->clientData, opts->interp, + &dateFmt->date, opts->timezoneObj, + GREGORIAN_CHANGE_DATE) != TCL_OK) { + return TCL_ERROR; + }; + objPtr = dateFmt->date.tzName; + s = TclGetString(objPtr); + len = objPtr->length; + if (FrmResultAllocate(dateFmt, len) != TCL_OK) { return TCL_ERROR; }; + memcpy(dateFmt->output, s, len + 1); + dateFmt->output += len; + } + return TCL_OK; +} + +static int +ClockFmtToken_LocaleERA_Proc( + ClockFmtScnCmdArgs *opts, + DateFormat *dateFmt, + ClockFormatToken *tok, + int *val) +{ + Tcl_Obj *mcObj; + const char *s; + int len; + + if (dateFmt->date.era == BCE) { + mcObj = ClockMCGet(opts, MCLIT_BCE); + } else { + mcObj = ClockMCGet(opts, MCLIT_CE); + } + if (mcObj == NULL) { + return TCL_ERROR; + } + s = TclGetString(mcObj); len = mcObj->length; + if (FrmResultAllocate(dateFmt, len) != TCL_OK) { return TCL_ERROR; }; + memcpy(dateFmt->output, s, len + 1); + dateFmt->output += len; + + return TCL_OK; +} + +static int +ClockFmtToken_LocaleERAYear_Proc( + ClockFmtScnCmdArgs *opts, + DateFormat *dateFmt, + ClockFormatToken *tok, + int *val) +{ + int rowc; + Tcl_Obj **rowv; + + if (dateFmt->localeEra == NULL) { + Tcl_Obj *mcObj = ClockMCGet(opts, MCLIT_LOCALE_ERAS); + if (mcObj == NULL) { + return TCL_ERROR; + } + if (TclListObjGetElements(opts->interp, mcObj, &rowc, &rowv) != TCL_OK) { + return TCL_ERROR; + } + if (rowc != 0) { + dateFmt->localeEra = LookupLastTransition(opts->interp, + dateFmt->date.localSeconds, rowc, rowv, NULL); + } + if (dateFmt->localeEra == NULL) { + dateFmt->localeEra = (Tcl_Obj*)1; + } + } + + /* if no LOCALE_ERAS in catalog or era not found */ + if (dateFmt->localeEra == (Tcl_Obj*)1) { + if (FrmResultAllocate(dateFmt, 11) != TCL_OK) { return TCL_ERROR; }; + if (*tok->tokWord.start == 'C') { /* %EC */ + *val = dateFmt->date.year / 100; + dateFmt->output = _itoaw(dateFmt->output, + *val, '0', 2); + } else { /* %Ey */ + *val = dateFmt->date.year % 100; + dateFmt->output = _itoaw(dateFmt->output, + *val, '0', 2); + } + } else { + Tcl_Obj *objPtr; + const char *s; + int len; + if (*tok->tokWord.start == 'C') { /* %EC */ + if (Tcl_ListObjIndex(opts->interp, dateFmt->localeEra, 1, + &objPtr) != TCL_OK ) { + return TCL_ERROR; + } + } else { /* %Ey */ + if (Tcl_ListObjIndex(opts->interp, dateFmt->localeEra, 2, + &objPtr) != TCL_OK ) { + return TCL_ERROR; + } + if (Tcl_GetIntFromObj(opts->interp, objPtr, val) != TCL_OK) { + return TCL_ERROR; + } + *val = dateFmt->date.year - *val; + /* if year in locale numerals */ + if (*val >= 0 && *val < 100) { + /* year as integer */ + Tcl_Obj * mcObj = ClockMCGet(opts, MCLIT_LOCALE_NUMERALS); + if (mcObj == NULL) { + return TCL_ERROR; + } + if (Tcl_ListObjIndex(opts->interp, mcObj, *val, &objPtr) != TCL_OK) { + return TCL_ERROR; + } + } else { + /* year as integer */ + if (FrmResultAllocate(dateFmt, 11) != TCL_OK) { return TCL_ERROR; }; + dateFmt->output = _itoaw(dateFmt->output, + *val, '0', 2); + return TCL_OK; + } + } + s = TclGetString(objPtr); + len = objPtr->length; + if (FrmResultAllocate(dateFmt, len) != TCL_OK) { return TCL_ERROR; }; + memcpy(dateFmt->output, s, len + 1); + dateFmt->output += len; + } + return TCL_OK; +} + + +static const char *FmtSTokenMapIndex = + "demNbByYCHMSIklpaAuwUVzgGjJsntQ"; +static ClockFormatTokenMap FmtSTokenMap[] = { + /* %d */ + {CFMTT_INT, "0", 2, 0, 0, 0, TclOffset(DateFormat, date.dayOfMonth), NULL}, + /* %e */ + {CFMTT_INT, " ", 2, 0, 0, 0, TclOffset(DateFormat, date.dayOfMonth), NULL}, + /* %m */ + {CFMTT_INT, "0", 2, 0, 0, 0, TclOffset(DateFormat, date.month), NULL}, + /* %N */ + {CFMTT_INT, " ", 2, 0, 0, 0, TclOffset(DateFormat, date.month), NULL}, + /* %b %h */ + {CFMTT_INT, NULL, 0, CLFMT_LOCALE_INDX | CLFMT_DECR, 0, 12, TclOffset(DateFormat, date.month), + NULL, (void *)MCLIT_MONTHS_ABBREV}, + /* %B */ + {CFMTT_INT, NULL, 0, CLFMT_LOCALE_INDX | CLFMT_DECR, 0, 12, TclOffset(DateFormat, date.month), + NULL, (void *)MCLIT_MONTHS_FULL}, + /* %y */ + {CFMTT_INT, "0", 2, 0, 0, 100, TclOffset(DateFormat, date.year), NULL}, + /* %Y */ + {CFMTT_INT, "0", 4, 0, 0, 0, TclOffset(DateFormat, date.year), NULL}, + /* %C */ + {CFMTT_INT, "0", 2, 0, 100, 0, TclOffset(DateFormat, date.year), NULL}, + /* %H */ + {CFMTT_INT, "0", 2, 0, 3600, 24, TclOffset(DateFormat, date.secondOfDay), NULL}, + /* %M */ + {CFMTT_INT, "0", 2, 0, 60, 60, TclOffset(DateFormat, date.secondOfDay), NULL}, + /* %S */ + {CFMTT_INT, "0", 2, 0, 0, 60, TclOffset(DateFormat, date.secondOfDay), NULL}, + /* %I */ + {CFMTT_INT, "0", 2, CLFMT_CALC, 0, 0, TclOffset(DateFormat, date.secondOfDay), + ClockFmtToken_HourAMPM_Proc, NULL}, + /* %k */ + {CFMTT_INT, " ", 2, 0, 3600, 24, TclOffset(DateFormat, date.secondOfDay), NULL}, + /* %l */ + {CFMTT_INT, " ", 2, CLFMT_CALC, 0, 0, TclOffset(DateFormat, date.secondOfDay), + ClockFmtToken_HourAMPM_Proc, NULL}, + /* %p %P */ + {CFMTT_INT, NULL, 0, 0, 0, 0, TclOffset(DateFormat, date.secondOfDay), + ClockFmtToken_AMPM_Proc, NULL}, + /* %a */ + {CFMTT_INT, NULL, 0, CLFMT_LOCALE_INDX, 0, 7, TclOffset(DateFormat, date.dayOfWeek), + NULL, (void *)MCLIT_DAYS_OF_WEEK_ABBREV}, + /* %A */ + {CFMTT_INT, NULL, 0, CLFMT_LOCALE_INDX, 0, 7, TclOffset(DateFormat, date.dayOfWeek), + NULL, (void *)MCLIT_DAYS_OF_WEEK_FULL}, + /* %u */ + {CFMTT_INT, " ", 1, 0, 0, 0, TclOffset(DateFormat, date.dayOfWeek), NULL}, + /* %w */ + {CFMTT_INT, " ", 1, 0, 0, 7, TclOffset(DateFormat, date.dayOfWeek), NULL}, + /* %U %W */ + {CFMTT_INT, "0", 2, CLFMT_CALC, 0, 0, TclOffset(DateFormat, date.dayOfYear), + ClockFmtToken_WeekOfYear_Proc, NULL}, + /* %V */ + {CFMTT_INT, "0", 2, 0, 0, 0, TclOffset(DateFormat, date.iso8601Week), NULL}, + /* %z %Z */ + {CFMTT_INT, NULL, 0, 0, 0, 0, 0, + ClockFmtToken_TimeZone_Proc, NULL}, + /* %g */ + {CFMTT_INT, "0", 2, 0, 0, 100, TclOffset(DateFormat, date.iso8601Year), NULL}, + /* %G */ + {CFMTT_INT, "0", 4, 0, 0, 0, TclOffset(DateFormat, date.iso8601Year), NULL}, + /* %j */ + {CFMTT_INT, "0", 3, 0, 0, 0, TclOffset(DateFormat, date.dayOfYear), NULL}, + /* %J */ + {CFMTT_INT, "0", 7, 0, 0, 0, TclOffset(DateFormat, date.julianDay), NULL}, + /* %s */ + {CFMTT_WIDE, "0", 1, 0, 0, 0, TclOffset(DateFormat, date.seconds), NULL}, + /* %n */ + {CTOKT_CHAR, "\n", 0, 0, 0, 0, 0, NULL}, + /* %t */ + {CTOKT_CHAR, "\t", 0, 0, 0, 0, 0, NULL}, + /* %Q */ + {CFMTT_INT, NULL, 0, 0, 0, 0, 0, + ClockFmtToken_StarDate_Proc, NULL}, +}; +static const char *FmtSTokenMapAliasIndex[2] = { + "hPWZ", + "bpUz" +}; + +static const char *FmtETokenMapIndex = + "Eys"; +static ClockFormatTokenMap FmtETokenMap[] = { + /* %EE */ + {CFMTT_INT, NULL, 0, 0, 0, 0, TclOffset(DateFormat, date.era), + ClockFmtToken_LocaleERA_Proc, NULL}, + /* %Ey %EC */ + {CFMTT_INT, NULL, 0, 0, 0, 0, TclOffset(DateFormat, date.year), + ClockFmtToken_LocaleERAYear_Proc, NULL}, + /* %Es */ + {CFMTT_WIDE, "0", 1, 0, 0, 0, TclOffset(DateFormat, date.localSeconds), NULL}, +}; +static const char *FmtETokenMapAliasIndex[2] = { + "C", + "y" +}; + +static const char *FmtOTokenMapIndex = + "dmyHIMSuw"; +static ClockFormatTokenMap FmtOTokenMap[] = { + /* %Od %Oe */ + {CFMTT_INT, NULL, 0, CLFMT_LOCALE_INDX, 0, 100, TclOffset(DateFormat, date.dayOfMonth), + NULL, (void *)MCLIT_LOCALE_NUMERALS}, + /* %Om */ + {CFMTT_INT, NULL, 0, CLFMT_LOCALE_INDX, 0, 100, TclOffset(DateFormat, date.month), + NULL, (void *)MCLIT_LOCALE_NUMERALS}, + /* %Oy */ + {CFMTT_INT, NULL, 0, CLFMT_LOCALE_INDX, 0, 100, TclOffset(DateFormat, date.year), + NULL, (void *)MCLIT_LOCALE_NUMERALS}, + /* %OH %Ok */ + {CFMTT_INT, NULL, 0, CLFMT_LOCALE_INDX, 3600, 24, TclOffset(DateFormat, date.secondOfDay), + NULL, (void *)MCLIT_LOCALE_NUMERALS}, + /* %OI %Ol */ + {CFMTT_INT, NULL, 0, CLFMT_CALC | CLFMT_LOCALE_INDX, 0, 0, TclOffset(DateFormat, date.secondOfDay), + ClockFmtToken_HourAMPM_Proc, (void *)MCLIT_LOCALE_NUMERALS}, + /* %OM */ + {CFMTT_INT, NULL, 0, CLFMT_LOCALE_INDX, 60, 60, TclOffset(DateFormat, date.secondOfDay), + NULL, (void *)MCLIT_LOCALE_NUMERALS}, + /* %OS */ + {CFMTT_INT, NULL, 0, CLFMT_LOCALE_INDX, 0, 60, TclOffset(DateFormat, date.secondOfDay), + NULL, (void *)MCLIT_LOCALE_NUMERALS}, + /* %Ou */ + {CFMTT_INT, NULL, 0, CLFMT_LOCALE_INDX, 0, 100, TclOffset(DateFormat, date.dayOfWeek), + NULL, (void *)MCLIT_LOCALE_NUMERALS}, + /* %Ow */ + {CFMTT_INT, NULL, 0, CLFMT_LOCALE_INDX, 0, 7, TclOffset(DateFormat, date.dayOfWeek), + NULL, (void *)MCLIT_LOCALE_NUMERALS}, +}; +static const char *FmtOTokenMapAliasIndex[2] = { + "ekl", + "dHI" +}; + +static ClockFormatTokenMap FmtWordTokenMap = { + CTOKT_WORD, NULL, 0, 0, 0, 0, 0, NULL +}; + +/* + *---------------------------------------------------------------------- + */ +ClockFmtScnStorage * +ClockGetOrParseFmtFormat( + Tcl_Interp *interp, /* Tcl interpreter */ + Tcl_Obj *formatObj) /* Format container */ +{ + ClockFmtScnStorage *fss; + ClockFormatToken *tok; + + fss = Tcl_GetClockFrmScnFromObj(interp, formatObj); + if (fss == NULL) { + return NULL; + } + + /* if first time scanning - tokenize format */ + if (fss->fmtTok == NULL) { + unsigned int tokCnt; + register const char *p, *e, *cp; + + e = p = HashEntry4FmtScn(fss)->key.string; + e += strlen(p); + + /* estimate token count by % char and format length */ + fss->fmtTokC = EstimateTokenCount(p, e); + + Tcl_MutexLock(&ClockFmtMutex); + + fss->fmtTok = tok = ckalloc(sizeof(*tok) * fss->fmtTokC); + memset(tok, 0, sizeof(*(tok))); + tokCnt = 1; + while (p < e) { + switch (*p) { + case '%': + if (1) { + ClockFormatTokenMap * fmtMap = FmtSTokenMap; + const char *mapIndex = FmtSTokenMapIndex, + **aliasIndex = FmtSTokenMapAliasIndex; + if (p+1 >= e) { + goto word_tok; + } + p++; + /* try to find modifier: */ + switch (*p) { + case '%': + /* begin new word token - don't join with previous word token, + * because current mapping should be "...%%..." -> "...%..." */ + tok->map = &FmtWordTokenMap; + tok->tokWord.start = p; + tok->tokWord.end = p+1; + AllocTokenInChain(tok, fss->fmtTok, fss->fmtTokC); tokCnt++; + p++; + continue; + break; + case 'E': + fmtMap = FmtETokenMap, + mapIndex = FmtETokenMapIndex, + aliasIndex = FmtETokenMapAliasIndex; + p++; + break; + case 'O': + fmtMap = FmtOTokenMap, + mapIndex = FmtOTokenMapIndex, + aliasIndex = FmtOTokenMapAliasIndex; + p++; + break; + } + /* search direct index */ + cp = strchr(mapIndex, *p); + if (!cp || *cp == '\0') { + /* search wrapper index (multiple chars for same token) */ + cp = strchr(aliasIndex[0], *p); + if (!cp || *cp == '\0') { + p--; if (fmtMap != FmtSTokenMap) p--; + goto word_tok; + } + cp = strchr(mapIndex, aliasIndex[1][cp - aliasIndex[0]]); + if (!cp || *cp == '\0') { /* unexpected, but ... */ + #ifdef DEBUG + Tcl_Panic("token \"%c\" has no map in wrapper resolver", *p); + #endif + p--; if (fmtMap != FmtSTokenMap) p--; + goto word_tok; + } + } + tok->map = &fmtMap[cp - mapIndex]; + tok->tokWord.start = p; + /* next token */ + AllocTokenInChain(tok, fss->fmtTok, fss->fmtTokC); tokCnt++; + p++; + continue; + } + break; + default: +word_tok: + if (1) { + ClockFormatToken *wordTok = tok; + if (tok > fss->fmtTok && (tok-1)->map == &FmtWordTokenMap) { + wordTok = tok-1; + } + if (wordTok == tok) { + wordTok->tokWord.start = p; + wordTok->map = &FmtWordTokenMap; + AllocTokenInChain(tok, fss->fmtTok, fss->fmtTokC); tokCnt++; + } + p = TclUtfNext(p); + wordTok->tokWord.end = p; + } + break; + } + } + + /* correct count of real used tokens and free mem if desired + * (1 is acceptable delta to prevent memory fragmentation) */ + if (fss->fmtTokC > tokCnt + (CLOCK_MIN_TOK_CHAIN_BLOCK_SIZE / 2)) { + if ( (tok = ckrealloc(fss->fmtTok, tokCnt * sizeof(*tok))) != NULL ) { + fss->fmtTok = tok; + } + } + fss->fmtTokC = tokCnt; + +done: + Tcl_MutexUnlock(&ClockFmtMutex); + } + + return fss; +} + +/* + *---------------------------------------------------------------------- + */ +int +ClockFormat( + register DateFormat *dateFmt, /* Date fields used for parsing & converting */ + ClockFmtScnCmdArgs *opts) /* Command options */ +{ + ClockFmtScnStorage *fss; + ClockFormatToken *tok; + ClockFormatTokenMap *map; + + /* get localized format */ + if (ClockLocalizeFormat(opts) == NULL) { + return TCL_ERROR; + } + + if ( !(fss = ClockGetOrParseFmtFormat(opts->interp, opts->formatObj)) + || !(tok = fss->fmtTok) + ) { + return TCL_ERROR; + } + + /* prepare formatting */ + dateFmt->date.secondOfDay = (int)(dateFmt->date.localSeconds % SECONDS_PER_DAY); + if (dateFmt->date.secondOfDay < 0) { + dateFmt->date.secondOfDay += SECONDS_PER_DAY; + } + + /* result container object */ + dateFmt->resMem = ckalloc(MIN_FMT_RESULT_BLOCK_ALLOC); + if (dateFmt->resMem == NULL) { + return TCL_ERROR; + } + dateFmt->output = dateFmt->resMem; + dateFmt->resEnd = dateFmt->resMem + MIN_FMT_RESULT_BLOCK_ALLOC; + *dateFmt->output = '\0'; + + /* do format each token */ + for (; tok->map != NULL; tok++) { + map = tok->map; + switch (map->type) + { + case CFMTT_INT: + if (1) { + int val = (int)*(int *)(((char *)dateFmt) + map->offs); + if (map->fmtproc == NULL) { + if (map->flags & CLFMT_DECR) { + val--; + } + if (map->flags & CLFMT_INCR) { + val++; + } + if (map->divider) { + val /= map->divider; + } + if (map->divmod) { + val %= map->divmod; + } + } else { + if (map->fmtproc(opts, dateFmt, tok, &val) != TCL_OK) { + goto done; + } + /* if not calculate only (output inside fmtproc) */ + if (!(map->flags & CLFMT_CALC)) { + continue; + } + } + if (!(map->flags & CLFMT_LOCALE_INDX)) { + if (FrmResultAllocate(dateFmt, 11) != TCL_OK) { goto error; }; + if (map->width) { + dateFmt->output = _itoaw(dateFmt->output, val, *map->tostr, map->width); + } else { + dateFmt->output += sprintf(dateFmt->output, map->tostr, val); + } + } else { + const char *s; + Tcl_Obj * mcObj = ClockMCGet(opts, PTR2INT(map->data) /* mcKey */); + if (mcObj == NULL) { + goto error; + } + if ( Tcl_ListObjIndex(opts->interp, mcObj, val, &mcObj) != TCL_OK + || mcObj == NULL + ) { + goto error; + } + s = TclGetString(mcObj); + if (FrmResultAllocate(dateFmt, mcObj->length) != TCL_OK) { goto error; }; + memcpy(dateFmt->output, s, mcObj->length + 1); + dateFmt->output += mcObj->length; + } + } + break; + case CFMTT_WIDE: + if (1) { + Tcl_WideInt val = *(Tcl_WideInt *)(((char *)dateFmt) + map->offs); + if (FrmResultAllocate(dateFmt, 21) != TCL_OK) { goto error; }; + if (map->width) { + dateFmt->output = _witoaw(dateFmt->output, val, *map->tostr, map->width); + } else { + dateFmt->output += sprintf(dateFmt->output, map->tostr, val); + } + } + break; + case CTOKT_CHAR: + if (FrmResultAllocate(dateFmt, 1) != TCL_OK) { goto error; }; + *dateFmt->output++ = *map->tostr; + break; + case CFMTT_PROC: + if (map->fmtproc(opts, dateFmt, tok, NULL) != TCL_OK) { + goto error; + }; + break; + case CTOKT_WORD: + if (1) { + int len = tok->tokWord.end - tok->tokWord.start; + if (FrmResultAllocate(dateFmt, len) != TCL_OK) { goto error; }; + if (len == 1) { + *dateFmt->output++ = *tok->tokWord.start; + } else { + memcpy(dateFmt->output, tok->tokWord.start, len); + dateFmt->output += len; + } + } + break; + } + } + + goto done; + +error: + + ckfree(dateFmt->resMem); + dateFmt->resMem = NULL; + +done: + + if (dateFmt->resMem) { + Tcl_Obj * result = Tcl_NewObj(); + result->length = dateFmt->output - dateFmt->resMem; + result->bytes = NULL; + result->bytes = ckrealloc(dateFmt->resMem, result->length+1); + if (result->bytes == NULL) { + result->bytes = dateFmt->resMem; + } + result->bytes[result->length] = '\0'; + Tcl_SetObjResult(opts->interp, result); + return TCL_OK; + } + + return TCL_ERROR; +} + + +MODULE_SCOPE void +ClockFrmScnClearCaches(void) +{ + Tcl_MutexLock(&ClockFmtMutex); + /* clear caches ... */ + Tcl_MutexUnlock(&ClockFmtMutex); +} + +static void +ClockFrmScnFinalize( + ClientData clientData) /* Not used. */ +{ + Tcl_MutexLock(&ClockFmtMutex); +#if CLOCK_FMT_SCN_STORAGE_GC_SIZE > 0 + /* clear GC */ + ClockFmtScnStorage_GC.stackPtr = NULL; + ClockFmtScnStorage_GC.stackBound = NULL; + ClockFmtScnStorage_GC.count = 0; +#endif + if (initialized) { + Tcl_DeleteHashTable(&FmtScnHashTable); + initialized = 0; + } + Tcl_MutexUnlock(&ClockFmtMutex); + Tcl_MutexFinalize(&ClockFmtMutex); +} +/* + * Local Variables: + * mode: c + * c-basic-offset: 4 + * fill-column: 78 + * End: + */ diff --git a/generic/tclDate.h b/generic/tclDate.h new file mode 100644 index 0000000..e614f9d --- /dev/null +++ b/generic/tclDate.h @@ -0,0 +1,512 @@ +/* + * tclDate.h -- + * + * This header file handles common usage of clock primitives + * between tclDate.c (yacc), tclClock.c and tclClockFmt.c. + * + * Copyright (c) 2014 Serg G. Brester (aka sebres) + * + * See the file "license.terms" for information on usage and redistribution + * of this file, and for a DISCLAIMER OF ALL WARRANTIES. + */ + +#ifndef _TCLCLOCK_H +#define _TCLCLOCK_H + +/* + * Constants + */ + +#define JULIAN_DAY_POSIX_EPOCH 2440588 +#define GREGORIAN_CHANGE_DATE 2361222 +#define SECONDS_PER_DAY 86400 +#define JULIAN_SEC_POSIX_EPOCH (((Tcl_WideInt) JULIAN_DAY_POSIX_EPOCH) \ + * SECONDS_PER_DAY) +#define FOUR_CENTURIES 146097 /* days */ +#define JDAY_1_JAN_1_CE_JULIAN 1721424 +#define JDAY_1_JAN_1_CE_GREGORIAN 1721426 +#define ONE_CENTURY_GREGORIAN 36524 /* days */ +#define FOUR_YEARS 1461 /* days */ +#define ONE_YEAR 365 /* days */ + +#define RODDENBERRY 1946 /* Another epoch (Hi, Jeff!) */ + + +#define CLF_OPTIONAL (1 << 0) /* token is non mandatory */ +#define CLF_POSIXSEC (1 << 1) +#define CLF_LOCALSEC (1 << 2) +#define CLF_JULIANDAY (1 << 3) +#define CLF_TIME (1 << 4) +#define CLF_CENTURY (1 << 6) +#define CLF_DAYOFMONTH (1 << 7) +#define CLF_DAYOFYEAR (1 << 8) +#define CLF_MONTH (1 << 9) +#define CLF_YEAR (1 << 10) +#define CLF_ISO8601YEAR (1 << 12) +#define CLF_ISO8601 (1 << 13) +#define CLF_ISO8601CENTURY (1 << 14) +#define CLF_SIGNED (1 << 15) +/* On demand (lazy) assemble flags */ +#define CLF_ASSEMBLE_DATE (1 << 28) /* assemble year, month, etc. using julianDay */ +#define CLF_ASSEMBLE_JULIANDAY (1 << 29) /* assemble julianDay using year, month, etc. */ +#define CLF_ASSEMBLE_SECONDS (1 << 30) /* assemble localSeconds (and seconds at end) */ + +#define CLF_DATE (CLF_JULIANDAY | CLF_DAYOFMONTH | CLF_DAYOFYEAR | \ + CLF_MONTH | CLF_YEAR | CLF_ISO8601YEAR | CLF_ISO8601) + +/* + * Enumeration of the string literals used in [clock] + */ + +typedef enum ClockLiteral { + LIT__NIL, + LIT__DEFAULT_FORMAT, + LIT_SYSTEM, LIT_CURRENT, LIT_C, + LIT_BCE, LIT_CE, + LIT_DAYOFMONTH, LIT_DAYOFWEEK, LIT_DAYOFYEAR, + LIT_ERA, LIT_GMT, LIT_GREGORIAN, + LIT_INTEGER_VALUE_TOO_LARGE, + LIT_ISO8601WEEK, LIT_ISO8601YEAR, + LIT_JULIANDAY, LIT_LOCALSECONDS, + LIT_MONTH, + LIT_SECONDS, LIT_TZNAME, LIT_TZOFFSET, + LIT_YEAR, + LIT_TZDATA, + LIT_GETSYSTEMTIMEZONE, + LIT_SETUPTIMEZONE, + LIT_MCGET, + LIT_GETSYSTEMLOCALE, LIT_GETCURRENTLOCALE, + LIT_LOCALIZE_FORMAT, + LIT__END +} ClockLiteral; + +#define CLOCK_LITERAL_ARRAY(litarr) static const char *const litarr[] = { \ + "", \ + "%a %b %d %H:%M:%S %Z %Y", \ + "system", "current", "C", \ + "BCE", "CE", \ + "dayOfMonth", "dayOfWeek", "dayOfYear", \ + "era", ":GMT", "gregorian", \ + "integer value too large to represent", \ + "iso8601Week", "iso8601Year", \ + "julianDay", "localSeconds", \ + "month", \ + "seconds", "tzName", "tzOffset", \ + "year", \ + "::tcl::clock::TZData", \ + "::tcl::clock::GetSystemTimeZone", \ + "::tcl::clock::SetupTimeZone", \ + "::tcl::clock::mcget", \ + "::tcl::clock::GetSystemLocale", "::tcl::clock::mclocale", \ + "::tcl::clock::LocalizeFormat" \ +} + +/* + * Enumeration of the msgcat literals used in [clock] + */ + +typedef enum ClockMsgCtLiteral { + MCLIT__NIL, /* placeholder */ + MCLIT_MONTHS_FULL, MCLIT_MONTHS_ABBREV, MCLIT_MONTHS_COMB, + MCLIT_DAYS_OF_WEEK_FULL, MCLIT_DAYS_OF_WEEK_ABBREV, MCLIT_DAYS_OF_WEEK_COMB, + MCLIT_AM, MCLIT_PM, + MCLIT_LOCALE_ERAS, + MCLIT_BCE, MCLIT_CE, + MCLIT_BCE2, MCLIT_CE2, + MCLIT_BCE3, MCLIT_CE3, + MCLIT_LOCALE_NUMERALS, + MCLIT__END +} ClockMsgCtLiteral; + +#define CLOCK_LOCALE_LITERAL_ARRAY(litarr, pref) static const char *const litarr[] = { \ + pref "", \ + pref "MONTHS_FULL", pref "MONTHS_ABBREV", pref "MONTHS_COMB", \ + pref "DAYS_OF_WEEK_FULL", pref "DAYS_OF_WEEK_ABBREV", pref "DAYS_OF_WEEK_COMB", \ + pref "AM", pref "PM", \ + pref "LOCALE_ERAS", \ + pref "BCE", pref "CE", \ + pref "b.c.e.", pref "c.e.", \ + pref "b.c.", pref "a.d.", \ + pref "LOCALE_NUMERALS", \ +} + +/* + * Structure containing the fields used in [clock format] and [clock scan] + */ + +typedef struct TclDateFields { + + /* Cacheable fields: */ + + Tcl_WideInt seconds; /* Time expressed in seconds from the Posix + * epoch */ + Tcl_WideInt localSeconds; /* Local time expressed in nominal seconds + * from the Posix epoch */ + int tzOffset; /* Time zone offset in seconds east of + * Greenwich */ + int julianDay; /* Julian Day Number in local time zone */ + enum {BCE=1, CE=0} era; /* Era */ + int gregorian; /* Flag == 1 if the date is Gregorian */ + int year; /* Year of the era */ + int dayOfYear; /* Day of the year (1 January == 1) */ + int month; /* Month number */ + int dayOfMonth; /* Day of the month */ + int iso8601Year; /* ISO8601 week-based year */ + int iso8601Week; /* ISO8601 week number */ + int dayOfWeek; /* Day of the week */ + int hour; /* Hours of day (in-between time only calculation) */ + int minutes; /* Minutes of day (in-between time only calculation) */ + int secondOfDay; /* Seconds of day (in-between time only calculation) */ + + /* Non cacheable fields: */ + + Tcl_Obj *tzName; /* Name (or corresponding DST-abbreviation) of the + * time zone, if set the refCount is incremented */ +} TclDateFields; + +#define ClockCacheableDateFieldsSize \ + TclOffset(TclDateFields, tzName) + +/* + * Structure contains return parsed fields. + */ + +typedef struct DateInfo { + const char *dateStart; + const char *dateInput; + const char *dateEnd; + + TclDateFields date; + + int flags; + + int dateHaveDate; + + int dateMeridian; + int dateHaveTime; + + int dateTimezone; + int dateDSTmode; + int dateHaveZone; + + int dateRelMonth; + int dateRelDay; + int dateRelSeconds; + int dateHaveRel; + + int dateMonthOrdinalIncr; + int dateMonthOrdinal; + int dateHaveOrdinalMonth; + + int dateDayOrdinal; + int dateDayNumber; + int dateHaveDay; + + int *dateRelPointer; + + int dateSpaceCount; + int dateDigitCount; + + int dateCentury; + + Tcl_Obj* messages; /* Error messages */ + const char* separatrix; /* String separating messages */ +} DateInfo; + +#define yydate (info->date) /* Date fields used for converting */ + +#define yyDay (info->date.dayOfMonth) +#define yyMonth (info->date.month) +#define yyYear (info->date.year) + +#define yyHour (info->date.hour) +#define yyMinutes (info->date.minutes) +#define yySeconds (info->date.secondOfDay) + +#define yyDSTmode (info->dateDSTmode) +#define yyDayOrdinal (info->dateDayOrdinal) +#define yyDayNumber (info->dateDayNumber) +#define yyMonthOrdinalIncr (info->dateMonthOrdinalIncr) +#define yyMonthOrdinal (info->dateMonthOrdinal) +#define yyHaveDate (info->dateHaveDate) +#define yyHaveDay (info->dateHaveDay) +#define yyHaveOrdinalMonth (info->dateHaveOrdinalMonth) +#define yyHaveRel (info->dateHaveRel) +#define yyHaveTime (info->dateHaveTime) +#define yyHaveZone (info->dateHaveZone) +#define yyTimezone (info->dateTimezone) +#define yyMeridian (info->dateMeridian) +#define yyRelMonth (info->dateRelMonth) +#define yyRelDay (info->dateRelDay) +#define yyRelSeconds (info->dateRelSeconds) +#define yyRelPointer (info->dateRelPointer) +#define yyInput (info->dateInput) +#define yyDigitCount (info->dateDigitCount) +#define yySpaceCount (info->dateSpaceCount) + +static inline void +ClockInitDateInfo(DateInfo *info) { + memset(info, 0, sizeof(DateInfo)); +} + +/* + * Structure containing the command arguments supplied to [clock format] and [clock scan] + */ + +#define CLF_EXTENDED (1 << 4) +#define CLF_STRICT (1 << 8) +#define CLF_LOCALE_USED (1 << 15) + +typedef struct ClockFmtScnCmdArgs { + ClientData clientData; /* Opaque pointer to literal pool, etc. */ + Tcl_Interp *interp; /* Tcl interpreter */ + + Tcl_Obj *formatObj; /* Format */ + Tcl_Obj *localeObj; /* Name of the locale where the time will be expressed. */ + Tcl_Obj *timezoneObj; /* Default time zone in which the time will be expressed */ + Tcl_Obj *baseObj; /* Base (scan and add) or clockValue (format) */ + int flags; /* Flags control scanning */ + + Tcl_Obj *mcDictObj; /* Current dictionary of tcl::clock package for given localeObj*/ +} ClockFmtScnCmdArgs; + +/* + * Structure containing the client data for [clock] + */ + +typedef struct ClockClientData { + size_t refCount; /* Number of live references. */ + Tcl_Obj **literals; /* Pool of object literals (common, locale independent). */ + Tcl_Obj **mcLiterals; /* Msgcat object literals with mc-keys for search with locale. */ + Tcl_Obj **mcLitIdxs; /* Msgcat object indices prefixed with _IDX_, + * used for quick dictionary search */ + + /* Cache for current clock parameters, imparted via "configure" */ + unsigned long LastTZEpoch; + int currentYearCentury; + int yearOfCenturySwitch; + Tcl_Obj *SystemTimeZone; + Tcl_Obj *SystemSetupTZData; + Tcl_Obj *GMTSetupTimeZone; + Tcl_Obj *GMTSetupTZData; + Tcl_Obj *AnySetupTimeZone; + Tcl_Obj *AnySetupTZData; + Tcl_Obj *LastUnnormSetupTimeZone; + Tcl_Obj *LastSetupTimeZone; + Tcl_Obj *LastSetupTZData; + + Tcl_Obj *CurrentLocale; + Tcl_Obj *CurrentLocaleDict; + Tcl_Obj *LastUnnormUsedLocale; + Tcl_Obj *LastUsedLocale; + Tcl_Obj *LastUsedLocaleDict; + + /* Cache for last base (last-second fast convert if base/tz not changed) */ + struct { + Tcl_Obj *timezoneObj; + TclDateFields Date; + } lastBase; + /* Las-period cache for fast UTC2Local conversion */ + struct { + /* keys */ + Tcl_Obj *timezoneObj; + int changeover; + Tcl_WideInt seconds; + Tcl_WideInt rangesVal[2]; /* Bounds for cached time zone offset */ + /* values */ + int tzOffset; + Tcl_Obj *tzName; + } UTC2Local; + /* Las-period cache for fast Local2UTC conversion */ + struct { + /* keys */ + Tcl_Obj *timezoneObj; + int changeover; + Tcl_WideInt localSeconds; + Tcl_WideInt rangesVal[2]; /* Bounds for cached time zone offset */ + /* values */ + int tzOffset; + } Local2UTC; +} ClockClientData; + +#define ClockDefaultYearCentury 2000 +#define ClockDefaultCenturySwitch 38 + +/* + * Meridian: am, pm, or 24-hour style. + */ + +typedef enum _MERIDIAN { + MERam, MERpm, MER24 +} MERIDIAN; + +/* + * Clock scan and format facilities. + */ + +#define CLOCK_FMT_SCN_STORAGE_GC_SIZE 32 + +#define CLOCK_MIN_TOK_CHAIN_BLOCK_SIZE 2 + +typedef struct ClockScanToken ClockScanToken; + + +typedef int ClockScanTokenProc( + ClockFmtScnCmdArgs *opts, + DateInfo *info, + ClockScanToken *tok); + + +typedef enum _CLCKTOK_TYPE { + CTOKT_DIGIT = 1, CTOKT_PARSER, CTOKT_SPACE, CTOKT_WORD, CTOKT_CHAR, + CFMTT_INT, CFMTT_WIDE, CFMTT_PROC +} CLCKTOK_TYPE; + +typedef struct ClockScanTokenMap { + unsigned short int type; + unsigned short int flags; + unsigned short int clearFlags; + unsigned short int minSize; + unsigned short int maxSize; + unsigned short int offs; + ClockScanTokenProc *parser; + void *data; +} ClockScanTokenMap; + +typedef struct ClockScanToken { + ClockScanTokenMap *map; + struct { + const char *start; + const char *end; + } tokWord; + unsigned short int endDistance; + unsigned short int lookAhMin; + unsigned short int lookAhMax; + unsigned short int lookAhTok; +} ClockScanToken; + + +#define MIN_FMT_RESULT_BLOCK_ALLOC 200 + +typedef struct DateFormat { + char *resMem; + char *resEnd; + char *output; + + TclDateFields date; + + Tcl_Obj *localeEra; +} DateFormat; + +#define CLFMT_INCR (1 << 3) +#define CLFMT_DECR (1 << 4) +#define CLFMT_CALC (1 << 5) +#define CLFMT_LOCALE_INDX (1 << 8) + +typedef struct ClockFormatToken ClockFormatToken; + +typedef int ClockFormatTokenProc( + ClockFmtScnCmdArgs *opts, + DateFormat *dateFmt, + ClockFormatToken *tok, + int *val); + +typedef struct ClockFormatTokenMap { + unsigned short int type; + const char *tostr; + unsigned short int width; + unsigned short int flags; + unsigned short int divider; + unsigned short int divmod; + unsigned short int offs; + ClockFormatTokenProc *fmtproc; + void *data; +} ClockFormatTokenMap; +typedef struct ClockFormatToken { + ClockFormatTokenMap *map; + struct { + const char *start; + const char *end; + } tokWord; +} ClockFormatToken; + + +typedef struct ClockFmtScnStorage ClockFmtScnStorage; + +typedef struct ClockFmtScnStorage { + int objRefCount; /* Reference count shared across threads */ + ClockScanToken *scnTok; + unsigned int scnTokC; + unsigned int scnSpaceCount; /* Count of mandatory spaces used in format */ + ClockFormatToken *fmtTok; + unsigned int fmtTokC; +#if CLOCK_FMT_SCN_STORAGE_GC_SIZE > 0 + ClockFmtScnStorage *nextPtr; + ClockFmtScnStorage *prevPtr; +#endif +#if 0 + +Tcl_HashEntry hashEntry /* ClockFmtScnStorage is a derivate of Tcl_HashEntry, + * stored by offset +sizeof(self) */ +#endif +} ClockFmtScnStorage; + +/* + * Prototypes of module functions. + */ + +MODULE_SCOPE int ToSeconds(int Hours, int Minutes, + int Seconds, MERIDIAN Meridian); +MODULE_SCOPE int IsGregorianLeapYear(TclDateFields *); +MODULE_SCOPE void + GetJulianDayFromEraYearWeekDay( + TclDateFields *fields, int changeover); +MODULE_SCOPE void + GetJulianDayFromEraYearMonthDay( + TclDateFields *fields, int changeover); +MODULE_SCOPE void + GetJulianDayFromEraYearDay( + TclDateFields *fields, int changeover); +MODULE_SCOPE int ConvertUTCToLocal(ClientData clientData, Tcl_Interp *, + TclDateFields *, Tcl_Obj *timezoneObj, int); +MODULE_SCOPE Tcl_Obj * + LookupLastTransition(Tcl_Interp *, Tcl_WideInt, + int, Tcl_Obj *const *, Tcl_WideInt rangesVal[2]); + +MODULE_SCOPE int TclClockFreeScan(Tcl_Interp *interp, DateInfo *info); + +/* tclClock.c module declarations */ + +MODULE_SCOPE Tcl_Obj * + ClockSetupTimeZone(ClientData clientData, + Tcl_Interp *interp, Tcl_Obj *timezoneObj); + +MODULE_SCOPE Tcl_Obj * + ClockMCDict(ClockFmtScnCmdArgs *opts); +MODULE_SCOPE Tcl_Obj * + ClockMCGet(ClockFmtScnCmdArgs *opts, int mcKey); +MODULE_SCOPE Tcl_Obj * + ClockMCGetIdx(ClockFmtScnCmdArgs *opts, int mcKey); +MODULE_SCOPE int ClockMCSetIdx(ClockFmtScnCmdArgs *opts, int mcKey, + Tcl_Obj *valObj); + +/* tclClockFmt.c module declarations */ + +MODULE_SCOPE Tcl_Obj* + ClockFrmObjGetLocFmtKey(Tcl_Interp *interp, + Tcl_Obj *objPtr); + +MODULE_SCOPE ClockFmtScnStorage * + Tcl_GetClockFrmScnFromObj(Tcl_Interp *interp, + Tcl_Obj *objPtr); +MODULE_SCOPE Tcl_Obj * + ClockLocalizeFormat(ClockFmtScnCmdArgs *opts); + +MODULE_SCOPE int ClockScan(register DateInfo *info, + Tcl_Obj *strObj, ClockFmtScnCmdArgs *opts); + +MODULE_SCOPE int ClockFormat(register DateFormat *dateFmt, + ClockFmtScnCmdArgs *opts); + +MODULE_SCOPE void ClockFrmScnClearCaches(void); + +#endif /* _TCLCLOCK_H */ diff --git a/generic/tclStrIdxTree.c b/generic/tclStrIdxTree.c new file mode 100644 index 0000000..d9b5da0 --- /dev/null +++ b/generic/tclStrIdxTree.c @@ -0,0 +1,520 @@ +/* + * tclStrIdxTree.c -- + * + * Contains the routines for managing string index tries in Tcl. + * + * This code is back-ported from the tclSE engine, by Serg G. Brester. + * + * Copyright (c) 2016 by Sergey G. Brester aka sebres. All rights reserved. + * + * See the file "license.terms" for information on usage and redistribution of + * this file, and for a DISCLAIMER OF ALL WARRANTIES. + * + * ----------------------------------------------------------------------- + * + * String index tries are prepaired structures used for fast greedy search of the string + * (index) by unique string prefix as key. + * + * Index tree build for two lists together can be explained in the following datagram + * + * Lists: + * + * {Januar Februar Maerz April Mai Juni Juli August September Oktober November Dezember} + * {Jnr Fbr Mrz Apr Mai Jni Jli Agt Spt Okt Nvb Dzb} + * + * Index-Tree: + * + * j -1 * ... + * anuar 0 * + * u -1 * a -1 + * ni 5 * pril 3 + * li 6 * ugust 7 + * n -1 * gt 7 + * r 0 * s 8 + * i 5 * eptember 8 + * li 6 * pt 8 + * f 1 * oktober 9 + * ebruar 1 * n 10 + * br 1 * ovember 10 + * m -1 * vb 10 + * a -1 * d 11 + * erz 2 * ezember 11 + * i 4 * zb 11 + * rz 2 * + * ... + * + * Thereby value -1 shows pure group items (corresponding ambigous matches). + * + * StrIdxTree's are very fast, so: + * build of above-mentioned tree takes about 10 microseconds. + * search of string index in this tree takes fewer as 0.1 microseconds. + * + */ + +#include "tclInt.h" +#include "tclStrIdxTree.h" + + +/* + *---------------------------------------------------------------------- + * + * TclStrIdxTreeSearch -- + * + * Find largest part of string "start" in indexed tree (case sensitive). + * + * Also used for building of string index tree. + * + * Results: + * Return position of UTF character in start after last equal character + * and found item (with parent). + * + * Side effects: + * None. + * + *---------------------------------------------------------------------- + */ + +MODULE_SCOPE const char* +TclStrIdxTreeSearch( + TclStrIdxTree **foundParent, /* Return value of found sub tree (used for tree build) */ + TclStrIdx **foundItem, /* Return value of found item */ + TclStrIdxTree *tree, /* Index tree will be browsed */ + const char *start, /* UTF string to find in tree */ + const char *end) /* End of string */ +{ + TclStrIdxTree *parent = tree, *prevParent = tree; + TclStrIdx *item = tree->firstPtr, *prevItem = NULL; + const char *s = start, *f, *cin, *cinf, *prevf; + int offs = 0; + + if (item == NULL) { + goto done; + } + + /* search in tree */ + do { + cinf = cin = TclGetString(item->key) + offs; + f = TclUtfFindEqualNCInLwr(s, end, cin, cin + item->length, &cinf); + /* if something was found */ + if (f > s) { + /* if whole string was found */ + if (f >= end) { + start = f; + goto done; + }; + /* set new offset and shift start string */ + offs += cinf - cin; + s = f; + /* if match item, go deeper as long as possible */ + if (offs >= item->length && item->childTree.firstPtr) { + /* save previuosly found item (if not ambigous) for + * possible fallback (few greedy match) */ + if (item->value != -1) { + prevf = f; + prevItem = item; + prevParent = parent; + } + parent = &item->childTree; + item = item->childTree.firstPtr; + continue; + } + /* no children - return this item and current chars found */ + start = f; + goto done; + } + + item = item->nextPtr; + + } while (item != NULL); + + /* fallback (few greedy match) not ambigous (has a value) */ + if (prevItem != NULL) { + item = prevItem; + parent = prevParent; + start = prevf; + } + +done: + + if (foundParent) + *foundParent = parent; + if (foundItem) + *foundItem = item; + return start; +} + +MODULE_SCOPE void +TclStrIdxTreeFree( + TclStrIdx *tree) +{ + while (tree != NULL) { + TclStrIdx *t; + Tcl_DecrRefCount(tree->key); + if (tree->childTree.firstPtr != NULL) { + TclStrIdxTreeFree(tree->childTree.firstPtr); + } + t = tree, tree = tree->nextPtr; + ckfree(t); + } +} + +/* + * Several bidirectional list primitives + */ +inline void +TclStrIdxTreeInsertBranch( + TclStrIdxTree *parent, + register TclStrIdx *item, + register TclStrIdx *child) +{ + if (parent->firstPtr == child) + parent->firstPtr = item; + if (parent->lastPtr == child) + parent->lastPtr = item; + if ( (item->nextPtr = child->nextPtr) ) { + item->nextPtr->prevPtr = item; + child->nextPtr = NULL; + } + if ( (item->prevPtr = child->prevPtr) ) { + item->prevPtr->nextPtr = item; + child->prevPtr = NULL; + } + item->childTree.firstPtr = child; + item->childTree.lastPtr = child; +} + +inline void +TclStrIdxTreeAppend( + register TclStrIdxTree *parent, + register TclStrIdx *item) +{ + if (parent->lastPtr != NULL) { + parent->lastPtr->nextPtr = item; + } + item->prevPtr = parent->lastPtr; + item->nextPtr = NULL; + parent->lastPtr = item; + if (parent->firstPtr == NULL) { + parent->firstPtr = item; + } +} + + +/* + *---------------------------------------------------------------------- + * + * TclStrIdxTreeBuildFromList -- + * + * Build or extend string indexed tree from tcl list. + * + * Important: by multiple lists, optimal tree can be created only if list with + * larger strings used firstly. + * + * Results: + * Returns a standard Tcl result. + * + * Side effects: + * None. + * + *---------------------------------------------------------------------- + */ + +MODULE_SCOPE int +TclStrIdxTreeBuildFromList( + TclStrIdxTree *idxTree, + int lstc, + Tcl_Obj **lstv) +{ + Tcl_Obj **lwrv; + int i, ret = TCL_ERROR; + const char *s, *e, *f; + TclStrIdx *item; + + /* create lowercase reflection of the list keys */ + + lwrv = ckalloc(sizeof(Tcl_Obj*) * lstc); + if (lwrv == NULL) { + return TCL_ERROR; + } + for (i = 0; i < lstc; i++) { + lwrv[i] = Tcl_DuplicateObj(lstv[i]); + if (lwrv[i] == NULL) { + return TCL_ERROR; + } + Tcl_IncrRefCount(lwrv[i]); + lwrv[i]->length = Tcl_UtfToLower(TclGetString(lwrv[i])); + } + + /* build index tree of the list keys */ + for (i = 0; i < lstc; i++) { + TclStrIdxTree *foundParent = idxTree; + e = s = TclGetString(lwrv[i]); + e += lwrv[i]->length; + + /* ignore empty values (impossible to index it) */ + if (lwrv[i]->length == 0) continue; + + item = NULL; + if (idxTree->firstPtr != NULL) { + TclStrIdx *foundItem; + f = TclStrIdxTreeSearch(&foundParent, &foundItem, + idxTree, s, e); + /* if common prefix was found */ + if (f > s) { + /* ignore element if fulfilled or ambigous */ + if (f == e) { + continue; + } + /* if shortest key was found with the same value, + * just replace its current key with longest key */ + if ( foundItem->value == i + && foundItem->length < lwrv[i]->length + && foundItem->childTree.firstPtr == NULL + ) { + Tcl_SetObjRef(foundItem->key, lwrv[i]); + foundItem->length = lwrv[i]->length; + continue; + } + /* split tree (e. g. j->(jan,jun) + jul == j->(jan,ju->(jun,jul)) ) + * but don't split by fulfilled child of found item ( ii->iii->iiii ) */ + if (foundItem->length != (f - s)) { + /* first split found item (insert one between parent and found + new one) */ + item = ckalloc(sizeof(*item)); + if (item == NULL) { + goto done; + } + Tcl_InitObjRef(item->key, foundItem->key); + item->length = f - s; + /* set value or mark as ambigous if not the same value of both */ + item->value = (foundItem->value == i) ? i : -1; + /* insert group item between foundParent and foundItem */ + TclStrIdxTreeInsertBranch(foundParent, item, foundItem); + foundParent = &item->childTree; + } else { + /* the new item should be added as child of found item */ + foundParent = &foundItem->childTree; + } + } + } + /* append item at end of found parent */ + item = ckalloc(sizeof(*item)); + if (item == NULL) { + goto done; + } + item->childTree.lastPtr = item->childTree.firstPtr = NULL; + Tcl_InitObjRef(item->key, lwrv[i]); + item->length = lwrv[i]->length; + item->value = i; + TclStrIdxTreeAppend(foundParent, item); + }; + + ret = TCL_OK; + +done: + + if (lwrv != NULL) { + for (i = 0; i < lstc; i++) { + Tcl_DecrRefCount(lwrv[i]); + } + ckfree(lwrv); + } + + if (ret != TCL_OK) { + if (idxTree->firstPtr != NULL) { + TclStrIdxTreeFree(idxTree->firstPtr); + } + } + + return ret; +} + + +static void +StrIdxTreeObj_DupIntRepProc(Tcl_Obj *srcPtr, Tcl_Obj *copyPtr); +static void +StrIdxTreeObj_FreeIntRepProc(Tcl_Obj *objPtr); +static void +StrIdxTreeObj_UpdateStringProc(Tcl_Obj *objPtr); + +Tcl_ObjType StrIdxTreeObjType = { + "str-idx-tree", /* name */ + StrIdxTreeObj_FreeIntRepProc, /* freeIntRepProc */ + StrIdxTreeObj_DupIntRepProc, /* dupIntRepProc */ + StrIdxTreeObj_UpdateStringProc, /* updateStringProc */ + NULL /* setFromAnyProc */ +}; + +MODULE_SCOPE Tcl_Obj* +TclStrIdxTreeNewObj() +{ + Tcl_Obj *objPtr = Tcl_NewObj(); + objPtr->internalRep.twoPtrValue.ptr1 = NULL; + objPtr->internalRep.twoPtrValue.ptr2 = NULL; + objPtr->typePtr = &StrIdxTreeObjType; + /* return tree root in internal representation */ + return objPtr; +} + +static void +StrIdxTreeObj_DupIntRepProc(Tcl_Obj *srcPtr, Tcl_Obj *copyPtr) +{ + /* follow links (smart pointers) */ + if ( srcPtr->internalRep.twoPtrValue.ptr1 != NULL + && srcPtr->internalRep.twoPtrValue.ptr2 == NULL + ) { + srcPtr = (Tcl_Obj*)srcPtr->internalRep.twoPtrValue.ptr1; + } + /* create smart pointer to it (ptr1 != NULL, ptr2 = NULL) */ + Tcl_InitObjRef(*((Tcl_Obj **)©Ptr->internalRep.twoPtrValue.ptr1), + srcPtr); + copyPtr->internalRep.twoPtrValue.ptr2 = NULL; + copyPtr->typePtr = &StrIdxTreeObjType; +} + +static void +StrIdxTreeObj_FreeIntRepProc(Tcl_Obj *objPtr) +{ + /* follow links (smart pointers) */ + if ( objPtr->internalRep.twoPtrValue.ptr1 != NULL + && objPtr->internalRep.twoPtrValue.ptr2 == NULL + ) { + /* is a link */ + Tcl_UnsetObjRef(*((Tcl_Obj **)&objPtr->internalRep.twoPtrValue.ptr1)); + } else { + /* is a tree */ + TclStrIdxTree *tree = (TclStrIdxTree*)&objPtr->internalRep.twoPtrValue.ptr1; + if (tree->firstPtr != NULL) { + TclStrIdxTreeFree(tree->firstPtr); + } + objPtr->internalRep.twoPtrValue.ptr1 = NULL; + objPtr->internalRep.twoPtrValue.ptr2 = NULL; + } + objPtr->typePtr = NULL; +}; + +static void +StrIdxTreeObj_UpdateStringProc(Tcl_Obj *objPtr) +{ + /* currently only dummy empty string possible */ + objPtr->length = 0; + objPtr->bytes = &tclEmptyString; +}; + +MODULE_SCOPE TclStrIdxTree * +TclStrIdxTreeGetFromObj(Tcl_Obj *objPtr) { + /* follow links (smart pointers) */ + if (objPtr->typePtr != &StrIdxTreeObjType) { + return NULL; + } + if ( objPtr->internalRep.twoPtrValue.ptr1 != NULL + && objPtr->internalRep.twoPtrValue.ptr2 == NULL + ) { + objPtr = (Tcl_Obj*)objPtr->internalRep.twoPtrValue.ptr1; + } + /* return tree root in internal representation */ + return (TclStrIdxTree*)&objPtr->internalRep.twoPtrValue.ptr1; +} + +/* + * Several debug primitives + */ +#if 0 +/* currently unused, debug resp. test purposes only */ + +void +TclStrIdxTreePrint( + Tcl_Interp *interp, + TclStrIdx *tree, + int offs) +{ + Tcl_Obj *obj[2]; + const char *s; + Tcl_InitObjRef(obj[0], Tcl_NewStringObj("::puts", -1)); + while (tree != NULL) { + s = TclGetString(tree->key) + offs; + Tcl_InitObjRef(obj[1], Tcl_ObjPrintf("%*s%.*s\t:%d", + offs, "", tree->length - offs, s, tree->value)); + Tcl_PutsObjCmd(NULL, interp, 2, obj); + Tcl_UnsetObjRef(obj[1]); + if (tree->childTree.firstPtr != NULL) { + TclStrIdxTreePrint(interp, tree->childTree.firstPtr, tree->length); + } + tree = tree->nextPtr; + } + Tcl_UnsetObjRef(obj[0]); +} + + +MODULE_SCOPE int +TclStrIdxTreeTestObjCmd( + ClientData clientData, Tcl_Interp *interp, + int objc, Tcl_Obj *const objv[]) +{ + const char *cs, *cin, *ret; + + static const char *const options[] = { + "index", "puts-index", "findequal", + NULL + }; + enum optionInd { + O_INDEX, O_PUTS_INDEX, O_FINDEQUAL + }; + int optionIndex; + + if (objc < 2) { + Tcl_SetResult(interp, "wrong # args", TCL_STATIC); + return TCL_ERROR; + } + if (Tcl_GetIndexFromObj(interp, objv[1], options, + "option", 0, &optionIndex) != TCL_OK) { + Tcl_SetErrorCode(interp, "CLOCK", "badOption", + Tcl_GetString(objv[1]), NULL); + return TCL_ERROR; + } + switch (optionIndex) { + case O_FINDEQUAL: + if (objc < 4) { + Tcl_SetResult(interp, "wrong # args", TCL_STATIC); + return TCL_ERROR; + } + cs = TclGetString(objv[2]); + cin = TclGetString(objv[3]); + ret = TclUtfFindEqual( + cs, cs + objv[1]->length, cin, cin + objv[2]->length); + Tcl_SetObjResult(interp, Tcl_NewIntObj(ret - cs)); + break; + case O_INDEX: + case O_PUTS_INDEX: + + if (1) { + Tcl_Obj **lstv; + int i, lstc; + TclStrIdxTree idxTree = {NULL, NULL}; + i = 1; + while (++i < objc) { + if (TclListObjGetElements(interp, objv[i], + &lstc, &lstv) != TCL_OK) { + return TCL_ERROR; + }; + TclStrIdxTreeBuildFromList(&idxTree, lstc, lstv); + } + if (optionIndex == O_PUTS_INDEX) { + TclStrIdxTreePrint(interp, idxTree.firstPtr, 0); + } + TclStrIdxTreeFree(idxTree.firstPtr); + } + break; + } + + return TCL_OK; +} + +#endif + +/* + * Local Variables: + * mode: c + * c-basic-offset: 4 + * fill-column: 78 + * End: + */ diff --git a/generic/tclStrIdxTree.h b/generic/tclStrIdxTree.h new file mode 100644 index 0000000..305053c --- /dev/null +++ b/generic/tclStrIdxTree.h @@ -0,0 +1,169 @@ +/* + * tclStrIdxTree.h -- + * + * Declarations of string index tries and other primitives currently + * back-ported from tclSE. + * + * Copyright (c) 2016 Serg G. Brester (aka sebres) + * + * See the file "license.terms" for information on usage and redistribution + * of this file, and for a DISCLAIMER OF ALL WARRANTIES. + */ + +#ifndef _TCLSTRIDXTREE_H +#define _TCLSTRIDXTREE_H + + +/* + * Main structures declarations of index tree and entry + */ + +typedef struct TclStrIdxTree { + struct TclStrIdx *firstPtr; + struct TclStrIdx *lastPtr; +} TclStrIdxTree; + +typedef struct TclStrIdx { + struct TclStrIdxTree childTree; + struct TclStrIdx *nextPtr; + struct TclStrIdx *prevPtr; + Tcl_Obj *key; + int length; + int value; +} TclStrIdx; + + +/* + *---------------------------------------------------------------------- + * + * TclUtfFindEqual, TclUtfFindEqualNC -- + * + * Find largest part of string cs in string cin (case sensitive and not). + * + * Results: + * Return position of UTF character in cs after last equal character. + * + * Side effects: + * None. + * + *---------------------------------------------------------------------- + */ + +static inline const char * +TclUtfFindEqual( + register const char *cs, /* UTF string to find in cin. */ + register const char *cse, /* End of cs */ + register const char *cin, /* UTF string will be browsed. */ + register const char *cine) /* End of cin */ +{ + register const char *ret = cs; + Tcl_UniChar ch1, ch2; + do { + cs += TclUtfToUniChar(cs, &ch1); + cin += TclUtfToUniChar(cin, &ch2); + if (ch1 != ch2) break; + } while ((ret = cs) < cse && cin < cine); + return ret; +} + +static inline const char * +TclUtfFindEqualNC( + register const char *cs, /* UTF string to find in cin. */ + register const char *cse, /* End of cs */ + register const char *cin, /* UTF string will be browsed. */ + register const char *cine, /* End of cin */ + const char **cinfnd) /* Return position in cin */ +{ + register const char *ret = cs; + Tcl_UniChar ch1, ch2; + do { + cs += TclUtfToUniChar(cs, &ch1); + cin += TclUtfToUniChar(cin, &ch2); + if (ch1 != ch2) { + ch1 = Tcl_UniCharToLower(ch1); + ch2 = Tcl_UniCharToLower(ch2); + if (ch1 != ch2) break; + } + *cinfnd = cin; + } while ((ret = cs) < cse && cin < cine); + return ret; +} + +static inline const char * +TclUtfFindEqualNCInLwr( + register const char *cs, /* UTF string (in anycase) to find in cin. */ + register const char *cse, /* End of cs */ + register const char *cin, /* UTF string (in lowercase) will be browsed. */ + register const char *cine, /* End of cin */ + const char **cinfnd) /* Return position in cin */ +{ + register const char *ret = cs; + Tcl_UniChar ch1, ch2; + do { + cs += TclUtfToUniChar(cs, &ch1); + cin += TclUtfToUniChar(cin, &ch2); + if (ch1 != ch2) { + ch1 = Tcl_UniCharToLower(ch1); + if (ch1 != ch2) break; + } + *cinfnd = cin; + } while ((ret = cs) < cse && cin < cine); + return ret; +} + +static inline const char * +TclUtfNext( + register const char *src) /* The current location in the string. */ +{ + if (((unsigned char) *(src)) < 0xC0) { + return ++src; + } else { + Tcl_UniChar ch; + return src + TclUtfToUniChar(src, &ch); + } +} + + +/* + * Primitives to safe set, reset and free references. + */ + +#define Tcl_UnsetObjRef(obj) \ + if (obj != NULL) { Tcl_DecrRefCount(obj); obj = NULL; } +#define Tcl_InitObjRef(obj, val) \ + obj = val; if (obj) { Tcl_IncrRefCount(obj); } +#define Tcl_SetObjRef(obj, val) \ +if (1) { \ + Tcl_Obj *nval = val; \ + if (obj != nval) { \ + Tcl_Obj *prev = obj; \ + Tcl_InitObjRef(obj, nval); \ + if (prev != NULL) { Tcl_DecrRefCount(prev); }; \ + } \ +} + +/* + * Prototypes of module functions. + */ + +MODULE_SCOPE const char* + TclStrIdxTreeSearch(TclStrIdxTree **foundParent, + TclStrIdx **foundItem, TclStrIdxTree *tree, + const char *start, const char *end); + +MODULE_SCOPE int TclStrIdxTreeBuildFromList(TclStrIdxTree *idxTree, + int lstc, Tcl_Obj **lstv); + +MODULE_SCOPE Tcl_Obj* + TclStrIdxTreeNewObj(); + +MODULE_SCOPE TclStrIdxTree* + TclStrIdxTreeGetFromObj(Tcl_Obj *objPtr); + +#if 1 + +MODULE_SCOPE int TclStrIdxTreeTestObjCmd(ClientData, Tcl_Interp *, + int, Tcl_Obj *const objv[]); +#endif + +#endif /* _TCLSTRIDXTREE_H */ diff --git a/tests-perf/clock.perf.tcl b/tests-perf/clock.perf.tcl new file mode 100644 index 0000000..733db1a --- /dev/null +++ b/tests-perf/clock.perf.tcl @@ -0,0 +1,385 @@ +#!/usr/bin/tclsh +# ------------------------------------------------------------------------ +# +# test-performance.tcl -- +# +# This file provides common performance tests for comparison of tcl-speed +# degradation by switching between branches. +# (currently for clock ensemble only) +# +# ------------------------------------------------------------------------ +# +# Copyright (c) 2014 Serg G. Brester (aka sebres) +# +# See the file "license.terms" for information on usage and redistribution +# of this file. +# + + +## set testing defaults: +set ::env(TCL_TZ) :CET + +# warm-up interpeter compiler env, clock platform-related features, +# calibrate timerate measurement functionality: +puts -nonewline "Calibration ... "; flush stdout +puts "done: [lrange \ + [timerate -calibrate {}] \ +0 1]" + +## warm-up test-related features (load clock.tcl, system zones, locales, etc.): +clock scan "" -gmt 1 +clock scan "" +clock scan "" -timezone :CET +clock scan "" -format "" -locale en +clock scan "" -format "" -locale de + +## ------------------------------------------ + +proc {**STOP**} {args} { + return -code error -level 4 "**STOP** in [info level [expr {[info level]-2}]] [join $args { }]" +} + +proc _test_get_commands {lst} { + regsub -all {(?:^|\n)[ \t]*(\#[^\n]*|\msetup\M[^\n]*|\mcleanup\M[^\n]*)(?=\n\s*(?:[\{\#]|setup|cleanup))} $lst "\n{\\1}" +} + +proc _test_out_total {} { + upvar _ _ + + set tcnt [llength $_(itm)] + if {!$tcnt} { + puts "" + return + } + + set mintm 0x7fffffff + set maxtm 0 + set nett 0 + set wtm 0 + set wcnt 0 + set i 0 + foreach tm $_(itm) { + if {[llength $tm] > 6} { + set nett [expr {$nett + [lindex $tm 6]}] + } + set wtm [expr {$wtm + [lindex $tm 0]}] + set wcnt [expr {$wcnt + [lindex $tm 2]}] + set tm [lindex $tm 0] + if {$tm > $maxtm} {set maxtm $tm; set maxi $i} + if {$tm < $mintm} {set mintm $tm; set mini $i} + incr i + } + + puts [string repeat ** 40] + set s [format "%d cases in %.2f sec." $tcnt [expr {$tcnt * $_(reptime) / 1000.0}]] + if {$nett > 0} { + append s [format " (%.2f nett-sec.)" [expr {$nett / 1000.0}]] + } + puts "Total $s:" + lset _(m) 0 [format %.6f $wtm] + lset _(m) 2 $wcnt + lset _(m) 4 [format %.3f [expr {$wcnt / (($nett ? $nett : ($tcnt * $_(reptime))) / 1000.0)}]] + if {[llength $_(m)] > 6} { + lset _(m) 6 [format %.3f $nett] + } + puts $_(m) + puts "Average:" + lset _(m) 0 [format %.6f [expr {[lindex $_(m) 0] / $tcnt}]] + lset _(m) 2 [expr {[lindex $_(m) 2] / $tcnt}] + if {[llength $_(m)] > 6} { + lset _(m) 6 [format %.3f [expr {[lindex $_(m) 6] / $tcnt}]] + lset _(m) 4 [format %.0f [expr {[lindex $_(m) 2] / [lindex $_(m) 6] * 1000}]] + } + puts $_(m) + puts "Min:" + puts [lindex $_(itm) $mini] + puts "Max:" + puts [lindex $_(itm) $maxi] + puts [string repeat ** 40] + puts "" +} + +proc _test_run {reptime lst {outcmd {puts $_(r)}}} { + upvar _ _ + array set _ [list itm {} reptime $reptime] + + foreach _(c) [_test_get_commands $lst] { + puts "% [regsub -all {\n[ \t]*} $_(c) {; }]" + if {[regexp {^\s*\#} $_(c)]} continue + if {[regexp {^\s*(?:setup|cleanup)\s+} $_(c)]} { + puts [if 1 [lindex $_(c) 1]] + continue + } + set _(r) [if 1 $_(c)] + if {$outcmd ne {}} $outcmd + puts [set _(m) [timerate $_(c) $reptime]] + lappend _(itm) $_(m) + puts "" + } + _test_out_total +} + +proc test-format {{reptime 1000}} { + _test_run $reptime { + # Format : short, week only (in gmt) + {clock format 1482525936 -format "%u" -gmt 1} + # Format : short, week only (system zone) + {clock format 1482525936 -format "%u"} + # Format : short, week only (CEST) + {clock format 1482525936 -format "%u" -timezone :CET} + # Format : date only (in gmt) + {clock format 1482525936 -format "%Y-%m-%d" -gmt 1} + # Format : date only (system zone) + {clock format 1482525936 -format "%Y-%m-%d"} + # Format : date only (CEST) + {clock format 1482525936 -format "%Y-%m-%d" -timezone :CET} + # Format : time only (in gmt) + {clock format 1482525936 -format "%H:%M" -gmt 1} + # Format : time only (system zone) + {clock format 1482525936 -format "%H:%M"} + # Format : time only (CEST) + {clock format 1482525936 -format "%H:%M" -timezone :CET} + # Format : time only (in gmt) + {clock format 1482525936 -format "%H:%M:%S" -gmt 1} + # Format : time only (system zone) + {clock format 1482525936 -format "%H:%M:%S"} + # Format : time only (CEST) + {clock format 1482525936 -format "%H:%M:%S" -timezone :CET} + # Format : default (in gmt) + {clock format 1482525936 -gmt 1 -locale en} + # Format : default (system zone) + {clock format 1482525936 -locale en} + # Format : default (CEST) + {clock format 1482525936 -timezone :CET -locale en} + # Format : ISO date-time (in gmt, numeric zone) + {clock format 1246379400 -format "%Y-%m-%dT%H:%M:%S %z" -gmt 1} + # Format : ISO date-time (system zone, CEST, numeric zone) + {clock format 1246379400 -format "%Y-%m-%dT%H:%M:%S %z"} + # Format : ISO date-time (CEST, numeric zone) + {clock format 1246379400 -format "%Y-%m-%dT%H:%M:%S %z" -timezone :CET} + # Format : ISO date-time (system zone, CEST) + {clock format 1246379400 -format "%Y-%m-%dT%H:%M:%S %Z"} + # Format : julian day with time (in gmt): + {clock format 1246379415 -format "%J %H:%M:%S" -gmt 1} + # Format : julian day with time (system zone): + {clock format 1246379415 -format "%J %H:%M:%S"} + + # Format : locale date-time (en): + {clock format 1246379415 -format "%x %X" -locale en} + # Format : locale date-time (de): + {clock format 1246379415 -format "%x %X" -locale de} + + # Format : locale lookup table month: + {clock format 1246379400 -format "%b" -locale en -gmt 1} + # Format : locale lookup 2 tables - month and day: + {clock format 1246379400 -format "%b %Od" -locale en -gmt 1} + # Format : locale lookup 3 tables - week, month and day: + {clock format 1246379400 -format "%a %b %Od" -locale en -gmt 1} + # Format : locale lookup 4 tables - week, month, day and year: + {clock format 1246379400 -format "%a %b %Od %Oy" -locale en -gmt 1} + + # Format : dynamic clock value (without converter caches): + setup {set i 0} + {clock format [incr i] -format "%Y-%m-%dT%H:%M:%S" -locale en -timezone :CET} + cleanup {puts [clock format $i -format "%Y-%m-%dT%H:%M:%S" -locale en -timezone :CET]} + # Format : dynamic clock value (without any converter caches, zone range overflow): + setup {set i 0} + {clock format [incr i 86400] -format "%Y-%m-%dT%H:%M:%S" -locale en -timezone :CET} + cleanup {puts [clock format $i -format "%Y-%m-%dT%H:%M:%S" -locale en -timezone :CET]} + + # Format : dynamic format (cacheable) + {clock format 1246379415 -format [string trim "%d.%m.%Y %H:%M:%S "] -gmt 1} + + # Format : all (in gmt, locale en) + {clock format 1482525936 -format "%%a = %a | %%A = %A | %%b = %b | %%h = %h | %%B = %B | %%C = %C | %%d = %d | %%e = %e | %%g = %g | %%G = %G | %%H = %H | %%I = %I | %%j = %j | %%J = %J | %%k = %k | %%l = %l | %%m = %m | %%M = %M | %%N = %N | %%p = %p | %%P = %P | %%Q = %Q | %%s = %s | %%S = %S | %%t = %t | %%u = %u | %%U = %U | %%V = %V | %%w = %w | %%W = %W | %%y = %y | %%Y = %Y | %%z = %z | %%Z = %Z | %%n = %n | %%EE = %EE | %%EC = %EC | %%Ey = %Ey | %%n = %n | %%Od = %Od | %%Oe = %Oe | %%OH = %OH | %%Ok = %Ok | %%OI = %OI | %%Ol = %Ol | %%Om = %Om | %%OM = %OM | %%OS = %OS | %%Ou = %Ou | %%Ow = %Ow | %%Oy = %Oy" -gmt 1 -locale en} + # Format : all (in CET, locale de) + {clock format 1482525936 -format "%%a = %a | %%A = %A | %%b = %b | %%h = %h | %%B = %B | %%C = %C | %%d = %d | %%e = %e | %%g = %g | %%G = %G | %%H = %H | %%I = %I | %%j = %j | %%J = %J | %%k = %k | %%l = %l | %%m = %m | %%M = %M | %%N = %N | %%p = %p | %%P = %P | %%Q = %Q | %%s = %s | %%S = %S | %%t = %t | %%u = %u | %%U = %U | %%V = %V | %%w = %w | %%W = %W | %%y = %y | %%Y = %Y | %%z = %z | %%Z = %Z | %%n = %n | %%EE = %EE | %%EC = %EC | %%Ey = %Ey | %%n = %n | %%Od = %Od | %%Oe = %Oe | %%OH = %OH | %%Ok = %Ok | %%OI = %OI | %%Ol = %Ol | %%Om = %Om | %%OM = %OM | %%OS = %OS | %%Ou = %Ou | %%Ow = %Ow | %%Oy = %Oy" -timezone :CET -locale de} + } +} + +proc test-scan {{reptime 1000}} { + _test_run $reptime { + # Scan : date (in gmt) + {clock scan "25.11.2015" -format "%d.%m.%Y" -base 0 -gmt 1} + # Scan : date (system time zone, with base) + {clock scan "25.11.2015" -format "%d.%m.%Y" -base 0} + # Scan : date (system time zone, without base) + {clock scan "25.11.2015" -format "%d.%m.%Y"} + # Scan : greedy match + {clock scan "111" -format "%d%m%y" -base 0 -gmt 1} + {clock scan "1111" -format "%d%m%y" -base 0 -gmt 1} + {clock scan "11111" -format "%d%m%y" -base 0 -gmt 1} + {clock scan "111111" -format "%d%m%y" -base 0 -gmt 1} + # Scan : greedy match (space separated) + {clock scan "1 1 1" -format "%d%m%y" -base 0 -gmt 1} + {clock scan "111 1" -format "%d%m%y" -base 0 -gmt 1} + {clock scan "1 111" -format "%d%m%y" -base 0 -gmt 1} + {clock scan "1 11 1" -format "%d%m%y" -base 0 -gmt 1} + {clock scan "1 11 11" -format "%d%m%y" -base 0 -gmt 1} + {clock scan "11 11 11" -format "%d%m%y" -base 0 -gmt 1} + + # Scan : time (in gmt) + {clock scan "10:35:55" -format "%H:%M:%S" -base 1000000000 -gmt 1} + # Scan : time (system time zone, with base) + {clock scan "10:35:55" -format "%H:%M:%S" -base 1000000000} + # Scan : time (gmt, without base) + {clock scan "10:35:55" -format "%H:%M:%S" -gmt 1} + # Scan : time (system time zone, without base) + {clock scan "10:35:55" -format "%H:%M:%S"} + + # Scan : date-time (in gmt) + {clock scan "25.11.2015 10:35:55" -format "%d.%m.%Y %H:%M:%S" -base 0 -gmt 1} + # Scan : date-time (system time zone with base) + {clock scan "25.11.2015 10:35:55" -format "%d.%m.%Y %H:%M:%S" -base 0} + # Scan : date-time (system time zone without base) + {clock scan "25.11.2015 10:35:55" -format "%d.%m.%Y %H:%M:%S"} + + # Scan : julian day in gmt + {clock scan 2451545 -format %J -gmt 1} + # Scan : julian day in system TZ + {clock scan 2451545 -format %J} + # Scan : julian day in other TZ + {clock scan 2451545 -format %J -timezone +0200} + # Scan : julian day with time: + {clock scan "2451545 10:20:30" -format "%J %H:%M:%S"} + # Scan : julian day with time (greedy match): + {clock scan "2451545 102030" -format "%J%H%M%S"} + + # Scan : century, lookup table month + {clock scan {1970 Jan 2} -format {%C%y %b %d} -locale en -gmt 1} + # Scan : century, lookup table month and day (both entries are first) + {clock scan {1970 Jan 01} -format {%C%y %b %Od} -locale en -gmt 1} + # Scan : century, lookup table month and day (list scan: entries with position 12 / 31) + {clock scan {2016 Dec 31} -format {%C%y %b %Od} -locale en -gmt 1} + + # Scan : ISO date-time (CEST) + {clock scan "2009-06-30T18:30:00+02:00" -format "%Y-%m-%dT%H:%M:%S%z"} + {clock scan "2009-06-30T18:30:00 CEST" -format "%Y-%m-%dT%H:%M:%S %z"} + # Scan : ISO date-time (UTC) + {clock scan "2009-06-30T18:30:00Z" -format "%Y-%m-%dT%H:%M:%S%z"} + {clock scan "2009-06-30T18:30:00 UTC" -format "%Y-%m-%dT%H:%M:%S %z"} + + # Scan : locale date-time (en): + {clock scan "06/30/2009 18:30:15" -format "%x %X" -gmt 1 -locale en} + # Scan : locale date-time (de): + {clock scan "30.06.2009 18:30:15" -format "%x %X" -gmt 1 -locale de} + + # Scan : dynamic format (cacheable) + {clock scan "25.11.2015 10:35:55" -format [string trim "%d.%m.%Y %H:%M:%S "] -base 0 -gmt 1} + + break + # # Scan : long format test (allock chain) + # {clock scan "25.11.2015" -format "%d.%m.%Y %d.%m.%Y %d.%m.%Y %d.%m.%Y %d.%m.%Y %d.%m.%Y %d.%m.%Y %d.%m.%Y" -base 0 -gmt 1} + # # Scan : dynamic, very long format test (create obj representation, allock chain, GC, etc): + # {clock scan "25.11.2015" -format [string repeat "[incr i] %d.%m.%Y %d.%m.%Y" 10] -base 0 -gmt 1} + # # Scan : again: + # {clock scan "25.11.2015" -format [string repeat "[incr i -1] %d.%m.%Y %d.%m.%Y" 10] -base 0 -gmt 1} + } {puts [clock format $_(r) -locale en]} +} + +proc test-freescan {{reptime 1000}} { + _test_run $reptime { + # FreeScan : relative date + {clock scan "5 years 18 months 385 days" -base 0 -gmt 1} + # FreeScan : relative date with relative weekday + {clock scan "5 years 18 months 385 days Fri" -base 0 -gmt 1} + # FreeScan : relative date with ordinal month + {clock scan "5 years 18 months 385 days next 1 January" -base 0 -gmt 1} + # FreeScan : relative date with ordinal month and relative weekday + {clock scan "5 years 18 months 385 days next January Fri" -base 0 -gmt 1} + # FreeScan : ordinal month + {clock scan "next January" -base 0 -gmt 1} + # FreeScan : relative week + {clock scan "next Fri" -base 0 -gmt 1} + # FreeScan : relative weekday and week offset + {clock scan "next January + 2 week" -base 0 -gmt 1} + # FreeScan : time only with base + {clock scan "19:18:30" -base 148863600 -gmt 1} + # FreeScan : time only without base, gmt + {clock scan "19:18:30" -gmt 1} + # FreeScan : time only without base, system + {clock scan "19:18:30"} + # FreeScan : date, system time zone + {clock scan "05/08/2016 20:18:30"} + # FreeScan : date, supplied time zone + {clock scan "05/08/2016 20:18:30" -timezone :CET} + # FreeScan : date, supplied gmt (equivalent -timezone :GMT) + {clock scan "05/08/2016 20:18:30" -gmt 1} + # FreeScan : date, supplied time zone gmt + {clock scan "05/08/2016 20:18:30" -timezone :GMT} + # FreeScan : time only, numeric zone in string, base time gmt (exchange zones between gmt / -0500) + {clock scan "20:18:30 -0500" -base 148863600 -gmt 1} + # FreeScan : time only, zone in string (exchange zones between system / gmt) + {clock scan "19:18:30 GMT" -base 148863600} + # FreeScan : fast switch of zones in cycle - GMT, MST, CET (system) and EST + {clock scan "19:18:30 MST" -base 148863600 -gmt 1 + clock scan "19:18:30 EST" -base 148863600 + } + } {puts [clock format $_(r) -locale en]} +} + +proc test-add {{reptime 1000}} { + _test_run $reptime { + # Add : years + {clock add 1246379415 5 years -gmt 1} + # Add : months + {clock add 1246379415 18 months -gmt 1} + # Add : weeks + {clock add 1246379415 20 weeks -gmt 1} + # Add : days + {clock add 1246379415 385 days -gmt 1} + # Add : weekdays + {clock add 1246379415 3 weekdays -gmt 1} + + # Add : hours + {clock add 1246379415 5 hours -gmt 1} + # Add : minutes + {clock add 1246379415 55 minutes -gmt 1} + # Add : seconds + {clock add 1246379415 100 seconds -gmt 1} + + # Add : +/- in gmt + {clock add 1246379415 -5 years +21 months -20 weeks +386 days -19 hours +30 minutes -10 seconds -gmt 1} + # Add : +/- in system timezone + {clock add 1246379415 -5 years +21 months -20 weeks +386 days -19 hours +30 minutes -10 seconds -timezone :CET} + + # Add : gmt + {clock add 1246379415 -5 years 18 months 366 days 5 hours 30 minutes 10 seconds -gmt 1} + # Add : system timezone + {clock add 1246379415 -5 years 18 months 366 days 5 hours 30 minutes 10 seconds -timezone :CET} + + # Add : all in gmt + {clock add 1246379415 4 years 18 months 50 weeks 378 days 3 weekdays 5 hours 30 minutes 10 seconds -gmt 1} + # Add : all in system timezone + {clock add 1246379415 4 years 18 months 50 weeks 378 days 3 weekdays 5 hours 30 minutes 10 seconds -timezone :CET} + + } {puts [clock format $_(r) -locale en]} +} + +proc test-other {{reptime 1000}} { + _test_run $reptime { + # Bad zone + {catch {clock scan "1 day" -timezone BAD_ZONE -locale en}} + + # Scan : julian day (overflow) + {catch {clock scan 5373485 -format %J}} + + # Scan : test rotate of GC objects (format is dynamic, so tcl-obj removed with last reference) + {set i 0; time { clock scan "[incr i] - 25.11.2015" -format "$i - %d.%m.%Y" -base 0 -gmt 1 } 50} + # Scan : test reusability of GC objects (format is dynamic, so tcl-obj removed with last reference) + {set i 50; time { clock scan "[incr i -1] - 25.11.2015" -format "$i - %d.%m.%Y" -base 0 -gmt 1 } 50} + } +} + +proc test {{reptime 1000}} { + puts "" + test-format $reptime + test-scan $reptime + test-freescan $reptime + test-add $reptime + test-other $reptime + + puts \n**OK** +} + +test 500; # ms -- cgit v0.12 From f9abf9b060c15ad2d4b00f99f7814a388875c642 Mon Sep 17 00:00:00 2001 From: sebres Date: Thu, 11 May 2017 09:46:43 +0000 Subject: man for timerate (doc/timerate.n) --- doc/timerate.n | 114 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 114 insertions(+) create mode 100644 doc/timerate.n diff --git a/doc/timerate.n b/doc/timerate.n new file mode 100644 index 0000000..df9a8f7 --- /dev/null +++ b/doc/timerate.n @@ -0,0 +1,114 @@ +'\" +'\" Copyright (c) 2005 Sergey Brester aka sebres. +'\" +'\" See the file "license.terms" for information on usage and redistribution +'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES. +'\" +.TH timerate n "" Tcl "Tcl Built-In Commands" +.so man.macros +.BS +'\" Note: do not modify the .SH NAME line immediately below! +.SH NAME +timerate \- Time-related execution resp. performance measurement of a script +.SH SYNOPSIS +\fBtimerate \fIscript\fR \fI?time?\fR +.sp +\fBtimerate \fI?-direct?\fR \fI?-overhead double?\fR \fIscript\fR \fI?time?\fR +.sp +\fBtimerate \fI?-calibrate?\fR \fI?-direct?\fR \fIscript\fR \fI?time?\fR +.BE +.SH DESCRIPTION +.PP +The first and second form will evaluate \fIscript\fR until the interval +\fItime\fR given in milliseconds elapses, or for 1000 milliseconds (1 second) +if \fItime\fR is not specified. +.sp +It will then return a canonical tcl-list of the form +.PP +.CS +\f0.095977 µs/# 52095836 # 10419167 #/sec 5000.000 nett-ms\fR +.CE +.PP +which indicates: +.IP \(bu +the average amount of time required per iteration, in microseconds (lindex $result 0) +.IP \(bu +the count how many times it was executed (lindex $result 2) +.IP \(bu +the estimated rate per second (lindex $result 4) +.IP \(bu +the estimated real execution time without measurement overhead (lindex $result 6) +.PP +Time is measured in elapsed time using heighest timer resolution as possible, not CPU time. +This command may be used to provide information as to how well the script or a tcl-command +is performing and can help determine bottlenecks and fine-tune application performance. +.PP +\fI-calibrate\fR +. +To measure very fast scripts as exact as posible the calibration process +may be required. + +This parameter used to calibrate \fBtimerate\fR calculating the estimated overhead +of given \fIscript\fR as default overhead for further execution of \fBtimerate\fR. +It can take up to 10 seconds if parameter \fItime\fR is not specified. +.PP +\fI-overhead double\fR +. +This parameter used to supply the measurement overhead of single iteration +(in microseconds) that should be ignored during whole evaluation process. +.PP +\fI-direct\fR +. +Causes direct execution per iteration (not compiled variant of evaluation used). +.PP +In opposition to \fBtime\fR the execution limited here by fixed time instead of +repetition count. +Additionally the compiled variant of the script will be used during whole evaluation +(as if it were part of a compiled \fBproc\fR), if parameter \fI-direct\fR is not specified. +Therefore it provides more precise results and prevents very long execution time +by slow scripts resp. scripts with unknown speed. + +.SH EXAMPLE +Estimate how fast it takes for a simple Tcl \fBfor\fR loop (including +operations on variable \fIi\fR) to count to a ten: +.PP +.CS +# calibrate: +timerate -calibrate {} +# measure: +timerate { for {set i 0} {$i<10} {incr i} {} } 5000 +.CE +.PP +Estimate how fast it takes for a simple Tcl \fBfor\fR loop only (ignoring the +overhead for operations on variable \fIi\fR) to count to a ten: +.PP +.CS +# calibrate for overhead of variable operations: +set i 0; timerate -calibrate {expr {$i<10}; incr i} 1000 +# measure: +timerate { for {set i 0} {$i<10} {incr i} {} } 5000 +.CE +.PP +Estimate the rate of calculating the hour using \fBclock format\fR only, ignoring +overhead of the rest, without measurement how fast it takes for a whole script: +.PP +.CS +# calibrate: +timerate -calibrate {} +# estimate overhead: +set tm 0 +set ovh [lindex [timerate { incr tm [expr {24*60*60}] }] 0] +# measure using esimated overhead: +set tm 0 +timerate -overhead $ovh { + clock format $tm -format %H + incr tm [expr {24*60*60}]; # overhead for this is ignored +} 5000 +.CE +.SH "SEE ALSO" +time(n) +.SH KEYWORDS +script, timerate, time +.\" Local Variables: +.\" mode: nroff +.\" End: -- cgit v0.12 From 0cdf2fd457ccaaa079eb8da08b23c1367f092d53 Mon Sep 17 00:00:00 2001 From: sebres Date: Thu, 11 May 2017 12:25:59 +0000 Subject: performance test cases extended: several cases to cover absence of the ensemble overhead --- tests-perf/clock.perf.tcl | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) diff --git a/tests-perf/clock.perf.tcl b/tests-perf/clock.perf.tcl index 733db1a..238e536 100644 --- a/tests-perf/clock.perf.tcl +++ b/tests-perf/clock.perf.tcl @@ -371,8 +371,34 @@ proc test-other {{reptime 1000}} { } } +proc test-ensemble-perf {{reptime 1000}} { + _test_run $reptime { + # Clock clicks (ensemble) + {clock clicks} + # Clock clicks (direct) + {::tcl::clock::clicks} + # Clock seconds (ensemble) + {clock seconds} + # Clock seconds (direct) + {::tcl::clock::seconds} + # Clock microseconds (ensemble) + {clock microseconds} + # Clock microseconds (direct) + {::tcl::clock::microseconds} + # Clock scan (ensemble) + {clock scan ""} + # Clock scan (direct) + {::tcl::clock::scan ""} + # Clock format (ensemble) + {clock format 0 -f %s} + # Clock format (direct) + {::tcl::clock::format 0 -f %s} + } +} + proc test {{reptime 1000}} { puts "" + test-ensemble-perf [expr {$reptime / 2}]; #fast enough test-format $reptime test-scan $reptime test-freescan $reptime -- cgit v0.12 From 1ea7d20306277fe9aab8d0f70fa57d214eb48ddb Mon Sep 17 00:00:00 2001 From: sebres Date: Thu, 11 May 2017 12:32:47 +0000 Subject: auto-loading of ensemble and stubs on demand only (+ test covered now, see clock-0.1); introduces new possibility to implement namespace-based auto-loading, e. g.: set ::auto_index_ns(::some::namespace) [list ::source [::file join $dir some namespace.tcl]]] loading of clock-stubs (clock.tcl) implemented via handler "auto_index_ns" now. --- library/init.tcl | 73 ++++++++++++++++++++++++++++++++++---------------------- tests/clock.test | 21 ++++++++++++++++ 2 files changed, 65 insertions(+), 29 deletions(-) diff --git a/library/init.tcl b/library/init.tcl index 824f66f..d2c3b6e 100644 --- a/library/init.tcl +++ b/library/init.tcl @@ -156,6 +156,17 @@ if {(![interp issafe]) && ($tcl_platform(platform) eq "windows")} { if {[interp issafe]} { package unknown {::tcl::tm::UnknownHandler ::tclPkgUnknown} } else { + # Default known auto_index (avoid loading auto index implicit after interp create): + + array set ::auto_index { + ::tcl::tm::UnknownHandler {source [info library]/tm.tcl} + ::tclPkgUnknown {source [info library]/package.tcl} + ::history {source [info library]/history.tcl} + } + + # The newest possibility to load whole namespace: + array set ::auto_index_ns {} + # Set up search for Tcl Modules (TIP #189). # and setup platform specific unknown package handlers if {$tcl_platform(os) eq "Darwin" @@ -168,28 +179,19 @@ if {[interp issafe]} { # Set up the 'clock' ensemble - namespace eval ::tcl::clock [list variable TclLibDir $::tcl_library] - proc clock args { set cmdmap [dict create] foreach cmd {add clicks format microseconds milliseconds scan seconds configure} { dict set cmdmap $cmd ::tcl::clock::$cmd } - namespace eval ::tcl::clock [list namespace ensemble create -command \ - [uplevel 1 [list namespace origin [lindex [info level 0] 0]]] \ + namespace inscope ::tcl::clock [list namespace ensemble create -command \ + [uplevel 1 [list ::namespace origin [::lindex [info level 0] 0]]] \ -map $cmdmap -compile 1] - # Auto-loading stubs for 'clock.tcl' - foreach cmd {mcget LocalizeFormat SetupTimeZone GetSystemTimeZone} { - proc ::tcl::clock::$cmd args { - variable TclLibDir - source -encoding utf-8 [file join $TclLibDir clock.tcl] - return [uplevel 1 [info level 0]] - } - } - - return [uplevel 1 [info level 0]] + uplevel 1 [info level 0] } + # Auto-loading stubs for 'clock.tcl' + set ::auto_index_ns(::tcl::clock) {::namespace inscope ::tcl::clock {::source [::file join [info library] clock.tcl]}} } # Conditionalize for presence of exec. @@ -417,18 +419,22 @@ proc unknown args { # for instance. If not given, namespace current is used. proc auto_load {cmd {namespace {}}} { - global auto_index auto_path + global auto_index auto_index_ns auto_path + # qualify names: if {$namespace eq ""} { set namespace [uplevel 1 [list ::namespace current]] } set nameList [auto_qualify $cmd $namespace] # workaround non canonical auto_index entries that might be around # from older auto_mkindex versions - lappend nameList $cmd - foreach name $nameList { + if {$cmd ni $nameList} {lappend nameList $cmd} + + # try to load (and create sub-cmd handler "_sub_load_cmd" for further usage): + foreach name $nameList [set _sub_load_cmd { + # via auto_index: if {[info exists auto_index($name)]} { - namespace eval :: $auto_index($name) + namespace inscope :: $auto_index($name) # There's a couple of ways to look for a command of a given # name. One is to use # info commands $name @@ -440,22 +446,31 @@ proc auto_load {cmd {namespace {}}} { return 1 } } - } + # via auto_index_ns - resolver for the whole namespace loaders + if {[set ns [::namespace qualifiers $name]] ni {"" "::"} && + [info exists auto_index_ns($ns)] + } { + # remove handler before loading (prevents several self-recursion cases): + set ldr $auto_index_ns($ns); unset auto_index_ns($ns) + namespace inscope :: $ldr + # if got it: + if {[namespace which -command $name] ne ""} { + return 1 + } + } + }] + + # load auto_index if possible: if {![info exists auto_path]} { return 0 } - if {![auto_load_index]} { return 0 } - foreach name $nameList { - if {[info exists auto_index($name)]} { - namespace eval :: $auto_index($name) - if {[namespace which -command $name] ne ""} { - return 1 - } - } - } + + # try again (something new could be loaded): + foreach name $nameList $_sub_load_cmd + return 0 } @@ -605,7 +620,7 @@ proc auto_import {pattern} { foreach name [array names auto_index $pattern] { if {([namespace which -command $name] eq "") && ([namespace qualifiers $pattern] eq [namespace qualifiers $name])} { - namespace eval :: $auto_index($name) + namespace inscope :: $auto_index($name) } } } diff --git a/tests/clock.test b/tests/clock.test index 0737558..af517c8 100644 --- a/tests/clock.test +++ b/tests/clock.test @@ -35,6 +35,9 @@ testConstraint y2038 \ # TEST PLAN +# clock-0: +# several base test-cases +# # clock-1: # [clock format] - tests of bad and empty arguments # @@ -251,6 +254,24 @@ proc ::testClock::registry { cmd path key } { return [dict get $reg $path $key] } +# Base test cases: + +test clock-0.1 "initial: auto-loading of ensemble and stubs on demand" { + set i [interp create]; # because clock can be used somewhere, test it in new interp: + + set ret [$i eval { + + lappend ret ens:[namespace ensemble exists ::clock] + clock seconds; # init ensemble (but not yet stubs, loading of clock.tcl retarded) + lappend ret ens:[namespace ensemble exists ::clock] + lappend ret stubs:[expr {[namespace which -command ::tcl::clock::GetSystemTimeZone] ne ""}] + clock format -now; # clock.tcl stubs expected + lappend ret stubs:[expr {[namespace which -command ::tcl::clock::GetSystemTimeZone] ne ""}] + }] + interp delete $i + set ret +} {ens:0 ens:1 stubs:0 stubs:1} + # Test some of the basics of [clock format] test clock-1.0 "clock format - wrong # args" { -- cgit v0.12 From 95d531e781ad6869e929820b306df7206c3f67b8 Mon Sep 17 00:00:00 2001 From: sebres Date: Thu, 11 May 2017 15:07:32 +0000 Subject: prevents loss of key object if the format object (where key stored) becomes changed (loses its internal representation during evals); should avoid possible theoretical segfault there. --- generic/tclClockFmt.c | 26 ++++++++++++++------------ 1 file changed, 14 insertions(+), 12 deletions(-) diff --git a/generic/tclClockFmt.c b/generic/tclClockFmt.c index d875bd4..18b82fa 100644 --- a/generic/tclClockFmt.c +++ b/generic/tclClockFmt.c @@ -634,7 +634,7 @@ ClockFmtObj_UpdateString(objPtr) * * This is normally stored in second pointer of internal representation. * If format object is not localizable, it is equal the given format - * pointer and the first pointer of internal representation may be NULL. + * pointer (special case to fast fallback by not-localizable formats). * * Results: * Returns tcl object with key or format object if not localizable. @@ -825,16 +825,20 @@ ClockLocalizeFormat( return opts->formatObj; } + /* prevents loss of key object if the format object (where key stored) + * becomes changed (loses its internal representation during evals) */ + Tcl_IncrRefCount(keyObj); + if (opts->mcDictObj == NULL) { ClockMCDict(opts); if (opts->mcDictObj == NULL) - return NULL; + goto done; } /* try to find in cache within locale mc-catalog */ if (Tcl_DictObjGet(NULL, opts->mcDictObj, keyObj, &valObj) != TCL_OK) { - return NULL; + goto done; } /* call LocalizeFormat locale format fmtkey */ @@ -844,10 +848,9 @@ ClockLocalizeFormat( callargs[1] = opts->localeObj; callargs[2] = opts->formatObj; callargs[3] = keyObj; - Tcl_IncrRefCount(keyObj); if (Tcl_EvalObjv(opts->interp, 4, callargs, 0) != TCL_OK ) { - goto clean; + goto done; } valObj = Tcl_GetObjResult(opts->interp); @@ -857,9 +860,11 @@ ClockLocalizeFormat( keyObj, valObj) != TCL_OK ) { valObj = NULL; - goto clean; + goto done; } + Tcl_ResetResult(opts->interp); + /* check special case - format object is not localizable */ if (valObj == opts->formatObj) { /* mark it as unlocalizable, by setting self as key (without refcount incr) */ @@ -868,14 +873,11 @@ ClockLocalizeFormat( ObjLocFmtKey(opts->formatObj) = opts->formatObj; } } -clean: - - Tcl_UnsetObjRef(keyObj); - if (valObj) { - Tcl_ResetResult(opts->interp); - } } +done: + + Tcl_UnsetObjRef(keyObj); return (opts->formatObj = valObj); } -- cgit v0.12 From ea1ae51d2d146dc75fd8132f6a7d9b9a24c3cb03 Mon Sep 17 00:00:00 2001 From: sebres Date: Thu, 11 May 2017 15:07:41 +0000 Subject: [clock] tclStrIdxTree extended with possibility to hold client data; also changed in clock - indices starts with 1 instead of 0, and 0(NULL) instead of -1 used as sign of ambiguous keys. --- generic/tclClockFmt.c | 14 +++++++----- generic/tclStrIdxTree.c | 59 +++++++++++++++++++++++++++---------------------- generic/tclStrIdxTree.h | 8 +++---- 3 files changed, 45 insertions(+), 36 deletions(-) diff --git a/generic/tclClockFmt.c b/generic/tclClockFmt.c index 18b82fa..70b3ad7 100644 --- a/generic/tclClockFmt.c +++ b/generic/tclClockFmt.c @@ -1174,7 +1174,7 @@ ClockMCGetListIdxTree( goto done; }; - if (TclStrIdxTreeBuildFromList(idxTree, lstc, lstv) != TCL_OK) { + if (TclStrIdxTreeBuildFromList(idxTree, lstc, lstv, NULL) != TCL_OK) { goto done; } @@ -1249,7 +1249,7 @@ ClockMCGetMultiListIdxTree( goto done; }; - if (TclStrIdxTreeBuildFromList(idxTree, lstc, lstv) != TCL_OK) { + if (TclStrIdxTreeBuildFromList(idxTree, lstc, lstv, NULL) != TCL_OK) { goto done; } mcKeys++; @@ -1301,12 +1301,12 @@ ClockStrIdxTreeSearch(ClockFmtScnCmdArgs *opts, /* not found */ return TCL_RETURN; } - if (foundItem->value == -1) { + if (!foundItem->value) { /* ambigous */ return TCL_RETURN; } - *val = foundItem->value; + *val = PTR2INT(foundItem->value); /* shift input pointer */ yyInput = f; @@ -1406,7 +1406,7 @@ ClockScnToken_Month_Proc(ClockFmtScnCmdArgs *opts, return ret; } - yyMonth = val + 1; + yyMonth = val; return TCL_OK; } @@ -1445,6 +1445,7 @@ ClockScnToken_DayOfWeek_Proc(ClockFmtScnCmdArgs *opts, if (ret != TCL_OK) { return ret; } + --val; } if (val != -1) { @@ -1476,6 +1477,7 @@ ClockScnToken_DayOfWeek_Proc(ClockFmtScnCmdArgs *opts, if (ret != TCL_OK) { return ret; } + --val; if (val == 0) { val = 7; @@ -1578,7 +1580,7 @@ ClockScnToken_LocaleListMatcher_Proc(ClockFmtScnCmdArgs *opts, } if (tok->map->offs > 0) { - *(int *)(((char *)info) + tok->map->offs) = val; + *(int *)(((char *)info) + tok->map->offs) = --val; } return TCL_OK; diff --git a/generic/tclStrIdxTree.c b/generic/tclStrIdxTree.c index d9b5da0..291e481 100644 --- a/generic/tclStrIdxTree.c +++ b/generic/tclStrIdxTree.c @@ -24,26 +24,28 @@ * * Index-Tree: * - * j -1 * ... - * anuar 0 * - * u -1 * a -1 - * ni 5 * pril 3 - * li 6 * ugust 7 - * n -1 * gt 7 - * r 0 * s 8 - * i 5 * eptember 8 - * li 6 * pt 8 - * f 1 * oktober 9 - * ebruar 1 * n 10 - * br 1 * ovember 10 - * m -1 * vb 10 - * a -1 * d 11 - * erz 2 * ezember 11 - * i 4 * zb 11 - * rz 2 * + * j 0 * ... + * anuar 1 * + * u 0 * a 0 + * ni 6 * pril 4 + * li 7 * ugust 8 + * n 0 * gt 8 + * r 1 * s 9 + * i 6 * eptember 9 + * li 7 * pt 9 + * f 2 * oktober 10 + * ebruar 2 * n 11 + * br 2 * ovember 11 + * m 0 * vb 11 + * a 0 * d 12 + * erz 3 * ezember 12 + * i 5 * zb 12 + * rz 3 * * ... * - * Thereby value -1 shows pure group items (corresponding ambigous matches). + * Thereby value 0 shows pure group items (corresponding ambigous matches). + * But the group may have a value if it contains only same values + * (see for example group "f" above). * * StrIdxTree's are very fast, so: * build of above-mentioned tree takes about 10 microseconds. @@ -109,7 +111,7 @@ TclStrIdxTreeSearch( if (offs >= item->length && item->childTree.firstPtr) { /* save previuosly found item (if not ambigous) for * possible fallback (few greedy match) */ - if (item->value != -1) { + if (item->value != NULL) { prevf = f; prevItem = item; prevParent = parent; @@ -206,7 +208,9 @@ TclStrIdxTreeAppend( * TclStrIdxTreeBuildFromList -- * * Build or extend string indexed tree from tcl list. - * + * If the values not given the values of built list are indices starts with 1. + * Value of 0 is thereby reserved to the ambigous values. + * * Important: by multiple lists, optimal tree can be created only if list with * larger strings used firstly. * @@ -223,10 +227,12 @@ MODULE_SCOPE int TclStrIdxTreeBuildFromList( TclStrIdxTree *idxTree, int lstc, - Tcl_Obj **lstv) + Tcl_Obj **lstv, + ClientData *values) { Tcl_Obj **lwrv; int i, ret = TCL_ERROR; + ClientData val; const char *s, *e, *f; TclStrIdx *item; @@ -250,8 +256,9 @@ TclStrIdxTreeBuildFromList( TclStrIdxTree *foundParent = idxTree; e = s = TclGetString(lwrv[i]); e += lwrv[i]->length; + val = values ? values[i] : INT2PTR(i+1); - /* ignore empty values (impossible to index it) */ + /* ignore empty keys (impossible to index it) */ if (lwrv[i]->length == 0) continue; item = NULL; @@ -267,7 +274,7 @@ TclStrIdxTreeBuildFromList( } /* if shortest key was found with the same value, * just replace its current key with longest key */ - if ( foundItem->value == i + if ( foundItem->value == val && foundItem->length < lwrv[i]->length && foundItem->childTree.firstPtr == NULL ) { @@ -286,7 +293,7 @@ TclStrIdxTreeBuildFromList( Tcl_InitObjRef(item->key, foundItem->key); item->length = f - s; /* set value or mark as ambigous if not the same value of both */ - item->value = (foundItem->value == i) ? i : -1; + item->value = (foundItem->value == val) ? val : NULL; /* insert group item between foundParent and foundItem */ TclStrIdxTreeInsertBranch(foundParent, item, foundItem); foundParent = &item->childTree; @@ -304,7 +311,7 @@ TclStrIdxTreeBuildFromList( item->childTree.lastPtr = item->childTree.firstPtr = NULL; Tcl_InitObjRef(item->key, lwrv[i]); item->length = lwrv[i]->length; - item->value = i; + item->value = val; TclStrIdxTreeAppend(foundParent, item); }; @@ -496,7 +503,7 @@ TclStrIdxTreeTestObjCmd( &lstc, &lstv) != TCL_OK) { return TCL_ERROR; }; - TclStrIdxTreeBuildFromList(&idxTree, lstc, lstv); + TclStrIdxTreeBuildFromList(&idxTree, lstc, lstv, NULL); } if (optionIndex == O_PUTS_INDEX) { TclStrIdxTreePrint(interp, idxTree.firstPtr, 0); diff --git a/generic/tclStrIdxTree.h b/generic/tclStrIdxTree.h index 305053c..9f26907 100644 --- a/generic/tclStrIdxTree.h +++ b/generic/tclStrIdxTree.h @@ -27,9 +27,9 @@ typedef struct TclStrIdx { struct TclStrIdxTree childTree; struct TclStrIdx *nextPtr; struct TclStrIdx *prevPtr; - Tcl_Obj *key; - int length; - int value; + Tcl_Obj *key; + int length; + ClientData value; } TclStrIdx; @@ -152,7 +152,7 @@ MODULE_SCOPE const char* const char *start, const char *end); MODULE_SCOPE int TclStrIdxTreeBuildFromList(TclStrIdxTree *idxTree, - int lstc, Tcl_Obj **lstv); + int lstc, Tcl_Obj **lstv, ClientData *values); MODULE_SCOPE Tcl_Obj* TclStrIdxTreeNewObj(); -- cgit v0.12 From 39a388f0350df40cc42cb9f09c2d1be32327ac93 Mon Sep 17 00:00:00 2001 From: sebres Date: Thu, 11 May 2017 16:56:56 +0000 Subject: update documentation doc/clock.n: small enhancements and relevant changes of new engine. --- doc/clock.n | 39 +++++++++++++++++++++++++++++++++++++-- 1 file changed, 37 insertions(+), 2 deletions(-) diff --git a/doc/clock.n b/doc/clock.n index 889a5da..38b408d 100644 --- a/doc/clock.n +++ b/doc/clock.n @@ -87,6 +87,15 @@ slowing its clock by a tiny fraction for some minutes until it is back in sync with UTC; its data model does not represent minutes that have 59 or 61 seconds. .TP +\fI\-now\fR +Instead of \fItimeVal\fR a non-integer option \fI\-now\fR can be used as +replacement for today, which is simply interpolated to the runt-time as value +of \fBclock seconds\fR. For example: +.sp +\fBclock format -now -f %a; # current day of the week\fR +.sp +\fBclock add -now 1 month; # next month\fR +.TP \fIunit\fR One of the words, \fBseconds\fR, \fBminutes\fR, \fBhours\fR, \fBdays\fR, \fBweeks\fR, \fBmonths\fR, or \fByears\fR, or @@ -528,6 +537,12 @@ abbreviation appropriate to the current locale, and uses it to fix whether \fB%Y\fR refers to years before or after Year 1 of the Common Era. .TP +\fB%Es\fR +This affects similar to \fB%s\fR, but in opposition to \fB%s\fR it parses +or formats local seconds (not the posix seconds). +Because \fB%s\fR has the same precedence as \fB%s\fR (uniquely determines +a point in time), it overrides all other input formats. +.TP \fB%Ex\fR On output, produces a locale-dependent representation of the date in the locale's alternative calendar. On input, matches @@ -722,13 +737,15 @@ week number \fB%V\fR; programs should use \fB%G\fR for that purpose. On output, produces the current time zone, expressed in hours and minutes east (+hhmm) or west (\-hhmm) of Greenwich. On input, accepts a time zone specifier (see \fBTIME ZONES\fR below) that will be used to -determine the time zone. +determine the time zone (this token is optionally applicable on input, +so the value is not mandatory and can be missing in input). .TP \fB%Z\fR On output, produces the current time zone's name, possibly translated to the given locale. On input, accepts a time zone specifier (see \fBTIME ZONES\fR below) that will be used to determine the -time zone. This option should, in general, be used on input only when +time zone (token is also like \fB%z\fR optionally applicable on input). +This option should, in general, be used on input only when parsing RFC822 dates. Other uses are fraught with ambiguity; for instance, the string \fBBST\fR may represent British Summer Time or Brazilian Standard Time. It is recommended that date/time strings for @@ -927,6 +944,24 @@ used. Finally, a correction is applied so that the correct hour of the day is produced after allowing for daylight savings time differences and the correct date is given when going from the end of a long month to a short month. +.PP +The precedence of the applying of single tokens resp. which sequence will be +used by calculating of the time is complex, e. g. heavily dependent on the +precision of type of the token. +.sp +In example below the second date-string contains "next January", therefore +it results in next year but in January. And third date-string besides "January" +contains also additionally "Fri", so it results in the nearest Friday. +Thus both win before "385 days" resp. make it more precise, because of higher +precision of this token types. +.CS +% clock format [clock scan "5 years 18 months 385 days" -base 0 -gmt 1] -gmt 1 +Thu Jul 21 00:00:00 GMT 1977 +% clock format [clock scan "5 years 18 months 385 days next January" -base 0 -gmt 1] -gmt 1 +Sat Jan 21 00:00:00 GMT 1978 +% clock format [clock scan "5 years 18 months 385 days next January Fri" -base 0 -gmt 1] -gmt 1 +Fri Jan 27 00:00:00 GMT 1978 +.CE .SH "SEE ALSO" msgcat(n) .SH KEYWORDS -- cgit v0.12 From 0ec19f6b1194fb374ddf9865375671b07033d9e1 Mon Sep 17 00:00:00 2001 From: sebres Date: Thu, 11 May 2017 21:53:38 +0000 Subject: fixes lost indentation during back-porting --- generic/tclClock.c | 36 ++++++++++++++++++------------------ 1 file changed, 18 insertions(+), 18 deletions(-) diff --git a/generic/tclClock.c b/generic/tclClock.c index a066f73..17c19c3 100644 --- a/generic/tclClock.c +++ b/generic/tclClock.c @@ -150,7 +150,7 @@ struct ClockCommand { const char *name; /* The tail of the command name. The full name * is "::tcl::clock::". When NULL marks * the end of the table. */ - Tcl_ObjCmdProc *objCmdProc; /* Function that implements the command. This + Tcl_ObjCmdProc *objCmdProc; /* Function that implements the command. This * will always have the ClockClientData sent * to it, but may well ignore this data. */ CompileProc *compileProc; /* The compiler for the command. */ @@ -2004,7 +2004,7 @@ ConvertUTCToLocal( if (ConvertUTCToLocalUsingTable(interp, fields, rowc, rowv, dataPtr->UTC2Local.rangesVal) != TCL_OK) { return TCL_ERROR; - } + } } /* Cache the last conversion */ @@ -2576,9 +2576,9 @@ GetJulianDayFromEraYearMonthDay( * See above bug for details. The casts are necessary. */ if (ym1 >= 0) - ym1o4 = ym1 / 4; + ym1o4 = ym1 / 4; else { - ym1o4 = - (int) (((unsigned int) -ym1) / 4); + ym1o4 = - (int) (((unsigned int) -ym1) / 4); } #endif if (ym1 % 4 < 0) { @@ -2992,12 +2992,12 @@ ClockInitFmtScnArgs( static int ClockParseFmtScnArgs( register - ClockFmtScnCmdArgs *opts, /* Result vector: format, locale, timezone... */ - TclDateFields *date, /* Extracted date-time corresponding base - * (by scan or add) resp. clockval (by format) */ + ClockFmtScnCmdArgs *opts, /* Result vector: format, locale, timezone... */ + TclDateFields *date, /* Extracted date-time corresponding base + * (by scan or add) resp. clockval (by format) */ int objc, /* Parameter count */ - Tcl_Obj *const objv[], /* Parameter vector */ - int flags /* Flags, differentiates between format, scan, add */ + Tcl_Obj *const objv[], /* Parameter vector */ + int flags /* Flags, differentiates between format, scan, add */ ) { Tcl_Interp *interp = opts->interp; ClockClientData *dataPtr = opts->clientData; @@ -3031,7 +3031,7 @@ ClockParseFmtScnArgs( Tcl_WideInt num; if (TclGetWideIntFromObj(NULL, objv[i], &num) == TCL_OK) { continue; - } + } } /* get option */ if (Tcl_GetIndexFromObj(interp, objv[i], options, @@ -3067,10 +3067,10 @@ ClockParseFmtScnArgs( case CLC_ARGS_BASE: if ( !(flags & (CLC_SCN_ARGS)) ) { goto badOptionMsg; - } + } opts->baseObj = objv[i+1]; break; - } + } saw |= (1 << optionIndex); } @@ -3130,10 +3130,10 @@ ClockParseFmtScnArgs( i = 1; goto badOption; } - /* + /* * seconds could be an unsigned number that overflowed. Make sure * that it isn't. - */ + */ if (opts->baseObj->typePtr == &tclBignumType) { Tcl_SetObjResult(interp, dataPtr->literals[LIT_INTEGER_VALUE_TOO_LARGE]); @@ -4042,14 +4042,14 @@ ClockSecondsObjCmd( static unsigned long TzsetGetEpoch(void) { - static char* tzWas = INT2PTR(-1); /* Previous value of TZ, protected by - * clockMutex. */ + static char* tzWas = INT2PTR(-1); /* Previous value of TZ, protected by + * clockMutex. */ static long tzLastRefresh = 0; /* Used for latency before next refresh */ static unsigned long tzWasEpoch = 0; /* Epoch, signals that TZ changed */ static unsigned long tzEnvEpoch = 0; /* Last env epoch, for faster signaling, that TZ changed via TCL */ - const char *tzIsNow; /* Current value of TZ */ + const char *tzIsNow; /* Current value of TZ */ /* * Prevent performance regression on some platforms by resolving of system time zone: @@ -4068,7 +4068,7 @@ TzsetGetEpoch(void) Tcl_MutexLock(&clockMutex); tzIsNow = getenv("TCL_TZ"); if (tzIsNow == NULL) { - tzIsNow = getenv("TZ"); + tzIsNow = getenv("TZ"); } if (tzIsNow != NULL && (tzWas == NULL || tzWas == INT2PTR(-1) || strcmp(tzIsNow, tzWas) != 0)) { -- cgit v0.12 From 0adb50f88bf8f3e5220dce66339ccc62c6139d28 Mon Sep 17 00:00:00 2001 From: sebres Date: Fri, 12 May 2017 07:45:15 +0000 Subject: restored "-encoding utf-8" by source clock.tcl (lost by merging) --- library/init.tcl | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/library/init.tcl b/library/init.tcl index d2c3b6e..de69730 100644 --- a/library/init.tcl +++ b/library/init.tcl @@ -191,7 +191,9 @@ if {[interp issafe]} { uplevel 1 [info level 0] } # Auto-loading stubs for 'clock.tcl' - set ::auto_index_ns(::tcl::clock) {::namespace inscope ::tcl::clock {::source [::file join [info library] clock.tcl]}} + set ::auto_index_ns(::tcl::clock) {::namespace inscope ::tcl::clock { + ::source -encoding utf-8 [::file join [info library] clock.tcl] + }} } # Conditionalize for presence of exec. -- cgit v0.12 From 5d20272000e4f0b9ad2d2e16c4835debcac832dd Mon Sep 17 00:00:00 2001 From: "jan.nijtmans" Date: Fri, 12 May 2017 14:31:17 +0000 Subject: Don't test Tcl_GetDefaultEncodingDir() any more (which is obsolete), test Tcl_GetEncodingSearchPath() in stead. --- tests/encoding.test | 14 +++++++------- tests/unixInit.test | 17 +++++++++++------ unix/tclUnixTest.c | 45 ++++++++++++++++++++++----------------------- 3 files changed, 40 insertions(+), 36 deletions(-) diff --git a/tests/encoding.test b/tests/encoding.test index 4dddbb5..d9ba072 100644 --- a/tests/encoding.test +++ b/tests/encoding.test @@ -35,7 +35,7 @@ proc runtests {} { # Some tests require the testencoding command testConstraint testencoding [llength [info commands testencoding]] testConstraint exec [llength [info commands exec]] -testConstraint testgetdefenc [llength [info commands testgetdefenc]] +testConstraint testgetencpath [llength [info commands testgetencpath]] # TclInitEncodingSubsystem is tested by the rest of this file # TclFinalizeEncodingSubsystem is not currently tested @@ -570,15 +570,15 @@ foreach from {cp932 shiftjis euc-jp iso2022-jp} { } } -test encoding-26.0 {Tcl_GetDefaultEncodingDir} -constraints { - testgetdefenc +test encoding-26.0 {Tcl_GetEncodingSearchPath} -constraints { + testgetencpath } -setup { - set origDir [testgetdefenc] - testsetdefenc slappy + set origPath [testgetencpath] + testsetencpath slappy } -body { - testgetdefenc + testgetencpath } -cleanup { - testsetdefenc $origDir + testsetencpath $origPath } -result slappy file delete {*}[glob -directory [temporaryDirectory] *.chars *.tcltestout] diff --git a/tests/unixInit.test b/tests/unixInit.test index 05338ed..0469ee8 100644 --- a/tests/unixInit.test +++ b/tests/unixInit.test @@ -15,6 +15,9 @@ namespace import ::tcltest::* unset -nocomplain path catch {set oldlang $env(LANG)} set env(LANG) C + +# Some tests require the testgetencpath command +testConstraint testgetencpath [llength [info commands testgetencpath]] test unixInit-1.1 {TclpInitPlatform: ignore SIGPIPE} {unix stdio} { set x {} @@ -87,13 +90,15 @@ test unixInit-1.2 {initialisation: standard channel type deduction} {unix stdio} skip [concat [skip] unixInit-2.*] -test unixInit-2.0 {TclpInitLibraryPath: setting tclDefaultEncodingDir} { - set origDir [testgetdefenc] - testsetdefenc slappy - set path [testgetdefenc] - testsetdefenc $origDir +test unixInit-2.0 {TclpInitLibraryPath: setting tclDefaultEncodingDir} -constraints { + testgetencpath +} -body { + set origPath [testgetencpath] + testsetencpath slappy + set path [testgetencpath] + testsetencpath $origPath set path -} {slappy} +} -result {slappy} test unixInit-2.1 {TclpInitLibraryPath: value of installLib, developLib} -setup { unset -nocomplain oldlibrary if {[info exists env(TCL_LIBRARY)]} { diff --git a/unix/tclUnixTest.c b/unix/tclUnixTest.c index 86e0925..ceb64d9 100644 --- a/unix/tclUnixTest.c +++ b/unix/tclUnixTest.c @@ -68,10 +68,10 @@ static Tcl_CmdProc TestfilehandlerCmd; static Tcl_CmdProc TestfilewaitCmd; static Tcl_CmdProc TestfindexecutableCmd; static Tcl_ObjCmdProc TestforkObjCmd; -static Tcl_CmdProc TestgetdefencdirCmd; +static Tcl_ObjCmdProc TestgetencpathObjCmd; static Tcl_CmdProc TestgetopenfileCmd; static Tcl_CmdProc TestgotsigCmd; -static Tcl_CmdProc TestsetdefencdirCmd; +static Tcl_ObjCmdProc TestsetencpathObjCmd; static Tcl_FileProc TestFileHandlerProc; static void AlarmHandler(int signum); @@ -108,9 +108,9 @@ TclplatformtestInit( NULL, NULL); Tcl_CreateCommand(interp, "testgetopenfile", TestgetopenfileCmd, NULL, NULL); - Tcl_CreateCommand(interp, "testgetdefenc", TestgetdefencdirCmd, + Tcl_CreateObjCommand(interp, "testgetencpath", TestgetencpathObjCmd, NULL, NULL); - Tcl_CreateCommand(interp, "testsetdefenc", TestsetdefencdirCmd, + Tcl_CreateObjCommand(interp, "testsetencpath", TestsetencpathObjCmd, NULL, NULL); Tcl_CreateCommand(interp, "testalarm", TestalarmCmd, NULL, NULL); @@ -499,9 +499,9 @@ TestgetopenfileCmd( /* *---------------------------------------------------------------------- * - * TestsetdefencdirCmd -- + * TestsetencpathCmd -- * - * This function implements the "testsetdefenc" command. It is used to + * This function implements the "testsetencpath" command. It is used to * test Tcl_SetDefaultEncodingDir(). * * Results: @@ -514,19 +514,18 @@ TestgetopenfileCmd( */ static int -TestsetdefencdirCmd( +TestsetencpathObjCmd( ClientData clientData, /* Not used. */ Tcl_Interp *interp, /* Current interpreter. */ - int argc, /* Number of arguments. */ - const char **argv) /* Argument strings. */ + int objc, /* Number of arguments. */ + Tcl_Obj *const *objv) /* Argument strings. */ { - if (argc != 2) { - Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0], - " defaultDir\"", NULL); + if (objc != 2) { + Tcl_WrongNumArgs(interp, 1, objv, "defaultDir"); return TCL_ERROR; } - Tcl_SetDefaultEncodingDir(argv[1]); + Tcl_SetEncodingSearchPath(objv[1]); return TCL_OK; } @@ -552,7 +551,7 @@ TestforkObjCmd( ClientData clientData, /* Not used. */ Tcl_Interp *interp, /* Current interpreter. */ int objc, /* Number of arguments. */ - Tcl_Obj *const *objv) /* Argument strings. */ + Tcl_Obj *const *objv) /* Argument strings. */ { pid_t pid; @@ -578,10 +577,10 @@ TestforkObjCmd( /* *---------------------------------------------------------------------- * - * TestgetdefencdirCmd -- + * TestgetencpathObjCmd -- * - * This function implements the "testgetdefenc" command. It is used to - * test Tcl_GetDefaultEncodingDir(). + * This function implements the "testgetencpath" command. It is used to + * test Tcl_GetEncodingSearchPath(). * * Results: * A standard Tcl result. @@ -593,18 +592,18 @@ TestforkObjCmd( */ static int -TestgetdefencdirCmd( +TestgetencpathObjCmd( ClientData clientData, /* Not used. */ Tcl_Interp *interp, /* Current interpreter. */ - int argc, /* Number of arguments. */ - const char **argv) /* Argument strings. */ + int objc, /* Number of arguments. */ + Tcl_Obj *const *objv) /* Argument strings. */ { - if (argc != 1) { - Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0], NULL); + if (objc != 1) { + Tcl_WrongNumArgs(interp, 1, objv, ""); return TCL_ERROR; } - Tcl_AppendResult(interp, Tcl_GetDefaultEncodingDir(), NULL); + Tcl_SetObjResult(interp, Tcl_GetEncodingSearchPath()); return TCL_OK; } -- cgit v0.12 From dcc8bd9aa801c05f114644fe9f6d520b03b3f812 Mon Sep 17 00:00:00 2001 From: sebres Date: Fri, 12 May 2017 19:58:01 +0000 Subject: Fixed stardate format: be sure positive after decimal point (note: clock-value can be negative - modulo operation in C has the same sign as dividend) --- generic/tclClockFmt.c | 12 +++++++----- tests/clock.test | 51 ++++++++++++++++++++++++++++++++++++--------------- 2 files changed, 43 insertions(+), 20 deletions(-) diff --git a/generic/tclClockFmt.c b/generic/tclClockFmt.c index 70b3ad7..d3cb339 100644 --- a/generic/tclClockFmt.c +++ b/generic/tclClockFmt.c @@ -2489,13 +2489,13 @@ ClockFmtToken_StarDate_Proc( { int fractYear; /* Get day of year, zero based */ - int doy = dateFmt->date.dayOfYear - 1; + int v = dateFmt->date.dayOfYear - 1; /* Convert day of year to a fractional year */ if (IsGregorianLeapYear(&dateFmt->date)) { - fractYear = 1000 * doy / 366; + fractYear = 1000 * v / 366; } else { - fractYear = 1000 * doy / 365; + fractYear = 1000 * v / 365; } /* Put together the StarDate as "Stardate %02d%03d.%1d" */ @@ -2507,8 +2507,10 @@ ClockFmtToken_StarDate_Proc( dateFmt->output = _itoaw(dateFmt->output, fractYear, '0', 3); *dateFmt->output++ = '.'; - dateFmt->output = _itoaw(dateFmt->output, - dateFmt->date.localSeconds % SECONDS_PER_DAY / ( SECONDS_PER_DAY / 10 ), '0', 1); + /* be sure positive after decimal point (note: clock-value can be negative) */ + v = dateFmt->date.localSeconds % SECONDS_PER_DAY / ( SECONDS_PER_DAY / 10 ); + if (v < 0) v = 10 + v; + dateFmt->output = _itoaw(dateFmt->output, v, '0', 1); return TCL_OK; } diff --git a/tests/clock.test b/tests/clock.test index af517c8..5f9a3ec 100644 --- a/tests/clock.test +++ b/tests/clock.test @@ -18647,10 +18647,42 @@ test clock-6.20 {special char tokens %n, %t} { } 1246386600 # Hi, Jeff! +proc _testStarDates {s {days {366*2}} {step {86400}}} { + set step [expr {int($step * 86400)}] + # reconvert - arrange in order of stardate: + set s [set i [clock scan [clock format $s -f "%Q" -g 1] -g 1]] + # test: + set wrong {} + while {$i < $s + $days*86400} { + set d [clock format $i -f "%Q" -g 1] + if {![regexp {^Stardate \d+\.\d$} $d]} { + lappend wrong "wrong: $d -- ($i) -- [clock format $i -g 1]" + } + if {[catch { + set i2 [clock scan $d -f "%Q" -g 1] + } msg]} { + lappend wrong "$d -- ($i) -- [clock format $i -g 1]: $msg" + } + if {$i != $i2} { + lappend wrong "$d -- ($i != $i2) -- [clock format $i -g 1]" + } + incr i $step + } + join $wrong \n +} test clock-6.21.0 {Stardate 0 day} { list [set d [clock format -757382400 -format "%Q" -gmt 1]] \ [clock scan $d -format "%Q" -gmt 1] } [list "Stardate 00000.0" -757382400] +test clock-6.21.0.1 {Stardate 0.1 - 1.9 (test negative clock value -> positive Stardate)} { + _testStarDates -757382400 2 0.1 +} {} +test clock-6.21.0.2 {Stardate 10000.1 - 10002.9 (test negative clock value -> positive Stardate)} { + _testStarDates [clock scan "Stardate 10000.1" -f %Q -g 1] 3 0.1 +} {} +test clock-6.21.0.2 {Stardate 80000.1 - 80002.9 (test positive clock value)} { + _testStarDates [clock scan "Stardate 80001.1" -f %Q -g 1] 3 0.1 +} {} test clock-6.21.1 {Stardate} { list [set d [clock format 1482857280 -format "%Q" -gmt 1]] \ [clock scan $d -format "%Q" -gmt 1] @@ -18659,21 +18691,10 @@ test clock-6.21.2 {Stardate next time} { list [set d [clock format 1482865920 -format "%Q" -gmt 1]] \ [clock scan $d -format "%Q" -gmt 1] } [list "Stardate 70986.8" 1482865920] -test clock-6.21.3 {Stardate correct scan over year (leap year, begin, middle and end of the year)} -body { - set s [clock scan "01.01.2016" -f "%d.%m.%Y" -g 1] - set s [set i [clock scan [clock format $s -f "%Q" -g 1] -g 1]] - set wrong {} - while {[incr i 86400] < $s + 86400*366*2} { - set d [clock format $i -f "%Q" -g 1] - set i2 [clock scan $d -f "%Q" -g 1] - if {$i != $i2} { - lappend wrong "$d -- ($i != $i2) -- [clock format $i -g 1]" - } - } - join $wrong \n -} -result {} -cleanup { - unset -nocomplain wrong i i2 s d -} +test clock-6.21.3 {Stardate correct scan over year (leap year, begin, middle and end of the year)} { + _testStarDates [clock scan "01.01.2016" -f "%d.%m.%Y" -g 1] [expr {366*2}] 1 +} {} +rename _testStarDates {} test clock-6.22.1 {Greedy match} { clock format [clock scan "111" -format "%d%m%y" -gmt 1] -locale en -gmt 1 -- cgit v0.12 From 02d6d68a6834591e799e305cf937b13b205f8b59 Mon Sep 17 00:00:00 2001 From: sebres Date: Tue, 16 May 2017 08:51:51 +0000 Subject: resolved warnings compiled with gcc, removed unused "MsgCtLitIdxs" (was moved to tclClock.c) --- generic/tclClockFmt.c | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/generic/tclClockFmt.c b/generic/tclClockFmt.c index d3cb339..d923ede 100644 --- a/generic/tclClockFmt.c +++ b/generic/tclClockFmt.c @@ -34,9 +34,6 @@ static void ClockFmtScnStorageDelete(ClockFmtScnStorage *fss); static void ClockFrmScnFinalize(ClientData clientData); -/* Msgcat index literals prefixed with _IDX_, used for quick dictionary search */ -CLOCK_LOCALE_LITERAL_ARRAY(MsgCtLitIdxs, "_IDX_"); - /* * Clock scan and format facilities. */ @@ -1906,7 +1903,7 @@ EstimateTokenCount( #define AllocTokenInChain(tok, chain, tokCnt) \ if (++(tok) >= (chain) + (tokCnt)) { \ - *((char **)&chain) = ckrealloc((char *)(chain), \ + chain = ckrealloc((char *)(chain), \ (tokCnt + CLOCK_MIN_TOK_CHAIN_BLOCK_SIZE) * sizeof(*(tok))); \ if ((chain) == NULL) { goto done; }; \ (tok) = (chain) + (tokCnt); \ -- cgit v0.12 From c3077bd013037c9dd95e23e2ed2e69e332287ba9 Mon Sep 17 00:00:00 2001 From: sebres Date: Tue, 16 May 2017 09:16:43 +0000 Subject: optimized special case "-now" of base (by scan or add) or clock value (by format): bypass integer recognition if it looks like option "-now" --- generic/tclClock.c | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/generic/tclClock.c b/generic/tclClock.c index 17c19c3..80740c8 100644 --- a/generic/tclClock.c +++ b/generic/tclClock.c @@ -3110,14 +3110,19 @@ ClockParseFmtScnArgs( /* Base (by scan or add) or clock value (by format) */ if (opts->baseObj != NULL) { - if (TclGetWideIntFromObj(NULL, opts->baseObj, &baseVal) != TCL_OK) { + register Tcl_Obj *baseObj = opts->baseObj; + /* bypass integer recognition if looks like option "-now" */ + if ( + (baseObj->length == 4 && baseObj->bytes && *(baseObj->bytes+1) == 'n') || + TclGetWideIntFromObj(NULL, baseObj, &baseVal) != TCL_OK + ) { /* we accept "-now" as current date-time */ const char *const nowOpts[] = { "-now", NULL }; int idx; - if (Tcl_GetIndexFromObj(NULL, opts->baseObj, nowOpts, "seconds or -now", + if (Tcl_GetIndexFromObj(NULL, baseObj, nowOpts, "seconds or -now", TCL_EXACT, &idx) == TCL_OK ) { goto baseNow; @@ -3125,7 +3130,7 @@ ClockParseFmtScnArgs( Tcl_SetObjResult(interp, Tcl_ObjPrintf( "expected integer but got \"%s\"", - Tcl_GetString(opts->baseObj))); + Tcl_GetString(baseObj))); Tcl_SetErrorCode(interp, "TCL", "VALUE", "INTEGER", NULL); i = 1; goto badOption; @@ -3135,7 +3140,7 @@ ClockParseFmtScnArgs( * that it isn't. */ - if (opts->baseObj->typePtr == &tclBignumType) { + if (baseObj->typePtr == &tclBignumType) { Tcl_SetObjResult(interp, dataPtr->literals[LIT_INTEGER_VALUE_TOO_LARGE]); return TCL_ERROR; } -- cgit v0.12 From 993aa1b3384b98684c0c16c3c0c9df672b389054 Mon Sep 17 00:00:00 2001 From: sebres Date: Tue, 16 May 2017 09:22:17 +0000 Subject: small amend with forgetten static keyword by option --- generic/tclClock.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/generic/tclClock.c b/generic/tclClock.c index 80740c8..c980a27 100644 --- a/generic/tclClock.c +++ b/generic/tclClock.c @@ -3118,7 +3118,7 @@ ClockParseFmtScnArgs( ) { /* we accept "-now" as current date-time */ - const char *const nowOpts[] = { + static const char *const nowOpts[] = { "-now", NULL }; int idx; -- cgit v0.12 From 8bdc7941770d91df0f7f258d97a0bd1951e0a1dd Mon Sep 17 00:00:00 2001 From: "jan.nijtmans" Date: Thu, 18 May 2017 09:16:39 +0000 Subject: Cherry-pick [http://core.tcl.tk/tclconfig/info/18e79736d236d15d|All the world was a VAX] for OpenBSD. Also fix [http://core.tcl.tk/tk/tktview?name=84a27b1c67|84a27b1c67]: Tcl and Tk's tcl.m4 not synced? (configure script not re-generated yet, I'm sure Don will do that in the rc branch) --- library/http/http.tcl | 2 +- unix/tcl.m4 | 49 +++++++++++++------------------------------------ 2 files changed, 14 insertions(+), 37 deletions(-) diff --git a/library/http/http.tcl b/library/http/http.tcl index d950441..0350808 100644 --- a/library/http/http.tcl +++ b/library/http/http.tcl @@ -206,7 +206,7 @@ proc http::Finish {token {errormsg ""} {skipCB 0}} { set state(error) [list $errormsg $errorInfo $errorCode] set state(status) "error" } - if { ($state(status) eq "timeout") + if { ($state(status) eq "timeout") || ($state(status) eq "error") || ([info exists state(-keepalive)] && !$state(-keepalive)) || ([info exists state(connection)] && ($state(connection) eq "close")) diff --git a/unix/tcl.m4 b/unix/tcl.m4 index b21ae31..22fe8c9 100644 --- a/unix/tcl.m4 +++ b/unix/tcl.m4 @@ -1236,9 +1236,9 @@ AC_DEFUN([SC_CONFIG_CFLAGS], [ fi do64bit_ok=yes if test "x${SHARED_BUILD}" = "x1"; then - echo "running cd ${TCL_SRC_DIR}/win; ${CONFIG_SHELL-/bin/sh} ./configure $ac_configure_args" + echo "running cd ../win; ${CONFIG_SHELL-/bin/sh} ./configure $ac_configure_args" # The eval makes quoting arguments work. - if cd ${TCL_SRC_DIR}/win; eval ${CONFIG_SHELL-/bin/sh} ./configure $ac_configure_args; cd ../unix + if cd ../win; eval ${CONFIG_SHELL-/bin/sh} ./configure $ac_configure_args; cd ../unix then : else { echo "configure: error: configure failed for ../win" 1>&2; exit 1; } @@ -1467,44 +1467,21 @@ AC_DEFUN([SC_CONFIG_CFLAGS], [ OpenBSD-*) arch=`arch -s` case "$arch" in - vax) - # Equivalent using configure option --disable-load - # Step 4 will set the necessary variables - DL_OBJS="" - SHLIB_LD_LIBS="" - LDFLAGS="" + alpha|sparc64) + SHLIB_CFLAGS="-fPIC" ;; *) - case "$arch" in - alpha|sparc|sparc64) - SHLIB_CFLAGS="-fPIC" - ;; - *) - SHLIB_CFLAGS="-fpic" - ;; - esac - SHLIB_LD='${CC} -shared ${SHLIB_CFLAGS}' - SHLIB_SUFFIX=".so" - DL_OBJS="tclLoadDl.o" - DL_LIBS="" - AS_IF([test $doRpath = yes], [ - CC_SEARCH_FLAGS='-Wl,-rpath,${LIB_RUNTIME_DIR}']) - LD_SEARCH_FLAGS=${CC_SEARCH_FLAGS} - SHARED_LIB_SUFFIX='${TCL_TRIM_DOTS}.so.${SHLIB_VERSION}' - LDFLAGS="-Wl,-export-dynamic" - ;; - esac - case "$arch" in - vax) - CFLAGS_OPTIMIZE="-O1" - ;; - sh) - CFLAGS_OPTIMIZE="-O0" - ;; - *) - CFLAGS_OPTIMIZE="-O2" + SHLIB_CFLAGS="-fpic" ;; esac + SHLIB_LD='${CC} -shared ${SHLIB_CFLAGS}' + SHLIB_SUFFIX=".so" + AS_IF([test $doRpath = yes], [ + CC_SEARCH_FLAGS='-Wl,-rpath,${LIB_RUNTIME_DIR}']) + LD_SEARCH_FLAGS=${CC_SEARCH_FLAGS} + SHARED_LIB_SUFFIX='${TCL_TRIM_DOTS}.so${SHLIB_VERSION}' + LDFLAGS="-Wl,-export-dynamic" + CFLAGS_OPTIMIZE="-O2" AS_IF([test "${TCL_THREADS}" = "1"], [ # On OpenBSD: Compile with -pthread # Don't link with -lpthread -- cgit v0.12 From 246869993a67bf863fd2d0cf5647e62a9152fae8 Mon Sep 17 00:00:00 2001 From: dgp Date: Thu, 18 May 2017 12:09:00 +0000 Subject: autoconf-2.59 --- unix/configure | 53 +++++++++++++++-------------------------------------- 1 file changed, 15 insertions(+), 38 deletions(-) diff --git a/unix/configure b/unix/configure index 38c3f9a..8531e81 100755 --- a/unix/configure +++ b/unix/configure @@ -6929,9 +6929,9 @@ echo "$as_me: error: CYGWIN compile is only supported with --enable-threads" >&2 fi do64bit_ok=yes if test "x${SHARED_BUILD}" = "x1"; then - echo "running cd ${TCL_SRC_DIR}/win; ${CONFIG_SHELL-/bin/sh} ./configure $ac_configure_args" + echo "running cd ../win; ${CONFIG_SHELL-/bin/sh} ./configure $ac_configure_args" # The eval makes quoting arguments work. - if cd ${TCL_SRC_DIR}/win; eval ${CONFIG_SHELL-/bin/sh} ./configure $ac_configure_args; cd ../unix + if cd ../win; eval ${CONFIG_SHELL-/bin/sh} ./configure $ac_configure_args; cd ../unix then : else { echo "configure: error: configure failed for ../win" 1>&2; exit 1; } @@ -7516,47 +7516,24 @@ fi OpenBSD-*) arch=`arch -s` case "$arch" in - vax) - # Equivalent using configure option --disable-load - # Step 4 will set the necessary variables - DL_OBJS="" - SHLIB_LD_LIBS="" - LDFLAGS="" + alpha|sparc64) + SHLIB_CFLAGS="-fPIC" ;; *) - case "$arch" in - alpha|sparc|sparc64) - SHLIB_CFLAGS="-fPIC" - ;; - *) - SHLIB_CFLAGS="-fpic" - ;; - esac - SHLIB_LD='${CC} -shared ${SHLIB_CFLAGS}' - SHLIB_SUFFIX=".so" - DL_OBJS="tclLoadDl.o" - DL_LIBS="" - if test $doRpath = yes; then + SHLIB_CFLAGS="-fpic" + ;; + esac + SHLIB_LD='${CC} -shared ${SHLIB_CFLAGS}' + SHLIB_SUFFIX=".so" + if test $doRpath = yes; then - CC_SEARCH_FLAGS='-Wl,-rpath,${LIB_RUNTIME_DIR}' + CC_SEARCH_FLAGS='-Wl,-rpath,${LIB_RUNTIME_DIR}' fi - LD_SEARCH_FLAGS=${CC_SEARCH_FLAGS} - SHARED_LIB_SUFFIX='${TCL_TRIM_DOTS}.so.${SHLIB_VERSION}' - LDFLAGS="-Wl,-export-dynamic" - ;; - esac - case "$arch" in - vax) - CFLAGS_OPTIMIZE="-O1" - ;; - sh) - CFLAGS_OPTIMIZE="-O0" - ;; - *) - CFLAGS_OPTIMIZE="-O2" - ;; - esac + LD_SEARCH_FLAGS=${CC_SEARCH_FLAGS} + SHARED_LIB_SUFFIX='${TCL_TRIM_DOTS}.so${SHLIB_VERSION}' + LDFLAGS="-Wl,-export-dynamic" + CFLAGS_OPTIMIZE="-O2" if test "${TCL_THREADS}" = "1"; then # On OpenBSD: Compile with -pthread -- cgit v0.12 From 8b5d3394c2827fa8bfa14ba8169b0139bc58195b Mon Sep 17 00:00:00 2001 From: "jan.nijtmans" Date: Thu, 18 May 2017 13:25:17 +0000 Subject: Fix test-case numbering --- tests/http.test | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/http.test b/tests/http.test index d7e42c2..e8f78e3 100644 --- a/tests/http.test +++ b/tests/http.test @@ -592,7 +592,7 @@ test http-4.15 {http::Event} -body { } -cleanup { catch {http::cleanup $token} } -returnCodes 1 -match glob -result "couldn't open socket*" -test http-1.15 {Leak with Close vs Keepalive (bug [6ca52aec14]} -body { +test http-4.16 {Leak with Close vs Keepalive (bug [6ca52aec14]} -body { set before [chan names] set token [http::geturl $url -headers {X-Connection keep-alive}] http::cleanup $token -- cgit v0.12 From 82ddcc716b49790cf70e81e2a116a93181f4ef12 Mon Sep 17 00:00:00 2001 From: aspect Date: Fri, 19 May 2017 14:21:46 +0000 Subject: fix build failure with TCL_MEM_DEBUG introduced by [8b717dc06a3e3d49] --- generic/tclInt.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/generic/tclInt.h b/generic/tclInt.h index 2938074..7b582c0 100644 --- a/generic/tclInt.h +++ b/generic/tclInt.h @@ -4766,9 +4766,9 @@ MODULE_SCOPE Tcl_PackageInitProc Procbodytest_SafeInit; #define TclSmallFreeEx(interp, memPtr) \ do { \ Tcl_Obj *_objPtr = (Tcl_Obj *) memPtr; \ - objPtr->bytes = NULL; \ - objPtr->typePtr = NULL; \ - objPtr->refCount = 1; \ + _objPtr->bytes = NULL; \ + _objPtr->typePtr = NULL; \ + _objPtr->refCount = 1; \ TclDecrRefCount(_objPtr); \ } while (0) #endif /* TCL_MEM_DEBUG */ -- cgit v0.12 From 62e71e311e8c0f4d38de59686af77451b1754fcb Mon Sep 17 00:00:00 2001 From: stu Date: Sat, 20 May 2017 12:45:31 +0000 Subject: Fix build on OpenBSD. [82701b94c4] missed a couple of bits. Tcl/Tk's tcl.m4 isn't identical to TEA's tcl.m4 - be careful! --- unix/configure | 4 +++- unix/tcl.m4 | 4 +++- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/unix/configure b/unix/configure index 2097111..8b8a464 100755 --- a/unix/configure +++ b/unix/configure @@ -5757,12 +5757,14 @@ fi esac SHLIB_LD='${CC} -shared ${SHLIB_CFLAGS}' SHLIB_SUFFIX=".so" + DL_OBJS="tclLoadDl.o" + DL_LIBS="" if test $doRpath = yes; then : CC_SEARCH_FLAGS='-Wl,-rpath,${LIB_RUNTIME_DIR}' fi LD_SEARCH_FLAGS=${CC_SEARCH_FLAGS} - SHARED_LIB_SUFFIX='${TCL_TRIM_DOTS}.so${SHLIB_VERSION}' + SHARED_LIB_SUFFIX='${TCL_TRIM_DOTS}.so.${SHLIB_VERSION}' LDFLAGS="-Wl,-export-dynamic" CFLAGS_OPTIMIZE="-O2" if test "${TCL_THREADS}" = "1"; then : diff --git a/unix/tcl.m4 b/unix/tcl.m4 index a69715d..559d8f3 100644 --- a/unix/tcl.m4 +++ b/unix/tcl.m4 @@ -1476,10 +1476,12 @@ AC_DEFUN([SC_CONFIG_CFLAGS], [ esac SHLIB_LD='${CC} -shared ${SHLIB_CFLAGS}' SHLIB_SUFFIX=".so" + DL_OBJS="tclLoadDl.o" + DL_LIBS="" AS_IF([test $doRpath = yes], [ CC_SEARCH_FLAGS='-Wl,-rpath,${LIB_RUNTIME_DIR}']) LD_SEARCH_FLAGS=${CC_SEARCH_FLAGS} - SHARED_LIB_SUFFIX='${TCL_TRIM_DOTS}.so${SHLIB_VERSION}' + SHARED_LIB_SUFFIX='${TCL_TRIM_DOTS}.so.${SHLIB_VERSION}' LDFLAGS="-Wl,-export-dynamic" CFLAGS_OPTIMIZE="-O2" AS_IF([test "${TCL_THREADS}" = "1"], [ -- cgit v0.12 From 4db003c2bf902b43e625ae690864201b9d3e51ed Mon Sep 17 00:00:00 2001 From: "jan.nijtmans" Date: Sun, 21 May 2017 17:42:16 +0000 Subject: Cherrypick Fix build on OpenBSD. [82701b94c4] missed a couple of bits. Tcl/Tk's tcl.m4 isn't identical to TEA's tcl.m4 - be careful! --- unix/configure | 4 +++- unix/tcl.m4 | 4 +++- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/unix/configure b/unix/configure index 8531e81..1ebe843 100755 --- a/unix/configure +++ b/unix/configure @@ -7525,13 +7525,15 @@ fi esac SHLIB_LD='${CC} -shared ${SHLIB_CFLAGS}' SHLIB_SUFFIX=".so" + DL_OBJS="tclLoadDl.o" + DL_LIBS="" if test $doRpath = yes; then CC_SEARCH_FLAGS='-Wl,-rpath,${LIB_RUNTIME_DIR}' fi LD_SEARCH_FLAGS=${CC_SEARCH_FLAGS} - SHARED_LIB_SUFFIX='${TCL_TRIM_DOTS}.so${SHLIB_VERSION}' + SHARED_LIB_SUFFIX='${TCL_TRIM_DOTS}.so.${SHLIB_VERSION}' LDFLAGS="-Wl,-export-dynamic" CFLAGS_OPTIMIZE="-O2" if test "${TCL_THREADS}" = "1"; then diff --git a/unix/tcl.m4 b/unix/tcl.m4 index 22fe8c9..26b2a4a 100644 --- a/unix/tcl.m4 +++ b/unix/tcl.m4 @@ -1476,10 +1476,12 @@ AC_DEFUN([SC_CONFIG_CFLAGS], [ esac SHLIB_LD='${CC} -shared ${SHLIB_CFLAGS}' SHLIB_SUFFIX=".so" + DL_OBJS="tclLoadDl.o" + DL_LIBS="" AS_IF([test $doRpath = yes], [ CC_SEARCH_FLAGS='-Wl,-rpath,${LIB_RUNTIME_DIR}']) LD_SEARCH_FLAGS=${CC_SEARCH_FLAGS} - SHARED_LIB_SUFFIX='${TCL_TRIM_DOTS}.so${SHLIB_VERSION}' + SHARED_LIB_SUFFIX='${TCL_TRIM_DOTS}.so.${SHLIB_VERSION}' LDFLAGS="-Wl,-export-dynamic" CFLAGS_OPTIMIZE="-O2" AS_IF([test "${TCL_THREADS}" = "1"], [ -- cgit v0.12 From f100bae7463dd1f68be8be40745c526342bd5e9d Mon Sep 17 00:00:00 2001 From: "jan.nijtmans" Date: Mon, 22 May 2017 08:53:04 +0000 Subject: If SHLIB_VERSION is specified as empty, don't let the SHLIB filename end with a dot (taken over from TEA) Cherry-pick [http://core.tcl.tk/tclconfig/info/c8eddeddb9bbabc4|c8eddeddb9] from TEA: Added /usr/pkg/lib to the paths searched on the journey to find tclConfig.sh --- unix/tcl.m4 | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/unix/tcl.m4 b/unix/tcl.m4 index 26b2a4a..8a802fb 100644 --- a/unix/tcl.m4 +++ b/unix/tcl.m4 @@ -91,8 +91,9 @@ AC_DEFUN([SC_PATH_TCLCONFIG], [ for i in `ls -d ${libdir} 2>/dev/null` \ `ls -d ${exec_prefix}/lib 2>/dev/null` \ `ls -d ${prefix}/lib 2>/dev/null` \ - `ls -d /usr/local/lib 2>/dev/null` \ `ls -d /usr/contrib/lib 2>/dev/null` \ + `ls -d /usr/local/lib 2>/dev/null` \ + `ls -d /usr/pkg/lib 2>/dev/null` \ `ls -d /usr/lib 2>/dev/null` \ `ls -d /usr/lib64 2>/dev/null` \ ; do @@ -611,7 +612,6 @@ AC_DEFUN([SC_ENABLE_FRAMEWORK], [ # TCL_THREADS # _REENTRANT # _THREAD_SAFE -# #------------------------------------------------------------------------ AC_DEFUN([SC_ENABLE_THREADS], [ @@ -727,7 +727,6 @@ AC_DEFUN([SC_ENABLE_THREADS], [ # Sets to $(LDFLAGS_OPTIMIZE) if false # DBGX Formerly used as debug library extension; # always blank now. -# #------------------------------------------------------------------------ AC_DEFUN([SC_ENABLE_SYMBOLS], [ @@ -977,7 +976,7 @@ AC_DEFUN([SC_CONFIG_SYSTEM], [ # SHLIB_LD_LIBS - Dependent libraries for the linker to scan when # creating shared libraries. This symbol typically # goes at the end of the "ld" commands that build -# shared libraries. The value of the symbol is +# shared libraries. The value of the symbol defaults to # "${LIBS}" if all of the dependent libraries should # be specified when creating a shared library. If # dependent libraries should not be specified (as on @@ -1107,7 +1106,7 @@ AC_DEFUN([SC_CONFIG_CFLAGS], [ PLAT_OBJS="" PLAT_SRCS="" LDAIX_SRC="" - AS_IF([test x"${SHLIB_VERSION}" = x], [SHLIB_VERSION="1.0"]) + AS_IF([test "x${SHLIB_VERSION}" = x],[SHLIB_VERSION=".1.0"],[SHLIB_VERSION=".${SHLIB_VERSION}"]) case $system in AIX-*) AS_IF([test "${TCL_THREADS}" = "1" -a "$GCC" != "yes"], [ @@ -1481,7 +1480,7 @@ AC_DEFUN([SC_CONFIG_CFLAGS], [ AS_IF([test $doRpath = yes], [ CC_SEARCH_FLAGS='-Wl,-rpath,${LIB_RUNTIME_DIR}']) LD_SEARCH_FLAGS=${CC_SEARCH_FLAGS} - SHARED_LIB_SUFFIX='${TCL_TRIM_DOTS}.so.${SHLIB_VERSION}' + SHARED_LIB_SUFFIX='${TCL_TRIM_DOTS}.so${SHLIB_VERSION}' LDFLAGS="-Wl,-export-dynamic" CFLAGS_OPTIMIZE="-O2" AS_IF([test "${TCL_THREADS}" = "1"], [ @@ -1804,7 +1803,7 @@ AC_DEFUN([SC_CONFIG_CFLAGS], [ # requires an extra version number at the end of .so file names. # So, the library has to have a name like libtcl75.so.1.0 - SHARED_LIB_SUFFIX='${TCL_TRIM_DOTS}.so.${SHLIB_VERSION}' + SHARED_LIB_SUFFIX='${TCL_TRIM_DOTS}.so${SHLIB_VERSION}' UNSHARED_LIB_SUFFIX='${TCL_TRIM_DOTS}.a' TCL_LIB_VERSIONS_OK=nodots ;; -- cgit v0.12 From c571887777c0fea5679125daa68dc66e94e3f834 Mon Sep 17 00:00:00 2001 From: "jan.nijtmans" Date: Mon, 22 May 2017 09:04:22 +0000 Subject: autoconf --- unix/configure | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/unix/configure b/unix/configure index 1ebe843..3e3b4c4 100755 --- a/unix/configure +++ b/unix/configure @@ -6650,8 +6650,10 @@ fi PLAT_OBJS="" PLAT_SRCS="" LDAIX_SRC="" - if test x"${SHLIB_VERSION}" = x; then - SHLIB_VERSION="1.0" + if test "x${SHLIB_VERSION}" = x; then + SHLIB_VERSION=".1.0" +else + SHLIB_VERSION=".${SHLIB_VERSION}" fi case $system in @@ -7533,7 +7535,7 @@ fi fi LD_SEARCH_FLAGS=${CC_SEARCH_FLAGS} - SHARED_LIB_SUFFIX='${TCL_TRIM_DOTS}.so.${SHLIB_VERSION}' + SHARED_LIB_SUFFIX='${TCL_TRIM_DOTS}.so${SHLIB_VERSION}' LDFLAGS="-Wl,-export-dynamic" CFLAGS_OPTIMIZE="-O2" if test "${TCL_THREADS}" = "1"; then @@ -8274,7 +8276,7 @@ fi # requires an extra version number at the end of .so file names. # So, the library has to have a name like libtcl75.so.1.0 - SHARED_LIB_SUFFIX='${TCL_TRIM_DOTS}.so.${SHLIB_VERSION}' + SHARED_LIB_SUFFIX='${TCL_TRIM_DOTS}.so${SHLIB_VERSION}' UNSHARED_LIB_SUFFIX='${TCL_TRIM_DOTS}.a' TCL_LIB_VERSIONS_OK=nodots ;; -- cgit v0.12 From f3ea991996a821a92f44c7f822766e7d59800f6c Mon Sep 17 00:00:00 2001 From: "jan.nijtmans" Date: Tue, 23 May 2017 14:48:58 +0000 Subject: Update internal tables to Unicode 10.0. Still in Beta, but to be released soon. --- generic/regc_locale.c | 6164 ++++++++++++++++++++++++++++++++++++++++++++++--- generic/tclUniData.c | 1226 +++++----- 2 files changed, 6496 insertions(+), 894 deletions(-) diff --git a/generic/regc_locale.c b/generic/regc_locale.c index ab3b7f1..f0e8439 100644 --- a/generic/regc_locale.c +++ b/generic/regc_locale.c @@ -140,106 +140,1106 @@ static const crange alphaRangeTable[] = { {0x3f7, 0x481}, {0x48a, 0x52f}, {0x531, 0x556}, {0x561, 0x587}, {0x5d0, 0x5ea}, {0x5f0, 0x5f2}, {0x620, 0x64a}, {0x671, 0x6d3}, {0x6fa, 0x6fc}, {0x712, 0x72f}, {0x74d, 0x7a5}, {0x7ca, 0x7ea}, - {0x800, 0x815}, {0x840, 0x858}, {0x8a0, 0x8b4}, {0x8b6, 0x8bd}, - {0x904, 0x939}, {0x958, 0x961}, {0x971, 0x980}, {0x985, 0x98c}, - {0x993, 0x9a8}, {0x9aa, 0x9b0}, {0x9b6, 0x9b9}, {0x9df, 0x9e1}, - {0xa05, 0xa0a}, {0xa13, 0xa28}, {0xa2a, 0xa30}, {0xa59, 0xa5c}, - {0xa72, 0xa74}, {0xa85, 0xa8d}, {0xa8f, 0xa91}, {0xa93, 0xaa8}, - {0xaaa, 0xab0}, {0xab5, 0xab9}, {0xb05, 0xb0c}, {0xb13, 0xb28}, - {0xb2a, 0xb30}, {0xb35, 0xb39}, {0xb5f, 0xb61}, {0xb85, 0xb8a}, - {0xb8e, 0xb90}, {0xb92, 0xb95}, {0xba8, 0xbaa}, {0xbae, 0xbb9}, - {0xc05, 0xc0c}, {0xc0e, 0xc10}, {0xc12, 0xc28}, {0xc2a, 0xc39}, - {0xc58, 0xc5a}, {0xc85, 0xc8c}, {0xc8e, 0xc90}, {0xc92, 0xca8}, - {0xcaa, 0xcb3}, {0xcb5, 0xcb9}, {0xd05, 0xd0c}, {0xd0e, 0xd10}, - {0xd12, 0xd3a}, {0xd54, 0xd56}, {0xd5f, 0xd61}, {0xd7a, 0xd7f}, - {0xd85, 0xd96}, {0xd9a, 0xdb1}, {0xdb3, 0xdbb}, {0xdc0, 0xdc6}, - {0xe01, 0xe30}, {0xe40, 0xe46}, {0xe94, 0xe97}, {0xe99, 0xe9f}, - {0xea1, 0xea3}, {0xead, 0xeb0}, {0xec0, 0xec4}, {0xedc, 0xedf}, - {0xf40, 0xf47}, {0xf49, 0xf6c}, {0xf88, 0xf8c}, {0x1000, 0x102a}, - {0x1050, 0x1055}, {0x105a, 0x105d}, {0x106e, 0x1070}, {0x1075, 0x1081}, - {0x10a0, 0x10c5}, {0x10d0, 0x10fa}, {0x10fc, 0x1248}, {0x124a, 0x124d}, - {0x1250, 0x1256}, {0x125a, 0x125d}, {0x1260, 0x1288}, {0x128a, 0x128d}, - {0x1290, 0x12b0}, {0x12b2, 0x12b5}, {0x12b8, 0x12be}, {0x12c2, 0x12c5}, - {0x12c8, 0x12d6}, {0x12d8, 0x1310}, {0x1312, 0x1315}, {0x1318, 0x135a}, - {0x1380, 0x138f}, {0x13a0, 0x13f5}, {0x13f8, 0x13fd}, {0x1401, 0x166c}, - {0x166f, 0x167f}, {0x1681, 0x169a}, {0x16a0, 0x16ea}, {0x16f1, 0x16f8}, - {0x1700, 0x170c}, {0x170e, 0x1711}, {0x1720, 0x1731}, {0x1740, 0x1751}, - {0x1760, 0x176c}, {0x176e, 0x1770}, {0x1780, 0x17b3}, {0x1820, 0x1877}, - {0x1880, 0x1884}, {0x1887, 0x18a8}, {0x18b0, 0x18f5}, {0x1900, 0x191e}, - {0x1950, 0x196d}, {0x1970, 0x1974}, {0x1980, 0x19ab}, {0x19b0, 0x19c9}, - {0x1a00, 0x1a16}, {0x1a20, 0x1a54}, {0x1b05, 0x1b33}, {0x1b45, 0x1b4b}, - {0x1b83, 0x1ba0}, {0x1bba, 0x1be5}, {0x1c00, 0x1c23}, {0x1c4d, 0x1c4f}, - {0x1c5a, 0x1c7d}, {0x1c80, 0x1c88}, {0x1ce9, 0x1cec}, {0x1cee, 0x1cf1}, - {0x1d00, 0x1dbf}, {0x1e00, 0x1f15}, {0x1f18, 0x1f1d}, {0x1f20, 0x1f45}, - {0x1f48, 0x1f4d}, {0x1f50, 0x1f57}, {0x1f5f, 0x1f7d}, {0x1f80, 0x1fb4}, - {0x1fb6, 0x1fbc}, {0x1fc2, 0x1fc4}, {0x1fc6, 0x1fcc}, {0x1fd0, 0x1fd3}, - {0x1fd6, 0x1fdb}, {0x1fe0, 0x1fec}, {0x1ff2, 0x1ff4}, {0x1ff6, 0x1ffc}, - {0x2090, 0x209c}, {0x210a, 0x2113}, {0x2119, 0x211d}, {0x212a, 0x212d}, - {0x212f, 0x2139}, {0x213c, 0x213f}, {0x2145, 0x2149}, {0x2c00, 0x2c2e}, - {0x2c30, 0x2c5e}, {0x2c60, 0x2ce4}, {0x2ceb, 0x2cee}, {0x2d00, 0x2d25}, - {0x2d30, 0x2d67}, {0x2d80, 0x2d96}, {0x2da0, 0x2da6}, {0x2da8, 0x2dae}, - {0x2db0, 0x2db6}, {0x2db8, 0x2dbe}, {0x2dc0, 0x2dc6}, {0x2dc8, 0x2dce}, - {0x2dd0, 0x2dd6}, {0x2dd8, 0x2dde}, {0x3031, 0x3035}, {0x3041, 0x3096}, - {0x309d, 0x309f}, {0x30a1, 0x30fa}, {0x30fc, 0x30ff}, {0x3105, 0x312d}, - {0x3131, 0x318e}, {0x31a0, 0x31ba}, {0x31f0, 0x31ff}, {0x3400, 0x4db5}, - {0x4e00, 0x9fd5}, {0xa000, 0xa48c}, {0xa4d0, 0xa4fd}, {0xa500, 0xa60c}, - {0xa610, 0xa61f}, {0xa640, 0xa66e}, {0xa67f, 0xa69d}, {0xa6a0, 0xa6e5}, - {0xa717, 0xa71f}, {0xa722, 0xa788}, {0xa78b, 0xa7ae}, {0xa7b0, 0xa7b7}, - {0xa7f7, 0xa801}, {0xa803, 0xa805}, {0xa807, 0xa80a}, {0xa80c, 0xa822}, - {0xa840, 0xa873}, {0xa882, 0xa8b3}, {0xa8f2, 0xa8f7}, {0xa90a, 0xa925}, - {0xa930, 0xa946}, {0xa960, 0xa97c}, {0xa984, 0xa9b2}, {0xa9e0, 0xa9e4}, - {0xa9e6, 0xa9ef}, {0xa9fa, 0xa9fe}, {0xaa00, 0xaa28}, {0xaa40, 0xaa42}, - {0xaa44, 0xaa4b}, {0xaa60, 0xaa76}, {0xaa7e, 0xaaaf}, {0xaab9, 0xaabd}, - {0xaadb, 0xaadd}, {0xaae0, 0xaaea}, {0xaaf2, 0xaaf4}, {0xab01, 0xab06}, - {0xab09, 0xab0e}, {0xab11, 0xab16}, {0xab20, 0xab26}, {0xab28, 0xab2e}, - {0xab30, 0xab5a}, {0xab5c, 0xab65}, {0xab70, 0xabe2}, {0xac00, 0xd7a3}, - {0xd7b0, 0xd7c6}, {0xd7cb, 0xd7fb}, {0xdc00, 0xdc3e}, {0xdc40, 0xdc7e}, - {0xdc80, 0xdcbe}, {0xdcc0, 0xdcfe}, {0xdd00, 0xdd3e}, {0xdd40, 0xdd7e}, - {0xdd80, 0xddbe}, {0xddc0, 0xddfe}, {0xde00, 0xde3e}, {0xde40, 0xde7e}, - {0xde80, 0xdebe}, {0xdec0, 0xdefe}, {0xdf00, 0xdf3e}, {0xdf40, 0xdf7e}, - {0xdf80, 0xdfbe}, {0xdfc0, 0xdffe}, {0xf900, 0xfa6d}, {0xfa70, 0xfad9}, - {0xfb00, 0xfb06}, {0xfb13, 0xfb17}, {0xfb1f, 0xfb28}, {0xfb2a, 0xfb36}, - {0xfb38, 0xfb3c}, {0xfb46, 0xfbb1}, {0xfbd3, 0xfd3d}, {0xfd50, 0xfd8f}, - {0xfd92, 0xfdc7}, {0xfdf0, 0xfdfb}, {0xfe70, 0xfe74}, {0xfe76, 0xfefc}, - {0xff21, 0xff3a}, {0xff41, 0xff5a}, {0xff66, 0xffbe}, {0xffc2, 0xffc7}, - {0xffca, 0xffcf}, {0xffd2, 0xffd7}, {0xffda, 0xffdc} + {0x800, 0x815}, {0x840, 0x858}, {0x860, 0x86a}, {0x8a0, 0x8b4}, + {0x8b6, 0x8bd}, {0x904, 0x939}, {0x958, 0x961}, {0x971, 0x980}, + {0x985, 0x98c}, {0x993, 0x9a8}, {0x9aa, 0x9b0}, {0x9b6, 0x9b9}, + {0x9df, 0x9e1}, {0xa05, 0xa0a}, {0xa13, 0xa28}, {0xa2a, 0xa30}, + {0xa59, 0xa5c}, {0xa72, 0xa74}, {0xa85, 0xa8d}, {0xa8f, 0xa91}, + {0xa93, 0xaa8}, {0xaaa, 0xab0}, {0xab5, 0xab9}, {0xb05, 0xb0c}, + {0xb13, 0xb28}, {0xb2a, 0xb30}, {0xb35, 0xb39}, {0xb5f, 0xb61}, + {0xb85, 0xb8a}, {0xb8e, 0xb90}, {0xb92, 0xb95}, {0xba8, 0xbaa}, + {0xbae, 0xbb9}, {0xc05, 0xc0c}, {0xc0e, 0xc10}, {0xc12, 0xc28}, + {0xc2a, 0xc39}, {0xc58, 0xc5a}, {0xc85, 0xc8c}, {0xc8e, 0xc90}, + {0xc92, 0xca8}, {0xcaa, 0xcb3}, {0xcb5, 0xcb9}, {0xd05, 0xd0c}, + {0xd0e, 0xd10}, {0xd12, 0xd3a}, {0xd54, 0xd56}, {0xd5f, 0xd61}, + {0xd7a, 0xd7f}, {0xd85, 0xd96}, {0xd9a, 0xdb1}, {0xdb3, 0xdbb}, + {0xdc0, 0xdc6}, {0xe01, 0xe30}, {0xe40, 0xe46}, {0xe94, 0xe97}, + {0xe99, 0xe9f}, {0xea1, 0xea3}, {0xead, 0xeb0}, {0xec0, 0xec4}, + {0xedc, 0xedf}, {0xf40, 0xf47}, {0xf49, 0xf6c}, {0xf88, 0xf8c}, + {0x1000, 0x102a}, {0x1050, 0x1055}, {0x105a, 0x105d}, {0x106e, 0x1070}, + {0x1075, 0x1081}, {0x10a0, 0x10c5}, {0x10d0, 0x10fa}, {0x10fc, 0x1248}, + {0x124a, 0x124d}, {0x1250, 0x1256}, {0x125a, 0x125d}, {0x1260, 0x1288}, + {0x128a, 0x128d}, {0x1290, 0x12b0}, {0x12b2, 0x12b5}, {0x12b8, 0x12be}, + {0x12c2, 0x12c5}, {0x12c8, 0x12d6}, {0x12d8, 0x1310}, {0x1312, 0x1315}, + {0x1318, 0x135a}, {0x1380, 0x138f}, {0x13a0, 0x13f5}, {0x13f8, 0x13fd}, + {0x1401, 0x166c}, {0x166f, 0x167f}, {0x1681, 0x169a}, {0x16a0, 0x16ea}, + {0x16f1, 0x16f8}, {0x1700, 0x170c}, {0x170e, 0x1711}, {0x1720, 0x1731}, + {0x1740, 0x1751}, {0x1760, 0x176c}, {0x176e, 0x1770}, {0x1780, 0x17b3}, + {0x1820, 0x1877}, {0x1880, 0x1884}, {0x1887, 0x18a8}, {0x18b0, 0x18f5}, + {0x1900, 0x191e}, {0x1950, 0x196d}, {0x1970, 0x1974}, {0x1980, 0x19ab}, + {0x19b0, 0x19c9}, {0x1a00, 0x1a16}, {0x1a20, 0x1a54}, {0x1b05, 0x1b33}, + {0x1b45, 0x1b4b}, {0x1b83, 0x1ba0}, {0x1bba, 0x1be5}, {0x1c00, 0x1c23}, + {0x1c4d, 0x1c4f}, {0x1c5a, 0x1c7d}, {0x1c80, 0x1c88}, {0x1ce9, 0x1cec}, + {0x1cee, 0x1cf1}, {0x1d00, 0x1dbf}, {0x1e00, 0x1f15}, {0x1f18, 0x1f1d}, + {0x1f20, 0x1f45}, {0x1f48, 0x1f4d}, {0x1f50, 0x1f57}, {0x1f5f, 0x1f7d}, + {0x1f80, 0x1fb4}, {0x1fb6, 0x1fbc}, {0x1fc2, 0x1fc4}, {0x1fc6, 0x1fcc}, + {0x1fd0, 0x1fd3}, {0x1fd6, 0x1fdb}, {0x1fe0, 0x1fec}, {0x1ff2, 0x1ff4}, + {0x1ff6, 0x1ffc}, {0x2090, 0x209c}, {0x210a, 0x2113}, {0x2119, 0x211d}, + {0x212a, 0x212d}, {0x212f, 0x2139}, {0x213c, 0x213f}, {0x2145, 0x2149}, + {0x2c00, 0x2c2e}, {0x2c30, 0x2c5e}, {0x2c60, 0x2ce4}, {0x2ceb, 0x2cee}, + {0x2d00, 0x2d25}, {0x2d30, 0x2d67}, {0x2d80, 0x2d96}, {0x2da0, 0x2da6}, + {0x2da8, 0x2dae}, {0x2db0, 0x2db6}, {0x2db8, 0x2dbe}, {0x2dc0, 0x2dc6}, + {0x2dc8, 0x2dce}, {0x2dd0, 0x2dd6}, {0x2dd8, 0x2dde}, {0x3031, 0x3035}, + {0x3041, 0x3096}, {0x309d, 0x309f}, {0x30a1, 0x30fa}, {0x30fc, 0x30ff}, + {0x3105, 0x312e}, {0x3131, 0x318e}, {0x31a0, 0x31ba}, {0x31f0, 0x31ff}, + {0x3400, 0x4db5}, {0x4e00, 0x9fea}, {0xa000, 0xa48c}, {0xa4d0, 0xa4fd}, + {0xa500, 0xa60c}, {0xa610, 0xa61f}, {0xa640, 0xa66e}, {0xa67f, 0xa69d}, + {0xa6a0, 0xa6e5}, {0xa717, 0xa71f}, {0xa722, 0xa788}, {0xa78b, 0xa7ae}, + {0xa7b0, 0xa7b7}, {0xa7f7, 0xa801}, {0xa803, 0xa805}, {0xa807, 0xa80a}, + {0xa80c, 0xa822}, {0xa840, 0xa873}, {0xa882, 0xa8b3}, {0xa8f2, 0xa8f7}, + {0xa90a, 0xa925}, {0xa930, 0xa946}, {0xa960, 0xa97c}, {0xa984, 0xa9b2}, + {0xa9e0, 0xa9e4}, {0xa9e6, 0xa9ef}, {0xa9fa, 0xa9fe}, {0xaa00, 0xaa28}, + {0xaa40, 0xaa42}, {0xaa44, 0xaa4b}, {0xaa60, 0xaa76}, {0xaa7e, 0xaaaf}, + {0xaab9, 0xaabd}, {0xaadb, 0xaadd}, {0xaae0, 0xaaea}, {0xaaf2, 0xaaf4}, + {0xab01, 0xab06}, {0xab09, 0xab0e}, {0xab11, 0xab16}, {0xab20, 0xab26}, + {0xab28, 0xab2e}, {0xab30, 0xab5a}, {0xab5c, 0xab65}, {0xab70, 0xabe2}, + {0xac00, 0xd7a3}, {0xd7b0, 0xd7c6}, {0xd7cb, 0xd7fb}, {0xf900, 0xfa6d}, + {0xfa70, 0xfad9}, {0xfb00, 0xfb06}, {0xfb13, 0xfb17}, {0xfb1f, 0xfb28}, + {0xfb2a, 0xfb36}, {0xfb38, 0xfb3c}, {0xfb46, 0xfbb1}, {0xfbd3, 0xfd3d}, + {0xfd50, 0xfd8f}, {0xfd92, 0xfdc7}, {0xfdf0, 0xfdfb}, {0xfe70, 0xfe74}, + {0xfe76, 0xfefc}, {0xff21, 0xff3a}, {0xff41, 0xff5a}, {0xff66, 0xffbe}, + {0xffc2, 0xffc7}, {0xffca, 0xffcf}, {0xffd2, 0xffd7}, {0xffda, 0xffdc} #if TCL_UTF_MAX > 4 - ,{0x10000, 0x1000b}, {0x1000d, 0x10026}, {0x10028, 0x1003a}, {0x1003f, 0x1004d}, - {0x10050, 0x1005d}, {0x10080, 0x100fa}, {0x10280, 0x1029c}, {0x102a0, 0x102d0}, - {0x10300, 0x1031f}, {0x10330, 0x10340}, {0x10342, 0x10349}, {0x10350, 0x10375}, - {0x10380, 0x1039d}, {0x103a0, 0x103c3}, {0x103c8, 0x103cf}, {0x10400, 0x1049d}, - {0x104b0, 0x104d3}, {0x104d8, 0x104fb}, {0x10500, 0x10527}, {0x10530, 0x10563}, - {0x10600, 0x10736}, {0x10740, 0x10755}, {0x10760, 0x10767}, {0x10800, 0x10805}, - {0x1080a, 0x10835}, {0x1083f, 0x10855}, {0x10860, 0x10876}, {0x10880, 0x1089e}, - {0x108e0, 0x108f2}, {0x10900, 0x10915}, {0x10920, 0x10939}, {0x10980, 0x109b7}, - {0x10a10, 0x10a13}, {0x10a15, 0x10a17}, {0x10a19, 0x10a33}, {0x10a60, 0x10a7c}, - {0x10a80, 0x10a9c}, {0x10ac0, 0x10ac7}, {0x10ac9, 0x10ae4}, {0x10b00, 0x10b35}, - {0x10b40, 0x10b55}, {0x10b60, 0x10b72}, {0x10b80, 0x10b91}, {0x10c00, 0x10c48}, - {0x10c80, 0x10cb2}, {0x10cc0, 0x10cf2}, {0x11003, 0x11037}, {0x11083, 0x110af}, - {0x110d0, 0x110e8}, {0x11103, 0x11126}, {0x11150, 0x11172}, {0x11183, 0x111b2}, - {0x111c1, 0x111c4}, {0x11200, 0x11211}, {0x11213, 0x1122b}, {0x11280, 0x11286}, - {0x1128a, 0x1128d}, {0x1128f, 0x1129d}, {0x1129f, 0x112a8}, {0x112b0, 0x112de}, - {0x11305, 0x1130c}, {0x11313, 0x11328}, {0x1132a, 0x11330}, {0x11335, 0x11339}, - {0x1135d, 0x11361}, {0x11400, 0x11434}, {0x11447, 0x1144a}, {0x11480, 0x114af}, - {0x11580, 0x115ae}, {0x115d8, 0x115db}, {0x11600, 0x1162f}, {0x11680, 0x116aa}, - {0x11700, 0x11719}, {0x118a0, 0x118df}, {0x11ac0, 0x11af8}, {0x11c00, 0x11c08}, - {0x11c0a, 0x11c2e}, {0x11c72, 0x11c8f}, {0x12000, 0x12399}, {0x12480, 0x12543}, - {0x13000, 0x1342e}, {0x14400, 0x14646}, {0x16800, 0x16a38}, {0x16a40, 0x16a5e}, - {0x16ad0, 0x16aed}, {0x16b00, 0x16b2f}, {0x16b40, 0x16b43}, {0x16b63, 0x16b77}, - {0x16b7d, 0x16b8f}, {0x16f00, 0x16f44}, {0x16f93, 0x16f9f}, {0x17000, 0x187ec}, - {0x18800, 0x18af2}, {0x1bc00, 0x1bc6a}, {0x1bc70, 0x1bc7c}, {0x1bc80, 0x1bc88}, - {0x1bc90, 0x1bc99}, {0x1d400, 0x1d454}, {0x1d456, 0x1d49c}, {0x1d4a9, 0x1d4ac}, - {0x1d4ae, 0x1d4b9}, {0x1d4bd, 0x1d4c3}, {0x1d4c5, 0x1d505}, {0x1d507, 0x1d50a}, - {0x1d50d, 0x1d514}, {0x1d516, 0x1d51c}, {0x1d51e, 0x1d539}, {0x1d53b, 0x1d53e}, - {0x1d540, 0x1d544}, {0x1d54a, 0x1d550}, {0x1d552, 0x1d6a5}, {0x1d6a8, 0x1d6c0}, - {0x1d6c2, 0x1d6da}, {0x1d6dc, 0x1d6fa}, {0x1d6fc, 0x1d714}, {0x1d716, 0x1d734}, - {0x1d736, 0x1d74e}, {0x1d750, 0x1d76e}, {0x1d770, 0x1d788}, {0x1d78a, 0x1d7a8}, - {0x1d7aa, 0x1d7c2}, {0x1d7c4, 0x1d7cb}, {0x1e800, 0x1e8c4}, {0x1e900, 0x1e943}, - {0x1ee00, 0x1ee03}, {0x1ee05, 0x1ee1f}, {0x1ee29, 0x1ee32}, {0x1ee34, 0x1ee37}, - {0x1ee4d, 0x1ee4f}, {0x1ee67, 0x1ee6a}, {0x1ee6c, 0x1ee72}, {0x1ee74, 0x1ee77}, - {0x1ee79, 0x1ee7c}, {0x1ee80, 0x1ee89}, {0x1ee8b, 0x1ee9b}, {0x1eea1, 0x1eea3}, - {0x1eea5, 0x1eea9}, {0x1eeab, 0x1eebb}, {0x20000, 0x2a6d6}, {0x2a700, 0x2b734}, - {0x2b740, 0x2b81d}, {0x2b820, 0x2cea1}, {0x2f800, 0x2fa1d} + ,{0x10041, 0x1005a}, {0x10061, 0x1007a}, {0x100c0, 0x100d6}, {0x100d8, 0x100f6}, + {0x100f8, 0x102c1}, {0x102c6, 0x102d1}, {0x102e0, 0x102e4}, {0x10370, 0x10374}, + {0x1037a, 0x1037d}, {0x10388, 0x1038a}, {0x1038e, 0x103a1}, {0x103a3, 0x103f5}, + {0x103f7, 0x10481}, {0x1048a, 0x1052f}, {0x10531, 0x10556}, {0x10561, 0x10587}, + {0x105d0, 0x105ea}, {0x105f0, 0x105f2}, {0x10620, 0x1064a}, {0x10671, 0x106d3}, + {0x106fa, 0x106fc}, {0x10712, 0x1072f}, {0x1074d, 0x107a5}, {0x107ca, 0x107ea}, + {0x10800, 0x10815}, {0x10840, 0x10858}, {0x10860, 0x1086a}, {0x108a0, 0x108b4}, + {0x108b6, 0x108bd}, {0x10904, 0x10939}, {0x10958, 0x10961}, {0x10971, 0x10980}, + {0x10985, 0x1098c}, {0x10993, 0x109a8}, {0x109aa, 0x109b0}, {0x109b6, 0x109b9}, + {0x109df, 0x109e1}, {0x10a05, 0x10a0a}, {0x10a13, 0x10a28}, {0x10a2a, 0x10a30}, + {0x10a59, 0x10a5c}, {0x10a72, 0x10a74}, {0x10a85, 0x10a8d}, {0x10a8f, 0x10a91}, + {0x10a93, 0x10aa8}, {0x10aaa, 0x10ab0}, {0x10ab5, 0x10ab9}, {0x10b05, 0x10b0c}, + {0x10b13, 0x10b28}, {0x10b2a, 0x10b30}, {0x10b35, 0x10b39}, {0x10b5f, 0x10b61}, + {0x10b85, 0x10b8a}, {0x10b8e, 0x10b90}, {0x10b92, 0x10b95}, {0x10ba8, 0x10baa}, + {0x10bae, 0x10bb9}, {0x10c05, 0x10c0c}, {0x10c0e, 0x10c10}, {0x10c12, 0x10c28}, + {0x10c2a, 0x10c39}, {0x10c58, 0x10c5a}, {0x10c85, 0x10c8c}, {0x10c8e, 0x10c90}, + {0x10c92, 0x10ca8}, {0x10caa, 0x10cb3}, {0x10cb5, 0x10cb9}, {0x10d05, 0x10d0c}, + {0x10d0e, 0x10d10}, {0x10d12, 0x10d3a}, {0x10d54, 0x10d56}, {0x10d5f, 0x10d61}, + {0x10d7a, 0x10d7f}, {0x10d85, 0x10d96}, {0x10d9a, 0x10db1}, {0x10db3, 0x10dbb}, + {0x10dc0, 0x10dc6}, {0x10e01, 0x10e30}, {0x10e40, 0x10e46}, {0x10e94, 0x10e97}, + {0x10e99, 0x10e9f}, {0x10ea1, 0x10ea3}, {0x10ead, 0x10eb0}, {0x10ec0, 0x10ec4}, + {0x10edc, 0x10edf}, {0x10f40, 0x10f47}, {0x10f49, 0x10f6c}, {0x10f88, 0x10f8c}, + {0x11000, 0x1102a}, {0x11050, 0x11055}, {0x1105a, 0x1105d}, {0x1106e, 0x11070}, + {0x11075, 0x11081}, {0x110a0, 0x110c5}, {0x110d0, 0x110fa}, {0x110fc, 0x11248}, + {0x1124a, 0x1124d}, {0x11250, 0x11256}, {0x1125a, 0x1125d}, {0x11260, 0x11288}, + {0x1128a, 0x1128d}, {0x11290, 0x112b0}, {0x112b2, 0x112b5}, {0x112b8, 0x112be}, + {0x112c2, 0x112c5}, {0x112c8, 0x112d6}, {0x112d8, 0x11310}, {0x11312, 0x11315}, + {0x11318, 0x1135a}, {0x11380, 0x1138f}, {0x113a0, 0x113f5}, {0x113f8, 0x113fd}, + {0x11401, 0x1166c}, {0x1166f, 0x1167f}, {0x11681, 0x1169a}, {0x116a0, 0x116ea}, + {0x116f1, 0x116f8}, {0x11700, 0x1170c}, {0x1170e, 0x11711}, {0x11720, 0x11731}, + {0x11740, 0x11751}, {0x11760, 0x1176c}, {0x1176e, 0x11770}, {0x11780, 0x117b3}, + {0x11820, 0x11877}, {0x11880, 0x11884}, {0x11887, 0x118a8}, {0x118b0, 0x118f5}, + {0x11900, 0x1191e}, {0x11950, 0x1196d}, {0x11970, 0x11974}, {0x11980, 0x119ab}, + {0x119b0, 0x119c9}, {0x11a00, 0x11a16}, {0x11a20, 0x11a54}, {0x11b05, 0x11b33}, + {0x11b45, 0x11b4b}, {0x11b83, 0x11ba0}, {0x11bba, 0x11be5}, {0x11c00, 0x11c23}, + {0x11c4d, 0x11c4f}, {0x11c5a, 0x11c7d}, {0x11c80, 0x11c88}, {0x11ce9, 0x11cec}, + {0x11cee, 0x11cf1}, {0x11d00, 0x11dbf}, {0x11e00, 0x11f15}, {0x11f18, 0x11f1d}, + {0x11f20, 0x11f45}, {0x11f48, 0x11f4d}, {0x11f50, 0x11f57}, {0x11f5f, 0x11f7d}, + {0x11f80, 0x11fb4}, {0x11fb6, 0x11fbc}, {0x11fc2, 0x11fc4}, {0x11fc6, 0x11fcc}, + {0x11fd0, 0x11fd3}, {0x11fd6, 0x11fdb}, {0x11fe0, 0x11fec}, {0x11ff2, 0x11ff4}, + {0x11ff6, 0x11ffc}, {0x12090, 0x1209c}, {0x1210a, 0x12113}, {0x12119, 0x1211d}, + {0x1212a, 0x1212d}, {0x1212f, 0x12139}, {0x1213c, 0x1213f}, {0x12145, 0x12149}, + {0x12c00, 0x12c2e}, {0x12c30, 0x12c5e}, {0x12c60, 0x12ce4}, {0x12ceb, 0x12cee}, + {0x12d00, 0x12d25}, {0x12d30, 0x12d67}, {0x12d80, 0x12d96}, {0x12da0, 0x12da6}, + {0x12da8, 0x12dae}, {0x12db0, 0x12db6}, {0x12db8, 0x12dbe}, {0x12dc0, 0x12dc6}, + {0x12dc8, 0x12dce}, {0x12dd0, 0x12dd6}, {0x12dd8, 0x12dde}, {0x13031, 0x13035}, + {0x13041, 0x13096}, {0x1309d, 0x1309f}, {0x130a1, 0x130fa}, {0x130fc, 0x130ff}, + {0x13105, 0x1312e}, {0x13131, 0x1318e}, {0x131a0, 0x131ba}, {0x131f0, 0x131ff}, + {0x13400, 0x14db5}, {0x14e00, 0x19fea}, {0x1a000, 0x1a48c}, {0x1a4d0, 0x1a4fd}, + {0x1a500, 0x1a60c}, {0x1a610, 0x1a61f}, {0x1a640, 0x1a66e}, {0x1a67f, 0x1a69d}, + {0x1a6a0, 0x1a6e5}, {0x1a717, 0x1a71f}, {0x1a722, 0x1a788}, {0x1a78b, 0x1a7ae}, + {0x1a7b0, 0x1a7b7}, {0x1a7f7, 0x1a801}, {0x1a803, 0x1a805}, {0x1a807, 0x1a80a}, + {0x1a80c, 0x1a822}, {0x1a840, 0x1a873}, {0x1a882, 0x1a8b3}, {0x1a8f2, 0x1a8f7}, + {0x1a90a, 0x1a925}, {0x1a930, 0x1a946}, {0x1a960, 0x1a97c}, {0x1a984, 0x1a9b2}, + {0x1a9e0, 0x1a9e4}, {0x1a9e6, 0x1a9ef}, {0x1a9fa, 0x1a9fe}, {0x1aa00, 0x1aa28}, + {0x1aa40, 0x1aa42}, {0x1aa44, 0x1aa4b}, {0x1aa60, 0x1aa76}, {0x1aa7e, 0x1aaaf}, + {0x1aab9, 0x1aabd}, {0x1aadb, 0x1aadd}, {0x1aae0, 0x1aaea}, {0x1aaf2, 0x1aaf4}, + {0x1ab01, 0x1ab06}, {0x1ab09, 0x1ab0e}, {0x1ab11, 0x1ab16}, {0x1ab20, 0x1ab26}, + {0x1ab28, 0x1ab2e}, {0x1ab30, 0x1ab5a}, {0x1ab5c, 0x1ab65}, {0x1ab70, 0x1abe2}, + {0x1ac00, 0x1d7a3}, {0x1d7b0, 0x1d7c6}, {0x1d7cb, 0x1d7fb}, {0x1f900, 0x1fa6d}, + {0x1fa70, 0x1fad9}, {0x1fb00, 0x1fb06}, {0x1fb13, 0x1fb17}, {0x1fb1f, 0x1fb28}, + {0x1fb2a, 0x1fb36}, {0x1fb38, 0x1fb3c}, {0x1fb46, 0x1fbb1}, {0x1fbd3, 0x1fd3d}, + {0x1fd50, 0x1fd8f}, {0x1fd92, 0x1fdc7}, {0x1fdf0, 0x1fdfb}, {0x1fe70, 0x1fe74}, + {0x1fe76, 0x1fefc}, {0x1ff21, 0x1ff3a}, {0x1ff41, 0x1ff5a}, {0x1ff66, 0x1ffbe}, + {0x1ffc2, 0x1ffc7}, {0x1ffca, 0x1ffcf}, {0x1ffd2, 0x1ffd7}, {0x1ffda, 0x1ffdc}, + {0x20041, 0x2005a}, {0x20061, 0x2007a}, {0x200c0, 0x200d6}, {0x200d8, 0x200f6}, + {0x200f8, 0x202c1}, {0x202c6, 0x202d1}, {0x202e0, 0x202e4}, {0x20370, 0x20374}, + {0x2037a, 0x2037d}, {0x20388, 0x2038a}, {0x2038e, 0x203a1}, {0x203a3, 0x203f5}, + {0x203f7, 0x20481}, {0x2048a, 0x2052f}, {0x20531, 0x20556}, {0x20561, 0x20587}, + {0x205d0, 0x205ea}, {0x205f0, 0x205f2}, {0x20620, 0x2064a}, {0x20671, 0x206d3}, + {0x206fa, 0x206fc}, {0x20712, 0x2072f}, {0x2074d, 0x207a5}, {0x207ca, 0x207ea}, + {0x20800, 0x20815}, {0x20840, 0x20858}, {0x20860, 0x2086a}, {0x208a0, 0x208b4}, + {0x208b6, 0x208bd}, {0x20904, 0x20939}, {0x20958, 0x20961}, {0x20971, 0x20980}, + {0x20985, 0x2098c}, {0x20993, 0x209a8}, {0x209aa, 0x209b0}, {0x209b6, 0x209b9}, + {0x209df, 0x209e1}, {0x20a05, 0x20a0a}, {0x20a13, 0x20a28}, {0x20a2a, 0x20a30}, + {0x20a59, 0x20a5c}, {0x20a72, 0x20a74}, {0x20a85, 0x20a8d}, {0x20a8f, 0x20a91}, + {0x20a93, 0x20aa8}, {0x20aaa, 0x20ab0}, {0x20ab5, 0x20ab9}, {0x20b05, 0x20b0c}, + {0x20b13, 0x20b28}, {0x20b2a, 0x20b30}, {0x20b35, 0x20b39}, {0x20b5f, 0x20b61}, + {0x20b85, 0x20b8a}, {0x20b8e, 0x20b90}, {0x20b92, 0x20b95}, {0x20ba8, 0x20baa}, + {0x20bae, 0x20bb9}, {0x20c05, 0x20c0c}, {0x20c0e, 0x20c10}, {0x20c12, 0x20c28}, + {0x20c2a, 0x20c39}, {0x20c58, 0x20c5a}, {0x20c85, 0x20c8c}, {0x20c8e, 0x20c90}, + {0x20c92, 0x20ca8}, {0x20caa, 0x20cb3}, {0x20cb5, 0x20cb9}, {0x20d05, 0x20d0c}, + {0x20d0e, 0x20d10}, {0x20d12, 0x20d3a}, {0x20d54, 0x20d56}, {0x20d5f, 0x20d61}, + {0x20d7a, 0x20d7f}, {0x20d85, 0x20d96}, {0x20d9a, 0x20db1}, {0x20db3, 0x20dbb}, + {0x20dc0, 0x20dc6}, {0x20e01, 0x20e30}, {0x20e40, 0x20e46}, {0x20e94, 0x20e97}, + {0x20e99, 0x20e9f}, {0x20ea1, 0x20ea3}, {0x20ead, 0x20eb0}, {0x20ec0, 0x20ec4}, + {0x20edc, 0x20edf}, {0x20f40, 0x20f47}, {0x20f49, 0x20f6c}, {0x20f88, 0x20f8c}, + {0x21000, 0x2102a}, {0x21050, 0x21055}, {0x2105a, 0x2105d}, {0x2106e, 0x21070}, + {0x21075, 0x21081}, {0x210a0, 0x210c5}, {0x210d0, 0x210fa}, {0x210fc, 0x21248}, + {0x2124a, 0x2124d}, {0x21250, 0x21256}, {0x2125a, 0x2125d}, {0x21260, 0x21288}, + {0x2128a, 0x2128d}, {0x21290, 0x212b0}, {0x212b2, 0x212b5}, {0x212b8, 0x212be}, + {0x212c2, 0x212c5}, {0x212c8, 0x212d6}, {0x212d8, 0x21310}, {0x21312, 0x21315}, + {0x21318, 0x2135a}, {0x21380, 0x2138f}, {0x213a0, 0x213f5}, {0x213f8, 0x213fd}, + {0x21401, 0x2166c}, {0x2166f, 0x2167f}, {0x21681, 0x2169a}, {0x216a0, 0x216ea}, + {0x216f1, 0x216f8}, {0x21700, 0x2170c}, {0x2170e, 0x21711}, {0x21720, 0x21731}, + {0x21740, 0x21751}, {0x21760, 0x2176c}, {0x2176e, 0x21770}, {0x21780, 0x217b3}, + {0x21820, 0x21877}, {0x21880, 0x21884}, {0x21887, 0x218a8}, {0x218b0, 0x218f5}, + {0x21900, 0x2191e}, {0x21950, 0x2196d}, {0x21970, 0x21974}, {0x21980, 0x219ab}, + {0x219b0, 0x219c9}, {0x21a00, 0x21a16}, {0x21a20, 0x21a54}, {0x21b05, 0x21b33}, + {0x21b45, 0x21b4b}, {0x21b83, 0x21ba0}, {0x21bba, 0x21be5}, {0x21c00, 0x21c23}, + {0x21c4d, 0x21c4f}, {0x21c5a, 0x21c7d}, {0x21c80, 0x21c88}, {0x21ce9, 0x21cec}, + {0x21cee, 0x21cf1}, {0x21d00, 0x21dbf}, {0x21e00, 0x21f15}, {0x21f18, 0x21f1d}, + {0x21f20, 0x21f45}, {0x21f48, 0x21f4d}, {0x21f50, 0x21f57}, {0x21f5f, 0x21f7d}, + {0x21f80, 0x21fb4}, {0x21fb6, 0x21fbc}, {0x21fc2, 0x21fc4}, {0x21fc6, 0x21fcc}, + {0x21fd0, 0x21fd3}, {0x21fd6, 0x21fdb}, {0x21fe0, 0x21fec}, {0x21ff2, 0x21ff4}, + {0x21ff6, 0x21ffc}, {0x22090, 0x2209c}, {0x2210a, 0x22113}, {0x22119, 0x2211d}, + {0x2212a, 0x2212d}, {0x2212f, 0x22139}, {0x2213c, 0x2213f}, {0x22145, 0x22149}, + {0x22c00, 0x22c2e}, {0x22c30, 0x22c5e}, {0x22c60, 0x22ce4}, {0x22ceb, 0x22cee}, + {0x22d00, 0x22d25}, {0x22d30, 0x22d67}, {0x22d80, 0x22d96}, {0x22da0, 0x22da6}, + {0x22da8, 0x22dae}, {0x22db0, 0x22db6}, {0x22db8, 0x22dbe}, {0x22dc0, 0x22dc6}, + {0x22dc8, 0x22dce}, {0x22dd0, 0x22dd6}, {0x22dd8, 0x22dde}, {0x23031, 0x23035}, + {0x23041, 0x23096}, {0x2309d, 0x2309f}, {0x230a1, 0x230fa}, {0x230fc, 0x230ff}, + {0x23105, 0x2312e}, {0x23131, 0x2318e}, {0x231a0, 0x231ba}, {0x231f0, 0x231ff}, + {0x23400, 0x24db5}, {0x24e00, 0x29fea}, {0x2a000, 0x2a48c}, {0x2a4d0, 0x2a4fd}, + {0x2a500, 0x2a60c}, {0x2a610, 0x2a61f}, {0x2a640, 0x2a66e}, {0x2a67f, 0x2a69d}, + {0x2a6a0, 0x2a6e5}, {0x2a717, 0x2a71f}, {0x2a722, 0x2a788}, {0x2a78b, 0x2a7ae}, + {0x2a7b0, 0x2a7b7}, {0x2a7f7, 0x2a801}, {0x2a803, 0x2a805}, {0x2a807, 0x2a80a}, + {0x2a80c, 0x2a822}, {0x2a840, 0x2a873}, {0x2a882, 0x2a8b3}, {0x2a8f2, 0x2a8f7}, + {0x2a90a, 0x2a925}, {0x2a930, 0x2a946}, {0x2a960, 0x2a97c}, {0x2a984, 0x2a9b2}, + {0x2a9e0, 0x2a9e4}, {0x2a9e6, 0x2a9ef}, {0x2a9fa, 0x2a9fe}, {0x2aa00, 0x2aa28}, + {0x2aa40, 0x2aa42}, {0x2aa44, 0x2aa4b}, {0x2aa60, 0x2aa76}, {0x2aa7e, 0x2aaaf}, + {0x2aab9, 0x2aabd}, {0x2aadb, 0x2aadd}, {0x2aae0, 0x2aaea}, {0x2aaf2, 0x2aaf4}, + {0x2ab01, 0x2ab06}, {0x2ab09, 0x2ab0e}, {0x2ab11, 0x2ab16}, {0x2ab20, 0x2ab26}, + {0x2ab28, 0x2ab2e}, {0x2ab30, 0x2ab5a}, {0x2ab5c, 0x2ab65}, {0x2ab70, 0x2abe2}, + {0x2ac00, 0x2d7a3}, {0x2d7b0, 0x2d7c6}, {0x2d7cb, 0x2d7fb}, {0x2f900, 0x2fa6d}, + {0x2fa70, 0x2fad9}, {0x2fb00, 0x2fb06}, {0x2fb13, 0x2fb17}, {0x2fb1f, 0x2fb28}, + {0x2fb2a, 0x2fb36}, {0x2fb38, 0x2fb3c}, {0x2fb46, 0x2fbb1}, {0x2fbd3, 0x2fd3d}, + {0x2fd50, 0x2fd8f}, {0x2fd92, 0x2fdc7}, {0x2fdf0, 0x2fdfb}, {0x2fe70, 0x2fe74}, + {0x2fe76, 0x2fefc}, {0x2ff21, 0x2ff3a}, {0x2ff41, 0x2ff5a}, {0x2ff66, 0x2ffbe}, + {0x2ffc2, 0x2ffc7}, {0x2ffca, 0x2ffcf}, {0x2ffd2, 0x2ffd7}, {0x2ffda, 0x2ffdc}, + {0x30041, 0x3005a}, {0x30061, 0x3007a}, {0x300c0, 0x300d6}, {0x300d8, 0x300f6}, + {0x300f8, 0x302c1}, {0x302c6, 0x302d1}, {0x302e0, 0x302e4}, {0x30370, 0x30374}, + {0x3037a, 0x3037d}, {0x30388, 0x3038a}, {0x3038e, 0x303a1}, {0x303a3, 0x303f5}, + {0x303f7, 0x30481}, {0x3048a, 0x3052f}, {0x30531, 0x30556}, {0x30561, 0x30587}, + {0x305d0, 0x305ea}, {0x305f0, 0x305f2}, {0x30620, 0x3064a}, {0x30671, 0x306d3}, + {0x306fa, 0x306fc}, {0x30712, 0x3072f}, {0x3074d, 0x307a5}, {0x307ca, 0x307ea}, + {0x30800, 0x30815}, {0x30840, 0x30858}, {0x30860, 0x3086a}, {0x308a0, 0x308b4}, + {0x308b6, 0x308bd}, {0x30904, 0x30939}, {0x30958, 0x30961}, {0x30971, 0x30980}, + {0x30985, 0x3098c}, {0x30993, 0x309a8}, {0x309aa, 0x309b0}, {0x309b6, 0x309b9}, + {0x309df, 0x309e1}, {0x30a05, 0x30a0a}, {0x30a13, 0x30a28}, {0x30a2a, 0x30a30}, + {0x30a59, 0x30a5c}, {0x30a72, 0x30a74}, {0x30a85, 0x30a8d}, {0x30a8f, 0x30a91}, + {0x30a93, 0x30aa8}, {0x30aaa, 0x30ab0}, {0x30ab5, 0x30ab9}, {0x30b05, 0x30b0c}, + {0x30b13, 0x30b28}, {0x30b2a, 0x30b30}, {0x30b35, 0x30b39}, {0x30b5f, 0x30b61}, + {0x30b85, 0x30b8a}, {0x30b8e, 0x30b90}, {0x30b92, 0x30b95}, {0x30ba8, 0x30baa}, + {0x30bae, 0x30bb9}, {0x30c05, 0x30c0c}, {0x30c0e, 0x30c10}, {0x30c12, 0x30c28}, + {0x30c2a, 0x30c39}, {0x30c58, 0x30c5a}, {0x30c85, 0x30c8c}, {0x30c8e, 0x30c90}, + {0x30c92, 0x30ca8}, {0x30caa, 0x30cb3}, {0x30cb5, 0x30cb9}, {0x30d05, 0x30d0c}, + {0x30d0e, 0x30d10}, {0x30d12, 0x30d3a}, {0x30d54, 0x30d56}, {0x30d5f, 0x30d61}, + {0x30d7a, 0x30d7f}, {0x30d85, 0x30d96}, {0x30d9a, 0x30db1}, {0x30db3, 0x30dbb}, + {0x30dc0, 0x30dc6}, {0x30e01, 0x30e30}, {0x30e40, 0x30e46}, {0x30e94, 0x30e97}, + {0x30e99, 0x30e9f}, {0x30ea1, 0x30ea3}, {0x30ead, 0x30eb0}, {0x30ec0, 0x30ec4}, + {0x30edc, 0x30edf}, {0x30f40, 0x30f47}, {0x30f49, 0x30f6c}, {0x30f88, 0x30f8c}, + {0x31000, 0x3102a}, {0x31050, 0x31055}, {0x3105a, 0x3105d}, {0x3106e, 0x31070}, + {0x31075, 0x31081}, {0x310a0, 0x310c5}, {0x310d0, 0x310fa}, {0x310fc, 0x31248}, + {0x3124a, 0x3124d}, {0x31250, 0x31256}, {0x3125a, 0x3125d}, {0x31260, 0x31288}, + {0x3128a, 0x3128d}, {0x31290, 0x312b0}, {0x312b2, 0x312b5}, {0x312b8, 0x312be}, + {0x312c2, 0x312c5}, {0x312c8, 0x312d6}, {0x312d8, 0x31310}, {0x31312, 0x31315}, + {0x31318, 0x3135a}, {0x31380, 0x3138f}, {0x313a0, 0x313f5}, {0x313f8, 0x313fd}, + {0x31401, 0x3166c}, {0x3166f, 0x3167f}, {0x31681, 0x3169a}, {0x316a0, 0x316ea}, + {0x316f1, 0x316f8}, {0x31700, 0x3170c}, {0x3170e, 0x31711}, {0x31720, 0x31731}, + {0x31740, 0x31751}, {0x31760, 0x3176c}, {0x3176e, 0x31770}, {0x31780, 0x317b3}, + {0x31820, 0x31877}, {0x31880, 0x31884}, {0x31887, 0x318a8}, {0x318b0, 0x318f5}, + {0x31900, 0x3191e}, {0x31950, 0x3196d}, {0x31970, 0x31974}, {0x31980, 0x319ab}, + {0x319b0, 0x319c9}, {0x31a00, 0x31a16}, {0x31a20, 0x31a54}, {0x31b05, 0x31b33}, + {0x31b45, 0x31b4b}, {0x31b83, 0x31ba0}, {0x31bba, 0x31be5}, {0x31c00, 0x31c23}, + {0x31c4d, 0x31c4f}, {0x31c5a, 0x31c7d}, {0x31c80, 0x31c88}, {0x31ce9, 0x31cec}, + {0x31cee, 0x31cf1}, {0x31d00, 0x31dbf}, {0x31e00, 0x31f15}, {0x31f18, 0x31f1d}, + {0x31f20, 0x31f45}, {0x31f48, 0x31f4d}, {0x31f50, 0x31f57}, {0x31f5f, 0x31f7d}, + {0x31f80, 0x31fb4}, {0x31fb6, 0x31fbc}, {0x31fc2, 0x31fc4}, {0x31fc6, 0x31fcc}, + {0x31fd0, 0x31fd3}, {0x31fd6, 0x31fdb}, {0x31fe0, 0x31fec}, {0x31ff2, 0x31ff4}, + {0x31ff6, 0x31ffc}, {0x32090, 0x3209c}, {0x3210a, 0x32113}, {0x32119, 0x3211d}, + {0x3212a, 0x3212d}, {0x3212f, 0x32139}, {0x3213c, 0x3213f}, {0x32145, 0x32149}, + {0x32c00, 0x32c2e}, {0x32c30, 0x32c5e}, {0x32c60, 0x32ce4}, {0x32ceb, 0x32cee}, + {0x32d00, 0x32d25}, {0x32d30, 0x32d67}, {0x32d80, 0x32d96}, {0x32da0, 0x32da6}, + {0x32da8, 0x32dae}, {0x32db0, 0x32db6}, {0x32db8, 0x32dbe}, {0x32dc0, 0x32dc6}, + {0x32dc8, 0x32dce}, {0x32dd0, 0x32dd6}, {0x32dd8, 0x32dde}, {0x33031, 0x33035}, + {0x33041, 0x33096}, {0x3309d, 0x3309f}, {0x330a1, 0x330fa}, {0x330fc, 0x330ff}, + {0x33105, 0x3312e}, {0x33131, 0x3318e}, {0x331a0, 0x331ba}, {0x331f0, 0x331ff}, + {0x33400, 0x34db5}, {0x34e00, 0x39fea}, {0x3a000, 0x3a48c}, {0x3a4d0, 0x3a4fd}, + {0x3a500, 0x3a60c}, {0x3a610, 0x3a61f}, {0x3a640, 0x3a66e}, {0x3a67f, 0x3a69d}, + {0x3a6a0, 0x3a6e5}, {0x3a717, 0x3a71f}, {0x3a722, 0x3a788}, {0x3a78b, 0x3a7ae}, + {0x3a7b0, 0x3a7b7}, {0x3a7f7, 0x3a801}, {0x3a803, 0x3a805}, {0x3a807, 0x3a80a}, + {0x3a80c, 0x3a822}, {0x3a840, 0x3a873}, {0x3a882, 0x3a8b3}, {0x3a8f2, 0x3a8f7}, + {0x3a90a, 0x3a925}, {0x3a930, 0x3a946}, {0x3a960, 0x3a97c}, {0x3a984, 0x3a9b2}, + {0x3a9e0, 0x3a9e4}, {0x3a9e6, 0x3a9ef}, {0x3a9fa, 0x3a9fe}, {0x3aa00, 0x3aa28}, + {0x3aa40, 0x3aa42}, {0x3aa44, 0x3aa4b}, {0x3aa60, 0x3aa76}, {0x3aa7e, 0x3aaaf}, + {0x3aab9, 0x3aabd}, {0x3aadb, 0x3aadd}, {0x3aae0, 0x3aaea}, {0x3aaf2, 0x3aaf4}, + {0x3ab01, 0x3ab06}, {0x3ab09, 0x3ab0e}, {0x3ab11, 0x3ab16}, {0x3ab20, 0x3ab26}, + {0x3ab28, 0x3ab2e}, {0x3ab30, 0x3ab5a}, {0x3ab5c, 0x3ab65}, {0x3ab70, 0x3abe2}, + {0x3ac00, 0x3d7a3}, {0x3d7b0, 0x3d7c6}, {0x3d7cb, 0x3d7fb}, {0x3f900, 0x3fa6d}, + {0x3fa70, 0x3fad9}, {0x3fb00, 0x3fb06}, {0x3fb13, 0x3fb17}, {0x3fb1f, 0x3fb28}, + {0x3fb2a, 0x3fb36}, {0x3fb38, 0x3fb3c}, {0x3fb46, 0x3fbb1}, {0x3fbd3, 0x3fd3d}, + {0x3fd50, 0x3fd8f}, {0x3fd92, 0x3fdc7}, {0x3fdf0, 0x3fdfb}, {0x3fe70, 0x3fe74}, + {0x3fe76, 0x3fefc}, {0x3ff21, 0x3ff3a}, {0x3ff41, 0x3ff5a}, {0x3ff66, 0x3ffbe}, + {0x3ffc2, 0x3ffc7}, {0x3ffca, 0x3ffcf}, {0x3ffd2, 0x3ffd7}, {0x3ffda, 0x3ffdc}, + {0x40041, 0x4005a}, {0x40061, 0x4007a}, {0x400c0, 0x400d6}, {0x400d8, 0x400f6}, + {0x400f8, 0x402c1}, {0x402c6, 0x402d1}, {0x402e0, 0x402e4}, {0x40370, 0x40374}, + {0x4037a, 0x4037d}, {0x40388, 0x4038a}, {0x4038e, 0x403a1}, {0x403a3, 0x403f5}, + {0x403f7, 0x40481}, {0x4048a, 0x4052f}, {0x40531, 0x40556}, {0x40561, 0x40587}, + {0x405d0, 0x405ea}, {0x405f0, 0x405f2}, {0x40620, 0x4064a}, {0x40671, 0x406d3}, + {0x406fa, 0x406fc}, {0x40712, 0x4072f}, {0x4074d, 0x407a5}, {0x407ca, 0x407ea}, + {0x40800, 0x40815}, {0x40840, 0x40858}, {0x40860, 0x4086a}, {0x408a0, 0x408b4}, + {0x408b6, 0x408bd}, {0x40904, 0x40939}, {0x40958, 0x40961}, {0x40971, 0x40980}, + {0x40985, 0x4098c}, {0x40993, 0x409a8}, {0x409aa, 0x409b0}, {0x409b6, 0x409b9}, + {0x409df, 0x409e1}, {0x40a05, 0x40a0a}, {0x40a13, 0x40a28}, {0x40a2a, 0x40a30}, + {0x40a59, 0x40a5c}, {0x40a72, 0x40a74}, {0x40a85, 0x40a8d}, {0x40a8f, 0x40a91}, + {0x40a93, 0x40aa8}, {0x40aaa, 0x40ab0}, {0x40ab5, 0x40ab9}, {0x40b05, 0x40b0c}, + {0x40b13, 0x40b28}, {0x40b2a, 0x40b30}, {0x40b35, 0x40b39}, {0x40b5f, 0x40b61}, + {0x40b85, 0x40b8a}, {0x40b8e, 0x40b90}, {0x40b92, 0x40b95}, {0x40ba8, 0x40baa}, + {0x40bae, 0x40bb9}, {0x40c05, 0x40c0c}, {0x40c0e, 0x40c10}, {0x40c12, 0x40c28}, + {0x40c2a, 0x40c39}, {0x40c58, 0x40c5a}, {0x40c85, 0x40c8c}, {0x40c8e, 0x40c90}, + {0x40c92, 0x40ca8}, {0x40caa, 0x40cb3}, {0x40cb5, 0x40cb9}, {0x40d05, 0x40d0c}, + {0x40d0e, 0x40d10}, {0x40d12, 0x40d3a}, {0x40d54, 0x40d56}, {0x40d5f, 0x40d61}, + {0x40d7a, 0x40d7f}, {0x40d85, 0x40d96}, {0x40d9a, 0x40db1}, {0x40db3, 0x40dbb}, + {0x40dc0, 0x40dc6}, {0x40e01, 0x40e30}, {0x40e40, 0x40e46}, {0x40e94, 0x40e97}, + {0x40e99, 0x40e9f}, {0x40ea1, 0x40ea3}, {0x40ead, 0x40eb0}, {0x40ec0, 0x40ec4}, + {0x40edc, 0x40edf}, {0x40f40, 0x40f47}, {0x40f49, 0x40f6c}, {0x40f88, 0x40f8c}, + {0x41000, 0x4102a}, {0x41050, 0x41055}, {0x4105a, 0x4105d}, {0x4106e, 0x41070}, + {0x41075, 0x41081}, {0x410a0, 0x410c5}, {0x410d0, 0x410fa}, {0x410fc, 0x41248}, + {0x4124a, 0x4124d}, {0x41250, 0x41256}, {0x4125a, 0x4125d}, {0x41260, 0x41288}, + {0x4128a, 0x4128d}, {0x41290, 0x412b0}, {0x412b2, 0x412b5}, {0x412b8, 0x412be}, + {0x412c2, 0x412c5}, {0x412c8, 0x412d6}, {0x412d8, 0x41310}, {0x41312, 0x41315}, + {0x41318, 0x4135a}, {0x41380, 0x4138f}, {0x413a0, 0x413f5}, {0x413f8, 0x413fd}, + {0x41401, 0x4166c}, {0x4166f, 0x4167f}, {0x41681, 0x4169a}, {0x416a0, 0x416ea}, + {0x416f1, 0x416f8}, {0x41700, 0x4170c}, {0x4170e, 0x41711}, {0x41720, 0x41731}, + {0x41740, 0x41751}, {0x41760, 0x4176c}, {0x4176e, 0x41770}, {0x41780, 0x417b3}, + {0x41820, 0x41877}, {0x41880, 0x41884}, {0x41887, 0x418a8}, {0x418b0, 0x418f5}, + {0x41900, 0x4191e}, {0x41950, 0x4196d}, {0x41970, 0x41974}, {0x41980, 0x419ab}, + {0x419b0, 0x419c9}, {0x41a00, 0x41a16}, {0x41a20, 0x41a54}, {0x41b05, 0x41b33}, + {0x41b45, 0x41b4b}, {0x41b83, 0x41ba0}, {0x41bba, 0x41be5}, {0x41c00, 0x41c23}, + {0x41c4d, 0x41c4f}, {0x41c5a, 0x41c7d}, {0x41c80, 0x41c88}, {0x41ce9, 0x41cec}, + {0x41cee, 0x41cf1}, {0x41d00, 0x41dbf}, {0x41e00, 0x41f15}, {0x41f18, 0x41f1d}, + {0x41f20, 0x41f45}, {0x41f48, 0x41f4d}, {0x41f50, 0x41f57}, {0x41f5f, 0x41f7d}, + {0x41f80, 0x41fb4}, {0x41fb6, 0x41fbc}, {0x41fc2, 0x41fc4}, {0x41fc6, 0x41fcc}, + {0x41fd0, 0x41fd3}, {0x41fd6, 0x41fdb}, {0x41fe0, 0x41fec}, {0x41ff2, 0x41ff4}, + {0x41ff6, 0x41ffc}, {0x42090, 0x4209c}, {0x4210a, 0x42113}, {0x42119, 0x4211d}, + {0x4212a, 0x4212d}, {0x4212f, 0x42139}, {0x4213c, 0x4213f}, {0x42145, 0x42149}, + {0x42c00, 0x42c2e}, {0x42c30, 0x42c5e}, {0x42c60, 0x42ce4}, {0x42ceb, 0x42cee}, + {0x42d00, 0x42d25}, {0x42d30, 0x42d67}, {0x42d80, 0x42d96}, {0x42da0, 0x42da6}, + {0x42da8, 0x42dae}, {0x42db0, 0x42db6}, {0x42db8, 0x42dbe}, {0x42dc0, 0x42dc6}, + {0x42dc8, 0x42dce}, {0x42dd0, 0x42dd6}, {0x42dd8, 0x42dde}, {0x43031, 0x43035}, + {0x43041, 0x43096}, {0x4309d, 0x4309f}, {0x430a1, 0x430fa}, {0x430fc, 0x430ff}, + {0x43105, 0x4312e}, {0x43131, 0x4318e}, {0x431a0, 0x431ba}, {0x431f0, 0x431ff}, + {0x43400, 0x44db5}, {0x44e00, 0x49fea}, {0x4a000, 0x4a48c}, {0x4a4d0, 0x4a4fd}, + {0x4a500, 0x4a60c}, {0x4a610, 0x4a61f}, {0x4a640, 0x4a66e}, {0x4a67f, 0x4a69d}, + {0x4a6a0, 0x4a6e5}, {0x4a717, 0x4a71f}, {0x4a722, 0x4a788}, {0x4a78b, 0x4a7ae}, + {0x4a7b0, 0x4a7b7}, {0x4a7f7, 0x4a801}, {0x4a803, 0x4a805}, {0x4a807, 0x4a80a}, + {0x4a80c, 0x4a822}, {0x4a840, 0x4a873}, {0x4a882, 0x4a8b3}, {0x4a8f2, 0x4a8f7}, + {0x4a90a, 0x4a925}, {0x4a930, 0x4a946}, {0x4a960, 0x4a97c}, {0x4a984, 0x4a9b2}, + {0x4a9e0, 0x4a9e4}, {0x4a9e6, 0x4a9ef}, {0x4a9fa, 0x4a9fe}, {0x4aa00, 0x4aa28}, + {0x4aa40, 0x4aa42}, {0x4aa44, 0x4aa4b}, {0x4aa60, 0x4aa76}, {0x4aa7e, 0x4aaaf}, + {0x4aab9, 0x4aabd}, {0x4aadb, 0x4aadd}, {0x4aae0, 0x4aaea}, {0x4aaf2, 0x4aaf4}, + {0x4ab01, 0x4ab06}, {0x4ab09, 0x4ab0e}, {0x4ab11, 0x4ab16}, {0x4ab20, 0x4ab26}, + {0x4ab28, 0x4ab2e}, {0x4ab30, 0x4ab5a}, {0x4ab5c, 0x4ab65}, {0x4ab70, 0x4abe2}, + {0x4ac00, 0x4d7a3}, {0x4d7b0, 0x4d7c6}, {0x4d7cb, 0x4d7fb}, {0x4f900, 0x4fa6d}, + {0x4fa70, 0x4fad9}, {0x4fb00, 0x4fb06}, {0x4fb13, 0x4fb17}, {0x4fb1f, 0x4fb28}, + {0x4fb2a, 0x4fb36}, {0x4fb38, 0x4fb3c}, {0x4fb46, 0x4fbb1}, {0x4fbd3, 0x4fd3d}, + {0x4fd50, 0x4fd8f}, {0x4fd92, 0x4fdc7}, {0x4fdf0, 0x4fdfb}, {0x4fe70, 0x4fe74}, + {0x4fe76, 0x4fefc}, {0x4ff21, 0x4ff3a}, {0x4ff41, 0x4ff5a}, {0x4ff66, 0x4ffbe}, + {0x4ffc2, 0x4ffc7}, {0x4ffca, 0x4ffcf}, {0x4ffd2, 0x4ffd7}, {0x4ffda, 0x4ffdc}, + {0x50041, 0x5005a}, {0x50061, 0x5007a}, {0x500c0, 0x500d6}, {0x500d8, 0x500f6}, + {0x500f8, 0x502c1}, {0x502c6, 0x502d1}, {0x502e0, 0x502e4}, {0x50370, 0x50374}, + {0x5037a, 0x5037d}, {0x50388, 0x5038a}, {0x5038e, 0x503a1}, {0x503a3, 0x503f5}, + {0x503f7, 0x50481}, {0x5048a, 0x5052f}, {0x50531, 0x50556}, {0x50561, 0x50587}, + {0x505d0, 0x505ea}, {0x505f0, 0x505f2}, {0x50620, 0x5064a}, {0x50671, 0x506d3}, + {0x506fa, 0x506fc}, {0x50712, 0x5072f}, {0x5074d, 0x507a5}, {0x507ca, 0x507ea}, + {0x50800, 0x50815}, {0x50840, 0x50858}, {0x50860, 0x5086a}, {0x508a0, 0x508b4}, + {0x508b6, 0x508bd}, {0x50904, 0x50939}, {0x50958, 0x50961}, {0x50971, 0x50980}, + {0x50985, 0x5098c}, {0x50993, 0x509a8}, {0x509aa, 0x509b0}, {0x509b6, 0x509b9}, + {0x509df, 0x509e1}, {0x50a05, 0x50a0a}, {0x50a13, 0x50a28}, {0x50a2a, 0x50a30}, + {0x50a59, 0x50a5c}, {0x50a72, 0x50a74}, {0x50a85, 0x50a8d}, {0x50a8f, 0x50a91}, + {0x50a93, 0x50aa8}, {0x50aaa, 0x50ab0}, {0x50ab5, 0x50ab9}, {0x50b05, 0x50b0c}, + {0x50b13, 0x50b28}, {0x50b2a, 0x50b30}, {0x50b35, 0x50b39}, {0x50b5f, 0x50b61}, + {0x50b85, 0x50b8a}, {0x50b8e, 0x50b90}, {0x50b92, 0x50b95}, {0x50ba8, 0x50baa}, + {0x50bae, 0x50bb9}, {0x50c05, 0x50c0c}, {0x50c0e, 0x50c10}, {0x50c12, 0x50c28}, + {0x50c2a, 0x50c39}, {0x50c58, 0x50c5a}, {0x50c85, 0x50c8c}, {0x50c8e, 0x50c90}, + {0x50c92, 0x50ca8}, {0x50caa, 0x50cb3}, {0x50cb5, 0x50cb9}, {0x50d05, 0x50d0c}, + {0x50d0e, 0x50d10}, {0x50d12, 0x50d3a}, {0x50d54, 0x50d56}, {0x50d5f, 0x50d61}, + {0x50d7a, 0x50d7f}, {0x50d85, 0x50d96}, {0x50d9a, 0x50db1}, {0x50db3, 0x50dbb}, + {0x50dc0, 0x50dc6}, {0x50e01, 0x50e30}, {0x50e40, 0x50e46}, {0x50e94, 0x50e97}, + {0x50e99, 0x50e9f}, {0x50ea1, 0x50ea3}, {0x50ead, 0x50eb0}, {0x50ec0, 0x50ec4}, + {0x50edc, 0x50edf}, {0x50f40, 0x50f47}, {0x50f49, 0x50f6c}, {0x50f88, 0x50f8c}, + {0x51000, 0x5102a}, {0x51050, 0x51055}, {0x5105a, 0x5105d}, {0x5106e, 0x51070}, + {0x51075, 0x51081}, {0x510a0, 0x510c5}, {0x510d0, 0x510fa}, {0x510fc, 0x51248}, + {0x5124a, 0x5124d}, {0x51250, 0x51256}, {0x5125a, 0x5125d}, {0x51260, 0x51288}, + {0x5128a, 0x5128d}, {0x51290, 0x512b0}, {0x512b2, 0x512b5}, {0x512b8, 0x512be}, + {0x512c2, 0x512c5}, {0x512c8, 0x512d6}, {0x512d8, 0x51310}, {0x51312, 0x51315}, + {0x51318, 0x5135a}, {0x51380, 0x5138f}, {0x513a0, 0x513f5}, {0x513f8, 0x513fd}, + {0x51401, 0x5166c}, {0x5166f, 0x5167f}, {0x51681, 0x5169a}, {0x516a0, 0x516ea}, + {0x516f1, 0x516f8}, {0x51700, 0x5170c}, {0x5170e, 0x51711}, {0x51720, 0x51731}, + {0x51740, 0x51751}, {0x51760, 0x5176c}, {0x5176e, 0x51770}, {0x51780, 0x517b3}, + {0x51820, 0x51877}, {0x51880, 0x51884}, {0x51887, 0x518a8}, {0x518b0, 0x518f5}, + {0x51900, 0x5191e}, {0x51950, 0x5196d}, {0x51970, 0x51974}, {0x51980, 0x519ab}, + {0x519b0, 0x519c9}, {0x51a00, 0x51a16}, {0x51a20, 0x51a54}, {0x51b05, 0x51b33}, + {0x51b45, 0x51b4b}, {0x51b83, 0x51ba0}, {0x51bba, 0x51be5}, {0x51c00, 0x51c23}, + {0x51c4d, 0x51c4f}, {0x51c5a, 0x51c7d}, {0x51c80, 0x51c88}, {0x51ce9, 0x51cec}, + {0x51cee, 0x51cf1}, {0x51d00, 0x51dbf}, {0x51e00, 0x51f15}, {0x51f18, 0x51f1d}, + {0x51f20, 0x51f45}, {0x51f48, 0x51f4d}, {0x51f50, 0x51f57}, {0x51f5f, 0x51f7d}, + {0x51f80, 0x51fb4}, {0x51fb6, 0x51fbc}, {0x51fc2, 0x51fc4}, {0x51fc6, 0x51fcc}, + {0x51fd0, 0x51fd3}, {0x51fd6, 0x51fdb}, {0x51fe0, 0x51fec}, {0x51ff2, 0x51ff4}, + {0x51ff6, 0x51ffc}, {0x52090, 0x5209c}, {0x5210a, 0x52113}, {0x52119, 0x5211d}, + {0x5212a, 0x5212d}, {0x5212f, 0x52139}, {0x5213c, 0x5213f}, {0x52145, 0x52149}, + {0x52c00, 0x52c2e}, {0x52c30, 0x52c5e}, {0x52c60, 0x52ce4}, {0x52ceb, 0x52cee}, + {0x52d00, 0x52d25}, {0x52d30, 0x52d67}, {0x52d80, 0x52d96}, {0x52da0, 0x52da6}, + {0x52da8, 0x52dae}, {0x52db0, 0x52db6}, {0x52db8, 0x52dbe}, {0x52dc0, 0x52dc6}, + {0x52dc8, 0x52dce}, {0x52dd0, 0x52dd6}, {0x52dd8, 0x52dde}, {0x53031, 0x53035}, + {0x53041, 0x53096}, {0x5309d, 0x5309f}, {0x530a1, 0x530fa}, {0x530fc, 0x530ff}, + {0x53105, 0x5312e}, {0x53131, 0x5318e}, {0x531a0, 0x531ba}, {0x531f0, 0x531ff}, + {0x53400, 0x54db5}, {0x54e00, 0x59fea}, {0x5a000, 0x5a48c}, {0x5a4d0, 0x5a4fd}, + {0x5a500, 0x5a60c}, {0x5a610, 0x5a61f}, {0x5a640, 0x5a66e}, {0x5a67f, 0x5a69d}, + {0x5a6a0, 0x5a6e5}, {0x5a717, 0x5a71f}, {0x5a722, 0x5a788}, {0x5a78b, 0x5a7ae}, + {0x5a7b0, 0x5a7b7}, {0x5a7f7, 0x5a801}, {0x5a803, 0x5a805}, {0x5a807, 0x5a80a}, + {0x5a80c, 0x5a822}, {0x5a840, 0x5a873}, {0x5a882, 0x5a8b3}, {0x5a8f2, 0x5a8f7}, + {0x5a90a, 0x5a925}, {0x5a930, 0x5a946}, {0x5a960, 0x5a97c}, {0x5a984, 0x5a9b2}, + {0x5a9e0, 0x5a9e4}, {0x5a9e6, 0x5a9ef}, {0x5a9fa, 0x5a9fe}, {0x5aa00, 0x5aa28}, + {0x5aa40, 0x5aa42}, {0x5aa44, 0x5aa4b}, {0x5aa60, 0x5aa76}, {0x5aa7e, 0x5aaaf}, + {0x5aab9, 0x5aabd}, {0x5aadb, 0x5aadd}, {0x5aae0, 0x5aaea}, {0x5aaf2, 0x5aaf4}, + {0x5ab01, 0x5ab06}, {0x5ab09, 0x5ab0e}, {0x5ab11, 0x5ab16}, {0x5ab20, 0x5ab26}, + {0x5ab28, 0x5ab2e}, {0x5ab30, 0x5ab5a}, {0x5ab5c, 0x5ab65}, {0x5ab70, 0x5abe2}, + {0x5ac00, 0x5d7a3}, {0x5d7b0, 0x5d7c6}, {0x5d7cb, 0x5d7fb}, {0x5f900, 0x5fa6d}, + {0x5fa70, 0x5fad9}, {0x5fb00, 0x5fb06}, {0x5fb13, 0x5fb17}, {0x5fb1f, 0x5fb28}, + {0x5fb2a, 0x5fb36}, {0x5fb38, 0x5fb3c}, {0x5fb46, 0x5fbb1}, {0x5fbd3, 0x5fd3d}, + {0x5fd50, 0x5fd8f}, {0x5fd92, 0x5fdc7}, {0x5fdf0, 0x5fdfb}, {0x5fe70, 0x5fe74}, + {0x5fe76, 0x5fefc}, {0x5ff21, 0x5ff3a}, {0x5ff41, 0x5ff5a}, {0x5ff66, 0x5ffbe}, + {0x5ffc2, 0x5ffc7}, {0x5ffca, 0x5ffcf}, {0x5ffd2, 0x5ffd7}, {0x5ffda, 0x5ffdc}, + {0x60041, 0x6005a}, {0x60061, 0x6007a}, {0x600c0, 0x600d6}, {0x600d8, 0x600f6}, + {0x600f8, 0x602c1}, {0x602c6, 0x602d1}, {0x602e0, 0x602e4}, {0x60370, 0x60374}, + {0x6037a, 0x6037d}, {0x60388, 0x6038a}, {0x6038e, 0x603a1}, {0x603a3, 0x603f5}, + {0x603f7, 0x60481}, {0x6048a, 0x6052f}, {0x60531, 0x60556}, {0x60561, 0x60587}, + {0x605d0, 0x605ea}, {0x605f0, 0x605f2}, {0x60620, 0x6064a}, {0x60671, 0x606d3}, + {0x606fa, 0x606fc}, {0x60712, 0x6072f}, {0x6074d, 0x607a5}, {0x607ca, 0x607ea}, + {0x60800, 0x60815}, {0x60840, 0x60858}, {0x60860, 0x6086a}, {0x608a0, 0x608b4}, + {0x608b6, 0x608bd}, {0x60904, 0x60939}, {0x60958, 0x60961}, {0x60971, 0x60980}, + {0x60985, 0x6098c}, {0x60993, 0x609a8}, {0x609aa, 0x609b0}, {0x609b6, 0x609b9}, + {0x609df, 0x609e1}, {0x60a05, 0x60a0a}, {0x60a13, 0x60a28}, {0x60a2a, 0x60a30}, + {0x60a59, 0x60a5c}, {0x60a72, 0x60a74}, {0x60a85, 0x60a8d}, {0x60a8f, 0x60a91}, + {0x60a93, 0x60aa8}, {0x60aaa, 0x60ab0}, {0x60ab5, 0x60ab9}, {0x60b05, 0x60b0c}, + {0x60b13, 0x60b28}, {0x60b2a, 0x60b30}, {0x60b35, 0x60b39}, {0x60b5f, 0x60b61}, + {0x60b85, 0x60b8a}, {0x60b8e, 0x60b90}, {0x60b92, 0x60b95}, {0x60ba8, 0x60baa}, + {0x60bae, 0x60bb9}, {0x60c05, 0x60c0c}, {0x60c0e, 0x60c10}, {0x60c12, 0x60c28}, + {0x60c2a, 0x60c39}, {0x60c58, 0x60c5a}, {0x60c85, 0x60c8c}, {0x60c8e, 0x60c90}, + {0x60c92, 0x60ca8}, {0x60caa, 0x60cb3}, {0x60cb5, 0x60cb9}, {0x60d05, 0x60d0c}, + {0x60d0e, 0x60d10}, {0x60d12, 0x60d3a}, {0x60d54, 0x60d56}, {0x60d5f, 0x60d61}, + {0x60d7a, 0x60d7f}, {0x60d85, 0x60d96}, {0x60d9a, 0x60db1}, {0x60db3, 0x60dbb}, + {0x60dc0, 0x60dc6}, {0x60e01, 0x60e30}, {0x60e40, 0x60e46}, {0x60e94, 0x60e97}, + {0x60e99, 0x60e9f}, {0x60ea1, 0x60ea3}, {0x60ead, 0x60eb0}, {0x60ec0, 0x60ec4}, + {0x60edc, 0x60edf}, {0x60f40, 0x60f47}, {0x60f49, 0x60f6c}, {0x60f88, 0x60f8c}, + {0x61000, 0x6102a}, {0x61050, 0x61055}, {0x6105a, 0x6105d}, {0x6106e, 0x61070}, + {0x61075, 0x61081}, {0x610a0, 0x610c5}, {0x610d0, 0x610fa}, {0x610fc, 0x61248}, + {0x6124a, 0x6124d}, {0x61250, 0x61256}, {0x6125a, 0x6125d}, {0x61260, 0x61288}, + {0x6128a, 0x6128d}, {0x61290, 0x612b0}, {0x612b2, 0x612b5}, {0x612b8, 0x612be}, + {0x612c2, 0x612c5}, {0x612c8, 0x612d6}, {0x612d8, 0x61310}, {0x61312, 0x61315}, + {0x61318, 0x6135a}, {0x61380, 0x6138f}, {0x613a0, 0x613f5}, {0x613f8, 0x613fd}, + {0x61401, 0x6166c}, {0x6166f, 0x6167f}, {0x61681, 0x6169a}, {0x616a0, 0x616ea}, + {0x616f1, 0x616f8}, {0x61700, 0x6170c}, {0x6170e, 0x61711}, {0x61720, 0x61731}, + {0x61740, 0x61751}, {0x61760, 0x6176c}, {0x6176e, 0x61770}, {0x61780, 0x617b3}, + {0x61820, 0x61877}, {0x61880, 0x61884}, {0x61887, 0x618a8}, {0x618b0, 0x618f5}, + {0x61900, 0x6191e}, {0x61950, 0x6196d}, {0x61970, 0x61974}, {0x61980, 0x619ab}, + {0x619b0, 0x619c9}, {0x61a00, 0x61a16}, {0x61a20, 0x61a54}, {0x61b05, 0x61b33}, + {0x61b45, 0x61b4b}, {0x61b83, 0x61ba0}, {0x61bba, 0x61be5}, {0x61c00, 0x61c23}, + {0x61c4d, 0x61c4f}, {0x61c5a, 0x61c7d}, {0x61c80, 0x61c88}, {0x61ce9, 0x61cec}, + {0x61cee, 0x61cf1}, {0x61d00, 0x61dbf}, {0x61e00, 0x61f15}, {0x61f18, 0x61f1d}, + {0x61f20, 0x61f45}, {0x61f48, 0x61f4d}, {0x61f50, 0x61f57}, {0x61f5f, 0x61f7d}, + {0x61f80, 0x61fb4}, {0x61fb6, 0x61fbc}, {0x61fc2, 0x61fc4}, {0x61fc6, 0x61fcc}, + {0x61fd0, 0x61fd3}, {0x61fd6, 0x61fdb}, {0x61fe0, 0x61fec}, {0x61ff2, 0x61ff4}, + {0x61ff6, 0x61ffc}, {0x62090, 0x6209c}, {0x6210a, 0x62113}, {0x62119, 0x6211d}, + {0x6212a, 0x6212d}, {0x6212f, 0x62139}, {0x6213c, 0x6213f}, {0x62145, 0x62149}, + {0x62c00, 0x62c2e}, {0x62c30, 0x62c5e}, {0x62c60, 0x62ce4}, {0x62ceb, 0x62cee}, + {0x62d00, 0x62d25}, {0x62d30, 0x62d67}, {0x62d80, 0x62d96}, {0x62da0, 0x62da6}, + {0x62da8, 0x62dae}, {0x62db0, 0x62db6}, {0x62db8, 0x62dbe}, {0x62dc0, 0x62dc6}, + {0x62dc8, 0x62dce}, {0x62dd0, 0x62dd6}, {0x62dd8, 0x62dde}, {0x63031, 0x63035}, + {0x63041, 0x63096}, {0x6309d, 0x6309f}, {0x630a1, 0x630fa}, {0x630fc, 0x630ff}, + {0x63105, 0x6312e}, {0x63131, 0x6318e}, {0x631a0, 0x631ba}, {0x631f0, 0x631ff}, + {0x63400, 0x64db5}, {0x64e00, 0x69fea}, {0x6a000, 0x6a48c}, {0x6a4d0, 0x6a4fd}, + {0x6a500, 0x6a60c}, {0x6a610, 0x6a61f}, {0x6a640, 0x6a66e}, {0x6a67f, 0x6a69d}, + {0x6a6a0, 0x6a6e5}, {0x6a717, 0x6a71f}, {0x6a722, 0x6a788}, {0x6a78b, 0x6a7ae}, + {0x6a7b0, 0x6a7b7}, {0x6a7f7, 0x6a801}, {0x6a803, 0x6a805}, {0x6a807, 0x6a80a}, + {0x6a80c, 0x6a822}, {0x6a840, 0x6a873}, {0x6a882, 0x6a8b3}, {0x6a8f2, 0x6a8f7}, + {0x6a90a, 0x6a925}, {0x6a930, 0x6a946}, {0x6a960, 0x6a97c}, {0x6a984, 0x6a9b2}, + {0x6a9e0, 0x6a9e4}, {0x6a9e6, 0x6a9ef}, {0x6a9fa, 0x6a9fe}, {0x6aa00, 0x6aa28}, + {0x6aa40, 0x6aa42}, {0x6aa44, 0x6aa4b}, {0x6aa60, 0x6aa76}, {0x6aa7e, 0x6aaaf}, + {0x6aab9, 0x6aabd}, {0x6aadb, 0x6aadd}, {0x6aae0, 0x6aaea}, {0x6aaf2, 0x6aaf4}, + {0x6ab01, 0x6ab06}, {0x6ab09, 0x6ab0e}, {0x6ab11, 0x6ab16}, {0x6ab20, 0x6ab26}, + {0x6ab28, 0x6ab2e}, {0x6ab30, 0x6ab5a}, {0x6ab5c, 0x6ab65}, {0x6ab70, 0x6abe2}, + {0x6ac00, 0x6d7a3}, {0x6d7b0, 0x6d7c6}, {0x6d7cb, 0x6d7fb}, {0x6f900, 0x6fa6d}, + {0x6fa70, 0x6fad9}, {0x6fb00, 0x6fb06}, {0x6fb13, 0x6fb17}, {0x6fb1f, 0x6fb28}, + {0x6fb2a, 0x6fb36}, {0x6fb38, 0x6fb3c}, {0x6fb46, 0x6fbb1}, {0x6fbd3, 0x6fd3d}, + {0x6fd50, 0x6fd8f}, {0x6fd92, 0x6fdc7}, {0x6fdf0, 0x6fdfb}, {0x6fe70, 0x6fe74}, + {0x6fe76, 0x6fefc}, {0x6ff21, 0x6ff3a}, {0x6ff41, 0x6ff5a}, {0x6ff66, 0x6ffbe}, + {0x6ffc2, 0x6ffc7}, {0x6ffca, 0x6ffcf}, {0x6ffd2, 0x6ffd7}, {0x6ffda, 0x6ffdc}, + {0x70041, 0x7005a}, {0x70061, 0x7007a}, {0x700c0, 0x700d6}, {0x700d8, 0x700f6}, + {0x700f8, 0x702c1}, {0x702c6, 0x702d1}, {0x702e0, 0x702e4}, {0x70370, 0x70374}, + {0x7037a, 0x7037d}, {0x70388, 0x7038a}, {0x7038e, 0x703a1}, {0x703a3, 0x703f5}, + {0x703f7, 0x70481}, {0x7048a, 0x7052f}, {0x70531, 0x70556}, {0x70561, 0x70587}, + {0x705d0, 0x705ea}, {0x705f0, 0x705f2}, {0x70620, 0x7064a}, {0x70671, 0x706d3}, + {0x706fa, 0x706fc}, {0x70712, 0x7072f}, {0x7074d, 0x707a5}, {0x707ca, 0x707ea}, + {0x70800, 0x70815}, {0x70840, 0x70858}, {0x70860, 0x7086a}, {0x708a0, 0x708b4}, + {0x708b6, 0x708bd}, {0x70904, 0x70939}, {0x70958, 0x70961}, {0x70971, 0x70980}, + {0x70985, 0x7098c}, {0x70993, 0x709a8}, {0x709aa, 0x709b0}, {0x709b6, 0x709b9}, + {0x709df, 0x709e1}, {0x70a05, 0x70a0a}, {0x70a13, 0x70a28}, {0x70a2a, 0x70a30}, + {0x70a59, 0x70a5c}, {0x70a72, 0x70a74}, {0x70a85, 0x70a8d}, {0x70a8f, 0x70a91}, + {0x70a93, 0x70aa8}, {0x70aaa, 0x70ab0}, {0x70ab5, 0x70ab9}, {0x70b05, 0x70b0c}, + {0x70b13, 0x70b28}, {0x70b2a, 0x70b30}, {0x70b35, 0x70b39}, {0x70b5f, 0x70b61}, + {0x70b85, 0x70b8a}, {0x70b8e, 0x70b90}, {0x70b92, 0x70b95}, {0x70ba8, 0x70baa}, + {0x70bae, 0x70bb9}, {0x70c05, 0x70c0c}, {0x70c0e, 0x70c10}, {0x70c12, 0x70c28}, + {0x70c2a, 0x70c39}, {0x70c58, 0x70c5a}, {0x70c85, 0x70c8c}, {0x70c8e, 0x70c90}, + {0x70c92, 0x70ca8}, {0x70caa, 0x70cb3}, {0x70cb5, 0x70cb9}, {0x70d05, 0x70d0c}, + {0x70d0e, 0x70d10}, {0x70d12, 0x70d3a}, {0x70d54, 0x70d56}, {0x70d5f, 0x70d61}, + {0x70d7a, 0x70d7f}, {0x70d85, 0x70d96}, {0x70d9a, 0x70db1}, {0x70db3, 0x70dbb}, + {0x70dc0, 0x70dc6}, {0x70e01, 0x70e30}, {0x70e40, 0x70e46}, {0x70e94, 0x70e97}, + {0x70e99, 0x70e9f}, {0x70ea1, 0x70ea3}, {0x70ead, 0x70eb0}, {0x70ec0, 0x70ec4}, + {0x70edc, 0x70edf}, {0x70f40, 0x70f47}, {0x70f49, 0x70f6c}, {0x70f88, 0x70f8c}, + {0x71000, 0x7102a}, {0x71050, 0x71055}, {0x7105a, 0x7105d}, {0x7106e, 0x71070}, + {0x71075, 0x71081}, {0x710a0, 0x710c5}, {0x710d0, 0x710fa}, {0x710fc, 0x71248}, + {0x7124a, 0x7124d}, {0x71250, 0x71256}, {0x7125a, 0x7125d}, {0x71260, 0x71288}, + {0x7128a, 0x7128d}, {0x71290, 0x712b0}, {0x712b2, 0x712b5}, {0x712b8, 0x712be}, + {0x712c2, 0x712c5}, {0x712c8, 0x712d6}, {0x712d8, 0x71310}, {0x71312, 0x71315}, + {0x71318, 0x7135a}, {0x71380, 0x7138f}, {0x713a0, 0x713f5}, {0x713f8, 0x713fd}, + {0x71401, 0x7166c}, {0x7166f, 0x7167f}, {0x71681, 0x7169a}, {0x716a0, 0x716ea}, + {0x716f1, 0x716f8}, {0x71700, 0x7170c}, {0x7170e, 0x71711}, {0x71720, 0x71731}, + {0x71740, 0x71751}, {0x71760, 0x7176c}, {0x7176e, 0x71770}, {0x71780, 0x717b3}, + {0x71820, 0x71877}, {0x71880, 0x71884}, {0x71887, 0x718a8}, {0x718b0, 0x718f5}, + {0x71900, 0x7191e}, {0x71950, 0x7196d}, {0x71970, 0x71974}, {0x71980, 0x719ab}, + {0x719b0, 0x719c9}, {0x71a00, 0x71a16}, {0x71a20, 0x71a54}, {0x71b05, 0x71b33}, + {0x71b45, 0x71b4b}, {0x71b83, 0x71ba0}, {0x71bba, 0x71be5}, {0x71c00, 0x71c23}, + {0x71c4d, 0x71c4f}, {0x71c5a, 0x71c7d}, {0x71c80, 0x71c88}, {0x71ce9, 0x71cec}, + {0x71cee, 0x71cf1}, {0x71d00, 0x71dbf}, {0x71e00, 0x71f15}, {0x71f18, 0x71f1d}, + {0x71f20, 0x71f45}, {0x71f48, 0x71f4d}, {0x71f50, 0x71f57}, {0x71f5f, 0x71f7d}, + {0x71f80, 0x71fb4}, {0x71fb6, 0x71fbc}, {0x71fc2, 0x71fc4}, {0x71fc6, 0x71fcc}, + {0x71fd0, 0x71fd3}, {0x71fd6, 0x71fdb}, {0x71fe0, 0x71fec}, {0x71ff2, 0x71ff4}, + {0x71ff6, 0x71ffc}, {0x72090, 0x7209c}, {0x7210a, 0x72113}, {0x72119, 0x7211d}, + {0x7212a, 0x7212d}, {0x7212f, 0x72139}, {0x7213c, 0x7213f}, {0x72145, 0x72149}, + {0x72c00, 0x72c2e}, {0x72c30, 0x72c5e}, {0x72c60, 0x72ce4}, {0x72ceb, 0x72cee}, + {0x72d00, 0x72d25}, {0x72d30, 0x72d67}, {0x72d80, 0x72d96}, {0x72da0, 0x72da6}, + {0x72da8, 0x72dae}, {0x72db0, 0x72db6}, {0x72db8, 0x72dbe}, {0x72dc0, 0x72dc6}, + {0x72dc8, 0x72dce}, {0x72dd0, 0x72dd6}, {0x72dd8, 0x72dde}, {0x73031, 0x73035}, + {0x73041, 0x73096}, {0x7309d, 0x7309f}, {0x730a1, 0x730fa}, {0x730fc, 0x730ff}, + {0x73105, 0x7312e}, {0x73131, 0x7318e}, {0x731a0, 0x731ba}, {0x731f0, 0x731ff}, + {0x73400, 0x74db5}, {0x74e00, 0x79fea}, {0x7a000, 0x7a48c}, {0x7a4d0, 0x7a4fd}, + {0x7a500, 0x7a60c}, {0x7a610, 0x7a61f}, {0x7a640, 0x7a66e}, {0x7a67f, 0x7a69d}, + {0x7a6a0, 0x7a6e5}, {0x7a717, 0x7a71f}, {0x7a722, 0x7a788}, {0x7a78b, 0x7a7ae}, + {0x7a7b0, 0x7a7b7}, {0x7a7f7, 0x7a801}, {0x7a803, 0x7a805}, {0x7a807, 0x7a80a}, + {0x7a80c, 0x7a822}, {0x7a840, 0x7a873}, {0x7a882, 0x7a8b3}, {0x7a8f2, 0x7a8f7}, + {0x7a90a, 0x7a925}, {0x7a930, 0x7a946}, {0x7a960, 0x7a97c}, {0x7a984, 0x7a9b2}, + {0x7a9e0, 0x7a9e4}, {0x7a9e6, 0x7a9ef}, {0x7a9fa, 0x7a9fe}, {0x7aa00, 0x7aa28}, + {0x7aa40, 0x7aa42}, {0x7aa44, 0x7aa4b}, {0x7aa60, 0x7aa76}, {0x7aa7e, 0x7aaaf}, + {0x7aab9, 0x7aabd}, {0x7aadb, 0x7aadd}, {0x7aae0, 0x7aaea}, {0x7aaf2, 0x7aaf4}, + {0x7ab01, 0x7ab06}, {0x7ab09, 0x7ab0e}, {0x7ab11, 0x7ab16}, {0x7ab20, 0x7ab26}, + {0x7ab28, 0x7ab2e}, {0x7ab30, 0x7ab5a}, {0x7ab5c, 0x7ab65}, {0x7ab70, 0x7abe2}, + {0x7ac00, 0x7d7a3}, {0x7d7b0, 0x7d7c6}, {0x7d7cb, 0x7d7fb}, {0x7f900, 0x7fa6d}, + {0x7fa70, 0x7fad9}, {0x7fb00, 0x7fb06}, {0x7fb13, 0x7fb17}, {0x7fb1f, 0x7fb28}, + {0x7fb2a, 0x7fb36}, {0x7fb38, 0x7fb3c}, {0x7fb46, 0x7fbb1}, {0x7fbd3, 0x7fd3d}, + {0x7fd50, 0x7fd8f}, {0x7fd92, 0x7fdc7}, {0x7fdf0, 0x7fdfb}, {0x7fe70, 0x7fe74}, + {0x7fe76, 0x7fefc}, {0x7ff21, 0x7ff3a}, {0x7ff41, 0x7ff5a}, {0x7ff66, 0x7ffbe}, + {0x7ffc2, 0x7ffc7}, {0x7ffca, 0x7ffcf}, {0x7ffd2, 0x7ffd7}, {0x7ffda, 0x7ffdc}, + {0x80041, 0x8005a}, {0x80061, 0x8007a}, {0x800c0, 0x800d6}, {0x800d8, 0x800f6}, + {0x800f8, 0x802c1}, {0x802c6, 0x802d1}, {0x802e0, 0x802e4}, {0x80370, 0x80374}, + {0x8037a, 0x8037d}, {0x80388, 0x8038a}, {0x8038e, 0x803a1}, {0x803a3, 0x803f5}, + {0x803f7, 0x80481}, {0x8048a, 0x8052f}, {0x80531, 0x80556}, {0x80561, 0x80587}, + {0x805d0, 0x805ea}, {0x805f0, 0x805f2}, {0x80620, 0x8064a}, {0x80671, 0x806d3}, + {0x806fa, 0x806fc}, {0x80712, 0x8072f}, {0x8074d, 0x807a5}, {0x807ca, 0x807ea}, + {0x80800, 0x80815}, {0x80840, 0x80858}, {0x80860, 0x8086a}, {0x808a0, 0x808b4}, + {0x808b6, 0x808bd}, {0x80904, 0x80939}, {0x80958, 0x80961}, {0x80971, 0x80980}, + {0x80985, 0x8098c}, {0x80993, 0x809a8}, {0x809aa, 0x809b0}, {0x809b6, 0x809b9}, + {0x809df, 0x809e1}, {0x80a05, 0x80a0a}, {0x80a13, 0x80a28}, {0x80a2a, 0x80a30}, + {0x80a59, 0x80a5c}, {0x80a72, 0x80a74}, {0x80a85, 0x80a8d}, {0x80a8f, 0x80a91}, + {0x80a93, 0x80aa8}, {0x80aaa, 0x80ab0}, {0x80ab5, 0x80ab9}, {0x80b05, 0x80b0c}, + {0x80b13, 0x80b28}, {0x80b2a, 0x80b30}, {0x80b35, 0x80b39}, {0x80b5f, 0x80b61}, + {0x80b85, 0x80b8a}, {0x80b8e, 0x80b90}, {0x80b92, 0x80b95}, {0x80ba8, 0x80baa}, + {0x80bae, 0x80bb9}, {0x80c05, 0x80c0c}, {0x80c0e, 0x80c10}, {0x80c12, 0x80c28}, + {0x80c2a, 0x80c39}, {0x80c58, 0x80c5a}, {0x80c85, 0x80c8c}, {0x80c8e, 0x80c90}, + {0x80c92, 0x80ca8}, {0x80caa, 0x80cb3}, {0x80cb5, 0x80cb9}, {0x80d05, 0x80d0c}, + {0x80d0e, 0x80d10}, {0x80d12, 0x80d3a}, {0x80d54, 0x80d56}, {0x80d5f, 0x80d61}, + {0x80d7a, 0x80d7f}, {0x80d85, 0x80d96}, {0x80d9a, 0x80db1}, {0x80db3, 0x80dbb}, + {0x80dc0, 0x80dc6}, {0x80e01, 0x80e30}, {0x80e40, 0x80e46}, {0x80e94, 0x80e97}, + {0x80e99, 0x80e9f}, {0x80ea1, 0x80ea3}, {0x80ead, 0x80eb0}, {0x80ec0, 0x80ec4}, + {0x80edc, 0x80edf}, {0x80f40, 0x80f47}, {0x80f49, 0x80f6c}, {0x80f88, 0x80f8c}, + {0x81000, 0x8102a}, {0x81050, 0x81055}, {0x8105a, 0x8105d}, {0x8106e, 0x81070}, + {0x81075, 0x81081}, {0x810a0, 0x810c5}, {0x810d0, 0x810fa}, {0x810fc, 0x81248}, + {0x8124a, 0x8124d}, {0x81250, 0x81256}, {0x8125a, 0x8125d}, {0x81260, 0x81288}, + {0x8128a, 0x8128d}, {0x81290, 0x812b0}, {0x812b2, 0x812b5}, {0x812b8, 0x812be}, + {0x812c2, 0x812c5}, {0x812c8, 0x812d6}, {0x812d8, 0x81310}, {0x81312, 0x81315}, + {0x81318, 0x8135a}, {0x81380, 0x8138f}, {0x813a0, 0x813f5}, {0x813f8, 0x813fd}, + {0x81401, 0x8166c}, {0x8166f, 0x8167f}, {0x81681, 0x8169a}, {0x816a0, 0x816ea}, + {0x816f1, 0x816f8}, {0x81700, 0x8170c}, {0x8170e, 0x81711}, {0x81720, 0x81731}, + {0x81740, 0x81751}, {0x81760, 0x8176c}, {0x8176e, 0x81770}, {0x81780, 0x817b3}, + {0x81820, 0x81877}, {0x81880, 0x81884}, {0x81887, 0x818a8}, {0x818b0, 0x818f5}, + {0x81900, 0x8191e}, {0x81950, 0x8196d}, {0x81970, 0x81974}, {0x81980, 0x819ab}, + {0x819b0, 0x819c9}, {0x81a00, 0x81a16}, {0x81a20, 0x81a54}, {0x81b05, 0x81b33}, + {0x81b45, 0x81b4b}, {0x81b83, 0x81ba0}, {0x81bba, 0x81be5}, {0x81c00, 0x81c23}, + {0x81c4d, 0x81c4f}, {0x81c5a, 0x81c7d}, {0x81c80, 0x81c88}, {0x81ce9, 0x81cec}, + {0x81cee, 0x81cf1}, {0x81d00, 0x81dbf}, {0x81e00, 0x81f15}, {0x81f18, 0x81f1d}, + {0x81f20, 0x81f45}, {0x81f48, 0x81f4d}, {0x81f50, 0x81f57}, {0x81f5f, 0x81f7d}, + {0x81f80, 0x81fb4}, {0x81fb6, 0x81fbc}, {0x81fc2, 0x81fc4}, {0x81fc6, 0x81fcc}, + {0x81fd0, 0x81fd3}, {0x81fd6, 0x81fdb}, {0x81fe0, 0x81fec}, {0x81ff2, 0x81ff4}, + {0x81ff6, 0x81ffc}, {0x82090, 0x8209c}, {0x8210a, 0x82113}, {0x82119, 0x8211d}, + {0x8212a, 0x8212d}, {0x8212f, 0x82139}, {0x8213c, 0x8213f}, {0x82145, 0x82149}, + {0x82c00, 0x82c2e}, {0x82c30, 0x82c5e}, {0x82c60, 0x82ce4}, {0x82ceb, 0x82cee}, + {0x82d00, 0x82d25}, {0x82d30, 0x82d67}, {0x82d80, 0x82d96}, {0x82da0, 0x82da6}, + {0x82da8, 0x82dae}, {0x82db0, 0x82db6}, {0x82db8, 0x82dbe}, {0x82dc0, 0x82dc6}, + {0x82dc8, 0x82dce}, {0x82dd0, 0x82dd6}, {0x82dd8, 0x82dde}, {0x83031, 0x83035}, + {0x83041, 0x83096}, {0x8309d, 0x8309f}, {0x830a1, 0x830fa}, {0x830fc, 0x830ff}, + {0x83105, 0x8312e}, {0x83131, 0x8318e}, {0x831a0, 0x831ba}, {0x831f0, 0x831ff}, + {0x83400, 0x84db5}, {0x84e00, 0x89fea}, {0x8a000, 0x8a48c}, {0x8a4d0, 0x8a4fd}, + {0x8a500, 0x8a60c}, {0x8a610, 0x8a61f}, {0x8a640, 0x8a66e}, {0x8a67f, 0x8a69d}, + {0x8a6a0, 0x8a6e5}, {0x8a717, 0x8a71f}, {0x8a722, 0x8a788}, {0x8a78b, 0x8a7ae}, + {0x8a7b0, 0x8a7b7}, {0x8a7f7, 0x8a801}, {0x8a803, 0x8a805}, {0x8a807, 0x8a80a}, + {0x8a80c, 0x8a822}, {0x8a840, 0x8a873}, {0x8a882, 0x8a8b3}, {0x8a8f2, 0x8a8f7}, + {0x8a90a, 0x8a925}, {0x8a930, 0x8a946}, {0x8a960, 0x8a97c}, {0x8a984, 0x8a9b2}, + {0x8a9e0, 0x8a9e4}, {0x8a9e6, 0x8a9ef}, {0x8a9fa, 0x8a9fe}, {0x8aa00, 0x8aa28}, + {0x8aa40, 0x8aa42}, {0x8aa44, 0x8aa4b}, {0x8aa60, 0x8aa76}, {0x8aa7e, 0x8aaaf}, + {0x8aab9, 0x8aabd}, {0x8aadb, 0x8aadd}, {0x8aae0, 0x8aaea}, {0x8aaf2, 0x8aaf4}, + {0x8ab01, 0x8ab06}, {0x8ab09, 0x8ab0e}, {0x8ab11, 0x8ab16}, {0x8ab20, 0x8ab26}, + {0x8ab28, 0x8ab2e}, {0x8ab30, 0x8ab5a}, {0x8ab5c, 0x8ab65}, {0x8ab70, 0x8abe2}, + {0x8ac00, 0x8d7a3}, {0x8d7b0, 0x8d7c6}, {0x8d7cb, 0x8d7fb}, {0x8f900, 0x8fa6d}, + {0x8fa70, 0x8fad9}, {0x8fb00, 0x8fb06}, {0x8fb13, 0x8fb17}, {0x8fb1f, 0x8fb28}, + {0x8fb2a, 0x8fb36}, {0x8fb38, 0x8fb3c}, {0x8fb46, 0x8fbb1}, {0x8fbd3, 0x8fd3d}, + {0x8fd50, 0x8fd8f}, {0x8fd92, 0x8fdc7}, {0x8fdf0, 0x8fdfb}, {0x8fe70, 0x8fe74}, + {0x8fe76, 0x8fefc}, {0x8ff21, 0x8ff3a}, {0x8ff41, 0x8ff5a}, {0x8ff66, 0x8ffbe}, + {0x8ffc2, 0x8ffc7}, {0x8ffca, 0x8ffcf}, {0x8ffd2, 0x8ffd7}, {0x8ffda, 0x8ffdc}, + {0x90041, 0x9005a}, {0x90061, 0x9007a}, {0x900c0, 0x900d6}, {0x900d8, 0x900f6}, + {0x900f8, 0x902c1}, {0x902c6, 0x902d1}, {0x902e0, 0x902e4}, {0x90370, 0x90374}, + {0x9037a, 0x9037d}, {0x90388, 0x9038a}, {0x9038e, 0x903a1}, {0x903a3, 0x903f5}, + {0x903f7, 0x90481}, {0x9048a, 0x9052f}, {0x90531, 0x90556}, {0x90561, 0x90587}, + {0x905d0, 0x905ea}, {0x905f0, 0x905f2}, {0x90620, 0x9064a}, {0x90671, 0x906d3}, + {0x906fa, 0x906fc}, {0x90712, 0x9072f}, {0x9074d, 0x907a5}, {0x907ca, 0x907ea}, + {0x90800, 0x90815}, {0x90840, 0x90858}, {0x90860, 0x9086a}, {0x908a0, 0x908b4}, + {0x908b6, 0x908bd}, {0x90904, 0x90939}, {0x90958, 0x90961}, {0x90971, 0x90980}, + {0x90985, 0x9098c}, {0x90993, 0x909a8}, {0x909aa, 0x909b0}, {0x909b6, 0x909b9}, + {0x909df, 0x909e1}, {0x90a05, 0x90a0a}, {0x90a13, 0x90a28}, {0x90a2a, 0x90a30}, + {0x90a59, 0x90a5c}, {0x90a72, 0x90a74}, {0x90a85, 0x90a8d}, {0x90a8f, 0x90a91}, + {0x90a93, 0x90aa8}, {0x90aaa, 0x90ab0}, {0x90ab5, 0x90ab9}, {0x90b05, 0x90b0c}, + {0x90b13, 0x90b28}, {0x90b2a, 0x90b30}, {0x90b35, 0x90b39}, {0x90b5f, 0x90b61}, + {0x90b85, 0x90b8a}, {0x90b8e, 0x90b90}, {0x90b92, 0x90b95}, {0x90ba8, 0x90baa}, + {0x90bae, 0x90bb9}, {0x90c05, 0x90c0c}, {0x90c0e, 0x90c10}, {0x90c12, 0x90c28}, + {0x90c2a, 0x90c39}, {0x90c58, 0x90c5a}, {0x90c85, 0x90c8c}, {0x90c8e, 0x90c90}, + {0x90c92, 0x90ca8}, {0x90caa, 0x90cb3}, {0x90cb5, 0x90cb9}, {0x90d05, 0x90d0c}, + {0x90d0e, 0x90d10}, {0x90d12, 0x90d3a}, {0x90d54, 0x90d56}, {0x90d5f, 0x90d61}, + {0x90d7a, 0x90d7f}, {0x90d85, 0x90d96}, {0x90d9a, 0x90db1}, {0x90db3, 0x90dbb}, + {0x90dc0, 0x90dc6}, {0x90e01, 0x90e30}, {0x90e40, 0x90e46}, {0x90e94, 0x90e97}, + {0x90e99, 0x90e9f}, {0x90ea1, 0x90ea3}, {0x90ead, 0x90eb0}, {0x90ec0, 0x90ec4}, + {0x90edc, 0x90edf}, {0x90f40, 0x90f47}, {0x90f49, 0x90f6c}, {0x90f88, 0x90f8c}, + {0x91000, 0x9102a}, {0x91050, 0x91055}, {0x9105a, 0x9105d}, {0x9106e, 0x91070}, + {0x91075, 0x91081}, {0x910a0, 0x910c5}, {0x910d0, 0x910fa}, {0x910fc, 0x91248}, + {0x9124a, 0x9124d}, {0x91250, 0x91256}, {0x9125a, 0x9125d}, {0x91260, 0x91288}, + {0x9128a, 0x9128d}, {0x91290, 0x912b0}, {0x912b2, 0x912b5}, {0x912b8, 0x912be}, + {0x912c2, 0x912c5}, {0x912c8, 0x912d6}, {0x912d8, 0x91310}, {0x91312, 0x91315}, + {0x91318, 0x9135a}, {0x91380, 0x9138f}, {0x913a0, 0x913f5}, {0x913f8, 0x913fd}, + {0x91401, 0x9166c}, {0x9166f, 0x9167f}, {0x91681, 0x9169a}, {0x916a0, 0x916ea}, + {0x916f1, 0x916f8}, {0x91700, 0x9170c}, {0x9170e, 0x91711}, {0x91720, 0x91731}, + {0x91740, 0x91751}, {0x91760, 0x9176c}, {0x9176e, 0x91770}, {0x91780, 0x917b3}, + {0x91820, 0x91877}, {0x91880, 0x91884}, {0x91887, 0x918a8}, {0x918b0, 0x918f5}, + {0x91900, 0x9191e}, {0x91950, 0x9196d}, {0x91970, 0x91974}, {0x91980, 0x919ab}, + {0x919b0, 0x919c9}, {0x91a00, 0x91a16}, {0x91a20, 0x91a54}, {0x91b05, 0x91b33}, + {0x91b45, 0x91b4b}, {0x91b83, 0x91ba0}, {0x91bba, 0x91be5}, {0x91c00, 0x91c23}, + {0x91c4d, 0x91c4f}, {0x91c5a, 0x91c7d}, {0x91c80, 0x91c88}, {0x91ce9, 0x91cec}, + {0x91cee, 0x91cf1}, {0x91d00, 0x91dbf}, {0x91e00, 0x91f15}, {0x91f18, 0x91f1d}, + {0x91f20, 0x91f45}, {0x91f48, 0x91f4d}, {0x91f50, 0x91f57}, {0x91f5f, 0x91f7d}, + {0x91f80, 0x91fb4}, {0x91fb6, 0x91fbc}, {0x91fc2, 0x91fc4}, {0x91fc6, 0x91fcc}, + {0x91fd0, 0x91fd3}, {0x91fd6, 0x91fdb}, {0x91fe0, 0x91fec}, {0x91ff2, 0x91ff4}, + {0x91ff6, 0x91ffc}, {0x92090, 0x9209c}, {0x9210a, 0x92113}, {0x92119, 0x9211d}, + {0x9212a, 0x9212d}, {0x9212f, 0x92139}, {0x9213c, 0x9213f}, {0x92145, 0x92149}, + {0x92c00, 0x92c2e}, {0x92c30, 0x92c5e}, {0x92c60, 0x92ce4}, {0x92ceb, 0x92cee}, + {0x92d00, 0x92d25}, {0x92d30, 0x92d67}, {0x92d80, 0x92d96}, {0x92da0, 0x92da6}, + {0x92da8, 0x92dae}, {0x92db0, 0x92db6}, {0x92db8, 0x92dbe}, {0x92dc0, 0x92dc6}, + {0x92dc8, 0x92dce}, {0x92dd0, 0x92dd6}, {0x92dd8, 0x92dde}, {0x93031, 0x93035}, + {0x93041, 0x93096}, {0x9309d, 0x9309f}, {0x930a1, 0x930fa}, {0x930fc, 0x930ff}, + {0x93105, 0x9312e}, {0x93131, 0x9318e}, {0x931a0, 0x931ba}, {0x931f0, 0x931ff}, + {0x93400, 0x94db5}, {0x94e00, 0x99fea}, {0x9a000, 0x9a48c}, {0x9a4d0, 0x9a4fd}, + {0x9a500, 0x9a60c}, {0x9a610, 0x9a61f}, {0x9a640, 0x9a66e}, {0x9a67f, 0x9a69d}, + {0x9a6a0, 0x9a6e5}, {0x9a717, 0x9a71f}, {0x9a722, 0x9a788}, {0x9a78b, 0x9a7ae}, + {0x9a7b0, 0x9a7b7}, {0x9a7f7, 0x9a801}, {0x9a803, 0x9a805}, {0x9a807, 0x9a80a}, + {0x9a80c, 0x9a822}, {0x9a840, 0x9a873}, {0x9a882, 0x9a8b3}, {0x9a8f2, 0x9a8f7}, + {0x9a90a, 0x9a925}, {0x9a930, 0x9a946}, {0x9a960, 0x9a97c}, {0x9a984, 0x9a9b2}, + {0x9a9e0, 0x9a9e4}, {0x9a9e6, 0x9a9ef}, {0x9a9fa, 0x9a9fe}, {0x9aa00, 0x9aa28}, + {0x9aa40, 0x9aa42}, {0x9aa44, 0x9aa4b}, {0x9aa60, 0x9aa76}, {0x9aa7e, 0x9aaaf}, + {0x9aab9, 0x9aabd}, {0x9aadb, 0x9aadd}, {0x9aae0, 0x9aaea}, {0x9aaf2, 0x9aaf4}, + {0x9ab01, 0x9ab06}, {0x9ab09, 0x9ab0e}, {0x9ab11, 0x9ab16}, {0x9ab20, 0x9ab26}, + {0x9ab28, 0x9ab2e}, {0x9ab30, 0x9ab5a}, {0x9ab5c, 0x9ab65}, {0x9ab70, 0x9abe2}, + {0x9ac00, 0x9d7a3}, {0x9d7b0, 0x9d7c6}, {0x9d7cb, 0x9d7fb}, {0x9f900, 0x9fa6d}, + {0x9fa70, 0x9fad9}, {0x9fb00, 0x9fb06}, {0x9fb13, 0x9fb17}, {0x9fb1f, 0x9fb28}, + {0x9fb2a, 0x9fb36}, {0x9fb38, 0x9fb3c}, {0x9fb46, 0x9fbb1}, {0x9fbd3, 0x9fd3d}, + {0x9fd50, 0x9fd8f}, {0x9fd92, 0x9fdc7}, {0x9fdf0, 0x9fdfb}, {0x9fe70, 0x9fe74}, + {0x9fe76, 0x9fefc}, {0x9ff21, 0x9ff3a}, {0x9ff41, 0x9ff5a}, {0x9ff66, 0x9ffbe}, + {0x9ffc2, 0x9ffc7}, {0x9ffca, 0x9ffcf}, {0x9ffd2, 0x9ffd7}, {0x9ffda, 0x9ffdc}, + {0xa0041, 0xa005a}, {0xa0061, 0xa007a}, {0xa00c0, 0xa00d6}, {0xa00d8, 0xa00f6}, + {0xa00f8, 0xa02c1}, {0xa02c6, 0xa02d1}, {0xa02e0, 0xa02e4}, {0xa0370, 0xa0374}, + {0xa037a, 0xa037d}, {0xa0388, 0xa038a}, {0xa038e, 0xa03a1}, {0xa03a3, 0xa03f5}, + {0xa03f7, 0xa0481}, {0xa048a, 0xa052f}, {0xa0531, 0xa0556}, {0xa0561, 0xa0587}, + {0xa05d0, 0xa05ea}, {0xa05f0, 0xa05f2}, {0xa0620, 0xa064a}, {0xa0671, 0xa06d3}, + {0xa06fa, 0xa06fc}, {0xa0712, 0xa072f}, {0xa074d, 0xa07a5}, {0xa07ca, 0xa07ea}, + {0xa0800, 0xa0815}, {0xa0840, 0xa0858}, {0xa0860, 0xa086a}, {0xa08a0, 0xa08b4}, + {0xa08b6, 0xa08bd}, {0xa0904, 0xa0939}, {0xa0958, 0xa0961}, {0xa0971, 0xa0980}, + {0xa0985, 0xa098c}, {0xa0993, 0xa09a8}, {0xa09aa, 0xa09b0}, {0xa09b6, 0xa09b9}, + {0xa09df, 0xa09e1}, {0xa0a05, 0xa0a0a}, {0xa0a13, 0xa0a28}, {0xa0a2a, 0xa0a30}, + {0xa0a59, 0xa0a5c}, {0xa0a72, 0xa0a74}, {0xa0a85, 0xa0a8d}, {0xa0a8f, 0xa0a91}, + {0xa0a93, 0xa0aa8}, {0xa0aaa, 0xa0ab0}, {0xa0ab5, 0xa0ab9}, {0xa0b05, 0xa0b0c}, + {0xa0b13, 0xa0b28}, {0xa0b2a, 0xa0b30}, {0xa0b35, 0xa0b39}, {0xa0b5f, 0xa0b61}, + {0xa0b85, 0xa0b8a}, {0xa0b8e, 0xa0b90}, {0xa0b92, 0xa0b95}, {0xa0ba8, 0xa0baa}, + {0xa0bae, 0xa0bb9}, {0xa0c05, 0xa0c0c}, {0xa0c0e, 0xa0c10}, {0xa0c12, 0xa0c28}, + {0xa0c2a, 0xa0c39}, {0xa0c58, 0xa0c5a}, {0xa0c85, 0xa0c8c}, {0xa0c8e, 0xa0c90}, + {0xa0c92, 0xa0ca8}, {0xa0caa, 0xa0cb3}, {0xa0cb5, 0xa0cb9}, {0xa0d05, 0xa0d0c}, + {0xa0d0e, 0xa0d10}, {0xa0d12, 0xa0d3a}, {0xa0d54, 0xa0d56}, {0xa0d5f, 0xa0d61}, + {0xa0d7a, 0xa0d7f}, {0xa0d85, 0xa0d96}, {0xa0d9a, 0xa0db1}, {0xa0db3, 0xa0dbb}, + {0xa0dc0, 0xa0dc6}, {0xa0e01, 0xa0e30}, {0xa0e40, 0xa0e46}, {0xa0e94, 0xa0e97}, + {0xa0e99, 0xa0e9f}, {0xa0ea1, 0xa0ea3}, {0xa0ead, 0xa0eb0}, {0xa0ec0, 0xa0ec4}, + {0xa0edc, 0xa0edf}, {0xa0f40, 0xa0f47}, {0xa0f49, 0xa0f6c}, {0xa0f88, 0xa0f8c}, + {0xa1000, 0xa102a}, {0xa1050, 0xa1055}, {0xa105a, 0xa105d}, {0xa106e, 0xa1070}, + {0xa1075, 0xa1081}, {0xa10a0, 0xa10c5}, {0xa10d0, 0xa10fa}, {0xa10fc, 0xa1248}, + {0xa124a, 0xa124d}, {0xa1250, 0xa1256}, {0xa125a, 0xa125d}, {0xa1260, 0xa1288}, + {0xa128a, 0xa128d}, {0xa1290, 0xa12b0}, {0xa12b2, 0xa12b5}, {0xa12b8, 0xa12be}, + {0xa12c2, 0xa12c5}, {0xa12c8, 0xa12d6}, {0xa12d8, 0xa1310}, {0xa1312, 0xa1315}, + {0xa1318, 0xa135a}, {0xa1380, 0xa138f}, {0xa13a0, 0xa13f5}, {0xa13f8, 0xa13fd}, + {0xa1401, 0xa166c}, {0xa166f, 0xa167f}, {0xa1681, 0xa169a}, {0xa16a0, 0xa16ea}, + {0xa16f1, 0xa16f8}, {0xa1700, 0xa170c}, {0xa170e, 0xa1711}, {0xa1720, 0xa1731}, + {0xa1740, 0xa1751}, {0xa1760, 0xa176c}, {0xa176e, 0xa1770}, {0xa1780, 0xa17b3}, + {0xa1820, 0xa1877}, {0xa1880, 0xa1884}, {0xa1887, 0xa18a8}, {0xa18b0, 0xa18f5}, + {0xa1900, 0xa191e}, {0xa1950, 0xa196d}, {0xa1970, 0xa1974}, {0xa1980, 0xa19ab}, + {0xa19b0, 0xa19c9}, {0xa1a00, 0xa1a16}, {0xa1a20, 0xa1a54}, {0xa1b05, 0xa1b33}, + {0xa1b45, 0xa1b4b}, {0xa1b83, 0xa1ba0}, {0xa1bba, 0xa1be5}, {0xa1c00, 0xa1c23}, + {0xa1c4d, 0xa1c4f}, {0xa1c5a, 0xa1c7d}, {0xa1c80, 0xa1c88}, {0xa1ce9, 0xa1cec}, + {0xa1cee, 0xa1cf1}, {0xa1d00, 0xa1dbf}, {0xa1e00, 0xa1f15}, {0xa1f18, 0xa1f1d}, + {0xa1f20, 0xa1f45}, {0xa1f48, 0xa1f4d}, {0xa1f50, 0xa1f57}, {0xa1f5f, 0xa1f7d}, + {0xa1f80, 0xa1fb4}, {0xa1fb6, 0xa1fbc}, {0xa1fc2, 0xa1fc4}, {0xa1fc6, 0xa1fcc}, + {0xa1fd0, 0xa1fd3}, {0xa1fd6, 0xa1fdb}, {0xa1fe0, 0xa1fec}, {0xa1ff2, 0xa1ff4}, + {0xa1ff6, 0xa1ffc}, {0xa2090, 0xa209c}, {0xa210a, 0xa2113}, {0xa2119, 0xa211d}, + {0xa212a, 0xa212d}, {0xa212f, 0xa2139}, {0xa213c, 0xa213f}, {0xa2145, 0xa2149}, + {0xa2c00, 0xa2c2e}, {0xa2c30, 0xa2c5e}, {0xa2c60, 0xa2ce4}, {0xa2ceb, 0xa2cee}, + {0xa2d00, 0xa2d25}, {0xa2d30, 0xa2d67}, {0xa2d80, 0xa2d96}, {0xa2da0, 0xa2da6}, + {0xa2da8, 0xa2dae}, {0xa2db0, 0xa2db6}, {0xa2db8, 0xa2dbe}, {0xa2dc0, 0xa2dc6}, + {0xa2dc8, 0xa2dce}, {0xa2dd0, 0xa2dd6}, {0xa2dd8, 0xa2dde}, {0xa3031, 0xa3035}, + {0xa3041, 0xa3096}, {0xa309d, 0xa309f}, {0xa30a1, 0xa30fa}, {0xa30fc, 0xa30ff}, + {0xa3105, 0xa312e}, {0xa3131, 0xa318e}, {0xa31a0, 0xa31ba}, {0xa31f0, 0xa31ff}, + {0xa3400, 0xa4db5}, {0xa4e00, 0xa9fea}, {0xaa000, 0xaa48c}, {0xaa4d0, 0xaa4fd}, + {0xaa500, 0xaa60c}, {0xaa610, 0xaa61f}, {0xaa640, 0xaa66e}, {0xaa67f, 0xaa69d}, + {0xaa6a0, 0xaa6e5}, {0xaa717, 0xaa71f}, {0xaa722, 0xaa788}, {0xaa78b, 0xaa7ae}, + {0xaa7b0, 0xaa7b7}, {0xaa7f7, 0xaa801}, {0xaa803, 0xaa805}, {0xaa807, 0xaa80a}, + {0xaa80c, 0xaa822}, {0xaa840, 0xaa873}, {0xaa882, 0xaa8b3}, {0xaa8f2, 0xaa8f7}, + {0xaa90a, 0xaa925}, {0xaa930, 0xaa946}, {0xaa960, 0xaa97c}, {0xaa984, 0xaa9b2}, + {0xaa9e0, 0xaa9e4}, {0xaa9e6, 0xaa9ef}, {0xaa9fa, 0xaa9fe}, {0xaaa00, 0xaaa28}, + {0xaaa40, 0xaaa42}, {0xaaa44, 0xaaa4b}, {0xaaa60, 0xaaa76}, {0xaaa7e, 0xaaaaf}, + {0xaaab9, 0xaaabd}, {0xaaadb, 0xaaadd}, {0xaaae0, 0xaaaea}, {0xaaaf2, 0xaaaf4}, + {0xaab01, 0xaab06}, {0xaab09, 0xaab0e}, {0xaab11, 0xaab16}, {0xaab20, 0xaab26}, + {0xaab28, 0xaab2e}, {0xaab30, 0xaab5a}, {0xaab5c, 0xaab65}, {0xaab70, 0xaabe2}, + {0xaac00, 0xad7a3}, {0xad7b0, 0xad7c6}, {0xad7cb, 0xad7fb}, {0xaf900, 0xafa6d}, + {0xafa70, 0xafad9}, {0xafb00, 0xafb06}, {0xafb13, 0xafb17}, {0xafb1f, 0xafb28}, + {0xafb2a, 0xafb36}, {0xafb38, 0xafb3c}, {0xafb46, 0xafbb1}, {0xafbd3, 0xafd3d}, + {0xafd50, 0xafd8f}, {0xafd92, 0xafdc7}, {0xafdf0, 0xafdfb}, {0xafe70, 0xafe74}, + {0xafe76, 0xafefc}, {0xaff21, 0xaff3a}, {0xaff41, 0xaff5a}, {0xaff66, 0xaffbe}, + {0xaffc2, 0xaffc7}, {0xaffca, 0xaffcf}, {0xaffd2, 0xaffd7}, {0xaffda, 0xaffdc}, + {0xb0041, 0xb005a}, {0xb0061, 0xb007a}, {0xb00c0, 0xb00d6}, {0xb00d8, 0xb00f6}, + {0xb00f8, 0xb02c1}, {0xb02c6, 0xb02d1}, {0xb02e0, 0xb02e4}, {0xb0370, 0xb0374}, + {0xb037a, 0xb037d}, {0xb0388, 0xb038a}, {0xb038e, 0xb03a1}, {0xb03a3, 0xb03f5}, + {0xb03f7, 0xb0481}, {0xb048a, 0xb052f}, {0xb0531, 0xb0556}, {0xb0561, 0xb0587}, + {0xb05d0, 0xb05ea}, {0xb05f0, 0xb05f2}, {0xb0620, 0xb064a}, {0xb0671, 0xb06d3}, + {0xb06fa, 0xb06fc}, {0xb0712, 0xb072f}, {0xb074d, 0xb07a5}, {0xb07ca, 0xb07ea}, + {0xb0800, 0xb0815}, {0xb0840, 0xb0858}, {0xb0860, 0xb086a}, {0xb08a0, 0xb08b4}, + {0xb08b6, 0xb08bd}, {0xb0904, 0xb0939}, {0xb0958, 0xb0961}, {0xb0971, 0xb0980}, + {0xb0985, 0xb098c}, {0xb0993, 0xb09a8}, {0xb09aa, 0xb09b0}, {0xb09b6, 0xb09b9}, + {0xb09df, 0xb09e1}, {0xb0a05, 0xb0a0a}, {0xb0a13, 0xb0a28}, {0xb0a2a, 0xb0a30}, + {0xb0a59, 0xb0a5c}, {0xb0a72, 0xb0a74}, {0xb0a85, 0xb0a8d}, {0xb0a8f, 0xb0a91}, + {0xb0a93, 0xb0aa8}, {0xb0aaa, 0xb0ab0}, {0xb0ab5, 0xb0ab9}, {0xb0b05, 0xb0b0c}, + {0xb0b13, 0xb0b28}, {0xb0b2a, 0xb0b30}, {0xb0b35, 0xb0b39}, {0xb0b5f, 0xb0b61}, + {0xb0b85, 0xb0b8a}, {0xb0b8e, 0xb0b90}, {0xb0b92, 0xb0b95}, {0xb0ba8, 0xb0baa}, + {0xb0bae, 0xb0bb9}, {0xb0c05, 0xb0c0c}, {0xb0c0e, 0xb0c10}, {0xb0c12, 0xb0c28}, + {0xb0c2a, 0xb0c39}, {0xb0c58, 0xb0c5a}, {0xb0c85, 0xb0c8c}, {0xb0c8e, 0xb0c90}, + {0xb0c92, 0xb0ca8}, {0xb0caa, 0xb0cb3}, {0xb0cb5, 0xb0cb9}, {0xb0d05, 0xb0d0c}, + {0xb0d0e, 0xb0d10}, {0xb0d12, 0xb0d3a}, {0xb0d54, 0xb0d56}, {0xb0d5f, 0xb0d61}, + {0xb0d7a, 0xb0d7f}, {0xb0d85, 0xb0d96}, {0xb0d9a, 0xb0db1}, {0xb0db3, 0xb0dbb}, + {0xb0dc0, 0xb0dc6}, {0xb0e01, 0xb0e30}, {0xb0e40, 0xb0e46}, {0xb0e94, 0xb0e97}, + {0xb0e99, 0xb0e9f}, {0xb0ea1, 0xb0ea3}, {0xb0ead, 0xb0eb0}, {0xb0ec0, 0xb0ec4}, + {0xb0edc, 0xb0edf}, {0xb0f40, 0xb0f47}, {0xb0f49, 0xb0f6c}, {0xb0f88, 0xb0f8c}, + {0xb1000, 0xb102a}, {0xb1050, 0xb1055}, {0xb105a, 0xb105d}, {0xb106e, 0xb1070}, + {0xb1075, 0xb1081}, {0xb10a0, 0xb10c5}, {0xb10d0, 0xb10fa}, {0xb10fc, 0xb1248}, + {0xb124a, 0xb124d}, {0xb1250, 0xb1256}, {0xb125a, 0xb125d}, {0xb1260, 0xb1288}, + {0xb128a, 0xb128d}, {0xb1290, 0xb12b0}, {0xb12b2, 0xb12b5}, {0xb12b8, 0xb12be}, + {0xb12c2, 0xb12c5}, {0xb12c8, 0xb12d6}, {0xb12d8, 0xb1310}, {0xb1312, 0xb1315}, + {0xb1318, 0xb135a}, {0xb1380, 0xb138f}, {0xb13a0, 0xb13f5}, {0xb13f8, 0xb13fd}, + {0xb1401, 0xb166c}, {0xb166f, 0xb167f}, {0xb1681, 0xb169a}, {0xb16a0, 0xb16ea}, + {0xb16f1, 0xb16f8}, {0xb1700, 0xb170c}, {0xb170e, 0xb1711}, {0xb1720, 0xb1731}, + {0xb1740, 0xb1751}, {0xb1760, 0xb176c}, {0xb176e, 0xb1770}, {0xb1780, 0xb17b3}, + {0xb1820, 0xb1877}, {0xb1880, 0xb1884}, {0xb1887, 0xb18a8}, {0xb18b0, 0xb18f5}, + {0xb1900, 0xb191e}, {0xb1950, 0xb196d}, {0xb1970, 0xb1974}, {0xb1980, 0xb19ab}, + {0xb19b0, 0xb19c9}, {0xb1a00, 0xb1a16}, {0xb1a20, 0xb1a54}, {0xb1b05, 0xb1b33}, + {0xb1b45, 0xb1b4b}, {0xb1b83, 0xb1ba0}, {0xb1bba, 0xb1be5}, {0xb1c00, 0xb1c23}, + {0xb1c4d, 0xb1c4f}, {0xb1c5a, 0xb1c7d}, {0xb1c80, 0xb1c88}, {0xb1ce9, 0xb1cec}, + {0xb1cee, 0xb1cf1}, {0xb1d00, 0xb1dbf}, {0xb1e00, 0xb1f15}, {0xb1f18, 0xb1f1d}, + {0xb1f20, 0xb1f45}, {0xb1f48, 0xb1f4d}, {0xb1f50, 0xb1f57}, {0xb1f5f, 0xb1f7d}, + {0xb1f80, 0xb1fb4}, {0xb1fb6, 0xb1fbc}, {0xb1fc2, 0xb1fc4}, {0xb1fc6, 0xb1fcc}, + {0xb1fd0, 0xb1fd3}, {0xb1fd6, 0xb1fdb}, {0xb1fe0, 0xb1fec}, {0xb1ff2, 0xb1ff4}, + {0xb1ff6, 0xb1ffc}, {0xb2090, 0xb209c}, {0xb210a, 0xb2113}, {0xb2119, 0xb211d}, + {0xb212a, 0xb212d}, {0xb212f, 0xb2139}, {0xb213c, 0xb213f}, {0xb2145, 0xb2149}, + {0xb2c00, 0xb2c2e}, {0xb2c30, 0xb2c5e}, {0xb2c60, 0xb2ce4}, {0xb2ceb, 0xb2cee}, + {0xb2d00, 0xb2d25}, {0xb2d30, 0xb2d67}, {0xb2d80, 0xb2d96}, {0xb2da0, 0xb2da6}, + {0xb2da8, 0xb2dae}, {0xb2db0, 0xb2db6}, {0xb2db8, 0xb2dbe}, {0xb2dc0, 0xb2dc6}, + {0xb2dc8, 0xb2dce}, {0xb2dd0, 0xb2dd6}, {0xb2dd8, 0xb2dde}, {0xb3031, 0xb3035}, + {0xb3041, 0xb3096}, {0xb309d, 0xb309f}, {0xb30a1, 0xb30fa}, {0xb30fc, 0xb30ff}, + {0xb3105, 0xb312e}, {0xb3131, 0xb318e}, {0xb31a0, 0xb31ba}, {0xb31f0, 0xb31ff}, + {0xb3400, 0xb4db5}, {0xb4e00, 0xb9fea}, {0xba000, 0xba48c}, {0xba4d0, 0xba4fd}, + {0xba500, 0xba60c}, {0xba610, 0xba61f}, {0xba640, 0xba66e}, {0xba67f, 0xba69d}, + {0xba6a0, 0xba6e5}, {0xba717, 0xba71f}, {0xba722, 0xba788}, {0xba78b, 0xba7ae}, + {0xba7b0, 0xba7b7}, {0xba7f7, 0xba801}, {0xba803, 0xba805}, {0xba807, 0xba80a}, + {0xba80c, 0xba822}, {0xba840, 0xba873}, {0xba882, 0xba8b3}, {0xba8f2, 0xba8f7}, + {0xba90a, 0xba925}, {0xba930, 0xba946}, {0xba960, 0xba97c}, {0xba984, 0xba9b2}, + {0xba9e0, 0xba9e4}, {0xba9e6, 0xba9ef}, {0xba9fa, 0xba9fe}, {0xbaa00, 0xbaa28}, + {0xbaa40, 0xbaa42}, {0xbaa44, 0xbaa4b}, {0xbaa60, 0xbaa76}, {0xbaa7e, 0xbaaaf}, + {0xbaab9, 0xbaabd}, {0xbaadb, 0xbaadd}, {0xbaae0, 0xbaaea}, {0xbaaf2, 0xbaaf4}, + {0xbab01, 0xbab06}, {0xbab09, 0xbab0e}, {0xbab11, 0xbab16}, {0xbab20, 0xbab26}, + {0xbab28, 0xbab2e}, {0xbab30, 0xbab5a}, {0xbab5c, 0xbab65}, {0xbab70, 0xbabe2}, + {0xbac00, 0xbd7a3}, {0xbd7b0, 0xbd7c6}, {0xbd7cb, 0xbd7fb}, {0xbf900, 0xbfa6d}, + {0xbfa70, 0xbfad9}, {0xbfb00, 0xbfb06}, {0xbfb13, 0xbfb17}, {0xbfb1f, 0xbfb28}, + {0xbfb2a, 0xbfb36}, {0xbfb38, 0xbfb3c}, {0xbfb46, 0xbfbb1}, {0xbfbd3, 0xbfd3d}, + {0xbfd50, 0xbfd8f}, {0xbfd92, 0xbfdc7}, {0xbfdf0, 0xbfdfb}, {0xbfe70, 0xbfe74}, + {0xbfe76, 0xbfefc}, {0xbff21, 0xbff3a}, {0xbff41, 0xbff5a}, {0xbff66, 0xbffbe}, + {0xbffc2, 0xbffc7}, {0xbffca, 0xbffcf}, {0xbffd2, 0xbffd7}, {0xbffda, 0xbffdc}, + {0xc0041, 0xc005a}, {0xc0061, 0xc007a}, {0xc00c0, 0xc00d6}, {0xc00d8, 0xc00f6}, + {0xc00f8, 0xc02c1}, {0xc02c6, 0xc02d1}, {0xc02e0, 0xc02e4}, {0xc0370, 0xc0374}, + {0xc037a, 0xc037d}, {0xc0388, 0xc038a}, {0xc038e, 0xc03a1}, {0xc03a3, 0xc03f5}, + {0xc03f7, 0xc0481}, {0xc048a, 0xc052f}, {0xc0531, 0xc0556}, {0xc0561, 0xc0587}, + {0xc05d0, 0xc05ea}, {0xc05f0, 0xc05f2}, {0xc0620, 0xc064a}, {0xc0671, 0xc06d3}, + {0xc06fa, 0xc06fc}, {0xc0712, 0xc072f}, {0xc074d, 0xc07a5}, {0xc07ca, 0xc07ea}, + {0xc0800, 0xc0815}, {0xc0840, 0xc0858}, {0xc0860, 0xc086a}, {0xc08a0, 0xc08b4}, + {0xc08b6, 0xc08bd}, {0xc0904, 0xc0939}, {0xc0958, 0xc0961}, {0xc0971, 0xc0980}, + {0xc0985, 0xc098c}, {0xc0993, 0xc09a8}, {0xc09aa, 0xc09b0}, {0xc09b6, 0xc09b9}, + {0xc09df, 0xc09e1}, {0xc0a05, 0xc0a0a}, {0xc0a13, 0xc0a28}, {0xc0a2a, 0xc0a30}, + {0xc0a59, 0xc0a5c}, {0xc0a72, 0xc0a74}, {0xc0a85, 0xc0a8d}, {0xc0a8f, 0xc0a91}, + {0xc0a93, 0xc0aa8}, {0xc0aaa, 0xc0ab0}, {0xc0ab5, 0xc0ab9}, {0xc0b05, 0xc0b0c}, + {0xc0b13, 0xc0b28}, {0xc0b2a, 0xc0b30}, {0xc0b35, 0xc0b39}, {0xc0b5f, 0xc0b61}, + {0xc0b85, 0xc0b8a}, {0xc0b8e, 0xc0b90}, {0xc0b92, 0xc0b95}, {0xc0ba8, 0xc0baa}, + {0xc0bae, 0xc0bb9}, {0xc0c05, 0xc0c0c}, {0xc0c0e, 0xc0c10}, {0xc0c12, 0xc0c28}, + {0xc0c2a, 0xc0c39}, {0xc0c58, 0xc0c5a}, {0xc0c85, 0xc0c8c}, {0xc0c8e, 0xc0c90}, + {0xc0c92, 0xc0ca8}, {0xc0caa, 0xc0cb3}, {0xc0cb5, 0xc0cb9}, {0xc0d05, 0xc0d0c}, + {0xc0d0e, 0xc0d10}, {0xc0d12, 0xc0d3a}, {0xc0d54, 0xc0d56}, {0xc0d5f, 0xc0d61}, + {0xc0d7a, 0xc0d7f}, {0xc0d85, 0xc0d96}, {0xc0d9a, 0xc0db1}, {0xc0db3, 0xc0dbb}, + {0xc0dc0, 0xc0dc6}, {0xc0e01, 0xc0e30}, {0xc0e40, 0xc0e46}, {0xc0e94, 0xc0e97}, + {0xc0e99, 0xc0e9f}, {0xc0ea1, 0xc0ea3}, {0xc0ead, 0xc0eb0}, {0xc0ec0, 0xc0ec4}, + {0xc0edc, 0xc0edf}, {0xc0f40, 0xc0f47}, {0xc0f49, 0xc0f6c}, {0xc0f88, 0xc0f8c}, + {0xc1000, 0xc102a}, {0xc1050, 0xc1055}, {0xc105a, 0xc105d}, {0xc106e, 0xc1070}, + {0xc1075, 0xc1081}, {0xc10a0, 0xc10c5}, {0xc10d0, 0xc10fa}, {0xc10fc, 0xc1248}, + {0xc124a, 0xc124d}, {0xc1250, 0xc1256}, {0xc125a, 0xc125d}, {0xc1260, 0xc1288}, + {0xc128a, 0xc128d}, {0xc1290, 0xc12b0}, {0xc12b2, 0xc12b5}, {0xc12b8, 0xc12be}, + {0xc12c2, 0xc12c5}, {0xc12c8, 0xc12d6}, {0xc12d8, 0xc1310}, {0xc1312, 0xc1315}, + {0xc1318, 0xc135a}, {0xc1380, 0xc138f}, {0xc13a0, 0xc13f5}, {0xc13f8, 0xc13fd}, + {0xc1401, 0xc166c}, {0xc166f, 0xc167f}, {0xc1681, 0xc169a}, {0xc16a0, 0xc16ea}, + {0xc16f1, 0xc16f8}, {0xc1700, 0xc170c}, {0xc170e, 0xc1711}, {0xc1720, 0xc1731}, + {0xc1740, 0xc1751}, {0xc1760, 0xc176c}, {0xc176e, 0xc1770}, {0xc1780, 0xc17b3}, + {0xc1820, 0xc1877}, {0xc1880, 0xc1884}, {0xc1887, 0xc18a8}, {0xc18b0, 0xc18f5}, + {0xc1900, 0xc191e}, {0xc1950, 0xc196d}, {0xc1970, 0xc1974}, {0xc1980, 0xc19ab}, + {0xc19b0, 0xc19c9}, {0xc1a00, 0xc1a16}, {0xc1a20, 0xc1a54}, {0xc1b05, 0xc1b33}, + {0xc1b45, 0xc1b4b}, {0xc1b83, 0xc1ba0}, {0xc1bba, 0xc1be5}, {0xc1c00, 0xc1c23}, + {0xc1c4d, 0xc1c4f}, {0xc1c5a, 0xc1c7d}, {0xc1c80, 0xc1c88}, {0xc1ce9, 0xc1cec}, + {0xc1cee, 0xc1cf1}, {0xc1d00, 0xc1dbf}, {0xc1e00, 0xc1f15}, {0xc1f18, 0xc1f1d}, + {0xc1f20, 0xc1f45}, {0xc1f48, 0xc1f4d}, {0xc1f50, 0xc1f57}, {0xc1f5f, 0xc1f7d}, + {0xc1f80, 0xc1fb4}, {0xc1fb6, 0xc1fbc}, {0xc1fc2, 0xc1fc4}, {0xc1fc6, 0xc1fcc}, + {0xc1fd0, 0xc1fd3}, {0xc1fd6, 0xc1fdb}, {0xc1fe0, 0xc1fec}, {0xc1ff2, 0xc1ff4}, + {0xc1ff6, 0xc1ffc}, {0xc2090, 0xc209c}, {0xc210a, 0xc2113}, {0xc2119, 0xc211d}, + {0xc212a, 0xc212d}, {0xc212f, 0xc2139}, {0xc213c, 0xc213f}, {0xc2145, 0xc2149}, + {0xc2c00, 0xc2c2e}, {0xc2c30, 0xc2c5e}, {0xc2c60, 0xc2ce4}, {0xc2ceb, 0xc2cee}, + {0xc2d00, 0xc2d25}, {0xc2d30, 0xc2d67}, {0xc2d80, 0xc2d96}, {0xc2da0, 0xc2da6}, + {0xc2da8, 0xc2dae}, {0xc2db0, 0xc2db6}, {0xc2db8, 0xc2dbe}, {0xc2dc0, 0xc2dc6}, + {0xc2dc8, 0xc2dce}, {0xc2dd0, 0xc2dd6}, {0xc2dd8, 0xc2dde}, {0xc3031, 0xc3035}, + {0xc3041, 0xc3096}, {0xc309d, 0xc309f}, {0xc30a1, 0xc30fa}, {0xc30fc, 0xc30ff}, + {0xc3105, 0xc312e}, {0xc3131, 0xc318e}, {0xc31a0, 0xc31ba}, {0xc31f0, 0xc31ff}, + {0xc3400, 0xc4db5}, {0xc4e00, 0xc9fea}, {0xca000, 0xca48c}, {0xca4d0, 0xca4fd}, + {0xca500, 0xca60c}, {0xca610, 0xca61f}, {0xca640, 0xca66e}, {0xca67f, 0xca69d}, + {0xca6a0, 0xca6e5}, {0xca717, 0xca71f}, {0xca722, 0xca788}, {0xca78b, 0xca7ae}, + {0xca7b0, 0xca7b7}, {0xca7f7, 0xca801}, {0xca803, 0xca805}, {0xca807, 0xca80a}, + {0xca80c, 0xca822}, {0xca840, 0xca873}, {0xca882, 0xca8b3}, {0xca8f2, 0xca8f7}, + {0xca90a, 0xca925}, {0xca930, 0xca946}, {0xca960, 0xca97c}, {0xca984, 0xca9b2}, + {0xca9e0, 0xca9e4}, {0xca9e6, 0xca9ef}, {0xca9fa, 0xca9fe}, {0xcaa00, 0xcaa28}, + {0xcaa40, 0xcaa42}, {0xcaa44, 0xcaa4b}, {0xcaa60, 0xcaa76}, {0xcaa7e, 0xcaaaf}, + {0xcaab9, 0xcaabd}, {0xcaadb, 0xcaadd}, {0xcaae0, 0xcaaea}, {0xcaaf2, 0xcaaf4}, + {0xcab01, 0xcab06}, {0xcab09, 0xcab0e}, {0xcab11, 0xcab16}, {0xcab20, 0xcab26}, + {0xcab28, 0xcab2e}, {0xcab30, 0xcab5a}, {0xcab5c, 0xcab65}, {0xcab70, 0xcabe2}, + {0xcac00, 0xcd7a3}, {0xcd7b0, 0xcd7c6}, {0xcd7cb, 0xcd7fb}, {0xcf900, 0xcfa6d}, + {0xcfa70, 0xcfad9}, {0xcfb00, 0xcfb06}, {0xcfb13, 0xcfb17}, {0xcfb1f, 0xcfb28}, + {0xcfb2a, 0xcfb36}, {0xcfb38, 0xcfb3c}, {0xcfb46, 0xcfbb1}, {0xcfbd3, 0xcfd3d}, + {0xcfd50, 0xcfd8f}, {0xcfd92, 0xcfdc7}, {0xcfdf0, 0xcfdfb}, {0xcfe70, 0xcfe74}, + {0xcfe76, 0xcfefc}, {0xcff21, 0xcff3a}, {0xcff41, 0xcff5a}, {0xcff66, 0xcffbe}, + {0xcffc2, 0xcffc7}, {0xcffca, 0xcffcf}, {0xcffd2, 0xcffd7}, {0xcffda, 0xcffdc}, + {0xd0041, 0xd005a}, {0xd0061, 0xd007a}, {0xd00c0, 0xd00d6}, {0xd00d8, 0xd00f6}, + {0xd00f8, 0xd02c1}, {0xd02c6, 0xd02d1}, {0xd02e0, 0xd02e4}, {0xd0370, 0xd0374}, + {0xd037a, 0xd037d}, {0xd0388, 0xd038a}, {0xd038e, 0xd03a1}, {0xd03a3, 0xd03f5}, + {0xd03f7, 0xd0481}, {0xd048a, 0xd052f}, {0xd0531, 0xd0556}, {0xd0561, 0xd0587}, + {0xd05d0, 0xd05ea}, {0xd05f0, 0xd05f2}, {0xd0620, 0xd064a}, {0xd0671, 0xd06d3}, + {0xd06fa, 0xd06fc}, {0xd0712, 0xd072f}, {0xd074d, 0xd07a5}, {0xd07ca, 0xd07ea}, + {0xd0800, 0xd0815}, {0xd0840, 0xd0858}, {0xd0860, 0xd086a}, {0xd08a0, 0xd08b4}, + {0xd08b6, 0xd08bd}, {0xd0904, 0xd0939}, {0xd0958, 0xd0961}, {0xd0971, 0xd0980}, + {0xd0985, 0xd098c}, {0xd0993, 0xd09a8}, {0xd09aa, 0xd09b0}, {0xd09b6, 0xd09b9}, + {0xd09df, 0xd09e1}, {0xd0a05, 0xd0a0a}, {0xd0a13, 0xd0a28}, {0xd0a2a, 0xd0a30}, + {0xd0a59, 0xd0a5c}, {0xd0a72, 0xd0a74}, {0xd0a85, 0xd0a8d}, {0xd0a8f, 0xd0a91}, + {0xd0a93, 0xd0aa8}, {0xd0aaa, 0xd0ab0}, {0xd0ab5, 0xd0ab9}, {0xd0b05, 0xd0b0c}, + {0xd0b13, 0xd0b28}, {0xd0b2a, 0xd0b30}, {0xd0b35, 0xd0b39}, {0xd0b5f, 0xd0b61}, + {0xd0b85, 0xd0b8a}, {0xd0b8e, 0xd0b90}, {0xd0b92, 0xd0b95}, {0xd0ba8, 0xd0baa}, + {0xd0bae, 0xd0bb9}, {0xd0c05, 0xd0c0c}, {0xd0c0e, 0xd0c10}, {0xd0c12, 0xd0c28}, + {0xd0c2a, 0xd0c39}, {0xd0c58, 0xd0c5a}, {0xd0c85, 0xd0c8c}, {0xd0c8e, 0xd0c90}, + {0xd0c92, 0xd0ca8}, {0xd0caa, 0xd0cb3}, {0xd0cb5, 0xd0cb9}, {0xd0d05, 0xd0d0c}, + {0xd0d0e, 0xd0d10}, {0xd0d12, 0xd0d3a}, {0xd0d54, 0xd0d56}, {0xd0d5f, 0xd0d61}, + {0xd0d7a, 0xd0d7f}, {0xd0d85, 0xd0d96}, {0xd0d9a, 0xd0db1}, {0xd0db3, 0xd0dbb}, + {0xd0dc0, 0xd0dc6}, {0xd0e01, 0xd0e30}, {0xd0e40, 0xd0e46}, {0xd0e94, 0xd0e97}, + {0xd0e99, 0xd0e9f}, {0xd0ea1, 0xd0ea3}, {0xd0ead, 0xd0eb0}, {0xd0ec0, 0xd0ec4}, + {0xd0edc, 0xd0edf}, {0xd0f40, 0xd0f47}, {0xd0f49, 0xd0f6c}, {0xd0f88, 0xd0f8c}, + {0xd1000, 0xd102a}, {0xd1050, 0xd1055}, {0xd105a, 0xd105d}, {0xd106e, 0xd1070}, + {0xd1075, 0xd1081}, {0xd10a0, 0xd10c5}, {0xd10d0, 0xd10fa}, {0xd10fc, 0xd1248}, + {0xd124a, 0xd124d}, {0xd1250, 0xd1256}, {0xd125a, 0xd125d}, {0xd1260, 0xd1288}, + {0xd128a, 0xd128d}, {0xd1290, 0xd12b0}, {0xd12b2, 0xd12b5}, {0xd12b8, 0xd12be}, + {0xd12c2, 0xd12c5}, {0xd12c8, 0xd12d6}, {0xd12d8, 0xd1310}, {0xd1312, 0xd1315}, + {0xd1318, 0xd135a}, {0xd1380, 0xd138f}, {0xd13a0, 0xd13f5}, {0xd13f8, 0xd13fd}, + {0xd1401, 0xd166c}, {0xd166f, 0xd167f}, {0xd1681, 0xd169a}, {0xd16a0, 0xd16ea}, + {0xd16f1, 0xd16f8}, {0xd1700, 0xd170c}, {0xd170e, 0xd1711}, {0xd1720, 0xd1731}, + {0xd1740, 0xd1751}, {0xd1760, 0xd176c}, {0xd176e, 0xd1770}, {0xd1780, 0xd17b3}, + {0xd1820, 0xd1877}, {0xd1880, 0xd1884}, {0xd1887, 0xd18a8}, {0xd18b0, 0xd18f5}, + {0xd1900, 0xd191e}, {0xd1950, 0xd196d}, {0xd1970, 0xd1974}, {0xd1980, 0xd19ab}, + {0xd19b0, 0xd19c9}, {0xd1a00, 0xd1a16}, {0xd1a20, 0xd1a54}, {0xd1b05, 0xd1b33}, + {0xd1b45, 0xd1b4b}, {0xd1b83, 0xd1ba0}, {0xd1bba, 0xd1be5}, {0xd1c00, 0xd1c23}, + {0xd1c4d, 0xd1c4f}, {0xd1c5a, 0xd1c7d}, {0xd1c80, 0xd1c88}, {0xd1ce9, 0xd1cec}, + {0xd1cee, 0xd1cf1}, {0xd1d00, 0xd1dbf}, {0xd1e00, 0xd1f15}, {0xd1f18, 0xd1f1d}, + {0xd1f20, 0xd1f45}, {0xd1f48, 0xd1f4d}, {0xd1f50, 0xd1f57}, {0xd1f5f, 0xd1f7d}, + {0xd1f80, 0xd1fb4}, {0xd1fb6, 0xd1fbc}, {0xd1fc2, 0xd1fc4}, {0xd1fc6, 0xd1fcc}, + {0xd1fd0, 0xd1fd3}, {0xd1fd6, 0xd1fdb}, {0xd1fe0, 0xd1fec}, {0xd1ff2, 0xd1ff4}, + {0xd1ff6, 0xd1ffc}, {0xd2090, 0xd209c}, {0xd210a, 0xd2113}, {0xd2119, 0xd211d}, + {0xd212a, 0xd212d}, {0xd212f, 0xd2139}, {0xd213c, 0xd213f}, {0xd2145, 0xd2149}, + {0xd2c00, 0xd2c2e}, {0xd2c30, 0xd2c5e}, {0xd2c60, 0xd2ce4}, {0xd2ceb, 0xd2cee}, + {0xd2d00, 0xd2d25}, {0xd2d30, 0xd2d67}, {0xd2d80, 0xd2d96}, {0xd2da0, 0xd2da6}, + {0xd2da8, 0xd2dae}, {0xd2db0, 0xd2db6}, {0xd2db8, 0xd2dbe}, {0xd2dc0, 0xd2dc6}, + {0xd2dc8, 0xd2dce}, {0xd2dd0, 0xd2dd6}, {0xd2dd8, 0xd2dde}, {0xd3031, 0xd3035}, + {0xd3041, 0xd3096}, {0xd309d, 0xd309f}, {0xd30a1, 0xd30fa}, {0xd30fc, 0xd30ff}, + {0xd3105, 0xd312e}, {0xd3131, 0xd318e}, {0xd31a0, 0xd31ba}, {0xd31f0, 0xd31ff}, + {0xd3400, 0xd4db5}, {0xd4e00, 0xd9fea}, {0xda000, 0xda48c}, {0xda4d0, 0xda4fd}, + {0xda500, 0xda60c}, {0xda610, 0xda61f}, {0xda640, 0xda66e}, {0xda67f, 0xda69d}, + {0xda6a0, 0xda6e5}, {0xda717, 0xda71f}, {0xda722, 0xda788}, {0xda78b, 0xda7ae}, + {0xda7b0, 0xda7b7}, {0xda7f7, 0xda801}, {0xda803, 0xda805}, {0xda807, 0xda80a}, + {0xda80c, 0xda822}, {0xda840, 0xda873}, {0xda882, 0xda8b3}, {0xda8f2, 0xda8f7}, + {0xda90a, 0xda925}, {0xda930, 0xda946}, {0xda960, 0xda97c}, {0xda984, 0xda9b2}, + {0xda9e0, 0xda9e4}, {0xda9e6, 0xda9ef}, {0xda9fa, 0xda9fe}, {0xdaa00, 0xdaa28}, + {0xdaa40, 0xdaa42}, {0xdaa44, 0xdaa4b}, {0xdaa60, 0xdaa76}, {0xdaa7e, 0xdaaaf}, + {0xdaab9, 0xdaabd}, {0xdaadb, 0xdaadd}, {0xdaae0, 0xdaaea}, {0xdaaf2, 0xdaaf4}, + {0xdab01, 0xdab06}, {0xdab09, 0xdab0e}, {0xdab11, 0xdab16}, {0xdab20, 0xdab26}, + {0xdab28, 0xdab2e}, {0xdab30, 0xdab5a}, {0xdab5c, 0xdab65}, {0xdab70, 0xdabe2}, + {0xdac00, 0xdd7a3}, {0xdd7b0, 0xdd7c6}, {0xdd7cb, 0xdd7fb}, {0xdf900, 0xdfa6d}, + {0xdfa70, 0xdfad9}, {0xdfb00, 0xdfb06}, {0xdfb13, 0xdfb17}, {0xdfb1f, 0xdfb28}, + {0xdfb2a, 0xdfb36}, {0xdfb38, 0xdfb3c}, {0xdfb46, 0xdfbb1}, {0xdfbd3, 0xdfd3d}, + {0xdfd50, 0xdfd8f}, {0xdfd92, 0xdfdc7}, {0xdfdf0, 0xdfdfb}, {0xdfe70, 0xdfe74}, + {0xdfe76, 0xdfefc}, {0xdff21, 0xdff3a}, {0xdff41, 0xdff5a}, {0xdff66, 0xdffbe}, + {0xdffc2, 0xdffc7}, {0xdffca, 0xdffcf}, {0xdffd2, 0xdffd7}, {0xdffda, 0xdffdc}, + {0xe0041, 0xe005a}, {0xe0061, 0xe007a}, {0xe00c0, 0xe00d6}, {0xe00d8, 0xe00f6}, + {0xe00f8, 0xe02c1}, {0xe02c6, 0xe02d1}, {0xe02e0, 0xe02e4}, {0xe0370, 0xe0374}, + {0xe037a, 0xe037d}, {0xe0388, 0xe038a}, {0xe038e, 0xe03a1}, {0xe03a3, 0xe03f5}, + {0xe03f7, 0xe0481}, {0xe048a, 0xe052f}, {0xe0531, 0xe0556}, {0xe0561, 0xe0587}, + {0xe05d0, 0xe05ea}, {0xe05f0, 0xe05f2}, {0xe0620, 0xe064a}, {0xe0671, 0xe06d3}, + {0xe06fa, 0xe06fc}, {0xe0712, 0xe072f}, {0xe074d, 0xe07a5}, {0xe07ca, 0xe07ea}, + {0xe0800, 0xe0815}, {0xe0840, 0xe0858}, {0xe0860, 0xe086a}, {0xe08a0, 0xe08b4}, + {0xe08b6, 0xe08bd}, {0xe0904, 0xe0939}, {0xe0958, 0xe0961}, {0xe0971, 0xe0980}, + {0xe0985, 0xe098c}, {0xe0993, 0xe09a8}, {0xe09aa, 0xe09b0}, {0xe09b6, 0xe09b9}, + {0xe09df, 0xe09e1}, {0xe0a05, 0xe0a0a}, {0xe0a13, 0xe0a28}, {0xe0a2a, 0xe0a30}, + {0xe0a59, 0xe0a5c}, {0xe0a72, 0xe0a74}, {0xe0a85, 0xe0a8d}, {0xe0a8f, 0xe0a91}, + {0xe0a93, 0xe0aa8}, {0xe0aaa, 0xe0ab0}, {0xe0ab5, 0xe0ab9}, {0xe0b05, 0xe0b0c}, + {0xe0b13, 0xe0b28}, {0xe0b2a, 0xe0b30}, {0xe0b35, 0xe0b39}, {0xe0b5f, 0xe0b61}, + {0xe0b85, 0xe0b8a}, {0xe0b8e, 0xe0b90}, {0xe0b92, 0xe0b95}, {0xe0ba8, 0xe0baa}, + {0xe0bae, 0xe0bb9}, {0xe0c05, 0xe0c0c}, {0xe0c0e, 0xe0c10}, {0xe0c12, 0xe0c28}, + {0xe0c2a, 0xe0c39}, {0xe0c58, 0xe0c5a}, {0xe0c85, 0xe0c8c}, {0xe0c8e, 0xe0c90}, + {0xe0c92, 0xe0ca8}, {0xe0caa, 0xe0cb3}, {0xe0cb5, 0xe0cb9}, {0xe0d05, 0xe0d0c}, + {0xe0d0e, 0xe0d10}, {0xe0d12, 0xe0d3a}, {0xe0d54, 0xe0d56}, {0xe0d5f, 0xe0d61}, + {0xe0d7a, 0xe0d7f}, {0xe0d85, 0xe0d96}, {0xe0d9a, 0xe0db1}, {0xe0db3, 0xe0dbb}, + {0xe0dc0, 0xe0dc6}, {0xe0e01, 0xe0e30}, {0xe0e40, 0xe0e46}, {0xe0e94, 0xe0e97}, + {0xe0e99, 0xe0e9f}, {0xe0ea1, 0xe0ea3}, {0xe0ead, 0xe0eb0}, {0xe0ec0, 0xe0ec4}, + {0xe0edc, 0xe0edf}, {0xe0f40, 0xe0f47}, {0xe0f49, 0xe0f6c}, {0xe0f88, 0xe0f8c}, + {0xe1000, 0xe102a}, {0xe1050, 0xe1055}, {0xe105a, 0xe105d}, {0xe106e, 0xe1070}, + {0xe1075, 0xe1081}, {0xe10a0, 0xe10c5}, {0xe10d0, 0xe10fa}, {0xe10fc, 0xe1248}, + {0xe124a, 0xe124d}, {0xe1250, 0xe1256}, {0xe125a, 0xe125d}, {0xe1260, 0xe1288}, + {0xe128a, 0xe128d}, {0xe1290, 0xe12b0}, {0xe12b2, 0xe12b5}, {0xe12b8, 0xe12be}, + {0xe12c2, 0xe12c5}, {0xe12c8, 0xe12d6}, {0xe12d8, 0xe1310}, {0xe1312, 0xe1315}, + {0xe1318, 0xe135a}, {0xe1380, 0xe138f}, {0xe13a0, 0xe13f5}, {0xe13f8, 0xe13fd}, + {0xe1401, 0xe166c}, {0xe166f, 0xe167f}, {0xe1681, 0xe169a}, {0xe16a0, 0xe16ea}, + {0xe16f1, 0xe16f8}, {0xe1700, 0xe170c}, {0xe170e, 0xe1711}, {0xe1720, 0xe1731}, + {0xe1740, 0xe1751}, {0xe1760, 0xe176c}, {0xe176e, 0xe1770}, {0xe1780, 0xe17b3}, + {0xe1820, 0xe1877}, {0xe1880, 0xe1884}, {0xe1887, 0xe18a8}, {0xe18b0, 0xe18f5}, + {0xe1900, 0xe191e}, {0xe1950, 0xe196d}, {0xe1970, 0xe1974}, {0xe1980, 0xe19ab}, + {0xe19b0, 0xe19c9}, {0xe1a00, 0xe1a16}, {0xe1a20, 0xe1a54}, {0xe1b05, 0xe1b33}, + {0xe1b45, 0xe1b4b}, {0xe1b83, 0xe1ba0}, {0xe1bba, 0xe1be5}, {0xe1c00, 0xe1c23}, + {0xe1c4d, 0xe1c4f}, {0xe1c5a, 0xe1c7d}, {0xe1c80, 0xe1c88}, {0xe1ce9, 0xe1cec}, + {0xe1cee, 0xe1cf1}, {0xe1d00, 0xe1dbf}, {0xe1e00, 0xe1f15}, {0xe1f18, 0xe1f1d}, + {0xe1f20, 0xe1f45}, {0xe1f48, 0xe1f4d}, {0xe1f50, 0xe1f57}, {0xe1f5f, 0xe1f7d}, + {0xe1f80, 0xe1fb4}, {0xe1fb6, 0xe1fbc}, {0xe1fc2, 0xe1fc4}, {0xe1fc6, 0xe1fcc}, + {0xe1fd0, 0xe1fd3}, {0xe1fd6, 0xe1fdb}, {0xe1fe0, 0xe1fec}, {0xe1ff2, 0xe1ff4}, + {0xe1ff6, 0xe1ffc}, {0xe2090, 0xe209c}, {0xe210a, 0xe2113}, {0xe2119, 0xe211d}, + {0xe212a, 0xe212d}, {0xe212f, 0xe2139}, {0xe213c, 0xe213f}, {0xe2145, 0xe2149}, + {0xe2c00, 0xe2c2e}, {0xe2c30, 0xe2c5e}, {0xe2c60, 0xe2ce4}, {0xe2ceb, 0xe2cee}, + {0xe2d00, 0xe2d25}, {0xe2d30, 0xe2d67}, {0xe2d80, 0xe2d96}, {0xe2da0, 0xe2da6}, + {0xe2da8, 0xe2dae}, {0xe2db0, 0xe2db6}, {0xe2db8, 0xe2dbe}, {0xe2dc0, 0xe2dc6}, + {0xe2dc8, 0xe2dce}, {0xe2dd0, 0xe2dd6}, {0xe2dd8, 0xe2dde}, {0xe3031, 0xe3035}, + {0xe3041, 0xe3096}, {0xe309d, 0xe309f}, {0xe30a1, 0xe30fa}, {0xe30fc, 0xe30ff}, + {0xe3105, 0xe312e}, {0xe3131, 0xe318e}, {0xe31a0, 0xe31ba}, {0xe31f0, 0xe31ff}, + {0xe3400, 0xe4db5}, {0xe4e00, 0xe9fea}, {0xea000, 0xea48c}, {0xea4d0, 0xea4fd}, + {0xea500, 0xea60c}, {0xea610, 0xea61f}, {0xea640, 0xea66e}, {0xea67f, 0xea69d}, + {0xea6a0, 0xea6e5}, {0xea717, 0xea71f}, {0xea722, 0xea788}, {0xea78b, 0xea7ae}, + {0xea7b0, 0xea7b7}, {0xea7f7, 0xea801}, {0xea803, 0xea805}, {0xea807, 0xea80a}, + {0xea80c, 0xea822}, {0xea840, 0xea873}, {0xea882, 0xea8b3}, {0xea8f2, 0xea8f7}, + {0xea90a, 0xea925}, {0xea930, 0xea946}, {0xea960, 0xea97c}, {0xea984, 0xea9b2}, + {0xea9e0, 0xea9e4}, {0xea9e6, 0xea9ef}, {0xea9fa, 0xea9fe}, {0xeaa00, 0xeaa28}, + {0xeaa40, 0xeaa42}, {0xeaa44, 0xeaa4b}, {0xeaa60, 0xeaa76}, {0xeaa7e, 0xeaaaf}, + {0xeaab9, 0xeaabd}, {0xeaadb, 0xeaadd}, {0xeaae0, 0xeaaea}, {0xeaaf2, 0xeaaf4}, + {0xeab01, 0xeab06}, {0xeab09, 0xeab0e}, {0xeab11, 0xeab16}, {0xeab20, 0xeab26}, + {0xeab28, 0xeab2e}, {0xeab30, 0xeab5a}, {0xeab5c, 0xeab65}, {0xeab70, 0xeabe2}, + {0xeac00, 0xed7a3}, {0xed7b0, 0xed7c6}, {0xed7cb, 0xed7fb}, {0xef900, 0xefa6d}, + {0xefa70, 0xefad9}, {0xefb00, 0xefb06}, {0xefb13, 0xefb17}, {0xefb1f, 0xefb28}, + {0xefb2a, 0xefb36}, {0xefb38, 0xefb3c}, {0xefb46, 0xefbb1}, {0xefbd3, 0xefd3d}, + {0xefd50, 0xefd8f}, {0xefd92, 0xefdc7}, {0xefdf0, 0xefdfb}, {0xefe70, 0xefe74}, + {0xefe76, 0xefefc}, {0xeff21, 0xeff3a}, {0xeff41, 0xeff5a}, {0xeff66, 0xeffbe}, + {0xeffc2, 0xeffc7}, {0xeffca, 0xeffcf}, {0xeffd2, 0xeffd7}, {0xeffda, 0xeffdc}, + {0xf0041, 0xf005a}, {0xf0061, 0xf007a}, {0xf00c0, 0xf00d6}, {0xf00d8, 0xf00f6}, + {0xf00f8, 0xf02c1}, {0xf02c6, 0xf02d1}, {0xf02e0, 0xf02e4}, {0xf0370, 0xf0374}, + {0xf037a, 0xf037d}, {0xf0388, 0xf038a}, {0xf038e, 0xf03a1}, {0xf03a3, 0xf03f5}, + {0xf03f7, 0xf0481}, {0xf048a, 0xf052f}, {0xf0531, 0xf0556}, {0xf0561, 0xf0587}, + {0xf05d0, 0xf05ea}, {0xf05f0, 0xf05f2}, {0xf0620, 0xf064a}, {0xf0671, 0xf06d3}, + {0xf06fa, 0xf06fc}, {0xf0712, 0xf072f}, {0xf074d, 0xf07a5}, {0xf07ca, 0xf07ea}, + {0xf0800, 0xf0815}, {0xf0840, 0xf0858}, {0xf0860, 0xf086a}, {0xf08a0, 0xf08b4}, + {0xf08b6, 0xf08bd}, {0xf0904, 0xf0939}, {0xf0958, 0xf0961}, {0xf0971, 0xf0980}, + {0xf0985, 0xf098c}, {0xf0993, 0xf09a8}, {0xf09aa, 0xf09b0}, {0xf09b6, 0xf09b9}, + {0xf09df, 0xf09e1}, {0xf0a05, 0xf0a0a}, {0xf0a13, 0xf0a28}, {0xf0a2a, 0xf0a30}, + {0xf0a59, 0xf0a5c}, {0xf0a72, 0xf0a74}, {0xf0a85, 0xf0a8d}, {0xf0a8f, 0xf0a91}, + {0xf0a93, 0xf0aa8}, {0xf0aaa, 0xf0ab0}, {0xf0ab5, 0xf0ab9}, {0xf0b05, 0xf0b0c}, + {0xf0b13, 0xf0b28}, {0xf0b2a, 0xf0b30}, {0xf0b35, 0xf0b39}, {0xf0b5f, 0xf0b61}, + {0xf0b85, 0xf0b8a}, {0xf0b8e, 0xf0b90}, {0xf0b92, 0xf0b95}, {0xf0ba8, 0xf0baa}, + {0xf0bae, 0xf0bb9}, {0xf0c05, 0xf0c0c}, {0xf0c0e, 0xf0c10}, {0xf0c12, 0xf0c28}, + {0xf0c2a, 0xf0c39}, {0xf0c58, 0xf0c5a}, {0xf0c85, 0xf0c8c}, {0xf0c8e, 0xf0c90}, + {0xf0c92, 0xf0ca8}, {0xf0caa, 0xf0cb3}, {0xf0cb5, 0xf0cb9}, {0xf0d05, 0xf0d0c}, + {0xf0d0e, 0xf0d10}, {0xf0d12, 0xf0d3a}, {0xf0d54, 0xf0d56}, {0xf0d5f, 0xf0d61}, + {0xf0d7a, 0xf0d7f}, {0xf0d85, 0xf0d96}, {0xf0d9a, 0xf0db1}, {0xf0db3, 0xf0dbb}, + {0xf0dc0, 0xf0dc6}, {0xf0e01, 0xf0e30}, {0xf0e40, 0xf0e46}, {0xf0e94, 0xf0e97}, + {0xf0e99, 0xf0e9f}, {0xf0ea1, 0xf0ea3}, {0xf0ead, 0xf0eb0}, {0xf0ec0, 0xf0ec4}, + {0xf0edc, 0xf0edf}, {0xf0f40, 0xf0f47}, {0xf0f49, 0xf0f6c}, {0xf0f88, 0xf0f8c}, + {0xf1000, 0xf102a}, {0xf1050, 0xf1055}, {0xf105a, 0xf105d}, {0xf106e, 0xf1070}, + {0xf1075, 0xf1081}, {0xf10a0, 0xf10c5}, {0xf10d0, 0xf10fa}, {0xf10fc, 0xf1248}, + {0xf124a, 0xf124d}, {0xf1250, 0xf1256}, {0xf125a, 0xf125d}, {0xf1260, 0xf1288}, + {0xf128a, 0xf128d}, {0xf1290, 0xf12b0}, {0xf12b2, 0xf12b5}, {0xf12b8, 0xf12be}, + {0xf12c2, 0xf12c5}, {0xf12c8, 0xf12d6}, {0xf12d8, 0xf1310}, {0xf1312, 0xf1315}, + {0xf1318, 0xf135a}, {0xf1380, 0xf138f}, {0xf13a0, 0xf13f5}, {0xf13f8, 0xf13fd}, + {0xf1401, 0xf166c}, {0xf166f, 0xf167f}, {0xf1681, 0xf169a}, {0xf16a0, 0xf16ea}, + {0xf16f1, 0xf16f8}, {0xf1700, 0xf170c}, {0xf170e, 0xf1711}, {0xf1720, 0xf1731}, + {0xf1740, 0xf1751}, {0xf1760, 0xf176c}, {0xf176e, 0xf1770}, {0xf1780, 0xf17b3}, + {0xf1820, 0xf1877}, {0xf1880, 0xf1884}, {0xf1887, 0xf18a8}, {0xf18b0, 0xf18f5}, + {0xf1900, 0xf191e}, {0xf1950, 0xf196d}, {0xf1970, 0xf1974}, {0xf1980, 0xf19ab}, + {0xf19b0, 0xf19c9}, {0xf1a00, 0xf1a16}, {0xf1a20, 0xf1a54}, {0xf1b05, 0xf1b33}, + {0xf1b45, 0xf1b4b}, {0xf1b83, 0xf1ba0}, {0xf1bba, 0xf1be5}, {0xf1c00, 0xf1c23}, + {0xf1c4d, 0xf1c4f}, {0xf1c5a, 0xf1c7d}, {0xf1c80, 0xf1c88}, {0xf1ce9, 0xf1cec}, + {0xf1cee, 0xf1cf1}, {0xf1d00, 0xf1dbf}, {0xf1e00, 0xf1f15}, {0xf1f18, 0xf1f1d}, + {0xf1f20, 0xf1f45}, {0xf1f48, 0xf1f4d}, {0xf1f50, 0xf1f57}, {0xf1f5f, 0xf1f7d}, + {0xf1f80, 0xf1fb4}, {0xf1fb6, 0xf1fbc}, {0xf1fc2, 0xf1fc4}, {0xf1fc6, 0xf1fcc}, + {0xf1fd0, 0xf1fd3}, {0xf1fd6, 0xf1fdb}, {0xf1fe0, 0xf1fec}, {0xf1ff2, 0xf1ff4}, + {0xf1ff6, 0xf1ffc}, {0xf2090, 0xf209c}, {0xf210a, 0xf2113}, {0xf2119, 0xf211d}, + {0xf212a, 0xf212d}, {0xf212f, 0xf2139}, {0xf213c, 0xf213f}, {0xf2145, 0xf2149}, + {0xf2c00, 0xf2c2e}, {0xf2c30, 0xf2c5e}, {0xf2c60, 0xf2ce4}, {0xf2ceb, 0xf2cee}, + {0xf2d00, 0xf2d25}, {0xf2d30, 0xf2d67}, {0xf2d80, 0xf2d96}, {0xf2da0, 0xf2da6}, + {0xf2da8, 0xf2dae}, {0xf2db0, 0xf2db6}, {0xf2db8, 0xf2dbe}, {0xf2dc0, 0xf2dc6}, + {0xf2dc8, 0xf2dce}, {0xf2dd0, 0xf2dd6}, {0xf2dd8, 0xf2dde}, {0xf3031, 0xf3035}, + {0xf3041, 0xf3096}, {0xf309d, 0xf309f}, {0xf30a1, 0xf30fa}, {0xf30fc, 0xf30ff}, + {0xf3105, 0xf312e}, {0xf3131, 0xf318e}, {0xf31a0, 0xf31ba}, {0xf31f0, 0xf31ff}, + {0xf3400, 0xf4db5}, {0xf4e00, 0xf9fea}, {0xfa000, 0xfa48c}, {0xfa4d0, 0xfa4fd}, + {0xfa500, 0xfa60c}, {0xfa610, 0xfa61f}, {0xfa640, 0xfa66e}, {0xfa67f, 0xfa69d}, + {0xfa6a0, 0xfa6e5}, {0xfa717, 0xfa71f}, {0xfa722, 0xfa788}, {0xfa78b, 0xfa7ae}, + {0xfa7b0, 0xfa7b7}, {0xfa7f7, 0xfa801}, {0xfa803, 0xfa805}, {0xfa807, 0xfa80a}, + {0xfa80c, 0xfa822}, {0xfa840, 0xfa873}, {0xfa882, 0xfa8b3}, {0xfa8f2, 0xfa8f7}, + {0xfa90a, 0xfa925}, {0xfa930, 0xfa946}, {0xfa960, 0xfa97c}, {0xfa984, 0xfa9b2}, + {0xfa9e0, 0xfa9e4}, {0xfa9e6, 0xfa9ef}, {0xfa9fa, 0xfa9fe}, {0xfaa00, 0xfaa28}, + {0xfaa40, 0xfaa42}, {0xfaa44, 0xfaa4b}, {0xfaa60, 0xfaa76}, {0xfaa7e, 0xfaaaf}, + {0xfaab9, 0xfaabd}, {0xfaadb, 0xfaadd}, {0xfaae0, 0xfaaea}, {0xfaaf2, 0xfaaf4}, + {0xfab01, 0xfab06}, {0xfab09, 0xfab0e}, {0xfab11, 0xfab16}, {0xfab20, 0xfab26}, + {0xfab28, 0xfab2e}, {0xfab30, 0xfab5a}, {0xfab5c, 0xfab65}, {0xfab70, 0xfabe2}, + {0xfac00, 0xfd7a3}, {0xfd7b0, 0xfd7c6}, {0xfd7cb, 0xfd7fb}, {0xff900, 0xffa6d}, + {0xffa70, 0xffad9}, {0xffb00, 0xffb06}, {0xffb13, 0xffb17}, {0xffb1f, 0xffb28}, + {0xffb2a, 0xffb36}, {0xffb38, 0xffb3c}, {0xffb46, 0xffbb1}, {0xffbd3, 0xffd3d}, + {0xffd50, 0xffd8f}, {0xffd92, 0xffdc7}, {0xffdf0, 0xffdfb}, {0xffe70, 0xffe74}, + {0xffe76, 0xffefc}, {0xfff21, 0xfff3a}, {0xfff41, 0xfff5a}, {0xfff66, 0xfffbe}, + {0xfffc2, 0xfffc7}, {0xfffca, 0xfffcf}, {0xfffd2, 0xfffd7}, {0xfffda, 0xfffdc}, + {0x100041, 0x10005a}, {0x100061, 0x10007a}, {0x1000c0, 0x1000d6}, {0x1000d8, 0x1000f6}, + {0x1000f8, 0x1002c1}, {0x1002c6, 0x1002d1}, {0x1002e0, 0x1002e4}, {0x100370, 0x100374}, + {0x10037a, 0x10037d}, {0x100388, 0x10038a}, {0x10038e, 0x1003a1}, {0x1003a3, 0x1003f5}, + {0x1003f7, 0x100481}, {0x10048a, 0x10052f}, {0x100531, 0x100556}, {0x100561, 0x100587}, + {0x1005d0, 0x1005ea}, {0x1005f0, 0x1005f2}, {0x100620, 0x10064a}, {0x100671, 0x1006d3}, + {0x1006fa, 0x1006fc}, {0x100712, 0x10072f}, {0x10074d, 0x1007a5}, {0x1007ca, 0x1007ea}, + {0x100800, 0x100815}, {0x100840, 0x100858}, {0x100860, 0x10086a}, {0x1008a0, 0x1008b4}, + {0x1008b6, 0x1008bd}, {0x100904, 0x100939}, {0x100958, 0x100961}, {0x100971, 0x100980}, + {0x100985, 0x10098c}, {0x100993, 0x1009a8}, {0x1009aa, 0x1009b0}, {0x1009b6, 0x1009b9}, + {0x1009df, 0x1009e1}, {0x100a05, 0x100a0a}, {0x100a13, 0x100a28}, {0x100a2a, 0x100a30}, + {0x100a59, 0x100a5c}, {0x100a72, 0x100a74}, {0x100a85, 0x100a8d}, {0x100a8f, 0x100a91}, + {0x100a93, 0x100aa8}, {0x100aaa, 0x100ab0}, {0x100ab5, 0x100ab9}, {0x100b05, 0x100b0c}, + {0x100b13, 0x100b28}, {0x100b2a, 0x100b30}, {0x100b35, 0x100b39}, {0x100b5f, 0x100b61}, + {0x100b85, 0x100b8a}, {0x100b8e, 0x100b90}, {0x100b92, 0x100b95}, {0x100ba8, 0x100baa}, + {0x100bae, 0x100bb9}, {0x100c05, 0x100c0c}, {0x100c0e, 0x100c10}, {0x100c12, 0x100c28}, + {0x100c2a, 0x100c39}, {0x100c58, 0x100c5a}, {0x100c85, 0x100c8c}, {0x100c8e, 0x100c90}, + {0x100c92, 0x100ca8}, {0x100caa, 0x100cb3}, {0x100cb5, 0x100cb9}, {0x100d05, 0x100d0c}, + {0x100d0e, 0x100d10}, {0x100d12, 0x100d3a}, {0x100d54, 0x100d56}, {0x100d5f, 0x100d61}, + {0x100d7a, 0x100d7f}, {0x100d85, 0x100d96}, {0x100d9a, 0x100db1}, {0x100db3, 0x100dbb}, + {0x100dc0, 0x100dc6}, {0x100e01, 0x100e30}, {0x100e40, 0x100e46}, {0x100e94, 0x100e97}, + {0x100e99, 0x100e9f}, {0x100ea1, 0x100ea3}, {0x100ead, 0x100eb0}, {0x100ec0, 0x100ec4}, + {0x100edc, 0x100edf}, {0x100f40, 0x100f47}, {0x100f49, 0x100f6c}, {0x100f88, 0x100f8c}, + {0x101000, 0x10102a}, {0x101050, 0x101055}, {0x10105a, 0x10105d}, {0x10106e, 0x101070}, + {0x101075, 0x101081}, {0x1010a0, 0x1010c5}, {0x1010d0, 0x1010fa}, {0x1010fc, 0x101248}, + {0x10124a, 0x10124d}, {0x101250, 0x101256}, {0x10125a, 0x10125d}, {0x101260, 0x101288}, + {0x10128a, 0x10128d}, {0x101290, 0x1012b0}, {0x1012b2, 0x1012b5}, {0x1012b8, 0x1012be}, + {0x1012c2, 0x1012c5}, {0x1012c8, 0x1012d6}, {0x1012d8, 0x101310}, {0x101312, 0x101315}, + {0x101318, 0x10135a}, {0x101380, 0x10138f}, {0x1013a0, 0x1013f5}, {0x1013f8, 0x1013fd}, + {0x101401, 0x10166c}, {0x10166f, 0x10167f}, {0x101681, 0x10169a}, {0x1016a0, 0x1016ea}, + {0x1016f1, 0x1016f8}, {0x101700, 0x10170c}, {0x10170e, 0x101711}, {0x101720, 0x101731}, + {0x101740, 0x101751}, {0x101760, 0x10176c}, {0x10176e, 0x101770}, {0x101780, 0x1017b3}, + {0x101820, 0x101877}, {0x101880, 0x101884}, {0x101887, 0x1018a8}, {0x1018b0, 0x1018f5}, + {0x101900, 0x10191e}, {0x101950, 0x10196d}, {0x101970, 0x101974}, {0x101980, 0x1019ab}, + {0x1019b0, 0x1019c9}, {0x101a00, 0x101a16}, {0x101a20, 0x101a54}, {0x101b05, 0x101b33}, + {0x101b45, 0x101b4b}, {0x101b83, 0x101ba0}, {0x101bba, 0x101be5}, {0x101c00, 0x101c23}, + {0x101c4d, 0x101c4f}, {0x101c5a, 0x101c7d}, {0x101c80, 0x101c88}, {0x101ce9, 0x101cec}, + {0x101cee, 0x101cf1}, {0x101d00, 0x101dbf}, {0x101e00, 0x101f15}, {0x101f18, 0x101f1d}, + {0x101f20, 0x101f45}, {0x101f48, 0x101f4d}, {0x101f50, 0x101f57}, {0x101f5f, 0x101f7d}, + {0x101f80, 0x101fb4}, {0x101fb6, 0x101fbc}, {0x101fc2, 0x101fc4}, {0x101fc6, 0x101fcc}, + {0x101fd0, 0x101fd3}, {0x101fd6, 0x101fdb}, {0x101fe0, 0x101fec}, {0x101ff2, 0x101ff4}, + {0x101ff6, 0x101ffc}, {0x102090, 0x10209c}, {0x10210a, 0x102113}, {0x102119, 0x10211d}, + {0x10212a, 0x10212d}, {0x10212f, 0x102139}, {0x10213c, 0x10213f}, {0x102145, 0x102149}, + {0x102c00, 0x102c2e}, {0x102c30, 0x102c5e}, {0x102c60, 0x102ce4}, {0x102ceb, 0x102cee}, + {0x102d00, 0x102d25}, {0x102d30, 0x102d67}, {0x102d80, 0x102d96}, {0x102da0, 0x102da6}, + {0x102da8, 0x102dae}, {0x102db0, 0x102db6}, {0x102db8, 0x102dbe}, {0x102dc0, 0x102dc6}, + {0x102dc8, 0x102dce}, {0x102dd0, 0x102dd6}, {0x102dd8, 0x102dde}, {0x103031, 0x103035}, + {0x103041, 0x103096}, {0x10309d, 0x10309f}, {0x1030a1, 0x1030fa}, {0x1030fc, 0x1030ff}, + {0x103105, 0x10312e}, {0x103131, 0x10318e}, {0x1031a0, 0x1031ba}, {0x1031f0, 0x1031ff}, + {0x103400, 0x104db5}, {0x104e00, 0x109fea}, {0x10a000, 0x10a48c}, {0x10a4d0, 0x10a4fd}, + {0x10a500, 0x10a60c}, {0x10a610, 0x10a61f}, {0x10a640, 0x10a66e}, {0x10a67f, 0x10a69d}, + {0x10a6a0, 0x10a6e5}, {0x10a717, 0x10a71f}, {0x10a722, 0x10a788}, {0x10a78b, 0x10a7ae}, + {0x10a7b0, 0x10a7b7}, {0x10a7f7, 0x10a801}, {0x10a803, 0x10a805}, {0x10a807, 0x10a80a}, + {0x10a80c, 0x10a822}, {0x10a840, 0x10a873}, {0x10a882, 0x10a8b3}, {0x10a8f2, 0x10a8f7}, + {0x10a90a, 0x10a925}, {0x10a930, 0x10a946}, {0x10a960, 0x10a97c}, {0x10a984, 0x10a9b2}, + {0x10a9e0, 0x10a9e4}, {0x10a9e6, 0x10a9ef}, {0x10a9fa, 0x10a9fe}, {0x10aa00, 0x10aa28}, + {0x10aa40, 0x10aa42}, {0x10aa44, 0x10aa4b}, {0x10aa60, 0x10aa76}, {0x10aa7e, 0x10aaaf}, + {0x10aab9, 0x10aabd}, {0x10aadb, 0x10aadd}, {0x10aae0, 0x10aaea}, {0x10aaf2, 0x10aaf4}, + {0x10ab01, 0x10ab06}, {0x10ab09, 0x10ab0e}, {0x10ab11, 0x10ab16}, {0x10ab20, 0x10ab26}, + {0x10ab28, 0x10ab2e}, {0x10ab30, 0x10ab5a}, {0x10ab5c, 0x10ab65}, {0x10ab70, 0x10abe2}, + {0x10ac00, 0x10d7a3}, {0x10d7b0, 0x10d7c6}, {0x10d7cb, 0x10d7fb}, {0x10f900, 0x10fa6d}, + {0x10fa70, 0x10fad9}, {0x10fb00, 0x10fb06}, {0x10fb13, 0x10fb17}, {0x10fb1f, 0x10fb28}, + {0x10fb2a, 0x10fb36}, {0x10fb38, 0x10fb3c}, {0x10fb46, 0x10fbb1}, {0x10fbd3, 0x10fd3d}, + {0x10fd50, 0x10fd8f}, {0x10fd92, 0x10fdc7}, {0x10fdf0, 0x10fdfb}, {0x10fe70, 0x10fe74}, + {0x10fe76, 0x10fefc}, {0x10ff21, 0x10ff3a}, {0x10ff41, 0x10ff5a}, {0x10ff66, 0x10ffbe}, + {0x10ffc2, 0x10ffc7}, {0x10ffca, 0x10ffcf}, {0x10ffd2, 0x10ffd7}, {0x10ffda, 0x10ffdc} #endif }; @@ -250,28 +1250,309 @@ static const chr alphaCharTable[] = { 0x38c, 0x559, 0x66e, 0x66f, 0x6d5, 0x6e5, 0x6e6, 0x6ee, 0x6ef, 0x6ff, 0x710, 0x7b1, 0x7f4, 0x7f5, 0x7fa, 0x81a, 0x824, 0x828, 0x93d, 0x950, 0x98f, 0x990, 0x9b2, 0x9bd, 0x9ce, 0x9dc, 0x9dd, - 0x9f0, 0x9f1, 0xa0f, 0xa10, 0xa32, 0xa33, 0xa35, 0xa36, 0xa38, - 0xa39, 0xa5e, 0xab2, 0xab3, 0xabd, 0xad0, 0xae0, 0xae1, 0xaf9, - 0xb0f, 0xb10, 0xb32, 0xb33, 0xb3d, 0xb5c, 0xb5d, 0xb71, 0xb83, - 0xb99, 0xb9a, 0xb9c, 0xb9e, 0xb9f, 0xba3, 0xba4, 0xbd0, 0xc3d, - 0xc60, 0xc61, 0xc80, 0xcbd, 0xcde, 0xce0, 0xce1, 0xcf1, 0xcf2, - 0xd3d, 0xd4e, 0xdbd, 0xe32, 0xe33, 0xe81, 0xe82, 0xe84, 0xe87, - 0xe88, 0xe8a, 0xe8d, 0xea5, 0xea7, 0xeaa, 0xeab, 0xeb2, 0xeb3, - 0xebd, 0xec6, 0xf00, 0x103f, 0x1061, 0x1065, 0x1066, 0x108e, 0x10c7, - 0x10cd, 0x1258, 0x12c0, 0x17d7, 0x17dc, 0x18aa, 0x1aa7, 0x1bae, 0x1baf, - 0x1cf5, 0x1cf6, 0x1f59, 0x1f5b, 0x1f5d, 0x1fbe, 0x2071, 0x207f, 0x2102, - 0x2107, 0x2115, 0x2124, 0x2126, 0x2128, 0x214e, 0x2183, 0x2184, 0x2cf2, - 0x2cf3, 0x2d27, 0x2d2d, 0x2d6f, 0x2e2f, 0x3005, 0x3006, 0x303b, 0x303c, - 0xa62a, 0xa62b, 0xa8fb, 0xa8fd, 0xa9cf, 0xaa7a, 0xaab1, 0xaab5, 0xaab6, - 0xaac0, 0xaac2, 0xfb1d, 0xfb3e, 0xfb40, 0xfb41, 0xfb43, 0xfb44 + 0x9f0, 0x9f1, 0x9fc, 0xa0f, 0xa10, 0xa32, 0xa33, 0xa35, 0xa36, + 0xa38, 0xa39, 0xa5e, 0xab2, 0xab3, 0xabd, 0xad0, 0xae0, 0xae1, + 0xaf9, 0xb0f, 0xb10, 0xb32, 0xb33, 0xb3d, 0xb5c, 0xb5d, 0xb71, + 0xb83, 0xb99, 0xb9a, 0xb9c, 0xb9e, 0xb9f, 0xba3, 0xba4, 0xbd0, + 0xc3d, 0xc60, 0xc61, 0xc80, 0xcbd, 0xcde, 0xce0, 0xce1, 0xcf1, + 0xcf2, 0xd3d, 0xd4e, 0xdbd, 0xe32, 0xe33, 0xe81, 0xe82, 0xe84, + 0xe87, 0xe88, 0xe8a, 0xe8d, 0xea5, 0xea7, 0xeaa, 0xeab, 0xeb2, + 0xeb3, 0xebd, 0xec6, 0xf00, 0x103f, 0x1061, 0x1065, 0x1066, 0x108e, + 0x10c7, 0x10cd, 0x1258, 0x12c0, 0x17d7, 0x17dc, 0x18aa, 0x1aa7, 0x1bae, + 0x1baf, 0x1cf5, 0x1cf6, 0x1f59, 0x1f5b, 0x1f5d, 0x1fbe, 0x2071, 0x207f, + 0x2102, 0x2107, 0x2115, 0x2124, 0x2126, 0x2128, 0x214e, 0x2183, 0x2184, + 0x2cf2, 0x2cf3, 0x2d27, 0x2d2d, 0x2d6f, 0x2e2f, 0x3005, 0x3006, 0x303b, + 0x303c, 0xa62a, 0xa62b, 0xa8fb, 0xa8fd, 0xa9cf, 0xaa7a, 0xaab1, 0xaab5, + 0xaab6, 0xaac0, 0xaac2, 0xfb1d, 0xfb3e, 0xfb40, 0xfb41, 0xfb43, 0xfb44 #if TCL_UTF_MAX > 4 - ,0x1003c, 0x1003d, 0x10808, 0x10837, 0x10838, 0x1083c, 0x108f4, 0x108f5, 0x109be, - 0x109bf, 0x10a00, 0x11176, 0x111da, 0x111dc, 0x11288, 0x1130f, 0x11310, 0x11332, - 0x11333, 0x1133d, 0x11350, 0x114c4, 0x114c5, 0x114c7, 0x11644, 0x118ff, 0x11c40, - 0x16f50, 0x16fe0, 0x1b000, 0x1b001, 0x1d49e, 0x1d49f, 0x1d4a2, 0x1d4a5, 0x1d4a6, - 0x1d4bb, 0x1d546, 0x1ee21, 0x1ee22, 0x1ee24, 0x1ee27, 0x1ee39, 0x1ee3b, 0x1ee42, - 0x1ee47, 0x1ee49, 0x1ee4b, 0x1ee51, 0x1ee52, 0x1ee54, 0x1ee57, 0x1ee59, 0x1ee5b, - 0x1ee5d, 0x1ee5f, 0x1ee61, 0x1ee62, 0x1ee64, 0x1ee7e + ,0x100aa, 0x100b5, 0x100ba, 0x102ec, 0x102ee, 0x10376, 0x10377, 0x1037f, 0x10386, + 0x1038c, 0x10559, 0x1066e, 0x1066f, 0x106d5, 0x106e5, 0x106e6, 0x106ee, 0x106ef, + 0x106ff, 0x10710, 0x107b1, 0x107f4, 0x107f5, 0x107fa, 0x1081a, 0x10824, 0x10828, + 0x1093d, 0x10950, 0x1098f, 0x10990, 0x109b2, 0x109bd, 0x109ce, 0x109dc, 0x109dd, + 0x109f0, 0x109f1, 0x109fc, 0x10a0f, 0x10a10, 0x10a32, 0x10a33, 0x10a35, 0x10a36, + 0x10a38, 0x10a39, 0x10a5e, 0x10ab2, 0x10ab3, 0x10abd, 0x10ad0, 0x10ae0, 0x10ae1, + 0x10af9, 0x10b0f, 0x10b10, 0x10b32, 0x10b33, 0x10b3d, 0x10b5c, 0x10b5d, 0x10b71, + 0x10b83, 0x10b99, 0x10b9a, 0x10b9c, 0x10b9e, 0x10b9f, 0x10ba3, 0x10ba4, 0x10bd0, + 0x10c3d, 0x10c60, 0x10c61, 0x10c80, 0x10cbd, 0x10cde, 0x10ce0, 0x10ce1, 0x10cf1, + 0x10cf2, 0x10d3d, 0x10d4e, 0x10dbd, 0x10e32, 0x10e33, 0x10e81, 0x10e82, 0x10e84, + 0x10e87, 0x10e88, 0x10e8a, 0x10e8d, 0x10ea5, 0x10ea7, 0x10eaa, 0x10eab, 0x10eb2, + 0x10eb3, 0x10ebd, 0x10ec6, 0x10f00, 0x1103f, 0x11061, 0x11065, 0x11066, 0x1108e, + 0x110c7, 0x110cd, 0x11258, 0x112c0, 0x117d7, 0x117dc, 0x118aa, 0x11aa7, 0x11bae, + 0x11baf, 0x11cf5, 0x11cf6, 0x11f59, 0x11f5b, 0x11f5d, 0x11fbe, 0x12071, 0x1207f, + 0x12102, 0x12107, 0x12115, 0x12124, 0x12126, 0x12128, 0x1214e, 0x12183, 0x12184, + 0x12cf2, 0x12cf3, 0x12d27, 0x12d2d, 0x12d6f, 0x12e2f, 0x13005, 0x13006, 0x1303b, + 0x1303c, 0x1a62a, 0x1a62b, 0x1a8fb, 0x1a8fd, 0x1a9cf, 0x1aa7a, 0x1aab1, 0x1aab5, + 0x1aab6, 0x1aac0, 0x1aac2, 0x1fb1d, 0x1fb3e, 0x1fb40, 0x1fb41, 0x1fb43, 0x1fb44, + 0x200aa, 0x200b5, 0x200ba, 0x202ec, 0x202ee, 0x20376, 0x20377, 0x2037f, 0x20386, + 0x2038c, 0x20559, 0x2066e, 0x2066f, 0x206d5, 0x206e5, 0x206e6, 0x206ee, 0x206ef, + 0x206ff, 0x20710, 0x207b1, 0x207f4, 0x207f5, 0x207fa, 0x2081a, 0x20824, 0x20828, + 0x2093d, 0x20950, 0x2098f, 0x20990, 0x209b2, 0x209bd, 0x209ce, 0x209dc, 0x209dd, + 0x209f0, 0x209f1, 0x209fc, 0x20a0f, 0x20a10, 0x20a32, 0x20a33, 0x20a35, 0x20a36, + 0x20a38, 0x20a39, 0x20a5e, 0x20ab2, 0x20ab3, 0x20abd, 0x20ad0, 0x20ae0, 0x20ae1, + 0x20af9, 0x20b0f, 0x20b10, 0x20b32, 0x20b33, 0x20b3d, 0x20b5c, 0x20b5d, 0x20b71, + 0x20b83, 0x20b99, 0x20b9a, 0x20b9c, 0x20b9e, 0x20b9f, 0x20ba3, 0x20ba4, 0x20bd0, + 0x20c3d, 0x20c60, 0x20c61, 0x20c80, 0x20cbd, 0x20cde, 0x20ce0, 0x20ce1, 0x20cf1, + 0x20cf2, 0x20d3d, 0x20d4e, 0x20dbd, 0x20e32, 0x20e33, 0x20e81, 0x20e82, 0x20e84, + 0x20e87, 0x20e88, 0x20e8a, 0x20e8d, 0x20ea5, 0x20ea7, 0x20eaa, 0x20eab, 0x20eb2, + 0x20eb3, 0x20ebd, 0x20ec6, 0x20f00, 0x2103f, 0x21061, 0x21065, 0x21066, 0x2108e, + 0x210c7, 0x210cd, 0x21258, 0x212c0, 0x217d7, 0x217dc, 0x218aa, 0x21aa7, 0x21bae, + 0x21baf, 0x21cf5, 0x21cf6, 0x21f59, 0x21f5b, 0x21f5d, 0x21fbe, 0x22071, 0x2207f, + 0x22102, 0x22107, 0x22115, 0x22124, 0x22126, 0x22128, 0x2214e, 0x22183, 0x22184, + 0x22cf2, 0x22cf3, 0x22d27, 0x22d2d, 0x22d6f, 0x22e2f, 0x23005, 0x23006, 0x2303b, + 0x2303c, 0x2a62a, 0x2a62b, 0x2a8fb, 0x2a8fd, 0x2a9cf, 0x2aa7a, 0x2aab1, 0x2aab5, + 0x2aab6, 0x2aac0, 0x2aac2, 0x2fb1d, 0x2fb3e, 0x2fb40, 0x2fb41, 0x2fb43, 0x2fb44, + 0x300aa, 0x300b5, 0x300ba, 0x302ec, 0x302ee, 0x30376, 0x30377, 0x3037f, 0x30386, + 0x3038c, 0x30559, 0x3066e, 0x3066f, 0x306d5, 0x306e5, 0x306e6, 0x306ee, 0x306ef, + 0x306ff, 0x30710, 0x307b1, 0x307f4, 0x307f5, 0x307fa, 0x3081a, 0x30824, 0x30828, + 0x3093d, 0x30950, 0x3098f, 0x30990, 0x309b2, 0x309bd, 0x309ce, 0x309dc, 0x309dd, + 0x309f0, 0x309f1, 0x309fc, 0x30a0f, 0x30a10, 0x30a32, 0x30a33, 0x30a35, 0x30a36, + 0x30a38, 0x30a39, 0x30a5e, 0x30ab2, 0x30ab3, 0x30abd, 0x30ad0, 0x30ae0, 0x30ae1, + 0x30af9, 0x30b0f, 0x30b10, 0x30b32, 0x30b33, 0x30b3d, 0x30b5c, 0x30b5d, 0x30b71, + 0x30b83, 0x30b99, 0x30b9a, 0x30b9c, 0x30b9e, 0x30b9f, 0x30ba3, 0x30ba4, 0x30bd0, + 0x30c3d, 0x30c60, 0x30c61, 0x30c80, 0x30cbd, 0x30cde, 0x30ce0, 0x30ce1, 0x30cf1, + 0x30cf2, 0x30d3d, 0x30d4e, 0x30dbd, 0x30e32, 0x30e33, 0x30e81, 0x30e82, 0x30e84, + 0x30e87, 0x30e88, 0x30e8a, 0x30e8d, 0x30ea5, 0x30ea7, 0x30eaa, 0x30eab, 0x30eb2, + 0x30eb3, 0x30ebd, 0x30ec6, 0x30f00, 0x3103f, 0x31061, 0x31065, 0x31066, 0x3108e, + 0x310c7, 0x310cd, 0x31258, 0x312c0, 0x317d7, 0x317dc, 0x318aa, 0x31aa7, 0x31bae, + 0x31baf, 0x31cf5, 0x31cf6, 0x31f59, 0x31f5b, 0x31f5d, 0x31fbe, 0x32071, 0x3207f, + 0x32102, 0x32107, 0x32115, 0x32124, 0x32126, 0x32128, 0x3214e, 0x32183, 0x32184, + 0x32cf2, 0x32cf3, 0x32d27, 0x32d2d, 0x32d6f, 0x32e2f, 0x33005, 0x33006, 0x3303b, + 0x3303c, 0x3a62a, 0x3a62b, 0x3a8fb, 0x3a8fd, 0x3a9cf, 0x3aa7a, 0x3aab1, 0x3aab5, + 0x3aab6, 0x3aac0, 0x3aac2, 0x3fb1d, 0x3fb3e, 0x3fb40, 0x3fb41, 0x3fb43, 0x3fb44, + 0x400aa, 0x400b5, 0x400ba, 0x402ec, 0x402ee, 0x40376, 0x40377, 0x4037f, 0x40386, + 0x4038c, 0x40559, 0x4066e, 0x4066f, 0x406d5, 0x406e5, 0x406e6, 0x406ee, 0x406ef, + 0x406ff, 0x40710, 0x407b1, 0x407f4, 0x407f5, 0x407fa, 0x4081a, 0x40824, 0x40828, + 0x4093d, 0x40950, 0x4098f, 0x40990, 0x409b2, 0x409bd, 0x409ce, 0x409dc, 0x409dd, + 0x409f0, 0x409f1, 0x409fc, 0x40a0f, 0x40a10, 0x40a32, 0x40a33, 0x40a35, 0x40a36, + 0x40a38, 0x40a39, 0x40a5e, 0x40ab2, 0x40ab3, 0x40abd, 0x40ad0, 0x40ae0, 0x40ae1, + 0x40af9, 0x40b0f, 0x40b10, 0x40b32, 0x40b33, 0x40b3d, 0x40b5c, 0x40b5d, 0x40b71, + 0x40b83, 0x40b99, 0x40b9a, 0x40b9c, 0x40b9e, 0x40b9f, 0x40ba3, 0x40ba4, 0x40bd0, + 0x40c3d, 0x40c60, 0x40c61, 0x40c80, 0x40cbd, 0x40cde, 0x40ce0, 0x40ce1, 0x40cf1, + 0x40cf2, 0x40d3d, 0x40d4e, 0x40dbd, 0x40e32, 0x40e33, 0x40e81, 0x40e82, 0x40e84, + 0x40e87, 0x40e88, 0x40e8a, 0x40e8d, 0x40ea5, 0x40ea7, 0x40eaa, 0x40eab, 0x40eb2, + 0x40eb3, 0x40ebd, 0x40ec6, 0x40f00, 0x4103f, 0x41061, 0x41065, 0x41066, 0x4108e, + 0x410c7, 0x410cd, 0x41258, 0x412c0, 0x417d7, 0x417dc, 0x418aa, 0x41aa7, 0x41bae, + 0x41baf, 0x41cf5, 0x41cf6, 0x41f59, 0x41f5b, 0x41f5d, 0x41fbe, 0x42071, 0x4207f, + 0x42102, 0x42107, 0x42115, 0x42124, 0x42126, 0x42128, 0x4214e, 0x42183, 0x42184, + 0x42cf2, 0x42cf3, 0x42d27, 0x42d2d, 0x42d6f, 0x42e2f, 0x43005, 0x43006, 0x4303b, + 0x4303c, 0x4a62a, 0x4a62b, 0x4a8fb, 0x4a8fd, 0x4a9cf, 0x4aa7a, 0x4aab1, 0x4aab5, + 0x4aab6, 0x4aac0, 0x4aac2, 0x4fb1d, 0x4fb3e, 0x4fb40, 0x4fb41, 0x4fb43, 0x4fb44, + 0x500aa, 0x500b5, 0x500ba, 0x502ec, 0x502ee, 0x50376, 0x50377, 0x5037f, 0x50386, + 0x5038c, 0x50559, 0x5066e, 0x5066f, 0x506d5, 0x506e5, 0x506e6, 0x506ee, 0x506ef, + 0x506ff, 0x50710, 0x507b1, 0x507f4, 0x507f5, 0x507fa, 0x5081a, 0x50824, 0x50828, + 0x5093d, 0x50950, 0x5098f, 0x50990, 0x509b2, 0x509bd, 0x509ce, 0x509dc, 0x509dd, + 0x509f0, 0x509f1, 0x509fc, 0x50a0f, 0x50a10, 0x50a32, 0x50a33, 0x50a35, 0x50a36, + 0x50a38, 0x50a39, 0x50a5e, 0x50ab2, 0x50ab3, 0x50abd, 0x50ad0, 0x50ae0, 0x50ae1, + 0x50af9, 0x50b0f, 0x50b10, 0x50b32, 0x50b33, 0x50b3d, 0x50b5c, 0x50b5d, 0x50b71, + 0x50b83, 0x50b99, 0x50b9a, 0x50b9c, 0x50b9e, 0x50b9f, 0x50ba3, 0x50ba4, 0x50bd0, + 0x50c3d, 0x50c60, 0x50c61, 0x50c80, 0x50cbd, 0x50cde, 0x50ce0, 0x50ce1, 0x50cf1, + 0x50cf2, 0x50d3d, 0x50d4e, 0x50dbd, 0x50e32, 0x50e33, 0x50e81, 0x50e82, 0x50e84, + 0x50e87, 0x50e88, 0x50e8a, 0x50e8d, 0x50ea5, 0x50ea7, 0x50eaa, 0x50eab, 0x50eb2, + 0x50eb3, 0x50ebd, 0x50ec6, 0x50f00, 0x5103f, 0x51061, 0x51065, 0x51066, 0x5108e, + 0x510c7, 0x510cd, 0x51258, 0x512c0, 0x517d7, 0x517dc, 0x518aa, 0x51aa7, 0x51bae, + 0x51baf, 0x51cf5, 0x51cf6, 0x51f59, 0x51f5b, 0x51f5d, 0x51fbe, 0x52071, 0x5207f, + 0x52102, 0x52107, 0x52115, 0x52124, 0x52126, 0x52128, 0x5214e, 0x52183, 0x52184, + 0x52cf2, 0x52cf3, 0x52d27, 0x52d2d, 0x52d6f, 0x52e2f, 0x53005, 0x53006, 0x5303b, + 0x5303c, 0x5a62a, 0x5a62b, 0x5a8fb, 0x5a8fd, 0x5a9cf, 0x5aa7a, 0x5aab1, 0x5aab5, + 0x5aab6, 0x5aac0, 0x5aac2, 0x5fb1d, 0x5fb3e, 0x5fb40, 0x5fb41, 0x5fb43, 0x5fb44, + 0x600aa, 0x600b5, 0x600ba, 0x602ec, 0x602ee, 0x60376, 0x60377, 0x6037f, 0x60386, + 0x6038c, 0x60559, 0x6066e, 0x6066f, 0x606d5, 0x606e5, 0x606e6, 0x606ee, 0x606ef, + 0x606ff, 0x60710, 0x607b1, 0x607f4, 0x607f5, 0x607fa, 0x6081a, 0x60824, 0x60828, + 0x6093d, 0x60950, 0x6098f, 0x60990, 0x609b2, 0x609bd, 0x609ce, 0x609dc, 0x609dd, + 0x609f0, 0x609f1, 0x609fc, 0x60a0f, 0x60a10, 0x60a32, 0x60a33, 0x60a35, 0x60a36, + 0x60a38, 0x60a39, 0x60a5e, 0x60ab2, 0x60ab3, 0x60abd, 0x60ad0, 0x60ae0, 0x60ae1, + 0x60af9, 0x60b0f, 0x60b10, 0x60b32, 0x60b33, 0x60b3d, 0x60b5c, 0x60b5d, 0x60b71, + 0x60b83, 0x60b99, 0x60b9a, 0x60b9c, 0x60b9e, 0x60b9f, 0x60ba3, 0x60ba4, 0x60bd0, + 0x60c3d, 0x60c60, 0x60c61, 0x60c80, 0x60cbd, 0x60cde, 0x60ce0, 0x60ce1, 0x60cf1, + 0x60cf2, 0x60d3d, 0x60d4e, 0x60dbd, 0x60e32, 0x60e33, 0x60e81, 0x60e82, 0x60e84, + 0x60e87, 0x60e88, 0x60e8a, 0x60e8d, 0x60ea5, 0x60ea7, 0x60eaa, 0x60eab, 0x60eb2, + 0x60eb3, 0x60ebd, 0x60ec6, 0x60f00, 0x6103f, 0x61061, 0x61065, 0x61066, 0x6108e, + 0x610c7, 0x610cd, 0x61258, 0x612c0, 0x617d7, 0x617dc, 0x618aa, 0x61aa7, 0x61bae, + 0x61baf, 0x61cf5, 0x61cf6, 0x61f59, 0x61f5b, 0x61f5d, 0x61fbe, 0x62071, 0x6207f, + 0x62102, 0x62107, 0x62115, 0x62124, 0x62126, 0x62128, 0x6214e, 0x62183, 0x62184, + 0x62cf2, 0x62cf3, 0x62d27, 0x62d2d, 0x62d6f, 0x62e2f, 0x63005, 0x63006, 0x6303b, + 0x6303c, 0x6a62a, 0x6a62b, 0x6a8fb, 0x6a8fd, 0x6a9cf, 0x6aa7a, 0x6aab1, 0x6aab5, + 0x6aab6, 0x6aac0, 0x6aac2, 0x6fb1d, 0x6fb3e, 0x6fb40, 0x6fb41, 0x6fb43, 0x6fb44, + 0x700aa, 0x700b5, 0x700ba, 0x702ec, 0x702ee, 0x70376, 0x70377, 0x7037f, 0x70386, + 0x7038c, 0x70559, 0x7066e, 0x7066f, 0x706d5, 0x706e5, 0x706e6, 0x706ee, 0x706ef, + 0x706ff, 0x70710, 0x707b1, 0x707f4, 0x707f5, 0x707fa, 0x7081a, 0x70824, 0x70828, + 0x7093d, 0x70950, 0x7098f, 0x70990, 0x709b2, 0x709bd, 0x709ce, 0x709dc, 0x709dd, + 0x709f0, 0x709f1, 0x709fc, 0x70a0f, 0x70a10, 0x70a32, 0x70a33, 0x70a35, 0x70a36, + 0x70a38, 0x70a39, 0x70a5e, 0x70ab2, 0x70ab3, 0x70abd, 0x70ad0, 0x70ae0, 0x70ae1, + 0x70af9, 0x70b0f, 0x70b10, 0x70b32, 0x70b33, 0x70b3d, 0x70b5c, 0x70b5d, 0x70b71, + 0x70b83, 0x70b99, 0x70b9a, 0x70b9c, 0x70b9e, 0x70b9f, 0x70ba3, 0x70ba4, 0x70bd0, + 0x70c3d, 0x70c60, 0x70c61, 0x70c80, 0x70cbd, 0x70cde, 0x70ce0, 0x70ce1, 0x70cf1, + 0x70cf2, 0x70d3d, 0x70d4e, 0x70dbd, 0x70e32, 0x70e33, 0x70e81, 0x70e82, 0x70e84, + 0x70e87, 0x70e88, 0x70e8a, 0x70e8d, 0x70ea5, 0x70ea7, 0x70eaa, 0x70eab, 0x70eb2, + 0x70eb3, 0x70ebd, 0x70ec6, 0x70f00, 0x7103f, 0x71061, 0x71065, 0x71066, 0x7108e, + 0x710c7, 0x710cd, 0x71258, 0x712c0, 0x717d7, 0x717dc, 0x718aa, 0x71aa7, 0x71bae, + 0x71baf, 0x71cf5, 0x71cf6, 0x71f59, 0x71f5b, 0x71f5d, 0x71fbe, 0x72071, 0x7207f, + 0x72102, 0x72107, 0x72115, 0x72124, 0x72126, 0x72128, 0x7214e, 0x72183, 0x72184, + 0x72cf2, 0x72cf3, 0x72d27, 0x72d2d, 0x72d6f, 0x72e2f, 0x73005, 0x73006, 0x7303b, + 0x7303c, 0x7a62a, 0x7a62b, 0x7a8fb, 0x7a8fd, 0x7a9cf, 0x7aa7a, 0x7aab1, 0x7aab5, + 0x7aab6, 0x7aac0, 0x7aac2, 0x7fb1d, 0x7fb3e, 0x7fb40, 0x7fb41, 0x7fb43, 0x7fb44, + 0x800aa, 0x800b5, 0x800ba, 0x802ec, 0x802ee, 0x80376, 0x80377, 0x8037f, 0x80386, + 0x8038c, 0x80559, 0x8066e, 0x8066f, 0x806d5, 0x806e5, 0x806e6, 0x806ee, 0x806ef, + 0x806ff, 0x80710, 0x807b1, 0x807f4, 0x807f5, 0x807fa, 0x8081a, 0x80824, 0x80828, + 0x8093d, 0x80950, 0x8098f, 0x80990, 0x809b2, 0x809bd, 0x809ce, 0x809dc, 0x809dd, + 0x809f0, 0x809f1, 0x809fc, 0x80a0f, 0x80a10, 0x80a32, 0x80a33, 0x80a35, 0x80a36, + 0x80a38, 0x80a39, 0x80a5e, 0x80ab2, 0x80ab3, 0x80abd, 0x80ad0, 0x80ae0, 0x80ae1, + 0x80af9, 0x80b0f, 0x80b10, 0x80b32, 0x80b33, 0x80b3d, 0x80b5c, 0x80b5d, 0x80b71, + 0x80b83, 0x80b99, 0x80b9a, 0x80b9c, 0x80b9e, 0x80b9f, 0x80ba3, 0x80ba4, 0x80bd0, + 0x80c3d, 0x80c60, 0x80c61, 0x80c80, 0x80cbd, 0x80cde, 0x80ce0, 0x80ce1, 0x80cf1, + 0x80cf2, 0x80d3d, 0x80d4e, 0x80dbd, 0x80e32, 0x80e33, 0x80e81, 0x80e82, 0x80e84, + 0x80e87, 0x80e88, 0x80e8a, 0x80e8d, 0x80ea5, 0x80ea7, 0x80eaa, 0x80eab, 0x80eb2, + 0x80eb3, 0x80ebd, 0x80ec6, 0x80f00, 0x8103f, 0x81061, 0x81065, 0x81066, 0x8108e, + 0x810c7, 0x810cd, 0x81258, 0x812c0, 0x817d7, 0x817dc, 0x818aa, 0x81aa7, 0x81bae, + 0x81baf, 0x81cf5, 0x81cf6, 0x81f59, 0x81f5b, 0x81f5d, 0x81fbe, 0x82071, 0x8207f, + 0x82102, 0x82107, 0x82115, 0x82124, 0x82126, 0x82128, 0x8214e, 0x82183, 0x82184, + 0x82cf2, 0x82cf3, 0x82d27, 0x82d2d, 0x82d6f, 0x82e2f, 0x83005, 0x83006, 0x8303b, + 0x8303c, 0x8a62a, 0x8a62b, 0x8a8fb, 0x8a8fd, 0x8a9cf, 0x8aa7a, 0x8aab1, 0x8aab5, + 0x8aab6, 0x8aac0, 0x8aac2, 0x8fb1d, 0x8fb3e, 0x8fb40, 0x8fb41, 0x8fb43, 0x8fb44, + 0x900aa, 0x900b5, 0x900ba, 0x902ec, 0x902ee, 0x90376, 0x90377, 0x9037f, 0x90386, + 0x9038c, 0x90559, 0x9066e, 0x9066f, 0x906d5, 0x906e5, 0x906e6, 0x906ee, 0x906ef, + 0x906ff, 0x90710, 0x907b1, 0x907f4, 0x907f5, 0x907fa, 0x9081a, 0x90824, 0x90828, + 0x9093d, 0x90950, 0x9098f, 0x90990, 0x909b2, 0x909bd, 0x909ce, 0x909dc, 0x909dd, + 0x909f0, 0x909f1, 0x909fc, 0x90a0f, 0x90a10, 0x90a32, 0x90a33, 0x90a35, 0x90a36, + 0x90a38, 0x90a39, 0x90a5e, 0x90ab2, 0x90ab3, 0x90abd, 0x90ad0, 0x90ae0, 0x90ae1, + 0x90af9, 0x90b0f, 0x90b10, 0x90b32, 0x90b33, 0x90b3d, 0x90b5c, 0x90b5d, 0x90b71, + 0x90b83, 0x90b99, 0x90b9a, 0x90b9c, 0x90b9e, 0x90b9f, 0x90ba3, 0x90ba4, 0x90bd0, + 0x90c3d, 0x90c60, 0x90c61, 0x90c80, 0x90cbd, 0x90cde, 0x90ce0, 0x90ce1, 0x90cf1, + 0x90cf2, 0x90d3d, 0x90d4e, 0x90dbd, 0x90e32, 0x90e33, 0x90e81, 0x90e82, 0x90e84, + 0x90e87, 0x90e88, 0x90e8a, 0x90e8d, 0x90ea5, 0x90ea7, 0x90eaa, 0x90eab, 0x90eb2, + 0x90eb3, 0x90ebd, 0x90ec6, 0x90f00, 0x9103f, 0x91061, 0x91065, 0x91066, 0x9108e, + 0x910c7, 0x910cd, 0x91258, 0x912c0, 0x917d7, 0x917dc, 0x918aa, 0x91aa7, 0x91bae, + 0x91baf, 0x91cf5, 0x91cf6, 0x91f59, 0x91f5b, 0x91f5d, 0x91fbe, 0x92071, 0x9207f, + 0x92102, 0x92107, 0x92115, 0x92124, 0x92126, 0x92128, 0x9214e, 0x92183, 0x92184, + 0x92cf2, 0x92cf3, 0x92d27, 0x92d2d, 0x92d6f, 0x92e2f, 0x93005, 0x93006, 0x9303b, + 0x9303c, 0x9a62a, 0x9a62b, 0x9a8fb, 0x9a8fd, 0x9a9cf, 0x9aa7a, 0x9aab1, 0x9aab5, + 0x9aab6, 0x9aac0, 0x9aac2, 0x9fb1d, 0x9fb3e, 0x9fb40, 0x9fb41, 0x9fb43, 0x9fb44, + 0xa00aa, 0xa00b5, 0xa00ba, 0xa02ec, 0xa02ee, 0xa0376, 0xa0377, 0xa037f, 0xa0386, + 0xa038c, 0xa0559, 0xa066e, 0xa066f, 0xa06d5, 0xa06e5, 0xa06e6, 0xa06ee, 0xa06ef, + 0xa06ff, 0xa0710, 0xa07b1, 0xa07f4, 0xa07f5, 0xa07fa, 0xa081a, 0xa0824, 0xa0828, + 0xa093d, 0xa0950, 0xa098f, 0xa0990, 0xa09b2, 0xa09bd, 0xa09ce, 0xa09dc, 0xa09dd, + 0xa09f0, 0xa09f1, 0xa09fc, 0xa0a0f, 0xa0a10, 0xa0a32, 0xa0a33, 0xa0a35, 0xa0a36, + 0xa0a38, 0xa0a39, 0xa0a5e, 0xa0ab2, 0xa0ab3, 0xa0abd, 0xa0ad0, 0xa0ae0, 0xa0ae1, + 0xa0af9, 0xa0b0f, 0xa0b10, 0xa0b32, 0xa0b33, 0xa0b3d, 0xa0b5c, 0xa0b5d, 0xa0b71, + 0xa0b83, 0xa0b99, 0xa0b9a, 0xa0b9c, 0xa0b9e, 0xa0b9f, 0xa0ba3, 0xa0ba4, 0xa0bd0, + 0xa0c3d, 0xa0c60, 0xa0c61, 0xa0c80, 0xa0cbd, 0xa0cde, 0xa0ce0, 0xa0ce1, 0xa0cf1, + 0xa0cf2, 0xa0d3d, 0xa0d4e, 0xa0dbd, 0xa0e32, 0xa0e33, 0xa0e81, 0xa0e82, 0xa0e84, + 0xa0e87, 0xa0e88, 0xa0e8a, 0xa0e8d, 0xa0ea5, 0xa0ea7, 0xa0eaa, 0xa0eab, 0xa0eb2, + 0xa0eb3, 0xa0ebd, 0xa0ec6, 0xa0f00, 0xa103f, 0xa1061, 0xa1065, 0xa1066, 0xa108e, + 0xa10c7, 0xa10cd, 0xa1258, 0xa12c0, 0xa17d7, 0xa17dc, 0xa18aa, 0xa1aa7, 0xa1bae, + 0xa1baf, 0xa1cf5, 0xa1cf6, 0xa1f59, 0xa1f5b, 0xa1f5d, 0xa1fbe, 0xa2071, 0xa207f, + 0xa2102, 0xa2107, 0xa2115, 0xa2124, 0xa2126, 0xa2128, 0xa214e, 0xa2183, 0xa2184, + 0xa2cf2, 0xa2cf3, 0xa2d27, 0xa2d2d, 0xa2d6f, 0xa2e2f, 0xa3005, 0xa3006, 0xa303b, + 0xa303c, 0xaa62a, 0xaa62b, 0xaa8fb, 0xaa8fd, 0xaa9cf, 0xaaa7a, 0xaaab1, 0xaaab5, + 0xaaab6, 0xaaac0, 0xaaac2, 0xafb1d, 0xafb3e, 0xafb40, 0xafb41, 0xafb43, 0xafb44, + 0xb00aa, 0xb00b5, 0xb00ba, 0xb02ec, 0xb02ee, 0xb0376, 0xb0377, 0xb037f, 0xb0386, + 0xb038c, 0xb0559, 0xb066e, 0xb066f, 0xb06d5, 0xb06e5, 0xb06e6, 0xb06ee, 0xb06ef, + 0xb06ff, 0xb0710, 0xb07b1, 0xb07f4, 0xb07f5, 0xb07fa, 0xb081a, 0xb0824, 0xb0828, + 0xb093d, 0xb0950, 0xb098f, 0xb0990, 0xb09b2, 0xb09bd, 0xb09ce, 0xb09dc, 0xb09dd, + 0xb09f0, 0xb09f1, 0xb09fc, 0xb0a0f, 0xb0a10, 0xb0a32, 0xb0a33, 0xb0a35, 0xb0a36, + 0xb0a38, 0xb0a39, 0xb0a5e, 0xb0ab2, 0xb0ab3, 0xb0abd, 0xb0ad0, 0xb0ae0, 0xb0ae1, + 0xb0af9, 0xb0b0f, 0xb0b10, 0xb0b32, 0xb0b33, 0xb0b3d, 0xb0b5c, 0xb0b5d, 0xb0b71, + 0xb0b83, 0xb0b99, 0xb0b9a, 0xb0b9c, 0xb0b9e, 0xb0b9f, 0xb0ba3, 0xb0ba4, 0xb0bd0, + 0xb0c3d, 0xb0c60, 0xb0c61, 0xb0c80, 0xb0cbd, 0xb0cde, 0xb0ce0, 0xb0ce1, 0xb0cf1, + 0xb0cf2, 0xb0d3d, 0xb0d4e, 0xb0dbd, 0xb0e32, 0xb0e33, 0xb0e81, 0xb0e82, 0xb0e84, + 0xb0e87, 0xb0e88, 0xb0e8a, 0xb0e8d, 0xb0ea5, 0xb0ea7, 0xb0eaa, 0xb0eab, 0xb0eb2, + 0xb0eb3, 0xb0ebd, 0xb0ec6, 0xb0f00, 0xb103f, 0xb1061, 0xb1065, 0xb1066, 0xb108e, + 0xb10c7, 0xb10cd, 0xb1258, 0xb12c0, 0xb17d7, 0xb17dc, 0xb18aa, 0xb1aa7, 0xb1bae, + 0xb1baf, 0xb1cf5, 0xb1cf6, 0xb1f59, 0xb1f5b, 0xb1f5d, 0xb1fbe, 0xb2071, 0xb207f, + 0xb2102, 0xb2107, 0xb2115, 0xb2124, 0xb2126, 0xb2128, 0xb214e, 0xb2183, 0xb2184, + 0xb2cf2, 0xb2cf3, 0xb2d27, 0xb2d2d, 0xb2d6f, 0xb2e2f, 0xb3005, 0xb3006, 0xb303b, + 0xb303c, 0xba62a, 0xba62b, 0xba8fb, 0xba8fd, 0xba9cf, 0xbaa7a, 0xbaab1, 0xbaab5, + 0xbaab6, 0xbaac0, 0xbaac2, 0xbfb1d, 0xbfb3e, 0xbfb40, 0xbfb41, 0xbfb43, 0xbfb44, + 0xc00aa, 0xc00b5, 0xc00ba, 0xc02ec, 0xc02ee, 0xc0376, 0xc0377, 0xc037f, 0xc0386, + 0xc038c, 0xc0559, 0xc066e, 0xc066f, 0xc06d5, 0xc06e5, 0xc06e6, 0xc06ee, 0xc06ef, + 0xc06ff, 0xc0710, 0xc07b1, 0xc07f4, 0xc07f5, 0xc07fa, 0xc081a, 0xc0824, 0xc0828, + 0xc093d, 0xc0950, 0xc098f, 0xc0990, 0xc09b2, 0xc09bd, 0xc09ce, 0xc09dc, 0xc09dd, + 0xc09f0, 0xc09f1, 0xc09fc, 0xc0a0f, 0xc0a10, 0xc0a32, 0xc0a33, 0xc0a35, 0xc0a36, + 0xc0a38, 0xc0a39, 0xc0a5e, 0xc0ab2, 0xc0ab3, 0xc0abd, 0xc0ad0, 0xc0ae0, 0xc0ae1, + 0xc0af9, 0xc0b0f, 0xc0b10, 0xc0b32, 0xc0b33, 0xc0b3d, 0xc0b5c, 0xc0b5d, 0xc0b71, + 0xc0b83, 0xc0b99, 0xc0b9a, 0xc0b9c, 0xc0b9e, 0xc0b9f, 0xc0ba3, 0xc0ba4, 0xc0bd0, + 0xc0c3d, 0xc0c60, 0xc0c61, 0xc0c80, 0xc0cbd, 0xc0cde, 0xc0ce0, 0xc0ce1, 0xc0cf1, + 0xc0cf2, 0xc0d3d, 0xc0d4e, 0xc0dbd, 0xc0e32, 0xc0e33, 0xc0e81, 0xc0e82, 0xc0e84, + 0xc0e87, 0xc0e88, 0xc0e8a, 0xc0e8d, 0xc0ea5, 0xc0ea7, 0xc0eaa, 0xc0eab, 0xc0eb2, + 0xc0eb3, 0xc0ebd, 0xc0ec6, 0xc0f00, 0xc103f, 0xc1061, 0xc1065, 0xc1066, 0xc108e, + 0xc10c7, 0xc10cd, 0xc1258, 0xc12c0, 0xc17d7, 0xc17dc, 0xc18aa, 0xc1aa7, 0xc1bae, + 0xc1baf, 0xc1cf5, 0xc1cf6, 0xc1f59, 0xc1f5b, 0xc1f5d, 0xc1fbe, 0xc2071, 0xc207f, + 0xc2102, 0xc2107, 0xc2115, 0xc2124, 0xc2126, 0xc2128, 0xc214e, 0xc2183, 0xc2184, + 0xc2cf2, 0xc2cf3, 0xc2d27, 0xc2d2d, 0xc2d6f, 0xc2e2f, 0xc3005, 0xc3006, 0xc303b, + 0xc303c, 0xca62a, 0xca62b, 0xca8fb, 0xca8fd, 0xca9cf, 0xcaa7a, 0xcaab1, 0xcaab5, + 0xcaab6, 0xcaac0, 0xcaac2, 0xcfb1d, 0xcfb3e, 0xcfb40, 0xcfb41, 0xcfb43, 0xcfb44, + 0xd00aa, 0xd00b5, 0xd00ba, 0xd02ec, 0xd02ee, 0xd0376, 0xd0377, 0xd037f, 0xd0386, + 0xd038c, 0xd0559, 0xd066e, 0xd066f, 0xd06d5, 0xd06e5, 0xd06e6, 0xd06ee, 0xd06ef, + 0xd06ff, 0xd0710, 0xd07b1, 0xd07f4, 0xd07f5, 0xd07fa, 0xd081a, 0xd0824, 0xd0828, + 0xd093d, 0xd0950, 0xd098f, 0xd0990, 0xd09b2, 0xd09bd, 0xd09ce, 0xd09dc, 0xd09dd, + 0xd09f0, 0xd09f1, 0xd09fc, 0xd0a0f, 0xd0a10, 0xd0a32, 0xd0a33, 0xd0a35, 0xd0a36, + 0xd0a38, 0xd0a39, 0xd0a5e, 0xd0ab2, 0xd0ab3, 0xd0abd, 0xd0ad0, 0xd0ae0, 0xd0ae1, + 0xd0af9, 0xd0b0f, 0xd0b10, 0xd0b32, 0xd0b33, 0xd0b3d, 0xd0b5c, 0xd0b5d, 0xd0b71, + 0xd0b83, 0xd0b99, 0xd0b9a, 0xd0b9c, 0xd0b9e, 0xd0b9f, 0xd0ba3, 0xd0ba4, 0xd0bd0, + 0xd0c3d, 0xd0c60, 0xd0c61, 0xd0c80, 0xd0cbd, 0xd0cde, 0xd0ce0, 0xd0ce1, 0xd0cf1, + 0xd0cf2, 0xd0d3d, 0xd0d4e, 0xd0dbd, 0xd0e32, 0xd0e33, 0xd0e81, 0xd0e82, 0xd0e84, + 0xd0e87, 0xd0e88, 0xd0e8a, 0xd0e8d, 0xd0ea5, 0xd0ea7, 0xd0eaa, 0xd0eab, 0xd0eb2, + 0xd0eb3, 0xd0ebd, 0xd0ec6, 0xd0f00, 0xd103f, 0xd1061, 0xd1065, 0xd1066, 0xd108e, + 0xd10c7, 0xd10cd, 0xd1258, 0xd12c0, 0xd17d7, 0xd17dc, 0xd18aa, 0xd1aa7, 0xd1bae, + 0xd1baf, 0xd1cf5, 0xd1cf6, 0xd1f59, 0xd1f5b, 0xd1f5d, 0xd1fbe, 0xd2071, 0xd207f, + 0xd2102, 0xd2107, 0xd2115, 0xd2124, 0xd2126, 0xd2128, 0xd214e, 0xd2183, 0xd2184, + 0xd2cf2, 0xd2cf3, 0xd2d27, 0xd2d2d, 0xd2d6f, 0xd2e2f, 0xd3005, 0xd3006, 0xd303b, + 0xd303c, 0xda62a, 0xda62b, 0xda8fb, 0xda8fd, 0xda9cf, 0xdaa7a, 0xdaab1, 0xdaab5, + 0xdaab6, 0xdaac0, 0xdaac2, 0xdfb1d, 0xdfb3e, 0xdfb40, 0xdfb41, 0xdfb43, 0xdfb44, + 0xe00aa, 0xe00b5, 0xe00ba, 0xe02ec, 0xe02ee, 0xe0376, 0xe0377, 0xe037f, 0xe0386, + 0xe038c, 0xe0559, 0xe066e, 0xe066f, 0xe06d5, 0xe06e5, 0xe06e6, 0xe06ee, 0xe06ef, + 0xe06ff, 0xe0710, 0xe07b1, 0xe07f4, 0xe07f5, 0xe07fa, 0xe081a, 0xe0824, 0xe0828, + 0xe093d, 0xe0950, 0xe098f, 0xe0990, 0xe09b2, 0xe09bd, 0xe09ce, 0xe09dc, 0xe09dd, + 0xe09f0, 0xe09f1, 0xe09fc, 0xe0a0f, 0xe0a10, 0xe0a32, 0xe0a33, 0xe0a35, 0xe0a36, + 0xe0a38, 0xe0a39, 0xe0a5e, 0xe0ab2, 0xe0ab3, 0xe0abd, 0xe0ad0, 0xe0ae0, 0xe0ae1, + 0xe0af9, 0xe0b0f, 0xe0b10, 0xe0b32, 0xe0b33, 0xe0b3d, 0xe0b5c, 0xe0b5d, 0xe0b71, + 0xe0b83, 0xe0b99, 0xe0b9a, 0xe0b9c, 0xe0b9e, 0xe0b9f, 0xe0ba3, 0xe0ba4, 0xe0bd0, + 0xe0c3d, 0xe0c60, 0xe0c61, 0xe0c80, 0xe0cbd, 0xe0cde, 0xe0ce0, 0xe0ce1, 0xe0cf1, + 0xe0cf2, 0xe0d3d, 0xe0d4e, 0xe0dbd, 0xe0e32, 0xe0e33, 0xe0e81, 0xe0e82, 0xe0e84, + 0xe0e87, 0xe0e88, 0xe0e8a, 0xe0e8d, 0xe0ea5, 0xe0ea7, 0xe0eaa, 0xe0eab, 0xe0eb2, + 0xe0eb3, 0xe0ebd, 0xe0ec6, 0xe0f00, 0xe103f, 0xe1061, 0xe1065, 0xe1066, 0xe108e, + 0xe10c7, 0xe10cd, 0xe1258, 0xe12c0, 0xe17d7, 0xe17dc, 0xe18aa, 0xe1aa7, 0xe1bae, + 0xe1baf, 0xe1cf5, 0xe1cf6, 0xe1f59, 0xe1f5b, 0xe1f5d, 0xe1fbe, 0xe2071, 0xe207f, + 0xe2102, 0xe2107, 0xe2115, 0xe2124, 0xe2126, 0xe2128, 0xe214e, 0xe2183, 0xe2184, + 0xe2cf2, 0xe2cf3, 0xe2d27, 0xe2d2d, 0xe2d6f, 0xe2e2f, 0xe3005, 0xe3006, 0xe303b, + 0xe303c, 0xea62a, 0xea62b, 0xea8fb, 0xea8fd, 0xea9cf, 0xeaa7a, 0xeaab1, 0xeaab5, + 0xeaab6, 0xeaac0, 0xeaac2, 0xefb1d, 0xefb3e, 0xefb40, 0xefb41, 0xefb43, 0xefb44, + 0xf00aa, 0xf00b5, 0xf00ba, 0xf02ec, 0xf02ee, 0xf0376, 0xf0377, 0xf037f, 0xf0386, + 0xf038c, 0xf0559, 0xf066e, 0xf066f, 0xf06d5, 0xf06e5, 0xf06e6, 0xf06ee, 0xf06ef, + 0xf06ff, 0xf0710, 0xf07b1, 0xf07f4, 0xf07f5, 0xf07fa, 0xf081a, 0xf0824, 0xf0828, + 0xf093d, 0xf0950, 0xf098f, 0xf0990, 0xf09b2, 0xf09bd, 0xf09ce, 0xf09dc, 0xf09dd, + 0xf09f0, 0xf09f1, 0xf09fc, 0xf0a0f, 0xf0a10, 0xf0a32, 0xf0a33, 0xf0a35, 0xf0a36, + 0xf0a38, 0xf0a39, 0xf0a5e, 0xf0ab2, 0xf0ab3, 0xf0abd, 0xf0ad0, 0xf0ae0, 0xf0ae1, + 0xf0af9, 0xf0b0f, 0xf0b10, 0xf0b32, 0xf0b33, 0xf0b3d, 0xf0b5c, 0xf0b5d, 0xf0b71, + 0xf0b83, 0xf0b99, 0xf0b9a, 0xf0b9c, 0xf0b9e, 0xf0b9f, 0xf0ba3, 0xf0ba4, 0xf0bd0, + 0xf0c3d, 0xf0c60, 0xf0c61, 0xf0c80, 0xf0cbd, 0xf0cde, 0xf0ce0, 0xf0ce1, 0xf0cf1, + 0xf0cf2, 0xf0d3d, 0xf0d4e, 0xf0dbd, 0xf0e32, 0xf0e33, 0xf0e81, 0xf0e82, 0xf0e84, + 0xf0e87, 0xf0e88, 0xf0e8a, 0xf0e8d, 0xf0ea5, 0xf0ea7, 0xf0eaa, 0xf0eab, 0xf0eb2, + 0xf0eb3, 0xf0ebd, 0xf0ec6, 0xf0f00, 0xf103f, 0xf1061, 0xf1065, 0xf1066, 0xf108e, + 0xf10c7, 0xf10cd, 0xf1258, 0xf12c0, 0xf17d7, 0xf17dc, 0xf18aa, 0xf1aa7, 0xf1bae, + 0xf1baf, 0xf1cf5, 0xf1cf6, 0xf1f59, 0xf1f5b, 0xf1f5d, 0xf1fbe, 0xf2071, 0xf207f, + 0xf2102, 0xf2107, 0xf2115, 0xf2124, 0xf2126, 0xf2128, 0xf214e, 0xf2183, 0xf2184, + 0xf2cf2, 0xf2cf3, 0xf2d27, 0xf2d2d, 0xf2d6f, 0xf2e2f, 0xf3005, 0xf3006, 0xf303b, + 0xf303c, 0xfa62a, 0xfa62b, 0xfa8fb, 0xfa8fd, 0xfa9cf, 0xfaa7a, 0xfaab1, 0xfaab5, + 0xfaab6, 0xfaac0, 0xfaac2, 0xffb1d, 0xffb3e, 0xffb40, 0xffb41, 0xffb43, 0xffb44, + 0x1000aa, 0x1000b5, 0x1000ba, 0x1002ec, 0x1002ee, 0x100376, 0x100377, 0x10037f, 0x100386, + 0x10038c, 0x100559, 0x10066e, 0x10066f, 0x1006d5, 0x1006e5, 0x1006e6, 0x1006ee, 0x1006ef, + 0x1006ff, 0x100710, 0x1007b1, 0x1007f4, 0x1007f5, 0x1007fa, 0x10081a, 0x100824, 0x100828, + 0x10093d, 0x100950, 0x10098f, 0x100990, 0x1009b2, 0x1009bd, 0x1009ce, 0x1009dc, 0x1009dd, + 0x1009f0, 0x1009f1, 0x1009fc, 0x100a0f, 0x100a10, 0x100a32, 0x100a33, 0x100a35, 0x100a36, + 0x100a38, 0x100a39, 0x100a5e, 0x100ab2, 0x100ab3, 0x100abd, 0x100ad0, 0x100ae0, 0x100ae1, + 0x100af9, 0x100b0f, 0x100b10, 0x100b32, 0x100b33, 0x100b3d, 0x100b5c, 0x100b5d, 0x100b71, + 0x100b83, 0x100b99, 0x100b9a, 0x100b9c, 0x100b9e, 0x100b9f, 0x100ba3, 0x100ba4, 0x100bd0, + 0x100c3d, 0x100c60, 0x100c61, 0x100c80, 0x100cbd, 0x100cde, 0x100ce0, 0x100ce1, 0x100cf1, + 0x100cf2, 0x100d3d, 0x100d4e, 0x100dbd, 0x100e32, 0x100e33, 0x100e81, 0x100e82, 0x100e84, + 0x100e87, 0x100e88, 0x100e8a, 0x100e8d, 0x100ea5, 0x100ea7, 0x100eaa, 0x100eab, 0x100eb2, + 0x100eb3, 0x100ebd, 0x100ec6, 0x100f00, 0x10103f, 0x101061, 0x101065, 0x101066, 0x10108e, + 0x1010c7, 0x1010cd, 0x101258, 0x1012c0, 0x1017d7, 0x1017dc, 0x1018aa, 0x101aa7, 0x101bae, + 0x101baf, 0x101cf5, 0x101cf6, 0x101f59, 0x101f5b, 0x101f5d, 0x101fbe, 0x102071, 0x10207f, + 0x102102, 0x102107, 0x102115, 0x102124, 0x102126, 0x102128, 0x10214e, 0x102183, 0x102184, + 0x102cf2, 0x102cf3, 0x102d27, 0x102d2d, 0x102d6f, 0x102e2f, 0x103005, 0x103006, 0x10303b, + 0x10303c, 0x10a62a, 0x10a62b, 0x10a8fb, 0x10a8fd, 0x10a9cf, 0x10aa7a, 0x10aab1, 0x10aab5, + 0x10aab6, 0x10aac0, 0x10aac2, 0x10fb1d, 0x10fb3e, 0x10fb40, 0x10fb41, 0x10fb43, 0x10fb44 #endif }; @@ -286,8 +1567,42 @@ static const crange controlRangeTable[] = { {0x202a, 0x202e}, {0x2060, 0x2064}, {0x2066, 0x206f}, {0xe000, 0xf8ff}, {0xfff9, 0xfffb} #if TCL_UTF_MAX > 4 - ,{0x1bca0, 0x1bca3}, {0x1d173, 0x1d17a}, {0xe0020, 0xe007f}, {0xf0000, 0xffffd}, - {0x100000, 0x10fffd} + ,{0x10000, 0x1001f}, {0x1007f, 0x1009f}, {0x10600, 0x10605}, {0x1200b, 0x1200f}, + {0x1202a, 0x1202e}, {0x12060, 0x12064}, {0x12066, 0x1206f}, {0x1e000, 0x1f8ff}, + {0x1fff9, 0x1fffb}, {0x20000, 0x2001f}, {0x2007f, 0x2009f}, {0x20600, 0x20605}, + {0x2200b, 0x2200f}, {0x2202a, 0x2202e}, {0x22060, 0x22064}, {0x22066, 0x2206f}, + {0x2e000, 0x2f8ff}, {0x2fff9, 0x2fffb}, {0x30000, 0x3001f}, {0x3007f, 0x3009f}, + {0x30600, 0x30605}, {0x3200b, 0x3200f}, {0x3202a, 0x3202e}, {0x32060, 0x32064}, + {0x32066, 0x3206f}, {0x3e000, 0x3f8ff}, {0x3fff9, 0x3fffb}, {0x40000, 0x4001f}, + {0x4007f, 0x4009f}, {0x40600, 0x40605}, {0x4200b, 0x4200f}, {0x4202a, 0x4202e}, + {0x42060, 0x42064}, {0x42066, 0x4206f}, {0x4e000, 0x4f8ff}, {0x4fff9, 0x4fffb}, + {0x50000, 0x5001f}, {0x5007f, 0x5009f}, {0x50600, 0x50605}, {0x5200b, 0x5200f}, + {0x5202a, 0x5202e}, {0x52060, 0x52064}, {0x52066, 0x5206f}, {0x5e000, 0x5f8ff}, + {0x5fff9, 0x5fffb}, {0x60000, 0x6001f}, {0x6007f, 0x6009f}, {0x60600, 0x60605}, + {0x6200b, 0x6200f}, {0x6202a, 0x6202e}, {0x62060, 0x62064}, {0x62066, 0x6206f}, + {0x6e000, 0x6f8ff}, {0x6fff9, 0x6fffb}, {0x70000, 0x7001f}, {0x7007f, 0x7009f}, + {0x70600, 0x70605}, {0x7200b, 0x7200f}, {0x7202a, 0x7202e}, {0x72060, 0x72064}, + {0x72066, 0x7206f}, {0x7e000, 0x7f8ff}, {0x7fff9, 0x7fffb}, {0x80000, 0x8001f}, + {0x8007f, 0x8009f}, {0x80600, 0x80605}, {0x8200b, 0x8200f}, {0x8202a, 0x8202e}, + {0x82060, 0x82064}, {0x82066, 0x8206f}, {0x8e000, 0x8f8ff}, {0x8fff9, 0x8fffb}, + {0x90000, 0x9001f}, {0x9007f, 0x9009f}, {0x90600, 0x90605}, {0x9200b, 0x9200f}, + {0x9202a, 0x9202e}, {0x92060, 0x92064}, {0x92066, 0x9206f}, {0x9e000, 0x9f8ff}, + {0x9fff9, 0x9fffb}, {0xa0000, 0xa001f}, {0xa007f, 0xa009f}, {0xa0600, 0xa0605}, + {0xa200b, 0xa200f}, {0xa202a, 0xa202e}, {0xa2060, 0xa2064}, {0xa2066, 0xa206f}, + {0xae000, 0xaf8ff}, {0xafff9, 0xafffb}, {0xb0000, 0xb001f}, {0xb007f, 0xb009f}, + {0xb0600, 0xb0605}, {0xb200b, 0xb200f}, {0xb202a, 0xb202e}, {0xb2060, 0xb2064}, + {0xb2066, 0xb206f}, {0xbe000, 0xbf8ff}, {0xbfff9, 0xbfffb}, {0xc0000, 0xc001f}, + {0xc007f, 0xc009f}, {0xc0600, 0xc0605}, {0xc200b, 0xc200f}, {0xc202a, 0xc202e}, + {0xc2060, 0xc2064}, {0xc2066, 0xc206f}, {0xce000, 0xcf8ff}, {0xcfff9, 0xcfffb}, + {0xd0000, 0xd001f}, {0xd007f, 0xd009f}, {0xd0600, 0xd0605}, {0xd200b, 0xd200f}, + {0xd202a, 0xd202e}, {0xd2060, 0xd2064}, {0xd2066, 0xd206f}, {0xde000, 0xdf8ff}, + {0xdfff9, 0xdfffb}, {0xe0000, 0xe001f}, {0xe007f, 0xe009f}, {0xe0600, 0xe0605}, + {0xe200b, 0xe200f}, {0xe202a, 0xe202e}, {0xe2060, 0xe2064}, {0xe2066, 0xe206f}, + {0xee000, 0xef8ff}, {0xefff9, 0xefffb}, {0xf0000, 0xf001f}, {0xf007f, 0xf009f}, + {0xf0600, 0xf0605}, {0xf200b, 0xf200f}, {0xf202a, 0xf202e}, {0xf2060, 0xf2064}, + {0xf2066, 0xf206f}, {0xfe000, 0xff8ff}, {0xffff9, 0xffffb}, {0x100000, 0x10001f}, + {0x10007f, 0x10009f}, {0x100600, 0x100605}, {0x10200b, 0x10200f}, {0x10202a, 0x10202e}, + {0x102060, 0x102064}, {0x102066, 0x10206f}, {0x10e000, 0x10f8ff}, {0x10fff9, 0x10fffb} #endif }; @@ -296,7 +1611,19 @@ static const crange controlRangeTable[] = { static const chr controlCharTable[] = { 0xad, 0x61c, 0x6dd, 0x70f, 0x8e2, 0x180e, 0xfeff #if TCL_UTF_MAX > 4 - ,0x110bd, 0xe0001 + ,0x100ad, 0x1061c, 0x106dd, 0x1070f, 0x108e2, 0x1180e, 0x1feff, 0x200ad, 0x2061c, + 0x206dd, 0x2070f, 0x208e2, 0x2180e, 0x2feff, 0x300ad, 0x3061c, 0x306dd, 0x3070f, + 0x308e2, 0x3180e, 0x3feff, 0x400ad, 0x4061c, 0x406dd, 0x4070f, 0x408e2, 0x4180e, + 0x4feff, 0x500ad, 0x5061c, 0x506dd, 0x5070f, 0x508e2, 0x5180e, 0x5feff, 0x600ad, + 0x6061c, 0x606dd, 0x6070f, 0x608e2, 0x6180e, 0x6feff, 0x700ad, 0x7061c, 0x706dd, + 0x7070f, 0x708e2, 0x7180e, 0x7feff, 0x800ad, 0x8061c, 0x806dd, 0x8070f, 0x808e2, + 0x8180e, 0x8feff, 0x900ad, 0x9061c, 0x906dd, 0x9070f, 0x908e2, 0x9180e, 0x9feff, + 0xa00ad, 0xa061c, 0xa06dd, 0xa070f, 0xa08e2, 0xa180e, 0xafeff, 0xb00ad, 0xb061c, + 0xb06dd, 0xb070f, 0xb08e2, 0xb180e, 0xbfeff, 0xc00ad, 0xc061c, 0xc06dd, 0xc070f, + 0xc08e2, 0xc180e, 0xcfeff, 0xd00ad, 0xd061c, 0xd06dd, 0xd070f, 0xd08e2, 0xd180e, + 0xdfeff, 0xe00ad, 0xe061c, 0xe06dd, 0xe070f, 0xe08e2, 0xe180e, 0xefeff, 0xf00ad, + 0xf061c, 0xf06dd, 0xf070f, 0xf08e2, 0xf180e, 0xffeff, 0x1000ad, 0x10061c, 0x1006dd, + 0x10070f, 0x1008e2, 0x10180e, 0x10feff #endif }; @@ -318,11 +1645,154 @@ static const crange digitRangeTable[] = { {0xa9d0, 0xa9d9}, {0xa9f0, 0xa9f9}, {0xaa50, 0xaa59}, {0xabf0, 0xabf9}, {0xff10, 0xff19} #if TCL_UTF_MAX > 4 - ,{0x104a0, 0x104a9}, {0x11066, 0x1106f}, {0x110f0, 0x110f9}, {0x11136, 0x1113f}, - {0x111d0, 0x111d9}, {0x112f0, 0x112f9}, {0x11450, 0x11459}, {0x114d0, 0x114d9}, - {0x11650, 0x11659}, {0x116c0, 0x116c9}, {0x11730, 0x11739}, {0x118e0, 0x118e9}, - {0x11c50, 0x11c59}, {0x16a60, 0x16a69}, {0x16b50, 0x16b59}, {0x1d7ce, 0x1d7ff}, - {0x1e950, 0x1e959} + ,{0x10030, 0x10039}, {0x10660, 0x10669}, {0x106f0, 0x106f9}, {0x107c0, 0x107c9}, + {0x10966, 0x1096f}, {0x109e6, 0x109ef}, {0x10a66, 0x10a6f}, {0x10ae6, 0x10aef}, + {0x10b66, 0x10b6f}, {0x10be6, 0x10bef}, {0x10c66, 0x10c6f}, {0x10ce6, 0x10cef}, + {0x10d66, 0x10d6f}, {0x10de6, 0x10def}, {0x10e50, 0x10e59}, {0x10ed0, 0x10ed9}, + {0x10f20, 0x10f29}, {0x11040, 0x11049}, {0x11090, 0x11099}, {0x117e0, 0x117e9}, + {0x11810, 0x11819}, {0x11946, 0x1194f}, {0x119d0, 0x119d9}, {0x11a80, 0x11a89}, + {0x11a90, 0x11a99}, {0x11b50, 0x11b59}, {0x11bb0, 0x11bb9}, {0x11c40, 0x11c49}, + {0x11c50, 0x11c59}, {0x1a620, 0x1a629}, {0x1a8d0, 0x1a8d9}, {0x1a900, 0x1a909}, + {0x1a9d0, 0x1a9d9}, {0x1a9f0, 0x1a9f9}, {0x1aa50, 0x1aa59}, {0x1abf0, 0x1abf9}, + {0x1ff10, 0x1ff19}, {0x20030, 0x20039}, {0x20660, 0x20669}, {0x206f0, 0x206f9}, + {0x207c0, 0x207c9}, {0x20966, 0x2096f}, {0x209e6, 0x209ef}, {0x20a66, 0x20a6f}, + {0x20ae6, 0x20aef}, {0x20b66, 0x20b6f}, {0x20be6, 0x20bef}, {0x20c66, 0x20c6f}, + {0x20ce6, 0x20cef}, {0x20d66, 0x20d6f}, {0x20de6, 0x20def}, {0x20e50, 0x20e59}, + {0x20ed0, 0x20ed9}, {0x20f20, 0x20f29}, {0x21040, 0x21049}, {0x21090, 0x21099}, + {0x217e0, 0x217e9}, {0x21810, 0x21819}, {0x21946, 0x2194f}, {0x219d0, 0x219d9}, + {0x21a80, 0x21a89}, {0x21a90, 0x21a99}, {0x21b50, 0x21b59}, {0x21bb0, 0x21bb9}, + {0x21c40, 0x21c49}, {0x21c50, 0x21c59}, {0x2a620, 0x2a629}, {0x2a8d0, 0x2a8d9}, + {0x2a900, 0x2a909}, {0x2a9d0, 0x2a9d9}, {0x2a9f0, 0x2a9f9}, {0x2aa50, 0x2aa59}, + {0x2abf0, 0x2abf9}, {0x2ff10, 0x2ff19}, {0x30030, 0x30039}, {0x30660, 0x30669}, + {0x306f0, 0x306f9}, {0x307c0, 0x307c9}, {0x30966, 0x3096f}, {0x309e6, 0x309ef}, + {0x30a66, 0x30a6f}, {0x30ae6, 0x30aef}, {0x30b66, 0x30b6f}, {0x30be6, 0x30bef}, + {0x30c66, 0x30c6f}, {0x30ce6, 0x30cef}, {0x30d66, 0x30d6f}, {0x30de6, 0x30def}, + {0x30e50, 0x30e59}, {0x30ed0, 0x30ed9}, {0x30f20, 0x30f29}, {0x31040, 0x31049}, + {0x31090, 0x31099}, {0x317e0, 0x317e9}, {0x31810, 0x31819}, {0x31946, 0x3194f}, + {0x319d0, 0x319d9}, {0x31a80, 0x31a89}, {0x31a90, 0x31a99}, {0x31b50, 0x31b59}, + {0x31bb0, 0x31bb9}, {0x31c40, 0x31c49}, {0x31c50, 0x31c59}, {0x3a620, 0x3a629}, + {0x3a8d0, 0x3a8d9}, {0x3a900, 0x3a909}, {0x3a9d0, 0x3a9d9}, {0x3a9f0, 0x3a9f9}, + {0x3aa50, 0x3aa59}, {0x3abf0, 0x3abf9}, {0x3ff10, 0x3ff19}, {0x40030, 0x40039}, + {0x40660, 0x40669}, {0x406f0, 0x406f9}, {0x407c0, 0x407c9}, {0x40966, 0x4096f}, + {0x409e6, 0x409ef}, {0x40a66, 0x40a6f}, {0x40ae6, 0x40aef}, {0x40b66, 0x40b6f}, + {0x40be6, 0x40bef}, {0x40c66, 0x40c6f}, {0x40ce6, 0x40cef}, {0x40d66, 0x40d6f}, + {0x40de6, 0x40def}, {0x40e50, 0x40e59}, {0x40ed0, 0x40ed9}, {0x40f20, 0x40f29}, + {0x41040, 0x41049}, {0x41090, 0x41099}, {0x417e0, 0x417e9}, {0x41810, 0x41819}, + {0x41946, 0x4194f}, {0x419d0, 0x419d9}, {0x41a80, 0x41a89}, {0x41a90, 0x41a99}, + {0x41b50, 0x41b59}, {0x41bb0, 0x41bb9}, {0x41c40, 0x41c49}, {0x41c50, 0x41c59}, + {0x4a620, 0x4a629}, {0x4a8d0, 0x4a8d9}, {0x4a900, 0x4a909}, {0x4a9d0, 0x4a9d9}, + {0x4a9f0, 0x4a9f9}, {0x4aa50, 0x4aa59}, {0x4abf0, 0x4abf9}, {0x4ff10, 0x4ff19}, + {0x50030, 0x50039}, {0x50660, 0x50669}, {0x506f0, 0x506f9}, {0x507c0, 0x507c9}, + {0x50966, 0x5096f}, {0x509e6, 0x509ef}, {0x50a66, 0x50a6f}, {0x50ae6, 0x50aef}, + {0x50b66, 0x50b6f}, {0x50be6, 0x50bef}, {0x50c66, 0x50c6f}, {0x50ce6, 0x50cef}, + {0x50d66, 0x50d6f}, {0x50de6, 0x50def}, {0x50e50, 0x50e59}, {0x50ed0, 0x50ed9}, + {0x50f20, 0x50f29}, {0x51040, 0x51049}, {0x51090, 0x51099}, {0x517e0, 0x517e9}, + {0x51810, 0x51819}, {0x51946, 0x5194f}, {0x519d0, 0x519d9}, {0x51a80, 0x51a89}, + {0x51a90, 0x51a99}, {0x51b50, 0x51b59}, {0x51bb0, 0x51bb9}, {0x51c40, 0x51c49}, + {0x51c50, 0x51c59}, {0x5a620, 0x5a629}, {0x5a8d0, 0x5a8d9}, {0x5a900, 0x5a909}, + {0x5a9d0, 0x5a9d9}, {0x5a9f0, 0x5a9f9}, {0x5aa50, 0x5aa59}, {0x5abf0, 0x5abf9}, + {0x5ff10, 0x5ff19}, {0x60030, 0x60039}, {0x60660, 0x60669}, {0x606f0, 0x606f9}, + {0x607c0, 0x607c9}, {0x60966, 0x6096f}, {0x609e6, 0x609ef}, {0x60a66, 0x60a6f}, + {0x60ae6, 0x60aef}, {0x60b66, 0x60b6f}, {0x60be6, 0x60bef}, {0x60c66, 0x60c6f}, + {0x60ce6, 0x60cef}, {0x60d66, 0x60d6f}, {0x60de6, 0x60def}, {0x60e50, 0x60e59}, + {0x60ed0, 0x60ed9}, {0x60f20, 0x60f29}, {0x61040, 0x61049}, {0x61090, 0x61099}, + {0x617e0, 0x617e9}, {0x61810, 0x61819}, {0x61946, 0x6194f}, {0x619d0, 0x619d9}, + {0x61a80, 0x61a89}, {0x61a90, 0x61a99}, {0x61b50, 0x61b59}, {0x61bb0, 0x61bb9}, + {0x61c40, 0x61c49}, {0x61c50, 0x61c59}, {0x6a620, 0x6a629}, {0x6a8d0, 0x6a8d9}, + {0x6a900, 0x6a909}, {0x6a9d0, 0x6a9d9}, {0x6a9f0, 0x6a9f9}, {0x6aa50, 0x6aa59}, + {0x6abf0, 0x6abf9}, {0x6ff10, 0x6ff19}, {0x70030, 0x70039}, {0x70660, 0x70669}, + {0x706f0, 0x706f9}, {0x707c0, 0x707c9}, {0x70966, 0x7096f}, {0x709e6, 0x709ef}, + {0x70a66, 0x70a6f}, {0x70ae6, 0x70aef}, {0x70b66, 0x70b6f}, {0x70be6, 0x70bef}, + {0x70c66, 0x70c6f}, {0x70ce6, 0x70cef}, {0x70d66, 0x70d6f}, {0x70de6, 0x70def}, + {0x70e50, 0x70e59}, {0x70ed0, 0x70ed9}, {0x70f20, 0x70f29}, {0x71040, 0x71049}, + {0x71090, 0x71099}, {0x717e0, 0x717e9}, {0x71810, 0x71819}, {0x71946, 0x7194f}, + {0x719d0, 0x719d9}, {0x71a80, 0x71a89}, {0x71a90, 0x71a99}, {0x71b50, 0x71b59}, + {0x71bb0, 0x71bb9}, {0x71c40, 0x71c49}, {0x71c50, 0x71c59}, {0x7a620, 0x7a629}, + {0x7a8d0, 0x7a8d9}, {0x7a900, 0x7a909}, {0x7a9d0, 0x7a9d9}, {0x7a9f0, 0x7a9f9}, + {0x7aa50, 0x7aa59}, {0x7abf0, 0x7abf9}, {0x7ff10, 0x7ff19}, {0x80030, 0x80039}, + {0x80660, 0x80669}, {0x806f0, 0x806f9}, {0x807c0, 0x807c9}, {0x80966, 0x8096f}, + {0x809e6, 0x809ef}, {0x80a66, 0x80a6f}, {0x80ae6, 0x80aef}, {0x80b66, 0x80b6f}, + {0x80be6, 0x80bef}, {0x80c66, 0x80c6f}, {0x80ce6, 0x80cef}, {0x80d66, 0x80d6f}, + {0x80de6, 0x80def}, {0x80e50, 0x80e59}, {0x80ed0, 0x80ed9}, {0x80f20, 0x80f29}, + {0x81040, 0x81049}, {0x81090, 0x81099}, {0x817e0, 0x817e9}, {0x81810, 0x81819}, + {0x81946, 0x8194f}, {0x819d0, 0x819d9}, {0x81a80, 0x81a89}, {0x81a90, 0x81a99}, + {0x81b50, 0x81b59}, {0x81bb0, 0x81bb9}, {0x81c40, 0x81c49}, {0x81c50, 0x81c59}, + {0x8a620, 0x8a629}, {0x8a8d0, 0x8a8d9}, {0x8a900, 0x8a909}, {0x8a9d0, 0x8a9d9}, + {0x8a9f0, 0x8a9f9}, {0x8aa50, 0x8aa59}, {0x8abf0, 0x8abf9}, {0x8ff10, 0x8ff19}, + {0x90030, 0x90039}, {0x90660, 0x90669}, {0x906f0, 0x906f9}, {0x907c0, 0x907c9}, + {0x90966, 0x9096f}, {0x909e6, 0x909ef}, {0x90a66, 0x90a6f}, {0x90ae6, 0x90aef}, + {0x90b66, 0x90b6f}, {0x90be6, 0x90bef}, {0x90c66, 0x90c6f}, {0x90ce6, 0x90cef}, + {0x90d66, 0x90d6f}, {0x90de6, 0x90def}, {0x90e50, 0x90e59}, {0x90ed0, 0x90ed9}, + {0x90f20, 0x90f29}, {0x91040, 0x91049}, {0x91090, 0x91099}, {0x917e0, 0x917e9}, + {0x91810, 0x91819}, {0x91946, 0x9194f}, {0x919d0, 0x919d9}, {0x91a80, 0x91a89}, + {0x91a90, 0x91a99}, {0x91b50, 0x91b59}, {0x91bb0, 0x91bb9}, {0x91c40, 0x91c49}, + {0x91c50, 0x91c59}, {0x9a620, 0x9a629}, {0x9a8d0, 0x9a8d9}, {0x9a900, 0x9a909}, + {0x9a9d0, 0x9a9d9}, {0x9a9f0, 0x9a9f9}, {0x9aa50, 0x9aa59}, {0x9abf0, 0x9abf9}, + {0x9ff10, 0x9ff19}, {0xa0030, 0xa0039}, {0xa0660, 0xa0669}, {0xa06f0, 0xa06f9}, + {0xa07c0, 0xa07c9}, {0xa0966, 0xa096f}, {0xa09e6, 0xa09ef}, {0xa0a66, 0xa0a6f}, + {0xa0ae6, 0xa0aef}, {0xa0b66, 0xa0b6f}, {0xa0be6, 0xa0bef}, {0xa0c66, 0xa0c6f}, + {0xa0ce6, 0xa0cef}, {0xa0d66, 0xa0d6f}, {0xa0de6, 0xa0def}, {0xa0e50, 0xa0e59}, + {0xa0ed0, 0xa0ed9}, {0xa0f20, 0xa0f29}, {0xa1040, 0xa1049}, {0xa1090, 0xa1099}, + {0xa17e0, 0xa17e9}, {0xa1810, 0xa1819}, {0xa1946, 0xa194f}, {0xa19d0, 0xa19d9}, + {0xa1a80, 0xa1a89}, {0xa1a90, 0xa1a99}, {0xa1b50, 0xa1b59}, {0xa1bb0, 0xa1bb9}, + {0xa1c40, 0xa1c49}, {0xa1c50, 0xa1c59}, {0xaa620, 0xaa629}, {0xaa8d0, 0xaa8d9}, + {0xaa900, 0xaa909}, {0xaa9d0, 0xaa9d9}, {0xaa9f0, 0xaa9f9}, {0xaaa50, 0xaaa59}, + {0xaabf0, 0xaabf9}, {0xaff10, 0xaff19}, {0xb0030, 0xb0039}, {0xb0660, 0xb0669}, + {0xb06f0, 0xb06f9}, {0xb07c0, 0xb07c9}, {0xb0966, 0xb096f}, {0xb09e6, 0xb09ef}, + {0xb0a66, 0xb0a6f}, {0xb0ae6, 0xb0aef}, {0xb0b66, 0xb0b6f}, {0xb0be6, 0xb0bef}, + {0xb0c66, 0xb0c6f}, {0xb0ce6, 0xb0cef}, {0xb0d66, 0xb0d6f}, {0xb0de6, 0xb0def}, + {0xb0e50, 0xb0e59}, {0xb0ed0, 0xb0ed9}, {0xb0f20, 0xb0f29}, {0xb1040, 0xb1049}, + {0xb1090, 0xb1099}, {0xb17e0, 0xb17e9}, {0xb1810, 0xb1819}, {0xb1946, 0xb194f}, + {0xb19d0, 0xb19d9}, {0xb1a80, 0xb1a89}, {0xb1a90, 0xb1a99}, {0xb1b50, 0xb1b59}, + {0xb1bb0, 0xb1bb9}, {0xb1c40, 0xb1c49}, {0xb1c50, 0xb1c59}, {0xba620, 0xba629}, + {0xba8d0, 0xba8d9}, {0xba900, 0xba909}, {0xba9d0, 0xba9d9}, {0xba9f0, 0xba9f9}, + {0xbaa50, 0xbaa59}, {0xbabf0, 0xbabf9}, {0xbff10, 0xbff19}, {0xc0030, 0xc0039}, + {0xc0660, 0xc0669}, {0xc06f0, 0xc06f9}, {0xc07c0, 0xc07c9}, {0xc0966, 0xc096f}, + {0xc09e6, 0xc09ef}, {0xc0a66, 0xc0a6f}, {0xc0ae6, 0xc0aef}, {0xc0b66, 0xc0b6f}, + {0xc0be6, 0xc0bef}, {0xc0c66, 0xc0c6f}, {0xc0ce6, 0xc0cef}, {0xc0d66, 0xc0d6f}, + {0xc0de6, 0xc0def}, {0xc0e50, 0xc0e59}, {0xc0ed0, 0xc0ed9}, {0xc0f20, 0xc0f29}, + {0xc1040, 0xc1049}, {0xc1090, 0xc1099}, {0xc17e0, 0xc17e9}, {0xc1810, 0xc1819}, + {0xc1946, 0xc194f}, {0xc19d0, 0xc19d9}, {0xc1a80, 0xc1a89}, {0xc1a90, 0xc1a99}, + {0xc1b50, 0xc1b59}, {0xc1bb0, 0xc1bb9}, {0xc1c40, 0xc1c49}, {0xc1c50, 0xc1c59}, + {0xca620, 0xca629}, {0xca8d0, 0xca8d9}, {0xca900, 0xca909}, {0xca9d0, 0xca9d9}, + {0xca9f0, 0xca9f9}, {0xcaa50, 0xcaa59}, {0xcabf0, 0xcabf9}, {0xcff10, 0xcff19}, + {0xd0030, 0xd0039}, {0xd0660, 0xd0669}, {0xd06f0, 0xd06f9}, {0xd07c0, 0xd07c9}, + {0xd0966, 0xd096f}, {0xd09e6, 0xd09ef}, {0xd0a66, 0xd0a6f}, {0xd0ae6, 0xd0aef}, + {0xd0b66, 0xd0b6f}, {0xd0be6, 0xd0bef}, {0xd0c66, 0xd0c6f}, {0xd0ce6, 0xd0cef}, + {0xd0d66, 0xd0d6f}, {0xd0de6, 0xd0def}, {0xd0e50, 0xd0e59}, {0xd0ed0, 0xd0ed9}, + {0xd0f20, 0xd0f29}, {0xd1040, 0xd1049}, {0xd1090, 0xd1099}, {0xd17e0, 0xd17e9}, + {0xd1810, 0xd1819}, {0xd1946, 0xd194f}, {0xd19d0, 0xd19d9}, {0xd1a80, 0xd1a89}, + {0xd1a90, 0xd1a99}, {0xd1b50, 0xd1b59}, {0xd1bb0, 0xd1bb9}, {0xd1c40, 0xd1c49}, + {0xd1c50, 0xd1c59}, {0xda620, 0xda629}, {0xda8d0, 0xda8d9}, {0xda900, 0xda909}, + {0xda9d0, 0xda9d9}, {0xda9f0, 0xda9f9}, {0xdaa50, 0xdaa59}, {0xdabf0, 0xdabf9}, + {0xdff10, 0xdff19}, {0xe0030, 0xe0039}, {0xe0660, 0xe0669}, {0xe06f0, 0xe06f9}, + {0xe07c0, 0xe07c9}, {0xe0966, 0xe096f}, {0xe09e6, 0xe09ef}, {0xe0a66, 0xe0a6f}, + {0xe0ae6, 0xe0aef}, {0xe0b66, 0xe0b6f}, {0xe0be6, 0xe0bef}, {0xe0c66, 0xe0c6f}, + {0xe0ce6, 0xe0cef}, {0xe0d66, 0xe0d6f}, {0xe0de6, 0xe0def}, {0xe0e50, 0xe0e59}, + {0xe0ed0, 0xe0ed9}, {0xe0f20, 0xe0f29}, {0xe1040, 0xe1049}, {0xe1090, 0xe1099}, + {0xe17e0, 0xe17e9}, {0xe1810, 0xe1819}, {0xe1946, 0xe194f}, {0xe19d0, 0xe19d9}, + {0xe1a80, 0xe1a89}, {0xe1a90, 0xe1a99}, {0xe1b50, 0xe1b59}, {0xe1bb0, 0xe1bb9}, + {0xe1c40, 0xe1c49}, {0xe1c50, 0xe1c59}, {0xea620, 0xea629}, {0xea8d0, 0xea8d9}, + {0xea900, 0xea909}, {0xea9d0, 0xea9d9}, {0xea9f0, 0xea9f9}, {0xeaa50, 0xeaa59}, + {0xeabf0, 0xeabf9}, {0xeff10, 0xeff19}, {0xf0030, 0xf0039}, {0xf0660, 0xf0669}, + {0xf06f0, 0xf06f9}, {0xf07c0, 0xf07c9}, {0xf0966, 0xf096f}, {0xf09e6, 0xf09ef}, + {0xf0a66, 0xf0a6f}, {0xf0ae6, 0xf0aef}, {0xf0b66, 0xf0b6f}, {0xf0be6, 0xf0bef}, + {0xf0c66, 0xf0c6f}, {0xf0ce6, 0xf0cef}, {0xf0d66, 0xf0d6f}, {0xf0de6, 0xf0def}, + {0xf0e50, 0xf0e59}, {0xf0ed0, 0xf0ed9}, {0xf0f20, 0xf0f29}, {0xf1040, 0xf1049}, + {0xf1090, 0xf1099}, {0xf17e0, 0xf17e9}, {0xf1810, 0xf1819}, {0xf1946, 0xf194f}, + {0xf19d0, 0xf19d9}, {0xf1a80, 0xf1a89}, {0xf1a90, 0xf1a99}, {0xf1b50, 0xf1b59}, + {0xf1bb0, 0xf1bb9}, {0xf1c40, 0xf1c49}, {0xf1c50, 0xf1c59}, {0xfa620, 0xfa629}, + {0xfa8d0, 0xfa8d9}, {0xfa900, 0xfa909}, {0xfa9d0, 0xfa9d9}, {0xfa9f0, 0xfa9f9}, + {0xfaa50, 0xfaa59}, {0xfabf0, 0xfabf9}, {0xfff10, 0xfff19}, {0x100030, 0x100039}, + {0x100660, 0x100669}, {0x1006f0, 0x1006f9}, {0x1007c0, 0x1007c9}, {0x100966, 0x10096f}, + {0x1009e6, 0x1009ef}, {0x100a66, 0x100a6f}, {0x100ae6, 0x100aef}, {0x100b66, 0x100b6f}, + {0x100be6, 0x100bef}, {0x100c66, 0x100c6f}, {0x100ce6, 0x100cef}, {0x100d66, 0x100d6f}, + {0x100de6, 0x100def}, {0x100e50, 0x100e59}, {0x100ed0, 0x100ed9}, {0x100f20, 0x100f29}, + {0x101040, 0x101049}, {0x101090, 0x101099}, {0x1017e0, 0x1017e9}, {0x101810, 0x101819}, + {0x101946, 0x10194f}, {0x1019d0, 0x1019d9}, {0x101a80, 0x101a89}, {0x101a90, 0x101a99}, + {0x101b50, 0x101b59}, {0x101bb0, 0x101bb9}, {0x101c40, 0x101c49}, {0x101c50, 0x101c59}, + {0x10a620, 0x10a629}, {0x10a8d0, 0x10a8d9}, {0x10a900, 0x10a909}, {0x10a9d0, 0x10a9d9}, + {0x10a9f0, 0x10a9f9}, {0x10aa50, 0x10aa59}, {0x10abf0, 0x10abf9}, {0x10ff10, 0x10ff19} #endif }; @@ -345,18 +1815,225 @@ static const crange punctRangeTable[] = { {0x1b5a, 0x1b60}, {0x1bfc, 0x1bff}, {0x1c3b, 0x1c3f}, {0x1cc0, 0x1cc7}, {0x2010, 0x2027}, {0x2030, 0x2043}, {0x2045, 0x2051}, {0x2053, 0x205e}, {0x2308, 0x230b}, {0x2768, 0x2775}, {0x27e6, 0x27ef}, {0x2983, 0x2998}, - {0x29d8, 0x29db}, {0x2cf9, 0x2cfc}, {0x2e00, 0x2e2e}, {0x2e30, 0x2e44}, + {0x29d8, 0x29db}, {0x2cf9, 0x2cfc}, {0x2e00, 0x2e2e}, {0x2e30, 0x2e49}, {0x3001, 0x3003}, {0x3008, 0x3011}, {0x3014, 0x301f}, {0xa60d, 0xa60f}, {0xa6f2, 0xa6f7}, {0xa874, 0xa877}, {0xa8f8, 0xa8fa}, {0xa9c1, 0xa9cd}, {0xaa5c, 0xaa5f}, {0xfe10, 0xfe19}, {0xfe30, 0xfe52}, {0xfe54, 0xfe61}, {0xff01, 0xff03}, {0xff05, 0xff0a}, {0xff0c, 0xff0f}, {0xff3b, 0xff3d}, {0xff5f, 0xff65} #if TCL_UTF_MAX > 4 - ,{0x10100, 0x10102}, {0x10a50, 0x10a58}, {0x10af0, 0x10af6}, {0x10b39, 0x10b3f}, - {0x10b99, 0x10b9c}, {0x11047, 0x1104d}, {0x110be, 0x110c1}, {0x11140, 0x11143}, - {0x111c5, 0x111c9}, {0x111dd, 0x111df}, {0x11238, 0x1123d}, {0x1144b, 0x1144f}, - {0x115c1, 0x115d7}, {0x11641, 0x11643}, {0x11660, 0x1166c}, {0x1173c, 0x1173e}, - {0x11c41, 0x11c45}, {0x12470, 0x12474}, {0x16b37, 0x16b3b}, {0x1da87, 0x1da8b} + ,{0x10021, 0x10023}, {0x10025, 0x1002a}, {0x1002c, 0x1002f}, {0x1005b, 0x1005d}, + {0x1055a, 0x1055f}, {0x1066a, 0x1066d}, {0x10700, 0x1070d}, {0x107f7, 0x107f9}, + {0x10830, 0x1083e}, {0x10f04, 0x10f12}, {0x10f3a, 0x10f3d}, {0x10fd0, 0x10fd4}, + {0x1104a, 0x1104f}, {0x11360, 0x11368}, {0x116eb, 0x116ed}, {0x117d4, 0x117d6}, + {0x117d8, 0x117da}, {0x11800, 0x1180a}, {0x11aa0, 0x11aa6}, {0x11aa8, 0x11aad}, + {0x11b5a, 0x11b60}, {0x11bfc, 0x11bff}, {0x11c3b, 0x11c3f}, {0x11cc0, 0x11cc7}, + {0x12010, 0x12027}, {0x12030, 0x12043}, {0x12045, 0x12051}, {0x12053, 0x1205e}, + {0x12308, 0x1230b}, {0x12768, 0x12775}, {0x127e6, 0x127ef}, {0x12983, 0x12998}, + {0x129d8, 0x129db}, {0x12cf9, 0x12cfc}, {0x12e00, 0x12e2e}, {0x12e30, 0x12e49}, + {0x13001, 0x13003}, {0x13008, 0x13011}, {0x13014, 0x1301f}, {0x1a60d, 0x1a60f}, + {0x1a6f2, 0x1a6f7}, {0x1a874, 0x1a877}, {0x1a8f8, 0x1a8fa}, {0x1a9c1, 0x1a9cd}, + {0x1aa5c, 0x1aa5f}, {0x1fe10, 0x1fe19}, {0x1fe30, 0x1fe52}, {0x1fe54, 0x1fe61}, + {0x1ff01, 0x1ff03}, {0x1ff05, 0x1ff0a}, {0x1ff0c, 0x1ff0f}, {0x1ff3b, 0x1ff3d}, + {0x1ff5f, 0x1ff65}, {0x20021, 0x20023}, {0x20025, 0x2002a}, {0x2002c, 0x2002f}, + {0x2005b, 0x2005d}, {0x2055a, 0x2055f}, {0x2066a, 0x2066d}, {0x20700, 0x2070d}, + {0x207f7, 0x207f9}, {0x20830, 0x2083e}, {0x20f04, 0x20f12}, {0x20f3a, 0x20f3d}, + {0x20fd0, 0x20fd4}, {0x2104a, 0x2104f}, {0x21360, 0x21368}, {0x216eb, 0x216ed}, + {0x217d4, 0x217d6}, {0x217d8, 0x217da}, {0x21800, 0x2180a}, {0x21aa0, 0x21aa6}, + {0x21aa8, 0x21aad}, {0x21b5a, 0x21b60}, {0x21bfc, 0x21bff}, {0x21c3b, 0x21c3f}, + {0x21cc0, 0x21cc7}, {0x22010, 0x22027}, {0x22030, 0x22043}, {0x22045, 0x22051}, + {0x22053, 0x2205e}, {0x22308, 0x2230b}, {0x22768, 0x22775}, {0x227e6, 0x227ef}, + {0x22983, 0x22998}, {0x229d8, 0x229db}, {0x22cf9, 0x22cfc}, {0x22e00, 0x22e2e}, + {0x22e30, 0x22e49}, {0x23001, 0x23003}, {0x23008, 0x23011}, {0x23014, 0x2301f}, + {0x2a60d, 0x2a60f}, {0x2a6f2, 0x2a6f7}, {0x2a874, 0x2a877}, {0x2a8f8, 0x2a8fa}, + {0x2a9c1, 0x2a9cd}, {0x2aa5c, 0x2aa5f}, {0x2fe10, 0x2fe19}, {0x2fe30, 0x2fe52}, + {0x2fe54, 0x2fe61}, {0x2ff01, 0x2ff03}, {0x2ff05, 0x2ff0a}, {0x2ff0c, 0x2ff0f}, + {0x2ff3b, 0x2ff3d}, {0x2ff5f, 0x2ff65}, {0x30021, 0x30023}, {0x30025, 0x3002a}, + {0x3002c, 0x3002f}, {0x3005b, 0x3005d}, {0x3055a, 0x3055f}, {0x3066a, 0x3066d}, + {0x30700, 0x3070d}, {0x307f7, 0x307f9}, {0x30830, 0x3083e}, {0x30f04, 0x30f12}, + {0x30f3a, 0x30f3d}, {0x30fd0, 0x30fd4}, {0x3104a, 0x3104f}, {0x31360, 0x31368}, + {0x316eb, 0x316ed}, {0x317d4, 0x317d6}, {0x317d8, 0x317da}, {0x31800, 0x3180a}, + {0x31aa0, 0x31aa6}, {0x31aa8, 0x31aad}, {0x31b5a, 0x31b60}, {0x31bfc, 0x31bff}, + {0x31c3b, 0x31c3f}, {0x31cc0, 0x31cc7}, {0x32010, 0x32027}, {0x32030, 0x32043}, + {0x32045, 0x32051}, {0x32053, 0x3205e}, {0x32308, 0x3230b}, {0x32768, 0x32775}, + {0x327e6, 0x327ef}, {0x32983, 0x32998}, {0x329d8, 0x329db}, {0x32cf9, 0x32cfc}, + {0x32e00, 0x32e2e}, {0x32e30, 0x32e49}, {0x33001, 0x33003}, {0x33008, 0x33011}, + {0x33014, 0x3301f}, {0x3a60d, 0x3a60f}, {0x3a6f2, 0x3a6f7}, {0x3a874, 0x3a877}, + {0x3a8f8, 0x3a8fa}, {0x3a9c1, 0x3a9cd}, {0x3aa5c, 0x3aa5f}, {0x3fe10, 0x3fe19}, + {0x3fe30, 0x3fe52}, {0x3fe54, 0x3fe61}, {0x3ff01, 0x3ff03}, {0x3ff05, 0x3ff0a}, + {0x3ff0c, 0x3ff0f}, {0x3ff3b, 0x3ff3d}, {0x3ff5f, 0x3ff65}, {0x40021, 0x40023}, + {0x40025, 0x4002a}, {0x4002c, 0x4002f}, {0x4005b, 0x4005d}, {0x4055a, 0x4055f}, + {0x4066a, 0x4066d}, {0x40700, 0x4070d}, {0x407f7, 0x407f9}, {0x40830, 0x4083e}, + {0x40f04, 0x40f12}, {0x40f3a, 0x40f3d}, {0x40fd0, 0x40fd4}, {0x4104a, 0x4104f}, + {0x41360, 0x41368}, {0x416eb, 0x416ed}, {0x417d4, 0x417d6}, {0x417d8, 0x417da}, + {0x41800, 0x4180a}, {0x41aa0, 0x41aa6}, {0x41aa8, 0x41aad}, {0x41b5a, 0x41b60}, + {0x41bfc, 0x41bff}, {0x41c3b, 0x41c3f}, {0x41cc0, 0x41cc7}, {0x42010, 0x42027}, + {0x42030, 0x42043}, {0x42045, 0x42051}, {0x42053, 0x4205e}, {0x42308, 0x4230b}, + {0x42768, 0x42775}, {0x427e6, 0x427ef}, {0x42983, 0x42998}, {0x429d8, 0x429db}, + {0x42cf9, 0x42cfc}, {0x42e00, 0x42e2e}, {0x42e30, 0x42e49}, {0x43001, 0x43003}, + {0x43008, 0x43011}, {0x43014, 0x4301f}, {0x4a60d, 0x4a60f}, {0x4a6f2, 0x4a6f7}, + {0x4a874, 0x4a877}, {0x4a8f8, 0x4a8fa}, {0x4a9c1, 0x4a9cd}, {0x4aa5c, 0x4aa5f}, + {0x4fe10, 0x4fe19}, {0x4fe30, 0x4fe52}, {0x4fe54, 0x4fe61}, {0x4ff01, 0x4ff03}, + {0x4ff05, 0x4ff0a}, {0x4ff0c, 0x4ff0f}, {0x4ff3b, 0x4ff3d}, {0x4ff5f, 0x4ff65}, + {0x50021, 0x50023}, {0x50025, 0x5002a}, {0x5002c, 0x5002f}, {0x5005b, 0x5005d}, + {0x5055a, 0x5055f}, {0x5066a, 0x5066d}, {0x50700, 0x5070d}, {0x507f7, 0x507f9}, + {0x50830, 0x5083e}, {0x50f04, 0x50f12}, {0x50f3a, 0x50f3d}, {0x50fd0, 0x50fd4}, + {0x5104a, 0x5104f}, {0x51360, 0x51368}, {0x516eb, 0x516ed}, {0x517d4, 0x517d6}, + {0x517d8, 0x517da}, {0x51800, 0x5180a}, {0x51aa0, 0x51aa6}, {0x51aa8, 0x51aad}, + {0x51b5a, 0x51b60}, {0x51bfc, 0x51bff}, {0x51c3b, 0x51c3f}, {0x51cc0, 0x51cc7}, + {0x52010, 0x52027}, {0x52030, 0x52043}, {0x52045, 0x52051}, {0x52053, 0x5205e}, + {0x52308, 0x5230b}, {0x52768, 0x52775}, {0x527e6, 0x527ef}, {0x52983, 0x52998}, + {0x529d8, 0x529db}, {0x52cf9, 0x52cfc}, {0x52e00, 0x52e2e}, {0x52e30, 0x52e49}, + {0x53001, 0x53003}, {0x53008, 0x53011}, {0x53014, 0x5301f}, {0x5a60d, 0x5a60f}, + {0x5a6f2, 0x5a6f7}, {0x5a874, 0x5a877}, {0x5a8f8, 0x5a8fa}, {0x5a9c1, 0x5a9cd}, + {0x5aa5c, 0x5aa5f}, {0x5fe10, 0x5fe19}, {0x5fe30, 0x5fe52}, {0x5fe54, 0x5fe61}, + {0x5ff01, 0x5ff03}, {0x5ff05, 0x5ff0a}, {0x5ff0c, 0x5ff0f}, {0x5ff3b, 0x5ff3d}, + {0x5ff5f, 0x5ff65}, {0x60021, 0x60023}, {0x60025, 0x6002a}, {0x6002c, 0x6002f}, + {0x6005b, 0x6005d}, {0x6055a, 0x6055f}, {0x6066a, 0x6066d}, {0x60700, 0x6070d}, + {0x607f7, 0x607f9}, {0x60830, 0x6083e}, {0x60f04, 0x60f12}, {0x60f3a, 0x60f3d}, + {0x60fd0, 0x60fd4}, {0x6104a, 0x6104f}, {0x61360, 0x61368}, {0x616eb, 0x616ed}, + {0x617d4, 0x617d6}, {0x617d8, 0x617da}, {0x61800, 0x6180a}, {0x61aa0, 0x61aa6}, + {0x61aa8, 0x61aad}, {0x61b5a, 0x61b60}, {0x61bfc, 0x61bff}, {0x61c3b, 0x61c3f}, + {0x61cc0, 0x61cc7}, {0x62010, 0x62027}, {0x62030, 0x62043}, {0x62045, 0x62051}, + {0x62053, 0x6205e}, {0x62308, 0x6230b}, {0x62768, 0x62775}, {0x627e6, 0x627ef}, + {0x62983, 0x62998}, {0x629d8, 0x629db}, {0x62cf9, 0x62cfc}, {0x62e00, 0x62e2e}, + {0x62e30, 0x62e49}, {0x63001, 0x63003}, {0x63008, 0x63011}, {0x63014, 0x6301f}, + {0x6a60d, 0x6a60f}, {0x6a6f2, 0x6a6f7}, {0x6a874, 0x6a877}, {0x6a8f8, 0x6a8fa}, + {0x6a9c1, 0x6a9cd}, {0x6aa5c, 0x6aa5f}, {0x6fe10, 0x6fe19}, {0x6fe30, 0x6fe52}, + {0x6fe54, 0x6fe61}, {0x6ff01, 0x6ff03}, {0x6ff05, 0x6ff0a}, {0x6ff0c, 0x6ff0f}, + {0x6ff3b, 0x6ff3d}, {0x6ff5f, 0x6ff65}, {0x70021, 0x70023}, {0x70025, 0x7002a}, + {0x7002c, 0x7002f}, {0x7005b, 0x7005d}, {0x7055a, 0x7055f}, {0x7066a, 0x7066d}, + {0x70700, 0x7070d}, {0x707f7, 0x707f9}, {0x70830, 0x7083e}, {0x70f04, 0x70f12}, + {0x70f3a, 0x70f3d}, {0x70fd0, 0x70fd4}, {0x7104a, 0x7104f}, {0x71360, 0x71368}, + {0x716eb, 0x716ed}, {0x717d4, 0x717d6}, {0x717d8, 0x717da}, {0x71800, 0x7180a}, + {0x71aa0, 0x71aa6}, {0x71aa8, 0x71aad}, {0x71b5a, 0x71b60}, {0x71bfc, 0x71bff}, + {0x71c3b, 0x71c3f}, {0x71cc0, 0x71cc7}, {0x72010, 0x72027}, {0x72030, 0x72043}, + {0x72045, 0x72051}, {0x72053, 0x7205e}, {0x72308, 0x7230b}, {0x72768, 0x72775}, + {0x727e6, 0x727ef}, {0x72983, 0x72998}, {0x729d8, 0x729db}, {0x72cf9, 0x72cfc}, + {0x72e00, 0x72e2e}, {0x72e30, 0x72e49}, {0x73001, 0x73003}, {0x73008, 0x73011}, + {0x73014, 0x7301f}, {0x7a60d, 0x7a60f}, {0x7a6f2, 0x7a6f7}, {0x7a874, 0x7a877}, + {0x7a8f8, 0x7a8fa}, {0x7a9c1, 0x7a9cd}, {0x7aa5c, 0x7aa5f}, {0x7fe10, 0x7fe19}, + {0x7fe30, 0x7fe52}, {0x7fe54, 0x7fe61}, {0x7ff01, 0x7ff03}, {0x7ff05, 0x7ff0a}, + {0x7ff0c, 0x7ff0f}, {0x7ff3b, 0x7ff3d}, {0x7ff5f, 0x7ff65}, {0x80021, 0x80023}, + {0x80025, 0x8002a}, {0x8002c, 0x8002f}, {0x8005b, 0x8005d}, {0x8055a, 0x8055f}, + {0x8066a, 0x8066d}, {0x80700, 0x8070d}, {0x807f7, 0x807f9}, {0x80830, 0x8083e}, + {0x80f04, 0x80f12}, {0x80f3a, 0x80f3d}, {0x80fd0, 0x80fd4}, {0x8104a, 0x8104f}, + {0x81360, 0x81368}, {0x816eb, 0x816ed}, {0x817d4, 0x817d6}, {0x817d8, 0x817da}, + {0x81800, 0x8180a}, {0x81aa0, 0x81aa6}, {0x81aa8, 0x81aad}, {0x81b5a, 0x81b60}, + {0x81bfc, 0x81bff}, {0x81c3b, 0x81c3f}, {0x81cc0, 0x81cc7}, {0x82010, 0x82027}, + {0x82030, 0x82043}, {0x82045, 0x82051}, {0x82053, 0x8205e}, {0x82308, 0x8230b}, + {0x82768, 0x82775}, {0x827e6, 0x827ef}, {0x82983, 0x82998}, {0x829d8, 0x829db}, + {0x82cf9, 0x82cfc}, {0x82e00, 0x82e2e}, {0x82e30, 0x82e49}, {0x83001, 0x83003}, + {0x83008, 0x83011}, {0x83014, 0x8301f}, {0x8a60d, 0x8a60f}, {0x8a6f2, 0x8a6f7}, + {0x8a874, 0x8a877}, {0x8a8f8, 0x8a8fa}, {0x8a9c1, 0x8a9cd}, {0x8aa5c, 0x8aa5f}, + {0x8fe10, 0x8fe19}, {0x8fe30, 0x8fe52}, {0x8fe54, 0x8fe61}, {0x8ff01, 0x8ff03}, + {0x8ff05, 0x8ff0a}, {0x8ff0c, 0x8ff0f}, {0x8ff3b, 0x8ff3d}, {0x8ff5f, 0x8ff65}, + {0x90021, 0x90023}, {0x90025, 0x9002a}, {0x9002c, 0x9002f}, {0x9005b, 0x9005d}, + {0x9055a, 0x9055f}, {0x9066a, 0x9066d}, {0x90700, 0x9070d}, {0x907f7, 0x907f9}, + {0x90830, 0x9083e}, {0x90f04, 0x90f12}, {0x90f3a, 0x90f3d}, {0x90fd0, 0x90fd4}, + {0x9104a, 0x9104f}, {0x91360, 0x91368}, {0x916eb, 0x916ed}, {0x917d4, 0x917d6}, + {0x917d8, 0x917da}, {0x91800, 0x9180a}, {0x91aa0, 0x91aa6}, {0x91aa8, 0x91aad}, + {0x91b5a, 0x91b60}, {0x91bfc, 0x91bff}, {0x91c3b, 0x91c3f}, {0x91cc0, 0x91cc7}, + {0x92010, 0x92027}, {0x92030, 0x92043}, {0x92045, 0x92051}, {0x92053, 0x9205e}, + {0x92308, 0x9230b}, {0x92768, 0x92775}, {0x927e6, 0x927ef}, {0x92983, 0x92998}, + {0x929d8, 0x929db}, {0x92cf9, 0x92cfc}, {0x92e00, 0x92e2e}, {0x92e30, 0x92e49}, + {0x93001, 0x93003}, {0x93008, 0x93011}, {0x93014, 0x9301f}, {0x9a60d, 0x9a60f}, + {0x9a6f2, 0x9a6f7}, {0x9a874, 0x9a877}, {0x9a8f8, 0x9a8fa}, {0x9a9c1, 0x9a9cd}, + {0x9aa5c, 0x9aa5f}, {0x9fe10, 0x9fe19}, {0x9fe30, 0x9fe52}, {0x9fe54, 0x9fe61}, + {0x9ff01, 0x9ff03}, {0x9ff05, 0x9ff0a}, {0x9ff0c, 0x9ff0f}, {0x9ff3b, 0x9ff3d}, + {0x9ff5f, 0x9ff65}, {0xa0021, 0xa0023}, {0xa0025, 0xa002a}, {0xa002c, 0xa002f}, + {0xa005b, 0xa005d}, {0xa055a, 0xa055f}, {0xa066a, 0xa066d}, {0xa0700, 0xa070d}, + {0xa07f7, 0xa07f9}, {0xa0830, 0xa083e}, {0xa0f04, 0xa0f12}, {0xa0f3a, 0xa0f3d}, + {0xa0fd0, 0xa0fd4}, {0xa104a, 0xa104f}, {0xa1360, 0xa1368}, {0xa16eb, 0xa16ed}, + {0xa17d4, 0xa17d6}, {0xa17d8, 0xa17da}, {0xa1800, 0xa180a}, {0xa1aa0, 0xa1aa6}, + {0xa1aa8, 0xa1aad}, {0xa1b5a, 0xa1b60}, {0xa1bfc, 0xa1bff}, {0xa1c3b, 0xa1c3f}, + {0xa1cc0, 0xa1cc7}, {0xa2010, 0xa2027}, {0xa2030, 0xa2043}, {0xa2045, 0xa2051}, + {0xa2053, 0xa205e}, {0xa2308, 0xa230b}, {0xa2768, 0xa2775}, {0xa27e6, 0xa27ef}, + {0xa2983, 0xa2998}, {0xa29d8, 0xa29db}, {0xa2cf9, 0xa2cfc}, {0xa2e00, 0xa2e2e}, + {0xa2e30, 0xa2e49}, {0xa3001, 0xa3003}, {0xa3008, 0xa3011}, {0xa3014, 0xa301f}, + {0xaa60d, 0xaa60f}, {0xaa6f2, 0xaa6f7}, {0xaa874, 0xaa877}, {0xaa8f8, 0xaa8fa}, + {0xaa9c1, 0xaa9cd}, {0xaaa5c, 0xaaa5f}, {0xafe10, 0xafe19}, {0xafe30, 0xafe52}, + {0xafe54, 0xafe61}, {0xaff01, 0xaff03}, {0xaff05, 0xaff0a}, {0xaff0c, 0xaff0f}, + {0xaff3b, 0xaff3d}, {0xaff5f, 0xaff65}, {0xb0021, 0xb0023}, {0xb0025, 0xb002a}, + {0xb002c, 0xb002f}, {0xb005b, 0xb005d}, {0xb055a, 0xb055f}, {0xb066a, 0xb066d}, + {0xb0700, 0xb070d}, {0xb07f7, 0xb07f9}, {0xb0830, 0xb083e}, {0xb0f04, 0xb0f12}, + {0xb0f3a, 0xb0f3d}, {0xb0fd0, 0xb0fd4}, {0xb104a, 0xb104f}, {0xb1360, 0xb1368}, + {0xb16eb, 0xb16ed}, {0xb17d4, 0xb17d6}, {0xb17d8, 0xb17da}, {0xb1800, 0xb180a}, + {0xb1aa0, 0xb1aa6}, {0xb1aa8, 0xb1aad}, {0xb1b5a, 0xb1b60}, {0xb1bfc, 0xb1bff}, + {0xb1c3b, 0xb1c3f}, {0xb1cc0, 0xb1cc7}, {0xb2010, 0xb2027}, {0xb2030, 0xb2043}, + {0xb2045, 0xb2051}, {0xb2053, 0xb205e}, {0xb2308, 0xb230b}, {0xb2768, 0xb2775}, + {0xb27e6, 0xb27ef}, {0xb2983, 0xb2998}, {0xb29d8, 0xb29db}, {0xb2cf9, 0xb2cfc}, + {0xb2e00, 0xb2e2e}, {0xb2e30, 0xb2e49}, {0xb3001, 0xb3003}, {0xb3008, 0xb3011}, + {0xb3014, 0xb301f}, {0xba60d, 0xba60f}, {0xba6f2, 0xba6f7}, {0xba874, 0xba877}, + {0xba8f8, 0xba8fa}, {0xba9c1, 0xba9cd}, {0xbaa5c, 0xbaa5f}, {0xbfe10, 0xbfe19}, + {0xbfe30, 0xbfe52}, {0xbfe54, 0xbfe61}, {0xbff01, 0xbff03}, {0xbff05, 0xbff0a}, + {0xbff0c, 0xbff0f}, {0xbff3b, 0xbff3d}, {0xbff5f, 0xbff65}, {0xc0021, 0xc0023}, + {0xc0025, 0xc002a}, {0xc002c, 0xc002f}, {0xc005b, 0xc005d}, {0xc055a, 0xc055f}, + {0xc066a, 0xc066d}, {0xc0700, 0xc070d}, {0xc07f7, 0xc07f9}, {0xc0830, 0xc083e}, + {0xc0f04, 0xc0f12}, {0xc0f3a, 0xc0f3d}, {0xc0fd0, 0xc0fd4}, {0xc104a, 0xc104f}, + {0xc1360, 0xc1368}, {0xc16eb, 0xc16ed}, {0xc17d4, 0xc17d6}, {0xc17d8, 0xc17da}, + {0xc1800, 0xc180a}, {0xc1aa0, 0xc1aa6}, {0xc1aa8, 0xc1aad}, {0xc1b5a, 0xc1b60}, + {0xc1bfc, 0xc1bff}, {0xc1c3b, 0xc1c3f}, {0xc1cc0, 0xc1cc7}, {0xc2010, 0xc2027}, + {0xc2030, 0xc2043}, {0xc2045, 0xc2051}, {0xc2053, 0xc205e}, {0xc2308, 0xc230b}, + {0xc2768, 0xc2775}, {0xc27e6, 0xc27ef}, {0xc2983, 0xc2998}, {0xc29d8, 0xc29db}, + {0xc2cf9, 0xc2cfc}, {0xc2e00, 0xc2e2e}, {0xc2e30, 0xc2e49}, {0xc3001, 0xc3003}, + {0xc3008, 0xc3011}, {0xc3014, 0xc301f}, {0xca60d, 0xca60f}, {0xca6f2, 0xca6f7}, + {0xca874, 0xca877}, {0xca8f8, 0xca8fa}, {0xca9c1, 0xca9cd}, {0xcaa5c, 0xcaa5f}, + {0xcfe10, 0xcfe19}, {0xcfe30, 0xcfe52}, {0xcfe54, 0xcfe61}, {0xcff01, 0xcff03}, + {0xcff05, 0xcff0a}, {0xcff0c, 0xcff0f}, {0xcff3b, 0xcff3d}, {0xcff5f, 0xcff65}, + {0xd0021, 0xd0023}, {0xd0025, 0xd002a}, {0xd002c, 0xd002f}, {0xd005b, 0xd005d}, + {0xd055a, 0xd055f}, {0xd066a, 0xd066d}, {0xd0700, 0xd070d}, {0xd07f7, 0xd07f9}, + {0xd0830, 0xd083e}, {0xd0f04, 0xd0f12}, {0xd0f3a, 0xd0f3d}, {0xd0fd0, 0xd0fd4}, + {0xd104a, 0xd104f}, {0xd1360, 0xd1368}, {0xd16eb, 0xd16ed}, {0xd17d4, 0xd17d6}, + {0xd17d8, 0xd17da}, {0xd1800, 0xd180a}, {0xd1aa0, 0xd1aa6}, {0xd1aa8, 0xd1aad}, + {0xd1b5a, 0xd1b60}, {0xd1bfc, 0xd1bff}, {0xd1c3b, 0xd1c3f}, {0xd1cc0, 0xd1cc7}, + {0xd2010, 0xd2027}, {0xd2030, 0xd2043}, {0xd2045, 0xd2051}, {0xd2053, 0xd205e}, + {0xd2308, 0xd230b}, {0xd2768, 0xd2775}, {0xd27e6, 0xd27ef}, {0xd2983, 0xd2998}, + {0xd29d8, 0xd29db}, {0xd2cf9, 0xd2cfc}, {0xd2e00, 0xd2e2e}, {0xd2e30, 0xd2e49}, + {0xd3001, 0xd3003}, {0xd3008, 0xd3011}, {0xd3014, 0xd301f}, {0xda60d, 0xda60f}, + {0xda6f2, 0xda6f7}, {0xda874, 0xda877}, {0xda8f8, 0xda8fa}, {0xda9c1, 0xda9cd}, + {0xdaa5c, 0xdaa5f}, {0xdfe10, 0xdfe19}, {0xdfe30, 0xdfe52}, {0xdfe54, 0xdfe61}, + {0xdff01, 0xdff03}, {0xdff05, 0xdff0a}, {0xdff0c, 0xdff0f}, {0xdff3b, 0xdff3d}, + {0xdff5f, 0xdff65}, {0xe0021, 0xe0023}, {0xe0025, 0xe002a}, {0xe002c, 0xe002f}, + {0xe005b, 0xe005d}, {0xe055a, 0xe055f}, {0xe066a, 0xe066d}, {0xe0700, 0xe070d}, + {0xe07f7, 0xe07f9}, {0xe0830, 0xe083e}, {0xe0f04, 0xe0f12}, {0xe0f3a, 0xe0f3d}, + {0xe0fd0, 0xe0fd4}, {0xe104a, 0xe104f}, {0xe1360, 0xe1368}, {0xe16eb, 0xe16ed}, + {0xe17d4, 0xe17d6}, {0xe17d8, 0xe17da}, {0xe1800, 0xe180a}, {0xe1aa0, 0xe1aa6}, + {0xe1aa8, 0xe1aad}, {0xe1b5a, 0xe1b60}, {0xe1bfc, 0xe1bff}, {0xe1c3b, 0xe1c3f}, + {0xe1cc0, 0xe1cc7}, {0xe2010, 0xe2027}, {0xe2030, 0xe2043}, {0xe2045, 0xe2051}, + {0xe2053, 0xe205e}, {0xe2308, 0xe230b}, {0xe2768, 0xe2775}, {0xe27e6, 0xe27ef}, + {0xe2983, 0xe2998}, {0xe29d8, 0xe29db}, {0xe2cf9, 0xe2cfc}, {0xe2e00, 0xe2e2e}, + {0xe2e30, 0xe2e49}, {0xe3001, 0xe3003}, {0xe3008, 0xe3011}, {0xe3014, 0xe301f}, + {0xea60d, 0xea60f}, {0xea6f2, 0xea6f7}, {0xea874, 0xea877}, {0xea8f8, 0xea8fa}, + {0xea9c1, 0xea9cd}, {0xeaa5c, 0xeaa5f}, {0xefe10, 0xefe19}, {0xefe30, 0xefe52}, + {0xefe54, 0xefe61}, {0xeff01, 0xeff03}, {0xeff05, 0xeff0a}, {0xeff0c, 0xeff0f}, + {0xeff3b, 0xeff3d}, {0xeff5f, 0xeff65}, {0xf0021, 0xf0023}, {0xf0025, 0xf002a}, + {0xf002c, 0xf002f}, {0xf005b, 0xf005d}, {0xf055a, 0xf055f}, {0xf066a, 0xf066d}, + {0xf0700, 0xf070d}, {0xf07f7, 0xf07f9}, {0xf0830, 0xf083e}, {0xf0f04, 0xf0f12}, + {0xf0f3a, 0xf0f3d}, {0xf0fd0, 0xf0fd4}, {0xf104a, 0xf104f}, {0xf1360, 0xf1368}, + {0xf16eb, 0xf16ed}, {0xf17d4, 0xf17d6}, {0xf17d8, 0xf17da}, {0xf1800, 0xf180a}, + {0xf1aa0, 0xf1aa6}, {0xf1aa8, 0xf1aad}, {0xf1b5a, 0xf1b60}, {0xf1bfc, 0xf1bff}, + {0xf1c3b, 0xf1c3f}, {0xf1cc0, 0xf1cc7}, {0xf2010, 0xf2027}, {0xf2030, 0xf2043}, + {0xf2045, 0xf2051}, {0xf2053, 0xf205e}, {0xf2308, 0xf230b}, {0xf2768, 0xf2775}, + {0xf27e6, 0xf27ef}, {0xf2983, 0xf2998}, {0xf29d8, 0xf29db}, {0xf2cf9, 0xf2cfc}, + {0xf2e00, 0xf2e2e}, {0xf2e30, 0xf2e49}, {0xf3001, 0xf3003}, {0xf3008, 0xf3011}, + {0xf3014, 0xf301f}, {0xfa60d, 0xfa60f}, {0xfa6f2, 0xfa6f7}, {0xfa874, 0xfa877}, + {0xfa8f8, 0xfa8fa}, {0xfa9c1, 0xfa9cd}, {0xfaa5c, 0xfaa5f}, {0xffe10, 0xffe19}, + {0xffe30, 0xffe52}, {0xffe54, 0xffe61}, {0xfff01, 0xfff03}, {0xfff05, 0xfff0a}, + {0xfff0c, 0xfff0f}, {0xfff3b, 0xfff3d}, {0xfff5f, 0xfff65}, {0x100021, 0x100023}, + {0x100025, 0x10002a}, {0x10002c, 0x10002f}, {0x10005b, 0x10005d}, {0x10055a, 0x10055f}, + {0x10066a, 0x10066d}, {0x100700, 0x10070d}, {0x1007f7, 0x1007f9}, {0x100830, 0x10083e}, + {0x100f04, 0x100f12}, {0x100f3a, 0x100f3d}, {0x100fd0, 0x100fd4}, {0x10104a, 0x10104f}, + {0x101360, 0x101368}, {0x1016eb, 0x1016ed}, {0x1017d4, 0x1017d6}, {0x1017d8, 0x1017da}, + {0x101800, 0x10180a}, {0x101aa0, 0x101aa6}, {0x101aa8, 0x101aad}, {0x101b5a, 0x101b60}, + {0x101bfc, 0x101bff}, {0x101c3b, 0x101c3f}, {0x101cc0, 0x101cc7}, {0x102010, 0x102027}, + {0x102030, 0x102043}, {0x102045, 0x102051}, {0x102053, 0x10205e}, {0x102308, 0x10230b}, + {0x102768, 0x102775}, {0x1027e6, 0x1027ef}, {0x102983, 0x102998}, {0x1029d8, 0x1029db}, + {0x102cf9, 0x102cfc}, {0x102e00, 0x102e2e}, {0x102e30, 0x102e49}, {0x103001, 0x103003}, + {0x103008, 0x103011}, {0x103014, 0x10301f}, {0x10a60d, 0x10a60f}, {0x10a6f2, 0x10a6f7}, + {0x10a874, 0x10a877}, {0x10a8f8, 0x10a8fa}, {0x10a9c1, 0x10a9cd}, {0x10aa5c, 0x10aa5f}, + {0x10fe10, 0x10fe19}, {0x10fe30, 0x10fe52}, {0x10fe54, 0x10fe61}, {0x10ff01, 0x10ff03}, + {0x10ff05, 0x10ff0a}, {0x10ff0c, 0x10ff0f}, {0x10ff3b, 0x10ff3d}, {0x10ff5f, 0x10ff65} #endif }; @@ -367,18 +2044,207 @@ static const chr punctCharTable[] = { 0xab, 0xb6, 0xb7, 0xbb, 0xbf, 0x37e, 0x387, 0x589, 0x58a, 0x5be, 0x5c0, 0x5c3, 0x5c6, 0x5f3, 0x5f4, 0x609, 0x60a, 0x60c, 0x60d, 0x61b, 0x61e, 0x61f, 0x6d4, 0x85e, 0x964, 0x965, 0x970, - 0xaf0, 0xdf4, 0xe4f, 0xe5a, 0xe5b, 0xf14, 0xf85, 0xfd9, 0xfda, - 0x10fb, 0x1400, 0x166d, 0x166e, 0x169b, 0x169c, 0x1735, 0x1736, 0x1944, - 0x1945, 0x1a1e, 0x1a1f, 0x1c7e, 0x1c7f, 0x1cd3, 0x207d, 0x207e, 0x208d, - 0x208e, 0x2329, 0x232a, 0x27c5, 0x27c6, 0x29fc, 0x29fd, 0x2cfe, 0x2cff, - 0x2d70, 0x3030, 0x303d, 0x30a0, 0x30fb, 0xa4fe, 0xa4ff, 0xa673, 0xa67e, - 0xa8ce, 0xa8cf, 0xa8fc, 0xa92e, 0xa92f, 0xa95f, 0xa9de, 0xa9df, 0xaade, - 0xaadf, 0xaaf0, 0xaaf1, 0xabeb, 0xfd3e, 0xfd3f, 0xfe63, 0xfe68, 0xfe6a, - 0xfe6b, 0xff1a, 0xff1b, 0xff1f, 0xff20, 0xff3f, 0xff5b, 0xff5d + 0x9fd, 0xaf0, 0xdf4, 0xe4f, 0xe5a, 0xe5b, 0xf14, 0xf85, 0xfd9, + 0xfda, 0x10fb, 0x1400, 0x166d, 0x166e, 0x169b, 0x169c, 0x1735, 0x1736, + 0x1944, 0x1945, 0x1a1e, 0x1a1f, 0x1c7e, 0x1c7f, 0x1cd3, 0x207d, 0x207e, + 0x208d, 0x208e, 0x2329, 0x232a, 0x27c5, 0x27c6, 0x29fc, 0x29fd, 0x2cfe, + 0x2cff, 0x2d70, 0x3030, 0x303d, 0x30a0, 0x30fb, 0xa4fe, 0xa4ff, 0xa673, + 0xa67e, 0xa8ce, 0xa8cf, 0xa8fc, 0xa92e, 0xa92f, 0xa95f, 0xa9de, 0xa9df, + 0xaade, 0xaadf, 0xaaf0, 0xaaf1, 0xabeb, 0xfd3e, 0xfd3f, 0xfe63, 0xfe68, + 0xfe6a, 0xfe6b, 0xff1a, 0xff1b, 0xff1f, 0xff20, 0xff3f, 0xff5b, 0xff5d #if TCL_UTF_MAX > 4 - ,0x1039f, 0x103d0, 0x1056f, 0x10857, 0x1091f, 0x1093f, 0x10a7f, 0x110bb, 0x110bc, - 0x11174, 0x11175, 0x111cd, 0x111db, 0x112a9, 0x1145b, 0x1145d, 0x114c6, 0x11c70, - 0x11c71, 0x16a6e, 0x16a6f, 0x16af5, 0x16b44, 0x1bc9f, 0x1e95e, 0x1e95f + ,0x1003a, 0x1003b, 0x1003f, 0x10040, 0x1005f, 0x1007b, 0x1007d, 0x100a1, 0x100a7, + 0x100ab, 0x100b6, 0x100b7, 0x100bb, 0x100bf, 0x1037e, 0x10387, 0x10589, 0x1058a, + 0x105be, 0x105c0, 0x105c3, 0x105c6, 0x105f3, 0x105f4, 0x10609, 0x1060a, 0x1060c, + 0x1060d, 0x1061b, 0x1061e, 0x1061f, 0x106d4, 0x1085e, 0x10964, 0x10965, 0x10970, + 0x109fd, 0x10af0, 0x10df4, 0x10e4f, 0x10e5a, 0x10e5b, 0x10f14, 0x10f85, 0x10fd9, + 0x10fda, 0x110fb, 0x11400, 0x1166d, 0x1166e, 0x1169b, 0x1169c, 0x11735, 0x11736, + 0x11944, 0x11945, 0x11a1e, 0x11a1f, 0x11c7e, 0x11c7f, 0x11cd3, 0x1207d, 0x1207e, + 0x1208d, 0x1208e, 0x12329, 0x1232a, 0x127c5, 0x127c6, 0x129fc, 0x129fd, 0x12cfe, + 0x12cff, 0x12d70, 0x13030, 0x1303d, 0x130a0, 0x130fb, 0x1a4fe, 0x1a4ff, 0x1a673, + 0x1a67e, 0x1a8ce, 0x1a8cf, 0x1a8fc, 0x1a92e, 0x1a92f, 0x1a95f, 0x1a9de, 0x1a9df, + 0x1aade, 0x1aadf, 0x1aaf0, 0x1aaf1, 0x1abeb, 0x1fd3e, 0x1fd3f, 0x1fe63, 0x1fe68, + 0x1fe6a, 0x1fe6b, 0x1ff1a, 0x1ff1b, 0x1ff1f, 0x1ff20, 0x1ff3f, 0x1ff5b, 0x1ff5d, + 0x2003a, 0x2003b, 0x2003f, 0x20040, 0x2005f, 0x2007b, 0x2007d, 0x200a1, 0x200a7, + 0x200ab, 0x200b6, 0x200b7, 0x200bb, 0x200bf, 0x2037e, 0x20387, 0x20589, 0x2058a, + 0x205be, 0x205c0, 0x205c3, 0x205c6, 0x205f3, 0x205f4, 0x20609, 0x2060a, 0x2060c, + 0x2060d, 0x2061b, 0x2061e, 0x2061f, 0x206d4, 0x2085e, 0x20964, 0x20965, 0x20970, + 0x209fd, 0x20af0, 0x20df4, 0x20e4f, 0x20e5a, 0x20e5b, 0x20f14, 0x20f85, 0x20fd9, + 0x20fda, 0x210fb, 0x21400, 0x2166d, 0x2166e, 0x2169b, 0x2169c, 0x21735, 0x21736, + 0x21944, 0x21945, 0x21a1e, 0x21a1f, 0x21c7e, 0x21c7f, 0x21cd3, 0x2207d, 0x2207e, + 0x2208d, 0x2208e, 0x22329, 0x2232a, 0x227c5, 0x227c6, 0x229fc, 0x229fd, 0x22cfe, + 0x22cff, 0x22d70, 0x23030, 0x2303d, 0x230a0, 0x230fb, 0x2a4fe, 0x2a4ff, 0x2a673, + 0x2a67e, 0x2a8ce, 0x2a8cf, 0x2a8fc, 0x2a92e, 0x2a92f, 0x2a95f, 0x2a9de, 0x2a9df, + 0x2aade, 0x2aadf, 0x2aaf0, 0x2aaf1, 0x2abeb, 0x2fd3e, 0x2fd3f, 0x2fe63, 0x2fe68, + 0x2fe6a, 0x2fe6b, 0x2ff1a, 0x2ff1b, 0x2ff1f, 0x2ff20, 0x2ff3f, 0x2ff5b, 0x2ff5d, + 0x3003a, 0x3003b, 0x3003f, 0x30040, 0x3005f, 0x3007b, 0x3007d, 0x300a1, 0x300a7, + 0x300ab, 0x300b6, 0x300b7, 0x300bb, 0x300bf, 0x3037e, 0x30387, 0x30589, 0x3058a, + 0x305be, 0x305c0, 0x305c3, 0x305c6, 0x305f3, 0x305f4, 0x30609, 0x3060a, 0x3060c, + 0x3060d, 0x3061b, 0x3061e, 0x3061f, 0x306d4, 0x3085e, 0x30964, 0x30965, 0x30970, + 0x309fd, 0x30af0, 0x30df4, 0x30e4f, 0x30e5a, 0x30e5b, 0x30f14, 0x30f85, 0x30fd9, + 0x30fda, 0x310fb, 0x31400, 0x3166d, 0x3166e, 0x3169b, 0x3169c, 0x31735, 0x31736, + 0x31944, 0x31945, 0x31a1e, 0x31a1f, 0x31c7e, 0x31c7f, 0x31cd3, 0x3207d, 0x3207e, + 0x3208d, 0x3208e, 0x32329, 0x3232a, 0x327c5, 0x327c6, 0x329fc, 0x329fd, 0x32cfe, + 0x32cff, 0x32d70, 0x33030, 0x3303d, 0x330a0, 0x330fb, 0x3a4fe, 0x3a4ff, 0x3a673, + 0x3a67e, 0x3a8ce, 0x3a8cf, 0x3a8fc, 0x3a92e, 0x3a92f, 0x3a95f, 0x3a9de, 0x3a9df, + 0x3aade, 0x3aadf, 0x3aaf0, 0x3aaf1, 0x3abeb, 0x3fd3e, 0x3fd3f, 0x3fe63, 0x3fe68, + 0x3fe6a, 0x3fe6b, 0x3ff1a, 0x3ff1b, 0x3ff1f, 0x3ff20, 0x3ff3f, 0x3ff5b, 0x3ff5d, + 0x4003a, 0x4003b, 0x4003f, 0x40040, 0x4005f, 0x4007b, 0x4007d, 0x400a1, 0x400a7, + 0x400ab, 0x400b6, 0x400b7, 0x400bb, 0x400bf, 0x4037e, 0x40387, 0x40589, 0x4058a, + 0x405be, 0x405c0, 0x405c3, 0x405c6, 0x405f3, 0x405f4, 0x40609, 0x4060a, 0x4060c, + 0x4060d, 0x4061b, 0x4061e, 0x4061f, 0x406d4, 0x4085e, 0x40964, 0x40965, 0x40970, + 0x409fd, 0x40af0, 0x40df4, 0x40e4f, 0x40e5a, 0x40e5b, 0x40f14, 0x40f85, 0x40fd9, + 0x40fda, 0x410fb, 0x41400, 0x4166d, 0x4166e, 0x4169b, 0x4169c, 0x41735, 0x41736, + 0x41944, 0x41945, 0x41a1e, 0x41a1f, 0x41c7e, 0x41c7f, 0x41cd3, 0x4207d, 0x4207e, + 0x4208d, 0x4208e, 0x42329, 0x4232a, 0x427c5, 0x427c6, 0x429fc, 0x429fd, 0x42cfe, + 0x42cff, 0x42d70, 0x43030, 0x4303d, 0x430a0, 0x430fb, 0x4a4fe, 0x4a4ff, 0x4a673, + 0x4a67e, 0x4a8ce, 0x4a8cf, 0x4a8fc, 0x4a92e, 0x4a92f, 0x4a95f, 0x4a9de, 0x4a9df, + 0x4aade, 0x4aadf, 0x4aaf0, 0x4aaf1, 0x4abeb, 0x4fd3e, 0x4fd3f, 0x4fe63, 0x4fe68, + 0x4fe6a, 0x4fe6b, 0x4ff1a, 0x4ff1b, 0x4ff1f, 0x4ff20, 0x4ff3f, 0x4ff5b, 0x4ff5d, + 0x5003a, 0x5003b, 0x5003f, 0x50040, 0x5005f, 0x5007b, 0x5007d, 0x500a1, 0x500a7, + 0x500ab, 0x500b6, 0x500b7, 0x500bb, 0x500bf, 0x5037e, 0x50387, 0x50589, 0x5058a, + 0x505be, 0x505c0, 0x505c3, 0x505c6, 0x505f3, 0x505f4, 0x50609, 0x5060a, 0x5060c, + 0x5060d, 0x5061b, 0x5061e, 0x5061f, 0x506d4, 0x5085e, 0x50964, 0x50965, 0x50970, + 0x509fd, 0x50af0, 0x50df4, 0x50e4f, 0x50e5a, 0x50e5b, 0x50f14, 0x50f85, 0x50fd9, + 0x50fda, 0x510fb, 0x51400, 0x5166d, 0x5166e, 0x5169b, 0x5169c, 0x51735, 0x51736, + 0x51944, 0x51945, 0x51a1e, 0x51a1f, 0x51c7e, 0x51c7f, 0x51cd3, 0x5207d, 0x5207e, + 0x5208d, 0x5208e, 0x52329, 0x5232a, 0x527c5, 0x527c6, 0x529fc, 0x529fd, 0x52cfe, + 0x52cff, 0x52d70, 0x53030, 0x5303d, 0x530a0, 0x530fb, 0x5a4fe, 0x5a4ff, 0x5a673, + 0x5a67e, 0x5a8ce, 0x5a8cf, 0x5a8fc, 0x5a92e, 0x5a92f, 0x5a95f, 0x5a9de, 0x5a9df, + 0x5aade, 0x5aadf, 0x5aaf0, 0x5aaf1, 0x5abeb, 0x5fd3e, 0x5fd3f, 0x5fe63, 0x5fe68, + 0x5fe6a, 0x5fe6b, 0x5ff1a, 0x5ff1b, 0x5ff1f, 0x5ff20, 0x5ff3f, 0x5ff5b, 0x5ff5d, + 0x6003a, 0x6003b, 0x6003f, 0x60040, 0x6005f, 0x6007b, 0x6007d, 0x600a1, 0x600a7, + 0x600ab, 0x600b6, 0x600b7, 0x600bb, 0x600bf, 0x6037e, 0x60387, 0x60589, 0x6058a, + 0x605be, 0x605c0, 0x605c3, 0x605c6, 0x605f3, 0x605f4, 0x60609, 0x6060a, 0x6060c, + 0x6060d, 0x6061b, 0x6061e, 0x6061f, 0x606d4, 0x6085e, 0x60964, 0x60965, 0x60970, + 0x609fd, 0x60af0, 0x60df4, 0x60e4f, 0x60e5a, 0x60e5b, 0x60f14, 0x60f85, 0x60fd9, + 0x60fda, 0x610fb, 0x61400, 0x6166d, 0x6166e, 0x6169b, 0x6169c, 0x61735, 0x61736, + 0x61944, 0x61945, 0x61a1e, 0x61a1f, 0x61c7e, 0x61c7f, 0x61cd3, 0x6207d, 0x6207e, + 0x6208d, 0x6208e, 0x62329, 0x6232a, 0x627c5, 0x627c6, 0x629fc, 0x629fd, 0x62cfe, + 0x62cff, 0x62d70, 0x63030, 0x6303d, 0x630a0, 0x630fb, 0x6a4fe, 0x6a4ff, 0x6a673, + 0x6a67e, 0x6a8ce, 0x6a8cf, 0x6a8fc, 0x6a92e, 0x6a92f, 0x6a95f, 0x6a9de, 0x6a9df, + 0x6aade, 0x6aadf, 0x6aaf0, 0x6aaf1, 0x6abeb, 0x6fd3e, 0x6fd3f, 0x6fe63, 0x6fe68, + 0x6fe6a, 0x6fe6b, 0x6ff1a, 0x6ff1b, 0x6ff1f, 0x6ff20, 0x6ff3f, 0x6ff5b, 0x6ff5d, + 0x7003a, 0x7003b, 0x7003f, 0x70040, 0x7005f, 0x7007b, 0x7007d, 0x700a1, 0x700a7, + 0x700ab, 0x700b6, 0x700b7, 0x700bb, 0x700bf, 0x7037e, 0x70387, 0x70589, 0x7058a, + 0x705be, 0x705c0, 0x705c3, 0x705c6, 0x705f3, 0x705f4, 0x70609, 0x7060a, 0x7060c, + 0x7060d, 0x7061b, 0x7061e, 0x7061f, 0x706d4, 0x7085e, 0x70964, 0x70965, 0x70970, + 0x709fd, 0x70af0, 0x70df4, 0x70e4f, 0x70e5a, 0x70e5b, 0x70f14, 0x70f85, 0x70fd9, + 0x70fda, 0x710fb, 0x71400, 0x7166d, 0x7166e, 0x7169b, 0x7169c, 0x71735, 0x71736, + 0x71944, 0x71945, 0x71a1e, 0x71a1f, 0x71c7e, 0x71c7f, 0x71cd3, 0x7207d, 0x7207e, + 0x7208d, 0x7208e, 0x72329, 0x7232a, 0x727c5, 0x727c6, 0x729fc, 0x729fd, 0x72cfe, + 0x72cff, 0x72d70, 0x73030, 0x7303d, 0x730a0, 0x730fb, 0x7a4fe, 0x7a4ff, 0x7a673, + 0x7a67e, 0x7a8ce, 0x7a8cf, 0x7a8fc, 0x7a92e, 0x7a92f, 0x7a95f, 0x7a9de, 0x7a9df, + 0x7aade, 0x7aadf, 0x7aaf0, 0x7aaf1, 0x7abeb, 0x7fd3e, 0x7fd3f, 0x7fe63, 0x7fe68, + 0x7fe6a, 0x7fe6b, 0x7ff1a, 0x7ff1b, 0x7ff1f, 0x7ff20, 0x7ff3f, 0x7ff5b, 0x7ff5d, + 0x8003a, 0x8003b, 0x8003f, 0x80040, 0x8005f, 0x8007b, 0x8007d, 0x800a1, 0x800a7, + 0x800ab, 0x800b6, 0x800b7, 0x800bb, 0x800bf, 0x8037e, 0x80387, 0x80589, 0x8058a, + 0x805be, 0x805c0, 0x805c3, 0x805c6, 0x805f3, 0x805f4, 0x80609, 0x8060a, 0x8060c, + 0x8060d, 0x8061b, 0x8061e, 0x8061f, 0x806d4, 0x8085e, 0x80964, 0x80965, 0x80970, + 0x809fd, 0x80af0, 0x80df4, 0x80e4f, 0x80e5a, 0x80e5b, 0x80f14, 0x80f85, 0x80fd9, + 0x80fda, 0x810fb, 0x81400, 0x8166d, 0x8166e, 0x8169b, 0x8169c, 0x81735, 0x81736, + 0x81944, 0x81945, 0x81a1e, 0x81a1f, 0x81c7e, 0x81c7f, 0x81cd3, 0x8207d, 0x8207e, + 0x8208d, 0x8208e, 0x82329, 0x8232a, 0x827c5, 0x827c6, 0x829fc, 0x829fd, 0x82cfe, + 0x82cff, 0x82d70, 0x83030, 0x8303d, 0x830a0, 0x830fb, 0x8a4fe, 0x8a4ff, 0x8a673, + 0x8a67e, 0x8a8ce, 0x8a8cf, 0x8a8fc, 0x8a92e, 0x8a92f, 0x8a95f, 0x8a9de, 0x8a9df, + 0x8aade, 0x8aadf, 0x8aaf0, 0x8aaf1, 0x8abeb, 0x8fd3e, 0x8fd3f, 0x8fe63, 0x8fe68, + 0x8fe6a, 0x8fe6b, 0x8ff1a, 0x8ff1b, 0x8ff1f, 0x8ff20, 0x8ff3f, 0x8ff5b, 0x8ff5d, + 0x9003a, 0x9003b, 0x9003f, 0x90040, 0x9005f, 0x9007b, 0x9007d, 0x900a1, 0x900a7, + 0x900ab, 0x900b6, 0x900b7, 0x900bb, 0x900bf, 0x9037e, 0x90387, 0x90589, 0x9058a, + 0x905be, 0x905c0, 0x905c3, 0x905c6, 0x905f3, 0x905f4, 0x90609, 0x9060a, 0x9060c, + 0x9060d, 0x9061b, 0x9061e, 0x9061f, 0x906d4, 0x9085e, 0x90964, 0x90965, 0x90970, + 0x909fd, 0x90af0, 0x90df4, 0x90e4f, 0x90e5a, 0x90e5b, 0x90f14, 0x90f85, 0x90fd9, + 0x90fda, 0x910fb, 0x91400, 0x9166d, 0x9166e, 0x9169b, 0x9169c, 0x91735, 0x91736, + 0x91944, 0x91945, 0x91a1e, 0x91a1f, 0x91c7e, 0x91c7f, 0x91cd3, 0x9207d, 0x9207e, + 0x9208d, 0x9208e, 0x92329, 0x9232a, 0x927c5, 0x927c6, 0x929fc, 0x929fd, 0x92cfe, + 0x92cff, 0x92d70, 0x93030, 0x9303d, 0x930a0, 0x930fb, 0x9a4fe, 0x9a4ff, 0x9a673, + 0x9a67e, 0x9a8ce, 0x9a8cf, 0x9a8fc, 0x9a92e, 0x9a92f, 0x9a95f, 0x9a9de, 0x9a9df, + 0x9aade, 0x9aadf, 0x9aaf0, 0x9aaf1, 0x9abeb, 0x9fd3e, 0x9fd3f, 0x9fe63, 0x9fe68, + 0x9fe6a, 0x9fe6b, 0x9ff1a, 0x9ff1b, 0x9ff1f, 0x9ff20, 0x9ff3f, 0x9ff5b, 0x9ff5d, + 0xa003a, 0xa003b, 0xa003f, 0xa0040, 0xa005f, 0xa007b, 0xa007d, 0xa00a1, 0xa00a7, + 0xa00ab, 0xa00b6, 0xa00b7, 0xa00bb, 0xa00bf, 0xa037e, 0xa0387, 0xa0589, 0xa058a, + 0xa05be, 0xa05c0, 0xa05c3, 0xa05c6, 0xa05f3, 0xa05f4, 0xa0609, 0xa060a, 0xa060c, + 0xa060d, 0xa061b, 0xa061e, 0xa061f, 0xa06d4, 0xa085e, 0xa0964, 0xa0965, 0xa0970, + 0xa09fd, 0xa0af0, 0xa0df4, 0xa0e4f, 0xa0e5a, 0xa0e5b, 0xa0f14, 0xa0f85, 0xa0fd9, + 0xa0fda, 0xa10fb, 0xa1400, 0xa166d, 0xa166e, 0xa169b, 0xa169c, 0xa1735, 0xa1736, + 0xa1944, 0xa1945, 0xa1a1e, 0xa1a1f, 0xa1c7e, 0xa1c7f, 0xa1cd3, 0xa207d, 0xa207e, + 0xa208d, 0xa208e, 0xa2329, 0xa232a, 0xa27c5, 0xa27c6, 0xa29fc, 0xa29fd, 0xa2cfe, + 0xa2cff, 0xa2d70, 0xa3030, 0xa303d, 0xa30a0, 0xa30fb, 0xaa4fe, 0xaa4ff, 0xaa673, + 0xaa67e, 0xaa8ce, 0xaa8cf, 0xaa8fc, 0xaa92e, 0xaa92f, 0xaa95f, 0xaa9de, 0xaa9df, + 0xaaade, 0xaaadf, 0xaaaf0, 0xaaaf1, 0xaabeb, 0xafd3e, 0xafd3f, 0xafe63, 0xafe68, + 0xafe6a, 0xafe6b, 0xaff1a, 0xaff1b, 0xaff1f, 0xaff20, 0xaff3f, 0xaff5b, 0xaff5d, + 0xb003a, 0xb003b, 0xb003f, 0xb0040, 0xb005f, 0xb007b, 0xb007d, 0xb00a1, 0xb00a7, + 0xb00ab, 0xb00b6, 0xb00b7, 0xb00bb, 0xb00bf, 0xb037e, 0xb0387, 0xb0589, 0xb058a, + 0xb05be, 0xb05c0, 0xb05c3, 0xb05c6, 0xb05f3, 0xb05f4, 0xb0609, 0xb060a, 0xb060c, + 0xb060d, 0xb061b, 0xb061e, 0xb061f, 0xb06d4, 0xb085e, 0xb0964, 0xb0965, 0xb0970, + 0xb09fd, 0xb0af0, 0xb0df4, 0xb0e4f, 0xb0e5a, 0xb0e5b, 0xb0f14, 0xb0f85, 0xb0fd9, + 0xb0fda, 0xb10fb, 0xb1400, 0xb166d, 0xb166e, 0xb169b, 0xb169c, 0xb1735, 0xb1736, + 0xb1944, 0xb1945, 0xb1a1e, 0xb1a1f, 0xb1c7e, 0xb1c7f, 0xb1cd3, 0xb207d, 0xb207e, + 0xb208d, 0xb208e, 0xb2329, 0xb232a, 0xb27c5, 0xb27c6, 0xb29fc, 0xb29fd, 0xb2cfe, + 0xb2cff, 0xb2d70, 0xb3030, 0xb303d, 0xb30a0, 0xb30fb, 0xba4fe, 0xba4ff, 0xba673, + 0xba67e, 0xba8ce, 0xba8cf, 0xba8fc, 0xba92e, 0xba92f, 0xba95f, 0xba9de, 0xba9df, + 0xbaade, 0xbaadf, 0xbaaf0, 0xbaaf1, 0xbabeb, 0xbfd3e, 0xbfd3f, 0xbfe63, 0xbfe68, + 0xbfe6a, 0xbfe6b, 0xbff1a, 0xbff1b, 0xbff1f, 0xbff20, 0xbff3f, 0xbff5b, 0xbff5d, + 0xc003a, 0xc003b, 0xc003f, 0xc0040, 0xc005f, 0xc007b, 0xc007d, 0xc00a1, 0xc00a7, + 0xc00ab, 0xc00b6, 0xc00b7, 0xc00bb, 0xc00bf, 0xc037e, 0xc0387, 0xc0589, 0xc058a, + 0xc05be, 0xc05c0, 0xc05c3, 0xc05c6, 0xc05f3, 0xc05f4, 0xc0609, 0xc060a, 0xc060c, + 0xc060d, 0xc061b, 0xc061e, 0xc061f, 0xc06d4, 0xc085e, 0xc0964, 0xc0965, 0xc0970, + 0xc09fd, 0xc0af0, 0xc0df4, 0xc0e4f, 0xc0e5a, 0xc0e5b, 0xc0f14, 0xc0f85, 0xc0fd9, + 0xc0fda, 0xc10fb, 0xc1400, 0xc166d, 0xc166e, 0xc169b, 0xc169c, 0xc1735, 0xc1736, + 0xc1944, 0xc1945, 0xc1a1e, 0xc1a1f, 0xc1c7e, 0xc1c7f, 0xc1cd3, 0xc207d, 0xc207e, + 0xc208d, 0xc208e, 0xc2329, 0xc232a, 0xc27c5, 0xc27c6, 0xc29fc, 0xc29fd, 0xc2cfe, + 0xc2cff, 0xc2d70, 0xc3030, 0xc303d, 0xc30a0, 0xc30fb, 0xca4fe, 0xca4ff, 0xca673, + 0xca67e, 0xca8ce, 0xca8cf, 0xca8fc, 0xca92e, 0xca92f, 0xca95f, 0xca9de, 0xca9df, + 0xcaade, 0xcaadf, 0xcaaf0, 0xcaaf1, 0xcabeb, 0xcfd3e, 0xcfd3f, 0xcfe63, 0xcfe68, + 0xcfe6a, 0xcfe6b, 0xcff1a, 0xcff1b, 0xcff1f, 0xcff20, 0xcff3f, 0xcff5b, 0xcff5d, + 0xd003a, 0xd003b, 0xd003f, 0xd0040, 0xd005f, 0xd007b, 0xd007d, 0xd00a1, 0xd00a7, + 0xd00ab, 0xd00b6, 0xd00b7, 0xd00bb, 0xd00bf, 0xd037e, 0xd0387, 0xd0589, 0xd058a, + 0xd05be, 0xd05c0, 0xd05c3, 0xd05c6, 0xd05f3, 0xd05f4, 0xd0609, 0xd060a, 0xd060c, + 0xd060d, 0xd061b, 0xd061e, 0xd061f, 0xd06d4, 0xd085e, 0xd0964, 0xd0965, 0xd0970, + 0xd09fd, 0xd0af0, 0xd0df4, 0xd0e4f, 0xd0e5a, 0xd0e5b, 0xd0f14, 0xd0f85, 0xd0fd9, + 0xd0fda, 0xd10fb, 0xd1400, 0xd166d, 0xd166e, 0xd169b, 0xd169c, 0xd1735, 0xd1736, + 0xd1944, 0xd1945, 0xd1a1e, 0xd1a1f, 0xd1c7e, 0xd1c7f, 0xd1cd3, 0xd207d, 0xd207e, + 0xd208d, 0xd208e, 0xd2329, 0xd232a, 0xd27c5, 0xd27c6, 0xd29fc, 0xd29fd, 0xd2cfe, + 0xd2cff, 0xd2d70, 0xd3030, 0xd303d, 0xd30a0, 0xd30fb, 0xda4fe, 0xda4ff, 0xda673, + 0xda67e, 0xda8ce, 0xda8cf, 0xda8fc, 0xda92e, 0xda92f, 0xda95f, 0xda9de, 0xda9df, + 0xdaade, 0xdaadf, 0xdaaf0, 0xdaaf1, 0xdabeb, 0xdfd3e, 0xdfd3f, 0xdfe63, 0xdfe68, + 0xdfe6a, 0xdfe6b, 0xdff1a, 0xdff1b, 0xdff1f, 0xdff20, 0xdff3f, 0xdff5b, 0xdff5d, + 0xe003a, 0xe003b, 0xe003f, 0xe0040, 0xe005f, 0xe007b, 0xe007d, 0xe00a1, 0xe00a7, + 0xe00ab, 0xe00b6, 0xe00b7, 0xe00bb, 0xe00bf, 0xe037e, 0xe0387, 0xe0589, 0xe058a, + 0xe05be, 0xe05c0, 0xe05c3, 0xe05c6, 0xe05f3, 0xe05f4, 0xe0609, 0xe060a, 0xe060c, + 0xe060d, 0xe061b, 0xe061e, 0xe061f, 0xe06d4, 0xe085e, 0xe0964, 0xe0965, 0xe0970, + 0xe09fd, 0xe0af0, 0xe0df4, 0xe0e4f, 0xe0e5a, 0xe0e5b, 0xe0f14, 0xe0f85, 0xe0fd9, + 0xe0fda, 0xe10fb, 0xe1400, 0xe166d, 0xe166e, 0xe169b, 0xe169c, 0xe1735, 0xe1736, + 0xe1944, 0xe1945, 0xe1a1e, 0xe1a1f, 0xe1c7e, 0xe1c7f, 0xe1cd3, 0xe207d, 0xe207e, + 0xe208d, 0xe208e, 0xe2329, 0xe232a, 0xe27c5, 0xe27c6, 0xe29fc, 0xe29fd, 0xe2cfe, + 0xe2cff, 0xe2d70, 0xe3030, 0xe303d, 0xe30a0, 0xe30fb, 0xea4fe, 0xea4ff, 0xea673, + 0xea67e, 0xea8ce, 0xea8cf, 0xea8fc, 0xea92e, 0xea92f, 0xea95f, 0xea9de, 0xea9df, + 0xeaade, 0xeaadf, 0xeaaf0, 0xeaaf1, 0xeabeb, 0xefd3e, 0xefd3f, 0xefe63, 0xefe68, + 0xefe6a, 0xefe6b, 0xeff1a, 0xeff1b, 0xeff1f, 0xeff20, 0xeff3f, 0xeff5b, 0xeff5d, + 0xf003a, 0xf003b, 0xf003f, 0xf0040, 0xf005f, 0xf007b, 0xf007d, 0xf00a1, 0xf00a7, + 0xf00ab, 0xf00b6, 0xf00b7, 0xf00bb, 0xf00bf, 0xf037e, 0xf0387, 0xf0589, 0xf058a, + 0xf05be, 0xf05c0, 0xf05c3, 0xf05c6, 0xf05f3, 0xf05f4, 0xf0609, 0xf060a, 0xf060c, + 0xf060d, 0xf061b, 0xf061e, 0xf061f, 0xf06d4, 0xf085e, 0xf0964, 0xf0965, 0xf0970, + 0xf09fd, 0xf0af0, 0xf0df4, 0xf0e4f, 0xf0e5a, 0xf0e5b, 0xf0f14, 0xf0f85, 0xf0fd9, + 0xf0fda, 0xf10fb, 0xf1400, 0xf166d, 0xf166e, 0xf169b, 0xf169c, 0xf1735, 0xf1736, + 0xf1944, 0xf1945, 0xf1a1e, 0xf1a1f, 0xf1c7e, 0xf1c7f, 0xf1cd3, 0xf207d, 0xf207e, + 0xf208d, 0xf208e, 0xf2329, 0xf232a, 0xf27c5, 0xf27c6, 0xf29fc, 0xf29fd, 0xf2cfe, + 0xf2cff, 0xf2d70, 0xf3030, 0xf303d, 0xf30a0, 0xf30fb, 0xfa4fe, 0xfa4ff, 0xfa673, + 0xfa67e, 0xfa8ce, 0xfa8cf, 0xfa8fc, 0xfa92e, 0xfa92f, 0xfa95f, 0xfa9de, 0xfa9df, + 0xfaade, 0xfaadf, 0xfaaf0, 0xfaaf1, 0xfabeb, 0xffd3e, 0xffd3f, 0xffe63, 0xffe68, + 0xffe6a, 0xffe6b, 0xfff1a, 0xfff1b, 0xfff1f, 0xfff20, 0xfff3f, 0xfff5b, 0xfff5d, + 0x10003a, 0x10003b, 0x10003f, 0x100040, 0x10005f, 0x10007b, 0x10007d, 0x1000a1, 0x1000a7, + 0x1000ab, 0x1000b6, 0x1000b7, 0x1000bb, 0x1000bf, 0x10037e, 0x100387, 0x100589, 0x10058a, + 0x1005be, 0x1005c0, 0x1005c3, 0x1005c6, 0x1005f3, 0x1005f4, 0x100609, 0x10060a, 0x10060c, + 0x10060d, 0x10061b, 0x10061e, 0x10061f, 0x1006d4, 0x10085e, 0x100964, 0x100965, 0x100970, + 0x1009fd, 0x100af0, 0x100df4, 0x100e4f, 0x100e5a, 0x100e5b, 0x100f14, 0x100f85, 0x100fd9, + 0x100fda, 0x1010fb, 0x101400, 0x10166d, 0x10166e, 0x10169b, 0x10169c, 0x101735, 0x101736, + 0x101944, 0x101945, 0x101a1e, 0x101a1f, 0x101c7e, 0x101c7f, 0x101cd3, 0x10207d, 0x10207e, + 0x10208d, 0x10208e, 0x102329, 0x10232a, 0x1027c5, 0x1027c6, 0x1029fc, 0x1029fd, 0x102cfe, + 0x102cff, 0x102d70, 0x103030, 0x10303d, 0x1030a0, 0x1030fb, 0x10a4fe, 0x10a4ff, 0x10a673, + 0x10a67e, 0x10a8ce, 0x10a8cf, 0x10a8fc, 0x10a92e, 0x10a92f, 0x10a95f, 0x10a9de, 0x10a9df, + 0x10aade, 0x10aadf, 0x10aaf0, 0x10aaf1, 0x10abeb, 0x10fd3e, 0x10fd3f, 0x10fe63, 0x10fe68, + 0x10fe6a, 0x10fe6b, 0x10ff1a, 0x10ff1b, 0x10ff1f, 0x10ff20, 0x10ff3f, 0x10ff5b, 0x10ff5d #endif }; @@ -390,6 +2256,16 @@ static const chr punctCharTable[] = { static const crange spaceRangeTable[] = { {0x9, 0xd}, {0x2000, 0x200b} +#if TCL_UTF_MAX > 4 + ,{0x10009, 0x1000d}, {0x12000, 0x1200b}, {0x20009, 0x2000d}, {0x22000, 0x2200b}, + {0x30009, 0x3000d}, {0x32000, 0x3200b}, {0x40009, 0x4000d}, {0x42000, 0x4200b}, + {0x50009, 0x5000d}, {0x52000, 0x5200b}, {0x60009, 0x6000d}, {0x62000, 0x6200b}, + {0x70009, 0x7000d}, {0x72000, 0x7200b}, {0x80009, 0x8000d}, {0x82000, 0x8200b}, + {0x90009, 0x9000d}, {0x92000, 0x9200b}, {0xa0009, 0xa000d}, {0xa2000, 0xa200b}, + {0xb0009, 0xb000d}, {0xb2000, 0xb200b}, {0xc0009, 0xc000d}, {0xc2000, 0xc200b}, + {0xd0009, 0xd000d}, {0xd2000, 0xd200b}, {0xe0009, 0xe000d}, {0xe2000, 0xe200b}, + {0xf0009, 0xf000d}, {0xf2000, 0xf200b}, {0x100009, 0x10000d}, {0x102000, 0x10200b} +#endif }; #define NUM_SPACE_RANGE (sizeof(spaceRangeTable)/sizeof(crange)) @@ -397,6 +2273,30 @@ static const crange spaceRangeTable[] = { static const chr spaceCharTable[] = { 0x20, 0x85, 0xa0, 0x1680, 0x180e, 0x2028, 0x2029, 0x202f, 0x205f, 0x2060, 0x3000, 0xfeff +#if TCL_UTF_MAX > 4 + ,0x10020, 0x10085, 0x100a0, 0x11680, 0x1180e, 0x12028, 0x12029, 0x1202f, 0x1205f, + 0x12060, 0x13000, 0x1feff, 0x20020, 0x20085, 0x200a0, 0x21680, 0x2180e, 0x22028, + 0x22029, 0x2202f, 0x2205f, 0x22060, 0x23000, 0x2feff, 0x30020, 0x30085, 0x300a0, + 0x31680, 0x3180e, 0x32028, 0x32029, 0x3202f, 0x3205f, 0x32060, 0x33000, 0x3feff, + 0x40020, 0x40085, 0x400a0, 0x41680, 0x4180e, 0x42028, 0x42029, 0x4202f, 0x4205f, + 0x42060, 0x43000, 0x4feff, 0x50020, 0x50085, 0x500a0, 0x51680, 0x5180e, 0x52028, + 0x52029, 0x5202f, 0x5205f, 0x52060, 0x53000, 0x5feff, 0x60020, 0x60085, 0x600a0, + 0x61680, 0x6180e, 0x62028, 0x62029, 0x6202f, 0x6205f, 0x62060, 0x63000, 0x6feff, + 0x70020, 0x70085, 0x700a0, 0x71680, 0x7180e, 0x72028, 0x72029, 0x7202f, 0x7205f, + 0x72060, 0x73000, 0x7feff, 0x80020, 0x80085, 0x800a0, 0x81680, 0x8180e, 0x82028, + 0x82029, 0x8202f, 0x8205f, 0x82060, 0x83000, 0x8feff, 0x90020, 0x90085, 0x900a0, + 0x91680, 0x9180e, 0x92028, 0x92029, 0x9202f, 0x9205f, 0x92060, 0x93000, 0x9feff, + 0xa0020, 0xa0085, 0xa00a0, 0xa1680, 0xa180e, 0xa2028, 0xa2029, 0xa202f, 0xa205f, + 0xa2060, 0xa3000, 0xafeff, 0xb0020, 0xb0085, 0xb00a0, 0xb1680, 0xb180e, 0xb2028, + 0xb2029, 0xb202f, 0xb205f, 0xb2060, 0xb3000, 0xbfeff, 0xc0020, 0xc0085, 0xc00a0, + 0xc1680, 0xc180e, 0xc2028, 0xc2029, 0xc202f, 0xc205f, 0xc2060, 0xc3000, 0xcfeff, + 0xd0020, 0xd0085, 0xd00a0, 0xd1680, 0xd180e, 0xd2028, 0xd2029, 0xd202f, 0xd205f, + 0xd2060, 0xd3000, 0xdfeff, 0xe0020, 0xe0085, 0xe00a0, 0xe1680, 0xe180e, 0xe2028, + 0xe2029, 0xe202f, 0xe205f, 0xe2060, 0xe3000, 0xefeff, 0xf0020, 0xf0085, 0xf00a0, + 0xf1680, 0xf180e, 0xf2028, 0xf2029, 0xf202f, 0xf205f, 0xf2060, 0xf3000, 0xffeff, + 0x100020, 0x100085, 0x1000a0, 0x101680, 0x10180e, 0x102028, 0x102029, 0x10202f, 0x10205f, + 0x102060, 0x103000, 0x10feff +#endif }; #define NUM_SPACE_CHAR (sizeof(spaceCharTable)/sizeof(chr)) @@ -420,14 +2320,206 @@ static const crange lowerRangeTable[] = { {0xab30, 0xab5a}, {0xab60, 0xab65}, {0xab70, 0xabbf}, {0xfb00, 0xfb06}, {0xfb13, 0xfb17}, {0xff41, 0xff5a} #if TCL_UTF_MAX > 4 - ,{0x10428, 0x1044f}, {0x104d8, 0x104fb}, {0x10cc0, 0x10cf2}, {0x118c0, 0x118df}, - {0x1d41a, 0x1d433}, {0x1d44e, 0x1d454}, {0x1d456, 0x1d467}, {0x1d482, 0x1d49b}, - {0x1d4b6, 0x1d4b9}, {0x1d4bd, 0x1d4c3}, {0x1d4c5, 0x1d4cf}, {0x1d4ea, 0x1d503}, - {0x1d51e, 0x1d537}, {0x1d552, 0x1d56b}, {0x1d586, 0x1d59f}, {0x1d5ba, 0x1d5d3}, - {0x1d5ee, 0x1d607}, {0x1d622, 0x1d63b}, {0x1d656, 0x1d66f}, {0x1d68a, 0x1d6a5}, - {0x1d6c2, 0x1d6da}, {0x1d6dc, 0x1d6e1}, {0x1d6fc, 0x1d714}, {0x1d716, 0x1d71b}, - {0x1d736, 0x1d74e}, {0x1d750, 0x1d755}, {0x1d770, 0x1d788}, {0x1d78a, 0x1d78f}, - {0x1d7aa, 0x1d7c2}, {0x1d7c4, 0x1d7c9}, {0x1e922, 0x1e943} + ,{0x10061, 0x1007a}, {0x100df, 0x100f6}, {0x100f8, 0x100ff}, {0x1017e, 0x10180}, + {0x10199, 0x1019b}, {0x101bd, 0x101bf}, {0x10233, 0x10239}, {0x1024f, 0x10293}, + {0x10295, 0x102af}, {0x1037b, 0x1037d}, {0x103ac, 0x103ce}, {0x103d5, 0x103d7}, + {0x103ef, 0x103f3}, {0x10430, 0x1045f}, {0x10561, 0x10587}, {0x113f8, 0x113fd}, + {0x11c80, 0x11c88}, {0x11d00, 0x11d2b}, {0x11d6b, 0x11d77}, {0x11d79, 0x11d9a}, + {0x11e95, 0x11e9d}, {0x11eff, 0x11f07}, {0x11f10, 0x11f15}, {0x11f20, 0x11f27}, + {0x11f30, 0x11f37}, {0x11f40, 0x11f45}, {0x11f50, 0x11f57}, {0x11f60, 0x11f67}, + {0x11f70, 0x11f7d}, {0x11f80, 0x11f87}, {0x11f90, 0x11f97}, {0x11fa0, 0x11fa7}, + {0x11fb0, 0x11fb4}, {0x11fc2, 0x11fc4}, {0x11fd0, 0x11fd3}, {0x11fe0, 0x11fe7}, + {0x11ff2, 0x11ff4}, {0x12146, 0x12149}, {0x12c30, 0x12c5e}, {0x12c76, 0x12c7b}, + {0x12d00, 0x12d25}, {0x1a72f, 0x1a731}, {0x1a771, 0x1a778}, {0x1a793, 0x1a795}, + {0x1ab30, 0x1ab5a}, {0x1ab60, 0x1ab65}, {0x1ab70, 0x1abbf}, {0x1fb00, 0x1fb06}, + {0x1fb13, 0x1fb17}, {0x1ff41, 0x1ff5a}, {0x20061, 0x2007a}, {0x200df, 0x200f6}, + {0x200f8, 0x200ff}, {0x2017e, 0x20180}, {0x20199, 0x2019b}, {0x201bd, 0x201bf}, + {0x20233, 0x20239}, {0x2024f, 0x20293}, {0x20295, 0x202af}, {0x2037b, 0x2037d}, + {0x203ac, 0x203ce}, {0x203d5, 0x203d7}, {0x203ef, 0x203f3}, {0x20430, 0x2045f}, + {0x20561, 0x20587}, {0x213f8, 0x213fd}, {0x21c80, 0x21c88}, {0x21d00, 0x21d2b}, + {0x21d6b, 0x21d77}, {0x21d79, 0x21d9a}, {0x21e95, 0x21e9d}, {0x21eff, 0x21f07}, + {0x21f10, 0x21f15}, {0x21f20, 0x21f27}, {0x21f30, 0x21f37}, {0x21f40, 0x21f45}, + {0x21f50, 0x21f57}, {0x21f60, 0x21f67}, {0x21f70, 0x21f7d}, {0x21f80, 0x21f87}, + {0x21f90, 0x21f97}, {0x21fa0, 0x21fa7}, {0x21fb0, 0x21fb4}, {0x21fc2, 0x21fc4}, + {0x21fd0, 0x21fd3}, {0x21fe0, 0x21fe7}, {0x21ff2, 0x21ff4}, {0x22146, 0x22149}, + {0x22c30, 0x22c5e}, {0x22c76, 0x22c7b}, {0x22d00, 0x22d25}, {0x2a72f, 0x2a731}, + {0x2a771, 0x2a778}, {0x2a793, 0x2a795}, {0x2ab30, 0x2ab5a}, {0x2ab60, 0x2ab65}, + {0x2ab70, 0x2abbf}, {0x2fb00, 0x2fb06}, {0x2fb13, 0x2fb17}, {0x2ff41, 0x2ff5a}, + {0x30061, 0x3007a}, {0x300df, 0x300f6}, {0x300f8, 0x300ff}, {0x3017e, 0x30180}, + {0x30199, 0x3019b}, {0x301bd, 0x301bf}, {0x30233, 0x30239}, {0x3024f, 0x30293}, + {0x30295, 0x302af}, {0x3037b, 0x3037d}, {0x303ac, 0x303ce}, {0x303d5, 0x303d7}, + {0x303ef, 0x303f3}, {0x30430, 0x3045f}, {0x30561, 0x30587}, {0x313f8, 0x313fd}, + {0x31c80, 0x31c88}, {0x31d00, 0x31d2b}, {0x31d6b, 0x31d77}, {0x31d79, 0x31d9a}, + {0x31e95, 0x31e9d}, {0x31eff, 0x31f07}, {0x31f10, 0x31f15}, {0x31f20, 0x31f27}, + {0x31f30, 0x31f37}, {0x31f40, 0x31f45}, {0x31f50, 0x31f57}, {0x31f60, 0x31f67}, + {0x31f70, 0x31f7d}, {0x31f80, 0x31f87}, {0x31f90, 0x31f97}, {0x31fa0, 0x31fa7}, + {0x31fb0, 0x31fb4}, {0x31fc2, 0x31fc4}, {0x31fd0, 0x31fd3}, {0x31fe0, 0x31fe7}, + {0x31ff2, 0x31ff4}, {0x32146, 0x32149}, {0x32c30, 0x32c5e}, {0x32c76, 0x32c7b}, + {0x32d00, 0x32d25}, {0x3a72f, 0x3a731}, {0x3a771, 0x3a778}, {0x3a793, 0x3a795}, + {0x3ab30, 0x3ab5a}, {0x3ab60, 0x3ab65}, {0x3ab70, 0x3abbf}, {0x3fb00, 0x3fb06}, + {0x3fb13, 0x3fb17}, {0x3ff41, 0x3ff5a}, {0x40061, 0x4007a}, {0x400df, 0x400f6}, + {0x400f8, 0x400ff}, {0x4017e, 0x40180}, {0x40199, 0x4019b}, {0x401bd, 0x401bf}, + {0x40233, 0x40239}, {0x4024f, 0x40293}, {0x40295, 0x402af}, {0x4037b, 0x4037d}, + {0x403ac, 0x403ce}, {0x403d5, 0x403d7}, {0x403ef, 0x403f3}, {0x40430, 0x4045f}, + {0x40561, 0x40587}, {0x413f8, 0x413fd}, {0x41c80, 0x41c88}, {0x41d00, 0x41d2b}, + {0x41d6b, 0x41d77}, {0x41d79, 0x41d9a}, {0x41e95, 0x41e9d}, {0x41eff, 0x41f07}, + {0x41f10, 0x41f15}, {0x41f20, 0x41f27}, {0x41f30, 0x41f37}, {0x41f40, 0x41f45}, + {0x41f50, 0x41f57}, {0x41f60, 0x41f67}, {0x41f70, 0x41f7d}, {0x41f80, 0x41f87}, + {0x41f90, 0x41f97}, {0x41fa0, 0x41fa7}, {0x41fb0, 0x41fb4}, {0x41fc2, 0x41fc4}, + {0x41fd0, 0x41fd3}, {0x41fe0, 0x41fe7}, {0x41ff2, 0x41ff4}, {0x42146, 0x42149}, + {0x42c30, 0x42c5e}, {0x42c76, 0x42c7b}, {0x42d00, 0x42d25}, {0x4a72f, 0x4a731}, + {0x4a771, 0x4a778}, {0x4a793, 0x4a795}, {0x4ab30, 0x4ab5a}, {0x4ab60, 0x4ab65}, + {0x4ab70, 0x4abbf}, {0x4fb00, 0x4fb06}, {0x4fb13, 0x4fb17}, {0x4ff41, 0x4ff5a}, + {0x50061, 0x5007a}, {0x500df, 0x500f6}, {0x500f8, 0x500ff}, {0x5017e, 0x50180}, + {0x50199, 0x5019b}, {0x501bd, 0x501bf}, {0x50233, 0x50239}, {0x5024f, 0x50293}, + {0x50295, 0x502af}, {0x5037b, 0x5037d}, {0x503ac, 0x503ce}, {0x503d5, 0x503d7}, + {0x503ef, 0x503f3}, {0x50430, 0x5045f}, {0x50561, 0x50587}, {0x513f8, 0x513fd}, + {0x51c80, 0x51c88}, {0x51d00, 0x51d2b}, {0x51d6b, 0x51d77}, {0x51d79, 0x51d9a}, + {0x51e95, 0x51e9d}, {0x51eff, 0x51f07}, {0x51f10, 0x51f15}, {0x51f20, 0x51f27}, + {0x51f30, 0x51f37}, {0x51f40, 0x51f45}, {0x51f50, 0x51f57}, {0x51f60, 0x51f67}, + {0x51f70, 0x51f7d}, {0x51f80, 0x51f87}, {0x51f90, 0x51f97}, {0x51fa0, 0x51fa7}, + {0x51fb0, 0x51fb4}, {0x51fc2, 0x51fc4}, {0x51fd0, 0x51fd3}, {0x51fe0, 0x51fe7}, + {0x51ff2, 0x51ff4}, {0x52146, 0x52149}, {0x52c30, 0x52c5e}, {0x52c76, 0x52c7b}, + {0x52d00, 0x52d25}, {0x5a72f, 0x5a731}, {0x5a771, 0x5a778}, {0x5a793, 0x5a795}, + {0x5ab30, 0x5ab5a}, {0x5ab60, 0x5ab65}, {0x5ab70, 0x5abbf}, {0x5fb00, 0x5fb06}, + {0x5fb13, 0x5fb17}, {0x5ff41, 0x5ff5a}, {0x60061, 0x6007a}, {0x600df, 0x600f6}, + {0x600f8, 0x600ff}, {0x6017e, 0x60180}, {0x60199, 0x6019b}, {0x601bd, 0x601bf}, + {0x60233, 0x60239}, {0x6024f, 0x60293}, {0x60295, 0x602af}, {0x6037b, 0x6037d}, + {0x603ac, 0x603ce}, {0x603d5, 0x603d7}, {0x603ef, 0x603f3}, {0x60430, 0x6045f}, + {0x60561, 0x60587}, {0x613f8, 0x613fd}, {0x61c80, 0x61c88}, {0x61d00, 0x61d2b}, + {0x61d6b, 0x61d77}, {0x61d79, 0x61d9a}, {0x61e95, 0x61e9d}, {0x61eff, 0x61f07}, + {0x61f10, 0x61f15}, {0x61f20, 0x61f27}, {0x61f30, 0x61f37}, {0x61f40, 0x61f45}, + {0x61f50, 0x61f57}, {0x61f60, 0x61f67}, {0x61f70, 0x61f7d}, {0x61f80, 0x61f87}, + {0x61f90, 0x61f97}, {0x61fa0, 0x61fa7}, {0x61fb0, 0x61fb4}, {0x61fc2, 0x61fc4}, + {0x61fd0, 0x61fd3}, {0x61fe0, 0x61fe7}, {0x61ff2, 0x61ff4}, {0x62146, 0x62149}, + {0x62c30, 0x62c5e}, {0x62c76, 0x62c7b}, {0x62d00, 0x62d25}, {0x6a72f, 0x6a731}, + {0x6a771, 0x6a778}, {0x6a793, 0x6a795}, {0x6ab30, 0x6ab5a}, {0x6ab60, 0x6ab65}, + {0x6ab70, 0x6abbf}, {0x6fb00, 0x6fb06}, {0x6fb13, 0x6fb17}, {0x6ff41, 0x6ff5a}, + {0x70061, 0x7007a}, {0x700df, 0x700f6}, {0x700f8, 0x700ff}, {0x7017e, 0x70180}, + {0x70199, 0x7019b}, {0x701bd, 0x701bf}, {0x70233, 0x70239}, {0x7024f, 0x70293}, + {0x70295, 0x702af}, {0x7037b, 0x7037d}, {0x703ac, 0x703ce}, {0x703d5, 0x703d7}, + {0x703ef, 0x703f3}, {0x70430, 0x7045f}, {0x70561, 0x70587}, {0x713f8, 0x713fd}, + {0x71c80, 0x71c88}, {0x71d00, 0x71d2b}, {0x71d6b, 0x71d77}, {0x71d79, 0x71d9a}, + {0x71e95, 0x71e9d}, {0x71eff, 0x71f07}, {0x71f10, 0x71f15}, {0x71f20, 0x71f27}, + {0x71f30, 0x71f37}, {0x71f40, 0x71f45}, {0x71f50, 0x71f57}, {0x71f60, 0x71f67}, + {0x71f70, 0x71f7d}, {0x71f80, 0x71f87}, {0x71f90, 0x71f97}, {0x71fa0, 0x71fa7}, + {0x71fb0, 0x71fb4}, {0x71fc2, 0x71fc4}, {0x71fd0, 0x71fd3}, {0x71fe0, 0x71fe7}, + {0x71ff2, 0x71ff4}, {0x72146, 0x72149}, {0x72c30, 0x72c5e}, {0x72c76, 0x72c7b}, + {0x72d00, 0x72d25}, {0x7a72f, 0x7a731}, {0x7a771, 0x7a778}, {0x7a793, 0x7a795}, + {0x7ab30, 0x7ab5a}, {0x7ab60, 0x7ab65}, {0x7ab70, 0x7abbf}, {0x7fb00, 0x7fb06}, + {0x7fb13, 0x7fb17}, {0x7ff41, 0x7ff5a}, {0x80061, 0x8007a}, {0x800df, 0x800f6}, + {0x800f8, 0x800ff}, {0x8017e, 0x80180}, {0x80199, 0x8019b}, {0x801bd, 0x801bf}, + {0x80233, 0x80239}, {0x8024f, 0x80293}, {0x80295, 0x802af}, {0x8037b, 0x8037d}, + {0x803ac, 0x803ce}, {0x803d5, 0x803d7}, {0x803ef, 0x803f3}, {0x80430, 0x8045f}, + {0x80561, 0x80587}, {0x813f8, 0x813fd}, {0x81c80, 0x81c88}, {0x81d00, 0x81d2b}, + {0x81d6b, 0x81d77}, {0x81d79, 0x81d9a}, {0x81e95, 0x81e9d}, {0x81eff, 0x81f07}, + {0x81f10, 0x81f15}, {0x81f20, 0x81f27}, {0x81f30, 0x81f37}, {0x81f40, 0x81f45}, + {0x81f50, 0x81f57}, {0x81f60, 0x81f67}, {0x81f70, 0x81f7d}, {0x81f80, 0x81f87}, + {0x81f90, 0x81f97}, {0x81fa0, 0x81fa7}, {0x81fb0, 0x81fb4}, {0x81fc2, 0x81fc4}, + {0x81fd0, 0x81fd3}, {0x81fe0, 0x81fe7}, {0x81ff2, 0x81ff4}, {0x82146, 0x82149}, + {0x82c30, 0x82c5e}, {0x82c76, 0x82c7b}, {0x82d00, 0x82d25}, {0x8a72f, 0x8a731}, + {0x8a771, 0x8a778}, {0x8a793, 0x8a795}, {0x8ab30, 0x8ab5a}, {0x8ab60, 0x8ab65}, + {0x8ab70, 0x8abbf}, {0x8fb00, 0x8fb06}, {0x8fb13, 0x8fb17}, {0x8ff41, 0x8ff5a}, + {0x90061, 0x9007a}, {0x900df, 0x900f6}, {0x900f8, 0x900ff}, {0x9017e, 0x90180}, + {0x90199, 0x9019b}, {0x901bd, 0x901bf}, {0x90233, 0x90239}, {0x9024f, 0x90293}, + {0x90295, 0x902af}, {0x9037b, 0x9037d}, {0x903ac, 0x903ce}, {0x903d5, 0x903d7}, + {0x903ef, 0x903f3}, {0x90430, 0x9045f}, {0x90561, 0x90587}, {0x913f8, 0x913fd}, + {0x91c80, 0x91c88}, {0x91d00, 0x91d2b}, {0x91d6b, 0x91d77}, {0x91d79, 0x91d9a}, + {0x91e95, 0x91e9d}, {0x91eff, 0x91f07}, {0x91f10, 0x91f15}, {0x91f20, 0x91f27}, + {0x91f30, 0x91f37}, {0x91f40, 0x91f45}, {0x91f50, 0x91f57}, {0x91f60, 0x91f67}, + {0x91f70, 0x91f7d}, {0x91f80, 0x91f87}, {0x91f90, 0x91f97}, {0x91fa0, 0x91fa7}, + {0x91fb0, 0x91fb4}, {0x91fc2, 0x91fc4}, {0x91fd0, 0x91fd3}, {0x91fe0, 0x91fe7}, + {0x91ff2, 0x91ff4}, {0x92146, 0x92149}, {0x92c30, 0x92c5e}, {0x92c76, 0x92c7b}, + {0x92d00, 0x92d25}, {0x9a72f, 0x9a731}, {0x9a771, 0x9a778}, {0x9a793, 0x9a795}, + {0x9ab30, 0x9ab5a}, {0x9ab60, 0x9ab65}, {0x9ab70, 0x9abbf}, {0x9fb00, 0x9fb06}, + {0x9fb13, 0x9fb17}, {0x9ff41, 0x9ff5a}, {0xa0061, 0xa007a}, {0xa00df, 0xa00f6}, + {0xa00f8, 0xa00ff}, {0xa017e, 0xa0180}, {0xa0199, 0xa019b}, {0xa01bd, 0xa01bf}, + {0xa0233, 0xa0239}, {0xa024f, 0xa0293}, {0xa0295, 0xa02af}, {0xa037b, 0xa037d}, + {0xa03ac, 0xa03ce}, {0xa03d5, 0xa03d7}, {0xa03ef, 0xa03f3}, {0xa0430, 0xa045f}, + {0xa0561, 0xa0587}, {0xa13f8, 0xa13fd}, {0xa1c80, 0xa1c88}, {0xa1d00, 0xa1d2b}, + {0xa1d6b, 0xa1d77}, {0xa1d79, 0xa1d9a}, {0xa1e95, 0xa1e9d}, {0xa1eff, 0xa1f07}, + {0xa1f10, 0xa1f15}, {0xa1f20, 0xa1f27}, {0xa1f30, 0xa1f37}, {0xa1f40, 0xa1f45}, + {0xa1f50, 0xa1f57}, {0xa1f60, 0xa1f67}, {0xa1f70, 0xa1f7d}, {0xa1f80, 0xa1f87}, + {0xa1f90, 0xa1f97}, {0xa1fa0, 0xa1fa7}, {0xa1fb0, 0xa1fb4}, {0xa1fc2, 0xa1fc4}, + {0xa1fd0, 0xa1fd3}, {0xa1fe0, 0xa1fe7}, {0xa1ff2, 0xa1ff4}, {0xa2146, 0xa2149}, + {0xa2c30, 0xa2c5e}, {0xa2c76, 0xa2c7b}, {0xa2d00, 0xa2d25}, {0xaa72f, 0xaa731}, + {0xaa771, 0xaa778}, {0xaa793, 0xaa795}, {0xaab30, 0xaab5a}, {0xaab60, 0xaab65}, + {0xaab70, 0xaabbf}, {0xafb00, 0xafb06}, {0xafb13, 0xafb17}, {0xaff41, 0xaff5a}, + {0xb0061, 0xb007a}, {0xb00df, 0xb00f6}, {0xb00f8, 0xb00ff}, {0xb017e, 0xb0180}, + {0xb0199, 0xb019b}, {0xb01bd, 0xb01bf}, {0xb0233, 0xb0239}, {0xb024f, 0xb0293}, + {0xb0295, 0xb02af}, {0xb037b, 0xb037d}, {0xb03ac, 0xb03ce}, {0xb03d5, 0xb03d7}, + {0xb03ef, 0xb03f3}, {0xb0430, 0xb045f}, {0xb0561, 0xb0587}, {0xb13f8, 0xb13fd}, + {0xb1c80, 0xb1c88}, {0xb1d00, 0xb1d2b}, {0xb1d6b, 0xb1d77}, {0xb1d79, 0xb1d9a}, + {0xb1e95, 0xb1e9d}, {0xb1eff, 0xb1f07}, {0xb1f10, 0xb1f15}, {0xb1f20, 0xb1f27}, + {0xb1f30, 0xb1f37}, {0xb1f40, 0xb1f45}, {0xb1f50, 0xb1f57}, {0xb1f60, 0xb1f67}, + {0xb1f70, 0xb1f7d}, {0xb1f80, 0xb1f87}, {0xb1f90, 0xb1f97}, {0xb1fa0, 0xb1fa7}, + {0xb1fb0, 0xb1fb4}, {0xb1fc2, 0xb1fc4}, {0xb1fd0, 0xb1fd3}, {0xb1fe0, 0xb1fe7}, + {0xb1ff2, 0xb1ff4}, {0xb2146, 0xb2149}, {0xb2c30, 0xb2c5e}, {0xb2c76, 0xb2c7b}, + {0xb2d00, 0xb2d25}, {0xba72f, 0xba731}, {0xba771, 0xba778}, {0xba793, 0xba795}, + {0xbab30, 0xbab5a}, {0xbab60, 0xbab65}, {0xbab70, 0xbabbf}, {0xbfb00, 0xbfb06}, + {0xbfb13, 0xbfb17}, {0xbff41, 0xbff5a}, {0xc0061, 0xc007a}, {0xc00df, 0xc00f6}, + {0xc00f8, 0xc00ff}, {0xc017e, 0xc0180}, {0xc0199, 0xc019b}, {0xc01bd, 0xc01bf}, + {0xc0233, 0xc0239}, {0xc024f, 0xc0293}, {0xc0295, 0xc02af}, {0xc037b, 0xc037d}, + {0xc03ac, 0xc03ce}, {0xc03d5, 0xc03d7}, {0xc03ef, 0xc03f3}, {0xc0430, 0xc045f}, + {0xc0561, 0xc0587}, {0xc13f8, 0xc13fd}, {0xc1c80, 0xc1c88}, {0xc1d00, 0xc1d2b}, + {0xc1d6b, 0xc1d77}, {0xc1d79, 0xc1d9a}, {0xc1e95, 0xc1e9d}, {0xc1eff, 0xc1f07}, + {0xc1f10, 0xc1f15}, {0xc1f20, 0xc1f27}, {0xc1f30, 0xc1f37}, {0xc1f40, 0xc1f45}, + {0xc1f50, 0xc1f57}, {0xc1f60, 0xc1f67}, {0xc1f70, 0xc1f7d}, {0xc1f80, 0xc1f87}, + {0xc1f90, 0xc1f97}, {0xc1fa0, 0xc1fa7}, {0xc1fb0, 0xc1fb4}, {0xc1fc2, 0xc1fc4}, + {0xc1fd0, 0xc1fd3}, {0xc1fe0, 0xc1fe7}, {0xc1ff2, 0xc1ff4}, {0xc2146, 0xc2149}, + {0xc2c30, 0xc2c5e}, {0xc2c76, 0xc2c7b}, {0xc2d00, 0xc2d25}, {0xca72f, 0xca731}, + {0xca771, 0xca778}, {0xca793, 0xca795}, {0xcab30, 0xcab5a}, {0xcab60, 0xcab65}, + {0xcab70, 0xcabbf}, {0xcfb00, 0xcfb06}, {0xcfb13, 0xcfb17}, {0xcff41, 0xcff5a}, + {0xd0061, 0xd007a}, {0xd00df, 0xd00f6}, {0xd00f8, 0xd00ff}, {0xd017e, 0xd0180}, + {0xd0199, 0xd019b}, {0xd01bd, 0xd01bf}, {0xd0233, 0xd0239}, {0xd024f, 0xd0293}, + {0xd0295, 0xd02af}, {0xd037b, 0xd037d}, {0xd03ac, 0xd03ce}, {0xd03d5, 0xd03d7}, + {0xd03ef, 0xd03f3}, {0xd0430, 0xd045f}, {0xd0561, 0xd0587}, {0xd13f8, 0xd13fd}, + {0xd1c80, 0xd1c88}, {0xd1d00, 0xd1d2b}, {0xd1d6b, 0xd1d77}, {0xd1d79, 0xd1d9a}, + {0xd1e95, 0xd1e9d}, {0xd1eff, 0xd1f07}, {0xd1f10, 0xd1f15}, {0xd1f20, 0xd1f27}, + {0xd1f30, 0xd1f37}, {0xd1f40, 0xd1f45}, {0xd1f50, 0xd1f57}, {0xd1f60, 0xd1f67}, + {0xd1f70, 0xd1f7d}, {0xd1f80, 0xd1f87}, {0xd1f90, 0xd1f97}, {0xd1fa0, 0xd1fa7}, + {0xd1fb0, 0xd1fb4}, {0xd1fc2, 0xd1fc4}, {0xd1fd0, 0xd1fd3}, {0xd1fe0, 0xd1fe7}, + {0xd1ff2, 0xd1ff4}, {0xd2146, 0xd2149}, {0xd2c30, 0xd2c5e}, {0xd2c76, 0xd2c7b}, + {0xd2d00, 0xd2d25}, {0xda72f, 0xda731}, {0xda771, 0xda778}, {0xda793, 0xda795}, + {0xdab30, 0xdab5a}, {0xdab60, 0xdab65}, {0xdab70, 0xdabbf}, {0xdfb00, 0xdfb06}, + {0xdfb13, 0xdfb17}, {0xdff41, 0xdff5a}, {0xe0061, 0xe007a}, {0xe00df, 0xe00f6}, + {0xe00f8, 0xe00ff}, {0xe017e, 0xe0180}, {0xe0199, 0xe019b}, {0xe01bd, 0xe01bf}, + {0xe0233, 0xe0239}, {0xe024f, 0xe0293}, {0xe0295, 0xe02af}, {0xe037b, 0xe037d}, + {0xe03ac, 0xe03ce}, {0xe03d5, 0xe03d7}, {0xe03ef, 0xe03f3}, {0xe0430, 0xe045f}, + {0xe0561, 0xe0587}, {0xe13f8, 0xe13fd}, {0xe1c80, 0xe1c88}, {0xe1d00, 0xe1d2b}, + {0xe1d6b, 0xe1d77}, {0xe1d79, 0xe1d9a}, {0xe1e95, 0xe1e9d}, {0xe1eff, 0xe1f07}, + {0xe1f10, 0xe1f15}, {0xe1f20, 0xe1f27}, {0xe1f30, 0xe1f37}, {0xe1f40, 0xe1f45}, + {0xe1f50, 0xe1f57}, {0xe1f60, 0xe1f67}, {0xe1f70, 0xe1f7d}, {0xe1f80, 0xe1f87}, + {0xe1f90, 0xe1f97}, {0xe1fa0, 0xe1fa7}, {0xe1fb0, 0xe1fb4}, {0xe1fc2, 0xe1fc4}, + {0xe1fd0, 0xe1fd3}, {0xe1fe0, 0xe1fe7}, {0xe1ff2, 0xe1ff4}, {0xe2146, 0xe2149}, + {0xe2c30, 0xe2c5e}, {0xe2c76, 0xe2c7b}, {0xe2d00, 0xe2d25}, {0xea72f, 0xea731}, + {0xea771, 0xea778}, {0xea793, 0xea795}, {0xeab30, 0xeab5a}, {0xeab60, 0xeab65}, + {0xeab70, 0xeabbf}, {0xefb00, 0xefb06}, {0xefb13, 0xefb17}, {0xeff41, 0xeff5a}, + {0xf0061, 0xf007a}, {0xf00df, 0xf00f6}, {0xf00f8, 0xf00ff}, {0xf017e, 0xf0180}, + {0xf0199, 0xf019b}, {0xf01bd, 0xf01bf}, {0xf0233, 0xf0239}, {0xf024f, 0xf0293}, + {0xf0295, 0xf02af}, {0xf037b, 0xf037d}, {0xf03ac, 0xf03ce}, {0xf03d5, 0xf03d7}, + {0xf03ef, 0xf03f3}, {0xf0430, 0xf045f}, {0xf0561, 0xf0587}, {0xf13f8, 0xf13fd}, + {0xf1c80, 0xf1c88}, {0xf1d00, 0xf1d2b}, {0xf1d6b, 0xf1d77}, {0xf1d79, 0xf1d9a}, + {0xf1e95, 0xf1e9d}, {0xf1eff, 0xf1f07}, {0xf1f10, 0xf1f15}, {0xf1f20, 0xf1f27}, + {0xf1f30, 0xf1f37}, {0xf1f40, 0xf1f45}, {0xf1f50, 0xf1f57}, {0xf1f60, 0xf1f67}, + {0xf1f70, 0xf1f7d}, {0xf1f80, 0xf1f87}, {0xf1f90, 0xf1f97}, {0xf1fa0, 0xf1fa7}, + {0xf1fb0, 0xf1fb4}, {0xf1fc2, 0xf1fc4}, {0xf1fd0, 0xf1fd3}, {0xf1fe0, 0xf1fe7}, + {0xf1ff2, 0xf1ff4}, {0xf2146, 0xf2149}, {0xf2c30, 0xf2c5e}, {0xf2c76, 0xf2c7b}, + {0xf2d00, 0xf2d25}, {0xfa72f, 0xfa731}, {0xfa771, 0xfa778}, {0xfa793, 0xfa795}, + {0xfab30, 0xfab5a}, {0xfab60, 0xfab65}, {0xfab70, 0xfabbf}, {0xffb00, 0xffb06}, + {0xffb13, 0xffb17}, {0xfff41, 0xfff5a}, {0x100061, 0x10007a}, {0x1000df, 0x1000f6}, + {0x1000f8, 0x1000ff}, {0x10017e, 0x100180}, {0x100199, 0x10019b}, {0x1001bd, 0x1001bf}, + {0x100233, 0x100239}, {0x10024f, 0x100293}, {0x100295, 0x1002af}, {0x10037b, 0x10037d}, + {0x1003ac, 0x1003ce}, {0x1003d5, 0x1003d7}, {0x1003ef, 0x1003f3}, {0x100430, 0x10045f}, + {0x100561, 0x100587}, {0x1013f8, 0x1013fd}, {0x101c80, 0x101c88}, {0x101d00, 0x101d2b}, + {0x101d6b, 0x101d77}, {0x101d79, 0x101d9a}, {0x101e95, 0x101e9d}, {0x101eff, 0x101f07}, + {0x101f10, 0x101f15}, {0x101f20, 0x101f27}, {0x101f30, 0x101f37}, {0x101f40, 0x101f45}, + {0x101f50, 0x101f57}, {0x101f60, 0x101f67}, {0x101f70, 0x101f7d}, {0x101f80, 0x101f87}, + {0x101f90, 0x101f97}, {0x101fa0, 0x101fa7}, {0x101fb0, 0x101fb4}, {0x101fc2, 0x101fc4}, + {0x101fd0, 0x101fd3}, {0x101fe0, 0x101fe7}, {0x101ff2, 0x101ff4}, {0x102146, 0x102149}, + {0x102c30, 0x102c5e}, {0x102c76, 0x102c7b}, {0x102d00, 0x102d25}, {0x10a72f, 0x10a731}, + {0x10a771, 0x10a778}, {0x10a793, 0x10a795}, {0x10ab30, 0x10ab5a}, {0x10ab60, 0x10ab65}, + {0x10ab70, 0x10abbf}, {0x10fb00, 0x10fb06}, {0x10fb13, 0x10fb17}, {0x10ff41, 0x10ff5a} #endif }; @@ -499,7 +2591,1020 @@ static const chr lowerCharTable[] = { 0xa799, 0xa79b, 0xa79d, 0xa79f, 0xa7a1, 0xa7a3, 0xa7a5, 0xa7a7, 0xa7a9, 0xa7b5, 0xa7b7, 0xa7fa #if TCL_UTF_MAX > 4 - ,0x1d4bb, 0x1d7cb + ,0x100b5, 0x10101, 0x10103, 0x10105, 0x10107, 0x10109, 0x1010b, 0x1010d, 0x1010f, + 0x10111, 0x10113, 0x10115, 0x10117, 0x10119, 0x1011b, 0x1011d, 0x1011f, 0x10121, + 0x10123, 0x10125, 0x10127, 0x10129, 0x1012b, 0x1012d, 0x1012f, 0x10131, 0x10133, + 0x10135, 0x10137, 0x10138, 0x1013a, 0x1013c, 0x1013e, 0x10140, 0x10142, 0x10144, + 0x10146, 0x10148, 0x10149, 0x1014b, 0x1014d, 0x1014f, 0x10151, 0x10153, 0x10155, + 0x10157, 0x10159, 0x1015b, 0x1015d, 0x1015f, 0x10161, 0x10163, 0x10165, 0x10167, + 0x10169, 0x1016b, 0x1016d, 0x1016f, 0x10171, 0x10173, 0x10175, 0x10177, 0x1017a, + 0x1017c, 0x10183, 0x10185, 0x10188, 0x1018c, 0x1018d, 0x10192, 0x10195, 0x1019e, + 0x101a1, 0x101a3, 0x101a5, 0x101a8, 0x101aa, 0x101ab, 0x101ad, 0x101b0, 0x101b4, + 0x101b6, 0x101b9, 0x101ba, 0x101c6, 0x101c9, 0x101cc, 0x101ce, 0x101d0, 0x101d2, + 0x101d4, 0x101d6, 0x101d8, 0x101da, 0x101dc, 0x101dd, 0x101df, 0x101e1, 0x101e3, + 0x101e5, 0x101e7, 0x101e9, 0x101eb, 0x101ed, 0x101ef, 0x101f0, 0x101f3, 0x101f5, + 0x101f9, 0x101fb, 0x101fd, 0x101ff, 0x10201, 0x10203, 0x10205, 0x10207, 0x10209, + 0x1020b, 0x1020d, 0x1020f, 0x10211, 0x10213, 0x10215, 0x10217, 0x10219, 0x1021b, + 0x1021d, 0x1021f, 0x10221, 0x10223, 0x10225, 0x10227, 0x10229, 0x1022b, 0x1022d, + 0x1022f, 0x10231, 0x1023c, 0x1023f, 0x10240, 0x10242, 0x10247, 0x10249, 0x1024b, + 0x1024d, 0x10371, 0x10373, 0x10377, 0x10390, 0x103d0, 0x103d1, 0x103d9, 0x103db, + 0x103dd, 0x103df, 0x103e1, 0x103e3, 0x103e5, 0x103e7, 0x103e9, 0x103eb, 0x103ed, + 0x103f5, 0x103f8, 0x103fb, 0x103fc, 0x10461, 0x10463, 0x10465, 0x10467, 0x10469, + 0x1046b, 0x1046d, 0x1046f, 0x10471, 0x10473, 0x10475, 0x10477, 0x10479, 0x1047b, + 0x1047d, 0x1047f, 0x10481, 0x1048b, 0x1048d, 0x1048f, 0x10491, 0x10493, 0x10495, + 0x10497, 0x10499, 0x1049b, 0x1049d, 0x1049f, 0x104a1, 0x104a3, 0x104a5, 0x104a7, + 0x104a9, 0x104ab, 0x104ad, 0x104af, 0x104b1, 0x104b3, 0x104b5, 0x104b7, 0x104b9, + 0x104bb, 0x104bd, 0x104bf, 0x104c2, 0x104c4, 0x104c6, 0x104c8, 0x104ca, 0x104cc, + 0x104ce, 0x104cf, 0x104d1, 0x104d3, 0x104d5, 0x104d7, 0x104d9, 0x104db, 0x104dd, + 0x104df, 0x104e1, 0x104e3, 0x104e5, 0x104e7, 0x104e9, 0x104eb, 0x104ed, 0x104ef, + 0x104f1, 0x104f3, 0x104f5, 0x104f7, 0x104f9, 0x104fb, 0x104fd, 0x104ff, 0x10501, + 0x10503, 0x10505, 0x10507, 0x10509, 0x1050b, 0x1050d, 0x1050f, 0x10511, 0x10513, + 0x10515, 0x10517, 0x10519, 0x1051b, 0x1051d, 0x1051f, 0x10521, 0x10523, 0x10525, + 0x10527, 0x10529, 0x1052b, 0x1052d, 0x1052f, 0x11e01, 0x11e03, 0x11e05, 0x11e07, + 0x11e09, 0x11e0b, 0x11e0d, 0x11e0f, 0x11e11, 0x11e13, 0x11e15, 0x11e17, 0x11e19, + 0x11e1b, 0x11e1d, 0x11e1f, 0x11e21, 0x11e23, 0x11e25, 0x11e27, 0x11e29, 0x11e2b, + 0x11e2d, 0x11e2f, 0x11e31, 0x11e33, 0x11e35, 0x11e37, 0x11e39, 0x11e3b, 0x11e3d, + 0x11e3f, 0x11e41, 0x11e43, 0x11e45, 0x11e47, 0x11e49, 0x11e4b, 0x11e4d, 0x11e4f, + 0x11e51, 0x11e53, 0x11e55, 0x11e57, 0x11e59, 0x11e5b, 0x11e5d, 0x11e5f, 0x11e61, + 0x11e63, 0x11e65, 0x11e67, 0x11e69, 0x11e6b, 0x11e6d, 0x11e6f, 0x11e71, 0x11e73, + 0x11e75, 0x11e77, 0x11e79, 0x11e7b, 0x11e7d, 0x11e7f, 0x11e81, 0x11e83, 0x11e85, + 0x11e87, 0x11e89, 0x11e8b, 0x11e8d, 0x11e8f, 0x11e91, 0x11e93, 0x11e9f, 0x11ea1, + 0x11ea3, 0x11ea5, 0x11ea7, 0x11ea9, 0x11eab, 0x11ead, 0x11eaf, 0x11eb1, 0x11eb3, + 0x11eb5, 0x11eb7, 0x11eb9, 0x11ebb, 0x11ebd, 0x11ebf, 0x11ec1, 0x11ec3, 0x11ec5, + 0x11ec7, 0x11ec9, 0x11ecb, 0x11ecd, 0x11ecf, 0x11ed1, 0x11ed3, 0x11ed5, 0x11ed7, + 0x11ed9, 0x11edb, 0x11edd, 0x11edf, 0x11ee1, 0x11ee3, 0x11ee5, 0x11ee7, 0x11ee9, + 0x11eeb, 0x11eed, 0x11eef, 0x11ef1, 0x11ef3, 0x11ef5, 0x11ef7, 0x11ef9, 0x11efb, + 0x11efd, 0x11fb6, 0x11fb7, 0x11fbe, 0x11fc6, 0x11fc7, 0x11fd6, 0x11fd7, 0x11ff6, + 0x11ff7, 0x1210a, 0x1210e, 0x1210f, 0x12113, 0x1212f, 0x12134, 0x12139, 0x1213c, + 0x1213d, 0x1214e, 0x12184, 0x12c61, 0x12c65, 0x12c66, 0x12c68, 0x12c6a, 0x12c6c, + 0x12c71, 0x12c73, 0x12c74, 0x12c81, 0x12c83, 0x12c85, 0x12c87, 0x12c89, 0x12c8b, + 0x12c8d, 0x12c8f, 0x12c91, 0x12c93, 0x12c95, 0x12c97, 0x12c99, 0x12c9b, 0x12c9d, + 0x12c9f, 0x12ca1, 0x12ca3, 0x12ca5, 0x12ca7, 0x12ca9, 0x12cab, 0x12cad, 0x12caf, + 0x12cb1, 0x12cb3, 0x12cb5, 0x12cb7, 0x12cb9, 0x12cbb, 0x12cbd, 0x12cbf, 0x12cc1, + 0x12cc3, 0x12cc5, 0x12cc7, 0x12cc9, 0x12ccb, 0x12ccd, 0x12ccf, 0x12cd1, 0x12cd3, + 0x12cd5, 0x12cd7, 0x12cd9, 0x12cdb, 0x12cdd, 0x12cdf, 0x12ce1, 0x12ce3, 0x12ce4, + 0x12cec, 0x12cee, 0x12cf3, 0x12d27, 0x12d2d, 0x1a641, 0x1a643, 0x1a645, 0x1a647, + 0x1a649, 0x1a64b, 0x1a64d, 0x1a64f, 0x1a651, 0x1a653, 0x1a655, 0x1a657, 0x1a659, + 0x1a65b, 0x1a65d, 0x1a65f, 0x1a661, 0x1a663, 0x1a665, 0x1a667, 0x1a669, 0x1a66b, + 0x1a66d, 0x1a681, 0x1a683, 0x1a685, 0x1a687, 0x1a689, 0x1a68b, 0x1a68d, 0x1a68f, + 0x1a691, 0x1a693, 0x1a695, 0x1a697, 0x1a699, 0x1a69b, 0x1a723, 0x1a725, 0x1a727, + 0x1a729, 0x1a72b, 0x1a72d, 0x1a733, 0x1a735, 0x1a737, 0x1a739, 0x1a73b, 0x1a73d, + 0x1a73f, 0x1a741, 0x1a743, 0x1a745, 0x1a747, 0x1a749, 0x1a74b, 0x1a74d, 0x1a74f, + 0x1a751, 0x1a753, 0x1a755, 0x1a757, 0x1a759, 0x1a75b, 0x1a75d, 0x1a75f, 0x1a761, + 0x1a763, 0x1a765, 0x1a767, 0x1a769, 0x1a76b, 0x1a76d, 0x1a76f, 0x1a77a, 0x1a77c, + 0x1a77f, 0x1a781, 0x1a783, 0x1a785, 0x1a787, 0x1a78c, 0x1a78e, 0x1a791, 0x1a797, + 0x1a799, 0x1a79b, 0x1a79d, 0x1a79f, 0x1a7a1, 0x1a7a3, 0x1a7a5, 0x1a7a7, 0x1a7a9, + 0x1a7b5, 0x1a7b7, 0x1a7fa, 0x200b5, 0x20101, 0x20103, 0x20105, 0x20107, 0x20109, + 0x2010b, 0x2010d, 0x2010f, 0x20111, 0x20113, 0x20115, 0x20117, 0x20119, 0x2011b, + 0x2011d, 0x2011f, 0x20121, 0x20123, 0x20125, 0x20127, 0x20129, 0x2012b, 0x2012d, + 0x2012f, 0x20131, 0x20133, 0x20135, 0x20137, 0x20138, 0x2013a, 0x2013c, 0x2013e, + 0x20140, 0x20142, 0x20144, 0x20146, 0x20148, 0x20149, 0x2014b, 0x2014d, 0x2014f, + 0x20151, 0x20153, 0x20155, 0x20157, 0x20159, 0x2015b, 0x2015d, 0x2015f, 0x20161, + 0x20163, 0x20165, 0x20167, 0x20169, 0x2016b, 0x2016d, 0x2016f, 0x20171, 0x20173, + 0x20175, 0x20177, 0x2017a, 0x2017c, 0x20183, 0x20185, 0x20188, 0x2018c, 0x2018d, + 0x20192, 0x20195, 0x2019e, 0x201a1, 0x201a3, 0x201a5, 0x201a8, 0x201aa, 0x201ab, + 0x201ad, 0x201b0, 0x201b4, 0x201b6, 0x201b9, 0x201ba, 0x201c6, 0x201c9, 0x201cc, + 0x201ce, 0x201d0, 0x201d2, 0x201d4, 0x201d6, 0x201d8, 0x201da, 0x201dc, 0x201dd, + 0x201df, 0x201e1, 0x201e3, 0x201e5, 0x201e7, 0x201e9, 0x201eb, 0x201ed, 0x201ef, + 0x201f0, 0x201f3, 0x201f5, 0x201f9, 0x201fb, 0x201fd, 0x201ff, 0x20201, 0x20203, + 0x20205, 0x20207, 0x20209, 0x2020b, 0x2020d, 0x2020f, 0x20211, 0x20213, 0x20215, + 0x20217, 0x20219, 0x2021b, 0x2021d, 0x2021f, 0x20221, 0x20223, 0x20225, 0x20227, + 0x20229, 0x2022b, 0x2022d, 0x2022f, 0x20231, 0x2023c, 0x2023f, 0x20240, 0x20242, + 0x20247, 0x20249, 0x2024b, 0x2024d, 0x20371, 0x20373, 0x20377, 0x20390, 0x203d0, + 0x203d1, 0x203d9, 0x203db, 0x203dd, 0x203df, 0x203e1, 0x203e3, 0x203e5, 0x203e7, + 0x203e9, 0x203eb, 0x203ed, 0x203f5, 0x203f8, 0x203fb, 0x203fc, 0x20461, 0x20463, + 0x20465, 0x20467, 0x20469, 0x2046b, 0x2046d, 0x2046f, 0x20471, 0x20473, 0x20475, + 0x20477, 0x20479, 0x2047b, 0x2047d, 0x2047f, 0x20481, 0x2048b, 0x2048d, 0x2048f, + 0x20491, 0x20493, 0x20495, 0x20497, 0x20499, 0x2049b, 0x2049d, 0x2049f, 0x204a1, + 0x204a3, 0x204a5, 0x204a7, 0x204a9, 0x204ab, 0x204ad, 0x204af, 0x204b1, 0x204b3, + 0x204b5, 0x204b7, 0x204b9, 0x204bb, 0x204bd, 0x204bf, 0x204c2, 0x204c4, 0x204c6, + 0x204c8, 0x204ca, 0x204cc, 0x204ce, 0x204cf, 0x204d1, 0x204d3, 0x204d5, 0x204d7, + 0x204d9, 0x204db, 0x204dd, 0x204df, 0x204e1, 0x204e3, 0x204e5, 0x204e7, 0x204e9, + 0x204eb, 0x204ed, 0x204ef, 0x204f1, 0x204f3, 0x204f5, 0x204f7, 0x204f9, 0x204fb, + 0x204fd, 0x204ff, 0x20501, 0x20503, 0x20505, 0x20507, 0x20509, 0x2050b, 0x2050d, + 0x2050f, 0x20511, 0x20513, 0x20515, 0x20517, 0x20519, 0x2051b, 0x2051d, 0x2051f, + 0x20521, 0x20523, 0x20525, 0x20527, 0x20529, 0x2052b, 0x2052d, 0x2052f, 0x21e01, + 0x21e03, 0x21e05, 0x21e07, 0x21e09, 0x21e0b, 0x21e0d, 0x21e0f, 0x21e11, 0x21e13, + 0x21e15, 0x21e17, 0x21e19, 0x21e1b, 0x21e1d, 0x21e1f, 0x21e21, 0x21e23, 0x21e25, + 0x21e27, 0x21e29, 0x21e2b, 0x21e2d, 0x21e2f, 0x21e31, 0x21e33, 0x21e35, 0x21e37, + 0x21e39, 0x21e3b, 0x21e3d, 0x21e3f, 0x21e41, 0x21e43, 0x21e45, 0x21e47, 0x21e49, + 0x21e4b, 0x21e4d, 0x21e4f, 0x21e51, 0x21e53, 0x21e55, 0x21e57, 0x21e59, 0x21e5b, + 0x21e5d, 0x21e5f, 0x21e61, 0x21e63, 0x21e65, 0x21e67, 0x21e69, 0x21e6b, 0x21e6d, + 0x21e6f, 0x21e71, 0x21e73, 0x21e75, 0x21e77, 0x21e79, 0x21e7b, 0x21e7d, 0x21e7f, + 0x21e81, 0x21e83, 0x21e85, 0x21e87, 0x21e89, 0x21e8b, 0x21e8d, 0x21e8f, 0x21e91, + 0x21e93, 0x21e9f, 0x21ea1, 0x21ea3, 0x21ea5, 0x21ea7, 0x21ea9, 0x21eab, 0x21ead, + 0x21eaf, 0x21eb1, 0x21eb3, 0x21eb5, 0x21eb7, 0x21eb9, 0x21ebb, 0x21ebd, 0x21ebf, + 0x21ec1, 0x21ec3, 0x21ec5, 0x21ec7, 0x21ec9, 0x21ecb, 0x21ecd, 0x21ecf, 0x21ed1, + 0x21ed3, 0x21ed5, 0x21ed7, 0x21ed9, 0x21edb, 0x21edd, 0x21edf, 0x21ee1, 0x21ee3, + 0x21ee5, 0x21ee7, 0x21ee9, 0x21eeb, 0x21eed, 0x21eef, 0x21ef1, 0x21ef3, 0x21ef5, + 0x21ef7, 0x21ef9, 0x21efb, 0x21efd, 0x21fb6, 0x21fb7, 0x21fbe, 0x21fc6, 0x21fc7, + 0x21fd6, 0x21fd7, 0x21ff6, 0x21ff7, 0x2210a, 0x2210e, 0x2210f, 0x22113, 0x2212f, + 0x22134, 0x22139, 0x2213c, 0x2213d, 0x2214e, 0x22184, 0x22c61, 0x22c65, 0x22c66, + 0x22c68, 0x22c6a, 0x22c6c, 0x22c71, 0x22c73, 0x22c74, 0x22c81, 0x22c83, 0x22c85, + 0x22c87, 0x22c89, 0x22c8b, 0x22c8d, 0x22c8f, 0x22c91, 0x22c93, 0x22c95, 0x22c97, + 0x22c99, 0x22c9b, 0x22c9d, 0x22c9f, 0x22ca1, 0x22ca3, 0x22ca5, 0x22ca7, 0x22ca9, + 0x22cab, 0x22cad, 0x22caf, 0x22cb1, 0x22cb3, 0x22cb5, 0x22cb7, 0x22cb9, 0x22cbb, + 0x22cbd, 0x22cbf, 0x22cc1, 0x22cc3, 0x22cc5, 0x22cc7, 0x22cc9, 0x22ccb, 0x22ccd, + 0x22ccf, 0x22cd1, 0x22cd3, 0x22cd5, 0x22cd7, 0x22cd9, 0x22cdb, 0x22cdd, 0x22cdf, + 0x22ce1, 0x22ce3, 0x22ce4, 0x22cec, 0x22cee, 0x22cf3, 0x22d27, 0x22d2d, 0x2a641, + 0x2a643, 0x2a645, 0x2a647, 0x2a649, 0x2a64b, 0x2a64d, 0x2a64f, 0x2a651, 0x2a653, + 0x2a655, 0x2a657, 0x2a659, 0x2a65b, 0x2a65d, 0x2a65f, 0x2a661, 0x2a663, 0x2a665, + 0x2a667, 0x2a669, 0x2a66b, 0x2a66d, 0x2a681, 0x2a683, 0x2a685, 0x2a687, 0x2a689, + 0x2a68b, 0x2a68d, 0x2a68f, 0x2a691, 0x2a693, 0x2a695, 0x2a697, 0x2a699, 0x2a69b, + 0x2a723, 0x2a725, 0x2a727, 0x2a729, 0x2a72b, 0x2a72d, 0x2a733, 0x2a735, 0x2a737, + 0x2a739, 0x2a73b, 0x2a73d, 0x2a73f, 0x2a741, 0x2a743, 0x2a745, 0x2a747, 0x2a749, + 0x2a74b, 0x2a74d, 0x2a74f, 0x2a751, 0x2a753, 0x2a755, 0x2a757, 0x2a759, 0x2a75b, + 0x2a75d, 0x2a75f, 0x2a761, 0x2a763, 0x2a765, 0x2a767, 0x2a769, 0x2a76b, 0x2a76d, + 0x2a76f, 0x2a77a, 0x2a77c, 0x2a77f, 0x2a781, 0x2a783, 0x2a785, 0x2a787, 0x2a78c, + 0x2a78e, 0x2a791, 0x2a797, 0x2a799, 0x2a79b, 0x2a79d, 0x2a79f, 0x2a7a1, 0x2a7a3, + 0x2a7a5, 0x2a7a7, 0x2a7a9, 0x2a7b5, 0x2a7b7, 0x2a7fa, 0x300b5, 0x30101, 0x30103, + 0x30105, 0x30107, 0x30109, 0x3010b, 0x3010d, 0x3010f, 0x30111, 0x30113, 0x30115, + 0x30117, 0x30119, 0x3011b, 0x3011d, 0x3011f, 0x30121, 0x30123, 0x30125, 0x30127, + 0x30129, 0x3012b, 0x3012d, 0x3012f, 0x30131, 0x30133, 0x30135, 0x30137, 0x30138, + 0x3013a, 0x3013c, 0x3013e, 0x30140, 0x30142, 0x30144, 0x30146, 0x30148, 0x30149, + 0x3014b, 0x3014d, 0x3014f, 0x30151, 0x30153, 0x30155, 0x30157, 0x30159, 0x3015b, + 0x3015d, 0x3015f, 0x30161, 0x30163, 0x30165, 0x30167, 0x30169, 0x3016b, 0x3016d, + 0x3016f, 0x30171, 0x30173, 0x30175, 0x30177, 0x3017a, 0x3017c, 0x30183, 0x30185, + 0x30188, 0x3018c, 0x3018d, 0x30192, 0x30195, 0x3019e, 0x301a1, 0x301a3, 0x301a5, + 0x301a8, 0x301aa, 0x301ab, 0x301ad, 0x301b0, 0x301b4, 0x301b6, 0x301b9, 0x301ba, + 0x301c6, 0x301c9, 0x301cc, 0x301ce, 0x301d0, 0x301d2, 0x301d4, 0x301d6, 0x301d8, + 0x301da, 0x301dc, 0x301dd, 0x301df, 0x301e1, 0x301e3, 0x301e5, 0x301e7, 0x301e9, + 0x301eb, 0x301ed, 0x301ef, 0x301f0, 0x301f3, 0x301f5, 0x301f9, 0x301fb, 0x301fd, + 0x301ff, 0x30201, 0x30203, 0x30205, 0x30207, 0x30209, 0x3020b, 0x3020d, 0x3020f, + 0x30211, 0x30213, 0x30215, 0x30217, 0x30219, 0x3021b, 0x3021d, 0x3021f, 0x30221, + 0x30223, 0x30225, 0x30227, 0x30229, 0x3022b, 0x3022d, 0x3022f, 0x30231, 0x3023c, + 0x3023f, 0x30240, 0x30242, 0x30247, 0x30249, 0x3024b, 0x3024d, 0x30371, 0x30373, + 0x30377, 0x30390, 0x303d0, 0x303d1, 0x303d9, 0x303db, 0x303dd, 0x303df, 0x303e1, + 0x303e3, 0x303e5, 0x303e7, 0x303e9, 0x303eb, 0x303ed, 0x303f5, 0x303f8, 0x303fb, + 0x303fc, 0x30461, 0x30463, 0x30465, 0x30467, 0x30469, 0x3046b, 0x3046d, 0x3046f, + 0x30471, 0x30473, 0x30475, 0x30477, 0x30479, 0x3047b, 0x3047d, 0x3047f, 0x30481, + 0x3048b, 0x3048d, 0x3048f, 0x30491, 0x30493, 0x30495, 0x30497, 0x30499, 0x3049b, + 0x3049d, 0x3049f, 0x304a1, 0x304a3, 0x304a5, 0x304a7, 0x304a9, 0x304ab, 0x304ad, + 0x304af, 0x304b1, 0x304b3, 0x304b5, 0x304b7, 0x304b9, 0x304bb, 0x304bd, 0x304bf, + 0x304c2, 0x304c4, 0x304c6, 0x304c8, 0x304ca, 0x304cc, 0x304ce, 0x304cf, 0x304d1, + 0x304d3, 0x304d5, 0x304d7, 0x304d9, 0x304db, 0x304dd, 0x304df, 0x304e1, 0x304e3, + 0x304e5, 0x304e7, 0x304e9, 0x304eb, 0x304ed, 0x304ef, 0x304f1, 0x304f3, 0x304f5, + 0x304f7, 0x304f9, 0x304fb, 0x304fd, 0x304ff, 0x30501, 0x30503, 0x30505, 0x30507, + 0x30509, 0x3050b, 0x3050d, 0x3050f, 0x30511, 0x30513, 0x30515, 0x30517, 0x30519, + 0x3051b, 0x3051d, 0x3051f, 0x30521, 0x30523, 0x30525, 0x30527, 0x30529, 0x3052b, + 0x3052d, 0x3052f, 0x31e01, 0x31e03, 0x31e05, 0x31e07, 0x31e09, 0x31e0b, 0x31e0d, + 0x31e0f, 0x31e11, 0x31e13, 0x31e15, 0x31e17, 0x31e19, 0x31e1b, 0x31e1d, 0x31e1f, + 0x31e21, 0x31e23, 0x31e25, 0x31e27, 0x31e29, 0x31e2b, 0x31e2d, 0x31e2f, 0x31e31, + 0x31e33, 0x31e35, 0x31e37, 0x31e39, 0x31e3b, 0x31e3d, 0x31e3f, 0x31e41, 0x31e43, + 0x31e45, 0x31e47, 0x31e49, 0x31e4b, 0x31e4d, 0x31e4f, 0x31e51, 0x31e53, 0x31e55, + 0x31e57, 0x31e59, 0x31e5b, 0x31e5d, 0x31e5f, 0x31e61, 0x31e63, 0x31e65, 0x31e67, + 0x31e69, 0x31e6b, 0x31e6d, 0x31e6f, 0x31e71, 0x31e73, 0x31e75, 0x31e77, 0x31e79, + 0x31e7b, 0x31e7d, 0x31e7f, 0x31e81, 0x31e83, 0x31e85, 0x31e87, 0x31e89, 0x31e8b, + 0x31e8d, 0x31e8f, 0x31e91, 0x31e93, 0x31e9f, 0x31ea1, 0x31ea3, 0x31ea5, 0x31ea7, + 0x31ea9, 0x31eab, 0x31ead, 0x31eaf, 0x31eb1, 0x31eb3, 0x31eb5, 0x31eb7, 0x31eb9, + 0x31ebb, 0x31ebd, 0x31ebf, 0x31ec1, 0x31ec3, 0x31ec5, 0x31ec7, 0x31ec9, 0x31ecb, + 0x31ecd, 0x31ecf, 0x31ed1, 0x31ed3, 0x31ed5, 0x31ed7, 0x31ed9, 0x31edb, 0x31edd, + 0x31edf, 0x31ee1, 0x31ee3, 0x31ee5, 0x31ee7, 0x31ee9, 0x31eeb, 0x31eed, 0x31eef, + 0x31ef1, 0x31ef3, 0x31ef5, 0x31ef7, 0x31ef9, 0x31efb, 0x31efd, 0x31fb6, 0x31fb7, + 0x31fbe, 0x31fc6, 0x31fc7, 0x31fd6, 0x31fd7, 0x31ff6, 0x31ff7, 0x3210a, 0x3210e, + 0x3210f, 0x32113, 0x3212f, 0x32134, 0x32139, 0x3213c, 0x3213d, 0x3214e, 0x32184, + 0x32c61, 0x32c65, 0x32c66, 0x32c68, 0x32c6a, 0x32c6c, 0x32c71, 0x32c73, 0x32c74, + 0x32c81, 0x32c83, 0x32c85, 0x32c87, 0x32c89, 0x32c8b, 0x32c8d, 0x32c8f, 0x32c91, + 0x32c93, 0x32c95, 0x32c97, 0x32c99, 0x32c9b, 0x32c9d, 0x32c9f, 0x32ca1, 0x32ca3, + 0x32ca5, 0x32ca7, 0x32ca9, 0x32cab, 0x32cad, 0x32caf, 0x32cb1, 0x32cb3, 0x32cb5, + 0x32cb7, 0x32cb9, 0x32cbb, 0x32cbd, 0x32cbf, 0x32cc1, 0x32cc3, 0x32cc5, 0x32cc7, + 0x32cc9, 0x32ccb, 0x32ccd, 0x32ccf, 0x32cd1, 0x32cd3, 0x32cd5, 0x32cd7, 0x32cd9, + 0x32cdb, 0x32cdd, 0x32cdf, 0x32ce1, 0x32ce3, 0x32ce4, 0x32cec, 0x32cee, 0x32cf3, + 0x32d27, 0x32d2d, 0x3a641, 0x3a643, 0x3a645, 0x3a647, 0x3a649, 0x3a64b, 0x3a64d, + 0x3a64f, 0x3a651, 0x3a653, 0x3a655, 0x3a657, 0x3a659, 0x3a65b, 0x3a65d, 0x3a65f, + 0x3a661, 0x3a663, 0x3a665, 0x3a667, 0x3a669, 0x3a66b, 0x3a66d, 0x3a681, 0x3a683, + 0x3a685, 0x3a687, 0x3a689, 0x3a68b, 0x3a68d, 0x3a68f, 0x3a691, 0x3a693, 0x3a695, + 0x3a697, 0x3a699, 0x3a69b, 0x3a723, 0x3a725, 0x3a727, 0x3a729, 0x3a72b, 0x3a72d, + 0x3a733, 0x3a735, 0x3a737, 0x3a739, 0x3a73b, 0x3a73d, 0x3a73f, 0x3a741, 0x3a743, + 0x3a745, 0x3a747, 0x3a749, 0x3a74b, 0x3a74d, 0x3a74f, 0x3a751, 0x3a753, 0x3a755, + 0x3a757, 0x3a759, 0x3a75b, 0x3a75d, 0x3a75f, 0x3a761, 0x3a763, 0x3a765, 0x3a767, + 0x3a769, 0x3a76b, 0x3a76d, 0x3a76f, 0x3a77a, 0x3a77c, 0x3a77f, 0x3a781, 0x3a783, + 0x3a785, 0x3a787, 0x3a78c, 0x3a78e, 0x3a791, 0x3a797, 0x3a799, 0x3a79b, 0x3a79d, + 0x3a79f, 0x3a7a1, 0x3a7a3, 0x3a7a5, 0x3a7a7, 0x3a7a9, 0x3a7b5, 0x3a7b7, 0x3a7fa, + 0x400b5, 0x40101, 0x40103, 0x40105, 0x40107, 0x40109, 0x4010b, 0x4010d, 0x4010f, + 0x40111, 0x40113, 0x40115, 0x40117, 0x40119, 0x4011b, 0x4011d, 0x4011f, 0x40121, + 0x40123, 0x40125, 0x40127, 0x40129, 0x4012b, 0x4012d, 0x4012f, 0x40131, 0x40133, + 0x40135, 0x40137, 0x40138, 0x4013a, 0x4013c, 0x4013e, 0x40140, 0x40142, 0x40144, + 0x40146, 0x40148, 0x40149, 0x4014b, 0x4014d, 0x4014f, 0x40151, 0x40153, 0x40155, + 0x40157, 0x40159, 0x4015b, 0x4015d, 0x4015f, 0x40161, 0x40163, 0x40165, 0x40167, + 0x40169, 0x4016b, 0x4016d, 0x4016f, 0x40171, 0x40173, 0x40175, 0x40177, 0x4017a, + 0x4017c, 0x40183, 0x40185, 0x40188, 0x4018c, 0x4018d, 0x40192, 0x40195, 0x4019e, + 0x401a1, 0x401a3, 0x401a5, 0x401a8, 0x401aa, 0x401ab, 0x401ad, 0x401b0, 0x401b4, + 0x401b6, 0x401b9, 0x401ba, 0x401c6, 0x401c9, 0x401cc, 0x401ce, 0x401d0, 0x401d2, + 0x401d4, 0x401d6, 0x401d8, 0x401da, 0x401dc, 0x401dd, 0x401df, 0x401e1, 0x401e3, + 0x401e5, 0x401e7, 0x401e9, 0x401eb, 0x401ed, 0x401ef, 0x401f0, 0x401f3, 0x401f5, + 0x401f9, 0x401fb, 0x401fd, 0x401ff, 0x40201, 0x40203, 0x40205, 0x40207, 0x40209, + 0x4020b, 0x4020d, 0x4020f, 0x40211, 0x40213, 0x40215, 0x40217, 0x40219, 0x4021b, + 0x4021d, 0x4021f, 0x40221, 0x40223, 0x40225, 0x40227, 0x40229, 0x4022b, 0x4022d, + 0x4022f, 0x40231, 0x4023c, 0x4023f, 0x40240, 0x40242, 0x40247, 0x40249, 0x4024b, + 0x4024d, 0x40371, 0x40373, 0x40377, 0x40390, 0x403d0, 0x403d1, 0x403d9, 0x403db, + 0x403dd, 0x403df, 0x403e1, 0x403e3, 0x403e5, 0x403e7, 0x403e9, 0x403eb, 0x403ed, + 0x403f5, 0x403f8, 0x403fb, 0x403fc, 0x40461, 0x40463, 0x40465, 0x40467, 0x40469, + 0x4046b, 0x4046d, 0x4046f, 0x40471, 0x40473, 0x40475, 0x40477, 0x40479, 0x4047b, + 0x4047d, 0x4047f, 0x40481, 0x4048b, 0x4048d, 0x4048f, 0x40491, 0x40493, 0x40495, + 0x40497, 0x40499, 0x4049b, 0x4049d, 0x4049f, 0x404a1, 0x404a3, 0x404a5, 0x404a7, + 0x404a9, 0x404ab, 0x404ad, 0x404af, 0x404b1, 0x404b3, 0x404b5, 0x404b7, 0x404b9, + 0x404bb, 0x404bd, 0x404bf, 0x404c2, 0x404c4, 0x404c6, 0x404c8, 0x404ca, 0x404cc, + 0x404ce, 0x404cf, 0x404d1, 0x404d3, 0x404d5, 0x404d7, 0x404d9, 0x404db, 0x404dd, + 0x404df, 0x404e1, 0x404e3, 0x404e5, 0x404e7, 0x404e9, 0x404eb, 0x404ed, 0x404ef, + 0x404f1, 0x404f3, 0x404f5, 0x404f7, 0x404f9, 0x404fb, 0x404fd, 0x404ff, 0x40501, + 0x40503, 0x40505, 0x40507, 0x40509, 0x4050b, 0x4050d, 0x4050f, 0x40511, 0x40513, + 0x40515, 0x40517, 0x40519, 0x4051b, 0x4051d, 0x4051f, 0x40521, 0x40523, 0x40525, + 0x40527, 0x40529, 0x4052b, 0x4052d, 0x4052f, 0x41e01, 0x41e03, 0x41e05, 0x41e07, + 0x41e09, 0x41e0b, 0x41e0d, 0x41e0f, 0x41e11, 0x41e13, 0x41e15, 0x41e17, 0x41e19, + 0x41e1b, 0x41e1d, 0x41e1f, 0x41e21, 0x41e23, 0x41e25, 0x41e27, 0x41e29, 0x41e2b, + 0x41e2d, 0x41e2f, 0x41e31, 0x41e33, 0x41e35, 0x41e37, 0x41e39, 0x41e3b, 0x41e3d, + 0x41e3f, 0x41e41, 0x41e43, 0x41e45, 0x41e47, 0x41e49, 0x41e4b, 0x41e4d, 0x41e4f, + 0x41e51, 0x41e53, 0x41e55, 0x41e57, 0x41e59, 0x41e5b, 0x41e5d, 0x41e5f, 0x41e61, + 0x41e63, 0x41e65, 0x41e67, 0x41e69, 0x41e6b, 0x41e6d, 0x41e6f, 0x41e71, 0x41e73, + 0x41e75, 0x41e77, 0x41e79, 0x41e7b, 0x41e7d, 0x41e7f, 0x41e81, 0x41e83, 0x41e85, + 0x41e87, 0x41e89, 0x41e8b, 0x41e8d, 0x41e8f, 0x41e91, 0x41e93, 0x41e9f, 0x41ea1, + 0x41ea3, 0x41ea5, 0x41ea7, 0x41ea9, 0x41eab, 0x41ead, 0x41eaf, 0x41eb1, 0x41eb3, + 0x41eb5, 0x41eb7, 0x41eb9, 0x41ebb, 0x41ebd, 0x41ebf, 0x41ec1, 0x41ec3, 0x41ec5, + 0x41ec7, 0x41ec9, 0x41ecb, 0x41ecd, 0x41ecf, 0x41ed1, 0x41ed3, 0x41ed5, 0x41ed7, + 0x41ed9, 0x41edb, 0x41edd, 0x41edf, 0x41ee1, 0x41ee3, 0x41ee5, 0x41ee7, 0x41ee9, + 0x41eeb, 0x41eed, 0x41eef, 0x41ef1, 0x41ef3, 0x41ef5, 0x41ef7, 0x41ef9, 0x41efb, + 0x41efd, 0x41fb6, 0x41fb7, 0x41fbe, 0x41fc6, 0x41fc7, 0x41fd6, 0x41fd7, 0x41ff6, + 0x41ff7, 0x4210a, 0x4210e, 0x4210f, 0x42113, 0x4212f, 0x42134, 0x42139, 0x4213c, + 0x4213d, 0x4214e, 0x42184, 0x42c61, 0x42c65, 0x42c66, 0x42c68, 0x42c6a, 0x42c6c, + 0x42c71, 0x42c73, 0x42c74, 0x42c81, 0x42c83, 0x42c85, 0x42c87, 0x42c89, 0x42c8b, + 0x42c8d, 0x42c8f, 0x42c91, 0x42c93, 0x42c95, 0x42c97, 0x42c99, 0x42c9b, 0x42c9d, + 0x42c9f, 0x42ca1, 0x42ca3, 0x42ca5, 0x42ca7, 0x42ca9, 0x42cab, 0x42cad, 0x42caf, + 0x42cb1, 0x42cb3, 0x42cb5, 0x42cb7, 0x42cb9, 0x42cbb, 0x42cbd, 0x42cbf, 0x42cc1, + 0x42cc3, 0x42cc5, 0x42cc7, 0x42cc9, 0x42ccb, 0x42ccd, 0x42ccf, 0x42cd1, 0x42cd3, + 0x42cd5, 0x42cd7, 0x42cd9, 0x42cdb, 0x42cdd, 0x42cdf, 0x42ce1, 0x42ce3, 0x42ce4, + 0x42cec, 0x42cee, 0x42cf3, 0x42d27, 0x42d2d, 0x4a641, 0x4a643, 0x4a645, 0x4a647, + 0x4a649, 0x4a64b, 0x4a64d, 0x4a64f, 0x4a651, 0x4a653, 0x4a655, 0x4a657, 0x4a659, + 0x4a65b, 0x4a65d, 0x4a65f, 0x4a661, 0x4a663, 0x4a665, 0x4a667, 0x4a669, 0x4a66b, + 0x4a66d, 0x4a681, 0x4a683, 0x4a685, 0x4a687, 0x4a689, 0x4a68b, 0x4a68d, 0x4a68f, + 0x4a691, 0x4a693, 0x4a695, 0x4a697, 0x4a699, 0x4a69b, 0x4a723, 0x4a725, 0x4a727, + 0x4a729, 0x4a72b, 0x4a72d, 0x4a733, 0x4a735, 0x4a737, 0x4a739, 0x4a73b, 0x4a73d, + 0x4a73f, 0x4a741, 0x4a743, 0x4a745, 0x4a747, 0x4a749, 0x4a74b, 0x4a74d, 0x4a74f, + 0x4a751, 0x4a753, 0x4a755, 0x4a757, 0x4a759, 0x4a75b, 0x4a75d, 0x4a75f, 0x4a761, + 0x4a763, 0x4a765, 0x4a767, 0x4a769, 0x4a76b, 0x4a76d, 0x4a76f, 0x4a77a, 0x4a77c, + 0x4a77f, 0x4a781, 0x4a783, 0x4a785, 0x4a787, 0x4a78c, 0x4a78e, 0x4a791, 0x4a797, + 0x4a799, 0x4a79b, 0x4a79d, 0x4a79f, 0x4a7a1, 0x4a7a3, 0x4a7a5, 0x4a7a7, 0x4a7a9, + 0x4a7b5, 0x4a7b7, 0x4a7fa, 0x500b5, 0x50101, 0x50103, 0x50105, 0x50107, 0x50109, + 0x5010b, 0x5010d, 0x5010f, 0x50111, 0x50113, 0x50115, 0x50117, 0x50119, 0x5011b, + 0x5011d, 0x5011f, 0x50121, 0x50123, 0x50125, 0x50127, 0x50129, 0x5012b, 0x5012d, + 0x5012f, 0x50131, 0x50133, 0x50135, 0x50137, 0x50138, 0x5013a, 0x5013c, 0x5013e, + 0x50140, 0x50142, 0x50144, 0x50146, 0x50148, 0x50149, 0x5014b, 0x5014d, 0x5014f, + 0x50151, 0x50153, 0x50155, 0x50157, 0x50159, 0x5015b, 0x5015d, 0x5015f, 0x50161, + 0x50163, 0x50165, 0x50167, 0x50169, 0x5016b, 0x5016d, 0x5016f, 0x50171, 0x50173, + 0x50175, 0x50177, 0x5017a, 0x5017c, 0x50183, 0x50185, 0x50188, 0x5018c, 0x5018d, + 0x50192, 0x50195, 0x5019e, 0x501a1, 0x501a3, 0x501a5, 0x501a8, 0x501aa, 0x501ab, + 0x501ad, 0x501b0, 0x501b4, 0x501b6, 0x501b9, 0x501ba, 0x501c6, 0x501c9, 0x501cc, + 0x501ce, 0x501d0, 0x501d2, 0x501d4, 0x501d6, 0x501d8, 0x501da, 0x501dc, 0x501dd, + 0x501df, 0x501e1, 0x501e3, 0x501e5, 0x501e7, 0x501e9, 0x501eb, 0x501ed, 0x501ef, + 0x501f0, 0x501f3, 0x501f5, 0x501f9, 0x501fb, 0x501fd, 0x501ff, 0x50201, 0x50203, + 0x50205, 0x50207, 0x50209, 0x5020b, 0x5020d, 0x5020f, 0x50211, 0x50213, 0x50215, + 0x50217, 0x50219, 0x5021b, 0x5021d, 0x5021f, 0x50221, 0x50223, 0x50225, 0x50227, + 0x50229, 0x5022b, 0x5022d, 0x5022f, 0x50231, 0x5023c, 0x5023f, 0x50240, 0x50242, + 0x50247, 0x50249, 0x5024b, 0x5024d, 0x50371, 0x50373, 0x50377, 0x50390, 0x503d0, + 0x503d1, 0x503d9, 0x503db, 0x503dd, 0x503df, 0x503e1, 0x503e3, 0x503e5, 0x503e7, + 0x503e9, 0x503eb, 0x503ed, 0x503f5, 0x503f8, 0x503fb, 0x503fc, 0x50461, 0x50463, + 0x50465, 0x50467, 0x50469, 0x5046b, 0x5046d, 0x5046f, 0x50471, 0x50473, 0x50475, + 0x50477, 0x50479, 0x5047b, 0x5047d, 0x5047f, 0x50481, 0x5048b, 0x5048d, 0x5048f, + 0x50491, 0x50493, 0x50495, 0x50497, 0x50499, 0x5049b, 0x5049d, 0x5049f, 0x504a1, + 0x504a3, 0x504a5, 0x504a7, 0x504a9, 0x504ab, 0x504ad, 0x504af, 0x504b1, 0x504b3, + 0x504b5, 0x504b7, 0x504b9, 0x504bb, 0x504bd, 0x504bf, 0x504c2, 0x504c4, 0x504c6, + 0x504c8, 0x504ca, 0x504cc, 0x504ce, 0x504cf, 0x504d1, 0x504d3, 0x504d5, 0x504d7, + 0x504d9, 0x504db, 0x504dd, 0x504df, 0x504e1, 0x504e3, 0x504e5, 0x504e7, 0x504e9, + 0x504eb, 0x504ed, 0x504ef, 0x504f1, 0x504f3, 0x504f5, 0x504f7, 0x504f9, 0x504fb, + 0x504fd, 0x504ff, 0x50501, 0x50503, 0x50505, 0x50507, 0x50509, 0x5050b, 0x5050d, + 0x5050f, 0x50511, 0x50513, 0x50515, 0x50517, 0x50519, 0x5051b, 0x5051d, 0x5051f, + 0x50521, 0x50523, 0x50525, 0x50527, 0x50529, 0x5052b, 0x5052d, 0x5052f, 0x51e01, + 0x51e03, 0x51e05, 0x51e07, 0x51e09, 0x51e0b, 0x51e0d, 0x51e0f, 0x51e11, 0x51e13, + 0x51e15, 0x51e17, 0x51e19, 0x51e1b, 0x51e1d, 0x51e1f, 0x51e21, 0x51e23, 0x51e25, + 0x51e27, 0x51e29, 0x51e2b, 0x51e2d, 0x51e2f, 0x51e31, 0x51e33, 0x51e35, 0x51e37, + 0x51e39, 0x51e3b, 0x51e3d, 0x51e3f, 0x51e41, 0x51e43, 0x51e45, 0x51e47, 0x51e49, + 0x51e4b, 0x51e4d, 0x51e4f, 0x51e51, 0x51e53, 0x51e55, 0x51e57, 0x51e59, 0x51e5b, + 0x51e5d, 0x51e5f, 0x51e61, 0x51e63, 0x51e65, 0x51e67, 0x51e69, 0x51e6b, 0x51e6d, + 0x51e6f, 0x51e71, 0x51e73, 0x51e75, 0x51e77, 0x51e79, 0x51e7b, 0x51e7d, 0x51e7f, + 0x51e81, 0x51e83, 0x51e85, 0x51e87, 0x51e89, 0x51e8b, 0x51e8d, 0x51e8f, 0x51e91, + 0x51e93, 0x51e9f, 0x51ea1, 0x51ea3, 0x51ea5, 0x51ea7, 0x51ea9, 0x51eab, 0x51ead, + 0x51eaf, 0x51eb1, 0x51eb3, 0x51eb5, 0x51eb7, 0x51eb9, 0x51ebb, 0x51ebd, 0x51ebf, + 0x51ec1, 0x51ec3, 0x51ec5, 0x51ec7, 0x51ec9, 0x51ecb, 0x51ecd, 0x51ecf, 0x51ed1, + 0x51ed3, 0x51ed5, 0x51ed7, 0x51ed9, 0x51edb, 0x51edd, 0x51edf, 0x51ee1, 0x51ee3, + 0x51ee5, 0x51ee7, 0x51ee9, 0x51eeb, 0x51eed, 0x51eef, 0x51ef1, 0x51ef3, 0x51ef5, + 0x51ef7, 0x51ef9, 0x51efb, 0x51efd, 0x51fb6, 0x51fb7, 0x51fbe, 0x51fc6, 0x51fc7, + 0x51fd6, 0x51fd7, 0x51ff6, 0x51ff7, 0x5210a, 0x5210e, 0x5210f, 0x52113, 0x5212f, + 0x52134, 0x52139, 0x5213c, 0x5213d, 0x5214e, 0x52184, 0x52c61, 0x52c65, 0x52c66, + 0x52c68, 0x52c6a, 0x52c6c, 0x52c71, 0x52c73, 0x52c74, 0x52c81, 0x52c83, 0x52c85, + 0x52c87, 0x52c89, 0x52c8b, 0x52c8d, 0x52c8f, 0x52c91, 0x52c93, 0x52c95, 0x52c97, + 0x52c99, 0x52c9b, 0x52c9d, 0x52c9f, 0x52ca1, 0x52ca3, 0x52ca5, 0x52ca7, 0x52ca9, + 0x52cab, 0x52cad, 0x52caf, 0x52cb1, 0x52cb3, 0x52cb5, 0x52cb7, 0x52cb9, 0x52cbb, + 0x52cbd, 0x52cbf, 0x52cc1, 0x52cc3, 0x52cc5, 0x52cc7, 0x52cc9, 0x52ccb, 0x52ccd, + 0x52ccf, 0x52cd1, 0x52cd3, 0x52cd5, 0x52cd7, 0x52cd9, 0x52cdb, 0x52cdd, 0x52cdf, + 0x52ce1, 0x52ce3, 0x52ce4, 0x52cec, 0x52cee, 0x52cf3, 0x52d27, 0x52d2d, 0x5a641, + 0x5a643, 0x5a645, 0x5a647, 0x5a649, 0x5a64b, 0x5a64d, 0x5a64f, 0x5a651, 0x5a653, + 0x5a655, 0x5a657, 0x5a659, 0x5a65b, 0x5a65d, 0x5a65f, 0x5a661, 0x5a663, 0x5a665, + 0x5a667, 0x5a669, 0x5a66b, 0x5a66d, 0x5a681, 0x5a683, 0x5a685, 0x5a687, 0x5a689, + 0x5a68b, 0x5a68d, 0x5a68f, 0x5a691, 0x5a693, 0x5a695, 0x5a697, 0x5a699, 0x5a69b, + 0x5a723, 0x5a725, 0x5a727, 0x5a729, 0x5a72b, 0x5a72d, 0x5a733, 0x5a735, 0x5a737, + 0x5a739, 0x5a73b, 0x5a73d, 0x5a73f, 0x5a741, 0x5a743, 0x5a745, 0x5a747, 0x5a749, + 0x5a74b, 0x5a74d, 0x5a74f, 0x5a751, 0x5a753, 0x5a755, 0x5a757, 0x5a759, 0x5a75b, + 0x5a75d, 0x5a75f, 0x5a761, 0x5a763, 0x5a765, 0x5a767, 0x5a769, 0x5a76b, 0x5a76d, + 0x5a76f, 0x5a77a, 0x5a77c, 0x5a77f, 0x5a781, 0x5a783, 0x5a785, 0x5a787, 0x5a78c, + 0x5a78e, 0x5a791, 0x5a797, 0x5a799, 0x5a79b, 0x5a79d, 0x5a79f, 0x5a7a1, 0x5a7a3, + 0x5a7a5, 0x5a7a7, 0x5a7a9, 0x5a7b5, 0x5a7b7, 0x5a7fa, 0x600b5, 0x60101, 0x60103, + 0x60105, 0x60107, 0x60109, 0x6010b, 0x6010d, 0x6010f, 0x60111, 0x60113, 0x60115, + 0x60117, 0x60119, 0x6011b, 0x6011d, 0x6011f, 0x60121, 0x60123, 0x60125, 0x60127, + 0x60129, 0x6012b, 0x6012d, 0x6012f, 0x60131, 0x60133, 0x60135, 0x60137, 0x60138, + 0x6013a, 0x6013c, 0x6013e, 0x60140, 0x60142, 0x60144, 0x60146, 0x60148, 0x60149, + 0x6014b, 0x6014d, 0x6014f, 0x60151, 0x60153, 0x60155, 0x60157, 0x60159, 0x6015b, + 0x6015d, 0x6015f, 0x60161, 0x60163, 0x60165, 0x60167, 0x60169, 0x6016b, 0x6016d, + 0x6016f, 0x60171, 0x60173, 0x60175, 0x60177, 0x6017a, 0x6017c, 0x60183, 0x60185, + 0x60188, 0x6018c, 0x6018d, 0x60192, 0x60195, 0x6019e, 0x601a1, 0x601a3, 0x601a5, + 0x601a8, 0x601aa, 0x601ab, 0x601ad, 0x601b0, 0x601b4, 0x601b6, 0x601b9, 0x601ba, + 0x601c6, 0x601c9, 0x601cc, 0x601ce, 0x601d0, 0x601d2, 0x601d4, 0x601d6, 0x601d8, + 0x601da, 0x601dc, 0x601dd, 0x601df, 0x601e1, 0x601e3, 0x601e5, 0x601e7, 0x601e9, + 0x601eb, 0x601ed, 0x601ef, 0x601f0, 0x601f3, 0x601f5, 0x601f9, 0x601fb, 0x601fd, + 0x601ff, 0x60201, 0x60203, 0x60205, 0x60207, 0x60209, 0x6020b, 0x6020d, 0x6020f, + 0x60211, 0x60213, 0x60215, 0x60217, 0x60219, 0x6021b, 0x6021d, 0x6021f, 0x60221, + 0x60223, 0x60225, 0x60227, 0x60229, 0x6022b, 0x6022d, 0x6022f, 0x60231, 0x6023c, + 0x6023f, 0x60240, 0x60242, 0x60247, 0x60249, 0x6024b, 0x6024d, 0x60371, 0x60373, + 0x60377, 0x60390, 0x603d0, 0x603d1, 0x603d9, 0x603db, 0x603dd, 0x603df, 0x603e1, + 0x603e3, 0x603e5, 0x603e7, 0x603e9, 0x603eb, 0x603ed, 0x603f5, 0x603f8, 0x603fb, + 0x603fc, 0x60461, 0x60463, 0x60465, 0x60467, 0x60469, 0x6046b, 0x6046d, 0x6046f, + 0x60471, 0x60473, 0x60475, 0x60477, 0x60479, 0x6047b, 0x6047d, 0x6047f, 0x60481, + 0x6048b, 0x6048d, 0x6048f, 0x60491, 0x60493, 0x60495, 0x60497, 0x60499, 0x6049b, + 0x6049d, 0x6049f, 0x604a1, 0x604a3, 0x604a5, 0x604a7, 0x604a9, 0x604ab, 0x604ad, + 0x604af, 0x604b1, 0x604b3, 0x604b5, 0x604b7, 0x604b9, 0x604bb, 0x604bd, 0x604bf, + 0x604c2, 0x604c4, 0x604c6, 0x604c8, 0x604ca, 0x604cc, 0x604ce, 0x604cf, 0x604d1, + 0x604d3, 0x604d5, 0x604d7, 0x604d9, 0x604db, 0x604dd, 0x604df, 0x604e1, 0x604e3, + 0x604e5, 0x604e7, 0x604e9, 0x604eb, 0x604ed, 0x604ef, 0x604f1, 0x604f3, 0x604f5, + 0x604f7, 0x604f9, 0x604fb, 0x604fd, 0x604ff, 0x60501, 0x60503, 0x60505, 0x60507, + 0x60509, 0x6050b, 0x6050d, 0x6050f, 0x60511, 0x60513, 0x60515, 0x60517, 0x60519, + 0x6051b, 0x6051d, 0x6051f, 0x60521, 0x60523, 0x60525, 0x60527, 0x60529, 0x6052b, + 0x6052d, 0x6052f, 0x61e01, 0x61e03, 0x61e05, 0x61e07, 0x61e09, 0x61e0b, 0x61e0d, + 0x61e0f, 0x61e11, 0x61e13, 0x61e15, 0x61e17, 0x61e19, 0x61e1b, 0x61e1d, 0x61e1f, + 0x61e21, 0x61e23, 0x61e25, 0x61e27, 0x61e29, 0x61e2b, 0x61e2d, 0x61e2f, 0x61e31, + 0x61e33, 0x61e35, 0x61e37, 0x61e39, 0x61e3b, 0x61e3d, 0x61e3f, 0x61e41, 0x61e43, + 0x61e45, 0x61e47, 0x61e49, 0x61e4b, 0x61e4d, 0x61e4f, 0x61e51, 0x61e53, 0x61e55, + 0x61e57, 0x61e59, 0x61e5b, 0x61e5d, 0x61e5f, 0x61e61, 0x61e63, 0x61e65, 0x61e67, + 0x61e69, 0x61e6b, 0x61e6d, 0x61e6f, 0x61e71, 0x61e73, 0x61e75, 0x61e77, 0x61e79, + 0x61e7b, 0x61e7d, 0x61e7f, 0x61e81, 0x61e83, 0x61e85, 0x61e87, 0x61e89, 0x61e8b, + 0x61e8d, 0x61e8f, 0x61e91, 0x61e93, 0x61e9f, 0x61ea1, 0x61ea3, 0x61ea5, 0x61ea7, + 0x61ea9, 0x61eab, 0x61ead, 0x61eaf, 0x61eb1, 0x61eb3, 0x61eb5, 0x61eb7, 0x61eb9, + 0x61ebb, 0x61ebd, 0x61ebf, 0x61ec1, 0x61ec3, 0x61ec5, 0x61ec7, 0x61ec9, 0x61ecb, + 0x61ecd, 0x61ecf, 0x61ed1, 0x61ed3, 0x61ed5, 0x61ed7, 0x61ed9, 0x61edb, 0x61edd, + 0x61edf, 0x61ee1, 0x61ee3, 0x61ee5, 0x61ee7, 0x61ee9, 0x61eeb, 0x61eed, 0x61eef, + 0x61ef1, 0x61ef3, 0x61ef5, 0x61ef7, 0x61ef9, 0x61efb, 0x61efd, 0x61fb6, 0x61fb7, + 0x61fbe, 0x61fc6, 0x61fc7, 0x61fd6, 0x61fd7, 0x61ff6, 0x61ff7, 0x6210a, 0x6210e, + 0x6210f, 0x62113, 0x6212f, 0x62134, 0x62139, 0x6213c, 0x6213d, 0x6214e, 0x62184, + 0x62c61, 0x62c65, 0x62c66, 0x62c68, 0x62c6a, 0x62c6c, 0x62c71, 0x62c73, 0x62c74, + 0x62c81, 0x62c83, 0x62c85, 0x62c87, 0x62c89, 0x62c8b, 0x62c8d, 0x62c8f, 0x62c91, + 0x62c93, 0x62c95, 0x62c97, 0x62c99, 0x62c9b, 0x62c9d, 0x62c9f, 0x62ca1, 0x62ca3, + 0x62ca5, 0x62ca7, 0x62ca9, 0x62cab, 0x62cad, 0x62caf, 0x62cb1, 0x62cb3, 0x62cb5, + 0x62cb7, 0x62cb9, 0x62cbb, 0x62cbd, 0x62cbf, 0x62cc1, 0x62cc3, 0x62cc5, 0x62cc7, + 0x62cc9, 0x62ccb, 0x62ccd, 0x62ccf, 0x62cd1, 0x62cd3, 0x62cd5, 0x62cd7, 0x62cd9, + 0x62cdb, 0x62cdd, 0x62cdf, 0x62ce1, 0x62ce3, 0x62ce4, 0x62cec, 0x62cee, 0x62cf3, + 0x62d27, 0x62d2d, 0x6a641, 0x6a643, 0x6a645, 0x6a647, 0x6a649, 0x6a64b, 0x6a64d, + 0x6a64f, 0x6a651, 0x6a653, 0x6a655, 0x6a657, 0x6a659, 0x6a65b, 0x6a65d, 0x6a65f, + 0x6a661, 0x6a663, 0x6a665, 0x6a667, 0x6a669, 0x6a66b, 0x6a66d, 0x6a681, 0x6a683, + 0x6a685, 0x6a687, 0x6a689, 0x6a68b, 0x6a68d, 0x6a68f, 0x6a691, 0x6a693, 0x6a695, + 0x6a697, 0x6a699, 0x6a69b, 0x6a723, 0x6a725, 0x6a727, 0x6a729, 0x6a72b, 0x6a72d, + 0x6a733, 0x6a735, 0x6a737, 0x6a739, 0x6a73b, 0x6a73d, 0x6a73f, 0x6a741, 0x6a743, + 0x6a745, 0x6a747, 0x6a749, 0x6a74b, 0x6a74d, 0x6a74f, 0x6a751, 0x6a753, 0x6a755, + 0x6a757, 0x6a759, 0x6a75b, 0x6a75d, 0x6a75f, 0x6a761, 0x6a763, 0x6a765, 0x6a767, + 0x6a769, 0x6a76b, 0x6a76d, 0x6a76f, 0x6a77a, 0x6a77c, 0x6a77f, 0x6a781, 0x6a783, + 0x6a785, 0x6a787, 0x6a78c, 0x6a78e, 0x6a791, 0x6a797, 0x6a799, 0x6a79b, 0x6a79d, + 0x6a79f, 0x6a7a1, 0x6a7a3, 0x6a7a5, 0x6a7a7, 0x6a7a9, 0x6a7b5, 0x6a7b7, 0x6a7fa, + 0x700b5, 0x70101, 0x70103, 0x70105, 0x70107, 0x70109, 0x7010b, 0x7010d, 0x7010f, + 0x70111, 0x70113, 0x70115, 0x70117, 0x70119, 0x7011b, 0x7011d, 0x7011f, 0x70121, + 0x70123, 0x70125, 0x70127, 0x70129, 0x7012b, 0x7012d, 0x7012f, 0x70131, 0x70133, + 0x70135, 0x70137, 0x70138, 0x7013a, 0x7013c, 0x7013e, 0x70140, 0x70142, 0x70144, + 0x70146, 0x70148, 0x70149, 0x7014b, 0x7014d, 0x7014f, 0x70151, 0x70153, 0x70155, + 0x70157, 0x70159, 0x7015b, 0x7015d, 0x7015f, 0x70161, 0x70163, 0x70165, 0x70167, + 0x70169, 0x7016b, 0x7016d, 0x7016f, 0x70171, 0x70173, 0x70175, 0x70177, 0x7017a, + 0x7017c, 0x70183, 0x70185, 0x70188, 0x7018c, 0x7018d, 0x70192, 0x70195, 0x7019e, + 0x701a1, 0x701a3, 0x701a5, 0x701a8, 0x701aa, 0x701ab, 0x701ad, 0x701b0, 0x701b4, + 0x701b6, 0x701b9, 0x701ba, 0x701c6, 0x701c9, 0x701cc, 0x701ce, 0x701d0, 0x701d2, + 0x701d4, 0x701d6, 0x701d8, 0x701da, 0x701dc, 0x701dd, 0x701df, 0x701e1, 0x701e3, + 0x701e5, 0x701e7, 0x701e9, 0x701eb, 0x701ed, 0x701ef, 0x701f0, 0x701f3, 0x701f5, + 0x701f9, 0x701fb, 0x701fd, 0x701ff, 0x70201, 0x70203, 0x70205, 0x70207, 0x70209, + 0x7020b, 0x7020d, 0x7020f, 0x70211, 0x70213, 0x70215, 0x70217, 0x70219, 0x7021b, + 0x7021d, 0x7021f, 0x70221, 0x70223, 0x70225, 0x70227, 0x70229, 0x7022b, 0x7022d, + 0x7022f, 0x70231, 0x7023c, 0x7023f, 0x70240, 0x70242, 0x70247, 0x70249, 0x7024b, + 0x7024d, 0x70371, 0x70373, 0x70377, 0x70390, 0x703d0, 0x703d1, 0x703d9, 0x703db, + 0x703dd, 0x703df, 0x703e1, 0x703e3, 0x703e5, 0x703e7, 0x703e9, 0x703eb, 0x703ed, + 0x703f5, 0x703f8, 0x703fb, 0x703fc, 0x70461, 0x70463, 0x70465, 0x70467, 0x70469, + 0x7046b, 0x7046d, 0x7046f, 0x70471, 0x70473, 0x70475, 0x70477, 0x70479, 0x7047b, + 0x7047d, 0x7047f, 0x70481, 0x7048b, 0x7048d, 0x7048f, 0x70491, 0x70493, 0x70495, + 0x70497, 0x70499, 0x7049b, 0x7049d, 0x7049f, 0x704a1, 0x704a3, 0x704a5, 0x704a7, + 0x704a9, 0x704ab, 0x704ad, 0x704af, 0x704b1, 0x704b3, 0x704b5, 0x704b7, 0x704b9, + 0x704bb, 0x704bd, 0x704bf, 0x704c2, 0x704c4, 0x704c6, 0x704c8, 0x704ca, 0x704cc, + 0x704ce, 0x704cf, 0x704d1, 0x704d3, 0x704d5, 0x704d7, 0x704d9, 0x704db, 0x704dd, + 0x704df, 0x704e1, 0x704e3, 0x704e5, 0x704e7, 0x704e9, 0x704eb, 0x704ed, 0x704ef, + 0x704f1, 0x704f3, 0x704f5, 0x704f7, 0x704f9, 0x704fb, 0x704fd, 0x704ff, 0x70501, + 0x70503, 0x70505, 0x70507, 0x70509, 0x7050b, 0x7050d, 0x7050f, 0x70511, 0x70513, + 0x70515, 0x70517, 0x70519, 0x7051b, 0x7051d, 0x7051f, 0x70521, 0x70523, 0x70525, + 0x70527, 0x70529, 0x7052b, 0x7052d, 0x7052f, 0x71e01, 0x71e03, 0x71e05, 0x71e07, + 0x71e09, 0x71e0b, 0x71e0d, 0x71e0f, 0x71e11, 0x71e13, 0x71e15, 0x71e17, 0x71e19, + 0x71e1b, 0x71e1d, 0x71e1f, 0x71e21, 0x71e23, 0x71e25, 0x71e27, 0x71e29, 0x71e2b, + 0x71e2d, 0x71e2f, 0x71e31, 0x71e33, 0x71e35, 0x71e37, 0x71e39, 0x71e3b, 0x71e3d, + 0x71e3f, 0x71e41, 0x71e43, 0x71e45, 0x71e47, 0x71e49, 0x71e4b, 0x71e4d, 0x71e4f, + 0x71e51, 0x71e53, 0x71e55, 0x71e57, 0x71e59, 0x71e5b, 0x71e5d, 0x71e5f, 0x71e61, + 0x71e63, 0x71e65, 0x71e67, 0x71e69, 0x71e6b, 0x71e6d, 0x71e6f, 0x71e71, 0x71e73, + 0x71e75, 0x71e77, 0x71e79, 0x71e7b, 0x71e7d, 0x71e7f, 0x71e81, 0x71e83, 0x71e85, + 0x71e87, 0x71e89, 0x71e8b, 0x71e8d, 0x71e8f, 0x71e91, 0x71e93, 0x71e9f, 0x71ea1, + 0x71ea3, 0x71ea5, 0x71ea7, 0x71ea9, 0x71eab, 0x71ead, 0x71eaf, 0x71eb1, 0x71eb3, + 0x71eb5, 0x71eb7, 0x71eb9, 0x71ebb, 0x71ebd, 0x71ebf, 0x71ec1, 0x71ec3, 0x71ec5, + 0x71ec7, 0x71ec9, 0x71ecb, 0x71ecd, 0x71ecf, 0x71ed1, 0x71ed3, 0x71ed5, 0x71ed7, + 0x71ed9, 0x71edb, 0x71edd, 0x71edf, 0x71ee1, 0x71ee3, 0x71ee5, 0x71ee7, 0x71ee9, + 0x71eeb, 0x71eed, 0x71eef, 0x71ef1, 0x71ef3, 0x71ef5, 0x71ef7, 0x71ef9, 0x71efb, + 0x71efd, 0x71fb6, 0x71fb7, 0x71fbe, 0x71fc6, 0x71fc7, 0x71fd6, 0x71fd7, 0x71ff6, + 0x71ff7, 0x7210a, 0x7210e, 0x7210f, 0x72113, 0x7212f, 0x72134, 0x72139, 0x7213c, + 0x7213d, 0x7214e, 0x72184, 0x72c61, 0x72c65, 0x72c66, 0x72c68, 0x72c6a, 0x72c6c, + 0x72c71, 0x72c73, 0x72c74, 0x72c81, 0x72c83, 0x72c85, 0x72c87, 0x72c89, 0x72c8b, + 0x72c8d, 0x72c8f, 0x72c91, 0x72c93, 0x72c95, 0x72c97, 0x72c99, 0x72c9b, 0x72c9d, + 0x72c9f, 0x72ca1, 0x72ca3, 0x72ca5, 0x72ca7, 0x72ca9, 0x72cab, 0x72cad, 0x72caf, + 0x72cb1, 0x72cb3, 0x72cb5, 0x72cb7, 0x72cb9, 0x72cbb, 0x72cbd, 0x72cbf, 0x72cc1, + 0x72cc3, 0x72cc5, 0x72cc7, 0x72cc9, 0x72ccb, 0x72ccd, 0x72ccf, 0x72cd1, 0x72cd3, + 0x72cd5, 0x72cd7, 0x72cd9, 0x72cdb, 0x72cdd, 0x72cdf, 0x72ce1, 0x72ce3, 0x72ce4, + 0x72cec, 0x72cee, 0x72cf3, 0x72d27, 0x72d2d, 0x7a641, 0x7a643, 0x7a645, 0x7a647, + 0x7a649, 0x7a64b, 0x7a64d, 0x7a64f, 0x7a651, 0x7a653, 0x7a655, 0x7a657, 0x7a659, + 0x7a65b, 0x7a65d, 0x7a65f, 0x7a661, 0x7a663, 0x7a665, 0x7a667, 0x7a669, 0x7a66b, + 0x7a66d, 0x7a681, 0x7a683, 0x7a685, 0x7a687, 0x7a689, 0x7a68b, 0x7a68d, 0x7a68f, + 0x7a691, 0x7a693, 0x7a695, 0x7a697, 0x7a699, 0x7a69b, 0x7a723, 0x7a725, 0x7a727, + 0x7a729, 0x7a72b, 0x7a72d, 0x7a733, 0x7a735, 0x7a737, 0x7a739, 0x7a73b, 0x7a73d, + 0x7a73f, 0x7a741, 0x7a743, 0x7a745, 0x7a747, 0x7a749, 0x7a74b, 0x7a74d, 0x7a74f, + 0x7a751, 0x7a753, 0x7a755, 0x7a757, 0x7a759, 0x7a75b, 0x7a75d, 0x7a75f, 0x7a761, + 0x7a763, 0x7a765, 0x7a767, 0x7a769, 0x7a76b, 0x7a76d, 0x7a76f, 0x7a77a, 0x7a77c, + 0x7a77f, 0x7a781, 0x7a783, 0x7a785, 0x7a787, 0x7a78c, 0x7a78e, 0x7a791, 0x7a797, + 0x7a799, 0x7a79b, 0x7a79d, 0x7a79f, 0x7a7a1, 0x7a7a3, 0x7a7a5, 0x7a7a7, 0x7a7a9, + 0x7a7b5, 0x7a7b7, 0x7a7fa, 0x800b5, 0x80101, 0x80103, 0x80105, 0x80107, 0x80109, + 0x8010b, 0x8010d, 0x8010f, 0x80111, 0x80113, 0x80115, 0x80117, 0x80119, 0x8011b, + 0x8011d, 0x8011f, 0x80121, 0x80123, 0x80125, 0x80127, 0x80129, 0x8012b, 0x8012d, + 0x8012f, 0x80131, 0x80133, 0x80135, 0x80137, 0x80138, 0x8013a, 0x8013c, 0x8013e, + 0x80140, 0x80142, 0x80144, 0x80146, 0x80148, 0x80149, 0x8014b, 0x8014d, 0x8014f, + 0x80151, 0x80153, 0x80155, 0x80157, 0x80159, 0x8015b, 0x8015d, 0x8015f, 0x80161, + 0x80163, 0x80165, 0x80167, 0x80169, 0x8016b, 0x8016d, 0x8016f, 0x80171, 0x80173, + 0x80175, 0x80177, 0x8017a, 0x8017c, 0x80183, 0x80185, 0x80188, 0x8018c, 0x8018d, + 0x80192, 0x80195, 0x8019e, 0x801a1, 0x801a3, 0x801a5, 0x801a8, 0x801aa, 0x801ab, + 0x801ad, 0x801b0, 0x801b4, 0x801b6, 0x801b9, 0x801ba, 0x801c6, 0x801c9, 0x801cc, + 0x801ce, 0x801d0, 0x801d2, 0x801d4, 0x801d6, 0x801d8, 0x801da, 0x801dc, 0x801dd, + 0x801df, 0x801e1, 0x801e3, 0x801e5, 0x801e7, 0x801e9, 0x801eb, 0x801ed, 0x801ef, + 0x801f0, 0x801f3, 0x801f5, 0x801f9, 0x801fb, 0x801fd, 0x801ff, 0x80201, 0x80203, + 0x80205, 0x80207, 0x80209, 0x8020b, 0x8020d, 0x8020f, 0x80211, 0x80213, 0x80215, + 0x80217, 0x80219, 0x8021b, 0x8021d, 0x8021f, 0x80221, 0x80223, 0x80225, 0x80227, + 0x80229, 0x8022b, 0x8022d, 0x8022f, 0x80231, 0x8023c, 0x8023f, 0x80240, 0x80242, + 0x80247, 0x80249, 0x8024b, 0x8024d, 0x80371, 0x80373, 0x80377, 0x80390, 0x803d0, + 0x803d1, 0x803d9, 0x803db, 0x803dd, 0x803df, 0x803e1, 0x803e3, 0x803e5, 0x803e7, + 0x803e9, 0x803eb, 0x803ed, 0x803f5, 0x803f8, 0x803fb, 0x803fc, 0x80461, 0x80463, + 0x80465, 0x80467, 0x80469, 0x8046b, 0x8046d, 0x8046f, 0x80471, 0x80473, 0x80475, + 0x80477, 0x80479, 0x8047b, 0x8047d, 0x8047f, 0x80481, 0x8048b, 0x8048d, 0x8048f, + 0x80491, 0x80493, 0x80495, 0x80497, 0x80499, 0x8049b, 0x8049d, 0x8049f, 0x804a1, + 0x804a3, 0x804a5, 0x804a7, 0x804a9, 0x804ab, 0x804ad, 0x804af, 0x804b1, 0x804b3, + 0x804b5, 0x804b7, 0x804b9, 0x804bb, 0x804bd, 0x804bf, 0x804c2, 0x804c4, 0x804c6, + 0x804c8, 0x804ca, 0x804cc, 0x804ce, 0x804cf, 0x804d1, 0x804d3, 0x804d5, 0x804d7, + 0x804d9, 0x804db, 0x804dd, 0x804df, 0x804e1, 0x804e3, 0x804e5, 0x804e7, 0x804e9, + 0x804eb, 0x804ed, 0x804ef, 0x804f1, 0x804f3, 0x804f5, 0x804f7, 0x804f9, 0x804fb, + 0x804fd, 0x804ff, 0x80501, 0x80503, 0x80505, 0x80507, 0x80509, 0x8050b, 0x8050d, + 0x8050f, 0x80511, 0x80513, 0x80515, 0x80517, 0x80519, 0x8051b, 0x8051d, 0x8051f, + 0x80521, 0x80523, 0x80525, 0x80527, 0x80529, 0x8052b, 0x8052d, 0x8052f, 0x81e01, + 0x81e03, 0x81e05, 0x81e07, 0x81e09, 0x81e0b, 0x81e0d, 0x81e0f, 0x81e11, 0x81e13, + 0x81e15, 0x81e17, 0x81e19, 0x81e1b, 0x81e1d, 0x81e1f, 0x81e21, 0x81e23, 0x81e25, + 0x81e27, 0x81e29, 0x81e2b, 0x81e2d, 0x81e2f, 0x81e31, 0x81e33, 0x81e35, 0x81e37, + 0x81e39, 0x81e3b, 0x81e3d, 0x81e3f, 0x81e41, 0x81e43, 0x81e45, 0x81e47, 0x81e49, + 0x81e4b, 0x81e4d, 0x81e4f, 0x81e51, 0x81e53, 0x81e55, 0x81e57, 0x81e59, 0x81e5b, + 0x81e5d, 0x81e5f, 0x81e61, 0x81e63, 0x81e65, 0x81e67, 0x81e69, 0x81e6b, 0x81e6d, + 0x81e6f, 0x81e71, 0x81e73, 0x81e75, 0x81e77, 0x81e79, 0x81e7b, 0x81e7d, 0x81e7f, + 0x81e81, 0x81e83, 0x81e85, 0x81e87, 0x81e89, 0x81e8b, 0x81e8d, 0x81e8f, 0x81e91, + 0x81e93, 0x81e9f, 0x81ea1, 0x81ea3, 0x81ea5, 0x81ea7, 0x81ea9, 0x81eab, 0x81ead, + 0x81eaf, 0x81eb1, 0x81eb3, 0x81eb5, 0x81eb7, 0x81eb9, 0x81ebb, 0x81ebd, 0x81ebf, + 0x81ec1, 0x81ec3, 0x81ec5, 0x81ec7, 0x81ec9, 0x81ecb, 0x81ecd, 0x81ecf, 0x81ed1, + 0x81ed3, 0x81ed5, 0x81ed7, 0x81ed9, 0x81edb, 0x81edd, 0x81edf, 0x81ee1, 0x81ee3, + 0x81ee5, 0x81ee7, 0x81ee9, 0x81eeb, 0x81eed, 0x81eef, 0x81ef1, 0x81ef3, 0x81ef5, + 0x81ef7, 0x81ef9, 0x81efb, 0x81efd, 0x81fb6, 0x81fb7, 0x81fbe, 0x81fc6, 0x81fc7, + 0x81fd6, 0x81fd7, 0x81ff6, 0x81ff7, 0x8210a, 0x8210e, 0x8210f, 0x82113, 0x8212f, + 0x82134, 0x82139, 0x8213c, 0x8213d, 0x8214e, 0x82184, 0x82c61, 0x82c65, 0x82c66, + 0x82c68, 0x82c6a, 0x82c6c, 0x82c71, 0x82c73, 0x82c74, 0x82c81, 0x82c83, 0x82c85, + 0x82c87, 0x82c89, 0x82c8b, 0x82c8d, 0x82c8f, 0x82c91, 0x82c93, 0x82c95, 0x82c97, + 0x82c99, 0x82c9b, 0x82c9d, 0x82c9f, 0x82ca1, 0x82ca3, 0x82ca5, 0x82ca7, 0x82ca9, + 0x82cab, 0x82cad, 0x82caf, 0x82cb1, 0x82cb3, 0x82cb5, 0x82cb7, 0x82cb9, 0x82cbb, + 0x82cbd, 0x82cbf, 0x82cc1, 0x82cc3, 0x82cc5, 0x82cc7, 0x82cc9, 0x82ccb, 0x82ccd, + 0x82ccf, 0x82cd1, 0x82cd3, 0x82cd5, 0x82cd7, 0x82cd9, 0x82cdb, 0x82cdd, 0x82cdf, + 0x82ce1, 0x82ce3, 0x82ce4, 0x82cec, 0x82cee, 0x82cf3, 0x82d27, 0x82d2d, 0x8a641, + 0x8a643, 0x8a645, 0x8a647, 0x8a649, 0x8a64b, 0x8a64d, 0x8a64f, 0x8a651, 0x8a653, + 0x8a655, 0x8a657, 0x8a659, 0x8a65b, 0x8a65d, 0x8a65f, 0x8a661, 0x8a663, 0x8a665, + 0x8a667, 0x8a669, 0x8a66b, 0x8a66d, 0x8a681, 0x8a683, 0x8a685, 0x8a687, 0x8a689, + 0x8a68b, 0x8a68d, 0x8a68f, 0x8a691, 0x8a693, 0x8a695, 0x8a697, 0x8a699, 0x8a69b, + 0x8a723, 0x8a725, 0x8a727, 0x8a729, 0x8a72b, 0x8a72d, 0x8a733, 0x8a735, 0x8a737, + 0x8a739, 0x8a73b, 0x8a73d, 0x8a73f, 0x8a741, 0x8a743, 0x8a745, 0x8a747, 0x8a749, + 0x8a74b, 0x8a74d, 0x8a74f, 0x8a751, 0x8a753, 0x8a755, 0x8a757, 0x8a759, 0x8a75b, + 0x8a75d, 0x8a75f, 0x8a761, 0x8a763, 0x8a765, 0x8a767, 0x8a769, 0x8a76b, 0x8a76d, + 0x8a76f, 0x8a77a, 0x8a77c, 0x8a77f, 0x8a781, 0x8a783, 0x8a785, 0x8a787, 0x8a78c, + 0x8a78e, 0x8a791, 0x8a797, 0x8a799, 0x8a79b, 0x8a79d, 0x8a79f, 0x8a7a1, 0x8a7a3, + 0x8a7a5, 0x8a7a7, 0x8a7a9, 0x8a7b5, 0x8a7b7, 0x8a7fa, 0x900b5, 0x90101, 0x90103, + 0x90105, 0x90107, 0x90109, 0x9010b, 0x9010d, 0x9010f, 0x90111, 0x90113, 0x90115, + 0x90117, 0x90119, 0x9011b, 0x9011d, 0x9011f, 0x90121, 0x90123, 0x90125, 0x90127, + 0x90129, 0x9012b, 0x9012d, 0x9012f, 0x90131, 0x90133, 0x90135, 0x90137, 0x90138, + 0x9013a, 0x9013c, 0x9013e, 0x90140, 0x90142, 0x90144, 0x90146, 0x90148, 0x90149, + 0x9014b, 0x9014d, 0x9014f, 0x90151, 0x90153, 0x90155, 0x90157, 0x90159, 0x9015b, + 0x9015d, 0x9015f, 0x90161, 0x90163, 0x90165, 0x90167, 0x90169, 0x9016b, 0x9016d, + 0x9016f, 0x90171, 0x90173, 0x90175, 0x90177, 0x9017a, 0x9017c, 0x90183, 0x90185, + 0x90188, 0x9018c, 0x9018d, 0x90192, 0x90195, 0x9019e, 0x901a1, 0x901a3, 0x901a5, + 0x901a8, 0x901aa, 0x901ab, 0x901ad, 0x901b0, 0x901b4, 0x901b6, 0x901b9, 0x901ba, + 0x901c6, 0x901c9, 0x901cc, 0x901ce, 0x901d0, 0x901d2, 0x901d4, 0x901d6, 0x901d8, + 0x901da, 0x901dc, 0x901dd, 0x901df, 0x901e1, 0x901e3, 0x901e5, 0x901e7, 0x901e9, + 0x901eb, 0x901ed, 0x901ef, 0x901f0, 0x901f3, 0x901f5, 0x901f9, 0x901fb, 0x901fd, + 0x901ff, 0x90201, 0x90203, 0x90205, 0x90207, 0x90209, 0x9020b, 0x9020d, 0x9020f, + 0x90211, 0x90213, 0x90215, 0x90217, 0x90219, 0x9021b, 0x9021d, 0x9021f, 0x90221, + 0x90223, 0x90225, 0x90227, 0x90229, 0x9022b, 0x9022d, 0x9022f, 0x90231, 0x9023c, + 0x9023f, 0x90240, 0x90242, 0x90247, 0x90249, 0x9024b, 0x9024d, 0x90371, 0x90373, + 0x90377, 0x90390, 0x903d0, 0x903d1, 0x903d9, 0x903db, 0x903dd, 0x903df, 0x903e1, + 0x903e3, 0x903e5, 0x903e7, 0x903e9, 0x903eb, 0x903ed, 0x903f5, 0x903f8, 0x903fb, + 0x903fc, 0x90461, 0x90463, 0x90465, 0x90467, 0x90469, 0x9046b, 0x9046d, 0x9046f, + 0x90471, 0x90473, 0x90475, 0x90477, 0x90479, 0x9047b, 0x9047d, 0x9047f, 0x90481, + 0x9048b, 0x9048d, 0x9048f, 0x90491, 0x90493, 0x90495, 0x90497, 0x90499, 0x9049b, + 0x9049d, 0x9049f, 0x904a1, 0x904a3, 0x904a5, 0x904a7, 0x904a9, 0x904ab, 0x904ad, + 0x904af, 0x904b1, 0x904b3, 0x904b5, 0x904b7, 0x904b9, 0x904bb, 0x904bd, 0x904bf, + 0x904c2, 0x904c4, 0x904c6, 0x904c8, 0x904ca, 0x904cc, 0x904ce, 0x904cf, 0x904d1, + 0x904d3, 0x904d5, 0x904d7, 0x904d9, 0x904db, 0x904dd, 0x904df, 0x904e1, 0x904e3, + 0x904e5, 0x904e7, 0x904e9, 0x904eb, 0x904ed, 0x904ef, 0x904f1, 0x904f3, 0x904f5, + 0x904f7, 0x904f9, 0x904fb, 0x904fd, 0x904ff, 0x90501, 0x90503, 0x90505, 0x90507, + 0x90509, 0x9050b, 0x9050d, 0x9050f, 0x90511, 0x90513, 0x90515, 0x90517, 0x90519, + 0x9051b, 0x9051d, 0x9051f, 0x90521, 0x90523, 0x90525, 0x90527, 0x90529, 0x9052b, + 0x9052d, 0x9052f, 0x91e01, 0x91e03, 0x91e05, 0x91e07, 0x91e09, 0x91e0b, 0x91e0d, + 0x91e0f, 0x91e11, 0x91e13, 0x91e15, 0x91e17, 0x91e19, 0x91e1b, 0x91e1d, 0x91e1f, + 0x91e21, 0x91e23, 0x91e25, 0x91e27, 0x91e29, 0x91e2b, 0x91e2d, 0x91e2f, 0x91e31, + 0x91e33, 0x91e35, 0x91e37, 0x91e39, 0x91e3b, 0x91e3d, 0x91e3f, 0x91e41, 0x91e43, + 0x91e45, 0x91e47, 0x91e49, 0x91e4b, 0x91e4d, 0x91e4f, 0x91e51, 0x91e53, 0x91e55, + 0x91e57, 0x91e59, 0x91e5b, 0x91e5d, 0x91e5f, 0x91e61, 0x91e63, 0x91e65, 0x91e67, + 0x91e69, 0x91e6b, 0x91e6d, 0x91e6f, 0x91e71, 0x91e73, 0x91e75, 0x91e77, 0x91e79, + 0x91e7b, 0x91e7d, 0x91e7f, 0x91e81, 0x91e83, 0x91e85, 0x91e87, 0x91e89, 0x91e8b, + 0x91e8d, 0x91e8f, 0x91e91, 0x91e93, 0x91e9f, 0x91ea1, 0x91ea3, 0x91ea5, 0x91ea7, + 0x91ea9, 0x91eab, 0x91ead, 0x91eaf, 0x91eb1, 0x91eb3, 0x91eb5, 0x91eb7, 0x91eb9, + 0x91ebb, 0x91ebd, 0x91ebf, 0x91ec1, 0x91ec3, 0x91ec5, 0x91ec7, 0x91ec9, 0x91ecb, + 0x91ecd, 0x91ecf, 0x91ed1, 0x91ed3, 0x91ed5, 0x91ed7, 0x91ed9, 0x91edb, 0x91edd, + 0x91edf, 0x91ee1, 0x91ee3, 0x91ee5, 0x91ee7, 0x91ee9, 0x91eeb, 0x91eed, 0x91eef, + 0x91ef1, 0x91ef3, 0x91ef5, 0x91ef7, 0x91ef9, 0x91efb, 0x91efd, 0x91fb6, 0x91fb7, + 0x91fbe, 0x91fc6, 0x91fc7, 0x91fd6, 0x91fd7, 0x91ff6, 0x91ff7, 0x9210a, 0x9210e, + 0x9210f, 0x92113, 0x9212f, 0x92134, 0x92139, 0x9213c, 0x9213d, 0x9214e, 0x92184, + 0x92c61, 0x92c65, 0x92c66, 0x92c68, 0x92c6a, 0x92c6c, 0x92c71, 0x92c73, 0x92c74, + 0x92c81, 0x92c83, 0x92c85, 0x92c87, 0x92c89, 0x92c8b, 0x92c8d, 0x92c8f, 0x92c91, + 0x92c93, 0x92c95, 0x92c97, 0x92c99, 0x92c9b, 0x92c9d, 0x92c9f, 0x92ca1, 0x92ca3, + 0x92ca5, 0x92ca7, 0x92ca9, 0x92cab, 0x92cad, 0x92caf, 0x92cb1, 0x92cb3, 0x92cb5, + 0x92cb7, 0x92cb9, 0x92cbb, 0x92cbd, 0x92cbf, 0x92cc1, 0x92cc3, 0x92cc5, 0x92cc7, + 0x92cc9, 0x92ccb, 0x92ccd, 0x92ccf, 0x92cd1, 0x92cd3, 0x92cd5, 0x92cd7, 0x92cd9, + 0x92cdb, 0x92cdd, 0x92cdf, 0x92ce1, 0x92ce3, 0x92ce4, 0x92cec, 0x92cee, 0x92cf3, + 0x92d27, 0x92d2d, 0x9a641, 0x9a643, 0x9a645, 0x9a647, 0x9a649, 0x9a64b, 0x9a64d, + 0x9a64f, 0x9a651, 0x9a653, 0x9a655, 0x9a657, 0x9a659, 0x9a65b, 0x9a65d, 0x9a65f, + 0x9a661, 0x9a663, 0x9a665, 0x9a667, 0x9a669, 0x9a66b, 0x9a66d, 0x9a681, 0x9a683, + 0x9a685, 0x9a687, 0x9a689, 0x9a68b, 0x9a68d, 0x9a68f, 0x9a691, 0x9a693, 0x9a695, + 0x9a697, 0x9a699, 0x9a69b, 0x9a723, 0x9a725, 0x9a727, 0x9a729, 0x9a72b, 0x9a72d, + 0x9a733, 0x9a735, 0x9a737, 0x9a739, 0x9a73b, 0x9a73d, 0x9a73f, 0x9a741, 0x9a743, + 0x9a745, 0x9a747, 0x9a749, 0x9a74b, 0x9a74d, 0x9a74f, 0x9a751, 0x9a753, 0x9a755, + 0x9a757, 0x9a759, 0x9a75b, 0x9a75d, 0x9a75f, 0x9a761, 0x9a763, 0x9a765, 0x9a767, + 0x9a769, 0x9a76b, 0x9a76d, 0x9a76f, 0x9a77a, 0x9a77c, 0x9a77f, 0x9a781, 0x9a783, + 0x9a785, 0x9a787, 0x9a78c, 0x9a78e, 0x9a791, 0x9a797, 0x9a799, 0x9a79b, 0x9a79d, + 0x9a79f, 0x9a7a1, 0x9a7a3, 0x9a7a5, 0x9a7a7, 0x9a7a9, 0x9a7b5, 0x9a7b7, 0x9a7fa, + 0xa00b5, 0xa0101, 0xa0103, 0xa0105, 0xa0107, 0xa0109, 0xa010b, 0xa010d, 0xa010f, + 0xa0111, 0xa0113, 0xa0115, 0xa0117, 0xa0119, 0xa011b, 0xa011d, 0xa011f, 0xa0121, + 0xa0123, 0xa0125, 0xa0127, 0xa0129, 0xa012b, 0xa012d, 0xa012f, 0xa0131, 0xa0133, + 0xa0135, 0xa0137, 0xa0138, 0xa013a, 0xa013c, 0xa013e, 0xa0140, 0xa0142, 0xa0144, + 0xa0146, 0xa0148, 0xa0149, 0xa014b, 0xa014d, 0xa014f, 0xa0151, 0xa0153, 0xa0155, + 0xa0157, 0xa0159, 0xa015b, 0xa015d, 0xa015f, 0xa0161, 0xa0163, 0xa0165, 0xa0167, + 0xa0169, 0xa016b, 0xa016d, 0xa016f, 0xa0171, 0xa0173, 0xa0175, 0xa0177, 0xa017a, + 0xa017c, 0xa0183, 0xa0185, 0xa0188, 0xa018c, 0xa018d, 0xa0192, 0xa0195, 0xa019e, + 0xa01a1, 0xa01a3, 0xa01a5, 0xa01a8, 0xa01aa, 0xa01ab, 0xa01ad, 0xa01b0, 0xa01b4, + 0xa01b6, 0xa01b9, 0xa01ba, 0xa01c6, 0xa01c9, 0xa01cc, 0xa01ce, 0xa01d0, 0xa01d2, + 0xa01d4, 0xa01d6, 0xa01d8, 0xa01da, 0xa01dc, 0xa01dd, 0xa01df, 0xa01e1, 0xa01e3, + 0xa01e5, 0xa01e7, 0xa01e9, 0xa01eb, 0xa01ed, 0xa01ef, 0xa01f0, 0xa01f3, 0xa01f5, + 0xa01f9, 0xa01fb, 0xa01fd, 0xa01ff, 0xa0201, 0xa0203, 0xa0205, 0xa0207, 0xa0209, + 0xa020b, 0xa020d, 0xa020f, 0xa0211, 0xa0213, 0xa0215, 0xa0217, 0xa0219, 0xa021b, + 0xa021d, 0xa021f, 0xa0221, 0xa0223, 0xa0225, 0xa0227, 0xa0229, 0xa022b, 0xa022d, + 0xa022f, 0xa0231, 0xa023c, 0xa023f, 0xa0240, 0xa0242, 0xa0247, 0xa0249, 0xa024b, + 0xa024d, 0xa0371, 0xa0373, 0xa0377, 0xa0390, 0xa03d0, 0xa03d1, 0xa03d9, 0xa03db, + 0xa03dd, 0xa03df, 0xa03e1, 0xa03e3, 0xa03e5, 0xa03e7, 0xa03e9, 0xa03eb, 0xa03ed, + 0xa03f5, 0xa03f8, 0xa03fb, 0xa03fc, 0xa0461, 0xa0463, 0xa0465, 0xa0467, 0xa0469, + 0xa046b, 0xa046d, 0xa046f, 0xa0471, 0xa0473, 0xa0475, 0xa0477, 0xa0479, 0xa047b, + 0xa047d, 0xa047f, 0xa0481, 0xa048b, 0xa048d, 0xa048f, 0xa0491, 0xa0493, 0xa0495, + 0xa0497, 0xa0499, 0xa049b, 0xa049d, 0xa049f, 0xa04a1, 0xa04a3, 0xa04a5, 0xa04a7, + 0xa04a9, 0xa04ab, 0xa04ad, 0xa04af, 0xa04b1, 0xa04b3, 0xa04b5, 0xa04b7, 0xa04b9, + 0xa04bb, 0xa04bd, 0xa04bf, 0xa04c2, 0xa04c4, 0xa04c6, 0xa04c8, 0xa04ca, 0xa04cc, + 0xa04ce, 0xa04cf, 0xa04d1, 0xa04d3, 0xa04d5, 0xa04d7, 0xa04d9, 0xa04db, 0xa04dd, + 0xa04df, 0xa04e1, 0xa04e3, 0xa04e5, 0xa04e7, 0xa04e9, 0xa04eb, 0xa04ed, 0xa04ef, + 0xa04f1, 0xa04f3, 0xa04f5, 0xa04f7, 0xa04f9, 0xa04fb, 0xa04fd, 0xa04ff, 0xa0501, + 0xa0503, 0xa0505, 0xa0507, 0xa0509, 0xa050b, 0xa050d, 0xa050f, 0xa0511, 0xa0513, + 0xa0515, 0xa0517, 0xa0519, 0xa051b, 0xa051d, 0xa051f, 0xa0521, 0xa0523, 0xa0525, + 0xa0527, 0xa0529, 0xa052b, 0xa052d, 0xa052f, 0xa1e01, 0xa1e03, 0xa1e05, 0xa1e07, + 0xa1e09, 0xa1e0b, 0xa1e0d, 0xa1e0f, 0xa1e11, 0xa1e13, 0xa1e15, 0xa1e17, 0xa1e19, + 0xa1e1b, 0xa1e1d, 0xa1e1f, 0xa1e21, 0xa1e23, 0xa1e25, 0xa1e27, 0xa1e29, 0xa1e2b, + 0xa1e2d, 0xa1e2f, 0xa1e31, 0xa1e33, 0xa1e35, 0xa1e37, 0xa1e39, 0xa1e3b, 0xa1e3d, + 0xa1e3f, 0xa1e41, 0xa1e43, 0xa1e45, 0xa1e47, 0xa1e49, 0xa1e4b, 0xa1e4d, 0xa1e4f, + 0xa1e51, 0xa1e53, 0xa1e55, 0xa1e57, 0xa1e59, 0xa1e5b, 0xa1e5d, 0xa1e5f, 0xa1e61, + 0xa1e63, 0xa1e65, 0xa1e67, 0xa1e69, 0xa1e6b, 0xa1e6d, 0xa1e6f, 0xa1e71, 0xa1e73, + 0xa1e75, 0xa1e77, 0xa1e79, 0xa1e7b, 0xa1e7d, 0xa1e7f, 0xa1e81, 0xa1e83, 0xa1e85, + 0xa1e87, 0xa1e89, 0xa1e8b, 0xa1e8d, 0xa1e8f, 0xa1e91, 0xa1e93, 0xa1e9f, 0xa1ea1, + 0xa1ea3, 0xa1ea5, 0xa1ea7, 0xa1ea9, 0xa1eab, 0xa1ead, 0xa1eaf, 0xa1eb1, 0xa1eb3, + 0xa1eb5, 0xa1eb7, 0xa1eb9, 0xa1ebb, 0xa1ebd, 0xa1ebf, 0xa1ec1, 0xa1ec3, 0xa1ec5, + 0xa1ec7, 0xa1ec9, 0xa1ecb, 0xa1ecd, 0xa1ecf, 0xa1ed1, 0xa1ed3, 0xa1ed5, 0xa1ed7, + 0xa1ed9, 0xa1edb, 0xa1edd, 0xa1edf, 0xa1ee1, 0xa1ee3, 0xa1ee5, 0xa1ee7, 0xa1ee9, + 0xa1eeb, 0xa1eed, 0xa1eef, 0xa1ef1, 0xa1ef3, 0xa1ef5, 0xa1ef7, 0xa1ef9, 0xa1efb, + 0xa1efd, 0xa1fb6, 0xa1fb7, 0xa1fbe, 0xa1fc6, 0xa1fc7, 0xa1fd6, 0xa1fd7, 0xa1ff6, + 0xa1ff7, 0xa210a, 0xa210e, 0xa210f, 0xa2113, 0xa212f, 0xa2134, 0xa2139, 0xa213c, + 0xa213d, 0xa214e, 0xa2184, 0xa2c61, 0xa2c65, 0xa2c66, 0xa2c68, 0xa2c6a, 0xa2c6c, + 0xa2c71, 0xa2c73, 0xa2c74, 0xa2c81, 0xa2c83, 0xa2c85, 0xa2c87, 0xa2c89, 0xa2c8b, + 0xa2c8d, 0xa2c8f, 0xa2c91, 0xa2c93, 0xa2c95, 0xa2c97, 0xa2c99, 0xa2c9b, 0xa2c9d, + 0xa2c9f, 0xa2ca1, 0xa2ca3, 0xa2ca5, 0xa2ca7, 0xa2ca9, 0xa2cab, 0xa2cad, 0xa2caf, + 0xa2cb1, 0xa2cb3, 0xa2cb5, 0xa2cb7, 0xa2cb9, 0xa2cbb, 0xa2cbd, 0xa2cbf, 0xa2cc1, + 0xa2cc3, 0xa2cc5, 0xa2cc7, 0xa2cc9, 0xa2ccb, 0xa2ccd, 0xa2ccf, 0xa2cd1, 0xa2cd3, + 0xa2cd5, 0xa2cd7, 0xa2cd9, 0xa2cdb, 0xa2cdd, 0xa2cdf, 0xa2ce1, 0xa2ce3, 0xa2ce4, + 0xa2cec, 0xa2cee, 0xa2cf3, 0xa2d27, 0xa2d2d, 0xaa641, 0xaa643, 0xaa645, 0xaa647, + 0xaa649, 0xaa64b, 0xaa64d, 0xaa64f, 0xaa651, 0xaa653, 0xaa655, 0xaa657, 0xaa659, + 0xaa65b, 0xaa65d, 0xaa65f, 0xaa661, 0xaa663, 0xaa665, 0xaa667, 0xaa669, 0xaa66b, + 0xaa66d, 0xaa681, 0xaa683, 0xaa685, 0xaa687, 0xaa689, 0xaa68b, 0xaa68d, 0xaa68f, + 0xaa691, 0xaa693, 0xaa695, 0xaa697, 0xaa699, 0xaa69b, 0xaa723, 0xaa725, 0xaa727, + 0xaa729, 0xaa72b, 0xaa72d, 0xaa733, 0xaa735, 0xaa737, 0xaa739, 0xaa73b, 0xaa73d, + 0xaa73f, 0xaa741, 0xaa743, 0xaa745, 0xaa747, 0xaa749, 0xaa74b, 0xaa74d, 0xaa74f, + 0xaa751, 0xaa753, 0xaa755, 0xaa757, 0xaa759, 0xaa75b, 0xaa75d, 0xaa75f, 0xaa761, + 0xaa763, 0xaa765, 0xaa767, 0xaa769, 0xaa76b, 0xaa76d, 0xaa76f, 0xaa77a, 0xaa77c, + 0xaa77f, 0xaa781, 0xaa783, 0xaa785, 0xaa787, 0xaa78c, 0xaa78e, 0xaa791, 0xaa797, + 0xaa799, 0xaa79b, 0xaa79d, 0xaa79f, 0xaa7a1, 0xaa7a3, 0xaa7a5, 0xaa7a7, 0xaa7a9, + 0xaa7b5, 0xaa7b7, 0xaa7fa, 0xb00b5, 0xb0101, 0xb0103, 0xb0105, 0xb0107, 0xb0109, + 0xb010b, 0xb010d, 0xb010f, 0xb0111, 0xb0113, 0xb0115, 0xb0117, 0xb0119, 0xb011b, + 0xb011d, 0xb011f, 0xb0121, 0xb0123, 0xb0125, 0xb0127, 0xb0129, 0xb012b, 0xb012d, + 0xb012f, 0xb0131, 0xb0133, 0xb0135, 0xb0137, 0xb0138, 0xb013a, 0xb013c, 0xb013e, + 0xb0140, 0xb0142, 0xb0144, 0xb0146, 0xb0148, 0xb0149, 0xb014b, 0xb014d, 0xb014f, + 0xb0151, 0xb0153, 0xb0155, 0xb0157, 0xb0159, 0xb015b, 0xb015d, 0xb015f, 0xb0161, + 0xb0163, 0xb0165, 0xb0167, 0xb0169, 0xb016b, 0xb016d, 0xb016f, 0xb0171, 0xb0173, + 0xb0175, 0xb0177, 0xb017a, 0xb017c, 0xb0183, 0xb0185, 0xb0188, 0xb018c, 0xb018d, + 0xb0192, 0xb0195, 0xb019e, 0xb01a1, 0xb01a3, 0xb01a5, 0xb01a8, 0xb01aa, 0xb01ab, + 0xb01ad, 0xb01b0, 0xb01b4, 0xb01b6, 0xb01b9, 0xb01ba, 0xb01c6, 0xb01c9, 0xb01cc, + 0xb01ce, 0xb01d0, 0xb01d2, 0xb01d4, 0xb01d6, 0xb01d8, 0xb01da, 0xb01dc, 0xb01dd, + 0xb01df, 0xb01e1, 0xb01e3, 0xb01e5, 0xb01e7, 0xb01e9, 0xb01eb, 0xb01ed, 0xb01ef, + 0xb01f0, 0xb01f3, 0xb01f5, 0xb01f9, 0xb01fb, 0xb01fd, 0xb01ff, 0xb0201, 0xb0203, + 0xb0205, 0xb0207, 0xb0209, 0xb020b, 0xb020d, 0xb020f, 0xb0211, 0xb0213, 0xb0215, + 0xb0217, 0xb0219, 0xb021b, 0xb021d, 0xb021f, 0xb0221, 0xb0223, 0xb0225, 0xb0227, + 0xb0229, 0xb022b, 0xb022d, 0xb022f, 0xb0231, 0xb023c, 0xb023f, 0xb0240, 0xb0242, + 0xb0247, 0xb0249, 0xb024b, 0xb024d, 0xb0371, 0xb0373, 0xb0377, 0xb0390, 0xb03d0, + 0xb03d1, 0xb03d9, 0xb03db, 0xb03dd, 0xb03df, 0xb03e1, 0xb03e3, 0xb03e5, 0xb03e7, + 0xb03e9, 0xb03eb, 0xb03ed, 0xb03f5, 0xb03f8, 0xb03fb, 0xb03fc, 0xb0461, 0xb0463, + 0xb0465, 0xb0467, 0xb0469, 0xb046b, 0xb046d, 0xb046f, 0xb0471, 0xb0473, 0xb0475, + 0xb0477, 0xb0479, 0xb047b, 0xb047d, 0xb047f, 0xb0481, 0xb048b, 0xb048d, 0xb048f, + 0xb0491, 0xb0493, 0xb0495, 0xb0497, 0xb0499, 0xb049b, 0xb049d, 0xb049f, 0xb04a1, + 0xb04a3, 0xb04a5, 0xb04a7, 0xb04a9, 0xb04ab, 0xb04ad, 0xb04af, 0xb04b1, 0xb04b3, + 0xb04b5, 0xb04b7, 0xb04b9, 0xb04bb, 0xb04bd, 0xb04bf, 0xb04c2, 0xb04c4, 0xb04c6, + 0xb04c8, 0xb04ca, 0xb04cc, 0xb04ce, 0xb04cf, 0xb04d1, 0xb04d3, 0xb04d5, 0xb04d7, + 0xb04d9, 0xb04db, 0xb04dd, 0xb04df, 0xb04e1, 0xb04e3, 0xb04e5, 0xb04e7, 0xb04e9, + 0xb04eb, 0xb04ed, 0xb04ef, 0xb04f1, 0xb04f3, 0xb04f5, 0xb04f7, 0xb04f9, 0xb04fb, + 0xb04fd, 0xb04ff, 0xb0501, 0xb0503, 0xb0505, 0xb0507, 0xb0509, 0xb050b, 0xb050d, + 0xb050f, 0xb0511, 0xb0513, 0xb0515, 0xb0517, 0xb0519, 0xb051b, 0xb051d, 0xb051f, + 0xb0521, 0xb0523, 0xb0525, 0xb0527, 0xb0529, 0xb052b, 0xb052d, 0xb052f, 0xb1e01, + 0xb1e03, 0xb1e05, 0xb1e07, 0xb1e09, 0xb1e0b, 0xb1e0d, 0xb1e0f, 0xb1e11, 0xb1e13, + 0xb1e15, 0xb1e17, 0xb1e19, 0xb1e1b, 0xb1e1d, 0xb1e1f, 0xb1e21, 0xb1e23, 0xb1e25, + 0xb1e27, 0xb1e29, 0xb1e2b, 0xb1e2d, 0xb1e2f, 0xb1e31, 0xb1e33, 0xb1e35, 0xb1e37, + 0xb1e39, 0xb1e3b, 0xb1e3d, 0xb1e3f, 0xb1e41, 0xb1e43, 0xb1e45, 0xb1e47, 0xb1e49, + 0xb1e4b, 0xb1e4d, 0xb1e4f, 0xb1e51, 0xb1e53, 0xb1e55, 0xb1e57, 0xb1e59, 0xb1e5b, + 0xb1e5d, 0xb1e5f, 0xb1e61, 0xb1e63, 0xb1e65, 0xb1e67, 0xb1e69, 0xb1e6b, 0xb1e6d, + 0xb1e6f, 0xb1e71, 0xb1e73, 0xb1e75, 0xb1e77, 0xb1e79, 0xb1e7b, 0xb1e7d, 0xb1e7f, + 0xb1e81, 0xb1e83, 0xb1e85, 0xb1e87, 0xb1e89, 0xb1e8b, 0xb1e8d, 0xb1e8f, 0xb1e91, + 0xb1e93, 0xb1e9f, 0xb1ea1, 0xb1ea3, 0xb1ea5, 0xb1ea7, 0xb1ea9, 0xb1eab, 0xb1ead, + 0xb1eaf, 0xb1eb1, 0xb1eb3, 0xb1eb5, 0xb1eb7, 0xb1eb9, 0xb1ebb, 0xb1ebd, 0xb1ebf, + 0xb1ec1, 0xb1ec3, 0xb1ec5, 0xb1ec7, 0xb1ec9, 0xb1ecb, 0xb1ecd, 0xb1ecf, 0xb1ed1, + 0xb1ed3, 0xb1ed5, 0xb1ed7, 0xb1ed9, 0xb1edb, 0xb1edd, 0xb1edf, 0xb1ee1, 0xb1ee3, + 0xb1ee5, 0xb1ee7, 0xb1ee9, 0xb1eeb, 0xb1eed, 0xb1eef, 0xb1ef1, 0xb1ef3, 0xb1ef5, + 0xb1ef7, 0xb1ef9, 0xb1efb, 0xb1efd, 0xb1fb6, 0xb1fb7, 0xb1fbe, 0xb1fc6, 0xb1fc7, + 0xb1fd6, 0xb1fd7, 0xb1ff6, 0xb1ff7, 0xb210a, 0xb210e, 0xb210f, 0xb2113, 0xb212f, + 0xb2134, 0xb2139, 0xb213c, 0xb213d, 0xb214e, 0xb2184, 0xb2c61, 0xb2c65, 0xb2c66, + 0xb2c68, 0xb2c6a, 0xb2c6c, 0xb2c71, 0xb2c73, 0xb2c74, 0xb2c81, 0xb2c83, 0xb2c85, + 0xb2c87, 0xb2c89, 0xb2c8b, 0xb2c8d, 0xb2c8f, 0xb2c91, 0xb2c93, 0xb2c95, 0xb2c97, + 0xb2c99, 0xb2c9b, 0xb2c9d, 0xb2c9f, 0xb2ca1, 0xb2ca3, 0xb2ca5, 0xb2ca7, 0xb2ca9, + 0xb2cab, 0xb2cad, 0xb2caf, 0xb2cb1, 0xb2cb3, 0xb2cb5, 0xb2cb7, 0xb2cb9, 0xb2cbb, + 0xb2cbd, 0xb2cbf, 0xb2cc1, 0xb2cc3, 0xb2cc5, 0xb2cc7, 0xb2cc9, 0xb2ccb, 0xb2ccd, + 0xb2ccf, 0xb2cd1, 0xb2cd3, 0xb2cd5, 0xb2cd7, 0xb2cd9, 0xb2cdb, 0xb2cdd, 0xb2cdf, + 0xb2ce1, 0xb2ce3, 0xb2ce4, 0xb2cec, 0xb2cee, 0xb2cf3, 0xb2d27, 0xb2d2d, 0xba641, + 0xba643, 0xba645, 0xba647, 0xba649, 0xba64b, 0xba64d, 0xba64f, 0xba651, 0xba653, + 0xba655, 0xba657, 0xba659, 0xba65b, 0xba65d, 0xba65f, 0xba661, 0xba663, 0xba665, + 0xba667, 0xba669, 0xba66b, 0xba66d, 0xba681, 0xba683, 0xba685, 0xba687, 0xba689, + 0xba68b, 0xba68d, 0xba68f, 0xba691, 0xba693, 0xba695, 0xba697, 0xba699, 0xba69b, + 0xba723, 0xba725, 0xba727, 0xba729, 0xba72b, 0xba72d, 0xba733, 0xba735, 0xba737, + 0xba739, 0xba73b, 0xba73d, 0xba73f, 0xba741, 0xba743, 0xba745, 0xba747, 0xba749, + 0xba74b, 0xba74d, 0xba74f, 0xba751, 0xba753, 0xba755, 0xba757, 0xba759, 0xba75b, + 0xba75d, 0xba75f, 0xba761, 0xba763, 0xba765, 0xba767, 0xba769, 0xba76b, 0xba76d, + 0xba76f, 0xba77a, 0xba77c, 0xba77f, 0xba781, 0xba783, 0xba785, 0xba787, 0xba78c, + 0xba78e, 0xba791, 0xba797, 0xba799, 0xba79b, 0xba79d, 0xba79f, 0xba7a1, 0xba7a3, + 0xba7a5, 0xba7a7, 0xba7a9, 0xba7b5, 0xba7b7, 0xba7fa, 0xc00b5, 0xc0101, 0xc0103, + 0xc0105, 0xc0107, 0xc0109, 0xc010b, 0xc010d, 0xc010f, 0xc0111, 0xc0113, 0xc0115, + 0xc0117, 0xc0119, 0xc011b, 0xc011d, 0xc011f, 0xc0121, 0xc0123, 0xc0125, 0xc0127, + 0xc0129, 0xc012b, 0xc012d, 0xc012f, 0xc0131, 0xc0133, 0xc0135, 0xc0137, 0xc0138, + 0xc013a, 0xc013c, 0xc013e, 0xc0140, 0xc0142, 0xc0144, 0xc0146, 0xc0148, 0xc0149, + 0xc014b, 0xc014d, 0xc014f, 0xc0151, 0xc0153, 0xc0155, 0xc0157, 0xc0159, 0xc015b, + 0xc015d, 0xc015f, 0xc0161, 0xc0163, 0xc0165, 0xc0167, 0xc0169, 0xc016b, 0xc016d, + 0xc016f, 0xc0171, 0xc0173, 0xc0175, 0xc0177, 0xc017a, 0xc017c, 0xc0183, 0xc0185, + 0xc0188, 0xc018c, 0xc018d, 0xc0192, 0xc0195, 0xc019e, 0xc01a1, 0xc01a3, 0xc01a5, + 0xc01a8, 0xc01aa, 0xc01ab, 0xc01ad, 0xc01b0, 0xc01b4, 0xc01b6, 0xc01b9, 0xc01ba, + 0xc01c6, 0xc01c9, 0xc01cc, 0xc01ce, 0xc01d0, 0xc01d2, 0xc01d4, 0xc01d6, 0xc01d8, + 0xc01da, 0xc01dc, 0xc01dd, 0xc01df, 0xc01e1, 0xc01e3, 0xc01e5, 0xc01e7, 0xc01e9, + 0xc01eb, 0xc01ed, 0xc01ef, 0xc01f0, 0xc01f3, 0xc01f5, 0xc01f9, 0xc01fb, 0xc01fd, + 0xc01ff, 0xc0201, 0xc0203, 0xc0205, 0xc0207, 0xc0209, 0xc020b, 0xc020d, 0xc020f, + 0xc0211, 0xc0213, 0xc0215, 0xc0217, 0xc0219, 0xc021b, 0xc021d, 0xc021f, 0xc0221, + 0xc0223, 0xc0225, 0xc0227, 0xc0229, 0xc022b, 0xc022d, 0xc022f, 0xc0231, 0xc023c, + 0xc023f, 0xc0240, 0xc0242, 0xc0247, 0xc0249, 0xc024b, 0xc024d, 0xc0371, 0xc0373, + 0xc0377, 0xc0390, 0xc03d0, 0xc03d1, 0xc03d9, 0xc03db, 0xc03dd, 0xc03df, 0xc03e1, + 0xc03e3, 0xc03e5, 0xc03e7, 0xc03e9, 0xc03eb, 0xc03ed, 0xc03f5, 0xc03f8, 0xc03fb, + 0xc03fc, 0xc0461, 0xc0463, 0xc0465, 0xc0467, 0xc0469, 0xc046b, 0xc046d, 0xc046f, + 0xc0471, 0xc0473, 0xc0475, 0xc0477, 0xc0479, 0xc047b, 0xc047d, 0xc047f, 0xc0481, + 0xc048b, 0xc048d, 0xc048f, 0xc0491, 0xc0493, 0xc0495, 0xc0497, 0xc0499, 0xc049b, + 0xc049d, 0xc049f, 0xc04a1, 0xc04a3, 0xc04a5, 0xc04a7, 0xc04a9, 0xc04ab, 0xc04ad, + 0xc04af, 0xc04b1, 0xc04b3, 0xc04b5, 0xc04b7, 0xc04b9, 0xc04bb, 0xc04bd, 0xc04bf, + 0xc04c2, 0xc04c4, 0xc04c6, 0xc04c8, 0xc04ca, 0xc04cc, 0xc04ce, 0xc04cf, 0xc04d1, + 0xc04d3, 0xc04d5, 0xc04d7, 0xc04d9, 0xc04db, 0xc04dd, 0xc04df, 0xc04e1, 0xc04e3, + 0xc04e5, 0xc04e7, 0xc04e9, 0xc04eb, 0xc04ed, 0xc04ef, 0xc04f1, 0xc04f3, 0xc04f5, + 0xc04f7, 0xc04f9, 0xc04fb, 0xc04fd, 0xc04ff, 0xc0501, 0xc0503, 0xc0505, 0xc0507, + 0xc0509, 0xc050b, 0xc050d, 0xc050f, 0xc0511, 0xc0513, 0xc0515, 0xc0517, 0xc0519, + 0xc051b, 0xc051d, 0xc051f, 0xc0521, 0xc0523, 0xc0525, 0xc0527, 0xc0529, 0xc052b, + 0xc052d, 0xc052f, 0xc1e01, 0xc1e03, 0xc1e05, 0xc1e07, 0xc1e09, 0xc1e0b, 0xc1e0d, + 0xc1e0f, 0xc1e11, 0xc1e13, 0xc1e15, 0xc1e17, 0xc1e19, 0xc1e1b, 0xc1e1d, 0xc1e1f, + 0xc1e21, 0xc1e23, 0xc1e25, 0xc1e27, 0xc1e29, 0xc1e2b, 0xc1e2d, 0xc1e2f, 0xc1e31, + 0xc1e33, 0xc1e35, 0xc1e37, 0xc1e39, 0xc1e3b, 0xc1e3d, 0xc1e3f, 0xc1e41, 0xc1e43, + 0xc1e45, 0xc1e47, 0xc1e49, 0xc1e4b, 0xc1e4d, 0xc1e4f, 0xc1e51, 0xc1e53, 0xc1e55, + 0xc1e57, 0xc1e59, 0xc1e5b, 0xc1e5d, 0xc1e5f, 0xc1e61, 0xc1e63, 0xc1e65, 0xc1e67, + 0xc1e69, 0xc1e6b, 0xc1e6d, 0xc1e6f, 0xc1e71, 0xc1e73, 0xc1e75, 0xc1e77, 0xc1e79, + 0xc1e7b, 0xc1e7d, 0xc1e7f, 0xc1e81, 0xc1e83, 0xc1e85, 0xc1e87, 0xc1e89, 0xc1e8b, + 0xc1e8d, 0xc1e8f, 0xc1e91, 0xc1e93, 0xc1e9f, 0xc1ea1, 0xc1ea3, 0xc1ea5, 0xc1ea7, + 0xc1ea9, 0xc1eab, 0xc1ead, 0xc1eaf, 0xc1eb1, 0xc1eb3, 0xc1eb5, 0xc1eb7, 0xc1eb9, + 0xc1ebb, 0xc1ebd, 0xc1ebf, 0xc1ec1, 0xc1ec3, 0xc1ec5, 0xc1ec7, 0xc1ec9, 0xc1ecb, + 0xc1ecd, 0xc1ecf, 0xc1ed1, 0xc1ed3, 0xc1ed5, 0xc1ed7, 0xc1ed9, 0xc1edb, 0xc1edd, + 0xc1edf, 0xc1ee1, 0xc1ee3, 0xc1ee5, 0xc1ee7, 0xc1ee9, 0xc1eeb, 0xc1eed, 0xc1eef, + 0xc1ef1, 0xc1ef3, 0xc1ef5, 0xc1ef7, 0xc1ef9, 0xc1efb, 0xc1efd, 0xc1fb6, 0xc1fb7, + 0xc1fbe, 0xc1fc6, 0xc1fc7, 0xc1fd6, 0xc1fd7, 0xc1ff6, 0xc1ff7, 0xc210a, 0xc210e, + 0xc210f, 0xc2113, 0xc212f, 0xc2134, 0xc2139, 0xc213c, 0xc213d, 0xc214e, 0xc2184, + 0xc2c61, 0xc2c65, 0xc2c66, 0xc2c68, 0xc2c6a, 0xc2c6c, 0xc2c71, 0xc2c73, 0xc2c74, + 0xc2c81, 0xc2c83, 0xc2c85, 0xc2c87, 0xc2c89, 0xc2c8b, 0xc2c8d, 0xc2c8f, 0xc2c91, + 0xc2c93, 0xc2c95, 0xc2c97, 0xc2c99, 0xc2c9b, 0xc2c9d, 0xc2c9f, 0xc2ca1, 0xc2ca3, + 0xc2ca5, 0xc2ca7, 0xc2ca9, 0xc2cab, 0xc2cad, 0xc2caf, 0xc2cb1, 0xc2cb3, 0xc2cb5, + 0xc2cb7, 0xc2cb9, 0xc2cbb, 0xc2cbd, 0xc2cbf, 0xc2cc1, 0xc2cc3, 0xc2cc5, 0xc2cc7, + 0xc2cc9, 0xc2ccb, 0xc2ccd, 0xc2ccf, 0xc2cd1, 0xc2cd3, 0xc2cd5, 0xc2cd7, 0xc2cd9, + 0xc2cdb, 0xc2cdd, 0xc2cdf, 0xc2ce1, 0xc2ce3, 0xc2ce4, 0xc2cec, 0xc2cee, 0xc2cf3, + 0xc2d27, 0xc2d2d, 0xca641, 0xca643, 0xca645, 0xca647, 0xca649, 0xca64b, 0xca64d, + 0xca64f, 0xca651, 0xca653, 0xca655, 0xca657, 0xca659, 0xca65b, 0xca65d, 0xca65f, + 0xca661, 0xca663, 0xca665, 0xca667, 0xca669, 0xca66b, 0xca66d, 0xca681, 0xca683, + 0xca685, 0xca687, 0xca689, 0xca68b, 0xca68d, 0xca68f, 0xca691, 0xca693, 0xca695, + 0xca697, 0xca699, 0xca69b, 0xca723, 0xca725, 0xca727, 0xca729, 0xca72b, 0xca72d, + 0xca733, 0xca735, 0xca737, 0xca739, 0xca73b, 0xca73d, 0xca73f, 0xca741, 0xca743, + 0xca745, 0xca747, 0xca749, 0xca74b, 0xca74d, 0xca74f, 0xca751, 0xca753, 0xca755, + 0xca757, 0xca759, 0xca75b, 0xca75d, 0xca75f, 0xca761, 0xca763, 0xca765, 0xca767, + 0xca769, 0xca76b, 0xca76d, 0xca76f, 0xca77a, 0xca77c, 0xca77f, 0xca781, 0xca783, + 0xca785, 0xca787, 0xca78c, 0xca78e, 0xca791, 0xca797, 0xca799, 0xca79b, 0xca79d, + 0xca79f, 0xca7a1, 0xca7a3, 0xca7a5, 0xca7a7, 0xca7a9, 0xca7b5, 0xca7b7, 0xca7fa, + 0xd00b5, 0xd0101, 0xd0103, 0xd0105, 0xd0107, 0xd0109, 0xd010b, 0xd010d, 0xd010f, + 0xd0111, 0xd0113, 0xd0115, 0xd0117, 0xd0119, 0xd011b, 0xd011d, 0xd011f, 0xd0121, + 0xd0123, 0xd0125, 0xd0127, 0xd0129, 0xd012b, 0xd012d, 0xd012f, 0xd0131, 0xd0133, + 0xd0135, 0xd0137, 0xd0138, 0xd013a, 0xd013c, 0xd013e, 0xd0140, 0xd0142, 0xd0144, + 0xd0146, 0xd0148, 0xd0149, 0xd014b, 0xd014d, 0xd014f, 0xd0151, 0xd0153, 0xd0155, + 0xd0157, 0xd0159, 0xd015b, 0xd015d, 0xd015f, 0xd0161, 0xd0163, 0xd0165, 0xd0167, + 0xd0169, 0xd016b, 0xd016d, 0xd016f, 0xd0171, 0xd0173, 0xd0175, 0xd0177, 0xd017a, + 0xd017c, 0xd0183, 0xd0185, 0xd0188, 0xd018c, 0xd018d, 0xd0192, 0xd0195, 0xd019e, + 0xd01a1, 0xd01a3, 0xd01a5, 0xd01a8, 0xd01aa, 0xd01ab, 0xd01ad, 0xd01b0, 0xd01b4, + 0xd01b6, 0xd01b9, 0xd01ba, 0xd01c6, 0xd01c9, 0xd01cc, 0xd01ce, 0xd01d0, 0xd01d2, + 0xd01d4, 0xd01d6, 0xd01d8, 0xd01da, 0xd01dc, 0xd01dd, 0xd01df, 0xd01e1, 0xd01e3, + 0xd01e5, 0xd01e7, 0xd01e9, 0xd01eb, 0xd01ed, 0xd01ef, 0xd01f0, 0xd01f3, 0xd01f5, + 0xd01f9, 0xd01fb, 0xd01fd, 0xd01ff, 0xd0201, 0xd0203, 0xd0205, 0xd0207, 0xd0209, + 0xd020b, 0xd020d, 0xd020f, 0xd0211, 0xd0213, 0xd0215, 0xd0217, 0xd0219, 0xd021b, + 0xd021d, 0xd021f, 0xd0221, 0xd0223, 0xd0225, 0xd0227, 0xd0229, 0xd022b, 0xd022d, + 0xd022f, 0xd0231, 0xd023c, 0xd023f, 0xd0240, 0xd0242, 0xd0247, 0xd0249, 0xd024b, + 0xd024d, 0xd0371, 0xd0373, 0xd0377, 0xd0390, 0xd03d0, 0xd03d1, 0xd03d9, 0xd03db, + 0xd03dd, 0xd03df, 0xd03e1, 0xd03e3, 0xd03e5, 0xd03e7, 0xd03e9, 0xd03eb, 0xd03ed, + 0xd03f5, 0xd03f8, 0xd03fb, 0xd03fc, 0xd0461, 0xd0463, 0xd0465, 0xd0467, 0xd0469, + 0xd046b, 0xd046d, 0xd046f, 0xd0471, 0xd0473, 0xd0475, 0xd0477, 0xd0479, 0xd047b, + 0xd047d, 0xd047f, 0xd0481, 0xd048b, 0xd048d, 0xd048f, 0xd0491, 0xd0493, 0xd0495, + 0xd0497, 0xd0499, 0xd049b, 0xd049d, 0xd049f, 0xd04a1, 0xd04a3, 0xd04a5, 0xd04a7, + 0xd04a9, 0xd04ab, 0xd04ad, 0xd04af, 0xd04b1, 0xd04b3, 0xd04b5, 0xd04b7, 0xd04b9, + 0xd04bb, 0xd04bd, 0xd04bf, 0xd04c2, 0xd04c4, 0xd04c6, 0xd04c8, 0xd04ca, 0xd04cc, + 0xd04ce, 0xd04cf, 0xd04d1, 0xd04d3, 0xd04d5, 0xd04d7, 0xd04d9, 0xd04db, 0xd04dd, + 0xd04df, 0xd04e1, 0xd04e3, 0xd04e5, 0xd04e7, 0xd04e9, 0xd04eb, 0xd04ed, 0xd04ef, + 0xd04f1, 0xd04f3, 0xd04f5, 0xd04f7, 0xd04f9, 0xd04fb, 0xd04fd, 0xd04ff, 0xd0501, + 0xd0503, 0xd0505, 0xd0507, 0xd0509, 0xd050b, 0xd050d, 0xd050f, 0xd0511, 0xd0513, + 0xd0515, 0xd0517, 0xd0519, 0xd051b, 0xd051d, 0xd051f, 0xd0521, 0xd0523, 0xd0525, + 0xd0527, 0xd0529, 0xd052b, 0xd052d, 0xd052f, 0xd1e01, 0xd1e03, 0xd1e05, 0xd1e07, + 0xd1e09, 0xd1e0b, 0xd1e0d, 0xd1e0f, 0xd1e11, 0xd1e13, 0xd1e15, 0xd1e17, 0xd1e19, + 0xd1e1b, 0xd1e1d, 0xd1e1f, 0xd1e21, 0xd1e23, 0xd1e25, 0xd1e27, 0xd1e29, 0xd1e2b, + 0xd1e2d, 0xd1e2f, 0xd1e31, 0xd1e33, 0xd1e35, 0xd1e37, 0xd1e39, 0xd1e3b, 0xd1e3d, + 0xd1e3f, 0xd1e41, 0xd1e43, 0xd1e45, 0xd1e47, 0xd1e49, 0xd1e4b, 0xd1e4d, 0xd1e4f, + 0xd1e51, 0xd1e53, 0xd1e55, 0xd1e57, 0xd1e59, 0xd1e5b, 0xd1e5d, 0xd1e5f, 0xd1e61, + 0xd1e63, 0xd1e65, 0xd1e67, 0xd1e69, 0xd1e6b, 0xd1e6d, 0xd1e6f, 0xd1e71, 0xd1e73, + 0xd1e75, 0xd1e77, 0xd1e79, 0xd1e7b, 0xd1e7d, 0xd1e7f, 0xd1e81, 0xd1e83, 0xd1e85, + 0xd1e87, 0xd1e89, 0xd1e8b, 0xd1e8d, 0xd1e8f, 0xd1e91, 0xd1e93, 0xd1e9f, 0xd1ea1, + 0xd1ea3, 0xd1ea5, 0xd1ea7, 0xd1ea9, 0xd1eab, 0xd1ead, 0xd1eaf, 0xd1eb1, 0xd1eb3, + 0xd1eb5, 0xd1eb7, 0xd1eb9, 0xd1ebb, 0xd1ebd, 0xd1ebf, 0xd1ec1, 0xd1ec3, 0xd1ec5, + 0xd1ec7, 0xd1ec9, 0xd1ecb, 0xd1ecd, 0xd1ecf, 0xd1ed1, 0xd1ed3, 0xd1ed5, 0xd1ed7, + 0xd1ed9, 0xd1edb, 0xd1edd, 0xd1edf, 0xd1ee1, 0xd1ee3, 0xd1ee5, 0xd1ee7, 0xd1ee9, + 0xd1eeb, 0xd1eed, 0xd1eef, 0xd1ef1, 0xd1ef3, 0xd1ef5, 0xd1ef7, 0xd1ef9, 0xd1efb, + 0xd1efd, 0xd1fb6, 0xd1fb7, 0xd1fbe, 0xd1fc6, 0xd1fc7, 0xd1fd6, 0xd1fd7, 0xd1ff6, + 0xd1ff7, 0xd210a, 0xd210e, 0xd210f, 0xd2113, 0xd212f, 0xd2134, 0xd2139, 0xd213c, + 0xd213d, 0xd214e, 0xd2184, 0xd2c61, 0xd2c65, 0xd2c66, 0xd2c68, 0xd2c6a, 0xd2c6c, + 0xd2c71, 0xd2c73, 0xd2c74, 0xd2c81, 0xd2c83, 0xd2c85, 0xd2c87, 0xd2c89, 0xd2c8b, + 0xd2c8d, 0xd2c8f, 0xd2c91, 0xd2c93, 0xd2c95, 0xd2c97, 0xd2c99, 0xd2c9b, 0xd2c9d, + 0xd2c9f, 0xd2ca1, 0xd2ca3, 0xd2ca5, 0xd2ca7, 0xd2ca9, 0xd2cab, 0xd2cad, 0xd2caf, + 0xd2cb1, 0xd2cb3, 0xd2cb5, 0xd2cb7, 0xd2cb9, 0xd2cbb, 0xd2cbd, 0xd2cbf, 0xd2cc1, + 0xd2cc3, 0xd2cc5, 0xd2cc7, 0xd2cc9, 0xd2ccb, 0xd2ccd, 0xd2ccf, 0xd2cd1, 0xd2cd3, + 0xd2cd5, 0xd2cd7, 0xd2cd9, 0xd2cdb, 0xd2cdd, 0xd2cdf, 0xd2ce1, 0xd2ce3, 0xd2ce4, + 0xd2cec, 0xd2cee, 0xd2cf3, 0xd2d27, 0xd2d2d, 0xda641, 0xda643, 0xda645, 0xda647, + 0xda649, 0xda64b, 0xda64d, 0xda64f, 0xda651, 0xda653, 0xda655, 0xda657, 0xda659, + 0xda65b, 0xda65d, 0xda65f, 0xda661, 0xda663, 0xda665, 0xda667, 0xda669, 0xda66b, + 0xda66d, 0xda681, 0xda683, 0xda685, 0xda687, 0xda689, 0xda68b, 0xda68d, 0xda68f, + 0xda691, 0xda693, 0xda695, 0xda697, 0xda699, 0xda69b, 0xda723, 0xda725, 0xda727, + 0xda729, 0xda72b, 0xda72d, 0xda733, 0xda735, 0xda737, 0xda739, 0xda73b, 0xda73d, + 0xda73f, 0xda741, 0xda743, 0xda745, 0xda747, 0xda749, 0xda74b, 0xda74d, 0xda74f, + 0xda751, 0xda753, 0xda755, 0xda757, 0xda759, 0xda75b, 0xda75d, 0xda75f, 0xda761, + 0xda763, 0xda765, 0xda767, 0xda769, 0xda76b, 0xda76d, 0xda76f, 0xda77a, 0xda77c, + 0xda77f, 0xda781, 0xda783, 0xda785, 0xda787, 0xda78c, 0xda78e, 0xda791, 0xda797, + 0xda799, 0xda79b, 0xda79d, 0xda79f, 0xda7a1, 0xda7a3, 0xda7a5, 0xda7a7, 0xda7a9, + 0xda7b5, 0xda7b7, 0xda7fa, 0xe00b5, 0xe0101, 0xe0103, 0xe0105, 0xe0107, 0xe0109, + 0xe010b, 0xe010d, 0xe010f, 0xe0111, 0xe0113, 0xe0115, 0xe0117, 0xe0119, 0xe011b, + 0xe011d, 0xe011f, 0xe0121, 0xe0123, 0xe0125, 0xe0127, 0xe0129, 0xe012b, 0xe012d, + 0xe012f, 0xe0131, 0xe0133, 0xe0135, 0xe0137, 0xe0138, 0xe013a, 0xe013c, 0xe013e, + 0xe0140, 0xe0142, 0xe0144, 0xe0146, 0xe0148, 0xe0149, 0xe014b, 0xe014d, 0xe014f, + 0xe0151, 0xe0153, 0xe0155, 0xe0157, 0xe0159, 0xe015b, 0xe015d, 0xe015f, 0xe0161, + 0xe0163, 0xe0165, 0xe0167, 0xe0169, 0xe016b, 0xe016d, 0xe016f, 0xe0171, 0xe0173, + 0xe0175, 0xe0177, 0xe017a, 0xe017c, 0xe0183, 0xe0185, 0xe0188, 0xe018c, 0xe018d, + 0xe0192, 0xe0195, 0xe019e, 0xe01a1, 0xe01a3, 0xe01a5, 0xe01a8, 0xe01aa, 0xe01ab, + 0xe01ad, 0xe01b0, 0xe01b4, 0xe01b6, 0xe01b9, 0xe01ba, 0xe01c6, 0xe01c9, 0xe01cc, + 0xe01ce, 0xe01d0, 0xe01d2, 0xe01d4, 0xe01d6, 0xe01d8, 0xe01da, 0xe01dc, 0xe01dd, + 0xe01df, 0xe01e1, 0xe01e3, 0xe01e5, 0xe01e7, 0xe01e9, 0xe01eb, 0xe01ed, 0xe01ef, + 0xe01f0, 0xe01f3, 0xe01f5, 0xe01f9, 0xe01fb, 0xe01fd, 0xe01ff, 0xe0201, 0xe0203, + 0xe0205, 0xe0207, 0xe0209, 0xe020b, 0xe020d, 0xe020f, 0xe0211, 0xe0213, 0xe0215, + 0xe0217, 0xe0219, 0xe021b, 0xe021d, 0xe021f, 0xe0221, 0xe0223, 0xe0225, 0xe0227, + 0xe0229, 0xe022b, 0xe022d, 0xe022f, 0xe0231, 0xe023c, 0xe023f, 0xe0240, 0xe0242, + 0xe0247, 0xe0249, 0xe024b, 0xe024d, 0xe0371, 0xe0373, 0xe0377, 0xe0390, 0xe03d0, + 0xe03d1, 0xe03d9, 0xe03db, 0xe03dd, 0xe03df, 0xe03e1, 0xe03e3, 0xe03e5, 0xe03e7, + 0xe03e9, 0xe03eb, 0xe03ed, 0xe03f5, 0xe03f8, 0xe03fb, 0xe03fc, 0xe0461, 0xe0463, + 0xe0465, 0xe0467, 0xe0469, 0xe046b, 0xe046d, 0xe046f, 0xe0471, 0xe0473, 0xe0475, + 0xe0477, 0xe0479, 0xe047b, 0xe047d, 0xe047f, 0xe0481, 0xe048b, 0xe048d, 0xe048f, + 0xe0491, 0xe0493, 0xe0495, 0xe0497, 0xe0499, 0xe049b, 0xe049d, 0xe049f, 0xe04a1, + 0xe04a3, 0xe04a5, 0xe04a7, 0xe04a9, 0xe04ab, 0xe04ad, 0xe04af, 0xe04b1, 0xe04b3, + 0xe04b5, 0xe04b7, 0xe04b9, 0xe04bb, 0xe04bd, 0xe04bf, 0xe04c2, 0xe04c4, 0xe04c6, + 0xe04c8, 0xe04ca, 0xe04cc, 0xe04ce, 0xe04cf, 0xe04d1, 0xe04d3, 0xe04d5, 0xe04d7, + 0xe04d9, 0xe04db, 0xe04dd, 0xe04df, 0xe04e1, 0xe04e3, 0xe04e5, 0xe04e7, 0xe04e9, + 0xe04eb, 0xe04ed, 0xe04ef, 0xe04f1, 0xe04f3, 0xe04f5, 0xe04f7, 0xe04f9, 0xe04fb, + 0xe04fd, 0xe04ff, 0xe0501, 0xe0503, 0xe0505, 0xe0507, 0xe0509, 0xe050b, 0xe050d, + 0xe050f, 0xe0511, 0xe0513, 0xe0515, 0xe0517, 0xe0519, 0xe051b, 0xe051d, 0xe051f, + 0xe0521, 0xe0523, 0xe0525, 0xe0527, 0xe0529, 0xe052b, 0xe052d, 0xe052f, 0xe1e01, + 0xe1e03, 0xe1e05, 0xe1e07, 0xe1e09, 0xe1e0b, 0xe1e0d, 0xe1e0f, 0xe1e11, 0xe1e13, + 0xe1e15, 0xe1e17, 0xe1e19, 0xe1e1b, 0xe1e1d, 0xe1e1f, 0xe1e21, 0xe1e23, 0xe1e25, + 0xe1e27, 0xe1e29, 0xe1e2b, 0xe1e2d, 0xe1e2f, 0xe1e31, 0xe1e33, 0xe1e35, 0xe1e37, + 0xe1e39, 0xe1e3b, 0xe1e3d, 0xe1e3f, 0xe1e41, 0xe1e43, 0xe1e45, 0xe1e47, 0xe1e49, + 0xe1e4b, 0xe1e4d, 0xe1e4f, 0xe1e51, 0xe1e53, 0xe1e55, 0xe1e57, 0xe1e59, 0xe1e5b, + 0xe1e5d, 0xe1e5f, 0xe1e61, 0xe1e63, 0xe1e65, 0xe1e67, 0xe1e69, 0xe1e6b, 0xe1e6d, + 0xe1e6f, 0xe1e71, 0xe1e73, 0xe1e75, 0xe1e77, 0xe1e79, 0xe1e7b, 0xe1e7d, 0xe1e7f, + 0xe1e81, 0xe1e83, 0xe1e85, 0xe1e87, 0xe1e89, 0xe1e8b, 0xe1e8d, 0xe1e8f, 0xe1e91, + 0xe1e93, 0xe1e9f, 0xe1ea1, 0xe1ea3, 0xe1ea5, 0xe1ea7, 0xe1ea9, 0xe1eab, 0xe1ead, + 0xe1eaf, 0xe1eb1, 0xe1eb3, 0xe1eb5, 0xe1eb7, 0xe1eb9, 0xe1ebb, 0xe1ebd, 0xe1ebf, + 0xe1ec1, 0xe1ec3, 0xe1ec5, 0xe1ec7, 0xe1ec9, 0xe1ecb, 0xe1ecd, 0xe1ecf, 0xe1ed1, + 0xe1ed3, 0xe1ed5, 0xe1ed7, 0xe1ed9, 0xe1edb, 0xe1edd, 0xe1edf, 0xe1ee1, 0xe1ee3, + 0xe1ee5, 0xe1ee7, 0xe1ee9, 0xe1eeb, 0xe1eed, 0xe1eef, 0xe1ef1, 0xe1ef3, 0xe1ef5, + 0xe1ef7, 0xe1ef9, 0xe1efb, 0xe1efd, 0xe1fb6, 0xe1fb7, 0xe1fbe, 0xe1fc6, 0xe1fc7, + 0xe1fd6, 0xe1fd7, 0xe1ff6, 0xe1ff7, 0xe210a, 0xe210e, 0xe210f, 0xe2113, 0xe212f, + 0xe2134, 0xe2139, 0xe213c, 0xe213d, 0xe214e, 0xe2184, 0xe2c61, 0xe2c65, 0xe2c66, + 0xe2c68, 0xe2c6a, 0xe2c6c, 0xe2c71, 0xe2c73, 0xe2c74, 0xe2c81, 0xe2c83, 0xe2c85, + 0xe2c87, 0xe2c89, 0xe2c8b, 0xe2c8d, 0xe2c8f, 0xe2c91, 0xe2c93, 0xe2c95, 0xe2c97, + 0xe2c99, 0xe2c9b, 0xe2c9d, 0xe2c9f, 0xe2ca1, 0xe2ca3, 0xe2ca5, 0xe2ca7, 0xe2ca9, + 0xe2cab, 0xe2cad, 0xe2caf, 0xe2cb1, 0xe2cb3, 0xe2cb5, 0xe2cb7, 0xe2cb9, 0xe2cbb, + 0xe2cbd, 0xe2cbf, 0xe2cc1, 0xe2cc3, 0xe2cc5, 0xe2cc7, 0xe2cc9, 0xe2ccb, 0xe2ccd, + 0xe2ccf, 0xe2cd1, 0xe2cd3, 0xe2cd5, 0xe2cd7, 0xe2cd9, 0xe2cdb, 0xe2cdd, 0xe2cdf, + 0xe2ce1, 0xe2ce3, 0xe2ce4, 0xe2cec, 0xe2cee, 0xe2cf3, 0xe2d27, 0xe2d2d, 0xea641, + 0xea643, 0xea645, 0xea647, 0xea649, 0xea64b, 0xea64d, 0xea64f, 0xea651, 0xea653, + 0xea655, 0xea657, 0xea659, 0xea65b, 0xea65d, 0xea65f, 0xea661, 0xea663, 0xea665, + 0xea667, 0xea669, 0xea66b, 0xea66d, 0xea681, 0xea683, 0xea685, 0xea687, 0xea689, + 0xea68b, 0xea68d, 0xea68f, 0xea691, 0xea693, 0xea695, 0xea697, 0xea699, 0xea69b, + 0xea723, 0xea725, 0xea727, 0xea729, 0xea72b, 0xea72d, 0xea733, 0xea735, 0xea737, + 0xea739, 0xea73b, 0xea73d, 0xea73f, 0xea741, 0xea743, 0xea745, 0xea747, 0xea749, + 0xea74b, 0xea74d, 0xea74f, 0xea751, 0xea753, 0xea755, 0xea757, 0xea759, 0xea75b, + 0xea75d, 0xea75f, 0xea761, 0xea763, 0xea765, 0xea767, 0xea769, 0xea76b, 0xea76d, + 0xea76f, 0xea77a, 0xea77c, 0xea77f, 0xea781, 0xea783, 0xea785, 0xea787, 0xea78c, + 0xea78e, 0xea791, 0xea797, 0xea799, 0xea79b, 0xea79d, 0xea79f, 0xea7a1, 0xea7a3, + 0xea7a5, 0xea7a7, 0xea7a9, 0xea7b5, 0xea7b7, 0xea7fa, 0xf00b5, 0xf0101, 0xf0103, + 0xf0105, 0xf0107, 0xf0109, 0xf010b, 0xf010d, 0xf010f, 0xf0111, 0xf0113, 0xf0115, + 0xf0117, 0xf0119, 0xf011b, 0xf011d, 0xf011f, 0xf0121, 0xf0123, 0xf0125, 0xf0127, + 0xf0129, 0xf012b, 0xf012d, 0xf012f, 0xf0131, 0xf0133, 0xf0135, 0xf0137, 0xf0138, + 0xf013a, 0xf013c, 0xf013e, 0xf0140, 0xf0142, 0xf0144, 0xf0146, 0xf0148, 0xf0149, + 0xf014b, 0xf014d, 0xf014f, 0xf0151, 0xf0153, 0xf0155, 0xf0157, 0xf0159, 0xf015b, + 0xf015d, 0xf015f, 0xf0161, 0xf0163, 0xf0165, 0xf0167, 0xf0169, 0xf016b, 0xf016d, + 0xf016f, 0xf0171, 0xf0173, 0xf0175, 0xf0177, 0xf017a, 0xf017c, 0xf0183, 0xf0185, + 0xf0188, 0xf018c, 0xf018d, 0xf0192, 0xf0195, 0xf019e, 0xf01a1, 0xf01a3, 0xf01a5, + 0xf01a8, 0xf01aa, 0xf01ab, 0xf01ad, 0xf01b0, 0xf01b4, 0xf01b6, 0xf01b9, 0xf01ba, + 0xf01c6, 0xf01c9, 0xf01cc, 0xf01ce, 0xf01d0, 0xf01d2, 0xf01d4, 0xf01d6, 0xf01d8, + 0xf01da, 0xf01dc, 0xf01dd, 0xf01df, 0xf01e1, 0xf01e3, 0xf01e5, 0xf01e7, 0xf01e9, + 0xf01eb, 0xf01ed, 0xf01ef, 0xf01f0, 0xf01f3, 0xf01f5, 0xf01f9, 0xf01fb, 0xf01fd, + 0xf01ff, 0xf0201, 0xf0203, 0xf0205, 0xf0207, 0xf0209, 0xf020b, 0xf020d, 0xf020f, + 0xf0211, 0xf0213, 0xf0215, 0xf0217, 0xf0219, 0xf021b, 0xf021d, 0xf021f, 0xf0221, + 0xf0223, 0xf0225, 0xf0227, 0xf0229, 0xf022b, 0xf022d, 0xf022f, 0xf0231, 0xf023c, + 0xf023f, 0xf0240, 0xf0242, 0xf0247, 0xf0249, 0xf024b, 0xf024d, 0xf0371, 0xf0373, + 0xf0377, 0xf0390, 0xf03d0, 0xf03d1, 0xf03d9, 0xf03db, 0xf03dd, 0xf03df, 0xf03e1, + 0xf03e3, 0xf03e5, 0xf03e7, 0xf03e9, 0xf03eb, 0xf03ed, 0xf03f5, 0xf03f8, 0xf03fb, + 0xf03fc, 0xf0461, 0xf0463, 0xf0465, 0xf0467, 0xf0469, 0xf046b, 0xf046d, 0xf046f, + 0xf0471, 0xf0473, 0xf0475, 0xf0477, 0xf0479, 0xf047b, 0xf047d, 0xf047f, 0xf0481, + 0xf048b, 0xf048d, 0xf048f, 0xf0491, 0xf0493, 0xf0495, 0xf0497, 0xf0499, 0xf049b, + 0xf049d, 0xf049f, 0xf04a1, 0xf04a3, 0xf04a5, 0xf04a7, 0xf04a9, 0xf04ab, 0xf04ad, + 0xf04af, 0xf04b1, 0xf04b3, 0xf04b5, 0xf04b7, 0xf04b9, 0xf04bb, 0xf04bd, 0xf04bf, + 0xf04c2, 0xf04c4, 0xf04c6, 0xf04c8, 0xf04ca, 0xf04cc, 0xf04ce, 0xf04cf, 0xf04d1, + 0xf04d3, 0xf04d5, 0xf04d7, 0xf04d9, 0xf04db, 0xf04dd, 0xf04df, 0xf04e1, 0xf04e3, + 0xf04e5, 0xf04e7, 0xf04e9, 0xf04eb, 0xf04ed, 0xf04ef, 0xf04f1, 0xf04f3, 0xf04f5, + 0xf04f7, 0xf04f9, 0xf04fb, 0xf04fd, 0xf04ff, 0xf0501, 0xf0503, 0xf0505, 0xf0507, + 0xf0509, 0xf050b, 0xf050d, 0xf050f, 0xf0511, 0xf0513, 0xf0515, 0xf0517, 0xf0519, + 0xf051b, 0xf051d, 0xf051f, 0xf0521, 0xf0523, 0xf0525, 0xf0527, 0xf0529, 0xf052b, + 0xf052d, 0xf052f, 0xf1e01, 0xf1e03, 0xf1e05, 0xf1e07, 0xf1e09, 0xf1e0b, 0xf1e0d, + 0xf1e0f, 0xf1e11, 0xf1e13, 0xf1e15, 0xf1e17, 0xf1e19, 0xf1e1b, 0xf1e1d, 0xf1e1f, + 0xf1e21, 0xf1e23, 0xf1e25, 0xf1e27, 0xf1e29, 0xf1e2b, 0xf1e2d, 0xf1e2f, 0xf1e31, + 0xf1e33, 0xf1e35, 0xf1e37, 0xf1e39, 0xf1e3b, 0xf1e3d, 0xf1e3f, 0xf1e41, 0xf1e43, + 0xf1e45, 0xf1e47, 0xf1e49, 0xf1e4b, 0xf1e4d, 0xf1e4f, 0xf1e51, 0xf1e53, 0xf1e55, + 0xf1e57, 0xf1e59, 0xf1e5b, 0xf1e5d, 0xf1e5f, 0xf1e61, 0xf1e63, 0xf1e65, 0xf1e67, + 0xf1e69, 0xf1e6b, 0xf1e6d, 0xf1e6f, 0xf1e71, 0xf1e73, 0xf1e75, 0xf1e77, 0xf1e79, + 0xf1e7b, 0xf1e7d, 0xf1e7f, 0xf1e81, 0xf1e83, 0xf1e85, 0xf1e87, 0xf1e89, 0xf1e8b, + 0xf1e8d, 0xf1e8f, 0xf1e91, 0xf1e93, 0xf1e9f, 0xf1ea1, 0xf1ea3, 0xf1ea5, 0xf1ea7, + 0xf1ea9, 0xf1eab, 0xf1ead, 0xf1eaf, 0xf1eb1, 0xf1eb3, 0xf1eb5, 0xf1eb7, 0xf1eb9, + 0xf1ebb, 0xf1ebd, 0xf1ebf, 0xf1ec1, 0xf1ec3, 0xf1ec5, 0xf1ec7, 0xf1ec9, 0xf1ecb, + 0xf1ecd, 0xf1ecf, 0xf1ed1, 0xf1ed3, 0xf1ed5, 0xf1ed7, 0xf1ed9, 0xf1edb, 0xf1edd, + 0xf1edf, 0xf1ee1, 0xf1ee3, 0xf1ee5, 0xf1ee7, 0xf1ee9, 0xf1eeb, 0xf1eed, 0xf1eef, + 0xf1ef1, 0xf1ef3, 0xf1ef5, 0xf1ef7, 0xf1ef9, 0xf1efb, 0xf1efd, 0xf1fb6, 0xf1fb7, + 0xf1fbe, 0xf1fc6, 0xf1fc7, 0xf1fd6, 0xf1fd7, 0xf1ff6, 0xf1ff7, 0xf210a, 0xf210e, + 0xf210f, 0xf2113, 0xf212f, 0xf2134, 0xf2139, 0xf213c, 0xf213d, 0xf214e, 0xf2184, + 0xf2c61, 0xf2c65, 0xf2c66, 0xf2c68, 0xf2c6a, 0xf2c6c, 0xf2c71, 0xf2c73, 0xf2c74, + 0xf2c81, 0xf2c83, 0xf2c85, 0xf2c87, 0xf2c89, 0xf2c8b, 0xf2c8d, 0xf2c8f, 0xf2c91, + 0xf2c93, 0xf2c95, 0xf2c97, 0xf2c99, 0xf2c9b, 0xf2c9d, 0xf2c9f, 0xf2ca1, 0xf2ca3, + 0xf2ca5, 0xf2ca7, 0xf2ca9, 0xf2cab, 0xf2cad, 0xf2caf, 0xf2cb1, 0xf2cb3, 0xf2cb5, + 0xf2cb7, 0xf2cb9, 0xf2cbb, 0xf2cbd, 0xf2cbf, 0xf2cc1, 0xf2cc3, 0xf2cc5, 0xf2cc7, + 0xf2cc9, 0xf2ccb, 0xf2ccd, 0xf2ccf, 0xf2cd1, 0xf2cd3, 0xf2cd5, 0xf2cd7, 0xf2cd9, + 0xf2cdb, 0xf2cdd, 0xf2cdf, 0xf2ce1, 0xf2ce3, 0xf2ce4, 0xf2cec, 0xf2cee, 0xf2cf3, + 0xf2d27, 0xf2d2d, 0xfa641, 0xfa643, 0xfa645, 0xfa647, 0xfa649, 0xfa64b, 0xfa64d, + 0xfa64f, 0xfa651, 0xfa653, 0xfa655, 0xfa657, 0xfa659, 0xfa65b, 0xfa65d, 0xfa65f, + 0xfa661, 0xfa663, 0xfa665, 0xfa667, 0xfa669, 0xfa66b, 0xfa66d, 0xfa681, 0xfa683, + 0xfa685, 0xfa687, 0xfa689, 0xfa68b, 0xfa68d, 0xfa68f, 0xfa691, 0xfa693, 0xfa695, + 0xfa697, 0xfa699, 0xfa69b, 0xfa723, 0xfa725, 0xfa727, 0xfa729, 0xfa72b, 0xfa72d, + 0xfa733, 0xfa735, 0xfa737, 0xfa739, 0xfa73b, 0xfa73d, 0xfa73f, 0xfa741, 0xfa743, + 0xfa745, 0xfa747, 0xfa749, 0xfa74b, 0xfa74d, 0xfa74f, 0xfa751, 0xfa753, 0xfa755, + 0xfa757, 0xfa759, 0xfa75b, 0xfa75d, 0xfa75f, 0xfa761, 0xfa763, 0xfa765, 0xfa767, + 0xfa769, 0xfa76b, 0xfa76d, 0xfa76f, 0xfa77a, 0xfa77c, 0xfa77f, 0xfa781, 0xfa783, + 0xfa785, 0xfa787, 0xfa78c, 0xfa78e, 0xfa791, 0xfa797, 0xfa799, 0xfa79b, 0xfa79d, + 0xfa79f, 0xfa7a1, 0xfa7a3, 0xfa7a5, 0xfa7a7, 0xfa7a9, 0xfa7b5, 0xfa7b7, 0xfa7fa, + 0x1000b5, 0x100101, 0x100103, 0x100105, 0x100107, 0x100109, 0x10010b, 0x10010d, 0x10010f, + 0x100111, 0x100113, 0x100115, 0x100117, 0x100119, 0x10011b, 0x10011d, 0x10011f, 0x100121, + 0x100123, 0x100125, 0x100127, 0x100129, 0x10012b, 0x10012d, 0x10012f, 0x100131, 0x100133, + 0x100135, 0x100137, 0x100138, 0x10013a, 0x10013c, 0x10013e, 0x100140, 0x100142, 0x100144, + 0x100146, 0x100148, 0x100149, 0x10014b, 0x10014d, 0x10014f, 0x100151, 0x100153, 0x100155, + 0x100157, 0x100159, 0x10015b, 0x10015d, 0x10015f, 0x100161, 0x100163, 0x100165, 0x100167, + 0x100169, 0x10016b, 0x10016d, 0x10016f, 0x100171, 0x100173, 0x100175, 0x100177, 0x10017a, + 0x10017c, 0x100183, 0x100185, 0x100188, 0x10018c, 0x10018d, 0x100192, 0x100195, 0x10019e, + 0x1001a1, 0x1001a3, 0x1001a5, 0x1001a8, 0x1001aa, 0x1001ab, 0x1001ad, 0x1001b0, 0x1001b4, + 0x1001b6, 0x1001b9, 0x1001ba, 0x1001c6, 0x1001c9, 0x1001cc, 0x1001ce, 0x1001d0, 0x1001d2, + 0x1001d4, 0x1001d6, 0x1001d8, 0x1001da, 0x1001dc, 0x1001dd, 0x1001df, 0x1001e1, 0x1001e3, + 0x1001e5, 0x1001e7, 0x1001e9, 0x1001eb, 0x1001ed, 0x1001ef, 0x1001f0, 0x1001f3, 0x1001f5, + 0x1001f9, 0x1001fb, 0x1001fd, 0x1001ff, 0x100201, 0x100203, 0x100205, 0x100207, 0x100209, + 0x10020b, 0x10020d, 0x10020f, 0x100211, 0x100213, 0x100215, 0x100217, 0x100219, 0x10021b, + 0x10021d, 0x10021f, 0x100221, 0x100223, 0x100225, 0x100227, 0x100229, 0x10022b, 0x10022d, + 0x10022f, 0x100231, 0x10023c, 0x10023f, 0x100240, 0x100242, 0x100247, 0x100249, 0x10024b, + 0x10024d, 0x100371, 0x100373, 0x100377, 0x100390, 0x1003d0, 0x1003d1, 0x1003d9, 0x1003db, + 0x1003dd, 0x1003df, 0x1003e1, 0x1003e3, 0x1003e5, 0x1003e7, 0x1003e9, 0x1003eb, 0x1003ed, + 0x1003f5, 0x1003f8, 0x1003fb, 0x1003fc, 0x100461, 0x100463, 0x100465, 0x100467, 0x100469, + 0x10046b, 0x10046d, 0x10046f, 0x100471, 0x100473, 0x100475, 0x100477, 0x100479, 0x10047b, + 0x10047d, 0x10047f, 0x100481, 0x10048b, 0x10048d, 0x10048f, 0x100491, 0x100493, 0x100495, + 0x100497, 0x100499, 0x10049b, 0x10049d, 0x10049f, 0x1004a1, 0x1004a3, 0x1004a5, 0x1004a7, + 0x1004a9, 0x1004ab, 0x1004ad, 0x1004af, 0x1004b1, 0x1004b3, 0x1004b5, 0x1004b7, 0x1004b9, + 0x1004bb, 0x1004bd, 0x1004bf, 0x1004c2, 0x1004c4, 0x1004c6, 0x1004c8, 0x1004ca, 0x1004cc, + 0x1004ce, 0x1004cf, 0x1004d1, 0x1004d3, 0x1004d5, 0x1004d7, 0x1004d9, 0x1004db, 0x1004dd, + 0x1004df, 0x1004e1, 0x1004e3, 0x1004e5, 0x1004e7, 0x1004e9, 0x1004eb, 0x1004ed, 0x1004ef, + 0x1004f1, 0x1004f3, 0x1004f5, 0x1004f7, 0x1004f9, 0x1004fb, 0x1004fd, 0x1004ff, 0x100501, + 0x100503, 0x100505, 0x100507, 0x100509, 0x10050b, 0x10050d, 0x10050f, 0x100511, 0x100513, + 0x100515, 0x100517, 0x100519, 0x10051b, 0x10051d, 0x10051f, 0x100521, 0x100523, 0x100525, + 0x100527, 0x100529, 0x10052b, 0x10052d, 0x10052f, 0x101e01, 0x101e03, 0x101e05, 0x101e07, + 0x101e09, 0x101e0b, 0x101e0d, 0x101e0f, 0x101e11, 0x101e13, 0x101e15, 0x101e17, 0x101e19, + 0x101e1b, 0x101e1d, 0x101e1f, 0x101e21, 0x101e23, 0x101e25, 0x101e27, 0x101e29, 0x101e2b, + 0x101e2d, 0x101e2f, 0x101e31, 0x101e33, 0x101e35, 0x101e37, 0x101e39, 0x101e3b, 0x101e3d, + 0x101e3f, 0x101e41, 0x101e43, 0x101e45, 0x101e47, 0x101e49, 0x101e4b, 0x101e4d, 0x101e4f, + 0x101e51, 0x101e53, 0x101e55, 0x101e57, 0x101e59, 0x101e5b, 0x101e5d, 0x101e5f, 0x101e61, + 0x101e63, 0x101e65, 0x101e67, 0x101e69, 0x101e6b, 0x101e6d, 0x101e6f, 0x101e71, 0x101e73, + 0x101e75, 0x101e77, 0x101e79, 0x101e7b, 0x101e7d, 0x101e7f, 0x101e81, 0x101e83, 0x101e85, + 0x101e87, 0x101e89, 0x101e8b, 0x101e8d, 0x101e8f, 0x101e91, 0x101e93, 0x101e9f, 0x101ea1, + 0x101ea3, 0x101ea5, 0x101ea7, 0x101ea9, 0x101eab, 0x101ead, 0x101eaf, 0x101eb1, 0x101eb3, + 0x101eb5, 0x101eb7, 0x101eb9, 0x101ebb, 0x101ebd, 0x101ebf, 0x101ec1, 0x101ec3, 0x101ec5, + 0x101ec7, 0x101ec9, 0x101ecb, 0x101ecd, 0x101ecf, 0x101ed1, 0x101ed3, 0x101ed5, 0x101ed7, + 0x101ed9, 0x101edb, 0x101edd, 0x101edf, 0x101ee1, 0x101ee3, 0x101ee5, 0x101ee7, 0x101ee9, + 0x101eeb, 0x101eed, 0x101eef, 0x101ef1, 0x101ef3, 0x101ef5, 0x101ef7, 0x101ef9, 0x101efb, + 0x101efd, 0x101fb6, 0x101fb7, 0x101fbe, 0x101fc6, 0x101fc7, 0x101fd6, 0x101fd7, 0x101ff6, + 0x101ff7, 0x10210a, 0x10210e, 0x10210f, 0x102113, 0x10212f, 0x102134, 0x102139, 0x10213c, + 0x10213d, 0x10214e, 0x102184, 0x102c61, 0x102c65, 0x102c66, 0x102c68, 0x102c6a, 0x102c6c, + 0x102c71, 0x102c73, 0x102c74, 0x102c81, 0x102c83, 0x102c85, 0x102c87, 0x102c89, 0x102c8b, + 0x102c8d, 0x102c8f, 0x102c91, 0x102c93, 0x102c95, 0x102c97, 0x102c99, 0x102c9b, 0x102c9d, + 0x102c9f, 0x102ca1, 0x102ca3, 0x102ca5, 0x102ca7, 0x102ca9, 0x102cab, 0x102cad, 0x102caf, + 0x102cb1, 0x102cb3, 0x102cb5, 0x102cb7, 0x102cb9, 0x102cbb, 0x102cbd, 0x102cbf, 0x102cc1, + 0x102cc3, 0x102cc5, 0x102cc7, 0x102cc9, 0x102ccb, 0x102ccd, 0x102ccf, 0x102cd1, 0x102cd3, + 0x102cd5, 0x102cd7, 0x102cd9, 0x102cdb, 0x102cdd, 0x102cdf, 0x102ce1, 0x102ce3, 0x102ce4, + 0x102cec, 0x102cee, 0x102cf3, 0x102d27, 0x102d2d, 0x10a641, 0x10a643, 0x10a645, 0x10a647, + 0x10a649, 0x10a64b, 0x10a64d, 0x10a64f, 0x10a651, 0x10a653, 0x10a655, 0x10a657, 0x10a659, + 0x10a65b, 0x10a65d, 0x10a65f, 0x10a661, 0x10a663, 0x10a665, 0x10a667, 0x10a669, 0x10a66b, + 0x10a66d, 0x10a681, 0x10a683, 0x10a685, 0x10a687, 0x10a689, 0x10a68b, 0x10a68d, 0x10a68f, + 0x10a691, 0x10a693, 0x10a695, 0x10a697, 0x10a699, 0x10a69b, 0x10a723, 0x10a725, 0x10a727, + 0x10a729, 0x10a72b, 0x10a72d, 0x10a733, 0x10a735, 0x10a737, 0x10a739, 0x10a73b, 0x10a73d, + 0x10a73f, 0x10a741, 0x10a743, 0x10a745, 0x10a747, 0x10a749, 0x10a74b, 0x10a74d, 0x10a74f, + 0x10a751, 0x10a753, 0x10a755, 0x10a757, 0x10a759, 0x10a75b, 0x10a75d, 0x10a75f, 0x10a761, + 0x10a763, 0x10a765, 0x10a767, 0x10a769, 0x10a76b, 0x10a76d, 0x10a76f, 0x10a77a, 0x10a77c, + 0x10a77f, 0x10a781, 0x10a783, 0x10a785, 0x10a787, 0x10a78c, 0x10a78e, 0x10a791, 0x10a797, + 0x10a799, 0x10a79b, 0x10a79d, 0x10a79f, 0x10a7a1, 0x10a7a3, 0x10a7a5, 0x10a7a7, 0x10a7a9, + 0x10a7b5, 0x10a7b7, 0x10a7fa #endif }; @@ -521,13 +3626,166 @@ static const crange upperRangeTable[] = { {0x2130, 0x2133}, {0x2c00, 0x2c2e}, {0x2c62, 0x2c64}, {0x2c6d, 0x2c70}, {0x2c7e, 0x2c80}, {0xa7aa, 0xa7ae}, {0xa7b0, 0xa7b4}, {0xff21, 0xff3a} #if TCL_UTF_MAX > 4 - ,{0x10400, 0x10427}, {0x104b0, 0x104d3}, {0x10c80, 0x10cb2}, {0x118a0, 0x118bf}, - {0x1d400, 0x1d419}, {0x1d434, 0x1d44d}, {0x1d468, 0x1d481}, {0x1d4a9, 0x1d4ac}, - {0x1d4ae, 0x1d4b5}, {0x1d4d0, 0x1d4e9}, {0x1d507, 0x1d50a}, {0x1d50d, 0x1d514}, - {0x1d516, 0x1d51c}, {0x1d53b, 0x1d53e}, {0x1d540, 0x1d544}, {0x1d54a, 0x1d550}, - {0x1d56c, 0x1d585}, {0x1d5a0, 0x1d5b9}, {0x1d5d4, 0x1d5ed}, {0x1d608, 0x1d621}, - {0x1d63c, 0x1d655}, {0x1d670, 0x1d689}, {0x1d6a8, 0x1d6c0}, {0x1d6e2, 0x1d6fa}, - {0x1d71c, 0x1d734}, {0x1d756, 0x1d76e}, {0x1d790, 0x1d7a8}, {0x1e900, 0x1e921} + ,{0x10041, 0x1005a}, {0x100c0, 0x100d6}, {0x100d8, 0x100de}, {0x10189, 0x1018b}, + {0x1018e, 0x10191}, {0x10196, 0x10198}, {0x101b1, 0x101b3}, {0x101f6, 0x101f8}, + {0x10243, 0x10246}, {0x10388, 0x1038a}, {0x10391, 0x103a1}, {0x103a3, 0x103ab}, + {0x103d2, 0x103d4}, {0x103fd, 0x1042f}, {0x10531, 0x10556}, {0x110a0, 0x110c5}, + {0x113a0, 0x113f5}, {0x11f08, 0x11f0f}, {0x11f18, 0x11f1d}, {0x11f28, 0x11f2f}, + {0x11f38, 0x11f3f}, {0x11f48, 0x11f4d}, {0x11f68, 0x11f6f}, {0x11fb8, 0x11fbb}, + {0x11fc8, 0x11fcb}, {0x11fd8, 0x11fdb}, {0x11fe8, 0x11fec}, {0x11ff8, 0x11ffb}, + {0x1210b, 0x1210d}, {0x12110, 0x12112}, {0x12119, 0x1211d}, {0x1212a, 0x1212d}, + {0x12130, 0x12133}, {0x12c00, 0x12c2e}, {0x12c62, 0x12c64}, {0x12c6d, 0x12c70}, + {0x12c7e, 0x12c80}, {0x1a7aa, 0x1a7ae}, {0x1a7b0, 0x1a7b4}, {0x1ff21, 0x1ff3a}, + {0x20041, 0x2005a}, {0x200c0, 0x200d6}, {0x200d8, 0x200de}, {0x20189, 0x2018b}, + {0x2018e, 0x20191}, {0x20196, 0x20198}, {0x201b1, 0x201b3}, {0x201f6, 0x201f8}, + {0x20243, 0x20246}, {0x20388, 0x2038a}, {0x20391, 0x203a1}, {0x203a3, 0x203ab}, + {0x203d2, 0x203d4}, {0x203fd, 0x2042f}, {0x20531, 0x20556}, {0x210a0, 0x210c5}, + {0x213a0, 0x213f5}, {0x21f08, 0x21f0f}, {0x21f18, 0x21f1d}, {0x21f28, 0x21f2f}, + {0x21f38, 0x21f3f}, {0x21f48, 0x21f4d}, {0x21f68, 0x21f6f}, {0x21fb8, 0x21fbb}, + {0x21fc8, 0x21fcb}, {0x21fd8, 0x21fdb}, {0x21fe8, 0x21fec}, {0x21ff8, 0x21ffb}, + {0x2210b, 0x2210d}, {0x22110, 0x22112}, {0x22119, 0x2211d}, {0x2212a, 0x2212d}, + {0x22130, 0x22133}, {0x22c00, 0x22c2e}, {0x22c62, 0x22c64}, {0x22c6d, 0x22c70}, + {0x22c7e, 0x22c80}, {0x2a7aa, 0x2a7ae}, {0x2a7b0, 0x2a7b4}, {0x2ff21, 0x2ff3a}, + {0x30041, 0x3005a}, {0x300c0, 0x300d6}, {0x300d8, 0x300de}, {0x30189, 0x3018b}, + {0x3018e, 0x30191}, {0x30196, 0x30198}, {0x301b1, 0x301b3}, {0x301f6, 0x301f8}, + {0x30243, 0x30246}, {0x30388, 0x3038a}, {0x30391, 0x303a1}, {0x303a3, 0x303ab}, + {0x303d2, 0x303d4}, {0x303fd, 0x3042f}, {0x30531, 0x30556}, {0x310a0, 0x310c5}, + {0x313a0, 0x313f5}, {0x31f08, 0x31f0f}, {0x31f18, 0x31f1d}, {0x31f28, 0x31f2f}, + {0x31f38, 0x31f3f}, {0x31f48, 0x31f4d}, {0x31f68, 0x31f6f}, {0x31fb8, 0x31fbb}, + {0x31fc8, 0x31fcb}, {0x31fd8, 0x31fdb}, {0x31fe8, 0x31fec}, {0x31ff8, 0x31ffb}, + {0x3210b, 0x3210d}, {0x32110, 0x32112}, {0x32119, 0x3211d}, {0x3212a, 0x3212d}, + {0x32130, 0x32133}, {0x32c00, 0x32c2e}, {0x32c62, 0x32c64}, {0x32c6d, 0x32c70}, + {0x32c7e, 0x32c80}, {0x3a7aa, 0x3a7ae}, {0x3a7b0, 0x3a7b4}, {0x3ff21, 0x3ff3a}, + {0x40041, 0x4005a}, {0x400c0, 0x400d6}, {0x400d8, 0x400de}, {0x40189, 0x4018b}, + {0x4018e, 0x40191}, {0x40196, 0x40198}, {0x401b1, 0x401b3}, {0x401f6, 0x401f8}, + {0x40243, 0x40246}, {0x40388, 0x4038a}, {0x40391, 0x403a1}, {0x403a3, 0x403ab}, + {0x403d2, 0x403d4}, {0x403fd, 0x4042f}, {0x40531, 0x40556}, {0x410a0, 0x410c5}, + {0x413a0, 0x413f5}, {0x41f08, 0x41f0f}, {0x41f18, 0x41f1d}, {0x41f28, 0x41f2f}, + {0x41f38, 0x41f3f}, {0x41f48, 0x41f4d}, {0x41f68, 0x41f6f}, {0x41fb8, 0x41fbb}, + {0x41fc8, 0x41fcb}, {0x41fd8, 0x41fdb}, {0x41fe8, 0x41fec}, {0x41ff8, 0x41ffb}, + {0x4210b, 0x4210d}, {0x42110, 0x42112}, {0x42119, 0x4211d}, {0x4212a, 0x4212d}, + {0x42130, 0x42133}, {0x42c00, 0x42c2e}, {0x42c62, 0x42c64}, {0x42c6d, 0x42c70}, + {0x42c7e, 0x42c80}, {0x4a7aa, 0x4a7ae}, {0x4a7b0, 0x4a7b4}, {0x4ff21, 0x4ff3a}, + {0x50041, 0x5005a}, {0x500c0, 0x500d6}, {0x500d8, 0x500de}, {0x50189, 0x5018b}, + {0x5018e, 0x50191}, {0x50196, 0x50198}, {0x501b1, 0x501b3}, {0x501f6, 0x501f8}, + {0x50243, 0x50246}, {0x50388, 0x5038a}, {0x50391, 0x503a1}, {0x503a3, 0x503ab}, + {0x503d2, 0x503d4}, {0x503fd, 0x5042f}, {0x50531, 0x50556}, {0x510a0, 0x510c5}, + {0x513a0, 0x513f5}, {0x51f08, 0x51f0f}, {0x51f18, 0x51f1d}, {0x51f28, 0x51f2f}, + {0x51f38, 0x51f3f}, {0x51f48, 0x51f4d}, {0x51f68, 0x51f6f}, {0x51fb8, 0x51fbb}, + {0x51fc8, 0x51fcb}, {0x51fd8, 0x51fdb}, {0x51fe8, 0x51fec}, {0x51ff8, 0x51ffb}, + {0x5210b, 0x5210d}, {0x52110, 0x52112}, {0x52119, 0x5211d}, {0x5212a, 0x5212d}, + {0x52130, 0x52133}, {0x52c00, 0x52c2e}, {0x52c62, 0x52c64}, {0x52c6d, 0x52c70}, + {0x52c7e, 0x52c80}, {0x5a7aa, 0x5a7ae}, {0x5a7b0, 0x5a7b4}, {0x5ff21, 0x5ff3a}, + {0x60041, 0x6005a}, {0x600c0, 0x600d6}, {0x600d8, 0x600de}, {0x60189, 0x6018b}, + {0x6018e, 0x60191}, {0x60196, 0x60198}, {0x601b1, 0x601b3}, {0x601f6, 0x601f8}, + {0x60243, 0x60246}, {0x60388, 0x6038a}, {0x60391, 0x603a1}, {0x603a3, 0x603ab}, + {0x603d2, 0x603d4}, {0x603fd, 0x6042f}, {0x60531, 0x60556}, {0x610a0, 0x610c5}, + {0x613a0, 0x613f5}, {0x61f08, 0x61f0f}, {0x61f18, 0x61f1d}, {0x61f28, 0x61f2f}, + {0x61f38, 0x61f3f}, {0x61f48, 0x61f4d}, {0x61f68, 0x61f6f}, {0x61fb8, 0x61fbb}, + {0x61fc8, 0x61fcb}, {0x61fd8, 0x61fdb}, {0x61fe8, 0x61fec}, {0x61ff8, 0x61ffb}, + {0x6210b, 0x6210d}, {0x62110, 0x62112}, {0x62119, 0x6211d}, {0x6212a, 0x6212d}, + {0x62130, 0x62133}, {0x62c00, 0x62c2e}, {0x62c62, 0x62c64}, {0x62c6d, 0x62c70}, + {0x62c7e, 0x62c80}, {0x6a7aa, 0x6a7ae}, {0x6a7b0, 0x6a7b4}, {0x6ff21, 0x6ff3a}, + {0x70041, 0x7005a}, {0x700c0, 0x700d6}, {0x700d8, 0x700de}, {0x70189, 0x7018b}, + {0x7018e, 0x70191}, {0x70196, 0x70198}, {0x701b1, 0x701b3}, {0x701f6, 0x701f8}, + {0x70243, 0x70246}, {0x70388, 0x7038a}, {0x70391, 0x703a1}, {0x703a3, 0x703ab}, + {0x703d2, 0x703d4}, {0x703fd, 0x7042f}, {0x70531, 0x70556}, {0x710a0, 0x710c5}, + {0x713a0, 0x713f5}, {0x71f08, 0x71f0f}, {0x71f18, 0x71f1d}, {0x71f28, 0x71f2f}, + {0x71f38, 0x71f3f}, {0x71f48, 0x71f4d}, {0x71f68, 0x71f6f}, {0x71fb8, 0x71fbb}, + {0x71fc8, 0x71fcb}, {0x71fd8, 0x71fdb}, {0x71fe8, 0x71fec}, {0x71ff8, 0x71ffb}, + {0x7210b, 0x7210d}, {0x72110, 0x72112}, {0x72119, 0x7211d}, {0x7212a, 0x7212d}, + {0x72130, 0x72133}, {0x72c00, 0x72c2e}, {0x72c62, 0x72c64}, {0x72c6d, 0x72c70}, + {0x72c7e, 0x72c80}, {0x7a7aa, 0x7a7ae}, {0x7a7b0, 0x7a7b4}, {0x7ff21, 0x7ff3a}, + {0x80041, 0x8005a}, {0x800c0, 0x800d6}, {0x800d8, 0x800de}, {0x80189, 0x8018b}, + {0x8018e, 0x80191}, {0x80196, 0x80198}, {0x801b1, 0x801b3}, {0x801f6, 0x801f8}, + {0x80243, 0x80246}, {0x80388, 0x8038a}, {0x80391, 0x803a1}, {0x803a3, 0x803ab}, + {0x803d2, 0x803d4}, {0x803fd, 0x8042f}, {0x80531, 0x80556}, {0x810a0, 0x810c5}, + {0x813a0, 0x813f5}, {0x81f08, 0x81f0f}, {0x81f18, 0x81f1d}, {0x81f28, 0x81f2f}, + {0x81f38, 0x81f3f}, {0x81f48, 0x81f4d}, {0x81f68, 0x81f6f}, {0x81fb8, 0x81fbb}, + {0x81fc8, 0x81fcb}, {0x81fd8, 0x81fdb}, {0x81fe8, 0x81fec}, {0x81ff8, 0x81ffb}, + {0x8210b, 0x8210d}, {0x82110, 0x82112}, {0x82119, 0x8211d}, {0x8212a, 0x8212d}, + {0x82130, 0x82133}, {0x82c00, 0x82c2e}, {0x82c62, 0x82c64}, {0x82c6d, 0x82c70}, + {0x82c7e, 0x82c80}, {0x8a7aa, 0x8a7ae}, {0x8a7b0, 0x8a7b4}, {0x8ff21, 0x8ff3a}, + {0x90041, 0x9005a}, {0x900c0, 0x900d6}, {0x900d8, 0x900de}, {0x90189, 0x9018b}, + {0x9018e, 0x90191}, {0x90196, 0x90198}, {0x901b1, 0x901b3}, {0x901f6, 0x901f8}, + {0x90243, 0x90246}, {0x90388, 0x9038a}, {0x90391, 0x903a1}, {0x903a3, 0x903ab}, + {0x903d2, 0x903d4}, {0x903fd, 0x9042f}, {0x90531, 0x90556}, {0x910a0, 0x910c5}, + {0x913a0, 0x913f5}, {0x91f08, 0x91f0f}, {0x91f18, 0x91f1d}, {0x91f28, 0x91f2f}, + {0x91f38, 0x91f3f}, {0x91f48, 0x91f4d}, {0x91f68, 0x91f6f}, {0x91fb8, 0x91fbb}, + {0x91fc8, 0x91fcb}, {0x91fd8, 0x91fdb}, {0x91fe8, 0x91fec}, {0x91ff8, 0x91ffb}, + {0x9210b, 0x9210d}, {0x92110, 0x92112}, {0x92119, 0x9211d}, {0x9212a, 0x9212d}, + {0x92130, 0x92133}, {0x92c00, 0x92c2e}, {0x92c62, 0x92c64}, {0x92c6d, 0x92c70}, + {0x92c7e, 0x92c80}, {0x9a7aa, 0x9a7ae}, {0x9a7b0, 0x9a7b4}, {0x9ff21, 0x9ff3a}, + {0xa0041, 0xa005a}, {0xa00c0, 0xa00d6}, {0xa00d8, 0xa00de}, {0xa0189, 0xa018b}, + {0xa018e, 0xa0191}, {0xa0196, 0xa0198}, {0xa01b1, 0xa01b3}, {0xa01f6, 0xa01f8}, + {0xa0243, 0xa0246}, {0xa0388, 0xa038a}, {0xa0391, 0xa03a1}, {0xa03a3, 0xa03ab}, + {0xa03d2, 0xa03d4}, {0xa03fd, 0xa042f}, {0xa0531, 0xa0556}, {0xa10a0, 0xa10c5}, + {0xa13a0, 0xa13f5}, {0xa1f08, 0xa1f0f}, {0xa1f18, 0xa1f1d}, {0xa1f28, 0xa1f2f}, + {0xa1f38, 0xa1f3f}, {0xa1f48, 0xa1f4d}, {0xa1f68, 0xa1f6f}, {0xa1fb8, 0xa1fbb}, + {0xa1fc8, 0xa1fcb}, {0xa1fd8, 0xa1fdb}, {0xa1fe8, 0xa1fec}, {0xa1ff8, 0xa1ffb}, + {0xa210b, 0xa210d}, {0xa2110, 0xa2112}, {0xa2119, 0xa211d}, {0xa212a, 0xa212d}, + {0xa2130, 0xa2133}, {0xa2c00, 0xa2c2e}, {0xa2c62, 0xa2c64}, {0xa2c6d, 0xa2c70}, + {0xa2c7e, 0xa2c80}, {0xaa7aa, 0xaa7ae}, {0xaa7b0, 0xaa7b4}, {0xaff21, 0xaff3a}, + {0xb0041, 0xb005a}, {0xb00c0, 0xb00d6}, {0xb00d8, 0xb00de}, {0xb0189, 0xb018b}, + {0xb018e, 0xb0191}, {0xb0196, 0xb0198}, {0xb01b1, 0xb01b3}, {0xb01f6, 0xb01f8}, + {0xb0243, 0xb0246}, {0xb0388, 0xb038a}, {0xb0391, 0xb03a1}, {0xb03a3, 0xb03ab}, + {0xb03d2, 0xb03d4}, {0xb03fd, 0xb042f}, {0xb0531, 0xb0556}, {0xb10a0, 0xb10c5}, + {0xb13a0, 0xb13f5}, {0xb1f08, 0xb1f0f}, {0xb1f18, 0xb1f1d}, {0xb1f28, 0xb1f2f}, + {0xb1f38, 0xb1f3f}, {0xb1f48, 0xb1f4d}, {0xb1f68, 0xb1f6f}, {0xb1fb8, 0xb1fbb}, + {0xb1fc8, 0xb1fcb}, {0xb1fd8, 0xb1fdb}, {0xb1fe8, 0xb1fec}, {0xb1ff8, 0xb1ffb}, + {0xb210b, 0xb210d}, {0xb2110, 0xb2112}, {0xb2119, 0xb211d}, {0xb212a, 0xb212d}, + {0xb2130, 0xb2133}, {0xb2c00, 0xb2c2e}, {0xb2c62, 0xb2c64}, {0xb2c6d, 0xb2c70}, + {0xb2c7e, 0xb2c80}, {0xba7aa, 0xba7ae}, {0xba7b0, 0xba7b4}, {0xbff21, 0xbff3a}, + {0xc0041, 0xc005a}, {0xc00c0, 0xc00d6}, {0xc00d8, 0xc00de}, {0xc0189, 0xc018b}, + {0xc018e, 0xc0191}, {0xc0196, 0xc0198}, {0xc01b1, 0xc01b3}, {0xc01f6, 0xc01f8}, + {0xc0243, 0xc0246}, {0xc0388, 0xc038a}, {0xc0391, 0xc03a1}, {0xc03a3, 0xc03ab}, + {0xc03d2, 0xc03d4}, {0xc03fd, 0xc042f}, {0xc0531, 0xc0556}, {0xc10a0, 0xc10c5}, + {0xc13a0, 0xc13f5}, {0xc1f08, 0xc1f0f}, {0xc1f18, 0xc1f1d}, {0xc1f28, 0xc1f2f}, + {0xc1f38, 0xc1f3f}, {0xc1f48, 0xc1f4d}, {0xc1f68, 0xc1f6f}, {0xc1fb8, 0xc1fbb}, + {0xc1fc8, 0xc1fcb}, {0xc1fd8, 0xc1fdb}, {0xc1fe8, 0xc1fec}, {0xc1ff8, 0xc1ffb}, + {0xc210b, 0xc210d}, {0xc2110, 0xc2112}, {0xc2119, 0xc211d}, {0xc212a, 0xc212d}, + {0xc2130, 0xc2133}, {0xc2c00, 0xc2c2e}, {0xc2c62, 0xc2c64}, {0xc2c6d, 0xc2c70}, + {0xc2c7e, 0xc2c80}, {0xca7aa, 0xca7ae}, {0xca7b0, 0xca7b4}, {0xcff21, 0xcff3a}, + {0xd0041, 0xd005a}, {0xd00c0, 0xd00d6}, {0xd00d8, 0xd00de}, {0xd0189, 0xd018b}, + {0xd018e, 0xd0191}, {0xd0196, 0xd0198}, {0xd01b1, 0xd01b3}, {0xd01f6, 0xd01f8}, + {0xd0243, 0xd0246}, {0xd0388, 0xd038a}, {0xd0391, 0xd03a1}, {0xd03a3, 0xd03ab}, + {0xd03d2, 0xd03d4}, {0xd03fd, 0xd042f}, {0xd0531, 0xd0556}, {0xd10a0, 0xd10c5}, + {0xd13a0, 0xd13f5}, {0xd1f08, 0xd1f0f}, {0xd1f18, 0xd1f1d}, {0xd1f28, 0xd1f2f}, + {0xd1f38, 0xd1f3f}, {0xd1f48, 0xd1f4d}, {0xd1f68, 0xd1f6f}, {0xd1fb8, 0xd1fbb}, + {0xd1fc8, 0xd1fcb}, {0xd1fd8, 0xd1fdb}, {0xd1fe8, 0xd1fec}, {0xd1ff8, 0xd1ffb}, + {0xd210b, 0xd210d}, {0xd2110, 0xd2112}, {0xd2119, 0xd211d}, {0xd212a, 0xd212d}, + {0xd2130, 0xd2133}, {0xd2c00, 0xd2c2e}, {0xd2c62, 0xd2c64}, {0xd2c6d, 0xd2c70}, + {0xd2c7e, 0xd2c80}, {0xda7aa, 0xda7ae}, {0xda7b0, 0xda7b4}, {0xdff21, 0xdff3a}, + {0xe0041, 0xe005a}, {0xe00c0, 0xe00d6}, {0xe00d8, 0xe00de}, {0xe0189, 0xe018b}, + {0xe018e, 0xe0191}, {0xe0196, 0xe0198}, {0xe01b1, 0xe01b3}, {0xe01f6, 0xe01f8}, + {0xe0243, 0xe0246}, {0xe0388, 0xe038a}, {0xe0391, 0xe03a1}, {0xe03a3, 0xe03ab}, + {0xe03d2, 0xe03d4}, {0xe03fd, 0xe042f}, {0xe0531, 0xe0556}, {0xe10a0, 0xe10c5}, + {0xe13a0, 0xe13f5}, {0xe1f08, 0xe1f0f}, {0xe1f18, 0xe1f1d}, {0xe1f28, 0xe1f2f}, + {0xe1f38, 0xe1f3f}, {0xe1f48, 0xe1f4d}, {0xe1f68, 0xe1f6f}, {0xe1fb8, 0xe1fbb}, + {0xe1fc8, 0xe1fcb}, {0xe1fd8, 0xe1fdb}, {0xe1fe8, 0xe1fec}, {0xe1ff8, 0xe1ffb}, + {0xe210b, 0xe210d}, {0xe2110, 0xe2112}, {0xe2119, 0xe211d}, {0xe212a, 0xe212d}, + {0xe2130, 0xe2133}, {0xe2c00, 0xe2c2e}, {0xe2c62, 0xe2c64}, {0xe2c6d, 0xe2c70}, + {0xe2c7e, 0xe2c80}, {0xea7aa, 0xea7ae}, {0xea7b0, 0xea7b4}, {0xeff21, 0xeff3a}, + {0xf0041, 0xf005a}, {0xf00c0, 0xf00d6}, {0xf00d8, 0xf00de}, {0xf0189, 0xf018b}, + {0xf018e, 0xf0191}, {0xf0196, 0xf0198}, {0xf01b1, 0xf01b3}, {0xf01f6, 0xf01f8}, + {0xf0243, 0xf0246}, {0xf0388, 0xf038a}, {0xf0391, 0xf03a1}, {0xf03a3, 0xf03ab}, + {0xf03d2, 0xf03d4}, {0xf03fd, 0xf042f}, {0xf0531, 0xf0556}, {0xf10a0, 0xf10c5}, + {0xf13a0, 0xf13f5}, {0xf1f08, 0xf1f0f}, {0xf1f18, 0xf1f1d}, {0xf1f28, 0xf1f2f}, + {0xf1f38, 0xf1f3f}, {0xf1f48, 0xf1f4d}, {0xf1f68, 0xf1f6f}, {0xf1fb8, 0xf1fbb}, + {0xf1fc8, 0xf1fcb}, {0xf1fd8, 0xf1fdb}, {0xf1fe8, 0xf1fec}, {0xf1ff8, 0xf1ffb}, + {0xf210b, 0xf210d}, {0xf2110, 0xf2112}, {0xf2119, 0xf211d}, {0xf212a, 0xf212d}, + {0xf2130, 0xf2133}, {0xf2c00, 0xf2c2e}, {0xf2c62, 0xf2c64}, {0xf2c6d, 0xf2c70}, + {0xf2c7e, 0xf2c80}, {0xfa7aa, 0xfa7ae}, {0xfa7b0, 0xfa7b4}, {0xfff21, 0xfff3a}, + {0x100041, 0x10005a}, {0x1000c0, 0x1000d6}, {0x1000d8, 0x1000de}, {0x100189, 0x10018b}, + {0x10018e, 0x100191}, {0x100196, 0x100198}, {0x1001b1, 0x1001b3}, {0x1001f6, 0x1001f8}, + {0x100243, 0x100246}, {0x100388, 0x10038a}, {0x100391, 0x1003a1}, {0x1003a3, 0x1003ab}, + {0x1003d2, 0x1003d4}, {0x1003fd, 0x10042f}, {0x100531, 0x100556}, {0x1010a0, 0x1010c5}, + {0x1013a0, 0x1013f5}, {0x101f08, 0x101f0f}, {0x101f18, 0x101f1d}, {0x101f28, 0x101f2f}, + {0x101f38, 0x101f3f}, {0x101f48, 0x101f4d}, {0x101f68, 0x101f6f}, {0x101fb8, 0x101fbb}, + {0x101fc8, 0x101fcb}, {0x101fd8, 0x101fdb}, {0x101fe8, 0x101fec}, {0x101ff8, 0x101ffb}, + {0x10210b, 0x10210d}, {0x102110, 0x102112}, {0x102119, 0x10211d}, {0x10212a, 0x10212d}, + {0x102130, 0x102133}, {0x102c00, 0x102c2e}, {0x102c62, 0x102c64}, {0x102c6d, 0x102c70}, + {0x102c7e, 0x102c80}, {0x10a7aa, 0x10a7ae}, {0x10a7b0, 0x10a7b4}, {0x10ff21, 0x10ff3a} #endif }; @@ -598,8 +3856,1014 @@ static const chr upperCharTable[] = { 0xa782, 0xa784, 0xa786, 0xa78b, 0xa78d, 0xa790, 0xa792, 0xa796, 0xa798, 0xa79a, 0xa79c, 0xa79e, 0xa7a0, 0xa7a2, 0xa7a4, 0xa7a6, 0xa7a8, 0xa7b6 #if TCL_UTF_MAX > 4 - ,0x1d49c, 0x1d49e, 0x1d49f, 0x1d4a2, 0x1d4a5, 0x1d4a6, 0x1d504, 0x1d505, 0x1d538, - 0x1d539, 0x1d546, 0x1d7ca + ,0x10100, 0x10102, 0x10104, 0x10106, 0x10108, 0x1010a, 0x1010c, 0x1010e, 0x10110, + 0x10112, 0x10114, 0x10116, 0x10118, 0x1011a, 0x1011c, 0x1011e, 0x10120, 0x10122, + 0x10124, 0x10126, 0x10128, 0x1012a, 0x1012c, 0x1012e, 0x10130, 0x10132, 0x10134, + 0x10136, 0x10139, 0x1013b, 0x1013d, 0x1013f, 0x10141, 0x10143, 0x10145, 0x10147, + 0x1014a, 0x1014c, 0x1014e, 0x10150, 0x10152, 0x10154, 0x10156, 0x10158, 0x1015a, + 0x1015c, 0x1015e, 0x10160, 0x10162, 0x10164, 0x10166, 0x10168, 0x1016a, 0x1016c, + 0x1016e, 0x10170, 0x10172, 0x10174, 0x10176, 0x10178, 0x10179, 0x1017b, 0x1017d, + 0x10181, 0x10182, 0x10184, 0x10186, 0x10187, 0x10193, 0x10194, 0x1019c, 0x1019d, + 0x1019f, 0x101a0, 0x101a2, 0x101a4, 0x101a6, 0x101a7, 0x101a9, 0x101ac, 0x101ae, + 0x101af, 0x101b5, 0x101b7, 0x101b8, 0x101bc, 0x101c4, 0x101c7, 0x101ca, 0x101cd, + 0x101cf, 0x101d1, 0x101d3, 0x101d5, 0x101d7, 0x101d9, 0x101db, 0x101de, 0x101e0, + 0x101e2, 0x101e4, 0x101e6, 0x101e8, 0x101ea, 0x101ec, 0x101ee, 0x101f1, 0x101f4, + 0x101fa, 0x101fc, 0x101fe, 0x10200, 0x10202, 0x10204, 0x10206, 0x10208, 0x1020a, + 0x1020c, 0x1020e, 0x10210, 0x10212, 0x10214, 0x10216, 0x10218, 0x1021a, 0x1021c, + 0x1021e, 0x10220, 0x10222, 0x10224, 0x10226, 0x10228, 0x1022a, 0x1022c, 0x1022e, + 0x10230, 0x10232, 0x1023a, 0x1023b, 0x1023d, 0x1023e, 0x10241, 0x10248, 0x1024a, + 0x1024c, 0x1024e, 0x10370, 0x10372, 0x10376, 0x1037f, 0x10386, 0x1038c, 0x1038e, + 0x1038f, 0x103cf, 0x103d8, 0x103da, 0x103dc, 0x103de, 0x103e0, 0x103e2, 0x103e4, + 0x103e6, 0x103e8, 0x103ea, 0x103ec, 0x103ee, 0x103f4, 0x103f7, 0x103f9, 0x103fa, + 0x10460, 0x10462, 0x10464, 0x10466, 0x10468, 0x1046a, 0x1046c, 0x1046e, 0x10470, + 0x10472, 0x10474, 0x10476, 0x10478, 0x1047a, 0x1047c, 0x1047e, 0x10480, 0x1048a, + 0x1048c, 0x1048e, 0x10490, 0x10492, 0x10494, 0x10496, 0x10498, 0x1049a, 0x1049c, + 0x1049e, 0x104a0, 0x104a2, 0x104a4, 0x104a6, 0x104a8, 0x104aa, 0x104ac, 0x104ae, + 0x104b0, 0x104b2, 0x104b4, 0x104b6, 0x104b8, 0x104ba, 0x104bc, 0x104be, 0x104c0, + 0x104c1, 0x104c3, 0x104c5, 0x104c7, 0x104c9, 0x104cb, 0x104cd, 0x104d0, 0x104d2, + 0x104d4, 0x104d6, 0x104d8, 0x104da, 0x104dc, 0x104de, 0x104e0, 0x104e2, 0x104e4, + 0x104e6, 0x104e8, 0x104ea, 0x104ec, 0x104ee, 0x104f0, 0x104f2, 0x104f4, 0x104f6, + 0x104f8, 0x104fa, 0x104fc, 0x104fe, 0x10500, 0x10502, 0x10504, 0x10506, 0x10508, + 0x1050a, 0x1050c, 0x1050e, 0x10510, 0x10512, 0x10514, 0x10516, 0x10518, 0x1051a, + 0x1051c, 0x1051e, 0x10520, 0x10522, 0x10524, 0x10526, 0x10528, 0x1052a, 0x1052c, + 0x1052e, 0x110c7, 0x110cd, 0x11e00, 0x11e02, 0x11e04, 0x11e06, 0x11e08, 0x11e0a, + 0x11e0c, 0x11e0e, 0x11e10, 0x11e12, 0x11e14, 0x11e16, 0x11e18, 0x11e1a, 0x11e1c, + 0x11e1e, 0x11e20, 0x11e22, 0x11e24, 0x11e26, 0x11e28, 0x11e2a, 0x11e2c, 0x11e2e, + 0x11e30, 0x11e32, 0x11e34, 0x11e36, 0x11e38, 0x11e3a, 0x11e3c, 0x11e3e, 0x11e40, + 0x11e42, 0x11e44, 0x11e46, 0x11e48, 0x11e4a, 0x11e4c, 0x11e4e, 0x11e50, 0x11e52, + 0x11e54, 0x11e56, 0x11e58, 0x11e5a, 0x11e5c, 0x11e5e, 0x11e60, 0x11e62, 0x11e64, + 0x11e66, 0x11e68, 0x11e6a, 0x11e6c, 0x11e6e, 0x11e70, 0x11e72, 0x11e74, 0x11e76, + 0x11e78, 0x11e7a, 0x11e7c, 0x11e7e, 0x11e80, 0x11e82, 0x11e84, 0x11e86, 0x11e88, + 0x11e8a, 0x11e8c, 0x11e8e, 0x11e90, 0x11e92, 0x11e94, 0x11e9e, 0x11ea0, 0x11ea2, + 0x11ea4, 0x11ea6, 0x11ea8, 0x11eaa, 0x11eac, 0x11eae, 0x11eb0, 0x11eb2, 0x11eb4, + 0x11eb6, 0x11eb8, 0x11eba, 0x11ebc, 0x11ebe, 0x11ec0, 0x11ec2, 0x11ec4, 0x11ec6, + 0x11ec8, 0x11eca, 0x11ecc, 0x11ece, 0x11ed0, 0x11ed2, 0x11ed4, 0x11ed6, 0x11ed8, + 0x11eda, 0x11edc, 0x11ede, 0x11ee0, 0x11ee2, 0x11ee4, 0x11ee6, 0x11ee8, 0x11eea, + 0x11eec, 0x11eee, 0x11ef0, 0x11ef2, 0x11ef4, 0x11ef6, 0x11ef8, 0x11efa, 0x11efc, + 0x11efe, 0x11f59, 0x11f5b, 0x11f5d, 0x11f5f, 0x12102, 0x12107, 0x12115, 0x12124, + 0x12126, 0x12128, 0x1213e, 0x1213f, 0x12145, 0x12183, 0x12c60, 0x12c67, 0x12c69, + 0x12c6b, 0x12c72, 0x12c75, 0x12c82, 0x12c84, 0x12c86, 0x12c88, 0x12c8a, 0x12c8c, + 0x12c8e, 0x12c90, 0x12c92, 0x12c94, 0x12c96, 0x12c98, 0x12c9a, 0x12c9c, 0x12c9e, + 0x12ca0, 0x12ca2, 0x12ca4, 0x12ca6, 0x12ca8, 0x12caa, 0x12cac, 0x12cae, 0x12cb0, + 0x12cb2, 0x12cb4, 0x12cb6, 0x12cb8, 0x12cba, 0x12cbc, 0x12cbe, 0x12cc0, 0x12cc2, + 0x12cc4, 0x12cc6, 0x12cc8, 0x12cca, 0x12ccc, 0x12cce, 0x12cd0, 0x12cd2, 0x12cd4, + 0x12cd6, 0x12cd8, 0x12cda, 0x12cdc, 0x12cde, 0x12ce0, 0x12ce2, 0x12ceb, 0x12ced, + 0x12cf2, 0x1a640, 0x1a642, 0x1a644, 0x1a646, 0x1a648, 0x1a64a, 0x1a64c, 0x1a64e, + 0x1a650, 0x1a652, 0x1a654, 0x1a656, 0x1a658, 0x1a65a, 0x1a65c, 0x1a65e, 0x1a660, + 0x1a662, 0x1a664, 0x1a666, 0x1a668, 0x1a66a, 0x1a66c, 0x1a680, 0x1a682, 0x1a684, + 0x1a686, 0x1a688, 0x1a68a, 0x1a68c, 0x1a68e, 0x1a690, 0x1a692, 0x1a694, 0x1a696, + 0x1a698, 0x1a69a, 0x1a722, 0x1a724, 0x1a726, 0x1a728, 0x1a72a, 0x1a72c, 0x1a72e, + 0x1a732, 0x1a734, 0x1a736, 0x1a738, 0x1a73a, 0x1a73c, 0x1a73e, 0x1a740, 0x1a742, + 0x1a744, 0x1a746, 0x1a748, 0x1a74a, 0x1a74c, 0x1a74e, 0x1a750, 0x1a752, 0x1a754, + 0x1a756, 0x1a758, 0x1a75a, 0x1a75c, 0x1a75e, 0x1a760, 0x1a762, 0x1a764, 0x1a766, + 0x1a768, 0x1a76a, 0x1a76c, 0x1a76e, 0x1a779, 0x1a77b, 0x1a77d, 0x1a77e, 0x1a780, + 0x1a782, 0x1a784, 0x1a786, 0x1a78b, 0x1a78d, 0x1a790, 0x1a792, 0x1a796, 0x1a798, + 0x1a79a, 0x1a79c, 0x1a79e, 0x1a7a0, 0x1a7a2, 0x1a7a4, 0x1a7a6, 0x1a7a8, 0x1a7b6, + 0x20100, 0x20102, 0x20104, 0x20106, 0x20108, 0x2010a, 0x2010c, 0x2010e, 0x20110, + 0x20112, 0x20114, 0x20116, 0x20118, 0x2011a, 0x2011c, 0x2011e, 0x20120, 0x20122, + 0x20124, 0x20126, 0x20128, 0x2012a, 0x2012c, 0x2012e, 0x20130, 0x20132, 0x20134, + 0x20136, 0x20139, 0x2013b, 0x2013d, 0x2013f, 0x20141, 0x20143, 0x20145, 0x20147, + 0x2014a, 0x2014c, 0x2014e, 0x20150, 0x20152, 0x20154, 0x20156, 0x20158, 0x2015a, + 0x2015c, 0x2015e, 0x20160, 0x20162, 0x20164, 0x20166, 0x20168, 0x2016a, 0x2016c, + 0x2016e, 0x20170, 0x20172, 0x20174, 0x20176, 0x20178, 0x20179, 0x2017b, 0x2017d, + 0x20181, 0x20182, 0x20184, 0x20186, 0x20187, 0x20193, 0x20194, 0x2019c, 0x2019d, + 0x2019f, 0x201a0, 0x201a2, 0x201a4, 0x201a6, 0x201a7, 0x201a9, 0x201ac, 0x201ae, + 0x201af, 0x201b5, 0x201b7, 0x201b8, 0x201bc, 0x201c4, 0x201c7, 0x201ca, 0x201cd, + 0x201cf, 0x201d1, 0x201d3, 0x201d5, 0x201d7, 0x201d9, 0x201db, 0x201de, 0x201e0, + 0x201e2, 0x201e4, 0x201e6, 0x201e8, 0x201ea, 0x201ec, 0x201ee, 0x201f1, 0x201f4, + 0x201fa, 0x201fc, 0x201fe, 0x20200, 0x20202, 0x20204, 0x20206, 0x20208, 0x2020a, + 0x2020c, 0x2020e, 0x20210, 0x20212, 0x20214, 0x20216, 0x20218, 0x2021a, 0x2021c, + 0x2021e, 0x20220, 0x20222, 0x20224, 0x20226, 0x20228, 0x2022a, 0x2022c, 0x2022e, + 0x20230, 0x20232, 0x2023a, 0x2023b, 0x2023d, 0x2023e, 0x20241, 0x20248, 0x2024a, + 0x2024c, 0x2024e, 0x20370, 0x20372, 0x20376, 0x2037f, 0x20386, 0x2038c, 0x2038e, + 0x2038f, 0x203cf, 0x203d8, 0x203da, 0x203dc, 0x203de, 0x203e0, 0x203e2, 0x203e4, + 0x203e6, 0x203e8, 0x203ea, 0x203ec, 0x203ee, 0x203f4, 0x203f7, 0x203f9, 0x203fa, + 0x20460, 0x20462, 0x20464, 0x20466, 0x20468, 0x2046a, 0x2046c, 0x2046e, 0x20470, + 0x20472, 0x20474, 0x20476, 0x20478, 0x2047a, 0x2047c, 0x2047e, 0x20480, 0x2048a, + 0x2048c, 0x2048e, 0x20490, 0x20492, 0x20494, 0x20496, 0x20498, 0x2049a, 0x2049c, + 0x2049e, 0x204a0, 0x204a2, 0x204a4, 0x204a6, 0x204a8, 0x204aa, 0x204ac, 0x204ae, + 0x204b0, 0x204b2, 0x204b4, 0x204b6, 0x204b8, 0x204ba, 0x204bc, 0x204be, 0x204c0, + 0x204c1, 0x204c3, 0x204c5, 0x204c7, 0x204c9, 0x204cb, 0x204cd, 0x204d0, 0x204d2, + 0x204d4, 0x204d6, 0x204d8, 0x204da, 0x204dc, 0x204de, 0x204e0, 0x204e2, 0x204e4, + 0x204e6, 0x204e8, 0x204ea, 0x204ec, 0x204ee, 0x204f0, 0x204f2, 0x204f4, 0x204f6, + 0x204f8, 0x204fa, 0x204fc, 0x204fe, 0x20500, 0x20502, 0x20504, 0x20506, 0x20508, + 0x2050a, 0x2050c, 0x2050e, 0x20510, 0x20512, 0x20514, 0x20516, 0x20518, 0x2051a, + 0x2051c, 0x2051e, 0x20520, 0x20522, 0x20524, 0x20526, 0x20528, 0x2052a, 0x2052c, + 0x2052e, 0x210c7, 0x210cd, 0x21e00, 0x21e02, 0x21e04, 0x21e06, 0x21e08, 0x21e0a, + 0x21e0c, 0x21e0e, 0x21e10, 0x21e12, 0x21e14, 0x21e16, 0x21e18, 0x21e1a, 0x21e1c, + 0x21e1e, 0x21e20, 0x21e22, 0x21e24, 0x21e26, 0x21e28, 0x21e2a, 0x21e2c, 0x21e2e, + 0x21e30, 0x21e32, 0x21e34, 0x21e36, 0x21e38, 0x21e3a, 0x21e3c, 0x21e3e, 0x21e40, + 0x21e42, 0x21e44, 0x21e46, 0x21e48, 0x21e4a, 0x21e4c, 0x21e4e, 0x21e50, 0x21e52, + 0x21e54, 0x21e56, 0x21e58, 0x21e5a, 0x21e5c, 0x21e5e, 0x21e60, 0x21e62, 0x21e64, + 0x21e66, 0x21e68, 0x21e6a, 0x21e6c, 0x21e6e, 0x21e70, 0x21e72, 0x21e74, 0x21e76, + 0x21e78, 0x21e7a, 0x21e7c, 0x21e7e, 0x21e80, 0x21e82, 0x21e84, 0x21e86, 0x21e88, + 0x21e8a, 0x21e8c, 0x21e8e, 0x21e90, 0x21e92, 0x21e94, 0x21e9e, 0x21ea0, 0x21ea2, + 0x21ea4, 0x21ea6, 0x21ea8, 0x21eaa, 0x21eac, 0x21eae, 0x21eb0, 0x21eb2, 0x21eb4, + 0x21eb6, 0x21eb8, 0x21eba, 0x21ebc, 0x21ebe, 0x21ec0, 0x21ec2, 0x21ec4, 0x21ec6, + 0x21ec8, 0x21eca, 0x21ecc, 0x21ece, 0x21ed0, 0x21ed2, 0x21ed4, 0x21ed6, 0x21ed8, + 0x21eda, 0x21edc, 0x21ede, 0x21ee0, 0x21ee2, 0x21ee4, 0x21ee6, 0x21ee8, 0x21eea, + 0x21eec, 0x21eee, 0x21ef0, 0x21ef2, 0x21ef4, 0x21ef6, 0x21ef8, 0x21efa, 0x21efc, + 0x21efe, 0x21f59, 0x21f5b, 0x21f5d, 0x21f5f, 0x22102, 0x22107, 0x22115, 0x22124, + 0x22126, 0x22128, 0x2213e, 0x2213f, 0x22145, 0x22183, 0x22c60, 0x22c67, 0x22c69, + 0x22c6b, 0x22c72, 0x22c75, 0x22c82, 0x22c84, 0x22c86, 0x22c88, 0x22c8a, 0x22c8c, + 0x22c8e, 0x22c90, 0x22c92, 0x22c94, 0x22c96, 0x22c98, 0x22c9a, 0x22c9c, 0x22c9e, + 0x22ca0, 0x22ca2, 0x22ca4, 0x22ca6, 0x22ca8, 0x22caa, 0x22cac, 0x22cae, 0x22cb0, + 0x22cb2, 0x22cb4, 0x22cb6, 0x22cb8, 0x22cba, 0x22cbc, 0x22cbe, 0x22cc0, 0x22cc2, + 0x22cc4, 0x22cc6, 0x22cc8, 0x22cca, 0x22ccc, 0x22cce, 0x22cd0, 0x22cd2, 0x22cd4, + 0x22cd6, 0x22cd8, 0x22cda, 0x22cdc, 0x22cde, 0x22ce0, 0x22ce2, 0x22ceb, 0x22ced, + 0x22cf2, 0x2a640, 0x2a642, 0x2a644, 0x2a646, 0x2a648, 0x2a64a, 0x2a64c, 0x2a64e, + 0x2a650, 0x2a652, 0x2a654, 0x2a656, 0x2a658, 0x2a65a, 0x2a65c, 0x2a65e, 0x2a660, + 0x2a662, 0x2a664, 0x2a666, 0x2a668, 0x2a66a, 0x2a66c, 0x2a680, 0x2a682, 0x2a684, + 0x2a686, 0x2a688, 0x2a68a, 0x2a68c, 0x2a68e, 0x2a690, 0x2a692, 0x2a694, 0x2a696, + 0x2a698, 0x2a69a, 0x2a722, 0x2a724, 0x2a726, 0x2a728, 0x2a72a, 0x2a72c, 0x2a72e, + 0x2a732, 0x2a734, 0x2a736, 0x2a738, 0x2a73a, 0x2a73c, 0x2a73e, 0x2a740, 0x2a742, + 0x2a744, 0x2a746, 0x2a748, 0x2a74a, 0x2a74c, 0x2a74e, 0x2a750, 0x2a752, 0x2a754, + 0x2a756, 0x2a758, 0x2a75a, 0x2a75c, 0x2a75e, 0x2a760, 0x2a762, 0x2a764, 0x2a766, + 0x2a768, 0x2a76a, 0x2a76c, 0x2a76e, 0x2a779, 0x2a77b, 0x2a77d, 0x2a77e, 0x2a780, + 0x2a782, 0x2a784, 0x2a786, 0x2a78b, 0x2a78d, 0x2a790, 0x2a792, 0x2a796, 0x2a798, + 0x2a79a, 0x2a79c, 0x2a79e, 0x2a7a0, 0x2a7a2, 0x2a7a4, 0x2a7a6, 0x2a7a8, 0x2a7b6, + 0x30100, 0x30102, 0x30104, 0x30106, 0x30108, 0x3010a, 0x3010c, 0x3010e, 0x30110, + 0x30112, 0x30114, 0x30116, 0x30118, 0x3011a, 0x3011c, 0x3011e, 0x30120, 0x30122, + 0x30124, 0x30126, 0x30128, 0x3012a, 0x3012c, 0x3012e, 0x30130, 0x30132, 0x30134, + 0x30136, 0x30139, 0x3013b, 0x3013d, 0x3013f, 0x30141, 0x30143, 0x30145, 0x30147, + 0x3014a, 0x3014c, 0x3014e, 0x30150, 0x30152, 0x30154, 0x30156, 0x30158, 0x3015a, + 0x3015c, 0x3015e, 0x30160, 0x30162, 0x30164, 0x30166, 0x30168, 0x3016a, 0x3016c, + 0x3016e, 0x30170, 0x30172, 0x30174, 0x30176, 0x30178, 0x30179, 0x3017b, 0x3017d, + 0x30181, 0x30182, 0x30184, 0x30186, 0x30187, 0x30193, 0x30194, 0x3019c, 0x3019d, + 0x3019f, 0x301a0, 0x301a2, 0x301a4, 0x301a6, 0x301a7, 0x301a9, 0x301ac, 0x301ae, + 0x301af, 0x301b5, 0x301b7, 0x301b8, 0x301bc, 0x301c4, 0x301c7, 0x301ca, 0x301cd, + 0x301cf, 0x301d1, 0x301d3, 0x301d5, 0x301d7, 0x301d9, 0x301db, 0x301de, 0x301e0, + 0x301e2, 0x301e4, 0x301e6, 0x301e8, 0x301ea, 0x301ec, 0x301ee, 0x301f1, 0x301f4, + 0x301fa, 0x301fc, 0x301fe, 0x30200, 0x30202, 0x30204, 0x30206, 0x30208, 0x3020a, + 0x3020c, 0x3020e, 0x30210, 0x30212, 0x30214, 0x30216, 0x30218, 0x3021a, 0x3021c, + 0x3021e, 0x30220, 0x30222, 0x30224, 0x30226, 0x30228, 0x3022a, 0x3022c, 0x3022e, + 0x30230, 0x30232, 0x3023a, 0x3023b, 0x3023d, 0x3023e, 0x30241, 0x30248, 0x3024a, + 0x3024c, 0x3024e, 0x30370, 0x30372, 0x30376, 0x3037f, 0x30386, 0x3038c, 0x3038e, + 0x3038f, 0x303cf, 0x303d8, 0x303da, 0x303dc, 0x303de, 0x303e0, 0x303e2, 0x303e4, + 0x303e6, 0x303e8, 0x303ea, 0x303ec, 0x303ee, 0x303f4, 0x303f7, 0x303f9, 0x303fa, + 0x30460, 0x30462, 0x30464, 0x30466, 0x30468, 0x3046a, 0x3046c, 0x3046e, 0x30470, + 0x30472, 0x30474, 0x30476, 0x30478, 0x3047a, 0x3047c, 0x3047e, 0x30480, 0x3048a, + 0x3048c, 0x3048e, 0x30490, 0x30492, 0x30494, 0x30496, 0x30498, 0x3049a, 0x3049c, + 0x3049e, 0x304a0, 0x304a2, 0x304a4, 0x304a6, 0x304a8, 0x304aa, 0x304ac, 0x304ae, + 0x304b0, 0x304b2, 0x304b4, 0x304b6, 0x304b8, 0x304ba, 0x304bc, 0x304be, 0x304c0, + 0x304c1, 0x304c3, 0x304c5, 0x304c7, 0x304c9, 0x304cb, 0x304cd, 0x304d0, 0x304d2, + 0x304d4, 0x304d6, 0x304d8, 0x304da, 0x304dc, 0x304de, 0x304e0, 0x304e2, 0x304e4, + 0x304e6, 0x304e8, 0x304ea, 0x304ec, 0x304ee, 0x304f0, 0x304f2, 0x304f4, 0x304f6, + 0x304f8, 0x304fa, 0x304fc, 0x304fe, 0x30500, 0x30502, 0x30504, 0x30506, 0x30508, + 0x3050a, 0x3050c, 0x3050e, 0x30510, 0x30512, 0x30514, 0x30516, 0x30518, 0x3051a, + 0x3051c, 0x3051e, 0x30520, 0x30522, 0x30524, 0x30526, 0x30528, 0x3052a, 0x3052c, + 0x3052e, 0x310c7, 0x310cd, 0x31e00, 0x31e02, 0x31e04, 0x31e06, 0x31e08, 0x31e0a, + 0x31e0c, 0x31e0e, 0x31e10, 0x31e12, 0x31e14, 0x31e16, 0x31e18, 0x31e1a, 0x31e1c, + 0x31e1e, 0x31e20, 0x31e22, 0x31e24, 0x31e26, 0x31e28, 0x31e2a, 0x31e2c, 0x31e2e, + 0x31e30, 0x31e32, 0x31e34, 0x31e36, 0x31e38, 0x31e3a, 0x31e3c, 0x31e3e, 0x31e40, + 0x31e42, 0x31e44, 0x31e46, 0x31e48, 0x31e4a, 0x31e4c, 0x31e4e, 0x31e50, 0x31e52, + 0x31e54, 0x31e56, 0x31e58, 0x31e5a, 0x31e5c, 0x31e5e, 0x31e60, 0x31e62, 0x31e64, + 0x31e66, 0x31e68, 0x31e6a, 0x31e6c, 0x31e6e, 0x31e70, 0x31e72, 0x31e74, 0x31e76, + 0x31e78, 0x31e7a, 0x31e7c, 0x31e7e, 0x31e80, 0x31e82, 0x31e84, 0x31e86, 0x31e88, + 0x31e8a, 0x31e8c, 0x31e8e, 0x31e90, 0x31e92, 0x31e94, 0x31e9e, 0x31ea0, 0x31ea2, + 0x31ea4, 0x31ea6, 0x31ea8, 0x31eaa, 0x31eac, 0x31eae, 0x31eb0, 0x31eb2, 0x31eb4, + 0x31eb6, 0x31eb8, 0x31eba, 0x31ebc, 0x31ebe, 0x31ec0, 0x31ec2, 0x31ec4, 0x31ec6, + 0x31ec8, 0x31eca, 0x31ecc, 0x31ece, 0x31ed0, 0x31ed2, 0x31ed4, 0x31ed6, 0x31ed8, + 0x31eda, 0x31edc, 0x31ede, 0x31ee0, 0x31ee2, 0x31ee4, 0x31ee6, 0x31ee8, 0x31eea, + 0x31eec, 0x31eee, 0x31ef0, 0x31ef2, 0x31ef4, 0x31ef6, 0x31ef8, 0x31efa, 0x31efc, + 0x31efe, 0x31f59, 0x31f5b, 0x31f5d, 0x31f5f, 0x32102, 0x32107, 0x32115, 0x32124, + 0x32126, 0x32128, 0x3213e, 0x3213f, 0x32145, 0x32183, 0x32c60, 0x32c67, 0x32c69, + 0x32c6b, 0x32c72, 0x32c75, 0x32c82, 0x32c84, 0x32c86, 0x32c88, 0x32c8a, 0x32c8c, + 0x32c8e, 0x32c90, 0x32c92, 0x32c94, 0x32c96, 0x32c98, 0x32c9a, 0x32c9c, 0x32c9e, + 0x32ca0, 0x32ca2, 0x32ca4, 0x32ca6, 0x32ca8, 0x32caa, 0x32cac, 0x32cae, 0x32cb0, + 0x32cb2, 0x32cb4, 0x32cb6, 0x32cb8, 0x32cba, 0x32cbc, 0x32cbe, 0x32cc0, 0x32cc2, + 0x32cc4, 0x32cc6, 0x32cc8, 0x32cca, 0x32ccc, 0x32cce, 0x32cd0, 0x32cd2, 0x32cd4, + 0x32cd6, 0x32cd8, 0x32cda, 0x32cdc, 0x32cde, 0x32ce0, 0x32ce2, 0x32ceb, 0x32ced, + 0x32cf2, 0x3a640, 0x3a642, 0x3a644, 0x3a646, 0x3a648, 0x3a64a, 0x3a64c, 0x3a64e, + 0x3a650, 0x3a652, 0x3a654, 0x3a656, 0x3a658, 0x3a65a, 0x3a65c, 0x3a65e, 0x3a660, + 0x3a662, 0x3a664, 0x3a666, 0x3a668, 0x3a66a, 0x3a66c, 0x3a680, 0x3a682, 0x3a684, + 0x3a686, 0x3a688, 0x3a68a, 0x3a68c, 0x3a68e, 0x3a690, 0x3a692, 0x3a694, 0x3a696, + 0x3a698, 0x3a69a, 0x3a722, 0x3a724, 0x3a726, 0x3a728, 0x3a72a, 0x3a72c, 0x3a72e, + 0x3a732, 0x3a734, 0x3a736, 0x3a738, 0x3a73a, 0x3a73c, 0x3a73e, 0x3a740, 0x3a742, + 0x3a744, 0x3a746, 0x3a748, 0x3a74a, 0x3a74c, 0x3a74e, 0x3a750, 0x3a752, 0x3a754, + 0x3a756, 0x3a758, 0x3a75a, 0x3a75c, 0x3a75e, 0x3a760, 0x3a762, 0x3a764, 0x3a766, + 0x3a768, 0x3a76a, 0x3a76c, 0x3a76e, 0x3a779, 0x3a77b, 0x3a77d, 0x3a77e, 0x3a780, + 0x3a782, 0x3a784, 0x3a786, 0x3a78b, 0x3a78d, 0x3a790, 0x3a792, 0x3a796, 0x3a798, + 0x3a79a, 0x3a79c, 0x3a79e, 0x3a7a0, 0x3a7a2, 0x3a7a4, 0x3a7a6, 0x3a7a8, 0x3a7b6, + 0x40100, 0x40102, 0x40104, 0x40106, 0x40108, 0x4010a, 0x4010c, 0x4010e, 0x40110, + 0x40112, 0x40114, 0x40116, 0x40118, 0x4011a, 0x4011c, 0x4011e, 0x40120, 0x40122, + 0x40124, 0x40126, 0x40128, 0x4012a, 0x4012c, 0x4012e, 0x40130, 0x40132, 0x40134, + 0x40136, 0x40139, 0x4013b, 0x4013d, 0x4013f, 0x40141, 0x40143, 0x40145, 0x40147, + 0x4014a, 0x4014c, 0x4014e, 0x40150, 0x40152, 0x40154, 0x40156, 0x40158, 0x4015a, + 0x4015c, 0x4015e, 0x40160, 0x40162, 0x40164, 0x40166, 0x40168, 0x4016a, 0x4016c, + 0x4016e, 0x40170, 0x40172, 0x40174, 0x40176, 0x40178, 0x40179, 0x4017b, 0x4017d, + 0x40181, 0x40182, 0x40184, 0x40186, 0x40187, 0x40193, 0x40194, 0x4019c, 0x4019d, + 0x4019f, 0x401a0, 0x401a2, 0x401a4, 0x401a6, 0x401a7, 0x401a9, 0x401ac, 0x401ae, + 0x401af, 0x401b5, 0x401b7, 0x401b8, 0x401bc, 0x401c4, 0x401c7, 0x401ca, 0x401cd, + 0x401cf, 0x401d1, 0x401d3, 0x401d5, 0x401d7, 0x401d9, 0x401db, 0x401de, 0x401e0, + 0x401e2, 0x401e4, 0x401e6, 0x401e8, 0x401ea, 0x401ec, 0x401ee, 0x401f1, 0x401f4, + 0x401fa, 0x401fc, 0x401fe, 0x40200, 0x40202, 0x40204, 0x40206, 0x40208, 0x4020a, + 0x4020c, 0x4020e, 0x40210, 0x40212, 0x40214, 0x40216, 0x40218, 0x4021a, 0x4021c, + 0x4021e, 0x40220, 0x40222, 0x40224, 0x40226, 0x40228, 0x4022a, 0x4022c, 0x4022e, + 0x40230, 0x40232, 0x4023a, 0x4023b, 0x4023d, 0x4023e, 0x40241, 0x40248, 0x4024a, + 0x4024c, 0x4024e, 0x40370, 0x40372, 0x40376, 0x4037f, 0x40386, 0x4038c, 0x4038e, + 0x4038f, 0x403cf, 0x403d8, 0x403da, 0x403dc, 0x403de, 0x403e0, 0x403e2, 0x403e4, + 0x403e6, 0x403e8, 0x403ea, 0x403ec, 0x403ee, 0x403f4, 0x403f7, 0x403f9, 0x403fa, + 0x40460, 0x40462, 0x40464, 0x40466, 0x40468, 0x4046a, 0x4046c, 0x4046e, 0x40470, + 0x40472, 0x40474, 0x40476, 0x40478, 0x4047a, 0x4047c, 0x4047e, 0x40480, 0x4048a, + 0x4048c, 0x4048e, 0x40490, 0x40492, 0x40494, 0x40496, 0x40498, 0x4049a, 0x4049c, + 0x4049e, 0x404a0, 0x404a2, 0x404a4, 0x404a6, 0x404a8, 0x404aa, 0x404ac, 0x404ae, + 0x404b0, 0x404b2, 0x404b4, 0x404b6, 0x404b8, 0x404ba, 0x404bc, 0x404be, 0x404c0, + 0x404c1, 0x404c3, 0x404c5, 0x404c7, 0x404c9, 0x404cb, 0x404cd, 0x404d0, 0x404d2, + 0x404d4, 0x404d6, 0x404d8, 0x404da, 0x404dc, 0x404de, 0x404e0, 0x404e2, 0x404e4, + 0x404e6, 0x404e8, 0x404ea, 0x404ec, 0x404ee, 0x404f0, 0x404f2, 0x404f4, 0x404f6, + 0x404f8, 0x404fa, 0x404fc, 0x404fe, 0x40500, 0x40502, 0x40504, 0x40506, 0x40508, + 0x4050a, 0x4050c, 0x4050e, 0x40510, 0x40512, 0x40514, 0x40516, 0x40518, 0x4051a, + 0x4051c, 0x4051e, 0x40520, 0x40522, 0x40524, 0x40526, 0x40528, 0x4052a, 0x4052c, + 0x4052e, 0x410c7, 0x410cd, 0x41e00, 0x41e02, 0x41e04, 0x41e06, 0x41e08, 0x41e0a, + 0x41e0c, 0x41e0e, 0x41e10, 0x41e12, 0x41e14, 0x41e16, 0x41e18, 0x41e1a, 0x41e1c, + 0x41e1e, 0x41e20, 0x41e22, 0x41e24, 0x41e26, 0x41e28, 0x41e2a, 0x41e2c, 0x41e2e, + 0x41e30, 0x41e32, 0x41e34, 0x41e36, 0x41e38, 0x41e3a, 0x41e3c, 0x41e3e, 0x41e40, + 0x41e42, 0x41e44, 0x41e46, 0x41e48, 0x41e4a, 0x41e4c, 0x41e4e, 0x41e50, 0x41e52, + 0x41e54, 0x41e56, 0x41e58, 0x41e5a, 0x41e5c, 0x41e5e, 0x41e60, 0x41e62, 0x41e64, + 0x41e66, 0x41e68, 0x41e6a, 0x41e6c, 0x41e6e, 0x41e70, 0x41e72, 0x41e74, 0x41e76, + 0x41e78, 0x41e7a, 0x41e7c, 0x41e7e, 0x41e80, 0x41e82, 0x41e84, 0x41e86, 0x41e88, + 0x41e8a, 0x41e8c, 0x41e8e, 0x41e90, 0x41e92, 0x41e94, 0x41e9e, 0x41ea0, 0x41ea2, + 0x41ea4, 0x41ea6, 0x41ea8, 0x41eaa, 0x41eac, 0x41eae, 0x41eb0, 0x41eb2, 0x41eb4, + 0x41eb6, 0x41eb8, 0x41eba, 0x41ebc, 0x41ebe, 0x41ec0, 0x41ec2, 0x41ec4, 0x41ec6, + 0x41ec8, 0x41eca, 0x41ecc, 0x41ece, 0x41ed0, 0x41ed2, 0x41ed4, 0x41ed6, 0x41ed8, + 0x41eda, 0x41edc, 0x41ede, 0x41ee0, 0x41ee2, 0x41ee4, 0x41ee6, 0x41ee8, 0x41eea, + 0x41eec, 0x41eee, 0x41ef0, 0x41ef2, 0x41ef4, 0x41ef6, 0x41ef8, 0x41efa, 0x41efc, + 0x41efe, 0x41f59, 0x41f5b, 0x41f5d, 0x41f5f, 0x42102, 0x42107, 0x42115, 0x42124, + 0x42126, 0x42128, 0x4213e, 0x4213f, 0x42145, 0x42183, 0x42c60, 0x42c67, 0x42c69, + 0x42c6b, 0x42c72, 0x42c75, 0x42c82, 0x42c84, 0x42c86, 0x42c88, 0x42c8a, 0x42c8c, + 0x42c8e, 0x42c90, 0x42c92, 0x42c94, 0x42c96, 0x42c98, 0x42c9a, 0x42c9c, 0x42c9e, + 0x42ca0, 0x42ca2, 0x42ca4, 0x42ca6, 0x42ca8, 0x42caa, 0x42cac, 0x42cae, 0x42cb0, + 0x42cb2, 0x42cb4, 0x42cb6, 0x42cb8, 0x42cba, 0x42cbc, 0x42cbe, 0x42cc0, 0x42cc2, + 0x42cc4, 0x42cc6, 0x42cc8, 0x42cca, 0x42ccc, 0x42cce, 0x42cd0, 0x42cd2, 0x42cd4, + 0x42cd6, 0x42cd8, 0x42cda, 0x42cdc, 0x42cde, 0x42ce0, 0x42ce2, 0x42ceb, 0x42ced, + 0x42cf2, 0x4a640, 0x4a642, 0x4a644, 0x4a646, 0x4a648, 0x4a64a, 0x4a64c, 0x4a64e, + 0x4a650, 0x4a652, 0x4a654, 0x4a656, 0x4a658, 0x4a65a, 0x4a65c, 0x4a65e, 0x4a660, + 0x4a662, 0x4a664, 0x4a666, 0x4a668, 0x4a66a, 0x4a66c, 0x4a680, 0x4a682, 0x4a684, + 0x4a686, 0x4a688, 0x4a68a, 0x4a68c, 0x4a68e, 0x4a690, 0x4a692, 0x4a694, 0x4a696, + 0x4a698, 0x4a69a, 0x4a722, 0x4a724, 0x4a726, 0x4a728, 0x4a72a, 0x4a72c, 0x4a72e, + 0x4a732, 0x4a734, 0x4a736, 0x4a738, 0x4a73a, 0x4a73c, 0x4a73e, 0x4a740, 0x4a742, + 0x4a744, 0x4a746, 0x4a748, 0x4a74a, 0x4a74c, 0x4a74e, 0x4a750, 0x4a752, 0x4a754, + 0x4a756, 0x4a758, 0x4a75a, 0x4a75c, 0x4a75e, 0x4a760, 0x4a762, 0x4a764, 0x4a766, + 0x4a768, 0x4a76a, 0x4a76c, 0x4a76e, 0x4a779, 0x4a77b, 0x4a77d, 0x4a77e, 0x4a780, + 0x4a782, 0x4a784, 0x4a786, 0x4a78b, 0x4a78d, 0x4a790, 0x4a792, 0x4a796, 0x4a798, + 0x4a79a, 0x4a79c, 0x4a79e, 0x4a7a0, 0x4a7a2, 0x4a7a4, 0x4a7a6, 0x4a7a8, 0x4a7b6, + 0x50100, 0x50102, 0x50104, 0x50106, 0x50108, 0x5010a, 0x5010c, 0x5010e, 0x50110, + 0x50112, 0x50114, 0x50116, 0x50118, 0x5011a, 0x5011c, 0x5011e, 0x50120, 0x50122, + 0x50124, 0x50126, 0x50128, 0x5012a, 0x5012c, 0x5012e, 0x50130, 0x50132, 0x50134, + 0x50136, 0x50139, 0x5013b, 0x5013d, 0x5013f, 0x50141, 0x50143, 0x50145, 0x50147, + 0x5014a, 0x5014c, 0x5014e, 0x50150, 0x50152, 0x50154, 0x50156, 0x50158, 0x5015a, + 0x5015c, 0x5015e, 0x50160, 0x50162, 0x50164, 0x50166, 0x50168, 0x5016a, 0x5016c, + 0x5016e, 0x50170, 0x50172, 0x50174, 0x50176, 0x50178, 0x50179, 0x5017b, 0x5017d, + 0x50181, 0x50182, 0x50184, 0x50186, 0x50187, 0x50193, 0x50194, 0x5019c, 0x5019d, + 0x5019f, 0x501a0, 0x501a2, 0x501a4, 0x501a6, 0x501a7, 0x501a9, 0x501ac, 0x501ae, + 0x501af, 0x501b5, 0x501b7, 0x501b8, 0x501bc, 0x501c4, 0x501c7, 0x501ca, 0x501cd, + 0x501cf, 0x501d1, 0x501d3, 0x501d5, 0x501d7, 0x501d9, 0x501db, 0x501de, 0x501e0, + 0x501e2, 0x501e4, 0x501e6, 0x501e8, 0x501ea, 0x501ec, 0x501ee, 0x501f1, 0x501f4, + 0x501fa, 0x501fc, 0x501fe, 0x50200, 0x50202, 0x50204, 0x50206, 0x50208, 0x5020a, + 0x5020c, 0x5020e, 0x50210, 0x50212, 0x50214, 0x50216, 0x50218, 0x5021a, 0x5021c, + 0x5021e, 0x50220, 0x50222, 0x50224, 0x50226, 0x50228, 0x5022a, 0x5022c, 0x5022e, + 0x50230, 0x50232, 0x5023a, 0x5023b, 0x5023d, 0x5023e, 0x50241, 0x50248, 0x5024a, + 0x5024c, 0x5024e, 0x50370, 0x50372, 0x50376, 0x5037f, 0x50386, 0x5038c, 0x5038e, + 0x5038f, 0x503cf, 0x503d8, 0x503da, 0x503dc, 0x503de, 0x503e0, 0x503e2, 0x503e4, + 0x503e6, 0x503e8, 0x503ea, 0x503ec, 0x503ee, 0x503f4, 0x503f7, 0x503f9, 0x503fa, + 0x50460, 0x50462, 0x50464, 0x50466, 0x50468, 0x5046a, 0x5046c, 0x5046e, 0x50470, + 0x50472, 0x50474, 0x50476, 0x50478, 0x5047a, 0x5047c, 0x5047e, 0x50480, 0x5048a, + 0x5048c, 0x5048e, 0x50490, 0x50492, 0x50494, 0x50496, 0x50498, 0x5049a, 0x5049c, + 0x5049e, 0x504a0, 0x504a2, 0x504a4, 0x504a6, 0x504a8, 0x504aa, 0x504ac, 0x504ae, + 0x504b0, 0x504b2, 0x504b4, 0x504b6, 0x504b8, 0x504ba, 0x504bc, 0x504be, 0x504c0, + 0x504c1, 0x504c3, 0x504c5, 0x504c7, 0x504c9, 0x504cb, 0x504cd, 0x504d0, 0x504d2, + 0x504d4, 0x504d6, 0x504d8, 0x504da, 0x504dc, 0x504de, 0x504e0, 0x504e2, 0x504e4, + 0x504e6, 0x504e8, 0x504ea, 0x504ec, 0x504ee, 0x504f0, 0x504f2, 0x504f4, 0x504f6, + 0x504f8, 0x504fa, 0x504fc, 0x504fe, 0x50500, 0x50502, 0x50504, 0x50506, 0x50508, + 0x5050a, 0x5050c, 0x5050e, 0x50510, 0x50512, 0x50514, 0x50516, 0x50518, 0x5051a, + 0x5051c, 0x5051e, 0x50520, 0x50522, 0x50524, 0x50526, 0x50528, 0x5052a, 0x5052c, + 0x5052e, 0x510c7, 0x510cd, 0x51e00, 0x51e02, 0x51e04, 0x51e06, 0x51e08, 0x51e0a, + 0x51e0c, 0x51e0e, 0x51e10, 0x51e12, 0x51e14, 0x51e16, 0x51e18, 0x51e1a, 0x51e1c, + 0x51e1e, 0x51e20, 0x51e22, 0x51e24, 0x51e26, 0x51e28, 0x51e2a, 0x51e2c, 0x51e2e, + 0x51e30, 0x51e32, 0x51e34, 0x51e36, 0x51e38, 0x51e3a, 0x51e3c, 0x51e3e, 0x51e40, + 0x51e42, 0x51e44, 0x51e46, 0x51e48, 0x51e4a, 0x51e4c, 0x51e4e, 0x51e50, 0x51e52, + 0x51e54, 0x51e56, 0x51e58, 0x51e5a, 0x51e5c, 0x51e5e, 0x51e60, 0x51e62, 0x51e64, + 0x51e66, 0x51e68, 0x51e6a, 0x51e6c, 0x51e6e, 0x51e70, 0x51e72, 0x51e74, 0x51e76, + 0x51e78, 0x51e7a, 0x51e7c, 0x51e7e, 0x51e80, 0x51e82, 0x51e84, 0x51e86, 0x51e88, + 0x51e8a, 0x51e8c, 0x51e8e, 0x51e90, 0x51e92, 0x51e94, 0x51e9e, 0x51ea0, 0x51ea2, + 0x51ea4, 0x51ea6, 0x51ea8, 0x51eaa, 0x51eac, 0x51eae, 0x51eb0, 0x51eb2, 0x51eb4, + 0x51eb6, 0x51eb8, 0x51eba, 0x51ebc, 0x51ebe, 0x51ec0, 0x51ec2, 0x51ec4, 0x51ec6, + 0x51ec8, 0x51eca, 0x51ecc, 0x51ece, 0x51ed0, 0x51ed2, 0x51ed4, 0x51ed6, 0x51ed8, + 0x51eda, 0x51edc, 0x51ede, 0x51ee0, 0x51ee2, 0x51ee4, 0x51ee6, 0x51ee8, 0x51eea, + 0x51eec, 0x51eee, 0x51ef0, 0x51ef2, 0x51ef4, 0x51ef6, 0x51ef8, 0x51efa, 0x51efc, + 0x51efe, 0x51f59, 0x51f5b, 0x51f5d, 0x51f5f, 0x52102, 0x52107, 0x52115, 0x52124, + 0x52126, 0x52128, 0x5213e, 0x5213f, 0x52145, 0x52183, 0x52c60, 0x52c67, 0x52c69, + 0x52c6b, 0x52c72, 0x52c75, 0x52c82, 0x52c84, 0x52c86, 0x52c88, 0x52c8a, 0x52c8c, + 0x52c8e, 0x52c90, 0x52c92, 0x52c94, 0x52c96, 0x52c98, 0x52c9a, 0x52c9c, 0x52c9e, + 0x52ca0, 0x52ca2, 0x52ca4, 0x52ca6, 0x52ca8, 0x52caa, 0x52cac, 0x52cae, 0x52cb0, + 0x52cb2, 0x52cb4, 0x52cb6, 0x52cb8, 0x52cba, 0x52cbc, 0x52cbe, 0x52cc0, 0x52cc2, + 0x52cc4, 0x52cc6, 0x52cc8, 0x52cca, 0x52ccc, 0x52cce, 0x52cd0, 0x52cd2, 0x52cd4, + 0x52cd6, 0x52cd8, 0x52cda, 0x52cdc, 0x52cde, 0x52ce0, 0x52ce2, 0x52ceb, 0x52ced, + 0x52cf2, 0x5a640, 0x5a642, 0x5a644, 0x5a646, 0x5a648, 0x5a64a, 0x5a64c, 0x5a64e, + 0x5a650, 0x5a652, 0x5a654, 0x5a656, 0x5a658, 0x5a65a, 0x5a65c, 0x5a65e, 0x5a660, + 0x5a662, 0x5a664, 0x5a666, 0x5a668, 0x5a66a, 0x5a66c, 0x5a680, 0x5a682, 0x5a684, + 0x5a686, 0x5a688, 0x5a68a, 0x5a68c, 0x5a68e, 0x5a690, 0x5a692, 0x5a694, 0x5a696, + 0x5a698, 0x5a69a, 0x5a722, 0x5a724, 0x5a726, 0x5a728, 0x5a72a, 0x5a72c, 0x5a72e, + 0x5a732, 0x5a734, 0x5a736, 0x5a738, 0x5a73a, 0x5a73c, 0x5a73e, 0x5a740, 0x5a742, + 0x5a744, 0x5a746, 0x5a748, 0x5a74a, 0x5a74c, 0x5a74e, 0x5a750, 0x5a752, 0x5a754, + 0x5a756, 0x5a758, 0x5a75a, 0x5a75c, 0x5a75e, 0x5a760, 0x5a762, 0x5a764, 0x5a766, + 0x5a768, 0x5a76a, 0x5a76c, 0x5a76e, 0x5a779, 0x5a77b, 0x5a77d, 0x5a77e, 0x5a780, + 0x5a782, 0x5a784, 0x5a786, 0x5a78b, 0x5a78d, 0x5a790, 0x5a792, 0x5a796, 0x5a798, + 0x5a79a, 0x5a79c, 0x5a79e, 0x5a7a0, 0x5a7a2, 0x5a7a4, 0x5a7a6, 0x5a7a8, 0x5a7b6, + 0x60100, 0x60102, 0x60104, 0x60106, 0x60108, 0x6010a, 0x6010c, 0x6010e, 0x60110, + 0x60112, 0x60114, 0x60116, 0x60118, 0x6011a, 0x6011c, 0x6011e, 0x60120, 0x60122, + 0x60124, 0x60126, 0x60128, 0x6012a, 0x6012c, 0x6012e, 0x60130, 0x60132, 0x60134, + 0x60136, 0x60139, 0x6013b, 0x6013d, 0x6013f, 0x60141, 0x60143, 0x60145, 0x60147, + 0x6014a, 0x6014c, 0x6014e, 0x60150, 0x60152, 0x60154, 0x60156, 0x60158, 0x6015a, + 0x6015c, 0x6015e, 0x60160, 0x60162, 0x60164, 0x60166, 0x60168, 0x6016a, 0x6016c, + 0x6016e, 0x60170, 0x60172, 0x60174, 0x60176, 0x60178, 0x60179, 0x6017b, 0x6017d, + 0x60181, 0x60182, 0x60184, 0x60186, 0x60187, 0x60193, 0x60194, 0x6019c, 0x6019d, + 0x6019f, 0x601a0, 0x601a2, 0x601a4, 0x601a6, 0x601a7, 0x601a9, 0x601ac, 0x601ae, + 0x601af, 0x601b5, 0x601b7, 0x601b8, 0x601bc, 0x601c4, 0x601c7, 0x601ca, 0x601cd, + 0x601cf, 0x601d1, 0x601d3, 0x601d5, 0x601d7, 0x601d9, 0x601db, 0x601de, 0x601e0, + 0x601e2, 0x601e4, 0x601e6, 0x601e8, 0x601ea, 0x601ec, 0x601ee, 0x601f1, 0x601f4, + 0x601fa, 0x601fc, 0x601fe, 0x60200, 0x60202, 0x60204, 0x60206, 0x60208, 0x6020a, + 0x6020c, 0x6020e, 0x60210, 0x60212, 0x60214, 0x60216, 0x60218, 0x6021a, 0x6021c, + 0x6021e, 0x60220, 0x60222, 0x60224, 0x60226, 0x60228, 0x6022a, 0x6022c, 0x6022e, + 0x60230, 0x60232, 0x6023a, 0x6023b, 0x6023d, 0x6023e, 0x60241, 0x60248, 0x6024a, + 0x6024c, 0x6024e, 0x60370, 0x60372, 0x60376, 0x6037f, 0x60386, 0x6038c, 0x6038e, + 0x6038f, 0x603cf, 0x603d8, 0x603da, 0x603dc, 0x603de, 0x603e0, 0x603e2, 0x603e4, + 0x603e6, 0x603e8, 0x603ea, 0x603ec, 0x603ee, 0x603f4, 0x603f7, 0x603f9, 0x603fa, + 0x60460, 0x60462, 0x60464, 0x60466, 0x60468, 0x6046a, 0x6046c, 0x6046e, 0x60470, + 0x60472, 0x60474, 0x60476, 0x60478, 0x6047a, 0x6047c, 0x6047e, 0x60480, 0x6048a, + 0x6048c, 0x6048e, 0x60490, 0x60492, 0x60494, 0x60496, 0x60498, 0x6049a, 0x6049c, + 0x6049e, 0x604a0, 0x604a2, 0x604a4, 0x604a6, 0x604a8, 0x604aa, 0x604ac, 0x604ae, + 0x604b0, 0x604b2, 0x604b4, 0x604b6, 0x604b8, 0x604ba, 0x604bc, 0x604be, 0x604c0, + 0x604c1, 0x604c3, 0x604c5, 0x604c7, 0x604c9, 0x604cb, 0x604cd, 0x604d0, 0x604d2, + 0x604d4, 0x604d6, 0x604d8, 0x604da, 0x604dc, 0x604de, 0x604e0, 0x604e2, 0x604e4, + 0x604e6, 0x604e8, 0x604ea, 0x604ec, 0x604ee, 0x604f0, 0x604f2, 0x604f4, 0x604f6, + 0x604f8, 0x604fa, 0x604fc, 0x604fe, 0x60500, 0x60502, 0x60504, 0x60506, 0x60508, + 0x6050a, 0x6050c, 0x6050e, 0x60510, 0x60512, 0x60514, 0x60516, 0x60518, 0x6051a, + 0x6051c, 0x6051e, 0x60520, 0x60522, 0x60524, 0x60526, 0x60528, 0x6052a, 0x6052c, + 0x6052e, 0x610c7, 0x610cd, 0x61e00, 0x61e02, 0x61e04, 0x61e06, 0x61e08, 0x61e0a, + 0x61e0c, 0x61e0e, 0x61e10, 0x61e12, 0x61e14, 0x61e16, 0x61e18, 0x61e1a, 0x61e1c, + 0x61e1e, 0x61e20, 0x61e22, 0x61e24, 0x61e26, 0x61e28, 0x61e2a, 0x61e2c, 0x61e2e, + 0x61e30, 0x61e32, 0x61e34, 0x61e36, 0x61e38, 0x61e3a, 0x61e3c, 0x61e3e, 0x61e40, + 0x61e42, 0x61e44, 0x61e46, 0x61e48, 0x61e4a, 0x61e4c, 0x61e4e, 0x61e50, 0x61e52, + 0x61e54, 0x61e56, 0x61e58, 0x61e5a, 0x61e5c, 0x61e5e, 0x61e60, 0x61e62, 0x61e64, + 0x61e66, 0x61e68, 0x61e6a, 0x61e6c, 0x61e6e, 0x61e70, 0x61e72, 0x61e74, 0x61e76, + 0x61e78, 0x61e7a, 0x61e7c, 0x61e7e, 0x61e80, 0x61e82, 0x61e84, 0x61e86, 0x61e88, + 0x61e8a, 0x61e8c, 0x61e8e, 0x61e90, 0x61e92, 0x61e94, 0x61e9e, 0x61ea0, 0x61ea2, + 0x61ea4, 0x61ea6, 0x61ea8, 0x61eaa, 0x61eac, 0x61eae, 0x61eb0, 0x61eb2, 0x61eb4, + 0x61eb6, 0x61eb8, 0x61eba, 0x61ebc, 0x61ebe, 0x61ec0, 0x61ec2, 0x61ec4, 0x61ec6, + 0x61ec8, 0x61eca, 0x61ecc, 0x61ece, 0x61ed0, 0x61ed2, 0x61ed4, 0x61ed6, 0x61ed8, + 0x61eda, 0x61edc, 0x61ede, 0x61ee0, 0x61ee2, 0x61ee4, 0x61ee6, 0x61ee8, 0x61eea, + 0x61eec, 0x61eee, 0x61ef0, 0x61ef2, 0x61ef4, 0x61ef6, 0x61ef8, 0x61efa, 0x61efc, + 0x61efe, 0x61f59, 0x61f5b, 0x61f5d, 0x61f5f, 0x62102, 0x62107, 0x62115, 0x62124, + 0x62126, 0x62128, 0x6213e, 0x6213f, 0x62145, 0x62183, 0x62c60, 0x62c67, 0x62c69, + 0x62c6b, 0x62c72, 0x62c75, 0x62c82, 0x62c84, 0x62c86, 0x62c88, 0x62c8a, 0x62c8c, + 0x62c8e, 0x62c90, 0x62c92, 0x62c94, 0x62c96, 0x62c98, 0x62c9a, 0x62c9c, 0x62c9e, + 0x62ca0, 0x62ca2, 0x62ca4, 0x62ca6, 0x62ca8, 0x62caa, 0x62cac, 0x62cae, 0x62cb0, + 0x62cb2, 0x62cb4, 0x62cb6, 0x62cb8, 0x62cba, 0x62cbc, 0x62cbe, 0x62cc0, 0x62cc2, + 0x62cc4, 0x62cc6, 0x62cc8, 0x62cca, 0x62ccc, 0x62cce, 0x62cd0, 0x62cd2, 0x62cd4, + 0x62cd6, 0x62cd8, 0x62cda, 0x62cdc, 0x62cde, 0x62ce0, 0x62ce2, 0x62ceb, 0x62ced, + 0x62cf2, 0x6a640, 0x6a642, 0x6a644, 0x6a646, 0x6a648, 0x6a64a, 0x6a64c, 0x6a64e, + 0x6a650, 0x6a652, 0x6a654, 0x6a656, 0x6a658, 0x6a65a, 0x6a65c, 0x6a65e, 0x6a660, + 0x6a662, 0x6a664, 0x6a666, 0x6a668, 0x6a66a, 0x6a66c, 0x6a680, 0x6a682, 0x6a684, + 0x6a686, 0x6a688, 0x6a68a, 0x6a68c, 0x6a68e, 0x6a690, 0x6a692, 0x6a694, 0x6a696, + 0x6a698, 0x6a69a, 0x6a722, 0x6a724, 0x6a726, 0x6a728, 0x6a72a, 0x6a72c, 0x6a72e, + 0x6a732, 0x6a734, 0x6a736, 0x6a738, 0x6a73a, 0x6a73c, 0x6a73e, 0x6a740, 0x6a742, + 0x6a744, 0x6a746, 0x6a748, 0x6a74a, 0x6a74c, 0x6a74e, 0x6a750, 0x6a752, 0x6a754, + 0x6a756, 0x6a758, 0x6a75a, 0x6a75c, 0x6a75e, 0x6a760, 0x6a762, 0x6a764, 0x6a766, + 0x6a768, 0x6a76a, 0x6a76c, 0x6a76e, 0x6a779, 0x6a77b, 0x6a77d, 0x6a77e, 0x6a780, + 0x6a782, 0x6a784, 0x6a786, 0x6a78b, 0x6a78d, 0x6a790, 0x6a792, 0x6a796, 0x6a798, + 0x6a79a, 0x6a79c, 0x6a79e, 0x6a7a0, 0x6a7a2, 0x6a7a4, 0x6a7a6, 0x6a7a8, 0x6a7b6, + 0x70100, 0x70102, 0x70104, 0x70106, 0x70108, 0x7010a, 0x7010c, 0x7010e, 0x70110, + 0x70112, 0x70114, 0x70116, 0x70118, 0x7011a, 0x7011c, 0x7011e, 0x70120, 0x70122, + 0x70124, 0x70126, 0x70128, 0x7012a, 0x7012c, 0x7012e, 0x70130, 0x70132, 0x70134, + 0x70136, 0x70139, 0x7013b, 0x7013d, 0x7013f, 0x70141, 0x70143, 0x70145, 0x70147, + 0x7014a, 0x7014c, 0x7014e, 0x70150, 0x70152, 0x70154, 0x70156, 0x70158, 0x7015a, + 0x7015c, 0x7015e, 0x70160, 0x70162, 0x70164, 0x70166, 0x70168, 0x7016a, 0x7016c, + 0x7016e, 0x70170, 0x70172, 0x70174, 0x70176, 0x70178, 0x70179, 0x7017b, 0x7017d, + 0x70181, 0x70182, 0x70184, 0x70186, 0x70187, 0x70193, 0x70194, 0x7019c, 0x7019d, + 0x7019f, 0x701a0, 0x701a2, 0x701a4, 0x701a6, 0x701a7, 0x701a9, 0x701ac, 0x701ae, + 0x701af, 0x701b5, 0x701b7, 0x701b8, 0x701bc, 0x701c4, 0x701c7, 0x701ca, 0x701cd, + 0x701cf, 0x701d1, 0x701d3, 0x701d5, 0x701d7, 0x701d9, 0x701db, 0x701de, 0x701e0, + 0x701e2, 0x701e4, 0x701e6, 0x701e8, 0x701ea, 0x701ec, 0x701ee, 0x701f1, 0x701f4, + 0x701fa, 0x701fc, 0x701fe, 0x70200, 0x70202, 0x70204, 0x70206, 0x70208, 0x7020a, + 0x7020c, 0x7020e, 0x70210, 0x70212, 0x70214, 0x70216, 0x70218, 0x7021a, 0x7021c, + 0x7021e, 0x70220, 0x70222, 0x70224, 0x70226, 0x70228, 0x7022a, 0x7022c, 0x7022e, + 0x70230, 0x70232, 0x7023a, 0x7023b, 0x7023d, 0x7023e, 0x70241, 0x70248, 0x7024a, + 0x7024c, 0x7024e, 0x70370, 0x70372, 0x70376, 0x7037f, 0x70386, 0x7038c, 0x7038e, + 0x7038f, 0x703cf, 0x703d8, 0x703da, 0x703dc, 0x703de, 0x703e0, 0x703e2, 0x703e4, + 0x703e6, 0x703e8, 0x703ea, 0x703ec, 0x703ee, 0x703f4, 0x703f7, 0x703f9, 0x703fa, + 0x70460, 0x70462, 0x70464, 0x70466, 0x70468, 0x7046a, 0x7046c, 0x7046e, 0x70470, + 0x70472, 0x70474, 0x70476, 0x70478, 0x7047a, 0x7047c, 0x7047e, 0x70480, 0x7048a, + 0x7048c, 0x7048e, 0x70490, 0x70492, 0x70494, 0x70496, 0x70498, 0x7049a, 0x7049c, + 0x7049e, 0x704a0, 0x704a2, 0x704a4, 0x704a6, 0x704a8, 0x704aa, 0x704ac, 0x704ae, + 0x704b0, 0x704b2, 0x704b4, 0x704b6, 0x704b8, 0x704ba, 0x704bc, 0x704be, 0x704c0, + 0x704c1, 0x704c3, 0x704c5, 0x704c7, 0x704c9, 0x704cb, 0x704cd, 0x704d0, 0x704d2, + 0x704d4, 0x704d6, 0x704d8, 0x704da, 0x704dc, 0x704de, 0x704e0, 0x704e2, 0x704e4, + 0x704e6, 0x704e8, 0x704ea, 0x704ec, 0x704ee, 0x704f0, 0x704f2, 0x704f4, 0x704f6, + 0x704f8, 0x704fa, 0x704fc, 0x704fe, 0x70500, 0x70502, 0x70504, 0x70506, 0x70508, + 0x7050a, 0x7050c, 0x7050e, 0x70510, 0x70512, 0x70514, 0x70516, 0x70518, 0x7051a, + 0x7051c, 0x7051e, 0x70520, 0x70522, 0x70524, 0x70526, 0x70528, 0x7052a, 0x7052c, + 0x7052e, 0x710c7, 0x710cd, 0x71e00, 0x71e02, 0x71e04, 0x71e06, 0x71e08, 0x71e0a, + 0x71e0c, 0x71e0e, 0x71e10, 0x71e12, 0x71e14, 0x71e16, 0x71e18, 0x71e1a, 0x71e1c, + 0x71e1e, 0x71e20, 0x71e22, 0x71e24, 0x71e26, 0x71e28, 0x71e2a, 0x71e2c, 0x71e2e, + 0x71e30, 0x71e32, 0x71e34, 0x71e36, 0x71e38, 0x71e3a, 0x71e3c, 0x71e3e, 0x71e40, + 0x71e42, 0x71e44, 0x71e46, 0x71e48, 0x71e4a, 0x71e4c, 0x71e4e, 0x71e50, 0x71e52, + 0x71e54, 0x71e56, 0x71e58, 0x71e5a, 0x71e5c, 0x71e5e, 0x71e60, 0x71e62, 0x71e64, + 0x71e66, 0x71e68, 0x71e6a, 0x71e6c, 0x71e6e, 0x71e70, 0x71e72, 0x71e74, 0x71e76, + 0x71e78, 0x71e7a, 0x71e7c, 0x71e7e, 0x71e80, 0x71e82, 0x71e84, 0x71e86, 0x71e88, + 0x71e8a, 0x71e8c, 0x71e8e, 0x71e90, 0x71e92, 0x71e94, 0x71e9e, 0x71ea0, 0x71ea2, + 0x71ea4, 0x71ea6, 0x71ea8, 0x71eaa, 0x71eac, 0x71eae, 0x71eb0, 0x71eb2, 0x71eb4, + 0x71eb6, 0x71eb8, 0x71eba, 0x71ebc, 0x71ebe, 0x71ec0, 0x71ec2, 0x71ec4, 0x71ec6, + 0x71ec8, 0x71eca, 0x71ecc, 0x71ece, 0x71ed0, 0x71ed2, 0x71ed4, 0x71ed6, 0x71ed8, + 0x71eda, 0x71edc, 0x71ede, 0x71ee0, 0x71ee2, 0x71ee4, 0x71ee6, 0x71ee8, 0x71eea, + 0x71eec, 0x71eee, 0x71ef0, 0x71ef2, 0x71ef4, 0x71ef6, 0x71ef8, 0x71efa, 0x71efc, + 0x71efe, 0x71f59, 0x71f5b, 0x71f5d, 0x71f5f, 0x72102, 0x72107, 0x72115, 0x72124, + 0x72126, 0x72128, 0x7213e, 0x7213f, 0x72145, 0x72183, 0x72c60, 0x72c67, 0x72c69, + 0x72c6b, 0x72c72, 0x72c75, 0x72c82, 0x72c84, 0x72c86, 0x72c88, 0x72c8a, 0x72c8c, + 0x72c8e, 0x72c90, 0x72c92, 0x72c94, 0x72c96, 0x72c98, 0x72c9a, 0x72c9c, 0x72c9e, + 0x72ca0, 0x72ca2, 0x72ca4, 0x72ca6, 0x72ca8, 0x72caa, 0x72cac, 0x72cae, 0x72cb0, + 0x72cb2, 0x72cb4, 0x72cb6, 0x72cb8, 0x72cba, 0x72cbc, 0x72cbe, 0x72cc0, 0x72cc2, + 0x72cc4, 0x72cc6, 0x72cc8, 0x72cca, 0x72ccc, 0x72cce, 0x72cd0, 0x72cd2, 0x72cd4, + 0x72cd6, 0x72cd8, 0x72cda, 0x72cdc, 0x72cde, 0x72ce0, 0x72ce2, 0x72ceb, 0x72ced, + 0x72cf2, 0x7a640, 0x7a642, 0x7a644, 0x7a646, 0x7a648, 0x7a64a, 0x7a64c, 0x7a64e, + 0x7a650, 0x7a652, 0x7a654, 0x7a656, 0x7a658, 0x7a65a, 0x7a65c, 0x7a65e, 0x7a660, + 0x7a662, 0x7a664, 0x7a666, 0x7a668, 0x7a66a, 0x7a66c, 0x7a680, 0x7a682, 0x7a684, + 0x7a686, 0x7a688, 0x7a68a, 0x7a68c, 0x7a68e, 0x7a690, 0x7a692, 0x7a694, 0x7a696, + 0x7a698, 0x7a69a, 0x7a722, 0x7a724, 0x7a726, 0x7a728, 0x7a72a, 0x7a72c, 0x7a72e, + 0x7a732, 0x7a734, 0x7a736, 0x7a738, 0x7a73a, 0x7a73c, 0x7a73e, 0x7a740, 0x7a742, + 0x7a744, 0x7a746, 0x7a748, 0x7a74a, 0x7a74c, 0x7a74e, 0x7a750, 0x7a752, 0x7a754, + 0x7a756, 0x7a758, 0x7a75a, 0x7a75c, 0x7a75e, 0x7a760, 0x7a762, 0x7a764, 0x7a766, + 0x7a768, 0x7a76a, 0x7a76c, 0x7a76e, 0x7a779, 0x7a77b, 0x7a77d, 0x7a77e, 0x7a780, + 0x7a782, 0x7a784, 0x7a786, 0x7a78b, 0x7a78d, 0x7a790, 0x7a792, 0x7a796, 0x7a798, + 0x7a79a, 0x7a79c, 0x7a79e, 0x7a7a0, 0x7a7a2, 0x7a7a4, 0x7a7a6, 0x7a7a8, 0x7a7b6, + 0x80100, 0x80102, 0x80104, 0x80106, 0x80108, 0x8010a, 0x8010c, 0x8010e, 0x80110, + 0x80112, 0x80114, 0x80116, 0x80118, 0x8011a, 0x8011c, 0x8011e, 0x80120, 0x80122, + 0x80124, 0x80126, 0x80128, 0x8012a, 0x8012c, 0x8012e, 0x80130, 0x80132, 0x80134, + 0x80136, 0x80139, 0x8013b, 0x8013d, 0x8013f, 0x80141, 0x80143, 0x80145, 0x80147, + 0x8014a, 0x8014c, 0x8014e, 0x80150, 0x80152, 0x80154, 0x80156, 0x80158, 0x8015a, + 0x8015c, 0x8015e, 0x80160, 0x80162, 0x80164, 0x80166, 0x80168, 0x8016a, 0x8016c, + 0x8016e, 0x80170, 0x80172, 0x80174, 0x80176, 0x80178, 0x80179, 0x8017b, 0x8017d, + 0x80181, 0x80182, 0x80184, 0x80186, 0x80187, 0x80193, 0x80194, 0x8019c, 0x8019d, + 0x8019f, 0x801a0, 0x801a2, 0x801a4, 0x801a6, 0x801a7, 0x801a9, 0x801ac, 0x801ae, + 0x801af, 0x801b5, 0x801b7, 0x801b8, 0x801bc, 0x801c4, 0x801c7, 0x801ca, 0x801cd, + 0x801cf, 0x801d1, 0x801d3, 0x801d5, 0x801d7, 0x801d9, 0x801db, 0x801de, 0x801e0, + 0x801e2, 0x801e4, 0x801e6, 0x801e8, 0x801ea, 0x801ec, 0x801ee, 0x801f1, 0x801f4, + 0x801fa, 0x801fc, 0x801fe, 0x80200, 0x80202, 0x80204, 0x80206, 0x80208, 0x8020a, + 0x8020c, 0x8020e, 0x80210, 0x80212, 0x80214, 0x80216, 0x80218, 0x8021a, 0x8021c, + 0x8021e, 0x80220, 0x80222, 0x80224, 0x80226, 0x80228, 0x8022a, 0x8022c, 0x8022e, + 0x80230, 0x80232, 0x8023a, 0x8023b, 0x8023d, 0x8023e, 0x80241, 0x80248, 0x8024a, + 0x8024c, 0x8024e, 0x80370, 0x80372, 0x80376, 0x8037f, 0x80386, 0x8038c, 0x8038e, + 0x8038f, 0x803cf, 0x803d8, 0x803da, 0x803dc, 0x803de, 0x803e0, 0x803e2, 0x803e4, + 0x803e6, 0x803e8, 0x803ea, 0x803ec, 0x803ee, 0x803f4, 0x803f7, 0x803f9, 0x803fa, + 0x80460, 0x80462, 0x80464, 0x80466, 0x80468, 0x8046a, 0x8046c, 0x8046e, 0x80470, + 0x80472, 0x80474, 0x80476, 0x80478, 0x8047a, 0x8047c, 0x8047e, 0x80480, 0x8048a, + 0x8048c, 0x8048e, 0x80490, 0x80492, 0x80494, 0x80496, 0x80498, 0x8049a, 0x8049c, + 0x8049e, 0x804a0, 0x804a2, 0x804a4, 0x804a6, 0x804a8, 0x804aa, 0x804ac, 0x804ae, + 0x804b0, 0x804b2, 0x804b4, 0x804b6, 0x804b8, 0x804ba, 0x804bc, 0x804be, 0x804c0, + 0x804c1, 0x804c3, 0x804c5, 0x804c7, 0x804c9, 0x804cb, 0x804cd, 0x804d0, 0x804d2, + 0x804d4, 0x804d6, 0x804d8, 0x804da, 0x804dc, 0x804de, 0x804e0, 0x804e2, 0x804e4, + 0x804e6, 0x804e8, 0x804ea, 0x804ec, 0x804ee, 0x804f0, 0x804f2, 0x804f4, 0x804f6, + 0x804f8, 0x804fa, 0x804fc, 0x804fe, 0x80500, 0x80502, 0x80504, 0x80506, 0x80508, + 0x8050a, 0x8050c, 0x8050e, 0x80510, 0x80512, 0x80514, 0x80516, 0x80518, 0x8051a, + 0x8051c, 0x8051e, 0x80520, 0x80522, 0x80524, 0x80526, 0x80528, 0x8052a, 0x8052c, + 0x8052e, 0x810c7, 0x810cd, 0x81e00, 0x81e02, 0x81e04, 0x81e06, 0x81e08, 0x81e0a, + 0x81e0c, 0x81e0e, 0x81e10, 0x81e12, 0x81e14, 0x81e16, 0x81e18, 0x81e1a, 0x81e1c, + 0x81e1e, 0x81e20, 0x81e22, 0x81e24, 0x81e26, 0x81e28, 0x81e2a, 0x81e2c, 0x81e2e, + 0x81e30, 0x81e32, 0x81e34, 0x81e36, 0x81e38, 0x81e3a, 0x81e3c, 0x81e3e, 0x81e40, + 0x81e42, 0x81e44, 0x81e46, 0x81e48, 0x81e4a, 0x81e4c, 0x81e4e, 0x81e50, 0x81e52, + 0x81e54, 0x81e56, 0x81e58, 0x81e5a, 0x81e5c, 0x81e5e, 0x81e60, 0x81e62, 0x81e64, + 0x81e66, 0x81e68, 0x81e6a, 0x81e6c, 0x81e6e, 0x81e70, 0x81e72, 0x81e74, 0x81e76, + 0x81e78, 0x81e7a, 0x81e7c, 0x81e7e, 0x81e80, 0x81e82, 0x81e84, 0x81e86, 0x81e88, + 0x81e8a, 0x81e8c, 0x81e8e, 0x81e90, 0x81e92, 0x81e94, 0x81e9e, 0x81ea0, 0x81ea2, + 0x81ea4, 0x81ea6, 0x81ea8, 0x81eaa, 0x81eac, 0x81eae, 0x81eb0, 0x81eb2, 0x81eb4, + 0x81eb6, 0x81eb8, 0x81eba, 0x81ebc, 0x81ebe, 0x81ec0, 0x81ec2, 0x81ec4, 0x81ec6, + 0x81ec8, 0x81eca, 0x81ecc, 0x81ece, 0x81ed0, 0x81ed2, 0x81ed4, 0x81ed6, 0x81ed8, + 0x81eda, 0x81edc, 0x81ede, 0x81ee0, 0x81ee2, 0x81ee4, 0x81ee6, 0x81ee8, 0x81eea, + 0x81eec, 0x81eee, 0x81ef0, 0x81ef2, 0x81ef4, 0x81ef6, 0x81ef8, 0x81efa, 0x81efc, + 0x81efe, 0x81f59, 0x81f5b, 0x81f5d, 0x81f5f, 0x82102, 0x82107, 0x82115, 0x82124, + 0x82126, 0x82128, 0x8213e, 0x8213f, 0x82145, 0x82183, 0x82c60, 0x82c67, 0x82c69, + 0x82c6b, 0x82c72, 0x82c75, 0x82c82, 0x82c84, 0x82c86, 0x82c88, 0x82c8a, 0x82c8c, + 0x82c8e, 0x82c90, 0x82c92, 0x82c94, 0x82c96, 0x82c98, 0x82c9a, 0x82c9c, 0x82c9e, + 0x82ca0, 0x82ca2, 0x82ca4, 0x82ca6, 0x82ca8, 0x82caa, 0x82cac, 0x82cae, 0x82cb0, + 0x82cb2, 0x82cb4, 0x82cb6, 0x82cb8, 0x82cba, 0x82cbc, 0x82cbe, 0x82cc0, 0x82cc2, + 0x82cc4, 0x82cc6, 0x82cc8, 0x82cca, 0x82ccc, 0x82cce, 0x82cd0, 0x82cd2, 0x82cd4, + 0x82cd6, 0x82cd8, 0x82cda, 0x82cdc, 0x82cde, 0x82ce0, 0x82ce2, 0x82ceb, 0x82ced, + 0x82cf2, 0x8a640, 0x8a642, 0x8a644, 0x8a646, 0x8a648, 0x8a64a, 0x8a64c, 0x8a64e, + 0x8a650, 0x8a652, 0x8a654, 0x8a656, 0x8a658, 0x8a65a, 0x8a65c, 0x8a65e, 0x8a660, + 0x8a662, 0x8a664, 0x8a666, 0x8a668, 0x8a66a, 0x8a66c, 0x8a680, 0x8a682, 0x8a684, + 0x8a686, 0x8a688, 0x8a68a, 0x8a68c, 0x8a68e, 0x8a690, 0x8a692, 0x8a694, 0x8a696, + 0x8a698, 0x8a69a, 0x8a722, 0x8a724, 0x8a726, 0x8a728, 0x8a72a, 0x8a72c, 0x8a72e, + 0x8a732, 0x8a734, 0x8a736, 0x8a738, 0x8a73a, 0x8a73c, 0x8a73e, 0x8a740, 0x8a742, + 0x8a744, 0x8a746, 0x8a748, 0x8a74a, 0x8a74c, 0x8a74e, 0x8a750, 0x8a752, 0x8a754, + 0x8a756, 0x8a758, 0x8a75a, 0x8a75c, 0x8a75e, 0x8a760, 0x8a762, 0x8a764, 0x8a766, + 0x8a768, 0x8a76a, 0x8a76c, 0x8a76e, 0x8a779, 0x8a77b, 0x8a77d, 0x8a77e, 0x8a780, + 0x8a782, 0x8a784, 0x8a786, 0x8a78b, 0x8a78d, 0x8a790, 0x8a792, 0x8a796, 0x8a798, + 0x8a79a, 0x8a79c, 0x8a79e, 0x8a7a0, 0x8a7a2, 0x8a7a4, 0x8a7a6, 0x8a7a8, 0x8a7b6, + 0x90100, 0x90102, 0x90104, 0x90106, 0x90108, 0x9010a, 0x9010c, 0x9010e, 0x90110, + 0x90112, 0x90114, 0x90116, 0x90118, 0x9011a, 0x9011c, 0x9011e, 0x90120, 0x90122, + 0x90124, 0x90126, 0x90128, 0x9012a, 0x9012c, 0x9012e, 0x90130, 0x90132, 0x90134, + 0x90136, 0x90139, 0x9013b, 0x9013d, 0x9013f, 0x90141, 0x90143, 0x90145, 0x90147, + 0x9014a, 0x9014c, 0x9014e, 0x90150, 0x90152, 0x90154, 0x90156, 0x90158, 0x9015a, + 0x9015c, 0x9015e, 0x90160, 0x90162, 0x90164, 0x90166, 0x90168, 0x9016a, 0x9016c, + 0x9016e, 0x90170, 0x90172, 0x90174, 0x90176, 0x90178, 0x90179, 0x9017b, 0x9017d, + 0x90181, 0x90182, 0x90184, 0x90186, 0x90187, 0x90193, 0x90194, 0x9019c, 0x9019d, + 0x9019f, 0x901a0, 0x901a2, 0x901a4, 0x901a6, 0x901a7, 0x901a9, 0x901ac, 0x901ae, + 0x901af, 0x901b5, 0x901b7, 0x901b8, 0x901bc, 0x901c4, 0x901c7, 0x901ca, 0x901cd, + 0x901cf, 0x901d1, 0x901d3, 0x901d5, 0x901d7, 0x901d9, 0x901db, 0x901de, 0x901e0, + 0x901e2, 0x901e4, 0x901e6, 0x901e8, 0x901ea, 0x901ec, 0x901ee, 0x901f1, 0x901f4, + 0x901fa, 0x901fc, 0x901fe, 0x90200, 0x90202, 0x90204, 0x90206, 0x90208, 0x9020a, + 0x9020c, 0x9020e, 0x90210, 0x90212, 0x90214, 0x90216, 0x90218, 0x9021a, 0x9021c, + 0x9021e, 0x90220, 0x90222, 0x90224, 0x90226, 0x90228, 0x9022a, 0x9022c, 0x9022e, + 0x90230, 0x90232, 0x9023a, 0x9023b, 0x9023d, 0x9023e, 0x90241, 0x90248, 0x9024a, + 0x9024c, 0x9024e, 0x90370, 0x90372, 0x90376, 0x9037f, 0x90386, 0x9038c, 0x9038e, + 0x9038f, 0x903cf, 0x903d8, 0x903da, 0x903dc, 0x903de, 0x903e0, 0x903e2, 0x903e4, + 0x903e6, 0x903e8, 0x903ea, 0x903ec, 0x903ee, 0x903f4, 0x903f7, 0x903f9, 0x903fa, + 0x90460, 0x90462, 0x90464, 0x90466, 0x90468, 0x9046a, 0x9046c, 0x9046e, 0x90470, + 0x90472, 0x90474, 0x90476, 0x90478, 0x9047a, 0x9047c, 0x9047e, 0x90480, 0x9048a, + 0x9048c, 0x9048e, 0x90490, 0x90492, 0x90494, 0x90496, 0x90498, 0x9049a, 0x9049c, + 0x9049e, 0x904a0, 0x904a2, 0x904a4, 0x904a6, 0x904a8, 0x904aa, 0x904ac, 0x904ae, + 0x904b0, 0x904b2, 0x904b4, 0x904b6, 0x904b8, 0x904ba, 0x904bc, 0x904be, 0x904c0, + 0x904c1, 0x904c3, 0x904c5, 0x904c7, 0x904c9, 0x904cb, 0x904cd, 0x904d0, 0x904d2, + 0x904d4, 0x904d6, 0x904d8, 0x904da, 0x904dc, 0x904de, 0x904e0, 0x904e2, 0x904e4, + 0x904e6, 0x904e8, 0x904ea, 0x904ec, 0x904ee, 0x904f0, 0x904f2, 0x904f4, 0x904f6, + 0x904f8, 0x904fa, 0x904fc, 0x904fe, 0x90500, 0x90502, 0x90504, 0x90506, 0x90508, + 0x9050a, 0x9050c, 0x9050e, 0x90510, 0x90512, 0x90514, 0x90516, 0x90518, 0x9051a, + 0x9051c, 0x9051e, 0x90520, 0x90522, 0x90524, 0x90526, 0x90528, 0x9052a, 0x9052c, + 0x9052e, 0x910c7, 0x910cd, 0x91e00, 0x91e02, 0x91e04, 0x91e06, 0x91e08, 0x91e0a, + 0x91e0c, 0x91e0e, 0x91e10, 0x91e12, 0x91e14, 0x91e16, 0x91e18, 0x91e1a, 0x91e1c, + 0x91e1e, 0x91e20, 0x91e22, 0x91e24, 0x91e26, 0x91e28, 0x91e2a, 0x91e2c, 0x91e2e, + 0x91e30, 0x91e32, 0x91e34, 0x91e36, 0x91e38, 0x91e3a, 0x91e3c, 0x91e3e, 0x91e40, + 0x91e42, 0x91e44, 0x91e46, 0x91e48, 0x91e4a, 0x91e4c, 0x91e4e, 0x91e50, 0x91e52, + 0x91e54, 0x91e56, 0x91e58, 0x91e5a, 0x91e5c, 0x91e5e, 0x91e60, 0x91e62, 0x91e64, + 0x91e66, 0x91e68, 0x91e6a, 0x91e6c, 0x91e6e, 0x91e70, 0x91e72, 0x91e74, 0x91e76, + 0x91e78, 0x91e7a, 0x91e7c, 0x91e7e, 0x91e80, 0x91e82, 0x91e84, 0x91e86, 0x91e88, + 0x91e8a, 0x91e8c, 0x91e8e, 0x91e90, 0x91e92, 0x91e94, 0x91e9e, 0x91ea0, 0x91ea2, + 0x91ea4, 0x91ea6, 0x91ea8, 0x91eaa, 0x91eac, 0x91eae, 0x91eb0, 0x91eb2, 0x91eb4, + 0x91eb6, 0x91eb8, 0x91eba, 0x91ebc, 0x91ebe, 0x91ec0, 0x91ec2, 0x91ec4, 0x91ec6, + 0x91ec8, 0x91eca, 0x91ecc, 0x91ece, 0x91ed0, 0x91ed2, 0x91ed4, 0x91ed6, 0x91ed8, + 0x91eda, 0x91edc, 0x91ede, 0x91ee0, 0x91ee2, 0x91ee4, 0x91ee6, 0x91ee8, 0x91eea, + 0x91eec, 0x91eee, 0x91ef0, 0x91ef2, 0x91ef4, 0x91ef6, 0x91ef8, 0x91efa, 0x91efc, + 0x91efe, 0x91f59, 0x91f5b, 0x91f5d, 0x91f5f, 0x92102, 0x92107, 0x92115, 0x92124, + 0x92126, 0x92128, 0x9213e, 0x9213f, 0x92145, 0x92183, 0x92c60, 0x92c67, 0x92c69, + 0x92c6b, 0x92c72, 0x92c75, 0x92c82, 0x92c84, 0x92c86, 0x92c88, 0x92c8a, 0x92c8c, + 0x92c8e, 0x92c90, 0x92c92, 0x92c94, 0x92c96, 0x92c98, 0x92c9a, 0x92c9c, 0x92c9e, + 0x92ca0, 0x92ca2, 0x92ca4, 0x92ca6, 0x92ca8, 0x92caa, 0x92cac, 0x92cae, 0x92cb0, + 0x92cb2, 0x92cb4, 0x92cb6, 0x92cb8, 0x92cba, 0x92cbc, 0x92cbe, 0x92cc0, 0x92cc2, + 0x92cc4, 0x92cc6, 0x92cc8, 0x92cca, 0x92ccc, 0x92cce, 0x92cd0, 0x92cd2, 0x92cd4, + 0x92cd6, 0x92cd8, 0x92cda, 0x92cdc, 0x92cde, 0x92ce0, 0x92ce2, 0x92ceb, 0x92ced, + 0x92cf2, 0x9a640, 0x9a642, 0x9a644, 0x9a646, 0x9a648, 0x9a64a, 0x9a64c, 0x9a64e, + 0x9a650, 0x9a652, 0x9a654, 0x9a656, 0x9a658, 0x9a65a, 0x9a65c, 0x9a65e, 0x9a660, + 0x9a662, 0x9a664, 0x9a666, 0x9a668, 0x9a66a, 0x9a66c, 0x9a680, 0x9a682, 0x9a684, + 0x9a686, 0x9a688, 0x9a68a, 0x9a68c, 0x9a68e, 0x9a690, 0x9a692, 0x9a694, 0x9a696, + 0x9a698, 0x9a69a, 0x9a722, 0x9a724, 0x9a726, 0x9a728, 0x9a72a, 0x9a72c, 0x9a72e, + 0x9a732, 0x9a734, 0x9a736, 0x9a738, 0x9a73a, 0x9a73c, 0x9a73e, 0x9a740, 0x9a742, + 0x9a744, 0x9a746, 0x9a748, 0x9a74a, 0x9a74c, 0x9a74e, 0x9a750, 0x9a752, 0x9a754, + 0x9a756, 0x9a758, 0x9a75a, 0x9a75c, 0x9a75e, 0x9a760, 0x9a762, 0x9a764, 0x9a766, + 0x9a768, 0x9a76a, 0x9a76c, 0x9a76e, 0x9a779, 0x9a77b, 0x9a77d, 0x9a77e, 0x9a780, + 0x9a782, 0x9a784, 0x9a786, 0x9a78b, 0x9a78d, 0x9a790, 0x9a792, 0x9a796, 0x9a798, + 0x9a79a, 0x9a79c, 0x9a79e, 0x9a7a0, 0x9a7a2, 0x9a7a4, 0x9a7a6, 0x9a7a8, 0x9a7b6, + 0xa0100, 0xa0102, 0xa0104, 0xa0106, 0xa0108, 0xa010a, 0xa010c, 0xa010e, 0xa0110, + 0xa0112, 0xa0114, 0xa0116, 0xa0118, 0xa011a, 0xa011c, 0xa011e, 0xa0120, 0xa0122, + 0xa0124, 0xa0126, 0xa0128, 0xa012a, 0xa012c, 0xa012e, 0xa0130, 0xa0132, 0xa0134, + 0xa0136, 0xa0139, 0xa013b, 0xa013d, 0xa013f, 0xa0141, 0xa0143, 0xa0145, 0xa0147, + 0xa014a, 0xa014c, 0xa014e, 0xa0150, 0xa0152, 0xa0154, 0xa0156, 0xa0158, 0xa015a, + 0xa015c, 0xa015e, 0xa0160, 0xa0162, 0xa0164, 0xa0166, 0xa0168, 0xa016a, 0xa016c, + 0xa016e, 0xa0170, 0xa0172, 0xa0174, 0xa0176, 0xa0178, 0xa0179, 0xa017b, 0xa017d, + 0xa0181, 0xa0182, 0xa0184, 0xa0186, 0xa0187, 0xa0193, 0xa0194, 0xa019c, 0xa019d, + 0xa019f, 0xa01a0, 0xa01a2, 0xa01a4, 0xa01a6, 0xa01a7, 0xa01a9, 0xa01ac, 0xa01ae, + 0xa01af, 0xa01b5, 0xa01b7, 0xa01b8, 0xa01bc, 0xa01c4, 0xa01c7, 0xa01ca, 0xa01cd, + 0xa01cf, 0xa01d1, 0xa01d3, 0xa01d5, 0xa01d7, 0xa01d9, 0xa01db, 0xa01de, 0xa01e0, + 0xa01e2, 0xa01e4, 0xa01e6, 0xa01e8, 0xa01ea, 0xa01ec, 0xa01ee, 0xa01f1, 0xa01f4, + 0xa01fa, 0xa01fc, 0xa01fe, 0xa0200, 0xa0202, 0xa0204, 0xa0206, 0xa0208, 0xa020a, + 0xa020c, 0xa020e, 0xa0210, 0xa0212, 0xa0214, 0xa0216, 0xa0218, 0xa021a, 0xa021c, + 0xa021e, 0xa0220, 0xa0222, 0xa0224, 0xa0226, 0xa0228, 0xa022a, 0xa022c, 0xa022e, + 0xa0230, 0xa0232, 0xa023a, 0xa023b, 0xa023d, 0xa023e, 0xa0241, 0xa0248, 0xa024a, + 0xa024c, 0xa024e, 0xa0370, 0xa0372, 0xa0376, 0xa037f, 0xa0386, 0xa038c, 0xa038e, + 0xa038f, 0xa03cf, 0xa03d8, 0xa03da, 0xa03dc, 0xa03de, 0xa03e0, 0xa03e2, 0xa03e4, + 0xa03e6, 0xa03e8, 0xa03ea, 0xa03ec, 0xa03ee, 0xa03f4, 0xa03f7, 0xa03f9, 0xa03fa, + 0xa0460, 0xa0462, 0xa0464, 0xa0466, 0xa0468, 0xa046a, 0xa046c, 0xa046e, 0xa0470, + 0xa0472, 0xa0474, 0xa0476, 0xa0478, 0xa047a, 0xa047c, 0xa047e, 0xa0480, 0xa048a, + 0xa048c, 0xa048e, 0xa0490, 0xa0492, 0xa0494, 0xa0496, 0xa0498, 0xa049a, 0xa049c, + 0xa049e, 0xa04a0, 0xa04a2, 0xa04a4, 0xa04a6, 0xa04a8, 0xa04aa, 0xa04ac, 0xa04ae, + 0xa04b0, 0xa04b2, 0xa04b4, 0xa04b6, 0xa04b8, 0xa04ba, 0xa04bc, 0xa04be, 0xa04c0, + 0xa04c1, 0xa04c3, 0xa04c5, 0xa04c7, 0xa04c9, 0xa04cb, 0xa04cd, 0xa04d0, 0xa04d2, + 0xa04d4, 0xa04d6, 0xa04d8, 0xa04da, 0xa04dc, 0xa04de, 0xa04e0, 0xa04e2, 0xa04e4, + 0xa04e6, 0xa04e8, 0xa04ea, 0xa04ec, 0xa04ee, 0xa04f0, 0xa04f2, 0xa04f4, 0xa04f6, + 0xa04f8, 0xa04fa, 0xa04fc, 0xa04fe, 0xa0500, 0xa0502, 0xa0504, 0xa0506, 0xa0508, + 0xa050a, 0xa050c, 0xa050e, 0xa0510, 0xa0512, 0xa0514, 0xa0516, 0xa0518, 0xa051a, + 0xa051c, 0xa051e, 0xa0520, 0xa0522, 0xa0524, 0xa0526, 0xa0528, 0xa052a, 0xa052c, + 0xa052e, 0xa10c7, 0xa10cd, 0xa1e00, 0xa1e02, 0xa1e04, 0xa1e06, 0xa1e08, 0xa1e0a, + 0xa1e0c, 0xa1e0e, 0xa1e10, 0xa1e12, 0xa1e14, 0xa1e16, 0xa1e18, 0xa1e1a, 0xa1e1c, + 0xa1e1e, 0xa1e20, 0xa1e22, 0xa1e24, 0xa1e26, 0xa1e28, 0xa1e2a, 0xa1e2c, 0xa1e2e, + 0xa1e30, 0xa1e32, 0xa1e34, 0xa1e36, 0xa1e38, 0xa1e3a, 0xa1e3c, 0xa1e3e, 0xa1e40, + 0xa1e42, 0xa1e44, 0xa1e46, 0xa1e48, 0xa1e4a, 0xa1e4c, 0xa1e4e, 0xa1e50, 0xa1e52, + 0xa1e54, 0xa1e56, 0xa1e58, 0xa1e5a, 0xa1e5c, 0xa1e5e, 0xa1e60, 0xa1e62, 0xa1e64, + 0xa1e66, 0xa1e68, 0xa1e6a, 0xa1e6c, 0xa1e6e, 0xa1e70, 0xa1e72, 0xa1e74, 0xa1e76, + 0xa1e78, 0xa1e7a, 0xa1e7c, 0xa1e7e, 0xa1e80, 0xa1e82, 0xa1e84, 0xa1e86, 0xa1e88, + 0xa1e8a, 0xa1e8c, 0xa1e8e, 0xa1e90, 0xa1e92, 0xa1e94, 0xa1e9e, 0xa1ea0, 0xa1ea2, + 0xa1ea4, 0xa1ea6, 0xa1ea8, 0xa1eaa, 0xa1eac, 0xa1eae, 0xa1eb0, 0xa1eb2, 0xa1eb4, + 0xa1eb6, 0xa1eb8, 0xa1eba, 0xa1ebc, 0xa1ebe, 0xa1ec0, 0xa1ec2, 0xa1ec4, 0xa1ec6, + 0xa1ec8, 0xa1eca, 0xa1ecc, 0xa1ece, 0xa1ed0, 0xa1ed2, 0xa1ed4, 0xa1ed6, 0xa1ed8, + 0xa1eda, 0xa1edc, 0xa1ede, 0xa1ee0, 0xa1ee2, 0xa1ee4, 0xa1ee6, 0xa1ee8, 0xa1eea, + 0xa1eec, 0xa1eee, 0xa1ef0, 0xa1ef2, 0xa1ef4, 0xa1ef6, 0xa1ef8, 0xa1efa, 0xa1efc, + 0xa1efe, 0xa1f59, 0xa1f5b, 0xa1f5d, 0xa1f5f, 0xa2102, 0xa2107, 0xa2115, 0xa2124, + 0xa2126, 0xa2128, 0xa213e, 0xa213f, 0xa2145, 0xa2183, 0xa2c60, 0xa2c67, 0xa2c69, + 0xa2c6b, 0xa2c72, 0xa2c75, 0xa2c82, 0xa2c84, 0xa2c86, 0xa2c88, 0xa2c8a, 0xa2c8c, + 0xa2c8e, 0xa2c90, 0xa2c92, 0xa2c94, 0xa2c96, 0xa2c98, 0xa2c9a, 0xa2c9c, 0xa2c9e, + 0xa2ca0, 0xa2ca2, 0xa2ca4, 0xa2ca6, 0xa2ca8, 0xa2caa, 0xa2cac, 0xa2cae, 0xa2cb0, + 0xa2cb2, 0xa2cb4, 0xa2cb6, 0xa2cb8, 0xa2cba, 0xa2cbc, 0xa2cbe, 0xa2cc0, 0xa2cc2, + 0xa2cc4, 0xa2cc6, 0xa2cc8, 0xa2cca, 0xa2ccc, 0xa2cce, 0xa2cd0, 0xa2cd2, 0xa2cd4, + 0xa2cd6, 0xa2cd8, 0xa2cda, 0xa2cdc, 0xa2cde, 0xa2ce0, 0xa2ce2, 0xa2ceb, 0xa2ced, + 0xa2cf2, 0xaa640, 0xaa642, 0xaa644, 0xaa646, 0xaa648, 0xaa64a, 0xaa64c, 0xaa64e, + 0xaa650, 0xaa652, 0xaa654, 0xaa656, 0xaa658, 0xaa65a, 0xaa65c, 0xaa65e, 0xaa660, + 0xaa662, 0xaa664, 0xaa666, 0xaa668, 0xaa66a, 0xaa66c, 0xaa680, 0xaa682, 0xaa684, + 0xaa686, 0xaa688, 0xaa68a, 0xaa68c, 0xaa68e, 0xaa690, 0xaa692, 0xaa694, 0xaa696, + 0xaa698, 0xaa69a, 0xaa722, 0xaa724, 0xaa726, 0xaa728, 0xaa72a, 0xaa72c, 0xaa72e, + 0xaa732, 0xaa734, 0xaa736, 0xaa738, 0xaa73a, 0xaa73c, 0xaa73e, 0xaa740, 0xaa742, + 0xaa744, 0xaa746, 0xaa748, 0xaa74a, 0xaa74c, 0xaa74e, 0xaa750, 0xaa752, 0xaa754, + 0xaa756, 0xaa758, 0xaa75a, 0xaa75c, 0xaa75e, 0xaa760, 0xaa762, 0xaa764, 0xaa766, + 0xaa768, 0xaa76a, 0xaa76c, 0xaa76e, 0xaa779, 0xaa77b, 0xaa77d, 0xaa77e, 0xaa780, + 0xaa782, 0xaa784, 0xaa786, 0xaa78b, 0xaa78d, 0xaa790, 0xaa792, 0xaa796, 0xaa798, + 0xaa79a, 0xaa79c, 0xaa79e, 0xaa7a0, 0xaa7a2, 0xaa7a4, 0xaa7a6, 0xaa7a8, 0xaa7b6, + 0xb0100, 0xb0102, 0xb0104, 0xb0106, 0xb0108, 0xb010a, 0xb010c, 0xb010e, 0xb0110, + 0xb0112, 0xb0114, 0xb0116, 0xb0118, 0xb011a, 0xb011c, 0xb011e, 0xb0120, 0xb0122, + 0xb0124, 0xb0126, 0xb0128, 0xb012a, 0xb012c, 0xb012e, 0xb0130, 0xb0132, 0xb0134, + 0xb0136, 0xb0139, 0xb013b, 0xb013d, 0xb013f, 0xb0141, 0xb0143, 0xb0145, 0xb0147, + 0xb014a, 0xb014c, 0xb014e, 0xb0150, 0xb0152, 0xb0154, 0xb0156, 0xb0158, 0xb015a, + 0xb015c, 0xb015e, 0xb0160, 0xb0162, 0xb0164, 0xb0166, 0xb0168, 0xb016a, 0xb016c, + 0xb016e, 0xb0170, 0xb0172, 0xb0174, 0xb0176, 0xb0178, 0xb0179, 0xb017b, 0xb017d, + 0xb0181, 0xb0182, 0xb0184, 0xb0186, 0xb0187, 0xb0193, 0xb0194, 0xb019c, 0xb019d, + 0xb019f, 0xb01a0, 0xb01a2, 0xb01a4, 0xb01a6, 0xb01a7, 0xb01a9, 0xb01ac, 0xb01ae, + 0xb01af, 0xb01b5, 0xb01b7, 0xb01b8, 0xb01bc, 0xb01c4, 0xb01c7, 0xb01ca, 0xb01cd, + 0xb01cf, 0xb01d1, 0xb01d3, 0xb01d5, 0xb01d7, 0xb01d9, 0xb01db, 0xb01de, 0xb01e0, + 0xb01e2, 0xb01e4, 0xb01e6, 0xb01e8, 0xb01ea, 0xb01ec, 0xb01ee, 0xb01f1, 0xb01f4, + 0xb01fa, 0xb01fc, 0xb01fe, 0xb0200, 0xb0202, 0xb0204, 0xb0206, 0xb0208, 0xb020a, + 0xb020c, 0xb020e, 0xb0210, 0xb0212, 0xb0214, 0xb0216, 0xb0218, 0xb021a, 0xb021c, + 0xb021e, 0xb0220, 0xb0222, 0xb0224, 0xb0226, 0xb0228, 0xb022a, 0xb022c, 0xb022e, + 0xb0230, 0xb0232, 0xb023a, 0xb023b, 0xb023d, 0xb023e, 0xb0241, 0xb0248, 0xb024a, + 0xb024c, 0xb024e, 0xb0370, 0xb0372, 0xb0376, 0xb037f, 0xb0386, 0xb038c, 0xb038e, + 0xb038f, 0xb03cf, 0xb03d8, 0xb03da, 0xb03dc, 0xb03de, 0xb03e0, 0xb03e2, 0xb03e4, + 0xb03e6, 0xb03e8, 0xb03ea, 0xb03ec, 0xb03ee, 0xb03f4, 0xb03f7, 0xb03f9, 0xb03fa, + 0xb0460, 0xb0462, 0xb0464, 0xb0466, 0xb0468, 0xb046a, 0xb046c, 0xb046e, 0xb0470, + 0xb0472, 0xb0474, 0xb0476, 0xb0478, 0xb047a, 0xb047c, 0xb047e, 0xb0480, 0xb048a, + 0xb048c, 0xb048e, 0xb0490, 0xb0492, 0xb0494, 0xb0496, 0xb0498, 0xb049a, 0xb049c, + 0xb049e, 0xb04a0, 0xb04a2, 0xb04a4, 0xb04a6, 0xb04a8, 0xb04aa, 0xb04ac, 0xb04ae, + 0xb04b0, 0xb04b2, 0xb04b4, 0xb04b6, 0xb04b8, 0xb04ba, 0xb04bc, 0xb04be, 0xb04c0, + 0xb04c1, 0xb04c3, 0xb04c5, 0xb04c7, 0xb04c9, 0xb04cb, 0xb04cd, 0xb04d0, 0xb04d2, + 0xb04d4, 0xb04d6, 0xb04d8, 0xb04da, 0xb04dc, 0xb04de, 0xb04e0, 0xb04e2, 0xb04e4, + 0xb04e6, 0xb04e8, 0xb04ea, 0xb04ec, 0xb04ee, 0xb04f0, 0xb04f2, 0xb04f4, 0xb04f6, + 0xb04f8, 0xb04fa, 0xb04fc, 0xb04fe, 0xb0500, 0xb0502, 0xb0504, 0xb0506, 0xb0508, + 0xb050a, 0xb050c, 0xb050e, 0xb0510, 0xb0512, 0xb0514, 0xb0516, 0xb0518, 0xb051a, + 0xb051c, 0xb051e, 0xb0520, 0xb0522, 0xb0524, 0xb0526, 0xb0528, 0xb052a, 0xb052c, + 0xb052e, 0xb10c7, 0xb10cd, 0xb1e00, 0xb1e02, 0xb1e04, 0xb1e06, 0xb1e08, 0xb1e0a, + 0xb1e0c, 0xb1e0e, 0xb1e10, 0xb1e12, 0xb1e14, 0xb1e16, 0xb1e18, 0xb1e1a, 0xb1e1c, + 0xb1e1e, 0xb1e20, 0xb1e22, 0xb1e24, 0xb1e26, 0xb1e28, 0xb1e2a, 0xb1e2c, 0xb1e2e, + 0xb1e30, 0xb1e32, 0xb1e34, 0xb1e36, 0xb1e38, 0xb1e3a, 0xb1e3c, 0xb1e3e, 0xb1e40, + 0xb1e42, 0xb1e44, 0xb1e46, 0xb1e48, 0xb1e4a, 0xb1e4c, 0xb1e4e, 0xb1e50, 0xb1e52, + 0xb1e54, 0xb1e56, 0xb1e58, 0xb1e5a, 0xb1e5c, 0xb1e5e, 0xb1e60, 0xb1e62, 0xb1e64, + 0xb1e66, 0xb1e68, 0xb1e6a, 0xb1e6c, 0xb1e6e, 0xb1e70, 0xb1e72, 0xb1e74, 0xb1e76, + 0xb1e78, 0xb1e7a, 0xb1e7c, 0xb1e7e, 0xb1e80, 0xb1e82, 0xb1e84, 0xb1e86, 0xb1e88, + 0xb1e8a, 0xb1e8c, 0xb1e8e, 0xb1e90, 0xb1e92, 0xb1e94, 0xb1e9e, 0xb1ea0, 0xb1ea2, + 0xb1ea4, 0xb1ea6, 0xb1ea8, 0xb1eaa, 0xb1eac, 0xb1eae, 0xb1eb0, 0xb1eb2, 0xb1eb4, + 0xb1eb6, 0xb1eb8, 0xb1eba, 0xb1ebc, 0xb1ebe, 0xb1ec0, 0xb1ec2, 0xb1ec4, 0xb1ec6, + 0xb1ec8, 0xb1eca, 0xb1ecc, 0xb1ece, 0xb1ed0, 0xb1ed2, 0xb1ed4, 0xb1ed6, 0xb1ed8, + 0xb1eda, 0xb1edc, 0xb1ede, 0xb1ee0, 0xb1ee2, 0xb1ee4, 0xb1ee6, 0xb1ee8, 0xb1eea, + 0xb1eec, 0xb1eee, 0xb1ef0, 0xb1ef2, 0xb1ef4, 0xb1ef6, 0xb1ef8, 0xb1efa, 0xb1efc, + 0xb1efe, 0xb1f59, 0xb1f5b, 0xb1f5d, 0xb1f5f, 0xb2102, 0xb2107, 0xb2115, 0xb2124, + 0xb2126, 0xb2128, 0xb213e, 0xb213f, 0xb2145, 0xb2183, 0xb2c60, 0xb2c67, 0xb2c69, + 0xb2c6b, 0xb2c72, 0xb2c75, 0xb2c82, 0xb2c84, 0xb2c86, 0xb2c88, 0xb2c8a, 0xb2c8c, + 0xb2c8e, 0xb2c90, 0xb2c92, 0xb2c94, 0xb2c96, 0xb2c98, 0xb2c9a, 0xb2c9c, 0xb2c9e, + 0xb2ca0, 0xb2ca2, 0xb2ca4, 0xb2ca6, 0xb2ca8, 0xb2caa, 0xb2cac, 0xb2cae, 0xb2cb0, + 0xb2cb2, 0xb2cb4, 0xb2cb6, 0xb2cb8, 0xb2cba, 0xb2cbc, 0xb2cbe, 0xb2cc0, 0xb2cc2, + 0xb2cc4, 0xb2cc6, 0xb2cc8, 0xb2cca, 0xb2ccc, 0xb2cce, 0xb2cd0, 0xb2cd2, 0xb2cd4, + 0xb2cd6, 0xb2cd8, 0xb2cda, 0xb2cdc, 0xb2cde, 0xb2ce0, 0xb2ce2, 0xb2ceb, 0xb2ced, + 0xb2cf2, 0xba640, 0xba642, 0xba644, 0xba646, 0xba648, 0xba64a, 0xba64c, 0xba64e, + 0xba650, 0xba652, 0xba654, 0xba656, 0xba658, 0xba65a, 0xba65c, 0xba65e, 0xba660, + 0xba662, 0xba664, 0xba666, 0xba668, 0xba66a, 0xba66c, 0xba680, 0xba682, 0xba684, + 0xba686, 0xba688, 0xba68a, 0xba68c, 0xba68e, 0xba690, 0xba692, 0xba694, 0xba696, + 0xba698, 0xba69a, 0xba722, 0xba724, 0xba726, 0xba728, 0xba72a, 0xba72c, 0xba72e, + 0xba732, 0xba734, 0xba736, 0xba738, 0xba73a, 0xba73c, 0xba73e, 0xba740, 0xba742, + 0xba744, 0xba746, 0xba748, 0xba74a, 0xba74c, 0xba74e, 0xba750, 0xba752, 0xba754, + 0xba756, 0xba758, 0xba75a, 0xba75c, 0xba75e, 0xba760, 0xba762, 0xba764, 0xba766, + 0xba768, 0xba76a, 0xba76c, 0xba76e, 0xba779, 0xba77b, 0xba77d, 0xba77e, 0xba780, + 0xba782, 0xba784, 0xba786, 0xba78b, 0xba78d, 0xba790, 0xba792, 0xba796, 0xba798, + 0xba79a, 0xba79c, 0xba79e, 0xba7a0, 0xba7a2, 0xba7a4, 0xba7a6, 0xba7a8, 0xba7b6, + 0xc0100, 0xc0102, 0xc0104, 0xc0106, 0xc0108, 0xc010a, 0xc010c, 0xc010e, 0xc0110, + 0xc0112, 0xc0114, 0xc0116, 0xc0118, 0xc011a, 0xc011c, 0xc011e, 0xc0120, 0xc0122, + 0xc0124, 0xc0126, 0xc0128, 0xc012a, 0xc012c, 0xc012e, 0xc0130, 0xc0132, 0xc0134, + 0xc0136, 0xc0139, 0xc013b, 0xc013d, 0xc013f, 0xc0141, 0xc0143, 0xc0145, 0xc0147, + 0xc014a, 0xc014c, 0xc014e, 0xc0150, 0xc0152, 0xc0154, 0xc0156, 0xc0158, 0xc015a, + 0xc015c, 0xc015e, 0xc0160, 0xc0162, 0xc0164, 0xc0166, 0xc0168, 0xc016a, 0xc016c, + 0xc016e, 0xc0170, 0xc0172, 0xc0174, 0xc0176, 0xc0178, 0xc0179, 0xc017b, 0xc017d, + 0xc0181, 0xc0182, 0xc0184, 0xc0186, 0xc0187, 0xc0193, 0xc0194, 0xc019c, 0xc019d, + 0xc019f, 0xc01a0, 0xc01a2, 0xc01a4, 0xc01a6, 0xc01a7, 0xc01a9, 0xc01ac, 0xc01ae, + 0xc01af, 0xc01b5, 0xc01b7, 0xc01b8, 0xc01bc, 0xc01c4, 0xc01c7, 0xc01ca, 0xc01cd, + 0xc01cf, 0xc01d1, 0xc01d3, 0xc01d5, 0xc01d7, 0xc01d9, 0xc01db, 0xc01de, 0xc01e0, + 0xc01e2, 0xc01e4, 0xc01e6, 0xc01e8, 0xc01ea, 0xc01ec, 0xc01ee, 0xc01f1, 0xc01f4, + 0xc01fa, 0xc01fc, 0xc01fe, 0xc0200, 0xc0202, 0xc0204, 0xc0206, 0xc0208, 0xc020a, + 0xc020c, 0xc020e, 0xc0210, 0xc0212, 0xc0214, 0xc0216, 0xc0218, 0xc021a, 0xc021c, + 0xc021e, 0xc0220, 0xc0222, 0xc0224, 0xc0226, 0xc0228, 0xc022a, 0xc022c, 0xc022e, + 0xc0230, 0xc0232, 0xc023a, 0xc023b, 0xc023d, 0xc023e, 0xc0241, 0xc0248, 0xc024a, + 0xc024c, 0xc024e, 0xc0370, 0xc0372, 0xc0376, 0xc037f, 0xc0386, 0xc038c, 0xc038e, + 0xc038f, 0xc03cf, 0xc03d8, 0xc03da, 0xc03dc, 0xc03de, 0xc03e0, 0xc03e2, 0xc03e4, + 0xc03e6, 0xc03e8, 0xc03ea, 0xc03ec, 0xc03ee, 0xc03f4, 0xc03f7, 0xc03f9, 0xc03fa, + 0xc0460, 0xc0462, 0xc0464, 0xc0466, 0xc0468, 0xc046a, 0xc046c, 0xc046e, 0xc0470, + 0xc0472, 0xc0474, 0xc0476, 0xc0478, 0xc047a, 0xc047c, 0xc047e, 0xc0480, 0xc048a, + 0xc048c, 0xc048e, 0xc0490, 0xc0492, 0xc0494, 0xc0496, 0xc0498, 0xc049a, 0xc049c, + 0xc049e, 0xc04a0, 0xc04a2, 0xc04a4, 0xc04a6, 0xc04a8, 0xc04aa, 0xc04ac, 0xc04ae, + 0xc04b0, 0xc04b2, 0xc04b4, 0xc04b6, 0xc04b8, 0xc04ba, 0xc04bc, 0xc04be, 0xc04c0, + 0xc04c1, 0xc04c3, 0xc04c5, 0xc04c7, 0xc04c9, 0xc04cb, 0xc04cd, 0xc04d0, 0xc04d2, + 0xc04d4, 0xc04d6, 0xc04d8, 0xc04da, 0xc04dc, 0xc04de, 0xc04e0, 0xc04e2, 0xc04e4, + 0xc04e6, 0xc04e8, 0xc04ea, 0xc04ec, 0xc04ee, 0xc04f0, 0xc04f2, 0xc04f4, 0xc04f6, + 0xc04f8, 0xc04fa, 0xc04fc, 0xc04fe, 0xc0500, 0xc0502, 0xc0504, 0xc0506, 0xc0508, + 0xc050a, 0xc050c, 0xc050e, 0xc0510, 0xc0512, 0xc0514, 0xc0516, 0xc0518, 0xc051a, + 0xc051c, 0xc051e, 0xc0520, 0xc0522, 0xc0524, 0xc0526, 0xc0528, 0xc052a, 0xc052c, + 0xc052e, 0xc10c7, 0xc10cd, 0xc1e00, 0xc1e02, 0xc1e04, 0xc1e06, 0xc1e08, 0xc1e0a, + 0xc1e0c, 0xc1e0e, 0xc1e10, 0xc1e12, 0xc1e14, 0xc1e16, 0xc1e18, 0xc1e1a, 0xc1e1c, + 0xc1e1e, 0xc1e20, 0xc1e22, 0xc1e24, 0xc1e26, 0xc1e28, 0xc1e2a, 0xc1e2c, 0xc1e2e, + 0xc1e30, 0xc1e32, 0xc1e34, 0xc1e36, 0xc1e38, 0xc1e3a, 0xc1e3c, 0xc1e3e, 0xc1e40, + 0xc1e42, 0xc1e44, 0xc1e46, 0xc1e48, 0xc1e4a, 0xc1e4c, 0xc1e4e, 0xc1e50, 0xc1e52, + 0xc1e54, 0xc1e56, 0xc1e58, 0xc1e5a, 0xc1e5c, 0xc1e5e, 0xc1e60, 0xc1e62, 0xc1e64, + 0xc1e66, 0xc1e68, 0xc1e6a, 0xc1e6c, 0xc1e6e, 0xc1e70, 0xc1e72, 0xc1e74, 0xc1e76, + 0xc1e78, 0xc1e7a, 0xc1e7c, 0xc1e7e, 0xc1e80, 0xc1e82, 0xc1e84, 0xc1e86, 0xc1e88, + 0xc1e8a, 0xc1e8c, 0xc1e8e, 0xc1e90, 0xc1e92, 0xc1e94, 0xc1e9e, 0xc1ea0, 0xc1ea2, + 0xc1ea4, 0xc1ea6, 0xc1ea8, 0xc1eaa, 0xc1eac, 0xc1eae, 0xc1eb0, 0xc1eb2, 0xc1eb4, + 0xc1eb6, 0xc1eb8, 0xc1eba, 0xc1ebc, 0xc1ebe, 0xc1ec0, 0xc1ec2, 0xc1ec4, 0xc1ec6, + 0xc1ec8, 0xc1eca, 0xc1ecc, 0xc1ece, 0xc1ed0, 0xc1ed2, 0xc1ed4, 0xc1ed6, 0xc1ed8, + 0xc1eda, 0xc1edc, 0xc1ede, 0xc1ee0, 0xc1ee2, 0xc1ee4, 0xc1ee6, 0xc1ee8, 0xc1eea, + 0xc1eec, 0xc1eee, 0xc1ef0, 0xc1ef2, 0xc1ef4, 0xc1ef6, 0xc1ef8, 0xc1efa, 0xc1efc, + 0xc1efe, 0xc1f59, 0xc1f5b, 0xc1f5d, 0xc1f5f, 0xc2102, 0xc2107, 0xc2115, 0xc2124, + 0xc2126, 0xc2128, 0xc213e, 0xc213f, 0xc2145, 0xc2183, 0xc2c60, 0xc2c67, 0xc2c69, + 0xc2c6b, 0xc2c72, 0xc2c75, 0xc2c82, 0xc2c84, 0xc2c86, 0xc2c88, 0xc2c8a, 0xc2c8c, + 0xc2c8e, 0xc2c90, 0xc2c92, 0xc2c94, 0xc2c96, 0xc2c98, 0xc2c9a, 0xc2c9c, 0xc2c9e, + 0xc2ca0, 0xc2ca2, 0xc2ca4, 0xc2ca6, 0xc2ca8, 0xc2caa, 0xc2cac, 0xc2cae, 0xc2cb0, + 0xc2cb2, 0xc2cb4, 0xc2cb6, 0xc2cb8, 0xc2cba, 0xc2cbc, 0xc2cbe, 0xc2cc0, 0xc2cc2, + 0xc2cc4, 0xc2cc6, 0xc2cc8, 0xc2cca, 0xc2ccc, 0xc2cce, 0xc2cd0, 0xc2cd2, 0xc2cd4, + 0xc2cd6, 0xc2cd8, 0xc2cda, 0xc2cdc, 0xc2cde, 0xc2ce0, 0xc2ce2, 0xc2ceb, 0xc2ced, + 0xc2cf2, 0xca640, 0xca642, 0xca644, 0xca646, 0xca648, 0xca64a, 0xca64c, 0xca64e, + 0xca650, 0xca652, 0xca654, 0xca656, 0xca658, 0xca65a, 0xca65c, 0xca65e, 0xca660, + 0xca662, 0xca664, 0xca666, 0xca668, 0xca66a, 0xca66c, 0xca680, 0xca682, 0xca684, + 0xca686, 0xca688, 0xca68a, 0xca68c, 0xca68e, 0xca690, 0xca692, 0xca694, 0xca696, + 0xca698, 0xca69a, 0xca722, 0xca724, 0xca726, 0xca728, 0xca72a, 0xca72c, 0xca72e, + 0xca732, 0xca734, 0xca736, 0xca738, 0xca73a, 0xca73c, 0xca73e, 0xca740, 0xca742, + 0xca744, 0xca746, 0xca748, 0xca74a, 0xca74c, 0xca74e, 0xca750, 0xca752, 0xca754, + 0xca756, 0xca758, 0xca75a, 0xca75c, 0xca75e, 0xca760, 0xca762, 0xca764, 0xca766, + 0xca768, 0xca76a, 0xca76c, 0xca76e, 0xca779, 0xca77b, 0xca77d, 0xca77e, 0xca780, + 0xca782, 0xca784, 0xca786, 0xca78b, 0xca78d, 0xca790, 0xca792, 0xca796, 0xca798, + 0xca79a, 0xca79c, 0xca79e, 0xca7a0, 0xca7a2, 0xca7a4, 0xca7a6, 0xca7a8, 0xca7b6, + 0xd0100, 0xd0102, 0xd0104, 0xd0106, 0xd0108, 0xd010a, 0xd010c, 0xd010e, 0xd0110, + 0xd0112, 0xd0114, 0xd0116, 0xd0118, 0xd011a, 0xd011c, 0xd011e, 0xd0120, 0xd0122, + 0xd0124, 0xd0126, 0xd0128, 0xd012a, 0xd012c, 0xd012e, 0xd0130, 0xd0132, 0xd0134, + 0xd0136, 0xd0139, 0xd013b, 0xd013d, 0xd013f, 0xd0141, 0xd0143, 0xd0145, 0xd0147, + 0xd014a, 0xd014c, 0xd014e, 0xd0150, 0xd0152, 0xd0154, 0xd0156, 0xd0158, 0xd015a, + 0xd015c, 0xd015e, 0xd0160, 0xd0162, 0xd0164, 0xd0166, 0xd0168, 0xd016a, 0xd016c, + 0xd016e, 0xd0170, 0xd0172, 0xd0174, 0xd0176, 0xd0178, 0xd0179, 0xd017b, 0xd017d, + 0xd0181, 0xd0182, 0xd0184, 0xd0186, 0xd0187, 0xd0193, 0xd0194, 0xd019c, 0xd019d, + 0xd019f, 0xd01a0, 0xd01a2, 0xd01a4, 0xd01a6, 0xd01a7, 0xd01a9, 0xd01ac, 0xd01ae, + 0xd01af, 0xd01b5, 0xd01b7, 0xd01b8, 0xd01bc, 0xd01c4, 0xd01c7, 0xd01ca, 0xd01cd, + 0xd01cf, 0xd01d1, 0xd01d3, 0xd01d5, 0xd01d7, 0xd01d9, 0xd01db, 0xd01de, 0xd01e0, + 0xd01e2, 0xd01e4, 0xd01e6, 0xd01e8, 0xd01ea, 0xd01ec, 0xd01ee, 0xd01f1, 0xd01f4, + 0xd01fa, 0xd01fc, 0xd01fe, 0xd0200, 0xd0202, 0xd0204, 0xd0206, 0xd0208, 0xd020a, + 0xd020c, 0xd020e, 0xd0210, 0xd0212, 0xd0214, 0xd0216, 0xd0218, 0xd021a, 0xd021c, + 0xd021e, 0xd0220, 0xd0222, 0xd0224, 0xd0226, 0xd0228, 0xd022a, 0xd022c, 0xd022e, + 0xd0230, 0xd0232, 0xd023a, 0xd023b, 0xd023d, 0xd023e, 0xd0241, 0xd0248, 0xd024a, + 0xd024c, 0xd024e, 0xd0370, 0xd0372, 0xd0376, 0xd037f, 0xd0386, 0xd038c, 0xd038e, + 0xd038f, 0xd03cf, 0xd03d8, 0xd03da, 0xd03dc, 0xd03de, 0xd03e0, 0xd03e2, 0xd03e4, + 0xd03e6, 0xd03e8, 0xd03ea, 0xd03ec, 0xd03ee, 0xd03f4, 0xd03f7, 0xd03f9, 0xd03fa, + 0xd0460, 0xd0462, 0xd0464, 0xd0466, 0xd0468, 0xd046a, 0xd046c, 0xd046e, 0xd0470, + 0xd0472, 0xd0474, 0xd0476, 0xd0478, 0xd047a, 0xd047c, 0xd047e, 0xd0480, 0xd048a, + 0xd048c, 0xd048e, 0xd0490, 0xd0492, 0xd0494, 0xd0496, 0xd0498, 0xd049a, 0xd049c, + 0xd049e, 0xd04a0, 0xd04a2, 0xd04a4, 0xd04a6, 0xd04a8, 0xd04aa, 0xd04ac, 0xd04ae, + 0xd04b0, 0xd04b2, 0xd04b4, 0xd04b6, 0xd04b8, 0xd04ba, 0xd04bc, 0xd04be, 0xd04c0, + 0xd04c1, 0xd04c3, 0xd04c5, 0xd04c7, 0xd04c9, 0xd04cb, 0xd04cd, 0xd04d0, 0xd04d2, + 0xd04d4, 0xd04d6, 0xd04d8, 0xd04da, 0xd04dc, 0xd04de, 0xd04e0, 0xd04e2, 0xd04e4, + 0xd04e6, 0xd04e8, 0xd04ea, 0xd04ec, 0xd04ee, 0xd04f0, 0xd04f2, 0xd04f4, 0xd04f6, + 0xd04f8, 0xd04fa, 0xd04fc, 0xd04fe, 0xd0500, 0xd0502, 0xd0504, 0xd0506, 0xd0508, + 0xd050a, 0xd050c, 0xd050e, 0xd0510, 0xd0512, 0xd0514, 0xd0516, 0xd0518, 0xd051a, + 0xd051c, 0xd051e, 0xd0520, 0xd0522, 0xd0524, 0xd0526, 0xd0528, 0xd052a, 0xd052c, + 0xd052e, 0xd10c7, 0xd10cd, 0xd1e00, 0xd1e02, 0xd1e04, 0xd1e06, 0xd1e08, 0xd1e0a, + 0xd1e0c, 0xd1e0e, 0xd1e10, 0xd1e12, 0xd1e14, 0xd1e16, 0xd1e18, 0xd1e1a, 0xd1e1c, + 0xd1e1e, 0xd1e20, 0xd1e22, 0xd1e24, 0xd1e26, 0xd1e28, 0xd1e2a, 0xd1e2c, 0xd1e2e, + 0xd1e30, 0xd1e32, 0xd1e34, 0xd1e36, 0xd1e38, 0xd1e3a, 0xd1e3c, 0xd1e3e, 0xd1e40, + 0xd1e42, 0xd1e44, 0xd1e46, 0xd1e48, 0xd1e4a, 0xd1e4c, 0xd1e4e, 0xd1e50, 0xd1e52, + 0xd1e54, 0xd1e56, 0xd1e58, 0xd1e5a, 0xd1e5c, 0xd1e5e, 0xd1e60, 0xd1e62, 0xd1e64, + 0xd1e66, 0xd1e68, 0xd1e6a, 0xd1e6c, 0xd1e6e, 0xd1e70, 0xd1e72, 0xd1e74, 0xd1e76, + 0xd1e78, 0xd1e7a, 0xd1e7c, 0xd1e7e, 0xd1e80, 0xd1e82, 0xd1e84, 0xd1e86, 0xd1e88, + 0xd1e8a, 0xd1e8c, 0xd1e8e, 0xd1e90, 0xd1e92, 0xd1e94, 0xd1e9e, 0xd1ea0, 0xd1ea2, + 0xd1ea4, 0xd1ea6, 0xd1ea8, 0xd1eaa, 0xd1eac, 0xd1eae, 0xd1eb0, 0xd1eb2, 0xd1eb4, + 0xd1eb6, 0xd1eb8, 0xd1eba, 0xd1ebc, 0xd1ebe, 0xd1ec0, 0xd1ec2, 0xd1ec4, 0xd1ec6, + 0xd1ec8, 0xd1eca, 0xd1ecc, 0xd1ece, 0xd1ed0, 0xd1ed2, 0xd1ed4, 0xd1ed6, 0xd1ed8, + 0xd1eda, 0xd1edc, 0xd1ede, 0xd1ee0, 0xd1ee2, 0xd1ee4, 0xd1ee6, 0xd1ee8, 0xd1eea, + 0xd1eec, 0xd1eee, 0xd1ef0, 0xd1ef2, 0xd1ef4, 0xd1ef6, 0xd1ef8, 0xd1efa, 0xd1efc, + 0xd1efe, 0xd1f59, 0xd1f5b, 0xd1f5d, 0xd1f5f, 0xd2102, 0xd2107, 0xd2115, 0xd2124, + 0xd2126, 0xd2128, 0xd213e, 0xd213f, 0xd2145, 0xd2183, 0xd2c60, 0xd2c67, 0xd2c69, + 0xd2c6b, 0xd2c72, 0xd2c75, 0xd2c82, 0xd2c84, 0xd2c86, 0xd2c88, 0xd2c8a, 0xd2c8c, + 0xd2c8e, 0xd2c90, 0xd2c92, 0xd2c94, 0xd2c96, 0xd2c98, 0xd2c9a, 0xd2c9c, 0xd2c9e, + 0xd2ca0, 0xd2ca2, 0xd2ca4, 0xd2ca6, 0xd2ca8, 0xd2caa, 0xd2cac, 0xd2cae, 0xd2cb0, + 0xd2cb2, 0xd2cb4, 0xd2cb6, 0xd2cb8, 0xd2cba, 0xd2cbc, 0xd2cbe, 0xd2cc0, 0xd2cc2, + 0xd2cc4, 0xd2cc6, 0xd2cc8, 0xd2cca, 0xd2ccc, 0xd2cce, 0xd2cd0, 0xd2cd2, 0xd2cd4, + 0xd2cd6, 0xd2cd8, 0xd2cda, 0xd2cdc, 0xd2cde, 0xd2ce0, 0xd2ce2, 0xd2ceb, 0xd2ced, + 0xd2cf2, 0xda640, 0xda642, 0xda644, 0xda646, 0xda648, 0xda64a, 0xda64c, 0xda64e, + 0xda650, 0xda652, 0xda654, 0xda656, 0xda658, 0xda65a, 0xda65c, 0xda65e, 0xda660, + 0xda662, 0xda664, 0xda666, 0xda668, 0xda66a, 0xda66c, 0xda680, 0xda682, 0xda684, + 0xda686, 0xda688, 0xda68a, 0xda68c, 0xda68e, 0xda690, 0xda692, 0xda694, 0xda696, + 0xda698, 0xda69a, 0xda722, 0xda724, 0xda726, 0xda728, 0xda72a, 0xda72c, 0xda72e, + 0xda732, 0xda734, 0xda736, 0xda738, 0xda73a, 0xda73c, 0xda73e, 0xda740, 0xda742, + 0xda744, 0xda746, 0xda748, 0xda74a, 0xda74c, 0xda74e, 0xda750, 0xda752, 0xda754, + 0xda756, 0xda758, 0xda75a, 0xda75c, 0xda75e, 0xda760, 0xda762, 0xda764, 0xda766, + 0xda768, 0xda76a, 0xda76c, 0xda76e, 0xda779, 0xda77b, 0xda77d, 0xda77e, 0xda780, + 0xda782, 0xda784, 0xda786, 0xda78b, 0xda78d, 0xda790, 0xda792, 0xda796, 0xda798, + 0xda79a, 0xda79c, 0xda79e, 0xda7a0, 0xda7a2, 0xda7a4, 0xda7a6, 0xda7a8, 0xda7b6, + 0xe0100, 0xe0102, 0xe0104, 0xe0106, 0xe0108, 0xe010a, 0xe010c, 0xe010e, 0xe0110, + 0xe0112, 0xe0114, 0xe0116, 0xe0118, 0xe011a, 0xe011c, 0xe011e, 0xe0120, 0xe0122, + 0xe0124, 0xe0126, 0xe0128, 0xe012a, 0xe012c, 0xe012e, 0xe0130, 0xe0132, 0xe0134, + 0xe0136, 0xe0139, 0xe013b, 0xe013d, 0xe013f, 0xe0141, 0xe0143, 0xe0145, 0xe0147, + 0xe014a, 0xe014c, 0xe014e, 0xe0150, 0xe0152, 0xe0154, 0xe0156, 0xe0158, 0xe015a, + 0xe015c, 0xe015e, 0xe0160, 0xe0162, 0xe0164, 0xe0166, 0xe0168, 0xe016a, 0xe016c, + 0xe016e, 0xe0170, 0xe0172, 0xe0174, 0xe0176, 0xe0178, 0xe0179, 0xe017b, 0xe017d, + 0xe0181, 0xe0182, 0xe0184, 0xe0186, 0xe0187, 0xe0193, 0xe0194, 0xe019c, 0xe019d, + 0xe019f, 0xe01a0, 0xe01a2, 0xe01a4, 0xe01a6, 0xe01a7, 0xe01a9, 0xe01ac, 0xe01ae, + 0xe01af, 0xe01b5, 0xe01b7, 0xe01b8, 0xe01bc, 0xe01c4, 0xe01c7, 0xe01ca, 0xe01cd, + 0xe01cf, 0xe01d1, 0xe01d3, 0xe01d5, 0xe01d7, 0xe01d9, 0xe01db, 0xe01de, 0xe01e0, + 0xe01e2, 0xe01e4, 0xe01e6, 0xe01e8, 0xe01ea, 0xe01ec, 0xe01ee, 0xe01f1, 0xe01f4, + 0xe01fa, 0xe01fc, 0xe01fe, 0xe0200, 0xe0202, 0xe0204, 0xe0206, 0xe0208, 0xe020a, + 0xe020c, 0xe020e, 0xe0210, 0xe0212, 0xe0214, 0xe0216, 0xe0218, 0xe021a, 0xe021c, + 0xe021e, 0xe0220, 0xe0222, 0xe0224, 0xe0226, 0xe0228, 0xe022a, 0xe022c, 0xe022e, + 0xe0230, 0xe0232, 0xe023a, 0xe023b, 0xe023d, 0xe023e, 0xe0241, 0xe0248, 0xe024a, + 0xe024c, 0xe024e, 0xe0370, 0xe0372, 0xe0376, 0xe037f, 0xe0386, 0xe038c, 0xe038e, + 0xe038f, 0xe03cf, 0xe03d8, 0xe03da, 0xe03dc, 0xe03de, 0xe03e0, 0xe03e2, 0xe03e4, + 0xe03e6, 0xe03e8, 0xe03ea, 0xe03ec, 0xe03ee, 0xe03f4, 0xe03f7, 0xe03f9, 0xe03fa, + 0xe0460, 0xe0462, 0xe0464, 0xe0466, 0xe0468, 0xe046a, 0xe046c, 0xe046e, 0xe0470, + 0xe0472, 0xe0474, 0xe0476, 0xe0478, 0xe047a, 0xe047c, 0xe047e, 0xe0480, 0xe048a, + 0xe048c, 0xe048e, 0xe0490, 0xe0492, 0xe0494, 0xe0496, 0xe0498, 0xe049a, 0xe049c, + 0xe049e, 0xe04a0, 0xe04a2, 0xe04a4, 0xe04a6, 0xe04a8, 0xe04aa, 0xe04ac, 0xe04ae, + 0xe04b0, 0xe04b2, 0xe04b4, 0xe04b6, 0xe04b8, 0xe04ba, 0xe04bc, 0xe04be, 0xe04c0, + 0xe04c1, 0xe04c3, 0xe04c5, 0xe04c7, 0xe04c9, 0xe04cb, 0xe04cd, 0xe04d0, 0xe04d2, + 0xe04d4, 0xe04d6, 0xe04d8, 0xe04da, 0xe04dc, 0xe04de, 0xe04e0, 0xe04e2, 0xe04e4, + 0xe04e6, 0xe04e8, 0xe04ea, 0xe04ec, 0xe04ee, 0xe04f0, 0xe04f2, 0xe04f4, 0xe04f6, + 0xe04f8, 0xe04fa, 0xe04fc, 0xe04fe, 0xe0500, 0xe0502, 0xe0504, 0xe0506, 0xe0508, + 0xe050a, 0xe050c, 0xe050e, 0xe0510, 0xe0512, 0xe0514, 0xe0516, 0xe0518, 0xe051a, + 0xe051c, 0xe051e, 0xe0520, 0xe0522, 0xe0524, 0xe0526, 0xe0528, 0xe052a, 0xe052c, + 0xe052e, 0xe10c7, 0xe10cd, 0xe1e00, 0xe1e02, 0xe1e04, 0xe1e06, 0xe1e08, 0xe1e0a, + 0xe1e0c, 0xe1e0e, 0xe1e10, 0xe1e12, 0xe1e14, 0xe1e16, 0xe1e18, 0xe1e1a, 0xe1e1c, + 0xe1e1e, 0xe1e20, 0xe1e22, 0xe1e24, 0xe1e26, 0xe1e28, 0xe1e2a, 0xe1e2c, 0xe1e2e, + 0xe1e30, 0xe1e32, 0xe1e34, 0xe1e36, 0xe1e38, 0xe1e3a, 0xe1e3c, 0xe1e3e, 0xe1e40, + 0xe1e42, 0xe1e44, 0xe1e46, 0xe1e48, 0xe1e4a, 0xe1e4c, 0xe1e4e, 0xe1e50, 0xe1e52, + 0xe1e54, 0xe1e56, 0xe1e58, 0xe1e5a, 0xe1e5c, 0xe1e5e, 0xe1e60, 0xe1e62, 0xe1e64, + 0xe1e66, 0xe1e68, 0xe1e6a, 0xe1e6c, 0xe1e6e, 0xe1e70, 0xe1e72, 0xe1e74, 0xe1e76, + 0xe1e78, 0xe1e7a, 0xe1e7c, 0xe1e7e, 0xe1e80, 0xe1e82, 0xe1e84, 0xe1e86, 0xe1e88, + 0xe1e8a, 0xe1e8c, 0xe1e8e, 0xe1e90, 0xe1e92, 0xe1e94, 0xe1e9e, 0xe1ea0, 0xe1ea2, + 0xe1ea4, 0xe1ea6, 0xe1ea8, 0xe1eaa, 0xe1eac, 0xe1eae, 0xe1eb0, 0xe1eb2, 0xe1eb4, + 0xe1eb6, 0xe1eb8, 0xe1eba, 0xe1ebc, 0xe1ebe, 0xe1ec0, 0xe1ec2, 0xe1ec4, 0xe1ec6, + 0xe1ec8, 0xe1eca, 0xe1ecc, 0xe1ece, 0xe1ed0, 0xe1ed2, 0xe1ed4, 0xe1ed6, 0xe1ed8, + 0xe1eda, 0xe1edc, 0xe1ede, 0xe1ee0, 0xe1ee2, 0xe1ee4, 0xe1ee6, 0xe1ee8, 0xe1eea, + 0xe1eec, 0xe1eee, 0xe1ef0, 0xe1ef2, 0xe1ef4, 0xe1ef6, 0xe1ef8, 0xe1efa, 0xe1efc, + 0xe1efe, 0xe1f59, 0xe1f5b, 0xe1f5d, 0xe1f5f, 0xe2102, 0xe2107, 0xe2115, 0xe2124, + 0xe2126, 0xe2128, 0xe213e, 0xe213f, 0xe2145, 0xe2183, 0xe2c60, 0xe2c67, 0xe2c69, + 0xe2c6b, 0xe2c72, 0xe2c75, 0xe2c82, 0xe2c84, 0xe2c86, 0xe2c88, 0xe2c8a, 0xe2c8c, + 0xe2c8e, 0xe2c90, 0xe2c92, 0xe2c94, 0xe2c96, 0xe2c98, 0xe2c9a, 0xe2c9c, 0xe2c9e, + 0xe2ca0, 0xe2ca2, 0xe2ca4, 0xe2ca6, 0xe2ca8, 0xe2caa, 0xe2cac, 0xe2cae, 0xe2cb0, + 0xe2cb2, 0xe2cb4, 0xe2cb6, 0xe2cb8, 0xe2cba, 0xe2cbc, 0xe2cbe, 0xe2cc0, 0xe2cc2, + 0xe2cc4, 0xe2cc6, 0xe2cc8, 0xe2cca, 0xe2ccc, 0xe2cce, 0xe2cd0, 0xe2cd2, 0xe2cd4, + 0xe2cd6, 0xe2cd8, 0xe2cda, 0xe2cdc, 0xe2cde, 0xe2ce0, 0xe2ce2, 0xe2ceb, 0xe2ced, + 0xe2cf2, 0xea640, 0xea642, 0xea644, 0xea646, 0xea648, 0xea64a, 0xea64c, 0xea64e, + 0xea650, 0xea652, 0xea654, 0xea656, 0xea658, 0xea65a, 0xea65c, 0xea65e, 0xea660, + 0xea662, 0xea664, 0xea666, 0xea668, 0xea66a, 0xea66c, 0xea680, 0xea682, 0xea684, + 0xea686, 0xea688, 0xea68a, 0xea68c, 0xea68e, 0xea690, 0xea692, 0xea694, 0xea696, + 0xea698, 0xea69a, 0xea722, 0xea724, 0xea726, 0xea728, 0xea72a, 0xea72c, 0xea72e, + 0xea732, 0xea734, 0xea736, 0xea738, 0xea73a, 0xea73c, 0xea73e, 0xea740, 0xea742, + 0xea744, 0xea746, 0xea748, 0xea74a, 0xea74c, 0xea74e, 0xea750, 0xea752, 0xea754, + 0xea756, 0xea758, 0xea75a, 0xea75c, 0xea75e, 0xea760, 0xea762, 0xea764, 0xea766, + 0xea768, 0xea76a, 0xea76c, 0xea76e, 0xea779, 0xea77b, 0xea77d, 0xea77e, 0xea780, + 0xea782, 0xea784, 0xea786, 0xea78b, 0xea78d, 0xea790, 0xea792, 0xea796, 0xea798, + 0xea79a, 0xea79c, 0xea79e, 0xea7a0, 0xea7a2, 0xea7a4, 0xea7a6, 0xea7a8, 0xea7b6, + 0xf0100, 0xf0102, 0xf0104, 0xf0106, 0xf0108, 0xf010a, 0xf010c, 0xf010e, 0xf0110, + 0xf0112, 0xf0114, 0xf0116, 0xf0118, 0xf011a, 0xf011c, 0xf011e, 0xf0120, 0xf0122, + 0xf0124, 0xf0126, 0xf0128, 0xf012a, 0xf012c, 0xf012e, 0xf0130, 0xf0132, 0xf0134, + 0xf0136, 0xf0139, 0xf013b, 0xf013d, 0xf013f, 0xf0141, 0xf0143, 0xf0145, 0xf0147, + 0xf014a, 0xf014c, 0xf014e, 0xf0150, 0xf0152, 0xf0154, 0xf0156, 0xf0158, 0xf015a, + 0xf015c, 0xf015e, 0xf0160, 0xf0162, 0xf0164, 0xf0166, 0xf0168, 0xf016a, 0xf016c, + 0xf016e, 0xf0170, 0xf0172, 0xf0174, 0xf0176, 0xf0178, 0xf0179, 0xf017b, 0xf017d, + 0xf0181, 0xf0182, 0xf0184, 0xf0186, 0xf0187, 0xf0193, 0xf0194, 0xf019c, 0xf019d, + 0xf019f, 0xf01a0, 0xf01a2, 0xf01a4, 0xf01a6, 0xf01a7, 0xf01a9, 0xf01ac, 0xf01ae, + 0xf01af, 0xf01b5, 0xf01b7, 0xf01b8, 0xf01bc, 0xf01c4, 0xf01c7, 0xf01ca, 0xf01cd, + 0xf01cf, 0xf01d1, 0xf01d3, 0xf01d5, 0xf01d7, 0xf01d9, 0xf01db, 0xf01de, 0xf01e0, + 0xf01e2, 0xf01e4, 0xf01e6, 0xf01e8, 0xf01ea, 0xf01ec, 0xf01ee, 0xf01f1, 0xf01f4, + 0xf01fa, 0xf01fc, 0xf01fe, 0xf0200, 0xf0202, 0xf0204, 0xf0206, 0xf0208, 0xf020a, + 0xf020c, 0xf020e, 0xf0210, 0xf0212, 0xf0214, 0xf0216, 0xf0218, 0xf021a, 0xf021c, + 0xf021e, 0xf0220, 0xf0222, 0xf0224, 0xf0226, 0xf0228, 0xf022a, 0xf022c, 0xf022e, + 0xf0230, 0xf0232, 0xf023a, 0xf023b, 0xf023d, 0xf023e, 0xf0241, 0xf0248, 0xf024a, + 0xf024c, 0xf024e, 0xf0370, 0xf0372, 0xf0376, 0xf037f, 0xf0386, 0xf038c, 0xf038e, + 0xf038f, 0xf03cf, 0xf03d8, 0xf03da, 0xf03dc, 0xf03de, 0xf03e0, 0xf03e2, 0xf03e4, + 0xf03e6, 0xf03e8, 0xf03ea, 0xf03ec, 0xf03ee, 0xf03f4, 0xf03f7, 0xf03f9, 0xf03fa, + 0xf0460, 0xf0462, 0xf0464, 0xf0466, 0xf0468, 0xf046a, 0xf046c, 0xf046e, 0xf0470, + 0xf0472, 0xf0474, 0xf0476, 0xf0478, 0xf047a, 0xf047c, 0xf047e, 0xf0480, 0xf048a, + 0xf048c, 0xf048e, 0xf0490, 0xf0492, 0xf0494, 0xf0496, 0xf0498, 0xf049a, 0xf049c, + 0xf049e, 0xf04a0, 0xf04a2, 0xf04a4, 0xf04a6, 0xf04a8, 0xf04aa, 0xf04ac, 0xf04ae, + 0xf04b0, 0xf04b2, 0xf04b4, 0xf04b6, 0xf04b8, 0xf04ba, 0xf04bc, 0xf04be, 0xf04c0, + 0xf04c1, 0xf04c3, 0xf04c5, 0xf04c7, 0xf04c9, 0xf04cb, 0xf04cd, 0xf04d0, 0xf04d2, + 0xf04d4, 0xf04d6, 0xf04d8, 0xf04da, 0xf04dc, 0xf04de, 0xf04e0, 0xf04e2, 0xf04e4, + 0xf04e6, 0xf04e8, 0xf04ea, 0xf04ec, 0xf04ee, 0xf04f0, 0xf04f2, 0xf04f4, 0xf04f6, + 0xf04f8, 0xf04fa, 0xf04fc, 0xf04fe, 0xf0500, 0xf0502, 0xf0504, 0xf0506, 0xf0508, + 0xf050a, 0xf050c, 0xf050e, 0xf0510, 0xf0512, 0xf0514, 0xf0516, 0xf0518, 0xf051a, + 0xf051c, 0xf051e, 0xf0520, 0xf0522, 0xf0524, 0xf0526, 0xf0528, 0xf052a, 0xf052c, + 0xf052e, 0xf10c7, 0xf10cd, 0xf1e00, 0xf1e02, 0xf1e04, 0xf1e06, 0xf1e08, 0xf1e0a, + 0xf1e0c, 0xf1e0e, 0xf1e10, 0xf1e12, 0xf1e14, 0xf1e16, 0xf1e18, 0xf1e1a, 0xf1e1c, + 0xf1e1e, 0xf1e20, 0xf1e22, 0xf1e24, 0xf1e26, 0xf1e28, 0xf1e2a, 0xf1e2c, 0xf1e2e, + 0xf1e30, 0xf1e32, 0xf1e34, 0xf1e36, 0xf1e38, 0xf1e3a, 0xf1e3c, 0xf1e3e, 0xf1e40, + 0xf1e42, 0xf1e44, 0xf1e46, 0xf1e48, 0xf1e4a, 0xf1e4c, 0xf1e4e, 0xf1e50, 0xf1e52, + 0xf1e54, 0xf1e56, 0xf1e58, 0xf1e5a, 0xf1e5c, 0xf1e5e, 0xf1e60, 0xf1e62, 0xf1e64, + 0xf1e66, 0xf1e68, 0xf1e6a, 0xf1e6c, 0xf1e6e, 0xf1e70, 0xf1e72, 0xf1e74, 0xf1e76, + 0xf1e78, 0xf1e7a, 0xf1e7c, 0xf1e7e, 0xf1e80, 0xf1e82, 0xf1e84, 0xf1e86, 0xf1e88, + 0xf1e8a, 0xf1e8c, 0xf1e8e, 0xf1e90, 0xf1e92, 0xf1e94, 0xf1e9e, 0xf1ea0, 0xf1ea2, + 0xf1ea4, 0xf1ea6, 0xf1ea8, 0xf1eaa, 0xf1eac, 0xf1eae, 0xf1eb0, 0xf1eb2, 0xf1eb4, + 0xf1eb6, 0xf1eb8, 0xf1eba, 0xf1ebc, 0xf1ebe, 0xf1ec0, 0xf1ec2, 0xf1ec4, 0xf1ec6, + 0xf1ec8, 0xf1eca, 0xf1ecc, 0xf1ece, 0xf1ed0, 0xf1ed2, 0xf1ed4, 0xf1ed6, 0xf1ed8, + 0xf1eda, 0xf1edc, 0xf1ede, 0xf1ee0, 0xf1ee2, 0xf1ee4, 0xf1ee6, 0xf1ee8, 0xf1eea, + 0xf1eec, 0xf1eee, 0xf1ef0, 0xf1ef2, 0xf1ef4, 0xf1ef6, 0xf1ef8, 0xf1efa, 0xf1efc, + 0xf1efe, 0xf1f59, 0xf1f5b, 0xf1f5d, 0xf1f5f, 0xf2102, 0xf2107, 0xf2115, 0xf2124, + 0xf2126, 0xf2128, 0xf213e, 0xf213f, 0xf2145, 0xf2183, 0xf2c60, 0xf2c67, 0xf2c69, + 0xf2c6b, 0xf2c72, 0xf2c75, 0xf2c82, 0xf2c84, 0xf2c86, 0xf2c88, 0xf2c8a, 0xf2c8c, + 0xf2c8e, 0xf2c90, 0xf2c92, 0xf2c94, 0xf2c96, 0xf2c98, 0xf2c9a, 0xf2c9c, 0xf2c9e, + 0xf2ca0, 0xf2ca2, 0xf2ca4, 0xf2ca6, 0xf2ca8, 0xf2caa, 0xf2cac, 0xf2cae, 0xf2cb0, + 0xf2cb2, 0xf2cb4, 0xf2cb6, 0xf2cb8, 0xf2cba, 0xf2cbc, 0xf2cbe, 0xf2cc0, 0xf2cc2, + 0xf2cc4, 0xf2cc6, 0xf2cc8, 0xf2cca, 0xf2ccc, 0xf2cce, 0xf2cd0, 0xf2cd2, 0xf2cd4, + 0xf2cd6, 0xf2cd8, 0xf2cda, 0xf2cdc, 0xf2cde, 0xf2ce0, 0xf2ce2, 0xf2ceb, 0xf2ced, + 0xf2cf2, 0xfa640, 0xfa642, 0xfa644, 0xfa646, 0xfa648, 0xfa64a, 0xfa64c, 0xfa64e, + 0xfa650, 0xfa652, 0xfa654, 0xfa656, 0xfa658, 0xfa65a, 0xfa65c, 0xfa65e, 0xfa660, + 0xfa662, 0xfa664, 0xfa666, 0xfa668, 0xfa66a, 0xfa66c, 0xfa680, 0xfa682, 0xfa684, + 0xfa686, 0xfa688, 0xfa68a, 0xfa68c, 0xfa68e, 0xfa690, 0xfa692, 0xfa694, 0xfa696, + 0xfa698, 0xfa69a, 0xfa722, 0xfa724, 0xfa726, 0xfa728, 0xfa72a, 0xfa72c, 0xfa72e, + 0xfa732, 0xfa734, 0xfa736, 0xfa738, 0xfa73a, 0xfa73c, 0xfa73e, 0xfa740, 0xfa742, + 0xfa744, 0xfa746, 0xfa748, 0xfa74a, 0xfa74c, 0xfa74e, 0xfa750, 0xfa752, 0xfa754, + 0xfa756, 0xfa758, 0xfa75a, 0xfa75c, 0xfa75e, 0xfa760, 0xfa762, 0xfa764, 0xfa766, + 0xfa768, 0xfa76a, 0xfa76c, 0xfa76e, 0xfa779, 0xfa77b, 0xfa77d, 0xfa77e, 0xfa780, + 0xfa782, 0xfa784, 0xfa786, 0xfa78b, 0xfa78d, 0xfa790, 0xfa792, 0xfa796, 0xfa798, + 0xfa79a, 0xfa79c, 0xfa79e, 0xfa7a0, 0xfa7a2, 0xfa7a4, 0xfa7a6, 0xfa7a8, 0xfa7b6, + 0x100100, 0x100102, 0x100104, 0x100106, 0x100108, 0x10010a, 0x10010c, 0x10010e, 0x100110, + 0x100112, 0x100114, 0x100116, 0x100118, 0x10011a, 0x10011c, 0x10011e, 0x100120, 0x100122, + 0x100124, 0x100126, 0x100128, 0x10012a, 0x10012c, 0x10012e, 0x100130, 0x100132, 0x100134, + 0x100136, 0x100139, 0x10013b, 0x10013d, 0x10013f, 0x100141, 0x100143, 0x100145, 0x100147, + 0x10014a, 0x10014c, 0x10014e, 0x100150, 0x100152, 0x100154, 0x100156, 0x100158, 0x10015a, + 0x10015c, 0x10015e, 0x100160, 0x100162, 0x100164, 0x100166, 0x100168, 0x10016a, 0x10016c, + 0x10016e, 0x100170, 0x100172, 0x100174, 0x100176, 0x100178, 0x100179, 0x10017b, 0x10017d, + 0x100181, 0x100182, 0x100184, 0x100186, 0x100187, 0x100193, 0x100194, 0x10019c, 0x10019d, + 0x10019f, 0x1001a0, 0x1001a2, 0x1001a4, 0x1001a6, 0x1001a7, 0x1001a9, 0x1001ac, 0x1001ae, + 0x1001af, 0x1001b5, 0x1001b7, 0x1001b8, 0x1001bc, 0x1001c4, 0x1001c7, 0x1001ca, 0x1001cd, + 0x1001cf, 0x1001d1, 0x1001d3, 0x1001d5, 0x1001d7, 0x1001d9, 0x1001db, 0x1001de, 0x1001e0, + 0x1001e2, 0x1001e4, 0x1001e6, 0x1001e8, 0x1001ea, 0x1001ec, 0x1001ee, 0x1001f1, 0x1001f4, + 0x1001fa, 0x1001fc, 0x1001fe, 0x100200, 0x100202, 0x100204, 0x100206, 0x100208, 0x10020a, + 0x10020c, 0x10020e, 0x100210, 0x100212, 0x100214, 0x100216, 0x100218, 0x10021a, 0x10021c, + 0x10021e, 0x100220, 0x100222, 0x100224, 0x100226, 0x100228, 0x10022a, 0x10022c, 0x10022e, + 0x100230, 0x100232, 0x10023a, 0x10023b, 0x10023d, 0x10023e, 0x100241, 0x100248, 0x10024a, + 0x10024c, 0x10024e, 0x100370, 0x100372, 0x100376, 0x10037f, 0x100386, 0x10038c, 0x10038e, + 0x10038f, 0x1003cf, 0x1003d8, 0x1003da, 0x1003dc, 0x1003de, 0x1003e0, 0x1003e2, 0x1003e4, + 0x1003e6, 0x1003e8, 0x1003ea, 0x1003ec, 0x1003ee, 0x1003f4, 0x1003f7, 0x1003f9, 0x1003fa, + 0x100460, 0x100462, 0x100464, 0x100466, 0x100468, 0x10046a, 0x10046c, 0x10046e, 0x100470, + 0x100472, 0x100474, 0x100476, 0x100478, 0x10047a, 0x10047c, 0x10047e, 0x100480, 0x10048a, + 0x10048c, 0x10048e, 0x100490, 0x100492, 0x100494, 0x100496, 0x100498, 0x10049a, 0x10049c, + 0x10049e, 0x1004a0, 0x1004a2, 0x1004a4, 0x1004a6, 0x1004a8, 0x1004aa, 0x1004ac, 0x1004ae, + 0x1004b0, 0x1004b2, 0x1004b4, 0x1004b6, 0x1004b8, 0x1004ba, 0x1004bc, 0x1004be, 0x1004c0, + 0x1004c1, 0x1004c3, 0x1004c5, 0x1004c7, 0x1004c9, 0x1004cb, 0x1004cd, 0x1004d0, 0x1004d2, + 0x1004d4, 0x1004d6, 0x1004d8, 0x1004da, 0x1004dc, 0x1004de, 0x1004e0, 0x1004e2, 0x1004e4, + 0x1004e6, 0x1004e8, 0x1004ea, 0x1004ec, 0x1004ee, 0x1004f0, 0x1004f2, 0x1004f4, 0x1004f6, + 0x1004f8, 0x1004fa, 0x1004fc, 0x1004fe, 0x100500, 0x100502, 0x100504, 0x100506, 0x100508, + 0x10050a, 0x10050c, 0x10050e, 0x100510, 0x100512, 0x100514, 0x100516, 0x100518, 0x10051a, + 0x10051c, 0x10051e, 0x100520, 0x100522, 0x100524, 0x100526, 0x100528, 0x10052a, 0x10052c, + 0x10052e, 0x1010c7, 0x1010cd, 0x101e00, 0x101e02, 0x101e04, 0x101e06, 0x101e08, 0x101e0a, + 0x101e0c, 0x101e0e, 0x101e10, 0x101e12, 0x101e14, 0x101e16, 0x101e18, 0x101e1a, 0x101e1c, + 0x101e1e, 0x101e20, 0x101e22, 0x101e24, 0x101e26, 0x101e28, 0x101e2a, 0x101e2c, 0x101e2e, + 0x101e30, 0x101e32, 0x101e34, 0x101e36, 0x101e38, 0x101e3a, 0x101e3c, 0x101e3e, 0x101e40, + 0x101e42, 0x101e44, 0x101e46, 0x101e48, 0x101e4a, 0x101e4c, 0x101e4e, 0x101e50, 0x101e52, + 0x101e54, 0x101e56, 0x101e58, 0x101e5a, 0x101e5c, 0x101e5e, 0x101e60, 0x101e62, 0x101e64, + 0x101e66, 0x101e68, 0x101e6a, 0x101e6c, 0x101e6e, 0x101e70, 0x101e72, 0x101e74, 0x101e76, + 0x101e78, 0x101e7a, 0x101e7c, 0x101e7e, 0x101e80, 0x101e82, 0x101e84, 0x101e86, 0x101e88, + 0x101e8a, 0x101e8c, 0x101e8e, 0x101e90, 0x101e92, 0x101e94, 0x101e9e, 0x101ea0, 0x101ea2, + 0x101ea4, 0x101ea6, 0x101ea8, 0x101eaa, 0x101eac, 0x101eae, 0x101eb0, 0x101eb2, 0x101eb4, + 0x101eb6, 0x101eb8, 0x101eba, 0x101ebc, 0x101ebe, 0x101ec0, 0x101ec2, 0x101ec4, 0x101ec6, + 0x101ec8, 0x101eca, 0x101ecc, 0x101ece, 0x101ed0, 0x101ed2, 0x101ed4, 0x101ed6, 0x101ed8, + 0x101eda, 0x101edc, 0x101ede, 0x101ee0, 0x101ee2, 0x101ee4, 0x101ee6, 0x101ee8, 0x101eea, + 0x101eec, 0x101eee, 0x101ef0, 0x101ef2, 0x101ef4, 0x101ef6, 0x101ef8, 0x101efa, 0x101efc, + 0x101efe, 0x101f59, 0x101f5b, 0x101f5d, 0x101f5f, 0x102102, 0x102107, 0x102115, 0x102124, + 0x102126, 0x102128, 0x10213e, 0x10213f, 0x102145, 0x102183, 0x102c60, 0x102c67, 0x102c69, + 0x102c6b, 0x102c72, 0x102c75, 0x102c82, 0x102c84, 0x102c86, 0x102c88, 0x102c8a, 0x102c8c, + 0x102c8e, 0x102c90, 0x102c92, 0x102c94, 0x102c96, 0x102c98, 0x102c9a, 0x102c9c, 0x102c9e, + 0x102ca0, 0x102ca2, 0x102ca4, 0x102ca6, 0x102ca8, 0x102caa, 0x102cac, 0x102cae, 0x102cb0, + 0x102cb2, 0x102cb4, 0x102cb6, 0x102cb8, 0x102cba, 0x102cbc, 0x102cbe, 0x102cc0, 0x102cc2, + 0x102cc4, 0x102cc6, 0x102cc8, 0x102cca, 0x102ccc, 0x102cce, 0x102cd0, 0x102cd2, 0x102cd4, + 0x102cd6, 0x102cd8, 0x102cda, 0x102cdc, 0x102cde, 0x102ce0, 0x102ce2, 0x102ceb, 0x102ced, + 0x102cf2, 0x10a640, 0x10a642, 0x10a644, 0x10a646, 0x10a648, 0x10a64a, 0x10a64c, 0x10a64e, + 0x10a650, 0x10a652, 0x10a654, 0x10a656, 0x10a658, 0x10a65a, 0x10a65c, 0x10a65e, 0x10a660, + 0x10a662, 0x10a664, 0x10a666, 0x10a668, 0x10a66a, 0x10a66c, 0x10a680, 0x10a682, 0x10a684, + 0x10a686, 0x10a688, 0x10a68a, 0x10a68c, 0x10a68e, 0x10a690, 0x10a692, 0x10a694, 0x10a696, + 0x10a698, 0x10a69a, 0x10a722, 0x10a724, 0x10a726, 0x10a728, 0x10a72a, 0x10a72c, 0x10a72e, + 0x10a732, 0x10a734, 0x10a736, 0x10a738, 0x10a73a, 0x10a73c, 0x10a73e, 0x10a740, 0x10a742, + 0x10a744, 0x10a746, 0x10a748, 0x10a74a, 0x10a74c, 0x10a74e, 0x10a750, 0x10a752, 0x10a754, + 0x10a756, 0x10a758, 0x10a75a, 0x10a75c, 0x10a75e, 0x10a760, 0x10a762, 0x10a764, 0x10a766, + 0x10a768, 0x10a76a, 0x10a76c, 0x10a76e, 0x10a779, 0x10a77b, 0x10a77d, 0x10a77e, 0x10a780, + 0x10a782, 0x10a784, 0x10a786, 0x10a78b, 0x10a78d, 0x10a790, 0x10a792, 0x10a796, 0x10a798, + 0x10a79a, 0x10a79c, 0x10a79e, 0x10a7a0, 0x10a7a2, 0x10a7a4, 0x10a7a6, 0x10a7a8, 0x10a7b6 #endif }; @@ -615,63 +4879,63 @@ static const crange graphRangeTable[] = { {0x559, 0x55f}, {0x561, 0x587}, {0x58d, 0x58f}, {0x591, 0x5c7}, {0x5d0, 0x5ea}, {0x5f0, 0x5f4}, {0x606, 0x61b}, {0x61e, 0x6dc}, {0x6de, 0x70d}, {0x710, 0x74a}, {0x74d, 0x7b1}, {0x7c0, 0x7fa}, - {0x800, 0x82d}, {0x830, 0x83e}, {0x840, 0x85b}, {0x8a0, 0x8b4}, - {0x8b6, 0x8bd}, {0x8d4, 0x8e1}, {0x8e3, 0x983}, {0x985, 0x98c}, - {0x993, 0x9a8}, {0x9aa, 0x9b0}, {0x9b6, 0x9b9}, {0x9bc, 0x9c4}, - {0x9cb, 0x9ce}, {0x9df, 0x9e3}, {0x9e6, 0x9fb}, {0xa01, 0xa03}, - {0xa05, 0xa0a}, {0xa13, 0xa28}, {0xa2a, 0xa30}, {0xa3e, 0xa42}, - {0xa4b, 0xa4d}, {0xa59, 0xa5c}, {0xa66, 0xa75}, {0xa81, 0xa83}, - {0xa85, 0xa8d}, {0xa8f, 0xa91}, {0xa93, 0xaa8}, {0xaaa, 0xab0}, - {0xab5, 0xab9}, {0xabc, 0xac5}, {0xac7, 0xac9}, {0xacb, 0xacd}, - {0xae0, 0xae3}, {0xae6, 0xaf1}, {0xb01, 0xb03}, {0xb05, 0xb0c}, - {0xb13, 0xb28}, {0xb2a, 0xb30}, {0xb35, 0xb39}, {0xb3c, 0xb44}, - {0xb4b, 0xb4d}, {0xb5f, 0xb63}, {0xb66, 0xb77}, {0xb85, 0xb8a}, - {0xb8e, 0xb90}, {0xb92, 0xb95}, {0xba8, 0xbaa}, {0xbae, 0xbb9}, - {0xbbe, 0xbc2}, {0xbc6, 0xbc8}, {0xbca, 0xbcd}, {0xbe6, 0xbfa}, - {0xc00, 0xc03}, {0xc05, 0xc0c}, {0xc0e, 0xc10}, {0xc12, 0xc28}, - {0xc2a, 0xc39}, {0xc3d, 0xc44}, {0xc46, 0xc48}, {0xc4a, 0xc4d}, - {0xc58, 0xc5a}, {0xc60, 0xc63}, {0xc66, 0xc6f}, {0xc78, 0xc83}, - {0xc85, 0xc8c}, {0xc8e, 0xc90}, {0xc92, 0xca8}, {0xcaa, 0xcb3}, - {0xcb5, 0xcb9}, {0xcbc, 0xcc4}, {0xcc6, 0xcc8}, {0xcca, 0xccd}, - {0xce0, 0xce3}, {0xce6, 0xcef}, {0xd01, 0xd03}, {0xd05, 0xd0c}, - {0xd0e, 0xd10}, {0xd12, 0xd3a}, {0xd3d, 0xd44}, {0xd46, 0xd48}, - {0xd4a, 0xd4f}, {0xd54, 0xd63}, {0xd66, 0xd7f}, {0xd85, 0xd96}, - {0xd9a, 0xdb1}, {0xdb3, 0xdbb}, {0xdc0, 0xdc6}, {0xdcf, 0xdd4}, - {0xdd8, 0xddf}, {0xde6, 0xdef}, {0xdf2, 0xdf4}, {0xe01, 0xe3a}, - {0xe3f, 0xe5b}, {0xe94, 0xe97}, {0xe99, 0xe9f}, {0xea1, 0xea3}, - {0xead, 0xeb9}, {0xebb, 0xebd}, {0xec0, 0xec4}, {0xec8, 0xecd}, - {0xed0, 0xed9}, {0xedc, 0xedf}, {0xf00, 0xf47}, {0xf49, 0xf6c}, - {0xf71, 0xf97}, {0xf99, 0xfbc}, {0xfbe, 0xfcc}, {0xfce, 0xfda}, - {0x1000, 0x10c5}, {0x10d0, 0x1248}, {0x124a, 0x124d}, {0x1250, 0x1256}, - {0x125a, 0x125d}, {0x1260, 0x1288}, {0x128a, 0x128d}, {0x1290, 0x12b0}, - {0x12b2, 0x12b5}, {0x12b8, 0x12be}, {0x12c2, 0x12c5}, {0x12c8, 0x12d6}, - {0x12d8, 0x1310}, {0x1312, 0x1315}, {0x1318, 0x135a}, {0x135d, 0x137c}, - {0x1380, 0x1399}, {0x13a0, 0x13f5}, {0x13f8, 0x13fd}, {0x1400, 0x167f}, - {0x1681, 0x169c}, {0x16a0, 0x16f8}, {0x1700, 0x170c}, {0x170e, 0x1714}, - {0x1720, 0x1736}, {0x1740, 0x1753}, {0x1760, 0x176c}, {0x176e, 0x1770}, - {0x1780, 0x17dd}, {0x17e0, 0x17e9}, {0x17f0, 0x17f9}, {0x1800, 0x180d}, - {0x1810, 0x1819}, {0x1820, 0x1877}, {0x1880, 0x18aa}, {0x18b0, 0x18f5}, - {0x1900, 0x191e}, {0x1920, 0x192b}, {0x1930, 0x193b}, {0x1944, 0x196d}, - {0x1970, 0x1974}, {0x1980, 0x19ab}, {0x19b0, 0x19c9}, {0x19d0, 0x19da}, - {0x19de, 0x1a1b}, {0x1a1e, 0x1a5e}, {0x1a60, 0x1a7c}, {0x1a7f, 0x1a89}, - {0x1a90, 0x1a99}, {0x1aa0, 0x1aad}, {0x1ab0, 0x1abe}, {0x1b00, 0x1b4b}, - {0x1b50, 0x1b7c}, {0x1b80, 0x1bf3}, {0x1bfc, 0x1c37}, {0x1c3b, 0x1c49}, - {0x1c4d, 0x1c88}, {0x1cc0, 0x1cc7}, {0x1cd0, 0x1cf6}, {0x1d00, 0x1df5}, - {0x1dfb, 0x1f15}, {0x1f18, 0x1f1d}, {0x1f20, 0x1f45}, {0x1f48, 0x1f4d}, - {0x1f50, 0x1f57}, {0x1f5f, 0x1f7d}, {0x1f80, 0x1fb4}, {0x1fb6, 0x1fc4}, - {0x1fc6, 0x1fd3}, {0x1fd6, 0x1fdb}, {0x1fdd, 0x1fef}, {0x1ff2, 0x1ff4}, - {0x1ff6, 0x1ffe}, {0x2010, 0x2027}, {0x2030, 0x205e}, {0x2074, 0x208e}, - {0x2090, 0x209c}, {0x20a0, 0x20be}, {0x20d0, 0x20f0}, {0x2100, 0x218b}, - {0x2190, 0x23fe}, {0x2400, 0x2426}, {0x2440, 0x244a}, {0x2460, 0x2b73}, - {0x2b76, 0x2b95}, {0x2b98, 0x2bb9}, {0x2bbd, 0x2bc8}, {0x2bca, 0x2bd1}, + {0x800, 0x82d}, {0x830, 0x83e}, {0x840, 0x85b}, {0x860, 0x86a}, + {0x8a0, 0x8b4}, {0x8b6, 0x8bd}, {0x8d4, 0x8e1}, {0x8e3, 0x983}, + {0x985, 0x98c}, {0x993, 0x9a8}, {0x9aa, 0x9b0}, {0x9b6, 0x9b9}, + {0x9bc, 0x9c4}, {0x9cb, 0x9ce}, {0x9df, 0x9e3}, {0x9e6, 0x9fd}, + {0xa01, 0xa03}, {0xa05, 0xa0a}, {0xa13, 0xa28}, {0xa2a, 0xa30}, + {0xa3e, 0xa42}, {0xa4b, 0xa4d}, {0xa59, 0xa5c}, {0xa66, 0xa75}, + {0xa81, 0xa83}, {0xa85, 0xa8d}, {0xa8f, 0xa91}, {0xa93, 0xaa8}, + {0xaaa, 0xab0}, {0xab5, 0xab9}, {0xabc, 0xac5}, {0xac7, 0xac9}, + {0xacb, 0xacd}, {0xae0, 0xae3}, {0xae6, 0xaf1}, {0xaf9, 0xaff}, + {0xb01, 0xb03}, {0xb05, 0xb0c}, {0xb13, 0xb28}, {0xb2a, 0xb30}, + {0xb35, 0xb39}, {0xb3c, 0xb44}, {0xb4b, 0xb4d}, {0xb5f, 0xb63}, + {0xb66, 0xb77}, {0xb85, 0xb8a}, {0xb8e, 0xb90}, {0xb92, 0xb95}, + {0xba8, 0xbaa}, {0xbae, 0xbb9}, {0xbbe, 0xbc2}, {0xbc6, 0xbc8}, + {0xbca, 0xbcd}, {0xbe6, 0xbfa}, {0xc00, 0xc03}, {0xc05, 0xc0c}, + {0xc0e, 0xc10}, {0xc12, 0xc28}, {0xc2a, 0xc39}, {0xc3d, 0xc44}, + {0xc46, 0xc48}, {0xc4a, 0xc4d}, {0xc58, 0xc5a}, {0xc60, 0xc63}, + {0xc66, 0xc6f}, {0xc78, 0xc83}, {0xc85, 0xc8c}, {0xc8e, 0xc90}, + {0xc92, 0xca8}, {0xcaa, 0xcb3}, {0xcb5, 0xcb9}, {0xcbc, 0xcc4}, + {0xcc6, 0xcc8}, {0xcca, 0xccd}, {0xce0, 0xce3}, {0xce6, 0xcef}, + {0xd00, 0xd03}, {0xd05, 0xd0c}, {0xd0e, 0xd10}, {0xd12, 0xd44}, + {0xd46, 0xd48}, {0xd4a, 0xd4f}, {0xd54, 0xd63}, {0xd66, 0xd7f}, + {0xd85, 0xd96}, {0xd9a, 0xdb1}, {0xdb3, 0xdbb}, {0xdc0, 0xdc6}, + {0xdcf, 0xdd4}, {0xdd8, 0xddf}, {0xde6, 0xdef}, {0xdf2, 0xdf4}, + {0xe01, 0xe3a}, {0xe3f, 0xe5b}, {0xe94, 0xe97}, {0xe99, 0xe9f}, + {0xea1, 0xea3}, {0xead, 0xeb9}, {0xebb, 0xebd}, {0xec0, 0xec4}, + {0xec8, 0xecd}, {0xed0, 0xed9}, {0xedc, 0xedf}, {0xf00, 0xf47}, + {0xf49, 0xf6c}, {0xf71, 0xf97}, {0xf99, 0xfbc}, {0xfbe, 0xfcc}, + {0xfce, 0xfda}, {0x1000, 0x10c5}, {0x10d0, 0x1248}, {0x124a, 0x124d}, + {0x1250, 0x1256}, {0x125a, 0x125d}, {0x1260, 0x1288}, {0x128a, 0x128d}, + {0x1290, 0x12b0}, {0x12b2, 0x12b5}, {0x12b8, 0x12be}, {0x12c2, 0x12c5}, + {0x12c8, 0x12d6}, {0x12d8, 0x1310}, {0x1312, 0x1315}, {0x1318, 0x135a}, + {0x135d, 0x137c}, {0x1380, 0x1399}, {0x13a0, 0x13f5}, {0x13f8, 0x13fd}, + {0x1400, 0x167f}, {0x1681, 0x169c}, {0x16a0, 0x16f8}, {0x1700, 0x170c}, + {0x170e, 0x1714}, {0x1720, 0x1736}, {0x1740, 0x1753}, {0x1760, 0x176c}, + {0x176e, 0x1770}, {0x1780, 0x17dd}, {0x17e0, 0x17e9}, {0x17f0, 0x17f9}, + {0x1800, 0x180d}, {0x1810, 0x1819}, {0x1820, 0x1877}, {0x1880, 0x18aa}, + {0x18b0, 0x18f5}, {0x1900, 0x191e}, {0x1920, 0x192b}, {0x1930, 0x193b}, + {0x1944, 0x196d}, {0x1970, 0x1974}, {0x1980, 0x19ab}, {0x19b0, 0x19c9}, + {0x19d0, 0x19da}, {0x19de, 0x1a1b}, {0x1a1e, 0x1a5e}, {0x1a60, 0x1a7c}, + {0x1a7f, 0x1a89}, {0x1a90, 0x1a99}, {0x1aa0, 0x1aad}, {0x1ab0, 0x1abe}, + {0x1b00, 0x1b4b}, {0x1b50, 0x1b7c}, {0x1b80, 0x1bf3}, {0x1bfc, 0x1c37}, + {0x1c3b, 0x1c49}, {0x1c4d, 0x1c88}, {0x1cc0, 0x1cc7}, {0x1cd0, 0x1cf9}, + {0x1d00, 0x1df9}, {0x1dfb, 0x1f15}, {0x1f18, 0x1f1d}, {0x1f20, 0x1f45}, + {0x1f48, 0x1f4d}, {0x1f50, 0x1f57}, {0x1f5f, 0x1f7d}, {0x1f80, 0x1fb4}, + {0x1fb6, 0x1fc4}, {0x1fc6, 0x1fd3}, {0x1fd6, 0x1fdb}, {0x1fdd, 0x1fef}, + {0x1ff2, 0x1ff4}, {0x1ff6, 0x1ffe}, {0x2010, 0x2027}, {0x2030, 0x205e}, + {0x2074, 0x208e}, {0x2090, 0x209c}, {0x20a0, 0x20bf}, {0x20d0, 0x20f0}, + {0x2100, 0x218b}, {0x2190, 0x2426}, {0x2440, 0x244a}, {0x2460, 0x2b73}, + {0x2b76, 0x2b95}, {0x2b98, 0x2bb9}, {0x2bbd, 0x2bc8}, {0x2bca, 0x2bd2}, {0x2bec, 0x2bef}, {0x2c00, 0x2c2e}, {0x2c30, 0x2c5e}, {0x2c60, 0x2cf3}, {0x2cf9, 0x2d25}, {0x2d30, 0x2d67}, {0x2d7f, 0x2d96}, {0x2da0, 0x2da6}, {0x2da8, 0x2dae}, {0x2db0, 0x2db6}, {0x2db8, 0x2dbe}, {0x2dc0, 0x2dc6}, - {0x2dc8, 0x2dce}, {0x2dd0, 0x2dd6}, {0x2dd8, 0x2dde}, {0x2de0, 0x2e44}, + {0x2dc8, 0x2dce}, {0x2dd0, 0x2dd6}, {0x2dd8, 0x2dde}, {0x2de0, 0x2e49}, {0x2e80, 0x2e99}, {0x2e9b, 0x2ef3}, {0x2f00, 0x2fd5}, {0x2ff0, 0x2ffb}, - {0x3001, 0x303f}, {0x3041, 0x3096}, {0x3099, 0x30ff}, {0x3105, 0x312d}, + {0x3001, 0x303f}, {0x3041, 0x3096}, {0x3099, 0x30ff}, {0x3105, 0x312e}, {0x3131, 0x318e}, {0x3190, 0x31ba}, {0x31c0, 0x31e3}, {0x31f0, 0x321e}, - {0x3220, 0x32fe}, {0x3300, 0x4db5}, {0x4dc0, 0x9fd5}, {0xa000, 0xa48c}, + {0x3220, 0x32fe}, {0x3300, 0x4db5}, {0x4dc0, 0x9fea}, {0xa000, 0xa48c}, {0xa490, 0xa4c6}, {0xa4d0, 0xa62b}, {0xa640, 0xa6f7}, {0xa700, 0xa7ae}, {0xa7b0, 0xa7b7}, {0xa7f7, 0xa82b}, {0xa830, 0xa839}, {0xa840, 0xa877}, {0xa880, 0xa8c5}, {0xa8ce, 0xa8d9}, {0xa8e0, 0xa8fd}, {0xa900, 0xa953}, @@ -680,10 +4944,6 @@ static const crange graphRangeTable[] = { {0xaadb, 0xaaf6}, {0xab01, 0xab06}, {0xab09, 0xab0e}, {0xab11, 0xab16}, {0xab20, 0xab26}, {0xab28, 0xab2e}, {0xab30, 0xab65}, {0xab70, 0xabed}, {0xabf0, 0xabf9}, {0xac00, 0xd7a3}, {0xd7b0, 0xd7c6}, {0xd7cb, 0xd7fb}, - {0xdc00, 0xdc3e}, {0xdc40, 0xdc7e}, {0xdc80, 0xdcbe}, {0xdcc0, 0xdcfe}, - {0xdd00, 0xdd3e}, {0xdd40, 0xdd7e}, {0xdd80, 0xddbe}, {0xddc0, 0xddfe}, - {0xde00, 0xde3e}, {0xde40, 0xde7e}, {0xde80, 0xdebe}, {0xdec0, 0xdefe}, - {0xdf00, 0xdf3e}, {0xdf40, 0xdf7e}, {0xdf80, 0xdfbe}, {0xdfc0, 0xdffe}, {0xf900, 0xfa6d}, {0xfa70, 0xfad9}, {0xfb00, 0xfb06}, {0xfb13, 0xfb17}, {0xfb1d, 0xfb36}, {0xfb38, 0xfb3c}, {0xfb46, 0xfbc1}, {0xfbd3, 0xfd3f}, {0xfd50, 0xfd8f}, {0xfd92, 0xfdc7}, {0xfdf0, 0xfdfd}, {0xfe00, 0xfe19}, @@ -691,61 +4951,1222 @@ static const crange graphRangeTable[] = { {0xfe76, 0xfefc}, {0xff01, 0xffbe}, {0xffc2, 0xffc7}, {0xffca, 0xffcf}, {0xffd2, 0xffd7}, {0xffda, 0xffdc}, {0xffe0, 0xffe6}, {0xffe8, 0xffee} #if TCL_UTF_MAX > 4 - ,{0x10000, 0x1000b}, {0x1000d, 0x10026}, {0x10028, 0x1003a}, {0x1003f, 0x1004d}, - {0x10050, 0x1005d}, {0x10080, 0x100fa}, {0x10100, 0x10102}, {0x10107, 0x10133}, - {0x10137, 0x1018e}, {0x10190, 0x1019b}, {0x101d0, 0x101fd}, {0x10280, 0x1029c}, - {0x102a0, 0x102d0}, {0x102e0, 0x102fb}, {0x10300, 0x10323}, {0x10330, 0x1034a}, - {0x10350, 0x1037a}, {0x10380, 0x1039d}, {0x1039f, 0x103c3}, {0x103c8, 0x103d5}, - {0x10400, 0x1049d}, {0x104a0, 0x104a9}, {0x104b0, 0x104d3}, {0x104d8, 0x104fb}, - {0x10500, 0x10527}, {0x10530, 0x10563}, {0x10600, 0x10736}, {0x10740, 0x10755}, - {0x10760, 0x10767}, {0x10800, 0x10805}, {0x1080a, 0x10835}, {0x1083f, 0x10855}, - {0x10857, 0x1089e}, {0x108a7, 0x108af}, {0x108e0, 0x108f2}, {0x108fb, 0x1091b}, - {0x1091f, 0x10939}, {0x10980, 0x109b7}, {0x109bc, 0x109cf}, {0x109d2, 0x10a03}, - {0x10a0c, 0x10a13}, {0x10a15, 0x10a17}, {0x10a19, 0x10a33}, {0x10a38, 0x10a3a}, - {0x10a3f, 0x10a47}, {0x10a50, 0x10a58}, {0x10a60, 0x10a9f}, {0x10ac0, 0x10ae6}, - {0x10aeb, 0x10af6}, {0x10b00, 0x10b35}, {0x10b39, 0x10b55}, {0x10b58, 0x10b72}, - {0x10b78, 0x10b91}, {0x10b99, 0x10b9c}, {0x10ba9, 0x10baf}, {0x10c00, 0x10c48}, - {0x10c80, 0x10cb2}, {0x10cc0, 0x10cf2}, {0x10cfa, 0x10cff}, {0x10e60, 0x10e7e}, - {0x11000, 0x1104d}, {0x11052, 0x1106f}, {0x1107f, 0x110bc}, {0x110be, 0x110c1}, - {0x110d0, 0x110e8}, {0x110f0, 0x110f9}, {0x11100, 0x11134}, {0x11136, 0x11143}, - {0x11150, 0x11176}, {0x11180, 0x111cd}, {0x111d0, 0x111df}, {0x111e1, 0x111f4}, - {0x11200, 0x11211}, {0x11213, 0x1123e}, {0x11280, 0x11286}, {0x1128a, 0x1128d}, - {0x1128f, 0x1129d}, {0x1129f, 0x112a9}, {0x112b0, 0x112ea}, {0x112f0, 0x112f9}, - {0x11300, 0x11303}, {0x11305, 0x1130c}, {0x11313, 0x11328}, {0x1132a, 0x11330}, - {0x11335, 0x11339}, {0x1133c, 0x11344}, {0x1134b, 0x1134d}, {0x1135d, 0x11363}, - {0x11366, 0x1136c}, {0x11370, 0x11374}, {0x11400, 0x11459}, {0x11480, 0x114c7}, - {0x114d0, 0x114d9}, {0x11580, 0x115b5}, {0x115b8, 0x115dd}, {0x11600, 0x11644}, - {0x11650, 0x11659}, {0x11660, 0x1166c}, {0x11680, 0x116b7}, {0x116c0, 0x116c9}, - {0x11700, 0x11719}, {0x1171d, 0x1172b}, {0x11730, 0x1173f}, {0x118a0, 0x118f2}, - {0x11ac0, 0x11af8}, {0x11c00, 0x11c08}, {0x11c0a, 0x11c36}, {0x11c38, 0x11c45}, - {0x11c50, 0x11c6c}, {0x11c70, 0x11c8f}, {0x11c92, 0x11ca7}, {0x11ca9, 0x11cb6}, - {0x12000, 0x12399}, {0x12400, 0x1246e}, {0x12470, 0x12474}, {0x12480, 0x12543}, - {0x13000, 0x1342e}, {0x14400, 0x14646}, {0x16800, 0x16a38}, {0x16a40, 0x16a5e}, - {0x16a60, 0x16a69}, {0x16ad0, 0x16aed}, {0x16af0, 0x16af5}, {0x16b00, 0x16b45}, - {0x16b50, 0x16b59}, {0x16b5b, 0x16b61}, {0x16b63, 0x16b77}, {0x16b7d, 0x16b8f}, - {0x16f00, 0x16f44}, {0x16f50, 0x16f7e}, {0x16f8f, 0x16f9f}, {0x17000, 0x187ec}, - {0x18800, 0x18af2}, {0x1bc00, 0x1bc6a}, {0x1bc70, 0x1bc7c}, {0x1bc80, 0x1bc88}, - {0x1bc90, 0x1bc99}, {0x1bc9c, 0x1bc9f}, {0x1d000, 0x1d0f5}, {0x1d100, 0x1d126}, - {0x1d129, 0x1d172}, {0x1d17b, 0x1d1e8}, {0x1d200, 0x1d245}, {0x1d300, 0x1d356}, - {0x1d360, 0x1d371}, {0x1d400, 0x1d454}, {0x1d456, 0x1d49c}, {0x1d4a9, 0x1d4ac}, - {0x1d4ae, 0x1d4b9}, {0x1d4bd, 0x1d4c3}, {0x1d4c5, 0x1d505}, {0x1d507, 0x1d50a}, - {0x1d50d, 0x1d514}, {0x1d516, 0x1d51c}, {0x1d51e, 0x1d539}, {0x1d53b, 0x1d53e}, - {0x1d540, 0x1d544}, {0x1d54a, 0x1d550}, {0x1d552, 0x1d6a5}, {0x1d6a8, 0x1d7cb}, - {0x1d7ce, 0x1da8b}, {0x1da9b, 0x1da9f}, {0x1daa1, 0x1daaf}, {0x1e000, 0x1e006}, - {0x1e008, 0x1e018}, {0x1e01b, 0x1e021}, {0x1e026, 0x1e02a}, {0x1e800, 0x1e8c4}, - {0x1e8c7, 0x1e8d6}, {0x1e900, 0x1e94a}, {0x1e950, 0x1e959}, {0x1ee00, 0x1ee03}, - {0x1ee05, 0x1ee1f}, {0x1ee29, 0x1ee32}, {0x1ee34, 0x1ee37}, {0x1ee4d, 0x1ee4f}, - {0x1ee67, 0x1ee6a}, {0x1ee6c, 0x1ee72}, {0x1ee74, 0x1ee77}, {0x1ee79, 0x1ee7c}, - {0x1ee80, 0x1ee89}, {0x1ee8b, 0x1ee9b}, {0x1eea1, 0x1eea3}, {0x1eea5, 0x1eea9}, - {0x1eeab, 0x1eebb}, {0x1f000, 0x1f02b}, {0x1f030, 0x1f093}, {0x1f0a0, 0x1f0ae}, - {0x1f0b1, 0x1f0bf}, {0x1f0c1, 0x1f0cf}, {0x1f0d1, 0x1f0f5}, {0x1f100, 0x1f10c}, - {0x1f110, 0x1f12e}, {0x1f130, 0x1f16b}, {0x1f170, 0x1f1ac}, {0x1f1e6, 0x1f202}, - {0x1f210, 0x1f23b}, {0x1f240, 0x1f248}, {0x1f300, 0x1f6d2}, {0x1f6e0, 0x1f6ec}, - {0x1f6f0, 0x1f6f6}, {0x1f700, 0x1f773}, {0x1f780, 0x1f7d4}, {0x1f800, 0x1f80b}, - {0x1f810, 0x1f847}, {0x1f850, 0x1f859}, {0x1f860, 0x1f887}, {0x1f890, 0x1f8ad}, - {0x1f910, 0x1f91e}, {0x1f920, 0x1f927}, {0x1f933, 0x1f93e}, {0x1f940, 0x1f94b}, - {0x1f950, 0x1f95e}, {0x1f980, 0x1f991}, {0x20000, 0x2a6d6}, {0x2a700, 0x2b734}, - {0x2b740, 0x2b81d}, {0x2b820, 0x2cea1}, {0x2f800, 0x2fa1d}, {0xe0100, 0xe01ef} + ,{0x10021, 0x1007e}, {0x100a1, 0x100ac}, {0x100ae, 0x10377}, {0x1037a, 0x1037f}, + {0x10384, 0x1038a}, {0x1038e, 0x103a1}, {0x103a3, 0x1052f}, {0x10531, 0x10556}, + {0x10559, 0x1055f}, {0x10561, 0x10587}, {0x1058d, 0x1058f}, {0x10591, 0x105c7}, + {0x105d0, 0x105ea}, {0x105f0, 0x105f4}, {0x10606, 0x1061b}, {0x1061e, 0x106dc}, + {0x106de, 0x1070d}, {0x10710, 0x1074a}, {0x1074d, 0x107b1}, {0x107c0, 0x107fa}, + {0x10800, 0x1082d}, {0x10830, 0x1083e}, {0x10840, 0x1085b}, {0x10860, 0x1086a}, + {0x108a0, 0x108b4}, {0x108b6, 0x108bd}, {0x108d4, 0x108e1}, {0x108e3, 0x10983}, + {0x10985, 0x1098c}, {0x10993, 0x109a8}, {0x109aa, 0x109b0}, {0x109b6, 0x109b9}, + {0x109bc, 0x109c4}, {0x109cb, 0x109ce}, {0x109df, 0x109e3}, {0x109e6, 0x109fd}, + {0x10a01, 0x10a03}, {0x10a05, 0x10a0a}, {0x10a13, 0x10a28}, {0x10a2a, 0x10a30}, + {0x10a3e, 0x10a42}, {0x10a4b, 0x10a4d}, {0x10a59, 0x10a5c}, {0x10a66, 0x10a75}, + {0x10a81, 0x10a83}, {0x10a85, 0x10a8d}, {0x10a8f, 0x10a91}, {0x10a93, 0x10aa8}, + {0x10aaa, 0x10ab0}, {0x10ab5, 0x10ab9}, {0x10abc, 0x10ac5}, {0x10ac7, 0x10ac9}, + {0x10acb, 0x10acd}, {0x10ae0, 0x10ae3}, {0x10ae6, 0x10af1}, {0x10af9, 0x10aff}, + {0x10b01, 0x10b03}, {0x10b05, 0x10b0c}, {0x10b13, 0x10b28}, {0x10b2a, 0x10b30}, + {0x10b35, 0x10b39}, {0x10b3c, 0x10b44}, {0x10b4b, 0x10b4d}, {0x10b5f, 0x10b63}, + {0x10b66, 0x10b77}, {0x10b85, 0x10b8a}, {0x10b8e, 0x10b90}, {0x10b92, 0x10b95}, + {0x10ba8, 0x10baa}, {0x10bae, 0x10bb9}, {0x10bbe, 0x10bc2}, {0x10bc6, 0x10bc8}, + {0x10bca, 0x10bcd}, {0x10be6, 0x10bfa}, {0x10c00, 0x10c03}, {0x10c05, 0x10c0c}, + {0x10c0e, 0x10c10}, {0x10c12, 0x10c28}, {0x10c2a, 0x10c39}, {0x10c3d, 0x10c44}, + {0x10c46, 0x10c48}, {0x10c4a, 0x10c4d}, {0x10c58, 0x10c5a}, {0x10c60, 0x10c63}, + {0x10c66, 0x10c6f}, {0x10c78, 0x10c83}, {0x10c85, 0x10c8c}, {0x10c8e, 0x10c90}, + {0x10c92, 0x10ca8}, {0x10caa, 0x10cb3}, {0x10cb5, 0x10cb9}, {0x10cbc, 0x10cc4}, + {0x10cc6, 0x10cc8}, {0x10cca, 0x10ccd}, {0x10ce0, 0x10ce3}, {0x10ce6, 0x10cef}, + {0x10d00, 0x10d03}, {0x10d05, 0x10d0c}, {0x10d0e, 0x10d10}, {0x10d12, 0x10d44}, + {0x10d46, 0x10d48}, {0x10d4a, 0x10d4f}, {0x10d54, 0x10d63}, {0x10d66, 0x10d7f}, + {0x10d85, 0x10d96}, {0x10d9a, 0x10db1}, {0x10db3, 0x10dbb}, {0x10dc0, 0x10dc6}, + {0x10dcf, 0x10dd4}, {0x10dd8, 0x10ddf}, {0x10de6, 0x10def}, {0x10df2, 0x10df4}, + {0x10e01, 0x10e3a}, {0x10e3f, 0x10e5b}, {0x10e94, 0x10e97}, {0x10e99, 0x10e9f}, + {0x10ea1, 0x10ea3}, {0x10ead, 0x10eb9}, {0x10ebb, 0x10ebd}, {0x10ec0, 0x10ec4}, + {0x10ec8, 0x10ecd}, {0x10ed0, 0x10ed9}, {0x10edc, 0x10edf}, {0x10f00, 0x10f47}, + {0x10f49, 0x10f6c}, {0x10f71, 0x10f97}, {0x10f99, 0x10fbc}, {0x10fbe, 0x10fcc}, + {0x10fce, 0x10fda}, {0x11000, 0x110c5}, {0x110d0, 0x11248}, {0x1124a, 0x1124d}, + {0x11250, 0x11256}, {0x1125a, 0x1125d}, {0x11260, 0x11288}, {0x1128a, 0x1128d}, + {0x11290, 0x112b0}, {0x112b2, 0x112b5}, {0x112b8, 0x112be}, {0x112c2, 0x112c5}, + {0x112c8, 0x112d6}, {0x112d8, 0x11310}, {0x11312, 0x11315}, {0x11318, 0x1135a}, + {0x1135d, 0x1137c}, {0x11380, 0x11399}, {0x113a0, 0x113f5}, {0x113f8, 0x113fd}, + {0x11400, 0x1167f}, {0x11681, 0x1169c}, {0x116a0, 0x116f8}, {0x11700, 0x1170c}, + {0x1170e, 0x11714}, {0x11720, 0x11736}, {0x11740, 0x11753}, {0x11760, 0x1176c}, + {0x1176e, 0x11770}, {0x11780, 0x117dd}, {0x117e0, 0x117e9}, {0x117f0, 0x117f9}, + {0x11800, 0x1180d}, {0x11810, 0x11819}, {0x11820, 0x11877}, {0x11880, 0x118aa}, + {0x118b0, 0x118f5}, {0x11900, 0x1191e}, {0x11920, 0x1192b}, {0x11930, 0x1193b}, + {0x11944, 0x1196d}, {0x11970, 0x11974}, {0x11980, 0x119ab}, {0x119b0, 0x119c9}, + {0x119d0, 0x119da}, {0x119de, 0x11a1b}, {0x11a1e, 0x11a5e}, {0x11a60, 0x11a7c}, + {0x11a7f, 0x11a89}, {0x11a90, 0x11a99}, {0x11aa0, 0x11aad}, {0x11ab0, 0x11abe}, + {0x11b00, 0x11b4b}, {0x11b50, 0x11b7c}, {0x11b80, 0x11bf3}, {0x11bfc, 0x11c37}, + {0x11c3b, 0x11c49}, {0x11c4d, 0x11c88}, {0x11cc0, 0x11cc7}, {0x11cd0, 0x11cf9}, + {0x11d00, 0x11df9}, {0x11dfb, 0x11f15}, {0x11f18, 0x11f1d}, {0x11f20, 0x11f45}, + {0x11f48, 0x11f4d}, {0x11f50, 0x11f57}, {0x11f5f, 0x11f7d}, {0x11f80, 0x11fb4}, + {0x11fb6, 0x11fc4}, {0x11fc6, 0x11fd3}, {0x11fd6, 0x11fdb}, {0x11fdd, 0x11fef}, + {0x11ff2, 0x11ff4}, {0x11ff6, 0x11ffe}, {0x12010, 0x12027}, {0x12030, 0x1205e}, + {0x12074, 0x1208e}, {0x12090, 0x1209c}, {0x120a0, 0x120bf}, {0x120d0, 0x120f0}, + {0x12100, 0x1218b}, {0x12190, 0x12426}, {0x12440, 0x1244a}, {0x12460, 0x12b73}, + {0x12b76, 0x12b95}, {0x12b98, 0x12bb9}, {0x12bbd, 0x12bc8}, {0x12bca, 0x12bd2}, + {0x12bec, 0x12bef}, {0x12c00, 0x12c2e}, {0x12c30, 0x12c5e}, {0x12c60, 0x12cf3}, + {0x12cf9, 0x12d25}, {0x12d30, 0x12d67}, {0x12d7f, 0x12d96}, {0x12da0, 0x12da6}, + {0x12da8, 0x12dae}, {0x12db0, 0x12db6}, {0x12db8, 0x12dbe}, {0x12dc0, 0x12dc6}, + {0x12dc8, 0x12dce}, {0x12dd0, 0x12dd6}, {0x12dd8, 0x12dde}, {0x12de0, 0x12e49}, + {0x12e80, 0x12e99}, {0x12e9b, 0x12ef3}, {0x12f00, 0x12fd5}, {0x12ff0, 0x12ffb}, + {0x13001, 0x1303f}, {0x13041, 0x13096}, {0x13099, 0x130ff}, {0x13105, 0x1312e}, + {0x13131, 0x1318e}, {0x13190, 0x131ba}, {0x131c0, 0x131e3}, {0x131f0, 0x1321e}, + {0x13220, 0x132fe}, {0x13300, 0x14db5}, {0x14dc0, 0x19fea}, {0x1a000, 0x1a48c}, + {0x1a490, 0x1a4c6}, {0x1a4d0, 0x1a62b}, {0x1a640, 0x1a6f7}, {0x1a700, 0x1a7ae}, + {0x1a7b0, 0x1a7b7}, {0x1a7f7, 0x1a82b}, {0x1a830, 0x1a839}, {0x1a840, 0x1a877}, + {0x1a880, 0x1a8c5}, {0x1a8ce, 0x1a8d9}, {0x1a8e0, 0x1a8fd}, {0x1a900, 0x1a953}, + {0x1a95f, 0x1a97c}, {0x1a980, 0x1a9cd}, {0x1a9cf, 0x1a9d9}, {0x1a9de, 0x1a9fe}, + {0x1aa00, 0x1aa36}, {0x1aa40, 0x1aa4d}, {0x1aa50, 0x1aa59}, {0x1aa5c, 0x1aac2}, + {0x1aadb, 0x1aaf6}, {0x1ab01, 0x1ab06}, {0x1ab09, 0x1ab0e}, {0x1ab11, 0x1ab16}, + {0x1ab20, 0x1ab26}, {0x1ab28, 0x1ab2e}, {0x1ab30, 0x1ab65}, {0x1ab70, 0x1abed}, + {0x1abf0, 0x1abf9}, {0x1ac00, 0x1d7a3}, {0x1d7b0, 0x1d7c6}, {0x1d7cb, 0x1d7fb}, + {0x1f900, 0x1fa6d}, {0x1fa70, 0x1fad9}, {0x1fb00, 0x1fb06}, {0x1fb13, 0x1fb17}, + {0x1fb1d, 0x1fb36}, {0x1fb38, 0x1fb3c}, {0x1fb46, 0x1fbc1}, {0x1fbd3, 0x1fd3f}, + {0x1fd50, 0x1fd8f}, {0x1fd92, 0x1fdc7}, {0x1fdf0, 0x1fdfd}, {0x1fe00, 0x1fe19}, + {0x1fe20, 0x1fe52}, {0x1fe54, 0x1fe66}, {0x1fe68, 0x1fe6b}, {0x1fe70, 0x1fe74}, + {0x1fe76, 0x1fefc}, {0x1ff01, 0x1ffbe}, {0x1ffc2, 0x1ffc7}, {0x1ffca, 0x1ffcf}, + {0x1ffd2, 0x1ffd7}, {0x1ffda, 0x1ffdc}, {0x1ffe0, 0x1ffe6}, {0x1ffe8, 0x1ffee}, + {0x20021, 0x2007e}, {0x200a1, 0x200ac}, {0x200ae, 0x20377}, {0x2037a, 0x2037f}, + {0x20384, 0x2038a}, {0x2038e, 0x203a1}, {0x203a3, 0x2052f}, {0x20531, 0x20556}, + {0x20559, 0x2055f}, {0x20561, 0x20587}, {0x2058d, 0x2058f}, {0x20591, 0x205c7}, + {0x205d0, 0x205ea}, {0x205f0, 0x205f4}, {0x20606, 0x2061b}, {0x2061e, 0x206dc}, + {0x206de, 0x2070d}, {0x20710, 0x2074a}, {0x2074d, 0x207b1}, {0x207c0, 0x207fa}, + {0x20800, 0x2082d}, {0x20830, 0x2083e}, {0x20840, 0x2085b}, {0x20860, 0x2086a}, + {0x208a0, 0x208b4}, {0x208b6, 0x208bd}, {0x208d4, 0x208e1}, {0x208e3, 0x20983}, + {0x20985, 0x2098c}, {0x20993, 0x209a8}, {0x209aa, 0x209b0}, {0x209b6, 0x209b9}, + {0x209bc, 0x209c4}, {0x209cb, 0x209ce}, {0x209df, 0x209e3}, {0x209e6, 0x209fd}, + {0x20a01, 0x20a03}, {0x20a05, 0x20a0a}, {0x20a13, 0x20a28}, {0x20a2a, 0x20a30}, + {0x20a3e, 0x20a42}, {0x20a4b, 0x20a4d}, {0x20a59, 0x20a5c}, {0x20a66, 0x20a75}, + {0x20a81, 0x20a83}, {0x20a85, 0x20a8d}, {0x20a8f, 0x20a91}, {0x20a93, 0x20aa8}, + {0x20aaa, 0x20ab0}, {0x20ab5, 0x20ab9}, {0x20abc, 0x20ac5}, {0x20ac7, 0x20ac9}, + {0x20acb, 0x20acd}, {0x20ae0, 0x20ae3}, {0x20ae6, 0x20af1}, {0x20af9, 0x20aff}, + {0x20b01, 0x20b03}, {0x20b05, 0x20b0c}, {0x20b13, 0x20b28}, {0x20b2a, 0x20b30}, + {0x20b35, 0x20b39}, {0x20b3c, 0x20b44}, {0x20b4b, 0x20b4d}, {0x20b5f, 0x20b63}, + {0x20b66, 0x20b77}, {0x20b85, 0x20b8a}, {0x20b8e, 0x20b90}, {0x20b92, 0x20b95}, + {0x20ba8, 0x20baa}, {0x20bae, 0x20bb9}, {0x20bbe, 0x20bc2}, {0x20bc6, 0x20bc8}, + {0x20bca, 0x20bcd}, {0x20be6, 0x20bfa}, {0x20c00, 0x20c03}, {0x20c05, 0x20c0c}, + {0x20c0e, 0x20c10}, {0x20c12, 0x20c28}, {0x20c2a, 0x20c39}, {0x20c3d, 0x20c44}, + {0x20c46, 0x20c48}, {0x20c4a, 0x20c4d}, {0x20c58, 0x20c5a}, {0x20c60, 0x20c63}, + {0x20c66, 0x20c6f}, {0x20c78, 0x20c83}, {0x20c85, 0x20c8c}, {0x20c8e, 0x20c90}, + {0x20c92, 0x20ca8}, {0x20caa, 0x20cb3}, {0x20cb5, 0x20cb9}, {0x20cbc, 0x20cc4}, + {0x20cc6, 0x20cc8}, {0x20cca, 0x20ccd}, {0x20ce0, 0x20ce3}, {0x20ce6, 0x20cef}, + {0x20d00, 0x20d03}, {0x20d05, 0x20d0c}, {0x20d0e, 0x20d10}, {0x20d12, 0x20d44}, + {0x20d46, 0x20d48}, {0x20d4a, 0x20d4f}, {0x20d54, 0x20d63}, {0x20d66, 0x20d7f}, + {0x20d85, 0x20d96}, {0x20d9a, 0x20db1}, {0x20db3, 0x20dbb}, {0x20dc0, 0x20dc6}, + {0x20dcf, 0x20dd4}, {0x20dd8, 0x20ddf}, {0x20de6, 0x20def}, {0x20df2, 0x20df4}, + {0x20e01, 0x20e3a}, {0x20e3f, 0x20e5b}, {0x20e94, 0x20e97}, {0x20e99, 0x20e9f}, + {0x20ea1, 0x20ea3}, {0x20ead, 0x20eb9}, {0x20ebb, 0x20ebd}, {0x20ec0, 0x20ec4}, + {0x20ec8, 0x20ecd}, {0x20ed0, 0x20ed9}, {0x20edc, 0x20edf}, {0x20f00, 0x20f47}, + {0x20f49, 0x20f6c}, {0x20f71, 0x20f97}, {0x20f99, 0x20fbc}, {0x20fbe, 0x20fcc}, + {0x20fce, 0x20fda}, {0x21000, 0x210c5}, {0x210d0, 0x21248}, {0x2124a, 0x2124d}, + {0x21250, 0x21256}, {0x2125a, 0x2125d}, {0x21260, 0x21288}, {0x2128a, 0x2128d}, + {0x21290, 0x212b0}, {0x212b2, 0x212b5}, {0x212b8, 0x212be}, {0x212c2, 0x212c5}, + {0x212c8, 0x212d6}, {0x212d8, 0x21310}, {0x21312, 0x21315}, {0x21318, 0x2135a}, + {0x2135d, 0x2137c}, {0x21380, 0x21399}, {0x213a0, 0x213f5}, {0x213f8, 0x213fd}, + {0x21400, 0x2167f}, {0x21681, 0x2169c}, {0x216a0, 0x216f8}, {0x21700, 0x2170c}, + {0x2170e, 0x21714}, {0x21720, 0x21736}, {0x21740, 0x21753}, {0x21760, 0x2176c}, + {0x2176e, 0x21770}, {0x21780, 0x217dd}, {0x217e0, 0x217e9}, {0x217f0, 0x217f9}, + {0x21800, 0x2180d}, {0x21810, 0x21819}, {0x21820, 0x21877}, {0x21880, 0x218aa}, + {0x218b0, 0x218f5}, {0x21900, 0x2191e}, {0x21920, 0x2192b}, {0x21930, 0x2193b}, + {0x21944, 0x2196d}, {0x21970, 0x21974}, {0x21980, 0x219ab}, {0x219b0, 0x219c9}, + {0x219d0, 0x219da}, {0x219de, 0x21a1b}, {0x21a1e, 0x21a5e}, {0x21a60, 0x21a7c}, + {0x21a7f, 0x21a89}, {0x21a90, 0x21a99}, {0x21aa0, 0x21aad}, {0x21ab0, 0x21abe}, + {0x21b00, 0x21b4b}, {0x21b50, 0x21b7c}, {0x21b80, 0x21bf3}, {0x21bfc, 0x21c37}, + {0x21c3b, 0x21c49}, {0x21c4d, 0x21c88}, {0x21cc0, 0x21cc7}, {0x21cd0, 0x21cf9}, + {0x21d00, 0x21df9}, {0x21dfb, 0x21f15}, {0x21f18, 0x21f1d}, {0x21f20, 0x21f45}, + {0x21f48, 0x21f4d}, {0x21f50, 0x21f57}, {0x21f5f, 0x21f7d}, {0x21f80, 0x21fb4}, + {0x21fb6, 0x21fc4}, {0x21fc6, 0x21fd3}, {0x21fd6, 0x21fdb}, {0x21fdd, 0x21fef}, + {0x21ff2, 0x21ff4}, {0x21ff6, 0x21ffe}, {0x22010, 0x22027}, {0x22030, 0x2205e}, + {0x22074, 0x2208e}, {0x22090, 0x2209c}, {0x220a0, 0x220bf}, {0x220d0, 0x220f0}, + {0x22100, 0x2218b}, {0x22190, 0x22426}, {0x22440, 0x2244a}, {0x22460, 0x22b73}, + {0x22b76, 0x22b95}, {0x22b98, 0x22bb9}, {0x22bbd, 0x22bc8}, {0x22bca, 0x22bd2}, + {0x22bec, 0x22bef}, {0x22c00, 0x22c2e}, {0x22c30, 0x22c5e}, {0x22c60, 0x22cf3}, + {0x22cf9, 0x22d25}, {0x22d30, 0x22d67}, {0x22d7f, 0x22d96}, {0x22da0, 0x22da6}, + {0x22da8, 0x22dae}, {0x22db0, 0x22db6}, {0x22db8, 0x22dbe}, {0x22dc0, 0x22dc6}, + {0x22dc8, 0x22dce}, {0x22dd0, 0x22dd6}, {0x22dd8, 0x22dde}, {0x22de0, 0x22e49}, + {0x22e80, 0x22e99}, {0x22e9b, 0x22ef3}, {0x22f00, 0x22fd5}, {0x22ff0, 0x22ffb}, + {0x23001, 0x2303f}, {0x23041, 0x23096}, {0x23099, 0x230ff}, {0x23105, 0x2312e}, + {0x23131, 0x2318e}, {0x23190, 0x231ba}, {0x231c0, 0x231e3}, {0x231f0, 0x2321e}, + {0x23220, 0x232fe}, {0x23300, 0x24db5}, {0x24dc0, 0x29fea}, {0x2a000, 0x2a48c}, + {0x2a490, 0x2a4c6}, {0x2a4d0, 0x2a62b}, {0x2a640, 0x2a6f7}, {0x2a700, 0x2a7ae}, + {0x2a7b0, 0x2a7b7}, {0x2a7f7, 0x2a82b}, {0x2a830, 0x2a839}, {0x2a840, 0x2a877}, + {0x2a880, 0x2a8c5}, {0x2a8ce, 0x2a8d9}, {0x2a8e0, 0x2a8fd}, {0x2a900, 0x2a953}, + {0x2a95f, 0x2a97c}, {0x2a980, 0x2a9cd}, {0x2a9cf, 0x2a9d9}, {0x2a9de, 0x2a9fe}, + {0x2aa00, 0x2aa36}, {0x2aa40, 0x2aa4d}, {0x2aa50, 0x2aa59}, {0x2aa5c, 0x2aac2}, + {0x2aadb, 0x2aaf6}, {0x2ab01, 0x2ab06}, {0x2ab09, 0x2ab0e}, {0x2ab11, 0x2ab16}, + {0x2ab20, 0x2ab26}, {0x2ab28, 0x2ab2e}, {0x2ab30, 0x2ab65}, {0x2ab70, 0x2abed}, + {0x2abf0, 0x2abf9}, {0x2ac00, 0x2d7a3}, {0x2d7b0, 0x2d7c6}, {0x2d7cb, 0x2d7fb}, + {0x2f900, 0x2fa6d}, {0x2fa70, 0x2fad9}, {0x2fb00, 0x2fb06}, {0x2fb13, 0x2fb17}, + {0x2fb1d, 0x2fb36}, {0x2fb38, 0x2fb3c}, {0x2fb46, 0x2fbc1}, {0x2fbd3, 0x2fd3f}, + {0x2fd50, 0x2fd8f}, {0x2fd92, 0x2fdc7}, {0x2fdf0, 0x2fdfd}, {0x2fe00, 0x2fe19}, + {0x2fe20, 0x2fe52}, {0x2fe54, 0x2fe66}, {0x2fe68, 0x2fe6b}, {0x2fe70, 0x2fe74}, + {0x2fe76, 0x2fefc}, {0x2ff01, 0x2ffbe}, {0x2ffc2, 0x2ffc7}, {0x2ffca, 0x2ffcf}, + {0x2ffd2, 0x2ffd7}, {0x2ffda, 0x2ffdc}, {0x2ffe0, 0x2ffe6}, {0x2ffe8, 0x2ffee}, + {0x30021, 0x3007e}, {0x300a1, 0x300ac}, {0x300ae, 0x30377}, {0x3037a, 0x3037f}, + {0x30384, 0x3038a}, {0x3038e, 0x303a1}, {0x303a3, 0x3052f}, {0x30531, 0x30556}, + {0x30559, 0x3055f}, {0x30561, 0x30587}, {0x3058d, 0x3058f}, {0x30591, 0x305c7}, + {0x305d0, 0x305ea}, {0x305f0, 0x305f4}, {0x30606, 0x3061b}, {0x3061e, 0x306dc}, + {0x306de, 0x3070d}, {0x30710, 0x3074a}, {0x3074d, 0x307b1}, {0x307c0, 0x307fa}, + {0x30800, 0x3082d}, {0x30830, 0x3083e}, {0x30840, 0x3085b}, {0x30860, 0x3086a}, + {0x308a0, 0x308b4}, {0x308b6, 0x308bd}, {0x308d4, 0x308e1}, {0x308e3, 0x30983}, + {0x30985, 0x3098c}, {0x30993, 0x309a8}, {0x309aa, 0x309b0}, {0x309b6, 0x309b9}, + {0x309bc, 0x309c4}, {0x309cb, 0x309ce}, {0x309df, 0x309e3}, {0x309e6, 0x309fd}, + {0x30a01, 0x30a03}, {0x30a05, 0x30a0a}, {0x30a13, 0x30a28}, {0x30a2a, 0x30a30}, + {0x30a3e, 0x30a42}, {0x30a4b, 0x30a4d}, {0x30a59, 0x30a5c}, {0x30a66, 0x30a75}, + {0x30a81, 0x30a83}, {0x30a85, 0x30a8d}, {0x30a8f, 0x30a91}, {0x30a93, 0x30aa8}, + {0x30aaa, 0x30ab0}, {0x30ab5, 0x30ab9}, {0x30abc, 0x30ac5}, {0x30ac7, 0x30ac9}, + {0x30acb, 0x30acd}, {0x30ae0, 0x30ae3}, {0x30ae6, 0x30af1}, {0x30af9, 0x30aff}, + {0x30b01, 0x30b03}, {0x30b05, 0x30b0c}, {0x30b13, 0x30b28}, {0x30b2a, 0x30b30}, + {0x30b35, 0x30b39}, {0x30b3c, 0x30b44}, {0x30b4b, 0x30b4d}, {0x30b5f, 0x30b63}, + {0x30b66, 0x30b77}, {0x30b85, 0x30b8a}, {0x30b8e, 0x30b90}, {0x30b92, 0x30b95}, + {0x30ba8, 0x30baa}, {0x30bae, 0x30bb9}, {0x30bbe, 0x30bc2}, {0x30bc6, 0x30bc8}, + {0x30bca, 0x30bcd}, {0x30be6, 0x30bfa}, {0x30c00, 0x30c03}, {0x30c05, 0x30c0c}, + {0x30c0e, 0x30c10}, {0x30c12, 0x30c28}, {0x30c2a, 0x30c39}, {0x30c3d, 0x30c44}, + {0x30c46, 0x30c48}, {0x30c4a, 0x30c4d}, {0x30c58, 0x30c5a}, {0x30c60, 0x30c63}, + {0x30c66, 0x30c6f}, {0x30c78, 0x30c83}, {0x30c85, 0x30c8c}, {0x30c8e, 0x30c90}, + {0x30c92, 0x30ca8}, {0x30caa, 0x30cb3}, {0x30cb5, 0x30cb9}, {0x30cbc, 0x30cc4}, + {0x30cc6, 0x30cc8}, {0x30cca, 0x30ccd}, {0x30ce0, 0x30ce3}, {0x30ce6, 0x30cef}, + {0x30d00, 0x30d03}, {0x30d05, 0x30d0c}, {0x30d0e, 0x30d10}, {0x30d12, 0x30d44}, + {0x30d46, 0x30d48}, {0x30d4a, 0x30d4f}, {0x30d54, 0x30d63}, {0x30d66, 0x30d7f}, + {0x30d85, 0x30d96}, {0x30d9a, 0x30db1}, {0x30db3, 0x30dbb}, {0x30dc0, 0x30dc6}, + {0x30dcf, 0x30dd4}, {0x30dd8, 0x30ddf}, {0x30de6, 0x30def}, {0x30df2, 0x30df4}, + {0x30e01, 0x30e3a}, {0x30e3f, 0x30e5b}, {0x30e94, 0x30e97}, {0x30e99, 0x30e9f}, + {0x30ea1, 0x30ea3}, {0x30ead, 0x30eb9}, {0x30ebb, 0x30ebd}, {0x30ec0, 0x30ec4}, + {0x30ec8, 0x30ecd}, {0x30ed0, 0x30ed9}, {0x30edc, 0x30edf}, {0x30f00, 0x30f47}, + {0x30f49, 0x30f6c}, {0x30f71, 0x30f97}, {0x30f99, 0x30fbc}, {0x30fbe, 0x30fcc}, + {0x30fce, 0x30fda}, {0x31000, 0x310c5}, {0x310d0, 0x31248}, {0x3124a, 0x3124d}, + {0x31250, 0x31256}, {0x3125a, 0x3125d}, {0x31260, 0x31288}, {0x3128a, 0x3128d}, + {0x31290, 0x312b0}, {0x312b2, 0x312b5}, {0x312b8, 0x312be}, {0x312c2, 0x312c5}, + {0x312c8, 0x312d6}, {0x312d8, 0x31310}, {0x31312, 0x31315}, {0x31318, 0x3135a}, + {0x3135d, 0x3137c}, {0x31380, 0x31399}, {0x313a0, 0x313f5}, {0x313f8, 0x313fd}, + {0x31400, 0x3167f}, {0x31681, 0x3169c}, {0x316a0, 0x316f8}, {0x31700, 0x3170c}, + {0x3170e, 0x31714}, {0x31720, 0x31736}, {0x31740, 0x31753}, {0x31760, 0x3176c}, + {0x3176e, 0x31770}, {0x31780, 0x317dd}, {0x317e0, 0x317e9}, {0x317f0, 0x317f9}, + {0x31800, 0x3180d}, {0x31810, 0x31819}, {0x31820, 0x31877}, {0x31880, 0x318aa}, + {0x318b0, 0x318f5}, {0x31900, 0x3191e}, {0x31920, 0x3192b}, {0x31930, 0x3193b}, + {0x31944, 0x3196d}, {0x31970, 0x31974}, {0x31980, 0x319ab}, {0x319b0, 0x319c9}, + {0x319d0, 0x319da}, {0x319de, 0x31a1b}, {0x31a1e, 0x31a5e}, {0x31a60, 0x31a7c}, + {0x31a7f, 0x31a89}, {0x31a90, 0x31a99}, {0x31aa0, 0x31aad}, {0x31ab0, 0x31abe}, + {0x31b00, 0x31b4b}, {0x31b50, 0x31b7c}, {0x31b80, 0x31bf3}, {0x31bfc, 0x31c37}, + {0x31c3b, 0x31c49}, {0x31c4d, 0x31c88}, {0x31cc0, 0x31cc7}, {0x31cd0, 0x31cf9}, + {0x31d00, 0x31df9}, {0x31dfb, 0x31f15}, {0x31f18, 0x31f1d}, {0x31f20, 0x31f45}, + {0x31f48, 0x31f4d}, {0x31f50, 0x31f57}, {0x31f5f, 0x31f7d}, {0x31f80, 0x31fb4}, + {0x31fb6, 0x31fc4}, {0x31fc6, 0x31fd3}, {0x31fd6, 0x31fdb}, {0x31fdd, 0x31fef}, + {0x31ff2, 0x31ff4}, {0x31ff6, 0x31ffe}, {0x32010, 0x32027}, {0x32030, 0x3205e}, + {0x32074, 0x3208e}, {0x32090, 0x3209c}, {0x320a0, 0x320bf}, {0x320d0, 0x320f0}, + {0x32100, 0x3218b}, {0x32190, 0x32426}, {0x32440, 0x3244a}, {0x32460, 0x32b73}, + {0x32b76, 0x32b95}, {0x32b98, 0x32bb9}, {0x32bbd, 0x32bc8}, {0x32bca, 0x32bd2}, + {0x32bec, 0x32bef}, {0x32c00, 0x32c2e}, {0x32c30, 0x32c5e}, {0x32c60, 0x32cf3}, + {0x32cf9, 0x32d25}, {0x32d30, 0x32d67}, {0x32d7f, 0x32d96}, {0x32da0, 0x32da6}, + {0x32da8, 0x32dae}, {0x32db0, 0x32db6}, {0x32db8, 0x32dbe}, {0x32dc0, 0x32dc6}, + {0x32dc8, 0x32dce}, {0x32dd0, 0x32dd6}, {0x32dd8, 0x32dde}, {0x32de0, 0x32e49}, + {0x32e80, 0x32e99}, {0x32e9b, 0x32ef3}, {0x32f00, 0x32fd5}, {0x32ff0, 0x32ffb}, + {0x33001, 0x3303f}, {0x33041, 0x33096}, {0x33099, 0x330ff}, {0x33105, 0x3312e}, + {0x33131, 0x3318e}, {0x33190, 0x331ba}, {0x331c0, 0x331e3}, {0x331f0, 0x3321e}, + {0x33220, 0x332fe}, {0x33300, 0x34db5}, {0x34dc0, 0x39fea}, {0x3a000, 0x3a48c}, + {0x3a490, 0x3a4c6}, {0x3a4d0, 0x3a62b}, {0x3a640, 0x3a6f7}, {0x3a700, 0x3a7ae}, + {0x3a7b0, 0x3a7b7}, {0x3a7f7, 0x3a82b}, {0x3a830, 0x3a839}, {0x3a840, 0x3a877}, + {0x3a880, 0x3a8c5}, {0x3a8ce, 0x3a8d9}, {0x3a8e0, 0x3a8fd}, {0x3a900, 0x3a953}, + {0x3a95f, 0x3a97c}, {0x3a980, 0x3a9cd}, {0x3a9cf, 0x3a9d9}, {0x3a9de, 0x3a9fe}, + {0x3aa00, 0x3aa36}, {0x3aa40, 0x3aa4d}, {0x3aa50, 0x3aa59}, {0x3aa5c, 0x3aac2}, + {0x3aadb, 0x3aaf6}, {0x3ab01, 0x3ab06}, {0x3ab09, 0x3ab0e}, {0x3ab11, 0x3ab16}, + {0x3ab20, 0x3ab26}, {0x3ab28, 0x3ab2e}, {0x3ab30, 0x3ab65}, {0x3ab70, 0x3abed}, + {0x3abf0, 0x3abf9}, {0x3ac00, 0x3d7a3}, {0x3d7b0, 0x3d7c6}, {0x3d7cb, 0x3d7fb}, + {0x3f900, 0x3fa6d}, {0x3fa70, 0x3fad9}, {0x3fb00, 0x3fb06}, {0x3fb13, 0x3fb17}, + {0x3fb1d, 0x3fb36}, {0x3fb38, 0x3fb3c}, {0x3fb46, 0x3fbc1}, {0x3fbd3, 0x3fd3f}, + {0x3fd50, 0x3fd8f}, {0x3fd92, 0x3fdc7}, {0x3fdf0, 0x3fdfd}, {0x3fe00, 0x3fe19}, + {0x3fe20, 0x3fe52}, {0x3fe54, 0x3fe66}, {0x3fe68, 0x3fe6b}, {0x3fe70, 0x3fe74}, + {0x3fe76, 0x3fefc}, {0x3ff01, 0x3ffbe}, {0x3ffc2, 0x3ffc7}, {0x3ffca, 0x3ffcf}, + {0x3ffd2, 0x3ffd7}, {0x3ffda, 0x3ffdc}, {0x3ffe0, 0x3ffe6}, {0x3ffe8, 0x3ffee}, + {0x40021, 0x4007e}, {0x400a1, 0x400ac}, {0x400ae, 0x40377}, {0x4037a, 0x4037f}, + {0x40384, 0x4038a}, {0x4038e, 0x403a1}, {0x403a3, 0x4052f}, {0x40531, 0x40556}, + {0x40559, 0x4055f}, {0x40561, 0x40587}, {0x4058d, 0x4058f}, {0x40591, 0x405c7}, + {0x405d0, 0x405ea}, {0x405f0, 0x405f4}, {0x40606, 0x4061b}, {0x4061e, 0x406dc}, + {0x406de, 0x4070d}, {0x40710, 0x4074a}, {0x4074d, 0x407b1}, {0x407c0, 0x407fa}, + {0x40800, 0x4082d}, {0x40830, 0x4083e}, {0x40840, 0x4085b}, {0x40860, 0x4086a}, + {0x408a0, 0x408b4}, {0x408b6, 0x408bd}, {0x408d4, 0x408e1}, {0x408e3, 0x40983}, + {0x40985, 0x4098c}, {0x40993, 0x409a8}, {0x409aa, 0x409b0}, {0x409b6, 0x409b9}, + {0x409bc, 0x409c4}, {0x409cb, 0x409ce}, {0x409df, 0x409e3}, {0x409e6, 0x409fd}, + {0x40a01, 0x40a03}, {0x40a05, 0x40a0a}, {0x40a13, 0x40a28}, {0x40a2a, 0x40a30}, + {0x40a3e, 0x40a42}, {0x40a4b, 0x40a4d}, {0x40a59, 0x40a5c}, {0x40a66, 0x40a75}, + {0x40a81, 0x40a83}, {0x40a85, 0x40a8d}, {0x40a8f, 0x40a91}, {0x40a93, 0x40aa8}, + {0x40aaa, 0x40ab0}, {0x40ab5, 0x40ab9}, {0x40abc, 0x40ac5}, {0x40ac7, 0x40ac9}, + {0x40acb, 0x40acd}, {0x40ae0, 0x40ae3}, {0x40ae6, 0x40af1}, {0x40af9, 0x40aff}, + {0x40b01, 0x40b03}, {0x40b05, 0x40b0c}, {0x40b13, 0x40b28}, {0x40b2a, 0x40b30}, + {0x40b35, 0x40b39}, {0x40b3c, 0x40b44}, {0x40b4b, 0x40b4d}, {0x40b5f, 0x40b63}, + {0x40b66, 0x40b77}, {0x40b85, 0x40b8a}, {0x40b8e, 0x40b90}, {0x40b92, 0x40b95}, + {0x40ba8, 0x40baa}, {0x40bae, 0x40bb9}, {0x40bbe, 0x40bc2}, {0x40bc6, 0x40bc8}, + {0x40bca, 0x40bcd}, {0x40be6, 0x40bfa}, {0x40c00, 0x40c03}, {0x40c05, 0x40c0c}, + {0x40c0e, 0x40c10}, {0x40c12, 0x40c28}, {0x40c2a, 0x40c39}, {0x40c3d, 0x40c44}, + {0x40c46, 0x40c48}, {0x40c4a, 0x40c4d}, {0x40c58, 0x40c5a}, {0x40c60, 0x40c63}, + {0x40c66, 0x40c6f}, {0x40c78, 0x40c83}, {0x40c85, 0x40c8c}, {0x40c8e, 0x40c90}, + {0x40c92, 0x40ca8}, {0x40caa, 0x40cb3}, {0x40cb5, 0x40cb9}, {0x40cbc, 0x40cc4}, + {0x40cc6, 0x40cc8}, {0x40cca, 0x40ccd}, {0x40ce0, 0x40ce3}, {0x40ce6, 0x40cef}, + {0x40d00, 0x40d03}, {0x40d05, 0x40d0c}, {0x40d0e, 0x40d10}, {0x40d12, 0x40d44}, + {0x40d46, 0x40d48}, {0x40d4a, 0x40d4f}, {0x40d54, 0x40d63}, {0x40d66, 0x40d7f}, + {0x40d85, 0x40d96}, {0x40d9a, 0x40db1}, {0x40db3, 0x40dbb}, {0x40dc0, 0x40dc6}, + {0x40dcf, 0x40dd4}, {0x40dd8, 0x40ddf}, {0x40de6, 0x40def}, {0x40df2, 0x40df4}, + {0x40e01, 0x40e3a}, {0x40e3f, 0x40e5b}, {0x40e94, 0x40e97}, {0x40e99, 0x40e9f}, + {0x40ea1, 0x40ea3}, {0x40ead, 0x40eb9}, {0x40ebb, 0x40ebd}, {0x40ec0, 0x40ec4}, + {0x40ec8, 0x40ecd}, {0x40ed0, 0x40ed9}, {0x40edc, 0x40edf}, {0x40f00, 0x40f47}, + {0x40f49, 0x40f6c}, {0x40f71, 0x40f97}, {0x40f99, 0x40fbc}, {0x40fbe, 0x40fcc}, + {0x40fce, 0x40fda}, {0x41000, 0x410c5}, {0x410d0, 0x41248}, {0x4124a, 0x4124d}, + {0x41250, 0x41256}, {0x4125a, 0x4125d}, {0x41260, 0x41288}, {0x4128a, 0x4128d}, + {0x41290, 0x412b0}, {0x412b2, 0x412b5}, {0x412b8, 0x412be}, {0x412c2, 0x412c5}, + {0x412c8, 0x412d6}, {0x412d8, 0x41310}, {0x41312, 0x41315}, {0x41318, 0x4135a}, + {0x4135d, 0x4137c}, {0x41380, 0x41399}, {0x413a0, 0x413f5}, {0x413f8, 0x413fd}, + {0x41400, 0x4167f}, {0x41681, 0x4169c}, {0x416a0, 0x416f8}, {0x41700, 0x4170c}, + {0x4170e, 0x41714}, {0x41720, 0x41736}, {0x41740, 0x41753}, {0x41760, 0x4176c}, + {0x4176e, 0x41770}, {0x41780, 0x417dd}, {0x417e0, 0x417e9}, {0x417f0, 0x417f9}, + {0x41800, 0x4180d}, {0x41810, 0x41819}, {0x41820, 0x41877}, {0x41880, 0x418aa}, + {0x418b0, 0x418f5}, {0x41900, 0x4191e}, {0x41920, 0x4192b}, {0x41930, 0x4193b}, + {0x41944, 0x4196d}, {0x41970, 0x41974}, {0x41980, 0x419ab}, {0x419b0, 0x419c9}, + {0x419d0, 0x419da}, {0x419de, 0x41a1b}, {0x41a1e, 0x41a5e}, {0x41a60, 0x41a7c}, + {0x41a7f, 0x41a89}, {0x41a90, 0x41a99}, {0x41aa0, 0x41aad}, {0x41ab0, 0x41abe}, + {0x41b00, 0x41b4b}, {0x41b50, 0x41b7c}, {0x41b80, 0x41bf3}, {0x41bfc, 0x41c37}, + {0x41c3b, 0x41c49}, {0x41c4d, 0x41c88}, {0x41cc0, 0x41cc7}, {0x41cd0, 0x41cf9}, + {0x41d00, 0x41df9}, {0x41dfb, 0x41f15}, {0x41f18, 0x41f1d}, {0x41f20, 0x41f45}, + {0x41f48, 0x41f4d}, {0x41f50, 0x41f57}, {0x41f5f, 0x41f7d}, {0x41f80, 0x41fb4}, + {0x41fb6, 0x41fc4}, {0x41fc6, 0x41fd3}, {0x41fd6, 0x41fdb}, {0x41fdd, 0x41fef}, + {0x41ff2, 0x41ff4}, {0x41ff6, 0x41ffe}, {0x42010, 0x42027}, {0x42030, 0x4205e}, + {0x42074, 0x4208e}, {0x42090, 0x4209c}, {0x420a0, 0x420bf}, {0x420d0, 0x420f0}, + {0x42100, 0x4218b}, {0x42190, 0x42426}, {0x42440, 0x4244a}, {0x42460, 0x42b73}, + {0x42b76, 0x42b95}, {0x42b98, 0x42bb9}, {0x42bbd, 0x42bc8}, {0x42bca, 0x42bd2}, + {0x42bec, 0x42bef}, {0x42c00, 0x42c2e}, {0x42c30, 0x42c5e}, {0x42c60, 0x42cf3}, + {0x42cf9, 0x42d25}, {0x42d30, 0x42d67}, {0x42d7f, 0x42d96}, {0x42da0, 0x42da6}, + {0x42da8, 0x42dae}, {0x42db0, 0x42db6}, {0x42db8, 0x42dbe}, {0x42dc0, 0x42dc6}, + {0x42dc8, 0x42dce}, {0x42dd0, 0x42dd6}, {0x42dd8, 0x42dde}, {0x42de0, 0x42e49}, + {0x42e80, 0x42e99}, {0x42e9b, 0x42ef3}, {0x42f00, 0x42fd5}, {0x42ff0, 0x42ffb}, + {0x43001, 0x4303f}, {0x43041, 0x43096}, {0x43099, 0x430ff}, {0x43105, 0x4312e}, + {0x43131, 0x4318e}, {0x43190, 0x431ba}, {0x431c0, 0x431e3}, {0x431f0, 0x4321e}, + {0x43220, 0x432fe}, {0x43300, 0x44db5}, {0x44dc0, 0x49fea}, {0x4a000, 0x4a48c}, + {0x4a490, 0x4a4c6}, {0x4a4d0, 0x4a62b}, {0x4a640, 0x4a6f7}, {0x4a700, 0x4a7ae}, + {0x4a7b0, 0x4a7b7}, {0x4a7f7, 0x4a82b}, {0x4a830, 0x4a839}, {0x4a840, 0x4a877}, + {0x4a880, 0x4a8c5}, {0x4a8ce, 0x4a8d9}, {0x4a8e0, 0x4a8fd}, {0x4a900, 0x4a953}, + {0x4a95f, 0x4a97c}, {0x4a980, 0x4a9cd}, {0x4a9cf, 0x4a9d9}, {0x4a9de, 0x4a9fe}, + {0x4aa00, 0x4aa36}, {0x4aa40, 0x4aa4d}, {0x4aa50, 0x4aa59}, {0x4aa5c, 0x4aac2}, + {0x4aadb, 0x4aaf6}, {0x4ab01, 0x4ab06}, {0x4ab09, 0x4ab0e}, {0x4ab11, 0x4ab16}, + {0x4ab20, 0x4ab26}, {0x4ab28, 0x4ab2e}, {0x4ab30, 0x4ab65}, {0x4ab70, 0x4abed}, + {0x4abf0, 0x4abf9}, {0x4ac00, 0x4d7a3}, {0x4d7b0, 0x4d7c6}, {0x4d7cb, 0x4d7fb}, + {0x4f900, 0x4fa6d}, {0x4fa70, 0x4fad9}, {0x4fb00, 0x4fb06}, {0x4fb13, 0x4fb17}, + {0x4fb1d, 0x4fb36}, {0x4fb38, 0x4fb3c}, {0x4fb46, 0x4fbc1}, {0x4fbd3, 0x4fd3f}, + {0x4fd50, 0x4fd8f}, {0x4fd92, 0x4fdc7}, {0x4fdf0, 0x4fdfd}, {0x4fe00, 0x4fe19}, + {0x4fe20, 0x4fe52}, {0x4fe54, 0x4fe66}, {0x4fe68, 0x4fe6b}, {0x4fe70, 0x4fe74}, + {0x4fe76, 0x4fefc}, {0x4ff01, 0x4ffbe}, {0x4ffc2, 0x4ffc7}, {0x4ffca, 0x4ffcf}, + {0x4ffd2, 0x4ffd7}, {0x4ffda, 0x4ffdc}, {0x4ffe0, 0x4ffe6}, {0x4ffe8, 0x4ffee}, + {0x50021, 0x5007e}, {0x500a1, 0x500ac}, {0x500ae, 0x50377}, {0x5037a, 0x5037f}, + {0x50384, 0x5038a}, {0x5038e, 0x503a1}, {0x503a3, 0x5052f}, {0x50531, 0x50556}, + {0x50559, 0x5055f}, {0x50561, 0x50587}, {0x5058d, 0x5058f}, {0x50591, 0x505c7}, + {0x505d0, 0x505ea}, {0x505f0, 0x505f4}, {0x50606, 0x5061b}, {0x5061e, 0x506dc}, + {0x506de, 0x5070d}, {0x50710, 0x5074a}, {0x5074d, 0x507b1}, {0x507c0, 0x507fa}, + {0x50800, 0x5082d}, {0x50830, 0x5083e}, {0x50840, 0x5085b}, {0x50860, 0x5086a}, + {0x508a0, 0x508b4}, {0x508b6, 0x508bd}, {0x508d4, 0x508e1}, {0x508e3, 0x50983}, + {0x50985, 0x5098c}, {0x50993, 0x509a8}, {0x509aa, 0x509b0}, {0x509b6, 0x509b9}, + {0x509bc, 0x509c4}, {0x509cb, 0x509ce}, {0x509df, 0x509e3}, {0x509e6, 0x509fd}, + {0x50a01, 0x50a03}, {0x50a05, 0x50a0a}, {0x50a13, 0x50a28}, {0x50a2a, 0x50a30}, + {0x50a3e, 0x50a42}, {0x50a4b, 0x50a4d}, {0x50a59, 0x50a5c}, {0x50a66, 0x50a75}, + {0x50a81, 0x50a83}, {0x50a85, 0x50a8d}, {0x50a8f, 0x50a91}, {0x50a93, 0x50aa8}, + {0x50aaa, 0x50ab0}, {0x50ab5, 0x50ab9}, {0x50abc, 0x50ac5}, {0x50ac7, 0x50ac9}, + {0x50acb, 0x50acd}, {0x50ae0, 0x50ae3}, {0x50ae6, 0x50af1}, {0x50af9, 0x50aff}, + {0x50b01, 0x50b03}, {0x50b05, 0x50b0c}, {0x50b13, 0x50b28}, {0x50b2a, 0x50b30}, + {0x50b35, 0x50b39}, {0x50b3c, 0x50b44}, {0x50b4b, 0x50b4d}, {0x50b5f, 0x50b63}, + {0x50b66, 0x50b77}, {0x50b85, 0x50b8a}, {0x50b8e, 0x50b90}, {0x50b92, 0x50b95}, + {0x50ba8, 0x50baa}, {0x50bae, 0x50bb9}, {0x50bbe, 0x50bc2}, {0x50bc6, 0x50bc8}, + {0x50bca, 0x50bcd}, {0x50be6, 0x50bfa}, {0x50c00, 0x50c03}, {0x50c05, 0x50c0c}, + {0x50c0e, 0x50c10}, {0x50c12, 0x50c28}, {0x50c2a, 0x50c39}, {0x50c3d, 0x50c44}, + {0x50c46, 0x50c48}, {0x50c4a, 0x50c4d}, {0x50c58, 0x50c5a}, {0x50c60, 0x50c63}, + {0x50c66, 0x50c6f}, {0x50c78, 0x50c83}, {0x50c85, 0x50c8c}, {0x50c8e, 0x50c90}, + {0x50c92, 0x50ca8}, {0x50caa, 0x50cb3}, {0x50cb5, 0x50cb9}, {0x50cbc, 0x50cc4}, + {0x50cc6, 0x50cc8}, {0x50cca, 0x50ccd}, {0x50ce0, 0x50ce3}, {0x50ce6, 0x50cef}, + {0x50d00, 0x50d03}, {0x50d05, 0x50d0c}, {0x50d0e, 0x50d10}, {0x50d12, 0x50d44}, + {0x50d46, 0x50d48}, {0x50d4a, 0x50d4f}, {0x50d54, 0x50d63}, {0x50d66, 0x50d7f}, + {0x50d85, 0x50d96}, {0x50d9a, 0x50db1}, {0x50db3, 0x50dbb}, {0x50dc0, 0x50dc6}, + {0x50dcf, 0x50dd4}, {0x50dd8, 0x50ddf}, {0x50de6, 0x50def}, {0x50df2, 0x50df4}, + {0x50e01, 0x50e3a}, {0x50e3f, 0x50e5b}, {0x50e94, 0x50e97}, {0x50e99, 0x50e9f}, + {0x50ea1, 0x50ea3}, {0x50ead, 0x50eb9}, {0x50ebb, 0x50ebd}, {0x50ec0, 0x50ec4}, + {0x50ec8, 0x50ecd}, {0x50ed0, 0x50ed9}, {0x50edc, 0x50edf}, {0x50f00, 0x50f47}, + {0x50f49, 0x50f6c}, {0x50f71, 0x50f97}, {0x50f99, 0x50fbc}, {0x50fbe, 0x50fcc}, + {0x50fce, 0x50fda}, {0x51000, 0x510c5}, {0x510d0, 0x51248}, {0x5124a, 0x5124d}, + {0x51250, 0x51256}, {0x5125a, 0x5125d}, {0x51260, 0x51288}, {0x5128a, 0x5128d}, + {0x51290, 0x512b0}, {0x512b2, 0x512b5}, {0x512b8, 0x512be}, {0x512c2, 0x512c5}, + {0x512c8, 0x512d6}, {0x512d8, 0x51310}, {0x51312, 0x51315}, {0x51318, 0x5135a}, + {0x5135d, 0x5137c}, {0x51380, 0x51399}, {0x513a0, 0x513f5}, {0x513f8, 0x513fd}, + {0x51400, 0x5167f}, {0x51681, 0x5169c}, {0x516a0, 0x516f8}, {0x51700, 0x5170c}, + {0x5170e, 0x51714}, {0x51720, 0x51736}, {0x51740, 0x51753}, {0x51760, 0x5176c}, + {0x5176e, 0x51770}, {0x51780, 0x517dd}, {0x517e0, 0x517e9}, {0x517f0, 0x517f9}, + {0x51800, 0x5180d}, {0x51810, 0x51819}, {0x51820, 0x51877}, {0x51880, 0x518aa}, + {0x518b0, 0x518f5}, {0x51900, 0x5191e}, {0x51920, 0x5192b}, {0x51930, 0x5193b}, + {0x51944, 0x5196d}, {0x51970, 0x51974}, {0x51980, 0x519ab}, {0x519b0, 0x519c9}, + {0x519d0, 0x519da}, {0x519de, 0x51a1b}, {0x51a1e, 0x51a5e}, {0x51a60, 0x51a7c}, + {0x51a7f, 0x51a89}, {0x51a90, 0x51a99}, {0x51aa0, 0x51aad}, {0x51ab0, 0x51abe}, + {0x51b00, 0x51b4b}, {0x51b50, 0x51b7c}, {0x51b80, 0x51bf3}, {0x51bfc, 0x51c37}, + {0x51c3b, 0x51c49}, {0x51c4d, 0x51c88}, {0x51cc0, 0x51cc7}, {0x51cd0, 0x51cf9}, + {0x51d00, 0x51df9}, {0x51dfb, 0x51f15}, {0x51f18, 0x51f1d}, {0x51f20, 0x51f45}, + {0x51f48, 0x51f4d}, {0x51f50, 0x51f57}, {0x51f5f, 0x51f7d}, {0x51f80, 0x51fb4}, + {0x51fb6, 0x51fc4}, {0x51fc6, 0x51fd3}, {0x51fd6, 0x51fdb}, {0x51fdd, 0x51fef}, + {0x51ff2, 0x51ff4}, {0x51ff6, 0x51ffe}, {0x52010, 0x52027}, {0x52030, 0x5205e}, + {0x52074, 0x5208e}, {0x52090, 0x5209c}, {0x520a0, 0x520bf}, {0x520d0, 0x520f0}, + {0x52100, 0x5218b}, {0x52190, 0x52426}, {0x52440, 0x5244a}, {0x52460, 0x52b73}, + {0x52b76, 0x52b95}, {0x52b98, 0x52bb9}, {0x52bbd, 0x52bc8}, {0x52bca, 0x52bd2}, + {0x52bec, 0x52bef}, {0x52c00, 0x52c2e}, {0x52c30, 0x52c5e}, {0x52c60, 0x52cf3}, + {0x52cf9, 0x52d25}, {0x52d30, 0x52d67}, {0x52d7f, 0x52d96}, {0x52da0, 0x52da6}, + {0x52da8, 0x52dae}, {0x52db0, 0x52db6}, {0x52db8, 0x52dbe}, {0x52dc0, 0x52dc6}, + {0x52dc8, 0x52dce}, {0x52dd0, 0x52dd6}, {0x52dd8, 0x52dde}, {0x52de0, 0x52e49}, + {0x52e80, 0x52e99}, {0x52e9b, 0x52ef3}, {0x52f00, 0x52fd5}, {0x52ff0, 0x52ffb}, + {0x53001, 0x5303f}, {0x53041, 0x53096}, {0x53099, 0x530ff}, {0x53105, 0x5312e}, + {0x53131, 0x5318e}, {0x53190, 0x531ba}, {0x531c0, 0x531e3}, {0x531f0, 0x5321e}, + {0x53220, 0x532fe}, {0x53300, 0x54db5}, {0x54dc0, 0x59fea}, {0x5a000, 0x5a48c}, + {0x5a490, 0x5a4c6}, {0x5a4d0, 0x5a62b}, {0x5a640, 0x5a6f7}, {0x5a700, 0x5a7ae}, + {0x5a7b0, 0x5a7b7}, {0x5a7f7, 0x5a82b}, {0x5a830, 0x5a839}, {0x5a840, 0x5a877}, + {0x5a880, 0x5a8c5}, {0x5a8ce, 0x5a8d9}, {0x5a8e0, 0x5a8fd}, {0x5a900, 0x5a953}, + {0x5a95f, 0x5a97c}, {0x5a980, 0x5a9cd}, {0x5a9cf, 0x5a9d9}, {0x5a9de, 0x5a9fe}, + {0x5aa00, 0x5aa36}, {0x5aa40, 0x5aa4d}, {0x5aa50, 0x5aa59}, {0x5aa5c, 0x5aac2}, + {0x5aadb, 0x5aaf6}, {0x5ab01, 0x5ab06}, {0x5ab09, 0x5ab0e}, {0x5ab11, 0x5ab16}, + {0x5ab20, 0x5ab26}, {0x5ab28, 0x5ab2e}, {0x5ab30, 0x5ab65}, {0x5ab70, 0x5abed}, + {0x5abf0, 0x5abf9}, {0x5ac00, 0x5d7a3}, {0x5d7b0, 0x5d7c6}, {0x5d7cb, 0x5d7fb}, + {0x5f900, 0x5fa6d}, {0x5fa70, 0x5fad9}, {0x5fb00, 0x5fb06}, {0x5fb13, 0x5fb17}, + {0x5fb1d, 0x5fb36}, {0x5fb38, 0x5fb3c}, {0x5fb46, 0x5fbc1}, {0x5fbd3, 0x5fd3f}, + {0x5fd50, 0x5fd8f}, {0x5fd92, 0x5fdc7}, {0x5fdf0, 0x5fdfd}, {0x5fe00, 0x5fe19}, + {0x5fe20, 0x5fe52}, {0x5fe54, 0x5fe66}, {0x5fe68, 0x5fe6b}, {0x5fe70, 0x5fe74}, + {0x5fe76, 0x5fefc}, {0x5ff01, 0x5ffbe}, {0x5ffc2, 0x5ffc7}, {0x5ffca, 0x5ffcf}, + {0x5ffd2, 0x5ffd7}, {0x5ffda, 0x5ffdc}, {0x5ffe0, 0x5ffe6}, {0x5ffe8, 0x5ffee}, + {0x60021, 0x6007e}, {0x600a1, 0x600ac}, {0x600ae, 0x60377}, {0x6037a, 0x6037f}, + {0x60384, 0x6038a}, {0x6038e, 0x603a1}, {0x603a3, 0x6052f}, {0x60531, 0x60556}, + {0x60559, 0x6055f}, {0x60561, 0x60587}, {0x6058d, 0x6058f}, {0x60591, 0x605c7}, + {0x605d0, 0x605ea}, {0x605f0, 0x605f4}, {0x60606, 0x6061b}, {0x6061e, 0x606dc}, + {0x606de, 0x6070d}, {0x60710, 0x6074a}, {0x6074d, 0x607b1}, {0x607c0, 0x607fa}, + {0x60800, 0x6082d}, {0x60830, 0x6083e}, {0x60840, 0x6085b}, {0x60860, 0x6086a}, + {0x608a0, 0x608b4}, {0x608b6, 0x608bd}, {0x608d4, 0x608e1}, {0x608e3, 0x60983}, + {0x60985, 0x6098c}, {0x60993, 0x609a8}, {0x609aa, 0x609b0}, {0x609b6, 0x609b9}, + {0x609bc, 0x609c4}, {0x609cb, 0x609ce}, {0x609df, 0x609e3}, {0x609e6, 0x609fd}, + {0x60a01, 0x60a03}, {0x60a05, 0x60a0a}, {0x60a13, 0x60a28}, {0x60a2a, 0x60a30}, + {0x60a3e, 0x60a42}, {0x60a4b, 0x60a4d}, {0x60a59, 0x60a5c}, {0x60a66, 0x60a75}, + {0x60a81, 0x60a83}, {0x60a85, 0x60a8d}, {0x60a8f, 0x60a91}, {0x60a93, 0x60aa8}, + {0x60aaa, 0x60ab0}, {0x60ab5, 0x60ab9}, {0x60abc, 0x60ac5}, {0x60ac7, 0x60ac9}, + {0x60acb, 0x60acd}, {0x60ae0, 0x60ae3}, {0x60ae6, 0x60af1}, {0x60af9, 0x60aff}, + {0x60b01, 0x60b03}, {0x60b05, 0x60b0c}, {0x60b13, 0x60b28}, {0x60b2a, 0x60b30}, + {0x60b35, 0x60b39}, {0x60b3c, 0x60b44}, {0x60b4b, 0x60b4d}, {0x60b5f, 0x60b63}, + {0x60b66, 0x60b77}, {0x60b85, 0x60b8a}, {0x60b8e, 0x60b90}, {0x60b92, 0x60b95}, + {0x60ba8, 0x60baa}, {0x60bae, 0x60bb9}, {0x60bbe, 0x60bc2}, {0x60bc6, 0x60bc8}, + {0x60bca, 0x60bcd}, {0x60be6, 0x60bfa}, {0x60c00, 0x60c03}, {0x60c05, 0x60c0c}, + {0x60c0e, 0x60c10}, {0x60c12, 0x60c28}, {0x60c2a, 0x60c39}, {0x60c3d, 0x60c44}, + {0x60c46, 0x60c48}, {0x60c4a, 0x60c4d}, {0x60c58, 0x60c5a}, {0x60c60, 0x60c63}, + {0x60c66, 0x60c6f}, {0x60c78, 0x60c83}, {0x60c85, 0x60c8c}, {0x60c8e, 0x60c90}, + {0x60c92, 0x60ca8}, {0x60caa, 0x60cb3}, {0x60cb5, 0x60cb9}, {0x60cbc, 0x60cc4}, + {0x60cc6, 0x60cc8}, {0x60cca, 0x60ccd}, {0x60ce0, 0x60ce3}, {0x60ce6, 0x60cef}, + {0x60d00, 0x60d03}, {0x60d05, 0x60d0c}, {0x60d0e, 0x60d10}, {0x60d12, 0x60d44}, + {0x60d46, 0x60d48}, {0x60d4a, 0x60d4f}, {0x60d54, 0x60d63}, {0x60d66, 0x60d7f}, + {0x60d85, 0x60d96}, {0x60d9a, 0x60db1}, {0x60db3, 0x60dbb}, {0x60dc0, 0x60dc6}, + {0x60dcf, 0x60dd4}, {0x60dd8, 0x60ddf}, {0x60de6, 0x60def}, {0x60df2, 0x60df4}, + {0x60e01, 0x60e3a}, {0x60e3f, 0x60e5b}, {0x60e94, 0x60e97}, {0x60e99, 0x60e9f}, + {0x60ea1, 0x60ea3}, {0x60ead, 0x60eb9}, {0x60ebb, 0x60ebd}, {0x60ec0, 0x60ec4}, + {0x60ec8, 0x60ecd}, {0x60ed0, 0x60ed9}, {0x60edc, 0x60edf}, {0x60f00, 0x60f47}, + {0x60f49, 0x60f6c}, {0x60f71, 0x60f97}, {0x60f99, 0x60fbc}, {0x60fbe, 0x60fcc}, + {0x60fce, 0x60fda}, {0x61000, 0x610c5}, {0x610d0, 0x61248}, {0x6124a, 0x6124d}, + {0x61250, 0x61256}, {0x6125a, 0x6125d}, {0x61260, 0x61288}, {0x6128a, 0x6128d}, + {0x61290, 0x612b0}, {0x612b2, 0x612b5}, {0x612b8, 0x612be}, {0x612c2, 0x612c5}, + {0x612c8, 0x612d6}, {0x612d8, 0x61310}, {0x61312, 0x61315}, {0x61318, 0x6135a}, + {0x6135d, 0x6137c}, {0x61380, 0x61399}, {0x613a0, 0x613f5}, {0x613f8, 0x613fd}, + {0x61400, 0x6167f}, {0x61681, 0x6169c}, {0x616a0, 0x616f8}, {0x61700, 0x6170c}, + {0x6170e, 0x61714}, {0x61720, 0x61736}, {0x61740, 0x61753}, {0x61760, 0x6176c}, + {0x6176e, 0x61770}, {0x61780, 0x617dd}, {0x617e0, 0x617e9}, {0x617f0, 0x617f9}, + {0x61800, 0x6180d}, {0x61810, 0x61819}, {0x61820, 0x61877}, {0x61880, 0x618aa}, + {0x618b0, 0x618f5}, {0x61900, 0x6191e}, {0x61920, 0x6192b}, {0x61930, 0x6193b}, + {0x61944, 0x6196d}, {0x61970, 0x61974}, {0x61980, 0x619ab}, {0x619b0, 0x619c9}, + {0x619d0, 0x619da}, {0x619de, 0x61a1b}, {0x61a1e, 0x61a5e}, {0x61a60, 0x61a7c}, + {0x61a7f, 0x61a89}, {0x61a90, 0x61a99}, {0x61aa0, 0x61aad}, {0x61ab0, 0x61abe}, + {0x61b00, 0x61b4b}, {0x61b50, 0x61b7c}, {0x61b80, 0x61bf3}, {0x61bfc, 0x61c37}, + {0x61c3b, 0x61c49}, {0x61c4d, 0x61c88}, {0x61cc0, 0x61cc7}, {0x61cd0, 0x61cf9}, + {0x61d00, 0x61df9}, {0x61dfb, 0x61f15}, {0x61f18, 0x61f1d}, {0x61f20, 0x61f45}, + {0x61f48, 0x61f4d}, {0x61f50, 0x61f57}, {0x61f5f, 0x61f7d}, {0x61f80, 0x61fb4}, + {0x61fb6, 0x61fc4}, {0x61fc6, 0x61fd3}, {0x61fd6, 0x61fdb}, {0x61fdd, 0x61fef}, + {0x61ff2, 0x61ff4}, {0x61ff6, 0x61ffe}, {0x62010, 0x62027}, {0x62030, 0x6205e}, + {0x62074, 0x6208e}, {0x62090, 0x6209c}, {0x620a0, 0x620bf}, {0x620d0, 0x620f0}, + {0x62100, 0x6218b}, {0x62190, 0x62426}, {0x62440, 0x6244a}, {0x62460, 0x62b73}, + {0x62b76, 0x62b95}, {0x62b98, 0x62bb9}, {0x62bbd, 0x62bc8}, {0x62bca, 0x62bd2}, + {0x62bec, 0x62bef}, {0x62c00, 0x62c2e}, {0x62c30, 0x62c5e}, {0x62c60, 0x62cf3}, + {0x62cf9, 0x62d25}, {0x62d30, 0x62d67}, {0x62d7f, 0x62d96}, {0x62da0, 0x62da6}, + {0x62da8, 0x62dae}, {0x62db0, 0x62db6}, {0x62db8, 0x62dbe}, {0x62dc0, 0x62dc6}, + {0x62dc8, 0x62dce}, {0x62dd0, 0x62dd6}, {0x62dd8, 0x62dde}, {0x62de0, 0x62e49}, + {0x62e80, 0x62e99}, {0x62e9b, 0x62ef3}, {0x62f00, 0x62fd5}, {0x62ff0, 0x62ffb}, + {0x63001, 0x6303f}, {0x63041, 0x63096}, {0x63099, 0x630ff}, {0x63105, 0x6312e}, + {0x63131, 0x6318e}, {0x63190, 0x631ba}, {0x631c0, 0x631e3}, {0x631f0, 0x6321e}, + {0x63220, 0x632fe}, {0x63300, 0x64db5}, {0x64dc0, 0x69fea}, {0x6a000, 0x6a48c}, + {0x6a490, 0x6a4c6}, {0x6a4d0, 0x6a62b}, {0x6a640, 0x6a6f7}, {0x6a700, 0x6a7ae}, + {0x6a7b0, 0x6a7b7}, {0x6a7f7, 0x6a82b}, {0x6a830, 0x6a839}, {0x6a840, 0x6a877}, + {0x6a880, 0x6a8c5}, {0x6a8ce, 0x6a8d9}, {0x6a8e0, 0x6a8fd}, {0x6a900, 0x6a953}, + {0x6a95f, 0x6a97c}, {0x6a980, 0x6a9cd}, {0x6a9cf, 0x6a9d9}, {0x6a9de, 0x6a9fe}, + {0x6aa00, 0x6aa36}, {0x6aa40, 0x6aa4d}, {0x6aa50, 0x6aa59}, {0x6aa5c, 0x6aac2}, + {0x6aadb, 0x6aaf6}, {0x6ab01, 0x6ab06}, {0x6ab09, 0x6ab0e}, {0x6ab11, 0x6ab16}, + {0x6ab20, 0x6ab26}, {0x6ab28, 0x6ab2e}, {0x6ab30, 0x6ab65}, {0x6ab70, 0x6abed}, + {0x6abf0, 0x6abf9}, {0x6ac00, 0x6d7a3}, {0x6d7b0, 0x6d7c6}, {0x6d7cb, 0x6d7fb}, + {0x6f900, 0x6fa6d}, {0x6fa70, 0x6fad9}, {0x6fb00, 0x6fb06}, {0x6fb13, 0x6fb17}, + {0x6fb1d, 0x6fb36}, {0x6fb38, 0x6fb3c}, {0x6fb46, 0x6fbc1}, {0x6fbd3, 0x6fd3f}, + {0x6fd50, 0x6fd8f}, {0x6fd92, 0x6fdc7}, {0x6fdf0, 0x6fdfd}, {0x6fe00, 0x6fe19}, + {0x6fe20, 0x6fe52}, {0x6fe54, 0x6fe66}, {0x6fe68, 0x6fe6b}, {0x6fe70, 0x6fe74}, + {0x6fe76, 0x6fefc}, {0x6ff01, 0x6ffbe}, {0x6ffc2, 0x6ffc7}, {0x6ffca, 0x6ffcf}, + {0x6ffd2, 0x6ffd7}, {0x6ffda, 0x6ffdc}, {0x6ffe0, 0x6ffe6}, {0x6ffe8, 0x6ffee}, + {0x70021, 0x7007e}, {0x700a1, 0x700ac}, {0x700ae, 0x70377}, {0x7037a, 0x7037f}, + {0x70384, 0x7038a}, {0x7038e, 0x703a1}, {0x703a3, 0x7052f}, {0x70531, 0x70556}, + {0x70559, 0x7055f}, {0x70561, 0x70587}, {0x7058d, 0x7058f}, {0x70591, 0x705c7}, + {0x705d0, 0x705ea}, {0x705f0, 0x705f4}, {0x70606, 0x7061b}, {0x7061e, 0x706dc}, + {0x706de, 0x7070d}, {0x70710, 0x7074a}, {0x7074d, 0x707b1}, {0x707c0, 0x707fa}, + {0x70800, 0x7082d}, {0x70830, 0x7083e}, {0x70840, 0x7085b}, {0x70860, 0x7086a}, + {0x708a0, 0x708b4}, {0x708b6, 0x708bd}, {0x708d4, 0x708e1}, {0x708e3, 0x70983}, + {0x70985, 0x7098c}, {0x70993, 0x709a8}, {0x709aa, 0x709b0}, {0x709b6, 0x709b9}, + {0x709bc, 0x709c4}, {0x709cb, 0x709ce}, {0x709df, 0x709e3}, {0x709e6, 0x709fd}, + {0x70a01, 0x70a03}, {0x70a05, 0x70a0a}, {0x70a13, 0x70a28}, {0x70a2a, 0x70a30}, + {0x70a3e, 0x70a42}, {0x70a4b, 0x70a4d}, {0x70a59, 0x70a5c}, {0x70a66, 0x70a75}, + {0x70a81, 0x70a83}, {0x70a85, 0x70a8d}, {0x70a8f, 0x70a91}, {0x70a93, 0x70aa8}, + {0x70aaa, 0x70ab0}, {0x70ab5, 0x70ab9}, {0x70abc, 0x70ac5}, {0x70ac7, 0x70ac9}, + {0x70acb, 0x70acd}, {0x70ae0, 0x70ae3}, {0x70ae6, 0x70af1}, {0x70af9, 0x70aff}, + {0x70b01, 0x70b03}, {0x70b05, 0x70b0c}, {0x70b13, 0x70b28}, {0x70b2a, 0x70b30}, + {0x70b35, 0x70b39}, {0x70b3c, 0x70b44}, {0x70b4b, 0x70b4d}, {0x70b5f, 0x70b63}, + {0x70b66, 0x70b77}, {0x70b85, 0x70b8a}, {0x70b8e, 0x70b90}, {0x70b92, 0x70b95}, + {0x70ba8, 0x70baa}, {0x70bae, 0x70bb9}, {0x70bbe, 0x70bc2}, {0x70bc6, 0x70bc8}, + {0x70bca, 0x70bcd}, {0x70be6, 0x70bfa}, {0x70c00, 0x70c03}, {0x70c05, 0x70c0c}, + {0x70c0e, 0x70c10}, {0x70c12, 0x70c28}, {0x70c2a, 0x70c39}, {0x70c3d, 0x70c44}, + {0x70c46, 0x70c48}, {0x70c4a, 0x70c4d}, {0x70c58, 0x70c5a}, {0x70c60, 0x70c63}, + {0x70c66, 0x70c6f}, {0x70c78, 0x70c83}, {0x70c85, 0x70c8c}, {0x70c8e, 0x70c90}, + {0x70c92, 0x70ca8}, {0x70caa, 0x70cb3}, {0x70cb5, 0x70cb9}, {0x70cbc, 0x70cc4}, + {0x70cc6, 0x70cc8}, {0x70cca, 0x70ccd}, {0x70ce0, 0x70ce3}, {0x70ce6, 0x70cef}, + {0x70d00, 0x70d03}, {0x70d05, 0x70d0c}, {0x70d0e, 0x70d10}, {0x70d12, 0x70d44}, + {0x70d46, 0x70d48}, {0x70d4a, 0x70d4f}, {0x70d54, 0x70d63}, {0x70d66, 0x70d7f}, + {0x70d85, 0x70d96}, {0x70d9a, 0x70db1}, {0x70db3, 0x70dbb}, {0x70dc0, 0x70dc6}, + {0x70dcf, 0x70dd4}, {0x70dd8, 0x70ddf}, {0x70de6, 0x70def}, {0x70df2, 0x70df4}, + {0x70e01, 0x70e3a}, {0x70e3f, 0x70e5b}, {0x70e94, 0x70e97}, {0x70e99, 0x70e9f}, + {0x70ea1, 0x70ea3}, {0x70ead, 0x70eb9}, {0x70ebb, 0x70ebd}, {0x70ec0, 0x70ec4}, + {0x70ec8, 0x70ecd}, {0x70ed0, 0x70ed9}, {0x70edc, 0x70edf}, {0x70f00, 0x70f47}, + {0x70f49, 0x70f6c}, {0x70f71, 0x70f97}, {0x70f99, 0x70fbc}, {0x70fbe, 0x70fcc}, + {0x70fce, 0x70fda}, {0x71000, 0x710c5}, {0x710d0, 0x71248}, {0x7124a, 0x7124d}, + {0x71250, 0x71256}, {0x7125a, 0x7125d}, {0x71260, 0x71288}, {0x7128a, 0x7128d}, + {0x71290, 0x712b0}, {0x712b2, 0x712b5}, {0x712b8, 0x712be}, {0x712c2, 0x712c5}, + {0x712c8, 0x712d6}, {0x712d8, 0x71310}, {0x71312, 0x71315}, {0x71318, 0x7135a}, + {0x7135d, 0x7137c}, {0x71380, 0x71399}, {0x713a0, 0x713f5}, {0x713f8, 0x713fd}, + {0x71400, 0x7167f}, {0x71681, 0x7169c}, {0x716a0, 0x716f8}, {0x71700, 0x7170c}, + {0x7170e, 0x71714}, {0x71720, 0x71736}, {0x71740, 0x71753}, {0x71760, 0x7176c}, + {0x7176e, 0x71770}, {0x71780, 0x717dd}, {0x717e0, 0x717e9}, {0x717f0, 0x717f9}, + {0x71800, 0x7180d}, {0x71810, 0x71819}, {0x71820, 0x71877}, {0x71880, 0x718aa}, + {0x718b0, 0x718f5}, {0x71900, 0x7191e}, {0x71920, 0x7192b}, {0x71930, 0x7193b}, + {0x71944, 0x7196d}, {0x71970, 0x71974}, {0x71980, 0x719ab}, {0x719b0, 0x719c9}, + {0x719d0, 0x719da}, {0x719de, 0x71a1b}, {0x71a1e, 0x71a5e}, {0x71a60, 0x71a7c}, + {0x71a7f, 0x71a89}, {0x71a90, 0x71a99}, {0x71aa0, 0x71aad}, {0x71ab0, 0x71abe}, + {0x71b00, 0x71b4b}, {0x71b50, 0x71b7c}, {0x71b80, 0x71bf3}, {0x71bfc, 0x71c37}, + {0x71c3b, 0x71c49}, {0x71c4d, 0x71c88}, {0x71cc0, 0x71cc7}, {0x71cd0, 0x71cf9}, + {0x71d00, 0x71df9}, {0x71dfb, 0x71f15}, {0x71f18, 0x71f1d}, {0x71f20, 0x71f45}, + {0x71f48, 0x71f4d}, {0x71f50, 0x71f57}, {0x71f5f, 0x71f7d}, {0x71f80, 0x71fb4}, + {0x71fb6, 0x71fc4}, {0x71fc6, 0x71fd3}, {0x71fd6, 0x71fdb}, {0x71fdd, 0x71fef}, + {0x71ff2, 0x71ff4}, {0x71ff6, 0x71ffe}, {0x72010, 0x72027}, {0x72030, 0x7205e}, + {0x72074, 0x7208e}, {0x72090, 0x7209c}, {0x720a0, 0x720bf}, {0x720d0, 0x720f0}, + {0x72100, 0x7218b}, {0x72190, 0x72426}, {0x72440, 0x7244a}, {0x72460, 0x72b73}, + {0x72b76, 0x72b95}, {0x72b98, 0x72bb9}, {0x72bbd, 0x72bc8}, {0x72bca, 0x72bd2}, + {0x72bec, 0x72bef}, {0x72c00, 0x72c2e}, {0x72c30, 0x72c5e}, {0x72c60, 0x72cf3}, + {0x72cf9, 0x72d25}, {0x72d30, 0x72d67}, {0x72d7f, 0x72d96}, {0x72da0, 0x72da6}, + {0x72da8, 0x72dae}, {0x72db0, 0x72db6}, {0x72db8, 0x72dbe}, {0x72dc0, 0x72dc6}, + {0x72dc8, 0x72dce}, {0x72dd0, 0x72dd6}, {0x72dd8, 0x72dde}, {0x72de0, 0x72e49}, + {0x72e80, 0x72e99}, {0x72e9b, 0x72ef3}, {0x72f00, 0x72fd5}, {0x72ff0, 0x72ffb}, + {0x73001, 0x7303f}, {0x73041, 0x73096}, {0x73099, 0x730ff}, {0x73105, 0x7312e}, + {0x73131, 0x7318e}, {0x73190, 0x731ba}, {0x731c0, 0x731e3}, {0x731f0, 0x7321e}, + {0x73220, 0x732fe}, {0x73300, 0x74db5}, {0x74dc0, 0x79fea}, {0x7a000, 0x7a48c}, + {0x7a490, 0x7a4c6}, {0x7a4d0, 0x7a62b}, {0x7a640, 0x7a6f7}, {0x7a700, 0x7a7ae}, + {0x7a7b0, 0x7a7b7}, {0x7a7f7, 0x7a82b}, {0x7a830, 0x7a839}, {0x7a840, 0x7a877}, + {0x7a880, 0x7a8c5}, {0x7a8ce, 0x7a8d9}, {0x7a8e0, 0x7a8fd}, {0x7a900, 0x7a953}, + {0x7a95f, 0x7a97c}, {0x7a980, 0x7a9cd}, {0x7a9cf, 0x7a9d9}, {0x7a9de, 0x7a9fe}, + {0x7aa00, 0x7aa36}, {0x7aa40, 0x7aa4d}, {0x7aa50, 0x7aa59}, {0x7aa5c, 0x7aac2}, + {0x7aadb, 0x7aaf6}, {0x7ab01, 0x7ab06}, {0x7ab09, 0x7ab0e}, {0x7ab11, 0x7ab16}, + {0x7ab20, 0x7ab26}, {0x7ab28, 0x7ab2e}, {0x7ab30, 0x7ab65}, {0x7ab70, 0x7abed}, + {0x7abf0, 0x7abf9}, {0x7ac00, 0x7d7a3}, {0x7d7b0, 0x7d7c6}, {0x7d7cb, 0x7d7fb}, + {0x7f900, 0x7fa6d}, {0x7fa70, 0x7fad9}, {0x7fb00, 0x7fb06}, {0x7fb13, 0x7fb17}, + {0x7fb1d, 0x7fb36}, {0x7fb38, 0x7fb3c}, {0x7fb46, 0x7fbc1}, {0x7fbd3, 0x7fd3f}, + {0x7fd50, 0x7fd8f}, {0x7fd92, 0x7fdc7}, {0x7fdf0, 0x7fdfd}, {0x7fe00, 0x7fe19}, + {0x7fe20, 0x7fe52}, {0x7fe54, 0x7fe66}, {0x7fe68, 0x7fe6b}, {0x7fe70, 0x7fe74}, + {0x7fe76, 0x7fefc}, {0x7ff01, 0x7ffbe}, {0x7ffc2, 0x7ffc7}, {0x7ffca, 0x7ffcf}, + {0x7ffd2, 0x7ffd7}, {0x7ffda, 0x7ffdc}, {0x7ffe0, 0x7ffe6}, {0x7ffe8, 0x7ffee}, + {0x80021, 0x8007e}, {0x800a1, 0x800ac}, {0x800ae, 0x80377}, {0x8037a, 0x8037f}, + {0x80384, 0x8038a}, {0x8038e, 0x803a1}, {0x803a3, 0x8052f}, {0x80531, 0x80556}, + {0x80559, 0x8055f}, {0x80561, 0x80587}, {0x8058d, 0x8058f}, {0x80591, 0x805c7}, + {0x805d0, 0x805ea}, {0x805f0, 0x805f4}, {0x80606, 0x8061b}, {0x8061e, 0x806dc}, + {0x806de, 0x8070d}, {0x80710, 0x8074a}, {0x8074d, 0x807b1}, {0x807c0, 0x807fa}, + {0x80800, 0x8082d}, {0x80830, 0x8083e}, {0x80840, 0x8085b}, {0x80860, 0x8086a}, + {0x808a0, 0x808b4}, {0x808b6, 0x808bd}, {0x808d4, 0x808e1}, {0x808e3, 0x80983}, + {0x80985, 0x8098c}, {0x80993, 0x809a8}, {0x809aa, 0x809b0}, {0x809b6, 0x809b9}, + {0x809bc, 0x809c4}, {0x809cb, 0x809ce}, {0x809df, 0x809e3}, {0x809e6, 0x809fd}, + {0x80a01, 0x80a03}, {0x80a05, 0x80a0a}, {0x80a13, 0x80a28}, {0x80a2a, 0x80a30}, + {0x80a3e, 0x80a42}, {0x80a4b, 0x80a4d}, {0x80a59, 0x80a5c}, {0x80a66, 0x80a75}, + {0x80a81, 0x80a83}, {0x80a85, 0x80a8d}, {0x80a8f, 0x80a91}, {0x80a93, 0x80aa8}, + {0x80aaa, 0x80ab0}, {0x80ab5, 0x80ab9}, {0x80abc, 0x80ac5}, {0x80ac7, 0x80ac9}, + {0x80acb, 0x80acd}, {0x80ae0, 0x80ae3}, {0x80ae6, 0x80af1}, {0x80af9, 0x80aff}, + {0x80b01, 0x80b03}, {0x80b05, 0x80b0c}, {0x80b13, 0x80b28}, {0x80b2a, 0x80b30}, + {0x80b35, 0x80b39}, {0x80b3c, 0x80b44}, {0x80b4b, 0x80b4d}, {0x80b5f, 0x80b63}, + {0x80b66, 0x80b77}, {0x80b85, 0x80b8a}, {0x80b8e, 0x80b90}, {0x80b92, 0x80b95}, + {0x80ba8, 0x80baa}, {0x80bae, 0x80bb9}, {0x80bbe, 0x80bc2}, {0x80bc6, 0x80bc8}, + {0x80bca, 0x80bcd}, {0x80be6, 0x80bfa}, {0x80c00, 0x80c03}, {0x80c05, 0x80c0c}, + {0x80c0e, 0x80c10}, {0x80c12, 0x80c28}, {0x80c2a, 0x80c39}, {0x80c3d, 0x80c44}, + {0x80c46, 0x80c48}, {0x80c4a, 0x80c4d}, {0x80c58, 0x80c5a}, {0x80c60, 0x80c63}, + {0x80c66, 0x80c6f}, {0x80c78, 0x80c83}, {0x80c85, 0x80c8c}, {0x80c8e, 0x80c90}, + {0x80c92, 0x80ca8}, {0x80caa, 0x80cb3}, {0x80cb5, 0x80cb9}, {0x80cbc, 0x80cc4}, + {0x80cc6, 0x80cc8}, {0x80cca, 0x80ccd}, {0x80ce0, 0x80ce3}, {0x80ce6, 0x80cef}, + {0x80d00, 0x80d03}, {0x80d05, 0x80d0c}, {0x80d0e, 0x80d10}, {0x80d12, 0x80d44}, + {0x80d46, 0x80d48}, {0x80d4a, 0x80d4f}, {0x80d54, 0x80d63}, {0x80d66, 0x80d7f}, + {0x80d85, 0x80d96}, {0x80d9a, 0x80db1}, {0x80db3, 0x80dbb}, {0x80dc0, 0x80dc6}, + {0x80dcf, 0x80dd4}, {0x80dd8, 0x80ddf}, {0x80de6, 0x80def}, {0x80df2, 0x80df4}, + {0x80e01, 0x80e3a}, {0x80e3f, 0x80e5b}, {0x80e94, 0x80e97}, {0x80e99, 0x80e9f}, + {0x80ea1, 0x80ea3}, {0x80ead, 0x80eb9}, {0x80ebb, 0x80ebd}, {0x80ec0, 0x80ec4}, + {0x80ec8, 0x80ecd}, {0x80ed0, 0x80ed9}, {0x80edc, 0x80edf}, {0x80f00, 0x80f47}, + {0x80f49, 0x80f6c}, {0x80f71, 0x80f97}, {0x80f99, 0x80fbc}, {0x80fbe, 0x80fcc}, + {0x80fce, 0x80fda}, {0x81000, 0x810c5}, {0x810d0, 0x81248}, {0x8124a, 0x8124d}, + {0x81250, 0x81256}, {0x8125a, 0x8125d}, {0x81260, 0x81288}, {0x8128a, 0x8128d}, + {0x81290, 0x812b0}, {0x812b2, 0x812b5}, {0x812b8, 0x812be}, {0x812c2, 0x812c5}, + {0x812c8, 0x812d6}, {0x812d8, 0x81310}, {0x81312, 0x81315}, {0x81318, 0x8135a}, + {0x8135d, 0x8137c}, {0x81380, 0x81399}, {0x813a0, 0x813f5}, {0x813f8, 0x813fd}, + {0x81400, 0x8167f}, {0x81681, 0x8169c}, {0x816a0, 0x816f8}, {0x81700, 0x8170c}, + {0x8170e, 0x81714}, {0x81720, 0x81736}, {0x81740, 0x81753}, {0x81760, 0x8176c}, + {0x8176e, 0x81770}, {0x81780, 0x817dd}, {0x817e0, 0x817e9}, {0x817f0, 0x817f9}, + {0x81800, 0x8180d}, {0x81810, 0x81819}, {0x81820, 0x81877}, {0x81880, 0x818aa}, + {0x818b0, 0x818f5}, {0x81900, 0x8191e}, {0x81920, 0x8192b}, {0x81930, 0x8193b}, + {0x81944, 0x8196d}, {0x81970, 0x81974}, {0x81980, 0x819ab}, {0x819b0, 0x819c9}, + {0x819d0, 0x819da}, {0x819de, 0x81a1b}, {0x81a1e, 0x81a5e}, {0x81a60, 0x81a7c}, + {0x81a7f, 0x81a89}, {0x81a90, 0x81a99}, {0x81aa0, 0x81aad}, {0x81ab0, 0x81abe}, + {0x81b00, 0x81b4b}, {0x81b50, 0x81b7c}, {0x81b80, 0x81bf3}, {0x81bfc, 0x81c37}, + {0x81c3b, 0x81c49}, {0x81c4d, 0x81c88}, {0x81cc0, 0x81cc7}, {0x81cd0, 0x81cf9}, + {0x81d00, 0x81df9}, {0x81dfb, 0x81f15}, {0x81f18, 0x81f1d}, {0x81f20, 0x81f45}, + {0x81f48, 0x81f4d}, {0x81f50, 0x81f57}, {0x81f5f, 0x81f7d}, {0x81f80, 0x81fb4}, + {0x81fb6, 0x81fc4}, {0x81fc6, 0x81fd3}, {0x81fd6, 0x81fdb}, {0x81fdd, 0x81fef}, + {0x81ff2, 0x81ff4}, {0x81ff6, 0x81ffe}, {0x82010, 0x82027}, {0x82030, 0x8205e}, + {0x82074, 0x8208e}, {0x82090, 0x8209c}, {0x820a0, 0x820bf}, {0x820d0, 0x820f0}, + {0x82100, 0x8218b}, {0x82190, 0x82426}, {0x82440, 0x8244a}, {0x82460, 0x82b73}, + {0x82b76, 0x82b95}, {0x82b98, 0x82bb9}, {0x82bbd, 0x82bc8}, {0x82bca, 0x82bd2}, + {0x82bec, 0x82bef}, {0x82c00, 0x82c2e}, {0x82c30, 0x82c5e}, {0x82c60, 0x82cf3}, + {0x82cf9, 0x82d25}, {0x82d30, 0x82d67}, {0x82d7f, 0x82d96}, {0x82da0, 0x82da6}, + {0x82da8, 0x82dae}, {0x82db0, 0x82db6}, {0x82db8, 0x82dbe}, {0x82dc0, 0x82dc6}, + {0x82dc8, 0x82dce}, {0x82dd0, 0x82dd6}, {0x82dd8, 0x82dde}, {0x82de0, 0x82e49}, + {0x82e80, 0x82e99}, {0x82e9b, 0x82ef3}, {0x82f00, 0x82fd5}, {0x82ff0, 0x82ffb}, + {0x83001, 0x8303f}, {0x83041, 0x83096}, {0x83099, 0x830ff}, {0x83105, 0x8312e}, + {0x83131, 0x8318e}, {0x83190, 0x831ba}, {0x831c0, 0x831e3}, {0x831f0, 0x8321e}, + {0x83220, 0x832fe}, {0x83300, 0x84db5}, {0x84dc0, 0x89fea}, {0x8a000, 0x8a48c}, + {0x8a490, 0x8a4c6}, {0x8a4d0, 0x8a62b}, {0x8a640, 0x8a6f7}, {0x8a700, 0x8a7ae}, + {0x8a7b0, 0x8a7b7}, {0x8a7f7, 0x8a82b}, {0x8a830, 0x8a839}, {0x8a840, 0x8a877}, + {0x8a880, 0x8a8c5}, {0x8a8ce, 0x8a8d9}, {0x8a8e0, 0x8a8fd}, {0x8a900, 0x8a953}, + {0x8a95f, 0x8a97c}, {0x8a980, 0x8a9cd}, {0x8a9cf, 0x8a9d9}, {0x8a9de, 0x8a9fe}, + {0x8aa00, 0x8aa36}, {0x8aa40, 0x8aa4d}, {0x8aa50, 0x8aa59}, {0x8aa5c, 0x8aac2}, + {0x8aadb, 0x8aaf6}, {0x8ab01, 0x8ab06}, {0x8ab09, 0x8ab0e}, {0x8ab11, 0x8ab16}, + {0x8ab20, 0x8ab26}, {0x8ab28, 0x8ab2e}, {0x8ab30, 0x8ab65}, {0x8ab70, 0x8abed}, + {0x8abf0, 0x8abf9}, {0x8ac00, 0x8d7a3}, {0x8d7b0, 0x8d7c6}, {0x8d7cb, 0x8d7fb}, + {0x8f900, 0x8fa6d}, {0x8fa70, 0x8fad9}, {0x8fb00, 0x8fb06}, {0x8fb13, 0x8fb17}, + {0x8fb1d, 0x8fb36}, {0x8fb38, 0x8fb3c}, {0x8fb46, 0x8fbc1}, {0x8fbd3, 0x8fd3f}, + {0x8fd50, 0x8fd8f}, {0x8fd92, 0x8fdc7}, {0x8fdf0, 0x8fdfd}, {0x8fe00, 0x8fe19}, + {0x8fe20, 0x8fe52}, {0x8fe54, 0x8fe66}, {0x8fe68, 0x8fe6b}, {0x8fe70, 0x8fe74}, + {0x8fe76, 0x8fefc}, {0x8ff01, 0x8ffbe}, {0x8ffc2, 0x8ffc7}, {0x8ffca, 0x8ffcf}, + {0x8ffd2, 0x8ffd7}, {0x8ffda, 0x8ffdc}, {0x8ffe0, 0x8ffe6}, {0x8ffe8, 0x8ffee}, + {0x90021, 0x9007e}, {0x900a1, 0x900ac}, {0x900ae, 0x90377}, {0x9037a, 0x9037f}, + {0x90384, 0x9038a}, {0x9038e, 0x903a1}, {0x903a3, 0x9052f}, {0x90531, 0x90556}, + {0x90559, 0x9055f}, {0x90561, 0x90587}, {0x9058d, 0x9058f}, {0x90591, 0x905c7}, + {0x905d0, 0x905ea}, {0x905f0, 0x905f4}, {0x90606, 0x9061b}, {0x9061e, 0x906dc}, + {0x906de, 0x9070d}, {0x90710, 0x9074a}, {0x9074d, 0x907b1}, {0x907c0, 0x907fa}, + {0x90800, 0x9082d}, {0x90830, 0x9083e}, {0x90840, 0x9085b}, {0x90860, 0x9086a}, + {0x908a0, 0x908b4}, {0x908b6, 0x908bd}, {0x908d4, 0x908e1}, {0x908e3, 0x90983}, + {0x90985, 0x9098c}, {0x90993, 0x909a8}, {0x909aa, 0x909b0}, {0x909b6, 0x909b9}, + {0x909bc, 0x909c4}, {0x909cb, 0x909ce}, {0x909df, 0x909e3}, {0x909e6, 0x909fd}, + {0x90a01, 0x90a03}, {0x90a05, 0x90a0a}, {0x90a13, 0x90a28}, {0x90a2a, 0x90a30}, + {0x90a3e, 0x90a42}, {0x90a4b, 0x90a4d}, {0x90a59, 0x90a5c}, {0x90a66, 0x90a75}, + {0x90a81, 0x90a83}, {0x90a85, 0x90a8d}, {0x90a8f, 0x90a91}, {0x90a93, 0x90aa8}, + {0x90aaa, 0x90ab0}, {0x90ab5, 0x90ab9}, {0x90abc, 0x90ac5}, {0x90ac7, 0x90ac9}, + {0x90acb, 0x90acd}, {0x90ae0, 0x90ae3}, {0x90ae6, 0x90af1}, {0x90af9, 0x90aff}, + {0x90b01, 0x90b03}, {0x90b05, 0x90b0c}, {0x90b13, 0x90b28}, {0x90b2a, 0x90b30}, + {0x90b35, 0x90b39}, {0x90b3c, 0x90b44}, {0x90b4b, 0x90b4d}, {0x90b5f, 0x90b63}, + {0x90b66, 0x90b77}, {0x90b85, 0x90b8a}, {0x90b8e, 0x90b90}, {0x90b92, 0x90b95}, + {0x90ba8, 0x90baa}, {0x90bae, 0x90bb9}, {0x90bbe, 0x90bc2}, {0x90bc6, 0x90bc8}, + {0x90bca, 0x90bcd}, {0x90be6, 0x90bfa}, {0x90c00, 0x90c03}, {0x90c05, 0x90c0c}, + {0x90c0e, 0x90c10}, {0x90c12, 0x90c28}, {0x90c2a, 0x90c39}, {0x90c3d, 0x90c44}, + {0x90c46, 0x90c48}, {0x90c4a, 0x90c4d}, {0x90c58, 0x90c5a}, {0x90c60, 0x90c63}, + {0x90c66, 0x90c6f}, {0x90c78, 0x90c83}, {0x90c85, 0x90c8c}, {0x90c8e, 0x90c90}, + {0x90c92, 0x90ca8}, {0x90caa, 0x90cb3}, {0x90cb5, 0x90cb9}, {0x90cbc, 0x90cc4}, + {0x90cc6, 0x90cc8}, {0x90cca, 0x90ccd}, {0x90ce0, 0x90ce3}, {0x90ce6, 0x90cef}, + {0x90d00, 0x90d03}, {0x90d05, 0x90d0c}, {0x90d0e, 0x90d10}, {0x90d12, 0x90d44}, + {0x90d46, 0x90d48}, {0x90d4a, 0x90d4f}, {0x90d54, 0x90d63}, {0x90d66, 0x90d7f}, + {0x90d85, 0x90d96}, {0x90d9a, 0x90db1}, {0x90db3, 0x90dbb}, {0x90dc0, 0x90dc6}, + {0x90dcf, 0x90dd4}, {0x90dd8, 0x90ddf}, {0x90de6, 0x90def}, {0x90df2, 0x90df4}, + {0x90e01, 0x90e3a}, {0x90e3f, 0x90e5b}, {0x90e94, 0x90e97}, {0x90e99, 0x90e9f}, + {0x90ea1, 0x90ea3}, {0x90ead, 0x90eb9}, {0x90ebb, 0x90ebd}, {0x90ec0, 0x90ec4}, + {0x90ec8, 0x90ecd}, {0x90ed0, 0x90ed9}, {0x90edc, 0x90edf}, {0x90f00, 0x90f47}, + {0x90f49, 0x90f6c}, {0x90f71, 0x90f97}, {0x90f99, 0x90fbc}, {0x90fbe, 0x90fcc}, + {0x90fce, 0x90fda}, {0x91000, 0x910c5}, {0x910d0, 0x91248}, {0x9124a, 0x9124d}, + {0x91250, 0x91256}, {0x9125a, 0x9125d}, {0x91260, 0x91288}, {0x9128a, 0x9128d}, + {0x91290, 0x912b0}, {0x912b2, 0x912b5}, {0x912b8, 0x912be}, {0x912c2, 0x912c5}, + {0x912c8, 0x912d6}, {0x912d8, 0x91310}, {0x91312, 0x91315}, {0x91318, 0x9135a}, + {0x9135d, 0x9137c}, {0x91380, 0x91399}, {0x913a0, 0x913f5}, {0x913f8, 0x913fd}, + {0x91400, 0x9167f}, {0x91681, 0x9169c}, {0x916a0, 0x916f8}, {0x91700, 0x9170c}, + {0x9170e, 0x91714}, {0x91720, 0x91736}, {0x91740, 0x91753}, {0x91760, 0x9176c}, + {0x9176e, 0x91770}, {0x91780, 0x917dd}, {0x917e0, 0x917e9}, {0x917f0, 0x917f9}, + {0x91800, 0x9180d}, {0x91810, 0x91819}, {0x91820, 0x91877}, {0x91880, 0x918aa}, + {0x918b0, 0x918f5}, {0x91900, 0x9191e}, {0x91920, 0x9192b}, {0x91930, 0x9193b}, + {0x91944, 0x9196d}, {0x91970, 0x91974}, {0x91980, 0x919ab}, {0x919b0, 0x919c9}, + {0x919d0, 0x919da}, {0x919de, 0x91a1b}, {0x91a1e, 0x91a5e}, {0x91a60, 0x91a7c}, + {0x91a7f, 0x91a89}, {0x91a90, 0x91a99}, {0x91aa0, 0x91aad}, {0x91ab0, 0x91abe}, + {0x91b00, 0x91b4b}, {0x91b50, 0x91b7c}, {0x91b80, 0x91bf3}, {0x91bfc, 0x91c37}, + {0x91c3b, 0x91c49}, {0x91c4d, 0x91c88}, {0x91cc0, 0x91cc7}, {0x91cd0, 0x91cf9}, + {0x91d00, 0x91df9}, {0x91dfb, 0x91f15}, {0x91f18, 0x91f1d}, {0x91f20, 0x91f45}, + {0x91f48, 0x91f4d}, {0x91f50, 0x91f57}, {0x91f5f, 0x91f7d}, {0x91f80, 0x91fb4}, + {0x91fb6, 0x91fc4}, {0x91fc6, 0x91fd3}, {0x91fd6, 0x91fdb}, {0x91fdd, 0x91fef}, + {0x91ff2, 0x91ff4}, {0x91ff6, 0x91ffe}, {0x92010, 0x92027}, {0x92030, 0x9205e}, + {0x92074, 0x9208e}, {0x92090, 0x9209c}, {0x920a0, 0x920bf}, {0x920d0, 0x920f0}, + {0x92100, 0x9218b}, {0x92190, 0x92426}, {0x92440, 0x9244a}, {0x92460, 0x92b73}, + {0x92b76, 0x92b95}, {0x92b98, 0x92bb9}, {0x92bbd, 0x92bc8}, {0x92bca, 0x92bd2}, + {0x92bec, 0x92bef}, {0x92c00, 0x92c2e}, {0x92c30, 0x92c5e}, {0x92c60, 0x92cf3}, + {0x92cf9, 0x92d25}, {0x92d30, 0x92d67}, {0x92d7f, 0x92d96}, {0x92da0, 0x92da6}, + {0x92da8, 0x92dae}, {0x92db0, 0x92db6}, {0x92db8, 0x92dbe}, {0x92dc0, 0x92dc6}, + {0x92dc8, 0x92dce}, {0x92dd0, 0x92dd6}, {0x92dd8, 0x92dde}, {0x92de0, 0x92e49}, + {0x92e80, 0x92e99}, {0x92e9b, 0x92ef3}, {0x92f00, 0x92fd5}, {0x92ff0, 0x92ffb}, + {0x93001, 0x9303f}, {0x93041, 0x93096}, {0x93099, 0x930ff}, {0x93105, 0x9312e}, + {0x93131, 0x9318e}, {0x93190, 0x931ba}, {0x931c0, 0x931e3}, {0x931f0, 0x9321e}, + {0x93220, 0x932fe}, {0x93300, 0x94db5}, {0x94dc0, 0x99fea}, {0x9a000, 0x9a48c}, + {0x9a490, 0x9a4c6}, {0x9a4d0, 0x9a62b}, {0x9a640, 0x9a6f7}, {0x9a700, 0x9a7ae}, + {0x9a7b0, 0x9a7b7}, {0x9a7f7, 0x9a82b}, {0x9a830, 0x9a839}, {0x9a840, 0x9a877}, + {0x9a880, 0x9a8c5}, {0x9a8ce, 0x9a8d9}, {0x9a8e0, 0x9a8fd}, {0x9a900, 0x9a953}, + {0x9a95f, 0x9a97c}, {0x9a980, 0x9a9cd}, {0x9a9cf, 0x9a9d9}, {0x9a9de, 0x9a9fe}, + {0x9aa00, 0x9aa36}, {0x9aa40, 0x9aa4d}, {0x9aa50, 0x9aa59}, {0x9aa5c, 0x9aac2}, + {0x9aadb, 0x9aaf6}, {0x9ab01, 0x9ab06}, {0x9ab09, 0x9ab0e}, {0x9ab11, 0x9ab16}, + {0x9ab20, 0x9ab26}, {0x9ab28, 0x9ab2e}, {0x9ab30, 0x9ab65}, {0x9ab70, 0x9abed}, + {0x9abf0, 0x9abf9}, {0x9ac00, 0x9d7a3}, {0x9d7b0, 0x9d7c6}, {0x9d7cb, 0x9d7fb}, + {0x9f900, 0x9fa6d}, {0x9fa70, 0x9fad9}, {0x9fb00, 0x9fb06}, {0x9fb13, 0x9fb17}, + {0x9fb1d, 0x9fb36}, {0x9fb38, 0x9fb3c}, {0x9fb46, 0x9fbc1}, {0x9fbd3, 0x9fd3f}, + {0x9fd50, 0x9fd8f}, {0x9fd92, 0x9fdc7}, {0x9fdf0, 0x9fdfd}, {0x9fe00, 0x9fe19}, + {0x9fe20, 0x9fe52}, {0x9fe54, 0x9fe66}, {0x9fe68, 0x9fe6b}, {0x9fe70, 0x9fe74}, + {0x9fe76, 0x9fefc}, {0x9ff01, 0x9ffbe}, {0x9ffc2, 0x9ffc7}, {0x9ffca, 0x9ffcf}, + {0x9ffd2, 0x9ffd7}, {0x9ffda, 0x9ffdc}, {0x9ffe0, 0x9ffe6}, {0x9ffe8, 0x9ffee}, + {0xa0021, 0xa007e}, {0xa00a1, 0xa00ac}, {0xa00ae, 0xa0377}, {0xa037a, 0xa037f}, + {0xa0384, 0xa038a}, {0xa038e, 0xa03a1}, {0xa03a3, 0xa052f}, {0xa0531, 0xa0556}, + {0xa0559, 0xa055f}, {0xa0561, 0xa0587}, {0xa058d, 0xa058f}, {0xa0591, 0xa05c7}, + {0xa05d0, 0xa05ea}, {0xa05f0, 0xa05f4}, {0xa0606, 0xa061b}, {0xa061e, 0xa06dc}, + {0xa06de, 0xa070d}, {0xa0710, 0xa074a}, {0xa074d, 0xa07b1}, {0xa07c0, 0xa07fa}, + {0xa0800, 0xa082d}, {0xa0830, 0xa083e}, {0xa0840, 0xa085b}, {0xa0860, 0xa086a}, + {0xa08a0, 0xa08b4}, {0xa08b6, 0xa08bd}, {0xa08d4, 0xa08e1}, {0xa08e3, 0xa0983}, + {0xa0985, 0xa098c}, {0xa0993, 0xa09a8}, {0xa09aa, 0xa09b0}, {0xa09b6, 0xa09b9}, + {0xa09bc, 0xa09c4}, {0xa09cb, 0xa09ce}, {0xa09df, 0xa09e3}, {0xa09e6, 0xa09fd}, + {0xa0a01, 0xa0a03}, {0xa0a05, 0xa0a0a}, {0xa0a13, 0xa0a28}, {0xa0a2a, 0xa0a30}, + {0xa0a3e, 0xa0a42}, {0xa0a4b, 0xa0a4d}, {0xa0a59, 0xa0a5c}, {0xa0a66, 0xa0a75}, + {0xa0a81, 0xa0a83}, {0xa0a85, 0xa0a8d}, {0xa0a8f, 0xa0a91}, {0xa0a93, 0xa0aa8}, + {0xa0aaa, 0xa0ab0}, {0xa0ab5, 0xa0ab9}, {0xa0abc, 0xa0ac5}, {0xa0ac7, 0xa0ac9}, + {0xa0acb, 0xa0acd}, {0xa0ae0, 0xa0ae3}, {0xa0ae6, 0xa0af1}, {0xa0af9, 0xa0aff}, + {0xa0b01, 0xa0b03}, {0xa0b05, 0xa0b0c}, {0xa0b13, 0xa0b28}, {0xa0b2a, 0xa0b30}, + {0xa0b35, 0xa0b39}, {0xa0b3c, 0xa0b44}, {0xa0b4b, 0xa0b4d}, {0xa0b5f, 0xa0b63}, + {0xa0b66, 0xa0b77}, {0xa0b85, 0xa0b8a}, {0xa0b8e, 0xa0b90}, {0xa0b92, 0xa0b95}, + {0xa0ba8, 0xa0baa}, {0xa0bae, 0xa0bb9}, {0xa0bbe, 0xa0bc2}, {0xa0bc6, 0xa0bc8}, + {0xa0bca, 0xa0bcd}, {0xa0be6, 0xa0bfa}, {0xa0c00, 0xa0c03}, {0xa0c05, 0xa0c0c}, + {0xa0c0e, 0xa0c10}, {0xa0c12, 0xa0c28}, {0xa0c2a, 0xa0c39}, {0xa0c3d, 0xa0c44}, + {0xa0c46, 0xa0c48}, {0xa0c4a, 0xa0c4d}, {0xa0c58, 0xa0c5a}, {0xa0c60, 0xa0c63}, + {0xa0c66, 0xa0c6f}, {0xa0c78, 0xa0c83}, {0xa0c85, 0xa0c8c}, {0xa0c8e, 0xa0c90}, + {0xa0c92, 0xa0ca8}, {0xa0caa, 0xa0cb3}, {0xa0cb5, 0xa0cb9}, {0xa0cbc, 0xa0cc4}, + {0xa0cc6, 0xa0cc8}, {0xa0cca, 0xa0ccd}, {0xa0ce0, 0xa0ce3}, {0xa0ce6, 0xa0cef}, + {0xa0d00, 0xa0d03}, {0xa0d05, 0xa0d0c}, {0xa0d0e, 0xa0d10}, {0xa0d12, 0xa0d44}, + {0xa0d46, 0xa0d48}, {0xa0d4a, 0xa0d4f}, {0xa0d54, 0xa0d63}, {0xa0d66, 0xa0d7f}, + {0xa0d85, 0xa0d96}, {0xa0d9a, 0xa0db1}, {0xa0db3, 0xa0dbb}, {0xa0dc0, 0xa0dc6}, + {0xa0dcf, 0xa0dd4}, {0xa0dd8, 0xa0ddf}, {0xa0de6, 0xa0def}, {0xa0df2, 0xa0df4}, + {0xa0e01, 0xa0e3a}, {0xa0e3f, 0xa0e5b}, {0xa0e94, 0xa0e97}, {0xa0e99, 0xa0e9f}, + {0xa0ea1, 0xa0ea3}, {0xa0ead, 0xa0eb9}, {0xa0ebb, 0xa0ebd}, {0xa0ec0, 0xa0ec4}, + {0xa0ec8, 0xa0ecd}, {0xa0ed0, 0xa0ed9}, {0xa0edc, 0xa0edf}, {0xa0f00, 0xa0f47}, + {0xa0f49, 0xa0f6c}, {0xa0f71, 0xa0f97}, {0xa0f99, 0xa0fbc}, {0xa0fbe, 0xa0fcc}, + {0xa0fce, 0xa0fda}, {0xa1000, 0xa10c5}, {0xa10d0, 0xa1248}, {0xa124a, 0xa124d}, + {0xa1250, 0xa1256}, {0xa125a, 0xa125d}, {0xa1260, 0xa1288}, {0xa128a, 0xa128d}, + {0xa1290, 0xa12b0}, {0xa12b2, 0xa12b5}, {0xa12b8, 0xa12be}, {0xa12c2, 0xa12c5}, + {0xa12c8, 0xa12d6}, {0xa12d8, 0xa1310}, {0xa1312, 0xa1315}, {0xa1318, 0xa135a}, + {0xa135d, 0xa137c}, {0xa1380, 0xa1399}, {0xa13a0, 0xa13f5}, {0xa13f8, 0xa13fd}, + {0xa1400, 0xa167f}, {0xa1681, 0xa169c}, {0xa16a0, 0xa16f8}, {0xa1700, 0xa170c}, + {0xa170e, 0xa1714}, {0xa1720, 0xa1736}, {0xa1740, 0xa1753}, {0xa1760, 0xa176c}, + {0xa176e, 0xa1770}, {0xa1780, 0xa17dd}, {0xa17e0, 0xa17e9}, {0xa17f0, 0xa17f9}, + {0xa1800, 0xa180d}, {0xa1810, 0xa1819}, {0xa1820, 0xa1877}, {0xa1880, 0xa18aa}, + {0xa18b0, 0xa18f5}, {0xa1900, 0xa191e}, {0xa1920, 0xa192b}, {0xa1930, 0xa193b}, + {0xa1944, 0xa196d}, {0xa1970, 0xa1974}, {0xa1980, 0xa19ab}, {0xa19b0, 0xa19c9}, + {0xa19d0, 0xa19da}, {0xa19de, 0xa1a1b}, {0xa1a1e, 0xa1a5e}, {0xa1a60, 0xa1a7c}, + {0xa1a7f, 0xa1a89}, {0xa1a90, 0xa1a99}, {0xa1aa0, 0xa1aad}, {0xa1ab0, 0xa1abe}, + {0xa1b00, 0xa1b4b}, {0xa1b50, 0xa1b7c}, {0xa1b80, 0xa1bf3}, {0xa1bfc, 0xa1c37}, + {0xa1c3b, 0xa1c49}, {0xa1c4d, 0xa1c88}, {0xa1cc0, 0xa1cc7}, {0xa1cd0, 0xa1cf9}, + {0xa1d00, 0xa1df9}, {0xa1dfb, 0xa1f15}, {0xa1f18, 0xa1f1d}, {0xa1f20, 0xa1f45}, + {0xa1f48, 0xa1f4d}, {0xa1f50, 0xa1f57}, {0xa1f5f, 0xa1f7d}, {0xa1f80, 0xa1fb4}, + {0xa1fb6, 0xa1fc4}, {0xa1fc6, 0xa1fd3}, {0xa1fd6, 0xa1fdb}, {0xa1fdd, 0xa1fef}, + {0xa1ff2, 0xa1ff4}, {0xa1ff6, 0xa1ffe}, {0xa2010, 0xa2027}, {0xa2030, 0xa205e}, + {0xa2074, 0xa208e}, {0xa2090, 0xa209c}, {0xa20a0, 0xa20bf}, {0xa20d0, 0xa20f0}, + {0xa2100, 0xa218b}, {0xa2190, 0xa2426}, {0xa2440, 0xa244a}, {0xa2460, 0xa2b73}, + {0xa2b76, 0xa2b95}, {0xa2b98, 0xa2bb9}, {0xa2bbd, 0xa2bc8}, {0xa2bca, 0xa2bd2}, + {0xa2bec, 0xa2bef}, {0xa2c00, 0xa2c2e}, {0xa2c30, 0xa2c5e}, {0xa2c60, 0xa2cf3}, + {0xa2cf9, 0xa2d25}, {0xa2d30, 0xa2d67}, {0xa2d7f, 0xa2d96}, {0xa2da0, 0xa2da6}, + {0xa2da8, 0xa2dae}, {0xa2db0, 0xa2db6}, {0xa2db8, 0xa2dbe}, {0xa2dc0, 0xa2dc6}, + {0xa2dc8, 0xa2dce}, {0xa2dd0, 0xa2dd6}, {0xa2dd8, 0xa2dde}, {0xa2de0, 0xa2e49}, + {0xa2e80, 0xa2e99}, {0xa2e9b, 0xa2ef3}, {0xa2f00, 0xa2fd5}, {0xa2ff0, 0xa2ffb}, + {0xa3001, 0xa303f}, {0xa3041, 0xa3096}, {0xa3099, 0xa30ff}, {0xa3105, 0xa312e}, + {0xa3131, 0xa318e}, {0xa3190, 0xa31ba}, {0xa31c0, 0xa31e3}, {0xa31f0, 0xa321e}, + {0xa3220, 0xa32fe}, {0xa3300, 0xa4db5}, {0xa4dc0, 0xa9fea}, {0xaa000, 0xaa48c}, + {0xaa490, 0xaa4c6}, {0xaa4d0, 0xaa62b}, {0xaa640, 0xaa6f7}, {0xaa700, 0xaa7ae}, + {0xaa7b0, 0xaa7b7}, {0xaa7f7, 0xaa82b}, {0xaa830, 0xaa839}, {0xaa840, 0xaa877}, + {0xaa880, 0xaa8c5}, {0xaa8ce, 0xaa8d9}, {0xaa8e0, 0xaa8fd}, {0xaa900, 0xaa953}, + {0xaa95f, 0xaa97c}, {0xaa980, 0xaa9cd}, {0xaa9cf, 0xaa9d9}, {0xaa9de, 0xaa9fe}, + {0xaaa00, 0xaaa36}, {0xaaa40, 0xaaa4d}, {0xaaa50, 0xaaa59}, {0xaaa5c, 0xaaac2}, + {0xaaadb, 0xaaaf6}, {0xaab01, 0xaab06}, {0xaab09, 0xaab0e}, {0xaab11, 0xaab16}, + {0xaab20, 0xaab26}, {0xaab28, 0xaab2e}, {0xaab30, 0xaab65}, {0xaab70, 0xaabed}, + {0xaabf0, 0xaabf9}, {0xaac00, 0xad7a3}, {0xad7b0, 0xad7c6}, {0xad7cb, 0xad7fb}, + {0xaf900, 0xafa6d}, {0xafa70, 0xafad9}, {0xafb00, 0xafb06}, {0xafb13, 0xafb17}, + {0xafb1d, 0xafb36}, {0xafb38, 0xafb3c}, {0xafb46, 0xafbc1}, {0xafbd3, 0xafd3f}, + {0xafd50, 0xafd8f}, {0xafd92, 0xafdc7}, {0xafdf0, 0xafdfd}, {0xafe00, 0xafe19}, + {0xafe20, 0xafe52}, {0xafe54, 0xafe66}, {0xafe68, 0xafe6b}, {0xafe70, 0xafe74}, + {0xafe76, 0xafefc}, {0xaff01, 0xaffbe}, {0xaffc2, 0xaffc7}, {0xaffca, 0xaffcf}, + {0xaffd2, 0xaffd7}, {0xaffda, 0xaffdc}, {0xaffe0, 0xaffe6}, {0xaffe8, 0xaffee}, + {0xb0021, 0xb007e}, {0xb00a1, 0xb00ac}, {0xb00ae, 0xb0377}, {0xb037a, 0xb037f}, + {0xb0384, 0xb038a}, {0xb038e, 0xb03a1}, {0xb03a3, 0xb052f}, {0xb0531, 0xb0556}, + {0xb0559, 0xb055f}, {0xb0561, 0xb0587}, {0xb058d, 0xb058f}, {0xb0591, 0xb05c7}, + {0xb05d0, 0xb05ea}, {0xb05f0, 0xb05f4}, {0xb0606, 0xb061b}, {0xb061e, 0xb06dc}, + {0xb06de, 0xb070d}, {0xb0710, 0xb074a}, {0xb074d, 0xb07b1}, {0xb07c0, 0xb07fa}, + {0xb0800, 0xb082d}, {0xb0830, 0xb083e}, {0xb0840, 0xb085b}, {0xb0860, 0xb086a}, + {0xb08a0, 0xb08b4}, {0xb08b6, 0xb08bd}, {0xb08d4, 0xb08e1}, {0xb08e3, 0xb0983}, + {0xb0985, 0xb098c}, {0xb0993, 0xb09a8}, {0xb09aa, 0xb09b0}, {0xb09b6, 0xb09b9}, + {0xb09bc, 0xb09c4}, {0xb09cb, 0xb09ce}, {0xb09df, 0xb09e3}, {0xb09e6, 0xb09fd}, + {0xb0a01, 0xb0a03}, {0xb0a05, 0xb0a0a}, {0xb0a13, 0xb0a28}, {0xb0a2a, 0xb0a30}, + {0xb0a3e, 0xb0a42}, {0xb0a4b, 0xb0a4d}, {0xb0a59, 0xb0a5c}, {0xb0a66, 0xb0a75}, + {0xb0a81, 0xb0a83}, {0xb0a85, 0xb0a8d}, {0xb0a8f, 0xb0a91}, {0xb0a93, 0xb0aa8}, + {0xb0aaa, 0xb0ab0}, {0xb0ab5, 0xb0ab9}, {0xb0abc, 0xb0ac5}, {0xb0ac7, 0xb0ac9}, + {0xb0acb, 0xb0acd}, {0xb0ae0, 0xb0ae3}, {0xb0ae6, 0xb0af1}, {0xb0af9, 0xb0aff}, + {0xb0b01, 0xb0b03}, {0xb0b05, 0xb0b0c}, {0xb0b13, 0xb0b28}, {0xb0b2a, 0xb0b30}, + {0xb0b35, 0xb0b39}, {0xb0b3c, 0xb0b44}, {0xb0b4b, 0xb0b4d}, {0xb0b5f, 0xb0b63}, + {0xb0b66, 0xb0b77}, {0xb0b85, 0xb0b8a}, {0xb0b8e, 0xb0b90}, {0xb0b92, 0xb0b95}, + {0xb0ba8, 0xb0baa}, {0xb0bae, 0xb0bb9}, {0xb0bbe, 0xb0bc2}, {0xb0bc6, 0xb0bc8}, + {0xb0bca, 0xb0bcd}, {0xb0be6, 0xb0bfa}, {0xb0c00, 0xb0c03}, {0xb0c05, 0xb0c0c}, + {0xb0c0e, 0xb0c10}, {0xb0c12, 0xb0c28}, {0xb0c2a, 0xb0c39}, {0xb0c3d, 0xb0c44}, + {0xb0c46, 0xb0c48}, {0xb0c4a, 0xb0c4d}, {0xb0c58, 0xb0c5a}, {0xb0c60, 0xb0c63}, + {0xb0c66, 0xb0c6f}, {0xb0c78, 0xb0c83}, {0xb0c85, 0xb0c8c}, {0xb0c8e, 0xb0c90}, + {0xb0c92, 0xb0ca8}, {0xb0caa, 0xb0cb3}, {0xb0cb5, 0xb0cb9}, {0xb0cbc, 0xb0cc4}, + {0xb0cc6, 0xb0cc8}, {0xb0cca, 0xb0ccd}, {0xb0ce0, 0xb0ce3}, {0xb0ce6, 0xb0cef}, + {0xb0d00, 0xb0d03}, {0xb0d05, 0xb0d0c}, {0xb0d0e, 0xb0d10}, {0xb0d12, 0xb0d44}, + {0xb0d46, 0xb0d48}, {0xb0d4a, 0xb0d4f}, {0xb0d54, 0xb0d63}, {0xb0d66, 0xb0d7f}, + {0xb0d85, 0xb0d96}, {0xb0d9a, 0xb0db1}, {0xb0db3, 0xb0dbb}, {0xb0dc0, 0xb0dc6}, + {0xb0dcf, 0xb0dd4}, {0xb0dd8, 0xb0ddf}, {0xb0de6, 0xb0def}, {0xb0df2, 0xb0df4}, + {0xb0e01, 0xb0e3a}, {0xb0e3f, 0xb0e5b}, {0xb0e94, 0xb0e97}, {0xb0e99, 0xb0e9f}, + {0xb0ea1, 0xb0ea3}, {0xb0ead, 0xb0eb9}, {0xb0ebb, 0xb0ebd}, {0xb0ec0, 0xb0ec4}, + {0xb0ec8, 0xb0ecd}, {0xb0ed0, 0xb0ed9}, {0xb0edc, 0xb0edf}, {0xb0f00, 0xb0f47}, + {0xb0f49, 0xb0f6c}, {0xb0f71, 0xb0f97}, {0xb0f99, 0xb0fbc}, {0xb0fbe, 0xb0fcc}, + {0xb0fce, 0xb0fda}, {0xb1000, 0xb10c5}, {0xb10d0, 0xb1248}, {0xb124a, 0xb124d}, + {0xb1250, 0xb1256}, {0xb125a, 0xb125d}, {0xb1260, 0xb1288}, {0xb128a, 0xb128d}, + {0xb1290, 0xb12b0}, {0xb12b2, 0xb12b5}, {0xb12b8, 0xb12be}, {0xb12c2, 0xb12c5}, + {0xb12c8, 0xb12d6}, {0xb12d8, 0xb1310}, {0xb1312, 0xb1315}, {0xb1318, 0xb135a}, + {0xb135d, 0xb137c}, {0xb1380, 0xb1399}, {0xb13a0, 0xb13f5}, {0xb13f8, 0xb13fd}, + {0xb1400, 0xb167f}, {0xb1681, 0xb169c}, {0xb16a0, 0xb16f8}, {0xb1700, 0xb170c}, + {0xb170e, 0xb1714}, {0xb1720, 0xb1736}, {0xb1740, 0xb1753}, {0xb1760, 0xb176c}, + {0xb176e, 0xb1770}, {0xb1780, 0xb17dd}, {0xb17e0, 0xb17e9}, {0xb17f0, 0xb17f9}, + {0xb1800, 0xb180d}, {0xb1810, 0xb1819}, {0xb1820, 0xb1877}, {0xb1880, 0xb18aa}, + {0xb18b0, 0xb18f5}, {0xb1900, 0xb191e}, {0xb1920, 0xb192b}, {0xb1930, 0xb193b}, + {0xb1944, 0xb196d}, {0xb1970, 0xb1974}, {0xb1980, 0xb19ab}, {0xb19b0, 0xb19c9}, + {0xb19d0, 0xb19da}, {0xb19de, 0xb1a1b}, {0xb1a1e, 0xb1a5e}, {0xb1a60, 0xb1a7c}, + {0xb1a7f, 0xb1a89}, {0xb1a90, 0xb1a99}, {0xb1aa0, 0xb1aad}, {0xb1ab0, 0xb1abe}, + {0xb1b00, 0xb1b4b}, {0xb1b50, 0xb1b7c}, {0xb1b80, 0xb1bf3}, {0xb1bfc, 0xb1c37}, + {0xb1c3b, 0xb1c49}, {0xb1c4d, 0xb1c88}, {0xb1cc0, 0xb1cc7}, {0xb1cd0, 0xb1cf9}, + {0xb1d00, 0xb1df9}, {0xb1dfb, 0xb1f15}, {0xb1f18, 0xb1f1d}, {0xb1f20, 0xb1f45}, + {0xb1f48, 0xb1f4d}, {0xb1f50, 0xb1f57}, {0xb1f5f, 0xb1f7d}, {0xb1f80, 0xb1fb4}, + {0xb1fb6, 0xb1fc4}, {0xb1fc6, 0xb1fd3}, {0xb1fd6, 0xb1fdb}, {0xb1fdd, 0xb1fef}, + {0xb1ff2, 0xb1ff4}, {0xb1ff6, 0xb1ffe}, {0xb2010, 0xb2027}, {0xb2030, 0xb205e}, + {0xb2074, 0xb208e}, {0xb2090, 0xb209c}, {0xb20a0, 0xb20bf}, {0xb20d0, 0xb20f0}, + {0xb2100, 0xb218b}, {0xb2190, 0xb2426}, {0xb2440, 0xb244a}, {0xb2460, 0xb2b73}, + {0xb2b76, 0xb2b95}, {0xb2b98, 0xb2bb9}, {0xb2bbd, 0xb2bc8}, {0xb2bca, 0xb2bd2}, + {0xb2bec, 0xb2bef}, {0xb2c00, 0xb2c2e}, {0xb2c30, 0xb2c5e}, {0xb2c60, 0xb2cf3}, + {0xb2cf9, 0xb2d25}, {0xb2d30, 0xb2d67}, {0xb2d7f, 0xb2d96}, {0xb2da0, 0xb2da6}, + {0xb2da8, 0xb2dae}, {0xb2db0, 0xb2db6}, {0xb2db8, 0xb2dbe}, {0xb2dc0, 0xb2dc6}, + {0xb2dc8, 0xb2dce}, {0xb2dd0, 0xb2dd6}, {0xb2dd8, 0xb2dde}, {0xb2de0, 0xb2e49}, + {0xb2e80, 0xb2e99}, {0xb2e9b, 0xb2ef3}, {0xb2f00, 0xb2fd5}, {0xb2ff0, 0xb2ffb}, + {0xb3001, 0xb303f}, {0xb3041, 0xb3096}, {0xb3099, 0xb30ff}, {0xb3105, 0xb312e}, + {0xb3131, 0xb318e}, {0xb3190, 0xb31ba}, {0xb31c0, 0xb31e3}, {0xb31f0, 0xb321e}, + {0xb3220, 0xb32fe}, {0xb3300, 0xb4db5}, {0xb4dc0, 0xb9fea}, {0xba000, 0xba48c}, + {0xba490, 0xba4c6}, {0xba4d0, 0xba62b}, {0xba640, 0xba6f7}, {0xba700, 0xba7ae}, + {0xba7b0, 0xba7b7}, {0xba7f7, 0xba82b}, {0xba830, 0xba839}, {0xba840, 0xba877}, + {0xba880, 0xba8c5}, {0xba8ce, 0xba8d9}, {0xba8e0, 0xba8fd}, {0xba900, 0xba953}, + {0xba95f, 0xba97c}, {0xba980, 0xba9cd}, {0xba9cf, 0xba9d9}, {0xba9de, 0xba9fe}, + {0xbaa00, 0xbaa36}, {0xbaa40, 0xbaa4d}, {0xbaa50, 0xbaa59}, {0xbaa5c, 0xbaac2}, + {0xbaadb, 0xbaaf6}, {0xbab01, 0xbab06}, {0xbab09, 0xbab0e}, {0xbab11, 0xbab16}, + {0xbab20, 0xbab26}, {0xbab28, 0xbab2e}, {0xbab30, 0xbab65}, {0xbab70, 0xbabed}, + {0xbabf0, 0xbabf9}, {0xbac00, 0xbd7a3}, {0xbd7b0, 0xbd7c6}, {0xbd7cb, 0xbd7fb}, + {0xbf900, 0xbfa6d}, {0xbfa70, 0xbfad9}, {0xbfb00, 0xbfb06}, {0xbfb13, 0xbfb17}, + {0xbfb1d, 0xbfb36}, {0xbfb38, 0xbfb3c}, {0xbfb46, 0xbfbc1}, {0xbfbd3, 0xbfd3f}, + {0xbfd50, 0xbfd8f}, {0xbfd92, 0xbfdc7}, {0xbfdf0, 0xbfdfd}, {0xbfe00, 0xbfe19}, + {0xbfe20, 0xbfe52}, {0xbfe54, 0xbfe66}, {0xbfe68, 0xbfe6b}, {0xbfe70, 0xbfe74}, + {0xbfe76, 0xbfefc}, {0xbff01, 0xbffbe}, {0xbffc2, 0xbffc7}, {0xbffca, 0xbffcf}, + {0xbffd2, 0xbffd7}, {0xbffda, 0xbffdc}, {0xbffe0, 0xbffe6}, {0xbffe8, 0xbffee}, + {0xc0021, 0xc007e}, {0xc00a1, 0xc00ac}, {0xc00ae, 0xc0377}, {0xc037a, 0xc037f}, + {0xc0384, 0xc038a}, {0xc038e, 0xc03a1}, {0xc03a3, 0xc052f}, {0xc0531, 0xc0556}, + {0xc0559, 0xc055f}, {0xc0561, 0xc0587}, {0xc058d, 0xc058f}, {0xc0591, 0xc05c7}, + {0xc05d0, 0xc05ea}, {0xc05f0, 0xc05f4}, {0xc0606, 0xc061b}, {0xc061e, 0xc06dc}, + {0xc06de, 0xc070d}, {0xc0710, 0xc074a}, {0xc074d, 0xc07b1}, {0xc07c0, 0xc07fa}, + {0xc0800, 0xc082d}, {0xc0830, 0xc083e}, {0xc0840, 0xc085b}, {0xc0860, 0xc086a}, + {0xc08a0, 0xc08b4}, {0xc08b6, 0xc08bd}, {0xc08d4, 0xc08e1}, {0xc08e3, 0xc0983}, + {0xc0985, 0xc098c}, {0xc0993, 0xc09a8}, {0xc09aa, 0xc09b0}, {0xc09b6, 0xc09b9}, + {0xc09bc, 0xc09c4}, {0xc09cb, 0xc09ce}, {0xc09df, 0xc09e3}, {0xc09e6, 0xc09fd}, + {0xc0a01, 0xc0a03}, {0xc0a05, 0xc0a0a}, {0xc0a13, 0xc0a28}, {0xc0a2a, 0xc0a30}, + {0xc0a3e, 0xc0a42}, {0xc0a4b, 0xc0a4d}, {0xc0a59, 0xc0a5c}, {0xc0a66, 0xc0a75}, + {0xc0a81, 0xc0a83}, {0xc0a85, 0xc0a8d}, {0xc0a8f, 0xc0a91}, {0xc0a93, 0xc0aa8}, + {0xc0aaa, 0xc0ab0}, {0xc0ab5, 0xc0ab9}, {0xc0abc, 0xc0ac5}, {0xc0ac7, 0xc0ac9}, + {0xc0acb, 0xc0acd}, {0xc0ae0, 0xc0ae3}, {0xc0ae6, 0xc0af1}, {0xc0af9, 0xc0aff}, + {0xc0b01, 0xc0b03}, {0xc0b05, 0xc0b0c}, {0xc0b13, 0xc0b28}, {0xc0b2a, 0xc0b30}, + {0xc0b35, 0xc0b39}, {0xc0b3c, 0xc0b44}, {0xc0b4b, 0xc0b4d}, {0xc0b5f, 0xc0b63}, + {0xc0b66, 0xc0b77}, {0xc0b85, 0xc0b8a}, {0xc0b8e, 0xc0b90}, {0xc0b92, 0xc0b95}, + {0xc0ba8, 0xc0baa}, {0xc0bae, 0xc0bb9}, {0xc0bbe, 0xc0bc2}, {0xc0bc6, 0xc0bc8}, + {0xc0bca, 0xc0bcd}, {0xc0be6, 0xc0bfa}, {0xc0c00, 0xc0c03}, {0xc0c05, 0xc0c0c}, + {0xc0c0e, 0xc0c10}, {0xc0c12, 0xc0c28}, {0xc0c2a, 0xc0c39}, {0xc0c3d, 0xc0c44}, + {0xc0c46, 0xc0c48}, {0xc0c4a, 0xc0c4d}, {0xc0c58, 0xc0c5a}, {0xc0c60, 0xc0c63}, + {0xc0c66, 0xc0c6f}, {0xc0c78, 0xc0c83}, {0xc0c85, 0xc0c8c}, {0xc0c8e, 0xc0c90}, + {0xc0c92, 0xc0ca8}, {0xc0caa, 0xc0cb3}, {0xc0cb5, 0xc0cb9}, {0xc0cbc, 0xc0cc4}, + {0xc0cc6, 0xc0cc8}, {0xc0cca, 0xc0ccd}, {0xc0ce0, 0xc0ce3}, {0xc0ce6, 0xc0cef}, + {0xc0d00, 0xc0d03}, {0xc0d05, 0xc0d0c}, {0xc0d0e, 0xc0d10}, {0xc0d12, 0xc0d44}, + {0xc0d46, 0xc0d48}, {0xc0d4a, 0xc0d4f}, {0xc0d54, 0xc0d63}, {0xc0d66, 0xc0d7f}, + {0xc0d85, 0xc0d96}, {0xc0d9a, 0xc0db1}, {0xc0db3, 0xc0dbb}, {0xc0dc0, 0xc0dc6}, + {0xc0dcf, 0xc0dd4}, {0xc0dd8, 0xc0ddf}, {0xc0de6, 0xc0def}, {0xc0df2, 0xc0df4}, + {0xc0e01, 0xc0e3a}, {0xc0e3f, 0xc0e5b}, {0xc0e94, 0xc0e97}, {0xc0e99, 0xc0e9f}, + {0xc0ea1, 0xc0ea3}, {0xc0ead, 0xc0eb9}, {0xc0ebb, 0xc0ebd}, {0xc0ec0, 0xc0ec4}, + {0xc0ec8, 0xc0ecd}, {0xc0ed0, 0xc0ed9}, {0xc0edc, 0xc0edf}, {0xc0f00, 0xc0f47}, + {0xc0f49, 0xc0f6c}, {0xc0f71, 0xc0f97}, {0xc0f99, 0xc0fbc}, {0xc0fbe, 0xc0fcc}, + {0xc0fce, 0xc0fda}, {0xc1000, 0xc10c5}, {0xc10d0, 0xc1248}, {0xc124a, 0xc124d}, + {0xc1250, 0xc1256}, {0xc125a, 0xc125d}, {0xc1260, 0xc1288}, {0xc128a, 0xc128d}, + {0xc1290, 0xc12b0}, {0xc12b2, 0xc12b5}, {0xc12b8, 0xc12be}, {0xc12c2, 0xc12c5}, + {0xc12c8, 0xc12d6}, {0xc12d8, 0xc1310}, {0xc1312, 0xc1315}, {0xc1318, 0xc135a}, + {0xc135d, 0xc137c}, {0xc1380, 0xc1399}, {0xc13a0, 0xc13f5}, {0xc13f8, 0xc13fd}, + {0xc1400, 0xc167f}, {0xc1681, 0xc169c}, {0xc16a0, 0xc16f8}, {0xc1700, 0xc170c}, + {0xc170e, 0xc1714}, {0xc1720, 0xc1736}, {0xc1740, 0xc1753}, {0xc1760, 0xc176c}, + {0xc176e, 0xc1770}, {0xc1780, 0xc17dd}, {0xc17e0, 0xc17e9}, {0xc17f0, 0xc17f9}, + {0xc1800, 0xc180d}, {0xc1810, 0xc1819}, {0xc1820, 0xc1877}, {0xc1880, 0xc18aa}, + {0xc18b0, 0xc18f5}, {0xc1900, 0xc191e}, {0xc1920, 0xc192b}, {0xc1930, 0xc193b}, + {0xc1944, 0xc196d}, {0xc1970, 0xc1974}, {0xc1980, 0xc19ab}, {0xc19b0, 0xc19c9}, + {0xc19d0, 0xc19da}, {0xc19de, 0xc1a1b}, {0xc1a1e, 0xc1a5e}, {0xc1a60, 0xc1a7c}, + {0xc1a7f, 0xc1a89}, {0xc1a90, 0xc1a99}, {0xc1aa0, 0xc1aad}, {0xc1ab0, 0xc1abe}, + {0xc1b00, 0xc1b4b}, {0xc1b50, 0xc1b7c}, {0xc1b80, 0xc1bf3}, {0xc1bfc, 0xc1c37}, + {0xc1c3b, 0xc1c49}, {0xc1c4d, 0xc1c88}, {0xc1cc0, 0xc1cc7}, {0xc1cd0, 0xc1cf9}, + {0xc1d00, 0xc1df9}, {0xc1dfb, 0xc1f15}, {0xc1f18, 0xc1f1d}, {0xc1f20, 0xc1f45}, + {0xc1f48, 0xc1f4d}, {0xc1f50, 0xc1f57}, {0xc1f5f, 0xc1f7d}, {0xc1f80, 0xc1fb4}, + {0xc1fb6, 0xc1fc4}, {0xc1fc6, 0xc1fd3}, {0xc1fd6, 0xc1fdb}, {0xc1fdd, 0xc1fef}, + {0xc1ff2, 0xc1ff4}, {0xc1ff6, 0xc1ffe}, {0xc2010, 0xc2027}, {0xc2030, 0xc205e}, + {0xc2074, 0xc208e}, {0xc2090, 0xc209c}, {0xc20a0, 0xc20bf}, {0xc20d0, 0xc20f0}, + {0xc2100, 0xc218b}, {0xc2190, 0xc2426}, {0xc2440, 0xc244a}, {0xc2460, 0xc2b73}, + {0xc2b76, 0xc2b95}, {0xc2b98, 0xc2bb9}, {0xc2bbd, 0xc2bc8}, {0xc2bca, 0xc2bd2}, + {0xc2bec, 0xc2bef}, {0xc2c00, 0xc2c2e}, {0xc2c30, 0xc2c5e}, {0xc2c60, 0xc2cf3}, + {0xc2cf9, 0xc2d25}, {0xc2d30, 0xc2d67}, {0xc2d7f, 0xc2d96}, {0xc2da0, 0xc2da6}, + {0xc2da8, 0xc2dae}, {0xc2db0, 0xc2db6}, {0xc2db8, 0xc2dbe}, {0xc2dc0, 0xc2dc6}, + {0xc2dc8, 0xc2dce}, {0xc2dd0, 0xc2dd6}, {0xc2dd8, 0xc2dde}, {0xc2de0, 0xc2e49}, + {0xc2e80, 0xc2e99}, {0xc2e9b, 0xc2ef3}, {0xc2f00, 0xc2fd5}, {0xc2ff0, 0xc2ffb}, + {0xc3001, 0xc303f}, {0xc3041, 0xc3096}, {0xc3099, 0xc30ff}, {0xc3105, 0xc312e}, + {0xc3131, 0xc318e}, {0xc3190, 0xc31ba}, {0xc31c0, 0xc31e3}, {0xc31f0, 0xc321e}, + {0xc3220, 0xc32fe}, {0xc3300, 0xc4db5}, {0xc4dc0, 0xc9fea}, {0xca000, 0xca48c}, + {0xca490, 0xca4c6}, {0xca4d0, 0xca62b}, {0xca640, 0xca6f7}, {0xca700, 0xca7ae}, + {0xca7b0, 0xca7b7}, {0xca7f7, 0xca82b}, {0xca830, 0xca839}, {0xca840, 0xca877}, + {0xca880, 0xca8c5}, {0xca8ce, 0xca8d9}, {0xca8e0, 0xca8fd}, {0xca900, 0xca953}, + {0xca95f, 0xca97c}, {0xca980, 0xca9cd}, {0xca9cf, 0xca9d9}, {0xca9de, 0xca9fe}, + {0xcaa00, 0xcaa36}, {0xcaa40, 0xcaa4d}, {0xcaa50, 0xcaa59}, {0xcaa5c, 0xcaac2}, + {0xcaadb, 0xcaaf6}, {0xcab01, 0xcab06}, {0xcab09, 0xcab0e}, {0xcab11, 0xcab16}, + {0xcab20, 0xcab26}, {0xcab28, 0xcab2e}, {0xcab30, 0xcab65}, {0xcab70, 0xcabed}, + {0xcabf0, 0xcabf9}, {0xcac00, 0xcd7a3}, {0xcd7b0, 0xcd7c6}, {0xcd7cb, 0xcd7fb}, + {0xcf900, 0xcfa6d}, {0xcfa70, 0xcfad9}, {0xcfb00, 0xcfb06}, {0xcfb13, 0xcfb17}, + {0xcfb1d, 0xcfb36}, {0xcfb38, 0xcfb3c}, {0xcfb46, 0xcfbc1}, {0xcfbd3, 0xcfd3f}, + {0xcfd50, 0xcfd8f}, {0xcfd92, 0xcfdc7}, {0xcfdf0, 0xcfdfd}, {0xcfe00, 0xcfe19}, + {0xcfe20, 0xcfe52}, {0xcfe54, 0xcfe66}, {0xcfe68, 0xcfe6b}, {0xcfe70, 0xcfe74}, + {0xcfe76, 0xcfefc}, {0xcff01, 0xcffbe}, {0xcffc2, 0xcffc7}, {0xcffca, 0xcffcf}, + {0xcffd2, 0xcffd7}, {0xcffda, 0xcffdc}, {0xcffe0, 0xcffe6}, {0xcffe8, 0xcffee}, + {0xd0021, 0xd007e}, {0xd00a1, 0xd00ac}, {0xd00ae, 0xd0377}, {0xd037a, 0xd037f}, + {0xd0384, 0xd038a}, {0xd038e, 0xd03a1}, {0xd03a3, 0xd052f}, {0xd0531, 0xd0556}, + {0xd0559, 0xd055f}, {0xd0561, 0xd0587}, {0xd058d, 0xd058f}, {0xd0591, 0xd05c7}, + {0xd05d0, 0xd05ea}, {0xd05f0, 0xd05f4}, {0xd0606, 0xd061b}, {0xd061e, 0xd06dc}, + {0xd06de, 0xd070d}, {0xd0710, 0xd074a}, {0xd074d, 0xd07b1}, {0xd07c0, 0xd07fa}, + {0xd0800, 0xd082d}, {0xd0830, 0xd083e}, {0xd0840, 0xd085b}, {0xd0860, 0xd086a}, + {0xd08a0, 0xd08b4}, {0xd08b6, 0xd08bd}, {0xd08d4, 0xd08e1}, {0xd08e3, 0xd0983}, + {0xd0985, 0xd098c}, {0xd0993, 0xd09a8}, {0xd09aa, 0xd09b0}, {0xd09b6, 0xd09b9}, + {0xd09bc, 0xd09c4}, {0xd09cb, 0xd09ce}, {0xd09df, 0xd09e3}, {0xd09e6, 0xd09fd}, + {0xd0a01, 0xd0a03}, {0xd0a05, 0xd0a0a}, {0xd0a13, 0xd0a28}, {0xd0a2a, 0xd0a30}, + {0xd0a3e, 0xd0a42}, {0xd0a4b, 0xd0a4d}, {0xd0a59, 0xd0a5c}, {0xd0a66, 0xd0a75}, + {0xd0a81, 0xd0a83}, {0xd0a85, 0xd0a8d}, {0xd0a8f, 0xd0a91}, {0xd0a93, 0xd0aa8}, + {0xd0aaa, 0xd0ab0}, {0xd0ab5, 0xd0ab9}, {0xd0abc, 0xd0ac5}, {0xd0ac7, 0xd0ac9}, + {0xd0acb, 0xd0acd}, {0xd0ae0, 0xd0ae3}, {0xd0ae6, 0xd0af1}, {0xd0af9, 0xd0aff}, + {0xd0b01, 0xd0b03}, {0xd0b05, 0xd0b0c}, {0xd0b13, 0xd0b28}, {0xd0b2a, 0xd0b30}, + {0xd0b35, 0xd0b39}, {0xd0b3c, 0xd0b44}, {0xd0b4b, 0xd0b4d}, {0xd0b5f, 0xd0b63}, + {0xd0b66, 0xd0b77}, {0xd0b85, 0xd0b8a}, {0xd0b8e, 0xd0b90}, {0xd0b92, 0xd0b95}, + {0xd0ba8, 0xd0baa}, {0xd0bae, 0xd0bb9}, {0xd0bbe, 0xd0bc2}, {0xd0bc6, 0xd0bc8}, + {0xd0bca, 0xd0bcd}, {0xd0be6, 0xd0bfa}, {0xd0c00, 0xd0c03}, {0xd0c05, 0xd0c0c}, + {0xd0c0e, 0xd0c10}, {0xd0c12, 0xd0c28}, {0xd0c2a, 0xd0c39}, {0xd0c3d, 0xd0c44}, + {0xd0c46, 0xd0c48}, {0xd0c4a, 0xd0c4d}, {0xd0c58, 0xd0c5a}, {0xd0c60, 0xd0c63}, + {0xd0c66, 0xd0c6f}, {0xd0c78, 0xd0c83}, {0xd0c85, 0xd0c8c}, {0xd0c8e, 0xd0c90}, + {0xd0c92, 0xd0ca8}, {0xd0caa, 0xd0cb3}, {0xd0cb5, 0xd0cb9}, {0xd0cbc, 0xd0cc4}, + {0xd0cc6, 0xd0cc8}, {0xd0cca, 0xd0ccd}, {0xd0ce0, 0xd0ce3}, {0xd0ce6, 0xd0cef}, + {0xd0d00, 0xd0d03}, {0xd0d05, 0xd0d0c}, {0xd0d0e, 0xd0d10}, {0xd0d12, 0xd0d44}, + {0xd0d46, 0xd0d48}, {0xd0d4a, 0xd0d4f}, {0xd0d54, 0xd0d63}, {0xd0d66, 0xd0d7f}, + {0xd0d85, 0xd0d96}, {0xd0d9a, 0xd0db1}, {0xd0db3, 0xd0dbb}, {0xd0dc0, 0xd0dc6}, + {0xd0dcf, 0xd0dd4}, {0xd0dd8, 0xd0ddf}, {0xd0de6, 0xd0def}, {0xd0df2, 0xd0df4}, + {0xd0e01, 0xd0e3a}, {0xd0e3f, 0xd0e5b}, {0xd0e94, 0xd0e97}, {0xd0e99, 0xd0e9f}, + {0xd0ea1, 0xd0ea3}, {0xd0ead, 0xd0eb9}, {0xd0ebb, 0xd0ebd}, {0xd0ec0, 0xd0ec4}, + {0xd0ec8, 0xd0ecd}, {0xd0ed0, 0xd0ed9}, {0xd0edc, 0xd0edf}, {0xd0f00, 0xd0f47}, + {0xd0f49, 0xd0f6c}, {0xd0f71, 0xd0f97}, {0xd0f99, 0xd0fbc}, {0xd0fbe, 0xd0fcc}, + {0xd0fce, 0xd0fda}, {0xd1000, 0xd10c5}, {0xd10d0, 0xd1248}, {0xd124a, 0xd124d}, + {0xd1250, 0xd1256}, {0xd125a, 0xd125d}, {0xd1260, 0xd1288}, {0xd128a, 0xd128d}, + {0xd1290, 0xd12b0}, {0xd12b2, 0xd12b5}, {0xd12b8, 0xd12be}, {0xd12c2, 0xd12c5}, + {0xd12c8, 0xd12d6}, {0xd12d8, 0xd1310}, {0xd1312, 0xd1315}, {0xd1318, 0xd135a}, + {0xd135d, 0xd137c}, {0xd1380, 0xd1399}, {0xd13a0, 0xd13f5}, {0xd13f8, 0xd13fd}, + {0xd1400, 0xd167f}, {0xd1681, 0xd169c}, {0xd16a0, 0xd16f8}, {0xd1700, 0xd170c}, + {0xd170e, 0xd1714}, {0xd1720, 0xd1736}, {0xd1740, 0xd1753}, {0xd1760, 0xd176c}, + {0xd176e, 0xd1770}, {0xd1780, 0xd17dd}, {0xd17e0, 0xd17e9}, {0xd17f0, 0xd17f9}, + {0xd1800, 0xd180d}, {0xd1810, 0xd1819}, {0xd1820, 0xd1877}, {0xd1880, 0xd18aa}, + {0xd18b0, 0xd18f5}, {0xd1900, 0xd191e}, {0xd1920, 0xd192b}, {0xd1930, 0xd193b}, + {0xd1944, 0xd196d}, {0xd1970, 0xd1974}, {0xd1980, 0xd19ab}, {0xd19b0, 0xd19c9}, + {0xd19d0, 0xd19da}, {0xd19de, 0xd1a1b}, {0xd1a1e, 0xd1a5e}, {0xd1a60, 0xd1a7c}, + {0xd1a7f, 0xd1a89}, {0xd1a90, 0xd1a99}, {0xd1aa0, 0xd1aad}, {0xd1ab0, 0xd1abe}, + {0xd1b00, 0xd1b4b}, {0xd1b50, 0xd1b7c}, {0xd1b80, 0xd1bf3}, {0xd1bfc, 0xd1c37}, + {0xd1c3b, 0xd1c49}, {0xd1c4d, 0xd1c88}, {0xd1cc0, 0xd1cc7}, {0xd1cd0, 0xd1cf9}, + {0xd1d00, 0xd1df9}, {0xd1dfb, 0xd1f15}, {0xd1f18, 0xd1f1d}, {0xd1f20, 0xd1f45}, + {0xd1f48, 0xd1f4d}, {0xd1f50, 0xd1f57}, {0xd1f5f, 0xd1f7d}, {0xd1f80, 0xd1fb4}, + {0xd1fb6, 0xd1fc4}, {0xd1fc6, 0xd1fd3}, {0xd1fd6, 0xd1fdb}, {0xd1fdd, 0xd1fef}, + {0xd1ff2, 0xd1ff4}, {0xd1ff6, 0xd1ffe}, {0xd2010, 0xd2027}, {0xd2030, 0xd205e}, + {0xd2074, 0xd208e}, {0xd2090, 0xd209c}, {0xd20a0, 0xd20bf}, {0xd20d0, 0xd20f0}, + {0xd2100, 0xd218b}, {0xd2190, 0xd2426}, {0xd2440, 0xd244a}, {0xd2460, 0xd2b73}, + {0xd2b76, 0xd2b95}, {0xd2b98, 0xd2bb9}, {0xd2bbd, 0xd2bc8}, {0xd2bca, 0xd2bd2}, + {0xd2bec, 0xd2bef}, {0xd2c00, 0xd2c2e}, {0xd2c30, 0xd2c5e}, {0xd2c60, 0xd2cf3}, + {0xd2cf9, 0xd2d25}, {0xd2d30, 0xd2d67}, {0xd2d7f, 0xd2d96}, {0xd2da0, 0xd2da6}, + {0xd2da8, 0xd2dae}, {0xd2db0, 0xd2db6}, {0xd2db8, 0xd2dbe}, {0xd2dc0, 0xd2dc6}, + {0xd2dc8, 0xd2dce}, {0xd2dd0, 0xd2dd6}, {0xd2dd8, 0xd2dde}, {0xd2de0, 0xd2e49}, + {0xd2e80, 0xd2e99}, {0xd2e9b, 0xd2ef3}, {0xd2f00, 0xd2fd5}, {0xd2ff0, 0xd2ffb}, + {0xd3001, 0xd303f}, {0xd3041, 0xd3096}, {0xd3099, 0xd30ff}, {0xd3105, 0xd312e}, + {0xd3131, 0xd318e}, {0xd3190, 0xd31ba}, {0xd31c0, 0xd31e3}, {0xd31f0, 0xd321e}, + {0xd3220, 0xd32fe}, {0xd3300, 0xd4db5}, {0xd4dc0, 0xd9fea}, {0xda000, 0xda48c}, + {0xda490, 0xda4c6}, {0xda4d0, 0xda62b}, {0xda640, 0xda6f7}, {0xda700, 0xda7ae}, + {0xda7b0, 0xda7b7}, {0xda7f7, 0xda82b}, {0xda830, 0xda839}, {0xda840, 0xda877}, + {0xda880, 0xda8c5}, {0xda8ce, 0xda8d9}, {0xda8e0, 0xda8fd}, {0xda900, 0xda953}, + {0xda95f, 0xda97c}, {0xda980, 0xda9cd}, {0xda9cf, 0xda9d9}, {0xda9de, 0xda9fe}, + {0xdaa00, 0xdaa36}, {0xdaa40, 0xdaa4d}, {0xdaa50, 0xdaa59}, {0xdaa5c, 0xdaac2}, + {0xdaadb, 0xdaaf6}, {0xdab01, 0xdab06}, {0xdab09, 0xdab0e}, {0xdab11, 0xdab16}, + {0xdab20, 0xdab26}, {0xdab28, 0xdab2e}, {0xdab30, 0xdab65}, {0xdab70, 0xdabed}, + {0xdabf0, 0xdabf9}, {0xdac00, 0xdd7a3}, {0xdd7b0, 0xdd7c6}, {0xdd7cb, 0xdd7fb}, + {0xdf900, 0xdfa6d}, {0xdfa70, 0xdfad9}, {0xdfb00, 0xdfb06}, {0xdfb13, 0xdfb17}, + {0xdfb1d, 0xdfb36}, {0xdfb38, 0xdfb3c}, {0xdfb46, 0xdfbc1}, {0xdfbd3, 0xdfd3f}, + {0xdfd50, 0xdfd8f}, {0xdfd92, 0xdfdc7}, {0xdfdf0, 0xdfdfd}, {0xdfe00, 0xdfe19}, + {0xdfe20, 0xdfe52}, {0xdfe54, 0xdfe66}, {0xdfe68, 0xdfe6b}, {0xdfe70, 0xdfe74}, + {0xdfe76, 0xdfefc}, {0xdff01, 0xdffbe}, {0xdffc2, 0xdffc7}, {0xdffca, 0xdffcf}, + {0xdffd2, 0xdffd7}, {0xdffda, 0xdffdc}, {0xdffe0, 0xdffe6}, {0xdffe8, 0xdffee}, + {0xe0021, 0xe007e}, {0xe00a1, 0xe00ac}, {0xe00ae, 0xe0377}, {0xe037a, 0xe037f}, + {0xe0384, 0xe038a}, {0xe038e, 0xe03a1}, {0xe03a3, 0xe052f}, {0xe0531, 0xe0556}, + {0xe0559, 0xe055f}, {0xe0561, 0xe0587}, {0xe058d, 0xe058f}, {0xe0591, 0xe05c7}, + {0xe05d0, 0xe05ea}, {0xe05f0, 0xe05f4}, {0xe0606, 0xe061b}, {0xe061e, 0xe06dc}, + {0xe06de, 0xe070d}, {0xe0710, 0xe074a}, {0xe074d, 0xe07b1}, {0xe07c0, 0xe07fa}, + {0xe0800, 0xe082d}, {0xe0830, 0xe083e}, {0xe0840, 0xe085b}, {0xe0860, 0xe086a}, + {0xe08a0, 0xe08b4}, {0xe08b6, 0xe08bd}, {0xe08d4, 0xe08e1}, {0xe08e3, 0xe0983}, + {0xe0985, 0xe098c}, {0xe0993, 0xe09a8}, {0xe09aa, 0xe09b0}, {0xe09b6, 0xe09b9}, + {0xe09bc, 0xe09c4}, {0xe09cb, 0xe09ce}, {0xe09df, 0xe09e3}, {0xe09e6, 0xe09fd}, + {0xe0a01, 0xe0a03}, {0xe0a05, 0xe0a0a}, {0xe0a13, 0xe0a28}, {0xe0a2a, 0xe0a30}, + {0xe0a3e, 0xe0a42}, {0xe0a4b, 0xe0a4d}, {0xe0a59, 0xe0a5c}, {0xe0a66, 0xe0a75}, + {0xe0a81, 0xe0a83}, {0xe0a85, 0xe0a8d}, {0xe0a8f, 0xe0a91}, {0xe0a93, 0xe0aa8}, + {0xe0aaa, 0xe0ab0}, {0xe0ab5, 0xe0ab9}, {0xe0abc, 0xe0ac5}, {0xe0ac7, 0xe0ac9}, + {0xe0acb, 0xe0acd}, {0xe0ae0, 0xe0ae3}, {0xe0ae6, 0xe0af1}, {0xe0af9, 0xe0aff}, + {0xe0b01, 0xe0b03}, {0xe0b05, 0xe0b0c}, {0xe0b13, 0xe0b28}, {0xe0b2a, 0xe0b30}, + {0xe0b35, 0xe0b39}, {0xe0b3c, 0xe0b44}, {0xe0b4b, 0xe0b4d}, {0xe0b5f, 0xe0b63}, + {0xe0b66, 0xe0b77}, {0xe0b85, 0xe0b8a}, {0xe0b8e, 0xe0b90}, {0xe0b92, 0xe0b95}, + {0xe0ba8, 0xe0baa}, {0xe0bae, 0xe0bb9}, {0xe0bbe, 0xe0bc2}, {0xe0bc6, 0xe0bc8}, + {0xe0bca, 0xe0bcd}, {0xe0be6, 0xe0bfa}, {0xe0c00, 0xe0c03}, {0xe0c05, 0xe0c0c}, + {0xe0c0e, 0xe0c10}, {0xe0c12, 0xe0c28}, {0xe0c2a, 0xe0c39}, {0xe0c3d, 0xe0c44}, + {0xe0c46, 0xe0c48}, {0xe0c4a, 0xe0c4d}, {0xe0c58, 0xe0c5a}, {0xe0c60, 0xe0c63}, + {0xe0c66, 0xe0c6f}, {0xe0c78, 0xe0c83}, {0xe0c85, 0xe0c8c}, {0xe0c8e, 0xe0c90}, + {0xe0c92, 0xe0ca8}, {0xe0caa, 0xe0cb3}, {0xe0cb5, 0xe0cb9}, {0xe0cbc, 0xe0cc4}, + {0xe0cc6, 0xe0cc8}, {0xe0cca, 0xe0ccd}, {0xe0ce0, 0xe0ce3}, {0xe0ce6, 0xe0cef}, + {0xe0d00, 0xe0d03}, {0xe0d05, 0xe0d0c}, {0xe0d0e, 0xe0d10}, {0xe0d12, 0xe0d44}, + {0xe0d46, 0xe0d48}, {0xe0d4a, 0xe0d4f}, {0xe0d54, 0xe0d63}, {0xe0d66, 0xe0d7f}, + {0xe0d85, 0xe0d96}, {0xe0d9a, 0xe0db1}, {0xe0db3, 0xe0dbb}, {0xe0dc0, 0xe0dc6}, + {0xe0dcf, 0xe0dd4}, {0xe0dd8, 0xe0ddf}, {0xe0de6, 0xe0def}, {0xe0df2, 0xe0df4}, + {0xe0e01, 0xe0e3a}, {0xe0e3f, 0xe0e5b}, {0xe0e94, 0xe0e97}, {0xe0e99, 0xe0e9f}, + {0xe0ea1, 0xe0ea3}, {0xe0ead, 0xe0eb9}, {0xe0ebb, 0xe0ebd}, {0xe0ec0, 0xe0ec4}, + {0xe0ec8, 0xe0ecd}, {0xe0ed0, 0xe0ed9}, {0xe0edc, 0xe0edf}, {0xe0f00, 0xe0f47}, + {0xe0f49, 0xe0f6c}, {0xe0f71, 0xe0f97}, {0xe0f99, 0xe0fbc}, {0xe0fbe, 0xe0fcc}, + {0xe0fce, 0xe0fda}, {0xe1000, 0xe10c5}, {0xe10d0, 0xe1248}, {0xe124a, 0xe124d}, + {0xe1250, 0xe1256}, {0xe125a, 0xe125d}, {0xe1260, 0xe1288}, {0xe128a, 0xe128d}, + {0xe1290, 0xe12b0}, {0xe12b2, 0xe12b5}, {0xe12b8, 0xe12be}, {0xe12c2, 0xe12c5}, + {0xe12c8, 0xe12d6}, {0xe12d8, 0xe1310}, {0xe1312, 0xe1315}, {0xe1318, 0xe135a}, + {0xe135d, 0xe137c}, {0xe1380, 0xe1399}, {0xe13a0, 0xe13f5}, {0xe13f8, 0xe13fd}, + {0xe1400, 0xe167f}, {0xe1681, 0xe169c}, {0xe16a0, 0xe16f8}, {0xe1700, 0xe170c}, + {0xe170e, 0xe1714}, {0xe1720, 0xe1736}, {0xe1740, 0xe1753}, {0xe1760, 0xe176c}, + {0xe176e, 0xe1770}, {0xe1780, 0xe17dd}, {0xe17e0, 0xe17e9}, {0xe17f0, 0xe17f9}, + {0xe1800, 0xe180d}, {0xe1810, 0xe1819}, {0xe1820, 0xe1877}, {0xe1880, 0xe18aa}, + {0xe18b0, 0xe18f5}, {0xe1900, 0xe191e}, {0xe1920, 0xe192b}, {0xe1930, 0xe193b}, + {0xe1944, 0xe196d}, {0xe1970, 0xe1974}, {0xe1980, 0xe19ab}, {0xe19b0, 0xe19c9}, + {0xe19d0, 0xe19da}, {0xe19de, 0xe1a1b}, {0xe1a1e, 0xe1a5e}, {0xe1a60, 0xe1a7c}, + {0xe1a7f, 0xe1a89}, {0xe1a90, 0xe1a99}, {0xe1aa0, 0xe1aad}, {0xe1ab0, 0xe1abe}, + {0xe1b00, 0xe1b4b}, {0xe1b50, 0xe1b7c}, {0xe1b80, 0xe1bf3}, {0xe1bfc, 0xe1c37}, + {0xe1c3b, 0xe1c49}, {0xe1c4d, 0xe1c88}, {0xe1cc0, 0xe1cc7}, {0xe1cd0, 0xe1cf9}, + {0xe1d00, 0xe1df9}, {0xe1dfb, 0xe1f15}, {0xe1f18, 0xe1f1d}, {0xe1f20, 0xe1f45}, + {0xe1f48, 0xe1f4d}, {0xe1f50, 0xe1f57}, {0xe1f5f, 0xe1f7d}, {0xe1f80, 0xe1fb4}, + {0xe1fb6, 0xe1fc4}, {0xe1fc6, 0xe1fd3}, {0xe1fd6, 0xe1fdb}, {0xe1fdd, 0xe1fef}, + {0xe1ff2, 0xe1ff4}, {0xe1ff6, 0xe1ffe}, {0xe2010, 0xe2027}, {0xe2030, 0xe205e}, + {0xe2074, 0xe208e}, {0xe2090, 0xe209c}, {0xe20a0, 0xe20bf}, {0xe20d0, 0xe20f0}, + {0xe2100, 0xe218b}, {0xe2190, 0xe2426}, {0xe2440, 0xe244a}, {0xe2460, 0xe2b73}, + {0xe2b76, 0xe2b95}, {0xe2b98, 0xe2bb9}, {0xe2bbd, 0xe2bc8}, {0xe2bca, 0xe2bd2}, + {0xe2bec, 0xe2bef}, {0xe2c00, 0xe2c2e}, {0xe2c30, 0xe2c5e}, {0xe2c60, 0xe2cf3}, + {0xe2cf9, 0xe2d25}, {0xe2d30, 0xe2d67}, {0xe2d7f, 0xe2d96}, {0xe2da0, 0xe2da6}, + {0xe2da8, 0xe2dae}, {0xe2db0, 0xe2db6}, {0xe2db8, 0xe2dbe}, {0xe2dc0, 0xe2dc6}, + {0xe2dc8, 0xe2dce}, {0xe2dd0, 0xe2dd6}, {0xe2dd8, 0xe2dde}, {0xe2de0, 0xe2e49}, + {0xe2e80, 0xe2e99}, {0xe2e9b, 0xe2ef3}, {0xe2f00, 0xe2fd5}, {0xe2ff0, 0xe2ffb}, + {0xe3001, 0xe303f}, {0xe3041, 0xe3096}, {0xe3099, 0xe30ff}, {0xe3105, 0xe312e}, + {0xe3131, 0xe318e}, {0xe3190, 0xe31ba}, {0xe31c0, 0xe31e3}, {0xe31f0, 0xe321e}, + {0xe3220, 0xe32fe}, {0xe3300, 0xe4db5}, {0xe4dc0, 0xe9fea}, {0xea000, 0xea48c}, + {0xea490, 0xea4c6}, {0xea4d0, 0xea62b}, {0xea640, 0xea6f7}, {0xea700, 0xea7ae}, + {0xea7b0, 0xea7b7}, {0xea7f7, 0xea82b}, {0xea830, 0xea839}, {0xea840, 0xea877}, + {0xea880, 0xea8c5}, {0xea8ce, 0xea8d9}, {0xea8e0, 0xea8fd}, {0xea900, 0xea953}, + {0xea95f, 0xea97c}, {0xea980, 0xea9cd}, {0xea9cf, 0xea9d9}, {0xea9de, 0xea9fe}, + {0xeaa00, 0xeaa36}, {0xeaa40, 0xeaa4d}, {0xeaa50, 0xeaa59}, {0xeaa5c, 0xeaac2}, + {0xeaadb, 0xeaaf6}, {0xeab01, 0xeab06}, {0xeab09, 0xeab0e}, {0xeab11, 0xeab16}, + {0xeab20, 0xeab26}, {0xeab28, 0xeab2e}, {0xeab30, 0xeab65}, {0xeab70, 0xeabed}, + {0xeabf0, 0xeabf9}, {0xeac00, 0xed7a3}, {0xed7b0, 0xed7c6}, {0xed7cb, 0xed7fb}, + {0xef900, 0xefa6d}, {0xefa70, 0xefad9}, {0xefb00, 0xefb06}, {0xefb13, 0xefb17}, + {0xefb1d, 0xefb36}, {0xefb38, 0xefb3c}, {0xefb46, 0xefbc1}, {0xefbd3, 0xefd3f}, + {0xefd50, 0xefd8f}, {0xefd92, 0xefdc7}, {0xefdf0, 0xefdfd}, {0xefe00, 0xefe19}, + {0xefe20, 0xefe52}, {0xefe54, 0xefe66}, {0xefe68, 0xefe6b}, {0xefe70, 0xefe74}, + {0xefe76, 0xefefc}, {0xeff01, 0xeffbe}, {0xeffc2, 0xeffc7}, {0xeffca, 0xeffcf}, + {0xeffd2, 0xeffd7}, {0xeffda, 0xeffdc}, {0xeffe0, 0xeffe6}, {0xeffe8, 0xeffee}, + {0xf0021, 0xf007e}, {0xf00a1, 0xf00ac}, {0xf00ae, 0xf0377}, {0xf037a, 0xf037f}, + {0xf0384, 0xf038a}, {0xf038e, 0xf03a1}, {0xf03a3, 0xf052f}, {0xf0531, 0xf0556}, + {0xf0559, 0xf055f}, {0xf0561, 0xf0587}, {0xf058d, 0xf058f}, {0xf0591, 0xf05c7}, + {0xf05d0, 0xf05ea}, {0xf05f0, 0xf05f4}, {0xf0606, 0xf061b}, {0xf061e, 0xf06dc}, + {0xf06de, 0xf070d}, {0xf0710, 0xf074a}, {0xf074d, 0xf07b1}, {0xf07c0, 0xf07fa}, + {0xf0800, 0xf082d}, {0xf0830, 0xf083e}, {0xf0840, 0xf085b}, {0xf0860, 0xf086a}, + {0xf08a0, 0xf08b4}, {0xf08b6, 0xf08bd}, {0xf08d4, 0xf08e1}, {0xf08e3, 0xf0983}, + {0xf0985, 0xf098c}, {0xf0993, 0xf09a8}, {0xf09aa, 0xf09b0}, {0xf09b6, 0xf09b9}, + {0xf09bc, 0xf09c4}, {0xf09cb, 0xf09ce}, {0xf09df, 0xf09e3}, {0xf09e6, 0xf09fd}, + {0xf0a01, 0xf0a03}, {0xf0a05, 0xf0a0a}, {0xf0a13, 0xf0a28}, {0xf0a2a, 0xf0a30}, + {0xf0a3e, 0xf0a42}, {0xf0a4b, 0xf0a4d}, {0xf0a59, 0xf0a5c}, {0xf0a66, 0xf0a75}, + {0xf0a81, 0xf0a83}, {0xf0a85, 0xf0a8d}, {0xf0a8f, 0xf0a91}, {0xf0a93, 0xf0aa8}, + {0xf0aaa, 0xf0ab0}, {0xf0ab5, 0xf0ab9}, {0xf0abc, 0xf0ac5}, {0xf0ac7, 0xf0ac9}, + {0xf0acb, 0xf0acd}, {0xf0ae0, 0xf0ae3}, {0xf0ae6, 0xf0af1}, {0xf0af9, 0xf0aff}, + {0xf0b01, 0xf0b03}, {0xf0b05, 0xf0b0c}, {0xf0b13, 0xf0b28}, {0xf0b2a, 0xf0b30}, + {0xf0b35, 0xf0b39}, {0xf0b3c, 0xf0b44}, {0xf0b4b, 0xf0b4d}, {0xf0b5f, 0xf0b63}, + {0xf0b66, 0xf0b77}, {0xf0b85, 0xf0b8a}, {0xf0b8e, 0xf0b90}, {0xf0b92, 0xf0b95}, + {0xf0ba8, 0xf0baa}, {0xf0bae, 0xf0bb9}, {0xf0bbe, 0xf0bc2}, {0xf0bc6, 0xf0bc8}, + {0xf0bca, 0xf0bcd}, {0xf0be6, 0xf0bfa}, {0xf0c00, 0xf0c03}, {0xf0c05, 0xf0c0c}, + {0xf0c0e, 0xf0c10}, {0xf0c12, 0xf0c28}, {0xf0c2a, 0xf0c39}, {0xf0c3d, 0xf0c44}, + {0xf0c46, 0xf0c48}, {0xf0c4a, 0xf0c4d}, {0xf0c58, 0xf0c5a}, {0xf0c60, 0xf0c63}, + {0xf0c66, 0xf0c6f}, {0xf0c78, 0xf0c83}, {0xf0c85, 0xf0c8c}, {0xf0c8e, 0xf0c90}, + {0xf0c92, 0xf0ca8}, {0xf0caa, 0xf0cb3}, {0xf0cb5, 0xf0cb9}, {0xf0cbc, 0xf0cc4}, + {0xf0cc6, 0xf0cc8}, {0xf0cca, 0xf0ccd}, {0xf0ce0, 0xf0ce3}, {0xf0ce6, 0xf0cef}, + {0xf0d00, 0xf0d03}, {0xf0d05, 0xf0d0c}, {0xf0d0e, 0xf0d10}, {0xf0d12, 0xf0d44}, + {0xf0d46, 0xf0d48}, {0xf0d4a, 0xf0d4f}, {0xf0d54, 0xf0d63}, {0xf0d66, 0xf0d7f}, + {0xf0d85, 0xf0d96}, {0xf0d9a, 0xf0db1}, {0xf0db3, 0xf0dbb}, {0xf0dc0, 0xf0dc6}, + {0xf0dcf, 0xf0dd4}, {0xf0dd8, 0xf0ddf}, {0xf0de6, 0xf0def}, {0xf0df2, 0xf0df4}, + {0xf0e01, 0xf0e3a}, {0xf0e3f, 0xf0e5b}, {0xf0e94, 0xf0e97}, {0xf0e99, 0xf0e9f}, + {0xf0ea1, 0xf0ea3}, {0xf0ead, 0xf0eb9}, {0xf0ebb, 0xf0ebd}, {0xf0ec0, 0xf0ec4}, + {0xf0ec8, 0xf0ecd}, {0xf0ed0, 0xf0ed9}, {0xf0edc, 0xf0edf}, {0xf0f00, 0xf0f47}, + {0xf0f49, 0xf0f6c}, {0xf0f71, 0xf0f97}, {0xf0f99, 0xf0fbc}, {0xf0fbe, 0xf0fcc}, + {0xf0fce, 0xf0fda}, {0xf1000, 0xf10c5}, {0xf10d0, 0xf1248}, {0xf124a, 0xf124d}, + {0xf1250, 0xf1256}, {0xf125a, 0xf125d}, {0xf1260, 0xf1288}, {0xf128a, 0xf128d}, + {0xf1290, 0xf12b0}, {0xf12b2, 0xf12b5}, {0xf12b8, 0xf12be}, {0xf12c2, 0xf12c5}, + {0xf12c8, 0xf12d6}, {0xf12d8, 0xf1310}, {0xf1312, 0xf1315}, {0xf1318, 0xf135a}, + {0xf135d, 0xf137c}, {0xf1380, 0xf1399}, {0xf13a0, 0xf13f5}, {0xf13f8, 0xf13fd}, + {0xf1400, 0xf167f}, {0xf1681, 0xf169c}, {0xf16a0, 0xf16f8}, {0xf1700, 0xf170c}, + {0xf170e, 0xf1714}, {0xf1720, 0xf1736}, {0xf1740, 0xf1753}, {0xf1760, 0xf176c}, + {0xf176e, 0xf1770}, {0xf1780, 0xf17dd}, {0xf17e0, 0xf17e9}, {0xf17f0, 0xf17f9}, + {0xf1800, 0xf180d}, {0xf1810, 0xf1819}, {0xf1820, 0xf1877}, {0xf1880, 0xf18aa}, + {0xf18b0, 0xf18f5}, {0xf1900, 0xf191e}, {0xf1920, 0xf192b}, {0xf1930, 0xf193b}, + {0xf1944, 0xf196d}, {0xf1970, 0xf1974}, {0xf1980, 0xf19ab}, {0xf19b0, 0xf19c9}, + {0xf19d0, 0xf19da}, {0xf19de, 0xf1a1b}, {0xf1a1e, 0xf1a5e}, {0xf1a60, 0xf1a7c}, + {0xf1a7f, 0xf1a89}, {0xf1a90, 0xf1a99}, {0xf1aa0, 0xf1aad}, {0xf1ab0, 0xf1abe}, + {0xf1b00, 0xf1b4b}, {0xf1b50, 0xf1b7c}, {0xf1b80, 0xf1bf3}, {0xf1bfc, 0xf1c37}, + {0xf1c3b, 0xf1c49}, {0xf1c4d, 0xf1c88}, {0xf1cc0, 0xf1cc7}, {0xf1cd0, 0xf1cf9}, + {0xf1d00, 0xf1df9}, {0xf1dfb, 0xf1f15}, {0xf1f18, 0xf1f1d}, {0xf1f20, 0xf1f45}, + {0xf1f48, 0xf1f4d}, {0xf1f50, 0xf1f57}, {0xf1f5f, 0xf1f7d}, {0xf1f80, 0xf1fb4}, + {0xf1fb6, 0xf1fc4}, {0xf1fc6, 0xf1fd3}, {0xf1fd6, 0xf1fdb}, {0xf1fdd, 0xf1fef}, + {0xf1ff2, 0xf1ff4}, {0xf1ff6, 0xf1ffe}, {0xf2010, 0xf2027}, {0xf2030, 0xf205e}, + {0xf2074, 0xf208e}, {0xf2090, 0xf209c}, {0xf20a0, 0xf20bf}, {0xf20d0, 0xf20f0}, + {0xf2100, 0xf218b}, {0xf2190, 0xf2426}, {0xf2440, 0xf244a}, {0xf2460, 0xf2b73}, + {0xf2b76, 0xf2b95}, {0xf2b98, 0xf2bb9}, {0xf2bbd, 0xf2bc8}, {0xf2bca, 0xf2bd2}, + {0xf2bec, 0xf2bef}, {0xf2c00, 0xf2c2e}, {0xf2c30, 0xf2c5e}, {0xf2c60, 0xf2cf3}, + {0xf2cf9, 0xf2d25}, {0xf2d30, 0xf2d67}, {0xf2d7f, 0xf2d96}, {0xf2da0, 0xf2da6}, + {0xf2da8, 0xf2dae}, {0xf2db0, 0xf2db6}, {0xf2db8, 0xf2dbe}, {0xf2dc0, 0xf2dc6}, + {0xf2dc8, 0xf2dce}, {0xf2dd0, 0xf2dd6}, {0xf2dd8, 0xf2dde}, {0xf2de0, 0xf2e49}, + {0xf2e80, 0xf2e99}, {0xf2e9b, 0xf2ef3}, {0xf2f00, 0xf2fd5}, {0xf2ff0, 0xf2ffb}, + {0xf3001, 0xf303f}, {0xf3041, 0xf3096}, {0xf3099, 0xf30ff}, {0xf3105, 0xf312e}, + {0xf3131, 0xf318e}, {0xf3190, 0xf31ba}, {0xf31c0, 0xf31e3}, {0xf31f0, 0xf321e}, + {0xf3220, 0xf32fe}, {0xf3300, 0xf4db5}, {0xf4dc0, 0xf9fea}, {0xfa000, 0xfa48c}, + {0xfa490, 0xfa4c6}, {0xfa4d0, 0xfa62b}, {0xfa640, 0xfa6f7}, {0xfa700, 0xfa7ae}, + {0xfa7b0, 0xfa7b7}, {0xfa7f7, 0xfa82b}, {0xfa830, 0xfa839}, {0xfa840, 0xfa877}, + {0xfa880, 0xfa8c5}, {0xfa8ce, 0xfa8d9}, {0xfa8e0, 0xfa8fd}, {0xfa900, 0xfa953}, + {0xfa95f, 0xfa97c}, {0xfa980, 0xfa9cd}, {0xfa9cf, 0xfa9d9}, {0xfa9de, 0xfa9fe}, + {0xfaa00, 0xfaa36}, {0xfaa40, 0xfaa4d}, {0xfaa50, 0xfaa59}, {0xfaa5c, 0xfaac2}, + {0xfaadb, 0xfaaf6}, {0xfab01, 0xfab06}, {0xfab09, 0xfab0e}, {0xfab11, 0xfab16}, + {0xfab20, 0xfab26}, {0xfab28, 0xfab2e}, {0xfab30, 0xfab65}, {0xfab70, 0xfabed}, + {0xfabf0, 0xfabf9}, {0xfac00, 0xfd7a3}, {0xfd7b0, 0xfd7c6}, {0xfd7cb, 0xfd7fb}, + {0xff900, 0xffa6d}, {0xffa70, 0xffad9}, {0xffb00, 0xffb06}, {0xffb13, 0xffb17}, + {0xffb1d, 0xffb36}, {0xffb38, 0xffb3c}, {0xffb46, 0xffbc1}, {0xffbd3, 0xffd3f}, + {0xffd50, 0xffd8f}, {0xffd92, 0xffdc7}, {0xffdf0, 0xffdfd}, {0xffe00, 0xffe19}, + {0xffe20, 0xffe52}, {0xffe54, 0xffe66}, {0xffe68, 0xffe6b}, {0xffe70, 0xffe74}, + {0xffe76, 0xffefc}, {0xfff01, 0xfffbe}, {0xfffc2, 0xfffc7}, {0xfffca, 0xfffcf}, + {0xfffd2, 0xfffd7}, {0xfffda, 0xfffdc}, {0xfffe0, 0xfffe6}, {0xfffe8, 0xfffee}, + {0x100021, 0x10007e}, {0x1000a1, 0x1000ac}, {0x1000ae, 0x100377}, {0x10037a, 0x10037f}, + {0x100384, 0x10038a}, {0x10038e, 0x1003a1}, {0x1003a3, 0x10052f}, {0x100531, 0x100556}, + {0x100559, 0x10055f}, {0x100561, 0x100587}, {0x10058d, 0x10058f}, {0x100591, 0x1005c7}, + {0x1005d0, 0x1005ea}, {0x1005f0, 0x1005f4}, {0x100606, 0x10061b}, {0x10061e, 0x1006dc}, + {0x1006de, 0x10070d}, {0x100710, 0x10074a}, {0x10074d, 0x1007b1}, {0x1007c0, 0x1007fa}, + {0x100800, 0x10082d}, {0x100830, 0x10083e}, {0x100840, 0x10085b}, {0x100860, 0x10086a}, + {0x1008a0, 0x1008b4}, {0x1008b6, 0x1008bd}, {0x1008d4, 0x1008e1}, {0x1008e3, 0x100983}, + {0x100985, 0x10098c}, {0x100993, 0x1009a8}, {0x1009aa, 0x1009b0}, {0x1009b6, 0x1009b9}, + {0x1009bc, 0x1009c4}, {0x1009cb, 0x1009ce}, {0x1009df, 0x1009e3}, {0x1009e6, 0x1009fd}, + {0x100a01, 0x100a03}, {0x100a05, 0x100a0a}, {0x100a13, 0x100a28}, {0x100a2a, 0x100a30}, + {0x100a3e, 0x100a42}, {0x100a4b, 0x100a4d}, {0x100a59, 0x100a5c}, {0x100a66, 0x100a75}, + {0x100a81, 0x100a83}, {0x100a85, 0x100a8d}, {0x100a8f, 0x100a91}, {0x100a93, 0x100aa8}, + {0x100aaa, 0x100ab0}, {0x100ab5, 0x100ab9}, {0x100abc, 0x100ac5}, {0x100ac7, 0x100ac9}, + {0x100acb, 0x100acd}, {0x100ae0, 0x100ae3}, {0x100ae6, 0x100af1}, {0x100af9, 0x100aff}, + {0x100b01, 0x100b03}, {0x100b05, 0x100b0c}, {0x100b13, 0x100b28}, {0x100b2a, 0x100b30}, + {0x100b35, 0x100b39}, {0x100b3c, 0x100b44}, {0x100b4b, 0x100b4d}, {0x100b5f, 0x100b63}, + {0x100b66, 0x100b77}, {0x100b85, 0x100b8a}, {0x100b8e, 0x100b90}, {0x100b92, 0x100b95}, + {0x100ba8, 0x100baa}, {0x100bae, 0x100bb9}, {0x100bbe, 0x100bc2}, {0x100bc6, 0x100bc8}, + {0x100bca, 0x100bcd}, {0x100be6, 0x100bfa}, {0x100c00, 0x100c03}, {0x100c05, 0x100c0c}, + {0x100c0e, 0x100c10}, {0x100c12, 0x100c28}, {0x100c2a, 0x100c39}, {0x100c3d, 0x100c44}, + {0x100c46, 0x100c48}, {0x100c4a, 0x100c4d}, {0x100c58, 0x100c5a}, {0x100c60, 0x100c63}, + {0x100c66, 0x100c6f}, {0x100c78, 0x100c83}, {0x100c85, 0x100c8c}, {0x100c8e, 0x100c90}, + {0x100c92, 0x100ca8}, {0x100caa, 0x100cb3}, {0x100cb5, 0x100cb9}, {0x100cbc, 0x100cc4}, + {0x100cc6, 0x100cc8}, {0x100cca, 0x100ccd}, {0x100ce0, 0x100ce3}, {0x100ce6, 0x100cef}, + {0x100d00, 0x100d03}, {0x100d05, 0x100d0c}, {0x100d0e, 0x100d10}, {0x100d12, 0x100d44}, + {0x100d46, 0x100d48}, {0x100d4a, 0x100d4f}, {0x100d54, 0x100d63}, {0x100d66, 0x100d7f}, + {0x100d85, 0x100d96}, {0x100d9a, 0x100db1}, {0x100db3, 0x100dbb}, {0x100dc0, 0x100dc6}, + {0x100dcf, 0x100dd4}, {0x100dd8, 0x100ddf}, {0x100de6, 0x100def}, {0x100df2, 0x100df4}, + {0x100e01, 0x100e3a}, {0x100e3f, 0x100e5b}, {0x100e94, 0x100e97}, {0x100e99, 0x100e9f}, + {0x100ea1, 0x100ea3}, {0x100ead, 0x100eb9}, {0x100ebb, 0x100ebd}, {0x100ec0, 0x100ec4}, + {0x100ec8, 0x100ecd}, {0x100ed0, 0x100ed9}, {0x100edc, 0x100edf}, {0x100f00, 0x100f47}, + {0x100f49, 0x100f6c}, {0x100f71, 0x100f97}, {0x100f99, 0x100fbc}, {0x100fbe, 0x100fcc}, + {0x100fce, 0x100fda}, {0x101000, 0x1010c5}, {0x1010d0, 0x101248}, {0x10124a, 0x10124d}, + {0x101250, 0x101256}, {0x10125a, 0x10125d}, {0x101260, 0x101288}, {0x10128a, 0x10128d}, + {0x101290, 0x1012b0}, {0x1012b2, 0x1012b5}, {0x1012b8, 0x1012be}, {0x1012c2, 0x1012c5}, + {0x1012c8, 0x1012d6}, {0x1012d8, 0x101310}, {0x101312, 0x101315}, {0x101318, 0x10135a}, + {0x10135d, 0x10137c}, {0x101380, 0x101399}, {0x1013a0, 0x1013f5}, {0x1013f8, 0x1013fd}, + {0x101400, 0x10167f}, {0x101681, 0x10169c}, {0x1016a0, 0x1016f8}, {0x101700, 0x10170c}, + {0x10170e, 0x101714}, {0x101720, 0x101736}, {0x101740, 0x101753}, {0x101760, 0x10176c}, + {0x10176e, 0x101770}, {0x101780, 0x1017dd}, {0x1017e0, 0x1017e9}, {0x1017f0, 0x1017f9}, + {0x101800, 0x10180d}, {0x101810, 0x101819}, {0x101820, 0x101877}, {0x101880, 0x1018aa}, + {0x1018b0, 0x1018f5}, {0x101900, 0x10191e}, {0x101920, 0x10192b}, {0x101930, 0x10193b}, + {0x101944, 0x10196d}, {0x101970, 0x101974}, {0x101980, 0x1019ab}, {0x1019b0, 0x1019c9}, + {0x1019d0, 0x1019da}, {0x1019de, 0x101a1b}, {0x101a1e, 0x101a5e}, {0x101a60, 0x101a7c}, + {0x101a7f, 0x101a89}, {0x101a90, 0x101a99}, {0x101aa0, 0x101aad}, {0x101ab0, 0x101abe}, + {0x101b00, 0x101b4b}, {0x101b50, 0x101b7c}, {0x101b80, 0x101bf3}, {0x101bfc, 0x101c37}, + {0x101c3b, 0x101c49}, {0x101c4d, 0x101c88}, {0x101cc0, 0x101cc7}, {0x101cd0, 0x101cf9}, + {0x101d00, 0x101df9}, {0x101dfb, 0x101f15}, {0x101f18, 0x101f1d}, {0x101f20, 0x101f45}, + {0x101f48, 0x101f4d}, {0x101f50, 0x101f57}, {0x101f5f, 0x101f7d}, {0x101f80, 0x101fb4}, + {0x101fb6, 0x101fc4}, {0x101fc6, 0x101fd3}, {0x101fd6, 0x101fdb}, {0x101fdd, 0x101fef}, + {0x101ff2, 0x101ff4}, {0x101ff6, 0x101ffe}, {0x102010, 0x102027}, {0x102030, 0x10205e}, + {0x102074, 0x10208e}, {0x102090, 0x10209c}, {0x1020a0, 0x1020bf}, {0x1020d0, 0x1020f0}, + {0x102100, 0x10218b}, {0x102190, 0x102426}, {0x102440, 0x10244a}, {0x102460, 0x102b73}, + {0x102b76, 0x102b95}, {0x102b98, 0x102bb9}, {0x102bbd, 0x102bc8}, {0x102bca, 0x102bd2}, + {0x102bec, 0x102bef}, {0x102c00, 0x102c2e}, {0x102c30, 0x102c5e}, {0x102c60, 0x102cf3}, + {0x102cf9, 0x102d25}, {0x102d30, 0x102d67}, {0x102d7f, 0x102d96}, {0x102da0, 0x102da6}, + {0x102da8, 0x102dae}, {0x102db0, 0x102db6}, {0x102db8, 0x102dbe}, {0x102dc0, 0x102dc6}, + {0x102dc8, 0x102dce}, {0x102dd0, 0x102dd6}, {0x102dd8, 0x102dde}, {0x102de0, 0x102e49}, + {0x102e80, 0x102e99}, {0x102e9b, 0x102ef3}, {0x102f00, 0x102fd5}, {0x102ff0, 0x102ffb}, + {0x103001, 0x10303f}, {0x103041, 0x103096}, {0x103099, 0x1030ff}, {0x103105, 0x10312e}, + {0x103131, 0x10318e}, {0x103190, 0x1031ba}, {0x1031c0, 0x1031e3}, {0x1031f0, 0x10321e}, + {0x103220, 0x1032fe}, {0x103300, 0x104db5}, {0x104dc0, 0x109fea}, {0x10a000, 0x10a48c}, + {0x10a490, 0x10a4c6}, {0x10a4d0, 0x10a62b}, {0x10a640, 0x10a6f7}, {0x10a700, 0x10a7ae}, + {0x10a7b0, 0x10a7b7}, {0x10a7f7, 0x10a82b}, {0x10a830, 0x10a839}, {0x10a840, 0x10a877}, + {0x10a880, 0x10a8c5}, {0x10a8ce, 0x10a8d9}, {0x10a8e0, 0x10a8fd}, {0x10a900, 0x10a953}, + {0x10a95f, 0x10a97c}, {0x10a980, 0x10a9cd}, {0x10a9cf, 0x10a9d9}, {0x10a9de, 0x10a9fe}, + {0x10aa00, 0x10aa36}, {0x10aa40, 0x10aa4d}, {0x10aa50, 0x10aa59}, {0x10aa5c, 0x10aac2}, + {0x10aadb, 0x10aaf6}, {0x10ab01, 0x10ab06}, {0x10ab09, 0x10ab0e}, {0x10ab11, 0x10ab16}, + {0x10ab20, 0x10ab26}, {0x10ab28, 0x10ab2e}, {0x10ab30, 0x10ab65}, {0x10ab70, 0x10abed}, + {0x10abf0, 0x10abf9}, {0x10ac00, 0x10d7a3}, {0x10d7b0, 0x10d7c6}, {0x10d7cb, 0x10d7fb}, + {0x10f900, 0x10fa6d}, {0x10fa70, 0x10fad9}, {0x10fb00, 0x10fb06}, {0x10fb13, 0x10fb17}, + {0x10fb1d, 0x10fb36}, {0x10fb38, 0x10fb3c}, {0x10fb46, 0x10fbc1}, {0x10fbd3, 0x10fd3f}, + {0x10fd50, 0x10fd8f}, {0x10fd92, 0x10fdc7}, {0x10fdf0, 0x10fdfd}, {0x10fe00, 0x10fe19}, + {0x10fe20, 0x10fe52}, {0x10fe54, 0x10fe66}, {0x10fe68, 0x10fe6b}, {0x10fe70, 0x10fe74}, + {0x10fe76, 0x10fefc}, {0x10ff01, 0x10ffbe}, {0x10ffc2, 0x10ffc7}, {0x10ffca, 0x10ffcf}, + {0x10ffd2, 0x10ffd7}, {0x10ffda, 0x10ffdc}, {0x10ffe0, 0x10ffe6}, {0x10ffe8, 0x10ffee} #endif }; @@ -755,23 +6176,186 @@ static const chr graphCharTable[] = { 0x38c, 0x589, 0x58a, 0x85e, 0x98f, 0x990, 0x9b2, 0x9c7, 0x9c8, 0x9d7, 0x9dc, 0x9dd, 0xa0f, 0xa10, 0xa32, 0xa33, 0xa35, 0xa36, 0xa38, 0xa39, 0xa3c, 0xa47, 0xa48, 0xa51, 0xa5e, 0xab2, 0xab3, - 0xad0, 0xaf9, 0xb0f, 0xb10, 0xb32, 0xb33, 0xb47, 0xb48, 0xb56, - 0xb57, 0xb5c, 0xb5d, 0xb82, 0xb83, 0xb99, 0xb9a, 0xb9c, 0xb9e, - 0xb9f, 0xba3, 0xba4, 0xbd0, 0xbd7, 0xc55, 0xc56, 0xcd5, 0xcd6, - 0xcde, 0xcf1, 0xcf2, 0xd82, 0xd83, 0xdbd, 0xdca, 0xdd6, 0xe81, - 0xe82, 0xe84, 0xe87, 0xe88, 0xe8a, 0xe8d, 0xea5, 0xea7, 0xeaa, - 0xeab, 0xec6, 0x10c7, 0x10cd, 0x1258, 0x12c0, 0x1772, 0x1773, 0x1940, - 0x1cf8, 0x1cf9, 0x1f59, 0x1f5b, 0x1f5d, 0x2070, 0x2071, 0x2d27, 0x2d2d, - 0x2d6f, 0x2d70, 0xfb3e, 0xfb40, 0xfb41, 0xfb43, 0xfb44, 0xfffc, 0xfffd + 0xad0, 0xb0f, 0xb10, 0xb32, 0xb33, 0xb47, 0xb48, 0xb56, 0xb57, + 0xb5c, 0xb5d, 0xb82, 0xb83, 0xb99, 0xb9a, 0xb9c, 0xb9e, 0xb9f, + 0xba3, 0xba4, 0xbd0, 0xbd7, 0xc55, 0xc56, 0xcd5, 0xcd6, 0xcde, + 0xcf1, 0xcf2, 0xd82, 0xd83, 0xdbd, 0xdca, 0xdd6, 0xe81, 0xe82, + 0xe84, 0xe87, 0xe88, 0xe8a, 0xe8d, 0xea5, 0xea7, 0xeaa, 0xeab, + 0xec6, 0x10c7, 0x10cd, 0x1258, 0x12c0, 0x1772, 0x1773, 0x1940, 0x1f59, + 0x1f5b, 0x1f5d, 0x2070, 0x2071, 0x2d27, 0x2d2d, 0x2d6f, 0x2d70, 0xfb3e, + 0xfb40, 0xfb41, 0xfb43, 0xfb44, 0xfffc, 0xfffd #if TCL_UTF_MAX > 4 - ,0x1003c, 0x1003d, 0x101a0, 0x1056f, 0x10808, 0x10837, 0x10838, 0x1083c, 0x108f4, - 0x108f5, 0x1093f, 0x10a05, 0x10a06, 0x11288, 0x1130f, 0x11310, 0x11332, 0x11333, - 0x11347, 0x11348, 0x11350, 0x11357, 0x1145b, 0x1145d, 0x118ff, 0x16a6e, 0x16a6f, - 0x16fe0, 0x1b000, 0x1b001, 0x1d49e, 0x1d49f, 0x1d4a2, 0x1d4a5, 0x1d4a6, 0x1d4bb, - 0x1d546, 0x1e023, 0x1e024, 0x1e95e, 0x1e95f, 0x1ee21, 0x1ee22, 0x1ee24, 0x1ee27, - 0x1ee39, 0x1ee3b, 0x1ee42, 0x1ee47, 0x1ee49, 0x1ee4b, 0x1ee51, 0x1ee52, 0x1ee54, - 0x1ee57, 0x1ee59, 0x1ee5b, 0x1ee5d, 0x1ee5f, 0x1ee61, 0x1ee62, 0x1ee64, 0x1ee7e, - 0x1eef0, 0x1eef1, 0x1f250, 0x1f251, 0x1f930, 0x1f9c0 + ,0x1038c, 0x10589, 0x1058a, 0x1085e, 0x1098f, 0x10990, 0x109b2, 0x109c7, 0x109c8, + 0x109d7, 0x109dc, 0x109dd, 0x10a0f, 0x10a10, 0x10a32, 0x10a33, 0x10a35, 0x10a36, + 0x10a38, 0x10a39, 0x10a3c, 0x10a47, 0x10a48, 0x10a51, 0x10a5e, 0x10ab2, 0x10ab3, + 0x10ad0, 0x10b0f, 0x10b10, 0x10b32, 0x10b33, 0x10b47, 0x10b48, 0x10b56, 0x10b57, + 0x10b5c, 0x10b5d, 0x10b82, 0x10b83, 0x10b99, 0x10b9a, 0x10b9c, 0x10b9e, 0x10b9f, + 0x10ba3, 0x10ba4, 0x10bd0, 0x10bd7, 0x10c55, 0x10c56, 0x10cd5, 0x10cd6, 0x10cde, + 0x10cf1, 0x10cf2, 0x10d82, 0x10d83, 0x10dbd, 0x10dca, 0x10dd6, 0x10e81, 0x10e82, + 0x10e84, 0x10e87, 0x10e88, 0x10e8a, 0x10e8d, 0x10ea5, 0x10ea7, 0x10eaa, 0x10eab, + 0x10ec6, 0x110c7, 0x110cd, 0x11258, 0x112c0, 0x11772, 0x11773, 0x11940, 0x11f59, + 0x11f5b, 0x11f5d, 0x12070, 0x12071, 0x12d27, 0x12d2d, 0x12d6f, 0x12d70, 0x1fb3e, + 0x1fb40, 0x1fb41, 0x1fb43, 0x1fb44, 0x1fffc, 0x1fffd, 0x2038c, 0x20589, 0x2058a, + 0x2085e, 0x2098f, 0x20990, 0x209b2, 0x209c7, 0x209c8, 0x209d7, 0x209dc, 0x209dd, + 0x20a0f, 0x20a10, 0x20a32, 0x20a33, 0x20a35, 0x20a36, 0x20a38, 0x20a39, 0x20a3c, + 0x20a47, 0x20a48, 0x20a51, 0x20a5e, 0x20ab2, 0x20ab3, 0x20ad0, 0x20b0f, 0x20b10, + 0x20b32, 0x20b33, 0x20b47, 0x20b48, 0x20b56, 0x20b57, 0x20b5c, 0x20b5d, 0x20b82, + 0x20b83, 0x20b99, 0x20b9a, 0x20b9c, 0x20b9e, 0x20b9f, 0x20ba3, 0x20ba4, 0x20bd0, + 0x20bd7, 0x20c55, 0x20c56, 0x20cd5, 0x20cd6, 0x20cde, 0x20cf1, 0x20cf2, 0x20d82, + 0x20d83, 0x20dbd, 0x20dca, 0x20dd6, 0x20e81, 0x20e82, 0x20e84, 0x20e87, 0x20e88, + 0x20e8a, 0x20e8d, 0x20ea5, 0x20ea7, 0x20eaa, 0x20eab, 0x20ec6, 0x210c7, 0x210cd, + 0x21258, 0x212c0, 0x21772, 0x21773, 0x21940, 0x21f59, 0x21f5b, 0x21f5d, 0x22070, + 0x22071, 0x22d27, 0x22d2d, 0x22d6f, 0x22d70, 0x2fb3e, 0x2fb40, 0x2fb41, 0x2fb43, + 0x2fb44, 0x2fffc, 0x2fffd, 0x3038c, 0x30589, 0x3058a, 0x3085e, 0x3098f, 0x30990, + 0x309b2, 0x309c7, 0x309c8, 0x309d7, 0x309dc, 0x309dd, 0x30a0f, 0x30a10, 0x30a32, + 0x30a33, 0x30a35, 0x30a36, 0x30a38, 0x30a39, 0x30a3c, 0x30a47, 0x30a48, 0x30a51, + 0x30a5e, 0x30ab2, 0x30ab3, 0x30ad0, 0x30b0f, 0x30b10, 0x30b32, 0x30b33, 0x30b47, + 0x30b48, 0x30b56, 0x30b57, 0x30b5c, 0x30b5d, 0x30b82, 0x30b83, 0x30b99, 0x30b9a, + 0x30b9c, 0x30b9e, 0x30b9f, 0x30ba3, 0x30ba4, 0x30bd0, 0x30bd7, 0x30c55, 0x30c56, + 0x30cd5, 0x30cd6, 0x30cde, 0x30cf1, 0x30cf2, 0x30d82, 0x30d83, 0x30dbd, 0x30dca, + 0x30dd6, 0x30e81, 0x30e82, 0x30e84, 0x30e87, 0x30e88, 0x30e8a, 0x30e8d, 0x30ea5, + 0x30ea7, 0x30eaa, 0x30eab, 0x30ec6, 0x310c7, 0x310cd, 0x31258, 0x312c0, 0x31772, + 0x31773, 0x31940, 0x31f59, 0x31f5b, 0x31f5d, 0x32070, 0x32071, 0x32d27, 0x32d2d, + 0x32d6f, 0x32d70, 0x3fb3e, 0x3fb40, 0x3fb41, 0x3fb43, 0x3fb44, 0x3fffc, 0x3fffd, + 0x4038c, 0x40589, 0x4058a, 0x4085e, 0x4098f, 0x40990, 0x409b2, 0x409c7, 0x409c8, + 0x409d7, 0x409dc, 0x409dd, 0x40a0f, 0x40a10, 0x40a32, 0x40a33, 0x40a35, 0x40a36, + 0x40a38, 0x40a39, 0x40a3c, 0x40a47, 0x40a48, 0x40a51, 0x40a5e, 0x40ab2, 0x40ab3, + 0x40ad0, 0x40b0f, 0x40b10, 0x40b32, 0x40b33, 0x40b47, 0x40b48, 0x40b56, 0x40b57, + 0x40b5c, 0x40b5d, 0x40b82, 0x40b83, 0x40b99, 0x40b9a, 0x40b9c, 0x40b9e, 0x40b9f, + 0x40ba3, 0x40ba4, 0x40bd0, 0x40bd7, 0x40c55, 0x40c56, 0x40cd5, 0x40cd6, 0x40cde, + 0x40cf1, 0x40cf2, 0x40d82, 0x40d83, 0x40dbd, 0x40dca, 0x40dd6, 0x40e81, 0x40e82, + 0x40e84, 0x40e87, 0x40e88, 0x40e8a, 0x40e8d, 0x40ea5, 0x40ea7, 0x40eaa, 0x40eab, + 0x40ec6, 0x410c7, 0x410cd, 0x41258, 0x412c0, 0x41772, 0x41773, 0x41940, 0x41f59, + 0x41f5b, 0x41f5d, 0x42070, 0x42071, 0x42d27, 0x42d2d, 0x42d6f, 0x42d70, 0x4fb3e, + 0x4fb40, 0x4fb41, 0x4fb43, 0x4fb44, 0x4fffc, 0x4fffd, 0x5038c, 0x50589, 0x5058a, + 0x5085e, 0x5098f, 0x50990, 0x509b2, 0x509c7, 0x509c8, 0x509d7, 0x509dc, 0x509dd, + 0x50a0f, 0x50a10, 0x50a32, 0x50a33, 0x50a35, 0x50a36, 0x50a38, 0x50a39, 0x50a3c, + 0x50a47, 0x50a48, 0x50a51, 0x50a5e, 0x50ab2, 0x50ab3, 0x50ad0, 0x50b0f, 0x50b10, + 0x50b32, 0x50b33, 0x50b47, 0x50b48, 0x50b56, 0x50b57, 0x50b5c, 0x50b5d, 0x50b82, + 0x50b83, 0x50b99, 0x50b9a, 0x50b9c, 0x50b9e, 0x50b9f, 0x50ba3, 0x50ba4, 0x50bd0, + 0x50bd7, 0x50c55, 0x50c56, 0x50cd5, 0x50cd6, 0x50cde, 0x50cf1, 0x50cf2, 0x50d82, + 0x50d83, 0x50dbd, 0x50dca, 0x50dd6, 0x50e81, 0x50e82, 0x50e84, 0x50e87, 0x50e88, + 0x50e8a, 0x50e8d, 0x50ea5, 0x50ea7, 0x50eaa, 0x50eab, 0x50ec6, 0x510c7, 0x510cd, + 0x51258, 0x512c0, 0x51772, 0x51773, 0x51940, 0x51f59, 0x51f5b, 0x51f5d, 0x52070, + 0x52071, 0x52d27, 0x52d2d, 0x52d6f, 0x52d70, 0x5fb3e, 0x5fb40, 0x5fb41, 0x5fb43, + 0x5fb44, 0x5fffc, 0x5fffd, 0x6038c, 0x60589, 0x6058a, 0x6085e, 0x6098f, 0x60990, + 0x609b2, 0x609c7, 0x609c8, 0x609d7, 0x609dc, 0x609dd, 0x60a0f, 0x60a10, 0x60a32, + 0x60a33, 0x60a35, 0x60a36, 0x60a38, 0x60a39, 0x60a3c, 0x60a47, 0x60a48, 0x60a51, + 0x60a5e, 0x60ab2, 0x60ab3, 0x60ad0, 0x60b0f, 0x60b10, 0x60b32, 0x60b33, 0x60b47, + 0x60b48, 0x60b56, 0x60b57, 0x60b5c, 0x60b5d, 0x60b82, 0x60b83, 0x60b99, 0x60b9a, + 0x60b9c, 0x60b9e, 0x60b9f, 0x60ba3, 0x60ba4, 0x60bd0, 0x60bd7, 0x60c55, 0x60c56, + 0x60cd5, 0x60cd6, 0x60cde, 0x60cf1, 0x60cf2, 0x60d82, 0x60d83, 0x60dbd, 0x60dca, + 0x60dd6, 0x60e81, 0x60e82, 0x60e84, 0x60e87, 0x60e88, 0x60e8a, 0x60e8d, 0x60ea5, + 0x60ea7, 0x60eaa, 0x60eab, 0x60ec6, 0x610c7, 0x610cd, 0x61258, 0x612c0, 0x61772, + 0x61773, 0x61940, 0x61f59, 0x61f5b, 0x61f5d, 0x62070, 0x62071, 0x62d27, 0x62d2d, + 0x62d6f, 0x62d70, 0x6fb3e, 0x6fb40, 0x6fb41, 0x6fb43, 0x6fb44, 0x6fffc, 0x6fffd, + 0x7038c, 0x70589, 0x7058a, 0x7085e, 0x7098f, 0x70990, 0x709b2, 0x709c7, 0x709c8, + 0x709d7, 0x709dc, 0x709dd, 0x70a0f, 0x70a10, 0x70a32, 0x70a33, 0x70a35, 0x70a36, + 0x70a38, 0x70a39, 0x70a3c, 0x70a47, 0x70a48, 0x70a51, 0x70a5e, 0x70ab2, 0x70ab3, + 0x70ad0, 0x70b0f, 0x70b10, 0x70b32, 0x70b33, 0x70b47, 0x70b48, 0x70b56, 0x70b57, + 0x70b5c, 0x70b5d, 0x70b82, 0x70b83, 0x70b99, 0x70b9a, 0x70b9c, 0x70b9e, 0x70b9f, + 0x70ba3, 0x70ba4, 0x70bd0, 0x70bd7, 0x70c55, 0x70c56, 0x70cd5, 0x70cd6, 0x70cde, + 0x70cf1, 0x70cf2, 0x70d82, 0x70d83, 0x70dbd, 0x70dca, 0x70dd6, 0x70e81, 0x70e82, + 0x70e84, 0x70e87, 0x70e88, 0x70e8a, 0x70e8d, 0x70ea5, 0x70ea7, 0x70eaa, 0x70eab, + 0x70ec6, 0x710c7, 0x710cd, 0x71258, 0x712c0, 0x71772, 0x71773, 0x71940, 0x71f59, + 0x71f5b, 0x71f5d, 0x72070, 0x72071, 0x72d27, 0x72d2d, 0x72d6f, 0x72d70, 0x7fb3e, + 0x7fb40, 0x7fb41, 0x7fb43, 0x7fb44, 0x7fffc, 0x7fffd, 0x8038c, 0x80589, 0x8058a, + 0x8085e, 0x8098f, 0x80990, 0x809b2, 0x809c7, 0x809c8, 0x809d7, 0x809dc, 0x809dd, + 0x80a0f, 0x80a10, 0x80a32, 0x80a33, 0x80a35, 0x80a36, 0x80a38, 0x80a39, 0x80a3c, + 0x80a47, 0x80a48, 0x80a51, 0x80a5e, 0x80ab2, 0x80ab3, 0x80ad0, 0x80b0f, 0x80b10, + 0x80b32, 0x80b33, 0x80b47, 0x80b48, 0x80b56, 0x80b57, 0x80b5c, 0x80b5d, 0x80b82, + 0x80b83, 0x80b99, 0x80b9a, 0x80b9c, 0x80b9e, 0x80b9f, 0x80ba3, 0x80ba4, 0x80bd0, + 0x80bd7, 0x80c55, 0x80c56, 0x80cd5, 0x80cd6, 0x80cde, 0x80cf1, 0x80cf2, 0x80d82, + 0x80d83, 0x80dbd, 0x80dca, 0x80dd6, 0x80e81, 0x80e82, 0x80e84, 0x80e87, 0x80e88, + 0x80e8a, 0x80e8d, 0x80ea5, 0x80ea7, 0x80eaa, 0x80eab, 0x80ec6, 0x810c7, 0x810cd, + 0x81258, 0x812c0, 0x81772, 0x81773, 0x81940, 0x81f59, 0x81f5b, 0x81f5d, 0x82070, + 0x82071, 0x82d27, 0x82d2d, 0x82d6f, 0x82d70, 0x8fb3e, 0x8fb40, 0x8fb41, 0x8fb43, + 0x8fb44, 0x8fffc, 0x8fffd, 0x9038c, 0x90589, 0x9058a, 0x9085e, 0x9098f, 0x90990, + 0x909b2, 0x909c7, 0x909c8, 0x909d7, 0x909dc, 0x909dd, 0x90a0f, 0x90a10, 0x90a32, + 0x90a33, 0x90a35, 0x90a36, 0x90a38, 0x90a39, 0x90a3c, 0x90a47, 0x90a48, 0x90a51, + 0x90a5e, 0x90ab2, 0x90ab3, 0x90ad0, 0x90b0f, 0x90b10, 0x90b32, 0x90b33, 0x90b47, + 0x90b48, 0x90b56, 0x90b57, 0x90b5c, 0x90b5d, 0x90b82, 0x90b83, 0x90b99, 0x90b9a, + 0x90b9c, 0x90b9e, 0x90b9f, 0x90ba3, 0x90ba4, 0x90bd0, 0x90bd7, 0x90c55, 0x90c56, + 0x90cd5, 0x90cd6, 0x90cde, 0x90cf1, 0x90cf2, 0x90d82, 0x90d83, 0x90dbd, 0x90dca, + 0x90dd6, 0x90e81, 0x90e82, 0x90e84, 0x90e87, 0x90e88, 0x90e8a, 0x90e8d, 0x90ea5, + 0x90ea7, 0x90eaa, 0x90eab, 0x90ec6, 0x910c7, 0x910cd, 0x91258, 0x912c0, 0x91772, + 0x91773, 0x91940, 0x91f59, 0x91f5b, 0x91f5d, 0x92070, 0x92071, 0x92d27, 0x92d2d, + 0x92d6f, 0x92d70, 0x9fb3e, 0x9fb40, 0x9fb41, 0x9fb43, 0x9fb44, 0x9fffc, 0x9fffd, + 0xa038c, 0xa0589, 0xa058a, 0xa085e, 0xa098f, 0xa0990, 0xa09b2, 0xa09c7, 0xa09c8, + 0xa09d7, 0xa09dc, 0xa09dd, 0xa0a0f, 0xa0a10, 0xa0a32, 0xa0a33, 0xa0a35, 0xa0a36, + 0xa0a38, 0xa0a39, 0xa0a3c, 0xa0a47, 0xa0a48, 0xa0a51, 0xa0a5e, 0xa0ab2, 0xa0ab3, + 0xa0ad0, 0xa0b0f, 0xa0b10, 0xa0b32, 0xa0b33, 0xa0b47, 0xa0b48, 0xa0b56, 0xa0b57, + 0xa0b5c, 0xa0b5d, 0xa0b82, 0xa0b83, 0xa0b99, 0xa0b9a, 0xa0b9c, 0xa0b9e, 0xa0b9f, + 0xa0ba3, 0xa0ba4, 0xa0bd0, 0xa0bd7, 0xa0c55, 0xa0c56, 0xa0cd5, 0xa0cd6, 0xa0cde, + 0xa0cf1, 0xa0cf2, 0xa0d82, 0xa0d83, 0xa0dbd, 0xa0dca, 0xa0dd6, 0xa0e81, 0xa0e82, + 0xa0e84, 0xa0e87, 0xa0e88, 0xa0e8a, 0xa0e8d, 0xa0ea5, 0xa0ea7, 0xa0eaa, 0xa0eab, + 0xa0ec6, 0xa10c7, 0xa10cd, 0xa1258, 0xa12c0, 0xa1772, 0xa1773, 0xa1940, 0xa1f59, + 0xa1f5b, 0xa1f5d, 0xa2070, 0xa2071, 0xa2d27, 0xa2d2d, 0xa2d6f, 0xa2d70, 0xafb3e, + 0xafb40, 0xafb41, 0xafb43, 0xafb44, 0xafffc, 0xafffd, 0xb038c, 0xb0589, 0xb058a, + 0xb085e, 0xb098f, 0xb0990, 0xb09b2, 0xb09c7, 0xb09c8, 0xb09d7, 0xb09dc, 0xb09dd, + 0xb0a0f, 0xb0a10, 0xb0a32, 0xb0a33, 0xb0a35, 0xb0a36, 0xb0a38, 0xb0a39, 0xb0a3c, + 0xb0a47, 0xb0a48, 0xb0a51, 0xb0a5e, 0xb0ab2, 0xb0ab3, 0xb0ad0, 0xb0b0f, 0xb0b10, + 0xb0b32, 0xb0b33, 0xb0b47, 0xb0b48, 0xb0b56, 0xb0b57, 0xb0b5c, 0xb0b5d, 0xb0b82, + 0xb0b83, 0xb0b99, 0xb0b9a, 0xb0b9c, 0xb0b9e, 0xb0b9f, 0xb0ba3, 0xb0ba4, 0xb0bd0, + 0xb0bd7, 0xb0c55, 0xb0c56, 0xb0cd5, 0xb0cd6, 0xb0cde, 0xb0cf1, 0xb0cf2, 0xb0d82, + 0xb0d83, 0xb0dbd, 0xb0dca, 0xb0dd6, 0xb0e81, 0xb0e82, 0xb0e84, 0xb0e87, 0xb0e88, + 0xb0e8a, 0xb0e8d, 0xb0ea5, 0xb0ea7, 0xb0eaa, 0xb0eab, 0xb0ec6, 0xb10c7, 0xb10cd, + 0xb1258, 0xb12c0, 0xb1772, 0xb1773, 0xb1940, 0xb1f59, 0xb1f5b, 0xb1f5d, 0xb2070, + 0xb2071, 0xb2d27, 0xb2d2d, 0xb2d6f, 0xb2d70, 0xbfb3e, 0xbfb40, 0xbfb41, 0xbfb43, + 0xbfb44, 0xbfffc, 0xbfffd, 0xc038c, 0xc0589, 0xc058a, 0xc085e, 0xc098f, 0xc0990, + 0xc09b2, 0xc09c7, 0xc09c8, 0xc09d7, 0xc09dc, 0xc09dd, 0xc0a0f, 0xc0a10, 0xc0a32, + 0xc0a33, 0xc0a35, 0xc0a36, 0xc0a38, 0xc0a39, 0xc0a3c, 0xc0a47, 0xc0a48, 0xc0a51, + 0xc0a5e, 0xc0ab2, 0xc0ab3, 0xc0ad0, 0xc0b0f, 0xc0b10, 0xc0b32, 0xc0b33, 0xc0b47, + 0xc0b48, 0xc0b56, 0xc0b57, 0xc0b5c, 0xc0b5d, 0xc0b82, 0xc0b83, 0xc0b99, 0xc0b9a, + 0xc0b9c, 0xc0b9e, 0xc0b9f, 0xc0ba3, 0xc0ba4, 0xc0bd0, 0xc0bd7, 0xc0c55, 0xc0c56, + 0xc0cd5, 0xc0cd6, 0xc0cde, 0xc0cf1, 0xc0cf2, 0xc0d82, 0xc0d83, 0xc0dbd, 0xc0dca, + 0xc0dd6, 0xc0e81, 0xc0e82, 0xc0e84, 0xc0e87, 0xc0e88, 0xc0e8a, 0xc0e8d, 0xc0ea5, + 0xc0ea7, 0xc0eaa, 0xc0eab, 0xc0ec6, 0xc10c7, 0xc10cd, 0xc1258, 0xc12c0, 0xc1772, + 0xc1773, 0xc1940, 0xc1f59, 0xc1f5b, 0xc1f5d, 0xc2070, 0xc2071, 0xc2d27, 0xc2d2d, + 0xc2d6f, 0xc2d70, 0xcfb3e, 0xcfb40, 0xcfb41, 0xcfb43, 0xcfb44, 0xcfffc, 0xcfffd, + 0xd038c, 0xd0589, 0xd058a, 0xd085e, 0xd098f, 0xd0990, 0xd09b2, 0xd09c7, 0xd09c8, + 0xd09d7, 0xd09dc, 0xd09dd, 0xd0a0f, 0xd0a10, 0xd0a32, 0xd0a33, 0xd0a35, 0xd0a36, + 0xd0a38, 0xd0a39, 0xd0a3c, 0xd0a47, 0xd0a48, 0xd0a51, 0xd0a5e, 0xd0ab2, 0xd0ab3, + 0xd0ad0, 0xd0b0f, 0xd0b10, 0xd0b32, 0xd0b33, 0xd0b47, 0xd0b48, 0xd0b56, 0xd0b57, + 0xd0b5c, 0xd0b5d, 0xd0b82, 0xd0b83, 0xd0b99, 0xd0b9a, 0xd0b9c, 0xd0b9e, 0xd0b9f, + 0xd0ba3, 0xd0ba4, 0xd0bd0, 0xd0bd7, 0xd0c55, 0xd0c56, 0xd0cd5, 0xd0cd6, 0xd0cde, + 0xd0cf1, 0xd0cf2, 0xd0d82, 0xd0d83, 0xd0dbd, 0xd0dca, 0xd0dd6, 0xd0e81, 0xd0e82, + 0xd0e84, 0xd0e87, 0xd0e88, 0xd0e8a, 0xd0e8d, 0xd0ea5, 0xd0ea7, 0xd0eaa, 0xd0eab, + 0xd0ec6, 0xd10c7, 0xd10cd, 0xd1258, 0xd12c0, 0xd1772, 0xd1773, 0xd1940, 0xd1f59, + 0xd1f5b, 0xd1f5d, 0xd2070, 0xd2071, 0xd2d27, 0xd2d2d, 0xd2d6f, 0xd2d70, 0xdfb3e, + 0xdfb40, 0xdfb41, 0xdfb43, 0xdfb44, 0xdfffc, 0xdfffd, 0xe038c, 0xe0589, 0xe058a, + 0xe085e, 0xe098f, 0xe0990, 0xe09b2, 0xe09c7, 0xe09c8, 0xe09d7, 0xe09dc, 0xe09dd, + 0xe0a0f, 0xe0a10, 0xe0a32, 0xe0a33, 0xe0a35, 0xe0a36, 0xe0a38, 0xe0a39, 0xe0a3c, + 0xe0a47, 0xe0a48, 0xe0a51, 0xe0a5e, 0xe0ab2, 0xe0ab3, 0xe0ad0, 0xe0b0f, 0xe0b10, + 0xe0b32, 0xe0b33, 0xe0b47, 0xe0b48, 0xe0b56, 0xe0b57, 0xe0b5c, 0xe0b5d, 0xe0b82, + 0xe0b83, 0xe0b99, 0xe0b9a, 0xe0b9c, 0xe0b9e, 0xe0b9f, 0xe0ba3, 0xe0ba4, 0xe0bd0, + 0xe0bd7, 0xe0c55, 0xe0c56, 0xe0cd5, 0xe0cd6, 0xe0cde, 0xe0cf1, 0xe0cf2, 0xe0d82, + 0xe0d83, 0xe0dbd, 0xe0dca, 0xe0dd6, 0xe0e81, 0xe0e82, 0xe0e84, 0xe0e87, 0xe0e88, + 0xe0e8a, 0xe0e8d, 0xe0ea5, 0xe0ea7, 0xe0eaa, 0xe0eab, 0xe0ec6, 0xe10c7, 0xe10cd, + 0xe1258, 0xe12c0, 0xe1772, 0xe1773, 0xe1940, 0xe1f59, 0xe1f5b, 0xe1f5d, 0xe2070, + 0xe2071, 0xe2d27, 0xe2d2d, 0xe2d6f, 0xe2d70, 0xefb3e, 0xefb40, 0xefb41, 0xefb43, + 0xefb44, 0xefffc, 0xefffd, 0xf038c, 0xf0589, 0xf058a, 0xf085e, 0xf098f, 0xf0990, + 0xf09b2, 0xf09c7, 0xf09c8, 0xf09d7, 0xf09dc, 0xf09dd, 0xf0a0f, 0xf0a10, 0xf0a32, + 0xf0a33, 0xf0a35, 0xf0a36, 0xf0a38, 0xf0a39, 0xf0a3c, 0xf0a47, 0xf0a48, 0xf0a51, + 0xf0a5e, 0xf0ab2, 0xf0ab3, 0xf0ad0, 0xf0b0f, 0xf0b10, 0xf0b32, 0xf0b33, 0xf0b47, + 0xf0b48, 0xf0b56, 0xf0b57, 0xf0b5c, 0xf0b5d, 0xf0b82, 0xf0b83, 0xf0b99, 0xf0b9a, + 0xf0b9c, 0xf0b9e, 0xf0b9f, 0xf0ba3, 0xf0ba4, 0xf0bd0, 0xf0bd7, 0xf0c55, 0xf0c56, + 0xf0cd5, 0xf0cd6, 0xf0cde, 0xf0cf1, 0xf0cf2, 0xf0d82, 0xf0d83, 0xf0dbd, 0xf0dca, + 0xf0dd6, 0xf0e81, 0xf0e82, 0xf0e84, 0xf0e87, 0xf0e88, 0xf0e8a, 0xf0e8d, 0xf0ea5, + 0xf0ea7, 0xf0eaa, 0xf0eab, 0xf0ec6, 0xf10c7, 0xf10cd, 0xf1258, 0xf12c0, 0xf1772, + 0xf1773, 0xf1940, 0xf1f59, 0xf1f5b, 0xf1f5d, 0xf2070, 0xf2071, 0xf2d27, 0xf2d2d, + 0xf2d6f, 0xf2d70, 0xffb3e, 0xffb40, 0xffb41, 0xffb43, 0xffb44, 0xffffc, 0xffffd, + 0x10038c, 0x100589, 0x10058a, 0x10085e, 0x10098f, 0x100990, 0x1009b2, 0x1009c7, 0x1009c8, + 0x1009d7, 0x1009dc, 0x1009dd, 0x100a0f, 0x100a10, 0x100a32, 0x100a33, 0x100a35, 0x100a36, + 0x100a38, 0x100a39, 0x100a3c, 0x100a47, 0x100a48, 0x100a51, 0x100a5e, 0x100ab2, 0x100ab3, + 0x100ad0, 0x100b0f, 0x100b10, 0x100b32, 0x100b33, 0x100b47, 0x100b48, 0x100b56, 0x100b57, + 0x100b5c, 0x100b5d, 0x100b82, 0x100b83, 0x100b99, 0x100b9a, 0x100b9c, 0x100b9e, 0x100b9f, + 0x100ba3, 0x100ba4, 0x100bd0, 0x100bd7, 0x100c55, 0x100c56, 0x100cd5, 0x100cd6, 0x100cde, + 0x100cf1, 0x100cf2, 0x100d82, 0x100d83, 0x100dbd, 0x100dca, 0x100dd6, 0x100e81, 0x100e82, + 0x100e84, 0x100e87, 0x100e88, 0x100e8a, 0x100e8d, 0x100ea5, 0x100ea7, 0x100eaa, 0x100eab, + 0x100ec6, 0x1010c7, 0x1010cd, 0x101258, 0x1012c0, 0x101772, 0x101773, 0x101940, 0x101f59, + 0x101f5b, 0x101f5d, 0x102070, 0x102071, 0x102d27, 0x102d2d, 0x102d6f, 0x102d70, 0x10fb3e, + 0x10fb40, 0x10fb41, 0x10fb43, 0x10fb44, 0x10fffc, 0x10fffd #endif }; diff --git a/generic/tclUniData.c b/generic/tclUniData.c index d8b317a..9f05230 100644 --- a/generic/tclUniData.c +++ b/generic/tclUniData.c @@ -29,36 +29,36 @@ static const unsigned short pageMap[] = { 832, 864, 896, 928, 960, 992, 224, 1024, 224, 1056, 224, 224, 1088, 1120, 1152, 1184, 1216, 1248, 1280, 1312, 1344, 1376, 1408, 1344, 1344, 1440, 1472, 1504, 1536, 1568, 1344, 1344, 1600, 1632, 1664, 1696, 1728, - 1760, 1792, 1792, 1824, 1856, 1888, 1920, 1952, 1984, 2016, 2048, 2080, - 2112, 2144, 2176, 2208, 2240, 2272, 2304, 2336, 2368, 2400, 2432, 2464, - 2496, 2528, 2560, 2592, 2624, 2656, 2688, 2720, 2752, 2784, 2816, 2848, - 2880, 2912, 2944, 2976, 3008, 3040, 3072, 3104, 3136, 3168, 3200, 3232, - 3264, 1792, 3296, 3328, 3360, 1792, 3392, 3424, 3456, 3488, 3520, 3552, - 3584, 1792, 1344, 3616, 3648, 3680, 3712, 3744, 3776, 3808, 1344, 1344, - 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 3840, 1344, 3872, 3904, - 3936, 1344, 3968, 1344, 4000, 4032, 4064, 4096, 4096, 4128, 4160, 1344, + 1760, 1792, 1824, 1856, 1888, 1920, 1952, 1984, 2016, 2048, 2080, 2112, + 2144, 2176, 2208, 2240, 2272, 2304, 2336, 2368, 2400, 2432, 2464, 2496, + 2528, 2560, 2592, 2624, 2656, 2688, 2720, 2752, 2784, 2816, 2848, 2880, + 2912, 2944, 2976, 3008, 3040, 3072, 3104, 3136, 3168, 3200, 3232, 3264, + 3296, 1824, 3328, 3360, 3392, 1824, 3424, 3456, 3488, 3520, 3552, 3584, + 3616, 1824, 1344, 3648, 3680, 3712, 3744, 3776, 3808, 3840, 1344, 1344, + 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 3872, 1344, 3904, 3936, + 3968, 1344, 4000, 1344, 4032, 4064, 4096, 4128, 4128, 4160, 4192, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, - 1344, 1344, 1344, 1344, 1344, 4192, 4224, 1344, 1344, 4256, 4288, 4320, - 4352, 4384, 1344, 4416, 4448, 4480, 4512, 1344, 4544, 4576, 4608, 4640, - 1344, 4672, 4704, 4736, 4768, 4800, 1344, 4832, 4864, 4896, 4928, 1344, - 4960, 4992, 5024, 5056, 1792, 1792, 5088, 5120, 5152, 5184, 5216, 5248, - 1344, 5280, 1344, 5312, 5344, 5376, 5408, 1792, 5440, 5472, 5504, 5536, - 5568, 5600, 5632, 5568, 704, 5664, 224, 224, 224, 224, 5696, 224, 224, - 224, 5728, 5760, 5792, 5824, 5856, 5888, 5920, 5952, 5984, 6016, 6048, - 6080, 6112, 6144, 6176, 6208, 6240, 6272, 6304, 6336, 6368, 6400, 6432, - 6464, 6496, 6496, 6496, 6496, 6496, 6496, 6496, 6496, 6528, 6560, 4896, - 6592, 6624, 6656, 6688, 6720, 4896, 6752, 6784, 6816, 6848, 6880, 6912, - 6944, 4896, 4896, 4896, 4896, 4896, 6976, 7008, 7040, 4896, 4896, 4896, - 7072, 4896, 4896, 4896, 4896, 4896, 4896, 4896, 7104, 7136, 4896, 7168, - 7200, 4896, 4896, 4896, 4896, 4896, 4896, 4896, 4896, 6496, 6496, 6496, - 6496, 7232, 6496, 7264, 7296, 6496, 6496, 6496, 6496, 6496, 6496, 6496, - 6496, 4896, 7328, 7360, 7392, 7424, 7456, 7488, 7520, 7552, 7584, 7616, - 7648, 224, 224, 224, 7680, 7712, 7744, 1344, 7776, 7808, 7840, 7840, - 704, 7872, 7904, 7936, 1792, 7968, 4896, 4896, 8000, 4896, 4896, 4896, - 4896, 4896, 4896, 8032, 8064, 8096, 8128, 3200, 1344, 8160, 4160, 1344, - 8192, 8224, 8256, 1344, 1344, 8288, 8320, 4896, 8352, 8384, 8416, 8448, - 4896, 8416, 8480, 4896, 8384, 4896, 4896, 4896, 4896, 4896, 4896, 4896, - 4896, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, + 1344, 1344, 1344, 1344, 1344, 4224, 4256, 1344, 1344, 4288, 4320, 4352, + 4384, 4416, 1344, 4448, 4480, 4512, 4544, 1344, 4576, 4608, 4640, 4672, + 1344, 4704, 4736, 4768, 4800, 4832, 1344, 4864, 4896, 4928, 4960, 1344, + 4992, 5024, 5056, 5088, 1824, 1824, 5120, 5152, 5184, 5216, 5248, 5280, + 1344, 5312, 1344, 5344, 5376, 5408, 5440, 1824, 5472, 5504, 5536, 5568, + 5600, 5632, 5664, 5600, 704, 5696, 224, 224, 224, 224, 5728, 224, 224, + 224, 5760, 5792, 5824, 5856, 5888, 5920, 5952, 5984, 6016, 6048, 6080, + 6112, 6144, 6176, 6208, 6240, 6272, 6304, 6336, 6368, 6400, 6432, 6464, + 6496, 6528, 6528, 6528, 6528, 6528, 6528, 6528, 6528, 6560, 6592, 4928, + 6624, 6656, 6688, 6720, 6752, 4928, 6784, 6816, 6848, 6880, 6912, 6944, + 6976, 4928, 4928, 4928, 4928, 4928, 7008, 7040, 7072, 4928, 4928, 4928, + 7104, 4928, 4928, 4928, 4928, 4928, 4928, 4928, 7136, 7168, 4928, 7200, + 7232, 4928, 4928, 4928, 4928, 4928, 4928, 4928, 4928, 6528, 6528, 6528, + 6528, 7264, 6528, 7296, 7328, 6528, 6528, 6528, 6528, 6528, 6528, 6528, + 6528, 4928, 7360, 7392, 7424, 7456, 7488, 7520, 7552, 7584, 7616, 7648, + 7680, 224, 224, 224, 7712, 7744, 7776, 1344, 7808, 7840, 7872, 7872, + 704, 7904, 7936, 7968, 1824, 8000, 4928, 4928, 8032, 4928, 4928, 4928, + 4928, 4928, 4928, 8064, 8096, 8128, 8160, 3232, 1344, 8192, 4192, 1344, + 8224, 8256, 8288, 1344, 1344, 8320, 8352, 4928, 8384, 8416, 8448, 8480, + 4928, 8448, 8512, 4928, 8416, 4928, 4928, 4928, 4928, 4928, 4928, 4928, + 4928, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, @@ -75,7 +75,7 @@ static const unsigned short pageMap[] = { 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, - 1344, 1344, 4672, 4896, 4896, 1344, 1344, 1344, 1344, 1344, 1344, 1344, + 1344, 1344, 4704, 4928, 4928, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, @@ -129,17 +129,16 @@ static const unsigned short pageMap[] = { 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, - 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 4672, - 1792, 8512, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, + 1792, 8544, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, - 1344, 8544, 4896, 8576, 5376, 1344, 1344, 1344, 1344, 1344, 1344, 1344, - 1344, 8608, 8640, 224, 8672, 8704, 1344, 1344, 8736, 8768, 8800, 224, - 8832, 8864, 8896, 1792, 8928, 8960, 8992, 1344, 9024, 9056, 9088, 9120, - 9152, 1632, 9184, 9216, 9248, 1920, 9280, 9312, 9344, 1344, 9376, 9408, - 9440, 1344, 9472, 9504, 9536, 9568, 9600, 9632, 9664, 9696, 9696, 1344, - 9728, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, + 1344, 8576, 4928, 8608, 5408, 1344, 1344, 1344, 1344, 1344, 1344, 1344, + 1344, 8640, 8672, 224, 8704, 8736, 1344, 1344, 8768, 8800, 8832, 224, + 8864, 8896, 8928, 1824, 8960, 8992, 9024, 1344, 9056, 9088, 9120, 9152, + 9184, 1632, 9216, 9248, 9280, 1952, 9312, 9344, 9376, 1344, 9408, 9440, + 9472, 1344, 9504, 9536, 9568, 9600, 9632, 9664, 9696, 9728, 9728, 1344, + 9760, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, @@ -167,211 +166,216 @@ static const unsigned short pageMap[] = { 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, - 1344, 1344, 9760, 9792, 9824, 9856, 9856, 9856, 9856, 9856, 9856, 9856, - 9856, 9856, 9856, 9856, 9856, 9856, 9856, 9856, 9856, 9856, 9856, 9856, - 9856, 9856, 9856, 9856, 9856, 9856, 9856, 9856, 9856, 9856, 9856, 9856, - 9856, 9856, 9856, 9856, 9856, 9856, 9856, 9856, 9856, 9856, 9856, 9856, - 9856, 9856, 9856, 9856, 9856, 9856, 9856, 9856, 9856, 9856, 9856, 9856, - 9856, 9856, 9856, 9856, 9856, 9856, 9856, 9856, 9856, 9888, 9888, 9888, - 9888, 9888, 9888, 9888, 9888, 9888, 9888, 9888, 9888, 9888, 9888, 9888, - 9888, 9888, 9888, 9888, 9888, 9888, 9888, 9888, 9888, 9888, 9888, 9888, - 9888, 9888, 9888, 9888, 9888, 9888, 9888, 9888, 9888, 9888, 9888, 9888, - 9888, 9888, 9888, 9888, 9888, 9888, 9888, 9888, 9888, 9888, 9888, 9888, - 9888, 9888, 9888, 9888, 9888, 9888, 9888, 9888, 9888, 9888, 9888, 9888, - 9888, 9888, 9888, 9888, 9888, 9888, 9888, 9888, 9888, 9888, 9888, 9888, - 9888, 9888, 9888, 9888, 9888, 9888, 9888, 9888, 9888, 9888, 9888, 9888, - 9888, 9888, 9888, 9888, 9888, 9888, 9888, 9888, 9888, 9888, 9888, 9888, - 9888, 9888, 9888, 9888, 9888, 9888, 9888, 9888, 9888, 9888, 9888, 9888, - 9888, 9888, 9888, 9888, 9888, 9888, 9888, 9888, 9888, 9888, 9888, 9888, - 9888, 9888, 9888, 9888, 9888, 9888, 9888, 9888, 9888, 9888, 9888, 9888, - 9888, 9888, 9888, 9888, 9888, 9888, 9888, 9888, 9888, 9888, 9888, 9888, + 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, + 1344, 1344, 9792, 9824, 9856, 9888, 9888, 9888, 9888, 9888, 9888, 9888, 9888, 9888, 9888, 9888, 9888, 9888, 9888, 9888, 9888, 9888, 9888, 9888, 9888, 9888, 9888, 9888, 9888, 9888, 9888, 9888, 9888, 9888, 9888, 9888, 9888, 9888, 9888, 9888, 9888, 9888, 9888, 9888, 9888, 9888, 9888, 9888, 9888, 9888, 9888, 9888, 9888, 9888, 9888, 9888, 9888, 9888, 9888, 9888, - 9888, 9888, 9888, 9888, 9888, 1344, 1344, 1344, 1344, 1344, 1344, 1344, - 1344, 1344, 1344, 1344, 9920, 1344, 1344, 9952, 1792, 9984, 10016, - 10048, 1344, 1344, 10080, 10112, 1344, 1344, 1344, 1344, 1344, 1344, - 1344, 1344, 1344, 1344, 10144, 10176, 1344, 10208, 1344, 10240, 10272, - 10304, 10336, 10368, 10400, 1344, 1344, 1344, 10432, 10464, 64, 10496, - 10528, 10560, 4704, 10592, 10624 + 9888, 9888, 9888, 9888, 9888, 9888, 9888, 9888, 9888, 9920, 9920, 9920, + 9920, 9920, 9920, 9920, 9920, 9920, 9920, 9920, 9920, 9920, 9920, 9920, + 9920, 9920, 9920, 9920, 9920, 9920, 9920, 9920, 9920, 9920, 9920, 9920, + 9920, 9920, 9920, 9920, 9920, 9920, 9920, 9920, 9920, 9920, 9920, 9920, + 9920, 9920, 9920, 9920, 9920, 9920, 9920, 9920, 9920, 9920, 9920, 9920, + 9920, 9920, 9920, 9920, 9920, 9920, 9920, 9920, 9920, 9920, 9920, 9920, + 9920, 9920, 9920, 9920, 9920, 9920, 9920, 9920, 9920, 9920, 9920, 9920, + 9920, 9920, 9920, 9920, 9920, 9920, 9920, 9920, 9920, 9920, 9920, 9920, + 9920, 9920, 9920, 9920, 9920, 9920, 9920, 9920, 9920, 9920, 9920, 9920, + 9920, 9920, 9920, 9920, 9920, 9920, 9920, 9920, 9920, 9920, 9920, 9920, + 9920, 9920, 9920, 9920, 9920, 9920, 9920, 9920, 9920, 9920, 9920, 9920, + 9920, 9920, 9920, 9920, 9920, 9920, 9920, 9920, 9920, 9920, 9920, 9920, + 9920, 9920, 9920, 9920, 9920, 9920, 9920, 9920, 9920, 9920, 9920, 9920, + 9920, 9920, 9920, 9920, 9920, 9920, 9920, 9920, 9920, 9920, 9920, 9920, + 9920, 9920, 9920, 9920, 9920, 9920, 9920, 9920, 9920, 9920, 9920, 9920, + 9920, 9920, 9920, 9920, 9920, 9920, 9920, 9920, 9920, 9920, 9920, 9920, + 9920, 9920, 9920, 9920, 9920, 9920, 9920, 9920, 9920, 9920, 9920, 9920, + 9920, 9920, 9920, 9920, 9920, 1344, 1344, 1344, 1344, 1344, 1344, 1344, + 1344, 1344, 1344, 1344, 9952, 1344, 1344, 9984, 1824, 10016, 10048, + 10080, 1344, 1344, 10112, 10144, 1344, 1344, 1344, 1344, 1344, 1344, + 1344, 1344, 1344, 1344, 10176, 10208, 1344, 10240, 1344, 10272, 10304, + 10336, 10368, 10400, 10432, 1344, 1344, 1344, 10464, 10496, 64, 10528, + 10560, 10592, 4736, 10624, 10656 #if TCL_UTF_MAX > 3 - ,10656, 10688, 10720, 1792, 1344, 1344, 1344, 8320, 10752, 10784, 10816, - 10848, 10880, 10912, 10944, 10976, 1792, 1792, 1792, 1792, 9248, 1344, - 11008, 11040, 1344, 11072, 11104, 11136, 11168, 1344, 11200, 1792, - 11232, 11264, 11296, 1344, 11328, 11360, 11392, 11424, 1344, 11456, - 1344, 11488, 1792, 1792, 1792, 1792, 1344, 1344, 1344, 1344, 1344, - 1344, 1344, 1344, 1344, 7808, 4672, 10240, 1792, 1792, 1792, 1792, - 11520, 11552, 11584, 11616, 4704, 11648, 1792, 11680, 11712, 11744, - 1792, 1792, 1344, 11776, 11808, 6816, 11840, 11872, 11904, 11936, 11968, - 1792, 12000, 12032, 1344, 12064, 12096, 12128, 12160, 12192, 1792, - 1792, 1344, 1344, 12224, 1792, 12256, 12288, 12320, 12352, 1792, 1792, - 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 12384, 1792, - 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 12416, - 12448, 12480, 12512, 5216, 12544, 12576, 12608, 12640, 12672, 12704, - 12736, 5216, 12768, 12800, 12832, 12864, 12896, 1792, 1792, 12928, - 12960, 12992, 13024, 13056, 2336, 13088, 13120, 1792, 1792, 1792, 1792, - 1344, 13152, 13184, 1792, 1344, 13216, 13248, 1792, 1792, 1792, 1792, - 1792, 1344, 13280, 13312, 1792, 1344, 13344, 13376, 13408, 1344, 13440, - 13472, 1792, 13504, 13536, 1792, 1792, 1792, 1792, 1792, 1792, 1792, - 1792, 1792, 1792, 1792, 13568, 13600, 13632, 1792, 1792, 1792, 1792, - 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1344, 13664, - 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 13696, 13728, 13760, - 13792, 13824, 13856, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, - 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, - 1792, 1792, 1792, 1792, 1792, 1792, 1344, 1344, 1344, 1344, 1344, 1344, - 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, - 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 9952, 1792, - 1792, 1792, 10816, 10816, 10816, 13888, 1344, 1344, 1344, 1344, 1344, - 1344, 13920, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, - 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, - 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, - 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, - 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, - 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, - 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, - 1792, 1792, 1792, 1792, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, - 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, - 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, - 1344, 13952, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, - 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, - 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, - 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, - 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, - 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, - 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, - 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, - 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, - 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, - 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1344, 1344, 1344, - 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, - 1344, 1344, 1344, 13984, 1792, 1792, 1792, 1792, 1792, 1792, 1792, - 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, - 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, - 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, - 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, - 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, - 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, - 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, - 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, - 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, - 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, - 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, - 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, - 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, - 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, - 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, - 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, - 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, - 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, - 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, - 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, - 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, - 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1344, 1344, - 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, - 1344, 1344, 1344, 13664, 4704, 14016, 1792, 1792, 10176, 14048, 1344, - 14080, 14112, 14144, 14176, 1792, 1792, 1792, 1792, 1792, 1792, 1792, - 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, - 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1344, 1344, 14208, - 14240, 14272, 1792, 1792, 14304, 1344, 1344, 1344, 1344, 1344, 1344, - 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, - 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, - 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, - 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, - 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, - 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, - 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, - 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, - 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, - 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, - 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, - 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, - 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, - 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, - 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, - 1344, 1344, 1344, 1344, 1344, 14336, 1344, 1344, 1344, 1344, 1344, - 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, - 1344, 1344, 1344, 1344, 1344, 1344, 14368, 1792, 1792, 1792, 1792, - 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, - 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, - 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, - 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, - 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, - 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, - 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, - 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, - 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, - 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, - 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, - 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, - 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, - 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, - 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, - 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, - 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, - 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, - 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, - 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, - 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, - 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, - 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, - 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, - 1792, 1792, 1792, 1792, 14400, 1792, 1792, 1792, 1792, 1792, 1792, - 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, - 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, - 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, - 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, - 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, - 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, - 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, - 1792, 1792, 1792, 1792, 1792, 1344, 1344, 1344, 14432, 14464, 14496, - 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, - 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, - 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, - 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, - 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, - 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, - 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, - 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, - 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, - 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, - 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, - 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, - 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 4896, 4896, - 4896, 4896, 4896, 4896, 4896, 8032, 4896, 14528, 4896, 14560, 14592, - 14624, 4896, 14656, 4896, 4896, 14688, 1792, 1792, 1792, 1792, 1792, - 4896, 4896, 14720, 14752, 1792, 1792, 1792, 1792, 14784, 14816, 14848, - 14880, 14912, 14944, 14976, 15008, 15040, 15072, 15104, 15136, 15168, - 14784, 14816, 15200, 14880, 15232, 15264, 15296, 15008, 15328, 15360, - 15392, 15424, 15456, 15488, 15520, 15552, 15584, 15616, 15648, 4896, - 4896, 4896, 4896, 4896, 4896, 4896, 4896, 4896, 4896, 4896, 4896, 4896, - 4896, 4896, 4896, 704, 15680, 704, 15712, 15744, 15776, 1792, 1792, - 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, - 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, - 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, - 1792, 1792, 1792, 1792, 15808, 15840, 1792, 1792, 1792, 1792, 1792, - 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, - 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, - 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, - 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, - 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1344, 1344, 1344, - 1344, 1344, 1344, 15872, 1792, 15904, 15936, 15968, 1792, 1792, 1792, - 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, - 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, - 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 16000, - 16032, 16064, 16096, 16128, 16160, 1792, 16192, 1792, 1792, 1792, 1792, - 1792, 1792, 1792, 1792, 4896, 16224, 4896, 4896, 8000, 16256, 16288, - 8032, 16320, 16352, 4896, 16224, 4896, 16384, 1792, 16416, 16448, 16480, - 16512, 1792, 1792, 1792, 1792, 1792, 4896, 4896, 4896, 4896, 4896, - 4896, 4896, 16544, 4896, 4896, 4896, 4896, 4896, 4896, 4896, 4896, - 4896, 4896, 4896, 4896, 4896, 4896, 4896, 4896, 4896, 4896, 4896, 4896, - 4896, 4896, 16576, 16608, 4896, 4896, 4896, 8000, 4896, 4896, 16640, - 1792, 16224, 4896, 16672, 4896, 16704, 16736, 1792, 1792, 16768, 16800, - 16832, 1792, 16864, 1792, 10912, 1792, 1792, 1792, 1792, 1792, 1792, - 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, - 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, - 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, - 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1344, 1344, 1344, 1344, 1344, + ,10688, 10720, 10752, 1824, 1344, 1344, 1344, 8352, 10784, 10816, 10848, + 10880, 10912, 10944, 10976, 11008, 1824, 1824, 1824, 1824, 9280, 1344, + 11040, 11072, 1344, 11104, 11136, 11168, 11200, 1344, 11232, 1824, + 11264, 11296, 11328, 1344, 11360, 11392, 11424, 11456, 1344, 11488, + 1344, 11520, 1824, 1824, 1824, 1824, 1344, 1344, 1344, 1344, 1344, + 1344, 1344, 1344, 1344, 7840, 4704, 10272, 1824, 1824, 1824, 1824, + 11552, 11584, 11616, 11648, 4736, 11680, 1824, 11712, 11744, 11776, + 1824, 1824, 1344, 11808, 11840, 6848, 11872, 11904, 11936, 11968, 12000, + 1824, 12032, 12064, 1344, 12096, 12128, 12160, 12192, 12224, 1824, + 1824, 1344, 1344, 12256, 1824, 12288, 12320, 12352, 12384, 1824, 1824, + 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 12416, 1824, + 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 12448, + 12480, 12512, 12544, 5248, 12576, 12608, 12640, 12672, 12704, 12736, + 12768, 5248, 12800, 12832, 12864, 12896, 12928, 1824, 1824, 12960, + 12992, 13024, 13056, 13088, 2368, 13120, 13152, 1824, 1824, 1824, 1824, + 1344, 13184, 13216, 1824, 1344, 13248, 13280, 1824, 1824, 1824, 1824, + 1824, 1344, 13312, 13344, 1824, 1344, 13376, 13408, 13440, 1344, 13472, + 13504, 1824, 13536, 13568, 1824, 1824, 1824, 1824, 1824, 1824, 1824, + 1824, 1824, 1824, 1824, 13600, 13632, 13664, 1824, 1824, 1824, 1824, + 1824, 1824, 1824, 1824, 13696, 13728, 13760, 1344, 13792, 13824, 1344, + 13856, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 13888, 13920, + 13952, 13984, 14016, 14048, 1824, 1824, 14080, 14112, 14144, 1824, + 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, + 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1344, 1344, 1344, 1344, + 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, + 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, + 9984, 1824, 1824, 1824, 10848, 10848, 10848, 14176, 1344, 1344, 1344, + 1344, 1344, 1344, 14208, 1824, 1824, 1824, 1824, 1824, 1824, 1824, + 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, + 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, + 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, + 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, + 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, + 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, + 1824, 1824, 1824, 1824, 1824, 1824, 1344, 1344, 1344, 1344, 1344, 1344, + 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, + 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, + 1344, 1344, 1344, 14240, 1824, 1824, 1824, 1824, 1824, 1824, 1824, + 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, + 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, + 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, + 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, + 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, + 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, + 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, + 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, + 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, + 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1344, + 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, + 1344, 1344, 1344, 1344, 1344, 14272, 1824, 1824, 1824, 1824, 1824, + 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, + 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, + 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, + 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, + 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, + 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, + 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, + 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, + 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, + 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, + 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, + 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, + 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, + 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, + 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, + 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, + 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, + 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, + 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, + 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, + 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, + 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, + 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, + 1344, 1344, 1344, 1344, 1344, 13856, 4736, 14304, 1824, 1824, 10208, + 14336, 1344, 14368, 14400, 14432, 14464, 1824, 1824, 1824, 1824, 1824, + 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, + 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1344, 1344, + 14496, 14528, 14560, 1824, 1824, 14592, 1344, 1344, 1344, 1344, 1344, + 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, + 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, + 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, + 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, + 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, + 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, + 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, + 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, + 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, + 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, + 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, + 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, + 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, + 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, + 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, + 1344, 1344, 1344, 1344, 1344, 1344, 14624, 1344, 1344, 1344, 1344, + 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, + 1344, 1344, 1344, 1344, 1344, 1344, 1344, 14656, 1824, 1824, 1824, + 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, + 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, + 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, + 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, + 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, + 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, + 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, + 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, + 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, + 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, + 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, + 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, + 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, + 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, + 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, + 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, + 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, + 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, + 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, + 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, + 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, + 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, + 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, + 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, + 1824, 1824, 1824, 1824, 1824, 1344, 1344, 1344, 1344, 1344, 1344, 1344, + 1344, 4736, 1824, 1824, 10208, 1344, 1344, 1344, 1344, 1344, 1344, + 1344, 1344, 1344, 1344, 1344, 9856, 1824, 1824, 1824, 1824, 1824, 1824, + 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, + 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, + 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, + 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, + 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, + 1824, 1824, 1824, 1824, 1824, 1824, 1344, 1344, 1344, 14688, 14720, + 14752, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, + 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, + 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, + 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, + 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, + 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, + 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, + 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, + 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, + 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, + 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, + 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, + 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, + 4928, 4928, 4928, 4928, 4928, 4928, 4928, 8064, 4928, 14784, 4928, + 14816, 14848, 14880, 4928, 14912, 4928, 4928, 14944, 1824, 1824, 1824, + 1824, 1824, 4928, 4928, 14976, 15008, 1824, 1824, 1824, 1824, 15040, + 15072, 15104, 15136, 15168, 15200, 15232, 15264, 15296, 15328, 15360, + 15392, 15424, 15040, 15072, 15456, 15136, 15488, 15520, 15552, 15264, + 15584, 15616, 15648, 15680, 15712, 15744, 15776, 15808, 15840, 15872, + 15904, 4928, 4928, 4928, 4928, 4928, 4928, 4928, 4928, 4928, 4928, + 4928, 4928, 4928, 4928, 4928, 4928, 704, 15936, 704, 15968, 16000, + 16032, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, + 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, + 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, + 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 16064, 16096, 1824, + 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, + 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, + 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, + 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, + 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, + 1824, 1344, 1344, 1344, 1344, 1344, 1344, 16128, 1824, 16160, 16192, + 16224, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, + 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, + 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, + 1824, 1824, 1824, 16256, 16288, 16320, 16352, 16384, 16416, 1824, 16448, + 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 4928, 16480, 4928, + 4928, 8032, 16512, 16544, 8064, 16576, 16608, 4928, 16480, 4928, 16640, + 1824, 16672, 16704, 16736, 16768, 16800, 1824, 1824, 1824, 1824, 4928, + 4928, 4928, 4928, 4928, 4928, 4928, 16832, 4928, 4928, 4928, 4928, + 4928, 4928, 4928, 4928, 4928, 4928, 4928, 4928, 4928, 4928, 4928, 4928, + 4928, 4928, 4928, 4928, 4928, 4928, 16864, 16896, 4928, 4928, 4928, + 8032, 4928, 4928, 16864, 1824, 16480, 4928, 16928, 4928, 16960, 16992, + 1824, 1824, 16480, 8416, 17024, 17056, 17088, 1824, 17120, 6784, 1824, + 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, + 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, + 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, + 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1344, + 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, + 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, + 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, + 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, @@ -479,10 +483,10 @@ static const unsigned short pageMap[] = { 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, + 1344, 7840, 1824, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, - 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 7808, 1792, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, @@ -490,11 +494,10 @@ static const unsigned short pageMap[] = { 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, + 17152, 1344, 1344, 1344, 1344, 1344, 1344, 11360, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, - 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 16896, 1344, 1344, - 1344, 1344, 1344, 1344, 11328, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, @@ -506,39 +509,36 @@ static const unsigned short pageMap[] = { 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, + 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 17184, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, - 1344, 1344, 1344, 1344, 1344, 1344, 14400, 1792, 1792, 1792, 1792, - 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, - 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, - 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, - 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, - 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, - 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, - 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, - 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, - 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, - 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, - 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, - 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, - 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, - 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, - 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, - 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, - 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, - 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, - 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, - 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, - 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, - 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, - 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, - 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, - 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, - 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, - 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, - 1792, 1792, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, - 1344, 1344, 1344, 1344, 1344, 1344, 11328 + 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, + 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, + 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, + 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, + 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, + 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, + 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, + 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, + 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, + 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, + 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, + 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, + 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, + 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, + 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, + 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, + 1344, 1344, 1344, 1344, 17216, 1824, 1824, 1824, 1824, 1824, 1824, + 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, + 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, + 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, + 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, + 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, + 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, + 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, + 1824, 1824, 1824, 1824, 1824, 1824, 1344, 1344, 1344, 1344, 1344, 1344, + 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 11360 #endif /* TCL_UTF_MAX > 3 */ }; @@ -652,72 +652,74 @@ static const unsigned char groupMap[] = { 92, 92, 91, 92, 92, 92, 91, 92, 92, 92, 92, 92, 0, 0, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 0, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 92, - 92, 92, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 0, - 15, 15, 15, 15, 15, 15, 15, 15, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, - 92, 92, 92, 92, 17, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, + 92, 92, 0, 0, 3, 0, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 0, 15, 15, 15, 15, 15, 15, 15, 15, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 92, + 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 17, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, - 92, 92, 92, 124, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 124, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 92, 124, 92, 15, 124, 124, 124, 92, 92, - 92, 92, 92, 92, 92, 92, 124, 124, 124, 124, 92, 124, 124, 15, 92, 92, - 92, 92, 92, 92, 92, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 92, 92, - 3, 3, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 3, 91, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 92, 124, 124, 0, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 92, + 124, 92, 15, 124, 124, 124, 92, 92, 92, 92, 92, 92, 92, 92, 124, 124, + 124, 124, 92, 124, 124, 15, 92, 92, 92, 92, 92, 92, 92, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 92, 92, 3, 3, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 3, 91, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 92, 124, 124, 0, 15, 15, 15, 15, 15, 15, 15, 15, 0, 0, 15, 15, 0, 0, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 0, 15, 15, 15, 15, 15, 15, 15, 0, 15, 0, 0, 0, + 15, 15, 15, 15, 0, 0, 92, 15, 124, 124, 124, 92, 92, 92, 92, 0, 0, + 124, 124, 0, 0, 124, 124, 92, 15, 0, 0, 0, 0, 0, 0, 0, 0, 124, 0, 0, + 0, 0, 15, 15, 0, 15, 15, 15, 92, 92, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 15, 15, 4, 4, 18, 18, 18, 18, 18, 18, 14, 4, 15, 3, 0, 0, 0, + 92, 92, 124, 0, 15, 15, 15, 15, 15, 15, 0, 0, 0, 0, 15, 15, 0, 0, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 0, 15, 15, 15, 15, 15, 15, 15, 0, 15, 15, 0, 15, 15, + 0, 15, 15, 0, 0, 92, 0, 124, 124, 124, 92, 92, 0, 0, 0, 0, 92, 92, + 0, 0, 92, 92, 92, 0, 0, 0, 92, 0, 0, 0, 0, 0, 0, 0, 15, 15, 15, 15, + 0, 15, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 92, 92, 15, + 15, 15, 92, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 92, 92, 124, 0, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 0, 15, 15, 15, 0, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 0, + 15, 15, 15, 15, 15, 15, 15, 0, 15, 15, 0, 15, 15, 15, 15, 15, 0, 0, + 92, 15, 124, 124, 124, 92, 92, 92, 92, 92, 0, 92, 92, 124, 0, 124, + 124, 92, 0, 0, 15, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 15, + 15, 92, 92, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 3, 4, 0, 0, 0, 0, 0, + 0, 0, 15, 92, 92, 92, 92, 92, 92, 0, 92, 124, 124, 0, 15, 15, 15, 15, 15, 15, 15, 15, 0, 0, 15, 15, 0, 0, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 0, 15, 15, - 15, 15, 15, 15, 15, 0, 15, 0, 0, 0, 15, 15, 15, 15, 0, 0, 92, 15, 124, - 124, 124, 92, 92, 92, 92, 0, 0, 124, 124, 0, 0, 124, 124, 92, 15, 0, - 0, 0, 0, 0, 0, 0, 0, 124, 0, 0, 0, 0, 15, 15, 0, 15, 15, 15, 92, 92, - 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 15, 15, 4, 4, 18, 18, 18, 18, 18, - 18, 14, 4, 0, 0, 0, 0, 0, 92, 92, 124, 0, 15, 15, 15, 15, 15, 15, 0, - 0, 0, 0, 15, 15, 0, 0, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 0, 15, 15, 15, 15, 15, - 15, 15, 0, 15, 15, 0, 15, 15, 0, 15, 15, 0, 0, 92, 0, 124, 124, 124, - 92, 92, 0, 0, 0, 0, 92, 92, 0, 0, 92, 92, 92, 0, 0, 0, 92, 0, 0, 0, - 0, 0, 0, 0, 15, 15, 15, 15, 0, 15, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 92, 92, 15, 15, 15, 92, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 92, 92, 124, 0, 15, 15, 15, 15, 15, 15, 15, 15, 15, 0, 15, 15, - 15, 0, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 0, 15, 15, 15, 15, 15, 15, 15, 0, 15, 15, - 0, 15, 15, 15, 15, 15, 0, 0, 92, 15, 124, 124, 124, 92, 92, 92, 92, - 92, 0, 92, 92, 124, 0, 124, 124, 92, 0, 0, 15, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 15, 15, 92, 92, 0, 0, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 3, 4, 0, 0, 0, 0, 0, 0, 0, 15, 0, 0, 0, 0, 0, 0, 0, 92, 124, - 124, 0, 15, 15, 15, 15, 15, 15, 15, 15, 0, 0, 15, 15, 0, 0, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 0, 15, 15, 15, 15, 15, 15, 15, 0, 15, 15, 0, 15, 15, 15, - 15, 15, 0, 0, 92, 15, 124, 92, 124, 92, 92, 92, 92, 0, 0, 124, 124, - 0, 0, 124, 124, 92, 0, 0, 0, 0, 0, 0, 0, 0, 92, 124, 0, 0, 0, 0, 15, - 15, 0, 15, 15, 15, 92, 92, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 14, - 15, 18, 18, 18, 18, 18, 18, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 92, 15, 0, - 15, 15, 15, 15, 15, 15, 0, 0, 0, 15, 15, 15, 0, 15, 15, 15, 15, 0, - 0, 0, 15, 15, 0, 15, 0, 15, 15, 0, 0, 0, 15, 15, 0, 0, 0, 15, 15, 15, - 0, 0, 0, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 0, 0, 0, 0, - 124, 124, 92, 124, 124, 0, 0, 0, 124, 124, 124, 0, 124, 124, 124, 92, - 0, 0, 15, 0, 0, 0, 0, 0, 0, 124, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 18, 18, 18, 14, 14, 14, 14, 14, - 14, 4, 14, 0, 0, 0, 0, 0, 92, 124, 124, 124, 0, 15, 15, 15, 15, 15, - 15, 15, 15, 0, 15, 15, 15, 0, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 0, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 0, 0, 0, 15, 92, - 92, 92, 124, 124, 124, 124, 0, 92, 92, 92, 0, 92, 92, 92, 92, 0, 0, - 0, 0, 0, 0, 0, 92, 92, 0, 15, 15, 15, 0, 0, 0, 0, 0, 15, 15, 92, 92, - 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 18, 18, - 18, 18, 18, 18, 18, 14, 15, 92, 124, 124, 0, 15, 15, 15, 15, 15, 15, - 15, 15, 0, 15, 15, 15, 0, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 0, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 0, 15, 15, 15, 15, 15, 0, 0, 92, 15, 124, 92, - 124, 124, 124, 124, 124, 0, 92, 124, 124, 0, 124, 124, 92, 92, 0, 0, - 0, 0, 0, 0, 0, 124, 124, 0, 0, 0, 0, 0, 0, 0, 15, 0, 15, 15, 92, 92, - 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 15, 15, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 92, 124, 124, 0, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 0, 15, 15, 0, 15, 15, 15, 15, 15, 0, 0, 92, 15, + 124, 92, 124, 92, 92, 92, 92, 0, 0, 124, 124, 0, 0, 124, 124, 92, 0, + 0, 0, 0, 0, 0, 0, 0, 92, 124, 0, 0, 0, 0, 15, 15, 0, 15, 15, 15, 92, + 92, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 14, 15, 18, 18, 18, 18, 18, + 18, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 92, 15, 0, 15, 15, 15, 15, 15, 15, + 0, 0, 0, 15, 15, 15, 0, 15, 15, 15, 15, 0, 0, 0, 15, 15, 0, 15, 0, + 15, 15, 0, 0, 0, 15, 15, 0, 0, 0, 15, 15, 15, 0, 0, 0, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 0, 0, 0, 0, 124, 124, 92, 124, + 124, 0, 0, 0, 124, 124, 124, 0, 124, 124, 124, 92, 0, 0, 15, 0, 0, + 0, 0, 0, 0, 124, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 18, 18, 18, 14, 14, 14, 14, 14, 14, 4, 14, 0, + 0, 0, 0, 0, 92, 124, 124, 124, 0, 15, 15, 15, 15, 15, 15, 15, 15, 0, + 15, 15, 15, 0, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 0, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 0, 0, 0, 15, 92, 92, 92, 124, + 124, 124, 124, 0, 92, 92, 92, 0, 92, 92, 92, 92, 0, 0, 0, 0, 0, 0, + 0, 92, 92, 0, 15, 15, 15, 0, 0, 0, 0, 0, 15, 15, 92, 92, 0, 0, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 18, 18, 18, 18, 18, + 18, 18, 14, 15, 92, 124, 124, 0, 15, 15, 15, 15, 15, 15, 15, 15, 0, + 15, 15, 15, 0, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 0, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 0, 15, 15, 15, 15, 15, 0, 0, 92, 15, 124, 92, 124, + 124, 124, 124, 124, 0, 92, 124, 124, 0, 124, 124, 92, 92, 0, 0, 0, + 0, 0, 0, 0, 124, 124, 0, 0, 0, 0, 0, 0, 0, 15, 0, 15, 15, 92, 92, 0, + 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 15, 15, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 92, 92, 124, 124, 0, 15, 15, 15, 15, 15, 15, 15, 15, 0, 15, 15, 15, 0, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 0, 0, 15, 124, 124, 124, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 92, 92, 15, 124, 124, 124, 92, 92, 92, 92, 0, 124, 124, 124, 0, 124, 124, 124, 92, 15, 14, 0, 0, 0, 0, 15, 15, 15, 124, 18, 18, 18, 18, 18, 18, 18, 15, 15, 15, 92, 92, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 18, 18, 18, 18, 18, 18, 18, @@ -857,7 +859,7 @@ static const unsigned char groupMap[] = { 0, 0, 0, 0, 0, 0, 0, 3, 3, 3, 3, 3, 3, 3, 3, 0, 0, 0, 0, 0, 0, 0, 0, 92, 92, 92, 3, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 124, 92, 92, 92, 92, 92, 92, 92, 15, 15, 15, 15, 92, 15, 15, 15, 15, - 124, 124, 92, 15, 15, 0, 92, 92, 0, 0, 0, 0, 0, 0, 21, 21, 21, 21, + 124, 124, 92, 15, 15, 124, 92, 92, 0, 0, 0, 0, 0, 0, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, @@ -868,9 +870,9 @@ static const unsigned char groupMap[] = { 21, 21, 137, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 91, 91, 91, 91, 91, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, - 92, 92, 92, 92, 92, 92, 92, 92, 0, 0, 0, 0, 0, 92, 92, 92, 92, 92, - 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, - 24, 23, 24, 23, 24, 21, 21, 21, 21, 21, 138, 21, 21, 139, 21, 140, + 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 0, 92, 92, 92, 92, + 92, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, + 23, 24, 23, 24, 23, 24, 21, 21, 21, 21, 21, 138, 21, 21, 139, 21, 140, 140, 140, 140, 140, 140, 140, 140, 141, 141, 141, 141, 141, 141, 141, 141, 140, 140, 140, 140, 140, 140, 0, 0, 141, 141, 141, 141, 141, 141, 0, 0, 140, 140, 140, 140, 140, 140, 140, 140, 141, 141, 141, 141, 141, @@ -897,7 +899,7 @@ static const unsigned char groupMap[] = { 18, 18, 7, 7, 7, 5, 6, 91, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 7, 7, 7, 5, 6, 0, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 0, 0, 0, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, - 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 119, 119, 119, 119, 92, 119, 119, 119, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 14, @@ -930,7 +932,7 @@ static const unsigned char groupMap[] = { 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 7, 7, 7, 7, 7, 7, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 0, 14, 14, 14, 14, 14, 14, 14, 0, 0, 0, 0, 0, 0, 0, 0, + 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, @@ -971,9 +973,9 @@ static const unsigned char groupMap[] = { 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 0, 0, 0, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 0, 14, 14, 14, 14, 14, - 14, 14, 14, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 14, 14, 14, 14, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 122, 122, 122, 122, 122, 122, 122, 122, 122, 122, + 14, 14, 14, 14, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 14, 14, 14, 14, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 122, 122, 122, 122, 122, 122, 122, 122, 122, 122, 122, 122, 122, 122, 122, 122, 122, 122, 122, 122, 122, 122, 122, 122, 122, 122, 122, 122, 122, 122, 122, 122, 122, 122, 122, 122, 122, 122, 122, 122, 122, 122, 122, 122, 122, 122, 122, 0, 123, 123, 123, 123, @@ -996,7 +998,7 @@ static const unsigned char groupMap[] = { 0, 3, 3, 16, 20, 16, 20, 3, 3, 3, 16, 20, 3, 16, 20, 3, 3, 3, 3, 3, 3, 3, 3, 3, 8, 3, 3, 8, 3, 16, 20, 3, 3, 16, 20, 5, 6, 5, 6, 5, 6, 5, 6, 3, 3, 3, 3, 3, 91, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 8, 8, 3, 3, - 3, 3, 8, 3, 5, 3, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 3, 3, 8, 3, 5, 3, 3, 3, 3, 3, 3, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 0, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, @@ -1014,7 +1016,7 @@ static const unsigned char groupMap[] = { 15, 15, 15, 15, 15, 3, 91, 91, 91, 15, 0, 0, 0, 0, 0, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 0, 0, 0, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 0, 0, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 0, 14, 14, 18, 18, 18, 18, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, @@ -1173,245 +1175,269 @@ static const unsigned char groupMap[] = { 15, 15, 15, 15, 15, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 92, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 0, 0, 0, 0, 18, 18, 18, 18, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 127, 15, 15, 15, 15, 15, 15, 15, - 15, 127, 0, 0, 0, 0, 0, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 127, 15, 15, 15, 15, 15, 15, + 15, 15, 127, 0, 0, 0, 0, 0, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 92, 92, 92, 92, 92, 0, 0, 0, - 0, 0, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 0, 3, 15, 15, - 15, 15, 0, 0, 0, 0, 15, 15, 15, 15, 15, 15, 15, 15, 3, 127, 127, 127, - 127, 127, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 194, 194, 194, 194, 194, 194, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 92, 92, 92, 92, 92, 0, + 0, 0, 0, 0, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 0, + 3, 15, 15, 15, 15, 0, 0, 0, 0, 15, 15, 15, 15, 15, 15, 15, 15, 3, 127, + 127, 127, 127, 127, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 194, 194, 194, 194, 194, 194, 194, 194, 194, 194, 194, 194, 194, 194, 194, 194, 194, 194, 194, 194, 194, 194, 194, 194, 194, 194, 194, 194, 194, 194, 194, 194, - 194, 194, 194, 194, 194, 194, 195, 195, 195, 195, 195, 195, 195, 195, + 194, 194, 194, 194, 194, 194, 194, 194, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, - 195, 195, 195, 195, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 195, 195, 195, 195, 195, 195, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 194, 194, 194, + 15, 15, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 194, 194, 194, 194, 194, 194, 194, 194, 194, 194, 194, 194, 194, 194, 194, 194, 194, 194, 194, 194, 194, 194, 194, 194, 194, 194, 194, 194, 194, - 194, 194, 194, 194, 194, 0, 0, 0, 0, 195, 195, 195, 195, 195, 195, + 194, 194, 194, 194, 194, 194, 194, 0, 0, 0, 0, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, - 195, 195, 0, 0, 0, 0, 15, 15, 15, 15, 15, 15, 15, 15, 0, 0, 0, 0, 0, - 0, 0, 0, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 15, 15, 15, 15, 15, 15, 0, 0, 15, - 0, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 0, 15, 15, 0, 0, 0, 15, - 0, 0, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 0, 3, 18, 18, 18, 18, 18, 18, 18, 18, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 14, 14, 18, 18, 18, 18, 18, 18, 18, 0, 0, 0, 0, - 0, 0, 0, 18, 18, 18, 18, 18, 18, 18, 18, 18, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 0, 15, 15, 0, 0, 0, 0, 0, 18, 18, 18, - 18, 18, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 18, 18, 18, 18, 18, 18, 0, 0, 0, 3, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 0, 0, 0, 0, 0, 3, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 0, 0, 0, 0, 18, 18, 15, 15, 18, 18, 18, 18, 18, 18, 18, 18, - 18, 18, 18, 18, 18, 18, 18, 18, 0, 0, 18, 18, 18, 18, 18, 18, 18, 18, - 18, 18, 18, 18, 18, 18, 15, 92, 92, 92, 0, 92, 92, 0, 0, 0, 0, 0, 92, - 92, 92, 92, 15, 15, 15, 15, 0, 15, 15, 15, 0, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 0, 0, 0, 0, 92, 92, 92, 0, 0, 0, 0, 92, 18, 18, 18, - 18, 18, 18, 18, 18, 0, 0, 0, 0, 0, 0, 0, 0, 3, 3, 3, 3, 3, 3, 3, 3, - 3, 0, 0, 0, 0, 0, 0, 0, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 18, 18, 3, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 18, - 18, 18, 15, 15, 15, 15, 15, 15, 15, 15, 14, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 92, 92, 0, 0, 0, 0, 18, 18, 18, 18, 18, 3, 3, 3, - 3, 3, 3, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 0, 0, 0, - 3, 3, 3, 3, 3, 3, 3, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 0, 0, 18, 18, 18, 18, 18, 18, - 18, 18, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 0, 0, 0, 0, 0, 18, 18, 18, 18, 18, 18, 18, 18, 15, + 195, 195, 195, 195, 0, 0, 0, 0, 15, 15, 15, 15, 15, 15, 15, 15, 0, + 0, 0, 0, 0, 0, 0, 0, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 15, 15, 15, 15, 15, + 15, 0, 0, 15, 0, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 0, 0, 0, 0, 0, 0, 0, 3, 3, 3, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 18, 18, 18, 18, 18, 18, 18, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 15, 15, 15, 15, 15, 15, 15, 15, 15, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 97, 97, 97, 97, 97, 97, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 0, 15, 15, + 0, 0, 0, 15, 0, 0, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 0, 3, 18, 18, 18, 18, 18, + 18, 18, 18, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 14, 14, 18, 18, 18, 18, 18, 18, + 18, 0, 0, 0, 0, 0, 0, 0, 18, 18, 18, 18, 18, 18, 18, 18, 18, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 0, 15, 15, 0, 0, 0, + 0, 0, 18, 18, 18, 18, 18, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 18, 18, 18, 18, 18, 18, + 0, 0, 0, 3, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 0, 0, 0, 0, 0, 3, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 0, 0, 0, 0, 18, 18, 15, 15, 18, 18, 18, 18, + 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 0, 0, 18, 18, 18, 18, + 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 15, 92, 92, 92, 0, 92, 92, + 0, 0, 0, 0, 0, 92, 92, 92, 92, 15, 15, 15, 15, 0, 15, 15, 15, 0, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 0, 0, 0, 0, 92, 92, 92, 0, 0, 0, + 0, 92, 18, 18, 18, 18, 18, 18, 18, 18, 0, 0, 0, 0, 0, 0, 0, 0, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 0, 0, 0, 0, 0, 0, 0, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 18, 18, 3, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 18, 18, 18, 15, 15, 15, 15, 15, 15, 15, 15, 14, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 92, 92, 0, 0, 0, 0, 18, 18, 18, + 18, 18, 3, 3, 3, 3, 3, 3, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 0, 0, 0, 3, 3, 3, 3, 3, 3, 3, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 0, 0, 18, 18, + 18, 18, 18, 18, 18, 18, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 0, 0, 0, 0, 0, 18, 18, 18, 18, 18, + 18, 18, 18, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 0, 0, 0, 0, 0, 0, 0, 3, 3, 3, 3, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 18, 18, 18, 18, 18, 18, 18, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 15, 15, 15, 15, 15, 15, 15, 15, 15, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, - 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, + 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, - 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 0, 0, 0, - 0, 0, 0, 0, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, + 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, + 102, 102, 0, 0, 0, 0, 0, 0, 0, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, - 18, 18, 18, 18, 18, 18, 0, 124, 92, 124, 15, 15, 15, 15, 15, 15, 15, + 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 0, 124, 92, 124, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 3, 3, 3, + 3, 3, 3, 3, 0, 0, 0, 0, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, + 18, 18, 18, 18, 18, 18, 18, 18, 18, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 92, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 124, 124, 124, 92, 92, 92, + 92, 124, 124, 92, 92, 3, 3, 17, 3, 3, 3, 3, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 0, 0, 0, 0, 0, 0, 0, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 92, 92, 92, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 92, 92, 92, 92, 92, - 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 3, 3, 3, 3, 3, 3, 3, 0, 0, - 0, 0, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, - 18, 18, 18, 18, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 92, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 124, 124, 124, 92, 92, 92, 92, 124, 124, 92, - 92, 3, 3, 17, 3, 3, 3, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 92, 92, 92, 92, 92, 124, 92, 92, 92, 92, 92, 92, 92, 92, 0, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 3, 3, 3, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 92, 92, 92, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 92, 92, 92, 92, - 92, 124, 92, 92, 92, 92, 92, 92, 92, 92, 0, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 3, 3, 3, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 15, 15, 15, 15, + 15, 92, 3, 3, 15, 0, 0, 0, 0, 0, 0, 0, 0, 0, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 124, 124, 124, + 92, 92, 92, 92, 92, 92, 92, 92, 92, 124, 124, 15, 15, 15, 15, 3, 3, + 3, 3, 3, 92, 92, 92, 3, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 15, 3, + 15, 3, 3, 3, 0, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, + 18, 18, 18, 18, 18, 18, 18, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 0, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 92, 3, 3, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 124, 124, 124, 92, 92, 92, 124, 124, + 92, 124, 92, 92, 3, 3, 3, 3, 3, 3, 92, 0, 15, 15, 15, 15, 15, 15, 15, + 0, 15, 0, 15, 15, 15, 15, 0, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 0, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 3, 0, + 0, 0, 0, 0, 0, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 92, 124, 124, 124, 92, 92, 92, 92, 92, 92, 92, 92, 0, 0, 0, 0, 0, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 92, 92, 124, 124, 0, 15, + 15, 15, 15, 15, 15, 15, 15, 0, 0, 15, 15, 0, 0, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 92, 124, 124, 124, 124, 0, 0, 124, + 124, 0, 0, 124, 124, 124, 0, 0, 15, 0, 0, 0, 0, 0, 0, 124, 0, 0, 0, + 0, 0, 15, 15, 15, 15, 15, 124, 124, 0, 0, 92, 92, 92, 92, 92, 92, 92, + 0, 0, 0, 92, 92, 92, 92, 92, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 124, 124, 124, 92, 92, 92, 92, 92, 92, 92, 92, 124, 124, 92, + 92, 92, 124, 92, 15, 15, 15, 15, 3, 3, 3, 3, 3, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 0, 3, 0, 3, 0, 0, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 124, 124, 124, 92, 92, 92, 92, 92, 92, 124, + 92, 124, 124, 124, 124, 92, 92, 124, 92, 92, 15, 15, 3, 15, 0, 0, 0, + 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 124, 124, 124, + 92, 92, 92, 92, 0, 0, 124, 124, 124, 124, 92, 92, 124, 92, 92, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 15, + 15, 15, 15, 92, 92, 0, 0, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 124, 124, 124, 92, 92, 92, 92, 92, 92, 92, 92, + 124, 124, 92, 124, 92, 92, 3, 3, 3, 15, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 92, 124, 92, + 124, 124, 92, 92, 92, 92, 92, 92, 124, 92, 0, 0, 0, 0, 0, 0, 0, 0, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 124, 124, 124, 92, 92, 92, 92, - 92, 92, 92, 92, 92, 124, 124, 15, 15, 15, 15, 3, 3, 3, 3, 3, 92, 92, - 92, 3, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 15, 3, 15, 3, 3, 3, 0, 18, - 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, - 18, 18, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 0, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 124, 124, 124, 92, 92, 92, 124, 124, 92, 124, 92, 92, 3, - 3, 3, 3, 3, 3, 92, 0, 15, 15, 15, 15, 15, 15, 15, 0, 15, 0, 15, 15, - 15, 15, 0, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 0, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 3, 0, 0, 0, 0, 0, 0, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 92, 124, 124, 124, - 92, 92, 92, 92, 92, 92, 92, 92, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 0, 0, 0, 0, 0, 0, 92, 92, 124, 124, 0, 15, 15, 15, 15, 15, - 15, 15, 15, 0, 0, 15, 15, 0, 0, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 92, 124, 124, 124, 124, 0, 0, 124, 124, 0, 0, 124, - 124, 124, 0, 0, 15, 0, 0, 0, 0, 0, 0, 124, 0, 0, 0, 0, 0, 15, 15, 15, - 15, 15, 124, 124, 0, 0, 92, 92, 92, 92, 92, 92, 92, 0, 0, 0, 92, 92, - 92, 92, 92, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 124, 124, - 124, 92, 92, 92, 92, 92, 92, 92, 92, 124, 124, 92, 92, 92, 124, 92, - 15, 15, 15, 15, 3, 3, 3, 3, 3, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 3, - 0, 3, 0, 0, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 124, 124, 124, 92, 92, 92, 92, 92, 92, 124, 92, 124, 124, 124, - 124, 92, 92, 124, 92, 92, 15, 15, 3, 15, 0, 0, 0, 0, 0, 0, 0, 0, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 124, 124, 124, 92, 92, 92, 92, - 0, 0, 124, 124, 124, 124, 92, 92, 124, 92, 92, 3, 3, 3, 3, 3, 3, 3, - 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 15, 15, 15, 15, 92, - 92, 0, 0, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 124, 124, 124, 92, 92, 92, 92, 92, 92, 92, 92, 124, 124, 92, 124, - 92, 92, 3, 3, 3, 15, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, - 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 92, 124, 92, 124, 124, 92, 92, - 92, 92, 92, 92, 124, 92, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 0, 0, 0, 92, 92, 92, 124, - 124, 92, 92, 92, 92, 124, 92, 92, 92, 92, 92, 0, 0, 0, 0, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 18, 18, 3, 3, 3, 14, 10, 10, 10, 10, 10, 10, 10, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 0, + 0, 0, 92, 92, 92, 124, 124, 92, 92, 92, 92, 124, 92, 92, 92, 92, 92, + 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 18, 18, 3, 3, 3, 14, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, - 10, 10, 10, 10, 10, 10, 10, 10, 13, 13, 13, 13, 13, 13, 13, 13, 13, + 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, - 13, 13, 13, 13, 13, 13, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 18, 18, 18, 18, - 18, 18, 18, 18, 18, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 15, 15, 15, + 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 18, 18, 18, 18, 18, 18, 18, 18, 18, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 15, 15, 92, 92, 92, 92, 92, 92, 124, 124, 92, 92, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 92, 92, 92, 92, 92, 92, 124, 15, 92, 92, 92, 92, 3, + 3, 3, 3, 3, 3, 3, 3, 92, 0, 0, 0, 0, 0, 0, 0, 0, 15, 92, 92, 92, 92, + 92, 92, 124, 124, 92, 92, 92, 15, 15, 15, 15, 15, 15, 15, 15, 0, 0, + 15, 15, 15, 15, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, + 124, 92, 92, 3, 3, 3, 0, 3, 3, 3, 3, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 0, 0, 0, 0, 0, 0, 0, 15, 15, 15, 15, 15, 15, 15, 15, 15, 0, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 124, 92, 92, 92, 92, 92, 92, 92, 0, 124, - 124, 124, 124, 92, 92, 124, 92, 15, 3, 3, 3, 3, 3, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 18, 18, 18, 18, 18, 18, 18, + 15, 15, 15, 15, 15, 15, 15, 124, 92, 92, 92, 92, 92, 92, 92, 0, 92, + 92, 92, 92, 92, 92, 124, 92, 15, 3, 3, 3, 3, 3, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 0, 0, 0, 3, 3, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 0, 0, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 0, 124, 92, 92, 92, 92, 92, 92, 92, 124, 92, 92, 124, 92, 92, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 127, 127, 127, 127, 127, 127, 127, 127, 127, - 127, 127, 127, 127, 127, 127, 0, 3, 3, 3, 3, 3, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 15, 15, 15, 15, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 15, 15, 15, 15, 15, 15, 15, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 0, 0, 0, 0, 3, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 0, 0, 92, 92, 92, 92, 92, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 92, 92, 92, - 92, 92, 92, 92, 3, 3, 3, 3, 3, 14, 14, 14, 14, 91, 91, 91, 91, 3, 14, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 18, - 18, 18, 18, 18, 18, 18, 0, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 0, 0, 0, 0, 0, 15, 15, + 0, 0, 0, 0, 0, 0, 0, 0, 15, 15, 15, 15, 15, 15, 15, 0, 15, 15, 0, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 15, 15, 15, 15, 15, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 15, 124, 124, 124, 124, 124, 124, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 92, 92, 92, 92, 92, 92, 0, 0, 0, 92, 0, 92, 92, 0, 92, + 92, 92, 92, 92, 92, 92, 15, 92, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 127, 127, 127, 127, 127, 127, 127, + 127, 127, 127, 127, 127, 127, 127, 127, 0, 3, 3, 3, 3, 3, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 15, 15, 15, 15, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 15, 15, 15, 15, 15, 15, 15, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 3, 3, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 0, 0, 92, 92, 92, 92, 92, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 92, 92, 92, 92, 92, 92, 92, 3, 3, 3, 3, 3, 14, 14, 14, 14, 91, 91, + 91, 91, 3, 14, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 0, 18, 18, 18, 18, 18, 18, 18, 0, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 0, 0, 0, 0, + 0, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 15, 15, + 15, 15, 15, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 15, 124, 124, 124, 124, + 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, - 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 92, 92, 92, 92, 91, 91, 91, - 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 92, 92, 92, 92, 91, + 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 15, 15, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 0, 0, 0, 0, 0, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 0, 0, 0, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 0, 0, 0, 0, 0, 0, 0, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 0, 0, - 14, 92, 92, 3, 17, 17, 17, 17, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 14, 14, 14, 14, 14, - 14, 14, 0, 0, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 124, 124, 92, - 92, 92, 14, 14, 14, 124, 124, 124, 124, 124, 124, 17, 17, 17, 17, 17, - 17, 17, 17, 92, 92, 92, 92, 92, 92, 92, 92, 14, 14, 92, 92, 92, 92, - 92, 92, 92, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 92, - 92, 92, 92, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 14, 14, 92, 92, - 92, 14, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, - 18, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 107, 107, 107, 107, 107, + 0, 0, 0, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 0, 0, 0, 0, 0, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 0, 0, 0, 15, 15, 15, 15, 15, 15, 15, 15, 15, 0, 0, 0, 0, 0, 0, + 0, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 0, 0, 14, 92, 92, 3, 17, + 17, 17, 17, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 14, 14, 14, 14, 14, 14, 14, 0, 0, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, 14, 124, 124, 92, 92, 92, 14, 14, 14, + 124, 124, 124, 124, 124, 124, 17, 17, 17, 17, 17, 17, 17, 17, 92, 92, + 92, 92, 92, 92, 92, 92, 14, 14, 92, 92, 92, 92, 92, 92, 92, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 92, 92, 92, 92, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 14, 14, 92, 92, 92, 14, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 14, + 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 0, 0, 0, 0, 0, 0, 0, 0, 0, 18, 18, 18, 18, 18, + 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 107, 107, 107, 107, 107, 107, 107, 107, + 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, + 107, 107, 107, 107, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, + 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 107, 107, 107, + 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, + 107, 107, 107, 107, 107, 107, 107, 107, 107, 21, 21, 21, 21, 21, 21, + 21, 0, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, + 21, 21, 21, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, + 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, + 107, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, + 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 107, 0, 107, 107, 0, 0, 107, + 0, 0, 107, 107, 0, 0, 107, 107, 107, 107, 0, 107, 107, 107, 107, 107, + 107, 107, 107, 21, 21, 21, 21, 0, 21, 0, 21, 21, 21, 21, 21, 21, 21, + 0, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 107, 107, 107, 107, + 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, + 107, 107, 107, 107, 107, 107, 107, 107, 21, 21, 21, 21, 21, 21, 21, + 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, + 21, 21, 107, 107, 0, 107, 107, 107, 107, 0, 0, 107, 107, 107, 107, + 107, 107, 107, 107, 0, 107, 107, 107, 107, 107, 107, 107, 0, 21, 21, + 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, + 21, 21, 21, 21, 21, 21, 21, 107, 107, 0, 107, 107, 107, 107, 0, 107, + 107, 107, 107, 107, 0, 107, 0, 0, 0, 107, 107, 107, 107, 107, 107, + 107, 0, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, + 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, - 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 21, - 21, 21, 21, 21, 21, 21, 0, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, - 21, 21, 21, 21, 21, 21, 21, 21, 107, 107, 107, 107, 107, 107, 107, + 107, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, + 21, 21, 107, 107, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, + 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, - 107, 107, 107, 107, 107, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, - 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 107, 0, - 107, 107, 0, 0, 107, 0, 0, 107, 107, 0, 0, 107, 107, 107, 107, 0, 107, - 107, 107, 107, 107, 107, 107, 107, 21, 21, 21, 21, 0, 21, 0, 21, 21, - 21, 21, 21, 21, 21, 0, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, - 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, - 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 21, 21, + 107, 107, 107, 107, 107, 107, 107, 107, 107, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, - 21, 21, 21, 21, 21, 21, 21, 107, 107, 0, 107, 107, 107, 107, 0, 0, - 107, 107, 107, 107, 107, 107, 107, 107, 0, 107, 107, 107, 107, 107, - 107, 107, 0, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, - 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 107, 107, 0, 107, 107, - 107, 107, 0, 107, 107, 107, 107, 107, 0, 107, 0, 0, 0, 107, 107, 107, - 107, 107, 107, 107, 0, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, - 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 107, 107, + 21, 21, 21, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, + 107, 107, 107, 107, 107, 21, 21, 21, 21, 21, 21, 0, 0, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, - 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 21, 21, 21, 21, 21, + 107, 107, 107, 107, 107, 107, 107, 107, 7, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, + 21, 21, 7, 21, 21, 21, 21, 21, 21, 107, 107, 107, 107, 107, 107, 107, + 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, + 107, 107, 107, 107, 7, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, + 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 7, 21, 21, 21, 21, 21, 21, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, - 107, 107, 107, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, - 21, 21, 21, 21, 21, 107, 107, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, - 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, - 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 21, 21, 21, - 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, - 21, 21, 21, 21, 21, 21, 107, 107, 107, 107, 107, 107, 107, 107, 107, - 107, 107, 107, 107, 107, 107, 107, 21, 21, 21, 21, 21, 21, 0, 0, 107, + 7, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, + 21, 21, 21, 21, 21, 21, 21, 21, 21, 7, 21, 21, 21, 21, 21, 21, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 7, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, @@ -1419,89 +1445,81 @@ static const unsigned char groupMap[] = { 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 7, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 7, - 21, 21, 21, 21, 21, 21, 107, 107, 107, 107, 107, 107, 107, 107, 107, - 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, - 107, 107, 7, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, - 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 7, 21, 21, 21, 21, 21, - 21, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, - 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 7, 21, - 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, - 21, 21, 21, 21, 21, 21, 21, 7, 21, 21, 21, 21, 21, 21, 107, 107, 107, - 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, - 107, 107, 107, 107, 107, 107, 107, 107, 7, 21, 21, 21, 21, 21, 21, - 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, - 21, 21, 7, 21, 21, 21, 21, 21, 21, 107, 21, 0, 0, 9, 9, 9, 9, 9, 9, + 21, 21, 21, 21, 21, 21, 107, 21, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 92, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, - 92, 92, 92, 92, 92, 14, 14, 14, 14, 92, 92, 92, 92, 92, 92, 92, 92, - 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 14, 14, 14, 14, 14, 14, 14, - 14, 92, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 92, - 14, 14, 3, 3, 3, 3, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 92, 92, 92, 92, 92, 0, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, - 92, 92, 92, 92, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 92, - 92, 92, 92, 92, 92, 92, 0, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, - 92, 92, 92, 92, 92, 92, 92, 0, 0, 92, 92, 92, 92, 92, 92, 92, 0, 92, - 92, 0, 92, 92, 92, 92, 92, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 15, 15, 15, 15, 15, 0, 0, 18, 18, 18, 18, 18, - 18, 18, 18, 18, 92, 92, 92, 92, 92, 92, 92, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, + 92, 92, 14, 14, 14, 14, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, + 92, 92, 92, 92, 92, 92, 92, 14, 14, 14, 14, 14, 14, 14, 14, 92, 14, + 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 92, 14, 14, 3, + 3, 3, 3, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 92, 92, 92, + 92, 92, 0, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, + 92, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 92, 92, 92, 92, + 92, 92, 92, 0, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, + 92, 92, 92, 92, 0, 0, 92, 92, 92, 92, 92, 92, 92, 0, 92, 92, 0, 92, + 92, 92, 92, 92, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 15, 15, 15, 15, 15, 0, 0, 18, 18, 18, 18, 18, 18, 18, 18, + 18, 92, 92, 92, 92, 92, 92, 92, 0, 0, 0, 0, 0, 0, 0, 0, 0, 196, 196, + 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, - 196, 196, 196, 196, 196, 196, 196, 197, 197, 197, 197, 197, 197, 197, + 196, 196, 196, 196, 197, 197, 197, 197, 197, 197, 197, 197, 197, 197, 197, 197, 197, 197, 197, 197, 197, 197, 197, 197, 197, 197, 197, 197, - 197, 197, 197, 197, 197, 197, 197, 197, 197, 197, 197, 197, 197, 92, - 92, 92, 92, 92, 92, 92, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 0, 0, 0, 0, 3, 3, 15, 15, 15, 15, 0, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 0, 15, 15, 0, 15, 0, 0, 15, 0, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 0, 15, 15, 15, 15, 0, 15, 0, 15, 0, 0, 0, 0, 0, 0, 15, - 0, 0, 0, 0, 15, 0, 15, 0, 15, 0, 15, 15, 15, 0, 15, 15, 0, 15, 0, 0, - 15, 0, 15, 0, 15, 0, 15, 0, 15, 0, 15, 15, 0, 15, 0, 0, 15, 15, 15, - 15, 0, 15, 15, 15, 15, 15, 15, 15, 0, 15, 15, 15, 15, 0, 15, 15, 15, - 15, 0, 15, 0, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 0, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 0, 0, 0, 0, - 0, 15, 15, 15, 0, 15, 15, 15, 15, 15, 0, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 0, 0, 0, - 0, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 0, 0, 14, - 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 0, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 0, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 18, 18, 18, 18, 18, - 18, 18, 18, 18, 18, 18, 18, 18, 0, 0, 0, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 0, 14, 14, 14, 14, 14, 14, 14, 14, 14, + 197, 197, 197, 197, 197, 197, 197, 197, 197, 197, 92, 92, 92, 92, 92, + 92, 92, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 3, + 3, 15, 15, 15, 15, 0, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 0, 15, + 15, 0, 15, 0, 0, 15, 0, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 0, + 15, 15, 15, 15, 0, 15, 0, 15, 0, 0, 0, 0, 0, 0, 15, 0, 0, 0, 0, 15, + 0, 15, 0, 15, 0, 15, 15, 15, 0, 15, 15, 0, 15, 0, 0, 15, 0, 15, 0, + 15, 0, 15, 0, 15, 0, 15, 15, 0, 15, 0, 0, 15, 15, 15, 15, 0, 15, 15, + 15, 15, 15, 15, 15, 0, 15, 15, 15, 15, 0, 15, 15, 15, 15, 0, 15, 0, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 0, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 0, 0, 0, 0, 0, 15, 15, + 15, 0, 15, 15, 15, 15, 15, 0, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 7, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 0, 0, 0, 0, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 14, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 0, 0, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 0, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 0, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, 14, 18, 18, 18, 18, 18, 18, 18, 18, + 18, 18, 18, 18, 18, 0, 0, 0, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 0, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 0, 0, 0, 0, 14, 14, 14, 14, 14, 14, 14, 14, 14, 0, 0, 0, 0, - 0, 0, 0, 14, 14, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 14, 14, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, 11, 11, 11, 11, 11, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 0, 0, 0, 14, 14, 14, 14, 14, 14, 14, 0, 0, 0, 0, 0, 0, + 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 0, + 0, 0, 0, 14, 14, 14, 14, 14, 14, 14, 14, 14, 0, 0, 0, 0, 0, 0, 0, 14, + 14, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 14, 14, 14, 14, 14, 14, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 14, 14, 14, - 14, 14, 14, 14, 14, 0, 0, 0, 0, 0, 0, 0, 0, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 0, 0, 0, 0, 0, 0, 14, 14, 14, 14, 14, 14, 14, 14, 0, - 0, 0, 0, 0, 0, 0, 0, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 11, 11, 11, 11, 11, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, - 14, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, 0, 14, 14, 14, 14, 14, 14, 14, 14, - 0, 0, 0, 0, 0, 0, 0, 0, 14, 0, 0, 14, 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 0, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 0, 0, - 0, 0, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 0, + 14, 14, 14, 14, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, 0, 0, 0, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 0, 0, 0, 0, 0, 0, 0, 14, 14, 14, 14, 14, 14, 14, 14, 0, 0, + 0, 0, 0, 0, 0, 0, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 0, 0, 0, + 0, 0, 0, 14, 14, 14, 14, 14, 14, 14, 14, 0, 0, 0, 0, 0, 0, 0, 0, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, - 14, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0 + 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 14, 14, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 0, 0, 0, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 0, 0, 0, 0, 0, 0, 0, 0, 14, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 15, 15, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0 #endif /* TCL_UTF_MAX > 3 */ }; -- cgit v0.12 From cf0cf6ad90055ae80f8ed7ec6b87d145d31cfcff Mon Sep 17 00:00:00 2001 From: dgp Date: Tue, 23 May 2017 16:00:29 +0000 Subject: [19a8c9399d] Plug mem leak in TIP 459 machinery. --- generic/tclPkg.c | 1 + 1 file changed, 1 insertion(+) diff --git a/generic/tclPkg.c b/generic/tclPkg.c index 9ad3cb7..3b0554a 100644 --- a/generic/tclPkg.c +++ b/generic/tclPkg.c @@ -224,6 +224,7 @@ static void PkgFilesCleanupProc(ClientData clientData, entry = Tcl_NextHashEntry(&search); } Tcl_DeleteHashTable(&pkgFiles->table); + ckfree(pkgFiles); return; } -- cgit v0.12 From 5badb6535fd037244cae95a25e9790c7dae3c7c8 Mon Sep 17 00:00:00 2001 From: griffin Date: Sat, 27 May 2017 22:17:21 +0000 Subject: Implement proposed 0d decimal radix prefix to compliment 0x,0b,0o. --- doc/GetInt.3 | 7 +++++-- doc/expr.n | 2 +- generic/tclStrToD.c | 16 +++++++++++++++- tests/cmdIL.test | 4 ++-- tests/util.test | 18 ++++++++++++++++++ 5 files changed, 41 insertions(+), 6 deletions(-) diff --git a/doc/GetInt.3 b/doc/GetInt.3 index 5a3304a..8d7a4d0 100644 --- a/doc/GetInt.3 +++ b/doc/GetInt.3 @@ -56,6 +56,9 @@ followed by white space. If the first two characters of \fIsrc\fR after the optional white space and sign are .QW \fB0x\fR then \fIsrc\fR is expected to be in hexadecimal form; otherwise, +if the first such characters are +.QW \fB0d\fR +then \fIsrc\fR is expected to be in decimal form; otherwise, if the first such characters are .QW \fB0o\fR then \fIsrc\fR is expected to be in octal form; otherwise, @@ -65,8 +68,8 @@ then \fIsrc\fR is expected to be in binary form; otherwise, if the first such character is .QW \fB0\fR then \fIsrc\fR -is expected to be in octal form; otherwise, \fIsrc\fR is -expected to be in decimal form. +is expected to be in octal form; otherwise, \fIsrc\fR +is expected to be in decimal form. .PP \fBTcl_GetDouble\fR expects \fIsrc\fR to consist of a floating-point number, which is: white space; a sign; a sequence of digits; a diff --git a/doc/expr.n b/doc/expr.n index cbb2395..3cd6d16 100644 --- a/doc/expr.n +++ b/doc/expr.n @@ -46,7 +46,7 @@ value is the form produced by the \fB%g\fR format specifier of Tcl's An expression consists of a combination of operands, operators, parentheses and commas, possibly with whitespace between any of these elements, which is ignored. -An integer operand may be specified in decimal, binary +An integer operand may be specified in decimal (the optional first two characters are \fB0d\fR), binary (the first two characters are \fB0b\fR), octal (the first two characters are \fB0o\fR), or hexadecimal (the first two characters are \fB0x\fR) form. For diff --git a/generic/tclStrToD.c b/generic/tclStrToD.c index c7fdc5a..cbdc3a0 100644 --- a/generic/tclStrToD.c +++ b/generic/tclStrToD.c @@ -482,7 +482,7 @@ TclParseNumber( { enum State { INITIAL, SIGNUM, ZERO, ZERO_X, - ZERO_O, ZERO_B, BINARY, + ZERO_O, ZERO_B, ZERO_D, BINARY, HEXADECIMAL, OCTAL, BAD_OCTAL, DECIMAL, LEADING_RADIX_POINT, FRACTION, EXPONENT_START, EXPONENT_SIGNUM, EXPONENT, @@ -664,6 +664,10 @@ TclParseNumber( state = ZERO_O; break; } + if (c == 'd' || c == 'D') { + state = ZERO_D; + break; + } #ifdef TCL_NO_DEPRECATED goto decimal; #endif @@ -880,6 +884,16 @@ TclParseNumber( state = BINARY; break; + case ZERO_D: + if (c == '0') { + numTrailZeros++; + } else if ( ! isdigit(UCHAR(c))) { + goto endgame; + } + state = DECIMAL; + flags |= TCL_PARSE_INTEGER_ONLY; + /* FALLTHROUGH */ + case DECIMAL: /* * Scanned an optional + or - followed by a string of decimal diff --git a/tests/cmdIL.test b/tests/cmdIL.test index 23a5f96..70ac6bb 100644 --- a/tests/cmdIL.test +++ b/tests/cmdIL.test @@ -219,8 +219,8 @@ test cmdIL-3.10 {SortCompare procedure, -integer option} -body { lsort -integer {3 q} } -returnCodes error -result {expected integer but got "q"} test cmdIL-3.11 {SortCompare procedure, -integer option} { - lsort -integer {35 21 0x20 30 0o23 100 8} -} {8 0o23 21 30 0x20 35 100} + lsort -integer {35 21 0x20 0d30 0o23 100 8} +} {8 0o23 21 0d30 0x20 35 100} test cmdIL-3.12 {SortCompare procedure, -real option} -body { lsort -real {6...4 3} } -returnCodes error -result {expected floating-point number but got "6...4"} diff --git a/tests/util.test b/tests/util.test index 22d120b..35fc642 100644 --- a/tests/util.test +++ b/tests/util.test @@ -553,6 +553,12 @@ test util-9.0.6 {TclGetIntForIndex} { test util-9.0.7 {TclGetIntForIndex} { string index abcd { 01 } } b +test util-9.0.8 {TclGetIntForIndex} { + string index abcd { 0d0 } +} a +test util-9.0.9 {TclGetIntForIndex} { + string index abcd { -0d0 } +} a test util-9.1.0 {TclGetIntForIndex} { string index abcd 3 } d @@ -565,6 +571,12 @@ test util-9.1.2 {TclGetIntForIndex} { test util-9.1.3 {TclGetIntForIndex} { string index abcdefghijk { 0xa } } k +test util-9.1.4 {TclGetIntForIndex} { + string index abcdefghijk 0d10 +} k +test util-9.1.5 {TclGetIntForIndex} { + string index abcdefghijk { 0d10 } +} k test util-9.2.0 {TclGetIntForIndex} { string index abcd end } d @@ -672,12 +684,18 @@ test util-9.30 {TclGetIntForIndex} -body { test util-9.31 {TclGetIntForIndex} -body { string index a 0x } -returnCodes error -match glob -result * +test util-9.31.1 {TclGetIntForIndex} -body { + string index a 0d +} -returnCodes error -match glob -result * test util-9.32 {TclGetIntForIndex} -body { string index a 0x1FFFFFFFF+0 } -returnCodes error -match glob -result * test util-9.33 {TclGetIntForIndex} -body { string index a 100000000000+0 } -returnCodes error -match glob -result * +test util-9.33.1 {TclGetIntForIndex} -body { + string index a 0d100000000000+0 +} -returnCodes error -match glob -result * test util-9.34 {TclGetIntForIndex} -body { string index a 1.0 } -returnCodes error -match glob -result * -- cgit v0.12 From 919fc5759927c4b114ccc7771b7bcf6193fb5b42 Mon Sep 17 00:00:00 2001 From: griffin Date: Sun, 28 May 2017 16:06:29 +0000 Subject: 0d in LinkVar --- generic/tclLink.c | 4 ++-- tests/link.test | 21 +++++++++++++++++++++ 2 files changed, 23 insertions(+), 2 deletions(-) diff --git a/generic/tclLink.c b/generic/tclLink.c index a39dfcd..7366acc 100644 --- a/generic/tclLink.c +++ b/generic/tclLink.c @@ -692,7 +692,7 @@ SetInvalidRealFromAny(Tcl_Interp *interp, Tcl_Obj *objPtr) { /* * This function checks for integer representations, which are valid * when linking with C variables, but which are invalid in other - * contexts in Tcl. Handled are "+", "-", "", "0x", "0b" and "0o" + * contexts in Tcl. Handled are "+", "-", "", "0x", "0b", "0d" and "0o" * (upperand lowercase). See bug [39f6304c2e]. */ int @@ -701,7 +701,7 @@ GetInvalidIntFromObj(Tcl_Obj *objPtr, int *intPtr) const char *str = TclGetString(objPtr); if ((objPtr->length == 0) || - ((objPtr->length == 2) && (str[0] == '0') && strchr("xXbBoO", str[1]))) { + ((objPtr->length == 2) && (str[0] == '0') && strchr("xXbBoOdD", str[1]))) { *intPtr = 0; return TCL_OK; } else if ((objPtr->length == 1) && strchr("+-", str[0])) { diff --git a/tests/link.test b/tests/link.test index 6bff356..a12759d 100644 --- a/tests/link.test +++ b/tests/link.test @@ -173,6 +173,27 @@ test link-2.9 {writing C variables from Tcl} -constraints {testlink} -setup { set uwide 0 concat [testlink get] | $int $real $bool $string $wide $char $uchar $short $ushort $uint $long $ulong $float $uwide } -result {0 5000.0 0 0 0 0 0 0 0 0 0 0 -60.0 0 | 0 5000e 0 0 0 0 0 0 0 0 0 0 -60.00e+ 0} +test link-2.10 {writing C variables from Tcl} -constraints {testlink} -setup { + testlink delete +} -body { + testlink set 43 1.21 4 - 56785678 64 250 30000 60000 0xbaadbeef 12321 32123 3.25 1231231234 + testlink create 1 1 1 1 1 1 1 1 1 1 1 1 1 1 + set int "0x" + set real "0b" + set bool 0 + set string "0" + set wide "0D" + set char "0X" + set uchar "0B" + set short "0D" + set ushort "0x" + set uint "0b" + set long "0d" + set ulong "0X" + set float "0B" + set uwide "0D" + concat [testlink get] | $int $real $bool $string $wide $char $uchar $short $ushort $uint $long $ulong $float $uwide +} -result {0 0.0 0 0 0 0 0 0 0 0 0 0 0.0 0 | 0x 0b 0 0 0D 0X 0B 0D 0x 0b 0d 0X 0B 0D} test link-3.1 {read-only variables} -constraints {testlink} -setup { testlink delete -- cgit v0.12 From e5726b43396ad7e3356c453ed8ae75c7349e6707 Mon Sep 17 00:00:00 2001 From: "jan.nijtmans" Date: Mon, 29 May 2017 13:10:30 +0000 Subject: Tcl_UtfToUniChar() -> TclUtfToUniChar() in various places: No change in functionality, just faster if ASCII only strings are involved. --- generic/tclBinary.c | 6 ++--- generic/tclCmdIL.c | 4 +-- generic/tclCompExpr.c | 4 +-- generic/tclEncoding.c | 4 +-- generic/tclLoad.c | 2 +- generic/tclParse.c | 4 +-- generic/tclScan.c | 66 +++++++++++++++++++++++++------------------------- generic/tclStringObj.c | 26 ++++++++++---------- win/tclWinPipe.c | 2 +- 9 files changed, 59 insertions(+), 59 deletions(-) diff --git a/generic/tclBinary.c b/generic/tclBinary.c index 2a4fd84..d0d9d5e 100644 --- a/generic/tclBinary.c +++ b/generic/tclBinary.c @@ -462,7 +462,7 @@ SetByteArrayFromAny( byteArrayPtr = ckalloc(BYTEARRAY_SIZE(length)); for (dst = byteArrayPtr->bytes; src < srcEnd; ) { - src += Tcl_UtfToUniChar(src, &ch); + src += TclUtfToUniChar(src, &ch); *dst++ = UCHAR(ch); } @@ -1213,7 +1213,7 @@ BinaryFormatCmd( Tcl_UniChar ch; char buf[TCL_UTF_MAX + 1]; - Tcl_UtfToUniChar(errorString, &ch); + TclUtfToUniChar(errorString, &ch); buf[Tcl_UniCharToUtf(ch, buf)] = '\0'; Tcl_SetObjResult(interp, Tcl_ObjPrintf( "bad field specifier \"%s\"", buf)); @@ -1583,7 +1583,7 @@ BinaryScanCmd( Tcl_UniChar ch; char buf[TCL_UTF_MAX + 1]; - Tcl_UtfToUniChar(errorString, &ch); + TclUtfToUniChar(errorString, &ch); buf[Tcl_UniCharToUtf(ch, buf)] = '\0'; Tcl_SetObjResult(interp, Tcl_ObjPrintf( "bad field specifier \"%s\"", buf)); diff --git a/generic/tclCmdIL.c b/generic/tclCmdIL.c index 9fbb0ad..bcf4434 100644 --- a/generic/tclCmdIL.c +++ b/generic/tclCmdIL.c @@ -4415,8 +4415,8 @@ DictionaryCompare( */ if ((*left != '\0') && (*right != '\0')) { - left += Tcl_UtfToUniChar(left, &uniLeft); - right += Tcl_UtfToUniChar(right, &uniRight); + left += TclUtfToUniChar(left, &uniLeft); + right += TclUtfToUniChar(right, &uniRight); /* * Convert both chars to lower for the comparison, because diff --git a/generic/tclCompExpr.c b/generic/tclCompExpr.c index 4390282..59eecf9 100644 --- a/generic/tclCompExpr.c +++ b/generic/tclCompExpr.c @@ -2064,13 +2064,13 @@ ParseLexeme( if (!TclIsBareword(*start) || *start == '_') { if (Tcl_UtfCharComplete(start, numBytes)) { - scanned = Tcl_UtfToUniChar(start, &ch); + scanned = TclUtfToUniChar(start, &ch); } else { char utfBytes[TCL_UTF_MAX]; memcpy(utfBytes, start, (size_t) numBytes); utfBytes[numBytes] = '\0'; - scanned = Tcl_UtfToUniChar(utfBytes, &ch); + scanned = TclUtfToUniChar(utfBytes, &ch); } *lexemePtr = INVALID; Tcl_DecrRefCount(literal); diff --git a/generic/tclEncoding.c b/generic/tclEncoding.c index 6820faa..b4acb5f 100644 --- a/generic/tclEncoding.c +++ b/generic/tclEncoding.c @@ -2344,7 +2344,7 @@ UtfToUtfProc( src += 2; } else if (!Tcl_UtfCharComplete(src, srcEnd - src)) { /* - * Always check before using Tcl_UtfToUniChar. Not doing can so + * Always check before using TclUtfToUniChar. Not doing can so * cause it run beyond the endof the buffer! If we happen such an * incomplete char its byts are made to represent themselves. */ @@ -2353,7 +2353,7 @@ UtfToUtfProc( src += 1; dst += Tcl_UniCharToUtf(ch, dst); } else { - src += Tcl_UtfToUniChar(src, &ch); + src += TclUtfToUniChar(src, &ch); dst += Tcl_UniCharToUtf(ch, dst); } } diff --git a/generic/tclLoad.c b/generic/tclLoad.c index 7c70e03..942e6b4 100644 --- a/generic/tclLoad.c +++ b/generic/tclLoad.c @@ -336,7 +336,7 @@ Tcl_LoadObjCmd( } #endif /* __CYGWIN__ */ for (p = pkgGuess; *p != 0; p += offset) { - offset = Tcl_UtfToUniChar(p, &ch); + offset = TclUtfToUniChar(p, &ch); if ((ch > 0x100) || !(isalpha(UCHAR(ch)) /* INTL: ISO only */ || (UCHAR(ch) == '_'))) { diff --git a/generic/tclParse.c b/generic/tclParse.c index ce87fb0..3ecf4a5 100644 --- a/generic/tclParse.c +++ b/generic/tclParse.c @@ -975,13 +975,13 @@ TclParseBackslash( */ if (Tcl_UtfCharComplete(p, numBytes - 1)) { - count = Tcl_UtfToUniChar(p, &unichar) + 1; /* +1 for '\' */ + count = TclUtfToUniChar(p, &unichar) + 1; /* +1 for '\' */ } else { char utfBytes[TCL_UTF_MAX]; memcpy(utfBytes, p, (size_t) (numBytes - 1)); utfBytes[numBytes - 1] = '\0'; - count = Tcl_UtfToUniChar(utfBytes, &unichar) + 1; + count = TclUtfToUniChar(utfBytes, &unichar) + 1; } result = unichar; break; diff --git a/generic/tclScan.c b/generic/tclScan.c index 3edb8be..17069eb 100644 --- a/generic/tclScan.c +++ b/generic/tclScan.c @@ -78,11 +78,11 @@ BuildCharSet( memset(cset, 0, sizeof(CharSet)); - offset = Tcl_UtfToUniChar(format, &ch); + offset = TclUtfToUniChar(format, &ch); if (ch == '^') { cset->exclude = 1; format += offset; - offset = Tcl_UtfToUniChar(format, &ch); + offset = TclUtfToUniChar(format, &ch); } end = format + offset; @@ -91,14 +91,14 @@ BuildCharSet( */ if (ch == ']') { - end += Tcl_UtfToUniChar(end, &ch); + end += TclUtfToUniChar(end, &ch); } nranges = 0; while (ch != ']') { if (ch == '-') { nranges++; } - end += Tcl_UtfToUniChar(end, &ch); + end += TclUtfToUniChar(end, &ch); } cset->chars = ckalloc(sizeof(Tcl_UniChar) * (end - format - 1)); @@ -113,11 +113,11 @@ BuildCharSet( */ cset->nchars = cset->nranges = 0; - format += Tcl_UtfToUniChar(format, &ch); + format += TclUtfToUniChar(format, &ch); start = ch; if (ch == ']' || ch == '-') { cset->chars[cset->nchars++] = ch; - format += Tcl_UtfToUniChar(format, &ch); + format += TclUtfToUniChar(format, &ch); } while (ch != ']') { if (*format == '-') { @@ -138,7 +138,7 @@ BuildCharSet( cset->chars[cset->nchars++] = start; cset->chars[cset->nchars++] = ch; } else { - format += Tcl_UtfToUniChar(format, &ch); + format += TclUtfToUniChar(format, &ch); /* * Check to see if the range is in reverse order. @@ -156,7 +156,7 @@ BuildCharSet( } else { cset->chars[cset->nchars++] = ch; } - format += Tcl_UtfToUniChar(format, &ch); + format += TclUtfToUniChar(format, &ch); } return format; } @@ -279,20 +279,20 @@ ValidateFormat( xpgSize = objIndex = gotXpg = gotSequential = 0; while (*format != '\0') { - format += Tcl_UtfToUniChar(format, &ch); + format += TclUtfToUniChar(format, &ch); flags = 0; if (ch != '%') { continue; } - format += Tcl_UtfToUniChar(format, &ch); + format += TclUtfToUniChar(format, &ch); if (ch == '%') { continue; } if (ch == '*') { flags |= SCAN_SUPPRESS; - format += Tcl_UtfToUniChar(format, &ch); + format += TclUtfToUniChar(format, &ch); goto xpgCheckDone; } @@ -308,7 +308,7 @@ ValidateFormat( goto notXpg; } format = end+1; - format += Tcl_UtfToUniChar(format, &ch); + format += TclUtfToUniChar(format, &ch); gotXpg = 1; if (gotSequential) { goto mixedXPG; @@ -347,7 +347,7 @@ ValidateFormat( if ((ch < 0x80) && isdigit(UCHAR(ch))) { /* INTL: "C" locale. */ value = strtoul(format-1, (char **) &format, 10); /* INTL: "C" locale. */ flags |= SCAN_WIDTH; - format += Tcl_UtfToUniChar(format, &ch); + format += TclUtfToUniChar(format, &ch); } /* @@ -359,13 +359,13 @@ ValidateFormat( if (*format == 'l') { flags |= SCAN_BIG; format += 1; - format += Tcl_UtfToUniChar(format, &ch); + format += TclUtfToUniChar(format, &ch); break; } case 'L': flags |= SCAN_LONGER; case 'h': - format += Tcl_UtfToUniChar(format, &ch); + format += TclUtfToUniChar(format, &ch); } if (!(flags & SCAN_SUPPRESS) && numVars && (objIndex >= numVars)) { @@ -434,24 +434,24 @@ ValidateFormat( if (*format == '\0') { goto badSet; } - format += Tcl_UtfToUniChar(format, &ch); + format += TclUtfToUniChar(format, &ch); if (ch == '^') { if (*format == '\0') { goto badSet; } - format += Tcl_UtfToUniChar(format, &ch); + format += TclUtfToUniChar(format, &ch); } if (ch == ']') { if (*format == '\0') { goto badSet; } - format += Tcl_UtfToUniChar(format, &ch); + format += TclUtfToUniChar(format, &ch); } while (ch != ']') { if (*format == '\0') { goto badSet; } - format += Tcl_UtfToUniChar(format, &ch); + format += TclUtfToUniChar(format, &ch); } break; badSet: @@ -630,7 +630,7 @@ Tcl_ScanObjCmd( nconversions = 0; while (*format != '\0') { int parseFlag = TCL_PARSE_NO_WHITESPACE; - format += Tcl_UtfToUniChar(format, &ch); + format += TclUtfToUniChar(format, &ch); flags = 0; @@ -639,13 +639,13 @@ Tcl_ScanObjCmd( */ if (Tcl_UniCharIsSpace(ch)) { - offset = Tcl_UtfToUniChar(string, &sch); + offset = TclUtfToUniChar(string, &sch); while (Tcl_UniCharIsSpace(sch)) { if (*string == '\0') { goto done; } string += offset; - offset = Tcl_UtfToUniChar(string, &sch); + offset = TclUtfToUniChar(string, &sch); } continue; } @@ -656,14 +656,14 @@ Tcl_ScanObjCmd( underflow = 1; goto done; } - string += Tcl_UtfToUniChar(string, &sch); + string += TclUtfToUniChar(string, &sch); if (ch != sch) { goto done; } continue; } - format += Tcl_UtfToUniChar(format, &ch); + format += TclUtfToUniChar(format, &ch); if (ch == '%') { goto literal; } @@ -675,13 +675,13 @@ Tcl_ScanObjCmd( if (ch == '*') { flags |= SCAN_SUPPRESS; - format += Tcl_UtfToUniChar(format, &ch); + format += TclUtfToUniChar(format, &ch); } else if ((ch < 0x80) && isdigit(UCHAR(ch))) { /* INTL: "C" locale. */ char *formatEnd; value = strtoul(format-1, &formatEnd, 10);/* INTL: "C" locale. */ if (*formatEnd == '$') { format = formatEnd+1; - format += Tcl_UtfToUniChar(format, &ch); + format += TclUtfToUniChar(format, &ch); objIndex = (int) value - 1; } } @@ -692,7 +692,7 @@ Tcl_ScanObjCmd( if ((ch < 0x80) && isdigit(UCHAR(ch))) { /* INTL: "C" locale. */ width = (int) strtoul(format-1, (char **) &format, 10);/* INTL: "C" locale. */ - format += Tcl_UtfToUniChar(format, &ch); + format += TclUtfToUniChar(format, &ch); } else { width = 0; } @@ -706,7 +706,7 @@ Tcl_ScanObjCmd( if (*format == 'l') { flags |= SCAN_BIG; format += 1; - format += Tcl_UtfToUniChar(format, &ch); + format += TclUtfToUniChar(format, &ch); break; } case 'L': @@ -715,7 +715,7 @@ Tcl_ScanObjCmd( * Fall through so we skip to the next character. */ case 'h': - format += Tcl_UtfToUniChar(format, &ch); + format += TclUtfToUniChar(format, &ch); } /* @@ -799,7 +799,7 @@ Tcl_ScanObjCmd( if (!(flags & SCAN_NOSKIP)) { while (*string != '\0') { - offset = Tcl_UtfToUniChar(string, &sch); + offset = TclUtfToUniChar(string, &sch); if (!Tcl_UniCharIsSpace(sch)) { break; } @@ -826,7 +826,7 @@ Tcl_ScanObjCmd( } end = string; while (*end != '\0') { - offset = Tcl_UtfToUniChar(end, &sch); + offset = TclUtfToUniChar(end, &sch); if (Tcl_UniCharIsSpace(sch)) { break; } @@ -854,7 +854,7 @@ Tcl_ScanObjCmd( format = BuildCharSet(&cset, format); while (*end != '\0') { - offset = Tcl_UtfToUniChar(end, &sch); + offset = TclUtfToUniChar(end, &sch); if (!CharInSet(&cset, (int)sch)) { break; } @@ -885,7 +885,7 @@ Tcl_ScanObjCmd( * Scan a single Unicode character. */ - string += Tcl_UtfToUniChar(string, &sch); + string += TclUtfToUniChar(string, &sch); if (!(flags & SCAN_SUPPRESS)) { objPtr = Tcl_NewIntObj((int)sch); Tcl_IncrRefCount(objPtr); diff --git a/generic/tclStringObj.c b/generic/tclStringObj.c index 4e19750..4a3b6f1 100644 --- a/generic/tclStringObj.c +++ b/generic/tclStringObj.c @@ -1710,7 +1710,7 @@ Tcl_AppendFormatToObj( int newXpg, numChars, allocSegment = 0, segmentLimit, segmentNumBytes; Tcl_Obj *segment; Tcl_UniChar ch; - int step = Tcl_UtfToUniChar(format, &ch); + int step = TclUtfToUniChar(format, &ch); format += step; if (ch != '%') { @@ -1734,7 +1734,7 @@ Tcl_AppendFormatToObj( * Step 0. Handle special case of escaped format marker (i.e., %%). */ - step = Tcl_UtfToUniChar(format, &ch); + step = TclUtfToUniChar(format, &ch); if (ch == '%') { span = format; numBytes = step; @@ -1754,7 +1754,7 @@ Tcl_AppendFormatToObj( newXpg = 1; objIndex = position - 1; format = end + 1; - step = Tcl_UtfToUniChar(format, &ch); + step = TclUtfToUniChar(format, &ch); } } if (newXpg) { @@ -1805,7 +1805,7 @@ Tcl_AppendFormatToObj( } if (sawFlag) { format += step; - step = Tcl_UtfToUniChar(format, &ch); + step = TclUtfToUniChar(format, &ch); } } while (sawFlag); @@ -1817,7 +1817,7 @@ Tcl_AppendFormatToObj( if (isdigit(UCHAR(ch))) { width = strtoul(format, &end, 10); format = end; - step = Tcl_UtfToUniChar(format, &ch); + step = TclUtfToUniChar(format, &ch); } else if (ch == '*') { if (objIndex >= objc - 1) { msg = badIndex[gotXpg]; @@ -1833,7 +1833,7 @@ Tcl_AppendFormatToObj( } objIndex++; format += step; - step = Tcl_UtfToUniChar(format, &ch); + step = TclUtfToUniChar(format, &ch); } if (width > limit) { msg = overflow; @@ -1849,12 +1849,12 @@ Tcl_AppendFormatToObj( if (ch == '.') { gotPrecision = 1; format += step; - step = Tcl_UtfToUniChar(format, &ch); + step = TclUtfToUniChar(format, &ch); } if (isdigit(UCHAR(ch))) { precision = strtoul(format, &end, 10); format = end; - step = Tcl_UtfToUniChar(format, &ch); + step = TclUtfToUniChar(format, &ch); } else if (ch == '*') { if (objIndex >= objc - 1) { msg = badIndex[gotXpg]; @@ -1875,7 +1875,7 @@ Tcl_AppendFormatToObj( } objIndex++; format += step; - step = Tcl_UtfToUniChar(format, &ch); + step = TclUtfToUniChar(format, &ch); } /* @@ -1885,14 +1885,14 @@ Tcl_AppendFormatToObj( if (ch == 'h') { useShort = 1; format += step; - step = Tcl_UtfToUniChar(format, &ch); + step = TclUtfToUniChar(format, &ch); } else if (ch == 'l') { format += step; - step = Tcl_UtfToUniChar(format, &ch); + step = TclUtfToUniChar(format, &ch); if (ch == 'l') { useBig = 1; format += step; - step = Tcl_UtfToUniChar(format, &ch); + step = TclUtfToUniChar(format, &ch); #ifndef TCL_WIDE_INT_IS_LONG } else { useWide = 1; @@ -2767,7 +2767,7 @@ TclStringObjReverse( * It's part of the contract for objPtr->bytes values. * Thus, we can skip calling Tcl_UtfCharComplete() here. */ - int bytesInChar = Tcl_UtfToUniChar(from, &ch); + int bytesInChar = TclUtfToUniChar(from, &ch); ReverseBytes((unsigned char *)to, (unsigned char *)from, bytesInChar); diff --git a/win/tclWinPipe.c b/win/tclWinPipe.c index 5246d53..fe0ed2d 100644 --- a/win/tclWinPipe.c +++ b/win/tclWinPipe.c @@ -1482,7 +1482,7 @@ BuildCommandLine( Tcl_UniChar ch; for (start = arg; *start != '\0'; start += count) { - count = Tcl_UtfToUniChar(start, &ch); + count = TclUtfToUniChar(start, &ch); if (Tcl_UniCharIsSpace(ch)) { /* INTL: ISO space. */ quote = 1; break; -- cgit v0.12 From 9220ca224bafcb35a09f48838501d36ab69762e9 Mon Sep 17 00:00:00 2001 From: sebres Date: Mon, 29 May 2017 19:36:31 +0000 Subject: fixed [a3fb3356b76ec4a853d1b86aadc08675f8bef359]: segfault by sorting of the large lists (firstly mistakenly introduced in [af40c6fb6940bab7]), additionally simplify done-points in Tcl_LsortObjCmd. --- generic/tclCmdIL.c | 37 ++++++++++++++++++------------------- 1 file changed, 18 insertions(+), 19 deletions(-) diff --git a/generic/tclCmdIL.c b/generic/tclCmdIL.c index bcf4434..ba9e1cf 100644 --- a/generic/tclCmdIL.c +++ b/generic/tclCmdIL.c @@ -3657,7 +3657,7 @@ Tcl_LsortObjCmd( int sortMode = SORTMODE_ASCII; int group, groupSize, groupOffset, idx, allocatedIndexVector = 0; Tcl_Obj *resultPtr, *cmdPtr, **listObjPtrs, *listObj, *indexPtr; - SortElement *elementArray, *elementPtr; + SortElement *elementArray = NULL, *elementPtr; SortInfo sortInfo; /* Information about this sort that needs to * be passed to the comparison function. */ # define NUM_LISTS 30 @@ -3703,7 +3703,7 @@ Tcl_LsortObjCmd( if (Tcl_GetIndexFromObj(interp, objv[i], switches, "option", 0, &index) != TCL_OK) { sortInfo.resultCode = TCL_ERROR; - goto done2; + goto done; } switch ((enum Lsort_Switches) index) { case LSORT_ASCII: @@ -3716,7 +3716,7 @@ Tcl_LsortObjCmd( "by comparison command", -1)); Tcl_SetErrorCode(interp, "TCL", "ARGUMENT", "MISSING", NULL); sortInfo.resultCode = TCL_ERROR; - goto done2; + goto done; } sortInfo.sortMode = SORTMODE_COMMAND; cmdPtr = objv[i+1]; @@ -3741,12 +3741,12 @@ Tcl_LsortObjCmd( -1)); Tcl_SetErrorCode(interp, "TCL", "ARGUMENT", "MISSING", NULL); sortInfo.resultCode = TCL_ERROR; - goto done2; + goto done; } if (TclListObjGetElements(interp, objv[i+1], &indexc, &indexv) != TCL_OK) { sortInfo.resultCode = TCL_ERROR; - goto done2; + goto done; } /* @@ -3763,7 +3763,7 @@ Tcl_LsortObjCmd( Tcl_AppendObjToErrorInfo(interp, Tcl_ObjPrintf( "\n (-index option item number %d)", j)); sortInfo.resultCode = TCL_ERROR; - goto done2; + goto done; } } indexPtr = objv[i+1]; @@ -3792,11 +3792,11 @@ Tcl_LsortObjCmd( "followed by stride length", -1)); Tcl_SetErrorCode(interp, "TCL", "ARGUMENT", "MISSING", NULL); sortInfo.resultCode = TCL_ERROR; - goto done2; + goto done; } if (Tcl_GetIntFromObj(interp, objv[i+1], &groupSize) != TCL_OK) { sortInfo.resultCode = TCL_ERROR; - goto done2; + goto done; } if (groupSize < 2) { Tcl_SetObjResult(interp, Tcl_NewStringObj( @@ -3804,7 +3804,7 @@ Tcl_LsortObjCmd( Tcl_SetErrorCode(interp, "TCL", "OPERATION", "LSORT", "BADSTRIDE", NULL); sortInfo.resultCode = TCL_ERROR; - goto done2; + goto done; } group = 1; i++; @@ -3859,7 +3859,7 @@ Tcl_LsortObjCmd( listObj = TclListObjCopy(interp, listObj); if (listObj == NULL) { sortInfo.resultCode = TCL_ERROR; - goto done2; + goto done; } /* @@ -3877,7 +3877,7 @@ Tcl_LsortObjCmd( Tcl_IncrRefCount(newObjPtr); TclDecrRefCount(newObjPtr); sortInfo.resultCode = TCL_ERROR; - goto done2; + goto done; } Tcl_ListObjAppendElement(interp, newCommandPtr, Tcl_NewObj()); sortInfo.compareCmdPtr = newCommandPtr; @@ -3970,7 +3970,7 @@ Tcl_LsortObjCmd( * begins sorting it into the sublists as it appears. */ - elementArray = TclStackAlloc(interp, length * sizeof(SortElement)); + elementArray = ckalloc(length * sizeof(SortElement)); for (i=0; i < length; i++){ idx = groupSize * i + groupOffset; @@ -3980,7 +3980,7 @@ Tcl_LsortObjCmd( */ indexPtr = SelectObjFromSublist(listObjPtrs[idx], &sortInfo); if (sortInfo.resultCode != TCL_OK) { - goto done1; + goto done; } } else { indexPtr = listObjPtrs[idx]; @@ -3997,7 +3997,7 @@ Tcl_LsortObjCmd( if (TclGetWideIntFromObj(sortInfo.interp, indexPtr, &a) != TCL_OK) { sortInfo.resultCode = TCL_ERROR; - goto done1; + goto done; } elementArray[i].collationKey.wideValue = a; } else if (sortMode == SORTMODE_REAL) { @@ -4006,7 +4006,7 @@ Tcl_LsortObjCmd( if (Tcl_GetDoubleFromObj(sortInfo.interp, indexPtr, &a) != TCL_OK) { sortInfo.resultCode = TCL_ERROR; - goto done1; + goto done; } elementArray[i].collationKey.doubleValue = a; } else { @@ -4093,19 +4093,18 @@ Tcl_LsortObjCmd( Tcl_SetObjResult(interp, resultPtr); } - done1: - TclStackFree(interp, elementArray); - done: if (sortMode == SORTMODE_COMMAND) { TclDecrRefCount(sortInfo.compareCmdPtr); TclDecrRefCount(listObj); sortInfo.compareCmdPtr = NULL; } - done2: if (allocatedIndexVector) { TclStackFree(interp, sortInfo.indexv); } + if (elementArray) { + ckfree(elementArray); + } return sortInfo.resultCode; } -- cgit v0.12 From ece8767c5cb0fc27a64b43df3c4558f14d3f5408 Mon Sep 17 00:00:00 2001 From: sebres Date: Tue, 30 May 2017 08:46:12 +0000 Subject: small code review: resolves several warning on some compilers --- generic/tclClock.c | 6 +++--- generic/tclClockFmt.c | 8 ++++---- generic/tclDate.h | 2 +- generic/tclStrIdxTree.c | 4 ++-- 4 files changed, 10 insertions(+), 10 deletions(-) diff --git a/generic/tclClock.c b/generic/tclClock.c index c980a27..0895bbb 100644 --- a/generic/tclClock.c +++ b/generic/tclClock.c @@ -606,7 +606,7 @@ ClockMCDict(ClockFmtScnCmdArgs *opts) if (opts->localeObj == NULL) { Tcl_SetResult(opts->interp, - "locale not specified and no default locale set", TCL_STATIC); + (char*)"locale not specified and no default locale set", TCL_STATIC); Tcl_SetErrorCode(opts->interp, "CLOCK", "badOption", NULL); return NULL; } @@ -3080,7 +3080,7 @@ ClockParseFmtScnArgs( if ((saw & (1 << CLC_ARGS_GMT)) && (saw & (1 << CLC_ARGS_TIMEZONE))) { - Tcl_SetResult(interp, "cannot use -gmt and -timezone in same call", TCL_STATIC); + Tcl_SetResult(interp, (char*)"cannot use -gmt and -timezone in same call", TCL_STATIC); Tcl_SetErrorCode(interp, "CLOCK", "gmtWithTimezone", NULL); return TCL_ERROR; } @@ -3335,7 +3335,7 @@ ClockScanObjCmd( /* [SB] TODO: Perhaps someday we'll localize the legacy code. Right now, it's not localized. */ if (opts.localeObj != NULL) { Tcl_SetResult(interp, - "legacy [clock scan] does not support -locale", TCL_STATIC); + (char*)"legacy [clock scan] does not support -locale", TCL_STATIC); Tcl_SetErrorCode(interp, "CLOCK", "flagWithLegacyFormat", NULL); return TCL_ERROR; } diff --git a/generic/tclClockFmt.c b/generic/tclClockFmt.c index d923ede..0ec8817 100644 --- a/generic/tclClockFmt.c +++ b/generic/tclClockFmt.c @@ -607,7 +607,7 @@ static void ClockFmtObj_UpdateString(objPtr) Tcl_Obj *objPtr; { - char *name = "UNKNOWN"; + const char *name = "UNKNOWN"; int len; ClockFmtScnStorage *fss = ObjClockFmtScn(objPtr); @@ -1450,7 +1450,7 @@ ClockScnToken_DayOfWeek_Proc(ClockFmtScnCmdArgs *opts, val = 7; } if (val > 7) { - Tcl_SetResult(opts->interp, "day of week is greater than 7", + Tcl_SetResult(opts->interp, (char*)"day of week is greater than 7", TCL_STATIC); Tcl_SetErrorCode(opts->interp, "CLOCK", "badDayOfWeek", NULL); return TCL_ERROR; @@ -2400,14 +2400,14 @@ ClockScan( overflow: - Tcl_SetResult(opts->interp, "requested date too large to represent", + Tcl_SetResult(opts->interp, (char*)"requested date too large to represent", TCL_STATIC); Tcl_SetErrorCode(opts->interp, "CLOCK", "dateTooLarge", NULL); goto done; not_match: - Tcl_SetResult(opts->interp, "input string does not match supplied format", + Tcl_SetResult(opts->interp, (char*)"input string does not match supplied format", TCL_STATIC); Tcl_SetErrorCode(opts->interp, "CLOCK", "badInputString", NULL); diff --git a/generic/tclDate.h b/generic/tclDate.h index e614f9d..abc231b 100644 --- a/generic/tclDate.h +++ b/generic/tclDate.h @@ -370,7 +370,7 @@ typedef struct ClockScanTokenMap { unsigned short int maxSize; unsigned short int offs; ClockScanTokenProc *parser; - void *data; + const void *data; } ClockScanTokenMap; typedef struct ClockScanToken { diff --git a/generic/tclStrIdxTree.c b/generic/tclStrIdxTree.c index 291e481..0045ea5 100644 --- a/generic/tclStrIdxTree.c +++ b/generic/tclStrIdxTree.c @@ -469,7 +469,7 @@ TclStrIdxTreeTestObjCmd( int optionIndex; if (objc < 2) { - Tcl_SetResult(interp, "wrong # args", TCL_STATIC); + Tcl_SetResult(interp, (char*)"wrong # args", TCL_STATIC); return TCL_ERROR; } if (Tcl_GetIndexFromObj(interp, objv[1], options, @@ -481,7 +481,7 @@ TclStrIdxTreeTestObjCmd( switch (optionIndex) { case O_FINDEQUAL: if (objc < 4) { - Tcl_SetResult(interp, "wrong # args", TCL_STATIC); + Tcl_SetResult(interp, (char*)"wrong # args", TCL_STATIC); return TCL_ERROR; } cs = TclGetString(objv[2]); -- cgit v0.12 From 777941e35bfc3de3b0ec36322ddbd9953169ad2f Mon Sep 17 00:00:00 2001 From: sebres Date: Tue, 30 May 2017 16:41:48 +0000 Subject: [msgcat] revert changes of "msgcat" to previous state before clock-speedup, move this functionality to "clock.tcl"; additionally avoids the usage of catch (uses pair "dict exists/dict get" instead of). --- library/clock.tcl | 98 +++++++++++++++++++++++++++++++++--- library/msgcat/msgcat.tcl | 125 ++-------------------------------------------- tests/msgcat.test | 2 +- 3 files changed, 98 insertions(+), 127 deletions(-) diff --git a/library/clock.tcl b/library/clock.tcl index 94d2341..1f3c669 100644 --- a/library/clock.tcl +++ b/library/clock.tcl @@ -506,18 +506,103 @@ proc ::tcl::clock::Initialize {} { variable FormatProc; # Array mapping format group # and locale to the name of a procedure # that renders the given format + + variable mcLocales [dict create]; # Dictionary with loaded locales + variable mcMergedCat [dict create]; # Dictionary with merged locale catalogs } ::tcl::clock::Initialize #---------------------------------------------------------------------- -proc mcget {locale args} { - switch -- $locale system { - set locale [GetSystemLocale] +# mcget -- +# +# Return the merged translation catalog for the ::tcl::clock namespace +# Searching of catalog is similar to "msgcat::mc". +# +# Contrary to "msgcat::mc" may additionally load a package catalog +# on demand. +# +# Arguments: +# loc The locale used for translation. +# +# Results: +# Returns the dictionary object as whole catalog of the package/locale. +# +proc mcget {loc} { + variable mcMergedCat + switch -- $loc system { + set loc [GetSystemLocale] } current { - set locale [mclocale] + set loc [mclocale] + } + if {$loc eq {C}} { + set loclist [msgcat::PackagePreferences ::tcl::clock] + set loc [lindex $loclist 0] + } else { + set loc [string tolower $loc] + } + + # try to retrieve now if already available: + if {[dict exists $mcMergedCat $loc]} { + set mrgcat [dict get $mcMergedCat $loc] + return [dict smartref $mrgcat] + } + + # get locales list for given locale (de_de -> {de_de de {}}) + variable mcLocales + if {[dict exists $mcLocales $loc]} { + set loclist [dict get $mcLocales $loc] + } else { + # save current locale: + set prevloc [mclocale] + # lazy load catalog on demand (set it will load the catalog) + mcpackagelocale set $loc + set loclist [msgcat::GetPreferences $loc] + dict set $mcLocales $loc $loclist + # restore: + if {$prevloc ne $loc} { + mcpackagelocale set $prevloc + } + } + # get whole catalog: + mcMerge $loclist +} + +# mcMerge -- +# +# Merge message catalog dictionaries to one dictionary. +# +# Arguments: +# locales List of locales to merge. +# +# Results: +# Returns the (weak pointer) to merged dictionary of message catalog. +# +proc mcMerge {locales} { + variable mcMergedCat + if {[dict exists $mcMergedCat [set loc [lindex $locales 0]]]} { + set mrgcat [dict get $mcMergedCat $loc] + return [dict smartref $mrgcat] + } + # package msgcat currently does not provide possibility to get whole catalog: + upvar ::msgcat::Msgs Msgs + set ns ::tcl::clock + # Merge sequential locales (in reverse order, e. g. {} -> en -> en_en): + if {[llength $locales] > 1} { + set mrgcat [mcMerge [lrange $locales 1 end]] + if {[dict exists $Msgs $ns $loc]} { + set mrgcat [dict merge $mrgcat [dict get $Msgs $ns $loc]] + } + } else { + if {[dict exists $Msgs $ns $loc]} { + set mrgcat [dict get $Msgs $ns $loc] + } else { + set mrgcat [dict create] + } } - msgcat::mcget ::tcl::clock $locale {*}$args + dict set mcMergedCat $loc $mrgcat + # return smart reference (shared dict as object with exact one ref-counter) + return [dict smartref $mrgcat] } #---------------------------------------------------------------------- @@ -2004,13 +2089,14 @@ proc ::tcl::clock::ClearCaches {} { variable FormatProc variable LocaleFormats variable LocaleNumeralCache + variable mcMergedCat variable TimeZoneBad # tell backend - should invalidate: configure -clear # clear msgcat cache: - msgcat::ClearCaches ::tcl::clock + set mcMergedCat [dict create] foreach p [info procs [namespace current]::scanproc'*] { rename $p {} diff --git a/library/msgcat/msgcat.tcl b/library/msgcat/msgcat.tcl index f9f57db..928474d 100644 --- a/library/msgcat/msgcat.tcl +++ b/library/msgcat/msgcat.tcl @@ -225,65 +225,6 @@ proc msgcat::mc {src args} { } } -# msgcat::mcget -- -# -# Return the translation for the given string based on the given -# locale setting or the whole dictionary object of the package/locale. -# Searching of catalog is similar to "msgcat::mc". -# -# Contrary to "msgcat::mc" may additionally load a package catalog -# on demand. -# -# Arguments: -# ns The package namespace (as catalog selector). -# loc The locale used for 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::mcget {ns loc args} { - if {$loc eq {C}} { - set loclist [PackagePreferences $ns] - set loc [lindex $loclist 0] - } else { - set loc [string tolower $loc] - variable PackageConfig - # get locales list for given locale (de_de -> {de_de de {}}) - if {[catch { - set loclist [dict get $PackageConfig locales $ns $loc] - }]} { - # lazy load catalog on demand - mcpackagelocale load $loc $ns - set loclist [dict get $PackageConfig locales $ns $loc] - } - } - if {![llength $args]} { - # get whole catalog: - return [msgcat::Merge $ns $loclist] - } - set src [lindex $args 0] - # search translation for each locale (regarding parent namespaces) - for {set nscur $ns} {$nscur != ""} {set nscur [namespace parent $nscur]} { - foreach loc $loclist { - set msgs [mcget $nscur $loc] - if {![catch { set val [dict get $msgs $src] }]} { - if {[llength $args] == 1} { - return $val - } - return [format $val {*}[lrange $args 1 end]] - } - } - } - # no translation : - if {[llength $args] == 1} { - return $src - } - return [format $src {*}[lrange $args 1 end]] -} - # msgcat::mcexists -- # # Check if a catalog item is set or if mc would invoke mcunknown. @@ -474,10 +415,6 @@ proc msgcat::mcloadedlocales {subcommand} { # items, if the former locale was the default locale. # Returns the normalized set locale. # The default locale is taken, if locale is not given. -# load -# Load a package locale without set it (lazy loading from mcget). -# Returns the normalized set locale. -# The default locale is taken, if locale is not given. # get # Get the locale valid for this package. # isset @@ -505,7 +442,7 @@ proc msgcat::mcloadedlocales {subcommand} { # Results: # Empty string, if not stated differently for the subcommand -proc msgcat::mcpackagelocale {subcommand {locale ""} {ns ""}} { +proc msgcat::mcpackagelocale {subcommand {locale ""}} { # todo: implement using an ensemble variable Loclist variable LoadedLocales @@ -525,9 +462,7 @@ proc msgcat::mcpackagelocale {subcommand {locale ""} {ns ""}} { } set locale [string tolower $locale] } - if {$ns eq ""} { - set ns [uplevel 1 {::namespace current}] - } + set ns [uplevel 1 {::namespace current}] switch -exact -- $subcommand { get { return [lindex [PackagePreferences $ns] 0] } @@ -535,7 +470,7 @@ proc msgcat::mcpackagelocale {subcommand {locale ""} {ns ""}} { loaded { return [PackageLocales $ns] } present { return [expr {$locale in [PackageLocales $ns]} ]} isset { return [dict exists $PackageConfig loclist $ns] } - set - load { # set a package locale or add a package locale + set { # set a package locale or add a package locale # Copy the default locale if no package locale set so far if {![dict exists $PackageConfig loclist $ns]} { @@ -545,21 +480,17 @@ proc msgcat::mcpackagelocale {subcommand {locale ""} {ns ""}} { # Check if changed set loclist [dict get $PackageConfig loclist $ns] - if {[llength [info level 0]] == 2 || $locale eq [lindex $loclist 0] } { + if {! [info exists locale] || $locale eq [lindex $loclist 0] } { return [lindex $loclist 0] } # Change loclist set loclist [GetPreferences $locale] set locale [lindex $loclist 0] - if {$subcommand eq {set}} { - # set loclist - dict set PackageConfig loclist $ns $loclist - } + dict set PackageConfig loclist $ns $loclist # load eventual missing locales set loadedLocales [dict get $PackageConfig loadedlocales $ns] - dict set PackageConfig locales $ns $locale $loclist if {$locale in $loadedLocales} { return $locale } set loadLocales [ListComplement $loadedLocales $loclist] dict set PackageConfig loadedlocales $ns\ @@ -590,7 +521,6 @@ proc msgcat::mcpackagelocale {subcommand {locale ""} {ns ""}} { [dict get $PackageConfig loadedlocales $ns] $LoadedLocales] dict unset PackageConfig loadedlocales $ns dict unset PackageConfig loclist $ns - dict unset PackageConfig locales $ns # unset keys not in global loaded locales if {[dict exists $Msgs $ns]} { @@ -917,47 +847,6 @@ proc msgcat::Load {ns locales {callbackonly 0}} { return $x } -# msgcat::Merge -- -# -# Merge message catalog dictionaries to one dictionary. -# -# Arguments: -# ns Namespace (equal package) to load the message catalog. -# locales List of locales to merge. -# -# Results: -# Returns the merged dictionary of message catalogs. -proc msgcat::Merge {ns locales} { - variable Merged - if {![catch { - set mrgcat [dict get $Merged $ns [set loc [lindex $locales 0]]] - }]} { - return $mrgcat - } - variable Msgs - # Merge sequential locales (in reverse order, e. g. {} -> en -> en_en): - if {[llength $locales] > 1} { - set mrgcat [msgcat::Merge $ns [lrange $locales 1 end]] - catch { - set mrgcat [dict merge $mrgcat [dict get $Msgs $ns $loc]] - } - } else { - if {[catch { - set mrgcat [dict get $Msgs $ns $loc] - }]} { - set mrgcat [dict create] - } - } - dict set Merged $ns $loc $mrgcat - # return smart reference (shared dict as object with exact one ref-counter) - return [dict smartref $mrgcat] -} - -proc msgcat::ClearCaches {ns} { - variable Merged - dict unset Merged $ns -} - # msgcat::Invoke -- # # Invoke a set of registered callbacks. @@ -1030,7 +919,6 @@ proc msgcat::Invoke {index arglist {ns ""} {resultname ""} {failerror 0}} { proc msgcat::mcset {locale src {dest ""}} { variable Msgs - variable Merged if {[llength [info level 0]] == 3} { ;# dest not specified set dest $src } @@ -1040,7 +928,6 @@ proc msgcat::mcset {locale src {dest ""}} { set locale [string tolower $locale] dict set Msgs $ns $locale $src $dest - dict unset Merged $ns return $dest } @@ -1080,7 +967,6 @@ proc msgcat::mcflset {src {dest ""}} { proc msgcat::mcmset {locale pairs} { variable Msgs - variable Merged set length [llength $pairs] if {$length % 2} { @@ -1094,7 +980,6 @@ proc msgcat::mcmset {locale pairs} { foreach {src dest} $pairs { dict set Msgs $ns $locale $src $dest } - dict unset Merged $ns return [expr {$length / 2}] } diff --git a/tests/msgcat.test b/tests/msgcat.test index 584e420..1c3ce58 100644 --- a/tests/msgcat.test +++ b/tests/msgcat.test @@ -811,7 +811,7 @@ namespace eval ::msgcat::test { test msgcat-12.1 {mcpackagelocale no subcommand} -body { mcpackagelocale } -returnCodes 1\ - -result {wrong # args: should be "mcpackagelocale subcommand ?locale? ?ns?"} + -result {wrong # args: should be "mcpackagelocale subcommand ?locale?"} test msgcat-12.2 {mclpackagelocale wrong subcommand} -body { mcpackagelocale junk -- cgit v0.12 From 73b3bf53adc72f6c32efe40bccb4fbff9d0c4aeb Mon Sep 17 00:00:00 2001 From: stu Date: Wed, 31 May 2017 05:39:57 +0000 Subject: Fully remove SunOS-4* from tcl.m4. --- unix/configure | 7 ------- unix/tcl.m4 | 8 ++------ 2 files changed, 2 insertions(+), 13 deletions(-) diff --git a/unix/configure b/unix/configure index dfeb036..bef7c84 100755 --- a/unix/configure +++ b/unix/configure @@ -9971,13 +9971,6 @@ $as_echo "#define USE_FIONBIO 1" >>confdefs.h { $as_echo "$as_me:${as_lineno-$LINENO}: result: FIONBIO" >&5 $as_echo "FIONBIO" >&6; } ;; - SunOS-4*) - -$as_echo "#define USE_FIONBIO 1" >>confdefs.h - - { $as_echo "$as_me:${as_lineno-$LINENO}: result: FIONBIO" >&5 -$as_echo "FIONBIO" >&6; } - ;; *) { $as_echo "$as_me:${as_lineno-$LINENO}: result: O_NONBLOCK" >&5 $as_echo "O_NONBLOCK" >&6; } diff --git a/unix/tcl.m4 b/unix/tcl.m4 index e21cc20..2fc82e5 100644 --- a/unix/tcl.m4 +++ b/unix/tcl.m4 @@ -971,8 +971,8 @@ AC_DEFUN([SC_CONFIG_SYSTEM], [ # shared libraries. The value of the symbol defaults to # "${LIBS}" if all of the dependent libraries should # be specified when creating a shared library. If -# dependent libraries should not be specified (as on -# SunOS 4.x, where they cause the link to fail, or in +# dependent libraries should not be specified (as on some +# SunOS systems, where they cause the link to fail, or in # general if Tcl and Tk aren't themselves shared # libraries), then this symbol has an empty string # as its value. @@ -2222,10 +2222,6 @@ AC_DEFUN([SC_BLOCKING_STYLE], [ AC_DEFINE(USE_FIONBIO, 1, [Should we use FIONBIO?]) AC_MSG_RESULT([FIONBIO]) ;; - SunOS-4*) - AC_DEFINE(USE_FIONBIO, 1, [Should we use FIONBIO?]) - AC_MSG_RESULT([FIONBIO]) - ;; *) AC_MSG_RESULT([O_NONBLOCK]) ;; -- cgit v0.12 From c05da96a3570bf04aa35293399fdca615ff2e04e Mon Sep 17 00:00:00 2001 From: stu Date: Wed, 31 May 2017 06:10:46 +0000 Subject: Unbreak on OpenBSD, again. Put back the old SHLIB_VERSION doings. On OpenBSD, Tcl's libs will need the extra version numbers probably forever. There's no point to adding the extra knob. On OpenBSD, the extra version numbers are used for dependency tracking. The extra version numbers must be on linkable libs (code will be linked to them, they have a corresponding .h file). Loadable libs (no code will be linked to them, they don't have a corresponding .h file. Usually a Tcl extension) don't need the burden (OpenBSD has to track the libs' dependencies) of the extra version numbers. Libs that are loadable and linkable are treated as linkable. I hope that clears things up. --- unix/configure | 4 +--- unix/tcl.m4 | 2 +- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/unix/configure b/unix/configure index bef7c84..a9132b57 100755 --- a/unix/configure +++ b/unix/configure @@ -5085,9 +5085,7 @@ fi PLAT_SRCS="" LDAIX_SRC="" if test "x${SHLIB_VERSION}" = x; then : - SHLIB_VERSION=".1.0" -else - SHLIB_VERSION=".${SHLIB_VERSION}" + SHLIB_VERSION="1.0" fi case $system in AIX-*) diff --git a/unix/tcl.m4 b/unix/tcl.m4 index 2fc82e5..45922e0 100644 --- a/unix/tcl.m4 +++ b/unix/tcl.m4 @@ -1098,7 +1098,7 @@ AC_DEFUN([SC_CONFIG_CFLAGS], [ PLAT_OBJS="" PLAT_SRCS="" LDAIX_SRC="" - AS_IF([test "x${SHLIB_VERSION}" = x],[SHLIB_VERSION=".1.0"],[SHLIB_VERSION=".${SHLIB_VERSION}"]) + AS_IF([test "x${SHLIB_VERSION}" = x], [SHLIB_VERSION="1.0"]) case $system in AIX-*) AS_IF([test "${TCL_THREADS}" = "1" -a "$GCC" != "yes"], [ -- cgit v0.12 From bbb13bf5770d18267ef18b9fc47a0e198916725d Mon Sep 17 00:00:00 2001 From: sebres Date: Wed, 31 May 2017 08:24:42 +0000 Subject: performance of INST_STR_CONCAT1: closes [716b427f76f8f97a8d9a06043903c53bb2b592c2]: minor optimization in simplest cases, fixed performance regression of TclStringCatObjv usage from [fc9ed1e751180816384d569101950c1f8c4582ad], optimizes patterns like "$v[unset v]", "$v[set v {}]" etc. --- generic/tclExecute.c | 25 ++++++++++++++++++++++++- 1 file changed, 24 insertions(+), 1 deletion(-) diff --git a/generic/tclExecute.c b/generic/tclExecute.c index cfcdd26..2d1c07f 100644 --- a/generic/tclExecute.c +++ b/generic/tclExecute.c @@ -2685,11 +2685,34 @@ TEBCresume( opnd = TclGetUInt1AtPtr(pc+1); + objv = &OBJ_AT_DEPTH(opnd-1); + /* minor optimization in simplest cases */ + switch (opnd) { + case 1: /* only one object */ + objResultPtr = *objv; + goto endINST_STR_CONCAT1; + case 2: /* two objects - check empty */ + if (objv[0]->bytes == &tclEmptyString) { + objResultPtr = objv[1]; + goto endINST_STR_CONCAT1; + } + else + if (objv[1]->bytes == &tclEmptyString) { + objResultPtr = objv[0]; + goto endINST_STR_CONCAT1; + } + break; + case 0: /* no objects - use new empty */ + TclNewObj(objResultPtr); + goto endINST_STR_CONCAT1; + } + /* do concat */ if (TCL_OK != TclStringCatObjv(interp, /* inPlace */ 1, - opnd, &OBJ_AT_DEPTH(opnd-1), &objResultPtr)) { + opnd, objv, &objResultPtr)) { TRACE_ERROR(interp); goto gotError; } + endINST_STR_CONCAT1: TRACE_WITH_OBJ(("%u => ", opnd), objResultPtr); NEXT_INST_V(2, opnd, 1); -- cgit v0.12 From 60c071ed625b30818a7151b4e77272f8fe55edb3 Mon Sep 17 00:00:00 2001 From: "jan.nijtmans" Date: Wed, 31 May 2017 08:31:10 +0000 Subject: Remove "timerate" functionality: this definitely needs a TIP. Also undo changes in library/reg/pkgIndex.tcl, which are unrelated to clock functionality --- generic/tclBasic.c | 1 - generic/tclCmdMZ.c | 348 +---------------------------------------------- generic/tclInt.h | 3 - library/reg/pkgIndex.tcl | 12 +- 4 files changed, 2 insertions(+), 362 deletions(-) diff --git a/generic/tclBasic.c b/generic/tclBasic.c index 4d392d0..0486383 100644 --- a/generic/tclBasic.c +++ b/generic/tclBasic.c @@ -285,7 +285,6 @@ static const CmdInfo builtInCmds[] = { {"source", Tcl_SourceObjCmd, NULL, TclNRSourceObjCmd, 0}, {"tell", Tcl_TellObjCmd, NULL, NULL, CMD_IS_SAFE}, {"time", Tcl_TimeObjCmd, NULL, NULL, CMD_IS_SAFE}, - {"timerate", Tcl_TimeRateObjCmd, NULL, NULL, CMD_IS_SAFE}, {"unload", Tcl_UnloadObjCmd, NULL, NULL, 0}, {"update", Tcl_UpdateObjCmd, NULL, NULL, CMD_IS_SAFE}, {"vwait", Tcl_VwaitObjCmd, NULL, NULL, CMD_IS_SAFE}, diff --git a/generic/tclCmdMZ.c b/generic/tclCmdMZ.c index 8c2c026..885a0bc 100644 --- a/generic/tclCmdMZ.c +++ b/generic/tclCmdMZ.c @@ -17,7 +17,6 @@ */ #include "tclInt.h" -#include "tclCompile.h" #include "tclRegexp.h" #include "tclStringTrim.h" @@ -4147,7 +4146,7 @@ Tcl_TimeObjCmd( start = TclpGetWideClicks(); #endif while (i-- > 0) { - result = TclEvalObjEx(interp, objPtr, 0, NULL, 0); + result = Tcl_EvalObjEx(interp, objPtr, 0); if (result != TCL_OK) { return result; } @@ -4187,351 +4186,6 @@ Tcl_TimeObjCmd( /* *---------------------------------------------------------------------- * - * Tcl_TimeRateObjCmd -- - * - * This object-based procedure is invoked to process the "timerate" Tcl - * command. - * This is similar to command "time", except the execution limited by - * given time (in milliseconds) instead of repetition count. - * - * Example: - * timerate {after 5} 1000 ; # equivalent for `time {after 5} [expr 1000/5]` - * - * Results: - * A standard Tcl object result. - * - * Side effects: - * See the user documentation. - * - *---------------------------------------------------------------------- - */ - -int -Tcl_TimeRateObjCmd( - ClientData dummy, /* Not used. */ - Tcl_Interp *interp, /* Current interpreter. */ - int objc, /* Number of arguments. */ - Tcl_Obj *const objv[]) /* Argument objects. */ -{ - static - double measureOverhead = 0; /* global measure-overhead */ - double overhead = -1; /* given measure-overhead */ - register Tcl_Obj *objPtr; - register int result, i; - Tcl_Obj *calibrate = NULL, *direct = NULL; - Tcl_WideInt count = 0; /* Holds repetition count */ - Tcl_WideInt maxms = -0x7FFFFFFFFFFFFFFFL; - /* Maximal running time (in milliseconds) */ - Tcl_WideInt threshold = 1; /* Current threshold for check time (faster - * repeat count without time check) */ - Tcl_WideInt maxIterTm = 1; /* Max time of some iteration as max threshold - * additionally avoid divide to zero (never < 1) */ - register Tcl_WideInt start, middle, stop; -#ifndef TCL_WIDE_CLICKS - Tcl_Time now; -#endif - - static const char *const options[] = { - "-direct", "-overhead", "-calibrate", "--", NULL - }; - enum options { - TMRT_EV_DIRECT, TMRT_OVERHEAD, TMRT_CALIBRATE, TMRT_LAST - }; - - NRE_callback *rootPtr; - ByteCode *codePtr = NULL; - - for (i = 1; i < objc - 1; i++) { - int index; - if (Tcl_GetIndexFromObj(NULL, objv[i], options, "option", TCL_EXACT, - &index) != TCL_OK) { - break; - } - if (index == TMRT_LAST) { - i++; - break; - } - switch (index) { - case TMRT_EV_DIRECT: - direct = objv[i]; - break; - case TMRT_OVERHEAD: - if (++i >= objc - 1) { - goto usage; - } - if (Tcl_GetDoubleFromObj(interp, objv[i], &overhead) != TCL_OK) { - return TCL_ERROR; - } - break; - case TMRT_CALIBRATE: - calibrate = objv[i]; - break; - } - } - - if (i >= objc || i < objc-2) { -usage: - Tcl_WrongNumArgs(interp, 1, objv, "?-direct? ?-calibrate? ?-overhead double? command ?time?"); - return TCL_ERROR; - } - objPtr = objv[i++]; - if (i < objc) { - result = TclGetWideIntFromObj(interp, objv[i], &maxms); - if (result != TCL_OK) { - return result; - } - } - - /* if calibrate */ - if (calibrate) { - - /* if no time specified for the calibration */ - if (maxms == -0x7FFFFFFFFFFFFFFFL) { - Tcl_Obj *clobjv[6]; - Tcl_WideInt maxCalTime = 5000; - double lastMeasureOverhead = measureOverhead; - - clobjv[0] = objv[0]; - i = 1; - if (direct) { - clobjv[i++] = direct; - } - clobjv[i++] = objPtr; - - /* reset last measurement overhead */ - measureOverhead = (double)0; - - /* self-call with 100 milliseconds to warm-up, - * before entering the calibration cycle */ - TclNewLongObj(clobjv[i], 100); - Tcl_IncrRefCount(clobjv[i]); - result = Tcl_TimeRateObjCmd(dummy, interp, i+1, clobjv); - Tcl_DecrRefCount(clobjv[i]); - if (result != TCL_OK) { - return result; - } - - i--; - clobjv[i++] = calibrate; - clobjv[i++] = objPtr; - - /* set last measurement overhead to max */ - measureOverhead = (double)0x7FFFFFFFFFFFFFFFL; - - /* calibration cycle until it'll be preciser */ - maxms = -1000; - do { - lastMeasureOverhead = measureOverhead; - TclNewLongObj(clobjv[i], (int)maxms); - Tcl_IncrRefCount(clobjv[i]); - result = Tcl_TimeRateObjCmd(dummy, interp, i+1, clobjv); - Tcl_DecrRefCount(clobjv[i]); - if (result != TCL_OK) { - return result; - } - maxCalTime += maxms; - /* increase maxms for preciser calibration */ - maxms -= (-maxms / 4); - /* as long as new value more as 0.05% better */ - } while ( (measureOverhead >= lastMeasureOverhead - || measureOverhead / lastMeasureOverhead <= 0.9995) - && maxCalTime > 0 - ); - - return result; - } - if (maxms == 0) { - /* reset last measurement overhead */ - measureOverhead = 0; - Tcl_SetObjResult(interp, Tcl_NewLongObj(0)); - return TCL_OK; - } - - /* if time is negative - make current overhead more precise */ - if (maxms > 0) { - /* set last measurement overhead to max */ - measureOverhead = (double)0x7FFFFFFFFFFFFFFFL; - } else { - maxms = -maxms; - } - - } - - if (maxms == -0x7FFFFFFFFFFFFFFFL) { - maxms = 1000; - } - if (overhead == -1) { - overhead = measureOverhead; - } - - /* be sure that resetting of result will not smudge the further measurement */ - Tcl_ResetResult(interp); - - /* compile object */ - if (!direct) { - if (TclInterpReady(interp) != TCL_OK) { - return TCL_ERROR; - } - codePtr = TclCompileObj(interp, objPtr, NULL, 0); - TclPreserveByteCode(codePtr); - } - - /* get start and stop time */ -#ifdef TCL_WIDE_CLICKS - start = middle = TclpGetWideClicks(); - /* time to stop execution (in wide clicks) */ - stop = start + (maxms * 1000 / TclpWideClickInMicrosec()); -#else - Tcl_GetTime(&now); - start = now.sec; start *= 1000000; start += now.usec; - middle = start; - /* time to stop execution (in microsecs) */ - stop = start + maxms * 1000; -#endif - - /* start measurement */ - while (1) { - /* eval single iteration */ - count++; - - if (!direct) { - /* precompiled */ - rootPtr = TOP_CB(interp); - result = TclNRExecuteByteCode(interp, codePtr); - result = TclNRRunCallbacks(interp, result, rootPtr); - } else { - /* eval */ - result = TclEvalObjEx(interp, objPtr, 0, NULL, 0); - } - if (result != TCL_OK) { - goto done; - } - - /* don't check time up to threshold */ - if (--threshold > 0) continue; - - /* check stop time reached, estimate new threshold */ - #ifdef TCL_WIDE_CLICKS - middle = TclpGetWideClicks(); - #else - Tcl_GetTime(&now); - middle = now.sec; middle *= 1000000; middle += now.usec; - #endif - if (middle >= stop) { - break; - } - - /* don't calculate threshold by few iterations, because sometimes - * first iteration(s) can be too fast (cached, delayed clean up, etc) */ - if (count < 10) { - threshold = 1; continue; - } - - /* average iteration time in microsecs */ - threshold = (middle - start) / count; - if (threshold > maxIterTm) { - maxIterTm = threshold; - } - /* as relation between remaining time and time since last check */ - threshold = ((stop - middle) / maxIterTm) / 4; - if (threshold > 100000) { /* fix for too large threshold */ - threshold = 100000; - } - } - - { - Tcl_Obj *objarr[8], **objs = objarr; - Tcl_WideInt val; - const char *fmt; - - middle -= start; /* execution time in microsecs */ - - #ifdef TCL_WIDE_CLICKS - /* convert execution time in wide clicks to microsecs */ - middle *= TclpWideClickInMicrosec(); - #endif - - /* if not calibrate */ - if (!calibrate) { - /* minimize influence of measurement overhead */ - if (overhead > 0) { - /* estimate the time of overhead (microsecs) */ - Tcl_WideInt curOverhead = overhead * count; - if (middle > curOverhead) { - middle -= curOverhead; - } else { - middle = 1; - } - } - } else { - /* calibration - obtaining new measurement overhead */ - if (measureOverhead > (double)middle / count) { - measureOverhead = (double)middle / count; - } - objs[0] = Tcl_NewDoubleObj(measureOverhead); - TclNewLiteralStringObj(objs[1], "\xC2\xB5s/#-overhead"); /* mics */ - objs += 2; - } - - val = middle / count; /* microsecs per iteration */ - if (val >= 1000000) { - objs[0] = Tcl_NewWideIntObj(val); - } else { - if (val < 10) { fmt = "%.6f"; } else - if (val < 100) { fmt = "%.4f"; } else - if (val < 1000) { fmt = "%.3f"; } else - if (val < 10000) { fmt = "%.2f"; } else - { fmt = "%.1f"; }; - objs[0] = Tcl_ObjPrintf(fmt, ((double)middle)/count); - } - - objs[2] = Tcl_NewWideIntObj(count); /* iterations */ - - /* calculate speed as rate (count) per sec */ - if (!middle) middle++; /* +1 ms, just to avoid divide by zero */ - if (count < (0x7FFFFFFFFFFFFFFFL / 1000000)) { - val = (count * 1000000) / middle; - if (val < 100000) { - if (val < 100) { fmt = "%.3f"; } else - if (val < 1000) { fmt = "%.2f"; } else - { fmt = "%.1f"; }; - objs[4] = Tcl_ObjPrintf(fmt, ((double)(count * 1000000)) / middle); - } else { - objs[4] = Tcl_NewWideIntObj(val); - } - } else { - objs[4] = Tcl_NewWideIntObj((count / middle) * 1000000); - } - - /* estimated net execution time (in millisecs) */ - if (!calibrate) { - objs[6] = Tcl_ObjPrintf("%.3f", (double)middle / 1000); - TclNewLiteralStringObj(objs[7], "nett-ms"); - } - - /* - * Construct the result as a list because many programs have always parsed - * as such (extracting the first element, typically). - */ - - TclNewLiteralStringObj(objs[1], "\xC2\xB5s/#"); /* mics/# */ - TclNewLiteralStringObj(objs[3], "#"); - TclNewLiteralStringObj(objs[5], "#/sec"); - Tcl_SetObjResult(interp, Tcl_NewListObj(8, objarr)); - } - -done: - - if (codePtr != NULL) { - TclReleaseByteCode(codePtr); - } - - return result; -} - -/* - *---------------------------------------------------------------------- - * * Tcl_TryObjCmd, TclNRTryObjCmd -- * * This procedure is invoked to process the "try" Tcl command. See the diff --git a/generic/tclInt.h b/generic/tclInt.h index 333a665..5bd4324 100644 --- a/generic/tclInt.h +++ b/generic/tclInt.h @@ -3437,9 +3437,6 @@ MODULE_SCOPE int Tcl_ThrowObjCmd(ClientData dummy, Tcl_Interp *interp, MODULE_SCOPE int Tcl_TimeObjCmd(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *const objv[]); -MODULE_SCOPE int Tcl_TimeRateObjCmd(ClientData clientData, - Tcl_Interp *interp, int objc, - Tcl_Obj *const objv[]); MODULE_SCOPE int Tcl_TraceObjCmd(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *const objv[]); diff --git a/library/reg/pkgIndex.tcl b/library/reg/pkgIndex.tcl index ab022ab..b1fe234 100755 --- a/library/reg/pkgIndex.tcl +++ b/library/reg/pkgIndex.tcl @@ -1,19 +1,9 @@ if {([info commands ::tcl::pkgconfig] eq "") - || ([info sharedlibextension] ne ".dll")} return + || ([info sharedlibextension] ne ".dll")} return if {[::tcl::pkgconfig get debug]} { - if {[info exists [file join $dir tclreg13g.dll]]} { package ifneeded registry 1.3.2 \ [list load [file join $dir tclreg13g.dll] registry] - } else { - package ifneeded registry 1.3.2 \ - [list load tclreg13g registry] - } } else { - if {[info exists [file join $dir tclreg13.dll]]} { package ifneeded registry 1.3.2 \ [list load [file join $dir tclreg13.dll] registry] - } else { - package ifneeded registry 1.3.2 \ - [list load tclreg13 registry] - } } -- cgit v0.12 From 4a9ae53836f768d0b615e5f98cedfb9dd5fbac7f Mon Sep 17 00:00:00 2001 From: "jan.nijtmans" Date: Wed, 31 May 2017 08:59:28 +0000 Subject: More code review, e.g. use Tcl_SetObjResult in stead of Tcl_SetResult, preventing a (char *) type case. No functional changes. --- generic/tclClock.c | 176 +++++++++++++++++------------------ generic/tclClockFmt.c | 239 ++++++++++++++++++++++++------------------------ generic/tclDate.c | 12 +-- generic/tclDate.h | 10 +- generic/tclEnsemble.c | 4 +- generic/tclEnv.c | 2 +- generic/tclGetDate.y | 2 +- generic/tclInt.h | 2 +- generic/tclStrIdxTree.c | 36 ++++---- generic/tclStrIdxTree.h | 8 +- library/clock.tcl | 16 ++-- library/init.tcl | 6 +- unix/tclUnixTime.c | 2 +- win/tclWinTime.c | 8 +- 14 files changed, 261 insertions(+), 262 deletions(-) diff --git a/generic/tclClock.c b/generic/tclClock.c index 0895bbb..95b3e36 100644 --- a/generic/tclClock.c +++ b/generic/tclClock.c @@ -96,8 +96,8 @@ static int ClockConvertlocaltoutcObjCmd( ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *const objv[]); -static int ClockGetDateFields(ClientData clientData, - Tcl_Interp *interp, TclDateFields *fields, +static int ClockGetDateFields(ClientData clientData, + Tcl_Interp *interp, TclDateFields *fields, Tcl_Obj *timezoneObj, int changeover); static int ClockGetdatefieldsObjCmd( ClientData clientData, Tcl_Interp *interp, @@ -130,7 +130,7 @@ static int ClockScanCommit( ClientData clientData, register DateInfo *info, register ClockFmtScnCmdArgs *opts); static int ClockFreeScan( - register DateInfo *info, + register DateInfo *info, Tcl_Obj *strObj, ClockFmtScnCmdArgs *opts); static int ClockCalcRelTime( register DateInfo *info, ClockFmtScnCmdArgs *opts); @@ -267,10 +267,10 @@ TclClockInit( clientData = data; data->refCount++; } - cmdPtr = (Command *)Tcl_CreateObjCommand(interp, cmdName, + cmdPtr = (Command *)Tcl_CreateObjCommand(interp, cmdName, clockCmdPtr->objCmdProc, clientData, clockCmdPtr->clientData ? NULL : ClockDeleteCmdProc); - cmdPtr->compileProc = clockCmdPtr->compileProc ? + cmdPtr->compileProc = clockCmdPtr->compileProc ? clockCmdPtr->compileProc : TclCompileBasicMin0ArgCmd; } } @@ -386,7 +386,7 @@ NormTimezoneObj( { const char *tz; if ( timezoneObj == dataPtr->LastUnnormSetupTimeZone - && dataPtr->LastSetupTimeZone != NULL + && dataPtr->LastSetupTimeZone != NULL ) { return dataPtr->LastSetupTimeZone; } @@ -468,7 +468,7 @@ static inline Tcl_Obj * ClockGetCurrentLocale( ClockClientData *dataPtr, /* Client data containing literal pool */ Tcl_Interp *interp) /* Tcl interpreter */ -{ +{ if (Tcl_EvalObjv(interp, 1, &dataPtr->literals[LIT_GETCURRENTLOCALE], 0) != TCL_OK) { return NULL; } @@ -504,7 +504,7 @@ NormLocaleObj( { const char *loc; if ( localeObj == NULL || localeObj == dataPtr->CurrentLocale - || localeObj == dataPtr->literals[LIT_C] + || localeObj == dataPtr->literals[LIT_C] || localeObj == dataPtr->literals[LIT_CURRENT] ) { if (dataPtr->CurrentLocale == NULL) { @@ -555,8 +555,8 @@ NormLocaleObj( } *mcDictObj = dataPtr->CurrentLocaleDict; localeObj = dataPtr->CurrentLocale; - } - else + } + else if ( (localeObj->length == 6 /* system */ && strncasecmp(loc, Literals[LIT_SYSTEM], localeObj->length) == 0) @@ -565,8 +565,8 @@ NormLocaleObj( localeObj = ClockGetSystemLocale(dataPtr, interp); Tcl_SetObjRef(dataPtr->LastUsedLocale, localeObj); *mcDictObj = NULL; - } - else + } + else { *mcDictObj = NULL; } @@ -578,7 +578,7 @@ NormLocaleObj( * * ClockMCDict -- * - * Retrieves a localized storage dictionary object for the given + * Retrieves a localized storage dictionary object for the given * locale object. * * This corresponds with call `::tcl::clock::mcget locale`. @@ -600,13 +600,13 @@ ClockMCDict(ClockFmtScnCmdArgs *opts) /* if locale was not yet used */ if ( !(opts->flags & CLF_LOCALE_USED) ) { - + opts->localeObj = NormLocaleObj(opts->clientData, opts->interp, opts->localeObj, &opts->mcDictObj); - + if (opts->localeObj == NULL) { - Tcl_SetResult(opts->interp, - (char*)"locale not specified and no default locale set", TCL_STATIC); + Tcl_SetObjResult(opts->interp, + Tcl_NewStringObj("locale not specified and no default locale set", -1)); Tcl_SetErrorCode(opts->interp, "CLOCK", "badOption", NULL); return NULL; } @@ -617,7 +617,7 @@ ClockMCDict(ClockFmtScnCmdArgs *opts) int i; dataPtr->mcLiterals = ckalloc(MCLIT__END * sizeof(Tcl_Obj*)); for (i = 0; i < MCLIT__END; ++i) { - Tcl_InitObjRef(dataPtr->mcLiterals[i], + Tcl_InitObjRef(dataPtr->mcLiterals[i], Tcl_NewStringObj(MsgCtLiterals[i], -1)); } } @@ -672,7 +672,7 @@ ClockMCDict(ClockFmtScnCmdArgs *opts) MODULE_SCOPE Tcl_Obj * ClockMCGet( - ClockFmtScnCmdArgs *opts, + ClockFmtScnCmdArgs *opts, int mcKey) { ClockClientData *dataPtr = opts->clientData; @@ -685,7 +685,7 @@ ClockMCGet( return NULL; } - Tcl_DictObjGet(opts->interp, opts->mcDictObj, + Tcl_DictObjGet(opts->interp, opts->mcDictObj, dataPtr->mcLiterals[mcKey], &valObj); return valObj; /* or NULL in obscure case if Tcl_DictObjGet failed */ @@ -708,7 +708,7 @@ ClockMCGet( MODULE_SCOPE Tcl_Obj * ClockMCGetIdx( - ClockFmtScnCmdArgs *opts, + ClockFmtScnCmdArgs *opts, int mcKey) { ClockClientData *dataPtr = opts->clientData; @@ -725,8 +725,8 @@ ClockMCGetIdx( if (dataPtr->mcLitIdxs == NULL) { return NULL; } - - if (Tcl_DictObjGet(NULL, opts->mcDictObj, + + if (Tcl_DictObjGet(NULL, opts->mcDictObj, dataPtr->mcLitIdxs[mcKey], &valObj) != TCL_OK ) { return NULL; @@ -752,7 +752,7 @@ ClockMCGetIdx( MODULE_SCOPE int ClockMCSetIdx( - ClockFmtScnCmdArgs *opts, + ClockFmtScnCmdArgs *opts, int mcKey, Tcl_Obj *valObj) { ClockClientData *dataPtr = opts->clientData; @@ -768,12 +768,12 @@ ClockMCSetIdx( int i; dataPtr->mcLitIdxs = ckalloc(MCLIT__END * sizeof(Tcl_Obj*)); for (i = 0; i < MCLIT__END; ++i) { - Tcl_InitObjRef(dataPtr->mcLitIdxs[i], + Tcl_InitObjRef(dataPtr->mcLitIdxs[i], Tcl_NewStringObj(MsgCtLitIdxs[i], -1)); } } - return Tcl_DictObjPut(opts->interp, opts->mcDictObj, + return Tcl_DictObjPut(opts->interp, opts->mcDictObj, dataPtr->mcLitIdxs[mcKey], valObj); } @@ -804,7 +804,7 @@ ClockConfigureObjCmd( Tcl_Obj *const objv[]) /* Parameter vector */ { ClockClientData *dataPtr = clientData; - + static const char *const options[] = { "-system-tz", "-setup-tz", "-default-locale", "-clear", @@ -821,7 +821,7 @@ ClockConfigureObjCmd( int i; for (i = 1; i < objc; i++) { - if (Tcl_GetIndexFromObj(interp, objv[i++], options, + if (Tcl_GetIndexFromObj(interp, objv[i++], options, "option", 0, &optionIndex) != TCL_OK) { Tcl_SetErrorCode(interp, "CLOCK", "badOption", Tcl_GetString(objv[i-1]), NULL); @@ -838,8 +838,8 @@ ClockConfigureObjCmd( Tcl_UnsetObjRef(dataPtr->SystemSetupTZData); } dataPtr->LastTZEpoch = lastTZEpoch; - } - if (i+1 >= objc && dataPtr->SystemTimeZone != NULL + } + if (i+1 >= objc && dataPtr->SystemTimeZone != NULL && dataPtr->LastTZEpoch == lastTZEpoch) { Tcl_SetObjResult(interp, dataPtr->SystemTimeZone); } @@ -874,7 +874,7 @@ ClockConfigureObjCmd( Tcl_SetObjRef(dataPtr->AnySetupTimeZone, timezoneObj); Tcl_UnsetObjRef(dataPtr->AnySetupTZData); } - } + } break; } } @@ -906,7 +906,7 @@ ClockConfigureObjCmd( continue; } if (i+1 >= objc) { - Tcl_SetObjResult(interp, + Tcl_SetObjResult(interp, Tcl_NewIntObj(dataPtr->currentYearCentury)); } break; @@ -921,7 +921,7 @@ ClockConfigureObjCmd( continue; } if (i+1 >= objc) { - Tcl_SetObjResult(interp, + Tcl_SetObjResult(interp, Tcl_NewIntObj(dataPtr->yearOfCenturySwitch)); } break; @@ -978,7 +978,7 @@ ClockGetTZData( } out = &dataPtr->SystemSetupTZData; } - else + else if (timezoneObj == dataPtr->GMTSetupTimeZone) { if (dataPtr->GMTSetupTZData != NULL) { return dataPtr->GMTSetupTZData; @@ -1033,7 +1033,7 @@ ClockGetSystemTimeZone( Tcl_Obj **literals; /* if known (cached and same epoch) - return now */ - if (dataPtr->SystemTimeZone != NULL + if (dataPtr->SystemTimeZone != NULL && dataPtr->LastTZEpoch == TzsetGetEpoch()) { return dataPtr->SystemTimeZone; } @@ -1121,7 +1121,7 @@ ClockSetupTimeZone( *---------------------------------------------------------------------- */ -Tcl_Obj * +Tcl_Obj * ClockFormatNumericTimeZone(int z) { char sign = '+'; int h, m; @@ -1298,7 +1298,7 @@ ClockGetdatefieldsObjCmd( /* Extract fields */ - if (ClockGetDateFields(clientData, interp, &fields, objv[2], + if (ClockGetDateFields(clientData, interp, &fields, objv[2], changeover) != TCL_OK) { return TCL_ERROR; } @@ -1344,8 +1344,8 @@ ClockGetdatefieldsObjCmd( * * ClockGetDateFields -- * - * Converts given UTC time (seconds in a TclDateFields structure) - * to local time and determines the values that clock routines will + * Converts given UTC time (seconds in a TclDateFields structure) + * to local time and determines the values that clock routines will * use in scanning or formatting a date. * * Results: @@ -1704,7 +1704,7 @@ ConvertLocalToUTC( return TCL_ERROR; }; } else { - if (ConvertLocalToUTCUsingTable(interp, fields, rowc, rowv, + if (ConvertLocalToUTCUsingTable(interp, fields, rowc, rowv, dataPtr->Local2UTC.rangesVal) != TCL_OK) { return TCL_ERROR; }; @@ -1806,7 +1806,7 @@ ConvertLocalToUTCUsingTable( Tcl_WideInt backCompVal; /* check DST-hole interval contains UTC time */ TclGetWideIntFromObj(NULL, cellv[0], &backCompVal); - if ( fields->seconds >= backCompVal - fields->tzOffset + if ( fields->seconds >= backCompVal - fields->tzOffset && fields->seconds <= backCompVal + fields->tzOffset ) { row = LookupLastTransition(interp, fields->seconds, rowc, rowv); @@ -1817,7 +1817,7 @@ ConvertLocalToUTCUsingTable( } if (fields->localSeconds != fields->seconds + corrOffset) { Tcl_Panic("wrong local time %ld by LocalToUTC conversion," - " local time seems to be in between DST-hole", + " local time seems to be in between DST-hole", fields->localSeconds); /* correcting offset * / fields->tzOffset -= corrOffset; @@ -1943,8 +1943,8 @@ ConvertUTCToLocal( Tcl_Obj **rowv; /* Pointers to the rows */ /* fast phase-out for shared GMT-object (don't need to convert UTC 2 UTC) */ - if (timezoneObj == dataPtr->GMTSetupTimeZone - && dataPtr->GMTSetupTimeZone != NULL + if (timezoneObj == dataPtr->GMTSetupTimeZone + && dataPtr->GMTSetupTimeZone != NULL && dataPtr->GMTSetupTZData != NULL ) { fields->localSeconds = fields->seconds; @@ -2001,7 +2001,7 @@ ConvertUTCToLocal( return TCL_ERROR; } } else { - if (ConvertUTCToLocalUsingTable(interp, fields, rowc, rowv, + if (ConvertUTCToLocalUsingTable(interp, fields, rowc, rowv, dataPtr->UTC2Local.rangesVal) != TCL_OK) { return TCL_ERROR; } @@ -2993,7 +2993,7 @@ static int ClockParseFmtScnArgs( register ClockFmtScnCmdArgs *opts, /* Result vector: format, locale, timezone... */ - TclDateFields *date, /* Extracted date-time corresponding base + TclDateFields *date, /* Extracted date-time corresponding base * (by scan or add) resp. clockval (by format) */ int objc, /* Parameter count */ Tcl_Obj *const objv[], /* Parameter vector */ @@ -3034,14 +3034,14 @@ ClockParseFmtScnArgs( } } /* get option */ - if (Tcl_GetIndexFromObj(interp, objv[i], options, + if (Tcl_GetIndexFromObj(interp, objv[i], options, "option", 0, &optionIndex) != TCL_OK) { goto badOption; } /* if already specified */ if (saw & (1 << optionIndex)) { Tcl_SetObjResult(interp, Tcl_ObjPrintf( - "bad option \"%s\": doubly present", + "bad option \"%s\": doubly present", TclGetString(objv[i])) ); goto badOption; @@ -3080,7 +3080,7 @@ ClockParseFmtScnArgs( if ((saw & (1 << CLC_ARGS_GMT)) && (saw & (1 << CLC_ARGS_TIMEZONE))) { - Tcl_SetResult(interp, (char*)"cannot use -gmt and -timezone in same call", TCL_STATIC); + Tcl_SetObjResult(interp, Tcl_NewStringObj("cannot use -gmt and -timezone in same call", -1)); Tcl_SetErrorCode(interp, "CLOCK", "gmtWithTimezone", NULL); return TCL_ERROR; } @@ -3091,7 +3091,7 @@ ClockParseFmtScnArgs( /* If time zone not specified use system time zone */ if ( opts->timezoneObj == NULL - || TclGetString(opts->timezoneObj) == NULL + || TclGetString(opts->timezoneObj) == NULL || opts->timezoneObj->length == 0 ) { opts->timezoneObj = ClockGetSystemTimeZone(opts->clientData, interp); @@ -3178,7 +3178,7 @@ baseNow: return TCL_OK; -badOptionMsg: +badOptionMsg: Tcl_SetObjResult(interp, Tcl_ObjPrintf( "bad option \"%s\": unexpected for command \"%s\"", @@ -3189,7 +3189,7 @@ badOption: Tcl_SetErrorCode(interp, "CLOCK", "badOption", i < objc ? Tcl_GetString(objv[i]) : NULL, NULL); - + return TCL_ERROR; } @@ -3201,7 +3201,7 @@ badOption: * * Formats a count of seconds since the Posix Epoch as a time of day. * - * The 'clock format' command formats times of day for output. Refer + * The 'clock format' command formats times of day for output. Refer * to the user documentation to see what it does. * * Results: @@ -3313,7 +3313,7 @@ ClockScanObjCmd( } ClockInitDateInfo(&yy); - + /* * Extract values for the keywords. */ @@ -3334,13 +3334,13 @@ ClockScanObjCmd( /* [SB] TODO: Perhaps someday we'll localize the legacy code. Right now, it's not localized. */ if (opts.localeObj != NULL) { - Tcl_SetResult(interp, - (char*)"legacy [clock scan] does not support -locale", TCL_STATIC); + Tcl_SetObjResult(interp, + Tcl_NewStringObj("legacy [clock scan] does not support -locale", -1)); Tcl_SetErrorCode(interp, "CLOCK", "flagWithLegacyFormat", NULL); return TCL_ERROR; } ret = ClockFreeScan(&yy, objv[1], &opts); - } + } else { /* Use compiled version of Scan - */ @@ -3420,14 +3420,14 @@ ClockScanCommit( } if (info->flags & (CLF_ASSEMBLE_SECONDS|CLF_ASSEMBLE_JULIANDAY|CLF_LOCALSEC)) { - if (ConvertLocalToUTC(clientData, opts->interp, &yydate, opts->timezoneObj, + if (ConvertLocalToUTC(clientData, opts->interp, &yydate, opts->timezoneObj, GREGORIAN_CHANGE_DATE) != TCL_OK) { return TCL_ERROR; } } /* Increment UTC seconds with relative time */ - + yydate.seconds += yyRelSeconds; return TCL_OK; @@ -3452,8 +3452,8 @@ int ClockFreeScan( register DateInfo *info, /* Date fields used for parsing & converting - * simultaneously a yy-parse structure of the - * TclClockFreeScan */ + * simultaneously a yy-parse structure of the + * TclClockFreeScan */ Tcl_Obj *strObj, /* String containing the time to scan */ ClockFmtScnCmdArgs *opts) /* Command options */ { @@ -3466,15 +3466,15 @@ ClockFreeScan( * Parse the date. The parser will fill a structure "info" with date, * time, time zone, relative month/day/seconds, relative weekday, ordinal * month. - * Notice that many yy-defines point to values in the "info" or "date" - * structure, e. g. yySeconds -> info->date.secondOfDay or + * Notice that many yy-defines point to values in the "info" or "date" + * structure, e. g. yySeconds -> info->date.secondOfDay or * yySeconds -> info->date.month (same as yydate.month) */ yyInput = Tcl_GetString(strObj); if (TclClockFreeScan(interp, info) != TCL_OK) { Tcl_Obj *msg = Tcl_NewObj(); - Tcl_AppendPrintfToObj(msg, "unable to convert date-time string \"%s\": %s", + Tcl_AppendPrintfToObj(msg, "unable to convert date-time string \"%s\": %s", Tcl_GetString(strObj), TclGetString(Tcl_GetObjResult(interp))); Tcl_SetObjResult(interp, msg); goto done; @@ -3501,7 +3501,7 @@ ClockFreeScan( } /* - * If the caller supplied a time zone in the string, make it into a time + * If the caller supplied a time zone in the string, make it into a time * zone indicator of +-hhmm and setup this time zone. */ @@ -3524,8 +3524,8 @@ ClockFreeScan( info->flags |= CLF_ASSEMBLE_SECONDS; } - - /* + + /* * Assemble date, time, zone into seconds-from-epoch */ @@ -3538,8 +3538,8 @@ ClockFreeScan( yySeconds = ToSeconds(yyHour, yyMinutes, yySeconds, yyMeridian); info->flags |= CLF_ASSEMBLE_SECONDS; - } - else + } + else if ( (yyHaveDay && !yyHaveDate) || yyHaveOrdinalMonth || ( yyHaveRel @@ -3548,7 +3548,7 @@ ClockFreeScan( ) { yySeconds = 0; info->flags |= CLF_ASSEMBLE_SECONDS; - } + } else { yySeconds = yydate.localSeconds % SECONDS_PER_DAY; } @@ -3588,13 +3588,13 @@ ClockCalcRelTime( { /* * Because some calculations require in-between conversion of the - * julian day, we can repeat this processing multiple times + * julian day, we can repeat this processing multiple times */ repeat_rel: if (yyHaveRel) { - /* + /* * Relative conversion normally possible in UTC time only, because * of possible wrong local time increment if ignores in-between DST-hole. * (see test-cases clock-34.53, clock-34.54). @@ -3641,7 +3641,7 @@ repeat_rel: info->flags &= ~CLF_ASSEMBLE_JULIANDAY; } yydate.julianDay += yyRelDay; - + /* julianDay was changed, on demand (lazy) extract year, month, etc. again */ info->flags |= CLF_ASSEMBLE_DATE|CLF_ASSEMBLE_SECONDS; @@ -3652,12 +3652,12 @@ repeat_rel: * leave rest of the increment in yyRelSeconds to add it hereafter in UTC seconds */ if (yyRelSeconds) { int newSecs = yySeconds + yyRelSeconds; - + /* if seconds increment outside of current date, increment day */ if (newSecs / SECONDS_PER_DAY != yySeconds / SECONDS_PER_DAY) { - + yyRelDay += newSecs / SECONDS_PER_DAY; - yySeconds = 0; + yySeconds = 0; yyRelSeconds = newSecs % SECONDS_PER_DAY; goto repeat_rel; @@ -3738,7 +3738,7 @@ repeat_rel: * * Get offset in days for the number of week days corresponding the * given day of week (skipping Saturdays and Sundays). - * + * * * Results: * Returns a day increment adjusted the given weekdays @@ -3819,7 +3819,7 @@ ClockWeekdaysOffs( * Used to determine the Gregorian change date. * * Results: - * Returns a standard Tcl result with the given time adjusted + * Returns a standard Tcl result with the given time adjusted * by the given offset(s) in order. * * Notes: @@ -3870,7 +3870,7 @@ ClockAddObjCmd( } ClockInitDateInfo(&yy); - + /* * Extract values for the keywords. */ @@ -3883,7 +3883,7 @@ ClockAddObjCmd( } /* time together as seconds of the day */ - yySeconds = yydate.localSeconds % SECONDS_PER_DAY; + yySeconds = yydate.localSeconds % SECONDS_PER_DAY; /* seconds are in localSeconds (relative base date), so reset time here */ yyHour = 0; yyMinutes = 0; yyMeridian = MER24; @@ -3913,12 +3913,12 @@ ClockAddObjCmd( continue; } - /* if in-between conversion needed (already have relative date/time), - * correct date info, because the date may be changed, + /* if in-between conversion needed (already have relative date/time), + * correct date info, because the date may be changed, * so refresh it now */ if ( yyHaveRel - && ( unitIndex == CLC_ADD_WEEKDAYS + && ( unitIndex == CLC_ADD_WEEKDAYS /* some months can be shorter as another */ || yyRelMonth || yyRelDay /* day changed */ @@ -4050,13 +4050,13 @@ TzsetGetEpoch(void) static char* tzWas = INT2PTR(-1); /* Previous value of TZ, protected by * clockMutex. */ static long tzLastRefresh = 0; /* Used for latency before next refresh */ - static unsigned long tzWasEpoch = 0; /* Epoch, signals that TZ changed */ - static unsigned long tzEnvEpoch = 0; /* Last env epoch, for faster signaling, + static size_t tzWasEpoch = 0; /* Epoch, signals that TZ changed */ + static size_t tzEnvEpoch = 0; /* Last env epoch, for faster signaling, that TZ changed via TCL */ - + const char *tzIsNow; /* Current value of TZ */ - - /* + + /* * Prevent performance regression on some platforms by resolving of system time zone: * small latency for check whether environment was changed (once per second) * no latency if environment was chaned with tcl-env (compare both epoch values) diff --git a/generic/tclClockFmt.c b/generic/tclClockFmt.c index 0ec8817..5de05d0 100644 --- a/generic/tclClockFmt.c +++ b/generic/tclClockFmt.c @@ -50,7 +50,7 @@ static void ClockFrmScnFinalize(ClientData clientData); * pre-validated within parsing routines) * * Results: - * Returns a standard Tcl result. + * Returns a standard Tcl result. * TCL_OK - by successful conversion, TCL_ERROR by (wide) int overflow * *---------------------------------------------------------------------- @@ -59,7 +59,7 @@ static void ClockFrmScnFinalize(ClientData clientData); static inline int _str2int( int *out, - register + register const char *p, const char *e, int sign) @@ -84,12 +84,12 @@ _str2int( } *out = val; return TCL_OK; -} +} static inline int _str2wideInt( Tcl_WideInt *out, - register + register const char *p, const char *e, int sign) @@ -289,13 +289,13 @@ _witoaw( /* * Global GC as LIFO for released scan/format object storages. - * + * * Used to holds last released CLOCK_FMT_SCN_STORAGE_GC_SIZE formats * (after last reference from Tcl-object will be removed). This is helpful * to avoid continuous (re)creation and compiling by some dynamically resp. * variable format objects, that could be often reused. - * - * As long as format storage is used resp. belongs to GC, it takes place in + * + * As long as format storage is used resp. belongs to GC, it takes place in * FmtScnHashTable also. */ @@ -326,7 +326,7 @@ static struct { */ static inline void -ClockFmtScnStorageGC_In(ClockFmtScnStorage *entry) +ClockFmtScnStorageGC_In(ClockFmtScnStorage *entry) { /* add new entry */ TclSpliceIn(entry, ClockFmtScnStorage_GC.stackPtr); @@ -382,7 +382,7 @@ ClockFmtScnStorage_GC_Out(ClockFmtScnStorage *entry) * Global format storage hash table of type ClockFmtScnStorageHashKeyType * (contains list of scan/format object storages, shared across all threads). * - * Used for fast searching by format string. + * Used for fast searching by format string. */ static Tcl_HashTable FmtScnHashTable; static int initialized = 0; @@ -422,7 +422,7 @@ ClockFmtScnStorageAllocProc( const char *string = (const char *) keyPtr; Tcl_HashEntry *hPtr; - unsigned int size, + unsigned int size, allocsize = sizeof(ClockFmtScnStorage) + sizeof(Tcl_HashEntry); allocsize += (size = strlen(string) + 1); @@ -455,7 +455,7 @@ ClockFmtScnStorageAllocProc( *---------------------------------------------------------------------- */ -static void +static void ClockFmtScnStorageFreeProc( Tcl_HashEntry *hPtr) { @@ -488,10 +488,10 @@ ClockFmtScnStorageFreeProc( *---------------------------------------------------------------------- */ -static void +static void ClockFmtScnStorageDelete(ClockFmtScnStorage *fss) { Tcl_HashEntry *hPtr = HashEntry4FmtScn(fss); - /* + /* * This will delete a hash entry and call "ckfree" for storage self, if * some additionally handling required, freeEntryProc can be used instead */ @@ -499,7 +499,7 @@ ClockFmtScnStorageDelete(ClockFmtScnStorage *fss) { } -/* +/* * Derivation of tclStringHashKeyType with another allocEntryProc */ @@ -567,10 +567,10 @@ ClockFmtObj_FreeInternalRep(objPtr) #if CLOCK_FMT_SCN_STORAGE_GC_SIZE > 0 /* don't remove it right now (may be reusable), just add to GC */ ClockFmtScnStorageGC_In(fss); - #else + #else /* remove storage (format representation) */ ClockFmtScnStorageDelete(fss); - #endif + #endif } Tcl_MutexUnlock(&ClockFmtMutex); } @@ -630,7 +630,7 @@ ClockFmtObj_UpdateString(objPtr) * Retrieves format key object used to search localized format. * * This is normally stored in second pointer of internal representation. - * If format object is not localizable, it is equal the given format + * If format object is not localizable, it is equal the given format * pointer (special case to fast fallback by not-localizable formats). * * Results: @@ -655,7 +655,7 @@ ClockFrmObjGetLocFmtKey( return NULL; } } - + keyObj = ObjLocFmtKey(objPtr); if (keyObj) { return keyObj; @@ -692,7 +692,7 @@ ClockFrmObjGetLocFmtKey( static ClockFmtScnStorage * FindOrCreateFmtScnStorage( - Tcl_Interp *interp, + Tcl_Interp *interp, Tcl_Obj *objPtr) { const char *strFmt = TclGetString(objPtr); @@ -720,7 +720,7 @@ FindOrCreateFmtScnStorage( /* get or create entry (and alocate storage) */ hPtr = Tcl_CreateHashEntry(&FmtScnHashTable, strFmt, &new); if (hPtr != NULL) { - + fss = FmtScn4HashEntry(hPtr); #if CLOCK_FMT_SCN_STORAGE_GC_SIZE > 0 @@ -772,7 +772,7 @@ Tcl_GetClockFrmScnFromObj( Tcl_Obj *objPtr) { ClockFmtScnStorage *fss; - + if (objPtr->typePtr != &ClockFmtObjType) { if (ClockFmtObj_SetFromAny(interp, objPtr) != TCL_OK) { return NULL; @@ -822,7 +822,7 @@ ClockLocalizeFormat( return opts->formatObj; } - /* prevents loss of key object if the format object (where key stored) + /* prevents loss of key object if the format object (where key stored) * becomes changed (loses its internal representation during evals) */ Tcl_IncrRefCount(keyObj); @@ -833,7 +833,7 @@ ClockLocalizeFormat( } /* try to find in cache within locale mc-catalog */ - if (Tcl_DictObjGet(NULL, opts->mcDictObj, + if (Tcl_DictObjGet(NULL, opts->mcDictObj, keyObj, &valObj) != TCL_OK) { goto done; } @@ -947,7 +947,7 @@ FindTokenBegin( static void DetermineGreedySearchLen(ClockFmtScnCmdArgs *opts, - DateInfo *info, ClockScanToken *tok, + DateInfo *info, ClockScanToken *tok, int *minLenPtr, int *maxLenPtr) { register int minLen = tok->map->minSize; @@ -973,7 +973,7 @@ DetermineGreedySearchLen(ClockFmtScnCmdArgs *opts, }; if (minLen < tok->map->minSize) { minLen = tok->map->minSize; - } + } if (minLen > maxLen) { maxLen = minLen; } @@ -1032,7 +1032,7 @@ DetermineGreedySearchLen(ClockFmtScnCmdArgs *opts, * * ObjListSearch -- * - * Find largest part of the input string from start regarding min and + * Find largest part of the input string from start regarding min and * max lengths in the given list (utf-8, case sensitive). * * Results: @@ -1044,9 +1044,9 @@ DetermineGreedySearchLen(ClockFmtScnCmdArgs *opts, *---------------------------------------------------------------------- */ -static inline int -ObjListSearch(ClockFmtScnCmdArgs *opts, - DateInfo *info, int *val, +static inline int +ObjListSearch(ClockFmtScnCmdArgs *opts, + DateInfo *info, int *val, Tcl_Obj **lstv, int lstc, int minLen, int maxLen) { @@ -1091,9 +1091,9 @@ ObjListSearch(ClockFmtScnCmdArgs *opts, #if 0 /* currently unused */ -static int -LocaleListSearch(ClockFmtScnCmdArgs *opts, - DateInfo *info, int mcKey, int *val, +static int +LocaleListSearch(ClockFmtScnCmdArgs *opts, + DateInfo *info, int mcKey, int *val, int minLen, int maxLen) { Tcl_Obj **lstv; @@ -1139,7 +1139,7 @@ LocaleListSearch(ClockFmtScnCmdArgs *opts, static TclStrIdxTree * ClockMCGetListIdxTree( - ClockFmtScnCmdArgs *opts, + ClockFmtScnCmdArgs *opts, int mcKey) { TclStrIdxTree * idxTree; @@ -1166,7 +1166,7 @@ ClockMCGetListIdxTree( goto done; } - if (TclListObjGetElements(opts->interp, valObj, + if (TclListObjGetElements(opts->interp, valObj, &lstc, &lstv) != TCL_OK) { goto done; }; @@ -1196,8 +1196,8 @@ done: * Retrieves localized string indexed tree in the locale catalog for * multiple lists by literal indices mcKeys (and builds it on demand). * - * Searches localized index in locale catalog for mcKey, and if not - * yet exists, creates string indexed tree and stores it in the + * Searches localized index in locale catalog for mcKey, and if not + * yet exists, creates string indexed tree and stores it in the * locale catalog. * * Results: @@ -1211,8 +1211,8 @@ done: static TclStrIdxTree * ClockMCGetMultiListIdxTree( - ClockFmtScnCmdArgs *opts, - int mcKey, + ClockFmtScnCmdArgs *opts, + int mcKey, int *mcKeys) { TclStrIdxTree * idxTree; @@ -1241,7 +1241,7 @@ ClockMCGetMultiListIdxTree( goto done; } - if (TclListObjGetElements(opts->interp, valObj, + if (TclListObjGetElements(opts->interp, valObj, &lstc, &lstv) != TCL_OK) { goto done; }; @@ -1275,7 +1275,7 @@ done: * * Results: * TCL_OK - match found and the index stored in *val, - * TCL_RETURN - not matched or ambigous, + * TCL_RETURN - not matched or ambigous, * TCL_ERROR - in error case. * * Side effects: @@ -1285,15 +1285,15 @@ done: */ static inline int -ClockStrIdxTreeSearch(ClockFmtScnCmdArgs *opts, - DateInfo *info, TclStrIdxTree *idxTree, int *val, +ClockStrIdxTreeSearch(ClockFmtScnCmdArgs *opts, + DateInfo *info, TclStrIdxTree *idxTree, int *val, int minLen, int maxLen) { const char *f; TclStrIdx *foundItem; - f = TclStrIdxTreeSearch(NULL, &foundItem, idxTree, + f = TclStrIdxTreeSearch(NULL, &foundItem, idxTree, yyInput, yyInput + maxLen); - + if (f <= yyInput || (f - yyInput) < minLen) { /* not found */ return TCL_RETURN; @@ -1313,15 +1313,15 @@ ClockStrIdxTreeSearch(ClockFmtScnCmdArgs *opts, #if 0 /* currently unused */ -static int -StaticListSearch(ClockFmtScnCmdArgs *opts, +static int +StaticListSearch(ClockFmtScnCmdArgs *opts, DateInfo *info, const char **lst, int *val) { int len; const char **s = lst; while (*s != NULL) { len = strlen(*s); - if ( len <= info->dateEnd - yyInput + if ( len <= info->dateEnd - yyInput && strncasecmp(yyInput, *s, len) == 0 ) { *val = (s - lst); @@ -1339,7 +1339,7 @@ StaticListSearch(ClockFmtScnCmdArgs *opts, static inline const char * FindWordEnd( - ClockScanToken *tok, + ClockScanToken *tok, register const char * p, const char * end) { register const char *x = tok->tokWord.start; @@ -1358,7 +1358,7 @@ FindWordEnd( return pfnd; } -static int +static int ClockScnToken_Month_Proc(ClockFmtScnCmdArgs *opts, DateInfo *info, ClockScanToken *tok) { @@ -1371,7 +1371,7 @@ ClockScnToken_Month_Proc(ClockFmtScnCmdArgs *opts, "July", "August", "September", "October", "November", "December", /* abbr */ - "Jan", "Feb", "Mar", "Apr", "May", "Jun", + "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec", NULL }; @@ -1408,7 +1408,7 @@ ClockScnToken_Month_Proc(ClockFmtScnCmdArgs *opts, } -static int +static int ClockScnToken_DayOfWeek_Proc(ClockFmtScnCmdArgs *opts, DateInfo *info, ClockScanToken *tok) { @@ -1425,7 +1425,7 @@ ClockScnToken_DayOfWeek_Proc(ClockFmtScnCmdArgs *opts, if ( curTok != 'a' && curTok != 'A' && ((minLen <= 1 && maxLen >= 1) || PTR2INT(tok->map->data)) ) { - + val = -1; if (PTR2INT(tok->map->data) == 0) { @@ -1450,8 +1450,7 @@ ClockScnToken_DayOfWeek_Proc(ClockFmtScnCmdArgs *opts, val = 7; } if (val > 7) { - Tcl_SetResult(opts->interp, (char*)"day of week is greater than 7", - TCL_STATIC); + Tcl_SetObjResult(opts->interp, Tcl_NewStringObj("day of week is greater than 7", -1)); Tcl_SetErrorCode(opts->interp, "CLOCK", "badDayOfWeek", NULL); return TCL_ERROR; } @@ -1484,8 +1483,8 @@ ClockScnToken_DayOfWeek_Proc(ClockFmtScnCmdArgs *opts, } -static int -ClockScnToken_amPmInd_Proc(ClockFmtScnCmdArgs *opts, +static int +ClockScnToken_amPmInd_Proc(ClockFmtScnCmdArgs *opts, DateInfo *info, ClockScanToken *tok) { int ret, val; @@ -1504,7 +1503,7 @@ ClockScnToken_amPmInd_Proc(ClockFmtScnCmdArgs *opts, ret = ObjListSearch(opts, info, &val, amPmObj, 2, minLen, maxLen); if (ret != TCL_OK) { - return ret; + return ret; } if (val == 0) { @@ -1516,8 +1515,8 @@ ClockScnToken_amPmInd_Proc(ClockFmtScnCmdArgs *opts, return TCL_OK; } -static int -ClockScnToken_LocaleERA_Proc(ClockFmtScnCmdArgs *opts, +static int +ClockScnToken_LocaleERA_Proc(ClockFmtScnCmdArgs *opts, DateInfo *info, ClockScanToken *tok) { ClockClientData *dataPtr = opts->clientData; @@ -1542,7 +1541,7 @@ ClockScnToken_LocaleERA_Proc(ClockFmtScnCmdArgs *opts, ret = ObjListSearch(opts, info, &val, eraObj, 6, minLen, maxLen); if (ret != TCL_OK) { - return ret; + return ret; } if (val & 1) { @@ -1554,8 +1553,8 @@ ClockScnToken_LocaleERA_Proc(ClockFmtScnCmdArgs *opts, return TCL_OK; } -static int -ClockScnToken_LocaleListMatcher_Proc(ClockFmtScnCmdArgs *opts, +static int +ClockScnToken_LocaleListMatcher_Proc(ClockFmtScnCmdArgs *opts, DateInfo *info, ClockScanToken *tok) { int ret, val; @@ -1583,8 +1582,8 @@ ClockScnToken_LocaleListMatcher_Proc(ClockFmtScnCmdArgs *opts, return TCL_OK; } -static int -ClockScnToken_TimeZone_Proc(ClockFmtScnCmdArgs *opts, +static int +ClockScnToken_TimeZone_Proc(ClockFmtScnCmdArgs *opts, DateInfo *info, ClockScanToken *tok) { int minLen, maxLen; @@ -1598,7 +1597,7 @@ ClockScnToken_TimeZone_Proc(ClockFmtScnCmdArgs *opts, if (*p == '+' || *p == '-') { /* max chars in numeric zone = "+00:00:00" */ #define MAX_ZONE_LEN 9 - char buf[MAX_ZONE_LEN + 1]; + char buf[MAX_ZONE_LEN + 1]; char *bp = buf; *bp++ = *p++; len++; if (maxLen > MAX_ZONE_LEN) @@ -1621,7 +1620,7 @@ ClockScnToken_TimeZone_Proc(ClockFmtScnCmdArgs *opts, return TCL_RETURN; } #undef MAX_ZONE_LEN - + /* timezone */ tzObjStor = Tcl_NewStringObj(buf, bp-buf); } else { @@ -1629,7 +1628,7 @@ ClockScnToken_TimeZone_Proc(ClockFmtScnCmdArgs *opts, if (maxLen > 4) maxLen = 4; while (len < maxLen) { - if ( (*p & 0x80) + if ( (*p & 0x80) || (!isalpha(UCHAR(*p)) && !isdigit(UCHAR(*p))) ) { /* INTL: ISO only. */ break; @@ -1650,7 +1649,7 @@ ClockScnToken_TimeZone_Proc(ClockFmtScnCmdArgs *opts, /* try to apply new time zone */ Tcl_IncrRefCount(tzObjStor); - opts->timezoneObj = ClockSetupTimeZone(opts->clientData, opts->interp, + opts->timezoneObj = ClockSetupTimeZone(opts->clientData, opts->interp, tzObjStor); Tcl_DecrRefCount(tzObjStor); @@ -1663,8 +1662,8 @@ ClockScnToken_TimeZone_Proc(ClockFmtScnCmdArgs *opts, return TCL_OK; } -static int -ClockScnToken_StarDate_Proc(ClockFmtScnCmdArgs *opts, +static int +ClockScnToken_StarDate_Proc(ClockFmtScnCmdArgs *opts, DateInfo *info, ClockScanToken *tok) { int minLen, maxLen; @@ -1741,7 +1740,7 @@ ClockScnToken_StarDate_Proc(ClockFmtScnCmdArgs *opts, return TCL_OK; } -static const char *ScnSTokenMapIndex = +static const char *ScnSTokenMapIndex = "dmbyYHMSpJjCgGVazUsntQ"; static ClockScanTokenMap ScnSTokenMap[] = { /* %d %e */ @@ -1814,7 +1813,7 @@ static const char *ScnSTokenMapAliasIndex[2] = { "dmbbHHHpaaazU" }; -static const char *ScnETokenMapIndex = +static const char *ScnETokenMapIndex = "Eys"; static ClockScanTokenMap ScnETokenMap[] = { /* %EE */ @@ -1832,7 +1831,7 @@ static const char *ScnETokenMapAliasIndex[2] = { "" }; -static const char *ScnOTokenMapIndex = +static const char *ScnOTokenMapIndex = "dmyHMSu"; static ClockScanTokenMap ScnOTokenMap[] = { /* %Od %Oe */ @@ -1862,7 +1861,7 @@ static const char *ScnOTokenMapAliasIndex[2] = { "dHHHu" }; -static const char *ScnSpecTokenMapIndex = +static const char *ScnSpecTokenMapIndex = " "; static ClockScanTokenMap ScnSpecTokenMap[] = { {CTOKT_SPACE, 0, 0, 1, 1, 0, @@ -1870,7 +1869,7 @@ static ClockScanTokenMap ScnSpecTokenMap[] = { }; static ClockScanTokenMap ScnWordTokenMap = { - CTOKT_WORD, 0, 0, 1, 1, 0, + CTOKT_WORD, 0, 0, 1, 1, 0, NULL }; @@ -1937,7 +1936,7 @@ ClockGetOrParseScanFormat( /* estimate token count by % char and format length */ fss->scnTokC = EstimateTokenCount(p, e); - + fss->scnSpaceCount = 0; Tcl_MutexLock(&ClockFmtMutex); @@ -1959,7 +1958,7 @@ ClockGetOrParseScanFormat( /* try to find modifier: */ switch (*p) { case '%': - /* begin new word token - don't join with previous word token, + /* begin new word token - don't join with previous word token, * because current mapping should be "...%%..." -> "...%..." */ tok->map = &ScnWordTokenMap; tok->tokWord.start = p; @@ -1969,7 +1968,7 @@ ClockGetOrParseScanFormat( continue; break; case 'E': - scnMap = ScnETokenMap, + scnMap = ScnETokenMap, mapIndex = ScnETokenMapIndex, aliasIndex = ScnETokenMapAliasIndex; p++; @@ -2018,7 +2017,7 @@ ClockGetOrParseScanFormat( } /* increase space count used in format */ - if ( tok->map->type == CTOKT_CHAR + if ( tok->map->type == CTOKT_CHAR && isspace(UCHAR(*((char *)tok->map->data))) ) { fss->scnSpaceCount++; @@ -2161,13 +2160,13 @@ ClockScan( } info->dateStart = p = yyInput; info->dateEnd = end; - + /* parse string */ for (; tok->map != NULL; tok++) { map = tok->map; /* bypass spaces at begin of input before parsing each token */ - if ( !(opts->flags & CLF_STRICT) - && ( map->type != CTOKT_SPACE + if ( !(opts->flags & CLF_STRICT) + && ( map->type != CTOKT_SPACE && map->type != CTOKT_WORD && map->type != CTOKT_CHAR ) ) { @@ -2206,13 +2205,13 @@ ClockScan( if (map->offs) { p = yyInput; x = p + size; if (!(map->flags & (CLF_LOCALSEC|CLF_POSIXSEC))) { - if (_str2int((int *)(((char *)info) + map->offs), + if (_str2int((int *)(((char *)info) + map->offs), p, x, sign) != TCL_OK) { goto overflow; } p = x; } else { - if (_str2wideInt((Tcl_WideInt *)(((char *)info) + map->offs), + if (_str2wideInt((Tcl_WideInt *)(((char *)info) + map->offs), p, x, sign) != TCL_OK) { goto overflow; } @@ -2297,8 +2296,8 @@ ClockScan( tok++; } - /* - * Invalidate result + /* + * Invalidate result */ /* seconds token (%s) take precedence over all other tokens */ @@ -2332,17 +2331,17 @@ ClockScan( } /* YearWeekDay below YearMonthDay */ - if ( (flags & CLF_ISO8601) + if ( (flags & CLF_ISO8601) && ( (flags & (CLF_YEAR|CLF_DAYOFYEAR)) == (CLF_YEAR|CLF_DAYOFYEAR) || (flags & (CLF_YEAR|CLF_DAYOFMONTH|CLF_MONTH)) == (CLF_YEAR|CLF_DAYOFMONTH|CLF_MONTH) - ) + ) ) { /* yy precedence below yyyy */ if (!(flags & CLF_ISO8601CENTURY) && (flags & CLF_CENTURY)) { /* normally precedence of ISO is higher, but no century - so put it down */ flags &= ~CLF_ISO8601; - } - else + } + else /* yymmdd or yyddd over naked weekday */ if (!(flags & CLF_ISO8601YEAR)) { flags &= ~CLF_ISO8601; @@ -2400,15 +2399,15 @@ ClockScan( overflow: - Tcl_SetResult(opts->interp, (char*)"requested date too large to represent", - TCL_STATIC); + Tcl_SetObjResult(opts->interp, Tcl_NewStringObj("requested date too large to represent", + -1)); Tcl_SetErrorCode(opts->interp, "CLOCK", "dateTooLarge", NULL); goto done; not_match: - Tcl_SetResult(opts->interp, (char*)"input string does not match supplied format", - TCL_STATIC); + Tcl_SetObjResult(opts->interp, Tcl_NewStringObj("input string does not match supplied format", + -1)); Tcl_SetErrorCode(opts->interp, "CLOCK", "badInputString", NULL); done: @@ -2423,7 +2422,7 @@ FrmResultAllocate( { int needed = dateFmt->output + len - dateFmt->resEnd; if (needed >= 0) { /* >= 0 - regards NTS zero */ - int newsize = dateFmt->resEnd - dateFmt->resMem + int newsize = dateFmt->resEnd - dateFmt->resMem + needed + MIN_FMT_RESULT_BLOCK_ALLOC; char *newRes = ckrealloc(dateFmt->resMem, newsize); if (newRes == NULL) { @@ -2499,9 +2498,9 @@ ClockFmtToken_StarDate_Proc( if (FrmResultAllocate(dateFmt, 30) != TCL_OK) { return TCL_ERROR; }; memcpy(dateFmt->output, "Stardate ", 9); dateFmt->output += 9; - dateFmt->output = _itoaw(dateFmt->output, + dateFmt->output = _itoaw(dateFmt->output, dateFmt->date.year - RODDENBERRY, '0', 2); - dateFmt->output = _itoaw(dateFmt->output, + dateFmt->output = _itoaw(dateFmt->output, fractYear, '0', 3); *dateFmt->output++ = '.'; /* be sure positive after decimal point (note: clock-value can be negative) */ @@ -2556,7 +2555,7 @@ ClockFmtToken_TimeZone_Proc( const char *s; int len; /* convert seconds to local seconds to obtain tzName object */ if (ConvertUTCToLocal(opts->clientData, opts->interp, - &dateFmt->date, opts->timezoneObj, + &dateFmt->date, opts->timezoneObj, GREGORIAN_CHANGE_DATE) != TCL_OK) { return TCL_ERROR; }; @@ -2616,7 +2615,7 @@ ClockFmtToken_LocaleERAYear_Proc( return TCL_ERROR; } if (rowc != 0) { - dateFmt->localeEra = LookupLastTransition(opts->interp, + dateFmt->localeEra = LookupLastTransition(opts->interp, dateFmt->date.localSeconds, rowc, rowv, NULL); } if (dateFmt->localeEra == NULL) { @@ -2629,11 +2628,11 @@ ClockFmtToken_LocaleERAYear_Proc( if (FrmResultAllocate(dateFmt, 11) != TCL_OK) { return TCL_ERROR; }; if (*tok->tokWord.start == 'C') { /* %EC */ *val = dateFmt->date.year / 100; - dateFmt->output = _itoaw(dateFmt->output, + dateFmt->output = _itoaw(dateFmt->output, *val, '0', 2); } else { /* %Ey */ *val = dateFmt->date.year % 100; - dateFmt->output = _itoaw(dateFmt->output, + dateFmt->output = _itoaw(dateFmt->output, *val, '0', 2); } } else { @@ -2667,7 +2666,7 @@ ClockFmtToken_LocaleERAYear_Proc( } else { /* year as integer */ if (FrmResultAllocate(dateFmt, 11) != TCL_OK) { return TCL_ERROR; }; - dateFmt->output = _itoaw(dateFmt->output, + dateFmt->output = _itoaw(dateFmt->output, *val, '0', 2); return TCL_OK; } @@ -2682,7 +2681,7 @@ ClockFmtToken_LocaleERAYear_Proc( } -static const char *FmtSTokenMapIndex = +static const char *FmtSTokenMapIndex = "demNbByYCHMSIklpaAuwUVzgGjJsntQ"; static ClockFormatTokenMap FmtSTokenMap[] = { /* %d */ @@ -2712,15 +2711,15 @@ static ClockFormatTokenMap FmtSTokenMap[] = { /* %S */ {CFMTT_INT, "0", 2, 0, 0, 60, TclOffset(DateFormat, date.secondOfDay), NULL}, /* %I */ - {CFMTT_INT, "0", 2, CLFMT_CALC, 0, 0, TclOffset(DateFormat, date.secondOfDay), + {CFMTT_INT, "0", 2, CLFMT_CALC, 0, 0, TclOffset(DateFormat, date.secondOfDay), ClockFmtToken_HourAMPM_Proc, NULL}, /* %k */ {CFMTT_INT, " ", 2, 0, 3600, 24, TclOffset(DateFormat, date.secondOfDay), NULL}, /* %l */ - {CFMTT_INT, " ", 2, CLFMT_CALC, 0, 0, TclOffset(DateFormat, date.secondOfDay), + {CFMTT_INT, " ", 2, CLFMT_CALC, 0, 0, TclOffset(DateFormat, date.secondOfDay), ClockFmtToken_HourAMPM_Proc, NULL}, /* %p %P */ - {CFMTT_INT, NULL, 0, 0, 0, 0, TclOffset(DateFormat, date.secondOfDay), + {CFMTT_INT, NULL, 0, 0, 0, 0, TclOffset(DateFormat, date.secondOfDay), ClockFmtToken_AMPM_Proc, NULL}, /* %a */ {CFMTT_INT, NULL, 0, CLFMT_LOCALE_INDX, 0, 7, TclOffset(DateFormat, date.dayOfWeek), @@ -2733,12 +2732,12 @@ static ClockFormatTokenMap FmtSTokenMap[] = { /* %w */ {CFMTT_INT, " ", 1, 0, 0, 7, TclOffset(DateFormat, date.dayOfWeek), NULL}, /* %U %W */ - {CFMTT_INT, "0", 2, CLFMT_CALC, 0, 0, TclOffset(DateFormat, date.dayOfYear), + {CFMTT_INT, "0", 2, CLFMT_CALC, 0, 0, TclOffset(DateFormat, date.dayOfYear), ClockFmtToken_WeekOfYear_Proc, NULL}, /* %V */ {CFMTT_INT, "0", 2, 0, 0, 0, TclOffset(DateFormat, date.iso8601Week), NULL}, /* %z %Z */ - {CFMTT_INT, NULL, 0, 0, 0, 0, 0, + {CFMTT_INT, NULL, 0, 0, 0, 0, 0, ClockFmtToken_TimeZone_Proc, NULL}, /* %g */ {CFMTT_INT, "0", 2, 0, 0, 100, TclOffset(DateFormat, date.iso8601Year), NULL}, @@ -2755,7 +2754,7 @@ static ClockFormatTokenMap FmtSTokenMap[] = { /* %t */ {CTOKT_CHAR, "\t", 0, 0, 0, 0, 0, NULL}, /* %Q */ - {CFMTT_INT, NULL, 0, 0, 0, 0, 0, + {CFMTT_INT, NULL, 0, 0, 0, 0, 0, ClockFmtToken_StarDate_Proc, NULL}, }; static const char *FmtSTokenMapAliasIndex[2] = { @@ -2763,11 +2762,11 @@ static const char *FmtSTokenMapAliasIndex[2] = { "bpUz" }; -static const char *FmtETokenMapIndex = +static const char *FmtETokenMapIndex = "Eys"; static ClockFormatTokenMap FmtETokenMap[] = { /* %EE */ - {CFMTT_INT, NULL, 0, 0, 0, 0, TclOffset(DateFormat, date.era), + {CFMTT_INT, NULL, 0, 0, 0, 0, TclOffset(DateFormat, date.era), ClockFmtToken_LocaleERA_Proc, NULL}, /* %Ey %EC */ {CFMTT_INT, NULL, 0, 0, 0, 0, TclOffset(DateFormat, date.year), @@ -2780,7 +2779,7 @@ static const char *FmtETokenMapAliasIndex[2] = { "y" }; -static const char *FmtOTokenMapIndex = +static const char *FmtOTokenMapIndex = "dmyHIMSuw"; static ClockFormatTokenMap FmtOTokenMap[] = { /* %Od %Oe */ @@ -2793,22 +2792,22 @@ static ClockFormatTokenMap FmtOTokenMap[] = { {CFMTT_INT, NULL, 0, CLFMT_LOCALE_INDX, 0, 100, TclOffset(DateFormat, date.year), NULL, (void *)MCLIT_LOCALE_NUMERALS}, /* %OH %Ok */ - {CFMTT_INT, NULL, 0, CLFMT_LOCALE_INDX, 3600, 24, TclOffset(DateFormat, date.secondOfDay), + {CFMTT_INT, NULL, 0, CLFMT_LOCALE_INDX, 3600, 24, TclOffset(DateFormat, date.secondOfDay), NULL, (void *)MCLIT_LOCALE_NUMERALS}, /* %OI %Ol */ - {CFMTT_INT, NULL, 0, CLFMT_CALC | CLFMT_LOCALE_INDX, 0, 0, TclOffset(DateFormat, date.secondOfDay), + {CFMTT_INT, NULL, 0, CLFMT_CALC | CLFMT_LOCALE_INDX, 0, 0, TclOffset(DateFormat, date.secondOfDay), ClockFmtToken_HourAMPM_Proc, (void *)MCLIT_LOCALE_NUMERALS}, /* %OM */ - {CFMTT_INT, NULL, 0, CLFMT_LOCALE_INDX, 60, 60, TclOffset(DateFormat, date.secondOfDay), + {CFMTT_INT, NULL, 0, CLFMT_LOCALE_INDX, 60, 60, TclOffset(DateFormat, date.secondOfDay), NULL, (void *)MCLIT_LOCALE_NUMERALS}, /* %OS */ - {CFMTT_INT, NULL, 0, CLFMT_LOCALE_INDX, 0, 60, TclOffset(DateFormat, date.secondOfDay), + {CFMTT_INT, NULL, 0, CLFMT_LOCALE_INDX, 0, 60, TclOffset(DateFormat, date.secondOfDay), NULL, (void *)MCLIT_LOCALE_NUMERALS}, /* %Ou */ {CFMTT_INT, NULL, 0, CLFMT_LOCALE_INDX, 0, 100, TclOffset(DateFormat, date.dayOfWeek), NULL, (void *)MCLIT_LOCALE_NUMERALS}, /* %Ow */ - {CFMTT_INT, NULL, 0, CLFMT_LOCALE_INDX, 0, 7, TclOffset(DateFormat, date.dayOfWeek), + {CFMTT_INT, NULL, 0, CLFMT_LOCALE_INDX, 0, 7, TclOffset(DateFormat, date.dayOfWeek), NULL, (void *)MCLIT_LOCALE_NUMERALS}, }; static const char *FmtOTokenMapAliasIndex[2] = { @@ -2866,7 +2865,7 @@ ClockGetOrParseFmtFormat( /* try to find modifier: */ switch (*p) { case '%': - /* begin new word token - don't join with previous word token, + /* begin new word token - don't join with previous word token, * because current mapping should be "...%%..." -> "...%..." */ tok->map = &FmtWordTokenMap; tok->tokWord.start = p; @@ -2876,7 +2875,7 @@ ClockGetOrParseFmtFormat( continue; break; case 'E': - fmtMap = FmtETokenMap, + fmtMap = FmtETokenMap, mapIndex = FmtETokenMapIndex, aliasIndex = FmtETokenMapAliasIndex; p++; @@ -2977,7 +2976,7 @@ ClockFormat( if (dateFmt->date.secondOfDay < 0) { dateFmt->date.secondOfDay += SECONDS_PER_DAY; } - + /* result container object */ dateFmt->resMem = ckalloc(MIN_FMT_RESULT_BLOCK_ALLOC); if (dateFmt->resMem == NULL) { diff --git a/generic/tclDate.c b/generic/tclDate.c index 64cb804..934fe5f 100644 --- a/generic/tclDate.c +++ b/generic/tclDate.c @@ -1,20 +1,20 @@ /* A Bison parser, made by GNU Bison 2.4.2. */ /* Skeleton implementation for Bison's Yacc-like parsers in C - + Copyright (C) 1984, 1989-1990, 2000-2006, 2009-2010 Free Software Foundation, Inc. - + This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. - + This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. - + You should have received a copy of the GNU General Public License along with this program. If not, see . */ @@ -27,7 +27,7 @@ special exception, which will cause the skeleton and the resulting Bison output files to be licensed under the GNU General Public License without this special exception. - + This special exception was added by the Free Software Foundation in version 2.2 of Bison. */ @@ -2685,7 +2685,7 @@ TclClockFreeScan( /* * yyInput = stringToParse; - * + * * ClockInitDateInfo(info) should be executed to pre-init info; */ diff --git a/generic/tclDate.h b/generic/tclDate.h index abc231b..570a8e4 100644 --- a/generic/tclDate.h +++ b/generic/tclDate.h @@ -109,7 +109,7 @@ typedef enum ClockMsgCtLiteral { MCLIT__NIL, /* placeholder */ MCLIT_MONTHS_FULL, MCLIT_MONTHS_ABBREV, MCLIT_MONTHS_COMB, MCLIT_DAYS_OF_WEEK_FULL, MCLIT_DAYS_OF_WEEK_ABBREV, MCLIT_DAYS_OF_WEEK_COMB, - MCLIT_AM, MCLIT_PM, + MCLIT_AM, MCLIT_PM, MCLIT_LOCALE_ERAS, MCLIT_BCE, MCLIT_CE, MCLIT_BCE2, MCLIT_CE2, @@ -486,16 +486,16 @@ MODULE_SCOPE Tcl_Obj * ClockMCGet(ClockFmtScnCmdArgs *opts, int mcKey); MODULE_SCOPE Tcl_Obj * ClockMCGetIdx(ClockFmtScnCmdArgs *opts, int mcKey); -MODULE_SCOPE int ClockMCSetIdx(ClockFmtScnCmdArgs *opts, int mcKey, +MODULE_SCOPE int ClockMCSetIdx(ClockFmtScnCmdArgs *opts, int mcKey, Tcl_Obj *valObj); /* tclClockFmt.c module declarations */ -MODULE_SCOPE Tcl_Obj* +MODULE_SCOPE Tcl_Obj* ClockFrmObjGetLocFmtKey(Tcl_Interp *interp, Tcl_Obj *objPtr); -MODULE_SCOPE ClockFmtScnStorage * +MODULE_SCOPE ClockFmtScnStorage * Tcl_GetClockFrmScnFromObj(Tcl_Interp *interp, Tcl_Obj *objPtr); MODULE_SCOPE Tcl_Obj * @@ -504,7 +504,7 @@ MODULE_SCOPE Tcl_Obj * MODULE_SCOPE int ClockScan(register DateInfo *info, Tcl_Obj *strObj, ClockFmtScnCmdArgs *opts); -MODULE_SCOPE int ClockFormat(register DateFormat *dateFmt, +MODULE_SCOPE int ClockFormat(register DateFormat *dateFmt, ClockFmtScnCmdArgs *opts); MODULE_SCOPE void ClockFrmScnClearCaches(void); diff --git a/generic/tclEnsemble.c b/generic/tclEnsemble.c index 2480685..5b8deb6 100644 --- a/generic/tclEnsemble.c +++ b/generic/tclEnsemble.c @@ -328,7 +328,7 @@ TclNamespaceEnsembleCmd( } continue; case CRT_COMPILE: - if (Tcl_GetBooleanFromObj(interp, objv[1], + if (Tcl_GetBooleanFromObj(interp, objv[1], &ensCompFlag) != TCL_OK) { return TCL_ERROR; }; @@ -358,7 +358,7 @@ TclNamespaceEnsembleCmd( Tcl_SetEnsembleMappingDict(interp, token, mapObj); Tcl_SetEnsembleUnknownHandler(interp, token, unknownObj); Tcl_SetEnsembleParameterList(interp, token, paramObj); - /* + /* * Ensemble should be compiled if it has map (performance purposes) */ if (ensCompFlag > 0 && mapObj != NULL) { diff --git a/generic/tclEnv.c b/generic/tclEnv.c index 0041a40..d05cc61 100644 --- a/generic/tclEnv.c +++ b/generic/tclEnv.c @@ -19,7 +19,7 @@ TCL_DECLARE_MUTEX(envMutex) /* To serialize access to environ. */ /* MODULE_SCOPE */ -unsigned long TclEnvEpoch = 0; /* Epoch of the tcl environment +size_t TclEnvEpoch = 0; /* Epoch of the tcl environment * (if changed with tcl-env). */ static struct { diff --git a/generic/tclGetDate.y b/generic/tclGetDate.y index 6d6a0d0..b83644b 100644 --- a/generic/tclGetDate.y +++ b/generic/tclGetDate.y @@ -896,7 +896,7 @@ TclClockFreeScan( /* * yyInput = stringToParse; - * + * * ClockInitDateInfo(info) should be executed to pre-init info; */ diff --git a/generic/tclInt.h b/generic/tclInt.h index 5bd4324..8edc518 100644 --- a/generic/tclInt.h +++ b/generic/tclInt.h @@ -4875,7 +4875,7 @@ typedef struct NRE_callback { * Other externals. */ -MODULE_SCOPE unsigned long TclEnvEpoch; /* Epoch of the tcl environment +MODULE_SCOPE size_t TclEnvEpoch; /* Epoch of the tcl environment * (if changed with tcl-env). */ #endif /* _TCLINT */ diff --git a/generic/tclStrIdxTree.c b/generic/tclStrIdxTree.c index 0045ea5..557d575 100644 --- a/generic/tclStrIdxTree.c +++ b/generic/tclStrIdxTree.c @@ -1,7 +1,7 @@ /* * tclStrIdxTree.c -- * - * Contains the routines for managing string index tries in Tcl. + * Contains the routines for managing string index tries in Tcl. * * This code is back-ported from the tclSE engine, by Serg G. Brester. * @@ -12,11 +12,11 @@ * * ----------------------------------------------------------------------- * - * String index tries are prepaired structures used for fast greedy search of the string + * String index tries are prepaired structures used for fast greedy search of the string * (index) by unique string prefix as key. * * Index tree build for two lists together can be explained in the following datagram - * + * * Lists: * * {Januar Februar Maerz April Mai Juni Juli August September Oktober November Dezember} @@ -42,9 +42,9 @@ * i 5 * zb 12 * rz 3 * * ... - * + * * Thereby value 0 shows pure group items (corresponding ambigous matches). - * But the group may have a value if it contains only same values + * But the group may have a value if it contains only same values * (see for example group "f" above). * * StrIdxTree's are very fast, so: @@ -109,7 +109,7 @@ TclStrIdxTreeSearch( s = f; /* if match item, go deeper as long as possible */ if (offs >= item->length && item->childTree.firstPtr) { - /* save previuosly found item (if not ambigous) for + /* save previuosly found item (if not ambigous) for * possible fallback (few greedy match) */ if (item->value != NULL) { prevf = f; @@ -145,7 +145,7 @@ done: return start; } -MODULE_SCOPE void +MODULE_SCOPE void TclStrIdxTreeFree( TclStrIdx *tree) { @@ -157,13 +157,13 @@ TclStrIdxTreeFree( } t = tree, tree = tree->nextPtr; ckfree(t); - } + } } /* * Several bidirectional list primitives */ -inline void +inline void TclStrIdxTreeInsertBranch( TclStrIdxTree *parent, register TclStrIdx *item, @@ -282,7 +282,7 @@ TclStrIdxTreeBuildFromList( foundItem->length = lwrv[i]->length; continue; } - /* split tree (e. g. j->(jan,jun) + jul == j->(jan,ju->(jun,jul)) ) + /* split tree (e. g. j->(jan,jun) + jul == j->(jan,ju->(jun,jul)) ) * but don't split by fulfilled child of found item ( ii->iii->iiii ) */ if (foundItem->length != (f - s)) { /* first split found item (insert one between parent and found + new one) */ @@ -351,7 +351,7 @@ Tcl_ObjType StrIdxTreeObjType = { NULL /* setFromAnyProc */ }; -MODULE_SCOPE Tcl_Obj* +MODULE_SCOPE Tcl_Obj* TclStrIdxTreeNewObj() { Tcl_Obj *objPtr = Tcl_NewObj(); @@ -372,7 +372,7 @@ StrIdxTreeObj_DupIntRepProc(Tcl_Obj *srcPtr, Tcl_Obj *copyPtr) srcPtr = (Tcl_Obj*)srcPtr->internalRep.twoPtrValue.ptr1; } /* create smart pointer to it (ptr1 != NULL, ptr2 = NULL) */ - Tcl_InitObjRef(*((Tcl_Obj **)©Ptr->internalRep.twoPtrValue.ptr1), + Tcl_InitObjRef(*((Tcl_Obj **)©Ptr->internalRep.twoPtrValue.ptr1), srcPtr); copyPtr->internalRep.twoPtrValue.ptr2 = NULL; copyPtr->typePtr = &StrIdxTreeObjType; @@ -428,7 +428,7 @@ TclStrIdxTreeGetFromObj(Tcl_Obj *objPtr) { #if 0 /* currently unused, debug resp. test purposes only */ -void +void TclStrIdxTreePrint( Tcl_Interp *interp, TclStrIdx *tree, @@ -439,7 +439,7 @@ TclStrIdxTreePrint( Tcl_InitObjRef(obj[0], Tcl_NewStringObj("::puts", -1)); while (tree != NULL) { s = TclGetString(tree->key) + offs; - Tcl_InitObjRef(obj[1], Tcl_ObjPrintf("%*s%.*s\t:%d", + Tcl_InitObjRef(obj[1], Tcl_ObjPrintf("%*s%.*s\t:%d", offs, "", tree->length - offs, s, tree->value)); Tcl_PutsObjCmd(NULL, interp, 2, obj); Tcl_UnsetObjRef(obj[1]); @@ -469,10 +469,10 @@ TclStrIdxTreeTestObjCmd( int optionIndex; if (objc < 2) { - Tcl_SetResult(interp, (char*)"wrong # args", TCL_STATIC); + Tcl_WrongNumArgs(interp, 1, objv, ""); return TCL_ERROR; } - if (Tcl_GetIndexFromObj(interp, objv[1], options, + if (Tcl_GetIndexFromObj(interp, objv[1], options, "option", 0, &optionIndex) != TCL_OK) { Tcl_SetErrorCode(interp, "CLOCK", "badOption", Tcl_GetString(objv[1]), NULL); @@ -481,7 +481,7 @@ TclStrIdxTreeTestObjCmd( switch (optionIndex) { case O_FINDEQUAL: if (objc < 4) { - Tcl_SetResult(interp, (char*)"wrong # args", TCL_STATIC); + Tcl_WrongNumArgs(interp, 1, objv, ""); return TCL_ERROR; } cs = TclGetString(objv[2]); @@ -499,7 +499,7 @@ TclStrIdxTreeTestObjCmd( TclStrIdxTree idxTree = {NULL, NULL}; i = 1; while (++i < objc) { - if (TclListObjGetElements(interp, objv[i], + if (TclListObjGetElements(interp, objv[i], &lstc, &lstv) != TCL_OK) { return TCL_ERROR; }; diff --git a/generic/tclStrIdxTree.h b/generic/tclStrIdxTree.h index 9f26907..6ed5170 100644 --- a/generic/tclStrIdxTree.h +++ b/generic/tclStrIdxTree.h @@ -1,7 +1,7 @@ /* * tclStrIdxTree.h -- * - * Declarations of string index tries and other primitives currently + * Declarations of string index tries and other primitives currently * back-ported from tclSE. * * Copyright (c) 2016 Serg G. Brester (aka sebres) @@ -38,7 +38,7 @@ typedef struct TclStrIdx { * * TclUtfFindEqual, TclUtfFindEqualNC -- * - * Find largest part of string cs in string cin (case sensitive and not). + * Find largest part of string cs in string cin (case sensitive and not). * * Results: * Return position of UTF character in cs after last equal character. @@ -148,13 +148,13 @@ if (1) { \ MODULE_SCOPE const char* TclStrIdxTreeSearch(TclStrIdxTree **foundParent, - TclStrIdx **foundItem, TclStrIdxTree *tree, + TclStrIdx **foundItem, TclStrIdxTree *tree, const char *start, const char *end); MODULE_SCOPE int TclStrIdxTreeBuildFromList(TclStrIdxTree *idxTree, int lstc, Tcl_Obj **lstv, ClientData *values); -MODULE_SCOPE Tcl_Obj* +MODULE_SCOPE Tcl_Obj* TclStrIdxTreeNewObj(); MODULE_SCOPE TclStrIdxTree* diff --git a/library/clock.tcl b/library/clock.tcl index 1f3c669..471deff 100644 --- a/library/clock.tcl +++ b/library/clock.tcl @@ -519,7 +519,7 @@ proc ::tcl::clock::Initialize {} { # Return the merged translation catalog for the ::tcl::clock namespace # Searching of catalog is similar to "msgcat::mc". # -# Contrary to "msgcat::mc" may additionally load a package catalog +# Contrary to "msgcat::mc" may additionally load a package catalog # on demand. # # Arguments: @@ -826,7 +826,7 @@ proc ::tcl::clock::LoadWindowsDateTimeFormats { locale } { proc ::tcl::clock::LocalizeFormat { locale format {fmtkey {}} } { variable LocaleFormats - + if { $fmtkey eq {} } { set fmtkey FMT_$format } if { [catch { set locfmt [dict get $LocaleFormats $locale $fmtkey] @@ -836,10 +836,10 @@ proc ::tcl::clock::LocalizeFormat { locale format {fmtkey {}} } { if { [catch { set mlst [dict get $LocaleFormats $locale MLST] }] } { - + # message catalog dictionary: set mcd [mcget $locale] - + # Handle locale-dependent format groups by mapping them out of the format # string. Note that the order of the [string map] operations is # significant because later formats can refer to later ones; for example @@ -864,7 +864,7 @@ proc ::tcl::clock::LocalizeFormat { locale format {fmtkey {}} } { dict set LocaleFormats $locale MLST $mlst } - # translate copy of format (don't use format object here, because otherwise + # translate copy of format (don't use format object here, because otherwise # it can lose its internal representation (string map - convert to unicode) set locfmt [string map $mlst [string range " $format" 1 end]] @@ -872,10 +872,10 @@ proc ::tcl::clock::LocalizeFormat { locale format {fmtkey {}} } { dict set LocaleFormats $locale $fmtkey $locfmt } - # Save original format as long as possible, because of internal + # Save original format as long as possible, because of internal # representation (performance). # Note that in this case such format will be never localized (also - # using another locales). To prevent this return a duplicate (but + # using another locales). To prevent this return a duplicate (but # it may be slower). if {$locfmt eq $format} { set locfmt $format @@ -934,7 +934,7 @@ proc ::tcl::clock::GetSystemTimeZone {} { if { [dict exists $TimeZoneBad $timezone] } { set timezone :localtime } - + # tell backend - current system timezone: configure -system-tz $timezone diff --git a/library/init.tcl b/library/init.tcl index de69730..e500e3d 100644 --- a/library/init.tcl +++ b/library/init.tcl @@ -157,7 +157,7 @@ if {[interp issafe]} { package unknown {::tcl::tm::UnknownHandler ::tclPkgUnknown} } else { # Default known auto_index (avoid loading auto index implicit after interp create): - + array set ::auto_index { ::tcl::tm::UnknownHandler {source [info library]/tm.tcl} ::tclPkgUnknown {source [info library]/package.tcl} @@ -431,7 +431,7 @@ proc auto_load {cmd {namespace {}}} { # workaround non canonical auto_index entries that might be around # from older auto_mkindex versions if {$cmd ni $nameList} {lappend nameList $cmd} - + # try to load (and create sub-cmd handler "_sub_load_cmd" for further usage): foreach name $nameList [set _sub_load_cmd { # via auto_index: @@ -461,7 +461,7 @@ proc auto_load {cmd {namespace {}}} { } } }] - + # load auto_index if possible: if {![info exists auto_path]} { return 0 diff --git a/unix/tclUnixTime.c b/unix/tclUnixTime.c index 375e366..2a30386 100644 --- a/unix/tclUnixTime.c +++ b/unix/tclUnixTime.c @@ -248,7 +248,7 @@ TclpWideClicksToNanoseconds( * * TclpWideClickInMicrosec -- * - * This procedure return scale to convert click values from the + * This procedure return scale to convert click values from the * TclpGetWideClicks native resolution to microsecond resolution * and back. * diff --git a/win/tclWinTime.c b/win/tclWinTime.c index e1aff48..db05cad 100644 --- a/win/tclWinTime.c +++ b/win/tclWinTime.c @@ -252,7 +252,7 @@ TclpGetWideClicks(void) /* * The frequency of the performance counter is fixed at system boot and - * is consistent across all processors. Therefore, the frequency need + * is consistent across all processors. Therefore, the frequency need * only be queried upon application initialization. */ if (QueryPerformanceFrequency(&perfCounterFreq)) { @@ -263,7 +263,7 @@ TclpGetWideClicks(void) wideClick.perfCounter = 0; wideClick.microsecsScale = 1; } - + wideClick.initialized = 1; } if (wideClick.perfCounter) { @@ -284,7 +284,7 @@ TclpGetWideClicks(void) * * TclpWideClickInMicrosec -- * - * This procedure return scale to convert wide click values from the + * This procedure return scale to convert wide click values from the * TclpGetWideClicks native resolution to microsecond resolution * and back. * @@ -323,7 +323,7 @@ TclpWideClickInMicrosec(void) *---------------------------------------------------------------------- */ -Tcl_WideInt +Tcl_WideInt TclpGetMicroseconds(void) { Tcl_WideInt usecSincePosixEpoch; -- cgit v0.12 From fcd399d49aee6b08b44aa50882a78c8d104c5e59 Mon Sep 17 00:00:00 2001 From: "jan.nijtmans" Date: Wed, 31 May 2017 12:05:45 +0000 Subject: Fix [67aa9a207037ae67f9014b544c3db34fa732f2dc|67aa9a2070]: Security: Invalid UTF-8 can inject unexpected characters --- generic/tclUtf.c | 12 +++++++++--- tests/encoding.test | 25 +++++++++++++++++++++++++ 2 files changed, 34 insertions(+), 3 deletions(-) diff --git a/generic/tclUtf.c b/generic/tclUtf.c index 68119a4..fe47f0b 100644 --- a/generic/tclUtf.c +++ b/generic/tclUtf.c @@ -298,7 +298,9 @@ Tcl_UtfToUniChar( */ *chPtr = (Tcl_UniChar) (((byte & 0x1F) << 6) | (src[1] & 0x3F)); - return 2; + if ((*chPtr == 0) || (*chPtr > 0x7f)) { + return 2; + } } /* @@ -313,7 +315,9 @@ Tcl_UtfToUniChar( *chPtr = (Tcl_UniChar) (((byte & 0x0F) << 12) | ((src[1] & 0x3F) << 6) | (src[2] & 0x3F)); - return 3; + if (*chPtr > 0x7ff) { + return 3; + } } /* @@ -330,7 +334,9 @@ Tcl_UtfToUniChar( *chPtr = (Tcl_UniChar) (((byte & 0x0E) << 18) | ((src[1] & 0x3F) << 12) | ((src[2] & 0x3F) << 6) | (src[3] & 0x3F)); - return 4; + if ((*chPtr <= 0x10ffff) && (*chPtr > 0xffff)) { + return 4; + } } /* diff --git a/tests/encoding.test b/tests/encoding.test index 0374e2d..1d8bae5 100644 --- a/tests/encoding.test +++ b/tests/encoding.test @@ -448,6 +448,31 @@ test encoding-24.3 {EscapeFreeProc on open channels} {stdio} { list $count [viewable $line] } [list 3 "\u4e4e\u4e5e\u4e5f (\\u4e4e\\u4e5e\\u4e5f)"] +test encoding-24.4 {Parse valid or invalid utf-8} { + string length [encoding convertfrom utf-8 "\xc0\x80"] +} 1 +test encoding-24.5 {Parse valid or invalid utf-8} { + string length [encoding convertfrom utf-8 "\xc0\x81"] +} 2 +test encoding-24.6 {Parse valid or invalid utf-8} { + string length [encoding convertfrom utf-8 "\xc1\xbf"] +} 2 +test encoding-24.7 {Parse valid or invalid utf-8} { + string length [encoding convertfrom utf-8 "\xc2\x80"] +} 1 +test encoding-24.8 {Parse valid or invalid utf-8} { + string length [encoding convertfrom utf-8 "\xe0\x80\x80"] +} 3 +test encoding-24.9 {Parse valid or invalid utf-8} { + string length [encoding convertfrom utf-8 "\xe0\x9f\xbf"] +} 3 +test encoding-24.10 {Parse valid or invalid utf-8} { + string length [encoding convertfrom utf-8 "\xe0\xa0\x80"] +} 1 +test encoding-24.10 {Parse valid or invalid utf-8} { + string length [encoding convertfrom utf-8 "\xef\xbf\xbf"] +} 1 + file delete [file join [temporaryDirectory] iso2022.txt] # -- cgit v0.12 From 3f0e8d6265db0d5853ab55de2ead9a045c678b6e Mon Sep 17 00:00:00 2001 From: "jan.nijtmans" Date: Wed, 31 May 2017 13:03:54 +0000 Subject: Fix [83a3d869722fab9caaae3b6728215fb2507a6f0d|83a3d86972]: tclEpollNotfy.c fails to compile on Linux 2.6.<22 due to unconditionally including Also re-generate regc_locale.c with Unicode 10 tables: previous generation went horribly wrong somehow... --- generic/regc_locale.c | 5889 ++----------------------------------------------- unix/tclEpollNotfy.c | 2 + 2 files changed, 158 insertions(+), 5733 deletions(-) diff --git a/generic/regc_locale.c b/generic/regc_locale.c index f0e8439..d781212 100644 --- a/generic/regc_locale.c +++ b/generic/regc_locale.c @@ -193,1053 +193,55 @@ static const crange alphaRangeTable[] = { {0xaab9, 0xaabd}, {0xaadb, 0xaadd}, {0xaae0, 0xaaea}, {0xaaf2, 0xaaf4}, {0xab01, 0xab06}, {0xab09, 0xab0e}, {0xab11, 0xab16}, {0xab20, 0xab26}, {0xab28, 0xab2e}, {0xab30, 0xab5a}, {0xab5c, 0xab65}, {0xab70, 0xabe2}, - {0xac00, 0xd7a3}, {0xd7b0, 0xd7c6}, {0xd7cb, 0xd7fb}, {0xf900, 0xfa6d}, + {0xac00, 0xd7a3}, {0xd7b0, 0xd7c6}, {0xd7cb, 0xd7fb}, {0xdc00, 0xdc3e}, + {0xdc40, 0xdc7e}, {0xdc80, 0xdcbe}, {0xdcc0, 0xdcfe}, {0xdd00, 0xdd3e}, + {0xdd40, 0xdd7e}, {0xdd80, 0xddbe}, {0xddc0, 0xddfe}, {0xde00, 0xde3e}, + {0xde40, 0xde7e}, {0xde80, 0xdebe}, {0xdec0, 0xdefe}, {0xdf00, 0xdf3e}, + {0xdf40, 0xdf7e}, {0xdf80, 0xdfbe}, {0xdfc0, 0xdffe}, {0xf900, 0xfa6d}, {0xfa70, 0xfad9}, {0xfb00, 0xfb06}, {0xfb13, 0xfb17}, {0xfb1f, 0xfb28}, {0xfb2a, 0xfb36}, {0xfb38, 0xfb3c}, {0xfb46, 0xfbb1}, {0xfbd3, 0xfd3d}, {0xfd50, 0xfd8f}, {0xfd92, 0xfdc7}, {0xfdf0, 0xfdfb}, {0xfe70, 0xfe74}, {0xfe76, 0xfefc}, {0xff21, 0xff3a}, {0xff41, 0xff5a}, {0xff66, 0xffbe}, {0xffc2, 0xffc7}, {0xffca, 0xffcf}, {0xffd2, 0xffd7}, {0xffda, 0xffdc} #if TCL_UTF_MAX > 4 - ,{0x10041, 0x1005a}, {0x10061, 0x1007a}, {0x100c0, 0x100d6}, {0x100d8, 0x100f6}, - {0x100f8, 0x102c1}, {0x102c6, 0x102d1}, {0x102e0, 0x102e4}, {0x10370, 0x10374}, - {0x1037a, 0x1037d}, {0x10388, 0x1038a}, {0x1038e, 0x103a1}, {0x103a3, 0x103f5}, - {0x103f7, 0x10481}, {0x1048a, 0x1052f}, {0x10531, 0x10556}, {0x10561, 0x10587}, - {0x105d0, 0x105ea}, {0x105f0, 0x105f2}, {0x10620, 0x1064a}, {0x10671, 0x106d3}, - {0x106fa, 0x106fc}, {0x10712, 0x1072f}, {0x1074d, 0x107a5}, {0x107ca, 0x107ea}, - {0x10800, 0x10815}, {0x10840, 0x10858}, {0x10860, 0x1086a}, {0x108a0, 0x108b4}, - {0x108b6, 0x108bd}, {0x10904, 0x10939}, {0x10958, 0x10961}, {0x10971, 0x10980}, - {0x10985, 0x1098c}, {0x10993, 0x109a8}, {0x109aa, 0x109b0}, {0x109b6, 0x109b9}, - {0x109df, 0x109e1}, {0x10a05, 0x10a0a}, {0x10a13, 0x10a28}, {0x10a2a, 0x10a30}, - {0x10a59, 0x10a5c}, {0x10a72, 0x10a74}, {0x10a85, 0x10a8d}, {0x10a8f, 0x10a91}, - {0x10a93, 0x10aa8}, {0x10aaa, 0x10ab0}, {0x10ab5, 0x10ab9}, {0x10b05, 0x10b0c}, - {0x10b13, 0x10b28}, {0x10b2a, 0x10b30}, {0x10b35, 0x10b39}, {0x10b5f, 0x10b61}, - {0x10b85, 0x10b8a}, {0x10b8e, 0x10b90}, {0x10b92, 0x10b95}, {0x10ba8, 0x10baa}, - {0x10bae, 0x10bb9}, {0x10c05, 0x10c0c}, {0x10c0e, 0x10c10}, {0x10c12, 0x10c28}, - {0x10c2a, 0x10c39}, {0x10c58, 0x10c5a}, {0x10c85, 0x10c8c}, {0x10c8e, 0x10c90}, - {0x10c92, 0x10ca8}, {0x10caa, 0x10cb3}, {0x10cb5, 0x10cb9}, {0x10d05, 0x10d0c}, - {0x10d0e, 0x10d10}, {0x10d12, 0x10d3a}, {0x10d54, 0x10d56}, {0x10d5f, 0x10d61}, - {0x10d7a, 0x10d7f}, {0x10d85, 0x10d96}, {0x10d9a, 0x10db1}, {0x10db3, 0x10dbb}, - {0x10dc0, 0x10dc6}, {0x10e01, 0x10e30}, {0x10e40, 0x10e46}, {0x10e94, 0x10e97}, - {0x10e99, 0x10e9f}, {0x10ea1, 0x10ea3}, {0x10ead, 0x10eb0}, {0x10ec0, 0x10ec4}, - {0x10edc, 0x10edf}, {0x10f40, 0x10f47}, {0x10f49, 0x10f6c}, {0x10f88, 0x10f8c}, - {0x11000, 0x1102a}, {0x11050, 0x11055}, {0x1105a, 0x1105d}, {0x1106e, 0x11070}, - {0x11075, 0x11081}, {0x110a0, 0x110c5}, {0x110d0, 0x110fa}, {0x110fc, 0x11248}, - {0x1124a, 0x1124d}, {0x11250, 0x11256}, {0x1125a, 0x1125d}, {0x11260, 0x11288}, - {0x1128a, 0x1128d}, {0x11290, 0x112b0}, {0x112b2, 0x112b5}, {0x112b8, 0x112be}, - {0x112c2, 0x112c5}, {0x112c8, 0x112d6}, {0x112d8, 0x11310}, {0x11312, 0x11315}, - {0x11318, 0x1135a}, {0x11380, 0x1138f}, {0x113a0, 0x113f5}, {0x113f8, 0x113fd}, - {0x11401, 0x1166c}, {0x1166f, 0x1167f}, {0x11681, 0x1169a}, {0x116a0, 0x116ea}, - {0x116f1, 0x116f8}, {0x11700, 0x1170c}, {0x1170e, 0x11711}, {0x11720, 0x11731}, - {0x11740, 0x11751}, {0x11760, 0x1176c}, {0x1176e, 0x11770}, {0x11780, 0x117b3}, - {0x11820, 0x11877}, {0x11880, 0x11884}, {0x11887, 0x118a8}, {0x118b0, 0x118f5}, - {0x11900, 0x1191e}, {0x11950, 0x1196d}, {0x11970, 0x11974}, {0x11980, 0x119ab}, - {0x119b0, 0x119c9}, {0x11a00, 0x11a16}, {0x11a20, 0x11a54}, {0x11b05, 0x11b33}, - {0x11b45, 0x11b4b}, {0x11b83, 0x11ba0}, {0x11bba, 0x11be5}, {0x11c00, 0x11c23}, - {0x11c4d, 0x11c4f}, {0x11c5a, 0x11c7d}, {0x11c80, 0x11c88}, {0x11ce9, 0x11cec}, - {0x11cee, 0x11cf1}, {0x11d00, 0x11dbf}, {0x11e00, 0x11f15}, {0x11f18, 0x11f1d}, - {0x11f20, 0x11f45}, {0x11f48, 0x11f4d}, {0x11f50, 0x11f57}, {0x11f5f, 0x11f7d}, - {0x11f80, 0x11fb4}, {0x11fb6, 0x11fbc}, {0x11fc2, 0x11fc4}, {0x11fc6, 0x11fcc}, - {0x11fd0, 0x11fd3}, {0x11fd6, 0x11fdb}, {0x11fe0, 0x11fec}, {0x11ff2, 0x11ff4}, - {0x11ff6, 0x11ffc}, {0x12090, 0x1209c}, {0x1210a, 0x12113}, {0x12119, 0x1211d}, - {0x1212a, 0x1212d}, {0x1212f, 0x12139}, {0x1213c, 0x1213f}, {0x12145, 0x12149}, - {0x12c00, 0x12c2e}, {0x12c30, 0x12c5e}, {0x12c60, 0x12ce4}, {0x12ceb, 0x12cee}, - {0x12d00, 0x12d25}, {0x12d30, 0x12d67}, {0x12d80, 0x12d96}, {0x12da0, 0x12da6}, - {0x12da8, 0x12dae}, {0x12db0, 0x12db6}, {0x12db8, 0x12dbe}, {0x12dc0, 0x12dc6}, - {0x12dc8, 0x12dce}, {0x12dd0, 0x12dd6}, {0x12dd8, 0x12dde}, {0x13031, 0x13035}, - {0x13041, 0x13096}, {0x1309d, 0x1309f}, {0x130a1, 0x130fa}, {0x130fc, 0x130ff}, - {0x13105, 0x1312e}, {0x13131, 0x1318e}, {0x131a0, 0x131ba}, {0x131f0, 0x131ff}, - {0x13400, 0x14db5}, {0x14e00, 0x19fea}, {0x1a000, 0x1a48c}, {0x1a4d0, 0x1a4fd}, - {0x1a500, 0x1a60c}, {0x1a610, 0x1a61f}, {0x1a640, 0x1a66e}, {0x1a67f, 0x1a69d}, - {0x1a6a0, 0x1a6e5}, {0x1a717, 0x1a71f}, {0x1a722, 0x1a788}, {0x1a78b, 0x1a7ae}, - {0x1a7b0, 0x1a7b7}, {0x1a7f7, 0x1a801}, {0x1a803, 0x1a805}, {0x1a807, 0x1a80a}, - {0x1a80c, 0x1a822}, {0x1a840, 0x1a873}, {0x1a882, 0x1a8b3}, {0x1a8f2, 0x1a8f7}, - {0x1a90a, 0x1a925}, {0x1a930, 0x1a946}, {0x1a960, 0x1a97c}, {0x1a984, 0x1a9b2}, - {0x1a9e0, 0x1a9e4}, {0x1a9e6, 0x1a9ef}, {0x1a9fa, 0x1a9fe}, {0x1aa00, 0x1aa28}, - {0x1aa40, 0x1aa42}, {0x1aa44, 0x1aa4b}, {0x1aa60, 0x1aa76}, {0x1aa7e, 0x1aaaf}, - {0x1aab9, 0x1aabd}, {0x1aadb, 0x1aadd}, {0x1aae0, 0x1aaea}, {0x1aaf2, 0x1aaf4}, - {0x1ab01, 0x1ab06}, {0x1ab09, 0x1ab0e}, {0x1ab11, 0x1ab16}, {0x1ab20, 0x1ab26}, - {0x1ab28, 0x1ab2e}, {0x1ab30, 0x1ab5a}, {0x1ab5c, 0x1ab65}, {0x1ab70, 0x1abe2}, - {0x1ac00, 0x1d7a3}, {0x1d7b0, 0x1d7c6}, {0x1d7cb, 0x1d7fb}, {0x1f900, 0x1fa6d}, - {0x1fa70, 0x1fad9}, {0x1fb00, 0x1fb06}, {0x1fb13, 0x1fb17}, {0x1fb1f, 0x1fb28}, - {0x1fb2a, 0x1fb36}, {0x1fb38, 0x1fb3c}, {0x1fb46, 0x1fbb1}, {0x1fbd3, 0x1fd3d}, - {0x1fd50, 0x1fd8f}, {0x1fd92, 0x1fdc7}, {0x1fdf0, 0x1fdfb}, {0x1fe70, 0x1fe74}, - {0x1fe76, 0x1fefc}, {0x1ff21, 0x1ff3a}, {0x1ff41, 0x1ff5a}, {0x1ff66, 0x1ffbe}, - {0x1ffc2, 0x1ffc7}, {0x1ffca, 0x1ffcf}, {0x1ffd2, 0x1ffd7}, {0x1ffda, 0x1ffdc}, - {0x20041, 0x2005a}, {0x20061, 0x2007a}, {0x200c0, 0x200d6}, {0x200d8, 0x200f6}, - {0x200f8, 0x202c1}, {0x202c6, 0x202d1}, {0x202e0, 0x202e4}, {0x20370, 0x20374}, - {0x2037a, 0x2037d}, {0x20388, 0x2038a}, {0x2038e, 0x203a1}, {0x203a3, 0x203f5}, - {0x203f7, 0x20481}, {0x2048a, 0x2052f}, {0x20531, 0x20556}, {0x20561, 0x20587}, - {0x205d0, 0x205ea}, {0x205f0, 0x205f2}, {0x20620, 0x2064a}, {0x20671, 0x206d3}, - {0x206fa, 0x206fc}, {0x20712, 0x2072f}, {0x2074d, 0x207a5}, {0x207ca, 0x207ea}, - {0x20800, 0x20815}, {0x20840, 0x20858}, {0x20860, 0x2086a}, {0x208a0, 0x208b4}, - {0x208b6, 0x208bd}, {0x20904, 0x20939}, {0x20958, 0x20961}, {0x20971, 0x20980}, - {0x20985, 0x2098c}, {0x20993, 0x209a8}, {0x209aa, 0x209b0}, {0x209b6, 0x209b9}, - {0x209df, 0x209e1}, {0x20a05, 0x20a0a}, {0x20a13, 0x20a28}, {0x20a2a, 0x20a30}, - {0x20a59, 0x20a5c}, {0x20a72, 0x20a74}, {0x20a85, 0x20a8d}, {0x20a8f, 0x20a91}, - {0x20a93, 0x20aa8}, {0x20aaa, 0x20ab0}, {0x20ab5, 0x20ab9}, {0x20b05, 0x20b0c}, - {0x20b13, 0x20b28}, {0x20b2a, 0x20b30}, {0x20b35, 0x20b39}, {0x20b5f, 0x20b61}, - {0x20b85, 0x20b8a}, {0x20b8e, 0x20b90}, {0x20b92, 0x20b95}, {0x20ba8, 0x20baa}, - {0x20bae, 0x20bb9}, {0x20c05, 0x20c0c}, {0x20c0e, 0x20c10}, {0x20c12, 0x20c28}, - {0x20c2a, 0x20c39}, {0x20c58, 0x20c5a}, {0x20c85, 0x20c8c}, {0x20c8e, 0x20c90}, - {0x20c92, 0x20ca8}, {0x20caa, 0x20cb3}, {0x20cb5, 0x20cb9}, {0x20d05, 0x20d0c}, - {0x20d0e, 0x20d10}, {0x20d12, 0x20d3a}, {0x20d54, 0x20d56}, {0x20d5f, 0x20d61}, - {0x20d7a, 0x20d7f}, {0x20d85, 0x20d96}, {0x20d9a, 0x20db1}, {0x20db3, 0x20dbb}, - {0x20dc0, 0x20dc6}, {0x20e01, 0x20e30}, {0x20e40, 0x20e46}, {0x20e94, 0x20e97}, - {0x20e99, 0x20e9f}, {0x20ea1, 0x20ea3}, {0x20ead, 0x20eb0}, {0x20ec0, 0x20ec4}, - {0x20edc, 0x20edf}, {0x20f40, 0x20f47}, {0x20f49, 0x20f6c}, {0x20f88, 0x20f8c}, - {0x21000, 0x2102a}, {0x21050, 0x21055}, {0x2105a, 0x2105d}, {0x2106e, 0x21070}, - {0x21075, 0x21081}, {0x210a0, 0x210c5}, {0x210d0, 0x210fa}, {0x210fc, 0x21248}, - {0x2124a, 0x2124d}, {0x21250, 0x21256}, {0x2125a, 0x2125d}, {0x21260, 0x21288}, - {0x2128a, 0x2128d}, {0x21290, 0x212b0}, {0x212b2, 0x212b5}, {0x212b8, 0x212be}, - {0x212c2, 0x212c5}, {0x212c8, 0x212d6}, {0x212d8, 0x21310}, {0x21312, 0x21315}, - {0x21318, 0x2135a}, {0x21380, 0x2138f}, {0x213a0, 0x213f5}, {0x213f8, 0x213fd}, - {0x21401, 0x2166c}, {0x2166f, 0x2167f}, {0x21681, 0x2169a}, {0x216a0, 0x216ea}, - {0x216f1, 0x216f8}, {0x21700, 0x2170c}, {0x2170e, 0x21711}, {0x21720, 0x21731}, - {0x21740, 0x21751}, {0x21760, 0x2176c}, {0x2176e, 0x21770}, {0x21780, 0x217b3}, - {0x21820, 0x21877}, {0x21880, 0x21884}, {0x21887, 0x218a8}, {0x218b0, 0x218f5}, - {0x21900, 0x2191e}, {0x21950, 0x2196d}, {0x21970, 0x21974}, {0x21980, 0x219ab}, - {0x219b0, 0x219c9}, {0x21a00, 0x21a16}, {0x21a20, 0x21a54}, {0x21b05, 0x21b33}, - {0x21b45, 0x21b4b}, {0x21b83, 0x21ba0}, {0x21bba, 0x21be5}, {0x21c00, 0x21c23}, - {0x21c4d, 0x21c4f}, {0x21c5a, 0x21c7d}, {0x21c80, 0x21c88}, {0x21ce9, 0x21cec}, - {0x21cee, 0x21cf1}, {0x21d00, 0x21dbf}, {0x21e00, 0x21f15}, {0x21f18, 0x21f1d}, - {0x21f20, 0x21f45}, {0x21f48, 0x21f4d}, {0x21f50, 0x21f57}, {0x21f5f, 0x21f7d}, - {0x21f80, 0x21fb4}, {0x21fb6, 0x21fbc}, {0x21fc2, 0x21fc4}, {0x21fc6, 0x21fcc}, - {0x21fd0, 0x21fd3}, {0x21fd6, 0x21fdb}, {0x21fe0, 0x21fec}, {0x21ff2, 0x21ff4}, - {0x21ff6, 0x21ffc}, {0x22090, 0x2209c}, {0x2210a, 0x22113}, {0x22119, 0x2211d}, - {0x2212a, 0x2212d}, {0x2212f, 0x22139}, {0x2213c, 0x2213f}, {0x22145, 0x22149}, - {0x22c00, 0x22c2e}, {0x22c30, 0x22c5e}, {0x22c60, 0x22ce4}, {0x22ceb, 0x22cee}, - {0x22d00, 0x22d25}, {0x22d30, 0x22d67}, {0x22d80, 0x22d96}, {0x22da0, 0x22da6}, - {0x22da8, 0x22dae}, {0x22db0, 0x22db6}, {0x22db8, 0x22dbe}, {0x22dc0, 0x22dc6}, - {0x22dc8, 0x22dce}, {0x22dd0, 0x22dd6}, {0x22dd8, 0x22dde}, {0x23031, 0x23035}, - {0x23041, 0x23096}, {0x2309d, 0x2309f}, {0x230a1, 0x230fa}, {0x230fc, 0x230ff}, - {0x23105, 0x2312e}, {0x23131, 0x2318e}, {0x231a0, 0x231ba}, {0x231f0, 0x231ff}, - {0x23400, 0x24db5}, {0x24e00, 0x29fea}, {0x2a000, 0x2a48c}, {0x2a4d0, 0x2a4fd}, - {0x2a500, 0x2a60c}, {0x2a610, 0x2a61f}, {0x2a640, 0x2a66e}, {0x2a67f, 0x2a69d}, - {0x2a6a0, 0x2a6e5}, {0x2a717, 0x2a71f}, {0x2a722, 0x2a788}, {0x2a78b, 0x2a7ae}, - {0x2a7b0, 0x2a7b7}, {0x2a7f7, 0x2a801}, {0x2a803, 0x2a805}, {0x2a807, 0x2a80a}, - {0x2a80c, 0x2a822}, {0x2a840, 0x2a873}, {0x2a882, 0x2a8b3}, {0x2a8f2, 0x2a8f7}, - {0x2a90a, 0x2a925}, {0x2a930, 0x2a946}, {0x2a960, 0x2a97c}, {0x2a984, 0x2a9b2}, - {0x2a9e0, 0x2a9e4}, {0x2a9e6, 0x2a9ef}, {0x2a9fa, 0x2a9fe}, {0x2aa00, 0x2aa28}, - {0x2aa40, 0x2aa42}, {0x2aa44, 0x2aa4b}, {0x2aa60, 0x2aa76}, {0x2aa7e, 0x2aaaf}, - {0x2aab9, 0x2aabd}, {0x2aadb, 0x2aadd}, {0x2aae0, 0x2aaea}, {0x2aaf2, 0x2aaf4}, - {0x2ab01, 0x2ab06}, {0x2ab09, 0x2ab0e}, {0x2ab11, 0x2ab16}, {0x2ab20, 0x2ab26}, - {0x2ab28, 0x2ab2e}, {0x2ab30, 0x2ab5a}, {0x2ab5c, 0x2ab65}, {0x2ab70, 0x2abe2}, - {0x2ac00, 0x2d7a3}, {0x2d7b0, 0x2d7c6}, {0x2d7cb, 0x2d7fb}, {0x2f900, 0x2fa6d}, - {0x2fa70, 0x2fad9}, {0x2fb00, 0x2fb06}, {0x2fb13, 0x2fb17}, {0x2fb1f, 0x2fb28}, - {0x2fb2a, 0x2fb36}, {0x2fb38, 0x2fb3c}, {0x2fb46, 0x2fbb1}, {0x2fbd3, 0x2fd3d}, - {0x2fd50, 0x2fd8f}, {0x2fd92, 0x2fdc7}, {0x2fdf0, 0x2fdfb}, {0x2fe70, 0x2fe74}, - {0x2fe76, 0x2fefc}, {0x2ff21, 0x2ff3a}, {0x2ff41, 0x2ff5a}, {0x2ff66, 0x2ffbe}, - {0x2ffc2, 0x2ffc7}, {0x2ffca, 0x2ffcf}, {0x2ffd2, 0x2ffd7}, {0x2ffda, 0x2ffdc}, - {0x30041, 0x3005a}, {0x30061, 0x3007a}, {0x300c0, 0x300d6}, {0x300d8, 0x300f6}, - {0x300f8, 0x302c1}, {0x302c6, 0x302d1}, {0x302e0, 0x302e4}, {0x30370, 0x30374}, - {0x3037a, 0x3037d}, {0x30388, 0x3038a}, {0x3038e, 0x303a1}, {0x303a3, 0x303f5}, - {0x303f7, 0x30481}, {0x3048a, 0x3052f}, {0x30531, 0x30556}, {0x30561, 0x30587}, - {0x305d0, 0x305ea}, {0x305f0, 0x305f2}, {0x30620, 0x3064a}, {0x30671, 0x306d3}, - {0x306fa, 0x306fc}, {0x30712, 0x3072f}, {0x3074d, 0x307a5}, {0x307ca, 0x307ea}, - {0x30800, 0x30815}, {0x30840, 0x30858}, {0x30860, 0x3086a}, {0x308a0, 0x308b4}, - {0x308b6, 0x308bd}, {0x30904, 0x30939}, {0x30958, 0x30961}, {0x30971, 0x30980}, - {0x30985, 0x3098c}, {0x30993, 0x309a8}, {0x309aa, 0x309b0}, {0x309b6, 0x309b9}, - {0x309df, 0x309e1}, {0x30a05, 0x30a0a}, {0x30a13, 0x30a28}, {0x30a2a, 0x30a30}, - {0x30a59, 0x30a5c}, {0x30a72, 0x30a74}, {0x30a85, 0x30a8d}, {0x30a8f, 0x30a91}, - {0x30a93, 0x30aa8}, {0x30aaa, 0x30ab0}, {0x30ab5, 0x30ab9}, {0x30b05, 0x30b0c}, - {0x30b13, 0x30b28}, {0x30b2a, 0x30b30}, {0x30b35, 0x30b39}, {0x30b5f, 0x30b61}, - {0x30b85, 0x30b8a}, {0x30b8e, 0x30b90}, {0x30b92, 0x30b95}, {0x30ba8, 0x30baa}, - {0x30bae, 0x30bb9}, {0x30c05, 0x30c0c}, {0x30c0e, 0x30c10}, {0x30c12, 0x30c28}, - {0x30c2a, 0x30c39}, {0x30c58, 0x30c5a}, {0x30c85, 0x30c8c}, {0x30c8e, 0x30c90}, - {0x30c92, 0x30ca8}, {0x30caa, 0x30cb3}, {0x30cb5, 0x30cb9}, {0x30d05, 0x30d0c}, - {0x30d0e, 0x30d10}, {0x30d12, 0x30d3a}, {0x30d54, 0x30d56}, {0x30d5f, 0x30d61}, - {0x30d7a, 0x30d7f}, {0x30d85, 0x30d96}, {0x30d9a, 0x30db1}, {0x30db3, 0x30dbb}, - {0x30dc0, 0x30dc6}, {0x30e01, 0x30e30}, {0x30e40, 0x30e46}, {0x30e94, 0x30e97}, - {0x30e99, 0x30e9f}, {0x30ea1, 0x30ea3}, {0x30ead, 0x30eb0}, {0x30ec0, 0x30ec4}, - {0x30edc, 0x30edf}, {0x30f40, 0x30f47}, {0x30f49, 0x30f6c}, {0x30f88, 0x30f8c}, - {0x31000, 0x3102a}, {0x31050, 0x31055}, {0x3105a, 0x3105d}, {0x3106e, 0x31070}, - {0x31075, 0x31081}, {0x310a0, 0x310c5}, {0x310d0, 0x310fa}, {0x310fc, 0x31248}, - {0x3124a, 0x3124d}, {0x31250, 0x31256}, {0x3125a, 0x3125d}, {0x31260, 0x31288}, - {0x3128a, 0x3128d}, {0x31290, 0x312b0}, {0x312b2, 0x312b5}, {0x312b8, 0x312be}, - {0x312c2, 0x312c5}, {0x312c8, 0x312d6}, {0x312d8, 0x31310}, {0x31312, 0x31315}, - {0x31318, 0x3135a}, {0x31380, 0x3138f}, {0x313a0, 0x313f5}, {0x313f8, 0x313fd}, - {0x31401, 0x3166c}, {0x3166f, 0x3167f}, {0x31681, 0x3169a}, {0x316a0, 0x316ea}, - {0x316f1, 0x316f8}, {0x31700, 0x3170c}, {0x3170e, 0x31711}, {0x31720, 0x31731}, - {0x31740, 0x31751}, {0x31760, 0x3176c}, {0x3176e, 0x31770}, {0x31780, 0x317b3}, - {0x31820, 0x31877}, {0x31880, 0x31884}, {0x31887, 0x318a8}, {0x318b0, 0x318f5}, - {0x31900, 0x3191e}, {0x31950, 0x3196d}, {0x31970, 0x31974}, {0x31980, 0x319ab}, - {0x319b0, 0x319c9}, {0x31a00, 0x31a16}, {0x31a20, 0x31a54}, {0x31b05, 0x31b33}, - {0x31b45, 0x31b4b}, {0x31b83, 0x31ba0}, {0x31bba, 0x31be5}, {0x31c00, 0x31c23}, - {0x31c4d, 0x31c4f}, {0x31c5a, 0x31c7d}, {0x31c80, 0x31c88}, {0x31ce9, 0x31cec}, - {0x31cee, 0x31cf1}, {0x31d00, 0x31dbf}, {0x31e00, 0x31f15}, {0x31f18, 0x31f1d}, - {0x31f20, 0x31f45}, {0x31f48, 0x31f4d}, {0x31f50, 0x31f57}, {0x31f5f, 0x31f7d}, - {0x31f80, 0x31fb4}, {0x31fb6, 0x31fbc}, {0x31fc2, 0x31fc4}, {0x31fc6, 0x31fcc}, - {0x31fd0, 0x31fd3}, {0x31fd6, 0x31fdb}, {0x31fe0, 0x31fec}, {0x31ff2, 0x31ff4}, - {0x31ff6, 0x31ffc}, {0x32090, 0x3209c}, {0x3210a, 0x32113}, {0x32119, 0x3211d}, - {0x3212a, 0x3212d}, {0x3212f, 0x32139}, {0x3213c, 0x3213f}, {0x32145, 0x32149}, - {0x32c00, 0x32c2e}, {0x32c30, 0x32c5e}, {0x32c60, 0x32ce4}, {0x32ceb, 0x32cee}, - {0x32d00, 0x32d25}, {0x32d30, 0x32d67}, {0x32d80, 0x32d96}, {0x32da0, 0x32da6}, - {0x32da8, 0x32dae}, {0x32db0, 0x32db6}, {0x32db8, 0x32dbe}, {0x32dc0, 0x32dc6}, - {0x32dc8, 0x32dce}, {0x32dd0, 0x32dd6}, {0x32dd8, 0x32dde}, {0x33031, 0x33035}, - {0x33041, 0x33096}, {0x3309d, 0x3309f}, {0x330a1, 0x330fa}, {0x330fc, 0x330ff}, - {0x33105, 0x3312e}, {0x33131, 0x3318e}, {0x331a0, 0x331ba}, {0x331f0, 0x331ff}, - {0x33400, 0x34db5}, {0x34e00, 0x39fea}, {0x3a000, 0x3a48c}, {0x3a4d0, 0x3a4fd}, - {0x3a500, 0x3a60c}, {0x3a610, 0x3a61f}, {0x3a640, 0x3a66e}, {0x3a67f, 0x3a69d}, - {0x3a6a0, 0x3a6e5}, {0x3a717, 0x3a71f}, {0x3a722, 0x3a788}, {0x3a78b, 0x3a7ae}, - {0x3a7b0, 0x3a7b7}, {0x3a7f7, 0x3a801}, {0x3a803, 0x3a805}, {0x3a807, 0x3a80a}, - {0x3a80c, 0x3a822}, {0x3a840, 0x3a873}, {0x3a882, 0x3a8b3}, {0x3a8f2, 0x3a8f7}, - {0x3a90a, 0x3a925}, {0x3a930, 0x3a946}, {0x3a960, 0x3a97c}, {0x3a984, 0x3a9b2}, - {0x3a9e0, 0x3a9e4}, {0x3a9e6, 0x3a9ef}, {0x3a9fa, 0x3a9fe}, {0x3aa00, 0x3aa28}, - {0x3aa40, 0x3aa42}, {0x3aa44, 0x3aa4b}, {0x3aa60, 0x3aa76}, {0x3aa7e, 0x3aaaf}, - {0x3aab9, 0x3aabd}, {0x3aadb, 0x3aadd}, {0x3aae0, 0x3aaea}, {0x3aaf2, 0x3aaf4}, - {0x3ab01, 0x3ab06}, {0x3ab09, 0x3ab0e}, {0x3ab11, 0x3ab16}, {0x3ab20, 0x3ab26}, - {0x3ab28, 0x3ab2e}, {0x3ab30, 0x3ab5a}, {0x3ab5c, 0x3ab65}, {0x3ab70, 0x3abe2}, - {0x3ac00, 0x3d7a3}, {0x3d7b0, 0x3d7c6}, {0x3d7cb, 0x3d7fb}, {0x3f900, 0x3fa6d}, - {0x3fa70, 0x3fad9}, {0x3fb00, 0x3fb06}, {0x3fb13, 0x3fb17}, {0x3fb1f, 0x3fb28}, - {0x3fb2a, 0x3fb36}, {0x3fb38, 0x3fb3c}, {0x3fb46, 0x3fbb1}, {0x3fbd3, 0x3fd3d}, - {0x3fd50, 0x3fd8f}, {0x3fd92, 0x3fdc7}, {0x3fdf0, 0x3fdfb}, {0x3fe70, 0x3fe74}, - {0x3fe76, 0x3fefc}, {0x3ff21, 0x3ff3a}, {0x3ff41, 0x3ff5a}, {0x3ff66, 0x3ffbe}, - {0x3ffc2, 0x3ffc7}, {0x3ffca, 0x3ffcf}, {0x3ffd2, 0x3ffd7}, {0x3ffda, 0x3ffdc}, - {0x40041, 0x4005a}, {0x40061, 0x4007a}, {0x400c0, 0x400d6}, {0x400d8, 0x400f6}, - {0x400f8, 0x402c1}, {0x402c6, 0x402d1}, {0x402e0, 0x402e4}, {0x40370, 0x40374}, - {0x4037a, 0x4037d}, {0x40388, 0x4038a}, {0x4038e, 0x403a1}, {0x403a3, 0x403f5}, - {0x403f7, 0x40481}, {0x4048a, 0x4052f}, {0x40531, 0x40556}, {0x40561, 0x40587}, - {0x405d0, 0x405ea}, {0x405f0, 0x405f2}, {0x40620, 0x4064a}, {0x40671, 0x406d3}, - {0x406fa, 0x406fc}, {0x40712, 0x4072f}, {0x4074d, 0x407a5}, {0x407ca, 0x407ea}, - {0x40800, 0x40815}, {0x40840, 0x40858}, {0x40860, 0x4086a}, {0x408a0, 0x408b4}, - {0x408b6, 0x408bd}, {0x40904, 0x40939}, {0x40958, 0x40961}, {0x40971, 0x40980}, - {0x40985, 0x4098c}, {0x40993, 0x409a8}, {0x409aa, 0x409b0}, {0x409b6, 0x409b9}, - {0x409df, 0x409e1}, {0x40a05, 0x40a0a}, {0x40a13, 0x40a28}, {0x40a2a, 0x40a30}, - {0x40a59, 0x40a5c}, {0x40a72, 0x40a74}, {0x40a85, 0x40a8d}, {0x40a8f, 0x40a91}, - {0x40a93, 0x40aa8}, {0x40aaa, 0x40ab0}, {0x40ab5, 0x40ab9}, {0x40b05, 0x40b0c}, - {0x40b13, 0x40b28}, {0x40b2a, 0x40b30}, {0x40b35, 0x40b39}, {0x40b5f, 0x40b61}, - {0x40b85, 0x40b8a}, {0x40b8e, 0x40b90}, {0x40b92, 0x40b95}, {0x40ba8, 0x40baa}, - {0x40bae, 0x40bb9}, {0x40c05, 0x40c0c}, {0x40c0e, 0x40c10}, {0x40c12, 0x40c28}, - {0x40c2a, 0x40c39}, {0x40c58, 0x40c5a}, {0x40c85, 0x40c8c}, {0x40c8e, 0x40c90}, - {0x40c92, 0x40ca8}, {0x40caa, 0x40cb3}, {0x40cb5, 0x40cb9}, {0x40d05, 0x40d0c}, - {0x40d0e, 0x40d10}, {0x40d12, 0x40d3a}, {0x40d54, 0x40d56}, {0x40d5f, 0x40d61}, - {0x40d7a, 0x40d7f}, {0x40d85, 0x40d96}, {0x40d9a, 0x40db1}, {0x40db3, 0x40dbb}, - {0x40dc0, 0x40dc6}, {0x40e01, 0x40e30}, {0x40e40, 0x40e46}, {0x40e94, 0x40e97}, - {0x40e99, 0x40e9f}, {0x40ea1, 0x40ea3}, {0x40ead, 0x40eb0}, {0x40ec0, 0x40ec4}, - {0x40edc, 0x40edf}, {0x40f40, 0x40f47}, {0x40f49, 0x40f6c}, {0x40f88, 0x40f8c}, - {0x41000, 0x4102a}, {0x41050, 0x41055}, {0x4105a, 0x4105d}, {0x4106e, 0x41070}, - {0x41075, 0x41081}, {0x410a0, 0x410c5}, {0x410d0, 0x410fa}, {0x410fc, 0x41248}, - {0x4124a, 0x4124d}, {0x41250, 0x41256}, {0x4125a, 0x4125d}, {0x41260, 0x41288}, - {0x4128a, 0x4128d}, {0x41290, 0x412b0}, {0x412b2, 0x412b5}, {0x412b8, 0x412be}, - {0x412c2, 0x412c5}, {0x412c8, 0x412d6}, {0x412d8, 0x41310}, {0x41312, 0x41315}, - {0x41318, 0x4135a}, {0x41380, 0x4138f}, {0x413a0, 0x413f5}, {0x413f8, 0x413fd}, - {0x41401, 0x4166c}, {0x4166f, 0x4167f}, {0x41681, 0x4169a}, {0x416a0, 0x416ea}, - {0x416f1, 0x416f8}, {0x41700, 0x4170c}, {0x4170e, 0x41711}, {0x41720, 0x41731}, - {0x41740, 0x41751}, {0x41760, 0x4176c}, {0x4176e, 0x41770}, {0x41780, 0x417b3}, - {0x41820, 0x41877}, {0x41880, 0x41884}, {0x41887, 0x418a8}, {0x418b0, 0x418f5}, - {0x41900, 0x4191e}, {0x41950, 0x4196d}, {0x41970, 0x41974}, {0x41980, 0x419ab}, - {0x419b0, 0x419c9}, {0x41a00, 0x41a16}, {0x41a20, 0x41a54}, {0x41b05, 0x41b33}, - {0x41b45, 0x41b4b}, {0x41b83, 0x41ba0}, {0x41bba, 0x41be5}, {0x41c00, 0x41c23}, - {0x41c4d, 0x41c4f}, {0x41c5a, 0x41c7d}, {0x41c80, 0x41c88}, {0x41ce9, 0x41cec}, - {0x41cee, 0x41cf1}, {0x41d00, 0x41dbf}, {0x41e00, 0x41f15}, {0x41f18, 0x41f1d}, - {0x41f20, 0x41f45}, {0x41f48, 0x41f4d}, {0x41f50, 0x41f57}, {0x41f5f, 0x41f7d}, - {0x41f80, 0x41fb4}, {0x41fb6, 0x41fbc}, {0x41fc2, 0x41fc4}, {0x41fc6, 0x41fcc}, - {0x41fd0, 0x41fd3}, {0x41fd6, 0x41fdb}, {0x41fe0, 0x41fec}, {0x41ff2, 0x41ff4}, - {0x41ff6, 0x41ffc}, {0x42090, 0x4209c}, {0x4210a, 0x42113}, {0x42119, 0x4211d}, - {0x4212a, 0x4212d}, {0x4212f, 0x42139}, {0x4213c, 0x4213f}, {0x42145, 0x42149}, - {0x42c00, 0x42c2e}, {0x42c30, 0x42c5e}, {0x42c60, 0x42ce4}, {0x42ceb, 0x42cee}, - {0x42d00, 0x42d25}, {0x42d30, 0x42d67}, {0x42d80, 0x42d96}, {0x42da0, 0x42da6}, - {0x42da8, 0x42dae}, {0x42db0, 0x42db6}, {0x42db8, 0x42dbe}, {0x42dc0, 0x42dc6}, - {0x42dc8, 0x42dce}, {0x42dd0, 0x42dd6}, {0x42dd8, 0x42dde}, {0x43031, 0x43035}, - {0x43041, 0x43096}, {0x4309d, 0x4309f}, {0x430a1, 0x430fa}, {0x430fc, 0x430ff}, - {0x43105, 0x4312e}, {0x43131, 0x4318e}, {0x431a0, 0x431ba}, {0x431f0, 0x431ff}, - {0x43400, 0x44db5}, {0x44e00, 0x49fea}, {0x4a000, 0x4a48c}, {0x4a4d0, 0x4a4fd}, - {0x4a500, 0x4a60c}, {0x4a610, 0x4a61f}, {0x4a640, 0x4a66e}, {0x4a67f, 0x4a69d}, - {0x4a6a0, 0x4a6e5}, {0x4a717, 0x4a71f}, {0x4a722, 0x4a788}, {0x4a78b, 0x4a7ae}, - {0x4a7b0, 0x4a7b7}, {0x4a7f7, 0x4a801}, {0x4a803, 0x4a805}, {0x4a807, 0x4a80a}, - {0x4a80c, 0x4a822}, {0x4a840, 0x4a873}, {0x4a882, 0x4a8b3}, {0x4a8f2, 0x4a8f7}, - {0x4a90a, 0x4a925}, {0x4a930, 0x4a946}, {0x4a960, 0x4a97c}, {0x4a984, 0x4a9b2}, - {0x4a9e0, 0x4a9e4}, {0x4a9e6, 0x4a9ef}, {0x4a9fa, 0x4a9fe}, {0x4aa00, 0x4aa28}, - {0x4aa40, 0x4aa42}, {0x4aa44, 0x4aa4b}, {0x4aa60, 0x4aa76}, {0x4aa7e, 0x4aaaf}, - {0x4aab9, 0x4aabd}, {0x4aadb, 0x4aadd}, {0x4aae0, 0x4aaea}, {0x4aaf2, 0x4aaf4}, - {0x4ab01, 0x4ab06}, {0x4ab09, 0x4ab0e}, {0x4ab11, 0x4ab16}, {0x4ab20, 0x4ab26}, - {0x4ab28, 0x4ab2e}, {0x4ab30, 0x4ab5a}, {0x4ab5c, 0x4ab65}, {0x4ab70, 0x4abe2}, - {0x4ac00, 0x4d7a3}, {0x4d7b0, 0x4d7c6}, {0x4d7cb, 0x4d7fb}, {0x4f900, 0x4fa6d}, - {0x4fa70, 0x4fad9}, {0x4fb00, 0x4fb06}, {0x4fb13, 0x4fb17}, {0x4fb1f, 0x4fb28}, - {0x4fb2a, 0x4fb36}, {0x4fb38, 0x4fb3c}, {0x4fb46, 0x4fbb1}, {0x4fbd3, 0x4fd3d}, - {0x4fd50, 0x4fd8f}, {0x4fd92, 0x4fdc7}, {0x4fdf0, 0x4fdfb}, {0x4fe70, 0x4fe74}, - {0x4fe76, 0x4fefc}, {0x4ff21, 0x4ff3a}, {0x4ff41, 0x4ff5a}, {0x4ff66, 0x4ffbe}, - {0x4ffc2, 0x4ffc7}, {0x4ffca, 0x4ffcf}, {0x4ffd2, 0x4ffd7}, {0x4ffda, 0x4ffdc}, - {0x50041, 0x5005a}, {0x50061, 0x5007a}, {0x500c0, 0x500d6}, {0x500d8, 0x500f6}, - {0x500f8, 0x502c1}, {0x502c6, 0x502d1}, {0x502e0, 0x502e4}, {0x50370, 0x50374}, - {0x5037a, 0x5037d}, {0x50388, 0x5038a}, {0x5038e, 0x503a1}, {0x503a3, 0x503f5}, - {0x503f7, 0x50481}, {0x5048a, 0x5052f}, {0x50531, 0x50556}, {0x50561, 0x50587}, - {0x505d0, 0x505ea}, {0x505f0, 0x505f2}, {0x50620, 0x5064a}, {0x50671, 0x506d3}, - {0x506fa, 0x506fc}, {0x50712, 0x5072f}, {0x5074d, 0x507a5}, {0x507ca, 0x507ea}, - {0x50800, 0x50815}, {0x50840, 0x50858}, {0x50860, 0x5086a}, {0x508a0, 0x508b4}, - {0x508b6, 0x508bd}, {0x50904, 0x50939}, {0x50958, 0x50961}, {0x50971, 0x50980}, - {0x50985, 0x5098c}, {0x50993, 0x509a8}, {0x509aa, 0x509b0}, {0x509b6, 0x509b9}, - {0x509df, 0x509e1}, {0x50a05, 0x50a0a}, {0x50a13, 0x50a28}, {0x50a2a, 0x50a30}, - {0x50a59, 0x50a5c}, {0x50a72, 0x50a74}, {0x50a85, 0x50a8d}, {0x50a8f, 0x50a91}, - {0x50a93, 0x50aa8}, {0x50aaa, 0x50ab0}, {0x50ab5, 0x50ab9}, {0x50b05, 0x50b0c}, - {0x50b13, 0x50b28}, {0x50b2a, 0x50b30}, {0x50b35, 0x50b39}, {0x50b5f, 0x50b61}, - {0x50b85, 0x50b8a}, {0x50b8e, 0x50b90}, {0x50b92, 0x50b95}, {0x50ba8, 0x50baa}, - {0x50bae, 0x50bb9}, {0x50c05, 0x50c0c}, {0x50c0e, 0x50c10}, {0x50c12, 0x50c28}, - {0x50c2a, 0x50c39}, {0x50c58, 0x50c5a}, {0x50c85, 0x50c8c}, {0x50c8e, 0x50c90}, - {0x50c92, 0x50ca8}, {0x50caa, 0x50cb3}, {0x50cb5, 0x50cb9}, {0x50d05, 0x50d0c}, - {0x50d0e, 0x50d10}, {0x50d12, 0x50d3a}, {0x50d54, 0x50d56}, {0x50d5f, 0x50d61}, - {0x50d7a, 0x50d7f}, {0x50d85, 0x50d96}, {0x50d9a, 0x50db1}, {0x50db3, 0x50dbb}, - {0x50dc0, 0x50dc6}, {0x50e01, 0x50e30}, {0x50e40, 0x50e46}, {0x50e94, 0x50e97}, - {0x50e99, 0x50e9f}, {0x50ea1, 0x50ea3}, {0x50ead, 0x50eb0}, {0x50ec0, 0x50ec4}, - {0x50edc, 0x50edf}, {0x50f40, 0x50f47}, {0x50f49, 0x50f6c}, {0x50f88, 0x50f8c}, - {0x51000, 0x5102a}, {0x51050, 0x51055}, {0x5105a, 0x5105d}, {0x5106e, 0x51070}, - {0x51075, 0x51081}, {0x510a0, 0x510c5}, {0x510d0, 0x510fa}, {0x510fc, 0x51248}, - {0x5124a, 0x5124d}, {0x51250, 0x51256}, {0x5125a, 0x5125d}, {0x51260, 0x51288}, - {0x5128a, 0x5128d}, {0x51290, 0x512b0}, {0x512b2, 0x512b5}, {0x512b8, 0x512be}, - {0x512c2, 0x512c5}, {0x512c8, 0x512d6}, {0x512d8, 0x51310}, {0x51312, 0x51315}, - {0x51318, 0x5135a}, {0x51380, 0x5138f}, {0x513a0, 0x513f5}, {0x513f8, 0x513fd}, - {0x51401, 0x5166c}, {0x5166f, 0x5167f}, {0x51681, 0x5169a}, {0x516a0, 0x516ea}, - {0x516f1, 0x516f8}, {0x51700, 0x5170c}, {0x5170e, 0x51711}, {0x51720, 0x51731}, - {0x51740, 0x51751}, {0x51760, 0x5176c}, {0x5176e, 0x51770}, {0x51780, 0x517b3}, - {0x51820, 0x51877}, {0x51880, 0x51884}, {0x51887, 0x518a8}, {0x518b0, 0x518f5}, - {0x51900, 0x5191e}, {0x51950, 0x5196d}, {0x51970, 0x51974}, {0x51980, 0x519ab}, - {0x519b0, 0x519c9}, {0x51a00, 0x51a16}, {0x51a20, 0x51a54}, {0x51b05, 0x51b33}, - {0x51b45, 0x51b4b}, {0x51b83, 0x51ba0}, {0x51bba, 0x51be5}, {0x51c00, 0x51c23}, - {0x51c4d, 0x51c4f}, {0x51c5a, 0x51c7d}, {0x51c80, 0x51c88}, {0x51ce9, 0x51cec}, - {0x51cee, 0x51cf1}, {0x51d00, 0x51dbf}, {0x51e00, 0x51f15}, {0x51f18, 0x51f1d}, - {0x51f20, 0x51f45}, {0x51f48, 0x51f4d}, {0x51f50, 0x51f57}, {0x51f5f, 0x51f7d}, - {0x51f80, 0x51fb4}, {0x51fb6, 0x51fbc}, {0x51fc2, 0x51fc4}, {0x51fc6, 0x51fcc}, - {0x51fd0, 0x51fd3}, {0x51fd6, 0x51fdb}, {0x51fe0, 0x51fec}, {0x51ff2, 0x51ff4}, - {0x51ff6, 0x51ffc}, {0x52090, 0x5209c}, {0x5210a, 0x52113}, {0x52119, 0x5211d}, - {0x5212a, 0x5212d}, {0x5212f, 0x52139}, {0x5213c, 0x5213f}, {0x52145, 0x52149}, - {0x52c00, 0x52c2e}, {0x52c30, 0x52c5e}, {0x52c60, 0x52ce4}, {0x52ceb, 0x52cee}, - {0x52d00, 0x52d25}, {0x52d30, 0x52d67}, {0x52d80, 0x52d96}, {0x52da0, 0x52da6}, - {0x52da8, 0x52dae}, {0x52db0, 0x52db6}, {0x52db8, 0x52dbe}, {0x52dc0, 0x52dc6}, - {0x52dc8, 0x52dce}, {0x52dd0, 0x52dd6}, {0x52dd8, 0x52dde}, {0x53031, 0x53035}, - {0x53041, 0x53096}, {0x5309d, 0x5309f}, {0x530a1, 0x530fa}, {0x530fc, 0x530ff}, - {0x53105, 0x5312e}, {0x53131, 0x5318e}, {0x531a0, 0x531ba}, {0x531f0, 0x531ff}, - {0x53400, 0x54db5}, {0x54e00, 0x59fea}, {0x5a000, 0x5a48c}, {0x5a4d0, 0x5a4fd}, - {0x5a500, 0x5a60c}, {0x5a610, 0x5a61f}, {0x5a640, 0x5a66e}, {0x5a67f, 0x5a69d}, - {0x5a6a0, 0x5a6e5}, {0x5a717, 0x5a71f}, {0x5a722, 0x5a788}, {0x5a78b, 0x5a7ae}, - {0x5a7b0, 0x5a7b7}, {0x5a7f7, 0x5a801}, {0x5a803, 0x5a805}, {0x5a807, 0x5a80a}, - {0x5a80c, 0x5a822}, {0x5a840, 0x5a873}, {0x5a882, 0x5a8b3}, {0x5a8f2, 0x5a8f7}, - {0x5a90a, 0x5a925}, {0x5a930, 0x5a946}, {0x5a960, 0x5a97c}, {0x5a984, 0x5a9b2}, - {0x5a9e0, 0x5a9e4}, {0x5a9e6, 0x5a9ef}, {0x5a9fa, 0x5a9fe}, {0x5aa00, 0x5aa28}, - {0x5aa40, 0x5aa42}, {0x5aa44, 0x5aa4b}, {0x5aa60, 0x5aa76}, {0x5aa7e, 0x5aaaf}, - {0x5aab9, 0x5aabd}, {0x5aadb, 0x5aadd}, {0x5aae0, 0x5aaea}, {0x5aaf2, 0x5aaf4}, - {0x5ab01, 0x5ab06}, {0x5ab09, 0x5ab0e}, {0x5ab11, 0x5ab16}, {0x5ab20, 0x5ab26}, - {0x5ab28, 0x5ab2e}, {0x5ab30, 0x5ab5a}, {0x5ab5c, 0x5ab65}, {0x5ab70, 0x5abe2}, - {0x5ac00, 0x5d7a3}, {0x5d7b0, 0x5d7c6}, {0x5d7cb, 0x5d7fb}, {0x5f900, 0x5fa6d}, - {0x5fa70, 0x5fad9}, {0x5fb00, 0x5fb06}, {0x5fb13, 0x5fb17}, {0x5fb1f, 0x5fb28}, - {0x5fb2a, 0x5fb36}, {0x5fb38, 0x5fb3c}, {0x5fb46, 0x5fbb1}, {0x5fbd3, 0x5fd3d}, - {0x5fd50, 0x5fd8f}, {0x5fd92, 0x5fdc7}, {0x5fdf0, 0x5fdfb}, {0x5fe70, 0x5fe74}, - {0x5fe76, 0x5fefc}, {0x5ff21, 0x5ff3a}, {0x5ff41, 0x5ff5a}, {0x5ff66, 0x5ffbe}, - {0x5ffc2, 0x5ffc7}, {0x5ffca, 0x5ffcf}, {0x5ffd2, 0x5ffd7}, {0x5ffda, 0x5ffdc}, - {0x60041, 0x6005a}, {0x60061, 0x6007a}, {0x600c0, 0x600d6}, {0x600d8, 0x600f6}, - {0x600f8, 0x602c1}, {0x602c6, 0x602d1}, {0x602e0, 0x602e4}, {0x60370, 0x60374}, - {0x6037a, 0x6037d}, {0x60388, 0x6038a}, {0x6038e, 0x603a1}, {0x603a3, 0x603f5}, - {0x603f7, 0x60481}, {0x6048a, 0x6052f}, {0x60531, 0x60556}, {0x60561, 0x60587}, - {0x605d0, 0x605ea}, {0x605f0, 0x605f2}, {0x60620, 0x6064a}, {0x60671, 0x606d3}, - {0x606fa, 0x606fc}, {0x60712, 0x6072f}, {0x6074d, 0x607a5}, {0x607ca, 0x607ea}, - {0x60800, 0x60815}, {0x60840, 0x60858}, {0x60860, 0x6086a}, {0x608a0, 0x608b4}, - {0x608b6, 0x608bd}, {0x60904, 0x60939}, {0x60958, 0x60961}, {0x60971, 0x60980}, - {0x60985, 0x6098c}, {0x60993, 0x609a8}, {0x609aa, 0x609b0}, {0x609b6, 0x609b9}, - {0x609df, 0x609e1}, {0x60a05, 0x60a0a}, {0x60a13, 0x60a28}, {0x60a2a, 0x60a30}, - {0x60a59, 0x60a5c}, {0x60a72, 0x60a74}, {0x60a85, 0x60a8d}, {0x60a8f, 0x60a91}, - {0x60a93, 0x60aa8}, {0x60aaa, 0x60ab0}, {0x60ab5, 0x60ab9}, {0x60b05, 0x60b0c}, - {0x60b13, 0x60b28}, {0x60b2a, 0x60b30}, {0x60b35, 0x60b39}, {0x60b5f, 0x60b61}, - {0x60b85, 0x60b8a}, {0x60b8e, 0x60b90}, {0x60b92, 0x60b95}, {0x60ba8, 0x60baa}, - {0x60bae, 0x60bb9}, {0x60c05, 0x60c0c}, {0x60c0e, 0x60c10}, {0x60c12, 0x60c28}, - {0x60c2a, 0x60c39}, {0x60c58, 0x60c5a}, {0x60c85, 0x60c8c}, {0x60c8e, 0x60c90}, - {0x60c92, 0x60ca8}, {0x60caa, 0x60cb3}, {0x60cb5, 0x60cb9}, {0x60d05, 0x60d0c}, - {0x60d0e, 0x60d10}, {0x60d12, 0x60d3a}, {0x60d54, 0x60d56}, {0x60d5f, 0x60d61}, - {0x60d7a, 0x60d7f}, {0x60d85, 0x60d96}, {0x60d9a, 0x60db1}, {0x60db3, 0x60dbb}, - {0x60dc0, 0x60dc6}, {0x60e01, 0x60e30}, {0x60e40, 0x60e46}, {0x60e94, 0x60e97}, - {0x60e99, 0x60e9f}, {0x60ea1, 0x60ea3}, {0x60ead, 0x60eb0}, {0x60ec0, 0x60ec4}, - {0x60edc, 0x60edf}, {0x60f40, 0x60f47}, {0x60f49, 0x60f6c}, {0x60f88, 0x60f8c}, - {0x61000, 0x6102a}, {0x61050, 0x61055}, {0x6105a, 0x6105d}, {0x6106e, 0x61070}, - {0x61075, 0x61081}, {0x610a0, 0x610c5}, {0x610d0, 0x610fa}, {0x610fc, 0x61248}, - {0x6124a, 0x6124d}, {0x61250, 0x61256}, {0x6125a, 0x6125d}, {0x61260, 0x61288}, - {0x6128a, 0x6128d}, {0x61290, 0x612b0}, {0x612b2, 0x612b5}, {0x612b8, 0x612be}, - {0x612c2, 0x612c5}, {0x612c8, 0x612d6}, {0x612d8, 0x61310}, {0x61312, 0x61315}, - {0x61318, 0x6135a}, {0x61380, 0x6138f}, {0x613a0, 0x613f5}, {0x613f8, 0x613fd}, - {0x61401, 0x6166c}, {0x6166f, 0x6167f}, {0x61681, 0x6169a}, {0x616a0, 0x616ea}, - {0x616f1, 0x616f8}, {0x61700, 0x6170c}, {0x6170e, 0x61711}, {0x61720, 0x61731}, - {0x61740, 0x61751}, {0x61760, 0x6176c}, {0x6176e, 0x61770}, {0x61780, 0x617b3}, - {0x61820, 0x61877}, {0x61880, 0x61884}, {0x61887, 0x618a8}, {0x618b0, 0x618f5}, - {0x61900, 0x6191e}, {0x61950, 0x6196d}, {0x61970, 0x61974}, {0x61980, 0x619ab}, - {0x619b0, 0x619c9}, {0x61a00, 0x61a16}, {0x61a20, 0x61a54}, {0x61b05, 0x61b33}, - {0x61b45, 0x61b4b}, {0x61b83, 0x61ba0}, {0x61bba, 0x61be5}, {0x61c00, 0x61c23}, - {0x61c4d, 0x61c4f}, {0x61c5a, 0x61c7d}, {0x61c80, 0x61c88}, {0x61ce9, 0x61cec}, - {0x61cee, 0x61cf1}, {0x61d00, 0x61dbf}, {0x61e00, 0x61f15}, {0x61f18, 0x61f1d}, - {0x61f20, 0x61f45}, {0x61f48, 0x61f4d}, {0x61f50, 0x61f57}, {0x61f5f, 0x61f7d}, - {0x61f80, 0x61fb4}, {0x61fb6, 0x61fbc}, {0x61fc2, 0x61fc4}, {0x61fc6, 0x61fcc}, - {0x61fd0, 0x61fd3}, {0x61fd6, 0x61fdb}, {0x61fe0, 0x61fec}, {0x61ff2, 0x61ff4}, - {0x61ff6, 0x61ffc}, {0x62090, 0x6209c}, {0x6210a, 0x62113}, {0x62119, 0x6211d}, - {0x6212a, 0x6212d}, {0x6212f, 0x62139}, {0x6213c, 0x6213f}, {0x62145, 0x62149}, - {0x62c00, 0x62c2e}, {0x62c30, 0x62c5e}, {0x62c60, 0x62ce4}, {0x62ceb, 0x62cee}, - {0x62d00, 0x62d25}, {0x62d30, 0x62d67}, {0x62d80, 0x62d96}, {0x62da0, 0x62da6}, - {0x62da8, 0x62dae}, {0x62db0, 0x62db6}, {0x62db8, 0x62dbe}, {0x62dc0, 0x62dc6}, - {0x62dc8, 0x62dce}, {0x62dd0, 0x62dd6}, {0x62dd8, 0x62dde}, {0x63031, 0x63035}, - {0x63041, 0x63096}, {0x6309d, 0x6309f}, {0x630a1, 0x630fa}, {0x630fc, 0x630ff}, - {0x63105, 0x6312e}, {0x63131, 0x6318e}, {0x631a0, 0x631ba}, {0x631f0, 0x631ff}, - {0x63400, 0x64db5}, {0x64e00, 0x69fea}, {0x6a000, 0x6a48c}, {0x6a4d0, 0x6a4fd}, - {0x6a500, 0x6a60c}, {0x6a610, 0x6a61f}, {0x6a640, 0x6a66e}, {0x6a67f, 0x6a69d}, - {0x6a6a0, 0x6a6e5}, {0x6a717, 0x6a71f}, {0x6a722, 0x6a788}, {0x6a78b, 0x6a7ae}, - {0x6a7b0, 0x6a7b7}, {0x6a7f7, 0x6a801}, {0x6a803, 0x6a805}, {0x6a807, 0x6a80a}, - {0x6a80c, 0x6a822}, {0x6a840, 0x6a873}, {0x6a882, 0x6a8b3}, {0x6a8f2, 0x6a8f7}, - {0x6a90a, 0x6a925}, {0x6a930, 0x6a946}, {0x6a960, 0x6a97c}, {0x6a984, 0x6a9b2}, - {0x6a9e0, 0x6a9e4}, {0x6a9e6, 0x6a9ef}, {0x6a9fa, 0x6a9fe}, {0x6aa00, 0x6aa28}, - {0x6aa40, 0x6aa42}, {0x6aa44, 0x6aa4b}, {0x6aa60, 0x6aa76}, {0x6aa7e, 0x6aaaf}, - {0x6aab9, 0x6aabd}, {0x6aadb, 0x6aadd}, {0x6aae0, 0x6aaea}, {0x6aaf2, 0x6aaf4}, - {0x6ab01, 0x6ab06}, {0x6ab09, 0x6ab0e}, {0x6ab11, 0x6ab16}, {0x6ab20, 0x6ab26}, - {0x6ab28, 0x6ab2e}, {0x6ab30, 0x6ab5a}, {0x6ab5c, 0x6ab65}, {0x6ab70, 0x6abe2}, - {0x6ac00, 0x6d7a3}, {0x6d7b0, 0x6d7c6}, {0x6d7cb, 0x6d7fb}, {0x6f900, 0x6fa6d}, - {0x6fa70, 0x6fad9}, {0x6fb00, 0x6fb06}, {0x6fb13, 0x6fb17}, {0x6fb1f, 0x6fb28}, - {0x6fb2a, 0x6fb36}, {0x6fb38, 0x6fb3c}, {0x6fb46, 0x6fbb1}, {0x6fbd3, 0x6fd3d}, - {0x6fd50, 0x6fd8f}, {0x6fd92, 0x6fdc7}, {0x6fdf0, 0x6fdfb}, {0x6fe70, 0x6fe74}, - {0x6fe76, 0x6fefc}, {0x6ff21, 0x6ff3a}, {0x6ff41, 0x6ff5a}, {0x6ff66, 0x6ffbe}, - {0x6ffc2, 0x6ffc7}, {0x6ffca, 0x6ffcf}, {0x6ffd2, 0x6ffd7}, {0x6ffda, 0x6ffdc}, - {0x70041, 0x7005a}, {0x70061, 0x7007a}, {0x700c0, 0x700d6}, {0x700d8, 0x700f6}, - {0x700f8, 0x702c1}, {0x702c6, 0x702d1}, {0x702e0, 0x702e4}, {0x70370, 0x70374}, - {0x7037a, 0x7037d}, {0x70388, 0x7038a}, {0x7038e, 0x703a1}, {0x703a3, 0x703f5}, - {0x703f7, 0x70481}, {0x7048a, 0x7052f}, {0x70531, 0x70556}, {0x70561, 0x70587}, - {0x705d0, 0x705ea}, {0x705f0, 0x705f2}, {0x70620, 0x7064a}, {0x70671, 0x706d3}, - {0x706fa, 0x706fc}, {0x70712, 0x7072f}, {0x7074d, 0x707a5}, {0x707ca, 0x707ea}, - {0x70800, 0x70815}, {0x70840, 0x70858}, {0x70860, 0x7086a}, {0x708a0, 0x708b4}, - {0x708b6, 0x708bd}, {0x70904, 0x70939}, {0x70958, 0x70961}, {0x70971, 0x70980}, - {0x70985, 0x7098c}, {0x70993, 0x709a8}, {0x709aa, 0x709b0}, {0x709b6, 0x709b9}, - {0x709df, 0x709e1}, {0x70a05, 0x70a0a}, {0x70a13, 0x70a28}, {0x70a2a, 0x70a30}, - {0x70a59, 0x70a5c}, {0x70a72, 0x70a74}, {0x70a85, 0x70a8d}, {0x70a8f, 0x70a91}, - {0x70a93, 0x70aa8}, {0x70aaa, 0x70ab0}, {0x70ab5, 0x70ab9}, {0x70b05, 0x70b0c}, - {0x70b13, 0x70b28}, {0x70b2a, 0x70b30}, {0x70b35, 0x70b39}, {0x70b5f, 0x70b61}, - {0x70b85, 0x70b8a}, {0x70b8e, 0x70b90}, {0x70b92, 0x70b95}, {0x70ba8, 0x70baa}, - {0x70bae, 0x70bb9}, {0x70c05, 0x70c0c}, {0x70c0e, 0x70c10}, {0x70c12, 0x70c28}, - {0x70c2a, 0x70c39}, {0x70c58, 0x70c5a}, {0x70c85, 0x70c8c}, {0x70c8e, 0x70c90}, - {0x70c92, 0x70ca8}, {0x70caa, 0x70cb3}, {0x70cb5, 0x70cb9}, {0x70d05, 0x70d0c}, - {0x70d0e, 0x70d10}, {0x70d12, 0x70d3a}, {0x70d54, 0x70d56}, {0x70d5f, 0x70d61}, - {0x70d7a, 0x70d7f}, {0x70d85, 0x70d96}, {0x70d9a, 0x70db1}, {0x70db3, 0x70dbb}, - {0x70dc0, 0x70dc6}, {0x70e01, 0x70e30}, {0x70e40, 0x70e46}, {0x70e94, 0x70e97}, - {0x70e99, 0x70e9f}, {0x70ea1, 0x70ea3}, {0x70ead, 0x70eb0}, {0x70ec0, 0x70ec4}, - {0x70edc, 0x70edf}, {0x70f40, 0x70f47}, {0x70f49, 0x70f6c}, {0x70f88, 0x70f8c}, - {0x71000, 0x7102a}, {0x71050, 0x71055}, {0x7105a, 0x7105d}, {0x7106e, 0x71070}, - {0x71075, 0x71081}, {0x710a0, 0x710c5}, {0x710d0, 0x710fa}, {0x710fc, 0x71248}, - {0x7124a, 0x7124d}, {0x71250, 0x71256}, {0x7125a, 0x7125d}, {0x71260, 0x71288}, - {0x7128a, 0x7128d}, {0x71290, 0x712b0}, {0x712b2, 0x712b5}, {0x712b8, 0x712be}, - {0x712c2, 0x712c5}, {0x712c8, 0x712d6}, {0x712d8, 0x71310}, {0x71312, 0x71315}, - {0x71318, 0x7135a}, {0x71380, 0x7138f}, {0x713a0, 0x713f5}, {0x713f8, 0x713fd}, - {0x71401, 0x7166c}, {0x7166f, 0x7167f}, {0x71681, 0x7169a}, {0x716a0, 0x716ea}, - {0x716f1, 0x716f8}, {0x71700, 0x7170c}, {0x7170e, 0x71711}, {0x71720, 0x71731}, - {0x71740, 0x71751}, {0x71760, 0x7176c}, {0x7176e, 0x71770}, {0x71780, 0x717b3}, - {0x71820, 0x71877}, {0x71880, 0x71884}, {0x71887, 0x718a8}, {0x718b0, 0x718f5}, - {0x71900, 0x7191e}, {0x71950, 0x7196d}, {0x71970, 0x71974}, {0x71980, 0x719ab}, - {0x719b0, 0x719c9}, {0x71a00, 0x71a16}, {0x71a20, 0x71a54}, {0x71b05, 0x71b33}, - {0x71b45, 0x71b4b}, {0x71b83, 0x71ba0}, {0x71bba, 0x71be5}, {0x71c00, 0x71c23}, - {0x71c4d, 0x71c4f}, {0x71c5a, 0x71c7d}, {0x71c80, 0x71c88}, {0x71ce9, 0x71cec}, - {0x71cee, 0x71cf1}, {0x71d00, 0x71dbf}, {0x71e00, 0x71f15}, {0x71f18, 0x71f1d}, - {0x71f20, 0x71f45}, {0x71f48, 0x71f4d}, {0x71f50, 0x71f57}, {0x71f5f, 0x71f7d}, - {0x71f80, 0x71fb4}, {0x71fb6, 0x71fbc}, {0x71fc2, 0x71fc4}, {0x71fc6, 0x71fcc}, - {0x71fd0, 0x71fd3}, {0x71fd6, 0x71fdb}, {0x71fe0, 0x71fec}, {0x71ff2, 0x71ff4}, - {0x71ff6, 0x71ffc}, {0x72090, 0x7209c}, {0x7210a, 0x72113}, {0x72119, 0x7211d}, - {0x7212a, 0x7212d}, {0x7212f, 0x72139}, {0x7213c, 0x7213f}, {0x72145, 0x72149}, - {0x72c00, 0x72c2e}, {0x72c30, 0x72c5e}, {0x72c60, 0x72ce4}, {0x72ceb, 0x72cee}, - {0x72d00, 0x72d25}, {0x72d30, 0x72d67}, {0x72d80, 0x72d96}, {0x72da0, 0x72da6}, - {0x72da8, 0x72dae}, {0x72db0, 0x72db6}, {0x72db8, 0x72dbe}, {0x72dc0, 0x72dc6}, - {0x72dc8, 0x72dce}, {0x72dd0, 0x72dd6}, {0x72dd8, 0x72dde}, {0x73031, 0x73035}, - {0x73041, 0x73096}, {0x7309d, 0x7309f}, {0x730a1, 0x730fa}, {0x730fc, 0x730ff}, - {0x73105, 0x7312e}, {0x73131, 0x7318e}, {0x731a0, 0x731ba}, {0x731f0, 0x731ff}, - {0x73400, 0x74db5}, {0x74e00, 0x79fea}, {0x7a000, 0x7a48c}, {0x7a4d0, 0x7a4fd}, - {0x7a500, 0x7a60c}, {0x7a610, 0x7a61f}, {0x7a640, 0x7a66e}, {0x7a67f, 0x7a69d}, - {0x7a6a0, 0x7a6e5}, {0x7a717, 0x7a71f}, {0x7a722, 0x7a788}, {0x7a78b, 0x7a7ae}, - {0x7a7b0, 0x7a7b7}, {0x7a7f7, 0x7a801}, {0x7a803, 0x7a805}, {0x7a807, 0x7a80a}, - {0x7a80c, 0x7a822}, {0x7a840, 0x7a873}, {0x7a882, 0x7a8b3}, {0x7a8f2, 0x7a8f7}, - {0x7a90a, 0x7a925}, {0x7a930, 0x7a946}, {0x7a960, 0x7a97c}, {0x7a984, 0x7a9b2}, - {0x7a9e0, 0x7a9e4}, {0x7a9e6, 0x7a9ef}, {0x7a9fa, 0x7a9fe}, {0x7aa00, 0x7aa28}, - {0x7aa40, 0x7aa42}, {0x7aa44, 0x7aa4b}, {0x7aa60, 0x7aa76}, {0x7aa7e, 0x7aaaf}, - {0x7aab9, 0x7aabd}, {0x7aadb, 0x7aadd}, {0x7aae0, 0x7aaea}, {0x7aaf2, 0x7aaf4}, - {0x7ab01, 0x7ab06}, {0x7ab09, 0x7ab0e}, {0x7ab11, 0x7ab16}, {0x7ab20, 0x7ab26}, - {0x7ab28, 0x7ab2e}, {0x7ab30, 0x7ab5a}, {0x7ab5c, 0x7ab65}, {0x7ab70, 0x7abe2}, - {0x7ac00, 0x7d7a3}, {0x7d7b0, 0x7d7c6}, {0x7d7cb, 0x7d7fb}, {0x7f900, 0x7fa6d}, - {0x7fa70, 0x7fad9}, {0x7fb00, 0x7fb06}, {0x7fb13, 0x7fb17}, {0x7fb1f, 0x7fb28}, - {0x7fb2a, 0x7fb36}, {0x7fb38, 0x7fb3c}, {0x7fb46, 0x7fbb1}, {0x7fbd3, 0x7fd3d}, - {0x7fd50, 0x7fd8f}, {0x7fd92, 0x7fdc7}, {0x7fdf0, 0x7fdfb}, {0x7fe70, 0x7fe74}, - {0x7fe76, 0x7fefc}, {0x7ff21, 0x7ff3a}, {0x7ff41, 0x7ff5a}, {0x7ff66, 0x7ffbe}, - {0x7ffc2, 0x7ffc7}, {0x7ffca, 0x7ffcf}, {0x7ffd2, 0x7ffd7}, {0x7ffda, 0x7ffdc}, - {0x80041, 0x8005a}, {0x80061, 0x8007a}, {0x800c0, 0x800d6}, {0x800d8, 0x800f6}, - {0x800f8, 0x802c1}, {0x802c6, 0x802d1}, {0x802e0, 0x802e4}, {0x80370, 0x80374}, - {0x8037a, 0x8037d}, {0x80388, 0x8038a}, {0x8038e, 0x803a1}, {0x803a3, 0x803f5}, - {0x803f7, 0x80481}, {0x8048a, 0x8052f}, {0x80531, 0x80556}, {0x80561, 0x80587}, - {0x805d0, 0x805ea}, {0x805f0, 0x805f2}, {0x80620, 0x8064a}, {0x80671, 0x806d3}, - {0x806fa, 0x806fc}, {0x80712, 0x8072f}, {0x8074d, 0x807a5}, {0x807ca, 0x807ea}, - {0x80800, 0x80815}, {0x80840, 0x80858}, {0x80860, 0x8086a}, {0x808a0, 0x808b4}, - {0x808b6, 0x808bd}, {0x80904, 0x80939}, {0x80958, 0x80961}, {0x80971, 0x80980}, - {0x80985, 0x8098c}, {0x80993, 0x809a8}, {0x809aa, 0x809b0}, {0x809b6, 0x809b9}, - {0x809df, 0x809e1}, {0x80a05, 0x80a0a}, {0x80a13, 0x80a28}, {0x80a2a, 0x80a30}, - {0x80a59, 0x80a5c}, {0x80a72, 0x80a74}, {0x80a85, 0x80a8d}, {0x80a8f, 0x80a91}, - {0x80a93, 0x80aa8}, {0x80aaa, 0x80ab0}, {0x80ab5, 0x80ab9}, {0x80b05, 0x80b0c}, - {0x80b13, 0x80b28}, {0x80b2a, 0x80b30}, {0x80b35, 0x80b39}, {0x80b5f, 0x80b61}, - {0x80b85, 0x80b8a}, {0x80b8e, 0x80b90}, {0x80b92, 0x80b95}, {0x80ba8, 0x80baa}, - {0x80bae, 0x80bb9}, {0x80c05, 0x80c0c}, {0x80c0e, 0x80c10}, {0x80c12, 0x80c28}, - {0x80c2a, 0x80c39}, {0x80c58, 0x80c5a}, {0x80c85, 0x80c8c}, {0x80c8e, 0x80c90}, - {0x80c92, 0x80ca8}, {0x80caa, 0x80cb3}, {0x80cb5, 0x80cb9}, {0x80d05, 0x80d0c}, - {0x80d0e, 0x80d10}, {0x80d12, 0x80d3a}, {0x80d54, 0x80d56}, {0x80d5f, 0x80d61}, - {0x80d7a, 0x80d7f}, {0x80d85, 0x80d96}, {0x80d9a, 0x80db1}, {0x80db3, 0x80dbb}, - {0x80dc0, 0x80dc6}, {0x80e01, 0x80e30}, {0x80e40, 0x80e46}, {0x80e94, 0x80e97}, - {0x80e99, 0x80e9f}, {0x80ea1, 0x80ea3}, {0x80ead, 0x80eb0}, {0x80ec0, 0x80ec4}, - {0x80edc, 0x80edf}, {0x80f40, 0x80f47}, {0x80f49, 0x80f6c}, {0x80f88, 0x80f8c}, - {0x81000, 0x8102a}, {0x81050, 0x81055}, {0x8105a, 0x8105d}, {0x8106e, 0x81070}, - {0x81075, 0x81081}, {0x810a0, 0x810c5}, {0x810d0, 0x810fa}, {0x810fc, 0x81248}, - {0x8124a, 0x8124d}, {0x81250, 0x81256}, {0x8125a, 0x8125d}, {0x81260, 0x81288}, - {0x8128a, 0x8128d}, {0x81290, 0x812b0}, {0x812b2, 0x812b5}, {0x812b8, 0x812be}, - {0x812c2, 0x812c5}, {0x812c8, 0x812d6}, {0x812d8, 0x81310}, {0x81312, 0x81315}, - {0x81318, 0x8135a}, {0x81380, 0x8138f}, {0x813a0, 0x813f5}, {0x813f8, 0x813fd}, - {0x81401, 0x8166c}, {0x8166f, 0x8167f}, {0x81681, 0x8169a}, {0x816a0, 0x816ea}, - {0x816f1, 0x816f8}, {0x81700, 0x8170c}, {0x8170e, 0x81711}, {0x81720, 0x81731}, - {0x81740, 0x81751}, {0x81760, 0x8176c}, {0x8176e, 0x81770}, {0x81780, 0x817b3}, - {0x81820, 0x81877}, {0x81880, 0x81884}, {0x81887, 0x818a8}, {0x818b0, 0x818f5}, - {0x81900, 0x8191e}, {0x81950, 0x8196d}, {0x81970, 0x81974}, {0x81980, 0x819ab}, - {0x819b0, 0x819c9}, {0x81a00, 0x81a16}, {0x81a20, 0x81a54}, {0x81b05, 0x81b33}, - {0x81b45, 0x81b4b}, {0x81b83, 0x81ba0}, {0x81bba, 0x81be5}, {0x81c00, 0x81c23}, - {0x81c4d, 0x81c4f}, {0x81c5a, 0x81c7d}, {0x81c80, 0x81c88}, {0x81ce9, 0x81cec}, - {0x81cee, 0x81cf1}, {0x81d00, 0x81dbf}, {0x81e00, 0x81f15}, {0x81f18, 0x81f1d}, - {0x81f20, 0x81f45}, {0x81f48, 0x81f4d}, {0x81f50, 0x81f57}, {0x81f5f, 0x81f7d}, - {0x81f80, 0x81fb4}, {0x81fb6, 0x81fbc}, {0x81fc2, 0x81fc4}, {0x81fc6, 0x81fcc}, - {0x81fd0, 0x81fd3}, {0x81fd6, 0x81fdb}, {0x81fe0, 0x81fec}, {0x81ff2, 0x81ff4}, - {0x81ff6, 0x81ffc}, {0x82090, 0x8209c}, {0x8210a, 0x82113}, {0x82119, 0x8211d}, - {0x8212a, 0x8212d}, {0x8212f, 0x82139}, {0x8213c, 0x8213f}, {0x82145, 0x82149}, - {0x82c00, 0x82c2e}, {0x82c30, 0x82c5e}, {0x82c60, 0x82ce4}, {0x82ceb, 0x82cee}, - {0x82d00, 0x82d25}, {0x82d30, 0x82d67}, {0x82d80, 0x82d96}, {0x82da0, 0x82da6}, - {0x82da8, 0x82dae}, {0x82db0, 0x82db6}, {0x82db8, 0x82dbe}, {0x82dc0, 0x82dc6}, - {0x82dc8, 0x82dce}, {0x82dd0, 0x82dd6}, {0x82dd8, 0x82dde}, {0x83031, 0x83035}, - {0x83041, 0x83096}, {0x8309d, 0x8309f}, {0x830a1, 0x830fa}, {0x830fc, 0x830ff}, - {0x83105, 0x8312e}, {0x83131, 0x8318e}, {0x831a0, 0x831ba}, {0x831f0, 0x831ff}, - {0x83400, 0x84db5}, {0x84e00, 0x89fea}, {0x8a000, 0x8a48c}, {0x8a4d0, 0x8a4fd}, - {0x8a500, 0x8a60c}, {0x8a610, 0x8a61f}, {0x8a640, 0x8a66e}, {0x8a67f, 0x8a69d}, - {0x8a6a0, 0x8a6e5}, {0x8a717, 0x8a71f}, {0x8a722, 0x8a788}, {0x8a78b, 0x8a7ae}, - {0x8a7b0, 0x8a7b7}, {0x8a7f7, 0x8a801}, {0x8a803, 0x8a805}, {0x8a807, 0x8a80a}, - {0x8a80c, 0x8a822}, {0x8a840, 0x8a873}, {0x8a882, 0x8a8b3}, {0x8a8f2, 0x8a8f7}, - {0x8a90a, 0x8a925}, {0x8a930, 0x8a946}, {0x8a960, 0x8a97c}, {0x8a984, 0x8a9b2}, - {0x8a9e0, 0x8a9e4}, {0x8a9e6, 0x8a9ef}, {0x8a9fa, 0x8a9fe}, {0x8aa00, 0x8aa28}, - {0x8aa40, 0x8aa42}, {0x8aa44, 0x8aa4b}, {0x8aa60, 0x8aa76}, {0x8aa7e, 0x8aaaf}, - {0x8aab9, 0x8aabd}, {0x8aadb, 0x8aadd}, {0x8aae0, 0x8aaea}, {0x8aaf2, 0x8aaf4}, - {0x8ab01, 0x8ab06}, {0x8ab09, 0x8ab0e}, {0x8ab11, 0x8ab16}, {0x8ab20, 0x8ab26}, - {0x8ab28, 0x8ab2e}, {0x8ab30, 0x8ab5a}, {0x8ab5c, 0x8ab65}, {0x8ab70, 0x8abe2}, - {0x8ac00, 0x8d7a3}, {0x8d7b0, 0x8d7c6}, {0x8d7cb, 0x8d7fb}, {0x8f900, 0x8fa6d}, - {0x8fa70, 0x8fad9}, {0x8fb00, 0x8fb06}, {0x8fb13, 0x8fb17}, {0x8fb1f, 0x8fb28}, - {0x8fb2a, 0x8fb36}, {0x8fb38, 0x8fb3c}, {0x8fb46, 0x8fbb1}, {0x8fbd3, 0x8fd3d}, - {0x8fd50, 0x8fd8f}, {0x8fd92, 0x8fdc7}, {0x8fdf0, 0x8fdfb}, {0x8fe70, 0x8fe74}, - {0x8fe76, 0x8fefc}, {0x8ff21, 0x8ff3a}, {0x8ff41, 0x8ff5a}, {0x8ff66, 0x8ffbe}, - {0x8ffc2, 0x8ffc7}, {0x8ffca, 0x8ffcf}, {0x8ffd2, 0x8ffd7}, {0x8ffda, 0x8ffdc}, - {0x90041, 0x9005a}, {0x90061, 0x9007a}, {0x900c0, 0x900d6}, {0x900d8, 0x900f6}, - {0x900f8, 0x902c1}, {0x902c6, 0x902d1}, {0x902e0, 0x902e4}, {0x90370, 0x90374}, - {0x9037a, 0x9037d}, {0x90388, 0x9038a}, {0x9038e, 0x903a1}, {0x903a3, 0x903f5}, - {0x903f7, 0x90481}, {0x9048a, 0x9052f}, {0x90531, 0x90556}, {0x90561, 0x90587}, - {0x905d0, 0x905ea}, {0x905f0, 0x905f2}, {0x90620, 0x9064a}, {0x90671, 0x906d3}, - {0x906fa, 0x906fc}, {0x90712, 0x9072f}, {0x9074d, 0x907a5}, {0x907ca, 0x907ea}, - {0x90800, 0x90815}, {0x90840, 0x90858}, {0x90860, 0x9086a}, {0x908a0, 0x908b4}, - {0x908b6, 0x908bd}, {0x90904, 0x90939}, {0x90958, 0x90961}, {0x90971, 0x90980}, - {0x90985, 0x9098c}, {0x90993, 0x909a8}, {0x909aa, 0x909b0}, {0x909b6, 0x909b9}, - {0x909df, 0x909e1}, {0x90a05, 0x90a0a}, {0x90a13, 0x90a28}, {0x90a2a, 0x90a30}, - {0x90a59, 0x90a5c}, {0x90a72, 0x90a74}, {0x90a85, 0x90a8d}, {0x90a8f, 0x90a91}, - {0x90a93, 0x90aa8}, {0x90aaa, 0x90ab0}, {0x90ab5, 0x90ab9}, {0x90b05, 0x90b0c}, - {0x90b13, 0x90b28}, {0x90b2a, 0x90b30}, {0x90b35, 0x90b39}, {0x90b5f, 0x90b61}, - {0x90b85, 0x90b8a}, {0x90b8e, 0x90b90}, {0x90b92, 0x90b95}, {0x90ba8, 0x90baa}, - {0x90bae, 0x90bb9}, {0x90c05, 0x90c0c}, {0x90c0e, 0x90c10}, {0x90c12, 0x90c28}, - {0x90c2a, 0x90c39}, {0x90c58, 0x90c5a}, {0x90c85, 0x90c8c}, {0x90c8e, 0x90c90}, - {0x90c92, 0x90ca8}, {0x90caa, 0x90cb3}, {0x90cb5, 0x90cb9}, {0x90d05, 0x90d0c}, - {0x90d0e, 0x90d10}, {0x90d12, 0x90d3a}, {0x90d54, 0x90d56}, {0x90d5f, 0x90d61}, - {0x90d7a, 0x90d7f}, {0x90d85, 0x90d96}, {0x90d9a, 0x90db1}, {0x90db3, 0x90dbb}, - {0x90dc0, 0x90dc6}, {0x90e01, 0x90e30}, {0x90e40, 0x90e46}, {0x90e94, 0x90e97}, - {0x90e99, 0x90e9f}, {0x90ea1, 0x90ea3}, {0x90ead, 0x90eb0}, {0x90ec0, 0x90ec4}, - {0x90edc, 0x90edf}, {0x90f40, 0x90f47}, {0x90f49, 0x90f6c}, {0x90f88, 0x90f8c}, - {0x91000, 0x9102a}, {0x91050, 0x91055}, {0x9105a, 0x9105d}, {0x9106e, 0x91070}, - {0x91075, 0x91081}, {0x910a0, 0x910c5}, {0x910d0, 0x910fa}, {0x910fc, 0x91248}, - {0x9124a, 0x9124d}, {0x91250, 0x91256}, {0x9125a, 0x9125d}, {0x91260, 0x91288}, - {0x9128a, 0x9128d}, {0x91290, 0x912b0}, {0x912b2, 0x912b5}, {0x912b8, 0x912be}, - {0x912c2, 0x912c5}, {0x912c8, 0x912d6}, {0x912d8, 0x91310}, {0x91312, 0x91315}, - {0x91318, 0x9135a}, {0x91380, 0x9138f}, {0x913a0, 0x913f5}, {0x913f8, 0x913fd}, - {0x91401, 0x9166c}, {0x9166f, 0x9167f}, {0x91681, 0x9169a}, {0x916a0, 0x916ea}, - {0x916f1, 0x916f8}, {0x91700, 0x9170c}, {0x9170e, 0x91711}, {0x91720, 0x91731}, - {0x91740, 0x91751}, {0x91760, 0x9176c}, {0x9176e, 0x91770}, {0x91780, 0x917b3}, - {0x91820, 0x91877}, {0x91880, 0x91884}, {0x91887, 0x918a8}, {0x918b0, 0x918f5}, - {0x91900, 0x9191e}, {0x91950, 0x9196d}, {0x91970, 0x91974}, {0x91980, 0x919ab}, - {0x919b0, 0x919c9}, {0x91a00, 0x91a16}, {0x91a20, 0x91a54}, {0x91b05, 0x91b33}, - {0x91b45, 0x91b4b}, {0x91b83, 0x91ba0}, {0x91bba, 0x91be5}, {0x91c00, 0x91c23}, - {0x91c4d, 0x91c4f}, {0x91c5a, 0x91c7d}, {0x91c80, 0x91c88}, {0x91ce9, 0x91cec}, - {0x91cee, 0x91cf1}, {0x91d00, 0x91dbf}, {0x91e00, 0x91f15}, {0x91f18, 0x91f1d}, - {0x91f20, 0x91f45}, {0x91f48, 0x91f4d}, {0x91f50, 0x91f57}, {0x91f5f, 0x91f7d}, - {0x91f80, 0x91fb4}, {0x91fb6, 0x91fbc}, {0x91fc2, 0x91fc4}, {0x91fc6, 0x91fcc}, - {0x91fd0, 0x91fd3}, {0x91fd6, 0x91fdb}, {0x91fe0, 0x91fec}, {0x91ff2, 0x91ff4}, - {0x91ff6, 0x91ffc}, {0x92090, 0x9209c}, {0x9210a, 0x92113}, {0x92119, 0x9211d}, - {0x9212a, 0x9212d}, {0x9212f, 0x92139}, {0x9213c, 0x9213f}, {0x92145, 0x92149}, - {0x92c00, 0x92c2e}, {0x92c30, 0x92c5e}, {0x92c60, 0x92ce4}, {0x92ceb, 0x92cee}, - {0x92d00, 0x92d25}, {0x92d30, 0x92d67}, {0x92d80, 0x92d96}, {0x92da0, 0x92da6}, - {0x92da8, 0x92dae}, {0x92db0, 0x92db6}, {0x92db8, 0x92dbe}, {0x92dc0, 0x92dc6}, - {0x92dc8, 0x92dce}, {0x92dd0, 0x92dd6}, {0x92dd8, 0x92dde}, {0x93031, 0x93035}, - {0x93041, 0x93096}, {0x9309d, 0x9309f}, {0x930a1, 0x930fa}, {0x930fc, 0x930ff}, - {0x93105, 0x9312e}, {0x93131, 0x9318e}, {0x931a0, 0x931ba}, {0x931f0, 0x931ff}, - {0x93400, 0x94db5}, {0x94e00, 0x99fea}, {0x9a000, 0x9a48c}, {0x9a4d0, 0x9a4fd}, - {0x9a500, 0x9a60c}, {0x9a610, 0x9a61f}, {0x9a640, 0x9a66e}, {0x9a67f, 0x9a69d}, - {0x9a6a0, 0x9a6e5}, {0x9a717, 0x9a71f}, {0x9a722, 0x9a788}, {0x9a78b, 0x9a7ae}, - {0x9a7b0, 0x9a7b7}, {0x9a7f7, 0x9a801}, {0x9a803, 0x9a805}, {0x9a807, 0x9a80a}, - {0x9a80c, 0x9a822}, {0x9a840, 0x9a873}, {0x9a882, 0x9a8b3}, {0x9a8f2, 0x9a8f7}, - {0x9a90a, 0x9a925}, {0x9a930, 0x9a946}, {0x9a960, 0x9a97c}, {0x9a984, 0x9a9b2}, - {0x9a9e0, 0x9a9e4}, {0x9a9e6, 0x9a9ef}, {0x9a9fa, 0x9a9fe}, {0x9aa00, 0x9aa28}, - {0x9aa40, 0x9aa42}, {0x9aa44, 0x9aa4b}, {0x9aa60, 0x9aa76}, {0x9aa7e, 0x9aaaf}, - {0x9aab9, 0x9aabd}, {0x9aadb, 0x9aadd}, {0x9aae0, 0x9aaea}, {0x9aaf2, 0x9aaf4}, - {0x9ab01, 0x9ab06}, {0x9ab09, 0x9ab0e}, {0x9ab11, 0x9ab16}, {0x9ab20, 0x9ab26}, - {0x9ab28, 0x9ab2e}, {0x9ab30, 0x9ab5a}, {0x9ab5c, 0x9ab65}, {0x9ab70, 0x9abe2}, - {0x9ac00, 0x9d7a3}, {0x9d7b0, 0x9d7c6}, {0x9d7cb, 0x9d7fb}, {0x9f900, 0x9fa6d}, - {0x9fa70, 0x9fad9}, {0x9fb00, 0x9fb06}, {0x9fb13, 0x9fb17}, {0x9fb1f, 0x9fb28}, - {0x9fb2a, 0x9fb36}, {0x9fb38, 0x9fb3c}, {0x9fb46, 0x9fbb1}, {0x9fbd3, 0x9fd3d}, - {0x9fd50, 0x9fd8f}, {0x9fd92, 0x9fdc7}, {0x9fdf0, 0x9fdfb}, {0x9fe70, 0x9fe74}, - {0x9fe76, 0x9fefc}, {0x9ff21, 0x9ff3a}, {0x9ff41, 0x9ff5a}, {0x9ff66, 0x9ffbe}, - {0x9ffc2, 0x9ffc7}, {0x9ffca, 0x9ffcf}, {0x9ffd2, 0x9ffd7}, {0x9ffda, 0x9ffdc}, - {0xa0041, 0xa005a}, {0xa0061, 0xa007a}, {0xa00c0, 0xa00d6}, {0xa00d8, 0xa00f6}, - {0xa00f8, 0xa02c1}, {0xa02c6, 0xa02d1}, {0xa02e0, 0xa02e4}, {0xa0370, 0xa0374}, - {0xa037a, 0xa037d}, {0xa0388, 0xa038a}, {0xa038e, 0xa03a1}, {0xa03a3, 0xa03f5}, - {0xa03f7, 0xa0481}, {0xa048a, 0xa052f}, {0xa0531, 0xa0556}, {0xa0561, 0xa0587}, - {0xa05d0, 0xa05ea}, {0xa05f0, 0xa05f2}, {0xa0620, 0xa064a}, {0xa0671, 0xa06d3}, - {0xa06fa, 0xa06fc}, {0xa0712, 0xa072f}, {0xa074d, 0xa07a5}, {0xa07ca, 0xa07ea}, - {0xa0800, 0xa0815}, {0xa0840, 0xa0858}, {0xa0860, 0xa086a}, {0xa08a0, 0xa08b4}, - {0xa08b6, 0xa08bd}, {0xa0904, 0xa0939}, {0xa0958, 0xa0961}, {0xa0971, 0xa0980}, - {0xa0985, 0xa098c}, {0xa0993, 0xa09a8}, {0xa09aa, 0xa09b0}, {0xa09b6, 0xa09b9}, - {0xa09df, 0xa09e1}, {0xa0a05, 0xa0a0a}, {0xa0a13, 0xa0a28}, {0xa0a2a, 0xa0a30}, - {0xa0a59, 0xa0a5c}, {0xa0a72, 0xa0a74}, {0xa0a85, 0xa0a8d}, {0xa0a8f, 0xa0a91}, - {0xa0a93, 0xa0aa8}, {0xa0aaa, 0xa0ab0}, {0xa0ab5, 0xa0ab9}, {0xa0b05, 0xa0b0c}, - {0xa0b13, 0xa0b28}, {0xa0b2a, 0xa0b30}, {0xa0b35, 0xa0b39}, {0xa0b5f, 0xa0b61}, - {0xa0b85, 0xa0b8a}, {0xa0b8e, 0xa0b90}, {0xa0b92, 0xa0b95}, {0xa0ba8, 0xa0baa}, - {0xa0bae, 0xa0bb9}, {0xa0c05, 0xa0c0c}, {0xa0c0e, 0xa0c10}, {0xa0c12, 0xa0c28}, - {0xa0c2a, 0xa0c39}, {0xa0c58, 0xa0c5a}, {0xa0c85, 0xa0c8c}, {0xa0c8e, 0xa0c90}, - {0xa0c92, 0xa0ca8}, {0xa0caa, 0xa0cb3}, {0xa0cb5, 0xa0cb9}, {0xa0d05, 0xa0d0c}, - {0xa0d0e, 0xa0d10}, {0xa0d12, 0xa0d3a}, {0xa0d54, 0xa0d56}, {0xa0d5f, 0xa0d61}, - {0xa0d7a, 0xa0d7f}, {0xa0d85, 0xa0d96}, {0xa0d9a, 0xa0db1}, {0xa0db3, 0xa0dbb}, - {0xa0dc0, 0xa0dc6}, {0xa0e01, 0xa0e30}, {0xa0e40, 0xa0e46}, {0xa0e94, 0xa0e97}, - {0xa0e99, 0xa0e9f}, {0xa0ea1, 0xa0ea3}, {0xa0ead, 0xa0eb0}, {0xa0ec0, 0xa0ec4}, - {0xa0edc, 0xa0edf}, {0xa0f40, 0xa0f47}, {0xa0f49, 0xa0f6c}, {0xa0f88, 0xa0f8c}, - {0xa1000, 0xa102a}, {0xa1050, 0xa1055}, {0xa105a, 0xa105d}, {0xa106e, 0xa1070}, - {0xa1075, 0xa1081}, {0xa10a0, 0xa10c5}, {0xa10d0, 0xa10fa}, {0xa10fc, 0xa1248}, - {0xa124a, 0xa124d}, {0xa1250, 0xa1256}, {0xa125a, 0xa125d}, {0xa1260, 0xa1288}, - {0xa128a, 0xa128d}, {0xa1290, 0xa12b0}, {0xa12b2, 0xa12b5}, {0xa12b8, 0xa12be}, - {0xa12c2, 0xa12c5}, {0xa12c8, 0xa12d6}, {0xa12d8, 0xa1310}, {0xa1312, 0xa1315}, - {0xa1318, 0xa135a}, {0xa1380, 0xa138f}, {0xa13a0, 0xa13f5}, {0xa13f8, 0xa13fd}, - {0xa1401, 0xa166c}, {0xa166f, 0xa167f}, {0xa1681, 0xa169a}, {0xa16a0, 0xa16ea}, - {0xa16f1, 0xa16f8}, {0xa1700, 0xa170c}, {0xa170e, 0xa1711}, {0xa1720, 0xa1731}, - {0xa1740, 0xa1751}, {0xa1760, 0xa176c}, {0xa176e, 0xa1770}, {0xa1780, 0xa17b3}, - {0xa1820, 0xa1877}, {0xa1880, 0xa1884}, {0xa1887, 0xa18a8}, {0xa18b0, 0xa18f5}, - {0xa1900, 0xa191e}, {0xa1950, 0xa196d}, {0xa1970, 0xa1974}, {0xa1980, 0xa19ab}, - {0xa19b0, 0xa19c9}, {0xa1a00, 0xa1a16}, {0xa1a20, 0xa1a54}, {0xa1b05, 0xa1b33}, - {0xa1b45, 0xa1b4b}, {0xa1b83, 0xa1ba0}, {0xa1bba, 0xa1be5}, {0xa1c00, 0xa1c23}, - {0xa1c4d, 0xa1c4f}, {0xa1c5a, 0xa1c7d}, {0xa1c80, 0xa1c88}, {0xa1ce9, 0xa1cec}, - {0xa1cee, 0xa1cf1}, {0xa1d00, 0xa1dbf}, {0xa1e00, 0xa1f15}, {0xa1f18, 0xa1f1d}, - {0xa1f20, 0xa1f45}, {0xa1f48, 0xa1f4d}, {0xa1f50, 0xa1f57}, {0xa1f5f, 0xa1f7d}, - {0xa1f80, 0xa1fb4}, {0xa1fb6, 0xa1fbc}, {0xa1fc2, 0xa1fc4}, {0xa1fc6, 0xa1fcc}, - {0xa1fd0, 0xa1fd3}, {0xa1fd6, 0xa1fdb}, {0xa1fe0, 0xa1fec}, {0xa1ff2, 0xa1ff4}, - {0xa1ff6, 0xa1ffc}, {0xa2090, 0xa209c}, {0xa210a, 0xa2113}, {0xa2119, 0xa211d}, - {0xa212a, 0xa212d}, {0xa212f, 0xa2139}, {0xa213c, 0xa213f}, {0xa2145, 0xa2149}, - {0xa2c00, 0xa2c2e}, {0xa2c30, 0xa2c5e}, {0xa2c60, 0xa2ce4}, {0xa2ceb, 0xa2cee}, - {0xa2d00, 0xa2d25}, {0xa2d30, 0xa2d67}, {0xa2d80, 0xa2d96}, {0xa2da0, 0xa2da6}, - {0xa2da8, 0xa2dae}, {0xa2db0, 0xa2db6}, {0xa2db8, 0xa2dbe}, {0xa2dc0, 0xa2dc6}, - {0xa2dc8, 0xa2dce}, {0xa2dd0, 0xa2dd6}, {0xa2dd8, 0xa2dde}, {0xa3031, 0xa3035}, - {0xa3041, 0xa3096}, {0xa309d, 0xa309f}, {0xa30a1, 0xa30fa}, {0xa30fc, 0xa30ff}, - {0xa3105, 0xa312e}, {0xa3131, 0xa318e}, {0xa31a0, 0xa31ba}, {0xa31f0, 0xa31ff}, - {0xa3400, 0xa4db5}, {0xa4e00, 0xa9fea}, {0xaa000, 0xaa48c}, {0xaa4d0, 0xaa4fd}, - {0xaa500, 0xaa60c}, {0xaa610, 0xaa61f}, {0xaa640, 0xaa66e}, {0xaa67f, 0xaa69d}, - {0xaa6a0, 0xaa6e5}, {0xaa717, 0xaa71f}, {0xaa722, 0xaa788}, {0xaa78b, 0xaa7ae}, - {0xaa7b0, 0xaa7b7}, {0xaa7f7, 0xaa801}, {0xaa803, 0xaa805}, {0xaa807, 0xaa80a}, - {0xaa80c, 0xaa822}, {0xaa840, 0xaa873}, {0xaa882, 0xaa8b3}, {0xaa8f2, 0xaa8f7}, - {0xaa90a, 0xaa925}, {0xaa930, 0xaa946}, {0xaa960, 0xaa97c}, {0xaa984, 0xaa9b2}, - {0xaa9e0, 0xaa9e4}, {0xaa9e6, 0xaa9ef}, {0xaa9fa, 0xaa9fe}, {0xaaa00, 0xaaa28}, - {0xaaa40, 0xaaa42}, {0xaaa44, 0xaaa4b}, {0xaaa60, 0xaaa76}, {0xaaa7e, 0xaaaaf}, - {0xaaab9, 0xaaabd}, {0xaaadb, 0xaaadd}, {0xaaae0, 0xaaaea}, {0xaaaf2, 0xaaaf4}, - {0xaab01, 0xaab06}, {0xaab09, 0xaab0e}, {0xaab11, 0xaab16}, {0xaab20, 0xaab26}, - {0xaab28, 0xaab2e}, {0xaab30, 0xaab5a}, {0xaab5c, 0xaab65}, {0xaab70, 0xaabe2}, - {0xaac00, 0xad7a3}, {0xad7b0, 0xad7c6}, {0xad7cb, 0xad7fb}, {0xaf900, 0xafa6d}, - {0xafa70, 0xafad9}, {0xafb00, 0xafb06}, {0xafb13, 0xafb17}, {0xafb1f, 0xafb28}, - {0xafb2a, 0xafb36}, {0xafb38, 0xafb3c}, {0xafb46, 0xafbb1}, {0xafbd3, 0xafd3d}, - {0xafd50, 0xafd8f}, {0xafd92, 0xafdc7}, {0xafdf0, 0xafdfb}, {0xafe70, 0xafe74}, - {0xafe76, 0xafefc}, {0xaff21, 0xaff3a}, {0xaff41, 0xaff5a}, {0xaff66, 0xaffbe}, - {0xaffc2, 0xaffc7}, {0xaffca, 0xaffcf}, {0xaffd2, 0xaffd7}, {0xaffda, 0xaffdc}, - {0xb0041, 0xb005a}, {0xb0061, 0xb007a}, {0xb00c0, 0xb00d6}, {0xb00d8, 0xb00f6}, - {0xb00f8, 0xb02c1}, {0xb02c6, 0xb02d1}, {0xb02e0, 0xb02e4}, {0xb0370, 0xb0374}, - {0xb037a, 0xb037d}, {0xb0388, 0xb038a}, {0xb038e, 0xb03a1}, {0xb03a3, 0xb03f5}, - {0xb03f7, 0xb0481}, {0xb048a, 0xb052f}, {0xb0531, 0xb0556}, {0xb0561, 0xb0587}, - {0xb05d0, 0xb05ea}, {0xb05f0, 0xb05f2}, {0xb0620, 0xb064a}, {0xb0671, 0xb06d3}, - {0xb06fa, 0xb06fc}, {0xb0712, 0xb072f}, {0xb074d, 0xb07a5}, {0xb07ca, 0xb07ea}, - {0xb0800, 0xb0815}, {0xb0840, 0xb0858}, {0xb0860, 0xb086a}, {0xb08a0, 0xb08b4}, - {0xb08b6, 0xb08bd}, {0xb0904, 0xb0939}, {0xb0958, 0xb0961}, {0xb0971, 0xb0980}, - {0xb0985, 0xb098c}, {0xb0993, 0xb09a8}, {0xb09aa, 0xb09b0}, {0xb09b6, 0xb09b9}, - {0xb09df, 0xb09e1}, {0xb0a05, 0xb0a0a}, {0xb0a13, 0xb0a28}, {0xb0a2a, 0xb0a30}, - {0xb0a59, 0xb0a5c}, {0xb0a72, 0xb0a74}, {0xb0a85, 0xb0a8d}, {0xb0a8f, 0xb0a91}, - {0xb0a93, 0xb0aa8}, {0xb0aaa, 0xb0ab0}, {0xb0ab5, 0xb0ab9}, {0xb0b05, 0xb0b0c}, - {0xb0b13, 0xb0b28}, {0xb0b2a, 0xb0b30}, {0xb0b35, 0xb0b39}, {0xb0b5f, 0xb0b61}, - {0xb0b85, 0xb0b8a}, {0xb0b8e, 0xb0b90}, {0xb0b92, 0xb0b95}, {0xb0ba8, 0xb0baa}, - {0xb0bae, 0xb0bb9}, {0xb0c05, 0xb0c0c}, {0xb0c0e, 0xb0c10}, {0xb0c12, 0xb0c28}, - {0xb0c2a, 0xb0c39}, {0xb0c58, 0xb0c5a}, {0xb0c85, 0xb0c8c}, {0xb0c8e, 0xb0c90}, - {0xb0c92, 0xb0ca8}, {0xb0caa, 0xb0cb3}, {0xb0cb5, 0xb0cb9}, {0xb0d05, 0xb0d0c}, - {0xb0d0e, 0xb0d10}, {0xb0d12, 0xb0d3a}, {0xb0d54, 0xb0d56}, {0xb0d5f, 0xb0d61}, - {0xb0d7a, 0xb0d7f}, {0xb0d85, 0xb0d96}, {0xb0d9a, 0xb0db1}, {0xb0db3, 0xb0dbb}, - {0xb0dc0, 0xb0dc6}, {0xb0e01, 0xb0e30}, {0xb0e40, 0xb0e46}, {0xb0e94, 0xb0e97}, - {0xb0e99, 0xb0e9f}, {0xb0ea1, 0xb0ea3}, {0xb0ead, 0xb0eb0}, {0xb0ec0, 0xb0ec4}, - {0xb0edc, 0xb0edf}, {0xb0f40, 0xb0f47}, {0xb0f49, 0xb0f6c}, {0xb0f88, 0xb0f8c}, - {0xb1000, 0xb102a}, {0xb1050, 0xb1055}, {0xb105a, 0xb105d}, {0xb106e, 0xb1070}, - {0xb1075, 0xb1081}, {0xb10a0, 0xb10c5}, {0xb10d0, 0xb10fa}, {0xb10fc, 0xb1248}, - {0xb124a, 0xb124d}, {0xb1250, 0xb1256}, {0xb125a, 0xb125d}, {0xb1260, 0xb1288}, - {0xb128a, 0xb128d}, {0xb1290, 0xb12b0}, {0xb12b2, 0xb12b5}, {0xb12b8, 0xb12be}, - {0xb12c2, 0xb12c5}, {0xb12c8, 0xb12d6}, {0xb12d8, 0xb1310}, {0xb1312, 0xb1315}, - {0xb1318, 0xb135a}, {0xb1380, 0xb138f}, {0xb13a0, 0xb13f5}, {0xb13f8, 0xb13fd}, - {0xb1401, 0xb166c}, {0xb166f, 0xb167f}, {0xb1681, 0xb169a}, {0xb16a0, 0xb16ea}, - {0xb16f1, 0xb16f8}, {0xb1700, 0xb170c}, {0xb170e, 0xb1711}, {0xb1720, 0xb1731}, - {0xb1740, 0xb1751}, {0xb1760, 0xb176c}, {0xb176e, 0xb1770}, {0xb1780, 0xb17b3}, - {0xb1820, 0xb1877}, {0xb1880, 0xb1884}, {0xb1887, 0xb18a8}, {0xb18b0, 0xb18f5}, - {0xb1900, 0xb191e}, {0xb1950, 0xb196d}, {0xb1970, 0xb1974}, {0xb1980, 0xb19ab}, - {0xb19b0, 0xb19c9}, {0xb1a00, 0xb1a16}, {0xb1a20, 0xb1a54}, {0xb1b05, 0xb1b33}, - {0xb1b45, 0xb1b4b}, {0xb1b83, 0xb1ba0}, {0xb1bba, 0xb1be5}, {0xb1c00, 0xb1c23}, - {0xb1c4d, 0xb1c4f}, {0xb1c5a, 0xb1c7d}, {0xb1c80, 0xb1c88}, {0xb1ce9, 0xb1cec}, - {0xb1cee, 0xb1cf1}, {0xb1d00, 0xb1dbf}, {0xb1e00, 0xb1f15}, {0xb1f18, 0xb1f1d}, - {0xb1f20, 0xb1f45}, {0xb1f48, 0xb1f4d}, {0xb1f50, 0xb1f57}, {0xb1f5f, 0xb1f7d}, - {0xb1f80, 0xb1fb4}, {0xb1fb6, 0xb1fbc}, {0xb1fc2, 0xb1fc4}, {0xb1fc6, 0xb1fcc}, - {0xb1fd0, 0xb1fd3}, {0xb1fd6, 0xb1fdb}, {0xb1fe0, 0xb1fec}, {0xb1ff2, 0xb1ff4}, - {0xb1ff6, 0xb1ffc}, {0xb2090, 0xb209c}, {0xb210a, 0xb2113}, {0xb2119, 0xb211d}, - {0xb212a, 0xb212d}, {0xb212f, 0xb2139}, {0xb213c, 0xb213f}, {0xb2145, 0xb2149}, - {0xb2c00, 0xb2c2e}, {0xb2c30, 0xb2c5e}, {0xb2c60, 0xb2ce4}, {0xb2ceb, 0xb2cee}, - {0xb2d00, 0xb2d25}, {0xb2d30, 0xb2d67}, {0xb2d80, 0xb2d96}, {0xb2da0, 0xb2da6}, - {0xb2da8, 0xb2dae}, {0xb2db0, 0xb2db6}, {0xb2db8, 0xb2dbe}, {0xb2dc0, 0xb2dc6}, - {0xb2dc8, 0xb2dce}, {0xb2dd0, 0xb2dd6}, {0xb2dd8, 0xb2dde}, {0xb3031, 0xb3035}, - {0xb3041, 0xb3096}, {0xb309d, 0xb309f}, {0xb30a1, 0xb30fa}, {0xb30fc, 0xb30ff}, - {0xb3105, 0xb312e}, {0xb3131, 0xb318e}, {0xb31a0, 0xb31ba}, {0xb31f0, 0xb31ff}, - {0xb3400, 0xb4db5}, {0xb4e00, 0xb9fea}, {0xba000, 0xba48c}, {0xba4d0, 0xba4fd}, - {0xba500, 0xba60c}, {0xba610, 0xba61f}, {0xba640, 0xba66e}, {0xba67f, 0xba69d}, - {0xba6a0, 0xba6e5}, {0xba717, 0xba71f}, {0xba722, 0xba788}, {0xba78b, 0xba7ae}, - {0xba7b0, 0xba7b7}, {0xba7f7, 0xba801}, {0xba803, 0xba805}, {0xba807, 0xba80a}, - {0xba80c, 0xba822}, {0xba840, 0xba873}, {0xba882, 0xba8b3}, {0xba8f2, 0xba8f7}, - {0xba90a, 0xba925}, {0xba930, 0xba946}, {0xba960, 0xba97c}, {0xba984, 0xba9b2}, - {0xba9e0, 0xba9e4}, {0xba9e6, 0xba9ef}, {0xba9fa, 0xba9fe}, {0xbaa00, 0xbaa28}, - {0xbaa40, 0xbaa42}, {0xbaa44, 0xbaa4b}, {0xbaa60, 0xbaa76}, {0xbaa7e, 0xbaaaf}, - {0xbaab9, 0xbaabd}, {0xbaadb, 0xbaadd}, {0xbaae0, 0xbaaea}, {0xbaaf2, 0xbaaf4}, - {0xbab01, 0xbab06}, {0xbab09, 0xbab0e}, {0xbab11, 0xbab16}, {0xbab20, 0xbab26}, - {0xbab28, 0xbab2e}, {0xbab30, 0xbab5a}, {0xbab5c, 0xbab65}, {0xbab70, 0xbabe2}, - {0xbac00, 0xbd7a3}, {0xbd7b0, 0xbd7c6}, {0xbd7cb, 0xbd7fb}, {0xbf900, 0xbfa6d}, - {0xbfa70, 0xbfad9}, {0xbfb00, 0xbfb06}, {0xbfb13, 0xbfb17}, {0xbfb1f, 0xbfb28}, - {0xbfb2a, 0xbfb36}, {0xbfb38, 0xbfb3c}, {0xbfb46, 0xbfbb1}, {0xbfbd3, 0xbfd3d}, - {0xbfd50, 0xbfd8f}, {0xbfd92, 0xbfdc7}, {0xbfdf0, 0xbfdfb}, {0xbfe70, 0xbfe74}, - {0xbfe76, 0xbfefc}, {0xbff21, 0xbff3a}, {0xbff41, 0xbff5a}, {0xbff66, 0xbffbe}, - {0xbffc2, 0xbffc7}, {0xbffca, 0xbffcf}, {0xbffd2, 0xbffd7}, {0xbffda, 0xbffdc}, - {0xc0041, 0xc005a}, {0xc0061, 0xc007a}, {0xc00c0, 0xc00d6}, {0xc00d8, 0xc00f6}, - {0xc00f8, 0xc02c1}, {0xc02c6, 0xc02d1}, {0xc02e0, 0xc02e4}, {0xc0370, 0xc0374}, - {0xc037a, 0xc037d}, {0xc0388, 0xc038a}, {0xc038e, 0xc03a1}, {0xc03a3, 0xc03f5}, - {0xc03f7, 0xc0481}, {0xc048a, 0xc052f}, {0xc0531, 0xc0556}, {0xc0561, 0xc0587}, - {0xc05d0, 0xc05ea}, {0xc05f0, 0xc05f2}, {0xc0620, 0xc064a}, {0xc0671, 0xc06d3}, - {0xc06fa, 0xc06fc}, {0xc0712, 0xc072f}, {0xc074d, 0xc07a5}, {0xc07ca, 0xc07ea}, - {0xc0800, 0xc0815}, {0xc0840, 0xc0858}, {0xc0860, 0xc086a}, {0xc08a0, 0xc08b4}, - {0xc08b6, 0xc08bd}, {0xc0904, 0xc0939}, {0xc0958, 0xc0961}, {0xc0971, 0xc0980}, - {0xc0985, 0xc098c}, {0xc0993, 0xc09a8}, {0xc09aa, 0xc09b0}, {0xc09b6, 0xc09b9}, - {0xc09df, 0xc09e1}, {0xc0a05, 0xc0a0a}, {0xc0a13, 0xc0a28}, {0xc0a2a, 0xc0a30}, - {0xc0a59, 0xc0a5c}, {0xc0a72, 0xc0a74}, {0xc0a85, 0xc0a8d}, {0xc0a8f, 0xc0a91}, - {0xc0a93, 0xc0aa8}, {0xc0aaa, 0xc0ab0}, {0xc0ab5, 0xc0ab9}, {0xc0b05, 0xc0b0c}, - {0xc0b13, 0xc0b28}, {0xc0b2a, 0xc0b30}, {0xc0b35, 0xc0b39}, {0xc0b5f, 0xc0b61}, - {0xc0b85, 0xc0b8a}, {0xc0b8e, 0xc0b90}, {0xc0b92, 0xc0b95}, {0xc0ba8, 0xc0baa}, - {0xc0bae, 0xc0bb9}, {0xc0c05, 0xc0c0c}, {0xc0c0e, 0xc0c10}, {0xc0c12, 0xc0c28}, - {0xc0c2a, 0xc0c39}, {0xc0c58, 0xc0c5a}, {0xc0c85, 0xc0c8c}, {0xc0c8e, 0xc0c90}, - {0xc0c92, 0xc0ca8}, {0xc0caa, 0xc0cb3}, {0xc0cb5, 0xc0cb9}, {0xc0d05, 0xc0d0c}, - {0xc0d0e, 0xc0d10}, {0xc0d12, 0xc0d3a}, {0xc0d54, 0xc0d56}, {0xc0d5f, 0xc0d61}, - {0xc0d7a, 0xc0d7f}, {0xc0d85, 0xc0d96}, {0xc0d9a, 0xc0db1}, {0xc0db3, 0xc0dbb}, - {0xc0dc0, 0xc0dc6}, {0xc0e01, 0xc0e30}, {0xc0e40, 0xc0e46}, {0xc0e94, 0xc0e97}, - {0xc0e99, 0xc0e9f}, {0xc0ea1, 0xc0ea3}, {0xc0ead, 0xc0eb0}, {0xc0ec0, 0xc0ec4}, - {0xc0edc, 0xc0edf}, {0xc0f40, 0xc0f47}, {0xc0f49, 0xc0f6c}, {0xc0f88, 0xc0f8c}, - {0xc1000, 0xc102a}, {0xc1050, 0xc1055}, {0xc105a, 0xc105d}, {0xc106e, 0xc1070}, - {0xc1075, 0xc1081}, {0xc10a0, 0xc10c5}, {0xc10d0, 0xc10fa}, {0xc10fc, 0xc1248}, - {0xc124a, 0xc124d}, {0xc1250, 0xc1256}, {0xc125a, 0xc125d}, {0xc1260, 0xc1288}, - {0xc128a, 0xc128d}, {0xc1290, 0xc12b0}, {0xc12b2, 0xc12b5}, {0xc12b8, 0xc12be}, - {0xc12c2, 0xc12c5}, {0xc12c8, 0xc12d6}, {0xc12d8, 0xc1310}, {0xc1312, 0xc1315}, - {0xc1318, 0xc135a}, {0xc1380, 0xc138f}, {0xc13a0, 0xc13f5}, {0xc13f8, 0xc13fd}, - {0xc1401, 0xc166c}, {0xc166f, 0xc167f}, {0xc1681, 0xc169a}, {0xc16a0, 0xc16ea}, - {0xc16f1, 0xc16f8}, {0xc1700, 0xc170c}, {0xc170e, 0xc1711}, {0xc1720, 0xc1731}, - {0xc1740, 0xc1751}, {0xc1760, 0xc176c}, {0xc176e, 0xc1770}, {0xc1780, 0xc17b3}, - {0xc1820, 0xc1877}, {0xc1880, 0xc1884}, {0xc1887, 0xc18a8}, {0xc18b0, 0xc18f5}, - {0xc1900, 0xc191e}, {0xc1950, 0xc196d}, {0xc1970, 0xc1974}, {0xc1980, 0xc19ab}, - {0xc19b0, 0xc19c9}, {0xc1a00, 0xc1a16}, {0xc1a20, 0xc1a54}, {0xc1b05, 0xc1b33}, - {0xc1b45, 0xc1b4b}, {0xc1b83, 0xc1ba0}, {0xc1bba, 0xc1be5}, {0xc1c00, 0xc1c23}, - {0xc1c4d, 0xc1c4f}, {0xc1c5a, 0xc1c7d}, {0xc1c80, 0xc1c88}, {0xc1ce9, 0xc1cec}, - {0xc1cee, 0xc1cf1}, {0xc1d00, 0xc1dbf}, {0xc1e00, 0xc1f15}, {0xc1f18, 0xc1f1d}, - {0xc1f20, 0xc1f45}, {0xc1f48, 0xc1f4d}, {0xc1f50, 0xc1f57}, {0xc1f5f, 0xc1f7d}, - {0xc1f80, 0xc1fb4}, {0xc1fb6, 0xc1fbc}, {0xc1fc2, 0xc1fc4}, {0xc1fc6, 0xc1fcc}, - {0xc1fd0, 0xc1fd3}, {0xc1fd6, 0xc1fdb}, {0xc1fe0, 0xc1fec}, {0xc1ff2, 0xc1ff4}, - {0xc1ff6, 0xc1ffc}, {0xc2090, 0xc209c}, {0xc210a, 0xc2113}, {0xc2119, 0xc211d}, - {0xc212a, 0xc212d}, {0xc212f, 0xc2139}, {0xc213c, 0xc213f}, {0xc2145, 0xc2149}, - {0xc2c00, 0xc2c2e}, {0xc2c30, 0xc2c5e}, {0xc2c60, 0xc2ce4}, {0xc2ceb, 0xc2cee}, - {0xc2d00, 0xc2d25}, {0xc2d30, 0xc2d67}, {0xc2d80, 0xc2d96}, {0xc2da0, 0xc2da6}, - {0xc2da8, 0xc2dae}, {0xc2db0, 0xc2db6}, {0xc2db8, 0xc2dbe}, {0xc2dc0, 0xc2dc6}, - {0xc2dc8, 0xc2dce}, {0xc2dd0, 0xc2dd6}, {0xc2dd8, 0xc2dde}, {0xc3031, 0xc3035}, - {0xc3041, 0xc3096}, {0xc309d, 0xc309f}, {0xc30a1, 0xc30fa}, {0xc30fc, 0xc30ff}, - {0xc3105, 0xc312e}, {0xc3131, 0xc318e}, {0xc31a0, 0xc31ba}, {0xc31f0, 0xc31ff}, - {0xc3400, 0xc4db5}, {0xc4e00, 0xc9fea}, {0xca000, 0xca48c}, {0xca4d0, 0xca4fd}, - {0xca500, 0xca60c}, {0xca610, 0xca61f}, {0xca640, 0xca66e}, {0xca67f, 0xca69d}, - {0xca6a0, 0xca6e5}, {0xca717, 0xca71f}, {0xca722, 0xca788}, {0xca78b, 0xca7ae}, - {0xca7b0, 0xca7b7}, {0xca7f7, 0xca801}, {0xca803, 0xca805}, {0xca807, 0xca80a}, - {0xca80c, 0xca822}, {0xca840, 0xca873}, {0xca882, 0xca8b3}, {0xca8f2, 0xca8f7}, - {0xca90a, 0xca925}, {0xca930, 0xca946}, {0xca960, 0xca97c}, {0xca984, 0xca9b2}, - {0xca9e0, 0xca9e4}, {0xca9e6, 0xca9ef}, {0xca9fa, 0xca9fe}, {0xcaa00, 0xcaa28}, - {0xcaa40, 0xcaa42}, {0xcaa44, 0xcaa4b}, {0xcaa60, 0xcaa76}, {0xcaa7e, 0xcaaaf}, - {0xcaab9, 0xcaabd}, {0xcaadb, 0xcaadd}, {0xcaae0, 0xcaaea}, {0xcaaf2, 0xcaaf4}, - {0xcab01, 0xcab06}, {0xcab09, 0xcab0e}, {0xcab11, 0xcab16}, {0xcab20, 0xcab26}, - {0xcab28, 0xcab2e}, {0xcab30, 0xcab5a}, {0xcab5c, 0xcab65}, {0xcab70, 0xcabe2}, - {0xcac00, 0xcd7a3}, {0xcd7b0, 0xcd7c6}, {0xcd7cb, 0xcd7fb}, {0xcf900, 0xcfa6d}, - {0xcfa70, 0xcfad9}, {0xcfb00, 0xcfb06}, {0xcfb13, 0xcfb17}, {0xcfb1f, 0xcfb28}, - {0xcfb2a, 0xcfb36}, {0xcfb38, 0xcfb3c}, {0xcfb46, 0xcfbb1}, {0xcfbd3, 0xcfd3d}, - {0xcfd50, 0xcfd8f}, {0xcfd92, 0xcfdc7}, {0xcfdf0, 0xcfdfb}, {0xcfe70, 0xcfe74}, - {0xcfe76, 0xcfefc}, {0xcff21, 0xcff3a}, {0xcff41, 0xcff5a}, {0xcff66, 0xcffbe}, - {0xcffc2, 0xcffc7}, {0xcffca, 0xcffcf}, {0xcffd2, 0xcffd7}, {0xcffda, 0xcffdc}, - {0xd0041, 0xd005a}, {0xd0061, 0xd007a}, {0xd00c0, 0xd00d6}, {0xd00d8, 0xd00f6}, - {0xd00f8, 0xd02c1}, {0xd02c6, 0xd02d1}, {0xd02e0, 0xd02e4}, {0xd0370, 0xd0374}, - {0xd037a, 0xd037d}, {0xd0388, 0xd038a}, {0xd038e, 0xd03a1}, {0xd03a3, 0xd03f5}, - {0xd03f7, 0xd0481}, {0xd048a, 0xd052f}, {0xd0531, 0xd0556}, {0xd0561, 0xd0587}, - {0xd05d0, 0xd05ea}, {0xd05f0, 0xd05f2}, {0xd0620, 0xd064a}, {0xd0671, 0xd06d3}, - {0xd06fa, 0xd06fc}, {0xd0712, 0xd072f}, {0xd074d, 0xd07a5}, {0xd07ca, 0xd07ea}, - {0xd0800, 0xd0815}, {0xd0840, 0xd0858}, {0xd0860, 0xd086a}, {0xd08a0, 0xd08b4}, - {0xd08b6, 0xd08bd}, {0xd0904, 0xd0939}, {0xd0958, 0xd0961}, {0xd0971, 0xd0980}, - {0xd0985, 0xd098c}, {0xd0993, 0xd09a8}, {0xd09aa, 0xd09b0}, {0xd09b6, 0xd09b9}, - {0xd09df, 0xd09e1}, {0xd0a05, 0xd0a0a}, {0xd0a13, 0xd0a28}, {0xd0a2a, 0xd0a30}, - {0xd0a59, 0xd0a5c}, {0xd0a72, 0xd0a74}, {0xd0a85, 0xd0a8d}, {0xd0a8f, 0xd0a91}, - {0xd0a93, 0xd0aa8}, {0xd0aaa, 0xd0ab0}, {0xd0ab5, 0xd0ab9}, {0xd0b05, 0xd0b0c}, - {0xd0b13, 0xd0b28}, {0xd0b2a, 0xd0b30}, {0xd0b35, 0xd0b39}, {0xd0b5f, 0xd0b61}, - {0xd0b85, 0xd0b8a}, {0xd0b8e, 0xd0b90}, {0xd0b92, 0xd0b95}, {0xd0ba8, 0xd0baa}, - {0xd0bae, 0xd0bb9}, {0xd0c05, 0xd0c0c}, {0xd0c0e, 0xd0c10}, {0xd0c12, 0xd0c28}, - {0xd0c2a, 0xd0c39}, {0xd0c58, 0xd0c5a}, {0xd0c85, 0xd0c8c}, {0xd0c8e, 0xd0c90}, - {0xd0c92, 0xd0ca8}, {0xd0caa, 0xd0cb3}, {0xd0cb5, 0xd0cb9}, {0xd0d05, 0xd0d0c}, - {0xd0d0e, 0xd0d10}, {0xd0d12, 0xd0d3a}, {0xd0d54, 0xd0d56}, {0xd0d5f, 0xd0d61}, - {0xd0d7a, 0xd0d7f}, {0xd0d85, 0xd0d96}, {0xd0d9a, 0xd0db1}, {0xd0db3, 0xd0dbb}, - {0xd0dc0, 0xd0dc6}, {0xd0e01, 0xd0e30}, {0xd0e40, 0xd0e46}, {0xd0e94, 0xd0e97}, - {0xd0e99, 0xd0e9f}, {0xd0ea1, 0xd0ea3}, {0xd0ead, 0xd0eb0}, {0xd0ec0, 0xd0ec4}, - {0xd0edc, 0xd0edf}, {0xd0f40, 0xd0f47}, {0xd0f49, 0xd0f6c}, {0xd0f88, 0xd0f8c}, - {0xd1000, 0xd102a}, {0xd1050, 0xd1055}, {0xd105a, 0xd105d}, {0xd106e, 0xd1070}, - {0xd1075, 0xd1081}, {0xd10a0, 0xd10c5}, {0xd10d0, 0xd10fa}, {0xd10fc, 0xd1248}, - {0xd124a, 0xd124d}, {0xd1250, 0xd1256}, {0xd125a, 0xd125d}, {0xd1260, 0xd1288}, - {0xd128a, 0xd128d}, {0xd1290, 0xd12b0}, {0xd12b2, 0xd12b5}, {0xd12b8, 0xd12be}, - {0xd12c2, 0xd12c5}, {0xd12c8, 0xd12d6}, {0xd12d8, 0xd1310}, {0xd1312, 0xd1315}, - {0xd1318, 0xd135a}, {0xd1380, 0xd138f}, {0xd13a0, 0xd13f5}, {0xd13f8, 0xd13fd}, - {0xd1401, 0xd166c}, {0xd166f, 0xd167f}, {0xd1681, 0xd169a}, {0xd16a0, 0xd16ea}, - {0xd16f1, 0xd16f8}, {0xd1700, 0xd170c}, {0xd170e, 0xd1711}, {0xd1720, 0xd1731}, - {0xd1740, 0xd1751}, {0xd1760, 0xd176c}, {0xd176e, 0xd1770}, {0xd1780, 0xd17b3}, - {0xd1820, 0xd1877}, {0xd1880, 0xd1884}, {0xd1887, 0xd18a8}, {0xd18b0, 0xd18f5}, - {0xd1900, 0xd191e}, {0xd1950, 0xd196d}, {0xd1970, 0xd1974}, {0xd1980, 0xd19ab}, - {0xd19b0, 0xd19c9}, {0xd1a00, 0xd1a16}, {0xd1a20, 0xd1a54}, {0xd1b05, 0xd1b33}, - {0xd1b45, 0xd1b4b}, {0xd1b83, 0xd1ba0}, {0xd1bba, 0xd1be5}, {0xd1c00, 0xd1c23}, - {0xd1c4d, 0xd1c4f}, {0xd1c5a, 0xd1c7d}, {0xd1c80, 0xd1c88}, {0xd1ce9, 0xd1cec}, - {0xd1cee, 0xd1cf1}, {0xd1d00, 0xd1dbf}, {0xd1e00, 0xd1f15}, {0xd1f18, 0xd1f1d}, - {0xd1f20, 0xd1f45}, {0xd1f48, 0xd1f4d}, {0xd1f50, 0xd1f57}, {0xd1f5f, 0xd1f7d}, - {0xd1f80, 0xd1fb4}, {0xd1fb6, 0xd1fbc}, {0xd1fc2, 0xd1fc4}, {0xd1fc6, 0xd1fcc}, - {0xd1fd0, 0xd1fd3}, {0xd1fd6, 0xd1fdb}, {0xd1fe0, 0xd1fec}, {0xd1ff2, 0xd1ff4}, - {0xd1ff6, 0xd1ffc}, {0xd2090, 0xd209c}, {0xd210a, 0xd2113}, {0xd2119, 0xd211d}, - {0xd212a, 0xd212d}, {0xd212f, 0xd2139}, {0xd213c, 0xd213f}, {0xd2145, 0xd2149}, - {0xd2c00, 0xd2c2e}, {0xd2c30, 0xd2c5e}, {0xd2c60, 0xd2ce4}, {0xd2ceb, 0xd2cee}, - {0xd2d00, 0xd2d25}, {0xd2d30, 0xd2d67}, {0xd2d80, 0xd2d96}, {0xd2da0, 0xd2da6}, - {0xd2da8, 0xd2dae}, {0xd2db0, 0xd2db6}, {0xd2db8, 0xd2dbe}, {0xd2dc0, 0xd2dc6}, - {0xd2dc8, 0xd2dce}, {0xd2dd0, 0xd2dd6}, {0xd2dd8, 0xd2dde}, {0xd3031, 0xd3035}, - {0xd3041, 0xd3096}, {0xd309d, 0xd309f}, {0xd30a1, 0xd30fa}, {0xd30fc, 0xd30ff}, - {0xd3105, 0xd312e}, {0xd3131, 0xd318e}, {0xd31a0, 0xd31ba}, {0xd31f0, 0xd31ff}, - {0xd3400, 0xd4db5}, {0xd4e00, 0xd9fea}, {0xda000, 0xda48c}, {0xda4d0, 0xda4fd}, - {0xda500, 0xda60c}, {0xda610, 0xda61f}, {0xda640, 0xda66e}, {0xda67f, 0xda69d}, - {0xda6a0, 0xda6e5}, {0xda717, 0xda71f}, {0xda722, 0xda788}, {0xda78b, 0xda7ae}, - {0xda7b0, 0xda7b7}, {0xda7f7, 0xda801}, {0xda803, 0xda805}, {0xda807, 0xda80a}, - {0xda80c, 0xda822}, {0xda840, 0xda873}, {0xda882, 0xda8b3}, {0xda8f2, 0xda8f7}, - {0xda90a, 0xda925}, {0xda930, 0xda946}, {0xda960, 0xda97c}, {0xda984, 0xda9b2}, - {0xda9e0, 0xda9e4}, {0xda9e6, 0xda9ef}, {0xda9fa, 0xda9fe}, {0xdaa00, 0xdaa28}, - {0xdaa40, 0xdaa42}, {0xdaa44, 0xdaa4b}, {0xdaa60, 0xdaa76}, {0xdaa7e, 0xdaaaf}, - {0xdaab9, 0xdaabd}, {0xdaadb, 0xdaadd}, {0xdaae0, 0xdaaea}, {0xdaaf2, 0xdaaf4}, - {0xdab01, 0xdab06}, {0xdab09, 0xdab0e}, {0xdab11, 0xdab16}, {0xdab20, 0xdab26}, - {0xdab28, 0xdab2e}, {0xdab30, 0xdab5a}, {0xdab5c, 0xdab65}, {0xdab70, 0xdabe2}, - {0xdac00, 0xdd7a3}, {0xdd7b0, 0xdd7c6}, {0xdd7cb, 0xdd7fb}, {0xdf900, 0xdfa6d}, - {0xdfa70, 0xdfad9}, {0xdfb00, 0xdfb06}, {0xdfb13, 0xdfb17}, {0xdfb1f, 0xdfb28}, - {0xdfb2a, 0xdfb36}, {0xdfb38, 0xdfb3c}, {0xdfb46, 0xdfbb1}, {0xdfbd3, 0xdfd3d}, - {0xdfd50, 0xdfd8f}, {0xdfd92, 0xdfdc7}, {0xdfdf0, 0xdfdfb}, {0xdfe70, 0xdfe74}, - {0xdfe76, 0xdfefc}, {0xdff21, 0xdff3a}, {0xdff41, 0xdff5a}, {0xdff66, 0xdffbe}, - {0xdffc2, 0xdffc7}, {0xdffca, 0xdffcf}, {0xdffd2, 0xdffd7}, {0xdffda, 0xdffdc}, - {0xe0041, 0xe005a}, {0xe0061, 0xe007a}, {0xe00c0, 0xe00d6}, {0xe00d8, 0xe00f6}, - {0xe00f8, 0xe02c1}, {0xe02c6, 0xe02d1}, {0xe02e0, 0xe02e4}, {0xe0370, 0xe0374}, - {0xe037a, 0xe037d}, {0xe0388, 0xe038a}, {0xe038e, 0xe03a1}, {0xe03a3, 0xe03f5}, - {0xe03f7, 0xe0481}, {0xe048a, 0xe052f}, {0xe0531, 0xe0556}, {0xe0561, 0xe0587}, - {0xe05d0, 0xe05ea}, {0xe05f0, 0xe05f2}, {0xe0620, 0xe064a}, {0xe0671, 0xe06d3}, - {0xe06fa, 0xe06fc}, {0xe0712, 0xe072f}, {0xe074d, 0xe07a5}, {0xe07ca, 0xe07ea}, - {0xe0800, 0xe0815}, {0xe0840, 0xe0858}, {0xe0860, 0xe086a}, {0xe08a0, 0xe08b4}, - {0xe08b6, 0xe08bd}, {0xe0904, 0xe0939}, {0xe0958, 0xe0961}, {0xe0971, 0xe0980}, - {0xe0985, 0xe098c}, {0xe0993, 0xe09a8}, {0xe09aa, 0xe09b0}, {0xe09b6, 0xe09b9}, - {0xe09df, 0xe09e1}, {0xe0a05, 0xe0a0a}, {0xe0a13, 0xe0a28}, {0xe0a2a, 0xe0a30}, - {0xe0a59, 0xe0a5c}, {0xe0a72, 0xe0a74}, {0xe0a85, 0xe0a8d}, {0xe0a8f, 0xe0a91}, - {0xe0a93, 0xe0aa8}, {0xe0aaa, 0xe0ab0}, {0xe0ab5, 0xe0ab9}, {0xe0b05, 0xe0b0c}, - {0xe0b13, 0xe0b28}, {0xe0b2a, 0xe0b30}, {0xe0b35, 0xe0b39}, {0xe0b5f, 0xe0b61}, - {0xe0b85, 0xe0b8a}, {0xe0b8e, 0xe0b90}, {0xe0b92, 0xe0b95}, {0xe0ba8, 0xe0baa}, - {0xe0bae, 0xe0bb9}, {0xe0c05, 0xe0c0c}, {0xe0c0e, 0xe0c10}, {0xe0c12, 0xe0c28}, - {0xe0c2a, 0xe0c39}, {0xe0c58, 0xe0c5a}, {0xe0c85, 0xe0c8c}, {0xe0c8e, 0xe0c90}, - {0xe0c92, 0xe0ca8}, {0xe0caa, 0xe0cb3}, {0xe0cb5, 0xe0cb9}, {0xe0d05, 0xe0d0c}, - {0xe0d0e, 0xe0d10}, {0xe0d12, 0xe0d3a}, {0xe0d54, 0xe0d56}, {0xe0d5f, 0xe0d61}, - {0xe0d7a, 0xe0d7f}, {0xe0d85, 0xe0d96}, {0xe0d9a, 0xe0db1}, {0xe0db3, 0xe0dbb}, - {0xe0dc0, 0xe0dc6}, {0xe0e01, 0xe0e30}, {0xe0e40, 0xe0e46}, {0xe0e94, 0xe0e97}, - {0xe0e99, 0xe0e9f}, {0xe0ea1, 0xe0ea3}, {0xe0ead, 0xe0eb0}, {0xe0ec0, 0xe0ec4}, - {0xe0edc, 0xe0edf}, {0xe0f40, 0xe0f47}, {0xe0f49, 0xe0f6c}, {0xe0f88, 0xe0f8c}, - {0xe1000, 0xe102a}, {0xe1050, 0xe1055}, {0xe105a, 0xe105d}, {0xe106e, 0xe1070}, - {0xe1075, 0xe1081}, {0xe10a0, 0xe10c5}, {0xe10d0, 0xe10fa}, {0xe10fc, 0xe1248}, - {0xe124a, 0xe124d}, {0xe1250, 0xe1256}, {0xe125a, 0xe125d}, {0xe1260, 0xe1288}, - {0xe128a, 0xe128d}, {0xe1290, 0xe12b0}, {0xe12b2, 0xe12b5}, {0xe12b8, 0xe12be}, - {0xe12c2, 0xe12c5}, {0xe12c8, 0xe12d6}, {0xe12d8, 0xe1310}, {0xe1312, 0xe1315}, - {0xe1318, 0xe135a}, {0xe1380, 0xe138f}, {0xe13a0, 0xe13f5}, {0xe13f8, 0xe13fd}, - {0xe1401, 0xe166c}, {0xe166f, 0xe167f}, {0xe1681, 0xe169a}, {0xe16a0, 0xe16ea}, - {0xe16f1, 0xe16f8}, {0xe1700, 0xe170c}, {0xe170e, 0xe1711}, {0xe1720, 0xe1731}, - {0xe1740, 0xe1751}, {0xe1760, 0xe176c}, {0xe176e, 0xe1770}, {0xe1780, 0xe17b3}, - {0xe1820, 0xe1877}, {0xe1880, 0xe1884}, {0xe1887, 0xe18a8}, {0xe18b0, 0xe18f5}, - {0xe1900, 0xe191e}, {0xe1950, 0xe196d}, {0xe1970, 0xe1974}, {0xe1980, 0xe19ab}, - {0xe19b0, 0xe19c9}, {0xe1a00, 0xe1a16}, {0xe1a20, 0xe1a54}, {0xe1b05, 0xe1b33}, - {0xe1b45, 0xe1b4b}, {0xe1b83, 0xe1ba0}, {0xe1bba, 0xe1be5}, {0xe1c00, 0xe1c23}, - {0xe1c4d, 0xe1c4f}, {0xe1c5a, 0xe1c7d}, {0xe1c80, 0xe1c88}, {0xe1ce9, 0xe1cec}, - {0xe1cee, 0xe1cf1}, {0xe1d00, 0xe1dbf}, {0xe1e00, 0xe1f15}, {0xe1f18, 0xe1f1d}, - {0xe1f20, 0xe1f45}, {0xe1f48, 0xe1f4d}, {0xe1f50, 0xe1f57}, {0xe1f5f, 0xe1f7d}, - {0xe1f80, 0xe1fb4}, {0xe1fb6, 0xe1fbc}, {0xe1fc2, 0xe1fc4}, {0xe1fc6, 0xe1fcc}, - {0xe1fd0, 0xe1fd3}, {0xe1fd6, 0xe1fdb}, {0xe1fe0, 0xe1fec}, {0xe1ff2, 0xe1ff4}, - {0xe1ff6, 0xe1ffc}, {0xe2090, 0xe209c}, {0xe210a, 0xe2113}, {0xe2119, 0xe211d}, - {0xe212a, 0xe212d}, {0xe212f, 0xe2139}, {0xe213c, 0xe213f}, {0xe2145, 0xe2149}, - {0xe2c00, 0xe2c2e}, {0xe2c30, 0xe2c5e}, {0xe2c60, 0xe2ce4}, {0xe2ceb, 0xe2cee}, - {0xe2d00, 0xe2d25}, {0xe2d30, 0xe2d67}, {0xe2d80, 0xe2d96}, {0xe2da0, 0xe2da6}, - {0xe2da8, 0xe2dae}, {0xe2db0, 0xe2db6}, {0xe2db8, 0xe2dbe}, {0xe2dc0, 0xe2dc6}, - {0xe2dc8, 0xe2dce}, {0xe2dd0, 0xe2dd6}, {0xe2dd8, 0xe2dde}, {0xe3031, 0xe3035}, - {0xe3041, 0xe3096}, {0xe309d, 0xe309f}, {0xe30a1, 0xe30fa}, {0xe30fc, 0xe30ff}, - {0xe3105, 0xe312e}, {0xe3131, 0xe318e}, {0xe31a0, 0xe31ba}, {0xe31f0, 0xe31ff}, - {0xe3400, 0xe4db5}, {0xe4e00, 0xe9fea}, {0xea000, 0xea48c}, {0xea4d0, 0xea4fd}, - {0xea500, 0xea60c}, {0xea610, 0xea61f}, {0xea640, 0xea66e}, {0xea67f, 0xea69d}, - {0xea6a0, 0xea6e5}, {0xea717, 0xea71f}, {0xea722, 0xea788}, {0xea78b, 0xea7ae}, - {0xea7b0, 0xea7b7}, {0xea7f7, 0xea801}, {0xea803, 0xea805}, {0xea807, 0xea80a}, - {0xea80c, 0xea822}, {0xea840, 0xea873}, {0xea882, 0xea8b3}, {0xea8f2, 0xea8f7}, - {0xea90a, 0xea925}, {0xea930, 0xea946}, {0xea960, 0xea97c}, {0xea984, 0xea9b2}, - {0xea9e0, 0xea9e4}, {0xea9e6, 0xea9ef}, {0xea9fa, 0xea9fe}, {0xeaa00, 0xeaa28}, - {0xeaa40, 0xeaa42}, {0xeaa44, 0xeaa4b}, {0xeaa60, 0xeaa76}, {0xeaa7e, 0xeaaaf}, - {0xeaab9, 0xeaabd}, {0xeaadb, 0xeaadd}, {0xeaae0, 0xeaaea}, {0xeaaf2, 0xeaaf4}, - {0xeab01, 0xeab06}, {0xeab09, 0xeab0e}, {0xeab11, 0xeab16}, {0xeab20, 0xeab26}, - {0xeab28, 0xeab2e}, {0xeab30, 0xeab5a}, {0xeab5c, 0xeab65}, {0xeab70, 0xeabe2}, - {0xeac00, 0xed7a3}, {0xed7b0, 0xed7c6}, {0xed7cb, 0xed7fb}, {0xef900, 0xefa6d}, - {0xefa70, 0xefad9}, {0xefb00, 0xefb06}, {0xefb13, 0xefb17}, {0xefb1f, 0xefb28}, - {0xefb2a, 0xefb36}, {0xefb38, 0xefb3c}, {0xefb46, 0xefbb1}, {0xefbd3, 0xefd3d}, - {0xefd50, 0xefd8f}, {0xefd92, 0xefdc7}, {0xefdf0, 0xefdfb}, {0xefe70, 0xefe74}, - {0xefe76, 0xefefc}, {0xeff21, 0xeff3a}, {0xeff41, 0xeff5a}, {0xeff66, 0xeffbe}, - {0xeffc2, 0xeffc7}, {0xeffca, 0xeffcf}, {0xeffd2, 0xeffd7}, {0xeffda, 0xeffdc}, - {0xf0041, 0xf005a}, {0xf0061, 0xf007a}, {0xf00c0, 0xf00d6}, {0xf00d8, 0xf00f6}, - {0xf00f8, 0xf02c1}, {0xf02c6, 0xf02d1}, {0xf02e0, 0xf02e4}, {0xf0370, 0xf0374}, - {0xf037a, 0xf037d}, {0xf0388, 0xf038a}, {0xf038e, 0xf03a1}, {0xf03a3, 0xf03f5}, - {0xf03f7, 0xf0481}, {0xf048a, 0xf052f}, {0xf0531, 0xf0556}, {0xf0561, 0xf0587}, - {0xf05d0, 0xf05ea}, {0xf05f0, 0xf05f2}, {0xf0620, 0xf064a}, {0xf0671, 0xf06d3}, - {0xf06fa, 0xf06fc}, {0xf0712, 0xf072f}, {0xf074d, 0xf07a5}, {0xf07ca, 0xf07ea}, - {0xf0800, 0xf0815}, {0xf0840, 0xf0858}, {0xf0860, 0xf086a}, {0xf08a0, 0xf08b4}, - {0xf08b6, 0xf08bd}, {0xf0904, 0xf0939}, {0xf0958, 0xf0961}, {0xf0971, 0xf0980}, - {0xf0985, 0xf098c}, {0xf0993, 0xf09a8}, {0xf09aa, 0xf09b0}, {0xf09b6, 0xf09b9}, - {0xf09df, 0xf09e1}, {0xf0a05, 0xf0a0a}, {0xf0a13, 0xf0a28}, {0xf0a2a, 0xf0a30}, - {0xf0a59, 0xf0a5c}, {0xf0a72, 0xf0a74}, {0xf0a85, 0xf0a8d}, {0xf0a8f, 0xf0a91}, - {0xf0a93, 0xf0aa8}, {0xf0aaa, 0xf0ab0}, {0xf0ab5, 0xf0ab9}, {0xf0b05, 0xf0b0c}, - {0xf0b13, 0xf0b28}, {0xf0b2a, 0xf0b30}, {0xf0b35, 0xf0b39}, {0xf0b5f, 0xf0b61}, - {0xf0b85, 0xf0b8a}, {0xf0b8e, 0xf0b90}, {0xf0b92, 0xf0b95}, {0xf0ba8, 0xf0baa}, - {0xf0bae, 0xf0bb9}, {0xf0c05, 0xf0c0c}, {0xf0c0e, 0xf0c10}, {0xf0c12, 0xf0c28}, - {0xf0c2a, 0xf0c39}, {0xf0c58, 0xf0c5a}, {0xf0c85, 0xf0c8c}, {0xf0c8e, 0xf0c90}, - {0xf0c92, 0xf0ca8}, {0xf0caa, 0xf0cb3}, {0xf0cb5, 0xf0cb9}, {0xf0d05, 0xf0d0c}, - {0xf0d0e, 0xf0d10}, {0xf0d12, 0xf0d3a}, {0xf0d54, 0xf0d56}, {0xf0d5f, 0xf0d61}, - {0xf0d7a, 0xf0d7f}, {0xf0d85, 0xf0d96}, {0xf0d9a, 0xf0db1}, {0xf0db3, 0xf0dbb}, - {0xf0dc0, 0xf0dc6}, {0xf0e01, 0xf0e30}, {0xf0e40, 0xf0e46}, {0xf0e94, 0xf0e97}, - {0xf0e99, 0xf0e9f}, {0xf0ea1, 0xf0ea3}, {0xf0ead, 0xf0eb0}, {0xf0ec0, 0xf0ec4}, - {0xf0edc, 0xf0edf}, {0xf0f40, 0xf0f47}, {0xf0f49, 0xf0f6c}, {0xf0f88, 0xf0f8c}, - {0xf1000, 0xf102a}, {0xf1050, 0xf1055}, {0xf105a, 0xf105d}, {0xf106e, 0xf1070}, - {0xf1075, 0xf1081}, {0xf10a0, 0xf10c5}, {0xf10d0, 0xf10fa}, {0xf10fc, 0xf1248}, - {0xf124a, 0xf124d}, {0xf1250, 0xf1256}, {0xf125a, 0xf125d}, {0xf1260, 0xf1288}, - {0xf128a, 0xf128d}, {0xf1290, 0xf12b0}, {0xf12b2, 0xf12b5}, {0xf12b8, 0xf12be}, - {0xf12c2, 0xf12c5}, {0xf12c8, 0xf12d6}, {0xf12d8, 0xf1310}, {0xf1312, 0xf1315}, - {0xf1318, 0xf135a}, {0xf1380, 0xf138f}, {0xf13a0, 0xf13f5}, {0xf13f8, 0xf13fd}, - {0xf1401, 0xf166c}, {0xf166f, 0xf167f}, {0xf1681, 0xf169a}, {0xf16a0, 0xf16ea}, - {0xf16f1, 0xf16f8}, {0xf1700, 0xf170c}, {0xf170e, 0xf1711}, {0xf1720, 0xf1731}, - {0xf1740, 0xf1751}, {0xf1760, 0xf176c}, {0xf176e, 0xf1770}, {0xf1780, 0xf17b3}, - {0xf1820, 0xf1877}, {0xf1880, 0xf1884}, {0xf1887, 0xf18a8}, {0xf18b0, 0xf18f5}, - {0xf1900, 0xf191e}, {0xf1950, 0xf196d}, {0xf1970, 0xf1974}, {0xf1980, 0xf19ab}, - {0xf19b0, 0xf19c9}, {0xf1a00, 0xf1a16}, {0xf1a20, 0xf1a54}, {0xf1b05, 0xf1b33}, - {0xf1b45, 0xf1b4b}, {0xf1b83, 0xf1ba0}, {0xf1bba, 0xf1be5}, {0xf1c00, 0xf1c23}, - {0xf1c4d, 0xf1c4f}, {0xf1c5a, 0xf1c7d}, {0xf1c80, 0xf1c88}, {0xf1ce9, 0xf1cec}, - {0xf1cee, 0xf1cf1}, {0xf1d00, 0xf1dbf}, {0xf1e00, 0xf1f15}, {0xf1f18, 0xf1f1d}, - {0xf1f20, 0xf1f45}, {0xf1f48, 0xf1f4d}, {0xf1f50, 0xf1f57}, {0xf1f5f, 0xf1f7d}, - {0xf1f80, 0xf1fb4}, {0xf1fb6, 0xf1fbc}, {0xf1fc2, 0xf1fc4}, {0xf1fc6, 0xf1fcc}, - {0xf1fd0, 0xf1fd3}, {0xf1fd6, 0xf1fdb}, {0xf1fe0, 0xf1fec}, {0xf1ff2, 0xf1ff4}, - {0xf1ff6, 0xf1ffc}, {0xf2090, 0xf209c}, {0xf210a, 0xf2113}, {0xf2119, 0xf211d}, - {0xf212a, 0xf212d}, {0xf212f, 0xf2139}, {0xf213c, 0xf213f}, {0xf2145, 0xf2149}, - {0xf2c00, 0xf2c2e}, {0xf2c30, 0xf2c5e}, {0xf2c60, 0xf2ce4}, {0xf2ceb, 0xf2cee}, - {0xf2d00, 0xf2d25}, {0xf2d30, 0xf2d67}, {0xf2d80, 0xf2d96}, {0xf2da0, 0xf2da6}, - {0xf2da8, 0xf2dae}, {0xf2db0, 0xf2db6}, {0xf2db8, 0xf2dbe}, {0xf2dc0, 0xf2dc6}, - {0xf2dc8, 0xf2dce}, {0xf2dd0, 0xf2dd6}, {0xf2dd8, 0xf2dde}, {0xf3031, 0xf3035}, - {0xf3041, 0xf3096}, {0xf309d, 0xf309f}, {0xf30a1, 0xf30fa}, {0xf30fc, 0xf30ff}, - {0xf3105, 0xf312e}, {0xf3131, 0xf318e}, {0xf31a0, 0xf31ba}, {0xf31f0, 0xf31ff}, - {0xf3400, 0xf4db5}, {0xf4e00, 0xf9fea}, {0xfa000, 0xfa48c}, {0xfa4d0, 0xfa4fd}, - {0xfa500, 0xfa60c}, {0xfa610, 0xfa61f}, {0xfa640, 0xfa66e}, {0xfa67f, 0xfa69d}, - {0xfa6a0, 0xfa6e5}, {0xfa717, 0xfa71f}, {0xfa722, 0xfa788}, {0xfa78b, 0xfa7ae}, - {0xfa7b0, 0xfa7b7}, {0xfa7f7, 0xfa801}, {0xfa803, 0xfa805}, {0xfa807, 0xfa80a}, - {0xfa80c, 0xfa822}, {0xfa840, 0xfa873}, {0xfa882, 0xfa8b3}, {0xfa8f2, 0xfa8f7}, - {0xfa90a, 0xfa925}, {0xfa930, 0xfa946}, {0xfa960, 0xfa97c}, {0xfa984, 0xfa9b2}, - {0xfa9e0, 0xfa9e4}, {0xfa9e6, 0xfa9ef}, {0xfa9fa, 0xfa9fe}, {0xfaa00, 0xfaa28}, - {0xfaa40, 0xfaa42}, {0xfaa44, 0xfaa4b}, {0xfaa60, 0xfaa76}, {0xfaa7e, 0xfaaaf}, - {0xfaab9, 0xfaabd}, {0xfaadb, 0xfaadd}, {0xfaae0, 0xfaaea}, {0xfaaf2, 0xfaaf4}, - {0xfab01, 0xfab06}, {0xfab09, 0xfab0e}, {0xfab11, 0xfab16}, {0xfab20, 0xfab26}, - {0xfab28, 0xfab2e}, {0xfab30, 0xfab5a}, {0xfab5c, 0xfab65}, {0xfab70, 0xfabe2}, - {0xfac00, 0xfd7a3}, {0xfd7b0, 0xfd7c6}, {0xfd7cb, 0xfd7fb}, {0xff900, 0xffa6d}, - {0xffa70, 0xffad9}, {0xffb00, 0xffb06}, {0xffb13, 0xffb17}, {0xffb1f, 0xffb28}, - {0xffb2a, 0xffb36}, {0xffb38, 0xffb3c}, {0xffb46, 0xffbb1}, {0xffbd3, 0xffd3d}, - {0xffd50, 0xffd8f}, {0xffd92, 0xffdc7}, {0xffdf0, 0xffdfb}, {0xffe70, 0xffe74}, - {0xffe76, 0xffefc}, {0xfff21, 0xfff3a}, {0xfff41, 0xfff5a}, {0xfff66, 0xfffbe}, - {0xfffc2, 0xfffc7}, {0xfffca, 0xfffcf}, {0xfffd2, 0xfffd7}, {0xfffda, 0xfffdc}, - {0x100041, 0x10005a}, {0x100061, 0x10007a}, {0x1000c0, 0x1000d6}, {0x1000d8, 0x1000f6}, - {0x1000f8, 0x1002c1}, {0x1002c6, 0x1002d1}, {0x1002e0, 0x1002e4}, {0x100370, 0x100374}, - {0x10037a, 0x10037d}, {0x100388, 0x10038a}, {0x10038e, 0x1003a1}, {0x1003a3, 0x1003f5}, - {0x1003f7, 0x100481}, {0x10048a, 0x10052f}, {0x100531, 0x100556}, {0x100561, 0x100587}, - {0x1005d0, 0x1005ea}, {0x1005f0, 0x1005f2}, {0x100620, 0x10064a}, {0x100671, 0x1006d3}, - {0x1006fa, 0x1006fc}, {0x100712, 0x10072f}, {0x10074d, 0x1007a5}, {0x1007ca, 0x1007ea}, - {0x100800, 0x100815}, {0x100840, 0x100858}, {0x100860, 0x10086a}, {0x1008a0, 0x1008b4}, - {0x1008b6, 0x1008bd}, {0x100904, 0x100939}, {0x100958, 0x100961}, {0x100971, 0x100980}, - {0x100985, 0x10098c}, {0x100993, 0x1009a8}, {0x1009aa, 0x1009b0}, {0x1009b6, 0x1009b9}, - {0x1009df, 0x1009e1}, {0x100a05, 0x100a0a}, {0x100a13, 0x100a28}, {0x100a2a, 0x100a30}, - {0x100a59, 0x100a5c}, {0x100a72, 0x100a74}, {0x100a85, 0x100a8d}, {0x100a8f, 0x100a91}, - {0x100a93, 0x100aa8}, {0x100aaa, 0x100ab0}, {0x100ab5, 0x100ab9}, {0x100b05, 0x100b0c}, - {0x100b13, 0x100b28}, {0x100b2a, 0x100b30}, {0x100b35, 0x100b39}, {0x100b5f, 0x100b61}, - {0x100b85, 0x100b8a}, {0x100b8e, 0x100b90}, {0x100b92, 0x100b95}, {0x100ba8, 0x100baa}, - {0x100bae, 0x100bb9}, {0x100c05, 0x100c0c}, {0x100c0e, 0x100c10}, {0x100c12, 0x100c28}, - {0x100c2a, 0x100c39}, {0x100c58, 0x100c5a}, {0x100c85, 0x100c8c}, {0x100c8e, 0x100c90}, - {0x100c92, 0x100ca8}, {0x100caa, 0x100cb3}, {0x100cb5, 0x100cb9}, {0x100d05, 0x100d0c}, - {0x100d0e, 0x100d10}, {0x100d12, 0x100d3a}, {0x100d54, 0x100d56}, {0x100d5f, 0x100d61}, - {0x100d7a, 0x100d7f}, {0x100d85, 0x100d96}, {0x100d9a, 0x100db1}, {0x100db3, 0x100dbb}, - {0x100dc0, 0x100dc6}, {0x100e01, 0x100e30}, {0x100e40, 0x100e46}, {0x100e94, 0x100e97}, - {0x100e99, 0x100e9f}, {0x100ea1, 0x100ea3}, {0x100ead, 0x100eb0}, {0x100ec0, 0x100ec4}, - {0x100edc, 0x100edf}, {0x100f40, 0x100f47}, {0x100f49, 0x100f6c}, {0x100f88, 0x100f8c}, - {0x101000, 0x10102a}, {0x101050, 0x101055}, {0x10105a, 0x10105d}, {0x10106e, 0x101070}, - {0x101075, 0x101081}, {0x1010a0, 0x1010c5}, {0x1010d0, 0x1010fa}, {0x1010fc, 0x101248}, - {0x10124a, 0x10124d}, {0x101250, 0x101256}, {0x10125a, 0x10125d}, {0x101260, 0x101288}, - {0x10128a, 0x10128d}, {0x101290, 0x1012b0}, {0x1012b2, 0x1012b5}, {0x1012b8, 0x1012be}, - {0x1012c2, 0x1012c5}, {0x1012c8, 0x1012d6}, {0x1012d8, 0x101310}, {0x101312, 0x101315}, - {0x101318, 0x10135a}, {0x101380, 0x10138f}, {0x1013a0, 0x1013f5}, {0x1013f8, 0x1013fd}, - {0x101401, 0x10166c}, {0x10166f, 0x10167f}, {0x101681, 0x10169a}, {0x1016a0, 0x1016ea}, - {0x1016f1, 0x1016f8}, {0x101700, 0x10170c}, {0x10170e, 0x101711}, {0x101720, 0x101731}, - {0x101740, 0x101751}, {0x101760, 0x10176c}, {0x10176e, 0x101770}, {0x101780, 0x1017b3}, - {0x101820, 0x101877}, {0x101880, 0x101884}, {0x101887, 0x1018a8}, {0x1018b0, 0x1018f5}, - {0x101900, 0x10191e}, {0x101950, 0x10196d}, {0x101970, 0x101974}, {0x101980, 0x1019ab}, - {0x1019b0, 0x1019c9}, {0x101a00, 0x101a16}, {0x101a20, 0x101a54}, {0x101b05, 0x101b33}, - {0x101b45, 0x101b4b}, {0x101b83, 0x101ba0}, {0x101bba, 0x101be5}, {0x101c00, 0x101c23}, - {0x101c4d, 0x101c4f}, {0x101c5a, 0x101c7d}, {0x101c80, 0x101c88}, {0x101ce9, 0x101cec}, - {0x101cee, 0x101cf1}, {0x101d00, 0x101dbf}, {0x101e00, 0x101f15}, {0x101f18, 0x101f1d}, - {0x101f20, 0x101f45}, {0x101f48, 0x101f4d}, {0x101f50, 0x101f57}, {0x101f5f, 0x101f7d}, - {0x101f80, 0x101fb4}, {0x101fb6, 0x101fbc}, {0x101fc2, 0x101fc4}, {0x101fc6, 0x101fcc}, - {0x101fd0, 0x101fd3}, {0x101fd6, 0x101fdb}, {0x101fe0, 0x101fec}, {0x101ff2, 0x101ff4}, - {0x101ff6, 0x101ffc}, {0x102090, 0x10209c}, {0x10210a, 0x102113}, {0x102119, 0x10211d}, - {0x10212a, 0x10212d}, {0x10212f, 0x102139}, {0x10213c, 0x10213f}, {0x102145, 0x102149}, - {0x102c00, 0x102c2e}, {0x102c30, 0x102c5e}, {0x102c60, 0x102ce4}, {0x102ceb, 0x102cee}, - {0x102d00, 0x102d25}, {0x102d30, 0x102d67}, {0x102d80, 0x102d96}, {0x102da0, 0x102da6}, - {0x102da8, 0x102dae}, {0x102db0, 0x102db6}, {0x102db8, 0x102dbe}, {0x102dc0, 0x102dc6}, - {0x102dc8, 0x102dce}, {0x102dd0, 0x102dd6}, {0x102dd8, 0x102dde}, {0x103031, 0x103035}, - {0x103041, 0x103096}, {0x10309d, 0x10309f}, {0x1030a1, 0x1030fa}, {0x1030fc, 0x1030ff}, - {0x103105, 0x10312e}, {0x103131, 0x10318e}, {0x1031a0, 0x1031ba}, {0x1031f0, 0x1031ff}, - {0x103400, 0x104db5}, {0x104e00, 0x109fea}, {0x10a000, 0x10a48c}, {0x10a4d0, 0x10a4fd}, - {0x10a500, 0x10a60c}, {0x10a610, 0x10a61f}, {0x10a640, 0x10a66e}, {0x10a67f, 0x10a69d}, - {0x10a6a0, 0x10a6e5}, {0x10a717, 0x10a71f}, {0x10a722, 0x10a788}, {0x10a78b, 0x10a7ae}, - {0x10a7b0, 0x10a7b7}, {0x10a7f7, 0x10a801}, {0x10a803, 0x10a805}, {0x10a807, 0x10a80a}, - {0x10a80c, 0x10a822}, {0x10a840, 0x10a873}, {0x10a882, 0x10a8b3}, {0x10a8f2, 0x10a8f7}, - {0x10a90a, 0x10a925}, {0x10a930, 0x10a946}, {0x10a960, 0x10a97c}, {0x10a984, 0x10a9b2}, - {0x10a9e0, 0x10a9e4}, {0x10a9e6, 0x10a9ef}, {0x10a9fa, 0x10a9fe}, {0x10aa00, 0x10aa28}, - {0x10aa40, 0x10aa42}, {0x10aa44, 0x10aa4b}, {0x10aa60, 0x10aa76}, {0x10aa7e, 0x10aaaf}, - {0x10aab9, 0x10aabd}, {0x10aadb, 0x10aadd}, {0x10aae0, 0x10aaea}, {0x10aaf2, 0x10aaf4}, - {0x10ab01, 0x10ab06}, {0x10ab09, 0x10ab0e}, {0x10ab11, 0x10ab16}, {0x10ab20, 0x10ab26}, - {0x10ab28, 0x10ab2e}, {0x10ab30, 0x10ab5a}, {0x10ab5c, 0x10ab65}, {0x10ab70, 0x10abe2}, - {0x10ac00, 0x10d7a3}, {0x10d7b0, 0x10d7c6}, {0x10d7cb, 0x10d7fb}, {0x10f900, 0x10fa6d}, - {0x10fa70, 0x10fad9}, {0x10fb00, 0x10fb06}, {0x10fb13, 0x10fb17}, {0x10fb1f, 0x10fb28}, - {0x10fb2a, 0x10fb36}, {0x10fb38, 0x10fb3c}, {0x10fb46, 0x10fbb1}, {0x10fbd3, 0x10fd3d}, - {0x10fd50, 0x10fd8f}, {0x10fd92, 0x10fdc7}, {0x10fdf0, 0x10fdfb}, {0x10fe70, 0x10fe74}, - {0x10fe76, 0x10fefc}, {0x10ff21, 0x10ff3a}, {0x10ff41, 0x10ff5a}, {0x10ff66, 0x10ffbe}, - {0x10ffc2, 0x10ffc7}, {0x10ffca, 0x10ffcf}, {0x10ffd2, 0x10ffd7}, {0x10ffda, 0x10ffdc} + ,{0x10000, 0x1000b}, {0x1000d, 0x10026}, {0x10028, 0x1003a}, {0x1003f, 0x1004d}, + {0x10050, 0x1005d}, {0x10080, 0x100fa}, {0x10280, 0x1029c}, {0x102a0, 0x102d0}, + {0x10300, 0x1031f}, {0x1032d, 0x10340}, {0x10342, 0x10349}, {0x10350, 0x10375}, + {0x10380, 0x1039d}, {0x103a0, 0x103c3}, {0x103c8, 0x103cf}, {0x10400, 0x1049d}, + {0x104b0, 0x104d3}, {0x104d8, 0x104fb}, {0x10500, 0x10527}, {0x10530, 0x10563}, + {0x10600, 0x10736}, {0x10740, 0x10755}, {0x10760, 0x10767}, {0x10800, 0x10805}, + {0x1080a, 0x10835}, {0x1083f, 0x10855}, {0x10860, 0x10876}, {0x10880, 0x1089e}, + {0x108e0, 0x108f2}, {0x10900, 0x10915}, {0x10920, 0x10939}, {0x10980, 0x109b7}, + {0x10a10, 0x10a13}, {0x10a15, 0x10a17}, {0x10a19, 0x10a33}, {0x10a60, 0x10a7c}, + {0x10a80, 0x10a9c}, {0x10ac0, 0x10ac7}, {0x10ac9, 0x10ae4}, {0x10b00, 0x10b35}, + {0x10b40, 0x10b55}, {0x10b60, 0x10b72}, {0x10b80, 0x10b91}, {0x10c00, 0x10c48}, + {0x10c80, 0x10cb2}, {0x10cc0, 0x10cf2}, {0x11003, 0x11037}, {0x11083, 0x110af}, + {0x110d0, 0x110e8}, {0x11103, 0x11126}, {0x11150, 0x11172}, {0x11183, 0x111b2}, + {0x111c1, 0x111c4}, {0x11200, 0x11211}, {0x11213, 0x1122b}, {0x11280, 0x11286}, + {0x1128a, 0x1128d}, {0x1128f, 0x1129d}, {0x1129f, 0x112a8}, {0x112b0, 0x112de}, + {0x11305, 0x1130c}, {0x11313, 0x11328}, {0x1132a, 0x11330}, {0x11335, 0x11339}, + {0x1135d, 0x11361}, {0x11400, 0x11434}, {0x11447, 0x1144a}, {0x11480, 0x114af}, + {0x11580, 0x115ae}, {0x115d8, 0x115db}, {0x11600, 0x1162f}, {0x11680, 0x116aa}, + {0x11700, 0x11719}, {0x118a0, 0x118df}, {0x11a0b, 0x11a32}, {0x11a5c, 0x11a83}, + {0x11a86, 0x11a89}, {0x11ac0, 0x11af8}, {0x11c00, 0x11c08}, {0x11c0a, 0x11c2e}, + {0x11c72, 0x11c8f}, {0x11d00, 0x11d06}, {0x11d0b, 0x11d30}, {0x12000, 0x12399}, + {0x12480, 0x12543}, {0x13000, 0x1342e}, {0x14400, 0x14646}, {0x16800, 0x16a38}, + {0x16a40, 0x16a5e}, {0x16ad0, 0x16aed}, {0x16b00, 0x16b2f}, {0x16b40, 0x16b43}, + {0x16b63, 0x16b77}, {0x16b7d, 0x16b8f}, {0x16f00, 0x16f44}, {0x16f93, 0x16f9f}, + {0x17000, 0x187ec}, {0x18800, 0x18af2}, {0x1b000, 0x1b11e}, {0x1b170, 0x1b2fb}, + {0x1bc00, 0x1bc6a}, {0x1bc70, 0x1bc7c}, {0x1bc80, 0x1bc88}, {0x1bc90, 0x1bc99}, + {0x1d400, 0x1d454}, {0x1d456, 0x1d49c}, {0x1d4a9, 0x1d4ac}, {0x1d4ae, 0x1d4b9}, + {0x1d4bd, 0x1d4c3}, {0x1d4c5, 0x1d505}, {0x1d507, 0x1d50a}, {0x1d50d, 0x1d514}, + {0x1d516, 0x1d51c}, {0x1d51e, 0x1d539}, {0x1d53b, 0x1d53e}, {0x1d540, 0x1d544}, + {0x1d54a, 0x1d550}, {0x1d552, 0x1d6a5}, {0x1d6a8, 0x1d6c0}, {0x1d6c2, 0x1d6da}, + {0x1d6dc, 0x1d6fa}, {0x1d6fc, 0x1d714}, {0x1d716, 0x1d734}, {0x1d736, 0x1d74e}, + {0x1d750, 0x1d76e}, {0x1d770, 0x1d788}, {0x1d78a, 0x1d7a8}, {0x1d7aa, 0x1d7c2}, + {0x1d7c4, 0x1d7cb}, {0x1e800, 0x1e8c4}, {0x1e900, 0x1e943}, {0x1ee00, 0x1ee03}, + {0x1ee05, 0x1ee1f}, {0x1ee29, 0x1ee32}, {0x1ee34, 0x1ee37}, {0x1ee4d, 0x1ee4f}, + {0x1ee67, 0x1ee6a}, {0x1ee6c, 0x1ee72}, {0x1ee74, 0x1ee77}, {0x1ee79, 0x1ee7c}, + {0x1ee80, 0x1ee89}, {0x1ee8b, 0x1ee9b}, {0x1eea1, 0x1eea3}, {0x1eea5, 0x1eea9}, + {0x1eeab, 0x1eebb}, {0x20000, 0x2a6d6}, {0x2a700, 0x2b734}, {0x2b740, 0x2b81d}, + {0x2b820, 0x2cea1}, {0x2ceb0, 0x2ebe0}, {0x2f800, 0x2fa1d} #endif }; @@ -1265,294 +267,14 @@ static const chr alphaCharTable[] = { 0x303c, 0xa62a, 0xa62b, 0xa8fb, 0xa8fd, 0xa9cf, 0xaa7a, 0xaab1, 0xaab5, 0xaab6, 0xaac0, 0xaac2, 0xfb1d, 0xfb3e, 0xfb40, 0xfb41, 0xfb43, 0xfb44 #if TCL_UTF_MAX > 4 - ,0x100aa, 0x100b5, 0x100ba, 0x102ec, 0x102ee, 0x10376, 0x10377, 0x1037f, 0x10386, - 0x1038c, 0x10559, 0x1066e, 0x1066f, 0x106d5, 0x106e5, 0x106e6, 0x106ee, 0x106ef, - 0x106ff, 0x10710, 0x107b1, 0x107f4, 0x107f5, 0x107fa, 0x1081a, 0x10824, 0x10828, - 0x1093d, 0x10950, 0x1098f, 0x10990, 0x109b2, 0x109bd, 0x109ce, 0x109dc, 0x109dd, - 0x109f0, 0x109f1, 0x109fc, 0x10a0f, 0x10a10, 0x10a32, 0x10a33, 0x10a35, 0x10a36, - 0x10a38, 0x10a39, 0x10a5e, 0x10ab2, 0x10ab3, 0x10abd, 0x10ad0, 0x10ae0, 0x10ae1, - 0x10af9, 0x10b0f, 0x10b10, 0x10b32, 0x10b33, 0x10b3d, 0x10b5c, 0x10b5d, 0x10b71, - 0x10b83, 0x10b99, 0x10b9a, 0x10b9c, 0x10b9e, 0x10b9f, 0x10ba3, 0x10ba4, 0x10bd0, - 0x10c3d, 0x10c60, 0x10c61, 0x10c80, 0x10cbd, 0x10cde, 0x10ce0, 0x10ce1, 0x10cf1, - 0x10cf2, 0x10d3d, 0x10d4e, 0x10dbd, 0x10e32, 0x10e33, 0x10e81, 0x10e82, 0x10e84, - 0x10e87, 0x10e88, 0x10e8a, 0x10e8d, 0x10ea5, 0x10ea7, 0x10eaa, 0x10eab, 0x10eb2, - 0x10eb3, 0x10ebd, 0x10ec6, 0x10f00, 0x1103f, 0x11061, 0x11065, 0x11066, 0x1108e, - 0x110c7, 0x110cd, 0x11258, 0x112c0, 0x117d7, 0x117dc, 0x118aa, 0x11aa7, 0x11bae, - 0x11baf, 0x11cf5, 0x11cf6, 0x11f59, 0x11f5b, 0x11f5d, 0x11fbe, 0x12071, 0x1207f, - 0x12102, 0x12107, 0x12115, 0x12124, 0x12126, 0x12128, 0x1214e, 0x12183, 0x12184, - 0x12cf2, 0x12cf3, 0x12d27, 0x12d2d, 0x12d6f, 0x12e2f, 0x13005, 0x13006, 0x1303b, - 0x1303c, 0x1a62a, 0x1a62b, 0x1a8fb, 0x1a8fd, 0x1a9cf, 0x1aa7a, 0x1aab1, 0x1aab5, - 0x1aab6, 0x1aac0, 0x1aac2, 0x1fb1d, 0x1fb3e, 0x1fb40, 0x1fb41, 0x1fb43, 0x1fb44, - 0x200aa, 0x200b5, 0x200ba, 0x202ec, 0x202ee, 0x20376, 0x20377, 0x2037f, 0x20386, - 0x2038c, 0x20559, 0x2066e, 0x2066f, 0x206d5, 0x206e5, 0x206e6, 0x206ee, 0x206ef, - 0x206ff, 0x20710, 0x207b1, 0x207f4, 0x207f5, 0x207fa, 0x2081a, 0x20824, 0x20828, - 0x2093d, 0x20950, 0x2098f, 0x20990, 0x209b2, 0x209bd, 0x209ce, 0x209dc, 0x209dd, - 0x209f0, 0x209f1, 0x209fc, 0x20a0f, 0x20a10, 0x20a32, 0x20a33, 0x20a35, 0x20a36, - 0x20a38, 0x20a39, 0x20a5e, 0x20ab2, 0x20ab3, 0x20abd, 0x20ad0, 0x20ae0, 0x20ae1, - 0x20af9, 0x20b0f, 0x20b10, 0x20b32, 0x20b33, 0x20b3d, 0x20b5c, 0x20b5d, 0x20b71, - 0x20b83, 0x20b99, 0x20b9a, 0x20b9c, 0x20b9e, 0x20b9f, 0x20ba3, 0x20ba4, 0x20bd0, - 0x20c3d, 0x20c60, 0x20c61, 0x20c80, 0x20cbd, 0x20cde, 0x20ce0, 0x20ce1, 0x20cf1, - 0x20cf2, 0x20d3d, 0x20d4e, 0x20dbd, 0x20e32, 0x20e33, 0x20e81, 0x20e82, 0x20e84, - 0x20e87, 0x20e88, 0x20e8a, 0x20e8d, 0x20ea5, 0x20ea7, 0x20eaa, 0x20eab, 0x20eb2, - 0x20eb3, 0x20ebd, 0x20ec6, 0x20f00, 0x2103f, 0x21061, 0x21065, 0x21066, 0x2108e, - 0x210c7, 0x210cd, 0x21258, 0x212c0, 0x217d7, 0x217dc, 0x218aa, 0x21aa7, 0x21bae, - 0x21baf, 0x21cf5, 0x21cf6, 0x21f59, 0x21f5b, 0x21f5d, 0x21fbe, 0x22071, 0x2207f, - 0x22102, 0x22107, 0x22115, 0x22124, 0x22126, 0x22128, 0x2214e, 0x22183, 0x22184, - 0x22cf2, 0x22cf3, 0x22d27, 0x22d2d, 0x22d6f, 0x22e2f, 0x23005, 0x23006, 0x2303b, - 0x2303c, 0x2a62a, 0x2a62b, 0x2a8fb, 0x2a8fd, 0x2a9cf, 0x2aa7a, 0x2aab1, 0x2aab5, - 0x2aab6, 0x2aac0, 0x2aac2, 0x2fb1d, 0x2fb3e, 0x2fb40, 0x2fb41, 0x2fb43, 0x2fb44, - 0x300aa, 0x300b5, 0x300ba, 0x302ec, 0x302ee, 0x30376, 0x30377, 0x3037f, 0x30386, - 0x3038c, 0x30559, 0x3066e, 0x3066f, 0x306d5, 0x306e5, 0x306e6, 0x306ee, 0x306ef, - 0x306ff, 0x30710, 0x307b1, 0x307f4, 0x307f5, 0x307fa, 0x3081a, 0x30824, 0x30828, - 0x3093d, 0x30950, 0x3098f, 0x30990, 0x309b2, 0x309bd, 0x309ce, 0x309dc, 0x309dd, - 0x309f0, 0x309f1, 0x309fc, 0x30a0f, 0x30a10, 0x30a32, 0x30a33, 0x30a35, 0x30a36, - 0x30a38, 0x30a39, 0x30a5e, 0x30ab2, 0x30ab3, 0x30abd, 0x30ad0, 0x30ae0, 0x30ae1, - 0x30af9, 0x30b0f, 0x30b10, 0x30b32, 0x30b33, 0x30b3d, 0x30b5c, 0x30b5d, 0x30b71, - 0x30b83, 0x30b99, 0x30b9a, 0x30b9c, 0x30b9e, 0x30b9f, 0x30ba3, 0x30ba4, 0x30bd0, - 0x30c3d, 0x30c60, 0x30c61, 0x30c80, 0x30cbd, 0x30cde, 0x30ce0, 0x30ce1, 0x30cf1, - 0x30cf2, 0x30d3d, 0x30d4e, 0x30dbd, 0x30e32, 0x30e33, 0x30e81, 0x30e82, 0x30e84, - 0x30e87, 0x30e88, 0x30e8a, 0x30e8d, 0x30ea5, 0x30ea7, 0x30eaa, 0x30eab, 0x30eb2, - 0x30eb3, 0x30ebd, 0x30ec6, 0x30f00, 0x3103f, 0x31061, 0x31065, 0x31066, 0x3108e, - 0x310c7, 0x310cd, 0x31258, 0x312c0, 0x317d7, 0x317dc, 0x318aa, 0x31aa7, 0x31bae, - 0x31baf, 0x31cf5, 0x31cf6, 0x31f59, 0x31f5b, 0x31f5d, 0x31fbe, 0x32071, 0x3207f, - 0x32102, 0x32107, 0x32115, 0x32124, 0x32126, 0x32128, 0x3214e, 0x32183, 0x32184, - 0x32cf2, 0x32cf3, 0x32d27, 0x32d2d, 0x32d6f, 0x32e2f, 0x33005, 0x33006, 0x3303b, - 0x3303c, 0x3a62a, 0x3a62b, 0x3a8fb, 0x3a8fd, 0x3a9cf, 0x3aa7a, 0x3aab1, 0x3aab5, - 0x3aab6, 0x3aac0, 0x3aac2, 0x3fb1d, 0x3fb3e, 0x3fb40, 0x3fb41, 0x3fb43, 0x3fb44, - 0x400aa, 0x400b5, 0x400ba, 0x402ec, 0x402ee, 0x40376, 0x40377, 0x4037f, 0x40386, - 0x4038c, 0x40559, 0x4066e, 0x4066f, 0x406d5, 0x406e5, 0x406e6, 0x406ee, 0x406ef, - 0x406ff, 0x40710, 0x407b1, 0x407f4, 0x407f5, 0x407fa, 0x4081a, 0x40824, 0x40828, - 0x4093d, 0x40950, 0x4098f, 0x40990, 0x409b2, 0x409bd, 0x409ce, 0x409dc, 0x409dd, - 0x409f0, 0x409f1, 0x409fc, 0x40a0f, 0x40a10, 0x40a32, 0x40a33, 0x40a35, 0x40a36, - 0x40a38, 0x40a39, 0x40a5e, 0x40ab2, 0x40ab3, 0x40abd, 0x40ad0, 0x40ae0, 0x40ae1, - 0x40af9, 0x40b0f, 0x40b10, 0x40b32, 0x40b33, 0x40b3d, 0x40b5c, 0x40b5d, 0x40b71, - 0x40b83, 0x40b99, 0x40b9a, 0x40b9c, 0x40b9e, 0x40b9f, 0x40ba3, 0x40ba4, 0x40bd0, - 0x40c3d, 0x40c60, 0x40c61, 0x40c80, 0x40cbd, 0x40cde, 0x40ce0, 0x40ce1, 0x40cf1, - 0x40cf2, 0x40d3d, 0x40d4e, 0x40dbd, 0x40e32, 0x40e33, 0x40e81, 0x40e82, 0x40e84, - 0x40e87, 0x40e88, 0x40e8a, 0x40e8d, 0x40ea5, 0x40ea7, 0x40eaa, 0x40eab, 0x40eb2, - 0x40eb3, 0x40ebd, 0x40ec6, 0x40f00, 0x4103f, 0x41061, 0x41065, 0x41066, 0x4108e, - 0x410c7, 0x410cd, 0x41258, 0x412c0, 0x417d7, 0x417dc, 0x418aa, 0x41aa7, 0x41bae, - 0x41baf, 0x41cf5, 0x41cf6, 0x41f59, 0x41f5b, 0x41f5d, 0x41fbe, 0x42071, 0x4207f, - 0x42102, 0x42107, 0x42115, 0x42124, 0x42126, 0x42128, 0x4214e, 0x42183, 0x42184, - 0x42cf2, 0x42cf3, 0x42d27, 0x42d2d, 0x42d6f, 0x42e2f, 0x43005, 0x43006, 0x4303b, - 0x4303c, 0x4a62a, 0x4a62b, 0x4a8fb, 0x4a8fd, 0x4a9cf, 0x4aa7a, 0x4aab1, 0x4aab5, - 0x4aab6, 0x4aac0, 0x4aac2, 0x4fb1d, 0x4fb3e, 0x4fb40, 0x4fb41, 0x4fb43, 0x4fb44, - 0x500aa, 0x500b5, 0x500ba, 0x502ec, 0x502ee, 0x50376, 0x50377, 0x5037f, 0x50386, - 0x5038c, 0x50559, 0x5066e, 0x5066f, 0x506d5, 0x506e5, 0x506e6, 0x506ee, 0x506ef, - 0x506ff, 0x50710, 0x507b1, 0x507f4, 0x507f5, 0x507fa, 0x5081a, 0x50824, 0x50828, - 0x5093d, 0x50950, 0x5098f, 0x50990, 0x509b2, 0x509bd, 0x509ce, 0x509dc, 0x509dd, - 0x509f0, 0x509f1, 0x509fc, 0x50a0f, 0x50a10, 0x50a32, 0x50a33, 0x50a35, 0x50a36, - 0x50a38, 0x50a39, 0x50a5e, 0x50ab2, 0x50ab3, 0x50abd, 0x50ad0, 0x50ae0, 0x50ae1, - 0x50af9, 0x50b0f, 0x50b10, 0x50b32, 0x50b33, 0x50b3d, 0x50b5c, 0x50b5d, 0x50b71, - 0x50b83, 0x50b99, 0x50b9a, 0x50b9c, 0x50b9e, 0x50b9f, 0x50ba3, 0x50ba4, 0x50bd0, - 0x50c3d, 0x50c60, 0x50c61, 0x50c80, 0x50cbd, 0x50cde, 0x50ce0, 0x50ce1, 0x50cf1, - 0x50cf2, 0x50d3d, 0x50d4e, 0x50dbd, 0x50e32, 0x50e33, 0x50e81, 0x50e82, 0x50e84, - 0x50e87, 0x50e88, 0x50e8a, 0x50e8d, 0x50ea5, 0x50ea7, 0x50eaa, 0x50eab, 0x50eb2, - 0x50eb3, 0x50ebd, 0x50ec6, 0x50f00, 0x5103f, 0x51061, 0x51065, 0x51066, 0x5108e, - 0x510c7, 0x510cd, 0x51258, 0x512c0, 0x517d7, 0x517dc, 0x518aa, 0x51aa7, 0x51bae, - 0x51baf, 0x51cf5, 0x51cf6, 0x51f59, 0x51f5b, 0x51f5d, 0x51fbe, 0x52071, 0x5207f, - 0x52102, 0x52107, 0x52115, 0x52124, 0x52126, 0x52128, 0x5214e, 0x52183, 0x52184, - 0x52cf2, 0x52cf3, 0x52d27, 0x52d2d, 0x52d6f, 0x52e2f, 0x53005, 0x53006, 0x5303b, - 0x5303c, 0x5a62a, 0x5a62b, 0x5a8fb, 0x5a8fd, 0x5a9cf, 0x5aa7a, 0x5aab1, 0x5aab5, - 0x5aab6, 0x5aac0, 0x5aac2, 0x5fb1d, 0x5fb3e, 0x5fb40, 0x5fb41, 0x5fb43, 0x5fb44, - 0x600aa, 0x600b5, 0x600ba, 0x602ec, 0x602ee, 0x60376, 0x60377, 0x6037f, 0x60386, - 0x6038c, 0x60559, 0x6066e, 0x6066f, 0x606d5, 0x606e5, 0x606e6, 0x606ee, 0x606ef, - 0x606ff, 0x60710, 0x607b1, 0x607f4, 0x607f5, 0x607fa, 0x6081a, 0x60824, 0x60828, - 0x6093d, 0x60950, 0x6098f, 0x60990, 0x609b2, 0x609bd, 0x609ce, 0x609dc, 0x609dd, - 0x609f0, 0x609f1, 0x609fc, 0x60a0f, 0x60a10, 0x60a32, 0x60a33, 0x60a35, 0x60a36, - 0x60a38, 0x60a39, 0x60a5e, 0x60ab2, 0x60ab3, 0x60abd, 0x60ad0, 0x60ae0, 0x60ae1, - 0x60af9, 0x60b0f, 0x60b10, 0x60b32, 0x60b33, 0x60b3d, 0x60b5c, 0x60b5d, 0x60b71, - 0x60b83, 0x60b99, 0x60b9a, 0x60b9c, 0x60b9e, 0x60b9f, 0x60ba3, 0x60ba4, 0x60bd0, - 0x60c3d, 0x60c60, 0x60c61, 0x60c80, 0x60cbd, 0x60cde, 0x60ce0, 0x60ce1, 0x60cf1, - 0x60cf2, 0x60d3d, 0x60d4e, 0x60dbd, 0x60e32, 0x60e33, 0x60e81, 0x60e82, 0x60e84, - 0x60e87, 0x60e88, 0x60e8a, 0x60e8d, 0x60ea5, 0x60ea7, 0x60eaa, 0x60eab, 0x60eb2, - 0x60eb3, 0x60ebd, 0x60ec6, 0x60f00, 0x6103f, 0x61061, 0x61065, 0x61066, 0x6108e, - 0x610c7, 0x610cd, 0x61258, 0x612c0, 0x617d7, 0x617dc, 0x618aa, 0x61aa7, 0x61bae, - 0x61baf, 0x61cf5, 0x61cf6, 0x61f59, 0x61f5b, 0x61f5d, 0x61fbe, 0x62071, 0x6207f, - 0x62102, 0x62107, 0x62115, 0x62124, 0x62126, 0x62128, 0x6214e, 0x62183, 0x62184, - 0x62cf2, 0x62cf3, 0x62d27, 0x62d2d, 0x62d6f, 0x62e2f, 0x63005, 0x63006, 0x6303b, - 0x6303c, 0x6a62a, 0x6a62b, 0x6a8fb, 0x6a8fd, 0x6a9cf, 0x6aa7a, 0x6aab1, 0x6aab5, - 0x6aab6, 0x6aac0, 0x6aac2, 0x6fb1d, 0x6fb3e, 0x6fb40, 0x6fb41, 0x6fb43, 0x6fb44, - 0x700aa, 0x700b5, 0x700ba, 0x702ec, 0x702ee, 0x70376, 0x70377, 0x7037f, 0x70386, - 0x7038c, 0x70559, 0x7066e, 0x7066f, 0x706d5, 0x706e5, 0x706e6, 0x706ee, 0x706ef, - 0x706ff, 0x70710, 0x707b1, 0x707f4, 0x707f5, 0x707fa, 0x7081a, 0x70824, 0x70828, - 0x7093d, 0x70950, 0x7098f, 0x70990, 0x709b2, 0x709bd, 0x709ce, 0x709dc, 0x709dd, - 0x709f0, 0x709f1, 0x709fc, 0x70a0f, 0x70a10, 0x70a32, 0x70a33, 0x70a35, 0x70a36, - 0x70a38, 0x70a39, 0x70a5e, 0x70ab2, 0x70ab3, 0x70abd, 0x70ad0, 0x70ae0, 0x70ae1, - 0x70af9, 0x70b0f, 0x70b10, 0x70b32, 0x70b33, 0x70b3d, 0x70b5c, 0x70b5d, 0x70b71, - 0x70b83, 0x70b99, 0x70b9a, 0x70b9c, 0x70b9e, 0x70b9f, 0x70ba3, 0x70ba4, 0x70bd0, - 0x70c3d, 0x70c60, 0x70c61, 0x70c80, 0x70cbd, 0x70cde, 0x70ce0, 0x70ce1, 0x70cf1, - 0x70cf2, 0x70d3d, 0x70d4e, 0x70dbd, 0x70e32, 0x70e33, 0x70e81, 0x70e82, 0x70e84, - 0x70e87, 0x70e88, 0x70e8a, 0x70e8d, 0x70ea5, 0x70ea7, 0x70eaa, 0x70eab, 0x70eb2, - 0x70eb3, 0x70ebd, 0x70ec6, 0x70f00, 0x7103f, 0x71061, 0x71065, 0x71066, 0x7108e, - 0x710c7, 0x710cd, 0x71258, 0x712c0, 0x717d7, 0x717dc, 0x718aa, 0x71aa7, 0x71bae, - 0x71baf, 0x71cf5, 0x71cf6, 0x71f59, 0x71f5b, 0x71f5d, 0x71fbe, 0x72071, 0x7207f, - 0x72102, 0x72107, 0x72115, 0x72124, 0x72126, 0x72128, 0x7214e, 0x72183, 0x72184, - 0x72cf2, 0x72cf3, 0x72d27, 0x72d2d, 0x72d6f, 0x72e2f, 0x73005, 0x73006, 0x7303b, - 0x7303c, 0x7a62a, 0x7a62b, 0x7a8fb, 0x7a8fd, 0x7a9cf, 0x7aa7a, 0x7aab1, 0x7aab5, - 0x7aab6, 0x7aac0, 0x7aac2, 0x7fb1d, 0x7fb3e, 0x7fb40, 0x7fb41, 0x7fb43, 0x7fb44, - 0x800aa, 0x800b5, 0x800ba, 0x802ec, 0x802ee, 0x80376, 0x80377, 0x8037f, 0x80386, - 0x8038c, 0x80559, 0x8066e, 0x8066f, 0x806d5, 0x806e5, 0x806e6, 0x806ee, 0x806ef, - 0x806ff, 0x80710, 0x807b1, 0x807f4, 0x807f5, 0x807fa, 0x8081a, 0x80824, 0x80828, - 0x8093d, 0x80950, 0x8098f, 0x80990, 0x809b2, 0x809bd, 0x809ce, 0x809dc, 0x809dd, - 0x809f0, 0x809f1, 0x809fc, 0x80a0f, 0x80a10, 0x80a32, 0x80a33, 0x80a35, 0x80a36, - 0x80a38, 0x80a39, 0x80a5e, 0x80ab2, 0x80ab3, 0x80abd, 0x80ad0, 0x80ae0, 0x80ae1, - 0x80af9, 0x80b0f, 0x80b10, 0x80b32, 0x80b33, 0x80b3d, 0x80b5c, 0x80b5d, 0x80b71, - 0x80b83, 0x80b99, 0x80b9a, 0x80b9c, 0x80b9e, 0x80b9f, 0x80ba3, 0x80ba4, 0x80bd0, - 0x80c3d, 0x80c60, 0x80c61, 0x80c80, 0x80cbd, 0x80cde, 0x80ce0, 0x80ce1, 0x80cf1, - 0x80cf2, 0x80d3d, 0x80d4e, 0x80dbd, 0x80e32, 0x80e33, 0x80e81, 0x80e82, 0x80e84, - 0x80e87, 0x80e88, 0x80e8a, 0x80e8d, 0x80ea5, 0x80ea7, 0x80eaa, 0x80eab, 0x80eb2, - 0x80eb3, 0x80ebd, 0x80ec6, 0x80f00, 0x8103f, 0x81061, 0x81065, 0x81066, 0x8108e, - 0x810c7, 0x810cd, 0x81258, 0x812c0, 0x817d7, 0x817dc, 0x818aa, 0x81aa7, 0x81bae, - 0x81baf, 0x81cf5, 0x81cf6, 0x81f59, 0x81f5b, 0x81f5d, 0x81fbe, 0x82071, 0x8207f, - 0x82102, 0x82107, 0x82115, 0x82124, 0x82126, 0x82128, 0x8214e, 0x82183, 0x82184, - 0x82cf2, 0x82cf3, 0x82d27, 0x82d2d, 0x82d6f, 0x82e2f, 0x83005, 0x83006, 0x8303b, - 0x8303c, 0x8a62a, 0x8a62b, 0x8a8fb, 0x8a8fd, 0x8a9cf, 0x8aa7a, 0x8aab1, 0x8aab5, - 0x8aab6, 0x8aac0, 0x8aac2, 0x8fb1d, 0x8fb3e, 0x8fb40, 0x8fb41, 0x8fb43, 0x8fb44, - 0x900aa, 0x900b5, 0x900ba, 0x902ec, 0x902ee, 0x90376, 0x90377, 0x9037f, 0x90386, - 0x9038c, 0x90559, 0x9066e, 0x9066f, 0x906d5, 0x906e5, 0x906e6, 0x906ee, 0x906ef, - 0x906ff, 0x90710, 0x907b1, 0x907f4, 0x907f5, 0x907fa, 0x9081a, 0x90824, 0x90828, - 0x9093d, 0x90950, 0x9098f, 0x90990, 0x909b2, 0x909bd, 0x909ce, 0x909dc, 0x909dd, - 0x909f0, 0x909f1, 0x909fc, 0x90a0f, 0x90a10, 0x90a32, 0x90a33, 0x90a35, 0x90a36, - 0x90a38, 0x90a39, 0x90a5e, 0x90ab2, 0x90ab3, 0x90abd, 0x90ad0, 0x90ae0, 0x90ae1, - 0x90af9, 0x90b0f, 0x90b10, 0x90b32, 0x90b33, 0x90b3d, 0x90b5c, 0x90b5d, 0x90b71, - 0x90b83, 0x90b99, 0x90b9a, 0x90b9c, 0x90b9e, 0x90b9f, 0x90ba3, 0x90ba4, 0x90bd0, - 0x90c3d, 0x90c60, 0x90c61, 0x90c80, 0x90cbd, 0x90cde, 0x90ce0, 0x90ce1, 0x90cf1, - 0x90cf2, 0x90d3d, 0x90d4e, 0x90dbd, 0x90e32, 0x90e33, 0x90e81, 0x90e82, 0x90e84, - 0x90e87, 0x90e88, 0x90e8a, 0x90e8d, 0x90ea5, 0x90ea7, 0x90eaa, 0x90eab, 0x90eb2, - 0x90eb3, 0x90ebd, 0x90ec6, 0x90f00, 0x9103f, 0x91061, 0x91065, 0x91066, 0x9108e, - 0x910c7, 0x910cd, 0x91258, 0x912c0, 0x917d7, 0x917dc, 0x918aa, 0x91aa7, 0x91bae, - 0x91baf, 0x91cf5, 0x91cf6, 0x91f59, 0x91f5b, 0x91f5d, 0x91fbe, 0x92071, 0x9207f, - 0x92102, 0x92107, 0x92115, 0x92124, 0x92126, 0x92128, 0x9214e, 0x92183, 0x92184, - 0x92cf2, 0x92cf3, 0x92d27, 0x92d2d, 0x92d6f, 0x92e2f, 0x93005, 0x93006, 0x9303b, - 0x9303c, 0x9a62a, 0x9a62b, 0x9a8fb, 0x9a8fd, 0x9a9cf, 0x9aa7a, 0x9aab1, 0x9aab5, - 0x9aab6, 0x9aac0, 0x9aac2, 0x9fb1d, 0x9fb3e, 0x9fb40, 0x9fb41, 0x9fb43, 0x9fb44, - 0xa00aa, 0xa00b5, 0xa00ba, 0xa02ec, 0xa02ee, 0xa0376, 0xa0377, 0xa037f, 0xa0386, - 0xa038c, 0xa0559, 0xa066e, 0xa066f, 0xa06d5, 0xa06e5, 0xa06e6, 0xa06ee, 0xa06ef, - 0xa06ff, 0xa0710, 0xa07b1, 0xa07f4, 0xa07f5, 0xa07fa, 0xa081a, 0xa0824, 0xa0828, - 0xa093d, 0xa0950, 0xa098f, 0xa0990, 0xa09b2, 0xa09bd, 0xa09ce, 0xa09dc, 0xa09dd, - 0xa09f0, 0xa09f1, 0xa09fc, 0xa0a0f, 0xa0a10, 0xa0a32, 0xa0a33, 0xa0a35, 0xa0a36, - 0xa0a38, 0xa0a39, 0xa0a5e, 0xa0ab2, 0xa0ab3, 0xa0abd, 0xa0ad0, 0xa0ae0, 0xa0ae1, - 0xa0af9, 0xa0b0f, 0xa0b10, 0xa0b32, 0xa0b33, 0xa0b3d, 0xa0b5c, 0xa0b5d, 0xa0b71, - 0xa0b83, 0xa0b99, 0xa0b9a, 0xa0b9c, 0xa0b9e, 0xa0b9f, 0xa0ba3, 0xa0ba4, 0xa0bd0, - 0xa0c3d, 0xa0c60, 0xa0c61, 0xa0c80, 0xa0cbd, 0xa0cde, 0xa0ce0, 0xa0ce1, 0xa0cf1, - 0xa0cf2, 0xa0d3d, 0xa0d4e, 0xa0dbd, 0xa0e32, 0xa0e33, 0xa0e81, 0xa0e82, 0xa0e84, - 0xa0e87, 0xa0e88, 0xa0e8a, 0xa0e8d, 0xa0ea5, 0xa0ea7, 0xa0eaa, 0xa0eab, 0xa0eb2, - 0xa0eb3, 0xa0ebd, 0xa0ec6, 0xa0f00, 0xa103f, 0xa1061, 0xa1065, 0xa1066, 0xa108e, - 0xa10c7, 0xa10cd, 0xa1258, 0xa12c0, 0xa17d7, 0xa17dc, 0xa18aa, 0xa1aa7, 0xa1bae, - 0xa1baf, 0xa1cf5, 0xa1cf6, 0xa1f59, 0xa1f5b, 0xa1f5d, 0xa1fbe, 0xa2071, 0xa207f, - 0xa2102, 0xa2107, 0xa2115, 0xa2124, 0xa2126, 0xa2128, 0xa214e, 0xa2183, 0xa2184, - 0xa2cf2, 0xa2cf3, 0xa2d27, 0xa2d2d, 0xa2d6f, 0xa2e2f, 0xa3005, 0xa3006, 0xa303b, - 0xa303c, 0xaa62a, 0xaa62b, 0xaa8fb, 0xaa8fd, 0xaa9cf, 0xaaa7a, 0xaaab1, 0xaaab5, - 0xaaab6, 0xaaac0, 0xaaac2, 0xafb1d, 0xafb3e, 0xafb40, 0xafb41, 0xafb43, 0xafb44, - 0xb00aa, 0xb00b5, 0xb00ba, 0xb02ec, 0xb02ee, 0xb0376, 0xb0377, 0xb037f, 0xb0386, - 0xb038c, 0xb0559, 0xb066e, 0xb066f, 0xb06d5, 0xb06e5, 0xb06e6, 0xb06ee, 0xb06ef, - 0xb06ff, 0xb0710, 0xb07b1, 0xb07f4, 0xb07f5, 0xb07fa, 0xb081a, 0xb0824, 0xb0828, - 0xb093d, 0xb0950, 0xb098f, 0xb0990, 0xb09b2, 0xb09bd, 0xb09ce, 0xb09dc, 0xb09dd, - 0xb09f0, 0xb09f1, 0xb09fc, 0xb0a0f, 0xb0a10, 0xb0a32, 0xb0a33, 0xb0a35, 0xb0a36, - 0xb0a38, 0xb0a39, 0xb0a5e, 0xb0ab2, 0xb0ab3, 0xb0abd, 0xb0ad0, 0xb0ae0, 0xb0ae1, - 0xb0af9, 0xb0b0f, 0xb0b10, 0xb0b32, 0xb0b33, 0xb0b3d, 0xb0b5c, 0xb0b5d, 0xb0b71, - 0xb0b83, 0xb0b99, 0xb0b9a, 0xb0b9c, 0xb0b9e, 0xb0b9f, 0xb0ba3, 0xb0ba4, 0xb0bd0, - 0xb0c3d, 0xb0c60, 0xb0c61, 0xb0c80, 0xb0cbd, 0xb0cde, 0xb0ce0, 0xb0ce1, 0xb0cf1, - 0xb0cf2, 0xb0d3d, 0xb0d4e, 0xb0dbd, 0xb0e32, 0xb0e33, 0xb0e81, 0xb0e82, 0xb0e84, - 0xb0e87, 0xb0e88, 0xb0e8a, 0xb0e8d, 0xb0ea5, 0xb0ea7, 0xb0eaa, 0xb0eab, 0xb0eb2, - 0xb0eb3, 0xb0ebd, 0xb0ec6, 0xb0f00, 0xb103f, 0xb1061, 0xb1065, 0xb1066, 0xb108e, - 0xb10c7, 0xb10cd, 0xb1258, 0xb12c0, 0xb17d7, 0xb17dc, 0xb18aa, 0xb1aa7, 0xb1bae, - 0xb1baf, 0xb1cf5, 0xb1cf6, 0xb1f59, 0xb1f5b, 0xb1f5d, 0xb1fbe, 0xb2071, 0xb207f, - 0xb2102, 0xb2107, 0xb2115, 0xb2124, 0xb2126, 0xb2128, 0xb214e, 0xb2183, 0xb2184, - 0xb2cf2, 0xb2cf3, 0xb2d27, 0xb2d2d, 0xb2d6f, 0xb2e2f, 0xb3005, 0xb3006, 0xb303b, - 0xb303c, 0xba62a, 0xba62b, 0xba8fb, 0xba8fd, 0xba9cf, 0xbaa7a, 0xbaab1, 0xbaab5, - 0xbaab6, 0xbaac0, 0xbaac2, 0xbfb1d, 0xbfb3e, 0xbfb40, 0xbfb41, 0xbfb43, 0xbfb44, - 0xc00aa, 0xc00b5, 0xc00ba, 0xc02ec, 0xc02ee, 0xc0376, 0xc0377, 0xc037f, 0xc0386, - 0xc038c, 0xc0559, 0xc066e, 0xc066f, 0xc06d5, 0xc06e5, 0xc06e6, 0xc06ee, 0xc06ef, - 0xc06ff, 0xc0710, 0xc07b1, 0xc07f4, 0xc07f5, 0xc07fa, 0xc081a, 0xc0824, 0xc0828, - 0xc093d, 0xc0950, 0xc098f, 0xc0990, 0xc09b2, 0xc09bd, 0xc09ce, 0xc09dc, 0xc09dd, - 0xc09f0, 0xc09f1, 0xc09fc, 0xc0a0f, 0xc0a10, 0xc0a32, 0xc0a33, 0xc0a35, 0xc0a36, - 0xc0a38, 0xc0a39, 0xc0a5e, 0xc0ab2, 0xc0ab3, 0xc0abd, 0xc0ad0, 0xc0ae0, 0xc0ae1, - 0xc0af9, 0xc0b0f, 0xc0b10, 0xc0b32, 0xc0b33, 0xc0b3d, 0xc0b5c, 0xc0b5d, 0xc0b71, - 0xc0b83, 0xc0b99, 0xc0b9a, 0xc0b9c, 0xc0b9e, 0xc0b9f, 0xc0ba3, 0xc0ba4, 0xc0bd0, - 0xc0c3d, 0xc0c60, 0xc0c61, 0xc0c80, 0xc0cbd, 0xc0cde, 0xc0ce0, 0xc0ce1, 0xc0cf1, - 0xc0cf2, 0xc0d3d, 0xc0d4e, 0xc0dbd, 0xc0e32, 0xc0e33, 0xc0e81, 0xc0e82, 0xc0e84, - 0xc0e87, 0xc0e88, 0xc0e8a, 0xc0e8d, 0xc0ea5, 0xc0ea7, 0xc0eaa, 0xc0eab, 0xc0eb2, - 0xc0eb3, 0xc0ebd, 0xc0ec6, 0xc0f00, 0xc103f, 0xc1061, 0xc1065, 0xc1066, 0xc108e, - 0xc10c7, 0xc10cd, 0xc1258, 0xc12c0, 0xc17d7, 0xc17dc, 0xc18aa, 0xc1aa7, 0xc1bae, - 0xc1baf, 0xc1cf5, 0xc1cf6, 0xc1f59, 0xc1f5b, 0xc1f5d, 0xc1fbe, 0xc2071, 0xc207f, - 0xc2102, 0xc2107, 0xc2115, 0xc2124, 0xc2126, 0xc2128, 0xc214e, 0xc2183, 0xc2184, - 0xc2cf2, 0xc2cf3, 0xc2d27, 0xc2d2d, 0xc2d6f, 0xc2e2f, 0xc3005, 0xc3006, 0xc303b, - 0xc303c, 0xca62a, 0xca62b, 0xca8fb, 0xca8fd, 0xca9cf, 0xcaa7a, 0xcaab1, 0xcaab5, - 0xcaab6, 0xcaac0, 0xcaac2, 0xcfb1d, 0xcfb3e, 0xcfb40, 0xcfb41, 0xcfb43, 0xcfb44, - 0xd00aa, 0xd00b5, 0xd00ba, 0xd02ec, 0xd02ee, 0xd0376, 0xd0377, 0xd037f, 0xd0386, - 0xd038c, 0xd0559, 0xd066e, 0xd066f, 0xd06d5, 0xd06e5, 0xd06e6, 0xd06ee, 0xd06ef, - 0xd06ff, 0xd0710, 0xd07b1, 0xd07f4, 0xd07f5, 0xd07fa, 0xd081a, 0xd0824, 0xd0828, - 0xd093d, 0xd0950, 0xd098f, 0xd0990, 0xd09b2, 0xd09bd, 0xd09ce, 0xd09dc, 0xd09dd, - 0xd09f0, 0xd09f1, 0xd09fc, 0xd0a0f, 0xd0a10, 0xd0a32, 0xd0a33, 0xd0a35, 0xd0a36, - 0xd0a38, 0xd0a39, 0xd0a5e, 0xd0ab2, 0xd0ab3, 0xd0abd, 0xd0ad0, 0xd0ae0, 0xd0ae1, - 0xd0af9, 0xd0b0f, 0xd0b10, 0xd0b32, 0xd0b33, 0xd0b3d, 0xd0b5c, 0xd0b5d, 0xd0b71, - 0xd0b83, 0xd0b99, 0xd0b9a, 0xd0b9c, 0xd0b9e, 0xd0b9f, 0xd0ba3, 0xd0ba4, 0xd0bd0, - 0xd0c3d, 0xd0c60, 0xd0c61, 0xd0c80, 0xd0cbd, 0xd0cde, 0xd0ce0, 0xd0ce1, 0xd0cf1, - 0xd0cf2, 0xd0d3d, 0xd0d4e, 0xd0dbd, 0xd0e32, 0xd0e33, 0xd0e81, 0xd0e82, 0xd0e84, - 0xd0e87, 0xd0e88, 0xd0e8a, 0xd0e8d, 0xd0ea5, 0xd0ea7, 0xd0eaa, 0xd0eab, 0xd0eb2, - 0xd0eb3, 0xd0ebd, 0xd0ec6, 0xd0f00, 0xd103f, 0xd1061, 0xd1065, 0xd1066, 0xd108e, - 0xd10c7, 0xd10cd, 0xd1258, 0xd12c0, 0xd17d7, 0xd17dc, 0xd18aa, 0xd1aa7, 0xd1bae, - 0xd1baf, 0xd1cf5, 0xd1cf6, 0xd1f59, 0xd1f5b, 0xd1f5d, 0xd1fbe, 0xd2071, 0xd207f, - 0xd2102, 0xd2107, 0xd2115, 0xd2124, 0xd2126, 0xd2128, 0xd214e, 0xd2183, 0xd2184, - 0xd2cf2, 0xd2cf3, 0xd2d27, 0xd2d2d, 0xd2d6f, 0xd2e2f, 0xd3005, 0xd3006, 0xd303b, - 0xd303c, 0xda62a, 0xda62b, 0xda8fb, 0xda8fd, 0xda9cf, 0xdaa7a, 0xdaab1, 0xdaab5, - 0xdaab6, 0xdaac0, 0xdaac2, 0xdfb1d, 0xdfb3e, 0xdfb40, 0xdfb41, 0xdfb43, 0xdfb44, - 0xe00aa, 0xe00b5, 0xe00ba, 0xe02ec, 0xe02ee, 0xe0376, 0xe0377, 0xe037f, 0xe0386, - 0xe038c, 0xe0559, 0xe066e, 0xe066f, 0xe06d5, 0xe06e5, 0xe06e6, 0xe06ee, 0xe06ef, - 0xe06ff, 0xe0710, 0xe07b1, 0xe07f4, 0xe07f5, 0xe07fa, 0xe081a, 0xe0824, 0xe0828, - 0xe093d, 0xe0950, 0xe098f, 0xe0990, 0xe09b2, 0xe09bd, 0xe09ce, 0xe09dc, 0xe09dd, - 0xe09f0, 0xe09f1, 0xe09fc, 0xe0a0f, 0xe0a10, 0xe0a32, 0xe0a33, 0xe0a35, 0xe0a36, - 0xe0a38, 0xe0a39, 0xe0a5e, 0xe0ab2, 0xe0ab3, 0xe0abd, 0xe0ad0, 0xe0ae0, 0xe0ae1, - 0xe0af9, 0xe0b0f, 0xe0b10, 0xe0b32, 0xe0b33, 0xe0b3d, 0xe0b5c, 0xe0b5d, 0xe0b71, - 0xe0b83, 0xe0b99, 0xe0b9a, 0xe0b9c, 0xe0b9e, 0xe0b9f, 0xe0ba3, 0xe0ba4, 0xe0bd0, - 0xe0c3d, 0xe0c60, 0xe0c61, 0xe0c80, 0xe0cbd, 0xe0cde, 0xe0ce0, 0xe0ce1, 0xe0cf1, - 0xe0cf2, 0xe0d3d, 0xe0d4e, 0xe0dbd, 0xe0e32, 0xe0e33, 0xe0e81, 0xe0e82, 0xe0e84, - 0xe0e87, 0xe0e88, 0xe0e8a, 0xe0e8d, 0xe0ea5, 0xe0ea7, 0xe0eaa, 0xe0eab, 0xe0eb2, - 0xe0eb3, 0xe0ebd, 0xe0ec6, 0xe0f00, 0xe103f, 0xe1061, 0xe1065, 0xe1066, 0xe108e, - 0xe10c7, 0xe10cd, 0xe1258, 0xe12c0, 0xe17d7, 0xe17dc, 0xe18aa, 0xe1aa7, 0xe1bae, - 0xe1baf, 0xe1cf5, 0xe1cf6, 0xe1f59, 0xe1f5b, 0xe1f5d, 0xe1fbe, 0xe2071, 0xe207f, - 0xe2102, 0xe2107, 0xe2115, 0xe2124, 0xe2126, 0xe2128, 0xe214e, 0xe2183, 0xe2184, - 0xe2cf2, 0xe2cf3, 0xe2d27, 0xe2d2d, 0xe2d6f, 0xe2e2f, 0xe3005, 0xe3006, 0xe303b, - 0xe303c, 0xea62a, 0xea62b, 0xea8fb, 0xea8fd, 0xea9cf, 0xeaa7a, 0xeaab1, 0xeaab5, - 0xeaab6, 0xeaac0, 0xeaac2, 0xefb1d, 0xefb3e, 0xefb40, 0xefb41, 0xefb43, 0xefb44, - 0xf00aa, 0xf00b5, 0xf00ba, 0xf02ec, 0xf02ee, 0xf0376, 0xf0377, 0xf037f, 0xf0386, - 0xf038c, 0xf0559, 0xf066e, 0xf066f, 0xf06d5, 0xf06e5, 0xf06e6, 0xf06ee, 0xf06ef, - 0xf06ff, 0xf0710, 0xf07b1, 0xf07f4, 0xf07f5, 0xf07fa, 0xf081a, 0xf0824, 0xf0828, - 0xf093d, 0xf0950, 0xf098f, 0xf0990, 0xf09b2, 0xf09bd, 0xf09ce, 0xf09dc, 0xf09dd, - 0xf09f0, 0xf09f1, 0xf09fc, 0xf0a0f, 0xf0a10, 0xf0a32, 0xf0a33, 0xf0a35, 0xf0a36, - 0xf0a38, 0xf0a39, 0xf0a5e, 0xf0ab2, 0xf0ab3, 0xf0abd, 0xf0ad0, 0xf0ae0, 0xf0ae1, - 0xf0af9, 0xf0b0f, 0xf0b10, 0xf0b32, 0xf0b33, 0xf0b3d, 0xf0b5c, 0xf0b5d, 0xf0b71, - 0xf0b83, 0xf0b99, 0xf0b9a, 0xf0b9c, 0xf0b9e, 0xf0b9f, 0xf0ba3, 0xf0ba4, 0xf0bd0, - 0xf0c3d, 0xf0c60, 0xf0c61, 0xf0c80, 0xf0cbd, 0xf0cde, 0xf0ce0, 0xf0ce1, 0xf0cf1, - 0xf0cf2, 0xf0d3d, 0xf0d4e, 0xf0dbd, 0xf0e32, 0xf0e33, 0xf0e81, 0xf0e82, 0xf0e84, - 0xf0e87, 0xf0e88, 0xf0e8a, 0xf0e8d, 0xf0ea5, 0xf0ea7, 0xf0eaa, 0xf0eab, 0xf0eb2, - 0xf0eb3, 0xf0ebd, 0xf0ec6, 0xf0f00, 0xf103f, 0xf1061, 0xf1065, 0xf1066, 0xf108e, - 0xf10c7, 0xf10cd, 0xf1258, 0xf12c0, 0xf17d7, 0xf17dc, 0xf18aa, 0xf1aa7, 0xf1bae, - 0xf1baf, 0xf1cf5, 0xf1cf6, 0xf1f59, 0xf1f5b, 0xf1f5d, 0xf1fbe, 0xf2071, 0xf207f, - 0xf2102, 0xf2107, 0xf2115, 0xf2124, 0xf2126, 0xf2128, 0xf214e, 0xf2183, 0xf2184, - 0xf2cf2, 0xf2cf3, 0xf2d27, 0xf2d2d, 0xf2d6f, 0xf2e2f, 0xf3005, 0xf3006, 0xf303b, - 0xf303c, 0xfa62a, 0xfa62b, 0xfa8fb, 0xfa8fd, 0xfa9cf, 0xfaa7a, 0xfaab1, 0xfaab5, - 0xfaab6, 0xfaac0, 0xfaac2, 0xffb1d, 0xffb3e, 0xffb40, 0xffb41, 0xffb43, 0xffb44, - 0x1000aa, 0x1000b5, 0x1000ba, 0x1002ec, 0x1002ee, 0x100376, 0x100377, 0x10037f, 0x100386, - 0x10038c, 0x100559, 0x10066e, 0x10066f, 0x1006d5, 0x1006e5, 0x1006e6, 0x1006ee, 0x1006ef, - 0x1006ff, 0x100710, 0x1007b1, 0x1007f4, 0x1007f5, 0x1007fa, 0x10081a, 0x100824, 0x100828, - 0x10093d, 0x100950, 0x10098f, 0x100990, 0x1009b2, 0x1009bd, 0x1009ce, 0x1009dc, 0x1009dd, - 0x1009f0, 0x1009f1, 0x1009fc, 0x100a0f, 0x100a10, 0x100a32, 0x100a33, 0x100a35, 0x100a36, - 0x100a38, 0x100a39, 0x100a5e, 0x100ab2, 0x100ab3, 0x100abd, 0x100ad0, 0x100ae0, 0x100ae1, - 0x100af9, 0x100b0f, 0x100b10, 0x100b32, 0x100b33, 0x100b3d, 0x100b5c, 0x100b5d, 0x100b71, - 0x100b83, 0x100b99, 0x100b9a, 0x100b9c, 0x100b9e, 0x100b9f, 0x100ba3, 0x100ba4, 0x100bd0, - 0x100c3d, 0x100c60, 0x100c61, 0x100c80, 0x100cbd, 0x100cde, 0x100ce0, 0x100ce1, 0x100cf1, - 0x100cf2, 0x100d3d, 0x100d4e, 0x100dbd, 0x100e32, 0x100e33, 0x100e81, 0x100e82, 0x100e84, - 0x100e87, 0x100e88, 0x100e8a, 0x100e8d, 0x100ea5, 0x100ea7, 0x100eaa, 0x100eab, 0x100eb2, - 0x100eb3, 0x100ebd, 0x100ec6, 0x100f00, 0x10103f, 0x101061, 0x101065, 0x101066, 0x10108e, - 0x1010c7, 0x1010cd, 0x101258, 0x1012c0, 0x1017d7, 0x1017dc, 0x1018aa, 0x101aa7, 0x101bae, - 0x101baf, 0x101cf5, 0x101cf6, 0x101f59, 0x101f5b, 0x101f5d, 0x101fbe, 0x102071, 0x10207f, - 0x102102, 0x102107, 0x102115, 0x102124, 0x102126, 0x102128, 0x10214e, 0x102183, 0x102184, - 0x102cf2, 0x102cf3, 0x102d27, 0x102d2d, 0x102d6f, 0x102e2f, 0x103005, 0x103006, 0x10303b, - 0x10303c, 0x10a62a, 0x10a62b, 0x10a8fb, 0x10a8fd, 0x10a9cf, 0x10aa7a, 0x10aab1, 0x10aab5, - 0x10aab6, 0x10aac0, 0x10aac2, 0x10fb1d, 0x10fb3e, 0x10fb40, 0x10fb41, 0x10fb43, 0x10fb44 + ,0x1003c, 0x1003d, 0x10808, 0x10837, 0x10838, 0x1083c, 0x108f4, 0x108f5, 0x109be, + 0x109bf, 0x10a00, 0x11176, 0x111da, 0x111dc, 0x11288, 0x1130f, 0x11310, 0x11332, + 0x11333, 0x1133d, 0x11350, 0x114c4, 0x114c5, 0x114c7, 0x11644, 0x118ff, 0x11a00, + 0x11a3a, 0x11a50, 0x11c40, 0x11d08, 0x11d09, 0x11d46, 0x16f50, 0x16fe0, 0x16fe1, + 0x1d49e, 0x1d49f, 0x1d4a2, 0x1d4a5, 0x1d4a6, 0x1d4bb, 0x1d546, 0x1ee21, 0x1ee22, + 0x1ee24, 0x1ee27, 0x1ee39, 0x1ee3b, 0x1ee42, 0x1ee47, 0x1ee49, 0x1ee4b, 0x1ee51, + 0x1ee52, 0x1ee54, 0x1ee57, 0x1ee59, 0x1ee5b, 0x1ee5d, 0x1ee5f, 0x1ee61, 0x1ee62, + 0x1ee64, 0x1ee7e #endif }; @@ -1567,42 +289,8 @@ static const crange controlRangeTable[] = { {0x202a, 0x202e}, {0x2060, 0x2064}, {0x2066, 0x206f}, {0xe000, 0xf8ff}, {0xfff9, 0xfffb} #if TCL_UTF_MAX > 4 - ,{0x10000, 0x1001f}, {0x1007f, 0x1009f}, {0x10600, 0x10605}, {0x1200b, 0x1200f}, - {0x1202a, 0x1202e}, {0x12060, 0x12064}, {0x12066, 0x1206f}, {0x1e000, 0x1f8ff}, - {0x1fff9, 0x1fffb}, {0x20000, 0x2001f}, {0x2007f, 0x2009f}, {0x20600, 0x20605}, - {0x2200b, 0x2200f}, {0x2202a, 0x2202e}, {0x22060, 0x22064}, {0x22066, 0x2206f}, - {0x2e000, 0x2f8ff}, {0x2fff9, 0x2fffb}, {0x30000, 0x3001f}, {0x3007f, 0x3009f}, - {0x30600, 0x30605}, {0x3200b, 0x3200f}, {0x3202a, 0x3202e}, {0x32060, 0x32064}, - {0x32066, 0x3206f}, {0x3e000, 0x3f8ff}, {0x3fff9, 0x3fffb}, {0x40000, 0x4001f}, - {0x4007f, 0x4009f}, {0x40600, 0x40605}, {0x4200b, 0x4200f}, {0x4202a, 0x4202e}, - {0x42060, 0x42064}, {0x42066, 0x4206f}, {0x4e000, 0x4f8ff}, {0x4fff9, 0x4fffb}, - {0x50000, 0x5001f}, {0x5007f, 0x5009f}, {0x50600, 0x50605}, {0x5200b, 0x5200f}, - {0x5202a, 0x5202e}, {0x52060, 0x52064}, {0x52066, 0x5206f}, {0x5e000, 0x5f8ff}, - {0x5fff9, 0x5fffb}, {0x60000, 0x6001f}, {0x6007f, 0x6009f}, {0x60600, 0x60605}, - {0x6200b, 0x6200f}, {0x6202a, 0x6202e}, {0x62060, 0x62064}, {0x62066, 0x6206f}, - {0x6e000, 0x6f8ff}, {0x6fff9, 0x6fffb}, {0x70000, 0x7001f}, {0x7007f, 0x7009f}, - {0x70600, 0x70605}, {0x7200b, 0x7200f}, {0x7202a, 0x7202e}, {0x72060, 0x72064}, - {0x72066, 0x7206f}, {0x7e000, 0x7f8ff}, {0x7fff9, 0x7fffb}, {0x80000, 0x8001f}, - {0x8007f, 0x8009f}, {0x80600, 0x80605}, {0x8200b, 0x8200f}, {0x8202a, 0x8202e}, - {0x82060, 0x82064}, {0x82066, 0x8206f}, {0x8e000, 0x8f8ff}, {0x8fff9, 0x8fffb}, - {0x90000, 0x9001f}, {0x9007f, 0x9009f}, {0x90600, 0x90605}, {0x9200b, 0x9200f}, - {0x9202a, 0x9202e}, {0x92060, 0x92064}, {0x92066, 0x9206f}, {0x9e000, 0x9f8ff}, - {0x9fff9, 0x9fffb}, {0xa0000, 0xa001f}, {0xa007f, 0xa009f}, {0xa0600, 0xa0605}, - {0xa200b, 0xa200f}, {0xa202a, 0xa202e}, {0xa2060, 0xa2064}, {0xa2066, 0xa206f}, - {0xae000, 0xaf8ff}, {0xafff9, 0xafffb}, {0xb0000, 0xb001f}, {0xb007f, 0xb009f}, - {0xb0600, 0xb0605}, {0xb200b, 0xb200f}, {0xb202a, 0xb202e}, {0xb2060, 0xb2064}, - {0xb2066, 0xb206f}, {0xbe000, 0xbf8ff}, {0xbfff9, 0xbfffb}, {0xc0000, 0xc001f}, - {0xc007f, 0xc009f}, {0xc0600, 0xc0605}, {0xc200b, 0xc200f}, {0xc202a, 0xc202e}, - {0xc2060, 0xc2064}, {0xc2066, 0xc206f}, {0xce000, 0xcf8ff}, {0xcfff9, 0xcfffb}, - {0xd0000, 0xd001f}, {0xd007f, 0xd009f}, {0xd0600, 0xd0605}, {0xd200b, 0xd200f}, - {0xd202a, 0xd202e}, {0xd2060, 0xd2064}, {0xd2066, 0xd206f}, {0xde000, 0xdf8ff}, - {0xdfff9, 0xdfffb}, {0xe0000, 0xe001f}, {0xe007f, 0xe009f}, {0xe0600, 0xe0605}, - {0xe200b, 0xe200f}, {0xe202a, 0xe202e}, {0xe2060, 0xe2064}, {0xe2066, 0xe206f}, - {0xee000, 0xef8ff}, {0xefff9, 0xefffb}, {0xf0000, 0xf001f}, {0xf007f, 0xf009f}, - {0xf0600, 0xf0605}, {0xf200b, 0xf200f}, {0xf202a, 0xf202e}, {0xf2060, 0xf2064}, - {0xf2066, 0xf206f}, {0xfe000, 0xff8ff}, {0xffff9, 0xffffb}, {0x100000, 0x10001f}, - {0x10007f, 0x10009f}, {0x100600, 0x100605}, {0x10200b, 0x10200f}, {0x10202a, 0x10202e}, - {0x102060, 0x102064}, {0x102066, 0x10206f}, {0x10e000, 0x10f8ff}, {0x10fff9, 0x10fffb} + ,{0x1bca0, 0x1bca3}, {0x1d173, 0x1d17a}, {0xe0020, 0xe007f}, {0xf0000, 0xffffd}, + {0x100000, 0x10fffd} #endif }; @@ -1611,19 +299,7 @@ static const crange controlRangeTable[] = { static const chr controlCharTable[] = { 0xad, 0x61c, 0x6dd, 0x70f, 0x8e2, 0x180e, 0xfeff #if TCL_UTF_MAX > 4 - ,0x100ad, 0x1061c, 0x106dd, 0x1070f, 0x108e2, 0x1180e, 0x1feff, 0x200ad, 0x2061c, - 0x206dd, 0x2070f, 0x208e2, 0x2180e, 0x2feff, 0x300ad, 0x3061c, 0x306dd, 0x3070f, - 0x308e2, 0x3180e, 0x3feff, 0x400ad, 0x4061c, 0x406dd, 0x4070f, 0x408e2, 0x4180e, - 0x4feff, 0x500ad, 0x5061c, 0x506dd, 0x5070f, 0x508e2, 0x5180e, 0x5feff, 0x600ad, - 0x6061c, 0x606dd, 0x6070f, 0x608e2, 0x6180e, 0x6feff, 0x700ad, 0x7061c, 0x706dd, - 0x7070f, 0x708e2, 0x7180e, 0x7feff, 0x800ad, 0x8061c, 0x806dd, 0x8070f, 0x808e2, - 0x8180e, 0x8feff, 0x900ad, 0x9061c, 0x906dd, 0x9070f, 0x908e2, 0x9180e, 0x9feff, - 0xa00ad, 0xa061c, 0xa06dd, 0xa070f, 0xa08e2, 0xa180e, 0xafeff, 0xb00ad, 0xb061c, - 0xb06dd, 0xb070f, 0xb08e2, 0xb180e, 0xbfeff, 0xc00ad, 0xc061c, 0xc06dd, 0xc070f, - 0xc08e2, 0xc180e, 0xcfeff, 0xd00ad, 0xd061c, 0xd06dd, 0xd070f, 0xd08e2, 0xd180e, - 0xdfeff, 0xe00ad, 0xe061c, 0xe06dd, 0xe070f, 0xe08e2, 0xe180e, 0xefeff, 0xf00ad, - 0xf061c, 0xf06dd, 0xf070f, 0xf08e2, 0xf180e, 0xffeff, 0x1000ad, 0x10061c, 0x1006dd, - 0x10070f, 0x1008e2, 0x10180e, 0x10feff + ,0x110bd, 0xe0001 #endif }; @@ -1645,154 +321,11 @@ static const crange digitRangeTable[] = { {0xa9d0, 0xa9d9}, {0xa9f0, 0xa9f9}, {0xaa50, 0xaa59}, {0xabf0, 0xabf9}, {0xff10, 0xff19} #if TCL_UTF_MAX > 4 - ,{0x10030, 0x10039}, {0x10660, 0x10669}, {0x106f0, 0x106f9}, {0x107c0, 0x107c9}, - {0x10966, 0x1096f}, {0x109e6, 0x109ef}, {0x10a66, 0x10a6f}, {0x10ae6, 0x10aef}, - {0x10b66, 0x10b6f}, {0x10be6, 0x10bef}, {0x10c66, 0x10c6f}, {0x10ce6, 0x10cef}, - {0x10d66, 0x10d6f}, {0x10de6, 0x10def}, {0x10e50, 0x10e59}, {0x10ed0, 0x10ed9}, - {0x10f20, 0x10f29}, {0x11040, 0x11049}, {0x11090, 0x11099}, {0x117e0, 0x117e9}, - {0x11810, 0x11819}, {0x11946, 0x1194f}, {0x119d0, 0x119d9}, {0x11a80, 0x11a89}, - {0x11a90, 0x11a99}, {0x11b50, 0x11b59}, {0x11bb0, 0x11bb9}, {0x11c40, 0x11c49}, - {0x11c50, 0x11c59}, {0x1a620, 0x1a629}, {0x1a8d0, 0x1a8d9}, {0x1a900, 0x1a909}, - {0x1a9d0, 0x1a9d9}, {0x1a9f0, 0x1a9f9}, {0x1aa50, 0x1aa59}, {0x1abf0, 0x1abf9}, - {0x1ff10, 0x1ff19}, {0x20030, 0x20039}, {0x20660, 0x20669}, {0x206f0, 0x206f9}, - {0x207c0, 0x207c9}, {0x20966, 0x2096f}, {0x209e6, 0x209ef}, {0x20a66, 0x20a6f}, - {0x20ae6, 0x20aef}, {0x20b66, 0x20b6f}, {0x20be6, 0x20bef}, {0x20c66, 0x20c6f}, - {0x20ce6, 0x20cef}, {0x20d66, 0x20d6f}, {0x20de6, 0x20def}, {0x20e50, 0x20e59}, - {0x20ed0, 0x20ed9}, {0x20f20, 0x20f29}, {0x21040, 0x21049}, {0x21090, 0x21099}, - {0x217e0, 0x217e9}, {0x21810, 0x21819}, {0x21946, 0x2194f}, {0x219d0, 0x219d9}, - {0x21a80, 0x21a89}, {0x21a90, 0x21a99}, {0x21b50, 0x21b59}, {0x21bb0, 0x21bb9}, - {0x21c40, 0x21c49}, {0x21c50, 0x21c59}, {0x2a620, 0x2a629}, {0x2a8d0, 0x2a8d9}, - {0x2a900, 0x2a909}, {0x2a9d0, 0x2a9d9}, {0x2a9f0, 0x2a9f9}, {0x2aa50, 0x2aa59}, - {0x2abf0, 0x2abf9}, {0x2ff10, 0x2ff19}, {0x30030, 0x30039}, {0x30660, 0x30669}, - {0x306f0, 0x306f9}, {0x307c0, 0x307c9}, {0x30966, 0x3096f}, {0x309e6, 0x309ef}, - {0x30a66, 0x30a6f}, {0x30ae6, 0x30aef}, {0x30b66, 0x30b6f}, {0x30be6, 0x30bef}, - {0x30c66, 0x30c6f}, {0x30ce6, 0x30cef}, {0x30d66, 0x30d6f}, {0x30de6, 0x30def}, - {0x30e50, 0x30e59}, {0x30ed0, 0x30ed9}, {0x30f20, 0x30f29}, {0x31040, 0x31049}, - {0x31090, 0x31099}, {0x317e0, 0x317e9}, {0x31810, 0x31819}, {0x31946, 0x3194f}, - {0x319d0, 0x319d9}, {0x31a80, 0x31a89}, {0x31a90, 0x31a99}, {0x31b50, 0x31b59}, - {0x31bb0, 0x31bb9}, {0x31c40, 0x31c49}, {0x31c50, 0x31c59}, {0x3a620, 0x3a629}, - {0x3a8d0, 0x3a8d9}, {0x3a900, 0x3a909}, {0x3a9d0, 0x3a9d9}, {0x3a9f0, 0x3a9f9}, - {0x3aa50, 0x3aa59}, {0x3abf0, 0x3abf9}, {0x3ff10, 0x3ff19}, {0x40030, 0x40039}, - {0x40660, 0x40669}, {0x406f0, 0x406f9}, {0x407c0, 0x407c9}, {0x40966, 0x4096f}, - {0x409e6, 0x409ef}, {0x40a66, 0x40a6f}, {0x40ae6, 0x40aef}, {0x40b66, 0x40b6f}, - {0x40be6, 0x40bef}, {0x40c66, 0x40c6f}, {0x40ce6, 0x40cef}, {0x40d66, 0x40d6f}, - {0x40de6, 0x40def}, {0x40e50, 0x40e59}, {0x40ed0, 0x40ed9}, {0x40f20, 0x40f29}, - {0x41040, 0x41049}, {0x41090, 0x41099}, {0x417e0, 0x417e9}, {0x41810, 0x41819}, - {0x41946, 0x4194f}, {0x419d0, 0x419d9}, {0x41a80, 0x41a89}, {0x41a90, 0x41a99}, - {0x41b50, 0x41b59}, {0x41bb0, 0x41bb9}, {0x41c40, 0x41c49}, {0x41c50, 0x41c59}, - {0x4a620, 0x4a629}, {0x4a8d0, 0x4a8d9}, {0x4a900, 0x4a909}, {0x4a9d0, 0x4a9d9}, - {0x4a9f0, 0x4a9f9}, {0x4aa50, 0x4aa59}, {0x4abf0, 0x4abf9}, {0x4ff10, 0x4ff19}, - {0x50030, 0x50039}, {0x50660, 0x50669}, {0x506f0, 0x506f9}, {0x507c0, 0x507c9}, - {0x50966, 0x5096f}, {0x509e6, 0x509ef}, {0x50a66, 0x50a6f}, {0x50ae6, 0x50aef}, - {0x50b66, 0x50b6f}, {0x50be6, 0x50bef}, {0x50c66, 0x50c6f}, {0x50ce6, 0x50cef}, - {0x50d66, 0x50d6f}, {0x50de6, 0x50def}, {0x50e50, 0x50e59}, {0x50ed0, 0x50ed9}, - {0x50f20, 0x50f29}, {0x51040, 0x51049}, {0x51090, 0x51099}, {0x517e0, 0x517e9}, - {0x51810, 0x51819}, {0x51946, 0x5194f}, {0x519d0, 0x519d9}, {0x51a80, 0x51a89}, - {0x51a90, 0x51a99}, {0x51b50, 0x51b59}, {0x51bb0, 0x51bb9}, {0x51c40, 0x51c49}, - {0x51c50, 0x51c59}, {0x5a620, 0x5a629}, {0x5a8d0, 0x5a8d9}, {0x5a900, 0x5a909}, - {0x5a9d0, 0x5a9d9}, {0x5a9f0, 0x5a9f9}, {0x5aa50, 0x5aa59}, {0x5abf0, 0x5abf9}, - {0x5ff10, 0x5ff19}, {0x60030, 0x60039}, {0x60660, 0x60669}, {0x606f0, 0x606f9}, - {0x607c0, 0x607c9}, {0x60966, 0x6096f}, {0x609e6, 0x609ef}, {0x60a66, 0x60a6f}, - {0x60ae6, 0x60aef}, {0x60b66, 0x60b6f}, {0x60be6, 0x60bef}, {0x60c66, 0x60c6f}, - {0x60ce6, 0x60cef}, {0x60d66, 0x60d6f}, {0x60de6, 0x60def}, {0x60e50, 0x60e59}, - {0x60ed0, 0x60ed9}, {0x60f20, 0x60f29}, {0x61040, 0x61049}, {0x61090, 0x61099}, - {0x617e0, 0x617e9}, {0x61810, 0x61819}, {0x61946, 0x6194f}, {0x619d0, 0x619d9}, - {0x61a80, 0x61a89}, {0x61a90, 0x61a99}, {0x61b50, 0x61b59}, {0x61bb0, 0x61bb9}, - {0x61c40, 0x61c49}, {0x61c50, 0x61c59}, {0x6a620, 0x6a629}, {0x6a8d0, 0x6a8d9}, - {0x6a900, 0x6a909}, {0x6a9d0, 0x6a9d9}, {0x6a9f0, 0x6a9f9}, {0x6aa50, 0x6aa59}, - {0x6abf0, 0x6abf9}, {0x6ff10, 0x6ff19}, {0x70030, 0x70039}, {0x70660, 0x70669}, - {0x706f0, 0x706f9}, {0x707c0, 0x707c9}, {0x70966, 0x7096f}, {0x709e6, 0x709ef}, - {0x70a66, 0x70a6f}, {0x70ae6, 0x70aef}, {0x70b66, 0x70b6f}, {0x70be6, 0x70bef}, - {0x70c66, 0x70c6f}, {0x70ce6, 0x70cef}, {0x70d66, 0x70d6f}, {0x70de6, 0x70def}, - {0x70e50, 0x70e59}, {0x70ed0, 0x70ed9}, {0x70f20, 0x70f29}, {0x71040, 0x71049}, - {0x71090, 0x71099}, {0x717e0, 0x717e9}, {0x71810, 0x71819}, {0x71946, 0x7194f}, - {0x719d0, 0x719d9}, {0x71a80, 0x71a89}, {0x71a90, 0x71a99}, {0x71b50, 0x71b59}, - {0x71bb0, 0x71bb9}, {0x71c40, 0x71c49}, {0x71c50, 0x71c59}, {0x7a620, 0x7a629}, - {0x7a8d0, 0x7a8d9}, {0x7a900, 0x7a909}, {0x7a9d0, 0x7a9d9}, {0x7a9f0, 0x7a9f9}, - {0x7aa50, 0x7aa59}, {0x7abf0, 0x7abf9}, {0x7ff10, 0x7ff19}, {0x80030, 0x80039}, - {0x80660, 0x80669}, {0x806f0, 0x806f9}, {0x807c0, 0x807c9}, {0x80966, 0x8096f}, - {0x809e6, 0x809ef}, {0x80a66, 0x80a6f}, {0x80ae6, 0x80aef}, {0x80b66, 0x80b6f}, - {0x80be6, 0x80bef}, {0x80c66, 0x80c6f}, {0x80ce6, 0x80cef}, {0x80d66, 0x80d6f}, - {0x80de6, 0x80def}, {0x80e50, 0x80e59}, {0x80ed0, 0x80ed9}, {0x80f20, 0x80f29}, - {0x81040, 0x81049}, {0x81090, 0x81099}, {0x817e0, 0x817e9}, {0x81810, 0x81819}, - {0x81946, 0x8194f}, {0x819d0, 0x819d9}, {0x81a80, 0x81a89}, {0x81a90, 0x81a99}, - {0x81b50, 0x81b59}, {0x81bb0, 0x81bb9}, {0x81c40, 0x81c49}, {0x81c50, 0x81c59}, - {0x8a620, 0x8a629}, {0x8a8d0, 0x8a8d9}, {0x8a900, 0x8a909}, {0x8a9d0, 0x8a9d9}, - {0x8a9f0, 0x8a9f9}, {0x8aa50, 0x8aa59}, {0x8abf0, 0x8abf9}, {0x8ff10, 0x8ff19}, - {0x90030, 0x90039}, {0x90660, 0x90669}, {0x906f0, 0x906f9}, {0x907c0, 0x907c9}, - {0x90966, 0x9096f}, {0x909e6, 0x909ef}, {0x90a66, 0x90a6f}, {0x90ae6, 0x90aef}, - {0x90b66, 0x90b6f}, {0x90be6, 0x90bef}, {0x90c66, 0x90c6f}, {0x90ce6, 0x90cef}, - {0x90d66, 0x90d6f}, {0x90de6, 0x90def}, {0x90e50, 0x90e59}, {0x90ed0, 0x90ed9}, - {0x90f20, 0x90f29}, {0x91040, 0x91049}, {0x91090, 0x91099}, {0x917e0, 0x917e9}, - {0x91810, 0x91819}, {0x91946, 0x9194f}, {0x919d0, 0x919d9}, {0x91a80, 0x91a89}, - {0x91a90, 0x91a99}, {0x91b50, 0x91b59}, {0x91bb0, 0x91bb9}, {0x91c40, 0x91c49}, - {0x91c50, 0x91c59}, {0x9a620, 0x9a629}, {0x9a8d0, 0x9a8d9}, {0x9a900, 0x9a909}, - {0x9a9d0, 0x9a9d9}, {0x9a9f0, 0x9a9f9}, {0x9aa50, 0x9aa59}, {0x9abf0, 0x9abf9}, - {0x9ff10, 0x9ff19}, {0xa0030, 0xa0039}, {0xa0660, 0xa0669}, {0xa06f0, 0xa06f9}, - {0xa07c0, 0xa07c9}, {0xa0966, 0xa096f}, {0xa09e6, 0xa09ef}, {0xa0a66, 0xa0a6f}, - {0xa0ae6, 0xa0aef}, {0xa0b66, 0xa0b6f}, {0xa0be6, 0xa0bef}, {0xa0c66, 0xa0c6f}, - {0xa0ce6, 0xa0cef}, {0xa0d66, 0xa0d6f}, {0xa0de6, 0xa0def}, {0xa0e50, 0xa0e59}, - {0xa0ed0, 0xa0ed9}, {0xa0f20, 0xa0f29}, {0xa1040, 0xa1049}, {0xa1090, 0xa1099}, - {0xa17e0, 0xa17e9}, {0xa1810, 0xa1819}, {0xa1946, 0xa194f}, {0xa19d0, 0xa19d9}, - {0xa1a80, 0xa1a89}, {0xa1a90, 0xa1a99}, {0xa1b50, 0xa1b59}, {0xa1bb0, 0xa1bb9}, - {0xa1c40, 0xa1c49}, {0xa1c50, 0xa1c59}, {0xaa620, 0xaa629}, {0xaa8d0, 0xaa8d9}, - {0xaa900, 0xaa909}, {0xaa9d0, 0xaa9d9}, {0xaa9f0, 0xaa9f9}, {0xaaa50, 0xaaa59}, - {0xaabf0, 0xaabf9}, {0xaff10, 0xaff19}, {0xb0030, 0xb0039}, {0xb0660, 0xb0669}, - {0xb06f0, 0xb06f9}, {0xb07c0, 0xb07c9}, {0xb0966, 0xb096f}, {0xb09e6, 0xb09ef}, - {0xb0a66, 0xb0a6f}, {0xb0ae6, 0xb0aef}, {0xb0b66, 0xb0b6f}, {0xb0be6, 0xb0bef}, - {0xb0c66, 0xb0c6f}, {0xb0ce6, 0xb0cef}, {0xb0d66, 0xb0d6f}, {0xb0de6, 0xb0def}, - {0xb0e50, 0xb0e59}, {0xb0ed0, 0xb0ed9}, {0xb0f20, 0xb0f29}, {0xb1040, 0xb1049}, - {0xb1090, 0xb1099}, {0xb17e0, 0xb17e9}, {0xb1810, 0xb1819}, {0xb1946, 0xb194f}, - {0xb19d0, 0xb19d9}, {0xb1a80, 0xb1a89}, {0xb1a90, 0xb1a99}, {0xb1b50, 0xb1b59}, - {0xb1bb0, 0xb1bb9}, {0xb1c40, 0xb1c49}, {0xb1c50, 0xb1c59}, {0xba620, 0xba629}, - {0xba8d0, 0xba8d9}, {0xba900, 0xba909}, {0xba9d0, 0xba9d9}, {0xba9f0, 0xba9f9}, - {0xbaa50, 0xbaa59}, {0xbabf0, 0xbabf9}, {0xbff10, 0xbff19}, {0xc0030, 0xc0039}, - {0xc0660, 0xc0669}, {0xc06f0, 0xc06f9}, {0xc07c0, 0xc07c9}, {0xc0966, 0xc096f}, - {0xc09e6, 0xc09ef}, {0xc0a66, 0xc0a6f}, {0xc0ae6, 0xc0aef}, {0xc0b66, 0xc0b6f}, - {0xc0be6, 0xc0bef}, {0xc0c66, 0xc0c6f}, {0xc0ce6, 0xc0cef}, {0xc0d66, 0xc0d6f}, - {0xc0de6, 0xc0def}, {0xc0e50, 0xc0e59}, {0xc0ed0, 0xc0ed9}, {0xc0f20, 0xc0f29}, - {0xc1040, 0xc1049}, {0xc1090, 0xc1099}, {0xc17e0, 0xc17e9}, {0xc1810, 0xc1819}, - {0xc1946, 0xc194f}, {0xc19d0, 0xc19d9}, {0xc1a80, 0xc1a89}, {0xc1a90, 0xc1a99}, - {0xc1b50, 0xc1b59}, {0xc1bb0, 0xc1bb9}, {0xc1c40, 0xc1c49}, {0xc1c50, 0xc1c59}, - {0xca620, 0xca629}, {0xca8d0, 0xca8d9}, {0xca900, 0xca909}, {0xca9d0, 0xca9d9}, - {0xca9f0, 0xca9f9}, {0xcaa50, 0xcaa59}, {0xcabf0, 0xcabf9}, {0xcff10, 0xcff19}, - {0xd0030, 0xd0039}, {0xd0660, 0xd0669}, {0xd06f0, 0xd06f9}, {0xd07c0, 0xd07c9}, - {0xd0966, 0xd096f}, {0xd09e6, 0xd09ef}, {0xd0a66, 0xd0a6f}, {0xd0ae6, 0xd0aef}, - {0xd0b66, 0xd0b6f}, {0xd0be6, 0xd0bef}, {0xd0c66, 0xd0c6f}, {0xd0ce6, 0xd0cef}, - {0xd0d66, 0xd0d6f}, {0xd0de6, 0xd0def}, {0xd0e50, 0xd0e59}, {0xd0ed0, 0xd0ed9}, - {0xd0f20, 0xd0f29}, {0xd1040, 0xd1049}, {0xd1090, 0xd1099}, {0xd17e0, 0xd17e9}, - {0xd1810, 0xd1819}, {0xd1946, 0xd194f}, {0xd19d0, 0xd19d9}, {0xd1a80, 0xd1a89}, - {0xd1a90, 0xd1a99}, {0xd1b50, 0xd1b59}, {0xd1bb0, 0xd1bb9}, {0xd1c40, 0xd1c49}, - {0xd1c50, 0xd1c59}, {0xda620, 0xda629}, {0xda8d0, 0xda8d9}, {0xda900, 0xda909}, - {0xda9d0, 0xda9d9}, {0xda9f0, 0xda9f9}, {0xdaa50, 0xdaa59}, {0xdabf0, 0xdabf9}, - {0xdff10, 0xdff19}, {0xe0030, 0xe0039}, {0xe0660, 0xe0669}, {0xe06f0, 0xe06f9}, - {0xe07c0, 0xe07c9}, {0xe0966, 0xe096f}, {0xe09e6, 0xe09ef}, {0xe0a66, 0xe0a6f}, - {0xe0ae6, 0xe0aef}, {0xe0b66, 0xe0b6f}, {0xe0be6, 0xe0bef}, {0xe0c66, 0xe0c6f}, - {0xe0ce6, 0xe0cef}, {0xe0d66, 0xe0d6f}, {0xe0de6, 0xe0def}, {0xe0e50, 0xe0e59}, - {0xe0ed0, 0xe0ed9}, {0xe0f20, 0xe0f29}, {0xe1040, 0xe1049}, {0xe1090, 0xe1099}, - {0xe17e0, 0xe17e9}, {0xe1810, 0xe1819}, {0xe1946, 0xe194f}, {0xe19d0, 0xe19d9}, - {0xe1a80, 0xe1a89}, {0xe1a90, 0xe1a99}, {0xe1b50, 0xe1b59}, {0xe1bb0, 0xe1bb9}, - {0xe1c40, 0xe1c49}, {0xe1c50, 0xe1c59}, {0xea620, 0xea629}, {0xea8d0, 0xea8d9}, - {0xea900, 0xea909}, {0xea9d0, 0xea9d9}, {0xea9f0, 0xea9f9}, {0xeaa50, 0xeaa59}, - {0xeabf0, 0xeabf9}, {0xeff10, 0xeff19}, {0xf0030, 0xf0039}, {0xf0660, 0xf0669}, - {0xf06f0, 0xf06f9}, {0xf07c0, 0xf07c9}, {0xf0966, 0xf096f}, {0xf09e6, 0xf09ef}, - {0xf0a66, 0xf0a6f}, {0xf0ae6, 0xf0aef}, {0xf0b66, 0xf0b6f}, {0xf0be6, 0xf0bef}, - {0xf0c66, 0xf0c6f}, {0xf0ce6, 0xf0cef}, {0xf0d66, 0xf0d6f}, {0xf0de6, 0xf0def}, - {0xf0e50, 0xf0e59}, {0xf0ed0, 0xf0ed9}, {0xf0f20, 0xf0f29}, {0xf1040, 0xf1049}, - {0xf1090, 0xf1099}, {0xf17e0, 0xf17e9}, {0xf1810, 0xf1819}, {0xf1946, 0xf194f}, - {0xf19d0, 0xf19d9}, {0xf1a80, 0xf1a89}, {0xf1a90, 0xf1a99}, {0xf1b50, 0xf1b59}, - {0xf1bb0, 0xf1bb9}, {0xf1c40, 0xf1c49}, {0xf1c50, 0xf1c59}, {0xfa620, 0xfa629}, - {0xfa8d0, 0xfa8d9}, {0xfa900, 0xfa909}, {0xfa9d0, 0xfa9d9}, {0xfa9f0, 0xfa9f9}, - {0xfaa50, 0xfaa59}, {0xfabf0, 0xfabf9}, {0xfff10, 0xfff19}, {0x100030, 0x100039}, - {0x100660, 0x100669}, {0x1006f0, 0x1006f9}, {0x1007c0, 0x1007c9}, {0x100966, 0x10096f}, - {0x1009e6, 0x1009ef}, {0x100a66, 0x100a6f}, {0x100ae6, 0x100aef}, {0x100b66, 0x100b6f}, - {0x100be6, 0x100bef}, {0x100c66, 0x100c6f}, {0x100ce6, 0x100cef}, {0x100d66, 0x100d6f}, - {0x100de6, 0x100def}, {0x100e50, 0x100e59}, {0x100ed0, 0x100ed9}, {0x100f20, 0x100f29}, - {0x101040, 0x101049}, {0x101090, 0x101099}, {0x1017e0, 0x1017e9}, {0x101810, 0x101819}, - {0x101946, 0x10194f}, {0x1019d0, 0x1019d9}, {0x101a80, 0x101a89}, {0x101a90, 0x101a99}, - {0x101b50, 0x101b59}, {0x101bb0, 0x101bb9}, {0x101c40, 0x101c49}, {0x101c50, 0x101c59}, - {0x10a620, 0x10a629}, {0x10a8d0, 0x10a8d9}, {0x10a900, 0x10a909}, {0x10a9d0, 0x10a9d9}, - {0x10a9f0, 0x10a9f9}, {0x10aa50, 0x10aa59}, {0x10abf0, 0x10abf9}, {0x10ff10, 0x10ff19} + ,{0x104a0, 0x104a9}, {0x11066, 0x1106f}, {0x110f0, 0x110f9}, {0x11136, 0x1113f}, + {0x111d0, 0x111d9}, {0x112f0, 0x112f9}, {0x11450, 0x11459}, {0x114d0, 0x114d9}, + {0x11650, 0x11659}, {0x116c0, 0x116c9}, {0x11730, 0x11739}, {0x118e0, 0x118e9}, + {0x11c50, 0x11c59}, {0x11d50, 0x11d59}, {0x16a60, 0x16a69}, {0x16b50, 0x16b59}, + {0x1d7ce, 0x1d7ff}, {0x1e950, 0x1e959} #endif }; @@ -1822,218 +355,12 @@ static const crange punctRangeTable[] = { {0xff01, 0xff03}, {0xff05, 0xff0a}, {0xff0c, 0xff0f}, {0xff3b, 0xff3d}, {0xff5f, 0xff65} #if TCL_UTF_MAX > 4 - ,{0x10021, 0x10023}, {0x10025, 0x1002a}, {0x1002c, 0x1002f}, {0x1005b, 0x1005d}, - {0x1055a, 0x1055f}, {0x1066a, 0x1066d}, {0x10700, 0x1070d}, {0x107f7, 0x107f9}, - {0x10830, 0x1083e}, {0x10f04, 0x10f12}, {0x10f3a, 0x10f3d}, {0x10fd0, 0x10fd4}, - {0x1104a, 0x1104f}, {0x11360, 0x11368}, {0x116eb, 0x116ed}, {0x117d4, 0x117d6}, - {0x117d8, 0x117da}, {0x11800, 0x1180a}, {0x11aa0, 0x11aa6}, {0x11aa8, 0x11aad}, - {0x11b5a, 0x11b60}, {0x11bfc, 0x11bff}, {0x11c3b, 0x11c3f}, {0x11cc0, 0x11cc7}, - {0x12010, 0x12027}, {0x12030, 0x12043}, {0x12045, 0x12051}, {0x12053, 0x1205e}, - {0x12308, 0x1230b}, {0x12768, 0x12775}, {0x127e6, 0x127ef}, {0x12983, 0x12998}, - {0x129d8, 0x129db}, {0x12cf9, 0x12cfc}, {0x12e00, 0x12e2e}, {0x12e30, 0x12e49}, - {0x13001, 0x13003}, {0x13008, 0x13011}, {0x13014, 0x1301f}, {0x1a60d, 0x1a60f}, - {0x1a6f2, 0x1a6f7}, {0x1a874, 0x1a877}, {0x1a8f8, 0x1a8fa}, {0x1a9c1, 0x1a9cd}, - {0x1aa5c, 0x1aa5f}, {0x1fe10, 0x1fe19}, {0x1fe30, 0x1fe52}, {0x1fe54, 0x1fe61}, - {0x1ff01, 0x1ff03}, {0x1ff05, 0x1ff0a}, {0x1ff0c, 0x1ff0f}, {0x1ff3b, 0x1ff3d}, - {0x1ff5f, 0x1ff65}, {0x20021, 0x20023}, {0x20025, 0x2002a}, {0x2002c, 0x2002f}, - {0x2005b, 0x2005d}, {0x2055a, 0x2055f}, {0x2066a, 0x2066d}, {0x20700, 0x2070d}, - {0x207f7, 0x207f9}, {0x20830, 0x2083e}, {0x20f04, 0x20f12}, {0x20f3a, 0x20f3d}, - {0x20fd0, 0x20fd4}, {0x2104a, 0x2104f}, {0x21360, 0x21368}, {0x216eb, 0x216ed}, - {0x217d4, 0x217d6}, {0x217d8, 0x217da}, {0x21800, 0x2180a}, {0x21aa0, 0x21aa6}, - {0x21aa8, 0x21aad}, {0x21b5a, 0x21b60}, {0x21bfc, 0x21bff}, {0x21c3b, 0x21c3f}, - {0x21cc0, 0x21cc7}, {0x22010, 0x22027}, {0x22030, 0x22043}, {0x22045, 0x22051}, - {0x22053, 0x2205e}, {0x22308, 0x2230b}, {0x22768, 0x22775}, {0x227e6, 0x227ef}, - {0x22983, 0x22998}, {0x229d8, 0x229db}, {0x22cf9, 0x22cfc}, {0x22e00, 0x22e2e}, - {0x22e30, 0x22e49}, {0x23001, 0x23003}, {0x23008, 0x23011}, {0x23014, 0x2301f}, - {0x2a60d, 0x2a60f}, {0x2a6f2, 0x2a6f7}, {0x2a874, 0x2a877}, {0x2a8f8, 0x2a8fa}, - {0x2a9c1, 0x2a9cd}, {0x2aa5c, 0x2aa5f}, {0x2fe10, 0x2fe19}, {0x2fe30, 0x2fe52}, - {0x2fe54, 0x2fe61}, {0x2ff01, 0x2ff03}, {0x2ff05, 0x2ff0a}, {0x2ff0c, 0x2ff0f}, - {0x2ff3b, 0x2ff3d}, {0x2ff5f, 0x2ff65}, {0x30021, 0x30023}, {0x30025, 0x3002a}, - {0x3002c, 0x3002f}, {0x3005b, 0x3005d}, {0x3055a, 0x3055f}, {0x3066a, 0x3066d}, - {0x30700, 0x3070d}, {0x307f7, 0x307f9}, {0x30830, 0x3083e}, {0x30f04, 0x30f12}, - {0x30f3a, 0x30f3d}, {0x30fd0, 0x30fd4}, {0x3104a, 0x3104f}, {0x31360, 0x31368}, - {0x316eb, 0x316ed}, {0x317d4, 0x317d6}, {0x317d8, 0x317da}, {0x31800, 0x3180a}, - {0x31aa0, 0x31aa6}, {0x31aa8, 0x31aad}, {0x31b5a, 0x31b60}, {0x31bfc, 0x31bff}, - {0x31c3b, 0x31c3f}, {0x31cc0, 0x31cc7}, {0x32010, 0x32027}, {0x32030, 0x32043}, - {0x32045, 0x32051}, {0x32053, 0x3205e}, {0x32308, 0x3230b}, {0x32768, 0x32775}, - {0x327e6, 0x327ef}, {0x32983, 0x32998}, {0x329d8, 0x329db}, {0x32cf9, 0x32cfc}, - {0x32e00, 0x32e2e}, {0x32e30, 0x32e49}, {0x33001, 0x33003}, {0x33008, 0x33011}, - {0x33014, 0x3301f}, {0x3a60d, 0x3a60f}, {0x3a6f2, 0x3a6f7}, {0x3a874, 0x3a877}, - {0x3a8f8, 0x3a8fa}, {0x3a9c1, 0x3a9cd}, {0x3aa5c, 0x3aa5f}, {0x3fe10, 0x3fe19}, - {0x3fe30, 0x3fe52}, {0x3fe54, 0x3fe61}, {0x3ff01, 0x3ff03}, {0x3ff05, 0x3ff0a}, - {0x3ff0c, 0x3ff0f}, {0x3ff3b, 0x3ff3d}, {0x3ff5f, 0x3ff65}, {0x40021, 0x40023}, - {0x40025, 0x4002a}, {0x4002c, 0x4002f}, {0x4005b, 0x4005d}, {0x4055a, 0x4055f}, - {0x4066a, 0x4066d}, {0x40700, 0x4070d}, {0x407f7, 0x407f9}, {0x40830, 0x4083e}, - {0x40f04, 0x40f12}, {0x40f3a, 0x40f3d}, {0x40fd0, 0x40fd4}, {0x4104a, 0x4104f}, - {0x41360, 0x41368}, {0x416eb, 0x416ed}, {0x417d4, 0x417d6}, {0x417d8, 0x417da}, - {0x41800, 0x4180a}, {0x41aa0, 0x41aa6}, {0x41aa8, 0x41aad}, {0x41b5a, 0x41b60}, - {0x41bfc, 0x41bff}, {0x41c3b, 0x41c3f}, {0x41cc0, 0x41cc7}, {0x42010, 0x42027}, - {0x42030, 0x42043}, {0x42045, 0x42051}, {0x42053, 0x4205e}, {0x42308, 0x4230b}, - {0x42768, 0x42775}, {0x427e6, 0x427ef}, {0x42983, 0x42998}, {0x429d8, 0x429db}, - {0x42cf9, 0x42cfc}, {0x42e00, 0x42e2e}, {0x42e30, 0x42e49}, {0x43001, 0x43003}, - {0x43008, 0x43011}, {0x43014, 0x4301f}, {0x4a60d, 0x4a60f}, {0x4a6f2, 0x4a6f7}, - {0x4a874, 0x4a877}, {0x4a8f8, 0x4a8fa}, {0x4a9c1, 0x4a9cd}, {0x4aa5c, 0x4aa5f}, - {0x4fe10, 0x4fe19}, {0x4fe30, 0x4fe52}, {0x4fe54, 0x4fe61}, {0x4ff01, 0x4ff03}, - {0x4ff05, 0x4ff0a}, {0x4ff0c, 0x4ff0f}, {0x4ff3b, 0x4ff3d}, {0x4ff5f, 0x4ff65}, - {0x50021, 0x50023}, {0x50025, 0x5002a}, {0x5002c, 0x5002f}, {0x5005b, 0x5005d}, - {0x5055a, 0x5055f}, {0x5066a, 0x5066d}, {0x50700, 0x5070d}, {0x507f7, 0x507f9}, - {0x50830, 0x5083e}, {0x50f04, 0x50f12}, {0x50f3a, 0x50f3d}, {0x50fd0, 0x50fd4}, - {0x5104a, 0x5104f}, {0x51360, 0x51368}, {0x516eb, 0x516ed}, {0x517d4, 0x517d6}, - {0x517d8, 0x517da}, {0x51800, 0x5180a}, {0x51aa0, 0x51aa6}, {0x51aa8, 0x51aad}, - {0x51b5a, 0x51b60}, {0x51bfc, 0x51bff}, {0x51c3b, 0x51c3f}, {0x51cc0, 0x51cc7}, - {0x52010, 0x52027}, {0x52030, 0x52043}, {0x52045, 0x52051}, {0x52053, 0x5205e}, - {0x52308, 0x5230b}, {0x52768, 0x52775}, {0x527e6, 0x527ef}, {0x52983, 0x52998}, - {0x529d8, 0x529db}, {0x52cf9, 0x52cfc}, {0x52e00, 0x52e2e}, {0x52e30, 0x52e49}, - {0x53001, 0x53003}, {0x53008, 0x53011}, {0x53014, 0x5301f}, {0x5a60d, 0x5a60f}, - {0x5a6f2, 0x5a6f7}, {0x5a874, 0x5a877}, {0x5a8f8, 0x5a8fa}, {0x5a9c1, 0x5a9cd}, - {0x5aa5c, 0x5aa5f}, {0x5fe10, 0x5fe19}, {0x5fe30, 0x5fe52}, {0x5fe54, 0x5fe61}, - {0x5ff01, 0x5ff03}, {0x5ff05, 0x5ff0a}, {0x5ff0c, 0x5ff0f}, {0x5ff3b, 0x5ff3d}, - {0x5ff5f, 0x5ff65}, {0x60021, 0x60023}, {0x60025, 0x6002a}, {0x6002c, 0x6002f}, - {0x6005b, 0x6005d}, {0x6055a, 0x6055f}, {0x6066a, 0x6066d}, {0x60700, 0x6070d}, - {0x607f7, 0x607f9}, {0x60830, 0x6083e}, {0x60f04, 0x60f12}, {0x60f3a, 0x60f3d}, - {0x60fd0, 0x60fd4}, {0x6104a, 0x6104f}, {0x61360, 0x61368}, {0x616eb, 0x616ed}, - {0x617d4, 0x617d6}, {0x617d8, 0x617da}, {0x61800, 0x6180a}, {0x61aa0, 0x61aa6}, - {0x61aa8, 0x61aad}, {0x61b5a, 0x61b60}, {0x61bfc, 0x61bff}, {0x61c3b, 0x61c3f}, - {0x61cc0, 0x61cc7}, {0x62010, 0x62027}, {0x62030, 0x62043}, {0x62045, 0x62051}, - {0x62053, 0x6205e}, {0x62308, 0x6230b}, {0x62768, 0x62775}, {0x627e6, 0x627ef}, - {0x62983, 0x62998}, {0x629d8, 0x629db}, {0x62cf9, 0x62cfc}, {0x62e00, 0x62e2e}, - {0x62e30, 0x62e49}, {0x63001, 0x63003}, {0x63008, 0x63011}, {0x63014, 0x6301f}, - {0x6a60d, 0x6a60f}, {0x6a6f2, 0x6a6f7}, {0x6a874, 0x6a877}, {0x6a8f8, 0x6a8fa}, - {0x6a9c1, 0x6a9cd}, {0x6aa5c, 0x6aa5f}, {0x6fe10, 0x6fe19}, {0x6fe30, 0x6fe52}, - {0x6fe54, 0x6fe61}, {0x6ff01, 0x6ff03}, {0x6ff05, 0x6ff0a}, {0x6ff0c, 0x6ff0f}, - {0x6ff3b, 0x6ff3d}, {0x6ff5f, 0x6ff65}, {0x70021, 0x70023}, {0x70025, 0x7002a}, - {0x7002c, 0x7002f}, {0x7005b, 0x7005d}, {0x7055a, 0x7055f}, {0x7066a, 0x7066d}, - {0x70700, 0x7070d}, {0x707f7, 0x707f9}, {0x70830, 0x7083e}, {0x70f04, 0x70f12}, - {0x70f3a, 0x70f3d}, {0x70fd0, 0x70fd4}, {0x7104a, 0x7104f}, {0x71360, 0x71368}, - {0x716eb, 0x716ed}, {0x717d4, 0x717d6}, {0x717d8, 0x717da}, {0x71800, 0x7180a}, - {0x71aa0, 0x71aa6}, {0x71aa8, 0x71aad}, {0x71b5a, 0x71b60}, {0x71bfc, 0x71bff}, - {0x71c3b, 0x71c3f}, {0x71cc0, 0x71cc7}, {0x72010, 0x72027}, {0x72030, 0x72043}, - {0x72045, 0x72051}, {0x72053, 0x7205e}, {0x72308, 0x7230b}, {0x72768, 0x72775}, - {0x727e6, 0x727ef}, {0x72983, 0x72998}, {0x729d8, 0x729db}, {0x72cf9, 0x72cfc}, - {0x72e00, 0x72e2e}, {0x72e30, 0x72e49}, {0x73001, 0x73003}, {0x73008, 0x73011}, - {0x73014, 0x7301f}, {0x7a60d, 0x7a60f}, {0x7a6f2, 0x7a6f7}, {0x7a874, 0x7a877}, - {0x7a8f8, 0x7a8fa}, {0x7a9c1, 0x7a9cd}, {0x7aa5c, 0x7aa5f}, {0x7fe10, 0x7fe19}, - {0x7fe30, 0x7fe52}, {0x7fe54, 0x7fe61}, {0x7ff01, 0x7ff03}, {0x7ff05, 0x7ff0a}, - {0x7ff0c, 0x7ff0f}, {0x7ff3b, 0x7ff3d}, {0x7ff5f, 0x7ff65}, {0x80021, 0x80023}, - {0x80025, 0x8002a}, {0x8002c, 0x8002f}, {0x8005b, 0x8005d}, {0x8055a, 0x8055f}, - {0x8066a, 0x8066d}, {0x80700, 0x8070d}, {0x807f7, 0x807f9}, {0x80830, 0x8083e}, - {0x80f04, 0x80f12}, {0x80f3a, 0x80f3d}, {0x80fd0, 0x80fd4}, {0x8104a, 0x8104f}, - {0x81360, 0x81368}, {0x816eb, 0x816ed}, {0x817d4, 0x817d6}, {0x817d8, 0x817da}, - {0x81800, 0x8180a}, {0x81aa0, 0x81aa6}, {0x81aa8, 0x81aad}, {0x81b5a, 0x81b60}, - {0x81bfc, 0x81bff}, {0x81c3b, 0x81c3f}, {0x81cc0, 0x81cc7}, {0x82010, 0x82027}, - {0x82030, 0x82043}, {0x82045, 0x82051}, {0x82053, 0x8205e}, {0x82308, 0x8230b}, - {0x82768, 0x82775}, {0x827e6, 0x827ef}, {0x82983, 0x82998}, {0x829d8, 0x829db}, - {0x82cf9, 0x82cfc}, {0x82e00, 0x82e2e}, {0x82e30, 0x82e49}, {0x83001, 0x83003}, - {0x83008, 0x83011}, {0x83014, 0x8301f}, {0x8a60d, 0x8a60f}, {0x8a6f2, 0x8a6f7}, - {0x8a874, 0x8a877}, {0x8a8f8, 0x8a8fa}, {0x8a9c1, 0x8a9cd}, {0x8aa5c, 0x8aa5f}, - {0x8fe10, 0x8fe19}, {0x8fe30, 0x8fe52}, {0x8fe54, 0x8fe61}, {0x8ff01, 0x8ff03}, - {0x8ff05, 0x8ff0a}, {0x8ff0c, 0x8ff0f}, {0x8ff3b, 0x8ff3d}, {0x8ff5f, 0x8ff65}, - {0x90021, 0x90023}, {0x90025, 0x9002a}, {0x9002c, 0x9002f}, {0x9005b, 0x9005d}, - {0x9055a, 0x9055f}, {0x9066a, 0x9066d}, {0x90700, 0x9070d}, {0x907f7, 0x907f9}, - {0x90830, 0x9083e}, {0x90f04, 0x90f12}, {0x90f3a, 0x90f3d}, {0x90fd0, 0x90fd4}, - {0x9104a, 0x9104f}, {0x91360, 0x91368}, {0x916eb, 0x916ed}, {0x917d4, 0x917d6}, - {0x917d8, 0x917da}, {0x91800, 0x9180a}, {0x91aa0, 0x91aa6}, {0x91aa8, 0x91aad}, - {0x91b5a, 0x91b60}, {0x91bfc, 0x91bff}, {0x91c3b, 0x91c3f}, {0x91cc0, 0x91cc7}, - {0x92010, 0x92027}, {0x92030, 0x92043}, {0x92045, 0x92051}, {0x92053, 0x9205e}, - {0x92308, 0x9230b}, {0x92768, 0x92775}, {0x927e6, 0x927ef}, {0x92983, 0x92998}, - {0x929d8, 0x929db}, {0x92cf9, 0x92cfc}, {0x92e00, 0x92e2e}, {0x92e30, 0x92e49}, - {0x93001, 0x93003}, {0x93008, 0x93011}, {0x93014, 0x9301f}, {0x9a60d, 0x9a60f}, - {0x9a6f2, 0x9a6f7}, {0x9a874, 0x9a877}, {0x9a8f8, 0x9a8fa}, {0x9a9c1, 0x9a9cd}, - {0x9aa5c, 0x9aa5f}, {0x9fe10, 0x9fe19}, {0x9fe30, 0x9fe52}, {0x9fe54, 0x9fe61}, - {0x9ff01, 0x9ff03}, {0x9ff05, 0x9ff0a}, {0x9ff0c, 0x9ff0f}, {0x9ff3b, 0x9ff3d}, - {0x9ff5f, 0x9ff65}, {0xa0021, 0xa0023}, {0xa0025, 0xa002a}, {0xa002c, 0xa002f}, - {0xa005b, 0xa005d}, {0xa055a, 0xa055f}, {0xa066a, 0xa066d}, {0xa0700, 0xa070d}, - {0xa07f7, 0xa07f9}, {0xa0830, 0xa083e}, {0xa0f04, 0xa0f12}, {0xa0f3a, 0xa0f3d}, - {0xa0fd0, 0xa0fd4}, {0xa104a, 0xa104f}, {0xa1360, 0xa1368}, {0xa16eb, 0xa16ed}, - {0xa17d4, 0xa17d6}, {0xa17d8, 0xa17da}, {0xa1800, 0xa180a}, {0xa1aa0, 0xa1aa6}, - {0xa1aa8, 0xa1aad}, {0xa1b5a, 0xa1b60}, {0xa1bfc, 0xa1bff}, {0xa1c3b, 0xa1c3f}, - {0xa1cc0, 0xa1cc7}, {0xa2010, 0xa2027}, {0xa2030, 0xa2043}, {0xa2045, 0xa2051}, - {0xa2053, 0xa205e}, {0xa2308, 0xa230b}, {0xa2768, 0xa2775}, {0xa27e6, 0xa27ef}, - {0xa2983, 0xa2998}, {0xa29d8, 0xa29db}, {0xa2cf9, 0xa2cfc}, {0xa2e00, 0xa2e2e}, - {0xa2e30, 0xa2e49}, {0xa3001, 0xa3003}, {0xa3008, 0xa3011}, {0xa3014, 0xa301f}, - {0xaa60d, 0xaa60f}, {0xaa6f2, 0xaa6f7}, {0xaa874, 0xaa877}, {0xaa8f8, 0xaa8fa}, - {0xaa9c1, 0xaa9cd}, {0xaaa5c, 0xaaa5f}, {0xafe10, 0xafe19}, {0xafe30, 0xafe52}, - {0xafe54, 0xafe61}, {0xaff01, 0xaff03}, {0xaff05, 0xaff0a}, {0xaff0c, 0xaff0f}, - {0xaff3b, 0xaff3d}, {0xaff5f, 0xaff65}, {0xb0021, 0xb0023}, {0xb0025, 0xb002a}, - {0xb002c, 0xb002f}, {0xb005b, 0xb005d}, {0xb055a, 0xb055f}, {0xb066a, 0xb066d}, - {0xb0700, 0xb070d}, {0xb07f7, 0xb07f9}, {0xb0830, 0xb083e}, {0xb0f04, 0xb0f12}, - {0xb0f3a, 0xb0f3d}, {0xb0fd0, 0xb0fd4}, {0xb104a, 0xb104f}, {0xb1360, 0xb1368}, - {0xb16eb, 0xb16ed}, {0xb17d4, 0xb17d6}, {0xb17d8, 0xb17da}, {0xb1800, 0xb180a}, - {0xb1aa0, 0xb1aa6}, {0xb1aa8, 0xb1aad}, {0xb1b5a, 0xb1b60}, {0xb1bfc, 0xb1bff}, - {0xb1c3b, 0xb1c3f}, {0xb1cc0, 0xb1cc7}, {0xb2010, 0xb2027}, {0xb2030, 0xb2043}, - {0xb2045, 0xb2051}, {0xb2053, 0xb205e}, {0xb2308, 0xb230b}, {0xb2768, 0xb2775}, - {0xb27e6, 0xb27ef}, {0xb2983, 0xb2998}, {0xb29d8, 0xb29db}, {0xb2cf9, 0xb2cfc}, - {0xb2e00, 0xb2e2e}, {0xb2e30, 0xb2e49}, {0xb3001, 0xb3003}, {0xb3008, 0xb3011}, - {0xb3014, 0xb301f}, {0xba60d, 0xba60f}, {0xba6f2, 0xba6f7}, {0xba874, 0xba877}, - {0xba8f8, 0xba8fa}, {0xba9c1, 0xba9cd}, {0xbaa5c, 0xbaa5f}, {0xbfe10, 0xbfe19}, - {0xbfe30, 0xbfe52}, {0xbfe54, 0xbfe61}, {0xbff01, 0xbff03}, {0xbff05, 0xbff0a}, - {0xbff0c, 0xbff0f}, {0xbff3b, 0xbff3d}, {0xbff5f, 0xbff65}, {0xc0021, 0xc0023}, - {0xc0025, 0xc002a}, {0xc002c, 0xc002f}, {0xc005b, 0xc005d}, {0xc055a, 0xc055f}, - {0xc066a, 0xc066d}, {0xc0700, 0xc070d}, {0xc07f7, 0xc07f9}, {0xc0830, 0xc083e}, - {0xc0f04, 0xc0f12}, {0xc0f3a, 0xc0f3d}, {0xc0fd0, 0xc0fd4}, {0xc104a, 0xc104f}, - {0xc1360, 0xc1368}, {0xc16eb, 0xc16ed}, {0xc17d4, 0xc17d6}, {0xc17d8, 0xc17da}, - {0xc1800, 0xc180a}, {0xc1aa0, 0xc1aa6}, {0xc1aa8, 0xc1aad}, {0xc1b5a, 0xc1b60}, - {0xc1bfc, 0xc1bff}, {0xc1c3b, 0xc1c3f}, {0xc1cc0, 0xc1cc7}, {0xc2010, 0xc2027}, - {0xc2030, 0xc2043}, {0xc2045, 0xc2051}, {0xc2053, 0xc205e}, {0xc2308, 0xc230b}, - {0xc2768, 0xc2775}, {0xc27e6, 0xc27ef}, {0xc2983, 0xc2998}, {0xc29d8, 0xc29db}, - {0xc2cf9, 0xc2cfc}, {0xc2e00, 0xc2e2e}, {0xc2e30, 0xc2e49}, {0xc3001, 0xc3003}, - {0xc3008, 0xc3011}, {0xc3014, 0xc301f}, {0xca60d, 0xca60f}, {0xca6f2, 0xca6f7}, - {0xca874, 0xca877}, {0xca8f8, 0xca8fa}, {0xca9c1, 0xca9cd}, {0xcaa5c, 0xcaa5f}, - {0xcfe10, 0xcfe19}, {0xcfe30, 0xcfe52}, {0xcfe54, 0xcfe61}, {0xcff01, 0xcff03}, - {0xcff05, 0xcff0a}, {0xcff0c, 0xcff0f}, {0xcff3b, 0xcff3d}, {0xcff5f, 0xcff65}, - {0xd0021, 0xd0023}, {0xd0025, 0xd002a}, {0xd002c, 0xd002f}, {0xd005b, 0xd005d}, - {0xd055a, 0xd055f}, {0xd066a, 0xd066d}, {0xd0700, 0xd070d}, {0xd07f7, 0xd07f9}, - {0xd0830, 0xd083e}, {0xd0f04, 0xd0f12}, {0xd0f3a, 0xd0f3d}, {0xd0fd0, 0xd0fd4}, - {0xd104a, 0xd104f}, {0xd1360, 0xd1368}, {0xd16eb, 0xd16ed}, {0xd17d4, 0xd17d6}, - {0xd17d8, 0xd17da}, {0xd1800, 0xd180a}, {0xd1aa0, 0xd1aa6}, {0xd1aa8, 0xd1aad}, - {0xd1b5a, 0xd1b60}, {0xd1bfc, 0xd1bff}, {0xd1c3b, 0xd1c3f}, {0xd1cc0, 0xd1cc7}, - {0xd2010, 0xd2027}, {0xd2030, 0xd2043}, {0xd2045, 0xd2051}, {0xd2053, 0xd205e}, - {0xd2308, 0xd230b}, {0xd2768, 0xd2775}, {0xd27e6, 0xd27ef}, {0xd2983, 0xd2998}, - {0xd29d8, 0xd29db}, {0xd2cf9, 0xd2cfc}, {0xd2e00, 0xd2e2e}, {0xd2e30, 0xd2e49}, - {0xd3001, 0xd3003}, {0xd3008, 0xd3011}, {0xd3014, 0xd301f}, {0xda60d, 0xda60f}, - {0xda6f2, 0xda6f7}, {0xda874, 0xda877}, {0xda8f8, 0xda8fa}, {0xda9c1, 0xda9cd}, - {0xdaa5c, 0xdaa5f}, {0xdfe10, 0xdfe19}, {0xdfe30, 0xdfe52}, {0xdfe54, 0xdfe61}, - {0xdff01, 0xdff03}, {0xdff05, 0xdff0a}, {0xdff0c, 0xdff0f}, {0xdff3b, 0xdff3d}, - {0xdff5f, 0xdff65}, {0xe0021, 0xe0023}, {0xe0025, 0xe002a}, {0xe002c, 0xe002f}, - {0xe005b, 0xe005d}, {0xe055a, 0xe055f}, {0xe066a, 0xe066d}, {0xe0700, 0xe070d}, - {0xe07f7, 0xe07f9}, {0xe0830, 0xe083e}, {0xe0f04, 0xe0f12}, {0xe0f3a, 0xe0f3d}, - {0xe0fd0, 0xe0fd4}, {0xe104a, 0xe104f}, {0xe1360, 0xe1368}, {0xe16eb, 0xe16ed}, - {0xe17d4, 0xe17d6}, {0xe17d8, 0xe17da}, {0xe1800, 0xe180a}, {0xe1aa0, 0xe1aa6}, - {0xe1aa8, 0xe1aad}, {0xe1b5a, 0xe1b60}, {0xe1bfc, 0xe1bff}, {0xe1c3b, 0xe1c3f}, - {0xe1cc0, 0xe1cc7}, {0xe2010, 0xe2027}, {0xe2030, 0xe2043}, {0xe2045, 0xe2051}, - {0xe2053, 0xe205e}, {0xe2308, 0xe230b}, {0xe2768, 0xe2775}, {0xe27e6, 0xe27ef}, - {0xe2983, 0xe2998}, {0xe29d8, 0xe29db}, {0xe2cf9, 0xe2cfc}, {0xe2e00, 0xe2e2e}, - {0xe2e30, 0xe2e49}, {0xe3001, 0xe3003}, {0xe3008, 0xe3011}, {0xe3014, 0xe301f}, - {0xea60d, 0xea60f}, {0xea6f2, 0xea6f7}, {0xea874, 0xea877}, {0xea8f8, 0xea8fa}, - {0xea9c1, 0xea9cd}, {0xeaa5c, 0xeaa5f}, {0xefe10, 0xefe19}, {0xefe30, 0xefe52}, - {0xefe54, 0xefe61}, {0xeff01, 0xeff03}, {0xeff05, 0xeff0a}, {0xeff0c, 0xeff0f}, - {0xeff3b, 0xeff3d}, {0xeff5f, 0xeff65}, {0xf0021, 0xf0023}, {0xf0025, 0xf002a}, - {0xf002c, 0xf002f}, {0xf005b, 0xf005d}, {0xf055a, 0xf055f}, {0xf066a, 0xf066d}, - {0xf0700, 0xf070d}, {0xf07f7, 0xf07f9}, {0xf0830, 0xf083e}, {0xf0f04, 0xf0f12}, - {0xf0f3a, 0xf0f3d}, {0xf0fd0, 0xf0fd4}, {0xf104a, 0xf104f}, {0xf1360, 0xf1368}, - {0xf16eb, 0xf16ed}, {0xf17d4, 0xf17d6}, {0xf17d8, 0xf17da}, {0xf1800, 0xf180a}, - {0xf1aa0, 0xf1aa6}, {0xf1aa8, 0xf1aad}, {0xf1b5a, 0xf1b60}, {0xf1bfc, 0xf1bff}, - {0xf1c3b, 0xf1c3f}, {0xf1cc0, 0xf1cc7}, {0xf2010, 0xf2027}, {0xf2030, 0xf2043}, - {0xf2045, 0xf2051}, {0xf2053, 0xf205e}, {0xf2308, 0xf230b}, {0xf2768, 0xf2775}, - {0xf27e6, 0xf27ef}, {0xf2983, 0xf2998}, {0xf29d8, 0xf29db}, {0xf2cf9, 0xf2cfc}, - {0xf2e00, 0xf2e2e}, {0xf2e30, 0xf2e49}, {0xf3001, 0xf3003}, {0xf3008, 0xf3011}, - {0xf3014, 0xf301f}, {0xfa60d, 0xfa60f}, {0xfa6f2, 0xfa6f7}, {0xfa874, 0xfa877}, - {0xfa8f8, 0xfa8fa}, {0xfa9c1, 0xfa9cd}, {0xfaa5c, 0xfaa5f}, {0xffe10, 0xffe19}, - {0xffe30, 0xffe52}, {0xffe54, 0xffe61}, {0xfff01, 0xfff03}, {0xfff05, 0xfff0a}, - {0xfff0c, 0xfff0f}, {0xfff3b, 0xfff3d}, {0xfff5f, 0xfff65}, {0x100021, 0x100023}, - {0x100025, 0x10002a}, {0x10002c, 0x10002f}, {0x10005b, 0x10005d}, {0x10055a, 0x10055f}, - {0x10066a, 0x10066d}, {0x100700, 0x10070d}, {0x1007f7, 0x1007f9}, {0x100830, 0x10083e}, - {0x100f04, 0x100f12}, {0x100f3a, 0x100f3d}, {0x100fd0, 0x100fd4}, {0x10104a, 0x10104f}, - {0x101360, 0x101368}, {0x1016eb, 0x1016ed}, {0x1017d4, 0x1017d6}, {0x1017d8, 0x1017da}, - {0x101800, 0x10180a}, {0x101aa0, 0x101aa6}, {0x101aa8, 0x101aad}, {0x101b5a, 0x101b60}, - {0x101bfc, 0x101bff}, {0x101c3b, 0x101c3f}, {0x101cc0, 0x101cc7}, {0x102010, 0x102027}, - {0x102030, 0x102043}, {0x102045, 0x102051}, {0x102053, 0x10205e}, {0x102308, 0x10230b}, - {0x102768, 0x102775}, {0x1027e6, 0x1027ef}, {0x102983, 0x102998}, {0x1029d8, 0x1029db}, - {0x102cf9, 0x102cfc}, {0x102e00, 0x102e2e}, {0x102e30, 0x102e49}, {0x103001, 0x103003}, - {0x103008, 0x103011}, {0x103014, 0x10301f}, {0x10a60d, 0x10a60f}, {0x10a6f2, 0x10a6f7}, - {0x10a874, 0x10a877}, {0x10a8f8, 0x10a8fa}, {0x10a9c1, 0x10a9cd}, {0x10aa5c, 0x10aa5f}, - {0x10fe10, 0x10fe19}, {0x10fe30, 0x10fe52}, {0x10fe54, 0x10fe61}, {0x10ff01, 0x10ff03}, - {0x10ff05, 0x10ff0a}, {0x10ff0c, 0x10ff0f}, {0x10ff3b, 0x10ff3d}, {0x10ff5f, 0x10ff65} + ,{0x10100, 0x10102}, {0x10a50, 0x10a58}, {0x10af0, 0x10af6}, {0x10b39, 0x10b3f}, + {0x10b99, 0x10b9c}, {0x11047, 0x1104d}, {0x110be, 0x110c1}, {0x11140, 0x11143}, + {0x111c5, 0x111c9}, {0x111dd, 0x111df}, {0x11238, 0x1123d}, {0x1144b, 0x1144f}, + {0x115c1, 0x115d7}, {0x11641, 0x11643}, {0x11660, 0x1166c}, {0x1173c, 0x1173e}, + {0x11a3f, 0x11a46}, {0x11a9a, 0x11a9c}, {0x11a9e, 0x11aa2}, {0x11c41, 0x11c45}, + {0x12470, 0x12474}, {0x16b37, 0x16b3b}, {0x1da87, 0x1da8b} #endif }; @@ -2053,198 +380,9 @@ static const chr punctCharTable[] = { 0xaade, 0xaadf, 0xaaf0, 0xaaf1, 0xabeb, 0xfd3e, 0xfd3f, 0xfe63, 0xfe68, 0xfe6a, 0xfe6b, 0xff1a, 0xff1b, 0xff1f, 0xff20, 0xff3f, 0xff5b, 0xff5d #if TCL_UTF_MAX > 4 - ,0x1003a, 0x1003b, 0x1003f, 0x10040, 0x1005f, 0x1007b, 0x1007d, 0x100a1, 0x100a7, - 0x100ab, 0x100b6, 0x100b7, 0x100bb, 0x100bf, 0x1037e, 0x10387, 0x10589, 0x1058a, - 0x105be, 0x105c0, 0x105c3, 0x105c6, 0x105f3, 0x105f4, 0x10609, 0x1060a, 0x1060c, - 0x1060d, 0x1061b, 0x1061e, 0x1061f, 0x106d4, 0x1085e, 0x10964, 0x10965, 0x10970, - 0x109fd, 0x10af0, 0x10df4, 0x10e4f, 0x10e5a, 0x10e5b, 0x10f14, 0x10f85, 0x10fd9, - 0x10fda, 0x110fb, 0x11400, 0x1166d, 0x1166e, 0x1169b, 0x1169c, 0x11735, 0x11736, - 0x11944, 0x11945, 0x11a1e, 0x11a1f, 0x11c7e, 0x11c7f, 0x11cd3, 0x1207d, 0x1207e, - 0x1208d, 0x1208e, 0x12329, 0x1232a, 0x127c5, 0x127c6, 0x129fc, 0x129fd, 0x12cfe, - 0x12cff, 0x12d70, 0x13030, 0x1303d, 0x130a0, 0x130fb, 0x1a4fe, 0x1a4ff, 0x1a673, - 0x1a67e, 0x1a8ce, 0x1a8cf, 0x1a8fc, 0x1a92e, 0x1a92f, 0x1a95f, 0x1a9de, 0x1a9df, - 0x1aade, 0x1aadf, 0x1aaf0, 0x1aaf1, 0x1abeb, 0x1fd3e, 0x1fd3f, 0x1fe63, 0x1fe68, - 0x1fe6a, 0x1fe6b, 0x1ff1a, 0x1ff1b, 0x1ff1f, 0x1ff20, 0x1ff3f, 0x1ff5b, 0x1ff5d, - 0x2003a, 0x2003b, 0x2003f, 0x20040, 0x2005f, 0x2007b, 0x2007d, 0x200a1, 0x200a7, - 0x200ab, 0x200b6, 0x200b7, 0x200bb, 0x200bf, 0x2037e, 0x20387, 0x20589, 0x2058a, - 0x205be, 0x205c0, 0x205c3, 0x205c6, 0x205f3, 0x205f4, 0x20609, 0x2060a, 0x2060c, - 0x2060d, 0x2061b, 0x2061e, 0x2061f, 0x206d4, 0x2085e, 0x20964, 0x20965, 0x20970, - 0x209fd, 0x20af0, 0x20df4, 0x20e4f, 0x20e5a, 0x20e5b, 0x20f14, 0x20f85, 0x20fd9, - 0x20fda, 0x210fb, 0x21400, 0x2166d, 0x2166e, 0x2169b, 0x2169c, 0x21735, 0x21736, - 0x21944, 0x21945, 0x21a1e, 0x21a1f, 0x21c7e, 0x21c7f, 0x21cd3, 0x2207d, 0x2207e, - 0x2208d, 0x2208e, 0x22329, 0x2232a, 0x227c5, 0x227c6, 0x229fc, 0x229fd, 0x22cfe, - 0x22cff, 0x22d70, 0x23030, 0x2303d, 0x230a0, 0x230fb, 0x2a4fe, 0x2a4ff, 0x2a673, - 0x2a67e, 0x2a8ce, 0x2a8cf, 0x2a8fc, 0x2a92e, 0x2a92f, 0x2a95f, 0x2a9de, 0x2a9df, - 0x2aade, 0x2aadf, 0x2aaf0, 0x2aaf1, 0x2abeb, 0x2fd3e, 0x2fd3f, 0x2fe63, 0x2fe68, - 0x2fe6a, 0x2fe6b, 0x2ff1a, 0x2ff1b, 0x2ff1f, 0x2ff20, 0x2ff3f, 0x2ff5b, 0x2ff5d, - 0x3003a, 0x3003b, 0x3003f, 0x30040, 0x3005f, 0x3007b, 0x3007d, 0x300a1, 0x300a7, - 0x300ab, 0x300b6, 0x300b7, 0x300bb, 0x300bf, 0x3037e, 0x30387, 0x30589, 0x3058a, - 0x305be, 0x305c0, 0x305c3, 0x305c6, 0x305f3, 0x305f4, 0x30609, 0x3060a, 0x3060c, - 0x3060d, 0x3061b, 0x3061e, 0x3061f, 0x306d4, 0x3085e, 0x30964, 0x30965, 0x30970, - 0x309fd, 0x30af0, 0x30df4, 0x30e4f, 0x30e5a, 0x30e5b, 0x30f14, 0x30f85, 0x30fd9, - 0x30fda, 0x310fb, 0x31400, 0x3166d, 0x3166e, 0x3169b, 0x3169c, 0x31735, 0x31736, - 0x31944, 0x31945, 0x31a1e, 0x31a1f, 0x31c7e, 0x31c7f, 0x31cd3, 0x3207d, 0x3207e, - 0x3208d, 0x3208e, 0x32329, 0x3232a, 0x327c5, 0x327c6, 0x329fc, 0x329fd, 0x32cfe, - 0x32cff, 0x32d70, 0x33030, 0x3303d, 0x330a0, 0x330fb, 0x3a4fe, 0x3a4ff, 0x3a673, - 0x3a67e, 0x3a8ce, 0x3a8cf, 0x3a8fc, 0x3a92e, 0x3a92f, 0x3a95f, 0x3a9de, 0x3a9df, - 0x3aade, 0x3aadf, 0x3aaf0, 0x3aaf1, 0x3abeb, 0x3fd3e, 0x3fd3f, 0x3fe63, 0x3fe68, - 0x3fe6a, 0x3fe6b, 0x3ff1a, 0x3ff1b, 0x3ff1f, 0x3ff20, 0x3ff3f, 0x3ff5b, 0x3ff5d, - 0x4003a, 0x4003b, 0x4003f, 0x40040, 0x4005f, 0x4007b, 0x4007d, 0x400a1, 0x400a7, - 0x400ab, 0x400b6, 0x400b7, 0x400bb, 0x400bf, 0x4037e, 0x40387, 0x40589, 0x4058a, - 0x405be, 0x405c0, 0x405c3, 0x405c6, 0x405f3, 0x405f4, 0x40609, 0x4060a, 0x4060c, - 0x4060d, 0x4061b, 0x4061e, 0x4061f, 0x406d4, 0x4085e, 0x40964, 0x40965, 0x40970, - 0x409fd, 0x40af0, 0x40df4, 0x40e4f, 0x40e5a, 0x40e5b, 0x40f14, 0x40f85, 0x40fd9, - 0x40fda, 0x410fb, 0x41400, 0x4166d, 0x4166e, 0x4169b, 0x4169c, 0x41735, 0x41736, - 0x41944, 0x41945, 0x41a1e, 0x41a1f, 0x41c7e, 0x41c7f, 0x41cd3, 0x4207d, 0x4207e, - 0x4208d, 0x4208e, 0x42329, 0x4232a, 0x427c5, 0x427c6, 0x429fc, 0x429fd, 0x42cfe, - 0x42cff, 0x42d70, 0x43030, 0x4303d, 0x430a0, 0x430fb, 0x4a4fe, 0x4a4ff, 0x4a673, - 0x4a67e, 0x4a8ce, 0x4a8cf, 0x4a8fc, 0x4a92e, 0x4a92f, 0x4a95f, 0x4a9de, 0x4a9df, - 0x4aade, 0x4aadf, 0x4aaf0, 0x4aaf1, 0x4abeb, 0x4fd3e, 0x4fd3f, 0x4fe63, 0x4fe68, - 0x4fe6a, 0x4fe6b, 0x4ff1a, 0x4ff1b, 0x4ff1f, 0x4ff20, 0x4ff3f, 0x4ff5b, 0x4ff5d, - 0x5003a, 0x5003b, 0x5003f, 0x50040, 0x5005f, 0x5007b, 0x5007d, 0x500a1, 0x500a7, - 0x500ab, 0x500b6, 0x500b7, 0x500bb, 0x500bf, 0x5037e, 0x50387, 0x50589, 0x5058a, - 0x505be, 0x505c0, 0x505c3, 0x505c6, 0x505f3, 0x505f4, 0x50609, 0x5060a, 0x5060c, - 0x5060d, 0x5061b, 0x5061e, 0x5061f, 0x506d4, 0x5085e, 0x50964, 0x50965, 0x50970, - 0x509fd, 0x50af0, 0x50df4, 0x50e4f, 0x50e5a, 0x50e5b, 0x50f14, 0x50f85, 0x50fd9, - 0x50fda, 0x510fb, 0x51400, 0x5166d, 0x5166e, 0x5169b, 0x5169c, 0x51735, 0x51736, - 0x51944, 0x51945, 0x51a1e, 0x51a1f, 0x51c7e, 0x51c7f, 0x51cd3, 0x5207d, 0x5207e, - 0x5208d, 0x5208e, 0x52329, 0x5232a, 0x527c5, 0x527c6, 0x529fc, 0x529fd, 0x52cfe, - 0x52cff, 0x52d70, 0x53030, 0x5303d, 0x530a0, 0x530fb, 0x5a4fe, 0x5a4ff, 0x5a673, - 0x5a67e, 0x5a8ce, 0x5a8cf, 0x5a8fc, 0x5a92e, 0x5a92f, 0x5a95f, 0x5a9de, 0x5a9df, - 0x5aade, 0x5aadf, 0x5aaf0, 0x5aaf1, 0x5abeb, 0x5fd3e, 0x5fd3f, 0x5fe63, 0x5fe68, - 0x5fe6a, 0x5fe6b, 0x5ff1a, 0x5ff1b, 0x5ff1f, 0x5ff20, 0x5ff3f, 0x5ff5b, 0x5ff5d, - 0x6003a, 0x6003b, 0x6003f, 0x60040, 0x6005f, 0x6007b, 0x6007d, 0x600a1, 0x600a7, - 0x600ab, 0x600b6, 0x600b7, 0x600bb, 0x600bf, 0x6037e, 0x60387, 0x60589, 0x6058a, - 0x605be, 0x605c0, 0x605c3, 0x605c6, 0x605f3, 0x605f4, 0x60609, 0x6060a, 0x6060c, - 0x6060d, 0x6061b, 0x6061e, 0x6061f, 0x606d4, 0x6085e, 0x60964, 0x60965, 0x60970, - 0x609fd, 0x60af0, 0x60df4, 0x60e4f, 0x60e5a, 0x60e5b, 0x60f14, 0x60f85, 0x60fd9, - 0x60fda, 0x610fb, 0x61400, 0x6166d, 0x6166e, 0x6169b, 0x6169c, 0x61735, 0x61736, - 0x61944, 0x61945, 0x61a1e, 0x61a1f, 0x61c7e, 0x61c7f, 0x61cd3, 0x6207d, 0x6207e, - 0x6208d, 0x6208e, 0x62329, 0x6232a, 0x627c5, 0x627c6, 0x629fc, 0x629fd, 0x62cfe, - 0x62cff, 0x62d70, 0x63030, 0x6303d, 0x630a0, 0x630fb, 0x6a4fe, 0x6a4ff, 0x6a673, - 0x6a67e, 0x6a8ce, 0x6a8cf, 0x6a8fc, 0x6a92e, 0x6a92f, 0x6a95f, 0x6a9de, 0x6a9df, - 0x6aade, 0x6aadf, 0x6aaf0, 0x6aaf1, 0x6abeb, 0x6fd3e, 0x6fd3f, 0x6fe63, 0x6fe68, - 0x6fe6a, 0x6fe6b, 0x6ff1a, 0x6ff1b, 0x6ff1f, 0x6ff20, 0x6ff3f, 0x6ff5b, 0x6ff5d, - 0x7003a, 0x7003b, 0x7003f, 0x70040, 0x7005f, 0x7007b, 0x7007d, 0x700a1, 0x700a7, - 0x700ab, 0x700b6, 0x700b7, 0x700bb, 0x700bf, 0x7037e, 0x70387, 0x70589, 0x7058a, - 0x705be, 0x705c0, 0x705c3, 0x705c6, 0x705f3, 0x705f4, 0x70609, 0x7060a, 0x7060c, - 0x7060d, 0x7061b, 0x7061e, 0x7061f, 0x706d4, 0x7085e, 0x70964, 0x70965, 0x70970, - 0x709fd, 0x70af0, 0x70df4, 0x70e4f, 0x70e5a, 0x70e5b, 0x70f14, 0x70f85, 0x70fd9, - 0x70fda, 0x710fb, 0x71400, 0x7166d, 0x7166e, 0x7169b, 0x7169c, 0x71735, 0x71736, - 0x71944, 0x71945, 0x71a1e, 0x71a1f, 0x71c7e, 0x71c7f, 0x71cd3, 0x7207d, 0x7207e, - 0x7208d, 0x7208e, 0x72329, 0x7232a, 0x727c5, 0x727c6, 0x729fc, 0x729fd, 0x72cfe, - 0x72cff, 0x72d70, 0x73030, 0x7303d, 0x730a0, 0x730fb, 0x7a4fe, 0x7a4ff, 0x7a673, - 0x7a67e, 0x7a8ce, 0x7a8cf, 0x7a8fc, 0x7a92e, 0x7a92f, 0x7a95f, 0x7a9de, 0x7a9df, - 0x7aade, 0x7aadf, 0x7aaf0, 0x7aaf1, 0x7abeb, 0x7fd3e, 0x7fd3f, 0x7fe63, 0x7fe68, - 0x7fe6a, 0x7fe6b, 0x7ff1a, 0x7ff1b, 0x7ff1f, 0x7ff20, 0x7ff3f, 0x7ff5b, 0x7ff5d, - 0x8003a, 0x8003b, 0x8003f, 0x80040, 0x8005f, 0x8007b, 0x8007d, 0x800a1, 0x800a7, - 0x800ab, 0x800b6, 0x800b7, 0x800bb, 0x800bf, 0x8037e, 0x80387, 0x80589, 0x8058a, - 0x805be, 0x805c0, 0x805c3, 0x805c6, 0x805f3, 0x805f4, 0x80609, 0x8060a, 0x8060c, - 0x8060d, 0x8061b, 0x8061e, 0x8061f, 0x806d4, 0x8085e, 0x80964, 0x80965, 0x80970, - 0x809fd, 0x80af0, 0x80df4, 0x80e4f, 0x80e5a, 0x80e5b, 0x80f14, 0x80f85, 0x80fd9, - 0x80fda, 0x810fb, 0x81400, 0x8166d, 0x8166e, 0x8169b, 0x8169c, 0x81735, 0x81736, - 0x81944, 0x81945, 0x81a1e, 0x81a1f, 0x81c7e, 0x81c7f, 0x81cd3, 0x8207d, 0x8207e, - 0x8208d, 0x8208e, 0x82329, 0x8232a, 0x827c5, 0x827c6, 0x829fc, 0x829fd, 0x82cfe, - 0x82cff, 0x82d70, 0x83030, 0x8303d, 0x830a0, 0x830fb, 0x8a4fe, 0x8a4ff, 0x8a673, - 0x8a67e, 0x8a8ce, 0x8a8cf, 0x8a8fc, 0x8a92e, 0x8a92f, 0x8a95f, 0x8a9de, 0x8a9df, - 0x8aade, 0x8aadf, 0x8aaf0, 0x8aaf1, 0x8abeb, 0x8fd3e, 0x8fd3f, 0x8fe63, 0x8fe68, - 0x8fe6a, 0x8fe6b, 0x8ff1a, 0x8ff1b, 0x8ff1f, 0x8ff20, 0x8ff3f, 0x8ff5b, 0x8ff5d, - 0x9003a, 0x9003b, 0x9003f, 0x90040, 0x9005f, 0x9007b, 0x9007d, 0x900a1, 0x900a7, - 0x900ab, 0x900b6, 0x900b7, 0x900bb, 0x900bf, 0x9037e, 0x90387, 0x90589, 0x9058a, - 0x905be, 0x905c0, 0x905c3, 0x905c6, 0x905f3, 0x905f4, 0x90609, 0x9060a, 0x9060c, - 0x9060d, 0x9061b, 0x9061e, 0x9061f, 0x906d4, 0x9085e, 0x90964, 0x90965, 0x90970, - 0x909fd, 0x90af0, 0x90df4, 0x90e4f, 0x90e5a, 0x90e5b, 0x90f14, 0x90f85, 0x90fd9, - 0x90fda, 0x910fb, 0x91400, 0x9166d, 0x9166e, 0x9169b, 0x9169c, 0x91735, 0x91736, - 0x91944, 0x91945, 0x91a1e, 0x91a1f, 0x91c7e, 0x91c7f, 0x91cd3, 0x9207d, 0x9207e, - 0x9208d, 0x9208e, 0x92329, 0x9232a, 0x927c5, 0x927c6, 0x929fc, 0x929fd, 0x92cfe, - 0x92cff, 0x92d70, 0x93030, 0x9303d, 0x930a0, 0x930fb, 0x9a4fe, 0x9a4ff, 0x9a673, - 0x9a67e, 0x9a8ce, 0x9a8cf, 0x9a8fc, 0x9a92e, 0x9a92f, 0x9a95f, 0x9a9de, 0x9a9df, - 0x9aade, 0x9aadf, 0x9aaf0, 0x9aaf1, 0x9abeb, 0x9fd3e, 0x9fd3f, 0x9fe63, 0x9fe68, - 0x9fe6a, 0x9fe6b, 0x9ff1a, 0x9ff1b, 0x9ff1f, 0x9ff20, 0x9ff3f, 0x9ff5b, 0x9ff5d, - 0xa003a, 0xa003b, 0xa003f, 0xa0040, 0xa005f, 0xa007b, 0xa007d, 0xa00a1, 0xa00a7, - 0xa00ab, 0xa00b6, 0xa00b7, 0xa00bb, 0xa00bf, 0xa037e, 0xa0387, 0xa0589, 0xa058a, - 0xa05be, 0xa05c0, 0xa05c3, 0xa05c6, 0xa05f3, 0xa05f4, 0xa0609, 0xa060a, 0xa060c, - 0xa060d, 0xa061b, 0xa061e, 0xa061f, 0xa06d4, 0xa085e, 0xa0964, 0xa0965, 0xa0970, - 0xa09fd, 0xa0af0, 0xa0df4, 0xa0e4f, 0xa0e5a, 0xa0e5b, 0xa0f14, 0xa0f85, 0xa0fd9, - 0xa0fda, 0xa10fb, 0xa1400, 0xa166d, 0xa166e, 0xa169b, 0xa169c, 0xa1735, 0xa1736, - 0xa1944, 0xa1945, 0xa1a1e, 0xa1a1f, 0xa1c7e, 0xa1c7f, 0xa1cd3, 0xa207d, 0xa207e, - 0xa208d, 0xa208e, 0xa2329, 0xa232a, 0xa27c5, 0xa27c6, 0xa29fc, 0xa29fd, 0xa2cfe, - 0xa2cff, 0xa2d70, 0xa3030, 0xa303d, 0xa30a0, 0xa30fb, 0xaa4fe, 0xaa4ff, 0xaa673, - 0xaa67e, 0xaa8ce, 0xaa8cf, 0xaa8fc, 0xaa92e, 0xaa92f, 0xaa95f, 0xaa9de, 0xaa9df, - 0xaaade, 0xaaadf, 0xaaaf0, 0xaaaf1, 0xaabeb, 0xafd3e, 0xafd3f, 0xafe63, 0xafe68, - 0xafe6a, 0xafe6b, 0xaff1a, 0xaff1b, 0xaff1f, 0xaff20, 0xaff3f, 0xaff5b, 0xaff5d, - 0xb003a, 0xb003b, 0xb003f, 0xb0040, 0xb005f, 0xb007b, 0xb007d, 0xb00a1, 0xb00a7, - 0xb00ab, 0xb00b6, 0xb00b7, 0xb00bb, 0xb00bf, 0xb037e, 0xb0387, 0xb0589, 0xb058a, - 0xb05be, 0xb05c0, 0xb05c3, 0xb05c6, 0xb05f3, 0xb05f4, 0xb0609, 0xb060a, 0xb060c, - 0xb060d, 0xb061b, 0xb061e, 0xb061f, 0xb06d4, 0xb085e, 0xb0964, 0xb0965, 0xb0970, - 0xb09fd, 0xb0af0, 0xb0df4, 0xb0e4f, 0xb0e5a, 0xb0e5b, 0xb0f14, 0xb0f85, 0xb0fd9, - 0xb0fda, 0xb10fb, 0xb1400, 0xb166d, 0xb166e, 0xb169b, 0xb169c, 0xb1735, 0xb1736, - 0xb1944, 0xb1945, 0xb1a1e, 0xb1a1f, 0xb1c7e, 0xb1c7f, 0xb1cd3, 0xb207d, 0xb207e, - 0xb208d, 0xb208e, 0xb2329, 0xb232a, 0xb27c5, 0xb27c6, 0xb29fc, 0xb29fd, 0xb2cfe, - 0xb2cff, 0xb2d70, 0xb3030, 0xb303d, 0xb30a0, 0xb30fb, 0xba4fe, 0xba4ff, 0xba673, - 0xba67e, 0xba8ce, 0xba8cf, 0xba8fc, 0xba92e, 0xba92f, 0xba95f, 0xba9de, 0xba9df, - 0xbaade, 0xbaadf, 0xbaaf0, 0xbaaf1, 0xbabeb, 0xbfd3e, 0xbfd3f, 0xbfe63, 0xbfe68, - 0xbfe6a, 0xbfe6b, 0xbff1a, 0xbff1b, 0xbff1f, 0xbff20, 0xbff3f, 0xbff5b, 0xbff5d, - 0xc003a, 0xc003b, 0xc003f, 0xc0040, 0xc005f, 0xc007b, 0xc007d, 0xc00a1, 0xc00a7, - 0xc00ab, 0xc00b6, 0xc00b7, 0xc00bb, 0xc00bf, 0xc037e, 0xc0387, 0xc0589, 0xc058a, - 0xc05be, 0xc05c0, 0xc05c3, 0xc05c6, 0xc05f3, 0xc05f4, 0xc0609, 0xc060a, 0xc060c, - 0xc060d, 0xc061b, 0xc061e, 0xc061f, 0xc06d4, 0xc085e, 0xc0964, 0xc0965, 0xc0970, - 0xc09fd, 0xc0af0, 0xc0df4, 0xc0e4f, 0xc0e5a, 0xc0e5b, 0xc0f14, 0xc0f85, 0xc0fd9, - 0xc0fda, 0xc10fb, 0xc1400, 0xc166d, 0xc166e, 0xc169b, 0xc169c, 0xc1735, 0xc1736, - 0xc1944, 0xc1945, 0xc1a1e, 0xc1a1f, 0xc1c7e, 0xc1c7f, 0xc1cd3, 0xc207d, 0xc207e, - 0xc208d, 0xc208e, 0xc2329, 0xc232a, 0xc27c5, 0xc27c6, 0xc29fc, 0xc29fd, 0xc2cfe, - 0xc2cff, 0xc2d70, 0xc3030, 0xc303d, 0xc30a0, 0xc30fb, 0xca4fe, 0xca4ff, 0xca673, - 0xca67e, 0xca8ce, 0xca8cf, 0xca8fc, 0xca92e, 0xca92f, 0xca95f, 0xca9de, 0xca9df, - 0xcaade, 0xcaadf, 0xcaaf0, 0xcaaf1, 0xcabeb, 0xcfd3e, 0xcfd3f, 0xcfe63, 0xcfe68, - 0xcfe6a, 0xcfe6b, 0xcff1a, 0xcff1b, 0xcff1f, 0xcff20, 0xcff3f, 0xcff5b, 0xcff5d, - 0xd003a, 0xd003b, 0xd003f, 0xd0040, 0xd005f, 0xd007b, 0xd007d, 0xd00a1, 0xd00a7, - 0xd00ab, 0xd00b6, 0xd00b7, 0xd00bb, 0xd00bf, 0xd037e, 0xd0387, 0xd0589, 0xd058a, - 0xd05be, 0xd05c0, 0xd05c3, 0xd05c6, 0xd05f3, 0xd05f4, 0xd0609, 0xd060a, 0xd060c, - 0xd060d, 0xd061b, 0xd061e, 0xd061f, 0xd06d4, 0xd085e, 0xd0964, 0xd0965, 0xd0970, - 0xd09fd, 0xd0af0, 0xd0df4, 0xd0e4f, 0xd0e5a, 0xd0e5b, 0xd0f14, 0xd0f85, 0xd0fd9, - 0xd0fda, 0xd10fb, 0xd1400, 0xd166d, 0xd166e, 0xd169b, 0xd169c, 0xd1735, 0xd1736, - 0xd1944, 0xd1945, 0xd1a1e, 0xd1a1f, 0xd1c7e, 0xd1c7f, 0xd1cd3, 0xd207d, 0xd207e, - 0xd208d, 0xd208e, 0xd2329, 0xd232a, 0xd27c5, 0xd27c6, 0xd29fc, 0xd29fd, 0xd2cfe, - 0xd2cff, 0xd2d70, 0xd3030, 0xd303d, 0xd30a0, 0xd30fb, 0xda4fe, 0xda4ff, 0xda673, - 0xda67e, 0xda8ce, 0xda8cf, 0xda8fc, 0xda92e, 0xda92f, 0xda95f, 0xda9de, 0xda9df, - 0xdaade, 0xdaadf, 0xdaaf0, 0xdaaf1, 0xdabeb, 0xdfd3e, 0xdfd3f, 0xdfe63, 0xdfe68, - 0xdfe6a, 0xdfe6b, 0xdff1a, 0xdff1b, 0xdff1f, 0xdff20, 0xdff3f, 0xdff5b, 0xdff5d, - 0xe003a, 0xe003b, 0xe003f, 0xe0040, 0xe005f, 0xe007b, 0xe007d, 0xe00a1, 0xe00a7, - 0xe00ab, 0xe00b6, 0xe00b7, 0xe00bb, 0xe00bf, 0xe037e, 0xe0387, 0xe0589, 0xe058a, - 0xe05be, 0xe05c0, 0xe05c3, 0xe05c6, 0xe05f3, 0xe05f4, 0xe0609, 0xe060a, 0xe060c, - 0xe060d, 0xe061b, 0xe061e, 0xe061f, 0xe06d4, 0xe085e, 0xe0964, 0xe0965, 0xe0970, - 0xe09fd, 0xe0af0, 0xe0df4, 0xe0e4f, 0xe0e5a, 0xe0e5b, 0xe0f14, 0xe0f85, 0xe0fd9, - 0xe0fda, 0xe10fb, 0xe1400, 0xe166d, 0xe166e, 0xe169b, 0xe169c, 0xe1735, 0xe1736, - 0xe1944, 0xe1945, 0xe1a1e, 0xe1a1f, 0xe1c7e, 0xe1c7f, 0xe1cd3, 0xe207d, 0xe207e, - 0xe208d, 0xe208e, 0xe2329, 0xe232a, 0xe27c5, 0xe27c6, 0xe29fc, 0xe29fd, 0xe2cfe, - 0xe2cff, 0xe2d70, 0xe3030, 0xe303d, 0xe30a0, 0xe30fb, 0xea4fe, 0xea4ff, 0xea673, - 0xea67e, 0xea8ce, 0xea8cf, 0xea8fc, 0xea92e, 0xea92f, 0xea95f, 0xea9de, 0xea9df, - 0xeaade, 0xeaadf, 0xeaaf0, 0xeaaf1, 0xeabeb, 0xefd3e, 0xefd3f, 0xefe63, 0xefe68, - 0xefe6a, 0xefe6b, 0xeff1a, 0xeff1b, 0xeff1f, 0xeff20, 0xeff3f, 0xeff5b, 0xeff5d, - 0xf003a, 0xf003b, 0xf003f, 0xf0040, 0xf005f, 0xf007b, 0xf007d, 0xf00a1, 0xf00a7, - 0xf00ab, 0xf00b6, 0xf00b7, 0xf00bb, 0xf00bf, 0xf037e, 0xf0387, 0xf0589, 0xf058a, - 0xf05be, 0xf05c0, 0xf05c3, 0xf05c6, 0xf05f3, 0xf05f4, 0xf0609, 0xf060a, 0xf060c, - 0xf060d, 0xf061b, 0xf061e, 0xf061f, 0xf06d4, 0xf085e, 0xf0964, 0xf0965, 0xf0970, - 0xf09fd, 0xf0af0, 0xf0df4, 0xf0e4f, 0xf0e5a, 0xf0e5b, 0xf0f14, 0xf0f85, 0xf0fd9, - 0xf0fda, 0xf10fb, 0xf1400, 0xf166d, 0xf166e, 0xf169b, 0xf169c, 0xf1735, 0xf1736, - 0xf1944, 0xf1945, 0xf1a1e, 0xf1a1f, 0xf1c7e, 0xf1c7f, 0xf1cd3, 0xf207d, 0xf207e, - 0xf208d, 0xf208e, 0xf2329, 0xf232a, 0xf27c5, 0xf27c6, 0xf29fc, 0xf29fd, 0xf2cfe, - 0xf2cff, 0xf2d70, 0xf3030, 0xf303d, 0xf30a0, 0xf30fb, 0xfa4fe, 0xfa4ff, 0xfa673, - 0xfa67e, 0xfa8ce, 0xfa8cf, 0xfa8fc, 0xfa92e, 0xfa92f, 0xfa95f, 0xfa9de, 0xfa9df, - 0xfaade, 0xfaadf, 0xfaaf0, 0xfaaf1, 0xfabeb, 0xffd3e, 0xffd3f, 0xffe63, 0xffe68, - 0xffe6a, 0xffe6b, 0xfff1a, 0xfff1b, 0xfff1f, 0xfff20, 0xfff3f, 0xfff5b, 0xfff5d, - 0x10003a, 0x10003b, 0x10003f, 0x100040, 0x10005f, 0x10007b, 0x10007d, 0x1000a1, 0x1000a7, - 0x1000ab, 0x1000b6, 0x1000b7, 0x1000bb, 0x1000bf, 0x10037e, 0x100387, 0x100589, 0x10058a, - 0x1005be, 0x1005c0, 0x1005c3, 0x1005c6, 0x1005f3, 0x1005f4, 0x100609, 0x10060a, 0x10060c, - 0x10060d, 0x10061b, 0x10061e, 0x10061f, 0x1006d4, 0x10085e, 0x100964, 0x100965, 0x100970, - 0x1009fd, 0x100af0, 0x100df4, 0x100e4f, 0x100e5a, 0x100e5b, 0x100f14, 0x100f85, 0x100fd9, - 0x100fda, 0x1010fb, 0x101400, 0x10166d, 0x10166e, 0x10169b, 0x10169c, 0x101735, 0x101736, - 0x101944, 0x101945, 0x101a1e, 0x101a1f, 0x101c7e, 0x101c7f, 0x101cd3, 0x10207d, 0x10207e, - 0x10208d, 0x10208e, 0x102329, 0x10232a, 0x1027c5, 0x1027c6, 0x1029fc, 0x1029fd, 0x102cfe, - 0x102cff, 0x102d70, 0x103030, 0x10303d, 0x1030a0, 0x1030fb, 0x10a4fe, 0x10a4ff, 0x10a673, - 0x10a67e, 0x10a8ce, 0x10a8cf, 0x10a8fc, 0x10a92e, 0x10a92f, 0x10a95f, 0x10a9de, 0x10a9df, - 0x10aade, 0x10aadf, 0x10aaf0, 0x10aaf1, 0x10abeb, 0x10fd3e, 0x10fd3f, 0x10fe63, 0x10fe68, - 0x10fe6a, 0x10fe6b, 0x10ff1a, 0x10ff1b, 0x10ff1f, 0x10ff20, 0x10ff3f, 0x10ff5b, 0x10ff5d + ,0x1039f, 0x103d0, 0x1056f, 0x10857, 0x1091f, 0x1093f, 0x10a7f, 0x110bb, 0x110bc, + 0x11174, 0x11175, 0x111cd, 0x111db, 0x112a9, 0x1145b, 0x1145d, 0x114c6, 0x11c70, + 0x11c71, 0x16a6e, 0x16a6f, 0x16af5, 0x16b44, 0x1bc9f, 0x1e95e, 0x1e95f #endif }; @@ -2256,16 +394,6 @@ static const chr punctCharTable[] = { static const crange spaceRangeTable[] = { {0x9, 0xd}, {0x2000, 0x200b} -#if TCL_UTF_MAX > 4 - ,{0x10009, 0x1000d}, {0x12000, 0x1200b}, {0x20009, 0x2000d}, {0x22000, 0x2200b}, - {0x30009, 0x3000d}, {0x32000, 0x3200b}, {0x40009, 0x4000d}, {0x42000, 0x4200b}, - {0x50009, 0x5000d}, {0x52000, 0x5200b}, {0x60009, 0x6000d}, {0x62000, 0x6200b}, - {0x70009, 0x7000d}, {0x72000, 0x7200b}, {0x80009, 0x8000d}, {0x82000, 0x8200b}, - {0x90009, 0x9000d}, {0x92000, 0x9200b}, {0xa0009, 0xa000d}, {0xa2000, 0xa200b}, - {0xb0009, 0xb000d}, {0xb2000, 0xb200b}, {0xc0009, 0xc000d}, {0xc2000, 0xc200b}, - {0xd0009, 0xd000d}, {0xd2000, 0xd200b}, {0xe0009, 0xe000d}, {0xe2000, 0xe200b}, - {0xf0009, 0xf000d}, {0xf2000, 0xf200b}, {0x100009, 0x10000d}, {0x102000, 0x10200b} -#endif }; #define NUM_SPACE_RANGE (sizeof(spaceRangeTable)/sizeof(crange)) @@ -2273,30 +401,6 @@ static const crange spaceRangeTable[] = { static const chr spaceCharTable[] = { 0x20, 0x85, 0xa0, 0x1680, 0x180e, 0x2028, 0x2029, 0x202f, 0x205f, 0x2060, 0x3000, 0xfeff -#if TCL_UTF_MAX > 4 - ,0x10020, 0x10085, 0x100a0, 0x11680, 0x1180e, 0x12028, 0x12029, 0x1202f, 0x1205f, - 0x12060, 0x13000, 0x1feff, 0x20020, 0x20085, 0x200a0, 0x21680, 0x2180e, 0x22028, - 0x22029, 0x2202f, 0x2205f, 0x22060, 0x23000, 0x2feff, 0x30020, 0x30085, 0x300a0, - 0x31680, 0x3180e, 0x32028, 0x32029, 0x3202f, 0x3205f, 0x32060, 0x33000, 0x3feff, - 0x40020, 0x40085, 0x400a0, 0x41680, 0x4180e, 0x42028, 0x42029, 0x4202f, 0x4205f, - 0x42060, 0x43000, 0x4feff, 0x50020, 0x50085, 0x500a0, 0x51680, 0x5180e, 0x52028, - 0x52029, 0x5202f, 0x5205f, 0x52060, 0x53000, 0x5feff, 0x60020, 0x60085, 0x600a0, - 0x61680, 0x6180e, 0x62028, 0x62029, 0x6202f, 0x6205f, 0x62060, 0x63000, 0x6feff, - 0x70020, 0x70085, 0x700a0, 0x71680, 0x7180e, 0x72028, 0x72029, 0x7202f, 0x7205f, - 0x72060, 0x73000, 0x7feff, 0x80020, 0x80085, 0x800a0, 0x81680, 0x8180e, 0x82028, - 0x82029, 0x8202f, 0x8205f, 0x82060, 0x83000, 0x8feff, 0x90020, 0x90085, 0x900a0, - 0x91680, 0x9180e, 0x92028, 0x92029, 0x9202f, 0x9205f, 0x92060, 0x93000, 0x9feff, - 0xa0020, 0xa0085, 0xa00a0, 0xa1680, 0xa180e, 0xa2028, 0xa2029, 0xa202f, 0xa205f, - 0xa2060, 0xa3000, 0xafeff, 0xb0020, 0xb0085, 0xb00a0, 0xb1680, 0xb180e, 0xb2028, - 0xb2029, 0xb202f, 0xb205f, 0xb2060, 0xb3000, 0xbfeff, 0xc0020, 0xc0085, 0xc00a0, - 0xc1680, 0xc180e, 0xc2028, 0xc2029, 0xc202f, 0xc205f, 0xc2060, 0xc3000, 0xcfeff, - 0xd0020, 0xd0085, 0xd00a0, 0xd1680, 0xd180e, 0xd2028, 0xd2029, 0xd202f, 0xd205f, - 0xd2060, 0xd3000, 0xdfeff, 0xe0020, 0xe0085, 0xe00a0, 0xe1680, 0xe180e, 0xe2028, - 0xe2029, 0xe202f, 0xe205f, 0xe2060, 0xe3000, 0xefeff, 0xf0020, 0xf0085, 0xf00a0, - 0xf1680, 0xf180e, 0xf2028, 0xf2029, 0xf202f, 0xf205f, 0xf2060, 0xf3000, 0xffeff, - 0x100020, 0x100085, 0x1000a0, 0x101680, 0x10180e, 0x102028, 0x102029, 0x10202f, 0x10205f, - 0x102060, 0x103000, 0x10feff -#endif }; #define NUM_SPACE_CHAR (sizeof(spaceCharTable)/sizeof(chr)) @@ -2320,206 +424,14 @@ static const crange lowerRangeTable[] = { {0xab30, 0xab5a}, {0xab60, 0xab65}, {0xab70, 0xabbf}, {0xfb00, 0xfb06}, {0xfb13, 0xfb17}, {0xff41, 0xff5a} #if TCL_UTF_MAX > 4 - ,{0x10061, 0x1007a}, {0x100df, 0x100f6}, {0x100f8, 0x100ff}, {0x1017e, 0x10180}, - {0x10199, 0x1019b}, {0x101bd, 0x101bf}, {0x10233, 0x10239}, {0x1024f, 0x10293}, - {0x10295, 0x102af}, {0x1037b, 0x1037d}, {0x103ac, 0x103ce}, {0x103d5, 0x103d7}, - {0x103ef, 0x103f3}, {0x10430, 0x1045f}, {0x10561, 0x10587}, {0x113f8, 0x113fd}, - {0x11c80, 0x11c88}, {0x11d00, 0x11d2b}, {0x11d6b, 0x11d77}, {0x11d79, 0x11d9a}, - {0x11e95, 0x11e9d}, {0x11eff, 0x11f07}, {0x11f10, 0x11f15}, {0x11f20, 0x11f27}, - {0x11f30, 0x11f37}, {0x11f40, 0x11f45}, {0x11f50, 0x11f57}, {0x11f60, 0x11f67}, - {0x11f70, 0x11f7d}, {0x11f80, 0x11f87}, {0x11f90, 0x11f97}, {0x11fa0, 0x11fa7}, - {0x11fb0, 0x11fb4}, {0x11fc2, 0x11fc4}, {0x11fd0, 0x11fd3}, {0x11fe0, 0x11fe7}, - {0x11ff2, 0x11ff4}, {0x12146, 0x12149}, {0x12c30, 0x12c5e}, {0x12c76, 0x12c7b}, - {0x12d00, 0x12d25}, {0x1a72f, 0x1a731}, {0x1a771, 0x1a778}, {0x1a793, 0x1a795}, - {0x1ab30, 0x1ab5a}, {0x1ab60, 0x1ab65}, {0x1ab70, 0x1abbf}, {0x1fb00, 0x1fb06}, - {0x1fb13, 0x1fb17}, {0x1ff41, 0x1ff5a}, {0x20061, 0x2007a}, {0x200df, 0x200f6}, - {0x200f8, 0x200ff}, {0x2017e, 0x20180}, {0x20199, 0x2019b}, {0x201bd, 0x201bf}, - {0x20233, 0x20239}, {0x2024f, 0x20293}, {0x20295, 0x202af}, {0x2037b, 0x2037d}, - {0x203ac, 0x203ce}, {0x203d5, 0x203d7}, {0x203ef, 0x203f3}, {0x20430, 0x2045f}, - {0x20561, 0x20587}, {0x213f8, 0x213fd}, {0x21c80, 0x21c88}, {0x21d00, 0x21d2b}, - {0x21d6b, 0x21d77}, {0x21d79, 0x21d9a}, {0x21e95, 0x21e9d}, {0x21eff, 0x21f07}, - {0x21f10, 0x21f15}, {0x21f20, 0x21f27}, {0x21f30, 0x21f37}, {0x21f40, 0x21f45}, - {0x21f50, 0x21f57}, {0x21f60, 0x21f67}, {0x21f70, 0x21f7d}, {0x21f80, 0x21f87}, - {0x21f90, 0x21f97}, {0x21fa0, 0x21fa7}, {0x21fb0, 0x21fb4}, {0x21fc2, 0x21fc4}, - {0x21fd0, 0x21fd3}, {0x21fe0, 0x21fe7}, {0x21ff2, 0x21ff4}, {0x22146, 0x22149}, - {0x22c30, 0x22c5e}, {0x22c76, 0x22c7b}, {0x22d00, 0x22d25}, {0x2a72f, 0x2a731}, - {0x2a771, 0x2a778}, {0x2a793, 0x2a795}, {0x2ab30, 0x2ab5a}, {0x2ab60, 0x2ab65}, - {0x2ab70, 0x2abbf}, {0x2fb00, 0x2fb06}, {0x2fb13, 0x2fb17}, {0x2ff41, 0x2ff5a}, - {0x30061, 0x3007a}, {0x300df, 0x300f6}, {0x300f8, 0x300ff}, {0x3017e, 0x30180}, - {0x30199, 0x3019b}, {0x301bd, 0x301bf}, {0x30233, 0x30239}, {0x3024f, 0x30293}, - {0x30295, 0x302af}, {0x3037b, 0x3037d}, {0x303ac, 0x303ce}, {0x303d5, 0x303d7}, - {0x303ef, 0x303f3}, {0x30430, 0x3045f}, {0x30561, 0x30587}, {0x313f8, 0x313fd}, - {0x31c80, 0x31c88}, {0x31d00, 0x31d2b}, {0x31d6b, 0x31d77}, {0x31d79, 0x31d9a}, - {0x31e95, 0x31e9d}, {0x31eff, 0x31f07}, {0x31f10, 0x31f15}, {0x31f20, 0x31f27}, - {0x31f30, 0x31f37}, {0x31f40, 0x31f45}, {0x31f50, 0x31f57}, {0x31f60, 0x31f67}, - {0x31f70, 0x31f7d}, {0x31f80, 0x31f87}, {0x31f90, 0x31f97}, {0x31fa0, 0x31fa7}, - {0x31fb0, 0x31fb4}, {0x31fc2, 0x31fc4}, {0x31fd0, 0x31fd3}, {0x31fe0, 0x31fe7}, - {0x31ff2, 0x31ff4}, {0x32146, 0x32149}, {0x32c30, 0x32c5e}, {0x32c76, 0x32c7b}, - {0x32d00, 0x32d25}, {0x3a72f, 0x3a731}, {0x3a771, 0x3a778}, {0x3a793, 0x3a795}, - {0x3ab30, 0x3ab5a}, {0x3ab60, 0x3ab65}, {0x3ab70, 0x3abbf}, {0x3fb00, 0x3fb06}, - {0x3fb13, 0x3fb17}, {0x3ff41, 0x3ff5a}, {0x40061, 0x4007a}, {0x400df, 0x400f6}, - {0x400f8, 0x400ff}, {0x4017e, 0x40180}, {0x40199, 0x4019b}, {0x401bd, 0x401bf}, - {0x40233, 0x40239}, {0x4024f, 0x40293}, {0x40295, 0x402af}, {0x4037b, 0x4037d}, - {0x403ac, 0x403ce}, {0x403d5, 0x403d7}, {0x403ef, 0x403f3}, {0x40430, 0x4045f}, - {0x40561, 0x40587}, {0x413f8, 0x413fd}, {0x41c80, 0x41c88}, {0x41d00, 0x41d2b}, - {0x41d6b, 0x41d77}, {0x41d79, 0x41d9a}, {0x41e95, 0x41e9d}, {0x41eff, 0x41f07}, - {0x41f10, 0x41f15}, {0x41f20, 0x41f27}, {0x41f30, 0x41f37}, {0x41f40, 0x41f45}, - {0x41f50, 0x41f57}, {0x41f60, 0x41f67}, {0x41f70, 0x41f7d}, {0x41f80, 0x41f87}, - {0x41f90, 0x41f97}, {0x41fa0, 0x41fa7}, {0x41fb0, 0x41fb4}, {0x41fc2, 0x41fc4}, - {0x41fd0, 0x41fd3}, {0x41fe0, 0x41fe7}, {0x41ff2, 0x41ff4}, {0x42146, 0x42149}, - {0x42c30, 0x42c5e}, {0x42c76, 0x42c7b}, {0x42d00, 0x42d25}, {0x4a72f, 0x4a731}, - {0x4a771, 0x4a778}, {0x4a793, 0x4a795}, {0x4ab30, 0x4ab5a}, {0x4ab60, 0x4ab65}, - {0x4ab70, 0x4abbf}, {0x4fb00, 0x4fb06}, {0x4fb13, 0x4fb17}, {0x4ff41, 0x4ff5a}, - {0x50061, 0x5007a}, {0x500df, 0x500f6}, {0x500f8, 0x500ff}, {0x5017e, 0x50180}, - {0x50199, 0x5019b}, {0x501bd, 0x501bf}, {0x50233, 0x50239}, {0x5024f, 0x50293}, - {0x50295, 0x502af}, {0x5037b, 0x5037d}, {0x503ac, 0x503ce}, {0x503d5, 0x503d7}, - {0x503ef, 0x503f3}, {0x50430, 0x5045f}, {0x50561, 0x50587}, {0x513f8, 0x513fd}, - {0x51c80, 0x51c88}, {0x51d00, 0x51d2b}, {0x51d6b, 0x51d77}, {0x51d79, 0x51d9a}, - {0x51e95, 0x51e9d}, {0x51eff, 0x51f07}, {0x51f10, 0x51f15}, {0x51f20, 0x51f27}, - {0x51f30, 0x51f37}, {0x51f40, 0x51f45}, {0x51f50, 0x51f57}, {0x51f60, 0x51f67}, - {0x51f70, 0x51f7d}, {0x51f80, 0x51f87}, {0x51f90, 0x51f97}, {0x51fa0, 0x51fa7}, - {0x51fb0, 0x51fb4}, {0x51fc2, 0x51fc4}, {0x51fd0, 0x51fd3}, {0x51fe0, 0x51fe7}, - {0x51ff2, 0x51ff4}, {0x52146, 0x52149}, {0x52c30, 0x52c5e}, {0x52c76, 0x52c7b}, - {0x52d00, 0x52d25}, {0x5a72f, 0x5a731}, {0x5a771, 0x5a778}, {0x5a793, 0x5a795}, - {0x5ab30, 0x5ab5a}, {0x5ab60, 0x5ab65}, {0x5ab70, 0x5abbf}, {0x5fb00, 0x5fb06}, - {0x5fb13, 0x5fb17}, {0x5ff41, 0x5ff5a}, {0x60061, 0x6007a}, {0x600df, 0x600f6}, - {0x600f8, 0x600ff}, {0x6017e, 0x60180}, {0x60199, 0x6019b}, {0x601bd, 0x601bf}, - {0x60233, 0x60239}, {0x6024f, 0x60293}, {0x60295, 0x602af}, {0x6037b, 0x6037d}, - {0x603ac, 0x603ce}, {0x603d5, 0x603d7}, {0x603ef, 0x603f3}, {0x60430, 0x6045f}, - {0x60561, 0x60587}, {0x613f8, 0x613fd}, {0x61c80, 0x61c88}, {0x61d00, 0x61d2b}, - {0x61d6b, 0x61d77}, {0x61d79, 0x61d9a}, {0x61e95, 0x61e9d}, {0x61eff, 0x61f07}, - {0x61f10, 0x61f15}, {0x61f20, 0x61f27}, {0x61f30, 0x61f37}, {0x61f40, 0x61f45}, - {0x61f50, 0x61f57}, {0x61f60, 0x61f67}, {0x61f70, 0x61f7d}, {0x61f80, 0x61f87}, - {0x61f90, 0x61f97}, {0x61fa0, 0x61fa7}, {0x61fb0, 0x61fb4}, {0x61fc2, 0x61fc4}, - {0x61fd0, 0x61fd3}, {0x61fe0, 0x61fe7}, {0x61ff2, 0x61ff4}, {0x62146, 0x62149}, - {0x62c30, 0x62c5e}, {0x62c76, 0x62c7b}, {0x62d00, 0x62d25}, {0x6a72f, 0x6a731}, - {0x6a771, 0x6a778}, {0x6a793, 0x6a795}, {0x6ab30, 0x6ab5a}, {0x6ab60, 0x6ab65}, - {0x6ab70, 0x6abbf}, {0x6fb00, 0x6fb06}, {0x6fb13, 0x6fb17}, {0x6ff41, 0x6ff5a}, - {0x70061, 0x7007a}, {0x700df, 0x700f6}, {0x700f8, 0x700ff}, {0x7017e, 0x70180}, - {0x70199, 0x7019b}, {0x701bd, 0x701bf}, {0x70233, 0x70239}, {0x7024f, 0x70293}, - {0x70295, 0x702af}, {0x7037b, 0x7037d}, {0x703ac, 0x703ce}, {0x703d5, 0x703d7}, - {0x703ef, 0x703f3}, {0x70430, 0x7045f}, {0x70561, 0x70587}, {0x713f8, 0x713fd}, - {0x71c80, 0x71c88}, {0x71d00, 0x71d2b}, {0x71d6b, 0x71d77}, {0x71d79, 0x71d9a}, - {0x71e95, 0x71e9d}, {0x71eff, 0x71f07}, {0x71f10, 0x71f15}, {0x71f20, 0x71f27}, - {0x71f30, 0x71f37}, {0x71f40, 0x71f45}, {0x71f50, 0x71f57}, {0x71f60, 0x71f67}, - {0x71f70, 0x71f7d}, {0x71f80, 0x71f87}, {0x71f90, 0x71f97}, {0x71fa0, 0x71fa7}, - {0x71fb0, 0x71fb4}, {0x71fc2, 0x71fc4}, {0x71fd0, 0x71fd3}, {0x71fe0, 0x71fe7}, - {0x71ff2, 0x71ff4}, {0x72146, 0x72149}, {0x72c30, 0x72c5e}, {0x72c76, 0x72c7b}, - {0x72d00, 0x72d25}, {0x7a72f, 0x7a731}, {0x7a771, 0x7a778}, {0x7a793, 0x7a795}, - {0x7ab30, 0x7ab5a}, {0x7ab60, 0x7ab65}, {0x7ab70, 0x7abbf}, {0x7fb00, 0x7fb06}, - {0x7fb13, 0x7fb17}, {0x7ff41, 0x7ff5a}, {0x80061, 0x8007a}, {0x800df, 0x800f6}, - {0x800f8, 0x800ff}, {0x8017e, 0x80180}, {0x80199, 0x8019b}, {0x801bd, 0x801bf}, - {0x80233, 0x80239}, {0x8024f, 0x80293}, {0x80295, 0x802af}, {0x8037b, 0x8037d}, - {0x803ac, 0x803ce}, {0x803d5, 0x803d7}, {0x803ef, 0x803f3}, {0x80430, 0x8045f}, - {0x80561, 0x80587}, {0x813f8, 0x813fd}, {0x81c80, 0x81c88}, {0x81d00, 0x81d2b}, - {0x81d6b, 0x81d77}, {0x81d79, 0x81d9a}, {0x81e95, 0x81e9d}, {0x81eff, 0x81f07}, - {0x81f10, 0x81f15}, {0x81f20, 0x81f27}, {0x81f30, 0x81f37}, {0x81f40, 0x81f45}, - {0x81f50, 0x81f57}, {0x81f60, 0x81f67}, {0x81f70, 0x81f7d}, {0x81f80, 0x81f87}, - {0x81f90, 0x81f97}, {0x81fa0, 0x81fa7}, {0x81fb0, 0x81fb4}, {0x81fc2, 0x81fc4}, - {0x81fd0, 0x81fd3}, {0x81fe0, 0x81fe7}, {0x81ff2, 0x81ff4}, {0x82146, 0x82149}, - {0x82c30, 0x82c5e}, {0x82c76, 0x82c7b}, {0x82d00, 0x82d25}, {0x8a72f, 0x8a731}, - {0x8a771, 0x8a778}, {0x8a793, 0x8a795}, {0x8ab30, 0x8ab5a}, {0x8ab60, 0x8ab65}, - {0x8ab70, 0x8abbf}, {0x8fb00, 0x8fb06}, {0x8fb13, 0x8fb17}, {0x8ff41, 0x8ff5a}, - {0x90061, 0x9007a}, {0x900df, 0x900f6}, {0x900f8, 0x900ff}, {0x9017e, 0x90180}, - {0x90199, 0x9019b}, {0x901bd, 0x901bf}, {0x90233, 0x90239}, {0x9024f, 0x90293}, - {0x90295, 0x902af}, {0x9037b, 0x9037d}, {0x903ac, 0x903ce}, {0x903d5, 0x903d7}, - {0x903ef, 0x903f3}, {0x90430, 0x9045f}, {0x90561, 0x90587}, {0x913f8, 0x913fd}, - {0x91c80, 0x91c88}, {0x91d00, 0x91d2b}, {0x91d6b, 0x91d77}, {0x91d79, 0x91d9a}, - {0x91e95, 0x91e9d}, {0x91eff, 0x91f07}, {0x91f10, 0x91f15}, {0x91f20, 0x91f27}, - {0x91f30, 0x91f37}, {0x91f40, 0x91f45}, {0x91f50, 0x91f57}, {0x91f60, 0x91f67}, - {0x91f70, 0x91f7d}, {0x91f80, 0x91f87}, {0x91f90, 0x91f97}, {0x91fa0, 0x91fa7}, - {0x91fb0, 0x91fb4}, {0x91fc2, 0x91fc4}, {0x91fd0, 0x91fd3}, {0x91fe0, 0x91fe7}, - {0x91ff2, 0x91ff4}, {0x92146, 0x92149}, {0x92c30, 0x92c5e}, {0x92c76, 0x92c7b}, - {0x92d00, 0x92d25}, {0x9a72f, 0x9a731}, {0x9a771, 0x9a778}, {0x9a793, 0x9a795}, - {0x9ab30, 0x9ab5a}, {0x9ab60, 0x9ab65}, {0x9ab70, 0x9abbf}, {0x9fb00, 0x9fb06}, - {0x9fb13, 0x9fb17}, {0x9ff41, 0x9ff5a}, {0xa0061, 0xa007a}, {0xa00df, 0xa00f6}, - {0xa00f8, 0xa00ff}, {0xa017e, 0xa0180}, {0xa0199, 0xa019b}, {0xa01bd, 0xa01bf}, - {0xa0233, 0xa0239}, {0xa024f, 0xa0293}, {0xa0295, 0xa02af}, {0xa037b, 0xa037d}, - {0xa03ac, 0xa03ce}, {0xa03d5, 0xa03d7}, {0xa03ef, 0xa03f3}, {0xa0430, 0xa045f}, - {0xa0561, 0xa0587}, {0xa13f8, 0xa13fd}, {0xa1c80, 0xa1c88}, {0xa1d00, 0xa1d2b}, - {0xa1d6b, 0xa1d77}, {0xa1d79, 0xa1d9a}, {0xa1e95, 0xa1e9d}, {0xa1eff, 0xa1f07}, - {0xa1f10, 0xa1f15}, {0xa1f20, 0xa1f27}, {0xa1f30, 0xa1f37}, {0xa1f40, 0xa1f45}, - {0xa1f50, 0xa1f57}, {0xa1f60, 0xa1f67}, {0xa1f70, 0xa1f7d}, {0xa1f80, 0xa1f87}, - {0xa1f90, 0xa1f97}, {0xa1fa0, 0xa1fa7}, {0xa1fb0, 0xa1fb4}, {0xa1fc2, 0xa1fc4}, - {0xa1fd0, 0xa1fd3}, {0xa1fe0, 0xa1fe7}, {0xa1ff2, 0xa1ff4}, {0xa2146, 0xa2149}, - {0xa2c30, 0xa2c5e}, {0xa2c76, 0xa2c7b}, {0xa2d00, 0xa2d25}, {0xaa72f, 0xaa731}, - {0xaa771, 0xaa778}, {0xaa793, 0xaa795}, {0xaab30, 0xaab5a}, {0xaab60, 0xaab65}, - {0xaab70, 0xaabbf}, {0xafb00, 0xafb06}, {0xafb13, 0xafb17}, {0xaff41, 0xaff5a}, - {0xb0061, 0xb007a}, {0xb00df, 0xb00f6}, {0xb00f8, 0xb00ff}, {0xb017e, 0xb0180}, - {0xb0199, 0xb019b}, {0xb01bd, 0xb01bf}, {0xb0233, 0xb0239}, {0xb024f, 0xb0293}, - {0xb0295, 0xb02af}, {0xb037b, 0xb037d}, {0xb03ac, 0xb03ce}, {0xb03d5, 0xb03d7}, - {0xb03ef, 0xb03f3}, {0xb0430, 0xb045f}, {0xb0561, 0xb0587}, {0xb13f8, 0xb13fd}, - {0xb1c80, 0xb1c88}, {0xb1d00, 0xb1d2b}, {0xb1d6b, 0xb1d77}, {0xb1d79, 0xb1d9a}, - {0xb1e95, 0xb1e9d}, {0xb1eff, 0xb1f07}, {0xb1f10, 0xb1f15}, {0xb1f20, 0xb1f27}, - {0xb1f30, 0xb1f37}, {0xb1f40, 0xb1f45}, {0xb1f50, 0xb1f57}, {0xb1f60, 0xb1f67}, - {0xb1f70, 0xb1f7d}, {0xb1f80, 0xb1f87}, {0xb1f90, 0xb1f97}, {0xb1fa0, 0xb1fa7}, - {0xb1fb0, 0xb1fb4}, {0xb1fc2, 0xb1fc4}, {0xb1fd0, 0xb1fd3}, {0xb1fe0, 0xb1fe7}, - {0xb1ff2, 0xb1ff4}, {0xb2146, 0xb2149}, {0xb2c30, 0xb2c5e}, {0xb2c76, 0xb2c7b}, - {0xb2d00, 0xb2d25}, {0xba72f, 0xba731}, {0xba771, 0xba778}, {0xba793, 0xba795}, - {0xbab30, 0xbab5a}, {0xbab60, 0xbab65}, {0xbab70, 0xbabbf}, {0xbfb00, 0xbfb06}, - {0xbfb13, 0xbfb17}, {0xbff41, 0xbff5a}, {0xc0061, 0xc007a}, {0xc00df, 0xc00f6}, - {0xc00f8, 0xc00ff}, {0xc017e, 0xc0180}, {0xc0199, 0xc019b}, {0xc01bd, 0xc01bf}, - {0xc0233, 0xc0239}, {0xc024f, 0xc0293}, {0xc0295, 0xc02af}, {0xc037b, 0xc037d}, - {0xc03ac, 0xc03ce}, {0xc03d5, 0xc03d7}, {0xc03ef, 0xc03f3}, {0xc0430, 0xc045f}, - {0xc0561, 0xc0587}, {0xc13f8, 0xc13fd}, {0xc1c80, 0xc1c88}, {0xc1d00, 0xc1d2b}, - {0xc1d6b, 0xc1d77}, {0xc1d79, 0xc1d9a}, {0xc1e95, 0xc1e9d}, {0xc1eff, 0xc1f07}, - {0xc1f10, 0xc1f15}, {0xc1f20, 0xc1f27}, {0xc1f30, 0xc1f37}, {0xc1f40, 0xc1f45}, - {0xc1f50, 0xc1f57}, {0xc1f60, 0xc1f67}, {0xc1f70, 0xc1f7d}, {0xc1f80, 0xc1f87}, - {0xc1f90, 0xc1f97}, {0xc1fa0, 0xc1fa7}, {0xc1fb0, 0xc1fb4}, {0xc1fc2, 0xc1fc4}, - {0xc1fd0, 0xc1fd3}, {0xc1fe0, 0xc1fe7}, {0xc1ff2, 0xc1ff4}, {0xc2146, 0xc2149}, - {0xc2c30, 0xc2c5e}, {0xc2c76, 0xc2c7b}, {0xc2d00, 0xc2d25}, {0xca72f, 0xca731}, - {0xca771, 0xca778}, {0xca793, 0xca795}, {0xcab30, 0xcab5a}, {0xcab60, 0xcab65}, - {0xcab70, 0xcabbf}, {0xcfb00, 0xcfb06}, {0xcfb13, 0xcfb17}, {0xcff41, 0xcff5a}, - {0xd0061, 0xd007a}, {0xd00df, 0xd00f6}, {0xd00f8, 0xd00ff}, {0xd017e, 0xd0180}, - {0xd0199, 0xd019b}, {0xd01bd, 0xd01bf}, {0xd0233, 0xd0239}, {0xd024f, 0xd0293}, - {0xd0295, 0xd02af}, {0xd037b, 0xd037d}, {0xd03ac, 0xd03ce}, {0xd03d5, 0xd03d7}, - {0xd03ef, 0xd03f3}, {0xd0430, 0xd045f}, {0xd0561, 0xd0587}, {0xd13f8, 0xd13fd}, - {0xd1c80, 0xd1c88}, {0xd1d00, 0xd1d2b}, {0xd1d6b, 0xd1d77}, {0xd1d79, 0xd1d9a}, - {0xd1e95, 0xd1e9d}, {0xd1eff, 0xd1f07}, {0xd1f10, 0xd1f15}, {0xd1f20, 0xd1f27}, - {0xd1f30, 0xd1f37}, {0xd1f40, 0xd1f45}, {0xd1f50, 0xd1f57}, {0xd1f60, 0xd1f67}, - {0xd1f70, 0xd1f7d}, {0xd1f80, 0xd1f87}, {0xd1f90, 0xd1f97}, {0xd1fa0, 0xd1fa7}, - {0xd1fb0, 0xd1fb4}, {0xd1fc2, 0xd1fc4}, {0xd1fd0, 0xd1fd3}, {0xd1fe0, 0xd1fe7}, - {0xd1ff2, 0xd1ff4}, {0xd2146, 0xd2149}, {0xd2c30, 0xd2c5e}, {0xd2c76, 0xd2c7b}, - {0xd2d00, 0xd2d25}, {0xda72f, 0xda731}, {0xda771, 0xda778}, {0xda793, 0xda795}, - {0xdab30, 0xdab5a}, {0xdab60, 0xdab65}, {0xdab70, 0xdabbf}, {0xdfb00, 0xdfb06}, - {0xdfb13, 0xdfb17}, {0xdff41, 0xdff5a}, {0xe0061, 0xe007a}, {0xe00df, 0xe00f6}, - {0xe00f8, 0xe00ff}, {0xe017e, 0xe0180}, {0xe0199, 0xe019b}, {0xe01bd, 0xe01bf}, - {0xe0233, 0xe0239}, {0xe024f, 0xe0293}, {0xe0295, 0xe02af}, {0xe037b, 0xe037d}, - {0xe03ac, 0xe03ce}, {0xe03d5, 0xe03d7}, {0xe03ef, 0xe03f3}, {0xe0430, 0xe045f}, - {0xe0561, 0xe0587}, {0xe13f8, 0xe13fd}, {0xe1c80, 0xe1c88}, {0xe1d00, 0xe1d2b}, - {0xe1d6b, 0xe1d77}, {0xe1d79, 0xe1d9a}, {0xe1e95, 0xe1e9d}, {0xe1eff, 0xe1f07}, - {0xe1f10, 0xe1f15}, {0xe1f20, 0xe1f27}, {0xe1f30, 0xe1f37}, {0xe1f40, 0xe1f45}, - {0xe1f50, 0xe1f57}, {0xe1f60, 0xe1f67}, {0xe1f70, 0xe1f7d}, {0xe1f80, 0xe1f87}, - {0xe1f90, 0xe1f97}, {0xe1fa0, 0xe1fa7}, {0xe1fb0, 0xe1fb4}, {0xe1fc2, 0xe1fc4}, - {0xe1fd0, 0xe1fd3}, {0xe1fe0, 0xe1fe7}, {0xe1ff2, 0xe1ff4}, {0xe2146, 0xe2149}, - {0xe2c30, 0xe2c5e}, {0xe2c76, 0xe2c7b}, {0xe2d00, 0xe2d25}, {0xea72f, 0xea731}, - {0xea771, 0xea778}, {0xea793, 0xea795}, {0xeab30, 0xeab5a}, {0xeab60, 0xeab65}, - {0xeab70, 0xeabbf}, {0xefb00, 0xefb06}, {0xefb13, 0xefb17}, {0xeff41, 0xeff5a}, - {0xf0061, 0xf007a}, {0xf00df, 0xf00f6}, {0xf00f8, 0xf00ff}, {0xf017e, 0xf0180}, - {0xf0199, 0xf019b}, {0xf01bd, 0xf01bf}, {0xf0233, 0xf0239}, {0xf024f, 0xf0293}, - {0xf0295, 0xf02af}, {0xf037b, 0xf037d}, {0xf03ac, 0xf03ce}, {0xf03d5, 0xf03d7}, - {0xf03ef, 0xf03f3}, {0xf0430, 0xf045f}, {0xf0561, 0xf0587}, {0xf13f8, 0xf13fd}, - {0xf1c80, 0xf1c88}, {0xf1d00, 0xf1d2b}, {0xf1d6b, 0xf1d77}, {0xf1d79, 0xf1d9a}, - {0xf1e95, 0xf1e9d}, {0xf1eff, 0xf1f07}, {0xf1f10, 0xf1f15}, {0xf1f20, 0xf1f27}, - {0xf1f30, 0xf1f37}, {0xf1f40, 0xf1f45}, {0xf1f50, 0xf1f57}, {0xf1f60, 0xf1f67}, - {0xf1f70, 0xf1f7d}, {0xf1f80, 0xf1f87}, {0xf1f90, 0xf1f97}, {0xf1fa0, 0xf1fa7}, - {0xf1fb0, 0xf1fb4}, {0xf1fc2, 0xf1fc4}, {0xf1fd0, 0xf1fd3}, {0xf1fe0, 0xf1fe7}, - {0xf1ff2, 0xf1ff4}, {0xf2146, 0xf2149}, {0xf2c30, 0xf2c5e}, {0xf2c76, 0xf2c7b}, - {0xf2d00, 0xf2d25}, {0xfa72f, 0xfa731}, {0xfa771, 0xfa778}, {0xfa793, 0xfa795}, - {0xfab30, 0xfab5a}, {0xfab60, 0xfab65}, {0xfab70, 0xfabbf}, {0xffb00, 0xffb06}, - {0xffb13, 0xffb17}, {0xfff41, 0xfff5a}, {0x100061, 0x10007a}, {0x1000df, 0x1000f6}, - {0x1000f8, 0x1000ff}, {0x10017e, 0x100180}, {0x100199, 0x10019b}, {0x1001bd, 0x1001bf}, - {0x100233, 0x100239}, {0x10024f, 0x100293}, {0x100295, 0x1002af}, {0x10037b, 0x10037d}, - {0x1003ac, 0x1003ce}, {0x1003d5, 0x1003d7}, {0x1003ef, 0x1003f3}, {0x100430, 0x10045f}, - {0x100561, 0x100587}, {0x1013f8, 0x1013fd}, {0x101c80, 0x101c88}, {0x101d00, 0x101d2b}, - {0x101d6b, 0x101d77}, {0x101d79, 0x101d9a}, {0x101e95, 0x101e9d}, {0x101eff, 0x101f07}, - {0x101f10, 0x101f15}, {0x101f20, 0x101f27}, {0x101f30, 0x101f37}, {0x101f40, 0x101f45}, - {0x101f50, 0x101f57}, {0x101f60, 0x101f67}, {0x101f70, 0x101f7d}, {0x101f80, 0x101f87}, - {0x101f90, 0x101f97}, {0x101fa0, 0x101fa7}, {0x101fb0, 0x101fb4}, {0x101fc2, 0x101fc4}, - {0x101fd0, 0x101fd3}, {0x101fe0, 0x101fe7}, {0x101ff2, 0x101ff4}, {0x102146, 0x102149}, - {0x102c30, 0x102c5e}, {0x102c76, 0x102c7b}, {0x102d00, 0x102d25}, {0x10a72f, 0x10a731}, - {0x10a771, 0x10a778}, {0x10a793, 0x10a795}, {0x10ab30, 0x10ab5a}, {0x10ab60, 0x10ab65}, - {0x10ab70, 0x10abbf}, {0x10fb00, 0x10fb06}, {0x10fb13, 0x10fb17}, {0x10ff41, 0x10ff5a} + ,{0x10428, 0x1044f}, {0x104d8, 0x104fb}, {0x10cc0, 0x10cf2}, {0x118c0, 0x118df}, + {0x1d41a, 0x1d433}, {0x1d44e, 0x1d454}, {0x1d456, 0x1d467}, {0x1d482, 0x1d49b}, + {0x1d4b6, 0x1d4b9}, {0x1d4bd, 0x1d4c3}, {0x1d4c5, 0x1d4cf}, {0x1d4ea, 0x1d503}, + {0x1d51e, 0x1d537}, {0x1d552, 0x1d56b}, {0x1d586, 0x1d59f}, {0x1d5ba, 0x1d5d3}, + {0x1d5ee, 0x1d607}, {0x1d622, 0x1d63b}, {0x1d656, 0x1d66f}, {0x1d68a, 0x1d6a5}, + {0x1d6c2, 0x1d6da}, {0x1d6dc, 0x1d6e1}, {0x1d6fc, 0x1d714}, {0x1d716, 0x1d71b}, + {0x1d736, 0x1d74e}, {0x1d750, 0x1d755}, {0x1d770, 0x1d788}, {0x1d78a, 0x1d78f}, + {0x1d7aa, 0x1d7c2}, {0x1d7c4, 0x1d7c9}, {0x1e922, 0x1e943} #endif }; @@ -2591,1020 +503,7 @@ static const chr lowerCharTable[] = { 0xa799, 0xa79b, 0xa79d, 0xa79f, 0xa7a1, 0xa7a3, 0xa7a5, 0xa7a7, 0xa7a9, 0xa7b5, 0xa7b7, 0xa7fa #if TCL_UTF_MAX > 4 - ,0x100b5, 0x10101, 0x10103, 0x10105, 0x10107, 0x10109, 0x1010b, 0x1010d, 0x1010f, - 0x10111, 0x10113, 0x10115, 0x10117, 0x10119, 0x1011b, 0x1011d, 0x1011f, 0x10121, - 0x10123, 0x10125, 0x10127, 0x10129, 0x1012b, 0x1012d, 0x1012f, 0x10131, 0x10133, - 0x10135, 0x10137, 0x10138, 0x1013a, 0x1013c, 0x1013e, 0x10140, 0x10142, 0x10144, - 0x10146, 0x10148, 0x10149, 0x1014b, 0x1014d, 0x1014f, 0x10151, 0x10153, 0x10155, - 0x10157, 0x10159, 0x1015b, 0x1015d, 0x1015f, 0x10161, 0x10163, 0x10165, 0x10167, - 0x10169, 0x1016b, 0x1016d, 0x1016f, 0x10171, 0x10173, 0x10175, 0x10177, 0x1017a, - 0x1017c, 0x10183, 0x10185, 0x10188, 0x1018c, 0x1018d, 0x10192, 0x10195, 0x1019e, - 0x101a1, 0x101a3, 0x101a5, 0x101a8, 0x101aa, 0x101ab, 0x101ad, 0x101b0, 0x101b4, - 0x101b6, 0x101b9, 0x101ba, 0x101c6, 0x101c9, 0x101cc, 0x101ce, 0x101d0, 0x101d2, - 0x101d4, 0x101d6, 0x101d8, 0x101da, 0x101dc, 0x101dd, 0x101df, 0x101e1, 0x101e3, - 0x101e5, 0x101e7, 0x101e9, 0x101eb, 0x101ed, 0x101ef, 0x101f0, 0x101f3, 0x101f5, - 0x101f9, 0x101fb, 0x101fd, 0x101ff, 0x10201, 0x10203, 0x10205, 0x10207, 0x10209, - 0x1020b, 0x1020d, 0x1020f, 0x10211, 0x10213, 0x10215, 0x10217, 0x10219, 0x1021b, - 0x1021d, 0x1021f, 0x10221, 0x10223, 0x10225, 0x10227, 0x10229, 0x1022b, 0x1022d, - 0x1022f, 0x10231, 0x1023c, 0x1023f, 0x10240, 0x10242, 0x10247, 0x10249, 0x1024b, - 0x1024d, 0x10371, 0x10373, 0x10377, 0x10390, 0x103d0, 0x103d1, 0x103d9, 0x103db, - 0x103dd, 0x103df, 0x103e1, 0x103e3, 0x103e5, 0x103e7, 0x103e9, 0x103eb, 0x103ed, - 0x103f5, 0x103f8, 0x103fb, 0x103fc, 0x10461, 0x10463, 0x10465, 0x10467, 0x10469, - 0x1046b, 0x1046d, 0x1046f, 0x10471, 0x10473, 0x10475, 0x10477, 0x10479, 0x1047b, - 0x1047d, 0x1047f, 0x10481, 0x1048b, 0x1048d, 0x1048f, 0x10491, 0x10493, 0x10495, - 0x10497, 0x10499, 0x1049b, 0x1049d, 0x1049f, 0x104a1, 0x104a3, 0x104a5, 0x104a7, - 0x104a9, 0x104ab, 0x104ad, 0x104af, 0x104b1, 0x104b3, 0x104b5, 0x104b7, 0x104b9, - 0x104bb, 0x104bd, 0x104bf, 0x104c2, 0x104c4, 0x104c6, 0x104c8, 0x104ca, 0x104cc, - 0x104ce, 0x104cf, 0x104d1, 0x104d3, 0x104d5, 0x104d7, 0x104d9, 0x104db, 0x104dd, - 0x104df, 0x104e1, 0x104e3, 0x104e5, 0x104e7, 0x104e9, 0x104eb, 0x104ed, 0x104ef, - 0x104f1, 0x104f3, 0x104f5, 0x104f7, 0x104f9, 0x104fb, 0x104fd, 0x104ff, 0x10501, - 0x10503, 0x10505, 0x10507, 0x10509, 0x1050b, 0x1050d, 0x1050f, 0x10511, 0x10513, - 0x10515, 0x10517, 0x10519, 0x1051b, 0x1051d, 0x1051f, 0x10521, 0x10523, 0x10525, - 0x10527, 0x10529, 0x1052b, 0x1052d, 0x1052f, 0x11e01, 0x11e03, 0x11e05, 0x11e07, - 0x11e09, 0x11e0b, 0x11e0d, 0x11e0f, 0x11e11, 0x11e13, 0x11e15, 0x11e17, 0x11e19, - 0x11e1b, 0x11e1d, 0x11e1f, 0x11e21, 0x11e23, 0x11e25, 0x11e27, 0x11e29, 0x11e2b, - 0x11e2d, 0x11e2f, 0x11e31, 0x11e33, 0x11e35, 0x11e37, 0x11e39, 0x11e3b, 0x11e3d, - 0x11e3f, 0x11e41, 0x11e43, 0x11e45, 0x11e47, 0x11e49, 0x11e4b, 0x11e4d, 0x11e4f, - 0x11e51, 0x11e53, 0x11e55, 0x11e57, 0x11e59, 0x11e5b, 0x11e5d, 0x11e5f, 0x11e61, - 0x11e63, 0x11e65, 0x11e67, 0x11e69, 0x11e6b, 0x11e6d, 0x11e6f, 0x11e71, 0x11e73, - 0x11e75, 0x11e77, 0x11e79, 0x11e7b, 0x11e7d, 0x11e7f, 0x11e81, 0x11e83, 0x11e85, - 0x11e87, 0x11e89, 0x11e8b, 0x11e8d, 0x11e8f, 0x11e91, 0x11e93, 0x11e9f, 0x11ea1, - 0x11ea3, 0x11ea5, 0x11ea7, 0x11ea9, 0x11eab, 0x11ead, 0x11eaf, 0x11eb1, 0x11eb3, - 0x11eb5, 0x11eb7, 0x11eb9, 0x11ebb, 0x11ebd, 0x11ebf, 0x11ec1, 0x11ec3, 0x11ec5, - 0x11ec7, 0x11ec9, 0x11ecb, 0x11ecd, 0x11ecf, 0x11ed1, 0x11ed3, 0x11ed5, 0x11ed7, - 0x11ed9, 0x11edb, 0x11edd, 0x11edf, 0x11ee1, 0x11ee3, 0x11ee5, 0x11ee7, 0x11ee9, - 0x11eeb, 0x11eed, 0x11eef, 0x11ef1, 0x11ef3, 0x11ef5, 0x11ef7, 0x11ef9, 0x11efb, - 0x11efd, 0x11fb6, 0x11fb7, 0x11fbe, 0x11fc6, 0x11fc7, 0x11fd6, 0x11fd7, 0x11ff6, - 0x11ff7, 0x1210a, 0x1210e, 0x1210f, 0x12113, 0x1212f, 0x12134, 0x12139, 0x1213c, - 0x1213d, 0x1214e, 0x12184, 0x12c61, 0x12c65, 0x12c66, 0x12c68, 0x12c6a, 0x12c6c, - 0x12c71, 0x12c73, 0x12c74, 0x12c81, 0x12c83, 0x12c85, 0x12c87, 0x12c89, 0x12c8b, - 0x12c8d, 0x12c8f, 0x12c91, 0x12c93, 0x12c95, 0x12c97, 0x12c99, 0x12c9b, 0x12c9d, - 0x12c9f, 0x12ca1, 0x12ca3, 0x12ca5, 0x12ca7, 0x12ca9, 0x12cab, 0x12cad, 0x12caf, - 0x12cb1, 0x12cb3, 0x12cb5, 0x12cb7, 0x12cb9, 0x12cbb, 0x12cbd, 0x12cbf, 0x12cc1, - 0x12cc3, 0x12cc5, 0x12cc7, 0x12cc9, 0x12ccb, 0x12ccd, 0x12ccf, 0x12cd1, 0x12cd3, - 0x12cd5, 0x12cd7, 0x12cd9, 0x12cdb, 0x12cdd, 0x12cdf, 0x12ce1, 0x12ce3, 0x12ce4, - 0x12cec, 0x12cee, 0x12cf3, 0x12d27, 0x12d2d, 0x1a641, 0x1a643, 0x1a645, 0x1a647, - 0x1a649, 0x1a64b, 0x1a64d, 0x1a64f, 0x1a651, 0x1a653, 0x1a655, 0x1a657, 0x1a659, - 0x1a65b, 0x1a65d, 0x1a65f, 0x1a661, 0x1a663, 0x1a665, 0x1a667, 0x1a669, 0x1a66b, - 0x1a66d, 0x1a681, 0x1a683, 0x1a685, 0x1a687, 0x1a689, 0x1a68b, 0x1a68d, 0x1a68f, - 0x1a691, 0x1a693, 0x1a695, 0x1a697, 0x1a699, 0x1a69b, 0x1a723, 0x1a725, 0x1a727, - 0x1a729, 0x1a72b, 0x1a72d, 0x1a733, 0x1a735, 0x1a737, 0x1a739, 0x1a73b, 0x1a73d, - 0x1a73f, 0x1a741, 0x1a743, 0x1a745, 0x1a747, 0x1a749, 0x1a74b, 0x1a74d, 0x1a74f, - 0x1a751, 0x1a753, 0x1a755, 0x1a757, 0x1a759, 0x1a75b, 0x1a75d, 0x1a75f, 0x1a761, - 0x1a763, 0x1a765, 0x1a767, 0x1a769, 0x1a76b, 0x1a76d, 0x1a76f, 0x1a77a, 0x1a77c, - 0x1a77f, 0x1a781, 0x1a783, 0x1a785, 0x1a787, 0x1a78c, 0x1a78e, 0x1a791, 0x1a797, - 0x1a799, 0x1a79b, 0x1a79d, 0x1a79f, 0x1a7a1, 0x1a7a3, 0x1a7a5, 0x1a7a7, 0x1a7a9, - 0x1a7b5, 0x1a7b7, 0x1a7fa, 0x200b5, 0x20101, 0x20103, 0x20105, 0x20107, 0x20109, - 0x2010b, 0x2010d, 0x2010f, 0x20111, 0x20113, 0x20115, 0x20117, 0x20119, 0x2011b, - 0x2011d, 0x2011f, 0x20121, 0x20123, 0x20125, 0x20127, 0x20129, 0x2012b, 0x2012d, - 0x2012f, 0x20131, 0x20133, 0x20135, 0x20137, 0x20138, 0x2013a, 0x2013c, 0x2013e, - 0x20140, 0x20142, 0x20144, 0x20146, 0x20148, 0x20149, 0x2014b, 0x2014d, 0x2014f, - 0x20151, 0x20153, 0x20155, 0x20157, 0x20159, 0x2015b, 0x2015d, 0x2015f, 0x20161, - 0x20163, 0x20165, 0x20167, 0x20169, 0x2016b, 0x2016d, 0x2016f, 0x20171, 0x20173, - 0x20175, 0x20177, 0x2017a, 0x2017c, 0x20183, 0x20185, 0x20188, 0x2018c, 0x2018d, - 0x20192, 0x20195, 0x2019e, 0x201a1, 0x201a3, 0x201a5, 0x201a8, 0x201aa, 0x201ab, - 0x201ad, 0x201b0, 0x201b4, 0x201b6, 0x201b9, 0x201ba, 0x201c6, 0x201c9, 0x201cc, - 0x201ce, 0x201d0, 0x201d2, 0x201d4, 0x201d6, 0x201d8, 0x201da, 0x201dc, 0x201dd, - 0x201df, 0x201e1, 0x201e3, 0x201e5, 0x201e7, 0x201e9, 0x201eb, 0x201ed, 0x201ef, - 0x201f0, 0x201f3, 0x201f5, 0x201f9, 0x201fb, 0x201fd, 0x201ff, 0x20201, 0x20203, - 0x20205, 0x20207, 0x20209, 0x2020b, 0x2020d, 0x2020f, 0x20211, 0x20213, 0x20215, - 0x20217, 0x20219, 0x2021b, 0x2021d, 0x2021f, 0x20221, 0x20223, 0x20225, 0x20227, - 0x20229, 0x2022b, 0x2022d, 0x2022f, 0x20231, 0x2023c, 0x2023f, 0x20240, 0x20242, - 0x20247, 0x20249, 0x2024b, 0x2024d, 0x20371, 0x20373, 0x20377, 0x20390, 0x203d0, - 0x203d1, 0x203d9, 0x203db, 0x203dd, 0x203df, 0x203e1, 0x203e3, 0x203e5, 0x203e7, - 0x203e9, 0x203eb, 0x203ed, 0x203f5, 0x203f8, 0x203fb, 0x203fc, 0x20461, 0x20463, - 0x20465, 0x20467, 0x20469, 0x2046b, 0x2046d, 0x2046f, 0x20471, 0x20473, 0x20475, - 0x20477, 0x20479, 0x2047b, 0x2047d, 0x2047f, 0x20481, 0x2048b, 0x2048d, 0x2048f, - 0x20491, 0x20493, 0x20495, 0x20497, 0x20499, 0x2049b, 0x2049d, 0x2049f, 0x204a1, - 0x204a3, 0x204a5, 0x204a7, 0x204a9, 0x204ab, 0x204ad, 0x204af, 0x204b1, 0x204b3, - 0x204b5, 0x204b7, 0x204b9, 0x204bb, 0x204bd, 0x204bf, 0x204c2, 0x204c4, 0x204c6, - 0x204c8, 0x204ca, 0x204cc, 0x204ce, 0x204cf, 0x204d1, 0x204d3, 0x204d5, 0x204d7, - 0x204d9, 0x204db, 0x204dd, 0x204df, 0x204e1, 0x204e3, 0x204e5, 0x204e7, 0x204e9, - 0x204eb, 0x204ed, 0x204ef, 0x204f1, 0x204f3, 0x204f5, 0x204f7, 0x204f9, 0x204fb, - 0x204fd, 0x204ff, 0x20501, 0x20503, 0x20505, 0x20507, 0x20509, 0x2050b, 0x2050d, - 0x2050f, 0x20511, 0x20513, 0x20515, 0x20517, 0x20519, 0x2051b, 0x2051d, 0x2051f, - 0x20521, 0x20523, 0x20525, 0x20527, 0x20529, 0x2052b, 0x2052d, 0x2052f, 0x21e01, - 0x21e03, 0x21e05, 0x21e07, 0x21e09, 0x21e0b, 0x21e0d, 0x21e0f, 0x21e11, 0x21e13, - 0x21e15, 0x21e17, 0x21e19, 0x21e1b, 0x21e1d, 0x21e1f, 0x21e21, 0x21e23, 0x21e25, - 0x21e27, 0x21e29, 0x21e2b, 0x21e2d, 0x21e2f, 0x21e31, 0x21e33, 0x21e35, 0x21e37, - 0x21e39, 0x21e3b, 0x21e3d, 0x21e3f, 0x21e41, 0x21e43, 0x21e45, 0x21e47, 0x21e49, - 0x21e4b, 0x21e4d, 0x21e4f, 0x21e51, 0x21e53, 0x21e55, 0x21e57, 0x21e59, 0x21e5b, - 0x21e5d, 0x21e5f, 0x21e61, 0x21e63, 0x21e65, 0x21e67, 0x21e69, 0x21e6b, 0x21e6d, - 0x21e6f, 0x21e71, 0x21e73, 0x21e75, 0x21e77, 0x21e79, 0x21e7b, 0x21e7d, 0x21e7f, - 0x21e81, 0x21e83, 0x21e85, 0x21e87, 0x21e89, 0x21e8b, 0x21e8d, 0x21e8f, 0x21e91, - 0x21e93, 0x21e9f, 0x21ea1, 0x21ea3, 0x21ea5, 0x21ea7, 0x21ea9, 0x21eab, 0x21ead, - 0x21eaf, 0x21eb1, 0x21eb3, 0x21eb5, 0x21eb7, 0x21eb9, 0x21ebb, 0x21ebd, 0x21ebf, - 0x21ec1, 0x21ec3, 0x21ec5, 0x21ec7, 0x21ec9, 0x21ecb, 0x21ecd, 0x21ecf, 0x21ed1, - 0x21ed3, 0x21ed5, 0x21ed7, 0x21ed9, 0x21edb, 0x21edd, 0x21edf, 0x21ee1, 0x21ee3, - 0x21ee5, 0x21ee7, 0x21ee9, 0x21eeb, 0x21eed, 0x21eef, 0x21ef1, 0x21ef3, 0x21ef5, - 0x21ef7, 0x21ef9, 0x21efb, 0x21efd, 0x21fb6, 0x21fb7, 0x21fbe, 0x21fc6, 0x21fc7, - 0x21fd6, 0x21fd7, 0x21ff6, 0x21ff7, 0x2210a, 0x2210e, 0x2210f, 0x22113, 0x2212f, - 0x22134, 0x22139, 0x2213c, 0x2213d, 0x2214e, 0x22184, 0x22c61, 0x22c65, 0x22c66, - 0x22c68, 0x22c6a, 0x22c6c, 0x22c71, 0x22c73, 0x22c74, 0x22c81, 0x22c83, 0x22c85, - 0x22c87, 0x22c89, 0x22c8b, 0x22c8d, 0x22c8f, 0x22c91, 0x22c93, 0x22c95, 0x22c97, - 0x22c99, 0x22c9b, 0x22c9d, 0x22c9f, 0x22ca1, 0x22ca3, 0x22ca5, 0x22ca7, 0x22ca9, - 0x22cab, 0x22cad, 0x22caf, 0x22cb1, 0x22cb3, 0x22cb5, 0x22cb7, 0x22cb9, 0x22cbb, - 0x22cbd, 0x22cbf, 0x22cc1, 0x22cc3, 0x22cc5, 0x22cc7, 0x22cc9, 0x22ccb, 0x22ccd, - 0x22ccf, 0x22cd1, 0x22cd3, 0x22cd5, 0x22cd7, 0x22cd9, 0x22cdb, 0x22cdd, 0x22cdf, - 0x22ce1, 0x22ce3, 0x22ce4, 0x22cec, 0x22cee, 0x22cf3, 0x22d27, 0x22d2d, 0x2a641, - 0x2a643, 0x2a645, 0x2a647, 0x2a649, 0x2a64b, 0x2a64d, 0x2a64f, 0x2a651, 0x2a653, - 0x2a655, 0x2a657, 0x2a659, 0x2a65b, 0x2a65d, 0x2a65f, 0x2a661, 0x2a663, 0x2a665, - 0x2a667, 0x2a669, 0x2a66b, 0x2a66d, 0x2a681, 0x2a683, 0x2a685, 0x2a687, 0x2a689, - 0x2a68b, 0x2a68d, 0x2a68f, 0x2a691, 0x2a693, 0x2a695, 0x2a697, 0x2a699, 0x2a69b, - 0x2a723, 0x2a725, 0x2a727, 0x2a729, 0x2a72b, 0x2a72d, 0x2a733, 0x2a735, 0x2a737, - 0x2a739, 0x2a73b, 0x2a73d, 0x2a73f, 0x2a741, 0x2a743, 0x2a745, 0x2a747, 0x2a749, - 0x2a74b, 0x2a74d, 0x2a74f, 0x2a751, 0x2a753, 0x2a755, 0x2a757, 0x2a759, 0x2a75b, - 0x2a75d, 0x2a75f, 0x2a761, 0x2a763, 0x2a765, 0x2a767, 0x2a769, 0x2a76b, 0x2a76d, - 0x2a76f, 0x2a77a, 0x2a77c, 0x2a77f, 0x2a781, 0x2a783, 0x2a785, 0x2a787, 0x2a78c, - 0x2a78e, 0x2a791, 0x2a797, 0x2a799, 0x2a79b, 0x2a79d, 0x2a79f, 0x2a7a1, 0x2a7a3, - 0x2a7a5, 0x2a7a7, 0x2a7a9, 0x2a7b5, 0x2a7b7, 0x2a7fa, 0x300b5, 0x30101, 0x30103, - 0x30105, 0x30107, 0x30109, 0x3010b, 0x3010d, 0x3010f, 0x30111, 0x30113, 0x30115, - 0x30117, 0x30119, 0x3011b, 0x3011d, 0x3011f, 0x30121, 0x30123, 0x30125, 0x30127, - 0x30129, 0x3012b, 0x3012d, 0x3012f, 0x30131, 0x30133, 0x30135, 0x30137, 0x30138, - 0x3013a, 0x3013c, 0x3013e, 0x30140, 0x30142, 0x30144, 0x30146, 0x30148, 0x30149, - 0x3014b, 0x3014d, 0x3014f, 0x30151, 0x30153, 0x30155, 0x30157, 0x30159, 0x3015b, - 0x3015d, 0x3015f, 0x30161, 0x30163, 0x30165, 0x30167, 0x30169, 0x3016b, 0x3016d, - 0x3016f, 0x30171, 0x30173, 0x30175, 0x30177, 0x3017a, 0x3017c, 0x30183, 0x30185, - 0x30188, 0x3018c, 0x3018d, 0x30192, 0x30195, 0x3019e, 0x301a1, 0x301a3, 0x301a5, - 0x301a8, 0x301aa, 0x301ab, 0x301ad, 0x301b0, 0x301b4, 0x301b6, 0x301b9, 0x301ba, - 0x301c6, 0x301c9, 0x301cc, 0x301ce, 0x301d0, 0x301d2, 0x301d4, 0x301d6, 0x301d8, - 0x301da, 0x301dc, 0x301dd, 0x301df, 0x301e1, 0x301e3, 0x301e5, 0x301e7, 0x301e9, - 0x301eb, 0x301ed, 0x301ef, 0x301f0, 0x301f3, 0x301f5, 0x301f9, 0x301fb, 0x301fd, - 0x301ff, 0x30201, 0x30203, 0x30205, 0x30207, 0x30209, 0x3020b, 0x3020d, 0x3020f, - 0x30211, 0x30213, 0x30215, 0x30217, 0x30219, 0x3021b, 0x3021d, 0x3021f, 0x30221, - 0x30223, 0x30225, 0x30227, 0x30229, 0x3022b, 0x3022d, 0x3022f, 0x30231, 0x3023c, - 0x3023f, 0x30240, 0x30242, 0x30247, 0x30249, 0x3024b, 0x3024d, 0x30371, 0x30373, - 0x30377, 0x30390, 0x303d0, 0x303d1, 0x303d9, 0x303db, 0x303dd, 0x303df, 0x303e1, - 0x303e3, 0x303e5, 0x303e7, 0x303e9, 0x303eb, 0x303ed, 0x303f5, 0x303f8, 0x303fb, - 0x303fc, 0x30461, 0x30463, 0x30465, 0x30467, 0x30469, 0x3046b, 0x3046d, 0x3046f, - 0x30471, 0x30473, 0x30475, 0x30477, 0x30479, 0x3047b, 0x3047d, 0x3047f, 0x30481, - 0x3048b, 0x3048d, 0x3048f, 0x30491, 0x30493, 0x30495, 0x30497, 0x30499, 0x3049b, - 0x3049d, 0x3049f, 0x304a1, 0x304a3, 0x304a5, 0x304a7, 0x304a9, 0x304ab, 0x304ad, - 0x304af, 0x304b1, 0x304b3, 0x304b5, 0x304b7, 0x304b9, 0x304bb, 0x304bd, 0x304bf, - 0x304c2, 0x304c4, 0x304c6, 0x304c8, 0x304ca, 0x304cc, 0x304ce, 0x304cf, 0x304d1, - 0x304d3, 0x304d5, 0x304d7, 0x304d9, 0x304db, 0x304dd, 0x304df, 0x304e1, 0x304e3, - 0x304e5, 0x304e7, 0x304e9, 0x304eb, 0x304ed, 0x304ef, 0x304f1, 0x304f3, 0x304f5, - 0x304f7, 0x304f9, 0x304fb, 0x304fd, 0x304ff, 0x30501, 0x30503, 0x30505, 0x30507, - 0x30509, 0x3050b, 0x3050d, 0x3050f, 0x30511, 0x30513, 0x30515, 0x30517, 0x30519, - 0x3051b, 0x3051d, 0x3051f, 0x30521, 0x30523, 0x30525, 0x30527, 0x30529, 0x3052b, - 0x3052d, 0x3052f, 0x31e01, 0x31e03, 0x31e05, 0x31e07, 0x31e09, 0x31e0b, 0x31e0d, - 0x31e0f, 0x31e11, 0x31e13, 0x31e15, 0x31e17, 0x31e19, 0x31e1b, 0x31e1d, 0x31e1f, - 0x31e21, 0x31e23, 0x31e25, 0x31e27, 0x31e29, 0x31e2b, 0x31e2d, 0x31e2f, 0x31e31, - 0x31e33, 0x31e35, 0x31e37, 0x31e39, 0x31e3b, 0x31e3d, 0x31e3f, 0x31e41, 0x31e43, - 0x31e45, 0x31e47, 0x31e49, 0x31e4b, 0x31e4d, 0x31e4f, 0x31e51, 0x31e53, 0x31e55, - 0x31e57, 0x31e59, 0x31e5b, 0x31e5d, 0x31e5f, 0x31e61, 0x31e63, 0x31e65, 0x31e67, - 0x31e69, 0x31e6b, 0x31e6d, 0x31e6f, 0x31e71, 0x31e73, 0x31e75, 0x31e77, 0x31e79, - 0x31e7b, 0x31e7d, 0x31e7f, 0x31e81, 0x31e83, 0x31e85, 0x31e87, 0x31e89, 0x31e8b, - 0x31e8d, 0x31e8f, 0x31e91, 0x31e93, 0x31e9f, 0x31ea1, 0x31ea3, 0x31ea5, 0x31ea7, - 0x31ea9, 0x31eab, 0x31ead, 0x31eaf, 0x31eb1, 0x31eb3, 0x31eb5, 0x31eb7, 0x31eb9, - 0x31ebb, 0x31ebd, 0x31ebf, 0x31ec1, 0x31ec3, 0x31ec5, 0x31ec7, 0x31ec9, 0x31ecb, - 0x31ecd, 0x31ecf, 0x31ed1, 0x31ed3, 0x31ed5, 0x31ed7, 0x31ed9, 0x31edb, 0x31edd, - 0x31edf, 0x31ee1, 0x31ee3, 0x31ee5, 0x31ee7, 0x31ee9, 0x31eeb, 0x31eed, 0x31eef, - 0x31ef1, 0x31ef3, 0x31ef5, 0x31ef7, 0x31ef9, 0x31efb, 0x31efd, 0x31fb6, 0x31fb7, - 0x31fbe, 0x31fc6, 0x31fc7, 0x31fd6, 0x31fd7, 0x31ff6, 0x31ff7, 0x3210a, 0x3210e, - 0x3210f, 0x32113, 0x3212f, 0x32134, 0x32139, 0x3213c, 0x3213d, 0x3214e, 0x32184, - 0x32c61, 0x32c65, 0x32c66, 0x32c68, 0x32c6a, 0x32c6c, 0x32c71, 0x32c73, 0x32c74, - 0x32c81, 0x32c83, 0x32c85, 0x32c87, 0x32c89, 0x32c8b, 0x32c8d, 0x32c8f, 0x32c91, - 0x32c93, 0x32c95, 0x32c97, 0x32c99, 0x32c9b, 0x32c9d, 0x32c9f, 0x32ca1, 0x32ca3, - 0x32ca5, 0x32ca7, 0x32ca9, 0x32cab, 0x32cad, 0x32caf, 0x32cb1, 0x32cb3, 0x32cb5, - 0x32cb7, 0x32cb9, 0x32cbb, 0x32cbd, 0x32cbf, 0x32cc1, 0x32cc3, 0x32cc5, 0x32cc7, - 0x32cc9, 0x32ccb, 0x32ccd, 0x32ccf, 0x32cd1, 0x32cd3, 0x32cd5, 0x32cd7, 0x32cd9, - 0x32cdb, 0x32cdd, 0x32cdf, 0x32ce1, 0x32ce3, 0x32ce4, 0x32cec, 0x32cee, 0x32cf3, - 0x32d27, 0x32d2d, 0x3a641, 0x3a643, 0x3a645, 0x3a647, 0x3a649, 0x3a64b, 0x3a64d, - 0x3a64f, 0x3a651, 0x3a653, 0x3a655, 0x3a657, 0x3a659, 0x3a65b, 0x3a65d, 0x3a65f, - 0x3a661, 0x3a663, 0x3a665, 0x3a667, 0x3a669, 0x3a66b, 0x3a66d, 0x3a681, 0x3a683, - 0x3a685, 0x3a687, 0x3a689, 0x3a68b, 0x3a68d, 0x3a68f, 0x3a691, 0x3a693, 0x3a695, - 0x3a697, 0x3a699, 0x3a69b, 0x3a723, 0x3a725, 0x3a727, 0x3a729, 0x3a72b, 0x3a72d, - 0x3a733, 0x3a735, 0x3a737, 0x3a739, 0x3a73b, 0x3a73d, 0x3a73f, 0x3a741, 0x3a743, - 0x3a745, 0x3a747, 0x3a749, 0x3a74b, 0x3a74d, 0x3a74f, 0x3a751, 0x3a753, 0x3a755, - 0x3a757, 0x3a759, 0x3a75b, 0x3a75d, 0x3a75f, 0x3a761, 0x3a763, 0x3a765, 0x3a767, - 0x3a769, 0x3a76b, 0x3a76d, 0x3a76f, 0x3a77a, 0x3a77c, 0x3a77f, 0x3a781, 0x3a783, - 0x3a785, 0x3a787, 0x3a78c, 0x3a78e, 0x3a791, 0x3a797, 0x3a799, 0x3a79b, 0x3a79d, - 0x3a79f, 0x3a7a1, 0x3a7a3, 0x3a7a5, 0x3a7a7, 0x3a7a9, 0x3a7b5, 0x3a7b7, 0x3a7fa, - 0x400b5, 0x40101, 0x40103, 0x40105, 0x40107, 0x40109, 0x4010b, 0x4010d, 0x4010f, - 0x40111, 0x40113, 0x40115, 0x40117, 0x40119, 0x4011b, 0x4011d, 0x4011f, 0x40121, - 0x40123, 0x40125, 0x40127, 0x40129, 0x4012b, 0x4012d, 0x4012f, 0x40131, 0x40133, - 0x40135, 0x40137, 0x40138, 0x4013a, 0x4013c, 0x4013e, 0x40140, 0x40142, 0x40144, - 0x40146, 0x40148, 0x40149, 0x4014b, 0x4014d, 0x4014f, 0x40151, 0x40153, 0x40155, - 0x40157, 0x40159, 0x4015b, 0x4015d, 0x4015f, 0x40161, 0x40163, 0x40165, 0x40167, - 0x40169, 0x4016b, 0x4016d, 0x4016f, 0x40171, 0x40173, 0x40175, 0x40177, 0x4017a, - 0x4017c, 0x40183, 0x40185, 0x40188, 0x4018c, 0x4018d, 0x40192, 0x40195, 0x4019e, - 0x401a1, 0x401a3, 0x401a5, 0x401a8, 0x401aa, 0x401ab, 0x401ad, 0x401b0, 0x401b4, - 0x401b6, 0x401b9, 0x401ba, 0x401c6, 0x401c9, 0x401cc, 0x401ce, 0x401d0, 0x401d2, - 0x401d4, 0x401d6, 0x401d8, 0x401da, 0x401dc, 0x401dd, 0x401df, 0x401e1, 0x401e3, - 0x401e5, 0x401e7, 0x401e9, 0x401eb, 0x401ed, 0x401ef, 0x401f0, 0x401f3, 0x401f5, - 0x401f9, 0x401fb, 0x401fd, 0x401ff, 0x40201, 0x40203, 0x40205, 0x40207, 0x40209, - 0x4020b, 0x4020d, 0x4020f, 0x40211, 0x40213, 0x40215, 0x40217, 0x40219, 0x4021b, - 0x4021d, 0x4021f, 0x40221, 0x40223, 0x40225, 0x40227, 0x40229, 0x4022b, 0x4022d, - 0x4022f, 0x40231, 0x4023c, 0x4023f, 0x40240, 0x40242, 0x40247, 0x40249, 0x4024b, - 0x4024d, 0x40371, 0x40373, 0x40377, 0x40390, 0x403d0, 0x403d1, 0x403d9, 0x403db, - 0x403dd, 0x403df, 0x403e1, 0x403e3, 0x403e5, 0x403e7, 0x403e9, 0x403eb, 0x403ed, - 0x403f5, 0x403f8, 0x403fb, 0x403fc, 0x40461, 0x40463, 0x40465, 0x40467, 0x40469, - 0x4046b, 0x4046d, 0x4046f, 0x40471, 0x40473, 0x40475, 0x40477, 0x40479, 0x4047b, - 0x4047d, 0x4047f, 0x40481, 0x4048b, 0x4048d, 0x4048f, 0x40491, 0x40493, 0x40495, - 0x40497, 0x40499, 0x4049b, 0x4049d, 0x4049f, 0x404a1, 0x404a3, 0x404a5, 0x404a7, - 0x404a9, 0x404ab, 0x404ad, 0x404af, 0x404b1, 0x404b3, 0x404b5, 0x404b7, 0x404b9, - 0x404bb, 0x404bd, 0x404bf, 0x404c2, 0x404c4, 0x404c6, 0x404c8, 0x404ca, 0x404cc, - 0x404ce, 0x404cf, 0x404d1, 0x404d3, 0x404d5, 0x404d7, 0x404d9, 0x404db, 0x404dd, - 0x404df, 0x404e1, 0x404e3, 0x404e5, 0x404e7, 0x404e9, 0x404eb, 0x404ed, 0x404ef, - 0x404f1, 0x404f3, 0x404f5, 0x404f7, 0x404f9, 0x404fb, 0x404fd, 0x404ff, 0x40501, - 0x40503, 0x40505, 0x40507, 0x40509, 0x4050b, 0x4050d, 0x4050f, 0x40511, 0x40513, - 0x40515, 0x40517, 0x40519, 0x4051b, 0x4051d, 0x4051f, 0x40521, 0x40523, 0x40525, - 0x40527, 0x40529, 0x4052b, 0x4052d, 0x4052f, 0x41e01, 0x41e03, 0x41e05, 0x41e07, - 0x41e09, 0x41e0b, 0x41e0d, 0x41e0f, 0x41e11, 0x41e13, 0x41e15, 0x41e17, 0x41e19, - 0x41e1b, 0x41e1d, 0x41e1f, 0x41e21, 0x41e23, 0x41e25, 0x41e27, 0x41e29, 0x41e2b, - 0x41e2d, 0x41e2f, 0x41e31, 0x41e33, 0x41e35, 0x41e37, 0x41e39, 0x41e3b, 0x41e3d, - 0x41e3f, 0x41e41, 0x41e43, 0x41e45, 0x41e47, 0x41e49, 0x41e4b, 0x41e4d, 0x41e4f, - 0x41e51, 0x41e53, 0x41e55, 0x41e57, 0x41e59, 0x41e5b, 0x41e5d, 0x41e5f, 0x41e61, - 0x41e63, 0x41e65, 0x41e67, 0x41e69, 0x41e6b, 0x41e6d, 0x41e6f, 0x41e71, 0x41e73, - 0x41e75, 0x41e77, 0x41e79, 0x41e7b, 0x41e7d, 0x41e7f, 0x41e81, 0x41e83, 0x41e85, - 0x41e87, 0x41e89, 0x41e8b, 0x41e8d, 0x41e8f, 0x41e91, 0x41e93, 0x41e9f, 0x41ea1, - 0x41ea3, 0x41ea5, 0x41ea7, 0x41ea9, 0x41eab, 0x41ead, 0x41eaf, 0x41eb1, 0x41eb3, - 0x41eb5, 0x41eb7, 0x41eb9, 0x41ebb, 0x41ebd, 0x41ebf, 0x41ec1, 0x41ec3, 0x41ec5, - 0x41ec7, 0x41ec9, 0x41ecb, 0x41ecd, 0x41ecf, 0x41ed1, 0x41ed3, 0x41ed5, 0x41ed7, - 0x41ed9, 0x41edb, 0x41edd, 0x41edf, 0x41ee1, 0x41ee3, 0x41ee5, 0x41ee7, 0x41ee9, - 0x41eeb, 0x41eed, 0x41eef, 0x41ef1, 0x41ef3, 0x41ef5, 0x41ef7, 0x41ef9, 0x41efb, - 0x41efd, 0x41fb6, 0x41fb7, 0x41fbe, 0x41fc6, 0x41fc7, 0x41fd6, 0x41fd7, 0x41ff6, - 0x41ff7, 0x4210a, 0x4210e, 0x4210f, 0x42113, 0x4212f, 0x42134, 0x42139, 0x4213c, - 0x4213d, 0x4214e, 0x42184, 0x42c61, 0x42c65, 0x42c66, 0x42c68, 0x42c6a, 0x42c6c, - 0x42c71, 0x42c73, 0x42c74, 0x42c81, 0x42c83, 0x42c85, 0x42c87, 0x42c89, 0x42c8b, - 0x42c8d, 0x42c8f, 0x42c91, 0x42c93, 0x42c95, 0x42c97, 0x42c99, 0x42c9b, 0x42c9d, - 0x42c9f, 0x42ca1, 0x42ca3, 0x42ca5, 0x42ca7, 0x42ca9, 0x42cab, 0x42cad, 0x42caf, - 0x42cb1, 0x42cb3, 0x42cb5, 0x42cb7, 0x42cb9, 0x42cbb, 0x42cbd, 0x42cbf, 0x42cc1, - 0x42cc3, 0x42cc5, 0x42cc7, 0x42cc9, 0x42ccb, 0x42ccd, 0x42ccf, 0x42cd1, 0x42cd3, - 0x42cd5, 0x42cd7, 0x42cd9, 0x42cdb, 0x42cdd, 0x42cdf, 0x42ce1, 0x42ce3, 0x42ce4, - 0x42cec, 0x42cee, 0x42cf3, 0x42d27, 0x42d2d, 0x4a641, 0x4a643, 0x4a645, 0x4a647, - 0x4a649, 0x4a64b, 0x4a64d, 0x4a64f, 0x4a651, 0x4a653, 0x4a655, 0x4a657, 0x4a659, - 0x4a65b, 0x4a65d, 0x4a65f, 0x4a661, 0x4a663, 0x4a665, 0x4a667, 0x4a669, 0x4a66b, - 0x4a66d, 0x4a681, 0x4a683, 0x4a685, 0x4a687, 0x4a689, 0x4a68b, 0x4a68d, 0x4a68f, - 0x4a691, 0x4a693, 0x4a695, 0x4a697, 0x4a699, 0x4a69b, 0x4a723, 0x4a725, 0x4a727, - 0x4a729, 0x4a72b, 0x4a72d, 0x4a733, 0x4a735, 0x4a737, 0x4a739, 0x4a73b, 0x4a73d, - 0x4a73f, 0x4a741, 0x4a743, 0x4a745, 0x4a747, 0x4a749, 0x4a74b, 0x4a74d, 0x4a74f, - 0x4a751, 0x4a753, 0x4a755, 0x4a757, 0x4a759, 0x4a75b, 0x4a75d, 0x4a75f, 0x4a761, - 0x4a763, 0x4a765, 0x4a767, 0x4a769, 0x4a76b, 0x4a76d, 0x4a76f, 0x4a77a, 0x4a77c, - 0x4a77f, 0x4a781, 0x4a783, 0x4a785, 0x4a787, 0x4a78c, 0x4a78e, 0x4a791, 0x4a797, - 0x4a799, 0x4a79b, 0x4a79d, 0x4a79f, 0x4a7a1, 0x4a7a3, 0x4a7a5, 0x4a7a7, 0x4a7a9, - 0x4a7b5, 0x4a7b7, 0x4a7fa, 0x500b5, 0x50101, 0x50103, 0x50105, 0x50107, 0x50109, - 0x5010b, 0x5010d, 0x5010f, 0x50111, 0x50113, 0x50115, 0x50117, 0x50119, 0x5011b, - 0x5011d, 0x5011f, 0x50121, 0x50123, 0x50125, 0x50127, 0x50129, 0x5012b, 0x5012d, - 0x5012f, 0x50131, 0x50133, 0x50135, 0x50137, 0x50138, 0x5013a, 0x5013c, 0x5013e, - 0x50140, 0x50142, 0x50144, 0x50146, 0x50148, 0x50149, 0x5014b, 0x5014d, 0x5014f, - 0x50151, 0x50153, 0x50155, 0x50157, 0x50159, 0x5015b, 0x5015d, 0x5015f, 0x50161, - 0x50163, 0x50165, 0x50167, 0x50169, 0x5016b, 0x5016d, 0x5016f, 0x50171, 0x50173, - 0x50175, 0x50177, 0x5017a, 0x5017c, 0x50183, 0x50185, 0x50188, 0x5018c, 0x5018d, - 0x50192, 0x50195, 0x5019e, 0x501a1, 0x501a3, 0x501a5, 0x501a8, 0x501aa, 0x501ab, - 0x501ad, 0x501b0, 0x501b4, 0x501b6, 0x501b9, 0x501ba, 0x501c6, 0x501c9, 0x501cc, - 0x501ce, 0x501d0, 0x501d2, 0x501d4, 0x501d6, 0x501d8, 0x501da, 0x501dc, 0x501dd, - 0x501df, 0x501e1, 0x501e3, 0x501e5, 0x501e7, 0x501e9, 0x501eb, 0x501ed, 0x501ef, - 0x501f0, 0x501f3, 0x501f5, 0x501f9, 0x501fb, 0x501fd, 0x501ff, 0x50201, 0x50203, - 0x50205, 0x50207, 0x50209, 0x5020b, 0x5020d, 0x5020f, 0x50211, 0x50213, 0x50215, - 0x50217, 0x50219, 0x5021b, 0x5021d, 0x5021f, 0x50221, 0x50223, 0x50225, 0x50227, - 0x50229, 0x5022b, 0x5022d, 0x5022f, 0x50231, 0x5023c, 0x5023f, 0x50240, 0x50242, - 0x50247, 0x50249, 0x5024b, 0x5024d, 0x50371, 0x50373, 0x50377, 0x50390, 0x503d0, - 0x503d1, 0x503d9, 0x503db, 0x503dd, 0x503df, 0x503e1, 0x503e3, 0x503e5, 0x503e7, - 0x503e9, 0x503eb, 0x503ed, 0x503f5, 0x503f8, 0x503fb, 0x503fc, 0x50461, 0x50463, - 0x50465, 0x50467, 0x50469, 0x5046b, 0x5046d, 0x5046f, 0x50471, 0x50473, 0x50475, - 0x50477, 0x50479, 0x5047b, 0x5047d, 0x5047f, 0x50481, 0x5048b, 0x5048d, 0x5048f, - 0x50491, 0x50493, 0x50495, 0x50497, 0x50499, 0x5049b, 0x5049d, 0x5049f, 0x504a1, - 0x504a3, 0x504a5, 0x504a7, 0x504a9, 0x504ab, 0x504ad, 0x504af, 0x504b1, 0x504b3, - 0x504b5, 0x504b7, 0x504b9, 0x504bb, 0x504bd, 0x504bf, 0x504c2, 0x504c4, 0x504c6, - 0x504c8, 0x504ca, 0x504cc, 0x504ce, 0x504cf, 0x504d1, 0x504d3, 0x504d5, 0x504d7, - 0x504d9, 0x504db, 0x504dd, 0x504df, 0x504e1, 0x504e3, 0x504e5, 0x504e7, 0x504e9, - 0x504eb, 0x504ed, 0x504ef, 0x504f1, 0x504f3, 0x504f5, 0x504f7, 0x504f9, 0x504fb, - 0x504fd, 0x504ff, 0x50501, 0x50503, 0x50505, 0x50507, 0x50509, 0x5050b, 0x5050d, - 0x5050f, 0x50511, 0x50513, 0x50515, 0x50517, 0x50519, 0x5051b, 0x5051d, 0x5051f, - 0x50521, 0x50523, 0x50525, 0x50527, 0x50529, 0x5052b, 0x5052d, 0x5052f, 0x51e01, - 0x51e03, 0x51e05, 0x51e07, 0x51e09, 0x51e0b, 0x51e0d, 0x51e0f, 0x51e11, 0x51e13, - 0x51e15, 0x51e17, 0x51e19, 0x51e1b, 0x51e1d, 0x51e1f, 0x51e21, 0x51e23, 0x51e25, - 0x51e27, 0x51e29, 0x51e2b, 0x51e2d, 0x51e2f, 0x51e31, 0x51e33, 0x51e35, 0x51e37, - 0x51e39, 0x51e3b, 0x51e3d, 0x51e3f, 0x51e41, 0x51e43, 0x51e45, 0x51e47, 0x51e49, - 0x51e4b, 0x51e4d, 0x51e4f, 0x51e51, 0x51e53, 0x51e55, 0x51e57, 0x51e59, 0x51e5b, - 0x51e5d, 0x51e5f, 0x51e61, 0x51e63, 0x51e65, 0x51e67, 0x51e69, 0x51e6b, 0x51e6d, - 0x51e6f, 0x51e71, 0x51e73, 0x51e75, 0x51e77, 0x51e79, 0x51e7b, 0x51e7d, 0x51e7f, - 0x51e81, 0x51e83, 0x51e85, 0x51e87, 0x51e89, 0x51e8b, 0x51e8d, 0x51e8f, 0x51e91, - 0x51e93, 0x51e9f, 0x51ea1, 0x51ea3, 0x51ea5, 0x51ea7, 0x51ea9, 0x51eab, 0x51ead, - 0x51eaf, 0x51eb1, 0x51eb3, 0x51eb5, 0x51eb7, 0x51eb9, 0x51ebb, 0x51ebd, 0x51ebf, - 0x51ec1, 0x51ec3, 0x51ec5, 0x51ec7, 0x51ec9, 0x51ecb, 0x51ecd, 0x51ecf, 0x51ed1, - 0x51ed3, 0x51ed5, 0x51ed7, 0x51ed9, 0x51edb, 0x51edd, 0x51edf, 0x51ee1, 0x51ee3, - 0x51ee5, 0x51ee7, 0x51ee9, 0x51eeb, 0x51eed, 0x51eef, 0x51ef1, 0x51ef3, 0x51ef5, - 0x51ef7, 0x51ef9, 0x51efb, 0x51efd, 0x51fb6, 0x51fb7, 0x51fbe, 0x51fc6, 0x51fc7, - 0x51fd6, 0x51fd7, 0x51ff6, 0x51ff7, 0x5210a, 0x5210e, 0x5210f, 0x52113, 0x5212f, - 0x52134, 0x52139, 0x5213c, 0x5213d, 0x5214e, 0x52184, 0x52c61, 0x52c65, 0x52c66, - 0x52c68, 0x52c6a, 0x52c6c, 0x52c71, 0x52c73, 0x52c74, 0x52c81, 0x52c83, 0x52c85, - 0x52c87, 0x52c89, 0x52c8b, 0x52c8d, 0x52c8f, 0x52c91, 0x52c93, 0x52c95, 0x52c97, - 0x52c99, 0x52c9b, 0x52c9d, 0x52c9f, 0x52ca1, 0x52ca3, 0x52ca5, 0x52ca7, 0x52ca9, - 0x52cab, 0x52cad, 0x52caf, 0x52cb1, 0x52cb3, 0x52cb5, 0x52cb7, 0x52cb9, 0x52cbb, - 0x52cbd, 0x52cbf, 0x52cc1, 0x52cc3, 0x52cc5, 0x52cc7, 0x52cc9, 0x52ccb, 0x52ccd, - 0x52ccf, 0x52cd1, 0x52cd3, 0x52cd5, 0x52cd7, 0x52cd9, 0x52cdb, 0x52cdd, 0x52cdf, - 0x52ce1, 0x52ce3, 0x52ce4, 0x52cec, 0x52cee, 0x52cf3, 0x52d27, 0x52d2d, 0x5a641, - 0x5a643, 0x5a645, 0x5a647, 0x5a649, 0x5a64b, 0x5a64d, 0x5a64f, 0x5a651, 0x5a653, - 0x5a655, 0x5a657, 0x5a659, 0x5a65b, 0x5a65d, 0x5a65f, 0x5a661, 0x5a663, 0x5a665, - 0x5a667, 0x5a669, 0x5a66b, 0x5a66d, 0x5a681, 0x5a683, 0x5a685, 0x5a687, 0x5a689, - 0x5a68b, 0x5a68d, 0x5a68f, 0x5a691, 0x5a693, 0x5a695, 0x5a697, 0x5a699, 0x5a69b, - 0x5a723, 0x5a725, 0x5a727, 0x5a729, 0x5a72b, 0x5a72d, 0x5a733, 0x5a735, 0x5a737, - 0x5a739, 0x5a73b, 0x5a73d, 0x5a73f, 0x5a741, 0x5a743, 0x5a745, 0x5a747, 0x5a749, - 0x5a74b, 0x5a74d, 0x5a74f, 0x5a751, 0x5a753, 0x5a755, 0x5a757, 0x5a759, 0x5a75b, - 0x5a75d, 0x5a75f, 0x5a761, 0x5a763, 0x5a765, 0x5a767, 0x5a769, 0x5a76b, 0x5a76d, - 0x5a76f, 0x5a77a, 0x5a77c, 0x5a77f, 0x5a781, 0x5a783, 0x5a785, 0x5a787, 0x5a78c, - 0x5a78e, 0x5a791, 0x5a797, 0x5a799, 0x5a79b, 0x5a79d, 0x5a79f, 0x5a7a1, 0x5a7a3, - 0x5a7a5, 0x5a7a7, 0x5a7a9, 0x5a7b5, 0x5a7b7, 0x5a7fa, 0x600b5, 0x60101, 0x60103, - 0x60105, 0x60107, 0x60109, 0x6010b, 0x6010d, 0x6010f, 0x60111, 0x60113, 0x60115, - 0x60117, 0x60119, 0x6011b, 0x6011d, 0x6011f, 0x60121, 0x60123, 0x60125, 0x60127, - 0x60129, 0x6012b, 0x6012d, 0x6012f, 0x60131, 0x60133, 0x60135, 0x60137, 0x60138, - 0x6013a, 0x6013c, 0x6013e, 0x60140, 0x60142, 0x60144, 0x60146, 0x60148, 0x60149, - 0x6014b, 0x6014d, 0x6014f, 0x60151, 0x60153, 0x60155, 0x60157, 0x60159, 0x6015b, - 0x6015d, 0x6015f, 0x60161, 0x60163, 0x60165, 0x60167, 0x60169, 0x6016b, 0x6016d, - 0x6016f, 0x60171, 0x60173, 0x60175, 0x60177, 0x6017a, 0x6017c, 0x60183, 0x60185, - 0x60188, 0x6018c, 0x6018d, 0x60192, 0x60195, 0x6019e, 0x601a1, 0x601a3, 0x601a5, - 0x601a8, 0x601aa, 0x601ab, 0x601ad, 0x601b0, 0x601b4, 0x601b6, 0x601b9, 0x601ba, - 0x601c6, 0x601c9, 0x601cc, 0x601ce, 0x601d0, 0x601d2, 0x601d4, 0x601d6, 0x601d8, - 0x601da, 0x601dc, 0x601dd, 0x601df, 0x601e1, 0x601e3, 0x601e5, 0x601e7, 0x601e9, - 0x601eb, 0x601ed, 0x601ef, 0x601f0, 0x601f3, 0x601f5, 0x601f9, 0x601fb, 0x601fd, - 0x601ff, 0x60201, 0x60203, 0x60205, 0x60207, 0x60209, 0x6020b, 0x6020d, 0x6020f, - 0x60211, 0x60213, 0x60215, 0x60217, 0x60219, 0x6021b, 0x6021d, 0x6021f, 0x60221, - 0x60223, 0x60225, 0x60227, 0x60229, 0x6022b, 0x6022d, 0x6022f, 0x60231, 0x6023c, - 0x6023f, 0x60240, 0x60242, 0x60247, 0x60249, 0x6024b, 0x6024d, 0x60371, 0x60373, - 0x60377, 0x60390, 0x603d0, 0x603d1, 0x603d9, 0x603db, 0x603dd, 0x603df, 0x603e1, - 0x603e3, 0x603e5, 0x603e7, 0x603e9, 0x603eb, 0x603ed, 0x603f5, 0x603f8, 0x603fb, - 0x603fc, 0x60461, 0x60463, 0x60465, 0x60467, 0x60469, 0x6046b, 0x6046d, 0x6046f, - 0x60471, 0x60473, 0x60475, 0x60477, 0x60479, 0x6047b, 0x6047d, 0x6047f, 0x60481, - 0x6048b, 0x6048d, 0x6048f, 0x60491, 0x60493, 0x60495, 0x60497, 0x60499, 0x6049b, - 0x6049d, 0x6049f, 0x604a1, 0x604a3, 0x604a5, 0x604a7, 0x604a9, 0x604ab, 0x604ad, - 0x604af, 0x604b1, 0x604b3, 0x604b5, 0x604b7, 0x604b9, 0x604bb, 0x604bd, 0x604bf, - 0x604c2, 0x604c4, 0x604c6, 0x604c8, 0x604ca, 0x604cc, 0x604ce, 0x604cf, 0x604d1, - 0x604d3, 0x604d5, 0x604d7, 0x604d9, 0x604db, 0x604dd, 0x604df, 0x604e1, 0x604e3, - 0x604e5, 0x604e7, 0x604e9, 0x604eb, 0x604ed, 0x604ef, 0x604f1, 0x604f3, 0x604f5, - 0x604f7, 0x604f9, 0x604fb, 0x604fd, 0x604ff, 0x60501, 0x60503, 0x60505, 0x60507, - 0x60509, 0x6050b, 0x6050d, 0x6050f, 0x60511, 0x60513, 0x60515, 0x60517, 0x60519, - 0x6051b, 0x6051d, 0x6051f, 0x60521, 0x60523, 0x60525, 0x60527, 0x60529, 0x6052b, - 0x6052d, 0x6052f, 0x61e01, 0x61e03, 0x61e05, 0x61e07, 0x61e09, 0x61e0b, 0x61e0d, - 0x61e0f, 0x61e11, 0x61e13, 0x61e15, 0x61e17, 0x61e19, 0x61e1b, 0x61e1d, 0x61e1f, - 0x61e21, 0x61e23, 0x61e25, 0x61e27, 0x61e29, 0x61e2b, 0x61e2d, 0x61e2f, 0x61e31, - 0x61e33, 0x61e35, 0x61e37, 0x61e39, 0x61e3b, 0x61e3d, 0x61e3f, 0x61e41, 0x61e43, - 0x61e45, 0x61e47, 0x61e49, 0x61e4b, 0x61e4d, 0x61e4f, 0x61e51, 0x61e53, 0x61e55, - 0x61e57, 0x61e59, 0x61e5b, 0x61e5d, 0x61e5f, 0x61e61, 0x61e63, 0x61e65, 0x61e67, - 0x61e69, 0x61e6b, 0x61e6d, 0x61e6f, 0x61e71, 0x61e73, 0x61e75, 0x61e77, 0x61e79, - 0x61e7b, 0x61e7d, 0x61e7f, 0x61e81, 0x61e83, 0x61e85, 0x61e87, 0x61e89, 0x61e8b, - 0x61e8d, 0x61e8f, 0x61e91, 0x61e93, 0x61e9f, 0x61ea1, 0x61ea3, 0x61ea5, 0x61ea7, - 0x61ea9, 0x61eab, 0x61ead, 0x61eaf, 0x61eb1, 0x61eb3, 0x61eb5, 0x61eb7, 0x61eb9, - 0x61ebb, 0x61ebd, 0x61ebf, 0x61ec1, 0x61ec3, 0x61ec5, 0x61ec7, 0x61ec9, 0x61ecb, - 0x61ecd, 0x61ecf, 0x61ed1, 0x61ed3, 0x61ed5, 0x61ed7, 0x61ed9, 0x61edb, 0x61edd, - 0x61edf, 0x61ee1, 0x61ee3, 0x61ee5, 0x61ee7, 0x61ee9, 0x61eeb, 0x61eed, 0x61eef, - 0x61ef1, 0x61ef3, 0x61ef5, 0x61ef7, 0x61ef9, 0x61efb, 0x61efd, 0x61fb6, 0x61fb7, - 0x61fbe, 0x61fc6, 0x61fc7, 0x61fd6, 0x61fd7, 0x61ff6, 0x61ff7, 0x6210a, 0x6210e, - 0x6210f, 0x62113, 0x6212f, 0x62134, 0x62139, 0x6213c, 0x6213d, 0x6214e, 0x62184, - 0x62c61, 0x62c65, 0x62c66, 0x62c68, 0x62c6a, 0x62c6c, 0x62c71, 0x62c73, 0x62c74, - 0x62c81, 0x62c83, 0x62c85, 0x62c87, 0x62c89, 0x62c8b, 0x62c8d, 0x62c8f, 0x62c91, - 0x62c93, 0x62c95, 0x62c97, 0x62c99, 0x62c9b, 0x62c9d, 0x62c9f, 0x62ca1, 0x62ca3, - 0x62ca5, 0x62ca7, 0x62ca9, 0x62cab, 0x62cad, 0x62caf, 0x62cb1, 0x62cb3, 0x62cb5, - 0x62cb7, 0x62cb9, 0x62cbb, 0x62cbd, 0x62cbf, 0x62cc1, 0x62cc3, 0x62cc5, 0x62cc7, - 0x62cc9, 0x62ccb, 0x62ccd, 0x62ccf, 0x62cd1, 0x62cd3, 0x62cd5, 0x62cd7, 0x62cd9, - 0x62cdb, 0x62cdd, 0x62cdf, 0x62ce1, 0x62ce3, 0x62ce4, 0x62cec, 0x62cee, 0x62cf3, - 0x62d27, 0x62d2d, 0x6a641, 0x6a643, 0x6a645, 0x6a647, 0x6a649, 0x6a64b, 0x6a64d, - 0x6a64f, 0x6a651, 0x6a653, 0x6a655, 0x6a657, 0x6a659, 0x6a65b, 0x6a65d, 0x6a65f, - 0x6a661, 0x6a663, 0x6a665, 0x6a667, 0x6a669, 0x6a66b, 0x6a66d, 0x6a681, 0x6a683, - 0x6a685, 0x6a687, 0x6a689, 0x6a68b, 0x6a68d, 0x6a68f, 0x6a691, 0x6a693, 0x6a695, - 0x6a697, 0x6a699, 0x6a69b, 0x6a723, 0x6a725, 0x6a727, 0x6a729, 0x6a72b, 0x6a72d, - 0x6a733, 0x6a735, 0x6a737, 0x6a739, 0x6a73b, 0x6a73d, 0x6a73f, 0x6a741, 0x6a743, - 0x6a745, 0x6a747, 0x6a749, 0x6a74b, 0x6a74d, 0x6a74f, 0x6a751, 0x6a753, 0x6a755, - 0x6a757, 0x6a759, 0x6a75b, 0x6a75d, 0x6a75f, 0x6a761, 0x6a763, 0x6a765, 0x6a767, - 0x6a769, 0x6a76b, 0x6a76d, 0x6a76f, 0x6a77a, 0x6a77c, 0x6a77f, 0x6a781, 0x6a783, - 0x6a785, 0x6a787, 0x6a78c, 0x6a78e, 0x6a791, 0x6a797, 0x6a799, 0x6a79b, 0x6a79d, - 0x6a79f, 0x6a7a1, 0x6a7a3, 0x6a7a5, 0x6a7a7, 0x6a7a9, 0x6a7b5, 0x6a7b7, 0x6a7fa, - 0x700b5, 0x70101, 0x70103, 0x70105, 0x70107, 0x70109, 0x7010b, 0x7010d, 0x7010f, - 0x70111, 0x70113, 0x70115, 0x70117, 0x70119, 0x7011b, 0x7011d, 0x7011f, 0x70121, - 0x70123, 0x70125, 0x70127, 0x70129, 0x7012b, 0x7012d, 0x7012f, 0x70131, 0x70133, - 0x70135, 0x70137, 0x70138, 0x7013a, 0x7013c, 0x7013e, 0x70140, 0x70142, 0x70144, - 0x70146, 0x70148, 0x70149, 0x7014b, 0x7014d, 0x7014f, 0x70151, 0x70153, 0x70155, - 0x70157, 0x70159, 0x7015b, 0x7015d, 0x7015f, 0x70161, 0x70163, 0x70165, 0x70167, - 0x70169, 0x7016b, 0x7016d, 0x7016f, 0x70171, 0x70173, 0x70175, 0x70177, 0x7017a, - 0x7017c, 0x70183, 0x70185, 0x70188, 0x7018c, 0x7018d, 0x70192, 0x70195, 0x7019e, - 0x701a1, 0x701a3, 0x701a5, 0x701a8, 0x701aa, 0x701ab, 0x701ad, 0x701b0, 0x701b4, - 0x701b6, 0x701b9, 0x701ba, 0x701c6, 0x701c9, 0x701cc, 0x701ce, 0x701d0, 0x701d2, - 0x701d4, 0x701d6, 0x701d8, 0x701da, 0x701dc, 0x701dd, 0x701df, 0x701e1, 0x701e3, - 0x701e5, 0x701e7, 0x701e9, 0x701eb, 0x701ed, 0x701ef, 0x701f0, 0x701f3, 0x701f5, - 0x701f9, 0x701fb, 0x701fd, 0x701ff, 0x70201, 0x70203, 0x70205, 0x70207, 0x70209, - 0x7020b, 0x7020d, 0x7020f, 0x70211, 0x70213, 0x70215, 0x70217, 0x70219, 0x7021b, - 0x7021d, 0x7021f, 0x70221, 0x70223, 0x70225, 0x70227, 0x70229, 0x7022b, 0x7022d, - 0x7022f, 0x70231, 0x7023c, 0x7023f, 0x70240, 0x70242, 0x70247, 0x70249, 0x7024b, - 0x7024d, 0x70371, 0x70373, 0x70377, 0x70390, 0x703d0, 0x703d1, 0x703d9, 0x703db, - 0x703dd, 0x703df, 0x703e1, 0x703e3, 0x703e5, 0x703e7, 0x703e9, 0x703eb, 0x703ed, - 0x703f5, 0x703f8, 0x703fb, 0x703fc, 0x70461, 0x70463, 0x70465, 0x70467, 0x70469, - 0x7046b, 0x7046d, 0x7046f, 0x70471, 0x70473, 0x70475, 0x70477, 0x70479, 0x7047b, - 0x7047d, 0x7047f, 0x70481, 0x7048b, 0x7048d, 0x7048f, 0x70491, 0x70493, 0x70495, - 0x70497, 0x70499, 0x7049b, 0x7049d, 0x7049f, 0x704a1, 0x704a3, 0x704a5, 0x704a7, - 0x704a9, 0x704ab, 0x704ad, 0x704af, 0x704b1, 0x704b3, 0x704b5, 0x704b7, 0x704b9, - 0x704bb, 0x704bd, 0x704bf, 0x704c2, 0x704c4, 0x704c6, 0x704c8, 0x704ca, 0x704cc, - 0x704ce, 0x704cf, 0x704d1, 0x704d3, 0x704d5, 0x704d7, 0x704d9, 0x704db, 0x704dd, - 0x704df, 0x704e1, 0x704e3, 0x704e5, 0x704e7, 0x704e9, 0x704eb, 0x704ed, 0x704ef, - 0x704f1, 0x704f3, 0x704f5, 0x704f7, 0x704f9, 0x704fb, 0x704fd, 0x704ff, 0x70501, - 0x70503, 0x70505, 0x70507, 0x70509, 0x7050b, 0x7050d, 0x7050f, 0x70511, 0x70513, - 0x70515, 0x70517, 0x70519, 0x7051b, 0x7051d, 0x7051f, 0x70521, 0x70523, 0x70525, - 0x70527, 0x70529, 0x7052b, 0x7052d, 0x7052f, 0x71e01, 0x71e03, 0x71e05, 0x71e07, - 0x71e09, 0x71e0b, 0x71e0d, 0x71e0f, 0x71e11, 0x71e13, 0x71e15, 0x71e17, 0x71e19, - 0x71e1b, 0x71e1d, 0x71e1f, 0x71e21, 0x71e23, 0x71e25, 0x71e27, 0x71e29, 0x71e2b, - 0x71e2d, 0x71e2f, 0x71e31, 0x71e33, 0x71e35, 0x71e37, 0x71e39, 0x71e3b, 0x71e3d, - 0x71e3f, 0x71e41, 0x71e43, 0x71e45, 0x71e47, 0x71e49, 0x71e4b, 0x71e4d, 0x71e4f, - 0x71e51, 0x71e53, 0x71e55, 0x71e57, 0x71e59, 0x71e5b, 0x71e5d, 0x71e5f, 0x71e61, - 0x71e63, 0x71e65, 0x71e67, 0x71e69, 0x71e6b, 0x71e6d, 0x71e6f, 0x71e71, 0x71e73, - 0x71e75, 0x71e77, 0x71e79, 0x71e7b, 0x71e7d, 0x71e7f, 0x71e81, 0x71e83, 0x71e85, - 0x71e87, 0x71e89, 0x71e8b, 0x71e8d, 0x71e8f, 0x71e91, 0x71e93, 0x71e9f, 0x71ea1, - 0x71ea3, 0x71ea5, 0x71ea7, 0x71ea9, 0x71eab, 0x71ead, 0x71eaf, 0x71eb1, 0x71eb3, - 0x71eb5, 0x71eb7, 0x71eb9, 0x71ebb, 0x71ebd, 0x71ebf, 0x71ec1, 0x71ec3, 0x71ec5, - 0x71ec7, 0x71ec9, 0x71ecb, 0x71ecd, 0x71ecf, 0x71ed1, 0x71ed3, 0x71ed5, 0x71ed7, - 0x71ed9, 0x71edb, 0x71edd, 0x71edf, 0x71ee1, 0x71ee3, 0x71ee5, 0x71ee7, 0x71ee9, - 0x71eeb, 0x71eed, 0x71eef, 0x71ef1, 0x71ef3, 0x71ef5, 0x71ef7, 0x71ef9, 0x71efb, - 0x71efd, 0x71fb6, 0x71fb7, 0x71fbe, 0x71fc6, 0x71fc7, 0x71fd6, 0x71fd7, 0x71ff6, - 0x71ff7, 0x7210a, 0x7210e, 0x7210f, 0x72113, 0x7212f, 0x72134, 0x72139, 0x7213c, - 0x7213d, 0x7214e, 0x72184, 0x72c61, 0x72c65, 0x72c66, 0x72c68, 0x72c6a, 0x72c6c, - 0x72c71, 0x72c73, 0x72c74, 0x72c81, 0x72c83, 0x72c85, 0x72c87, 0x72c89, 0x72c8b, - 0x72c8d, 0x72c8f, 0x72c91, 0x72c93, 0x72c95, 0x72c97, 0x72c99, 0x72c9b, 0x72c9d, - 0x72c9f, 0x72ca1, 0x72ca3, 0x72ca5, 0x72ca7, 0x72ca9, 0x72cab, 0x72cad, 0x72caf, - 0x72cb1, 0x72cb3, 0x72cb5, 0x72cb7, 0x72cb9, 0x72cbb, 0x72cbd, 0x72cbf, 0x72cc1, - 0x72cc3, 0x72cc5, 0x72cc7, 0x72cc9, 0x72ccb, 0x72ccd, 0x72ccf, 0x72cd1, 0x72cd3, - 0x72cd5, 0x72cd7, 0x72cd9, 0x72cdb, 0x72cdd, 0x72cdf, 0x72ce1, 0x72ce3, 0x72ce4, - 0x72cec, 0x72cee, 0x72cf3, 0x72d27, 0x72d2d, 0x7a641, 0x7a643, 0x7a645, 0x7a647, - 0x7a649, 0x7a64b, 0x7a64d, 0x7a64f, 0x7a651, 0x7a653, 0x7a655, 0x7a657, 0x7a659, - 0x7a65b, 0x7a65d, 0x7a65f, 0x7a661, 0x7a663, 0x7a665, 0x7a667, 0x7a669, 0x7a66b, - 0x7a66d, 0x7a681, 0x7a683, 0x7a685, 0x7a687, 0x7a689, 0x7a68b, 0x7a68d, 0x7a68f, - 0x7a691, 0x7a693, 0x7a695, 0x7a697, 0x7a699, 0x7a69b, 0x7a723, 0x7a725, 0x7a727, - 0x7a729, 0x7a72b, 0x7a72d, 0x7a733, 0x7a735, 0x7a737, 0x7a739, 0x7a73b, 0x7a73d, - 0x7a73f, 0x7a741, 0x7a743, 0x7a745, 0x7a747, 0x7a749, 0x7a74b, 0x7a74d, 0x7a74f, - 0x7a751, 0x7a753, 0x7a755, 0x7a757, 0x7a759, 0x7a75b, 0x7a75d, 0x7a75f, 0x7a761, - 0x7a763, 0x7a765, 0x7a767, 0x7a769, 0x7a76b, 0x7a76d, 0x7a76f, 0x7a77a, 0x7a77c, - 0x7a77f, 0x7a781, 0x7a783, 0x7a785, 0x7a787, 0x7a78c, 0x7a78e, 0x7a791, 0x7a797, - 0x7a799, 0x7a79b, 0x7a79d, 0x7a79f, 0x7a7a1, 0x7a7a3, 0x7a7a5, 0x7a7a7, 0x7a7a9, - 0x7a7b5, 0x7a7b7, 0x7a7fa, 0x800b5, 0x80101, 0x80103, 0x80105, 0x80107, 0x80109, - 0x8010b, 0x8010d, 0x8010f, 0x80111, 0x80113, 0x80115, 0x80117, 0x80119, 0x8011b, - 0x8011d, 0x8011f, 0x80121, 0x80123, 0x80125, 0x80127, 0x80129, 0x8012b, 0x8012d, - 0x8012f, 0x80131, 0x80133, 0x80135, 0x80137, 0x80138, 0x8013a, 0x8013c, 0x8013e, - 0x80140, 0x80142, 0x80144, 0x80146, 0x80148, 0x80149, 0x8014b, 0x8014d, 0x8014f, - 0x80151, 0x80153, 0x80155, 0x80157, 0x80159, 0x8015b, 0x8015d, 0x8015f, 0x80161, - 0x80163, 0x80165, 0x80167, 0x80169, 0x8016b, 0x8016d, 0x8016f, 0x80171, 0x80173, - 0x80175, 0x80177, 0x8017a, 0x8017c, 0x80183, 0x80185, 0x80188, 0x8018c, 0x8018d, - 0x80192, 0x80195, 0x8019e, 0x801a1, 0x801a3, 0x801a5, 0x801a8, 0x801aa, 0x801ab, - 0x801ad, 0x801b0, 0x801b4, 0x801b6, 0x801b9, 0x801ba, 0x801c6, 0x801c9, 0x801cc, - 0x801ce, 0x801d0, 0x801d2, 0x801d4, 0x801d6, 0x801d8, 0x801da, 0x801dc, 0x801dd, - 0x801df, 0x801e1, 0x801e3, 0x801e5, 0x801e7, 0x801e9, 0x801eb, 0x801ed, 0x801ef, - 0x801f0, 0x801f3, 0x801f5, 0x801f9, 0x801fb, 0x801fd, 0x801ff, 0x80201, 0x80203, - 0x80205, 0x80207, 0x80209, 0x8020b, 0x8020d, 0x8020f, 0x80211, 0x80213, 0x80215, - 0x80217, 0x80219, 0x8021b, 0x8021d, 0x8021f, 0x80221, 0x80223, 0x80225, 0x80227, - 0x80229, 0x8022b, 0x8022d, 0x8022f, 0x80231, 0x8023c, 0x8023f, 0x80240, 0x80242, - 0x80247, 0x80249, 0x8024b, 0x8024d, 0x80371, 0x80373, 0x80377, 0x80390, 0x803d0, - 0x803d1, 0x803d9, 0x803db, 0x803dd, 0x803df, 0x803e1, 0x803e3, 0x803e5, 0x803e7, - 0x803e9, 0x803eb, 0x803ed, 0x803f5, 0x803f8, 0x803fb, 0x803fc, 0x80461, 0x80463, - 0x80465, 0x80467, 0x80469, 0x8046b, 0x8046d, 0x8046f, 0x80471, 0x80473, 0x80475, - 0x80477, 0x80479, 0x8047b, 0x8047d, 0x8047f, 0x80481, 0x8048b, 0x8048d, 0x8048f, - 0x80491, 0x80493, 0x80495, 0x80497, 0x80499, 0x8049b, 0x8049d, 0x8049f, 0x804a1, - 0x804a3, 0x804a5, 0x804a7, 0x804a9, 0x804ab, 0x804ad, 0x804af, 0x804b1, 0x804b3, - 0x804b5, 0x804b7, 0x804b9, 0x804bb, 0x804bd, 0x804bf, 0x804c2, 0x804c4, 0x804c6, - 0x804c8, 0x804ca, 0x804cc, 0x804ce, 0x804cf, 0x804d1, 0x804d3, 0x804d5, 0x804d7, - 0x804d9, 0x804db, 0x804dd, 0x804df, 0x804e1, 0x804e3, 0x804e5, 0x804e7, 0x804e9, - 0x804eb, 0x804ed, 0x804ef, 0x804f1, 0x804f3, 0x804f5, 0x804f7, 0x804f9, 0x804fb, - 0x804fd, 0x804ff, 0x80501, 0x80503, 0x80505, 0x80507, 0x80509, 0x8050b, 0x8050d, - 0x8050f, 0x80511, 0x80513, 0x80515, 0x80517, 0x80519, 0x8051b, 0x8051d, 0x8051f, - 0x80521, 0x80523, 0x80525, 0x80527, 0x80529, 0x8052b, 0x8052d, 0x8052f, 0x81e01, - 0x81e03, 0x81e05, 0x81e07, 0x81e09, 0x81e0b, 0x81e0d, 0x81e0f, 0x81e11, 0x81e13, - 0x81e15, 0x81e17, 0x81e19, 0x81e1b, 0x81e1d, 0x81e1f, 0x81e21, 0x81e23, 0x81e25, - 0x81e27, 0x81e29, 0x81e2b, 0x81e2d, 0x81e2f, 0x81e31, 0x81e33, 0x81e35, 0x81e37, - 0x81e39, 0x81e3b, 0x81e3d, 0x81e3f, 0x81e41, 0x81e43, 0x81e45, 0x81e47, 0x81e49, - 0x81e4b, 0x81e4d, 0x81e4f, 0x81e51, 0x81e53, 0x81e55, 0x81e57, 0x81e59, 0x81e5b, - 0x81e5d, 0x81e5f, 0x81e61, 0x81e63, 0x81e65, 0x81e67, 0x81e69, 0x81e6b, 0x81e6d, - 0x81e6f, 0x81e71, 0x81e73, 0x81e75, 0x81e77, 0x81e79, 0x81e7b, 0x81e7d, 0x81e7f, - 0x81e81, 0x81e83, 0x81e85, 0x81e87, 0x81e89, 0x81e8b, 0x81e8d, 0x81e8f, 0x81e91, - 0x81e93, 0x81e9f, 0x81ea1, 0x81ea3, 0x81ea5, 0x81ea7, 0x81ea9, 0x81eab, 0x81ead, - 0x81eaf, 0x81eb1, 0x81eb3, 0x81eb5, 0x81eb7, 0x81eb9, 0x81ebb, 0x81ebd, 0x81ebf, - 0x81ec1, 0x81ec3, 0x81ec5, 0x81ec7, 0x81ec9, 0x81ecb, 0x81ecd, 0x81ecf, 0x81ed1, - 0x81ed3, 0x81ed5, 0x81ed7, 0x81ed9, 0x81edb, 0x81edd, 0x81edf, 0x81ee1, 0x81ee3, - 0x81ee5, 0x81ee7, 0x81ee9, 0x81eeb, 0x81eed, 0x81eef, 0x81ef1, 0x81ef3, 0x81ef5, - 0x81ef7, 0x81ef9, 0x81efb, 0x81efd, 0x81fb6, 0x81fb7, 0x81fbe, 0x81fc6, 0x81fc7, - 0x81fd6, 0x81fd7, 0x81ff6, 0x81ff7, 0x8210a, 0x8210e, 0x8210f, 0x82113, 0x8212f, - 0x82134, 0x82139, 0x8213c, 0x8213d, 0x8214e, 0x82184, 0x82c61, 0x82c65, 0x82c66, - 0x82c68, 0x82c6a, 0x82c6c, 0x82c71, 0x82c73, 0x82c74, 0x82c81, 0x82c83, 0x82c85, - 0x82c87, 0x82c89, 0x82c8b, 0x82c8d, 0x82c8f, 0x82c91, 0x82c93, 0x82c95, 0x82c97, - 0x82c99, 0x82c9b, 0x82c9d, 0x82c9f, 0x82ca1, 0x82ca3, 0x82ca5, 0x82ca7, 0x82ca9, - 0x82cab, 0x82cad, 0x82caf, 0x82cb1, 0x82cb3, 0x82cb5, 0x82cb7, 0x82cb9, 0x82cbb, - 0x82cbd, 0x82cbf, 0x82cc1, 0x82cc3, 0x82cc5, 0x82cc7, 0x82cc9, 0x82ccb, 0x82ccd, - 0x82ccf, 0x82cd1, 0x82cd3, 0x82cd5, 0x82cd7, 0x82cd9, 0x82cdb, 0x82cdd, 0x82cdf, - 0x82ce1, 0x82ce3, 0x82ce4, 0x82cec, 0x82cee, 0x82cf3, 0x82d27, 0x82d2d, 0x8a641, - 0x8a643, 0x8a645, 0x8a647, 0x8a649, 0x8a64b, 0x8a64d, 0x8a64f, 0x8a651, 0x8a653, - 0x8a655, 0x8a657, 0x8a659, 0x8a65b, 0x8a65d, 0x8a65f, 0x8a661, 0x8a663, 0x8a665, - 0x8a667, 0x8a669, 0x8a66b, 0x8a66d, 0x8a681, 0x8a683, 0x8a685, 0x8a687, 0x8a689, - 0x8a68b, 0x8a68d, 0x8a68f, 0x8a691, 0x8a693, 0x8a695, 0x8a697, 0x8a699, 0x8a69b, - 0x8a723, 0x8a725, 0x8a727, 0x8a729, 0x8a72b, 0x8a72d, 0x8a733, 0x8a735, 0x8a737, - 0x8a739, 0x8a73b, 0x8a73d, 0x8a73f, 0x8a741, 0x8a743, 0x8a745, 0x8a747, 0x8a749, - 0x8a74b, 0x8a74d, 0x8a74f, 0x8a751, 0x8a753, 0x8a755, 0x8a757, 0x8a759, 0x8a75b, - 0x8a75d, 0x8a75f, 0x8a761, 0x8a763, 0x8a765, 0x8a767, 0x8a769, 0x8a76b, 0x8a76d, - 0x8a76f, 0x8a77a, 0x8a77c, 0x8a77f, 0x8a781, 0x8a783, 0x8a785, 0x8a787, 0x8a78c, - 0x8a78e, 0x8a791, 0x8a797, 0x8a799, 0x8a79b, 0x8a79d, 0x8a79f, 0x8a7a1, 0x8a7a3, - 0x8a7a5, 0x8a7a7, 0x8a7a9, 0x8a7b5, 0x8a7b7, 0x8a7fa, 0x900b5, 0x90101, 0x90103, - 0x90105, 0x90107, 0x90109, 0x9010b, 0x9010d, 0x9010f, 0x90111, 0x90113, 0x90115, - 0x90117, 0x90119, 0x9011b, 0x9011d, 0x9011f, 0x90121, 0x90123, 0x90125, 0x90127, - 0x90129, 0x9012b, 0x9012d, 0x9012f, 0x90131, 0x90133, 0x90135, 0x90137, 0x90138, - 0x9013a, 0x9013c, 0x9013e, 0x90140, 0x90142, 0x90144, 0x90146, 0x90148, 0x90149, - 0x9014b, 0x9014d, 0x9014f, 0x90151, 0x90153, 0x90155, 0x90157, 0x90159, 0x9015b, - 0x9015d, 0x9015f, 0x90161, 0x90163, 0x90165, 0x90167, 0x90169, 0x9016b, 0x9016d, - 0x9016f, 0x90171, 0x90173, 0x90175, 0x90177, 0x9017a, 0x9017c, 0x90183, 0x90185, - 0x90188, 0x9018c, 0x9018d, 0x90192, 0x90195, 0x9019e, 0x901a1, 0x901a3, 0x901a5, - 0x901a8, 0x901aa, 0x901ab, 0x901ad, 0x901b0, 0x901b4, 0x901b6, 0x901b9, 0x901ba, - 0x901c6, 0x901c9, 0x901cc, 0x901ce, 0x901d0, 0x901d2, 0x901d4, 0x901d6, 0x901d8, - 0x901da, 0x901dc, 0x901dd, 0x901df, 0x901e1, 0x901e3, 0x901e5, 0x901e7, 0x901e9, - 0x901eb, 0x901ed, 0x901ef, 0x901f0, 0x901f3, 0x901f5, 0x901f9, 0x901fb, 0x901fd, - 0x901ff, 0x90201, 0x90203, 0x90205, 0x90207, 0x90209, 0x9020b, 0x9020d, 0x9020f, - 0x90211, 0x90213, 0x90215, 0x90217, 0x90219, 0x9021b, 0x9021d, 0x9021f, 0x90221, - 0x90223, 0x90225, 0x90227, 0x90229, 0x9022b, 0x9022d, 0x9022f, 0x90231, 0x9023c, - 0x9023f, 0x90240, 0x90242, 0x90247, 0x90249, 0x9024b, 0x9024d, 0x90371, 0x90373, - 0x90377, 0x90390, 0x903d0, 0x903d1, 0x903d9, 0x903db, 0x903dd, 0x903df, 0x903e1, - 0x903e3, 0x903e5, 0x903e7, 0x903e9, 0x903eb, 0x903ed, 0x903f5, 0x903f8, 0x903fb, - 0x903fc, 0x90461, 0x90463, 0x90465, 0x90467, 0x90469, 0x9046b, 0x9046d, 0x9046f, - 0x90471, 0x90473, 0x90475, 0x90477, 0x90479, 0x9047b, 0x9047d, 0x9047f, 0x90481, - 0x9048b, 0x9048d, 0x9048f, 0x90491, 0x90493, 0x90495, 0x90497, 0x90499, 0x9049b, - 0x9049d, 0x9049f, 0x904a1, 0x904a3, 0x904a5, 0x904a7, 0x904a9, 0x904ab, 0x904ad, - 0x904af, 0x904b1, 0x904b3, 0x904b5, 0x904b7, 0x904b9, 0x904bb, 0x904bd, 0x904bf, - 0x904c2, 0x904c4, 0x904c6, 0x904c8, 0x904ca, 0x904cc, 0x904ce, 0x904cf, 0x904d1, - 0x904d3, 0x904d5, 0x904d7, 0x904d9, 0x904db, 0x904dd, 0x904df, 0x904e1, 0x904e3, - 0x904e5, 0x904e7, 0x904e9, 0x904eb, 0x904ed, 0x904ef, 0x904f1, 0x904f3, 0x904f5, - 0x904f7, 0x904f9, 0x904fb, 0x904fd, 0x904ff, 0x90501, 0x90503, 0x90505, 0x90507, - 0x90509, 0x9050b, 0x9050d, 0x9050f, 0x90511, 0x90513, 0x90515, 0x90517, 0x90519, - 0x9051b, 0x9051d, 0x9051f, 0x90521, 0x90523, 0x90525, 0x90527, 0x90529, 0x9052b, - 0x9052d, 0x9052f, 0x91e01, 0x91e03, 0x91e05, 0x91e07, 0x91e09, 0x91e0b, 0x91e0d, - 0x91e0f, 0x91e11, 0x91e13, 0x91e15, 0x91e17, 0x91e19, 0x91e1b, 0x91e1d, 0x91e1f, - 0x91e21, 0x91e23, 0x91e25, 0x91e27, 0x91e29, 0x91e2b, 0x91e2d, 0x91e2f, 0x91e31, - 0x91e33, 0x91e35, 0x91e37, 0x91e39, 0x91e3b, 0x91e3d, 0x91e3f, 0x91e41, 0x91e43, - 0x91e45, 0x91e47, 0x91e49, 0x91e4b, 0x91e4d, 0x91e4f, 0x91e51, 0x91e53, 0x91e55, - 0x91e57, 0x91e59, 0x91e5b, 0x91e5d, 0x91e5f, 0x91e61, 0x91e63, 0x91e65, 0x91e67, - 0x91e69, 0x91e6b, 0x91e6d, 0x91e6f, 0x91e71, 0x91e73, 0x91e75, 0x91e77, 0x91e79, - 0x91e7b, 0x91e7d, 0x91e7f, 0x91e81, 0x91e83, 0x91e85, 0x91e87, 0x91e89, 0x91e8b, - 0x91e8d, 0x91e8f, 0x91e91, 0x91e93, 0x91e9f, 0x91ea1, 0x91ea3, 0x91ea5, 0x91ea7, - 0x91ea9, 0x91eab, 0x91ead, 0x91eaf, 0x91eb1, 0x91eb3, 0x91eb5, 0x91eb7, 0x91eb9, - 0x91ebb, 0x91ebd, 0x91ebf, 0x91ec1, 0x91ec3, 0x91ec5, 0x91ec7, 0x91ec9, 0x91ecb, - 0x91ecd, 0x91ecf, 0x91ed1, 0x91ed3, 0x91ed5, 0x91ed7, 0x91ed9, 0x91edb, 0x91edd, - 0x91edf, 0x91ee1, 0x91ee3, 0x91ee5, 0x91ee7, 0x91ee9, 0x91eeb, 0x91eed, 0x91eef, - 0x91ef1, 0x91ef3, 0x91ef5, 0x91ef7, 0x91ef9, 0x91efb, 0x91efd, 0x91fb6, 0x91fb7, - 0x91fbe, 0x91fc6, 0x91fc7, 0x91fd6, 0x91fd7, 0x91ff6, 0x91ff7, 0x9210a, 0x9210e, - 0x9210f, 0x92113, 0x9212f, 0x92134, 0x92139, 0x9213c, 0x9213d, 0x9214e, 0x92184, - 0x92c61, 0x92c65, 0x92c66, 0x92c68, 0x92c6a, 0x92c6c, 0x92c71, 0x92c73, 0x92c74, - 0x92c81, 0x92c83, 0x92c85, 0x92c87, 0x92c89, 0x92c8b, 0x92c8d, 0x92c8f, 0x92c91, - 0x92c93, 0x92c95, 0x92c97, 0x92c99, 0x92c9b, 0x92c9d, 0x92c9f, 0x92ca1, 0x92ca3, - 0x92ca5, 0x92ca7, 0x92ca9, 0x92cab, 0x92cad, 0x92caf, 0x92cb1, 0x92cb3, 0x92cb5, - 0x92cb7, 0x92cb9, 0x92cbb, 0x92cbd, 0x92cbf, 0x92cc1, 0x92cc3, 0x92cc5, 0x92cc7, - 0x92cc9, 0x92ccb, 0x92ccd, 0x92ccf, 0x92cd1, 0x92cd3, 0x92cd5, 0x92cd7, 0x92cd9, - 0x92cdb, 0x92cdd, 0x92cdf, 0x92ce1, 0x92ce3, 0x92ce4, 0x92cec, 0x92cee, 0x92cf3, - 0x92d27, 0x92d2d, 0x9a641, 0x9a643, 0x9a645, 0x9a647, 0x9a649, 0x9a64b, 0x9a64d, - 0x9a64f, 0x9a651, 0x9a653, 0x9a655, 0x9a657, 0x9a659, 0x9a65b, 0x9a65d, 0x9a65f, - 0x9a661, 0x9a663, 0x9a665, 0x9a667, 0x9a669, 0x9a66b, 0x9a66d, 0x9a681, 0x9a683, - 0x9a685, 0x9a687, 0x9a689, 0x9a68b, 0x9a68d, 0x9a68f, 0x9a691, 0x9a693, 0x9a695, - 0x9a697, 0x9a699, 0x9a69b, 0x9a723, 0x9a725, 0x9a727, 0x9a729, 0x9a72b, 0x9a72d, - 0x9a733, 0x9a735, 0x9a737, 0x9a739, 0x9a73b, 0x9a73d, 0x9a73f, 0x9a741, 0x9a743, - 0x9a745, 0x9a747, 0x9a749, 0x9a74b, 0x9a74d, 0x9a74f, 0x9a751, 0x9a753, 0x9a755, - 0x9a757, 0x9a759, 0x9a75b, 0x9a75d, 0x9a75f, 0x9a761, 0x9a763, 0x9a765, 0x9a767, - 0x9a769, 0x9a76b, 0x9a76d, 0x9a76f, 0x9a77a, 0x9a77c, 0x9a77f, 0x9a781, 0x9a783, - 0x9a785, 0x9a787, 0x9a78c, 0x9a78e, 0x9a791, 0x9a797, 0x9a799, 0x9a79b, 0x9a79d, - 0x9a79f, 0x9a7a1, 0x9a7a3, 0x9a7a5, 0x9a7a7, 0x9a7a9, 0x9a7b5, 0x9a7b7, 0x9a7fa, - 0xa00b5, 0xa0101, 0xa0103, 0xa0105, 0xa0107, 0xa0109, 0xa010b, 0xa010d, 0xa010f, - 0xa0111, 0xa0113, 0xa0115, 0xa0117, 0xa0119, 0xa011b, 0xa011d, 0xa011f, 0xa0121, - 0xa0123, 0xa0125, 0xa0127, 0xa0129, 0xa012b, 0xa012d, 0xa012f, 0xa0131, 0xa0133, - 0xa0135, 0xa0137, 0xa0138, 0xa013a, 0xa013c, 0xa013e, 0xa0140, 0xa0142, 0xa0144, - 0xa0146, 0xa0148, 0xa0149, 0xa014b, 0xa014d, 0xa014f, 0xa0151, 0xa0153, 0xa0155, - 0xa0157, 0xa0159, 0xa015b, 0xa015d, 0xa015f, 0xa0161, 0xa0163, 0xa0165, 0xa0167, - 0xa0169, 0xa016b, 0xa016d, 0xa016f, 0xa0171, 0xa0173, 0xa0175, 0xa0177, 0xa017a, - 0xa017c, 0xa0183, 0xa0185, 0xa0188, 0xa018c, 0xa018d, 0xa0192, 0xa0195, 0xa019e, - 0xa01a1, 0xa01a3, 0xa01a5, 0xa01a8, 0xa01aa, 0xa01ab, 0xa01ad, 0xa01b0, 0xa01b4, - 0xa01b6, 0xa01b9, 0xa01ba, 0xa01c6, 0xa01c9, 0xa01cc, 0xa01ce, 0xa01d0, 0xa01d2, - 0xa01d4, 0xa01d6, 0xa01d8, 0xa01da, 0xa01dc, 0xa01dd, 0xa01df, 0xa01e1, 0xa01e3, - 0xa01e5, 0xa01e7, 0xa01e9, 0xa01eb, 0xa01ed, 0xa01ef, 0xa01f0, 0xa01f3, 0xa01f5, - 0xa01f9, 0xa01fb, 0xa01fd, 0xa01ff, 0xa0201, 0xa0203, 0xa0205, 0xa0207, 0xa0209, - 0xa020b, 0xa020d, 0xa020f, 0xa0211, 0xa0213, 0xa0215, 0xa0217, 0xa0219, 0xa021b, - 0xa021d, 0xa021f, 0xa0221, 0xa0223, 0xa0225, 0xa0227, 0xa0229, 0xa022b, 0xa022d, - 0xa022f, 0xa0231, 0xa023c, 0xa023f, 0xa0240, 0xa0242, 0xa0247, 0xa0249, 0xa024b, - 0xa024d, 0xa0371, 0xa0373, 0xa0377, 0xa0390, 0xa03d0, 0xa03d1, 0xa03d9, 0xa03db, - 0xa03dd, 0xa03df, 0xa03e1, 0xa03e3, 0xa03e5, 0xa03e7, 0xa03e9, 0xa03eb, 0xa03ed, - 0xa03f5, 0xa03f8, 0xa03fb, 0xa03fc, 0xa0461, 0xa0463, 0xa0465, 0xa0467, 0xa0469, - 0xa046b, 0xa046d, 0xa046f, 0xa0471, 0xa0473, 0xa0475, 0xa0477, 0xa0479, 0xa047b, - 0xa047d, 0xa047f, 0xa0481, 0xa048b, 0xa048d, 0xa048f, 0xa0491, 0xa0493, 0xa0495, - 0xa0497, 0xa0499, 0xa049b, 0xa049d, 0xa049f, 0xa04a1, 0xa04a3, 0xa04a5, 0xa04a7, - 0xa04a9, 0xa04ab, 0xa04ad, 0xa04af, 0xa04b1, 0xa04b3, 0xa04b5, 0xa04b7, 0xa04b9, - 0xa04bb, 0xa04bd, 0xa04bf, 0xa04c2, 0xa04c4, 0xa04c6, 0xa04c8, 0xa04ca, 0xa04cc, - 0xa04ce, 0xa04cf, 0xa04d1, 0xa04d3, 0xa04d5, 0xa04d7, 0xa04d9, 0xa04db, 0xa04dd, - 0xa04df, 0xa04e1, 0xa04e3, 0xa04e5, 0xa04e7, 0xa04e9, 0xa04eb, 0xa04ed, 0xa04ef, - 0xa04f1, 0xa04f3, 0xa04f5, 0xa04f7, 0xa04f9, 0xa04fb, 0xa04fd, 0xa04ff, 0xa0501, - 0xa0503, 0xa0505, 0xa0507, 0xa0509, 0xa050b, 0xa050d, 0xa050f, 0xa0511, 0xa0513, - 0xa0515, 0xa0517, 0xa0519, 0xa051b, 0xa051d, 0xa051f, 0xa0521, 0xa0523, 0xa0525, - 0xa0527, 0xa0529, 0xa052b, 0xa052d, 0xa052f, 0xa1e01, 0xa1e03, 0xa1e05, 0xa1e07, - 0xa1e09, 0xa1e0b, 0xa1e0d, 0xa1e0f, 0xa1e11, 0xa1e13, 0xa1e15, 0xa1e17, 0xa1e19, - 0xa1e1b, 0xa1e1d, 0xa1e1f, 0xa1e21, 0xa1e23, 0xa1e25, 0xa1e27, 0xa1e29, 0xa1e2b, - 0xa1e2d, 0xa1e2f, 0xa1e31, 0xa1e33, 0xa1e35, 0xa1e37, 0xa1e39, 0xa1e3b, 0xa1e3d, - 0xa1e3f, 0xa1e41, 0xa1e43, 0xa1e45, 0xa1e47, 0xa1e49, 0xa1e4b, 0xa1e4d, 0xa1e4f, - 0xa1e51, 0xa1e53, 0xa1e55, 0xa1e57, 0xa1e59, 0xa1e5b, 0xa1e5d, 0xa1e5f, 0xa1e61, - 0xa1e63, 0xa1e65, 0xa1e67, 0xa1e69, 0xa1e6b, 0xa1e6d, 0xa1e6f, 0xa1e71, 0xa1e73, - 0xa1e75, 0xa1e77, 0xa1e79, 0xa1e7b, 0xa1e7d, 0xa1e7f, 0xa1e81, 0xa1e83, 0xa1e85, - 0xa1e87, 0xa1e89, 0xa1e8b, 0xa1e8d, 0xa1e8f, 0xa1e91, 0xa1e93, 0xa1e9f, 0xa1ea1, - 0xa1ea3, 0xa1ea5, 0xa1ea7, 0xa1ea9, 0xa1eab, 0xa1ead, 0xa1eaf, 0xa1eb1, 0xa1eb3, - 0xa1eb5, 0xa1eb7, 0xa1eb9, 0xa1ebb, 0xa1ebd, 0xa1ebf, 0xa1ec1, 0xa1ec3, 0xa1ec5, - 0xa1ec7, 0xa1ec9, 0xa1ecb, 0xa1ecd, 0xa1ecf, 0xa1ed1, 0xa1ed3, 0xa1ed5, 0xa1ed7, - 0xa1ed9, 0xa1edb, 0xa1edd, 0xa1edf, 0xa1ee1, 0xa1ee3, 0xa1ee5, 0xa1ee7, 0xa1ee9, - 0xa1eeb, 0xa1eed, 0xa1eef, 0xa1ef1, 0xa1ef3, 0xa1ef5, 0xa1ef7, 0xa1ef9, 0xa1efb, - 0xa1efd, 0xa1fb6, 0xa1fb7, 0xa1fbe, 0xa1fc6, 0xa1fc7, 0xa1fd6, 0xa1fd7, 0xa1ff6, - 0xa1ff7, 0xa210a, 0xa210e, 0xa210f, 0xa2113, 0xa212f, 0xa2134, 0xa2139, 0xa213c, - 0xa213d, 0xa214e, 0xa2184, 0xa2c61, 0xa2c65, 0xa2c66, 0xa2c68, 0xa2c6a, 0xa2c6c, - 0xa2c71, 0xa2c73, 0xa2c74, 0xa2c81, 0xa2c83, 0xa2c85, 0xa2c87, 0xa2c89, 0xa2c8b, - 0xa2c8d, 0xa2c8f, 0xa2c91, 0xa2c93, 0xa2c95, 0xa2c97, 0xa2c99, 0xa2c9b, 0xa2c9d, - 0xa2c9f, 0xa2ca1, 0xa2ca3, 0xa2ca5, 0xa2ca7, 0xa2ca9, 0xa2cab, 0xa2cad, 0xa2caf, - 0xa2cb1, 0xa2cb3, 0xa2cb5, 0xa2cb7, 0xa2cb9, 0xa2cbb, 0xa2cbd, 0xa2cbf, 0xa2cc1, - 0xa2cc3, 0xa2cc5, 0xa2cc7, 0xa2cc9, 0xa2ccb, 0xa2ccd, 0xa2ccf, 0xa2cd1, 0xa2cd3, - 0xa2cd5, 0xa2cd7, 0xa2cd9, 0xa2cdb, 0xa2cdd, 0xa2cdf, 0xa2ce1, 0xa2ce3, 0xa2ce4, - 0xa2cec, 0xa2cee, 0xa2cf3, 0xa2d27, 0xa2d2d, 0xaa641, 0xaa643, 0xaa645, 0xaa647, - 0xaa649, 0xaa64b, 0xaa64d, 0xaa64f, 0xaa651, 0xaa653, 0xaa655, 0xaa657, 0xaa659, - 0xaa65b, 0xaa65d, 0xaa65f, 0xaa661, 0xaa663, 0xaa665, 0xaa667, 0xaa669, 0xaa66b, - 0xaa66d, 0xaa681, 0xaa683, 0xaa685, 0xaa687, 0xaa689, 0xaa68b, 0xaa68d, 0xaa68f, - 0xaa691, 0xaa693, 0xaa695, 0xaa697, 0xaa699, 0xaa69b, 0xaa723, 0xaa725, 0xaa727, - 0xaa729, 0xaa72b, 0xaa72d, 0xaa733, 0xaa735, 0xaa737, 0xaa739, 0xaa73b, 0xaa73d, - 0xaa73f, 0xaa741, 0xaa743, 0xaa745, 0xaa747, 0xaa749, 0xaa74b, 0xaa74d, 0xaa74f, - 0xaa751, 0xaa753, 0xaa755, 0xaa757, 0xaa759, 0xaa75b, 0xaa75d, 0xaa75f, 0xaa761, - 0xaa763, 0xaa765, 0xaa767, 0xaa769, 0xaa76b, 0xaa76d, 0xaa76f, 0xaa77a, 0xaa77c, - 0xaa77f, 0xaa781, 0xaa783, 0xaa785, 0xaa787, 0xaa78c, 0xaa78e, 0xaa791, 0xaa797, - 0xaa799, 0xaa79b, 0xaa79d, 0xaa79f, 0xaa7a1, 0xaa7a3, 0xaa7a5, 0xaa7a7, 0xaa7a9, - 0xaa7b5, 0xaa7b7, 0xaa7fa, 0xb00b5, 0xb0101, 0xb0103, 0xb0105, 0xb0107, 0xb0109, - 0xb010b, 0xb010d, 0xb010f, 0xb0111, 0xb0113, 0xb0115, 0xb0117, 0xb0119, 0xb011b, - 0xb011d, 0xb011f, 0xb0121, 0xb0123, 0xb0125, 0xb0127, 0xb0129, 0xb012b, 0xb012d, - 0xb012f, 0xb0131, 0xb0133, 0xb0135, 0xb0137, 0xb0138, 0xb013a, 0xb013c, 0xb013e, - 0xb0140, 0xb0142, 0xb0144, 0xb0146, 0xb0148, 0xb0149, 0xb014b, 0xb014d, 0xb014f, - 0xb0151, 0xb0153, 0xb0155, 0xb0157, 0xb0159, 0xb015b, 0xb015d, 0xb015f, 0xb0161, - 0xb0163, 0xb0165, 0xb0167, 0xb0169, 0xb016b, 0xb016d, 0xb016f, 0xb0171, 0xb0173, - 0xb0175, 0xb0177, 0xb017a, 0xb017c, 0xb0183, 0xb0185, 0xb0188, 0xb018c, 0xb018d, - 0xb0192, 0xb0195, 0xb019e, 0xb01a1, 0xb01a3, 0xb01a5, 0xb01a8, 0xb01aa, 0xb01ab, - 0xb01ad, 0xb01b0, 0xb01b4, 0xb01b6, 0xb01b9, 0xb01ba, 0xb01c6, 0xb01c9, 0xb01cc, - 0xb01ce, 0xb01d0, 0xb01d2, 0xb01d4, 0xb01d6, 0xb01d8, 0xb01da, 0xb01dc, 0xb01dd, - 0xb01df, 0xb01e1, 0xb01e3, 0xb01e5, 0xb01e7, 0xb01e9, 0xb01eb, 0xb01ed, 0xb01ef, - 0xb01f0, 0xb01f3, 0xb01f5, 0xb01f9, 0xb01fb, 0xb01fd, 0xb01ff, 0xb0201, 0xb0203, - 0xb0205, 0xb0207, 0xb0209, 0xb020b, 0xb020d, 0xb020f, 0xb0211, 0xb0213, 0xb0215, - 0xb0217, 0xb0219, 0xb021b, 0xb021d, 0xb021f, 0xb0221, 0xb0223, 0xb0225, 0xb0227, - 0xb0229, 0xb022b, 0xb022d, 0xb022f, 0xb0231, 0xb023c, 0xb023f, 0xb0240, 0xb0242, - 0xb0247, 0xb0249, 0xb024b, 0xb024d, 0xb0371, 0xb0373, 0xb0377, 0xb0390, 0xb03d0, - 0xb03d1, 0xb03d9, 0xb03db, 0xb03dd, 0xb03df, 0xb03e1, 0xb03e3, 0xb03e5, 0xb03e7, - 0xb03e9, 0xb03eb, 0xb03ed, 0xb03f5, 0xb03f8, 0xb03fb, 0xb03fc, 0xb0461, 0xb0463, - 0xb0465, 0xb0467, 0xb0469, 0xb046b, 0xb046d, 0xb046f, 0xb0471, 0xb0473, 0xb0475, - 0xb0477, 0xb0479, 0xb047b, 0xb047d, 0xb047f, 0xb0481, 0xb048b, 0xb048d, 0xb048f, - 0xb0491, 0xb0493, 0xb0495, 0xb0497, 0xb0499, 0xb049b, 0xb049d, 0xb049f, 0xb04a1, - 0xb04a3, 0xb04a5, 0xb04a7, 0xb04a9, 0xb04ab, 0xb04ad, 0xb04af, 0xb04b1, 0xb04b3, - 0xb04b5, 0xb04b7, 0xb04b9, 0xb04bb, 0xb04bd, 0xb04bf, 0xb04c2, 0xb04c4, 0xb04c6, - 0xb04c8, 0xb04ca, 0xb04cc, 0xb04ce, 0xb04cf, 0xb04d1, 0xb04d3, 0xb04d5, 0xb04d7, - 0xb04d9, 0xb04db, 0xb04dd, 0xb04df, 0xb04e1, 0xb04e3, 0xb04e5, 0xb04e7, 0xb04e9, - 0xb04eb, 0xb04ed, 0xb04ef, 0xb04f1, 0xb04f3, 0xb04f5, 0xb04f7, 0xb04f9, 0xb04fb, - 0xb04fd, 0xb04ff, 0xb0501, 0xb0503, 0xb0505, 0xb0507, 0xb0509, 0xb050b, 0xb050d, - 0xb050f, 0xb0511, 0xb0513, 0xb0515, 0xb0517, 0xb0519, 0xb051b, 0xb051d, 0xb051f, - 0xb0521, 0xb0523, 0xb0525, 0xb0527, 0xb0529, 0xb052b, 0xb052d, 0xb052f, 0xb1e01, - 0xb1e03, 0xb1e05, 0xb1e07, 0xb1e09, 0xb1e0b, 0xb1e0d, 0xb1e0f, 0xb1e11, 0xb1e13, - 0xb1e15, 0xb1e17, 0xb1e19, 0xb1e1b, 0xb1e1d, 0xb1e1f, 0xb1e21, 0xb1e23, 0xb1e25, - 0xb1e27, 0xb1e29, 0xb1e2b, 0xb1e2d, 0xb1e2f, 0xb1e31, 0xb1e33, 0xb1e35, 0xb1e37, - 0xb1e39, 0xb1e3b, 0xb1e3d, 0xb1e3f, 0xb1e41, 0xb1e43, 0xb1e45, 0xb1e47, 0xb1e49, - 0xb1e4b, 0xb1e4d, 0xb1e4f, 0xb1e51, 0xb1e53, 0xb1e55, 0xb1e57, 0xb1e59, 0xb1e5b, - 0xb1e5d, 0xb1e5f, 0xb1e61, 0xb1e63, 0xb1e65, 0xb1e67, 0xb1e69, 0xb1e6b, 0xb1e6d, - 0xb1e6f, 0xb1e71, 0xb1e73, 0xb1e75, 0xb1e77, 0xb1e79, 0xb1e7b, 0xb1e7d, 0xb1e7f, - 0xb1e81, 0xb1e83, 0xb1e85, 0xb1e87, 0xb1e89, 0xb1e8b, 0xb1e8d, 0xb1e8f, 0xb1e91, - 0xb1e93, 0xb1e9f, 0xb1ea1, 0xb1ea3, 0xb1ea5, 0xb1ea7, 0xb1ea9, 0xb1eab, 0xb1ead, - 0xb1eaf, 0xb1eb1, 0xb1eb3, 0xb1eb5, 0xb1eb7, 0xb1eb9, 0xb1ebb, 0xb1ebd, 0xb1ebf, - 0xb1ec1, 0xb1ec3, 0xb1ec5, 0xb1ec7, 0xb1ec9, 0xb1ecb, 0xb1ecd, 0xb1ecf, 0xb1ed1, - 0xb1ed3, 0xb1ed5, 0xb1ed7, 0xb1ed9, 0xb1edb, 0xb1edd, 0xb1edf, 0xb1ee1, 0xb1ee3, - 0xb1ee5, 0xb1ee7, 0xb1ee9, 0xb1eeb, 0xb1eed, 0xb1eef, 0xb1ef1, 0xb1ef3, 0xb1ef5, - 0xb1ef7, 0xb1ef9, 0xb1efb, 0xb1efd, 0xb1fb6, 0xb1fb7, 0xb1fbe, 0xb1fc6, 0xb1fc7, - 0xb1fd6, 0xb1fd7, 0xb1ff6, 0xb1ff7, 0xb210a, 0xb210e, 0xb210f, 0xb2113, 0xb212f, - 0xb2134, 0xb2139, 0xb213c, 0xb213d, 0xb214e, 0xb2184, 0xb2c61, 0xb2c65, 0xb2c66, - 0xb2c68, 0xb2c6a, 0xb2c6c, 0xb2c71, 0xb2c73, 0xb2c74, 0xb2c81, 0xb2c83, 0xb2c85, - 0xb2c87, 0xb2c89, 0xb2c8b, 0xb2c8d, 0xb2c8f, 0xb2c91, 0xb2c93, 0xb2c95, 0xb2c97, - 0xb2c99, 0xb2c9b, 0xb2c9d, 0xb2c9f, 0xb2ca1, 0xb2ca3, 0xb2ca5, 0xb2ca7, 0xb2ca9, - 0xb2cab, 0xb2cad, 0xb2caf, 0xb2cb1, 0xb2cb3, 0xb2cb5, 0xb2cb7, 0xb2cb9, 0xb2cbb, - 0xb2cbd, 0xb2cbf, 0xb2cc1, 0xb2cc3, 0xb2cc5, 0xb2cc7, 0xb2cc9, 0xb2ccb, 0xb2ccd, - 0xb2ccf, 0xb2cd1, 0xb2cd3, 0xb2cd5, 0xb2cd7, 0xb2cd9, 0xb2cdb, 0xb2cdd, 0xb2cdf, - 0xb2ce1, 0xb2ce3, 0xb2ce4, 0xb2cec, 0xb2cee, 0xb2cf3, 0xb2d27, 0xb2d2d, 0xba641, - 0xba643, 0xba645, 0xba647, 0xba649, 0xba64b, 0xba64d, 0xba64f, 0xba651, 0xba653, - 0xba655, 0xba657, 0xba659, 0xba65b, 0xba65d, 0xba65f, 0xba661, 0xba663, 0xba665, - 0xba667, 0xba669, 0xba66b, 0xba66d, 0xba681, 0xba683, 0xba685, 0xba687, 0xba689, - 0xba68b, 0xba68d, 0xba68f, 0xba691, 0xba693, 0xba695, 0xba697, 0xba699, 0xba69b, - 0xba723, 0xba725, 0xba727, 0xba729, 0xba72b, 0xba72d, 0xba733, 0xba735, 0xba737, - 0xba739, 0xba73b, 0xba73d, 0xba73f, 0xba741, 0xba743, 0xba745, 0xba747, 0xba749, - 0xba74b, 0xba74d, 0xba74f, 0xba751, 0xba753, 0xba755, 0xba757, 0xba759, 0xba75b, - 0xba75d, 0xba75f, 0xba761, 0xba763, 0xba765, 0xba767, 0xba769, 0xba76b, 0xba76d, - 0xba76f, 0xba77a, 0xba77c, 0xba77f, 0xba781, 0xba783, 0xba785, 0xba787, 0xba78c, - 0xba78e, 0xba791, 0xba797, 0xba799, 0xba79b, 0xba79d, 0xba79f, 0xba7a1, 0xba7a3, - 0xba7a5, 0xba7a7, 0xba7a9, 0xba7b5, 0xba7b7, 0xba7fa, 0xc00b5, 0xc0101, 0xc0103, - 0xc0105, 0xc0107, 0xc0109, 0xc010b, 0xc010d, 0xc010f, 0xc0111, 0xc0113, 0xc0115, - 0xc0117, 0xc0119, 0xc011b, 0xc011d, 0xc011f, 0xc0121, 0xc0123, 0xc0125, 0xc0127, - 0xc0129, 0xc012b, 0xc012d, 0xc012f, 0xc0131, 0xc0133, 0xc0135, 0xc0137, 0xc0138, - 0xc013a, 0xc013c, 0xc013e, 0xc0140, 0xc0142, 0xc0144, 0xc0146, 0xc0148, 0xc0149, - 0xc014b, 0xc014d, 0xc014f, 0xc0151, 0xc0153, 0xc0155, 0xc0157, 0xc0159, 0xc015b, - 0xc015d, 0xc015f, 0xc0161, 0xc0163, 0xc0165, 0xc0167, 0xc0169, 0xc016b, 0xc016d, - 0xc016f, 0xc0171, 0xc0173, 0xc0175, 0xc0177, 0xc017a, 0xc017c, 0xc0183, 0xc0185, - 0xc0188, 0xc018c, 0xc018d, 0xc0192, 0xc0195, 0xc019e, 0xc01a1, 0xc01a3, 0xc01a5, - 0xc01a8, 0xc01aa, 0xc01ab, 0xc01ad, 0xc01b0, 0xc01b4, 0xc01b6, 0xc01b9, 0xc01ba, - 0xc01c6, 0xc01c9, 0xc01cc, 0xc01ce, 0xc01d0, 0xc01d2, 0xc01d4, 0xc01d6, 0xc01d8, - 0xc01da, 0xc01dc, 0xc01dd, 0xc01df, 0xc01e1, 0xc01e3, 0xc01e5, 0xc01e7, 0xc01e9, - 0xc01eb, 0xc01ed, 0xc01ef, 0xc01f0, 0xc01f3, 0xc01f5, 0xc01f9, 0xc01fb, 0xc01fd, - 0xc01ff, 0xc0201, 0xc0203, 0xc0205, 0xc0207, 0xc0209, 0xc020b, 0xc020d, 0xc020f, - 0xc0211, 0xc0213, 0xc0215, 0xc0217, 0xc0219, 0xc021b, 0xc021d, 0xc021f, 0xc0221, - 0xc0223, 0xc0225, 0xc0227, 0xc0229, 0xc022b, 0xc022d, 0xc022f, 0xc0231, 0xc023c, - 0xc023f, 0xc0240, 0xc0242, 0xc0247, 0xc0249, 0xc024b, 0xc024d, 0xc0371, 0xc0373, - 0xc0377, 0xc0390, 0xc03d0, 0xc03d1, 0xc03d9, 0xc03db, 0xc03dd, 0xc03df, 0xc03e1, - 0xc03e3, 0xc03e5, 0xc03e7, 0xc03e9, 0xc03eb, 0xc03ed, 0xc03f5, 0xc03f8, 0xc03fb, - 0xc03fc, 0xc0461, 0xc0463, 0xc0465, 0xc0467, 0xc0469, 0xc046b, 0xc046d, 0xc046f, - 0xc0471, 0xc0473, 0xc0475, 0xc0477, 0xc0479, 0xc047b, 0xc047d, 0xc047f, 0xc0481, - 0xc048b, 0xc048d, 0xc048f, 0xc0491, 0xc0493, 0xc0495, 0xc0497, 0xc0499, 0xc049b, - 0xc049d, 0xc049f, 0xc04a1, 0xc04a3, 0xc04a5, 0xc04a7, 0xc04a9, 0xc04ab, 0xc04ad, - 0xc04af, 0xc04b1, 0xc04b3, 0xc04b5, 0xc04b7, 0xc04b9, 0xc04bb, 0xc04bd, 0xc04bf, - 0xc04c2, 0xc04c4, 0xc04c6, 0xc04c8, 0xc04ca, 0xc04cc, 0xc04ce, 0xc04cf, 0xc04d1, - 0xc04d3, 0xc04d5, 0xc04d7, 0xc04d9, 0xc04db, 0xc04dd, 0xc04df, 0xc04e1, 0xc04e3, - 0xc04e5, 0xc04e7, 0xc04e9, 0xc04eb, 0xc04ed, 0xc04ef, 0xc04f1, 0xc04f3, 0xc04f5, - 0xc04f7, 0xc04f9, 0xc04fb, 0xc04fd, 0xc04ff, 0xc0501, 0xc0503, 0xc0505, 0xc0507, - 0xc0509, 0xc050b, 0xc050d, 0xc050f, 0xc0511, 0xc0513, 0xc0515, 0xc0517, 0xc0519, - 0xc051b, 0xc051d, 0xc051f, 0xc0521, 0xc0523, 0xc0525, 0xc0527, 0xc0529, 0xc052b, - 0xc052d, 0xc052f, 0xc1e01, 0xc1e03, 0xc1e05, 0xc1e07, 0xc1e09, 0xc1e0b, 0xc1e0d, - 0xc1e0f, 0xc1e11, 0xc1e13, 0xc1e15, 0xc1e17, 0xc1e19, 0xc1e1b, 0xc1e1d, 0xc1e1f, - 0xc1e21, 0xc1e23, 0xc1e25, 0xc1e27, 0xc1e29, 0xc1e2b, 0xc1e2d, 0xc1e2f, 0xc1e31, - 0xc1e33, 0xc1e35, 0xc1e37, 0xc1e39, 0xc1e3b, 0xc1e3d, 0xc1e3f, 0xc1e41, 0xc1e43, - 0xc1e45, 0xc1e47, 0xc1e49, 0xc1e4b, 0xc1e4d, 0xc1e4f, 0xc1e51, 0xc1e53, 0xc1e55, - 0xc1e57, 0xc1e59, 0xc1e5b, 0xc1e5d, 0xc1e5f, 0xc1e61, 0xc1e63, 0xc1e65, 0xc1e67, - 0xc1e69, 0xc1e6b, 0xc1e6d, 0xc1e6f, 0xc1e71, 0xc1e73, 0xc1e75, 0xc1e77, 0xc1e79, - 0xc1e7b, 0xc1e7d, 0xc1e7f, 0xc1e81, 0xc1e83, 0xc1e85, 0xc1e87, 0xc1e89, 0xc1e8b, - 0xc1e8d, 0xc1e8f, 0xc1e91, 0xc1e93, 0xc1e9f, 0xc1ea1, 0xc1ea3, 0xc1ea5, 0xc1ea7, - 0xc1ea9, 0xc1eab, 0xc1ead, 0xc1eaf, 0xc1eb1, 0xc1eb3, 0xc1eb5, 0xc1eb7, 0xc1eb9, - 0xc1ebb, 0xc1ebd, 0xc1ebf, 0xc1ec1, 0xc1ec3, 0xc1ec5, 0xc1ec7, 0xc1ec9, 0xc1ecb, - 0xc1ecd, 0xc1ecf, 0xc1ed1, 0xc1ed3, 0xc1ed5, 0xc1ed7, 0xc1ed9, 0xc1edb, 0xc1edd, - 0xc1edf, 0xc1ee1, 0xc1ee3, 0xc1ee5, 0xc1ee7, 0xc1ee9, 0xc1eeb, 0xc1eed, 0xc1eef, - 0xc1ef1, 0xc1ef3, 0xc1ef5, 0xc1ef7, 0xc1ef9, 0xc1efb, 0xc1efd, 0xc1fb6, 0xc1fb7, - 0xc1fbe, 0xc1fc6, 0xc1fc7, 0xc1fd6, 0xc1fd7, 0xc1ff6, 0xc1ff7, 0xc210a, 0xc210e, - 0xc210f, 0xc2113, 0xc212f, 0xc2134, 0xc2139, 0xc213c, 0xc213d, 0xc214e, 0xc2184, - 0xc2c61, 0xc2c65, 0xc2c66, 0xc2c68, 0xc2c6a, 0xc2c6c, 0xc2c71, 0xc2c73, 0xc2c74, - 0xc2c81, 0xc2c83, 0xc2c85, 0xc2c87, 0xc2c89, 0xc2c8b, 0xc2c8d, 0xc2c8f, 0xc2c91, - 0xc2c93, 0xc2c95, 0xc2c97, 0xc2c99, 0xc2c9b, 0xc2c9d, 0xc2c9f, 0xc2ca1, 0xc2ca3, - 0xc2ca5, 0xc2ca7, 0xc2ca9, 0xc2cab, 0xc2cad, 0xc2caf, 0xc2cb1, 0xc2cb3, 0xc2cb5, - 0xc2cb7, 0xc2cb9, 0xc2cbb, 0xc2cbd, 0xc2cbf, 0xc2cc1, 0xc2cc3, 0xc2cc5, 0xc2cc7, - 0xc2cc9, 0xc2ccb, 0xc2ccd, 0xc2ccf, 0xc2cd1, 0xc2cd3, 0xc2cd5, 0xc2cd7, 0xc2cd9, - 0xc2cdb, 0xc2cdd, 0xc2cdf, 0xc2ce1, 0xc2ce3, 0xc2ce4, 0xc2cec, 0xc2cee, 0xc2cf3, - 0xc2d27, 0xc2d2d, 0xca641, 0xca643, 0xca645, 0xca647, 0xca649, 0xca64b, 0xca64d, - 0xca64f, 0xca651, 0xca653, 0xca655, 0xca657, 0xca659, 0xca65b, 0xca65d, 0xca65f, - 0xca661, 0xca663, 0xca665, 0xca667, 0xca669, 0xca66b, 0xca66d, 0xca681, 0xca683, - 0xca685, 0xca687, 0xca689, 0xca68b, 0xca68d, 0xca68f, 0xca691, 0xca693, 0xca695, - 0xca697, 0xca699, 0xca69b, 0xca723, 0xca725, 0xca727, 0xca729, 0xca72b, 0xca72d, - 0xca733, 0xca735, 0xca737, 0xca739, 0xca73b, 0xca73d, 0xca73f, 0xca741, 0xca743, - 0xca745, 0xca747, 0xca749, 0xca74b, 0xca74d, 0xca74f, 0xca751, 0xca753, 0xca755, - 0xca757, 0xca759, 0xca75b, 0xca75d, 0xca75f, 0xca761, 0xca763, 0xca765, 0xca767, - 0xca769, 0xca76b, 0xca76d, 0xca76f, 0xca77a, 0xca77c, 0xca77f, 0xca781, 0xca783, - 0xca785, 0xca787, 0xca78c, 0xca78e, 0xca791, 0xca797, 0xca799, 0xca79b, 0xca79d, - 0xca79f, 0xca7a1, 0xca7a3, 0xca7a5, 0xca7a7, 0xca7a9, 0xca7b5, 0xca7b7, 0xca7fa, - 0xd00b5, 0xd0101, 0xd0103, 0xd0105, 0xd0107, 0xd0109, 0xd010b, 0xd010d, 0xd010f, - 0xd0111, 0xd0113, 0xd0115, 0xd0117, 0xd0119, 0xd011b, 0xd011d, 0xd011f, 0xd0121, - 0xd0123, 0xd0125, 0xd0127, 0xd0129, 0xd012b, 0xd012d, 0xd012f, 0xd0131, 0xd0133, - 0xd0135, 0xd0137, 0xd0138, 0xd013a, 0xd013c, 0xd013e, 0xd0140, 0xd0142, 0xd0144, - 0xd0146, 0xd0148, 0xd0149, 0xd014b, 0xd014d, 0xd014f, 0xd0151, 0xd0153, 0xd0155, - 0xd0157, 0xd0159, 0xd015b, 0xd015d, 0xd015f, 0xd0161, 0xd0163, 0xd0165, 0xd0167, - 0xd0169, 0xd016b, 0xd016d, 0xd016f, 0xd0171, 0xd0173, 0xd0175, 0xd0177, 0xd017a, - 0xd017c, 0xd0183, 0xd0185, 0xd0188, 0xd018c, 0xd018d, 0xd0192, 0xd0195, 0xd019e, - 0xd01a1, 0xd01a3, 0xd01a5, 0xd01a8, 0xd01aa, 0xd01ab, 0xd01ad, 0xd01b0, 0xd01b4, - 0xd01b6, 0xd01b9, 0xd01ba, 0xd01c6, 0xd01c9, 0xd01cc, 0xd01ce, 0xd01d0, 0xd01d2, - 0xd01d4, 0xd01d6, 0xd01d8, 0xd01da, 0xd01dc, 0xd01dd, 0xd01df, 0xd01e1, 0xd01e3, - 0xd01e5, 0xd01e7, 0xd01e9, 0xd01eb, 0xd01ed, 0xd01ef, 0xd01f0, 0xd01f3, 0xd01f5, - 0xd01f9, 0xd01fb, 0xd01fd, 0xd01ff, 0xd0201, 0xd0203, 0xd0205, 0xd0207, 0xd0209, - 0xd020b, 0xd020d, 0xd020f, 0xd0211, 0xd0213, 0xd0215, 0xd0217, 0xd0219, 0xd021b, - 0xd021d, 0xd021f, 0xd0221, 0xd0223, 0xd0225, 0xd0227, 0xd0229, 0xd022b, 0xd022d, - 0xd022f, 0xd0231, 0xd023c, 0xd023f, 0xd0240, 0xd0242, 0xd0247, 0xd0249, 0xd024b, - 0xd024d, 0xd0371, 0xd0373, 0xd0377, 0xd0390, 0xd03d0, 0xd03d1, 0xd03d9, 0xd03db, - 0xd03dd, 0xd03df, 0xd03e1, 0xd03e3, 0xd03e5, 0xd03e7, 0xd03e9, 0xd03eb, 0xd03ed, - 0xd03f5, 0xd03f8, 0xd03fb, 0xd03fc, 0xd0461, 0xd0463, 0xd0465, 0xd0467, 0xd0469, - 0xd046b, 0xd046d, 0xd046f, 0xd0471, 0xd0473, 0xd0475, 0xd0477, 0xd0479, 0xd047b, - 0xd047d, 0xd047f, 0xd0481, 0xd048b, 0xd048d, 0xd048f, 0xd0491, 0xd0493, 0xd0495, - 0xd0497, 0xd0499, 0xd049b, 0xd049d, 0xd049f, 0xd04a1, 0xd04a3, 0xd04a5, 0xd04a7, - 0xd04a9, 0xd04ab, 0xd04ad, 0xd04af, 0xd04b1, 0xd04b3, 0xd04b5, 0xd04b7, 0xd04b9, - 0xd04bb, 0xd04bd, 0xd04bf, 0xd04c2, 0xd04c4, 0xd04c6, 0xd04c8, 0xd04ca, 0xd04cc, - 0xd04ce, 0xd04cf, 0xd04d1, 0xd04d3, 0xd04d5, 0xd04d7, 0xd04d9, 0xd04db, 0xd04dd, - 0xd04df, 0xd04e1, 0xd04e3, 0xd04e5, 0xd04e7, 0xd04e9, 0xd04eb, 0xd04ed, 0xd04ef, - 0xd04f1, 0xd04f3, 0xd04f5, 0xd04f7, 0xd04f9, 0xd04fb, 0xd04fd, 0xd04ff, 0xd0501, - 0xd0503, 0xd0505, 0xd0507, 0xd0509, 0xd050b, 0xd050d, 0xd050f, 0xd0511, 0xd0513, - 0xd0515, 0xd0517, 0xd0519, 0xd051b, 0xd051d, 0xd051f, 0xd0521, 0xd0523, 0xd0525, - 0xd0527, 0xd0529, 0xd052b, 0xd052d, 0xd052f, 0xd1e01, 0xd1e03, 0xd1e05, 0xd1e07, - 0xd1e09, 0xd1e0b, 0xd1e0d, 0xd1e0f, 0xd1e11, 0xd1e13, 0xd1e15, 0xd1e17, 0xd1e19, - 0xd1e1b, 0xd1e1d, 0xd1e1f, 0xd1e21, 0xd1e23, 0xd1e25, 0xd1e27, 0xd1e29, 0xd1e2b, - 0xd1e2d, 0xd1e2f, 0xd1e31, 0xd1e33, 0xd1e35, 0xd1e37, 0xd1e39, 0xd1e3b, 0xd1e3d, - 0xd1e3f, 0xd1e41, 0xd1e43, 0xd1e45, 0xd1e47, 0xd1e49, 0xd1e4b, 0xd1e4d, 0xd1e4f, - 0xd1e51, 0xd1e53, 0xd1e55, 0xd1e57, 0xd1e59, 0xd1e5b, 0xd1e5d, 0xd1e5f, 0xd1e61, - 0xd1e63, 0xd1e65, 0xd1e67, 0xd1e69, 0xd1e6b, 0xd1e6d, 0xd1e6f, 0xd1e71, 0xd1e73, - 0xd1e75, 0xd1e77, 0xd1e79, 0xd1e7b, 0xd1e7d, 0xd1e7f, 0xd1e81, 0xd1e83, 0xd1e85, - 0xd1e87, 0xd1e89, 0xd1e8b, 0xd1e8d, 0xd1e8f, 0xd1e91, 0xd1e93, 0xd1e9f, 0xd1ea1, - 0xd1ea3, 0xd1ea5, 0xd1ea7, 0xd1ea9, 0xd1eab, 0xd1ead, 0xd1eaf, 0xd1eb1, 0xd1eb3, - 0xd1eb5, 0xd1eb7, 0xd1eb9, 0xd1ebb, 0xd1ebd, 0xd1ebf, 0xd1ec1, 0xd1ec3, 0xd1ec5, - 0xd1ec7, 0xd1ec9, 0xd1ecb, 0xd1ecd, 0xd1ecf, 0xd1ed1, 0xd1ed3, 0xd1ed5, 0xd1ed7, - 0xd1ed9, 0xd1edb, 0xd1edd, 0xd1edf, 0xd1ee1, 0xd1ee3, 0xd1ee5, 0xd1ee7, 0xd1ee9, - 0xd1eeb, 0xd1eed, 0xd1eef, 0xd1ef1, 0xd1ef3, 0xd1ef5, 0xd1ef7, 0xd1ef9, 0xd1efb, - 0xd1efd, 0xd1fb6, 0xd1fb7, 0xd1fbe, 0xd1fc6, 0xd1fc7, 0xd1fd6, 0xd1fd7, 0xd1ff6, - 0xd1ff7, 0xd210a, 0xd210e, 0xd210f, 0xd2113, 0xd212f, 0xd2134, 0xd2139, 0xd213c, - 0xd213d, 0xd214e, 0xd2184, 0xd2c61, 0xd2c65, 0xd2c66, 0xd2c68, 0xd2c6a, 0xd2c6c, - 0xd2c71, 0xd2c73, 0xd2c74, 0xd2c81, 0xd2c83, 0xd2c85, 0xd2c87, 0xd2c89, 0xd2c8b, - 0xd2c8d, 0xd2c8f, 0xd2c91, 0xd2c93, 0xd2c95, 0xd2c97, 0xd2c99, 0xd2c9b, 0xd2c9d, - 0xd2c9f, 0xd2ca1, 0xd2ca3, 0xd2ca5, 0xd2ca7, 0xd2ca9, 0xd2cab, 0xd2cad, 0xd2caf, - 0xd2cb1, 0xd2cb3, 0xd2cb5, 0xd2cb7, 0xd2cb9, 0xd2cbb, 0xd2cbd, 0xd2cbf, 0xd2cc1, - 0xd2cc3, 0xd2cc5, 0xd2cc7, 0xd2cc9, 0xd2ccb, 0xd2ccd, 0xd2ccf, 0xd2cd1, 0xd2cd3, - 0xd2cd5, 0xd2cd7, 0xd2cd9, 0xd2cdb, 0xd2cdd, 0xd2cdf, 0xd2ce1, 0xd2ce3, 0xd2ce4, - 0xd2cec, 0xd2cee, 0xd2cf3, 0xd2d27, 0xd2d2d, 0xda641, 0xda643, 0xda645, 0xda647, - 0xda649, 0xda64b, 0xda64d, 0xda64f, 0xda651, 0xda653, 0xda655, 0xda657, 0xda659, - 0xda65b, 0xda65d, 0xda65f, 0xda661, 0xda663, 0xda665, 0xda667, 0xda669, 0xda66b, - 0xda66d, 0xda681, 0xda683, 0xda685, 0xda687, 0xda689, 0xda68b, 0xda68d, 0xda68f, - 0xda691, 0xda693, 0xda695, 0xda697, 0xda699, 0xda69b, 0xda723, 0xda725, 0xda727, - 0xda729, 0xda72b, 0xda72d, 0xda733, 0xda735, 0xda737, 0xda739, 0xda73b, 0xda73d, - 0xda73f, 0xda741, 0xda743, 0xda745, 0xda747, 0xda749, 0xda74b, 0xda74d, 0xda74f, - 0xda751, 0xda753, 0xda755, 0xda757, 0xda759, 0xda75b, 0xda75d, 0xda75f, 0xda761, - 0xda763, 0xda765, 0xda767, 0xda769, 0xda76b, 0xda76d, 0xda76f, 0xda77a, 0xda77c, - 0xda77f, 0xda781, 0xda783, 0xda785, 0xda787, 0xda78c, 0xda78e, 0xda791, 0xda797, - 0xda799, 0xda79b, 0xda79d, 0xda79f, 0xda7a1, 0xda7a3, 0xda7a5, 0xda7a7, 0xda7a9, - 0xda7b5, 0xda7b7, 0xda7fa, 0xe00b5, 0xe0101, 0xe0103, 0xe0105, 0xe0107, 0xe0109, - 0xe010b, 0xe010d, 0xe010f, 0xe0111, 0xe0113, 0xe0115, 0xe0117, 0xe0119, 0xe011b, - 0xe011d, 0xe011f, 0xe0121, 0xe0123, 0xe0125, 0xe0127, 0xe0129, 0xe012b, 0xe012d, - 0xe012f, 0xe0131, 0xe0133, 0xe0135, 0xe0137, 0xe0138, 0xe013a, 0xe013c, 0xe013e, - 0xe0140, 0xe0142, 0xe0144, 0xe0146, 0xe0148, 0xe0149, 0xe014b, 0xe014d, 0xe014f, - 0xe0151, 0xe0153, 0xe0155, 0xe0157, 0xe0159, 0xe015b, 0xe015d, 0xe015f, 0xe0161, - 0xe0163, 0xe0165, 0xe0167, 0xe0169, 0xe016b, 0xe016d, 0xe016f, 0xe0171, 0xe0173, - 0xe0175, 0xe0177, 0xe017a, 0xe017c, 0xe0183, 0xe0185, 0xe0188, 0xe018c, 0xe018d, - 0xe0192, 0xe0195, 0xe019e, 0xe01a1, 0xe01a3, 0xe01a5, 0xe01a8, 0xe01aa, 0xe01ab, - 0xe01ad, 0xe01b0, 0xe01b4, 0xe01b6, 0xe01b9, 0xe01ba, 0xe01c6, 0xe01c9, 0xe01cc, - 0xe01ce, 0xe01d0, 0xe01d2, 0xe01d4, 0xe01d6, 0xe01d8, 0xe01da, 0xe01dc, 0xe01dd, - 0xe01df, 0xe01e1, 0xe01e3, 0xe01e5, 0xe01e7, 0xe01e9, 0xe01eb, 0xe01ed, 0xe01ef, - 0xe01f0, 0xe01f3, 0xe01f5, 0xe01f9, 0xe01fb, 0xe01fd, 0xe01ff, 0xe0201, 0xe0203, - 0xe0205, 0xe0207, 0xe0209, 0xe020b, 0xe020d, 0xe020f, 0xe0211, 0xe0213, 0xe0215, - 0xe0217, 0xe0219, 0xe021b, 0xe021d, 0xe021f, 0xe0221, 0xe0223, 0xe0225, 0xe0227, - 0xe0229, 0xe022b, 0xe022d, 0xe022f, 0xe0231, 0xe023c, 0xe023f, 0xe0240, 0xe0242, - 0xe0247, 0xe0249, 0xe024b, 0xe024d, 0xe0371, 0xe0373, 0xe0377, 0xe0390, 0xe03d0, - 0xe03d1, 0xe03d9, 0xe03db, 0xe03dd, 0xe03df, 0xe03e1, 0xe03e3, 0xe03e5, 0xe03e7, - 0xe03e9, 0xe03eb, 0xe03ed, 0xe03f5, 0xe03f8, 0xe03fb, 0xe03fc, 0xe0461, 0xe0463, - 0xe0465, 0xe0467, 0xe0469, 0xe046b, 0xe046d, 0xe046f, 0xe0471, 0xe0473, 0xe0475, - 0xe0477, 0xe0479, 0xe047b, 0xe047d, 0xe047f, 0xe0481, 0xe048b, 0xe048d, 0xe048f, - 0xe0491, 0xe0493, 0xe0495, 0xe0497, 0xe0499, 0xe049b, 0xe049d, 0xe049f, 0xe04a1, - 0xe04a3, 0xe04a5, 0xe04a7, 0xe04a9, 0xe04ab, 0xe04ad, 0xe04af, 0xe04b1, 0xe04b3, - 0xe04b5, 0xe04b7, 0xe04b9, 0xe04bb, 0xe04bd, 0xe04bf, 0xe04c2, 0xe04c4, 0xe04c6, - 0xe04c8, 0xe04ca, 0xe04cc, 0xe04ce, 0xe04cf, 0xe04d1, 0xe04d3, 0xe04d5, 0xe04d7, - 0xe04d9, 0xe04db, 0xe04dd, 0xe04df, 0xe04e1, 0xe04e3, 0xe04e5, 0xe04e7, 0xe04e9, - 0xe04eb, 0xe04ed, 0xe04ef, 0xe04f1, 0xe04f3, 0xe04f5, 0xe04f7, 0xe04f9, 0xe04fb, - 0xe04fd, 0xe04ff, 0xe0501, 0xe0503, 0xe0505, 0xe0507, 0xe0509, 0xe050b, 0xe050d, - 0xe050f, 0xe0511, 0xe0513, 0xe0515, 0xe0517, 0xe0519, 0xe051b, 0xe051d, 0xe051f, - 0xe0521, 0xe0523, 0xe0525, 0xe0527, 0xe0529, 0xe052b, 0xe052d, 0xe052f, 0xe1e01, - 0xe1e03, 0xe1e05, 0xe1e07, 0xe1e09, 0xe1e0b, 0xe1e0d, 0xe1e0f, 0xe1e11, 0xe1e13, - 0xe1e15, 0xe1e17, 0xe1e19, 0xe1e1b, 0xe1e1d, 0xe1e1f, 0xe1e21, 0xe1e23, 0xe1e25, - 0xe1e27, 0xe1e29, 0xe1e2b, 0xe1e2d, 0xe1e2f, 0xe1e31, 0xe1e33, 0xe1e35, 0xe1e37, - 0xe1e39, 0xe1e3b, 0xe1e3d, 0xe1e3f, 0xe1e41, 0xe1e43, 0xe1e45, 0xe1e47, 0xe1e49, - 0xe1e4b, 0xe1e4d, 0xe1e4f, 0xe1e51, 0xe1e53, 0xe1e55, 0xe1e57, 0xe1e59, 0xe1e5b, - 0xe1e5d, 0xe1e5f, 0xe1e61, 0xe1e63, 0xe1e65, 0xe1e67, 0xe1e69, 0xe1e6b, 0xe1e6d, - 0xe1e6f, 0xe1e71, 0xe1e73, 0xe1e75, 0xe1e77, 0xe1e79, 0xe1e7b, 0xe1e7d, 0xe1e7f, - 0xe1e81, 0xe1e83, 0xe1e85, 0xe1e87, 0xe1e89, 0xe1e8b, 0xe1e8d, 0xe1e8f, 0xe1e91, - 0xe1e93, 0xe1e9f, 0xe1ea1, 0xe1ea3, 0xe1ea5, 0xe1ea7, 0xe1ea9, 0xe1eab, 0xe1ead, - 0xe1eaf, 0xe1eb1, 0xe1eb3, 0xe1eb5, 0xe1eb7, 0xe1eb9, 0xe1ebb, 0xe1ebd, 0xe1ebf, - 0xe1ec1, 0xe1ec3, 0xe1ec5, 0xe1ec7, 0xe1ec9, 0xe1ecb, 0xe1ecd, 0xe1ecf, 0xe1ed1, - 0xe1ed3, 0xe1ed5, 0xe1ed7, 0xe1ed9, 0xe1edb, 0xe1edd, 0xe1edf, 0xe1ee1, 0xe1ee3, - 0xe1ee5, 0xe1ee7, 0xe1ee9, 0xe1eeb, 0xe1eed, 0xe1eef, 0xe1ef1, 0xe1ef3, 0xe1ef5, - 0xe1ef7, 0xe1ef9, 0xe1efb, 0xe1efd, 0xe1fb6, 0xe1fb7, 0xe1fbe, 0xe1fc6, 0xe1fc7, - 0xe1fd6, 0xe1fd7, 0xe1ff6, 0xe1ff7, 0xe210a, 0xe210e, 0xe210f, 0xe2113, 0xe212f, - 0xe2134, 0xe2139, 0xe213c, 0xe213d, 0xe214e, 0xe2184, 0xe2c61, 0xe2c65, 0xe2c66, - 0xe2c68, 0xe2c6a, 0xe2c6c, 0xe2c71, 0xe2c73, 0xe2c74, 0xe2c81, 0xe2c83, 0xe2c85, - 0xe2c87, 0xe2c89, 0xe2c8b, 0xe2c8d, 0xe2c8f, 0xe2c91, 0xe2c93, 0xe2c95, 0xe2c97, - 0xe2c99, 0xe2c9b, 0xe2c9d, 0xe2c9f, 0xe2ca1, 0xe2ca3, 0xe2ca5, 0xe2ca7, 0xe2ca9, - 0xe2cab, 0xe2cad, 0xe2caf, 0xe2cb1, 0xe2cb3, 0xe2cb5, 0xe2cb7, 0xe2cb9, 0xe2cbb, - 0xe2cbd, 0xe2cbf, 0xe2cc1, 0xe2cc3, 0xe2cc5, 0xe2cc7, 0xe2cc9, 0xe2ccb, 0xe2ccd, - 0xe2ccf, 0xe2cd1, 0xe2cd3, 0xe2cd5, 0xe2cd7, 0xe2cd9, 0xe2cdb, 0xe2cdd, 0xe2cdf, - 0xe2ce1, 0xe2ce3, 0xe2ce4, 0xe2cec, 0xe2cee, 0xe2cf3, 0xe2d27, 0xe2d2d, 0xea641, - 0xea643, 0xea645, 0xea647, 0xea649, 0xea64b, 0xea64d, 0xea64f, 0xea651, 0xea653, - 0xea655, 0xea657, 0xea659, 0xea65b, 0xea65d, 0xea65f, 0xea661, 0xea663, 0xea665, - 0xea667, 0xea669, 0xea66b, 0xea66d, 0xea681, 0xea683, 0xea685, 0xea687, 0xea689, - 0xea68b, 0xea68d, 0xea68f, 0xea691, 0xea693, 0xea695, 0xea697, 0xea699, 0xea69b, - 0xea723, 0xea725, 0xea727, 0xea729, 0xea72b, 0xea72d, 0xea733, 0xea735, 0xea737, - 0xea739, 0xea73b, 0xea73d, 0xea73f, 0xea741, 0xea743, 0xea745, 0xea747, 0xea749, - 0xea74b, 0xea74d, 0xea74f, 0xea751, 0xea753, 0xea755, 0xea757, 0xea759, 0xea75b, - 0xea75d, 0xea75f, 0xea761, 0xea763, 0xea765, 0xea767, 0xea769, 0xea76b, 0xea76d, - 0xea76f, 0xea77a, 0xea77c, 0xea77f, 0xea781, 0xea783, 0xea785, 0xea787, 0xea78c, - 0xea78e, 0xea791, 0xea797, 0xea799, 0xea79b, 0xea79d, 0xea79f, 0xea7a1, 0xea7a3, - 0xea7a5, 0xea7a7, 0xea7a9, 0xea7b5, 0xea7b7, 0xea7fa, 0xf00b5, 0xf0101, 0xf0103, - 0xf0105, 0xf0107, 0xf0109, 0xf010b, 0xf010d, 0xf010f, 0xf0111, 0xf0113, 0xf0115, - 0xf0117, 0xf0119, 0xf011b, 0xf011d, 0xf011f, 0xf0121, 0xf0123, 0xf0125, 0xf0127, - 0xf0129, 0xf012b, 0xf012d, 0xf012f, 0xf0131, 0xf0133, 0xf0135, 0xf0137, 0xf0138, - 0xf013a, 0xf013c, 0xf013e, 0xf0140, 0xf0142, 0xf0144, 0xf0146, 0xf0148, 0xf0149, - 0xf014b, 0xf014d, 0xf014f, 0xf0151, 0xf0153, 0xf0155, 0xf0157, 0xf0159, 0xf015b, - 0xf015d, 0xf015f, 0xf0161, 0xf0163, 0xf0165, 0xf0167, 0xf0169, 0xf016b, 0xf016d, - 0xf016f, 0xf0171, 0xf0173, 0xf0175, 0xf0177, 0xf017a, 0xf017c, 0xf0183, 0xf0185, - 0xf0188, 0xf018c, 0xf018d, 0xf0192, 0xf0195, 0xf019e, 0xf01a1, 0xf01a3, 0xf01a5, - 0xf01a8, 0xf01aa, 0xf01ab, 0xf01ad, 0xf01b0, 0xf01b4, 0xf01b6, 0xf01b9, 0xf01ba, - 0xf01c6, 0xf01c9, 0xf01cc, 0xf01ce, 0xf01d0, 0xf01d2, 0xf01d4, 0xf01d6, 0xf01d8, - 0xf01da, 0xf01dc, 0xf01dd, 0xf01df, 0xf01e1, 0xf01e3, 0xf01e5, 0xf01e7, 0xf01e9, - 0xf01eb, 0xf01ed, 0xf01ef, 0xf01f0, 0xf01f3, 0xf01f5, 0xf01f9, 0xf01fb, 0xf01fd, - 0xf01ff, 0xf0201, 0xf0203, 0xf0205, 0xf0207, 0xf0209, 0xf020b, 0xf020d, 0xf020f, - 0xf0211, 0xf0213, 0xf0215, 0xf0217, 0xf0219, 0xf021b, 0xf021d, 0xf021f, 0xf0221, - 0xf0223, 0xf0225, 0xf0227, 0xf0229, 0xf022b, 0xf022d, 0xf022f, 0xf0231, 0xf023c, - 0xf023f, 0xf0240, 0xf0242, 0xf0247, 0xf0249, 0xf024b, 0xf024d, 0xf0371, 0xf0373, - 0xf0377, 0xf0390, 0xf03d0, 0xf03d1, 0xf03d9, 0xf03db, 0xf03dd, 0xf03df, 0xf03e1, - 0xf03e3, 0xf03e5, 0xf03e7, 0xf03e9, 0xf03eb, 0xf03ed, 0xf03f5, 0xf03f8, 0xf03fb, - 0xf03fc, 0xf0461, 0xf0463, 0xf0465, 0xf0467, 0xf0469, 0xf046b, 0xf046d, 0xf046f, - 0xf0471, 0xf0473, 0xf0475, 0xf0477, 0xf0479, 0xf047b, 0xf047d, 0xf047f, 0xf0481, - 0xf048b, 0xf048d, 0xf048f, 0xf0491, 0xf0493, 0xf0495, 0xf0497, 0xf0499, 0xf049b, - 0xf049d, 0xf049f, 0xf04a1, 0xf04a3, 0xf04a5, 0xf04a7, 0xf04a9, 0xf04ab, 0xf04ad, - 0xf04af, 0xf04b1, 0xf04b3, 0xf04b5, 0xf04b7, 0xf04b9, 0xf04bb, 0xf04bd, 0xf04bf, - 0xf04c2, 0xf04c4, 0xf04c6, 0xf04c8, 0xf04ca, 0xf04cc, 0xf04ce, 0xf04cf, 0xf04d1, - 0xf04d3, 0xf04d5, 0xf04d7, 0xf04d9, 0xf04db, 0xf04dd, 0xf04df, 0xf04e1, 0xf04e3, - 0xf04e5, 0xf04e7, 0xf04e9, 0xf04eb, 0xf04ed, 0xf04ef, 0xf04f1, 0xf04f3, 0xf04f5, - 0xf04f7, 0xf04f9, 0xf04fb, 0xf04fd, 0xf04ff, 0xf0501, 0xf0503, 0xf0505, 0xf0507, - 0xf0509, 0xf050b, 0xf050d, 0xf050f, 0xf0511, 0xf0513, 0xf0515, 0xf0517, 0xf0519, - 0xf051b, 0xf051d, 0xf051f, 0xf0521, 0xf0523, 0xf0525, 0xf0527, 0xf0529, 0xf052b, - 0xf052d, 0xf052f, 0xf1e01, 0xf1e03, 0xf1e05, 0xf1e07, 0xf1e09, 0xf1e0b, 0xf1e0d, - 0xf1e0f, 0xf1e11, 0xf1e13, 0xf1e15, 0xf1e17, 0xf1e19, 0xf1e1b, 0xf1e1d, 0xf1e1f, - 0xf1e21, 0xf1e23, 0xf1e25, 0xf1e27, 0xf1e29, 0xf1e2b, 0xf1e2d, 0xf1e2f, 0xf1e31, - 0xf1e33, 0xf1e35, 0xf1e37, 0xf1e39, 0xf1e3b, 0xf1e3d, 0xf1e3f, 0xf1e41, 0xf1e43, - 0xf1e45, 0xf1e47, 0xf1e49, 0xf1e4b, 0xf1e4d, 0xf1e4f, 0xf1e51, 0xf1e53, 0xf1e55, - 0xf1e57, 0xf1e59, 0xf1e5b, 0xf1e5d, 0xf1e5f, 0xf1e61, 0xf1e63, 0xf1e65, 0xf1e67, - 0xf1e69, 0xf1e6b, 0xf1e6d, 0xf1e6f, 0xf1e71, 0xf1e73, 0xf1e75, 0xf1e77, 0xf1e79, - 0xf1e7b, 0xf1e7d, 0xf1e7f, 0xf1e81, 0xf1e83, 0xf1e85, 0xf1e87, 0xf1e89, 0xf1e8b, - 0xf1e8d, 0xf1e8f, 0xf1e91, 0xf1e93, 0xf1e9f, 0xf1ea1, 0xf1ea3, 0xf1ea5, 0xf1ea7, - 0xf1ea9, 0xf1eab, 0xf1ead, 0xf1eaf, 0xf1eb1, 0xf1eb3, 0xf1eb5, 0xf1eb7, 0xf1eb9, - 0xf1ebb, 0xf1ebd, 0xf1ebf, 0xf1ec1, 0xf1ec3, 0xf1ec5, 0xf1ec7, 0xf1ec9, 0xf1ecb, - 0xf1ecd, 0xf1ecf, 0xf1ed1, 0xf1ed3, 0xf1ed5, 0xf1ed7, 0xf1ed9, 0xf1edb, 0xf1edd, - 0xf1edf, 0xf1ee1, 0xf1ee3, 0xf1ee5, 0xf1ee7, 0xf1ee9, 0xf1eeb, 0xf1eed, 0xf1eef, - 0xf1ef1, 0xf1ef3, 0xf1ef5, 0xf1ef7, 0xf1ef9, 0xf1efb, 0xf1efd, 0xf1fb6, 0xf1fb7, - 0xf1fbe, 0xf1fc6, 0xf1fc7, 0xf1fd6, 0xf1fd7, 0xf1ff6, 0xf1ff7, 0xf210a, 0xf210e, - 0xf210f, 0xf2113, 0xf212f, 0xf2134, 0xf2139, 0xf213c, 0xf213d, 0xf214e, 0xf2184, - 0xf2c61, 0xf2c65, 0xf2c66, 0xf2c68, 0xf2c6a, 0xf2c6c, 0xf2c71, 0xf2c73, 0xf2c74, - 0xf2c81, 0xf2c83, 0xf2c85, 0xf2c87, 0xf2c89, 0xf2c8b, 0xf2c8d, 0xf2c8f, 0xf2c91, - 0xf2c93, 0xf2c95, 0xf2c97, 0xf2c99, 0xf2c9b, 0xf2c9d, 0xf2c9f, 0xf2ca1, 0xf2ca3, - 0xf2ca5, 0xf2ca7, 0xf2ca9, 0xf2cab, 0xf2cad, 0xf2caf, 0xf2cb1, 0xf2cb3, 0xf2cb5, - 0xf2cb7, 0xf2cb9, 0xf2cbb, 0xf2cbd, 0xf2cbf, 0xf2cc1, 0xf2cc3, 0xf2cc5, 0xf2cc7, - 0xf2cc9, 0xf2ccb, 0xf2ccd, 0xf2ccf, 0xf2cd1, 0xf2cd3, 0xf2cd5, 0xf2cd7, 0xf2cd9, - 0xf2cdb, 0xf2cdd, 0xf2cdf, 0xf2ce1, 0xf2ce3, 0xf2ce4, 0xf2cec, 0xf2cee, 0xf2cf3, - 0xf2d27, 0xf2d2d, 0xfa641, 0xfa643, 0xfa645, 0xfa647, 0xfa649, 0xfa64b, 0xfa64d, - 0xfa64f, 0xfa651, 0xfa653, 0xfa655, 0xfa657, 0xfa659, 0xfa65b, 0xfa65d, 0xfa65f, - 0xfa661, 0xfa663, 0xfa665, 0xfa667, 0xfa669, 0xfa66b, 0xfa66d, 0xfa681, 0xfa683, - 0xfa685, 0xfa687, 0xfa689, 0xfa68b, 0xfa68d, 0xfa68f, 0xfa691, 0xfa693, 0xfa695, - 0xfa697, 0xfa699, 0xfa69b, 0xfa723, 0xfa725, 0xfa727, 0xfa729, 0xfa72b, 0xfa72d, - 0xfa733, 0xfa735, 0xfa737, 0xfa739, 0xfa73b, 0xfa73d, 0xfa73f, 0xfa741, 0xfa743, - 0xfa745, 0xfa747, 0xfa749, 0xfa74b, 0xfa74d, 0xfa74f, 0xfa751, 0xfa753, 0xfa755, - 0xfa757, 0xfa759, 0xfa75b, 0xfa75d, 0xfa75f, 0xfa761, 0xfa763, 0xfa765, 0xfa767, - 0xfa769, 0xfa76b, 0xfa76d, 0xfa76f, 0xfa77a, 0xfa77c, 0xfa77f, 0xfa781, 0xfa783, - 0xfa785, 0xfa787, 0xfa78c, 0xfa78e, 0xfa791, 0xfa797, 0xfa799, 0xfa79b, 0xfa79d, - 0xfa79f, 0xfa7a1, 0xfa7a3, 0xfa7a5, 0xfa7a7, 0xfa7a9, 0xfa7b5, 0xfa7b7, 0xfa7fa, - 0x1000b5, 0x100101, 0x100103, 0x100105, 0x100107, 0x100109, 0x10010b, 0x10010d, 0x10010f, - 0x100111, 0x100113, 0x100115, 0x100117, 0x100119, 0x10011b, 0x10011d, 0x10011f, 0x100121, - 0x100123, 0x100125, 0x100127, 0x100129, 0x10012b, 0x10012d, 0x10012f, 0x100131, 0x100133, - 0x100135, 0x100137, 0x100138, 0x10013a, 0x10013c, 0x10013e, 0x100140, 0x100142, 0x100144, - 0x100146, 0x100148, 0x100149, 0x10014b, 0x10014d, 0x10014f, 0x100151, 0x100153, 0x100155, - 0x100157, 0x100159, 0x10015b, 0x10015d, 0x10015f, 0x100161, 0x100163, 0x100165, 0x100167, - 0x100169, 0x10016b, 0x10016d, 0x10016f, 0x100171, 0x100173, 0x100175, 0x100177, 0x10017a, - 0x10017c, 0x100183, 0x100185, 0x100188, 0x10018c, 0x10018d, 0x100192, 0x100195, 0x10019e, - 0x1001a1, 0x1001a3, 0x1001a5, 0x1001a8, 0x1001aa, 0x1001ab, 0x1001ad, 0x1001b0, 0x1001b4, - 0x1001b6, 0x1001b9, 0x1001ba, 0x1001c6, 0x1001c9, 0x1001cc, 0x1001ce, 0x1001d0, 0x1001d2, - 0x1001d4, 0x1001d6, 0x1001d8, 0x1001da, 0x1001dc, 0x1001dd, 0x1001df, 0x1001e1, 0x1001e3, - 0x1001e5, 0x1001e7, 0x1001e9, 0x1001eb, 0x1001ed, 0x1001ef, 0x1001f0, 0x1001f3, 0x1001f5, - 0x1001f9, 0x1001fb, 0x1001fd, 0x1001ff, 0x100201, 0x100203, 0x100205, 0x100207, 0x100209, - 0x10020b, 0x10020d, 0x10020f, 0x100211, 0x100213, 0x100215, 0x100217, 0x100219, 0x10021b, - 0x10021d, 0x10021f, 0x100221, 0x100223, 0x100225, 0x100227, 0x100229, 0x10022b, 0x10022d, - 0x10022f, 0x100231, 0x10023c, 0x10023f, 0x100240, 0x100242, 0x100247, 0x100249, 0x10024b, - 0x10024d, 0x100371, 0x100373, 0x100377, 0x100390, 0x1003d0, 0x1003d1, 0x1003d9, 0x1003db, - 0x1003dd, 0x1003df, 0x1003e1, 0x1003e3, 0x1003e5, 0x1003e7, 0x1003e9, 0x1003eb, 0x1003ed, - 0x1003f5, 0x1003f8, 0x1003fb, 0x1003fc, 0x100461, 0x100463, 0x100465, 0x100467, 0x100469, - 0x10046b, 0x10046d, 0x10046f, 0x100471, 0x100473, 0x100475, 0x100477, 0x100479, 0x10047b, - 0x10047d, 0x10047f, 0x100481, 0x10048b, 0x10048d, 0x10048f, 0x100491, 0x100493, 0x100495, - 0x100497, 0x100499, 0x10049b, 0x10049d, 0x10049f, 0x1004a1, 0x1004a3, 0x1004a5, 0x1004a7, - 0x1004a9, 0x1004ab, 0x1004ad, 0x1004af, 0x1004b1, 0x1004b3, 0x1004b5, 0x1004b7, 0x1004b9, - 0x1004bb, 0x1004bd, 0x1004bf, 0x1004c2, 0x1004c4, 0x1004c6, 0x1004c8, 0x1004ca, 0x1004cc, - 0x1004ce, 0x1004cf, 0x1004d1, 0x1004d3, 0x1004d5, 0x1004d7, 0x1004d9, 0x1004db, 0x1004dd, - 0x1004df, 0x1004e1, 0x1004e3, 0x1004e5, 0x1004e7, 0x1004e9, 0x1004eb, 0x1004ed, 0x1004ef, - 0x1004f1, 0x1004f3, 0x1004f5, 0x1004f7, 0x1004f9, 0x1004fb, 0x1004fd, 0x1004ff, 0x100501, - 0x100503, 0x100505, 0x100507, 0x100509, 0x10050b, 0x10050d, 0x10050f, 0x100511, 0x100513, - 0x100515, 0x100517, 0x100519, 0x10051b, 0x10051d, 0x10051f, 0x100521, 0x100523, 0x100525, - 0x100527, 0x100529, 0x10052b, 0x10052d, 0x10052f, 0x101e01, 0x101e03, 0x101e05, 0x101e07, - 0x101e09, 0x101e0b, 0x101e0d, 0x101e0f, 0x101e11, 0x101e13, 0x101e15, 0x101e17, 0x101e19, - 0x101e1b, 0x101e1d, 0x101e1f, 0x101e21, 0x101e23, 0x101e25, 0x101e27, 0x101e29, 0x101e2b, - 0x101e2d, 0x101e2f, 0x101e31, 0x101e33, 0x101e35, 0x101e37, 0x101e39, 0x101e3b, 0x101e3d, - 0x101e3f, 0x101e41, 0x101e43, 0x101e45, 0x101e47, 0x101e49, 0x101e4b, 0x101e4d, 0x101e4f, - 0x101e51, 0x101e53, 0x101e55, 0x101e57, 0x101e59, 0x101e5b, 0x101e5d, 0x101e5f, 0x101e61, - 0x101e63, 0x101e65, 0x101e67, 0x101e69, 0x101e6b, 0x101e6d, 0x101e6f, 0x101e71, 0x101e73, - 0x101e75, 0x101e77, 0x101e79, 0x101e7b, 0x101e7d, 0x101e7f, 0x101e81, 0x101e83, 0x101e85, - 0x101e87, 0x101e89, 0x101e8b, 0x101e8d, 0x101e8f, 0x101e91, 0x101e93, 0x101e9f, 0x101ea1, - 0x101ea3, 0x101ea5, 0x101ea7, 0x101ea9, 0x101eab, 0x101ead, 0x101eaf, 0x101eb1, 0x101eb3, - 0x101eb5, 0x101eb7, 0x101eb9, 0x101ebb, 0x101ebd, 0x101ebf, 0x101ec1, 0x101ec3, 0x101ec5, - 0x101ec7, 0x101ec9, 0x101ecb, 0x101ecd, 0x101ecf, 0x101ed1, 0x101ed3, 0x101ed5, 0x101ed7, - 0x101ed9, 0x101edb, 0x101edd, 0x101edf, 0x101ee1, 0x101ee3, 0x101ee5, 0x101ee7, 0x101ee9, - 0x101eeb, 0x101eed, 0x101eef, 0x101ef1, 0x101ef3, 0x101ef5, 0x101ef7, 0x101ef9, 0x101efb, - 0x101efd, 0x101fb6, 0x101fb7, 0x101fbe, 0x101fc6, 0x101fc7, 0x101fd6, 0x101fd7, 0x101ff6, - 0x101ff7, 0x10210a, 0x10210e, 0x10210f, 0x102113, 0x10212f, 0x102134, 0x102139, 0x10213c, - 0x10213d, 0x10214e, 0x102184, 0x102c61, 0x102c65, 0x102c66, 0x102c68, 0x102c6a, 0x102c6c, - 0x102c71, 0x102c73, 0x102c74, 0x102c81, 0x102c83, 0x102c85, 0x102c87, 0x102c89, 0x102c8b, - 0x102c8d, 0x102c8f, 0x102c91, 0x102c93, 0x102c95, 0x102c97, 0x102c99, 0x102c9b, 0x102c9d, - 0x102c9f, 0x102ca1, 0x102ca3, 0x102ca5, 0x102ca7, 0x102ca9, 0x102cab, 0x102cad, 0x102caf, - 0x102cb1, 0x102cb3, 0x102cb5, 0x102cb7, 0x102cb9, 0x102cbb, 0x102cbd, 0x102cbf, 0x102cc1, - 0x102cc3, 0x102cc5, 0x102cc7, 0x102cc9, 0x102ccb, 0x102ccd, 0x102ccf, 0x102cd1, 0x102cd3, - 0x102cd5, 0x102cd7, 0x102cd9, 0x102cdb, 0x102cdd, 0x102cdf, 0x102ce1, 0x102ce3, 0x102ce4, - 0x102cec, 0x102cee, 0x102cf3, 0x102d27, 0x102d2d, 0x10a641, 0x10a643, 0x10a645, 0x10a647, - 0x10a649, 0x10a64b, 0x10a64d, 0x10a64f, 0x10a651, 0x10a653, 0x10a655, 0x10a657, 0x10a659, - 0x10a65b, 0x10a65d, 0x10a65f, 0x10a661, 0x10a663, 0x10a665, 0x10a667, 0x10a669, 0x10a66b, - 0x10a66d, 0x10a681, 0x10a683, 0x10a685, 0x10a687, 0x10a689, 0x10a68b, 0x10a68d, 0x10a68f, - 0x10a691, 0x10a693, 0x10a695, 0x10a697, 0x10a699, 0x10a69b, 0x10a723, 0x10a725, 0x10a727, - 0x10a729, 0x10a72b, 0x10a72d, 0x10a733, 0x10a735, 0x10a737, 0x10a739, 0x10a73b, 0x10a73d, - 0x10a73f, 0x10a741, 0x10a743, 0x10a745, 0x10a747, 0x10a749, 0x10a74b, 0x10a74d, 0x10a74f, - 0x10a751, 0x10a753, 0x10a755, 0x10a757, 0x10a759, 0x10a75b, 0x10a75d, 0x10a75f, 0x10a761, - 0x10a763, 0x10a765, 0x10a767, 0x10a769, 0x10a76b, 0x10a76d, 0x10a76f, 0x10a77a, 0x10a77c, - 0x10a77f, 0x10a781, 0x10a783, 0x10a785, 0x10a787, 0x10a78c, 0x10a78e, 0x10a791, 0x10a797, - 0x10a799, 0x10a79b, 0x10a79d, 0x10a79f, 0x10a7a1, 0x10a7a3, 0x10a7a5, 0x10a7a7, 0x10a7a9, - 0x10a7b5, 0x10a7b7, 0x10a7fa + ,0x1d4bb, 0x1d7cb #endif }; @@ -3626,166 +525,13 @@ static const crange upperRangeTable[] = { {0x2130, 0x2133}, {0x2c00, 0x2c2e}, {0x2c62, 0x2c64}, {0x2c6d, 0x2c70}, {0x2c7e, 0x2c80}, {0xa7aa, 0xa7ae}, {0xa7b0, 0xa7b4}, {0xff21, 0xff3a} #if TCL_UTF_MAX > 4 - ,{0x10041, 0x1005a}, {0x100c0, 0x100d6}, {0x100d8, 0x100de}, {0x10189, 0x1018b}, - {0x1018e, 0x10191}, {0x10196, 0x10198}, {0x101b1, 0x101b3}, {0x101f6, 0x101f8}, - {0x10243, 0x10246}, {0x10388, 0x1038a}, {0x10391, 0x103a1}, {0x103a3, 0x103ab}, - {0x103d2, 0x103d4}, {0x103fd, 0x1042f}, {0x10531, 0x10556}, {0x110a0, 0x110c5}, - {0x113a0, 0x113f5}, {0x11f08, 0x11f0f}, {0x11f18, 0x11f1d}, {0x11f28, 0x11f2f}, - {0x11f38, 0x11f3f}, {0x11f48, 0x11f4d}, {0x11f68, 0x11f6f}, {0x11fb8, 0x11fbb}, - {0x11fc8, 0x11fcb}, {0x11fd8, 0x11fdb}, {0x11fe8, 0x11fec}, {0x11ff8, 0x11ffb}, - {0x1210b, 0x1210d}, {0x12110, 0x12112}, {0x12119, 0x1211d}, {0x1212a, 0x1212d}, - {0x12130, 0x12133}, {0x12c00, 0x12c2e}, {0x12c62, 0x12c64}, {0x12c6d, 0x12c70}, - {0x12c7e, 0x12c80}, {0x1a7aa, 0x1a7ae}, {0x1a7b0, 0x1a7b4}, {0x1ff21, 0x1ff3a}, - {0x20041, 0x2005a}, {0x200c0, 0x200d6}, {0x200d8, 0x200de}, {0x20189, 0x2018b}, - {0x2018e, 0x20191}, {0x20196, 0x20198}, {0x201b1, 0x201b3}, {0x201f6, 0x201f8}, - {0x20243, 0x20246}, {0x20388, 0x2038a}, {0x20391, 0x203a1}, {0x203a3, 0x203ab}, - {0x203d2, 0x203d4}, {0x203fd, 0x2042f}, {0x20531, 0x20556}, {0x210a0, 0x210c5}, - {0x213a0, 0x213f5}, {0x21f08, 0x21f0f}, {0x21f18, 0x21f1d}, {0x21f28, 0x21f2f}, - {0x21f38, 0x21f3f}, {0x21f48, 0x21f4d}, {0x21f68, 0x21f6f}, {0x21fb8, 0x21fbb}, - {0x21fc8, 0x21fcb}, {0x21fd8, 0x21fdb}, {0x21fe8, 0x21fec}, {0x21ff8, 0x21ffb}, - {0x2210b, 0x2210d}, {0x22110, 0x22112}, {0x22119, 0x2211d}, {0x2212a, 0x2212d}, - {0x22130, 0x22133}, {0x22c00, 0x22c2e}, {0x22c62, 0x22c64}, {0x22c6d, 0x22c70}, - {0x22c7e, 0x22c80}, {0x2a7aa, 0x2a7ae}, {0x2a7b0, 0x2a7b4}, {0x2ff21, 0x2ff3a}, - {0x30041, 0x3005a}, {0x300c0, 0x300d6}, {0x300d8, 0x300de}, {0x30189, 0x3018b}, - {0x3018e, 0x30191}, {0x30196, 0x30198}, {0x301b1, 0x301b3}, {0x301f6, 0x301f8}, - {0x30243, 0x30246}, {0x30388, 0x3038a}, {0x30391, 0x303a1}, {0x303a3, 0x303ab}, - {0x303d2, 0x303d4}, {0x303fd, 0x3042f}, {0x30531, 0x30556}, {0x310a0, 0x310c5}, - {0x313a0, 0x313f5}, {0x31f08, 0x31f0f}, {0x31f18, 0x31f1d}, {0x31f28, 0x31f2f}, - {0x31f38, 0x31f3f}, {0x31f48, 0x31f4d}, {0x31f68, 0x31f6f}, {0x31fb8, 0x31fbb}, - {0x31fc8, 0x31fcb}, {0x31fd8, 0x31fdb}, {0x31fe8, 0x31fec}, {0x31ff8, 0x31ffb}, - {0x3210b, 0x3210d}, {0x32110, 0x32112}, {0x32119, 0x3211d}, {0x3212a, 0x3212d}, - {0x32130, 0x32133}, {0x32c00, 0x32c2e}, {0x32c62, 0x32c64}, {0x32c6d, 0x32c70}, - {0x32c7e, 0x32c80}, {0x3a7aa, 0x3a7ae}, {0x3a7b0, 0x3a7b4}, {0x3ff21, 0x3ff3a}, - {0x40041, 0x4005a}, {0x400c0, 0x400d6}, {0x400d8, 0x400de}, {0x40189, 0x4018b}, - {0x4018e, 0x40191}, {0x40196, 0x40198}, {0x401b1, 0x401b3}, {0x401f6, 0x401f8}, - {0x40243, 0x40246}, {0x40388, 0x4038a}, {0x40391, 0x403a1}, {0x403a3, 0x403ab}, - {0x403d2, 0x403d4}, {0x403fd, 0x4042f}, {0x40531, 0x40556}, {0x410a0, 0x410c5}, - {0x413a0, 0x413f5}, {0x41f08, 0x41f0f}, {0x41f18, 0x41f1d}, {0x41f28, 0x41f2f}, - {0x41f38, 0x41f3f}, {0x41f48, 0x41f4d}, {0x41f68, 0x41f6f}, {0x41fb8, 0x41fbb}, - {0x41fc8, 0x41fcb}, {0x41fd8, 0x41fdb}, {0x41fe8, 0x41fec}, {0x41ff8, 0x41ffb}, - {0x4210b, 0x4210d}, {0x42110, 0x42112}, {0x42119, 0x4211d}, {0x4212a, 0x4212d}, - {0x42130, 0x42133}, {0x42c00, 0x42c2e}, {0x42c62, 0x42c64}, {0x42c6d, 0x42c70}, - {0x42c7e, 0x42c80}, {0x4a7aa, 0x4a7ae}, {0x4a7b0, 0x4a7b4}, {0x4ff21, 0x4ff3a}, - {0x50041, 0x5005a}, {0x500c0, 0x500d6}, {0x500d8, 0x500de}, {0x50189, 0x5018b}, - {0x5018e, 0x50191}, {0x50196, 0x50198}, {0x501b1, 0x501b3}, {0x501f6, 0x501f8}, - {0x50243, 0x50246}, {0x50388, 0x5038a}, {0x50391, 0x503a1}, {0x503a3, 0x503ab}, - {0x503d2, 0x503d4}, {0x503fd, 0x5042f}, {0x50531, 0x50556}, {0x510a0, 0x510c5}, - {0x513a0, 0x513f5}, {0x51f08, 0x51f0f}, {0x51f18, 0x51f1d}, {0x51f28, 0x51f2f}, - {0x51f38, 0x51f3f}, {0x51f48, 0x51f4d}, {0x51f68, 0x51f6f}, {0x51fb8, 0x51fbb}, - {0x51fc8, 0x51fcb}, {0x51fd8, 0x51fdb}, {0x51fe8, 0x51fec}, {0x51ff8, 0x51ffb}, - {0x5210b, 0x5210d}, {0x52110, 0x52112}, {0x52119, 0x5211d}, {0x5212a, 0x5212d}, - {0x52130, 0x52133}, {0x52c00, 0x52c2e}, {0x52c62, 0x52c64}, {0x52c6d, 0x52c70}, - {0x52c7e, 0x52c80}, {0x5a7aa, 0x5a7ae}, {0x5a7b0, 0x5a7b4}, {0x5ff21, 0x5ff3a}, - {0x60041, 0x6005a}, {0x600c0, 0x600d6}, {0x600d8, 0x600de}, {0x60189, 0x6018b}, - {0x6018e, 0x60191}, {0x60196, 0x60198}, {0x601b1, 0x601b3}, {0x601f6, 0x601f8}, - {0x60243, 0x60246}, {0x60388, 0x6038a}, {0x60391, 0x603a1}, {0x603a3, 0x603ab}, - {0x603d2, 0x603d4}, {0x603fd, 0x6042f}, {0x60531, 0x60556}, {0x610a0, 0x610c5}, - {0x613a0, 0x613f5}, {0x61f08, 0x61f0f}, {0x61f18, 0x61f1d}, {0x61f28, 0x61f2f}, - {0x61f38, 0x61f3f}, {0x61f48, 0x61f4d}, {0x61f68, 0x61f6f}, {0x61fb8, 0x61fbb}, - {0x61fc8, 0x61fcb}, {0x61fd8, 0x61fdb}, {0x61fe8, 0x61fec}, {0x61ff8, 0x61ffb}, - {0x6210b, 0x6210d}, {0x62110, 0x62112}, {0x62119, 0x6211d}, {0x6212a, 0x6212d}, - {0x62130, 0x62133}, {0x62c00, 0x62c2e}, {0x62c62, 0x62c64}, {0x62c6d, 0x62c70}, - {0x62c7e, 0x62c80}, {0x6a7aa, 0x6a7ae}, {0x6a7b0, 0x6a7b4}, {0x6ff21, 0x6ff3a}, - {0x70041, 0x7005a}, {0x700c0, 0x700d6}, {0x700d8, 0x700de}, {0x70189, 0x7018b}, - {0x7018e, 0x70191}, {0x70196, 0x70198}, {0x701b1, 0x701b3}, {0x701f6, 0x701f8}, - {0x70243, 0x70246}, {0x70388, 0x7038a}, {0x70391, 0x703a1}, {0x703a3, 0x703ab}, - {0x703d2, 0x703d4}, {0x703fd, 0x7042f}, {0x70531, 0x70556}, {0x710a0, 0x710c5}, - {0x713a0, 0x713f5}, {0x71f08, 0x71f0f}, {0x71f18, 0x71f1d}, {0x71f28, 0x71f2f}, - {0x71f38, 0x71f3f}, {0x71f48, 0x71f4d}, {0x71f68, 0x71f6f}, {0x71fb8, 0x71fbb}, - {0x71fc8, 0x71fcb}, {0x71fd8, 0x71fdb}, {0x71fe8, 0x71fec}, {0x71ff8, 0x71ffb}, - {0x7210b, 0x7210d}, {0x72110, 0x72112}, {0x72119, 0x7211d}, {0x7212a, 0x7212d}, - {0x72130, 0x72133}, {0x72c00, 0x72c2e}, {0x72c62, 0x72c64}, {0x72c6d, 0x72c70}, - {0x72c7e, 0x72c80}, {0x7a7aa, 0x7a7ae}, {0x7a7b0, 0x7a7b4}, {0x7ff21, 0x7ff3a}, - {0x80041, 0x8005a}, {0x800c0, 0x800d6}, {0x800d8, 0x800de}, {0x80189, 0x8018b}, - {0x8018e, 0x80191}, {0x80196, 0x80198}, {0x801b1, 0x801b3}, {0x801f6, 0x801f8}, - {0x80243, 0x80246}, {0x80388, 0x8038a}, {0x80391, 0x803a1}, {0x803a3, 0x803ab}, - {0x803d2, 0x803d4}, {0x803fd, 0x8042f}, {0x80531, 0x80556}, {0x810a0, 0x810c5}, - {0x813a0, 0x813f5}, {0x81f08, 0x81f0f}, {0x81f18, 0x81f1d}, {0x81f28, 0x81f2f}, - {0x81f38, 0x81f3f}, {0x81f48, 0x81f4d}, {0x81f68, 0x81f6f}, {0x81fb8, 0x81fbb}, - {0x81fc8, 0x81fcb}, {0x81fd8, 0x81fdb}, {0x81fe8, 0x81fec}, {0x81ff8, 0x81ffb}, - {0x8210b, 0x8210d}, {0x82110, 0x82112}, {0x82119, 0x8211d}, {0x8212a, 0x8212d}, - {0x82130, 0x82133}, {0x82c00, 0x82c2e}, {0x82c62, 0x82c64}, {0x82c6d, 0x82c70}, - {0x82c7e, 0x82c80}, {0x8a7aa, 0x8a7ae}, {0x8a7b0, 0x8a7b4}, {0x8ff21, 0x8ff3a}, - {0x90041, 0x9005a}, {0x900c0, 0x900d6}, {0x900d8, 0x900de}, {0x90189, 0x9018b}, - {0x9018e, 0x90191}, {0x90196, 0x90198}, {0x901b1, 0x901b3}, {0x901f6, 0x901f8}, - {0x90243, 0x90246}, {0x90388, 0x9038a}, {0x90391, 0x903a1}, {0x903a3, 0x903ab}, - {0x903d2, 0x903d4}, {0x903fd, 0x9042f}, {0x90531, 0x90556}, {0x910a0, 0x910c5}, - {0x913a0, 0x913f5}, {0x91f08, 0x91f0f}, {0x91f18, 0x91f1d}, {0x91f28, 0x91f2f}, - {0x91f38, 0x91f3f}, {0x91f48, 0x91f4d}, {0x91f68, 0x91f6f}, {0x91fb8, 0x91fbb}, - {0x91fc8, 0x91fcb}, {0x91fd8, 0x91fdb}, {0x91fe8, 0x91fec}, {0x91ff8, 0x91ffb}, - {0x9210b, 0x9210d}, {0x92110, 0x92112}, {0x92119, 0x9211d}, {0x9212a, 0x9212d}, - {0x92130, 0x92133}, {0x92c00, 0x92c2e}, {0x92c62, 0x92c64}, {0x92c6d, 0x92c70}, - {0x92c7e, 0x92c80}, {0x9a7aa, 0x9a7ae}, {0x9a7b0, 0x9a7b4}, {0x9ff21, 0x9ff3a}, - {0xa0041, 0xa005a}, {0xa00c0, 0xa00d6}, {0xa00d8, 0xa00de}, {0xa0189, 0xa018b}, - {0xa018e, 0xa0191}, {0xa0196, 0xa0198}, {0xa01b1, 0xa01b3}, {0xa01f6, 0xa01f8}, - {0xa0243, 0xa0246}, {0xa0388, 0xa038a}, {0xa0391, 0xa03a1}, {0xa03a3, 0xa03ab}, - {0xa03d2, 0xa03d4}, {0xa03fd, 0xa042f}, {0xa0531, 0xa0556}, {0xa10a0, 0xa10c5}, - {0xa13a0, 0xa13f5}, {0xa1f08, 0xa1f0f}, {0xa1f18, 0xa1f1d}, {0xa1f28, 0xa1f2f}, - {0xa1f38, 0xa1f3f}, {0xa1f48, 0xa1f4d}, {0xa1f68, 0xa1f6f}, {0xa1fb8, 0xa1fbb}, - {0xa1fc8, 0xa1fcb}, {0xa1fd8, 0xa1fdb}, {0xa1fe8, 0xa1fec}, {0xa1ff8, 0xa1ffb}, - {0xa210b, 0xa210d}, {0xa2110, 0xa2112}, {0xa2119, 0xa211d}, {0xa212a, 0xa212d}, - {0xa2130, 0xa2133}, {0xa2c00, 0xa2c2e}, {0xa2c62, 0xa2c64}, {0xa2c6d, 0xa2c70}, - {0xa2c7e, 0xa2c80}, {0xaa7aa, 0xaa7ae}, {0xaa7b0, 0xaa7b4}, {0xaff21, 0xaff3a}, - {0xb0041, 0xb005a}, {0xb00c0, 0xb00d6}, {0xb00d8, 0xb00de}, {0xb0189, 0xb018b}, - {0xb018e, 0xb0191}, {0xb0196, 0xb0198}, {0xb01b1, 0xb01b3}, {0xb01f6, 0xb01f8}, - {0xb0243, 0xb0246}, {0xb0388, 0xb038a}, {0xb0391, 0xb03a1}, {0xb03a3, 0xb03ab}, - {0xb03d2, 0xb03d4}, {0xb03fd, 0xb042f}, {0xb0531, 0xb0556}, {0xb10a0, 0xb10c5}, - {0xb13a0, 0xb13f5}, {0xb1f08, 0xb1f0f}, {0xb1f18, 0xb1f1d}, {0xb1f28, 0xb1f2f}, - {0xb1f38, 0xb1f3f}, {0xb1f48, 0xb1f4d}, {0xb1f68, 0xb1f6f}, {0xb1fb8, 0xb1fbb}, - {0xb1fc8, 0xb1fcb}, {0xb1fd8, 0xb1fdb}, {0xb1fe8, 0xb1fec}, {0xb1ff8, 0xb1ffb}, - {0xb210b, 0xb210d}, {0xb2110, 0xb2112}, {0xb2119, 0xb211d}, {0xb212a, 0xb212d}, - {0xb2130, 0xb2133}, {0xb2c00, 0xb2c2e}, {0xb2c62, 0xb2c64}, {0xb2c6d, 0xb2c70}, - {0xb2c7e, 0xb2c80}, {0xba7aa, 0xba7ae}, {0xba7b0, 0xba7b4}, {0xbff21, 0xbff3a}, - {0xc0041, 0xc005a}, {0xc00c0, 0xc00d6}, {0xc00d8, 0xc00de}, {0xc0189, 0xc018b}, - {0xc018e, 0xc0191}, {0xc0196, 0xc0198}, {0xc01b1, 0xc01b3}, {0xc01f6, 0xc01f8}, - {0xc0243, 0xc0246}, {0xc0388, 0xc038a}, {0xc0391, 0xc03a1}, {0xc03a3, 0xc03ab}, - {0xc03d2, 0xc03d4}, {0xc03fd, 0xc042f}, {0xc0531, 0xc0556}, {0xc10a0, 0xc10c5}, - {0xc13a0, 0xc13f5}, {0xc1f08, 0xc1f0f}, {0xc1f18, 0xc1f1d}, {0xc1f28, 0xc1f2f}, - {0xc1f38, 0xc1f3f}, {0xc1f48, 0xc1f4d}, {0xc1f68, 0xc1f6f}, {0xc1fb8, 0xc1fbb}, - {0xc1fc8, 0xc1fcb}, {0xc1fd8, 0xc1fdb}, {0xc1fe8, 0xc1fec}, {0xc1ff8, 0xc1ffb}, - {0xc210b, 0xc210d}, {0xc2110, 0xc2112}, {0xc2119, 0xc211d}, {0xc212a, 0xc212d}, - {0xc2130, 0xc2133}, {0xc2c00, 0xc2c2e}, {0xc2c62, 0xc2c64}, {0xc2c6d, 0xc2c70}, - {0xc2c7e, 0xc2c80}, {0xca7aa, 0xca7ae}, {0xca7b0, 0xca7b4}, {0xcff21, 0xcff3a}, - {0xd0041, 0xd005a}, {0xd00c0, 0xd00d6}, {0xd00d8, 0xd00de}, {0xd0189, 0xd018b}, - {0xd018e, 0xd0191}, {0xd0196, 0xd0198}, {0xd01b1, 0xd01b3}, {0xd01f6, 0xd01f8}, - {0xd0243, 0xd0246}, {0xd0388, 0xd038a}, {0xd0391, 0xd03a1}, {0xd03a3, 0xd03ab}, - {0xd03d2, 0xd03d4}, {0xd03fd, 0xd042f}, {0xd0531, 0xd0556}, {0xd10a0, 0xd10c5}, - {0xd13a0, 0xd13f5}, {0xd1f08, 0xd1f0f}, {0xd1f18, 0xd1f1d}, {0xd1f28, 0xd1f2f}, - {0xd1f38, 0xd1f3f}, {0xd1f48, 0xd1f4d}, {0xd1f68, 0xd1f6f}, {0xd1fb8, 0xd1fbb}, - {0xd1fc8, 0xd1fcb}, {0xd1fd8, 0xd1fdb}, {0xd1fe8, 0xd1fec}, {0xd1ff8, 0xd1ffb}, - {0xd210b, 0xd210d}, {0xd2110, 0xd2112}, {0xd2119, 0xd211d}, {0xd212a, 0xd212d}, - {0xd2130, 0xd2133}, {0xd2c00, 0xd2c2e}, {0xd2c62, 0xd2c64}, {0xd2c6d, 0xd2c70}, - {0xd2c7e, 0xd2c80}, {0xda7aa, 0xda7ae}, {0xda7b0, 0xda7b4}, {0xdff21, 0xdff3a}, - {0xe0041, 0xe005a}, {0xe00c0, 0xe00d6}, {0xe00d8, 0xe00de}, {0xe0189, 0xe018b}, - {0xe018e, 0xe0191}, {0xe0196, 0xe0198}, {0xe01b1, 0xe01b3}, {0xe01f6, 0xe01f8}, - {0xe0243, 0xe0246}, {0xe0388, 0xe038a}, {0xe0391, 0xe03a1}, {0xe03a3, 0xe03ab}, - {0xe03d2, 0xe03d4}, {0xe03fd, 0xe042f}, {0xe0531, 0xe0556}, {0xe10a0, 0xe10c5}, - {0xe13a0, 0xe13f5}, {0xe1f08, 0xe1f0f}, {0xe1f18, 0xe1f1d}, {0xe1f28, 0xe1f2f}, - {0xe1f38, 0xe1f3f}, {0xe1f48, 0xe1f4d}, {0xe1f68, 0xe1f6f}, {0xe1fb8, 0xe1fbb}, - {0xe1fc8, 0xe1fcb}, {0xe1fd8, 0xe1fdb}, {0xe1fe8, 0xe1fec}, {0xe1ff8, 0xe1ffb}, - {0xe210b, 0xe210d}, {0xe2110, 0xe2112}, {0xe2119, 0xe211d}, {0xe212a, 0xe212d}, - {0xe2130, 0xe2133}, {0xe2c00, 0xe2c2e}, {0xe2c62, 0xe2c64}, {0xe2c6d, 0xe2c70}, - {0xe2c7e, 0xe2c80}, {0xea7aa, 0xea7ae}, {0xea7b0, 0xea7b4}, {0xeff21, 0xeff3a}, - {0xf0041, 0xf005a}, {0xf00c0, 0xf00d6}, {0xf00d8, 0xf00de}, {0xf0189, 0xf018b}, - {0xf018e, 0xf0191}, {0xf0196, 0xf0198}, {0xf01b1, 0xf01b3}, {0xf01f6, 0xf01f8}, - {0xf0243, 0xf0246}, {0xf0388, 0xf038a}, {0xf0391, 0xf03a1}, {0xf03a3, 0xf03ab}, - {0xf03d2, 0xf03d4}, {0xf03fd, 0xf042f}, {0xf0531, 0xf0556}, {0xf10a0, 0xf10c5}, - {0xf13a0, 0xf13f5}, {0xf1f08, 0xf1f0f}, {0xf1f18, 0xf1f1d}, {0xf1f28, 0xf1f2f}, - {0xf1f38, 0xf1f3f}, {0xf1f48, 0xf1f4d}, {0xf1f68, 0xf1f6f}, {0xf1fb8, 0xf1fbb}, - {0xf1fc8, 0xf1fcb}, {0xf1fd8, 0xf1fdb}, {0xf1fe8, 0xf1fec}, {0xf1ff8, 0xf1ffb}, - {0xf210b, 0xf210d}, {0xf2110, 0xf2112}, {0xf2119, 0xf211d}, {0xf212a, 0xf212d}, - {0xf2130, 0xf2133}, {0xf2c00, 0xf2c2e}, {0xf2c62, 0xf2c64}, {0xf2c6d, 0xf2c70}, - {0xf2c7e, 0xf2c80}, {0xfa7aa, 0xfa7ae}, {0xfa7b0, 0xfa7b4}, {0xfff21, 0xfff3a}, - {0x100041, 0x10005a}, {0x1000c0, 0x1000d6}, {0x1000d8, 0x1000de}, {0x100189, 0x10018b}, - {0x10018e, 0x100191}, {0x100196, 0x100198}, {0x1001b1, 0x1001b3}, {0x1001f6, 0x1001f8}, - {0x100243, 0x100246}, {0x100388, 0x10038a}, {0x100391, 0x1003a1}, {0x1003a3, 0x1003ab}, - {0x1003d2, 0x1003d4}, {0x1003fd, 0x10042f}, {0x100531, 0x100556}, {0x1010a0, 0x1010c5}, - {0x1013a0, 0x1013f5}, {0x101f08, 0x101f0f}, {0x101f18, 0x101f1d}, {0x101f28, 0x101f2f}, - {0x101f38, 0x101f3f}, {0x101f48, 0x101f4d}, {0x101f68, 0x101f6f}, {0x101fb8, 0x101fbb}, - {0x101fc8, 0x101fcb}, {0x101fd8, 0x101fdb}, {0x101fe8, 0x101fec}, {0x101ff8, 0x101ffb}, - {0x10210b, 0x10210d}, {0x102110, 0x102112}, {0x102119, 0x10211d}, {0x10212a, 0x10212d}, - {0x102130, 0x102133}, {0x102c00, 0x102c2e}, {0x102c62, 0x102c64}, {0x102c6d, 0x102c70}, - {0x102c7e, 0x102c80}, {0x10a7aa, 0x10a7ae}, {0x10a7b0, 0x10a7b4}, {0x10ff21, 0x10ff3a} + ,{0x10400, 0x10427}, {0x104b0, 0x104d3}, {0x10c80, 0x10cb2}, {0x118a0, 0x118bf}, + {0x1d400, 0x1d419}, {0x1d434, 0x1d44d}, {0x1d468, 0x1d481}, {0x1d4a9, 0x1d4ac}, + {0x1d4ae, 0x1d4b5}, {0x1d4d0, 0x1d4e9}, {0x1d507, 0x1d50a}, {0x1d50d, 0x1d514}, + {0x1d516, 0x1d51c}, {0x1d53b, 0x1d53e}, {0x1d540, 0x1d544}, {0x1d54a, 0x1d550}, + {0x1d56c, 0x1d585}, {0x1d5a0, 0x1d5b9}, {0x1d5d4, 0x1d5ed}, {0x1d608, 0x1d621}, + {0x1d63c, 0x1d655}, {0x1d670, 0x1d689}, {0x1d6a8, 0x1d6c0}, {0x1d6e2, 0x1d6fa}, + {0x1d71c, 0x1d734}, {0x1d756, 0x1d76e}, {0x1d790, 0x1d7a8}, {0x1e900, 0x1e921} #endif }; @@ -3856,1014 +602,8 @@ static const chr upperCharTable[] = { 0xa782, 0xa784, 0xa786, 0xa78b, 0xa78d, 0xa790, 0xa792, 0xa796, 0xa798, 0xa79a, 0xa79c, 0xa79e, 0xa7a0, 0xa7a2, 0xa7a4, 0xa7a6, 0xa7a8, 0xa7b6 #if TCL_UTF_MAX > 4 - ,0x10100, 0x10102, 0x10104, 0x10106, 0x10108, 0x1010a, 0x1010c, 0x1010e, 0x10110, - 0x10112, 0x10114, 0x10116, 0x10118, 0x1011a, 0x1011c, 0x1011e, 0x10120, 0x10122, - 0x10124, 0x10126, 0x10128, 0x1012a, 0x1012c, 0x1012e, 0x10130, 0x10132, 0x10134, - 0x10136, 0x10139, 0x1013b, 0x1013d, 0x1013f, 0x10141, 0x10143, 0x10145, 0x10147, - 0x1014a, 0x1014c, 0x1014e, 0x10150, 0x10152, 0x10154, 0x10156, 0x10158, 0x1015a, - 0x1015c, 0x1015e, 0x10160, 0x10162, 0x10164, 0x10166, 0x10168, 0x1016a, 0x1016c, - 0x1016e, 0x10170, 0x10172, 0x10174, 0x10176, 0x10178, 0x10179, 0x1017b, 0x1017d, - 0x10181, 0x10182, 0x10184, 0x10186, 0x10187, 0x10193, 0x10194, 0x1019c, 0x1019d, - 0x1019f, 0x101a0, 0x101a2, 0x101a4, 0x101a6, 0x101a7, 0x101a9, 0x101ac, 0x101ae, - 0x101af, 0x101b5, 0x101b7, 0x101b8, 0x101bc, 0x101c4, 0x101c7, 0x101ca, 0x101cd, - 0x101cf, 0x101d1, 0x101d3, 0x101d5, 0x101d7, 0x101d9, 0x101db, 0x101de, 0x101e0, - 0x101e2, 0x101e4, 0x101e6, 0x101e8, 0x101ea, 0x101ec, 0x101ee, 0x101f1, 0x101f4, - 0x101fa, 0x101fc, 0x101fe, 0x10200, 0x10202, 0x10204, 0x10206, 0x10208, 0x1020a, - 0x1020c, 0x1020e, 0x10210, 0x10212, 0x10214, 0x10216, 0x10218, 0x1021a, 0x1021c, - 0x1021e, 0x10220, 0x10222, 0x10224, 0x10226, 0x10228, 0x1022a, 0x1022c, 0x1022e, - 0x10230, 0x10232, 0x1023a, 0x1023b, 0x1023d, 0x1023e, 0x10241, 0x10248, 0x1024a, - 0x1024c, 0x1024e, 0x10370, 0x10372, 0x10376, 0x1037f, 0x10386, 0x1038c, 0x1038e, - 0x1038f, 0x103cf, 0x103d8, 0x103da, 0x103dc, 0x103de, 0x103e0, 0x103e2, 0x103e4, - 0x103e6, 0x103e8, 0x103ea, 0x103ec, 0x103ee, 0x103f4, 0x103f7, 0x103f9, 0x103fa, - 0x10460, 0x10462, 0x10464, 0x10466, 0x10468, 0x1046a, 0x1046c, 0x1046e, 0x10470, - 0x10472, 0x10474, 0x10476, 0x10478, 0x1047a, 0x1047c, 0x1047e, 0x10480, 0x1048a, - 0x1048c, 0x1048e, 0x10490, 0x10492, 0x10494, 0x10496, 0x10498, 0x1049a, 0x1049c, - 0x1049e, 0x104a0, 0x104a2, 0x104a4, 0x104a6, 0x104a8, 0x104aa, 0x104ac, 0x104ae, - 0x104b0, 0x104b2, 0x104b4, 0x104b6, 0x104b8, 0x104ba, 0x104bc, 0x104be, 0x104c0, - 0x104c1, 0x104c3, 0x104c5, 0x104c7, 0x104c9, 0x104cb, 0x104cd, 0x104d0, 0x104d2, - 0x104d4, 0x104d6, 0x104d8, 0x104da, 0x104dc, 0x104de, 0x104e0, 0x104e2, 0x104e4, - 0x104e6, 0x104e8, 0x104ea, 0x104ec, 0x104ee, 0x104f0, 0x104f2, 0x104f4, 0x104f6, - 0x104f8, 0x104fa, 0x104fc, 0x104fe, 0x10500, 0x10502, 0x10504, 0x10506, 0x10508, - 0x1050a, 0x1050c, 0x1050e, 0x10510, 0x10512, 0x10514, 0x10516, 0x10518, 0x1051a, - 0x1051c, 0x1051e, 0x10520, 0x10522, 0x10524, 0x10526, 0x10528, 0x1052a, 0x1052c, - 0x1052e, 0x110c7, 0x110cd, 0x11e00, 0x11e02, 0x11e04, 0x11e06, 0x11e08, 0x11e0a, - 0x11e0c, 0x11e0e, 0x11e10, 0x11e12, 0x11e14, 0x11e16, 0x11e18, 0x11e1a, 0x11e1c, - 0x11e1e, 0x11e20, 0x11e22, 0x11e24, 0x11e26, 0x11e28, 0x11e2a, 0x11e2c, 0x11e2e, - 0x11e30, 0x11e32, 0x11e34, 0x11e36, 0x11e38, 0x11e3a, 0x11e3c, 0x11e3e, 0x11e40, - 0x11e42, 0x11e44, 0x11e46, 0x11e48, 0x11e4a, 0x11e4c, 0x11e4e, 0x11e50, 0x11e52, - 0x11e54, 0x11e56, 0x11e58, 0x11e5a, 0x11e5c, 0x11e5e, 0x11e60, 0x11e62, 0x11e64, - 0x11e66, 0x11e68, 0x11e6a, 0x11e6c, 0x11e6e, 0x11e70, 0x11e72, 0x11e74, 0x11e76, - 0x11e78, 0x11e7a, 0x11e7c, 0x11e7e, 0x11e80, 0x11e82, 0x11e84, 0x11e86, 0x11e88, - 0x11e8a, 0x11e8c, 0x11e8e, 0x11e90, 0x11e92, 0x11e94, 0x11e9e, 0x11ea0, 0x11ea2, - 0x11ea4, 0x11ea6, 0x11ea8, 0x11eaa, 0x11eac, 0x11eae, 0x11eb0, 0x11eb2, 0x11eb4, - 0x11eb6, 0x11eb8, 0x11eba, 0x11ebc, 0x11ebe, 0x11ec0, 0x11ec2, 0x11ec4, 0x11ec6, - 0x11ec8, 0x11eca, 0x11ecc, 0x11ece, 0x11ed0, 0x11ed2, 0x11ed4, 0x11ed6, 0x11ed8, - 0x11eda, 0x11edc, 0x11ede, 0x11ee0, 0x11ee2, 0x11ee4, 0x11ee6, 0x11ee8, 0x11eea, - 0x11eec, 0x11eee, 0x11ef0, 0x11ef2, 0x11ef4, 0x11ef6, 0x11ef8, 0x11efa, 0x11efc, - 0x11efe, 0x11f59, 0x11f5b, 0x11f5d, 0x11f5f, 0x12102, 0x12107, 0x12115, 0x12124, - 0x12126, 0x12128, 0x1213e, 0x1213f, 0x12145, 0x12183, 0x12c60, 0x12c67, 0x12c69, - 0x12c6b, 0x12c72, 0x12c75, 0x12c82, 0x12c84, 0x12c86, 0x12c88, 0x12c8a, 0x12c8c, - 0x12c8e, 0x12c90, 0x12c92, 0x12c94, 0x12c96, 0x12c98, 0x12c9a, 0x12c9c, 0x12c9e, - 0x12ca0, 0x12ca2, 0x12ca4, 0x12ca6, 0x12ca8, 0x12caa, 0x12cac, 0x12cae, 0x12cb0, - 0x12cb2, 0x12cb4, 0x12cb6, 0x12cb8, 0x12cba, 0x12cbc, 0x12cbe, 0x12cc0, 0x12cc2, - 0x12cc4, 0x12cc6, 0x12cc8, 0x12cca, 0x12ccc, 0x12cce, 0x12cd0, 0x12cd2, 0x12cd4, - 0x12cd6, 0x12cd8, 0x12cda, 0x12cdc, 0x12cde, 0x12ce0, 0x12ce2, 0x12ceb, 0x12ced, - 0x12cf2, 0x1a640, 0x1a642, 0x1a644, 0x1a646, 0x1a648, 0x1a64a, 0x1a64c, 0x1a64e, - 0x1a650, 0x1a652, 0x1a654, 0x1a656, 0x1a658, 0x1a65a, 0x1a65c, 0x1a65e, 0x1a660, - 0x1a662, 0x1a664, 0x1a666, 0x1a668, 0x1a66a, 0x1a66c, 0x1a680, 0x1a682, 0x1a684, - 0x1a686, 0x1a688, 0x1a68a, 0x1a68c, 0x1a68e, 0x1a690, 0x1a692, 0x1a694, 0x1a696, - 0x1a698, 0x1a69a, 0x1a722, 0x1a724, 0x1a726, 0x1a728, 0x1a72a, 0x1a72c, 0x1a72e, - 0x1a732, 0x1a734, 0x1a736, 0x1a738, 0x1a73a, 0x1a73c, 0x1a73e, 0x1a740, 0x1a742, - 0x1a744, 0x1a746, 0x1a748, 0x1a74a, 0x1a74c, 0x1a74e, 0x1a750, 0x1a752, 0x1a754, - 0x1a756, 0x1a758, 0x1a75a, 0x1a75c, 0x1a75e, 0x1a760, 0x1a762, 0x1a764, 0x1a766, - 0x1a768, 0x1a76a, 0x1a76c, 0x1a76e, 0x1a779, 0x1a77b, 0x1a77d, 0x1a77e, 0x1a780, - 0x1a782, 0x1a784, 0x1a786, 0x1a78b, 0x1a78d, 0x1a790, 0x1a792, 0x1a796, 0x1a798, - 0x1a79a, 0x1a79c, 0x1a79e, 0x1a7a0, 0x1a7a2, 0x1a7a4, 0x1a7a6, 0x1a7a8, 0x1a7b6, - 0x20100, 0x20102, 0x20104, 0x20106, 0x20108, 0x2010a, 0x2010c, 0x2010e, 0x20110, - 0x20112, 0x20114, 0x20116, 0x20118, 0x2011a, 0x2011c, 0x2011e, 0x20120, 0x20122, - 0x20124, 0x20126, 0x20128, 0x2012a, 0x2012c, 0x2012e, 0x20130, 0x20132, 0x20134, - 0x20136, 0x20139, 0x2013b, 0x2013d, 0x2013f, 0x20141, 0x20143, 0x20145, 0x20147, - 0x2014a, 0x2014c, 0x2014e, 0x20150, 0x20152, 0x20154, 0x20156, 0x20158, 0x2015a, - 0x2015c, 0x2015e, 0x20160, 0x20162, 0x20164, 0x20166, 0x20168, 0x2016a, 0x2016c, - 0x2016e, 0x20170, 0x20172, 0x20174, 0x20176, 0x20178, 0x20179, 0x2017b, 0x2017d, - 0x20181, 0x20182, 0x20184, 0x20186, 0x20187, 0x20193, 0x20194, 0x2019c, 0x2019d, - 0x2019f, 0x201a0, 0x201a2, 0x201a4, 0x201a6, 0x201a7, 0x201a9, 0x201ac, 0x201ae, - 0x201af, 0x201b5, 0x201b7, 0x201b8, 0x201bc, 0x201c4, 0x201c7, 0x201ca, 0x201cd, - 0x201cf, 0x201d1, 0x201d3, 0x201d5, 0x201d7, 0x201d9, 0x201db, 0x201de, 0x201e0, - 0x201e2, 0x201e4, 0x201e6, 0x201e8, 0x201ea, 0x201ec, 0x201ee, 0x201f1, 0x201f4, - 0x201fa, 0x201fc, 0x201fe, 0x20200, 0x20202, 0x20204, 0x20206, 0x20208, 0x2020a, - 0x2020c, 0x2020e, 0x20210, 0x20212, 0x20214, 0x20216, 0x20218, 0x2021a, 0x2021c, - 0x2021e, 0x20220, 0x20222, 0x20224, 0x20226, 0x20228, 0x2022a, 0x2022c, 0x2022e, - 0x20230, 0x20232, 0x2023a, 0x2023b, 0x2023d, 0x2023e, 0x20241, 0x20248, 0x2024a, - 0x2024c, 0x2024e, 0x20370, 0x20372, 0x20376, 0x2037f, 0x20386, 0x2038c, 0x2038e, - 0x2038f, 0x203cf, 0x203d8, 0x203da, 0x203dc, 0x203de, 0x203e0, 0x203e2, 0x203e4, - 0x203e6, 0x203e8, 0x203ea, 0x203ec, 0x203ee, 0x203f4, 0x203f7, 0x203f9, 0x203fa, - 0x20460, 0x20462, 0x20464, 0x20466, 0x20468, 0x2046a, 0x2046c, 0x2046e, 0x20470, - 0x20472, 0x20474, 0x20476, 0x20478, 0x2047a, 0x2047c, 0x2047e, 0x20480, 0x2048a, - 0x2048c, 0x2048e, 0x20490, 0x20492, 0x20494, 0x20496, 0x20498, 0x2049a, 0x2049c, - 0x2049e, 0x204a0, 0x204a2, 0x204a4, 0x204a6, 0x204a8, 0x204aa, 0x204ac, 0x204ae, - 0x204b0, 0x204b2, 0x204b4, 0x204b6, 0x204b8, 0x204ba, 0x204bc, 0x204be, 0x204c0, - 0x204c1, 0x204c3, 0x204c5, 0x204c7, 0x204c9, 0x204cb, 0x204cd, 0x204d0, 0x204d2, - 0x204d4, 0x204d6, 0x204d8, 0x204da, 0x204dc, 0x204de, 0x204e0, 0x204e2, 0x204e4, - 0x204e6, 0x204e8, 0x204ea, 0x204ec, 0x204ee, 0x204f0, 0x204f2, 0x204f4, 0x204f6, - 0x204f8, 0x204fa, 0x204fc, 0x204fe, 0x20500, 0x20502, 0x20504, 0x20506, 0x20508, - 0x2050a, 0x2050c, 0x2050e, 0x20510, 0x20512, 0x20514, 0x20516, 0x20518, 0x2051a, - 0x2051c, 0x2051e, 0x20520, 0x20522, 0x20524, 0x20526, 0x20528, 0x2052a, 0x2052c, - 0x2052e, 0x210c7, 0x210cd, 0x21e00, 0x21e02, 0x21e04, 0x21e06, 0x21e08, 0x21e0a, - 0x21e0c, 0x21e0e, 0x21e10, 0x21e12, 0x21e14, 0x21e16, 0x21e18, 0x21e1a, 0x21e1c, - 0x21e1e, 0x21e20, 0x21e22, 0x21e24, 0x21e26, 0x21e28, 0x21e2a, 0x21e2c, 0x21e2e, - 0x21e30, 0x21e32, 0x21e34, 0x21e36, 0x21e38, 0x21e3a, 0x21e3c, 0x21e3e, 0x21e40, - 0x21e42, 0x21e44, 0x21e46, 0x21e48, 0x21e4a, 0x21e4c, 0x21e4e, 0x21e50, 0x21e52, - 0x21e54, 0x21e56, 0x21e58, 0x21e5a, 0x21e5c, 0x21e5e, 0x21e60, 0x21e62, 0x21e64, - 0x21e66, 0x21e68, 0x21e6a, 0x21e6c, 0x21e6e, 0x21e70, 0x21e72, 0x21e74, 0x21e76, - 0x21e78, 0x21e7a, 0x21e7c, 0x21e7e, 0x21e80, 0x21e82, 0x21e84, 0x21e86, 0x21e88, - 0x21e8a, 0x21e8c, 0x21e8e, 0x21e90, 0x21e92, 0x21e94, 0x21e9e, 0x21ea0, 0x21ea2, - 0x21ea4, 0x21ea6, 0x21ea8, 0x21eaa, 0x21eac, 0x21eae, 0x21eb0, 0x21eb2, 0x21eb4, - 0x21eb6, 0x21eb8, 0x21eba, 0x21ebc, 0x21ebe, 0x21ec0, 0x21ec2, 0x21ec4, 0x21ec6, - 0x21ec8, 0x21eca, 0x21ecc, 0x21ece, 0x21ed0, 0x21ed2, 0x21ed4, 0x21ed6, 0x21ed8, - 0x21eda, 0x21edc, 0x21ede, 0x21ee0, 0x21ee2, 0x21ee4, 0x21ee6, 0x21ee8, 0x21eea, - 0x21eec, 0x21eee, 0x21ef0, 0x21ef2, 0x21ef4, 0x21ef6, 0x21ef8, 0x21efa, 0x21efc, - 0x21efe, 0x21f59, 0x21f5b, 0x21f5d, 0x21f5f, 0x22102, 0x22107, 0x22115, 0x22124, - 0x22126, 0x22128, 0x2213e, 0x2213f, 0x22145, 0x22183, 0x22c60, 0x22c67, 0x22c69, - 0x22c6b, 0x22c72, 0x22c75, 0x22c82, 0x22c84, 0x22c86, 0x22c88, 0x22c8a, 0x22c8c, - 0x22c8e, 0x22c90, 0x22c92, 0x22c94, 0x22c96, 0x22c98, 0x22c9a, 0x22c9c, 0x22c9e, - 0x22ca0, 0x22ca2, 0x22ca4, 0x22ca6, 0x22ca8, 0x22caa, 0x22cac, 0x22cae, 0x22cb0, - 0x22cb2, 0x22cb4, 0x22cb6, 0x22cb8, 0x22cba, 0x22cbc, 0x22cbe, 0x22cc0, 0x22cc2, - 0x22cc4, 0x22cc6, 0x22cc8, 0x22cca, 0x22ccc, 0x22cce, 0x22cd0, 0x22cd2, 0x22cd4, - 0x22cd6, 0x22cd8, 0x22cda, 0x22cdc, 0x22cde, 0x22ce0, 0x22ce2, 0x22ceb, 0x22ced, - 0x22cf2, 0x2a640, 0x2a642, 0x2a644, 0x2a646, 0x2a648, 0x2a64a, 0x2a64c, 0x2a64e, - 0x2a650, 0x2a652, 0x2a654, 0x2a656, 0x2a658, 0x2a65a, 0x2a65c, 0x2a65e, 0x2a660, - 0x2a662, 0x2a664, 0x2a666, 0x2a668, 0x2a66a, 0x2a66c, 0x2a680, 0x2a682, 0x2a684, - 0x2a686, 0x2a688, 0x2a68a, 0x2a68c, 0x2a68e, 0x2a690, 0x2a692, 0x2a694, 0x2a696, - 0x2a698, 0x2a69a, 0x2a722, 0x2a724, 0x2a726, 0x2a728, 0x2a72a, 0x2a72c, 0x2a72e, - 0x2a732, 0x2a734, 0x2a736, 0x2a738, 0x2a73a, 0x2a73c, 0x2a73e, 0x2a740, 0x2a742, - 0x2a744, 0x2a746, 0x2a748, 0x2a74a, 0x2a74c, 0x2a74e, 0x2a750, 0x2a752, 0x2a754, - 0x2a756, 0x2a758, 0x2a75a, 0x2a75c, 0x2a75e, 0x2a760, 0x2a762, 0x2a764, 0x2a766, - 0x2a768, 0x2a76a, 0x2a76c, 0x2a76e, 0x2a779, 0x2a77b, 0x2a77d, 0x2a77e, 0x2a780, - 0x2a782, 0x2a784, 0x2a786, 0x2a78b, 0x2a78d, 0x2a790, 0x2a792, 0x2a796, 0x2a798, - 0x2a79a, 0x2a79c, 0x2a79e, 0x2a7a0, 0x2a7a2, 0x2a7a4, 0x2a7a6, 0x2a7a8, 0x2a7b6, - 0x30100, 0x30102, 0x30104, 0x30106, 0x30108, 0x3010a, 0x3010c, 0x3010e, 0x30110, - 0x30112, 0x30114, 0x30116, 0x30118, 0x3011a, 0x3011c, 0x3011e, 0x30120, 0x30122, - 0x30124, 0x30126, 0x30128, 0x3012a, 0x3012c, 0x3012e, 0x30130, 0x30132, 0x30134, - 0x30136, 0x30139, 0x3013b, 0x3013d, 0x3013f, 0x30141, 0x30143, 0x30145, 0x30147, - 0x3014a, 0x3014c, 0x3014e, 0x30150, 0x30152, 0x30154, 0x30156, 0x30158, 0x3015a, - 0x3015c, 0x3015e, 0x30160, 0x30162, 0x30164, 0x30166, 0x30168, 0x3016a, 0x3016c, - 0x3016e, 0x30170, 0x30172, 0x30174, 0x30176, 0x30178, 0x30179, 0x3017b, 0x3017d, - 0x30181, 0x30182, 0x30184, 0x30186, 0x30187, 0x30193, 0x30194, 0x3019c, 0x3019d, - 0x3019f, 0x301a0, 0x301a2, 0x301a4, 0x301a6, 0x301a7, 0x301a9, 0x301ac, 0x301ae, - 0x301af, 0x301b5, 0x301b7, 0x301b8, 0x301bc, 0x301c4, 0x301c7, 0x301ca, 0x301cd, - 0x301cf, 0x301d1, 0x301d3, 0x301d5, 0x301d7, 0x301d9, 0x301db, 0x301de, 0x301e0, - 0x301e2, 0x301e4, 0x301e6, 0x301e8, 0x301ea, 0x301ec, 0x301ee, 0x301f1, 0x301f4, - 0x301fa, 0x301fc, 0x301fe, 0x30200, 0x30202, 0x30204, 0x30206, 0x30208, 0x3020a, - 0x3020c, 0x3020e, 0x30210, 0x30212, 0x30214, 0x30216, 0x30218, 0x3021a, 0x3021c, - 0x3021e, 0x30220, 0x30222, 0x30224, 0x30226, 0x30228, 0x3022a, 0x3022c, 0x3022e, - 0x30230, 0x30232, 0x3023a, 0x3023b, 0x3023d, 0x3023e, 0x30241, 0x30248, 0x3024a, - 0x3024c, 0x3024e, 0x30370, 0x30372, 0x30376, 0x3037f, 0x30386, 0x3038c, 0x3038e, - 0x3038f, 0x303cf, 0x303d8, 0x303da, 0x303dc, 0x303de, 0x303e0, 0x303e2, 0x303e4, - 0x303e6, 0x303e8, 0x303ea, 0x303ec, 0x303ee, 0x303f4, 0x303f7, 0x303f9, 0x303fa, - 0x30460, 0x30462, 0x30464, 0x30466, 0x30468, 0x3046a, 0x3046c, 0x3046e, 0x30470, - 0x30472, 0x30474, 0x30476, 0x30478, 0x3047a, 0x3047c, 0x3047e, 0x30480, 0x3048a, - 0x3048c, 0x3048e, 0x30490, 0x30492, 0x30494, 0x30496, 0x30498, 0x3049a, 0x3049c, - 0x3049e, 0x304a0, 0x304a2, 0x304a4, 0x304a6, 0x304a8, 0x304aa, 0x304ac, 0x304ae, - 0x304b0, 0x304b2, 0x304b4, 0x304b6, 0x304b8, 0x304ba, 0x304bc, 0x304be, 0x304c0, - 0x304c1, 0x304c3, 0x304c5, 0x304c7, 0x304c9, 0x304cb, 0x304cd, 0x304d0, 0x304d2, - 0x304d4, 0x304d6, 0x304d8, 0x304da, 0x304dc, 0x304de, 0x304e0, 0x304e2, 0x304e4, - 0x304e6, 0x304e8, 0x304ea, 0x304ec, 0x304ee, 0x304f0, 0x304f2, 0x304f4, 0x304f6, - 0x304f8, 0x304fa, 0x304fc, 0x304fe, 0x30500, 0x30502, 0x30504, 0x30506, 0x30508, - 0x3050a, 0x3050c, 0x3050e, 0x30510, 0x30512, 0x30514, 0x30516, 0x30518, 0x3051a, - 0x3051c, 0x3051e, 0x30520, 0x30522, 0x30524, 0x30526, 0x30528, 0x3052a, 0x3052c, - 0x3052e, 0x310c7, 0x310cd, 0x31e00, 0x31e02, 0x31e04, 0x31e06, 0x31e08, 0x31e0a, - 0x31e0c, 0x31e0e, 0x31e10, 0x31e12, 0x31e14, 0x31e16, 0x31e18, 0x31e1a, 0x31e1c, - 0x31e1e, 0x31e20, 0x31e22, 0x31e24, 0x31e26, 0x31e28, 0x31e2a, 0x31e2c, 0x31e2e, - 0x31e30, 0x31e32, 0x31e34, 0x31e36, 0x31e38, 0x31e3a, 0x31e3c, 0x31e3e, 0x31e40, - 0x31e42, 0x31e44, 0x31e46, 0x31e48, 0x31e4a, 0x31e4c, 0x31e4e, 0x31e50, 0x31e52, - 0x31e54, 0x31e56, 0x31e58, 0x31e5a, 0x31e5c, 0x31e5e, 0x31e60, 0x31e62, 0x31e64, - 0x31e66, 0x31e68, 0x31e6a, 0x31e6c, 0x31e6e, 0x31e70, 0x31e72, 0x31e74, 0x31e76, - 0x31e78, 0x31e7a, 0x31e7c, 0x31e7e, 0x31e80, 0x31e82, 0x31e84, 0x31e86, 0x31e88, - 0x31e8a, 0x31e8c, 0x31e8e, 0x31e90, 0x31e92, 0x31e94, 0x31e9e, 0x31ea0, 0x31ea2, - 0x31ea4, 0x31ea6, 0x31ea8, 0x31eaa, 0x31eac, 0x31eae, 0x31eb0, 0x31eb2, 0x31eb4, - 0x31eb6, 0x31eb8, 0x31eba, 0x31ebc, 0x31ebe, 0x31ec0, 0x31ec2, 0x31ec4, 0x31ec6, - 0x31ec8, 0x31eca, 0x31ecc, 0x31ece, 0x31ed0, 0x31ed2, 0x31ed4, 0x31ed6, 0x31ed8, - 0x31eda, 0x31edc, 0x31ede, 0x31ee0, 0x31ee2, 0x31ee4, 0x31ee6, 0x31ee8, 0x31eea, - 0x31eec, 0x31eee, 0x31ef0, 0x31ef2, 0x31ef4, 0x31ef6, 0x31ef8, 0x31efa, 0x31efc, - 0x31efe, 0x31f59, 0x31f5b, 0x31f5d, 0x31f5f, 0x32102, 0x32107, 0x32115, 0x32124, - 0x32126, 0x32128, 0x3213e, 0x3213f, 0x32145, 0x32183, 0x32c60, 0x32c67, 0x32c69, - 0x32c6b, 0x32c72, 0x32c75, 0x32c82, 0x32c84, 0x32c86, 0x32c88, 0x32c8a, 0x32c8c, - 0x32c8e, 0x32c90, 0x32c92, 0x32c94, 0x32c96, 0x32c98, 0x32c9a, 0x32c9c, 0x32c9e, - 0x32ca0, 0x32ca2, 0x32ca4, 0x32ca6, 0x32ca8, 0x32caa, 0x32cac, 0x32cae, 0x32cb0, - 0x32cb2, 0x32cb4, 0x32cb6, 0x32cb8, 0x32cba, 0x32cbc, 0x32cbe, 0x32cc0, 0x32cc2, - 0x32cc4, 0x32cc6, 0x32cc8, 0x32cca, 0x32ccc, 0x32cce, 0x32cd0, 0x32cd2, 0x32cd4, - 0x32cd6, 0x32cd8, 0x32cda, 0x32cdc, 0x32cde, 0x32ce0, 0x32ce2, 0x32ceb, 0x32ced, - 0x32cf2, 0x3a640, 0x3a642, 0x3a644, 0x3a646, 0x3a648, 0x3a64a, 0x3a64c, 0x3a64e, - 0x3a650, 0x3a652, 0x3a654, 0x3a656, 0x3a658, 0x3a65a, 0x3a65c, 0x3a65e, 0x3a660, - 0x3a662, 0x3a664, 0x3a666, 0x3a668, 0x3a66a, 0x3a66c, 0x3a680, 0x3a682, 0x3a684, - 0x3a686, 0x3a688, 0x3a68a, 0x3a68c, 0x3a68e, 0x3a690, 0x3a692, 0x3a694, 0x3a696, - 0x3a698, 0x3a69a, 0x3a722, 0x3a724, 0x3a726, 0x3a728, 0x3a72a, 0x3a72c, 0x3a72e, - 0x3a732, 0x3a734, 0x3a736, 0x3a738, 0x3a73a, 0x3a73c, 0x3a73e, 0x3a740, 0x3a742, - 0x3a744, 0x3a746, 0x3a748, 0x3a74a, 0x3a74c, 0x3a74e, 0x3a750, 0x3a752, 0x3a754, - 0x3a756, 0x3a758, 0x3a75a, 0x3a75c, 0x3a75e, 0x3a760, 0x3a762, 0x3a764, 0x3a766, - 0x3a768, 0x3a76a, 0x3a76c, 0x3a76e, 0x3a779, 0x3a77b, 0x3a77d, 0x3a77e, 0x3a780, - 0x3a782, 0x3a784, 0x3a786, 0x3a78b, 0x3a78d, 0x3a790, 0x3a792, 0x3a796, 0x3a798, - 0x3a79a, 0x3a79c, 0x3a79e, 0x3a7a0, 0x3a7a2, 0x3a7a4, 0x3a7a6, 0x3a7a8, 0x3a7b6, - 0x40100, 0x40102, 0x40104, 0x40106, 0x40108, 0x4010a, 0x4010c, 0x4010e, 0x40110, - 0x40112, 0x40114, 0x40116, 0x40118, 0x4011a, 0x4011c, 0x4011e, 0x40120, 0x40122, - 0x40124, 0x40126, 0x40128, 0x4012a, 0x4012c, 0x4012e, 0x40130, 0x40132, 0x40134, - 0x40136, 0x40139, 0x4013b, 0x4013d, 0x4013f, 0x40141, 0x40143, 0x40145, 0x40147, - 0x4014a, 0x4014c, 0x4014e, 0x40150, 0x40152, 0x40154, 0x40156, 0x40158, 0x4015a, - 0x4015c, 0x4015e, 0x40160, 0x40162, 0x40164, 0x40166, 0x40168, 0x4016a, 0x4016c, - 0x4016e, 0x40170, 0x40172, 0x40174, 0x40176, 0x40178, 0x40179, 0x4017b, 0x4017d, - 0x40181, 0x40182, 0x40184, 0x40186, 0x40187, 0x40193, 0x40194, 0x4019c, 0x4019d, - 0x4019f, 0x401a0, 0x401a2, 0x401a4, 0x401a6, 0x401a7, 0x401a9, 0x401ac, 0x401ae, - 0x401af, 0x401b5, 0x401b7, 0x401b8, 0x401bc, 0x401c4, 0x401c7, 0x401ca, 0x401cd, - 0x401cf, 0x401d1, 0x401d3, 0x401d5, 0x401d7, 0x401d9, 0x401db, 0x401de, 0x401e0, - 0x401e2, 0x401e4, 0x401e6, 0x401e8, 0x401ea, 0x401ec, 0x401ee, 0x401f1, 0x401f4, - 0x401fa, 0x401fc, 0x401fe, 0x40200, 0x40202, 0x40204, 0x40206, 0x40208, 0x4020a, - 0x4020c, 0x4020e, 0x40210, 0x40212, 0x40214, 0x40216, 0x40218, 0x4021a, 0x4021c, - 0x4021e, 0x40220, 0x40222, 0x40224, 0x40226, 0x40228, 0x4022a, 0x4022c, 0x4022e, - 0x40230, 0x40232, 0x4023a, 0x4023b, 0x4023d, 0x4023e, 0x40241, 0x40248, 0x4024a, - 0x4024c, 0x4024e, 0x40370, 0x40372, 0x40376, 0x4037f, 0x40386, 0x4038c, 0x4038e, - 0x4038f, 0x403cf, 0x403d8, 0x403da, 0x403dc, 0x403de, 0x403e0, 0x403e2, 0x403e4, - 0x403e6, 0x403e8, 0x403ea, 0x403ec, 0x403ee, 0x403f4, 0x403f7, 0x403f9, 0x403fa, - 0x40460, 0x40462, 0x40464, 0x40466, 0x40468, 0x4046a, 0x4046c, 0x4046e, 0x40470, - 0x40472, 0x40474, 0x40476, 0x40478, 0x4047a, 0x4047c, 0x4047e, 0x40480, 0x4048a, - 0x4048c, 0x4048e, 0x40490, 0x40492, 0x40494, 0x40496, 0x40498, 0x4049a, 0x4049c, - 0x4049e, 0x404a0, 0x404a2, 0x404a4, 0x404a6, 0x404a8, 0x404aa, 0x404ac, 0x404ae, - 0x404b0, 0x404b2, 0x404b4, 0x404b6, 0x404b8, 0x404ba, 0x404bc, 0x404be, 0x404c0, - 0x404c1, 0x404c3, 0x404c5, 0x404c7, 0x404c9, 0x404cb, 0x404cd, 0x404d0, 0x404d2, - 0x404d4, 0x404d6, 0x404d8, 0x404da, 0x404dc, 0x404de, 0x404e0, 0x404e2, 0x404e4, - 0x404e6, 0x404e8, 0x404ea, 0x404ec, 0x404ee, 0x404f0, 0x404f2, 0x404f4, 0x404f6, - 0x404f8, 0x404fa, 0x404fc, 0x404fe, 0x40500, 0x40502, 0x40504, 0x40506, 0x40508, - 0x4050a, 0x4050c, 0x4050e, 0x40510, 0x40512, 0x40514, 0x40516, 0x40518, 0x4051a, - 0x4051c, 0x4051e, 0x40520, 0x40522, 0x40524, 0x40526, 0x40528, 0x4052a, 0x4052c, - 0x4052e, 0x410c7, 0x410cd, 0x41e00, 0x41e02, 0x41e04, 0x41e06, 0x41e08, 0x41e0a, - 0x41e0c, 0x41e0e, 0x41e10, 0x41e12, 0x41e14, 0x41e16, 0x41e18, 0x41e1a, 0x41e1c, - 0x41e1e, 0x41e20, 0x41e22, 0x41e24, 0x41e26, 0x41e28, 0x41e2a, 0x41e2c, 0x41e2e, - 0x41e30, 0x41e32, 0x41e34, 0x41e36, 0x41e38, 0x41e3a, 0x41e3c, 0x41e3e, 0x41e40, - 0x41e42, 0x41e44, 0x41e46, 0x41e48, 0x41e4a, 0x41e4c, 0x41e4e, 0x41e50, 0x41e52, - 0x41e54, 0x41e56, 0x41e58, 0x41e5a, 0x41e5c, 0x41e5e, 0x41e60, 0x41e62, 0x41e64, - 0x41e66, 0x41e68, 0x41e6a, 0x41e6c, 0x41e6e, 0x41e70, 0x41e72, 0x41e74, 0x41e76, - 0x41e78, 0x41e7a, 0x41e7c, 0x41e7e, 0x41e80, 0x41e82, 0x41e84, 0x41e86, 0x41e88, - 0x41e8a, 0x41e8c, 0x41e8e, 0x41e90, 0x41e92, 0x41e94, 0x41e9e, 0x41ea0, 0x41ea2, - 0x41ea4, 0x41ea6, 0x41ea8, 0x41eaa, 0x41eac, 0x41eae, 0x41eb0, 0x41eb2, 0x41eb4, - 0x41eb6, 0x41eb8, 0x41eba, 0x41ebc, 0x41ebe, 0x41ec0, 0x41ec2, 0x41ec4, 0x41ec6, - 0x41ec8, 0x41eca, 0x41ecc, 0x41ece, 0x41ed0, 0x41ed2, 0x41ed4, 0x41ed6, 0x41ed8, - 0x41eda, 0x41edc, 0x41ede, 0x41ee0, 0x41ee2, 0x41ee4, 0x41ee6, 0x41ee8, 0x41eea, - 0x41eec, 0x41eee, 0x41ef0, 0x41ef2, 0x41ef4, 0x41ef6, 0x41ef8, 0x41efa, 0x41efc, - 0x41efe, 0x41f59, 0x41f5b, 0x41f5d, 0x41f5f, 0x42102, 0x42107, 0x42115, 0x42124, - 0x42126, 0x42128, 0x4213e, 0x4213f, 0x42145, 0x42183, 0x42c60, 0x42c67, 0x42c69, - 0x42c6b, 0x42c72, 0x42c75, 0x42c82, 0x42c84, 0x42c86, 0x42c88, 0x42c8a, 0x42c8c, - 0x42c8e, 0x42c90, 0x42c92, 0x42c94, 0x42c96, 0x42c98, 0x42c9a, 0x42c9c, 0x42c9e, - 0x42ca0, 0x42ca2, 0x42ca4, 0x42ca6, 0x42ca8, 0x42caa, 0x42cac, 0x42cae, 0x42cb0, - 0x42cb2, 0x42cb4, 0x42cb6, 0x42cb8, 0x42cba, 0x42cbc, 0x42cbe, 0x42cc0, 0x42cc2, - 0x42cc4, 0x42cc6, 0x42cc8, 0x42cca, 0x42ccc, 0x42cce, 0x42cd0, 0x42cd2, 0x42cd4, - 0x42cd6, 0x42cd8, 0x42cda, 0x42cdc, 0x42cde, 0x42ce0, 0x42ce2, 0x42ceb, 0x42ced, - 0x42cf2, 0x4a640, 0x4a642, 0x4a644, 0x4a646, 0x4a648, 0x4a64a, 0x4a64c, 0x4a64e, - 0x4a650, 0x4a652, 0x4a654, 0x4a656, 0x4a658, 0x4a65a, 0x4a65c, 0x4a65e, 0x4a660, - 0x4a662, 0x4a664, 0x4a666, 0x4a668, 0x4a66a, 0x4a66c, 0x4a680, 0x4a682, 0x4a684, - 0x4a686, 0x4a688, 0x4a68a, 0x4a68c, 0x4a68e, 0x4a690, 0x4a692, 0x4a694, 0x4a696, - 0x4a698, 0x4a69a, 0x4a722, 0x4a724, 0x4a726, 0x4a728, 0x4a72a, 0x4a72c, 0x4a72e, - 0x4a732, 0x4a734, 0x4a736, 0x4a738, 0x4a73a, 0x4a73c, 0x4a73e, 0x4a740, 0x4a742, - 0x4a744, 0x4a746, 0x4a748, 0x4a74a, 0x4a74c, 0x4a74e, 0x4a750, 0x4a752, 0x4a754, - 0x4a756, 0x4a758, 0x4a75a, 0x4a75c, 0x4a75e, 0x4a760, 0x4a762, 0x4a764, 0x4a766, - 0x4a768, 0x4a76a, 0x4a76c, 0x4a76e, 0x4a779, 0x4a77b, 0x4a77d, 0x4a77e, 0x4a780, - 0x4a782, 0x4a784, 0x4a786, 0x4a78b, 0x4a78d, 0x4a790, 0x4a792, 0x4a796, 0x4a798, - 0x4a79a, 0x4a79c, 0x4a79e, 0x4a7a0, 0x4a7a2, 0x4a7a4, 0x4a7a6, 0x4a7a8, 0x4a7b6, - 0x50100, 0x50102, 0x50104, 0x50106, 0x50108, 0x5010a, 0x5010c, 0x5010e, 0x50110, - 0x50112, 0x50114, 0x50116, 0x50118, 0x5011a, 0x5011c, 0x5011e, 0x50120, 0x50122, - 0x50124, 0x50126, 0x50128, 0x5012a, 0x5012c, 0x5012e, 0x50130, 0x50132, 0x50134, - 0x50136, 0x50139, 0x5013b, 0x5013d, 0x5013f, 0x50141, 0x50143, 0x50145, 0x50147, - 0x5014a, 0x5014c, 0x5014e, 0x50150, 0x50152, 0x50154, 0x50156, 0x50158, 0x5015a, - 0x5015c, 0x5015e, 0x50160, 0x50162, 0x50164, 0x50166, 0x50168, 0x5016a, 0x5016c, - 0x5016e, 0x50170, 0x50172, 0x50174, 0x50176, 0x50178, 0x50179, 0x5017b, 0x5017d, - 0x50181, 0x50182, 0x50184, 0x50186, 0x50187, 0x50193, 0x50194, 0x5019c, 0x5019d, - 0x5019f, 0x501a0, 0x501a2, 0x501a4, 0x501a6, 0x501a7, 0x501a9, 0x501ac, 0x501ae, - 0x501af, 0x501b5, 0x501b7, 0x501b8, 0x501bc, 0x501c4, 0x501c7, 0x501ca, 0x501cd, - 0x501cf, 0x501d1, 0x501d3, 0x501d5, 0x501d7, 0x501d9, 0x501db, 0x501de, 0x501e0, - 0x501e2, 0x501e4, 0x501e6, 0x501e8, 0x501ea, 0x501ec, 0x501ee, 0x501f1, 0x501f4, - 0x501fa, 0x501fc, 0x501fe, 0x50200, 0x50202, 0x50204, 0x50206, 0x50208, 0x5020a, - 0x5020c, 0x5020e, 0x50210, 0x50212, 0x50214, 0x50216, 0x50218, 0x5021a, 0x5021c, - 0x5021e, 0x50220, 0x50222, 0x50224, 0x50226, 0x50228, 0x5022a, 0x5022c, 0x5022e, - 0x50230, 0x50232, 0x5023a, 0x5023b, 0x5023d, 0x5023e, 0x50241, 0x50248, 0x5024a, - 0x5024c, 0x5024e, 0x50370, 0x50372, 0x50376, 0x5037f, 0x50386, 0x5038c, 0x5038e, - 0x5038f, 0x503cf, 0x503d8, 0x503da, 0x503dc, 0x503de, 0x503e0, 0x503e2, 0x503e4, - 0x503e6, 0x503e8, 0x503ea, 0x503ec, 0x503ee, 0x503f4, 0x503f7, 0x503f9, 0x503fa, - 0x50460, 0x50462, 0x50464, 0x50466, 0x50468, 0x5046a, 0x5046c, 0x5046e, 0x50470, - 0x50472, 0x50474, 0x50476, 0x50478, 0x5047a, 0x5047c, 0x5047e, 0x50480, 0x5048a, - 0x5048c, 0x5048e, 0x50490, 0x50492, 0x50494, 0x50496, 0x50498, 0x5049a, 0x5049c, - 0x5049e, 0x504a0, 0x504a2, 0x504a4, 0x504a6, 0x504a8, 0x504aa, 0x504ac, 0x504ae, - 0x504b0, 0x504b2, 0x504b4, 0x504b6, 0x504b8, 0x504ba, 0x504bc, 0x504be, 0x504c0, - 0x504c1, 0x504c3, 0x504c5, 0x504c7, 0x504c9, 0x504cb, 0x504cd, 0x504d0, 0x504d2, - 0x504d4, 0x504d6, 0x504d8, 0x504da, 0x504dc, 0x504de, 0x504e0, 0x504e2, 0x504e4, - 0x504e6, 0x504e8, 0x504ea, 0x504ec, 0x504ee, 0x504f0, 0x504f2, 0x504f4, 0x504f6, - 0x504f8, 0x504fa, 0x504fc, 0x504fe, 0x50500, 0x50502, 0x50504, 0x50506, 0x50508, - 0x5050a, 0x5050c, 0x5050e, 0x50510, 0x50512, 0x50514, 0x50516, 0x50518, 0x5051a, - 0x5051c, 0x5051e, 0x50520, 0x50522, 0x50524, 0x50526, 0x50528, 0x5052a, 0x5052c, - 0x5052e, 0x510c7, 0x510cd, 0x51e00, 0x51e02, 0x51e04, 0x51e06, 0x51e08, 0x51e0a, - 0x51e0c, 0x51e0e, 0x51e10, 0x51e12, 0x51e14, 0x51e16, 0x51e18, 0x51e1a, 0x51e1c, - 0x51e1e, 0x51e20, 0x51e22, 0x51e24, 0x51e26, 0x51e28, 0x51e2a, 0x51e2c, 0x51e2e, - 0x51e30, 0x51e32, 0x51e34, 0x51e36, 0x51e38, 0x51e3a, 0x51e3c, 0x51e3e, 0x51e40, - 0x51e42, 0x51e44, 0x51e46, 0x51e48, 0x51e4a, 0x51e4c, 0x51e4e, 0x51e50, 0x51e52, - 0x51e54, 0x51e56, 0x51e58, 0x51e5a, 0x51e5c, 0x51e5e, 0x51e60, 0x51e62, 0x51e64, - 0x51e66, 0x51e68, 0x51e6a, 0x51e6c, 0x51e6e, 0x51e70, 0x51e72, 0x51e74, 0x51e76, - 0x51e78, 0x51e7a, 0x51e7c, 0x51e7e, 0x51e80, 0x51e82, 0x51e84, 0x51e86, 0x51e88, - 0x51e8a, 0x51e8c, 0x51e8e, 0x51e90, 0x51e92, 0x51e94, 0x51e9e, 0x51ea0, 0x51ea2, - 0x51ea4, 0x51ea6, 0x51ea8, 0x51eaa, 0x51eac, 0x51eae, 0x51eb0, 0x51eb2, 0x51eb4, - 0x51eb6, 0x51eb8, 0x51eba, 0x51ebc, 0x51ebe, 0x51ec0, 0x51ec2, 0x51ec4, 0x51ec6, - 0x51ec8, 0x51eca, 0x51ecc, 0x51ece, 0x51ed0, 0x51ed2, 0x51ed4, 0x51ed6, 0x51ed8, - 0x51eda, 0x51edc, 0x51ede, 0x51ee0, 0x51ee2, 0x51ee4, 0x51ee6, 0x51ee8, 0x51eea, - 0x51eec, 0x51eee, 0x51ef0, 0x51ef2, 0x51ef4, 0x51ef6, 0x51ef8, 0x51efa, 0x51efc, - 0x51efe, 0x51f59, 0x51f5b, 0x51f5d, 0x51f5f, 0x52102, 0x52107, 0x52115, 0x52124, - 0x52126, 0x52128, 0x5213e, 0x5213f, 0x52145, 0x52183, 0x52c60, 0x52c67, 0x52c69, - 0x52c6b, 0x52c72, 0x52c75, 0x52c82, 0x52c84, 0x52c86, 0x52c88, 0x52c8a, 0x52c8c, - 0x52c8e, 0x52c90, 0x52c92, 0x52c94, 0x52c96, 0x52c98, 0x52c9a, 0x52c9c, 0x52c9e, - 0x52ca0, 0x52ca2, 0x52ca4, 0x52ca6, 0x52ca8, 0x52caa, 0x52cac, 0x52cae, 0x52cb0, - 0x52cb2, 0x52cb4, 0x52cb6, 0x52cb8, 0x52cba, 0x52cbc, 0x52cbe, 0x52cc0, 0x52cc2, - 0x52cc4, 0x52cc6, 0x52cc8, 0x52cca, 0x52ccc, 0x52cce, 0x52cd0, 0x52cd2, 0x52cd4, - 0x52cd6, 0x52cd8, 0x52cda, 0x52cdc, 0x52cde, 0x52ce0, 0x52ce2, 0x52ceb, 0x52ced, - 0x52cf2, 0x5a640, 0x5a642, 0x5a644, 0x5a646, 0x5a648, 0x5a64a, 0x5a64c, 0x5a64e, - 0x5a650, 0x5a652, 0x5a654, 0x5a656, 0x5a658, 0x5a65a, 0x5a65c, 0x5a65e, 0x5a660, - 0x5a662, 0x5a664, 0x5a666, 0x5a668, 0x5a66a, 0x5a66c, 0x5a680, 0x5a682, 0x5a684, - 0x5a686, 0x5a688, 0x5a68a, 0x5a68c, 0x5a68e, 0x5a690, 0x5a692, 0x5a694, 0x5a696, - 0x5a698, 0x5a69a, 0x5a722, 0x5a724, 0x5a726, 0x5a728, 0x5a72a, 0x5a72c, 0x5a72e, - 0x5a732, 0x5a734, 0x5a736, 0x5a738, 0x5a73a, 0x5a73c, 0x5a73e, 0x5a740, 0x5a742, - 0x5a744, 0x5a746, 0x5a748, 0x5a74a, 0x5a74c, 0x5a74e, 0x5a750, 0x5a752, 0x5a754, - 0x5a756, 0x5a758, 0x5a75a, 0x5a75c, 0x5a75e, 0x5a760, 0x5a762, 0x5a764, 0x5a766, - 0x5a768, 0x5a76a, 0x5a76c, 0x5a76e, 0x5a779, 0x5a77b, 0x5a77d, 0x5a77e, 0x5a780, - 0x5a782, 0x5a784, 0x5a786, 0x5a78b, 0x5a78d, 0x5a790, 0x5a792, 0x5a796, 0x5a798, - 0x5a79a, 0x5a79c, 0x5a79e, 0x5a7a0, 0x5a7a2, 0x5a7a4, 0x5a7a6, 0x5a7a8, 0x5a7b6, - 0x60100, 0x60102, 0x60104, 0x60106, 0x60108, 0x6010a, 0x6010c, 0x6010e, 0x60110, - 0x60112, 0x60114, 0x60116, 0x60118, 0x6011a, 0x6011c, 0x6011e, 0x60120, 0x60122, - 0x60124, 0x60126, 0x60128, 0x6012a, 0x6012c, 0x6012e, 0x60130, 0x60132, 0x60134, - 0x60136, 0x60139, 0x6013b, 0x6013d, 0x6013f, 0x60141, 0x60143, 0x60145, 0x60147, - 0x6014a, 0x6014c, 0x6014e, 0x60150, 0x60152, 0x60154, 0x60156, 0x60158, 0x6015a, - 0x6015c, 0x6015e, 0x60160, 0x60162, 0x60164, 0x60166, 0x60168, 0x6016a, 0x6016c, - 0x6016e, 0x60170, 0x60172, 0x60174, 0x60176, 0x60178, 0x60179, 0x6017b, 0x6017d, - 0x60181, 0x60182, 0x60184, 0x60186, 0x60187, 0x60193, 0x60194, 0x6019c, 0x6019d, - 0x6019f, 0x601a0, 0x601a2, 0x601a4, 0x601a6, 0x601a7, 0x601a9, 0x601ac, 0x601ae, - 0x601af, 0x601b5, 0x601b7, 0x601b8, 0x601bc, 0x601c4, 0x601c7, 0x601ca, 0x601cd, - 0x601cf, 0x601d1, 0x601d3, 0x601d5, 0x601d7, 0x601d9, 0x601db, 0x601de, 0x601e0, - 0x601e2, 0x601e4, 0x601e6, 0x601e8, 0x601ea, 0x601ec, 0x601ee, 0x601f1, 0x601f4, - 0x601fa, 0x601fc, 0x601fe, 0x60200, 0x60202, 0x60204, 0x60206, 0x60208, 0x6020a, - 0x6020c, 0x6020e, 0x60210, 0x60212, 0x60214, 0x60216, 0x60218, 0x6021a, 0x6021c, - 0x6021e, 0x60220, 0x60222, 0x60224, 0x60226, 0x60228, 0x6022a, 0x6022c, 0x6022e, - 0x60230, 0x60232, 0x6023a, 0x6023b, 0x6023d, 0x6023e, 0x60241, 0x60248, 0x6024a, - 0x6024c, 0x6024e, 0x60370, 0x60372, 0x60376, 0x6037f, 0x60386, 0x6038c, 0x6038e, - 0x6038f, 0x603cf, 0x603d8, 0x603da, 0x603dc, 0x603de, 0x603e0, 0x603e2, 0x603e4, - 0x603e6, 0x603e8, 0x603ea, 0x603ec, 0x603ee, 0x603f4, 0x603f7, 0x603f9, 0x603fa, - 0x60460, 0x60462, 0x60464, 0x60466, 0x60468, 0x6046a, 0x6046c, 0x6046e, 0x60470, - 0x60472, 0x60474, 0x60476, 0x60478, 0x6047a, 0x6047c, 0x6047e, 0x60480, 0x6048a, - 0x6048c, 0x6048e, 0x60490, 0x60492, 0x60494, 0x60496, 0x60498, 0x6049a, 0x6049c, - 0x6049e, 0x604a0, 0x604a2, 0x604a4, 0x604a6, 0x604a8, 0x604aa, 0x604ac, 0x604ae, - 0x604b0, 0x604b2, 0x604b4, 0x604b6, 0x604b8, 0x604ba, 0x604bc, 0x604be, 0x604c0, - 0x604c1, 0x604c3, 0x604c5, 0x604c7, 0x604c9, 0x604cb, 0x604cd, 0x604d0, 0x604d2, - 0x604d4, 0x604d6, 0x604d8, 0x604da, 0x604dc, 0x604de, 0x604e0, 0x604e2, 0x604e4, - 0x604e6, 0x604e8, 0x604ea, 0x604ec, 0x604ee, 0x604f0, 0x604f2, 0x604f4, 0x604f6, - 0x604f8, 0x604fa, 0x604fc, 0x604fe, 0x60500, 0x60502, 0x60504, 0x60506, 0x60508, - 0x6050a, 0x6050c, 0x6050e, 0x60510, 0x60512, 0x60514, 0x60516, 0x60518, 0x6051a, - 0x6051c, 0x6051e, 0x60520, 0x60522, 0x60524, 0x60526, 0x60528, 0x6052a, 0x6052c, - 0x6052e, 0x610c7, 0x610cd, 0x61e00, 0x61e02, 0x61e04, 0x61e06, 0x61e08, 0x61e0a, - 0x61e0c, 0x61e0e, 0x61e10, 0x61e12, 0x61e14, 0x61e16, 0x61e18, 0x61e1a, 0x61e1c, - 0x61e1e, 0x61e20, 0x61e22, 0x61e24, 0x61e26, 0x61e28, 0x61e2a, 0x61e2c, 0x61e2e, - 0x61e30, 0x61e32, 0x61e34, 0x61e36, 0x61e38, 0x61e3a, 0x61e3c, 0x61e3e, 0x61e40, - 0x61e42, 0x61e44, 0x61e46, 0x61e48, 0x61e4a, 0x61e4c, 0x61e4e, 0x61e50, 0x61e52, - 0x61e54, 0x61e56, 0x61e58, 0x61e5a, 0x61e5c, 0x61e5e, 0x61e60, 0x61e62, 0x61e64, - 0x61e66, 0x61e68, 0x61e6a, 0x61e6c, 0x61e6e, 0x61e70, 0x61e72, 0x61e74, 0x61e76, - 0x61e78, 0x61e7a, 0x61e7c, 0x61e7e, 0x61e80, 0x61e82, 0x61e84, 0x61e86, 0x61e88, - 0x61e8a, 0x61e8c, 0x61e8e, 0x61e90, 0x61e92, 0x61e94, 0x61e9e, 0x61ea0, 0x61ea2, - 0x61ea4, 0x61ea6, 0x61ea8, 0x61eaa, 0x61eac, 0x61eae, 0x61eb0, 0x61eb2, 0x61eb4, - 0x61eb6, 0x61eb8, 0x61eba, 0x61ebc, 0x61ebe, 0x61ec0, 0x61ec2, 0x61ec4, 0x61ec6, - 0x61ec8, 0x61eca, 0x61ecc, 0x61ece, 0x61ed0, 0x61ed2, 0x61ed4, 0x61ed6, 0x61ed8, - 0x61eda, 0x61edc, 0x61ede, 0x61ee0, 0x61ee2, 0x61ee4, 0x61ee6, 0x61ee8, 0x61eea, - 0x61eec, 0x61eee, 0x61ef0, 0x61ef2, 0x61ef4, 0x61ef6, 0x61ef8, 0x61efa, 0x61efc, - 0x61efe, 0x61f59, 0x61f5b, 0x61f5d, 0x61f5f, 0x62102, 0x62107, 0x62115, 0x62124, - 0x62126, 0x62128, 0x6213e, 0x6213f, 0x62145, 0x62183, 0x62c60, 0x62c67, 0x62c69, - 0x62c6b, 0x62c72, 0x62c75, 0x62c82, 0x62c84, 0x62c86, 0x62c88, 0x62c8a, 0x62c8c, - 0x62c8e, 0x62c90, 0x62c92, 0x62c94, 0x62c96, 0x62c98, 0x62c9a, 0x62c9c, 0x62c9e, - 0x62ca0, 0x62ca2, 0x62ca4, 0x62ca6, 0x62ca8, 0x62caa, 0x62cac, 0x62cae, 0x62cb0, - 0x62cb2, 0x62cb4, 0x62cb6, 0x62cb8, 0x62cba, 0x62cbc, 0x62cbe, 0x62cc0, 0x62cc2, - 0x62cc4, 0x62cc6, 0x62cc8, 0x62cca, 0x62ccc, 0x62cce, 0x62cd0, 0x62cd2, 0x62cd4, - 0x62cd6, 0x62cd8, 0x62cda, 0x62cdc, 0x62cde, 0x62ce0, 0x62ce2, 0x62ceb, 0x62ced, - 0x62cf2, 0x6a640, 0x6a642, 0x6a644, 0x6a646, 0x6a648, 0x6a64a, 0x6a64c, 0x6a64e, - 0x6a650, 0x6a652, 0x6a654, 0x6a656, 0x6a658, 0x6a65a, 0x6a65c, 0x6a65e, 0x6a660, - 0x6a662, 0x6a664, 0x6a666, 0x6a668, 0x6a66a, 0x6a66c, 0x6a680, 0x6a682, 0x6a684, - 0x6a686, 0x6a688, 0x6a68a, 0x6a68c, 0x6a68e, 0x6a690, 0x6a692, 0x6a694, 0x6a696, - 0x6a698, 0x6a69a, 0x6a722, 0x6a724, 0x6a726, 0x6a728, 0x6a72a, 0x6a72c, 0x6a72e, - 0x6a732, 0x6a734, 0x6a736, 0x6a738, 0x6a73a, 0x6a73c, 0x6a73e, 0x6a740, 0x6a742, - 0x6a744, 0x6a746, 0x6a748, 0x6a74a, 0x6a74c, 0x6a74e, 0x6a750, 0x6a752, 0x6a754, - 0x6a756, 0x6a758, 0x6a75a, 0x6a75c, 0x6a75e, 0x6a760, 0x6a762, 0x6a764, 0x6a766, - 0x6a768, 0x6a76a, 0x6a76c, 0x6a76e, 0x6a779, 0x6a77b, 0x6a77d, 0x6a77e, 0x6a780, - 0x6a782, 0x6a784, 0x6a786, 0x6a78b, 0x6a78d, 0x6a790, 0x6a792, 0x6a796, 0x6a798, - 0x6a79a, 0x6a79c, 0x6a79e, 0x6a7a0, 0x6a7a2, 0x6a7a4, 0x6a7a6, 0x6a7a8, 0x6a7b6, - 0x70100, 0x70102, 0x70104, 0x70106, 0x70108, 0x7010a, 0x7010c, 0x7010e, 0x70110, - 0x70112, 0x70114, 0x70116, 0x70118, 0x7011a, 0x7011c, 0x7011e, 0x70120, 0x70122, - 0x70124, 0x70126, 0x70128, 0x7012a, 0x7012c, 0x7012e, 0x70130, 0x70132, 0x70134, - 0x70136, 0x70139, 0x7013b, 0x7013d, 0x7013f, 0x70141, 0x70143, 0x70145, 0x70147, - 0x7014a, 0x7014c, 0x7014e, 0x70150, 0x70152, 0x70154, 0x70156, 0x70158, 0x7015a, - 0x7015c, 0x7015e, 0x70160, 0x70162, 0x70164, 0x70166, 0x70168, 0x7016a, 0x7016c, - 0x7016e, 0x70170, 0x70172, 0x70174, 0x70176, 0x70178, 0x70179, 0x7017b, 0x7017d, - 0x70181, 0x70182, 0x70184, 0x70186, 0x70187, 0x70193, 0x70194, 0x7019c, 0x7019d, - 0x7019f, 0x701a0, 0x701a2, 0x701a4, 0x701a6, 0x701a7, 0x701a9, 0x701ac, 0x701ae, - 0x701af, 0x701b5, 0x701b7, 0x701b8, 0x701bc, 0x701c4, 0x701c7, 0x701ca, 0x701cd, - 0x701cf, 0x701d1, 0x701d3, 0x701d5, 0x701d7, 0x701d9, 0x701db, 0x701de, 0x701e0, - 0x701e2, 0x701e4, 0x701e6, 0x701e8, 0x701ea, 0x701ec, 0x701ee, 0x701f1, 0x701f4, - 0x701fa, 0x701fc, 0x701fe, 0x70200, 0x70202, 0x70204, 0x70206, 0x70208, 0x7020a, - 0x7020c, 0x7020e, 0x70210, 0x70212, 0x70214, 0x70216, 0x70218, 0x7021a, 0x7021c, - 0x7021e, 0x70220, 0x70222, 0x70224, 0x70226, 0x70228, 0x7022a, 0x7022c, 0x7022e, - 0x70230, 0x70232, 0x7023a, 0x7023b, 0x7023d, 0x7023e, 0x70241, 0x70248, 0x7024a, - 0x7024c, 0x7024e, 0x70370, 0x70372, 0x70376, 0x7037f, 0x70386, 0x7038c, 0x7038e, - 0x7038f, 0x703cf, 0x703d8, 0x703da, 0x703dc, 0x703de, 0x703e0, 0x703e2, 0x703e4, - 0x703e6, 0x703e8, 0x703ea, 0x703ec, 0x703ee, 0x703f4, 0x703f7, 0x703f9, 0x703fa, - 0x70460, 0x70462, 0x70464, 0x70466, 0x70468, 0x7046a, 0x7046c, 0x7046e, 0x70470, - 0x70472, 0x70474, 0x70476, 0x70478, 0x7047a, 0x7047c, 0x7047e, 0x70480, 0x7048a, - 0x7048c, 0x7048e, 0x70490, 0x70492, 0x70494, 0x70496, 0x70498, 0x7049a, 0x7049c, - 0x7049e, 0x704a0, 0x704a2, 0x704a4, 0x704a6, 0x704a8, 0x704aa, 0x704ac, 0x704ae, - 0x704b0, 0x704b2, 0x704b4, 0x704b6, 0x704b8, 0x704ba, 0x704bc, 0x704be, 0x704c0, - 0x704c1, 0x704c3, 0x704c5, 0x704c7, 0x704c9, 0x704cb, 0x704cd, 0x704d0, 0x704d2, - 0x704d4, 0x704d6, 0x704d8, 0x704da, 0x704dc, 0x704de, 0x704e0, 0x704e2, 0x704e4, - 0x704e6, 0x704e8, 0x704ea, 0x704ec, 0x704ee, 0x704f0, 0x704f2, 0x704f4, 0x704f6, - 0x704f8, 0x704fa, 0x704fc, 0x704fe, 0x70500, 0x70502, 0x70504, 0x70506, 0x70508, - 0x7050a, 0x7050c, 0x7050e, 0x70510, 0x70512, 0x70514, 0x70516, 0x70518, 0x7051a, - 0x7051c, 0x7051e, 0x70520, 0x70522, 0x70524, 0x70526, 0x70528, 0x7052a, 0x7052c, - 0x7052e, 0x710c7, 0x710cd, 0x71e00, 0x71e02, 0x71e04, 0x71e06, 0x71e08, 0x71e0a, - 0x71e0c, 0x71e0e, 0x71e10, 0x71e12, 0x71e14, 0x71e16, 0x71e18, 0x71e1a, 0x71e1c, - 0x71e1e, 0x71e20, 0x71e22, 0x71e24, 0x71e26, 0x71e28, 0x71e2a, 0x71e2c, 0x71e2e, - 0x71e30, 0x71e32, 0x71e34, 0x71e36, 0x71e38, 0x71e3a, 0x71e3c, 0x71e3e, 0x71e40, - 0x71e42, 0x71e44, 0x71e46, 0x71e48, 0x71e4a, 0x71e4c, 0x71e4e, 0x71e50, 0x71e52, - 0x71e54, 0x71e56, 0x71e58, 0x71e5a, 0x71e5c, 0x71e5e, 0x71e60, 0x71e62, 0x71e64, - 0x71e66, 0x71e68, 0x71e6a, 0x71e6c, 0x71e6e, 0x71e70, 0x71e72, 0x71e74, 0x71e76, - 0x71e78, 0x71e7a, 0x71e7c, 0x71e7e, 0x71e80, 0x71e82, 0x71e84, 0x71e86, 0x71e88, - 0x71e8a, 0x71e8c, 0x71e8e, 0x71e90, 0x71e92, 0x71e94, 0x71e9e, 0x71ea0, 0x71ea2, - 0x71ea4, 0x71ea6, 0x71ea8, 0x71eaa, 0x71eac, 0x71eae, 0x71eb0, 0x71eb2, 0x71eb4, - 0x71eb6, 0x71eb8, 0x71eba, 0x71ebc, 0x71ebe, 0x71ec0, 0x71ec2, 0x71ec4, 0x71ec6, - 0x71ec8, 0x71eca, 0x71ecc, 0x71ece, 0x71ed0, 0x71ed2, 0x71ed4, 0x71ed6, 0x71ed8, - 0x71eda, 0x71edc, 0x71ede, 0x71ee0, 0x71ee2, 0x71ee4, 0x71ee6, 0x71ee8, 0x71eea, - 0x71eec, 0x71eee, 0x71ef0, 0x71ef2, 0x71ef4, 0x71ef6, 0x71ef8, 0x71efa, 0x71efc, - 0x71efe, 0x71f59, 0x71f5b, 0x71f5d, 0x71f5f, 0x72102, 0x72107, 0x72115, 0x72124, - 0x72126, 0x72128, 0x7213e, 0x7213f, 0x72145, 0x72183, 0x72c60, 0x72c67, 0x72c69, - 0x72c6b, 0x72c72, 0x72c75, 0x72c82, 0x72c84, 0x72c86, 0x72c88, 0x72c8a, 0x72c8c, - 0x72c8e, 0x72c90, 0x72c92, 0x72c94, 0x72c96, 0x72c98, 0x72c9a, 0x72c9c, 0x72c9e, - 0x72ca0, 0x72ca2, 0x72ca4, 0x72ca6, 0x72ca8, 0x72caa, 0x72cac, 0x72cae, 0x72cb0, - 0x72cb2, 0x72cb4, 0x72cb6, 0x72cb8, 0x72cba, 0x72cbc, 0x72cbe, 0x72cc0, 0x72cc2, - 0x72cc4, 0x72cc6, 0x72cc8, 0x72cca, 0x72ccc, 0x72cce, 0x72cd0, 0x72cd2, 0x72cd4, - 0x72cd6, 0x72cd8, 0x72cda, 0x72cdc, 0x72cde, 0x72ce0, 0x72ce2, 0x72ceb, 0x72ced, - 0x72cf2, 0x7a640, 0x7a642, 0x7a644, 0x7a646, 0x7a648, 0x7a64a, 0x7a64c, 0x7a64e, - 0x7a650, 0x7a652, 0x7a654, 0x7a656, 0x7a658, 0x7a65a, 0x7a65c, 0x7a65e, 0x7a660, - 0x7a662, 0x7a664, 0x7a666, 0x7a668, 0x7a66a, 0x7a66c, 0x7a680, 0x7a682, 0x7a684, - 0x7a686, 0x7a688, 0x7a68a, 0x7a68c, 0x7a68e, 0x7a690, 0x7a692, 0x7a694, 0x7a696, - 0x7a698, 0x7a69a, 0x7a722, 0x7a724, 0x7a726, 0x7a728, 0x7a72a, 0x7a72c, 0x7a72e, - 0x7a732, 0x7a734, 0x7a736, 0x7a738, 0x7a73a, 0x7a73c, 0x7a73e, 0x7a740, 0x7a742, - 0x7a744, 0x7a746, 0x7a748, 0x7a74a, 0x7a74c, 0x7a74e, 0x7a750, 0x7a752, 0x7a754, - 0x7a756, 0x7a758, 0x7a75a, 0x7a75c, 0x7a75e, 0x7a760, 0x7a762, 0x7a764, 0x7a766, - 0x7a768, 0x7a76a, 0x7a76c, 0x7a76e, 0x7a779, 0x7a77b, 0x7a77d, 0x7a77e, 0x7a780, - 0x7a782, 0x7a784, 0x7a786, 0x7a78b, 0x7a78d, 0x7a790, 0x7a792, 0x7a796, 0x7a798, - 0x7a79a, 0x7a79c, 0x7a79e, 0x7a7a0, 0x7a7a2, 0x7a7a4, 0x7a7a6, 0x7a7a8, 0x7a7b6, - 0x80100, 0x80102, 0x80104, 0x80106, 0x80108, 0x8010a, 0x8010c, 0x8010e, 0x80110, - 0x80112, 0x80114, 0x80116, 0x80118, 0x8011a, 0x8011c, 0x8011e, 0x80120, 0x80122, - 0x80124, 0x80126, 0x80128, 0x8012a, 0x8012c, 0x8012e, 0x80130, 0x80132, 0x80134, - 0x80136, 0x80139, 0x8013b, 0x8013d, 0x8013f, 0x80141, 0x80143, 0x80145, 0x80147, - 0x8014a, 0x8014c, 0x8014e, 0x80150, 0x80152, 0x80154, 0x80156, 0x80158, 0x8015a, - 0x8015c, 0x8015e, 0x80160, 0x80162, 0x80164, 0x80166, 0x80168, 0x8016a, 0x8016c, - 0x8016e, 0x80170, 0x80172, 0x80174, 0x80176, 0x80178, 0x80179, 0x8017b, 0x8017d, - 0x80181, 0x80182, 0x80184, 0x80186, 0x80187, 0x80193, 0x80194, 0x8019c, 0x8019d, - 0x8019f, 0x801a0, 0x801a2, 0x801a4, 0x801a6, 0x801a7, 0x801a9, 0x801ac, 0x801ae, - 0x801af, 0x801b5, 0x801b7, 0x801b8, 0x801bc, 0x801c4, 0x801c7, 0x801ca, 0x801cd, - 0x801cf, 0x801d1, 0x801d3, 0x801d5, 0x801d7, 0x801d9, 0x801db, 0x801de, 0x801e0, - 0x801e2, 0x801e4, 0x801e6, 0x801e8, 0x801ea, 0x801ec, 0x801ee, 0x801f1, 0x801f4, - 0x801fa, 0x801fc, 0x801fe, 0x80200, 0x80202, 0x80204, 0x80206, 0x80208, 0x8020a, - 0x8020c, 0x8020e, 0x80210, 0x80212, 0x80214, 0x80216, 0x80218, 0x8021a, 0x8021c, - 0x8021e, 0x80220, 0x80222, 0x80224, 0x80226, 0x80228, 0x8022a, 0x8022c, 0x8022e, - 0x80230, 0x80232, 0x8023a, 0x8023b, 0x8023d, 0x8023e, 0x80241, 0x80248, 0x8024a, - 0x8024c, 0x8024e, 0x80370, 0x80372, 0x80376, 0x8037f, 0x80386, 0x8038c, 0x8038e, - 0x8038f, 0x803cf, 0x803d8, 0x803da, 0x803dc, 0x803de, 0x803e0, 0x803e2, 0x803e4, - 0x803e6, 0x803e8, 0x803ea, 0x803ec, 0x803ee, 0x803f4, 0x803f7, 0x803f9, 0x803fa, - 0x80460, 0x80462, 0x80464, 0x80466, 0x80468, 0x8046a, 0x8046c, 0x8046e, 0x80470, - 0x80472, 0x80474, 0x80476, 0x80478, 0x8047a, 0x8047c, 0x8047e, 0x80480, 0x8048a, - 0x8048c, 0x8048e, 0x80490, 0x80492, 0x80494, 0x80496, 0x80498, 0x8049a, 0x8049c, - 0x8049e, 0x804a0, 0x804a2, 0x804a4, 0x804a6, 0x804a8, 0x804aa, 0x804ac, 0x804ae, - 0x804b0, 0x804b2, 0x804b4, 0x804b6, 0x804b8, 0x804ba, 0x804bc, 0x804be, 0x804c0, - 0x804c1, 0x804c3, 0x804c5, 0x804c7, 0x804c9, 0x804cb, 0x804cd, 0x804d0, 0x804d2, - 0x804d4, 0x804d6, 0x804d8, 0x804da, 0x804dc, 0x804de, 0x804e0, 0x804e2, 0x804e4, - 0x804e6, 0x804e8, 0x804ea, 0x804ec, 0x804ee, 0x804f0, 0x804f2, 0x804f4, 0x804f6, - 0x804f8, 0x804fa, 0x804fc, 0x804fe, 0x80500, 0x80502, 0x80504, 0x80506, 0x80508, - 0x8050a, 0x8050c, 0x8050e, 0x80510, 0x80512, 0x80514, 0x80516, 0x80518, 0x8051a, - 0x8051c, 0x8051e, 0x80520, 0x80522, 0x80524, 0x80526, 0x80528, 0x8052a, 0x8052c, - 0x8052e, 0x810c7, 0x810cd, 0x81e00, 0x81e02, 0x81e04, 0x81e06, 0x81e08, 0x81e0a, - 0x81e0c, 0x81e0e, 0x81e10, 0x81e12, 0x81e14, 0x81e16, 0x81e18, 0x81e1a, 0x81e1c, - 0x81e1e, 0x81e20, 0x81e22, 0x81e24, 0x81e26, 0x81e28, 0x81e2a, 0x81e2c, 0x81e2e, - 0x81e30, 0x81e32, 0x81e34, 0x81e36, 0x81e38, 0x81e3a, 0x81e3c, 0x81e3e, 0x81e40, - 0x81e42, 0x81e44, 0x81e46, 0x81e48, 0x81e4a, 0x81e4c, 0x81e4e, 0x81e50, 0x81e52, - 0x81e54, 0x81e56, 0x81e58, 0x81e5a, 0x81e5c, 0x81e5e, 0x81e60, 0x81e62, 0x81e64, - 0x81e66, 0x81e68, 0x81e6a, 0x81e6c, 0x81e6e, 0x81e70, 0x81e72, 0x81e74, 0x81e76, - 0x81e78, 0x81e7a, 0x81e7c, 0x81e7e, 0x81e80, 0x81e82, 0x81e84, 0x81e86, 0x81e88, - 0x81e8a, 0x81e8c, 0x81e8e, 0x81e90, 0x81e92, 0x81e94, 0x81e9e, 0x81ea0, 0x81ea2, - 0x81ea4, 0x81ea6, 0x81ea8, 0x81eaa, 0x81eac, 0x81eae, 0x81eb0, 0x81eb2, 0x81eb4, - 0x81eb6, 0x81eb8, 0x81eba, 0x81ebc, 0x81ebe, 0x81ec0, 0x81ec2, 0x81ec4, 0x81ec6, - 0x81ec8, 0x81eca, 0x81ecc, 0x81ece, 0x81ed0, 0x81ed2, 0x81ed4, 0x81ed6, 0x81ed8, - 0x81eda, 0x81edc, 0x81ede, 0x81ee0, 0x81ee2, 0x81ee4, 0x81ee6, 0x81ee8, 0x81eea, - 0x81eec, 0x81eee, 0x81ef0, 0x81ef2, 0x81ef4, 0x81ef6, 0x81ef8, 0x81efa, 0x81efc, - 0x81efe, 0x81f59, 0x81f5b, 0x81f5d, 0x81f5f, 0x82102, 0x82107, 0x82115, 0x82124, - 0x82126, 0x82128, 0x8213e, 0x8213f, 0x82145, 0x82183, 0x82c60, 0x82c67, 0x82c69, - 0x82c6b, 0x82c72, 0x82c75, 0x82c82, 0x82c84, 0x82c86, 0x82c88, 0x82c8a, 0x82c8c, - 0x82c8e, 0x82c90, 0x82c92, 0x82c94, 0x82c96, 0x82c98, 0x82c9a, 0x82c9c, 0x82c9e, - 0x82ca0, 0x82ca2, 0x82ca4, 0x82ca6, 0x82ca8, 0x82caa, 0x82cac, 0x82cae, 0x82cb0, - 0x82cb2, 0x82cb4, 0x82cb6, 0x82cb8, 0x82cba, 0x82cbc, 0x82cbe, 0x82cc0, 0x82cc2, - 0x82cc4, 0x82cc6, 0x82cc8, 0x82cca, 0x82ccc, 0x82cce, 0x82cd0, 0x82cd2, 0x82cd4, - 0x82cd6, 0x82cd8, 0x82cda, 0x82cdc, 0x82cde, 0x82ce0, 0x82ce2, 0x82ceb, 0x82ced, - 0x82cf2, 0x8a640, 0x8a642, 0x8a644, 0x8a646, 0x8a648, 0x8a64a, 0x8a64c, 0x8a64e, - 0x8a650, 0x8a652, 0x8a654, 0x8a656, 0x8a658, 0x8a65a, 0x8a65c, 0x8a65e, 0x8a660, - 0x8a662, 0x8a664, 0x8a666, 0x8a668, 0x8a66a, 0x8a66c, 0x8a680, 0x8a682, 0x8a684, - 0x8a686, 0x8a688, 0x8a68a, 0x8a68c, 0x8a68e, 0x8a690, 0x8a692, 0x8a694, 0x8a696, - 0x8a698, 0x8a69a, 0x8a722, 0x8a724, 0x8a726, 0x8a728, 0x8a72a, 0x8a72c, 0x8a72e, - 0x8a732, 0x8a734, 0x8a736, 0x8a738, 0x8a73a, 0x8a73c, 0x8a73e, 0x8a740, 0x8a742, - 0x8a744, 0x8a746, 0x8a748, 0x8a74a, 0x8a74c, 0x8a74e, 0x8a750, 0x8a752, 0x8a754, - 0x8a756, 0x8a758, 0x8a75a, 0x8a75c, 0x8a75e, 0x8a760, 0x8a762, 0x8a764, 0x8a766, - 0x8a768, 0x8a76a, 0x8a76c, 0x8a76e, 0x8a779, 0x8a77b, 0x8a77d, 0x8a77e, 0x8a780, - 0x8a782, 0x8a784, 0x8a786, 0x8a78b, 0x8a78d, 0x8a790, 0x8a792, 0x8a796, 0x8a798, - 0x8a79a, 0x8a79c, 0x8a79e, 0x8a7a0, 0x8a7a2, 0x8a7a4, 0x8a7a6, 0x8a7a8, 0x8a7b6, - 0x90100, 0x90102, 0x90104, 0x90106, 0x90108, 0x9010a, 0x9010c, 0x9010e, 0x90110, - 0x90112, 0x90114, 0x90116, 0x90118, 0x9011a, 0x9011c, 0x9011e, 0x90120, 0x90122, - 0x90124, 0x90126, 0x90128, 0x9012a, 0x9012c, 0x9012e, 0x90130, 0x90132, 0x90134, - 0x90136, 0x90139, 0x9013b, 0x9013d, 0x9013f, 0x90141, 0x90143, 0x90145, 0x90147, - 0x9014a, 0x9014c, 0x9014e, 0x90150, 0x90152, 0x90154, 0x90156, 0x90158, 0x9015a, - 0x9015c, 0x9015e, 0x90160, 0x90162, 0x90164, 0x90166, 0x90168, 0x9016a, 0x9016c, - 0x9016e, 0x90170, 0x90172, 0x90174, 0x90176, 0x90178, 0x90179, 0x9017b, 0x9017d, - 0x90181, 0x90182, 0x90184, 0x90186, 0x90187, 0x90193, 0x90194, 0x9019c, 0x9019d, - 0x9019f, 0x901a0, 0x901a2, 0x901a4, 0x901a6, 0x901a7, 0x901a9, 0x901ac, 0x901ae, - 0x901af, 0x901b5, 0x901b7, 0x901b8, 0x901bc, 0x901c4, 0x901c7, 0x901ca, 0x901cd, - 0x901cf, 0x901d1, 0x901d3, 0x901d5, 0x901d7, 0x901d9, 0x901db, 0x901de, 0x901e0, - 0x901e2, 0x901e4, 0x901e6, 0x901e8, 0x901ea, 0x901ec, 0x901ee, 0x901f1, 0x901f4, - 0x901fa, 0x901fc, 0x901fe, 0x90200, 0x90202, 0x90204, 0x90206, 0x90208, 0x9020a, - 0x9020c, 0x9020e, 0x90210, 0x90212, 0x90214, 0x90216, 0x90218, 0x9021a, 0x9021c, - 0x9021e, 0x90220, 0x90222, 0x90224, 0x90226, 0x90228, 0x9022a, 0x9022c, 0x9022e, - 0x90230, 0x90232, 0x9023a, 0x9023b, 0x9023d, 0x9023e, 0x90241, 0x90248, 0x9024a, - 0x9024c, 0x9024e, 0x90370, 0x90372, 0x90376, 0x9037f, 0x90386, 0x9038c, 0x9038e, - 0x9038f, 0x903cf, 0x903d8, 0x903da, 0x903dc, 0x903de, 0x903e0, 0x903e2, 0x903e4, - 0x903e6, 0x903e8, 0x903ea, 0x903ec, 0x903ee, 0x903f4, 0x903f7, 0x903f9, 0x903fa, - 0x90460, 0x90462, 0x90464, 0x90466, 0x90468, 0x9046a, 0x9046c, 0x9046e, 0x90470, - 0x90472, 0x90474, 0x90476, 0x90478, 0x9047a, 0x9047c, 0x9047e, 0x90480, 0x9048a, - 0x9048c, 0x9048e, 0x90490, 0x90492, 0x90494, 0x90496, 0x90498, 0x9049a, 0x9049c, - 0x9049e, 0x904a0, 0x904a2, 0x904a4, 0x904a6, 0x904a8, 0x904aa, 0x904ac, 0x904ae, - 0x904b0, 0x904b2, 0x904b4, 0x904b6, 0x904b8, 0x904ba, 0x904bc, 0x904be, 0x904c0, - 0x904c1, 0x904c3, 0x904c5, 0x904c7, 0x904c9, 0x904cb, 0x904cd, 0x904d0, 0x904d2, - 0x904d4, 0x904d6, 0x904d8, 0x904da, 0x904dc, 0x904de, 0x904e0, 0x904e2, 0x904e4, - 0x904e6, 0x904e8, 0x904ea, 0x904ec, 0x904ee, 0x904f0, 0x904f2, 0x904f4, 0x904f6, - 0x904f8, 0x904fa, 0x904fc, 0x904fe, 0x90500, 0x90502, 0x90504, 0x90506, 0x90508, - 0x9050a, 0x9050c, 0x9050e, 0x90510, 0x90512, 0x90514, 0x90516, 0x90518, 0x9051a, - 0x9051c, 0x9051e, 0x90520, 0x90522, 0x90524, 0x90526, 0x90528, 0x9052a, 0x9052c, - 0x9052e, 0x910c7, 0x910cd, 0x91e00, 0x91e02, 0x91e04, 0x91e06, 0x91e08, 0x91e0a, - 0x91e0c, 0x91e0e, 0x91e10, 0x91e12, 0x91e14, 0x91e16, 0x91e18, 0x91e1a, 0x91e1c, - 0x91e1e, 0x91e20, 0x91e22, 0x91e24, 0x91e26, 0x91e28, 0x91e2a, 0x91e2c, 0x91e2e, - 0x91e30, 0x91e32, 0x91e34, 0x91e36, 0x91e38, 0x91e3a, 0x91e3c, 0x91e3e, 0x91e40, - 0x91e42, 0x91e44, 0x91e46, 0x91e48, 0x91e4a, 0x91e4c, 0x91e4e, 0x91e50, 0x91e52, - 0x91e54, 0x91e56, 0x91e58, 0x91e5a, 0x91e5c, 0x91e5e, 0x91e60, 0x91e62, 0x91e64, - 0x91e66, 0x91e68, 0x91e6a, 0x91e6c, 0x91e6e, 0x91e70, 0x91e72, 0x91e74, 0x91e76, - 0x91e78, 0x91e7a, 0x91e7c, 0x91e7e, 0x91e80, 0x91e82, 0x91e84, 0x91e86, 0x91e88, - 0x91e8a, 0x91e8c, 0x91e8e, 0x91e90, 0x91e92, 0x91e94, 0x91e9e, 0x91ea0, 0x91ea2, - 0x91ea4, 0x91ea6, 0x91ea8, 0x91eaa, 0x91eac, 0x91eae, 0x91eb0, 0x91eb2, 0x91eb4, - 0x91eb6, 0x91eb8, 0x91eba, 0x91ebc, 0x91ebe, 0x91ec0, 0x91ec2, 0x91ec4, 0x91ec6, - 0x91ec8, 0x91eca, 0x91ecc, 0x91ece, 0x91ed0, 0x91ed2, 0x91ed4, 0x91ed6, 0x91ed8, - 0x91eda, 0x91edc, 0x91ede, 0x91ee0, 0x91ee2, 0x91ee4, 0x91ee6, 0x91ee8, 0x91eea, - 0x91eec, 0x91eee, 0x91ef0, 0x91ef2, 0x91ef4, 0x91ef6, 0x91ef8, 0x91efa, 0x91efc, - 0x91efe, 0x91f59, 0x91f5b, 0x91f5d, 0x91f5f, 0x92102, 0x92107, 0x92115, 0x92124, - 0x92126, 0x92128, 0x9213e, 0x9213f, 0x92145, 0x92183, 0x92c60, 0x92c67, 0x92c69, - 0x92c6b, 0x92c72, 0x92c75, 0x92c82, 0x92c84, 0x92c86, 0x92c88, 0x92c8a, 0x92c8c, - 0x92c8e, 0x92c90, 0x92c92, 0x92c94, 0x92c96, 0x92c98, 0x92c9a, 0x92c9c, 0x92c9e, - 0x92ca0, 0x92ca2, 0x92ca4, 0x92ca6, 0x92ca8, 0x92caa, 0x92cac, 0x92cae, 0x92cb0, - 0x92cb2, 0x92cb4, 0x92cb6, 0x92cb8, 0x92cba, 0x92cbc, 0x92cbe, 0x92cc0, 0x92cc2, - 0x92cc4, 0x92cc6, 0x92cc8, 0x92cca, 0x92ccc, 0x92cce, 0x92cd0, 0x92cd2, 0x92cd4, - 0x92cd6, 0x92cd8, 0x92cda, 0x92cdc, 0x92cde, 0x92ce0, 0x92ce2, 0x92ceb, 0x92ced, - 0x92cf2, 0x9a640, 0x9a642, 0x9a644, 0x9a646, 0x9a648, 0x9a64a, 0x9a64c, 0x9a64e, - 0x9a650, 0x9a652, 0x9a654, 0x9a656, 0x9a658, 0x9a65a, 0x9a65c, 0x9a65e, 0x9a660, - 0x9a662, 0x9a664, 0x9a666, 0x9a668, 0x9a66a, 0x9a66c, 0x9a680, 0x9a682, 0x9a684, - 0x9a686, 0x9a688, 0x9a68a, 0x9a68c, 0x9a68e, 0x9a690, 0x9a692, 0x9a694, 0x9a696, - 0x9a698, 0x9a69a, 0x9a722, 0x9a724, 0x9a726, 0x9a728, 0x9a72a, 0x9a72c, 0x9a72e, - 0x9a732, 0x9a734, 0x9a736, 0x9a738, 0x9a73a, 0x9a73c, 0x9a73e, 0x9a740, 0x9a742, - 0x9a744, 0x9a746, 0x9a748, 0x9a74a, 0x9a74c, 0x9a74e, 0x9a750, 0x9a752, 0x9a754, - 0x9a756, 0x9a758, 0x9a75a, 0x9a75c, 0x9a75e, 0x9a760, 0x9a762, 0x9a764, 0x9a766, - 0x9a768, 0x9a76a, 0x9a76c, 0x9a76e, 0x9a779, 0x9a77b, 0x9a77d, 0x9a77e, 0x9a780, - 0x9a782, 0x9a784, 0x9a786, 0x9a78b, 0x9a78d, 0x9a790, 0x9a792, 0x9a796, 0x9a798, - 0x9a79a, 0x9a79c, 0x9a79e, 0x9a7a0, 0x9a7a2, 0x9a7a4, 0x9a7a6, 0x9a7a8, 0x9a7b6, - 0xa0100, 0xa0102, 0xa0104, 0xa0106, 0xa0108, 0xa010a, 0xa010c, 0xa010e, 0xa0110, - 0xa0112, 0xa0114, 0xa0116, 0xa0118, 0xa011a, 0xa011c, 0xa011e, 0xa0120, 0xa0122, - 0xa0124, 0xa0126, 0xa0128, 0xa012a, 0xa012c, 0xa012e, 0xa0130, 0xa0132, 0xa0134, - 0xa0136, 0xa0139, 0xa013b, 0xa013d, 0xa013f, 0xa0141, 0xa0143, 0xa0145, 0xa0147, - 0xa014a, 0xa014c, 0xa014e, 0xa0150, 0xa0152, 0xa0154, 0xa0156, 0xa0158, 0xa015a, - 0xa015c, 0xa015e, 0xa0160, 0xa0162, 0xa0164, 0xa0166, 0xa0168, 0xa016a, 0xa016c, - 0xa016e, 0xa0170, 0xa0172, 0xa0174, 0xa0176, 0xa0178, 0xa0179, 0xa017b, 0xa017d, - 0xa0181, 0xa0182, 0xa0184, 0xa0186, 0xa0187, 0xa0193, 0xa0194, 0xa019c, 0xa019d, - 0xa019f, 0xa01a0, 0xa01a2, 0xa01a4, 0xa01a6, 0xa01a7, 0xa01a9, 0xa01ac, 0xa01ae, - 0xa01af, 0xa01b5, 0xa01b7, 0xa01b8, 0xa01bc, 0xa01c4, 0xa01c7, 0xa01ca, 0xa01cd, - 0xa01cf, 0xa01d1, 0xa01d3, 0xa01d5, 0xa01d7, 0xa01d9, 0xa01db, 0xa01de, 0xa01e0, - 0xa01e2, 0xa01e4, 0xa01e6, 0xa01e8, 0xa01ea, 0xa01ec, 0xa01ee, 0xa01f1, 0xa01f4, - 0xa01fa, 0xa01fc, 0xa01fe, 0xa0200, 0xa0202, 0xa0204, 0xa0206, 0xa0208, 0xa020a, - 0xa020c, 0xa020e, 0xa0210, 0xa0212, 0xa0214, 0xa0216, 0xa0218, 0xa021a, 0xa021c, - 0xa021e, 0xa0220, 0xa0222, 0xa0224, 0xa0226, 0xa0228, 0xa022a, 0xa022c, 0xa022e, - 0xa0230, 0xa0232, 0xa023a, 0xa023b, 0xa023d, 0xa023e, 0xa0241, 0xa0248, 0xa024a, - 0xa024c, 0xa024e, 0xa0370, 0xa0372, 0xa0376, 0xa037f, 0xa0386, 0xa038c, 0xa038e, - 0xa038f, 0xa03cf, 0xa03d8, 0xa03da, 0xa03dc, 0xa03de, 0xa03e0, 0xa03e2, 0xa03e4, - 0xa03e6, 0xa03e8, 0xa03ea, 0xa03ec, 0xa03ee, 0xa03f4, 0xa03f7, 0xa03f9, 0xa03fa, - 0xa0460, 0xa0462, 0xa0464, 0xa0466, 0xa0468, 0xa046a, 0xa046c, 0xa046e, 0xa0470, - 0xa0472, 0xa0474, 0xa0476, 0xa0478, 0xa047a, 0xa047c, 0xa047e, 0xa0480, 0xa048a, - 0xa048c, 0xa048e, 0xa0490, 0xa0492, 0xa0494, 0xa0496, 0xa0498, 0xa049a, 0xa049c, - 0xa049e, 0xa04a0, 0xa04a2, 0xa04a4, 0xa04a6, 0xa04a8, 0xa04aa, 0xa04ac, 0xa04ae, - 0xa04b0, 0xa04b2, 0xa04b4, 0xa04b6, 0xa04b8, 0xa04ba, 0xa04bc, 0xa04be, 0xa04c0, - 0xa04c1, 0xa04c3, 0xa04c5, 0xa04c7, 0xa04c9, 0xa04cb, 0xa04cd, 0xa04d0, 0xa04d2, - 0xa04d4, 0xa04d6, 0xa04d8, 0xa04da, 0xa04dc, 0xa04de, 0xa04e0, 0xa04e2, 0xa04e4, - 0xa04e6, 0xa04e8, 0xa04ea, 0xa04ec, 0xa04ee, 0xa04f0, 0xa04f2, 0xa04f4, 0xa04f6, - 0xa04f8, 0xa04fa, 0xa04fc, 0xa04fe, 0xa0500, 0xa0502, 0xa0504, 0xa0506, 0xa0508, - 0xa050a, 0xa050c, 0xa050e, 0xa0510, 0xa0512, 0xa0514, 0xa0516, 0xa0518, 0xa051a, - 0xa051c, 0xa051e, 0xa0520, 0xa0522, 0xa0524, 0xa0526, 0xa0528, 0xa052a, 0xa052c, - 0xa052e, 0xa10c7, 0xa10cd, 0xa1e00, 0xa1e02, 0xa1e04, 0xa1e06, 0xa1e08, 0xa1e0a, - 0xa1e0c, 0xa1e0e, 0xa1e10, 0xa1e12, 0xa1e14, 0xa1e16, 0xa1e18, 0xa1e1a, 0xa1e1c, - 0xa1e1e, 0xa1e20, 0xa1e22, 0xa1e24, 0xa1e26, 0xa1e28, 0xa1e2a, 0xa1e2c, 0xa1e2e, - 0xa1e30, 0xa1e32, 0xa1e34, 0xa1e36, 0xa1e38, 0xa1e3a, 0xa1e3c, 0xa1e3e, 0xa1e40, - 0xa1e42, 0xa1e44, 0xa1e46, 0xa1e48, 0xa1e4a, 0xa1e4c, 0xa1e4e, 0xa1e50, 0xa1e52, - 0xa1e54, 0xa1e56, 0xa1e58, 0xa1e5a, 0xa1e5c, 0xa1e5e, 0xa1e60, 0xa1e62, 0xa1e64, - 0xa1e66, 0xa1e68, 0xa1e6a, 0xa1e6c, 0xa1e6e, 0xa1e70, 0xa1e72, 0xa1e74, 0xa1e76, - 0xa1e78, 0xa1e7a, 0xa1e7c, 0xa1e7e, 0xa1e80, 0xa1e82, 0xa1e84, 0xa1e86, 0xa1e88, - 0xa1e8a, 0xa1e8c, 0xa1e8e, 0xa1e90, 0xa1e92, 0xa1e94, 0xa1e9e, 0xa1ea0, 0xa1ea2, - 0xa1ea4, 0xa1ea6, 0xa1ea8, 0xa1eaa, 0xa1eac, 0xa1eae, 0xa1eb0, 0xa1eb2, 0xa1eb4, - 0xa1eb6, 0xa1eb8, 0xa1eba, 0xa1ebc, 0xa1ebe, 0xa1ec0, 0xa1ec2, 0xa1ec4, 0xa1ec6, - 0xa1ec8, 0xa1eca, 0xa1ecc, 0xa1ece, 0xa1ed0, 0xa1ed2, 0xa1ed4, 0xa1ed6, 0xa1ed8, - 0xa1eda, 0xa1edc, 0xa1ede, 0xa1ee0, 0xa1ee2, 0xa1ee4, 0xa1ee6, 0xa1ee8, 0xa1eea, - 0xa1eec, 0xa1eee, 0xa1ef0, 0xa1ef2, 0xa1ef4, 0xa1ef6, 0xa1ef8, 0xa1efa, 0xa1efc, - 0xa1efe, 0xa1f59, 0xa1f5b, 0xa1f5d, 0xa1f5f, 0xa2102, 0xa2107, 0xa2115, 0xa2124, - 0xa2126, 0xa2128, 0xa213e, 0xa213f, 0xa2145, 0xa2183, 0xa2c60, 0xa2c67, 0xa2c69, - 0xa2c6b, 0xa2c72, 0xa2c75, 0xa2c82, 0xa2c84, 0xa2c86, 0xa2c88, 0xa2c8a, 0xa2c8c, - 0xa2c8e, 0xa2c90, 0xa2c92, 0xa2c94, 0xa2c96, 0xa2c98, 0xa2c9a, 0xa2c9c, 0xa2c9e, - 0xa2ca0, 0xa2ca2, 0xa2ca4, 0xa2ca6, 0xa2ca8, 0xa2caa, 0xa2cac, 0xa2cae, 0xa2cb0, - 0xa2cb2, 0xa2cb4, 0xa2cb6, 0xa2cb8, 0xa2cba, 0xa2cbc, 0xa2cbe, 0xa2cc0, 0xa2cc2, - 0xa2cc4, 0xa2cc6, 0xa2cc8, 0xa2cca, 0xa2ccc, 0xa2cce, 0xa2cd0, 0xa2cd2, 0xa2cd4, - 0xa2cd6, 0xa2cd8, 0xa2cda, 0xa2cdc, 0xa2cde, 0xa2ce0, 0xa2ce2, 0xa2ceb, 0xa2ced, - 0xa2cf2, 0xaa640, 0xaa642, 0xaa644, 0xaa646, 0xaa648, 0xaa64a, 0xaa64c, 0xaa64e, - 0xaa650, 0xaa652, 0xaa654, 0xaa656, 0xaa658, 0xaa65a, 0xaa65c, 0xaa65e, 0xaa660, - 0xaa662, 0xaa664, 0xaa666, 0xaa668, 0xaa66a, 0xaa66c, 0xaa680, 0xaa682, 0xaa684, - 0xaa686, 0xaa688, 0xaa68a, 0xaa68c, 0xaa68e, 0xaa690, 0xaa692, 0xaa694, 0xaa696, - 0xaa698, 0xaa69a, 0xaa722, 0xaa724, 0xaa726, 0xaa728, 0xaa72a, 0xaa72c, 0xaa72e, - 0xaa732, 0xaa734, 0xaa736, 0xaa738, 0xaa73a, 0xaa73c, 0xaa73e, 0xaa740, 0xaa742, - 0xaa744, 0xaa746, 0xaa748, 0xaa74a, 0xaa74c, 0xaa74e, 0xaa750, 0xaa752, 0xaa754, - 0xaa756, 0xaa758, 0xaa75a, 0xaa75c, 0xaa75e, 0xaa760, 0xaa762, 0xaa764, 0xaa766, - 0xaa768, 0xaa76a, 0xaa76c, 0xaa76e, 0xaa779, 0xaa77b, 0xaa77d, 0xaa77e, 0xaa780, - 0xaa782, 0xaa784, 0xaa786, 0xaa78b, 0xaa78d, 0xaa790, 0xaa792, 0xaa796, 0xaa798, - 0xaa79a, 0xaa79c, 0xaa79e, 0xaa7a0, 0xaa7a2, 0xaa7a4, 0xaa7a6, 0xaa7a8, 0xaa7b6, - 0xb0100, 0xb0102, 0xb0104, 0xb0106, 0xb0108, 0xb010a, 0xb010c, 0xb010e, 0xb0110, - 0xb0112, 0xb0114, 0xb0116, 0xb0118, 0xb011a, 0xb011c, 0xb011e, 0xb0120, 0xb0122, - 0xb0124, 0xb0126, 0xb0128, 0xb012a, 0xb012c, 0xb012e, 0xb0130, 0xb0132, 0xb0134, - 0xb0136, 0xb0139, 0xb013b, 0xb013d, 0xb013f, 0xb0141, 0xb0143, 0xb0145, 0xb0147, - 0xb014a, 0xb014c, 0xb014e, 0xb0150, 0xb0152, 0xb0154, 0xb0156, 0xb0158, 0xb015a, - 0xb015c, 0xb015e, 0xb0160, 0xb0162, 0xb0164, 0xb0166, 0xb0168, 0xb016a, 0xb016c, - 0xb016e, 0xb0170, 0xb0172, 0xb0174, 0xb0176, 0xb0178, 0xb0179, 0xb017b, 0xb017d, - 0xb0181, 0xb0182, 0xb0184, 0xb0186, 0xb0187, 0xb0193, 0xb0194, 0xb019c, 0xb019d, - 0xb019f, 0xb01a0, 0xb01a2, 0xb01a4, 0xb01a6, 0xb01a7, 0xb01a9, 0xb01ac, 0xb01ae, - 0xb01af, 0xb01b5, 0xb01b7, 0xb01b8, 0xb01bc, 0xb01c4, 0xb01c7, 0xb01ca, 0xb01cd, - 0xb01cf, 0xb01d1, 0xb01d3, 0xb01d5, 0xb01d7, 0xb01d9, 0xb01db, 0xb01de, 0xb01e0, - 0xb01e2, 0xb01e4, 0xb01e6, 0xb01e8, 0xb01ea, 0xb01ec, 0xb01ee, 0xb01f1, 0xb01f4, - 0xb01fa, 0xb01fc, 0xb01fe, 0xb0200, 0xb0202, 0xb0204, 0xb0206, 0xb0208, 0xb020a, - 0xb020c, 0xb020e, 0xb0210, 0xb0212, 0xb0214, 0xb0216, 0xb0218, 0xb021a, 0xb021c, - 0xb021e, 0xb0220, 0xb0222, 0xb0224, 0xb0226, 0xb0228, 0xb022a, 0xb022c, 0xb022e, - 0xb0230, 0xb0232, 0xb023a, 0xb023b, 0xb023d, 0xb023e, 0xb0241, 0xb0248, 0xb024a, - 0xb024c, 0xb024e, 0xb0370, 0xb0372, 0xb0376, 0xb037f, 0xb0386, 0xb038c, 0xb038e, - 0xb038f, 0xb03cf, 0xb03d8, 0xb03da, 0xb03dc, 0xb03de, 0xb03e0, 0xb03e2, 0xb03e4, - 0xb03e6, 0xb03e8, 0xb03ea, 0xb03ec, 0xb03ee, 0xb03f4, 0xb03f7, 0xb03f9, 0xb03fa, - 0xb0460, 0xb0462, 0xb0464, 0xb0466, 0xb0468, 0xb046a, 0xb046c, 0xb046e, 0xb0470, - 0xb0472, 0xb0474, 0xb0476, 0xb0478, 0xb047a, 0xb047c, 0xb047e, 0xb0480, 0xb048a, - 0xb048c, 0xb048e, 0xb0490, 0xb0492, 0xb0494, 0xb0496, 0xb0498, 0xb049a, 0xb049c, - 0xb049e, 0xb04a0, 0xb04a2, 0xb04a4, 0xb04a6, 0xb04a8, 0xb04aa, 0xb04ac, 0xb04ae, - 0xb04b0, 0xb04b2, 0xb04b4, 0xb04b6, 0xb04b8, 0xb04ba, 0xb04bc, 0xb04be, 0xb04c0, - 0xb04c1, 0xb04c3, 0xb04c5, 0xb04c7, 0xb04c9, 0xb04cb, 0xb04cd, 0xb04d0, 0xb04d2, - 0xb04d4, 0xb04d6, 0xb04d8, 0xb04da, 0xb04dc, 0xb04de, 0xb04e0, 0xb04e2, 0xb04e4, - 0xb04e6, 0xb04e8, 0xb04ea, 0xb04ec, 0xb04ee, 0xb04f0, 0xb04f2, 0xb04f4, 0xb04f6, - 0xb04f8, 0xb04fa, 0xb04fc, 0xb04fe, 0xb0500, 0xb0502, 0xb0504, 0xb0506, 0xb0508, - 0xb050a, 0xb050c, 0xb050e, 0xb0510, 0xb0512, 0xb0514, 0xb0516, 0xb0518, 0xb051a, - 0xb051c, 0xb051e, 0xb0520, 0xb0522, 0xb0524, 0xb0526, 0xb0528, 0xb052a, 0xb052c, - 0xb052e, 0xb10c7, 0xb10cd, 0xb1e00, 0xb1e02, 0xb1e04, 0xb1e06, 0xb1e08, 0xb1e0a, - 0xb1e0c, 0xb1e0e, 0xb1e10, 0xb1e12, 0xb1e14, 0xb1e16, 0xb1e18, 0xb1e1a, 0xb1e1c, - 0xb1e1e, 0xb1e20, 0xb1e22, 0xb1e24, 0xb1e26, 0xb1e28, 0xb1e2a, 0xb1e2c, 0xb1e2e, - 0xb1e30, 0xb1e32, 0xb1e34, 0xb1e36, 0xb1e38, 0xb1e3a, 0xb1e3c, 0xb1e3e, 0xb1e40, - 0xb1e42, 0xb1e44, 0xb1e46, 0xb1e48, 0xb1e4a, 0xb1e4c, 0xb1e4e, 0xb1e50, 0xb1e52, - 0xb1e54, 0xb1e56, 0xb1e58, 0xb1e5a, 0xb1e5c, 0xb1e5e, 0xb1e60, 0xb1e62, 0xb1e64, - 0xb1e66, 0xb1e68, 0xb1e6a, 0xb1e6c, 0xb1e6e, 0xb1e70, 0xb1e72, 0xb1e74, 0xb1e76, - 0xb1e78, 0xb1e7a, 0xb1e7c, 0xb1e7e, 0xb1e80, 0xb1e82, 0xb1e84, 0xb1e86, 0xb1e88, - 0xb1e8a, 0xb1e8c, 0xb1e8e, 0xb1e90, 0xb1e92, 0xb1e94, 0xb1e9e, 0xb1ea0, 0xb1ea2, - 0xb1ea4, 0xb1ea6, 0xb1ea8, 0xb1eaa, 0xb1eac, 0xb1eae, 0xb1eb0, 0xb1eb2, 0xb1eb4, - 0xb1eb6, 0xb1eb8, 0xb1eba, 0xb1ebc, 0xb1ebe, 0xb1ec0, 0xb1ec2, 0xb1ec4, 0xb1ec6, - 0xb1ec8, 0xb1eca, 0xb1ecc, 0xb1ece, 0xb1ed0, 0xb1ed2, 0xb1ed4, 0xb1ed6, 0xb1ed8, - 0xb1eda, 0xb1edc, 0xb1ede, 0xb1ee0, 0xb1ee2, 0xb1ee4, 0xb1ee6, 0xb1ee8, 0xb1eea, - 0xb1eec, 0xb1eee, 0xb1ef0, 0xb1ef2, 0xb1ef4, 0xb1ef6, 0xb1ef8, 0xb1efa, 0xb1efc, - 0xb1efe, 0xb1f59, 0xb1f5b, 0xb1f5d, 0xb1f5f, 0xb2102, 0xb2107, 0xb2115, 0xb2124, - 0xb2126, 0xb2128, 0xb213e, 0xb213f, 0xb2145, 0xb2183, 0xb2c60, 0xb2c67, 0xb2c69, - 0xb2c6b, 0xb2c72, 0xb2c75, 0xb2c82, 0xb2c84, 0xb2c86, 0xb2c88, 0xb2c8a, 0xb2c8c, - 0xb2c8e, 0xb2c90, 0xb2c92, 0xb2c94, 0xb2c96, 0xb2c98, 0xb2c9a, 0xb2c9c, 0xb2c9e, - 0xb2ca0, 0xb2ca2, 0xb2ca4, 0xb2ca6, 0xb2ca8, 0xb2caa, 0xb2cac, 0xb2cae, 0xb2cb0, - 0xb2cb2, 0xb2cb4, 0xb2cb6, 0xb2cb8, 0xb2cba, 0xb2cbc, 0xb2cbe, 0xb2cc0, 0xb2cc2, - 0xb2cc4, 0xb2cc6, 0xb2cc8, 0xb2cca, 0xb2ccc, 0xb2cce, 0xb2cd0, 0xb2cd2, 0xb2cd4, - 0xb2cd6, 0xb2cd8, 0xb2cda, 0xb2cdc, 0xb2cde, 0xb2ce0, 0xb2ce2, 0xb2ceb, 0xb2ced, - 0xb2cf2, 0xba640, 0xba642, 0xba644, 0xba646, 0xba648, 0xba64a, 0xba64c, 0xba64e, - 0xba650, 0xba652, 0xba654, 0xba656, 0xba658, 0xba65a, 0xba65c, 0xba65e, 0xba660, - 0xba662, 0xba664, 0xba666, 0xba668, 0xba66a, 0xba66c, 0xba680, 0xba682, 0xba684, - 0xba686, 0xba688, 0xba68a, 0xba68c, 0xba68e, 0xba690, 0xba692, 0xba694, 0xba696, - 0xba698, 0xba69a, 0xba722, 0xba724, 0xba726, 0xba728, 0xba72a, 0xba72c, 0xba72e, - 0xba732, 0xba734, 0xba736, 0xba738, 0xba73a, 0xba73c, 0xba73e, 0xba740, 0xba742, - 0xba744, 0xba746, 0xba748, 0xba74a, 0xba74c, 0xba74e, 0xba750, 0xba752, 0xba754, - 0xba756, 0xba758, 0xba75a, 0xba75c, 0xba75e, 0xba760, 0xba762, 0xba764, 0xba766, - 0xba768, 0xba76a, 0xba76c, 0xba76e, 0xba779, 0xba77b, 0xba77d, 0xba77e, 0xba780, - 0xba782, 0xba784, 0xba786, 0xba78b, 0xba78d, 0xba790, 0xba792, 0xba796, 0xba798, - 0xba79a, 0xba79c, 0xba79e, 0xba7a0, 0xba7a2, 0xba7a4, 0xba7a6, 0xba7a8, 0xba7b6, - 0xc0100, 0xc0102, 0xc0104, 0xc0106, 0xc0108, 0xc010a, 0xc010c, 0xc010e, 0xc0110, - 0xc0112, 0xc0114, 0xc0116, 0xc0118, 0xc011a, 0xc011c, 0xc011e, 0xc0120, 0xc0122, - 0xc0124, 0xc0126, 0xc0128, 0xc012a, 0xc012c, 0xc012e, 0xc0130, 0xc0132, 0xc0134, - 0xc0136, 0xc0139, 0xc013b, 0xc013d, 0xc013f, 0xc0141, 0xc0143, 0xc0145, 0xc0147, - 0xc014a, 0xc014c, 0xc014e, 0xc0150, 0xc0152, 0xc0154, 0xc0156, 0xc0158, 0xc015a, - 0xc015c, 0xc015e, 0xc0160, 0xc0162, 0xc0164, 0xc0166, 0xc0168, 0xc016a, 0xc016c, - 0xc016e, 0xc0170, 0xc0172, 0xc0174, 0xc0176, 0xc0178, 0xc0179, 0xc017b, 0xc017d, - 0xc0181, 0xc0182, 0xc0184, 0xc0186, 0xc0187, 0xc0193, 0xc0194, 0xc019c, 0xc019d, - 0xc019f, 0xc01a0, 0xc01a2, 0xc01a4, 0xc01a6, 0xc01a7, 0xc01a9, 0xc01ac, 0xc01ae, - 0xc01af, 0xc01b5, 0xc01b7, 0xc01b8, 0xc01bc, 0xc01c4, 0xc01c7, 0xc01ca, 0xc01cd, - 0xc01cf, 0xc01d1, 0xc01d3, 0xc01d5, 0xc01d7, 0xc01d9, 0xc01db, 0xc01de, 0xc01e0, - 0xc01e2, 0xc01e4, 0xc01e6, 0xc01e8, 0xc01ea, 0xc01ec, 0xc01ee, 0xc01f1, 0xc01f4, - 0xc01fa, 0xc01fc, 0xc01fe, 0xc0200, 0xc0202, 0xc0204, 0xc0206, 0xc0208, 0xc020a, - 0xc020c, 0xc020e, 0xc0210, 0xc0212, 0xc0214, 0xc0216, 0xc0218, 0xc021a, 0xc021c, - 0xc021e, 0xc0220, 0xc0222, 0xc0224, 0xc0226, 0xc0228, 0xc022a, 0xc022c, 0xc022e, - 0xc0230, 0xc0232, 0xc023a, 0xc023b, 0xc023d, 0xc023e, 0xc0241, 0xc0248, 0xc024a, - 0xc024c, 0xc024e, 0xc0370, 0xc0372, 0xc0376, 0xc037f, 0xc0386, 0xc038c, 0xc038e, - 0xc038f, 0xc03cf, 0xc03d8, 0xc03da, 0xc03dc, 0xc03de, 0xc03e0, 0xc03e2, 0xc03e4, - 0xc03e6, 0xc03e8, 0xc03ea, 0xc03ec, 0xc03ee, 0xc03f4, 0xc03f7, 0xc03f9, 0xc03fa, - 0xc0460, 0xc0462, 0xc0464, 0xc0466, 0xc0468, 0xc046a, 0xc046c, 0xc046e, 0xc0470, - 0xc0472, 0xc0474, 0xc0476, 0xc0478, 0xc047a, 0xc047c, 0xc047e, 0xc0480, 0xc048a, - 0xc048c, 0xc048e, 0xc0490, 0xc0492, 0xc0494, 0xc0496, 0xc0498, 0xc049a, 0xc049c, - 0xc049e, 0xc04a0, 0xc04a2, 0xc04a4, 0xc04a6, 0xc04a8, 0xc04aa, 0xc04ac, 0xc04ae, - 0xc04b0, 0xc04b2, 0xc04b4, 0xc04b6, 0xc04b8, 0xc04ba, 0xc04bc, 0xc04be, 0xc04c0, - 0xc04c1, 0xc04c3, 0xc04c5, 0xc04c7, 0xc04c9, 0xc04cb, 0xc04cd, 0xc04d0, 0xc04d2, - 0xc04d4, 0xc04d6, 0xc04d8, 0xc04da, 0xc04dc, 0xc04de, 0xc04e0, 0xc04e2, 0xc04e4, - 0xc04e6, 0xc04e8, 0xc04ea, 0xc04ec, 0xc04ee, 0xc04f0, 0xc04f2, 0xc04f4, 0xc04f6, - 0xc04f8, 0xc04fa, 0xc04fc, 0xc04fe, 0xc0500, 0xc0502, 0xc0504, 0xc0506, 0xc0508, - 0xc050a, 0xc050c, 0xc050e, 0xc0510, 0xc0512, 0xc0514, 0xc0516, 0xc0518, 0xc051a, - 0xc051c, 0xc051e, 0xc0520, 0xc0522, 0xc0524, 0xc0526, 0xc0528, 0xc052a, 0xc052c, - 0xc052e, 0xc10c7, 0xc10cd, 0xc1e00, 0xc1e02, 0xc1e04, 0xc1e06, 0xc1e08, 0xc1e0a, - 0xc1e0c, 0xc1e0e, 0xc1e10, 0xc1e12, 0xc1e14, 0xc1e16, 0xc1e18, 0xc1e1a, 0xc1e1c, - 0xc1e1e, 0xc1e20, 0xc1e22, 0xc1e24, 0xc1e26, 0xc1e28, 0xc1e2a, 0xc1e2c, 0xc1e2e, - 0xc1e30, 0xc1e32, 0xc1e34, 0xc1e36, 0xc1e38, 0xc1e3a, 0xc1e3c, 0xc1e3e, 0xc1e40, - 0xc1e42, 0xc1e44, 0xc1e46, 0xc1e48, 0xc1e4a, 0xc1e4c, 0xc1e4e, 0xc1e50, 0xc1e52, - 0xc1e54, 0xc1e56, 0xc1e58, 0xc1e5a, 0xc1e5c, 0xc1e5e, 0xc1e60, 0xc1e62, 0xc1e64, - 0xc1e66, 0xc1e68, 0xc1e6a, 0xc1e6c, 0xc1e6e, 0xc1e70, 0xc1e72, 0xc1e74, 0xc1e76, - 0xc1e78, 0xc1e7a, 0xc1e7c, 0xc1e7e, 0xc1e80, 0xc1e82, 0xc1e84, 0xc1e86, 0xc1e88, - 0xc1e8a, 0xc1e8c, 0xc1e8e, 0xc1e90, 0xc1e92, 0xc1e94, 0xc1e9e, 0xc1ea0, 0xc1ea2, - 0xc1ea4, 0xc1ea6, 0xc1ea8, 0xc1eaa, 0xc1eac, 0xc1eae, 0xc1eb0, 0xc1eb2, 0xc1eb4, - 0xc1eb6, 0xc1eb8, 0xc1eba, 0xc1ebc, 0xc1ebe, 0xc1ec0, 0xc1ec2, 0xc1ec4, 0xc1ec6, - 0xc1ec8, 0xc1eca, 0xc1ecc, 0xc1ece, 0xc1ed0, 0xc1ed2, 0xc1ed4, 0xc1ed6, 0xc1ed8, - 0xc1eda, 0xc1edc, 0xc1ede, 0xc1ee0, 0xc1ee2, 0xc1ee4, 0xc1ee6, 0xc1ee8, 0xc1eea, - 0xc1eec, 0xc1eee, 0xc1ef0, 0xc1ef2, 0xc1ef4, 0xc1ef6, 0xc1ef8, 0xc1efa, 0xc1efc, - 0xc1efe, 0xc1f59, 0xc1f5b, 0xc1f5d, 0xc1f5f, 0xc2102, 0xc2107, 0xc2115, 0xc2124, - 0xc2126, 0xc2128, 0xc213e, 0xc213f, 0xc2145, 0xc2183, 0xc2c60, 0xc2c67, 0xc2c69, - 0xc2c6b, 0xc2c72, 0xc2c75, 0xc2c82, 0xc2c84, 0xc2c86, 0xc2c88, 0xc2c8a, 0xc2c8c, - 0xc2c8e, 0xc2c90, 0xc2c92, 0xc2c94, 0xc2c96, 0xc2c98, 0xc2c9a, 0xc2c9c, 0xc2c9e, - 0xc2ca0, 0xc2ca2, 0xc2ca4, 0xc2ca6, 0xc2ca8, 0xc2caa, 0xc2cac, 0xc2cae, 0xc2cb0, - 0xc2cb2, 0xc2cb4, 0xc2cb6, 0xc2cb8, 0xc2cba, 0xc2cbc, 0xc2cbe, 0xc2cc0, 0xc2cc2, - 0xc2cc4, 0xc2cc6, 0xc2cc8, 0xc2cca, 0xc2ccc, 0xc2cce, 0xc2cd0, 0xc2cd2, 0xc2cd4, - 0xc2cd6, 0xc2cd8, 0xc2cda, 0xc2cdc, 0xc2cde, 0xc2ce0, 0xc2ce2, 0xc2ceb, 0xc2ced, - 0xc2cf2, 0xca640, 0xca642, 0xca644, 0xca646, 0xca648, 0xca64a, 0xca64c, 0xca64e, - 0xca650, 0xca652, 0xca654, 0xca656, 0xca658, 0xca65a, 0xca65c, 0xca65e, 0xca660, - 0xca662, 0xca664, 0xca666, 0xca668, 0xca66a, 0xca66c, 0xca680, 0xca682, 0xca684, - 0xca686, 0xca688, 0xca68a, 0xca68c, 0xca68e, 0xca690, 0xca692, 0xca694, 0xca696, - 0xca698, 0xca69a, 0xca722, 0xca724, 0xca726, 0xca728, 0xca72a, 0xca72c, 0xca72e, - 0xca732, 0xca734, 0xca736, 0xca738, 0xca73a, 0xca73c, 0xca73e, 0xca740, 0xca742, - 0xca744, 0xca746, 0xca748, 0xca74a, 0xca74c, 0xca74e, 0xca750, 0xca752, 0xca754, - 0xca756, 0xca758, 0xca75a, 0xca75c, 0xca75e, 0xca760, 0xca762, 0xca764, 0xca766, - 0xca768, 0xca76a, 0xca76c, 0xca76e, 0xca779, 0xca77b, 0xca77d, 0xca77e, 0xca780, - 0xca782, 0xca784, 0xca786, 0xca78b, 0xca78d, 0xca790, 0xca792, 0xca796, 0xca798, - 0xca79a, 0xca79c, 0xca79e, 0xca7a0, 0xca7a2, 0xca7a4, 0xca7a6, 0xca7a8, 0xca7b6, - 0xd0100, 0xd0102, 0xd0104, 0xd0106, 0xd0108, 0xd010a, 0xd010c, 0xd010e, 0xd0110, - 0xd0112, 0xd0114, 0xd0116, 0xd0118, 0xd011a, 0xd011c, 0xd011e, 0xd0120, 0xd0122, - 0xd0124, 0xd0126, 0xd0128, 0xd012a, 0xd012c, 0xd012e, 0xd0130, 0xd0132, 0xd0134, - 0xd0136, 0xd0139, 0xd013b, 0xd013d, 0xd013f, 0xd0141, 0xd0143, 0xd0145, 0xd0147, - 0xd014a, 0xd014c, 0xd014e, 0xd0150, 0xd0152, 0xd0154, 0xd0156, 0xd0158, 0xd015a, - 0xd015c, 0xd015e, 0xd0160, 0xd0162, 0xd0164, 0xd0166, 0xd0168, 0xd016a, 0xd016c, - 0xd016e, 0xd0170, 0xd0172, 0xd0174, 0xd0176, 0xd0178, 0xd0179, 0xd017b, 0xd017d, - 0xd0181, 0xd0182, 0xd0184, 0xd0186, 0xd0187, 0xd0193, 0xd0194, 0xd019c, 0xd019d, - 0xd019f, 0xd01a0, 0xd01a2, 0xd01a4, 0xd01a6, 0xd01a7, 0xd01a9, 0xd01ac, 0xd01ae, - 0xd01af, 0xd01b5, 0xd01b7, 0xd01b8, 0xd01bc, 0xd01c4, 0xd01c7, 0xd01ca, 0xd01cd, - 0xd01cf, 0xd01d1, 0xd01d3, 0xd01d5, 0xd01d7, 0xd01d9, 0xd01db, 0xd01de, 0xd01e0, - 0xd01e2, 0xd01e4, 0xd01e6, 0xd01e8, 0xd01ea, 0xd01ec, 0xd01ee, 0xd01f1, 0xd01f4, - 0xd01fa, 0xd01fc, 0xd01fe, 0xd0200, 0xd0202, 0xd0204, 0xd0206, 0xd0208, 0xd020a, - 0xd020c, 0xd020e, 0xd0210, 0xd0212, 0xd0214, 0xd0216, 0xd0218, 0xd021a, 0xd021c, - 0xd021e, 0xd0220, 0xd0222, 0xd0224, 0xd0226, 0xd0228, 0xd022a, 0xd022c, 0xd022e, - 0xd0230, 0xd0232, 0xd023a, 0xd023b, 0xd023d, 0xd023e, 0xd0241, 0xd0248, 0xd024a, - 0xd024c, 0xd024e, 0xd0370, 0xd0372, 0xd0376, 0xd037f, 0xd0386, 0xd038c, 0xd038e, - 0xd038f, 0xd03cf, 0xd03d8, 0xd03da, 0xd03dc, 0xd03de, 0xd03e0, 0xd03e2, 0xd03e4, - 0xd03e6, 0xd03e8, 0xd03ea, 0xd03ec, 0xd03ee, 0xd03f4, 0xd03f7, 0xd03f9, 0xd03fa, - 0xd0460, 0xd0462, 0xd0464, 0xd0466, 0xd0468, 0xd046a, 0xd046c, 0xd046e, 0xd0470, - 0xd0472, 0xd0474, 0xd0476, 0xd0478, 0xd047a, 0xd047c, 0xd047e, 0xd0480, 0xd048a, - 0xd048c, 0xd048e, 0xd0490, 0xd0492, 0xd0494, 0xd0496, 0xd0498, 0xd049a, 0xd049c, - 0xd049e, 0xd04a0, 0xd04a2, 0xd04a4, 0xd04a6, 0xd04a8, 0xd04aa, 0xd04ac, 0xd04ae, - 0xd04b0, 0xd04b2, 0xd04b4, 0xd04b6, 0xd04b8, 0xd04ba, 0xd04bc, 0xd04be, 0xd04c0, - 0xd04c1, 0xd04c3, 0xd04c5, 0xd04c7, 0xd04c9, 0xd04cb, 0xd04cd, 0xd04d0, 0xd04d2, - 0xd04d4, 0xd04d6, 0xd04d8, 0xd04da, 0xd04dc, 0xd04de, 0xd04e0, 0xd04e2, 0xd04e4, - 0xd04e6, 0xd04e8, 0xd04ea, 0xd04ec, 0xd04ee, 0xd04f0, 0xd04f2, 0xd04f4, 0xd04f6, - 0xd04f8, 0xd04fa, 0xd04fc, 0xd04fe, 0xd0500, 0xd0502, 0xd0504, 0xd0506, 0xd0508, - 0xd050a, 0xd050c, 0xd050e, 0xd0510, 0xd0512, 0xd0514, 0xd0516, 0xd0518, 0xd051a, - 0xd051c, 0xd051e, 0xd0520, 0xd0522, 0xd0524, 0xd0526, 0xd0528, 0xd052a, 0xd052c, - 0xd052e, 0xd10c7, 0xd10cd, 0xd1e00, 0xd1e02, 0xd1e04, 0xd1e06, 0xd1e08, 0xd1e0a, - 0xd1e0c, 0xd1e0e, 0xd1e10, 0xd1e12, 0xd1e14, 0xd1e16, 0xd1e18, 0xd1e1a, 0xd1e1c, - 0xd1e1e, 0xd1e20, 0xd1e22, 0xd1e24, 0xd1e26, 0xd1e28, 0xd1e2a, 0xd1e2c, 0xd1e2e, - 0xd1e30, 0xd1e32, 0xd1e34, 0xd1e36, 0xd1e38, 0xd1e3a, 0xd1e3c, 0xd1e3e, 0xd1e40, - 0xd1e42, 0xd1e44, 0xd1e46, 0xd1e48, 0xd1e4a, 0xd1e4c, 0xd1e4e, 0xd1e50, 0xd1e52, - 0xd1e54, 0xd1e56, 0xd1e58, 0xd1e5a, 0xd1e5c, 0xd1e5e, 0xd1e60, 0xd1e62, 0xd1e64, - 0xd1e66, 0xd1e68, 0xd1e6a, 0xd1e6c, 0xd1e6e, 0xd1e70, 0xd1e72, 0xd1e74, 0xd1e76, - 0xd1e78, 0xd1e7a, 0xd1e7c, 0xd1e7e, 0xd1e80, 0xd1e82, 0xd1e84, 0xd1e86, 0xd1e88, - 0xd1e8a, 0xd1e8c, 0xd1e8e, 0xd1e90, 0xd1e92, 0xd1e94, 0xd1e9e, 0xd1ea0, 0xd1ea2, - 0xd1ea4, 0xd1ea6, 0xd1ea8, 0xd1eaa, 0xd1eac, 0xd1eae, 0xd1eb0, 0xd1eb2, 0xd1eb4, - 0xd1eb6, 0xd1eb8, 0xd1eba, 0xd1ebc, 0xd1ebe, 0xd1ec0, 0xd1ec2, 0xd1ec4, 0xd1ec6, - 0xd1ec8, 0xd1eca, 0xd1ecc, 0xd1ece, 0xd1ed0, 0xd1ed2, 0xd1ed4, 0xd1ed6, 0xd1ed8, - 0xd1eda, 0xd1edc, 0xd1ede, 0xd1ee0, 0xd1ee2, 0xd1ee4, 0xd1ee6, 0xd1ee8, 0xd1eea, - 0xd1eec, 0xd1eee, 0xd1ef0, 0xd1ef2, 0xd1ef4, 0xd1ef6, 0xd1ef8, 0xd1efa, 0xd1efc, - 0xd1efe, 0xd1f59, 0xd1f5b, 0xd1f5d, 0xd1f5f, 0xd2102, 0xd2107, 0xd2115, 0xd2124, - 0xd2126, 0xd2128, 0xd213e, 0xd213f, 0xd2145, 0xd2183, 0xd2c60, 0xd2c67, 0xd2c69, - 0xd2c6b, 0xd2c72, 0xd2c75, 0xd2c82, 0xd2c84, 0xd2c86, 0xd2c88, 0xd2c8a, 0xd2c8c, - 0xd2c8e, 0xd2c90, 0xd2c92, 0xd2c94, 0xd2c96, 0xd2c98, 0xd2c9a, 0xd2c9c, 0xd2c9e, - 0xd2ca0, 0xd2ca2, 0xd2ca4, 0xd2ca6, 0xd2ca8, 0xd2caa, 0xd2cac, 0xd2cae, 0xd2cb0, - 0xd2cb2, 0xd2cb4, 0xd2cb6, 0xd2cb8, 0xd2cba, 0xd2cbc, 0xd2cbe, 0xd2cc0, 0xd2cc2, - 0xd2cc4, 0xd2cc6, 0xd2cc8, 0xd2cca, 0xd2ccc, 0xd2cce, 0xd2cd0, 0xd2cd2, 0xd2cd4, - 0xd2cd6, 0xd2cd8, 0xd2cda, 0xd2cdc, 0xd2cde, 0xd2ce0, 0xd2ce2, 0xd2ceb, 0xd2ced, - 0xd2cf2, 0xda640, 0xda642, 0xda644, 0xda646, 0xda648, 0xda64a, 0xda64c, 0xda64e, - 0xda650, 0xda652, 0xda654, 0xda656, 0xda658, 0xda65a, 0xda65c, 0xda65e, 0xda660, - 0xda662, 0xda664, 0xda666, 0xda668, 0xda66a, 0xda66c, 0xda680, 0xda682, 0xda684, - 0xda686, 0xda688, 0xda68a, 0xda68c, 0xda68e, 0xda690, 0xda692, 0xda694, 0xda696, - 0xda698, 0xda69a, 0xda722, 0xda724, 0xda726, 0xda728, 0xda72a, 0xda72c, 0xda72e, - 0xda732, 0xda734, 0xda736, 0xda738, 0xda73a, 0xda73c, 0xda73e, 0xda740, 0xda742, - 0xda744, 0xda746, 0xda748, 0xda74a, 0xda74c, 0xda74e, 0xda750, 0xda752, 0xda754, - 0xda756, 0xda758, 0xda75a, 0xda75c, 0xda75e, 0xda760, 0xda762, 0xda764, 0xda766, - 0xda768, 0xda76a, 0xda76c, 0xda76e, 0xda779, 0xda77b, 0xda77d, 0xda77e, 0xda780, - 0xda782, 0xda784, 0xda786, 0xda78b, 0xda78d, 0xda790, 0xda792, 0xda796, 0xda798, - 0xda79a, 0xda79c, 0xda79e, 0xda7a0, 0xda7a2, 0xda7a4, 0xda7a6, 0xda7a8, 0xda7b6, - 0xe0100, 0xe0102, 0xe0104, 0xe0106, 0xe0108, 0xe010a, 0xe010c, 0xe010e, 0xe0110, - 0xe0112, 0xe0114, 0xe0116, 0xe0118, 0xe011a, 0xe011c, 0xe011e, 0xe0120, 0xe0122, - 0xe0124, 0xe0126, 0xe0128, 0xe012a, 0xe012c, 0xe012e, 0xe0130, 0xe0132, 0xe0134, - 0xe0136, 0xe0139, 0xe013b, 0xe013d, 0xe013f, 0xe0141, 0xe0143, 0xe0145, 0xe0147, - 0xe014a, 0xe014c, 0xe014e, 0xe0150, 0xe0152, 0xe0154, 0xe0156, 0xe0158, 0xe015a, - 0xe015c, 0xe015e, 0xe0160, 0xe0162, 0xe0164, 0xe0166, 0xe0168, 0xe016a, 0xe016c, - 0xe016e, 0xe0170, 0xe0172, 0xe0174, 0xe0176, 0xe0178, 0xe0179, 0xe017b, 0xe017d, - 0xe0181, 0xe0182, 0xe0184, 0xe0186, 0xe0187, 0xe0193, 0xe0194, 0xe019c, 0xe019d, - 0xe019f, 0xe01a0, 0xe01a2, 0xe01a4, 0xe01a6, 0xe01a7, 0xe01a9, 0xe01ac, 0xe01ae, - 0xe01af, 0xe01b5, 0xe01b7, 0xe01b8, 0xe01bc, 0xe01c4, 0xe01c7, 0xe01ca, 0xe01cd, - 0xe01cf, 0xe01d1, 0xe01d3, 0xe01d5, 0xe01d7, 0xe01d9, 0xe01db, 0xe01de, 0xe01e0, - 0xe01e2, 0xe01e4, 0xe01e6, 0xe01e8, 0xe01ea, 0xe01ec, 0xe01ee, 0xe01f1, 0xe01f4, - 0xe01fa, 0xe01fc, 0xe01fe, 0xe0200, 0xe0202, 0xe0204, 0xe0206, 0xe0208, 0xe020a, - 0xe020c, 0xe020e, 0xe0210, 0xe0212, 0xe0214, 0xe0216, 0xe0218, 0xe021a, 0xe021c, - 0xe021e, 0xe0220, 0xe0222, 0xe0224, 0xe0226, 0xe0228, 0xe022a, 0xe022c, 0xe022e, - 0xe0230, 0xe0232, 0xe023a, 0xe023b, 0xe023d, 0xe023e, 0xe0241, 0xe0248, 0xe024a, - 0xe024c, 0xe024e, 0xe0370, 0xe0372, 0xe0376, 0xe037f, 0xe0386, 0xe038c, 0xe038e, - 0xe038f, 0xe03cf, 0xe03d8, 0xe03da, 0xe03dc, 0xe03de, 0xe03e0, 0xe03e2, 0xe03e4, - 0xe03e6, 0xe03e8, 0xe03ea, 0xe03ec, 0xe03ee, 0xe03f4, 0xe03f7, 0xe03f9, 0xe03fa, - 0xe0460, 0xe0462, 0xe0464, 0xe0466, 0xe0468, 0xe046a, 0xe046c, 0xe046e, 0xe0470, - 0xe0472, 0xe0474, 0xe0476, 0xe0478, 0xe047a, 0xe047c, 0xe047e, 0xe0480, 0xe048a, - 0xe048c, 0xe048e, 0xe0490, 0xe0492, 0xe0494, 0xe0496, 0xe0498, 0xe049a, 0xe049c, - 0xe049e, 0xe04a0, 0xe04a2, 0xe04a4, 0xe04a6, 0xe04a8, 0xe04aa, 0xe04ac, 0xe04ae, - 0xe04b0, 0xe04b2, 0xe04b4, 0xe04b6, 0xe04b8, 0xe04ba, 0xe04bc, 0xe04be, 0xe04c0, - 0xe04c1, 0xe04c3, 0xe04c5, 0xe04c7, 0xe04c9, 0xe04cb, 0xe04cd, 0xe04d0, 0xe04d2, - 0xe04d4, 0xe04d6, 0xe04d8, 0xe04da, 0xe04dc, 0xe04de, 0xe04e0, 0xe04e2, 0xe04e4, - 0xe04e6, 0xe04e8, 0xe04ea, 0xe04ec, 0xe04ee, 0xe04f0, 0xe04f2, 0xe04f4, 0xe04f6, - 0xe04f8, 0xe04fa, 0xe04fc, 0xe04fe, 0xe0500, 0xe0502, 0xe0504, 0xe0506, 0xe0508, - 0xe050a, 0xe050c, 0xe050e, 0xe0510, 0xe0512, 0xe0514, 0xe0516, 0xe0518, 0xe051a, - 0xe051c, 0xe051e, 0xe0520, 0xe0522, 0xe0524, 0xe0526, 0xe0528, 0xe052a, 0xe052c, - 0xe052e, 0xe10c7, 0xe10cd, 0xe1e00, 0xe1e02, 0xe1e04, 0xe1e06, 0xe1e08, 0xe1e0a, - 0xe1e0c, 0xe1e0e, 0xe1e10, 0xe1e12, 0xe1e14, 0xe1e16, 0xe1e18, 0xe1e1a, 0xe1e1c, - 0xe1e1e, 0xe1e20, 0xe1e22, 0xe1e24, 0xe1e26, 0xe1e28, 0xe1e2a, 0xe1e2c, 0xe1e2e, - 0xe1e30, 0xe1e32, 0xe1e34, 0xe1e36, 0xe1e38, 0xe1e3a, 0xe1e3c, 0xe1e3e, 0xe1e40, - 0xe1e42, 0xe1e44, 0xe1e46, 0xe1e48, 0xe1e4a, 0xe1e4c, 0xe1e4e, 0xe1e50, 0xe1e52, - 0xe1e54, 0xe1e56, 0xe1e58, 0xe1e5a, 0xe1e5c, 0xe1e5e, 0xe1e60, 0xe1e62, 0xe1e64, - 0xe1e66, 0xe1e68, 0xe1e6a, 0xe1e6c, 0xe1e6e, 0xe1e70, 0xe1e72, 0xe1e74, 0xe1e76, - 0xe1e78, 0xe1e7a, 0xe1e7c, 0xe1e7e, 0xe1e80, 0xe1e82, 0xe1e84, 0xe1e86, 0xe1e88, - 0xe1e8a, 0xe1e8c, 0xe1e8e, 0xe1e90, 0xe1e92, 0xe1e94, 0xe1e9e, 0xe1ea0, 0xe1ea2, - 0xe1ea4, 0xe1ea6, 0xe1ea8, 0xe1eaa, 0xe1eac, 0xe1eae, 0xe1eb0, 0xe1eb2, 0xe1eb4, - 0xe1eb6, 0xe1eb8, 0xe1eba, 0xe1ebc, 0xe1ebe, 0xe1ec0, 0xe1ec2, 0xe1ec4, 0xe1ec6, - 0xe1ec8, 0xe1eca, 0xe1ecc, 0xe1ece, 0xe1ed0, 0xe1ed2, 0xe1ed4, 0xe1ed6, 0xe1ed8, - 0xe1eda, 0xe1edc, 0xe1ede, 0xe1ee0, 0xe1ee2, 0xe1ee4, 0xe1ee6, 0xe1ee8, 0xe1eea, - 0xe1eec, 0xe1eee, 0xe1ef0, 0xe1ef2, 0xe1ef4, 0xe1ef6, 0xe1ef8, 0xe1efa, 0xe1efc, - 0xe1efe, 0xe1f59, 0xe1f5b, 0xe1f5d, 0xe1f5f, 0xe2102, 0xe2107, 0xe2115, 0xe2124, - 0xe2126, 0xe2128, 0xe213e, 0xe213f, 0xe2145, 0xe2183, 0xe2c60, 0xe2c67, 0xe2c69, - 0xe2c6b, 0xe2c72, 0xe2c75, 0xe2c82, 0xe2c84, 0xe2c86, 0xe2c88, 0xe2c8a, 0xe2c8c, - 0xe2c8e, 0xe2c90, 0xe2c92, 0xe2c94, 0xe2c96, 0xe2c98, 0xe2c9a, 0xe2c9c, 0xe2c9e, - 0xe2ca0, 0xe2ca2, 0xe2ca4, 0xe2ca6, 0xe2ca8, 0xe2caa, 0xe2cac, 0xe2cae, 0xe2cb0, - 0xe2cb2, 0xe2cb4, 0xe2cb6, 0xe2cb8, 0xe2cba, 0xe2cbc, 0xe2cbe, 0xe2cc0, 0xe2cc2, - 0xe2cc4, 0xe2cc6, 0xe2cc8, 0xe2cca, 0xe2ccc, 0xe2cce, 0xe2cd0, 0xe2cd2, 0xe2cd4, - 0xe2cd6, 0xe2cd8, 0xe2cda, 0xe2cdc, 0xe2cde, 0xe2ce0, 0xe2ce2, 0xe2ceb, 0xe2ced, - 0xe2cf2, 0xea640, 0xea642, 0xea644, 0xea646, 0xea648, 0xea64a, 0xea64c, 0xea64e, - 0xea650, 0xea652, 0xea654, 0xea656, 0xea658, 0xea65a, 0xea65c, 0xea65e, 0xea660, - 0xea662, 0xea664, 0xea666, 0xea668, 0xea66a, 0xea66c, 0xea680, 0xea682, 0xea684, - 0xea686, 0xea688, 0xea68a, 0xea68c, 0xea68e, 0xea690, 0xea692, 0xea694, 0xea696, - 0xea698, 0xea69a, 0xea722, 0xea724, 0xea726, 0xea728, 0xea72a, 0xea72c, 0xea72e, - 0xea732, 0xea734, 0xea736, 0xea738, 0xea73a, 0xea73c, 0xea73e, 0xea740, 0xea742, - 0xea744, 0xea746, 0xea748, 0xea74a, 0xea74c, 0xea74e, 0xea750, 0xea752, 0xea754, - 0xea756, 0xea758, 0xea75a, 0xea75c, 0xea75e, 0xea760, 0xea762, 0xea764, 0xea766, - 0xea768, 0xea76a, 0xea76c, 0xea76e, 0xea779, 0xea77b, 0xea77d, 0xea77e, 0xea780, - 0xea782, 0xea784, 0xea786, 0xea78b, 0xea78d, 0xea790, 0xea792, 0xea796, 0xea798, - 0xea79a, 0xea79c, 0xea79e, 0xea7a0, 0xea7a2, 0xea7a4, 0xea7a6, 0xea7a8, 0xea7b6, - 0xf0100, 0xf0102, 0xf0104, 0xf0106, 0xf0108, 0xf010a, 0xf010c, 0xf010e, 0xf0110, - 0xf0112, 0xf0114, 0xf0116, 0xf0118, 0xf011a, 0xf011c, 0xf011e, 0xf0120, 0xf0122, - 0xf0124, 0xf0126, 0xf0128, 0xf012a, 0xf012c, 0xf012e, 0xf0130, 0xf0132, 0xf0134, - 0xf0136, 0xf0139, 0xf013b, 0xf013d, 0xf013f, 0xf0141, 0xf0143, 0xf0145, 0xf0147, - 0xf014a, 0xf014c, 0xf014e, 0xf0150, 0xf0152, 0xf0154, 0xf0156, 0xf0158, 0xf015a, - 0xf015c, 0xf015e, 0xf0160, 0xf0162, 0xf0164, 0xf0166, 0xf0168, 0xf016a, 0xf016c, - 0xf016e, 0xf0170, 0xf0172, 0xf0174, 0xf0176, 0xf0178, 0xf0179, 0xf017b, 0xf017d, - 0xf0181, 0xf0182, 0xf0184, 0xf0186, 0xf0187, 0xf0193, 0xf0194, 0xf019c, 0xf019d, - 0xf019f, 0xf01a0, 0xf01a2, 0xf01a4, 0xf01a6, 0xf01a7, 0xf01a9, 0xf01ac, 0xf01ae, - 0xf01af, 0xf01b5, 0xf01b7, 0xf01b8, 0xf01bc, 0xf01c4, 0xf01c7, 0xf01ca, 0xf01cd, - 0xf01cf, 0xf01d1, 0xf01d3, 0xf01d5, 0xf01d7, 0xf01d9, 0xf01db, 0xf01de, 0xf01e0, - 0xf01e2, 0xf01e4, 0xf01e6, 0xf01e8, 0xf01ea, 0xf01ec, 0xf01ee, 0xf01f1, 0xf01f4, - 0xf01fa, 0xf01fc, 0xf01fe, 0xf0200, 0xf0202, 0xf0204, 0xf0206, 0xf0208, 0xf020a, - 0xf020c, 0xf020e, 0xf0210, 0xf0212, 0xf0214, 0xf0216, 0xf0218, 0xf021a, 0xf021c, - 0xf021e, 0xf0220, 0xf0222, 0xf0224, 0xf0226, 0xf0228, 0xf022a, 0xf022c, 0xf022e, - 0xf0230, 0xf0232, 0xf023a, 0xf023b, 0xf023d, 0xf023e, 0xf0241, 0xf0248, 0xf024a, - 0xf024c, 0xf024e, 0xf0370, 0xf0372, 0xf0376, 0xf037f, 0xf0386, 0xf038c, 0xf038e, - 0xf038f, 0xf03cf, 0xf03d8, 0xf03da, 0xf03dc, 0xf03de, 0xf03e0, 0xf03e2, 0xf03e4, - 0xf03e6, 0xf03e8, 0xf03ea, 0xf03ec, 0xf03ee, 0xf03f4, 0xf03f7, 0xf03f9, 0xf03fa, - 0xf0460, 0xf0462, 0xf0464, 0xf0466, 0xf0468, 0xf046a, 0xf046c, 0xf046e, 0xf0470, - 0xf0472, 0xf0474, 0xf0476, 0xf0478, 0xf047a, 0xf047c, 0xf047e, 0xf0480, 0xf048a, - 0xf048c, 0xf048e, 0xf0490, 0xf0492, 0xf0494, 0xf0496, 0xf0498, 0xf049a, 0xf049c, - 0xf049e, 0xf04a0, 0xf04a2, 0xf04a4, 0xf04a6, 0xf04a8, 0xf04aa, 0xf04ac, 0xf04ae, - 0xf04b0, 0xf04b2, 0xf04b4, 0xf04b6, 0xf04b8, 0xf04ba, 0xf04bc, 0xf04be, 0xf04c0, - 0xf04c1, 0xf04c3, 0xf04c5, 0xf04c7, 0xf04c9, 0xf04cb, 0xf04cd, 0xf04d0, 0xf04d2, - 0xf04d4, 0xf04d6, 0xf04d8, 0xf04da, 0xf04dc, 0xf04de, 0xf04e0, 0xf04e2, 0xf04e4, - 0xf04e6, 0xf04e8, 0xf04ea, 0xf04ec, 0xf04ee, 0xf04f0, 0xf04f2, 0xf04f4, 0xf04f6, - 0xf04f8, 0xf04fa, 0xf04fc, 0xf04fe, 0xf0500, 0xf0502, 0xf0504, 0xf0506, 0xf0508, - 0xf050a, 0xf050c, 0xf050e, 0xf0510, 0xf0512, 0xf0514, 0xf0516, 0xf0518, 0xf051a, - 0xf051c, 0xf051e, 0xf0520, 0xf0522, 0xf0524, 0xf0526, 0xf0528, 0xf052a, 0xf052c, - 0xf052e, 0xf10c7, 0xf10cd, 0xf1e00, 0xf1e02, 0xf1e04, 0xf1e06, 0xf1e08, 0xf1e0a, - 0xf1e0c, 0xf1e0e, 0xf1e10, 0xf1e12, 0xf1e14, 0xf1e16, 0xf1e18, 0xf1e1a, 0xf1e1c, - 0xf1e1e, 0xf1e20, 0xf1e22, 0xf1e24, 0xf1e26, 0xf1e28, 0xf1e2a, 0xf1e2c, 0xf1e2e, - 0xf1e30, 0xf1e32, 0xf1e34, 0xf1e36, 0xf1e38, 0xf1e3a, 0xf1e3c, 0xf1e3e, 0xf1e40, - 0xf1e42, 0xf1e44, 0xf1e46, 0xf1e48, 0xf1e4a, 0xf1e4c, 0xf1e4e, 0xf1e50, 0xf1e52, - 0xf1e54, 0xf1e56, 0xf1e58, 0xf1e5a, 0xf1e5c, 0xf1e5e, 0xf1e60, 0xf1e62, 0xf1e64, - 0xf1e66, 0xf1e68, 0xf1e6a, 0xf1e6c, 0xf1e6e, 0xf1e70, 0xf1e72, 0xf1e74, 0xf1e76, - 0xf1e78, 0xf1e7a, 0xf1e7c, 0xf1e7e, 0xf1e80, 0xf1e82, 0xf1e84, 0xf1e86, 0xf1e88, - 0xf1e8a, 0xf1e8c, 0xf1e8e, 0xf1e90, 0xf1e92, 0xf1e94, 0xf1e9e, 0xf1ea0, 0xf1ea2, - 0xf1ea4, 0xf1ea6, 0xf1ea8, 0xf1eaa, 0xf1eac, 0xf1eae, 0xf1eb0, 0xf1eb2, 0xf1eb4, - 0xf1eb6, 0xf1eb8, 0xf1eba, 0xf1ebc, 0xf1ebe, 0xf1ec0, 0xf1ec2, 0xf1ec4, 0xf1ec6, - 0xf1ec8, 0xf1eca, 0xf1ecc, 0xf1ece, 0xf1ed0, 0xf1ed2, 0xf1ed4, 0xf1ed6, 0xf1ed8, - 0xf1eda, 0xf1edc, 0xf1ede, 0xf1ee0, 0xf1ee2, 0xf1ee4, 0xf1ee6, 0xf1ee8, 0xf1eea, - 0xf1eec, 0xf1eee, 0xf1ef0, 0xf1ef2, 0xf1ef4, 0xf1ef6, 0xf1ef8, 0xf1efa, 0xf1efc, - 0xf1efe, 0xf1f59, 0xf1f5b, 0xf1f5d, 0xf1f5f, 0xf2102, 0xf2107, 0xf2115, 0xf2124, - 0xf2126, 0xf2128, 0xf213e, 0xf213f, 0xf2145, 0xf2183, 0xf2c60, 0xf2c67, 0xf2c69, - 0xf2c6b, 0xf2c72, 0xf2c75, 0xf2c82, 0xf2c84, 0xf2c86, 0xf2c88, 0xf2c8a, 0xf2c8c, - 0xf2c8e, 0xf2c90, 0xf2c92, 0xf2c94, 0xf2c96, 0xf2c98, 0xf2c9a, 0xf2c9c, 0xf2c9e, - 0xf2ca0, 0xf2ca2, 0xf2ca4, 0xf2ca6, 0xf2ca8, 0xf2caa, 0xf2cac, 0xf2cae, 0xf2cb0, - 0xf2cb2, 0xf2cb4, 0xf2cb6, 0xf2cb8, 0xf2cba, 0xf2cbc, 0xf2cbe, 0xf2cc0, 0xf2cc2, - 0xf2cc4, 0xf2cc6, 0xf2cc8, 0xf2cca, 0xf2ccc, 0xf2cce, 0xf2cd0, 0xf2cd2, 0xf2cd4, - 0xf2cd6, 0xf2cd8, 0xf2cda, 0xf2cdc, 0xf2cde, 0xf2ce0, 0xf2ce2, 0xf2ceb, 0xf2ced, - 0xf2cf2, 0xfa640, 0xfa642, 0xfa644, 0xfa646, 0xfa648, 0xfa64a, 0xfa64c, 0xfa64e, - 0xfa650, 0xfa652, 0xfa654, 0xfa656, 0xfa658, 0xfa65a, 0xfa65c, 0xfa65e, 0xfa660, - 0xfa662, 0xfa664, 0xfa666, 0xfa668, 0xfa66a, 0xfa66c, 0xfa680, 0xfa682, 0xfa684, - 0xfa686, 0xfa688, 0xfa68a, 0xfa68c, 0xfa68e, 0xfa690, 0xfa692, 0xfa694, 0xfa696, - 0xfa698, 0xfa69a, 0xfa722, 0xfa724, 0xfa726, 0xfa728, 0xfa72a, 0xfa72c, 0xfa72e, - 0xfa732, 0xfa734, 0xfa736, 0xfa738, 0xfa73a, 0xfa73c, 0xfa73e, 0xfa740, 0xfa742, - 0xfa744, 0xfa746, 0xfa748, 0xfa74a, 0xfa74c, 0xfa74e, 0xfa750, 0xfa752, 0xfa754, - 0xfa756, 0xfa758, 0xfa75a, 0xfa75c, 0xfa75e, 0xfa760, 0xfa762, 0xfa764, 0xfa766, - 0xfa768, 0xfa76a, 0xfa76c, 0xfa76e, 0xfa779, 0xfa77b, 0xfa77d, 0xfa77e, 0xfa780, - 0xfa782, 0xfa784, 0xfa786, 0xfa78b, 0xfa78d, 0xfa790, 0xfa792, 0xfa796, 0xfa798, - 0xfa79a, 0xfa79c, 0xfa79e, 0xfa7a0, 0xfa7a2, 0xfa7a4, 0xfa7a6, 0xfa7a8, 0xfa7b6, - 0x100100, 0x100102, 0x100104, 0x100106, 0x100108, 0x10010a, 0x10010c, 0x10010e, 0x100110, - 0x100112, 0x100114, 0x100116, 0x100118, 0x10011a, 0x10011c, 0x10011e, 0x100120, 0x100122, - 0x100124, 0x100126, 0x100128, 0x10012a, 0x10012c, 0x10012e, 0x100130, 0x100132, 0x100134, - 0x100136, 0x100139, 0x10013b, 0x10013d, 0x10013f, 0x100141, 0x100143, 0x100145, 0x100147, - 0x10014a, 0x10014c, 0x10014e, 0x100150, 0x100152, 0x100154, 0x100156, 0x100158, 0x10015a, - 0x10015c, 0x10015e, 0x100160, 0x100162, 0x100164, 0x100166, 0x100168, 0x10016a, 0x10016c, - 0x10016e, 0x100170, 0x100172, 0x100174, 0x100176, 0x100178, 0x100179, 0x10017b, 0x10017d, - 0x100181, 0x100182, 0x100184, 0x100186, 0x100187, 0x100193, 0x100194, 0x10019c, 0x10019d, - 0x10019f, 0x1001a0, 0x1001a2, 0x1001a4, 0x1001a6, 0x1001a7, 0x1001a9, 0x1001ac, 0x1001ae, - 0x1001af, 0x1001b5, 0x1001b7, 0x1001b8, 0x1001bc, 0x1001c4, 0x1001c7, 0x1001ca, 0x1001cd, - 0x1001cf, 0x1001d1, 0x1001d3, 0x1001d5, 0x1001d7, 0x1001d9, 0x1001db, 0x1001de, 0x1001e0, - 0x1001e2, 0x1001e4, 0x1001e6, 0x1001e8, 0x1001ea, 0x1001ec, 0x1001ee, 0x1001f1, 0x1001f4, - 0x1001fa, 0x1001fc, 0x1001fe, 0x100200, 0x100202, 0x100204, 0x100206, 0x100208, 0x10020a, - 0x10020c, 0x10020e, 0x100210, 0x100212, 0x100214, 0x100216, 0x100218, 0x10021a, 0x10021c, - 0x10021e, 0x100220, 0x100222, 0x100224, 0x100226, 0x100228, 0x10022a, 0x10022c, 0x10022e, - 0x100230, 0x100232, 0x10023a, 0x10023b, 0x10023d, 0x10023e, 0x100241, 0x100248, 0x10024a, - 0x10024c, 0x10024e, 0x100370, 0x100372, 0x100376, 0x10037f, 0x100386, 0x10038c, 0x10038e, - 0x10038f, 0x1003cf, 0x1003d8, 0x1003da, 0x1003dc, 0x1003de, 0x1003e0, 0x1003e2, 0x1003e4, - 0x1003e6, 0x1003e8, 0x1003ea, 0x1003ec, 0x1003ee, 0x1003f4, 0x1003f7, 0x1003f9, 0x1003fa, - 0x100460, 0x100462, 0x100464, 0x100466, 0x100468, 0x10046a, 0x10046c, 0x10046e, 0x100470, - 0x100472, 0x100474, 0x100476, 0x100478, 0x10047a, 0x10047c, 0x10047e, 0x100480, 0x10048a, - 0x10048c, 0x10048e, 0x100490, 0x100492, 0x100494, 0x100496, 0x100498, 0x10049a, 0x10049c, - 0x10049e, 0x1004a0, 0x1004a2, 0x1004a4, 0x1004a6, 0x1004a8, 0x1004aa, 0x1004ac, 0x1004ae, - 0x1004b0, 0x1004b2, 0x1004b4, 0x1004b6, 0x1004b8, 0x1004ba, 0x1004bc, 0x1004be, 0x1004c0, - 0x1004c1, 0x1004c3, 0x1004c5, 0x1004c7, 0x1004c9, 0x1004cb, 0x1004cd, 0x1004d0, 0x1004d2, - 0x1004d4, 0x1004d6, 0x1004d8, 0x1004da, 0x1004dc, 0x1004de, 0x1004e0, 0x1004e2, 0x1004e4, - 0x1004e6, 0x1004e8, 0x1004ea, 0x1004ec, 0x1004ee, 0x1004f0, 0x1004f2, 0x1004f4, 0x1004f6, - 0x1004f8, 0x1004fa, 0x1004fc, 0x1004fe, 0x100500, 0x100502, 0x100504, 0x100506, 0x100508, - 0x10050a, 0x10050c, 0x10050e, 0x100510, 0x100512, 0x100514, 0x100516, 0x100518, 0x10051a, - 0x10051c, 0x10051e, 0x100520, 0x100522, 0x100524, 0x100526, 0x100528, 0x10052a, 0x10052c, - 0x10052e, 0x1010c7, 0x1010cd, 0x101e00, 0x101e02, 0x101e04, 0x101e06, 0x101e08, 0x101e0a, - 0x101e0c, 0x101e0e, 0x101e10, 0x101e12, 0x101e14, 0x101e16, 0x101e18, 0x101e1a, 0x101e1c, - 0x101e1e, 0x101e20, 0x101e22, 0x101e24, 0x101e26, 0x101e28, 0x101e2a, 0x101e2c, 0x101e2e, - 0x101e30, 0x101e32, 0x101e34, 0x101e36, 0x101e38, 0x101e3a, 0x101e3c, 0x101e3e, 0x101e40, - 0x101e42, 0x101e44, 0x101e46, 0x101e48, 0x101e4a, 0x101e4c, 0x101e4e, 0x101e50, 0x101e52, - 0x101e54, 0x101e56, 0x101e58, 0x101e5a, 0x101e5c, 0x101e5e, 0x101e60, 0x101e62, 0x101e64, - 0x101e66, 0x101e68, 0x101e6a, 0x101e6c, 0x101e6e, 0x101e70, 0x101e72, 0x101e74, 0x101e76, - 0x101e78, 0x101e7a, 0x101e7c, 0x101e7e, 0x101e80, 0x101e82, 0x101e84, 0x101e86, 0x101e88, - 0x101e8a, 0x101e8c, 0x101e8e, 0x101e90, 0x101e92, 0x101e94, 0x101e9e, 0x101ea0, 0x101ea2, - 0x101ea4, 0x101ea6, 0x101ea8, 0x101eaa, 0x101eac, 0x101eae, 0x101eb0, 0x101eb2, 0x101eb4, - 0x101eb6, 0x101eb8, 0x101eba, 0x101ebc, 0x101ebe, 0x101ec0, 0x101ec2, 0x101ec4, 0x101ec6, - 0x101ec8, 0x101eca, 0x101ecc, 0x101ece, 0x101ed0, 0x101ed2, 0x101ed4, 0x101ed6, 0x101ed8, - 0x101eda, 0x101edc, 0x101ede, 0x101ee0, 0x101ee2, 0x101ee4, 0x101ee6, 0x101ee8, 0x101eea, - 0x101eec, 0x101eee, 0x101ef0, 0x101ef2, 0x101ef4, 0x101ef6, 0x101ef8, 0x101efa, 0x101efc, - 0x101efe, 0x101f59, 0x101f5b, 0x101f5d, 0x101f5f, 0x102102, 0x102107, 0x102115, 0x102124, - 0x102126, 0x102128, 0x10213e, 0x10213f, 0x102145, 0x102183, 0x102c60, 0x102c67, 0x102c69, - 0x102c6b, 0x102c72, 0x102c75, 0x102c82, 0x102c84, 0x102c86, 0x102c88, 0x102c8a, 0x102c8c, - 0x102c8e, 0x102c90, 0x102c92, 0x102c94, 0x102c96, 0x102c98, 0x102c9a, 0x102c9c, 0x102c9e, - 0x102ca0, 0x102ca2, 0x102ca4, 0x102ca6, 0x102ca8, 0x102caa, 0x102cac, 0x102cae, 0x102cb0, - 0x102cb2, 0x102cb4, 0x102cb6, 0x102cb8, 0x102cba, 0x102cbc, 0x102cbe, 0x102cc0, 0x102cc2, - 0x102cc4, 0x102cc6, 0x102cc8, 0x102cca, 0x102ccc, 0x102cce, 0x102cd0, 0x102cd2, 0x102cd4, - 0x102cd6, 0x102cd8, 0x102cda, 0x102cdc, 0x102cde, 0x102ce0, 0x102ce2, 0x102ceb, 0x102ced, - 0x102cf2, 0x10a640, 0x10a642, 0x10a644, 0x10a646, 0x10a648, 0x10a64a, 0x10a64c, 0x10a64e, - 0x10a650, 0x10a652, 0x10a654, 0x10a656, 0x10a658, 0x10a65a, 0x10a65c, 0x10a65e, 0x10a660, - 0x10a662, 0x10a664, 0x10a666, 0x10a668, 0x10a66a, 0x10a66c, 0x10a680, 0x10a682, 0x10a684, - 0x10a686, 0x10a688, 0x10a68a, 0x10a68c, 0x10a68e, 0x10a690, 0x10a692, 0x10a694, 0x10a696, - 0x10a698, 0x10a69a, 0x10a722, 0x10a724, 0x10a726, 0x10a728, 0x10a72a, 0x10a72c, 0x10a72e, - 0x10a732, 0x10a734, 0x10a736, 0x10a738, 0x10a73a, 0x10a73c, 0x10a73e, 0x10a740, 0x10a742, - 0x10a744, 0x10a746, 0x10a748, 0x10a74a, 0x10a74c, 0x10a74e, 0x10a750, 0x10a752, 0x10a754, - 0x10a756, 0x10a758, 0x10a75a, 0x10a75c, 0x10a75e, 0x10a760, 0x10a762, 0x10a764, 0x10a766, - 0x10a768, 0x10a76a, 0x10a76c, 0x10a76e, 0x10a779, 0x10a77b, 0x10a77d, 0x10a77e, 0x10a780, - 0x10a782, 0x10a784, 0x10a786, 0x10a78b, 0x10a78d, 0x10a790, 0x10a792, 0x10a796, 0x10a798, - 0x10a79a, 0x10a79c, 0x10a79e, 0x10a7a0, 0x10a7a2, 0x10a7a4, 0x10a7a6, 0x10a7a8, 0x10a7b6 + ,0x1d49c, 0x1d49e, 0x1d49f, 0x1d4a2, 0x1d4a5, 0x1d4a6, 0x1d504, 0x1d505, 0x1d538, + 0x1d539, 0x1d546, 0x1d7ca #endif }; @@ -4944,6 +684,10 @@ static const crange graphRangeTable[] = { {0xaadb, 0xaaf6}, {0xab01, 0xab06}, {0xab09, 0xab0e}, {0xab11, 0xab16}, {0xab20, 0xab26}, {0xab28, 0xab2e}, {0xab30, 0xab65}, {0xab70, 0xabed}, {0xabf0, 0xabf9}, {0xac00, 0xd7a3}, {0xd7b0, 0xd7c6}, {0xd7cb, 0xd7fb}, + {0xdc00, 0xdc3e}, {0xdc40, 0xdc7e}, {0xdc80, 0xdcbe}, {0xdcc0, 0xdcfe}, + {0xdd00, 0xdd3e}, {0xdd40, 0xdd7e}, {0xdd80, 0xddbe}, {0xddc0, 0xddfe}, + {0xde00, 0xde3e}, {0xde40, 0xde7e}, {0xde80, 0xdebe}, {0xdec0, 0xdefe}, + {0xdf00, 0xdf3e}, {0xdf40, 0xdf7e}, {0xdf80, 0xdfbe}, {0xdfc0, 0xdffe}, {0xf900, 0xfa6d}, {0xfa70, 0xfad9}, {0xfb00, 0xfb06}, {0xfb13, 0xfb17}, {0xfb1d, 0xfb36}, {0xfb38, 0xfb3c}, {0xfb46, 0xfbc1}, {0xfbd3, 0xfd3f}, {0xfd50, 0xfd8f}, {0xfd92, 0xfdc7}, {0xfdf0, 0xfdfd}, {0xfe00, 0xfe19}, @@ -4951,1222 +695,64 @@ static const crange graphRangeTable[] = { {0xfe76, 0xfefc}, {0xff01, 0xffbe}, {0xffc2, 0xffc7}, {0xffca, 0xffcf}, {0xffd2, 0xffd7}, {0xffda, 0xffdc}, {0xffe0, 0xffe6}, {0xffe8, 0xffee} #if TCL_UTF_MAX > 4 - ,{0x10021, 0x1007e}, {0x100a1, 0x100ac}, {0x100ae, 0x10377}, {0x1037a, 0x1037f}, - {0x10384, 0x1038a}, {0x1038e, 0x103a1}, {0x103a3, 0x1052f}, {0x10531, 0x10556}, - {0x10559, 0x1055f}, {0x10561, 0x10587}, {0x1058d, 0x1058f}, {0x10591, 0x105c7}, - {0x105d0, 0x105ea}, {0x105f0, 0x105f4}, {0x10606, 0x1061b}, {0x1061e, 0x106dc}, - {0x106de, 0x1070d}, {0x10710, 0x1074a}, {0x1074d, 0x107b1}, {0x107c0, 0x107fa}, - {0x10800, 0x1082d}, {0x10830, 0x1083e}, {0x10840, 0x1085b}, {0x10860, 0x1086a}, - {0x108a0, 0x108b4}, {0x108b6, 0x108bd}, {0x108d4, 0x108e1}, {0x108e3, 0x10983}, - {0x10985, 0x1098c}, {0x10993, 0x109a8}, {0x109aa, 0x109b0}, {0x109b6, 0x109b9}, - {0x109bc, 0x109c4}, {0x109cb, 0x109ce}, {0x109df, 0x109e3}, {0x109e6, 0x109fd}, - {0x10a01, 0x10a03}, {0x10a05, 0x10a0a}, {0x10a13, 0x10a28}, {0x10a2a, 0x10a30}, - {0x10a3e, 0x10a42}, {0x10a4b, 0x10a4d}, {0x10a59, 0x10a5c}, {0x10a66, 0x10a75}, - {0x10a81, 0x10a83}, {0x10a85, 0x10a8d}, {0x10a8f, 0x10a91}, {0x10a93, 0x10aa8}, - {0x10aaa, 0x10ab0}, {0x10ab5, 0x10ab9}, {0x10abc, 0x10ac5}, {0x10ac7, 0x10ac9}, - {0x10acb, 0x10acd}, {0x10ae0, 0x10ae3}, {0x10ae6, 0x10af1}, {0x10af9, 0x10aff}, - {0x10b01, 0x10b03}, {0x10b05, 0x10b0c}, {0x10b13, 0x10b28}, {0x10b2a, 0x10b30}, - {0x10b35, 0x10b39}, {0x10b3c, 0x10b44}, {0x10b4b, 0x10b4d}, {0x10b5f, 0x10b63}, - {0x10b66, 0x10b77}, {0x10b85, 0x10b8a}, {0x10b8e, 0x10b90}, {0x10b92, 0x10b95}, - {0x10ba8, 0x10baa}, {0x10bae, 0x10bb9}, {0x10bbe, 0x10bc2}, {0x10bc6, 0x10bc8}, - {0x10bca, 0x10bcd}, {0x10be6, 0x10bfa}, {0x10c00, 0x10c03}, {0x10c05, 0x10c0c}, - {0x10c0e, 0x10c10}, {0x10c12, 0x10c28}, {0x10c2a, 0x10c39}, {0x10c3d, 0x10c44}, - {0x10c46, 0x10c48}, {0x10c4a, 0x10c4d}, {0x10c58, 0x10c5a}, {0x10c60, 0x10c63}, - {0x10c66, 0x10c6f}, {0x10c78, 0x10c83}, {0x10c85, 0x10c8c}, {0x10c8e, 0x10c90}, - {0x10c92, 0x10ca8}, {0x10caa, 0x10cb3}, {0x10cb5, 0x10cb9}, {0x10cbc, 0x10cc4}, - {0x10cc6, 0x10cc8}, {0x10cca, 0x10ccd}, {0x10ce0, 0x10ce3}, {0x10ce6, 0x10cef}, - {0x10d00, 0x10d03}, {0x10d05, 0x10d0c}, {0x10d0e, 0x10d10}, {0x10d12, 0x10d44}, - {0x10d46, 0x10d48}, {0x10d4a, 0x10d4f}, {0x10d54, 0x10d63}, {0x10d66, 0x10d7f}, - {0x10d85, 0x10d96}, {0x10d9a, 0x10db1}, {0x10db3, 0x10dbb}, {0x10dc0, 0x10dc6}, - {0x10dcf, 0x10dd4}, {0x10dd8, 0x10ddf}, {0x10de6, 0x10def}, {0x10df2, 0x10df4}, - {0x10e01, 0x10e3a}, {0x10e3f, 0x10e5b}, {0x10e94, 0x10e97}, {0x10e99, 0x10e9f}, - {0x10ea1, 0x10ea3}, {0x10ead, 0x10eb9}, {0x10ebb, 0x10ebd}, {0x10ec0, 0x10ec4}, - {0x10ec8, 0x10ecd}, {0x10ed0, 0x10ed9}, {0x10edc, 0x10edf}, {0x10f00, 0x10f47}, - {0x10f49, 0x10f6c}, {0x10f71, 0x10f97}, {0x10f99, 0x10fbc}, {0x10fbe, 0x10fcc}, - {0x10fce, 0x10fda}, {0x11000, 0x110c5}, {0x110d0, 0x11248}, {0x1124a, 0x1124d}, - {0x11250, 0x11256}, {0x1125a, 0x1125d}, {0x11260, 0x11288}, {0x1128a, 0x1128d}, - {0x11290, 0x112b0}, {0x112b2, 0x112b5}, {0x112b8, 0x112be}, {0x112c2, 0x112c5}, - {0x112c8, 0x112d6}, {0x112d8, 0x11310}, {0x11312, 0x11315}, {0x11318, 0x1135a}, - {0x1135d, 0x1137c}, {0x11380, 0x11399}, {0x113a0, 0x113f5}, {0x113f8, 0x113fd}, - {0x11400, 0x1167f}, {0x11681, 0x1169c}, {0x116a0, 0x116f8}, {0x11700, 0x1170c}, - {0x1170e, 0x11714}, {0x11720, 0x11736}, {0x11740, 0x11753}, {0x11760, 0x1176c}, - {0x1176e, 0x11770}, {0x11780, 0x117dd}, {0x117e0, 0x117e9}, {0x117f0, 0x117f9}, - {0x11800, 0x1180d}, {0x11810, 0x11819}, {0x11820, 0x11877}, {0x11880, 0x118aa}, - {0x118b0, 0x118f5}, {0x11900, 0x1191e}, {0x11920, 0x1192b}, {0x11930, 0x1193b}, - {0x11944, 0x1196d}, {0x11970, 0x11974}, {0x11980, 0x119ab}, {0x119b0, 0x119c9}, - {0x119d0, 0x119da}, {0x119de, 0x11a1b}, {0x11a1e, 0x11a5e}, {0x11a60, 0x11a7c}, - {0x11a7f, 0x11a89}, {0x11a90, 0x11a99}, {0x11aa0, 0x11aad}, {0x11ab0, 0x11abe}, - {0x11b00, 0x11b4b}, {0x11b50, 0x11b7c}, {0x11b80, 0x11bf3}, {0x11bfc, 0x11c37}, - {0x11c3b, 0x11c49}, {0x11c4d, 0x11c88}, {0x11cc0, 0x11cc7}, {0x11cd0, 0x11cf9}, - {0x11d00, 0x11df9}, {0x11dfb, 0x11f15}, {0x11f18, 0x11f1d}, {0x11f20, 0x11f45}, - {0x11f48, 0x11f4d}, {0x11f50, 0x11f57}, {0x11f5f, 0x11f7d}, {0x11f80, 0x11fb4}, - {0x11fb6, 0x11fc4}, {0x11fc6, 0x11fd3}, {0x11fd6, 0x11fdb}, {0x11fdd, 0x11fef}, - {0x11ff2, 0x11ff4}, {0x11ff6, 0x11ffe}, {0x12010, 0x12027}, {0x12030, 0x1205e}, - {0x12074, 0x1208e}, {0x12090, 0x1209c}, {0x120a0, 0x120bf}, {0x120d0, 0x120f0}, - {0x12100, 0x1218b}, {0x12190, 0x12426}, {0x12440, 0x1244a}, {0x12460, 0x12b73}, - {0x12b76, 0x12b95}, {0x12b98, 0x12bb9}, {0x12bbd, 0x12bc8}, {0x12bca, 0x12bd2}, - {0x12bec, 0x12bef}, {0x12c00, 0x12c2e}, {0x12c30, 0x12c5e}, {0x12c60, 0x12cf3}, - {0x12cf9, 0x12d25}, {0x12d30, 0x12d67}, {0x12d7f, 0x12d96}, {0x12da0, 0x12da6}, - {0x12da8, 0x12dae}, {0x12db0, 0x12db6}, {0x12db8, 0x12dbe}, {0x12dc0, 0x12dc6}, - {0x12dc8, 0x12dce}, {0x12dd0, 0x12dd6}, {0x12dd8, 0x12dde}, {0x12de0, 0x12e49}, - {0x12e80, 0x12e99}, {0x12e9b, 0x12ef3}, {0x12f00, 0x12fd5}, {0x12ff0, 0x12ffb}, - {0x13001, 0x1303f}, {0x13041, 0x13096}, {0x13099, 0x130ff}, {0x13105, 0x1312e}, - {0x13131, 0x1318e}, {0x13190, 0x131ba}, {0x131c0, 0x131e3}, {0x131f0, 0x1321e}, - {0x13220, 0x132fe}, {0x13300, 0x14db5}, {0x14dc0, 0x19fea}, {0x1a000, 0x1a48c}, - {0x1a490, 0x1a4c6}, {0x1a4d0, 0x1a62b}, {0x1a640, 0x1a6f7}, {0x1a700, 0x1a7ae}, - {0x1a7b0, 0x1a7b7}, {0x1a7f7, 0x1a82b}, {0x1a830, 0x1a839}, {0x1a840, 0x1a877}, - {0x1a880, 0x1a8c5}, {0x1a8ce, 0x1a8d9}, {0x1a8e0, 0x1a8fd}, {0x1a900, 0x1a953}, - {0x1a95f, 0x1a97c}, {0x1a980, 0x1a9cd}, {0x1a9cf, 0x1a9d9}, {0x1a9de, 0x1a9fe}, - {0x1aa00, 0x1aa36}, {0x1aa40, 0x1aa4d}, {0x1aa50, 0x1aa59}, {0x1aa5c, 0x1aac2}, - {0x1aadb, 0x1aaf6}, {0x1ab01, 0x1ab06}, {0x1ab09, 0x1ab0e}, {0x1ab11, 0x1ab16}, - {0x1ab20, 0x1ab26}, {0x1ab28, 0x1ab2e}, {0x1ab30, 0x1ab65}, {0x1ab70, 0x1abed}, - {0x1abf0, 0x1abf9}, {0x1ac00, 0x1d7a3}, {0x1d7b0, 0x1d7c6}, {0x1d7cb, 0x1d7fb}, - {0x1f900, 0x1fa6d}, {0x1fa70, 0x1fad9}, {0x1fb00, 0x1fb06}, {0x1fb13, 0x1fb17}, - {0x1fb1d, 0x1fb36}, {0x1fb38, 0x1fb3c}, {0x1fb46, 0x1fbc1}, {0x1fbd3, 0x1fd3f}, - {0x1fd50, 0x1fd8f}, {0x1fd92, 0x1fdc7}, {0x1fdf0, 0x1fdfd}, {0x1fe00, 0x1fe19}, - {0x1fe20, 0x1fe52}, {0x1fe54, 0x1fe66}, {0x1fe68, 0x1fe6b}, {0x1fe70, 0x1fe74}, - {0x1fe76, 0x1fefc}, {0x1ff01, 0x1ffbe}, {0x1ffc2, 0x1ffc7}, {0x1ffca, 0x1ffcf}, - {0x1ffd2, 0x1ffd7}, {0x1ffda, 0x1ffdc}, {0x1ffe0, 0x1ffe6}, {0x1ffe8, 0x1ffee}, - {0x20021, 0x2007e}, {0x200a1, 0x200ac}, {0x200ae, 0x20377}, {0x2037a, 0x2037f}, - {0x20384, 0x2038a}, {0x2038e, 0x203a1}, {0x203a3, 0x2052f}, {0x20531, 0x20556}, - {0x20559, 0x2055f}, {0x20561, 0x20587}, {0x2058d, 0x2058f}, {0x20591, 0x205c7}, - {0x205d0, 0x205ea}, {0x205f0, 0x205f4}, {0x20606, 0x2061b}, {0x2061e, 0x206dc}, - {0x206de, 0x2070d}, {0x20710, 0x2074a}, {0x2074d, 0x207b1}, {0x207c0, 0x207fa}, - {0x20800, 0x2082d}, {0x20830, 0x2083e}, {0x20840, 0x2085b}, {0x20860, 0x2086a}, - {0x208a0, 0x208b4}, {0x208b6, 0x208bd}, {0x208d4, 0x208e1}, {0x208e3, 0x20983}, - {0x20985, 0x2098c}, {0x20993, 0x209a8}, {0x209aa, 0x209b0}, {0x209b6, 0x209b9}, - {0x209bc, 0x209c4}, {0x209cb, 0x209ce}, {0x209df, 0x209e3}, {0x209e6, 0x209fd}, - {0x20a01, 0x20a03}, {0x20a05, 0x20a0a}, {0x20a13, 0x20a28}, {0x20a2a, 0x20a30}, - {0x20a3e, 0x20a42}, {0x20a4b, 0x20a4d}, {0x20a59, 0x20a5c}, {0x20a66, 0x20a75}, - {0x20a81, 0x20a83}, {0x20a85, 0x20a8d}, {0x20a8f, 0x20a91}, {0x20a93, 0x20aa8}, - {0x20aaa, 0x20ab0}, {0x20ab5, 0x20ab9}, {0x20abc, 0x20ac5}, {0x20ac7, 0x20ac9}, - {0x20acb, 0x20acd}, {0x20ae0, 0x20ae3}, {0x20ae6, 0x20af1}, {0x20af9, 0x20aff}, - {0x20b01, 0x20b03}, {0x20b05, 0x20b0c}, {0x20b13, 0x20b28}, {0x20b2a, 0x20b30}, - {0x20b35, 0x20b39}, {0x20b3c, 0x20b44}, {0x20b4b, 0x20b4d}, {0x20b5f, 0x20b63}, - {0x20b66, 0x20b77}, {0x20b85, 0x20b8a}, {0x20b8e, 0x20b90}, {0x20b92, 0x20b95}, - {0x20ba8, 0x20baa}, {0x20bae, 0x20bb9}, {0x20bbe, 0x20bc2}, {0x20bc6, 0x20bc8}, - {0x20bca, 0x20bcd}, {0x20be6, 0x20bfa}, {0x20c00, 0x20c03}, {0x20c05, 0x20c0c}, - {0x20c0e, 0x20c10}, {0x20c12, 0x20c28}, {0x20c2a, 0x20c39}, {0x20c3d, 0x20c44}, - {0x20c46, 0x20c48}, {0x20c4a, 0x20c4d}, {0x20c58, 0x20c5a}, {0x20c60, 0x20c63}, - {0x20c66, 0x20c6f}, {0x20c78, 0x20c83}, {0x20c85, 0x20c8c}, {0x20c8e, 0x20c90}, - {0x20c92, 0x20ca8}, {0x20caa, 0x20cb3}, {0x20cb5, 0x20cb9}, {0x20cbc, 0x20cc4}, - {0x20cc6, 0x20cc8}, {0x20cca, 0x20ccd}, {0x20ce0, 0x20ce3}, {0x20ce6, 0x20cef}, - {0x20d00, 0x20d03}, {0x20d05, 0x20d0c}, {0x20d0e, 0x20d10}, {0x20d12, 0x20d44}, - {0x20d46, 0x20d48}, {0x20d4a, 0x20d4f}, {0x20d54, 0x20d63}, {0x20d66, 0x20d7f}, - {0x20d85, 0x20d96}, {0x20d9a, 0x20db1}, {0x20db3, 0x20dbb}, {0x20dc0, 0x20dc6}, - {0x20dcf, 0x20dd4}, {0x20dd8, 0x20ddf}, {0x20de6, 0x20def}, {0x20df2, 0x20df4}, - {0x20e01, 0x20e3a}, {0x20e3f, 0x20e5b}, {0x20e94, 0x20e97}, {0x20e99, 0x20e9f}, - {0x20ea1, 0x20ea3}, {0x20ead, 0x20eb9}, {0x20ebb, 0x20ebd}, {0x20ec0, 0x20ec4}, - {0x20ec8, 0x20ecd}, {0x20ed0, 0x20ed9}, {0x20edc, 0x20edf}, {0x20f00, 0x20f47}, - {0x20f49, 0x20f6c}, {0x20f71, 0x20f97}, {0x20f99, 0x20fbc}, {0x20fbe, 0x20fcc}, - {0x20fce, 0x20fda}, {0x21000, 0x210c5}, {0x210d0, 0x21248}, {0x2124a, 0x2124d}, - {0x21250, 0x21256}, {0x2125a, 0x2125d}, {0x21260, 0x21288}, {0x2128a, 0x2128d}, - {0x21290, 0x212b0}, {0x212b2, 0x212b5}, {0x212b8, 0x212be}, {0x212c2, 0x212c5}, - {0x212c8, 0x212d6}, {0x212d8, 0x21310}, {0x21312, 0x21315}, {0x21318, 0x2135a}, - {0x2135d, 0x2137c}, {0x21380, 0x21399}, {0x213a0, 0x213f5}, {0x213f8, 0x213fd}, - {0x21400, 0x2167f}, {0x21681, 0x2169c}, {0x216a0, 0x216f8}, {0x21700, 0x2170c}, - {0x2170e, 0x21714}, {0x21720, 0x21736}, {0x21740, 0x21753}, {0x21760, 0x2176c}, - {0x2176e, 0x21770}, {0x21780, 0x217dd}, {0x217e0, 0x217e9}, {0x217f0, 0x217f9}, - {0x21800, 0x2180d}, {0x21810, 0x21819}, {0x21820, 0x21877}, {0x21880, 0x218aa}, - {0x218b0, 0x218f5}, {0x21900, 0x2191e}, {0x21920, 0x2192b}, {0x21930, 0x2193b}, - {0x21944, 0x2196d}, {0x21970, 0x21974}, {0x21980, 0x219ab}, {0x219b0, 0x219c9}, - {0x219d0, 0x219da}, {0x219de, 0x21a1b}, {0x21a1e, 0x21a5e}, {0x21a60, 0x21a7c}, - {0x21a7f, 0x21a89}, {0x21a90, 0x21a99}, {0x21aa0, 0x21aad}, {0x21ab0, 0x21abe}, - {0x21b00, 0x21b4b}, {0x21b50, 0x21b7c}, {0x21b80, 0x21bf3}, {0x21bfc, 0x21c37}, - {0x21c3b, 0x21c49}, {0x21c4d, 0x21c88}, {0x21cc0, 0x21cc7}, {0x21cd0, 0x21cf9}, - {0x21d00, 0x21df9}, {0x21dfb, 0x21f15}, {0x21f18, 0x21f1d}, {0x21f20, 0x21f45}, - {0x21f48, 0x21f4d}, {0x21f50, 0x21f57}, {0x21f5f, 0x21f7d}, {0x21f80, 0x21fb4}, - {0x21fb6, 0x21fc4}, {0x21fc6, 0x21fd3}, {0x21fd6, 0x21fdb}, {0x21fdd, 0x21fef}, - {0x21ff2, 0x21ff4}, {0x21ff6, 0x21ffe}, {0x22010, 0x22027}, {0x22030, 0x2205e}, - {0x22074, 0x2208e}, {0x22090, 0x2209c}, {0x220a0, 0x220bf}, {0x220d0, 0x220f0}, - {0x22100, 0x2218b}, {0x22190, 0x22426}, {0x22440, 0x2244a}, {0x22460, 0x22b73}, - {0x22b76, 0x22b95}, {0x22b98, 0x22bb9}, {0x22bbd, 0x22bc8}, {0x22bca, 0x22bd2}, - {0x22bec, 0x22bef}, {0x22c00, 0x22c2e}, {0x22c30, 0x22c5e}, {0x22c60, 0x22cf3}, - {0x22cf9, 0x22d25}, {0x22d30, 0x22d67}, {0x22d7f, 0x22d96}, {0x22da0, 0x22da6}, - {0x22da8, 0x22dae}, {0x22db0, 0x22db6}, {0x22db8, 0x22dbe}, {0x22dc0, 0x22dc6}, - {0x22dc8, 0x22dce}, {0x22dd0, 0x22dd6}, {0x22dd8, 0x22dde}, {0x22de0, 0x22e49}, - {0x22e80, 0x22e99}, {0x22e9b, 0x22ef3}, {0x22f00, 0x22fd5}, {0x22ff0, 0x22ffb}, - {0x23001, 0x2303f}, {0x23041, 0x23096}, {0x23099, 0x230ff}, {0x23105, 0x2312e}, - {0x23131, 0x2318e}, {0x23190, 0x231ba}, {0x231c0, 0x231e3}, {0x231f0, 0x2321e}, - {0x23220, 0x232fe}, {0x23300, 0x24db5}, {0x24dc0, 0x29fea}, {0x2a000, 0x2a48c}, - {0x2a490, 0x2a4c6}, {0x2a4d0, 0x2a62b}, {0x2a640, 0x2a6f7}, {0x2a700, 0x2a7ae}, - {0x2a7b0, 0x2a7b7}, {0x2a7f7, 0x2a82b}, {0x2a830, 0x2a839}, {0x2a840, 0x2a877}, - {0x2a880, 0x2a8c5}, {0x2a8ce, 0x2a8d9}, {0x2a8e0, 0x2a8fd}, {0x2a900, 0x2a953}, - {0x2a95f, 0x2a97c}, {0x2a980, 0x2a9cd}, {0x2a9cf, 0x2a9d9}, {0x2a9de, 0x2a9fe}, - {0x2aa00, 0x2aa36}, {0x2aa40, 0x2aa4d}, {0x2aa50, 0x2aa59}, {0x2aa5c, 0x2aac2}, - {0x2aadb, 0x2aaf6}, {0x2ab01, 0x2ab06}, {0x2ab09, 0x2ab0e}, {0x2ab11, 0x2ab16}, - {0x2ab20, 0x2ab26}, {0x2ab28, 0x2ab2e}, {0x2ab30, 0x2ab65}, {0x2ab70, 0x2abed}, - {0x2abf0, 0x2abf9}, {0x2ac00, 0x2d7a3}, {0x2d7b0, 0x2d7c6}, {0x2d7cb, 0x2d7fb}, - {0x2f900, 0x2fa6d}, {0x2fa70, 0x2fad9}, {0x2fb00, 0x2fb06}, {0x2fb13, 0x2fb17}, - {0x2fb1d, 0x2fb36}, {0x2fb38, 0x2fb3c}, {0x2fb46, 0x2fbc1}, {0x2fbd3, 0x2fd3f}, - {0x2fd50, 0x2fd8f}, {0x2fd92, 0x2fdc7}, {0x2fdf0, 0x2fdfd}, {0x2fe00, 0x2fe19}, - {0x2fe20, 0x2fe52}, {0x2fe54, 0x2fe66}, {0x2fe68, 0x2fe6b}, {0x2fe70, 0x2fe74}, - {0x2fe76, 0x2fefc}, {0x2ff01, 0x2ffbe}, {0x2ffc2, 0x2ffc7}, {0x2ffca, 0x2ffcf}, - {0x2ffd2, 0x2ffd7}, {0x2ffda, 0x2ffdc}, {0x2ffe0, 0x2ffe6}, {0x2ffe8, 0x2ffee}, - {0x30021, 0x3007e}, {0x300a1, 0x300ac}, {0x300ae, 0x30377}, {0x3037a, 0x3037f}, - {0x30384, 0x3038a}, {0x3038e, 0x303a1}, {0x303a3, 0x3052f}, {0x30531, 0x30556}, - {0x30559, 0x3055f}, {0x30561, 0x30587}, {0x3058d, 0x3058f}, {0x30591, 0x305c7}, - {0x305d0, 0x305ea}, {0x305f0, 0x305f4}, {0x30606, 0x3061b}, {0x3061e, 0x306dc}, - {0x306de, 0x3070d}, {0x30710, 0x3074a}, {0x3074d, 0x307b1}, {0x307c0, 0x307fa}, - {0x30800, 0x3082d}, {0x30830, 0x3083e}, {0x30840, 0x3085b}, {0x30860, 0x3086a}, - {0x308a0, 0x308b4}, {0x308b6, 0x308bd}, {0x308d4, 0x308e1}, {0x308e3, 0x30983}, - {0x30985, 0x3098c}, {0x30993, 0x309a8}, {0x309aa, 0x309b0}, {0x309b6, 0x309b9}, - {0x309bc, 0x309c4}, {0x309cb, 0x309ce}, {0x309df, 0x309e3}, {0x309e6, 0x309fd}, - {0x30a01, 0x30a03}, {0x30a05, 0x30a0a}, {0x30a13, 0x30a28}, {0x30a2a, 0x30a30}, - {0x30a3e, 0x30a42}, {0x30a4b, 0x30a4d}, {0x30a59, 0x30a5c}, {0x30a66, 0x30a75}, - {0x30a81, 0x30a83}, {0x30a85, 0x30a8d}, {0x30a8f, 0x30a91}, {0x30a93, 0x30aa8}, - {0x30aaa, 0x30ab0}, {0x30ab5, 0x30ab9}, {0x30abc, 0x30ac5}, {0x30ac7, 0x30ac9}, - {0x30acb, 0x30acd}, {0x30ae0, 0x30ae3}, {0x30ae6, 0x30af1}, {0x30af9, 0x30aff}, - {0x30b01, 0x30b03}, {0x30b05, 0x30b0c}, {0x30b13, 0x30b28}, {0x30b2a, 0x30b30}, - {0x30b35, 0x30b39}, {0x30b3c, 0x30b44}, {0x30b4b, 0x30b4d}, {0x30b5f, 0x30b63}, - {0x30b66, 0x30b77}, {0x30b85, 0x30b8a}, {0x30b8e, 0x30b90}, {0x30b92, 0x30b95}, - {0x30ba8, 0x30baa}, {0x30bae, 0x30bb9}, {0x30bbe, 0x30bc2}, {0x30bc6, 0x30bc8}, - {0x30bca, 0x30bcd}, {0x30be6, 0x30bfa}, {0x30c00, 0x30c03}, {0x30c05, 0x30c0c}, - {0x30c0e, 0x30c10}, {0x30c12, 0x30c28}, {0x30c2a, 0x30c39}, {0x30c3d, 0x30c44}, - {0x30c46, 0x30c48}, {0x30c4a, 0x30c4d}, {0x30c58, 0x30c5a}, {0x30c60, 0x30c63}, - {0x30c66, 0x30c6f}, {0x30c78, 0x30c83}, {0x30c85, 0x30c8c}, {0x30c8e, 0x30c90}, - {0x30c92, 0x30ca8}, {0x30caa, 0x30cb3}, {0x30cb5, 0x30cb9}, {0x30cbc, 0x30cc4}, - {0x30cc6, 0x30cc8}, {0x30cca, 0x30ccd}, {0x30ce0, 0x30ce3}, {0x30ce6, 0x30cef}, - {0x30d00, 0x30d03}, {0x30d05, 0x30d0c}, {0x30d0e, 0x30d10}, {0x30d12, 0x30d44}, - {0x30d46, 0x30d48}, {0x30d4a, 0x30d4f}, {0x30d54, 0x30d63}, {0x30d66, 0x30d7f}, - {0x30d85, 0x30d96}, {0x30d9a, 0x30db1}, {0x30db3, 0x30dbb}, {0x30dc0, 0x30dc6}, - {0x30dcf, 0x30dd4}, {0x30dd8, 0x30ddf}, {0x30de6, 0x30def}, {0x30df2, 0x30df4}, - {0x30e01, 0x30e3a}, {0x30e3f, 0x30e5b}, {0x30e94, 0x30e97}, {0x30e99, 0x30e9f}, - {0x30ea1, 0x30ea3}, {0x30ead, 0x30eb9}, {0x30ebb, 0x30ebd}, {0x30ec0, 0x30ec4}, - {0x30ec8, 0x30ecd}, {0x30ed0, 0x30ed9}, {0x30edc, 0x30edf}, {0x30f00, 0x30f47}, - {0x30f49, 0x30f6c}, {0x30f71, 0x30f97}, {0x30f99, 0x30fbc}, {0x30fbe, 0x30fcc}, - {0x30fce, 0x30fda}, {0x31000, 0x310c5}, {0x310d0, 0x31248}, {0x3124a, 0x3124d}, - {0x31250, 0x31256}, {0x3125a, 0x3125d}, {0x31260, 0x31288}, {0x3128a, 0x3128d}, - {0x31290, 0x312b0}, {0x312b2, 0x312b5}, {0x312b8, 0x312be}, {0x312c2, 0x312c5}, - {0x312c8, 0x312d6}, {0x312d8, 0x31310}, {0x31312, 0x31315}, {0x31318, 0x3135a}, - {0x3135d, 0x3137c}, {0x31380, 0x31399}, {0x313a0, 0x313f5}, {0x313f8, 0x313fd}, - {0x31400, 0x3167f}, {0x31681, 0x3169c}, {0x316a0, 0x316f8}, {0x31700, 0x3170c}, - {0x3170e, 0x31714}, {0x31720, 0x31736}, {0x31740, 0x31753}, {0x31760, 0x3176c}, - {0x3176e, 0x31770}, {0x31780, 0x317dd}, {0x317e0, 0x317e9}, {0x317f0, 0x317f9}, - {0x31800, 0x3180d}, {0x31810, 0x31819}, {0x31820, 0x31877}, {0x31880, 0x318aa}, - {0x318b0, 0x318f5}, {0x31900, 0x3191e}, {0x31920, 0x3192b}, {0x31930, 0x3193b}, - {0x31944, 0x3196d}, {0x31970, 0x31974}, {0x31980, 0x319ab}, {0x319b0, 0x319c9}, - {0x319d0, 0x319da}, {0x319de, 0x31a1b}, {0x31a1e, 0x31a5e}, {0x31a60, 0x31a7c}, - {0x31a7f, 0x31a89}, {0x31a90, 0x31a99}, {0x31aa0, 0x31aad}, {0x31ab0, 0x31abe}, - {0x31b00, 0x31b4b}, {0x31b50, 0x31b7c}, {0x31b80, 0x31bf3}, {0x31bfc, 0x31c37}, - {0x31c3b, 0x31c49}, {0x31c4d, 0x31c88}, {0x31cc0, 0x31cc7}, {0x31cd0, 0x31cf9}, - {0x31d00, 0x31df9}, {0x31dfb, 0x31f15}, {0x31f18, 0x31f1d}, {0x31f20, 0x31f45}, - {0x31f48, 0x31f4d}, {0x31f50, 0x31f57}, {0x31f5f, 0x31f7d}, {0x31f80, 0x31fb4}, - {0x31fb6, 0x31fc4}, {0x31fc6, 0x31fd3}, {0x31fd6, 0x31fdb}, {0x31fdd, 0x31fef}, - {0x31ff2, 0x31ff4}, {0x31ff6, 0x31ffe}, {0x32010, 0x32027}, {0x32030, 0x3205e}, - {0x32074, 0x3208e}, {0x32090, 0x3209c}, {0x320a0, 0x320bf}, {0x320d0, 0x320f0}, - {0x32100, 0x3218b}, {0x32190, 0x32426}, {0x32440, 0x3244a}, {0x32460, 0x32b73}, - {0x32b76, 0x32b95}, {0x32b98, 0x32bb9}, {0x32bbd, 0x32bc8}, {0x32bca, 0x32bd2}, - {0x32bec, 0x32bef}, {0x32c00, 0x32c2e}, {0x32c30, 0x32c5e}, {0x32c60, 0x32cf3}, - {0x32cf9, 0x32d25}, {0x32d30, 0x32d67}, {0x32d7f, 0x32d96}, {0x32da0, 0x32da6}, - {0x32da8, 0x32dae}, {0x32db0, 0x32db6}, {0x32db8, 0x32dbe}, {0x32dc0, 0x32dc6}, - {0x32dc8, 0x32dce}, {0x32dd0, 0x32dd6}, {0x32dd8, 0x32dde}, {0x32de0, 0x32e49}, - {0x32e80, 0x32e99}, {0x32e9b, 0x32ef3}, {0x32f00, 0x32fd5}, {0x32ff0, 0x32ffb}, - {0x33001, 0x3303f}, {0x33041, 0x33096}, {0x33099, 0x330ff}, {0x33105, 0x3312e}, - {0x33131, 0x3318e}, {0x33190, 0x331ba}, {0x331c0, 0x331e3}, {0x331f0, 0x3321e}, - {0x33220, 0x332fe}, {0x33300, 0x34db5}, {0x34dc0, 0x39fea}, {0x3a000, 0x3a48c}, - {0x3a490, 0x3a4c6}, {0x3a4d0, 0x3a62b}, {0x3a640, 0x3a6f7}, {0x3a700, 0x3a7ae}, - {0x3a7b0, 0x3a7b7}, {0x3a7f7, 0x3a82b}, {0x3a830, 0x3a839}, {0x3a840, 0x3a877}, - {0x3a880, 0x3a8c5}, {0x3a8ce, 0x3a8d9}, {0x3a8e0, 0x3a8fd}, {0x3a900, 0x3a953}, - {0x3a95f, 0x3a97c}, {0x3a980, 0x3a9cd}, {0x3a9cf, 0x3a9d9}, {0x3a9de, 0x3a9fe}, - {0x3aa00, 0x3aa36}, {0x3aa40, 0x3aa4d}, {0x3aa50, 0x3aa59}, {0x3aa5c, 0x3aac2}, - {0x3aadb, 0x3aaf6}, {0x3ab01, 0x3ab06}, {0x3ab09, 0x3ab0e}, {0x3ab11, 0x3ab16}, - {0x3ab20, 0x3ab26}, {0x3ab28, 0x3ab2e}, {0x3ab30, 0x3ab65}, {0x3ab70, 0x3abed}, - {0x3abf0, 0x3abf9}, {0x3ac00, 0x3d7a3}, {0x3d7b0, 0x3d7c6}, {0x3d7cb, 0x3d7fb}, - {0x3f900, 0x3fa6d}, {0x3fa70, 0x3fad9}, {0x3fb00, 0x3fb06}, {0x3fb13, 0x3fb17}, - {0x3fb1d, 0x3fb36}, {0x3fb38, 0x3fb3c}, {0x3fb46, 0x3fbc1}, {0x3fbd3, 0x3fd3f}, - {0x3fd50, 0x3fd8f}, {0x3fd92, 0x3fdc7}, {0x3fdf0, 0x3fdfd}, {0x3fe00, 0x3fe19}, - {0x3fe20, 0x3fe52}, {0x3fe54, 0x3fe66}, {0x3fe68, 0x3fe6b}, {0x3fe70, 0x3fe74}, - {0x3fe76, 0x3fefc}, {0x3ff01, 0x3ffbe}, {0x3ffc2, 0x3ffc7}, {0x3ffca, 0x3ffcf}, - {0x3ffd2, 0x3ffd7}, {0x3ffda, 0x3ffdc}, {0x3ffe0, 0x3ffe6}, {0x3ffe8, 0x3ffee}, - {0x40021, 0x4007e}, {0x400a1, 0x400ac}, {0x400ae, 0x40377}, {0x4037a, 0x4037f}, - {0x40384, 0x4038a}, {0x4038e, 0x403a1}, {0x403a3, 0x4052f}, {0x40531, 0x40556}, - {0x40559, 0x4055f}, {0x40561, 0x40587}, {0x4058d, 0x4058f}, {0x40591, 0x405c7}, - {0x405d0, 0x405ea}, {0x405f0, 0x405f4}, {0x40606, 0x4061b}, {0x4061e, 0x406dc}, - {0x406de, 0x4070d}, {0x40710, 0x4074a}, {0x4074d, 0x407b1}, {0x407c0, 0x407fa}, - {0x40800, 0x4082d}, {0x40830, 0x4083e}, {0x40840, 0x4085b}, {0x40860, 0x4086a}, - {0x408a0, 0x408b4}, {0x408b6, 0x408bd}, {0x408d4, 0x408e1}, {0x408e3, 0x40983}, - {0x40985, 0x4098c}, {0x40993, 0x409a8}, {0x409aa, 0x409b0}, {0x409b6, 0x409b9}, - {0x409bc, 0x409c4}, {0x409cb, 0x409ce}, {0x409df, 0x409e3}, {0x409e6, 0x409fd}, - {0x40a01, 0x40a03}, {0x40a05, 0x40a0a}, {0x40a13, 0x40a28}, {0x40a2a, 0x40a30}, - {0x40a3e, 0x40a42}, {0x40a4b, 0x40a4d}, {0x40a59, 0x40a5c}, {0x40a66, 0x40a75}, - {0x40a81, 0x40a83}, {0x40a85, 0x40a8d}, {0x40a8f, 0x40a91}, {0x40a93, 0x40aa8}, - {0x40aaa, 0x40ab0}, {0x40ab5, 0x40ab9}, {0x40abc, 0x40ac5}, {0x40ac7, 0x40ac9}, - {0x40acb, 0x40acd}, {0x40ae0, 0x40ae3}, {0x40ae6, 0x40af1}, {0x40af9, 0x40aff}, - {0x40b01, 0x40b03}, {0x40b05, 0x40b0c}, {0x40b13, 0x40b28}, {0x40b2a, 0x40b30}, - {0x40b35, 0x40b39}, {0x40b3c, 0x40b44}, {0x40b4b, 0x40b4d}, {0x40b5f, 0x40b63}, - {0x40b66, 0x40b77}, {0x40b85, 0x40b8a}, {0x40b8e, 0x40b90}, {0x40b92, 0x40b95}, - {0x40ba8, 0x40baa}, {0x40bae, 0x40bb9}, {0x40bbe, 0x40bc2}, {0x40bc6, 0x40bc8}, - {0x40bca, 0x40bcd}, {0x40be6, 0x40bfa}, {0x40c00, 0x40c03}, {0x40c05, 0x40c0c}, - {0x40c0e, 0x40c10}, {0x40c12, 0x40c28}, {0x40c2a, 0x40c39}, {0x40c3d, 0x40c44}, - {0x40c46, 0x40c48}, {0x40c4a, 0x40c4d}, {0x40c58, 0x40c5a}, {0x40c60, 0x40c63}, - {0x40c66, 0x40c6f}, {0x40c78, 0x40c83}, {0x40c85, 0x40c8c}, {0x40c8e, 0x40c90}, - {0x40c92, 0x40ca8}, {0x40caa, 0x40cb3}, {0x40cb5, 0x40cb9}, {0x40cbc, 0x40cc4}, - {0x40cc6, 0x40cc8}, {0x40cca, 0x40ccd}, {0x40ce0, 0x40ce3}, {0x40ce6, 0x40cef}, - {0x40d00, 0x40d03}, {0x40d05, 0x40d0c}, {0x40d0e, 0x40d10}, {0x40d12, 0x40d44}, - {0x40d46, 0x40d48}, {0x40d4a, 0x40d4f}, {0x40d54, 0x40d63}, {0x40d66, 0x40d7f}, - {0x40d85, 0x40d96}, {0x40d9a, 0x40db1}, {0x40db3, 0x40dbb}, {0x40dc0, 0x40dc6}, - {0x40dcf, 0x40dd4}, {0x40dd8, 0x40ddf}, {0x40de6, 0x40def}, {0x40df2, 0x40df4}, - {0x40e01, 0x40e3a}, {0x40e3f, 0x40e5b}, {0x40e94, 0x40e97}, {0x40e99, 0x40e9f}, - {0x40ea1, 0x40ea3}, {0x40ead, 0x40eb9}, {0x40ebb, 0x40ebd}, {0x40ec0, 0x40ec4}, - {0x40ec8, 0x40ecd}, {0x40ed0, 0x40ed9}, {0x40edc, 0x40edf}, {0x40f00, 0x40f47}, - {0x40f49, 0x40f6c}, {0x40f71, 0x40f97}, {0x40f99, 0x40fbc}, {0x40fbe, 0x40fcc}, - {0x40fce, 0x40fda}, {0x41000, 0x410c5}, {0x410d0, 0x41248}, {0x4124a, 0x4124d}, - {0x41250, 0x41256}, {0x4125a, 0x4125d}, {0x41260, 0x41288}, {0x4128a, 0x4128d}, - {0x41290, 0x412b0}, {0x412b2, 0x412b5}, {0x412b8, 0x412be}, {0x412c2, 0x412c5}, - {0x412c8, 0x412d6}, {0x412d8, 0x41310}, {0x41312, 0x41315}, {0x41318, 0x4135a}, - {0x4135d, 0x4137c}, {0x41380, 0x41399}, {0x413a0, 0x413f5}, {0x413f8, 0x413fd}, - {0x41400, 0x4167f}, {0x41681, 0x4169c}, {0x416a0, 0x416f8}, {0x41700, 0x4170c}, - {0x4170e, 0x41714}, {0x41720, 0x41736}, {0x41740, 0x41753}, {0x41760, 0x4176c}, - {0x4176e, 0x41770}, {0x41780, 0x417dd}, {0x417e0, 0x417e9}, {0x417f0, 0x417f9}, - {0x41800, 0x4180d}, {0x41810, 0x41819}, {0x41820, 0x41877}, {0x41880, 0x418aa}, - {0x418b0, 0x418f5}, {0x41900, 0x4191e}, {0x41920, 0x4192b}, {0x41930, 0x4193b}, - {0x41944, 0x4196d}, {0x41970, 0x41974}, {0x41980, 0x419ab}, {0x419b0, 0x419c9}, - {0x419d0, 0x419da}, {0x419de, 0x41a1b}, {0x41a1e, 0x41a5e}, {0x41a60, 0x41a7c}, - {0x41a7f, 0x41a89}, {0x41a90, 0x41a99}, {0x41aa0, 0x41aad}, {0x41ab0, 0x41abe}, - {0x41b00, 0x41b4b}, {0x41b50, 0x41b7c}, {0x41b80, 0x41bf3}, {0x41bfc, 0x41c37}, - {0x41c3b, 0x41c49}, {0x41c4d, 0x41c88}, {0x41cc0, 0x41cc7}, {0x41cd0, 0x41cf9}, - {0x41d00, 0x41df9}, {0x41dfb, 0x41f15}, {0x41f18, 0x41f1d}, {0x41f20, 0x41f45}, - {0x41f48, 0x41f4d}, {0x41f50, 0x41f57}, {0x41f5f, 0x41f7d}, {0x41f80, 0x41fb4}, - {0x41fb6, 0x41fc4}, {0x41fc6, 0x41fd3}, {0x41fd6, 0x41fdb}, {0x41fdd, 0x41fef}, - {0x41ff2, 0x41ff4}, {0x41ff6, 0x41ffe}, {0x42010, 0x42027}, {0x42030, 0x4205e}, - {0x42074, 0x4208e}, {0x42090, 0x4209c}, {0x420a0, 0x420bf}, {0x420d0, 0x420f0}, - {0x42100, 0x4218b}, {0x42190, 0x42426}, {0x42440, 0x4244a}, {0x42460, 0x42b73}, - {0x42b76, 0x42b95}, {0x42b98, 0x42bb9}, {0x42bbd, 0x42bc8}, {0x42bca, 0x42bd2}, - {0x42bec, 0x42bef}, {0x42c00, 0x42c2e}, {0x42c30, 0x42c5e}, {0x42c60, 0x42cf3}, - {0x42cf9, 0x42d25}, {0x42d30, 0x42d67}, {0x42d7f, 0x42d96}, {0x42da0, 0x42da6}, - {0x42da8, 0x42dae}, {0x42db0, 0x42db6}, {0x42db8, 0x42dbe}, {0x42dc0, 0x42dc6}, - {0x42dc8, 0x42dce}, {0x42dd0, 0x42dd6}, {0x42dd8, 0x42dde}, {0x42de0, 0x42e49}, - {0x42e80, 0x42e99}, {0x42e9b, 0x42ef3}, {0x42f00, 0x42fd5}, {0x42ff0, 0x42ffb}, - {0x43001, 0x4303f}, {0x43041, 0x43096}, {0x43099, 0x430ff}, {0x43105, 0x4312e}, - {0x43131, 0x4318e}, {0x43190, 0x431ba}, {0x431c0, 0x431e3}, {0x431f0, 0x4321e}, - {0x43220, 0x432fe}, {0x43300, 0x44db5}, {0x44dc0, 0x49fea}, {0x4a000, 0x4a48c}, - {0x4a490, 0x4a4c6}, {0x4a4d0, 0x4a62b}, {0x4a640, 0x4a6f7}, {0x4a700, 0x4a7ae}, - {0x4a7b0, 0x4a7b7}, {0x4a7f7, 0x4a82b}, {0x4a830, 0x4a839}, {0x4a840, 0x4a877}, - {0x4a880, 0x4a8c5}, {0x4a8ce, 0x4a8d9}, {0x4a8e0, 0x4a8fd}, {0x4a900, 0x4a953}, - {0x4a95f, 0x4a97c}, {0x4a980, 0x4a9cd}, {0x4a9cf, 0x4a9d9}, {0x4a9de, 0x4a9fe}, - {0x4aa00, 0x4aa36}, {0x4aa40, 0x4aa4d}, {0x4aa50, 0x4aa59}, {0x4aa5c, 0x4aac2}, - {0x4aadb, 0x4aaf6}, {0x4ab01, 0x4ab06}, {0x4ab09, 0x4ab0e}, {0x4ab11, 0x4ab16}, - {0x4ab20, 0x4ab26}, {0x4ab28, 0x4ab2e}, {0x4ab30, 0x4ab65}, {0x4ab70, 0x4abed}, - {0x4abf0, 0x4abf9}, {0x4ac00, 0x4d7a3}, {0x4d7b0, 0x4d7c6}, {0x4d7cb, 0x4d7fb}, - {0x4f900, 0x4fa6d}, {0x4fa70, 0x4fad9}, {0x4fb00, 0x4fb06}, {0x4fb13, 0x4fb17}, - {0x4fb1d, 0x4fb36}, {0x4fb38, 0x4fb3c}, {0x4fb46, 0x4fbc1}, {0x4fbd3, 0x4fd3f}, - {0x4fd50, 0x4fd8f}, {0x4fd92, 0x4fdc7}, {0x4fdf0, 0x4fdfd}, {0x4fe00, 0x4fe19}, - {0x4fe20, 0x4fe52}, {0x4fe54, 0x4fe66}, {0x4fe68, 0x4fe6b}, {0x4fe70, 0x4fe74}, - {0x4fe76, 0x4fefc}, {0x4ff01, 0x4ffbe}, {0x4ffc2, 0x4ffc7}, {0x4ffca, 0x4ffcf}, - {0x4ffd2, 0x4ffd7}, {0x4ffda, 0x4ffdc}, {0x4ffe0, 0x4ffe6}, {0x4ffe8, 0x4ffee}, - {0x50021, 0x5007e}, {0x500a1, 0x500ac}, {0x500ae, 0x50377}, {0x5037a, 0x5037f}, - {0x50384, 0x5038a}, {0x5038e, 0x503a1}, {0x503a3, 0x5052f}, {0x50531, 0x50556}, - {0x50559, 0x5055f}, {0x50561, 0x50587}, {0x5058d, 0x5058f}, {0x50591, 0x505c7}, - {0x505d0, 0x505ea}, {0x505f0, 0x505f4}, {0x50606, 0x5061b}, {0x5061e, 0x506dc}, - {0x506de, 0x5070d}, {0x50710, 0x5074a}, {0x5074d, 0x507b1}, {0x507c0, 0x507fa}, - {0x50800, 0x5082d}, {0x50830, 0x5083e}, {0x50840, 0x5085b}, {0x50860, 0x5086a}, - {0x508a0, 0x508b4}, {0x508b6, 0x508bd}, {0x508d4, 0x508e1}, {0x508e3, 0x50983}, - {0x50985, 0x5098c}, {0x50993, 0x509a8}, {0x509aa, 0x509b0}, {0x509b6, 0x509b9}, - {0x509bc, 0x509c4}, {0x509cb, 0x509ce}, {0x509df, 0x509e3}, {0x509e6, 0x509fd}, - {0x50a01, 0x50a03}, {0x50a05, 0x50a0a}, {0x50a13, 0x50a28}, {0x50a2a, 0x50a30}, - {0x50a3e, 0x50a42}, {0x50a4b, 0x50a4d}, {0x50a59, 0x50a5c}, {0x50a66, 0x50a75}, - {0x50a81, 0x50a83}, {0x50a85, 0x50a8d}, {0x50a8f, 0x50a91}, {0x50a93, 0x50aa8}, - {0x50aaa, 0x50ab0}, {0x50ab5, 0x50ab9}, {0x50abc, 0x50ac5}, {0x50ac7, 0x50ac9}, - {0x50acb, 0x50acd}, {0x50ae0, 0x50ae3}, {0x50ae6, 0x50af1}, {0x50af9, 0x50aff}, - {0x50b01, 0x50b03}, {0x50b05, 0x50b0c}, {0x50b13, 0x50b28}, {0x50b2a, 0x50b30}, - {0x50b35, 0x50b39}, {0x50b3c, 0x50b44}, {0x50b4b, 0x50b4d}, {0x50b5f, 0x50b63}, - {0x50b66, 0x50b77}, {0x50b85, 0x50b8a}, {0x50b8e, 0x50b90}, {0x50b92, 0x50b95}, - {0x50ba8, 0x50baa}, {0x50bae, 0x50bb9}, {0x50bbe, 0x50bc2}, {0x50bc6, 0x50bc8}, - {0x50bca, 0x50bcd}, {0x50be6, 0x50bfa}, {0x50c00, 0x50c03}, {0x50c05, 0x50c0c}, - {0x50c0e, 0x50c10}, {0x50c12, 0x50c28}, {0x50c2a, 0x50c39}, {0x50c3d, 0x50c44}, - {0x50c46, 0x50c48}, {0x50c4a, 0x50c4d}, {0x50c58, 0x50c5a}, {0x50c60, 0x50c63}, - {0x50c66, 0x50c6f}, {0x50c78, 0x50c83}, {0x50c85, 0x50c8c}, {0x50c8e, 0x50c90}, - {0x50c92, 0x50ca8}, {0x50caa, 0x50cb3}, {0x50cb5, 0x50cb9}, {0x50cbc, 0x50cc4}, - {0x50cc6, 0x50cc8}, {0x50cca, 0x50ccd}, {0x50ce0, 0x50ce3}, {0x50ce6, 0x50cef}, - {0x50d00, 0x50d03}, {0x50d05, 0x50d0c}, {0x50d0e, 0x50d10}, {0x50d12, 0x50d44}, - {0x50d46, 0x50d48}, {0x50d4a, 0x50d4f}, {0x50d54, 0x50d63}, {0x50d66, 0x50d7f}, - {0x50d85, 0x50d96}, {0x50d9a, 0x50db1}, {0x50db3, 0x50dbb}, {0x50dc0, 0x50dc6}, - {0x50dcf, 0x50dd4}, {0x50dd8, 0x50ddf}, {0x50de6, 0x50def}, {0x50df2, 0x50df4}, - {0x50e01, 0x50e3a}, {0x50e3f, 0x50e5b}, {0x50e94, 0x50e97}, {0x50e99, 0x50e9f}, - {0x50ea1, 0x50ea3}, {0x50ead, 0x50eb9}, {0x50ebb, 0x50ebd}, {0x50ec0, 0x50ec4}, - {0x50ec8, 0x50ecd}, {0x50ed0, 0x50ed9}, {0x50edc, 0x50edf}, {0x50f00, 0x50f47}, - {0x50f49, 0x50f6c}, {0x50f71, 0x50f97}, {0x50f99, 0x50fbc}, {0x50fbe, 0x50fcc}, - {0x50fce, 0x50fda}, {0x51000, 0x510c5}, {0x510d0, 0x51248}, {0x5124a, 0x5124d}, - {0x51250, 0x51256}, {0x5125a, 0x5125d}, {0x51260, 0x51288}, {0x5128a, 0x5128d}, - {0x51290, 0x512b0}, {0x512b2, 0x512b5}, {0x512b8, 0x512be}, {0x512c2, 0x512c5}, - {0x512c8, 0x512d6}, {0x512d8, 0x51310}, {0x51312, 0x51315}, {0x51318, 0x5135a}, - {0x5135d, 0x5137c}, {0x51380, 0x51399}, {0x513a0, 0x513f5}, {0x513f8, 0x513fd}, - {0x51400, 0x5167f}, {0x51681, 0x5169c}, {0x516a0, 0x516f8}, {0x51700, 0x5170c}, - {0x5170e, 0x51714}, {0x51720, 0x51736}, {0x51740, 0x51753}, {0x51760, 0x5176c}, - {0x5176e, 0x51770}, {0x51780, 0x517dd}, {0x517e0, 0x517e9}, {0x517f0, 0x517f9}, - {0x51800, 0x5180d}, {0x51810, 0x51819}, {0x51820, 0x51877}, {0x51880, 0x518aa}, - {0x518b0, 0x518f5}, {0x51900, 0x5191e}, {0x51920, 0x5192b}, {0x51930, 0x5193b}, - {0x51944, 0x5196d}, {0x51970, 0x51974}, {0x51980, 0x519ab}, {0x519b0, 0x519c9}, - {0x519d0, 0x519da}, {0x519de, 0x51a1b}, {0x51a1e, 0x51a5e}, {0x51a60, 0x51a7c}, - {0x51a7f, 0x51a89}, {0x51a90, 0x51a99}, {0x51aa0, 0x51aad}, {0x51ab0, 0x51abe}, - {0x51b00, 0x51b4b}, {0x51b50, 0x51b7c}, {0x51b80, 0x51bf3}, {0x51bfc, 0x51c37}, - {0x51c3b, 0x51c49}, {0x51c4d, 0x51c88}, {0x51cc0, 0x51cc7}, {0x51cd0, 0x51cf9}, - {0x51d00, 0x51df9}, {0x51dfb, 0x51f15}, {0x51f18, 0x51f1d}, {0x51f20, 0x51f45}, - {0x51f48, 0x51f4d}, {0x51f50, 0x51f57}, {0x51f5f, 0x51f7d}, {0x51f80, 0x51fb4}, - {0x51fb6, 0x51fc4}, {0x51fc6, 0x51fd3}, {0x51fd6, 0x51fdb}, {0x51fdd, 0x51fef}, - {0x51ff2, 0x51ff4}, {0x51ff6, 0x51ffe}, {0x52010, 0x52027}, {0x52030, 0x5205e}, - {0x52074, 0x5208e}, {0x52090, 0x5209c}, {0x520a0, 0x520bf}, {0x520d0, 0x520f0}, - {0x52100, 0x5218b}, {0x52190, 0x52426}, {0x52440, 0x5244a}, {0x52460, 0x52b73}, - {0x52b76, 0x52b95}, {0x52b98, 0x52bb9}, {0x52bbd, 0x52bc8}, {0x52bca, 0x52bd2}, - {0x52bec, 0x52bef}, {0x52c00, 0x52c2e}, {0x52c30, 0x52c5e}, {0x52c60, 0x52cf3}, - {0x52cf9, 0x52d25}, {0x52d30, 0x52d67}, {0x52d7f, 0x52d96}, {0x52da0, 0x52da6}, - {0x52da8, 0x52dae}, {0x52db0, 0x52db6}, {0x52db8, 0x52dbe}, {0x52dc0, 0x52dc6}, - {0x52dc8, 0x52dce}, {0x52dd0, 0x52dd6}, {0x52dd8, 0x52dde}, {0x52de0, 0x52e49}, - {0x52e80, 0x52e99}, {0x52e9b, 0x52ef3}, {0x52f00, 0x52fd5}, {0x52ff0, 0x52ffb}, - {0x53001, 0x5303f}, {0x53041, 0x53096}, {0x53099, 0x530ff}, {0x53105, 0x5312e}, - {0x53131, 0x5318e}, {0x53190, 0x531ba}, {0x531c0, 0x531e3}, {0x531f0, 0x5321e}, - {0x53220, 0x532fe}, {0x53300, 0x54db5}, {0x54dc0, 0x59fea}, {0x5a000, 0x5a48c}, - {0x5a490, 0x5a4c6}, {0x5a4d0, 0x5a62b}, {0x5a640, 0x5a6f7}, {0x5a700, 0x5a7ae}, - {0x5a7b0, 0x5a7b7}, {0x5a7f7, 0x5a82b}, {0x5a830, 0x5a839}, {0x5a840, 0x5a877}, - {0x5a880, 0x5a8c5}, {0x5a8ce, 0x5a8d9}, {0x5a8e0, 0x5a8fd}, {0x5a900, 0x5a953}, - {0x5a95f, 0x5a97c}, {0x5a980, 0x5a9cd}, {0x5a9cf, 0x5a9d9}, {0x5a9de, 0x5a9fe}, - {0x5aa00, 0x5aa36}, {0x5aa40, 0x5aa4d}, {0x5aa50, 0x5aa59}, {0x5aa5c, 0x5aac2}, - {0x5aadb, 0x5aaf6}, {0x5ab01, 0x5ab06}, {0x5ab09, 0x5ab0e}, {0x5ab11, 0x5ab16}, - {0x5ab20, 0x5ab26}, {0x5ab28, 0x5ab2e}, {0x5ab30, 0x5ab65}, {0x5ab70, 0x5abed}, - {0x5abf0, 0x5abf9}, {0x5ac00, 0x5d7a3}, {0x5d7b0, 0x5d7c6}, {0x5d7cb, 0x5d7fb}, - {0x5f900, 0x5fa6d}, {0x5fa70, 0x5fad9}, {0x5fb00, 0x5fb06}, {0x5fb13, 0x5fb17}, - {0x5fb1d, 0x5fb36}, {0x5fb38, 0x5fb3c}, {0x5fb46, 0x5fbc1}, {0x5fbd3, 0x5fd3f}, - {0x5fd50, 0x5fd8f}, {0x5fd92, 0x5fdc7}, {0x5fdf0, 0x5fdfd}, {0x5fe00, 0x5fe19}, - {0x5fe20, 0x5fe52}, {0x5fe54, 0x5fe66}, {0x5fe68, 0x5fe6b}, {0x5fe70, 0x5fe74}, - {0x5fe76, 0x5fefc}, {0x5ff01, 0x5ffbe}, {0x5ffc2, 0x5ffc7}, {0x5ffca, 0x5ffcf}, - {0x5ffd2, 0x5ffd7}, {0x5ffda, 0x5ffdc}, {0x5ffe0, 0x5ffe6}, {0x5ffe8, 0x5ffee}, - {0x60021, 0x6007e}, {0x600a1, 0x600ac}, {0x600ae, 0x60377}, {0x6037a, 0x6037f}, - {0x60384, 0x6038a}, {0x6038e, 0x603a1}, {0x603a3, 0x6052f}, {0x60531, 0x60556}, - {0x60559, 0x6055f}, {0x60561, 0x60587}, {0x6058d, 0x6058f}, {0x60591, 0x605c7}, - {0x605d0, 0x605ea}, {0x605f0, 0x605f4}, {0x60606, 0x6061b}, {0x6061e, 0x606dc}, - {0x606de, 0x6070d}, {0x60710, 0x6074a}, {0x6074d, 0x607b1}, {0x607c0, 0x607fa}, - {0x60800, 0x6082d}, {0x60830, 0x6083e}, {0x60840, 0x6085b}, {0x60860, 0x6086a}, - {0x608a0, 0x608b4}, {0x608b6, 0x608bd}, {0x608d4, 0x608e1}, {0x608e3, 0x60983}, - {0x60985, 0x6098c}, {0x60993, 0x609a8}, {0x609aa, 0x609b0}, {0x609b6, 0x609b9}, - {0x609bc, 0x609c4}, {0x609cb, 0x609ce}, {0x609df, 0x609e3}, {0x609e6, 0x609fd}, - {0x60a01, 0x60a03}, {0x60a05, 0x60a0a}, {0x60a13, 0x60a28}, {0x60a2a, 0x60a30}, - {0x60a3e, 0x60a42}, {0x60a4b, 0x60a4d}, {0x60a59, 0x60a5c}, {0x60a66, 0x60a75}, - {0x60a81, 0x60a83}, {0x60a85, 0x60a8d}, {0x60a8f, 0x60a91}, {0x60a93, 0x60aa8}, - {0x60aaa, 0x60ab0}, {0x60ab5, 0x60ab9}, {0x60abc, 0x60ac5}, {0x60ac7, 0x60ac9}, - {0x60acb, 0x60acd}, {0x60ae0, 0x60ae3}, {0x60ae6, 0x60af1}, {0x60af9, 0x60aff}, - {0x60b01, 0x60b03}, {0x60b05, 0x60b0c}, {0x60b13, 0x60b28}, {0x60b2a, 0x60b30}, - {0x60b35, 0x60b39}, {0x60b3c, 0x60b44}, {0x60b4b, 0x60b4d}, {0x60b5f, 0x60b63}, - {0x60b66, 0x60b77}, {0x60b85, 0x60b8a}, {0x60b8e, 0x60b90}, {0x60b92, 0x60b95}, - {0x60ba8, 0x60baa}, {0x60bae, 0x60bb9}, {0x60bbe, 0x60bc2}, {0x60bc6, 0x60bc8}, - {0x60bca, 0x60bcd}, {0x60be6, 0x60bfa}, {0x60c00, 0x60c03}, {0x60c05, 0x60c0c}, - {0x60c0e, 0x60c10}, {0x60c12, 0x60c28}, {0x60c2a, 0x60c39}, {0x60c3d, 0x60c44}, - {0x60c46, 0x60c48}, {0x60c4a, 0x60c4d}, {0x60c58, 0x60c5a}, {0x60c60, 0x60c63}, - {0x60c66, 0x60c6f}, {0x60c78, 0x60c83}, {0x60c85, 0x60c8c}, {0x60c8e, 0x60c90}, - {0x60c92, 0x60ca8}, {0x60caa, 0x60cb3}, {0x60cb5, 0x60cb9}, {0x60cbc, 0x60cc4}, - {0x60cc6, 0x60cc8}, {0x60cca, 0x60ccd}, {0x60ce0, 0x60ce3}, {0x60ce6, 0x60cef}, - {0x60d00, 0x60d03}, {0x60d05, 0x60d0c}, {0x60d0e, 0x60d10}, {0x60d12, 0x60d44}, - {0x60d46, 0x60d48}, {0x60d4a, 0x60d4f}, {0x60d54, 0x60d63}, {0x60d66, 0x60d7f}, - {0x60d85, 0x60d96}, {0x60d9a, 0x60db1}, {0x60db3, 0x60dbb}, {0x60dc0, 0x60dc6}, - {0x60dcf, 0x60dd4}, {0x60dd8, 0x60ddf}, {0x60de6, 0x60def}, {0x60df2, 0x60df4}, - {0x60e01, 0x60e3a}, {0x60e3f, 0x60e5b}, {0x60e94, 0x60e97}, {0x60e99, 0x60e9f}, - {0x60ea1, 0x60ea3}, {0x60ead, 0x60eb9}, {0x60ebb, 0x60ebd}, {0x60ec0, 0x60ec4}, - {0x60ec8, 0x60ecd}, {0x60ed0, 0x60ed9}, {0x60edc, 0x60edf}, {0x60f00, 0x60f47}, - {0x60f49, 0x60f6c}, {0x60f71, 0x60f97}, {0x60f99, 0x60fbc}, {0x60fbe, 0x60fcc}, - {0x60fce, 0x60fda}, {0x61000, 0x610c5}, {0x610d0, 0x61248}, {0x6124a, 0x6124d}, - {0x61250, 0x61256}, {0x6125a, 0x6125d}, {0x61260, 0x61288}, {0x6128a, 0x6128d}, - {0x61290, 0x612b0}, {0x612b2, 0x612b5}, {0x612b8, 0x612be}, {0x612c2, 0x612c5}, - {0x612c8, 0x612d6}, {0x612d8, 0x61310}, {0x61312, 0x61315}, {0x61318, 0x6135a}, - {0x6135d, 0x6137c}, {0x61380, 0x61399}, {0x613a0, 0x613f5}, {0x613f8, 0x613fd}, - {0x61400, 0x6167f}, {0x61681, 0x6169c}, {0x616a0, 0x616f8}, {0x61700, 0x6170c}, - {0x6170e, 0x61714}, {0x61720, 0x61736}, {0x61740, 0x61753}, {0x61760, 0x6176c}, - {0x6176e, 0x61770}, {0x61780, 0x617dd}, {0x617e0, 0x617e9}, {0x617f0, 0x617f9}, - {0x61800, 0x6180d}, {0x61810, 0x61819}, {0x61820, 0x61877}, {0x61880, 0x618aa}, - {0x618b0, 0x618f5}, {0x61900, 0x6191e}, {0x61920, 0x6192b}, {0x61930, 0x6193b}, - {0x61944, 0x6196d}, {0x61970, 0x61974}, {0x61980, 0x619ab}, {0x619b0, 0x619c9}, - {0x619d0, 0x619da}, {0x619de, 0x61a1b}, {0x61a1e, 0x61a5e}, {0x61a60, 0x61a7c}, - {0x61a7f, 0x61a89}, {0x61a90, 0x61a99}, {0x61aa0, 0x61aad}, {0x61ab0, 0x61abe}, - {0x61b00, 0x61b4b}, {0x61b50, 0x61b7c}, {0x61b80, 0x61bf3}, {0x61bfc, 0x61c37}, - {0x61c3b, 0x61c49}, {0x61c4d, 0x61c88}, {0x61cc0, 0x61cc7}, {0x61cd0, 0x61cf9}, - {0x61d00, 0x61df9}, {0x61dfb, 0x61f15}, {0x61f18, 0x61f1d}, {0x61f20, 0x61f45}, - {0x61f48, 0x61f4d}, {0x61f50, 0x61f57}, {0x61f5f, 0x61f7d}, {0x61f80, 0x61fb4}, - {0x61fb6, 0x61fc4}, {0x61fc6, 0x61fd3}, {0x61fd6, 0x61fdb}, {0x61fdd, 0x61fef}, - {0x61ff2, 0x61ff4}, {0x61ff6, 0x61ffe}, {0x62010, 0x62027}, {0x62030, 0x6205e}, - {0x62074, 0x6208e}, {0x62090, 0x6209c}, {0x620a0, 0x620bf}, {0x620d0, 0x620f0}, - {0x62100, 0x6218b}, {0x62190, 0x62426}, {0x62440, 0x6244a}, {0x62460, 0x62b73}, - {0x62b76, 0x62b95}, {0x62b98, 0x62bb9}, {0x62bbd, 0x62bc8}, {0x62bca, 0x62bd2}, - {0x62bec, 0x62bef}, {0x62c00, 0x62c2e}, {0x62c30, 0x62c5e}, {0x62c60, 0x62cf3}, - {0x62cf9, 0x62d25}, {0x62d30, 0x62d67}, {0x62d7f, 0x62d96}, {0x62da0, 0x62da6}, - {0x62da8, 0x62dae}, {0x62db0, 0x62db6}, {0x62db8, 0x62dbe}, {0x62dc0, 0x62dc6}, - {0x62dc8, 0x62dce}, {0x62dd0, 0x62dd6}, {0x62dd8, 0x62dde}, {0x62de0, 0x62e49}, - {0x62e80, 0x62e99}, {0x62e9b, 0x62ef3}, {0x62f00, 0x62fd5}, {0x62ff0, 0x62ffb}, - {0x63001, 0x6303f}, {0x63041, 0x63096}, {0x63099, 0x630ff}, {0x63105, 0x6312e}, - {0x63131, 0x6318e}, {0x63190, 0x631ba}, {0x631c0, 0x631e3}, {0x631f0, 0x6321e}, - {0x63220, 0x632fe}, {0x63300, 0x64db5}, {0x64dc0, 0x69fea}, {0x6a000, 0x6a48c}, - {0x6a490, 0x6a4c6}, {0x6a4d0, 0x6a62b}, {0x6a640, 0x6a6f7}, {0x6a700, 0x6a7ae}, - {0x6a7b0, 0x6a7b7}, {0x6a7f7, 0x6a82b}, {0x6a830, 0x6a839}, {0x6a840, 0x6a877}, - {0x6a880, 0x6a8c5}, {0x6a8ce, 0x6a8d9}, {0x6a8e0, 0x6a8fd}, {0x6a900, 0x6a953}, - {0x6a95f, 0x6a97c}, {0x6a980, 0x6a9cd}, {0x6a9cf, 0x6a9d9}, {0x6a9de, 0x6a9fe}, - {0x6aa00, 0x6aa36}, {0x6aa40, 0x6aa4d}, {0x6aa50, 0x6aa59}, {0x6aa5c, 0x6aac2}, - {0x6aadb, 0x6aaf6}, {0x6ab01, 0x6ab06}, {0x6ab09, 0x6ab0e}, {0x6ab11, 0x6ab16}, - {0x6ab20, 0x6ab26}, {0x6ab28, 0x6ab2e}, {0x6ab30, 0x6ab65}, {0x6ab70, 0x6abed}, - {0x6abf0, 0x6abf9}, {0x6ac00, 0x6d7a3}, {0x6d7b0, 0x6d7c6}, {0x6d7cb, 0x6d7fb}, - {0x6f900, 0x6fa6d}, {0x6fa70, 0x6fad9}, {0x6fb00, 0x6fb06}, {0x6fb13, 0x6fb17}, - {0x6fb1d, 0x6fb36}, {0x6fb38, 0x6fb3c}, {0x6fb46, 0x6fbc1}, {0x6fbd3, 0x6fd3f}, - {0x6fd50, 0x6fd8f}, {0x6fd92, 0x6fdc7}, {0x6fdf0, 0x6fdfd}, {0x6fe00, 0x6fe19}, - {0x6fe20, 0x6fe52}, {0x6fe54, 0x6fe66}, {0x6fe68, 0x6fe6b}, {0x6fe70, 0x6fe74}, - {0x6fe76, 0x6fefc}, {0x6ff01, 0x6ffbe}, {0x6ffc2, 0x6ffc7}, {0x6ffca, 0x6ffcf}, - {0x6ffd2, 0x6ffd7}, {0x6ffda, 0x6ffdc}, {0x6ffe0, 0x6ffe6}, {0x6ffe8, 0x6ffee}, - {0x70021, 0x7007e}, {0x700a1, 0x700ac}, {0x700ae, 0x70377}, {0x7037a, 0x7037f}, - {0x70384, 0x7038a}, {0x7038e, 0x703a1}, {0x703a3, 0x7052f}, {0x70531, 0x70556}, - {0x70559, 0x7055f}, {0x70561, 0x70587}, {0x7058d, 0x7058f}, {0x70591, 0x705c7}, - {0x705d0, 0x705ea}, {0x705f0, 0x705f4}, {0x70606, 0x7061b}, {0x7061e, 0x706dc}, - {0x706de, 0x7070d}, {0x70710, 0x7074a}, {0x7074d, 0x707b1}, {0x707c0, 0x707fa}, - {0x70800, 0x7082d}, {0x70830, 0x7083e}, {0x70840, 0x7085b}, {0x70860, 0x7086a}, - {0x708a0, 0x708b4}, {0x708b6, 0x708bd}, {0x708d4, 0x708e1}, {0x708e3, 0x70983}, - {0x70985, 0x7098c}, {0x70993, 0x709a8}, {0x709aa, 0x709b0}, {0x709b6, 0x709b9}, - {0x709bc, 0x709c4}, {0x709cb, 0x709ce}, {0x709df, 0x709e3}, {0x709e6, 0x709fd}, - {0x70a01, 0x70a03}, {0x70a05, 0x70a0a}, {0x70a13, 0x70a28}, {0x70a2a, 0x70a30}, - {0x70a3e, 0x70a42}, {0x70a4b, 0x70a4d}, {0x70a59, 0x70a5c}, {0x70a66, 0x70a75}, - {0x70a81, 0x70a83}, {0x70a85, 0x70a8d}, {0x70a8f, 0x70a91}, {0x70a93, 0x70aa8}, - {0x70aaa, 0x70ab0}, {0x70ab5, 0x70ab9}, {0x70abc, 0x70ac5}, {0x70ac7, 0x70ac9}, - {0x70acb, 0x70acd}, {0x70ae0, 0x70ae3}, {0x70ae6, 0x70af1}, {0x70af9, 0x70aff}, - {0x70b01, 0x70b03}, {0x70b05, 0x70b0c}, {0x70b13, 0x70b28}, {0x70b2a, 0x70b30}, - {0x70b35, 0x70b39}, {0x70b3c, 0x70b44}, {0x70b4b, 0x70b4d}, {0x70b5f, 0x70b63}, - {0x70b66, 0x70b77}, {0x70b85, 0x70b8a}, {0x70b8e, 0x70b90}, {0x70b92, 0x70b95}, - {0x70ba8, 0x70baa}, {0x70bae, 0x70bb9}, {0x70bbe, 0x70bc2}, {0x70bc6, 0x70bc8}, - {0x70bca, 0x70bcd}, {0x70be6, 0x70bfa}, {0x70c00, 0x70c03}, {0x70c05, 0x70c0c}, - {0x70c0e, 0x70c10}, {0x70c12, 0x70c28}, {0x70c2a, 0x70c39}, {0x70c3d, 0x70c44}, - {0x70c46, 0x70c48}, {0x70c4a, 0x70c4d}, {0x70c58, 0x70c5a}, {0x70c60, 0x70c63}, - {0x70c66, 0x70c6f}, {0x70c78, 0x70c83}, {0x70c85, 0x70c8c}, {0x70c8e, 0x70c90}, - {0x70c92, 0x70ca8}, {0x70caa, 0x70cb3}, {0x70cb5, 0x70cb9}, {0x70cbc, 0x70cc4}, - {0x70cc6, 0x70cc8}, {0x70cca, 0x70ccd}, {0x70ce0, 0x70ce3}, {0x70ce6, 0x70cef}, - {0x70d00, 0x70d03}, {0x70d05, 0x70d0c}, {0x70d0e, 0x70d10}, {0x70d12, 0x70d44}, - {0x70d46, 0x70d48}, {0x70d4a, 0x70d4f}, {0x70d54, 0x70d63}, {0x70d66, 0x70d7f}, - {0x70d85, 0x70d96}, {0x70d9a, 0x70db1}, {0x70db3, 0x70dbb}, {0x70dc0, 0x70dc6}, - {0x70dcf, 0x70dd4}, {0x70dd8, 0x70ddf}, {0x70de6, 0x70def}, {0x70df2, 0x70df4}, - {0x70e01, 0x70e3a}, {0x70e3f, 0x70e5b}, {0x70e94, 0x70e97}, {0x70e99, 0x70e9f}, - {0x70ea1, 0x70ea3}, {0x70ead, 0x70eb9}, {0x70ebb, 0x70ebd}, {0x70ec0, 0x70ec4}, - {0x70ec8, 0x70ecd}, {0x70ed0, 0x70ed9}, {0x70edc, 0x70edf}, {0x70f00, 0x70f47}, - {0x70f49, 0x70f6c}, {0x70f71, 0x70f97}, {0x70f99, 0x70fbc}, {0x70fbe, 0x70fcc}, - {0x70fce, 0x70fda}, {0x71000, 0x710c5}, {0x710d0, 0x71248}, {0x7124a, 0x7124d}, - {0x71250, 0x71256}, {0x7125a, 0x7125d}, {0x71260, 0x71288}, {0x7128a, 0x7128d}, - {0x71290, 0x712b0}, {0x712b2, 0x712b5}, {0x712b8, 0x712be}, {0x712c2, 0x712c5}, - {0x712c8, 0x712d6}, {0x712d8, 0x71310}, {0x71312, 0x71315}, {0x71318, 0x7135a}, - {0x7135d, 0x7137c}, {0x71380, 0x71399}, {0x713a0, 0x713f5}, {0x713f8, 0x713fd}, - {0x71400, 0x7167f}, {0x71681, 0x7169c}, {0x716a0, 0x716f8}, {0x71700, 0x7170c}, - {0x7170e, 0x71714}, {0x71720, 0x71736}, {0x71740, 0x71753}, {0x71760, 0x7176c}, - {0x7176e, 0x71770}, {0x71780, 0x717dd}, {0x717e0, 0x717e9}, {0x717f0, 0x717f9}, - {0x71800, 0x7180d}, {0x71810, 0x71819}, {0x71820, 0x71877}, {0x71880, 0x718aa}, - {0x718b0, 0x718f5}, {0x71900, 0x7191e}, {0x71920, 0x7192b}, {0x71930, 0x7193b}, - {0x71944, 0x7196d}, {0x71970, 0x71974}, {0x71980, 0x719ab}, {0x719b0, 0x719c9}, - {0x719d0, 0x719da}, {0x719de, 0x71a1b}, {0x71a1e, 0x71a5e}, {0x71a60, 0x71a7c}, - {0x71a7f, 0x71a89}, {0x71a90, 0x71a99}, {0x71aa0, 0x71aad}, {0x71ab0, 0x71abe}, - {0x71b00, 0x71b4b}, {0x71b50, 0x71b7c}, {0x71b80, 0x71bf3}, {0x71bfc, 0x71c37}, - {0x71c3b, 0x71c49}, {0x71c4d, 0x71c88}, {0x71cc0, 0x71cc7}, {0x71cd0, 0x71cf9}, - {0x71d00, 0x71df9}, {0x71dfb, 0x71f15}, {0x71f18, 0x71f1d}, {0x71f20, 0x71f45}, - {0x71f48, 0x71f4d}, {0x71f50, 0x71f57}, {0x71f5f, 0x71f7d}, {0x71f80, 0x71fb4}, - {0x71fb6, 0x71fc4}, {0x71fc6, 0x71fd3}, {0x71fd6, 0x71fdb}, {0x71fdd, 0x71fef}, - {0x71ff2, 0x71ff4}, {0x71ff6, 0x71ffe}, {0x72010, 0x72027}, {0x72030, 0x7205e}, - {0x72074, 0x7208e}, {0x72090, 0x7209c}, {0x720a0, 0x720bf}, {0x720d0, 0x720f0}, - {0x72100, 0x7218b}, {0x72190, 0x72426}, {0x72440, 0x7244a}, {0x72460, 0x72b73}, - {0x72b76, 0x72b95}, {0x72b98, 0x72bb9}, {0x72bbd, 0x72bc8}, {0x72bca, 0x72bd2}, - {0x72bec, 0x72bef}, {0x72c00, 0x72c2e}, {0x72c30, 0x72c5e}, {0x72c60, 0x72cf3}, - {0x72cf9, 0x72d25}, {0x72d30, 0x72d67}, {0x72d7f, 0x72d96}, {0x72da0, 0x72da6}, - {0x72da8, 0x72dae}, {0x72db0, 0x72db6}, {0x72db8, 0x72dbe}, {0x72dc0, 0x72dc6}, - {0x72dc8, 0x72dce}, {0x72dd0, 0x72dd6}, {0x72dd8, 0x72dde}, {0x72de0, 0x72e49}, - {0x72e80, 0x72e99}, {0x72e9b, 0x72ef3}, {0x72f00, 0x72fd5}, {0x72ff0, 0x72ffb}, - {0x73001, 0x7303f}, {0x73041, 0x73096}, {0x73099, 0x730ff}, {0x73105, 0x7312e}, - {0x73131, 0x7318e}, {0x73190, 0x731ba}, {0x731c0, 0x731e3}, {0x731f0, 0x7321e}, - {0x73220, 0x732fe}, {0x73300, 0x74db5}, {0x74dc0, 0x79fea}, {0x7a000, 0x7a48c}, - {0x7a490, 0x7a4c6}, {0x7a4d0, 0x7a62b}, {0x7a640, 0x7a6f7}, {0x7a700, 0x7a7ae}, - {0x7a7b0, 0x7a7b7}, {0x7a7f7, 0x7a82b}, {0x7a830, 0x7a839}, {0x7a840, 0x7a877}, - {0x7a880, 0x7a8c5}, {0x7a8ce, 0x7a8d9}, {0x7a8e0, 0x7a8fd}, {0x7a900, 0x7a953}, - {0x7a95f, 0x7a97c}, {0x7a980, 0x7a9cd}, {0x7a9cf, 0x7a9d9}, {0x7a9de, 0x7a9fe}, - {0x7aa00, 0x7aa36}, {0x7aa40, 0x7aa4d}, {0x7aa50, 0x7aa59}, {0x7aa5c, 0x7aac2}, - {0x7aadb, 0x7aaf6}, {0x7ab01, 0x7ab06}, {0x7ab09, 0x7ab0e}, {0x7ab11, 0x7ab16}, - {0x7ab20, 0x7ab26}, {0x7ab28, 0x7ab2e}, {0x7ab30, 0x7ab65}, {0x7ab70, 0x7abed}, - {0x7abf0, 0x7abf9}, {0x7ac00, 0x7d7a3}, {0x7d7b0, 0x7d7c6}, {0x7d7cb, 0x7d7fb}, - {0x7f900, 0x7fa6d}, {0x7fa70, 0x7fad9}, {0x7fb00, 0x7fb06}, {0x7fb13, 0x7fb17}, - {0x7fb1d, 0x7fb36}, {0x7fb38, 0x7fb3c}, {0x7fb46, 0x7fbc1}, {0x7fbd3, 0x7fd3f}, - {0x7fd50, 0x7fd8f}, {0x7fd92, 0x7fdc7}, {0x7fdf0, 0x7fdfd}, {0x7fe00, 0x7fe19}, - {0x7fe20, 0x7fe52}, {0x7fe54, 0x7fe66}, {0x7fe68, 0x7fe6b}, {0x7fe70, 0x7fe74}, - {0x7fe76, 0x7fefc}, {0x7ff01, 0x7ffbe}, {0x7ffc2, 0x7ffc7}, {0x7ffca, 0x7ffcf}, - {0x7ffd2, 0x7ffd7}, {0x7ffda, 0x7ffdc}, {0x7ffe0, 0x7ffe6}, {0x7ffe8, 0x7ffee}, - {0x80021, 0x8007e}, {0x800a1, 0x800ac}, {0x800ae, 0x80377}, {0x8037a, 0x8037f}, - {0x80384, 0x8038a}, {0x8038e, 0x803a1}, {0x803a3, 0x8052f}, {0x80531, 0x80556}, - {0x80559, 0x8055f}, {0x80561, 0x80587}, {0x8058d, 0x8058f}, {0x80591, 0x805c7}, - {0x805d0, 0x805ea}, {0x805f0, 0x805f4}, {0x80606, 0x8061b}, {0x8061e, 0x806dc}, - {0x806de, 0x8070d}, {0x80710, 0x8074a}, {0x8074d, 0x807b1}, {0x807c0, 0x807fa}, - {0x80800, 0x8082d}, {0x80830, 0x8083e}, {0x80840, 0x8085b}, {0x80860, 0x8086a}, - {0x808a0, 0x808b4}, {0x808b6, 0x808bd}, {0x808d4, 0x808e1}, {0x808e3, 0x80983}, - {0x80985, 0x8098c}, {0x80993, 0x809a8}, {0x809aa, 0x809b0}, {0x809b6, 0x809b9}, - {0x809bc, 0x809c4}, {0x809cb, 0x809ce}, {0x809df, 0x809e3}, {0x809e6, 0x809fd}, - {0x80a01, 0x80a03}, {0x80a05, 0x80a0a}, {0x80a13, 0x80a28}, {0x80a2a, 0x80a30}, - {0x80a3e, 0x80a42}, {0x80a4b, 0x80a4d}, {0x80a59, 0x80a5c}, {0x80a66, 0x80a75}, - {0x80a81, 0x80a83}, {0x80a85, 0x80a8d}, {0x80a8f, 0x80a91}, {0x80a93, 0x80aa8}, - {0x80aaa, 0x80ab0}, {0x80ab5, 0x80ab9}, {0x80abc, 0x80ac5}, {0x80ac7, 0x80ac9}, - {0x80acb, 0x80acd}, {0x80ae0, 0x80ae3}, {0x80ae6, 0x80af1}, {0x80af9, 0x80aff}, - {0x80b01, 0x80b03}, {0x80b05, 0x80b0c}, {0x80b13, 0x80b28}, {0x80b2a, 0x80b30}, - {0x80b35, 0x80b39}, {0x80b3c, 0x80b44}, {0x80b4b, 0x80b4d}, {0x80b5f, 0x80b63}, - {0x80b66, 0x80b77}, {0x80b85, 0x80b8a}, {0x80b8e, 0x80b90}, {0x80b92, 0x80b95}, - {0x80ba8, 0x80baa}, {0x80bae, 0x80bb9}, {0x80bbe, 0x80bc2}, {0x80bc6, 0x80bc8}, - {0x80bca, 0x80bcd}, {0x80be6, 0x80bfa}, {0x80c00, 0x80c03}, {0x80c05, 0x80c0c}, - {0x80c0e, 0x80c10}, {0x80c12, 0x80c28}, {0x80c2a, 0x80c39}, {0x80c3d, 0x80c44}, - {0x80c46, 0x80c48}, {0x80c4a, 0x80c4d}, {0x80c58, 0x80c5a}, {0x80c60, 0x80c63}, - {0x80c66, 0x80c6f}, {0x80c78, 0x80c83}, {0x80c85, 0x80c8c}, {0x80c8e, 0x80c90}, - {0x80c92, 0x80ca8}, {0x80caa, 0x80cb3}, {0x80cb5, 0x80cb9}, {0x80cbc, 0x80cc4}, - {0x80cc6, 0x80cc8}, {0x80cca, 0x80ccd}, {0x80ce0, 0x80ce3}, {0x80ce6, 0x80cef}, - {0x80d00, 0x80d03}, {0x80d05, 0x80d0c}, {0x80d0e, 0x80d10}, {0x80d12, 0x80d44}, - {0x80d46, 0x80d48}, {0x80d4a, 0x80d4f}, {0x80d54, 0x80d63}, {0x80d66, 0x80d7f}, - {0x80d85, 0x80d96}, {0x80d9a, 0x80db1}, {0x80db3, 0x80dbb}, {0x80dc0, 0x80dc6}, - {0x80dcf, 0x80dd4}, {0x80dd8, 0x80ddf}, {0x80de6, 0x80def}, {0x80df2, 0x80df4}, - {0x80e01, 0x80e3a}, {0x80e3f, 0x80e5b}, {0x80e94, 0x80e97}, {0x80e99, 0x80e9f}, - {0x80ea1, 0x80ea3}, {0x80ead, 0x80eb9}, {0x80ebb, 0x80ebd}, {0x80ec0, 0x80ec4}, - {0x80ec8, 0x80ecd}, {0x80ed0, 0x80ed9}, {0x80edc, 0x80edf}, {0x80f00, 0x80f47}, - {0x80f49, 0x80f6c}, {0x80f71, 0x80f97}, {0x80f99, 0x80fbc}, {0x80fbe, 0x80fcc}, - {0x80fce, 0x80fda}, {0x81000, 0x810c5}, {0x810d0, 0x81248}, {0x8124a, 0x8124d}, - {0x81250, 0x81256}, {0x8125a, 0x8125d}, {0x81260, 0x81288}, {0x8128a, 0x8128d}, - {0x81290, 0x812b0}, {0x812b2, 0x812b5}, {0x812b8, 0x812be}, {0x812c2, 0x812c5}, - {0x812c8, 0x812d6}, {0x812d8, 0x81310}, {0x81312, 0x81315}, {0x81318, 0x8135a}, - {0x8135d, 0x8137c}, {0x81380, 0x81399}, {0x813a0, 0x813f5}, {0x813f8, 0x813fd}, - {0x81400, 0x8167f}, {0x81681, 0x8169c}, {0x816a0, 0x816f8}, {0x81700, 0x8170c}, - {0x8170e, 0x81714}, {0x81720, 0x81736}, {0x81740, 0x81753}, {0x81760, 0x8176c}, - {0x8176e, 0x81770}, {0x81780, 0x817dd}, {0x817e0, 0x817e9}, {0x817f0, 0x817f9}, - {0x81800, 0x8180d}, {0x81810, 0x81819}, {0x81820, 0x81877}, {0x81880, 0x818aa}, - {0x818b0, 0x818f5}, {0x81900, 0x8191e}, {0x81920, 0x8192b}, {0x81930, 0x8193b}, - {0x81944, 0x8196d}, {0x81970, 0x81974}, {0x81980, 0x819ab}, {0x819b0, 0x819c9}, - {0x819d0, 0x819da}, {0x819de, 0x81a1b}, {0x81a1e, 0x81a5e}, {0x81a60, 0x81a7c}, - {0x81a7f, 0x81a89}, {0x81a90, 0x81a99}, {0x81aa0, 0x81aad}, {0x81ab0, 0x81abe}, - {0x81b00, 0x81b4b}, {0x81b50, 0x81b7c}, {0x81b80, 0x81bf3}, {0x81bfc, 0x81c37}, - {0x81c3b, 0x81c49}, {0x81c4d, 0x81c88}, {0x81cc0, 0x81cc7}, {0x81cd0, 0x81cf9}, - {0x81d00, 0x81df9}, {0x81dfb, 0x81f15}, {0x81f18, 0x81f1d}, {0x81f20, 0x81f45}, - {0x81f48, 0x81f4d}, {0x81f50, 0x81f57}, {0x81f5f, 0x81f7d}, {0x81f80, 0x81fb4}, - {0x81fb6, 0x81fc4}, {0x81fc6, 0x81fd3}, {0x81fd6, 0x81fdb}, {0x81fdd, 0x81fef}, - {0x81ff2, 0x81ff4}, {0x81ff6, 0x81ffe}, {0x82010, 0x82027}, {0x82030, 0x8205e}, - {0x82074, 0x8208e}, {0x82090, 0x8209c}, {0x820a0, 0x820bf}, {0x820d0, 0x820f0}, - {0x82100, 0x8218b}, {0x82190, 0x82426}, {0x82440, 0x8244a}, {0x82460, 0x82b73}, - {0x82b76, 0x82b95}, {0x82b98, 0x82bb9}, {0x82bbd, 0x82bc8}, {0x82bca, 0x82bd2}, - {0x82bec, 0x82bef}, {0x82c00, 0x82c2e}, {0x82c30, 0x82c5e}, {0x82c60, 0x82cf3}, - {0x82cf9, 0x82d25}, {0x82d30, 0x82d67}, {0x82d7f, 0x82d96}, {0x82da0, 0x82da6}, - {0x82da8, 0x82dae}, {0x82db0, 0x82db6}, {0x82db8, 0x82dbe}, {0x82dc0, 0x82dc6}, - {0x82dc8, 0x82dce}, {0x82dd0, 0x82dd6}, {0x82dd8, 0x82dde}, {0x82de0, 0x82e49}, - {0x82e80, 0x82e99}, {0x82e9b, 0x82ef3}, {0x82f00, 0x82fd5}, {0x82ff0, 0x82ffb}, - {0x83001, 0x8303f}, {0x83041, 0x83096}, {0x83099, 0x830ff}, {0x83105, 0x8312e}, - {0x83131, 0x8318e}, {0x83190, 0x831ba}, {0x831c0, 0x831e3}, {0x831f0, 0x8321e}, - {0x83220, 0x832fe}, {0x83300, 0x84db5}, {0x84dc0, 0x89fea}, {0x8a000, 0x8a48c}, - {0x8a490, 0x8a4c6}, {0x8a4d0, 0x8a62b}, {0x8a640, 0x8a6f7}, {0x8a700, 0x8a7ae}, - {0x8a7b0, 0x8a7b7}, {0x8a7f7, 0x8a82b}, {0x8a830, 0x8a839}, {0x8a840, 0x8a877}, - {0x8a880, 0x8a8c5}, {0x8a8ce, 0x8a8d9}, {0x8a8e0, 0x8a8fd}, {0x8a900, 0x8a953}, - {0x8a95f, 0x8a97c}, {0x8a980, 0x8a9cd}, {0x8a9cf, 0x8a9d9}, {0x8a9de, 0x8a9fe}, - {0x8aa00, 0x8aa36}, {0x8aa40, 0x8aa4d}, {0x8aa50, 0x8aa59}, {0x8aa5c, 0x8aac2}, - {0x8aadb, 0x8aaf6}, {0x8ab01, 0x8ab06}, {0x8ab09, 0x8ab0e}, {0x8ab11, 0x8ab16}, - {0x8ab20, 0x8ab26}, {0x8ab28, 0x8ab2e}, {0x8ab30, 0x8ab65}, {0x8ab70, 0x8abed}, - {0x8abf0, 0x8abf9}, {0x8ac00, 0x8d7a3}, {0x8d7b0, 0x8d7c6}, {0x8d7cb, 0x8d7fb}, - {0x8f900, 0x8fa6d}, {0x8fa70, 0x8fad9}, {0x8fb00, 0x8fb06}, {0x8fb13, 0x8fb17}, - {0x8fb1d, 0x8fb36}, {0x8fb38, 0x8fb3c}, {0x8fb46, 0x8fbc1}, {0x8fbd3, 0x8fd3f}, - {0x8fd50, 0x8fd8f}, {0x8fd92, 0x8fdc7}, {0x8fdf0, 0x8fdfd}, {0x8fe00, 0x8fe19}, - {0x8fe20, 0x8fe52}, {0x8fe54, 0x8fe66}, {0x8fe68, 0x8fe6b}, {0x8fe70, 0x8fe74}, - {0x8fe76, 0x8fefc}, {0x8ff01, 0x8ffbe}, {0x8ffc2, 0x8ffc7}, {0x8ffca, 0x8ffcf}, - {0x8ffd2, 0x8ffd7}, {0x8ffda, 0x8ffdc}, {0x8ffe0, 0x8ffe6}, {0x8ffe8, 0x8ffee}, - {0x90021, 0x9007e}, {0x900a1, 0x900ac}, {0x900ae, 0x90377}, {0x9037a, 0x9037f}, - {0x90384, 0x9038a}, {0x9038e, 0x903a1}, {0x903a3, 0x9052f}, {0x90531, 0x90556}, - {0x90559, 0x9055f}, {0x90561, 0x90587}, {0x9058d, 0x9058f}, {0x90591, 0x905c7}, - {0x905d0, 0x905ea}, {0x905f0, 0x905f4}, {0x90606, 0x9061b}, {0x9061e, 0x906dc}, - {0x906de, 0x9070d}, {0x90710, 0x9074a}, {0x9074d, 0x907b1}, {0x907c0, 0x907fa}, - {0x90800, 0x9082d}, {0x90830, 0x9083e}, {0x90840, 0x9085b}, {0x90860, 0x9086a}, - {0x908a0, 0x908b4}, {0x908b6, 0x908bd}, {0x908d4, 0x908e1}, {0x908e3, 0x90983}, - {0x90985, 0x9098c}, {0x90993, 0x909a8}, {0x909aa, 0x909b0}, {0x909b6, 0x909b9}, - {0x909bc, 0x909c4}, {0x909cb, 0x909ce}, {0x909df, 0x909e3}, {0x909e6, 0x909fd}, - {0x90a01, 0x90a03}, {0x90a05, 0x90a0a}, {0x90a13, 0x90a28}, {0x90a2a, 0x90a30}, - {0x90a3e, 0x90a42}, {0x90a4b, 0x90a4d}, {0x90a59, 0x90a5c}, {0x90a66, 0x90a75}, - {0x90a81, 0x90a83}, {0x90a85, 0x90a8d}, {0x90a8f, 0x90a91}, {0x90a93, 0x90aa8}, - {0x90aaa, 0x90ab0}, {0x90ab5, 0x90ab9}, {0x90abc, 0x90ac5}, {0x90ac7, 0x90ac9}, - {0x90acb, 0x90acd}, {0x90ae0, 0x90ae3}, {0x90ae6, 0x90af1}, {0x90af9, 0x90aff}, - {0x90b01, 0x90b03}, {0x90b05, 0x90b0c}, {0x90b13, 0x90b28}, {0x90b2a, 0x90b30}, - {0x90b35, 0x90b39}, {0x90b3c, 0x90b44}, {0x90b4b, 0x90b4d}, {0x90b5f, 0x90b63}, - {0x90b66, 0x90b77}, {0x90b85, 0x90b8a}, {0x90b8e, 0x90b90}, {0x90b92, 0x90b95}, - {0x90ba8, 0x90baa}, {0x90bae, 0x90bb9}, {0x90bbe, 0x90bc2}, {0x90bc6, 0x90bc8}, - {0x90bca, 0x90bcd}, {0x90be6, 0x90bfa}, {0x90c00, 0x90c03}, {0x90c05, 0x90c0c}, - {0x90c0e, 0x90c10}, {0x90c12, 0x90c28}, {0x90c2a, 0x90c39}, {0x90c3d, 0x90c44}, - {0x90c46, 0x90c48}, {0x90c4a, 0x90c4d}, {0x90c58, 0x90c5a}, {0x90c60, 0x90c63}, - {0x90c66, 0x90c6f}, {0x90c78, 0x90c83}, {0x90c85, 0x90c8c}, {0x90c8e, 0x90c90}, - {0x90c92, 0x90ca8}, {0x90caa, 0x90cb3}, {0x90cb5, 0x90cb9}, {0x90cbc, 0x90cc4}, - {0x90cc6, 0x90cc8}, {0x90cca, 0x90ccd}, {0x90ce0, 0x90ce3}, {0x90ce6, 0x90cef}, - {0x90d00, 0x90d03}, {0x90d05, 0x90d0c}, {0x90d0e, 0x90d10}, {0x90d12, 0x90d44}, - {0x90d46, 0x90d48}, {0x90d4a, 0x90d4f}, {0x90d54, 0x90d63}, {0x90d66, 0x90d7f}, - {0x90d85, 0x90d96}, {0x90d9a, 0x90db1}, {0x90db3, 0x90dbb}, {0x90dc0, 0x90dc6}, - {0x90dcf, 0x90dd4}, {0x90dd8, 0x90ddf}, {0x90de6, 0x90def}, {0x90df2, 0x90df4}, - {0x90e01, 0x90e3a}, {0x90e3f, 0x90e5b}, {0x90e94, 0x90e97}, {0x90e99, 0x90e9f}, - {0x90ea1, 0x90ea3}, {0x90ead, 0x90eb9}, {0x90ebb, 0x90ebd}, {0x90ec0, 0x90ec4}, - {0x90ec8, 0x90ecd}, {0x90ed0, 0x90ed9}, {0x90edc, 0x90edf}, {0x90f00, 0x90f47}, - {0x90f49, 0x90f6c}, {0x90f71, 0x90f97}, {0x90f99, 0x90fbc}, {0x90fbe, 0x90fcc}, - {0x90fce, 0x90fda}, {0x91000, 0x910c5}, {0x910d0, 0x91248}, {0x9124a, 0x9124d}, - {0x91250, 0x91256}, {0x9125a, 0x9125d}, {0x91260, 0x91288}, {0x9128a, 0x9128d}, - {0x91290, 0x912b0}, {0x912b2, 0x912b5}, {0x912b8, 0x912be}, {0x912c2, 0x912c5}, - {0x912c8, 0x912d6}, {0x912d8, 0x91310}, {0x91312, 0x91315}, {0x91318, 0x9135a}, - {0x9135d, 0x9137c}, {0x91380, 0x91399}, {0x913a0, 0x913f5}, {0x913f8, 0x913fd}, - {0x91400, 0x9167f}, {0x91681, 0x9169c}, {0x916a0, 0x916f8}, {0x91700, 0x9170c}, - {0x9170e, 0x91714}, {0x91720, 0x91736}, {0x91740, 0x91753}, {0x91760, 0x9176c}, - {0x9176e, 0x91770}, {0x91780, 0x917dd}, {0x917e0, 0x917e9}, {0x917f0, 0x917f9}, - {0x91800, 0x9180d}, {0x91810, 0x91819}, {0x91820, 0x91877}, {0x91880, 0x918aa}, - {0x918b0, 0x918f5}, {0x91900, 0x9191e}, {0x91920, 0x9192b}, {0x91930, 0x9193b}, - {0x91944, 0x9196d}, {0x91970, 0x91974}, {0x91980, 0x919ab}, {0x919b0, 0x919c9}, - {0x919d0, 0x919da}, {0x919de, 0x91a1b}, {0x91a1e, 0x91a5e}, {0x91a60, 0x91a7c}, - {0x91a7f, 0x91a89}, {0x91a90, 0x91a99}, {0x91aa0, 0x91aad}, {0x91ab0, 0x91abe}, - {0x91b00, 0x91b4b}, {0x91b50, 0x91b7c}, {0x91b80, 0x91bf3}, {0x91bfc, 0x91c37}, - {0x91c3b, 0x91c49}, {0x91c4d, 0x91c88}, {0x91cc0, 0x91cc7}, {0x91cd0, 0x91cf9}, - {0x91d00, 0x91df9}, {0x91dfb, 0x91f15}, {0x91f18, 0x91f1d}, {0x91f20, 0x91f45}, - {0x91f48, 0x91f4d}, {0x91f50, 0x91f57}, {0x91f5f, 0x91f7d}, {0x91f80, 0x91fb4}, - {0x91fb6, 0x91fc4}, {0x91fc6, 0x91fd3}, {0x91fd6, 0x91fdb}, {0x91fdd, 0x91fef}, - {0x91ff2, 0x91ff4}, {0x91ff6, 0x91ffe}, {0x92010, 0x92027}, {0x92030, 0x9205e}, - {0x92074, 0x9208e}, {0x92090, 0x9209c}, {0x920a0, 0x920bf}, {0x920d0, 0x920f0}, - {0x92100, 0x9218b}, {0x92190, 0x92426}, {0x92440, 0x9244a}, {0x92460, 0x92b73}, - {0x92b76, 0x92b95}, {0x92b98, 0x92bb9}, {0x92bbd, 0x92bc8}, {0x92bca, 0x92bd2}, - {0x92bec, 0x92bef}, {0x92c00, 0x92c2e}, {0x92c30, 0x92c5e}, {0x92c60, 0x92cf3}, - {0x92cf9, 0x92d25}, {0x92d30, 0x92d67}, {0x92d7f, 0x92d96}, {0x92da0, 0x92da6}, - {0x92da8, 0x92dae}, {0x92db0, 0x92db6}, {0x92db8, 0x92dbe}, {0x92dc0, 0x92dc6}, - {0x92dc8, 0x92dce}, {0x92dd0, 0x92dd6}, {0x92dd8, 0x92dde}, {0x92de0, 0x92e49}, - {0x92e80, 0x92e99}, {0x92e9b, 0x92ef3}, {0x92f00, 0x92fd5}, {0x92ff0, 0x92ffb}, - {0x93001, 0x9303f}, {0x93041, 0x93096}, {0x93099, 0x930ff}, {0x93105, 0x9312e}, - {0x93131, 0x9318e}, {0x93190, 0x931ba}, {0x931c0, 0x931e3}, {0x931f0, 0x9321e}, - {0x93220, 0x932fe}, {0x93300, 0x94db5}, {0x94dc0, 0x99fea}, {0x9a000, 0x9a48c}, - {0x9a490, 0x9a4c6}, {0x9a4d0, 0x9a62b}, {0x9a640, 0x9a6f7}, {0x9a700, 0x9a7ae}, - {0x9a7b0, 0x9a7b7}, {0x9a7f7, 0x9a82b}, {0x9a830, 0x9a839}, {0x9a840, 0x9a877}, - {0x9a880, 0x9a8c5}, {0x9a8ce, 0x9a8d9}, {0x9a8e0, 0x9a8fd}, {0x9a900, 0x9a953}, - {0x9a95f, 0x9a97c}, {0x9a980, 0x9a9cd}, {0x9a9cf, 0x9a9d9}, {0x9a9de, 0x9a9fe}, - {0x9aa00, 0x9aa36}, {0x9aa40, 0x9aa4d}, {0x9aa50, 0x9aa59}, {0x9aa5c, 0x9aac2}, - {0x9aadb, 0x9aaf6}, {0x9ab01, 0x9ab06}, {0x9ab09, 0x9ab0e}, {0x9ab11, 0x9ab16}, - {0x9ab20, 0x9ab26}, {0x9ab28, 0x9ab2e}, {0x9ab30, 0x9ab65}, {0x9ab70, 0x9abed}, - {0x9abf0, 0x9abf9}, {0x9ac00, 0x9d7a3}, {0x9d7b0, 0x9d7c6}, {0x9d7cb, 0x9d7fb}, - {0x9f900, 0x9fa6d}, {0x9fa70, 0x9fad9}, {0x9fb00, 0x9fb06}, {0x9fb13, 0x9fb17}, - {0x9fb1d, 0x9fb36}, {0x9fb38, 0x9fb3c}, {0x9fb46, 0x9fbc1}, {0x9fbd3, 0x9fd3f}, - {0x9fd50, 0x9fd8f}, {0x9fd92, 0x9fdc7}, {0x9fdf0, 0x9fdfd}, {0x9fe00, 0x9fe19}, - {0x9fe20, 0x9fe52}, {0x9fe54, 0x9fe66}, {0x9fe68, 0x9fe6b}, {0x9fe70, 0x9fe74}, - {0x9fe76, 0x9fefc}, {0x9ff01, 0x9ffbe}, {0x9ffc2, 0x9ffc7}, {0x9ffca, 0x9ffcf}, - {0x9ffd2, 0x9ffd7}, {0x9ffda, 0x9ffdc}, {0x9ffe0, 0x9ffe6}, {0x9ffe8, 0x9ffee}, - {0xa0021, 0xa007e}, {0xa00a1, 0xa00ac}, {0xa00ae, 0xa0377}, {0xa037a, 0xa037f}, - {0xa0384, 0xa038a}, {0xa038e, 0xa03a1}, {0xa03a3, 0xa052f}, {0xa0531, 0xa0556}, - {0xa0559, 0xa055f}, {0xa0561, 0xa0587}, {0xa058d, 0xa058f}, {0xa0591, 0xa05c7}, - {0xa05d0, 0xa05ea}, {0xa05f0, 0xa05f4}, {0xa0606, 0xa061b}, {0xa061e, 0xa06dc}, - {0xa06de, 0xa070d}, {0xa0710, 0xa074a}, {0xa074d, 0xa07b1}, {0xa07c0, 0xa07fa}, - {0xa0800, 0xa082d}, {0xa0830, 0xa083e}, {0xa0840, 0xa085b}, {0xa0860, 0xa086a}, - {0xa08a0, 0xa08b4}, {0xa08b6, 0xa08bd}, {0xa08d4, 0xa08e1}, {0xa08e3, 0xa0983}, - {0xa0985, 0xa098c}, {0xa0993, 0xa09a8}, {0xa09aa, 0xa09b0}, {0xa09b6, 0xa09b9}, - {0xa09bc, 0xa09c4}, {0xa09cb, 0xa09ce}, {0xa09df, 0xa09e3}, {0xa09e6, 0xa09fd}, - {0xa0a01, 0xa0a03}, {0xa0a05, 0xa0a0a}, {0xa0a13, 0xa0a28}, {0xa0a2a, 0xa0a30}, - {0xa0a3e, 0xa0a42}, {0xa0a4b, 0xa0a4d}, {0xa0a59, 0xa0a5c}, {0xa0a66, 0xa0a75}, - {0xa0a81, 0xa0a83}, {0xa0a85, 0xa0a8d}, {0xa0a8f, 0xa0a91}, {0xa0a93, 0xa0aa8}, - {0xa0aaa, 0xa0ab0}, {0xa0ab5, 0xa0ab9}, {0xa0abc, 0xa0ac5}, {0xa0ac7, 0xa0ac9}, - {0xa0acb, 0xa0acd}, {0xa0ae0, 0xa0ae3}, {0xa0ae6, 0xa0af1}, {0xa0af9, 0xa0aff}, - {0xa0b01, 0xa0b03}, {0xa0b05, 0xa0b0c}, {0xa0b13, 0xa0b28}, {0xa0b2a, 0xa0b30}, - {0xa0b35, 0xa0b39}, {0xa0b3c, 0xa0b44}, {0xa0b4b, 0xa0b4d}, {0xa0b5f, 0xa0b63}, - {0xa0b66, 0xa0b77}, {0xa0b85, 0xa0b8a}, {0xa0b8e, 0xa0b90}, {0xa0b92, 0xa0b95}, - {0xa0ba8, 0xa0baa}, {0xa0bae, 0xa0bb9}, {0xa0bbe, 0xa0bc2}, {0xa0bc6, 0xa0bc8}, - {0xa0bca, 0xa0bcd}, {0xa0be6, 0xa0bfa}, {0xa0c00, 0xa0c03}, {0xa0c05, 0xa0c0c}, - {0xa0c0e, 0xa0c10}, {0xa0c12, 0xa0c28}, {0xa0c2a, 0xa0c39}, {0xa0c3d, 0xa0c44}, - {0xa0c46, 0xa0c48}, {0xa0c4a, 0xa0c4d}, {0xa0c58, 0xa0c5a}, {0xa0c60, 0xa0c63}, - {0xa0c66, 0xa0c6f}, {0xa0c78, 0xa0c83}, {0xa0c85, 0xa0c8c}, {0xa0c8e, 0xa0c90}, - {0xa0c92, 0xa0ca8}, {0xa0caa, 0xa0cb3}, {0xa0cb5, 0xa0cb9}, {0xa0cbc, 0xa0cc4}, - {0xa0cc6, 0xa0cc8}, {0xa0cca, 0xa0ccd}, {0xa0ce0, 0xa0ce3}, {0xa0ce6, 0xa0cef}, - {0xa0d00, 0xa0d03}, {0xa0d05, 0xa0d0c}, {0xa0d0e, 0xa0d10}, {0xa0d12, 0xa0d44}, - {0xa0d46, 0xa0d48}, {0xa0d4a, 0xa0d4f}, {0xa0d54, 0xa0d63}, {0xa0d66, 0xa0d7f}, - {0xa0d85, 0xa0d96}, {0xa0d9a, 0xa0db1}, {0xa0db3, 0xa0dbb}, {0xa0dc0, 0xa0dc6}, - {0xa0dcf, 0xa0dd4}, {0xa0dd8, 0xa0ddf}, {0xa0de6, 0xa0def}, {0xa0df2, 0xa0df4}, - {0xa0e01, 0xa0e3a}, {0xa0e3f, 0xa0e5b}, {0xa0e94, 0xa0e97}, {0xa0e99, 0xa0e9f}, - {0xa0ea1, 0xa0ea3}, {0xa0ead, 0xa0eb9}, {0xa0ebb, 0xa0ebd}, {0xa0ec0, 0xa0ec4}, - {0xa0ec8, 0xa0ecd}, {0xa0ed0, 0xa0ed9}, {0xa0edc, 0xa0edf}, {0xa0f00, 0xa0f47}, - {0xa0f49, 0xa0f6c}, {0xa0f71, 0xa0f97}, {0xa0f99, 0xa0fbc}, {0xa0fbe, 0xa0fcc}, - {0xa0fce, 0xa0fda}, {0xa1000, 0xa10c5}, {0xa10d0, 0xa1248}, {0xa124a, 0xa124d}, - {0xa1250, 0xa1256}, {0xa125a, 0xa125d}, {0xa1260, 0xa1288}, {0xa128a, 0xa128d}, - {0xa1290, 0xa12b0}, {0xa12b2, 0xa12b5}, {0xa12b8, 0xa12be}, {0xa12c2, 0xa12c5}, - {0xa12c8, 0xa12d6}, {0xa12d8, 0xa1310}, {0xa1312, 0xa1315}, {0xa1318, 0xa135a}, - {0xa135d, 0xa137c}, {0xa1380, 0xa1399}, {0xa13a0, 0xa13f5}, {0xa13f8, 0xa13fd}, - {0xa1400, 0xa167f}, {0xa1681, 0xa169c}, {0xa16a0, 0xa16f8}, {0xa1700, 0xa170c}, - {0xa170e, 0xa1714}, {0xa1720, 0xa1736}, {0xa1740, 0xa1753}, {0xa1760, 0xa176c}, - {0xa176e, 0xa1770}, {0xa1780, 0xa17dd}, {0xa17e0, 0xa17e9}, {0xa17f0, 0xa17f9}, - {0xa1800, 0xa180d}, {0xa1810, 0xa1819}, {0xa1820, 0xa1877}, {0xa1880, 0xa18aa}, - {0xa18b0, 0xa18f5}, {0xa1900, 0xa191e}, {0xa1920, 0xa192b}, {0xa1930, 0xa193b}, - {0xa1944, 0xa196d}, {0xa1970, 0xa1974}, {0xa1980, 0xa19ab}, {0xa19b0, 0xa19c9}, - {0xa19d0, 0xa19da}, {0xa19de, 0xa1a1b}, {0xa1a1e, 0xa1a5e}, {0xa1a60, 0xa1a7c}, - {0xa1a7f, 0xa1a89}, {0xa1a90, 0xa1a99}, {0xa1aa0, 0xa1aad}, {0xa1ab0, 0xa1abe}, - {0xa1b00, 0xa1b4b}, {0xa1b50, 0xa1b7c}, {0xa1b80, 0xa1bf3}, {0xa1bfc, 0xa1c37}, - {0xa1c3b, 0xa1c49}, {0xa1c4d, 0xa1c88}, {0xa1cc0, 0xa1cc7}, {0xa1cd0, 0xa1cf9}, - {0xa1d00, 0xa1df9}, {0xa1dfb, 0xa1f15}, {0xa1f18, 0xa1f1d}, {0xa1f20, 0xa1f45}, - {0xa1f48, 0xa1f4d}, {0xa1f50, 0xa1f57}, {0xa1f5f, 0xa1f7d}, {0xa1f80, 0xa1fb4}, - {0xa1fb6, 0xa1fc4}, {0xa1fc6, 0xa1fd3}, {0xa1fd6, 0xa1fdb}, {0xa1fdd, 0xa1fef}, - {0xa1ff2, 0xa1ff4}, {0xa1ff6, 0xa1ffe}, {0xa2010, 0xa2027}, {0xa2030, 0xa205e}, - {0xa2074, 0xa208e}, {0xa2090, 0xa209c}, {0xa20a0, 0xa20bf}, {0xa20d0, 0xa20f0}, - {0xa2100, 0xa218b}, {0xa2190, 0xa2426}, {0xa2440, 0xa244a}, {0xa2460, 0xa2b73}, - {0xa2b76, 0xa2b95}, {0xa2b98, 0xa2bb9}, {0xa2bbd, 0xa2bc8}, {0xa2bca, 0xa2bd2}, - {0xa2bec, 0xa2bef}, {0xa2c00, 0xa2c2e}, {0xa2c30, 0xa2c5e}, {0xa2c60, 0xa2cf3}, - {0xa2cf9, 0xa2d25}, {0xa2d30, 0xa2d67}, {0xa2d7f, 0xa2d96}, {0xa2da0, 0xa2da6}, - {0xa2da8, 0xa2dae}, {0xa2db0, 0xa2db6}, {0xa2db8, 0xa2dbe}, {0xa2dc0, 0xa2dc6}, - {0xa2dc8, 0xa2dce}, {0xa2dd0, 0xa2dd6}, {0xa2dd8, 0xa2dde}, {0xa2de0, 0xa2e49}, - {0xa2e80, 0xa2e99}, {0xa2e9b, 0xa2ef3}, {0xa2f00, 0xa2fd5}, {0xa2ff0, 0xa2ffb}, - {0xa3001, 0xa303f}, {0xa3041, 0xa3096}, {0xa3099, 0xa30ff}, {0xa3105, 0xa312e}, - {0xa3131, 0xa318e}, {0xa3190, 0xa31ba}, {0xa31c0, 0xa31e3}, {0xa31f0, 0xa321e}, - {0xa3220, 0xa32fe}, {0xa3300, 0xa4db5}, {0xa4dc0, 0xa9fea}, {0xaa000, 0xaa48c}, - {0xaa490, 0xaa4c6}, {0xaa4d0, 0xaa62b}, {0xaa640, 0xaa6f7}, {0xaa700, 0xaa7ae}, - {0xaa7b0, 0xaa7b7}, {0xaa7f7, 0xaa82b}, {0xaa830, 0xaa839}, {0xaa840, 0xaa877}, - {0xaa880, 0xaa8c5}, {0xaa8ce, 0xaa8d9}, {0xaa8e0, 0xaa8fd}, {0xaa900, 0xaa953}, - {0xaa95f, 0xaa97c}, {0xaa980, 0xaa9cd}, {0xaa9cf, 0xaa9d9}, {0xaa9de, 0xaa9fe}, - {0xaaa00, 0xaaa36}, {0xaaa40, 0xaaa4d}, {0xaaa50, 0xaaa59}, {0xaaa5c, 0xaaac2}, - {0xaaadb, 0xaaaf6}, {0xaab01, 0xaab06}, {0xaab09, 0xaab0e}, {0xaab11, 0xaab16}, - {0xaab20, 0xaab26}, {0xaab28, 0xaab2e}, {0xaab30, 0xaab65}, {0xaab70, 0xaabed}, - {0xaabf0, 0xaabf9}, {0xaac00, 0xad7a3}, {0xad7b0, 0xad7c6}, {0xad7cb, 0xad7fb}, - {0xaf900, 0xafa6d}, {0xafa70, 0xafad9}, {0xafb00, 0xafb06}, {0xafb13, 0xafb17}, - {0xafb1d, 0xafb36}, {0xafb38, 0xafb3c}, {0xafb46, 0xafbc1}, {0xafbd3, 0xafd3f}, - {0xafd50, 0xafd8f}, {0xafd92, 0xafdc7}, {0xafdf0, 0xafdfd}, {0xafe00, 0xafe19}, - {0xafe20, 0xafe52}, {0xafe54, 0xafe66}, {0xafe68, 0xafe6b}, {0xafe70, 0xafe74}, - {0xafe76, 0xafefc}, {0xaff01, 0xaffbe}, {0xaffc2, 0xaffc7}, {0xaffca, 0xaffcf}, - {0xaffd2, 0xaffd7}, {0xaffda, 0xaffdc}, {0xaffe0, 0xaffe6}, {0xaffe8, 0xaffee}, - {0xb0021, 0xb007e}, {0xb00a1, 0xb00ac}, {0xb00ae, 0xb0377}, {0xb037a, 0xb037f}, - {0xb0384, 0xb038a}, {0xb038e, 0xb03a1}, {0xb03a3, 0xb052f}, {0xb0531, 0xb0556}, - {0xb0559, 0xb055f}, {0xb0561, 0xb0587}, {0xb058d, 0xb058f}, {0xb0591, 0xb05c7}, - {0xb05d0, 0xb05ea}, {0xb05f0, 0xb05f4}, {0xb0606, 0xb061b}, {0xb061e, 0xb06dc}, - {0xb06de, 0xb070d}, {0xb0710, 0xb074a}, {0xb074d, 0xb07b1}, {0xb07c0, 0xb07fa}, - {0xb0800, 0xb082d}, {0xb0830, 0xb083e}, {0xb0840, 0xb085b}, {0xb0860, 0xb086a}, - {0xb08a0, 0xb08b4}, {0xb08b6, 0xb08bd}, {0xb08d4, 0xb08e1}, {0xb08e3, 0xb0983}, - {0xb0985, 0xb098c}, {0xb0993, 0xb09a8}, {0xb09aa, 0xb09b0}, {0xb09b6, 0xb09b9}, - {0xb09bc, 0xb09c4}, {0xb09cb, 0xb09ce}, {0xb09df, 0xb09e3}, {0xb09e6, 0xb09fd}, - {0xb0a01, 0xb0a03}, {0xb0a05, 0xb0a0a}, {0xb0a13, 0xb0a28}, {0xb0a2a, 0xb0a30}, - {0xb0a3e, 0xb0a42}, {0xb0a4b, 0xb0a4d}, {0xb0a59, 0xb0a5c}, {0xb0a66, 0xb0a75}, - {0xb0a81, 0xb0a83}, {0xb0a85, 0xb0a8d}, {0xb0a8f, 0xb0a91}, {0xb0a93, 0xb0aa8}, - {0xb0aaa, 0xb0ab0}, {0xb0ab5, 0xb0ab9}, {0xb0abc, 0xb0ac5}, {0xb0ac7, 0xb0ac9}, - {0xb0acb, 0xb0acd}, {0xb0ae0, 0xb0ae3}, {0xb0ae6, 0xb0af1}, {0xb0af9, 0xb0aff}, - {0xb0b01, 0xb0b03}, {0xb0b05, 0xb0b0c}, {0xb0b13, 0xb0b28}, {0xb0b2a, 0xb0b30}, - {0xb0b35, 0xb0b39}, {0xb0b3c, 0xb0b44}, {0xb0b4b, 0xb0b4d}, {0xb0b5f, 0xb0b63}, - {0xb0b66, 0xb0b77}, {0xb0b85, 0xb0b8a}, {0xb0b8e, 0xb0b90}, {0xb0b92, 0xb0b95}, - {0xb0ba8, 0xb0baa}, {0xb0bae, 0xb0bb9}, {0xb0bbe, 0xb0bc2}, {0xb0bc6, 0xb0bc8}, - {0xb0bca, 0xb0bcd}, {0xb0be6, 0xb0bfa}, {0xb0c00, 0xb0c03}, {0xb0c05, 0xb0c0c}, - {0xb0c0e, 0xb0c10}, {0xb0c12, 0xb0c28}, {0xb0c2a, 0xb0c39}, {0xb0c3d, 0xb0c44}, - {0xb0c46, 0xb0c48}, {0xb0c4a, 0xb0c4d}, {0xb0c58, 0xb0c5a}, {0xb0c60, 0xb0c63}, - {0xb0c66, 0xb0c6f}, {0xb0c78, 0xb0c83}, {0xb0c85, 0xb0c8c}, {0xb0c8e, 0xb0c90}, - {0xb0c92, 0xb0ca8}, {0xb0caa, 0xb0cb3}, {0xb0cb5, 0xb0cb9}, {0xb0cbc, 0xb0cc4}, - {0xb0cc6, 0xb0cc8}, {0xb0cca, 0xb0ccd}, {0xb0ce0, 0xb0ce3}, {0xb0ce6, 0xb0cef}, - {0xb0d00, 0xb0d03}, {0xb0d05, 0xb0d0c}, {0xb0d0e, 0xb0d10}, {0xb0d12, 0xb0d44}, - {0xb0d46, 0xb0d48}, {0xb0d4a, 0xb0d4f}, {0xb0d54, 0xb0d63}, {0xb0d66, 0xb0d7f}, - {0xb0d85, 0xb0d96}, {0xb0d9a, 0xb0db1}, {0xb0db3, 0xb0dbb}, {0xb0dc0, 0xb0dc6}, - {0xb0dcf, 0xb0dd4}, {0xb0dd8, 0xb0ddf}, {0xb0de6, 0xb0def}, {0xb0df2, 0xb0df4}, - {0xb0e01, 0xb0e3a}, {0xb0e3f, 0xb0e5b}, {0xb0e94, 0xb0e97}, {0xb0e99, 0xb0e9f}, - {0xb0ea1, 0xb0ea3}, {0xb0ead, 0xb0eb9}, {0xb0ebb, 0xb0ebd}, {0xb0ec0, 0xb0ec4}, - {0xb0ec8, 0xb0ecd}, {0xb0ed0, 0xb0ed9}, {0xb0edc, 0xb0edf}, {0xb0f00, 0xb0f47}, - {0xb0f49, 0xb0f6c}, {0xb0f71, 0xb0f97}, {0xb0f99, 0xb0fbc}, {0xb0fbe, 0xb0fcc}, - {0xb0fce, 0xb0fda}, {0xb1000, 0xb10c5}, {0xb10d0, 0xb1248}, {0xb124a, 0xb124d}, - {0xb1250, 0xb1256}, {0xb125a, 0xb125d}, {0xb1260, 0xb1288}, {0xb128a, 0xb128d}, - {0xb1290, 0xb12b0}, {0xb12b2, 0xb12b5}, {0xb12b8, 0xb12be}, {0xb12c2, 0xb12c5}, - {0xb12c8, 0xb12d6}, {0xb12d8, 0xb1310}, {0xb1312, 0xb1315}, {0xb1318, 0xb135a}, - {0xb135d, 0xb137c}, {0xb1380, 0xb1399}, {0xb13a0, 0xb13f5}, {0xb13f8, 0xb13fd}, - {0xb1400, 0xb167f}, {0xb1681, 0xb169c}, {0xb16a0, 0xb16f8}, {0xb1700, 0xb170c}, - {0xb170e, 0xb1714}, {0xb1720, 0xb1736}, {0xb1740, 0xb1753}, {0xb1760, 0xb176c}, - {0xb176e, 0xb1770}, {0xb1780, 0xb17dd}, {0xb17e0, 0xb17e9}, {0xb17f0, 0xb17f9}, - {0xb1800, 0xb180d}, {0xb1810, 0xb1819}, {0xb1820, 0xb1877}, {0xb1880, 0xb18aa}, - {0xb18b0, 0xb18f5}, {0xb1900, 0xb191e}, {0xb1920, 0xb192b}, {0xb1930, 0xb193b}, - {0xb1944, 0xb196d}, {0xb1970, 0xb1974}, {0xb1980, 0xb19ab}, {0xb19b0, 0xb19c9}, - {0xb19d0, 0xb19da}, {0xb19de, 0xb1a1b}, {0xb1a1e, 0xb1a5e}, {0xb1a60, 0xb1a7c}, - {0xb1a7f, 0xb1a89}, {0xb1a90, 0xb1a99}, {0xb1aa0, 0xb1aad}, {0xb1ab0, 0xb1abe}, - {0xb1b00, 0xb1b4b}, {0xb1b50, 0xb1b7c}, {0xb1b80, 0xb1bf3}, {0xb1bfc, 0xb1c37}, - {0xb1c3b, 0xb1c49}, {0xb1c4d, 0xb1c88}, {0xb1cc0, 0xb1cc7}, {0xb1cd0, 0xb1cf9}, - {0xb1d00, 0xb1df9}, {0xb1dfb, 0xb1f15}, {0xb1f18, 0xb1f1d}, {0xb1f20, 0xb1f45}, - {0xb1f48, 0xb1f4d}, {0xb1f50, 0xb1f57}, {0xb1f5f, 0xb1f7d}, {0xb1f80, 0xb1fb4}, - {0xb1fb6, 0xb1fc4}, {0xb1fc6, 0xb1fd3}, {0xb1fd6, 0xb1fdb}, {0xb1fdd, 0xb1fef}, - {0xb1ff2, 0xb1ff4}, {0xb1ff6, 0xb1ffe}, {0xb2010, 0xb2027}, {0xb2030, 0xb205e}, - {0xb2074, 0xb208e}, {0xb2090, 0xb209c}, {0xb20a0, 0xb20bf}, {0xb20d0, 0xb20f0}, - {0xb2100, 0xb218b}, {0xb2190, 0xb2426}, {0xb2440, 0xb244a}, {0xb2460, 0xb2b73}, - {0xb2b76, 0xb2b95}, {0xb2b98, 0xb2bb9}, {0xb2bbd, 0xb2bc8}, {0xb2bca, 0xb2bd2}, - {0xb2bec, 0xb2bef}, {0xb2c00, 0xb2c2e}, {0xb2c30, 0xb2c5e}, {0xb2c60, 0xb2cf3}, - {0xb2cf9, 0xb2d25}, {0xb2d30, 0xb2d67}, {0xb2d7f, 0xb2d96}, {0xb2da0, 0xb2da6}, - {0xb2da8, 0xb2dae}, {0xb2db0, 0xb2db6}, {0xb2db8, 0xb2dbe}, {0xb2dc0, 0xb2dc6}, - {0xb2dc8, 0xb2dce}, {0xb2dd0, 0xb2dd6}, {0xb2dd8, 0xb2dde}, {0xb2de0, 0xb2e49}, - {0xb2e80, 0xb2e99}, {0xb2e9b, 0xb2ef3}, {0xb2f00, 0xb2fd5}, {0xb2ff0, 0xb2ffb}, - {0xb3001, 0xb303f}, {0xb3041, 0xb3096}, {0xb3099, 0xb30ff}, {0xb3105, 0xb312e}, - {0xb3131, 0xb318e}, {0xb3190, 0xb31ba}, {0xb31c0, 0xb31e3}, {0xb31f0, 0xb321e}, - {0xb3220, 0xb32fe}, {0xb3300, 0xb4db5}, {0xb4dc0, 0xb9fea}, {0xba000, 0xba48c}, - {0xba490, 0xba4c6}, {0xba4d0, 0xba62b}, {0xba640, 0xba6f7}, {0xba700, 0xba7ae}, - {0xba7b0, 0xba7b7}, {0xba7f7, 0xba82b}, {0xba830, 0xba839}, {0xba840, 0xba877}, - {0xba880, 0xba8c5}, {0xba8ce, 0xba8d9}, {0xba8e0, 0xba8fd}, {0xba900, 0xba953}, - {0xba95f, 0xba97c}, {0xba980, 0xba9cd}, {0xba9cf, 0xba9d9}, {0xba9de, 0xba9fe}, - {0xbaa00, 0xbaa36}, {0xbaa40, 0xbaa4d}, {0xbaa50, 0xbaa59}, {0xbaa5c, 0xbaac2}, - {0xbaadb, 0xbaaf6}, {0xbab01, 0xbab06}, {0xbab09, 0xbab0e}, {0xbab11, 0xbab16}, - {0xbab20, 0xbab26}, {0xbab28, 0xbab2e}, {0xbab30, 0xbab65}, {0xbab70, 0xbabed}, - {0xbabf0, 0xbabf9}, {0xbac00, 0xbd7a3}, {0xbd7b0, 0xbd7c6}, {0xbd7cb, 0xbd7fb}, - {0xbf900, 0xbfa6d}, {0xbfa70, 0xbfad9}, {0xbfb00, 0xbfb06}, {0xbfb13, 0xbfb17}, - {0xbfb1d, 0xbfb36}, {0xbfb38, 0xbfb3c}, {0xbfb46, 0xbfbc1}, {0xbfbd3, 0xbfd3f}, - {0xbfd50, 0xbfd8f}, {0xbfd92, 0xbfdc7}, {0xbfdf0, 0xbfdfd}, {0xbfe00, 0xbfe19}, - {0xbfe20, 0xbfe52}, {0xbfe54, 0xbfe66}, {0xbfe68, 0xbfe6b}, {0xbfe70, 0xbfe74}, - {0xbfe76, 0xbfefc}, {0xbff01, 0xbffbe}, {0xbffc2, 0xbffc7}, {0xbffca, 0xbffcf}, - {0xbffd2, 0xbffd7}, {0xbffda, 0xbffdc}, {0xbffe0, 0xbffe6}, {0xbffe8, 0xbffee}, - {0xc0021, 0xc007e}, {0xc00a1, 0xc00ac}, {0xc00ae, 0xc0377}, {0xc037a, 0xc037f}, - {0xc0384, 0xc038a}, {0xc038e, 0xc03a1}, {0xc03a3, 0xc052f}, {0xc0531, 0xc0556}, - {0xc0559, 0xc055f}, {0xc0561, 0xc0587}, {0xc058d, 0xc058f}, {0xc0591, 0xc05c7}, - {0xc05d0, 0xc05ea}, {0xc05f0, 0xc05f4}, {0xc0606, 0xc061b}, {0xc061e, 0xc06dc}, - {0xc06de, 0xc070d}, {0xc0710, 0xc074a}, {0xc074d, 0xc07b1}, {0xc07c0, 0xc07fa}, - {0xc0800, 0xc082d}, {0xc0830, 0xc083e}, {0xc0840, 0xc085b}, {0xc0860, 0xc086a}, - {0xc08a0, 0xc08b4}, {0xc08b6, 0xc08bd}, {0xc08d4, 0xc08e1}, {0xc08e3, 0xc0983}, - {0xc0985, 0xc098c}, {0xc0993, 0xc09a8}, {0xc09aa, 0xc09b0}, {0xc09b6, 0xc09b9}, - {0xc09bc, 0xc09c4}, {0xc09cb, 0xc09ce}, {0xc09df, 0xc09e3}, {0xc09e6, 0xc09fd}, - {0xc0a01, 0xc0a03}, {0xc0a05, 0xc0a0a}, {0xc0a13, 0xc0a28}, {0xc0a2a, 0xc0a30}, - {0xc0a3e, 0xc0a42}, {0xc0a4b, 0xc0a4d}, {0xc0a59, 0xc0a5c}, {0xc0a66, 0xc0a75}, - {0xc0a81, 0xc0a83}, {0xc0a85, 0xc0a8d}, {0xc0a8f, 0xc0a91}, {0xc0a93, 0xc0aa8}, - {0xc0aaa, 0xc0ab0}, {0xc0ab5, 0xc0ab9}, {0xc0abc, 0xc0ac5}, {0xc0ac7, 0xc0ac9}, - {0xc0acb, 0xc0acd}, {0xc0ae0, 0xc0ae3}, {0xc0ae6, 0xc0af1}, {0xc0af9, 0xc0aff}, - {0xc0b01, 0xc0b03}, {0xc0b05, 0xc0b0c}, {0xc0b13, 0xc0b28}, {0xc0b2a, 0xc0b30}, - {0xc0b35, 0xc0b39}, {0xc0b3c, 0xc0b44}, {0xc0b4b, 0xc0b4d}, {0xc0b5f, 0xc0b63}, - {0xc0b66, 0xc0b77}, {0xc0b85, 0xc0b8a}, {0xc0b8e, 0xc0b90}, {0xc0b92, 0xc0b95}, - {0xc0ba8, 0xc0baa}, {0xc0bae, 0xc0bb9}, {0xc0bbe, 0xc0bc2}, {0xc0bc6, 0xc0bc8}, - {0xc0bca, 0xc0bcd}, {0xc0be6, 0xc0bfa}, {0xc0c00, 0xc0c03}, {0xc0c05, 0xc0c0c}, - {0xc0c0e, 0xc0c10}, {0xc0c12, 0xc0c28}, {0xc0c2a, 0xc0c39}, {0xc0c3d, 0xc0c44}, - {0xc0c46, 0xc0c48}, {0xc0c4a, 0xc0c4d}, {0xc0c58, 0xc0c5a}, {0xc0c60, 0xc0c63}, - {0xc0c66, 0xc0c6f}, {0xc0c78, 0xc0c83}, {0xc0c85, 0xc0c8c}, {0xc0c8e, 0xc0c90}, - {0xc0c92, 0xc0ca8}, {0xc0caa, 0xc0cb3}, {0xc0cb5, 0xc0cb9}, {0xc0cbc, 0xc0cc4}, - {0xc0cc6, 0xc0cc8}, {0xc0cca, 0xc0ccd}, {0xc0ce0, 0xc0ce3}, {0xc0ce6, 0xc0cef}, - {0xc0d00, 0xc0d03}, {0xc0d05, 0xc0d0c}, {0xc0d0e, 0xc0d10}, {0xc0d12, 0xc0d44}, - {0xc0d46, 0xc0d48}, {0xc0d4a, 0xc0d4f}, {0xc0d54, 0xc0d63}, {0xc0d66, 0xc0d7f}, - {0xc0d85, 0xc0d96}, {0xc0d9a, 0xc0db1}, {0xc0db3, 0xc0dbb}, {0xc0dc0, 0xc0dc6}, - {0xc0dcf, 0xc0dd4}, {0xc0dd8, 0xc0ddf}, {0xc0de6, 0xc0def}, {0xc0df2, 0xc0df4}, - {0xc0e01, 0xc0e3a}, {0xc0e3f, 0xc0e5b}, {0xc0e94, 0xc0e97}, {0xc0e99, 0xc0e9f}, - {0xc0ea1, 0xc0ea3}, {0xc0ead, 0xc0eb9}, {0xc0ebb, 0xc0ebd}, {0xc0ec0, 0xc0ec4}, - {0xc0ec8, 0xc0ecd}, {0xc0ed0, 0xc0ed9}, {0xc0edc, 0xc0edf}, {0xc0f00, 0xc0f47}, - {0xc0f49, 0xc0f6c}, {0xc0f71, 0xc0f97}, {0xc0f99, 0xc0fbc}, {0xc0fbe, 0xc0fcc}, - {0xc0fce, 0xc0fda}, {0xc1000, 0xc10c5}, {0xc10d0, 0xc1248}, {0xc124a, 0xc124d}, - {0xc1250, 0xc1256}, {0xc125a, 0xc125d}, {0xc1260, 0xc1288}, {0xc128a, 0xc128d}, - {0xc1290, 0xc12b0}, {0xc12b2, 0xc12b5}, {0xc12b8, 0xc12be}, {0xc12c2, 0xc12c5}, - {0xc12c8, 0xc12d6}, {0xc12d8, 0xc1310}, {0xc1312, 0xc1315}, {0xc1318, 0xc135a}, - {0xc135d, 0xc137c}, {0xc1380, 0xc1399}, {0xc13a0, 0xc13f5}, {0xc13f8, 0xc13fd}, - {0xc1400, 0xc167f}, {0xc1681, 0xc169c}, {0xc16a0, 0xc16f8}, {0xc1700, 0xc170c}, - {0xc170e, 0xc1714}, {0xc1720, 0xc1736}, {0xc1740, 0xc1753}, {0xc1760, 0xc176c}, - {0xc176e, 0xc1770}, {0xc1780, 0xc17dd}, {0xc17e0, 0xc17e9}, {0xc17f0, 0xc17f9}, - {0xc1800, 0xc180d}, {0xc1810, 0xc1819}, {0xc1820, 0xc1877}, {0xc1880, 0xc18aa}, - {0xc18b0, 0xc18f5}, {0xc1900, 0xc191e}, {0xc1920, 0xc192b}, {0xc1930, 0xc193b}, - {0xc1944, 0xc196d}, {0xc1970, 0xc1974}, {0xc1980, 0xc19ab}, {0xc19b0, 0xc19c9}, - {0xc19d0, 0xc19da}, {0xc19de, 0xc1a1b}, {0xc1a1e, 0xc1a5e}, {0xc1a60, 0xc1a7c}, - {0xc1a7f, 0xc1a89}, {0xc1a90, 0xc1a99}, {0xc1aa0, 0xc1aad}, {0xc1ab0, 0xc1abe}, - {0xc1b00, 0xc1b4b}, {0xc1b50, 0xc1b7c}, {0xc1b80, 0xc1bf3}, {0xc1bfc, 0xc1c37}, - {0xc1c3b, 0xc1c49}, {0xc1c4d, 0xc1c88}, {0xc1cc0, 0xc1cc7}, {0xc1cd0, 0xc1cf9}, - {0xc1d00, 0xc1df9}, {0xc1dfb, 0xc1f15}, {0xc1f18, 0xc1f1d}, {0xc1f20, 0xc1f45}, - {0xc1f48, 0xc1f4d}, {0xc1f50, 0xc1f57}, {0xc1f5f, 0xc1f7d}, {0xc1f80, 0xc1fb4}, - {0xc1fb6, 0xc1fc4}, {0xc1fc6, 0xc1fd3}, {0xc1fd6, 0xc1fdb}, {0xc1fdd, 0xc1fef}, - {0xc1ff2, 0xc1ff4}, {0xc1ff6, 0xc1ffe}, {0xc2010, 0xc2027}, {0xc2030, 0xc205e}, - {0xc2074, 0xc208e}, {0xc2090, 0xc209c}, {0xc20a0, 0xc20bf}, {0xc20d0, 0xc20f0}, - {0xc2100, 0xc218b}, {0xc2190, 0xc2426}, {0xc2440, 0xc244a}, {0xc2460, 0xc2b73}, - {0xc2b76, 0xc2b95}, {0xc2b98, 0xc2bb9}, {0xc2bbd, 0xc2bc8}, {0xc2bca, 0xc2bd2}, - {0xc2bec, 0xc2bef}, {0xc2c00, 0xc2c2e}, {0xc2c30, 0xc2c5e}, {0xc2c60, 0xc2cf3}, - {0xc2cf9, 0xc2d25}, {0xc2d30, 0xc2d67}, {0xc2d7f, 0xc2d96}, {0xc2da0, 0xc2da6}, - {0xc2da8, 0xc2dae}, {0xc2db0, 0xc2db6}, {0xc2db8, 0xc2dbe}, {0xc2dc0, 0xc2dc6}, - {0xc2dc8, 0xc2dce}, {0xc2dd0, 0xc2dd6}, {0xc2dd8, 0xc2dde}, {0xc2de0, 0xc2e49}, - {0xc2e80, 0xc2e99}, {0xc2e9b, 0xc2ef3}, {0xc2f00, 0xc2fd5}, {0xc2ff0, 0xc2ffb}, - {0xc3001, 0xc303f}, {0xc3041, 0xc3096}, {0xc3099, 0xc30ff}, {0xc3105, 0xc312e}, - {0xc3131, 0xc318e}, {0xc3190, 0xc31ba}, {0xc31c0, 0xc31e3}, {0xc31f0, 0xc321e}, - {0xc3220, 0xc32fe}, {0xc3300, 0xc4db5}, {0xc4dc0, 0xc9fea}, {0xca000, 0xca48c}, - {0xca490, 0xca4c6}, {0xca4d0, 0xca62b}, {0xca640, 0xca6f7}, {0xca700, 0xca7ae}, - {0xca7b0, 0xca7b7}, {0xca7f7, 0xca82b}, {0xca830, 0xca839}, {0xca840, 0xca877}, - {0xca880, 0xca8c5}, {0xca8ce, 0xca8d9}, {0xca8e0, 0xca8fd}, {0xca900, 0xca953}, - {0xca95f, 0xca97c}, {0xca980, 0xca9cd}, {0xca9cf, 0xca9d9}, {0xca9de, 0xca9fe}, - {0xcaa00, 0xcaa36}, {0xcaa40, 0xcaa4d}, {0xcaa50, 0xcaa59}, {0xcaa5c, 0xcaac2}, - {0xcaadb, 0xcaaf6}, {0xcab01, 0xcab06}, {0xcab09, 0xcab0e}, {0xcab11, 0xcab16}, - {0xcab20, 0xcab26}, {0xcab28, 0xcab2e}, {0xcab30, 0xcab65}, {0xcab70, 0xcabed}, - {0xcabf0, 0xcabf9}, {0xcac00, 0xcd7a3}, {0xcd7b0, 0xcd7c6}, {0xcd7cb, 0xcd7fb}, - {0xcf900, 0xcfa6d}, {0xcfa70, 0xcfad9}, {0xcfb00, 0xcfb06}, {0xcfb13, 0xcfb17}, - {0xcfb1d, 0xcfb36}, {0xcfb38, 0xcfb3c}, {0xcfb46, 0xcfbc1}, {0xcfbd3, 0xcfd3f}, - {0xcfd50, 0xcfd8f}, {0xcfd92, 0xcfdc7}, {0xcfdf0, 0xcfdfd}, {0xcfe00, 0xcfe19}, - {0xcfe20, 0xcfe52}, {0xcfe54, 0xcfe66}, {0xcfe68, 0xcfe6b}, {0xcfe70, 0xcfe74}, - {0xcfe76, 0xcfefc}, {0xcff01, 0xcffbe}, {0xcffc2, 0xcffc7}, {0xcffca, 0xcffcf}, - {0xcffd2, 0xcffd7}, {0xcffda, 0xcffdc}, {0xcffe0, 0xcffe6}, {0xcffe8, 0xcffee}, - {0xd0021, 0xd007e}, {0xd00a1, 0xd00ac}, {0xd00ae, 0xd0377}, {0xd037a, 0xd037f}, - {0xd0384, 0xd038a}, {0xd038e, 0xd03a1}, {0xd03a3, 0xd052f}, {0xd0531, 0xd0556}, - {0xd0559, 0xd055f}, {0xd0561, 0xd0587}, {0xd058d, 0xd058f}, {0xd0591, 0xd05c7}, - {0xd05d0, 0xd05ea}, {0xd05f0, 0xd05f4}, {0xd0606, 0xd061b}, {0xd061e, 0xd06dc}, - {0xd06de, 0xd070d}, {0xd0710, 0xd074a}, {0xd074d, 0xd07b1}, {0xd07c0, 0xd07fa}, - {0xd0800, 0xd082d}, {0xd0830, 0xd083e}, {0xd0840, 0xd085b}, {0xd0860, 0xd086a}, - {0xd08a0, 0xd08b4}, {0xd08b6, 0xd08bd}, {0xd08d4, 0xd08e1}, {0xd08e3, 0xd0983}, - {0xd0985, 0xd098c}, {0xd0993, 0xd09a8}, {0xd09aa, 0xd09b0}, {0xd09b6, 0xd09b9}, - {0xd09bc, 0xd09c4}, {0xd09cb, 0xd09ce}, {0xd09df, 0xd09e3}, {0xd09e6, 0xd09fd}, - {0xd0a01, 0xd0a03}, {0xd0a05, 0xd0a0a}, {0xd0a13, 0xd0a28}, {0xd0a2a, 0xd0a30}, - {0xd0a3e, 0xd0a42}, {0xd0a4b, 0xd0a4d}, {0xd0a59, 0xd0a5c}, {0xd0a66, 0xd0a75}, - {0xd0a81, 0xd0a83}, {0xd0a85, 0xd0a8d}, {0xd0a8f, 0xd0a91}, {0xd0a93, 0xd0aa8}, - {0xd0aaa, 0xd0ab0}, {0xd0ab5, 0xd0ab9}, {0xd0abc, 0xd0ac5}, {0xd0ac7, 0xd0ac9}, - {0xd0acb, 0xd0acd}, {0xd0ae0, 0xd0ae3}, {0xd0ae6, 0xd0af1}, {0xd0af9, 0xd0aff}, - {0xd0b01, 0xd0b03}, {0xd0b05, 0xd0b0c}, {0xd0b13, 0xd0b28}, {0xd0b2a, 0xd0b30}, - {0xd0b35, 0xd0b39}, {0xd0b3c, 0xd0b44}, {0xd0b4b, 0xd0b4d}, {0xd0b5f, 0xd0b63}, - {0xd0b66, 0xd0b77}, {0xd0b85, 0xd0b8a}, {0xd0b8e, 0xd0b90}, {0xd0b92, 0xd0b95}, - {0xd0ba8, 0xd0baa}, {0xd0bae, 0xd0bb9}, {0xd0bbe, 0xd0bc2}, {0xd0bc6, 0xd0bc8}, - {0xd0bca, 0xd0bcd}, {0xd0be6, 0xd0bfa}, {0xd0c00, 0xd0c03}, {0xd0c05, 0xd0c0c}, - {0xd0c0e, 0xd0c10}, {0xd0c12, 0xd0c28}, {0xd0c2a, 0xd0c39}, {0xd0c3d, 0xd0c44}, - {0xd0c46, 0xd0c48}, {0xd0c4a, 0xd0c4d}, {0xd0c58, 0xd0c5a}, {0xd0c60, 0xd0c63}, - {0xd0c66, 0xd0c6f}, {0xd0c78, 0xd0c83}, {0xd0c85, 0xd0c8c}, {0xd0c8e, 0xd0c90}, - {0xd0c92, 0xd0ca8}, {0xd0caa, 0xd0cb3}, {0xd0cb5, 0xd0cb9}, {0xd0cbc, 0xd0cc4}, - {0xd0cc6, 0xd0cc8}, {0xd0cca, 0xd0ccd}, {0xd0ce0, 0xd0ce3}, {0xd0ce6, 0xd0cef}, - {0xd0d00, 0xd0d03}, {0xd0d05, 0xd0d0c}, {0xd0d0e, 0xd0d10}, {0xd0d12, 0xd0d44}, - {0xd0d46, 0xd0d48}, {0xd0d4a, 0xd0d4f}, {0xd0d54, 0xd0d63}, {0xd0d66, 0xd0d7f}, - {0xd0d85, 0xd0d96}, {0xd0d9a, 0xd0db1}, {0xd0db3, 0xd0dbb}, {0xd0dc0, 0xd0dc6}, - {0xd0dcf, 0xd0dd4}, {0xd0dd8, 0xd0ddf}, {0xd0de6, 0xd0def}, {0xd0df2, 0xd0df4}, - {0xd0e01, 0xd0e3a}, {0xd0e3f, 0xd0e5b}, {0xd0e94, 0xd0e97}, {0xd0e99, 0xd0e9f}, - {0xd0ea1, 0xd0ea3}, {0xd0ead, 0xd0eb9}, {0xd0ebb, 0xd0ebd}, {0xd0ec0, 0xd0ec4}, - {0xd0ec8, 0xd0ecd}, {0xd0ed0, 0xd0ed9}, {0xd0edc, 0xd0edf}, {0xd0f00, 0xd0f47}, - {0xd0f49, 0xd0f6c}, {0xd0f71, 0xd0f97}, {0xd0f99, 0xd0fbc}, {0xd0fbe, 0xd0fcc}, - {0xd0fce, 0xd0fda}, {0xd1000, 0xd10c5}, {0xd10d0, 0xd1248}, {0xd124a, 0xd124d}, - {0xd1250, 0xd1256}, {0xd125a, 0xd125d}, {0xd1260, 0xd1288}, {0xd128a, 0xd128d}, - {0xd1290, 0xd12b0}, {0xd12b2, 0xd12b5}, {0xd12b8, 0xd12be}, {0xd12c2, 0xd12c5}, - {0xd12c8, 0xd12d6}, {0xd12d8, 0xd1310}, {0xd1312, 0xd1315}, {0xd1318, 0xd135a}, - {0xd135d, 0xd137c}, {0xd1380, 0xd1399}, {0xd13a0, 0xd13f5}, {0xd13f8, 0xd13fd}, - {0xd1400, 0xd167f}, {0xd1681, 0xd169c}, {0xd16a0, 0xd16f8}, {0xd1700, 0xd170c}, - {0xd170e, 0xd1714}, {0xd1720, 0xd1736}, {0xd1740, 0xd1753}, {0xd1760, 0xd176c}, - {0xd176e, 0xd1770}, {0xd1780, 0xd17dd}, {0xd17e0, 0xd17e9}, {0xd17f0, 0xd17f9}, - {0xd1800, 0xd180d}, {0xd1810, 0xd1819}, {0xd1820, 0xd1877}, {0xd1880, 0xd18aa}, - {0xd18b0, 0xd18f5}, {0xd1900, 0xd191e}, {0xd1920, 0xd192b}, {0xd1930, 0xd193b}, - {0xd1944, 0xd196d}, {0xd1970, 0xd1974}, {0xd1980, 0xd19ab}, {0xd19b0, 0xd19c9}, - {0xd19d0, 0xd19da}, {0xd19de, 0xd1a1b}, {0xd1a1e, 0xd1a5e}, {0xd1a60, 0xd1a7c}, - {0xd1a7f, 0xd1a89}, {0xd1a90, 0xd1a99}, {0xd1aa0, 0xd1aad}, {0xd1ab0, 0xd1abe}, - {0xd1b00, 0xd1b4b}, {0xd1b50, 0xd1b7c}, {0xd1b80, 0xd1bf3}, {0xd1bfc, 0xd1c37}, - {0xd1c3b, 0xd1c49}, {0xd1c4d, 0xd1c88}, {0xd1cc0, 0xd1cc7}, {0xd1cd0, 0xd1cf9}, - {0xd1d00, 0xd1df9}, {0xd1dfb, 0xd1f15}, {0xd1f18, 0xd1f1d}, {0xd1f20, 0xd1f45}, - {0xd1f48, 0xd1f4d}, {0xd1f50, 0xd1f57}, {0xd1f5f, 0xd1f7d}, {0xd1f80, 0xd1fb4}, - {0xd1fb6, 0xd1fc4}, {0xd1fc6, 0xd1fd3}, {0xd1fd6, 0xd1fdb}, {0xd1fdd, 0xd1fef}, - {0xd1ff2, 0xd1ff4}, {0xd1ff6, 0xd1ffe}, {0xd2010, 0xd2027}, {0xd2030, 0xd205e}, - {0xd2074, 0xd208e}, {0xd2090, 0xd209c}, {0xd20a0, 0xd20bf}, {0xd20d0, 0xd20f0}, - {0xd2100, 0xd218b}, {0xd2190, 0xd2426}, {0xd2440, 0xd244a}, {0xd2460, 0xd2b73}, - {0xd2b76, 0xd2b95}, {0xd2b98, 0xd2bb9}, {0xd2bbd, 0xd2bc8}, {0xd2bca, 0xd2bd2}, - {0xd2bec, 0xd2bef}, {0xd2c00, 0xd2c2e}, {0xd2c30, 0xd2c5e}, {0xd2c60, 0xd2cf3}, - {0xd2cf9, 0xd2d25}, {0xd2d30, 0xd2d67}, {0xd2d7f, 0xd2d96}, {0xd2da0, 0xd2da6}, - {0xd2da8, 0xd2dae}, {0xd2db0, 0xd2db6}, {0xd2db8, 0xd2dbe}, {0xd2dc0, 0xd2dc6}, - {0xd2dc8, 0xd2dce}, {0xd2dd0, 0xd2dd6}, {0xd2dd8, 0xd2dde}, {0xd2de0, 0xd2e49}, - {0xd2e80, 0xd2e99}, {0xd2e9b, 0xd2ef3}, {0xd2f00, 0xd2fd5}, {0xd2ff0, 0xd2ffb}, - {0xd3001, 0xd303f}, {0xd3041, 0xd3096}, {0xd3099, 0xd30ff}, {0xd3105, 0xd312e}, - {0xd3131, 0xd318e}, {0xd3190, 0xd31ba}, {0xd31c0, 0xd31e3}, {0xd31f0, 0xd321e}, - {0xd3220, 0xd32fe}, {0xd3300, 0xd4db5}, {0xd4dc0, 0xd9fea}, {0xda000, 0xda48c}, - {0xda490, 0xda4c6}, {0xda4d0, 0xda62b}, {0xda640, 0xda6f7}, {0xda700, 0xda7ae}, - {0xda7b0, 0xda7b7}, {0xda7f7, 0xda82b}, {0xda830, 0xda839}, {0xda840, 0xda877}, - {0xda880, 0xda8c5}, {0xda8ce, 0xda8d9}, {0xda8e0, 0xda8fd}, {0xda900, 0xda953}, - {0xda95f, 0xda97c}, {0xda980, 0xda9cd}, {0xda9cf, 0xda9d9}, {0xda9de, 0xda9fe}, - {0xdaa00, 0xdaa36}, {0xdaa40, 0xdaa4d}, {0xdaa50, 0xdaa59}, {0xdaa5c, 0xdaac2}, - {0xdaadb, 0xdaaf6}, {0xdab01, 0xdab06}, {0xdab09, 0xdab0e}, {0xdab11, 0xdab16}, - {0xdab20, 0xdab26}, {0xdab28, 0xdab2e}, {0xdab30, 0xdab65}, {0xdab70, 0xdabed}, - {0xdabf0, 0xdabf9}, {0xdac00, 0xdd7a3}, {0xdd7b0, 0xdd7c6}, {0xdd7cb, 0xdd7fb}, - {0xdf900, 0xdfa6d}, {0xdfa70, 0xdfad9}, {0xdfb00, 0xdfb06}, {0xdfb13, 0xdfb17}, - {0xdfb1d, 0xdfb36}, {0xdfb38, 0xdfb3c}, {0xdfb46, 0xdfbc1}, {0xdfbd3, 0xdfd3f}, - {0xdfd50, 0xdfd8f}, {0xdfd92, 0xdfdc7}, {0xdfdf0, 0xdfdfd}, {0xdfe00, 0xdfe19}, - {0xdfe20, 0xdfe52}, {0xdfe54, 0xdfe66}, {0xdfe68, 0xdfe6b}, {0xdfe70, 0xdfe74}, - {0xdfe76, 0xdfefc}, {0xdff01, 0xdffbe}, {0xdffc2, 0xdffc7}, {0xdffca, 0xdffcf}, - {0xdffd2, 0xdffd7}, {0xdffda, 0xdffdc}, {0xdffe0, 0xdffe6}, {0xdffe8, 0xdffee}, - {0xe0021, 0xe007e}, {0xe00a1, 0xe00ac}, {0xe00ae, 0xe0377}, {0xe037a, 0xe037f}, - {0xe0384, 0xe038a}, {0xe038e, 0xe03a1}, {0xe03a3, 0xe052f}, {0xe0531, 0xe0556}, - {0xe0559, 0xe055f}, {0xe0561, 0xe0587}, {0xe058d, 0xe058f}, {0xe0591, 0xe05c7}, - {0xe05d0, 0xe05ea}, {0xe05f0, 0xe05f4}, {0xe0606, 0xe061b}, {0xe061e, 0xe06dc}, - {0xe06de, 0xe070d}, {0xe0710, 0xe074a}, {0xe074d, 0xe07b1}, {0xe07c0, 0xe07fa}, - {0xe0800, 0xe082d}, {0xe0830, 0xe083e}, {0xe0840, 0xe085b}, {0xe0860, 0xe086a}, - {0xe08a0, 0xe08b4}, {0xe08b6, 0xe08bd}, {0xe08d4, 0xe08e1}, {0xe08e3, 0xe0983}, - {0xe0985, 0xe098c}, {0xe0993, 0xe09a8}, {0xe09aa, 0xe09b0}, {0xe09b6, 0xe09b9}, - {0xe09bc, 0xe09c4}, {0xe09cb, 0xe09ce}, {0xe09df, 0xe09e3}, {0xe09e6, 0xe09fd}, - {0xe0a01, 0xe0a03}, {0xe0a05, 0xe0a0a}, {0xe0a13, 0xe0a28}, {0xe0a2a, 0xe0a30}, - {0xe0a3e, 0xe0a42}, {0xe0a4b, 0xe0a4d}, {0xe0a59, 0xe0a5c}, {0xe0a66, 0xe0a75}, - {0xe0a81, 0xe0a83}, {0xe0a85, 0xe0a8d}, {0xe0a8f, 0xe0a91}, {0xe0a93, 0xe0aa8}, - {0xe0aaa, 0xe0ab0}, {0xe0ab5, 0xe0ab9}, {0xe0abc, 0xe0ac5}, {0xe0ac7, 0xe0ac9}, - {0xe0acb, 0xe0acd}, {0xe0ae0, 0xe0ae3}, {0xe0ae6, 0xe0af1}, {0xe0af9, 0xe0aff}, - {0xe0b01, 0xe0b03}, {0xe0b05, 0xe0b0c}, {0xe0b13, 0xe0b28}, {0xe0b2a, 0xe0b30}, - {0xe0b35, 0xe0b39}, {0xe0b3c, 0xe0b44}, {0xe0b4b, 0xe0b4d}, {0xe0b5f, 0xe0b63}, - {0xe0b66, 0xe0b77}, {0xe0b85, 0xe0b8a}, {0xe0b8e, 0xe0b90}, {0xe0b92, 0xe0b95}, - {0xe0ba8, 0xe0baa}, {0xe0bae, 0xe0bb9}, {0xe0bbe, 0xe0bc2}, {0xe0bc6, 0xe0bc8}, - {0xe0bca, 0xe0bcd}, {0xe0be6, 0xe0bfa}, {0xe0c00, 0xe0c03}, {0xe0c05, 0xe0c0c}, - {0xe0c0e, 0xe0c10}, {0xe0c12, 0xe0c28}, {0xe0c2a, 0xe0c39}, {0xe0c3d, 0xe0c44}, - {0xe0c46, 0xe0c48}, {0xe0c4a, 0xe0c4d}, {0xe0c58, 0xe0c5a}, {0xe0c60, 0xe0c63}, - {0xe0c66, 0xe0c6f}, {0xe0c78, 0xe0c83}, {0xe0c85, 0xe0c8c}, {0xe0c8e, 0xe0c90}, - {0xe0c92, 0xe0ca8}, {0xe0caa, 0xe0cb3}, {0xe0cb5, 0xe0cb9}, {0xe0cbc, 0xe0cc4}, - {0xe0cc6, 0xe0cc8}, {0xe0cca, 0xe0ccd}, {0xe0ce0, 0xe0ce3}, {0xe0ce6, 0xe0cef}, - {0xe0d00, 0xe0d03}, {0xe0d05, 0xe0d0c}, {0xe0d0e, 0xe0d10}, {0xe0d12, 0xe0d44}, - {0xe0d46, 0xe0d48}, {0xe0d4a, 0xe0d4f}, {0xe0d54, 0xe0d63}, {0xe0d66, 0xe0d7f}, - {0xe0d85, 0xe0d96}, {0xe0d9a, 0xe0db1}, {0xe0db3, 0xe0dbb}, {0xe0dc0, 0xe0dc6}, - {0xe0dcf, 0xe0dd4}, {0xe0dd8, 0xe0ddf}, {0xe0de6, 0xe0def}, {0xe0df2, 0xe0df4}, - {0xe0e01, 0xe0e3a}, {0xe0e3f, 0xe0e5b}, {0xe0e94, 0xe0e97}, {0xe0e99, 0xe0e9f}, - {0xe0ea1, 0xe0ea3}, {0xe0ead, 0xe0eb9}, {0xe0ebb, 0xe0ebd}, {0xe0ec0, 0xe0ec4}, - {0xe0ec8, 0xe0ecd}, {0xe0ed0, 0xe0ed9}, {0xe0edc, 0xe0edf}, {0xe0f00, 0xe0f47}, - {0xe0f49, 0xe0f6c}, {0xe0f71, 0xe0f97}, {0xe0f99, 0xe0fbc}, {0xe0fbe, 0xe0fcc}, - {0xe0fce, 0xe0fda}, {0xe1000, 0xe10c5}, {0xe10d0, 0xe1248}, {0xe124a, 0xe124d}, - {0xe1250, 0xe1256}, {0xe125a, 0xe125d}, {0xe1260, 0xe1288}, {0xe128a, 0xe128d}, - {0xe1290, 0xe12b0}, {0xe12b2, 0xe12b5}, {0xe12b8, 0xe12be}, {0xe12c2, 0xe12c5}, - {0xe12c8, 0xe12d6}, {0xe12d8, 0xe1310}, {0xe1312, 0xe1315}, {0xe1318, 0xe135a}, - {0xe135d, 0xe137c}, {0xe1380, 0xe1399}, {0xe13a0, 0xe13f5}, {0xe13f8, 0xe13fd}, - {0xe1400, 0xe167f}, {0xe1681, 0xe169c}, {0xe16a0, 0xe16f8}, {0xe1700, 0xe170c}, - {0xe170e, 0xe1714}, {0xe1720, 0xe1736}, {0xe1740, 0xe1753}, {0xe1760, 0xe176c}, - {0xe176e, 0xe1770}, {0xe1780, 0xe17dd}, {0xe17e0, 0xe17e9}, {0xe17f0, 0xe17f9}, - {0xe1800, 0xe180d}, {0xe1810, 0xe1819}, {0xe1820, 0xe1877}, {0xe1880, 0xe18aa}, - {0xe18b0, 0xe18f5}, {0xe1900, 0xe191e}, {0xe1920, 0xe192b}, {0xe1930, 0xe193b}, - {0xe1944, 0xe196d}, {0xe1970, 0xe1974}, {0xe1980, 0xe19ab}, {0xe19b0, 0xe19c9}, - {0xe19d0, 0xe19da}, {0xe19de, 0xe1a1b}, {0xe1a1e, 0xe1a5e}, {0xe1a60, 0xe1a7c}, - {0xe1a7f, 0xe1a89}, {0xe1a90, 0xe1a99}, {0xe1aa0, 0xe1aad}, {0xe1ab0, 0xe1abe}, - {0xe1b00, 0xe1b4b}, {0xe1b50, 0xe1b7c}, {0xe1b80, 0xe1bf3}, {0xe1bfc, 0xe1c37}, - {0xe1c3b, 0xe1c49}, {0xe1c4d, 0xe1c88}, {0xe1cc0, 0xe1cc7}, {0xe1cd0, 0xe1cf9}, - {0xe1d00, 0xe1df9}, {0xe1dfb, 0xe1f15}, {0xe1f18, 0xe1f1d}, {0xe1f20, 0xe1f45}, - {0xe1f48, 0xe1f4d}, {0xe1f50, 0xe1f57}, {0xe1f5f, 0xe1f7d}, {0xe1f80, 0xe1fb4}, - {0xe1fb6, 0xe1fc4}, {0xe1fc6, 0xe1fd3}, {0xe1fd6, 0xe1fdb}, {0xe1fdd, 0xe1fef}, - {0xe1ff2, 0xe1ff4}, {0xe1ff6, 0xe1ffe}, {0xe2010, 0xe2027}, {0xe2030, 0xe205e}, - {0xe2074, 0xe208e}, {0xe2090, 0xe209c}, {0xe20a0, 0xe20bf}, {0xe20d0, 0xe20f0}, - {0xe2100, 0xe218b}, {0xe2190, 0xe2426}, {0xe2440, 0xe244a}, {0xe2460, 0xe2b73}, - {0xe2b76, 0xe2b95}, {0xe2b98, 0xe2bb9}, {0xe2bbd, 0xe2bc8}, {0xe2bca, 0xe2bd2}, - {0xe2bec, 0xe2bef}, {0xe2c00, 0xe2c2e}, {0xe2c30, 0xe2c5e}, {0xe2c60, 0xe2cf3}, - {0xe2cf9, 0xe2d25}, {0xe2d30, 0xe2d67}, {0xe2d7f, 0xe2d96}, {0xe2da0, 0xe2da6}, - {0xe2da8, 0xe2dae}, {0xe2db0, 0xe2db6}, {0xe2db8, 0xe2dbe}, {0xe2dc0, 0xe2dc6}, - {0xe2dc8, 0xe2dce}, {0xe2dd0, 0xe2dd6}, {0xe2dd8, 0xe2dde}, {0xe2de0, 0xe2e49}, - {0xe2e80, 0xe2e99}, {0xe2e9b, 0xe2ef3}, {0xe2f00, 0xe2fd5}, {0xe2ff0, 0xe2ffb}, - {0xe3001, 0xe303f}, {0xe3041, 0xe3096}, {0xe3099, 0xe30ff}, {0xe3105, 0xe312e}, - {0xe3131, 0xe318e}, {0xe3190, 0xe31ba}, {0xe31c0, 0xe31e3}, {0xe31f0, 0xe321e}, - {0xe3220, 0xe32fe}, {0xe3300, 0xe4db5}, {0xe4dc0, 0xe9fea}, {0xea000, 0xea48c}, - {0xea490, 0xea4c6}, {0xea4d0, 0xea62b}, {0xea640, 0xea6f7}, {0xea700, 0xea7ae}, - {0xea7b0, 0xea7b7}, {0xea7f7, 0xea82b}, {0xea830, 0xea839}, {0xea840, 0xea877}, - {0xea880, 0xea8c5}, {0xea8ce, 0xea8d9}, {0xea8e0, 0xea8fd}, {0xea900, 0xea953}, - {0xea95f, 0xea97c}, {0xea980, 0xea9cd}, {0xea9cf, 0xea9d9}, {0xea9de, 0xea9fe}, - {0xeaa00, 0xeaa36}, {0xeaa40, 0xeaa4d}, {0xeaa50, 0xeaa59}, {0xeaa5c, 0xeaac2}, - {0xeaadb, 0xeaaf6}, {0xeab01, 0xeab06}, {0xeab09, 0xeab0e}, {0xeab11, 0xeab16}, - {0xeab20, 0xeab26}, {0xeab28, 0xeab2e}, {0xeab30, 0xeab65}, {0xeab70, 0xeabed}, - {0xeabf0, 0xeabf9}, {0xeac00, 0xed7a3}, {0xed7b0, 0xed7c6}, {0xed7cb, 0xed7fb}, - {0xef900, 0xefa6d}, {0xefa70, 0xefad9}, {0xefb00, 0xefb06}, {0xefb13, 0xefb17}, - {0xefb1d, 0xefb36}, {0xefb38, 0xefb3c}, {0xefb46, 0xefbc1}, {0xefbd3, 0xefd3f}, - {0xefd50, 0xefd8f}, {0xefd92, 0xefdc7}, {0xefdf0, 0xefdfd}, {0xefe00, 0xefe19}, - {0xefe20, 0xefe52}, {0xefe54, 0xefe66}, {0xefe68, 0xefe6b}, {0xefe70, 0xefe74}, - {0xefe76, 0xefefc}, {0xeff01, 0xeffbe}, {0xeffc2, 0xeffc7}, {0xeffca, 0xeffcf}, - {0xeffd2, 0xeffd7}, {0xeffda, 0xeffdc}, {0xeffe0, 0xeffe6}, {0xeffe8, 0xeffee}, - {0xf0021, 0xf007e}, {0xf00a1, 0xf00ac}, {0xf00ae, 0xf0377}, {0xf037a, 0xf037f}, - {0xf0384, 0xf038a}, {0xf038e, 0xf03a1}, {0xf03a3, 0xf052f}, {0xf0531, 0xf0556}, - {0xf0559, 0xf055f}, {0xf0561, 0xf0587}, {0xf058d, 0xf058f}, {0xf0591, 0xf05c7}, - {0xf05d0, 0xf05ea}, {0xf05f0, 0xf05f4}, {0xf0606, 0xf061b}, {0xf061e, 0xf06dc}, - {0xf06de, 0xf070d}, {0xf0710, 0xf074a}, {0xf074d, 0xf07b1}, {0xf07c0, 0xf07fa}, - {0xf0800, 0xf082d}, {0xf0830, 0xf083e}, {0xf0840, 0xf085b}, {0xf0860, 0xf086a}, - {0xf08a0, 0xf08b4}, {0xf08b6, 0xf08bd}, {0xf08d4, 0xf08e1}, {0xf08e3, 0xf0983}, - {0xf0985, 0xf098c}, {0xf0993, 0xf09a8}, {0xf09aa, 0xf09b0}, {0xf09b6, 0xf09b9}, - {0xf09bc, 0xf09c4}, {0xf09cb, 0xf09ce}, {0xf09df, 0xf09e3}, {0xf09e6, 0xf09fd}, - {0xf0a01, 0xf0a03}, {0xf0a05, 0xf0a0a}, {0xf0a13, 0xf0a28}, {0xf0a2a, 0xf0a30}, - {0xf0a3e, 0xf0a42}, {0xf0a4b, 0xf0a4d}, {0xf0a59, 0xf0a5c}, {0xf0a66, 0xf0a75}, - {0xf0a81, 0xf0a83}, {0xf0a85, 0xf0a8d}, {0xf0a8f, 0xf0a91}, {0xf0a93, 0xf0aa8}, - {0xf0aaa, 0xf0ab0}, {0xf0ab5, 0xf0ab9}, {0xf0abc, 0xf0ac5}, {0xf0ac7, 0xf0ac9}, - {0xf0acb, 0xf0acd}, {0xf0ae0, 0xf0ae3}, {0xf0ae6, 0xf0af1}, {0xf0af9, 0xf0aff}, - {0xf0b01, 0xf0b03}, {0xf0b05, 0xf0b0c}, {0xf0b13, 0xf0b28}, {0xf0b2a, 0xf0b30}, - {0xf0b35, 0xf0b39}, {0xf0b3c, 0xf0b44}, {0xf0b4b, 0xf0b4d}, {0xf0b5f, 0xf0b63}, - {0xf0b66, 0xf0b77}, {0xf0b85, 0xf0b8a}, {0xf0b8e, 0xf0b90}, {0xf0b92, 0xf0b95}, - {0xf0ba8, 0xf0baa}, {0xf0bae, 0xf0bb9}, {0xf0bbe, 0xf0bc2}, {0xf0bc6, 0xf0bc8}, - {0xf0bca, 0xf0bcd}, {0xf0be6, 0xf0bfa}, {0xf0c00, 0xf0c03}, {0xf0c05, 0xf0c0c}, - {0xf0c0e, 0xf0c10}, {0xf0c12, 0xf0c28}, {0xf0c2a, 0xf0c39}, {0xf0c3d, 0xf0c44}, - {0xf0c46, 0xf0c48}, {0xf0c4a, 0xf0c4d}, {0xf0c58, 0xf0c5a}, {0xf0c60, 0xf0c63}, - {0xf0c66, 0xf0c6f}, {0xf0c78, 0xf0c83}, {0xf0c85, 0xf0c8c}, {0xf0c8e, 0xf0c90}, - {0xf0c92, 0xf0ca8}, {0xf0caa, 0xf0cb3}, {0xf0cb5, 0xf0cb9}, {0xf0cbc, 0xf0cc4}, - {0xf0cc6, 0xf0cc8}, {0xf0cca, 0xf0ccd}, {0xf0ce0, 0xf0ce3}, {0xf0ce6, 0xf0cef}, - {0xf0d00, 0xf0d03}, {0xf0d05, 0xf0d0c}, {0xf0d0e, 0xf0d10}, {0xf0d12, 0xf0d44}, - {0xf0d46, 0xf0d48}, {0xf0d4a, 0xf0d4f}, {0xf0d54, 0xf0d63}, {0xf0d66, 0xf0d7f}, - {0xf0d85, 0xf0d96}, {0xf0d9a, 0xf0db1}, {0xf0db3, 0xf0dbb}, {0xf0dc0, 0xf0dc6}, - {0xf0dcf, 0xf0dd4}, {0xf0dd8, 0xf0ddf}, {0xf0de6, 0xf0def}, {0xf0df2, 0xf0df4}, - {0xf0e01, 0xf0e3a}, {0xf0e3f, 0xf0e5b}, {0xf0e94, 0xf0e97}, {0xf0e99, 0xf0e9f}, - {0xf0ea1, 0xf0ea3}, {0xf0ead, 0xf0eb9}, {0xf0ebb, 0xf0ebd}, {0xf0ec0, 0xf0ec4}, - {0xf0ec8, 0xf0ecd}, {0xf0ed0, 0xf0ed9}, {0xf0edc, 0xf0edf}, {0xf0f00, 0xf0f47}, - {0xf0f49, 0xf0f6c}, {0xf0f71, 0xf0f97}, {0xf0f99, 0xf0fbc}, {0xf0fbe, 0xf0fcc}, - {0xf0fce, 0xf0fda}, {0xf1000, 0xf10c5}, {0xf10d0, 0xf1248}, {0xf124a, 0xf124d}, - {0xf1250, 0xf1256}, {0xf125a, 0xf125d}, {0xf1260, 0xf1288}, {0xf128a, 0xf128d}, - {0xf1290, 0xf12b0}, {0xf12b2, 0xf12b5}, {0xf12b8, 0xf12be}, {0xf12c2, 0xf12c5}, - {0xf12c8, 0xf12d6}, {0xf12d8, 0xf1310}, {0xf1312, 0xf1315}, {0xf1318, 0xf135a}, - {0xf135d, 0xf137c}, {0xf1380, 0xf1399}, {0xf13a0, 0xf13f5}, {0xf13f8, 0xf13fd}, - {0xf1400, 0xf167f}, {0xf1681, 0xf169c}, {0xf16a0, 0xf16f8}, {0xf1700, 0xf170c}, - {0xf170e, 0xf1714}, {0xf1720, 0xf1736}, {0xf1740, 0xf1753}, {0xf1760, 0xf176c}, - {0xf176e, 0xf1770}, {0xf1780, 0xf17dd}, {0xf17e0, 0xf17e9}, {0xf17f0, 0xf17f9}, - {0xf1800, 0xf180d}, {0xf1810, 0xf1819}, {0xf1820, 0xf1877}, {0xf1880, 0xf18aa}, - {0xf18b0, 0xf18f5}, {0xf1900, 0xf191e}, {0xf1920, 0xf192b}, {0xf1930, 0xf193b}, - {0xf1944, 0xf196d}, {0xf1970, 0xf1974}, {0xf1980, 0xf19ab}, {0xf19b0, 0xf19c9}, - {0xf19d0, 0xf19da}, {0xf19de, 0xf1a1b}, {0xf1a1e, 0xf1a5e}, {0xf1a60, 0xf1a7c}, - {0xf1a7f, 0xf1a89}, {0xf1a90, 0xf1a99}, {0xf1aa0, 0xf1aad}, {0xf1ab0, 0xf1abe}, - {0xf1b00, 0xf1b4b}, {0xf1b50, 0xf1b7c}, {0xf1b80, 0xf1bf3}, {0xf1bfc, 0xf1c37}, - {0xf1c3b, 0xf1c49}, {0xf1c4d, 0xf1c88}, {0xf1cc0, 0xf1cc7}, {0xf1cd0, 0xf1cf9}, - {0xf1d00, 0xf1df9}, {0xf1dfb, 0xf1f15}, {0xf1f18, 0xf1f1d}, {0xf1f20, 0xf1f45}, - {0xf1f48, 0xf1f4d}, {0xf1f50, 0xf1f57}, {0xf1f5f, 0xf1f7d}, {0xf1f80, 0xf1fb4}, - {0xf1fb6, 0xf1fc4}, {0xf1fc6, 0xf1fd3}, {0xf1fd6, 0xf1fdb}, {0xf1fdd, 0xf1fef}, - {0xf1ff2, 0xf1ff4}, {0xf1ff6, 0xf1ffe}, {0xf2010, 0xf2027}, {0xf2030, 0xf205e}, - {0xf2074, 0xf208e}, {0xf2090, 0xf209c}, {0xf20a0, 0xf20bf}, {0xf20d0, 0xf20f0}, - {0xf2100, 0xf218b}, {0xf2190, 0xf2426}, {0xf2440, 0xf244a}, {0xf2460, 0xf2b73}, - {0xf2b76, 0xf2b95}, {0xf2b98, 0xf2bb9}, {0xf2bbd, 0xf2bc8}, {0xf2bca, 0xf2bd2}, - {0xf2bec, 0xf2bef}, {0xf2c00, 0xf2c2e}, {0xf2c30, 0xf2c5e}, {0xf2c60, 0xf2cf3}, - {0xf2cf9, 0xf2d25}, {0xf2d30, 0xf2d67}, {0xf2d7f, 0xf2d96}, {0xf2da0, 0xf2da6}, - {0xf2da8, 0xf2dae}, {0xf2db0, 0xf2db6}, {0xf2db8, 0xf2dbe}, {0xf2dc0, 0xf2dc6}, - {0xf2dc8, 0xf2dce}, {0xf2dd0, 0xf2dd6}, {0xf2dd8, 0xf2dde}, {0xf2de0, 0xf2e49}, - {0xf2e80, 0xf2e99}, {0xf2e9b, 0xf2ef3}, {0xf2f00, 0xf2fd5}, {0xf2ff0, 0xf2ffb}, - {0xf3001, 0xf303f}, {0xf3041, 0xf3096}, {0xf3099, 0xf30ff}, {0xf3105, 0xf312e}, - {0xf3131, 0xf318e}, {0xf3190, 0xf31ba}, {0xf31c0, 0xf31e3}, {0xf31f0, 0xf321e}, - {0xf3220, 0xf32fe}, {0xf3300, 0xf4db5}, {0xf4dc0, 0xf9fea}, {0xfa000, 0xfa48c}, - {0xfa490, 0xfa4c6}, {0xfa4d0, 0xfa62b}, {0xfa640, 0xfa6f7}, {0xfa700, 0xfa7ae}, - {0xfa7b0, 0xfa7b7}, {0xfa7f7, 0xfa82b}, {0xfa830, 0xfa839}, {0xfa840, 0xfa877}, - {0xfa880, 0xfa8c5}, {0xfa8ce, 0xfa8d9}, {0xfa8e0, 0xfa8fd}, {0xfa900, 0xfa953}, - {0xfa95f, 0xfa97c}, {0xfa980, 0xfa9cd}, {0xfa9cf, 0xfa9d9}, {0xfa9de, 0xfa9fe}, - {0xfaa00, 0xfaa36}, {0xfaa40, 0xfaa4d}, {0xfaa50, 0xfaa59}, {0xfaa5c, 0xfaac2}, - {0xfaadb, 0xfaaf6}, {0xfab01, 0xfab06}, {0xfab09, 0xfab0e}, {0xfab11, 0xfab16}, - {0xfab20, 0xfab26}, {0xfab28, 0xfab2e}, {0xfab30, 0xfab65}, {0xfab70, 0xfabed}, - {0xfabf0, 0xfabf9}, {0xfac00, 0xfd7a3}, {0xfd7b0, 0xfd7c6}, {0xfd7cb, 0xfd7fb}, - {0xff900, 0xffa6d}, {0xffa70, 0xffad9}, {0xffb00, 0xffb06}, {0xffb13, 0xffb17}, - {0xffb1d, 0xffb36}, {0xffb38, 0xffb3c}, {0xffb46, 0xffbc1}, {0xffbd3, 0xffd3f}, - {0xffd50, 0xffd8f}, {0xffd92, 0xffdc7}, {0xffdf0, 0xffdfd}, {0xffe00, 0xffe19}, - {0xffe20, 0xffe52}, {0xffe54, 0xffe66}, {0xffe68, 0xffe6b}, {0xffe70, 0xffe74}, - {0xffe76, 0xffefc}, {0xfff01, 0xfffbe}, {0xfffc2, 0xfffc7}, {0xfffca, 0xfffcf}, - {0xfffd2, 0xfffd7}, {0xfffda, 0xfffdc}, {0xfffe0, 0xfffe6}, {0xfffe8, 0xfffee}, - {0x100021, 0x10007e}, {0x1000a1, 0x1000ac}, {0x1000ae, 0x100377}, {0x10037a, 0x10037f}, - {0x100384, 0x10038a}, {0x10038e, 0x1003a1}, {0x1003a3, 0x10052f}, {0x100531, 0x100556}, - {0x100559, 0x10055f}, {0x100561, 0x100587}, {0x10058d, 0x10058f}, {0x100591, 0x1005c7}, - {0x1005d0, 0x1005ea}, {0x1005f0, 0x1005f4}, {0x100606, 0x10061b}, {0x10061e, 0x1006dc}, - {0x1006de, 0x10070d}, {0x100710, 0x10074a}, {0x10074d, 0x1007b1}, {0x1007c0, 0x1007fa}, - {0x100800, 0x10082d}, {0x100830, 0x10083e}, {0x100840, 0x10085b}, {0x100860, 0x10086a}, - {0x1008a0, 0x1008b4}, {0x1008b6, 0x1008bd}, {0x1008d4, 0x1008e1}, {0x1008e3, 0x100983}, - {0x100985, 0x10098c}, {0x100993, 0x1009a8}, {0x1009aa, 0x1009b0}, {0x1009b6, 0x1009b9}, - {0x1009bc, 0x1009c4}, {0x1009cb, 0x1009ce}, {0x1009df, 0x1009e3}, {0x1009e6, 0x1009fd}, - {0x100a01, 0x100a03}, {0x100a05, 0x100a0a}, {0x100a13, 0x100a28}, {0x100a2a, 0x100a30}, - {0x100a3e, 0x100a42}, {0x100a4b, 0x100a4d}, {0x100a59, 0x100a5c}, {0x100a66, 0x100a75}, - {0x100a81, 0x100a83}, {0x100a85, 0x100a8d}, {0x100a8f, 0x100a91}, {0x100a93, 0x100aa8}, - {0x100aaa, 0x100ab0}, {0x100ab5, 0x100ab9}, {0x100abc, 0x100ac5}, {0x100ac7, 0x100ac9}, - {0x100acb, 0x100acd}, {0x100ae0, 0x100ae3}, {0x100ae6, 0x100af1}, {0x100af9, 0x100aff}, - {0x100b01, 0x100b03}, {0x100b05, 0x100b0c}, {0x100b13, 0x100b28}, {0x100b2a, 0x100b30}, - {0x100b35, 0x100b39}, {0x100b3c, 0x100b44}, {0x100b4b, 0x100b4d}, {0x100b5f, 0x100b63}, - {0x100b66, 0x100b77}, {0x100b85, 0x100b8a}, {0x100b8e, 0x100b90}, {0x100b92, 0x100b95}, - {0x100ba8, 0x100baa}, {0x100bae, 0x100bb9}, {0x100bbe, 0x100bc2}, {0x100bc6, 0x100bc8}, - {0x100bca, 0x100bcd}, {0x100be6, 0x100bfa}, {0x100c00, 0x100c03}, {0x100c05, 0x100c0c}, - {0x100c0e, 0x100c10}, {0x100c12, 0x100c28}, {0x100c2a, 0x100c39}, {0x100c3d, 0x100c44}, - {0x100c46, 0x100c48}, {0x100c4a, 0x100c4d}, {0x100c58, 0x100c5a}, {0x100c60, 0x100c63}, - {0x100c66, 0x100c6f}, {0x100c78, 0x100c83}, {0x100c85, 0x100c8c}, {0x100c8e, 0x100c90}, - {0x100c92, 0x100ca8}, {0x100caa, 0x100cb3}, {0x100cb5, 0x100cb9}, {0x100cbc, 0x100cc4}, - {0x100cc6, 0x100cc8}, {0x100cca, 0x100ccd}, {0x100ce0, 0x100ce3}, {0x100ce6, 0x100cef}, - {0x100d00, 0x100d03}, {0x100d05, 0x100d0c}, {0x100d0e, 0x100d10}, {0x100d12, 0x100d44}, - {0x100d46, 0x100d48}, {0x100d4a, 0x100d4f}, {0x100d54, 0x100d63}, {0x100d66, 0x100d7f}, - {0x100d85, 0x100d96}, {0x100d9a, 0x100db1}, {0x100db3, 0x100dbb}, {0x100dc0, 0x100dc6}, - {0x100dcf, 0x100dd4}, {0x100dd8, 0x100ddf}, {0x100de6, 0x100def}, {0x100df2, 0x100df4}, - {0x100e01, 0x100e3a}, {0x100e3f, 0x100e5b}, {0x100e94, 0x100e97}, {0x100e99, 0x100e9f}, - {0x100ea1, 0x100ea3}, {0x100ead, 0x100eb9}, {0x100ebb, 0x100ebd}, {0x100ec0, 0x100ec4}, - {0x100ec8, 0x100ecd}, {0x100ed0, 0x100ed9}, {0x100edc, 0x100edf}, {0x100f00, 0x100f47}, - {0x100f49, 0x100f6c}, {0x100f71, 0x100f97}, {0x100f99, 0x100fbc}, {0x100fbe, 0x100fcc}, - {0x100fce, 0x100fda}, {0x101000, 0x1010c5}, {0x1010d0, 0x101248}, {0x10124a, 0x10124d}, - {0x101250, 0x101256}, {0x10125a, 0x10125d}, {0x101260, 0x101288}, {0x10128a, 0x10128d}, - {0x101290, 0x1012b0}, {0x1012b2, 0x1012b5}, {0x1012b8, 0x1012be}, {0x1012c2, 0x1012c5}, - {0x1012c8, 0x1012d6}, {0x1012d8, 0x101310}, {0x101312, 0x101315}, {0x101318, 0x10135a}, - {0x10135d, 0x10137c}, {0x101380, 0x101399}, {0x1013a0, 0x1013f5}, {0x1013f8, 0x1013fd}, - {0x101400, 0x10167f}, {0x101681, 0x10169c}, {0x1016a0, 0x1016f8}, {0x101700, 0x10170c}, - {0x10170e, 0x101714}, {0x101720, 0x101736}, {0x101740, 0x101753}, {0x101760, 0x10176c}, - {0x10176e, 0x101770}, {0x101780, 0x1017dd}, {0x1017e0, 0x1017e9}, {0x1017f0, 0x1017f9}, - {0x101800, 0x10180d}, {0x101810, 0x101819}, {0x101820, 0x101877}, {0x101880, 0x1018aa}, - {0x1018b0, 0x1018f5}, {0x101900, 0x10191e}, {0x101920, 0x10192b}, {0x101930, 0x10193b}, - {0x101944, 0x10196d}, {0x101970, 0x101974}, {0x101980, 0x1019ab}, {0x1019b0, 0x1019c9}, - {0x1019d0, 0x1019da}, {0x1019de, 0x101a1b}, {0x101a1e, 0x101a5e}, {0x101a60, 0x101a7c}, - {0x101a7f, 0x101a89}, {0x101a90, 0x101a99}, {0x101aa0, 0x101aad}, {0x101ab0, 0x101abe}, - {0x101b00, 0x101b4b}, {0x101b50, 0x101b7c}, {0x101b80, 0x101bf3}, {0x101bfc, 0x101c37}, - {0x101c3b, 0x101c49}, {0x101c4d, 0x101c88}, {0x101cc0, 0x101cc7}, {0x101cd0, 0x101cf9}, - {0x101d00, 0x101df9}, {0x101dfb, 0x101f15}, {0x101f18, 0x101f1d}, {0x101f20, 0x101f45}, - {0x101f48, 0x101f4d}, {0x101f50, 0x101f57}, {0x101f5f, 0x101f7d}, {0x101f80, 0x101fb4}, - {0x101fb6, 0x101fc4}, {0x101fc6, 0x101fd3}, {0x101fd6, 0x101fdb}, {0x101fdd, 0x101fef}, - {0x101ff2, 0x101ff4}, {0x101ff6, 0x101ffe}, {0x102010, 0x102027}, {0x102030, 0x10205e}, - {0x102074, 0x10208e}, {0x102090, 0x10209c}, {0x1020a0, 0x1020bf}, {0x1020d0, 0x1020f0}, - {0x102100, 0x10218b}, {0x102190, 0x102426}, {0x102440, 0x10244a}, {0x102460, 0x102b73}, - {0x102b76, 0x102b95}, {0x102b98, 0x102bb9}, {0x102bbd, 0x102bc8}, {0x102bca, 0x102bd2}, - {0x102bec, 0x102bef}, {0x102c00, 0x102c2e}, {0x102c30, 0x102c5e}, {0x102c60, 0x102cf3}, - {0x102cf9, 0x102d25}, {0x102d30, 0x102d67}, {0x102d7f, 0x102d96}, {0x102da0, 0x102da6}, - {0x102da8, 0x102dae}, {0x102db0, 0x102db6}, {0x102db8, 0x102dbe}, {0x102dc0, 0x102dc6}, - {0x102dc8, 0x102dce}, {0x102dd0, 0x102dd6}, {0x102dd8, 0x102dde}, {0x102de0, 0x102e49}, - {0x102e80, 0x102e99}, {0x102e9b, 0x102ef3}, {0x102f00, 0x102fd5}, {0x102ff0, 0x102ffb}, - {0x103001, 0x10303f}, {0x103041, 0x103096}, {0x103099, 0x1030ff}, {0x103105, 0x10312e}, - {0x103131, 0x10318e}, {0x103190, 0x1031ba}, {0x1031c0, 0x1031e3}, {0x1031f0, 0x10321e}, - {0x103220, 0x1032fe}, {0x103300, 0x104db5}, {0x104dc0, 0x109fea}, {0x10a000, 0x10a48c}, - {0x10a490, 0x10a4c6}, {0x10a4d0, 0x10a62b}, {0x10a640, 0x10a6f7}, {0x10a700, 0x10a7ae}, - {0x10a7b0, 0x10a7b7}, {0x10a7f7, 0x10a82b}, {0x10a830, 0x10a839}, {0x10a840, 0x10a877}, - {0x10a880, 0x10a8c5}, {0x10a8ce, 0x10a8d9}, {0x10a8e0, 0x10a8fd}, {0x10a900, 0x10a953}, - {0x10a95f, 0x10a97c}, {0x10a980, 0x10a9cd}, {0x10a9cf, 0x10a9d9}, {0x10a9de, 0x10a9fe}, - {0x10aa00, 0x10aa36}, {0x10aa40, 0x10aa4d}, {0x10aa50, 0x10aa59}, {0x10aa5c, 0x10aac2}, - {0x10aadb, 0x10aaf6}, {0x10ab01, 0x10ab06}, {0x10ab09, 0x10ab0e}, {0x10ab11, 0x10ab16}, - {0x10ab20, 0x10ab26}, {0x10ab28, 0x10ab2e}, {0x10ab30, 0x10ab65}, {0x10ab70, 0x10abed}, - {0x10abf0, 0x10abf9}, {0x10ac00, 0x10d7a3}, {0x10d7b0, 0x10d7c6}, {0x10d7cb, 0x10d7fb}, - {0x10f900, 0x10fa6d}, {0x10fa70, 0x10fad9}, {0x10fb00, 0x10fb06}, {0x10fb13, 0x10fb17}, - {0x10fb1d, 0x10fb36}, {0x10fb38, 0x10fb3c}, {0x10fb46, 0x10fbc1}, {0x10fbd3, 0x10fd3f}, - {0x10fd50, 0x10fd8f}, {0x10fd92, 0x10fdc7}, {0x10fdf0, 0x10fdfd}, {0x10fe00, 0x10fe19}, - {0x10fe20, 0x10fe52}, {0x10fe54, 0x10fe66}, {0x10fe68, 0x10fe6b}, {0x10fe70, 0x10fe74}, - {0x10fe76, 0x10fefc}, {0x10ff01, 0x10ffbe}, {0x10ffc2, 0x10ffc7}, {0x10ffca, 0x10ffcf}, - {0x10ffd2, 0x10ffd7}, {0x10ffda, 0x10ffdc}, {0x10ffe0, 0x10ffe6}, {0x10ffe8, 0x10ffee} + ,{0x10000, 0x1000b}, {0x1000d, 0x10026}, {0x10028, 0x1003a}, {0x1003f, 0x1004d}, + {0x10050, 0x1005d}, {0x10080, 0x100fa}, {0x10100, 0x10102}, {0x10107, 0x10133}, + {0x10137, 0x1018e}, {0x10190, 0x1019b}, {0x101d0, 0x101fd}, {0x10280, 0x1029c}, + {0x102a0, 0x102d0}, {0x102e0, 0x102fb}, {0x10300, 0x10323}, {0x1032d, 0x1034a}, + {0x10350, 0x1037a}, {0x10380, 0x1039d}, {0x1039f, 0x103c3}, {0x103c8, 0x103d5}, + {0x10400, 0x1049d}, {0x104a0, 0x104a9}, {0x104b0, 0x104d3}, {0x104d8, 0x104fb}, + {0x10500, 0x10527}, {0x10530, 0x10563}, {0x10600, 0x10736}, {0x10740, 0x10755}, + {0x10760, 0x10767}, {0x10800, 0x10805}, {0x1080a, 0x10835}, {0x1083f, 0x10855}, + {0x10857, 0x1089e}, {0x108a7, 0x108af}, {0x108e0, 0x108f2}, {0x108fb, 0x1091b}, + {0x1091f, 0x10939}, {0x10980, 0x109b7}, {0x109bc, 0x109cf}, {0x109d2, 0x10a03}, + {0x10a0c, 0x10a13}, {0x10a15, 0x10a17}, {0x10a19, 0x10a33}, {0x10a38, 0x10a3a}, + {0x10a3f, 0x10a47}, {0x10a50, 0x10a58}, {0x10a60, 0x10a9f}, {0x10ac0, 0x10ae6}, + {0x10aeb, 0x10af6}, {0x10b00, 0x10b35}, {0x10b39, 0x10b55}, {0x10b58, 0x10b72}, + {0x10b78, 0x10b91}, {0x10b99, 0x10b9c}, {0x10ba9, 0x10baf}, {0x10c00, 0x10c48}, + {0x10c80, 0x10cb2}, {0x10cc0, 0x10cf2}, {0x10cfa, 0x10cff}, {0x10e60, 0x10e7e}, + {0x11000, 0x1104d}, {0x11052, 0x1106f}, {0x1107f, 0x110bc}, {0x110be, 0x110c1}, + {0x110d0, 0x110e8}, {0x110f0, 0x110f9}, {0x11100, 0x11134}, {0x11136, 0x11143}, + {0x11150, 0x11176}, {0x11180, 0x111cd}, {0x111d0, 0x111df}, {0x111e1, 0x111f4}, + {0x11200, 0x11211}, {0x11213, 0x1123e}, {0x11280, 0x11286}, {0x1128a, 0x1128d}, + {0x1128f, 0x1129d}, {0x1129f, 0x112a9}, {0x112b0, 0x112ea}, {0x112f0, 0x112f9}, + {0x11300, 0x11303}, {0x11305, 0x1130c}, {0x11313, 0x11328}, {0x1132a, 0x11330}, + {0x11335, 0x11339}, {0x1133c, 0x11344}, {0x1134b, 0x1134d}, {0x1135d, 0x11363}, + {0x11366, 0x1136c}, {0x11370, 0x11374}, {0x11400, 0x11459}, {0x11480, 0x114c7}, + {0x114d0, 0x114d9}, {0x11580, 0x115b5}, {0x115b8, 0x115dd}, {0x11600, 0x11644}, + {0x11650, 0x11659}, {0x11660, 0x1166c}, {0x11680, 0x116b7}, {0x116c0, 0x116c9}, + {0x11700, 0x11719}, {0x1171d, 0x1172b}, {0x11730, 0x1173f}, {0x118a0, 0x118f2}, + {0x11a00, 0x11a47}, {0x11a50, 0x11a83}, {0x11a86, 0x11a9c}, {0x11a9e, 0x11aa2}, + {0x11ac0, 0x11af8}, {0x11c00, 0x11c08}, {0x11c0a, 0x11c36}, {0x11c38, 0x11c45}, + {0x11c50, 0x11c6c}, {0x11c70, 0x11c8f}, {0x11c92, 0x11ca7}, {0x11ca9, 0x11cb6}, + {0x11d00, 0x11d06}, {0x11d0b, 0x11d36}, {0x11d3f, 0x11d47}, {0x11d50, 0x11d59}, + {0x12000, 0x12399}, {0x12400, 0x1246e}, {0x12470, 0x12474}, {0x12480, 0x12543}, + {0x13000, 0x1342e}, {0x14400, 0x14646}, {0x16800, 0x16a38}, {0x16a40, 0x16a5e}, + {0x16a60, 0x16a69}, {0x16ad0, 0x16aed}, {0x16af0, 0x16af5}, {0x16b00, 0x16b45}, + {0x16b50, 0x16b59}, {0x16b5b, 0x16b61}, {0x16b63, 0x16b77}, {0x16b7d, 0x16b8f}, + {0x16f00, 0x16f44}, {0x16f50, 0x16f7e}, {0x16f8f, 0x16f9f}, {0x17000, 0x187ec}, + {0x18800, 0x18af2}, {0x1b000, 0x1b11e}, {0x1b170, 0x1b2fb}, {0x1bc00, 0x1bc6a}, + {0x1bc70, 0x1bc7c}, {0x1bc80, 0x1bc88}, {0x1bc90, 0x1bc99}, {0x1bc9c, 0x1bc9f}, + {0x1d000, 0x1d0f5}, {0x1d100, 0x1d126}, {0x1d129, 0x1d172}, {0x1d17b, 0x1d1e8}, + {0x1d200, 0x1d245}, {0x1d300, 0x1d356}, {0x1d360, 0x1d371}, {0x1d400, 0x1d454}, + {0x1d456, 0x1d49c}, {0x1d4a9, 0x1d4ac}, {0x1d4ae, 0x1d4b9}, {0x1d4bd, 0x1d4c3}, + {0x1d4c5, 0x1d505}, {0x1d507, 0x1d50a}, {0x1d50d, 0x1d514}, {0x1d516, 0x1d51c}, + {0x1d51e, 0x1d539}, {0x1d53b, 0x1d53e}, {0x1d540, 0x1d544}, {0x1d54a, 0x1d550}, + {0x1d552, 0x1d6a5}, {0x1d6a8, 0x1d7cb}, {0x1d7ce, 0x1da8b}, {0x1da9b, 0x1da9f}, + {0x1daa1, 0x1daaf}, {0x1e000, 0x1e006}, {0x1e008, 0x1e018}, {0x1e01b, 0x1e021}, + {0x1e026, 0x1e02a}, {0x1e800, 0x1e8c4}, {0x1e8c7, 0x1e8d6}, {0x1e900, 0x1e94a}, + {0x1e950, 0x1e959}, {0x1ee00, 0x1ee03}, {0x1ee05, 0x1ee1f}, {0x1ee29, 0x1ee32}, + {0x1ee34, 0x1ee37}, {0x1ee4d, 0x1ee4f}, {0x1ee67, 0x1ee6a}, {0x1ee6c, 0x1ee72}, + {0x1ee74, 0x1ee77}, {0x1ee79, 0x1ee7c}, {0x1ee80, 0x1ee89}, {0x1ee8b, 0x1ee9b}, + {0x1eea1, 0x1eea3}, {0x1eea5, 0x1eea9}, {0x1eeab, 0x1eebb}, {0x1f000, 0x1f02b}, + {0x1f030, 0x1f093}, {0x1f0a0, 0x1f0ae}, {0x1f0b1, 0x1f0bf}, {0x1f0c1, 0x1f0cf}, + {0x1f0d1, 0x1f0f5}, {0x1f100, 0x1f10c}, {0x1f110, 0x1f12e}, {0x1f130, 0x1f16b}, + {0x1f170, 0x1f1ac}, {0x1f1e6, 0x1f202}, {0x1f210, 0x1f23b}, {0x1f240, 0x1f248}, + {0x1f260, 0x1f265}, {0x1f300, 0x1f6d4}, {0x1f6e0, 0x1f6ec}, {0x1f6f0, 0x1f6f8}, + {0x1f700, 0x1f773}, {0x1f780, 0x1f7d4}, {0x1f800, 0x1f80b}, {0x1f810, 0x1f847}, + {0x1f850, 0x1f859}, {0x1f860, 0x1f887}, {0x1f890, 0x1f8ad}, {0x1f900, 0x1f90b}, + {0x1f910, 0x1f93e}, {0x1f940, 0x1f94c}, {0x1f950, 0x1f96b}, {0x1f980, 0x1f997}, + {0x1f9d0, 0x1f9e6}, {0x20000, 0x2a6d6}, {0x2a700, 0x2b734}, {0x2b740, 0x2b81d}, + {0x2b820, 0x2cea1}, {0x2ceb0, 0x2ebe0}, {0x2f800, 0x2fa1d}, {0xe0100, 0xe01ef} #endif }; @@ -6185,177 +771,14 @@ static const chr graphCharTable[] = { 0x1f5b, 0x1f5d, 0x2070, 0x2071, 0x2d27, 0x2d2d, 0x2d6f, 0x2d70, 0xfb3e, 0xfb40, 0xfb41, 0xfb43, 0xfb44, 0xfffc, 0xfffd #if TCL_UTF_MAX > 4 - ,0x1038c, 0x10589, 0x1058a, 0x1085e, 0x1098f, 0x10990, 0x109b2, 0x109c7, 0x109c8, - 0x109d7, 0x109dc, 0x109dd, 0x10a0f, 0x10a10, 0x10a32, 0x10a33, 0x10a35, 0x10a36, - 0x10a38, 0x10a39, 0x10a3c, 0x10a47, 0x10a48, 0x10a51, 0x10a5e, 0x10ab2, 0x10ab3, - 0x10ad0, 0x10b0f, 0x10b10, 0x10b32, 0x10b33, 0x10b47, 0x10b48, 0x10b56, 0x10b57, - 0x10b5c, 0x10b5d, 0x10b82, 0x10b83, 0x10b99, 0x10b9a, 0x10b9c, 0x10b9e, 0x10b9f, - 0x10ba3, 0x10ba4, 0x10bd0, 0x10bd7, 0x10c55, 0x10c56, 0x10cd5, 0x10cd6, 0x10cde, - 0x10cf1, 0x10cf2, 0x10d82, 0x10d83, 0x10dbd, 0x10dca, 0x10dd6, 0x10e81, 0x10e82, - 0x10e84, 0x10e87, 0x10e88, 0x10e8a, 0x10e8d, 0x10ea5, 0x10ea7, 0x10eaa, 0x10eab, - 0x10ec6, 0x110c7, 0x110cd, 0x11258, 0x112c0, 0x11772, 0x11773, 0x11940, 0x11f59, - 0x11f5b, 0x11f5d, 0x12070, 0x12071, 0x12d27, 0x12d2d, 0x12d6f, 0x12d70, 0x1fb3e, - 0x1fb40, 0x1fb41, 0x1fb43, 0x1fb44, 0x1fffc, 0x1fffd, 0x2038c, 0x20589, 0x2058a, - 0x2085e, 0x2098f, 0x20990, 0x209b2, 0x209c7, 0x209c8, 0x209d7, 0x209dc, 0x209dd, - 0x20a0f, 0x20a10, 0x20a32, 0x20a33, 0x20a35, 0x20a36, 0x20a38, 0x20a39, 0x20a3c, - 0x20a47, 0x20a48, 0x20a51, 0x20a5e, 0x20ab2, 0x20ab3, 0x20ad0, 0x20b0f, 0x20b10, - 0x20b32, 0x20b33, 0x20b47, 0x20b48, 0x20b56, 0x20b57, 0x20b5c, 0x20b5d, 0x20b82, - 0x20b83, 0x20b99, 0x20b9a, 0x20b9c, 0x20b9e, 0x20b9f, 0x20ba3, 0x20ba4, 0x20bd0, - 0x20bd7, 0x20c55, 0x20c56, 0x20cd5, 0x20cd6, 0x20cde, 0x20cf1, 0x20cf2, 0x20d82, - 0x20d83, 0x20dbd, 0x20dca, 0x20dd6, 0x20e81, 0x20e82, 0x20e84, 0x20e87, 0x20e88, - 0x20e8a, 0x20e8d, 0x20ea5, 0x20ea7, 0x20eaa, 0x20eab, 0x20ec6, 0x210c7, 0x210cd, - 0x21258, 0x212c0, 0x21772, 0x21773, 0x21940, 0x21f59, 0x21f5b, 0x21f5d, 0x22070, - 0x22071, 0x22d27, 0x22d2d, 0x22d6f, 0x22d70, 0x2fb3e, 0x2fb40, 0x2fb41, 0x2fb43, - 0x2fb44, 0x2fffc, 0x2fffd, 0x3038c, 0x30589, 0x3058a, 0x3085e, 0x3098f, 0x30990, - 0x309b2, 0x309c7, 0x309c8, 0x309d7, 0x309dc, 0x309dd, 0x30a0f, 0x30a10, 0x30a32, - 0x30a33, 0x30a35, 0x30a36, 0x30a38, 0x30a39, 0x30a3c, 0x30a47, 0x30a48, 0x30a51, - 0x30a5e, 0x30ab2, 0x30ab3, 0x30ad0, 0x30b0f, 0x30b10, 0x30b32, 0x30b33, 0x30b47, - 0x30b48, 0x30b56, 0x30b57, 0x30b5c, 0x30b5d, 0x30b82, 0x30b83, 0x30b99, 0x30b9a, - 0x30b9c, 0x30b9e, 0x30b9f, 0x30ba3, 0x30ba4, 0x30bd0, 0x30bd7, 0x30c55, 0x30c56, - 0x30cd5, 0x30cd6, 0x30cde, 0x30cf1, 0x30cf2, 0x30d82, 0x30d83, 0x30dbd, 0x30dca, - 0x30dd6, 0x30e81, 0x30e82, 0x30e84, 0x30e87, 0x30e88, 0x30e8a, 0x30e8d, 0x30ea5, - 0x30ea7, 0x30eaa, 0x30eab, 0x30ec6, 0x310c7, 0x310cd, 0x31258, 0x312c0, 0x31772, - 0x31773, 0x31940, 0x31f59, 0x31f5b, 0x31f5d, 0x32070, 0x32071, 0x32d27, 0x32d2d, - 0x32d6f, 0x32d70, 0x3fb3e, 0x3fb40, 0x3fb41, 0x3fb43, 0x3fb44, 0x3fffc, 0x3fffd, - 0x4038c, 0x40589, 0x4058a, 0x4085e, 0x4098f, 0x40990, 0x409b2, 0x409c7, 0x409c8, - 0x409d7, 0x409dc, 0x409dd, 0x40a0f, 0x40a10, 0x40a32, 0x40a33, 0x40a35, 0x40a36, - 0x40a38, 0x40a39, 0x40a3c, 0x40a47, 0x40a48, 0x40a51, 0x40a5e, 0x40ab2, 0x40ab3, - 0x40ad0, 0x40b0f, 0x40b10, 0x40b32, 0x40b33, 0x40b47, 0x40b48, 0x40b56, 0x40b57, - 0x40b5c, 0x40b5d, 0x40b82, 0x40b83, 0x40b99, 0x40b9a, 0x40b9c, 0x40b9e, 0x40b9f, - 0x40ba3, 0x40ba4, 0x40bd0, 0x40bd7, 0x40c55, 0x40c56, 0x40cd5, 0x40cd6, 0x40cde, - 0x40cf1, 0x40cf2, 0x40d82, 0x40d83, 0x40dbd, 0x40dca, 0x40dd6, 0x40e81, 0x40e82, - 0x40e84, 0x40e87, 0x40e88, 0x40e8a, 0x40e8d, 0x40ea5, 0x40ea7, 0x40eaa, 0x40eab, - 0x40ec6, 0x410c7, 0x410cd, 0x41258, 0x412c0, 0x41772, 0x41773, 0x41940, 0x41f59, - 0x41f5b, 0x41f5d, 0x42070, 0x42071, 0x42d27, 0x42d2d, 0x42d6f, 0x42d70, 0x4fb3e, - 0x4fb40, 0x4fb41, 0x4fb43, 0x4fb44, 0x4fffc, 0x4fffd, 0x5038c, 0x50589, 0x5058a, - 0x5085e, 0x5098f, 0x50990, 0x509b2, 0x509c7, 0x509c8, 0x509d7, 0x509dc, 0x509dd, - 0x50a0f, 0x50a10, 0x50a32, 0x50a33, 0x50a35, 0x50a36, 0x50a38, 0x50a39, 0x50a3c, - 0x50a47, 0x50a48, 0x50a51, 0x50a5e, 0x50ab2, 0x50ab3, 0x50ad0, 0x50b0f, 0x50b10, - 0x50b32, 0x50b33, 0x50b47, 0x50b48, 0x50b56, 0x50b57, 0x50b5c, 0x50b5d, 0x50b82, - 0x50b83, 0x50b99, 0x50b9a, 0x50b9c, 0x50b9e, 0x50b9f, 0x50ba3, 0x50ba4, 0x50bd0, - 0x50bd7, 0x50c55, 0x50c56, 0x50cd5, 0x50cd6, 0x50cde, 0x50cf1, 0x50cf2, 0x50d82, - 0x50d83, 0x50dbd, 0x50dca, 0x50dd6, 0x50e81, 0x50e82, 0x50e84, 0x50e87, 0x50e88, - 0x50e8a, 0x50e8d, 0x50ea5, 0x50ea7, 0x50eaa, 0x50eab, 0x50ec6, 0x510c7, 0x510cd, - 0x51258, 0x512c0, 0x51772, 0x51773, 0x51940, 0x51f59, 0x51f5b, 0x51f5d, 0x52070, - 0x52071, 0x52d27, 0x52d2d, 0x52d6f, 0x52d70, 0x5fb3e, 0x5fb40, 0x5fb41, 0x5fb43, - 0x5fb44, 0x5fffc, 0x5fffd, 0x6038c, 0x60589, 0x6058a, 0x6085e, 0x6098f, 0x60990, - 0x609b2, 0x609c7, 0x609c8, 0x609d7, 0x609dc, 0x609dd, 0x60a0f, 0x60a10, 0x60a32, - 0x60a33, 0x60a35, 0x60a36, 0x60a38, 0x60a39, 0x60a3c, 0x60a47, 0x60a48, 0x60a51, - 0x60a5e, 0x60ab2, 0x60ab3, 0x60ad0, 0x60b0f, 0x60b10, 0x60b32, 0x60b33, 0x60b47, - 0x60b48, 0x60b56, 0x60b57, 0x60b5c, 0x60b5d, 0x60b82, 0x60b83, 0x60b99, 0x60b9a, - 0x60b9c, 0x60b9e, 0x60b9f, 0x60ba3, 0x60ba4, 0x60bd0, 0x60bd7, 0x60c55, 0x60c56, - 0x60cd5, 0x60cd6, 0x60cde, 0x60cf1, 0x60cf2, 0x60d82, 0x60d83, 0x60dbd, 0x60dca, - 0x60dd6, 0x60e81, 0x60e82, 0x60e84, 0x60e87, 0x60e88, 0x60e8a, 0x60e8d, 0x60ea5, - 0x60ea7, 0x60eaa, 0x60eab, 0x60ec6, 0x610c7, 0x610cd, 0x61258, 0x612c0, 0x61772, - 0x61773, 0x61940, 0x61f59, 0x61f5b, 0x61f5d, 0x62070, 0x62071, 0x62d27, 0x62d2d, - 0x62d6f, 0x62d70, 0x6fb3e, 0x6fb40, 0x6fb41, 0x6fb43, 0x6fb44, 0x6fffc, 0x6fffd, - 0x7038c, 0x70589, 0x7058a, 0x7085e, 0x7098f, 0x70990, 0x709b2, 0x709c7, 0x709c8, - 0x709d7, 0x709dc, 0x709dd, 0x70a0f, 0x70a10, 0x70a32, 0x70a33, 0x70a35, 0x70a36, - 0x70a38, 0x70a39, 0x70a3c, 0x70a47, 0x70a48, 0x70a51, 0x70a5e, 0x70ab2, 0x70ab3, - 0x70ad0, 0x70b0f, 0x70b10, 0x70b32, 0x70b33, 0x70b47, 0x70b48, 0x70b56, 0x70b57, - 0x70b5c, 0x70b5d, 0x70b82, 0x70b83, 0x70b99, 0x70b9a, 0x70b9c, 0x70b9e, 0x70b9f, - 0x70ba3, 0x70ba4, 0x70bd0, 0x70bd7, 0x70c55, 0x70c56, 0x70cd5, 0x70cd6, 0x70cde, - 0x70cf1, 0x70cf2, 0x70d82, 0x70d83, 0x70dbd, 0x70dca, 0x70dd6, 0x70e81, 0x70e82, - 0x70e84, 0x70e87, 0x70e88, 0x70e8a, 0x70e8d, 0x70ea5, 0x70ea7, 0x70eaa, 0x70eab, - 0x70ec6, 0x710c7, 0x710cd, 0x71258, 0x712c0, 0x71772, 0x71773, 0x71940, 0x71f59, - 0x71f5b, 0x71f5d, 0x72070, 0x72071, 0x72d27, 0x72d2d, 0x72d6f, 0x72d70, 0x7fb3e, - 0x7fb40, 0x7fb41, 0x7fb43, 0x7fb44, 0x7fffc, 0x7fffd, 0x8038c, 0x80589, 0x8058a, - 0x8085e, 0x8098f, 0x80990, 0x809b2, 0x809c7, 0x809c8, 0x809d7, 0x809dc, 0x809dd, - 0x80a0f, 0x80a10, 0x80a32, 0x80a33, 0x80a35, 0x80a36, 0x80a38, 0x80a39, 0x80a3c, - 0x80a47, 0x80a48, 0x80a51, 0x80a5e, 0x80ab2, 0x80ab3, 0x80ad0, 0x80b0f, 0x80b10, - 0x80b32, 0x80b33, 0x80b47, 0x80b48, 0x80b56, 0x80b57, 0x80b5c, 0x80b5d, 0x80b82, - 0x80b83, 0x80b99, 0x80b9a, 0x80b9c, 0x80b9e, 0x80b9f, 0x80ba3, 0x80ba4, 0x80bd0, - 0x80bd7, 0x80c55, 0x80c56, 0x80cd5, 0x80cd6, 0x80cde, 0x80cf1, 0x80cf2, 0x80d82, - 0x80d83, 0x80dbd, 0x80dca, 0x80dd6, 0x80e81, 0x80e82, 0x80e84, 0x80e87, 0x80e88, - 0x80e8a, 0x80e8d, 0x80ea5, 0x80ea7, 0x80eaa, 0x80eab, 0x80ec6, 0x810c7, 0x810cd, - 0x81258, 0x812c0, 0x81772, 0x81773, 0x81940, 0x81f59, 0x81f5b, 0x81f5d, 0x82070, - 0x82071, 0x82d27, 0x82d2d, 0x82d6f, 0x82d70, 0x8fb3e, 0x8fb40, 0x8fb41, 0x8fb43, - 0x8fb44, 0x8fffc, 0x8fffd, 0x9038c, 0x90589, 0x9058a, 0x9085e, 0x9098f, 0x90990, - 0x909b2, 0x909c7, 0x909c8, 0x909d7, 0x909dc, 0x909dd, 0x90a0f, 0x90a10, 0x90a32, - 0x90a33, 0x90a35, 0x90a36, 0x90a38, 0x90a39, 0x90a3c, 0x90a47, 0x90a48, 0x90a51, - 0x90a5e, 0x90ab2, 0x90ab3, 0x90ad0, 0x90b0f, 0x90b10, 0x90b32, 0x90b33, 0x90b47, - 0x90b48, 0x90b56, 0x90b57, 0x90b5c, 0x90b5d, 0x90b82, 0x90b83, 0x90b99, 0x90b9a, - 0x90b9c, 0x90b9e, 0x90b9f, 0x90ba3, 0x90ba4, 0x90bd0, 0x90bd7, 0x90c55, 0x90c56, - 0x90cd5, 0x90cd6, 0x90cde, 0x90cf1, 0x90cf2, 0x90d82, 0x90d83, 0x90dbd, 0x90dca, - 0x90dd6, 0x90e81, 0x90e82, 0x90e84, 0x90e87, 0x90e88, 0x90e8a, 0x90e8d, 0x90ea5, - 0x90ea7, 0x90eaa, 0x90eab, 0x90ec6, 0x910c7, 0x910cd, 0x91258, 0x912c0, 0x91772, - 0x91773, 0x91940, 0x91f59, 0x91f5b, 0x91f5d, 0x92070, 0x92071, 0x92d27, 0x92d2d, - 0x92d6f, 0x92d70, 0x9fb3e, 0x9fb40, 0x9fb41, 0x9fb43, 0x9fb44, 0x9fffc, 0x9fffd, - 0xa038c, 0xa0589, 0xa058a, 0xa085e, 0xa098f, 0xa0990, 0xa09b2, 0xa09c7, 0xa09c8, - 0xa09d7, 0xa09dc, 0xa09dd, 0xa0a0f, 0xa0a10, 0xa0a32, 0xa0a33, 0xa0a35, 0xa0a36, - 0xa0a38, 0xa0a39, 0xa0a3c, 0xa0a47, 0xa0a48, 0xa0a51, 0xa0a5e, 0xa0ab2, 0xa0ab3, - 0xa0ad0, 0xa0b0f, 0xa0b10, 0xa0b32, 0xa0b33, 0xa0b47, 0xa0b48, 0xa0b56, 0xa0b57, - 0xa0b5c, 0xa0b5d, 0xa0b82, 0xa0b83, 0xa0b99, 0xa0b9a, 0xa0b9c, 0xa0b9e, 0xa0b9f, - 0xa0ba3, 0xa0ba4, 0xa0bd0, 0xa0bd7, 0xa0c55, 0xa0c56, 0xa0cd5, 0xa0cd6, 0xa0cde, - 0xa0cf1, 0xa0cf2, 0xa0d82, 0xa0d83, 0xa0dbd, 0xa0dca, 0xa0dd6, 0xa0e81, 0xa0e82, - 0xa0e84, 0xa0e87, 0xa0e88, 0xa0e8a, 0xa0e8d, 0xa0ea5, 0xa0ea7, 0xa0eaa, 0xa0eab, - 0xa0ec6, 0xa10c7, 0xa10cd, 0xa1258, 0xa12c0, 0xa1772, 0xa1773, 0xa1940, 0xa1f59, - 0xa1f5b, 0xa1f5d, 0xa2070, 0xa2071, 0xa2d27, 0xa2d2d, 0xa2d6f, 0xa2d70, 0xafb3e, - 0xafb40, 0xafb41, 0xafb43, 0xafb44, 0xafffc, 0xafffd, 0xb038c, 0xb0589, 0xb058a, - 0xb085e, 0xb098f, 0xb0990, 0xb09b2, 0xb09c7, 0xb09c8, 0xb09d7, 0xb09dc, 0xb09dd, - 0xb0a0f, 0xb0a10, 0xb0a32, 0xb0a33, 0xb0a35, 0xb0a36, 0xb0a38, 0xb0a39, 0xb0a3c, - 0xb0a47, 0xb0a48, 0xb0a51, 0xb0a5e, 0xb0ab2, 0xb0ab3, 0xb0ad0, 0xb0b0f, 0xb0b10, - 0xb0b32, 0xb0b33, 0xb0b47, 0xb0b48, 0xb0b56, 0xb0b57, 0xb0b5c, 0xb0b5d, 0xb0b82, - 0xb0b83, 0xb0b99, 0xb0b9a, 0xb0b9c, 0xb0b9e, 0xb0b9f, 0xb0ba3, 0xb0ba4, 0xb0bd0, - 0xb0bd7, 0xb0c55, 0xb0c56, 0xb0cd5, 0xb0cd6, 0xb0cde, 0xb0cf1, 0xb0cf2, 0xb0d82, - 0xb0d83, 0xb0dbd, 0xb0dca, 0xb0dd6, 0xb0e81, 0xb0e82, 0xb0e84, 0xb0e87, 0xb0e88, - 0xb0e8a, 0xb0e8d, 0xb0ea5, 0xb0ea7, 0xb0eaa, 0xb0eab, 0xb0ec6, 0xb10c7, 0xb10cd, - 0xb1258, 0xb12c0, 0xb1772, 0xb1773, 0xb1940, 0xb1f59, 0xb1f5b, 0xb1f5d, 0xb2070, - 0xb2071, 0xb2d27, 0xb2d2d, 0xb2d6f, 0xb2d70, 0xbfb3e, 0xbfb40, 0xbfb41, 0xbfb43, - 0xbfb44, 0xbfffc, 0xbfffd, 0xc038c, 0xc0589, 0xc058a, 0xc085e, 0xc098f, 0xc0990, - 0xc09b2, 0xc09c7, 0xc09c8, 0xc09d7, 0xc09dc, 0xc09dd, 0xc0a0f, 0xc0a10, 0xc0a32, - 0xc0a33, 0xc0a35, 0xc0a36, 0xc0a38, 0xc0a39, 0xc0a3c, 0xc0a47, 0xc0a48, 0xc0a51, - 0xc0a5e, 0xc0ab2, 0xc0ab3, 0xc0ad0, 0xc0b0f, 0xc0b10, 0xc0b32, 0xc0b33, 0xc0b47, - 0xc0b48, 0xc0b56, 0xc0b57, 0xc0b5c, 0xc0b5d, 0xc0b82, 0xc0b83, 0xc0b99, 0xc0b9a, - 0xc0b9c, 0xc0b9e, 0xc0b9f, 0xc0ba3, 0xc0ba4, 0xc0bd0, 0xc0bd7, 0xc0c55, 0xc0c56, - 0xc0cd5, 0xc0cd6, 0xc0cde, 0xc0cf1, 0xc0cf2, 0xc0d82, 0xc0d83, 0xc0dbd, 0xc0dca, - 0xc0dd6, 0xc0e81, 0xc0e82, 0xc0e84, 0xc0e87, 0xc0e88, 0xc0e8a, 0xc0e8d, 0xc0ea5, - 0xc0ea7, 0xc0eaa, 0xc0eab, 0xc0ec6, 0xc10c7, 0xc10cd, 0xc1258, 0xc12c0, 0xc1772, - 0xc1773, 0xc1940, 0xc1f59, 0xc1f5b, 0xc1f5d, 0xc2070, 0xc2071, 0xc2d27, 0xc2d2d, - 0xc2d6f, 0xc2d70, 0xcfb3e, 0xcfb40, 0xcfb41, 0xcfb43, 0xcfb44, 0xcfffc, 0xcfffd, - 0xd038c, 0xd0589, 0xd058a, 0xd085e, 0xd098f, 0xd0990, 0xd09b2, 0xd09c7, 0xd09c8, - 0xd09d7, 0xd09dc, 0xd09dd, 0xd0a0f, 0xd0a10, 0xd0a32, 0xd0a33, 0xd0a35, 0xd0a36, - 0xd0a38, 0xd0a39, 0xd0a3c, 0xd0a47, 0xd0a48, 0xd0a51, 0xd0a5e, 0xd0ab2, 0xd0ab3, - 0xd0ad0, 0xd0b0f, 0xd0b10, 0xd0b32, 0xd0b33, 0xd0b47, 0xd0b48, 0xd0b56, 0xd0b57, - 0xd0b5c, 0xd0b5d, 0xd0b82, 0xd0b83, 0xd0b99, 0xd0b9a, 0xd0b9c, 0xd0b9e, 0xd0b9f, - 0xd0ba3, 0xd0ba4, 0xd0bd0, 0xd0bd7, 0xd0c55, 0xd0c56, 0xd0cd5, 0xd0cd6, 0xd0cde, - 0xd0cf1, 0xd0cf2, 0xd0d82, 0xd0d83, 0xd0dbd, 0xd0dca, 0xd0dd6, 0xd0e81, 0xd0e82, - 0xd0e84, 0xd0e87, 0xd0e88, 0xd0e8a, 0xd0e8d, 0xd0ea5, 0xd0ea7, 0xd0eaa, 0xd0eab, - 0xd0ec6, 0xd10c7, 0xd10cd, 0xd1258, 0xd12c0, 0xd1772, 0xd1773, 0xd1940, 0xd1f59, - 0xd1f5b, 0xd1f5d, 0xd2070, 0xd2071, 0xd2d27, 0xd2d2d, 0xd2d6f, 0xd2d70, 0xdfb3e, - 0xdfb40, 0xdfb41, 0xdfb43, 0xdfb44, 0xdfffc, 0xdfffd, 0xe038c, 0xe0589, 0xe058a, - 0xe085e, 0xe098f, 0xe0990, 0xe09b2, 0xe09c7, 0xe09c8, 0xe09d7, 0xe09dc, 0xe09dd, - 0xe0a0f, 0xe0a10, 0xe0a32, 0xe0a33, 0xe0a35, 0xe0a36, 0xe0a38, 0xe0a39, 0xe0a3c, - 0xe0a47, 0xe0a48, 0xe0a51, 0xe0a5e, 0xe0ab2, 0xe0ab3, 0xe0ad0, 0xe0b0f, 0xe0b10, - 0xe0b32, 0xe0b33, 0xe0b47, 0xe0b48, 0xe0b56, 0xe0b57, 0xe0b5c, 0xe0b5d, 0xe0b82, - 0xe0b83, 0xe0b99, 0xe0b9a, 0xe0b9c, 0xe0b9e, 0xe0b9f, 0xe0ba3, 0xe0ba4, 0xe0bd0, - 0xe0bd7, 0xe0c55, 0xe0c56, 0xe0cd5, 0xe0cd6, 0xe0cde, 0xe0cf1, 0xe0cf2, 0xe0d82, - 0xe0d83, 0xe0dbd, 0xe0dca, 0xe0dd6, 0xe0e81, 0xe0e82, 0xe0e84, 0xe0e87, 0xe0e88, - 0xe0e8a, 0xe0e8d, 0xe0ea5, 0xe0ea7, 0xe0eaa, 0xe0eab, 0xe0ec6, 0xe10c7, 0xe10cd, - 0xe1258, 0xe12c0, 0xe1772, 0xe1773, 0xe1940, 0xe1f59, 0xe1f5b, 0xe1f5d, 0xe2070, - 0xe2071, 0xe2d27, 0xe2d2d, 0xe2d6f, 0xe2d70, 0xefb3e, 0xefb40, 0xefb41, 0xefb43, - 0xefb44, 0xefffc, 0xefffd, 0xf038c, 0xf0589, 0xf058a, 0xf085e, 0xf098f, 0xf0990, - 0xf09b2, 0xf09c7, 0xf09c8, 0xf09d7, 0xf09dc, 0xf09dd, 0xf0a0f, 0xf0a10, 0xf0a32, - 0xf0a33, 0xf0a35, 0xf0a36, 0xf0a38, 0xf0a39, 0xf0a3c, 0xf0a47, 0xf0a48, 0xf0a51, - 0xf0a5e, 0xf0ab2, 0xf0ab3, 0xf0ad0, 0xf0b0f, 0xf0b10, 0xf0b32, 0xf0b33, 0xf0b47, - 0xf0b48, 0xf0b56, 0xf0b57, 0xf0b5c, 0xf0b5d, 0xf0b82, 0xf0b83, 0xf0b99, 0xf0b9a, - 0xf0b9c, 0xf0b9e, 0xf0b9f, 0xf0ba3, 0xf0ba4, 0xf0bd0, 0xf0bd7, 0xf0c55, 0xf0c56, - 0xf0cd5, 0xf0cd6, 0xf0cde, 0xf0cf1, 0xf0cf2, 0xf0d82, 0xf0d83, 0xf0dbd, 0xf0dca, - 0xf0dd6, 0xf0e81, 0xf0e82, 0xf0e84, 0xf0e87, 0xf0e88, 0xf0e8a, 0xf0e8d, 0xf0ea5, - 0xf0ea7, 0xf0eaa, 0xf0eab, 0xf0ec6, 0xf10c7, 0xf10cd, 0xf1258, 0xf12c0, 0xf1772, - 0xf1773, 0xf1940, 0xf1f59, 0xf1f5b, 0xf1f5d, 0xf2070, 0xf2071, 0xf2d27, 0xf2d2d, - 0xf2d6f, 0xf2d70, 0xffb3e, 0xffb40, 0xffb41, 0xffb43, 0xffb44, 0xffffc, 0xffffd, - 0x10038c, 0x100589, 0x10058a, 0x10085e, 0x10098f, 0x100990, 0x1009b2, 0x1009c7, 0x1009c8, - 0x1009d7, 0x1009dc, 0x1009dd, 0x100a0f, 0x100a10, 0x100a32, 0x100a33, 0x100a35, 0x100a36, - 0x100a38, 0x100a39, 0x100a3c, 0x100a47, 0x100a48, 0x100a51, 0x100a5e, 0x100ab2, 0x100ab3, - 0x100ad0, 0x100b0f, 0x100b10, 0x100b32, 0x100b33, 0x100b47, 0x100b48, 0x100b56, 0x100b57, - 0x100b5c, 0x100b5d, 0x100b82, 0x100b83, 0x100b99, 0x100b9a, 0x100b9c, 0x100b9e, 0x100b9f, - 0x100ba3, 0x100ba4, 0x100bd0, 0x100bd7, 0x100c55, 0x100c56, 0x100cd5, 0x100cd6, 0x100cde, - 0x100cf1, 0x100cf2, 0x100d82, 0x100d83, 0x100dbd, 0x100dca, 0x100dd6, 0x100e81, 0x100e82, - 0x100e84, 0x100e87, 0x100e88, 0x100e8a, 0x100e8d, 0x100ea5, 0x100ea7, 0x100eaa, 0x100eab, - 0x100ec6, 0x1010c7, 0x1010cd, 0x101258, 0x1012c0, 0x101772, 0x101773, 0x101940, 0x101f59, - 0x101f5b, 0x101f5d, 0x102070, 0x102071, 0x102d27, 0x102d2d, 0x102d6f, 0x102d70, 0x10fb3e, - 0x10fb40, 0x10fb41, 0x10fb43, 0x10fb44, 0x10fffc, 0x10fffd + ,0x1003c, 0x1003d, 0x101a0, 0x1056f, 0x10808, 0x10837, 0x10838, 0x1083c, 0x108f4, + 0x108f5, 0x1093f, 0x10a05, 0x10a06, 0x11288, 0x1130f, 0x11310, 0x11332, 0x11333, + 0x11347, 0x11348, 0x11350, 0x11357, 0x1145b, 0x1145d, 0x118ff, 0x11d08, 0x11d09, + 0x11d3a, 0x11d3c, 0x11d3d, 0x16a6e, 0x16a6f, 0x16fe0, 0x16fe1, 0x1d49e, 0x1d49f, + 0x1d4a2, 0x1d4a5, 0x1d4a6, 0x1d4bb, 0x1d546, 0x1e023, 0x1e024, 0x1e95e, 0x1e95f, + 0x1ee21, 0x1ee22, 0x1ee24, 0x1ee27, 0x1ee39, 0x1ee3b, 0x1ee42, 0x1ee47, 0x1ee49, + 0x1ee4b, 0x1ee51, 0x1ee52, 0x1ee54, 0x1ee57, 0x1ee59, 0x1ee5b, 0x1ee5d, 0x1ee5f, + 0x1ee61, 0x1ee62, 0x1ee64, 0x1ee7e, 0x1eef0, 0x1eef1, 0x1f250, 0x1f251, 0x1f9c0 #endif }; diff --git a/unix/tclEpollNotfy.c b/unix/tclEpollNotfy.c index 5ed5d5d..088f314 100644 --- a/unix/tclEpollNotfy.c +++ b/unix/tclEpollNotfy.c @@ -21,7 +21,9 @@ #include #include #include +#ifdef HAVE_EVENTFD #include +#endif /* HAVE_EVENTFD */ #include #include -- cgit v0.12 From c688e0737c069a7a0eb18ae41dbea80d5645032d Mon Sep 17 00:00:00 2001 From: "jan.nijtmans" Date: Fri, 2 Jun 2017 08:17:26 +0000 Subject: Fix [67aa9a207037ae67f9014b544c3db34fa732f2dc|67aa9a2070]: Security: Invalid UTF-8 can inject unexpected characters --- generic/tclUtf.c | 12 +++++++++--- tests/encoding.test | 25 +++++++++++++++++++++++++ 2 files changed, 34 insertions(+), 3 deletions(-) diff --git a/generic/tclUtf.c b/generic/tclUtf.c index 68119a4..fe47f0b 100644 --- a/generic/tclUtf.c +++ b/generic/tclUtf.c @@ -298,7 +298,9 @@ Tcl_UtfToUniChar( */ *chPtr = (Tcl_UniChar) (((byte & 0x1F) << 6) | (src[1] & 0x3F)); - return 2; + if ((*chPtr == 0) || (*chPtr > 0x7f)) { + return 2; + } } /* @@ -313,7 +315,9 @@ Tcl_UtfToUniChar( *chPtr = (Tcl_UniChar) (((byte & 0x0F) << 12) | ((src[1] & 0x3F) << 6) | (src[2] & 0x3F)); - return 3; + if (*chPtr > 0x7ff) { + return 3; + } } /* @@ -330,7 +334,9 @@ Tcl_UtfToUniChar( *chPtr = (Tcl_UniChar) (((byte & 0x0E) << 18) | ((src[1] & 0x3F) << 12) | ((src[2] & 0x3F) << 6) | (src[3] & 0x3F)); - return 4; + if ((*chPtr <= 0x10ffff) && (*chPtr > 0xffff)) { + return 4; + } } /* diff --git a/tests/encoding.test b/tests/encoding.test index 0374e2d..1d8bae5 100644 --- a/tests/encoding.test +++ b/tests/encoding.test @@ -448,6 +448,31 @@ test encoding-24.3 {EscapeFreeProc on open channels} {stdio} { list $count [viewable $line] } [list 3 "\u4e4e\u4e5e\u4e5f (\\u4e4e\\u4e5e\\u4e5f)"] +test encoding-24.4 {Parse valid or invalid utf-8} { + string length [encoding convertfrom utf-8 "\xc0\x80"] +} 1 +test encoding-24.5 {Parse valid or invalid utf-8} { + string length [encoding convertfrom utf-8 "\xc0\x81"] +} 2 +test encoding-24.6 {Parse valid or invalid utf-8} { + string length [encoding convertfrom utf-8 "\xc1\xbf"] +} 2 +test encoding-24.7 {Parse valid or invalid utf-8} { + string length [encoding convertfrom utf-8 "\xc2\x80"] +} 1 +test encoding-24.8 {Parse valid or invalid utf-8} { + string length [encoding convertfrom utf-8 "\xe0\x80\x80"] +} 3 +test encoding-24.9 {Parse valid or invalid utf-8} { + string length [encoding convertfrom utf-8 "\xe0\x9f\xbf"] +} 3 +test encoding-24.10 {Parse valid or invalid utf-8} { + string length [encoding convertfrom utf-8 "\xe0\xa0\x80"] +} 1 +test encoding-24.10 {Parse valid or invalid utf-8} { + string length [encoding convertfrom utf-8 "\xef\xbf\xbf"] +} 1 + file delete [file join [temporaryDirectory] iso2022.txt] # -- cgit v0.12 From 901f58f13be249bb5c70ece3be76324576d5b494 Mon Sep 17 00:00:00 2001 From: "jan.nijtmans" Date: Fri, 2 Jun 2017 10:34:45 +0000 Subject: Change refCount field in DictObj from int to size_t. Cherry-picked from "sebres-8-6-clock-speedup-cr1" branch. --- generic/tclDictObj.c | 18 ++++++++---------- 1 file changed, 8 insertions(+), 10 deletions(-) diff --git a/generic/tclDictObj.c b/generic/tclDictObj.c index 428173d..87fb333 100644 --- a/generic/tclDictObj.c +++ b/generic/tclDictObj.c @@ -142,7 +142,7 @@ typedef struct Dict { * the entries in the order that they are * created. */ int epoch; /* Epoch counter */ - int refcount; /* Reference counter (see above) */ + size_t refCount; /* Reference counter (see above) */ Tcl_Obj *chain; /* Linked list used for invalidating the * string representations of updated nested * dictionaries. */ @@ -392,7 +392,7 @@ DupDictInternalRep( newDict->epoch = 0; newDict->chain = NULL; - newDict->refcount = 1; + newDict->refCount = 1; /* * Store in the object. @@ -427,8 +427,7 @@ FreeDictInternalRep( { Dict *dict = DICT(dictPtr); - dict->refcount--; - if (dict->refcount <= 0) { + if (dict->refCount-- <= 1) { DeleteDict(dict); } dictPtr->typePtr = NULL; @@ -713,7 +712,7 @@ SetDictFromAny( TclFreeIntRep(objPtr); dict->epoch = 0; dict->chain = NULL; - dict->refcount = 1; + dict->refCount = 1; DICT(objPtr) = dict; objPtr->internalRep.twoPtrValue.ptr2 = NULL; objPtr->typePtr = &tclDictType; @@ -1117,7 +1116,7 @@ Tcl_DictObjFirst( searchPtr->dictionaryPtr = (Tcl_Dict) dict; searchPtr->epoch = dict->epoch; searchPtr->next = cPtr->nextPtr; - dict->refcount++; + dict->refCount++; if (keyPtrPtr != NULL) { *keyPtrPtr = Tcl_GetHashKey(&dict->table, &cPtr->entry); } @@ -1231,8 +1230,7 @@ Tcl_DictObjDone( if (searchPtr->epoch != -1) { searchPtr->epoch = -1; dict = (Dict *) searchPtr->dictionaryPtr; - dict->refcount--; - if (dict->refcount <= 0) { + if (dict->refCount-- <= 1) { DeleteDict(dict); } } @@ -1384,7 +1382,7 @@ Tcl_NewDictObj(void) InitChainTable(dict); dict->epoch = 0; dict->chain = NULL; - dict->refcount = 1; + dict->refCount = 1; DICT(dictPtr) = dict; dictPtr->internalRep.twoPtrValue.ptr2 = NULL; dictPtr->typePtr = &tclDictType; @@ -1434,7 +1432,7 @@ Tcl_DbNewDictObj( InitChainTable(dict); dict->epoch = 0; dict->chain = NULL; - dict->refcount = 1; + dict->refCount = 1; DICT(dictPtr) = dict; dictPtr->internalRep.twoPtrValue.ptr2 = NULL; dictPtr->typePtr = &tclDictType; -- cgit v0.12 From 5c4bb0f4e9e073df2b65f086dd9660cd344dcb26 Mon Sep 17 00:00:00 2001 From: dgp Date: Mon, 5 Jun 2017 17:57:33 +0000 Subject: Revert performance optimization as first step to providing a refactored one. --- generic/tclExecute.c | 25 +------------------------ 1 file changed, 1 insertion(+), 24 deletions(-) diff --git a/generic/tclExecute.c b/generic/tclExecute.c index 30ef536..cfcdd26 100644 --- a/generic/tclExecute.c +++ b/generic/tclExecute.c @@ -2685,34 +2685,11 @@ TEBCresume( opnd = TclGetUInt1AtPtr(pc+1); - objv = &OBJ_AT_DEPTH(opnd-1); - /* minor optimization in simplest cases */ - switch (opnd) { - case 1: /* only one object */ - objResultPtr = *objv; - goto endINST_STR_CONCAT1; - case 2: /* two objects - check empty */ - if (objv[0]->bytes == &tclEmptyString) { - objResultPtr = objv[1]; - goto endINST_STR_CONCAT1; - } - else - if (objv[1]->bytes == &tclEmptyString) { - objResultPtr = objv[0]; - goto endINST_STR_CONCAT1; - } - break; - case 0: /* no objects - use new empty */ - TclNewObj(objResultPtr); - goto endINST_STR_CONCAT1; - } - /* do concat */ if (TCL_OK != TclStringCatObjv(interp, /* inPlace */ 1, - opnd, objv, &objResultPtr)) { + opnd, &OBJ_AT_DEPTH(opnd-1), &objResultPtr)) { TRACE_ERROR(interp); goto gotError; } - endINST_STR_CONCAT1: TRACE_WITH_OBJ(("%u => ", opnd), objResultPtr); NEXT_INST_V(2, opnd, 1); -- cgit v0.12 From cb68061d12f2680e86ea13986fd98eabbe706537 Mon Sep 17 00:00:00 2001 From: dgp Date: Mon, 5 Jun 2017 20:03:19 +0000 Subject: Optimize TclStringCatObjv() for case when only one argument is non-empty. --- generic/tclStringObj.c | 30 ++++++++++++++++++++++-------- 1 file changed, 22 insertions(+), 8 deletions(-) diff --git a/generic/tclStringObj.c b/generic/tclStringObj.c index 3478cbb..a4c242a 100644 --- a/generic/tclStringObj.c +++ b/generic/tclStringObj.c @@ -2848,7 +2848,7 @@ TclStringCatObjv( Tcl_Obj **objPtrPtr) { Tcl_Obj *objPtr, *objResultPtr, * const *ov; - int oc, length = 0, binary = 1, first = 0; + int oc, length = 0, binary = 1, first = 0, last = 0; int allowUniChar = 1, requestUniChar = 0; /* assert (objc >= 2) */ @@ -2904,8 +2904,11 @@ TclStringCatObjv( int numBytes; Tcl_GetByteArrayFromObj(objPtr, &numBytes); /* PANIC? */ - if (length == 0) { - first = objc - oc - 1; + if (numBytes) { + last = objc - oc - 1; + if (length == 0) { + first = last; + } } length += numBytes; } @@ -2920,8 +2923,11 @@ TclStringCatObjv( int numChars; Tcl_GetUnicodeFromObj(objPtr, &numChars); /* PANIC? */ - if (length == 0) { - first = objc - oc - 1; + if (numChars) { + last = objc - oc - 1; + if (length == 0) { + first = last; + } } length += numChars; } @@ -2935,8 +2941,11 @@ TclStringCatObjv( objPtr = *ov++; Tcl_GetStringFromObj(objPtr, &numBytes); /* PANIC? */ - if ((length == 0) && numBytes) { - first = objc - oc - 1; + if (numBytes) { + last = objc - oc - 1; + if (length == 0) { + first = last; + } } length += numBytes; } @@ -2956,8 +2965,13 @@ TclStringCatObjv( *objPtrPtr = objv[0]; return TCL_OK; } + if (last == first) { + /* Only one non-empty value; return it */ + *objPtrPtr = objv[first]; + return TCL_OK; + } - objv += first; objc -= first; + objv += first; objc = (last - first + 1); if (binary) { /* Efficiently produce a pure byte array result */ -- cgit v0.12 From 3d8a0152affb0feac24a3e9b6272e7c2badb050f Mon Sep 17 00:00:00 2001 From: sebres Date: Tue, 6 Jun 2017 08:34:00 +0000 Subject: small code review: don't need to check length if unchanged + the same case if 0 length --- generic/tclStringObj.c | 35 ++++++++++++++++++----------------- 1 file changed, 18 insertions(+), 17 deletions(-) diff --git a/generic/tclStringObj.c b/generic/tclStringObj.c index a4c242a..c1c15f2 100644 --- a/generic/tclStringObj.c +++ b/generic/tclStringObj.c @@ -2897,7 +2897,7 @@ TclStringCatObjv( if (binary) { /* Result will be pure byte array. Pre-size it */ ov = objv; oc = objc; - while (oc-- && (length >= 0)) { + while (oc--) { objPtr = *ov++; if (objPtr->bytes == NULL) { @@ -2909,14 +2909,16 @@ TclStringCatObjv( if (length == 0) { first = last; } + if ((length += numBytes) < 0) { + break; /* overflow */ + } } - length += numBytes; } } } else if (allowUniChar && requestUniChar) { /* Result will be pure Tcl_UniChar array. Pre-size it. */ ov = objv; oc = objc; - while (oc-- && (length >= 0)) { + while (oc--) { objPtr = *ov++; if ((objPtr->bytes == NULL) || (objPtr->length)) { @@ -2929,13 +2931,15 @@ TclStringCatObjv( first = last; } } - length += numChars; + if ((length += numChars) < 0) { + break; /* overflow */ + } } } } else { /* Result will be concat of string reps. Pre-size it. */ ov = objv; oc = objc; - while (oc-- && (length >= 0)) { + while (oc--) { int numBytes; objPtr = *ov++; @@ -2946,11 +2950,19 @@ TclStringCatObjv( if (length == 0) { first = last; } + if ((length += numBytes) < 0) { + break; /* overflow */ + } } - length += numBytes; } } + if (last == first || length == 0) { + /* Only one non-empty value or zero length; return first */ + *objPtrPtr = objv[first]; + return TCL_OK; + } + if (length < 0) { if (interp) { Tcl_SetObjResult(interp, Tcl_ObjPrintf( @@ -2960,17 +2972,6 @@ TclStringCatObjv( return TCL_ERROR; } - if (length == 0) { - /* Total length of zero means every value has length zero */ - *objPtrPtr = objv[0]; - return TCL_OK; - } - if (last == first) { - /* Only one non-empty value; return it */ - *objPtrPtr = objv[first]; - return TCL_OK; - } - objv += first; objc = (last - first + 1); if (binary) { -- cgit v0.12 From 7edce7686e817824758808dfba651a68c00558dd Mon Sep 17 00:00:00 2001 From: sebres Date: Tue, 6 Jun 2017 09:01:18 +0000 Subject: amend to [eac4656f1e8cf793] (moved to scope where numChars != 0 in Unicode case) --- generic/tclStringObj.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/generic/tclStringObj.c b/generic/tclStringObj.c index c1c15f2..6332e9f 100644 --- a/generic/tclStringObj.c +++ b/generic/tclStringObj.c @@ -2930,9 +2930,9 @@ TclStringCatObjv( if (length == 0) { first = last; } - } - if ((length += numChars) < 0) { - break; /* overflow */ + if ((length += numChars) < 0) { + break; /* overflow */ + } } } } -- cgit v0.12 From 615771f0b6f577cc8f23a668314bdf5cd8309a59 Mon Sep 17 00:00:00 2001 From: sebres Date: Tue, 6 Jun 2017 09:25:00 +0000 Subject: makes TclStringCatObjv safe accepting objc = 0 (or 1), then fast exits with new object / first; check-cycles rewritten to be still more faster. --- generic/tclStringObj.c | 28 ++++++++++++++++------------ 1 file changed, 16 insertions(+), 12 deletions(-) diff --git a/generic/tclStringObj.c b/generic/tclStringObj.c index 6332e9f..b78394e 100644 --- a/generic/tclStringObj.c +++ b/generic/tclStringObj.c @@ -2851,7 +2851,11 @@ TclStringCatObjv( int oc, length = 0, binary = 1, first = 0, last = 0; int allowUniChar = 1, requestUniChar = 0; - /* assert (objc >= 2) */ + if (objc <= 1) { + /* Only one or no objects; return first or empty */ + *objPtrPtr = objc ? objv[0] : Tcl_NewObj(); + return TCL_OK; + } /* * Analyze to determine what representation result should be. @@ -2861,7 +2865,7 @@ TclStringCatObjv( */ ov = objv, oc = objc; - while (oc-- && (binary || allowUniChar)) { + do { objPtr = *ov++; if (objPtr->bytes) { @@ -2892,12 +2896,12 @@ TclStringCatObjv( } } } - } + } while (--oc && (binary || allowUniChar)); if (binary) { /* Result will be pure byte array. Pre-size it */ ov = objv; oc = objc; - while (oc--) { + do { objPtr = *ov++; if (objPtr->bytes == NULL) { @@ -2905,7 +2909,7 @@ TclStringCatObjv( Tcl_GetByteArrayFromObj(objPtr, &numBytes); /* PANIC? */ if (numBytes) { - last = objc - oc - 1; + last = objc - oc; if (length == 0) { first = last; } @@ -2914,11 +2918,11 @@ TclStringCatObjv( } } } - } + } while (--oc); } else if (allowUniChar && requestUniChar) { /* Result will be pure Tcl_UniChar array. Pre-size it. */ ov = objv; oc = objc; - while (oc--) { + do { objPtr = *ov++; if ((objPtr->bytes == NULL) || (objPtr->length)) { @@ -2926,7 +2930,7 @@ TclStringCatObjv( Tcl_GetUnicodeFromObj(objPtr, &numChars); /* PANIC? */ if (numChars) { - last = objc - oc - 1; + last = objc - oc; if (length == 0) { first = last; } @@ -2935,18 +2939,18 @@ TclStringCatObjv( } } } - } + } while (--oc); } else { /* Result will be concat of string reps. Pre-size it. */ ov = objv; oc = objc; - while (oc--) { + do { int numBytes; objPtr = *ov++; Tcl_GetStringFromObj(objPtr, &numBytes); /* PANIC? */ if (numBytes) { - last = objc - oc - 1; + last = objc - oc; if (length == 0) { first = last; } @@ -2954,7 +2958,7 @@ TclStringCatObjv( break; /* overflow */ } } - } + } while (--oc); } if (last == first || length == 0) { -- cgit v0.12 From b0146fbd504c02b6561813c75835ac8333f22805 Mon Sep 17 00:00:00 2001 From: dgp Date: Tue, 6 Jun 2017 12:56:37 +0000 Subject: A few more tweaks to streamline and clarify. --- generic/tclStringObj.c | 30 +++++++++++++++++------------- 1 file changed, 17 insertions(+), 13 deletions(-) diff --git a/generic/tclStringObj.c b/generic/tclStringObj.c index b78394e..aae52ba 100644 --- a/generic/tclStringObj.c +++ b/generic/tclStringObj.c @@ -2851,12 +2851,16 @@ TclStringCatObjv( int oc, length = 0, binary = 1, first = 0, last = 0; int allowUniChar = 1, requestUniChar = 0; + /* assert ( objc >= 0 ) */ + if (objc <= 1) { /* Only one or no objects; return first or empty */ *objPtrPtr = objc ? objv[0] : Tcl_NewObj(); return TCL_OK; } + /* assert ( objc >= 2 ) */ + /* * Analyze to determine what representation result should be. * GOALS: Avoid shimmering & string rep generation. @@ -2914,7 +2918,7 @@ TclStringCatObjv( first = last; } if ((length += numBytes) < 0) { - break; /* overflow */ + goto overflow; } } } @@ -2935,7 +2939,7 @@ TclStringCatObjv( first = last; } if ((length += numChars) < 0) { - break; /* overflow */ + goto overflow; } } } @@ -2955,27 +2959,19 @@ TclStringCatObjv( first = last; } if ((length += numBytes) < 0) { - break; /* overflow */ + goto overflow; } } } while (--oc); } - if (last == first || length == 0) { + if (last == first /*|| length == 0 */) { /* Only one non-empty value or zero length; return first */ + /* NOTE: (length == 0) implies (last == first) */ *objPtrPtr = objv[first]; return TCL_OK; } - if (length < 0) { - 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 TCL_ERROR; - } - objv += first; objc = (last - first + 1); if (binary) { @@ -3106,6 +3102,14 @@ TclStringCatObjv( } *objPtrPtr = objResultPtr; return TCL_OK; + + overflow: + 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 TCL_ERROR; } /* -- cgit v0.12 From 0aa0da515cfab250658ae8010baea869bb889595 Mon Sep 17 00:00:00 2001 From: "jan.nijtmans" Date: Tue, 6 Jun 2017 14:33:16 +0000 Subject: Add more test-cases for UTF-8 parser, including test-cases for TCL_UTF_MAX=4 or TCL_UTF_MAX=6 --- tests/encoding.test | 20 +++++++++++++------- tests/string.test | 18 +++++++++++------- tests/utf.test | 38 ++++++++++++++++++++++++++++++++------ 3 files changed, 56 insertions(+), 20 deletions(-) diff --git a/tests/encoding.test b/tests/encoding.test index a359f76..5b3c3e1 100644 --- a/tests/encoding.test +++ b/tests/encoding.test @@ -34,6 +34,7 @@ proc runtests {} { # Some tests require the testencoding command testConstraint testencoding [llength [info commands testencoding]] +testConstraint fullutf [expr {[format %c 0x010000] != "\ufffd"}] testConstraint exec [llength [info commands exec]] testConstraint testgetdefenc [llength [info commands testgetdefenc]] @@ -73,7 +74,7 @@ test encoding-2.2 {Tcl_FreeEncoding: refcount != 0} -setup { } -constraints {testencoding} -body { encoding system shiftjis ;# incr ref count encoding dirs [list [pwd]] - set x [encoding convertto shiftjis \u4e4e] ;# old one found + set x [encoding convertto shiftjis \u4e4e] ;# old one found encoding system identity llength shiftjis ;# Shimmer away any cache of Tcl_Encoding lappend x [catch {encoding convertto shiftjis \u4e4e} msg] $msg @@ -182,7 +183,7 @@ test encoding-8.1 {Tcl_ExternalToUtf} { puts -nonewline $f "ab\x8c\xc1g" close $f set f [open [file join [temporaryDirectory] dummy] r] - fconfigure $f -translation binary -encoding shiftjis + fconfigure $f -translation binary -encoding shiftjis set x [read $f] close $f file delete [file join [temporaryDirectory] dummy] @@ -265,7 +266,7 @@ test encoding-11.6 {LoadEncodingFile: invalid file} -constraints {testencoding} makeDirectory tmp makeDirectory [file join tmp encoding] set f [open [file join tmp encoding splat.enc] w] - fconfigure $f -translation binary + fconfigure $f -translation binary puts $f "abcdefghijklmnop" close $f encoding convertto splat \u4e4e @@ -286,11 +287,11 @@ test encoding-12.1 {LoadTableEncoding: normal encoding} { append x [encoding convertfrom iso8859-3 \xd5] } "\xd5?\u120" test encoding-12.2 {LoadTableEncoding: single-byte encoding} { - set x [encoding convertto iso8859-3 ab\u0120g] + set x [encoding convertto iso8859-3 ab\u0120g] append x [encoding convertfrom iso8859-3 ab\xd5g] } "ab\xd5gab\u120g" test encoding-12.3 {LoadTableEncoding: multi-byte encoding} { - set x [encoding convertto shiftjis ab\u4e4eg] + set x [encoding convertto shiftjis ab\u4e4eg] append x [encoding convertfrom shiftjis ab\x8c\xc1g] } "ab\x8c\xc1gab\u4e4eg" test encoding-12.4 {LoadTableEncoding: double-byte encoding} { @@ -332,9 +333,14 @@ test encoding-16.1 {UnicodeToUtfProc} { set val [encoding convertfrom unicode NN] list $val [format %x [scan $val %c]] } "\u4e4e 4e4e" +test encoding-16.2 {UnicodeToUtfProc} -constraints fullutf -body { + set val [encoding convertfrom unicode "\xd8\xd8\xdc\xdc"] + list $val [format %x [scan $val %c]] +} -result "\U460dc 460dc" -test encoding-17.1 {UtfToUnicodeProc} { -} {} +test encoding-17.1 {UtfToUnicodeProc} -constraints fullutf -body { + encoding convertto unicode "\U460dc" +} -result "\xd8\xd8\xdc\xdc" test encoding-18.1 {TableToUtfProc} { } {} diff --git a/tests/string.test b/tests/string.test index 3611753..cc65e67 100644 --- a/tests/string.test +++ b/tests/string.test @@ -219,7 +219,7 @@ test string-4.14 {string first, negative start index} { } 1 test string-4.15 {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] + # 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 @@ -419,7 +419,7 @@ test string-6.37 {string is double, false on int overflow} -setup { } -result {1 priorValue} # string-6.38 removed, underflow on input is no longer an error. test string-6.39 {string is double, false} { - # This test is non-portable because IRIX thinks + # 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 # @@ -576,12 +576,12 @@ test string-6.85 {string is control} { } 0 test string-6.86 {string is graph} { ## graph is any print char, except space - list [string is gra -fail var "0123abc!@#\$\u0100 "] $var -} {0 12} + list [string is gra -fail var "0123abc!@#\$\u0100\UE0100\UE01EF "] $var +} {0 14} test string-6.87 {string is print} { ## basically any printable char - list [string is print -fail var "0123abc!@#\$\u0100 \u0010"] $var -} {0 13} + list [string is print -fail var "0123abc!@#\$\u0100 \UE0100\UE01EF\u0010"] $var +} {0 15} test string-6.88 {string is punct} { ## any graph char that isn't alnum list [string is punct -fail var "_!@#\u00beq0"] $var @@ -901,6 +901,10 @@ test string-10.20 {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] } {XY XY 2 XY} +test string-10.20.1 {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] +} {ZZZ XXX 2 XXX} test string-10.21 {string map, ABR checks} { string map {longstring foob} long } long @@ -1833,7 +1837,7 @@ proc MemStress {args} { set res {} foreach body $args { set end 0 - for {set i 0} {$i < 5} {incr i} { + for {set i 0} {$i < 5} {incr i} { proc MemStress_Body {} $body uplevel 1 MemStress_Body rename MemStress_Body {} diff --git a/tests/utf.test b/tests/utf.test index a03dd6c..28981d6 100644 --- a/tests/utf.test +++ b/tests/utf.test @@ -20,6 +20,9 @@ testConstraint testbytestring [llength [info commands testbytestring]] catch {unset x} +# Some tests require support for 4-byte UTF-8 sequences +testConstraint fullutf [expr {[format %c 0x010000] != "\ufffd"}] + test utf-1.1 {Tcl_UniCharToUtf: 1 byte sequences} testbytestring { expr {"\x01" eq [testbytestring "\x01"]} } 1 @@ -38,6 +41,9 @@ test utf-1.5 {Tcl_UniCharToUtf: overflowed Tcl_UniChar} testbytestring { test utf-1.6 {Tcl_UniCharToUtf: negative Tcl_UniChar} testbytestring { expr {[format %c -1] eq [testbytestring "\xef\xbf\xbd"]} } 1 +test utf-1.7 {Tcl_UniCharToUtf: 4 byte sequences} -constraints {fullutf testbytestring} -body { + expr {"\U014e4e" eq [testbytestring "\xf0\x94\xb9\x8e"]} +} -result 1 test utf-2.1 {Tcl_UtfToUniChar: low ascii} { string length "abc" @@ -60,9 +66,21 @@ test utf-2.6 {Tcl_UtfToUniChar: lead (3-byte) followed by 1 trail} testbytestrin test utf-2.7 {Tcl_UtfToUniChar: lead (3-byte) followed by 2 trail} testbytestring { string length [testbytestring "\xE4\xb9\x8e"] } {1} -test utf-2.8 {Tcl_UtfToUniChar: longer UTF sequences not supported} testbytestring { - string length [testbytestring "\xF4\xA2\xA2\xA2"] +test utf-2.8 {Tcl_UtfToUniChar: lead (4-byte) followed by 3 trail} -constraints {fullutf testbytestring} -body { + string length [testbytestring "\xF0\x90\x80\x80"] +} -result {1} +test utf-2.9 {Tcl_UtfToUniChar: lead (4-byte) followed by 3 trail} -constraints {fullutf testbytestring} -body { + string length [testbytestring "\xF4\x8F\xBF\xBF"] +} -result {1} +test utf-2.10 {Tcl_UtfToUniChar: lead (4-byte) followed by 3 trail, underflow} testbytestring { + string length [testbytestring "\xF0\x8F\xBF\xBF"] +} {4} +test utf-2.11 {Tcl_UtfToUniChar: lead (4-byte) followed by 3 trail, overflow} testbytestring { + string length [testbytestring "\xF4\x90\x80\x80"] } {4} +test utf-2.12 {Tcl_UtfToUniChar: longer UTF sequences not supported} testbytestring { + string length [testbytestring "\xF8\xA2\xA2\xA2\xA2"] +} {5} test utf-3.1 {Tcl_UtfCharComplete} { } {} @@ -195,8 +213,16 @@ bsCheck \Ua1 161 bsCheck \U4e21 20001 bsCheck \U004e21 20001 bsCheck \U00004e21 20001 -bsCheck \U00110000 65533 -bsCheck \Uffffffff 65533 +bsCheck \U0000004e21 78 +if {[testConstraint fullutf]} { + bsCheck \U00110000 69632 + bsCheck \U01100000 69632 + bsCheck \U11000000 69632 + bsCheck \U0010FFFF 1114111 + bsCheck \U010FFFF0 1114111 + bsCheck \U10FFFF00 1114111 + bsCheck \UFFFFFFFF 1048575 +} test utf-11.1 {Tcl_UtfToUpper} { string toupper {} @@ -264,8 +290,8 @@ test utf-16.1 {Tcl_UniCharToLower, negative delta} { string tolower aA } aa test utf-16.2 {Tcl_UniCharToLower, positive delta} { - string tolower \u0178\u00ff\uA78D\u01c5 -} \u00ff\u00ff\u0265\u01c6 + string tolower \u0178\u00ff\uA78D\u01c5\U10400 +} \u00ff\u00ff\u0265\u01c6\U10428 test utf-17.1 {Tcl_UniCharToLower, no delta} { string tolower ! -- cgit v0.12 From 4cf238f3c3fd4ef9aed542f0f5f55a4dff225cd9 Mon Sep 17 00:00:00 2001 From: dkf Date: Tue, 6 Jun 2017 17:51:12 +0000 Subject: Expose some of the core variable access APIs. (Cherrypick from [b4dfc30083]) --- generic/tclDictObj.c | 6 +- generic/tclExecute.c | 45 +++++---- generic/tclInt.decls | 26 +++++ generic/tclInt.h | 13 +-- generic/tclIntDecls.h | 37 +++++++ generic/tclStubInit.c | 5 + generic/tclVar.c | 275 +++++++++++++++++++++++++++++++++++++++++++++----- 7 files changed, 349 insertions(+), 58 deletions(-) diff --git a/generic/tclDictObj.c b/generic/tclDictObj.c index 87fb333..d15255f 100644 --- a/generic/tclDictObj.c +++ b/generic/tclDictObj.c @@ -3535,7 +3535,7 @@ TclDictWithFinish( * If the dictionary variable doesn't exist, drop everything silently.