Tcl Source Code

Check-in [ad3f046675]
Login
Bounty program for improvements to Tcl and certain Tcl packages.
Tcl 2019 Conference, Houston/TX, US, Nov 4-8
Send your abstracts to [email protected]
or submit via the online form by Sep 9.

Many hyperlinks are disabled.
Use anonymous login to enable hyperlinks.

Overview
Comment:merge 8.7
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | bg-tip-282
Files: files | file ages | folders
SHA3-256: ad3f0466752f5658919286c144cd5b7042e26f001db3b3ff4c78cafb585a19a5
User & Date: dgp 2018-03-15 13:49:57
Context
2018-03-15
13:49
merge 8.7 Leaf check-in: ad3f046675 user: dgp tags: bg-tip-282
11:08
merge 8.6 check-in: ff4b8f1a06 user: dgp tags: core-8-branch
2017-02-27
15:19
merge trunk check-in: 5fb0e5ebc8 user: dgp tags: bg-tip-282
Changes
Hide Diffs Side-by-Side Diffs Ignore Whitespace Patch

Added .fossil-settings/crlf-glob.

            1  +compat/zlib/contrib/dotzlib/DotZLib/UnitTests.cs
            2  +compat/zlib/contrib/vstudio/readme.txt
            3  +compat/zlib/contrib/vstudio/*/zlib.rc
            4  +compat/zlib/win32/*.txt
            5  +compat/zlib/win64/*.txt
            6  +libtommath/*.dsp
            7  +libtommath/*.sln
            8  +libtommath/*.vcproj
            9  +tools/tcl.hpj.in
           10  +tools/tcl.wse.in
           11  +win/buildall.vc.bat
           12  +win/coffbase.txt
           13  +win/makefile.vc
           14  +win/rules.vc
           15  +win/rules-ext.vc
           16  +win/targets.vc
           17  +win/tcl.dsp
           18  +win/tcl.dsw
           19  +win/tcl.hpj.in

Changes to .fossil-settings/crnl-glob.

     1      1   compat/zlib/contrib/dotzlib/DotZLib/UnitTests.cs
     2      2   compat/zlib/contrib/vstudio/readme.txt
     3      3   compat/zlib/contrib/vstudio/*/zlib.rc
     4      4   compat/zlib/win32/*.txt
     5      5   compat/zlib/win64/*.txt
            6  +libtommath/*.dsp
            7  +libtommath/*.sln
            8  +libtommath/*.vcproj
     6      9   tools/tcl.hpj.in
     7     10   tools/tcl.wse.in
     8     11   win/buildall.vc.bat
     9     12   win/coffbase.txt
    10         -win/makefile.bc
    11     13   win/makefile.vc
    12     14   win/rules.vc
           15  +win/rules-ext.vc
           16  +win/targets.vc
    13     17   win/tcl.dsp
    14     18   win/tcl.dsw
    15     19   win/tcl.hpj.in

Changes to .fossil-settings/encoding-glob.

     1      1   tools/tcl.hpj.in
     2      2   tools/tcl.wse.in
     3      3   win/buildall.vc.bat
     4      4   win/coffbase.txt
     5         -win/makefile.bc
     6      5   win/makefile.vc
     7      6   win/rules.vc
     8      7   win/tcl.dsp
     9      8   win/tcl.dsw
    10      9   win/tcl.hpj.in

Changes to .fossil-settings/ignore-glob.

    14     14   */config.cache
    15     15   */config.log
    16     16   */config.status
    17     17   */tclConfig.sh
    18     18   */tclsh*
    19     19   */tcltest*
    20     20   */versions.vc
           21  +*/version.vc
    21     22   html
    22     23   libtommath/bn.ilg
    23     24   libtommath/bn.ind
    24     25   libtommath/pretty.build
    25     26   libtommath/tommath.src
    26     27   libtommath/*.pdf
    27     28   libtommath/*.pl
................................................................................
    36     37   libtommath/*.out
    37     38   libtommath/*.tex
    38     39   unix/autoMkindex.tcl
    39     40   unix/dltest.marker
    40     41   unix/tcl.pc
    41     42   unix/tclIndex
    42     43   unix/pkgs/*
    43         -win/Debug_VC*
    44         -win/Release_VC*
           44  +win/Debug*
           45  +win/Release*
    45     46   win/pkgs/*
           47  +win/coffbase.txt
    46     48   win/tcl.hpj
           49  +win/nmhlp-out.txt

Changes to .project.

     1      1   <?xml version="1.0" encoding="UTF-8"?>
     2      2   <projectDescription>
     3         -	<name>tcl8.7</name>
            3  +	<name>tcl8</name>
     4      4   	<comment></comment>
     5      5   	<projects>
     6      6   	</projects>
     7      7   	<buildSpec>
     8      8   	</buildSpec>
     9      9   	<natures>
    10     10   	</natures>
    11     11   </projectDescription>

Changes to README.

     1      1   README:  Tcl
     2         -    This is the Tcl 8.7a0 source distribution.
            2  +    This is the Tcl 8.7a2 source distribution.
     3      3   	http://sourceforge.net/projects/tcl/files/Tcl/
     4      4       You can get any source release of Tcl from the URL above.
     5      5   
     6      6   Contents
     7      7   --------
     8      8       1. Introduction
     9      9       2. Documentation

Changes to changes.

  8620   8620   2016-02-03 (bug)[25842c] stream [zlib deflate] fails with 0 input (ade,fellows)
  8621   8621   
  8622   8622   2016-02-04 (bug)[3d96b7][593baa][cf74de] crashes in OO teardown (porter,fellows)
  8623   8623   
  8624   8624   2016-02-22 (bug)[9b4702] [info exists env(missing)] kills trace (nijtmans)
  8625   8625   
  8626   8626   --- Released 8.6.5, February 29, 2016 --- http://core.tcl.tk/tcl/ for details
         8627  +
         8628  +2016-03-01 (bug)[803042] mem leak due to reference cycle (porter)
         8629  +
         8630  +2016-03-08 (bug)[bbc304] reflected watch race condition (porter)
         8631  +
         8632  +2016-03-17 (bug)[fadc99] compile-5.3 (rodriguez,porter)
         8633  +
         8634  +2016-03-17 (enhancement)[1a25fd] compile [variable ${ns}::v] (porter)
         8635  +
         8636  +2016-03-20 (bug)[1af8de] crash in compiled [string replace] (harder,fellows)
         8637  +
         8638  +2016-03-21 (bug)[d30718] segv in notifier finalize (hirofumi,nijtmans)
         8639  +
         8640  +2016-03-23 (enhancement)[7d0db7] parallel make (yarda,nijtmans)
         8641  +
         8642  +2016-03-23 [f12535] enable test bindings customization (vogel,nijtmans)
         8643  +
         8644  +2016-04-04 (bug)[47ac84] compiled [lreplace] fixes (aspect,ferrieux,fellows)
         8645  +        *** POTENTIAL INCOMPATIBILITY ***
         8646  +
         8647  +2016-04-08 (bug)[866368] RE \w includes 'Punctuation Connector' (nijtmans)
         8648  +
         8649  +2016-04-08 (bug)[2538f3] Win crash Tcl_OpenTcpServer() (griffin)
         8650  +
         8651  +2016-04-10 [07d13d] Restore TclBlend support lost in 8.6.1 (buratti)
         8652  +
         8653  +2016-05-13 (bug)[3154ea] Mem corruption in assembler exceptions (tkob,kenny)
         8654  +
         8655  +2016-05-13 (bug) registry package support any Unicode env (nijtmans)
         8656  +=> registry 1.3.2
         8657  +
         8658  +2016-05-21 (bug)[f7d4e] [namespace delete] performance (fellows)
         8659  +
         8660  +2016-06-02 (TIP 447) execution time verbosity option (cerutti)
         8661  +=> tcltest 2.4.0
         8662  +
         8663  +2016-06-16 (bug)[16828b] crash due to [vwait] trace undo fail (dah,porter)
         8664  +
         8665  +2016-06-16 (enhancement)[4b61af] good [info frame] from more cases (beric)
         8666  +
         8667  +2016-06-21 (bug)[c383eb] crash in [glob -path a] (oehlmann,porter)
         8668  +
         8669  +2016-06-21 (update) Update Unicode data to 9.0 (nijtmans)
         8670  +        *** POTENTIAL INCOMPATIBILITY ***
         8671  +
         8672  +2016-06-22 (bug)[16896d] Tcl_DString tolerate append to self. (dah,porter)
         8673  +
         8674  +2016-06-23 (bug)[d55322] crash in [dict update] (yorick,fellows)
         8675  +
         8676  +2016-06-27 (bug)[dd260a] crash in [chan configure -dictionary] (madden,aspect)
         8677  +
         8678  +2016-07-02 (bug)[f961d7] usage message with parameters with spaces (porter)
         8679  +        *** POTENTIAL INCOMPATIBILITY ***
         8680  +
         8681  +2016-07-02 (enhancement)[09fabc] Sort order of -relateddir (lanam)
         8682  +
         8683  +2016-07-07 (bug)[5d7ca0] Win: [file executable] for .cmd and .ps1 (nadkarni)
         8684  +        *** POTENTIAL INCOMPATIBILITY ***
         8685  +
         8686  +2016-07-08 (bug)[a47641] [file normalize] & Windows junctions (nadkarni)
         8687  +
         8688  +2016-07-09 [ae61a6] [file] handling of Win hardcoded names (CON) (nadkarni)
         8689  +        *** POTENTIAL INCOMPATIBILITY ***
         8690  +
         8691  +2016-07-09 [3613671] [file owned] (more) useful on Win (nadkarni)
         8692  +
         8693  +2016-07-09 (bug)[1493a4] [namespace upvar] use of resolvers (beric,fellows)
         8694  +        *** POTENTIAL INCOMPATIBILITY ***
         8695  +
         8696  +2016-07-10 (bug)[da340d] integer division in clock math (nadkarni)
         8697  +
         8698  +2016-07-20 tzdata updated to Olson's tzdata2016f (venkat)
         8699  +
         8700  +--- Released 8.6.6, July 27, 2016 --- http://core.tcl.tk/tcl/ for details
         8701  +
         8702  +2016-09-07 (bug)[c09edf] Bad caching with  custom resolver (neumann,nijtmans)
         8703  +
         8704  +2016-09-07 (bug)[4dbdd9] Memleak in test var-8.3 (mr_calvin,porter)
         8705  +
         8706  +2016-10-03 (bug)[2bf561] Allow empty command as alias target (yorick,nijtmans)
         8707  +        *** POTENTIAL INCOMPATIBILITY ***
         8708  +
         8709  +2016-10-04 (bug)[4d5ae7] Crash in async connects host no address (gahr,fellows)
         8710  +
         8711  +2016-10-08 (bug)[838e99] treat application/xml as text (gahr,fellows)
         8712  +=> http 2.8.10
         8713  +
         8714  +2016-10-11 (bug)[3cc1d9] Thread finalization crash in zippy (neumann)
         8715  +
         8716  +2016-10-12 (bug)[be003d] Fix [scan 0x1 %b], [scan 0x1 %o] (porter)
         8717  +
         8718  +2016-10-14 (bug)[eb6b68] Fix stringComp-14.5 (porter)
         8719  +
         8720  +2016-10-30 (bug)[b26e38] Fix zlib-7.8 (fellows)
         8721  +
         8722  +2016-10-30 (bug)[1ae129] Fix memleak in [history] destruction (fellows)
         8723  +
         8724  +2016-11-04 (feature) Provisional Tcl 9 support in msgcat and tcltest (nijtmans)
         8725  +=> msgcat 1.6.1
         8726  +=> tcltest 2.4.1
         8727  +
         8728  +2016-11-04 (bug)[824752] Crash in Tcl_ListObjReplace() (gahr,porter)
         8729  +
         8730  +2016-11-11 (bug)[79614f] invalidate VFS mounts on sytem encoding change (yorick)
         8731  +
         8732  +2016-11-14 OSX: End panic() as legacy support macro; system conflicts (nijtmans)
         8733  +        *** POTENTIAL INCOMPATIBILITY ***
         8734  +
         8735  +2016-11-15 (bug) TclOO fix stops crash mixing Itcl and snit (fellows)
         8736  +
         8737  +2016-11-17 (update) Reconcile libtommath updates; purge unused files (nijtmans)
         8738  +        *** POTENTIAL INCOMPATIBILITY ***
         8739  +
         8740  +2017-01-09 (bug)[b87ad7] Repair drifts in timer clock (sebres)
         8741  +
         8742  +2017-01-17 (update) => zlib 1.2.11 (nijtmans)
         8743  +
         8744  +2017-01-31 (bug)[39f630] Revise Tcl_LinkVar to tolerate some prefixes (nijtmans)
         8745  +        *** POTENTIAL INCOMPATIBILITY ***
         8746  +
         8747  +2017-02-01 (bug)[d0f7ba] Improper NAN optimization. expr-22.1[01] (aspect)
         8748  +
         8749  +2017-02-26 (bug)[25842c] zlib stream finalization (aspect)
         8750  +
         8751  +2017-03-07 (deprecate) Remove unmaintained makefile.bc file (nijtmans)
         8752  +        *** POTENTIAL INCOMPATIBILITY ***
         8753  +
         8754  +2017-03-14 (enhancement) [clock] and [encoding] are now ensembles (kenny)
         8755  +
         8756  +2017-03-15 (enhancement) several [clock] subcommands bytecoded (kenny)
         8757  +
         8758  +2017-03-23 tzdata updated to Olson's tzdata2017b (jima)
         8759  +
         8760  +2017-03-29 (bug)[900cb0] Fix OO unexport introspection (napier)
         8761  +
         8762  +2017-04-12 (bug)[42202b] Nesting imbalance in coro injection (nadkarni,sebres)
         8763  +
         8764  +2017-04-18 (bug)[bc4322] http package support for safe interps (nash,nijtmans)
         8765  +
         8766  +2017-04-28 (bug)[f34cf8] [file join a //b] => /b (neumann,porter)
         8767  +
         8768  +2017-05-01 (bug)[8bd13f] Windows threads and pipes (sebres,nijtmans)
         8769  +
         8770  +2017-05-01 (bug)[f9fe90] [file join //a b] EIAS violation (aspect,porter)
         8771  +
         8772  +2017-05-04 (bug) Make test filesystem-1.52 pass on Windows (nijtmans)
         8773  +
         8774  +2017-05-05 (bug)[601522] [binary] field spec overflow -> segfault (porter)
         8775  +
         8776  +2017-05-08 (bug)[6ca52a] http memleak handling keep-alive (aspect,nijtmans)
         8777  +=> http 2.8.11
         8778  +
         8779  +2017-05-29 (bug)[a3fb33] crash in [lsort] on long lists (sebres)
         8780  +
         8781  +2017-06-05 (bug)[67aa9a] Tcl_UtfToUniChar() revised handling invalid UTF-8 (nijtmans)
         8782  +        *** POTENTIAL INCOMPATIBILITY ***
         8783  +
         8784  +2017-06-08 (bug)[2738427] Tcl_NumUtfChars() corner case utf-4.9 (nijtmans)
         8785  +
         8786  +2017-06-22 (update) Update Unicode data to 10.0 (nijtmans)
         8787  +        *** POTENTIAL INCOMPATIBILITY ***
         8788  +
         8789  +2017-06-22 (TIP 473) Let [oo::copy] specify target namespace (fellows)
         8790  +
         8791  +2017-06-26 (bug)[46f801] Repair autoloader fragility (porter)
         8792  +
         8793  +2017-07-06 (bug)[adb198] Plug memleak in TclJoinPath (sebres,porter)
         8794  +
         8795  +2017-07-17 (bug)[fb2208] Repeatable tclIndex generation (wiedemann,nijtmans)
         8796  +
         8797  +--- Released 8.6.7, August 9, 2017 --- http://core.tcl.tk/tcl/ for details
         8798  +
         8799  +2017-08-10 [array names -regexp] supports backrefs (goth)
         8800  +
         8801  +2017-08-10 Fix gcc build failures due to #pragma placement (cassoff,fellows)
         8802  +
         8803  +2017-08-29 (bug)[b50fb2] exec redir append stdout and stderr to file (coulter)
         8804  +
         8805  +2017-08-31 (bug)[2a9465] http state 100 continue handling broken (oehlmann)
         8806  +=> http 2.8.12
         8807  +
         8808  +2017-09-02 (bug)[0e4d88] replace command, delete trace kills namespace (porter)
         8809  +
         8810  +2017-10-19 (bug)[1a5655] [info * methods] includes mixins (fellows)
         8811  +
         8812  +2017-10-23 tzdata updated to Olson's tzdata2017c (jima)
         8813  +
         8814  +2017-10-24 (bug)[fc1409] segfault in method cloning, oo-15.15 (coulter,fellows)
         8815  +
         8816  +2017-11-03 (bug)[6f2f83] More robust [load] for ReactOS (werner)
         8817  +
         8818  +2017-11-08 (bug)[3298012] Stop crash when hash tables overflow 32 bits (porter)
         8819  +
         8820  +2017-11-14 (bug)[5d6de6] Close failing case of [package prefer stable] (kupries)
         8821  +
         8822  +2017-11-17 (bug)[fab924] Fix misleading [load] message on Windows (oehlmann)
         8823  +
         8824  +2017-12-05 (bug)[4f6a1e] Crash when ensemble map and list are same (sebres)
         8825  +
         8826  +2017-12-06 (bug)[ce3a21] file normalize failure when tail is empty (porter)
         8827  +
         8828  +2017-12-08 (new)[TIP 477] nmake build system reform (nadkarni)
         8829  +
         8830  +2017-12-19 (bug)[586e71] EvalObjv exception handling at level #0 (sebres,porter)
         8831  +
         8832  +--- Released 8.6.8, December 22, 2017 --- http://core.tcl.tk/tcl/ for details
         8833  +
         8834  +Changes to 8.7a1 include all changes to the 8.6 line through 8.6.7,
         8835  +plus the following, which focuses on the high-level feature changes
         8836  +in this changeset (new minor version) rather than bug fixes:
         8837  +
         8838  +2016-03-17 (bug)[0b8c38] socket accept callbacks always in global ns (porter)
         8839  +        *** POTENTIAL INCOMPATIBILITY ***
         8840  +
         8841  +2016-07-01 Hack accommodations for legacy Itcl 3 disabled (porter)
         8842  +
         8843  +2016-07-12 Make TCL_HASH_TYPE build-time configurable (nijtmans)
         8844  +
         8845  +2016-07-19 (bug)[0363f0] Partial array search ID reform (porter)
         8846  +
         8847  +2016-07-19 (feature removed) Tcl_ObjType "array search" unregistered (porter)
         8848  +	*** POTENTIAL INCOMPATIBILITY for Tcl_GetObjType("array search") ***
         8849  +
         8850  +2016-10-04 Server socket on port 0 chooses port supporting IPv4 * IPv6 (max)
         8851  +
         8852  +2016-11-25 [array named -regexp] supports backrefs (goth)
         8853  +
         8854  +2017-01-04 (TIP 456) New routine Tcl_OpenTcpServerEx() (limeboy)
         8855  +
         8856  +2017-01-04 (TIP 459) New subcommand [package files] (nijtmans)
         8857  +
         8858  +2017-01-16 threaded allocator initialization repair (vasiljevic,nijtmans)
         8859  +
         8860  +2017-01-30 Add to Win shell builtins: assoc ftype move (ashok)
         8861  +
         8862  +2017-03-31 TCL_MEM_DEBUG facilities better support 64-bit memory (nijtmans)
         8863  +
         8864  +2017-04-13 \u escaped content in msg files converted to true utf-8 (nijtmans)
         8865  +
         8866  +2017-05-18 (TIP 458) New epoll or kqueue notifiers are default (alborboz)
         8867  +
         8868  +2017-05-31 Purge build support for SunOS-4.* (stu)
         8869  +
         8870  +2017-06-22 (TIP 463) New option [regsub ... -command ...] (fellows)
         8871  +
         8872  +2017-06-22 (TIP 470) Tcl_GetDefineContextObject();[oo::define [self]] (fellows)
         8873  +=> TclOO 1.2.0
         8874  +
         8875  +2017-06-23 (TIP 472) Support 0d as prefix of decimal numbers (iyer,griffin)
         8876  +
         8877  +2017-08-31 (bug)[2a9465] http state 100 continue handling broken (oehlmann)
         8878  +
         8879  +2017-09-02 (bug)[0e4d88] replace command, delete trace kills namespace (porter)
         8880  +
         8881  +--- Released 8.7a1, September 8, 2017 --- http://core.tcl.tk/tcl/ for details
         8882  +
         8883  +2018-03-12 (TIP 490) add oo support for msgcat => msgcat 1.7.0 (oehlmann)
         8884  +
         8885  +2018-03-12 (TIP 499) custom locale preference list (oehlmann)
         8886  +=> msgcat 1.7.0

Deleted compat/float.h.

     1         -/*
     2         - * float.h --
     3         - *
     4         - *	This is a dummy header file to #include in Tcl when there
     5         - *	is no float.h in /usr/include.  Right now this file is empty:
     6         - *	Tcl contains #ifdefs to deal with the lack of definitions;
     7         - *	all it needs is for the #include statement to work.
     8         - *
     9         - * Copyright (c) 1993 The Regents of the University of California.
    10         - * Copyright (c) 1994 Sun Microsystems, Inc.
    11         - *
    12         - * See the file "license.terms" for information on usage and redistribution
    13         - * of this file, and for a DISCLAIMER OF ALL WARRANTIES.
    14         - */

Deleted compat/zlib/doc/algorithm.txt.

     1         -1. Compression algorithm (deflate)
     2         -
     3         -The deflation algorithm used by gzip (also zip and zlib) is a variation of
     4         -LZ77 (Lempel-Ziv 1977, see reference below). It finds duplicated strings in
     5         -the input data.  The second occurrence of a string is replaced by a
     6         -pointer to the previous string, in the form of a pair (distance,
     7         -length).  Distances are limited to 32K bytes, and lengths are limited
     8         -to 258 bytes. When a string does not occur anywhere in the previous
     9         -32K bytes, it is emitted as a sequence of literal bytes.  (In this
    10         -description, `string' must be taken as an arbitrary sequence of bytes,
    11         -and is not restricted to printable characters.)
    12         -
    13         -Literals or match lengths are compressed with one Huffman tree, and
    14         -match distances are compressed with another tree. The trees are stored
    15         -in a compact form at the start of each block. The blocks can have any
    16         -size (except that the compressed data for one block must fit in
    17         -available memory). A block is terminated when deflate() determines that
    18         -it would be useful to start another block with fresh trees. (This is
    19         -somewhat similar to the behavior of LZW-based _compress_.)
    20         -
    21         -Duplicated strings are found using a hash table. All input strings of
    22         -length 3 are inserted in the hash table. A hash index is computed for
    23         -the next 3 bytes. If the hash chain for this index is not empty, all
    24         -strings in the chain are compared with the current input string, and
    25         -the longest match is selected.
    26         -
    27         -The hash chains are searched starting with the most recent strings, to
    28         -favor small distances and thus take advantage of the Huffman encoding.
    29         -The hash chains are singly linked. There are no deletions from the
    30         -hash chains, the algorithm simply discards matches that are too old.
    31         -
    32         -To avoid a worst-case situation, very long hash chains are arbitrarily
    33         -truncated at a certain length, determined by a runtime option (level
    34         -parameter of deflateInit). So deflate() does not always find the longest
    35         -possible match but generally finds a match which is long enough.
    36         -
    37         -deflate() also defers the selection of matches with a lazy evaluation
    38         -mechanism. After a match of length N has been found, deflate() searches for
    39         -a longer match at the next input byte. If a longer match is found, the
    40         -previous match is truncated to a length of one (thus producing a single
    41         -literal byte) and the process of lazy evaluation begins again. Otherwise,
    42         -the original match is kept, and the next match search is attempted only N
    43         -steps later.
    44         -
    45         -The lazy match evaluation is also subject to a runtime parameter. If
    46         -the current match is long enough, deflate() reduces the search for a longer
    47         -match, thus speeding up the whole process. If compression ratio is more
    48         -important than speed, deflate() attempts a complete second search even if
    49         -the first match is already long enough.
    50         -
    51         -The lazy match evaluation is not performed for the fastest compression
    52         -modes (level parameter 1 to 3). For these fast modes, new strings
    53         -are inserted in the hash table only when no match was found, or
    54         -when the match is not too long. This degrades the compression ratio
    55         -but saves time since there are both fewer insertions and fewer searches.
    56         -
    57         -
    58         -2. Decompression algorithm (inflate)
    59         -
    60         -2.1 Introduction
    61         -
    62         -The key question is how to represent a Huffman code (or any prefix code) so
    63         -that you can decode fast.  The most important characteristic is that shorter
    64         -codes are much more common than longer codes, so pay attention to decoding the
    65         -short codes fast, and let the long codes take longer to decode.
    66         -
    67         -inflate() sets up a first level table that covers some number of bits of
    68         -input less than the length of longest code.  It gets that many bits from the
    69         -stream, and looks it up in the table.  The table will tell if the next
    70         -code is that many bits or less and how many, and if it is, it will tell
    71         -the value, else it will point to the next level table for which inflate()
    72         -grabs more bits and tries to decode a longer code.
    73         -
    74         -How many bits to make the first lookup is a tradeoff between the time it
    75         -takes to decode and the time it takes to build the table.  If building the
    76         -table took no time (and if you had infinite memory), then there would only
    77         -be a first level table to cover all the way to the longest code.  However,
    78         -building the table ends up taking a lot longer for more bits since short
    79         -codes are replicated many times in such a table.  What inflate() does is
    80         -simply to make the number of bits in the first table a variable, and  then
    81         -to set that variable for the maximum speed.
    82         -
    83         -For inflate, which has 286 possible codes for the literal/length tree, the size
    84         -of the first table is nine bits.  Also the distance trees have 30 possible
    85         -values, and the size of the first table is six bits.  Note that for each of
    86         -those cases, the table ended up one bit longer than the ``average'' code
    87         -length, i.e. the code length of an approximately flat code which would be a
    88         -little more than eight bits for 286 symbols and a little less than five bits
    89         -for 30 symbols.
    90         -
    91         -
    92         -2.2 More details on the inflate table lookup
    93         -
    94         -Ok, you want to know what this cleverly obfuscated inflate tree actually
    95         -looks like.  You are correct that it's not a Huffman tree.  It is simply a
    96         -lookup table for the first, let's say, nine bits of a Huffman symbol.  The
    97         -symbol could be as short as one bit or as long as 15 bits.  If a particular
    98         -symbol is shorter than nine bits, then that symbol's translation is duplicated
    99         -in all those entries that start with that symbol's bits.  For example, if the
   100         -symbol is four bits, then it's duplicated 32 times in a nine-bit table.  If a
   101         -symbol is nine bits long, it appears in the table once.
   102         -
   103         -If the symbol is longer than nine bits, then that entry in the table points
   104         -to another similar table for the remaining bits.  Again, there are duplicated
   105         -entries as needed.  The idea is that most of the time the symbol will be short
   106         -and there will only be one table look up.  (That's whole idea behind data
   107         -compression in the first place.)  For the less frequent long symbols, there
   108         -will be two lookups.  If you had a compression method with really long
   109         -symbols, you could have as many levels of lookups as is efficient.  For
   110         -inflate, two is enough.
   111         -
   112         -So a table entry either points to another table (in which case nine bits in
   113         -the above example are gobbled), or it contains the translation for the symbol
   114         -and the number of bits to gobble.  Then you start again with the next
   115         -ungobbled bit.
   116         -
   117         -You may wonder: why not just have one lookup table for how ever many bits the
   118         -longest symbol is?  The reason is that if you do that, you end up spending
   119         -more time filling in duplicate symbol entries than you do actually decoding.
   120         -At least for deflate's output that generates new trees every several 10's of
   121         -kbytes.  You can imagine that filling in a 2^15 entry table for a 15-bit code
   122         -would take too long if you're only decoding several thousand symbols.  At the
   123         -other extreme, you could make a new table for every bit in the code.  In fact,
   124         -that's essentially a Huffman tree.  But then you spend too much time
   125         -traversing the tree while decoding, even for short symbols.
   126         -
   127         -So the number of bits for the first lookup table is a trade of the time to
   128         -fill out the table vs. the time spent looking at the second level and above of
   129         -the table.
   130         -
   131         -Here is an example, scaled down:
   132         -
   133         -The code being decoded, with 10 symbols, from 1 to 6 bits long:
   134         -
   135         -A: 0
   136         -B: 10
   137         -C: 1100
   138         -D: 11010
   139         -E: 11011
   140         -F: 11100
   141         -G: 11101
   142         -H: 11110
   143         -I: 111110
   144         -J: 111111
   145         -
   146         -Let's make the first table three bits long (eight entries):
   147         -
   148         -000: A,1
   149         -001: A,1
   150         -010: A,1
   151         -011: A,1
   152         -100: B,2
   153         -101: B,2
   154         -110: -> table X (gobble 3 bits)
   155         -111: -> table Y (gobble 3 bits)
   156         -
   157         -Each entry is what the bits decode as and how many bits that is, i.e. how
   158         -many bits to gobble.  Or the entry points to another table, with the number of
   159         -bits to gobble implicit in the size of the table.
   160         -
   161         -Table X is two bits long since the longest code starting with 110 is five bits
   162         -long:
   163         -
   164         -00: C,1
   165         -01: C,1
   166         -10: D,2
   167         -11: E,2
   168         -
   169         -Table Y is three bits long since the longest code starting with 111 is six
   170         -bits long:
   171         -
   172         -000: F,2
   173         -001: F,2
   174         -010: G,2
   175         -011: G,2
   176         -100: H,2
   177         -101: H,2
   178         -110: I,3
   179         -111: J,3
   180         -
   181         -So what we have here are three tables with a total of 20 entries that had to
   182         -be constructed.  That's compared to 64 entries for a single table.  Or
   183         -compared to 16 entries for a Huffman tree (six two entry tables and one four
   184         -entry table).  Assuming that the code ideally represents the probability of
   185         -the symbols, it takes on the average 1.25 lookups per symbol.  That's compared
   186         -to one lookup for the single table, or 1.66 lookups per symbol for the
   187         -Huffman tree.
   188         -
   189         -There, I think that gives you a picture of what's going on.  For inflate, the
   190         -meaning of a particular symbol is often more than just a letter.  It can be a
   191         -byte (a "literal"), or it can be either a length or a distance which
   192         -indicates a base value and a number of bits to fetch after the code that is
   193         -added to the base value.  Or it might be the special end-of-block code.  The
   194         -data structures created in inftrees.c try to encode all that information
   195         -compactly in the tables.
   196         -
   197         -
   198         -Jean-loup Gailly        Mark Adler
   199         -[email protected]          [email protected]
   200         -
   201         -
   202         -References:
   203         -
   204         -[LZ77] Ziv J., Lempel A., ``A Universal Algorithm for Sequential Data
   205         -Compression,'' IEEE Transactions on Information Theory, Vol. 23, No. 3,
   206         -pp. 337-343.
   207         -
   208         -``DEFLATE Compressed Data Format Specification'' available in
   209         -http://tools.ietf.org/html/rfc1951

Deleted compat/zlib/doc/rfc1950.txt.

     1         -
     2         -
     3         -
     4         -
     5         -
     6         -
     7         -Network Working Group                                         P. Deutsch
     8         -Request for Comments: 1950                           Aladdin Enterprises
     9         -Category: Informational                                      J-L. Gailly
    10         -                                                                Info-ZIP
    11         -                                                                May 1996
    12         -
    13         -
    14         -         ZLIB Compressed Data Format Specification version 3.3
    15         -
    16         -Status of This Memo
    17         -
    18         -   This memo provides information for the Internet community.  This memo
    19         -   does not specify an Internet standard of any kind.  Distribution of
    20         -   this memo is unlimited.
    21         -
    22         -IESG Note:
    23         -
    24         -   The IESG takes no position on the validity of any Intellectual
    25         -   Property Rights statements contained in this document.
    26         -
    27         -Notices
    28         -
    29         -   Copyright (c) 1996 L. Peter Deutsch and Jean-Loup Gailly
    30         -
    31         -   Permission is granted to copy and distribute this document for any
    32         -   purpose and without charge, including translations into other
    33         -   languages and incorporation into compilations, provided that the
    34         -   copyright notice and this notice are preserved, and that any
    35         -   substantive changes or deletions from the original are clearly
    36         -   marked.
    37         -
    38         -   A pointer to the latest version of this and related documentation in
    39         -   HTML format can be found at the URL
    40         -   <ftp://ftp.uu.net/graphics/png/documents/zlib/zdoc-index.html>.
    41         -
    42         -Abstract
    43         -
    44         -   This specification defines a lossless compressed data format.  The
    45         -   data can be produced or consumed, even for an arbitrarily long
    46         -   sequentially presented input data stream, using only an a priori
    47         -   bounded amount of intermediate storage.  The format presently uses
    48         -   the DEFLATE compression method but can be easily extended to use
    49         -   other compression methods.  It can be implemented readily in a manner
    50         -   not covered by patents.  This specification also defines the ADLER-32
    51         -   checksum (an extension and improvement of the Fletcher checksum),
    52         -   used for detection of data corruption, and provides an algorithm for
    53         -   computing it.
    54         -
    55         -
    56         -
    57         -
    58         -Deutsch & Gailly             Informational                      [Page 1]
    59         -
    60         -RFC 1950       ZLIB Compressed Data Format Specification        May 1996
    61         -
    62         -
    63         -Table of Contents
    64         -
    65         -   1. Introduction ................................................... 2
    66         -      1.1. Purpose ................................................... 2
    67         -      1.2. Intended audience ......................................... 3
    68         -      1.3. Scope ..................................................... 3
    69         -      1.4. Compliance ................................................ 3
    70         -      1.5.  Definitions of terms and conventions used ................ 3
    71         -      1.6. Changes from previous versions ............................ 3
    72         -   2. Detailed specification ......................................... 3
    73         -      2.1. Overall conventions ....................................... 3
    74         -      2.2. Data format ............................................... 4
    75         -      2.3. Compliance ................................................ 7
    76         -   3. References ..................................................... 7
    77         -   4. Source code .................................................... 8
    78         -   5. Security Considerations ........................................ 8
    79         -   6. Acknowledgements ............................................... 8
    80         -   7. Authors' Addresses ............................................. 8
    81         -   8. Appendix: Rationale ............................................ 9
    82         -   9. Appendix: Sample code ..........................................10
    83         -
    84         -1. Introduction
    85         -
    86         -   1.1. Purpose
    87         -
    88         -      The purpose of this specification is to define a lossless
    89         -      compressed data format that:
    90         -
    91         -          * Is independent of CPU type, operating system, file system,
    92         -            and character set, and hence can be used for interchange;
    93         -
    94         -          * Can be produced or consumed, even for an arbitrarily long
    95         -            sequentially presented input data stream, using only an a
    96         -            priori bounded amount of intermediate storage, and hence can
    97         -            be used in data communications or similar structures such as
    98         -            Unix filters;
    99         -
   100         -          * Can use a number of different compression methods;
   101         -
   102         -          * Can be implemented readily in a manner not covered by
   103         -            patents, and hence can be practiced freely.
   104         -
   105         -      The data format defined by this specification does not attempt to
   106         -      allow random access to compressed data.
   107         -
   108         -
   109         -
   110         -
   111         -
   112         -
   113         -
   114         -Deutsch & Gailly             Informational                      [Page 2]
   115         -
   116         -RFC 1950       ZLIB Compressed Data Format Specification        May 1996
   117         -
   118         -
   119         -   1.2. Intended audience
   120         -
   121         -      This specification is intended for use by implementors of software
   122         -      to compress data into zlib format and/or decompress data from zlib
   123         -      format.
   124         -
   125         -      The text of the specification assumes a basic background in
   126         -      programming at the level of bits and other primitive data
   127         -      representations.
   128         -
   129         -   1.3. Scope
   130         -
   131         -      The specification specifies a compressed data format that can be
   132         -      used for in-memory compression of a sequence of arbitrary bytes.
   133         -
   134         -   1.4. Compliance
   135         -
   136         -      Unless otherwise indicated below, a compliant decompressor must be
   137         -      able to accept and decompress any data set that conforms to all
   138         -      the specifications presented here; a compliant compressor must
   139         -      produce data sets that conform to all the specifications presented
   140         -      here.
   141         -
   142         -   1.5.  Definitions of terms and conventions used
   143         -
   144         -      byte: 8 bits stored or transmitted as a unit (same as an octet).
   145         -      (For this specification, a byte is exactly 8 bits, even on
   146         -      machines which store a character on a number of bits different
   147         -      from 8.) See below, for the numbering of bits within a byte.
   148         -
   149         -   1.6. Changes from previous versions
   150         -
   151         -      Version 3.1 was the first public release of this specification.
   152         -      In version 3.2, some terminology was changed and the Adler-32
   153         -      sample code was rewritten for clarity.  In version 3.3, the
   154         -      support for a preset dictionary was introduced, and the
   155         -      specification was converted to RFC style.
   156         -
   157         -2. Detailed specification
   158         -
   159         -   2.1. Overall conventions
   160         -
   161         -      In the diagrams below, a box like this:
   162         -
   163         -         +---+
   164         -         |   | <-- the vertical bars might be missing
   165         -         +---+
   166         -
   167         -
   168         -
   169         -
   170         -Deutsch & Gailly             Informational                      [Page 3]
   171         -
   172         -RFC 1950       ZLIB Compressed Data Format Specification        May 1996
   173         -
   174         -
   175         -      represents one byte; a box like this:
   176         -
   177         -         +==============+
   178         -         |              |
   179         -         +==============+
   180         -
   181         -      represents a variable number of bytes.
   182         -
   183         -      Bytes stored within a computer do not have a "bit order", since
   184         -      they are always treated as a unit.  However, a byte considered as
   185         -      an integer between 0 and 255 does have a most- and least-
   186         -      significant bit, and since we write numbers with the most-
   187         -      significant digit on the left, we also write bytes with the most-
   188         -      significant bit on the left.  In the diagrams below, we number the
   189         -      bits of a byte so that bit 0 is the least-significant bit, i.e.,
   190         -      the bits are numbered:
   191         -
   192         -         +--------+
   193         -         |76543210|
   194         -         +--------+
   195         -
   196         -      Within a computer, a number may occupy multiple bytes.  All
   197         -      multi-byte numbers in the format described here are stored with
   198         -      the MOST-significant byte first (at the lower memory address).
   199         -      For example, the decimal number 520 is stored as:
   200         -
   201         -             0     1
   202         -         +--------+--------+
   203         -         |00000010|00001000|
   204         -         +--------+--------+
   205         -          ^        ^
   206         -          |        |
   207         -          |        + less significant byte = 8
   208         -          + more significant byte = 2 x 256
   209         -
   210         -   2.2. Data format
   211         -
   212         -      A zlib stream has the following structure:
   213         -
   214         -           0   1
   215         -         +---+---+
   216         -         |CMF|FLG|   (more-->)
   217         -         +---+---+
   218         -
   219         -
   220         -
   221         -
   222         -
   223         -
   224         -
   225         -
   226         -Deutsch & Gailly             Informational                      [Page 4]
   227         -
   228         -RFC 1950       ZLIB Compressed Data Format Specification        May 1996
   229         -
   230         -
   231         -      (if FLG.FDICT set)
   232         -
   233         -           0   1   2   3
   234         -         +---+---+---+---+
   235         -         |     DICTID    |   (more-->)
   236         -         +---+---+---+---+
   237         -
   238         -         +=====================+---+---+---+---+
   239         -         |...compressed data...|    ADLER32    |
   240         -         +=====================+---+---+---+---+
   241         -
   242         -      Any data which may appear after ADLER32 are not part of the zlib
   243         -      stream.
   244         -
   245         -      CMF (Compression Method and flags)
   246         -         This byte is divided into a 4-bit compression method and a 4-
   247         -         bit information field depending on the compression method.
   248         -
   249         -            bits 0 to 3  CM     Compression method
   250         -            bits 4 to 7  CINFO  Compression info
   251         -
   252         -      CM (Compression method)
   253         -         This identifies the compression method used in the file. CM = 8
   254         -         denotes the "deflate" compression method with a window size up
   255         -         to 32K.  This is the method used by gzip and PNG (see
   256         -         references [1] and [2] in Chapter 3, below, for the reference
   257         -         documents).  CM = 15 is reserved.  It might be used in a future
   258         -         version of this specification to indicate the presence of an
   259         -         extra field before the compressed data.
   260         -
   261         -      CINFO (Compression info)
   262         -         For CM = 8, CINFO is the base-2 logarithm of the LZ77 window
   263         -         size, minus eight (CINFO=7 indicates a 32K window size). Values
   264         -         of CINFO above 7 are not allowed in this version of the
   265         -         specification.  CINFO is not defined in this specification for
   266         -         CM not equal to 8.
   267         -
   268         -      FLG (FLaGs)
   269         -         This flag byte is divided as follows:
   270         -
   271         -            bits 0 to 4  FCHECK  (check bits for CMF and FLG)
   272         -            bit  5       FDICT   (preset dictionary)
   273         -            bits 6 to 7  FLEVEL  (compression level)
   274         -
   275         -         The FCHECK value must be such that CMF and FLG, when viewed as
   276         -         a 16-bit unsigned integer stored in MSB order (CMF*256 + FLG),
   277         -         is a multiple of 31.
   278         -
   279         -
   280         -
   281         -
   282         -Deutsch & Gailly             Informational                      [Page 5]
   283         -
   284         -RFC 1950       ZLIB Compressed Data Format Specification        May 1996
   285         -
   286         -
   287         -      FDICT (Preset dictionary)
   288         -         If FDICT is set, a DICT dictionary identifier is present
   289         -         immediately after the FLG byte. The dictionary is a sequence of
   290         -         bytes which are initially fed to the compressor without
   291         -         producing any compressed output. DICT is the Adler-32 checksum
   292         -         of this sequence of bytes (see the definition of ADLER32
   293         -         below).  The decompressor can use this identifier to determine
   294         -         which dictionary has been used by the compressor.
   295         -
   296         -      FLEVEL (Compression level)
   297         -         These flags are available for use by specific compression
   298         -         methods.  The "deflate" method (CM = 8) sets these flags as
   299         -         follows:
   300         -
   301         -            0 - compressor used fastest algorithm
   302         -            1 - compressor used fast algorithm
   303         -            2 - compressor used default algorithm
   304         -            3 - compressor used maximum compression, slowest algorithm
   305         -
   306         -         The information in FLEVEL is not needed for decompression; it
   307         -         is there to indicate if recompression might be worthwhile.
   308         -
   309         -      compressed data
   310         -         For compression method 8, the compressed data is stored in the
   311         -         deflate compressed data format as described in the document
   312         -         "DEFLATE Compressed Data Format Specification" by L. Peter
   313         -         Deutsch. (See reference [3] in Chapter 3, below)
   314         -
   315         -         Other compressed data formats are not specified in this version
   316         -         of the zlib specification.
   317         -
   318         -      ADLER32 (Adler-32 checksum)
   319         -         This contains a checksum value of the uncompressed data
   320         -         (excluding any dictionary data) computed according to Adler-32
   321         -         algorithm. This algorithm is a 32-bit extension and improvement
   322         -         of the Fletcher algorithm, used in the ITU-T X.224 / ISO 8073
   323         -         standard. See references [4] and [5] in Chapter 3, below)
   324         -
   325         -         Adler-32 is composed of two sums accumulated per byte: s1 is
   326         -         the sum of all bytes, s2 is the sum of all s1 values. Both sums
   327         -         are done modulo 65521. s1 is initialized to 1, s2 to zero.  The
   328         -         Adler-32 checksum is stored as s2*65536 + s1 in most-
   329         -         significant-byte first (network) order.
   330         -
   331         -
   332         -
   333         -
   334         -
   335         -
   336         -
   337         -
   338         -Deutsch & Gailly             Informational                      [Page 6]
   339         -
   340         -RFC 1950       ZLIB Compressed Data Format Specification        May 1996
   341         -
   342         -
   343         -   2.3. Compliance
   344         -
   345         -      A compliant compressor must produce streams with correct CMF, FLG
   346         -      and ADLER32, but need not support preset dictionaries.  When the
   347         -      zlib data format is used as part of another standard data format,
   348         -      the compressor may use only preset dictionaries that are specified
   349         -      by this other data format.  If this other format does not use the
   350         -      preset dictionary feature, the compressor must not set the FDICT
   351         -      flag.
   352         -
   353         -      A compliant decompressor must check CMF, FLG, and ADLER32, and
   354         -      provide an error indication if any of these have incorrect values.
   355         -      A compliant decompressor must give an error indication if CM is
   356         -      not one of the values defined in this specification (only the
   357         -      value 8 is permitted in this version), since another value could
   358         -      indicate the presence of new features that would cause subsequent
   359         -      data to be interpreted incorrectly.  A compliant decompressor must
   360         -      give an error indication if FDICT is set and DICTID is not the
   361         -      identifier of a known preset dictionary.  A decompressor may
   362         -      ignore FLEVEL and still be compliant.  When the zlib data format
   363         -      is being used as a part of another standard format, a compliant
   364         -      decompressor must support all the preset dictionaries specified by
   365         -      the other format. When the other format does not use the preset
   366         -      dictionary feature, a compliant decompressor must reject any
   367         -      stream in which the FDICT flag is set.
   368         -
   369         -3. References
   370         -
   371         -   [1] Deutsch, L.P.,"GZIP Compressed Data Format Specification",
   372         -       available in ftp://ftp.uu.net/pub/archiving/zip/doc/
   373         -
   374         -   [2] Thomas Boutell, "PNG (Portable Network Graphics) specification",
   375         -       available in ftp://ftp.uu.net/graphics/png/documents/
   376         -
   377         -   [3] Deutsch, L.P.,"DEFLATE Compressed Data Format Specification",
   378         -       available in ftp://ftp.uu.net/pub/archiving/zip/doc/
   379         -
   380         -   [4] Fletcher, J. G., "An Arithmetic Checksum for Serial
   381         -       Transmissions," IEEE Transactions on Communications, Vol. COM-30,
   382         -       No. 1, January 1982, pp. 247-252.
   383         -
   384         -   [5] ITU-T Recommendation X.224, Annex D, "Checksum Algorithms,"
   385         -       November, 1993, pp. 144, 145. (Available from
   386         -       gopher://info.itu.ch). ITU-T X.244 is also the same as ISO 8073.
   387         -
   388         -
   389         -
   390         -
   391         -
   392         -
   393         -
   394         -Deutsch & Gailly             Informational                      [Page 7]
   395         -
   396         -RFC 1950       ZLIB Compressed Data Format Specification        May 1996
   397         -
   398         -
   399         -4. Source code
   400         -
   401         -   Source code for a C language implementation of a "zlib" compliant
   402         -   library is available at ftp://ftp.uu.net/pub/archiving/zip/zlib/.
   403         -
   404         -5. Security Considerations
   405         -
   406         -   A decoder that fails to check the ADLER32 checksum value may be
   407         -   subject to undetected data corruption.
   408         -
   409         -6. Acknowledgements
   410         -
   411         -   Trademarks cited in this document are the property of their
   412         -   respective owners.
   413         -
   414         -   Jean-Loup Gailly and Mark Adler designed the zlib format and wrote
   415         -   the related software described in this specification.  Glenn
   416         -   Randers-Pehrson converted this document to RFC and HTML format.
   417         -
   418         -7. Authors' Addresses
   419         -
   420         -   L. Peter Deutsch
   421         -   Aladdin Enterprises
   422         -   203 Santa Margarita Ave.
   423         -   Menlo Park, CA 94025
   424         -
   425         -   Phone: (415) 322-0103 (AM only)
   426         -   FAX:   (415) 322-1734
   427         -   EMail: <[email protected]>
   428         -
   429         -
   430         -   Jean-Loup Gailly
   431         -
   432         -   EMail: <[email protected]>
   433         -
   434         -   Questions about the technical content of this specification can be
   435         -   sent by email to
   436         -
   437         -   Jean-Loup Gailly <[email protected]> and
   438         -   Mark Adler <[email protected]>
   439         -
   440         -   Editorial comments on this specification can be sent by email to
   441         -
   442         -   L. Peter Deutsch <[email protected]> and
   443         -   Glenn Randers-Pehrson <[email protected]>
   444         -
   445         -
   446         -
   447         -
   448         -
   449         -
   450         -Deutsch & Gailly             Informational                      [Page 8]
   451         -
   452         -RFC 1950       ZLIB Compressed Data Format Specification        May 1996
   453         -
   454         -
   455         -8. Appendix: Rationale
   456         -
   457         -   8.1. Preset dictionaries
   458         -
   459         -      A preset dictionary is specially useful to compress short input
   460         -      sequences. The compressor can take advantage of the dictionary
   461         -      context to encode the input in a more compact manner. The
   462         -      decompressor can be initialized with the appropriate context by
   463         -      virtually decompressing a compressed version of the dictionary
   464         -      without producing any output. However for certain compression
   465         -      algorithms such as the deflate algorithm this operation can be
   466         -      achieved without actually performing any decompression.
   467         -
   468         -      The compressor and the decompressor must use exactly the same
   469         -      dictionary. The dictionary may be fixed or may be chosen among a
   470         -      certain number of predefined dictionaries, according to the kind
   471         -      of input data. The decompressor can determine which dictionary has
   472         -      been chosen by the compressor by checking the dictionary
   473         -      identifier. This document does not specify the contents of
   474         -      predefined dictionaries, since the optimal dictionaries are
   475         -      application specific. Standard data formats using this feature of
   476         -      the zlib specification must precisely define the allowed
   477         -      dictionaries.
   478         -
   479         -   8.2. The Adler-32 algorithm
   480         -
   481         -      The Adler-32 algorithm is much faster than the CRC32 algorithm yet
   482         -      still provides an extremely low probability of undetected errors.
   483         -
   484         -      The modulo on unsigned long accumulators can be delayed for 5552
   485         -      bytes, so the modulo operation time is negligible.  If the bytes
   486         -      are a, b, c, the second sum is 3a + 2b + c + 3, and so is position
   487         -      and order sensitive, unlike the first sum, which is just a
   488         -      checksum.  That 65521 is prime is important to avoid a possible
   489         -      large class of two-byte errors that leave the check unchanged.
   490         -      (The Fletcher checksum uses 255, which is not prime and which also
   491         -      makes the Fletcher check insensitive to single byte changes 0 <->
   492         -      255.)
   493         -
   494         -      The sum s1 is initialized to 1 instead of zero to make the length
   495         -      of the sequence part of s2, so that the length does not have to be
   496         -      checked separately. (Any sequence of zeroes has a Fletcher
   497         -      checksum of zero.)
   498         -
   499         -
   500         -
   501         -
   502         -
   503         -
   504         -
   505         -
   506         -Deutsch & Gailly             Informational                      [Page 9]
   507         -
   508         -RFC 1950       ZLIB Compressed Data Format Specification        May 1996
   509         -
   510         -
   511         -9. Appendix: Sample code
   512         -
   513         -   The following C code computes the Adler-32 checksum of a data buffer.
   514         -   It is written for clarity, not for speed.  The sample code is in the
   515         -   ANSI C programming language. Non C users may find it easier to read
   516         -   with these hints:
   517         -
   518         -      &      Bitwise AND operator.
   519         -      >>     Bitwise right shift operator. When applied to an
   520         -             unsigned quantity, as here, right shift inserts zero bit(s)
   521         -             at the left.
   522         -      <<     Bitwise left shift operator. Left shift inserts zero
   523         -             bit(s) at the right.
   524         -      ++     "n++" increments the variable n.
   525         -      %      modulo operator: a % b is the remainder of a divided by b.
   526         -
   527         -      #define BASE 65521 /* largest prime smaller than 65536 */
   528         -
   529         -      /*
   530         -         Update a running Adler-32 checksum with the bytes buf[0..len-1]
   531         -       and return the updated checksum. The Adler-32 checksum should be
   532         -       initialized to 1.
   533         -
   534         -       Usage example:
   535         -
   536         -         unsigned long adler = 1L;
   537         -
   538         -         while (read_buffer(buffer, length) != EOF) {
   539         -           adler = update_adler32(adler, buffer, length);
   540         -         }
   541         -         if (adler != original_adler) error();
   542         -      */
   543         -      unsigned long update_adler32(unsigned long adler,
   544         -         unsigned char *buf, int len)
   545         -      {
   546         -        unsigned long s1 = adler & 0xffff;
   547         -        unsigned long s2 = (adler >> 16) & 0xffff;
   548         -        int n;
   549         -
   550         -        for (n = 0; n < len; n++) {
   551         -          s1 = (s1 + buf[n]) % BASE;
   552         -          s2 = (s2 + s1)     % BASE;
   553         -        }
   554         -        return (s2 << 16) + s1;
   555         -      }
   556         -
   557         -      /* Return the adler32 of the bytes buf[0..len-1] */
   558         -
   559         -
   560         -
   561         -
   562         -Deutsch & Gailly             Informational                     [Page 10]
   563         -
   564         -RFC 1950       ZLIB Compressed Data Format Specification        May 1996
   565         -
   566         -
   567         -      unsigned long adler32(unsigned char *buf, int len)
   568         -      {
   569         -        return update_adler32(1L, buf, len);
   570         -      }
   571         -
   572         -
   573         -
   574         -
   575         -
   576         -
   577         -
   578         -
   579         -
   580         -
   581         -
   582         -
   583         -
   584         -
   585         -
   586         -
   587         -
   588         -
   589         -
   590         -
   591         -
   592         -
   593         -
   594         -
   595         -
   596         -
   597         -
   598         -
   599         -
   600         -
   601         -
   602         -
   603         -
   604         -
   605         -
   606         -
   607         -
   608         -
   609         -
   610         -
   611         -
   612         -
   613         -
   614         -
   615         -
   616         -
   617         -
   618         -Deutsch & Gailly             Informational                     [Page 11]
   619         -

Deleted compat/zlib/doc/rfc1951.txt.

     1         -
     2         -
     3         -
     4         -
     5         -
     6         -
     7         -Network Working Group                                         P. Deutsch
     8         -Request for Comments: 1951                           Aladdin Enterprises
     9         -Category: Informational                                         May 1996
    10         -
    11         -
    12         -        DEFLATE Compressed Data Format Specification version 1.3
    13         -
    14         -Status of This Memo
    15         -
    16         -   This memo provides information for the Internet community.  This memo
    17         -   does not specify an Internet standard of any kind.  Distribution of
    18         -   this memo is unlimited.
    19         -
    20         -IESG Note:
    21         -
    22         -   The IESG takes no position on the validity of any Intellectual
    23         -   Property Rights statements contained in this document.
    24         -
    25         -Notices
    26         -
    27         -   Copyright (c) 1996 L. Peter Deutsch
    28         -
    29         -   Permission is granted to copy and distribute this document for any
    30         -   purpose and without charge, including translations into other
    31         -   languages and incorporation into compilations, provided that the
    32         -   copyright notice and this notice are preserved, and that any
    33         -   substantive changes or deletions from the original are clearly
    34         -   marked.
    35         -
    36         -   A pointer to the latest version of this and related documentation in
    37         -   HTML format can be found at the URL
    38         -   <ftp://ftp.uu.net/graphics/png/documents/zlib/zdoc-index.html>.
    39         -
    40         -Abstract
    41         -
    42         -   This specification defines a lossless compressed data format that
    43         -   compresses data using a combination of the LZ77 algorithm and Huffman
    44         -   coding, with efficiency comparable to the best currently available
    45         -   general-purpose compression methods.  The data can be produced or
    46         -   consumed, even for an arbitrarily long sequentially presented input
    47         -   data stream, using only an a priori bounded amount of intermediate
    48         -   storage.  The format can be implemented readily in a manner not
    49         -   covered by patents.
    50         -
    51         -
    52         -
    53         -
    54         -
    55         -
    56         -
    57         -
    58         -Deutsch                      Informational                      [Page 1]
    59         -
    60         -RFC 1951      DEFLATE Compressed Data Format Specification      May 1996
    61         -
    62         -
    63         -Table of Contents
    64         -
    65         -   1. Introduction ................................................... 2
    66         -      1.1. Purpose ................................................... 2
    67         -      1.2. Intended audience ......................................... 3
    68         -      1.3. Scope ..................................................... 3
    69         -      1.4. Compliance ................................................ 3
    70         -      1.5.  Definitions of terms and conventions used ................ 3
    71         -      1.6. Changes from previous versions ............................ 4
    72         -   2. Compressed representation overview ............................. 4
    73         -   3. Detailed specification ......................................... 5
    74         -      3.1. Overall conventions ....................................... 5
    75         -          3.1.1. Packing into bytes .................................. 5
    76         -      3.2. Compressed block format ................................... 6
    77         -          3.2.1. Synopsis of prefix and Huffman coding ............... 6
    78         -          3.2.2. Use of Huffman coding in the "deflate" format ....... 7
    79         -          3.2.3. Details of block format ............................. 9
    80         -          3.2.4. Non-compressed blocks (BTYPE=00) ................... 11
    81         -          3.2.5. Compressed blocks (length and distance codes) ...... 11
    82         -          3.2.6. Compression with fixed Huffman codes (BTYPE=01) .... 12
    83         -          3.2.7. Compression with dynamic Huffman codes (BTYPE=10) .. 13
    84         -      3.3. Compliance ............................................... 14
    85         -   4. Compression algorithm details ................................. 14
    86         -   5. References .................................................... 16
    87         -   6. Security Considerations ....................................... 16
    88         -   7. Source code ................................................... 16
    89         -   8. Acknowledgements .............................................. 16
    90         -   9. Author's Address .............................................. 17
    91         -
    92         -1. Introduction
    93         -
    94         -   1.1. Purpose
    95         -
    96         -      The purpose of this specification is to define a lossless
    97         -      compressed data format that:
    98         -          * Is independent of CPU type, operating system, file system,
    99         -            and character set, and hence can be used for interchange;
   100         -          * Can be produced or consumed, even for an arbitrarily long
   101         -            sequentially presented input data stream, using only an a
   102         -            priori bounded amount of intermediate storage, and hence
   103         -            can be used in data communications or similar structures
   104         -            such as Unix filters;
   105         -          * Compresses data with efficiency comparable to the best
   106         -            currently available general-purpose compression methods,
   107         -            and in particular considerably better than the "compress"
   108         -            program;
   109         -          * Can be implemented readily in a manner not covered by
   110         -            patents, and hence can be practiced freely;
   111         -
   112         -
   113         -
   114         -Deutsch                      Informational                      [Page 2]
   115         -
   116         -RFC 1951      DEFLATE Compressed Data Format Specification      May 1996
   117         -
   118         -
   119         -          * Is compatible with the file format produced by the current
   120         -            widely used gzip utility, in that conforming decompressors
   121         -            will be able to read data produced by the existing gzip
   122         -            compressor.
   123         -
   124         -      The data format defined by this specification does not attempt to:
   125         -
   126         -          * Allow random access to compressed data;
   127         -          * Compress specialized data (e.g., raster graphics) as well
   128         -            as the best currently available specialized algorithms.
   129         -
   130         -      A simple counting argument shows that no lossless compression
   131         -      algorithm can compress every possible input data set.  For the
   132         -      format defined here, the worst case expansion is 5 bytes per 32K-
   133         -      byte block, i.e., a size increase of 0.015% for large data sets.
   134         -      English text usually compresses by a factor of 2.5 to 3;
   135         -      executable files usually compress somewhat less; graphical data
   136         -      such as raster images may compress much more.
   137         -
   138         -   1.2. Intended audience
   139         -
   140         -      This specification is intended for use by implementors of software
   141         -      to compress data into "deflate" format and/or decompress data from
   142         -      "deflate" format.
   143         -
   144         -      The text of the specification assumes a basic background in
   145         -      programming at the level of bits and other primitive data
   146         -      representations.  Familiarity with the technique of Huffman coding
   147         -      is helpful but not required.
   148         -
   149         -   1.3. Scope
   150         -
   151         -      The specification specifies a method for representing a sequence
   152         -      of bytes as a (usually shorter) sequence of bits, and a method for
   153         -      packing the latter bit sequence into bytes.
   154         -
   155         -   1.4. Compliance
   156         -
   157         -      Unless otherwise indicated below, a compliant decompressor must be
   158         -      able to accept and decompress any data set that conforms to all
   159         -      the specifications presented here; a compliant compressor must
   160         -      produce data sets that conform to all the specifications presented
   161         -      here.
   162         -
   163         -   1.5.  Definitions of terms and conventions used
   164         -
   165         -      Byte: 8 bits stored or transmitted as a unit (same as an octet).
   166         -      For this specification, a byte is exactly 8 bits, even on machines
   167         -
   168         -
   169         -
   170         -Deutsch                      Informational                      [Page 3]
   171         -
   172         -RFC 1951      DEFLATE Compressed Data Format Specification      May 1996
   173         -
   174         -
   175         -      which store a character on a number of bits different from eight.
   176         -      See below, for the numbering of bits within a byte.
   177         -
   178         -      String: a sequence of arbitrary bytes.
   179         -
   180         -   1.6. Changes from previous versions
   181         -
   182         -      There have been no technical changes to the deflate format since
   183         -      version 1.1 of this specification.  In version 1.2, some
   184         -      terminology was changed.  Version 1.3 is a conversion of the
   185         -      specification to RFC style.
   186         -
   187         -2. Compressed representation overview
   188         -
   189         -   A compressed data set consists of a series of blocks, corresponding
   190         -   to successive blocks of input data.  The block sizes are arbitrary,
   191         -   except that non-compressible blocks are limited to 65,535 bytes.
   192         -
   193         -   Each block is compressed using a combination of the LZ77 algorithm
   194         -   and Huffman coding. The Huffman trees for each block are independent
   195         -   of those for previous or subsequent blocks; the LZ77 algorithm may
   196         -   use a reference to a duplicated string occurring in a previous block,
   197         -   up to 32K input bytes before.
   198         -
   199         -   Each block consists of two parts: a pair of Huffman code trees that
   200         -   describe the representation of the compressed data part, and a
   201         -   compressed data part.  (The Huffman trees themselves are compressed
   202         -   using Huffman encoding.)  The compressed data consists of a series of
   203         -   elements of two types: literal bytes (of strings that have not been
   204         -   detected as duplicated within the previous 32K input bytes), and
   205         -   pointers to duplicated strings, where a pointer is represented as a
   206         -   pair <length, backward distance>.  The representation used in the
   207         -   "deflate" format limits distances to 32K bytes and lengths to 258
   208         -   bytes, but does not limit the size of a block, except for
   209         -   uncompressible blocks, which are limited as noted above.
   210         -
   211         -   Each type of value (literals, distances, and lengths) in the
   212         -   compressed data is represented using a Huffman code, using one code
   213         -   tree for literals and lengths and a separate code tree for distances.
   214         -   The code trees for each block appear in a compact form just before
   215         -   the compressed data for that block.
   216         -
   217         -
   218         -
   219         -
   220         -
   221         -
   222         -
   223         -
   224         -
   225         -
   226         -Deutsch                      Informational                      [Page 4]
   227         -
   228         -RFC 1951      DEFLATE Compressed Data Format Specification      May 1996
   229         -
   230         -
   231         -3. Detailed specification
   232         -
   233         -   3.1. Overall conventions In the diagrams below, a box like this:
   234         -
   235         -         +---+
   236         -         |   | <-- the vertical bars might be missing
   237         -         +---+
   238         -
   239         -      represents one byte; a box like this:
   240         -
   241         -         +==============+
   242         -         |              |
   243         -         +==============+
   244         -
   245         -      represents a variable number of bytes.
   246         -
   247         -      Bytes stored within a computer do not have a "bit order", since
   248         -      they are always treated as a unit.  However, a byte considered as
   249         -      an integer between 0 and 255 does have a most- and least-
   250         -      significant bit, and since we write numbers with the most-
   251         -      significant digit on the left, we also write bytes with the most-
   252         -      significant bit on the left.  In the diagrams below, we number the
   253         -      bits of a byte so that bit 0 is the least-significant bit, i.e.,
   254         -      the bits are numbered:
   255         -
   256         -         +--------+
   257         -         |76543210|
   258         -         +--------+
   259         -
   260         -      Within a computer, a number may occupy multiple bytes.  All
   261         -      multi-byte numbers in the format described here are stored with
   262         -      the least-significant byte first (at the lower memory address).
   263         -      For example, the decimal number 520 is stored as:
   264         -
   265         -             0        1
   266         -         +--------+--------+
   267         -         |00001000|00000010|
   268         -         +--------+--------+
   269         -          ^        ^
   270         -          |        |
   271         -          |        + more significant byte = 2 x 256
   272         -          + less significant byte = 8
   273         -
   274         -      3.1.1. Packing into bytes
   275         -
   276         -         This document does not address the issue of the order in which
   277         -         bits of a byte are transmitted on a bit-sequential medium,
   278         -         since the final data format described here is byte- rather than
   279         -
   280         -
   281         -
   282         -Deutsch                      Informational                      [Page 5]
   283         -
   284         -RFC 1951      DEFLATE Compressed Data Format Specification      May 1996
   285         -
   286         -
   287         -         bit-oriented.  However, we describe the compressed block format
   288         -         in below, as a sequence of data elements of various bit
   289         -         lengths, not a sequence of bytes.  We must therefore specify
   290         -         how to pack these data elements into bytes to form the final
   291         -         compressed byte sequence:
   292         -
   293         -             * Data elements are packed into bytes in order of
   294         -               increasing bit number within the byte, i.e., starting
   295         -               with the least-significant bit of the byte.
   296         -             * Data elements other than Huffman codes are packed
   297         -               starting with the least-significant bit of the data
   298         -               element.
   299         -             * Huffman codes are packed starting with the most-
   300         -               significant bit of the code.
   301         -
   302         -         In other words, if one were to print out the compressed data as
   303         -         a sequence of bytes, starting with the first byte at the
   304         -         *right* margin and proceeding to the *left*, with the most-
   305         -         significant bit of each byte on the left as usual, one would be
   306         -         able to parse the result from right to left, with fixed-width
   307         -         elements in the correct MSB-to-LSB order and Huffman codes in
   308         -         bit-reversed order (i.e., with the first bit of the code in the
   309         -         relative LSB position).
   310         -
   311         -   3.2. Compressed block format
   312         -
   313         -      3.2.1. Synopsis of prefix and Huffman coding
   314         -
   315         -         Prefix coding represents symbols from an a priori known
   316         -         alphabet by bit sequences (codes), one code for each symbol, in
   317         -         a manner such that different symbols may be represented by bit
   318         -         sequences of different lengths, but a parser can always parse
   319         -         an encoded string unambiguously symbol-by-symbol.
   320         -
   321         -         We define a prefix code in terms of a binary tree in which the
   322         -         two edges descending from each non-leaf node are labeled 0 and
   323         -         1 and in which the leaf nodes correspond one-for-one with (are
   324         -         labeled with) the symbols of the alphabet; then the code for a
   325         -         symbol is the sequence of 0's and 1's on the edges leading from
   326         -         the root to the leaf labeled with that symbol.  For example:
   327         -
   328         -
   329         -
   330         -
   331         -
   332         -
   333         -
   334         -
   335         -
   336         -
   337         -
   338         -Deutsch                      Informational                      [Page 6]
   339         -
   340         -RFC 1951      DEFLATE Compressed Data Format Specification      May 1996
   341         -
   342         -
   343         -                          /\              Symbol    Code
   344         -                         0  1             ------    ----
   345         -                        /    \                A      00
   346         -                       /\     B               B       1
   347         -                      0  1                    C     011
   348         -                     /    \                   D     010
   349         -                    A     /\
   350         -                         0  1
   351         -                        /    \
   352         -                       D      C
   353         -
   354         -         A parser can decode the next symbol from an encoded input
   355         -         stream by walking down the tree from the root, at each step
   356         -         choosing the edge corresponding to the next input bit.
   357         -
   358         -         Given an alphabet with known symbol frequencies, the Huffman
   359         -         algorithm allows the construction of an optimal prefix code
   360         -         (one which represents strings with those symbol frequencies
   361         -         using the fewest bits of any possible prefix codes for that
   362         -         alphabet).  Such a code is called a Huffman code.  (See
   363         -         reference [1] in Chapter 5, references for additional
   364         -         information on Huffman codes.)
   365         -
   366         -         Note that in the "deflate" format, the Huffman codes for the
   367         -         various alphabets must not exceed certain maximum code lengths.
   368         -         This constraint complicates the algorithm for computing code
   369         -         lengths from symbol frequencies.  Again, see Chapter 5,
   370         -         references for details.
   371         -
   372         -      3.2.2. Use of Huffman coding in the "deflate" format
   373         -
   374         -         The Huffman codes used for each alphabet in the "deflate"
   375         -         format have two additional rules:
   376         -
   377         -             * All codes of a given bit length have lexicographically
   378         -               consecutive values, in the same order as the symbols
   379         -               they represent;
   380         -
   381         -             * Shorter codes lexicographically precede longer codes.
   382         -
   383         -
   384         -
   385         -
   386         -
   387         -
   388         -
   389         -
   390         -
   391         -
   392         -
   393         -
   394         -Deutsch                      Informational                      [Page 7]
   395         -
   396         -RFC 1951      DEFLATE Compressed Data Format Specification      May 1996
   397         -
   398         -
   399         -         We could recode the example above to follow this rule as
   400         -         follows, assuming that the order of the alphabet is ABCD:
   401         -
   402         -            Symbol  Code
   403         -            ------  ----
   404         -            A       10
   405         -            B       0
   406         -            C       110
   407         -            D       111
   408         -
   409         -         I.e., 0 precedes 10 which precedes 11x, and 110 and 111 are
   410         -         lexicographically consecutive.
   411         -
   412         -         Given this rule, we can define the Huffman code for an alphabet
   413         -         just by giving the bit lengths of the codes for each symbol of
   414         -         the alphabet in order; this is sufficient to determine the
   415         -         actual codes.  In our example, the code is completely defined
   416         -         by the sequence of bit lengths (2, 1, 3, 3).  The following
   417         -         algorithm generates the codes as integers, intended to be read
   418         -         from most- to least-significant bit.  The code lengths are
   419         -         initially in tree[I].Len; the codes are produced in
   420         -         tree[I].Code.
   421         -
   422         -         1)  Count the number of codes for each code length.  Let
   423         -             bl_count[N] be the number of codes of length N, N >= 1.
   424         -
   425         -         2)  Find the numerical value of the smallest code for each
   426         -             code length:
   427         -
   428         -                code = 0;
   429         -                bl_count[0] = 0;
   430         -                for (bits = 1; bits <= MAX_BITS; bits++) {
   431         -                    code = (code + bl_count[bits-1]) << 1;
   432         -                    next_code[bits] = code;
   433         -                }
   434         -
   435         -         3)  Assign numerical values to all codes, using consecutive
   436         -             values for all codes of the same length with the base
   437         -             values determined at step 2. Codes that are never used
   438         -             (which have a bit length of zero) must not be assigned a
   439         -             value.
   440         -
   441         -                for (n = 0;  n <= max_code; n++) {
   442         -                    len = tree[n].Len;
   443         -                    if (len != 0) {
   444         -                        tree[n].Code = next_code[len];
   445         -                        next_code[len]++;
   446         -                    }
   447         -
   448         -
   449         -
   450         -Deutsch                      Informational                      [Page 8]
   451         -
   452         -RFC 1951      DEFLATE Compressed Data Format Specification      May 1996
   453         -
   454         -
   455         -                }
   456         -
   457         -         Example:
   458         -
   459         -         Consider the alphabet ABCDEFGH, with bit lengths (3, 3, 3, 3,
   460         -         3, 2, 4, 4).  After step 1, we have:
   461         -
   462         -            N      bl_count[N]
   463         -            -      -----------
   464         -            2      1
   465         -            3      5
   466         -            4      2
   467         -
   468         -         Step 2 computes the following next_code values:
   469         -
   470         -            N      next_code[N]
   471         -            -      ------------
   472         -            1      0
   473         -            2      0
   474         -            3      2
   475         -            4      14
   476         -
   477         -         Step 3 produces the following code values:
   478         -
   479         -            Symbol Length   Code
   480         -            ------ ------   ----
   481         -            A       3        010
   482         -            B       3        011
   483         -            C       3        100
   484         -            D       3        101
   485         -            E       3        110
   486         -            F       2         00
   487         -            G       4       1110
   488         -            H       4       1111
   489         -
   490         -      3.2.3. Details of block format
   491         -
   492         -         Each block of compressed data begins with 3 header bits
   493         -         containing the following data:
   494         -
   495         -            first bit       BFINAL
   496         -            next 2 bits     BTYPE
   497         -
   498         -         Note that the header bits do not necessarily begin on a byte
   499         -         boundary, since a block does not necessarily occupy an integral
   500         -         number of bytes.
   501         -
   502         -
   503         -
   504         -
   505         -
   506         -Deutsch                      Informational                      [Page 9]
   507         -
   508         -RFC 1951      DEFLATE Compressed Data Format Specification      May 1996
   509         -
   510         -
   511         -         BFINAL is set if and only if this is the last block of the data
   512         -         set.
   513         -
   514         -         BTYPE specifies how the data are compressed, as follows:
   515         -
   516         -            00 - no compression
   517         -            01 - compressed with fixed Huffman codes
   518         -            10 - compressed with dynamic Huffman codes
   519         -            11 - reserved (error)
   520         -
   521         -         The only difference between the two compressed cases is how the
   522         -         Huffman codes for the literal/length and distance alphabets are
   523         -         defined.
   524         -
   525         -         In all cases, the decoding algorithm for the actual data is as
   526         -         follows:
   527         -
   528         -            do
   529         -               read block header from input stream.
   530         -               if stored with no compression
   531         -                  skip any remaining bits in current partially
   532         -                     processed byte
   533         -                  read LEN and NLEN (see next section)
   534         -                  copy LEN bytes of data to output
   535         -               otherwise
   536         -                  if compressed with dynamic Huffman codes
   537         -                     read representation of code trees (see
   538         -                        subsection below)
   539         -                  loop (until end of block code recognized)
   540         -                     decode literal/length value from input stream
   541         -                     if value < 256
   542         -                        copy value (literal byte) to output stream
   543         -                     otherwise
   544         -                        if value = end of block (256)
   545         -                           break from loop
   546         -                        otherwise (value = 257..285)
   547         -                           decode distance from input stream
   548         -
   549         -                           move backwards distance bytes in the output
   550         -                           stream, and copy length bytes from this
   551         -                           position to the output stream.
   552         -                  end loop
   553         -            while not last block
   554         -
   555         -         Note that a duplicated string reference may refer to a string
   556         -         in a previous block; i.e., the backward distance may cross one
   557         -         or more block boundaries.  However a distance cannot refer past
   558         -         the beginning of the output stream.  (An application using a
   559         -
   560         -
   561         -
   562         -Deutsch                      Informational                     [Page 10]
   563         -
   564         -RFC 1951      DEFLATE Compressed Data Format Specification      May 1996
   565         -
   566         -
   567         -         preset dictionary might discard part of the output stream; a
   568         -         distance can refer to that part of the output stream anyway)
   569         -         Note also that the referenced string may overlap the current
   570         -         position; for example, if the last 2 bytes decoded have values
   571         -         X and Y, a string reference with <length = 5, distance = 2>
   572         -         adds X,Y,X,Y,X to the output stream.
   573         -
   574         -         We now specify each compression method in turn.
   575         -
   576         -      3.2.4. Non-compressed blocks (BTYPE=00)
   577         -
   578         -         Any bits of input up to the next byte boundary are ignored.
   579         -         The rest of the block consists of the following information:
   580         -
   581         -              0   1   2   3   4...
   582         -            +---+---+---+---+================================+
   583         -            |  LEN  | NLEN  |... LEN bytes of literal data...|
   584         -            +---+---+---+---+================================+
   585         -
   586         -         LEN is the number of data bytes in the block.  NLEN is the
   587         -         one's complement of LEN.
   588         -
   589         -      3.2.5. Compressed blocks (length and distance codes)
   590         -
   591         -         As noted above, encoded data blocks in the "deflate" format
   592         -         consist of sequences of symbols drawn from three conceptually
   593         -         distinct alphabets: either literal bytes, from the alphabet of
   594         -         byte values (0..255), or <length, backward distance> pairs,
   595         -         where the length is drawn from (3..258) and the distance is
   596         -         drawn from (1..32,768).  In fact, the literal and length
   597         -         alphabets are merged into a single alphabet (0..285), where
   598         -         values 0..255 represent literal bytes, the value 256 indicates
   599         -         end-of-block, and values 257..285 represent length codes
   600         -         (possibly in conjunction with extra bits following the symbol
   601         -         code) as follows:
   602         -
   603         -
   604         -
   605         -
   606         -
   607         -
   608         -
   609         -
   610         -
   611         -
   612         -
   613         -
   614         -
   615         -
   616         -
   617         -
   618         -Deutsch                      Informational                     [Page 11]
   619         -
   620         -RFC 1951      DEFLATE Compressed Data Format Specification      May 1996
   621         -
   622         -
   623         -                 Extra               Extra               Extra
   624         -            Code Bits Length(s) Code Bits Lengths   Code Bits Length(s)
   625         -            ---- ---- ------     ---- ---- -------   ---- ---- -------
   626         -             257   0     3       267   1   15,16     277   4   67-82
   627         -             258   0     4       268   1   17,18     278   4   83-98
   628         -             259   0     5       269   2   19-22     279   4   99-114
   629         -             260   0     6       270   2   23-26     280   4  115-130
   630         -             261   0     7       271   2   27-30     281   5  131-162
   631         -             262   0     8       272   2   31-34     282   5  163-194
   632         -             263   0     9       273   3   35-42     283   5  195-226
   633         -             264   0    10       274   3   43-50     284   5  227-257
   634         -             265   1  11,12      275   3   51-58     285   0    258
   635         -             266   1  13,14      276   3   59-66
   636         -
   637         -         The extra bits should be interpreted as a machine integer
   638         -         stored with the most-significant bit first, e.g., bits 1110
   639         -         represent the value 14.
   640         -
   641         -                  Extra           Extra               Extra
   642         -             Code Bits Dist  Code Bits   Dist     Code Bits Distance
   643         -             ---- ---- ----  ---- ----  ------    ---- ---- --------
   644         -               0   0    1     10   4     33-48    20    9   1025-1536
   645         -               1   0    2     11   4     49-64    21    9   1537-2048
   646         -               2   0    3     12   5     65-96    22   10   2049-3072
   647         -               3   0    4     13   5     97-128   23   10   3073-4096
   648         -               4   1   5,6    14   6    129-192   24   11   4097-6144
   649         -               5   1   7,8    15   6    193-256   25   11   6145-8192
   650         -               6   2   9-12   16   7    257-384   26   12  8193-12288
   651         -               7   2  13-16   17   7    385-512   27   12 12289-16384
   652         -               8   3  17-24   18   8    513-768   28   13 16385-24576
   653         -               9   3  25-32   19   8   769-1024   29   13 24577-32768
   654         -
   655         -      3.2.6. Compression with fixed Huffman codes (BTYPE=01)
   656         -
   657         -         The Huffman codes for the two alphabets are fixed, and are not
   658         -         represented explicitly in the data.  The Huffman code lengths
   659         -         for the literal/length alphabet are:
   660         -
   661         -                   Lit Value    Bits        Codes
   662         -                   ---------    ----        -----
   663         -                     0 - 143     8          00110000 through
   664         -                                            10111111
   665         -                   144 - 255     9          110010000 through
   666         -                                            111111111
   667         -                   256 - 279     7          0000000 through
   668         -                                            0010111
   669         -                   280 - 287     8          11000000 through
   670         -                                            11000111
   671         -
   672         -
   673         -
   674         -Deutsch                      Informational                     [Page 12]
   675         -
   676         -RFC 1951      DEFLATE Compressed Data Format Specification      May 1996
   677         -
   678         -
   679         -         The code lengths are sufficient to generate the actual codes,
   680         -         as described above; we show the codes in the table for added
   681         -         clarity.  Literal/length values 286-287 will never actually
   682         -         occur in the compressed data, but participate in the code
   683         -         construction.
   684         -
   685         -         Distance codes 0-31 are represented by (fixed-length) 5-bit
   686         -         codes, with possible additional bits as shown in the table
   687         -         shown in Paragraph 3.2.5, above.  Note that distance codes 30-
   688         -         31 will never actually occur in the compressed data.
   689         -
   690         -      3.2.7. Compression with dynamic Huffman codes (BTYPE=10)
   691         -
   692         -         The Huffman codes for the two alphabets appear in the block
   693         -         immediately after the header bits and before the actual
   694         -         compressed data, first the literal/length code and then the
   695         -         distance code.  Each code is defined by a sequence of code
   696         -         lengths, as discussed in Paragraph 3.2.2, above.  For even
   697         -         greater compactness, the code length sequences themselves are
   698         -         compressed using a Huffman code.  The alphabet for code lengths
   699         -         is as follows:
   700         -
   701         -               0 - 15: Represent code lengths of 0 - 15
   702         -                   16: Copy the previous code length 3 - 6 times.
   703         -                       The next 2 bits indicate repeat length
   704         -                             (0 = 3, ... , 3 = 6)
   705         -                          Example:  Codes 8, 16 (+2 bits 11),
   706         -                                    16 (+2 bits 10) will expand to
   707         -                                    12 code lengths of 8 (1 + 6 + 5)
   708         -                   17: Repeat a code length of 0 for 3 - 10 times.
   709         -                       (3 bits of length)
   710         -                   18: Repeat a code length of 0 for 11 - 138 times
   711         -                       (7 bits of length)
   712         -
   713         -         A code length of 0 indicates that the corresponding symbol in
   714         -         the literal/length or distance alphabet will not occur in the
   715         -         block, and should not participate in the Huffman code
   716         -         construction algorithm given earlier.  If only one distance
   717         -         code is used, it is encoded using one bit, not zero bits; in
   718         -         this case there is a single code length of one, with one unused
   719         -         code.  One distance code of zero bits means that there are no
   720         -         distance codes used at all (the data is all literals).
   721         -
   722         -         We can now define the format of the block:
   723         -
   724         -               5 Bits: HLIT, # of Literal/Length codes - 257 (257 - 286)
   725         -               5 Bits: HDIST, # of Distance codes - 1        (1 - 32)
   726         -               4 Bits: HCLEN, # of Code Length codes - 4     (4 - 19)
   727         -
   728         -
   729         -
   730         -Deutsch                      Informational                     [Page 13]
   731         -
   732         -RFC 1951      DEFLATE Compressed Data Format Specification      May 1996
   733         -
   734         -
   735         -               (HCLEN + 4) x 3 bits: code lengths for the code length
   736         -                  alphabet given just above, in the order: 16, 17, 18,
   737         -                  0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15
   738         -
   739         -                  These code lengths are interpreted as 3-bit integers
   740         -                  (0-7); as above, a code length of 0 means the
   741         -                  corresponding symbol (literal/length or distance code
   742         -                  length) is not used.
   743         -
   744         -               HLIT + 257 code lengths for the literal/length alphabet,
   745         -                  encoded using the code length Huffman code
   746         -
   747         -               HDIST + 1 code lengths for the distance alphabet,
   748         -                  encoded using the code length Huffman code
   749         -
   750         -               The actual compressed data of the block,
   751         -                  encoded using the literal/length and distance Huffman
   752         -                  codes
   753         -
   754         -               The literal/length symbol 256 (end of data),
   755         -                  encoded using the literal/length Huffman code
   756         -
   757         -         The code length repeat codes can cross from HLIT + 257 to the
   758         -         HDIST + 1 code lengths.  In other words, all code lengths form
   759         -         a single sequence of HLIT + HDIST + 258 values.
   760         -
   761         -   3.3. Compliance
   762         -
   763         -      A compressor may limit further the ranges of values specified in
   764         -      the previous section and still be compliant; for example, it may
   765         -      limit the range of backward pointers to some value smaller than
   766         -      32K.  Similarly, a compressor may limit the size of blocks so that
   767         -      a compressible block fits in memory.
   768         -
   769         -      A compliant decompressor must accept the full range of possible
   770         -      values defined in the previous section, and must accept blocks of
   771         -      arbitrary size.
   772         -
   773         -4. Compression algorithm details
   774         -
   775         -   While it is the intent of this document to define the "deflate"
   776         -   compressed data format without reference to any particular
   777         -   compression algorithm, the format is related to the compressed
   778         -   formats produced by LZ77 (Lempel-Ziv 1977, see reference [2] below);
   779         -   since many variations of LZ77 are patented, it is strongly
   780         -   recommended that the implementor of a compressor follow the general
   781         -   algorithm presented here, which is known not to be patented per se.
   782         -   The material in this section is not part of the definition of the
   783         -
   784         -
   785         -
   786         -Deutsch                      Informational                     [Page 14]
   787         -
   788         -RFC 1951      DEFLATE Compressed Data Format Specification      May 1996
   789         -
   790         -
   791         -   specification per se, and a compressor need not follow it in order to
   792         -   be compliant.
   793         -
   794         -   The compressor terminates a block when it determines that starting a
   795         -   new block with fresh trees would be useful, or when the block size
   796         -   fills up the compressor's block buffer.
   797         -
   798         -   The compressor uses a chained hash table to find duplicated strings,
   799         -   using a hash function that operates on 3-byte sequences.  At any
   800         -   given point during compression, let XYZ be the next 3 input bytes to
   801         -   be examined (not necessarily all different, of course).  First, the
   802         -   compressor examines the hash chain for XYZ.  If the chain is empty,
   803         -   the compressor simply writes out X as a literal byte and advances one
   804         -   byte in the input.  If the hash chain is not empty, indicating that
   805         -   the sequence XYZ (or, if we are unlucky, some other 3 bytes with the
   806         -   same hash function value) has occurred recently, the compressor
   807         -   compares all strings on the XYZ hash chain with the actual input data
   808         -   sequence starting at the current point, and selects the longest
   809         -   match.
   810         -
   811         -   The compressor searches the hash chains starting with the most recent
   812         -   strings, to favor small distances and thus take advantage of the
   813         -   Huffman encoding.  The hash chains are singly linked. There are no
   814         -   deletions from the hash chains; the algorithm simply discards matches
   815         -   that are too old.  To avoid a worst-case situation, very long hash
   816         -   chains are arbitrarily truncated at a certain length, determined by a
   817         -   run-time parameter.
   818         -
   819         -   To improve overall compression, the compressor optionally defers the
   820         -   selection of matches ("lazy matching"): after a match of length N has
   821         -   been found, the compressor searches for a longer match starting at
   822         -   the next input byte.  If it finds a longer match, it truncates the
   823         -   previous match to a length of one (thus producing a single literal
   824         -   byte) and then emits the longer match.  Otherwise, it emits the
   825         -   original match, and, as described above, advances N bytes before
   826         -   continuing.
   827         -
   828         -   Run-time parameters also control this "lazy match" procedure.  If
   829         -   compression ratio is most important, the compressor attempts a
   830         -   complete second search regardless of the length of the first match.
   831         -   In the normal case, if the current match is "long enough", the
   832         -   compressor reduces the search for a longer match, thus speeding up
   833         -   the process.  If speed is most important, the compressor inserts new
   834         -   strings in the hash table only when no match was found, or when the
   835         -   match is not "too long".  This degrades the compression ratio but
   836         -   saves time since there are both fewer insertions and fewer searches.
   837         -
   838         -
   839         -
   840         -
   841         -
   842         -Deutsch                      Informational                     [Page 15]
   843         -
   844         -RFC 1951      DEFLATE Compressed Data Format Specification      May 1996
   845         -
   846         -
   847         -5. References
   848         -
   849         -   [1] Huffman, D. A., "A Method for the Construction of Minimum
   850         -       Redundancy Codes", Proceedings of the Institute of Radio
   851         -       Engineers, September 1952, Volume 40, Number 9, pp. 1098-1101.
   852         -
   853         -   [2] Ziv J., Lempel A., "A Universal Algorithm for Sequential Data
   854         -       Compression", IEEE Transactions on Information Theory, Vol. 23,
   855         -       No. 3, pp. 337-343.
   856         -
   857         -   [3] Gailly, J.-L., and Adler, M., ZLIB documentation and sources,
   858         -       available in ftp://ftp.uu.net/pub/archiving/zip/doc/
   859         -
   860         -   [4] Gailly, J.-L., and Adler, M., GZIP documentation and sources,
   861         -       available as gzip-*.tar in ftp://prep.ai.mit.edu/pub/gnu/
   862         -
   863         -   [5] Schwartz, E. S., and Kallick, B. "Generating a canonical prefix
   864         -       encoding." Comm. ACM, 7,3 (Mar. 1964), pp. 166-169.
   865         -
   866         -   [6] Hirschberg and Lelewer, "Efficient decoding of prefix codes,"
   867         -       Comm. ACM, 33,4, April 1990, pp. 449-459.
   868         -
   869         -6. Security Considerations
   870         -
   871         -   Any data compression method involves the reduction of redundancy in
   872         -   the data.  Consequently, any corruption of the data is likely to have
   873         -   severe effects and be difficult to correct.  Uncompressed text, on
   874         -   the other hand, will probably still be readable despite the presence
   875         -   of some corrupted bytes.
   876         -
   877         -   It is recommended that systems using this data format provide some
   878         -   means of validating the integrity of the compressed data.  See
   879         -   reference [3], for example.
   880         -
   881         -7. Source code
   882         -
   883         -   Source code for a C language implementation of a "deflate" compliant
   884         -   compressor and decompressor is available within the zlib package at
   885         -   ftp://ftp.uu.net/pub/archiving/zip/zlib/.
   886         -
   887         -8. Acknowledgements
   888         -
   889         -   Trademarks cited in this document are the property of their
   890         -   respective owners.
   891         -
   892         -   Phil Katz designed the deflate format.  Jean-Loup Gailly and Mark
   893         -   Adler wrote the related software described in this specification.
   894         -   Glenn Randers-Pehrson converted this document to RFC and HTML format.
   895         -
   896         -
   897         -
   898         -Deutsch                      Informational                     [Page 16]
   899         -
   900         -RFC 1951      DEFLATE Compressed Data Format Specification      May 1996
   901         -
   902         -
   903         -9. Author's Address
   904         -
   905         -   L. Peter Deutsch
   906         -   Aladdin Enterprises
   907         -   203 Santa Margarita Ave.
   908         -   Menlo Park, CA 94025
   909         -
   910         -   Phone: (415) 322-0103 (AM only)
   911         -   FAX:   (415) 322-1734
   912         -   EMail: <[email protected]>
   913         -
   914         -   Questions about the technical content of this specification can be
   915         -   sent by email to:
   916         -
   917         -   Jean-Loup Gailly <[email protected]> and
   918         -   Mark Adler <[email protected]>
   919         -
   920         -   Editorial comments on this specification can be sent by email to:
   921         -
   922         -   L. Peter Deutsch <[email protected]> and
   923         -   Glenn Randers-Pehrson <[email protected]>
   924         -
   925         -
   926         -
   927         -
   928         -
   929         -
   930         -
   931         -
   932         -
   933         -
   934         -
   935         -
   936         -
   937         -
   938         -
   939         -
   940         -
   941         -
   942         -
   943         -
   944         -
   945         -
   946         -
   947         -
   948         -
   949         -
   950         -
   951         -
   952         -
   953         -
   954         -Deutsch                      Informational                     [Page 17]
   955         -

Deleted compat/zlib/doc/rfc1952.txt.

     1         -
     2         -
     3         -
     4         -
     5         -
     6         -
     7         -Network Working Group                                         P. Deutsch
     8         -Request for Comments: 1952                           Aladdin Enterprises
     9         -Category: Informational                                         May 1996
    10         -
    11         -
    12         -               GZIP file format specification version 4.3
    13         -
    14         -Status of This Memo
    15         -
    16         -   This memo provides information for the Internet community.  This memo
    17         -   does not specify an Internet standard of any kind.  Distribution of
    18         -   this memo is unlimited.
    19         -
    20         -IESG Note:
    21         -
    22         -   The IESG takes no position on the validity of any Intellectual
    23         -   Property Rights statements contained in this document.
    24         -
    25         -Notices
    26         -
    27         -   Copyright (c) 1996 L. Peter Deutsch
    28         -
    29         -   Permission is granted to copy and distribute this document for any
    30         -   purpose and without charge, including translations into other
    31         -   languages and incorporation into compilations, provided that the
    32         -   copyright notice and this notice are preserved, and that any
    33         -   substantive changes or deletions from the original are clearly
    34         -   marked.
    35         -
    36         -   A pointer to the latest version of this and related documentation in
    37         -   HTML format can be found at the URL
    38         -   <ftp://ftp.uu.net/graphics/png/documents/zlib/zdoc-index.html>.
    39         -
    40         -Abstract
    41         -
    42         -   This specification defines a lossless compressed data format that is
    43         -   compatible with the widely used GZIP utility.  The format includes a
    44         -   cyclic redundancy check value for detecting data corruption.  The
    45         -   format presently uses the DEFLATE method of compression but can be
    46         -   easily extended to use other compression methods.  The format can be
    47         -   implemented readily in a manner not covered by patents.
    48         -
    49         -
    50         -
    51         -
    52         -
    53         -
    54         -
    55         -
    56         -
    57         -
    58         -Deutsch                      Informational                      [Page 1]
    59         -
    60         -RFC 1952             GZIP File Format Specification             May 1996
    61         -
    62         -
    63         -Table of Contents
    64         -
    65         -   1. Introduction ................................................... 2
    66         -      1.1. Purpose ................................................... 2
    67         -      1.2. Intended audience ......................................... 3
    68         -      1.3. Scope ..................................................... 3
    69         -      1.4. Compliance ................................................ 3
    70         -      1.5. Definitions of terms and conventions used ................. 3
    71         -      1.6. Changes from previous versions ............................ 3
    72         -   2. Detailed specification ......................................... 4
    73         -      2.1. Overall conventions ....................................... 4
    74         -      2.2. File format ............................................... 5
    75         -      2.3. Member format ............................................. 5
    76         -          2.3.1. Member header and trailer ........................... 6
    77         -              2.3.1.1. Extra field ................................... 8
    78         -              2.3.1.2. Compliance .................................... 9
    79         -      3. References .................................................. 9
    80         -      4. Security Considerations .................................... 10
    81         -      5. Acknowledgements ........................................... 10
    82         -      6. Author's Address ........................................... 10
    83         -      7. Appendix: Jean-Loup Gailly's gzip utility .................. 11
    84         -      8. Appendix: Sample CRC Code .................................. 11
    85         -
    86         -1. Introduction
    87         -
    88         -   1.1. Purpose
    89         -
    90         -      The purpose of this specification is to define a lossless
    91         -      compressed data format that:
    92         -
    93         -          * Is independent of CPU type, operating system, file system,
    94         -            and character set, and hence can be used for interchange;
    95         -          * Can compress or decompress a data stream (as opposed to a
    96         -            randomly accessible file) to produce another data stream,
    97         -            using only an a priori bounded amount of intermediate
    98         -            storage, and hence can be used in data communications or
    99         -            similar structures such as Unix filters;
   100         -          * Compresses data with efficiency comparable to the best
   101         -            currently available general-purpose compression methods,
   102         -            and in particular considerably better than the "compress"
   103         -            program;
   104         -          * Can be implemented readily in a manner not covered by
   105         -            patents, and hence can be practiced freely;
   106         -          * Is compatible with the file format produced by the current
   107         -            widely used gzip utility, in that conforming decompressors
   108         -            will be able to read data produced by the existing gzip
   109         -            compressor.
   110         -
   111         -
   112         -
   113         -
   114         -Deutsch                      Informational                      [Page 2]
   115         -
   116         -RFC 1952             GZIP File Format Specification             May 1996
   117         -
   118         -
   119         -      The data format defined by this specification does not attempt to:
   120         -
   121         -          * Provide random access to compressed data;
   122         -          * Compress specialized data (e.g., raster graphics) as well as
   123         -            the best currently available specialized algorithms.
   124         -
   125         -   1.2. Intended audience
   126         -
   127         -      This specification is intended for use by implementors of software
   128         -      to compress data into gzip format and/or decompress data from gzip
   129         -      format.
   130         -
   131         -      The text of the specification assumes a basic background in
   132         -      programming at the level of bits and other primitive data
   133         -      representations.
   134         -
   135         -   1.3. Scope
   136         -
   137         -      The specification specifies a compression method and a file format
   138         -      (the latter assuming only that a file can store a sequence of
   139         -      arbitrary bytes).  It does not specify any particular interface to
   140         -      a file system or anything about character sets or encodings
   141         -      (except for file names and comments, which are optional).
   142         -
   143         -   1.4. Compliance
   144         -
   145         -      Unless otherwise indicated below, a compliant decompressor must be
   146         -      able to accept and decompress any file that conforms to all the
   147         -      specifications presented here; a compliant compressor must produce
   148         -      files that conform to all the specifications presented here.  The
   149         -      material in the appendices is not part of the specification per se
   150         -      and is not relevant to compliance.
   151         -
   152         -   1.5. Definitions of terms and conventions used
   153         -
   154         -      byte: 8 bits stored or transmitted as a unit (same as an octet).
   155         -      (For this specification, a byte is exactly 8 bits, even on
   156         -      machines which store a character on a number of bits different
   157         -      from 8.)  See below for the numbering of bits within a byte.
   158         -
   159         -   1.6. Changes from previous versions
   160         -
   161         -      There have been no technical changes to the gzip format since
   162         -      version 4.1 of this specification.  In version 4.2, some
   163         -      terminology was changed, and the sample CRC code was rewritten for
   164         -      clarity and to eliminate the requirement for the caller to do pre-
   165         -      and post-conditioning.  Version 4.3 is a conversion of the
   166         -      specification to RFC style.
   167         -
   168         -
   169         -
   170         -Deutsch                      Informational                      [Page 3]
   171         -
   172         -RFC 1952             GZIP File Format Specification             May 1996
   173         -
   174         -
   175         -2. Detailed specification
   176         -
   177         -   2.1. Overall conventions
   178         -
   179         -      In the diagrams below, a box like this:
   180         -
   181         -         +---+
   182         -         |   | <-- the vertical bars might be missing
   183         -         +---+
   184         -
   185         -      represents one byte; a box like this:
   186         -
   187         -         +==============+
   188         -         |              |
   189         -         +==============+
   190         -
   191         -      represents a variable number of bytes.
   192         -
   193         -      Bytes stored within a computer do not have a "bit order", since
   194         -      they are always treated as a unit.  However, a byte considered as
   195         -      an integer between 0 and 255 does have a most- and least-
   196         -      significant bit, and since we write numbers with the most-
   197         -      significant digit on the left, we also write bytes with the most-
   198         -      significant bit on the left.  In the diagrams below, we number the
   199         -      bits of a byte so that bit 0 is the least-significant bit, i.e.,
   200         -      the bits are numbered:
   201         -
   202         -         +--------+
   203         -         |76543210|
   204         -         +--------+
   205         -
   206         -      This document does not address the issue of the order in which
   207         -      bits of a byte are transmitted on a bit-sequential medium, since
   208         -      the data format described here is byte- rather than bit-oriented.
   209         -
   210         -      Within a computer, a number may occupy multiple bytes.  All
   211         -      multi-byte numbers in the format described here are stored with
   212         -      the least-significant byte first (at the lower memory address).
   213         -      For example, the decimal number 520 is stored as:
   214         -
   215         -             0        1
   216         -         +--------+--------+
   217         -         |00001000|00000010|
   218         -         +--------+--------+
   219         -          ^        ^
   220         -          |        |
   221         -          |        + more significant byte = 2 x 256
   222         -          + less significant byte = 8
   223         -
   224         -
   225         -
   226         -Deutsch                      Informational                      [Page 4]
   227         -
   228         -RFC 1952             GZIP File Format Specification             May 1996
   229         -
   230         -
   231         -   2.2. File format
   232         -
   233         -      A gzip file consists of a series of "members" (compressed data
   234         -      sets).  The format of each member is specified in the following
   235         -      section.  The members simply appear one after another in the file,
   236         -      with no additional information before, between, or after them.
   237         -
   238         -   2.3. Member format
   239         -
   240         -      Each member has the following structure:
   241         -
   242         -         +---+---+---+---+---+---+---+---+---+---+
   243         -         |ID1|ID2|CM |FLG|     MTIME     |XFL|OS | (more-->)
   244         -         +---+---+---+---+---+---+---+---+---+---+
   245         -
   246         -      (if FLG.FEXTRA set)
   247         -
   248         -         +---+---+=================================+
   249         -         | XLEN  |...XLEN bytes of "extra field"...| (more-->)
   250         -         +---+---+=================================+
   251         -
   252         -      (if FLG.FNAME set)
   253         -
   254         -         +=========================================+
   255         -         |...original file name, zero-terminated...| (more-->)
   256         -         +=========================================+
   257         -
   258         -      (if FLG.FCOMMENT set)
   259         -
   260         -         +===================================+
   261         -         |...file comment, zero-terminated...| (more-->)
   262         -         +===================================+
   263         -
   264         -      (if FLG.FHCRC set)
   265         -
   266         -         +---+---+
   267         -         | CRC16 |
   268         -         +---+---+
   269         -
   270         -         +=======================+
   271         -         |...compressed blocks...| (more-->)
   272         -         +=======================+
   273         -
   274         -           0   1   2   3   4   5   6   7
   275         -         +---+---+---+---+---+---+---+---+
   276         -         |     CRC32     |     ISIZE     |
   277         -         +---+---+---+---+---+---+---+---+
   278         -
   279         -
   280         -
   281         -
   282         -Deutsch                      Informational                      [Page 5]
   283         -
   284         -RFC 1952             GZIP File Format Specification             May 1996
   285         -
   286         -
   287         -      2.3.1. Member header and trailer
   288         -
   289         -         ID1 (IDentification 1)
   290         -         ID2 (IDentification 2)
   291         -            These have the fixed values ID1 = 31 (0x1f, \037), ID2 = 139
   292         -            (0x8b, \213), to identify the file as being in gzip format.
   293         -
   294         -         CM (Compression Method)
   295         -            This identifies the compression method used in the file.  CM
   296         -            = 0-7 are reserved.  CM = 8 denotes the "deflate"
   297         -            compression method, which is the one customarily used by
   298         -            gzip and which is documented elsewhere.
   299         -
   300         -         FLG (FLaGs)
   301         -            This flag byte is divided into individual bits as follows:
   302         -
   303         -               bit 0   FTEXT
   304         -               bit 1   FHCRC
   305         -               bit 2   FEXTRA
   306         -               bit 3   FNAME
   307         -               bit 4   FCOMMENT
   308         -               bit 5   reserved
   309         -               bit 6   reserved
   310         -               bit 7   reserved
   311         -
   312         -            If FTEXT is set, the file is probably ASCII text.  This is
   313         -            an optional indication, which the compressor may set by
   314         -            checking a small amount of the input data to see whether any
   315         -            non-ASCII characters are present.  In case of doubt, FTEXT
   316         -            is cleared, indicating binary data. For systems which have
   317         -            different file formats for ascii text and binary data, the
   318         -            decompressor can use FTEXT to choose the appropriate format.
   319         -            We deliberately do not specify the algorithm used to set
   320         -            this bit, since a compressor always has the option of
   321         -            leaving it cleared and a decompressor always has the option
   322         -            of ignoring it and letting some other program handle issues
   323         -            of data conversion.
   324         -
   325         -            If FHCRC is set, a CRC16 for the gzip header is present,
   326         -            immediately before the compressed data. The CRC16 consists
   327         -            of the two least significant bytes of the CRC32 for all
   328         -            bytes of the gzip header up to and not including the CRC16.
   329         -            [The FHCRC bit was never set by versions of gzip up to
   330         -            1.2.4, even though it was documented with a different
   331         -            meaning in gzip 1.2.4.]
   332         -
   333         -            If FEXTRA is set, optional extra fields are present, as
   334         -            described in a following section.
   335         -
   336         -
   337         -
   338         -Deutsch                      Informational                      [Page 6]
   339         -
   340         -RFC 1952             GZIP File Format Specification             May 1996
   341         -
   342         -
   343         -            If FNAME is set, an original file name is present,
   344         -            terminated by a zero byte.  The name must consist of ISO
   345         -            8859-1 (LATIN-1) characters; on operating systems using
   346         -            EBCDIC or any other character set for file names, the name
   347         -            must be translated to the ISO LATIN-1 character set.  This
   348         -            is the original name of the file being compressed, with any
   349         -            directory components removed, and, if the file being
   350         -            compressed is on a file system with case insensitive names,
   351         -            forced to lower case. There is no original file name if the
   352         -            data was compressed from a source other than a named file;
   353         -            for example, if the source was stdin on a Unix system, there
   354         -            is no file name.
   355         -
   356         -            If FCOMMENT is set, a zero-terminated file comment is
   357         -            present.  This comment is not interpreted; it is only
   358         -            intended for human consumption.  The comment must consist of
   359         -            ISO 8859-1 (LATIN-1) characters.  Line breaks should be
   360         -            denoted by a single line feed character (10 decimal).
   361         -
   362         -            Reserved FLG bits must be zero.
   363         -
   364         -         MTIME (Modification TIME)
   365         -            This gives the most recent modification time of the original
   366         -            file being compressed.  The time is in Unix format, i.e.,
   367         -            seconds since 00:00:00 GMT, Jan.  1, 1970.  (Note that this
   368         -            may cause problems for MS-DOS and other systems that use
   369         -            local rather than Universal time.)  If the compressed data
   370         -            did not come from a file, MTIME is set to the time at which
   371         -            compression started.  MTIME = 0 means no time stamp is
   372         -            available.
   373         -
   374         -         XFL (eXtra FLags)
   375         -            These flags are available for use by specific compression
   376         -            methods.  The "deflate" method (CM = 8) sets these flags as
   377         -            follows:
   378         -
   379         -               XFL = 2 - compressor used maximum compression,
   380         -                         slowest algorithm
   381         -               XFL = 4 - compressor used fastest algorithm
   382         -
   383         -         OS (Operating System)
   384         -            This identifies the type of file system on which compression
   385         -            took place.  This may be useful in determining end-of-line
   386         -            convention for text files.  The currently defined values are
   387         -            as follows:
   388         -
   389         -
   390         -
   391         -
   392         -
   393         -
   394         -Deutsch                      Informational                      [Page 7]
   395         -
   396         -RFC 1952             GZIP File Format Specification             May 1996
   397         -
   398         -
   399         -                 0 - FAT filesystem (MS-DOS, OS/2, NT/Win32)
   400         -                 1 - Amiga
   401         -                 2 - VMS (or OpenVMS)
   402         -                 3 - Unix
   403         -                 4 - VM/CMS
   404         -                 5 - Atari TOS
   405         -                 6 - HPFS filesystem (OS/2, NT)
   406         -                 7 - Macintosh
   407         -                 8 - Z-System
   408         -                 9 - CP/M
   409         -                10 - TOPS-20
   410         -                11 - NTFS filesystem (NT)
   411         -                12 - QDOS
   412         -                13 - Acorn RISCOS
   413         -               255 - unknown
   414         -
   415         -         XLEN (eXtra LENgth)
   416         -            If FLG.FEXTRA is set, this gives the length of the optional
   417         -            extra field.  See below for details.
   418         -
   419         -         CRC32 (CRC-32)
   420         -            This contains a Cyclic Redundancy Check value of the
   421         -            uncompressed data computed according to CRC-32 algorithm
   422         -            used in the ISO 3309 standard and in section 8.1.1.6.2 of
   423         -            ITU-T recommendation V.42.  (See http://www.iso.ch for
   424         -            ordering ISO documents. See gopher://info.itu.ch for an
   425         -            online version of ITU-T V.42.)
   426         -
   427         -         ISIZE (Input SIZE)
   428         -            This contains the size of the original (uncompressed) input
   429         -            data modulo 2^32.
   430         -
   431         -      2.3.1.1. Extra field
   432         -
   433         -         If the FLG.FEXTRA bit is set, an "extra field" is present in
   434         -         the header, with total length XLEN bytes.  It consists of a
   435         -         series of subfields, each of the form:
   436         -
   437         -            +---+---+---+---+==================================+
   438         -            |SI1|SI2|  LEN  |... LEN bytes of subfield data ...|
   439         -            +---+---+---+---+==================================+
   440         -
   441         -         SI1 and SI2 provide a subfield ID, typically two ASCII letters
   442         -         with some mnemonic value.  Jean-Loup Gailly
   443         -         <[email protected]> is maintaining a registry of subfield
   444         -         IDs; please send him any subfield ID you wish to use.  Subfield
   445         -         IDs with SI2 = 0 are reserved for future use.  The following
   446         -         IDs are currently defined:
   447         -
   448         -
   449         -
   450         -Deutsch                      Informational                      [Page 8]
   451         -
   452         -RFC 1952             GZIP File Format Specification             May 1996
   453         -
   454         -
   455         -            SI1         SI2         Data
   456         -            ----------  ----------  ----
   457         -            0x41 ('A')  0x70 ('P')  Apollo file type information
   458         -
   459         -         LEN gives the length of the subfield data, excluding the 4
   460         -         initial bytes.
   461         -
   462         -      2.3.1.2. Compliance
   463         -
   464         -         A compliant compressor must produce files with correct ID1,
   465         -         ID2, CM, CRC32, and ISIZE, but may set all the other fields in
   466         -         the fixed-length part of the header to default values (255 for
   467         -         OS, 0 for all others).  The compressor must set all reserved
   468         -         bits to zero.
   469         -
   470         -         A compliant decompressor must check ID1, ID2, and CM, and
   471         -         provide an error indication if any of these have incorrect
   472         -         values.  It must examine FEXTRA/XLEN, FNAME, FCOMMENT and FHCRC
   473         -         at least so it can skip over the optional fields if they are
   474         -         present.  It need not examine any other part of the header or
   475         -         trailer; in particular, a decompressor may ignore FTEXT and OS
   476         -         and always produce binary output, and still be compliant.  A
   477         -         compliant decompressor must give an error indication if any
   478         -         reserved bit is non-zero, since such a bit could indicate the
   479         -         presence of a new field that would cause subsequent data to be
   480         -         interpreted incorrectly.
   481         -
   482         -3. References
   483         -
   484         -   [1] "Information Processing - 8-bit single-byte coded graphic
   485         -       character sets - Part 1: Latin alphabet No.1" (ISO 8859-1:1987).
   486         -       The ISO 8859-1 (Latin-1) character set is a superset of 7-bit
   487         -       ASCII. Files defining this character set are available as
   488         -       iso_8859-1.* in ftp://ftp.uu.net/graphics/png/documents/
   489         -
   490         -   [2] ISO 3309
   491         -
   492         -   [3] ITU-T recommendation V.42
   493         -
   494         -   [4] Deutsch, L.P.,"DEFLATE Compressed Data Format Specification",
   495         -       available in ftp://ftp.uu.net/pub/archiving/zip/doc/
   496         -
   497         -   [5] Gailly, J.-L., GZIP documentation, available as gzip-*.tar in
   498         -       ftp://prep.ai.mit.edu/pub/gnu/
   499         -
   500         -   [6] Sarwate, D.V., "Computation of Cyclic Redundancy Checks via Table
   501         -       Look-Up", Communications of the ACM, 31(8), pp.1008-1013.
   502         -
   503         -
   504         -
   505         -
   506         -Deutsch                      Informational                      [Page 9]
   507         -
   508         -RFC 1952             GZIP File Format Specification             May 1996
   509         -
   510         -
   511         -   [7] Schwaderer, W.D., "CRC Calculation", April 85 PC Tech Journal,
   512         -       pp.118-133.
   513         -
   514         -   [8] ftp://ftp.adelaide.edu.au/pub/rocksoft/papers/crc_v3.txt,
   515         -       describing the CRC concept.
   516         -
   517         -4. Security Considerations
   518         -
   519         -   Any data compression method involves the reduction of redundancy in
   520         -   the data.  Consequently, any corruption of the data is likely to have
   521         -   severe effects and be difficult to correct.  Uncompressed text, on
   522         -   the other hand, will probably still be readable despite the presence
   523         -   of some corrupted bytes.
   524         -
   525         -   It is recommended that systems using this data format provide some
   526         -   means of validating the integrity of the compressed data, such as by
   527         -   setting and checking the CRC-32 check value.
   528         -
   529         -5. Acknowledgements
   530         -
   531         -   Trademarks cited in this document are the property of their
   532         -   respective owners.
   533         -
   534         -   Jean-Loup Gailly designed the gzip format and wrote, with Mark Adler,
   535         -   the related software described in this specification.  Glenn
   536         -   Randers-Pehrson converted this document to RFC and HTML format.
   537         -
   538         -6. Author's Address
   539         -
   540         -   L. Peter Deutsch
   541         -   Aladdin Enterprises
   542         -   203 Santa Margarita Ave.
   543         -   Menlo Park, CA 94025
   544         -
   545         -   Phone: (415) 322-0103 (AM only)
   546         -   FAX:   (415) 322-1734
   547         -   EMail: <[email protected]>
   548         -
   549         -   Questions about the technical content of this specification can be
   550         -   sent by email to:
   551         -
   552         -   Jean-Loup Gailly <[email protected]> and
   553         -   Mark Adler <[email protected]>
   554         -
   555         -   Editorial comments on this specification can be sent by email to:
   556         -
   557         -   L. Peter Deutsch <[email protected]> and
   558         -   Glenn Randers-Pehrson <[email protected]>
   559         -
   560         -
   561         -
   562         -Deutsch                      Informational                     [Page 10]
   563         -
   564         -RFC 1952             GZIP File Format Specification             May 1996
   565         -
   566         -
   567         -7. Appendix: Jean-Loup Gailly's gzip utility
   568         -
   569         -   The most widely used implementation of gzip compression, and the
   570         -   original documentation on which this specification is based, were
   571         -   created by Jean-Loup Gailly <[email protected]>.  Since this
   572         -   implementation is a de facto standard, we mention some more of its
   573         -   features here.  Again, the material in this section is not part of
   574         -   the specification per se, and implementations need not follow it to
   575         -   be compliant.
   576         -
   577         -   When compressing or decompressing a file, gzip preserves the
   578         -   protection, ownership, and modification time attributes on the local
   579         -   file system, since there is no provision for representing protection
   580         -   attributes in the gzip file format itself.  Since the file format
   581         -   includes a modification time, the gzip decompressor provides a
   582         -   command line switch that assigns the modification time from the file,
   583         -   rather than the local modification time of the compressed input, to
   584         -   the decompressed output.
   585         -
   586         -8. Appendix: Sample CRC Code
   587         -
   588         -   The following sample code represents a practical implementation of
   589         -   the CRC (Cyclic Redundancy Check). (See also ISO 3309 and ITU-T V.42
   590         -   for a formal specification.)
   591         -
   592         -   The sample code is in the ANSI C programming language. Non C users
   593         -   may find it easier to read with these hints:
   594         -
   595         -      &      Bitwise AND operator.
   596         -      ^      Bitwise exclusive-OR operator.
   597         -      >>     Bitwise right shift operator. When applied to an
   598         -             unsigned quantity, as here, right shift inserts zero
   599         -             bit(s) at the left.
   600         -      !      Logical NOT operator.
   601         -      ++     "n++" increments the variable n.
   602         -      0xNNN  0x introduces a hexadecimal (base 16) constant.
   603         -             Suffix L indicates a long value (at least 32 bits).
   604         -
   605         -      /* Table of CRCs of all 8-bit messages. */
   606         -      unsigned long crc_table[256];
   607         -
   608         -      /* Flag: has the table been computed? Initially false. */
   609         -      int crc_table_computed = 0;
   610         -
   611         -      /* Make the table for a fast CRC. */
   612         -      void make_crc_table(void)
   613         -      {
   614         -        unsigned long c;
   615         -
   616         -
   617         -
   618         -Deutsch                      Informational                     [Page 11]
   619         -
   620         -RFC 1952             GZIP File Format Specification             May 1996
   621         -
   622         -
   623         -        int n, k;
   624         -        for (n = 0; n < 256; n++) {
   625         -          c = (unsigned long) n;
   626         -          for (k = 0; k < 8; k++) {
   627         -            if (c & 1) {
   628         -              c = 0xedb88320L ^ (c >> 1);
   629         -            } else {
   630         -              c = c >> 1;
   631         -            }
   632         -          }
   633         -          crc_table[n] = c;
   634         -        }
   635         -        crc_table_computed = 1;
   636         -      }
   637         -
   638         -      /*
   639         -         Update a running crc with the bytes buf[0..len-1] and return
   640         -       the updated crc. The crc should be initialized to zero. Pre- and
   641         -       post-conditioning (one's complement) is performed within this
   642         -       function so it shouldn't be done by the caller. Usage example:
   643         -
   644         -         unsigned long crc = 0L;
   645         -
   646         -         while (read_buffer(buffer, length) != EOF) {
   647         -           crc = update_crc(crc, buffer, length);
   648         -         }
   649         -         if (crc != original_crc) error();
   650         -      */
   651         -      unsigned long update_crc(unsigned long crc,
   652         -                      unsigned char *buf, int len)
   653         -      {
   654         -        unsigned long c = crc ^ 0xffffffffL;
   655         -        int n;
   656         -
   657         -        if (!crc_table_computed)
   658         -          make_crc_table();
   659         -        for (n = 0; n < len; n++) {
   660         -          c = crc_table[(c ^ buf[n]) & 0xff] ^ (c >> 8);
   661         -        }
   662         -        return c ^ 0xffffffffL;
   663         -      }
   664         -
   665         -      /* Return the CRC of the bytes buf[0..len-1]. */
   666         -      unsigned long crc(unsigned char *buf, int len)
   667         -      {
   668         -        return update_crc(0L, buf, len);
   669         -      }
   670         -
   671         -
   672         -
   673         -
   674         -Deutsch                      Informational                     [Page 12]
   675         -

Deleted compat/zlib/doc/txtvsbin.txt.

     1         -A Fast Method for Identifying Plain Text Files
     2         -==============================================
     3         -
     4         -
     5         -Introduction
     6         -------------
     7         -
     8         -Given a file coming from an unknown source, it is sometimes desirable
     9         -to find out whether the format of that file is plain text.  Although
    10         -this may appear like a simple task, a fully accurate detection of the
    11         -file type requires heavy-duty semantic analysis on the file contents.
    12         -It is, however, possible to obtain satisfactory results by employing
    13         -various heuristics.
    14         -
    15         -Previous versions of PKZip and other zip-compatible compression tools
    16         -were using a crude detection scheme: if more than 80% (4/5) of the bytes
    17         -found in a certain buffer are within the range [7..127], the file is
    18         -labeled as plain text, otherwise it is labeled as binary.  A prominent
    19         -limitation of this scheme is the restriction to Latin-based alphabets.
    20         -Other alphabets, like Greek, Cyrillic or Asian, make extensive use of
    21         -the bytes within the range [128..255], and texts using these alphabets
    22         -are most often misidentified by this scheme; in other words, the rate
    23         -of false negatives is sometimes too high, which means that the recall
    24         -is low.  Another weakness of this scheme is a reduced precision, due to
    25         -the false positives that may occur when binary files containing large
    26         -amounts of textual characters are misidentified as plain text.
    27         -
    28         -In this article we propose a new, simple detection scheme that features
    29         -a much increased precision and a near-100% recall.  This scheme is
    30         -designed to work on ASCII, Unicode and other ASCII-derived alphabets,
    31         -and it handles single-byte encodings (ISO-8859, MacRoman, KOI8, etc.)
    32         -and variable-sized encodings (ISO-2022, UTF-8, etc.).  Wider encodings
    33         -(UCS-2/UTF-16 and UCS-4/UTF-32) are not handled, however.
    34         -
    35         -
    36         -The Algorithm
    37         --------------
    38         -
    39         -The algorithm works by dividing the set of bytecodes [0..255] into three
    40         -categories:
    41         -- The white list of textual bytecodes:
    42         -  9 (TAB), 10 (LF), 13 (CR), 32 (SPACE) to 255.
    43         -- The gray list of tolerated bytecodes:
    44         -  7 (BEL), 8 (BS), 11 (VT), 12 (FF), 26 (SUB), 27 (ESC).
    45         -- The black list of undesired, non-textual bytecodes:
    46         -  0 (NUL) to 6, 14 to 31.
    47         -
    48         -If a file contains at least one byte that belongs to the white list and
    49         -no byte that belongs to the black list, then the file is categorized as
    50         -plain text; otherwise, it is categorized as binary.  (The boundary case,
    51         -when the file is empty, automatically falls into the latter category.)
    52         -
    53         -
    54         -Rationale
    55         ----------
    56         -
    57         -The idea behind this algorithm relies on two observations.
    58         -
    59         -The first observation is that, although the full range of 7-bit codes
    60         -[0..127] is properly specified by the ASCII standard, most control
    61         -characters in the range [0..31] are not used in practice.  The only
    62         -widely-used, almost universally-portable control codes are 9 (TAB),
    63         -10 (LF) and 13 (CR).  There are a few more control codes that are
    64         -recognized on a reduced range of platforms and text viewers/editors:
    65         -7 (BEL), 8 (BS), 11 (VT), 12 (FF), 26 (SUB) and 27 (ESC); but these
    66         -codes are rarely (if ever) used alone, without being accompanied by
    67         -some printable text.  Even the newer, portable text formats such as
    68         -XML avoid using control characters outside the list mentioned here.
    69         -
    70         -The second observation is that most of the binary files tend to contain
    71         -control characters, especially 0 (NUL).  Even though the older text
    72         -detection schemes observe the presence of non-ASCII codes from the range
    73         -[128..255], the precision rarely has to suffer if this upper range is
    74         -labeled as textual, because the files that are genuinely binary tend to
    75         -contain both control characters and codes from the upper range.  On the
    76         -other hand, the upper range needs to be labeled as textual, because it
    77         -is used by virtually all ASCII extensions.  In particular, this range is
    78         -used for encoding non-Latin scripts.
    79         -
    80         -Since there is no counting involved, other than simply observing the
    81         -presence or the absence of some byte values, the algorithm produces
    82         -consistent results, regardless what alphabet encoding is being used.
    83         -(If counting were involved, it could be possible to obtain different
    84         -results on a text encoded, say, using ISO-8859-16 versus UTF-8.)
    85         -
    86         -There is an extra category of plain text files that are "polluted" with
    87         -one or more black-listed codes, either by mistake or by peculiar design
    88         -considerations.  In such cases, a scheme that tolerates a small fraction
    89         -of black-listed codes would provide an increased recall (i.e. more true
    90         -positives).  This, however, incurs a reduced precision overall, since
    91         -false positives are more likely to appear in binary files that contain
    92         -large chunks of textual data.  Furthermore, "polluted" plain text should
    93         -be regarded as binary by general-purpose text detection schemes, because
    94         -general-purpose text processing algorithms might not be applicable.
    95         -Under this premise, it is safe to say that our detection method provides
    96         -a near-100% recall.
    97         -
    98         -Experiments have been run on many files coming from various platforms
    99         -and applications.  We tried plain text files, system logs, source code,
   100         -formatted office documents, compiled object code, etc.  The results
   101         -confirm the optimistic assumptions about the capabilities of this
   102         -algorithm.
   103         -
   104         -
   105         ---
   106         -Cosmin Truta
   107         -Last updated: 2006-May-28

Changes to doc/Encoding.3.

   256    256   \fBTcl_ExternalToUtf\fR.
   257    257   .PP
   258    258   \fBTcl_WinUtfToTChar\fR and \fBTcl_WinTCharToUtf\fR are
   259    259   Windows-only convenience
   260    260   functions for converting between UTF-8 and Windows strings
   261    261   based on the TCHAR type which is by convention
   262    262   a Unicode character on Windows NT.
   263         -These functions are essentially wrappers around
   264         -\fBTcl_UtfToExternalDString\fR and
   265         -\fBTcl_ExternalToUtfDString\fR that convert to and from the
   266         -Unicode encoding.
   267    263   .PP
   268    264   \fBTcl_GetEncodingName\fR is roughly the inverse of \fBTcl_GetEncoding\fR.
   269    265   Given an \fIencoding\fR, the return value is the \fIname\fR argument that
   270    266   was used to create the encoding.  The string returned by
   271    267   \fBTcl_GetEncodingName\fR is only guaranteed to persist until the
   272    268   \fIencoding\fR is deleted.  The caller must not modify this string.
   273    269   .PP

Changes to doc/Eval.3.

   172    172   \fBTCL_EVAL_DIRECT\fR flag is useful in situations where the
   173    173   contents of a value are going to change immediately, so the
   174    174   bytecodes will not be reused in a future execution.  In this case,
   175    175   it is faster to execute the script directly.
   176    176   .TP 23
   177    177   \fBTCL_EVAL_GLOBAL\fR
   178    178   .
   179         -If this flag is set, the script is processed at global level.  This
   180         -means that it is evaluated in the global namespace and its variable
   181         -context consists of global variables only (it ignores any Tcl
   182         -procedures that are active).
          179  +If this flag is set, the script is evaluated in the global namespace instead of
          180  +the current namespace and its variable context consists of global variables
          181  +only (it ignores any Tcl procedures that are active).
          182  +.\" TODO: document TCL_EVAL_INVOKE and TCL_EVAL_NOERR.
   183    183   
   184    184   .SH "MISCELLANEOUS DETAILS"
   185    185   .PP
   186    186   During the processing of a Tcl command it is legal to make nested
   187    187   calls to evaluate other commands (this is how procedures and
   188    188   some control structures are implemented).
   189    189   If a code other than \fBTCL_OK\fR is returned

Changes to doc/GetInt.3.

    53     53   \fBTcl_GetInt\fR expects \fIsrc\fR to consist of a collection
    54     54   of integer digits, optionally signed and optionally preceded and
    55     55   followed by white space.  If the first two characters of \fIsrc\fR
    56     56   after the optional white space and sign are
    57     57   .QW \fB0x\fR
    58     58   then \fIsrc\fR is expected to be in hexadecimal form;  otherwise,
    59     59   if the first such characters are
           60  +.QW \fB0d\fR
           61  +then \fIsrc\fR is expected to be in decimal form; otherwise,
           62  +if the first such characters are
    60     63   .QW \fB0o\fR
    61     64   then \fIsrc\fR is expected to be in octal form;  otherwise,
    62     65   if the first such characters are
    63     66   .QW \fB0b\fR
    64     67   then \fIsrc\fR is expected to be in binary form;  otherwise,
    65     68   if the first such character is
    66     69   .QW \fB0\fR
    67     70   then \fIsrc\fR
    68         -is expected to be in octal form;  otherwise, \fIsrc\fR is
    69         -expected to be in decimal form.
           71  +is expected to be in octal form;  otherwise, \fIsrc\fR
           72  +is expected to be in decimal form.
    70     73   .PP
    71     74   \fBTcl_GetDouble\fR expects \fIsrc\fR to consist of a floating-point
    72     75   number, which is:  white space;  a sign; a sequence of digits;  a
    73     76   decimal point
    74     77   .QW \fB.\fR ;
    75     78   a sequence of digits;  the letter
    76     79   .QW \fBe\fR ;

Changes to doc/IntObj.3.

    93     93   with which values might be exchanged.  The C integral types for which Tcl
    94     94   provides value exchange routines are \fBint\fR, \fBlong int\fR,
    95     95   \fBTcl_WideInt\fR, and \fBmp_int\fR.  The \fBint\fR and \fBlong int\fR types
    96     96   are provided by the C language standard.  The \fBTcl_WideInt\fR type is a
    97     97   typedef defined to be whatever signed integral type covers at least the
    98     98   64-bit integer range (-9223372036854775808 to 9223372036854775807).  Depending
    99     99   on the platform and the C compiler, the actual type might be
   100         -\fBlong int\fR, \fBlong long int\fR, \fBint64\fR, or something else.
          100  +\fBlong long int\fR, \fB__int64\fR, or something else.
   101    101   The \fBmp_int\fR type is a multiple-precision integer type defined
   102    102   by the LibTomMath multiple-precision integer library.
   103    103   .PP
   104    104   The \fBTcl_NewIntObj\fR, \fBTcl_NewLongObj\fR, \fBTcl_NewWideIntObj\fR,
   105    105   and \fBTcl_NewBignumObj\fR routines each create and return a new
   106    106   Tcl value initialized to the integral value of the argument.  The
   107    107   returned Tcl value is unshared.

Changes to doc/Interp.3.

    97     97   As part of processing each command, \fBTcl_Eval\fR initializes
    98     98   \fIinterp->result\fR
    99     99   and \fIinterp->freeProc\fR just before calling the command procedure for
   100    100   the command.  The \fIfreeProc\fR field will be initialized to zero,
   101    101   and \fIinterp->result\fR will point to an empty string.  Commands that
   102    102   do not return any value can simply leave the fields alone.
   103    103   Furthermore, the empty string pointed to by \fIresult\fR is actually
   104         -part of an array of \fBTCL_RESULT_SIZE\fR characters (approximately 200).
          104  +part of an array of approximately 200 characters.
   105    105   If a command wishes to return a short string, it can simply copy
   106    106   it to the area pointed to by \fIinterp->result\fR.  Or, it can use
   107    107   the sprintf procedure to generate a short result string at the location
   108    108   pointed to by \fIinterp->result\fR.
   109    109   .PP
   110    110   It is a general convention in Tcl-based applications that the result
   111    111   of an interpreter is normally in the initialized state described

Changes to doc/NRE.3.

     1      1   .\"
     2      2   .\" Copyright (c) 2008 by Kevin B. Kenny.
            3  +.\" Copyright (c) 2018 by Nathan Coulter. 
     3      4   .\"
     4      5   '\" See the file "license.terms" for information on usage and redistribution
     5      6   '\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
     6      7   '\"
     7      8   .TH NRE 3 8.6 Tcl "Tcl Library Procedures"
     8      9   .so man.macros
     9     10   .BS
................................................................................
    34     35   .sp
    35     36   void
    36     37   \fBTcl_NRAddCallback\fR(\fIinterp, postProcPtr, data0, data1, data2, data3\fR)
    37     38   .fi
    38     39   .SH ARGUMENTS
    39     40   .AS Tcl_CmdDeleteProc *interp in
    40     41   .AP Tcl_Interp *interp in
    41         -Interpreter in which to create or evaluate a command.
           42  +The relevant Interpreter.
    42     43   .AP char *cmdName in
    43         -Name of a new command to create.
           44  +Name of the command to create.
    44     45   .AP Tcl_ObjCmdProc *proc in
    45         -Implementation of a command that will be called whenever \fIcmdName\fR
    46         -is invoked as a command in the unoptimized way.
           46  +Called in order to evaluate a command.  Is often just a small wrapper that uses
           47  +\fBTcl_NRCallObjProc\fR to call \fInreProc\fR using a new trampoline.  Behaves
           48  +in the same way as the \fIproc\fR argument to \fBTcl_CreateObjCommand\fR(3)
           49  +(\fIq.v.\fR).
    47     50   .AP Tcl_ObjCmdProc *nreProc in
    48         -Implementation of a command that will be called whenever \fIcmdName\fR
    49         -is invoked and requested to conserve the C stack.
           51  +Called instead of \fIproc\fR when a trampoline is already in use.
    50     52   .AP ClientData clientData in
    51         -Arbitrary one-word value that will be passed to \fIproc\fR, \fInreProc\fR,
    52         -\fIdeleteProc\fR and \fIobjProc\fR.
           53  +Arbitrary one-word value passed to \fIproc\fR, \fInreProc\fR, \fIdeleteProc\fR
           54  +and \fIobjProc\fR.
    53     55   .AP Tcl_CmdDeleteProc *deleteProc in/out
    54         -Procedure to call before \fIcmdName\fR is deleted from the interpreter.
    55         -This procedure allows for command-specific cleanup. If \fIdeleteProc\fR
    56         -is \fBNULL\fR, then no procedure is called before the command is deleted.
           56  +Called before \fIcmdName\fR is deleted from the interpreter, allowing for
           57  +command-specific cleanup. May be NULL.
    57     58   .AP int objc in
    58         -Count of parameters provided to the implementation of a command.
           59  +Number of items in \fIobjv\fR.
    59     60   .AP Tcl_Obj **objv in
    60         -Pointer to an array of Tcl values. Each value holds the value of a
    61         -single word in the command to execute.
           61  +Words in the command.
    62     62   .AP Tcl_Obj *objPtr in
    63         -Pointer to a Tcl_Obj whose value is a script or expression to execute.
           63  +A script or expression to evaluate.
    64     64   .AP int flags in
    65         -ORed combination of flag bits that specify additional options.
    66         -\fBTCL_EVAL_GLOBAL\fR is the only flag that is currently supported.
    67         -.\" TODO: This is a lie. But kbk didn't grasp TCL_EVAL_INVOKE and
    68         -.\"       TCL_EVAL_NOERR well enough to document them.
           65  +As described for \fITcl_EvalObjv\fR.
           66  +.PP
    69     67   .AP Tcl_Command cmd in
    70         -Token for a command that is to be used instead of the currently
    71         -executing command.
           68  +Token to use instead of one derived from the first word of \fIobjv\fR in order
           69  +to evaluate a command.
    72     70   .AP Tcl_Obj *resultPtr out
    73         -Pointer to an unshared Tcl_Obj where the result of expression
    74         -evaluation is written.
           71  +Pointer to an unshared Tcl_Obj where the result of the evaluation is stored if
           72  +the return code is TCL_OK.
    75     73   .AP Tcl_NRPostProc *postProcPtr in
    76         -Pointer to a function that will be invoked when the command currently
    77         -executing in the interpreter designated by \fIinterp\fR completes.
           74  +A function to push.
    78     75   .AP ClientData data0 in
    79     76   .AP ClientData data1 in
    80     77   .AP ClientData data2 in
    81     78   .AP ClientData data3 in
    82     79   \fIdata0\fR through \fIdata3\fR are four one-word values that will be passed
    83     80   to the function designated by \fIpostProcPtr\fR when it is invoked.
    84     81   .BE
    85     82   .SH DESCRIPTION
    86     83   .PP
    87         -This series of C functions provides an interface whereby commands that
    88         -are implemented in C can be evaluated, and invoke Tcl commands scripts
    89         -and scripts, without consuming space on the C stack. The non-recursive
    90         -evaluation is done by installing a \fItrampoline\fR, a small piece of
    91         -code that invokes a command or script, and then executes a series of
    92         -callbacks when the command or script returns.
    93         -.PP
    94         -The \fBTcl_NRCreateCommand\fR function creates a Tcl command in the
    95         -interpreter designated by \fIinterp\fR that is prepared to handle
    96         -nonrecursive evaluation with a trampoline. The \fIcmdName\fR argument
    97         -gives the name of the new command. If \fIcmdName\fR contains any
    98         -namespace qualifiers, then the new command is added to the specified
    99         -namespace; otherwise, it is added to the global namespace. \fIproc\fR
   100         -gives the procedure that will be called when the interpreter wishes to
   101         -evaluate the command in an unoptimized manner, and \fInreProc\fR is
   102         -the procedure that will be called when the interpreter wishes to
   103         -evaluate the command using a trampoline. \fIdeleteProc\fR is a
   104         -function that will be called before the command is deleted from the
   105         -interpreter. When any of the three functions is invoked, it is passed
   106         -the \fIclientData\fR parameter.
   107         -.PP
   108         -\fBTcl_NRCreateCommand\fR deletes any existing command
   109         -\fIname\fR already associated with the interpreter
   110         -(however see below for an exception where the existing command
   111         -is not deleted).
   112         -It returns a token that may be used to refer
   113         -to the command in subsequent calls to \fBTcl_GetCommandName\fR.
   114         -If \fBTcl_NRCreateCommand\fR is called for an interpreter that is in
   115         -the process of being deleted, then it does not create a new command,
   116         -does not delete any existing command of the same name, and returns NULL.
           84  +These functions provide an interface to the function stack that an interpreter
           85  +iterates through to evaluate commands.  The routine behind a command is
           86  +implemented by an initial function and any additional functions that the
           87  +routine pushes onto the stack as it progresses.  The interpreter itself pushes
           88  +functions onto the stack to react to the end of a routine and to exercise other
           89  +forms of control such as switching between in-progress stacks and the
           90  +evaluation of other scripts at additional levels without adding frames to the C
           91  +stack.  To execute a routine, the initial function for the routine is called
           92  +and then a small bit of code called a \fItrampoline\fR iteratively takes
           93  +functions off the stack and calls them, using the value of the last call as the
           94  +value of the routine.
           95  +.PP
           96  +\fBTcl_NRCallObjProc\fR calls \fInreProc\fR using a new trampoline.
           97  +.PP
           98  +\fBTcl_NRCreateCommand\fR, an alternative to \fBTcl_CreateObjCommand\fR,
           99  +resolves \fIcmdName\fR, which may contain namespace qualifiers, relative to the
          100  +current namespace, creates a command by that name, and returns a token for the
          101  +command which may be used in subsequent calls to \fBTcl_GetCommandName\fR.
          102  +Except for a few cases noted below any existing command by the same name is
          103  +first deleted.  If \fIinterp\fR is in the process of being deleted
          104  +\fBTcl_NRCreateCommand\fR does not create any command, does not delete any
          105  +command, and returns NULL.
          106  +.PP
          107  +\fBTcl_NREvalObj\fR pushes a function that is like \fBTcl_EvalObjEx\fR but
          108  +consumes no space on the C stack.
          109  +.PP
          110  +\fBTcl_NREvalObjv\fR pushes a function that is like \fBTcl_EvalObjv\fR but
          111  +consumes no space on the C stack.
          112  +.PP
          113  +\fBTcl_NRCmdSwap\fR is like \fBTcl_NREvalObjv\fR, but uses \fIcmd\fR, a token
          114  +previously returned by \fBTcl_CreateObjCommand\fR or
          115  +\fBTcl_GetCommandFromObj\fR, instead of resolving the first word of \fIobjv\fR.
          116  +.  The name of this command must be the same as \fIobjv[0]\fR.
          117  +.PP
          118  +\fBTcl_NRExprObj\fR pushes a function that evaluates \fIobjPtr\fR as an
          119  +expression in the same manner as \fBTcl_ExprObj\fR but without consuming space
          120  +on the C stack.
   117    121   .PP
   118         -The \fIproc\fR and \fInreProc\fR function are expected to conform to
   119         -all the rules set forth for the \fIproc\fR argument to
   120         -\fBTcl_CreateObjCommand\fR(3) (\fIq.v.\fR).
   121         -.PP
   122         -When a command that is written to cope with evaluation via trampoline
   123         -is invoked without a trampoline on the stack, it will usually respond
   124         -to the invocation by creating a trampoline and calling the
   125         -trampoline-enabled implementation of the same command. This call is done by
   126         -means of \fBTcl_NRCallObjProc\fR. In the call to
   127         -\fBTcl_NRCallObjProc\fR, the \fIinterp\fR, \fIclientData\fR,
   128         -\fIobjc\fR and \fIobjv\fR parameters should be the same ones that were
   129         -passed to \fIproc\fR. The \fInreProc\fR parameter should designate the
   130         -trampoline-enabled implementation of the command.
          122  +All of the functions return \fBTCL_OK\fR if the evaluation of the script,
          123  +command, or expression has been scheduled successfully.  Otherwise (for example
          124  +if the command name cannot be resolved), they return \fBTCL_ERROR\fR and store
          125  +a message as the interpreter's result.
   131    126   .PP
   132         -\fBTcl_NREvalObj\fR arranges for the script contained in \fIobjPtr\fR
   133         -to be evaluated in the interpreter designated by \fIinterp\fR after
   134         -the current command (which must be trampoline-enabled) returns. It is
   135         -the method by which a command may invoke a script without consuming
   136         -space on the C stack. Similarly, \fBTcl_NREvalObjv\fR arranges to
   137         -invoke a single Tcl command whose words have already been separated
   138         -and substituted. The \fIobjc\fR and \fIobjv\fR parameters give the
   139         -words of the command to be evaluated when execution reaches the
   140         -trampoline.
   141         -.PP
   142         -\fBTcl_NRCmdSwap\fR allows for trampoline evaluation of a command whose
   143         -resolution is already known.  The \fIcmd\fR parameter gives a
   144         -\fBTcl_Command\fR token (returned from \fBTcl_CreateObjCommand\fR or
   145         -\fBTcl_GetCommandFromObj\fR) identifying the command to be invoked in
   146         -the trampoline; this command must match the word in \fIobjv[0]\fR.
   147         -The remaining arguments are as for \fBTcl_NREvalObjv\fR.
   148         -.PP
   149         -\fBTcl_NREvalObj\fR, \fBTcl_NREvalObjv\fR and \fBTcl_NRCmdSwap\fR
   150         -all accept a \fIflags\fR parameter, which is an OR-ed-together set of
   151         -bits to control evaluation. At the present time, the only supported flag
   152         -available to callers is \fBTCL_EVAL_GLOBAL\fR.
   153         -.\" TODO: Again, this is a lie. Do we want to explain TCL_EVAL_INVOKE
   154         -.\"       and TCL_EVAL_NOERR?
   155         -If the \fBTCL_EVAL_GLOBAL\fR flag is set, the script or command is
   156         -evaluated in the global namespace. If it is not set, it is evaluated
   157         -in the current namespace.
   158         -.PP
   159         -\fBTcl_NRExprObj\fR arranges for the expression contained in \fIobjPtr\fR
   160         -to be evaluated in the interpreter designated by \fIinterp\fR after
   161         -the current command (which must be trampoline-enabled) returns. It is
   162         -the method by which a command may evaluate a Tcl expression without consuming
   163         -space on the C stack.  The argument \fIresultPtr\fR is a pointer to an
   164         -unshared Tcl_Obj where the result of expression evaluation is to be written.
   165         -If expression evaluation returns any code other than TCL_OK, the
   166         -\fIresultPtr\fR value is left untouched.
   167         -.PP
   168         -All of the routines return \fBTCL_OK\fR if command or expression invocation
   169         -has been scheduled successfully. If for any reason the scheduling cannot
   170         -be completed (for example, if the interpreter is unable to find
   171         -the requested command), they return \fBTCL_ERROR\fR with an
   172         -appropriate message left in the interpreter's result.
   173         -.PP
   174         -\fBTcl_NRAddCallback\fR arranges to have a C function called when the
   175         -current trampoline-enabled command in the Tcl interpreter designated
   176         -by \fIinterp\fR returns.  The \fIpostProcPtr\fR argument is a pointer
   177         -to the callback function, which must have arguments and return value
   178         -consistent with the \fBTcl_NRPostProc\fR data type:
          127  +\fBTcl_NRAddCallback\fR pushes \fIpostProcPtr\fR.  The signature for
          128  +\fBTcl_NRPostProc\fR is:
   179    129   .PP
   180    130   .CS
   181    131   typedef int
   182    132   \fBTcl_NRPostProc\fR(
   183    133           \fBClientData\fR \fIdata\fR[],
   184    134           \fBTcl_Interp\fR *\fIinterp\fR,
   185    135           int \fIresult\fR);
   186    136   .CE
   187    137   .PP
   188         -When the trampoline invokes the callback function, the \fIdata\fR
   189         -parameter will point to an array containing the four one-word
   190         -quantities that were passed to \fBTcl_NRAddCallback\fR in the
   191         -\fIdata0\fR through \fIdata3\fR parameters. The Tcl interpreter will
   192         -be designated by the \fIinterp\fR parameter, and the \fIresult\fR
   193         -parameter will contain the result (\fBTCL_OK\fR, \fBTCL_ERROR\fR,
   194         -\fBTCL_RETURN\fR, \fBTCL_BREAK\fR or \fBTCL_CONTINUE\fR) that was
   195         -returned by the command evaluation. The callback function is expected,
   196         -in turn, either to return a \fIresult\fR to control further evaluation.
   197         -.PP
   198         -Multiple \fBTcl_NRAddCallback\fR invocations may request multiple
   199         -callbacks, which may be to the same or different callback
   200         -functions. If multiple callbacks are requested, they are executed in
   201         -last-in, first-out order, that is, the most recently requested
   202         -callback is executed first.
          138  +\fIdata\fR is a pointer to an array containing \fIdata0\fR through \fIdata3\fR.
          139  +\fIresult\fR is the value returned by the previous function implementing part
          140  +the routine.
   203    141   .SH EXAMPLE
   204    142   .PP
   205         -The usual pattern for Tcl commands that invoke other Tcl commands
   206         -is something like:
          143  +The following command uses \fBTcl_EvalObjEx\fR, which consumes space on the C
          144  +stack, to evalute a script:
   207    145   .PP
   208    146   .CS
   209    147   int
   210    148   \fITheCmdOldObjProc\fR(
   211    149       ClientData clientData,
   212    150       Tcl_Interp *interp,
   213    151       int objc,
................................................................................
   224    162   
   225    163       return result;
   226    164   }
   227    165   \fBTcl_CreateObjCommand\fR(interp, "theCommand",
   228    166           \fITheCmdOldObjProc\fR, clientData, TheCmdDeleteProc);
   229    167   .CE
   230    168   .PP
   231         -To enable a command like this one for trampoline-based evaluation,
   232         -it must be split into three pieces:
   233         -.IP \(bu
   234         -A non-trampoline implementation, \fITheCmdNewObjProc\fR,
   235         -which will simply create a trampoline
   236         -and invoke the trampoline-based implementation.
   237         -.IP \(bu
   238         -A trampoline-enabled implementation, \fITheCmdNRObjProc\fR.  This
   239         -function will perform the initialization, request that the trampoline
   240         -call the postprocessing routine after command evaluation, and finally,
   241         -request that the trampoline call the inner command.
   242         -.IP \(bu
   243         -A postprocessing routine, \fITheCmdPostProc\fR. This function will
   244         -perform the postprocessing formerly done after the return from the
   245         -inner command in \fITheCmdObjProc\fR.
   246         -.PP
   247         -The non-trampoline implementation is simple and stylized, containing
   248         -a single statement:
          169  +To avoid consuming space on the C stack, \fITheCmdOldObjProc\fR is renamed to
          170  +\fITheCmdNRObjProc\fR and the postprocessing step is split into a separate
          171  +function, \fITheCmdPostProc\fR, which is pushed onto the function stack.
          172  +\fITcl_EvalObjEx\fR is replaced with \fITcl_NREvalObj\fR, which uses a
          173  +trampoline instead of consuming space on the C stack.  A new version of
          174  +\fITheCmdOldObjProc\fR is just a a wrapper that uses \fBTcl_NRCallObjProc\fR to
          175  +call \fITheCmdNRObjProc\fR:
   249    176   .PP
   250    177   .CS
   251    178   int
   252         -\fITheCmdNewObjProc\fR(
          179  +\fITheCmdOldObjProc\fR(
   253    180       ClientData clientData,
   254    181       Tcl_Interp *interp,
   255    182       int objc,
   256    183       Tcl_Obj *const objv[])
   257    184   {
   258    185       return \fBTcl_NRCallObjProc\fR(interp, \fITheCmdNRObjProc\fR,
   259    186               clientData, objc, objv);
   260    187   }
   261    188   .CE
   262    189   .PP
   263         -The trampoline-enabled implementation requests postprocessing,
   264         -and returns to the trampoline requesting command evaluation.
   265         -.PP
   266    190   .CS
   267    191   int
   268    192   \fITheCmdNRObjProc\fR
   269    193       ClientData clientData,
   270    194       Tcl_Interp *interp,
   271    195       int objc,
   272    196       Tcl_Obj *const objv[])
................................................................................
   280    204       /* \fIdata0 .. data3\fR are up to four one-word items to
   281    205        * pass to the postprocessing procedure */
   282    206   
   283    207       return \fBTcl_NREvalObj\fR(interp, objPtr, 0);
   284    208   }
   285    209   .CE
   286    210   .PP
   287         -The postprocessing procedure does whatever the original command did
   288         -upon return from the inner evaluation.
   289         -.PP
   290    211   .CS
   291    212   int
   292    213   \fITheCmdNRPostProc\fR(
   293    214       ClientData data[],
   294    215       Tcl_Interp *interp,
   295    216       int result)
   296    217   {
................................................................................
   299    220   
   300    221       \fI... postprocessing ...\fR
   301    222   
   302    223       return result;
   303    224   }
   304    225   .CE
   305    226   .PP
   306         -If \fItheCommand\fR is a command that results in multiple commands or
   307         -scripts being evaluated, its postprocessing routine may schedule
   308         -additional postprocessing and then request another command evaluation
   309         -by means of \fBTcl_NREvalObj\fR or one of the other evaluation
   310         -routines. Looping and sequencing constructs may be implemented in this way.
          227  +Any function comprising a routine can push other functions, making it possible
          228  +implement looping and sequencing constructs using the function stack.
   311    229   .PP
   312         -Finally, to install a trampoline-enabled command in the interpreter,
   313         -\fBTcl_NRCreateCommand\fR is used in place of
   314         -\fBTcl_CreateObjCommand\fR.  It accepts two command procedures instead
   315         -of one. The first is for use when no trampoline is yet on the stack,
   316         -and the second is for use when there is already a trampoline in place.
   317         -.PP
   318         -.CS
   319         -\fBTcl_NRCreateCommand\fR(interp, "theCommand",
   320         -        \fITheCmdNewObjProc\fR, \fITheCmdNRObjProc\fR, clientData,
   321         -        TheCmdDeleteProc);
   322         -.CE
   323    230   .SH "SEE ALSO"
   324    231   Tcl_CreateCommand(3), Tcl_CreateObjCommand(3), Tcl_EvalObjEx(3), Tcl_GetCommandFromObj(3), Tcl_ExprObj(3)
   325    232   .SH KEYWORDS
   326    233   stackless, nonrecursive, execute, command, global, value, result, script
   327    234   .SH COPYRIGHT
   328         -Copyright (c) 2008 by Kevin B. Kenny
          235  +Copyright (c) 2008 by Kevin B. Kenny.
          236  +Copyright (c) 2018 by Nathan Coulter.

Changes to doc/Object.3.

   253    253   \fBincr x\fR
   254    254   .CE
   255    255   .PP
   256    256   The \fBincr\fR command first gets an integer from \fIx\fR's value
   257    257   by calling \fBTcl_GetIntFromObj\fR.
   258    258   This procedure checks whether the value is already an integer value.
   259    259   Since it is not, it converts the value
   260         -by setting the value's \fIinternalRep.longValue\fR member
          260  +by setting the value's internal representation
   261    261   to the integer \fB123\fR
   262    262   and setting the value's \fItypePtr\fR
   263    263   to point to the integer Tcl_ObjType structure.
   264    264   Both representations are now valid.
   265    265   \fBincr\fR increments the value's integer internal representation
   266    266   then invalidates its string representation
   267    267   (by calling \fBTcl_InvalidateStringRep\fR)

Changes to doc/RecEvalObj.3.

    28     28   the command at global level instead of the current stack level.
    29     29   .BE
    30     30   
    31     31   .SH DESCRIPTION
    32     32   .PP
    33     33   \fBTcl_RecordAndEvalObj\fR is invoked to record a command as an event
    34     34   on the history list and then execute it using \fBTcl_EvalObjEx\fR
    35         -(or \fBTcl_GlobalEvalObj\fR if the \fBTCL_EVAL_GLOBAL\fR bit is set
    36         -in \fIflags\fR).
    37     35   It returns a completion code such as \fBTCL_OK\fR just like \fBTcl_EvalObjEx\fR,
    38     36   as well as a result value containing additional information
    39     37   (a result value or error message)
    40     38   that can be retrieved using \fBTcl_GetObjResult\fR.
    41     39   If you do not want the command recorded on the history list then
    42     40   you should invoke \fBTcl_EvalObjEx\fR instead of \fBTcl_RecordAndEvalObj\fR.
    43     41   Normally \fBTcl_RecordAndEvalObj\fR is only called with top-level

Changes to doc/SaveResult.3.

    50     50   value may then be passed back to one of \fBTcl_RestoreInterpState\fR
    51     51   or \fBTcl_DiscardInterpState\fR, depending on whether the interp
    52     52   state is to be restored.  So long as one of the latter two routines
    53     53   is called, Tcl will take care of memory management.
    54     54   .PP
    55     55   The second triplet stores the snapshot of only the interpreter
    56     56   result (not its complete state) in memory allocated by the caller.
    57         -These routines are passed a pointer to a \fBTcl_SavedResult\fR structure
           57  +These routines are passed a pointer to \fBTcl_SavedResult\fR
    58     58   that is used to store enough information to restore the interpreter result.
    59         -This structure can be allocated on the stack of the calling
           59  +\fBTcl_SavedResult\fR can be allocated on the stack of the calling
    60     60   procedure.  These routines do not save the state of any error
    61     61   information in the interpreter (e.g. the \fB\-errorcode\fR or
    62     62   \fB\-errorinfo\fR return options, when an error is in progress).
    63     63   .PP
    64     64   Because the routines \fBTcl_SaveInterpState\fR,
    65     65   \fBTcl_RestoreInterpState\fR, and \fBTcl_DiscardInterpState\fR perform
    66     66   a superset of the functions provided by the other routines,

Changes to doc/ToUpper.3.

    29     29   \fBTcl_UtfToLower\fR(\fIstr\fR)
    30     30   .sp
    31     31   int
    32     32   \fBTcl_UtfToTitle\fR(\fIstr\fR)
    33     33   .SH ARGUMENTS
    34     34   .AS char *str in/out
    35     35   .AP int ch in
    36         -The Tcl_UniChar to be converted.
           36  +The Unicode character to be converted.
    37     37   .AP char *str in/out
    38     38   Pointer to UTF-8 string to be converted in place.
    39     39   .BE
    40     40   
    41     41   .SH DESCRIPTION
    42     42   .PP
    43     43   The first three routines convert the case of individual Unicode characters:

Changes to doc/UniCharIsAlpha.3.

    44     44   \fBTcl_UniCharIsUpper\fR(\fIch\fR)
    45     45   .sp
    46     46   int
    47     47   \fBTcl_UniCharIsWordChar\fR(\fIch\fR)
    48     48   .SH ARGUMENTS
    49     49   .AS int ch
    50     50   .AP int ch in
    51         -The Tcl_UniChar to be examined.
           51  +The Unicode character to be examined.
    52     52   .BE
    53     53   
    54     54   .SH DESCRIPTION
    55     55   .PP
    56         -All of the routines described examine Tcl_UniChars and return a
           56  +All of the routines described examine Unicode characters and return a
    57     57   boolean value. A non-zero return value means that the character does
    58     58   belong to the character class associated with the called routine. The
    59     59   rest of this document just describes the character classes associated
    60     60   with the various routines.
    61         -.PP
    62         -Note: A Tcl_UniChar is a Unicode character represented as an unsigned,
    63         -fixed-size quantity.
    64     61   
    65     62   .SH "CHARACTER CLASSES"
    66     63   .PP
    67     64   \fBTcl_UniCharIsAlnum\fR tests if the character is an alphanumeric Unicode character.
    68     65   .PP
    69     66   \fBTcl_UniCharIsAlpha\fR tests if the character is an alphabetic Unicode character.
    70     67   .PP

Changes to doc/Utf.3.

    73     73   \fBTcl_UtfBackslash\fR(\fIsrc, readPtr, dst\fR)
    74     74   .SH ARGUMENTS
    75     75   .AS "const Tcl_UniChar" *uniPattern in/out
    76     76   .AP char *buf out
    77     77   Buffer in which the UTF-8 representation of the Tcl_UniChar is stored.  At most
    78     78   \fBTCL_UTF_MAX\fR bytes are stored in the buffer.
    79     79   .AP int ch in
    80         -The Tcl_UniChar to be converted or examined.
           80  +The Unicode character to be converted or examined.
    81     81   .AP Tcl_UniChar *chPtr out
    82     82   Filled with the Tcl_UniChar represented by the head of the UTF-8 string.
    83     83   .AP "const char" *src in
    84     84   Pointer to a UTF-8 string.
    85     85   .AP "const char" *cs in
    86     86   Pointer to a UTF-8 string.
    87     87   .AP "const char" *ct in

Changes to doc/continue.n.

    19     19   This command is typically invoked inside the body of a looping command
    20     20   such as \fBfor\fR or \fBforeach\fR or \fBwhile\fR.
    21     21   It returns a 4 (\fBTCL_CONTINUE\fR) result code, which causes a continue
    22     22   exception to occur.
    23     23   The exception causes the current script to be aborted
    24     24   out to the innermost containing loop command, which then
    25     25   continues with the next iteration of the loop.
    26         -Catch exceptions are also handled in a few other situations, such
           26  +Continue exceptions are also handled in a few other situations, such
    27     27   as the \fBcatch\fR command and the outermost scripts of procedure
    28     28   bodies.
    29     29   .SH EXAMPLE
    30     30   .PP
    31     31   Print a line for each of the integers from 0 to 10 \fIexcept\fR 5:
    32     32   .PP
    33     33   .CS

Changes to doc/copy.n.

    10     10   '\" Note:  do not modify the .SH NAME line immediately below!
    11     11   .SH NAME
    12     12   oo::copy \- create copies of objects and classes
    13     13   .SH SYNOPSIS
    14     14   .nf
    15     15   package require TclOO
    16     16   
    17         -\fBoo::copy\fI sourceObject \fR?\fItargetObject\fR?
           17  +\fBoo::copy\fI sourceObject \fR?\fItargetObject\fR? ?\fItargetNamespace\fR?
    18     18   .fi
    19     19   .BE
    20     20   .SH DESCRIPTION
    21     21   .PP
    22     22   The \fBoo::copy\fR command creates a copy of an object or class. It takes the
    23     23   name of the object or class to be copied, \fIsourceObject\fR, and optionally
    24     24   the name of the object or class to create, \fItargetObject\fR, which will be
    25         -resolved relative to the current namespace if not an absolute qualified name.
    26         -If \fItargetObject\fR is omitted, a new name is chosen. The copied object will
    27         -be of the same class as the source object, and will have all its per-object
    28         -methods copied. If it is a class, it will also have all the class methods in
    29         -the class copied, but it will not have any of its instances copied.
           25  +resolved relative to the current namespace if not an absolute qualified name
           26  +and
           27  +.VS TIP473
           28  +\fItargetNamespace\fR which is the name of the namespace that will hold the
           29  +internal state of the object (\fBmy\fR command, etc.); it \fImust not\fR
           30  +refer to an existing namespace.
           31  +If either \fItargetObject\fR or \fItargetNamespace\fR is omitted or is given
           32  +as the empty string, a new name is chosen. Names, unless specified, are
           33  +chosen with the same algorithm used by the \fBnew\fR method of
           34  +\fBoo::class\fR.
           35  +.VE TIP473
           36  +The copied object will be of the same class as the source object, and will have
           37  +all its per-object methods copied. If it is a class, it will also have all the
           38  +class methods in the class copied, but it will not have any of its instances
           39  +copied.
    30     40   .PP
    31     41   .VS
    32     42   After the \fItargetObject\fR has been created and all definitions of its
    33     43   configuration (e.g., methods, filters, mixins) copied, the \fB<cloned>\fR
    34     44   method of \fItargetObject\fR will be invoked, to allow for customization of
    35     45   the created object such as installing related variable traces. The only
    36     46   argument given will be \fIsourceObject\fR. The default implementation of this

Changes to doc/define.n.

   138    138   (except when they have a call chain through the class being modified). Does
   139    139   not change the export status of the method; if it was exported before, it will
   140    140   be afterwards.
   141    141   .TP
   142    142   \fBself\fI subcommand arg ...\fR
   143    143   .TP
   144    144   \fBself\fI script\fR
          145  +.TP
          146  +\fBself\fR
   145    147   .
   146    148   This command is equivalent to calling \fBoo::objdefine\fR on the class being
   147    149   defined (see \fBCONFIGURING OBJECTS\fR below for a description of the
   148    150   supported values of \fIsubcommand\fR). It follows the same general pattern of
   149    151   argument handling as the \fBoo::define\fR and \fBoo::objdefine\fR commands,
   150    152   and
   151    153   .QW "\fBoo::define \fIcls \fBself \fIsubcommand ...\fR"
   152    154   operates identically to
   153    155   .QW "\fBoo::objdefine \fIcls subcommand ...\fR" .
          156  +.RS
          157  +.PP
          158  +.VS TIP470
          159  +If no arguments at all are used, this gives the name of the class currently
          160  +being configured.
          161  +.VE TIP470
          162  +.RE
   154    163   .TP
   155    164   \fBsuperclass\fR ?\fI\-slotOperation\fR? ?\fIclassName ...\fR?
   156    165   .VS
   157    166   This slot (see \fBSLOTTED DEFINITIONS\fR below)
   158    167   .VE
   159    168   allows the alteration of the superclasses of the class being defined.
   160    169   Each \fIclassName\fR argument names one class that is to be a superclass of
................................................................................
   260    269   \fBrenamemethod\fI fromName toName\fR
   261    270   .
   262    271   This renames the method called \fIfromName\fR in an object to \fItoName\fR.
   263    272   The method must have previously existed in the object, and \fItoName\fR must
   264    273   not previously refer to a method in that object. Does not affect the classes
   265    274   that the object is an instance of. Does not change the export status of the
   266    275   method; if it was exported before, it will be afterwards.
          276  +.TP
          277  +\fBself \fR
          278  +.
          279  +.VS TIP470
          280  +This gives the name of the object currently being configured.
          281  +.VE TIP470
   267    282   .TP
   268    283   \fBunexport\fI name \fR?\fIname ...\fR?
   269    284   .
   270    285   This arranges for each of the named methods, \fIname\fR, to be not exported
   271    286   (i.e. not usable outside the object through the object's command, but instead
   272    287   just through the \fBmy\fR command visible in the object's context) by the
   273    288   object being defined. Note that the methods themselves may be actually defined

Changes to doc/dict.n.

   433    433   .CS
   434    434   set foo {foo {a b} bar 2 baz 3}
   435    435   \fBdict with\fR foo {}
   436    436   puts $foo
   437    437   #    prints: \fIa b foo {a b} bar 2 baz 3\fR
   438    438   .CE
   439    439   .SH "SEE ALSO"
   440         -append(n), array(n), foreach(n), mapeach(n), incr(n), list(n), lappend(n), set(n)
          440  +append(n), array(n), foreach(n), incr(n), list(n), lappend(n), lmap(n), set(n)
   441    441   .SH KEYWORDS
   442    442   dictionary, create, update, lookup, iterate, filter, map
   443    443   '\" Local Variables:
   444    444   '\" mode: nroff
   445    445   '\" End:

Changes to doc/expr.n.

    42     42   value is the form produced by the \fB%g\fR format specifier of Tcl's
    43     43   \fBformat\fR command.
    44     44   .SS OPERANDS
    45     45   .PP
    46     46   An expression consists of a combination of operands, operators, parentheses and
    47     47   commas, possibly with whitespace between any of these elements, which is
    48     48   ignored.
    49         -An integer operand may be specified in decimal, binary
           49  +An integer operand may be specified in decimal (the normal case, the optional
           50  +first two characters are \fB0d\fR), binary
    50     51   (the first two characters are \fB0b\fR), octal
    51     52   (the first two characters are \fB0o\fR), or hexadecimal
    52     53   (the first two characters are \fB0x\fR) form.  For
    53     54   compatibility with older Tcl releases, an operand that begins with \fB0\fR is
    54     55   interpreted as an octal integer even if the second character is not \fBo\fR.
    55     56   A floating-point number may be specified in any of several
    56     57   common decimal formats, and may use the decimal point \fB.\fR,

Changes to doc/format.n.

    79     79   number if the first character is not a sign.
    80     80   .TP 10
    81     81   \fB0\fR
    82     82   Specifies that the number should be padded on the left with
    83     83   zeroes instead of spaces.
    84     84   .TP 10
    85     85   \fB#\fR
    86         -Requests an alternate output form. For \fBo\fR and \fBO\fR
    87         -conversions it guarantees that the first digit is always \fB0\fR.
    88         -For \fBx\fR or \fBX\fR conversions, \fB0x\fR or \fB0X\fR (respectively)
           86  +Requests an alternate output form. For \fBo\fR conversions,
           87  +\fB0o\fR will be added to the beginning of the result unless
           88  +it is zero. For \fBx\fR or \fBX\fR conversions, \fB0x\fR
    89     89   will be added to the beginning of the result unless it is zero.
    90     90   For \fBb\fR conversions, \fB0b\fR
    91     91   will be added to the beginning of the result unless it is zero.
           92  +For \fBd\fR conversions, \fB0d\fR there is no effect unless
           93  +the \fB0\fR specifier is used as well: In that case, \fB0d\fR
           94  +will be added to the beginning.
    92     95   For all floating-point conversions (\fBe\fR, \fBE\fR, \fBf\fR,
    93     96   \fBg\fR, and \fBG\fR) it guarantees that the result always
    94     97   has a decimal point.
    95     98   For \fBg\fR and \fBG\fR conversions it specifies that
    96     99   trailing zeroes should not be removed.
    97    100   .SS "OPTIONAL FIELD WIDTH"
    98    101   .PP
................................................................................
   126    129   printed; if the string is longer than this then the trailing characters will be dropped.
   127    130   If the precision is specified with \fB*\fR rather than a number
   128    131   then the next argument to the \fBformat\fR command determines the precision;
   129    132   it must be a numeric string.
   130    133   .SS "OPTIONAL SIZE MODIFIER"
   131    134   .PP
   132    135   The fifth part of a conversion specifier is a size modifier,
   133         -which must be \fBll\fR, \fBh\fR, or \fBl\fR.
          136  +which must be \fBll\fR, \fBh\fR, \fBl\fR, or \fBL\fR.
   134    137   If it is \fBll\fR it specifies that an integer value is taken
   135    138   without truncation for conversion to a formatted substring.
   136    139   If it is \fBh\fR it specifies that an integer value is
   137    140   truncated to a 16-bit range before converting.  This option is rarely useful.
   138    141   If it is \fBl\fR it specifies that the integer value is
   139    142   truncated to the same range as that produced by the \fBwide()\fR
   140    143   function of the \fBexpr\fR command (at least a 64-bit range).
   141         -If neither \fBh\fR nor \fBl\fR are present, the integer value is
          144  +If it is \fBL\fR it specifies that an integer or double value is taken
          145  +without truncation for conversion to a formatted substring.
          146  +If neither \fBh\fR nor \fBl\fR nor \fBL\fR are present, the integer value is
   142    147   truncated to the same range as that produced by the \fBint()\fR
   143    148   function of the \fBexpr\fR command (at least a 32-bit range, but
   144    149   determined by the value of the \fBwordSize\fR element of the
   145    150   \fBtcl_platform\fR array).
   146    151   .SS "MANDATORY CONVERSION TYPE"
   147    152   .PP
   148    153   The last thing in a conversion specifier is an alphabetic character
................................................................................
   165    170   Convert integer to unsigned hexadecimal string, using digits
   166    171   .QW 0123456789abcdef
   167    172   for \fBx\fR and
   168    173   .QW 0123456789ABCDEF
   169    174   for \fBX\fR).
   170    175   .TP 10
   171    176   \fBb\fR
   172         -Convert integer to binary string, using digits 0 and 1.
          177  +Convert integer to unsigned binary string, using digits 0 and 1.
   173    178   .TP 10
   174    179   \fBc\fR
   175    180   Convert integer to the Unicode character it represents.
   176    181   .TP 10
   177    182   \fBs\fR
   178    183   No conversion; just insert string.
   179    184   .TP 10
................................................................................
   194    199   \fBg\fR or \fBG\fR
   195    200   If the exponent is less than \-4 or greater than or equal to the
   196    201   precision, then convert number as for \fB%e\fR or
   197    202   \fB%E\fR.
   198    203   Otherwise convert as for \fB%f\fR.
   199    204   Trailing zeroes and a trailing decimal point are omitted.
   200    205   .TP 10
          206  +\fBa\fR or \fBA\fR
          207  +Convert double to hexadecimal notation in the form
          208  +\fI0x1.yyy\fBp\(+-\fIzz\fR, where the number of \fIy\fR's is
          209  +determined by the precision (default: 13).
          210  +If the \fBA\fR form is used then the hex characters
          211  +are printed in uppercase.
          212  +.TP 10
   201    213   \fB%\fR
   202    214   No conversion: just insert \fB%\fR.
          215  +.TP 10
          216  +\fBp\fR
          217  +Shorthand form for \fB0x%zx\fR, so it outputs the integer in
          218  +hexadecimal form with \fB0x\fR prefix.
   203    219   .SH "DIFFERENCES FROM ANSI SPRINTF"
   204    220   .PP
   205    221   The behavior of the format command is the same as the
   206    222   ANSI C \fBsprintf\fR procedure except for the following
   207    223   differences:
   208    224   .IP [1]
   209    225   Tcl guarantees that it will be working with UNICODE characters.
   210    226   .IP [2]
   211         -\fB%p\fR and \fB%n\fR specifiers are not supported.
          227  +\fB%n\fR specifier is not supported.
   212    228   .IP [3]
   213    229   For \fB%c\fR conversions the argument must be an integer value,
   214    230   which will then be converted to the corresponding character value.
   215    231   .IP [4]
   216    232   The size modifiers are ignored when formatting floating-point values.
   217         -The \fBll\fR modifier has no \fBsprintf\fR counterpart.
   218    233   The \fBb\fR specifier has no \fBsprintf\fR counterpart.
   219    234   .SH EXAMPLES
   220    235   .PP
   221    236   Convert the numeric value of a UNICODE character to the character
   222    237   itself:
   223    238   .PP
   224    239   .CS

Changes to doc/info.n.

   293    293   \fBinfo library\fR
   294    294   .
   295    295   Returns the name of the library directory in which standard Tcl
   296    296   scripts are stored.
   297    297   This is actually the value of the \fBtcl_library\fR
   298    298   variable and may be changed by setting \fBtcl_library\fR.
   299    299   .TP
   300         -\fBinfo loaded \fR?\fIinterp\fR? \fR?\fIpackage\fR?
          300  +\fBinfo loaded \fR?\fIinterp\fR? ?\fIpackage\fR?
   301    301   .
   302    302   Returns the filename loaded as part of \fIpackage\fR. If \fIpackage\fR
   303    303   is not specified, returns a list describing all of the packages
   304    304   that have been loaded into \fIinterp\fR with the \fBload\fR command.
   305    305   Each list element is a sub-list with two elements consisting of the
   306    306   name of the file from which the package was loaded and the name of
   307    307   the package.

Changes to doc/lsearch.n.

   143    143   This option implies \fB\-sorted\fR and cannot be used with either \fB\-all\fR
   144    144   or \fB\-not\fR.
   145    145   .VE 8.6
   146    146   .SS "NESTED LIST OPTIONS"
   147    147   .PP
   148    148   These options are used to search lists of lists.  They may be used
   149    149   with any other options.
          150  +.TP
          151  +\fB\-stride\0\fIstrideLength\fR
          152  +.
          153  +If this option is specified, the list is treated as consisting of
          154  +groups of \fIstrideLength\fR elements and the groups are searched by
          155  +either their first element or, if the \fB\-index\fR option is used,
          156  +by the element within each group given by the first index passed to
          157  +\fB\-index\fR (which is then ignored by \fB\-index\fR). The resulting
          158  +index always points to the first element in a group.
          159  +.PP
          160  +The list length must be an integer multiple of \fIstrideLength\fR, which
          161  +in turn must be at least 1. A \fIstrideLength\fR of 1 is the default and
          162  +indicates no grouping.
   150    163   .TP
   151    164   \fB\-index\fR\0\fIindexList\fR
   152    165   .
   153    166   This option is designed for use when searching within nested lists.
   154    167   The \fIindexList\fR argument gives a path of indices (much as might be
   155    168   used with the \fBlindex\fR or \fBlset\fR commands) within each element
   156    169   to allow the location of the term being matched against.
................................................................................
   204    217   .PP
   205    218   It is also possible to search inside elements:
   206    219   .PP
   207    220   .CS
   208    221   \fBlsearch\fR -index 1 -all -inline {{a abc} {b bcd} {c cde}} *bc*
   209    222         \fI\(-> {a abc} {b bcd}\fR
   210    223   .CE
          224  +.PP
          225  +The same thing for a flattened list:
          226  +.PP
          227  +.CS
          228  +\fBlsearch\fR -stride 2 -index 1 -all -inline {a abc b bcd c cde} *bc*
          229  +      \fI\(-> {a abc b bcd}\fR
          230  +.CE
   211    231   .SH "SEE ALSO"
   212    232   foreach(n), list(n), lappend(n), lindex(n), linsert(n), llength(n),
   213    233   lset(n), lsort(n), lrange(n), lreplace(n),
   214    234   string(n)
   215    235   .SH KEYWORDS
   216    236   binary search, linear search,
   217    237   list, match, pattern, regular expression, search, string
   218    238   '\" Local Variables:
   219    239   '\" mode: nroff
   220    240   '\" End:

Changes to doc/msgcat.n.

     7      7   .TH "msgcat" n 1.5 msgcat "Tcl Bundled Packages"
     8      8   .so man.macros
     9      9   .BS
    10     10   '\" Note:  do not modify the .SH NAME line immediately below!
    11     11   .SH NAME
    12     12   msgcat \- Tcl message catalog
    13     13   .SH SYNOPSIS
    14         -\fBpackage require Tcl 8.5\fR
           14  +\fBpackage require Tcl 8.7\fR
    15     15   .sp
    16         -\fBpackage require msgcat 1.6\fR
           16  +\fBpackage require msgcat 1.7\fR
    17     17   .sp
    18     18   \fB::msgcat::mc \fIsrc-string\fR ?\fIarg arg ...\fR?
    19     19   .sp
    20     20   \fB::msgcat::mcmax ?\fIsrc-string src-string ...\fR?
    21     21   .sp
    22     22   .VS "TIP 412"
    23     23   \fB::msgcat::mcexists\fR ?\fB-exactnamespace\fR? ?\fB-exactlocale\fR? \fIsrc-string\fR
    24     24   .VE "TIP 412"
           25  +.sp
           26  +.VS "TIP 490"
           27  +\fB::msgcat::mcpackagenamespaceget\fR
           28  +.VE "TIP 490"
    25     29   .sp
    26     30   \fB::msgcat::mclocale \fR?\fInewLocale\fR?
    27     31   .sp
    28         -\fB::msgcat::mcpreferences\fR
           32  +.VS "TIP 499"
           33  +\fB::msgcat::mcpreferences\fR ?\fIlocale preference\fR? ...
           34  +.VE "TIP 499"
    29     35   .sp
    30     36   .VS "TIP 412"
    31     37   \fB::msgcat::mcloadedlocales subcommand\fR ?\fIlocale\fR?
    32     38   .VE "TIP 412"
    33     39   .sp
    34     40   \fB::msgcat::mcload \fIdirname\fR
    35     41   .sp
................................................................................
    46     52   .VS "TIP 412"
    47     53   \fB::msgcat::mcpackagelocale subcommand\fR ?\fIlocale\fR?
    48     54   .sp
    49     55   \fB::msgcat::mcpackageconfig subcommand\fR \fIoption\fR ?\fIvalue\fR?
    50     56   .sp
    51     57   \fB::msgcat::mcforgetpackage\fR
    52     58   .VE "TIP 412"
           59  +.sp
           60  +.VS "TIP 499"
           61  +\fB::msgcat::mcutil subcommand\fR ?\fIlocale\fR?
           62  +.VS "TIP 499"
    53     63   .BE
    54     64   .SH DESCRIPTION
    55     65   .PP
    56     66   The \fBmsgcat\fR package provides a set of functions
    57     67   that can be used to manage multi-lingual user interfaces.
    58     68   Text strings are defined in a
    59     69   .QW "message catalog"
................................................................................
    67     77   Each package has its own message catalog and configuration settings in \fBmsgcat\fR.
    68     78   .PP
    69     79   A \fIlocale\fR is a specification string describing a user language like \fBde_ch\fR for Swiss German.
    70     80   In \fBmsgcat\fR, there is a global locale initialized by the system locale of the current system.
    71     81   Each package may decide to use the global locale or to use a package specific locale.
    72     82   .PP
    73     83   The global locale may be changed on demand, for example by a user initiated language change or within a multi user application like a web server.
           84  +.PP
           85  +.VS tip490
           86  +Object oriented programming is supported by the use of a package namespace.
           87  +.VE tip490
           88  +.PP
    74     89   .SH COMMANDS
    75     90   .TP
    76     91   \fB::msgcat::mc \fIsrc-string\fR ?\fIarg arg ...\fR?
    77     92   .
    78     93   Returns a translation of \fIsrc-string\fR according to the
    79     94   current locale.  If additional arguments past \fIsrc-string\fR
    80     95   are given, the \fBformat\fR command is used to substitute the
................................................................................
    91    106   \fB::msgcat::mc\fR is the main function used to localize an
    92    107   application.  Instead of using an English string directly, an
    93    108   application can pass the English string through \fB::msgcat::mc\fR and
    94    109   use the result.  If an application is written for a single language in
    95    110   this fashion, then it is easy to add support for additional languages
    96    111   later simply by defining new message catalog entries.
    97    112   .RE
          113  +.VS "TIP 490"
          114  +.TP
          115  +\fB::msgcat::mcn \fInamespace\fR \fIsrc-string\fR ?\fIarg arg ...\fR?
          116  +.
          117  +Like \fB::msgcat::mc\fR, but with the message namespace specified as first argument.
          118  +.PP
          119  +.RS
          120  +\fBmcn\fR may be used for cases where the package namespace is not the namespace of the caller.
          121  +An example is shown within the description of the command \fB::msgcat::mcpackagenamespaceget\fR below.
          122  +.RE
          123  +.PP
    98    124   .TP
    99    125   \fB::msgcat::mcmax ?\fIsrc-string src-string ...\fR?
   100    126   .
   101    127   Given several source strings, \fB::msgcat::mcmax\fR returns the length
   102    128   of the longest translated string.  This is useful when designing
   103    129   localized GUIs, which may require that all buttons, for example, be a
   104    130   fixed width (which will be the width of the widest button).
   105    131   .TP
   106         -\fB::msgcat::mcexists\fR ?\fB-exactnamespace\fR? ?\fB-exactlocale\fR? \fIsrc-string\fR
   107         -.
   108    132   .VS "TIP 412"
          133  +\fB::msgcat::mcexists\fR ?\fB-exactnamespace\fR? ?\fB-exactlocale\fR? ?\fB-namespace\fR \fInamespace\fR? \fIsrc-string\fR
          134  +.
   109    135   Return true, if there is a translation for the given \fIsrc-string\fR.
   110    136   .PP
   111    137   .RS
   112    138   The search may be limited by the option \fB\-exactnamespace\fR to only check the current namespace and not any parent namespaces.
   113    139   .PP
   114    140   It may also be limited by the option \fB\-exactlocale\fR to only check the first prefered locale (e.g. first element returned by \fB::msgcat::mcpreferences\fR if global locale is used).
   115         -.RE
          141  +.PP
   116    142   .VE "TIP 412"
          143  +.VS "TIP 490"
          144  +An explicit package namespace may be specified by the option \fB-namespace\fR.
          145  +The namespace of the caller is used if not explicitly specified.
          146  +.RE
          147  +.PP
          148  +.VE "TIP 490"
          149  +.VS "TIP 490"
          150  +.TP
          151  +\fB::msgcat::mcpackagenamespaceget\fR
          152  +.
          153  +Return the package namespace of the caller.
          154  +This command handles all cases described in section \fBOBJECT ORIENTED PROGRAMMING\fR.
          155  +.PP
          156  +.RS
          157  +Example usage is a tooltip package, which saves the caller package namespace to update the translation each time the tooltip is shown:
          158  +.CS
          159  +proc ::tooltip::tooltip {widget message} {
          160  +    ...
          161  +    set messagenamespace [uplevel 1 {::msgcat::mcpackagenamespaceget}]
          162  +    ...
          163  +    bind $widget  [list ::tooltip::show $widget $messagenamespace $message]
          164  +}
          165  +
          166  +proc ::tooltip::show {widget messagenamespace message} {
          167  +    ...
          168  +    set message [::msgcat::mcn $messagenamespace $message]
          169  +    ...
          170  +}
          171  +.CE
          172  +.RE
          173  +.PP
          174  +.VE "TIP 490"
   117    175   .TP
   118    176   \fB::msgcat::mclocale \fR?\fInewLocale\fR?
   119    177   .
   120         -This function sets the locale to \fInewLocale\fR.  If \fInewLocale\fR
   121         -is omitted, the current locale is returned, otherwise the current locale
   122         -is set to \fInewLocale\fR.  msgcat stores and compares the locale in a
          178  +If \fInewLocale\fR is omitted, the current locale is returned, otherwise the current locale
          179  +is set to \fInewLocale\fR.
          180  +.PP
          181  +.RS
          182  +If the new locale is set to \fInewLocale\fR, the corresponding preferences are calculated and set.
          183  +For example, if the current locale is en_US_funky, then \fB::msgcat::mcpreferences\fR returns \fB{en_us_funky en_us en {}}\fR.
          184  +.PP
          185  +The same result may be acheved by \fB::msgcat::mcpreferences\fR {*}[\fB::msgcat::mcutil getpreferences\fR \fInewLocale\fR].
          186  +.PP
          187  +The current locale is always the first element of the list returned by \fBmcpreferences\fR.
          188  +.PP
          189  +msgcat stores and compares the locale in a
   123    190   case-insensitive manner, and returns locales in lowercase.
   124    191   The initial locale is determined by the locale specified in
   125    192   the user's environment.  See \fBLOCALE SPECIFICATION\fR
   126    193   below for a description of the locale string format.
   127         -.RS
   128    194   .PP
   129    195   .VS "TIP 412"
   130    196   If the locale is set, the preference list of locales is evaluated.
   131    197   Locales in this list are loaded now, if not jet loaded.
   132    198   .VE "TIP 412"
   133    199   .RE
   134    200   .TP
   135         -\fB::msgcat::mcpreferences\fR
          201  +\fB::msgcat::mcpreferences\fR ?\fIlocale preference\fR? ...
   136    202   .
   137         -Returns an ordered list of the locales preferred by
   138         -the user, based on the user's language specification.
   139         -The list is ordered from most specific to least
   140         -preference.  The list is derived from the current
   141         -locale set in msgcat by \fB::msgcat::mclocale\fR, and
   142         -cannot be set independently.  For example, if the
   143         -current locale is en_US_funky, then \fB::msgcat::mcpreferences\fR
   144         -returns \fB{en_us_funky en_us en {}}\fR.
          203  +Without arguments, returns an ordered list of the locales preferred by
          204  +the user.
          205  +The list is ordered from most specific to least preference.
          206  +.PP
          207  +.VS "TIP 499"
          208  +.RS
          209  +A set of locale preferences may be given to set the list of locale preferences.
          210  +The current locale is also set, which is the first element of the locale preferences list.
          211  +.PP
          212  +Locale preferences are loaded now, if not jet loaded.
          213  +.PP
          214  +As an example, the user may prefer French or English text. This may be configured by:
          215  +.CS
          216  +::msgcat::mcpreferences fr en {}
          217  +.CE
          218  +.RE
          219  +.PP
          220  +.VS "TIP 499"
   145    221   .TP
   146    222   \fB::msgcat:mcloadedlocales subcommand\fR ?\fIlocale\fR?
   147    223   .
   148    224   This group of commands manage the list of loaded locales for packages not setting a package locale.
   149    225   .PP
   150    226   .RS
   151    227   The subcommand \fBget\fR returns the list of currently loaded locales.
................................................................................
   227    303   Note that this routine is only called if the concerned package did not set a package locale unknown command name.
   228    304   .RE
   229    305   .TP
   230    306   \fB::msgcat::mcforgetpackage\fR
   231    307   .
   232    308   The calling package clears all its state within the \fBmsgcat\fR package including all settings and translations.
   233    309   .VE "TIP 412"
          310  +.PP
          311  +.VS "TIP 499"
          312  +.TP
          313  +\fB::msgcat::mcutil getpreferences\fR \fIlocale\fR
          314  +.
          315  +Return the preferences list of the given locale as described in section \fBLOCALE SPECIFICATION\fR.
          316  +An example is the composition of a preference list for the bilingual region "Biel/Bienne" as a concatenation of swiss german and swiss french:
          317  +.CS
          318  +% concat [lrange [msgcat::mcutil getpreferences fr_CH] 0 end-1] [msgcat::mcutil getpreferences de_CH]
          319  +fr_ch fr de_ch de {}
          320  +.CE
          321  +.TP
          322  +\fB::msgcat::mcutil getsystemlocale\fR
          323  +.
          324  +The system locale is returned as described by the section \fBLOCALE SPECIFICATION\fR.
          325  +.VE "TIP 499"
   234    326   .PP
   235    327   .SH "LOCALE SPECIFICATION"
   236    328   .PP
   237    329   The locale is specified to \fBmsgcat\fR by a locale string
   238    330   passed to \fB::msgcat::mclocale\fR.
   239    331   The locale string consists of
   240    332   a language code, an optional country code, and an optional
................................................................................
   433    525   .PP
   434    526   .CS
   435    527   \fBmsgcat::mc\fR {Produced %1$d at %2$s} $num $city
   436    528   # ... where that key is mapped to one of the
   437    529   # human-oriented versions by \fBmsgcat::mcset\fR
   438    530   .CE
   439    531   .VS "TIP 412"
   440         -.SH Package private locale
          532  +.SH "PACKAGE PRIVATE LOCALE"
   441    533   .PP
   442    534   A package using \fBmsgcat\fR may choose to use its own package private
   443    535   locale and its own set of loaded locales, independent to the global
   444    536   locale set by \fB::msgcat::mclocale\fR.
   445    537   .PP
   446    538   This allows a package to change its locale without causing any locales load or removal in other packages and not to invoke the global locale change callback (see below).
   447    539   .PP
................................................................................
   457    549   This command may cause the load of locales.
   458    550   .RE
   459    551   .TP
   460    552   \fB::msgcat::mcpackagelocale get\fR
   461    553   .
   462    554   Return the package private locale or the global locale, if no package private locale is set.
   463    555   .TP
   464         -\fB::msgcat::mcpackagelocale preferences\fR
          556  +\fB::msgcat::mcpackagelocale preferences\fR ?\fIlocale preference\fR? ...
   465    557   .
   466         -Return the package private preferences or the global preferences,
          558  +With no parameters, return the package private preferences or the global preferences,
   467    559   if no package private locale is set.
          560  +The package locale state (set or not) is not changed (in contrast to the command \fB::msgcat::mcpackagelocale set\fR).
          561  +.PP
          562  +.RS
          563  +.VS "TIP 499"
          564  +If a set of locale preferences is given, it is set as package locale preference list.
          565  +The package locale is set to the first element of the preference list.
          566  +A package locale is activated, if it was not set so far.
          567  +.PP
          568  +Locale preferences are loaded now for the package, if not jet loaded.
          569  +.VE "TIP 499"
          570  +.RE
          571  +.PP
   468    572   .TP
   469    573   \fB::msgcat::mcpackagelocale loaded\fR
   470    574   .
   471    575   Return the list of locales loaded for this package.
   472    576   .TP
   473    577   \fB::msgcat::mcpackagelocale isset\fR
   474    578   .
................................................................................
   484    588   .
   485    589   Returns true, if the given locale is loaded for the package.
   486    590   .TP
   487    591   \fB::msgcat::mcpackagelocale clear\fR
   488    592   .
   489    593   Clear any loaded locales of the package not present in the package preferences.
   490    594   .PP
   491         -.SH Changing package options
          595  +.SH "CHANGING PACKAGE OPTIONS"
   492    596   .PP
   493    597   Each package using msgcat has a set of options within \fBmsgcat\fR.
   494    598   The package options are described in the next sectionPackage options.
   495    599   Each package option may be set or unset individually using the following ensemble:
   496    600   .TP
   497    601   \fB::msgcat::mcpackageconfig get\fR \fIoption\fR
   498    602   .
................................................................................
   559    663   The called procedure must return the formatted message which will finally be returned by msgcat::mc.
   560    664   .PP
   561    665   A generic unknown handler is used if set to the empty string. This consists in returning the key if no arguments are given. With given arguments, format is used to process the arguments.
   562    666   .PP
   563    667   See section \fBcallback invocation\fR below.
   564    668   The appended arguments are identical to \fB::msgcat::mcunknown\fR.
   565    669   .RE
   566         -.SS Callback invocation
          670  +.SH "Callback invocation"
   567    671   A package may decide to register one or multiple callbacks, as described above.
   568    672   .PP
   569    673   Callbacks are invoked, if:
   570    674   .PP
   571    675   1. the callback command is set,
   572    676   .PP
   573    677   2. the command is not the empty string,
   574    678   .PP
   575    679   3. the registering namespace exists.
   576    680   .PP
   577    681   If a called routine fails with an error, the \fBbgerror\fR routine for the interpreter is invoked after command completion.
   578    682   Only exception is the callback \fBunknowncmd\fR, where an error causes the invoking \fBmc\fR-command to fail with that error.
   579    683   .PP
   580         -.SS Examples
          684  +.VS tip490
          685  +.SH "OBJECT ORIENTED PROGRAMMING"
          686  +\fBmsgcat\fR supports packages implemented by object oriented programming.
          687  +Objects and classes should be defined within a package namespace.
          688  +.PP
          689  +There are 3 supported cases where package namespace sensitive commands of msgcat (\fBmc\fR, \fBmcexists\fR, \fBmcpackagelocale\fR, \fBmcforgetpackage\fR, \fBmcpackagenamespaceget\fR, \fBmcpackageconfig\fR, \fBmcset\fR and \fBmcmset\fR) may be called:
          690  +.PP
          691  +.TP
          692  +\fB1) In class definition script\fR
          693  +.
          694  +\fBmsgcat\fR command is called within a class definition script.
          695  +.CS
          696  +namespace eval ::N2 {
          697  +    mcload $dir/msgs
          698  +    oo::class create C1 {puts [mc Hi!]}
          699  +}
          700  +.CE
          701  +.PP
          702  +.TP
          703  +\fB2) method defined in a class\fR
          704  +.
          705  +\fBmsgcat\fR command is called from a method in an object and the method is defined in a class.
          706  +.CS
          707  +namespace eval ::N3Class {
          708  +    mcload $dir/msgs
          709  +    oo::class create C1
          710  +    oo::define C1 method m1 {
          711  +        puts [mc Hi!]
          712  +    }
          713  +}
          714  +.CE
          715  +.PP
          716  +.TP
          717  +\fB3) method defined in a classless object\fR
          718  +.
          719  +\fBmsgcat\fR command is called from a method of a classless object.
          720  +.CS
          721  +namespace eval ::N4 {
          722  +    mcload $dir/msgs
          723  +    oo::object create O1
          724  +    oo::objdefine O1 method m1 {} {
          725  +        puts [mc Hi!]
          726  +    }
          727  +}
          728  +.CE
          729  +.PP
          730  +.VE tip490
          731  +.SH EXAMPLES
   581    732   Packages which display a GUI may update their widgets when the global locale changes.
   582    733   To register to a callback, use:
   583    734   .CS
   584    735   namespace eval gui {
   585    736       msgcat::mcpackageconfig changecmd updateGUI
   586    737   
   587    738       proc updateGui args {
................................................................................
   639    790   }
   640    791   .CE
   641    792   .VE "TIP 412"
   642    793   .SH CREDITS
   643    794   .PP
   644    795   The message catalog code was developed by Mark Harrison.
   645    796   .SH "SEE ALSO"
   646         -format(n), scan(n), namespace(n), package(n)
          797  +format(n), scan(n), namespace(n), package(n), oo::class(n), oo::object
   647    798   .SH KEYWORDS
   648         -internationalization, i18n, localization, l10n, message, text, translation
          799  +internationalization, i18n, localization, l10n, message, text, translation, class, object
   649    800   .\" Local Variables:
   650    801   .\" mode: nroff
   651    802   .\" End:

Changes to doc/re_syntax.n.

   289    289   and \fB=]\fR is an equivalence class, standing for the sequences of
   290    290   characters of all collating elements equivalent to that one, including
   291    291   itself. (If there are no other equivalent collating elements, the
   292    292   treatment is as if the enclosing delimiters were
   293    293   .QW \fB[.\fR \&
   294    294   and
   295    295   .QW \fB.]\fR .)
   296         -For example, if \fBo\fR and \fB\*(qo\fR are the members of an
          296  +For example, if \fBo\fR and \fB\[^o]\fR are the members of an
   297    297   equivalence class, then
   298    298   .QW \fB[[=o=]]\fR ,
   299         -.QW \fB[[=\*(qo=]]\fR ,
          299  +.QW \fB[[=\[^o]=]]\fR ,
   300    300   and
   301         -.QW \fB[o\*(qo]\fR \&
          301  +.QW \fB[o\[^o]]\fR \&
   302    302   are all synonymous. An equivalence class may not be an endpoint of a range.
   303    303   .RS
   304    304   .PP
   305    305   (\fINote:\fR Tcl implements only the Unicode locale. It does not define any
   306    306   equivalence classes. The examples above are just illustrations.)
   307    307   .RE
   308    308   .SH ESCAPES

Changes to doc/regsub.n.

    63     63   matching range is found and substituted.
    64     64   If \fB\-all\fR is specified, then
    65     65   .QW &
    66     66   and
    67     67   .QW \e\fIn\fR
    68     68   sequences are handled for each substitution using the information
    69     69   from the corresponding match.
           70  +.TP
           71  +\fB\-command\fR
           72  +.VS 8.7
           73  +Changes the handling of \fIsubSpec\fR so that it is not treated
           74  +as a template for a substitution string and the substrings
           75  +.QW &
           76  +and
           77  +.QW \e\fIn\fR
           78  +no longer have special meaning. Instead \fIsubSpec\fR must be a
           79  +command prefix, that is, a non-empty list.  The substring of \fIstring\fR
           80  +that matches \fIexp\fR, and then each substring that matches each
           81  +capturing sub-RE within \fIexp\fR are appended as additional elements
           82  +to that list. (The items appended to the list are much like what
           83  +\fBregexp\fR \fB-inline\fR would return).  The completed list is then
           84  +evaluated as a Tcl command, and the result of that command is the
           85  +substitution string.  Any error or exception from command evaluation
           86  +becomes an error or exception from the \fBregsub\fR command.
           87  +.RS
           88  +.PP
           89  +If \fB\-all\fR is not also given, the command callback will be invoked at most
           90  +once (exactly when the regular expression matches). If \fB\-all\fR is given,
           91  +the command callback will be invoked for each matched location, in sequence.
           92  +The exact location indices that matched are not made available to the script.
           93  +.PP
           94  +See \fBEXAMPLES\fR below for illustrative cases.
           95  +.RE
           96  +.VE 8.7
    70     97   .TP
    71     98   \fB\-expanded\fR
    72     99   .
    73    100   Enables use of the expanded regular expression syntax where
    74    101   whitespace and comments are ignored.  This is the same as specifying
    75    102   the \fB(?x)\fR embedded option (see the \fBre_syntax\fR manual page).
    76    103   .TP
................................................................................
   179    206   # Now we apply the substitution to get a subst-string that
   180    207   # will perform the computational parts of the conversion. Note
   181    208   # that newline is handled specially through \fBstring map\fR since
   182    209   # backslash-newline is a special sequence.
   183    210   set quoted [subst [string map {\en {\e\eu000a}} \e
   184    211           [\fBregsub\fR -all $RE $string $substitution]]]
   185    212   .CE
          213  +.PP
          214  +.VS 8.7
          215  +The above operation can be done using \fBregsub \-command\fR instead, which is
          216  +often faster. (A full pre-computed \fBstring map\fR would be faster still, but
          217  +the cost of computing the map for a transformation as complex as this can be
          218  +quite large.)
          219  +.PP
          220  +.CS
          221  +# This RE is just a character class for everything "bad"
          222  +set RE {[][{};#\e\e\e$\es\eu0080-\euffff]}
          223  +
          224  +# This encodes what the RE described above matches
          225  +proc encodeChar {ch} {
          226  +    # newline is handled specially since backslash-newline is a
          227  +    # special sequence.
          228  +    if {$ch eq "\en"} {
          229  +        return "\e\eu000a"
          230  +    }
          231  +    # No point in writing this as a one-liner
          232  +    scan $ch %c charNumber
          233  +    format "\e\eu%04x" $charNumber
          234  +}
          235  +
          236  +set quoted [\fBregsub\fR -all -command $RE $string encodeChar]
          237  +.CE
          238  +.PP
          239  +Decoding a URL-encoded string using \fBregsub \-command\fR, a lambda term and
          240  +the \fBapply\fR command.
          241  +.PP
          242  +.CS
          243  +# Match one of the sequences in a URL-encoded string that needs
          244  +# fixing, converting + to space and %XX to the right character
          245  +# (e.g., %7e becomes ~)
          246  +set RE {(\e+)|%([0-9A-Fa-f]{2})}
          247  +
          248  +# Note that -command uses a command prefix, not a command name
          249  +set decoded [\fBregsub\fR -all -command $RE $string {apply {{- p h} {
          250  +    # + is a special case; handle directly
          251  +    if {$p eq "+"} {
          252  +        return " "
          253  +    }
          254  +    # convert hex to a char
          255  +    scan $h %x charNumber
          256  +    format %c $charNumber
          257  +}}}]
          258  +.CE
          259  +.VE 8.7
   186    260   .SH "SEE ALSO"
   187    261   regexp(n), re_syntax(n), subst(n), string(n)
   188    262   .SH KEYWORDS
   189    263   match, pattern, quoting, regular expression, substitution
   190    264   '\" Local Variables:
   191    265   '\" mode: nroff
   192    266   '\" End:

Changes to generic/regc_locale.c.

   136    136   static const crange alphaRangeTable[] = {
   137    137       {0x41, 0x5a}, {0x61, 0x7a}, {0xc0, 0xd6}, {0xd8, 0xf6},
   138    138       {0xf8, 0x2c1}, {0x2c6, 0x2d1}, {0x2e0, 0x2e4}, {0x370, 0x374},
   139    139       {0x37a, 0x37d}, {0x388, 0x38a}, {0x38e, 0x3a1}, {0x3a3, 0x3f5},
   140    140       {0x3f7, 0x481}, {0x48a, 0x52f}, {0x531, 0x556}, {0x561, 0x587},
   141    141       {0x5d0, 0x5ea}, {0x5f0, 0x5f2}, {0x620, 0x64a}, {0x671, 0x6d3},
   142    142       {0x6fa, 0x6fc}, {0x712, 0x72f}, {0x74d, 0x7a5}, {0x7ca, 0x7ea},
   143         -    {0x800, 0x815}, {0x840, 0x858}, {0x8a0, 0x8b4}, {0x8b6, 0x8bd},
   144         -    {0x904, 0x939}, {0x958, 0x961}, {0x971, 0x980}, {0x985, 0x98c},
   145         -    {0x993, 0x9a8}, {0x9aa, 0x9b0}, {0x9b6, 0x9b9}, {0x9df, 0x9e1},
   146         -    {0xa05, 0xa0a}, {0xa13, 0xa28}, {0xa2a, 0xa30}, {0xa59, 0xa5c},
   147         -    {0xa72, 0xa74}, {0xa85, 0xa8d}, {0xa8f, 0xa91}, {0xa93, 0xaa8},
   148         -    {0xaaa, 0xab0}, {0xab5, 0xab9}, {0xb05, 0xb0c}, {0xb13, 0xb28},
   149         -    {0xb2a, 0xb30}, {0xb35, 0xb39}, {0xb5f, 0xb61}, {0xb85, 0xb8a},
   150         -    {0xb8e, 0xb90}, {0xb92, 0xb95}, {0xba8, 0xbaa}, {0xbae, 0xbb9},
   151         -    {0xc05, 0xc0c}, {0xc0e, 0xc10}, {0xc12, 0xc28}, {0xc2a, 0xc39},
   152         -    {0xc58, 0xc5a}, {0xc85, 0xc8c}, {0xc8e, 0xc90}, {0xc92, 0xca8},
   153         -    {0xcaa, 0xcb3}, {0xcb5, 0xcb9}, {0xd05, 0xd0c}, {0xd0e, 0xd10},
   154         -    {0xd12, 0xd3a}, {0xd54, 0xd56}, {0xd5f, 0xd61}, {0xd7a, 0xd7f},
   155         -    {0xd85, 0xd96}, {0xd9a, 0xdb1}, {0xdb3, 0xdbb}, {0xdc0, 0xdc6},
   156         -    {0xe01, 0xe30}, {0xe40, 0xe46}, {0xe94, 0xe97}, {0xe99, 0xe9f},
   157         -    {0xea1, 0xea3}, {0xead, 0xeb0}, {0xec0, 0xec4}, {0xedc, 0xedf},
   158         -    {0xf40, 0xf47}, {0xf49, 0xf6c}, {0xf88, 0xf8c}, {0x1000, 0x102a},
   159         -    {0x1050, 0x1055}, {0x105a, 0x105d}, {0x106e, 0x1070}, {0x1075, 0x1081},
   160         -    {0x10a0, 0x10c5}, {0x10d0, 0x10fa}, {0x10fc, 0x1248}, {0x124a, 0x124d},
   161         -    {0x1250, 0x1256}, {0x125a, 0x125d}, {0x1260, 0x1288}, {0x128a, 0x128d},
   162         -    {0x1290, 0x12b0}, {0x12b2, 0x12b5}, {0x12b8, 0x12be}, {0x12c2, 0x12c5},
   163         -    {0x12c8, 0x12d6}, {0x12d8, 0x1310}, {0x1312, 0x1315}, {0x1318, 0x135a},
   164         -    {0x1380, 0x138f}, {0x13a0, 0x13f5}, {0x13f8, 0x13fd}, {0x1401, 0x166c},
   165         -    {0x166f, 0x167f}, {0x1681, 0x169a}, {0x16a0, 0x16ea}, {0x16f1, 0x16f8},
   166         -    {0x1700, 0x170c}, {0x170e, 0x1711}, {0x1720, 0x1731}, {0x1740, 0x1751},
   167         -    {0x1760, 0x176c}, {0x176e, 0x1770}, {0x1780, 0x17b3}, {0x1820, 0x1877},
   168         -    {0x1880, 0x1884}, {0x1887, 0x18a8}, {0x18b0, 0x18f5}, {0x1900, 0x191e},
   169         -    {0x1950, 0x196d}, {0x1970, 0x1974}, {0x1980, 0x19ab}, {0x19b0, 0x19c9},
   170         -    {0x1a00, 0x1a16}, {0x1a20, 0x1a54}, {0x1b05, 0x1b33}, {0x1b45, 0x1b4b},
   171         -    {0x1b83, 0x1ba0}, {0x1bba, 0x1be5}, {0x1c00, 0x1c23}, {0x1c4d, 0x1c4f},
   172         -    {0x1c5a, 0x1c7d}, {0x1c80, 0x1c88}, {0x1ce9, 0x1cec}, {0x1cee, 0x1cf1},
   173         -    {0x1d00, 0x1dbf}, {0x1e00, 0x1f15}, {0x1f18, 0x1f1d}, {0x1f20, 0x1f45},
   174         -    {0x1f48, 0x1f4d}, {0x1f50, 0x1f57}, {0x1f5f, 0x1f7d}, {0x1f80, 0x1fb4},
   175         -    {0x1fb6, 0x1fbc}, {0x1fc2, 0x1fc4}, {0x1fc6, 0x1fcc}, {0x1fd0, 0x1fd3},
   176         -    {0x1fd6, 0x1fdb}, {0x1fe0, 0x1fec}, {0x1ff2, 0x1ff4}, {0x1ff6, 0x1ffc},
   177         -    {0x2090, 0x209c}, {0x210a, 0x2113}, {0x2119, 0x211d}, {0x212a, 0x212d},
   178         -    {0x212f, 0x2139}, {0x213c, 0x213f}, {0x2145, 0x2149}, {0x2c00, 0x2c2e},
   179         -    {0x2c30, 0x2c5e}, {0x2c60, 0x2ce4}, {0x2ceb, 0x2cee}, {0x2d00, 0x2d25},
   180         -    {0x2d30, 0x2d67}, {0x2d80, 0x2d96}, {0x2da0, 0x2da6}, {0x2da8, 0x2dae},
   181         -    {0x2db0, 0x2db6}, {0x2db8, 0x2dbe}, {0x2dc0, 0x2dc6}, {0x2dc8, 0x2dce},
   182         -    {0x2dd0, 0x2dd6}, {0x2dd8, 0x2dde}, {0x3031, 0x3035}, {0x3041, 0x3096},
   183         -    {0x309d, 0x309f}, {0x30a1, 0x30fa}, {0x30fc, 0x30ff}, {0x3105, 0x312d},
   184         -    {0x3131, 0x318e}, {0x31a0, 0x31ba}, {0x31f0, 0x31ff}, {0x3400, 0x4db5},
   185         -    {0x4e00, 0x9fd5}, {0xa000, 0xa48c}, {0xa4d0, 0xa4fd}, {0xa500, 0xa60c},
   186         -    {0xa610, 0xa61f}, {0xa640, 0xa66e}, {0xa67f, 0xa69d}, {0xa6a0, 0xa6e5},
   187         -    {0xa717, 0xa71f}, {0xa722, 0xa788}, {0xa78b, 0xa7ae}, {0xa7b0, 0xa7b7},
   188         -    {0xa7f7, 0xa801}, {0xa803, 0xa805}, {0xa807, 0xa80a}, {0xa80c, 0xa822},
   189         -    {0xa840, 0xa873}, {0xa882, 0xa8b3}, {0xa8f2, 0xa8f7}, {0xa90a, 0xa925},
   190         -    {0xa930, 0xa946}, {0xa960, 0xa97c}, {0xa984, 0xa9b2}, {0xa9e0, 0xa9e4},
   191         -    {0xa9e6, 0xa9ef}, {0xa9fa, 0xa9fe}, {0xaa00, 0xaa28}, {0xaa40, 0xaa42},
   192         -    {0xaa44, 0xaa4b}, {0xaa60, 0xaa76}, {0xaa7e, 0xaaaf}, {0xaab9, 0xaabd},
   193         -    {0xaadb, 0xaadd}, {0xaae0, 0xaaea}, {0xaaf2, 0xaaf4}, {0xab01, 0xab06},
   194         -    {0xab09, 0xab0e}, {0xab11, 0xab16}, {0xab20, 0xab26}, {0xab28, 0xab2e},
   195         -    {0xab30, 0xab5a}, {0xab5c, 0xab65}, {0xab70, 0xabe2}, {0xac00, 0xd7a3},
   196         -    {0xd7b0, 0xd7c6}, {0xd7cb, 0xd7fb}, {0xdc00, 0xdc3e}, {0xdc40, 0xdc7e},
   197         -    {0xdc80, 0xdcbe}, {0xdcc0, 0xdcfe}, {0xdd00, 0xdd3e}, {0xdd40, 0xdd7e},
   198         -    {0xdd80, 0xddbe}, {0xddc0, 0xddfe}, {0xde00, 0xde3e}, {0xde40, 0xde7e},
   199         -    {0xde80, 0xdebe}, {0xdec0, 0xdefe}, {0xdf00, 0xdf3e}, {0xdf40, 0xdf7e},
   200         -    {0xdf80, 0xdfbe}, {0xdfc0, 0xdffe}, {0xf900, 0xfa6d}, {0xfa70, 0xfad9},
   201         -    {0xfb00, 0xfb06}, {0xfb13, 0xfb17}, {0xfb1f, 0xfb28}, {0xfb2a, 0xfb36},
   202         -    {0xfb38, 0xfb3c}, {0xfb46, 0xfbb1}, {0xfbd3, 0xfd3d}, {0xfd50, 0xfd8f},
   203         -    {0xfd92, 0xfdc7}, {0xfdf0, 0xfdfb}, {0xfe70, 0xfe74}, {0xfe76, 0xfefc},
   204         -    {0xff21, 0xff3a}, {0xff41, 0xff5a}, {0xff66, 0xffbe}, {0xffc2, 0xffc7},
   205         -    {0xffca, 0xffcf}, {0xffd2, 0xffd7}, {0xffda, 0xffdc}
          143  +    {0x800, 0x815}, {0x840, 0x858}, {0x860, 0x86a}, {0x8a0, 0x8b4},
          144  +    {0x8b6, 0x8bd}, {0x904, 0x939}, {0x958, 0x961}, {0x971, 0x980},
          145  +    {0x985, 0x98c}, {0x993, 0x9a8}, {0x9aa, 0x9b0}, {0x9b6, 0x9b9},
          146  +    {0x9df, 0x9e1}, {0xa05, 0xa0a}, {0xa13, 0xa28}, {0xa2a, 0xa30},
          147  +    {0xa59, 0xa5c}, {0xa72, 0xa74}, {0xa85, 0xa8d}, {0xa8f, 0xa91},
          148  +    {0xa93, 0xaa8}, {0xaaa, 0xab0}, {0xab5, 0xab9}, {0xb05, 0xb0c},
          149  +    {0xb13, 0xb28}, {0xb2a, 0xb30}, {0xb35, 0xb39}, {0xb5f, 0xb61},
          150  +    {0xb85, 0xb8a}, {0xb8e, 0xb90}, {0xb92, 0xb95}, {0xba8, 0xbaa},
          151  +    {0xbae, 0xbb9}, {0xc05, 0xc0c}, {0xc0e, 0xc10}, {0xc12, 0xc28},
          152  +    {0xc2a, 0xc39}, {0xc58, 0xc5a}, {0xc85, 0xc8c}, {0xc8e, 0xc90},
          153  +    {0xc92, 0xca8}, {0xcaa, 0xcb3}, {0xcb5, 0xcb9}, {0xd05, 0xd0c},
          154  +    {0xd0e, 0xd10}, {0xd12, 0xd3a}, {0xd54, 0xd56}, {0xd5f, 0xd61},
          155  +    {0xd7a, 0xd7f}, {0xd85, 0xd96}, {0xd9a, 0xdb1}, {0xdb3, 0xdbb},
          156  +    {0xdc0, 0xdc6}, {0xe01, 0xe30}, {0xe40, 0xe46}, {0xe94, 0xe97},
          157  +    {0xe99, 0xe9f}, {0xea1, 0xea3}, {0xead, 0xeb0}, {0xec0, 0xec4},
          158  +    {0xedc, 0xedf}, {0xf40, 0xf47}, {0xf49, 0xf6c}, {0xf88, 0xf8c},
          159  +    {0x1000, 0x102a}, {0x1050, 0x1055}, {0x105a, 0x105d}, {0x106e, 0x1070},
          160  +    {0x1075, 0x1081}, {0x10a0, 0x10c5}, {0x10d0, 0x10fa}, {0x10fc, 0x1248},
          161  +    {0x124a, 0x124d}, {0x1250, 0x1256}, {0x125a, 0x125d}, {0x1260, 0x1288},
          162  +    {0x128a, 0x128d}, {0x1290, 0x12b0}, {0x12b2, 0x12b5}, {0x12b8, 0x12be},
          163  +    {0x12c2, 0x12c5}, {0x12c8, 0x12d6}, {0x12d8, 0x1310}, {0x1312, 0x1315},
          164  +    {0x1318, 0x135a}, {0x1380, 0x138f}, {0x13a0, 0x13f5}, {0x13f8, 0x13fd},
          165  +    {0x1401, 0x166c}, {0x166f, 0x167f}, {0x1681, 0x169a}, {0x16a0, 0x16ea},
          166  +    {0x16f1, 0x16f8}, {0x1700, 0x170c}, {0x170e, 0x1711}, {0x1720, 0x1731},
          167  +    {0x1740, 0x1751}, {0x1760, 0x176c}, {0x176e, 0x1770}, {0x1780, 0x17b3},
          168  +    {0x1820, 0x1877}, {0x1880, 0x1884}, {0x1887, 0x18a8}, {0x18b0, 0x18f5},
          169  +    {0x1900, 0x191e}, {0x1950, 0x196d}, {0x1970, 0x1974}, {0x1980, 0x19ab},
          170  +    {0x19b0, 0x19c9}, {0x1a00, 0x1a16}, {0x1a20, 0x1a54}, {0x1b05, 0x1b33},
          171  +    {0x1b45, 0x1b4b}, {0x1b83, 0x1ba0}, {0x1bba, 0x1be5}, {0x1c00, 0x1c23},
          172  +    {0x1c4d, 0x1c4f}, {0x1c5a, 0x1c7d}, {0x1c80, 0x1c88}, {0x1ce9, 0x1cec},
          173  +    {0x1cee, 0x1cf1}, {0x1d00, 0x1dbf}, {0x1e00, 0x1f15}, {0x1f18, 0x1f1d},
          174  +    {0x1f20, 0x1f45}, {0x1f48, 0x1f4d}, {0x1f50, 0x1f57}, {0x1f5f, 0x1f7d},
          175  +    {0x1f80, 0x1fb4}, {0x1fb6, 0x1fbc}, {0x1fc2, 0x1fc4}, {0x1fc6, 0x1fcc},
          176  +    {0x1fd0, 0x1fd3}, {0x1fd6, 0x1fdb}, {0x1fe0, 0x1fec}, {0x1ff2, 0x1ff4},
          177  +    {0x1ff6, 0x1ffc}, {0x2090, 0x209c}, {0x210a, 0x2113}, {0x2119, 0x211d},
          178  +    {0x212a, 0x212d}, {0x212f, 0x2139}, {0x213c, 0x213f}, {0x2145, 0x2149},
          179  +    {0x2c00, 0x2c2e}, {0x2c30, 0x2c5e}, {0x2c60, 0x2ce4}, {0x2ceb, 0x2cee},
          180  +    {0x2d00, 0x2d25}, {0x2d30, 0x2d67}, {0x2d80, 0x2d96}, {0x2da0, 0x2da6},
          181  +    {0x2da8, 0x2dae}, {0x2db0, 0x2db6}, {0x2db8, 0x2dbe}, {0x2dc0, 0x2dc6},
          182  +    {0x2dc8, 0x2dce}, {0x2dd0, 0x2dd6}, {0x2dd8, 0x2dde}, {0x3031, 0x3035},
          183  +    {0x3041, 0x3096}, {0x309d, 0x309f}, {0x30a1, 0x30fa}, {0x30fc, 0x30ff},
          184  +    {0x3105, 0x312e}, {0x3131, 0x318e}, {0x31a0, 0x31ba}, {0x31f0, 0x31ff},
          185  +    {0x3400, 0x4db5}, {0x4e00, 0x9fea}, {0xa000, 0xa48c}, {0xa4d0, 0xa4fd},
          186  +    {0xa500, 0xa60c}, {0xa610, 0xa61f}, {0xa640, 0xa66e}, {0xa67f, 0xa69d},
          187  +    {0xa6a0, 0xa6e5}, {0xa717, 0xa71f}, {0xa722, 0xa788}, {0xa78b, 0xa7ae},
          188  +    {0xa7b0, 0xa7b7}, {0xa7f7, 0xa801}, {0xa803, 0xa805}, {0xa807, 0xa80a},
          189  +    {0xa80c, 0xa822}, {0xa840, 0xa873}, {0xa882, 0xa8b3}, {0xa8f2, 0xa8f7},
          190  +    {0xa90a, 0xa925}, {0xa930, 0xa946}, {0xa960, 0xa97c}, {0xa984, 0xa9b2},
          191  +    {0xa9e0, 0xa9e4}, {0xa9e6, 0xa9ef}, {0xa9fa, 0xa9fe}, {0xaa00, 0xaa28},
          192  +    {0xaa40, 0xaa42}, {0xaa44, 0xaa4b}, {0xaa60, 0xaa76}, {0xaa7e, 0xaaaf},
          193  +    {0xaab9, 0xaabd}, {0xaadb, 0xaadd}, {0xaae0, 0xaaea}, {0xaaf2, 0xaaf4},
          194  +    {0xab01, 0xab06}, {0xab09, 0xab0e}, {0xab11, 0xab16}, {0xab20, 0xab26},
          195  +    {0xab28, 0xab2e}, {0xab30, 0xab5a}, {0xab5c, 0xab65}, {0xab70, 0xabe2},
          196  +    {0xac00, 0xd7a3}, {0xd7b0, 0xd7c6}, {0xd7cb, 0xd7fb}, {0xdc00, 0xdc3e},
          197  +    {0xdc40, 0xdc7e}, {0xdc80, 0xdcbe}, {0xdcc0, 0xdcfe}, {0xdd00, 0xdd3e},
          198  +    {0xdd40, 0xdd7e}, {0xdd80, 0xddbe}, {0xddc0, 0xddfe}, {0xde00, 0xde3e},
          199  +    {0xde40, 0xde7e}, {0xde80, 0xdebe}, {0xdec0, 0xdefe}, {0xdf00, 0xdf3e},
          200  +    {0xdf40, 0xdf7e}, {0xdf80, 0xdfbe}, {0xdfc0, 0xdffe}, {0xf900, 0xfa6d},
          201  +    {0xfa70, 0xfad9}, {0xfb00, 0xfb06}, {0xfb13, 0xfb17}, {0xfb1f, 0xfb28},
          202  +    {0xfb2a, 0xfb36}, {0xfb38, 0xfb3c}, {0xfb46, 0xfbb1}, {0xfbd3, 0xfd3d},
          203  +    {0xfd50, 0xfd8f}, {0xfd92, 0xfdc7}, {0xfdf0, 0xfdfb}, {0xfe70, 0xfe74},
          204  +    {0xfe76, 0xfefc}, {0xff21, 0xff3a}, {0xff41, 0xff5a}, {0xff66, 0xffbe},
          205  +    {0xffc2, 0xffc7}, {0xffca, 0xffcf}, {0xffd2, 0xffd7}, {0xffda, 0xffdc}
   206    206   #if TCL_UTF_MAX > 4
   207    207       ,{0x10000, 0x1000b}, {0x1000d, 0x10026}, {0x10028, 0x1003a}, {0x1003f, 0x1004d},
   208    208       {0x10050, 0x1005d}, {0x10080, 0x100fa}, {0x10280, 0x1029c}, {0x102a0, 0x102d0},
   209         -    {0x10300, 0x1031f}, {0x10330, 0x10340}, {0x10342, 0x10349}, {0x10350, 0x10375},
          209  +    {0x10300, 0x1031f}, {0x1032d, 0x10340}, {0x10342, 0x10349}, {0x10350, 0x10375},
   210    210       {0x10380, 0x1039d}, {0x103a0, 0x103c3}, {0x103c8, 0x103cf}, {0x10400, 0x1049d},
   211    211       {0x104b0, 0x104d3}, {0x104d8, 0x104fb}, {0x10500, 0x10527}, {0x10530, 0x10563},
   212    212       {0x10600, 0x10736}, {0x10740, 0x10755}, {0x10760, 0x10767}, {0x10800, 0x10805},
   213    213       {0x1080a, 0x10835}, {0x1083f, 0x10855}, {0x10860, 0x10876}, {0x10880, 0x1089e},
   214    214       {0x108e0, 0x108f2}, {0x10900, 0x10915}, {0x10920, 0x10939}, {0x10980, 0x109b7},
   215    215       {0x10a10, 0x10a13}, {0x10a15, 0x10a17}, {0x10a19, 0x10a33}, {0x10a60, 0x10a7c},
   216    216       {0x10a80, 0x10a9c}, {0x10ac0, 0x10ac7}, {0x10ac9, 0x10ae4}, {0x10b00, 0x10b35},
................................................................................
   218    218       {0x10c80, 0x10cb2}, {0x10cc0, 0x10cf2}, {0x11003, 0x11037}, {0x11083, 0x110af},
   219    219       {0x110d0, 0x110e8}, {0x11103, 0x11126}, {0x11150, 0x11172}, {0x11183, 0x111b2},
   220    220       {0x111c1, 0x111c4}, {0x11200, 0x11211}, {0x11213, 0x1122b}, {0x11280, 0x11286},
   221    221       {0x1128a, 0x1128d}, {0x1128f, 0x1129d}, {0x1129f, 0x112a8}, {0x112b0, 0x112de},
   222    222       {0x11305, 0x1130c}, {0x11313, 0x11328}, {0x1132a, 0x11330}, {0x11335, 0x11339},
   223    223       {0x1135d, 0x11361}, {0x11400, 0x11434}, {0x11447, 0x1144a}, {0x11480, 0x114af},
   224    224       {0x11580, 0x115ae}, {0x115d8, 0x115db}, {0x11600, 0x1162f}, {0x11680, 0x116aa},
   225         -    {0x11700, 0x11719}, {0x118a0, 0x118df}, {0x11ac0, 0x11af8}, {0x11c00, 0x11c08},
   226         -    {0x11c0a, 0x11c2e}, {0x11c72, 0x11c8f}, {0x12000, 0x12399}, {0x12480, 0x12543},
   227         -    {0x13000, 0x1342e}, {0x14400, 0x14646}, {0x16800, 0x16a38}, {0x16a40, 0x16a5e},
   228         -    {0x16ad0, 0x16aed}, {0x16b00, 0x16b2f}, {0x16b40, 0x16b43}, {0x16b63, 0x16b77},
   229         -    {0x16b7d, 0x16b8f}, {0x16f00, 0x16f44}, {0x16f93, 0x16f9f}, {0x17000, 0x187ec},
   230         -    {0x18800, 0x18af2}, {0x1bc00, 0x1bc6a}, {0x1bc70, 0x1bc7c}, {0x1bc80, 0x1bc88},
   231         -    {0x1bc90, 0x1bc99}, {0x1d400, 0x1d454}, {0x1d456, 0x1d49c}, {0x1d4a9, 0x1d4ac},
   232         -    {0x1d4ae, 0x1d4b9}, {0x1d4bd, 0x1d4c3}, {0x1d4c5, 0x1d505}, {0x1d507, 0x1d50a},
   233         -    {0x1d50d, 0x1d514}, {0x1d516, 0x1d51c}, {0x1d51e, 0x1d539}, {0x1d53b, 0x1d53e},
   234         -    {0x1d540, 0x1d544}, {0x1d54a, 0x1d550}, {0x1d552, 0x1d6a5}, {0x1d6a8, 0x1d6c0},
   235         -    {0x1d6c2, 0x1d6da}, {0x1d6dc, 0x1d6fa}, {0x1d6fc, 0x1d714}, {0x1d716, 0x1d734},
   236         -    {0x1d736, 0x1d74e}, {0x1d750, 0x1d76e}, {0x1d770, 0x1d788}, {0x1d78a, 0x1d7a8},
   237         -    {0x1d7aa, 0x1d7c2}, {0x1d7c4, 0x1d7cb}, {0x1e800, 0x1e8c4}, {0x1e900, 0x1e943},
   238         -    {0x1ee00, 0x1ee03}, {0x1ee05, 0x1ee1f}, {0x1ee29, 0x1ee32}, {0x1ee34, 0x1ee37},
   239         -    {0x1ee4d, 0x1ee4f}, {0x1ee67, 0x1ee6a}, {0x1ee6c, 0x1ee72}, {0x1ee74, 0x1ee77},
   240         -    {0x1ee79, 0x1ee7c}, {0x1ee80, 0x1ee89}, {0x1ee8b, 0x1ee9b}, {0x1eea1, 0x1eea3},
   241         -    {0x1eea5, 0x1eea9}, {0x1eeab, 0x1eebb}, {0x20000, 0x2a6d6}, {0x2a700, 0x2b734},
   242         -    {0x2b740, 0x2b81d}, {0x2b820, 0x2cea1}, {0x2f800, 0x2fa1d}
          225  +    {0x11700, 0x11719}, {0x118a0, 0x118df}, {0x11a0b, 0x11a32}, {0x11a5c, 0x11a83},
          226  +    {0x11a86, 0x11a89}, {0x11ac0, 0x11af8}, {0x11c00, 0x11c08}, {0x11c0a, 0x11c2e},
          227  +    {0x11c72, 0x11c8f}, {0x11d00, 0x11d06}, {0x11d0b, 0x11d30}, {0x12000, 0x12399},
          228  +    {0x12480, 0x12543}, {0x13000, 0x1342e}, {0x14400, 0x14646}, {0x16800, 0x16a38},
          229  +    {0x16a40, 0x16a5e}, {0x16ad0, 0x16aed}, {0x16b00, 0x16b2f}, {0x16b40, 0x16b43},
          230  +    {0x16b63, 0x16b77}, {0x16b7d, 0x16b8f}, {0x16f00, 0x16f44}, {0x16f93, 0x16f9f},
          231  +    {0x17000, 0x187ec}, {0x18800, 0x18af2}, {0x1b000, 0x1b11e}, {0x1b170, 0x1b2fb},
          232  +    {0x1bc00, 0x1bc6a}, {0x1bc70, 0x1bc7c}, {0x1bc80, 0x1bc88}, {0x1bc90, 0x1bc99},
          233  +    {0x1d400, 0x1d454}, {0x1d456, 0x1d49c}, {0x1d4a9, 0x1d4ac}, {0x1d4ae, 0x1d4b9},
          234  +    {0x1d4bd, 0x1d4c3}, {0x1d4c5, 0x1d505}, {0x1d507, 0x1d50a}, {0x1d50d, 0x1d514},
          235  +    {0x1d516, 0x1d51c}, {0x1d51e, 0x1d539}, {0x1d53b, 0x1d53e}, {0x1d540, 0x1d544},
          236  +    {0x1d54a, 0x1d550}, {0x1d552, 0x1d6a5}, {0x1d6a8, 0x1d6c0}, {0x1d6c2, 0x1d6da},
          237  +    {0x1d6dc, 0x1d6fa}, {0x1d6fc, 0x1d714}, {0x1d716, 0x1d734}, {0x1d736, 0x1d74e},
          238  +    {0x1d750, 0x1d76e}, {0x1d770, 0x1d788}, {0x1d78a, 0x1d7a8}, {0x1d7aa, 0x1d7c2},
          239  +    {0x1d7c4, 0x1d7cb}, {0x1e800, 0x1e8c4}, {0x1e900, 0x1e943}, {0x1ee00, 0x1ee03},
          240  +    {0x1ee05, 0x1ee1f}, {0x1ee29, 0x1ee32}, {0x1ee34, 0x1ee37}, {0x1ee4d, 0x1ee4f},
          241  +    {0x1ee67, 0x1ee6a}, {0x1ee6c, 0x1ee72}, {0x1ee74, 0x1ee77}, {0x1ee79, 0x1ee7c},
          242  +    {0x1ee80, 0x1ee89}, {0x1ee8b, 0x1ee9b}, {0x1eea1, 0x1eea3}, {0x1eea5, 0x1eea9},
          243  +    {0x1eeab, 0x1eebb}, {0x20000, 0x2a6d6}, {0x2a700, 0x2b734}, {0x2b740, 0x2b81d},
          244  +    {0x2b820, 0x2cea1}, {0x2ceb0, 0x2ebe0}, {0x2f800, 0x2fa1d}
   243    245   #endif
   244    246   };
   245    247   
   246    248   #define NUM_ALPHA_RANGE (sizeof(alphaRangeTable)/sizeof(crange))
   247    249   
   248    250   static const chr alphaCharTable[] = {
   249    251       0xaa, 0xb5, 0xba, 0x2ec, 0x2ee, 0x376, 0x377, 0x37f, 0x386,
   250    252       0x38c, 0x559, 0x66e, 0x66f, 0x6d5, 0x6e5, 0x6e6, 0x6ee, 0x6ef,
   251    253       0x6ff, 0x710, 0x7b1, 0x7f4, 0x7f5, 0x7fa, 0x81a, 0x824, 0x828,
   252    254       0x93d, 0x950, 0x98f, 0x990, 0x9b2, 0x9bd, 0x9ce, 0x9dc, 0x9dd,
   253         -    0x9f0, 0x9f1, 0xa0f, 0xa10, 0xa32, 0xa33, 0xa35, 0xa36, 0xa38,
   254         -    0xa39, 0xa5e, 0xab2, 0xab3, 0xabd, 0xad0, 0xae0, 0xae1, 0xaf9,
   255         -    0xb0f, 0xb10, 0xb32, 0xb33, 0xb3d, 0xb5c, 0xb5d, 0xb71, 0xb83,
   256         -    0xb99, 0xb9a, 0xb9c, 0xb9e, 0xb9f, 0xba3, 0xba4, 0xbd0, 0xc3d,
   257         -    0xc60, 0xc61, 0xc80, 0xcbd, 0xcde, 0xce0, 0xce1, 0xcf1, 0xcf2,
   258         -    0xd3d, 0xd4e, 0xdbd, 0xe32, 0xe33, 0xe81, 0xe82, 0xe84, 0xe87,
   259         -    0xe88, 0xe8a, 0xe8d, 0xea5, 0xea7, 0xeaa, 0xeab, 0xeb2, 0xeb3,
   260         -    0xebd, 0xec6, 0xf00, 0x103f, 0x1061, 0x1065, 0x1066, 0x108e, 0x10c7,
   261         -    0x10cd, 0x1258, 0x12c0, 0x17d7, 0x17dc, 0x18aa, 0x1aa7, 0x1bae, 0x1baf,
   262         -    0x1cf5, 0x1cf6, 0x1f59, 0x1f5b, 0x1f5d, 0x1fbe, 0x2071, 0x207f, 0x2102,
   263         -    0x2107, 0x2115, 0x2124, 0x2126, 0x2128, 0x214e, 0x2183, 0x2184, 0x2cf2,
   264         -    0x2cf3, 0x2d27, 0x2d2d, 0x2d6f, 0x2e2f, 0x3005, 0x3006, 0x303b, 0x303c,
   265         -    0xa62a, 0xa62b, 0xa8fb, 0xa8fd, 0xa9cf, 0xaa7a, 0xaab1, 0xaab5, 0xaab6,
   266         -    0xaac0, 0xaac2, 0xfb1d, 0xfb3e, 0xfb40, 0xfb41, 0xfb43, 0xfb44
          255  +    0x9f0, 0x9f1, 0x9fc, 0xa0f, 0xa10, 0xa32, 0xa33, 0xa35, 0xa36,
          256  +    0xa38, 0xa39, 0xa5e, 0xab2, 0xab3, 0xabd, 0xad0, 0xae0, 0xae1,
          257  +    0xaf9, 0xb0f, 0xb10, 0xb32, 0xb33, 0xb3d, 0xb5c, 0xb5d, 0xb71,
          258  +    0xb83, 0xb99, 0xb9a, 0xb9c, 0xb9e, 0xb9f, 0xba3, 0xba4, 0xbd0,
          259  +    0xc3d, 0xc60, 0xc61, 0xc80, 0xcbd, 0xcde, 0xce0, 0xce1, 0xcf1,
          260  +    0xcf2, 0xd3d, 0xd4e, 0xdbd, 0xe32, 0xe33, 0xe81, 0xe82, 0xe84,
          261  +    0xe87, 0xe88, 0xe8a, 0xe8d, 0xea5, 0xea7, 0xeaa, 0xeab, 0xeb2,
          262  +    0xeb3, 0xebd, 0xec6, 0xf00, 0x103f, 0x1061, 0x1065, 0x1066, 0x108e,
          263  +    0x10c7, 0x10cd, 0x1258, 0x12c0, 0x17d7, 0x17dc, 0x18aa, 0x1aa7, 0x1bae,
          264  +    0x1baf, 0x1cf5, 0x1cf6, 0x1f59, 0x1f5b, 0x1f5d, 0x1fbe, 0x2071, 0x207f,
          265  +    0x2102, 0x2107, 0x2115, 0x2124, 0x2126, 0x2128, 0x214e, 0x2183, 0x2184,
          266  +    0x2cf2, 0x2cf3, 0x2d27, 0x2d2d, 0x2d6f, 0x2e2f, 0x3005, 0x3006, 0x303b,
          267  +    0x303c, 0xa62a, 0xa62b, 0xa8fb, 0xa8fd, 0xa9cf, 0xaa7a, 0xaab1, 0xaab5,
          268  +    0xaab6, 0xaac0, 0xaac2, 0xfb1d, 0xfb3e, 0xfb40, 0xfb41, 0xfb43, 0xfb44
   267    269   #if TCL_UTF_MAX > 4
   268    270       ,0x1003c, 0x1003d, 0x10808, 0x10837, 0x10838, 0x1083c, 0x108f4, 0x108f5, 0x109be,
   269    271       0x109bf, 0x10a00, 0x11176, 0x111da, 0x111dc, 0x11288, 0x1130f, 0x11310, 0x11332,
   270         -    0x11333, 0x1133d, 0x11350, 0x114c4, 0x114c5, 0x114c7, 0x11644, 0x118ff, 0x11c40,
   271         -    0x16f50, 0x16fe0, 0x1b000, 0x1b001, 0x1d49e, 0x1d49f, 0x1d4a2, 0x1d4a5, 0x1d4a6,
   272         -    0x1d4bb, 0x1d546, 0x1ee21, 0x1ee22, 0x1ee24, 0x1ee27, 0x1ee39, 0x1ee3b, 0x1ee42,
   273         -    0x1ee47, 0x1ee49, 0x1ee4b, 0x1ee51, 0x1ee52, 0x1ee54, 0x1ee57, 0x1ee59, 0x1ee5b,
   274         -    0x1ee5d, 0x1ee5f, 0x1ee61, 0x1ee62, 0x1ee64, 0x1ee7e
          272  +    0x11333, 0x1133d, 0x11350, 0x114c4, 0x114c5, 0x114c7, 0x11644, 0x118ff, 0x11a00,
          273  +    0x11a3a, 0x11a50, 0x11c40, 0x11d08, 0x11d09, 0x11d46, 0x16f50, 0x16fe0, 0x16fe1,
          274  +    0x1d49e, 0x1d49f, 0x1d4a2, 0x1d4a5, 0x1d4a6, 0x1d4bb, 0x1d546, 0x1ee21, 0x1ee22,
          275  +    0x1ee24, 0x1ee27, 0x1ee39, 0x1ee3b, 0x1ee42, 0x1ee47, 0x1ee49, 0x1ee4b, 0x1ee51,
          276  +    0x1ee52, 0x1ee54, 0x1ee57, 0x1ee59, 0x1ee5b, 0x1ee5d, 0x1ee5f, 0x1ee61, 0x1ee62,
          277  +    0x1ee64, 0x1ee7e
   275    278   #endif
   276    279   };
   277    280   
   278    281   #define NUM_ALPHA_CHAR (sizeof(alphaCharTable)/sizeof(chr))
   279    282   
   280    283   /*
   281    284    * Unicode: control characters.
................................................................................
   317    320       {0x1c50, 0x1c59}, {0xa620, 0xa629}, {0xa8d0, 0xa8d9}, {0xa900, 0xa909},
   318    321       {0xa9d0, 0xa9d9}, {0xa9f0, 0xa9f9}, {0xaa50, 0xaa59}, {0xabf0, 0xabf9},
   319    322       {0xff10, 0xff19}
   320    323   #if TCL_UTF_MAX > 4
   321    324       ,{0x104a0, 0x104a9}, {0x11066, 0x1106f}, {0x110f0, 0x110f9}, {0x11136, 0x1113f},
   322    325       {0x111d0, 0x111d9}, {0x112f0, 0x112f9}, {0x11450, 0x11459}, {0x114d0, 0x114d9},
   323    326       {0x11650, 0x11659}, {0x116c0, 0x116c9}, {0x11730, 0x11739}, {0x118e0, 0x118e9},
   324         -    {0x11c50, 0x11c59}, {0x16a60, 0x16a69}, {0x16b50, 0x16b59}, {0x1d7ce, 0x1d7ff},
   325         -    {0x1e950, 0x1e959}
          327  +    {0x11c50, 0x11c59}, {0x11d50, 0x11d59}, {0x16a60, 0x16a69}, {0x16b50, 0x16b59},
          328  +    {0x1d7ce, 0x1d7ff}, {0x1e950, 0x1e959}
   326    329   #endif
   327    330   };
   328    331   
   329    332   #define NUM_DIGIT_RANGE (sizeof(digitRangeTable)/sizeof(crange))
   330    333   
   331    334   /*
   332    335    * no singletons of digit characters.
................................................................................
   341    344       {0x55a, 0x55f}, {0x66a, 0x66d}, {0x700, 0x70d}, {0x7f7, 0x7f9},
   342    345       {0x830, 0x83e}, {0xf04, 0xf12}, {0xf3a, 0xf3d}, {0xfd0, 0xfd4},
   343    346       {0x104a, 0x104f}, {0x1360, 0x1368}, {0x16eb, 0x16ed}, {0x17d4, 0x17d6},
   344    347       {0x17d8, 0x17da}, {0x1800, 0x180a}, {0x1aa0, 0x1aa6}, {0x1aa8, 0x1aad},
   345    348       {0x1b5a, 0x1b60}, {0x1bfc, 0x1bff}, {0x1c3b, 0x1c3f}, {0x1cc0, 0x1cc7},
   346    349       {0x2010, 0x2027}, {0x2030, 0x2043}, {0x2045, 0x2051}, {0x2053, 0x205e},
   347    350       {0x2308, 0x230b}, {0x2768, 0x2775}, {0x27e6, 0x27ef}, {0x2983, 0x2998},
   348         -    {0x29d8, 0x29db}, {0x2cf9, 0x2cfc}, {0x2e00, 0x2e2e}, {0x2e30, 0x2e44},
          351  +    {0x29d8, 0x29db}, {0x2cf9, 0x2cfc}, {0x2e00, 0x2e2e}, {0x2e30, 0x2e49},
   349    352       {0x3001, 0x3003}, {0x3008, 0x3011}, {0x3014, 0x301f}, {0xa60d, 0xa60f},
   350    353       {0xa6f2, 0xa6f7}, {0xa874, 0xa877}, {0xa8f8, 0xa8fa}, {0xa9c1, 0xa9cd},
   351    354       {0xaa5c, 0xaa5f}, {0xfe10, 0xfe19}, {0xfe30, 0xfe52}, {0xfe54, 0xfe61},
   352    355       {0xff01, 0xff03}, {0xff05, 0xff0a}, {0xff0c, 0xff0f}, {0xff3b, 0xff3d},
   353    356       {0xff5f, 0xff65}
   354    357   #if TCL_UTF_MAX > 4
   355    358       ,{0x10100, 0x10102}, {0x10a50, 0x10a58}, {0x10af0, 0x10af6}, {0x10b39, 0x10b3f},
   356    359       {0x10b99, 0x10b9c}, {0x11047, 0x1104d}, {0x110be, 0x110c1}, {0x11140, 0x11143},
   357    360       {0x111c5, 0x111c9}, {0x111dd, 0x111df}, {0x11238, 0x1123d}, {0x1144b, 0x1144f},
   358    361       {0x115c1, 0x115d7}, {0x11641, 0x11643}, {0x11660, 0x1166c}, {0x1173c, 0x1173e},
   359         -    {0x11c41, 0x11c45}, {0x12470, 0x12474}, {0x16b37, 0x16b3b}, {0x1da87, 0x1da8b}
          362  +    {0x11a3f, 0x11a46}, {0x11a9a, 0x11a9c}, {0x11a9e, 0x11aa2}, {0x11c41, 0x11c45},
          363  +    {0x12470, 0x12474}, {0x16b37, 0x16b3b}, {0x1da87, 0x1da8b}
   360    364   #endif
   361    365   };
   362    366   
   363    367   #define NUM_PUNCT_RANGE (sizeof(punctRangeTable)/sizeof(crange))
   364    368   
   365    369   static const chr punctCharTable[] = {
   366    370       0x3a, 0x3b, 0x3f, 0x40, 0x5f, 0x7b, 0x7d, 0xa1, 0xa7,
   367    371       0xab, 0xb6, 0xb7, 0xbb, 0xbf, 0x37e, 0x387, 0x589, 0x58a,
   368    372       0x5be, 0x5c0, 0x5c3, 0x5c6, 0x5f3, 0x5f4, 0x609, 0x60a, 0x60c,
   369    373       0x60d, 0x61b, 0x61e, 0x61f, 0x6d4, 0x85e, 0x964, 0x965, 0x970,
   370         -    0xaf0, 0xdf4, 0xe4f, 0xe5a, 0xe5b, 0xf14, 0xf85, 0xfd9, 0xfda,
   371         -    0x10fb, 0x1400, 0x166d, 0x166e, 0x169b, 0x169c, 0x1735, 0x1736, 0x1944,
   372         -    0x1945, 0x1a1e, 0x1a1f, 0x1c7e, 0x1c7f, 0x1cd3, 0x207d, 0x207e, 0x208d,
   373         -    0x208e, 0x2329, 0x232a, 0x27c5, 0x27c6, 0x29fc, 0x29fd, 0x2cfe, 0x2cff,
   374         -    0x2d70, 0x3030, 0x303d, 0x30a0, 0x30fb, 0xa4fe, 0xa4ff, 0xa673, 0xa67e,
   375         -    0xa8ce, 0xa8cf, 0xa8fc, 0xa92e, 0xa92f, 0xa95f, 0xa9de, 0xa9df, 0xaade,
   376         -    0xaadf, 0xaaf0, 0xaaf1, 0xabeb, 0xfd3e, 0xfd3f, 0xfe63, 0xfe68, 0xfe6a,
   377         -    0xfe6b, 0xff1a, 0xff1b, 0xff1f, 0xff20, 0xff3f, 0xff5b, 0xff5d
          374  +    0x9fd, 0xaf0, 0xdf4, 0xe4f, 0xe5a, 0xe5b, 0xf14, 0xf85, 0xfd9,
          375  +    0xfda, 0x10fb, 0x1400, 0x166d, 0x166e, 0x169b, 0x169c, 0x1735, 0x1736,
          376  +    0x1944, 0x1945, 0x1a1e, 0x1a1f, 0x1c7e, 0x1c7f, 0x1cd3, 0x207d, 0x207e,
          377  +    0x208d, 0x208e, 0x2329, 0x232a, 0x27c5, 0x27c6, 0x29fc, 0x29fd, 0x2cfe,
          378  +    0x2cff, 0x2d70, 0x3030, 0x303d, 0x30a0, 0x30fb, 0xa4fe, 0xa4ff, 0xa673,
          379  +    0xa67e, 0xa8ce, 0xa8cf, 0xa8fc, 0xa92e, 0xa92f, 0xa95f, 0xa9de, 0xa9df,
          380  +    0xaade, 0xaadf, 0xaaf0, 0xaaf1, 0xabeb, 0xfd3e, 0xfd3f, 0xfe63, 0xfe68,
          381  +    0xfe6a, 0xfe6b, 0xff1a, 0xff1b, 0xff1f, 0xff20, 0xff3f, 0xff5b, 0xff5d
   378    382   #if TCL_UTF_MAX > 4
   379    383       ,0x1039f, 0x103d0, 0x1056f, 0x10857, 0x1091f, 0x1093f, 0x10a7f, 0x110bb, 0x110bc,
   380    384       0x11174, 0x11175, 0x111cd, 0x111db, 0x112a9, 0x1145b, 0x1145d, 0x114c6, 0x11c70,
   381    385       0x11c71, 0x16a6e, 0x16a6f, 0x16af5, 0x16b44, 0x1bc9f, 0x1e95e, 0x1e95f
   382    386   #endif
   383    387   };
   384    388   
................................................................................
   611    615   
   612    616   static const crange graphRangeTable[] = {
   613    617       {0x21, 0x7e}, {0xa1, 0xac}, {0xae, 0x377}, {0x37a, 0x37f},
   614    618       {0x384, 0x38a}, {0x38e, 0x3a1}, {0x3a3, 0x52f}, {0x531, 0x556},
   615    619       {0x559, 0x55f}, {0x561, 0x587}, {0x58d, 0x58f}, {0x591, 0x5c7},
   616    620       {0x5d0, 0x5ea}, {0x5f0, 0x5f4}, {0x606, 0x61b}, {0x61e, 0x6dc},
   617    621       {0x6de, 0x70d}, {0x710, 0x74a}, {0x74d, 0x7b1}, {0x7c0, 0x7fa},
   618         -    {0x800, 0x82d}, {0x830, 0x83e}, {0x840, 0x85b}, {0x8a0, 0x8b4},
   619         -    {0x8b6, 0x8bd}, {0x8d4, 0x8e1}, {0x8e3, 0x983}, {0x985, 0x98c},
   620         -    {0x993, 0x9a8}, {0x9aa, 0x9b0}, {0x9b6, 0x9b9}, {0x9bc, 0x9c4},
   621         -    {0x9cb, 0x9ce}, {0x9df, 0x9e3}, {0x9e6, 0x9fb}, {0xa01, 0xa03},
   622         -    {0xa05, 0xa0a}, {0xa13, 0xa28}, {0xa2a, 0xa30}, {0xa3e, 0xa42},
   623         -    {0xa4b, 0xa4d}, {0xa59, 0xa5c}, {0xa66, 0xa75}, {0xa81, 0xa83},
   624         -    {0xa85, 0xa8d}, {0xa8f, 0xa91}, {0xa93, 0xaa8}, {0xaaa, 0xab0},
   625         -    {0xab5, 0xab9}, {0xabc, 0xac5}, {0xac7, 0xac9}, {0xacb, 0xacd},
   626         -    {0xae0, 0xae3}, {0xae6, 0xaf1}, {0xb01, 0xb03}, {0xb05, 0xb0c},
   627         -    {0xb13, 0xb28}, {0xb2a, 0xb30}, {0xb35, 0xb39}, {0xb3c, 0xb44},
   628         -    {0xb4b, 0xb4d}, {0xb5f, 0xb63}, {0xb66, 0xb77}, {0xb85, 0xb8a},
   629         -    {0xb8e, 0xb90}, {0xb92, 0xb95}, {0xba8, 0xbaa}, {0xbae, 0xbb9},
   630         -    {0xbbe, 0xbc2}, {0xbc6, 0xbc8}, {0xbca, 0xbcd}, {0xbe6, 0xbfa},
   631         -    {0xc00, 0xc03}, {0xc05, 0xc0c}, {0xc0e, 0xc10}, {0xc12, 0xc28},
   632         -    {0xc2a, 0xc39}, {0xc3d, 0xc44}, {0xc46, 0xc48}, {0xc4a, 0xc4d},
   633         -    {0xc58, 0xc5a}, {0xc60, 0xc63}, {0xc66, 0xc6f}, {0xc78, 0xc83},
   634         -    {0xc85, 0xc8c}, {0xc8e, 0xc90}, {0xc92, 0xca8}, {0xcaa, 0xcb3},
   635         -    {0xcb5, 0xcb9}, {0xcbc, 0xcc4}, {0xcc6, 0xcc8}, {0xcca, 0xccd},
   636         -    {0xce0, 0xce3}, {0xce6, 0xcef}, {0xd01, 0xd03}, {0xd05, 0xd0c},
   637         -    {0xd0e, 0xd10}, {0xd12, 0xd3a}, {0xd3d, 0xd44}, {0xd46, 0xd48},
   638         -    {0xd4a, 0xd4f}, {0xd54, 0xd63}, {0xd66, 0xd7f}, {0xd85, 0xd96},
   639         -    {0xd9a, 0xdb1}, {0xdb3, 0xdbb}, {0xdc0, 0xdc6}, {0xdcf, 0xdd4},
   640         -    {0xdd8, 0xddf}, {0xde6, 0xdef}, {0xdf2, 0xdf4}, {0xe01, 0xe3a},
   641         -    {0xe3f, 0xe5b}, {0xe94, 0xe97}, {0xe99, 0xe9f}, {0xea1, 0xea3},
   642         -    {0xead, 0xeb9}, {0xebb, 0xebd}, {0xec0, 0xec4}, {0xec8, 0xecd},
   643         -    {0xed0, 0xed9}, {0xedc, 0xedf}, {0xf00, 0xf47}, {0xf49, 0xf6c},
   644         -    {0xf71, 0xf97}, {0xf99, 0xfbc}, {0xfbe, 0xfcc}, {0xfce, 0xfda},
   645         -    {0x1000, 0x10c5}, {0x10d0, 0x1248}, {0x124a, 0x124d}, {0x1250, 0x1256},
   646         -    {0x125a, 0x125d}, {0x1260, 0x1288}, {0x128a, 0x128d}, {0x1290, 0x12b0},
   647         -    {0x12b2, 0x12b5}, {0x12b8, 0x12be}, {0x12c2, 0x12c5}, {0x12c8, 0x12d6},
   648         -    {0x12d8, 0x1310}, {0x1312, 0x1315}, {0x1318, 0x135a}, {0x135d, 0x137c},
   649         -    {0x1380, 0x1399}, {0x13a0, 0x13f5}, {0x13f8, 0x13fd}, {0x1400, 0x167f},
   650         -    {0x1681, 0x169c}, {0x16a0, 0x16f8}, {0x1700, 0x170c}, {0x170e, 0x1714},
   651         -    {0x1720, 0x1736}, {0x1740, 0x1753}, {0x1760, 0x176c}, {0x176e, 0x1770},
   652         -    {0x1780, 0x17dd}, {0x17e0, 0x17e9}, {0x17f0, 0x17f9}, {0x1800, 0x180d},
   653         -    {0x1810, 0x1819}, {0x1820, 0x1877}, {0x1880, 0x18aa}, {0x18b0, 0x18f5},
   654         -    {0x1900, 0x191e}, {0x1920, 0x192b}, {0x1930, 0x193b}, {0x1944, 0x196d},
   655         -    {0x1970, 0x1974}, {0x1980, 0x19ab}, {0x19b0, 0x19c9}, {0x19d0, 0x19da},
   656         -    {0x19de, 0x1a1b}, {0x1a1e, 0x1a5e}, {0x1a60, 0x1a7c}, {0x1a7f, 0x1a89},
   657         -    {0x1a90, 0x1a99}, {0x1aa0, 0x1aad}, {0x1ab0, 0x1abe}, {0x1b00, 0x1b4b},
   658         -    {0x1b50, 0x1b7c}, {0x1b80, 0x1bf3}, {0x1bfc, 0x1c37}, {0x1c3b, 0x1c49},
   659         -    {0x1c4d, 0x1c88}, {0x1cc0, 0x1cc7}, {0x1cd0, 0x1cf6}, {0x1d00, 0x1df5},
   660         -    {0x1dfb, 0x1f15}, {0x1f18, 0x1f1d}, {0x1f20, 0x1f45}, {0x1f48, 0x1f4d},
   661         -    {0x1f50, 0x1f57}, {0x1f5f, 0x1f7d}, {0x1f80, 0x1fb4}, {0x1fb6, 0x1fc4},
   662         -    {0x1fc6, 0x1fd3}, {0x1fd6, 0x1fdb}, {0x1fdd, 0x1fef}, {0x1ff2, 0x1ff4},
   663         -    {0x1ff6, 0x1ffe}, {0x2010, 0x2027}, {0x2030, 0x205e}, {0x2074, 0x208e},
   664         -    {0x2090, 0x209c}, {0x20a0, 0x20be}, {0x20d0, 0x20f0}, {0x2100, 0x218b},
   665         -    {0x2190, 0x23fe}, {0x2400, 0x2426}, {0x2440, 0x244a}, {0x2460, 0x2b73},
   666         -    {0x2b76, 0x2b95}, {0x2b98, 0x2bb9}, {0x2bbd, 0x2bc8}, {0x2bca, 0x2bd1},
          622  +    {0x800, 0x82d}, {0x830, 0x83e}, {0x840, 0x85b}, {0x860, 0x86a},
          623  +    {0x8a0, 0x8b4}, {0x8b6, 0x8bd}, {0x8d4, 0x8e1}, {0x8e3, 0x983},
          624  +    {0x985, 0x98c}, {0x993, 0x9a8}, {0x9aa, 0x9b0}, {0x9b6, 0x9b9},
          625  +    {0x9bc, 0x9c4}, {0x9cb, 0x9ce}, {0x9df, 0x9e3}, {0x9e6, 0x9fd},
          626  +    {0xa01, 0xa03}, {0xa05, 0xa0a}, {0xa13, 0xa28}, {0xa2a, 0xa30},
          627  +    {0xa3e, 0xa42}, {0xa4b, 0xa4d}, {0xa59, 0xa5c}, {0xa66, 0xa75},
          628  +    {0xa81, 0xa83}, {0xa85, 0xa8d}, {0xa8f, 0xa91}, {0xa93, 0xaa8},
          629  +    {0xaaa, 0xab0}, {0xab5, 0xab9}, {0xabc, 0xac5}, {0xac7, 0xac9},
          630  +    {0xacb, 0xacd}, {0xae0, 0xae3}, {0xae6, 0xaf1}, {0xaf9, 0xaff},
          631  +    {0xb01, 0xb03}, {0xb05, 0xb0c}, {0xb13, 0xb28}, {0xb2a, 0xb30},
          632  +    {0xb35, 0xb39}, {0xb3c, 0xb44}, {0xb4b, 0xb4d}, {0xb5f, 0xb63},
          633  +    {0xb66, 0xb77}, {0xb85, 0xb8a}, {0xb8e, 0xb90}, {0xb92, 0xb95},
          634  +    {0xba8, 0xbaa}, {0xbae, 0xbb9}, {0xbbe, 0xbc2}, {0xbc6, 0xbc8},
          635  +    {0xbca, 0xbcd}, {0xbe6, 0xbfa}, {0xc00, 0xc03}, {0xc05, 0xc0c},
          636  +    {0xc0e, 0xc10}, {0xc12, 0xc28}, {0xc2a, 0xc39}, {0xc3d, 0xc44},
          637  +    {0xc46, 0xc48}, {0xc4a, 0xc4d}, {0xc58, 0xc5a}, {0xc60, 0xc63},
          638  +    {0xc66, 0xc6f}, {0xc78, 0xc83}, {0xc85, 0xc8c}, {0xc8e, 0xc90},
          639  +    {0xc92, 0xca8}, {0xcaa, 0xcb3}, {0xcb5, 0xcb9}, {0xcbc, 0xcc4},
          640  +    {0xcc6, 0xcc8}, {0xcca, 0xccd}, {0xce0, 0xce3}, {0xce6, 0xcef},
          641  +    {0xd00, 0xd03}, {0xd05, 0xd0c}, {0xd0e, 0xd10}, {0xd12, 0xd44},
          642  +    {0xd46, 0xd48}, {0xd4a, 0xd4f}, {0xd54, 0xd63}, {0xd66, 0xd7f},
          643  +    {0xd85, 0xd96}, {0xd9a, 0xdb1}, {0xdb3, 0xdbb}, {0xdc0, 0xdc6},
          644  +    {0xdcf, 0xdd4}, {0xdd8, 0xddf}, {0xde6, 0xdef}, {0xdf2, 0xdf4},
          645  +    {0xe01, 0xe3a}, {0xe3f, 0xe5b}, {0xe94, 0xe97}, {0xe99, 0xe9f},
          646  +    {0xea1, 0xea3}, {0xead, 0xeb9}, {0xebb, 0xebd}, {0xec0, 0xec4},
          647  +    {0xec8, 0xecd}, {0xed0, 0xed9}, {0xedc, 0xedf}, {0xf00, 0xf47},
          648  +    {0xf49, 0xf6c}, {0xf71, 0xf97}, {0xf99, 0xfbc}, {0xfbe, 0xfcc},
          649  +    {0xfce, 0xfda}, {0x1000, 0x10c5}, {0x10d0, 0x1248}, {0x124a, 0x124d},
          650  +    {0x1250, 0x1256}, {0x125a, 0x125d}, {0x1260, 0x1288}, {0x128a, 0x128d},
          651  +    {0x1290, 0x12b0}, {0x12b2, 0x12b5}, {0x12b8, 0x12be}, {0x12c2, 0x12c5},
          652  +    {0x12c8, 0x12d6}, {0x12d8, 0x1310}, {0x1312, 0x1315}, {0x1318, 0x135a},
          653  +    {0x135d, 0x137c}, {0x1380, 0x1399}, {0x13a0, 0x13f5}, {0x13f8, 0x13fd},
          654  +    {0x1400, 0x167f}, {0x1681, 0x169c}, {0x16a0, 0x16f8}, {0x1700, 0x170c},
          655  +    {0x170e, 0x1714}, {0x1720, 0x1736}, {0x1740, 0x1753}, {0x1760, 0x176c},
          656  +    {0x176e, 0x1770}, {0x1780, 0x17dd}, {0x17e0, 0x17e9}, {0x17f0, 0x17f9},
          657  +    {0x1800, 0x180d}, {0x1810, 0x1819}, {0x1820, 0x1877}, {0x1880, 0x18aa},
          658  +    {0x18b0, 0x18f5}, {0x1900, 0x191e}, {0x1920, 0x192b}, {0x1930, 0x193b},
          659  +    {0x1944, 0x196d}, {0x1970, 0x1974}, {0x1980, 0x19ab}, {0x19b0, 0x19c9},
          660  +    {0x19d0, 0x19da}, {0x19de, 0x1a1b}, {0x1a1e, 0x1a5e}, {0x1a60, 0x1a7c},
          661  +    {0x1a7f, 0x1a89}, {0x1a90, 0x1a99}, {0x1aa0, 0x1aad}, {0x1ab0, 0x1abe},
          662  +    {0x1b00, 0x1b4b}, {0x1b50, 0x1b7c}, {0x1b80, 0x1bf3}, {0x1bfc, 0x1c37},
          663  +    {0x1c3b, 0x1c49}, {0x1c4d, 0x1c88}, {0x1cc0, 0x1cc7}, {0x1cd0, 0x1cf9},
          664  +    {0x1d00, 0x1df9}, {0x1dfb, 0x1f15}, {0x1f18, 0x1f1d}, {0x1f20, 0x1f45},
          665  +    {0x1f48, 0x1f4d}, {0x1f50, 0x1f57}, {0x1f5f, 0x1f7d}, {0x1f80, 0x1fb4},
          666  +    {0x1fb6, 0x1fc4}, {0x1fc6, 0x1fd3}, {0x1fd6, 0x1fdb}, {0x1fdd, 0x1fef},
          667  +    {0x1ff2, 0x1ff4}, {0x1ff6, 0x1ffe}, {0x2010, 0x2027}, {0x2030, 0x205e},
          668  +    {0x2074, 0x208e}, {0x2090, 0x209c}, {0x20a0, 0x20bf}, {0x20d0, 0x20f0},
          669  +    {0x2100, 0x218b}, {0x2190, 0x2426}, {0x2440, 0x244a}, {0x2460, 0x2b73},
          670  +    {0x2b76, 0x2b95}, {0x2b98, 0x2bb9}, {0x2bbd, 0x2bc8}, {0x2bca, 0x2bd2},
   667    671       {0x2bec, 0x2bef}, {0x2c00, 0x2c2e}, {0x2c30, 0x2c5e}, {0x2c60, 0x2cf3},
   668    672       {0x2cf9, 0x2d25}, {0x2d30, 0x2d67}, {0x2d7f, 0x2d96}, {0x2da0, 0x2da6},
   669    673       {0x2da8, 0x2dae}, {0x2db0, 0x2db6}, {0x2db8, 0x2dbe}, {0x2dc0, 0x2dc6},
   670         -    {0x2dc8, 0x2dce}, {0x2dd0, 0x2dd6}, {0x2dd8, 0x2dde}, {0x2de0, 0x2e44},
          674  +    {0x2dc8, 0x2dce}, {0x2dd0, 0x2dd6}, {0x2dd8, 0x2dde}, {0x2de0, 0x2e49},
   671    675       {0x2e80, 0x2e99}, {0x2e9b, 0x2ef3}, {0x2f00, 0x2fd5}, {0x2ff0, 0x2ffb},
   672         -    {0x3001, 0x303f}, {0x3041, 0x3096}, {0x3099, 0x30ff}, {0x3105, 0x312d},
          676  +    {0x3001, 0x303f}, {0x3041, 0x3096}, {0x3099, 0x30ff}, {0x3105, 0x312e},
   673    677       {0x3131, 0x318e}, {0x3190, 0x31ba}, {0x31c0, 0x31e3}, {0x31f0, 0x321e},
   674         -    {0x3220, 0x32fe}, {0x3300, 0x4db5}, {0x4dc0, 0x9fd5}, {0xa000, 0xa48c},
          678  +    {0x3220, 0x32fe}, {0x3300, 0x4db5}, {0x4dc0, 0x9fea}, {0xa000, 0xa48c},
   675    679       {0xa490, 0xa4c6}, {0xa4d0, 0xa62b}, {0xa640, 0xa6f7}, {0xa700, 0xa7ae},
   676    680       {0xa7b0, 0xa7b7}, {0xa7f7, 0xa82b}, {0xa830, 0xa839}, {0xa840, 0xa877},
   677    681       {0xa880, 0xa8c5}, {0xa8ce, 0xa8d9}, {0xa8e0, 0xa8fd}, {0xa900, 0xa953},
   678    682       {0xa95f, 0xa97c}, {0xa980, 0xa9cd}, {0xa9cf, 0xa9d9}, {0xa9de, 0xa9fe},
   679    683       {0xaa00, 0xaa36}, {0xaa40, 0xaa4d}, {0xaa50, 0xaa59}, {0xaa5c, 0xaac2},
   680    684       {0xaadb, 0xaaf6}, {0xab01, 0xab06}, {0xab09, 0xab0e}, {0xab11, 0xab16},
   681    685       {0xab20, 0xab26}, {0xab28, 0xab2e}, {0xab30, 0xab65}, {0xab70, 0xabed},
................................................................................
   690    694       {0xfe20, 0xfe52}, {0xfe54, 0xfe66}, {0xfe68, 0xfe6b}, {0xfe70, 0xfe74},
   691    695       {0xfe76, 0xfefc}, {0xff01, 0xffbe}, {0xffc2, 0xffc7}, {0xffca, 0xffcf},
   692    696       {0xffd2, 0xffd7}, {0xffda, 0xffdc}, {0xffe0, 0xffe6}, {0xffe8, 0xffee}
   693    697   #if TCL_UTF_MAX > 4
   694    698       ,{0x10000, 0x1000b}, {0x1000d, 0x10026}, {0x10028, 0x1003a}, {0x1003f, 0x1004d},
   695    699       {0x10050, 0x1005d}, {0x10080, 0x100fa}, {0x10100, 0x10102}, {0x10107, 0x10133},
   696    700       {0x10137, 0x1018e}, {0x10190, 0x1019b}, {0x101d0, 0x101fd}, {0x10280, 0x1029c},
   697         -    {0x102a0, 0x102d0}, {0x102e0, 0x102fb}, {0x10300, 0x10323}, {0x10330, 0x1034a},
          701  +    {0x102a0, 0x102d0}, {0x102e0, 0x102fb}, {0x10300, 0x10323}, {0x1032d, 0x1034a},
   698    702       {0x10350, 0x1037a}, {0x10380, 0x1039d}, {0x1039f, 0x103c3}, {0x103c8, 0x103d5},
   699    703       {0x10400, 0x1049d}, {0x104a0, 0x104a9}, {0x104b0, 0x104d3}, {0x104d8, 0x104fb},
   700    704       {0x10500, 0x10527}, {0x10530, 0x10563}, {0x10600, 0x10736}, {0x10740, 0x10755},
   701    705       {0x10760, 0x10767}, {0x10800, 0x10805}, {0x1080a, 0x10835}, {0x1083f, 0x10855},
   702    706       {0x10857, 0x1089e}, {0x108a7, 0x108af}, {0x108e0, 0x108f2}, {0x108fb, 0x1091b},
   703    707       {0x1091f, 0x10939}, {0x10980, 0x109b7}, {0x109bc, 0x109cf}, {0x109d2, 0x10a03},
   704    708       {0x10a0c, 0x10a13}, {0x10a15, 0x10a17}, {0x10a19, 0x10a33}, {0x10a38, 0x10a3a},
................................................................................
   713    717       {0x1128f, 0x1129d}, {0x1129f, 0x112a9}, {0x112b0, 0x112ea}, {0x112f0, 0x112f9},
   714    718       {0x11300, 0x11303}, {0x11305, 0x1130c}, {0x11313, 0x11328}, {0x1132a, 0x11330},
   715    719       {0x11335, 0x11339}, {0x1133c, 0x11344}, {0x1134b, 0x1134d}, {0x1135d, 0x11363},
   716    720       {0x11366, 0x1136c}, {0x11370, 0x11374}, {0x11400, 0x11459}, {0x11480, 0x114c7},
   717    721       {0x114d0, 0x114d9}, {0x11580, 0x115b5}, {0x115b8, 0x115dd}, {0x11600, 0x11644},
   718    722       {0x11650, 0x11659}, {0x11660, 0x1166c}, {0x11680, 0x116b7}, {0x116c0, 0x116c9},
   719    723       {0x11700, 0x11719}, {0x1171d, 0x1172b}, {0x11730, 0x1173f}, {0x118a0, 0x118f2},
          724  +    {0x11a00, 0x11a47}, {0x11a50, 0x11a83}, {0x11a86, 0x11a9c}, {0x11a9e, 0x11aa2},
   720    725       {0x11ac0, 0x11af8}, {0x11c00, 0x11c08}, {0x11c0a, 0x11c36}, {0x11c38, 0x11c45},
   721    726       {0x11c50, 0x11c6c}, {0x11c70, 0x11c8f}, {0x11c92, 0x11ca7}, {0x11ca9, 0x11cb6},
          727  +    {0x11d00, 0x11d06}, {0x11d0b, 0x11d36}, {0x11d3f, 0x11d47}, {0x11d50, 0x11d59},
   722    728       {0x12000, 0x12399}, {0x12400, 0x1246e}, {0x12470, 0x12474}, {0x12480, 0x12543},
   723    729       {0x13000, 0x1342e}, {0x14400, 0x14646}, {0x16800, 0x16a38}, {0x16a40, 0x16a5e},
   724    730       {0x16a60, 0x16a69}, {0x16ad0, 0x16aed}, {0x16af0, 0x16af5}, {0x16b00, 0x16b45},
   725    731       {0x16b50, 0x16b59}, {0x16b5b, 0x16b61}, {0x16b63, 0x16b77}, {0x16b7d, 0x16b8f},
   726    732       {0x16f00, 0x16f44}, {0x16f50, 0x16f7e}, {0x16f8f, 0x16f9f}, {0x17000, 0x187ec},
   727         -    {0x18800, 0x18af2}, {0x1bc00, 0x1bc6a}, {0x1bc70, 0x1bc7c}, {0x1bc80, 0x1bc88},
   728         -    {0x1bc90, 0x1bc99}, {0x1bc9c, 0x1bc9f}, {0x1d000, 0x1d0f5}, {0x1d100, 0x1d126},
   729         -    {0x1d129, 0x1d172}, {0x1d17b, 0x1d1e8}, {0x1d200, 0x1d245}, {0x1d300, 0x1d356},
   730         -    {0x1d360, 0x1d371}, {0x1d400, 0x1d454}, {0x1d456, 0x1d49c}, {0x1d4a9, 0x1d4ac},
   731         -    {0x1d4ae, 0x1d4b9}, {0x1d4bd, 0x1d4c3}, {0x1d4c5, 0x1d505}, {0x1d507, 0x1d50a},
   732         -    {0x1d50d, 0x1d514}, {0x1d516, 0x1d51c}, {0x1d51e, 0x1d539}, {0x1d53b, 0x1d53e},
   733         -    {0x1d540, 0x1d544}, {0x1d54a, 0x1d550}, {0x1d552, 0x1d6a5}, {0x1d6a8, 0x1d7cb},
   734         -    {0x1d7ce, 0x1da8b}, {0x1da9b, 0x1da9f}, {0x1daa1, 0x1daaf}, {0x1e000, 0x1e006},
   735         -    {0x1e008, 0x1e018}, {0x1e01b, 0x1e021}, {0x1e026, 0x1e02a}, {0x1e800, 0x1e8c4},
   736         -    {0x1e8c7, 0x1e8d6}, {0x1e900, 0x1e94a}, {0x1e950, 0x1e959}, {0x1ee00, 0x1ee03},
   737         -    {0x1ee05, 0x1ee1f}, {0x1ee29, 0x1ee32}, {0x1ee34, 0x1ee37}, {0x1ee4d, 0x1ee4f},
   738         -    {0x1ee67, 0x1ee6a}, {0x1ee6c, 0x1ee72}, {0x1ee74, 0x1ee77}, {0x1ee79, 0x1ee7c},
   739         -    {0x1ee80, 0x1ee89}, {0x1ee8b, 0x1ee9b}, {0x1eea1, 0x1eea3}, {0x1eea5, 0x1eea9},
   740         -    {0x1eeab, 0x1eebb}, {0x1f000, 0x1f02b}, {0x1f030, 0x1f093}, {0x1f0a0, 0x1f0ae},
   741         -    {0x1f0b1, 0x1f0bf}, {0x1f0c1, 0x1f0cf}, {0x1f0d1, 0x1f0f5}, {0x1f100, 0x1f10c},
   742         -    {0x1f110, 0x1f12e}, {0x1f130, 0x1f16b}, {0x1f170, 0x1f1ac}, {0x1f1e6, 0x1f202},
   743         -    {0x1f210, 0x1f23b}, {0x1f240, 0x1f248}, {0x1f300, 0x1f6d2}, {0x1f6e0, 0x1f6ec},
   744         -    {0x1f6f0, 0x1f6f6}, {0x1f700, 0x1f773}, {0x1f780, 0x1f7d4}, {0x1f800, 0x1f80b},
   745         -    {0x1f810, 0x1f847}, {0x1f850, 0x1f859}, {0x1f860, 0x1f887}, {0x1f890, 0x1f8ad},
   746         -    {0x1f910, 0x1f91e}, {0x1f920, 0x1f927}, {0x1f933, 0x1f93e}, {0x1f940, 0x1f94b},
   747         -    {0x1f950, 0x1f95e}, {0x1f980, 0x1f991}, {0x20000, 0x2a6d6}, {0x2a700, 0x2b734},
   748         -    {0x2b740, 0x2b81d}, {0x2b820, 0x2cea1}, {0x2f800, 0x2fa1d}, {0xe0100, 0xe01ef}
          733  +    {0x18800, 0x18af2}, {0x1b000, 0x1b11e}, {0x1b170, 0x1b2fb}, {0x1bc00, 0x1bc6a},
          734  +    {0x1bc70, 0x1bc7c}, {0x1bc80, 0x1bc88}, {0x1bc90, 0x1bc99}, {0x1bc9c, 0x1bc9f},
          735  +    {0x1d000, 0x1d0f5}, {0x1d100, 0x1d126}, {0x1d129, 0x1d172}, {0x1d17b, 0x1d1e8},
          736  +    {0x1d200, 0x1d245}, {0x1d300, 0x1d356}, {0x1d360, 0x1d371}, {0x1d400, 0x1d454},
          737  +    {0x1d456, 0x1d49c}, {0x1d4a9, 0x1d4ac}, {0x1d4ae, 0x1d4b9}, {0x1d4bd, 0x1d4c3},
          738  +    {0x1d4c5, 0x1d505}, {0x1d507, 0x1d50a}, {0x1d50d, 0x1d514}, {0x1d516, 0x1d51c},
          739  +    {0x1d51e, 0x1d539}, {0x1d53b, 0x1d53e}, {0x1d540, 0x1d544}, {0x1d54a, 0x1d550},
          740  +    {0x1d552, 0x1d6a5}, {0x1d6a8, 0x1d7cb}, {0x1d7ce, 0x1da8b}, {0x1da9b, 0x1da9f},
          741  +    {0x1daa1, 0x1daaf}, {0x1e000, 0x1e006}, {0x1e008, 0x1e018}, {0x1e01b, 0x1e021},
          742  +    {0x1e026, 0x1e02a}, {0x1e800, 0x1e8c4}, {0x1e8c7, 0x1e8d6}, {0x1e900, 0x1e94a},
          743  +    {0x1e950, 0x1e959}, {0x1ee00, 0x1ee03}, {0x1ee05, 0x1ee1f}, {0x1ee29, 0x1ee32},
          744  +    {0x1ee34, 0x1ee37}, {0x1ee4d, 0x1ee4f}, {0x1ee67, 0x1ee6a}, {0x1ee6c, 0x1ee72},
          745  +    {0x1ee74, 0x1ee77}, {0x1ee79, 0x1ee7c}, {0x1ee80, 0x1ee89}, {0x1ee8b, 0x1ee9b},
          746  +    {0x1eea1, 0x1eea3}, {0x1eea5, 0x1eea9}, {0x1eeab, 0x1eebb}, {0x1f000, 0x1f02b},
          747  +    {0x1f030, 0x1f093}, {0x1f0a0, 0x1f0ae}, {0x1f0b1, 0x1f0bf}, {0x1f0c1, 0x1f0cf},
          748  +    {0x1f0d1, 0x1f0f5}, {0x1f100, 0x1f10c}, {0x1f110, 0x1f12e}, {0x1f130, 0x1f16b},
          749  +    {0x1f170, 0x1f1ac}, {0x1f1e6, 0x1f202}, {0x1f210, 0x1f23b}, {0x1f240, 0x1f248},
          750  +    {0x1f260, 0x1f265}, {0x1f300, 0x1f6d4}, {0x1f6e0, 0x1f6ec}, {0x1f6f0, 0x1f6f8},
          751  +    {0x1f700, 0x1f773}, {0x1f780, 0x1f7d4}, {0x1f800, 0x1f80b}, {0x1f810, 0x1f847},
          752  +    {0x1f850, 0x1f859}, {0x1f860, 0x1f887}, {0x1f890, 0x1f8ad}, {0x1f900, 0x1f90b},
          753  +    {0x1f910, 0x1f93e}, {0x1f940, 0x1f94c}, {0x1f950, 0x1f96b}, {0x1f980, 0x1f997},
          754  +    {0x1f9d0, 0x1f9e6}, {0x20000, 0x2a6d6}, {0x2a700, 0x2b734}, {0x2b740, 0x2b81d},
          755  +    {0x2b820, 0x2cea1}, {0x2ceb0, 0x2ebe0}, {0x2f800, 0x2fa1d}, {0xe0100, 0xe01ef}
   749    756   #endif
   750    757   };
   751    758   
   752    759   #define NUM_GRAPH_RANGE (sizeof(graphRangeTable)/sizeof(crange))
   753    760   
   754    761   static const chr graphCharTable[] = {
   755    762       0x38c, 0x589, 0x58a, 0x85e, 0x98f, 0x990, 0x9b2, 0x9c7, 0x9c8,
   756    763       0x9d7, 0x9dc, 0x9dd, 0xa0f, 0xa10, 0xa32, 0xa33, 0xa35, 0xa36,
   757    764       0xa38, 0xa39, 0xa3c, 0xa47, 0xa48, 0xa51, 0xa5e, 0xab2, 0xab3,
   758         -    0xad0, 0xaf9, 0xb0f, 0xb10, 0xb32, 0xb33, 0xb47, 0xb48, 0xb56,
   759         -    0xb57, 0xb5c, 0xb5d, 0xb82, 0xb83, 0xb99, 0xb9a, 0xb9c, 0xb9e,
   760         -    0xb9f, 0xba3, 0xba4, 0xbd0, 0xbd7, 0xc55, 0xc56, 0xcd5, 0xcd6,
   761         -    0xcde, 0xcf1, 0xcf2, 0xd82, 0xd83, 0xdbd, 0xdca, 0xdd6, 0xe81,
   762         -    0xe82, 0xe84, 0xe87, 0xe88, 0xe8a, 0xe8d, 0xea5, 0xea7, 0xeaa,
   763         -    0xeab, 0xec6, 0x10c7, 0x10cd, 0x1258, 0x12c0, 0x1772, 0x1773, 0x1940,
   764         -    0x1cf8, 0x1cf9, 0x1f59, 0x1f5b, 0x1f5d, 0x2070, 0x2071, 0x2d27, 0x2d2d,
   765         -    0x2d6f, 0x2d70, 0xfb3e, 0xfb40, 0xfb41, 0xfb43, 0xfb44, 0xfffc, 0xfffd
          765  +    0xad0, 0xb0f, 0xb10, 0xb32, 0xb33, 0xb47, 0xb48, 0xb56, 0xb57,
          766  +    0xb5c, 0xb5d, 0xb82, 0xb83, 0xb99, 0xb9a, 0xb9c, 0xb9e, 0xb9f,
          767  +    0xba3, 0xba4, 0xbd0, 0xbd7, 0xc55, 0xc56, 0xcd5, 0xcd6, 0xcde,
          768  +    0xcf1, 0xcf2, 0xd82, 0xd83, 0xdbd, 0xdca, 0xdd6, 0xe81, 0xe82,
          769  +    0xe84, 0xe87, 0xe88, 0xe8a, 0xe8d, 0xea5, 0xea7, 0xeaa, 0xeab,
          770  +    0xec6, 0x10c7, 0x10cd, 0x1258, 0x12c0, 0x1772, 0x1773, 0x1940, 0x1f59,
          771  +    0x1f5b, 0x1f5d, 0x2070, 0x2071, 0x2d27, 0x2d2d, 0x2d6f, 0x2d70, 0xfb3e,
          772  +    0xfb40, 0xfb41, 0xfb43, 0xfb44, 0xfffc, 0xfffd
   766    773   #if TCL_UTF_MAX > 4
   767    774       ,0x1003c, 0x1003d, 0x101a0, 0x1056f, 0x10808, 0x10837, 0x10838, 0x1083c, 0x108f4,
   768    775       0x108f5, 0x1093f, 0x10a05, 0x10a06, 0x11288, 0x1130f, 0x11310, 0x11332, 0x11333,
   769         -    0x11347, 0x11348, 0x11350, 0x11357, 0x1145b, 0x1145d, 0x118ff, 0x16a6e, 0x16a6f,
   770         -    0x16fe0, 0x1b000, 0x1b001, 0x1d49e, 0x1d49f, 0x1d4a2, 0x1d4a5, 0x1d4a6, 0x1d4bb,
   771         -    0x1d546, 0x1e023, 0x1e024, 0x1e95e, 0x1e95f, 0x1ee21, 0x1ee22, 0x1ee24, 0x1ee27,
   772         -    0x1ee39, 0x1ee3b, 0x1ee42, 0x1ee47, 0x1ee49, 0x1ee4b, 0x1ee51, 0x1ee52, 0x1ee54,
   773         -    0x1ee57, 0x1ee59, 0x1ee5b, 0x1ee5d, 0x1ee5f, 0x1ee61, 0x1ee62, 0x1ee64, 0x1ee7e,
   774         -    0x1eef0, 0x1eef1, 0x1f250, 0x1f251, 0x1f930, 0x1f9c0
          776  +    0x11347, 0x11348, 0x11350, 0x11357, 0x1145b, 0x1145d, 0x118ff, 0x11d08, 0x11d09,
          777  +    0x11d3a, 0x11d3c, 0x11d3d, 0x16a6e, 0x16a6f, 0x16fe0, 0x16fe1, 0x1d49e, 0x1d49f,
          778  +    0x1d4a2, 0x1d4a5, 0x1d4a6, 0x1d4bb, 0x1d546, 0x1e023, 0x1e024, 0x1e95e, 0x1e95f,
          779  +    0x1ee21, 0x1ee22, 0x1ee24, 0x1ee27, 0x1ee39, 0x1ee3b, 0x1ee42, 0x1ee47, 0x1ee49,
          780  +    0x1ee4b, 0x1ee51, 0x1ee52, 0x1ee54, 0x1ee57, 0x1ee59, 0x1ee5b, 0x1ee5d, 0x1ee5f,
          781  +    0x1ee61, 0x1ee62, 0x1ee64, 0x1ee7e, 0x1eef0, 0x1eef1, 0x1f250, 0x1f251, 0x1f9c0
   775    782   #endif
   776    783   };
   777    784   
   778    785   #define NUM_GRAPH_CHAR (sizeof(graphCharTable)/sizeof(chr))
   779    786   
   780    787   /*
   781    788    *	End of auto-generated Unicode character ranges declarations.

Changes to generic/regguts.h.

    66     66   #endif
    67     67   
    68     68   /*
    69     69    * misc
    70     70    */
    71     71   
    72     72   #define	NOTREACHED	0
    73         -#define	xxx		1
    74     73   
    75     74   #define	DUPMAX	_POSIX2_RE_DUP_MAX
    76     75   #define	DUPINF	(DUPMAX+1)
    77     76   
    78     77   #define	REMAGIC	0xfed7		/* magic number for main struct */
    79     78   
    80     79   /*

Changes to generic/tcl.decls.

    28     28   # to preserve backwards compatibility.
    29     29   
    30     30   declare 0 {
    31     31       int Tcl_PkgProvideEx(Tcl_Interp *interp, const char *name,
    32     32   	    const char *version, const void *clientData)
    33     33   }
    34     34   declare 1 {
    35         -    CONST84_RETURN char *Tcl_PkgRequireEx(Tcl_Interp *interp,
           35  +    const char *Tcl_PkgRequireEx(Tcl_Interp *interp,
    36     36   	    const char *name, const char *version, int exact,
    37     37   	    void *clientDataPtr)
    38     38   }
    39     39   declare 2 {
    40     40       TCL_NORETURN void Tcl_Panic(const char *format, ...)
    41     41   }
    42     42   declare 3 {
................................................................................
   150    150   }
   151    151   declare 35 {
   152    152       int Tcl_GetDoubleFromObj(Tcl_Interp *interp, Tcl_Obj *objPtr,
   153    153   	    double *doublePtr)
   154    154   }
   155    155   declare 36 {
   156    156       int Tcl_GetIndexFromObj(Tcl_Interp *interp, Tcl_Obj *objPtr,
   157         -	    CONST84 char *const *tablePtr, const char *msg, int flags, int *indexPtr)
          157  +	    const char *const *tablePtr, const char *msg, int flags, int *indexPtr)
   158    158   }
   159    159   declare 37 {
   160    160       int Tcl_GetInt(Tcl_Interp *interp, const char *src, int *intPtr)
   161    161   }
   162    162   declare 38 {
   163    163       int Tcl_GetIntFromObj(Tcl_Interp *interp, Tcl_Obj *objPtr, int *intPtr)
   164    164   }
................................................................................
   281    281   }
   282    282   declare 75 {
   283    283       int Tcl_AsyncReady(void)
   284    284   }
   285    285   declare 76 {
   286    286       void Tcl_BackgroundError(Tcl_Interp *interp)
   287    287   }
   288         -declare 77 {
          288  +declare 77 {deprecated {Use Tcl_UtfBackslash}} {
   289    289       char Tcl_Backslash(const char *src, int *readPtr)
   290    290   }
   291    291   declare 78 {
   292    292       int Tcl_BadChannelOption(Tcl_Interp *interp, const char *optionName,
   293    293   	    const char *optionList)
   294    294   }
   295    295   declare 79 {
................................................................................
   302    302   declare 81 {
   303    303       int Tcl_Close(Tcl_Interp *interp, Tcl_Channel chan)
   304    304   }
   305    305   declare 82 {
   306    306       int Tcl_CommandComplete(const char *cmd)
   307    307   }
   308    308   declare 83 {
   309         -    char *Tcl_Concat(int argc, CONST84 char *const *argv)
          309  +    char *Tcl_Concat(int argc, const char *const *argv)
   310    310   }
   311    311   declare 84 {
   312    312       int Tcl_ConvertElement(const char *src, char *dst, int flags)
   313    313   }
   314    314   declare 85 {
   315    315       int Tcl_ConvertCountedElement(const char *src, int length, char *dst,
   316    316   	    int flags)
   317    317   }
   318    318   declare 86 {
   319    319       int Tcl_CreateAlias(Tcl_Interp *slave, const char *slaveCmd,
   320    320   	    Tcl_Interp *target, const char *targetCmd, int argc,
   321         -	    CONST84 char *const *argv)
          321  +	    const char *const *argv)
   322    322   }
   323    323   declare 87 {
   324    324       int Tcl_CreateAliasObj(Tcl_Interp *slave, const char *slaveCmd,
   325    325   	    Tcl_Interp *target, const char *targetCmd, int objc,
   326    326   	    Tcl_Obj *const objv[])
   327    327   }
   328    328   declare 88 {
................................................................................
   348    348   }
   349    349   declare 93 {
   350    350       void Tcl_CreateExitHandler(Tcl_ExitProc *proc, ClientData clientData)
   351    351   }
   352    352   declare 94 {
   353    353       Tcl_Interp *Tcl_CreateInterp(void)
   354    354   }
   355         -declare 95 {
          355  +declare 95 {deprecated {}} {
   356    356       void Tcl_CreateMathFunc(Tcl_Interp *interp, const char *name,
   357    357   	    int numArgs, Tcl_ValueType *argTypes,
   358    358   	    Tcl_MathProc *proc, ClientData clientData)
   359    359   }
   360    360   declare 96 {
   361    361       Tcl_Command Tcl_CreateObjCommand(Tcl_Interp *interp,
   362    362   	    const char *cmdName,
................................................................................
   457    457   declare 125 {
   458    458       void Tcl_DStringStartSublist(Tcl_DString *dsPtr)
   459    459   }
   460    460   declare 126 {
   461    461       int Tcl_Eof(Tcl_Channel chan)
   462    462   }
   463    463   declare 127 {
   464         -    CONST84_RETURN char *Tcl_ErrnoId(void)
          464  +    const char *Tcl_ErrnoId(void)
   465    465   }
   466    466   declare 128 {
   467         -    CONST84_RETURN char *Tcl_ErrnoMsg(int err)
          467  +    const char *Tcl_ErrnoMsg(int err)
   468    468   }
   469    469   declare 129 {
   470    470       int Tcl_Eval(Tcl_Interp *interp, const char *script)
   471    471   }
   472         -# This is obsolete, use Tcl_FSEvalFile
   473    472   declare 130 {
   474    473       int Tcl_EvalFile(Tcl_Interp *interp, const char *fileName)
   475    474   }
   476    475   declare 131 {
   477    476       int Tcl_EvalObj(Tcl_Interp *interp, Tcl_Obj *objPtr)
   478    477   }
   479    478   declare 132 {
................................................................................
   525    524       int Tcl_Flush(Tcl_Channel chan)
   526    525   }
   527    526   declare 147 {
   528    527       void Tcl_FreeResult(Tcl_Interp *interp)
   529    528   }
   530    529   declare 148 {
   531    530       int Tcl_GetAlias(Tcl_Interp *interp, const char *slaveCmd,
   532         -	    Tcl_Interp **targetInterpPtr, CONST84 char **targetCmdPtr,
   533         -	    int *argcPtr, CONST84 char ***argvPtr)
          531  +	    Tcl_Interp **targetInterpPtr, const char **targetCmdPtr,
          532  +	    int *argcPtr, const char ***argvPtr)
   534    533   }
   535    534   declare 149 {
   536    535       int Tcl_GetAliasObj(Tcl_Interp *interp, const char *slaveCmd,
   537         -	    Tcl_Interp **targetInterpPtr, CONST84 char **targetCmdPtr,
          536  +	    Tcl_Interp **targetInterpPtr, const char **targetCmdPtr,
   538    537   	    int *objcPtr, Tcl_Obj ***objv)
   539    538   }
   540    539   declare 150 {
   541    540       ClientData Tcl_GetAssocData(Tcl_Interp *interp, const char *name,
   542    541   	    Tcl_InterpDeleteProc **procPtr)
   543    542   }
   544    543   declare 151 {
................................................................................
   555    554   declare 154 {
   556    555       ClientData Tcl_GetChannelInstanceData(Tcl_Channel chan)
   557    556   }
   558    557   declare 155 {
   559    558       int Tcl_GetChannelMode(Tcl_Channel chan)
   560    559   }
   561    560   declare 156 {
   562         -    CONST84_RETURN char *Tcl_GetChannelName(Tcl_Channel chan)
          561  +    const char *Tcl_GetChannelName(Tcl_Channel chan)
   563    562   }
   564    563   declare 157 {
   565    564       int Tcl_GetChannelOption(Tcl_Interp *interp, Tcl_Channel chan,
   566    565   	    const char *optionName, Tcl_DString *dsPtr)
   567    566   }
   568    567   declare 158 {
   569    568       CONST86 Tcl_ChannelType *Tcl_GetChannelType(Tcl_Channel chan)
   570    569   }
   571    570   declare 159 {
   572    571       int Tcl_GetCommandInfo(Tcl_Interp *interp, const char *cmdName,
   573    572   	    Tcl_CmdInfo *infoPtr)
   574    573   }
   575    574   declare 160 {
   576         -    CONST84_RETURN char *Tcl_GetCommandName(Tcl_Interp *interp,
          575  +    const char *Tcl_GetCommandName(Tcl_Interp *interp,
   577    576   	    Tcl_Command command)
   578    577   }
   579    578   declare 161 {
   580    579       int Tcl_GetErrno(void)
   581    580   }
   582    581   declare 162 {
   583         -    CONST84_RETURN char *Tcl_GetHostName(void)
          582  +    const char *Tcl_GetHostName(void)
   584    583   }
   585    584   declare 163 {
   586    585       int Tcl_GetInterpPath(Tcl_Interp *askInterp, Tcl_Interp *slaveInterp)
   587    586   }
   588    587   declare 164 {
   589    588       Tcl_Interp *Tcl_GetMaster(Tcl_Interp *interp)
   590    589   }
................................................................................
   619    618   declare 172 {
   620    619       Tcl_Interp *Tcl_GetSlave(Tcl_Interp *interp, const char *slaveName)
   621    620   }
   622    621   declare 173 {
   623    622       Tcl_Channel Tcl_GetStdChannel(int type)
   624    623   }
   625    624   declare 174 {
   626         -    CONST84_RETURN char *Tcl_GetStringResult(Tcl_Interp *interp)
          625  +    const char *Tcl_GetStringResult(Tcl_Interp *interp)
   627    626   }
   628    627   declare 175 {
   629         -    CONST84_RETURN char *Tcl_GetVar(Tcl_Interp *interp, const char *varName,
          628  +    const char *Tcl_GetVar(Tcl_Interp *interp, const char *varName,
   630    629   	    int flags)
   631    630   }
   632    631   declare 176 {
   633         -    CONST84_RETURN char *Tcl_GetVar2(Tcl_Interp *interp, const char *part1,
          632  +    const char *Tcl_GetVar2(Tcl_Interp *interp, const char *part1,
   634    633   	    const char *part2, int flags)
   635    634   }
   636    635   declare 177 {
   637    636       int Tcl_GlobalEval(Tcl_Interp *interp, const char *command)
   638    637   }
   639    638   declare 178 {
   640    639       int Tcl_GlobalEvalObj(Tcl_Interp *interp, Tcl_Obj *objPtr)
................................................................................
   659    658       int Tcl_InterpDeleted(Tcl_Interp *interp)
   660    659   }
   661    660   declare 185 {
   662    661       int Tcl_IsSafe(Tcl_Interp *interp)
   663    662   }
   664    663   # Obsolete, use Tcl_FSJoinPath
   665    664   declare 186 {
   666         -    char *Tcl_JoinPath(int argc, CONST84 char *const *argv,
          665  +    char *Tcl_JoinPath(int argc, const char *const *argv,
   667    666   	    Tcl_DString *resultPtr)
   668    667   }
   669    668   declare 187 {
   670    669       int Tcl_LinkVar(Tcl_Interp *interp, const char *varName, char *addr,
   671    670   	    int type)
   672    671   }
   673    672   
................................................................................
   682    681   declare 190 {
   683    682       int Tcl_MakeSafe(Tcl_Interp *interp)
   684    683   }
   685    684   declare 191 {
   686    685       Tcl_Channel Tcl_MakeTcpClientChannel(ClientData tcpSocket)
   687    686   }
   688    687   declare 192 {
   689         -    char *Tcl_Merge(int argc, CONST84 char *const *argv)
          688  +    char *Tcl_Merge(int argc, const char *const *argv)
   690    689   }
   691    690   declare 193 {
   692    691       Tcl_HashEntry *Tcl_NextHashEntry(Tcl_HashSearch *searchPtr)
   693    692   }
   694    693   declare 194 {
   695    694       void Tcl_NotifyChannel(Tcl_Channel channel, int mask)
   696    695   }
................................................................................
   700    699   }
   701    700   declare 196 {
   702    701       Tcl_Obj *Tcl_ObjSetVar2(Tcl_Interp *interp, Tcl_Obj *part1Ptr,
   703    702   	    Tcl_Obj *part2Ptr, Tcl_Obj *newValuePtr, int flags)
   704    703   }
   705    704   declare 197 {
   706    705       Tcl_Channel Tcl_OpenCommandChannel(Tcl_Interp *interp, int argc,
   707         -	    CONST84 char **argv, int flags)
          706  +	    const char **argv, int flags)
   708    707   }
   709    708   # This is obsolete, use Tcl_FSOpenFileChannel
   710    709   declare 198 {
   711    710       Tcl_Channel Tcl_OpenFileChannel(Tcl_Interp *interp, const char *fileName,
   712    711   	    const char *modeString, int permissions)
   713    712   }
   714    713   declare 199 {
................................................................................
   726    725   declare 202 {
   727    726       void Tcl_PrintDouble(Tcl_Interp *interp, double value, char *dst)
   728    727   }
   729    728   declare 203 {
   730    729       int Tcl_PutEnv(const char *assignment)
   731    730   }
   732    731   declare 204 {
   733         -    CONST84_RETURN char *Tcl_PosixError(Tcl_Interp *interp)
          732  +    const char *Tcl_PosixError(Tcl_Interp *interp)
   734    733   }
   735    734   declare 205 {
   736    735       void Tcl_QueueEvent(Tcl_Event *evPtr, Tcl_QueuePosition position)
   737    736   }
   738    737   declare 206 {
   739    738       int Tcl_Read(Tcl_Channel chan, char *bufPtr, int toRead)
   740    739   }
................................................................................
   762    761   }
   763    762   declare 214 {
   764    763       int Tcl_RegExpMatch(Tcl_Interp *interp, const char *text,
   765    764   	    const char *pattern)
   766    765   }
   767    766   declare 215 {
   768    767       void Tcl_RegExpRange(Tcl_RegExp regexp, int index,
   769         -	    CONST84 char **startPtr, CONST84 char **endPtr)
          768  +	    const char **startPtr, const char **endPtr)
   770    769   }
   771    770   declare 216 {
   772    771       void Tcl_Release(ClientData clientData)
   773    772   }
   774    773   declare 217 {
   775    774       void Tcl_ResetResult(Tcl_Interp *interp)
   776    775   }
   777    776   declare 218 {
   778    777       int Tcl_ScanElement(const char *src, int *flagPtr)
   779    778   }
   780    779   declare 219 {
   781    780       int Tcl_ScanCountedElement(const char *src, int length, int *flagPtr)
   782    781   }
   783         -# Obsolete
   784         -declare 220 {
          782  +declare 220 {deprecated {}} {
   785    783       int Tcl_SeekOld(Tcl_Channel chan, int offset, int mode)
   786    784   }
   787    785   declare 221 {
   788    786       int Tcl_ServiceAll(void)
   789    787   }
   790    788   declare 222 {
   791    789       int Tcl_ServiceEvent(int flags)
................................................................................
   833    831   declare 235 {
   834    832       void Tcl_SetObjResult(Tcl_Interp *interp, Tcl_Obj *resultObjPtr)
   835    833   }
   836    834   declare 236 {
   837    835       void Tcl_SetStdChannel(Tcl_Channel channel, int type)
   838    836   }
   839    837   declare 237 {
   840         -    CONST84_RETURN char *Tcl_SetVar(Tcl_Interp *interp, const char *varName,
          838  +    const char *Tcl_SetVar(Tcl_Interp *interp, const char *varName,
   841    839   	    const char *newValue, int flags)
   842    840   }
   843    841   declare 238 {
   844         -    CONST84_RETURN char *Tcl_SetVar2(Tcl_Interp *interp, const char *part1,
          842  +    const char *Tcl_SetVar2(Tcl_Interp *interp, const char *part1,
   845    843   	    const char *part2, const char *newValue, int flags)
   846    844   }
   847    845   declare 239 {
   848         -    CONST84_RETURN char *Tcl_SignalId(int sig)
          846  +    const char *Tcl_SignalId(int sig)
   849    847   }
   850    848   declare 240 {
   851         -    CONST84_RETURN char *Tcl_SignalMsg(int sig)
          849  +    const char *Tcl_SignalMsg(int sig)
   852    850   }
   853    851   declare 241 {
   854    852       void Tcl_SourceRCFile(Tcl_Interp *interp)
   855    853   }
   856    854   declare 242 {
   857    855       int Tcl_SplitList(Tcl_Interp *interp, const char *listStr, int *argcPtr,
   858         -	    CONST84 char ***argvPtr)
          856  +	    const char ***argvPtr)
   859    857   }
   860    858   # Obsolete, use Tcl_FSSplitPath
   861    859   declare 243 {
   862         -    void Tcl_SplitPath(const char *path, int *argcPtr, CONST84 char ***argvPtr)
          860  +    void Tcl_SplitPath(const char *path, int *argcPtr, const char ***argvPtr)
   863    861   }
   864    862   declare 244 {
   865    863       void Tcl_StaticPackage(Tcl_Interp *interp, const char *pkgName,
   866    864   	    Tcl_PackageInitProc *initProc, Tcl_PackageInitProc *safeInitProc)
   867    865   }
   868    866   declare 245 {
   869    867       int Tcl_StringMatch(const char *str, const char *pattern)
   870    868   }
   871         -# Obsolete
   872         -declare 246 {
          869  +declare 246 {deprecated {}} {
   873    870       int Tcl_TellOld(Tcl_Channel chan)
   874    871   }
   875    872   declare 247 {
   876    873       int Tcl_TraceVar(Tcl_Interp *interp, const char *varName, int flags,
   877    874   	    Tcl_VarTraceProc *proc, ClientData clientData)
   878    875   }
   879    876   declare 248 {
................................................................................
   941    938   }
   942    939   declare 265 {
   943    940       int Tcl_DumpActiveMemory(const char *fileName)
   944    941   }
   945    942   declare 266 {
   946    943       void Tcl_ValidateAllMemory(const char *file, int line)
   947    944   }
   948         -declare 267 {
          945  +declare 267 {deprecated {see TIP #422}} {
   949    946       void Tcl_AppendResultVA(Tcl_Interp *interp, va_list argList)
   950    947   }
   951         -declare 268 {
          948  +declare 268 {deprecated {see TIP #422}} {
   952    949       void Tcl_AppendStringsToObjVA(Tcl_Obj *objPtr, va_list argList)
   953    950   }
   954    951   declare 269 {
   955    952       char *Tcl_HashStats(Tcl_HashTable *tablePtr)
   956    953   }
   957    954   declare 270 {
   958         -    CONST84_RETURN char *Tcl_ParseVar(Tcl_Interp *interp, const char *start,
   959         -	    CONST84 char **termPtr)
          955  +    const char *Tcl_ParseVar(Tcl_Interp *interp, const char *start,
          956  +	    const char **termPtr)
   960    957   }
   961    958   declare 271 {
   962         -    CONST84_RETURN char *Tcl_PkgPresent(Tcl_Interp *interp, const char *name,
          959  +    const char *Tcl_PkgPresent(Tcl_Interp *interp, const char *name,
   963    960   	    const char *version, int exact)
   964    961   }
   965    962   declare 272 {
   966         -    CONST84_RETURN char *Tcl_PkgPresentEx(Tcl_Interp *interp,
          963  +    const char *Tcl_PkgPresentEx(Tcl_Interp *interp,
   967    964   	    const char *name, const char *version, int exact,
   968    965   	    void *clientDataPtr)
   969    966   }
   970    967   declare 273 {
   971    968       int Tcl_PkgProvide(Tcl_Interp *interp, const char *name,
   972    969   	    const char *version)
   973    970   }
   974    971   # TIP #268: The internally used new Require function is in slot 573.
   975    972   declare 274 {
   976         -    CONST84_RETURN char *Tcl_PkgRequire(Tcl_Interp *interp, const char *name,
          973  +    const char *Tcl_PkgRequire(Tcl_Interp *interp, const char *name,
   977    974   	    const char *version, int exact)
   978    975   }
   979         -declare 275 {
          976  +declare 275 {deprecated {see TIP #422}} {
   980    977       void Tcl_SetErrorCodeVA(Tcl_Interp *interp, va_list argList)
   981    978   }
   982         -declare 276 {
          979  +declare 276 {deprecated {see TIP #422}} {
   983    980       int  Tcl_VarEvalVA(Tcl_Interp *interp, va_list argList)
   984    981   }
   985    982   declare 277 {
   986    983       Tcl_Pid Tcl_WaitPid(Tcl_Pid pid, int *statPtr, int options)
   987    984   }
   988         -declare 278 {
          985  +declare 278 {deprecated {see TIP #422}} {
   989    986       TCL_NORETURN void Tcl_PanicVA(const char *format, va_list argList)
   990    987   }
   991    988   declare 279 {
   992    989       void Tcl_GetVersion(int *major, int *minor, int *patchLevel, int *type)
   993    990   }
   994    991   declare 280 {
   995    992       void Tcl_InitMemory(Tcl_Interp *interp)
................................................................................
  1055   1052       int Tcl_EvalObjv(Tcl_Interp *interp, int objc, Tcl_Obj *const objv[],
  1056   1053   	    int flags)
  1057   1054   }
  1058   1055   declare 293 {
  1059   1056       int Tcl_EvalObjEx(Tcl_Interp *interp, Tcl_Obj *objPtr, int flags)
  1060   1057   }
  1061   1058   declare 294 {
  1062         -    void Tcl_ExitThread(int status)
         1059  +    TCL_NORETURN void Tcl_ExitThread(int status)
  1063   1060   }
  1064   1061   declare 295 {
  1065   1062       int Tcl_ExternalToUtf(Tcl_Interp *interp, Tcl_Encoding encoding,
  1066   1063   	    const char *src, int srcLen, int flags,
  1067   1064   	    Tcl_EncodingState *statePtr, char *dst, int dstLen,
  1068   1065   	    int *srcReadPtr, int *dstWrotePtr, int *dstCharsPtr)
  1069   1066   }
................................................................................
  1083   1080   declare 300 {
  1084   1081       Tcl_ThreadId Tcl_GetCurrentThread(void)
  1085   1082   }
  1086   1083   declare 301 {
  1087   1084       Tcl_Encoding Tcl_GetEncoding(Tcl_Interp *interp, const char *name)
  1088   1085   }
  1089   1086   declare 302 {
  1090         -    CONST84_RETURN char *Tcl_GetEncodingName(Tcl_Encoding encoding)
         1087  +    const char *Tcl_GetEncodingName(Tcl_Encoding encoding)
  1091   1088   }
  1092   1089   declare 303 {
  1093   1090       void Tcl_GetEncodingNames(Tcl_Interp *interp)
  1094   1091   }
  1095   1092   declare 304 {
  1096   1093       int Tcl_GetIndexFromObjStruct(Tcl_Interp *interp, Tcl_Obj *objPtr,
  1097   1094   	    const void *tablePtr, int offset, const char *msg, int flags,
................................................................................
  1159   1156   declare 323 {
  1160   1157       Tcl_UniChar Tcl_UniCharToUpper(int ch)
  1161   1158   }
  1162   1159   declare 324 {
  1163   1160       int Tcl_UniCharToUtf(int ch, char *buf)
  1164   1161   }
  1165   1162   declare 325 {
  1166         -    CONST84_RETURN char *Tcl_UtfAtIndex(const char *src, int index)
         1163  +    const char *Tcl_UtfAtIndex(const char *src, int index)
  1167   1164   }
  1168   1165   declare 326 {
  1169   1166       int Tcl_UtfCharComplete(const char *src, int length)
  1170   1167   }
  1171   1168   declare 327 {
  1172   1169       int Tcl_UtfBackslash(const char *src, int *readPtr, char *dst)
  1173   1170   }
  1174   1171   declare 328 {
  1175         -    CONST84_RETURN char *Tcl_UtfFindFirst(const char *src, int ch)
         1172  +    const char *Tcl_UtfFindFirst(const char *src, int ch)
  1176   1173   }
  1177   1174   declare 329 {
  1178         -    CONST84_RETURN char *Tcl_UtfFindLast(const char *src, int ch)
         1175  +    const char *Tcl_UtfFindLast(const char *src, int ch)
  1179   1176   }
  1180   1177   declare 330 {
  1181         -    CONST84_RETURN char *Tcl_UtfNext(const char *src)
         1178  +    const char *Tcl_UtfNext(const char *src)
  1182   1179   }
  1183   1180   declare 331 {
  1184         -    CONST84_RETURN char *Tcl_UtfPrev(const char *src, const char *start)
         1181  +    const char *Tcl_UtfPrev(const char *src, const char *start)
  1185   1182   }
  1186   1183   declare 332 {
  1187   1184       int Tcl_UtfToExternal(Tcl_Interp *interp, Tcl_Encoding encoding,
  1188   1185   	    const char *src, int srcLen, int flags,
  1189   1186   	    Tcl_EncodingState *statePtr, char *dst, int dstLen,
  1190   1187   	    int *srcReadPtr, int *dstWrotePtr, int *dstCharsPtr)
  1191   1188   }
................................................................................
  1210   1207   }
  1211   1208   declare 339 {
  1212   1209       int Tcl_WriteObj(Tcl_Channel chan, Tcl_Obj *objPtr)
  1213   1210   }
  1214   1211   declare 340 {
  1215   1212       char *Tcl_GetString(Tcl_Obj *objPtr)
  1216   1213   }
  1217         -declare 341 {
  1218         -    CONST84_RETURN char *Tcl_GetDefaultEncodingDir(void)
         1214  +declare 341 {deprecated {Use Tcl_GetEncodingSearchPath}} {
         1215  +    const char *Tcl_GetDefaultEncodingDir(void)
  1219   1216   }
  1220         -declare 342 {
         1217  +declare 342 {deprecated {Use Tcl_SetEncodingSearchPath}} {
  1221   1218       void Tcl_SetDefaultEncodingDir(const char *path)
  1222   1219   }
  1223   1220   declare 343 {
  1224   1221       void Tcl_AlertNotifier(ClientData clientData)
  1225   1222   }
  1226   1223   declare 344 {
  1227   1224       void Tcl_ServiceModeHook(int mode)
................................................................................
  1262   1259       Tcl_UniChar *Tcl_UtfToUniCharDString(const char *src,
  1263   1260   	    int length, Tcl_DString *dsPtr)
  1264   1261   }
  1265   1262   declare 356 {
  1266   1263       Tcl_RegExp Tcl_GetRegExpFromObj(Tcl_Interp *interp, Tcl_Obj *patObj,
  1267   1264   	    int flags)
  1268   1265   }
  1269         -declare 357 {
         1266  +declare 357 {deprecated {Use Tcl_EvalTokensStandard}} {
  1270   1267       Tcl_Obj *Tcl_EvalTokens(Tcl_Interp *interp, Tcl_Token *tokenPtr,
  1271   1268   	    int count)
  1272   1269   }
  1273   1270   declare 358 {
  1274   1271       void Tcl_FreeParse(Tcl_Parse *parsePtr)
  1275   1272   }
  1276   1273   declare 359 {
  1277   1274       void Tcl_LogCommandInfo(Tcl_Interp *interp, const char *script,
  1278   1275   	    const char *command, int length)
  1279   1276   }
  1280   1277   declare 360 {
  1281   1278       int Tcl_ParseBraces(Tcl_Interp *interp, const char *start, int numBytes,
  1282         -	    Tcl_Parse *parsePtr, int append, CONST84 char **termPtr)
         1279  +	    Tcl_Parse *parsePtr, int append, const char **termPtr)
  1283   1280   }
  1284   1281   declare 361 {
  1285   1282       int Tcl_ParseCommand(Tcl_Interp *interp, const char *start, int numBytes,
  1286   1283   	    int nested, Tcl_Parse *parsePtr)
  1287   1284   }
  1288   1285   declare 362 {
  1289   1286       int Tcl_ParseExpr(Tcl_Interp *interp, const char *start, int numBytes,
  1290   1287   	    Tcl_Parse *parsePtr)
  1291   1288   }
  1292   1289   declare 363 {
  1293   1290       int Tcl_ParseQuotedString(Tcl_Interp *interp, const char *start,
  1294   1291   	    int numBytes, Tcl_Parse *parsePtr, int append,
  1295         -	    CONST84 char **termPtr)
         1292  +	    const char **termPtr)
  1296   1293   }
  1297   1294   declare 364 {
  1298   1295       int Tcl_ParseVarName(Tcl_Interp *interp, const char *start, int numBytes,
  1299   1296   	    Tcl_Parse *parsePtr, int append)
  1300   1297   }
  1301   1298   # These 4 functions are obsolete, use Tcl_FSGetCwd, Tcl_FSChdir,
  1302   1299   # Tcl_FSAccess and Tcl_FSStat
................................................................................
  1404   1401   declare 396 {
  1405   1402       Tcl_Channel Tcl_GetTopChannel(Tcl_Channel chan)
  1406   1403   }
  1407   1404   declare 397 {
  1408   1405       int Tcl_ChannelBuffered(Tcl_Channel chan)
  1409   1406   }
  1410   1407   declare 398 {
  1411         -    CONST84_RETURN char *Tcl_ChannelName(const Tcl_ChannelType *chanTypePtr)
         1408  +    const char *Tcl_ChannelName(const Tcl_ChannelType *chanTypePtr)
  1412   1409   }
  1413   1410   declare 399 {
  1414   1411       Tcl_ChannelTypeVersion Tcl_ChannelVersion(
  1415   1412   	    const Tcl_ChannelType *chanTypePtr)
  1416   1413   }
  1417   1414   declare 400 {
  1418   1415       Tcl_DriverBlockModeProc *Tcl_ChannelBlockModeProc(
................................................................................
  1544   1541   
  1545   1542   # introduced in 8.4a3
  1546   1543   declare 434 {
  1547   1544       Tcl_UniChar *Tcl_GetUnicodeFromObj(Tcl_Obj *objPtr, int *lengthPtr)
  1548   1545   }
  1549   1546   
  1550   1547   # TIP#15 (math function introspection) dkf
  1551         -declare 435 {
         1548  +declare 435 {deprecated {}} {
  1552   1549       int Tcl_GetMathFuncInfo(Tcl_Interp *interp, const char *name,
  1553   1550   	    int *numArgsPtr, Tcl_ValueType **argTypesPtr,
  1554   1551   	    Tcl_MathProc **procPtr, ClientData *clientDataPtr)
  1555   1552   }
  1556         -declare 436 {
         1553  +declare 436 {deprecated {}} {
  1557   1554       Tcl_Obj *Tcl_ListMathFuncs(Tcl_Interp *interp, const char *pattern)
  1558   1555   }
  1559   1556   
  1560   1557   # TIP#36 (better access to 'subst') dkf
  1561   1558   declare 437 {
  1562   1559       Tcl_Obj *Tcl_SubstObj(Tcl_Interp *interp, Tcl_Obj *objPtr, int flags)
  1563   1560   }

Changes to generic/tcl.h.

    37     37    * When version numbers change here, must also go into the following files and
    38     38    * update the version numbers:
    39     39    *
    40     40    * library/init.tcl	(1 LOC patch)
    41     41    * unix/configure.ac	(2 LOC Major, 2 LOC minor, 1 LOC patch)
    42     42    * win/configure.ac	(as above)
    43     43    * win/tcl.m4		(not patchlevel)
    44         - * win/makefile.bc	(not patchlevel) 2 LOC
    45     44    * README		(sections 0 and 2, with and without separator)
    46     45    * macosx/Tcl.pbproj/project.pbxproj (not patchlevel) 1 LOC
    47     46    * macosx/Tcl.pbproj/default.pbxuser (not patchlevel) 1 LOC
    48     47    * macosx/Tcl.xcode/project.pbxproj (not patchlevel) 2 LOC
    49     48    * macosx/Tcl.xcode/default.pbxuser (not patchlevel) 1 LOC
    50     49    * macosx/Tcl-Common.xcconfig (not patchlevel) 1 LOC
    51     50    * win/README		(not patchlevel) (sections 0 and 2)
................................................................................
    52     51    * unix/tcl.spec	(1 LOC patch)
    53     52    * tools/tcl.hpj.in	(not patchlevel, for windows installer)
    54     53    */
    55     54   
    56     55   #define TCL_MAJOR_VERSION   8
    57     56   #define TCL_MINOR_VERSION   7
    58     57   #define TCL_RELEASE_LEVEL   TCL_ALPHA_RELEASE
    59         -#define TCL_RELEASE_SERIAL  0
           58  +#define TCL_RELEASE_SERIAL  2
    60     59   
    61     60   #define TCL_VERSION	    "8.7"
    62         -#define TCL_PATCH_LEVEL	    "8.7a0"
           61  +#define TCL_PATCH_LEVEL	    "8.7a2"
    63     62   
           63  +#if !defined(TCL_NO_DEPRECATED) || defined(RC_INVOKED)
    64     64   /*
    65     65    *----------------------------------------------------------------------------
    66     66    * The following definitions set up the proper options for Windows compilers.
    67     67    * We use this method because there is no autoconf equivalent.
    68     68    */
    69     69   
    70     70   #ifdef _WIN32
................................................................................
    85     85   #  define STRINGIFY(x) STRINGIFY1(x)
    86     86   #  define STRINGIFY1(x) #x
    87     87   #endif
    88     88   #ifndef JOIN
    89     89   #  define JOIN(a,b) JOIN1(a,b)
    90     90   #  define JOIN1(a,b) a##b
    91     91   #endif
           92  +#endif /* !TCL_NO_DEPRECATED */
    92     93   
    93     94   /*
    94     95    * A special definition used to allow this header file to be included from
    95     96    * windows resource files so that they can obtain version information.
    96     97    * RC_INVOKED is defined by default by the windows RC tool.
    97     98    *
    98     99    * Resource compilers don't like all the C stuff, like typedefs and function
................................................................................
   132    133    * written for older versions of Tcl where the macros permitted
   133    134    * support for the varargs.h system as well as stdarg.h .
   134    135    *
   135    136    * New code should just directly be written to use stdarg.h conventions.
   136    137    */
   137    138   
   138    139   #include <stdarg.h>
   139         -#ifndef TCL_NO_DEPRECATED
          140  +#if !defined(TCL_NO_DEPRECATED) && TCL_MAJOR_VERSION < 9
   140    141   #    define TCL_VARARGS(type, name) (type name, ...)
   141    142   #    define TCL_VARARGS_DEF(type, name) (type name, ...)
   142    143   #    define TCL_VARARGS_START(type, name, list) (va_start(list, name), name)
   143         -#endif
          144  +#endif /* !TCL_NO_DEPRECATED */
   144    145   #if defined(__GNUC__) && (__GNUC__ > 2)
   145    146   #   define TCL_FORMAT_PRINTF(a,b) __attribute__ ((__format__ (__printf__, a, b)))
   146    147   #   define TCL_NORETURN __attribute__ ((noreturn))
   147    148   #   define TCL_NOINLINE __attribute__ ((noinline))
   148    149   #   if defined(BUILD_tcl) || defined(BUILD_tk)
   149    150   #	define TCL_NORETURN1 __attribute__ ((noreturn))
   150    151   #   else
................................................................................
   249    250    * The following _ANSI_ARGS_ macro is to support old extensions
   250    251    * written for older versions of Tcl where it permitted support
   251    252    * for compilers written in the pre-prototype era of C.
   252    253    *
   253    254    * New code should use prototypes.
   254    255    */
   255    256   
   256         -#ifndef TCL_NO_DEPRECATED
          257  +#if !defined(TCL_NO_DEPRECATED) && TCL_MAJOR_VERSION < 9
   257    258   #   undef _ANSI_ARGS_
   258    259   #   define _ANSI_ARGS_(x)	x
   259         -#endif
   260    260   
   261    261   /*
   262    262    * Definitions that allow this header file to be used either with or without
   263    263    * ANSI C features.
   264    264    */
   265    265   
   266    266   #ifndef INLINE
   267    267   #   define INLINE
   268    268   #endif
   269         -
   270         -#ifdef NO_CONST
   271         -#   ifndef const
   272         -#      define const
   273         -#   endif
   274         -#endif
   275    269   #ifndef CONST
   276    270   #   define CONST const
   277    271   #endif
          272  +#define CONST84 const
          273  +#define CONST84_RETURN const
   278    274   
   279         -#ifdef USE_NON_CONST
   280         -#   ifdef USE_COMPAT_CONST
   281         -#      error define at most one of USE_NON_CONST and USE_COMPAT_CONST
   282         -#   endif
   283         -#   define CONST84
   284         -#   define CONST84_RETURN
   285         -#else
   286         -#   ifdef USE_COMPAT_CONST
   287         -#      define CONST84
   288         -#      define CONST84_RETURN const
   289         -#   else
   290         -#      define CONST84 const
   291         -#      define CONST84_RETURN const
   292         -#   endif
   293         -#endif
          275  +#endif /* !TCL_NO_DEPRECATED */
   294    276   
   295    277   #ifndef CONST86
   296         -#      define CONST86 CONST84
          278  +#      define CONST86 const
   297    279   #endif
   298    280   
   299    281   /*
   300    282    * Make sure EXTERN isn't defined elsewhere.
   301    283    */
   302    284   
   303    285   #ifdef EXTERN
................................................................................
   313    295   /*
   314    296    *----------------------------------------------------------------------------
   315    297    * The following code is copied from winnt.h. If we don't replicate it here,
   316    298    * then <windows.h> can't be included after tcl.h, since tcl.h also defines
   317    299    * VOID. This block is skipped under Cygwin and Mingw.
   318    300    */
   319    301   
          302  +#if !defined(TCL_NO_DEPRECATED) && TCL_MAJOR_VERSION < 9
   320    303   #if defined(_WIN32) && !defined(HAVE_WINNT_IGNORE_VOID)
   321    304   #ifndef VOID
   322    305   #define VOID void
   323    306   typedef char CHAR;
   324    307   typedef short SHORT;
   325    308   typedef long LONG;
   326    309   #endif
................................................................................
   328    311   
   329    312   /*
   330    313    * Macro to use instead of "void" for arguments that must have type "void *"
   331    314    * in ANSI C; maps them to type "char *" in non-ANSI systems.
   332    315    */
   333    316   
   334    317   #ifndef __VXWORKS__
   335         -#   ifndef NO_VOID
   336         -#	define VOID void
   337         -#   else
   338         -#	define VOID char
   339         -#   endif
          318  +#   define VOID void
   340    319   #endif
          320  +#endif /* !defined(TCL_NO_DEPRECATED) && TCL_MAJOR_VERSION < 9 */
   341    321   
   342    322   /*
   343    323    * Miscellaneous declarations.
   344    324    */
   345    325   
   346    326   #ifndef _CLIENTDATA
   347         -#   ifndef NO_VOID
   348         -	typedef void *ClientData;
   349         -#   else
   350         -	typedef int *ClientData;
   351         -#   endif
          327  +    typedef void *ClientData;
   352    328   #   define _CLIENTDATA
   353    329   #endif
   354    330   
   355    331   /*
   356    332    * Darwin specific configure overrides (to support fat compiles, where
   357    333    * configure runs only once for multiple architectures):
   358    334    */
................................................................................
   372    348   
   373    349   /*
   374    350    * Define Tcl_WideInt to be a type that is (at least) 64-bits wide, and define
   375    351    * Tcl_WideUInt to be the unsigned variant of that type (assuming that where
   376    352    * we have one, we can have the other.)
   377    353    *
   378    354    * Also defines the following macros:
   379         - * TCL_WIDE_INT_IS_LONG - if wide ints are really longs (i.e. we're on a real
   380         - *	64-bit system.)
          355  + * TCL_WIDE_INT_IS_LONG - if wide ints are really longs (i.e. we're on a
          356  + *	LP64 system such as modern Solaris or Linux ... not including Win64)
   381    357    * Tcl_WideAsLong - forgetful converter from wideInt to long.
   382    358    * Tcl_LongAsWide - sign-extending converter from long to wideInt.
   383    359    * Tcl_WideAsDouble - converter from wideInt to double.
   384    360    * Tcl_DoubleAsWide - converter from double to wideInt.
   385    361    *
   386    362    * The following invariant should hold for any long value 'longVal':
   387    363    *	longVal == Tcl_WideAsLong(Tcl_LongAsWide(longVal))
................................................................................
   390    366    * tclObj.c) depends on the function
   391    367    * sprintf(...,"%" TCL_LL_MODIFIER "d",...).
   392    368    */
   393    369   
   394    370   #if !defined(TCL_WIDE_INT_TYPE)&&!defined(TCL_WIDE_INT_IS_LONG)
   395    371   #   if defined(_WIN32)
   396    372   #      define TCL_WIDE_INT_TYPE __int64
   397         -#      ifdef __BORLANDC__
   398         -#         define TCL_LL_MODIFIER	"L"
   399         -#      else /* __BORLANDC__ */
   400         -#         define TCL_LL_MODIFIER	"I64"
   401         -#      endif /* __BORLANDC__ */
          373  +#      define TCL_LL_MODIFIER	"I64"
          374  +#      if defined(_WIN64)
          375  +#         define TCL_Z_MODIFIER	"I"
          376  +#      endif
   402    377   #   elif defined(__GNUC__)
   403         -#      define TCL_WIDE_INT_TYPE long long
   404         -#      define TCL_LL_MODIFIER	"ll"
          378  +#      define TCL_Z_MODIFIER	"z"
   405    379   #   else /* ! _WIN32 && ! __GNUC__ */
   406    380   /*
   407    381    * Don't know what platform it is and configure hasn't discovered what is
   408    382    * going on for us. Try to guess...
   409    383    */
   410    384   #      include <limits.h>
   411         -#      if (INT_MAX < LONG_MAX)
          385  +#      if defined(LLONG_MAX) && (LLONG_MAX == LONG_MAX)
   412    386   #         define TCL_WIDE_INT_IS_LONG	1
   413         -#      else
   414         -#         define TCL_WIDE_INT_TYPE long long
   415    387   #      endif
   416    388   #   endif /* _WIN32 */
   417    389   #endif /* !TCL_WIDE_INT_TYPE & !TCL_WIDE_INT_IS_LONG */
   418         -#ifdef TCL_WIDE_INT_IS_LONG
   419         -#   undef TCL_WIDE_INT_TYPE
   420         -#   define TCL_WIDE_INT_TYPE	long
   421         -#endif /* TCL_WIDE_INT_IS_LONG */
          390  +
          391  +#ifndef TCL_WIDE_INT_TYPE
          392  +#   define TCL_WIDE_INT_TYPE		long long
          393  +#endif /* !TCL_WIDE_INT_TYPE */
   422    394   
   423    395   typedef TCL_WIDE_INT_TYPE		Tcl_WideInt;
   424    396   typedef unsigned TCL_WIDE_INT_TYPE	Tcl_WideUInt;
   425    397   
   426         -#ifdef TCL_WIDE_INT_IS_LONG
   427         -#   define Tcl_WideAsLong(val)		((long)(val))
   428         -#   define Tcl_LongAsWide(val)		((long)(val))
   429         -#   define Tcl_WideAsDouble(val)	((double)((long)(val)))
   430         -#   define Tcl_DoubleAsWide(val)	((long)((double)(val)))
   431         -#   ifndef TCL_LL_MODIFIER
   432         -#      define TCL_LL_MODIFIER		"l"
   433         -#   endif /* !TCL_LL_MODIFIER */
   434         -#else /* TCL_WIDE_INT_IS_LONG */
   435         -/*
   436         - * The next short section of defines are only done when not running on Windows
   437         - * or some other strange platform.
   438         - */
   439         -#   ifndef TCL_LL_MODIFIER
   440         -#      define TCL_LL_MODIFIER		"ll"
   441         -#   endif /* !TCL_LL_MODIFIER */
   442         -#   define Tcl_WideAsLong(val)		((long)((Tcl_WideInt)(val)))
   443         -#   define Tcl_LongAsWide(val)		((Tcl_WideInt)((long)(val)))
   444         -#   define Tcl_WideAsDouble(val)	((double)((Tcl_WideInt)(val)))
   445         -#   define Tcl_DoubleAsWide(val)	((Tcl_WideInt)((double)(val)))
   446         -#endif /* TCL_WIDE_INT_IS_LONG */
          398  +#ifndef TCL_LL_MODIFIER
          399  +#   define TCL_LL_MODIFIER	"ll"
          400  +#endif /* !TCL_LL_MODIFIER */
          401  +#ifndef TCL_Z_MODIFIER
          402  +#   if defined(__GNUC__) && !defined(_WIN32)
          403  +#	define TCL_Z_MODIFIER	"z"
          404  +#   else
          405  +#	define TCL_Z_MODIFIER	""
          406  +#   endif
          407  +#endif /* !TCL_Z_MODIFIER */
          408  +#define Tcl_WideAsLong(val)	((long)((Tcl_WideInt)(val)))
          409  +#define Tcl_LongAsWide(val)	((Tcl_WideInt)((long)(val)))
          410  +#define Tcl_WideAsDouble(val)	((double)((Tcl_WideInt)(val)))
          411  +#define Tcl_DoubleAsWide(val)	((Tcl_WideInt)((double)(val)))
   447    412   
   448    413   #if defined(_WIN32)
   449    414   #   ifdef __BORLANDC__
   450    415   	typedef struct stati64 Tcl_StatBuf;
   451    416   #   elif defined(_WIN64)
   452    417   	typedef struct __stat64 Tcl_StatBuf;
   453    418   #   elif (defined(_MSC_VER) && (_MSC_VER < 1400)) || defined(_USE_32BIT_TIME_T)
................................................................................
   495    460    *
   496    461    * Note: Tcl_ObjCmdProc functions do not directly set result and freeProc.
   497    462    * Instead, they set a Tcl_Obj member in the "real" structure that can be
   498    463    * accessed with Tcl_GetObjResult() and Tcl_SetObjResult().
   499    464    */
   500    465   
   501    466   typedef struct Tcl_Interp
   502         -#ifndef TCL_NO_DEPRECATED
          467  +#if !defined(TCL_NO_DEPRECATED) && TCL_MAJOR_VERSION < 9
   503    468   {
   504    469       /* TIP #330: Strongly discourage extensions from using the string
   505    470        * result. */
   506         -#ifdef USE_INTERP_RESULT
   507         -    char *result TCL_DEPRECATED_API("use Tcl_GetStringResult/Tcl_SetResult");
   508         -				/* If the last command returned a string
   509         -				 * result, this points to it. */
   510         -    void (*freeProc) (char *blockPtr)
   511         -	    TCL_DEPRECATED_API("use Tcl_GetStringResult/Tcl_SetResult");
   512         -				/* Zero means the string result is statically
   513         -				 * allocated. TCL_DYNAMIC means it was
   514         -				 * allocated with ckalloc and should be freed
   515         -				 * with ckfree. Other values give the address
   516         -				 * of function to invoke to free the result.
   517         -				 * Tcl_Eval must free it before executing next
   518         -				 * command. */
   519         -#else
   520    471       char *resultDontUse; /* Don't use in extensions! */
   521    472       void (*freeProcDontUse) (char *); /* Don't use in extensions! */
   522         -#endif
   523         -#ifdef USE_INTERP_ERRORLINE
   524         -    int errorLine TCL_DEPRECATED_API("use Tcl_GetErrorLine/Tcl_SetErrorLine");
   525         -				/* When TCL_ERROR is returned, this gives the
   526         -				 * line number within the command where the
   527         -				 * error occurred (1 if first line). */
   528         -#else
   529    473       int errorLineDontUse; /* Don't use in extensions! */
   530         -#endif
   531    474   }
   532         -#endif /* TCL_NO_DEPRECATED */
          475  +#endif /* !TCL_NO_DEPRECATED */
   533    476   Tcl_Interp;
   534    477   
   535    478   typedef struct Tcl_AsyncHandler_ *Tcl_AsyncHandler;
   536    479   typedef struct Tcl_Channel_ *Tcl_Channel;
   537    480   typedef struct Tcl_ChannelTypeVersion_ *Tcl_ChannelTypeVersion;
   538    481   typedef struct Tcl_Command_ *Tcl_Command;
   539    482   typedef struct Tcl_Condition_ *Tcl_Condition;
................................................................................
   675    618   
   676    619   #define TCL_OK			0
   677    620   #define TCL_ERROR		1
   678    621   #define TCL_RETURN		2
   679    622   #define TCL_BREAK		3
   680    623   #define TCL_CONTINUE		4
   681    624   
          625  +#if !defined(TCL_NO_DEPRECATED) && TCL_MAJOR_VERSION < 9
   682    626   #define TCL_RESULT_SIZE		200
          627  +#endif
   683    628   
   684    629   /*
   685    630    *----------------------------------------------------------------------------
   686    631    * Flags to control what substitutions are performed by Tcl_SubstObj():
   687    632    */
   688    633   
   689    634   #define TCL_SUBST_COMMANDS	001
................................................................................
   691    636   #define TCL_SUBST_BACKSLASHES	004
   692    637   #define TCL_SUBST_ALL		007
   693    638   
   694    639   /*
   695    640    * Argument descriptors for math function callbacks in expressions:
   696    641    */
   697    642   
          643  +#if !defined(TCL_NO_DEPRECATED) && TCL_MAJOR_VERSION < 9
   698    644   typedef enum {
   699    645       TCL_INT, TCL_DOUBLE, TCL_EITHER, TCL_WIDE_INT
   700    646   } Tcl_ValueType;
   701    647   
   702    648   typedef struct Tcl_Value {
   703    649       Tcl_ValueType type;		/* Indicates intValue or doubleValue is valid,
   704    650   				 * or both. */
   705    651       long intValue;		/* Integer value. */
   706    652       double doubleValue;		/* Double-precision floating value. */
   707    653       Tcl_WideInt wideValue;	/* Wide (min. 64-bit) integer value. */
   708    654   } Tcl_Value;
          655  +#else
          656  +#define Tcl_ValueType void /* Just enough to prevent compilation error in Tcl */
          657  +#define Tcl_Value void /* Just enough to prevent compilation error in Tcl */
          658  +#endif
   709    659   
   710    660   /*
   711    661    * Forward declaration of Tcl_Obj to prevent an error when the forward
   712    662    * reference to Tcl_Obj is encountered in the function types declared below.
   713    663    */
   714    664   
   715    665   struct Tcl_Obj;
................................................................................
   722    672   typedef int (Tcl_AppInitProc) (Tcl_Interp *interp);
   723    673   typedef int (Tcl_AsyncProc) (ClientData clientData, Tcl_Interp *interp,
   724    674   	int code);
   725    675   typedef void (Tcl_ChannelProc) (ClientData clientData, int mask);
   726    676   typedef void (Tcl_CloseProc) (ClientData data);
   727    677   typedef void (Tcl_CmdDeleteProc) (ClientData clientData);
   728    678   typedef int (Tcl_CmdProc) (ClientData clientData, Tcl_Interp *interp,
   729         -	int argc, CONST84 char *argv[]);
          679  +	int argc, const char *argv[]);
   730    680   typedef void (Tcl_CmdTraceProc) (ClientData clientData, Tcl_Interp *interp,
   731    681   	int level, char *command, Tcl_CmdProc *proc,
   732         -	ClientData cmdClientData, int argc, CONST84 char *argv[]);
          682  +	ClientData cmdClientData, int argc, const char *argv[]);
   733    683   typedef int (Tcl_CmdObjTraceProc) (ClientData clientData, Tcl_Interp *interp,
   734    684   	int level, const char *command, Tcl_Command commandInfo, int objc,
   735    685   	struct Tcl_Obj *const *objv);
   736    686   typedef void (Tcl_CmdObjTraceDeleteProc) (ClientData clientData);
   737    687   typedef void (Tcl_DupInternalRepProc) (struct Tcl_Obj *srcPtr,
   738    688   	struct Tcl_Obj *dupPtr);
   739    689   typedef int (Tcl_EncodingConvertProc) (ClientData clientData, const char *src,
................................................................................
   762    712   typedef void (Tcl_PanicProc) (const char *format, ...);
   763    713   typedef void (Tcl_TcpAcceptProc) (ClientData callbackData, Tcl_Channel chan,
   764    714   	char *address, int port);
   765    715   typedef void (Tcl_TimerProc) (ClientData clientData);
   766    716   typedef int (Tcl_SetFromAnyProc) (Tcl_Interp *interp, struct Tcl_Obj *objPtr);
   767    717   typedef void (Tcl_UpdateStringProc) (struct Tcl_Obj *objPtr);
   768    718   typedef char * (Tcl_VarTraceProc) (ClientData clientData, Tcl_Interp *interp,
   769         -	CONST84 char *part1, CONST84 char *part2, int flags);
          719  +	const char *part1, const char *part2, int flags);
   770    720   typedef void (Tcl_CommandTraceProc) (ClientData clientData, Tcl_Interp *interp,
   771    721   	const char *oldName, const char *newName, int flags);
   772    722   typedef void (Tcl_CreateFileHandlerProc) (int fd, int mask, Tcl_FileProc *proc,
   773    723   	ClientData clientData);
   774    724   typedef void (Tcl_DeleteFileHandlerProc) (int fd);
   775    725   typedef void (Tcl_AlertNotifierProc) (ClientData clientData);
   776    726   typedef void (Tcl_ServiceModeHookProc) (int mode);
................................................................................
   873    823   typedef struct Tcl_SavedResult {
   874    824       char *result;
   875    825       Tcl_FreeProc *freeProc;
   876    826       Tcl_Obj *objResultPtr;
   877    827       char *appendResult;
   878    828       int appendAvl;
   879    829       int appendUsed;
   880         -    char resultSpace[TCL_RESULT_SIZE+1];
          830  +    char resultSpace[200+1];
   881    831   } Tcl_SavedResult;
   882    832   
   883    833   /*
   884    834    *----------------------------------------------------------------------------
   885    835    * The following definitions support Tcl's namespace facility. Note: the first
   886    836    * five fields must match exactly the fields in a Namespace structure (see
   887    837    * tclInt.h).
................................................................................
   999    949       char staticSpace[TCL_DSTRING_STATIC_SIZE];
  1000    950   				/* Space to use in common case where string is
  1001    951   				 * small. */
  1002    952   } Tcl_DString;
  1003    953   
  1004    954   #define Tcl_DStringLength(dsPtr) ((dsPtr)->length)
  1005    955   #define Tcl_DStringValue(dsPtr) ((dsPtr)->string)
  1006         -#define Tcl_DStringTrunc Tcl_DStringSetLength
          956  +#if !defined(TCL_NO_DEPRECATED) && TCL_MAJOR_VERSION < 9
          957  +#   define Tcl_DStringTrunc Tcl_DStringSetLength
          958  +#endif /* !TCL_NO_DEPRECATED */
  1007    959   
  1008    960   /*
  1009    961    * Definitions for the maximum number of digits of precision that may be
  1010    962    * specified in the "tcl_precision" variable, and the number of bytes of
  1011    963    * buffer space required by Tcl_PrintDouble.
  1012    964    */
  1013    965   
................................................................................
  1125   1077   /*
  1126   1078    * The TCL_PARSE_PART1 flag is deprecated and has no effect. The part1 is now
  1127   1079    * always parsed whenever the part2 is NULL. (This is to avoid a common error
  1128   1080    * when converting code to use the new object based APIs and forgetting to
  1129   1081    * give the flag)
  1130   1082    */
  1131   1083   
  1132         -#ifndef TCL_NO_DEPRECATED
         1084  +#if !defined(TCL_NO_DEPRECATED) && TCL_MAJOR_VERSION < 9
  1133   1085   #   define TCL_PARSE_PART1	0x400
  1134         -#endif
         1086  +#endif /* !TCL_NO_DEPRECATED */
  1135   1087   
  1136   1088   /*
  1137   1089    * Types for linked variables:
  1138   1090    */
  1139   1091   
  1140   1092   #define TCL_LINK_INT		1
  1141   1093   #define TCL_LINK_DOUBLE		2
................................................................................
  1344   1296    * dictionaries. These fields should not be accessed by code outside
  1345   1297    * tclDictObj.c
  1346   1298    */
  1347   1299   
  1348   1300   typedef struct {
  1349   1301       void *next;			/* Search position for underlying hash
  1350   1302   				 * table. */
  1351         -    int epoch;			/* Epoch marker for dictionary being searched,
  1352         -				 * or -1 if search has terminated. */
         1303  +    unsigned int epoch; 	/* Epoch marker for dictionary being searched,
         1304  +				 * or 0 if search has terminated. */
  1353   1305       Tcl_Dict dictionaryPtr;	/* Reference to dictionary being searched. */
  1354   1306   } Tcl_DictSearch;
  1355   1307   
  1356   1308   /*
  1357   1309    *----------------------------------------------------------------------------
  1358   1310    * Flag values to pass to Tcl_DoOneEvent to disable searches for some kinds of
  1359   1311    * events:
................................................................................
  1478   1430   typedef int	(Tcl_DriverCloseProc) (ClientData instanceData,
  1479   1431   			Tcl_Interp *interp);
  1480   1432   typedef int	(Tcl_DriverClose2Proc) (ClientData instanceData,
  1481   1433   			Tcl_Interp *interp, int flags);
  1482   1434   typedef int	(Tcl_DriverInputProc) (ClientData instanceData, char *buf,
  1483   1435   			int toRead, int *errorCodePtr);
  1484   1436   typedef int	(Tcl_DriverOutputProc) (ClientData instanceData,
  1485         -			CONST84 char *buf, int toWrite, int *errorCodePtr);
         1437  +			const char *buf, int toWrite, int *errorCodePtr);
  1486   1438   typedef int	(Tcl_DriverSeekProc) (ClientData instanceData, long offset,
  1487   1439   			int mode, int *errorCodePtr);
  1488   1440   typedef int	(Tcl_DriverSetOptionProc) (ClientData instanceData,
  1489   1441   			Tcl_Interp *interp, const char *optionName,
  1490   1442   			const char *value);
  1491   1443   typedef int	(Tcl_DriverGetOptionProc) (ClientData instanceData,
  1492         -			Tcl_Interp *interp, CONST84 char *optionName,
         1444  +			Tcl_Interp *interp, const char *optionName,
  1493   1445   			Tcl_DString *dsPtr);
  1494   1446   typedef void	(Tcl_DriverWatchProc) (ClientData instanceData, int mask);
  1495   1447   typedef int	(Tcl_DriverGetHandleProc) (ClientData instanceData,
  1496   1448   			int direction, ClientData *handlePtr);
  1497   1449   typedef int	(Tcl_DriverFlushProc) (ClientData instanceData);
  1498   1450   typedef int	(Tcl_DriverHandlerProc) (ClientData instanceData,
  1499   1451   			int interestMask);
................................................................................
  1978   1930    *				is described by a TCL_TOKEN_SUB_EXPR token
  1979   1931    *				followed by the TCL_TOKEN_OPERATOR token for
  1980   1932    *				the operator, then TCL_TOKEN_SUB_EXPR tokens
  1981   1933    *				for the left then the right operands.
  1982   1934    * TCL_TOKEN_OPERATOR -		The token describes one expression operator.
  1983   1935    *				An operator might be the name of a math
  1984   1936    *				function such as "abs". A TCL_TOKEN_OPERATOR
  1985         - *				token is always preceeded by one
         1937  + *				token is always preceded by one
  1986   1938    *				TCL_TOKEN_SUB_EXPR token for the operator's
  1987   1939    *				subexpression, and is followed by zero or more
  1988   1940    *				TCL_TOKEN_SUB_EXPR tokens for the operator's
  1989   1941    *				operands. NumComponents is always 0.
  1990   1942    * TCL_TOKEN_EXPAND_WORD -	This token is just like TCL_TOKEN_WORD except
  1991   1943    *				that it marks a word that began with the
  1992   1944    *				literal character prefix "{*}". This word is
................................................................................
  2263   2215    * Override definitions for libtommath.
  2264   2216    */
  2265   2217   
  2266   2218   typedef struct mp_int mp_int;
  2267   2219   #define MP_INT_DECLARED
  2268   2220   typedef unsigned int mp_digit;
  2269   2221   #define MP_DIGIT_DECLARED
         2222  +typedef unsigned TCL_WIDE_INT_TYPE mp_word;
         2223  +#define MP_WORD_DECLARED
  2270   2224   
  2271   2225   /*
  2272   2226    *----------------------------------------------------------------------------
  2273   2227    * Definitions needed for Tcl_ParseArgvObj routines.
  2274   2228    * Based on tkArgv.c.
  2275   2229    * Modifications from the original are copyright (c) Sam Bromley 2006
  2276   2230    */
................................................................................
  2407   2361   
  2408   2362   const char *		Tcl_InitStubs(Tcl_Interp *interp, const char *version,
  2409   2363   			    int exact, int magic);
  2410   2364   const char *		TclTomMathInitializeStubs(Tcl_Interp *interp,
  2411   2365   			    const char *version, int epoch, int revision);
  2412   2366   
  2413   2367   #ifdef USE_TCL_STUBS
  2414         -#define Tcl_InitStubs(interp, version, exact) \
  2415         -    (Tcl_InitStubs)(interp, version, \
         2368  +#if TCL_RELEASE_LEVEL == TCL_FINAL_RELEASE
         2369  +#   define Tcl_InitStubs(interp, version, exact) \
         2370  +	(Tcl_InitStubs)(interp, version, \
  2416   2371   	    (exact)|(TCL_MAJOR_VERSION<<8)|(TCL_MINOR_VERSION<<16), \
  2417   2372   	    TCL_STUB_MAGIC)
  2418   2373   #else
  2419         -#define Tcl_InitStubs(interp, version, exact) \
  2420         -    Tcl_PkgInitStubsCheck(interp, version, \
  2421         -	    (exact)|(TCL_MAJOR_VERSION<<8)|(TCL_MINOR_VERSION<<16))
         2374  +#   define Tcl_InitStubs(interp, version, exact) \
         2375  +	(Tcl_InitStubs)(interp, TCL_PATCH_LEVEL, \
         2376  +	    1|(TCL_MAJOR_VERSION<<8)|(TCL_MINOR_VERSION<<16), \
         2377  +	    TCL_STUB_MAGIC)
         2378  +#endif
         2379  +#else
         2380  +#if TCL_RELEASE_LEVEL == TCL_FINAL_RELEASE
         2381  +#   define Tcl_InitStubs(interp, version, exact) \
         2382  +	Tcl_PkgInitStubsCheck(interp, version, \
         2383  +		(exact)|(TCL_MAJOR_VERSION<<8)|(TCL_MINOR_VERSION<<16))
         2384  +#else
         2385  +#   define Tcl_InitStubs(interp, version, exact) \
         2386  +	Tcl_PkgInitStubsCheck(interp, TCL_PATCH_LEVEL, \
         2387  +		1|(TCL_MAJOR_VERSION<<8)|(TCL_MINOR_VERSION<<16))
         2388  +#endif
  2422   2389   #endif
  2423   2390   
  2424   2391   /*
  2425   2392    * Public functions that are not accessible via the stubs table.
  2426   2393    * Tcl_GetMemoryInfo is needed for AOLserver. [Bug 1868171]
  2427   2394    */
  2428   2395   
................................................................................
  2535   2502   
  2536   2503   #ifdef TCL_MEM_DEBUG
  2537   2504   #  undef  Tcl_NewBignumObj
  2538   2505   #  define Tcl_NewBignumObj(val) \
  2539   2506        Tcl_DbNewBignumObj(val, __FILE__, __LINE__)
  2540   2507   #  undef  Tcl_NewBooleanObj
  2541   2508   #  define Tcl_NewBooleanObj(val) \
  2542         -     Tcl_DbNewBooleanObj(val, __FILE__, __LINE__)
         2509  +     Tcl_DbNewLongObj((val)!=0, __FILE__, __LINE__)
  2543   2510   #  undef  Tcl_NewByteArrayObj
  2544   2511   #  define Tcl_NewByteArrayObj(bytes, len) \
  2545   2512        Tcl_DbNewByteArrayObj(bytes, len, __FILE__, __LINE__)
  2546   2513   #  undef  Tcl_NewDoubleObj
  2547   2514   #  define Tcl_NewDoubleObj(val) \
  2548   2515        Tcl_DbNewDoubleObj(val, __FILE__, __LINE__)
  2549         -#  undef  Tcl_NewIntObj
  2550         -#  define Tcl_NewIntObj(val) \
  2551         -     Tcl_DbNewLongObj(val, __FILE__, __LINE__)
  2552   2516   #  undef  Tcl_NewListObj
  2553   2517   #  define Tcl_NewListObj(objc, objv) \
  2554   2518        Tcl_DbNewListObj(objc, objv, __FILE__, __LINE__)
  2555         -#  undef  Tcl_NewLongObj
  2556         -#  define Tcl_NewLongObj(val) \
  2557         -     Tcl_DbNewLongObj(val, __FILE__, __LINE__)
  2558   2519   #  undef  Tcl_NewObj
  2559   2520   #  define Tcl_NewObj() \
  2560   2521        Tcl_DbNewObj(__FILE__, __LINE__)
  2561   2522   #  undef  Tcl_NewStringObj
  2562   2523   #  define Tcl_NewStringObj(bytes, len) \
  2563   2524        Tcl_DbNewStringObj(bytes, len, __FILE__, __LINE__)
  2564   2525   #  undef  Tcl_NewWideIntObj
................................................................................
  2613   2574   #endif /* TCL_THREADS */
  2614   2575   
  2615   2576   /*
  2616   2577    *----------------------------------------------------------------------------
  2617   2578    * Deprecated Tcl functions:
  2618   2579    */
  2619   2580   
  2620         -#ifndef TCL_NO_DEPRECATED
         2581  +#if !defined(TCL_NO_DEPRECATED) && TCL_MAJOR_VERSION < 9
  2621   2582   /*
  2622   2583    * These function have been renamed. The old names are deprecated, but we
  2623         - * define these macros for backwards compatibilty.
         2584  + * define these macros for backwards compatibility.
  2624   2585    */
  2625   2586   
  2626   2587   #   define Tcl_Ckalloc		Tcl_Alloc
  2627   2588   #   define Tcl_Ckfree		Tcl_Free
  2628   2589   #   define Tcl_Ckrealloc	Tcl_Realloc
  2629   2590   #   define Tcl_Return		Tcl_SetResult
  2630   2591   #   define Tcl_TildeSubst	Tcl_TranslateFileName
  2631   2592   #if !defined(__APPLE__) /* On OSX, there is a conflict with "mach/mach.h" */
  2632   2593   #   define panic		Tcl_Panic
  2633   2594   #endif
  2634   2595   #   define panicVA		Tcl_PanicVA
  2635         -#endif /* !TCL_NO_DEPRECATED */
  2636   2596   
  2637   2597   /*
  2638   2598    *----------------------------------------------------------------------------
  2639   2599    * Convenience declaration of Tcl_AppInit for backwards compatibility. This
  2640   2600    * function is not *implemented* by the tcl library, so the storage class is
  2641   2601    * neither DLLEXPORT nor DLLIMPORT.
  2642   2602    */
  2643   2603   
  2644   2604   extern Tcl_AppInitProc Tcl_AppInit;
         2605  +
         2606  +#endif /* !TCL_NO_DEPRECATED */
  2645   2607   
  2646   2608   #endif /* RC_INVOKED */
  2647   2609   
  2648   2610   /*
  2649   2611    * end block for C++
  2650   2612    */
  2651   2613   

Changes to generic/tclAlloc.c.

   657    657   	    fprintf(stderr, " %u", j);
   658    658   	}
   659    659   	totalFree += ((size_t)j) * (1 << (i + 3));
   660    660       }
   661    661   
   662    662       fprintf(stderr, "\nused:\t");
   663    663       for (i = 0; i < NBUCKETS; i++) {
   664         -	fprintf(stderr, " %" TCL_LL_MODIFIER "d", (Tcl_WideInt)numMallocs[i]);
          664  +	fprintf(stderr, " %" TCL_Z_MODIFIER "u", numMallocs[i]);
   665    665   	totalUsed += numMallocs[i] * (1 << (i + 3));
   666    666       }
   667    667   
   668         -    fprintf(stderr, "\n\tTotal small in use: %" TCL_LL_MODIFIER "d, total free: %" TCL_LL_MODIFIER "d\n",
   669         -	(Tcl_WideInt)totalUsed, (Tcl_WideInt)totalFree);
   670         -    fprintf(stderr, "\n\tNumber of big (>%d) blocks in use: %" TCL_LL_MODIFIER "d\n",
   671         -	    MAXMALLOC, (Tcl_WideInt)numMallocs[NBUCKETS]);
          668  +    fprintf(stderr, "\n\tTotal small in use: %" TCL_Z_MODIFIER "u, total free: %" TCL_Z_MODIFIER "u\n",
          669  +	totalUsed, totalFree);
          670  +    fprintf(stderr, "\n\tNumber of big (>%d) blocks in use: %" TCL_Z_MODIFIER "u\n",
          671  +	    MAXMALLOC, numMallocs[NBUCKETS]);
   672    672   
   673    673       Tcl_MutexUnlock(allocMutexPtr);
   674    674   }
   675    675   #endif
   676    676   
   677    677   #else	/* !USE_TCLALLOC */
   678    678   

Changes to generic/tclAssembly.c.

   133    133   typedef enum TalInstType {
   134    134       ASSEM_1BYTE,		/* Fixed arity, 1-byte instruction */
   135    135       ASSEM_BEGIN_CATCH,		/* Begin catch: one 4-byte jump offset to be
   136    136   				 * converted to appropriate exception
   137    137   				 * ranges */
   138    138       ASSEM_BOOL,			/* One Boolean operand */
   139    139       ASSEM_BOOL_LVT4,		/* One Boolean, one 4-byte LVT ref. */
          140  +    ASSEM_CLOCK_READ,		/* 1-byte unsigned-integer case number, in the
          141  +				 * range 0-3 */
   140    142       ASSEM_CONCAT1,		/* 1-byte unsigned-integer operand count, must
   141    143   				 * be strictly positive, consumes N, produces
   142    144   				 * 1 */
   143    145       ASSEM_DICT_GET,		/* 'dict get' and related - consumes N+1
   144    146   				 * operands, produces 1, N > 0 */
   145    147       ASSEM_DICT_SET,		/* specifies key count and LVT index, consumes
   146    148   				 * N+1 operands, produces 1, N > 0 */
................................................................................
   346    348       {"arrayMakeStk",	ASSEM_1BYTE,	INST_ARRAY_MAKE_STK,	1,	0},
   347    349       {"beginCatch",	ASSEM_BEGIN_CATCH,
   348    350   					INST_BEGIN_CATCH4,	0,	0},
   349    351       {"bitand",		ASSEM_1BYTE,	INST_BITAND,		2,	1},
   350    352       {"bitnot",		ASSEM_1BYTE,	INST_BITNOT,		1,	1},
   351    353       {"bitor",		ASSEM_1BYTE,	INST_BITOR,		2,	1},
   352    354       {"bitxor",		ASSEM_1BYTE,	INST_BITXOR,		2,	1},
          355  +    {"clockRead",	ASSEM_CLOCK_READ, INST_CLOCK_READ,	0,	1},
   353    356       {"concat",		ASSEM_CONCAT1,	INST_STR_CONCAT1,	INT_MIN,1},
   354    357       {"concatStk",	ASSEM_LIST,	INST_CONCAT_STK,	INT_MIN,1},
   355    358       {"coroName",	ASSEM_1BYTE,	INST_COROUTINE_NAME,	0,	1},
   356    359       {"currentNamespace",ASSEM_1BYTE,	INST_NS_CURRENT,	0,	1},
   357    360       {"dictAppend",	ASSEM_LVT4,	INST_DICT_APPEND,	2,	1},
   358    361       {"dictExists",	ASSEM_DICT_GET, INST_DICT_EXISTS,	INT_MIN,1},
   359    362       {"dictExpand",	ASSEM_1BYTE,	INST_DICT_EXPAND,	3,	1},
................................................................................
  1356   1359   	localVar = FindLocalVar(assemEnvPtr, &tokenPtr);
  1357   1360   	if (localVar < 0) {
  1358   1361   	    goto cleanup;
  1359   1362   	}
  1360   1363   	BBEmitInstInt1(assemEnvPtr, tblIdx, opnd, 0);
  1361   1364   	TclEmitInt4(localVar, envPtr);
  1362   1365   	break;
         1366  +
         1367  +    case ASSEM_CLOCK_READ:
         1368  +	if (parsePtr->numWords != 2) {
         1369  +	    Tcl_WrongNumArgs(interp, 1, &instNameObj, "imm8");
         1370  +	    goto cleanup;
         1371  +	}
         1372  +	if (GetIntegerOperand(assemEnvPtr, &tokenPtr, &opnd) != TCL_OK) {
         1373  +	    goto cleanup;
         1374  +	}
         1375  +	if (opnd < 0 || opnd > 3) {
         1376  +	    Tcl_SetObjResult(interp,
         1377  +			     Tcl_NewStringObj("operand must be [0..3]", -1));
         1378  +	    Tcl_SetErrorCode(interp, "TCL", "ASSEM", "OPERAND<0,>3", NULL);
         1379  +	    goto cleanup;
         1380  +	}
         1381  +	BBEmitInstInt1(assemEnvPtr, tblIdx, opnd, opnd);
         1382  +	break;
  1363   1383   
  1364   1384       case ASSEM_CONCAT1:
  1365   1385   	if (parsePtr->numWords != 2) {
  1366   1386   	    Tcl_WrongNumArgs(interp, 1, &instNameObj, "imm8");
  1367   1387   	    goto cleanup;
  1368   1388   	}
  1369   1389   	if (GetIntegerOperand(assemEnvPtr, &tokenPtr, &opnd) != TCL_OK
................................................................................
  2222   2242       CompileEnv* envPtr = assemEnvPtr->envPtr;
  2223   2243   				/* Compilation environment */
  2224   2244       Tcl_Interp* interp = (Tcl_Interp*) envPtr->iPtr;
  2225   2245   				/* Tcl interpreter */
  2226   2246       Tcl_Token* tokenPtr = *tokenPtrPtr;
  2227   2247   				/* INOUT: Pointer to the next token in the
  2228   2248   				 * source code */
  2229         -    Tcl_Obj* intObj;		/* Integer from the source code */
  2230         -    int status;			/* Tcl status return */
         2249  +    Tcl_Obj *value;
         2250  +    int status;
  2231   2251   
  2232         -    /*
  2233         -     * Extract the next token as a string.
  2234         -     */
  2235         -
  2236         -    if (GetNextOperand(assemEnvPtr, tokenPtrPtr, &intObj) != TCL_OK) {
         2252  +    /* General operand validity check */
         2253  +    if (GetNextOperand(assemEnvPtr, tokenPtrPtr, &value) != TCL_OK) {
  2237   2254   	return TCL_ERROR;
  2238   2255       }
         2256  +     
         2257  +    /* Convert to an integer, advance to the next token and return. */
         2258  +    /*
         2259  +     * NOTE: Indexing a list with an index before it yields the
         2260  +     * same result as indexing after it, and might be more easily portable
         2261  +     * when list size limits grow.
         2262  +     */
         2263  +    status = TclIndexEncode(interp, value,
         2264  +	    TCL_INDEX_BEFORE,TCL_INDEX_BEFORE, result);
  2239   2265   
  2240         -    /*
  2241         -     * Convert to an integer, advance to the next token and return.
  2242         -     */
  2243         -
  2244         -    status = TclGetIntForIndex(interp, intObj, -2, result);
  2245         -    Tcl_DecrRefCount(intObj);
         2266  +    Tcl_DecrRefCount(value);
  2246   2267       *tokenPtrPtr = TokenAfter(tokenPtr);
  2247   2268       return status;
  2248   2269   }
  2249   2270   
  2250   2271   /*
  2251   2272    *-----------------------------------------------------------------------------
  2252   2273    *
................................................................................
  4242   4263   
  4243   4264       Tcl_AddErrorInfo(interp, "\n    in assembly code between lines ");
  4244   4265       lineNo = Tcl_NewIntObj(bbPtr->startLine);
  4245   4266       Tcl_IncrRefCount(lineNo);
  4246   4267       Tcl_AppendObjToErrorInfo(interp, lineNo);
  4247   4268       Tcl_AddErrorInfo(interp, " and ");
  4248   4269       if (bbPtr->successor1 != NULL) {
  4249         -	Tcl_SetIntObj(lineNo, bbPtr->successor1->startLine);
         4270  +	TclSetIntObj(lineNo, bbPtr->successor1->startLine);
  4250   4271   	Tcl_AppendObjToErrorInfo(interp, lineNo);
  4251   4272       } else {
  4252   4273   	Tcl_AddErrorInfo(interp, "end of assembly code");
  4253   4274       }
  4254   4275       Tcl_DecrRefCount(lineNo);
  4255   4276   }
  4256   4277   

Changes to generic/tclBasic.c.

   114    114   static Tcl_ObjCmdProc	ExprBoolFunc;
   115    115   static Tcl_ObjCmdProc	ExprCeilFunc;
   116    116   static Tcl_ObjCmdProc	ExprDoubleFunc;
   117    117   static Tcl_ObjCmdProc	ExprEntierFunc;
   118    118   static Tcl_ObjCmdProc	ExprFloorFunc;
   119    119   static Tcl_ObjCmdProc	ExprIntFunc;
   120    120   static Tcl_ObjCmdProc	ExprIsqrtFunc;
          121  +static Tcl_ObjCmdProc	ExprMaxFunc;
          122  +static Tcl_ObjCmdProc	ExprMinFunc;
   121    123   static Tcl_ObjCmdProc	ExprRandFunc;
   122    124   static Tcl_ObjCmdProc	ExprRoundFunc;
   123    125   static Tcl_ObjCmdProc	ExprSqrtFunc;
   124    126   static Tcl_ObjCmdProc	ExprSrandFunc;
   125    127   static Tcl_ObjCmdProc	ExprUnaryFunc;
   126    128   static Tcl_ObjCmdProc	ExprWideFunc;
   127    129   static void		MathFuncWrongNumArgs(Tcl_Interp *interp, int expected,
   128    130   			    int actual, Tcl_Obj *const *objv);
   129    131   static Tcl_NRPostProc	NRCoroutineCallerCallback;
   130    132   static Tcl_NRPostProc	NRCoroutineExitCallback;
   131    133   static Tcl_NRPostProc	NRCommand;
   132    134   
          135  +#if !defined(TCL_NO_DEPRECATED)
   133    136   static Tcl_ObjCmdProc	OldMathFuncProc;
   134    137   static void		OldMathFuncDeleteProc(ClientData clientData);
          138  +#endif /* !defined(TCL_NO_DEPRECATED) */
   135    139   static void		ProcessUnexpectedResult(Tcl_Interp *interp,
   136    140   			    int returnCode);
   137    141   static int		RewindCoroutine(CoroutineData *corPtr, int result);
   138    142   static void		TEOV_SwitchVarFrame(Tcl_Interp *interp);
   139    143   static void		TEOV_PushExceptionHandlers(Tcl_Interp *interp,
   140    144   			    int objc, Tcl_Obj *const objv[], int flags);
   141    145   static inline Command *	TEOV_LookupCmdFromObj(Tcl_Interp *interp,
................................................................................
   199    203       /*
   200    204        * Commands in the generic core.
   201    205        */
   202    206   
   203    207       {"append",		Tcl_AppendObjCmd,	TclCompileAppendCmd,	NULL,	CMD_IS_SAFE},
   204    208       {"apply",		Tcl_ApplyObjCmd,	NULL,			TclNRApplyObjCmd,	CMD_IS_SAFE},
   205    209       {"break",		Tcl_BreakObjCmd,	TclCompileBreakCmd,	NULL,	CMD_IS_SAFE},
   206         -#ifndef TCL_NO_DEPRECATED
          210  +#if !defined(TCL_NO_DEPRECATED) && TCL_MAJOR_VERSION < 9
   207    211       {"case",		Tcl_CaseObjCmd,		NULL,			NULL,	CMD_IS_SAFE},
   208    212   #endif
   209    213       {"catch",		Tcl_CatchObjCmd,	TclCompileCatchCmd,	TclNRCatchObjCmd,	CMD_IS_SAFE},
   210    214       {"concat",		Tcl_ConcatObjCmd,	TclCompileConcatCmd,	NULL,	CMD_IS_SAFE},
   211    215       {"continue",	Tcl_ContinueObjCmd,	TclCompileContinueCmd,	NULL,	CMD_IS_SAFE},
   212    216       {"coroutine",	NULL,			NULL,			TclNRCoroutineObjCmd,	CMD_IS_SAFE},
   213    217       {"error",		Tcl_ErrorObjCmd,	TclCompileErrorCmd,	NULL,	CMD_IS_SAFE},
................................................................................
   230    234       {"lrange",		Tcl_LrangeObjCmd,	TclCompileLrangeCmd,	NULL,	CMD_IS_SAFE},
   231    235       {"lrepeat",		Tcl_LrepeatObjCmd,	NULL,			NULL,	CMD_IS_SAFE},
   232    236       {"lreplace",	Tcl_LreplaceObjCmd,	TclCompileLreplaceCmd,	NULL,	CMD_IS_SAFE},
   233    237       {"lreverse",	Tcl_LreverseObjCmd,	NULL,			NULL,	CMD_IS_SAFE},
   234    238       {"lsearch",		Tcl_LsearchObjCmd,	NULL,			NULL,	CMD_IS_SAFE},
   235    239       {"lset",		Tcl_LsetObjCmd,		TclCompileLsetCmd,	NULL,	CMD_IS_SAFE},
   236    240       {"lsort",		Tcl_LsortObjCmd,	NULL,			NULL,	CMD_IS_SAFE},
   237         -    {"package",		Tcl_PackageObjCmd,	NULL,			NULL,	CMD_IS_SAFE},
          241  +    {"package",		Tcl_PackageObjCmd,	NULL,			TclNRPackageObjCmd,	CMD_IS_SAFE},
   238    242       {"proc",		Tcl_ProcObjCmd,		NULL,			NULL,	CMD_IS_SAFE},
   239    243       {"regexp",		Tcl_RegexpObjCmd,	TclCompileRegexpCmd,	NULL,	CMD_IS_SAFE},
   240    244       {"regsub",		Tcl_RegsubObjCmd,	TclCompileRegsubCmd,	NULL,	CMD_IS_SAFE},
   241    245       {"rename",		Tcl_RenameObjCmd,	NULL,			NULL,	CMD_IS_SAFE},
   242    246       {"return",		Tcl_ReturnObjCmd,	TclCompileReturnCmd,	NULL,	CMD_IS_SAFE},
   243    247       {"scan",		Tcl_ScanObjCmd,		NULL,			NULL,	CMD_IS_SAFE},
   244    248       {"set",		Tcl_SetObjCmd,		TclCompileSetCmd,	NULL,	CMD_IS_SAFE},
................................................................................
   261    265        * Commands in the OS-interface. Note that many of these are unsafe.
   262    266        */
   263    267   
   264    268       {"after",		Tcl_AfterObjCmd,	NULL,			NULL,	CMD_IS_SAFE},
   265    269       {"cd",		Tcl_CdObjCmd,		NULL,			NULL,	0},
   266    270       {"close",		Tcl_CloseObjCmd,	NULL,			NULL,	CMD_IS_SAFE},
   267    271       {"eof",		Tcl_EofObjCmd,		NULL,			NULL,	CMD_IS_SAFE},
   268         -    {"encoding",	Tcl_EncodingObjCmd,	NULL,			NULL,	0},
   269    272       {"exec",		Tcl_ExecObjCmd,		NULL,			NULL,	0},
   270    273       {"exit",		Tcl_ExitObjCmd,		NULL,			NULL,	0},
   271    274       {"fblocked",	Tcl_FblockedObjCmd,	NULL,			NULL,	CMD_IS_SAFE},
   272    275       {"fconfigure",	Tcl_FconfigureObjCmd,	NULL,			NULL,	0},
   273    276       {"fcopy",		Tcl_FcopyObjCmd,	NULL,			NULL,	CMD_IS_SAFE},
   274    277       {"fileevent",	Tcl_FileEventObjCmd,	NULL,			NULL,	CMD_IS_SAFE},
   275    278       {"flush",		Tcl_FlushObjCmd,	NULL,			NULL,	CMD_IS_SAFE},
................................................................................
   318    321       { "floor",	ExprFloorFunc,	NULL			},
   319    322       { "fmod",	ExprBinaryFunc,	(ClientData) fmod	},
   320    323       { "hypot",	ExprBinaryFunc,	(ClientData) hypot	},
   321    324       { "int",	ExprIntFunc,	NULL			},
   322    325       { "isqrt",	ExprIsqrtFunc,	NULL			},
   323    326       { "log",	ExprUnaryFunc,	(ClientData) log	},
   324    327       { "log10",	ExprUnaryFunc,	(ClientData) log10	},
          328  +    { "max",	ExprMaxFunc,	NULL			},
          329  +    { "min",	ExprMinFunc,	NULL			},
   325    330       { "pow",	ExprBinaryFunc,	(ClientData) pow	},
   326    331       { "rand",	ExprRandFunc,	NULL			},
   327    332       { "round",	ExprRoundFunc,	NULL			},
   328    333       { "sin",	ExprUnaryFunc,	(ClientData) sin	},
   329    334       { "sinh",	ExprUnaryFunc,	(ClientData) sinh	},
   330    335       { "sqrt",	ExprSqrtFunc,	NULL			},
   331    336       { "srand",	ExprSrandFunc,	NULL			},
................................................................................
   507    512        * (whose name is ""; an alias is "::"). This also initializes the Tcl
   508    513        * object type table and other object management code.
   509    514        */
   510    515   
   511    516       iPtr = ckalloc(sizeof(Interp));
   512    517       interp = (Tcl_Interp *) iPtr;
   513    518   
          519  +#ifdef TCL_NO_DEPRECATED
          520  +    iPtr->result = &tclEmptyString;
          521  +#else
   514    522       iPtr->result = iPtr->resultSpace;
          523  +#endif
   515    524       iPtr->freeProc = NULL;
   516    525       iPtr->errorLine = 0;
   517    526       iPtr->objResultPtr = Tcl_NewObj();
   518    527       Tcl_IncrRefCount(iPtr->objResultPtr);
   519    528       iPtr->handle = TclHandleCreate(iPtr);
   520    529       iPtr->globalNsPtr = NULL;
   521    530       iPtr->hiddenCmdTablePtr = NULL;
................................................................................
   567    576       Tcl_IncrRefCount(iPtr->ecVar);
   568    577       iPtr->returnLevel = 1;
   569    578       iPtr->returnCode = TCL_OK;
   570    579   
   571    580       iPtr->rootFramePtr = NULL;	/* Initialise as soon as :: is available */
   572    581       iPtr->lookupNsPtr = NULL;
   573    582   
          583  +#ifndef TCL_NO_DEPRECATED
   574    584       iPtr->appendResult = NULL;
   575    585       iPtr->appendAvl = 0;
   576    586       iPtr->appendUsed = 0;
          587  +#endif
   577    588   
   578    589       Tcl_InitHashTable(&iPtr->packageTable, TCL_STRING_KEYS);
   579    590       iPtr->packageUnknown = NULL;
   580    591   
   581    592       /* TIP #268 */
   582    593   #if (TCL_RELEASE_LEVEL == TCL_FINAL_RELEASE)
   583    594       if (getenv("TCL_PKG_PREFER_LATEST") == NULL) {
................................................................................
   599    610       iPtr->activeCmdTracePtr = NULL;
   600    611       iPtr->activeInterpTracePtr = NULL;
   601    612       iPtr->assocData = NULL;
   602    613       iPtr->execEnvPtr = NULL;	/* Set after namespaces initialized. */
   603    614       iPtr->emptyObjPtr = Tcl_NewObj();
   604    615   				/* Another empty object. */
   605    616       Tcl_IncrRefCount(iPtr->emptyObjPtr);
          617  +#ifndef TCL_NO_DEPRECATED
   606    618       iPtr->resultSpace[0] = 0;
          619  +#endif
   607    620       iPtr->threadId = Tcl_GetCurrentThread();
   608    621   
   609    622       /* TIP #378 */
   610    623   #ifdef TCL_INTERP_DEBUG_FRAME
   611    624       iPtr->flags |= INTERP_DEBUG_FRAME;
   612    625   #else
   613    626       if (getenv("TCL_INTERP_DEBUG_FRAME") != NULL) {
................................................................................
   786    799   	    cmdPtr->tracePtr = NULL;
   787    800   	    cmdPtr->nreProc = cmdInfoPtr->nreProc;
   788    801   	    Tcl_SetHashValue(hPtr, cmdPtr);
   789    802   	}
   790    803       }
   791    804   
   792    805       /*
   793         -     * Create the "array", "binary", "chan", "dict", "file", "info",
   794         -     * "namespace" and "string" ensembles. Note that all these commands (and
   795         -     * their subcommands that are not present in the global namespace) are
   796         -     * wholly safe *except* for "file".
          806  +     * Create the "array", "binary", "chan", "clock", "dict", "encoding",
          807  +     * "file", "info", "namespace" and "string" ensembles. Note that all these
          808  +     * commands (and their subcommands that are not present in the global
          809  +     * namespace) are wholly safe *except* for "clock", "encoding" and "file".
   797    810        */
   798    811   
   799    812       TclInitArrayCmd(interp);
   800    813       TclInitBinaryCmd(interp);
   801    814       TclInitChanCmd(interp);
   802    815       TclInitDictCmd(interp);
          816  +    TclInitEncodingCmd(interp);
   803    817       TclInitFileCmd(interp);
   804    818       TclInitInfoCmd(interp);
   805    819       TclInitNamespaceCmd(interp);
   806    820       TclInitStringCmd(interp);
   807    821       TclInitPrefixCmd(interp);
          822  +    TclInitProcessCmd(interp);
   808    823   
   809    824       /*
   810    825        * Register "clock" subcommands. These *do* go through
   811    826        * Tcl_CreateObjCommand, since they aren't in the global namespace and
   812    827        * involve ensembles.
   813    828        */
   814    829   
................................................................................
   941    956   
   942    957       /*
   943    958        * Set up other variables such as tcl_version and tcl_library
   944    959        */
   945    960   
   946    961       Tcl_SetVar2(interp, "tcl_patchLevel", NULL, TCL_PATCH_LEVEL, TCL_GLOBAL_ONLY);
   947    962       Tcl_SetVar2(interp, "tcl_version", NULL, TCL_VERSION, TCL_GLOBAL_ONLY);
          963  +#if !defined(TCL_NO_DEPRECATED) && TCL_MAJOR_VERSION < 9
   948    964       Tcl_TraceVar2(interp, "tcl_precision", NULL,
   949    965   	    TCL_GLOBAL_ONLY|TCL_TRACE_READS|TCL_TRACE_WRITES|TCL_TRACE_UNSETS,
   950    966   	    TclPrecTraceProc, NULL);
          967  +#endif /* !TCL_NO_DEPRECATED */
   951    968       TclpSetVariables(interp);
   952    969   
   953    970   #ifdef TCL_THREADS
   954    971       /*
   955    972        * The existence of the "threaded" element of the tcl_platform array
   956    973        * indicates that this particular Tcl shell has been compiled with threads
   957    974        * turned on. Using "info exists tcl_platform(threaded)" a Tcl script can
................................................................................
  1026   1043   	return TCL_ERROR;
  1027   1044       }
  1028   1045       for (cmdInfoPtr = builtInCmds; cmdInfoPtr->name != NULL; cmdInfoPtr++) {
  1029   1046   	if (!(cmdInfoPtr->flags & CMD_IS_SAFE)) {
  1030   1047   	    Tcl_HideCommand(interp, cmdInfoPtr->name, cmdInfoPtr->name);
  1031   1048   	}
  1032   1049       }
         1050  +    TclMakeEncodingCommandSafe(interp); /* Ugh! */
  1033   1051       TclMakeFileCommandSafe(interp);     /* Ugh! */
  1034   1052       return TCL_OK;
  1035   1053   }
  1036   1054   
  1037   1055   /*
  1038   1056    *--------------------------------------------------------------
  1039   1057    *
................................................................................
  1061   1079       Tcl_InterpDeleteProc *proc,	/* Function to call when interpreter is about
  1062   1080   				 * to be deleted. */
  1063   1081       ClientData clientData)	/* One-word value to pass to proc. */
  1064   1082   {
  1065   1083       Interp *iPtr = (Interp *) interp;
  1066   1084       static Tcl_ThreadDataKey assocDataCounterKey;
  1067   1085       int *assocDataCounterPtr =
  1068         -	    Tcl_GetThreadData(&assocDataCounterKey, (int)sizeof(int));
         1086  +	    Tcl_GetThreadData(&assocDataCounterKey, sizeof(int));
  1069   1087       int isNew;
  1070   1088       char buffer[32 + TCL_INTEGER_SPACE];
  1071   1089       AssocData *dPtr = ckalloc(sizeof(AssocData));
  1072   1090       Tcl_HashEntry *hPtr;
  1073   1091   
  1074   1092       sprintf(buffer, "Assoc Data Key #%d", *assocDataCounterPtr);
  1075   1093       (*assocDataCounterPtr)++;
................................................................................
  1533   1551       Tcl_DecrRefCount(iPtr->upLiteral);
  1534   1552       Tcl_DecrRefCount(iPtr->callLiteral);
  1535   1553       Tcl_DecrRefCount(iPtr->innerLiteral);
  1536   1554       Tcl_DecrRefCount(iPtr->innerContext);
  1537   1555       if (iPtr->returnOpts) {
  1538   1556   	Tcl_DecrRefCount(iPtr->returnOpts);
  1539   1557       }
         1558  +#ifndef TCL_NO_DEPRECATED
  1540   1559       if (iPtr->appendResult != NULL) {
  1541   1560   	ckfree(iPtr->appendResult);
  1542   1561   	iPtr->appendResult = NULL;
  1543   1562       }
         1563  +#endif
  1544   1564       TclFreePackageInfo(iPtr);
  1545   1565       while (iPtr->tracePtr != NULL) {
  1546   1566   	Tcl_DeleteTrace((Tcl_Interp *) iPtr, (Tcl_Trace) iPtr->tracePtr);
  1547   1567       }
  1548   1568       if (iPtr->execEnvPtr != NULL) {
  1549   1569   	TclDeleteExecEnv(iPtr->execEnvPtr);
  1550   1570       }
................................................................................
  2041   2061       ClientData clientData,	/* Arbitrary value passed to string proc. */
  2042   2062       Tcl_CmdDeleteProc *deleteProc)
  2043   2063   				/* If not NULL, gives a function to call when
  2044   2064   				 * this command is deleted. */
  2045   2065   {
  2046   2066       Interp *iPtr = (Interp *) interp;
  2047   2067       ImportRef *oldRefPtr = NULL;
  2048         -    Namespace *nsPtr, *dummy1, *dummy2;
  2049         -    Command *cmdPtr, *refCmdPtr;
         2068  +    Namespace *nsPtr;
         2069  +    Command *cmdPtr;
  2050   2070       Tcl_HashEntry *hPtr;
  2051   2071       const char *tail;
  2052         -    int isNew;
         2072  +    int isNew = 0, deleted = 0;
  2053   2073       ImportedCmdData *dataPtr;
  2054   2074   
  2055   2075       if (iPtr->flags & DELETED) {
  2056   2076   	/*
  2057   2077   	 * The interpreter is being deleted. Don't create any new commands;
  2058   2078   	 * it's not safe to muck with the interpreter anymore.
  2059   2079   	 */
  2060   2080   
  2061   2081   	return (Tcl_Command) NULL;
  2062   2082       }
  2063   2083   
  2064   2084       /*
  2065         -     * Determine where the command should reside. If its name contains
  2066         -     * namespace qualifiers, we put it in the specified namespace; otherwise,
  2067         -     * we always put it in the global namespace.
  2068         -     */
  2069         -
  2070         -    if (strstr(cmdName, "::") != NULL) {
  2071         -	TclGetNamespaceForQualName(interp, cmdName, NULL,
  2072         -		TCL_CREATE_NS_IF_UNKNOWN, &nsPtr, &dummy1, &dummy2, &tail);
  2073         -	if ((nsPtr == NULL) || (tail == NULL)) {
  2074         -	    return (Tcl_Command) NULL;
  2075         -	}
  2076         -    } else {
  2077         -	nsPtr = iPtr->globalNsPtr;
  2078         -	tail = cmdName;
  2079         -    }
  2080         -
  2081         -    hPtr = Tcl_CreateHashEntry(&nsPtr->cmdTable, tail, &isNew);
  2082         -    if (!isNew) {
  2083         -	/*
  2084         -	 * Command already exists. Delete the old one. Be careful to preserve
         2085  +     * If the command name we seek to create already exists, we need to
         2086  +     * delete that first.  That can be tricky in the presence of traces.
         2087  +     * Loop until we no longer find an existing command in the way, or
         2088  +     * until we've deleted one command and that didn't finish the job.
         2089  +     */
         2090  +
         2091  +    while (1) {
         2092  +        /*
         2093  +         * Determine where the command should reside. If its name contains
         2094  +         * namespace qualifiers, we put it in the specified namespace;
         2095  +	 * otherwise, we always put it in the global namespace.
         2096  +         */
         2097  +
         2098  +        if (strstr(cmdName, "::") != NULL) {
         2099  +	    Namespace *dummy1, *dummy2;
         2100  +
         2101  +	    TclGetNamespaceForQualName(interp, cmdName, NULL,
         2102  +		    TCL_CREATE_NS_IF_UNKNOWN, &nsPtr, &dummy1, &dummy2, &tail);
         2103  +	    if ((nsPtr == NULL) || (tail == NULL)) {
         2104  +	        return (Tcl_Command) NULL;
         2105  +	    }
         2106  +        } else {
         2107  +	    nsPtr = iPtr->globalNsPtr;
         2108  +	    tail = cmdName;
         2109  +        }
         2110  +
         2111  +        hPtr = Tcl_CreateHashEntry(&nsPtr->cmdTable, tail, &isNew);
         2112  +
         2113  +	if (isNew || deleted) {
         2114  +	    /*
         2115  +	     * isNew - No conflict with existing command.
         2116  +	     * deleted - We've already deleted a conflicting command
         2117  +	     */
         2118  +	    break;
         2119  +	}
         2120  +
         2121  +	/* An existing command conflicts. Try to delete it.. */
         2122  +	cmdPtr = Tcl_GetHashValue(hPtr);
         2123  +
         2124  +	/*
         2125  +	 * Be careful to preserve
  2085   2126   	 * any existing import links so we can restore them down below. That
  2086   2127   	 * way, you can redefine a command and its import status will remain
  2087   2128   	 * intact.
  2088   2129   	 */
  2089   2130   
  2090         -	cmdPtr = Tcl_GetHashValue(hPtr);
  2091   2131   	cmdPtr->refCount++;
  2092   2132   	if (cmdPtr->importRefPtr) {
  2093   2133   	    cmdPtr->flags |= CMD_REDEF_IN_PROGRESS;
  2094   2134   	}
  2095   2135   
  2096   2136   	Tcl_DeleteCommandFromToken(interp, (Tcl_Command) cmdPtr);
  2097   2137   
  2098   2138   	if (cmdPtr->flags & CMD_REDEF_IN_PROGRESS) {
  2099   2139   	    oldRefPtr = cmdPtr->importRefPtr;
  2100   2140   	    cmdPtr->importRefPtr = NULL;
  2101   2141   	}
  2102   2142   	TclCleanupCommandMacro(cmdPtr);
         2143  +	deleted = 1;
         2144  +    }
  2103   2145   
  2104         -	hPtr = Tcl_CreateHashEntry(&nsPtr->cmdTable, tail, &isNew);
  2105         -	if (!isNew) {
  2106         -	    /*
  2107         -	     * If the deletion callback recreated the command, just throw away
  2108         -	     * the new command (if we try to delete it again, we could get
  2109         -	     * stuck in an infinite loop).
  2110         -	     */
         2146  +    if (!isNew) {
         2147  +	/*
         2148  +	 * If the deletion callback recreated the command, just throw away
         2149  +	 * the new command (if we try to delete it again, we could get
         2150  +	 * stuck in an infinite loop).
         2151  +	 */
  2111   2152   
  2112         -	    ckfree(Tcl_GetHashValue(hPtr));
  2113         -	}
  2114         -    } else {
         2153  +	ckfree(Tcl_GetHashValue(hPtr));
         2154  +    }
         2155  +
         2156  +    if (!deleted) {
         2157  +
  2115   2158   	/*
  2116   2159   	 * Command resolvers (per-interp, per-namespace) might have resolved
  2117   2160   	 * to a command for the given namespace scope with this command not
  2118   2161   	 * being registered with the namespace's command table. During BC
  2119   2162   	 * compilation, the so-resolved command turns into a CmdName literal.
  2120   2163   	 * Without invalidating a possible CmdName literal here explicitly,
  2121   2164   	 * such literals keep being reused while pointing to overhauled
................................................................................
  2155   2198        * Plug in any existing import references found above. Be sure to update
  2156   2199        * all of these references to point to the new command.
  2157   2200        */
  2158   2201   
  2159   2202       if (oldRefPtr != NULL) {
  2160   2203   	cmdPtr->importRefPtr = oldRefPtr;
  2161   2204   	while (oldRefPtr != NULL) {
  2162         -	    refCmdPtr = oldRefPtr->importedCmdPtr;
         2205  +	    Command *refCmdPtr = oldRefPtr->importedCmdPtr;
  2163   2206   	    dataPtr = refCmdPtr->objClientData;
  2164   2207   	    dataPtr->realCmdPtr = cmdPtr;
  2165   2208   	    oldRefPtr = oldRefPtr->nextPtr;
  2166   2209   	}
  2167   2210       }
  2168   2211   
  2169   2212       /*
................................................................................
  2210   2253   				 * qualifiers, the new command is put in the
  2211   2254   				 * specified namespace; otherwise it is put in
  2212   2255   				 * the global namespace. */
  2213   2256       Tcl_ObjCmdProc *proc,	/* Object-based function to associate with
  2214   2257   				 * name. */
  2215   2258       ClientData clientData,	/* Arbitrary value to pass to object
  2216   2259   				 * function. */
  2217         -    Tcl_CmdDeleteProc *deleteProc)
         2260  +    Tcl_CmdDeleteProc *deleteProc
  2218   2261   				/* If not NULL, gives a function to call when
  2219   2262   				 * this command is deleted. */
         2263  +)
  2220   2264   {
  2221   2265       Interp *iPtr = (Interp *) interp;
  2222         -    ImportRef *oldRefPtr = NULL;
  2223         -    Namespace *nsPtr, *dummy1, *dummy2;
  2224         -    Command *cmdPtr, *refCmdPtr;
  2225         -    Tcl_HashEntry *hPtr;
         2266  +    Namespace *nsPtr;
  2226   2267       const char *tail;
  2227         -    int isNew;
  2228         -    ImportedCmdData *dataPtr;
  2229   2268   
  2230   2269       if (iPtr->flags & DELETED) {
  2231   2270   	/*
  2232   2271   	 * The interpreter is being deleted. Don't create any new commands;
  2233   2272   	 * it's not safe to muck with the interpreter anymore.
  2234   2273   	 */
  2235         -
  2236   2274   	return (Tcl_Command) NULL;
  2237   2275       }
  2238   2276   
  2239   2277       /*
  2240   2278        * Determine where the command should reside. If its name contains
  2241         -     * namespace qualifiers, we put it in the specified namespace; otherwise,
  2242         -     * we always put it in the global namespace.
         2279  +     * namespace qualifiers, we put it in the specified namespace;
         2280  +     * otherwise, we always put it in the global namespace.
  2243   2281        */
  2244   2282   
  2245   2283       if (strstr(cmdName, "::") != NULL) {
         2284  +	Namespace *dummy1, *dummy2;
         2285  +
  2246   2286   	TclGetNamespaceForQualName(interp, cmdName, NULL,
  2247         -		TCL_CREATE_NS_IF_UNKNOWN, &nsPtr, &dummy1, &dummy2, &tail);
         2287  +	    TCL_CREATE_NS_IF_UNKNOWN, &nsPtr, &dummy1, &dummy2, &tail);
  2248   2288   	if ((nsPtr == NULL) || (tail == NULL)) {
  2249   2289   	    return (Tcl_Command) NULL;
  2250   2290   	}
  2251   2291       } else {
  2252   2292   	nsPtr = iPtr->globalNsPtr;
  2253   2293   	tail = cmdName;
  2254   2294       }
  2255   2295   
  2256         -    hPtr = Tcl_CreateHashEntry(&nsPtr->cmdTable, tail, &isNew);
  2257         -    TclInvalidateNsPath(nsPtr);
  2258         -    if (!isNew) {
         2296  +    return TclCreateObjCommandInNs(interp, tail, (Tcl_Namespace *) nsPtr,
         2297  +	proc, clientData, deleteProc);
         2298  +}
         2299  +
         2300  +Tcl_Command
         2301  +TclCreateObjCommandInNs (
         2302  +    Tcl_Interp *interp,
         2303  +    const char *cmdName,	/* Name of command, without any namespace components */
         2304  +    Tcl_Namespace *namespace,   /* The namespace to create the command in */
         2305  +    Tcl_ObjCmdProc *proc,	/* Object-based function to associate with
         2306  +				 * name. */
         2307  +    ClientData clientData,	/* Arbitrary value to pass to object
         2308  +				 * function. */
         2309  +    Tcl_CmdDeleteProc *deleteProc
         2310  +				/* If not NULL, gives a function to call when
         2311  +				 * this command is deleted. */
         2312  +) {
         2313  +    int deleted = 0, isNew = 0;
         2314  +    Command *cmdPtr;
         2315  +    ImportRef *oldRefPtr = NULL;
         2316  +    ImportedCmdData *dataPtr;
         2317  +    Tcl_HashEntry *hPtr;
         2318  +    Namespace *nsPtr = (Namespace *) namespace;
         2319  +    /*
         2320  +     * If the command name we seek to create already exists, we need to
         2321  +     * delete that first.  That can be tricky in the presence of traces.
         2322  +     * Loop until we no longer find an existing command in the way, or
         2323  +     * until we've deleted one command and that didn't finish the job.
         2324  +     */
         2325  +    while (1) {
         2326  +	hPtr = Tcl_CreateHashEntry(&nsPtr->cmdTable, cmdName, &isNew);
         2327  +
         2328  +	if (isNew || deleted) {
         2329  +	    /*
         2330  +	     * isNew - No conflict with existing command.
         2331  +	     * deleted - We've already deleted a conflicting command
         2332  +	     */
         2333  +	    break;
         2334  +	}
         2335  +
         2336  +
         2337  +	/* An existing command conflicts. Try to delete it.. */
  2259   2338   	cmdPtr = Tcl_GetHashValue(hPtr);
  2260   2339   
  2261         -	/* Command already exists. */
  2262         -
  2263   2340   	/*
  2264   2341   	 * [***] This is wrong.  See Tcl Bug a16752c252.
  2265   2342   	 * However, this buggy behavior is kept under particular
  2266   2343   	 * circumstances to accommodate deployed binaries of the
  2267   2344   	 * "tclcompiler" program. http://sourceforge.net/projects/tclpro/
  2268   2345   	 * that crash if the bug is fixed.
  2269   2346   	 */
................................................................................
  2284   2361   	 * intact.
  2285   2362   	 */
  2286   2363   
  2287   2364   	cmdPtr->refCount++;
  2288   2365   	if (cmdPtr->importRefPtr) {
  2289   2366   	    cmdPtr->flags |= CMD_REDEF_IN_PROGRESS;
  2290   2367   	}
         2368  +
         2369  +	/* Make sure namespace doesn't get deallocated. */
         2370  +	cmdPtr->nsPtr->refCount++;
  2291   2371   
  2292   2372   	Tcl_DeleteCommandFromToken(interp, (Tcl_Command) cmdPtr);
         2373  +	nsPtr = (Namespace *) TclEnsureNamespace(interp,
         2374  +	    (Tcl_Namespace *)cmdPtr->nsPtr);
         2375  +	TclNsDecrRefCount(cmdPtr->nsPtr);
  2293   2376   
  2294   2377   	if (cmdPtr->flags & CMD_REDEF_IN_PROGRESS) {
  2295   2378   	    oldRefPtr = cmdPtr->importRefPtr;
  2296   2379   	    cmdPtr->importRefPtr = NULL;
  2297   2380   	}
  2298   2381   	TclCleanupCommandMacro(cmdPtr);
         2382  +	deleted = 1;
         2383  +    }
         2384  +    if (!isNew) {
         2385  +	/*
         2386  +	 * If the deletion callback recreated the command, just throw away
         2387  +	 * the new command (if we try to delete it again, we could get
         2388  +	 * stuck in an infinite loop).
         2389  +	 */
  2299   2390   
  2300         -	hPtr = Tcl_CreateHashEntry(&nsPtr->cmdTable, tail, &isNew);
  2301         -	if (!isNew) {
  2302         -	    /*
  2303         -	     * If the deletion callback recreated the command, just throw away
  2304         -	     * the new command (if we try to delete it again, we could get
  2305         -	     * stuck in an infinite loop).
  2306         -	     */
         2391  +	ckfree(Tcl_GetHashValue(hPtr));
         2392  +    }
  2307   2393   
  2308         -	    ckfree(Tcl_GetHashValue(hPtr));
  2309         -	}
  2310         -    } else {
         2394  +    if (!deleted) {
  2311   2395   	/*
  2312   2396   	 * Command resolvers (per-interp, per-namespace) might have resolved
  2313   2397   	 * to a command for the given namespace scope with this command not
  2314   2398   	 * being registered with the namespace's command table. During BC
  2315   2399   	 * compilation, the so-resolved command turns into a CmdName literal.
  2316   2400   	 * Without invalidating a possible CmdName literal here explicitly,
  2317   2401   	 * such literals keep being reused while pointing to overhauled
  2318   2402   	 * commands.
  2319   2403   	 */
  2320   2404   
  2321         -	TclInvalidateCmdLiteral(interp, tail, nsPtr);
         2405  +	TclInvalidateCmdLiteral(interp, cmdName, nsPtr);
  2322   2406   
  2323   2407   	/*
  2324   2408   	 * The list of command exported from the namespace might have changed.
  2325   2409   	 * However, we do not need to recompute this just yet; next time we
  2326   2410   	 * need the info will be soon enough.
  2327   2411   	 */
  2328   2412   
  2329   2413   	TclInvalidateNsCmdLookup(nsPtr);
         2414  +	TclInvalidateNsPath(nsPtr);
  2330   2415       }
  2331   2416       cmdPtr = ckalloc(sizeof(Command));
  2332   2417       Tcl_SetHashValue(hPtr, cmdPtr);
  2333   2418       cmdPtr->hPtr = hPtr;
  2334   2419       cmdPtr->nsPtr = nsPtr;
  2335   2420       cmdPtr->refCount = 1;
  2336   2421       cmdPtr->cmdEpoch = 0;
................................................................................
  2350   2435        * Plug in any existing import references found above. Be sure to update
  2351   2436        * all of these references to point to the new command.
  2352   2437        */
  2353   2438   
  2354   2439       if (oldRefPtr != NULL) {
  2355   2440   	cmdPtr->importRefPtr = oldRefPtr;
  2356   2441   	while (oldRefPtr != NULL) {
  2357         -	    refCmdPtr = oldRefPtr->importedCmdPtr;
         2442  +	    Command *refCmdPtr = oldRefPtr->importedCmdPtr;
  2358   2443   	    dataPtr = refCmdPtr->objClientData;
  2359   2444   	    dataPtr->realCmdPtr = cmdPtr;
  2360   2445   	    oldRefPtr = oldRefPtr->nextPtr;
  2361   2446   	}
  2362   2447       }
  2363   2448   
  2364   2449       /*
................................................................................
  2543   2628   	Tcl_SetObjResult(interp, Tcl_ObjPrintf(
  2544   2629                   "can't %s \"%s\": command doesn't exist",
  2545   2630   		((newName == NULL)||(*newName == '\0'))? "delete":"rename",
  2546   2631   		oldName));
  2547   2632           Tcl_SetErrorCode(interp, "TCL", "LOOKUP", "COMMAND", oldName, NULL);
  2548   2633   	return TCL_ERROR;
  2549   2634       }
  2550         -    cmdNsPtr = cmdPtr->nsPtr;
  2551         -    oldFullName = Tcl_NewObj();
  2552         -    Tcl_IncrRefCount(oldFullName);
  2553         -    Tcl_GetCommandFullName(interp, cmd, oldFullName);
  2554   2635   
  2555   2636       /*
  2556   2637        * If the new command name is NULL or empty, delete the command. Do this
  2557   2638        * with Tcl_DeleteCommandFromToken, since we already have the command.
  2558   2639        */
  2559   2640   
  2560   2641       if ((newName == NULL) || (*newName == '\0')) {
  2561   2642   	Tcl_DeleteCommandFromToken(interp, cmd);
  2562         -	result = TCL_OK;
  2563         -	goto done;
         2643  +	return TCL_OK;
  2564   2644       }
  2565   2645   
         2646  +    cmdNsPtr = cmdPtr->nsPtr;
         2647  +    oldFullName = Tcl_NewObj();
         2648  +    Tcl_IncrRefCount(oldFullName);
         2649  +    Tcl_GetCommandFullName(interp, cmd, oldFullName);
         2650  +
  2566   2651       /*
  2567   2652        * Make sure that the destination command does not already exist. The
  2568   2653        * rename operation is like creating a command, so we should automatically
  2569   2654        * create the containing namespaces just like Tcl_CreateCommand would.
  2570   2655        */
  2571   2656   
  2572   2657       TclGetNamespaceForQualName(interp, newName, NULL,
................................................................................
  3058   3143   
  3059   3144   	return 0;
  3060   3145       }
  3061   3146   
  3062   3147       /*
  3063   3148        * We must delete this command, even though both traces and delete procs
  3064   3149        * may try to avoid this (renaming the command etc). Also traces and
  3065         -     * delete procs may try to delete the command themsevles. This flag
         3150  +     * delete procs may try to delete the command themselves. This flag
  3066   3151        * declares that a delete is in progress and that recursive deletes should
  3067   3152        * be ignored.
  3068   3153        */
  3069   3154   
  3070   3155       cmdPtr->flags |= CMD_IS_DELETED;
  3071   3156   
  3072   3157       /*
  3073   3158        * Call trace functions for the command being deleted. Then delete its
  3074   3159        * traces.
  3075   3160        */
         3161  +
         3162  +    cmdPtr->nsPtr->refCount++;
  3076   3163   
  3077   3164       if (cmdPtr->tracePtr != NULL) {
  3078   3165   	CommandTrace *tracePtr;
  3079   3166   	CallCommandTraces(iPtr,cmdPtr,NULL,NULL,TCL_TRACE_DELETE);
  3080   3167   
  3081   3168   	/*
  3082   3169   	 * Now delete these traces.
................................................................................
  3097   3184       /*
  3098   3185        * The list of command exported from the namespace might have changed.
  3099   3186        * However, we do not need to recompute this just yet; next time we need
  3100   3187        * the info will be soon enough.
  3101   3188        */
  3102   3189   
  3103   3190       TclInvalidateNsCmdLookup(cmdPtr->nsPtr);
         3191  +    TclNsDecrRefCount(cmdPtr->nsPtr);
  3104   3192   
  3105   3193       /*
  3106   3194        * If the command being deleted has a compile function, increment the
  3107   3195        * interpreter's compileEpoch to invalidate its compiled code. This makes
  3108   3196        * sure that we don't later try to execute old code compiled with
  3109   3197        * command-specific (i.e., inline) bytecodes for the now-deleted command.
  3110   3198        * This field is checked in Tcl_EvalObj and ObjInterpProc, and code whose
................................................................................
  3434   3522    *	an instruction specific to the replaced function. In addition,
  3435   3523    *	redefioning a non-builtin function will force existing code to be
  3436   3524    *	invalidated if the number of arguments has changed.
  3437   3525    *
  3438   3526    *----------------------------------------------------------------------
  3439   3527    */
  3440   3528   
         3529  +#if !defined(TCL_NO_DEPRECATED)
  3441   3530   void
  3442   3531   Tcl_CreateMathFunc(
  3443   3532       Tcl_Interp *interp,		/* Interpreter in which function is to be
  3444   3533   				 * available. */
  3445   3534       const char *name,		/* Name of function (e.g. "sin"). */
  3446   3535       int numArgs,		/* Nnumber of arguments required by
  3447   3536   				 * function. */
................................................................................
  3484   3573    *	Whatever the math function does.
  3485   3574    *
  3486   3575    *----------------------------------------------------------------------
  3487   3576    */
  3488   3577   
  3489   3578   static int
  3490   3579   OldMathFuncProc(
  3491         -    ClientData clientData,	/* Ponter to OldMathFuncData describing the
         3580  +    ClientData clientData,	/* Pointer to OldMathFuncData describing the
  3492   3581   				 * function being called */
  3493   3582       Tcl_Interp *interp,		/* Tcl interpreter */
  3494   3583       int objc,			/* Actual parameter count */
  3495   3584       Tcl_Obj *const *objv)	/* Parameter vector */
  3496   3585   {
  3497   3586       Tcl_Obj *valuePtr;
  3498   3587       OldMathFuncData *dataPtr = clientData;
................................................................................
  3549   3638   	switch (args[k].type) {
  3550   3639   	case TCL_EITHER:
  3551   3640   	    if (Tcl_GetLongFromObj(NULL, valuePtr, &args[k].intValue)
  3552   3641   		    == TCL_OK) {
  3553   3642   		args[k].type = TCL_INT;
  3554   3643   		break;
  3555   3644   	    }
  3556         -	    if (Tcl_GetWideIntFromObj(interp, valuePtr, &args[k].wideValue)
         3645  +	    if (TclGetWideIntFromObj(interp, valuePtr, &args[k].wideValue)
  3557   3646   		    == TCL_OK) {
  3558   3647   		args[k].type = TCL_WIDE_INT;
  3559   3648   		break;
  3560   3649   	    }
  3561   3650   	    args[k].type = TCL_DOUBLE;
  3562   3651   	    /* FALLTHROUGH */
  3563   3652   
................................................................................
  3575   3664   	    break;
  3576   3665   	case TCL_WIDE_INT:
  3577   3666   	    if (ExprWideFunc(NULL, interp, 2, &objv[j-1]) != TCL_OK) {
  3578   3667   		ckfree(args);
  3579   3668   		return TCL_ERROR;
  3580   3669   	    }
  3581   3670   	    valuePtr = Tcl_GetObjResult(interp);
  3582         -	    Tcl_GetWideIntFromObj(NULL, valuePtr, &args[k].wideValue);
         3671  +	    TclGetWideIntFromObj(NULL, valuePtr, &args[k].wideValue);
  3583   3672   	    Tcl_ResetResult(interp);
  3584   3673   	    break;
  3585   3674   	}
  3586   3675       }
  3587   3676   
  3588   3677       /*
  3589   3678        * Call the function.
................................................................................
  3597   3686       }
  3598   3687   
  3599   3688       /*
  3600   3689        * Return the result of the call.
  3601   3690        */
  3602   3691   
  3603   3692       if (funcResult.type == TCL_INT) {
  3604         -	TclNewLongObj(valuePtr, funcResult.intValue);
         3693  +	TclNewIntObj(valuePtr, funcResult.intValue);
  3605   3694       } else if (funcResult.type == TCL_WIDE_INT) {
  3606   3695   	valuePtr = Tcl_NewWideIntObj(funcResult.wideValue);
  3607   3696       } else {
  3608   3697   	return CheckDoubleResult(interp, funcResult.doubleValue);
  3609   3698       }
  3610   3699       Tcl_SetObjResult(interp, valuePtr);
  3611   3700       return TCL_OK;
................................................................................
  3765   3854   	result = Tcl_NewObj();
  3766   3855       }
  3767   3856       Tcl_DecrRefCount(script);
  3768   3857       Tcl_RestoreInterpState(interp, state);
  3769   3858   
  3770   3859       return result;
  3771   3860   }
         3861  +#endif /* !defined(TCL_NO_DEPRECATED) */
  3772   3862   
  3773   3863   /*
  3774   3864    *----------------------------------------------------------------------
  3775   3865    *
  3776   3866    * TclInterpReady --
  3777   3867    *
  3778   3868    *	Check if an interpreter is ready to eval commands or scripts, i.e., if
................................................................................
  4372   4462   TclNRRunCallbacks(
  4373   4463       Tcl_Interp *interp,
  4374   4464       int result,
  4375   4465       struct NRE_callback *rootPtr)
  4376   4466   				/* All callbacks down to rootPtr not inclusive
  4377   4467   				 * are to be run. */
  4378   4468   {
         4469  +#if !defined(TCL_NO_DEPRECATED) && TCL_MAJOR_VERSION < 9
  4379   4470       Interp *iPtr = (Interp *) interp;
         4471  +#endif /* !defined(TCL_NO_DEPRECATED) */
  4380   4472       NRE_callback *callbackPtr;
  4381   4473       Tcl_NRPostProc *procPtr;
  4382   4474   
  4383   4475       /*
  4384   4476        * If the interpreter has a non-empty string result, the result object is
  4385   4477        * either empty or stale because some function set interp->result
  4386   4478        * directly. If so, move the string result to the result object, then
  4387   4479        * reset the string result.
  4388   4480        *
  4389   4481        * This only needs to be done for the first item in the list: all other
  4390   4482        * are for NR function calls, and those are Tcl_Obj based.
  4391   4483        */
  4392   4484   
         4485  +#if !defined(TCL_NO_DEPRECATED) && TCL_MAJOR_VERSION < 9
  4393   4486       if (*(iPtr->result) != 0) {
  4394   4487   	(void) Tcl_GetObjResult(interp);
  4395   4488       }
         4489  +#endif /* !defined(TCL_NO_DEPRECATED) */
         4490  +
         4491  +    /* This is the trampoline. */
  4396   4492   
  4397   4493       while (TOP_CB(interp) != rootPtr) {
  4398   4494   	callbackPtr = TOP_CB(interp);
  4399   4495   	procPtr = callbackPtr->procPtr;
  4400   4496   	TOP_CB(interp) = callbackPtr->nextPtr;
  4401   4497   	result = procPtr(callbackPtr->data, interp, result);
  4402   4498   	TCLNR_FREE(interp, callbackPtr);
................................................................................
  4523   4619       Interp *iPtr = (Interp *) interp;
  4524   4620       int allowExceptions = (PTR2INT(data[0]) & TCL_ALLOW_EXCEPTIONS);
  4525   4621   
  4526   4622       if (result != TCL_OK) {
  4527   4623   	if (result == TCL_RETURN) {
  4528   4624   	    result = TclUpdateReturnInfo(iPtr);
  4529   4625   	}
  4530         -	if ((result != TCL_ERROR) && !allowExceptions) {
         4626  +	if ((result != TCL_OK) && (result != TCL_ERROR) && !allowExceptions) {
  4531   4627   	    ProcessUnexpectedResult(interp, result);
  4532   4628   	    result = TCL_ERROR;
  4533   4629   	}
  4534   4630       }
  4535   4631   
  4536   4632       /*
  4537   4633        * We are returning to level 0, so should process TclResetCancellation. As
................................................................................
  4704   4800       Command **cmdPtrPtr,
  4705   4801       Tcl_Obj *commandPtr,
  4706   4802       int objc,
  4707   4803       Tcl_Obj *const objv[])
  4708   4804   {
  4709   4805       Interp *iPtr = (Interp *) interp;
  4710   4806       Command *cmdPtr = *cmdPtrPtr;
  4711         -    size_t newEpoch, cmdEpoch = cmdPtr->cmdEpoch;
         4807  +    unsigned int newEpoch, cmdEpoch = cmdPtr->cmdEpoch;
  4712   4808       int length, traceCode = TCL_OK;
  4713   4809       const char *command = TclGetStringFromObj(commandPtr, &length);
  4714   4810   
  4715   4811       /*
  4716   4812        * Call trace functions.
  4717   4813        * Execute any command or execution traces. Note that we bump up the
  4718   4814        * command's reference count for the duration of the calling of the
................................................................................
  4847   4943       int count)			/* Number of tokens to consider at tokenPtr.
  4848   4944   				 * Must be at least 1. */
  4849   4945   {
  4850   4946       return TclSubstTokens(interp, tokenPtr, count, /* numLeftPtr */ NULL, 1,
  4851   4947   	    NULL, NULL);
  4852   4948   }
  4853   4949   
         4950  +#if !defined(TCL_NO_DEPRECATED) && TCL_MAJOR_VERSION < 9
  4854   4951   /*
  4855   4952    *----------------------------------------------------------------------
  4856   4953    *
  4857   4954    * Tcl_EvalTokens --
  4858   4955    *
  4859   4956    *	Given an array of tokens parsed from a Tcl command (e.g., the tokens
  4860   4957    *	that make up a word or the index for an array variable) this function
................................................................................
  4894   4991   	return NULL;
  4895   4992       }
  4896   4993       resPtr = Tcl_GetObjResult(interp);
  4897   4994       Tcl_IncrRefCount(resPtr);
  4898   4995       Tcl_ResetResult(interp);
  4899   4996       return resPtr;
  4900   4997   }
         4998  +#endif /* !TCL_NO_DEPRECATED */
  4901   4999   
  4902   5000   /*
  4903   5001    *----------------------------------------------------------------------
  4904   5002    *
  4905   5003    * Tcl_EvalEx, TclEvalEx --
  4906   5004    *
  4907   5005    *	This function evaluates a Tcl script without using the compiler or
................................................................................
  5849   5947    *
  5850   5948    * Side effects:
  5851   5949    *	Can be almost arbitrary, depending on the commands in the script.
  5852   5950    *
  5853   5951    *----------------------------------------------------------------------
  5854   5952    */
  5855   5953   
         5954  +#ifndef TCL_NO_DEPRECATED
  5856   5955   #undef Tcl_Eval
  5857   5956   int
  5858   5957   Tcl_Eval(
  5859   5958       Tcl_Interp *interp,		/* Token for command interpreter (returned by
  5860   5959   				 * previous call to Tcl_CreateInterp). */
  5861   5960       const char *script)		/* Pointer to TCL command to execute. */
  5862   5961   {
................................................................................
  5901   6000   int
  5902   6001   Tcl_GlobalEvalObj(
  5903   6002       Tcl_Interp *interp,
  5904   6003       Tcl_Obj *objPtr)
  5905   6004   {
  5906   6005       return Tcl_EvalObjEx(interp, objPtr, TCL_EVAL_GLOBAL);
  5907   6006   }
         6007  +#endif /* TCL_NO_DEPRECATED */
  5908   6008   
  5909   6009   /*
  5910   6010    *----------------------------------------------------------------------
  5911   6011    *
  5912   6012    * Tcl_EvalObjEx, TclEvalObjEx --
  5913   6013    *
  5914   6014    *	Execute Tcl commands stored in a Tcl object. These commands are
................................................................................
  6410   6510   	Tcl_DecrRefCount(resultPtr);
  6411   6511   	if (Tcl_InitBignumFromDouble(interp, d, &big) != TCL_OK) {
  6412   6512   	    return TCL_ERROR;
  6413   6513   	}
  6414   6514   	resultPtr = Tcl_NewBignumObj(&big);
  6415   6515   	/* FALLTHROUGH */
  6416   6516       }
  6417         -    case TCL_NUMBER_LONG:
  6418   6517       case TCL_NUMBER_WIDE:
  6419   6518       case TCL_NUMBER_BIG:
  6420   6519   	result = TclGetLongFromObj(interp, resultPtr, ptr);
  6421   6520   	break;
  6422   6521   
  6423   6522       case TCL_NUMBER_NAN:
  6424   6523   	Tcl_GetDoubleFromObj(interp, resultPtr, &d);
................................................................................
  6727   6826    *	The contents of message are appended to the errorInfo field. If we are
  6728   6827    *	just starting to log an error, errorInfo is initialized from the error
  6729   6828    *	message in the interpreter's result.
  6730   6829    *
  6731   6830    *----------------------------------------------------------------------
  6732   6831    */
  6733   6832   
         6833  +#ifndef TCL_NO_DEPRECATED
  6734   6834   #undef Tcl_AddErrorInfo
  6735   6835   void
  6736   6836   Tcl_AddErrorInfo(
  6737   6837       Tcl_Interp *interp,		/* Interpreter to which error information
  6738   6838   				 * pertains. */
  6739   6839       const char *message)	/* Message to record. */
  6740   6840   {
  6741   6841       Tcl_AddObjErrorInfo(interp, message, -1);
  6742   6842   }
         6843  +#endif /* TCL_NO_DEPRECATED */
  6743   6844   
  6744   6845   /*
  6745   6846    *----------------------------------------------------------------------
  6746   6847    *
  6747   6848    * Tcl_AddObjErrorInfo --
  6748   6849    *
  6749   6850    *	Add information to the errorInfo field that describes the current
................................................................................
  6776   6877       /*
  6777   6878        * If we are just starting to log an error, errorInfo is initialized from
  6778   6879        * the error message in the interpreter's result.
  6779   6880        */
  6780   6881   
  6781   6882       iPtr->flags |= ERR_LEGACY_COPY;
  6782   6883       if (iPtr->errorInfo == NULL) {
  6783         -	if (iPtr->result[0] != 0) {
         6884  +#if !defined(TCL_NO_DEPRECATED) && TCL_MAJOR_VERSION < 9
         6885  +	if (*(iPtr->result) != 0) {
  6784   6886   	    /*
  6785   6887   	     * The interp's string result is set, apparently by some extension
  6786   6888   	     * making a deprecated direct write to it. That extension may
  6787   6889   	     * expect interp->result to continue to be set, so we'll take
  6788   6890   	     * special pains to avoid clearing it, until we drop support for
  6789   6891   	     * interp->result completely.
  6790   6892   	     */
  6791   6893   
  6792   6894   	    iPtr->errorInfo = Tcl_NewStringObj(iPtr->result, -1);
  6793         -	} else {
         6895  +	} else
         6896  +#endif /* !defined(TCL_NO_DEPRECATED) */
  6794   6897   	    iPtr->errorInfo = iPtr->objResultPtr;
  6795         -	}
  6796   6898   	Tcl_IncrRefCount(iPtr->errorInfo);
  6797   6899   	if (!iPtr->errorCode) {
  6798   6900   	    Tcl_SetErrorCode(interp, "NONE", NULL);
  6799   6901   	}
  6800   6902       }
  6801   6903   
  6802   6904       /*
................................................................................
  6908   7010    *	The command string is executed in interp, and the execution is carried
  6909   7011    *	out in the variable context of global level (no functions active),
  6910   7012    *	just as if an "uplevel #0" command were being executed.
  6911   7013    *
  6912   7014    *----------------------------------------------------------------------
  6913   7015    */
  6914   7016   
         7017  +#ifndef TCL_NO_DEPRECATED
  6915   7018   #undef Tcl_GlobalEval
  6916   7019   int
  6917   7020   Tcl_GlobalEval(
  6918   7021       Tcl_Interp *interp,		/* Interpreter in which to evaluate
  6919   7022   				 * command. */
  6920   7023       const char *command)	/* Command to evaluate. */
  6921   7024   {
................................................................................
  6925   7028   
  6926   7029       savedVarFramePtr = iPtr->varFramePtr;
  6927   7030       iPtr->varFramePtr = iPtr->rootFramePtr;
  6928   7031       result = Tcl_EvalEx(interp, command, -1, 0);
  6929   7032       iPtr->varFramePtr = savedVarFramePtr;
  6930   7033       return result;
  6931   7034   }
         7035  +#endif /* TCL_NO_DEPRECATED */
  6932   7036   
  6933   7037   /*
  6934   7038    *----------------------------------------------------------------------
  6935   7039    *
  6936   7040    * Tcl_SetRecursionLimit --
  6937   7041    *
  6938   7042    *	Set the maximum number of recursive calls that may be active for an
................................................................................
  7178   7282   	}
  7179   7283   	if (SIGN(&big) == MP_NEG) {
  7180   7284   	    mp_clear(&big);
  7181   7285   	    goto negarg;
  7182   7286   	}
  7183   7287   	break;
  7184   7288       default:
  7185         -	if (Tcl_GetWideIntFromObj(interp, objv[1], &w) != TCL_OK) {
         7289  +	if (TclGetWideIntFromObj(interp, objv[1], &w) != TCL_OK) {
  7186   7290   	    return TCL_ERROR;
  7187   7291   	}
  7188   7292   	if (w < 0) {
  7189   7293   	    goto negarg;
  7190   7294   	}
  7191   7295   	d = (double) w;
  7192   7296   #ifdef IEEE_FLOATING_POINT
................................................................................
  7382   7486   	return TCL_ERROR;
  7383   7487       }
  7384   7488   
  7385   7489       if (TclGetNumberFromObj(interp, objv[1], &ptr, &type) != TCL_OK) {
  7386   7490   	return TCL_ERROR;
  7387   7491       }
  7388   7492   
  7389         -    if (type == TCL_NUMBER_LONG) {
  7390         -	long l = *((const long *) ptr);
         7493  +    if (type == TCL_NUMBER_WIDE) {
         7494  +	Tcl_WideInt l = *((const Tcl_WideInt *) ptr);
  7391   7495   
  7392         -	if (l > (long)0) {
         7496  +	if (l > (Tcl_WideInt)0) {
  7393   7497   	    goto unChanged;
  7394         -	} else if (l == (long)0) {
         7498  +	} else if (l == (Tcl_WideInt)0) {
  7395   7499   	    const char *string = objv[1]->bytes;
  7396   7500   	    if (string) {
  7397   7501   		while (*string != '0') {
  7398   7502   		    if (*string == '-') {
  7399   7503   			Tcl_SetObjResult(interp, Tcl_NewLongObj(0));
  7400   7504   			return TCL_OK;
  7401   7505   		    }
  7402   7506   		    string++;
  7403   7507   		}
  7404   7508   	    }
  7405   7509   	    goto unChanged;
  7406         -	} else if (l == LONG_MIN) {
  7407         -	    TclBNInitBignumFromLong(&big, l);
         7510  +	} else if (l == LLONG_MIN) {
         7511  +	    TclInitBignumFromWideInt(&big, l);
  7408   7512   	    goto tooLarge;
  7409   7513   	}
  7410         -	Tcl_SetObjResult(interp, Tcl_NewLongObj(-l));
         7514  +	Tcl_SetObjResult(interp, Tcl_NewWideIntObj(-l));
  7411   7515   	return TCL_OK;
  7412   7516       }
  7413   7517   
  7414   7518       if (type == TCL_NUMBER_DOUBLE) {
  7415   7519   	double d = *((const double *) ptr);
  7416   7520   	static const double poszero = 0.0;
  7417   7521   
................................................................................
  7427   7531   	} else if (d > -0.0) {
  7428   7532   	    goto unChanged;
  7429   7533   	}
  7430   7534   	Tcl_SetObjResult(interp, Tcl_NewDoubleObj(-d));
  7431   7535   	return TCL_OK;
  7432   7536       }
  7433   7537   
  7434         -#ifndef TCL_WIDE_INT_IS_LONG
  7435         -    if (type == TCL_NUMBER_WIDE) {
  7436         -	Tcl_WideInt w = *((const Tcl_WideInt *) ptr);
  7437         -
  7438         -	if (w >= (Tcl_WideInt)0) {
  7439         -	    goto unChanged;
  7440         -	}
  7441         -	if (w == LLONG_MIN) {
  7442         -	    TclBNInitBignumFromWideInt(&big, w);
  7443         -	    goto tooLarge;
  7444         -	}
  7445         -	Tcl_SetObjResult(interp, Tcl_NewWideIntObj(-w));
  7446         -	return TCL_OK;
  7447         -    }
  7448         -#endif
  7449         -
  7450   7538       if (type == TCL_NUMBER_BIG) {
  7451         -	if (mp_cmp_d((const mp_int *) ptr, 0) == MP_LT) {
         7539  +	if (mp_isneg((const mp_int *) ptr)) {
  7452   7540   	    Tcl_GetBignumFromObj(NULL, objv[1], &big);
  7453   7541   	tooLarge:
  7454   7542   	    mp_neg(&big, &big);
  7455   7543   	    Tcl_SetObjResult(interp, Tcl_NewBignumObj(&big));
  7456   7544   	} else {
  7457   7545   	unChanged:
  7458   7546   	    Tcl_SetObjResult(interp, objv[1]);
................................................................................
  7621   7709       Tcl_WideInt wResult;
  7622   7710       Tcl_Obj *objPtr;
  7623   7711   
  7624   7712       if (ExprEntierFunc(NULL, interp, objc, objv) != TCL_OK) {
  7625   7713   	return TCL_ERROR;
  7626   7714       }
  7627   7715       objPtr = Tcl_GetObjResult(interp);
  7628         -    if (Tcl_GetWideIntFromObj(NULL, objPtr, &wResult) != TCL_OK) {
         7716  +    if (TclGetWideIntFromObj(NULL, objPtr, &wResult) != TCL_OK) {
  7629   7717   	/*
  7630   7718   	 * Truncate the bignum; keep only bits in wide int range.
  7631   7719   	 */
  7632   7720   
  7633   7721   	mp_int big;
  7634   7722   
  7635   7723   	Tcl_GetBignumFromObj(NULL, objPtr, &big);
  7636   7724   	mp_mod_2d(&big, (int) CHAR_BIT * sizeof(Tcl_WideInt), &big);
  7637   7725   	objPtr = Tcl_NewBignumObj(&big);
  7638   7726   	Tcl_IncrRefCount(objPtr);
  7639         -	Tcl_GetWideIntFromObj(NULL, objPtr, &wResult);
         7727  +	TclGetWideIntFromObj(NULL, objPtr, &wResult);
  7640   7728   	Tcl_DecrRefCount(objPtr);
  7641   7729       }
  7642   7730       Tcl_SetObjResult(interp, Tcl_NewWideIntObj(wResult));
  7643   7731       return TCL_OK;
  7644   7732   }
         7733  +
         7734  +/*
         7735  + * Common implmentation of max() and min().
         7736  + */
         7737  +static int
         7738  +ExprMaxMinFunc(
         7739  +    ClientData clientData,	/* Ignored. */
         7740  +    Tcl_Interp *interp,		/* The interpreter in which to execute the
         7741  +				 * function. */
         7742  +    int objc,			/* Actual parameter count. */
         7743  +    Tcl_Obj *const *objv,	/* Actual parameter vector. */
         7744  +    int op)			/* Comparison direction */
         7745  +{
         7746  +    Tcl_Obj *res;
         7747  +    double d;
         7748  +    int type, i;
         7749  +    ClientData ptr;
         7750  +
         7751  +    if (objc < 2) {
         7752  +	MathFuncWrongNumArgs(interp, 2, objc, objv);
         7753  +	return TCL_ERROR;
         7754  +    }
         7755  +    res = objv[1];
         7756  +    for (i = 1; i < objc; i++) {
         7757  +        if (TclGetNumberFromObj(interp, objv[i], &ptr, &type) != TCL_OK) {
         7758  +            return TCL_ERROR;
         7759  +        }
         7760  +        if (type == TCL_NUMBER_NAN) {
         7761  +            /*
         7762  +             * Get the error message for NaN.
         7763  +             */
         7764  +
         7765  +            Tcl_GetDoubleFromObj(interp, objv[i], &d);
         7766  +            return TCL_ERROR;
         7767  +        }
         7768  +        if (TclCompareTwoNumbers(objv[i], res) == op)  {
         7769  +            res = objv[i];
         7770  +        }
         7771  +    }
         7772  +
         7773  +    Tcl_SetObjResult(interp, res);
         7774  +    return TCL_OK;
         7775  +}
         7776  +
         7777  +static int
         7778  +ExprMaxFunc(
         7779  +    ClientData clientData,	/* Ignored. */
         7780  +    Tcl_Interp *interp,		/* The interpreter in which to execute the
         7781  +				 * function. */
         7782  +    int objc,			/* Actual parameter count. */
         7783  +    Tcl_Obj *const *objv)	/* Actual parameter vector. */
         7784  +{
         7785  +    return ExprMaxMinFunc(clientData, interp, objc, objv, MP_GT);
         7786  +}
         7787  +
         7788  +static int
         7789  +ExprMinFunc(
         7790  +    ClientData clientData,	/* Ignored. */
         7791  +    Tcl_Interp *interp,		/* The interpreter in which to execute the
         7792  +				 * function. */
         7793  +    int objc,			/* Actual parameter count. */
         7794  +    Tcl_Obj *const *objv)	/* Actual parameter vector. */
         7795  +{
         7796  +    return ExprMaxMinFunc(clientData, interp, objc, objv, MP_LT);
         7797  +}
  7645   7798   
  7646   7799   static int
  7647   7800   ExprRandFunc(
  7648   7801       ClientData clientData,	/* Ignored. */
  7649   7802       Tcl_Interp *interp,		/* The interpreter in which to execute the
  7650   7803   				 * function. */
  7651   7804       int objc,			/* Actual parameter count. */
................................................................................
  7662   7815   	return TCL_ERROR;
  7663   7816       }
  7664   7817   
  7665   7818       if (!(iPtr->flags & RAND_SEED_INITIALIZED)) {
  7666   7819   	iPtr->flags |= RAND_SEED_INITIALIZED;
  7667   7820   
  7668   7821   	/*
  7669         -	 * Take into consideration the thread this interp is running in order
  7670         -	 * to insure different seeds in different threads (bug #416643)
         7822  +	 * To ensure different seeds in different threads (bug #416643),
         7823  +	 * take into consideration the thread this interp is running in.
  7671   7824   	 */
  7672   7825   
  7673   7826   	iPtr->randSeed = TclpGetClicks() + (PTR2INT(Tcl_GetCurrentThread())<<12);
  7674   7827   
  7675   7828   	/*
  7676   7829   	 * Make sure 1 <= randSeed <= (2^31) - 2. See below.
  7677   7830   	 */
................................................................................
  8124   8277       Tcl_CmdDeleteProc *deleteProc)
  8125   8278   				/* If not NULL, gives a function to call when
  8126   8279   				 * this command is deleted. */
  8127   8280   {
  8128   8281       Command *cmdPtr = (Command *)
  8129   8282   	    Tcl_CreateObjCommand(interp,cmdName,proc,clientData,deleteProc);
  8130   8283   
         8284  +    cmdPtr->nreProc = nreProc;
         8285  +    return (Tcl_Command) cmdPtr;
         8286  +}
         8287  +
         8288  +Tcl_Command
         8289  +TclNRCreateCommandInNs (
         8290  +    Tcl_Interp *interp,
         8291  +    const char *cmdName,
         8292  +    Tcl_Namespace *nsPtr,
         8293  +    Tcl_ObjCmdProc *proc,
         8294  +    Tcl_ObjCmdProc *nreProc,
         8295  +    ClientData clientData,
         8296  +    Tcl_CmdDeleteProc *deleteProc) {
         8297  +    Command *cmdPtr = (Command *)
         8298  +	TclCreateObjCommandInNs(interp,cmdName,nsPtr,proc,clientData,deleteProc);
         8299  +
  8131   8300       cmdPtr->nreProc = nreProc;
  8132   8301       return (Tcl_Command) cmdPtr;
  8133   8302   }
  8134   8303   
  8135   8304   /****************************************************************************
  8136   8305    * Stuff for the public api
  8137   8306    ****************************************************************************/
................................................................................
  8752   8921   
  8753   8922       return TCL_OK;
  8754   8923   }
  8755   8924   
  8756   8925   /*
  8757   8926    *----------------------------------------------------------------------
  8758   8927    *
         8928  + * TclNREvalList --
         8929  + *
         8930  + *      Callback to invoke command as list, used in order to delayed
         8931  + *	processing of canonical list command in sane environment.
         8932  + *
         8933  + *----------------------------------------------------------------------
         8934  + */
         8935  +
         8936  +static int
         8937  +TclNREvalList(
         8938  +    ClientData data[],
         8939  +    Tcl_Interp *interp,
         8940  +    int result)
         8941  +{
         8942  +    int objc;
         8943  +    Tcl_Obj **objv;
         8944  +    Tcl_Obj *listPtr = data[0];
         8945  +
         8946  +    Tcl_IncrRefCount(listPtr);
         8947  +
         8948  +    TclMarkTailcall(interp);
         8949  +    TclNRAddCallback(interp, TclNRReleaseValues, listPtr, NULL, NULL,NULL);
         8950  +    TclListObjGetElements(NULL, listPtr, &objc, &objv);
         8951  +    return TclNREvalObjv(interp, objc, objv, 0, NULL);
         8952  +}
         8953  +
         8954  +/*
         8955  + *----------------------------------------------------------------------
         8956  + *
  8759   8957    * NRCoroInjectObjCmd --
  8760   8958    *
  8761   8959    *      Implementation of [::tcl::unsupported::inject] command.
  8762   8960    *
  8763   8961    *----------------------------------------------------------------------
  8764   8962    */
  8765   8963   
................................................................................
  8803   9001   
  8804   9002       /*
  8805   9003        * Add the callback to the coro's execEnv, so that it is the first thing
  8806   9004        * to happen when the coro is resumed.
  8807   9005        */
  8808   9006   
  8809   9007       iPtr->execEnvPtr = corPtr->eePtr;
  8810         -    TclNREvalObjEx(interp, Tcl_NewListObj(objc-2, objv+2), 0, NULL, INT_MIN);
         9008  +    TclNRAddCallback(interp, TclNREvalList, Tcl_NewListObj(objc-2, objv+2),
         9009  +	NULL, NULL, NULL);
  8811   9010       iPtr->execEnvPtr = savedEEPtr;
  8812   9011   
  8813   9012       return TCL_OK;
  8814   9013   }
  8815   9014   
  8816   9015   int
  8817   9016   TclNRInterpCoroutine(
................................................................................
  8882   9081       ClientData dummy,		/* Not used. */
  8883   9082       Tcl_Interp *interp,		/* Current interpreter. */
  8884   9083       int objc,			/* Number of arguments. */
  8885   9084       Tcl_Obj *const objv[])	/* Argument objects. */
  8886   9085   {
  8887   9086       Command *cmdPtr;
  8888   9087       CoroutineData *corPtr;
  8889         -    const char *fullName, *procName;
  8890         -    Namespace *nsPtr, *altNsPtr, *cxtNsPtr;
  8891         -    Tcl_DString ds;
         9088  +    const char *procName, *simpleName;
         9089  +    Namespace *nsPtr, *altNsPtr, *cxtNsPtr,
         9090  +	*inNsPtr = (Namespace *)TclGetCurrentNamespace(interp);
  8892   9091       Namespace *lookupNsPtr = iPtr->varFramePtr->nsPtr;
  8893   9092   
  8894   9093       if (objc < 3) {
  8895   9094   	Tcl_WrongNumArgs(interp, 1, objv, "name cmd ?arg ...?");
  8896   9095   	return TCL_ERROR;
  8897   9096       }
  8898   9097   
  8899         -    /*
  8900         -     * FIXME: this is copy/pasted from Tcl_ProcObjCommand. Should have
  8901         -     * something in tclUtil.c to find the FQ name.
  8902         -     */
  8903         -
  8904         -    fullName = TclGetString(objv[1]);
  8905         -    TclGetNamespaceForQualName(interp, fullName, NULL, 0,
  8906         -	    &nsPtr, &altNsPtr, &cxtNsPtr, &procName);
         9098  +    procName = TclGetString(objv[1]);
         9099  +    TclGetNamespaceForQualName(interp, procName, inNsPtr, 0,
         9100  +	    &nsPtr, &altNsPtr, &cxtNsPtr, &simpleName);
  8907   9101   
  8908   9102       if (nsPtr == NULL) {
  8909   9103   	Tcl_SetObjResult(interp, Tcl_ObjPrintf(
  8910   9104                   "can't create procedure \"%s\": unknown namespace",
  8911         -                fullName));
         9105  +                procName));
  8912   9106           Tcl_SetErrorCode(interp, "TCL", "LOOKUP", "NAMESPACE", NULL);
  8913   9107   	return TCL_ERROR;
  8914   9108       }
  8915         -    if (procName == NULL) {
         9109  +    if (simpleName == NULL) {
  8916   9110   	Tcl_SetObjResult(interp, Tcl_ObjPrintf(
  8917   9111                   "can't create procedure \"%s\": bad procedure name",
  8918         -                fullName));
  8919         -        Tcl_SetErrorCode(interp, "TCL", "VALUE", "COMMAND", fullName, NULL);
  8920         -	return TCL_ERROR;
  8921         -    }
  8922         -    if ((nsPtr != iPtr->globalNsPtr)
  8923         -	    && (procName != NULL) && (procName[0] == ':')) {
  8924         -	Tcl_SetObjResult(interp, Tcl_ObjPrintf(
  8925         -                "can't create procedure \"%s\" in non-global namespace with"
  8926         -                " name starting with \":\"", procName));
         9112  +                procName));
  8927   9113           Tcl_SetErrorCode(interp, "TCL", "VALUE", "COMMAND", procName, NULL);
  8928   9114   	return TCL_ERROR;
  8929   9115       }
  8930   9116   
  8931   9117       /*
  8932   9118        * We ARE creating the coroutine command: allocate the corresponding
  8933   9119        * struct and create the corresponding command.
  8934   9120        */
  8935   9121   
  8936   9122       corPtr = ckalloc(sizeof(CoroutineData));
  8937   9123   
  8938         -    Tcl_DStringInit(&ds);
  8939         -    if (nsPtr != iPtr->globalNsPtr) {
  8940         -	Tcl_DStringAppend(&ds, nsPtr->fullName, -1);
  8941         -	TclDStringAppendLiteral(&ds, "::");
  8942         -    }
  8943         -    Tcl_DStringAppend(&ds, procName, -1);
  8944         -
  8945         -    cmdPtr = (Command *) Tcl_NRCreateCommand(interp, Tcl_DStringValue(&ds),
  8946         -	    /*objProc*/ NULL, TclNRInterpCoroutine, corPtr, DeleteCoroutine);
  8947         -    Tcl_DStringFree(&ds);
         9124  +    cmdPtr = (Command *) TclNRCreateCommandInNs(interp, simpleName,
         9125  +	    (Tcl_Namespace *)nsPtr, /*objProc*/ NULL, TclNRInterpCoroutine,
         9126  +	    corPtr, DeleteCoroutine);
  8948   9127   
  8949   9128       corPtr->cmdPtr = cmdPtr;
  8950   9129       cmdPtr->refCount++;
  8951   9130   
  8952   9131       /*
  8953   9132        * #280.
  8954   9133        * Provide the new coroutine with its own copy of the lineLABCPtr
................................................................................
  9001   9180       corPtr->callerEEPtr = iPtr->execEnvPtr;
  9002   9181       RESTORE_CONTEXT(corPtr->running);
  9003   9182       iPtr->execEnvPtr = corPtr->eePtr;
  9004   9183   
  9005   9184       TclNRAddCallback(interp, NRCoroutineExitCallback, corPtr,
  9006   9185   	    NULL, NULL, NULL);
  9007   9186   
  9008         -    /* insure that the command is looked up in the correct namespace */
         9187  +    /* ensure that the command is looked up in the correct namespace */
  9009   9188       iPtr->lookupNsPtr = lookupNsPtr;
  9010   9189       Tcl_NREvalObj(interp, Tcl_NewListObj(objc-2, objv+2), 0);
  9011   9190       iPtr->numLevels--;
  9012   9191   
  9013   9192       SAVE_CONTEXT(corPtr->running);
  9014   9193       RESTORE_CONTEXT(corPtr->caller);
  9015   9194       iPtr->execEnvPtr = corPtr->callerEEPtr;

Changes to generic/tclBinary.c.

   532    532       Tcl_Obj *objPtr)		/* The object to convert to type ByteArray. */
   533    533   {
   534    534       size_t length;
   535    535       int improper = 0;
   536    536       const char *src, *srcEnd;
   537    537       unsigned char *dst;
   538    538       ByteArray *byteArrayPtr;
   539         -    Tcl_UniChar ch;
          539  +    Tcl_UniChar ch = 0;
   540    540   
   541    541       if (objPtr->typePtr == &properByteArrayType) {
   542    542   	return TCL_OK;
   543    543       }
   544    544       if (objPtr->typePtr == &tclByteArrayType) {
   545    545   	return TCL_OK;
   546    546       }
................................................................................
   547    547   
   548    548       src = TclGetString(objPtr);
   549    549       length = objPtr->length;
   550    550       srcEnd = src + length;
   551    551   
   552    552       byteArrayPtr = ckalloc(BYTEARRAY_SIZE(length));
   553    553       for (dst = byteArrayPtr->bytes; src < srcEnd; ) {
   554         -	src += Tcl_UtfToUniChar(src, &ch);
          554  +	src += TclUtfToUniChar(src, &ch);
   555    555   	improper = improper || (ch > 255);
   556    556   	*dst++ = UCHAR(ch);
   557    557       }
   558    558   
   559    559       byteArrayPtr->used = dst - byteArrayPtr->bytes;
   560    560       byteArrayPtr->allocated = length;
   561    561   
................................................................................
  1296   1296   
  1297   1297    badIndex:
  1298   1298       errorString = "not enough arguments for all format specifiers";
  1299   1299       goto error;
  1300   1300   
  1301   1301    badField:
  1302   1302       {
  1303         -	Tcl_UniChar ch;
         1303  +	Tcl_UniChar ch = 0;
  1304   1304   	char buf[TCL_UTF_MAX + 1];
  1305   1305   
  1306         -	Tcl_UtfToUniChar(errorString, &ch);
         1306  +	TclUtfToUniChar(errorString, &ch);
  1307   1307   	buf[Tcl_UniCharToUtf(ch, buf)] = '\0';
  1308   1308   	Tcl_SetObjResult(interp, Tcl_ObjPrintf(
  1309   1309   		"bad field specifier \"%s\"", buf));
  1310   1310   	return TCL_ERROR;
  1311   1311       }
  1312   1312   
  1313   1313    error:
................................................................................
  1666   1666   
  1667   1667    badIndex:
  1668   1668       errorString = "not enough arguments for all format specifiers";
  1669   1669       goto error;
  1670   1670   
  1671   1671    badField:
  1672   1672       {
  1673         -	Tcl_UniChar ch;
         1673  +	Tcl_UniChar ch = 0;
  1674   1674   	char buf[TCL_UTF_MAX + 1];
  1675   1675   
  1676         -	Tcl_UtfToUniChar(errorString, &ch);
         1676  +	TclUtfToUniChar(errorString, &ch);
  1677   1677   	buf[Tcl_UniCharToUtf(ch, buf)] = '\0';
  1678   1678   	Tcl_SetObjResult(interp, Tcl_ObjPrintf(
  1679   1679   		"bad field specifier \"%s\"", buf));
  1680   1680   	return TCL_ERROR;
  1681   1681       }
  1682   1682   
  1683   1683    error:
................................................................................
  1739   1739   	(*formatPtr)++;
  1740   1740   	*flagsPtr |= BINARY_UNSIGNED;
  1741   1741       }
  1742   1742       if (**formatPtr == '*') {
  1743   1743   	(*formatPtr)++;
  1744   1744   	*countPtr = BINARY_ALL;
  1745   1745       } else if (isdigit(UCHAR(**formatPtr))) { /* INTL: digit */
  1746         -	*countPtr = strtoul(*formatPtr, (char **) formatPtr, 10);
         1746  +	unsigned long int count;
         1747  +
         1748  +	errno = 0;
         1749  +	count = strtoul(*formatPtr, (char **) formatPtr, 10);
         1750  +	if (errno || (count > (unsigned long) INT_MAX)) {
         1751  +	    *countPtr = INT_MAX;
         1752  +	} else {
         1753  +	    *countPtr = (int) count;
         1754  +	}
  1747   1755       } else {
  1748   1756   	*countPtr = BINARY_NOCOUNT;
  1749   1757       }
  1750   1758       return 1;
  1751   1759   }
  1752   1760   
  1753   1761   /*
................................................................................
  2272   2280   		    | (((Tcl_WideUInt) buffer[1]) << 48)
  2273   2281   		    | (((Tcl_WideUInt) buffer[0]) << 56);
  2274   2282   	}
  2275   2283   	if (flags & BINARY_UNSIGNED) {
  2276   2284   	    Tcl_Obj *bigObj = NULL;
  2277   2285   	    mp_int big;
  2278   2286   
  2279         -	    TclBNInitBignumFromWideUInt(&big, uwvalue);
         2287  +	    TclInitBignumFromWideUInt(&big, uwvalue);
  2280   2288   	    bigObj = Tcl_NewBignumObj(&big);
  2281   2289   	    return bigObj;
  2282   2290   	}
  2283   2291   	return Tcl_NewWideIntObj((Tcl_WideInt) uwvalue);
  2284   2292   
  2285   2293   	/*
  2286   2294   	 * Do not cache double values; they are already too large to use as

Changes to generic/tclCkalloc.c.

    85     85    * mem_header. It is used to get back to the header pointer from the body
    86     86    * pointer that's used by clients.
    87     87    */
    88     88   
    89     89   #define BODY_OFFSET \
    90     90   	((size_t) (&((struct mem_header *) 0)->body))
    91     91   
    92         -static int total_mallocs = 0;
    93         -static int total_frees = 0;
           92  +static unsigned int total_mallocs = 0;
           93  +static unsigned int total_frees = 0;
    94     94   static size_t current_bytes_malloced = 0;
    95     95   static size_t maximum_bytes_malloced = 0;
    96         -static int current_malloc_packets = 0;
    97         -static int maximum_malloc_packets = 0;
    98         -static int break_on_malloc = 0;
    99         -static int trace_on_at_malloc = 0;
           96  +static unsigned int current_malloc_packets = 0;
           97  +static unsigned int  maximum_malloc_packets = 0;
           98  +static unsigned int break_on_malloc = 0;
           99  +static unsigned int trace_on_at_malloc = 0;
   100    100   static int alloc_tracing = FALSE;
   101    101   static int init_malloced_bodies = TRUE;
   102    102   #ifdef MEM_VALIDATE
   103    103   static int validate_memory = TRUE;
   104    104   #else
   105    105   static int validate_memory = FALSE;
   106    106   #endif
................................................................................
   180    180   {
   181    181       char buf[1024];
   182    182   
   183    183       if (clientData == NULL) {
   184    184           return 0;
   185    185       }
   186    186       sprintf(buf,
   187         -	    "total mallocs             %10d\n"
   188         -	    "total frees               %10d\n"
   189         -	    "current packets allocated %10d\n"
   190         -	    "current bytes allocated   %10lu\n"
   191         -	    "maximum packets allocated %10d\n"
   192         -	    "maximum bytes allocated   %10lu\n",
          187  +	    "total mallocs             %10u\n"
          188  +	    "total frees               %10u\n"
          189  +	    "current packets allocated %10u\n"
          190  +	    "current bytes allocated   %10" TCL_Z_MODIFIER "u\n"
          191  +	    "maximum packets allocated %10u\n"
          192  +	    "maximum bytes allocated   %10" TCL_Z_MODIFIER "u\n",
   193    193   	    total_mallocs,
   194    194   	    total_frees,
   195    195   	    current_malloc_packets,
   196         -	    (unsigned long)current_bytes_malloced,
          196  +	    current_bytes_malloced,
   197    197   	    maximum_malloc_packets,
   198         -	    (unsigned long)maximum_bytes_malloced);
          198  +	    maximum_bytes_malloced);
   199    199       if (flags == 0) {
   200    200   	fprintf((FILE *)clientData, "%s", buf);
   201    201       } else {
   202    202   	/* Assume objPtr to append to */
   203    203   	Tcl_AppendToObj((Tcl_Obj *) clientData, buf, -1);
   204    204       }
   205    205       return 1;
................................................................................
   250    250   	}
   251    251       }
   252    252       if (guard_failed) {
   253    253   	TclDumpMemoryInfo((ClientData) stderr, 0);
   254    254   	fprintf(stderr, "low guard failed at %p, %s %d\n",
   255    255   		memHeaderP->body, file, line);
   256    256   	fflush(stderr);			/* In case name pointer is bad. */
   257         -	fprintf(stderr, "%" TCL_LL_MODIFIER "d bytes allocated at (%s %d)\n", (Tcl_WideInt) memHeaderP->length,
          257  +	fprintf(stderr, "%" TCL_Z_MODIFIER "u bytes allocated at (%s %d)\n", memHeaderP->length,
   258    258   		memHeaderP->file, memHeaderP->line);
   259    259   	Tcl_Panic("Memory validation failure");
   260    260       }
   261    261   
   262    262       hiPtr = (unsigned char *)memHeaderP->body + memHeaderP->length;
   263    263       for (idx = 0; idx < HIGH_GUARD_SIZE; idx++) {
   264    264   	byte = *(hiPtr + idx);
................................................................................
   272    272       }
   273    273   
   274    274       if (guard_failed) {
   275    275   	TclDumpMemoryInfo((ClientData) stderr, 0);
   276    276   	fprintf(stderr, "high guard failed at %p, %s %d\n",
   277    277   		memHeaderP->body, file, line);
   278    278   	fflush(stderr);			/* In case name pointer is bad. */
   279         -	fprintf(stderr, "%" TCL_LL_MODIFIER "d bytes allocated at (%s %d)\n",
   280         -		(Tcl_WideInt)memHeaderP->length, memHeaderP->file,
          279  +	fprintf(stderr, "%" TCL_Z_MODIFIER "u bytes allocated at (%s %d)\n",
          280  +		memHeaderP->length, memHeaderP->file,
   281    281   		memHeaderP->line);
   282    282   	Tcl_Panic("Memory validation failure");
   283    283       }
   284    284   
   285    285       if (nukeGuards) {
   286    286   	memset(memHeaderP->low_guard, 0, LOW_GUARD_SIZE);
   287    287   	memset(hiPtr, 0, HIGH_GUARD_SIZE);
................................................................................
   355    355   	    return TCL_ERROR;
   356    356   	}
   357    357       }
   358    358   
   359    359       Tcl_MutexLock(ckallocMutexPtr);
   360    360       for (memScanP = allocHead; memScanP != NULL; memScanP = memScanP->flink) {
   361    361   	address = &memScanP->body[0];
   362         -	fprintf(fileP, "%8" TCL_LL_MODIFIER "x - %8" TCL_LL_MODIFIER "x  %7" TCL_LL_MODIFIER "d @ %s %d %s",
   363         -		(Tcl_WideInt)(size_t)address,
   364         -		(Tcl_WideInt)((size_t)address + memScanP->length - 1),
   365         -		(Tcl_WideInt)memScanP->length, memScanP->file, memScanP->line,
          362  +	fprintf(fileP, "%p - %p  %" TCL_Z_MODIFIER "u @ %s %d %s",
          363  +		address, address + memScanP->length - 1,
          364  +		memScanP->length, memScanP->file, memScanP->line,
   366    365   		(memScanP->tagPtr == NULL) ? "" : memScanP->tagPtr->string);
   367    366   	(void) fputc('\n', fileP);
   368    367       }
   369    368       Tcl_MutexUnlock(ckallocMutexPtr);
   370    369   
   371    370       if (fileP != stderr) {
   372    371   	fclose(fileP);
................................................................................
   446    445   	allocHead->blink = result;
   447    446       }
   448    447       allocHead = result;
   449    448   
   450    449       total_mallocs++;
   451    450       if (trace_on_at_malloc && (total_mallocs >= trace_on_at_malloc)) {
   452    451   	(void) fflush(stdout);
   453         -	fprintf(stderr, "reached malloc trace enable point (%d)\n",
          452  +	fprintf(stderr, "reached malloc trace enable point (%u)\n",
   454    453   		total_mallocs);
   455    454   	fflush(stderr);
   456    455   	alloc_tracing = TRUE;
   457    456   	trace_on_at_malloc = 0;
   458    457       }
   459    458   
   460    459       if (alloc_tracing) {
................................................................................
   461    460   	fprintf(stderr,"ckalloc %p %u %s %d\n",
   462    461   		result->body, size, file, line);
   463    462       }
   464    463   
   465    464       if (break_on_malloc && (total_mallocs >= break_on_malloc)) {
   466    465   	break_on_malloc = 0;
   467    466   	(void) fflush(stdout);
   468         -	Tcl_Panic("reached malloc break limit (%d)", total_mallocs);
          467  +	Tcl_Panic("reached malloc break limit (%u)", total_mallocs);
   469    468       }
   470    469   
   471    470       current_malloc_packets++;
   472    471       if (current_malloc_packets > maximum_malloc_packets) {
   473    472   	maximum_malloc_packets = current_malloc_packets;
   474    473       }
   475    474       current_bytes_malloced += size;
................................................................................
   608    607        * such as Crays (will subtract only bytes, even though BODY_OFFSET is in
   609    608        * words on these machines).
   610    609        */
   611    610   
   612    611       memp = (struct mem_header *) (((size_t) ptr) - BODY_OFFSET);
   613    612   
   614    613       if (alloc_tracing) {
   615         -	fprintf(stderr, "ckfree %p %" TCL_LL_MODIFIER "d %s %d\n",
   616         -		memp->body, (Tcl_WideInt) memp->length, file, line);
          614  +	fprintf(stderr, "ckfree %p %" TCL_Z_MODIFIER "u %s %d\n",
          615  +		memp->body, memp->length, file, line);
   617    616       }
   618    617   
   619    618       if (validate_memory) {
   620    619   	Tcl_ValidateAllMemory(file, line);
   621    620       }
   622    621   
   623    622       Tcl_MutexLock(ckallocMutexPtr);
................................................................................
   844    843   	    Tcl_SetObjResult(interp, Tcl_ObjPrintf("error accessing %s: %s",
   845    844                       argv[2], Tcl_PosixError(interp)));
   846    845   	    return TCL_ERROR;
   847    846   	}
   848    847   	return TCL_OK;
   849    848       }
   850    849       if (strcmp(argv[1],"break_on_malloc") == 0) {
          850  +	int value;
   851    851   	if (argc != 3) {
   852    852   	    goto argError;
   853    853   	}
   854         -	if (Tcl_GetInt(interp, argv[2], &break_on_malloc) != TCL_OK) {
          854  +	if (Tcl_GetInt(interp, argv[2], &value) != TCL_OK) {
   855    855   	    return TCL_ERROR;
   856    856   	}
          857  +	break_on_malloc = (unsigned int) value;
   857    858   	return TCL_OK;
   858    859       }
   859    860       if (strcmp(argv[1],"info") == 0) {
   860    861   	Tcl_SetObjResult(interp, Tcl_ObjPrintf(
   861         -		"%-25s %10d\n%-25s %10d\n%-25s %10d\n%-25s %10lu\n%-25s %10d\n%-25s %10lu\n",
          862  +		"%-25s %10u\n%-25s %10u\n%-25s %10u\n%-25s %10" TCL_Z_MODIFIER"u\n%-25s %10u\n%-25s %10" TCL_Z_MODIFIER "u\n",
   862    863   		"total mallocs", total_mallocs, "total frees", total_frees,
   863    864   		"current packets allocated", current_malloc_packets,
   864         -		"current bytes allocated", (unsigned long)current_bytes_malloced,
          865  +		"current bytes allocated", current_bytes_malloced,
   865    866   		"maximum packets allocated", maximum_malloc_packets,
   866         -		"maximum bytes allocated", (unsigned long)maximum_bytes_malloced));
          867  +		"maximum bytes allocated", maximum_bytes_malloced));
   867    868   	return TCL_OK;
   868    869       }
   869    870       if (strcmp(argv[1], "init") == 0) {
   870    871   	if (argc != 3) {
   871    872   	    goto bad_suboption;
   872    873   	}
   873    874   	init_malloced_bodies = (strcmp(argv[2],"on") == 0);
................................................................................
   930    931   	    goto bad_suboption;
   931    932   	}
   932    933   	alloc_tracing = (strcmp(argv[2],"on") == 0);
   933    934   	return TCL_OK;
   934    935       }
   935    936   
   936    937       if (strcmp(argv[1],"trace_on_at_malloc") == 0) {
          938  +	int value;
   937    939   	if (argc != 3) {
   938    940   	    goto argError;
   939    941   	}
   940         -	if (Tcl_GetInt(interp, argv[2], &trace_on_at_malloc) != TCL_OK) {
          942  +	if (Tcl_GetInt(interp, argv[2], &value) != TCL_OK) {
   941    943   	    return TCL_ERROR;
   942    944   	}
          945  +	trace_on_at_malloc = value;
   943    946   	return TCL_OK;
   944    947       }
   945    948       if (strcmp(argv[1],"validate") == 0) {
   946    949   	if (argc != 3) {
   947    950   	    goto bad_suboption;
   948    951   	}
   949    952   	validate_memory = (strcmp(argv[2],"on") == 0);

Changes to generic/tclClock.c.

    87     87       "year"
    88     88   };
    89     89   
    90     90   /*
    91     91    * Structure containing the client data for [clock]
    92     92    */
    93     93   
    94         -typedef struct ClockClientData {
           94  +typedef struct {
    95     95       size_t refCount;		/* Number of live references. */
    96     96       Tcl_Obj **literals;		/* Pool of object literals. */
    97     97   } ClockClientData;
    98     98   
    99     99   /*
   100    100    * Structure containing the fields used in [clock format] and [clock scan]
   101    101    */
................................................................................
   204    204   				 * the end of the table. */
   205    205       Tcl_ObjCmdProc *objCmdProc;	/* Function that implements the command. This
   206    206   				 * will always have the ClockClientData sent
   207    207   				 * to it, but may well ignore this data. */
   208    208   };
   209    209   
   210    210   static const struct ClockCommand clockCommands[] = {
   211         -    { "clicks",			ClockClicksObjCmd },
   212    211       { "getenv",			ClockGetenvObjCmd },
   213         -    { "microseconds",		ClockMicrosecondsObjCmd },
   214         -    { "milliseconds",		ClockMillisecondsObjCmd },
   215         -    { "seconds",		ClockSecondsObjCmd },
   216    212       { "Oldscan",		TclClockOldscanObjCmd },
   217    213       { "ConvertLocalToUTC",	ClockConvertlocaltoutcObjCmd },
   218    214       { "GetDateFields",		ClockGetdatefieldsObjCmd },
   219    215       { "GetJulianDayFromEraYearMonthDay",
   220    216   		ClockGetjuliandayfromerayearmonthdayObjCmd },
   221    217       { "GetJulianDayFromEraYearWeekDay",
   222    218   		ClockGetjuliandayfromerayearweekdayObjCmd },
................................................................................
   249    245       const struct ClockCommand *clockCmdPtr;
   250    246       char cmdName[50];		/* Buffer large enough to hold the string
   251    247   				 *::tcl::clock::GetJulianDayFromEraYearMonthDay
   252    248   				 * plus a terminating NUL. */
   253    249       ClockClientData *data;
   254    250       int i;
   255    251   
          252  +    /* Structure of the 'clock' ensemble */
          253  +
          254  +    static const EnsembleImplMap clockImplMap[] = {
          255  +	{"add",          NULL,                    TclCompileBasicMin1ArgCmd, NULL, NULL,       0},
          256  +	{"clicks",       ClockClicksObjCmd,       TclCompileClockClicksCmd,  NULL, NULL,       0},
          257  +	{"format",       NULL,                    TclCompileBasicMin1ArgCmd, NULL, NULL,       0},
          258  +	{"microseconds", ClockMicrosecondsObjCmd, TclCompileClockReadingCmd, NULL, INT2PTR(1), 0},
          259  +	{"milliseconds", ClockMillisecondsObjCmd, TclCompileClockReadingCmd, NULL, INT2PTR(2), 0},
          260  +	{"scan",         NULL,                    TclCompileBasicMin1ArgCmd, NULL, NULL      , 0},
          261  +	{"seconds",      ClockSecondsObjCmd,      TclCompileClockReadingCmd, NULL, INT2PTR(3), 0},
          262  +	{NULL,           NULL,                    NULL,                      NULL, NULL,       0}
          263  +    };
          264  +
   256    265       /*
   257    266        * Safe interps get [::clock] as alias to a master, so do not need their
   258    267        * own copies of the support routines.
   259    268        */
   260    269   
   261    270       if (Tcl_IsSafe(interp)) {
   262    271   	return;
................................................................................
   272    281       for (i = 0; i < LIT__END; ++i) {
   273    282   	data->literals[i] = Tcl_NewStringObj(literals[i], -1);
   274    283   	Tcl_IncrRefCount(data->literals[i]);
   275    284       }
   276    285   
   277    286       /*
   278    287        * Install the commands.
          288  +     * TODO - Let Tcl_MakeEnsemble do this?
   279    289        */
   280    290   
   281    291   #define TCL_CLOCK_PREFIX_LEN 14 /* == strlen("::tcl::clock::") */
   282    292       memcpy(cmdName, "::tcl::clock::", TCL_CLOCK_PREFIX_LEN);
   283    293       for (clockCmdPtr=clockCommands ; clockCmdPtr->name!=NULL ; clockCmdPtr++) {
   284    294   	strcpy(cmdName + TCL_CLOCK_PREFIX_LEN, clockCmdPtr->name);
   285    295   	data->refCount++;
   286    296   	Tcl_CreateObjCommand(interp, cmdName, clockCmdPtr->objCmdProc, data,
   287    297   		ClockDeleteCmdProc);
   288    298       }
          299  +
          300  +    /* Make the clock ensemble */
          301  +
          302  +    TclMakeEnsemble(interp, "clock", clockImplMap);
   289    303   }
   290    304   
   291    305   /*
   292    306    *----------------------------------------------------------------------
   293    307    *
   294    308    * ClockConvertlocaltoutcObjCmd --
   295    309    *
................................................................................
   345    359   	return TCL_ERROR;
   346    360       }
   347    361       if (secondsObj == NULL) {
   348    362   	Tcl_SetObjResult(interp, Tcl_NewStringObj("key \"localseconds\" not "
   349    363   		"found in dictionary", -1));
   350    364   	return TCL_ERROR;
   351    365       }
   352         -    if ((Tcl_GetWideIntFromObj(interp, secondsObj,
          366  +    if ((TclGetWideIntFromObj(interp, secondsObj,
   353    367   	    &fields.localSeconds) != TCL_OK)
   354    368   	|| (TclGetIntFromObj(interp, objv[3], &changeover) != TCL_OK)
   355    369   	|| ConvertLocalToUTC(interp, &fields, objv[2], changeover)) {
   356    370   	return TCL_ERROR;
   357    371       }
   358    372   
   359    373       /*
................................................................................
   424    438        * Check params.
   425    439        */
   426    440   
   427    441       if (objc != 4) {
   428    442   	Tcl_WrongNumArgs(interp, 1, objv, "seconds tzdata changeover");
   429    443   	return TCL_ERROR;
   430    444       }
   431         -    if (Tcl_GetWideIntFromObj(interp, objv[1], &fields.seconds) != TCL_OK
          445  +    if (TclGetWideIntFromObj(interp, objv[1], &fields.seconds) != TCL_OK
   432    446   	    || TclGetIntFromObj(interp, objv[3], &changeover) != TCL_OK) {
   433    447   	return TCL_ERROR;
   434    448       }
   435    449   
   436    450       /*
   437    451        * fields.seconds could be an unsigned number that overflowed. Make sure
   438    452        * that it isn't.
................................................................................
  1130   1144       Tcl_WideInt compVal;
  1131   1145   
  1132   1146       /*
  1133   1147        * Examine the first row to make sure we're in bounds.
  1134   1148        */
  1135   1149   
  1136   1150       if (Tcl_ListObjIndex(interp, rowv[0], 0, &compObj) != TCL_OK
  1137         -	    || Tcl_GetWideIntFromObj(interp, compObj, &compVal) != TCL_OK) {
         1151  +	    || TclGetWideIntFromObj(interp, compObj, &compVal) != TCL_OK) {
  1138   1152   	return NULL;
  1139   1153       }
  1140   1154   
  1141   1155       /*
  1142   1156        * Bizarre case - first row doesn't begin at MIN_WIDE_INT. Return it
  1143   1157        * anyway.
  1144   1158        */
................................................................................
  1153   1167   
  1154   1168       l = 0;
  1155   1169       u = rowc-1;
  1156   1170       while (l < u) {
  1157   1171   	int m = (l + u + 1) / 2;
  1158   1172   
  1159   1173   	if (Tcl_ListObjIndex(interp, rowv[m], 0, &compObj) != TCL_OK ||
  1160         -		Tcl_GetWideIntFromObj(interp, compObj, &compVal) != TCL_OK) {
         1174  +		TclGetWideIntFromObj(interp, compObj, &compVal) != TCL_OK) {
  1161   1175   	    return NULL;
  1162   1176   	}
  1163   1177   	if (tick >= compVal) {
  1164   1178   	    l = m;
  1165   1179   	} else {
  1166   1180   	    u = m-1;
  1167   1181   	}
................................................................................
  1503   1517       ym1o4 = ym1 / 4;
  1504   1518   #else
  1505   1519       /*
  1506   1520        * Have to make sure quotient is truncated towards 0 when negative.
  1507   1521        * See above bug for details. The casts are necessary.
  1508   1522        */
  1509   1523       if (ym1 >= 0)
  1510         -        ym1o4 = ym1 / 4;
         1524  +	ym1o4 = ym1 / 4;
  1511   1525       else {
  1512         -        ym1o4 = - (int) (((unsigned int) -ym1) / 4);
         1526  +	ym1o4 = - (int) (((unsigned int) -ym1) / 4);
  1513   1527       }
  1514   1528   #endif
  1515   1529       if (ym1 % 4 < 0) {
  1516   1530   	ym1o4--;
  1517   1531       }
  1518   1532       ym1o100 = ym1 / 100;
  1519   1533       if (ym1 % 100 < 0) {
................................................................................
  1560   1574    *----------------------------------------------------------------------
  1561   1575    */
  1562   1576   
  1563   1577   static int
  1564   1578   IsGregorianLeapYear(
  1565   1579       TclDateFields *fields)	/* Date to test */
  1566   1580   {
  1567         -    int year;
         1581  +    int year = fields->year;
  1568   1582   
  1569   1583       if (fields->era == BCE) {
  1570         -	year = 1 - fields->year;
  1571         -    } else {
  1572         -	year = fields->year;
         1584  +	year = 1 - year;
  1573   1585       }
  1574   1586       if (year%4 != 0) {
  1575   1587   	return 0;
  1576   1588       } else if (!(fields->gregorian)) {
  1577   1589   	return 1;
  1578   1590       } else if (year%400 == 0) {
  1579   1591   	return 1;
................................................................................
  1676   1688       const time_t *timePtr)	/* Pointer to the number of seconds since the
  1677   1689   				 * local system's epoch */
  1678   1690   {
  1679   1691       /*
  1680   1692        * Get a thread-local buffer to hold the returned time.
  1681   1693        */
  1682   1694   
  1683         -    struct tm *tmPtr = Tcl_GetThreadData(&tmKey, (int) sizeof(struct tm));
         1695  +    struct tm *tmPtr = Tcl_GetThreadData(&tmKey, sizeof(struct tm));
  1684   1696   #ifdef HAVE_LOCALTIME_R
  1685   1697       localtime_r(timePtr, tmPtr);
  1686   1698   #else
  1687   1699       struct tm *sysTmPtr;
  1688   1700   
  1689   1701       Tcl_MutexLock(&clockMutex);
  1690   1702       sysTmPtr = localtime(timePtr);
................................................................................
  1932   1944   	saw |= 1 << optionIndex;
  1933   1945       }
  1934   1946   
  1935   1947       /*
  1936   1948        * Check options.
  1937   1949        */
  1938   1950   
  1939         -    if (Tcl_GetWideIntFromObj(interp, objv[1], &clockVal) != TCL_OK) {
         1951  +    if (TclGetWideIntFromObj(interp, objv[1], &clockVal) != TCL_OK) {
  1940   1952   	return TCL_ERROR;
  1941   1953       }
  1942   1954       if ((saw & (1 << CLOCK_FORMAT_GMT))
  1943   1955   	    && (saw & (1 << CLOCK_FORMAT_TIMEZONE))) {
  1944   1956   	Tcl_SetObjResult(interp, litPtr[LIT_CANNOT_USE_GMT_AND_TIMEZONE]);
  1945   1957   	Tcl_SetErrorCode(interp, "CLOCK", "gmtWithTimezone", NULL);
  1946   1958   	return TCL_ERROR;

Changes to generic/tclCmdAH.c.

    42     42   
    43     43   /*
    44     44    * Prototypes for local procedures defined in this file:
    45     45    */
    46     46   
    47     47   static int		CheckAccess(Tcl_Interp *interp, Tcl_Obj *pathPtr,
    48     48   			    int mode);
           49  +static int		BadEncodingSubcommand(ClientData dummy,
           50  +			    Tcl_Interp *interp, int objc,
           51  +			    Tcl_Obj *const objv[]);
           52  +static int		EncodingConvertfromObjCmd(ClientData dummy,
           53  +			    Tcl_Interp *interp, int objc,
           54  +			    Tcl_Obj *const objv[]);
           55  +static int		EncodingConverttoObjCmd(ClientData dummy,
           56  +			    Tcl_Interp *interp, int objc,
           57  +			    Tcl_Obj *const objv[]);
    49     58   static int		EncodingDirsObjCmd(ClientData dummy,
    50     59   			    Tcl_Interp *interp, int objc,
           60  +			    Tcl_Obj *const objv[]);
           61  +static int		EncodingNamesObjCmd(ClientData dummy,
           62  +			    Tcl_Interp *interp, int objc,
           63  +			    Tcl_Obj *const objv[]);
           64  +static int		EncodingSystemObjCmd(ClientData dummy,
           65  +			    Tcl_Interp *interp, int objc,
    51     66   			    Tcl_Obj *const objv[]);
    52     67   static inline int	ForeachAssignments(Tcl_Interp *interp,
    53     68   			    struct ForeachState *statePtr);
    54     69   static inline void	ForeachCleanup(Tcl_Interp *interp,
    55     70   			    struct ForeachState *statePtr);
    56     71   static int		GetStatBuf(Tcl_Interp *interp, Tcl_Obj *pathPtr,
    57     72   			    Tcl_FSStatProc *statProc, Tcl_StatBuf *statPtr);
................................................................................
   145    160    *	A standard Tcl object result.
   146    161    *
   147    162    * Side effects:
   148    163    *	See the user documentation.
   149    164    *
   150    165    *----------------------------------------------------------------------
   151    166    */
   152         -#ifndef TCL_NO_DEPRECATED
          167  +#if !defined(TCL_NO_DEPRECATED) && TCL_MAJOR_VERSION < 9
   153    168   	/* ARGSUSED */
   154    169   int
   155    170   Tcl_CaseObjCmd(
   156    171       ClientData dummy,		/* Not used. */
   157    172       Tcl_Interp *interp,		/* Current interpreter. */
   158    173       int objc,			/* Number of arguments. */
   159    174       Tcl_Obj *const objv[])	/* Argument objects. */
................................................................................
   538    553       if (Tcl_GetIndexFromObj(interp, objv[1], optionStrings, "option", 0,
   539    554   	    &index) != TCL_OK) {
   540    555   	return TCL_ERROR;
   541    556       }
   542    557   
   543    558       switch ((enum options) index) {
   544    559       case ENC_CONVERTTO:
   545         -    case ENC_CONVERTFROM: {
   546         -	Tcl_Obj *data;
   547         -	Tcl_DString ds;
   548         -	Tcl_Encoding encoding;
   549         -	int length;
   550         -	const char *stringPtr;
   551         -
   552         -	if (objc == 3) {
   553         -	    encoding = Tcl_GetEncoding(interp, NULL);
   554         -	    data = objv[2];
   555         -	} else if (objc == 4) {
   556         -	    if (Tcl_GetEncodingFromObj(interp, objv[2], &encoding) != TCL_OK) {
   557         -		return TCL_ERROR;
   558         -	    }
   559         -	    data = objv[3];
   560         -	} else {
   561         -	    Tcl_WrongNumArgs(interp, 2, objv, "?encoding? data");
   562         -	    return TCL_ERROR;
   563         -	}
   564         -
   565         -	if ((enum options) index == ENC_CONVERTFROM) {
   566         -	    /*
   567         -	     * Treat the string as binary data.
   568         -	     */
   569         -
   570         -	    stringPtr = (char *) Tcl_GetByteArrayFromObj(data, &length);
   571         -	    Tcl_ExternalToUtfDString(encoding, stringPtr, length, &ds);
   572         -
   573         -	    /*
   574         -	     * Note that we cannot use Tcl_DStringResult here because it will
   575         -	     * truncate the string at the first null byte.
   576         -	     */
   577         -
   578         -	    Tcl_SetObjResult(interp, TclDStringToObj(&ds));
   579         -	} else {
   580         -	    /*
   581         -	     * Store the result as binary data.
   582         -	     */
   583         -
   584         -	    stringPtr = TclGetStringFromObj(data, &length);
   585         -	    Tcl_UtfToExternalDString(encoding, stringPtr, length, &ds);
   586         -	    Tcl_SetObjResult(interp, Tcl_NewByteArrayObj(
   587         -		    (unsigned char *) Tcl_DStringValue(&ds),
   588         -		    Tcl_DStringLength(&ds)));
   589         -	    Tcl_DStringFree(&ds);
   590         -	}
   591         -
   592         -	Tcl_FreeEncoding(encoding);
   593         -	break;
   594         -    }
          560  +	return EncodingConverttoObjCmd(dummy, interp, objc, objv);
          561  +    case ENC_CONVERTFROM:
          562  +	return EncodingConvertfromObjCmd(dummy, interp, objc, objv);
   595    563       case ENC_DIRS:
   596    564   	return EncodingDirsObjCmd(dummy, interp, objc, objv);
   597    565       case ENC_NAMES:
   598         -	if (objc > 2) {
   599         -	    Tcl_WrongNumArgs(interp, 2, objv, NULL);
          566  +	return EncodingNamesObjCmd(dummy, interp, objc, objv);
          567  +    case ENC_SYSTEM:
          568  +	return EncodingSystemObjCmd(dummy, interp, objc, objv);
          569  +    }
          570  +    return TCL_OK;
          571  +}
          572  +
          573  +/*
          574  + *-----------------------------------------------------------------------------
          575  + *
          576  + * TclInitEncodingCmd --
          577  + *
          578  + *	This function creates the 'encoding' ensemble.
          579  + *
          580  + * Results:
          581  + *	Returns the Tcl_Command so created.
          582  + *
          583  + * Side effects:
          584  + *	The ensemble is initialized.
          585  + *
          586  + * This command is hidden in a safe interpreter.
          587  + */
          588  +
          589  +Tcl_Command
          590  +TclInitEncodingCmd(
          591  +    Tcl_Interp* interp)		/* Tcl interpreter */
          592  +{
          593  +    static const EnsembleImplMap encodingImplMap[] = {
          594  +	{"convertfrom", EncodingConvertfromObjCmd, TclCompileBasic1Or2ArgCmd, NULL, NULL, 0},
          595  +	{"convertto",   EncodingConverttoObjCmd,   TclCompileBasic1Or2ArgCmd, NULL, NULL, 0},
          596  +	{"dirs",        EncodingDirsObjCmd,        TclCompileBasic0Or1ArgCmd, NULL, NULL, 0},
          597  +	{"names",       EncodingNamesObjCmd,       TclCompileBasic0ArgCmd,    NULL, NULL, 0},
          598  +	{"system",      EncodingSystemObjCmd,      TclCompileBasic0Or1ArgCmd, NULL, NULL, 0},
          599  +	{NULL,          NULL,                      NULL,                      NULL, NULL, 0}
          600  +    };
          601  +
          602  +    return TclMakeEnsemble(interp, "encoding", encodingImplMap);
          603  +}
          604  +
          605  +/*
          606  + *-----------------------------------------------------------------------------
          607  + *
          608  + * TclMakeEncodingCommandSafe --
          609  + *
          610  + *	This function hides the unsafe 'dirs' and 'system' subcommands of
          611  + *	the "encoding" Tcl command ensemble. It must be called only from
          612  + *	TclHideUnsafeCommands.
          613  + *
          614  + * Results:
          615  + *	A standard Tcl result
          616  + *
          617  + * Side effects:
          618  + *	Adds commands to the table of hidden commands.
          619  + *
          620  + *-----------------------------------------------------------------------------
          621  + */
          622  +
          623  +int
          624  +TclMakeEncodingCommandSafe(
          625  +    Tcl_Interp* interp)		/* Tcl interpreter */
          626  +{
          627  +    static const struct {
          628  +	const char *cmdName;
          629  +	int unsafe;
          630  +    } unsafeInfo[] = {
          631  +	{"convertfrom", 0},
          632  +	{"convertto",   0},
          633  +	{"dirs",        1},
          634  +	{"names",       0},
          635  +	{"system",      0},
          636  +	{NULL,          0}
          637  +    };
          638  +
          639  +    int i;
          640  +    Tcl_DString oldBuf, newBuf;
          641  +
          642  +    Tcl_DStringInit(&oldBuf);
          643  +    TclDStringAppendLiteral(&oldBuf, "::tcl::encoding::");
          644  +    Tcl_DStringInit(&newBuf);
          645  +    TclDStringAppendLiteral(&newBuf, "tcl:encoding:");
          646  +    for (i=0 ; unsafeInfo[i].cmdName != NULL ; i++) {
          647  +	if (unsafeInfo[i].unsafe) {
          648  +	    const char *oldName, *newName;
          649  +
          650  +	    Tcl_DStringSetLength(&oldBuf, 17);
          651  +	    oldName = Tcl_DStringAppend(&oldBuf, unsafeInfo[i].cmdName, -1);
          652  +	    Tcl_DStringSetLength(&newBuf, 13);
          653  +	    newName = Tcl_DStringAppend(&newBuf, unsafeInfo[i].cmdName, -1);
          654  +	    if (TclRenameCommand(interp, oldName, "___tmp") != TCL_OK
          655  +		    || Tcl_HideCommand(interp, "___tmp", newName) != TCL_OK) {
          656  +		Tcl_Panic("problem making 'encoding %s' safe: %s",
          657  +			unsafeInfo[i].cmdName,
          658  +			Tcl_GetString(Tcl_GetObjResult(interp)));
          659  +	    }
          660  +	    Tcl_CreateObjCommand(interp, oldName, BadEncodingSubcommand,
          661  +		    (ClientData) unsafeInfo[i].cmdName, NULL);
          662  +	}
          663  +    }
          664  +    Tcl_DStringFree(&oldBuf);
          665  +    Tcl_DStringFree(&newBuf);
          666  +
          667  +    /*
          668  +     * Ugh. The [encoding] command is now actually safe, but it is assumed by
          669  +     * scripts that it is not, which messes up security policies.
          670  +     */
          671  +
          672  +    if (Tcl_HideCommand(interp, "encoding", "encoding") != TCL_OK) {
          673  +	Tcl_Panic("problem making 'encoding' safe: %s",
          674  +		Tcl_GetString(Tcl_GetObjResult(interp)));
          675  +    }
          676  +    return TCL_OK;
          677  +}
          678  +
          679  +/*
          680  + *----------------------------------------------------------------------
          681  + *
          682  + * BadEncodingSubcommand --
          683  + *
          684  + *	Command used to act as a backstop implementation when subcommands of
          685  + *	"encoding" are unsafe (the real implementations of the subcommands are
          686  + *	hidden). The clientData is always the full official subcommand name.
          687  + *
          688  + * Results:
          689  + *	A standard Tcl result (always a TCL_ERROR).
          690  + *
          691  + * Side effects:
          692  + *	None.
          693  + *
          694  + *----------------------------------------------------------------------
          695  + */
          696  +
          697  +static int
          698  +BadEncodingSubcommand(
          699  +    ClientData clientData,
          700  +    Tcl_Interp *interp,
          701  +    int objc,
          702  +    Tcl_Obj *const objv[])
          703  +{
          704  +    const char *subcommandName = (const char *) clientData;
          705  +
          706  +    Tcl_SetObjResult(interp, Tcl_ObjPrintf(
          707  +	    "not allowed to invoke subcommand %s of encoding", subcommandName));
          708  +    Tcl_SetErrorCode(interp, "TCL", "SAFE", "SUBCOMMAND", NULL);
          709  +    return TCL_ERROR;
          710  +}
          711  +
          712  +/*
          713  + *----------------------------------------------------------------------
          714  + *
          715  + * EncodingConvertfromObjCmd --
          716  + *
          717  + *	This command converts a byte array in an external encoding into a
          718  + *	Tcl string
          719  + *
          720  + * Results:
          721  + *	A standard Tcl result.
          722  + *
          723  + *----------------------------------------------------------------------
          724  + */
          725  +
          726  +int
          727  +EncodingConvertfromObjCmd(
          728  +    ClientData dummy,		/* Not used. */
          729  +    Tcl_Interp *interp,		/* Current interpreter. */
          730  +    int objc,			/* Number of arguments. */
          731  +    Tcl_Obj *const objv[])	/* Argument objects. */
          732  +{
          733  +    Tcl_Obj *data;		/* Byte array to convert */
          734  +    Tcl_DString ds;		/* Buffer to hold the string */
          735  +    Tcl_Encoding encoding;	/* Encoding to use */
          736  +    int length;			/* Length of the byte array being converted */
          737  +    const char *bytesPtr;	/* Pointer to the first byte of the array */
          738  +
          739  +    if (objc == 2) {
          740  +	encoding = Tcl_GetEncoding(interp, NULL);
          741  +	data = objv[1];
          742  +    } else if (objc == 3) {
          743  +	if (Tcl_GetEncodingFromObj(interp, objv[1], &encoding) != TCL_OK) {
   600    744   	    return TCL_ERROR;
   601    745   	}
   602         -	Tcl_GetEncodingNames(interp);
   603         -	break;
   604         -    case ENC_SYSTEM:
   605         -	if (objc > 3) {
   606         -	    Tcl_WrongNumArgs(interp, 2, objv, "?encoding?");
          746  +	data = objv[2];
          747  +    } else {
          748  +	Tcl_WrongNumArgs(interp, 1, objv, "?encoding? data");
          749  +	return TCL_ERROR;
          750  +    }
          751  +
          752  +    /*
          753  +     * Convert the string into a byte array in 'ds'
          754  +     */
          755  +    bytesPtr = (char *) Tcl_GetByteArrayFromObj(data, &length);
          756  +    Tcl_ExternalToUtfDString(encoding, bytesPtr, length, &ds);
          757  +
          758  +    /*
          759  +     * Note that we cannot use Tcl_DStringResult here because it will
          760  +     * truncate the string at the first null byte.
          761  +     */
          762  +
          763  +    Tcl_SetObjResult(interp, TclDStringToObj(&ds));
          764  +
          765  +    /*
          766  +     * We're done with the encoding
          767  +     */
          768  +
          769  +    Tcl_FreeEncoding(encoding);
          770  +    return TCL_OK;
          771  +
          772  +}
          773  +
          774  +/*
          775  + *----------------------------------------------------------------------
          776  + *
          777  + * EncodingConverttoObjCmd --
          778  + *
          779  + *	This command converts a Tcl string into a byte array that
          780  + *	encodes the string according to some encoding.
          781  + *
          782  + * Results:
          783  + *	A standard Tcl result.
          784  + *
          785  + *----------------------------------------------------------------------
          786  + */
          787  +
          788  +int
          789  +EncodingConverttoObjCmd(
          790  +    ClientData dummy,		/* Not used. */
          791  +    Tcl_Interp *interp,		/* Current interpreter. */
          792  +    int objc,			/* Number of arguments. */
          793  +    Tcl_Obj *const objv[])	/* Argument objects. */
          794  +{
          795  +    Tcl_Obj *data;		/* String to convert */
          796  +    Tcl_DString ds;		/* Buffer to hold the byte array */
          797  +    Tcl_Encoding encoding;	/* Encoding to use */
          798  +    int length;			/* Length of the string being converted */
          799  +    const char *stringPtr;	/* Pointer to the first byte of the string */
          800  +
          801  +    /* TODO - ADJUST OBJ INDICES WHEN ENSEMBLIFYING THIS */
          802  +
          803  +    if (objc == 2) {
          804  +	encoding = Tcl_GetEncoding(interp, NULL);
          805  +	data = objv[1];
          806  +    } else if (objc == 3) {
          807  +	if (Tcl_GetEncodingFromObj(interp, objv[1], &encoding) != TCL_OK) {
   607    808   	    return TCL_ERROR;
   608    809   	}
   609         -	if (objc == 2) {
   610         -	    Tcl_SetObjResult(interp, Tcl_NewStringObj(
   611         -		    Tcl_GetEncodingName(NULL), -1));
   612         -	} else {
   613         -	    return Tcl_SetSystemEncoding(interp, TclGetString(objv[2]));
   614         -	}
   615         -	break;
          810  +	data = objv[2];
          811  +    } else {
          812  +	Tcl_WrongNumArgs(interp, 1, objv, "?encoding? data");
          813  +	return TCL_ERROR;
   616    814       }
          815  +
          816  +    /*
          817  +     * Convert the string to a byte array in 'ds'
          818  +     */
          819  +
          820  +    stringPtr = TclGetStringFromObj(data, &length);
          821  +    Tcl_UtfToExternalDString(encoding, stringPtr, length, &ds);
          822  +    Tcl_SetObjResult(interp,
          823  +		     Tcl_NewByteArrayObj((unsigned char*) Tcl_DStringValue(&ds),
          824  +					 Tcl_DStringLength(&ds)));
          825  +    Tcl_DStringFree(&ds);
          826  +
          827  +    /*
          828  +     * We're done with the encoding
          829  +     */
          830  +
          831  +    Tcl_FreeEncoding(encoding);
   617    832       return TCL_OK;
          833  +
   618    834   }
   619    835   
   620    836   /*
   621    837    *----------------------------------------------------------------------
   622    838    *
   623    839    * EncodingDirsObjCmd --
   624    840    *
................................................................................
   638    854       ClientData dummy,		/* Not used. */
   639    855       Tcl_Interp *interp,		/* Current interpreter. */
   640    856       int objc,			/* Number of arguments. */
   641    857       Tcl_Obj *const objv[])	/* Argument objects. */
   642    858   {
   643    859       Tcl_Obj *dirListObj;
   644    860   
   645         -    if (objc > 3) {
   646         -	Tcl_WrongNumArgs(interp, 2, objv, "?dirList?");
          861  +    if (objc > 2) {
          862  +	Tcl_WrongNumArgs(interp, 1, objv, "?dirList?");
   647    863   	return TCL_ERROR;
   648    864       }
   649         -    if (objc == 2) {
          865  +    if (objc == 1) {
   650    866   	Tcl_SetObjResult(interp, Tcl_GetEncodingSearchPath());
   651    867   	return TCL_OK;
   652    868       }
   653    869   
   654         -    dirListObj = objv[2];
          870  +    dirListObj = objv[1];
   655    871       if (Tcl_SetEncodingSearchPath(dirListObj) == TCL_ERROR) {
   656    872   	Tcl_SetObjResult(interp, Tcl_ObjPrintf(
   657    873   		"expected directory list but got \"%s\"",
   658    874   		TclGetString(dirListObj)));
   659    875   	Tcl_SetErrorCode(interp, "TCL", "OPERATION", "ENCODING", "BADPATH",
   660    876   		NULL);
   661    877   	return TCL_ERROR;
   662    878       }
   663    879       Tcl_SetObjResult(interp, dirListObj);
   664    880       return TCL_OK;
   665    881   }
          882  +
          883  +/*
          884  + *-----------------------------------------------------------------------------
          885  + *
          886  + * EncodingNamesObjCmd --
          887  + *
          888  + *	This command returns a list of the available encoding names
          889  + *
          890  + * Results:
          891  + *	Returns a standard Tcl result
          892  + *
          893  + *-----------------------------------------------------------------------------
          894  + */
          895  +
          896  +int
          897  +EncodingNamesObjCmd(ClientData dummy,       /* Unused */
          898  +		    Tcl_Interp* interp,	    /* Tcl interpreter */
          899  +		    int objc,		    /* Number of command line args */
          900  +		    Tcl_Obj* const objv[])  /* Vector of command line args */
          901  +{
          902  +    if (objc > 1) {
          903  +	Tcl_WrongNumArgs(interp, 1, objv, NULL);
          904  +	return TCL_ERROR;
          905  +    }
          906  +    Tcl_GetEncodingNames(interp);
          907  +    return TCL_OK;
          908  +}
          909  +
          910  +/*
          911  + *-----------------------------------------------------------------------------
          912  + *
          913  + * EncodingSystemObjCmd --
          914  + *
          915  + *	This command retrieves or changes the system encoding
          916  + *
          917  + * Results:
          918  + *	Returns a standard Tcl result
          919  + *
          920  + * Side effects:
          921  + *	May change the system encoding.
          922  + *
          923  + *-----------------------------------------------------------------------------
          924  + */
          925  +
          926  +int
          927  +EncodingSystemObjCmd(ClientData dummy,      /* Unused */
          928  +		     Tcl_Interp* interp,    /* Tcl interpreter */
          929  +		     int objc,		    /* Number of command line args */
          930  +		     Tcl_Obj* const objv[]) /* Vector of command line args */
          931  +{
          932  +    if (objc > 2) {
          933  +	Tcl_WrongNumArgs(interp, 1, objv, "?encoding?");
          934  +	return TCL_ERROR;
          935  +    }
          936  +    if (objc == 1) {
          937  +	Tcl_SetObjResult(interp,
          938  +			 Tcl_NewStringObj(Tcl_GetEncodingName(NULL), -1));
          939  +    } else {
          940  +	return Tcl_SetSystemEncoding(interp, TclGetString(objv[1]));
          941  +    }
          942  +    return TCL_OK;
          943  +}
   666    944   
   667    945   /*
   668    946    *----------------------------------------------------------------------
   669    947    *
   670    948    * Tcl_ErrorObjCmd --
   671    949    *
   672    950    *	This procedure is invoked to process the "error" Tcl command. See the

Changes to generic/tclCmdIL.c.

    60     60       int isIncreasing;		/* Nonzero means sort in increasing order. */
    61     61       int sortMode;		/* The sort mode. One of SORTMODE_* values
    62     62   				 * defined below. */
    63     63       Tcl_Obj *compareCmdPtr;	/* The Tcl comparison command when sortMode is
    64     64   				 * SORTMODE_COMMAND. Pre-initialized to hold
    65     65   				 * base of command. */
    66     66       int *indexv;		/* If the -index option was specified, this
    67         -				 * holds the indexes contained in the list
    68         -				 * supplied as an argument to that option.
           67  +				 * holds an encoding of the indexes contained
           68  +				 * in the list supplied as an argument to
           69  +				 * that option.
    69     70   				 * NULL if no indexes supplied, and points to
    70     71   				 * singleIndex field when only one
    71     72   				 * supplied. */
    72     73       int indexc;			/* Number of indexes in indexv array. */
    73     74       int singleIndex;		/* Static space for common index case. */
    74     75       int unique;
    75     76       int numElements;
................................................................................
    88     89   #define SORTMODE_ASCII		0
    89     90   #define SORTMODE_INTEGER	1
    90     91   #define SORTMODE_REAL		2
    91     92   #define SORTMODE_COMMAND	3
    92     93   #define SORTMODE_DICTIONARY	4
    93     94   #define SORTMODE_ASCII_NC	8
    94     95   
    95         -/*
    96         - * Magic values for the index field of the SortInfo structure. Note that the
    97         - * index "end-1" will be translated to SORTIDX_END-1, etc.
    98         - */
    99         -
   100         -#define SORTIDX_NONE	-1	/* Not indexed; use whole value. */
   101         -#define SORTIDX_END	-2	/* Indexed from end. */
   102         -
   103     96   /*
   104     97    * Forward declarations for procedures defined in this file:
   105     98    */
   106     99   
   107    100   static int		DictionaryCompare(const char *left, const char *right);
   108    101   static Tcl_NRPostProc	IfConditionCallback;
   109    102   static int		InfoArgsCmd(ClientData dummy, Tcl_Interp *interp,
................................................................................
  2156   2149   int
  2157   2150   Tcl_JoinObjCmd(
  2158   2151       ClientData dummy,		/* Not used. */
  2159   2152       Tcl_Interp *interp,		/* Current interpreter. */
  2160   2153       int objc,			/* Number of arguments. */
  2161   2154       Tcl_Obj *const objv[])	/* The argument objects. */
  2162   2155   {
  2163         -    int listLen;
         2156  +    int length, listLen;
  2164   2157       Tcl_Obj *resObjPtr = NULL, *joinObjPtr, **elemPtrs;
  2165   2158   
  2166   2159       if ((objc < 2) || (objc > 3)) {
  2167   2160   	Tcl_WrongNumArgs(interp, 1, objv, "list ?joinString?");
  2168   2161   	return TCL_ERROR;
  2169   2162       }
  2170   2163   
................................................................................
  2187   2180   	Tcl_SetObjResult(interp, elemPtrs[0]);
  2188   2181   	return TCL_OK;
  2189   2182       }
  2190   2183   
  2191   2184       joinObjPtr = (objc == 2) ? Tcl_NewStringObj(" ", 1) : objv[2];
  2192   2185       Tcl_IncrRefCount(joinObjPtr);
  2193   2186   
  2194         -    if (Tcl_GetCharLength(joinObjPtr) == 0) {
  2195         -	TclStringCatObjv(interp, /* inPlace */ 0, listLen, elemPtrs,
  2196         -		&resObjPtr);
         2187  +    (void) Tcl_GetStringFromObj(joinObjPtr, &length);
         2188  +    if (length == 0) {
         2189  +	resObjPtr = TclStringCat(interp, listLen, elemPtrs, 0);
  2197   2190       } else {
  2198   2191   	int i;
  2199   2192   
  2200   2193   	resObjPtr = Tcl_NewObj();
  2201   2194   	for (i = 0;  i < listLen;  i++) {
  2202   2195   	    if (i > 0) {
  2203   2196   
................................................................................
  2783   2776       /*
  2784   2777        * Complain if the user asked for a start element that is greater than the
  2785   2778        * list length. This won't ever trigger for the "end-*" case as that will
  2786   2779        * be properly constrained by TclGetIntForIndex because we use listLen-1
  2787   2780        * (to allow for replacing the last elem).
  2788   2781        */
  2789   2782   
  2790         -    if ((first > listLen) && (listLen > 0)) {
         2783  +    if ((first >= listLen) && (listLen > 0)) {
  2791   2784   	Tcl_SetObjResult(interp, Tcl_ObjPrintf(
  2792   2785   		"list doesn't contain element %s", TclGetString(objv[2])));
  2793   2786   	Tcl_SetErrorCode(interp, "TCL", "OPERATION", "LREPLACE", "BADIDX",
  2794   2787   		NULL);
  2795   2788   	return TCL_ERROR;
  2796   2789       }
  2797   2790       if (last >= listLen) {
................................................................................
  2934   2927   Tcl_LsearchObjCmd(
  2935   2928       ClientData clientData,	/* Not used. */
  2936   2929       Tcl_Interp *interp,		/* Current interpreter. */
  2937   2930       int objc,			/* Number of arguments. */
  2938   2931       Tcl_Obj *const objv[])	/* Argument values. */
  2939   2932   {
  2940   2933       const char *bytes, *patternBytes;
  2941         -    int i, match, index, result, listc, length, elemLen, bisect;
  2942         -    int dataType, isIncreasing, lower, upper, offset;
         2934  +    int i, match, index, result=TCL_OK, listc, length, elemLen, bisect;
         2935  +    int allocatedIndexVector = 0;
         2936  +    int dataType, isIncreasing, lower, upper, start, groupSize, groupOffset;
  2943   2937       Tcl_WideInt patWide, objWide;
  2944   2938       int allMatches, inlineReturn, negatedMatch, returnSubindices, noCase;
  2945   2939       double patDouble, objDouble;
  2946   2940       SortInfo sortInfo;
  2947   2941       Tcl_Obj *patObj, **listv, *listPtr, *startPtr, *itemPtr;
  2948         -    SortStrCmpFn_t strCmpFn = strcmp;
         2942  +    SortStrCmpFn_t strCmpFn = TclUtfCmp;
  2949   2943       Tcl_RegExp regexp = NULL;
  2950   2944       static const char *const options[] = {
  2951   2945   	"-all",	    "-ascii",   "-bisect", "-decreasing", "-dictionary",
  2952   2946   	"-exact",   "-glob",    "-increasing", "-index",
  2953   2947   	"-inline",  "-integer", "-nocase",     "-not",
  2954         -	"-real",    "-regexp",  "-sorted",     "-start",
         2948  +	"-real",    "-regexp",  "-sorted",     "-start", "-stride",
  2955   2949   	"-subindices", NULL
  2956   2950       };
  2957   2951       enum options {
  2958   2952   	LSEARCH_ALL, LSEARCH_ASCII, LSEARCH_BISECT, LSEARCH_DECREASING,
  2959   2953   	LSEARCH_DICTIONARY, LSEARCH_EXACT, LSEARCH_GLOB, LSEARCH_INCREASING,
  2960   2954   	LSEARCH_INDEX, LSEARCH_INLINE, LSEARCH_INTEGER, LSEARCH_NOCASE,
  2961   2955   	LSEARCH_NOT, LSEARCH_REAL, LSEARCH_REGEXP, LSEARCH_SORTED,
  2962         -	LSEARCH_START, LSEARCH_SUBINDICES
         2956  +	LSEARCH_START, LSEARCH_STRIDE, LSEARCH_SUBINDICES
  2963   2957       };
  2964   2958       enum datatypes {
  2965   2959   	ASCII, DICTIONARY, INTEGER, REAL
  2966   2960       };
  2967   2961       enum modes {
  2968   2962   	EXACT, GLOB, REGEXP, SORTED
  2969   2963       };
................................................................................
  2975   2969       allMatches = 0;
  2976   2970       inlineReturn = 0;
  2977   2971       returnSubindices = 0;
  2978   2972       negatedMatch = 0;
  2979   2973       bisect = 0;
  2980   2974       listPtr = NULL;
  2981   2975       startPtr = NULL;
  2982         -    offset = 0;
         2976  +    groupSize = 1;
         2977  +    groupOffset = 0;
         2978  +    start = 0;
  2983   2979       noCase = 0;
  2984   2980       sortInfo.compareCmdPtr = NULL;
  2985   2981       sortInfo.isIncreasing = 1;
  2986   2982       sortInfo.sortMode = 0;
  2987   2983       sortInfo.interp = interp;
  2988   2984       sortInfo.resultCode = TCL_OK;
  2989   2985       sortInfo.indexv = NULL;
................................................................................
  2993   2989   	Tcl_WrongNumArgs(interp, 1, objv, "?-option value ...? list pattern");
  2994   2990   	return TCL_ERROR;
  2995   2991       }
  2996   2992   
  2997   2993       for (i = 1; i < objc-2; i++) {
  2998   2994   	if (Tcl_GetIndexFromObj(interp, objv[i], options, "option", 0, &index)
  2999   2995   		!= TCL_OK) {
  3000         -	    if (startPtr != NULL) {
  3001         -		Tcl_DecrRefCount(startPtr);
  3002         -	    }
  3003   2996   	    result = TCL_ERROR;
  3004   2997   	    goto done;
  3005   2998   	}
  3006   2999   	switch ((enum options) index) {
  3007   3000   	case LSEARCH_ALL:		/* -all */
  3008   3001   	    allMatches = 1;
  3009   3002   	    break;
................................................................................
  3060   3053   	    /*
  3061   3054   	     * If there was a previous -start option, release its saved index
  3062   3055   	     * because it will either be replaced or there will be an error.
  3063   3056   	     */
  3064   3057   
  3065   3058   	    if (startPtr != NULL) {
  3066   3059   		Tcl_DecrRefCount(startPtr);
         3060  +		startPtr = NULL;
  3067   3061   	    }
  3068   3062   	    if (i > objc-4) {
  3069   3063   		Tcl_SetObjResult(interp, Tcl_NewStringObj(
  3070   3064   			"missing starting index", -1));
  3071   3065   		Tcl_SetErrorCode(interp, "TCL", "ARGUMENT", "MISSING", NULL);
  3072   3066   		result = TCL_ERROR;
  3073   3067   		goto done;
................................................................................
  3080   3074   		 * being searched. We only need to copy where the list and the
  3081   3075   		 * index are one-and-the-same.
  3082   3076   		 */
  3083   3077   
  3084   3078   		startPtr = Tcl_DuplicateObj(objv[i]);
  3085   3079   	    } else {
  3086   3080   		startPtr = objv[i];
  3087         -		Tcl_IncrRefCount(startPtr);
  3088   3081   	    }
         3082  +	    Tcl_IncrRefCount(startPtr);
         3083  +	    break;
         3084  +	case LSEARCH_STRIDE:		/* -stride */
         3085  +	    if (i > objc-4) {
         3086  +		Tcl_SetObjResult(interp, Tcl_NewStringObj(
         3087  +			"\"-stride\" option must be "
         3088  +			"followed by stride length", -1));
         3089  +		Tcl_SetErrorCode(interp, "TCL", "ARGUMENT", "MISSING", NULL);
         3090  +		result = TCL_ERROR;
         3091  +		goto done;
         3092  +	    }
         3093  +	    if (Tcl_GetIntFromObj(interp, objv[i+1], &groupSize) != TCL_OK) {
         3094  +		result = TCL_ERROR;
         3095  +		goto done;
         3096  +	    }
         3097  +	    if (groupSize < 1) {
         3098  +		Tcl_SetObjResult(interp, Tcl_NewStringObj(
         3099  +			"stride length must be at least 1", -1));
         3100  +		Tcl_SetErrorCode(interp, "TCL", "OPERATION", "LSORT",
         3101  +			"BADSTRIDE", NULL);
         3102  +		result = TCL_ERROR;
         3103  +		goto done;
         3104  +	    }
         3105  +	    i++;
  3089   3106   	    break;
  3090   3107   	case LSEARCH_INDEX: {		/* -index */
  3091   3108   	    Tcl_Obj **indices;
  3092   3109   	    int j;
  3093   3110   
  3094         -	    if (sortInfo.indexc > 1) {
         3111  +	    if (allocatedIndexVector) {
  3095   3112   		TclStackFree(interp, sortInfo.indexv);
         3113  +		allocatedIndexVector = 0;
  3096   3114   	    }
  3097   3115   	    if (i > objc-4) {
  3098         -		if (startPtr != NULL) {
  3099         -		    Tcl_DecrRefCount(startPtr);
  3100         -		}
  3101   3116   		Tcl_SetObjResult(interp, Tcl_NewStringObj(
  3102   3117   			"\"-index\" option must be followed by list index",
  3103   3118   			-1));
  3104   3119   		Tcl_SetErrorCode(interp, "TCL", "ARGUMENT", "MISSING", NULL);
  3105         -		return TCL_ERROR;
         3120  +		result = TCL_ERROR;
         3121  +		goto done;
  3106   3122   	    }
  3107   3123   
  3108   3124   	    /*
  3109   3125   	     * Store the extracted indices for processing by sublist
  3110   3126   	     * extraction. Note that we don't do this using objects because
  3111   3127   	     * that has shimmering problems.
  3112   3128   	     */
  3113   3129   
  3114   3130   	    i++;
  3115   3131   	    if (TclListObjGetElements(interp, objv[i],
  3116   3132   		    &sortInfo.indexc, &indices) != TCL_OK) {
  3117         -		if (startPtr != NULL) {
  3118         -		    Tcl_DecrRefCount(startPtr);
  3119         -		}
  3120         -		return TCL_ERROR;
         3133  +		result = TCL_ERROR;
         3134  +		goto done;
  3121   3135   	    }
  3122   3136   	    switch (sortInfo.indexc) {
  3123   3137   	    case 0:
  3124   3138   		sortInfo.indexv = NULL;
  3125   3139   		break;
  3126   3140   	    case 1:
  3127   3141   		sortInfo.indexv = &sortInfo.singleIndex;
  3128   3142   		break;
  3129   3143   	    default:
  3130   3144   		sortInfo.indexv =
  3131   3145   			TclStackAlloc(interp, sizeof(int) * sortInfo.indexc);
         3146  +		allocatedIndexVector = 1; /* Cannot use indexc field, as it
         3147  +					   * might be decreased by 1 later. */
  3132   3148   	    }
  3133   3149   
  3134   3150   	    /*
  3135   3151   	     * Fill the array by parsing each index. We don't know whether
  3136   3152   	     * their scale is sensible yet, but we at least perform the
  3137   3153   	     * syntactic check here.
  3138   3154   	     */
  3139   3155   
  3140   3156   	    for (j=0 ; j<sortInfo.indexc ; j++) {
  3141         -		if (TclGetIntForIndexM(interp, indices[j], SORTIDX_END,
  3142         -			&sortInfo.indexv[j]) != TCL_OK) {
         3157  +		int encoded = 0;
         3158  +		if (TclIndexEncode(interp, indices[j], TCL_INDEX_BEFORE,
         3159  +			TCL_INDEX_AFTER, &encoded) != TCL_OK) {
         3160  +		    result = TCL_ERROR;
         3161  +		}
         3162  +		if ((encoded == TCL_INDEX_BEFORE)
         3163  +			|| (encoded == TCL_INDEX_AFTER)) {
         3164  +		    Tcl_SetObjResult(interp, Tcl_ObjPrintf(
         3165  +			    "index \"%s\" cannot select an element "
         3166  +			    "from any list", Tcl_GetString(indices[j])));
         3167  +		    Tcl_SetErrorCode(interp, "TCL", "VALUE", "INDEX"
         3168  +			    "OUTOFRANGE", NULL);
         3169  +		    result = TCL_ERROR;
         3170  +		}
         3171  +		if (result == TCL_ERROR) {
  3143   3172   		    Tcl_AppendObjToErrorInfo(interp, Tcl_ObjPrintf(
  3144   3173   			    "\n    (-index option item number %d)", j));
  3145         -		    result = TCL_ERROR;
  3146   3174   		    goto done;
  3147   3175   		}
         3176  +		sortInfo.indexv[j] = encoded;
  3148   3177   	    }
  3149   3178   	    break;
  3150   3179   	}
  3151   3180   	}
  3152   3181       }
  3153   3182   
  3154   3183       /*
  3155   3184        * Subindices only make sense if asked for with -index option set.
  3156   3185        */
  3157   3186   
  3158   3187       if (returnSubindices && sortInfo.indexc==0) {
  3159         -	if (startPtr != NULL) {
  3160         -	    Tcl_DecrRefCount(startPtr);
  3161         -	}
  3162   3188   	Tcl_SetObjResult(interp, Tcl_NewStringObj(
  3163   3189   		"-subindices cannot be used without -index option", -1));
  3164   3190   	Tcl_SetErrorCode(interp, "TCL", "OPERATION", "LSEARCH",
  3165   3191   		"BAD_OPTION_MIX", NULL);
  3166         -	return TCL_ERROR;
         3192  +	result = TCL_ERROR;
         3193  +	goto done;
  3167   3194       }
  3168   3195   
  3169   3196       if (bisect && (allMatches || negatedMatch)) {
  3170   3197   	Tcl_SetObjResult(interp, Tcl_NewStringObj(
  3171   3198   		"-bisect is not compatible with -all or -not", -1));
  3172   3199   	Tcl_SetErrorCode(interp, "TCL", "OPERATION", "LSEARCH",
  3173   3200   		"BAD_OPTION_MIX", NULL);
  3174         -	return TCL_ERROR;
         3201  +	result = TCL_ERROR;
         3202  +	goto done;
  3175   3203       }
  3176   3204   
  3177   3205       if (mode == REGEXP) {
  3178   3206   	/*
  3179   3207   	 * We can shimmer regexp/list if listv[i] == pattern, so get the
  3180   3208   	 * regexp rep before the list rep. First time round, omit the interp
  3181   3209   	 * and hope that the compilation will succeed. If it fails, we'll
................................................................................
  3193   3221   	     */
  3194   3222   
  3195   3223   	    regexp = Tcl_GetRegExpFromObj(interp, objv[objc - 1],
  3196   3224   		    TCL_REG_ADVANCED | (noCase ? TCL_REG_NOCASE : 0));
  3197   3225   	}
  3198   3226   
  3199   3227   	if (regexp == NULL) {
  3200         -	    if (startPtr != NULL) {
  3201         -		Tcl_DecrRefCount(startPtr);
  3202         -	    }
  3203   3228   	    result = TCL_ERROR;
  3204   3229   	    goto done;
  3205   3230   	}
  3206   3231       }
  3207   3232   
  3208   3233       /*
  3209   3234        * Make sure the list argument is a list object and get its length and a
  3210   3235        * pointer to its array of element pointers.
  3211   3236        */
  3212   3237   
  3213   3238       result = TclListObjGetElements(interp, objv[objc - 2], &listc, &listv);
  3214   3239       if (result != TCL_OK) {
  3215         -	if (startPtr != NULL) {
  3216         -	    Tcl_DecrRefCount(startPtr);
  3217         -	}
  3218   3240   	goto done;
  3219   3241       }
         3242  +
         3243  +    /*
         3244  +     * Check for sanity when grouping elements of the overall list together
         3245  +     * because of the -stride option. [TIP #351]
         3246  +     */
         3247  +
         3248  +    if (groupSize > 1) {
         3249  +	if (listc % groupSize) {
         3250  +	    Tcl_SetObjResult(interp, Tcl_NewStringObj(
         3251  +		    "list size must be a multiple of the stride length",
         3252  +		    -1));
         3253  +	    Tcl_SetErrorCode(interp, "TCL", "OPERATION", "LSEARCH", "BADSTRIDE",
         3254  +		    NULL);
         3255  +	    result = TCL_ERROR;
         3256  +	    goto done;
         3257  +	}
         3258  +	if (sortInfo.indexc > 0) {
         3259  +	    /*
         3260  +	     * Use the first value in the list supplied to -index as the
         3261  +	     * offset of the element within each group by which to sort.
         3262  +	     */
         3263  +
         3264  +	    groupOffset = TclIndexDecode(sortInfo.indexv[0], groupSize - 1);
         3265  +	    if (groupOffset < 0 || groupOffset >= groupSize) {
         3266  +		Tcl_SetObjResult(interp, Tcl_NewStringObj(
         3267  +			"when used with \"-stride\", the leading \"-index\""
         3268  +			" value must be within the group", -1));
         3269  +		Tcl_SetErrorCode(interp, "TCL", "OPERATION", "LSEARCH",
         3270  +			"BADINDEX", NULL);
         3271  +		result = TCL_ERROR;
         3272  +		goto done;
         3273  +	    }
         3274  +	    if (sortInfo.indexc == 1) {
         3275  +		sortInfo.indexc = 0;
         3276  +		sortInfo.indexv = NULL;
         3277  +	    } else {
         3278  +		sortInfo.indexc--;
         3279  +
         3280  +		for (i = 0; i < sortInfo.indexc; i++) {
         3281  +		    sortInfo.indexv[i] = sortInfo.indexv[i+1];
         3282  +		}
         3283  +	    }
         3284  +	}
         3285  +    }
  3220   3286   
  3221   3287       /*
  3222   3288        * Get the user-specified start offset.
  3223   3289        */
  3224   3290   
  3225   3291       if (startPtr) {
  3226         -	result = TclGetIntForIndexM(interp, startPtr, listc-1, &offset);
  3227         -	Tcl_DecrRefCount(startPtr);
         3292  +	result = TclGetIntForIndexM(interp, startPtr, listc-1, &start);
  3228   3293   	if (result != TCL_OK) {
  3229   3294   	    goto done;
  3230   3295   	}
  3231         -	if (offset < 0) {
  3232         -	    offset = 0;
         3296  +	if (start < 0) {
         3297  +	    start = 0;
  3233   3298   	}
  3234   3299   
  3235   3300   	/*
  3236   3301   	 * If the search started past the end of the list, we just return a
  3237   3302   	 * "did not match anything at all" result straight away. [Bug 1374778]
  3238   3303   	 */
  3239   3304   
  3240         -	if (offset > listc-1) {
  3241         -	    if (sortInfo.indexc > 1) {
  3242         -		TclStackFree(interp, sortInfo.indexv);
  3243         -	    }
         3305  +	if (start > listc-1) {
  3244   3306   	    if (allMatches || inlineReturn) {
  3245   3307   		Tcl_ResetResult(interp);
  3246   3308   	    } else {
  3247   3309   		Tcl_SetObjResult(interp, Tcl_NewIntObj(-1));
  3248   3310   	    }
  3249         -	    return TCL_OK;
         3311  +	    goto done;
         3312  +	}
         3313  +
         3314  +	/*
         3315  +	 * If start points within a group, it points to the start of the group.
         3316  +	 */
         3317  +
         3318  +	if (groupSize > 1) {
         3319  +	    start -= (start % groupSize);
  3250   3320   	}
  3251   3321       }
  3252   3322   
  3253   3323       patObj = objv[objc - 1];
  3254   3324       patternBytes = NULL;
  3255   3325       if (mode == EXACT || mode == SORTED) {
  3256   3326   	switch ((enum datatypes) dataType) {
................................................................................
  3301   3371   	/*
  3302   3372   	 * If the data is sorted, we can do a more intelligent search. Note
  3303   3373   	 * that there is no point in being smart when -all was specified; in
  3304   3374   	 * that case, we have to look at all items anyway, and there is no
  3305   3375   	 * sense in doing this when the match sense is inverted.
  3306   3376   	 */
  3307   3377   
  3308         -	lower = offset - 1;
         3378  +	/* 
         3379  +	 * With -stride, lower, upper and i are kept as multiples of groupSize.
         3380  +	 */
         3381  +
         3382  +	lower = start - groupSize;
  3309   3383   	upper = listc;
  3310         -	while (lower + 1 != upper && sortInfo.resultCode == TCL_OK) {
         3384  +	while (lower + groupSize != upper && sortInfo.resultCode == TCL_OK) {
  3311   3385   	    i = (lower + upper)/2;
         3386  +	    i -= i % groupSize;
  3312   3387   	    if (sortInfo.indexc != 0) {
  3313         -		itemPtr = SelectObjFromSublist(listv[i], &sortInfo);
         3388  +		itemPtr = SelectObjFromSublist(listv[i+groupOffset], &sortInfo);
  3314   3389   		if (sortInfo.resultCode != TCL_OK) {
  3315   3390   		    result = sortInfo.resultCode;
  3316   3391   		    goto done;
  3317   3392   		}
  3318   3393   	    } else {
  3319         -		itemPtr = listv[i];
         3394  +		itemPtr = listv[i+groupOffset];
  3320   3395   	    }
  3321   3396   	    switch ((enum datatypes) dataType) {
  3322   3397   	    case ASCII:
  3323   3398   		bytes = TclGetString(itemPtr);
  3324   3399   		match = strCmpFn(patternBytes, bytes);
  3325   3400   		break;
  3326   3401   	    case DICTIONARY:
................................................................................
  3401   3476   	 *   - our matching sense is negated
  3402   3477   	 *   - we're building a list of all matched items
  3403   3478   	 */
  3404   3479   
  3405   3480   	if (allMatches) {
  3406   3481   	    listPtr = Tcl_NewListObj(0, NULL);
  3407   3482   	}
  3408         -	for (i = offset; i < listc; i++) {
         3483  +	for (i = start; i < listc; i += groupSize) {
  3409   3484   	    match = 0;
  3410   3485   	    if (sortInfo.indexc != 0) {
  3411         -		itemPtr = SelectObjFromSublist(listv[i], &sortInfo);
         3486  +		itemPtr = SelectObjFromSublist(listv[i+groupOffset], &sortInfo);
  3412   3487   		if (sortInfo.resultCode != TCL_OK) {
  3413   3488   		    if (listPtr != NULL) {
  3414   3489   			Tcl_DecrRefCount(listPtr);
  3415   3490   		    }
  3416   3491   		    result = sortInfo.resultCode;
  3417   3492   		    goto done;
  3418   3493   		}
  3419   3494   	    } else {
  3420         -		itemPtr = listv[i];
         3495  +		itemPtr = listv[i+groupOffset];
  3421   3496   	    }
  3422   3497   
  3423   3498   	    switch (mode) {
  3424   3499   	    case SORTED:
  3425   3500   	    case EXACT:
  3426   3501   		switch ((enum datatypes) dataType) {
  3427   3502   		case ASCII:
................................................................................
  3503   3578   		break;
  3504   3579   	    } else if (inlineReturn) {
  3505   3580   		/*
  3506   3581   		 * Note that these appends are not expected to fail.
  3507   3582   		 */
  3508   3583   
  3509   3584   		if (returnSubindices && (sortInfo.indexc != 0)) {
  3510         -		    itemPtr = SelectObjFromSublist(listv[i], &sortInfo);
         3585  +		    itemPtr = SelectObjFromSublist(listv[i+groupOffset],
         3586  +			    &sortInfo);
         3587  +		    Tcl_ListObjAppendElement(interp, listPtr, itemPtr);
         3588  +		} else if (groupSize > 1) {
         3589  +		    Tcl_ListObjReplace(interp, listPtr, LIST_MAX, 0,
         3590  +			    groupSize, &listv[i]);
  3511   3591   		} else {
  3512   3592   		    itemPtr = listv[i];
         3593  +		    Tcl_ListObjAppendElement(interp, listPtr, itemPtr);
  3513   3594   		}
  3514         -		Tcl_ListObjAppendElement(interp, listPtr, itemPtr);
  3515   3595   	    } else if (returnSubindices) {
  3516   3596   		int j;
  3517   3597   
  3518         -		itemPtr = Tcl_NewIntObj(i);
         3598  +		itemPtr = Tcl_NewIntObj(i+groupOffset);
  3519   3599   		for (j=0 ; j<sortInfo.indexc ; j++) {
  3520         -		    Tcl_ListObjAppendElement(interp, itemPtr,
  3521         -			    Tcl_NewIntObj(sortInfo.indexv[j]));
         3600  +		    Tcl_ListObjAppendElement(interp, itemPtr, Tcl_NewIntObj(
         3601  +			    TclIndexDecode(sortInfo.indexv[j], listc)));
  3522   3602   		}
  3523   3603   		Tcl_ListObjAppendElement(interp, listPtr, itemPtr);
  3524   3604   	    } else {
  3525   3605   		Tcl_ListObjAppendElement(interp, listPtr, Tcl_NewIntObj(i));
  3526   3606   	    }
  3527   3607   	}
  3528   3608       }
................................................................................
  3533   3613   
  3534   3614       if (allMatches) {
  3535   3615   	Tcl_SetObjResult(interp, listPtr);
  3536   3616       } else if (!inlineReturn) {
  3537   3617   	if (returnSubindices) {
  3538   3618   	    int j;
  3539   3619   
  3540         -	    itemPtr = Tcl_NewIntObj(index);
         3620  +	    itemPtr = Tcl_NewIntObj(index+groupOffset);
  3541   3621   	    for (j=0 ; j<sortInfo.indexc ; j++) {
  3542         -		Tcl_ListObjAppendElement(interp, itemPtr,
  3543         -			Tcl_NewIntObj(sortInfo.indexv[j]));
         3622  +		Tcl_ListObjAppendElement(interp, itemPtr, Tcl_NewIntObj(
         3623  +			TclIndexDecode(sortInfo.indexv[j], listc)));
  3544   3624   	    }
  3545   3625   	    Tcl_SetObjResult(interp, itemPtr);
  3546   3626   	} else {
  3547   3627   	    Tcl_SetObjResult(interp, Tcl_NewIntObj(index));
  3548   3628   	}
  3549   3629       } else if (index < 0) {
  3550   3630   	/*
  3551   3631   	 * Is this superfluous? The result should be a blank object by
  3552   3632   	 * default...
  3553   3633   	 */
  3554   3634   
  3555   3635   	Tcl_SetObjResult(interp, Tcl_NewObj());
  3556   3636       } else {
  3557         -	Tcl_SetObjResult(interp, listv[index]);
         3637  +	if (returnSubindices) {
         3638  +	    Tcl_SetObjResult(interp, SelectObjFromSublist(listv[i+groupOffset],
         3639  +		    &sortInfo));
         3640  +	} else if (groupSize > 1) {
         3641  +	    Tcl_SetObjResult(interp, Tcl_NewListObj(groupSize, &listv[index]));
         3642  +	} else {
         3643  +	    Tcl_SetObjResult(interp, listv[index]);
         3644  +	}
  3558   3645       }
  3559   3646       result = TCL_OK;
  3560   3647   
  3561   3648       /*
  3562   3649        * Cleanup the index list array.
  3563   3650        */
  3564   3651   
  3565   3652     done:
  3566         -    if (sortInfo.indexc > 1) {
         3653  +    if (startPtr != NULL) {
         3654  +	Tcl_DecrRefCount(startPtr);
         3655  +    }
         3656  +    if (allocatedIndexVector) {
  3567   3657   	TclStackFree(interp, sortInfo.indexv);
  3568   3658       }
  3569   3659       return result;
  3570   3660   }
  3571   3661   
  3572   3662   /*
  3573   3663    *----------------------------------------------------------------------
................................................................................
  3678   3768       int objc,			/* Number of arguments. */
  3679   3769       Tcl_Obj *const objv[])	/* Argument values. */
  3680   3770   {
  3681   3771       int i, j, index, indices, length, nocase = 0, indexc;
  3682   3772       int sortMode = SORTMODE_ASCII;
  3683   3773       int group, groupSize, groupOffset, idx, allocatedIndexVector = 0;
  3684   3774       Tcl_Obj *resultPtr, *cmdPtr, **listObjPtrs, *listObj, *indexPtr;
  3685         -    SortElement *elementArray, *elementPtr;
         3775  +    SortElement *elementArray = NULL, *elementPtr;
  3686   3776       SortInfo sortInfo;		/* Information about this sort that needs to
  3687   3777   				 * be passed to the comparison function. */
  3688   3778   #   define NUM_LISTS 30
  3689   3779       SortElement *subList[NUM_LISTS+1];
  3690   3780   				/* This array holds pointers to temporary
  3691   3781   				 * lists built during the merge sort. Element
  3692   3782   				 * i of the array holds a list of length
................................................................................
  3724   3814       groupSize = 1;
  3725   3815       groupOffset = 0;
  3726   3816       indexPtr = NULL;
  3727   3817       for (i = 1; i < objc-1; i++) {
  3728   3818   	if (Tcl_GetIndexFromObj(interp, objv[i], switches, "option", 0,
  3729   3819   		&index) != TCL_OK) {
  3730   3820   	    sortInfo.resultCode = TCL_ERROR;
  3731         -	    goto done2;
         3821  +	    goto done;
  3732   3822   	}
  3733   3823   	switch ((enum Lsort_Switches) index) {
  3734   3824   	case LSORT_ASCII:
  3735   3825   	    sortInfo.sortMode = SORTMODE_ASCII;
  3736   3826   	    break;
  3737   3827   	case LSORT_COMMAND:
  3738   3828   	    if (i == objc-2) {
  3739   3829   		Tcl_SetObjResult(interp, Tcl_NewStringObj(
  3740   3830   			"\"-command\" option must be followed "
  3741   3831   			"by comparison command", -1));
  3742   3832   		Tcl_SetErrorCode(interp, "TCL", "ARGUMENT", "MISSING", NULL);
  3743   3833   		sortInfo.resultCode = TCL_ERROR;
  3744         -		goto done2;
         3834  +		goto done;
  3745   3835   	    }
  3746   3836   	    sortInfo.sortMode = SORTMODE_COMMAND;
  3747   3837   	    cmdPtr = objv[i+1];
  3748   3838   	    i++;
  3749   3839   	    break;
  3750   3840   	case LSORT_DECREASING:
  3751   3841   	    sortInfo.isIncreasing = 0;
................................................................................
  3753   3843   	case LSORT_DICTIONARY:
  3754   3844   	    sortInfo.sortMode = SORTMODE_DICTIONARY;
  3755   3845   	    break;
  3756   3846   	case LSORT_INCREASING:
  3757   3847   	    sortInfo.isIncreasing = 1;
  3758   3848   	    break;
  3759   3849   	case LSORT_INDEX: {
  3760         -	    int indexc, dummy;
         3850  +	    int indexc;
  3761   3851   	    Tcl_Obj **indexv;
  3762   3852   
  3763   3853   	    if (i == objc-2) {
  3764   3854   		Tcl_SetObjResult(interp, Tcl_NewStringObj(
  3765   3855   			"\"-index\" option must be followed by list index",
  3766   3856   			-1));
  3767   3857   		Tcl_SetErrorCode(interp, "TCL", "ARGUMENT", "MISSING", NULL);
  3768   3858   		sortInfo.resultCode = TCL_ERROR;
  3769         -		goto done2;
         3859  +		goto done;
  3770   3860   	    }
  3771   3861   	    if (TclListObjGetElements(interp, objv[i+1], &indexc,
  3772   3862   		    &indexv) != TCL_OK) {
  3773   3863   		sortInfo.resultCode = TCL_ERROR;
  3774         -		goto done2;
         3864  +		goto done;
  3775   3865   	    }
  3776   3866   
  3777   3867   	    /*
  3778   3868   	     * Check each of the indices for syntactic correctness. Note that
  3779   3869   	     * we do not store the converted values here because we do not
  3780   3870   	     * know if this is the only -index option yet and so we can't
  3781   3871   	     * allocate any space; that happens after the scan through all the
  3782   3872   	     * options is done.
  3783   3873   	     */
  3784   3874   
  3785   3875   	    for (j=0 ; j<indexc ; j++) {
  3786         -		if (TclGetIntForIndexM(interp, indexv[j], SORTIDX_END,
  3787         -			&dummy) != TCL_OK) {
         3876  +		int encoded = 0;
         3877  +		int result = TclIndexEncode(interp, indexv[j],
         3878  +			TCL_INDEX_BEFORE, TCL_INDEX_AFTER, &encoded);
         3879  +
         3880  +		if ((result == TCL_OK) && ((encoded == TCL_INDEX_BEFORE)
         3881  +			|| (encoded == TCL_INDEX_AFTER))) {
         3882  +		    Tcl_SetObjResult(interp, Tcl_ObjPrintf(
         3883  +			    "index \"%s\" cannot select an element "
         3884  +			    "from any list", Tcl_GetString(indexv[j])));
         3885  +		    Tcl_SetErrorCode(interp, "TCL", "VALUE", "INDEX"
         3886  +			    "OUTOFRANGE", NULL);
         3887  +		    result = TCL_ERROR;
         3888  +		}
         3889  +		if (result == TCL_ERROR) {
  3788   3890   		    Tcl_AppendObjToErrorInfo(interp, Tcl_ObjPrintf(
  3789   3891   			    "\n    (-index option item number %d)", j));
  3790   3892   		    sortInfo.resultCode = TCL_ERROR;
  3791         -		    goto done2;
         3893  +		    goto done;
  3792   3894   		}
  3793   3895   	    }
  3794   3896   	    indexPtr = objv[i+1];
  3795   3897   	    i++;
  3796   3898   	    break;
  3797   3899   	}
  3798   3900   	case LSORT_INTEGER:
................................................................................
  3813   3915   	case LSORT_STRIDE:
  3814   3916   	    if (i == objc-2) {
  3815   3917   		Tcl_SetObjResult(interp, Tcl_NewStringObj(
  3816   3918   			"\"-stride\" option must be "
  3817   3919   			"followed by stride length", -1));
  3818   3920   		Tcl_SetErrorCode(interp, "TCL", "ARGUMENT", "MISSING", NULL);
  3819   3921   		sortInfo.resultCode = TCL_ERROR;
  3820         -		goto done2;
         3922  +		goto done;
  3821   3923   	    }
  3822   3924   	    if (Tcl_GetIntFromObj(interp, objv[i+1], &groupSize) != TCL_OK) {
  3823   3925   		sortInfo.resultCode = TCL_ERROR;
  3824         -		goto done2;
         3926  +		goto done;
  3825   3927   	    }
  3826   3928   	    if (groupSize < 2) {
  3827   3929   		Tcl_SetObjResult(interp, Tcl_NewStringObj(
  3828   3930   			"stride length must be at least 2", -1));
  3829   3931   		Tcl_SetErrorCode(interp, "TCL", "OPERATION", "LSORT",
  3830   3932   			"BADSTRIDE", NULL);
  3831   3933   		sortInfo.resultCode = TCL_ERROR;
  3832         -		goto done2;
         3934  +		goto done;
  3833   3935   	    }
  3834   3936   	    group = 1;
  3835   3937   	    i++;
  3836   3938   	    break;
  3837   3939   	}
  3838   3940       }
  3839   3941       if (nocase && (sortInfo.sortMode == SORTMODE_ASCII)) {
................................................................................
  3860   3962   	default:
  3861   3963   	    sortInfo.indexv =
  3862   3964   		    TclStackAlloc(interp, sizeof(int) * sortInfo.indexc);
  3863   3965   	    allocatedIndexVector = 1;	/* Cannot use indexc field, as it
  3864   3966   					 * might be decreased by 1 later. */
  3865   3967   	}
  3866   3968   	for (j=0 ; j<sortInfo.indexc ; j++) {
  3867         -	    TclGetIntForIndexM(interp, indexv[j], SORTIDX_END,
  3868         -		    &sortInfo.indexv[j]);
         3969  +	    /* Prescreened values, no errors or out of range possible */
         3970  +	    TclIndexEncode(NULL, indexv[j], 0, 0, &sortInfo.indexv[j]);
  3869   3971   	}
  3870   3972       }
  3871   3973   
  3872   3974       listObj = objv[objc-1];
  3873   3975   
  3874   3976       if (sortInfo.sortMode == SORTMODE_COMMAND) {
  3875   3977   	Tcl_Obj *newCommandPtr, *newObjPtr;
................................................................................
  3880   3982   	 * underneath our feet. Take a copy (cheap) to prevent this. [Bug
  3881   3983   	 * 1675116]
  3882   3984   	 */
  3883   3985   
  3884   3986   	listObj = TclListObjCopy(interp, listObj);
  3885   3987   	if (listObj == NULL) {
  3886   3988   	    sortInfo.resultCode = TCL_ERROR;
  3887         -	    goto done2;
         3989  +	    goto done;
  3888   3990   	}
  3889   3991   
  3890   3992   	/*
  3891   3993   	 * The existing command is a list. We want to flatten it, append two
  3892   3994   	 * dummy arguments on the end, and replace these arguments later.
  3893   3995   	 */
  3894   3996   
................................................................................
  3898   4000   	if (Tcl_ListObjAppendElement(interp, newCommandPtr, newObjPtr)
  3899   4001   		!= TCL_OK) {
  3900   4002   	    TclDecrRefCount(newCommandPtr);
  3901   4003   	    TclDecrRefCount(listObj);
  3902   4004   	    Tcl_IncrRefCount(newObjPtr);
  3903   4005   	    TclDecrRefCount(newObjPtr);
  3904   4006   	    sortInfo.resultCode = TCL_ERROR;
  3905         -	    goto done2;
         4007  +	    goto done;
  3906   4008   	}
  3907   4009   	Tcl_ListObjAppendElement(interp, newCommandPtr, Tcl_NewObj());
  3908   4010   	sortInfo.compareCmdPtr = newCommandPtr;
  3909   4011       }
  3910   4012   
  3911   4013       sortInfo.resultCode = TclListObjGetElements(interp, listObj,
  3912   4014   	    &length, &listObjPtrs);
................................................................................
  3932   4034   	length = length / groupSize;
  3933   4035   	if (sortInfo.indexc > 0) {
  3934   4036   	    /*
  3935   4037   	     * Use the first value in the list supplied to -index as the
  3936   4038   	     * offset of the element within each group by which to sort.
  3937   4039   	     */
  3938   4040   
  3939         -	    groupOffset = sortInfo.indexv[0];
  3940         -	    if (groupOffset <= SORTIDX_END) {
  3941         -		groupOffset = (groupOffset - SORTIDX_END) + groupSize - 1;
  3942         -	    }
         4041  +	    groupOffset = TclIndexDecode(sortInfo.indexv[0], groupSize - 1);
  3943   4042   	    if (groupOffset < 0 || groupOffset >= groupSize) {
  3944   4043   		Tcl_SetObjResult(interp, Tcl_NewStringObj(
  3945   4044   			"when used with \"-stride\", the leading \"-index\""
  3946   4045   			" value must be within the group", -1));
  3947   4046   		Tcl_SetErrorCode(interp, "TCL", "OPERATION", "LSORT",
  3948   4047   			"BADINDEX", NULL);
  3949   4048   		sortInfo.resultCode = TCL_ERROR;
................................................................................
  3954   4053   		sortInfo.indexv = NULL;
  3955   4054   	    } else {
  3956   4055   		sortInfo.indexc--;
  3957   4056   
  3958   4057   		/*
  3959   4058   		 * Do not shrink the actual memory block used; that doesn't
  3960   4059   		 * work with TclStackAlloc-allocated memory. [Bug 2918962]
         4060  +		 * 
         4061  +		 * TODO: Consider a pointer increment to replace this
         4062  +		 * array shift.
  3961   4063   		 */
  3962   4064   
  3963   4065   		for (i = 0; i < sortInfo.indexc; i++) {
  3964   4066   		    sortInfo.indexv[i] = sortInfo.indexv[i+1];
  3965   4067   		}
  3966   4068   	    }
  3967   4069   	}
................................................................................
  3991   4093       }
  3992   4094   
  3993   4095       /*
  3994   4096        * The following loop creates a SortElement for each list element and
  3995   4097        * begins sorting it into the sublists as it appears.
  3996   4098        */
  3997   4099   
  3998         -    elementArray = TclStackAlloc(interp, length * sizeof(SortElement));
         4100  +    elementArray = ckalloc(length * sizeof(SortElement));
  3999   4101   
  4000   4102       for (i=0; i < length; i++){
  4001   4103   	idx = groupSize * i + groupOffset;
  4002   4104   	if (indexc) {
  4003   4105   	    /*
  4004   4106   	     * If this is an indexed sort, retrieve the corresponding element
  4005   4107   	     */
  4006   4108   	    indexPtr = SelectObjFromSublist(listObjPtrs[idx], &sortInfo);
  4007   4109   	    if (sortInfo.resultCode != TCL_OK) {
  4008         -		goto done1;
         4110  +		goto done;
  4009   4111   	    }
  4010   4112   	} else {
  4011   4113   	    indexPtr = listObjPtrs[idx];
  4012   4114   	}
  4013   4115   
  4014   4116   	/*
  4015   4117   	 * Determine the "value" of this object for sorting purposes
................................................................................
  4018   4120   	if (sortMode == SORTMODE_ASCII) {
  4019   4121   	    elementArray[i].collationKey.strValuePtr = TclGetString(indexPtr);
  4020   4122   	} else if (sortMode == SORTMODE_INTEGER) {
  4021   4123   	    Tcl_WideInt a;
  4022   4124   
  4023   4125   	    if (TclGetWideIntFromObj(sortInfo.interp, indexPtr, &a) != TCL_OK) {
  4024   4126   		sortInfo.resultCode = TCL_ERROR;
  4025         -		goto done1;
         4127  +		goto done;
  4026   4128   	    }
  4027   4129   	    elementArray[i].collationKey.wideValue = a;
  4028   4130   	} else if (sortMode == SORTMODE_REAL) {
  4029   4131   	    double a;
  4030   4132   
  4031   4133   	    if (Tcl_GetDoubleFromObj(sortInfo.interp, indexPtr,
  4032   4134   		    &a) != TCL_OK) {
  4033   4135   		sortInfo.resultCode = TCL_ERROR;
  4034         -		goto done1;
         4136  +		goto done;
  4035   4137   	    }
  4036   4138   	    elementArray[i].collationKey.doubleValue = a;
  4037   4139   	} else {
  4038   4140   	    elementArray[i].collationKey.objValuePtr = indexPtr;
  4039   4141   	}
  4040   4142   
  4041   4143   	/*
................................................................................
  4114   4216   		Tcl_IncrRefCount(objPtr);
  4115   4217   	    }
  4116   4218   	}
  4117   4219   	listRepPtr->elemCount = i;
  4118   4220   	Tcl_SetObjResult(interp, resultPtr);
  4119   4221       }
  4120   4222   
  4121         -  done1:
  4122         -    TclStackFree(interp, elementArray);
  4123         -
  4124   4223     done:
  4125   4224       if (sortMode == SORTMODE_COMMAND) {
  4126   4225   	TclDecrRefCount(sortInfo.compareCmdPtr);
  4127   4226   	TclDecrRefCount(listObj);
  4128   4227   	sortInfo.compareCmdPtr = NULL;
  4129   4228       }
  4130         -  done2:
  4131   4229       if (allocatedIndexVector) {
  4132   4230   	TclStackFree(interp, sortInfo.indexv);
         4231  +    }
         4232  +    if (elementArray) {
         4233  +	ckfree(elementArray);
  4133   4234       }
  4134   4235       return sortInfo.resultCode;
  4135   4236   }
  4136   4237   
  4137   4238   /*
  4138   4239    *----------------------------------------------------------------------
  4139   4240    *
................................................................................
  4260   4361   				/* Values to be compared. */
  4261   4362       SortInfo *infoPtr)		/* Information passed from the top-level
  4262   4363   				 * "lsort" command. */
  4263   4364   {
  4264   4365       int order = 0;
  4265   4366   
  4266   4367       if (infoPtr->sortMode == SORTMODE_ASCII) {
  4267         -	order = strcmp(elemPtr1->collationKey.strValuePtr,
         4368  +	order = TclUtfCmp(elemPtr1->collationKey.strValuePtr,
  4268   4369   		elemPtr2->collationKey.strValuePtr);
  4269   4370       } else if (infoPtr->sortMode == SORTMODE_ASCII_NC) {
  4270   4371   	order = TclUtfCasecmp(elemPtr1->collationKey.strValuePtr,
  4271   4372   		elemPtr2->collationKey.strValuePtr);
  4272   4373       } else if (infoPtr->sortMode == SORTMODE_DICTIONARY) {
  4273   4374   	order = DictionaryCompare(elemPtr1->collationKey.strValuePtr,
  4274   4375   		elemPtr2->collationKey.strValuePtr);
................................................................................
  4367   4468    *----------------------------------------------------------------------
  4368   4469    */
  4369   4470   
  4370   4471   static int
  4371   4472   DictionaryCompare(
  4372   4473       const char *left, const char *right)	/* The strings to compare. */
  4373   4474   {
  4374         -    Tcl_UniChar uniLeft, uniRight, uniLeftLower, uniRightLower;
         4475  +    Tcl_UniChar uniLeft = 0, uniRight = 0, uniLeftLower, uniRightLower;
  4375   4476       int diff, zeros;
  4376   4477       int secondaryDiff = 0;
  4377   4478   
  4378   4479       while (1) {
  4379   4480   	if (isdigit(UCHAR(*right))		/* INTL: digit */
  4380   4481   		&& isdigit(UCHAR(*left))) {	/* INTL: digit */
  4381   4482   	    /*
................................................................................
  4436   4537   	/*
  4437   4538   	 * Convert character to Unicode for comparison purposes. If either
  4438   4539   	 * string is at the terminating null, do a byte-wise comparison and
  4439   4540   	 * bail out immediately.
  4440   4541   	 */
  4441   4542   
  4442   4543   	if ((*left != '\0') && (*right != '\0')) {
  4443         -	    left += Tcl_UtfToUniChar(left, &uniLeft);
  4444         -	    right += Tcl_UtfToUniChar(right, &uniRight);
         4544  +	    left += TclUtfToUniChar(left, &uniLeft);
         4545  +	    right += TclUtfToUniChar(right, &uniRight);
  4445   4546   
  4446   4547   	    /*
  4447   4548   	     * Convert both chars to lower for the comparison, because
  4448   4549   	     * dictionary sorts are case insensitve. Covert to lower, not
  4449   4550   	     * upper, so chars between Z and a will sort before A (where most
  4450   4551   	     * other interesting punctuations occur).
  4451   4552   	     */
................................................................................
  4523   4624   	int listLen, index;
  4524   4625   	Tcl_Obj *currentObj;
  4525   4626   
  4526   4627   	if (TclListObjLength(infoPtr->interp, objPtr, &listLen) != TCL_OK) {
  4527   4628   	    infoPtr->resultCode = TCL_ERROR;
  4528   4629   	    return NULL;
  4529   4630   	}
  4530         -	index = infoPtr->indexv[i];
  4531   4631   
  4532         -	/*
  4533         -	 * Adjust for end-based indexing.
  4534         -	 */
  4535         -
  4536         -	if (index < SORTIDX_NONE) {
  4537         -	    index += listLen + 1;
  4538         -	}
         4632  +	index = TclIndexDecode(infoPtr->indexv[i], listLen - 1);
  4539   4633   
  4540   4634   	if (Tcl_ListObjIndex(infoPtr->interp, objPtr, index,
  4541   4635   		&currentObj) != TCL_OK) {
  4542   4636   	    infoPtr->resultCode = TCL_ERROR;
  4543   4637   	    return NULL;
  4544   4638   	}
  4545   4639   	if (currentObj == NULL) {

Changes to generic/tclCmdMZ.c.

   305    305   	 * start of the string unless the previous character is a newline.
   306    306   	 */
   307    307   
   308    308   	if (offset == 0) {
   309    309   	    eflags = 0;
   310    310   	} else if (offset > stringLength) {
   311    311   	    eflags = TCL_REG_NOTBOL;
   312         -	} else if (Tcl_GetUniChar(objPtr, offset-1) == (Tcl_UniChar)'\n') {
          312  +	} else if (Tcl_GetUniChar(objPtr, offset-1) == '\n') {
   313    313   	    eflags = 0;
   314    314   	} else {
   315    315   	    eflags = TCL_REG_NOTBOL;
   316    316   	}
   317    317   
   318    318   	match = Tcl_RegExpExecObj(interp, regExpr, objPtr, offset,
   319    319   		numMatchesSaved, eflags);
................................................................................
   483    483   Tcl_RegsubObjCmd(
   484    484       ClientData dummy,		/* Not used. */
   485    485       Tcl_Interp *interp,		/* Current interpreter. */
   486    486       int objc,			/* Number of arguments. */
   487    487       Tcl_Obj *const objv[])	/* Argument objects. */
   488    488   {
   489    489       int idx, result, cflags, all, wlen, wsublen, numMatches, offset;
   490         -    int start, end, subStart, subEnd, match;
          490  +    int start, end, subStart, subEnd, match, command, numParts;
   491    491       Tcl_RegExp regExpr;
   492    492       Tcl_RegExpInfo info;
   493    493       Tcl_Obj *resultPtr, *subPtr, *objPtr, *startIndex = NULL;
   494    494       Tcl_UniChar ch, *wsrc, *wfirstChar, *wstring, *wsubspec, *wend;
   495    495   
   496    496       static const char *const options[] = {
   497         -	"-all",		"-nocase",	"-expanded",
   498         -	"-line",	"-linestop",	"-lineanchor",	"-start",
          497  +	"-all",		"-command",	"-expanded",	"-line",
          498  +	"-linestop",	"-lineanchor",	"-nocase",	"-start",
   499    499   	"--",		NULL
   500    500       };
   501    501       enum options {
   502         -	REGSUB_ALL,	REGSUB_NOCASE,	REGSUB_EXPANDED,
   503         -	REGSUB_LINE,	REGSUB_LINESTOP, REGSUB_LINEANCHOR,	REGSUB_START,
          502  +	REGSUB_ALL,	 REGSUB_COMMAND,    REGSUB_EXPANDED, REGSUB_LINE,
          503  +	REGSUB_LINESTOP, REGSUB_LINEANCHOR, REGSUB_NOCASE,   REGSUB_START,
   504    504   	REGSUB_LAST
   505    505       };
   506    506   
   507    507       cflags = TCL_REG_ADVANCED;
   508    508       all = 0;
   509    509       offset = 0;
          510  +    command = 0;
   510    511       resultPtr = NULL;
   511    512   
   512    513       for (idx = 1; idx < objc; idx++) {
   513    514   	const char *name;
   514    515   	int index;
   515    516   
   516    517   	name = TclGetString(objv[idx]);
................................................................................
   523    524   	}
   524    525   	switch ((enum options) index) {
   525    526   	case REGSUB_ALL:
   526    527   	    all = 1;
   527    528   	    break;
   528    529   	case REGSUB_NOCASE:
   529    530   	    cflags |= TCL_REG_NOCASE;
          531  +	    break;
          532  +	case REGSUB_COMMAND:
          533  +	    command = 1;
   530    534   	    break;
   531    535   	case REGSUB_EXPANDED:
   532    536   	    cflags |= TCL_REG_EXPANDED;
   533    537   	    break;
   534    538   	case REGSUB_LINE:
   535    539   	    cflags |= TCL_REG_NEWLINE;
   536    540   	    break;
................................................................................
   581    585   	TclGetIntForIndexM(NULL, startIndex, stringLength, &offset);
   582    586   	Tcl_DecrRefCount(startIndex);
   583    587   	if (offset < 0) {
   584    588   	    offset = 0;
   585    589   	}
   586    590       }
   587    591   
   588         -    if (all && (offset == 0)
          592  +    if (all && (offset == 0) && (command == 0)
   589    593   	    && (strpbrk(TclGetString(objv[2]), "&\\") == NULL)
   590    594   	    && (strpbrk(TclGetString(objv[0]), "*+?{}()[].\\|^$") == NULL)) {
   591    595   	/*
   592    596   	 * This is a simple one pair string map situation. We make use of a
   593    597   	 * slightly modified version of the one pair STR_MAP code.
   594    598   	 */
   595    599   
................................................................................
   656    660   	goto regsubDone;
   657    661       }
   658    662   
   659    663       regExpr = Tcl_GetRegExpFromObj(interp, objv[0], cflags);
   660    664       if (regExpr == NULL) {
   661    665   	return TCL_ERROR;
   662    666       }
          667  +
          668  +    if (command) {
          669  +	/*
          670  +	 * In command-prefix mode, we require that the third non-option
          671  +	 * argument be a list, so we enforce that here. Afterwards, we fetch
          672  +	 * the RE compilation again in case objv[0] and objv[2] are the same
          673  +	 * object. (If they aren't, that's cheap to do.)
          674  +	 */
          675  +
          676  +	if (Tcl_ListObjLength(interp, objv[2], &numParts) != TCL_OK) {
          677  +	    return TCL_ERROR;
          678  +	}
          679  +	if (numParts < 1) {
          680  +	    Tcl_SetObjResult(interp, Tcl_NewStringObj(
          681  +		    "command prefix must be a list of at least one element",
          682  +		    -1));
          683  +	    Tcl_SetErrorCode(interp, "TCL", "OPERATION", "REGSUB",
          684  +		    "CMDEMPTY", NULL);
          685  +	    return TCL_ERROR;
          686  +	}
          687  +	regExpr = Tcl_GetRegExpFromObj(interp, objv[0], cflags);
          688  +    }
   663    689   
   664    690       /*
   665    691        * Make sure to avoid problems where the objects are shared. This can
   666    692        * cause RegExpObj <> UnicodeObj shimmering that causes data corruption.
   667    693        * [Bug #461322]
   668    694        */
   669    695   
................................................................................
   674    700       }
   675    701       wstring = Tcl_GetUnicodeFromObj(objPtr, &wlen);
   676    702       if (objv[2] == objv[0]) {
   677    703   	subPtr = Tcl_DuplicateObj(objv[2]);
   678    704       } else {
   679    705   	subPtr = objv[2];
   680    706       }
   681         -    wsubspec = Tcl_GetUnicodeFromObj(subPtr, &wsublen);
          707  +    if (!command) {
          708  +	wsubspec = Tcl_GetUnicodeFromObj(subPtr, &wsublen);
          709  +    }
   682    710   
   683    711       result = TCL_OK;
   684    712   
   685    713       /*
   686    714        * The following loop is to handle multiple matches within the same source
   687    715        * string; each iteration handles one match and its corresponding
   688    716        * substitution. If "-all" hasn't been specified then the loop body only
................................................................................
   731    759   	 * result variable.
   732    760   	 */
   733    761   
   734    762   	Tcl_RegExpGetInfo(regExpr, &info);
   735    763   	start = info.matches[0].start;
   736    764   	end = info.matches[0].end;
   737    765   	Tcl_AppendUnicodeToObj(resultPtr, wstring + offset, start);
          766  +
          767  +	/*
          768  +	 * In command-prefix mode, the substitutions are added as quoted
          769  +	 * arguments to the subSpec to form a command, that is then executed
          770  +	 * and the result used as the string to substitute in. Actually,
          771  +	 * everything is passed through Tcl_EvalObjv, as that's much faster.
          772  +	 */
          773  +
          774  +	if (command) {
          775  +	    Tcl_Obj **args = NULL, **parts;
          776  +	    int numArgs;
          777  +
          778  +	    Tcl_ListObjGetElements(interp, subPtr, &numParts, &parts);
          779  +	    numArgs = numParts + info.nsubs + 1;
          780  +	    args = ckalloc(sizeof(Tcl_Obj*) * numArgs);
          781  +	    memcpy(args, parts, sizeof(Tcl_Obj*) * numParts);
          782  +
          783  +	    for (idx = 0 ; idx <= info.nsubs ; idx++) {
          784  +		subStart = info.matches[idx].start;
          785  +		subEnd = info.matches[idx].end;
          786  +		if ((subStart >= 0) && (subEnd >= 0)) {
          787  +		    args[idx + numParts] = Tcl_NewUnicodeObj(
          788  +			    wstring + offset + subStart, subEnd - subStart);
          789  +		} else {
          790  +		    args[idx + numParts] = Tcl_NewObj();
          791  +		}
          792  +		Tcl_IncrRefCount(args[idx + numParts]);
          793  +	    }
          794  +
          795  +	    /*
          796  +	     * At this point, we're locally holding the references to the
          797  +	     * argument words we added for this time round the loop, and the
          798  +	     * subPtr is holding the references to the words that the user
          799  +	     * supplied directly. None are zero-refcount, which is important
          800  +	     * because Tcl_EvalObjv is "hairy monster" in terms of refcount
          801  +	     * handling, being able to optionally add references to any of its
          802  +	     * argument words. We'll drop the local refs immediately
          803  +	     * afterwards; subPtr is handled in the main exit stanza.
          804  +	     */
          805  +
          806  +	    result = Tcl_EvalObjv(interp, numArgs, args, 0);
          807  +	    for (idx = 0 ; idx <= info.nsubs ; idx++) {
          808  +		TclDecrRefCount(args[idx + numParts]);
          809  +	    }
          810  +	    ckfree(args);
          811  +	    if (result != TCL_OK) {
          812  +		if (result == TCL_ERROR) {
          813  +		    Tcl_AppendObjToErrorInfo(interp, Tcl_ObjPrintf(
          814  +			    "\n    (%s substitution computation script)",
          815  +			    options[REGSUB_COMMAND]));
          816  +		}
          817  +		goto done;
          818  +	    }
          819  +
          820  +	    Tcl_AppendObjToObj(resultPtr, Tcl_GetObjResult(interp));
          821  +	    Tcl_ResetResult(interp);
          822  +
          823  +	    /*
          824  +	     * Refetch the unicode, in case the representation was smashed by
          825  +	     * the user code.
          826  +	     */
          827  +
          828  +	    wstring = Tcl_GetUnicodeFromObj(objPtr, &wlen);
          829  +
          830  +	    offset += end;
          831  +	    if (end == 0 || start == end) {
          832  +		/*
          833  +		 * Always consume at least one character of the input string
          834  +		 * in order to prevent infinite loops, even when we
          835  +		 * technically matched the empty string; we must not match
          836  +		 * again at the same spot.
          837  +		 */
          838  +
          839  +		if (offset < wlen) {
          840  +		    Tcl_AppendUnicodeToObj(resultPtr, wstring + offset, 1);
          841  +		}
          842  +		offset++;
          843  +	    }
          844  +	    if (all) {
          845  +		continue;
          846  +	    } else {
          847  +		break;
          848  +	    }
          849  +	}
   738    850   
   739    851   	/*
   740    852   	 * Append the subSpec argument to the variable, making appropriate
   741    853   	 * substitutions. This code is a bit hairy because of the backslash
   742    854   	 * conventions and because the code saves up ranges of characters in
   743    855   	 * subSpec to reduce the number of calls to Tcl_SetVar.
   744    856   	 */
................................................................................
  1057   1169   int
  1058   1170   Tcl_SplitObjCmd(
  1059   1171       ClientData dummy,		/* Not used. */
  1060   1172       Tcl_Interp *interp,		/* Current interpreter. */
  1061   1173       int objc,			/* Number of arguments. */
  1062   1174       Tcl_Obj *const objv[])	/* Argument objects. */
  1063   1175   {
  1064         -    Tcl_UniChar ch;
         1176  +    Tcl_UniChar ch = 0;
  1065   1177       int len;
  1066   1178       const char *splitChars;
  1067   1179       const char *stringPtr;
  1068   1180       const char *end;
  1069   1181       int splitCharLen, stringLen;
  1070   1182       Tcl_Obj *listPtr, *objPtr;
  1071   1183   
................................................................................
  1100   1212   	 * is a *major* win when splitting on a long string (especially in the
  1101   1213   	 * megabyte range!) - DKF
  1102   1214   	 */
  1103   1215   
  1104   1216   	Tcl_InitHashTable(&charReuseTable, TCL_ONE_WORD_KEYS);
  1105   1217   
  1106   1218   	for ( ; stringPtr < end; stringPtr += len) {
         1219  +		int fullchar;
  1107   1220   	    len = TclUtfToUniChar(stringPtr, &ch);
         1221  +	    fullchar = ch;
         1222  +
         1223  +#if TCL_UTF_MAX == 4
         1224  +	    if (!len) {
         1225  +		len += TclUtfToUniChar(stringPtr, &ch);
         1226  +		fullchar = (((fullchar & 0x3ff) << 10) | (ch & 0x3ff)) + 0x10000;
         1227  +	    }
         1228  +#endif
  1108   1229   
  1109   1230   	    /*
  1110   1231   	     * Assume Tcl_UniChar is an integral type...
  1111   1232   	     */
  1112   1233   
  1113         -	    hPtr = Tcl_CreateHashEntry(&charReuseTable, INT2PTR((int) ch),
         1234  +	    hPtr = Tcl_CreateHashEntry(&charReuseTable, INT2PTR(fullchar),
  1114   1235   		    &isNew);
  1115   1236   	    if (isNew) {
  1116   1237   		TclNewStringObj(objPtr, stringPtr, len);
  1117   1238   
  1118   1239   		/*
  1119   1240   		 * Don't need to fiddle with refcount...
  1120   1241   		 */
................................................................................
  1142   1263   	    stringPtr = p + 1;
  1143   1264   	}
  1144   1265   	TclNewStringObj(objPtr, stringPtr, end - stringPtr);
  1145   1266   	Tcl_ListObjAppendElement(NULL, listPtr, objPtr);
  1146   1267       } else {
  1147   1268   	const char *element, *p, *splitEnd;
  1148   1269   	int splitLen;
  1149         -	Tcl_UniChar splitChar;
         1270  +	Tcl_UniChar splitChar = 0;
  1150   1271   
  1151   1272   	/*
  1152   1273   	 * Normal case: split on any of a given set of characters. Discard
  1153   1274   	 * instances of the split characters.
  1154   1275   	 */
  1155   1276   
  1156   1277   	splitEnd = splitChars + splitCharLen;
................................................................................
  1210   1331   
  1211   1332       if (objc == 4) {
  1212   1333   	int size = Tcl_GetCharLength(objv[2]);
  1213   1334   
  1214   1335   	if (TCL_OK != TclGetIntForIndexM(interp, objv[3], size - 1, &start)) {
  1215   1336   	    return TCL_ERROR;
  1216   1337   	}
  1217         -
  1218         -	if (start < 0) {
  1219         -	    start = 0;
  1220         -	}
  1221         -	if (start >= size) {
  1222         -	    Tcl_SetObjResult(interp, Tcl_NewIntObj(-1));
  1223         -	    return TCL_OK;
  1224         -	}
  1225   1338       }
  1226         -    Tcl_SetObjResult(interp, Tcl_NewIntObj(TclStringFind(objv[1],
         1339  +    Tcl_SetObjResult(interp, Tcl_NewIntObj(TclStringFirst(objv[1],
  1227   1340   	    objv[2], start)));
  1228   1341       return TCL_OK;
  1229   1342   }
  1230   1343   
  1231   1344   /*
  1232   1345    *----------------------------------------------------------------------
  1233   1346    *
................................................................................
  1263   1376   
  1264   1377       if (objc == 4) {
  1265   1378   	int size = Tcl_GetCharLength(objv[2]);
  1266   1379   
  1267   1380   	if (TCL_OK != TclGetIntForIndexM(interp, objv[3], size - 1, &last)) {
  1268   1381   	    return TCL_ERROR;
  1269   1382   	}
  1270         -
  1271         -	if (last < 0) {
  1272         -	    Tcl_SetObjResult(interp, Tcl_NewIntObj(-1));
  1273         -	    return TCL_OK;
  1274         -	}
  1275         -	if (last >= size) {
  1276         -	    last = size - 1;
  1277         -	}
  1278   1383       }
  1279   1384       Tcl_SetObjResult(interp, Tcl_NewIntObj(TclStringLast(objv[1],
  1280   1385   	    objv[2], last)));
  1281   1386       return TCL_OK;
  1282   1387   }
  1283   1388   
  1284   1389   /*
................................................................................
  1366   1471   StringIsCmd(
  1367   1472       ClientData dummy,		/* Not used. */
  1368   1473       Tcl_Interp *interp,		/* Current interpreter. */
  1369   1474       int objc,			/* Number of arguments. */
  1370   1475       Tcl_Obj *const objv[])	/* Argument objects. */
  1371   1476   {
  1372   1477       const char *string1, *end, *stop;
  1373         -    Tcl_UniChar ch;
         1478  +    Tcl_UniChar ch = 0;
  1374   1479       int (*chcomp)(int) = NULL;	/* The UniChar comparison function. */
  1375   1480       int i, failat = 0, result = 1, strict = 0, index, length1, length2;
  1376   1481       Tcl_Obj *objPtr, *failVarObj = NULL;
  1377   1482       Tcl_WideInt w;
  1378   1483   
  1379   1484       static const char *const isClasses[] = {
  1380   1485   	"alnum",	"alpha",	"ascii",	"control",
................................................................................
  1463   1568   		&& (TCL_OK != TclSetBooleanFromAny(NULL, objPtr))) {
  1464   1569   	    if (strict) {
  1465   1570   		result = 0;
  1466   1571   	    } else {
  1467   1572   		string1 = TclGetStringFromObj(objPtr, &length1);
  1468   1573   		result = length1 == 0;
  1469   1574   	    }
  1470         -	} else if (((index == STR_IS_TRUE) &&
  1471         -		objPtr->internalRep.longValue == 0)
  1472         -	    || ((index == STR_IS_FALSE) &&
  1473         -		objPtr->internalRep.longValue != 0)) {
  1474         -	    result = 0;
         1575  +	} else if (index != STR_IS_BOOL) {
         1576  +	    TclGetBooleanFromObj(NULL, objPtr, &i);
         1577  +	    if ((index == STR_IS_TRUE) ^ i) {
         1578  +		result = 0;
         1579  +	    }
  1475   1580   	}
  1476   1581   	break;
  1477   1582       case STR_IS_CONTROL:
  1478   1583   	chcomp = Tcl_UniCharIsControl;
  1479   1584   	break;
  1480   1585       case STR_IS_DIGIT:
  1481   1586   	chcomp = Tcl_UniCharIsDigit;
  1482   1587   	break;
  1483   1588       case STR_IS_DOUBLE: {
  1484   1589   	/* TODO */
  1485   1590   	if ((objPtr->typePtr == &tclDoubleType) ||
  1486   1591   		(objPtr->typePtr == &tclIntType) ||
  1487         -#ifndef TCL_WIDE_INT_IS_LONG
  1488         -		(objPtr->typePtr == &tclWideIntType) ||
  1489         -#endif
  1490   1592   		(objPtr->typePtr == &tclBignumType)) {
  1491   1593   	    break;
  1492   1594   	}
  1493   1595   	string1 = TclGetStringFromObj(objPtr, &length1);
  1494   1596   	if (length1 == 0) {
  1495   1597   	    if (strict) {
  1496   1598   		result = 0;
................................................................................
  1517   1619       case STR_IS_INT:
  1518   1620   	if (TCL_OK == TclGetIntFromObj(NULL, objPtr, &i)) {
  1519   1621   	    break;
  1520   1622   	}
  1521   1623   	goto failedIntParse;
  1522   1624       case STR_IS_ENTIER:
  1523   1625   	if ((objPtr->typePtr == &tclIntType) ||
  1524         -#ifndef TCL_WIDE_INT_IS_LONG
  1525         -		(objPtr->typePtr == &tclWideIntType) ||
  1526         -#endif
  1527   1626   		(objPtr->typePtr == &tclBignumType)) {
  1528   1627   	    break;
  1529   1628   	}
  1530   1629   	string1 = TclGetStringFromObj(objPtr, &length1);
  1531   1630   	if (length1 == 0) {
  1532   1631   	    if (strict) {
  1533   1632   		result = 0;
................................................................................
  1561   1660   	     */
  1562   1661   
  1563   1662   	    result = 0;
  1564   1663   	    failat = 0;
  1565   1664   	}
  1566   1665   	break;
  1567   1666       case STR_IS_WIDE:
  1568         -	if (TCL_OK == Tcl_GetWideIntFromObj(NULL, objPtr, &w)) {
         1667  +	if (TCL_OK == TclGetWideIntFromObj(NULL, objPtr, &w)) {
  1569   1668   	    break;
  1570   1669   	}
  1571   1670   
  1572   1671       failedIntParse:
  1573   1672   	string1 = TclGetStringFromObj(objPtr, &length1);
  1574   1673   	if (length1 == 0) {
  1575   1674   	    if (strict) {
................................................................................
  1698   1797   	    if (strict) {
  1699   1798   		result = 0;
  1700   1799   	    }
  1701   1800   	    goto str_is_done;
  1702   1801   	}
  1703   1802   	end = string1 + length1;
  1704   1803   	for (; string1 < end; string1 += length2, failat++) {
         1804  +	    int fullchar;
  1705   1805   	    length2 = TclUtfToUniChar(string1, &ch);
  1706         -	    if (!chcomp(ch)) {
         1806  +	    fullchar = ch;
         1807  +#if TCL_UTF_MAX == 4
         1808  +	    if (!length2) {
         1809  +	    	length2 = TclUtfToUniChar(string1, &ch);
         1810  +	    	fullchar = (((fullchar & 0x3ff) << 10) | (ch & 0x3ff)) + 0x10000;
         1811  +	    }
         1812  +#endif
         1813  +	    if (!chcomp(fullchar)) {
  1707   1814   		result = 0;
  1708   1815   		break;
  1709   1816   	    }
  1710   1817   	}
  1711   1818       }
  1712   1819   
  1713   1820       /*
................................................................................
  2161   2268       if (count == 1) {
  2162   2269   	Tcl_SetObjResult(interp, objv[1]);
  2163   2270   	return TCL_OK;
  2164   2271       } else if (count < 1) {
  2165   2272   	return TCL_OK;
  2166   2273       }
  2167   2274   
  2168         -    if (TCL_OK != TclStringRepeat(interp, objv[1], count, &resultPtr)) {
  2169         -	return TCL_ERROR;
         2275  +    resultPtr = TclStringRepeat(interp, objv[1], count, TCL_STRING_IN_PLACE);
         2276  +    if (resultPtr) {
         2277  +	Tcl_SetObjResult(interp, resultPtr);
         2278  +	return TCL_OK;
  2170   2279       }
  2171         -    Tcl_SetObjResult(interp, resultPtr);
  2172         -    return TCL_OK;
         2280  +    return TCL_ERROR;
  2173   2281   }
  2174   2282   
  2175   2283   /*
  2176   2284    *----------------------------------------------------------------------
  2177   2285    *
  2178   2286    * StringRplcCmd --
  2179   2287    *
................................................................................
  2193   2301   static int
  2194   2302   StringRplcCmd(
  2195   2303       ClientData dummy,		/* Not used. */
  2196   2304       Tcl_Interp *interp,		/* Current interpreter. */
  2197   2305       int objc,			/* Number of arguments. */
  2198   2306       Tcl_Obj *const objv[])	/* Argument objects. */
  2199   2307   {
  2200         -    Tcl_UniChar *ustring;
  2201         -    int first, last, length;
         2308  +    int first, last, length, end;
  2202   2309   
  2203   2310       if (objc < 4 || objc > 5) {
  2204   2311   	Tcl_WrongNumArgs(interp, 1, objv, "string first last ?string?");
  2205   2312   	return TCL_ERROR;
  2206   2313       }
  2207   2314   
  2208         -    ustring = Tcl_GetUnicodeFromObj(objv[1], &length);
  2209         -    length--;
         2315  +    length = Tcl_GetCharLength(objv[1]);
         2316  +    end = length - 1;
  2210   2317   
  2211         -    if (TclGetIntForIndexM(interp, objv[2], length, &first) != TCL_OK ||
  2212         -	    TclGetIntForIndexM(interp, objv[3], length, &last) != TCL_OK){
         2318  +    if (TclGetIntForIndexM(interp, objv[2], end, &first) != TCL_OK ||
         2319  +	    TclGetIntForIndexM(interp, objv[3], end, &last) != TCL_OK){
  2213   2320   	return TCL_ERROR;
  2214   2321       }
  2215   2322   
  2216         -    if ((last < first) || (last < 0) || (first > length)) {
         2323  +    /*
         2324  +     * The following test screens out most empty substrings as
         2325  +     * candidates for replacement. When they are detected, no
         2326  +     * replacement is done, and the result is the original string,
         2327  +     */
         2328  +    if ((last < 0) ||		/* Range ends before start of string */
         2329  +	    (first > end) ||	/* Range begins after end of string */
         2330  +	    (last < first)) {	/* Range begins after it starts */
         2331  +
         2332  +	/*
         2333  +	 * BUT!!! when (end < 0) -- an empty original string -- we can
         2334  +	 * have (first <= end < 0 <= last) and an empty string is permitted
         2335  +	 * to be replaced.
         2336  +	 */
  2217   2337   	Tcl_SetObjResult(interp, objv[1]);
  2218   2338       } else {
  2219   2339   	Tcl_Obj *resultPtr;
  2220   2340   
  2221         -	ustring = Tcl_GetUnicodeFromObj(objv[1], &length);
  2222         -	length--;
  2223         -
  2224   2341   	if (first < 0) {
  2225   2342   	    first = 0;
  2226   2343   	}
         2344  +	if (last > end) {
         2345  +	    last = end;
         2346  +	}
  2227   2347   
  2228         -	resultPtr = Tcl_NewUnicodeObj(ustring, first);
  2229         -	if (objc == 5) {
  2230         -	    Tcl_AppendObjToObj(resultPtr, objv[4]);
  2231         -	}
  2232         -	if (last < length) {
  2233         -	    Tcl_AppendUnicodeToObj(resultPtr, ustring + last + 1,
  2234         -		    length - last);
  2235         -	}
         2348  +	resultPtr = TclStringReplace(interp, objv[1], first,
         2349  +		last + 1 - first, (objc == 5) ? objv[4] : NULL,
         2350  +		TCL_STRING_IN_PLACE);
         2351  +
  2236   2352   	Tcl_SetObjResult(interp, resultPtr);
  2237   2353       }
  2238   2354       return TCL_OK;
  2239   2355   }
  2240   2356   
  2241   2357   /*
  2242   2358    *----------------------------------------------------------------------
................................................................................
  2264   2380       Tcl_Obj *const objv[])	/* Argument objects. */
  2265   2381   {
  2266   2382       if (objc != 2) {
  2267   2383   	Tcl_WrongNumArgs(interp, 1, objv, "string");
  2268   2384   	return TCL_ERROR;
  2269   2385       }
  2270   2386   
  2271         -    Tcl_SetObjResult(interp, TclStringObjReverse(objv[1]));
         2387  +    Tcl_SetObjResult(interp, TclStringReverse(objv[1], TCL_STRING_IN_PLACE));
  2272   2388       return TCL_OK;
  2273   2389   }
  2274   2390   
  2275   2391   /*
  2276   2392    *----------------------------------------------------------------------
  2277   2393    *
  2278   2394    * StringStartCmd --
................................................................................
  2294   2410   static int
  2295   2411   StringStartCmd(
  2296   2412       ClientData dummy,		/* Not used. */
  2297   2413       Tcl_Interp *interp,		/* Current interpreter. */
  2298   2414       int objc,			/* Number of ar