Tcl Source Code

Changes On Branch core_zip_vfs
Login
Bounty program for improvements to Tcl and certain Tcl packages.

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

Changes In Branch core_zip_vfs Excluding Merge-Ins

This is equivalent to a diff from 49e104fa48 to c9c0d29199

2018-09-12
19:30
TIP #430 implementation check-in: b74093feee user: jan.nijtmans tags: core-8-branch
2018-09-06
09:47
Code review check-in: 281daabd0b user: jan.nijtmans tags: core_zip_vfs-review
2018-08-14
08:46
Merging changes with 8.7 Closed-Leaf check-in: c9c0d29199 user: hypnotoad tags: core_zip_vfs
05:43
Reposition the MODULE_SCOPE definition so that packages like tbcload don't get an error when they in... check-in: 7e7c72ccc9 user: pooryorick tags: core-8-branch
2018-06-12
19:32
Adding typecasts in tclZipfs.c to eliminate a compiler warning check-in: ebd55b94e1 user: hypnotoad tags: core_zip_vfs
2017-11-13
08:59
merge tcl-9-cleanup (and also a minor bug-fix from core-8-branch). check-in: b03c4194f0 user: jan.nijtmans tags: trunk
2017-11-09
15:47
Rebase branch to trunk. check-in: f714eca8f2 user: dgp tags: dgp-refactor
14:44
merge trunk check-in: d27981d722 user: dgp tags: no-wideint
14:40
merge trunk Closed-Leaf check-in: 844ae11ba0 user: dgp tags: tcl-9-cleanup
13:46
merge trunk check-in: a10fc87c05 user: dgp tags: dgp-properbytearray
12:52
merge trunk check-in: 54f289e311 user: jan.nijtmans tags: novem
12:51
merge core-8-branch check-in: 49e104fa48 user: jan.nijtmans tags: trunk
12:50
merge core-8-6-branch check-in: ef4cc04bc1 user: jan.nijtmans tags: core-8-branch
2017-11-08
09:38
merge core-8-branch check-in: 3885b08997 user: jan.nijtmans tags: trunk

Changes to .fossil-settings/crlf-glob.

     8      8   libtommath/*.vcproj
     9      9   tools/tcl.hpj.in
    10     10   tools/tcl.wse.in
    11     11   win/buildall.vc.bat
    12     12   win/coffbase.txt
    13     13   win/makefile.vc
    14     14   win/rules.vc
           15  +win/rules-ext.vc
           16  +win/targets.vc
    15     17   win/tcl.dsp
    16     18   win/tcl.dsw
    17     19   win/tcl.hpj.in

Changes to .fossil-settings/crnl-glob.

     8      8   libtommath/*.vcproj
     9      9   tools/tcl.hpj.in
    10     10   tools/tcl.wse.in
    11     11   win/buildall.vc.bat
    12     12   win/coffbase.txt
    13     13   win/makefile.vc
    14     14   win/rules.vc
           15  +win/rules-ext.vc
           16  +win/targets.vc
    15     17   win/tcl.dsp
    16     18   win/tcl.dsw
    17     19   win/tcl.hpj.in

Changes to .fossil-settings/ignore-glob.

    40     40   unix/dltest.marker
    41     41   unix/tcl.pc
    42     42   unix/tclIndex
    43     43   unix/pkgs/*
    44     44   win/Debug*
    45     45   win/Release*
    46     46   win/pkgs/*
           47  +win/coffbase.txt
    47     48   win/tcl.hpj
    48     49   win/nmhlp-out.txt

Added .github/ISSUE_TEMPLATE.md.

            1  +Important Note
            2  +==========
            3  +Please do not file issues with Tcl on Github. They are unlikely to be noticed in a timely fashion. Tcl issues are hosted in the [tcl fossil repository on core.tcl.tk](https://core.tcl.tk/tcl/tktnew); please post them there.

Added .github/PULL_REQUEST_TEMPLATE.md.

            1  +Important Note
            2  +==========
            3  +Please do not file pull requests with Tcl on Github. They are unlikely to be noticed in a timely fashion. Tcl issues (including patches) are hosted in the [tcl fossil repository on core.tcl.tk](https://core.tcl.tk/tcl/tktnew); please post them there.

Changes to .project.

     1      1   <?xml version="1.0" encoding="UTF-8"?>
     2      2   <projectDescription>
     3         -	<name>tcl9</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 9.0a0 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.

  8230   8230   
  8231   8231   2013-05-06 (platform support) Cygwin64 (nijtmans)
  8232   8232   
  8233   8233   2013-05-15 (enhancement) Improved [list {*}...] compile (fellows)
  8234   8234   
  8235   8235   2013-05-16 (platform support) mingw-4.0 (nijtmans)
  8236   8236   
  8237         -2013-05-19 (platform support) FreeBSD updates (gahr)
         8237  +2013-05-19 (platform support) FreeBSD updates (cerutti)
  8238   8238   
  8239   8239   2013-05-20 (bug fix)[3613567] access error temp file creation (keene)
  8240   8240   
  8241   8241   2013-05-20 (bug fix)[3613569] temp file open fail can crash [load] (keene)
  8242   8242   
  8243   8243   2013-05-22 (bug fix)[3613609] [lsort -nocase] failed on non-ASCII (fellows)
  8244   8244   
................................................................................
  8653   8653   2016-05-13 (bug)[3154ea] Mem corruption in assembler exceptions (tkob,kenny)
  8654   8654   
  8655   8655   2016-05-13 (bug) registry package support any Unicode env (nijtmans)
  8656   8656   => registry 1.3.2
  8657   8657   
  8658   8658   2016-05-21 (bug)[f7d4e] [namespace delete] performance (fellows)
  8659   8659   
  8660         -2016-06-02 (TIP 447) execution time verbosity option (gahr)
         8660  +2016-06-02 (TIP 447) execution time verbosity option (cerutti)
  8661   8661   => tcltest 2.4.0
  8662   8662   
  8663   8663   2016-06-16 (bug)[16828b] crash due to [vwait] trace undo fail (dah,porter)
  8664   8664   
  8665   8665   2016-06-16 (enhancement)[4b61af] good [info frame] from more cases (beric)
  8666   8666   
  8667   8667   2016-06-21 (bug)[c383eb] crash in [glob -path a] (oehlmann,porter)
................................................................................
  8792   8792   
  8793   8793   2017-07-06 (bug)[adb198] Plug memleak in TclJoinPath (sebres,porter)
  8794   8794   
  8795   8795   2017-07-17 (bug)[fb2208] Repeatable tclIndex generation (wiedemann,nijtmans)
  8796   8796   
  8797   8797   --- Released 8.6.7, August 9, 2017 --- http://core.tcl.tk/tcl/ for details
  8798   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  +
  8799   8838   2016-03-17 (bug)[0b8c38] socket accept callbacks always in global ns (porter)
  8800   8839           *** POTENTIAL INCOMPATIBILITY ***
  8801   8840   
  8802   8841   2016-07-01 Hack accommodations for legacy Itcl 3 disabled (porter)
  8803   8842   
  8804   8843   2016-07-12 Make TCL_HASH_TYPE build-time configurable (nijtmans)
  8805   8844   
................................................................................
  8832   8871   
  8833   8872   2017-06-22 (TIP 470) Tcl_GetDefineContextObject();[oo::define [self]] (fellows)
  8834   8873   => TclOO 1.2.0
  8835   8874   
  8836   8875   2017-06-23 (TIP 472) Support 0d as prefix of decimal numbers (iyer,griffin)
  8837   8876   
  8838   8877   2017-08-31 (bug)[2a9465] http state 100 continue handling broken (oehlmann)
  8839         -=> http 2.8.12
  8840   8878   
  8841   8879   2017-09-02 (bug)[0e4d88] replace command, delete trace kills namespace (porter)
  8842   8880   
  8843   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         - */

Changes to compat/zlib/contrib/minizip/minizip.c.

     8      8            Modifications of Unzip for Zip64
     9      9            Copyright (C) 2007-2008 Even Rouault
    10     10   
    11     11            Modifications for Zip64 support on both zip and unzip
    12     12            Copyright (C) 2009-2010 Mathias Svensson ( http://result42.com )
    13     13   */
    14     14   
    15         -
    16     15   #if (!defined(_WIN32)) && (!defined(WIN32)) && (!defined(__APPLE__))
    17     16           #ifndef __USE_FILE_OFFSET64
    18     17                   #define __USE_FILE_OFFSET64
    19     18           #endif
    20     19           #ifndef __USE_LARGEFILE64
    21     20                   #define __USE_LARGEFILE64
    22     21           #endif
................................................................................
    35     34   #define FSEEKO_FUNC(stream, offset, origin) fseeko(stream, offset, origin)
    36     35   #else
    37     36   #define FOPEN_FUNC(filename, mode) fopen64(filename, mode)
    38     37   #define FTELLO_FUNC(stream) ftello64(stream)
    39     38   #define FSEEKO_FUNC(stream, offset, origin) fseeko64(stream, offset, origin)
    40     39   #endif
    41     40   
    42         -
    43         -
           41  +#include "tinydir.h"
    44     42   #include <stdio.h>
    45     43   #include <stdlib.h>
    46     44   #include <string.h>
    47     45   #include <time.h>
    48     46   #include <errno.h>
    49     47   #include <fcntl.h>
    50     48   
................................................................................
   168    166       printf("MiniZip 1.1, demo of zLib + MiniZip64 package, written by Gilles Vollant\n");
   169    167       printf("more info on MiniZip at http://www.winimage.com/zLibDll/minizip.html\n\n");
   170    168   }
   171    169   
   172    170   void do_help()
   173    171   {
   174    172       printf("Usage : minizip [-o] [-a] [-0 to -9] [-p password] [-j] file.zip [files_to_add]\n\n" \
          173  +           "  -r  Scan directories recursively\n" \
   175    174              "  -o  Overwrite existing file.zip\n" \
   176    175              "  -a  Append to existing file.zip\n" \
   177    176              "  -0  Store only\n" \
   178    177              "  -1  Compress faster\n" \
   179    178              "  -9  Compress better\n\n" \
   180    179              "  -j  exclude path. store only the file name.\n\n");
   181    180   }
................................................................................
   238    237        largeFile = 1;
   239    238   
   240    239                   fclose(pFile);
   241    240     }
   242    241   
   243    242    return largeFile;
   244    243   }
          244  +
          245  +void addFileToZip(zipFile zf, const char *filenameinzip, const char *password, int opt_exclude_path,int opt_compress_level) {
          246  +    FILE * fin;
          247  +    int size_read;
          248  +    const char *savefilenameinzip;
          249  +    zip_fileinfo zi;
          250  +    unsigned long crcFile=0;
          251  +    int zip64 = 0;
          252  +    int err=0;
          253  +    int size_buf=WRITEBUFFERSIZE;
          254  +    unsigned char buf[WRITEBUFFERSIZE];
          255  +    zi.tmz_date.tm_sec = zi.tmz_date.tm_min = zi.tmz_date.tm_hour =
          256  +    zi.tmz_date.tm_mday = zi.tmz_date.tm_mon = zi.tmz_date.tm_year = 0;
          257  +    zi.dosDate = 0;
          258  +    zi.internal_fa = 0;
          259  +    zi.external_fa = 0;
          260  +    filetime(filenameinzip,&zi.tmz_date,&zi.dosDate);
          261  +
          262  +/*
          263  +    err = zipOpenNewFileInZip(zf,filenameinzip,&zi,
          264  +                     NULL,0,NULL,0,NULL / * comment * /,
          265  +                     (opt_compress_level != 0) ? Z_DEFLATED : 0,
          266  +                     opt_compress_level);
          267  +*/
          268  +    if ((password != NULL) && (err==ZIP_OK))
          269  +        err = getFileCrc(filenameinzip,buf,size_buf,&crcFile);
          270  +
          271  +    zip64 = isLargeFile(filenameinzip);
          272  +
          273  +   /* The path name saved, should not include a leading slash. */
          274  +   /*if it did, windows/xp and dynazip couldn't read the zip file. */
          275  +     savefilenameinzip = filenameinzip;
          276  +     while( savefilenameinzip[0] == '\\' || savefilenameinzip[0] == '/' )
          277  +     {
          278  +         savefilenameinzip++;
          279  +     }
          280  +
          281  +     /*should the zip file contain any path at all?*/
          282  +     if( opt_exclude_path )
          283  +     {
          284  +         const char *tmpptr;
          285  +         const char *lastslash = 0;
          286  +         for( tmpptr = savefilenameinzip; *tmpptr; tmpptr++)
          287  +         {
          288  +             if( *tmpptr == '\\' || *tmpptr == '/')
          289  +             {
          290  +                 lastslash = tmpptr;
          291  +             }
          292  +         }
          293  +         if( lastslash != NULL )
          294  +         {
          295  +             savefilenameinzip = lastslash+1; // base filename follows last slash.
          296  +         }
          297  +     }
          298  +
          299  +     /**/
          300  +    err = zipOpenNewFileInZip3_64(zf,savefilenameinzip,&zi,
          301  +                     NULL,0,NULL,0,NULL /* comment*/,
          302  +                     (opt_compress_level != 0) ? Z_DEFLATED : 0,
          303  +                     opt_compress_level,0,
          304  +                     /* -MAX_WBITS, DEF_MEM_LEVEL, Z_DEFAULT_STRATEGY, */
          305  +                     -MAX_WBITS, DEF_MEM_LEVEL, Z_DEFAULT_STRATEGY,
          306  +                     password,crcFile, zip64);
          307  +
          308  +    if (err != ZIP_OK)
          309  +        printf("error in opening %s in zipfile\n",filenameinzip);
          310  +    else
          311  +    {
          312  +        fin = FOPEN_FUNC(filenameinzip,"rb");
          313  +        if (fin==NULL)
          314  +        {
          315  +            err=ZIP_ERRNO;
          316  +            printf("error in opening %s for reading\n",filenameinzip);
          317  +        }
          318  +    }
          319  +
          320  +    if (err == ZIP_OK)
          321  +        do
          322  +        {
          323  +            err = ZIP_OK;
          324  +            size_read = (int)fread(buf,1,size_buf,fin);
          325  +            if (size_read < size_buf)
          326  +                if (feof(fin)==0)
          327  +            {
          328  +                printf("error in reading %s\n",filenameinzip);
          329  +                err = ZIP_ERRNO;
          330  +            }
          331  +
          332  +            if (size_read>0)
          333  +            {
          334  +                err = zipWriteInFileInZip (zf,buf,size_read);
          335  +                if (err<0)
          336  +                {
          337  +                    printf("error in writing %s in the zipfile\n",
          338  +                                     filenameinzip);
          339  +                }
          340  +
          341  +            }
          342  +        } while ((err == ZIP_OK) && (size_read>0));
          343  +
          344  +    if (fin)
          345  +        fclose(fin);
          346  +
          347  +    if (err<0)
          348  +        err=ZIP_ERRNO;
          349  +    else
          350  +    {
          351  +        err = zipCloseFileInZip(zf);
          352  +        if (err!=ZIP_OK)
          353  +            printf("error in closing %s in the zipfile\n",
          354  +                        filenameinzip);
          355  +    }
          356  +}
          357  +
          358  +
          359  +void addPathToZip(zipFile zf, const char *filenameinzip, const char *password, int opt_exclude_path,int opt_compress_level) {
          360  +    tinydir_dir dir;
          361  +    int i;
          362  +    char *newname[512];
          363  +
          364  +    tinydir_open_sorted(&dir, filenameinzip);
          365  +
          366  +    for (i = 0; i < dir.n_files; i++)
          367  +    {
          368  +        tinydir_file file;
          369  +        tinydir_readfile_n(&dir, &file, i);
          370  +        if(strcmp(file.name,".")==0) continue;
          371  +        if(strcmp(file.name,"..")==0) continue;
          372  +        sprintf(newname,"%s/%s",dir.path,file.name);
          373  +        if (file.is_dir)
          374  +        {
          375  +            addPathToZip(zf,newname,password,opt_exclude_path,opt_compress_level);
          376  +        } else {
          377  +            addFileToZip(zf,newname,password,opt_exclude_path,opt_compress_level);
          378  +        }
          379  +    }
          380  +
          381  +    tinydir_close(&dir);
          382  +}
          383  +
   245    384   
   246    385   int main(argc,argv)
   247    386       int argc;
   248    387       char *argv[];
   249    388   {
   250    389       int i;
   251         -    int opt_overwrite=0;
          390  +    int opt_recursive=0;
          391  +    int opt_overwrite=1;
   252    392       int opt_compress_level=Z_DEFAULT_COMPRESSION;
   253    393       int opt_exclude_path=0;
   254    394       int zipfilenamearg = 0;
   255    395       char filename_try[MAXFILENAME+16];
   256    396       int zipok;
   257    397       int err=0;
   258    398       int size_buf=0;
................................................................................
   281    421                           opt_overwrite = 1;
   282    422                       if ((c=='a') || (c=='A'))
   283    423                           opt_overwrite = 2;
   284    424                       if ((c>='0') && (c<='9'))
   285    425                           opt_compress_level = c-'0';
   286    426                       if ((c=='j') || (c=='J'))
   287    427                           opt_exclude_path = 1;
   288         -
          428  +                    if ((c=='r') || (c=='R'))
          429  +                        opt_recursive = 1;
   289    430                       if (((c=='p') || (c=='P')) && (i+1<argc))
   290    431                       {
   291    432                           password=argv[i+1];
   292    433                           i++;
   293    434                       }
   294    435                   }
   295    436               }
................................................................................
   388    529   
   389    530           for (i=zipfilenamearg+1;(i<argc) && (err==ZIP_OK);i++)
   390    531           {
   391    532               if (!((((*(argv[i]))=='-') || ((*(argv[i]))=='/')) &&
   392    533                     ((argv[i][1]=='o') || (argv[i][1]=='O') ||
   393    534                      (argv[i][1]=='a') || (argv[i][1]=='A') ||
   394    535                      (argv[i][1]=='p') || (argv[i][1]=='P') ||
          536  +                   (argv[i][1]=='r') || (argv[i][1]=='R') ||
   395    537                      ((argv[i][1]>='0') || (argv[i][1]<='9'))) &&
   396    538                     (strlen(argv[i]) == 2)))
   397    539               {
   398         -                FILE * fin;
   399         -                int size_read;
   400         -                const char* filenameinzip = argv[i];
   401         -                const char *savefilenameinzip;
   402         -                zip_fileinfo zi;
   403         -                unsigned long crcFile=0;
   404         -                int zip64 = 0;
   405         -
   406         -                zi.tmz_date.tm_sec = zi.tmz_date.tm_min = zi.tmz_date.tm_hour =
   407         -                zi.tmz_date.tm_mday = zi.tmz_date.tm_mon = zi.tmz_date.tm_year = 0;
   408         -                zi.dosDate = 0;
   409         -                zi.internal_fa = 0;
   410         -                zi.external_fa = 0;
   411         -                filetime(filenameinzip,&zi.tmz_date,&zi.dosDate);
   412         -
   413         -/*
   414         -                err = zipOpenNewFileInZip(zf,filenameinzip,&zi,
   415         -                                 NULL,0,NULL,0,NULL / * comment * /,
   416         -                                 (opt_compress_level != 0) ? Z_DEFLATED : 0,
   417         -                                 opt_compress_level);
   418         -*/
   419         -                if ((password != NULL) && (err==ZIP_OK))
   420         -                    err = getFileCrc(filenameinzip,buf,size_buf,&crcFile);
   421         -
   422         -                zip64 = isLargeFile(filenameinzip);
   423         -
   424         -                                                         /* The path name saved, should not include a leading slash. */
   425         -               /*if it did, windows/xp and dynazip couldn't read the zip file. */
   426         -                 savefilenameinzip = filenameinzip;
   427         -                 while( savefilenameinzip[0] == '\\' || savefilenameinzip[0] == '/' )
   428         -                 {
   429         -                     savefilenameinzip++;
   430         -                 }
   431         -
   432         -                 /*should the zip file contain any path at all?*/
   433         -                 if( opt_exclude_path )
   434         -                 {
   435         -                     const char *tmpptr;
   436         -                     const char *lastslash = 0;
   437         -                     for( tmpptr = savefilenameinzip; *tmpptr; tmpptr++)
   438         -                     {
   439         -                         if( *tmpptr == '\\' || *tmpptr == '/')
   440         -                         {
   441         -                             lastslash = tmpptr;
   442         -                         }
   443         -                     }
   444         -                     if( lastslash != NULL )
   445         -                     {
   446         -                         savefilenameinzip = lastslash+1; // base filename follows last slash.
   447         -                     }
   448         -                 }
   449         -
   450         -                 /**/
   451         -                err = zipOpenNewFileInZip3_64(zf,savefilenameinzip,&zi,
   452         -                                 NULL,0,NULL,0,NULL /* comment*/,
   453         -                                 (opt_compress_level != 0) ? Z_DEFLATED : 0,
   454         -                                 opt_compress_level,0,
   455         -                                 /* -MAX_WBITS, DEF_MEM_LEVEL, Z_DEFAULT_STRATEGY, */
   456         -                                 -MAX_WBITS, DEF_MEM_LEVEL, Z_DEFAULT_STRATEGY,
   457         -                                 password,crcFile, zip64);
   458         -
   459         -                if (err != ZIP_OK)
   460         -                    printf("error in opening %s in zipfile\n",filenameinzip);
   461         -                else
   462         -                {
   463         -                    fin = FOPEN_FUNC(filenameinzip,"rb");
   464         -                    if (fin==NULL)
   465         -                    {
   466         -                        err=ZIP_ERRNO;
   467         -                        printf("error in opening %s for reading\n",filenameinzip);
   468         -                    }
   469         -                }
   470         -
   471         -                if (err == ZIP_OK)
   472         -                    do
   473         -                    {
   474         -                        err = ZIP_OK;
   475         -                        size_read = (int)fread(buf,1,size_buf,fin);
   476         -                        if (size_read < size_buf)
   477         -                            if (feof(fin)==0)
   478         -                        {
   479         -                            printf("error in reading %s\n",filenameinzip);
   480         -                            err = ZIP_ERRNO;
   481         -                        }
   482         -
   483         -                        if (size_read>0)
   484         -                        {
   485         -                            err = zipWriteInFileInZip (zf,buf,size_read);
   486         -                            if (err<0)
   487         -                            {
   488         -                                printf("error in writing %s in the zipfile\n",
   489         -                                                 filenameinzip);
   490         -                            }
   491         -
   492         -                        }
   493         -                    } while ((err == ZIP_OK) && (size_read>0));
   494         -
   495         -                if (fin)
   496         -                    fclose(fin);
   497         -
   498         -                if (err<0)
   499         -                    err=ZIP_ERRNO;
   500         -                else
   501         -                {
   502         -                    err = zipCloseFileInZip(zf);
   503         -                    if (err!=ZIP_OK)
   504         -                        printf("error in closing %s in the zipfile\n",
   505         -                                    filenameinzip);
          540  +                if(opt_recursive) {
          541  +                    addPathToZip(zf,argv[i],password,opt_exclude_path,opt_compress_level);
          542  +                } else {
          543  +                    addFileToZip(zf,argv[i],password,opt_exclude_path,opt_compress_level);
   506    544                   }
   507    545               }
   508    546           }
   509    547           errclose = zipClose(zf,NULL);
   510    548           if (errclose != ZIP_OK)
   511    549               printf("error in closing %s\n",filename_try);
   512    550       }

Added compat/zlib/contrib/minizip/tinydir.h.

            1  +/*
            2  +Copyright (c) 2013-2017, tinydir authors:
            3  +- Cong Xu
            4  +- Lautis Sun
            5  +- Baudouin Feildel
            6  +- Andargor <[email protected]>
            7  +All rights reserved.
            8  +
            9  +Redistribution and use in source and binary forms, with or without
           10  +modification, are permitted provided that the following conditions are met:
           11  +
           12  +1. Redistributions of source code must retain the above copyright notice, this
           13  +   list of conditions and the following disclaimer.
           14  +2. Redistributions in binary form must reproduce the above copyright notice,
           15  +   this list of conditions and the following disclaimer in the documentation
           16  +   and/or other materials provided with the distribution.
           17  +
           18  +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
           19  +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
           20  +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
           21  +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
           22  +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
           23  +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
           24  +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
           25  +ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
           26  +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
           27  +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
           28  +*/
           29  +#ifndef TINYDIR_H
           30  +#define TINYDIR_H
           31  +
           32  +#ifdef __cplusplus
           33  +extern "C" {
           34  +#endif
           35  +
           36  +#if ((defined _UNICODE) && !(defined UNICODE))
           37  +#define UNICODE
           38  +#endif
           39  +
           40  +#if ((defined UNICODE) && !(defined _UNICODE))
           41  +#define _UNICODE
           42  +#endif
           43  +
           44  +#include <errno.h>
           45  +#include <stdlib.h>
           46  +#include <string.h>
           47  +#ifdef _MSC_VER
           48  +# define WIN32_LEAN_AND_MEAN
           49  +# include <windows.h>
           50  +# include <tchar.h>
           51  +# pragma warning(push)
           52  +# pragma warning (disable : 4996)
           53  +#else
           54  +# include <dirent.h>
           55  +# include <libgen.h>
           56  +# include <sys/stat.h>
           57  +# include <stddef.h>
           58  +#endif
           59  +#ifdef __MINGW32__
           60  +# include <tchar.h>
           61  +#endif
           62  +
           63  +
           64  +/* types */
           65  +
           66  +/* Windows UNICODE wide character support */
           67  +#if defined _MSC_VER || defined __MINGW32__
           68  +# define _tinydir_char_t TCHAR
           69  +# define TINYDIR_STRING(s) _TEXT(s)
           70  +# define _tinydir_strlen _tcslen
           71  +# define _tinydir_strcpy _tcscpy
           72  +# define _tinydir_strcat _tcscat
           73  +# define _tinydir_strcmp _tcscmp
           74  +# define _tinydir_strrchr _tcsrchr
           75  +# define _tinydir_strncmp _tcsncmp
           76  +#else
           77  +# define _tinydir_char_t char
           78  +# define TINYDIR_STRING(s) s
           79  +# define _tinydir_strlen strlen
           80  +# define _tinydir_strcpy strcpy
           81  +# define _tinydir_strcat strcat
           82  +# define _tinydir_strcmp strcmp
           83  +# define _tinydir_strrchr strrchr
           84  +# define _tinydir_strncmp strncmp
           85  +#endif
           86  +
           87  +#if (defined _MSC_VER || defined __MINGW32__)
           88  +# include <windows.h>
           89  +# define _TINYDIR_PATH_MAX MAX_PATH
           90  +#elif defined  __linux__
           91  +# include <limits.h>
           92  +# define _TINYDIR_PATH_MAX PATH_MAX
           93  +#elif defined(__unix__) || (defined(__APPLE__) && defined(__MACH__))
           94  +# include <sys/param.h>
           95  +# if defined(BSD)
           96  +#  include <limits.h>
           97  +#  define _TINYDIR_PATH_MAX PATH_MAX
           98  +# endif
           99  +#endif
          100  +
          101  +#ifndef _TINYDIR_PATH_MAX
          102  +#define _TINYDIR_PATH_MAX 4096
          103  +#endif
          104  +
          105  +#ifdef _MSC_VER
          106  +/* extra chars for the "\\*" mask */
          107  +# define _TINYDIR_PATH_EXTRA 2
          108  +#else
          109  +# define _TINYDIR_PATH_EXTRA 0
          110  +#endif
          111  +
          112  +#define _TINYDIR_FILENAME_MAX 256
          113  +
          114  +#if (defined _MSC_VER || defined __MINGW32__)
          115  +#define _TINYDIR_DRIVE_MAX 3
          116  +#endif
          117  +
          118  +#ifdef _MSC_VER
          119  +# define _TINYDIR_FUNC static __inline
          120  +#elif !defined __STDC_VERSION__ || __STDC_VERSION__ < 199901L
          121  +# define _TINYDIR_FUNC static __inline__
          122  +#else
          123  +# define _TINYDIR_FUNC static inline
          124  +#endif
          125  +
          126  +/* readdir_r usage; define TINYDIR_USE_READDIR_R to use it (if supported) */
          127  +#ifdef TINYDIR_USE_READDIR_R
          128  +
          129  +/* readdir_r is a POSIX-only function, and may not be available under various
          130  + * environments/settings, e.g. MinGW. Use readdir fallback */
          131  +#if _POSIX_C_SOURCE >= 1 || _XOPEN_SOURCE || _BSD_SOURCE || _SVID_SOURCE ||\
          132  +	_POSIX_SOURCE
          133  +# define _TINYDIR_HAS_READDIR_R
          134  +#endif
          135  +#if _POSIX_C_SOURCE >= 200112L
          136  +# define _TINYDIR_HAS_FPATHCONF
          137  +# include <unistd.h>
          138  +#endif
          139  +#if _BSD_SOURCE || _SVID_SOURCE || \
          140  +	(_POSIX_C_SOURCE >= 200809L || _XOPEN_SOURCE >= 700)
          141  +# define _TINYDIR_HAS_DIRFD
          142  +# include <sys/types.h>
          143  +#endif
          144  +#if defined _TINYDIR_HAS_FPATHCONF && defined _TINYDIR_HAS_DIRFD &&\
          145  +	defined _PC_NAME_MAX
          146  +# define _TINYDIR_USE_FPATHCONF
          147  +#endif
          148  +#if defined __MINGW32__ || !defined _TINYDIR_HAS_READDIR_R ||\
          149  +	!(defined _TINYDIR_USE_FPATHCONF || defined NAME_MAX)
          150  +# define _TINYDIR_USE_READDIR
          151  +#endif
          152  +
          153  +/* Use readdir by default */
          154  +#else
          155  +# define _TINYDIR_USE_READDIR
          156  +#endif
          157  +
          158  +/* MINGW32 has two versions of dirent, ASCII and UNICODE*/
          159  +#ifndef _MSC_VER
          160  +#if (defined __MINGW32__) && (defined _UNICODE)
          161  +#define _TINYDIR_DIR _WDIR
          162  +#define _tinydir_dirent _wdirent
          163  +#define _tinydir_opendir _wopendir
          164  +#define _tinydir_readdir _wreaddir
          165  +#define _tinydir_closedir _wclosedir
          166  +#else
          167  +#define _TINYDIR_DIR DIR
          168  +#define _tinydir_dirent dirent
          169  +#define _tinydir_opendir opendir
          170  +#define _tinydir_readdir readdir
          171  +#define _tinydir_closedir closedir
          172  +#endif
          173  +#endif
          174  +
          175  +/* Allow user to use a custom allocator by defining _TINYDIR_MALLOC and _TINYDIR_FREE. */
          176  +#if    defined(_TINYDIR_MALLOC) &&  defined(_TINYDIR_FREE)
          177  +#elif !defined(_TINYDIR_MALLOC) && !defined(_TINYDIR_FREE)
          178  +#else
          179  +#error "Either define both alloc and free or none of them!"
          180  +#endif
          181  +
          182  +#if !defined(_TINYDIR_MALLOC)
          183  +	#define _TINYDIR_MALLOC(_size) malloc(_size)
          184  +	#define _TINYDIR_FREE(_ptr)    free(_ptr)
          185  +#endif /* !defined(_TINYDIR_MALLOC) */
          186  +
          187  +typedef struct tinydir_file
          188  +{
          189  +	_tinydir_char_t path[_TINYDIR_PATH_MAX];
          190  +	_tinydir_char_t name[_TINYDIR_FILENAME_MAX];
          191  +	_tinydir_char_t *extension;
          192  +	int is_dir;
          193  +	int is_reg;
          194  +
          195  +#ifndef _MSC_VER
          196  +#ifdef __MINGW32__
          197  +	struct _stat _s;
          198  +#else
          199  +	struct stat _s;
          200  +#endif
          201  +#endif
          202  +} tinydir_file;
          203  +
          204  +typedef struct tinydir_dir
          205  +{
          206  +	_tinydir_char_t path[_TINYDIR_PATH_MAX];
          207  +	int has_next;
          208  +	size_t n_files;
          209  +
          210  +	tinydir_file *_files;
          211  +#ifdef _MSC_VER
          212  +	HANDLE _h;
          213  +	WIN32_FIND_DATA _f;
          214  +#else
          215  +	_TINYDIR_DIR *_d;
          216  +	struct _tinydir_dirent *_e;
          217  +#ifndef _TINYDIR_USE_READDIR
          218  +	struct _tinydir_dirent *_ep;
          219  +#endif
          220  +#endif
          221  +} tinydir_dir;
          222  +
          223  +
          224  +/* declarations */
          225  +
          226  +_TINYDIR_FUNC
          227  +int tinydir_open(tinydir_dir *dir, const _tinydir_char_t *path);
          228  +_TINYDIR_FUNC
          229  +int tinydir_open_sorted(tinydir_dir *dir, const _tinydir_char_t *path);
          230  +_TINYDIR_FUNC
          231  +void tinydir_close(tinydir_dir *dir);
          232  +
          233  +_TINYDIR_FUNC
          234  +int tinydir_next(tinydir_dir *dir);
          235  +_TINYDIR_FUNC
          236  +int tinydir_readfile(const tinydir_dir *dir, tinydir_file *file);
          237  +_TINYDIR_FUNC
          238  +int tinydir_readfile_n(const tinydir_dir *dir, tinydir_file *file, size_t i);
          239  +_TINYDIR_FUNC
          240  +int tinydir_open_subdir_n(tinydir_dir *dir, size_t i);
          241  +
          242  +_TINYDIR_FUNC
          243  +int tinydir_file_open(tinydir_file *file, const _tinydir_char_t *path);
          244  +_TINYDIR_FUNC
          245  +void _tinydir_get_ext(tinydir_file *file);
          246  +_TINYDIR_FUNC
          247  +int _tinydir_file_cmp(const void *a, const void *b);
          248  +#ifndef _MSC_VER
          249  +#ifndef _TINYDIR_USE_READDIR
          250  +_TINYDIR_FUNC
          251  +size_t _tinydir_dirent_buf_size(_TINYDIR_DIR *dirp);
          252  +#endif
          253  +#endif
          254  +
          255  +
          256  +/* definitions*/
          257  +
          258  +_TINYDIR_FUNC
          259  +int tinydir_open(tinydir_dir *dir, const _tinydir_char_t *path)
          260  +{
          261  +#ifndef _MSC_VER
          262  +#ifndef _TINYDIR_USE_READDIR
          263  +	int error;
          264  +	int size;	/* using int size */
          265  +#endif
          266  +#else
          267  +	_tinydir_char_t path_buf[_TINYDIR_PATH_MAX];
          268  +#endif
          269  +	_tinydir_char_t *pathp;
          270  +
          271  +	if (dir == NULL || path == NULL || _tinydir_strlen(path) == 0)
          272  +	{
          273  +		errno = EINVAL;
          274  +		return -1;
          275  +	}
          276  +	if (_tinydir_strlen(path) + _TINYDIR_PATH_EXTRA >= _TINYDIR_PATH_MAX)
          277  +	{
          278  +		errno = ENAMETOOLONG;
          279  +		return -1;
          280  +	}
          281  +
          282  +	/* initialise dir */
          283  +	dir->_files = NULL;
          284  +#ifdef _MSC_VER
          285  +	dir->_h = INVALID_HANDLE_VALUE;
          286  +#else
          287  +	dir->_d = NULL;
          288  +#ifndef _TINYDIR_USE_READDIR
          289  +	dir->_ep = NULL;
          290  +#endif
          291  +#endif
          292  +	tinydir_close(dir);
          293  +
          294  +	_tinydir_strcpy(dir->path, path);
          295  +	/* Remove trailing slashes */
          296  +	pathp = &dir->path[_tinydir_strlen(dir->path) - 1];
          297  +	while (pathp != dir->path && (*pathp == TINYDIR_STRING('\\') || *pathp == TINYDIR_STRING('/')))
          298  +	{
          299  +		*pathp = TINYDIR_STRING('\0');
          300  +		pathp++;
          301  +	}
          302  +#ifdef _MSC_VER
          303  +	_tinydir_strcpy(path_buf, dir->path);
          304  +	_tinydir_strcat(path_buf, TINYDIR_STRING("\\*"));
          305  +#if (defined WINAPI_FAMILY) && (WINAPI_FAMILY != WINAPI_FAMILY_DESKTOP_APP)
          306  +	dir->_h = FindFirstFileEx(path_buf, FindExInfoStandard, &dir->_f, FindExSearchNameMatch, NULL, 0);
          307  +#else
          308  +	dir->_h = FindFirstFile(path_buf, &dir->_f);
          309  +#endif
          310  +	if (dir->_h == INVALID_HANDLE_VALUE)
          311  +	{
          312  +		errno = ENOENT;
          313  +#else
          314  +	dir->_d = _tinydir_opendir(path);
          315  +	if (dir->_d == NULL)
          316  +	{
          317  +#endif
          318  +		goto bail;
          319  +	}
          320  +
          321  +	/* read first file */
          322  +	dir->has_next = 1;
          323  +#ifndef _MSC_VER
          324  +#ifdef _TINYDIR_USE_READDIR
          325  +	dir->_e = _tinydir_readdir(dir->_d);
          326  +#else
          327  +	/* allocate dirent buffer for readdir_r */
          328  +	size = _tinydir_dirent_buf_size(dir->_d); /* conversion to int */
          329  +	if (size == -1) return -1;
          330  +	dir->_ep = (struct _tinydir_dirent*)_TINYDIR_MALLOC(size);
          331  +	if (dir->_ep == NULL) return -1;
          332  +
          333  +	error = readdir_r(dir->_d, dir->_ep, &dir->_e);
          334  +	if (error != 0) return -1;
          335  +#endif
          336  +	if (dir->_e == NULL)
          337  +	{
          338  +		dir->has_next = 0;
          339  +	}
          340  +#endif
          341  +
          342  +	return 0;
          343  +
          344  +bail:
          345  +	tinydir_close(dir);
          346  +	return -1;
          347  +}
          348  +
          349  +_TINYDIR_FUNC
          350  +int tinydir_open_sorted(tinydir_dir *dir, const _tinydir_char_t *path)
          351  +{
          352  +	/* Count the number of files first, to pre-allocate the files array */
          353  +	size_t n_files = 0;
          354  +	if (tinydir_open(dir, path) == -1)
          355  +	{
          356  +		return -1;
          357  +	}
          358  +	while (dir->has_next)
          359  +	{
          360  +		n_files++;
          361  +		if (tinydir_next(dir) == -1)
          362  +		{
          363  +			goto bail;
          364  +		}
          365  +	}
          366  +	tinydir_close(dir);
          367  +
          368  +	if (tinydir_open(dir, path) == -1)
          369  +	{
          370  +		return -1;
          371  +	}
          372  +
          373  +	dir->n_files = 0;
          374  +	dir->_files = (tinydir_file *)_TINYDIR_MALLOC(sizeof *dir->_files * n_files);
          375  +	if (dir->_files == NULL)
          376  +	{
          377  +		goto bail;
          378  +	}
          379  +	while (dir->has_next)
          380  +	{
          381  +		tinydir_file *p_file;
          382  +		dir->n_files++;
          383  +
          384  +		p_file = &dir->_files[dir->n_files - 1];
          385  +		if (tinydir_readfile(dir, p_file) == -1)
          386  +		{
          387  +			goto bail;
          388  +		}
          389  +
          390  +		if (tinydir_next(dir) == -1)
          391  +		{
          392  +			goto bail;
          393  +		}
          394  +
          395  +		/* Just in case the number of files has changed between the first and
          396  +		second reads, terminate without writing into unallocated memory */
          397  +		if (dir->n_files == n_files)
          398  +		{
          399  +			break;
          400  +		}
          401  +	}
          402  +
          403  +	qsort(dir->_files, dir->n_files, sizeof(tinydir_file), _tinydir_file_cmp);
          404  +
          405  +	return 0;
          406  +
          407  +bail:
          408  +	tinydir_close(dir);
          409  +	return -1;
          410  +}
          411  +
          412  +_TINYDIR_FUNC
          413  +void tinydir_close(tinydir_dir *dir)
          414  +{
          415  +	if (dir == NULL)
          416  +	{
          417  +		return;
          418  +	}
          419  +
          420  +	memset(dir->path, 0, sizeof(dir->path));
          421  +	dir->has_next = 0;
          422  +	dir->n_files = 0;
          423  +	_TINYDIR_FREE(dir->_files);
          424  +	dir->_files = NULL;
          425  +#ifdef _MSC_VER
          426  +	if (dir->_h != INVALID_HANDLE_VALUE)
          427  +	{
          428  +		FindClose(dir->_h);
          429  +	}
          430  +	dir->_h = INVALID_HANDLE_VALUE;
          431  +#else
          432  +	if (dir->_d)
          433  +	{
          434  +		_tinydir_closedir(dir->_d);
          435  +	}
          436  +	dir->_d = NULL;
          437  +	dir->_e = NULL;
          438  +#ifndef _TINYDIR_USE_READDIR
          439  +	_TINYDIR_FREE(dir->_ep);
          440  +	dir->_ep = NULL;
          441  +#endif
          442  +#endif
          443  +}
          444  +
          445  +_TINYDIR_FUNC
          446  +int tinydir_next(tinydir_dir *dir)
          447  +{
          448  +	if (dir == NULL)
          449  +	{
          450  +		errno = EINVAL;
          451  +		return -1;
          452  +	}
          453  +	if (!dir->has_next)
          454  +	{
          455  +		errno = ENOENT;
          456  +		return -1;
          457  +	}
          458  +
          459  +#ifdef _MSC_VER
          460  +	if (FindNextFile(dir->_h, &dir->_f) == 0)
          461  +#else
          462  +#ifdef _TINYDIR_USE_READDIR
          463  +	dir->_e = _tinydir_readdir(dir->_d);
          464  +#else
          465  +	if (dir->_ep == NULL)
          466  +	{
          467  +		return -1;
          468  +	}
          469  +	if (readdir_r(dir->_d, dir->_ep, &dir->_e) != 0)
          470  +	{
          471  +		return -1;
          472  +	}
          473  +#endif
          474  +	if (dir->_e == NULL)
          475  +#endif
          476  +	{
          477  +		dir->has_next = 0;
          478  +#ifdef _MSC_VER
          479  +		if (GetLastError() != ERROR_SUCCESS &&
          480  +			GetLastError() != ERROR_NO_MORE_FILES)
          481  +		{
          482  +			tinydir_close(dir);
          483  +			errno = EIO;
          484  +			return -1;
          485  +		}
          486  +#endif
          487  +	}
          488  +
          489  +	return 0;
          490  +}
          491  +
          492  +_TINYDIR_FUNC
          493  +int tinydir_readfile(const tinydir_dir *dir, tinydir_file *file)
          494  +{
          495  +	if (dir == NULL || file == NULL)
          496  +	{
          497  +		errno = EINVAL;
          498  +		return -1;
          499  +	}
          500  +#ifdef _MSC_VER
          501  +	if (dir->_h == INVALID_HANDLE_VALUE)
          502  +#else
          503  +	if (dir->_e == NULL)
          504  +#endif
          505  +	{
          506  +		errno = ENOENT;
          507  +		return -1;
          508  +	}
          509  +	if (_tinydir_strlen(dir->path) +
          510  +		_tinydir_strlen(
          511  +#ifdef _MSC_VER
          512  +			dir->_f.cFileName
          513  +#else
          514  +			dir->_e->d_name
          515  +#endif
          516  +		) + 1 + _TINYDIR_PATH_EXTRA >=
          517  +		_TINYDIR_PATH_MAX)
          518  +	{
          519  +		/* the path for the file will be too long */
          520  +		errno = ENAMETOOLONG;
          521  +		return -1;
          522  +	}
          523  +	if (_tinydir_strlen(
          524  +#ifdef _MSC_VER
          525  +			dir->_f.cFileName
          526  +#else
          527  +			dir->_e->d_name
          528  +#endif
          529  +		) >= _TINYDIR_FILENAME_MAX)
          530  +	{
          531  +		errno = ENAMETOOLONG;
          532  +		return -1;
          533  +	}
          534  +
          535  +	_tinydir_strcpy(file->path, dir->path);
          536  +	_tinydir_strcat(file->path, TINYDIR_STRING("/"));
          537  +	_tinydir_strcpy(file->name,
          538  +#ifdef _MSC_VER
          539  +		dir->_f.cFileName
          540  +#else
          541  +		dir->_e->d_name
          542  +#endif
          543  +	);
          544  +	_tinydir_strcat(file->path, file->name);
          545  +#ifndef _MSC_VER
          546  +#ifdef __MINGW32__
          547  +	if (_tstat(
          548  +#else
          549  +	if (stat(
          550  +#endif
          551  +		file->path, &file->_s) == -1)
          552  +	{
          553  +		return -1;
          554  +	}
          555  +#endif
          556  +	_tinydir_get_ext(file);
          557  +
          558  +	file->is_dir =
          559  +#ifdef _MSC_VER
          560  +		!!(dir->_f.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY);
          561  +#else
          562  +		S_ISDIR(file->_s.st_mode);
          563  +#endif
          564  +	file->is_reg =
          565  +#ifdef _MSC_VER
          566  +		!!(dir->_f.dwFileAttributes & FILE_ATTRIBUTE_NORMAL) ||
          567  +		(
          568  +			!(dir->_f.dwFileAttributes & FILE_ATTRIBUTE_DEVICE) &&
          569  +			!(dir->_f.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) &&
          570  +			!(dir->_f.dwFileAttributes & FILE_ATTRIBUTE_ENCRYPTED) &&
          571  +#ifdef FILE_ATTRIBUTE_INTEGRITY_STREAM
          572  +			!(dir->_f.dwFileAttributes & FILE_ATTRIBUTE_INTEGRITY_STREAM) &&
          573  +#endif
          574  +#ifdef FILE_ATTRIBUTE_NO_SCRUB_DATA
          575  +			!(dir->_f.dwFileAttributes & FILE_ATTRIBUTE_NO_SCRUB_DATA) &&
          576  +#endif
          577  +			!(dir->_f.dwFileAttributes & FILE_ATTRIBUTE_OFFLINE) &&
          578  +			!(dir->_f.dwFileAttributes & FILE_ATTRIBUTE_TEMPORARY));
          579  +#else
          580  +		S_ISREG(file->_s.st_mode);
          581  +#endif
          582  +
          583  +	return 0;
          584  +}
          585  +
          586  +_TINYDIR_FUNC
          587  +int tinydir_readfile_n(const tinydir_dir *dir, tinydir_file *file, size_t i)
          588  +{
          589  +	if (dir == NULL || file == NULL)
          590  +	{
          591  +		errno = EINVAL;
          592  +		return -1;
          593  +	}
          594  +	if (i >= dir->n_files)
          595  +	{
          596  +		errno = ENOENT;
          597  +		return -1;
          598  +	}
          599  +
          600  +	memcpy(file, &dir->_files[i], sizeof(tinydir_file));
          601  +	_tinydir_get_ext(file);
          602  +
          603  +	return 0;
          604  +}
          605  +
          606  +_TINYDIR_FUNC
          607  +int tinydir_open_subdir_n(tinydir_dir *dir, size_t i)
          608  +{
          609  +	_tinydir_char_t path[_TINYDIR_PATH_MAX];
          610  +	if (dir == NULL)
          611  +	{
          612  +		errno = EINVAL;
          613  +		return -1;
          614  +	}
          615  +	if (i >= dir->n_files || !dir->_files[i].is_dir)
          616  +	{
          617  +		errno = ENOENT;
          618  +		return -1;
          619  +	}
          620  +
          621  +	_tinydir_strcpy(path, dir->_files[i].path);
          622  +	tinydir_close(dir);
          623  +	if (tinydir_open_sorted(dir, path) == -1)
          624  +	{
          625  +		return -1;
          626  +	}
          627  +
          628  +	return 0;
          629  +}
          630  +
          631  +/* Open a single file given its path */
          632  +_TINYDIR_FUNC
          633  +int tinydir_file_open(tinydir_file *file, const _tinydir_char_t *path)
          634  +{
          635  +	tinydir_dir dir;
          636  +	int result = 0;
          637  +	int found = 0;
          638  +	_tinydir_char_t dir_name_buf[_TINYDIR_PATH_MAX];
          639  +	_tinydir_char_t file_name_buf[_TINYDIR_FILENAME_MAX];
          640  +	_tinydir_char_t *dir_name;
          641  +	_tinydir_char_t *base_name;
          642  +#if (defined _MSC_VER || defined __MINGW32__)
          643  +	_tinydir_char_t drive_buf[_TINYDIR_PATH_MAX];
          644  +	_tinydir_char_t ext_buf[_TINYDIR_FILENAME_MAX];
          645  +#endif
          646  +
          647  +	if (file == NULL || path == NULL || _tinydir_strlen(path) == 0)
          648  +	{
          649  +		errno = EINVAL;
          650  +		return -1;
          651  +	}
          652  +	if (_tinydir_strlen(path) + _TINYDIR_PATH_EXTRA >= _TINYDIR_PATH_MAX)
          653  +	{
          654  +		errno = ENAMETOOLONG;
          655  +		return -1;
          656  +	}
          657  +
          658  +	/* Get the parent path */
          659  +#if (defined _MSC_VER || defined __MINGW32__)
          660  +#if ((defined _MSC_VER) && (_MSC_VER >= 1400))
          661  +		_tsplitpath_s(
          662  +			path,
          663  +			drive_buf, _TINYDIR_DRIVE_MAX,
          664  +			dir_name_buf, _TINYDIR_FILENAME_MAX,
          665  +			file_name_buf, _TINYDIR_FILENAME_MAX,
          666  +			ext_buf, _TINYDIR_FILENAME_MAX);
          667  +#else
          668  +		_tsplitpath(
          669  +			path,
          670  +			drive_buf,
          671  +			dir_name_buf,
          672  +			file_name_buf,
          673  +			ext_buf);
          674  +#endif
          675  +
          676  +/* _splitpath_s not work fine with only filename and widechar support */
          677  +#ifdef _UNICODE
          678  +		if (drive_buf[0] == L'\xFEFE')
          679  +			drive_buf[0] = '\0';
          680  +		if (dir_name_buf[0] == L'\xFEFE')
          681  +			dir_name_buf[0] = '\0';
          682  +#endif
          683  +
          684  +	if (errno)
          685  +	{
          686  +		errno = EINVAL;
          687  +		return -1;
          688  +	}
          689  +	/* Emulate the behavior of dirname by returning "." for dir name if it's
          690  +	empty */
          691  +	if (drive_buf[0] == '\0' && dir_name_buf[0] == '\0')
          692  +	{
          693  +		_tinydir_strcpy(dir_name_buf, TINYDIR_STRING("."));
          694  +	}
          695  +	/* Concatenate the drive letter and dir name to form full dir name */
          696  +	_tinydir_strcat(drive_buf, dir_name_buf);
          697  +	dir_name = drive_buf;
          698  +	/* Concatenate the file name and extension to form base name */
          699  +	_tinydir_strcat(file_name_buf, ext_buf);
          700  +	base_name = file_name_buf;
          701  +#else
          702  +	_tinydir_strcpy(dir_name_buf, path);
          703  +	dir_name = dirname(dir_name_buf);
          704  +	_tinydir_strcpy(file_name_buf, path);
          705  +	base_name =basename(file_name_buf);
          706  +#endif
          707  +
          708  +	/* Open the parent directory */
          709  +	if (tinydir_open(&dir, dir_name) == -1)
          710  +	{
          711  +		return -1;
          712  +	}
          713  +
          714  +	/* Read through the parent directory and look for the file */
          715  +	while (dir.has_next)
          716  +	{
          717  +		if (tinydir_readfile(&dir, file) == -1)
          718  +		{
          719  +			result = -1;
          720  +			goto bail;
          721  +		}
          722  +		if (_tinydir_strcmp(file->name, base_name) == 0)
          723  +		{
          724  +			/* File found */
          725  +			found = 1;
          726  +			break;
          727  +		}
          728  +		tinydir_next(&dir);
          729  +	}
          730  +	if (!found)
          731  +	{
          732  +		result = -1;
          733  +		errno = ENOENT;
          734  +	}
          735  +
          736  +bail:
          737  +	tinydir_close(&dir);
          738  +	return result;
          739  +}
          740  +
          741  +_TINYDIR_FUNC
          742  +void _tinydir_get_ext(tinydir_file *file)
          743  +{
          744  +	_tinydir_char_t *period = _tinydir_strrchr(file->name, TINYDIR_STRING('.'));
          745  +	if (period == NULL)
          746  +	{
          747  +		file->extension = &(file->name[_tinydir_strlen(file->name)]);
          748  +	}
          749  +	else
          750  +	{
          751  +		file->extension = period + 1;
          752  +	}
          753  +}
          754  +
          755  +_TINYDIR_FUNC
          756  +int _tinydir_file_cmp(const void *a, const void *b)
          757  +{
          758  +	const tinydir_file *fa = (const tinydir_file *)a;
          759  +	const tinydir_file *fb = (const tinydir_file *)b;
          760  +	if (fa->is_dir != fb->is_dir)
          761  +	{
          762  +		return -(fa->is_dir - fb->is_dir);
          763  +	}
          764  +	return _tinydir_strncmp(fa->name, fb->name, _TINYDIR_FILENAME_MAX);
          765  +}
          766  +
          767  +#ifndef _MSC_VER
          768  +#ifndef _TINYDIR_USE_READDIR
          769  +/*
          770  +The following authored by Ben Hutchings <[email protected]>
          771  +from https://womble.decadent.org.uk/readdir_r-advisory.html
          772  +*/
          773  +/* Calculate the required buffer size (in bytes) for directory      *
          774  +* entries read from the given directory handle.  Return -1 if this  *
          775  +* this cannot be done.                                              *
          776  +*                                                                   *
          777  +* This code does not trust values of NAME_MAX that are less than    *
          778  +* 255, since some systems (including at least HP-UX) incorrectly    *
          779  +* define it to be a smaller value.                                  */
          780  +_TINYDIR_FUNC
          781  +size_t _tinydir_dirent_buf_size(_TINYDIR_DIR *dirp)
          782  +{
          783  +	long name_max;
          784  +	size_t name_end;
          785  +	/* parameter may be unused */
          786  +	(void)dirp;
          787  +
          788  +#if defined _TINYDIR_USE_FPATHCONF
          789  +	name_max = fpathconf(dirfd(dirp), _PC_NAME_MAX);
          790  +	if (name_max == -1)
          791  +#if defined(NAME_MAX)
          792  +		name_max = (NAME_MAX > 255) ? NAME_MAX : 255;
          793  +#else
          794  +		return (size_t)(-1);
          795  +#endif
          796  +#elif defined(NAME_MAX)
          797  + 	name_max = (NAME_MAX > 255) ? NAME_MAX : 255;
          798  +#else
          799  +#error "buffer size for readdir_r cannot be determined"
          800  +#endif
          801  +	name_end = (size_t)offsetof(struct _tinydir_dirent, d_name) + name_max + 1;
          802  +	return (name_end > sizeof(struct _tinydir_dirent) ?
          803  +		name_end : sizeof(struct _tinydir_dirent));
          804  +}
          805  +#endif
          806  +#endif
          807  +
          808  +#ifdef __cplusplus
          809  +}
          810  +#endif
          811  +
          812  +# if defined (_MSC_VER)
          813  +# pragma warning(pop)
          814  +# endif
          815  +
          816  +#endif

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.

    60     60   .QW \fB0d\fR
    61     61   then \fIsrc\fR is expected to be in decimal form; otherwise,
    62     62   if the first such characters are
    63     63   .QW \fB0o\fR
    64     64   then \fIsrc\fR is expected to be in octal form;  otherwise,
    65     65   if the first such characters are
    66     66   .QW \fB0b\fR
           67  +then \fIsrc\fR is expected to be in binary form;  otherwise,
           68  +if the first such character is
           69  +.QW \fB0\fR
    67     70   then \fIsrc\fR
    68         -is expected to be in binary 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, \fB__int64\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.

    29     29   structure.  Callers of \fBTcl_CreateInterp\fR should use this pointer
    30     30   as an opaque token, suitable for nothing other than passing back to
    31     31   other routines in the Tcl interface.  Accessing fields directly through
    32     32   the pointer as described below is no longer supported.  The supported
    33     33   public routines \fBTcl_SetResult\fR, \fBTcl_GetResult\fR,
    34     34   \fBTcl_SetErrorLine\fR, \fBTcl_GetErrorLine\fR must be used instead.
    35     35   .PP
           36  +For legacy programs and extensions no longer being maintained, compiles
           37  +against the Tcl 8.6 header files are only possible with the compiler
           38  +directives
           39  +.CS
           40  +#define USE_INTERP_RESULT
           41  +.CE
           42  +and/or
           43  +.CS
           44  +#define USE_INTERP_ERRORLINE
           45  +.CE
           46  +depending on which fields of the \fBTcl_Interp\fR struct are accessed.
           47  +These directives may be embedded in code or supplied via compiler options.
           48  +.PP
    36     49   The \fIresult\fR and \fIfreeProc\fR fields are used to return
    37     50   results or error messages from commands.
    38     51   This information is returned by command procedures back to \fBTcl_Eval\fR,
    39     52   and by \fBTcl_Eval\fR back to its callers.
    40     53   The \fIresult\fR field points to the string that represents the
    41     54   result or error message, and the \fIfreeProc\fR field tells how
    42     55   to dispose of the storage for the string when it is not needed anymore.
................................................................................
    84     97   As part of processing each command, \fBTcl_Eval\fR initializes
    85     98   \fIinterp->result\fR
    86     99   and \fIinterp->freeProc\fR just before calling the command procedure for
    87    100   the command.  The \fIfreeProc\fR field will be initialized to zero,
    88    101   and \fIinterp->result\fR will point to an empty string.  Commands that
    89    102   do not return any value can simply leave the fields alone.
    90    103   Furthermore, the empty string pointed to by \fIresult\fR is actually
    91         -part of an array of \fBTCL_RESULT_SIZE\fR characters (approximately 200).
          104  +part of an array of approximately 200 characters.
    92    105   If a command wishes to return a short string, it can simply copy
    93    106   it to the area pointed to by \fIinterp->result\fR.  Or, it can use
    94    107   the sprintf procedure to generate a short result string at the location
    95    108   pointed to by \fIinterp->result\fR.
    96    109   .PP
    97    110   It is a general convention in Tcl-based applications that the result
    98    111   of an interpreter is normally in the initialized state described

Changes to doc/Method.3.

     5      5   '\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
     6      6   '\"
     7      7   .TH Tcl_Method 3 0.1 TclOO "TclOO Library Functions"
     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         -Tcl_ClassSetConstructor, Tcl_ClassSetDestructor, Tcl_MethodDeclarerClass, Tcl_MethodDeclarerObject, Tcl_MethodIsPublic, Tcl_MethodIsType, Tcl_MethodName, Tcl_NewInstanceMethod, Tcl_NewMethod, Tcl_ObjectContextInvokeNext, Tcl_ObjectContextIsFiltering, Tcl_ObjectContextMethod, Tcl_ObjectContextObject, Tcl_ObjectContextSkippedArgs \- manipulate methods and method-call contexts
           12  +Tcl_ClassSetConstructor, Tcl_ClassSetDestructor, Tcl_MethodDeclarerClass, Tcl_MethodDeclarerObject, Tcl_MethodIsPublic, Tcl_MethodIsPrivate, Tcl_MethodIsType, Tcl_MethodName, Tcl_NewInstanceMethod, Tcl_NewMethod, Tcl_ObjectContextInvokeNext, Tcl_ObjectContextIsFiltering, Tcl_ObjectContextMethod, Tcl_ObjectContextObject, Tcl_ObjectContextSkippedArgs \- manipulate methods and method-call contexts
    13     13   .SH SYNOPSIS
    14     14   .nf
    15     15   \fB#include <tclOO.h>\fR
    16     16   .sp
    17     17   Tcl_Method
    18         -\fBTcl_NewMethod\fR(\fIinterp, class, nameObj, isPublic,
    19         -              methodTypePtr, clientData\fR)
           18  +\fBTcl_NewMethod\fR(\fIinterp, class, nameObj, flags, methodTypePtr,
           19  +              clientData\fR)
    20     20   .sp
    21     21   Tcl_Method
    22         -\fBTcl_NewInstanceMethod\fR(\fIinterp, object, nameObj, isPublic,
    23         -                      methodTypePtr, clientData\fR)
           22  +\fBTcl_NewInstanceMethod\fR(\fIinterp, object, nameObj, flags, methodTypePtr,
           23  +                      clientData\fR)
    24     24   .sp
    25     25   \fBTcl_ClassSetConstructor\fR(\fIinterp, class, method\fR)
    26     26   .sp
    27     27   \fBTcl_ClassSetDestructor\fR(\fIinterp, class, method\fR)
    28     28   .sp
    29     29   Tcl_Class
    30     30   \fBTcl_MethodDeclarerClass\fR(\fImethod\fR)
................................................................................
    31     31   .sp
    32     32   Tcl_Object
    33     33   \fBTcl_MethodDeclarerObject\fR(\fImethod\fR)
    34     34   .sp
    35     35   Tcl_Obj *
    36     36   \fBTcl_MethodName\fR(\fImethod\fR)
    37     37   .sp
           38  +.VS TIP500
    38     39   int
    39     40   \fBTcl_MethodIsPublic\fR(\fImethod\fR)
           41  +.VE TIP500
           42  +.sp
           43  +int
           44  +\fBTcl_MethodIsPrivate\fR(\fImethod\fR)
    40     45   .sp
    41     46   int
    42     47   \fBTcl_MethodIsType\fR(\fImethod, methodTypePtr, clientDataPtr\fR)
    43     48   .sp
    44     49   int
    45     50   \fBTcl_ObjectContextInvokeNext\fR(\fIinterp, context, objc, objv, skip\fR)
    46     51   .sp
................................................................................
    62     67   .AP Tcl_Object object in
    63     68   The object to create the method in.
    64     69   .AP Tcl_Class class in
    65     70   The class to create the method in.
    66     71   .AP Tcl_Obj *nameObj in
    67     72   The name of the method to create. Should not be NULL unless creating
    68     73   constructors or destructors.
    69         -.AP int isPublic in
    70         -A flag saying what the visibility of the method is. The only supported public
    71         -values of this flag are 0 for a non-exported method, and 1 for an exported
    72         -method.
           74  +.AP int flags in
           75  +A flag saying (currently) what the visibility of the method is. The supported
           76  +public values of this flag are \fBTCL_OO_METHOD_PUBLIC\fR (which is fixed at 1
           77  +for backward compatibility) for an exported method,
           78  +\fBTCL_OO_METHOD_UNEXPORTED\fR (which is fixed at 0 for backward
           79  +compatibility) for a non-exported method,
           80  +.VS TIP500
           81  +and \fBTCL_OO_METHOD_PRIVATE\fR for a private method.
           82  +.VE TIP500
    73     83   .AP Tcl_MethodType *methodTypePtr in
    74     84   A description of the type of the method to create, or the type of method to
    75     85   compare against.
    76     86   .AP ClientData clientData in
    77     87   A piece of data that is passed to the implementation of the method without
    78     88   interpretation.
    79     89   .AP ClientData *clientDataPtr out
................................................................................
   101    111   that class.
   102    112   .PP
   103    113   Given a method, the entity that declared it can be found using
   104    114   \fBTcl_MethodDeclarerClass\fR which returns the class that the method is
   105    115   attached to (or NULL if the method is not attached to any class) and
   106    116   \fBTcl_MethodDeclarerObject\fR which returns the object that the method is
   107    117   attached to (or NULL if the method is not attached to an object). The name of
   108         -the method can be retrieved with \fBTcl_MethodName\fR and whether the method
   109         -is exported is retrieved with \fBTcl_MethodIsPublic\fR. The type of the method
          118  +the method can be retrieved with \fBTcl_MethodName\fR, whether the method
          119  +is exported is retrieved with \fBTcl_MethodIsPublic\fR,
          120  +.VS TIP500
          121  +and whether the method is private is retrieved with \fBTcl_MethodIsPrivate\fR.
          122  +.VE TIP500
          123  +The type of the method
   110    124   can also be introspected upon to a limited degree; the function
   111    125   \fBTcl_MethodIsType\fR returns whether a method is of a particular type,
   112    126   assigning the per-method \fIclientData\fR to the variable pointed to by
   113    127   \fIclientDataPtr\fR if (that is non-NULL) if the type is matched.
   114    128   .SS "METHOD CREATION"
   115    129   .PP
   116    130   Methods are created by \fBTcl_NewMethod\fR and \fBTcl_NewInstanceMethod\fR,
   117    131   which
   118    132   create a method attached to a class or an object respectively. In both cases,
   119    133   the \fInameObj\fR argument gives the name of the method to create, the
   120         -\fIisPublic\fR argument states whether the method should be exported
   121         -initially, the \fImethodTypePtr\fR argument describes the implementation of
          134  +\fIflags\fR argument states whether the method should be exported
          135  +initially
          136  +.VS TIP500
          137  +or be marked as a private method,
          138  +.VE TIP500
          139  +the \fImethodTypePtr\fR argument describes the implementation of
   122    140   the method (see the \fBMETHOD TYPES\fR section below) and the \fIclientData\fR
   123    141   argument gives some implementation-specific data that is passed on to the
   124    142   implementation of the method when it is called.
   125    143   .PP
   126    144   When the \fInameObj\fR argument to \fBTcl_NewMethod\fR is NULL, an
   127    145   unnamed method is created, which is used for constructors and destructors.
   128    146   Constructors should be installed into their class using the

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.
   117         -.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.
   131         -.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:
           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.
          121  +.PP
          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.
          126  +.PP
          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/Panic.3.

     3      3   '\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
     4      4   '\"
     5      5   .TH Tcl_Panic 3 8.4 Tcl "Tcl Library Procedures"
     6      6   .so man.macros
     7      7   .BS
     8      8   '\"  Note:  do not modify the .SH NAME line immediately below!
     9      9   .SH NAME
    10         -Tcl_Panic, Tcl_PanicVA, Tcl_SetPanicProc \- report fatal error and abort
           10  +Tcl_Panic, Tcl_PanicVA, Tcl_SetPanicProc, Tcl_ConsolePanic \- report fatal error and abort
    11     11   .SH SYNOPSIS
    12     12   .nf
    13     13   \fB#include <tcl.h>\fR
    14     14   .sp
    15     15   void
    16     16   \fBTcl_Panic\fR(\fIformat\fR, \fIarg\fR, \fIarg\fR, \fI...\fR)
    17     17   .sp
    18     18   void
    19     19   \fBTcl_PanicVA\fR(\fIformat\fR, \fIargList\fR)
    20     20   .sp
    21     21   void
    22     22   \fBTcl_SetPanicProc\fR(\fIpanicProc\fR)
    23     23   .sp
           24  +void
           25  +\fBTcl_ConsolePanic\fR(\fIformat\fR, \fIarg\fR, \fIarg\fR, \fI...\fR)
           26  +.sp
    24     27   .SH ARGUMENTS
    25     28   .AS Tcl_PanicProc *panicProc
    26     29   .AP "const char*" format in
    27     30   A printf-style format string.
    28     31   .AP "" arg in
    29     32   Arguments matching the format string.
    30     33   .AP va_list argList in
................................................................................
    49     52   In a freshly loaded Tcl library, \fBTcl_Panic\fR prints the formatted
    50     53   error message to the standard error file of the process, and then
    51     54   calls \fBabort\fR to terminate the process.  \fBTcl_Panic\fR does not
    52     55   return. On Windows, when a debugger is running, the formatted error
    53     56   message is sent to the debugger in stead. If the windows executable
    54     57   does not have a stderr channel (e.g. \fBwish.exe\fR), then a
    55     58   system dialog box is used to display the panic message.
           59  +.PP
           60  +If your application doesn't use \fBTcl_Main\fR or \fBTk_Main\fR
           61  +and you want to implicitly use the stderr channel of your
           62  +application's C runtime (in stead of the stderr channel of the
           63  +C runtime used by Tcl), you can call \fBTcl_SetPanicProc\fR
           64  +with \fBTcl_ConsolePanic\fR as its argument. On platforms which
           65  +only have one C runtime (almost all platforms except Windows)
           66  +\fBTcl_ConsolePanic\fR is equivalent to NULL.
    56     67   .PP
    57     68   \fBTcl_SetPanicProc\fR may be used to modify the behavior of
    58     69   \fBTcl_Panic\fR.  The \fIpanicProc\fR argument should match the
    59     70   type \fBTcl_PanicProc\fR:
    60     71   .PP
    61     72   .CS
    62     73   typedef void \fBTcl_PanicProc\fR(

Changes to doc/SaveResult.3.

     1      1   '\"
     2      2   '\" Copyright (c) 1997 by Sun Microsystems, Inc.
     3      3   '\" Contributions from Don Porter, NIST, 2004. (not subject to US copyright)
            4  +'\" Copyright (c) 2018 Nathan Coulter. 
     4      5   '\"
     5      6   '\" See the file "license.terms" for information on usage and redistribution
     6      7   '\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
     7      8   '\"
     8      9   .TH Tcl_SaveResult 3 8.1 Tcl "Tcl Library Procedures"
     9     10   .so man.macros
    10     11   .BS
    11     12   .SH NAME
    12         -Tcl_SaveInterpState, Tcl_RestoreInterpState, Tcl_DiscardInterpState, Tcl_SaveResult, Tcl_RestoreResult, Tcl_DiscardResult \- save and restore an interpreter's state
           13  +Tcl_SaveInterpState, Tcl_RestoreInterpState, Tcl_DiscardInterpState,
           14  +Tcl_SaveResult, Tcl_RestoreResult, Tcl_DiscardResult \- Save and restore the
           15  +state of an an interpreter.
    13     16   .SH SYNOPSIS
    14     17   .nf
    15     18   \fB#include <tcl.h>\fR
    16     19   .sp
    17     20   Tcl_InterpState
    18     21   \fBTcl_SaveInterpState\fR(\fIinterp, status\fR)
    19     22   .sp
................................................................................
    26     29   .sp
    27     30   \fBTcl_RestoreResult\fR(\fIinterp, savedPtr\fR)
    28     31   .sp
    29     32   \fBTcl_DiscardResult\fR(\fIsavedPtr\fR)
    30     33   .SH ARGUMENTS
    31     34   .AS Tcl_InterpState savedPtr
    32     35   .AP Tcl_Interp *interp in
    33         -Interpreter for which state should be saved.
           36  +The interpreter for the operation.
    34     37   .AP int status in
    35         -Return code value to save as part of interpreter state.
           38  +The return code for the state.
    36     39   .AP Tcl_InterpState state in
    37         -Saved state token to be restored or discarded.
           40  +A token for saved state.
    38     41   .AP Tcl_SavedResult *savedPtr in
    39         -Pointer to location where interpreter result should be saved or restored.
           42  +A pointer to storage for saved state.
    40     43   .BE
    41     44   .SH DESCRIPTION
    42     45   .PP
    43         -These routines allows a C procedure to take a snapshot of the current
    44         -state of an interpreter so that it can be restored after a call
    45         -to \fBTcl_Eval\fR or some other routine that modifies the interpreter
    46         -state.  There are two triplets of routines meant to work together.
           46  +These routines save the state of an interpreter before a call to a routine such
           47  +as \fBTcl_Eval\fR, and restore the state afterwards.
           48  +.PP
           49  +\fBTcl_SaveInterpState\fR saves the parts of \fIinterp\fR that comprise the
           50  +result of a script, including the resulting value, the return code passed as
           51  +\fIstatus\fR, and any options such as \fB\-errorinfo\fR and \fB\-errorcode\fR.
           52  +It returns a token for the saved state.  The interpreter result is not reset
           53  +and no interpreter state is changed.
           54  +.PP
           55  +\fBTcl_RestoreInterpState\fR restores the state indicated by \fIstate\fR and
           56  +returns the \fIstatus\fR originally passed in the corresponding call to
           57  +\fBTcl_SaveInterpState\fR.
           58  +.PP
           59  +If a saved state is not restored, \fBTcl_DiscardInterpState\fR must be called
           60  +to release it.  A token used to discard or restore state must not be used
           61  +again.
    47     62   .PP
    48         -The first triplet stores the snapshot of interpreter state in
    49         -an opaque token returned by \fBTcl_SaveInterpState\fR.  That token
    50         -value may then be passed back to one of \fBTcl_RestoreInterpState\fR
    51         -or \fBTcl_DiscardInterpState\fR, depending on whether the interp
    52         -state is to be restored.  So long as one of the latter two routines
    53         -is called, Tcl will take care of memory management.
           63  +\fBTcl_SaveResult\fR, \fBTcl_RestoreResult\fR, and \fBTcl_DiscardResult\fR are
           64  +deprecated.  Instead use \fBTcl_SaveInterpState\fR,
           65  +\fBTcl_RestoreInterpState\fR, and \fBTcl_DiscardInterpState\fR, which are more
           66  +capable.
    54     67   .PP
    55         -The second triplet stores the snapshot of only the interpreter
    56         -result (not its complete state) in memory allocated by the caller.
    57         -These routines are passed a pointer to \fBTcl_SavedResult\fR
    58         -that is used to store enough information to restore the interpreter result.
    59         -\fBTcl_SavedResult\fR can be allocated on the stack of the calling
    60         -procedure.  These routines do not save the state of any error
    61         -information in the interpreter (e.g. the \fB\-errorcode\fR or
    62         -\fB\-errorinfo\fR return options, when an error is in progress).
           68  +\fBTcl_SaveResult\fR moves the result of \fIinterp\fR to the location
           69  +\fIstatePtr\fR points to and returns the interpreter result to its initial
           70  +state.  It does not save options such as \fB\-errorcode\fR or
           71  +\fB\-errorinfo\fR.
    63     72   .PP
    64         -Because the routines \fBTcl_SaveInterpState\fR,
    65         -\fBTcl_RestoreInterpState\fR, and \fBTcl_DiscardInterpState\fR perform
    66         -a superset of the functions provided by the other routines,
    67         -any new code should only make use of the more powerful routines.
    68         -The older, weaker routines \fBTcl_SaveResult\fR, \fBTcl_RestoreResult\fR,
    69         -and \fBTcl_DiscardResult\fR continue to exist only for the sake
    70         -of existing programs that may already be using them.
           73  +\fBTcl_RestoreResult\fR clears any existing result or error in \fIinterp\fR and
           74  +moves the result from \fIstatePtr\fR back to \fIinterp\fR.  \fIstatePtr\fR is
           75  +then in an undefined state and must not be used until passed again to
           76  +\fBTcl_SaveResult\fR.
    71     77   .PP
    72         -\fBTcl_SaveInterpState\fR takes a snapshot of those portions of
    73         -interpreter state that make up the full result of script evaluation.
    74         -This include the interpreter result, the return code (passed in
    75         -as the \fIstatus\fR argument, and any return options, including
    76         -\fB\-errorinfo\fR and \fB\-errorcode\fR when an error is in progress.
    77         -This snapshot is returned as an opaque token of type \fBTcl_InterpState\fR.
    78         -The call to \fBTcl_SaveInterpState\fR does not itself change the
    79         -state of the interpreter.  Unlike \fBTcl_SaveResult\fR, it does
    80         -not reset the interpreter.
    81         -.PP
    82         -\fBTcl_RestoreInterpState\fR accepts a \fBTcl_InterpState\fR token
    83         -previously returned by \fBTcl_SaveInterpState\fR and restores the
    84         -state of the interp to the state held in that snapshot.  The return
    85         -value of \fBTcl_RestoreInterpState\fR is the status value originally
    86         -passed to \fBTcl_SaveInterpState\fR when the snapshot token was
    87         -created.
    88         -.PP
    89         -\fBTcl_DiscardInterpState\fR is called to release a \fBTcl_InterpState\fR
    90         -token previously returned by \fBTcl_SaveInterpState\fR when that
    91         -snapshot is not to be restored to an interp.
    92         -.PP
    93         -The \fBTcl_InterpState\fR token returned by \fBTcl_SaveInterpState\fR
    94         -must eventually be passed to either \fBTcl_RestoreInterpState\fR
    95         -or \fBTcl_DiscardInterpState\fR to avoid a memory leak.  Once
    96         -the \fBTcl_InterpState\fR token is passed to one of them, the
    97         -token is no longer valid and should not be used anymore.
    98         -.PP
    99         -\fBTcl_SaveResult\fR moves the string and value results
   100         -of \fIinterp\fR into the location specified by \fIstatePtr\fR.
   101         -\fBTcl_SaveResult\fR clears the result for \fIinterp\fR and
   102         -leaves the result in its normal empty initialized state.
   103         -.PP
   104         -\fBTcl_RestoreResult\fR moves the string and value results from
   105         -\fIstatePtr\fR back into \fIinterp\fR.  Any result or error that was
   106         -already in the interpreter will be cleared.  The \fIstatePtr\fR is left
   107         -in an uninitialized state and cannot be used until another call to
           78  +\fBTcl_DiscardResult\fR releases the state stored at \fBstatePtr\fR, which is
           79  +then in an undefined state and must not be used until passed again to
   108     80   \fBTcl_SaveResult\fR.
   109     81   .PP
   110         -\fBTcl_DiscardResult\fR releases the saved interpreter state
   111         -stored at \fBstatePtr\fR.  The state structure is left in an
   112         -uninitialized state and cannot be used until another call to
   113         -\fBTcl_SaveResult\fR.
   114         -.PP
   115         -Once \fBTcl_SaveResult\fR is called to save the interpreter
   116         -result, either \fBTcl_RestoreResult\fR or
   117         -\fBTcl_DiscardResult\fR must be called to properly clean up the
   118         -memory associated with the saved state.
           82  +If a saved result is not restored, \fBTcl_DiscardResult\fR must be called to
           83  +release it.
   119     84   .SH KEYWORDS
   120     85   result, state, interp

Changes to doc/SetResult.3.

   193    193   \fBTcl_FreeResult\fR performs part of the work
   194    194   of \fBTcl_ResetResult\fR.
   195    195   It frees up the memory associated with \fIinterp\fR's result.
   196    196   It also sets \fIinterp->freeProc\fR to zero, but does not
   197    197   change \fIinterp->result\fR or clear error state.
   198    198   \fBTcl_FreeResult\fR is most commonly used when a procedure
   199    199   is about to replace one result value with another.
          200  +.SS "DIRECT ACCESS TO INTERP->RESULT"
          201  +.PP
          202  +It used to be legal for programs to
          203  +directly read and write \fIinterp->result\fR
          204  +to manipulate the interpreter result.  The Tcl headers no longer
          205  +permit this access by default, and C code still doing this must
          206  +be updated to use supported routines \fBTcl_GetObjResult\fR,
          207  +\fBTcl_GetStringResult\fR, \fBTcl_SetObjResult\fR, and \fBTcl_SetResult\fR.
          208  +As a migration aid, access can be restored with the compiler directive
          209  +.CS
          210  +#define USE_INTERP_RESULT
          211  +.CE
          212  +but this is meant only to offer life support to otherwise dead code.
   200    213   .SH "THE TCL_FREEPROC ARGUMENT TO TCL_SETRESULT"
   201    214   .PP
   202    215   \fBTcl_SetResult\fR's \fIfreeProc\fR argument specifies how
   203    216   the Tcl system is to manage the storage for the \fIresult\fR argument.
   204    217   If \fBTcl_SetResult\fR or \fBTcl_SetObjResult\fR are called
   205    218   at a time when \fIinterp\fR holds a string result,
   206    219   they do whatever is necessary to dispose of the old string result

Changes to doc/StringObj.3.

    33     33   .sp
    34     34   Tcl_UniChar *
    35     35   \fBTcl_GetUnicodeFromObj\fR(\fIobjPtr, lengthPtr\fR)
    36     36   .sp
    37     37   Tcl_UniChar *
    38     38   \fBTcl_GetUnicode\fR(\fIobjPtr\fR)
    39     39   .sp
    40         -Tcl_UniChar
           40  +int
    41     41   \fBTcl_GetUniChar\fR(\fIobjPtr, index\fR)
    42     42   .sp
    43     43   int
    44     44   \fBTcl_GetCharLength\fR(\fIobjPtr\fR)
    45     45   .sp
    46     46   Tcl_Obj *
    47     47   \fBTcl_GetRange\fR(\fIobjPtr, first, last\fR)
................................................................................
   200    200   \fIlengthPtr\fR if it is non-NULL.  The storage referenced by the returned
   201    201   byte pointer is owned by the value manager and should not be modified by
   202    202   the caller.  The procedure \fBTcl_GetUnicode\fR is used in the common case
   203    203   where the caller does not need the length of the unicode string
   204    204   representation.
   205    205   .PP
   206    206   \fBTcl_GetUniChar\fR returns the \fIindex\fR'th character in the
   207         -value's Unicode representation.
          207  +value's Unicode representation. If the index is out of range or
          208  +it references a low surrogate preceded by a high surrogate, it returns -1;
   208    209   .PP
   209    210   \fBTcl_GetRange\fR returns a newly created value comprised of the
   210    211   characters between \fIfirst\fR and \fIlast\fR (inclusive) in the
   211    212   value's Unicode representation.  If the value's Unicode
   212    213   representation is invalid, the Unicode representation is regenerated
   213    214   from the value's string representation.
   214    215   .PP

Changes to doc/ToUpper.3.

     9      9   .BS
    10     10   .SH NAME
    11     11   Tcl_UniCharToUpper, Tcl_UniCharToLower, Tcl_UniCharToTitle, Tcl_UtfToUpper, Tcl_UtfToLower, Tcl_UtfToTitle \- routines for manipulating the case of Unicode characters and UTF-8 strings
    12     12   .SH SYNOPSIS
    13     13   .nf
    14     14   \fB#include <tcl.h>\fR
    15     15   .sp
    16         -Tcl_UniChar
           16  +int
    17     17   \fBTcl_UniCharToUpper\fR(\fIch\fR)
    18     18   .sp
    19         -Tcl_UniChar
           19  +int
    20     20   \fBTcl_UniCharToLower\fR(\fIch\fR)
    21     21   .sp
    22         -Tcl_UniChar
           22  +int
    23     23   \fBTcl_UniCharToTitle\fR(\fIch\fR)
    24     24   .sp
    25     25   int
    26     26   \fBTcl_UtfToUpper\fR(\fIstr\fR)
    27     27   .sp
    28     28   int
    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.

    59     59   .sp
    60     60   const char *
    61     61   \fBTcl_UtfNext\fR(\fIsrc\fR)
    62     62   .sp
    63     63   const char *
    64     64   \fBTcl_UtfPrev\fR(\fIsrc, start\fR)
    65     65   .sp
    66         -Tcl_UniChar
           66  +int
    67     67   \fBTcl_UniCharAtIndex\fR(\fIsrc, index\fR)
    68     68   .sp
    69     69   const char *
    70     70   \fBTcl_UtfAtIndex\fR(\fIsrc, index\fR)
    71     71   .sp
    72     72   int
    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
................................................................................
   117    117   .AP int nocase in
   118    118   Specifies whether the match should be done case-sensitive (0) or
   119    119   case-insensitive (1).
   120    120   .BE
   121    121   
   122    122   .SH DESCRIPTION
   123    123   .PP
   124         -These routines convert between UTF-8 strings and Tcl_UniChars.  A
   125         -Tcl_UniChar is a Unicode character represented as an unsigned, fixed-size
          124  +These routines convert between UTF-8 strings and Unicode characters.  An
          125  +Unicode character represented as an unsigned, fixed-size
   126    126   quantity.  A UTF-8 character is a Unicode character represented as
   127    127   a varying-length sequence of up to \fBTCL_UTF_MAX\fR bytes.  A multibyte UTF-8
   128    128   sequence consists of a lead byte followed by some number of trail bytes.
   129    129   .PP
   130    130   \fBTCL_UTF_MAX\fR is the maximum number of bytes that it takes to
   131    131   represent one Unicode character in the UTF-8 representation.
   132    132   .PP
   133         -\fBTcl_UniCharToUtf\fR stores the Tcl_UniChar \fIch\fR as a UTF-8 string
          133  +\fBTcl_UniCharToUtf\fR stores the character \fIch\fR as a UTF-8 string
   134    134   in starting at \fIbuf\fR.  The return value is the number of bytes stored
   135         -in \fIbuf\fR.
          135  +in \fIbuf\fR. If ch is an upper surrogate (range U+D800 - U+DBFF), then
          136  +the return value will be 0 and nothing will be stored. If you still
          137  +want to produce UTF-8 output for it (even though knowing it's an illegal
          138  +code-point on its own), just call \fBTcl_UniCharToUtf\fR again using ch = -1.
   136    139   .PP
   137    140   \fBTcl_UtfToUniChar\fR reads one UTF-8 character starting at \fIsrc\fR
   138    141   and stores it as a Tcl_UniChar in \fI*chPtr\fR.  The return value is the
   139    142   number of bytes read from \fIsrc\fR.  The caller must ensure that the
   140    143   source buffer is long enough such that this routine does not run off the
   141    144   end and dereference non-existent or random memory; if the source buffer
   142    145   is known to be null-terminated, this will not happen.  If the input is
          146  +a byte in the range 0x80 - 0x9F, \fBTcl_UtfToUniChar\fR assumes the
          147  +cp1252 encoding, stores the corresponding Tcl_UniChar in \fI*chPtr\fR
          148  +and returns 1. If the input is otherwise
   143    149   not in proper UTF-8 format, \fBTcl_UtfToUniChar\fR will store the first
   144    150   byte of \fIsrc\fR in \fI*chPtr\fR as a Tcl_UniChar between 0x0000 and
   145    151   0x00ff and return 1.
   146    152   .PP
   147    153   \fBTcl_UniCharToUtfDString\fR converts the given Unicode string
   148    154   to UTF-8, storing the result in a previously initialized \fBTcl_DString\fR.
   149    155   You must specify \fIuniLength\fR, the length of the given Unicode string.
................................................................................
   196    202   characters.
   197    203   .PP
   198    204   \fBTcl_UtfCharComplete\fR returns 1 if the source UTF-8 string \fIsrc\fR
   199    205   of \fIlength\fR bytes is long enough to be decoded by
   200    206   \fBTcl_UtfToUniChar\fR, or 0 otherwise.  This function does not guarantee
   201    207   that the UTF-8 string is properly formed.  This routine is used by
   202    208   procedures that are operating on a byte at a time and need to know if a
   203         -full Tcl_UniChar has been seen.
          209  +full Unicode character has been seen.
   204    210   .PP
   205    211   \fBTcl_NumUtfChars\fR corresponds to \fBstrlen\fR for UTF-8 strings.  It
   206    212   returns the number of Tcl_UniChars that are represented by the UTF-8 string
   207    213   \fIsrc\fR.  The length of the source string is \fIlength\fR bytes.  If the
   208    214   length is negative, all bytes up to the first null byte are used.
   209    215   .PP
   210    216   \fBTcl_UtfFindFirst\fR corresponds to \fBstrchr\fR for UTF-8 strings.  It
   211         -returns a pointer to the first occurrence of the Tcl_UniChar \fIch\fR
          217  +returns a pointer to the first occurrence of the Unicode character \fIch\fR
   212    218   in the null-terminated UTF-8 string \fIsrc\fR.  The null terminator is
   213    219   considered part of the UTF-8 string.
   214    220   .PP
   215    221   \fBTcl_UtfFindLast\fR corresponds to \fBstrrchr\fR for UTF-8 strings.  It
   216         -returns a pointer to the last occurrence of the Tcl_UniChar \fIch\fR
          222  +returns a pointer to the last occurrence of the Unicode character \fIch\fR
   217    223   in the null-terminated UTF-8 string \fIsrc\fR.  The null terminator is
   218    224   considered part of the UTF-8 string.
   219    225   .PP
   220    226   Given \fIsrc\fR, a pointer to some location in a UTF-8 string,
   221    227   \fBTcl_UtfNext\fR returns a pointer to the next UTF-8 character in the
   222    228   string.  The caller must not ask for the next character after the last
   223    229   character in the string if the string is not terminated by a null

Changes to doc/array.n.

    43     43   been the return value from a previous invocation of
    44     44   \fBarray startsearch\fR.  Returns an empty string.
    45     45   .TP
    46     46   \fBarray exists \fIarrayName\fR
    47     47   Returns 1 if \fIarrayName\fR is an array variable, 0 if there
    48     48   is no variable by that name or if it is a scalar variable.
    49     49   .TP
           50  +\fBarray for {\fIkeyVariable valueVariable\fB} \fIarrayName body\fP
           51  +The first argument is a two element list of variable names for the
           52  +key and value of each entry in the array.  The second argument is the
           53  +array name to iterate over.  The third argument is the body to execute
           54  +for each key and value returned.
           55  +The ordering of the returned keys is undefined.
           56  +If an array element is deleted or a new array element is inserted during
           57  +the \fIarray for\fP process, the command will terminate with an error.
           58  +.TP
    50     59   \fBarray get \fIarrayName\fR ?\fIpattern\fR?
    51     60   Returns a list containing pairs of elements.  The first
    52     61   element in each pair is the name of an element in \fIarrayName\fR
    53     62   and the second element of each pair is the value of the
    54     63   array element.  The order of the pairs is undefined.
    55     64   If \fIpattern\fR is not specified, then all of the elements of the
    56     65   array are included in the result.

Changes to doc/clock.n.

   448    448   If a format string lacks a \fB%z\fR or \fB%Z\fR format group,
   449    449   it is possible for the time to be ambiguous because it appears twice
   450    450   in the same day, once without and once with Daylight Saving Time.
   451    451   If this situation occurs, the first occurrence of the time is chosen.
   452    452   (For this reason, it is wise to have the input string contain the
   453    453   time zone when converting local times.  This caveat does not apply to
   454    454   UTC times.)
          455  +.PP
          456  +If the interpretation of the groups yields an impossible time because
          457  +a field is out of range, enough of that field's unit will be added to
          458  +or subtracted from the time to bring it in range. Thus, if attempting to
          459  +scan or format day 0 of the month, one day will be subtracted from day
          460  +1 of the month, yielding the last day of the previous month.
          461  +.PP
          462  +If the interpretation of the groups yields an impossible time because
          463  +a Daylight Saving Time change skips over that time, or an ambiguous
          464  +time because a Daylight Saving Time change skips back so that the clock
          465  +observes the given time twice, and no time zone specifier (\fB%z\fR
          466  +or \fB%Z\fR) is present in the format, the time is interpreted as
          467  +if the clock had not changed.
   455    468   .SH "FORMAT GROUPS"
   456    469   .PP
   457    470   The following format groups are recognized by the \fBclock scan\fR and
   458    471   \fBclock format\fR commands.
   459    472   .TP
   460    473   \fB%a\fR
   461    474   On output, receives an abbreviation (\fIe.g.,\fR \fBMon\fR) for the day

Changes to doc/define.n.

    46     46   command) will be \fIargList\fR, and the body of the constructor will be
    47     47   \fIbodyScript\fR. When the body of the constructor is evaluated, the current
    48     48   namespace of the constructor will be a namespace that is unique to the object
    49     49   being constructed. Within the constructor, the \fBnext\fR command should be
    50     50   used to call the superclasses' constructors. If \fIbodyScript\fR is the empty
    51     51   string, the constructor will be deleted.
    52     52   .TP
    53         -\fBdeletemethod\fI name\fR ?\fIname ...\fR
           53  +\fBdeletemethod\fI name\fR ?\fIname ...\fR?
    54     54   .
    55     55   This deletes each of the methods called \fIname\fR from a class. The methods
    56     56   must have previously existed in that class. Does not affect the superclasses
    57     57   of the class, nor does it affect the subclasses or instances of the class
    58     58   (except when they have a call chain through the class being modified).
    59     59   .TP
    60     60   \fBdestructor\fI bodyScript\fR
................................................................................
    78     78   This arranges for each of the named methods, \fIname\fR, to be exported
    79     79   (i.e. usable outside an instance through the instance object's command) by the
    80     80   class being defined. Note that the methods themselves may be actually defined
    81     81   by a superclass; subclass exports override superclass visibility, and may in
    82     82   turn be overridden by instances.
    83     83   .TP
    84     84   \fBfilter\fR ?\fI\-slotOperation\fR? ?\fImethodName ...\fR?
    85         -.VS
           85  +.
    86     86   This slot (see \fBSLOTTED DEFINITIONS\fR below)
    87         -.VE
    88     87   sets or updates the list of method names that are used to guard whether
    89     88   method call to instances of the class may be called and what the method's
    90     89   results are. Each \fImethodName\fR names a single filtering method (which may
    91     90   be exposed or not exposed); it is not an error for a non-existent method to be
    92     91   named since they may be defined by subclasses.
    93         -.VS
    94     92   By default, this slot works by appending.
    95         -.VE
    96     93   .TP
    97     94   \fBforward\fI name cmdName \fR?\fIarg ...\fR?
    98     95   .
    99     96   This creates or updates a forwarded method called \fIname\fR. The method is
   100     97   defined be forwarded to the command called \fIcmdName\fR, with additional
   101     98   arguments, \fIarg\fR etc., added before those arguments specified by the
   102     99   caller of the method. The \fIcmdName\fR will always be resolved using the
   103    100   rules of the invoking objects' namespaces, i.e., when \fIcmdName\fR is not
   104    101   fully-qualified, the command will be searched for in each object's namespace,
   105    102   using the instances' namespace's path, or by looking in the global namespace.
   106    103   The method will be exported if \fIname\fR starts with a lower-case letter, and
   107    104   non-exported otherwise.
          105  +.RS
          106  +.PP
          107  +.VS TIP500
          108  +If in a private definition context (see the \fBprivate\fR definition command,
          109  +below), this command creates private forwarded methods.
          110  +.VE TIP500
          111  +.RE
   108    112   .TP
   109    113   \fBmethod\fI name argList bodyScript\fR
   110    114   .
   111    115   This creates or updates a method that is implemented as a procedure-like
   112    116   script. The name of the method is \fIname\fR, the formal arguments to the
   113    117   method (defined using the same format as for the Tcl \fBproc\fR command) will
   114    118   be \fIargList\fR, and the body of the method will be \fIbodyScript\fR. When
   115    119   the body of the method is evaluated, the current namespace of the method will
   116    120   be a namespace that is unique to the current object. The method will be
   117    121   exported if \fIname\fR starts with a lower-case letter, and non-exported
   118    122   otherwise; this behavior can be overridden via \fBexport\fR and
   119    123   \fBunexport\fR.
          124  +.RS
          125  +.PP
          126  +.VS TIP500
          127  +If in a private definition context (see the \fBprivate\fR definition command,
          128  +below), this command creates private procedure-like methods.
          129  +.VE TIP500
          130  +.RE
   120    131   .TP
   121    132   \fBmixin\fR ?\fI\-slotOperation\fR? ?\fIclassName ...\fR?
   122         -.VS
          133  +.
   123    134   This slot (see \fBSLOTTED DEFINITIONS\fR below)
   124         -.VE
   125    135   sets or updates the list of additional classes that are to be mixed into
   126    136   all the instances of the class being defined. Each \fIclassName\fR argument
   127    137   names a single class that is to be mixed in.
   128         -.VS
   129    138   By default, this slot works by replacement.
   130         -.VE
          139  +.TP
          140  +\fBprivate \fIcmd arg...\fR
          141  +.TP
          142  +\fBprivate \fIscript\fR
          143  +.
          144  +.VS TIP500
          145  +This evaluates the \fIscript\fR (or the list of command and arguments given by
          146  +\fIcmd\fR and \fIarg\fRs) in a context where the definitions made on the
          147  +current class will be private definitions.
          148  +.RS
          149  +.PP
          150  +The following class definition commands are affected by \fBprivate\fR:
          151  +\fBforward\fR, \fBmethod\fR, \fBself\fR, and \fBvariable\fR. Nesting
          152  +\fBprivate\fR inside \fBprivate\fR has no cumulative effect; the innermost
          153  +definition context is just a private definition context. All other definition
          154  +commands have no difference in behavior when used in a private definition
          155  +context.
          156  +.RE
          157  +.VE TIP500
   131    158   .TP
   132    159   \fBrenamemethod\fI fromName toName\fR
   133    160   .
   134    161   This renames the method called \fIfromName\fR in a class to \fItoName\fR. The
   135    162   method must have previously existed in the class, and \fItoName\fR must not
   136    163   previously refer to a method in that class. Does not affect the superclasses
   137    164   of the class, nor does it affect the subclasses or instances of the class
................................................................................
   155    182   .QW "\fBoo::objdefine \fIcls subcommand ...\fR" .
   156    183   .RS
   157    184   .PP
   158    185   .VS TIP470
   159    186   If no arguments at all are used, this gives the name of the class currently
   160    187   being configured.
   161    188   .VE TIP470
          189  +.VS TIP500
          190  +If in a private definition context (see the \fBprivate\fR definition command,
          191  +below), the definitions on the class object will also be made in a private
          192  +definition context.
          193  +.VE TIP500
   162    194   .RE
   163    195   .TP
   164    196   \fBsuperclass\fR ?\fI\-slotOperation\fR? ?\fIclassName ...\fR?
   165         -.VS
          197  +.
   166    198   This slot (see \fBSLOTTED DEFINITIONS\fR below)
   167         -.VE
   168    199   allows the alteration of the superclasses of the class being defined.
   169    200   Each \fIclassName\fR argument names one class that is to be a superclass of
   170    201   the defined class. Note that objects must not be changed from being classes to
   171    202   being non-classes or vice-versa, that an empty parent class is equivalent to
   172    203   \fBoo::object\fR, and that the parent classes of \fBoo::object\fR and
   173    204   \fBoo::class\fR may not be modified.
   174         -.VS
   175    205   By default, this slot works by replacement.
   176         -.VE
   177    206   .TP
   178    207   \fBunexport\fI name \fR?\fIname ...\fR?
   179    208   .
   180    209   This arranges for each of the named methods, \fIname\fR, to be not exported
   181    210   (i.e. not usable outside the instance through the instance object's command,
   182    211   but instead just through the \fBmy\fR command visible in each object's
   183    212   context) by the class being defined. Note that the methods themselves may be
   184    213   actually defined by a superclass; subclass unexports override superclass
   185    214   visibility, and may be overridden by instance unexports.
   186    215   .TP
   187    216   \fBvariable\fR ?\fI\-slotOperation\fR? ?\fIname ...\fR?
   188         -.VS
          217  +.
   189    218   This slot (see \fBSLOTTED DEFINITIONS\fR below) arranges for each of the named
   190    219   variables to be automatically made
   191    220   available in the methods, constructor and destructor declared by the class
   192    221   being defined. Each variable name must not have any namespace
   193    222   separators and must not look like an array access. All variables will be
   194         -actually present in the instance object on which the method is executed. Note
          223  +actually present in the namespace of the instance object on which the method
          224  +is executed. Note
   195    225   that the variable lists declared by a superclass or subclass are completely
   196    226   disjoint, as are variable lists declared by instances; the list of variable
   197    227   names is just for methods (and constructors and destructors) declared by this
   198    228   class. By default, this slot works by appending.
   199         -.VE
          229  +.RS
          230  +.PP
          231  +.VS TIP500
          232  +If in a private definition context (see the \fBprivate\fR definition command,
          233  +below), this slot manipulates the list of private variable bindings for this
          234  +class. In a private variable binding, the name of the variable within the
          235  +instance object is different to the name given in the definition; the name
          236  +used in the definition is the name that you use to access the variable within
          237  +the methods of this class, and the name of the variable in the instance
          238  +namespace has a unique prefix that makes accidental use from other classes
          239  +extremely unlikely.
          240  +.VE TIP500
          241  +.RE
   200    242   .SS "CONFIGURING OBJECTS"
   201    243   .PP
   202    244   The following commands are supported in the \fIdefScript\fR for
   203    245   \fBoo::objdefine\fR, each of which may also be used in the \fIsubcommand\fR
   204    246   form:
   205    247   .TP
   206    248   \fBclass\fI className\fR
................................................................................
   219    261   .
   220    262   This arranges for each of the named methods, \fIname\fR, to be exported
   221    263   (i.e. usable outside the object through the object's command) by the object
   222    264   being defined. Note that the methods themselves may be actually defined by a
   223    265   class or superclass; object exports override class visibility.
   224    266   .TP
   225    267   \fBfilter\fR ?\fI\-slotOperation\fR? ?\fImethodName ...\fR?
   226         -.VS
          268  +.
   227    269   This slot (see \fBSLOTTED DEFINITIONS\fR below)
   228         -.VE
   229    270   sets or updates the list of method names that are used to guard whether a
   230    271   method call to the object may be called and what the method's results are.
   231    272   Each \fImethodName\fR names a single filtering method (which may be exposed or
   232    273   not exposed); it is not an error for a non-existent method to be named. Note
   233    274   that the actual list of filters also depends on the filters set upon any
   234    275   classes that the object is an instance of.
   235         -.VS
   236    276   By default, this slot works by appending.
   237         -.VE
   238    277   .TP
   239    278   \fBforward\fI name cmdName \fR?\fIarg ...\fR?
   240    279   .
   241    280   This creates or updates a forwarded object method called \fIname\fR. The
   242    281   method is defined be forwarded to the command called \fIcmdName\fR, with
   243    282   additional arguments, \fIarg\fR etc., added before those arguments specified
   244    283   by the caller of the method. Forwarded methods should be deleted using the
   245    284   \fBmethod\fR subcommand. The method will be exported if \fIname\fR starts with
   246    285   a lower-case letter, and non-exported otherwise.
          286  +.RS
          287  +.PP
          288  +.VS TIP500
          289  +If in a private definition context (see the \fBprivate\fR definition command,
          290  +below), this command creates private forwarded methods.
          291  +.VE TIP500
          292  +.RE
   247    293   .TP
   248    294   \fBmethod\fI name argList bodyScript\fR
   249    295   .
   250    296   This creates, updates or deletes an object method. The name of the method is
   251    297   \fIname\fR, the formal arguments to the method (defined using the same format
   252    298   as for the Tcl \fBproc\fR command) will be \fIargList\fR, and the body of the
   253    299   method will be \fIbodyScript\fR. When the body of the method is evaluated, the
   254    300   current namespace of the method will be a namespace that is unique to the
   255    301   object. The method will be exported if \fIname\fR starts with a lower-case
   256    302   letter, and non-exported otherwise.
          303  +.RS
          304  +.PP
          305  +.VS TIP500
          306  +If in a private definition context (see the \fBprivate\fR definition command,
          307  +below), this command creates private procedure-like methods.
          308  +.VE TIP500
          309  +.RE
   257    310   .TP
   258    311   \fBmixin\fR ?\fI\-slotOperation\fR? ?\fIclassName ...\fR?
   259         -.VS
          312  +.
   260    313   This slot (see \fBSLOTTED DEFINITIONS\fR below)
   261         -.VE
   262    314   sets or updates a per-object list of additional classes that are to be
   263    315   mixed into the object. Each argument, \fIclassName\fR, names a single class
   264    316   that is to be mixed in.
   265         -.VS
   266    317   By default, this slot works by replacement.
   267         -.VE
          318  +.TP
          319  +\fBprivate \fIcmd arg...\fR
          320  +.TP
          321  +\fBprivate \fIscript\fR
          322  +.VS TIP500
          323  +This evaluates the \fIscript\fR (or the list of command and arguments given by
          324  +\fIcmd\fR and \fIarg\fRs) in a context where the definitions made on the
          325  +current object will be private definitions.
          326  +.RS
          327  +.PP
          328  +The following class definition commands are affected by \fBprivate\fR:
          329  +\fBforward\fR, \fBmethod\fR, and \fBvariable\fR. Nesting \fBprivate\fR inside
          330  +\fBprivate\fR has no cumulative effect; the innermost definition context is
          331  +just a private definition context. All other definition commands have no
          332  +difference in behavior when used in a private definition context.
          333  +.RE
          334  +.VE TIP500
   268    335   .TP
   269    336   \fBrenamemethod\fI fromName toName\fR
   270    337   .
   271    338   This renames the method called \fIfromName\fR in an object to \fItoName\fR.
   272    339   The method must have previously existed in the object, and \fItoName\fR must
   273    340   not previously refer to a method in that object. Does not affect the classes
   274    341   that the object is an instance of. Does not change the export status of the
   275    342   method; if it was exported before, it will be afterwards.
   276    343   .TP
   277    344   \fBself \fR
   278         -.
   279    345   .VS TIP470
   280    346   This gives the name of the object currently being configured.
   281    347   .VE TIP470
   282    348   .TP
   283    349   \fBunexport\fI name \fR?\fIname ...\fR?
   284    350   .
   285    351   This arranges for each of the named methods, \fIname\fR, to be not exported
   286    352   (i.e. not usable outside the object through the object's command, but instead
   287    353   just through the \fBmy\fR command visible in the object's context) by the
   288    354   object being defined. Note that the methods themselves may be actually defined
   289    355   by a class; instance unexports override class visibility.
   290    356   .TP
   291    357   \fBvariable\fR ?\fI\-slotOperation\fR? ?\fIname ...\fR?
   292         -.VS
          358  +.
   293    359   This slot (see \fBSLOTTED DEFINITIONS\fR below) arranges for each of the named
   294    360   variables to be automatically made available in the methods declared by the
   295    361   object being defined.  Each variable name must not have any namespace
   296    362   separators and must not look like an array access. All variables will be
   297         -actually present in the object on which the method is executed. Note that the
          363  +actually present in the namespace of the object on which the method is
          364  +executed. Note that the
   298    365   variable lists declared by the classes and mixins of which the object is an
   299    366   instance are completely disjoint; the list of variable names is just for
   300    367   methods declared by this object. By default, this slot works by appending.
          368  +.RS
          369  +.PP
          370  +.VS TIP500
          371  +If in a private definition context (see the \fBprivate\fR definition command,
          372  +below), this slot manipulates the list of private variable bindings for this
          373  +object.  In a private variable binding, the name of the variable within the
          374  +instance object is different to the name given in the definition; the name
          375  +used in the definition is the name that you use to access the variable within
          376  +the methods of this instance object, and the name of the variable in the
          377  +instance namespace has a unique prefix that makes accidental use from
          378  +superclass methods extremely unlikely.
          379  +.VE TIP500
          380  +.RE
          381  +.SH "PRIVATE METHODS"
          382  +.VS TIP500
          383  +When a class or instance has a private method, that private method can only be
          384  +invoked from within methods of that class or instance. Other callers of the
          385  +object's methods \fIcannot\fR invoke private methods, it is as if the private
          386  +methods do not exist. However, a private method of a class \fIcan\fR be
          387  +invoked from the class's methods when those methods are being used on another
          388  +instance object; this means that a class can use them to coordinate behaviour
          389  +between several instances of itself without interfering with how other
          390  +classes (especially either subclasses or superclasses) interact. Private
          391  +methods precede all mixed in classes in the method call order (as reported by
          392  +\fBself call\fR).
          393  +.VE TIP500
   301    394   .SH "SLOTTED DEFINITIONS"
   302    395   Some of the configurable definitions of a class or object are \fIslotted
   303    396   definitions\fR. This means that the configuration is implemented by a slot
   304    397   object, that is an instance of the class \fBoo::Slot\fR, which manages a list
   305    398   of values (class names, variable names, etc.) that comprises the contents of
   306    399   the slot. The class defines three operations (as methods) that may be done on
   307    400   the slot:
   308         -.VE
   309    401   .TP
   310    402   \fIslot\fR \fB\-append\fR ?\fImember ...\fR?
   311         -.VS
          403  +.
   312    404   This appends the given \fImember\fR elements to the slot definition.
   313         -.VE
   314    405   .TP
   315    406   \fIslot\fR \fB\-clear\fR
   316         -.VS
          407  +.
   317    408   This sets the slot definition to the empty list.
   318         -.VE
   319    409   .TP
   320    410   \fIslot\fR \fB\-set\fR ?\fImember ...\fR?
   321         -.VS
          411  +.
   322    412   This replaces the slot definition with the given \fImember\fR elements.
   323    413   .PP
   324    414   A consequence of this is that any use of a slot's default operation where the
   325    415   first member argument begins with a hyphen will be an error. One of the above
   326    416   operations should be used explicitly in those circumstances.
   327    417   .SS "SLOT IMPLEMENTATION"
   328    418   Internally, slot objects also define a method \fB\-\-default\-operation\fR
   329    419   which is forwarded to the default operation of the slot (thus, for the class
   330    420   .QW \fBvariable\fR
   331    421   slot, this is forwarded to
   332    422   .QW "\fBmy \-append\fR" ),
   333    423   and these methods which provide the implementation interface:
   334         -.VE
   335    424   .TP
   336    425   \fIslot\fR \fBGet\fR
   337         -.VS
          426  +.
   338    427   Returns a list that is the current contents of the slot. This method must
   339    428   always be called from a stack frame created by a call to \fBoo::define\fR or
   340    429   \fBoo::objdefine\fR.
   341         -.VE
   342    430   .TP
   343    431   \fIslot\fR \fBSet \fIelementList\fR
   344         -.VS
          432  +.
   345    433   Sets the contents of the slot to the list \fIelementList\fR and returns the
   346    434   empty string. This method must always be called from a stack frame created by
   347    435   a call to \fBoo::define\fR or \fBoo::objdefine\fR.
   348    436   .PP
   349    437   The implementation of these methods is slot-dependent (and responsible for
   350    438   accessing the correct part of the class or object definition). Slots also have
   351    439   an unknown method handler to tie all these pieces together, and they hide
   352    440   their \fBdestroy\fR method so that it is not invoked inadvertently. It is
   353    441   \fIrecommended\fR that any user changes to the slot mechanism be restricted to
   354    442   defining new operations whose names start with a hyphen.
   355         -.VE
   356    443   .SH EXAMPLES
   357    444   This example demonstrates how to use both forms of the \fBoo::define\fR and
   358    445   \fBoo::objdefine\fR commands (they work in the same way), as well as
   359    446   illustrating four of the subcommands of them.
   360    447   .PP
   361    448   .CS
   362    449   oo::class create c

Changes to doc/expr.n.

    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     49   An integer operand may be specified in decimal (the normal case, the optional
    50     50   first two characters are \fB0d\fR), binary
    51     51   (the first two characters are \fB0b\fR), octal
    52     52   (the first two characters are \fB0o\fR), or hexadecimal
    53         -(the first two characters are \fB0x\fR) form.
           53  +(the first two characters are \fB0x\fR) form.  For
           54  +compatibility with older Tcl releases, an operand that begins with \fB0\fR is
           55  +interpreted as an octal integer even if the second character is not \fBo\fR.
    54     56   A floating-point number may be specified in any of several
    55     57   common decimal formats, and may use the decimal point \fB.\fR,
    56     58   \fBe\fR or \fBE\fR for scientific notation, and
    57     59   the sign characters \fB+\fR and \fB\-\fR.  The
    58     60   following are all valid floating-point numbers:  2.1, 3., 6e4, 7.91e+16.
    59     61   The strings \fBInf\fR
    60     62   and \fBNaN\fR, in any combination of case, are also recognized as floating point

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 will be added to the beginning
    93         -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.
    94     95   For all floating-point conversions (\fBe\fR, \fBE\fR, \fBf\fR,
    95     96   \fBg\fR, and \fBG\fR) it guarantees that the result always
    96     97   has a decimal point.
    97     98   For \fBg\fR and \fBG\fR conversions it specifies that
    98     99   trailing zeroes should not be removed.
    99    100   .SS "OPTIONAL FIELD WIDTH"
   100    101   .PP
................................................................................
   128    129   printed; if the string is longer than this then the trailing characters will be dropped.
   129    130   If the precision is specified with \fB*\fR rather than a number
   130    131   then the next argument to the \fBformat\fR command determines the precision;
   131    132   it must be a numeric string.
   132    133   .SS "OPTIONAL SIZE MODIFIER"
   133    134   .PP
   134    135   The fifth part of a conversion specifier is a size modifier,
   135         -which must be \fBll\fR, \fBh\fR, or \fBl\fR.
          136  +which must be \fBll\fR, \fBh\fR, \fBl\fR, or \fBL\fR.
   136    137   If it is \fBll\fR it specifies that an integer value is taken
   137    138   without truncation for conversion to a formatted substring.
   138    139   If it is \fBh\fR it specifies that an integer value is
   139    140   truncated to a 16-bit range before converting.  This option is rarely useful.
   140    141   If it is \fBl\fR it specifies that the integer value is
   141    142   truncated to the same range as that produced by the \fBwide()\fR
   142    143   function of the \fBexpr\fR command (at least a 64-bit range).
   143         -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
   144    147   truncated to the same range as that produced by the \fBint()\fR
   145    148   function of the \fBexpr\fR command (at least a 32-bit range, but
   146    149   determined by the value of the \fBwordSize\fR element of the
   147    150   \fBtcl_platform\fR array).
   148    151   .SS "MANDATORY CONVERSION TYPE"
   149    152   .PP
   150    153   The last thing in a conversion specifier is an alphabetic character
................................................................................
   167    170   Convert integer to unsigned hexadecimal string, using digits
   168    171   .QW 0123456789abcdef
   169    172   for \fBx\fR and
   170    173   .QW 0123456789ABCDEF
   171    174   for \fBX\fR).
   172    175   .TP 10
   173    176   \fBb\fR
   174         -Convert integer to binary string, using digits 0 and 1.
          177  +Convert integer to unsigned binary string, using digits 0 and 1.
   175    178   .TP 10
   176    179   \fBc\fR
   177    180   Convert integer to the Unicode character it represents.
   178    181   .TP 10
   179    182   \fBs\fR
   180    183   No conversion; just insert string.
   181    184   .TP 10
................................................................................
   196    199   \fBg\fR or \fBG\fR
   197    200   If the exponent is less than \-4 or greater than or equal to the
   198    201   precision, then convert number as for \fB%e\fR or
   199    202   \fB%E\fR.
   200    203   Otherwise convert as for \fB%f\fR.
   201    204   Trailing zeroes and a trailing decimal point are omitted.
   202    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
   203    213   \fB%\fR
   204    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.
   205    219   .SH "DIFFERENCES FROM ANSI SPRINTF"
   206    220   .PP
   207    221   The behavior of the format command is the same as the
   208    222   ANSI C \fBsprintf\fR procedure except for the following
   209    223   differences:
   210    224   .IP [1]
   211    225   Tcl guarantees that it will be working with UNICODE characters.
   212    226   .IP [2]
   213         -\fB%p\fR and \fB%n\fR specifiers are not supported.
          227  +\fB%n\fR specifier is not supported.
   214    228   .IP [3]
   215    229   For \fB%c\fR conversions the argument must be an integer value,
   216    230   which will then be converted to the corresponding character value.
   217    231   .IP [4]
   218    232   The size modifiers are ignored when formatting floating-point values.
   219         -The \fBll\fR modifier has no \fBsprintf\fR counterpart.
   220    233   The \fBb\fR specifier has no \fBsprintf\fR counterpart.
   221    234   .SH EXAMPLES
   222    235   .PP
   223    236   Convert the numeric value of a UNICODE character to the character
   224    237   itself:
   225    238   .PP
   226    239   .CS

Changes to doc/info.n.

    31     31   .TP
    32     32   \fBinfo body \fIprocname\fR
    33     33   .
    34     34   Returns the body of procedure \fIprocname\fR.  \fIProcname\fR must be
    35     35   the name of a Tcl command procedure.
    36     36   .TP
    37     37   \fBinfo class\fI subcommand class\fR ?\fIarg ...\fR
    38         -.VS 8.6
           38  +.
    39     39   Returns information about the class, \fIclass\fR. The \fIsubcommand\fRs are
    40     40   described in \fBCLASS INTROSPECTION\fR below.
    41         -.VE 8.6
    42     41   .TP
    43     42   \fBinfo cmdcount\fR
    44     43   .
    45     44   Returns a count of the total number of commands that have been invoked
    46     45   in this interpreter.
    47     46   .TP
    48     47   \fBinfo commands \fR?\fIpattern\fR?
................................................................................
    74     73   If the command does not appear to be complete then 0 is returned.
    75     74   This command is typically used in line-oriented input environments
    76     75   to allow users to type in commands that span multiple lines;  if the
    77     76   command is not complete, the script can delay evaluating it until additional
    78     77   lines have been typed to complete the command.
    79     78   .TP
    80     79   \fBinfo coroutine\fR
    81         -.VS 8.6
           80  +.
    82     81   Returns the name of the currently executing \fBcoroutine\fR, or the empty
    83     82   string if either no coroutine is currently executing, or the current coroutine
    84     83   has been deleted (but has not yet returned or yielded since deletion).
    85         -.VE 8.6
    86     84   .TP
    87     85   \fBinfo default \fIprocname arg varname\fR
    88     86   .
    89     87   \fIProcname\fR must be the name of a Tcl command procedure and \fIarg\fR
    90     88   must be the name of an argument to that procedure.  If \fIarg\fR
    91     89   does not have a default value then the command returns \fB0\fR.
    92     90   Otherwise it returns \fB1\fR and places the default value of \fIarg\fR
    93     91   into variable \fIvarname\fR.
    94     92   .TP
    95     93   \fBinfo errorstack \fR?\fIinterp\fR?
    96         -.VS 8.6
           94  +.
    97     95   Returns, in a form that is programmatically easy to parse, the function names
    98     96   and arguments at each level from the call stack of the last error in the given
    99     97   \fIinterp\fR, or in the current one if not specified.
   100     98   .RS
   101     99   .PP
   102    100   This form is an even-sized list alternating tokens and parameters. Tokens are
   103    101   currently either \fBCALL\fR, \fBUP\fR, or \fBINNER\fR, but other values may be
................................................................................
   114    112   granularity.
   115    113   .PP
   116    114   This information is also present in the \fB\-errorstack\fR entry of the
   117    115   options dictionary returned by 3-argument \fBcatch\fR; \fBinfo errorstack\fR
   118    116   is a convenient way of retrieving it for uncaught errors at top-level in an
   119    117   interactive \fBtclsh\fR.
   120    118   .RE
   121         -.VE 8.6
   122    119   .TP
   123    120   \fBinfo exists \fIvarName\fR
   124    121   .
   125    122   Returns \fB1\fR if the variable named \fIvarName\fR exists in the
   126    123   current context (either as a global or local variable) and has been
   127    124   defined by being given a value, returns \fB0\fR otherwise.
   128    125   .TP
................................................................................
   325    322   \fBinfo nameofexecutable\fR
   326    323   .
   327    324   Returns the full path name of the binary file from which the application
   328    325   was invoked.  If Tcl was unable to identify the file, then an empty
   329    326   string is returned.
   330    327   .TP
   331    328   \fBinfo object\fI subcommand object\fR ?\fIarg ...\fR
   332         -.VS 8.6
          329  +.
   333    330   Returns information about the object, \fIobject\fR. The \fIsubcommand\fRs are
   334    331   described in \fBOBJECT INTROSPECTION\fR below.
   335         -.VE 8.6
   336    332   .TP
   337    333   \fBinfo patchlevel\fR
   338    334   .
   339    335   Returns the value of the global variable \fBtcl_patchLevel\fR, which holds
   340    336   the exact version of the Tcl library by default.
   341    337   .TP
   342    338   \fBinfo procs \fR?\fIpattern\fR?
................................................................................
   395    391   has each matching namespace variable qualified with the name
   396    392   of its namespace.
   397    393   Note that a currently-visible variable may not yet
   398    394   .QW exist
   399    395   if it has not
   400    396   been set (e.g. a variable declared but not set by \fBvariable\fR).
   401    397   .SS "CLASS INTROSPECTION"
   402         -.VS 8.6
   403    398   .PP
   404    399   The following \fIsubcommand\fR values are supported by \fBinfo class\fR:
   405         -.VE 8.6
   406    400   .TP
   407    401   \fBinfo class call\fI class method\fR
   408         -.VS
          402  +.
   409    403   Returns a description of the method implementations that are used to provide a
   410    404   stereotypical instance of \fIclass\fR's implementation of \fImethod\fR
   411    405   (stereotypical instances being objects instantiated by a class without having
   412    406   any object-specific definitions added). This consists of a list of lists of
   413    407   four elements, where each sublist consists of a word that describes the
   414    408   general type of method implementation (being one of \fBmethod\fR for an
   415         -ordinary method, \fBfilter\fR for an applied filter, and \fBunknown\fR for a
          409  +ordinary method, \fBfilter\fR for an applied filter,
          410  +.VS TIP500
          411  +\fBprivate\fR for a private method,
          412  +.VE TIP500
          413  +and \fBunknown\fR for a
   416    414   method that is invoked as part of unknown method handling), a word giving the
   417    415   name of the particular method invoked (which is always the same as
   418    416   \fImethod\fR for the \fBmethod\fR type, and
   419    417   .QW \fBunknown\fR
   420    418   for the \fBunknown\fR type), a word giving the fully qualified name of the
   421    419   class that defined the method, and a word describing the type of method
   422    420   implementation (see \fBinfo class methodtype\fR).
   423    421   .RS
   424    422   .PP
   425    423   Note that there is no inspection of whether the method implementations
   426         -actually use \fBnext\fR to transfer control along the call chain.
          424  +actually use \fBnext\fR to transfer control along the call chain,
          425  +.VS TIP500
          426  +and the call chains that this command files do not actually contain private
          427  +methods.
          428  +.VE TIP500
   427    429   .RE
   428         -.VE 8.6
   429    430   .TP
   430    431   \fBinfo class constructor\fI class\fR
   431         -.VS 8.6
          432  +.
   432    433   This subcommand returns a description of the definition of the constructor of
   433    434   class \fIclass\fR. The definition is described as a two element list; the first
   434    435   element is the list of arguments to the constructor in a form suitable for
   435    436   passing to another call to \fBproc\fR or a method definition, and the second
   436    437   element is the body of the constructor. If no constructor is present, this
   437    438   returns the empty list.
   438         -.VE 8.6
   439    439   .TP
   440    440   \fBinfo class definition\fI class method\fR
   441         -.VS 8.6
          441  +.
   442    442   This subcommand returns a description of the definition of the method named
   443    443   \fImethod\fR of class \fIclass\fR. The definition is described as a two element
   444    444   list; the first element is the list of arguments to the method in a form
   445    445   suitable for passing to another call to \fBproc\fR or a method definition, and
   446    446   the second element is the body of the method.
   447         -.VE 8.6
   448    447   .TP
   449    448   \fBinfo class destructor\fI class\fR
   450         -.VS 8.6
          449  +.
   451    450   This subcommand returns the body of the destructor of class \fIclass\fR. If no
   452    451   destructor is present, this returns the empty string.
   453         -.VE 8.6
   454    452   .TP
   455    453   \fBinfo class filters\fI class\fR
   456         -.VS 8.6
          454  +.
   457    455   This subcommand returns the list of filter methods set on the class.
   458         -.VE 8.6
   459    456   .TP
   460    457   \fBinfo class forward\fI class method\fR
   461         -.VS 8.6
          458  +.
   462    459   This subcommand returns the argument list for the method forwarding called
   463    460   \fImethod\fR that is set on the class called \fIclass\fR.
   464         -.VE 8.6
   465    461   .TP
   466    462   \fBinfo class instances\fI class\fR ?\fIpattern\fR?
   467         -.VS 8.6
          463  +.
   468    464   This subcommand returns a list of instances of class \fIclass\fR. If the
   469    465   optional \fIpattern\fR argument is present, it constrains the list of returned
   470    466   instances to those that match it according to the rules of \fBstring match\fR.
   471         -.VE 8.6
   472    467   .TP
   473    468   \fBinfo class methods\fI class\fR ?\fIoptions...\fR?
   474         -.VS 8.6
          469  +.
   475    470   This subcommand returns a list of all public (i.e. exported) methods of the
   476    471   class called \fIclass\fR. Any of the following \fIoption\fRs may be
   477    472   specified, controlling exactly which method names are returned:
   478    473   .RS
   479         -.VE 8.6
   480    474   .TP
   481    475   \fB\-all\fR
   482         -.VS 8.6
   483         -If the \fB\-all\fR flag is given, the list of methods will include those
          476  +.
          477  +If the \fB\-all\fR flag is given,
          478  +.VS TIP500
          479  +and the \fB\-scope\fR flag is not given,
          480  +.VE TIP500
          481  +the list of methods will include those
   484    482   methods defined not just by the class, but also by the class's superclasses
   485    483   and mixins.
   486         -.VE 8.6
   487    484   .TP
   488    485   \fB\-private\fR
   489         -.VS 8.6
   490         -If the \fB\-private\fR flag is given, the list of methods will also include
   491         -the private (i.e. non-exported) methods of the class (and superclasses and
          486  +.
          487  +If the \fB\-private\fR flag is given,
          488  +.VS TIP500
          489  +and the \fB\-scope\fR flag is not given,
          490  +.VE TIP500
          491  +the list of methods will also include
          492  +the non-exported methods of the class (and superclasses and
   492    493   mixins, if \fB\-all\fR is also given).
          494  +.VS TIP500
          495  +Note that this naming is an unfortunate clash with true private methods; this
          496  +option name is retained for backward compatibility.
          497  +.VE TIP500
          498  +.TP
          499  +\fB\-scope\fI scope\fR
          500  +.VS TIP500
          501  +Returns a list of all methods on \fIclass\fR that have the given visibility
          502  +\fIscope\fR.  When this option is supplied, both the \fB\-all\fR and
          503  +\fB\-private\fR options are ignored. The valid values for \fIscope\fR are:
          504  +.RS
          505  +.IP \fBpublic\fR 3
          506  +Only methods with \fIpublic\fR scope (i.e., callable from anywhere by any instance
          507  +of this class) are to be returned.
          508  +.IP \fBunexported\fR 3
          509  +Only methods with \fIunexported\fR scope (i.e., only callable via \fBmy\fR) are to
          510  +be returned.
          511  +.IP \fBprivate\fR 3
          512  +Only methods with \fIprivate\fR scope (i.e., only callable from within this class's
          513  +methods) are to be returned.
   493    514   .RE
   494         -.VE 8.6
          515  +.VE TIP500
          516  +.RE
   495    517   .TP
   496    518   \fBinfo class methodtype\fI class method\fR
   497         -.VS 8.6
          519  +.
   498    520   This subcommand returns a description of the type of implementation used for
   499    521   the method named \fImethod\fR of class \fIclass\fR. When the result is
   500    522   \fBmethod\fR, further information can be discovered with \fBinfo class
   501    523   definition\fR, and when the result is \fBforward\fR, further information can
   502    524   be discovered with \fBinfo class forward\fR.
   503         -.VE 8.6
   504    525   .TP
   505    526   \fBinfo class mixins\fI class\fR
   506         -.VS 8.6
          527  +.
   507    528   This subcommand returns a list of all classes that have been mixed into the
   508    529   class named \fIclass\fR.
   509         -.VE 8.6
   510    530   .TP
   511    531   \fBinfo class subclasses\fI class\fR ?\fIpattern\fR?
   512         -.VS 8.6
          532  +.
   513    533   This subcommand returns a list of direct subclasses of class \fIclass\fR. If
   514    534   the optional \fIpattern\fR argument is present, it constrains the list of
   515    535   returned classes to those that match it according to the rules of
   516    536   \fBstring match\fR.
   517         -.VE 8.6
   518    537   .TP
   519    538   \fBinfo class superclasses\fI class\fR
   520         -.VS 8.6
          539  +.
   521    540   This subcommand returns a list of direct superclasses of class \fIclass\fR in
   522    541   inheritance precedence order.
   523         -.VE 8.6
   524    542   .TP
   525         -\fBinfo class variables\fI class\fR
   526         -.VS 8.6
          543  +\fBinfo class variables\fI class\fR ?\fB\-private\fR?
          544  +.
   527    545   This subcommand returns a list of all variables that have been declared for
   528    546   the class named \fIclass\fR (i.e. that are automatically present in the
   529    547   class's methods, constructor and destructor).
          548  +.VS TIP500
          549  +If the \fB\-private\fR option is specified, this lists the private variables
          550  +declared instead.
          551  +.VE TIP500
   530    552   .SS "OBJECT INTROSPECTION"
   531    553   .PP
   532    554   The following \fIsubcommand\fR values are supported by \fBinfo object\fR:
   533         -.VE 8.6
   534    555   .TP
   535    556   \fBinfo object call\fI object method\fR
   536         -.VS 8.6
          557  +.
   537    558   Returns a description of the method implementations that are used to provide
   538    559   \fIobject\fR's implementation of \fImethod\fR.  This consists of a list of
   539    560   lists of four elements, where each sublist consists of a word that describes
   540    561   the general type of method implementation (being one of \fBmethod\fR for an
   541         -ordinary method, \fBfilter\fR for an applied filter, and \fBunknown\fR for a
          562  +ordinary method, \fBfilter\fR for an applied filter,
          563  +.VS TIP500
          564  +\fBprivate\fR for a private method,
          565  +.VE TIP500
          566  +and \fBunknown\fR for a
   542    567   method that is invoked as part of unknown method handling), a word giving the
   543    568   name of the particular method invoked (which is always the same as
   544    569   \fImethod\fR for the \fBmethod\fR type, and
   545    570   .QW \fBunknown\fR
   546    571   for the \fBunknown\fR type), a word giving what defined the method (the fully
   547    572   qualified name of the class, or the literal string \fBobject\fR if the method
   548    573   implementation is on an instance), and a word describing the type of method
   549    574   implementation (see \fBinfo object methodtype\fR).
   550    575   .RS
   551    576   .PP
   552    577   Note that there is no inspection of whether the method implementations
   553         -actually use \fBnext\fR to transfer control along the call chain.
          578  +actually use \fBnext\fR to transfer control along the call chain,
          579  +.VS TIP500
          580  +and the call chains that this command files do not actually contain private
          581  +methods.
          582  +.VE TIP500
   554    583   .RE
   555         -.VE 8.6
   556    584   .TP
   557    585   \fBinfo object class\fI object\fR ?\fIclassName\fR?
   558         -.VS 8.6
          586  +.
   559    587   If \fIclassName\fR is unspecified, this subcommand returns class of the
   560    588   \fIobject\fR object. If \fIclassName\fR is present, this subcommand returns a
   561    589   boolean value indicating whether the \fIobject\fR is of that class.
   562         -.VE 8.6
          590  +.TP
          591  +\fBinfo object creationid\fI object\fR
          592  +.VS TIP500
          593  +Returns the unique creation identifier for the \fIobject\fR object. This
          594  +creation identifier is unique to the object (within a Tcl interpreter) and
          595  +cannot be controlled at object creation time or altered afterwards.
          596  +.RS
          597  +.PP
          598  +\fIImplementation note:\fR the creation identifier is used to generate unique
          599  +identifiers associated with the object, especially for private variables.
          600  +.RE
          601  +.VE TIP500
   563    602   .TP
   564    603   \fBinfo object definition\fI object method\fR
   565         -.VS 8.6
          604  +.
   566    605   This subcommand returns a description of the definition of the method named
   567    606   \fImethod\fR of object \fIobject\fR. The definition is described as a two
   568    607   element list; the first element is the list of arguments to the method in a
   569    608   form suitable for passing to another call to \fBproc\fR or a method definition,
   570    609   and the second element is the body of the method.
   571         -.VE 8.6
   572    610   .TP
   573    611   \fBinfo object filters\fI object\fR
   574         -.VS 8.6
          612  +.
   575    613   This subcommand returns the list of filter methods set on the object.
   576         -.VE 8.6
   577    614   .TP
   578    615   \fBinfo object forward\fI object method\fR
   579         -.VS 8.6
          616  +.
   580    617   This subcommand returns the argument list for the method forwarding called
   581    618   \fImethod\fR that is set on the object called \fIobject\fR.
   582         -.VE 8.6
   583    619   .TP
   584    620   \fBinfo object isa\fI category object\fR ?\fIarg\fR?
   585         -.VS 8.6
          621  +.
   586    622   This subcommand tests whether an object belongs to a particular category,
   587    623   returning a boolean value that indicates whether the \fIobject\fR argument
   588    624   meets the criteria for the category. The supported categories are:
   589         -.VE 8.6
   590    625   .RS
   591    626   .TP
   592    627   \fBinfo object isa class\fI object\fR
   593         -.VS 8.6
          628  +.
   594    629   This returns whether \fIobject\fR is a class (i.e. an instance of
   595    630   \fBoo::class\fR or one of its subclasses).
   596         -.VE 8.6
   597    631   .TP
   598    632   \fBinfo object isa metaclass\fI object\fR
   599         -.VS 8.6
          633  +.
   600    634   This returns whether \fIobject\fR is a class that can manufacture classes
   601    635   (i.e. is \fBoo::class\fR or a subclass of it).
   602         -.VE 8.6
   603    636   .TP
   604    637   \fBinfo object isa mixin\fI object class\fR
   605         -.VS 8.6
          638  +.
   606    639   This returns whether \fIclass\fR is directly mixed into \fIobject\fR.
   607         -.VE 8.6
   608    640   .TP
   609    641   \fBinfo object isa object\fI object\fR
   610         -.VS 8.6
          642  +.
   611    643   This returns whether \fIobject\fR really is an object.
   612         -.VE 8.6
   613    644   .TP
   614    645   \fBinfo object isa typeof\fI object class\fR
   615         -.VS 8.6
          646  +.
   616    647   This returns whether \fIclass\fR is the type of \fIobject\fR (i.e. whether
   617    648   \fIobject\fR is an instance of \fIclass\fR or one of its subclasses, whether
   618    649   direct or indirect).
   619    650   .RE
   620         -.VE 8.6
   621    651   .TP
   622    652   \fBinfo object methods\fI object\fR ?\fIoption...\fR?
   623         -.VS 8.6
          653  +.
   624    654   This subcommand returns a list of all public (i.e. exported) methods of the
   625    655   object called \fIobject\fR. Any of the following \fIoption\fRs may be
   626    656   specified, controlling exactly which method names are returned:
   627    657   .RS
   628         -.VE 8.6
   629    658   .TP
   630    659   \fB\-all\fR
   631         -.VS 8.6
   632         -If the \fB\-all\fR flag is given, the list of methods will include those
          660  +.
          661  +If the \fB\-all\fR flag is given,
          662  +.VS TIP500
          663  +and the \fB\-scope\fR flag is not given,
          664  +.VE TIP500
          665  +the list of methods will include those
   633    666   methods defined not just by the object, but also by the object's class and
   634    667   mixins, plus the superclasses of those classes.
   635         -.VE 8.6
   636    668   .TP
   637    669   \fB\-private\fR
   638         -.VS 8.6
   639         -If the \fB\-private\fR flag is given, the list of methods will also include
   640         -the private (i.e. non-exported) methods of the object (and classes, if
          670  +.
          671  +If the \fB\-private\fR flag is given,
          672  +.VS TIP500
          673  +and the \fB\-scope\fR flag is not given,
          674  +.VE TIP500
          675  +the list of methods will also include
          676  +the non-exported methods of the object (and classes, if
   641    677   \fB\-all\fR is also given).
          678  +.VS TIP500
          679  +Note that this naming is an unfortunate clash with true private methods; this
          680  +option name is retained for backward compatibility.
          681  +.VE TIP500
          682  +.TP
          683  +\fB\-scope\fI scope\fR
          684  +.VS TIP500
          685  +Returns a list of all methods on \fIobject\fR that have the given visibility
          686  +\fIscope\fR.  When this option is supplied, both the \fB\-all\fR and
          687  +\fB\-private\fR options are ignored. The valid values for \fIscope\fR are:
          688  +.RS
          689  +.IP \fBpublic\fR 3
          690  +Only methods with \fIpublic\fR scope (i.e., callable from anywhere) are to be
          691  +returned.
          692  +.IP \fBunexported\fR 3
          693  +Only methods with \fIunexported\fR scope (i.e., only callable via \fBmy\fR) are to
          694  +be returned.
          695  +.IP \fBprivate\fR 3
          696  +Only methods with \fIprivate\fR scope (i.e., only callable from within this object's
          697  +instance methods) are to be returned.
   642    698   .RE
   643         -.VE 8.6
          699  +.VE TIP500
          700  +.RE
   644    701   .TP
   645    702   \fBinfo object methodtype\fI object method\fR
   646         -.VS 8.6
          703  +.
   647    704   This subcommand returns a description of the type of implementation used for
   648    705   the method named \fImethod\fR of object \fIobject\fR. When the result is
   649    706   \fBmethod\fR, further information can be discovered with \fBinfo object
   650    707   definition\fR, and when the result is \fBforward\fR, further information can
   651    708   be discovered with \fBinfo object forward\fR.
   652         -.VE 8.6
   653    709   .TP
   654    710   \fBinfo object mixins\fI object\fR
   655         -.VS 8.6
          711  +.
   656    712   This subcommand returns a list of all classes that have been mixed into the
   657    713   object named \fIobject\fR.
   658         -.VE 8.6
   659    714   .TP
   660    715   \fBinfo object namespace\fI object\fR
   661         -.VS 8.6
          716  +.
   662    717   This subcommand returns the name of the internal namespace of the object named
   663    718   \fIobject\fR.
   664         -.VE 8.6
   665    719   .TP
   666         -\fBinfo object variables\fI object\fR
   667         -.VS 8.6
          720  +\fBinfo object variables\fI object\fRR ?\fB\-private\fR?
          721  +.
   668    722   This subcommand returns a list of all variables that have been declared for
   669    723   the object named \fIobject\fR (i.e. that are automatically present in the
   670    724   object's methods).
   671         -.VE 8.6
          725  +.VS TIP500
          726  +If the \fB\-private\fR option is specified, this lists the private variables
          727  +declared instead.
          728  +.VE TIP500
   672    729   .TP
   673    730   \fBinfo object vars\fI object\fR ?\fIpattern\fR?
   674         -.VS 8.6
          731  +.
   675    732   This subcommand returns a list of all variables in the private namespace of
   676    733   the object named \fIobject\fR. If the optional \fIpattern\fR argument is
   677    734   given, it is a filter (in the syntax of a \fBstring match\fR glob pattern)
   678    735   that constrains the list of variables returned. Note that this is different
   679    736   from the list returned by \fBinfo object variables\fR; that can include
   680    737   variables that are currently unset, whereas this can include variables that
   681    738   are not automatically included by any of \fIobject\fR's methods (or those of
   682    739   its class, superclasses or mixins).
   683         -.VE 8.6
   684    740   .SH EXAMPLES
   685    741   .PP
   686    742   This command prints out a procedure suitable for saving in a Tcl
   687    743   script:
   688    744   .PP
   689    745   .CS
   690    746   proc printProc {procName} {
................................................................................
   699    755               lappend formals [list $var]
   700    756           }
   701    757       }
   702    758       puts [lappend result $formals [\fBinfo body\fR $procName]]
   703    759   }
   704    760   .CE
   705    761   .SS "EXAMPLES WITH OBJECTS"
   706         -.VS 8.6
   707    762   .PP
   708    763   Every object necessarily knows what its class is; this information is
   709    764   trivially extractable through introspection:
   710    765   .PP
   711    766   .CS
   712    767   oo::class create c
   713    768   c create o
................................................................................
   720    775   The introspection capabilities can be used to discover what class implements a
   721    776   method and get how it is defined. This procedure illustrates how:
   722    777   .PP
   723    778   .CS
   724    779   proc getDef {obj method} {
   725    780       foreach inf [\fBinfo object call\fR $obj $method] {
   726    781           lassign $inf calltype name locus methodtype
          782  +
   727    783           # Assume no forwards or filters, and hence no $calltype
   728    784           # or $methodtype checks...
          785  +
   729    786           if {$locus eq "object"} {
   730    787               return [\fBinfo object definition\fR $obj $name]
   731    788           } else {
   732    789               return [\fBinfo class definition\fR $locus $name]
   733    790           }
   734    791       }
   735    792       error "no definition for $method"
................................................................................
   744    801   .PP
   745    802   .CS
   746    803   proc getDef {obj method} {
   747    804       if {$method in [\fBinfo object methods\fR $obj]} {
   748    805           # Assume no forwards
   749    806           return [\fBinfo object definition\fR $obj $method]
   750    807       }
          808  +
   751    809       set cls [\fBinfo object class\fR $obj]
          810  +
   752    811       while {$method ni [\fBinfo class methods\fR $cls]} {
   753    812           # Assume the simple case
   754    813           set cls [lindex [\fBinfo class superclass\fR $cls] 0]
   755    814           if {$cls eq ""} {
   756    815               error "no definition for $method"
   757    816           }
   758    817       }
          818  +
   759    819       # Assume no forwards
   760    820       return [\fBinfo class definition\fR $cls $method]
   761    821   }
   762    822   .CE
   763         -.VE 8.6
   764    823   .SH "SEE ALSO"
   765         -.VS 8.6
   766    824   global(n), oo::class(n), oo::define(n), oo::object(n), proc(n), self(n),
   767         -.VE 8.6
   768    825   tcl_library(n), tcl_patchLevel(n), tcl_version(n)
   769    826   .SH KEYWORDS
   770    827   command, information, interpreter, introspection, level, namespace,
   771         -.VS 8.6
   772         -object,
   773         -.VE 8.6
   774         -procedure, variable
          828  +object, procedure, variable
   775    829   '\" Local Variables:
   776    830   '\" mode: nroff
   777    831   '\" fill-column: 78
   778    832   '\" End:

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         -.TP
   106         -\fB::msgcat::mcexists\fR ?\fB-exactnamespace\fR? ?\fB-exactlocale\fR? \fIsrc-string\fR
   107         -.
   108    131   .VS "TIP 412"
          132  +.TP
          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/my.n.

    15     15   package require TclOO
    16     16   
    17     17   \fBmy\fI methodName\fR ?\fIarg ...\fR?
    18     18   .fi
    19     19   .BE
    20     20   .SH DESCRIPTION
    21     21   .PP
    22         -The \fBmy\fR command is used to allow methods of objects to invoke any method
           22  +The \fBmy\fR command is used to allow methods of objects to invoke methods
    23     23   of the object (or its class). In particular, the set of valid values for
    24     24   \fImethodName\fR is the set of all methods supported by an object and its
    25         -superclasses, including those that are not exported. The object upon which the
    26         -method is invoked is always the one that is the current context of the method
    27         -(i.e. the object that is returned by \fBself object\fR) from which the
    28         -\fBmy\fR command is invoked.
           25  +superclasses, including those that are not exported
           26  +.VS TIP500
           27  +and private methods of the object or class when used within another method
           28  +defined by that object or class.
           29  +.VE TIP500
           30  +The object upon which the method is invoked is the one that owns the namespace
           31  +that the \fBmy\fR command is contained in initially (\fBNB:\fR the link
           32  +remains if the command is renamed), which is the currently invoked object by
           33  +default.
    29     34   .PP
    30     35   Each object has its own \fBmy\fR command, contained in its instance namespace.
    31     36   .SH EXAMPLES
    32     37   .PP
    33     38   This example shows basic use of \fBmy\fR to use the \fBvariables\fR method of
    34     39   the \fBoo::object\fR class, which is not publicly visible by default:
    35     40   .PP
................................................................................
    36     41   .CS
    37     42   oo::class create c {
    38     43       method count {} {
    39     44           \fBmy\fR variable counter
    40     45           puts [incr counter]
    41     46       }
    42     47   }
           48  +
    43     49   c create o
    44     50   o count              \fI\(-> prints "1"\fR
    45     51   o count              \fI\(-> prints "2"\fR
    46     52   o count              \fI\(-> prints "3"\fR
    47     53   .CE
           54  +.PP
           55  +This example shows how you can use \fBmy\fR to make callbacks to private
           56  +methods from outside the object (from a \fBtrace\fR), using
           57  +\fBnamespace code\fR to enter the correct context:
           58  +.PP
           59  +.CS
           60  +oo::class create HasCallback {
           61  +    method makeCallback {} {
           62  +        return [namespace code {
           63  +            \fBmy\fR Callback
           64  +        }]
           65  +    }
           66  +
           67  +    method Callback {args} {
           68  +        puts "callback: $args"
           69  +    }
           70  +}
           71  +
           72  +set o [HasCallback new]
           73  +trace add variable xyz write [$o makeCallback]
           74  +set xyz "called"     \fI\(-> prints "callback: xyz {} write"\fR
           75  +.CE
    48     76   .SH "SEE ALSO"
    49     77   next(n), oo::object(n), self(n)
    50     78   .SH KEYWORDS
    51     79   method, method visibility, object, private method, public method
    52         -
    53     80   .\" Local variables:
    54     81   .\" mode: nroff
    55     82   .\" fill-column: 78
    56     83   .\" End:

Changes to doc/next.n.

   108    108   .PP
   109    109   .CS
   110    110   oo::class create theSuperclass {
   111    111       method example {args} {
   112    112           puts "in the superclass, args = $args"
   113    113       }
   114    114   }
          115  +
   115    116   oo::class create theSubclass {
   116    117       superclass theSuperclass
   117    118       method example {args} {
   118    119           puts "before chaining from subclass, args = $args"
   119    120           \fBnext\fR a {*}$args b
   120    121           \fBnext\fR pureSynthesis
   121    122           puts "after chaining from subclass"
   122    123       }
   123    124   }
          125  +
   124    126   theSubclass create obj
   125    127   oo::objdefine obj method example args {
   126    128       puts "per-object method, args = $args"
   127    129       \fBnext\fR x {*}$args y
   128    130       \fBnext\fR
   129    131   }
   130    132   obj example 1 2 3
................................................................................
   163    165           if {[info exist ValueCache($key)]} {
   164    166               return $ValueCache($key)
   165    167           }
   166    168   
   167    169           \fI# Compute value, insert into cache, and return it\fR
   168    170           return [set ValueCache($key) [\fBnext\fR {*}$args]]
   169    171       }
          172  +
   170    173       method flushCache {} {
   171    174           my variable ValueCache
   172    175           unset ValueCache
   173    176           \fI# Skip the caching\fR
   174    177           return -level 2 ""
   175    178       }
   176    179   }
   177    180   
   178    181   oo::object create demo
   179    182   oo::objdefine demo {
   180    183       mixin cache
          184  +
   181    185       method compute {a b c} {
   182    186           after 3000 \fI;# Simulate deep thought\fR
   183    187           return [expr {$a + $b * $c}]
   184    188       }
          189  +
   185    190       method compute2 {a b c} {
   186    191           after 3000 \fI;# Simulate deep thought\fR
   187    192           return [expr {$a * $b + $c}]
   188    193       }
   189    194   }
   190    195   
   191    196   puts [demo compute  1 2 3]      \fI\(-> prints "7" after delay\fR

Added doc/process.n.

            1  +'\"
            2  +'\" Copyright (c) 2017 Frederic Bonnet.
            3  +'\"
            4  +'\" See the file "license.terms" for information on usage and redistribution
            5  +'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
            6  +'\"
            7  +.TH process n 8.7 Tcl "Tcl Built-In Commands"
            8  +.so man.macros
            9  +.BS
           10  +'\" Note:  do not modify the .SH NAME line immediately below!
           11  +.SH NAME
           12  +tcl::process \- Subprocess management
           13  +.SH SYNOPSIS
           14  +\fB::tcl::process \fIoption \fR?\fIarg arg ...\fR?
           15  +.BE
           16  +.SH DESCRIPTION
           17  +.PP
           18  +This command provides a way to manage subprocesses created by the \fBopen\fR
           19  +and \fBexec\fR commands. The legal \fIoptions\fR (which may be abbreviated) are:
           20  +.TP
           21  +\fB::tcl::process list\fR
           22  +.
           23  +Returns the list of subprocess PIDs.
           24  +.TP
           25  +\fB::tcl::process status\fR ?\fIswitches\fR? ?\fIpids\fR?
           26  +.
           27  +Returns a dictionary mapping subprocess PIDs to their respective status. If
           28  +\fIpids\fR is specified as a list of PIDs then the command only returns the
           29  +status of the matching subprocesses if they exist, and raises an error
           30  +otherwise. For active processes, the status is an empty value. For terminated
           31  +processes, the status is a list with the following format:
           32  +.QW "{code ?\fImsg errorCode\fR?}" ,
           33  +where:
           34  +.RS
           35  +.TP
           36  +\fBcode\fR\0
           37  +.
           38  +is a standard Tcl return code,
           39  +.TP
           40  +\fBmsg\fR\0
           41  +.
           42  +is the human-readable error message,
           43  +.TP
           44  +\fBerrorCode\fR\0
           45  +.
           46  +uses the same format as the \fBerrorCode\fR global variable
           47  +.RE
           48  +Note that \fBmsg\fR and \fBerrorCode\fR are only present for abnormally
           49  +terminated processes (i.e. those where \fBcode\fR is nonzero). Under the hood
           50  +this command calls \fBTcl_WaitPid\fR with the \fBWNOHANG\fR flag set for
           51  +non-blocking behavior, unless the \fB\-wait\fR switch is set (see below).
           52  +.RS
           53  +.PP
           54  +Additionally, \fB::tcl::process status\fR accepts the following switches:
           55  +.TP
           56  +\fB\-wait\fR\0
           57  +.
           58  +By default the command returns immediately (the underlying \fBTcl_WaitPid\fR is
           59  +called with the \fBWNOHANG\fR flag set) unless this switch is set. If \fBpids\fR
           60  +is specified as a list of PIDs then the command waits until the status of the
           61  +matching subprocesses are available. If \fBpids\fR is not specified then it
           62  +waits for all known subprocesses.
           63  +.TP
           64  +\fB\-\|\-\fR
           65  +.
           66  +Marks the end of switches.  The argument following this one will
           67  +be treated as the first \fIarg\fR even if it starts with a \fB\-\fR.
           68  +.RE
           69  +.TP
           70  +\fB::tcl::process purge ?\fIpids\fR?
           71  +.
           72  +Cleans up all data associated with terminated subprocesses. If \fBpids\fR is
           73  +specified as a list of PIDs then the command only cleanup data for the matching
           74  +subprocesses if they exist, and raises an error otherwise. If the process is
           75  +still active then it does nothing.
           76  +.TP
           77  +\fB::tcl::process autopurge ?\fIflag\fR?
           78  +.
           79  +Automatic purge facility. If \fBflag\fR is specified as a boolean value then it
           80  +activates or deactivate autopurge. In all cases it returns the current status as
           81  +a boolean value. When autopurge is active, \fBTcl_ReapDetachedProcs\fR is called
           82  +each time the exec command is executed or a pipe channel created by open is
           83  +closed. When autopurge is inactive, \fB::tcl::process\fR purge must be called
           84  +explicitly. By default autopurge is active.
           85  +.RE
           86  +.SH "EXAMPLES"
           87  +.PP
           88  +.CS
           89  +\fB::tcl::process autopurge\fR
           90  +     \fI\(-> true\fR
           91  +\fB::tcl::process autopurge\fR false
           92  +     \fI\(-> false\fR
           93  +
           94  +set pid1 [exec command1 a b c | command2 d e f &]
           95  +     \fI\(-> 123 456\fR
           96  +set chan [open "|command1 a b c | command2 d e f"]
           97  +     \fI\(-> file123\fR
           98  +set pid2 [pid $chan]
           99  +     \fI\(-> 789 1011\fR
          100  +
          101  +\fB::tcl::process list\fR
          102  +     \fI\(-> 123 456 789 1011\fR
          103  +
          104  +\fB::tcl::process status\fR
          105  +     \fI\(-> 123 0 456 {1 "child killed: write on pipe with no readers" {CHILDKILLED 456 SIGPIPE "write on pipe with no readers"}} 789 {1 "child suspended: background tty read" {CHILDSUSP 789 SIGTTIN "background tty read"}} 1011 {}\fR
          106  +
          107  +\fB::tcl::process status\fR 123
          108  +     \fI\(-> 123 0\fR
          109  +
          110  +\fB::tcl::process status\fR 1011
          111  +     \fI\(-> 1011 {}\fR
          112  +
          113  +\fB::tcl::process status\fR -wait
          114  +     \fI\(-> 123 0 456 {1 "child killed: write on pipe with no readers" {CHILDKILLED 456 SIGPIPE "write on pipe with no readers"}} 789 {1 "child suspended: background tty read" {CHILDSUSP 789 SIGTTIN "background tty read"}} 1011 {1 "child process exited abnormally" {CHILDSTATUS 1011 -1}}\fR
          115  +
          116  +\fB::tcl::process status\fR 1011
          117  +     \fI\(-> 1011 {1 "child process exited abnormally" {CHILDSTATUS 1011 -1}}\fR
          118  +
          119  +\fB::tcl::process purge\fR
          120  +exec command1 1 2 3 &
          121  +     \fI\(-> 1213\fR
          122  +\fB::tcl::process list\fR
          123  +     \fI\(-> 1213\fR
          124  +.CE
          125  +.SH "SEE ALSO"
          126  +exec(n), open(n), Tcl_DetachPids(3), Tcl_WaitPid(3), Tcl_ReapDetachedProcs(3)
          127  +.SH "KEYWORDS"
          128  +background, child, detach, process, wait
          129  +'\" Local Variables:
          130  +'\" mode: nroff
          131  +'\" End:

Changes to doc/scan.n.

   220    220   hexadecimal conversions with substring sizes:
   221    221   .PP
   222    222   .CS
   223    223   set string "#08D03F"
   224    224   \fBscan\fR $string "#%2x%2x%2x" r g b
   225    225   .CE
   226    226   .PP
   227         -Parse a \fIHH:MM\fR time string:
          227  +Parse a \fIHH:MM\fR time string, noting that this avoids problems with
          228  +octal numbers by forcing interpretation as decimals (if we did not
          229  +care, we would use the \fB%i\fR conversion instead):
   228    230   .PP
   229    231   .CS
   230         -set string "08:08"
          232  +set string "08:08"   ;# *Not* octal!
   231    233   if {[\fBscan\fR $string "%d:%d" hours minutes] != 2} {
   232    234       error "not a valid time string"
   233    235   }
   234    236   # We have to understand numeric ranges ourselves...
   235    237   if {$minutes < 0 || $minutes > 59} {
   236    238       error "invalid number of minutes"
   237    239   }

Changes to doc/self.n.

    28     28   \fBself call\fR
    29     29   .
    30     30   This returns a two-element list describing the method implementations used to
    31     31   implement the current call chain. The first element is the same as would be
    32     32   reported by \fBinfo object\fR \fBcall\fR for the current method (except that this
    33     33   also reports useful values from within constructors and destructors, whose
    34     34   names are reported as \fB<constructor>\fR and \fB<destructor>\fR
    35         -respectively), and the second element is an index into the first element's
           35  +respectively,
           36  +.VS TIP500
           37  +and for private methods, which are described as being \fBprivate\fR instead of
           38  +being a \fBmethod\fR),
           39  +.VE TIP500
           40  +and the second element is an index into the first element's
    36     41   list that indicates which actual implementation is currently executing (the
    37     42   first implementation to execute is always at index 0).
    38     43   .TP
    39     44   \fBself caller\fR
    40     45   .
    41     46   When the method was invoked from inside another object method, this subcommand
    42     47   returns a three element list describing the containing object and method. The

Changes to doc/string.n.

   111    111   Any of the forms allowed to \fBTcl_GetBoolean\fR.
   112    112   .IP \fBcontrol\fR 12
   113    113   Any Unicode control character.
   114    114   .IP \fBdigit\fR 12
   115    115   Any Unicode digit character.  Note that this includes characters
   116    116   outside of the [0\-9] range.
   117    117   .IP \fBdouble\fR 12
   118         -Any of the valid forms for a double in Tcl, with optional surrounding
   119         -whitespace.  In case of under/overflow in the value, 0 is returned and
   120         -the \fIvarname\fR will contain \-1.
          118  +Any of the forms allowed to \fBTcl_GetDoubleFromObj\fR.
   121    119   .IP \fBentier\fR 12
   122    120   .VS 8.6
   123    121   Any of the valid string formats for an integer value of arbitrary size
   124    122   in Tcl, with optional surrounding whitespace. The formats accepted are
   125    123   exactly those accepted by the C routine \fBTcl_GetBignumFromObj\fR.
   126    124   .VE
   127    125   .IP \fBfalse\fR 12
   128    126   Any of the forms allowed to \fBTcl_GetBoolean\fR where the value is
   129    127   false.
   130    128   .IP \fBgraph\fR 12
   131    129   Any Unicode printing character, except space.
   132    130   .IP \fBinteger\fR 12
   133    131   Any of the valid string formats for a 32-bit integer value in Tcl,
   134         -with optional surrounding whitespace.  In case of under/overflow in
          132  +with optional surrounding whitespace.  In case of overflow in
   135    133   the value, 0 is returned and the \fIvarname\fR will contain \-1.
   136    134   .IP \fBlist\fR 12
   137    135   Any proper list structure, with optional surrounding whitespace. In
   138    136   case of improper list structure, 0 is returned and the \fIvarname\fR
   139    137   will contain the index of the
   140    138   .QW element
   141    139   where the list parsing fails, or \-1 if this cannot be determined.
................................................................................
   152    150   .IP \fBtrue\fR 12
   153    151   Any of the forms allowed to \fBTcl_GetBoolean\fR where the value is
   154    152   true.
   155    153   .IP \fBupper\fR 12
   156    154   Any upper case alphabet character in the Unicode character set.
   157    155   .IP \fBwideinteger\fR 12
   158    156   Any of the valid forms for a wide integer in Tcl, with optional
   159         -surrounding whitespace.  In case of under/overflow in the value, 0 is
          157  +surrounding whitespace.  In case of overflow in the value, 0 is
   160    158   returned and the \fIvarname\fR will contain \-1.
   161    159   .IP \fBwordchar\fR 12
   162    160   Any Unicode word character.  That is any alphanumeric character, and
   163    161   any Unicode connector punctuation characters (e.g. underscore).
   164    162   .IP \fBxdigit\fR 12
   165    163   Any hexadecimal digit character ([0\-9A\-Fa\-f]).
   166    164   .PP

Changes to doc/tclsh.1.

   139    139   The variable \fBtcl_prompt2\fR is used in a similar way when
   140    140   a newline is typed but the current command is not yet complete;
   141    141   if \fBtcl_prompt2\fR is not set then no prompt is output for
   142    142   incomplete commands.
   143    143   .SH "STANDARD CHANNELS"
   144    144   .PP
   145    145   See \fBTcl_StandardChannels\fR for more explanations.
          146  +.SH ZIPVFS
          147  +.PP
          148  +When a zipfile is concatenated to the end of a \fBtclsh\fR, on
          149  +startup the contents of the zip archive will be mounted as the
          150  +virtual file system /zvfs. If a top level directory tcl8.6 is
          151  +present in the zip archive, it will become the directory loaded
          152  +as env(TCL_LIBRARY). If a file named \fBmain.tcl\fR is present
          153  +in the top level directory of the zip archive, it will be sourced
          154  +instead of the shell's normal command line handing.
   146    155   .SH "SEE ALSO"
   147    156   auto_path(n), encoding(n), env(n), fconfigure(n)
   148    157   .SH KEYWORDS
   149    158   application, argument, interpreter, prompt, script file, shell

Added doc/zipfs.3.

            1  +'\"
            2  +'\" Copyright (c) 2015 Jan Nijtmans <[email protected]>
            3  +'\" Copyright (c) 2015 Christian Werner <[email protected]>
            4  +'\" Copyright (c) 2017 Sean Woods <[email protected]>
            5  +'\"
            6  +'\" See the file "license.terms" for information on usage and redistribution
            7  +'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
            8  +'\"
            9  +.TH Tclzipfs 3 8.7 Tcl "Tcl Library Procedures"
           10  +.so man.macros
           11  +.BS
           12  +.SH NAME
           13  +TclZipfs_AppHook, Tclzipfs_Mount, Tclzipfs_Unmount,  \- handle ZIP files as VFS
           14  +.SH SYNOPSIS
           15  +.nf
           16  +.sp
           17  +int
           18  +\fBTclZipfs_AppHook(\fIint *argc, char ***argv\fR)
           19  +.sp
           20  +int
           21  +\fBTclzipfs_Mount\fR(\fIinterp, mntpt, zipname, passwd\fR)
           22  +.sp
           23  +int
           24  +\fBTclzipfs_Unmount\fR(\fIinterp, zipname\fR)
           25  +.SH ARGUMENTS
           26  +.AP "int" *argc in
           27  +Number of command line arguments from main()
           28  +.AP "char" ***argv in
           29  +Pointer to an array of strings containing the command
           30  +line arguments to main()
           31  +.AS Tcl_Interp **termPtr
           32  +.AP Tcl_Interp *interp in
           33  +Interpreter in which the zip file system is mounted.  The interpreter's result is
           34  +modified to hold the result or error message from the script.
           35  +.AP "const char" *zipname in
           36  +Name of a zipfile.
           37  +.AP "const char" *mntpt in
           38  +Name of a mount point.
           39  +.AP "const char" *passwd in
           40  +An (optional) password.
           41  +.BE
           42  +.SH DESCRIPTION
           43  +\fBTclZipfs_AppHook()\fR is a utility function to perform standard
           44  +application initialization procedures. If the current application has
           45  +a mountable zip file system, that file system is mounted under \fIZIPROOT\fR\fB/app\fR.
           46  +If a file named \fBmain.tcl\fR is located in that file system, it is treated
           47  +as the startup script for the process. If the file \fIZIPROOT\fR\fB/app/tcl_library/init.tcl\fR
           48  +is present, \fBtcl_library\fR is set to  \fIZIPROOT\fR\fB/app/tcl_library.
           49  +.PP
           50  +If the \fBtcl_library\fR was not found in the application, the system will then search for it
           51  +as either a VFS attached to the application dynamic library, or as a zip archive named
           52  +libtcl_\fIMAJOR\fR_\fIMINOR\fR_\fIpatchLevel\fR.zip either in the present working directory
           53  +or in the standard tcl install location.
           54  +.PP
           55  +\fBTclzipfs_Mount()\fR mount the ZIP archive \fIzipname\fR on the mount
           56  +point given in \fImntpt\fR using the optional ZIP password \fIpasswd\fR.
           57  +Errors during that process are reported in the interpreter \fIinterp\fR.
           58  +If \fImountpoint\fR is a NULL pointer, information on all currently mounted
           59  +ZIP file systems is written into \fIinterp\fR's result as a sequence of
           60  +mount points and ZIP file names.
           61  +.PP
           62  +\fBTclzipfs_Unmount()\fR undoes the effect of \fBTclzipfs_Mount()\fR,
           63  +i.e. it unmounts the mounted ZIP file system at \fImountpoint\fR. Errors are
           64  +reported in the interpreter \fIinterp\fR.
           65  +.SH KEYWORDS
           66  +compress, filesystem, zip

Added doc/zipfs.n.

            1  +'\"
            2  +'\" Copyright (c) 2015 Jan Nijtmans <[email protected]>
            3  +'\" Copyright (c) 2015 Christian Werner <[email protected]>
            4  +'\" Copyright (c) 2015 Sean Woods <[email protected]>
            5  +'\"
            6  +'\" See the file "license.terms" for information on usage and redistribution
            7  +'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
            8  +'\"
            9  +.TH zipfs n 1.0 Zipfs "zipfs Commands"
           10  +.so man.macros
           11  +.BS
           12  +'\" Note:  do not modify the .SH NAME line immediately below!
           13  +.SH NAME
           14  +zipfs \- Mount and work with ZIP files within Tcl
           15  +.SH SYNOPSIS
           16  +.nf
           17  +\fBpackage require zipfs \fR?\fB1.0\fR?
           18  +.sp
           19  +\fBzipfs exists\fR \fIfilename\fR
           20  +\fBzipfs find\fR \fIdir\fR
           21  +\fBzipfs info\fR \fIfilename\fR
           22  +\fBzipfs list\fR \fB?(-glob|-regexp)?\fR \fI?pattern?\fR
           23  +\fBzipfs mkimg\fR \fIoutfile\fR \fIindir\fR \fI?strip?\fR \fI?password?\fR \fI?infile?\fR
           24  +\fBzipfs mkkey\fR \fIpassword\fR
           25  +\fBzipfs mkzip\fR \fIoutfile\fR \fIindir\fR \fI?strip?\fR \fI?password?\fR
           26  +\fBzipfs mount\fR \fI?mountpoint?\fR \fI?zipfile?\fR \fI?password?\fR
           27  +\fBzipfs root\fR
           28  +\fBzipfs unmount\fR \fImountpoint\fR
           29  +.fi
           30  +.BE
           31  +.SH DESCRIPTION
           32  +.PP
           33  +The \fBzipfs\fR package provides tcl with the ability to mount
           34  +the contents of a zip file as a virtual file system.
           35  +.TP
           36  +\fBzipfs exists\fR \fIfilename\fR
           37  +.
           38  +Return 1 if the given filename exists in the mounted zipfs and 0 if it does not.
           39  +.TP
           40  +\fBzipfs find\fR \fIdir\fR
           41  +.
           42  +Recursively lists files including and below the directory \fIdir\fR.
           43  +The result list consists of relative path names starting from the
           44  +given directory. This command is also used by the \fBzipfs mkzip\fR
           45  +and \fBzipfs mkimg\fR commands.
           46  +.TP
           47  +\fBzipfs info\fR \fIfile\fR
           48  +.
           49  +Return information about the given file in the mounted zipfs.  The information
           50  +consists of (1) the name of the ZIP archive file that contains the file,
           51  +(2) the size of the file after decompressions, (3) the compressed size of
           52  +the file, and (4) the offset of the compressed data in the ZIP archive file.
           53  +.RS
           54  +.PP
           55  +Note: querying the mount point gives the start of zip data offset in (4),
           56  +which can be used to truncate the zip info off an executable.
           57  +.RE
           58  +.TP
           59  +\fBzipfs list\fR \fB?(-glob|-regexp)?\fR \fI?pattern?\fR
           60  +.
           61  +Return a list of all files in the mounted zipfs.  The order of the names
           62  +in the list is arbitrary.
           63  +.TP
           64  +\fBzipfs mkimg\fR \fIoutfile\fR \fIindir\fR \fI?strip?\fR \fI?password?\fR \fI?infile?\fR
           65  +.
           66  +Creates an image (potentially a new executable file) similar to
           67  +\fBzipfs mkzip\fR. If the \fIinfile\fR parameter is specified,
           68  +this file is prepended in front of the ZIP archive, otherwise the file
           69  +returned by \fBTcl_NameOfExecutable(3)\fR (i.e. the executable file of
           70  +the running process) is used. If the \fIpassword\fR parameter is not empty,
           71  +an obfuscated version of that password is placed between the image and ZIP
           72  +chunks of the output file and the contents of the ZIP chunk are protected
           73  +with that password.
           74  +.RS
           75  +.PP
           76  +Caution: highly experimental, not usable on Android, only partially tested
           77  +on Linux and Windows.
           78  +.RE
           79  +.TP
           80  +\fBzipfs mkkey\fR \fIpassword\fR
           81  +.
           82  +For the clear text \fIpassword\fR argument an obfuscated string version
           83  +is returned with the same format used in the \fBzipfs mkimg\fR command.
           84  +.TP
           85  +\fBzipfs mkzip\fR \fIoutfile\fR \fIindir\fR \fI?strip?\fR \fI?password?\fR
           86  +.
           87  +Creates a ZIP archive file named \fIoutfile\fR from the contents of the input
           88  +directory \fIindir\fR (contained regular files only) with optional ZIP
           89  +password \fIpassword\fR. While processing the files below \fIindir\fR the
           90  +optional file name prefix given in \fIstrip\fR is stripped off the beginning
           91  +of the respective file name.
           92  +.RS
           93  +.PP
           94  +Caution: the choice of the \fIindir\fR parameter
           95  +(less the optional stripped prefix) determines the later root name of the
           96  +archive's content.
           97  +.RE
           98  +.TP
           99  +\fBzipfs mount ?\fImountpoint\fR? ?\fIzipfile\fR? ?\fIpassword\fR?
          100  +.
          101  +The \fBzipfs mount\fR command mounts a ZIP archive file as a VFS.
          102  +After this command executes, files contained in \fIzipfile\fR
          103  +will appear to Tcl to be regular files at the mount point.
          104  +.RS
          105  +.PP
          106  +With no \fIzipfile\fR, returns the zipfile mounted at \fImountpoint\fR.
          107  +With no \fImountpoint\fR, return all zipfile/mount pairs.
          108  +If \fImountpoint\fR is specified as an empty string, mount on file path.
          109  +.RE
          110  +.TP
          111  +\fBzipfs root\fR
          112  +Returns a constant string which indicates the mount point for zipfs volumes
          113  +for the current platform. On Windows, this value is zipfs:/. On Unux, //zipfs:/
          114  +.RE
          115  +.TP
          116  +\fBzipfs unmount \fImountpoint\fR
          117  +.
          118  +Unmounts a previously mounted ZIP archive mounted to \fImountpoint\fR.
          119  +.SH "SEE ALSO"
          120  +tclsh(1), file(n), zlib(n)
          121  +.SH "KEYWORDS"
          122  +compress, filesystem, zip
          123  +'\" Local Variables:
          124  +'\" mode: nroff
          125  +'\" End:

Changes to generic/regc_locale.c.

   133    133    * Unicode: alphabetic characters.
   134    134    */
   135    135   
   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         -    {0x3f7, 0x481}, {0x48a, 0x52f}, {0x531, 0x556}, {0x561, 0x587},
   141         -    {0x5d0, 0x5ea}, {0x5f0, 0x5f2}, {0x620, 0x64a}, {0x671, 0x6d3},
          140  +    {0x3f7, 0x481}, {0x48a, 0x52f}, {0x531, 0x556}, {0x560, 0x588},
          141  +    {0x5d0, 0x5ea}, {0x5ef, 0x5f2}, {0x620, 0x64a}, {0x671, 0x6d3},
   142    142       {0x6fa, 0x6fc}, {0x712, 0x72f}, {0x74d, 0x7a5}, {0x7ca, 0x7ea},
   143    143       {0x800, 0x815}, {0x840, 0x858}, {0x860, 0x86a}, {0x8a0, 0x8b4},
   144    144       {0x8b6, 0x8bd}, {0x904, 0x939}, {0x958, 0x961}, {0x971, 0x980},
   145    145       {0x985, 0x98c}, {0x993, 0x9a8}, {0x9aa, 0x9b0}, {0x9b6, 0x9b9},
   146    146       {0x9df, 0x9e1}, {0xa05, 0xa0a}, {0xa13, 0xa28}, {0xa2a, 0xa30},
   147    147       {0xa59, 0xa5c}, {0xa72, 0xa74}, {0xa85, 0xa8d}, {0xa8f, 0xa91},
   148    148       {0xa93, 0xaa8}, {0xaaa, 0xab0}, {0xab5, 0xab9}, {0xb05, 0xb0c},
................................................................................
   161    161       {0x124a, 0x124d}, {0x1250, 0x1256}, {0x125a, 0x125d}, {0x1260, 0x1288},
   162    162       {0x128a, 0x128d}, {0x1290, 0x12b0}, {0x12b2, 0x12b5}, {0x12b8, 0x12be},
   163    163       {0x12c2, 0x12c5}, {0x12c8, 0x12d6}, {0x12d8, 0x1310}, {0x1312, 0x1315},
   164    164       {0x1318, 0x135a}, {0x1380, 0x138f}, {0x13a0, 0x13f5}, {0x13f8, 0x13fd},
   165    165       {0x1401, 0x166c}, {0x166f, 0x167f}, {0x1681, 0x169a}, {0x16a0, 0x16ea},
   166    166       {0x16f1, 0x16f8}, {0x1700, 0x170c}, {0x170e, 0x1711}, {0x1720, 0x1731},
   167    167       {0x1740, 0x1751}, {0x1760, 0x176c}, {0x176e, 0x1770}, {0x1780, 0x17b3},
   168         -    {0x1820, 0x1877}, {0x1880, 0x1884}, {0x1887, 0x18a8}, {0x18b0, 0x18f5},
          168  +    {0x1820, 0x1878}, {0x1880, 0x1884}, {0x1887, 0x18a8}, {0x18b0, 0x18f5},
   169    169       {0x1900, 0x191e}, {0x1950, 0x196d}, {0x1970, 0x1974}, {0x1980, 0x19ab},
   170    170       {0x19b0, 0x19c9}, {0x1a00, 0x1a16}, {0x1a20, 0x1a54}, {0x1b05, 0x1b33},
   171    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         -#if TCL_UTF_MAX > 4
          172  +    {0x1c4d, 0x1c4f}, {0x1c5a, 0x1c7d}, {0x1c80, 0x1c88}, {0x1c90, 0x1cba},
          173  +    {0x1cbd, 0x1cbf}, {0x1ce9, 0x1cec}, {0x1cee, 0x1cf1}, {0x1d00, 0x1dbf},
          174  +    {0x1e00, 0x1f15}, {0x1f18, 0x1f1d}, {0x1f20, 0x1f45}, {0x1f48, 0x1f4d},
          175  +    {0x1f50, 0x1f57}, {0x1f5f, 0x1f7d}, {0x1f80, 0x1fb4}, {0x1fb6, 0x1fbc},
          176  +    {0x1fc2, 0x1fc4}, {0x1fc6, 0x1fcc}, {0x1fd0, 0x1fd3}, {0x1fd6, 0x1fdb},
          177  +    {0x1fe0, 0x1fec}, {0x1ff2, 0x1ff4}, {0x1ff6, 0x1ffc}, {0x2090, 0x209c},
          178  +    {0x210a, 0x2113}, {0x2119, 0x211d}, {0x212a, 0x212d}, {0x212f, 0x2139},
          179  +    {0x213c, 0x213f}, {0x2145, 0x2149}, {0x2c00, 0x2c2e}, {0x2c30, 0x2c5e},
          180  +    {0x2c60, 0x2ce4}, {0x2ceb, 0x2cee}, {0x2d00, 0x2d25}, {0x2d30, 0x2d67},
          181  +    {0x2d80, 0x2d96}, {0x2da0, 0x2da6}, {0x2da8, 0x2dae}, {0x2db0, 0x2db6},
          182  +    {0x2db8, 0x2dbe}, {0x2dc0, 0x2dc6}, {0x2dc8, 0x2dce}, {0x2dd0, 0x2dd6},
          183  +    {0x2dd8, 0x2dde}, {0x3031, 0x3035}, {0x3041, 0x3096}, {0x309d, 0x309f},
          184  +    {0x30a1, 0x30fa}, {0x30fc, 0x30ff}, {0x3105, 0x312f}, {0x3131, 0x318e},
          185  +    {0x31a0, 0x31ba}, {0x31f0, 0x31ff}, {0x3400, 0x4db5}, {0x4e00, 0x9fef},
          186  +    {0xa000, 0xa48c}, {0xa4d0, 0xa4fd}, {0xa500, 0xa60c}, {0xa610, 0xa61f},
          187  +    {0xa640, 0xa66e}, {0xa67f, 0xa69d}, {0xa6a0, 0xa6e5}, {0xa717, 0xa71f},
          188  +    {0xa722, 0xa788}, {0xa78b, 0xa7b9}, {0xa7f7, 0xa801}, {0xa803, 0xa805},
          189  +    {0xa807, 0xa80a}, {0xa80c, 0xa822}, {0xa840, 0xa873}, {0xa882, 0xa8b3},
          190  +    {0xa8f2, 0xa8f7}, {0xa90a, 0xa925}, {0xa930, 0xa946}, {0xa960, 0xa97c},
          191  +    {0xa984, 0xa9b2}, {0xa9e0, 0xa9e4}, {0xa9e6, 0xa9ef}, {0xa9fa, 0xa9fe},
          192  +    {0xaa00, 0xaa28}, {0xaa40, 0xaa42}, {0xaa44, 0xaa4b}, {0xaa60, 0xaa76},
          193  +    {0xaa7e, 0xaaaf}, {0xaab9, 0xaabd}, {0xaadb, 0xaadd}, {0xaae0, 0xaaea},
          194  +    {0xaaf2, 0xaaf4}, {0xab01, 0xab06}, {0xab09, 0xab0e}, {0xab11, 0xab16},
          195  +    {0xab20, 0xab26}, {0xab28, 0xab2e}, {0xab30, 0xab5a}, {0xab5c, 0xab65},
          196  +    {0xab70, 0xabe2}, {0xac00, 0xd7a3}, {0xd7b0, 0xd7c6}, {0xd7cb, 0xd7fb},
          197  +    {0xf900, 0xfa6d}, {0xfa70, 0xfad9}, {0xfb00, 0xfb06}, {0xfb13, 0xfb17},
          198  +    {0xfb1f, 0xfb28}, {0xfb2a, 0xfb36}, {0xfb38, 0xfb3c}, {0xfb46, 0xfbb1},
          199  +    {0xfbd3, 0xfd3d}, {0xfd50, 0xfd8f}, {0xfd92, 0xfdc7}, {0xfdf0, 0xfdfb},
          200  +    {0xfe70, 0xfe74}, {0xfe76, 0xfefc}, {0xff21, 0xff3a}, {0xff41, 0xff5a},
          201  +    {0xff66, 0xffbe}, {0xffc2, 0xffc7}, {0xffca, 0xffcf}, {0xffd2, 0xffd7},
          202  +    {0xffda, 0xffdc}
          203  +#if CHRBITS > 16
   207    204       ,{0x10000, 0x1000b}, {0x1000d, 0x10026}, {0x10028, 0x1003a}, {0x1003f, 0x1004d},
   208    205       {0x10050, 0x1005d}, {0x10080, 0x100fa}, {0x10280, 0x1029c}, {0x102a0, 0x102d0},
   209    206       {0x10300, 0x1031f}, {0x1032d, 0x10340}, {0x10342, 0x10349}, {0x10350, 0x10375},
   210    207       {0x10380, 0x1039d}, {0x103a0, 0x103c3}, {0x103c8, 0x103cf}, {0x10400, 0x1049d},
   211    208       {0x104b0, 0x104d3}, {0x104d8, 0x104fb}, {0x10500, 0x10527}, {0x10530, 0x10563},
   212    209       {0x10600, 0x10736}, {0x10740, 0x10755}, {0x10760, 0x10767}, {0x10800, 0x10805},
   213    210       {0x1080a, 0x10835}, {0x1083f, 0x10855}, {0x10860, 0x10876}, {0x10880, 0x1089e},
   214    211       {0x108e0, 0x108f2}, {0x10900, 0x10915}, {0x10920, 0x10939}, {0x10980, 0x109b7},
   215         -    {0x10a10, 0x10a13}, {0x10a15, 0x10a17}, {0x10a19, 0x10a33}, {0x10a60, 0x10a7c},
          212  +    {0x10a10, 0x10a13}, {0x10a15, 0x10a17}, {0x10a19, 0x10a35}, {0x10a60, 0x10a7c},
   216    213       {0x10a80, 0x10a9c}, {0x10ac0, 0x10ac7}, {0x10ac9, 0x10ae4}, {0x10b00, 0x10b35},
   217    214       {0x10b40, 0x10b55}, {0x10b60, 0x10b72}, {0x10b80, 0x10b91}, {0x10c00, 0x10c48},
   218         -    {0x10c80, 0x10cb2}, {0x10cc0, 0x10cf2}, {0x11003, 0x11037}, {0x11083, 0x110af},
   219         -    {0x110d0, 0x110e8}, {0x11103, 0x11126}, {0x11150, 0x11172}, {0x11183, 0x111b2},
   220         -    {0x111c1, 0x111c4}, {0x11200, 0x11211}, {0x11213, 0x1122b}, {0x11280, 0x11286},
   221         -    {0x1128a, 0x1128d}, {0x1128f, 0x1129d}, {0x1129f, 0x112a8}, {0x112b0, 0x112de},
   222         -    {0x11305, 0x1130c}, {0x11313, 0x11328}, {0x1132a, 0x11330}, {0x11335, 0x11339},
   223         -    {0x1135d, 0x11361}, {0x11400, 0x11434}, {0x11447, 0x1144a}, {0x11480, 0x114af},
   224         -    {0x11580, 0x115ae}, {0x115d8, 0x115db}, {0x11600, 0x1162f}, {0x11680, 0x116aa},
   225         -    {0x11700, 0x11719}, {0x118a0, 0x118df}, {0x11a0b, 0x11a32}, {0x11a5c, 0x11a83},
          215  +    {0x10c80, 0x10cb2}, {0x10cc0, 0x10cf2}, {0x10d00, 0x10d23}, {0x10f00, 0x10f1c},
          216  +    {0x10f30, 0x10f45}, {0x11003, 0x11037}, {0x11083, 0x110af}, {0x110d0, 0x110e8},
          217  +    {0x11103, 0x11126}, {0x11150, 0x11172}, {0x11183, 0x111b2}, {0x111c1, 0x111c4},
          218  +    {0x11200, 0x11211}, {0x11213, 0x1122b}, {0x11280, 0x11286}, {0x1128a, 0x1128d},
          219  +    {0x1128f, 0x1129d}, {0x1129f, 0x112a8}, {0x112b0, 0x112de}, {0x11305, 0x1130c},
          220  +    {0x11313, 0x11328}, {0x1132a, 0x11330}, {0x11335, 0x11339}, {0x1135d, 0x11361},
          221  +    {0x11400, 0x11434}, {0x11447, 0x1144a}, {0x11480, 0x114af}, {0x11580, 0x115ae},
          222  +    {0x115d8, 0x115db}, {0x11600, 0x1162f}, {0x11680, 0x116aa}, {0x11700, 0x1171a},
          223  +    {0x11800, 0x1182b}, {0x118a0, 0x118df}, {0x11a0b, 0x11a32}, {0x11a5c, 0x11a83},
   226    224       {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},
          225  +    {0x11c72, 0x11c8f}, {0x11d00, 0x11d06}, {0x11d0b, 0x11d30}, {0x11d60, 0x11d65},
          226  +    {0x11d6a, 0x11d89}, {0x11ee0, 0x11ef2}, {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}, {0x16e40, 0x16e7f}, {0x16f00, 0x16f44}, {0x16f93, 0x16f9f},
          230  +    {0x17000, 0x187f1}, {0x18800, 0x18af2}, {0x1b000, 0x1b11e}, {0x1b170, 0x1b2fb},
   232    231       {0x1bc00, 0x1bc6a}, {0x1bc70, 0x1bc7c}, {0x1bc80, 0x1bc88}, {0x1bc90, 0x1bc99},
   233    232       {0x1d400, 0x1d454}, {0x1d456, 0x1d49c}, {0x1d4a9, 0x1d4ac}, {0x1d4ae, 0x1d4b9},
   234    233       {0x1d4bd, 0x1d4c3}, {0x1d4c5, 0x1d505}, {0x1d507, 0x1d50a}, {0x1d50d, 0x1d514},
   235    234       {0x1d516, 0x1d51c}, {0x1d51e, 0x1d539}, {0x1d53b, 0x1d53e}, {0x1d540, 0x1d544},
   236    235       {0x1d54a, 0x1d550}, {0x1d552, 0x1d6a5}, {0x1d6a8, 0x1d6c0}, {0x1d6c2, 0x1d6da},
   237    236       {0x1d6dc, 0x1d6fa}, {0x1d6fc, 0x1d714}, {0x1d716, 0x1d734}, {0x1d736, 0x1d74e},
   238    237       {0x1d750, 0x1d76e}, {0x1d770, 0x1d788}, {0x1d78a, 0x1d7a8}, {0x1d7aa, 0x1d7c2},
................................................................................
   260    259       0xcf2, 0xd3d, 0xd4e, 0xdbd, 0xe32, 0xe33, 0xe81, 0xe82, 0xe84,
   261    260       0xe87, 0xe88, 0xe8a, 0xe8d, 0xea5, 0xea7, 0xeaa, 0xeab, 0xeb2,
   262    261       0xeb3, 0xebd, 0xec6, 0xf00, 0x103f, 0x1061, 0x1065, 0x1066, 0x108e,
   263    262       0x10c7, 0x10cd, 0x1258, 0x12c0, 0x17d7, 0x17dc, 0x18aa, 0x1aa7, 0x1bae,
   264    263       0x1baf, 0x1cf5, 0x1cf6, 0x1f59, 0x1f5b, 0x1f5d, 0x1fbe, 0x2071, 0x207f,
   265    264       0x2102, 0x2107, 0x2115, 0x2124, 0x2126, 0x2128, 0x214e, 0x2183, 0x2184,
   266    265       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
   269         -#if TCL_UTF_MAX > 4
          266  +    0x303c, 0xa62a, 0xa62b, 0xa8fb, 0xa8fd, 0xa8fe, 0xa9cf, 0xaa7a, 0xaab1,
          267  +    0xaab5, 0xaab6, 0xaac0, 0xaac2, 0xfb1d, 0xfb3e, 0xfb40, 0xfb41, 0xfb43,
          268  +    0xfb44
          269  +#if CHRBITS > 16
   270    270       ,0x1003c, 0x1003d, 0x10808, 0x10837, 0x10838, 0x1083c, 0x108f4, 0x108f5, 0x109be,
   271         -    0x109bf, 0x10a00, 0x11176, 0x111da, 0x111dc, 0x11288, 0x1130f, 0x11310, 0x11332,
   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
          271  +    0x109bf, 0x10a00, 0x10f27, 0x11144, 0x11176, 0x111da, 0x111dc, 0x11288, 0x1130f,
          272  +    0x11310, 0x11332, 0x11333, 0x1133d, 0x11350, 0x114c4, 0x114c5, 0x114c7, 0x11644,
          273  +    0x118ff, 0x11a00, 0x11a3a, 0x11a50, 0x11a9d, 0x11c40, 0x11d08, 0x11d09, 0x11d46,
          274  +    0x11d67, 0x11d68, 0x11d98, 0x16f50, 0x16fe0, 0x16fe1, 0x1d49e, 0x1d49f, 0x1d4a2,
          275  +    0x1d4a5, 0x1d4a6, 0x1d4bb, 0x1d546, 0x1ee21, 0x1ee22, 0x1ee24, 0x1ee27, 0x1ee39,
          276  +    0x1ee3b, 0x1ee42, 0x1ee47, 0x1ee49, 0x1ee4b, 0x1ee51, 0x1ee52, 0x1ee54, 0x1ee57,
          277  +    0x1ee59, 0x1ee5b, 0x1ee5d, 0x1ee5f, 0x1ee61, 0x1ee62, 0x1ee64, 0x1ee7e
   278    278   #endif
   279    279   };
   280    280   
   281    281   #define NUM_ALPHA_CHAR (sizeof(alphaCharTable)/sizeof(chr))
   282    282   
   283    283   /*
   284    284    * Unicode: control characters.
   285    285    */
   286    286   
   287    287   static const crange controlRangeTable[] = {
   288    288       {0x0, 0x1f}, {0x7f, 0x9f}, {0x600, 0x605}, {0x200b, 0x200f},
   289    289       {0x202a, 0x202e}, {0x2060, 0x2064}, {0x2066, 0x206f}, {0xe000, 0xf8ff},
   290    290       {0xfff9, 0xfffb}
   291         -#if TCL_UTF_MAX > 4
          291  +#if CHRBITS > 16
   292    292       ,{0x1bca0, 0x1bca3}, {0x1d173, 0x1d17a}, {0xe0020, 0xe007f}, {0xf0000, 0xffffd},
   293    293       {0x100000, 0x10fffd}
   294    294   #endif
   295    295   };
   296    296   
   297    297   #define NUM_CONTROL_RANGE (sizeof(controlRangeTable)/sizeof(crange))
   298    298   
   299    299   static const chr controlCharTable[] = {
   300    300       0xad, 0x61c, 0x6dd, 0x70f, 0x8e2, 0x180e, 0xfeff
   301         -#if TCL_UTF_MAX > 4
   302         -    ,0x110bd, 0xe0001
          301  +#if CHRBITS > 16
          302  +    ,0x110bd, 0x110cd, 0xe0001
   303    303   #endif
   304    304   };
   305    305   
   306    306   #define NUM_CONTROL_CHAR (sizeof(controlCharTable)/sizeof(chr))
   307    307   
   308    308   /*
   309    309    * Unicode: decimal digit characters.
................................................................................
   316    316       {0xd66, 0xd6f}, {0xde6, 0xdef}, {0xe50, 0xe59}, {0xed0, 0xed9},
   317    317       {0xf20, 0xf29}, {0x1040, 0x1049}, {0x1090, 0x1099}, {0x17e0, 0x17e9},
   318    318       {0x1810, 0x1819}, {0x1946, 0x194f}, {0x19d0, 0x19d9}, {0x1a80, 0x1a89},
   319    319       {0x1a90, 0x1a99}, {0x1b50, 0x1b59}, {0x1bb0, 0x1bb9}, {0x1c40, 0x1c49},
   320    320       {0x1c50, 0x1c59}, {0xa620, 0xa629}, {0xa8d0, 0xa8d9}, {0xa900, 0xa909},
   321    321       {0xa9d0, 0xa9d9}, {0xa9f0, 0xa9f9}, {0xaa50, 0xaa59}, {0xabf0, 0xabf9},
   322    322       {0xff10, 0xff19}
   323         -#if TCL_UTF_MAX > 4
   324         -    ,{0x104a0, 0x104a9}, {0x11066, 0x1106f}, {0x110f0, 0x110f9}, {0x11136, 0x1113f},
   325         -    {0x111d0, 0x111d9}, {0x112f0, 0x112f9}, {0x11450, 0x11459}, {0x114d0, 0x114d9},
   326         -    {0x11650, 0x11659}, {0x116c0, 0x116c9}, {0x11730, 0x11739}, {0x118e0, 0x118e9},
   327         -    {0x11c50, 0x11c59}, {0x11d50, 0x11d59}, {0x16a60, 0x16a69}, {0x16b50, 0x16b59},
   328         -    {0x1d7ce, 0x1d7ff}, {0x1e950, 0x1e959}
          323  +#if CHRBITS > 16
          324  +    ,{0x104a0, 0x104a9}, {0x10d30, 0x10d39}, {0x11066, 0x1106f}, {0x110f0, 0x110f9},
          325  +    {0x11136, 0x1113f}, {0x111d0, 0x111d9}, {0x112f0, 0x112f9}, {0x11450, 0x11459},
          326  +    {0x114d0, 0x114d9}, {0x11650, 0x11659}, {0x116c0, 0x116c9}, {0x11730, 0x11739},
          327  +    {0x118e0, 0x118e9}, {0x11c50, 0x11c59}, {0x11d50, 0x11d59}, {0x11da0, 0x11da9},
          328  +    {0x16a60, 0x16a69}, {0x16b50, 0x16b59}, {0x1d7ce, 0x1d7ff}, {0x1e950, 0x1e959}
   329    329   #endif
   330    330   };
   331    331   
   332    332   #define NUM_DIGIT_RANGE (sizeof(digitRangeTable)/sizeof(crange))
   333    333   
   334    334   /*
   335    335    * no singletons of digit characters.
................................................................................
   344    344       {0x55a, 0x55f}, {0x66a, 0x66d}, {0x700, 0x70d}, {0x7f7, 0x7f9},
   345    345       {0x830, 0x83e}, {0xf04, 0xf12}, {0xf3a, 0xf3d}, {0xfd0, 0xfd4},
   346    346       {0x104a, 0x104f}, {0x1360, 0x1368}, {0x16eb, 0x16ed}, {0x17d4, 0x17d6},
   347    347       {0x17d8, 0x17da}, {0x1800, 0x180a}, {0x1aa0, 0x1aa6}, {0x1aa8, 0x1aad},
   348    348       {0x1b5a, 0x1b60}, {0x1bfc, 0x1bff}, {0x1c3b, 0x1c3f}, {0x1cc0, 0x1cc7},
   349    349       {0x2010, 0x2027}, {0x2030, 0x2043}, {0x2045, 0x2051}, {0x2053, 0x205e},
   350    350       {0x2308, 0x230b}, {0x2768, 0x2775}, {0x27e6, 0x27ef}, {0x2983, 0x2998},
   351         -    {0x29d8, 0x29db}, {0x2cf9, 0x2cfc}, {0x2e00, 0x2e2e}, {0x2e30, 0x2e49},
          351  +    {0x29d8, 0x29db}, {0x2cf9, 0x2cfc}, {0x2e00, 0x2e2e}, {0x2e30, 0x2e4e},
   352    352       {0x3001, 0x3003}, {0x3008, 0x3011}, {0x3014, 0x301f}, {0xa60d, 0xa60f},
   353    353       {0xa6f2, 0xa6f7}, {0xa874, 0xa877}, {0xa8f8, 0xa8fa}, {0xa9c1, 0xa9cd},
   354    354       {0xaa5c, 0xaa5f}, {0xfe10, 0xfe19}, {0xfe30, 0xfe52}, {0xfe54, 0xfe61},
   355    355       {0xff01, 0xff03}, {0xff05, 0xff0a}, {0xff0c, 0xff0f}, {0xff3b, 0xff3d},
   356    356       {0xff5f, 0xff65}
   357         -#if TCL_UTF_MAX > 4
          357  +#if CHRBITS > 16
   358    358       ,{0x10100, 0x10102}, {0x10a50, 0x10a58}, {0x10af0, 0x10af6}, {0x10b39, 0x10b3f},
   359         -    {0x10b99, 0x10b9c}, {0x11047, 0x1104d}, {0x110be, 0x110c1}, {0x11140, 0x11143},
   360         -    {0x111c5, 0x111c9}, {0x111dd, 0x111df}, {0x11238, 0x1123d}, {0x1144b, 0x1144f},
   361         -    {0x115c1, 0x115d7}, {0x11641, 0x11643}, {0x11660, 0x1166c}, {0x1173c, 0x1173e},
   362         -    {0x11a3f, 0x11a46}, {0x11a9a, 0x11a9c}, {0x11a9e, 0x11aa2}, {0x11c41, 0x11c45},
   363         -    {0x12470, 0x12474}, {0x16b37, 0x16b3b}, {0x1da87, 0x1da8b}
          359  +    {0x10b99, 0x10b9c}, {0x10f55, 0x10f59}, {0x11047, 0x1104d}, {0x110be, 0x110c1},
          360  +    {0x11140, 0x11143}, {0x111c5, 0x111c8}, {0x111dd, 0x111df}, {0x11238, 0x1123d},
          361  +    {0x1144b, 0x1144f}, {0x115c1, 0x115d7}, {0x11641, 0x11643}, {0x11660, 0x1166c},
          362  +    {0x1173c, 0x1173e}, {0x11a3f, 0x11a46}, {0x11a9a, 0x11a9c}, {0x11a9e, 0x11aa2},
          363  +    {0x11c41, 0x11c45}, {0x12470, 0x12474}, {0x16b37, 0x16b3b}, {0x16e97, 0x16e9a},
          364  +    {0x1da87, 0x1da8b}
   364    365   #endif
   365    366   };
   366    367   
   367    368   #define NUM_PUNCT_RANGE (sizeof(punctRangeTable)/sizeof(crange))
   368    369   
   369    370   static const chr punctCharTable[] = {
   370    371       0x3a, 0x3b, 0x3f, 0x40, 0x5f, 0x7b, 0x7d, 0xa1, 0xa7,
   371    372       0xab, 0xb6, 0xb7, 0xbb, 0xbf, 0x37e, 0x387, 0x589, 0x58a,
   372    373       0x5be, 0x5c0, 0x5c3, 0x5c6, 0x5f3, 0x5f4, 0x609, 0x60a, 0x60c,
   373    374       0x60d, 0x61b, 0x61e, 0x61f, 0x6d4, 0x85e, 0x964, 0x965, 0x970,
   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
   382         -#if TCL_UTF_MAX > 4
          375  +    0x9fd, 0xa76, 0xaf0, 0xc84, 0xdf4, 0xe4f, 0xe5a, 0xe5b, 0xf14,
          376  +    0xf85, 0xfd9, 0xfda, 0x10fb, 0x1400, 0x166d, 0x166e, 0x169b, 0x169c,
          377  +    0x1735, 0x1736, 0x1944, 0x1945, 0x1a1e, 0x1a1f, 0x1c7e, 0x1c7f, 0x1cd3,
          378  +    0x207d, 0x207e, 0x208d, 0x208e, 0x2329, 0x232a, 0x27c5, 0x27c6, 0x29fc,
          379  +    0x29fd, 0x2cfe, 0x2cff, 0x2d70, 0x3030, 0x303d, 0x30a0, 0x30fb, 0xa4fe,
          380  +    0xa4ff, 0xa673, 0xa67e, 0xa8ce, 0xa8cf, 0xa8fc, 0xa92e, 0xa92f, 0xa95f,
          381  +    0xa9de, 0xa9df, 0xaade, 0xaadf, 0xaaf0, 0xaaf1, 0xabeb, 0xfd3e, 0xfd3f,
          382  +    0xfe63, 0xfe68, 0xfe6a, 0xfe6b, 0xff1a, 0xff1b, 0xff1f, 0xff20, 0xff3f,
          383  +    0xff5b, 0xff5d
          384  +#if CHRBITS > 16
   383    385       ,0x1039f, 0x103d0, 0x1056f, 0x10857, 0x1091f, 0x1093f, 0x10a7f, 0x110bb, 0x110bc,
   384         -    0x11174, 0x11175, 0x111cd, 0x111db, 0x112a9, 0x1145b, 0x1145d, 0x114c6, 0x11c70,
   385         -    0x11c71, 0x16a6e, 0x16a6f, 0x16af5, 0x16b44, 0x1bc9f, 0x1e95e, 0x1e95f
          386  +    0x11174, 0x11175, 0x111cd, 0x111db, 0x112a9, 0x1145b, 0x1145d, 0x114c6, 0x1183b,
          387  +    0x11c70, 0x11c71, 0x11ef7, 0x11ef8, 0x16a6e, 0x16a6f, 0x16af5, 0x16b44, 0x1bc9f,
          388  +    0x1e95e, 0x1e95f
   386    389   #endif
   387    390   };
   388    391   
   389    392   #define NUM_PUNCT_CHAR (sizeof(punctCharTable)/sizeof(chr))
   390    393   
   391    394   /*
   392    395    * Unicode: white space characters.
................................................................................
   409    412    * Unicode: lowercase characters.
   410    413    */
   411    414   
   412    415   static const crange lowerRangeTable[] = {
   413    416       {0x61, 0x7a}, {0xdf, 0xf6}, {0xf8, 0xff}, {0x17e, 0x180},
   414    417       {0x199, 0x19b}, {0x1bd, 0x1bf}, {0x233, 0x239}, {0x24f, 0x293},
   415    418       {0x295, 0x2af}, {0x37b, 0x37d}, {0x3ac, 0x3ce}, {0x3d5, 0x3d7},
   416         -    {0x3ef, 0x3f3}, {0x430, 0x45f}, {0x561, 0x587}, {0x13f8, 0x13fd},
   417         -    {0x1c80, 0x1c88}, {0x1d00, 0x1d2b}, {0x1d6b, 0x1d77}, {0x1d79, 0x1d9a},
   418         -    {0x1e95, 0x1e9d}, {0x1eff, 0x1f07}, {0x1f10, 0x1f15}, {0x1f20, 0x1f27},
   419         -    {0x1f30, 0x1f37}, {0x1f40, 0x1f45}, {0x1f50, 0x1f57}, {0x1f60, 0x1f67},
   420         -    {0x1f70, 0x1f7d}, {0x1f80, 0x1f87}, {0x1f90, 0x1f97}, {0x1fa0, 0x1fa7},
   421         -    {0x1fb0, 0x1fb4}, {0x1fc2, 0x1fc4}, {0x1fd0, 0x1fd3}, {0x1fe0, 0x1fe7},
   422         -    {0x1ff2, 0x1ff4}, {0x2146, 0x2149}, {0x2c30, 0x2c5e}, {0x2c76, 0x2c7b},
   423         -    {0x2d00, 0x2d25}, {0xa72f, 0xa731}, {0xa771, 0xa778}, {0xa793, 0xa795},
   424         -    {0xab30, 0xab5a}, {0xab60, 0xab65}, {0xab70, 0xabbf}, {0xfb00, 0xfb06},
   425         -    {0xfb13, 0xfb17}, {0xff41, 0xff5a}
   426         -#if TCL_UTF_MAX > 4
          419  +    {0x3ef, 0x3f3}, {0x430, 0x45f}, {0x560, 0x588}, {0x10d0, 0x10fa},
          420  +    {0x10fd, 0x10ff}, {0x13f8, 0x13fd}, {0x1c80, 0x1c88}, {0x1d00, 0x1d2b},
          421  +    {0x1d6b, 0x1d77}, {0x1d79, 0x1d9a}, {0x1e95, 0x1e9d}, {0x1eff, 0x1f07},
          422  +    {0x1f10, 0x1f15}, {0x1f20, 0x1f27}, {0x1f30, 0x1f37}, {0x1f40, 0x1f45},
          423  +    {0x1f50, 0x1f57}, {0x1f60, 0x1f67}, {0x1f70, 0x1f7d}, {0x1f80, 0x1f87},
          424  +    {0x1f90, 0x1f97}, {0x1fa0, 0x1fa7}, {0x1fb0, 0x1fb4}, {0x1fc2, 0x1fc4},
          425  +    {0x1fd0, 0x1fd3}, {0x1fe0, 0x1fe7}, {0x1ff2, 0x1ff4}, {0x2146, 0x2149},
          426  +    {0x2c30, 0x2c5e}, {0x2c76, 0x2c7b}, {0x2d00, 0x2d25}, {0xa72f, 0xa731},
          427  +    {0xa771, 0xa778}, {0xa793, 0xa795}, {0xab30, 0xab5a}, {0xab60, 0xab65},
          428  +    {0xab70, 0xabbf}, {0xfb00, 0xfb06}, {0xfb13, 0xfb17}, {0xff41, 0xff5a}
          429  +#if CHRBITS > 16
   427    430       ,{0x10428, 0x1044f}, {0x104d8, 0x104fb}, {0x10cc0, 0x10cf2}, {0x118c0, 0x118df},
   428         -    {0x1d41a, 0x1d433}, {0x1d44e, 0x1d454}, {0x1d456, 0x1d467}, {0x1d482, 0x1d49b},
   429         -    {0x1d4b6, 0x1d4b9}, {0x1d4bd, 0x1d4c3}, {0x1d4c5, 0x1d4cf}, {0x1d4ea, 0x1d503},
   430         -    {0x1d51e, 0x1d537}, {0x1d552, 0x1d56b}, {0x1d586, 0x1d59f}, {0x1d5ba, 0x1d5d3},
   431         -    {0x1d5ee, 0x1d607}, {0x1d622, 0x1d63b}, {0x1d656, 0x1d66f}, {0x1d68a, 0x1d6a5},
   432         -    {0x1d6c2, 0x1d6da}, {0x1d6dc, 0x1d6e1}, {0x1d6fc, 0x1d714}, {0x1d716, 0x1d71b},
   433         -    {0x1d736, 0x1d74e}, {0x1d750, 0x1d755}, {0x1d770, 0x1d788}, {0x1d78a, 0x1d78f},
   434         -    {0x1d7aa, 0x1d7c2}, {0x1d7c4, 0x1d7c9}, {0x1e922, 0x1e943}
          431  +    {0x16e60, 0x16e7f}, {0x1d41a, 0x1d433}, {0x1d44e, 0x1d454}, {0x1d456, 0x1d467},
          432  +    {0x1d482, 0x1d49b}, {0x1d4b6, 0x1d4b9}, {0x1d4bd, 0x1d4c3}, {0x1d4c5, 0x1d4cf},
          433  +    {0x1d4ea, 0x1d503}, {0x1d51e, 0x1d537}, {0x1d552, 0x1d56b}, {0x1d586, 0x1d59f},
          434  +    {0x1d5ba, 0x1d5d3}, {0x1d5ee, 0x1d607}, {0x1d622, 0x1d63b}, {0x1d656, 0x1d66f},
          435  +    {0x1d68a, 0x1d6a5}, {0x1d6c2, 0x1d6da}, {0x1d6dc, 0x1d6e1}, {0x1d6fc, 0x1d714},
          436  +    {0x1d716, 0x1d71b}, {0x1d736, 0x1d74e}, {0x1d750, 0x1d755}, {0x1d770, 0x1d788},
          437  +    {0x1d78a, 0x1d78f}, {0x1d7aa, 0x1d7c2}, {0x1d7c4, 0x1d7c9}, {0x1e922, 0x1e943}
   435    438   #endif
   436    439   };
   437    440   
   438    441   #define NUM_LOWER_RANGE (sizeof(lowerRangeTable)/sizeof(crange))
   439    442   
   440    443   static const chr lowerCharTable[] = {
   441    444       0xb5, 0x101, 0x103, 0x105, 0x107, 0x109, 0x10b, 0x10d, 0x10f,
................................................................................
   497    500       0xa691, 0xa693, 0xa695, 0xa697, 0xa699, 0xa69b, 0xa723, 0xa725, 0xa727,
   498    501       0xa729, 0xa72b, 0xa72d, 0xa733, 0xa735, 0xa737, 0xa739, 0xa73b, 0xa73d,
   499    502       0xa73f, 0xa741, 0xa743, 0xa745, 0xa747, 0xa749, 0xa74b, 0xa74d, 0xa74f,
   500    503       0xa751, 0xa753, 0xa755, 0xa757, 0xa759, 0xa75b, 0xa75d, 0xa75f, 0xa761,
   501    504       0xa763, 0xa765, 0xa767, 0xa769, 0xa76b, 0xa76d, 0xa76f, 0xa77a, 0xa77c,
   502    505       0xa77f, 0xa781, 0xa783, 0xa785, 0xa787, 0xa78c, 0xa78e, 0xa791, 0xa797,
   503    506       0xa799, 0xa79b, 0xa79d, 0xa79f, 0xa7a1, 0xa7a3, 0xa7a5, 0xa7a7, 0xa7a9,
   504         -    0xa7b5, 0xa7b7, 0xa7fa
   505         -#if TCL_UTF_MAX > 4
          507  +    0xa7af, 0xa7b5, 0xa7b7, 0xa7b9, 0xa7fa
          508  +#if CHRBITS > 16
   506    509       ,0x1d4bb, 0x1d7cb
   507    510   #endif
   508    511   };
   509    512   
   510    513   #define NUM_LOWER_CHAR (sizeof(lowerCharTable)/sizeof(chr))
   511    514   
   512    515   /*
................................................................................
   514    517    */
   515    518   
   516    519   static const crange upperRangeTable[] = {
   517    520       {0x41, 0x5a}, {0xc0, 0xd6}, {0xd8, 0xde}, {0x189, 0x18b},
   518    521       {0x18e, 0x191}, {0x196, 0x198}, {0x1b1, 0x1b3}, {0x1f6, 0x1f8},
   519    522       {0x243, 0x246}, {0x388, 0x38a}, {0x391, 0x3a1}, {0x3a3, 0x3ab},
   520    523       {0x3d2, 0x3d4}, {0x3fd, 0x42f}, {0x531, 0x556}, {0x10a0, 0x10c5},
   521         -    {0x13a0, 0x13f5}, {0x1f08, 0x1f0f}, {0x1f18, 0x1f1d}, {0x1f28, 0x1f2f},
   522         -    {0x1f38, 0x1f3f}, {0x1f48, 0x1f4d}, {0x1f68, 0x1f6f}, {0x1fb8, 0x1fbb},
   523         -    {0x1fc8, 0x1fcb}, {0x1fd8, 0x1fdb}, {0x1fe8, 0x1fec}, {0x1ff8, 0x1ffb},
   524         -    {0x210b, 0x210d}, {0x2110, 0x2112}, {0x2119, 0x211d}, {0x212a, 0x212d},
   525         -    {0x2130, 0x2133}, {0x2c00, 0x2c2e}, {0x2c62, 0x2c64}, {0x2c6d, 0x2c70},
   526         -    {0x2c7e, 0x2c80}, {0xa7aa, 0xa7ae}, {0xa7b0, 0xa7b4}, {0xff21, 0xff3a}
   527         -#if TCL_UTF_MAX > 4
          524  +    {0x13a0, 0x13f5}, {0x1c90, 0x1cba}, {0x1cbd, 0x1cbf}, {0x1f08, 0x1f0f},
          525  +    {0x1f18, 0x1f1d}, {0x1f28, 0x1f2f}, {0x1f38, 0x1f3f}, {0x1f48, 0x1f4d},
          526  +    {0x1f68, 0x1f6f}, {0x1fb8, 0x1fbb}, {0x1fc8, 0x1fcb}, {0x1fd8, 0x1fdb},
          527  +    {0x1fe8, 0x1fec}, {0x1ff8, 0x1ffb}, {0x210b, 0x210d}, {0x2110, 0x2112},
          528  +    {0x2119, 0x211d}, {0x212a, 0x212d}, {0x2130, 0x2133}, {0x2c00, 0x2c2e},
          529  +    {0x2c62, 0x2c64}, {0x2c6d, 0x2c70}, {0x2c7e, 0x2c80}, {0xa7aa, 0xa7ae},
          530  +    {0xa7b0, 0xa7b4}, {0xff21, 0xff3a}
          531  +#if CHRBITS > 16
   528    532       ,{0x10400, 0x10427}, {0x104b0, 0x104d3}, {0x10c80, 0x10cb2}, {0x118a0, 0x118bf},
   529         -    {0x1d400, 0x1d419}, {0x1d434, 0x1d44d}, {0x1d468, 0x1d481}, {0x1d4a9, 0x1d4ac},
   530         -    {0x1d4ae, 0x1d4b5}, {0x1d4d0, 0x1d4e9}, {0x1d507, 0x1d50a}, {0x1d50d, 0x1d514},
   531         -    {0x1d516, 0x1d51c}, {0x1d53b, 0x1d53e}, {0x1d540, 0x1d544}, {0x1d54a, 0x1d550},
   532         -    {0x1d56c, 0x1d585}, {0x1d5a0, 0x1d5b9}, {0x1d5d4, 0x1d5ed}, {0x1d608, 0x1d621},
   533         -    {0x1d63c, 0x1d655}, {0x1d670, 0x1d689}, {0x1d6a8, 0x1d6c0}, {0x1d6e2, 0x1d6fa},
   534         -    {0x1d71c, 0x1d734}, {0x1d756, 0x1d76e}, {0x1d790, 0x1d7a8}, {0x1e900, 0x1e921}
          533  +    {0x16e40, 0x16e5f}, {0x1d400, 0x1d419}, {0x1d434, 0x1d44d}, {0x1d468, 0x1d481},
          534  +    {0x1d4a9, 0x1d4ac}, {0x1d4ae, 0x1d4b5}, {0x1d4d0, 0x1d4e9}, {0x1d507, 0x1d50a},
          535  +    {0x1d50d, 0x1d514}, {0x1d516, 0x1d51c}, {0x1d53b, 0x1d53e}, {0x1d540, 0x1d544},
          536  +    {0x1d54a, 0x1d550}, {0x1d56c, 0x1d585}, {0x1d5a0, 0x1d5b9}, {0x1d5d4, 0x1d5ed},
          537  +    {0x1d608, 0x1d621}, {0x1d63c, 0x1d655}, {0x1d670, 0x1d689}, {0x1d6a8, 0x1d6c0},
          538  +    {0x1d6e2, 0x1d6fa}, {0x1d71c, 0x1d734}, {0x1d756, 0x1d76e}, {0x1d790, 0x1d7a8},
          539  +    {0x1e900, 0x1e921}
   535    540   #endif
   536    541   };
   537    542   
   538    543   #define NUM_UPPER_RANGE (sizeof(upperRangeTable)/sizeof(crange))
   539    544   
   540    545   static const chr upperCharTable[] = {
   541    546       0x100, 0x102, 0x104, 0x106, 0x108, 0x10a, 0x10c, 0x10e, 0x110,
................................................................................
   596    601       0xa686, 0xa688, 0xa68a, 0xa68c, 0xa68e, 0xa690, 0xa692, 0xa694, 0xa696,
   597    602       0xa698, 0xa69a, 0xa722, 0xa724, 0xa726, 0xa728, 0xa72a, 0xa72c, 0xa72e,
   598    603       0xa732, 0xa734, 0xa736, 0xa738, 0xa73a, 0xa73c, 0xa73e, 0xa740, 0xa742,
   599    604       0xa744, 0xa746, 0xa748, 0xa74a, 0xa74c, 0xa74e, 0xa750, 0xa752, 0xa754,
   600    605       0xa756, 0xa758, 0xa75a, 0xa75c, 0xa75e, 0xa760, 0xa762, 0xa764, 0xa766,
   601    606       0xa768, 0xa76a, 0xa76c, 0xa76e, 0xa779, 0xa77b, 0xa77d, 0xa77e, 0xa780,
   602    607       0xa782, 0xa784, 0xa786, 0xa78b, 0xa78d, 0xa790, 0xa792, 0xa796, 0xa798,
   603         -    0xa79a, 0xa79c, 0xa79e, 0xa7a0, 0xa7a2, 0xa7a4, 0xa7a6, 0xa7a8, 0xa7b6
   604         -#if TCL_UTF_MAX > 4
          608  +    0xa79a, 0xa79c, 0xa79e, 0xa7a0, 0xa7a2, 0xa7a4, 0xa7a6, 0xa7a8, 0xa7b6,
          609  +    0xa7b8
          610  +#if CHRBITS > 16
   605    611       ,0x1d49c, 0x1d49e, 0x1d49f, 0x1d4a2, 0x1d4a5, 0x1d4a6, 0x1d504, 0x1d505, 0x1d538,
   606    612       0x1d539, 0x1d546, 0x1d7ca
   607    613   #endif
   608    614   };
   609    615   
   610    616   #define NUM_UPPER_CHAR (sizeof(upperCharTable)/sizeof(chr))
   611    617   
................................................................................
   612    618   /*
   613    619    * Unicode: unicode print characters excluding space.
   614    620    */
   615    621   
   616    622   static const crange graphRangeTable[] = {
   617    623       {0x21, 0x7e}, {0xa1, 0xac}, {0xae, 0x377}, {0x37a, 0x37f},
   618    624       {0x384, 0x38a}, {0x38e, 0x3a1}, {0x3a3, 0x52f}, {0x531, 0x556},
   619         -    {0x559, 0x55f}, {0x561, 0x587}, {0x58d, 0x58f}, {0x591, 0x5c7},
   620         -    {0x5d0, 0x5ea}, {0x5f0, 0x5f4}, {0x606, 0x61b}, {0x61e, 0x6dc},
   621         -    {0x6de, 0x70d}, {0x710, 0x74a}, {0x74d, 0x7b1}, {0x7c0, 0x7fa},
   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},
   671         -    {0x2bec, 0x2bef}, {0x2c00, 0x2c2e}, {0x2c30, 0x2c5e}, {0x2c60, 0x2cf3},
          625  +    {0x559, 0x58a}, {0x58d, 0x58f}, {0x591, 0x5c7}, {0x5d0, 0x5ea},
          626  +    {0x5ef, 0x5f4}, {0x606, 0x61b}, {0x61e, 0x6dc}, {0x6de, 0x70d},
          627  +    {0x710, 0x74a}, {0x74d, 0x7b1}, {0x7c0, 0x7fa}, {0x7fd, 0x82d},
          628  +    {0x830, 0x83e}, {0x840, 0x85b}, {0x860, 0x86a}, {0x8a0, 0x8b4},
          629  +    {0x8b6, 0x8bd}, {0x8d3, 0x8e1}, {0x8e3, 0x983}, {0x985, 0x98c},
          630  +    {0x993, 0x9a8}, {0x9aa, 0x9b0}, {0x9b6, 0x9b9}, {0x9bc, 0x9c4},
          631  +    {0x9cb, 0x9ce}, {0x9df, 0x9e3}, {0x9e6, 0x9fe}, {0xa01, 0xa03},
          632  +    {0xa05, 0xa0a}, {0xa13, 0xa28}, {0xa2a, 0xa30}, {0xa3e, 0xa42},
          633  +    {0xa4b, 0xa4d}, {0xa59, 0xa5c}, {0xa66, 0xa76}, {0xa81, 0xa83},
          634  +    {0xa85, 0xa8d}, {0xa8f, 0xa91}, {0xa93, 0xaa8}, {0xaaa, 0xab0},
          635  +    {0xab5, 0xab9}, {0xabc, 0xac5}, {0xac7, 0xac9}, {0xacb, 0xacd},
          636  +    {0xae0, 0xae3}, {0xae6, 0xaf1}, {0xaf9, 0xaff}, {0xb01, 0xb03},
          637  +    {0xb05, 0xb0c}, {0xb13, 0xb28}, {0xb2a, 0xb30}, {0xb35, 0xb39},
          638  +    {0xb3c, 0xb44}, {0xb4b, 0xb4d}, {0xb5f, 0xb63}, {0xb66, 0xb77},
          639  +    {0xb85, 0xb8a}, {0xb8e, 0xb90}, {0xb92, 0xb95}, {0xba8, 0xbaa},
          640  +    {0xbae, 0xbb9}, {0xbbe, 0xbc2}, {0xbc6, 0xbc8}, {0xbca, 0xbcd},
          641  +    {0xbe6, 0xbfa}, {0xc00, 0xc0c}, {0xc0e, 0xc10}, {0xc12, 0xc28},
          642  +    {0xc2a, 0xc39}, {0xc3d, 0xc44}, {0xc46, 0xc48}, {0xc4a, 0xc4d},
          643  +    {0xc58, 0xc5a}, {0xc60, 0xc63}, {0xc66, 0xc6f}, {0xc78, 0xc8c},
          644  +    {0xc8e, 0xc90}, {0xc92, 0xca8}, {0xcaa, 0xcb3}, {0xcb5, 0xcb9},
          645  +    {0xcbc, 0xcc4}, {0xcc6, 0xcc8}, {0xcca, 0xccd}, {0xce0, 0xce3},
          646  +    {0xce6, 0xcef}, {0xd00, 0xd03}, {0xd05, 0xd0c}, {0xd0e, 0xd10},
          647  +    {0xd12, 0xd44}, {0xd46, 0xd48}, {0xd4a, 0xd4f}, {0xd54, 0xd63},
          648  +    {0xd66, 0xd7f}, {0xd85, 0xd96}, {0xd9a, 0xdb1}, {0xdb3, 0xdbb},
          649  +    {0xdc0, 0xdc6}, {0xdcf, 0xdd4}, {0xdd8, 0xddf}, {0xde6, 0xdef},
          650  +    {0xdf2, 0xdf4}, {0xe01, 0xe3a}, {0xe3f, 0xe5b}, {0xe94, 0xe97},
          651  +    {0xe99, 0xe9f}, {0xea1, 0xea3}, {0xead, 0xeb9}, {0xebb, 0xebd},
          652  +    {0xec0, 0xec4}, {0xec8, 0xecd}, {0xed0, 0xed9}, {0xedc, 0xedf},
          653  +    {0xf00, 0xf47}, {0xf49, 0xf6c}, {0xf71, 0xf97}, {0xf99, 0xfbc},
          654  +    {0xfbe, 0xfcc}, {0xfce, 0xfda}, {0x1000, 0x10c5}, {0x10d0, 0x1248},
          655  +    {0x124a, 0x124d}, {0x1250, 0x1256}, {0x125a, 0x125d}, {0x1260, 0x1288},
          656  +    {0x128a, 0x128d}, {0x1290, 0x12b0}, {0x12b2, 0x12b5}, {0x12b8, 0x12be},
          657  +    {0x12c2, 0x12c5}, {0x12c8, 0x12d6}, {0x12d8, 0x1310}, {0x1312, 0x1315},
          658  +    {0x1318, 0x135a}, {0x135d, 0x137c}, {0x1380, 0x1399}, {0x13a0, 0x13f5},
          659  +    {0x13f8, 0x13fd}, {0x1400, 0x167f}, {0x1681, 0x169c}, {0x16a0, 0x16f8},
          660  +    {0x1700, 0x170c}, {0x170e, 0x1714}, {0x1720, 0x1736}, {0x1740, 0x1753},
          661  +    {0x1760, 0x176c}, {0x176e, 0x1770}, {0x1780, 0x17dd}, {0x17e0, 0x17e9},
          662  +    {0x17f0, 0x17f9}, {0x1800, 0x180d}, {0x1810, 0x1819}, {0x1820, 0x1878},
          663  +    {0x1880, 0x18aa}, {0x18b0, 0x18f5}, {0x1900, 0x191e}, {0x1920, 0x192b},
          664  +    {0x1930, 0x193b}, {0x1944, 0x196d}, {0x1970, 0x1974}, {0x1980, 0x19ab},
          665  +    {0x19b0, 0x19c9}, {0x19d0, 0x19da}, {0x19de, 0x1a1b}, {0x1a1e, 0x1a5e},
          666  +    {0x1a60, 0x1a7c}, {0x1a7f, 0x1a89}, {0x1a90, 0x1a99}, {0x1aa0, 0x1aad},
          667  +    {0x1ab0, 0x1abe}, {0x1b00, 0x1b4b}, {0x1b50, 0x1b7c}, {0x1b80, 0x1bf3},
          668  +    {0x1bfc, 0x1c37}, {0x1c3b, 0x1c49}, {0x1c4d, 0x1c88}, {0x1c90, 0x1cba},
          669  +    {0x1cbd, 0x1cc7}, {0x1cd0, 0x1cf9}, {0x1d00, 0x1df9}, {0x1dfb, 0x1f15},
          670  +    {0x1f18, 0x1f1d}, {0x1f20, 0x1f45}, {0x1f48, 0x1f4d}, {0x1f50, 0x1f57},
          671  +    {0x1f5f, 0x1f7d}, {0x1f80, 0x1fb4}, {0x1fb6, 0x1fc4}, {0x1fc6, 0x1fd3},
          672  +    {0x1fd6, 0x1fdb}, {0x1fdd, 0x1fef}, {0x1ff2, 0x1ff4}, {0x1ff6, 0x1ffe},
          673  +    {0x2010, 0x2027}, {0x2030, 0x205e}, {0x2074, 0x208e}, {0x2090, 0x209c},
          674  +    {0x20a0, 0x20bf}, {0x20d0, 0x20f0}, {0x2100, 0x218b}, {0x2190, 0x2426},
          675  +    {0x2440, 0x244a}, {0x2460, 0x2b73}, {0x2b76, 0x2b95}, {0x2b98, 0x2bc8},
          676  +    {0x2bca, 0x2bfe}, {0x2c00, 0x2c2e}, {0x2c30, 0x2c5e}, {0x2c60, 0x2cf3},
   672    677       {0x2cf9, 0x2d25}, {0x2d30, 0x2d67}, {0x2d7f, 0x2d96}, {0x2da0, 0x2da6},
   673    678       {0x2da8, 0x2dae}, {0x2db0, 0x2db6}, {0x2db8, 0x2dbe}, {0x2dc0, 0x2dc6},
   674         -    {0x2dc8, 0x2dce}, {0x2dd0, 0x2dd6}, {0x2dd8, 0x2dde}, {0x2de0, 0x2e49},
          679  +    {0x2dc8, 0x2dce}, {0x2dd0, 0x2dd6}, {0x2dd8, 0x2dde}, {0x2de0, 0x2e4e},
   675    680       {0x2e80, 0x2e99}, {0x2e9b, 0x2ef3}, {0x2f00, 0x2fd5}, {0x2ff0, 0x2ffb},
   676         -    {0x3001, 0x303f}, {0x3041, 0x3096}, {0x3099, 0x30ff}, {0x3105, 0x312e},
          681  +    {0x3001, 0x303f}, {0x3041, 0x3096}, {0x3099, 0x30ff}, {0x3105, 0x312f},
   677    682       {0x3131, 0x318e}, {0x3190, 0x31ba}, {0x31c0, 0x31e3}, {0x31f0, 0x321e},
   678         -    {0x3220, 0x32fe}, {0x3300, 0x4db5}, {0x4dc0, 0x9fea}, {0xa000, 0xa48c},
   679         -    {0xa490, 0xa4c6}, {0xa4d0, 0xa62b}, {0xa640, 0xa6f7}, {0xa700, 0xa7ae},
   680         -    {0xa7b0, 0xa7b7}, {0xa7f7, 0xa82b}, {0xa830, 0xa839}, {0xa840, 0xa877},
   681         -    {0xa880, 0xa8c5}, {0xa8ce, 0xa8d9}, {0xa8e0, 0xa8fd}, {0xa900, 0xa953},
   682         -    {0xa95f, 0xa97c}, {0xa980, 0xa9cd}, {0xa9cf, 0xa9d9}, {0xa9de, 0xa9fe},
   683         -    {0xaa00, 0xaa36}, {0xaa40, 0xaa4d}, {0xaa50, 0xaa59}, {0xaa5c, 0xaac2},
   684         -    {0xaadb, 0xaaf6}, {0xab01, 0xab06}, {0xab09, 0xab0e}, {0xab11, 0xab16},
   685         -    {0xab20, 0xab26}, {0xab28, 0xab2e}, {0xab30, 0xab65}, {0xab70, 0xabed},
   686         -    {0xabf0, 0xabf9}, {0xac00, 0xd7a3}, {0xd7b0, 0xd7c6}, {0xd7cb, 0xd7fb},
   687         -    {0xdc00, 0xdc3e}, {0xdc40, 0xdc7e}, {0xdc80, 0xdcbe}, {0xdcc0, 0xdcfe},
   688         -    {0xdd00, 0xdd3e}, {0xdd40, 0xdd7e}, {0xdd80, 0xddbe}, {0xddc0, 0xddfe},
   689         -    {0xde00, 0xde3e}, {0xde40, 0xde7e}, {0xde80, 0xdebe}, {0xdec0, 0xdefe},
   690         -    {0xdf00, 0xdf3e}, {0xdf40, 0xdf7e}, {0xdf80, 0xdfbe}, {0xdfc0, 0xdffe},
   691         -    {0xf900, 0xfa6d}, {0xfa70, 0xfad9}, {0xfb00, 0xfb06}, {0xfb13, 0xfb17},
   692         -    {0xfb1d, 0xfb36}, {0xfb38, 0xfb3c}, {0xfb46, 0xfbc1}, {0xfbd3, 0xfd3f},
   693         -    {0xfd50, 0xfd8f}, {0xfd92, 0xfdc7}, {0xfdf0, 0xfdfd}, {0xfe00, 0xfe19},
   694         -    {0xfe20, 0xfe52}, {0xfe54, 0xfe66}, {0xfe68, 0xfe6b}, {0xfe70, 0xfe74},
   695         -    {0xfe76, 0xfefc}, {0xff01, 0xffbe}, {0xffc2, 0xffc7}, {0xffca, 0xffcf},
   696         -    {0xffd2, 0xffd7}, {0xffda, 0xffdc}, {0xffe0, 0xffe6}, {0xffe8, 0xffee}
   697         -#if TCL_UTF_MAX > 4
          683  +    {0x3220, 0x32fe}, {0x3300, 0x4db5}, {0x4dc0, 0x9fef}, {0xa000, 0xa48c},
          684  +    {0xa490, 0xa4c6}, {0xa4d0, 0xa62b}, {0xa640, 0xa6f7}, {0xa700, 0xa7b9},
          685  +    {0xa7f7, 0xa82b}, {0xa830, 0xa839}, {0xa840, 0xa877}, {0xa880, 0xa8c5},
          686  +    {0xa8ce, 0xa8d9}, {0xa8e0, 0xa953}, {0xa95f, 0xa97c}, {0xa980, 0xa9cd},
          687  +    {0xa9cf, 0xa9d9}, {0xa9de, 0xa9fe}, {0xaa00, 0xaa36}, {0xaa40, 0xaa4d},
          688  +    {0xaa50, 0xaa59}, {0xaa5c, 0xaac2}, {0xaadb, 0xaaf6}, {0xab01, 0xab06},
          689  +    {0xab09, 0xab0e}, {0xab11, 0xab16}, {0xab20, 0xab26}, {0xab28, 0xab2e},
          690  +    {0xab30, 0xab65}, {0xab70, 0xabed}, {0xabf0, 0xabf9}, {0xac00, 0xd7a3},
          691  +    {0xd7b0, 0xd7c6}, {0xd7cb, 0xd7fb}, {0xf900, 0xfa6d}, {0xfa70, 0xfad9},
          692  +    {0xfb00, 0xfb06}, {0xfb13, 0xfb17}, {0xfb1d, 0xfb36}, {0xfb38, 0xfb3c},
          693  +    {0xfb46, 0xfbc1}, {0xfbd3, 0xfd3f}, {0xfd50, 0xfd8f}, {0xfd92, 0xfdc7},
          694  +    {0xfdf0, 0xfdfd}, {0xfe00, 0xfe19}, {0xfe20, 0xfe52}, {0xfe54, 0xfe66},
          695  +    {0xfe68, 0xfe6b}, {0xfe70, 0xfe74}, {0xfe76, 0xfefc}, {0xff01, 0xffbe},
          696  +    {0xffc2, 0xffc7}, {0xffca, 0xffcf}, {0xffd2, 0xffd7}, {0xffda, 0xffdc},
          697  +    {0xffe0, 0xffe6}, {0xffe8, 0xffee}
          698  +#if CHRBITS > 16
   698    699       ,{0x10000, 0x1000b}, {0x1000d, 0x10026}, {0x10028, 0x1003a}, {0x1003f, 0x1004d},
   699    700       {0x10050, 0x1005d}, {0x10080, 0x100fa}, {0x10100, 0x10102}, {0x10107, 0x10133},
   700    701       {0x10137, 0x1018e}, {0x10190, 0x1019b}, {0x101d0, 0x101fd}, {0x10280, 0x1029c},
   701    702       {0x102a0, 0x102d0}, {0x102e0, 0x102fb}, {0x10300, 0x10323}, {0x1032d, 0x1034a},
   702    703       {0x10350, 0x1037a}, {0x10380, 0x1039d}, {0x1039f, 0x103c3}, {0x103c8, 0x103d5},
   703    704       {0x10400, 0x1049d}, {0x104a0, 0x104a9}, {0x104b0, 0x104d3}, {0x104d8, 0x104fb},
   704    705       {0x10500, 0x10527}, {0x10530, 0x10563}, {0x10600, 0x10736}, {0x10740, 0x10755},
   705    706       {0x10760, 0x10767}, {0x10800, 0x10805}, {0x1080a, 0x10835}, {0x1083f, 0x10855},
   706    707       {0x10857, 0x1089e}, {0x108a7, 0x108af}, {0x108e0, 0x108f2}, {0x108fb, 0x1091b},
   707    708       {0x1091f, 0x10939}, {0x10980, 0x109b7}, {0x109bc, 0x109cf}, {0x109d2, 0x10a03},
   708         -    {0x10a0c, 0x10a13}, {0x10a15, 0x10a17}, {0x10a19, 0x10a33}, {0x10a38, 0x10a3a},
   709         -    {0x10a3f, 0x10a47}, {0x10a50, 0x10a58}, {0x10a60, 0x10a9f}, {0x10ac0, 0x10ae6},
          709  +    {0x10a0c, 0x10a13}, {0x10a15, 0x10a17}, {0x10a19, 0x10a35}, {0x10a38, 0x10a3a},
          710  +    {0x10a3f, 0x10a48}, {0x10a50, 0x10a58}, {0x10a60, 0x10a9f}, {0x10ac0, 0x10ae6},
   710    711       {0x10aeb, 0x10af6}, {0x10b00, 0x10b35}, {0x10b39, 0x10b55}, {0x10b58, 0x10b72},
   711    712       {0x10b78, 0x10b91}, {0x10b99, 0x10b9c}, {0x10ba9, 0x10baf}, {0x10c00, 0x10c48},
   712         -    {0x10c80, 0x10cb2}, {0x10cc0, 0x10cf2}, {0x10cfa, 0x10cff}, {0x10e60, 0x10e7e},
   713         -    {0x11000, 0x1104d}, {0x11052, 0x1106f}, {0x1107f, 0x110bc}, {0x110be, 0x110c1},
   714         -    {0x110d0, 0x110e8}, {0x110f0, 0x110f9}, {0x11100, 0x11134}, {0x11136, 0x11143},
   715         -    {0x11150, 0x11176}, {0x11180, 0x111cd}, {0x111d0, 0x111df}, {0x111e1, 0x111f4},
   716         -    {0x11200, 0x11211}, {0x11213, 0x1123e}, {0x11280, 0x11286}, {0x1128a, 0x1128d},
   717         -    {0x1128f, 0x1129d}, {0x1129f, 0x112a9}, {0x112b0, 0x112ea}, {0x112f0, 0x112f9},
   718         -    {0x11300, 0x11303}, {0x11305, 0x1130c}, {0x11313, 0x11328}, {0x1132a, 0x11330},
   719         -    {0x11335, 0x11339}, {0x1133c, 0x11344}, {0x1134b, 0x1134d}, {0x1135d, 0x11363},
   720         -    {0x11366, 0x1136c}, {0x11370, 0x11374}, {0x11400, 0x11459}, {0x11480, 0x114c7},
   721         -    {0x114d0, 0x114d9}, {0x11580, 0x115b5}, {0x115b8, 0x115dd}, {0x11600, 0x11644},
   722         -    {0x11650, 0x11659}, {0x11660, 0x1166c}, {0x11680, 0x116b7}, {0x116c0, 0x116c9},
   723         -    {0x11700, 0x11719}, {0x1171d, 0x1172b}, {0x11730, 0x1173f}, {0x118a0, 0x118f2},
   724         -    {0x11a00, 0x11a47}, {0x11a50, 0x11a83}, {0x11a86, 0x11a9c}, {0x11a9e, 0x11aa2},
   725         -    {0x11ac0, 0x11af8}, {0x11c00, 0x11c08}, {0x11c0a, 0x11c36}, {0x11c38, 0x11c45},
   726         -    {0x11c50, 0x11c6c}, {0x11c70, 0x11c8f}, {0x11c92, 0x11ca7}, {0x11ca9, 0x11cb6},
   727         -    {0x11d00, 0x11d06}, {0x11d0b, 0x11d36}, {0x11d3f, 0x11d47}, {0x11d50, 0x11d59},
          713  +    {0x10c80, 0x10cb2}, {0x10cc0, 0x10cf2}, {0x10cfa, 0x10d27}, {0x10d30, 0x10d39},
          714  +    {0x10e60, 0x10e7e}, {0x10f00, 0x10f27}, {0x10f30, 0x10f59}, {0x11000, 0x1104d},
          715  +    {0x11052, 0x1106f}, {0x1107f, 0x110bc}, {0x110be, 0x110c1}, {0x110d0, 0x110e8},
          716  +    {0x110f0, 0x110f9}, {0x11100, 0x11134}, {0x11136, 0x11146}, {0x11150, 0x11176},
          717  +    {0x11180, 0x111cd}, {0x111d0, 0x111df}, {0x111e1, 0x111f4}, {0x11200, 0x11211},
          718  +    {0x11213, 0x1123e}, {0x11280, 0x11286}, {0x1128a, 0x1128d}, {0x1128f, 0x1129d},
          719  +    {0x1129f, 0x112a9}, {0x112b0, 0x112ea}, {0x112f0, 0x112f9}, {0x11300, 0x11303},
          720  +    {0x11305, 0x1130c}, {0x11313, 0x11328}, {0x1132a, 0x11330}, {0x11335, 0x11339},
          721  +    {0x1133b, 0x11344}, {0x1134b, 0x1134d}, {0x1135d, 0x11363}, {0x11366, 0x1136c},
          722  +    {0x11370, 0x11374}, {0x11400, 0x11459}, {0x11480, 0x114c7}, {0x114d0, 0x114d9},
          723  +    {0x11580, 0x115b5}, {0x115b8, 0x115dd}, {0x11600, 0x11644}, {0x11650, 0x11659},
          724  +    {0x11660, 0x1166c}, {0x11680, 0x116b7}, {0x116c0, 0x116c9}, {0x11700, 0x1171a},
          725  +    {0x1171d, 0x1172b}, {0x11730, 0x1173f}, {0x11800, 0x1183b}, {0x118a0, 0x118f2},
          726  +    {0x11a00, 0x11a47}, {0x11a50, 0x11a83}, {0x11a86, 0x11aa2}, {0x11ac0, 0x11af8},
          727  +    {0x11c00, 0x11c08}, {0x11c0a, 0x11c36}, {0x11c38, 0x11c45}, {0x11c50, 0x11c6c},
          728  +    {0x11c70, 0x11c8f}, {0x11c92, 0x11ca7}, {0x11ca9, 0x11cb6}, {0x11d00, 0x11d06},
          729  +    {0x11d0b, 0x11d36}, {0x11d3f, 0x11d47}, {0x11d50, 0x11d59}, {0x11d60, 0x11d65},
          730  +    {0x11d6a, 0x11d8e}, {0x11d93, 0x11d98}, {0x11da0, 0x11da9}, {0x11ee0, 0x11ef8},
   728    731       {0x12000, 0x12399}, {0x12400, 0x1246e}, {0x12470, 0x12474}, {0x12480, 0x12543},
   729    732       {0x13000, 0x1342e}, {0x14400, 0x14646}, {0x16800, 0x16a38}, {0x16a40, 0x16a5e},
   730    733       {0x16a60, 0x16a69}, {0x16ad0, 0x16aed}, {0x16af0, 0x16af5}, {0x16b00, 0x16b45},
   731    734       {0x16b50, 0x16b59}, {0x16b5b, 0x16b61}, {0x16b63, 0x16b77}, {0x16b7d, 0x16b8f},
   732         -    {0x16f00, 0x16f44}, {0x16f50, 0x16f7e}, {0x16f8f, 0x16f9f}, {0x17000, 0x187ec},
   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}
          735  +    {0x16e40, 0x16e9a}, {0x16f00, 0x16f44}, {0x16f50, 0x16f7e}, {0x16f8f, 0x16f9f},
          736  +    {0x17000, 0x187f1}, {0x18800, 0x18af2}, {0x1b000, 0x1b11e}, {0x1b170, 0x1b2fb},
          737  +    {0x1bc00, 0x1bc6a}, {0x1bc70, 0x1bc7c}, {0x1bc80, 0x1bc88}, {0x1bc90, 0x1bc99},
          738  +    {0x1bc9c, 0x1bc9f}, {0x1d000, 0x1d0f5}, {0x1d100, 0x1d126}, {0x1d129, 0x1d172},
          739  +    {0x1d17b, 0x1d1e8}, {0x1d200, 0x1d245}, {0x1d2e0, 0x1d2f3}, {0x1d300, 0x1d356},
          740  +    {0x1d360, 0x1d378}, {0x1d400, 0x1d454}, {0x1d456, 0x1d49c}, {0x1d4a9, 0x1d4ac},
          741  +    {0x1d4ae, 0x1d4b9}, {0x1d4bd, 0x1d4c3}, {0x1d4c5, 0x1d505}, {0x1d507, 0x1d50a},
          742  +    {0x1d50d, 0x1d514}, {0x1d516, 0x1d51c}, {0x1d51e, 0x1d539}, {0x1d53b, 0x1d53e},
          743  +    {0x1d540, 0x1d544}, {0x1d54a, 0x1d550}, {0x1d552, 0x1d6a5}, {0x1d6a8, 0x1d7cb},
          744  +    {0x1d7ce, 0x1da8b}, {0x1da9b, 0x1da9f}, {0x1daa1, 0x1daaf}, {0x1e000, 0x1e006},
          745  +    {0x1e008, 0x1e018}, {0x1e01b, 0x1e021}, {0x1e026, 0x1e02a}, {0x1e800, 0x1e8c4},
          746  +    {0x1e8c7, 0x1e8d6}, {0x1e900, 0x1e94a}, {0x1e950, 0x1e959}, {0x1ec71, 0x1ecb4},
          747  +    {0x1ee00, 0x1ee03}, {0x1ee05, 0x1ee1f}, {0x1ee29, 0x1ee32}, {0x1ee34, 0x1ee37},
          748  +    {0x1ee4d, 0x1ee4f}, {0x1ee67, 0x1ee6a}, {0x1ee6c, 0x1ee72}, {0x1ee74, 0x1ee77},
          749  +    {0x1ee79, 0x1ee7c}, {0x1ee80, 0x1ee89}, {0x1ee8b, 0x1ee9b}, {0x1eea1, 0x1eea3},
          750  +    {0x1eea5, 0x1eea9}, {0x1eeab, 0x1eebb}, {0x1f000, 0x1f02b}, {0x1f030, 0x1f093},
          751  +    {0x1f0a0, 0x1f0ae}, {0x1f0b1, 0x1f0bf}, {0x1f0c1, 0x1f0cf}, {0x1f0d1, 0x1f0f5},
          752  +    {0x1f100, 0x1f10c}, {0x1f110, 0x1f16b}, {0x1f170, 0x1f1ac}, {0x1f1e6, 0x1f202},
          753  +    {0x1f210, 0x1f23b}, {0x1f240, 0x1f248}, {0x1f260, 0x1f265}, {0x1f300, 0x1f6d4},
          754  +    {0x1f6e0, 0x1f6ec}, {0x1f6f0, 0x1f6f9}, {0x1f700, 0x1f773}, {0x1f780, 0x1f7d8},
          755  +    {0x1f800, 0x1f80b}, {0x1f810, 0x1f847}, {0x1f850, 0x1f859}, {0x1f860, 0x1f887},
          756  +    {0x1f890, 0x1f8ad}, {0x1f900, 0x1f90b}, {0x1f910, 0x1f93e}, {0x1f940, 0x1f970},
          757  +    {0x1f973, 0x1f976}, {0x1f97c, 0x1f9a2}, {0x1f9b0, 0x1f9b9}, {0x1f9c0, 0x1f9c2},
          758  +    {0x1f9d0, 0x1f9ff}, {0x1fa60, 0x1fa6d}, {0x20000, 0x2a6d6}, {0x2a700, 0x2b734},
          759  +    {0x2b740, 0x2b81d}, {0x2b820, 0x2cea1}, {0x2ceb0, 0x2ebe0}, {0x2f800, 0x2fa1d},
          760  +    {0xe0100, 0xe01ef}
   756    761   #endif
   757    762   };
   758    763   
   759    764   #define NUM_GRAPH_RANGE (sizeof(graphRangeTable)/sizeof(crange))
   760    765   
   761    766   static const chr graphCharTable[] = {
   762         -    0x38c, 0x589, 0x58a, 0x85e, 0x98f, 0x990, 0x9b2, 0x9c7, 0x9c8,
   763         -    0x9d7, 0x9dc, 0x9dd, 0xa0f, 0xa10, 0xa32, 0xa33, 0xa35, 0xa36,
   764         -    0xa38, 0xa39, 0xa3c, 0xa47, 0xa48, 0xa51, 0xa5e, 0xab2, 0xab3,
   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
   773         -#if TCL_UTF_MAX > 4
          767  +    0x38c, 0x85e, 0x98f, 0x990, 0x9b2, 0x9c7, 0x9c8, 0x9d7, 0x9dc,
          768  +    0x9dd, 0xa0f, 0xa10, 0xa32, 0xa33, 0xa35, 0xa36, 0xa38, 0xa39,
          769  +    0xa3c, 0xa47, 0xa48, 0xa51, 0xa5e, 0xab2, 0xab3, 0xad0, 0xb0f,
          770  +    0xb10, 0xb32, 0xb33, 0xb47, 0xb48, 0xb56, 0xb57, 0xb5c, 0xb5d,
          771  +    0xb82, 0xb83, 0xb99, 0xb9a, 0xb9c, 0xb9e, 0xb9f, 0xba3, 0xba4,
          772  +    0xbd0, 0xbd7, 0xc55, 0xc56, 0xcd5, 0xcd6, 0xcde, 0xcf1, 0xcf2,
          773  +    0xd82, 0xd83, 0xdbd, 0xdca, 0xdd6, 0xe81, 0xe82, 0xe84, 0xe87,
          774  +    0xe88, 0xe8a, 0xe8d, 0xea5, 0xea7, 0xeaa, 0xeab, 0xec6, 0x10c7,
          775  +    0x10cd, 0x1258, 0x12c0, 0x1772, 0x1773, 0x1940, 0x1f59, 0x1f5b, 0x1f5d,
          776  +    0x2070, 0x2071, 0x2d27, 0x2d2d, 0x2d6f, 0x2d70, 0xfb3e, 0xfb40, 0xfb41,
          777  +    0xfb43, 0xfb44, 0xfffc, 0xfffd
          778  +#if CHRBITS > 16
   774    779       ,0x1003c, 0x1003d, 0x101a0, 0x1056f, 0x10808, 0x10837, 0x10838, 0x1083c, 0x108f4,
   775    780       0x108f5, 0x1093f, 0x10a05, 0x10a06, 0x11288, 0x1130f, 0x11310, 0x11332, 0x11333,
   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
          781  +    0x11347, 0x11348, 0x11350, 0x11357, 0x1145b, 0x1145d, 0x1145e, 0x118ff, 0x11d08,
          782  +    0x11d09, 0x11d3a, 0x11d3c, 0x11d3d, 0x11d67, 0x11d68, 0x11d90, 0x11d91, 0x16a6e,
          783  +    0x16a6f, 0x16fe0, 0x16fe1, 0x1d49e, 0x1d49f, 0x1d4a2, 0x1d4a5, 0x1d4a6, 0x1d4bb,
          784  +    0x1d546, 0x1e023, 0x1e024, 0x1e95e, 0x1e95f, 0x1ee21, 0x1ee22, 0x1ee24, 0x1ee27,
          785  +    0x1ee39, 0x1ee3b, 0x1ee42, 0x1ee47, 0x1ee49, 0x1ee4b, 0x1ee51, 0x1ee52, 0x1ee54,
          786  +    0x1ee57, 0x1ee59, 0x1ee5b, 0x1ee5d, 0x1ee5f, 0x1ee61, 0x1ee62, 0x1ee64, 0x1ee7e,
          787  +    0x1eef0, 0x1eef1, 0x1f250, 0x1f251, 0x1f97a
   782    788   #endif
   783    789   };
   784    790   
   785    791   #define NUM_GRAPH_CHAR (sizeof(graphCharTable)/sizeof(chr))
   786    792   
   787    793   /*
   788    794    *	End of auto-generated Unicode character ranges declarations.

Changes to generic/regcustom.h.

    87     87   typedef int celt;		/* Type to hold chr, or NOCELT */
    88     88   #define	NOCELT (-1)		/* Celt value which is not valid chr */
    89     89   #define	CHR(c) (UCHAR(c))	/* Turn char literal into chr literal */
    90     90   #define	DIGITVAL(c) ((c)-'0')	/* Turn chr digit into its value */
    91     91   #if TCL_UTF_MAX > 4
    92     92   #define	CHRBITS	32		/* Bits in a chr; must not use sizeof */
    93     93   #define	CHR_MIN	0x00000000	/* Smallest and largest chr; the value */
    94         -#define	CHR_MAX	0xffffffff	/* CHR_MAX-CHR_MIN+1 should fit in uchr */
           94  +#define	CHR_MAX	0x10ffff	/* CHR_MAX-CHR_MIN+1 should fit in uchr */
    95     95   #else
    96     96   #define	CHRBITS	16		/* Bits in a chr; must not use sizeof */
    97     97   #define	CHR_MIN	0x0000		/* Smallest and largest chr; the value */
    98     98   #define	CHR_MAX	0xffff		/* CHR_MAX-CHR_MIN+1 should fit in uchr */
    99     99   #endif
   100    100   
   101    101   /*

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 {
................................................................................
   100    100   }
   101    101   declare 20 {
   102    102       void Tcl_DbIncrRefCount(Tcl_Obj *objPtr, const char *file, int line)
   103    103   }
   104    104   declare 21 {
   105    105       int Tcl_DbIsShared(Tcl_Obj *objPtr, const char *file, int line)
   106    106   }
   107         -declare 22 {
          107  +declare 22 {deprecated {No longer in use, changed to macro}} {
   108    108       Tcl_Obj *Tcl_DbNewBooleanObj(int boolValue, const char *file, int line)
   109    109   }
   110    110   declare 23 {
   111    111       Tcl_Obj *Tcl_DbNewByteArrayObj(const unsigned char *bytes, int length,
   112    112   	    const char *file, int line)
   113    113   }
   114    114   declare 24 {
................................................................................
   115    115       Tcl_Obj *Tcl_DbNewDoubleObj(double doubleValue, const char *file,
   116    116   	    int line)
   117    117   }
   118    118   declare 25 {
   119    119       Tcl_Obj *Tcl_DbNewListObj(int objc, Tcl_Obj *const *objv,
   120    120   	    const char *file, int line)
   121    121   }
   122         -declare 26 {
          122  +declare 26 {deprecated {No longer in use, changed to macro}} {
   123    123       Tcl_Obj *Tcl_DbNewLongObj(long longValue, const char *file, int line)
   124    124   }
   125    125   declare 27 {
   126    126       Tcl_Obj *Tcl_DbNewObj(const char *file, int line)
   127    127   }
   128    128   declare 28 {
   129    129       Tcl_Obj *Tcl_DbNewStringObj(const char *bytes, int length,
................................................................................
   148    148   declare 34 {
   149    149       int Tcl_GetDouble(Tcl_Interp *interp, const char *src, double *doublePtr)
   150    150   }
   151    151   declare 35 {
   152    152       int Tcl_GetDoubleFromObj(Tcl_Interp *interp, Tcl_Obj *objPtr,
   153    153   	    double *doublePtr)
   154    154   }
   155         -declare 36 {
          155  +declare 36 {deprecated {No longer in use, changed to macro}} {
   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   }
................................................................................
   194    194       int Tcl_ListObjLength(Tcl_Interp *interp, Tcl_Obj *listPtr,
   195    195   	    int *lengthPtr)
   196    196   }
   197    197   declare 48 {
   198    198       int Tcl_ListObjReplace(Tcl_Interp *interp, Tcl_Obj *listPtr, int first,
   199    199   	    int count, int objc, Tcl_Obj *const objv[])
   200    200   }
   201         -declare 49 {
          201  +declare 49 {deprecated {No longer in use, changed to macro}} {
   202    202       Tcl_Obj *Tcl_NewBooleanObj(int boolValue)
   203    203   }
   204    204   declare 50 {
   205    205       Tcl_Obj *Tcl_NewByteArrayObj(const unsigned char *bytes, int length)
   206    206   }
   207    207   declare 51 {
   208    208       Tcl_Obj *Tcl_NewDoubleObj(double doubleValue)
   209    209   }
   210         -declare 52 {
          210  +declare 52 {deprecated {No longer in use, changed to macro}} {
   211    211       Tcl_Obj *Tcl_NewIntObj(int intValue)
   212    212   }
   213    213   declare 53 {
   214    214       Tcl_Obj *Tcl_NewListObj(int objc, Tcl_Obj *const objv[])
   215    215   }
   216         -declare 54 {
          216  +declare 54 {deprecated {No longer in use, changed to macro}} {
   217    217       Tcl_Obj *Tcl_NewLongObj(long longValue)
   218    218   }
   219    219   declare 55 {
   220    220       Tcl_Obj *Tcl_NewObj(void)
   221    221   }
   222    222   declare 56 {
   223    223       Tcl_Obj *Tcl_NewStringObj(const char *bytes, int length)
   224    224   }
   225         -declare 57 {
          225  +declare 57 {deprecated {No longer in use, changed to macro}} {
   226    226       void Tcl_SetBooleanObj(Tcl_Obj *objPtr, int boolValue)
   227    227   }
   228    228   declare 58 {
   229    229       unsigned char *Tcl_SetByteArrayLength(Tcl_Obj *objPtr, int length)
   230    230   }
   231    231   declare 59 {
   232    232       void Tcl_SetByteArrayObj(Tcl_Obj *objPtr, const unsigned char *bytes,
   233    233   	    int length)
   234    234   }
   235    235   declare 60 {
   236    236       void Tcl_SetDoubleObj(Tcl_Obj *objPtr, double doubleValue)
   237    237   }
   238         -declare 61 {
          238  +declare 61 {deprecated {No longer in use, changed to macro}} {
   239    239       void Tcl_SetIntObj(Tcl_Obj *objPtr, int intValue)
   240    240   }
   241    241   declare 62 {
   242    242       void Tcl_SetListObj(Tcl_Obj *objPtr, int objc, Tcl_Obj *const objv[])
   243    243   }
   244         -declare 63 {
          244  +declare 63 {deprecated {No longer in use, changed to macro}} {
   245    245       void Tcl_SetLongObj(Tcl_Obj *objPtr, long longValue)
   246    246   }
   247    247   declare 64 {
   248    248       void Tcl_SetObjLength(Tcl_Obj *objPtr, int length)
   249    249   }
   250    250   declare 65 {
   251    251       void Tcl_SetStringObj(Tcl_Obj *objPtr, const char *bytes, int length)
   252    252   }
   253         -declare 66 {
          253  +declare 66 {deprecated {No longer in use, changed to macro}} {
   254    254       void Tcl_AddErrorInfo(Tcl_Interp *interp, const char *message)
   255    255   }
   256         -declare 67 {
          256  +declare 67 {deprecated {No longer in use, changed to macro}} {
   257    257       void Tcl_AddObjErrorInfo(Tcl_Interp *interp, const char *message,
   258    258   	    int length)
   259    259   }
   260    260   declare 68 {
   261    261       void Tcl_AllowExceptions(Tcl_Interp *interp)
   262    262   }
   263    263   declare 69 {
................................................................................
   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         -declare 131 {
          475  +declare 131 {deprecated {No longer in use, changed to macro}} {
   477    476       int Tcl_EvalObj(Tcl_Interp *interp, Tcl_Obj *objPtr)
   478    477   }
   479    478   declare 132 {
   480    479       void Tcl_EventuallyFree(ClientData clientData, Tcl_FreeProc *freeProc)
   481    480   }
   482    481   declare 133 {
   483    482       TCL_NORETURN void Tcl_Exit(int status)
................................................................................
   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         -declare 175 {
   629         -    CONST84_RETURN char *Tcl_GetVar(Tcl_Interp *interp, const char *varName,
          627  +declare 175 {deprecated {No longer in use, changed to macro}} {
          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         -declare 178 {
          638  +declare 178 {deprecated {No longer in use, changed to macro}} {
   640    639       int Tcl_GlobalEvalObj(Tcl_Interp *interp, Tcl_Obj *objPtr)
   641    640   }
   642    641   declare 179 {
   643    642       int Tcl_HideCommand(Tcl_Interp *interp, const char *cmdName,
   644    643   	    const char *hiddenCmdToken)
   645    644   }
   646    645   declare 180 {
................................................................................
   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)
................................................................................
   832    830   }
   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         -declare 237 {
   840         -    CONST84_RETURN char *Tcl_SetVar(Tcl_Interp *interp, const char *varName,
          837  +declare 237 {deprecated {No longer in use, changed to macro}} {
          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         -declare 247 {
          872  +declare 247 {deprecated {No longer in use, changed to macro}} {
   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 {
   880    877       int Tcl_TraceVar2(Tcl_Interp *interp, const char *part1, const char *part2,
   881    878   	    int flags, Tcl_VarTraceProc *proc, ClientData clientData)
   882    879   }
................................................................................
   889    886   }
   890    887   declare 251 {
   891    888       void Tcl_UnlinkVar(Tcl_Interp *interp, const char *varName)
   892    889   }
   893    890   declare 252 {
   894    891       int Tcl_UnregisterChannel(Tcl_Interp *interp, Tcl_Channel chan)
   895    892   }
   896         -declare 253 {
          893  +declare 253 {deprecated {No longer in use, changed to macro}} {
   897    894       int Tcl_UnsetVar(Tcl_Interp *interp, const char *varName, int flags)
   898    895   }
   899    896   declare 254 {
   900    897       int Tcl_UnsetVar2(Tcl_Interp *interp, const char *part1, const char *part2,
   901    898   	    int flags)
   902    899   }
   903         -declare 255 {
          900  +declare 255 {deprecated {No longer in use, changed to macro}} {
   904    901       void Tcl_UntraceVar(Tcl_Interp *interp, const char *varName, int flags,
   905    902   	    Tcl_VarTraceProc *proc, ClientData clientData)
   906    903   }
   907    904   declare 256 {
   908    905       void Tcl_UntraceVar2(Tcl_Interp *interp, const char *part1,
   909    906   	    const char *part2, int flags, Tcl_VarTraceProc *proc,
   910    907   	    ClientData clientData)
   911    908   }
   912    909   declare 257 {
   913    910       void Tcl_UpdateLinkedVar(Tcl_Interp *interp, const char *varName)
   914    911   }
   915         -declare 258 {
          912  +declare 258 {deprecated {No longer in use, changed to macro}} {
   916    913       int Tcl_UpVar(Tcl_Interp *interp, const char *frameName,
   917    914   	    const char *varName, const char *localName, int flags)
   918    915   }
   919    916   declare 259 {
   920    917       int Tcl_UpVar2(Tcl_Interp *interp, const char *frameName, const char *part1,
   921    918   	    const char *part2, const char *localName, int flags)
   922    919   }
   923    920   declare 260 {
   924    921       int Tcl_VarEval(Tcl_Interp *interp, ...)
   925    922   }
   926         -declare 261 {
          923  +declare 261 {deprecated {No longer in use, changed to macro}} {
   927    924       ClientData Tcl_VarTraceInfo(Tcl_Interp *interp, const char *varName,
   928    925   	    int flags, Tcl_VarTraceProc *procPtr, ClientData prevClientData)
   929    926   }
   930    927   declare 262 {
   931    928       ClientData Tcl_VarTraceInfo2(Tcl_Interp *interp, const char *part1,
   932    929   	    const char *part2, int flags, Tcl_VarTraceProc *procPtr,
   933    930   	    ClientData prevClientData)
................................................................................
   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         -declare 271 {
   962         -    CONST84_RETURN char *Tcl_PkgPresent(Tcl_Interp *interp, const char *name,
          958  +declare 271 {deprecated {No longer in use, changed to macro}} {
          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         -declare 273 {
          967  +declare 273 {deprecated {No longer in use, changed to macro}} {
   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         -declare 274 {
   976         -    CONST84_RETURN char *Tcl_PkgRequire(Tcl_Interp *interp, const char *name,
          972  +declare 274 {deprecated {No longer in use, changed to macro}} {
          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)
................................................................................
  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,
................................................................................
  1144   1141       void Tcl_ThreadAlert(Tcl_ThreadId threadId)
  1145   1142   }
  1146   1143   declare 319 {
  1147   1144       void Tcl_ThreadQueueEvent(Tcl_ThreadId threadId, Tcl_Event *evPtr,
  1148   1145   	    Tcl_QueuePosition position)
  1149   1146   }
  1150   1147   declare 320 {
  1151         -    Tcl_UniChar Tcl_UniCharAtIndex(const char *src, int index)
         1148  +    int Tcl_UniCharAtIndex(const char *src, int index)
  1152   1149   }
  1153   1150   declare 321 {
  1154         -    Tcl_UniChar Tcl_UniCharToLower(int ch)
         1151  +    int Tcl_UniCharToLower(int ch)
  1155   1152   }
  1156   1153   declare 322 {
  1157         -    Tcl_UniChar Tcl_UniCharToTitle(int ch)
         1154  +    int Tcl_UniCharToTitle(int ch)
  1158   1155   }
  1159   1156   declare 323 {
  1160         -    Tcl_UniChar Tcl_UniCharToUpper(int ch)
         1157  +    int 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
................................................................................
  1347   1344       void Tcl_SetUnicodeObj(Tcl_Obj *objPtr, const Tcl_UniChar *unicode,
  1348   1345   	    int numChars)
  1349   1346   }
  1350   1347   declare 380 {
  1351   1348       int Tcl_GetCharLength(Tcl_Obj *objPtr)
  1352   1349   }
  1353   1350   declare 381 {
  1354         -    Tcl_UniChar Tcl_GetUniChar(Tcl_Obj *objPtr, int index)
         1351  +    int Tcl_GetUniChar(Tcl_Obj *objPtr, int index)
  1355   1352   }
  1356         -declare 382 {
         1353  +declare 382 {deprecated {No longer in use, changed to macro}} {
  1357   1354       Tcl_UniChar *Tcl_GetUnicode(Tcl_Obj *objPtr)
  1358   1355   }
  1359   1356   declare 383 {
  1360   1357       Tcl_Obj *Tcl_GetRange(Tcl_Obj *objPtr, int first, int last)
  1361   1358   }
  1362   1359   declare 384 {
  1363   1360       void Tcl_AppendUnicodeToObj(Tcl_Obj *objPtr, const Tcl_UniChar *unicode,
................................................................................
  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   }
................................................................................
  2331   2328       Tcl_Channel Tcl_OpenTcpServerEx(Tcl_Interp *interp, const char *service,
  2332   2329   	    const char *host, unsigned int flags, Tcl_TcpAcceptProc *acceptProc,
  2333   2330   	    ClientData callbackData)
  2334   2331   }
  2335   2332   
  2336   2333   # ----- BASELINE -- FOR -- 8.7.0 ----- #
  2337   2334   
  2338         -
  2339         -
         2335  +# TIP #430
         2336  +declare 632 {
         2337  +    int TclZipfs_Mount(
         2338  +    Tcl_Interp *interp,
         2339  +    const char *mntpt,
         2340  +    const char *zipname,
         2341  +    const char *passwd)
         2342  +}
         2343  +declare 633 {
         2344  +    int TclZipfs_Unmount(Tcl_Interp *interp, const char *zipname)
         2345  +}
         2346  +declare 634 {
         2347  +    Tcl_Obj *TclZipfs_TclLibrary(void)
         2348  +}
         2349  +declare 635 {
         2350  +    int TclZipfs_Mount_Buffer(
         2351  +    Tcl_Interp *interp,
         2352  +    const char *mntpt,
         2353  +    unsigned char *data,
         2354  +    size_t datalen,
         2355  +    int copy)
         2356  +}
  2340   2357   ##############################################################################
  2341   2358   
  2342   2359   # Define the platform specific public Tcl interface. These functions are only
  2343   2360   # available on the designated platform.
  2344   2361   
  2345   2362   interface tclPlat
  2346   2363   
  2347   2364   ################################
  2348   2365   # Unix specific functions
  2349   2366   #   (none)
         2367  +declare 0 unix {
         2368  +    int TclZipfs_AppHook(int *argc, char ***argv)
         2369  +}
  2350   2370   
  2351   2371   ################################
  2352   2372   # Windows specific functions
  2353   2373   
  2354   2374   # Added in Tcl 8.1
  2355   2375   
  2356   2376   declare 0 win {
  2357   2377       TCHAR *Tcl_WinUtfToTChar(const char *str, int len, Tcl_DString *dsPtr)
  2358   2378   }
  2359   2379   declare 1 win {
  2360   2380       char *Tcl_WinTCharToUtf(const TCHAR *str, int len, Tcl_DString *dsPtr)
  2361   2381   }
  2362         -
         2382  +declare 2 win {
         2383  +    int TclZipfs_AppHook(int *argc, TCHAR ***argv)
         2384  +}
  2363   2385   ################################
  2364   2386   # Mac OS X specific functions
  2365   2387   
  2366   2388   declare 0 macosx {
  2367   2389       int Tcl_MacOSXOpenBundleResources(Tcl_Interp *interp,
  2368   2390   	    const char *bundleName, int hasResourceFile,
  2369   2391   	    int maxPathLen, char *libraryPath)
................................................................................
  2377   2399   ##############################################################################
  2378   2400   
  2379   2401   # Public functions that are not accessible via the stubs table.
  2380   2402   
  2381   2403   export {
  2382   2404       void Tcl_Main(int argc, char **argv, Tcl_AppInitProc *appInitProc)
  2383   2405   }
         2406  +export {
         2407  +    void Tcl_MainEx(int argc, char **argv, Tcl_AppInitProc *appInitProc,
         2408  +    Tcl_Interp *interp)
         2409  +}
  2384   2410   export {
  2385   2411       const char *Tcl_InitStubs(Tcl_Interp *interp, const char *version,
  2386   2412   	int exact)
  2387   2413   }
  2388   2414   export {
  2389   2415       const char *TclTomMathInitializeStubs(Tcl_Interp* interp,
  2390   2416   	const char* version, int epoch, int revision)

Changes to generic/tcl.h.

    48     48    * macosx/Tcl.xcode/default.pbxuser (not patchlevel) 1 LOC
    49     49    * macosx/Tcl-Common.xcconfig (not patchlevel) 1 LOC
    50     50    * win/README		(not patchlevel) (sections 0 and 2)
    51     51    * unix/tcl.spec	(1 LOC patch)
    52     52    * tools/tcl.hpj.in	(not patchlevel, for windows installer)
    53     53    */
    54     54   
    55         -#define TCL_MAJOR_VERSION   9
    56         -#define TCL_MINOR_VERSION   0
           55  +#define TCL_MAJOR_VERSION   8
           56  +#define TCL_MINOR_VERSION   7
    57     57   #define TCL_RELEASE_LEVEL   TCL_ALPHA_RELEASE
    58         -#define TCL_RELEASE_SERIAL  0
           58  +#define TCL_RELEASE_SERIAL  2
    59     59   
    60         -#define TCL_VERSION	    "9.0"
    61         -#define TCL_PATCH_LEVEL	    "9.0a0"
           60  +#define TCL_VERSION	    "8.7"
           61  +#define TCL_PATCH_LEVEL	    "8.7a2"
    62     62   
    63     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    */
................................................................................
    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  +
           93  +#ifndef TCL_THREADS
           94  +#   define TCL_THREADS 1
           95  +#endif
    92     96   #endif /* !TCL_NO_DEPRECATED */
    93     97   
    94     98   /*
    95     99    * A special definition used to allow this header file to be included from
    96    100    * windows resource files so that they can obtain version information.
    97    101    * RC_INVOKED is defined by default by the windows RC tool.
    98    102    *
................................................................................
    99    103    * Resource compilers don't like all the C stuff, like typedefs and function
   100    104    * declarations, that occur below, so block them out.
   101    105    */
   102    106   
   103    107   #ifndef RC_INVOKED
   104    108   
   105    109   /*
   106         - * Special macro to define mutexes, that doesn't do anything if we are not
   107         - * using threads.
          110  + * Special macro to define mutexes.
   108    111    */
   109    112   
   110         -#ifdef TCL_THREADS
   111    113   #define TCL_DECLARE_MUTEX(name) static Tcl_Mutex name;
   112         -#else
   113         -#define TCL_DECLARE_MUTEX(name)
   114         -#endif
   115    114   
   116    115   /*
   117    116    * Tcl's public routine Tcl_FSSeek() uses the values SEEK_SET, SEEK_CUR, and
   118    117    * SEEK_END, all #define'd by stdio.h .
   119    118    *
   120    119    * Also, many extensions need stdio.h, and they've grown accustomed to tcl.h
   121    120    * providing it for them rather than #include-ing it themselves as they
................................................................................
   133    132    * written for older versions of Tcl where the macros permitted
   134    133    * support for the varargs.h system as well as stdarg.h .
   135    134    *
   136    135    * New code should just directly be written to use stdarg.h conventions.
   137    136    */
   138    137   
   139    138   #include <stdarg.h>
   140         -#ifndef TCL_NO_DEPRECATED
          139  +#if !defined(TCL_NO_DEPRECATED) && TCL_MAJOR_VERSION < 9
   141    140   #    define TCL_VARARGS(type, name) (type name, ...)
   142    141   #    define TCL_VARARGS_DEF(type, name) (type name, ...)
   143    142   #    define TCL_VARARGS_START(type, name, list) (va_start(list, name), name)
   144    143   #endif /* !TCL_NO_DEPRECATED */
   145    144   #if defined(__GNUC__) && (__GNUC__ > 2)
   146    145   #   define TCL_FORMAT_PRINTF(a,b) __attribute__ ((__format__ (__printf__, a, b)))
   147    146   #   define TCL_NORETURN __attribute__ ((noreturn))
................................................................................
   250    249    * The following _ANSI_ARGS_ macro is to support old extensions
   251    250    * written for older versions of Tcl where it permitted support
   252    251    * for compilers written in the pre-prototype era of C.
   253    252    *
   254    253    * New code should use prototypes.
   255    254    */
   256    255   
   257         -#ifndef TCL_NO_DEPRECATED
          256  +#if !defined(TCL_NO_DEPRECATED) && TCL_MAJOR_VERSION < 9
   258    257   #   undef _ANSI_ARGS_
   259    258   #   define _ANSI_ARGS_(x)	x
   260         -#endif /* !TCL_NO_DEPRECATED */
   261    259   
   262    260   /*
   263    261    * Definitions that allow this header file to be used either with or without
   264    262    * ANSI C features.
   265    263    */
   266    264   
   267    265   #ifndef INLINE
   268    266   #   define INLINE
   269    267   #endif
   270         -
   271         -#ifdef NO_CONST
   272         -#   ifndef const
   273         -#      define const
   274         -#   endif
   275         -#endif
   276    268   #ifndef CONST
   277    269   #   define CONST const
   278    270   #endif
   279    271   
   280         -#ifdef USE_NON_CONST
   281         -#   ifdef USE_COMPAT_CONST
   282         -#      error define at most one of USE_NON_CONST and USE_COMPAT_CONST
   283         -#   endif
   284         -#   define CONST84
   285         -#   define CONST84_RETURN
   286         -#else
   287         -#   ifdef USE_COMPAT_CONST
   288         -#      define CONST84
   289         -#      define CONST84_RETURN const
   290         -#   else
   291         -#      define CONST84 const
   292         -#      define CONST84_RETURN const
   293         -#   endif
   294         -#endif
          272  +#endif /* !TCL_NO_DEPRECATED */
   295    273   
   296    274   #ifndef CONST86
   297         -#      define CONST86 CONST84
          275  +#      define CONST86 const
   298    276   #endif
   299    277   
   300    278   /*
   301    279    * Make sure EXTERN isn't defined elsewhere.
   302    280    */
   303    281   
   304    282   #ifdef EXTERN
................................................................................
   314    292   /*
   315    293    *----------------------------------------------------------------------------
   316    294    * The following code is copied from winnt.h. If we don't replicate it here,
   317    295    * then <windows.h> can't be included after tcl.h, since tcl.h also defines
   318    296    * VOID. This block is skipped under Cygwin and Mingw.
   319    297    */
   320    298   
          299  +#if !defined(TCL_NO_DEPRECATED) && TCL_MAJOR_VERSION < 9
   321    300   #if defined(_WIN32) && !defined(HAVE_WINNT_IGNORE_VOID)
   322    301   #ifndef VOID
   323    302   #define VOID void
   324    303   typedef char CHAR;
   325    304   typedef short SHORT;
   326    305   typedef long LONG;
   327    306   #endif
................................................................................
   329    308   
   330    309   /*
   331    310    * Macro to use instead of "void" for arguments that must have type "void *"
   332    311    * in ANSI C; maps them to type "char *" in non-ANSI systems.
   333    312    */
   334    313   
   335    314   #ifndef __VXWORKS__
   336         -#   ifndef NO_VOID
   337         -#	define VOID void
   338         -#   else
   339         -#	define VOID char
   340         -#   endif
          315  +#   define VOID void
   341    316   #endif
          317  +#endif /* !defined(TCL_NO_DEPRECATED) && TCL_MAJOR_VERSION < 9 */
   342    318   
   343    319   /*
   344    320    * Miscellaneous declarations.
   345    321    */
   346    322   
   347    323   #ifndef _CLIENTDATA
   348         -#   ifndef NO_VOID
   349         -	typedef void *ClientData;
   350         -#   else
   351         -	typedef int *ClientData;
   352         -#   endif
          324  +    typedef void *ClientData;
   353    325   #   define _CLIENTDATA
   354    326   #endif
   355    327   
   356    328   /*
   357    329    * Darwin specific configure overrides (to support fat compiles, where
   358    330    * configure runs only once for multiple architectures):
   359    331    */
................................................................................
   392    364    * sprintf(...,"%" TCL_LL_MODIFIER "d",...).
   393    365    */
   394    366   
   395    367   #if !defined(TCL_WIDE_INT_TYPE)&&!defined(TCL_WIDE_INT_IS_LONG)
   396    368   #   if defined(_WIN32)
   397    369   #      define TCL_WIDE_INT_TYPE __int64
   398    370   #      define TCL_LL_MODIFIER	"I64"
          371  +#      if defined(_WIN64)
          372  +#         define TCL_Z_MODIFIER	"I"
          373  +#      endif
   399    374   #   elif defined(__GNUC__)
   400         -#      define TCL_WIDE_INT_TYPE long long
   401         -#      define TCL_LL_MODIFIER	"ll"
          375  +#      define TCL_Z_MODIFIER	"z"
   402    376   #   else /* ! _WIN32 && ! __GNUC__ */
   403    377   /*
   404    378    * Don't know what platform it is and configure hasn't discovered what is
   405    379    * going on for us. Try to guess...
   406    380    */
   407    381   #      include <limits.h>
   408         -#      if (INT_MAX < LONG_MAX)
          382  +#      if defined(LLONG_MAX) && (LLONG_MAX == LONG_MAX)
   409    383   #         define TCL_WIDE_INT_IS_LONG	1
   410         -#      else
   411         -#         define TCL_WIDE_INT_TYPE long long
   412    384   #      endif
   413    385   #   endif /* _WIN32 */
   414    386   #endif /* !TCL_WIDE_INT_TYPE & !TCL_WIDE_INT_IS_LONG */
   415         -#ifdef TCL_WIDE_INT_IS_LONG
   416         -#   undef TCL_WIDE_INT_TYPE
   417         -#   define TCL_WIDE_INT_TYPE	long
   418         -#endif /* TCL_WIDE_INT_IS_LONG */
          387  +
          388  +#ifndef TCL_WIDE_INT_TYPE
          389  +#   define TCL_WIDE_INT_TYPE		long long
          390  +#endif /* !TCL_WIDE_INT_TYPE */
   419    391   
   420    392   typedef TCL_WIDE_INT_TYPE		Tcl_WideInt;
   421    393   typedef unsigned TCL_WIDE_INT_TYPE	Tcl_WideUInt;
   422    394   
   423         -#ifdef TCL_WIDE_INT_IS_LONG
   424         -#   ifndef TCL_LL_MODIFIER
   425         -#      define TCL_LL_MODIFIER		"l"
   426         -#   endif /* !TCL_LL_MODIFIER */
   427         -#else /* TCL_WIDE_INT_IS_LONG */
   428         -/*
   429         - * The next short section of defines are only done when not running on Windows
   430         - * or some other strange platform.
   431         - */
   432         -#   ifndef TCL_LL_MODIFIER
   433         -#      define TCL_LL_MODIFIER		"ll"
   434         -#   endif /* !TCL_LL_MODIFIER */
   435         -#endif /* TCL_WIDE_INT_IS_LONG */
   436         -
          395  +#ifndef TCL_LL_MODIFIER
          396  +#   define TCL_LL_MODIFIER	"ll"
          397  +#endif /* !TCL_LL_MODIFIER */
          398  +#ifndef TCL_Z_MODIFIER
          399  +#   if defined(__GNUC__) && !defined(_WIN32)
          400  +#	define TCL_Z_MODIFIER	"z"
          401  +#   else
          402  +#	define TCL_Z_MODIFIER	""
          403  +#   endif
          404  +#endif /* !TCL_Z_MODIFIER */
   437    405   #define Tcl_WideAsLong(val)	((long)((Tcl_WideInt)(val)))
   438    406   #define Tcl_LongAsWide(val)	((Tcl_WideInt)((long)(val)))
   439    407   #define Tcl_WideAsDouble(val)	((double)((Tcl_WideInt)(val)))
   440    408   #define Tcl_DoubleAsWide(val)	((Tcl_WideInt)((double)(val)))
   441    409   
   442    410   #if defined(_WIN32)
   443    411   #   ifdef __BORLANDC__
................................................................................
   488    456    * "real" definition in tclInt.h.
   489    457    *
   490    458    * Note: Tcl_ObjCmdProc functions do not directly set result and freeProc.
   491    459    * Instead, they set a Tcl_Obj member in the "real" structure that can be
   492    460    * accessed with Tcl_GetObjResult() and Tcl_SetObjResult().
   493    461    */
   494    462   
   495         -typedef struct Tcl_Interp Tcl_Interp;
          463  +typedef struct Tcl_Interp
          464  +#if !defined(TCL_NO_DEPRECATED) && TCL_MAJOR_VERSION < 9
          465  +{
          466  +    /* TIP #330: Strongly discourage extensions from using the string
          467  +     * result. */
          468  +    char *resultDontUse; /* Don't use in extensions! */
          469  +    void (*freeProcDontUse) (char *); /* Don't use in extensions! */
          470  +    int errorLineDontUse; /* Don't use in extensions! */
          471  +}
          472  +#endif /* !TCL_NO_DEPRECATED */
          473  +Tcl_Interp;
   496    474   
   497    475   typedef struct Tcl_AsyncHandler_ *Tcl_AsyncHandler;
   498    476   typedef struct Tcl_Channel_ *Tcl_Channel;
   499    477   typedef struct Tcl_ChannelTypeVersion_ *Tcl_ChannelTypeVersion;
   500    478   typedef struct Tcl_Command_ *Tcl_Command;
   501    479   typedef struct Tcl_Condition_ *Tcl_Condition;
   502    480   typedef struct Tcl_Dict_ *Tcl_Dict;
................................................................................
   637    615   
   638    616   #define TCL_OK			0
   639    617   #define TCL_ERROR		1
   640    618   #define TCL_RETURN		2
   641    619   #define TCL_BREAK		3
   642    620   #define TCL_CONTINUE		4
   643    621   
          622  +#if !defined(TCL_NO_DEPRECATED) && TCL_MAJOR_VERSION < 9
          623  +#define TCL_RESULT_SIZE		200
          624  +#endif
          625  +
   644    626   /*
   645    627    *----------------------------------------------------------------------------
   646    628    * Flags to control what substitutions are performed by Tcl_SubstObj():
   647    629    */
   648    630   
   649    631   #define TCL_SUBST_COMMANDS	001
   650    632   #define TCL_SUBST_VARIABLES	002
................................................................................
   651    633   #define TCL_SUBST_BACKSLASHES	004
   652    634   #define TCL_SUBST_ALL		007
   653    635   
   654    636   /*
   655    637    * Argument descriptors for math function callbacks in expressions:
   656    638    */
   657    639   
          640  +#if !defined(TCL_NO_DEPRECATED) && TCL_MAJOR_VERSION < 9
   658    641   typedef enum {
   659    642       TCL_INT, TCL_DOUBLE, TCL_EITHER, TCL_WIDE_INT
   660    643   } Tcl_ValueType;
   661    644   
   662    645   typedef struct Tcl_Value {
   663    646       Tcl_ValueType type;		/* Indicates intValue or doubleValue is valid,
   664    647   				 * or both. */
   665    648       long intValue;		/* Integer value. */
   666    649       double doubleValue;		/* Double-precision floating value. */
   667    650       Tcl_WideInt wideValue;	/* Wide (min. 64-bit) integer value. */
   668    651   } Tcl_Value;
          652  +#else
          653  +#define Tcl_ValueType void /* Just enough to prevent compilation error in Tcl */
          654  +#define Tcl_Value void /* Just enough to prevent compilation error in Tcl */
          655  +#endif
   669    656   
   670    657   /*
   671    658    * Forward declaration of Tcl_Obj to prevent an error when the forward
   672    659    * reference to Tcl_Obj is encountered in the function types declared below.
   673    660    */
   674    661   
   675    662   struct Tcl_Obj;
................................................................................
   682    669   typedef int (Tcl_AppInitProc) (Tcl_Interp *interp);
   683    670   typedef int (Tcl_AsyncProc) (ClientData clientData, Tcl_Interp *interp,
   684    671   	int code);
   685    672   typedef void (Tcl_ChannelProc) (ClientData clientData, int mask);
   686    673   typedef void (Tcl_CloseProc) (ClientData data);
   687    674   typedef void (Tcl_CmdDeleteProc) (ClientData clientData);
   688    675   typedef int (Tcl_CmdProc) (ClientData clientData, Tcl_Interp *interp,
   689         -	int argc, CONST84 char *argv[]);
          676  +	int argc, const char *argv[]);
   690    677   typedef void (Tcl_CmdTraceProc) (ClientData clientData, Tcl_Interp *interp,
   691    678   	int level, char *command, Tcl_CmdProc *proc,
   692         -	ClientData cmdClientData, int argc, CONST84 char *argv[]);
          679  +	ClientData cmdClientData, int argc, const char *argv[]);
   693    680   typedef int (Tcl_CmdObjTraceProc) (ClientData clientData, Tcl_Interp *interp,
   694    681   	int level, const char *command, Tcl_Command commandInfo, int objc,
   695    682   	struct Tcl_Obj *const *objv);
   696    683   typedef void (Tcl_CmdObjTraceDeleteProc) (ClientData clientData);
   697    684   typedef void (Tcl_DupInternalRepProc) (struct Tcl_Obj *srcPtr,
   698    685   	struct Tcl_Obj *dupPtr);
   699    686   typedef int (Tcl_EncodingConvertProc) (ClientData clientData, const char *src,
................................................................................
   722    709   typedef void (Tcl_PanicProc) (const char *format, ...);
   723    710   typedef void (Tcl_TcpAcceptProc) (ClientData callbackData, Tcl_Channel chan,
   724    711   	char *address, int port);
   725    712   typedef void (Tcl_TimerProc) (ClientData clientData);
   726    713   typedef int (Tcl_SetFromAnyProc) (Tcl_Interp *interp, struct Tcl_Obj *objPtr);
   727    714   typedef void (Tcl_UpdateStringProc) (struct Tcl_Obj *objPtr);
   728    715   typedef char * (Tcl_VarTraceProc) (ClientData clientData, Tcl_Interp *interp,
   729         -	CONST84 char *part1, CONST84 char *part2, int flags);
          716  +	const char *part1, const char *part2, int flags);
   730    717   typedef void (Tcl_CommandTraceProc) (ClientData clientData, Tcl_Interp *interp,
   731    718   	const char *oldName, const char *newName, int flags);
   732    719   typedef void (Tcl_CreateFileHandlerProc) (int fd, int mask, Tcl_FileProc *proc,
   733    720   	ClientData clientData);
   734    721   typedef void (Tcl_DeleteFileHandlerProc) (int fd);
   735    722   typedef void (Tcl_AlertNotifierProc) (ClientData clientData);
   736    723   typedef void (Tcl_ServiceModeHookProc) (int mode);
................................................................................
   821    808   
   822    809   void		Tcl_IncrRefCount(Tcl_Obj *objPtr);
   823    810   void		Tcl_DecrRefCount(Tcl_Obj *objPtr);
   824    811   int		Tcl_IsShared(Tcl_Obj *objPtr);
   825    812   
   826    813   /*
   827    814    *----------------------------------------------------------------------------
   828         - * The following type contains the state needed by Tcl_SaveResult. It
   829         - * is typically allocated on the stack.
          815  + * The following structure contains the state needed by Tcl_SaveResult. No-one
          816  + * outside of Tcl should access any of these fields. This structure is
          817  + * typically allocated on the stack.
   830    818    */
   831    819   
   832         -typedef Tcl_Obj *Tcl_SavedResult;
          820  +typedef struct Tcl_SavedResult {
          821  +    char *result;
          822  +    Tcl_FreeProc *freeProc;
          823  +    Tcl_Obj *objResultPtr;
          824  +    char *appendResult;
          825  +    int appendAvl;
          826  +    int appendUsed;
          827  +    char resultSpace[200+1];
          828  +} Tcl_SavedResult;
   833    829   
   834    830   /*
   835    831    *----------------------------------------------------------------------------
   836    832    * The following definitions support Tcl's namespace facility. Note: the first
   837    833    * five fields must match exactly the fields in a Namespace structure (see
   838    834    * tclInt.h).
   839    835    */
................................................................................
   950    946       char staticSpace[TCL_DSTRING_STATIC_SIZE];
   951    947   				/* Space to use in common case where string is
   952    948   				 * small. */
   953    949   } Tcl_DString;
   954    950   
   955    951   #define Tcl_DStringLength(dsPtr) ((dsPtr)->length)
   956    952   #define Tcl_DStringValue(dsPtr) ((dsPtr)->string)
   957         -#ifndef TCL_NO_DEPRECATED
          953  +#if !defined(TCL_NO_DEPRECATED) && TCL_MAJOR_VERSION < 9
   958    954   #   define Tcl_DStringTrunc Tcl_DStringSetLength
   959    955   #endif /* !TCL_NO_DEPRECATED */
   960    956   
   961    957   /*
   962    958    * Definitions for the maximum number of digits of precision that may be
   963    959    * specified in the "tcl_precision" variable, and the number of bytes of
   964    960    * buffer space required by Tcl_PrintDouble.
................................................................................
  1078   1074   /*
  1079   1075    * The TCL_PARSE_PART1 flag is deprecated and has no effect. The part1 is now
  1080   1076    * always parsed whenever the part2 is NULL. (This is to avoid a common error
  1081   1077    * when converting code to use the new object based APIs and forgetting to
  1082   1078    * give the flag)
  1083   1079    */
  1084   1080   
  1085         -#ifndef TCL_NO_DEPRECATED
         1081  +#if !defined(TCL_NO_DEPRECATED) && TCL_MAJOR_VERSION < 9
  1086   1082   #   define TCL_PARSE_PART1	0x400
  1087   1083   #endif /* !TCL_NO_DEPRECATED */
  1088   1084   
  1089   1085   /*
  1090   1086    * Types for linked variables:
  1091   1087    */
  1092   1088   
................................................................................
  1431   1427   typedef int	(Tcl_DriverCloseProc) (ClientData instanceData,
  1432   1428   			Tcl_Interp *interp);
  1433   1429   typedef int	(Tcl_DriverClose2Proc) (ClientData instanceData,
  1434   1430   			Tcl_Interp *interp, int flags);
  1435   1431   typedef int	(Tcl_DriverInputProc) (ClientData instanceData, char *buf,
  1436   1432   			int toRead, int *errorCodePtr);
  1437   1433   typedef int	(Tcl_DriverOutputProc) (ClientData instanceData,
  1438         -			CONST84 char *buf, int toWrite, int *errorCodePtr);
         1434  +			const char *buf, int toWrite, int *errorCodePtr);
  1439   1435   typedef int	(Tcl_DriverSeekProc) (ClientData instanceData, long offset,
  1440   1436   			int mode, int *errorCodePtr);
  1441   1437   typedef int	(Tcl_DriverSetOptionProc) (ClientData instanceData,
  1442   1438   			Tcl_Interp *interp, const char *optionName,
  1443   1439   			const char *value);
  1444   1440   typedef int	(Tcl_DriverGetOptionProc) (ClientData instanceData,
  1445         -			Tcl_Interp *interp, CONST84 char *optionName,
         1441  +			Tcl_Interp *interp, const char *optionName,
  1446   1442   			Tcl_DString *dsPtr);
  1447   1443   typedef void	(Tcl_DriverWatchProc) (ClientData instanceData, int mask);
  1448   1444   typedef int	(Tcl_DriverGetHandleProc) (ClientData instanceData,
  1449   1445   			int direction, ClientData *handlePtr);
  1450   1446   typedef int	(Tcl_DriverFlushProc) (ClientData instanceData);
  1451   1447   typedef int	(Tcl_DriverHandlerProc) (ClientData instanceData,
  1452   1448   			int interestMask);
................................................................................
  1931   1927    *				is described by a TCL_TOKEN_SUB_EXPR token
  1932   1928    *				followed by the TCL_TOKEN_OPERATOR token for
  1933   1929    *				the operator, then TCL_TOKEN_SUB_EXPR tokens
  1934   1930    *				for the left then the right operands.
  1935   1931    * TCL_TOKEN_OPERATOR -		The token describes one expression operator.
  1936   1932    *				An operator might be the name of a math
  1937   1933    *				function such as "abs". A TCL_TOKEN_OPERATOR
  1938         - *				token is always preceeded by one
         1934  + *				token is always preceded by one
  1939   1935    *				TCL_TOKEN_SUB_EXPR token for the operator's
  1940   1936    *				subexpression, and is followed by zero or more
  1941   1937    *				TCL_TOKEN_SUB_EXPR tokens for the operator's
  1942   1938    *				operands. NumComponents is always 0.
  1943   1939    * TCL_TOKEN_EXPAND_WORD -	This token is just like TCL_TOKEN_WORD except
  1944   1940    *				that it marks a word that began with the
  1945   1941    *				literal character prefix "{*}". This word is
................................................................................
  2145   2141   #define TCL_CONVERT_MULTIBYTE	(-1)
  2146   2142   #define TCL_CONVERT_SYNTAX	(-2)
  2147   2143   #define TCL_CONVERT_UNKNOWN	(-3)
  2148   2144   #define TCL_CONVERT_NOSPACE	(-4)
  2149   2145   
  2150   2146   /*
  2151   2147    * The maximum number of bytes that are necessary to represent a single
  2152         - * Unicode character in UTF-8. The valid values should be 3, 4 or 6
  2153         - * (or perhaps 1 if we want to support a non-unicode enabled core). If 3 or
  2154         - * 4, then Tcl_UniChar must be 2-bytes in size (UCS-2) (the default). If 6,
         2148  + * Unicode character in UTF-8. The valid values are 4 and 6
         2149  + * (or perhaps 1 if we want to support a non-unicode enabled core). If 4,
         2150  + * then Tcl_UniChar must be 2-bytes in size (UCS-2) (the default). If 6,
  2155   2151    * then Tcl_UniChar must be 4-bytes in size (UCS-4). At this time UCS-2 mode
  2156   2152    * is the default and recommended mode. UCS-4 is experimental and not
  2157   2153    * recommended. It works for the core, but most extensions expect UCS-2.
  2158   2154    */
  2159   2155   
  2160   2156   #ifndef TCL_UTF_MAX
  2161         -#define TCL_UTF_MAX		3
         2157  +#define TCL_UTF_MAX		4
  2162   2158   #endif
  2163   2159   
  2164   2160   /*
  2165   2161    * This represents a Unicode character. Any changes to this should also be
  2166   2162    * reflected in regcustom.h.
  2167   2163    */
  2168   2164   
................................................................................
  2344   2340   
  2345   2341   typedef int (Tcl_NRPostProc) (ClientData data[], Tcl_Interp *interp,
  2346   2342   				int result);
  2347   2343   
  2348   2344   /*
  2349   2345    *----------------------------------------------------------------------------
  2350   2346    * The following constant is used to test for older versions of Tcl in the
  2351         - * stubs tables.
         2347  + * stubs tables. If TCL_UTF_MAX>4 use a different value.
  2352   2348    */
  2353   2349   
  2354         -#define TCL_STUB_MAGIC		((int) 0xFCA3BACF)
         2350  +#define TCL_STUB_MAGIC		((int) 0xFCA3BACF + (TCL_UTF_MAX>4))
  2355   2351   
  2356   2352   /*
  2357   2353    * The following function is required to be defined in all stubs aware
  2358   2354    * extensions. The function is actually implemented in the stub library, not
  2359   2355    * the main Tcl library, although there is a trivial implementation in the
  2360   2356    * main library in case an extension is statically linked into an application.
  2361   2357    */
  2362   2358   
  2363   2359   const char *		Tcl_InitStubs(Tcl_Interp *interp, const char *version,
  2364   2360   			    int exact, int magic);
  2365   2361   const char *		TclTomMathInitializeStubs(Tcl_Interp *interp,
  2366   2362   			    const char *version, int epoch, int revision);
         2363  +#if defined(_WIN32)
         2364  +    TCL_NORETURN void Tcl_ConsolePanic(const char *format, ...);
         2365  +#else
         2366  +#   define Tcl_ConsolePanic ((Tcl_PanicProc *)0)
         2367  +#endif
  2367   2368   
  2368   2369   #ifdef USE_TCL_STUBS
  2369   2370   #if TCL_RELEASE_LEVEL == TCL_FINAL_RELEASE
  2370   2371   #   define Tcl_InitStubs(interp, version, exact) \
  2371   2372   	(Tcl_InitStubs)(interp, version, \
  2372   2373   	    (exact)|(TCL_MAJOR_VERSION<<8)|(TCL_MINOR_VERSION<<16), \
  2373   2374   	    TCL_STUB_MAGIC)
................................................................................
  2391   2392   
  2392   2393   /*
  2393   2394    * Public functions that are not accessible via the stubs table.
  2394   2395    * Tcl_GetMemoryInfo is needed for AOLserver. [Bug 1868171]
  2395   2396    */
  2396   2397   
  2397   2398   #define Tcl_Main(argc, argv, proc) Tcl_MainEx(argc, argv, proc, \
  2398         -	    ((Tcl_CreateInterp)()))
         2399  +	    (((Tcl_SetPanicProc)(Tcl_ConsolePanic), Tcl_CreateInterp)()))
  2399   2400   EXTERN void		Tcl_MainEx(int argc, char **argv,
  2400   2401   			    Tcl_AppInitProc *appInitProc, Tcl_Interp *interp);
  2401   2402   EXTERN const char *	Tcl_PkgInitStubsCheck(Tcl_Interp *interp,
  2402   2403   			    const char *version, int exact);
  2403   2404   EXTERN void		Tcl_GetMemoryInfo(Tcl_DString *dsPtr);
  2404   2405   
  2405   2406   /*
................................................................................
  2510   2511        Tcl_DbNewLongObj((val)!=0, __FILE__, __LINE__)
  2511   2512   #  undef  Tcl_NewByteArrayObj
  2512   2513   #  define Tcl_NewByteArrayObj(bytes, len) \
  2513   2514        Tcl_DbNewByteArrayObj(bytes, len, __FILE__, __LINE__)
  2514   2515   #  undef  Tcl_NewDoubleObj
  2515   2516   #  define Tcl_NewDoubleObj(val) \
  2516   2517        Tcl_DbNewDoubleObj(val, __FILE__, __LINE__)
  2517         -#  undef  Tcl_NewIntObj
  2518         -#  define Tcl_NewIntObj(val) \
  2519         -     Tcl_DbNewLongObj(val, __FILE__, __LINE__)
  2520   2518   #  undef  Tcl_NewListObj
  2521   2519   #  define Tcl_NewListObj(objc, objv) \
  2522   2520        Tcl_DbNewListObj(objc, objv, __FILE__, __LINE__)
  2523         -#  undef  Tcl_NewLongObj
  2524         -#  define Tcl_NewLongObj(val) \
  2525         -     Tcl_DbNewLongObj(val, __FILE__, __LINE__)
  2526   2521   #  undef  Tcl_NewObj
  2527   2522   #  define Tcl_NewObj() \
  2528   2523        Tcl_DbNewObj(__FILE__, __LINE__)
  2529   2524   #  undef  Tcl_NewStringObj
  2530   2525   #  define Tcl_NewStringObj(bytes, len) \
  2531   2526        Tcl_DbNewStringObj(bytes, len, __FILE__, __LINE__)
  2532   2527   #  undef  Tcl_NewWideIntObj
................................................................................
  2555   2550   #undef  Tcl_FindHashEntry
  2556   2551   #define Tcl_FindHashEntry(tablePtr, key) \
  2557   2552   	(*((tablePtr)->findProc))(tablePtr, (const char *)(key))
  2558   2553   #undef  Tcl_CreateHashEntry
  2559   2554   #define Tcl_CreateHashEntry(tablePtr, key, newPtr) \
  2560   2555   	(*((tablePtr)->createProc))(tablePtr, (const char *)(key), newPtr)
  2561   2556   
  2562         -/*
  2563         - *----------------------------------------------------------------------------
  2564         - * Macros that eliminate the overhead of the thread synchronization functions
  2565         - * when compiling without thread support.
  2566         - */
  2567         -
  2568         -#ifndef TCL_THREADS
  2569         -#undef  Tcl_MutexLock
  2570         -#define Tcl_MutexLock(mutexPtr)
  2571         -#undef  Tcl_MutexUnlock
  2572         -#define Tcl_MutexUnlock(mutexPtr)
  2573         -#undef  Tcl_MutexFinalize
  2574         -#define Tcl_MutexFinalize(mutexPtr)
  2575         -#undef  Tcl_ConditionNotify
  2576         -#define Tcl_ConditionNotify(condPtr)
  2577         -#undef  Tcl_ConditionWait
  2578         -#define Tcl_ConditionWait(condPtr, mutexPtr, timePtr)
  2579         -#undef  Tcl_ConditionFinalize
  2580         -#define Tcl_ConditionFinalize(condPtr)
  2581         -#endif /* TCL_THREADS */
  2582         -
  2583   2557   /*
  2584   2558    *----------------------------------------------------------------------------
  2585   2559    * Deprecated Tcl functions:
  2586   2560    */
  2587   2561   
  2588         -#ifndef TCL_NO_DEPRECATED
         2562  +#if !defined(TCL_NO_DEPRECATED) && TCL_MAJOR_VERSION < 9
  2589   2563   /*
  2590   2564    * These function have been renamed. The old names are deprecated, but we
  2591         - * define these macros for backwards compatibilty.
         2565  + * define these macros for backwards compatibility.
  2592   2566    */
  2593   2567   
  2594   2568   #   define Tcl_Ckalloc		Tcl_Alloc
  2595   2569   #   define Tcl_Ckfree		Tcl_Free
  2596   2570   #   define Tcl_Ckrealloc	Tcl_Realloc
  2597   2571   #   define Tcl_Return		Tcl_SetResult
  2598   2572   #   define Tcl_TildeSubst	Tcl_TranslateFileName

Changes to generic/tclAlloc.c.

    18     18   
    19     19   /*
    20     20    * Windows and Unix use an alternative allocator when building with threads
    21     21    * that has significantly reduced lock contention.
    22     22    */
    23     23   
    24     24   #include "tclInt.h"
    25         -#if !defined(TCL_THREADS) || !defined(USE_THREAD_ALLOC)
           25  +#if !TCL_THREADS || !defined(USE_THREAD_ALLOC)
    26     26   
    27     27   #if USE_TCLALLOC
    28     28   
    29     29   /*
    30     30    * We should really make use of AC_CHECK_TYPE(caddr_t) here, but it can wait
    31     31    * until Tcl uses config.h properly.
    32     32    */
................................................................................
   117    117   /*
   118    118    * The allocator is protected by a special mutex that must be explicitly
   119    119    * initialized. Futhermore, because Tcl_Alloc may be used before anything else
   120    120    * in Tcl, we make this module self-initializing after all with the allocInit
   121    121    * variable.
   122    122    */
   123    123   
   124         -#ifdef TCL_THREADS
          124  +#if TCL_THREADS
   125    125   static Tcl_Mutex *allocMutexPtr;
   126    126   #endif
   127    127   static int allocInit = 0;
   128    128   
   129    129   #ifdef MSTATS
   130    130   
   131    131   /*
................................................................................
   167    167    */
   168    168   
   169    169   void
   170    170   TclInitAlloc(void)
   171    171   {
   172    172       if (!allocInit) {
   173    173   	allocInit = 1;
   174         -#ifdef TCL_THREADS
          174  +#if TCL_THREADS
   175    175   	allocMutexPtr = Tcl_GetAllocMutex();
   176    176   #endif
   177    177       }
   178    178   }
   179    179   
   180    180   /*
   181    181    *-------------------------------------------------------------------------
................................................................................
   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.

  2242   2242       CompileEnv* envPtr = assemEnvPtr->envPtr;
  2243   2243   				/* Compilation environment */
  2244   2244       Tcl_Interp* interp = (Tcl_Interp*) envPtr->iPtr;
  2245   2245   				/* Tcl interpreter */
  2246   2246       Tcl_Token* tokenPtr = *tokenPtrPtr;
  2247   2247   				/* INOUT: Pointer to the next token in the
  2248   2248   				 * source code */
  2249         -    Tcl_Obj* intObj;		/* Integer from the source code */
  2250         -    int status;			/* Tcl status return */
         2249  +    Tcl_Obj *value;
         2250  +    int status;
  2251   2251   
  2252         -    /*
  2253         -     * Extract the next token as a string.
  2254         -     */
  2255         -
  2256         -    if (GetNextOperand(assemEnvPtr, tokenPtrPtr, &intObj) != TCL_OK) {
         2252  +    /* General operand validity check */
         2253  +    if (GetNextOperand(assemEnvPtr, tokenPtrPtr, &value) != TCL_OK) {
  2257   2254   	return TCL_ERROR;
  2258   2255       }
  2259   2256   
         2257  +    /* Convert to an integer, advance to the next token and return. */
  2260   2258       /*
  2261         -     * Convert to an integer, advance to the next token and return.
         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   2262        */
         2263  +    status = TclIndexEncode(interp, value,
         2264  +	    TCL_INDEX_BEFORE,TCL_INDEX_BEFORE, result);
  2263   2265   
  2264         -    status = TclGetIntForIndex(interp, intObj, -2, result);
  2265         -    Tcl_DecrRefCount(intObj);
         2266  +    Tcl_DecrRefCount(value);
  2266   2267       *tokenPtrPtr = TokenAfter(tokenPtr);
  2267   2268       return status;
  2268   2269   }
  2269   2270   
  2270   2271   /*
  2271   2272    *-----------------------------------------------------------------------------
  2272   2273    *
................................................................................
  4262   4263   
  4263   4264       Tcl_AddErrorInfo(interp, "\n    in assembly code between lines ");
  4264   4265       lineNo = Tcl_NewIntObj(bbPtr->startLine);
  4265   4266       Tcl_IncrRefCount(lineNo);
  4266   4267       Tcl_AppendObjToErrorInfo(interp, lineNo);
  4267   4268       Tcl_AddErrorInfo(interp, " and ");
  4268   4269       if (bbPtr->successor1 != NULL) {
  4269         -	TclSetLongObj(lineNo, bbPtr->successor1->startLine);
         4270  +	TclSetIntObj(lineNo, bbPtr->successor1->startLine);
  4270   4271   	Tcl_AppendObjToErrorInfo(interp, lineNo);
  4271   4272       } else {
  4272   4273   	Tcl_AddErrorInfo(interp, "end of assembly code");
  4273   4274       }
  4274   4275       Tcl_DecrRefCount(lineNo);
  4275   4276   }
  4276   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},
................................................................................
   317    321       { "floor",	ExprFloorFunc,	NULL			},
   318    322       { "fmod",	ExprBinaryFunc,	(ClientData) fmod	},
   319    323       { "hypot",	ExprBinaryFunc,	(ClientData) hypot	},
   320    324       { "int",	ExprIntFunc,	NULL			},
   321    325       { "isqrt",	ExprIsqrtFunc,	NULL			},
   322    326       { "log",	ExprUnaryFunc,	(ClientData) log	},
   323    327       { "log10",	ExprUnaryFunc,	(ClientData) log10	},
          328  +    { "max",	ExprMaxFunc,	NULL			},
          329  +    { "min",	ExprMinFunc,	NULL			},
   324    330       { "pow",	ExprBinaryFunc,	(ClientData) pow	},
   325    331       { "rand",	ExprRandFunc,	NULL			},
   326    332       { "round",	ExprRoundFunc,	NULL			},
   327    333       { "sin",	ExprUnaryFunc,	(ClientData) sin	},
   328    334       { "sinh",	ExprUnaryFunc,	(ClientData) sinh	},
   329    335       { "sqrt",	ExprSqrtFunc,	NULL			},
   330    336       { "srand",	ExprSrandFunc,	NULL			},
................................................................................
   506    512        * (whose name is ""; an alias is "::"). This also initializes the Tcl
   507    513        * object type table and other object management code.
   508    514        */
   509    515   
   510    516       iPtr = ckalloc(sizeof(Interp));
   511    517       interp = (Tcl_Interp *) iPtr;
   512    518   
   513         -    iPtr->legacyResult = NULL;
   514         -    /* Special invalid value: Any attempt to free the legacy result
   515         -     * will cause a crash. */
   516         -    iPtr->legacyFreeProc = (void (*) (void))-1;
          519  +#ifdef TCL_NO_DEPRECATED
          520  +    iPtr->result = &tclEmptyString;
          521  +#else
          522  +    iPtr->result = iPtr->resultSpace;
          523  +#endif
          524  +    iPtr->freeProc = NULL;
   517    525       iPtr->errorLine = 0;
   518         -    iPtr->stubTable = &tclStubs;
   519    526       iPtr->objResultPtr = Tcl_NewObj();
   520    527       Tcl_IncrRefCount(iPtr->objResultPtr);
   521    528       iPtr->handle = TclHandleCreate(iPtr);
   522    529       iPtr->globalNsPtr = NULL;
   523    530       iPtr->hiddenCmdTablePtr = NULL;
   524    531       iPtr->interpInfo = NULL;
   525    532   
................................................................................
   568    575       TclNewLiteralStringObj(iPtr->ecVar, "::errorCode");
   569    576       Tcl_IncrRefCount(iPtr->ecVar);
   570    577       iPtr->returnLevel = 1;
   571    578       iPtr->returnCode = TCL_OK;
   572    579   
   573    580       iPtr->rootFramePtr = NULL;	/* Initialise as soon as :: is available */
   574    581       iPtr->lookupNsPtr = NULL;
          582  +
          583  +#ifndef TCL_NO_DEPRECATED
          584  +    iPtr->appendResult = NULL;
          585  +    iPtr->appendAvl = 0;
          586  +    iPtr->appendUsed = 0;
          587  +#endif
   575    588   
   576    589       Tcl_InitHashTable(&iPtr->packageTable, TCL_STRING_KEYS);
   577    590       iPtr->packageUnknown = NULL;
   578    591   
   579    592       /* TIP #268 */
   580    593   #if (TCL_RELEASE_LEVEL == TCL_FINAL_RELEASE)
   581    594       if (getenv("TCL_PKG_PREFER_LATEST") == NULL) {
................................................................................
   597    610       iPtr->activeCmdTracePtr = NULL;
   598    611       iPtr->activeInterpTracePtr = NULL;
   599    612       iPtr->assocData = NULL;
   600    613       iPtr->execEnvPtr = NULL;	/* Set after namespaces initialized. */
   601    614       iPtr->emptyObjPtr = Tcl_NewObj();
   602    615   				/* Another empty object. */
   603    616       Tcl_IncrRefCount(iPtr->emptyObjPtr);
          617  +#ifndef TCL_NO_DEPRECATED
          618  +    iPtr->resultSpace[0] = 0;
          619  +#endif
   604    620       iPtr->threadId = Tcl_GetCurrentThread();
   605    621   
   606    622       /* TIP #378 */
   607    623   #ifdef TCL_INTERP_DEBUG_FRAME
   608    624       iPtr->flags |= INTERP_DEBUG_FRAME;
   609    625   #else
   610    626       if (getenv("TCL_INTERP_DEBUG_FRAME") != NULL) {
................................................................................
   706    722   
   707    723       statsPtr->numLiteralsCreated = 0;
   708    724       statsPtr->totalLitStringBytes = 0.0;
   709    725       statsPtr->currentLitStringBytes = 0.0;
   710    726       memset(statsPtr->literalCount, 0, sizeof(statsPtr->literalCount));
   711    727   #endif /* TCL_COMPILE_STATS */
   712    728   
          729  +    /*
          730  +     * Initialise the stub table pointer.
          731  +     */
          732  +
          733  +    iPtr->stubTable = &tclStubs;
          734  +
   713    735       /*
   714    736        * Initialize the ensemble error message rewriting support.
   715    737        */
   716    738   
   717    739       TclResetRewriteEnsemble(interp, 1);
   718    740   
   719    741       /*
................................................................................
   723    745       TclInitLimitSupport(interp);
   724    746   
   725    747       /*
   726    748        * Initialise the thread-specific data ekeko. Note that the thread's alloc
   727    749        * cache was already initialised by the call to alloc the interp struct.
   728    750        */
   729    751   
   730         -#if defined(TCL_THREADS) && defined(USE_THREAD_ALLOC)
          752  +#if TCL_THREADS && defined(USE_THREAD_ALLOC)
   731    753       iPtr->allocCache = TclpGetAllocCache();
   732    754   #else
   733    755       iPtr->allocCache = NULL;
   734    756   #endif
   735    757       iPtr->pendingObjDataPtr = NULL;
   736    758       iPtr->asyncReadyPtr = TclGetAsyncReadyPtr();
   737    759       iPtr->deferredCallbacks = NULL;
................................................................................
   793    815       TclInitDictCmd(interp);
   794    816       TclInitEncodingCmd(interp);
   795    817       TclInitFileCmd(interp);
   796    818       TclInitInfoCmd(interp);
   797    819       TclInitNamespaceCmd(interp);
   798    820       TclInitStringCmd(interp);
   799    821       TclInitPrefixCmd(interp);
          822  +    TclInitProcessCmd(interp);
   800    823   
   801    824       /*
   802    825        * Register "clock" subcommands. These *do* go through
   803    826        * Tcl_CreateObjCommand, since they aren't in the global namespace and
   804    827        * involve ensembles.
   805    828        */
   806    829   
................................................................................
   930    953   
   931    954       /*
   932    955        * Set up other variables such as tcl_version and tcl_library
   933    956        */
   934    957   
   935    958       Tcl_SetVar2(interp, "tcl_patchLevel", NULL, TCL_PATCH_LEVEL, TCL_GLOBAL_ONLY);
   936    959       Tcl_SetVar2(interp, "tcl_version", NULL, TCL_VERSION, TCL_GLOBAL_ONLY);
          960  +#if !defined(TCL_NO_DEPRECATED) && TCL_MAJOR_VERSION < 9
   937    961       Tcl_TraceVar2(interp, "tcl_precision", NULL,
   938    962   	    TCL_GLOBAL_ONLY|TCL_TRACE_READS|TCL_TRACE_WRITES|TCL_TRACE_UNSETS,
   939    963   	    TclPrecTraceProc, NULL);
          964  +#endif /* !TCL_NO_DEPRECATED */
   940    965       TclpSetVariables(interp);
   941    966   
   942         -#ifdef TCL_THREADS
          967  +#if TCL_THREADS
   943    968       /*
   944    969        * The existence of the "threaded" element of the tcl_platform array
   945    970        * indicates that this particular Tcl shell has been compiled with threads
   946    971        * turned on. Using "info exists tcl_platform(threaded)" a Tcl script can
   947    972        * introspect on the interpreter level of thread safety.
   948    973        */
   949    974   
................................................................................
   970    995        * compile and link against.
   971    996        */
   972    997   
   973    998   #ifdef HAVE_ZLIB
   974    999       if (TclZlibInit(interp) != TCL_OK) {
   975   1000   	Tcl_Panic("%s", TclGetString(Tcl_GetObjResult(interp)));
   976   1001       }
         1002  +    if (TclZipfs_Init(interp) != TCL_OK) {
         1003  +	Tcl_Panic("%s", Tcl_GetString(Tcl_GetObjResult(interp)));
         1004  +    }
   977   1005   #endif
   978   1006   
   979   1007       TOP_CB(iPtr) = NULL;
   980   1008       return interp;
   981   1009   }
   982   1010   
   983   1011   static void
................................................................................
  1501   1529   
  1502   1530       /*
  1503   1531        * Free up the result *after* deleting variables, since variable deletion
  1504   1532        * could have transferred ownership of the result string to Tcl.
  1505   1533        */
  1506   1534   
  1507   1535       Tcl_FreeResult(interp);
         1536  +    iPtr->result = NULL;
  1508   1537       Tcl_DecrRefCount(iPtr->objResultPtr);
  1509   1538       iPtr->objResultPtr = NULL;
  1510   1539       Tcl_DecrRefCount(iPtr->ecVar);
  1511   1540       if (iPtr->errorCode) {
  1512   1541   	Tcl_DecrRefCount(iPtr->errorCode);
  1513   1542   	iPtr->errorCode = NULL;
  1514   1543       }
................................................................................
  1522   1551       Tcl_DecrRefCount(iPtr->upLiteral);
  1523   1552       Tcl_DecrRefCount(iPtr->callLiteral);
  1524   1553       Tcl_DecrRefCount(iPtr->innerLiteral);
  1525   1554       Tcl_DecrRefCount(iPtr->innerContext);
  1526   1555       if (iPtr->returnOpts) {
  1527   1556   	Tcl_DecrRefCount(iPtr->returnOpts);
  1528   1557       }
         1558  +#ifndef TCL_NO_DEPRECATED
         1559  +    if (iPtr->appendResult != NULL) {
         1560  +	ckfree(iPtr->appendResult);
         1561  +	iPtr->appendResult = NULL;
         1562  +    }
         1563  +#endif
  1529   1564       TclFreePackageInfo(iPtr);
  1530   1565       while (iPtr->tracePtr != NULL) {
  1531   1566   	Tcl_DeleteTrace((Tcl_Interp *) iPtr, (Tcl_Trace) iPtr->tracePtr);
  1532   1567       }
  1533   1568       if (iPtr->execEnvPtr != NULL) {
  1534   1569   	TclDeleteExecEnv(iPtr->execEnvPtr);
  1535   1570       }
................................................................................
  2071   2106           } else {
  2072   2107   	    nsPtr = iPtr->globalNsPtr;
  2073   2108   	    tail = cmdName;
  2074   2109           }
  2075   2110   
  2076   2111           hPtr = Tcl_CreateHashEntry(&nsPtr->cmdTable, tail, &isNew);
  2077   2112   
  2078         -        if (isNew || deleted) {
         2113  +	if (isNew || deleted) {
  2079   2114   	    /*
  2080   2115   	     * isNew - No conflict with existing command.
  2081   2116   	     * deleted - We've already deleted a conflicting command
  2082   2117   	     */
  2083   2118   	    break;
  2084         -        }
         2119  +	}
  2085   2120   
  2086   2121   	/* An existing command conflicts. Try to delete it.. */
  2087   2122   	cmdPtr = Tcl_GetHashValue(hPtr);
  2088   2123   
  2089   2124   	/*
  2090   2125   	 * Be careful to preserve
  2091   2126   	 * any existing import links so we can restore them down below. That
................................................................................
  2218   2253   				 * qualifiers, the new command is put in the
  2219   2254   				 * specified namespace; otherwise it is put in
  2220   2255   				 * the global namespace. */
  2221   2256       Tcl_ObjCmdProc *proc,	/* Object-based function to associate with
  2222   2257   				 * name. */
  2223   2258       ClientData clientData,	/* Arbitrary value to pass to object
  2224   2259   				 * function. */
  2225         -    Tcl_CmdDeleteProc *deleteProc)
         2260  +    Tcl_CmdDeleteProc *deleteProc
  2226   2261   				/* If not NULL, gives a function to call when
  2227   2262   				 * this command is deleted. */
         2263  +)
  2228   2264   {
  2229   2265       Interp *iPtr = (Interp *) interp;
  2230         -    ImportRef *oldRefPtr = NULL;
  2231   2266       Namespace *nsPtr;
  2232         -    Command *cmdPtr;
  2233         -    Tcl_HashEntry *hPtr;
  2234   2267       const char *tail;
  2235         -    int isNew = 0, deleted = 0;
  2236         -    ImportedCmdData *dataPtr;
  2237   2268   
  2238   2269       if (iPtr->flags & DELETED) {
  2239   2270   	/*
  2240   2271   	 * The interpreter is being deleted. Don't create any new commands;
  2241   2272   	 * it's not safe to muck with the interpreter anymore.
  2242   2273   	 */
  2243         -
  2244   2274   	return (Tcl_Command) NULL;
  2245   2275       }
  2246   2276   
  2247   2277       /*
  2248         -     * If the command name we seek to create already exists, we need to
  2249         -     * delete that first.  That can be tricky in the presence of traces.
  2250         -     * Loop until we no longer find an existing command in the way, or
  2251         -     * until we've deleted one command and that didn't finish the job.
         2278  +     * Determine where the command should reside. If its name contains
         2279  +     * namespace qualifiers, we put it in the specified namespace;
         2280  +     * otherwise, we always put it in the global namespace.
         2281  +     */
         2282  +
         2283  +    if (strstr(cmdName, "::") != NULL) {
         2284  +	Namespace *dummy1, *dummy2;
         2285  +
         2286  +	TclGetNamespaceForQualName(interp, cmdName, NULL,
         2287  +	    TCL_CREATE_NS_IF_UNKNOWN, &nsPtr, &dummy1, &dummy2, &tail);
         2288  +	if ((nsPtr == NULL) || (tail == NULL)) {
         2289  +	    return (Tcl_Command) NULL;
         2290  +	}
         2291  +    } else {
         2292  +	nsPtr = iPtr->globalNsPtr;
         2293  +	tail = cmdName;
         2294  +    }
         2295  +
         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
         2304  +                                 * components. */
         2305  +    Tcl_Namespace *namespace,   /* The namespace to create the command in */
         2306  +    Tcl_ObjCmdProc *proc,	/* Object-based function to associate with
         2307  +				 * name. */
         2308  +    ClientData clientData,	/* Arbitrary value to pass to object
         2309  +				 * function. */
         2310  +    Tcl_CmdDeleteProc *deleteProc)
         2311  +				/* If not NULL, gives a function to call when
         2312  +				 * this command is deleted. */
         2313  +{
         2314  +    int deleted = 0, isNew = 0;
         2315  +    Command *cmdPtr;
         2316  +    ImportRef *oldRefPtr = NULL;
         2317  +    ImportedCmdData *dataPtr;
         2318  +    Tcl_HashEntry *hPtr;
         2319  +    Namespace *nsPtr = (Namespace *) namespace;
         2320  +
         2321  +    /*
         2322  +     * If the command name we seek to create already exists, we need to delete
         2323  +     * that first. That can be tricky in the presence of traces. Loop until we
         2324  +     * no longer find an existing command in the way, or until we've deleted
         2325  +     * one command and that didn't finish the job.
  2252   2326        */
  2253   2327   
  2254   2328       while (1) {
  2255         -        /*
  2256         -         * Determine where the command should reside. If its name contains
  2257         -         * namespace qualifiers, we put it in the specified namespace;
  2258         -	 * otherwise, we always put it in the global namespace.
  2259         -         */
         2329  +	hPtr = Tcl_CreateHashEntry(&nsPtr->cmdTable, cmdName, &isNew);
  2260   2330   
  2261         -        if (strstr(cmdName, "::") != NULL) {
  2262         -	    Namespace *dummy1, *dummy2;
  2263         -
  2264         -	    TclGetNamespaceForQualName(interp, cmdName, NULL,
  2265         -		TCL_CREATE_NS_IF_UNKNOWN, &nsPtr, &dummy1, &dummy2, &tail);
  2266         -	    if ((nsPtr == NULL) || (tail == NULL)) {
  2267         -	        return (Tcl_Command) NULL;
  2268         -	    }
  2269         -        } else {
  2270         -	    nsPtr = iPtr->globalNsPtr;
  2271         -	    tail = cmdName;
  2272         -        }
  2273         -
  2274         -        hPtr = Tcl_CreateHashEntry(&nsPtr->cmdTable, tail, &isNew);
  2275         -
  2276         -        if (isNew || deleted) {
         2331  +	if (isNew || deleted) {
  2277   2332   	    /*
  2278   2333   	     * isNew - No conflict with existing command.
  2279   2334   	     * deleted - We've already deleted a conflicting command
  2280   2335   	     */
  2281   2336   	    break;
  2282         -        }
         2337  +	}
  2283   2338   
  2284         -	/* An existing command conflicts. Try to delete it.. */
         2339  +	/*
         2340  +         * An existing command conflicts. Try to delete it.
         2341  +         */
         2342  +
  2285   2343   	cmdPtr = Tcl_GetHashValue(hPtr);
  2286   2344   
  2287   2345   	/*
  2288         -	 * [***] This is wrong.  See Tcl Bug a16752c252.
  2289         -	 * However, this buggy behavior is kept under particular
  2290         -	 * circumstances to accommodate deployed binaries of the
  2291         -	 * "tclcompiler" program. http://sourceforge.net/projects/tclpro/
  2292         -	 * that crash if the bug is fixed.
         2346  +	 * [***] This is wrong. See Tcl Bug a16752c252. However, this buggy
         2347  +	 * behavior is kept under particular circumstances to accommodate
         2348  +	 * deployed binaries of the "tclcompiler" program
         2349  +	 *     http://sourceforge.net/projects/tclpro/
         2350  +         * that crash if the bug is fixed.
  2293   2351   	 */
  2294   2352   
  2295   2353   	if (cmdPtr->objProc == TclInvokeStringCommand
  2296   2354   		&& cmdPtr->clientData == clientData
  2297   2355   		&& cmdPtr->deleteData == clientData
  2298   2356   		&& cmdPtr->deleteProc == deleteProc) {
  2299   2357   	    cmdPtr->objProc = proc;
................................................................................
  2309   2367   	 */
  2310   2368   
  2311   2369   	cmdPtr->refCount++;
  2312   2370   	if (cmdPtr->importRefPtr) {
  2313   2371   	    cmdPtr->flags |= CMD_REDEF_IN_PROGRESS;
  2314   2372   	}
  2315   2373   
         2374  +	/*
         2375  +         * Make sure namespace doesn't get deallocated.
         2376  +         */
         2377  +
         2378  +	cmdPtr->nsPtr->refCount++;
         2379  +
  2316   2380   	Tcl_DeleteCommandFromToken(interp, (Tcl_Command) cmdPtr);
         2381  +	nsPtr = (Namespace *) TclEnsureNamespace(interp,
         2382  +                (Tcl_Namespace *) cmdPtr->nsPtr);
         2383  +	TclNsDecrRefCount(cmdPtr->nsPtr);
  2317   2384   
  2318   2385   	if (cmdPtr->flags & CMD_REDEF_IN_PROGRESS) {
  2319   2386   	    oldRefPtr = cmdPtr->importRefPtr;
  2320   2387   	    cmdPtr->importRefPtr = NULL;
  2321   2388   	}
  2322   2389   	TclCleanupCommandMacro(cmdPtr);
  2323   2390   	deleted = 1;
  2324   2391       }
  2325         -
  2326   2392       if (!isNew) {
  2327   2393   	/*
  2328         -	 * If the deletion callback recreated the command, just throw away
  2329         -	 * the new command (if we try to delete it again, we could get
  2330         -	 * stuck in an infinite loop).
         2394  +	 * If the deletion callback recreated the command, just throw away the
         2395  +	 * new command (if we try to delete it again, we could get stuck in an
         2396  +	 * infinite loop).
  2331   2397   	 */
  2332   2398   
  2333   2399   	ckfree(Tcl_GetHashValue(hPtr));
  2334   2400       }
  2335   2401   
  2336   2402       if (!deleted) {
  2337   2403   	/*
................................................................................
  2340   2406   	 * being registered with the namespace's command table. During BC
  2341   2407   	 * compilation, the so-resolved command turns into a CmdName literal.
  2342   2408   	 * Without invalidating a possible CmdName literal here explicitly,
  2343   2409   	 * such literals keep being reused while pointing to overhauled
  2344   2410   	 * commands.
  2345   2411   	 */
  2346   2412   
  2347         -	TclInvalidateCmdLiteral(interp, tail, nsPtr);
         2413  +	TclInvalidateCmdLiteral(interp, cmdName, nsPtr);
  2348   2414   
  2349   2415   	/*
  2350   2416   	 * The list of command exported from the namespace might have changed.
  2351   2417   	 * However, we do not need to recompute this just yet; next time we
  2352   2418   	 * need the info will be soon enough.
  2353   2419   	 */
  2354   2420   
................................................................................
  2378   2444        * all of these references to point to the new command.
  2379   2445        */
  2380   2446   
  2381   2447       if (oldRefPtr != NULL) {
  2382   2448   	cmdPtr->importRefPtr = oldRefPtr;
  2383   2449   	while (oldRefPtr != NULL) {
  2384   2450   	    Command *refCmdPtr = oldRefPtr->importedCmdPtr;
         2451  +
  2385   2452   	    dataPtr = refCmdPtr->objClientData;
  2386   2453   	    dataPtr->realCmdPtr = cmdPtr;
  2387   2454   	    oldRefPtr = oldRefPtr->nextPtr;
  2388   2455   	}
  2389   2456       }
  2390   2457   
  2391   2458       /*
................................................................................
  2455   2522    *	"Wrapper" Tcl_CmdProc used to call an existing object-based
  2456   2523    *	Tcl_ObjCmdProc if no string-based function exists for a command. A
  2457   2524    *	pointer to this function is stored as the Tcl_CmdProc in a Command
  2458   2525    *	structure. It simply turns around and calls the object Tcl_ObjCmdProc
  2459   2526    *	in the Command structure.
  2460   2527    *
  2461   2528    * Results:
  2462         - *	A standard Tcl result value.
         2529  + *	A standard Tcl string result value.
  2463   2530    *
  2464   2531    * Side effects:
  2465   2532    *	Besides those side effects of the called Tcl_ObjCmdProc,
  2466   2533    *	TclInvokeObjectCommand allocates and frees storage.
  2467   2534    *
  2468   2535    *----------------------------------------------------------------------
  2469   2536    */
................................................................................
  2495   2562       if (cmdPtr->objProc != NULL) {
  2496   2563   	result = cmdPtr->objProc(cmdPtr->objClientData, interp, argc, objv);
  2497   2564       } else {
  2498   2565   	result = Tcl_NRCallObjProc(interp, cmdPtr->nreProc,
  2499   2566   		cmdPtr->objClientData, argc, objv);
  2500   2567       }
  2501   2568   
         2569  +    /*
         2570  +     * Move the interpreter's object result to the string result, then reset
         2571  +     * the object result.
         2572  +     */
         2573  +
         2574  +    (void) Tcl_GetStringResult(interp);
         2575  +
  2502   2576       /*
  2503   2577        * Decrement the ref counts for the argument objects created above, then
  2504   2578        * free the objv array if malloc'ed storage was used.
  2505   2579        */
  2506   2580   
  2507   2581       for (i = 0; i < argc; i++) {
  2508   2582   	objPtr = objv[i];
................................................................................
  2563   2637   	Tcl_SetObjResult(interp, Tcl_ObjPrintf(
  2564   2638                   "can't %s \"%s\": command doesn't exist",
  2565   2639   		((newName == NULL)||(*newName == '\0'))? "delete":"rename",
  2566   2640   		oldName));
  2567   2641           Tcl_SetErrorCode(interp, "TCL", "LOOKUP", "COMMAND", oldName, NULL);
  2568   2642   	return TCL_ERROR;
  2569   2643       }
  2570         -    cmdNsPtr = cmdPtr->nsPtr;
  2571         -    oldFullName = Tcl_NewObj();
  2572         -    Tcl_IncrRefCount(oldFullName);
  2573         -    Tcl_GetCommandFullName(interp, cmd, oldFullName);
  2574   2644   
  2575   2645       /*
  2576   2646        * If the new command name is NULL or empty, delete the command. Do this
  2577   2647        * with Tcl_DeleteCommandFromToken, since we already have the command.
  2578   2648        */
  2579   2649   
  2580   2650       if ((newName == NULL) || (*newName == '\0')) {
  2581   2651   	Tcl_DeleteCommandFromToken(interp, cmd);
  2582         -	result = TCL_OK;
  2583         -	goto done;
         2652  +	return TCL_OK;
  2584   2653       }
  2585   2654   
         2655  +    cmdNsPtr = cmdPtr->nsPtr;
         2656  +    oldFullName = Tcl_NewObj();
         2657  +    Tcl_IncrRefCount(oldFullName);
         2658  +    Tcl_GetCommandFullName(interp, cmd, oldFullName);
         2659  +
  2586   2660       /*
  2587   2661        * Make sure that the destination command does not already exist. The
  2588   2662        * rename operation is like creating a command, so we should automatically
  2589   2663        * create the containing namespaces just like Tcl_CreateCommand would.
  2590   2664        */
  2591   2665   
  2592   2666       TclGetNamespaceForQualName(interp, newName, NULL,
................................................................................
  3089   3163   
  3090   3164       cmdPtr->flags |= CMD_IS_DELETED;
  3091   3165   
  3092   3166       /*
  3093   3167        * Call trace functions for the command being deleted. Then delete its
  3094   3168        * traces.
  3095   3169        */
         3170  +
         3171  +    cmdPtr->nsPtr->refCount++;
  3096   3172   
  3097   3173       if (cmdPtr->tracePtr != NULL) {
  3098   3174   	CommandTrace *tracePtr;
  3099   3175   	CallCommandTraces(iPtr,cmdPtr,NULL,NULL,TCL_TRACE_DELETE);
  3100   3176   
  3101   3177   	/*
  3102   3178   	 * Now delete these traces.
................................................................................
  3117   3193       /*
  3118   3194        * The list of command exported from the namespace might have changed.
  3119   3195        * However, we do not need to recompute this just yet; next time we need
  3120   3196        * the info will be soon enough.
  3121   3197        */
  3122   3198   
  3123   3199       TclInvalidateNsCmdLookup(cmdPtr->nsPtr);
         3200  +    TclNsDecrRefCount(cmdPtr->nsPtr);
  3124   3201   
  3125   3202       /*
  3126   3203        * If the command being deleted has a compile function, increment the
  3127   3204        * interpreter's compileEpoch to invalidate its compiled code. This makes
  3128   3205        * sure that we don't later try to execute old code compiled with
  3129   3206        * command-specific (i.e., inline) bytecodes for the now-deleted command.
  3130   3207        * This field is checked in Tcl_EvalObj and ObjInterpProc, and code whose
................................................................................
  3454   3531    *	an instruction specific to the replaced function. In addition,
  3455   3532    *	redefioning a non-builtin function will force existing code to be
  3456   3533    *	invalidated if the number of arguments has changed.
  3457   3534    *
  3458   3535    *----------------------------------------------------------------------
  3459   3536    */
  3460   3537   
         3538  +#if !defined(TCL_NO_DEPRECATED)
  3461   3539   void
  3462   3540   Tcl_CreateMathFunc(
  3463   3541       Tcl_Interp *interp,		/* Interpreter in which function is to be
  3464   3542   				 * available. */
  3465   3543       const char *name,		/* Name of function (e.g. "sin"). */
  3466   3544       int numArgs,		/* Nnumber of arguments required by
  3467   3545   				 * function. */
................................................................................
  3504   3582    *	Whatever the math function does.
  3505   3583    *
  3506   3584    *----------------------------------------------------------------------
  3507   3585    */
  3508   3586   
  3509   3587   static int
  3510   3588   OldMathFuncProc(
  3511         -    ClientData clientData,	/* Ponter to OldMathFuncData describing the
         3589  +    ClientData clientData,	/* Pointer to OldMathFuncData describing the
  3512   3590   				 * function being called */
  3513   3591       Tcl_Interp *interp,		/* Tcl interpreter */
  3514   3592       int objc,			/* Actual parameter count */
  3515   3593       Tcl_Obj *const *objv)	/* Parameter vector */
  3516   3594   {
  3517   3595       Tcl_Obj *valuePtr;
  3518   3596       OldMathFuncData *dataPtr = clientData;
................................................................................
  3549   3627   	    /*
  3550   3628   	     * We have a non-numeric argument.
  3551   3629   	     */
  3552   3630   
  3553   3631   	    Tcl_SetObjResult(interp, Tcl_NewStringObj(
  3554   3632   		    "argument to math function didn't have numeric value",
  3555   3633   		    -1));
         3634  +	    TclCheckBadOctal(interp, TclGetString(valuePtr));
  3556   3635   	    ckfree(args);
  3557   3636   	    return TCL_ERROR;
  3558   3637   	}
  3559   3638   
  3560   3639   	/*
  3561   3640   	 * Copy the object's numeric value to the argument record, converting
  3562   3641   	 * it if necessary.
................................................................................
  3616   3695       }
  3617   3696   
  3618   3697       /*
  3619   3698        * Return the result of the call.
  3620   3699        */
  3621   3700   
  3622   3701       if (funcResult.type == TCL_INT) {
  3623         -	TclNewLongObj(valuePtr, funcResult.intValue);
         3702  +	TclNewIntObj(valuePtr, funcResult.intValue);
  3624   3703       } else if (funcResult.type == TCL_WIDE_INT) {
  3625   3704   	valuePtr = Tcl_NewWideIntObj(funcResult.wideValue);
  3626   3705       } else {
  3627   3706   	return CheckDoubleResult(interp, funcResult.doubleValue);
  3628   3707       }
  3629   3708       Tcl_SetObjResult(interp, valuePtr);
  3630   3709       return TCL_OK;
................................................................................
  3784   3863   	result = Tcl_NewObj();
  3785   3864       }
  3786   3865       Tcl_DecrRefCount(script);
  3787   3866       Tcl_RestoreInterpState(interp, state);
  3788   3867   
  3789   3868       return result;
  3790   3869   }
         3870  +#endif /* !defined(TCL_NO_DEPRECATED) */
  3791   3871   
  3792   3872   /*
  3793   3873    *----------------------------------------------------------------------
  3794   3874    *
  3795   3875    * TclInterpReady --
  3796   3876    *
  3797   3877    *	Check if an interpreter is ready to eval commands or scripts, i.e., if
................................................................................
  3798   3878    *	it was not deleted and if the nesting level is not too high.
  3799   3879    *
  3800   3880    * Results:
  3801   3881    *	The return value is TCL_OK if it the interpreter is ready, TCL_ERROR
  3802   3882    *	otherwise.
  3803   3883    *
  3804   3884    * Side effects:
  3805         - *	The interpreter's result is cleared.
         3885  + *	The interpreters object and string results are cleared.
  3806   3886    *
  3807   3887    *----------------------------------------------------------------------
  3808   3888    */
  3809   3889   
  3810   3890   int
  3811   3891   TclInterpReady(
  3812   3892       Tcl_Interp *interp)
  3813   3893   {
  3814   3894       register Interp *iPtr = (Interp *) interp;
  3815   3895   
  3816   3896       /*
  3817         -     * Reset the interpreter's result and clear out any previous error
  3818         -     * information.
         3897  +     * Reset both the interpreter's string and object results and clear out
         3898  +     * any previous error information.
  3819   3899        */
  3820   3900   
  3821   3901       Tcl_ResetResult(interp);
  3822   3902   
  3823   3903       /*
  3824   3904        * If the interpreter has been deleted, return an error.
  3825   3905        */
................................................................................
  4391   4471   TclNRRunCallbacks(
  4392   4472       Tcl_Interp *interp,
  4393   4473       int result,
  4394   4474       struct NRE_callback *rootPtr)
  4395   4475   				/* All callbacks down to rootPtr not inclusive
  4396   4476   				 * are to be run. */
  4397   4477   {
         4478  +#if !defined(TCL_NO_DEPRECATED) && TCL_MAJOR_VERSION < 9
         4479  +    Interp *iPtr = (Interp *) interp;
         4480  +#endif /* !defined(TCL_NO_DEPRECATED) */
  4398   4481       NRE_callback *callbackPtr;
  4399   4482       Tcl_NRPostProc *procPtr;
  4400   4483   
         4484  +    /*
         4485  +     * If the interpreter has a non-empty string result, the result object is
         4486  +     * either empty or stale because some function set interp->result
         4487  +     * directly. If so, move the string result to the result object, then
         4488  +     * reset the string result.
         4489  +     *
         4490  +     * This only needs to be done for the first item in the list: all other
         4491  +     * are for NR function calls, and those are Tcl_Obj based.
         4492  +     */
         4493  +
         4494  +#if !defined(TCL_NO_DEPRECATED) && TCL_MAJOR_VERSION < 9
         4495  +    if (*(iPtr->result) != 0) {
         4496  +	(void) Tcl_GetObjResult(interp);
         4497  +    }
         4498  +#endif /* !defined(TCL_NO_DEPRECATED) */
         4499  +
         4500  +    /* This is the trampoline. */
         4501  +
  4401   4502       while (TOP_CB(interp) != rootPtr) {
  4402   4503   	callbackPtr = TOP_CB(interp);
  4403   4504   	procPtr = callbackPtr->procPtr;
  4404   4505   	TOP_CB(interp) = callbackPtr->nextPtr;
  4405   4506   	result = procPtr(callbackPtr->data, interp, result);
  4406   4507   	TCLNR_FREE(interp, callbackPtr);
  4407   4508       }
................................................................................
  4527   4628       Interp *iPtr = (Interp *) interp;
  4528   4629       int allowExceptions = (PTR2INT(data[0]) & TCL_ALLOW_EXCEPTIONS);
  4529   4630   
  4530   4631       if (result != TCL_OK) {
  4531   4632   	if (result == TCL_RETURN) {
  4532   4633   	    result = TclUpdateReturnInfo(iPtr);
  4533   4634   	}
  4534         -	if ((result != TCL_ERROR) && !allowExceptions) {
         4635  +	if ((result != TCL_OK) && (result != TCL_ERROR) && !allowExceptions) {
  4535   4636   	    ProcessUnexpectedResult(interp, result);
  4536   4637   	    result = TCL_ERROR;
  4537   4638   	}
  4538   4639       }
  4539   4640   
  4540   4641       /*
  4541   4642        * We are returning to level 0, so should process TclResetCancellation. As
................................................................................
  4708   4809       Command **cmdPtrPtr,
  4709   4810       Tcl_Obj *commandPtr,
  4710   4811       int objc,
  4711   4812       Tcl_Obj *const objv[])
  4712   4813   {
  4713   4814       Interp *iPtr = (Interp *) interp;
  4714   4815       Command *cmdPtr = *cmdPtrPtr;
  4715         -    size_t newEpoch, cmdEpoch = cmdPtr->cmdEpoch;
         4816  +    unsigned int newEpoch, cmdEpoch = cmdPtr->cmdEpoch;
  4716   4817       int length, traceCode = TCL_OK;
  4717   4818       const char *command = TclGetStringFromObj(commandPtr, &length);
  4718   4819   
  4719   4820       /*
  4720   4821        * Call trace functions.
  4721   4822        * Execute any command or execution traces. Note that we bump up the
  4722   4823        * command's reference count for the duration of the calling of the
................................................................................
  4851   4952       int count)			/* Number of tokens to consider at tokenPtr.
  4852   4953   				 * Must be at least 1. */
  4853   4954   {
  4854   4955       return TclSubstTokens(interp, tokenPtr, count, /* numLeftPtr */ NULL, 1,
  4855   4956   	    NULL, NULL);
  4856   4957   }
  4857   4958   
         4959  +#if !defined(TCL_NO_DEPRECATED) && TCL_MAJOR_VERSION < 9
  4858   4960   /*
  4859   4961    *----------------------------------------------------------------------
  4860   4962    *
  4861   4963    * Tcl_EvalTokens --
  4862   4964    *
  4863   4965    *	Given an array of tokens parsed from a Tcl command (e.g., the tokens
  4864   4966    *	that make up a word or the index for an array variable) this function
................................................................................
  4898   5000   	return NULL;
  4899   5001       }
  4900   5002       resPtr = Tcl_GetObjResult(interp);
  4901   5003       Tcl_IncrRefCount(resPtr);
  4902   5004       Tcl_ResetResult(interp);
  4903   5005       return resPtr;
  4904   5006   }
         5007  +#endif /* !TCL_NO_DEPRECATED */
  4905   5008   
  4906   5009   /*
  4907   5010    *----------------------------------------------------------------------
  4908   5011    *
  4909   5012    * Tcl_EvalEx, TclEvalEx --
  4910   5013    *
  4911   5014    *	This function evaluates a Tcl script without using the compiler or
................................................................................
  5861   5964   #undef Tcl_Eval
  5862   5965   int
  5863   5966   Tcl_Eval(
  5864   5967       Tcl_Interp *interp,		/* Token for command interpreter (returned by
  5865   5968   				 * previous call to Tcl_CreateInterp). */
  5866   5969       const char *script)		/* Pointer to TCL command to execute. */
  5867   5970   {
  5868         -    return Tcl_EvalEx(interp, script, -1, 0);
         5971  +    int code = Tcl_EvalEx(interp, script, -1, 0);
         5972  +
         5973  +    /*
         5974  +     * For backwards compatibility with old C code that predates the object
         5975  +     * system in Tcl 8.0, we have to mirror the object result back into the
         5976  +     * string result (some callers may expect it there).
         5977  +     */
         5978  +
         5979  +    (void) Tcl_GetStringResult(interp);
         5980  +    return code;
  5869   5981   }
  5870   5982   
  5871   5983   /*
  5872   5984    *----------------------------------------------------------------------
  5873   5985    *
  5874   5986    * Tcl_EvalObj, Tcl_GlobalEvalObj --
  5875   5987    *
................................................................................
  6284   6396   
  6285   6397   	*ptr = 0;
  6286   6398       } else {
  6287   6399   	exprPtr = Tcl_NewStringObj(exprstring, -1);
  6288   6400   	Tcl_IncrRefCount(exprPtr);
  6289   6401   	result = Tcl_ExprLongObj(interp, exprPtr, ptr);
  6290   6402   	Tcl_DecrRefCount(exprPtr);
         6403  +	if (result != TCL_OK) {
         6404  +	    (void) Tcl_GetStringResult(interp);
         6405  +	}
  6291   6406       }
  6292   6407       return result;
  6293   6408   }
  6294   6409   
  6295   6410   int
  6296   6411   Tcl_ExprDouble(
  6297   6412       Tcl_Interp *interp,		/* Context in which to evaluate the
................................................................................
  6310   6425   	*ptr = 0.0;
  6311   6426       } else {
  6312   6427   	exprPtr = Tcl_NewStringObj(exprstring, -1);
  6313   6428   	Tcl_IncrRefCount(exprPtr);
  6314   6429   	result = Tcl_ExprDoubleObj(interp, exprPtr, ptr);
  6315   6430   	Tcl_DecrRefCount(exprPtr);
  6316   6431   				/* Discard the expression object. */
         6432  +	if (result != TCL_OK) {
         6433  +	    (void) Tcl_GetStringResult(interp);
         6434  +	}
  6317   6435       }
  6318   6436       return result;
  6319   6437   }
  6320   6438   
  6321   6439   int
  6322   6440   Tcl_ExprBoolean(
  6323   6441       Tcl_Interp *interp,		/* Context in which to evaluate the
................................................................................
  6335   6453       } else {
  6336   6454   	int result;
  6337   6455   	Tcl_Obj *exprPtr = Tcl_NewStringObj(exprstring, -1);
  6338   6456   
  6339   6457   	Tcl_IncrRefCount(exprPtr);
  6340   6458   	result = Tcl_ExprBooleanObj(interp, exprPtr, ptr);
  6341   6459   	Tcl_DecrRefCount(exprPtr);
         6460  +	if (result != TCL_OK) {
         6461  +	    /*
         6462  +	     * Move the interpreter's object result to the string result, then
         6463  +	     * reset the object result.
         6464  +	     */
         6465  +
         6466  +	    (void) Tcl_GetStringResult(interp);
         6467  +	}
  6342   6468   	return result;
  6343   6469       }
  6344   6470   }
  6345   6471   
  6346   6472   /*
  6347   6473    *--------------------------------------------------------------
  6348   6474    *
................................................................................
  6393   6519   	Tcl_DecrRefCount(resultPtr);
  6394   6520   	if (Tcl_InitBignumFromDouble(interp, d, &big) != TCL_OK) {
  6395   6521   	    return TCL_ERROR;
  6396   6522   	}
  6397   6523   	resultPtr = Tcl_NewBignumObj(&big);
  6398   6524   	/* FALLTHROUGH */
  6399   6525       }
  6400         -    case TCL_NUMBER_LONG:
  6401   6526       case TCL_NUMBER_WIDE:
  6402   6527       case TCL_NUMBER_BIG:
  6403   6528   	result = TclGetLongFromObj(interp, resultPtr, ptr);
  6404   6529   	break;
  6405   6530   
  6406   6531       case TCL_NUMBER_NAN:
  6407   6532   	Tcl_GetDoubleFromObj(interp, resultPtr, &d);
................................................................................
  6649   6774   	code = Tcl_ExprObj(interp, exprObj, &resultPtr);
  6650   6775   	Tcl_DecrRefCount(exprObj);
  6651   6776   	if (code == TCL_OK) {
  6652   6777   	    Tcl_SetObjResult(interp, resultPtr);
  6653   6778   	    Tcl_DecrRefCount(resultPtr);
  6654   6779   	}
  6655   6780       }
         6781  +
         6782  +    /*
         6783  +     * Force the string rep of the interp result.
         6784  +     */
         6785  +
         6786  +    (void) Tcl_GetStringResult(interp);
  6656   6787       return code;
  6657   6788   }
  6658   6789   
  6659   6790   /*
  6660   6791    *----------------------------------------------------------------------
  6661   6792    *
  6662   6793    * Tcl_AppendObjToErrorInfo --
................................................................................
  6755   6886       /*
  6756   6887        * If we are just starting to log an error, errorInfo is initialized from
  6757   6888        * the error message in the interpreter's result.
  6758   6889        */
  6759   6890   
  6760   6891       iPtr->flags |= ERR_LEGACY_COPY;
  6761   6892       if (iPtr->errorInfo == NULL) {
  6762         -        iPtr->errorInfo = iPtr->objResultPtr;
         6893  +#if !defined(TCL_NO_DEPRECATED) && TCL_MAJOR_VERSION < 9
         6894  +	if (*(iPtr->result) != 0) {
         6895  +	    /*
         6896  +	     * The interp's string result is set, apparently by some extension
         6897  +	     * making a deprecated direct write to it. That extension may
         6898  +	     * expect interp->result to continue to be set, so we'll take
         6899  +	     * special pains to avoid clearing it, until we drop support for
         6900  +	     * interp->result completely.
         6901  +	     */
         6902  +
         6903  +	    iPtr->errorInfo = Tcl_NewStringObj(iPtr->result, -1);
         6904  +	} else
         6905  +#endif /* !defined(TCL_NO_DEPRECATED) */
         6906  +	    iPtr->errorInfo = iPtr->objResultPtr;
  6763   6907   	Tcl_IncrRefCount(iPtr->errorInfo);
  6764   6908   	if (!iPtr->errorCode) {
  6765   6909   	    Tcl_SetErrorCode(interp, "NONE", NULL);
  6766   6910   	}
  6767   6911       }
  6768   6912   
  6769   6913       /*
................................................................................
  6833   6977    * Tcl_VarEval --
  6834   6978    *
  6835   6979    *	Given a variable number of string arguments, concatenate them all
  6836   6980    *	together and execute the result as a Tcl command.
  6837   6981    *
  6838   6982    * Results:
  6839   6983    *	A standard Tcl return result. An error message or other result may be
  6840         - *	left in the interp.
         6984  + *	left in interp->result.
  6841   6985    *
  6842   6986    * Side effects:
  6843   6987    *	Depends on what was done by the command.
  6844   6988    *
  6845   6989    *----------------------------------------------------------------------
  6846   6990    */
  6847   6991   	/* ARGSUSED */
................................................................................
  7351   7495   	return TCL_ERROR;
  7352   7496       }
  7353   7497   
  7354   7498       if (TclGetNumberFromObj(interp, objv[1], &ptr, &type) != TCL_OK) {
  7355   7499   	return TCL_ERROR;
  7356   7500       }
  7357   7501   
  7358         -    if (type == TCL_NUMBER_LONG) {
  7359         -	long l = *((const long *) ptr);
         7502  +    if (type == TCL_NUMBER_WIDE) {
         7503  +	Tcl_WideInt l = *((const Tcl_WideInt *) ptr);
  7360   7504   
  7361         -	if (l > (long)0) {
         7505  +	if (l > (Tcl_WideInt)0) {
  7362   7506   	    goto unChanged;
  7363         -	} else if (l == (long)0) {
         7507  +	} else if (l == (Tcl_WideInt)0) {
  7364   7508   	    const char *string = objv[1]->bytes;
  7365   7509   	    if (string) {
  7366   7510   		while (*string != '0') {
  7367   7511   		    if (*string == '-') {
  7368   7512   			Tcl_SetObjResult(interp, Tcl_NewLongObj(0));
  7369   7513   			return TCL_OK;
  7370   7514   		    }
  7371   7515   		    string++;
  7372   7516   		}
  7373   7517   	    }
  7374   7518   	    goto unChanged;
  7375         -	} else if (l == LONG_MIN) {
  7376         -	    TclInitBignumFromLong(&big, l);
         7519  +	} else if (l == LLONG_MIN) {
         7520  +	    TclInitBignumFromWideInt(&big, l);
  7377   7521   	    goto tooLarge;
  7378   7522   	}
  7379         -	Tcl_SetObjResult(interp, Tcl_NewLongObj(-l));
         7523  +	Tcl_SetObjResult(interp, Tcl_NewWideIntObj(-l));
  7380   7524   	return TCL_OK;
  7381   7525       }
  7382   7526   
  7383   7527       if (type == TCL_NUMBER_DOUBLE) {
  7384   7528   	double d = *((const double *) ptr);
  7385   7529   	static const double poszero = 0.0;
  7386   7530   
................................................................................
  7396   7540   	} else if (d > -0.0) {
  7397   7541   	    goto unChanged;
  7398   7542   	}
  7399   7543   	Tcl_SetObjResult(interp, Tcl_NewDoubleObj(-d));
  7400   7544   	return TCL_OK;
  7401   7545       }
  7402   7546   
  7403         -#ifndef TCL_WIDE_INT_IS_LONG
  7404         -    if (type == TCL_NUMBER_WIDE) {
  7405         -	Tcl_WideInt w = *((const Tcl_WideInt *) ptr);
  7406         -
  7407         -	if (w >= (Tcl_WideInt)0) {
  7408         -	    goto unChanged;
  7409         -	}
  7410         -	if (w == LLONG_MIN) {
  7411         -	    TclInitBignumFromWideInt(&big, w);
  7412         -	    goto tooLarge;
  7413         -	}
  7414         -	Tcl_SetObjResult(interp, Tcl_NewWideIntObj(-w));
  7415         -	return TCL_OK;
  7416         -    }
  7417         -#endif
  7418         -
  7419   7547       if (type == TCL_NUMBER_BIG) {
  7420         -	if (mp_cmp_d((const mp_int *) ptr, 0) == MP_LT) {
         7548  +	if (mp_isneg((const mp_int *) ptr)) {
  7421   7549   	    Tcl_GetBignumFromObj(NULL, objv[1], &big);
  7422   7550   	tooLarge:
  7423   7551   	    mp_neg(&big, &big);
  7424   7552   	    Tcl_SetObjResult(interp, Tcl_NewBignumObj(&big));
  7425   7553   	} else {
  7426   7554   	unChanged:
  7427   7555   	    Tcl_SetObjResult(interp, objv[1]);
................................................................................
  7607   7735   	Tcl_IncrRefCount(objPtr);
  7608   7736   	TclGetWideIntFromObj(NULL, objPtr, &wResult);
  7609   7737   	Tcl_DecrRefCount(objPtr);
  7610   7738       }
  7611   7739       Tcl_SetObjResult(interp, Tcl_NewWideIntObj(wResult));
  7612   7740       return TCL_OK;
  7613   7741   }
         7742  +
         7743  +/*
         7744  + * Common implmentation of max() and min().
         7745  + */
         7746  +static int
         7747  +ExprMaxMinFunc(
         7748  +    ClientData clientData,	/* Ignored. */
         7749  +    Tcl_Interp *interp,		/* The interpreter in which to execute the
         7750  +				 * function. */
         7751  +    int objc,			/* Actual parameter count. */
         7752  +    Tcl_Obj *const *objv,	/* Actual parameter vector. */
         7753  +    int op)			/* Comparison direction */
         7754  +{
         7755  +    Tcl_Obj *res;
         7756  +    double d;
         7757  +    int type, i;
         7758  +    ClientData ptr;
         7759  +
         7760  +    if (objc < 2) {
         7761  +	MathFuncWrongNumArgs(interp, 2, objc, objv);
         7762  +	return TCL_ERROR;
         7763  +    }
         7764  +    res = objv[1];
         7765  +    for (i = 1; i < objc; i++) {
         7766  +        if (TclGetNumberFromObj(interp, objv[i], &ptr, &type) != TCL_OK) {
         7767  +            return TCL_ERROR;
         7768  +        }
         7769  +        if (type == TCL_NUMBER_NAN) {
         7770  +            /*
         7771  +             * Get the error message for NaN.
         7772  +             */
         7773  +
         7774  +            Tcl_GetDoubleFromObj(interp, objv[i], &d);
         7775  +            return TCL_ERROR;
         7776  +        }
         7777  +        if (TclCompareTwoNumbers(objv[i], res) == op)  {
         7778  +            res = objv[i];
         7779  +        }
         7780  +    }
         7781  +
         7782  +    Tcl_SetObjResult(interp, res);
         7783  +    return TCL_OK;
         7784  +}
         7785  +
         7786  +static int
         7787  +ExprMaxFunc(
         7788  +    ClientData clientData,	/* Ignored. */
         7789  +    Tcl_Interp *interp,		/* The interpreter in which to execute the
         7790  +				 * function. */
         7791  +    int objc,			/* Actual parameter count. */
         7792  +    Tcl_Obj *const *objv)	/* Actual parameter vector. */
         7793  +{
         7794  +    return ExprMaxMinFunc(clientData, interp, objc, objv, MP_GT);
         7795  +}
         7796  +
         7797  +static int
         7798  +ExprMinFunc(
         7799  +    ClientData clientData,	/* Ignored. */
         7800  +    Tcl_Interp *interp,		/* The interpreter in which to execute the
         7801  +				 * function. */
         7802  +    int objc,			/* Actual parameter count. */
         7803  +    Tcl_Obj *const *objv)	/* Actual parameter vector. */
         7804  +{
         7805  +    return ExprMaxMinFunc(clientData, interp, objc, objv, MP_LT);
         7806  +}
  7614   7807   
  7615   7808   static int
  7616   7809   ExprRandFunc(
  7617   7810       ClientData clientData,	/* Ignored. */
  7618   7811       Tcl_Interp *interp,		/* The interpreter in which to execute the
  7619   7812   				 * function. */
  7620   7813       int objc,			/* Actual parameter count. */
................................................................................
  7631   7824   	return TCL_ERROR;
  7632   7825       }
  7633   7826   
  7634   7827       if (!(iPtr->flags & RAND_SEED_INITIALIZED)) {
  7635   7828   	iPtr->flags |= RAND_SEED_INITIALIZED;
  7636   7829   
  7637   7830   	/*
  7638         -	 * To ensure different seeds in different threads (bug #416643), 
         7831  +	 * To ensure different seeds in different threads (bug #416643),
  7639   7832   	 * take into consideration the thread this interp is running in.
  7640   7833   	 */
  7641   7834   
  7642   7835   	iPtr->randSeed = TclpGetClicks() + (PTR2INT(Tcl_GetCurrentThread())<<12);
  7643   7836   
  7644   7837   	/*
  7645   7838   	 * Make sure 1 <= randSeed <= (2^31) - 2. See below.
................................................................................
  8091   8284       ClientData clientData,	/* Arbitrary value to pass to object
  8092   8285   				 * function. */
  8093   8286       Tcl_CmdDeleteProc *deleteProc)
  8094   8287   				/* If not NULL, gives a function to call when
  8095   8288   				 * this command is deleted. */
  8096   8289   {
  8097   8290       Command *cmdPtr = (Command *)
  8098         -	    Tcl_CreateObjCommand(interp,cmdName,proc,clientData,deleteProc);
         8291  +	    Tcl_CreateObjCommand(interp, cmdName, proc, clientData,
         8292  +                    deleteProc);
         8293  +
         8294  +    cmdPtr->nreProc = nreProc;
         8295  +    return (Tcl_Command) cmdPtr;
         8296  +}
         8297  +
         8298  +Tcl_Command
         8299  +TclNRCreateCommandInNs(
         8300  +    Tcl_Interp *interp,
         8301  +    const char *cmdName,
         8302  +    Tcl_Namespace *nsPtr,
         8303  +    Tcl_ObjCmdProc *proc,
         8304  +    Tcl_ObjCmdProc *nreProc,
         8305  +    ClientData clientData,
         8306  +    Tcl_CmdDeleteProc *deleteProc)
         8307  +{
         8308  +    Command *cmdPtr = (Command *)
         8309  +            TclCreateObjCommandInNs(interp, cmdName, nsPtr, proc, clientData,
         8310  +                    deleteProc);
  8099   8311   
  8100   8312       cmdPtr->nreProc = nreProc;
  8101   8313       return (Tcl_Command) cmdPtr;
  8102   8314   }
  8103   8315   
  8104   8316   /****************************************************************************
  8105   8317    * Stuff for the public api
................................................................................
  8195   8407   void
  8196   8408   TclPushTailcallPoint(
  8197   8409       Tcl_Interp *interp)
  8198   8410   {
  8199   8411       TclNRAddCallback(interp, NRCommand, NULL, NULL, NULL, NULL);
  8200   8412       ((Interp *) interp)->numLevels++;
  8201   8413   }
  8202         -
  8203   8414   
  8204   8415   /*
  8205   8416    *----------------------------------------------------------------------
  8206   8417    *
  8207   8418    * TclSetTailcall --
  8208   8419    *
  8209   8420    *	Splice a tailcall command in the proper spot of the NRE callback
................................................................................
  8231   8442           }
  8232   8443       }
  8233   8444       if (!runPtr) {
  8234   8445           Tcl_Panic("tailcall cannot find the right splicing spot: should not happen!");
  8235   8446       }
  8236   8447       runPtr->data[1] = listPtr;
  8237   8448   }
  8238         -
  8239   8449   
  8240   8450   /*
  8241   8451    *----------------------------------------------------------------------
  8242   8452    *
  8243   8453    * TclNRTailcallObjCmd --
  8244   8454    *
  8245   8455    *	Prepare the tailcall as a list and store it in the current
................................................................................
  8289   8499        * command, then set it in the varFrame so that PopCallFrame can use it
  8290   8500        * at the proper time.
  8291   8501        */
  8292   8502   
  8293   8503       if (objc > 1) {
  8294   8504           Tcl_Obj *listPtr, *nsObjPtr;
  8295   8505           Tcl_Namespace *nsPtr = (Tcl_Namespace *) iPtr->varFramePtr->nsPtr;
  8296         -        Tcl_Namespace *ns1Ptr;
  8297   8506   
  8298   8507           /* The tailcall data is in a Tcl list: the first element is the
  8299   8508            * namespace, the rest the command to be tailcalled. */
  8300   8509   
  8301         -        listPtr = Tcl_NewListObj(objc, objv);
  8302         -
  8303   8510           nsObjPtr = Tcl_NewStringObj(nsPtr->fullName, -1);
  8304         -        if ((TCL_OK != TclGetNamespaceFromObj(interp, nsObjPtr, &ns1Ptr))
  8305         -                || (nsPtr != ns1Ptr)) {
  8306         -            Tcl_Panic("Tailcall failed to find the proper namespace");
  8307         -        }
         8511  +        listPtr = Tcl_NewListObj(objc, objv);
  8308   8512    	TclListObjSetElement(interp, listPtr, 0, nsObjPtr);
  8309   8513   
  8310   8514           iPtr->varFramePtr->tailcallPtr = listPtr;
  8311   8515       }
  8312   8516       return TCL_RETURN;
  8313   8517   }
  8314         -
  8315   8518   
  8316   8519   /*
  8317   8520    *----------------------------------------------------------------------
  8318   8521    *
  8319   8522    * TclNRTailcallEval --
  8320   8523    *
  8321   8524    *	This NREcallback actually causes the tailcall to be evaluated.
................................................................................
  8375   8578   	} else {
  8376   8579   	    break;
  8377   8580   	}
  8378   8581   	i++;
  8379   8582       }
  8380   8583       return result;
  8381   8584   }
  8382         -
  8383   8585   
  8384   8586   void
  8385   8587   Tcl_NRAddCallback(
  8386   8588       Tcl_Interp *interp,
  8387   8589       Tcl_NRPostProc *postProcPtr,
  8388   8590       ClientData data0,
  8389   8591       ClientData data1,
................................................................................
  8881   9083       ClientData dummy,		/* Not used. */
  8882   9084       Tcl_Interp *interp,		/* Current interpreter. */
  8883   9085       int objc,			/* Number of arguments. */
  8884   9086       Tcl_Obj *const objv[])	/* Argument objects. */
  8885   9087   {
  8886   9088       Command *cmdPtr;
  8887   9089       CoroutineData *corPtr;
  8888         -    const char *fullName, *procName;
  8889         -    Namespace *nsPtr, *altNsPtr, *cxtNsPtr;
  8890         -    Tcl_DString ds;
         9090  +    const char *procName, *simpleName;
         9091  +    Namespace *nsPtr, *altNsPtr, *cxtNsPtr,
         9092  +	*inNsPtr = (Namespace *)TclGetCurrentNamespace(interp);
  8891   9093       Namespace *lookupNsPtr = iPtr->varFramePtr->nsPtr;
  8892   9094   
  8893   9095       if (objc < 3) {
  8894   9096   	Tcl_WrongNumArgs(interp, 1, objv, "name cmd ?arg ...?");
  8895   9097   	return TCL_ERROR;
  8896   9098       }
  8897   9099   
  8898         -    /*
  8899         -     * FIXME: this is copy/pasted from Tcl_ProcObjCommand. Should have
  8900         -     * something in tclUtil.c to find the FQ name.
  8901         -     */
  8902         -
  8903         -    fullName = TclGetString(objv[1]);
  8904         -    TclGetNamespaceForQualName(interp, fullName, NULL, 0,
  8905         -	    &nsPtr, &altNsPtr, &cxtNsPtr, &procName);
         9100  +    procName = TclGetString(objv[1]);
         9101  +    TclGetNamespaceForQualName(interp, procName, inNsPtr, 0,
         9102  +	    &nsPtr, &altNsPtr, &cxtNsPtr, &simpleName);
  8906   9103   
  8907   9104       if (nsPtr == NULL) {
  8908   9105   	Tcl_SetObjResult(interp, Tcl_ObjPrintf(
  8909   9106                   "can't create procedure \"%s\": unknown namespace",
  8910         -                fullName));
         9107  +                procName));
  8911   9108           Tcl_SetErrorCode(interp, "TCL", "LOOKUP", "NAMESPACE", NULL);
  8912   9109   	return TCL_ERROR;
  8913   9110       }
  8914         -    if (procName == NULL) {
         9111  +    if (simpleName == NULL) {
  8915   9112   	Tcl_SetObjResult(interp, Tcl_ObjPrintf(
  8916   9113                   "can't create procedure \"%s\": bad procedure name",
  8917         -                fullName));
  8918         -        Tcl_SetErrorCode(interp, "TCL", "VALUE", "COMMAND", fullName, NULL);
  8919         -	return TCL_ERROR;
  8920         -    }
  8921         -    if ((nsPtr != iPtr->globalNsPtr)
  8922         -	    && (procName != NULL) && (procName[0] == ':')) {
  8923         -	Tcl_SetObjResult(interp, Tcl_ObjPrintf(
  8924         -                "can't create procedure \"%s\" in non-global namespace with"
  8925         -                " name starting with \":\"", procName));
         9114  +                procName));
  8926   9115           Tcl_SetErrorCode(interp, "TCL", "VALUE", "COMMAND", procName, NULL);
  8927   9116   	return TCL_ERROR;
  8928   9117       }
  8929   9118   
  8930   9119       /*
  8931   9120        * We ARE creating the coroutine command: allocate the corresponding
  8932   9121        * struct and create the corresponding command.
  8933   9122        */
  8934   9123   
  8935   9124       corPtr = ckalloc(sizeof(CoroutineData));
  8936   9125   
  8937         -    Tcl_DStringInit(&ds);
  8938         -    if (nsPtr != iPtr->globalNsPtr) {
  8939         -	Tcl_DStringAppend(&ds, nsPtr->fullName, -1);
  8940         -	TclDStringAppendLiteral(&ds, "::");
  8941         -    }
  8942         -    Tcl_DStringAppend(&ds, procName, -1);
  8943         -
  8944         -    cmdPtr = (Command *) Tcl_NRCreateCommand(interp, Tcl_DStringValue(&ds),
  8945         -	    /*objProc*/ NULL, TclNRInterpCoroutine, corPtr, DeleteCoroutine);
  8946         -    Tcl_DStringFree(&ds);
         9126  +    cmdPtr = (Command *) TclNRCreateCommandInNs(interp, simpleName,
         9127  +	    (Tcl_Namespace *)nsPtr, /*objProc*/ NULL, TclNRInterpCoroutine,
         9128  +	    corPtr, DeleteCoroutine);
  8947   9129   
  8948   9130       corPtr->cmdPtr = cmdPtr;
  8949   9131       cmdPtr->refCount++;
  8950   9132   
  8951   9133       /*
  8952   9134        * #280.
  8953   9135        * Provide the new coroutine with its own copy of the lineLABCPtr

Changes to generic/tclCkalloc.c.

   152    152   
   153    153   void
   154    154   TclInitDbCkalloc(void)
   155    155   {
   156    156       if (!ckallocInit) {
   157    157   	ckallocInit = 1;
   158    158   	ckallocMutexPtr = Tcl_GetAllocMutex();
   159         -#ifndef TCL_THREADS
          159  +#if !TCL_THREADS
   160    160   	/* Silence compiler warning */
   161    161   	(void)ckallocMutexPtr;
   162    162   #endif
   163    163       }
   164    164   }
   165    165   
   166    166   /*
................................................................................
   183    183       if (clientData == NULL) {
   184    184           return 0;
   185    185       }
   186    186       sprintf(buf,
   187    187   	    "total mallocs             %10u\n"
   188    188   	    "total frees               %10u\n"
   189    189   	    "current packets allocated %10u\n"
   190         -	    "current bytes allocated   %10" TCL_LL_MODIFIER "u\n"
          190  +	    "current bytes allocated   %10" TCL_Z_MODIFIER "u\n"
   191    191   	    "maximum packets allocated %10u\n"
   192         -	    "maximum bytes allocated   %10" TCL_LL_MODIFIER "u\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         -	    (Tcl_WideInt)current_bytes_malloced,
          196  +	    current_bytes_malloced,
   197    197   	    maximum_malloc_packets,
   198         -	    (Tcl_WideInt)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, "%p - %p  %" TCL_LL_MODIFIER "d @ %s %d %s",
          362  +	fprintf(fileP, "%p - %p  %" TCL_Z_MODIFIER "u @ %s %d %s",
   363    363   		address, address + memScanP->length - 1,
   364         -		(Tcl_WideInt)memScanP->length, memScanP->file, memScanP->line,
          364  +		memScanP->length, memScanP->file, memScanP->line,
   365    365   		(memScanP->tagPtr == NULL) ? "" : memScanP->tagPtr->string);
   366    366   	(void) fputc('\n', fileP);
   367    367       }
   368    368       Tcl_MutexUnlock(ckallocMutexPtr);
   369    369   
   370    370       if (fileP != stderr) {
   371    371   	fclose(fileP);
................................................................................
   607    607        * such as Crays (will subtract only bytes, even though BODY_OFFSET is in
   608    608        * words on these machines).
   609    609        */
   610    610   
   611    611       memp = (struct mem_header *) (((size_t) ptr) - BODY_OFFSET);
   612    612   
   613    613       if (alloc_tracing) {
   614         -	fprintf(stderr, "ckfree %p %" TCL_LL_MODIFIER "d %s %d\n",
   615         -		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);
   616    616       }
   617    617   
   618    618       if (validate_memory) {
   619    619   	Tcl_ValidateAllMemory(file, line);
   620    620       }
   621    621   
   622    622       Tcl_MutexLock(ckallocMutexPtr);
................................................................................
   855    855   	    return TCL_ERROR;
   856    856   	}
   857    857   	break_on_malloc = (unsigned int) value;
   858    858   	return TCL_OK;
   859    859       }
   860    860       if (strcmp(argv[1],"info") == 0) {
   861    861   	Tcl_SetObjResult(interp, Tcl_ObjPrintf(
   862         -		"%-25s %10u\n%-25s %10u\n%-25s %10u\n%-25s %10" TCL_LL_MODIFIER"d\n%-25s %10u\n%-25s %10" TCL_LL_MODIFIER "d\n",
          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",
   863    863   		"total mallocs", total_mallocs, "total frees", total_frees,
   864    864   		"current packets allocated", current_malloc_packets,
   865         -		"current bytes allocated", (Tcl_WideInt)current_bytes_malloced,
          865  +		"current bytes allocated", current_bytes_malloced,
   866    866   		"maximum packets allocated", maximum_malloc_packets,
   867         -		"maximum bytes allocated", (Tcl_WideInt)maximum_bytes_malloced));
          867  +		"maximum bytes allocated", maximum_bytes_malloced));
   868    868   	return TCL_OK;
   869    869       }
   870    870       if (strcmp(argv[1], "init") == 0) {
   871    871   	if (argc != 3) {
   872    872   	    goto bad_suboption;
   873    873   	}
   874    874   	init_malloced_bodies = (strcmp(argv[2],"on") == 0);

Changes to generic/tclCmdAH.c.

   160    160    *	A standard Tcl object result.
   161    161    *
   162    162    * Side effects:
   163    163    *	See the user documentation.
   164    164    *
   165    165    *----------------------------------------------------------------------
   166    166    */
   167         -#ifndef TCL_NO_DEPRECATED
          167  +#if !defined(TCL_NO_DEPRECATED) && TCL_MAJOR_VERSION < 9
   168    168   	/* ARGSUSED */
   169    169   int
   170    170   Tcl_CaseObjCmd(
   171    171       ClientData dummy,		/* Not used. */
   172    172       Tcl_Interp *interp,		/* Current interpreter. */
   173    173       int objc,			/* Number of arguments. */
   174    174       Tcl_Obj *const objv[])	/* Argument objects. */
................................................................................
   508    508   {
   509    509       if (objc != 1) {
   510    510   	Tcl_WrongNumArgs(interp, 1, objv, NULL);
   511    511   	return TCL_ERROR;
   512    512       }
   513    513       return TCL_CONTINUE;
   514    514   }
   515         -
   516         -/*
   517         - *----------------------------------------------------------------------
   518         - *
   519         - * Tcl_EncodingObjCmd --
   520         - *
   521         - *	This command manipulates encodings.
   522         - *
   523         - * Results:
   524         - *	A standard Tcl result.
   525         - *
   526         - * Side effects:
   527         - *	See the user documentation.
   528         - *
   529         - *----------------------------------------------------------------------
   530         - */
   531         -
   532         -int
   533         -Tcl_EncodingObjCmd(
   534         -    ClientData dummy,		/* Not used. */
   535         -    Tcl_Interp *interp,		/* Current interpreter. */
   536         -    int objc,			/* Number of arguments. */
   537         -    Tcl_Obj *const objv[])	/* Argument objects. */
   538         -{
   539         -    int index;
   540         -
   541         -    static const char *const optionStrings[] = {
   542         -	"convertfrom", "convertto", "dirs", "names", "system",
   543         -	NULL
   544         -    };
   545         -    enum options {
   546         -	ENC_CONVERTFROM, ENC_CONVERTTO, ENC_DIRS, ENC_NAMES, ENC_SYSTEM
   547         -    };
   548         -
   549         -    if (objc < 2) {
   550         -	Tcl_WrongNumArgs(interp, 1, objv, "option ?arg ...?");
   551         -	return TCL_ERROR;
   552         -    }
   553         -    if (Tcl_GetIndexFromObj(interp, objv[1], optionStrings, "option", 0,
   554         -	    &index) != TCL_OK) {
   555         -	return TCL_ERROR;
   556         -    }
   557         -
   558         -    switch ((enum options) index) {
   559         -    case ENC_CONVERTTO:
   560         -	return EncodingConverttoObjCmd(dummy, interp, objc, objv);
   561         -    case ENC_CONVERTFROM:
   562         -	return EncodingConvertfromObjCmd(dummy, interp, objc, objv);
   563         -    case ENC_DIRS:
   564         -	return EncodingDirsObjCmd(dummy, interp, objc, objv);
   565         -    case ENC_NAMES:
   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    515   
   573    516   /*
   574    517    *-----------------------------------------------------------------------------
   575    518    *
   576    519    * TclInitEncodingCmd --
   577    520    *
   578    521    *	This function creates the 'encoding' ensemble.

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   
................................................................................
  2539   2532   Tcl_LrangeObjCmd(
  2540   2533       ClientData notUsed,		/* Not used. */
  2541   2534       Tcl_Interp *interp,		/* Current interpreter. */
  2542   2535       int objc,			/* Number of arguments. */
  2543   2536       register Tcl_Obj *const objv[])
  2544   2537   				/* Argument objects. */
  2545   2538   {
  2546         -    Tcl_Obj **elemPtrs;
  2547   2539       int listLen, first, last, result;
  2548   2540   
  2549   2541       if (objc != 4) {
  2550   2542   	Tcl_WrongNumArgs(interp, 1, objv, "list first last");
  2551   2543   	return TCL_ERROR;
  2552   2544       }
  2553   2545   
................................................................................
  2557   2549       }
  2558   2550   
  2559   2551       result = TclGetIntForIndexM(interp, objv[2], /*endValue*/ listLen - 1,
  2560   2552   	    &first);
  2561   2553       if (result != TCL_OK) {
  2562   2554   	return result;
  2563   2555       }
  2564         -    if (first < 0) {
  2565         -	first = 0;
  2566         -    }
  2567   2556   
  2568   2557       result = TclGetIntForIndexM(interp, objv[3], /*endValue*/ listLen - 1,
  2569   2558   	    &last);
  2570   2559       if (result != TCL_OK) {
  2571   2560   	return result;
  2572   2561       }
  2573         -    if (last >= listLen) {
  2574         -	last = listLen - 1;
  2575         -    }
  2576   2562   
  2577         -    if (first > last) {
  2578         -	/*
  2579         -	 * Returning an empty list is easy.
  2580         -	 */
  2581         -
  2582         -	return TCL_OK;
  2583         -    }
  2584         -
  2585         -    result = TclListObjGetElements(interp, objv[1], &listLen, &elemPtrs);
  2586         -    if (result != TCL_OK) {
  2587         -	return result;
  2588         -    }
  2589         -
  2590         -    if (Tcl_IsShared(objv[1]) ||
  2591         -	    ((ListRepPtr(objv[1])->refCount > 1))) {
  2592         -	Tcl_SetObjResult(interp, Tcl_NewListObj(last - first + 1,
  2593         -		&elemPtrs[first]));
  2594         -    } else {
  2595         -	/*
  2596         -	 * In-place is possible.
  2597         -	 */
  2598         -
  2599         -	if (last < (listLen - 1)) {
  2600         -	    Tcl_ListObjReplace(interp, objv[1], last + 1, listLen - 1 - last,
  2601         -		    0, NULL);
  2602         -	}
  2603         -
  2604         -	/*
  2605         -	 * This one is not conditioned on (first > 0) in order to preserve the
  2606         -	 * string-canonizing effect of [lrange 0 end].
  2607         -	 */
  2608         -
  2609         -	Tcl_ListObjReplace(interp, objv[1], 0, first, 0, NULL);
  2610         -	Tcl_SetObjResult(interp, objv[1]);
  2611         -    }
  2612         -
         2563  +    Tcl_SetObjResult(interp, TclListObjRange(objv[1], first, last));
  2613   2564       return TCL_OK;
  2614   2565   }
  2615   2566   
  2616   2567   /*
  2617   2568    *----------------------------------------------------------------------
  2618   2569    *
  2619   2570    * Tcl_LrepeatObjCmd --
................................................................................
  2783   2734       /*
  2784   2735        * Complain if the user asked for a start element that is greater than the
  2785   2736        * list length. This won't ever trigger for the "end-*" case as that will
  2786   2737        * be properly constrained by TclGetIntForIndex because we use listLen-1
  2787   2738        * (to allow for replacing the last elem).
  2788   2739        */
  2789   2740   
  2790         -    if ((first > listLen) && (listLen > 0)) {
         2741  +    if ((first >= listLen) && (listLen > 0)) {
  2791   2742   	Tcl_SetObjResult(interp, Tcl_ObjPrintf(
  2792   2743   		"list doesn't contain element %s", TclGetString(objv[2])));
  2793   2744   	Tcl_SetErrorCode(interp, "TCL", "OPERATION", "LREPLACE", "BADIDX",
  2794   2745   		NULL);
  2795   2746   	return TCL_ERROR;
  2796   2747       }
  2797   2748       if (last >= listLen) {
................................................................................
  2934   2885   Tcl_LsearchObjCmd(
  2935   2886       ClientData clientData,	/* Not used. */
  2936   2887       Tcl_Interp *interp,		/* Current interpreter. */
  2937   2888       int objc,			/* Number of arguments. */
  2938   2889       Tcl_Obj *const objv[])	/* Argument values. */
  2939   2890   {
  2940   2891       const char *bytes, *patternBytes;
  2941         -    int i, match, index, result, listc, length, elemLen, bisect;
  2942         -    int dataType, isIncreasing, lower, upper, offset;
         2892  +    int i, match, index, result=TCL_OK, listc, length, elemLen, bisect;
         2893  +    int allocatedIndexVector = 0;
         2894  +    int dataType, isIncreasing, lower, upper, start, groupSize, groupOffset;
  2943   2895       Tcl_WideInt patWide, objWide;
  2944   2896       int allMatches, inlineReturn, negatedMatch, returnSubindices, noCase;
  2945   2897       double patDouble, objDouble;
  2946   2898       SortInfo sortInfo;
  2947   2899       Tcl_Obj *patObj, **listv, *listPtr, *startPtr, *itemPtr;
  2948         -    SortStrCmpFn_t strCmpFn = strcmp;
         2900  +    SortStrCmpFn_t strCmpFn = TclUtfCmp;
  2949   2901       Tcl_RegExp regexp = NULL;
  2950   2902       static const char *const options[] = {
  2951   2903   	"-all",	    "-ascii",   "-bisect", "-decreasing", "-dictionary",
  2952   2904   	"-exact",   "-glob",    "-increasing", "-index",
  2953   2905   	"-inline",  "-integer", "-nocase",     "-not",
  2954         -	"-real",    "-regexp",  "-sorted",     "-start",
         2906  +	"-real",    "-regexp",  "-sorted",     "-start", "-stride",
  2955   2907   	"-subindices", NULL
  2956   2908       };
  2957   2909       enum options {
  2958   2910   	LSEARCH_ALL, LSEARCH_ASCII, LSEARCH_BISECT, LSEARCH_DECREASING,
  2959   2911   	LSEARCH_DICTIONARY, LSEARCH_EXACT, LSEARCH_GLOB, LSEARCH_INCREASING,
  2960   2912   	LSEARCH_INDEX, LSEARCH_INLINE, LSEARCH_INTEGER, LSEARCH_NOCASE,
  2961   2913   	LSEARCH_NOT, LSEARCH_REAL, LSEARCH_REGEXP, LSEARCH_SORTED,
  2962         -	LSEARCH_START, LSEARCH_SUBINDICES
         2914  +	LSEARCH_START, LSEARCH_STRIDE, LSEARCH_SUBINDICES
  2963   2915       };
  2964   2916       enum datatypes {
  2965   2917   	ASCII, DICTIONARY, INTEGER, REAL
  2966   2918       };
  2967   2919       enum modes {
  2968   2920   	EXACT, GLOB, REGEXP, SORTED
  2969   2921       };
................................................................................
  2975   2927       allMatches = 0;
  2976   2928       inlineReturn = 0;
  2977   2929       returnSubindices = 0;
  2978   2930       negatedMatch = 0;
  2979   2931       bisect = 0;
  2980   2932       listPtr = NULL;
  2981   2933       startPtr = NULL;
  2982         -    offset = 0;
         2934  +    groupSize = 1;
         2935  +    groupOffset = 0;
         2936  +    start = 0;
  2983   2937       noCase = 0;
  2984   2938       sortInfo.compareCmdPtr = NULL;
  2985   2939       sortInfo.isIncreasing = 1;
  2986   2940       sortInfo.sortMode = 0;
  2987   2941       sortInfo.interp = interp;
  2988   2942       sortInfo.resultCode = TCL_OK;
  2989   2943       sortInfo.indexv = NULL;
................................................................................
  2993   2947   	Tcl_WrongNumArgs(interp, 1, objv, "?-option value ...? list pattern");
  2994   2948   	return TCL_ERROR;
  2995   2949       }
  2996   2950   
  2997   2951       for (i = 1; i < objc-2; i++) {
  2998   2952   	if (Tcl_GetIndexFromObj(interp, objv[i], options, "option", 0, &index)
  2999   2953   		!= TCL_OK) {
  3000         -	    if (startPtr != NULL) {
  3001         -		Tcl_DecrRefCount(startPtr);
  3002         -	    }
  3003   2954   	    result = TCL_ERROR;
  3004   2955   	    goto done;
  3005   2956   	}
  3006   2957   	switch ((enum options) index) {
  3007   2958   	case LSEARCH_ALL:		/* -all */
  3008   2959   	    allMatches = 1;
  3009   2960   	    break;
................................................................................
  3060   3011   	    /*
  3061   3012   	     * If there was a previous -start option, release its saved index
  3062   3013   	     * because it will either be replaced or there will be an error.
  3063   3014   	     */
  3064   3015   
  3065   3016   	    if (startPtr != NULL) {
  3066   3017   		Tcl_DecrRefCount(startPtr);
         3018  +		startPtr = NULL;
  3067   3019   	    }
  3068   3020   	    if (i > objc-4) {
  3069   3021   		Tcl_SetObjResult(interp, Tcl_NewStringObj(
  3070   3022   			"missing starting index", -1));
  3071   3023   		Tcl_SetErrorCode(interp, "TCL", "ARGUMENT", "MISSING", NULL);
  3072   3024   		result = TCL_ERROR;
  3073   3025   		goto done;
................................................................................
  3080   3032   		 * being searched. We only need to copy where the list and the
  3081   3033   		 * index are one-and-the-same.
  3082   3034   		 */
  3083   3035   
  3084   3036   		startPtr = Tcl_DuplicateObj(objv[i]);
  3085   3037   	    } else {
  3086   3038   		startPtr = objv[i];
  3087         -		Tcl_IncrRefCount(startPtr);
  3088   3039   	    }
         3040  +	    Tcl_IncrRefCount(startPtr);
         3041  +	    break;
         3042  +	case LSEARCH_STRIDE:		/* -stride */
         3043  +	    if (i > objc-4) {
         3044  +		Tcl_SetObjResult(interp, Tcl_NewStringObj(
         3045  +			"\"-stride\" option must be "
         3046  +			"followed by stride length", -1));
         3047  +		Tcl_SetErrorCode(interp, "TCL", "ARGUMENT", "MISSING", NULL);
         3048  +		result = TCL_ERROR;
         3049  +		goto done;
         3050  +	    }
         3051  +	    if (Tcl_GetIntFromObj(interp, objv[i+1], &groupSize) != TCL_OK) {
         3052  +		result = TCL_ERROR;
         3053  +		goto done;
         3054  +	    }
         3055  +	    if (groupSize < 1) {
         3056  +		Tcl_SetObjResult(interp, Tcl_NewStringObj(
         3057  +			"stride length must be at least 1", -1));
         3058  +		Tcl_SetErrorCode(interp, "TCL", "OPERATION", "LSORT",
         3059  +			"BADSTRIDE", NULL);
         3060  +		result = TCL_ERROR;
         3061  +		goto done;
         3062  +	    }
         3063  +	    i++;
  3089   3064   	    break;
  3090   3065   	case LSEARCH_INDEX: {		/* -index */
  3091   3066   	    Tcl_Obj **indices;
  3092   3067   	    int j;
  3093   3068   
  3094         -	    if (sortInfo.indexc > 1) {
         3069  +	    if (allocatedIndexVector) {
  3095   3070   		TclStackFree(interp, sortInfo.indexv);
         3071  +		allocatedIndexVector = 0;
  3096   3072   	    }
  3097   3073   	    if (i > objc-4) {
  3098         -		if (startPtr != NULL) {
  3099         -		    Tcl_DecrRefCount(startPtr);
  3100         -		}
  3101   3074   		Tcl_SetObjResult(interp, Tcl_NewStringObj(
  3102   3075   			"\"-index\" option must be followed by list index",
  3103   3076   			-1));
  3104   3077   		Tcl_SetErrorCode(interp, "TCL", "ARGUMENT", "MISSING", NULL);
  3105         -		return TCL_ERROR;
         3078  +		result = TCL_ERROR;
         3079  +		goto done;
  3106   3080   	    }
  3107   3081   
  3108   3082   	    /*
  3109   3083   	     * Store the extracted indices for processing by sublist
  3110   3084   	     * extraction. Note that we don't do this using objects because
  3111   3085   	     * that has shimmering problems.
  3112   3086   	     */
  3113   3087   
  3114   3088   	    i++;
  3115   3089   	    if (TclListObjGetElements(interp, objv[i],
  3116   3090   		    &sortInfo.indexc, &indices) != TCL_OK) {
  3117         -		if (startPtr != NULL) {
  3118         -		    Tcl_DecrRefCount(startPtr);
  3119         -		}
  3120         -		return TCL_ERROR;
         3091  +		result = TCL_ERROR;
         3092  +		goto done;
  3121   3093   	    }
  3122   3094   	    switch (sortInfo.indexc) {
  3123   3095   	    case 0:
  3124   3096   		sortInfo.indexv = NULL;
  3125   3097   		break;
  3126   3098   	    case 1:
  3127   3099   		sortInfo.indexv = &sortInfo.singleIndex;
  3128   3100   		break;
  3129   3101   	    default:
  3130   3102   		sortInfo.indexv =
  3131   3103   			TclStackAlloc(interp, sizeof(int) * sortInfo.indexc);
         3104  +		allocatedIndexVector = 1; /* Cannot use indexc field, as it
         3105  +					   * might be decreased by 1 later. */
  3132   3106   	    }
  3133   3107   
  3134   3108   	    /*
  3135   3109   	     * Fill the array by parsing each index. We don't know whether
  3136   3110   	     * their scale is sensible yet, but we at least perform the
  3137   3111   	     * syntactic check here.
  3138   3112   	     */
  3139   3113   
  3140   3114   	    for (j=0 ; j<sortInfo.indexc ; j++) {
  3141         -		if (TclGetIntForIndexM(interp, indices[j], SORTIDX_END,
  3142         -			&sortInfo.indexv[j]) != TCL_OK) {
         3115  +		int encoded = 0;
         3116  +		if (TclIndexEncode(interp, indices[j], TCL_INDEX_BEFORE,
         3117  +			TCL_INDEX_AFTER, &encoded) != TCL_OK) {
         3118  +		    result = TCL_ERROR;
         3119  +		}
         3120  +		if ((encoded == TCL_INDEX_BEFORE)
         3121  +			|| (encoded == TCL_INDEX_AFTER)) {
         3122  +		    Tcl_SetObjResult(interp, Tcl_ObjPrintf(
         3123  +			    "index \"%s\" cannot select an element "
         3124  +			    "from any list", Tcl_GetString(indices[j])));
         3125  +		    Tcl_SetErrorCode(interp, "TCL", "VALUE", "INDEX"
         3126  +			    "OUTOFRANGE", NULL);
         3127  +		    result = TCL_ERROR;
         3128  +		}
         3129  +		if (result == TCL_ERROR) {
  3143   3130   		    Tcl_AppendObjToErrorInfo(interp, Tcl_ObjPrintf(
  3144   3131   			    "\n    (-index option item number %d)", j));
  3145         -		    result = TCL_ERROR;
  3146   3132   		    goto done;
  3147   3133   		}
         3134  +		sortInfo.indexv[j] = encoded;
  3148   3135   	    }
  3149   3136   	    break;
  3150   3137   	}
  3151   3138   	}
  3152   3139       }
  3153   3140   
  3154   3141       /*
  3155   3142        * Subindices only make sense if asked for with -index option set.
  3156   3143        */
  3157   3144   
  3158   3145       if (returnSubindices && sortInfo.indexc==0) {
  3159         -	if (startPtr != NULL) {
  3160         -	    Tcl_DecrRefCount(startPtr);
  3161         -	}
  3162   3146   	Tcl_SetObjResult(interp, Tcl_NewStringObj(
  3163   3147   		"-subindices cannot be used without -index option", -1));
  3164   3148   	Tcl_SetErrorCode(interp, "TCL", "OPERATION", "LSEARCH",
  3165   3149   		"BAD_OPTION_MIX", NULL);
  3166         -	return TCL_ERROR;
         3150  +	result = TCL_ERROR;
         3151  +	goto done;
  3167   3152       }
  3168   3153   
  3169   3154       if (bisect && (allMatches || negatedMatch)) {
  3170   3155   	Tcl_SetObjResult(interp, Tcl_NewStringObj(
  3171   3156   		"-bisect is not compatible with -all or -not", -1));
  3172   3157   	Tcl_SetErrorCode(interp, "TCL", "OPERATION", "LSEARCH",
  3173   3158   		"BAD_OPTION_MIX", NULL);
  3174         -	return TCL_ERROR;
         3159  +	result = TCL_ERROR;
         3160  +	goto done;
  3175   3161       }
  3176   3162   
  3177   3163       if (mode == REGEXP) {
  3178   3164   	/*
  3179   3165   	 * We can shimmer regexp/list if listv[i] == pattern, so get the
  3180   3166   	 * regexp rep before the list rep. First time round, omit the interp
  3181   3167   	 * and hope that the compilation will succeed. If it fails, we'll
................................................................................
  3193   3179   	     */
  3194   3180   
  3195   3181   	    regexp = Tcl_GetRegExpFromObj(interp, objv[objc - 1],
  3196   3182   		    TCL_REG_ADVANCED | (noCase ? TCL_REG_NOCASE : 0));
  3197   3183   	}
  3198   3184   
  3199   3185   	if (regexp == NULL) {
  3200         -	    if (startPtr != NULL) {
  3201         -		Tcl_DecrRefCount(startPtr);
  3202         -	    }
  3203   3186   	    result = TCL_ERROR;
  3204   3187   	    goto done;
  3205   3188   	}
  3206   3189       }
  3207   3190   
  3208   3191       /*
  3209   3192        * Make sure the list argument is a list object and get its length and a
  3210   3193        * pointer to its array of element pointers.
  3211   3194        */
  3212   3195   
  3213   3196       result = TclListObjGetElements(interp, objv[objc - 2], &listc, &listv);
  3214   3197       if (result != TCL_OK) {
  3215         -	if (startPtr != NULL) {
  3216         -	    Tcl_DecrRefCount(startPtr);
  3217         -	}
  3218   3198   	goto done;
  3219   3199       }
         3200  +
         3201  +    /*
         3202  +     * Check for sanity when grouping elements of the overall list together
         3203  +     * because of the -stride option. [TIP #351]
         3204  +     */
         3205  +
         3206  +    if (groupSize > 1) {
         3207  +	if (listc % groupSize) {
         3208  +	    Tcl_SetObjResult(interp, Tcl_NewStringObj(
         3209  +		    "list size must be a multiple of the stride length",
         3210  +		    -1));
         3211  +	    Tcl_SetErrorCode(interp, "TCL", "OPERATION", "LSEARCH", "BADSTRIDE",
         3212  +		    NULL);
         3213  +	    result = TCL_ERROR;
         3214  +	    goto done;
         3215  +	}
         3216  +	if (sortInfo.indexc > 0) {
         3217  +	    /*
         3218  +	     * Use the first value in the list supplied to -index as the
         3219  +	     * offset of the element within each group by which to sort.
         3220  +	     */
         3221  +
         3222  +	    groupOffset = TclIndexDecode(sortInfo.indexv[0], groupSize - 1);
         3223  +	    if (groupOffset < 0 || groupOffset >= groupSize) {
         3224  +		Tcl_SetObjResult(interp, Tcl_NewStringObj(
         3225  +			"when used with \"-stride\", the leading \"-index\""
         3226  +			" value must be within the group", -1));
         3227  +		Tcl_SetErrorCode(interp, "TCL", "OPERATION", "LSEARCH",
         3228  +			"BADINDEX", NULL);
         3229  +		result = TCL_ERROR;
         3230  +		goto done;
         3231  +	    }
         3232  +	    if (sortInfo.indexc == 1) {
         3233  +		sortInfo.indexc = 0;
         3234  +		sortInfo.indexv = NULL;
         3235  +	    } else {
         3236  +		sortInfo.indexc--;
         3237  +
         3238  +		for (i = 0; i < sortInfo.indexc; i++) {
         3239  +		    sortInfo.indexv[i] = sortInfo.indexv[i+1];
         3240  +		}
         3241  +	    }
         3242  +	}
         3243  +    }
  3220   3244   
  3221   3245       /*
  3222   3246        * Get the user-specified start offset.
  3223   3247        */
  3224   3248   
  3225   3249       if (startPtr) {
  3226         -	result = TclGetIntForIndexM(interp, startPtr, listc-1, &offset);
  3227         -	Tcl_DecrRefCount(startPtr);
         3250  +	result = TclGetIntForIndexM(interp, startPtr, listc-1, &start);
  3228   3251   	if (result != TCL_OK) {
  3229   3252   	    goto done;
  3230   3253   	}
  3231         -	if (offset < 0) {
  3232         -	    offset = 0;
         3254  +	if (start < 0) {
         3255  +	    start = 0;
  3233   3256   	}
  3234   3257   
  3235   3258   	/*
  3236   3259   	 * If the search started past the end of the list, we just return a
  3237   3260   	 * "did not match anything at all" result straight away. [Bug 1374778]
  3238   3261   	 */
  3239   3262   
  3240         -	if (offset > listc-1) {
  3241         -	    if (sortInfo.indexc > 1) {
  3242         -		TclStackFree(interp, sortInfo.indexv);
  3243         -	    }
         3263  +	if (start > listc-1) {
  3244   3264   	    if (allMatches || inlineReturn) {
  3245   3265   		Tcl_ResetResult(interp);
  3246   3266   	    } else {
  3247   3267   		Tcl_SetObjResult(interp, Tcl_NewIntObj(-1));
  3248   3268   	    }
  3249         -	    return TCL_OK;
         3269  +	    goto done;
         3270  +	}
         3271  +
         3272  +	/*
         3273  +	 * If start points within a group, it points to the start of the group.
         3274  +	 */
         3275  +
         3276  +	if (groupSize > 1) {
         3277  +	    start -= (start % groupSize);
  3250   3278   	}
  3251   3279       }
  3252   3280   
  3253   3281       patObj = objv[objc - 1];
  3254   3282       patternBytes = NULL;
  3255   3283       if (mode == EXACT || mode == SORTED) {
  3256   3284   	switch ((enum datatypes) dataType) {
................................................................................
  3301   3329   	/*
  3302   3330   	 * If the data is sorted, we can do a more intelligent search. Note
  3303   3331   	 * that there is no point in being smart when -all was specified; in
  3304   3332   	 * that case, we have to look at all items anyway, and there is no
  3305   3333   	 * sense in doing this when the match sense is inverted.
  3306   3334   	 */
  3307   3335   
  3308         -	lower = offset - 1;
         3336  +	/*
         3337  +	 * With -stride, lower, upper and i are kept as multiples of groupSize.
         3338  +	 */
         3339  +
         3340  +	lower = start - groupSize;
  3309   3341   	upper = listc;
  3310         -	while (lower + 1 != upper && sortInfo.resultCode == TCL_OK) {
         3342  +	while (lower + groupSize != upper && sortInfo.resultCode == TCL_OK) {
  3311   3343   	    i = (lower + upper)/2;
         3344  +	    i -= i % groupSize;
  3312   3345   	    if (sortInfo.indexc != 0) {
  3313         -		itemPtr = SelectObjFromSublist(listv[i], &sortInfo);
         3346  +		itemPtr = SelectObjFromSublist(listv[i+groupOffset], &sortInfo);
  3314   3347   		if (sortInfo.resultCode != TCL_OK) {
  3315   3348   		    result = sortInfo.resultCode;
  3316   3349   		    goto done;
  3317   3350   		}
  3318   3351   	    } else {
  3319         -		itemPtr = listv[i];
         3352  +		itemPtr = listv[i+groupOffset];
  3320   3353   	    }
  3321   3354   	    switch ((enum datatypes) dataType) {
  3322   3355   	    case ASCII:
  3323   3356   		bytes = TclGetString(itemPtr);
  3324   3357   		match = strCmpFn(patternBytes, bytes);
  3325   3358   		break;
  3326   3359   	    case DICTIONARY:
................................................................................
  3401   3434   	 *   - our matching sense is negated
  3402   3435   	 *   - we're building a list of all matched items
  3403   3436   	 */
  3404   3437   
  3405   3438   	if (allMatches) {
  3406   3439   	    listPtr = Tcl_NewListObj(0, NULL);
  3407   3440   	}
  3408         -	for (i = offset; i < listc; i++) {
         3441  +	for (i = start; i < listc; i += groupSize) {
  3409   3442   	    match = 0;
  3410   3443   	    if (sortInfo.indexc != 0) {
  3411         -		itemPtr = SelectObjFromSublist(listv[i], &sortInfo);
         3444  +		itemPtr = SelectObjFromSublist(listv[i+groupOffset], &sortInfo);
  3412   3445   		if (sortInfo.resultCode != TCL_OK) {
  3413   3446   		    if (listPtr != NULL) {
  3414   3447   			Tcl_DecrRefCount(listPtr);
  3415   3448   		    }
  3416   3449   		    result = sortInfo.resultCode;
  3417   3450   		    goto done;
  3418   3451   		}
  3419   3452   	    } else {
  3420         -		itemPtr = listv[i];
         3453  +		itemPtr = listv[i+groupOffset];
  3421   3454   	    }
  3422   3455   
  3423   3456   	    switch (mode) {
  3424   3457   	    case SORTED:
  3425   3458   	    case EXACT:
  3426   3459   		switch ((enum datatypes) dataType) {
  3427   3460   		case ASCII:
................................................................................
  3503   3536   		break;
  3504   3537   	    } else if (inlineReturn) {
  3505   3538   		/*
  3506   3539   		 * Note that these appends are not expected to fail.
  3507   3540   		 */
  3508   3541   
  3509   3542   		if (returnSubindices && (sortInfo.indexc != 0)) {
  3510         -		    itemPtr = SelectObjFromSublist(listv[i], &sortInfo);
         3543  +		    itemPtr = SelectObjFromSublist(listv[i+groupOffset],
         3544  +			    &sortInfo);
         3545  +		    Tcl_ListObjAppendElement(interp, listPtr, itemPtr);
         3546  +		} else if (groupSize > 1) {
         3547  +		    Tcl_ListObjReplace(interp, listPtr, LIST_MAX, 0,
         3548  +			    groupSize, &listv[i]);
  3511   3549   		} else {
  3512   3550   		    itemPtr = listv[i];
         3551  +		    Tcl_ListObjAppendElement(interp, listPtr, itemPtr);
  3513   3552   		}
  3514         -		Tcl_ListObjAppendElement(interp, listPtr, itemPtr);
  3515   3553   	    } else if (returnSubindices) {
  3516   3554   		int j;
  3517   3555   
  3518         -		itemPtr = Tcl_NewIntObj(i);
         3556  +		itemPtr = Tcl_NewIntObj(i+groupOffset);
  3519   3557   		for (j=0 ; j<sortInfo.indexc ; j++) {
  3520         -		    Tcl_ListObjAppendElement(interp, itemPtr,
  3521         -			    Tcl_NewIntObj(sortInfo.indexv[j]));
         3558  +		    Tcl_ListObjAppendElement(interp, itemPtr, Tcl_NewIntObj(
         3559  +			    TclIndexDecode(sortInfo.indexv[j], listc)));
  3522   3560   		}
  3523   3561   		Tcl_ListObjAppendElement(interp, listPtr, itemPtr);
  3524   3562   	    } else {
  3525   3563   		Tcl_ListObjAppendElement(interp, listPtr, Tcl_NewIntObj(i));
  3526   3564   	    }
  3527   3565   	}
  3528   3566       }
................................................................................
  3533   3571   
  3534   3572       if (allMatches) {
  3535   3573   	Tcl_SetObjResult(interp, listPtr);
  3536   3574       } else if (!inlineReturn) {
  3537   3575   	if (returnSubindices) {
  3538   3576   	    int j;
  3539   3577   
  3540         -	    itemPtr = Tcl_NewIntObj(index);
         3578  +	    itemPtr = Tcl_NewIntObj(index+groupOffset);
  3541   3579   	    for (j=0 ; j<sortInfo.indexc ; j++) {
  3542         -		Tcl_ListObjAppendElement(interp, itemPtr,
  3543         -			Tcl_NewIntObj(sortInfo.indexv[j]));
         3580  +		Tcl_ListObjAppendElement(interp, itemPtr, Tcl_NewIntObj(
         3581  +			TclIndexDecode(sortInfo.indexv[j], listc)));
  3544   3582   	    }
  3545   3583   	    Tcl_SetObjResult(interp, itemPtr);
  3546   3584   	} else {
  3547   3585   	    Tcl_SetObjResult(interp, Tcl_NewIntObj(index));
  3548   3586   	}
  3549   3587       } else if (index < 0) {
  3550   3588   	/*
  3551   3589   	 * Is this superfluous? The result should be a blank object by
  3552   3590   	 * default...
  3553   3591   	 */
  3554   3592   
  3555   3593   	Tcl_SetObjResult(interp, Tcl_NewObj());
  3556   3594       } else {
  3557         -	Tcl_SetObjResult(interp, listv[index]);
         3595  +	if (returnSubindices) {
         3596  +	    Tcl_SetObjResult(interp, SelectObjFromSublist(listv[i+groupOffset],
         3597  +		    &sortInfo));
         3598  +	} else if (groupSize > 1) {
         3599  +	    Tcl_SetObjResult(interp, Tcl_NewListObj(groupSize, &listv[index]));
         3600  +	} else {
         3601  +	    Tcl_SetObjResult(interp, listv[index]);
         3602  +	}
  3558   3603       }
  3559   3604       result = TCL_OK;
  3560   3605   
  3561   3606       /*
  3562   3607        * Cleanup the index list array.
  3563   3608        */
  3564   3609   
  3565   3610     done:
  3566         -    if (sortInfo.indexc > 1) {
         3611  +    if (startPtr != NULL) {
         3612  +	Tcl_DecrRefCount(startPtr);
         3613  +    }
         3614  +    if (allocatedIndexVector) {
  3567   3615   	TclStackFree(interp, sortInfo.indexv);
  3568   3616       }
  3569   3617       return result;
  3570   3618   }
  3571   3619   
  3572   3620   /*
  3573   3621    *----------------------------------------------------------------------
................................................................................
  3753   3801   	case LSORT_DICTIONARY:
  3754   3802   	    sortInfo.sortMode = SORTMODE_DICTIONARY;
  3755   3803   	    break;
  3756   3804   	case LSORT_INCREASING:
  3757   3805   	    sortInfo.isIncreasing = 1;
  3758   3806   	    break;
  3759   3807   	case LSORT_INDEX: {
  3760         -	    int indexc, dummy;
         3808  +	    int indexc;
  3761   3809   	    Tcl_Obj **indexv;
  3762   3810   
  3763   3811   	    if (i == objc-2) {
  3764   3812   		Tcl_SetObjResult(interp, Tcl_NewStringObj(
  3765   3813   			"\"-index\" option must be followed by list index",
  3766   3814   			-1));
  3767   3815   		Tcl_SetErrorCode(interp, "TCL", "ARGUMENT", "MISSING", NULL);
................................................................................
  3779   3827   	     * we do not store the converted values here because we do not
  3780   3828   	     * know if this is the only -index option yet and so we can't
  3781   3829   	     * allocate any space; that happens after the scan through all the
  3782   3830   	     * options is done.
  3783   3831   	     */
  3784   3832   
  3785   3833   	    for (j=0 ; j<indexc ; j++) {
  3786         -		if (TclGetIntForIndexM(interp, indexv[j], SORTIDX_END,
  3787         -			&dummy) != TCL_OK) {
         3834  +		int encoded = 0;
         3835  +		int result = TclIndexEncode(interp, indexv[j],
         3836  +			TCL_INDEX_BEFORE, TCL_INDEX_AFTER, &encoded);
         3837  +
         3838  +		if ((result == TCL_OK) && ((encoded == TCL_INDEX_BEFORE)
         3839  +			|| (encoded == TCL_INDEX_AFTER))) {
         3840  +		    Tcl_SetObjResult(interp, Tcl_ObjPrintf(
         3841  +			    "index \"%s\" cannot select an element "
         3842  +			    "from any list", Tcl_GetString(indexv[j])));
         3843  +		    Tcl_SetErrorCode(interp, "TCL", "VALUE", "INDEX"
         3844  +			    "OUTOFRANGE", NULL);
         3845  +		    result = TCL_ERROR;
         3846  +		}
         3847  +		if (result == TCL_ERROR) {
  3788   3848   		    Tcl_AppendObjToErrorInfo(interp, Tcl_ObjPrintf(
  3789   3849   			    "\n    (-index option item number %d)", j));
  3790   3850   		    sortInfo.resultCode = TCL_ERROR;
  3791   3851   		    goto done;
  3792   3852   		}
  3793   3853   	    }
  3794   3854   	    indexPtr = objv[i+1];
................................................................................
  3860   3920   	default:
  3861   3921   	    sortInfo.indexv =
  3862   3922   		    TclStackAlloc(interp, sizeof(int) * sortInfo.indexc);
  3863   3923   	    allocatedIndexVector = 1;	/* Cannot use indexc field, as it
  3864   3924   					 * might be decreased by 1 later. */
  3865   3925   	}
  3866   3926   	for (j=0 ; j<sortInfo.indexc ; j++) {
  3867         -	    TclGetIntForIndexM(interp, indexv[j], SORTIDX_END,
  3868         -		    &sortInfo.indexv[j]);
         3927  +	    /* Prescreened values, no errors or out of range possible */
         3928  +	    TclIndexEncode(NULL, indexv[j], 0, 0, &sortInfo.indexv[j]);
  3869   3929   	}
  3870   3930       }
  3871   3931   
  3872   3932       listObj = objv[objc-1];
  3873   3933   
  3874   3934       if (sortInfo.sortMode == SORTMODE_COMMAND) {
  3875   3935   	Tcl_Obj *newCommandPtr, *newObjPtr;
................................................................................
  3932   3992   	length = length / groupSize;
  3933   3993   	if (sortInfo.indexc > 0) {
  3934   3994   	    /*
  3935   3995   	     * Use the first value in the list supplied to -index as the
  3936   3996   	     * offset of the element within each group by which to sort.
  3937   3997   	     */
  3938   3998   
  3939         -	    groupOffset = sortInfo.indexv[0];
  3940         -	    if (groupOffset <= SORTIDX_END) {
  3941         -		groupOffset = (groupOffset - SORTIDX_END) + groupSize - 1;
  3942         -	    }
         3999  +	    groupOffset = TclIndexDecode(sortInfo.indexv[0], groupSize - 1);
  3943   4000   	    if (groupOffset < 0 || groupOffset >= groupSize) {
  3944   4001   		Tcl_SetObjResult(interp, Tcl_NewStringObj(
  3945   4002   			"when used with \"-stride\", the leading \"-index\""
  3946   4003   			" value must be within the group", -1));
  3947   4004   		Tcl_SetErrorCode(interp, "TCL", "OPERATION", "LSORT",
  3948   4005   			"BADINDEX", NULL);
  3949   4006   		sortInfo.resultCode = TCL_ERROR;
................................................................................
  3954   4011   		sortInfo.indexv = NULL;
  3955   4012   	    } else {
  3956   4013   		sortInfo.indexc--;
  3957   4014   
  3958   4015   		/*
  3959   4016   		 * Do not shrink the actual memory block used; that doesn't
  3960   4017   		 * work with TclStackAlloc-allocated memory. [Bug 2918962]
         4018  +		 *
         4019  +		 * TODO: Consider a pointer increment to replace this
         4020  +		 * array shift.
  3961   4021   		 */
  3962   4022   
  3963   4023   		for (i = 0; i < sortInfo.indexc; i++) {
  3964   4024   		    sortInfo.indexv[i] = sortInfo.indexv[i+1];
  3965   4025   		}
  3966   4026   	    }
  3967   4027   	}
................................................................................
  4259   4319   				/* Values to be compared. */
  4260   4320       SortInfo *infoPtr)		/* Information passed from the top-level
  4261   4321   				 * "lsort" command. */
  4262   4322   {
  4263   4323       int order = 0;
  4264   4324   
  4265   4325       if (infoPtr->sortMode == SORTMODE_ASCII) {
  4266         -	order = strcmp(elemPtr1->collationKey.strValuePtr,
         4326  +	order = TclUtfCmp(elemPtr1->collationKey.strValuePtr,
  4267   4327   		elemPtr2->collationKey.strValuePtr);
  4268   4328       } else if (infoPtr->sortMode == SORTMODE_ASCII_NC) {
  4269   4329   	order = TclUtfCasecmp(elemPtr1->collationKey.strValuePtr,
  4270   4330   		elemPtr2->collationKey.strValuePtr);
  4271   4331       } else if (infoPtr->sortMode == SORTMODE_DICTIONARY) {
  4272   4332   	order = DictionaryCompare(elemPtr1->collationKey.strValuePtr,
  4273   4333   		elemPtr2->collationKey.strValuePtr);
................................................................................
  4522   4582   	int listLen, index;
  4523   4583   	Tcl_Obj *currentObj;
  4524   4584   
  4525   4585   	if (TclListObjLength(infoPtr->interp, objPtr, &listLen) != TCL_OK) {
  4526   4586   	    infoPtr->resultCode = TCL_ERROR;
  4527   4587   	    return NULL;
  4528   4588   	}
  4529         -	index = infoPtr->indexv[i];
  4530   4589   
  4531         -	/*
  4532         -	 * Adjust for end-based indexing.
  4533         -	 */
  4534         -
  4535         -	if (index < SORTIDX_NONE) {
  4536         -	    index += listLen + 1;
  4537         -	}
         4590  +	index = TclIndexDecode(infoPtr->indexv[i], listLen - 1);
  4538   4591   
  4539   4592   	if (Tcl_ListObjIndex(infoPtr->interp, objPtr, index,
  4540   4593   		&currentObj) != TCL_OK) {
  4541   4594   	    infoPtr->resultCode = TCL_ERROR;
  4542   4595   	    return NULL;
  4543   4596   	}
  4544   4597   	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);
................................................................................
   487    487       Tcl_Obj *const objv[])	/* Argument objects. */
   488    488   {
   489    489       int idx, result, cflags, all, wlen, wsublen, numMatches, offset;
   490    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         -    Tcl_UniChar ch, *wsrc, *wfirstChar, *wstring, *wsubspec, *wend;
          494  +    Tcl_UniChar ch, *wsrc, *wfirstChar, *wstring, *wsubspec = 0, *wend;
   495    495   
   496    496       static const char *const options[] = {
   497    497   	"-all",		"-command",	"-expanded",	"-line",
   498    498   	"-linestop",	"-lineanchor",	"-nocase",	"-start",
   499    499   	"--",		NULL
   500    500       };
   501    501       enum options {
................................................................................
   593    593   	    && (strpbrk(TclGetString(objv[2]), "&\\") == NULL)
   594    594   	    && (strpbrk(TclGetString(objv[0]), "*+?{}()[].\\|^$") == NULL)) {
   595    595   	/*
   596    596   	 * This is a simple one pair string map situation. We make use of a
   597    597   	 * slightly modified version of the one pair STR_MAP code.
   598    598   	 */
   599    599   
   600         -	int slen, nocase;
          600  +	int slen, nocase, wsrclc;
   601    601   	int (*strCmpFn)(const Tcl_UniChar*,const Tcl_UniChar*,unsigned long);
   602         -	Tcl_UniChar *p, wsrclc;
          602  +	Tcl_UniChar *p;
   603    603   
   604    604   	numMatches = 0;
   605    605   	nocase = (cflags & TCL_REG_NOCASE);
   606    606   	strCmpFn = nocase ? Tcl_UniCharNcasecmp : Tcl_UniCharNcmp;
   607    607   
   608    608   	wsrc = Tcl_GetUnicodeFromObj(objv[0], &slen);
   609    609   	wstring = Tcl_GetUnicodeFromObj(objv[1], &wlen);
................................................................................
  1212   1212   	 * is a *major* win when splitting on a long string (especially in the
  1213   1213   	 * megabyte range!) - DKF
  1214   1214   	 */
  1215   1215   
  1216   1216   	Tcl_InitHashTable(&charReuseTable, TCL_ONE_WORD_KEYS);
  1217   1217   
  1218   1218   	for ( ; stringPtr < end; stringPtr += len) {
         1219  +		int fullchar;
  1219   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
  1220   1229   
  1221   1230   	    /*
  1222   1231   	     * Assume Tcl_UniChar is an integral type...
  1223   1232   	     */
  1224   1233   
  1225         -	    hPtr = Tcl_CreateHashEntry(&charReuseTable, INT2PTR((int) ch),
         1234  +	    hPtr = Tcl_CreateHashEntry(&charReuseTable, INT2PTR(fullchar),
  1226   1235   		    &isNew);
  1227   1236   	    if (isNew) {
  1228   1237   		TclNewStringObj(objPtr, stringPtr, len);
  1229   1238   
  1230   1239   		/*
  1231   1240   		 * Don't need to fiddle with refcount...
  1232   1241   		 */
................................................................................
  1322   1331   
  1323   1332       if (objc == 4) {
  1324   1333   	int size = Tcl_GetCharLength(objv[2]);
  1325   1334   
  1326   1335   	if (TCL_OK != TclGetIntForIndexM(interp, objv[3], size - 1, &start)) {
  1327   1336   	    return TCL_ERROR;
  1328   1337   	}
  1329         -
  1330         -	if (start < 0) {
  1331         -	    start = 0;
  1332         -	}
  1333         -	if (start >= size) {
  1334         -	    Tcl_SetObjResult(interp, Tcl_NewIntObj(-1));
  1335         -	    return TCL_OK;
  1336         -	}
  1337   1338       }
  1338         -    Tcl_SetObjResult(interp, Tcl_NewIntObj(TclStringFind(objv[1],
         1339  +    Tcl_SetObjResult(interp, Tcl_NewIntObj(TclStringFirst(objv[1],
  1339   1340   	    objv[2], start)));
  1340   1341       return TCL_OK;
  1341   1342   }
  1342   1343   
  1343   1344   /*
  1344   1345    *----------------------------------------------------------------------
  1345   1346    *
................................................................................
  1375   1376   
  1376   1377       if (objc == 4) {
  1377   1378   	int size = Tcl_GetCharLength(objv[2]);
  1378   1379   
  1379   1380   	if (TCL_OK != TclGetIntForIndexM(interp, objv[3], size - 1, &last)) {
  1380   1381   	    return TCL_ERROR;
  1381   1382   	}
  1382         -
  1383         -	if (last < 0) {
  1384         -	    Tcl_SetObjResult(interp, Tcl_NewIntObj(-1));
  1385         -	    return TCL_OK;
  1386         -	}
  1387         -	if (last >= size) {
  1388         -	    last = size - 1;
  1389         -	}
  1390   1383       }
  1391   1384       Tcl_SetObjResult(interp, Tcl_NewIntObj(TclStringLast(objv[1],
  1392   1385   	    objv[2], last)));
  1393   1386       return TCL_OK;
  1394   1387   }
  1395   1388   
  1396   1389   /*
................................................................................
  1422   1415   
  1423   1416       if (objc != 3) {
  1424   1417   	Tcl_WrongNumArgs(interp, 1, objv, "string charIndex");
  1425   1418   	return TCL_ERROR;
  1426   1419       }
  1427   1420   
  1428   1421       /*
  1429         -     * Get the char length to calulate what 'end' means.
         1422  +     * Get the char length to calculate what 'end' means.
  1430   1423        */
  1431   1424   
  1432   1425       length = Tcl_GetCharLength(objv[1]);
  1433   1426       if (TclGetIntForIndexM(interp, objv[2], length-1, &index) != TCL_OK) {
  1434   1427   	return TCL_ERROR;
  1435   1428       }
  1436   1429   
  1437   1430       if ((index >= 0) && (index < length)) {
  1438         -	Tcl_UniChar ch = Tcl_GetUniChar(objv[1], index);
         1431  +	int ch = Tcl_GetUniChar(objv[1], index);
         1432  +
         1433  +	if (ch == -1) {
         1434  +	    return TCL_OK;
         1435  +	}
  1439   1436   
  1440   1437   	/*
  1441   1438   	 * If we have a ByteArray object, we're careful to generate a new
  1442   1439   	 * bytearray for a result.
  1443   1440   	 */
  1444   1441   
  1445   1442   	if (TclIsPureByteArray(objv[1])) {
  1446   1443   	    unsigned char uch = (unsigned char) ch;
  1447   1444   
  1448   1445   	    Tcl_SetObjResult(interp, Tcl_NewByteArrayObj(&uch, 1));
  1449   1446   	} else {
  1450         -	    char buf[TCL_UTF_MAX];
         1447  +	    char buf[4];
  1451   1448   
  1452   1449   	    length = Tcl_UniCharToUtf(ch, buf);
         1450  +	    if (!length) {
         1451  +		length = Tcl_UniCharToUtf(-1, buf);
         1452  +	    }
  1453   1453   	    Tcl_SetObjResult(interp, Tcl_NewStringObj(buf, length));
  1454   1454   	}
  1455   1455       }
  1456   1456       return TCL_OK;
  1457   1457   }
  1458   1458   
  1459   1459   /*
................................................................................
  1575   1575   		&& (TCL_OK != TclSetBooleanFromAny(NULL, objPtr))) {
  1576   1576   	    if (strict) {
  1577   1577   		result = 0;
  1578   1578   	    } else {
  1579   1579   		string1 = TclGetStringFromObj(objPtr, &length1);
  1580   1580   		result = length1 == 0;
  1581   1581   	    }
  1582         -	} else if (((index == STR_IS_TRUE) &&
  1583         -		objPtr->internalRep.longValue == 0)
  1584         -	    || ((index == STR_IS_FALSE) &&
  1585         -		objPtr->internalRep.longValue != 0)) {
  1586         -	    result = 0;
         1582  +	} else if (index != STR_IS_BOOL) {
         1583  +	    TclGetBooleanFromObj(NULL, objPtr, &i);
         1584  +	    if ((index == STR_IS_TRUE) ^ i) {
         1585  +		result = 0;
         1586  +	    }
  1587   1587   	}
  1588   1588   	break;
  1589   1589       case STR_IS_CONTROL:
  1590   1590   	chcomp = Tcl_UniCharIsControl;
  1591   1591   	break;
  1592   1592       case STR_IS_DIGIT:
  1593   1593   	chcomp = Tcl_UniCharIsDigit;
  1594   1594   	break;
  1595   1595       case STR_IS_DOUBLE: {
  1596         -	/* TODO */
  1597   1596   	if ((objPtr->typePtr == &tclDoubleType) ||
  1598   1597   		(objPtr->typePtr == &tclIntType) ||
  1599         -#ifndef TCL_WIDE_INT_IS_LONG
  1600         -		(objPtr->typePtr == &tclWideIntType) ||
  1601         -#endif
  1602   1598   		(objPtr->typePtr == &tclBignumType)) {
  1603   1599   	    break;
  1604   1600   	}
  1605   1601   	string1 = TclGetStringFromObj(objPtr, &length1);
  1606   1602   	if (length1 == 0) {
  1607   1603   	    if (strict) {
  1608   1604   		result = 0;
................................................................................
  1629   1625       case STR_IS_INT:
  1630   1626   	if (TCL_OK == TclGetIntFromObj(NULL, objPtr, &i)) {
  1631   1627   	    break;
  1632   1628   	}
  1633   1629   	goto failedIntParse;
  1634   1630       case STR_IS_ENTIER:
  1635   1631   	if ((objPtr->typePtr == &tclIntType) ||
  1636         -#ifndef TCL_WIDE_INT_IS_LONG
  1637         -		(objPtr->typePtr == &tclWideIntType) ||
  1638         -#endif
  1639   1632   		(objPtr->typePtr == &tclBignumType)) {
  1640   1633   	    break;
  1641   1634   	}
  1642   1635   	string1 = TclGetStringFromObj(objPtr, &length1);
  1643   1636   	if (length1 == 0) {
  1644   1637   	    if (strict) {
  1645   1638   		result = 0;
................................................................................
  1810   1803   	    if (strict) {
  1811   1804   		result = 0;
  1812   1805   	    }
  1813   1806   	    goto str_is_done;
  1814   1807   	}
  1815   1808   	end = string1 + length1;
  1816   1809   	for (; string1 < end; string1 += length2, failat++) {
         1810  +	    int fullchar;
  1817   1811   	    length2 = TclUtfToUniChar(string1, &ch);
  1818         -	    if (!chcomp(ch)) {
         1812  +	    fullchar = ch;
         1813  +#if TCL_UTF_MAX <= 4
         1814  +	    if (!length2) {
         1815  +	    	length2 = TclUtfToUniChar(string1, &ch);
         1816  +	    	fullchar = (((fullchar & 0x3ff) << 10) | (ch & 0x3ff)) + 0x10000;
         1817  +	    }
         1818  +#endif
         1819  +	    if (!chcomp(fullchar)) {
  1819   1820   		result = 0;
  1820   1821   		break;
  1821   1822   	    }
  1822   1823   	}
  1823   1824       }
  1824   1825   
  1825   1826       /*
................................................................................
  1999   2000   	/*
  2000   2001   	 * Special case for one map pair which avoids the extra for loop and
  2001   2002   	 * extra calls to get Unicode data. The algorithm is otherwise
  2002   2003   	 * identical to the multi-pair case. This will be >30% faster on
  2003   2004   	 * larger strings.
  2004   2005   	 */
  2005   2006   
  2006         -	int mapLen;
  2007         -	Tcl_UniChar *mapString, u2lc;
         2007  +	int mapLen, u2lc;
         2008  +	Tcl_UniChar *mapString;
  2008   2009   
  2009   2010   	ustring2 = Tcl_GetUnicodeFromObj(mapElemv[0], &length2);
  2010   2011   	p = ustring1;
  2011   2012   	if ((length2 > length1) || (length2 == 0)) {
  2012   2013   	    /*
  2013   2014   	     * Match string is either longer than input or empty.
  2014   2015   	     */
................................................................................
  2031   2032   		    ustring1 = p - 1;
  2032   2033   
  2033   2034   		    Tcl_AppendUnicodeToObj(resultPtr, mapString, mapLen);
  2034   2035   		}
  2035   2036   	    }
  2036   2037   	}
  2037   2038       } else {
  2038         -	Tcl_UniChar **mapStrings, *u2lc = NULL;
  2039         -	int *mapLens;
         2039  +	Tcl_UniChar **mapStrings;
         2040  +	int *mapLens, *u2lc = NULL;
  2040   2041   
  2041   2042   	/*
  2042   2043   	 * Precompute pointers to the unicode string and length. This saves us
  2043   2044   	 * repeated function calls later, significantly speeding up the
  2044   2045   	 * algorithm. We only need the lowercase first char in the nocase
  2045   2046   	 * case.
  2046   2047   	 */
  2047   2048   
  2048   2049   	mapStrings = TclStackAlloc(interp, mapElemc*2*sizeof(Tcl_UniChar *));
  2049   2050   	mapLens = TclStackAlloc(interp, mapElemc * 2 * sizeof(int));
  2050   2051   	if (nocase) {
  2051         -	    u2lc = TclStackAlloc(interp, mapElemc * sizeof(Tcl_UniChar));
         2052  +	    u2lc = TclStackAlloc(interp, mapElemc * sizeof(int));
  2052   2053   	}
  2053   2054   	for (index = 0; index < mapElemc; index++) {
  2054   2055   	    mapStrings[index] = Tcl_GetUnicodeFromObj(mapElemv[index],
  2055   2056   		    mapLens+index);
  2056   2057   	    if (nocase && ((index % 2) == 0)) {
  2057   2058   		u2lc[index/2] = Tcl_UniCharToLower(*mapStrings[index]);
  2058   2059   	    }
................................................................................
  2273   2274       if (count == 1) {
  2274   2275   	Tcl_SetObjResult(interp, objv[1]);
  2275   2276   	return TCL_OK;
  2276   2277       } else if (count < 1) {
  2277   2278   	return TCL_OK;
  2278   2279       }
  2279   2280   
  2280         -    if (TCL_OK != TclStringRepeat(interp, objv[1], count, &resultPtr)) {
  2281         -	return TCL_ERROR;
         2281  +    resultPtr = TclStringRepeat(interp, objv[1], count, TCL_STRING_IN_PLACE);
         2282  +    if (resultPtr) {
         2283  +	Tcl_SetObjResult(interp, resultPtr);
         2284  +	return TCL_OK;
  2282   2285       }
  2283         -    Tcl_SetObjResult(interp, resultPtr);
  2284         -    return TCL_OK;
         2286  +    return TCL_ERROR;
  2285   2287   }
  2286   2288   
  2287   2289   /*
  2288   2290    *----------------------------------------------------------------------
  2289   2291    *
  2290   2292    * StringRplcCmd --
  2291   2293    *
................................................................................
  2305   2307   static int
  2306   2308   StringRplcCmd(
  2307   2309       ClientData dummy,		/* Not used. */
  2308   2310       Tcl_Interp *interp,		/* Current interpreter. */
  2309   2311       int objc,			/* Number of arguments. */
  2310   2312       Tcl_Obj *const objv[])	/* Argument objects. */
  2311   2313   {
  2312         -    Tcl_UniChar *ustring;
  2313         -    int first, last, length;
         2314  +    int first, last, length, end;
  2314   2315   
  2315   2316       if (objc < 4 || objc > 5) {
  2316   2317   	Tcl_WrongNumArgs(interp, 1, objv, "string first last ?string?");
  2317   2318   	return TCL_ERROR;
  2318   2319       }
  2319   2320   
  2320         -    ustring = Tcl_GetUnicodeFromObj(objv[1], &length);
  2321         -    length--;
         2321  +    length = Tcl_GetCharLength(objv[1]);
         2322  +    end = length - 1;
  2322   2323   
  2323         -    if (TclGetIntForIndexM(interp, objv[2], length, &first) != TCL_OK ||
  2324         -	    TclGetIntForIndexM(interp, objv[3], length, &last) != TCL_OK){
         2324  +    if (TclGetIntForIndexM(interp, objv[2], end, &first) != TCL_OK ||
         2325  +	    TclGetIntForIndexM(interp, objv[3], end, &last) != TCL_OK){
  2325   2326   	return TCL_ERROR;
  2326   2327       }
  2327   2328   
  2328         -    if ((last < first) || (last < 0) || (first > length)) {
         2329  +    /*
         2330  +     * The following test screens out most empty substrings as
         2331  +     * candidates for replacement. When they are detected, no
         2332  +     * replacement is done, and the result is the original string,
         2333  +     */
         2334  +    if ((last < 0) ||		/* Range ends before start of string */
         2335  +	    (first > end) ||	/* Range begins after end of string */
         2336  +	    (last < first)) {	/* Range begins after it starts */
         2337  +
         2338  +	/*
         2339  +	 * BUT!!! when (end < 0) -- an empty original string -- we can
         2340  +	 * have (first <= end < 0 <= last) and an empty string is permitted
         2341  +	 * to be replaced.
         2342  +	 */
  2329   2343   	Tcl_SetObjResult(interp, objv[1]);
  2330   2344       } else {
  2331   2345   	Tcl_Obj *resultPtr;
  2332   2346   
  2333         -	ustring = Tcl_GetUnicodeFromObj(objv[1], &length);
  2334         -	length--;
  2335         -
  2336   2347   	if (first < 0) {
  2337   2348   	    first = 0;
  2338   2349   	}
         2350  +	if (last > end) {
         2351  +	    last = end;
         2352  +	}
  2339   2353   
  2340         -	resultPtr = Tcl_NewUnicodeObj(ustring, first);
  2341         -	if (objc == 5) {
  2342         -	    Tcl_AppendObjToObj(resultPtr, objv[4]);
  2343         -	}
  2344         -	if (last < length) {
  2345         -	    Tcl_AppendUnicodeToObj(resultPtr, ustring + last + 1,
  2346         -		    length - last);
  2347         -	}
         2354  +	resultPtr = TclStringReplace(interp, objv[1], first,
         2355  +		last + 1 - first, (objc == 5) ? objv[4] : NULL,
         2356  +		TCL_STRING_IN_PLACE);
         2357  +
  2348   2358   	Tcl_SetObjResult(interp, resultPtr);
  2349   2359       }
  2350   2360       return TCL_OK;
  2351   2361   }
  2352   2362   
  2353   2363   /*
  2354   2364    *----------------------------------------------------------------------
................................................................................
  2376   2386       Tcl_Obj *const objv[])	/* Argument objects. */
  2377   2387   {
  2378   2388       if (objc != 2) {
  2379   2389   	Tcl_WrongNumArgs(interp, 1, objv, "string");
  2380   2390   	return TCL_ERROR;
  2381   2391       }
  2382   2392   
  2383         -    Tcl_SetObjResult(interp, TclStringObjReverse(objv[1]));
         2393  +    Tcl_SetObjResult(interp, TclStringReverse(objv[1], TCL_STRING_IN_PLACE));
  2384   2394       return TCL_OK;
  2385   2395   }
  2386   2396   
  2387   2397   /*
  2388   2398    *----------------------------------------------------------------------
  2389   2399    *
  2390   2400    * StringStartCmd --
................................................................................
  2535   2545   {
  2536   2546       /*
  2537   2547        * Remember to keep code here in some sync with the byte-compiled versions
  2538   2548        * in tclExecute.c (INST_STR_EQ, INST_STR_NEQ and INST_STR_CMP as well as
  2539   2549        * the expr string comparison in INST_EQ/INST_NEQ/INST_LT/...).
  2540   2550        */
  2541   2551   
  2542         -    const char *string1, *string2;
  2543         -    int length1, length2, i, match, length, nocase = 0, reqlength = -1;
  2544         -    typedef int (*strCmpFn_t)(const char *, const char *, unsigned int);
  2545         -    strCmpFn_t strCmpFn;
         2552  +    const char *string2;
         2553  +    int length, i, match, nocase = 0, reqlength = -1;
  2546   2554   
  2547   2555       if (objc < 3 || objc > 6) {
  2548   2556       str_cmp_args:
  2549   2557   	Tcl_WrongNumArgs(interp, 1, objv,
  2550   2558   		"?-nocase? ?-length int? string1 string2");
  2551   2559   	return TCL_ERROR;
  2552   2560       }
  2553   2561   
  2554   2562       for (i = 1; i < objc-2; i++) {
  2555         -	string2 = TclGetStringFromObj(objv[i], &length2);
  2556         -	if ((length2 > 1) && !strncmp(string2, "-nocase", (size_t)length2)) {
         2563  +	string2 = TclGetStringFromObj(objv[i], &length);
         2564  +	if ((length > 1) && !strncmp(string2, "-nocase", (size_t)length)) {
  2557   2565   	    nocase = 1;
  2558         -	} else if ((length2 > 1)
  2559         -		&& !strncmp(string2, "-length", (size_t)length2)) {
         2566  +	} else if ((length > 1)
         2567  +		&& !strncmp(string2, "-length", (size_t)length)) {
  2560   2568   	    if (i+1 >= objc-2) {
  2561   2569   		goto str_cmp_args;
  2562   2570   	    }
  2563   2571   	    i++;
  2564   2572   	    if (TclGetIntFromObj(interp, objv[i], &reqlength) != TCL_OK) {
  2565   2573   		return TCL_ERROR;
  2566   2574   	    }
................................................................................
  2577   2585       /*
  2578   2586        * From now on, we only access the two objects at the end of the argument
  2579   2587        * array.
  2580   2588        */
  2581   2589   
  2582   2590       objv += objc-2;
  2583   2591   
  2584         -    if ((reqlength == 0) || (objv[0] == objv[1])) {
  2585         -	/*
  2586         -	 * Always match at 0 chars of if it is the same obj.
  2587         -	 */
  2588         -
  2589         -	Tcl_SetObjResult(interp, Tcl_NewBooleanObj(1));
  2590         -	return TCL_OK;
  2591         -    }
  2592         -
  2593         -    if (!nocase && TclIsPureByteArray(objv[0]) &&
  2594         -	    TclIsPureByteArray(objv[1])) {
  2595         -	/*
  2596         -	 * Use binary versions of comparisons since that won't cause undue
  2597         -	 * type conversions and it is much faster. Only do this if we're
  2598         -	 * case-sensitive (which is all that really makes sense with byte
  2599         -	 * arrays anyway, and we have no memcasecmp() for some reason... :^)
  2600         -	 */
  2601         -
  2602         -	string1 = (char *) Tcl_GetByteArrayFromObj(objv[0], &length1);
  2603         -	string2 = (char *) Tcl_GetByteArrayFromObj(objv[1], &length2);
  2604         -	strCmpFn = (strCmpFn_t) memcmp;
  2605         -    } else if ((objv[0]->typePtr == &tclStringType)
  2606         -	    && (objv[1]->typePtr == &tclStringType)) {
  2607         -	/*
  2608         -	 * Do a unicode-specific comparison if both of the args are of String
  2609         -	 * type. In benchmark testing this proved the most efficient check
  2610         -	 * between the unicode and string comparison operations.
  2611         -	 */
  2612         -
  2613         -	string1 = (char *) Tcl_GetUnicodeFromObj(objv[0], &length1);
  2614         -	string2 = (char *) Tcl_GetUnicodeFromObj(objv[1], &length2);
  2615         -	strCmpFn = (strCmpFn_t)
  2616         -		(nocase ? Tcl_UniCharNcasecmp : Tcl_UniCharNcmp);
  2617         -    } else {
  2618         -	/*
  2619         -	 * As a catch-all we will work with UTF-8. We cannot use memcmp() as
  2620         -	 * that is unsafe with any string containing NUL (\xC0\x80 in Tcl's
  2621         -	 * utf rep). We can use the more efficient TclpUtfNcmp2 if we are
  2622         -	 * case-sensitive and no specific length was requested.
  2623         -	 */
  2624         -
  2625         -	string1 = (char *) TclGetStringFromObj(objv[0], &length1);
  2626         -	string2 = (char *) TclGetStringFromObj(objv[1], &length2);
  2627         -	if ((reqlength < 0) && !nocase) {
  2628         -	    strCmpFn = (strCmpFn_t) TclpUtfNcmp2;
  2629         -	} else {
  2630         -	    length1 = Tcl_NumUtfChars(string1, length1);
  2631         -	    length2 = Tcl_NumUtfChars(string2, length2);
  2632         -	    strCmpFn = (strCmpFn_t) (nocase ? Tcl_UtfNcasecmp : Tcl_UtfNcmp);
  2633         -	}
  2634         -    }
  2635         -
  2636         -    if ((reqlength < 0) && (length1 != length2)) {
  2637         -	match = 1;		/* This will be reversed below. */
  2638         -    } else {
  2639         -	length = (length1 < length2) ? length1 : length2;
  2640         -	if (reqlength > 0 && reqlength < length) {
  2641         -	    length = reqlength;
  2642         -	} else if (reqlength < 0) {
  2643         -	    /*
  2644         -	     * The requested length is negative, so we ignore it by setting it
  2645         -	     * to length + 1 so we correct the match var.
  2646         -	     */
  2647         -
  2648         -	    reqlength = length + 1;
  2649         -	}
  2650         -
  2651         -	match = strCmpFn(string1, string2, (unsigned) length);
  2652         -	if ((match == 0) && (reqlength > length)) {
  2653         -	    match = length1 - length2;
  2654         -	}
  2655         -    }
         2592  +    match = TclStringCmp(objv[0], objv[1], 0, nocase, reqlength);
  2656   2593   
  2657   2594       Tcl_SetObjResult(interp, Tcl_NewBooleanObj(match ? 0 : 1));
  2658   2595       return TCL_OK;
  2659   2596   }
  2660   2597   
  2661   2598   /*
  2662   2599    *----------------------------------------------------------------------
................................................................................
  2685   2622   {
  2686   2623       /*
  2687   2624        * Remember to keep code here in some sync with the byte-compiled versions
  2688   2625        * in tclExecute.c (INST_STR_EQ, INST_STR_NEQ and INST_STR_CMP as well as
  2689   2626        * the expr string comparison in INST_EQ/INST_NEQ/INST_LT/...).
  2690   2627        */
  2691   2628   
  2692         -    const char *string1, *string2;
  2693         -    int length1, length2, i, match, length, nocase = 0, reqlength = -1;
  2694         -    typedef int (*strCmpFn_t)(const char *, const char *, unsigned int);
  2695         -    strCmpFn_t strCmpFn;
         2629  +    int match, nocase, reqlength, status;
  2696   2630   
         2631  +    status = TclStringCmpOpts(interp, objc, objv, &nocase, &reqlength);
         2632  +    if (status != TCL_OK) {
         2633  +	return status;
         2634  +    }
         2635  +
         2636  +    objv += objc-2;
         2637  +    match = TclStringCmp(objv[0], objv[1], 0, nocase, reqlength);
         2638  +    Tcl_SetObjResult(interp, Tcl_NewIntObj(match));
         2639  +    return TCL_OK;
         2640  +}
         2641  +
         2642  +int TclStringCmpOpts(
         2643  +    Tcl_Interp *interp,		/* Current interpreter. */
         2644  +    int objc,			/* Number of arguments. */
         2645  +    Tcl_Obj *const objv[],	/* Argument objects. */
         2646  +    int *nocase,
         2647  +    int *reqlength)
         2648  +{
         2649  +    int i, length;
         2650  +    const char *string;
         2651  +
         2652  +    *reqlength = -1;
         2653  +    *nocase = 0;
  2697   2654       if (objc < 3 || objc > 6) {
  2698   2655       str_cmp_args:
  2699   2656   	Tcl_WrongNumArgs(interp, 1, objv,
  2700   2657   		"?-nocase? ?-length int? string1 string2");
  2701   2658   	return TCL_ERROR;
  2702   2659       }
  2703   2660   
  2704   2661       for (i = 1; i < objc-2; i++) {
  2705         -	string2 = TclGetStringFromObj(objv[i], &length2);
  2706         -	if ((length2 > 1) && !strncmp(string2, "-nocase", (size_t)length2)) {
  2707         -	    nocase = 1;
  2708         -	} else if ((length2 > 1)
  2709         -		&& !strncmp(string2, "-length", (size_t)length2)) {
         2662  +	string = TclGetStringFromObj(objv[i], &length);
         2663  +	if ((length > 1) && !strncmp(string, "-nocase", (size_t)length)) {
         2664  +	    *nocase = 1;
         2665  +	} else if ((length > 1)
         2666  +		&& !strncmp(string, "-length", (size_t)length)) {
  2710   2667   	    if (i+1 >= objc-2) {
  2711   2668   		goto str_cmp_args;
  2712   2669   	    }
  2713   2670   	    i++;
  2714         -	    if (TclGetIntFromObj(interp, objv[i], &reqlength) != TCL_OK) {
         2671  +	    if (TclGetIntFromObj(interp, objv[i], reqlength) != TCL_OK) {
  2715   2672   		return TCL_ERROR;
  2716   2673   	    }
  2717   2674   	} else {
  2718   2675   	    Tcl_SetObjResult(interp, Tcl_ObjPrintf(
  2719   2676   		    "bad option \"%s\": must be -nocase or -length",
  2720         -		    string2));
         2677  +		    string));
  2721   2678   	    Tcl_SetErrorCode(interp, "TCL", "LOOKUP", "INDEX", "option",
  2722         -		    string2, NULL);
         2679  +		    string, NULL);
  2723   2680   	    return TCL_ERROR;
  2724   2681   	}
  2725   2682       }
  2726         -
  2727         -    /*
  2728         -     * From now on, we only access the two objects at the end of the argument
  2729         -     * array.
  2730         -     */
  2731         -
  2732         -    objv += objc-2;
  2733         -
  2734         -    if ((reqlength == 0) || (objv[0] == objv[1])) {
  2735         -	/*
  2736         -	 * Always match at 0 chars of if it is the same obj.
  2737         -	 */
  2738         -
  2739         -	Tcl_SetObjResult(interp, Tcl_NewBooleanObj(0));
  2740         -	return TCL_OK;
  2741         -    }
  2742         -
  2743         -    if (!nocase && TclIsPureByteArray(objv[0]) &&
  2744         -	    TclIsPureByteArray(objv[1])) {
  2745         -	/*
  2746         -	 * Use binary versions of comparisons since that won't cause undue
  2747         -	 * type conversions and it is much faster. Only do this if we're
  2748         -	 * case-sensitive (which is all that really makes sense with byte
  2749         -	 * arrays anyway, and we have no memcasecmp() for some reason... :^)
  2750         -	 */
  2751         -
  2752         -	string1 = (char *) Tcl_GetByteArrayFromObj(objv[0], &length1);
  2753         -	string2 = (char *) Tcl_GetByteArrayFromObj(objv[1], &length2);
  2754         -	strCmpFn = (strCmpFn_t) memcmp;
  2755         -    } else if ((objv[0]->typePtr == &tclStringType)
  2756         -	    && (objv[1]->typePtr == &tclStringType)) {
  2757         -	/*
  2758         -	 * Do a unicode-specific comparison if both of the args are of String
  2759         -	 * type. In benchmark testing this proved the most efficient check
  2760         -	 * between the unicode and string comparison operations.
  2761         -	 */
  2762         -
  2763         -	string1 = (char *) Tcl_GetUnicodeFromObj(objv[0], &length1);
  2764         -	string2 = (char *) Tcl_GetUnicodeFromObj(objv[1], &length2);
  2765         -	strCmpFn = (strCmpFn_t)
  2766         -		(nocase ? Tcl_UniCharNcasecmp : Tcl_UniCharNcmp);
  2767         -    } else {
  2768         -	/*
  2769         -	 * As a catch-all we will work with UTF-8. We cannot use memcmp() as
  2770         -	 * that is unsafe with any string containing NUL (\xC0\x80 in Tcl's
  2771         -	 * utf rep). We can use the more efficient TclpUtfNcmp2 if we are
  2772         -	 * case-sensitive and no specific length was requested.
  2773         -	 */
  2774         -
  2775         -	string1 = (char *) TclGetStringFromObj(objv[0], &length1);
  2776         -	string2 = (char *) TclGetStringFromObj(objv[1], &length2);
  2777         -	if ((reqlength < 0) && !nocase) {
  2778         -	    strCmpFn = (strCmpFn_t) TclpUtfNcmp2;
  2779         -	} else {
  2780         -	    length1 = Tcl_NumUtfChars(string1, length1);
  2781         -	    length2 = Tcl_NumUtfChars(string2, length2);
  2782         -	    strCmpFn = (strCmpFn_t) (nocase ? Tcl_UtfNcasecmp : Tcl_UtfNcmp);
  2783         -	}
  2784         -    }
  2785         -
  2786         -    length = (length1 < length2) ? length1 : length2;
  2787         -    if (reqlength > 0 && reqlength < length) {
  2788         -	length = reqlength;
  2789         -    } else if (reqlength < 0) {
  2790         -	/*
  2791         -	 * The requested length is negative, so we ignore it by setting it to
  2792         -	 * length + 1 so we correct the match var.
  2793         -	 */
  2794         -
  2795         -	reqlength = length + 1;
  2796         -    }
  2797         -
  2798         -    match = strCmpFn(string1, string2, (unsigned) length);
  2799         -    if ((match == 0) && (reqlength > length)) {
  2800         -	match = length1 - length2;
  2801         -    }
  2802         -
  2803         -    Tcl_SetObjResult(interp,
  2804         -	    Tcl_NewIntObj((match > 0) ? 1 : (match < 0) ? -1 : 0));
  2805   2683       return TCL_OK;
  2806   2684   }
  2807   2685   
  2808   2686   /*
  2809   2687    *----------------------------------------------------------------------
  2810   2688    *
  2811   2689    * StringCatCmd --
................................................................................
  2825   2703   static int
  2826   2704   StringCatCmd(
  2827   2705       ClientData dummy,		/* Not used. */
  2828   2706       Tcl_Interp *interp,		/* Current interpreter. */
  2829   2707       int objc,			/* Number of arguments. */
  2830   2708       Tcl_Obj *const objv[])	/* Argument objects. */
  2831   2709   {
  2832         -    int code;
  2833   2710       Tcl_Obj *objResultPtr;
  2834   2711   
  2835   2712       if (objc < 2) {
  2836   2713   	/*
  2837   2714   	 * If there are no args, the result is an empty object.
  2838   2715   	 * Just leave the preset empty interp result.
  2839   2716   	 */
  2840   2717   	return TCL_OK;
  2841   2718       }
  2842         -    if (objc == 2) {
  2843         -	/*
  2844         -	 * Other trivial case, single arg, just return it.
  2845         -	 */
  2846         -	Tcl_SetObjResult(interp, objv[1]);
  2847         -	return TCL_OK;
  2848         -    }
  2849   2719   
  2850         -    code = TclStringCatObjv(interp, /* inPlace */ 1, objc-1, objv+1,
  2851         -	    &objResultPtr);
         2720  +    objResultPtr = TclStringCat(interp, objc-1, objv+1, TCL_STRING_IN_PLACE);
  2852   2721   
  2853         -    if (code == TCL_OK) {
         2722  +    if (objResultPtr) {
  2854   2723   	Tcl_SetObjResult(interp, objResultPtr);
  2855   2724   	return TCL_OK;
  2856   2725       }
  2857   2726   
  2858         -    return code;
         2727  +    return TCL_ERROR;
  2859   2728   }
  2860   2729   
  2861   2730   /*
  2862   2731    *----------------------------------------------------------------------
  2863   2732    *
  2864   2733    * StringBytesCmd --
  2865   2734    *
................................................................................
  2872   2741    *	A standard Tcl result.
  2873   2742    *
  2874   2743    * Side effects:
  2875   2744    *	See the user documentation.
  2876   2745    *
  2877   2746    *----------------------------------------------------------------------
  2878   2747    */
  2879         -
  2880   2748   static int
  2881   2749   StringBytesCmd(
  2882   2750       ClientData dummy,		/* Not used. */
  2883   2751       Tcl_Interp *interp,		/* Current interpreter. */
  2884   2752       int objc,			/* Number of arguments. */
  2885   2753       Tcl_Obj *const objv[])	/* Argument objects. */
  2886   2754   {
................................................................................
  3220   3088   	length2 = strlen(tclDefaultTrimSet);
  3221   3089       } else {
  3222   3090   	Tcl_WrongNumArgs(interp, 1, objv, "string ?chars?");
  3223   3091   	return TCL_ERROR;
  3224   3092       }
  3225   3093       string1 = TclGetStringFromObj(objv[1], &length1);
  3226   3094   
  3227         -    triml = TclTrimLeft(string1, length1, string2, length2);
  3228         -    trimr = TclTrimRight(string1 + triml, length1 - triml, string2, length2);
         3095  +    triml = TclTrim(string1, length1, string2, length2, &trimr);
  3229   3096   
  3230   3097       Tcl_SetObjResult(interp,
  3231   3098   	    Tcl_NewStringObj(string1 + triml, length1 - triml - trimr));
  3232   3099       return TCL_OK;
  3233   3100   }
  3234   3101   
  3235   3102   /*
................................................................................
  3526   3393   	"--", NULL
  3527   3394       };
  3528   3395       enum options {
  3529   3396   	OPT_EXACT, OPT_GLOB, OPT_INDEXV, OPT_MATCHV, OPT_NOCASE, OPT_REGEXP,
  3530   3397   	OPT_LAST
  3531   3398       };
  3532   3399       typedef int (*strCmpFn_t)(const char *, const char *);
  3533         -    strCmpFn_t strCmpFn = strcmp;
         3400  +    strCmpFn_t strCmpFn = TclUtfCmp;
  3534   3401   
  3535   3402       mode = OPT_EXACT;
  3536   3403       foundmode = 0;
  3537   3404       indexVarObj = NULL;
  3538   3405       matchVarObj = NULL;
  3539   3406       numMatchesSaved = 0;
  3540   3407       noCase = 0;
................................................................................
  4289   4156   	commonHandler:
  4290   4157   	    if (Tcl_ListObjLength(interp, objv[i+2], &dummy) != TCL_OK) {
  4291   4158   		Tcl_DecrRefCount(handlersObj);
  4292   4159   		return TCL_ERROR;
  4293   4160   	    }
  4294   4161   
  4295   4162   	    info[0] = objv[i];			/* type */
  4296         -	    TclNewLongObj(info[1], code);	/* returnCode */
         4163  +	    TclNewIntObj(info[1], code);	/* returnCode */
  4297   4164   	    if (info[2] == NULL) {		/* errorCodePrefix */
  4298   4165   		TclNewObj(info[2]);
  4299   4166   	    }
  4300   4167   	    info[3] = objv[i+2];		/* bindVariables */
  4301   4168   	    info[4] = objv[i+3];		/* script */
  4302   4169   
  4303   4170   	    bodyShared = !strcmp(TclGetString(objv[i+3]), "-");

Changes to generic/tclCompCmds.c.

   318    318       isDataEven = (isDataValid && (len & 1) == 0);
   319    319   
   320    320       /*
   321    321        * Special case: literal odd-length argument is always an error.
   322    322        */
   323    323   
   324    324       if (isDataValid && !isDataEven) {
          325  +	/* Abandon custom compile and let invocation raise the error */
          326  +	code = TclCompileBasic2ArgCmd(interp, parsePtr, cmdPtr, envPtr);
          327  +	goto done;
          328  +
          329  +	/*
          330  +	 * We used to compile to the bytecode that would throw the error,
          331  +	 * but that was wrong because it would not invoke the array trace
          332  +	 * on the variable.
          333  +	 *
   325    334   	PushStringLiteral(envPtr, "list must have an even number of elements");
   326    335   	PushStringLiteral(envPtr, "-errorcode {TCL ARGUMENT FORMAT}");
   327    336   	TclEmitInstInt4(INST_RETURN_IMM, TCL_ERROR,		envPtr);
   328    337   	TclEmitInt4(		0,				envPtr);
   329    338   	goto done;
          339  +	 *
          340  +	 */
   330    341       }
   331    342   
   332    343       /*
   333    344        * Except for the special "ensure array" case below, when we're not in
   334    345        * a proc, we cannot do a better compile than generic.
   335    346        */
   336    347   
................................................................................
   400    411       infoPtr->varLists[0]->varIndexes[1] = valVar;
   401    412       infoIndex = TclCreateAuxData(infoPtr, &newForeachInfoType, envPtr);
   402    413   
   403    414       /*
   404    415        * Start issuing instructions to write to the array.
   405    416        */
   406    417   
          418  +    TclEmitInstInt4(INST_ARRAY_EXISTS_IMM, localIndex,	envPtr);
          419  +    TclEmitInstInt1(INST_JUMP_TRUE1, 7,			envPtr);
          420  +    TclEmitInstInt4(INST_ARRAY_MAKE_IMM, localIndex,	envPtr);
          421  +
   407    422       CompileWord(envPtr, dataTokenPtr, interp, 2);
   408    423       if (!isDataLiteral || !isDataValid) {
   409    424   	/*
   410    425   	 * Only need this safety check if we're handling a non-literal or list
   411    426   	 * containing an invalid literal; with valid list literals, we've
   412    427   	 * already checked (worth it because literals are a very common
   413    428   	 * use-case with [array set]).
................................................................................
   424    439   	TclEmitInstInt4(INST_RETURN_IMM, TCL_ERROR,		envPtr);
   425    440   	TclEmitInt4(		0,				envPtr);
   426    441   	TclAdjustStackDepth(-1, envPtr);
   427    442   	fwd = CurrentOffset(envPtr) - offsetFwd;
   428    443   	TclStoreInt1AtPtr(fwd, envPtr->codeStart+offsetFwd+1);
   429    444       }
   430    445   
   431         -    TclEmitInstInt4(INST_ARRAY_EXISTS_IMM, localIndex,	envPtr);
   432         -    TclEmitInstInt1(INST_JUMP_TRUE1, 7,			envPtr);
   433         -    TclEmitInstInt4(INST_ARRAY_MAKE_IMM, localIndex,	envPtr);
   434    446       TclEmitInstInt4(INST_FOREACH_START, infoIndex,	envPtr);
   435    447       offsetBack = CurrentOffset(envPtr);
   436    448       Emit14Inst(	INST_LOAD_SCALAR, keyVar,		envPtr);
   437    449       Emit14Inst(	INST_LOAD_SCALAR, valVar,		envPtr);
   438    450       Emit14Inst(	INST_STORE_ARRAY, localIndex,		envPtr);
   439    451       TclEmitOpcode(	INST_POP,			envPtr);
   440    452       infoPtr->loopCtTemp = offsetBack - CurrentOffset(envPtr); /*misuse */

Changes to generic/tclCompCmdsGR.c.

    23     23    */
    24     24   
    25     25   static void		CompileReturnInternal(CompileEnv *envPtr,
    26     26   			    unsigned char op, int code, int level,
    27     27   			    Tcl_Obj *returnOpts);
    28     28   static int		IndexTailVarIfKnown(Tcl_Interp *interp,
    29     29   			    Tcl_Token *varTokenPtr, CompileEnv *envPtr);
    30         -
    31         -#define INDEX_END	(-2)
    32     30   
    33     31   /*
    34     32    *----------------------------------------------------------------------
    35     33    *
    36         - * GetIndexFromToken --
           34  + * TclGetIndexFromToken --
    37     35    *
    38         - *	Parse a token and get the encoded version of the index (as understood
    39         - *	by TEBC), assuming it is at all knowable at compile time. Only handles
    40         - *	indices that are integers or 'end' or 'end-integer'.
           36  + *	Parse a token to determine if an index value is known at
           37  + *	compile time.
    41     38    *
    42     39    * Returns:
    43     40    *	TCL_OK if parsing succeeded, and TCL_ERROR if it failed.
    44     41    *
    45     42    * Side effects:
    46         - *	Sets *index to the index value if successful.
           43  + *	When TCL_OK is returned, the encoded index value is written
           44  + *	to *index.
    47     45    *
    48     46    *----------------------------------------------------------------------
    49     47    */
    50     48   
    51         -static inline int
    52         -GetIndexFromToken(
           49  +int
           50  +TclGetIndexFromToken(
    53     51       Tcl_Token *tokenPtr,
    54         -    int *index)
           52  +    int before,
           53  +    int after,
           54  +    int *indexPtr)
    55     55   {
    56     56       Tcl_Obj *tmpObj = Tcl_NewObj();
    57         -    int result, idx;
           57  +    int result = TCL_ERROR;
    58     58   
    59         -    if (!TclWordKnownAtCompileTime(tokenPtr, tmpObj)) {
    60         -	Tcl_DecrRefCount(tmpObj);
    61         -	return TCL_ERROR;
    62         -    }
    63         -
    64         -    result = TclGetIntFromObj(NULL, tmpObj, &idx);
    65         -    if (result == TCL_OK) {
    66         -	if (idx < 0) {
    67         -	    result = TCL_ERROR;
    68         -	}
    69         -    } else {
    70         -	result = TclGetIntForIndexM(NULL, tmpObj, INDEX_END, &idx);
    71         -	if (result == TCL_OK && idx > INDEX_END) {
    72         -	    result = TCL_ERROR;
    73         -	}
           59  +    if (TclWordKnownAtCompileTime(tokenPtr, tmpObj)) {
           60  +	result = TclIndexEncode(NULL, tmpObj, before, after, indexPtr);
    74     61       }
    75     62       Tcl_DecrRefCount(tmpObj);
    76         -
    77         -    if (result == TCL_OK) {
    78         -	*index = idx;
    79         -    }
    80         -
    81     63       return result;
    82     64   }
    83     65   
    84     66   /*
    85     67    *----------------------------------------------------------------------
    86     68    *
    87     69    * TclCompileGlobalCmd --
................................................................................
   140    122       for (i=1; i<numWords; varTokenPtr = TokenAfter(varTokenPtr),i++) {
   141    123   	localIndex = IndexTailVarIfKnown(interp, varTokenPtr, envPtr);
   142    124   
   143    125   	if (localIndex < 0) {
   144    126   	    return TCL_ERROR;
   145    127   	}
   146    128   
   147         -	/* TODO: Consider what value can pass throug the
   148         -	 * IndexTailVarIfKnown() screen.  Full CompileWord()
   149         -	 * likely does not apply here.  Push known value instead. */
          129  +	/*
          130  +	 * TODO: Consider what value can pass through the
          131  +	 * IndexTailVarIfKnown() screen. Full CompileWord() likely does not
          132  +	 * apply here. Push known value instead.
          133  +	 */
          134  +
   150    135   	CompileWord(envPtr, varTokenPtr, interp, i);
   151    136   	TclEmitInstInt4(	INST_NSUPVAR, localIndex,	envPtr);
   152    137       }
   153    138   
   154    139       /*
   155    140        * Pop the namespace, and set the result to empty
   156    141        */
................................................................................
   283    268   		TclCompileExprWords(interp, testTokenPtr, 1, envPtr);
   284    269   		if (jumpFalseFixupArray.next >= jumpFalseFixupArray.end) {
   285    270   		    TclExpandJumpFixupArray(&jumpFalseFixupArray);
   286    271   		}
   287    272   		jumpIndex = jumpFalseFixupArray.next;
   288    273   		jumpFalseFixupArray.next++;
   289    274   		TclEmitForwardJump(envPtr, TCL_FALSE_JUMP,
   290         -			jumpFalseFixupArray.fixup+jumpIndex);
          275  +			jumpFalseFixupArray.fixup + jumpIndex);
   291    276   	    }
   292    277   	    code = TCL_OK;
   293    278   	}
   294    279   
   295    280   	/*
   296    281   	 * Skip over the optional "then" before the then clause.
   297    282   	 */
................................................................................
   330    315   	     */
   331    316   
   332    317   	    if (jumpEndFixupArray.next >= jumpEndFixupArray.end) {
   333    318   		TclExpandJumpFixupArray(&jumpEndFixupArray);
   334    319   	    }
   335    320   	    jumpEndFixupArray.next++;
   336    321   	    TclEmitForwardJump(envPtr, TCL_UNCONDITIONAL_JUMP,
   337         -		    jumpEndFixupArray.fixup+jumpIndex);
          322  +		    jumpEndFixupArray.fixup + jumpIndex);
   338    323   
   339    324   	    /*
   340    325   	     * Fix the target of the jumpFalse after the test. Generate a 4
   341    326   	     * byte jump if the distance is > 120 bytes. This is conservative,
   342    327   	     * and ensures that we won't have to replace this jump if we later
   343    328   	     * also need to replace the proceeding jump to the end of the "if"
   344    329   	     * with a 4 byte jump.
   345    330   	     */
   346    331   
   347    332   	    TclAdjustStackDepth(-1, envPtr);
   348    333   	    if (TclFixupForwardJumpToHere(envPtr,
   349         -		    jumpFalseFixupArray.fixup+jumpIndex, 120)) {
          334  +		    jumpFalseFixupArray.fixup + jumpIndex, 120)) {
   350    335   		/*
   351    336   		 * Adjust the code offset for the proceeding jump to the end
   352    337   		 * of the "if" command.
   353    338   		 */
   354    339   
   355    340   		jumpEndFixupArray.fixup[jumpIndex].codeOffset += 3;
   356    341   	    }
................................................................................
   425    410       /*
   426    411        * Fix the unconditional jumps to the end of the "if" command.
   427    412        */
   428    413   
   429    414       for (j = jumpEndFixupArray.next;  j > 0;  j--) {
   430    415   	jumpIndex = (j - 1);	/* i.e. process the closest jump first. */
   431    416   	if (TclFixupForwardJumpToHere(envPtr,
   432         -		jumpEndFixupArray.fixup+jumpIndex, 127)) {
          417  +		jumpEndFixupArray.fixup + jumpIndex, 127)) {
   433    418   	    /*
   434    419   	     * Adjust the immediately preceeding "ifFalse" jump. We moved it's
   435    420   	     * target (just after this jump) down three bytes.
   436    421   	     */
   437    422   
   438    423   	    unsigned char *ifFalsePc = envPtr->codeStart
   439    424   		    + jumpFalseFixupArray.fixup[jumpIndex].codeOffset;
................................................................................
   933    918       PushVarNameWord(interp, varTokenPtr, envPtr, 0,
   934    919   	    &localIndex, &isScalar, 1);
   935    920       valueTokenPtr = TokenAfter(varTokenPtr);
   936    921       for (i = 2 ; i < numWords ; i++) {
   937    922   	CompileWord(envPtr, valueTokenPtr, interp, i);
   938    923   	valueTokenPtr = TokenAfter(valueTokenPtr);
   939    924       }
   940         -    TclEmitInstInt4(	    INST_LIST, numWords-2,		envPtr);
          925  +    TclEmitInstInt4(	    INST_LIST, numWords - 2,		envPtr);
   941    926       if (isScalar) {
   942    927   	if (localIndex < 0) {
   943    928   	    TclEmitOpcode(  INST_LAPPEND_LIST_STK,		envPtr);
   944    929   	} else {
   945    930   	    TclEmitInstInt4(INST_LAPPEND_LIST, localIndex,	envPtr);
   946    931   	}
   947    932       } else {
................................................................................
  1010    995   	tokenPtr = TokenAfter(tokenPtr);
  1011    996   
  1012    997   	/*
  1013    998   	 * Generate the next variable name.
  1014    999   	 */
  1015   1000   
  1016   1001   	PushVarNameWord(interp, tokenPtr, envPtr, 0, &localIndex,
  1017         -		&isScalar, idx+2);
         1002  +		&isScalar, idx + 2);
  1018   1003   
  1019   1004   	/*
  1020   1005   	 * Emit instructions to get the idx'th item out of the list value on
  1021   1006   	 * the stack and assign it to the variable.
  1022   1007   	 */
  1023   1008   
  1024   1009   	if (isScalar) {
................................................................................
  1049   1034       }
  1050   1035   
  1051   1036       /*
  1052   1037        * Generate code to leave the rest of the list on the stack.
  1053   1038        */
  1054   1039   
  1055   1040       TclEmitInstInt4(		INST_LIST_RANGE_IMM, idx,	envPtr);
  1056         -    TclEmitInt4(			INDEX_END,		envPtr);
         1041  +    TclEmitInt4(			TCL_INDEX_END,		envPtr);
  1057   1042   
  1058   1043       return TCL_OK;
  1059   1044   }
  1060   1045   
  1061   1046   /*
  1062   1047    *----------------------------------------------------------------------
  1063   1048    *
................................................................................
  1100   1085   
  1101   1086       valTokenPtr = TokenAfter(parsePtr->tokenPtr);
  1102   1087       if (numWords != 3) {
  1103   1088   	goto emitComplexLindex;
  1104   1089       }
  1105   1090   
  1106   1091       idxTokenPtr = TokenAfter(valTokenPtr);
  1107         -    if (GetIndexFromToken(idxTokenPtr, &idx) == TCL_OK) {
         1092  +    if (TclGetIndexFromToken(idxTokenPtr, TCL_INDEX_BEFORE, TCL_INDEX_BEFORE,
         1093  +	    &idx) == TCL_OK) {
  1108   1094   	/*
  1109         -	 * All checks have been completed, and we have exactly one of these
  1110         -	 * constructs:
  1111         -	 *	 lindex <arbitraryValue> <posInt>
  1112         -	 *	 lindex <arbitraryValue> end-<posInt>
  1113         -	 * This is best compiled as a push of the arbitrary value followed by
  1114         -	 * an "immediate lindex" which is the most efficient variety.
         1095  +	 * The idxTokenPtr parsed as a valid index value and was
         1096  +	 * encoded as expected by INST_LIST_INDEX_IMM.
         1097  +	 *
         1098  +	 * NOTE: that we rely on indexing before a list producing the
         1099  +	 * same result as indexing after a list.
  1115   1100   	 */
  1116   1101   
  1117   1102   	CompileWord(envPtr, valTokenPtr, interp, 1);
  1118   1103   	TclEmitInstInt4(	INST_LIST_INDEX_IMM, idx,	envPtr);
  1119   1104   	return TCL_OK;
  1120   1105       }
  1121   1106   
................................................................................
  1254   1239        * at this point. We use an [lrange ... 0 end] for this (instead of
  1255   1240        * [llength], as with literals) as we must drop any string representation
  1256   1241        * that might be hanging around.
  1257   1242        */
  1258   1243   
  1259   1244       if (concat && numWords == 2) {
  1260   1245   	TclEmitInstInt4(	INST_LIST_RANGE_IMM, 0,	envPtr);
  1261         -	TclEmitInt4(			INDEX_END,	envPtr);
         1246  +	TclEmitInt4(			TCL_INDEX_END,	envPtr);
  1262   1247       }
  1263   1248       return TCL_OK;
  1264   1249   }
  1265   1250   
  1266   1251   /*
  1267   1252    *----------------------------------------------------------------------
  1268   1253    *
................................................................................
  1328   1313       int idx1, idx2;
  1329   1314   
  1330   1315       if (parsePtr->numWords != 4) {
  1331   1316   	return TCL_ERROR;
  1332   1317       }
  1333   1318       listTokenPtr = TokenAfter(parsePtr->tokenPtr);
  1334   1319   
  1335         -    /*
  1336         -     * Parse the indices. Will only compile if both are constants and not an
  1337         -     * _integer_ less than zero (since we reserve negative indices here for
  1338         -     * end-relative indexing) or an end-based index greater than 'end' itself.
  1339         -     */
  1340         -
  1341   1320       tokenPtr = TokenAfter(listTokenPtr);
  1342         -    if (GetIndexFromToken(tokenPtr, &idx1) != TCL_OK) {
         1321  +    if (TclGetIndexFromToken(tokenPtr, TCL_INDEX_START, TCL_INDEX_AFTER,
         1322  +	    &idx1) != TCL_OK) {
  1343   1323   	return TCL_ERROR;
  1344   1324       }
         1325  +    /*
         1326  +     * Token was an index value, and we treat all "first" indices
         1327  +     * before the list same as the start of the list.
         1328  +     */
  1345   1329   
  1346   1330       tokenPtr = TokenAfter(tokenPtr);
  1347         -    if (GetIndexFromToken(tokenPtr, &idx2) != TCL_OK) {
         1331  +    if (TclGetIndexFromToken(tokenPtr, TCL_INDEX_BEFORE, TCL_INDEX_END,
         1332  +	    &idx2) != TCL_OK) {
  1348   1333   	return TCL_ERROR;
  1349   1334       }
         1335  +    /*
         1336  +     * Token was an index value, and we treat all "last" indices
         1337  +     * after the list same as the end of the list.
         1338  +     */
  1350   1339   
  1351   1340       /*
  1352   1341        * Issue instructions. It's not safe to skip doing the LIST_RANGE, as
  1353   1342        * we've not proved that the 'list' argument is really a list. Not that it
  1354   1343        * is worth trying to do that given current knowledge.
  1355   1344        */
  1356   1345   
................................................................................
  1392   1381       /*
  1393   1382        * Parse the index. Will only compile if it is constant and not an
  1394   1383        * _integer_ less than zero (since we reserve negative indices here for
  1395   1384        * end-relative indexing) or an end-based index greater than 'end' itself.
  1396   1385        */
  1397   1386   
  1398   1387       tokenPtr = TokenAfter(listTokenPtr);
  1399         -    if (GetIndexFromToken(tokenPtr, &idx) != TCL_OK) {
         1388  +
         1389  +    /*
         1390  +     * NOTE: This command treats all inserts at indices before the list
         1391  +     * the same as inserts at the start of the list, and all inserts
         1392  +     * after the list the same as inserts at the end of the list. We
         1393  +     * make that transformation here so we can use the optimized bytecode
         1394  +     * as much as possible.
         1395  +     */
         1396  +    if (TclGetIndexFromToken(tokenPtr, TCL_INDEX_START, TCL_INDEX_END,
         1397  +	    &idx) != TCL_OK) {
  1400   1398   	return TCL_ERROR;
  1401   1399       }
  1402   1400   
  1403   1401       /*
  1404   1402        * There are four main cases. If there are no values to insert, this is
  1405   1403        * just a confirm-listiness check. If the index is '0', this is a prepend.
  1406         -     * If the index is 'end' (== INDEX_END), this is an append. Otherwise,
         1404  +     * If the index is 'end' (== TCL_INDEX_END), this is an append. Otherwise,
  1407   1405        * this is a splice (== split, insert values as list, concat-3).
  1408   1406        */
  1409   1407   
  1410   1408       CompileWord(envPtr, listTokenPtr, interp, 1);
  1411   1409       if (parsePtr->numWords == 3) {
  1412   1410   	TclEmitInstInt4(	INST_LIST_RANGE_IMM, 0,		envPtr);
  1413         -	TclEmitInt4(			INDEX_END,		envPtr);
         1411  +	TclEmitInt4(			TCL_INDEX_END,		envPtr);
  1414   1412   	return TCL_OK;
  1415   1413       }
  1416   1414   
  1417   1415       for (i=3 ; i<parsePtr->numWords ; i++) {
  1418   1416   	tokenPtr = TokenAfter(tokenPtr);
  1419   1417   	CompileWord(envPtr, tokenPtr, interp, i);
  1420   1418       }
  1421         -    TclEmitInstInt4(		INST_LIST, i-3,			envPtr);
         1419  +    TclEmitInstInt4(		INST_LIST, i - 3,		envPtr);
  1422   1420   
  1423         -    if (idx == 0 /*start*/) {
         1421  +    if (idx == TCL_INDEX_START) {
  1424   1422   	TclEmitInstInt4(	INST_REVERSE, 2,		envPtr);
  1425   1423   	TclEmitOpcode(		INST_LIST_CONCAT,		envPtr);
  1426         -    } else if (idx == INDEX_END /*end*/) {
         1424  +    } else if (idx == TCL_INDEX_END) {
  1427   1425   	TclEmitOpcode(		INST_LIST_CONCAT,		envPtr);
  1428   1426       } else {
  1429         -	if (idx < 0) {
         1427  +	/*
         1428  +	 * Here we handle two ranges for idx. First when idx > 0, we
         1429  +	 * want the first half of the split to end at index idx-1 and
         1430  +	 * the second half to start at index idx.
         1431  +	 * Second when idx < TCL_INDEX_END, indicating "end-N" indexing,
         1432  +	 * we want the first half of the split to end at index end-N and
         1433  +	 * the second half to start at index end-N+1. We accomplish this
         1434  +	 * with a pre-adjustment of the end-N value.
         1435  +	 * The root of this is that the commands [lrange] and [linsert]
         1436  +	 * differ in their interpretation of the "end" index.
         1437  +	 */
         1438  +
         1439  +	if (idx < TCL_INDEX_END) {
  1430   1440   	    idx++;
  1431   1441   	}
  1432   1442   	TclEmitInstInt4(	INST_OVER, 1,			envPtr);
  1433   1443   	TclEmitInstInt4(	INST_LIST_RANGE_IMM, 0,		envPtr);
  1434         -	TclEmitInt4(			idx-1,			envPtr);
         1444  +	TclEmitInt4(			idx - 1,		envPtr);
  1435   1445   	TclEmitInstInt4(	INST_REVERSE, 3,		envPtr);
  1436   1446   	TclEmitInstInt4(	INST_LIST_RANGE_IMM, idx,	envPtr);
  1437         -	TclEmitInt4(			INDEX_END,		envPtr);
         1447  +	TclEmitInt4(			TCL_INDEX_END,		envPtr);
  1438   1448   	TclEmitOpcode(		INST_LIST_CONCAT,		envPtr);
  1439   1449   	TclEmitOpcode(		INST_LIST_CONCAT,		envPtr);
  1440   1450       }
  1441   1451   
  1442   1452       return TCL_OK;
  1443   1453   }
  1444   1454   
................................................................................
  1460   1470   				 * command. */
  1461   1471       Command *cmdPtr,		/* Points to defintion of command being
  1462   1472   				 * compiled. */
  1463   1473       CompileEnv *envPtr)		/* Holds the resulting instructions. */
  1464   1474   {
  1465   1475       Tcl_Token *tokenPtr, *listTokenPtr;
  1466   1476       DefineLineInformation;	/* TIP #280 */
  1467         -    Tcl_Obj *tmpObj;
  1468   1477       int idx1, idx2, i, offset, offset2;
         1478  +    int emptyPrefix=1, suffixStart = 0;
  1469   1479   
  1470   1480       if (parsePtr->numWords < 4) {
  1471   1481   	return TCL_ERROR;
  1472   1482       }
  1473   1483       listTokenPtr = TokenAfter(parsePtr->tokenPtr);
  1474   1484   
  1475         -    /*
  1476         -     * Parse the indices. Will only compile if both are constants an